Merge pull request #8889 from janlazo/vim-8.0.0999

[RDY] vim-patch:8.0.{999,1041,1043,1044}
This commit is contained in:
James McCoy 2018-08-23 10:45:58 -04:00 committed by GitHub
commit dfbb75fdab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 129 additions and 67 deletions

View File

@ -302,8 +302,8 @@ Visual-block Insert *v_b_I*
With a blockwise selection, I{string}<ESC> will insert {string} at the start
of block on every line of the block, provided that the line extends into the
block. Thus lines that are short will remain unmodified. TABs are split to
retain visual columns.
See |v_b_I_example|.
retain visual columns. Works only for adding text to a line, not for
deletions. See |v_b_I_example|.
Visual-block Append *v_b_A*
With a blockwise selection, A{string}<ESC> will append {string} to the end of
@ -319,6 +319,7 @@ See |v_b_A_example|.
Note: "I" and "A" behave differently for lines that don't extend into the
selected block. This was done intentionally, so that you can do it the way
you want.
Works only for adding text to a line, not for deletions.
Visual-block change *v_b_c*
All selected text in the block will be replaced by the same text string. When

View File

@ -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.

View File

@ -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;
@ -6919,7 +6919,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
p = look + STRLEN(look);
if ((try_match || try_match_word)
&& curwin->w_cursor.col >= (colnr_T)(p - look)) {
int match = FALSE;
bool match = false;
if (keytyped == KEY_COMPLETE) {
char_u *s;
@ -6944,29 +6944,30 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
&& (icase
? mb_strnicmp(s, look, (size_t)(p - look))
: STRNCMP(s, look, p - look)) == 0)
match = TRUE;
} else
/* TODO: multi-byte */
if (keytyped == (int)p[-1] || (icase && keytyped < 256
&& TOLOWER_LOC(keytyped) ==
TOLOWER_LOC((int)p[-1]))) {
line = get_cursor_pos_ptr();
assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX);
if ((curwin->w_cursor.col == (colnr_T)(p - look)
|| !vim_iswordc(line[-(p - look) - 1]))
&& (icase
? mb_strnicmp(line - (p - look), look, (size_t)(p - look))
: STRNCMP(line - (p - look), look, p - look))
== 0)
match = TRUE;
match = true;
} else {
// TODO(@brammool): multi-byte
if (keytyped == (int)p[-1]
|| (icase && keytyped < 256
&& TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1]))) {
line = get_cursor_pos_ptr();
assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX);
if ((curwin->w_cursor.col == (colnr_T)(p - look)
|| !vim_iswordc(line[-(p - look) - 1]))
&& (icase
? mb_strnicmp(line - (p - look), look, (size_t)(p - look))
: STRNCMP(line - (p - look), look, p - look)) == 0) {
match = true;
}
}
}
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) !=
(int)(curwin->w_cursor.col - (p - look)))
match = FALSE;
if (getwhitecols(line) !=
(int)(curwin->w_cursor.col - (p - look))) {
match = false;
}
}
if (match) {
return true;

View File

@ -75,11 +75,12 @@ find_start_comment ( /* XXX */
/// Find the start of a comment or raw string, not knowing if we are in a
/// comment or raw string right now.
/// Search starts at w_cursor.lnum and goes backwards.
/// If is_raw is given and returns start of raw_string, sets it to true.
///
/// @returns NULL when not inside a comment or raw string.
///
/// @note "CORS" -> Comment Or Raw String
static pos_T *ind_find_start_CORS(void)
static pos_T *ind_find_start_CORS(linenr_T *is_raw)
{
// XXX
static pos_T comment_pos_copy;
@ -96,6 +97,9 @@ static pos_T *ind_find_start_CORS(void)
// If comment_pos is before rs_pos the raw string is inside the comment.
// If rs_pos is before comment_pos the comment is inside the raw string.
if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos))) {
if (is_raw != NULL && rs_pos != NULL) {
*is_raw = rs_pos->lnum;
}
return rs_pos;
}
return comment_pos;
@ -384,8 +388,9 @@ int cin_islabel(void)
* it.
*/
curwin->w_cursor.col = 0;
if ((trypos = ind_find_start_CORS()) != NULL) /* XXX */
if ((trypos = ind_find_start_CORS(NULL)) != NULL) { // XXX
curwin->w_cursor = *trypos;
}
line = get_cursor_line_ptr();
if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
@ -1401,10 +1406,12 @@ static pos_T *find_start_brace(void)
pos = NULL;
/* ignore the { if it's in a // or / * * / comment */
if ((colnr_T)cin_skip2pos(trypos) == trypos->col
&& (pos = ind_find_start_CORS()) == NULL) /* XXX */
&& (pos = ind_find_start_CORS(NULL)) == NULL) { // XXX
break;
if (pos != NULL)
}
if (pos != NULL) {
curwin->w_cursor.lnum = pos->lnum;
}
}
curwin->w_cursor = cursor_save;
return trypos;
@ -1443,7 +1450,7 @@ retry:
pos_copy = *trypos; /* copy trypos, findmatch will change it */
trypos = &pos_copy;
curwin->w_cursor = *trypos;
if ((trypos_wk = ind_find_start_CORS()) != NULL) { /* XXX */
if ((trypos_wk = ind_find_start_CORS(NULL)) != NULL) { // XXX
ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
- trypos_wk->lnum);
if (ind_maxp_wk > 0) {
@ -1793,6 +1800,7 @@ int get_c_indent(void)
int cont_amount = 0; /* amount for continuation line */
int original_line_islabel;
int added_to_amount = 0;
linenr_T raw_string_start = 0;
cpp_baseclass_cache_T cache_cpp_baseclass = { false, { MAXLNUM, 0 } };
/* make a copy, value is changed below */
@ -2059,8 +2067,8 @@ int get_c_indent(void)
}
curwin->w_cursor.lnum = lnum;
/* Skip a comment or raw string. XXX */
if ((trypos = ind_find_start_CORS()) != NULL) {
// Skip a comment or raw string. XXX
if ((trypos = ind_find_start_CORS(NULL)) != NULL) {
lnum = trypos->lnum + 1;
continue;
}
@ -2443,7 +2451,7 @@ int get_c_indent(void)
* If we're in a comment or raw string now, skip to
* the start of it.
*/
trypos = ind_find_start_CORS();
trypos = ind_find_start_CORS(NULL);
if (trypos != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
@ -2552,7 +2560,7 @@ int get_c_indent(void)
/* If we're in a comment or raw string now, skip
* to the start of it. */
trypos = ind_find_start_CORS();
trypos = ind_find_start_CORS(NULL);
if (trypos != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
@ -2581,11 +2589,10 @@ int get_c_indent(void)
break;
}
/*
* If we're in a comment or raw string now, skip to the start
* of it.
*/ /* XXX */
if ((trypos = ind_find_start_CORS()) != NULL) {
// If we're in a comment or raw string now, skip to the start
// of it.
// XXX
if ((trypos = ind_find_start_CORS(&raw_string_start)) != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;
@ -3096,7 +3103,8 @@ int get_c_indent(void)
}
if (lookfor != LOOKFOR_TERM
&& lookfor != LOOKFOR_JS_KEY
&& lookfor != LOOKFOR_COMMA) {
&& lookfor != LOOKFOR_COMMA
&& raw_string_start != curwin->w_cursor.lnum) {
lookfor = LOOKFOR_UNTERM;
}
}
@ -3351,11 +3359,10 @@ term_again:
l = get_cursor_line_ptr();
/*
* If we're in a comment or raw string now, skip to the start
* of it.
*/ /* XXX */
if ((trypos = ind_find_start_CORS()) != NULL) {
// If we're in a comment or raw string now, skip to the start
// of it.
// XXX
if ((trypos = ind_find_start_CORS(NULL)) != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;

View File

@ -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;

View File

@ -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 = 0;
struct block_def bd;
int i;
pos_T t1;
@ -2044,9 +2045,13 @@ 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)
if (oap->op_type == OP_APPEND) {
firstline += bd.textlen;
}
pre_textlen = (long)STRLEN(firstline);
}
@ -2100,6 +2105,14 @@ void op_insert(oparg_T *oap, long count1)
if (oap->motion_type == kMTBlockWise) {
struct block_def bd2;
// if indent kicked in, the firstline might have changed
// but only do that, if the indent actually increased
const colnr_T 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;
}
/* The user may have moved the cursor before inserting something, try
* to adjust the block for that. */
if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX) {
@ -2216,7 +2229,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 +2250,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);
@ -4120,10 +4133,9 @@ format_lines (
if (next_leader_len > 0) {
(void)del_bytes(next_leader_len, false, false);
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);
(long)-next_leader_len);
} else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
int indent = (int)getwhitecols_curline();
if (indent > 0) {
(void)del_bytes(indent, FALSE, FALSE);

View File

@ -2460,9 +2460,10 @@ win_line (
ptr = line;
if (has_spell) {
/* For checking first word with a capital skip white space. */
if (cap_col == 0)
cap_col = (int)(skipwhite(line) - line);
// For checking first word with a capital skip white space.
if (cap_col == 0) {
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

View File

@ -1398,13 +1398,14 @@ spell_move_to (
capcol = 0;
// For checking first word with a capital skip white space.
if (capcol == 0)
capcol = (int)(skipwhite(line) - line);
else if (curline && wp == curwin) {
if (capcol == 0) {
capcol = (int)getwhitecols(line);
} else if (curline && wp == curwin) {
// For spellbadword(): check if first word needs a capital.
col = (int)(skipwhite(line) - line);
if (check_need_cap(lnum, col))
col = (int)getwhitecols(line);
if (check_need_cap(lnum, col)) {
capcol = col;
}
// Need to get the line again, may have looked at the previous
// one.
@ -2976,7 +2977,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)

View File

@ -68,9 +68,38 @@ func Test_cino_extern_c()
call assert_equal(pair[2], getline(len(lines) + 1), 'Failed for "' . string(lines) . '"')
endfor
bwipe!
endfunc
func Test_cindent_rawstring()
new
setl cindent
call feedkeys("i" .
\ "int main() {\<CR>" .
\ "R\"(\<CR>" .
\ ")\";\<CR>" .
\ "statement;\<Esc>", "x")
call assert_equal("\tstatement;", getline(line('.')))
bw!
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