aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/charset.c14
-rw-r--r--src/nvim/edit.c7
-rw-r--r--src/nvim/misc1.c6
-rw-r--r--src/nvim/ops.c19
-rw-r--r--src/nvim/screen.c2
-rw-r--r--src/nvim/spell.c6
-rw-r--r--src/nvim/testdir/test_cindent.vim24
7 files changed, 59 insertions, 19 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index f1b3be6b46..4e8bb3b0d7 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -30,7 +30,7 @@
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/path.h"
-
+#include "nvim/cursor.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "charset.c.generated.h"
@@ -1465,6 +1465,18 @@ char_u *skipwhite(const char_u *q)
return (char_u *)p;
}
+// getwhitecols: return the number of whitespace
+// columns (bytes) at the start of a given line
+intptr_t getwhitecols_curline(void)
+{
+ return getwhitecols(get_cursor_line_ptr());
+}
+
+intptr_t getwhitecols(const char_u *p)
+{
+ return skipwhite(p) - p;
+}
+
/// Skip over digits
///
/// @param[in] q String to skip digits in.
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 085f12473e..be2797ee3e 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -4506,7 +4506,7 @@ static int ins_complete(int c, bool enable_pum)
* first non_blank in the line, if it is not a wordchar
* include it to get a better pattern, but then we don't
* want the "\\<" prefix, check it bellow */
- compl_col = (colnr_T)(skipwhite(line) - line);
+ compl_col = (colnr_T)getwhitecols(line);
compl_startpos.col = compl_col;
compl_startpos.lnum = curwin->w_cursor.lnum;
compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
@@ -4625,7 +4625,7 @@ static int ins_complete(int c, bool enable_pum)
}
}
} else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) {
- compl_col = (colnr_T)(skipwhite(line) - line);
+ compl_col = (colnr_T)getwhitecols(line);
compl_length = (int)curs_col - (int)compl_col;
if (compl_length < 0) /* cursor in indent: empty pattern */
compl_length = 0;
@@ -6963,8 +6963,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
if (match && try_match_word && !try_match) {
/* "0=word": Check if there are only blanks before the
* word. */
- line = get_cursor_line_ptr();
- if ((int)(skipwhite(line) - line) !=
+ if (getwhitecols(line) !=
(int)(curwin->w_cursor.col - (p - look)))
match = FALSE;
}
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 84d8c995a6..e87c754eb8 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -884,8 +884,7 @@ open_line (
&& curbuf->b_p_lisp
&& curbuf->b_p_ai) {
fixthisline(get_lisp_indent);
- p = get_cursor_line_ptr();
- ai_col = (colnr_T)(skipwhite(p) - p);
+ ai_col = (colnr_T)getwhitecols_curline();
}
/*
* May do indenting after opening a new line.
@@ -898,8 +897,7 @@ open_line (
? KEY_OPEN_FORW
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) {
do_c_expr_indent();
- p = get_cursor_line_ptr();
- ai_col = (colnr_T)(skipwhite(p) - p);
+ ai_col = (colnr_T)getwhitecols_curline();
}
if (vreplace_mode != 0)
State = vreplace_mode;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index ff02d82ff3..f3661b2045 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -2014,6 +2014,7 @@ void op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
char_u *firstline, *ins_text;
+ colnr_T ind_pre, ind_post;
struct block_def bd;
int i;
pos_T t1;
@@ -2044,7 +2045,10 @@ void op_insert(oparg_T *oap, long count1)
}
// Get the info about the block before entering the text
block_prep(oap, &bd, oap->start.lnum, true);
+ // Get indent information
+ ind_pre = (colnr_T)getwhitecols_curline();
firstline = ml_get(oap->start.lnum) + bd.textcol;
+
if (oap->op_type == OP_APPEND)
firstline += bd.textlen;
pre_textlen = (long)STRLEN(firstline);
@@ -2091,6 +2095,14 @@ void op_insert(oparg_T *oap, long count1)
oap->start = curbuf->b_op_start_orig;
}
+ // if indent kicked in, the firstline might have changed
+ // but only do that, if the indent actually increased
+ ind_post = (colnr_T)getwhitecols_curline();
+ if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre) {
+ bd.textcol += ind_post - ind_pre;
+ bd.start_vcol += ind_post - ind_pre;
+ }
+
/* If user has moved off this line, we don't know what to do, so do
* nothing.
* Also don't repeat the insert when Insert mode ended with CTRL-C. */
@@ -2216,7 +2228,7 @@ int op_change(oparg_T *oap)
}
firstline = ml_get(oap->start.lnum);
pre_textlen = (long)STRLEN(firstline);
- pre_indent = (long)(skipwhite(firstline) - firstline);
+ pre_indent = (long)getwhitecols(firstline);
bd.textcol = curwin->w_cursor.col;
}
@@ -2237,7 +2249,7 @@ int op_change(oparg_T *oap)
// the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum);
if (bd.textcol > (colnr_T)pre_indent) {
- long new_indent = (long)(skipwhite(firstline) - firstline);
+ long new_indent = (long)getwhitecols(firstline);
pre_textlen += new_indent - pre_indent;
bd.textcol += (colnr_T)(new_indent - pre_indent);
@@ -4122,8 +4134,7 @@ format_lines (
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
(long)-next_leader_len);
} else if (second_indent > 0) { /* the "leader" for FO_Q_SECOND */
- char_u *p = get_cursor_line_ptr();
- int indent = (int)(skipwhite(p) - p);
+ int indent = (int)getwhitecols_curline();
if (indent > 0) {
(void)del_bytes(indent, FALSE, FALSE);
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ec48bf5dcf..e1bc8556f9 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2462,7 +2462,7 @@ win_line (
if (has_spell) {
/* For checking first word with a capital skip white space. */
if (cap_col == 0)
- cap_col = (int)(skipwhite(line) - line);
+ cap_col = (int)getwhitecols(line);
/* To be able to spell-check over line boundaries copy the end of the
* current line into nextline[]. Above the start of the next line was
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 1cb679245b..c05a1d107a 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1399,10 +1399,10 @@ spell_move_to (
// For checking first word with a capital skip white space.
if (capcol == 0)
- capcol = (int)(skipwhite(line) - line);
+ capcol = (int)getwhitecols(line);
else if (curline && wp == curwin) {
// For spellbadword(): check if first word needs a capital.
- col = (int)(skipwhite(line) - line);
+ col = (int)getwhitecols(line);
if (check_need_cap(lnum, col))
capcol = col;
@@ -2976,7 +2976,7 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
line = get_cursor_line_ptr();
endcol = 0;
- if ((int)(skipwhite(line) - line) >= (int)col) {
+ if (getwhitecols(line) >= (int)col) {
// At start of line, check if previous line is empty or sentence
// ends there.
if (lnum == 1)
diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim
index d352e8feff..7c2c5e341c 100644
--- a/src/nvim/testdir/test_cindent.vim
+++ b/src/nvim/testdir/test_cindent.vim
@@ -71,7 +71,7 @@ func Test_cino_extern_c()
bwipe!
endfunc
-func! Test_cindent_rawstring()
+func Test_cindent_rawstring()
new
setl cindent
call feedkeys("i" .
@@ -81,5 +81,25 @@ func! Test_cindent_rawstring()
\ "statement;\<Esc>", "x")
call assert_equal("\tstatement;", getline(line('.')))
bw!
-endfunction
+endfunc
+
+func Test_cindent_expr()
+ new
+ func! MyIndentFunction()
+ return v:lnum == 1 ? shiftwidth() : 0
+ endfunc
+ setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction()
+ call setline(1, ['var_a = something()', 'b = something()'])
+ call cursor(1, 1)
+ call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
+ call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$'))
+
+ %d
+ call setline(1, [' var_a = something()', ' b = something()'])
+ call cursor(1, 1)
+ call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
+ call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$'))
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab