diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-01-22 10:00:11 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-22 10:00:11 +0800 |
commit | 8c6de9147cabbf99d18afbdbed2f11f30c1d0dfc (patch) | |
tree | b05e873236f53b2b9dc244c00f538eb47f45ab2f /src/nvim/plines.h | |
parent | a25aeee856e2fb02f93ffa5c2e5d43fd75ead2cf (diff) | |
parent | fd08de4b85ae42fe3ad5b480b58df9f7fff76269 (diff) | |
download | rneovim-8c6de9147cabbf99d18afbdbed2f11f30c1d0dfc.tar.gz rneovim-8c6de9147cabbf99d18afbdbed2f11f30c1d0dfc.tar.bz2 rneovim-8c6de9147cabbf99d18afbdbed2f11f30c1d0dfc.zip |
Merge pull request #26813 from VanaIgr/screen-pos-speedup
perf: make screen size and position calculations more efficient
N/A patches for version.c:
vim-patch:9.1.0037: Calling get_breakindent_win() repeatedly when computing virtcol
vim-patch:9.1.0038: Unnecessary loop in getvcol()
Diffstat (limited to 'src/nvim/plines.h')
-rw-r--r-- | src/nvim/plines.h | 95 |
1 files changed, 83 insertions, 12 deletions
diff --git a/src/nvim/plines.h b/src/nvim/plines.h index 38024e622e..4611101041 100644 --- a/src/nvim/plines.h +++ b/src/nvim/plines.h @@ -4,25 +4,96 @@ #include <stdint.h> // IWYU pragma: keep #include "nvim/marktree_defs.h" +#include "nvim/mbyte_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" -/// Argument for lbr_chartabsize(). +typedef bool CSType; + +enum { + kCharsizeRegular, + kCharsizeFast, +}; + +/// Argument for char size functions. typedef struct { - win_T *cts_win; - char *cts_line; ///< start of the line - char *cts_ptr; ///< current position in line - int cts_row; + win_T *win; + char *line; ///< start of the line + + bool use_tabstop; ///< use tabstop for tab insted of counting it as ^I + int indent_width; ///< width of showbreak and breakindent on wrapped lines + /// INT_MIN if not yet calculated - bool cts_has_virt_text; ///< true if if there is inline virtual text - int cts_cur_text_width_left; ///< width of virtual text left of cursor - int cts_cur_text_width_right; ///< width of virtual text right of cursor - MarkTreeIter cts_iter[1]; + int virt_row; ///< line number, -1 if no virtual text + int cur_text_width_left; ///< width of virtual text left of cursor + int cur_text_width_right; ///< width of virtual text right of cursor - int cts_vcol; ///< virtual column at current position - int cts_max_head_vcol; ///< see win_lbr_chartabsize() -} chartabsize_T; + int max_head_vcol; ///< see charsize_regular() + MarkTreeIter iter[1]; +} CharsizeArg; + +typedef struct { + int width; + int head; // size of breakindent etc. before the character (included in width) +} CharSize; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "plines.h.generated.h" #endif + +static inline CharSize win_charsize(CSType cstype, int vcol, char *ptr, int32_t chr, + CharsizeArg *arg) + REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; + +/// Get the number of cells taken up on the screen by the given character at vcol. +/// "arg->cur_text_width_left" and "arg->cur_text_width_right" are set +/// to the extra size for inline virtual text. +/// +/// When "arg->max_head_vcol" is positive, only count in "head" the size +/// of 'showbreak'/'breakindent' before "arg->max_head_vcol". +/// When "arg->max_head_vcol" is negative, only count in "head" the size +/// of 'showbreak'/'breakindent' before where cursor should be placed. +static inline CharSize win_charsize(CSType cstype, int vcol, char *ptr, int32_t chr, + CharsizeArg *arg) +{ + if (cstype == kCharsizeFast) { + return charsize_fast(arg, vcol, chr); + } else { + return charsize_regular(arg, ptr, vcol, chr); + } +} + +static inline int linetabsize_str(char *s) + REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; + +/// Return the number of characters the string 's' will take on the screen, +/// taking into account the size of a tab. +/// +/// @param s +/// +/// @return Number of characters the string will take on the screen. +static inline int linetabsize_str(char *s) +{ + return linetabsize_col(0, s); +} + +static inline int win_linetabsize(win_T *wp, linenr_T lnum, char *line, colnr_T len) + REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; + +/// Like linetabsize_str(), but for a given window instead of the current one. +/// +/// @param wp +/// @param line +/// @param len +/// +/// @return Number of characters the string will take on the screen. +static inline int win_linetabsize(win_T *wp, linenr_T lnum, char *line, colnr_T len) +{ + CharsizeArg arg; + CSType const cstype = init_charsize_arg(&arg, wp, lnum, line); + if (cstype == kCharsizeFast) { + return linesize_fast(&arg, 0, len); + } else { + return linesize_regular(&arg, 0, len); + } +} |