aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/charset.c299
-rw-r--r--src/nvim/charset.h3
-rw-r--r--src/nvim/indent_c.c1
-rw-r--r--src/nvim/plines.c296
-rw-r--r--src/nvim/plines.h4
-rw-r--r--src/nvim/search.c1
-rw-r--r--src/nvim/statusline.c1
7 files changed, 302 insertions, 303 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index ce49f2ad86..2756a60d60 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -18,24 +18,17 @@
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
-#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/garray.h"
#include "nvim/globals.h"
#include "nvim/grid_defs.h"
-#include "nvim/indent.h"
#include "nvim/keycodes.h"
#include "nvim/macros.h"
-#include "nvim/mark.h"
#include "nvim/mbyte.h"
-#include "nvim/memline.h"
#include "nvim/memory.h"
-#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/path.h"
-#include "nvim/plines.h"
#include "nvim/pos.h"
-#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/vim.h"
@@ -921,298 +914,6 @@ bool vim_isprintc_strict(int c)
return c > 0 && (g_chartab[c] & CT_PRINT_CHAR);
}
-/// Check that virtual column "vcol" is in the rightmost column of window "wp".
-///
-/// @param wp window
-/// @param vcol column number
-bool in_win_border(win_T *wp, colnr_T vcol)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
-{
- if (wp->w_width_inner == 0) {
- // there is no border
- return false;
- }
- int width1 = wp->w_width_inner - win_col_off(wp); // width of first line (after line number)
-
- if ((int)vcol < width1 - 1) {
- return false;
- }
-
- if ((int)vcol == width1 - 1) {
- return true;
- }
- int width2 = width1 + win_col_off2(wp); // width of further lines
-
- if (width2 <= 0) {
- return false;
- }
- return (vcol - width1) % width2 == width2 - 1;
-}
-
-/// Get virtual column number of pos.
-/// start: on the first position of this character (TAB, ctrl)
-/// cursor: where the cursor is on this character (first char, except for TAB)
-/// end: on the last position of this character (TAB, ctrl)
-///
-/// This is used very often, keep it fast!
-///
-/// @param wp
-/// @param pos
-/// @param start
-/// @param cursor
-/// @param end
-void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
-{
- char *ptr; // points to current char
- char *posptr; // points to char at pos->col
- int incr;
- int head;
- long *vts = wp->w_buffer->b_p_vts_array;
- int ts = (int)wp->w_buffer->b_p_ts;
-
- colnr_T vcol = 0;
- char *line = ptr = ml_get_buf(wp->w_buffer, pos->lnum); // start of the line
-
- if (pos->col == MAXCOL) {
- // continue until the NUL
- posptr = NULL;
- } else {
- // In a few cases the position can be beyond the end of the line.
- for (colnr_T i = 0; i < pos->col; i++) {
- if (ptr[i] == NUL) {
- pos->col = i;
- break;
- }
- }
- posptr = ptr + pos->col;
- posptr -= utf_head_off(line, posptr);
- }
-
- chartabsize_T cts;
- bool on_NUL = false;
- init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line);
- cts.cts_max_head_vcol = -1;
-
- // This function is used very often, do some speed optimizations.
- // When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
- // and there are no virtual text use a simple loop.
- // Also use this when 'list' is set but tabs take their normal size.
- if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL))
- && !wp->w_p_lbr
- && *get_showbreak_value(wp) == NUL
- && !wp->w_p_bri
- && !cts.cts_has_virt_text) {
- while (true) {
- head = 0;
- int c = (uint8_t)(*ptr);
-
- // make sure we don't go past the end of the line
- if (c == NUL) {
- // NUL at end of line only takes one column
- incr = 1;
- break;
- }
-
- // A tab gets expanded, depending on the current column
- if (c == TAB) {
- incr = tabstop_padding(vcol, ts, vts);
- } else {
- // For utf-8, if the byte is >= 0x80, need to look at
- // further bytes to find the cell width.
- if (c >= 0x80) {
- incr = utf_ptr2cells(ptr);
- } else {
- incr = g_chartab[c] & CT_CELL_MASK;
- }
-
- // If a double-cell char doesn't fit at the end of a line
- // it wraps to the next line, it's like this char is three
- // cells wide.
- if ((incr == 2)
- && wp->w_p_wrap
- && (MB_BYTE2LEN((uint8_t)(*ptr)) > 1)
- && in_win_border(wp, vcol)) {
- incr++;
- head = 1;
- }
- }
-
- if ((posptr != NULL) && (ptr >= posptr)) {
- // character at pos->col
- break;
- }
-
- vcol += incr;
- MB_PTR_ADV(ptr);
- }
- } else {
- while (true) {
- // A tab gets expanded, depending on the current column
- // Other things also take up space.
- head = 0;
- incr = win_lbr_chartabsize(&cts, &head);
-
- // make sure we don't go past the end of the line
- if (*cts.cts_ptr == NUL) {
- // NUL at end of line only takes one column, unless there is virtual text
- incr = MAX(1, cts.cts_cur_text_width_left + cts.cts_cur_text_width_right);
- on_NUL = true;
- break;
- }
-
- if ((posptr != NULL) && (cts.cts_ptr >= posptr)) {
- // character at pos->col
- break;
- }
-
- cts.cts_vcol += incr;
- MB_PTR_ADV(cts.cts_ptr);
- }
- vcol = cts.cts_vcol;
- ptr = cts.cts_ptr;
- }
- clear_chartabsize_arg(&cts);
-
- if (start != NULL) {
- *start = vcol + head;
- }
-
- if (end != NULL) {
- *end = vcol + incr - 1;
- }
-
- if (cursor != NULL) {
- if ((*ptr == TAB)
- && (State & MODE_NORMAL)
- && !wp->w_p_list
- && !virtual_active()
- && !(VIsual_active && ((*p_sel == 'e') || ltoreq(*pos, VIsual)))) {
- // cursor at end
- *cursor = vcol + incr - 1;
- } else {
- if (!on_NUL || !(State & MODE_NORMAL)) {
- vcol += cts.cts_cur_text_width_left;
- }
- if (!on_NUL && (State & MODE_NORMAL)) {
- vcol += cts.cts_cur_text_width_right;
- }
- // cursor at start
- *cursor = vcol + head;
- }
- }
-}
-
-/// Get virtual cursor column in the current window, pretending 'list' is off.
-///
-/// @param posp
-///
-/// @retujrn The virtual cursor column.
-colnr_T getvcol_nolist(pos_T *posp)
-{
- int list_save = curwin->w_p_list;
- colnr_T vcol;
-
- curwin->w_p_list = false;
- if (posp->coladd) {
- getvvcol(curwin, posp, NULL, &vcol, NULL);
- } else {
- getvcol(curwin, posp, NULL, &vcol, NULL);
- }
- curwin->w_p_list = list_save;
- return vcol;
-}
-
-/// Get virtual column in virtual mode.
-///
-/// @param wp
-/// @param pos
-/// @param start
-/// @param cursor
-/// @param end
-void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
-{
- colnr_T col;
-
- if (virtual_active()) {
- // For virtual mode, only want one value
- getvcol(wp, pos, &col, NULL, NULL);
-
- colnr_T coladd = pos->coladd;
- colnr_T endadd = 0;
-
- // Cannot put the cursor on part of a wide character.
- char *ptr = ml_get_buf(wp->w_buffer, pos->lnum);
-
- if (pos->col < (colnr_T)strlen(ptr)) {
- int c = utf_ptr2char(ptr + pos->col);
- if ((c != TAB) && vim_isprintc(c)) {
- endadd = (colnr_T)(char2cells(c) - 1);
- if (coladd > endadd) {
- // past end of line
- endadd = 0;
- } else {
- coladd = 0;
- }
- }
- }
- col += coladd;
-
- if (start != NULL) {
- *start = col;
- }
-
- if (cursor != NULL) {
- *cursor = col;
- }
-
- if (end != NULL) {
- *end = col + endadd;
- }
- } else {
- getvcol(wp, pos, start, cursor, end);
- }
-}
-
-/// Get the leftmost and rightmost virtual column of pos1 and pos2.
-/// Used for Visual block mode.
-///
-/// @param wp
-/// @param pos1
-/// @param pos2
-/// @param left
-/// @param right
-void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right)
-{
- colnr_T from1;
- colnr_T from2;
- colnr_T to1;
- colnr_T to2;
-
- if (lt(*pos1, *pos2)) {
- getvvcol(wp, pos1, &from1, NULL, &to1);
- getvvcol(wp, pos2, &from2, NULL, &to2);
- } else {
- getvvcol(wp, pos2, &from1, NULL, &to1);
- getvvcol(wp, pos1, &from2, NULL, &to2);
- }
-
- if (from2 < from1) {
- *left = from2;
- } else {
- *left = from1;
- }
-
- if (to2 > to1) {
- if ((*p_sel == 'e') && (from2 - 1 >= to1)) {
- *right = from2 - 1;
- } else {
- *right = to2;
- }
- } else {
- *right = to1;
- }
-}
-
/// skipwhite: skip over ' ' and '\t'.
///
/// @param[in] p String to skip in.
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index 258e95bec0..cb5fbb22ed 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -2,13 +2,12 @@
#define NVIM_CHARSET_H
#include <stdbool.h>
+#include <stdint.h>
#include "nvim/buffer_defs.h"
#include "nvim/eval/typval_defs.h"
-#include "nvim/option_defs.h"
#include "nvim/pos.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
/// Return the folded-case equivalent of the given character
///
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index 37a76542d4..1671bf009a 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -20,6 +20,7 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/option.h"
+#include "nvim/plines.h"
#include "nvim/pos.h"
#include "nvim/search.h"
#include "nvim/strings.h"
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
index 1123d42916..4fba3b4c4e 100644
--- a/src/nvim/plines.c
+++ b/src/nvim/plines.c
@@ -3,7 +3,6 @@
// plines.c: calculate the vertical and horizontal size of text in a window
-#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
@@ -17,12 +16,15 @@
#include "nvim/globals.h"
#include "nvim/indent.h"
#include "nvim/macros.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/plines.h"
#include "nvim/pos.h"
+#include "nvim/state.h"
+#include "nvim/types.h"
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -423,6 +425,298 @@ static int win_nolbr_chartabsize(chartabsize_T *cts, int *headp)
return n;
}
+/// Check that virtual column "vcol" is in the rightmost column of window "wp".
+///
+/// @param wp window
+/// @param vcol column number
+static bool in_win_border(win_T *wp, colnr_T vcol)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
+{
+ if (wp->w_width_inner == 0) {
+ // there is no border
+ return false;
+ }
+ int width1 = wp->w_width_inner - win_col_off(wp); // width of first line (after line number)
+
+ if ((int)vcol < width1 - 1) {
+ return false;
+ }
+
+ if ((int)vcol == width1 - 1) {
+ return true;
+ }
+ int width2 = width1 + win_col_off2(wp); // width of further lines
+
+ if (width2 <= 0) {
+ return false;
+ }
+ return (vcol - width1) % width2 == width2 - 1;
+}
+
+/// Get virtual column number of pos.
+/// start: on the first position of this character (TAB, ctrl)
+/// cursor: where the cursor is on this character (first char, except for TAB)
+/// end: on the last position of this character (TAB, ctrl)
+///
+/// This is used very often, keep it fast!
+///
+/// @param wp
+/// @param pos
+/// @param start
+/// @param cursor
+/// @param end
+void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
+{
+ char *ptr; // points to current char
+ char *posptr; // points to char at pos->col
+ int incr;
+ int head;
+ long *vts = wp->w_buffer->b_p_vts_array;
+ int ts = (int)wp->w_buffer->b_p_ts;
+
+ colnr_T vcol = 0;
+ char *line = ptr = ml_get_buf(wp->w_buffer, pos->lnum); // start of the line
+
+ if (pos->col == MAXCOL) {
+ // continue until the NUL
+ posptr = NULL;
+ } else {
+ // In a few cases the position can be beyond the end of the line.
+ for (colnr_T i = 0; i < pos->col; i++) {
+ if (ptr[i] == NUL) {
+ pos->col = i;
+ break;
+ }
+ }
+ posptr = ptr + pos->col;
+ posptr -= utf_head_off(line, posptr);
+ }
+
+ chartabsize_T cts;
+ bool on_NUL = false;
+ init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line);
+ cts.cts_max_head_vcol = -1;
+
+ // This function is used very often, do some speed optimizations.
+ // When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
+ // and there are no virtual text use a simple loop.
+ // Also use this when 'list' is set but tabs take their normal size.
+ if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL))
+ && !wp->w_p_lbr
+ && *get_showbreak_value(wp) == NUL
+ && !wp->w_p_bri
+ && !cts.cts_has_virt_text) {
+ while (true) {
+ head = 0;
+ int c = (uint8_t)(*ptr);
+
+ // make sure we don't go past the end of the line
+ if (c == NUL) {
+ // NUL at end of line only takes one column
+ incr = 1;
+ break;
+ }
+
+ // A tab gets expanded, depending on the current column
+ if (c == TAB) {
+ incr = tabstop_padding(vcol, ts, vts);
+ } else {
+ // For utf-8, if the byte is >= 0x80, need to look at
+ // further bytes to find the cell width.
+ if (c >= 0x80) {
+ incr = utf_ptr2cells(ptr);
+ } else {
+ incr = byte2cells(c);
+ }
+
+ // If a double-cell char doesn't fit at the end of a line
+ // it wraps to the next line, it's like this char is three
+ // cells wide.
+ if ((incr == 2)
+ && wp->w_p_wrap
+ && (MB_BYTE2LEN((uint8_t)(*ptr)) > 1)
+ && in_win_border(wp, vcol)) {
+ incr++;
+ head = 1;
+ }
+ }
+
+ if ((posptr != NULL) && (ptr >= posptr)) {
+ // character at pos->col
+ break;
+ }
+
+ vcol += incr;
+ MB_PTR_ADV(ptr);
+ }
+ } else {
+ while (true) {
+ // A tab gets expanded, depending on the current column
+ // Other things also take up space.
+ head = 0;
+ incr = win_lbr_chartabsize(&cts, &head);
+
+ // make sure we don't go past the end of the line
+ if (*cts.cts_ptr == NUL) {
+ // NUL at end of line only takes one column, unless there is virtual text
+ incr = MAX(1, cts.cts_cur_text_width_left + cts.cts_cur_text_width_right);
+ on_NUL = true;
+ break;
+ }
+
+ if ((posptr != NULL) && (cts.cts_ptr >= posptr)) {
+ // character at pos->col
+ break;
+ }
+
+ cts.cts_vcol += incr;
+ MB_PTR_ADV(cts.cts_ptr);
+ }
+ vcol = cts.cts_vcol;
+ ptr = cts.cts_ptr;
+ }
+ clear_chartabsize_arg(&cts);
+
+ if (start != NULL) {
+ *start = vcol + head;
+ }
+
+ if (end != NULL) {
+ *end = vcol + incr - 1;
+ }
+
+ if (cursor != NULL) {
+ if ((*ptr == TAB)
+ && (State & MODE_NORMAL)
+ && !wp->w_p_list
+ && !virtual_active()
+ && !(VIsual_active && ((*p_sel == 'e') || ltoreq(*pos, VIsual)))) {
+ // cursor at end
+ *cursor = vcol + incr - 1;
+ } else {
+ if (!on_NUL || !(State & MODE_NORMAL)) {
+ vcol += cts.cts_cur_text_width_left;
+ }
+ if (!on_NUL && (State & MODE_NORMAL)) {
+ vcol += cts.cts_cur_text_width_right;
+ }
+ // cursor at start
+ *cursor = vcol + head;
+ }
+ }
+}
+
+/// Get virtual cursor column in the current window, pretending 'list' is off.
+///
+/// @param posp
+///
+/// @retujrn The virtual cursor column.
+colnr_T getvcol_nolist(pos_T *posp)
+{
+ int list_save = curwin->w_p_list;
+ colnr_T vcol;
+
+ curwin->w_p_list = false;
+ if (posp->coladd) {
+ getvvcol(curwin, posp, NULL, &vcol, NULL);
+ } else {
+ getvcol(curwin, posp, NULL, &vcol, NULL);
+ }
+ curwin->w_p_list = list_save;
+ return vcol;
+}
+
+/// Get virtual column in virtual mode.
+///
+/// @param wp
+/// @param pos
+/// @param start
+/// @param cursor
+/// @param end
+void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
+{
+ colnr_T col;
+
+ if (virtual_active()) {
+ // For virtual mode, only want one value
+ getvcol(wp, pos, &col, NULL, NULL);
+
+ colnr_T coladd = pos->coladd;
+ colnr_T endadd = 0;
+
+ // Cannot put the cursor on part of a wide character.
+ char *ptr = ml_get_buf(wp->w_buffer, pos->lnum);
+
+ if (pos->col < (colnr_T)strlen(ptr)) {
+ int c = utf_ptr2char(ptr + pos->col);
+ if ((c != TAB) && vim_isprintc(c)) {
+ endadd = (colnr_T)(char2cells(c) - 1);
+ if (coladd > endadd) {
+ // past end of line
+ endadd = 0;
+ } else {
+ coladd = 0;
+ }
+ }
+ }
+ col += coladd;
+
+ if (start != NULL) {
+ *start = col;
+ }
+
+ if (cursor != NULL) {
+ *cursor = col;
+ }
+
+ if (end != NULL) {
+ *end = col + endadd;
+ }
+ } else {
+ getvcol(wp, pos, start, cursor, end);
+ }
+}
+
+/// Get the leftmost and rightmost virtual column of pos1 and pos2.
+/// Used for Visual block mode.
+///
+/// @param wp
+/// @param pos1
+/// @param pos2
+/// @param left
+/// @param right
+void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right)
+{
+ colnr_T from1;
+ colnr_T from2;
+ colnr_T to1;
+ colnr_T to2;
+
+ if (lt(*pos1, *pos2)) {
+ getvvcol(wp, pos1, &from1, NULL, &to1);
+ getvvcol(wp, pos2, &from2, NULL, &to2);
+ } else {
+ getvvcol(wp, pos2, &from1, NULL, &to1);
+ getvvcol(wp, pos1, &from2, NULL, &to2);
+ }
+
+ if (from2 < from1) {
+ *left = from2;
+ } else {
+ *left = from1;
+ }
+
+ if (to2 > to1) {
+ if ((*p_sel == 'e') && (from2 - 1 >= to1)) {
+ *right = from2 - 1;
+ } else {
+ *right = to2;
+ }
+ } else {
+ *right = to1;
+ }
+}
+
/// Functions calculating vertical size of text when displayed inside a window.
/// Calls horizontal size functions defined above.
diff --git a/src/nvim/plines.h b/src/nvim/plines.h
index 153d84e8bb..ba04ef4554 100644
--- a/src/nvim/plines.h
+++ b/src/nvim/plines.h
@@ -2,9 +2,11 @@
#define NVIM_PLINES_H
#include <stdbool.h>
+#include <stdint.h>
#include "nvim/buffer_defs.h"
-#include "nvim/vim.h"
+#include "nvim/marktree.h"
+#include "nvim/pos.h"
/// Argument for lbr_chartabsize().
typedef struct {
diff --git a/src/nvim/search.c b/src/nvim/search.c
index d42da8fb18..cb6596d211 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -47,6 +47,7 @@
#include "nvim/os/input.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/profile.h"
#include "nvim/regexp.h"
#include "nvim/search.h"
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c
index b708ccb4a3..30c98a2f1e 100644
--- a/src/nvim/statusline.c
+++ b/src/nvim/statusline.c
@@ -36,6 +36,7 @@
#include "nvim/optionstr.h"
#include "nvim/os/os.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/pos.h"
#include "nvim/sign.h"
#include "nvim/statusline.h"