mirror of
https://github.com/neovim/neovim.git
synced 2025-10-01 23:48:32 +00:00
vim-patch:8.1.2127: the indent.c file is a bit big
Problem: The indent.c file is a bit big.
Solution: Move C-indent code a a new cindent.c file. Move other
indent-related code to indent.c. (Yegappan Lakshmanan,
closes vim/vim#5031)
14c01f8348
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
274
src/nvim/edit.c
274
src/nvim/edit.c
@@ -1636,204 +1636,6 @@ void undisplay_dollar(void)
|
||||
redrawWinline(curwin, curwin->w_cursor.lnum);
|
||||
}
|
||||
|
||||
/// Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
|
||||
/// Keep the cursor on the same character.
|
||||
/// type == INDENT_INC increase indent (for CTRL-T or <Tab>)
|
||||
/// type == INDENT_DEC decrease indent (for CTRL-D)
|
||||
/// type == INDENT_SET set indent to "amount"
|
||||
///
|
||||
/// @param round if true, round the indent to 'shiftwidth' (only with _INC and _Dec).
|
||||
/// @param call_changed_bytes call changed_bytes()
|
||||
void change_indent(int type, int amount, int round, bool call_changed_bytes)
|
||||
{
|
||||
int insstart_less; // reduction for Insstart.col
|
||||
colnr_T orig_col = 0; // init for GCC
|
||||
char *orig_line = NULL; // init for GCC
|
||||
|
||||
// MODE_VREPLACE state needs to know what the line was like before changing
|
||||
if (State & VREPLACE_FLAG) {
|
||||
orig_line = xstrnsave(get_cursor_line_ptr(), (size_t)get_cursor_line_len());
|
||||
orig_col = curwin->w_cursor.col;
|
||||
}
|
||||
|
||||
// for the following tricks we don't want list mode
|
||||
int save_p_list = curwin->w_p_list;
|
||||
curwin->w_p_list = false;
|
||||
colnr_T vc = getvcol_nolist(&curwin->w_cursor);
|
||||
int vcol = vc;
|
||||
|
||||
// For Replace mode we need to fix the replace stack later, which is only
|
||||
// possible when the cursor is in the indent. Remember the number of
|
||||
// characters before the cursor if it's possible.
|
||||
int start_col = curwin->w_cursor.col;
|
||||
|
||||
// determine offset from first non-blank
|
||||
int new_cursor_col = curwin->w_cursor.col;
|
||||
beginline(BL_WHITE);
|
||||
new_cursor_col -= curwin->w_cursor.col;
|
||||
|
||||
insstart_less = curwin->w_cursor.col;
|
||||
|
||||
// If the cursor is in the indent, compute how many screen columns the
|
||||
// cursor is to the left of the first non-blank.
|
||||
if (new_cursor_col < 0) {
|
||||
vcol = get_indent() - vcol;
|
||||
}
|
||||
|
||||
if (new_cursor_col > 0) { // can't fix replace stack
|
||||
start_col = -1;
|
||||
}
|
||||
|
||||
// Set the new indent. The cursor will be put on the first non-blank.
|
||||
if (type == INDENT_SET) {
|
||||
set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
|
||||
} else {
|
||||
int save_State = State;
|
||||
|
||||
// Avoid being called recursively.
|
||||
if (State & VREPLACE_FLAG) {
|
||||
State = MODE_INSERT;
|
||||
}
|
||||
shift_line(type == INDENT_DEC, round, 1, call_changed_bytes);
|
||||
State = save_State;
|
||||
}
|
||||
insstart_less -= curwin->w_cursor.col;
|
||||
|
||||
// Try to put cursor on same character.
|
||||
// If the cursor is at or after the first non-blank in the line,
|
||||
// compute the cursor column relative to the column of the first
|
||||
// non-blank character.
|
||||
// If we are not in insert mode, leave the cursor on the first non-blank.
|
||||
// If the cursor is before the first non-blank, position it relative
|
||||
// to the first non-blank, counted in screen columns.
|
||||
if (new_cursor_col >= 0) {
|
||||
// When changing the indent while the cursor is touching it, reset
|
||||
// Insstart_col to 0.
|
||||
if (new_cursor_col == 0) {
|
||||
insstart_less = MAXCOL;
|
||||
}
|
||||
new_cursor_col += curwin->w_cursor.col;
|
||||
} else if (!(State & MODE_INSERT)) {
|
||||
new_cursor_col = curwin->w_cursor.col;
|
||||
} else {
|
||||
// Compute the screen column where the cursor should be.
|
||||
vcol = get_indent() - vcol;
|
||||
int const end_vcol = (colnr_T)((vcol < 0) ? 0 : vcol);
|
||||
curwin->w_virtcol = end_vcol;
|
||||
|
||||
// Advance the cursor until we reach the right screen column.
|
||||
new_cursor_col = 0;
|
||||
char *const line = get_cursor_line_ptr();
|
||||
vcol = 0;
|
||||
if (*line != NUL) {
|
||||
CharsizeArg csarg;
|
||||
CSType cstype = init_charsize_arg(&csarg, curwin, 0, line);
|
||||
StrCharInfo ci = utf_ptr2StrCharInfo(line);
|
||||
while (true) {
|
||||
int next_vcol = vcol + win_charsize(cstype, vcol, ci.ptr, ci.chr.value, &csarg).width;
|
||||
if (next_vcol > end_vcol) {
|
||||
break;
|
||||
}
|
||||
vcol = next_vcol;
|
||||
ci = utfc_next(ci);
|
||||
if (*ci.ptr == NUL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_cursor_col = (int)(ci.ptr - line);
|
||||
}
|
||||
|
||||
// May need to insert spaces to be able to position the cursor on
|
||||
// the right screen column.
|
||||
if (vcol != (int)curwin->w_virtcol) {
|
||||
curwin->w_cursor.col = (colnr_T)new_cursor_col;
|
||||
const size_t ptrlen = (size_t)(curwin->w_virtcol - vcol);
|
||||
char *ptr = xmallocz(ptrlen);
|
||||
memset(ptr, ' ', ptrlen);
|
||||
new_cursor_col += (int)ptrlen;
|
||||
ins_str(ptr, ptrlen);
|
||||
xfree(ptr);
|
||||
}
|
||||
|
||||
// When changing the indent while the cursor is in it, reset
|
||||
// Insstart_col to 0.
|
||||
insstart_less = MAXCOL;
|
||||
}
|
||||
|
||||
curwin->w_p_list = save_p_list;
|
||||
curwin->w_cursor.col = MAX(0, (colnr_T)new_cursor_col);
|
||||
curwin->w_set_curswant = true;
|
||||
changed_cline_bef_curs(curwin);
|
||||
|
||||
// May have to adjust the start of the insert.
|
||||
if (State & MODE_INSERT) {
|
||||
if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) {
|
||||
if ((int)Insstart.col <= insstart_less) {
|
||||
Insstart.col = 0;
|
||||
} else {
|
||||
Insstart.col -= insstart_less;
|
||||
}
|
||||
}
|
||||
if ((int)ai_col <= insstart_less) {
|
||||
ai_col = 0;
|
||||
} else {
|
||||
ai_col -= insstart_less;
|
||||
}
|
||||
}
|
||||
|
||||
// For MODE_REPLACE state, may have to fix the replace stack, if it's
|
||||
// possible. If the number of characters before the cursor decreased, need
|
||||
// to pop a few characters from the replace stack.
|
||||
// If the number of characters before the cursor increased, need to push a
|
||||
// few NULs onto the replace stack.
|
||||
if (REPLACE_NORMAL(State) && start_col >= 0) {
|
||||
while (start_col > (int)curwin->w_cursor.col) {
|
||||
replace_join(0); // remove a NUL from the replace stack
|
||||
start_col--;
|
||||
}
|
||||
while (start_col < (int)curwin->w_cursor.col) {
|
||||
replace_push_nul();
|
||||
start_col++;
|
||||
}
|
||||
}
|
||||
|
||||
// For MODE_VREPLACE state, we also have to fix the replace stack. In this
|
||||
// case it is always possible because we backspace over the whole line and
|
||||
// then put it back again the way we wanted it.
|
||||
if (State & VREPLACE_FLAG) {
|
||||
// Save new line
|
||||
char *new_line = xstrnsave(get_cursor_line_ptr(), (size_t)get_cursor_line_len());
|
||||
|
||||
// We only put back the new line up to the cursor
|
||||
new_line[curwin->w_cursor.col] = NUL;
|
||||
int new_col = curwin->w_cursor.col;
|
||||
|
||||
// Put back original line
|
||||
ml_replace(curwin->w_cursor.lnum, orig_line, false);
|
||||
curwin->w_cursor.col = orig_col;
|
||||
|
||||
curbuf_splice_pending++;
|
||||
|
||||
// Backspace from cursor to start of line
|
||||
backspace_until_column(0);
|
||||
|
||||
// Insert new stuff into line again
|
||||
ins_bytes(new_line);
|
||||
|
||||
xfree(new_line);
|
||||
|
||||
curbuf_splice_pending--;
|
||||
|
||||
// TODO(bfredl): test for crazy edge cases, like we stand on a TAB or
|
||||
// something? does this even do the right text change then?
|
||||
int delta = orig_col - new_col;
|
||||
extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum - 1, new_col,
|
||||
delta < 0 ? -delta : 0,
|
||||
delta > 0 ? delta : 0,
|
||||
kExtmarkUndo);
|
||||
}
|
||||
}
|
||||
|
||||
/// Truncate the space at the end of a line. This is to be used only in an
|
||||
/// insert mode. It handles fixing the replace stack for MODE_REPLACE and
|
||||
/// MODE_VREPLACE modes.
|
||||
@@ -2885,7 +2687,7 @@ static int replace_pop_if_nul(void)
|
||||
/// encountered.
|
||||
///
|
||||
/// @param off offset for which NUL to remove
|
||||
static void replace_join(int off)
|
||||
void replace_join(int off)
|
||||
{
|
||||
for (ssize_t i = (ssize_t)kv_size(replace_stack); --i >= 0;) {
|
||||
if (kv_A(replace_stack, i) == NUL && off-- <= 0) {
|
||||
@@ -4403,80 +4205,6 @@ static int ins_ctrl_ey(int tc)
|
||||
return c;
|
||||
}
|
||||
|
||||
// Try to do some very smart auto-indenting.
|
||||
// Used when inserting a "normal" character.
|
||||
static void ins_try_si(int c)
|
||||
{
|
||||
pos_T *pos;
|
||||
|
||||
// do some very smart indenting when entering '{' or '}'
|
||||
if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) {
|
||||
pos_T old_pos;
|
||||
char *ptr;
|
||||
int i;
|
||||
bool temp;
|
||||
// for '}' set indent equal to indent of line containing matching '{'
|
||||
if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) {
|
||||
old_pos = curwin->w_cursor;
|
||||
// If the matching '{' has a ')' immediately before it (ignoring
|
||||
// white-space), then line up with the start of the line
|
||||
// containing the matching '(' if there is one. This handles the
|
||||
// case where an "if (..\n..) {" statement continues over multiple
|
||||
// lines -- webb
|
||||
ptr = ml_get(pos->lnum);
|
||||
i = pos->col;
|
||||
if (i > 0) { // skip blanks before '{'
|
||||
while (--i > 0 && ascii_iswhite(ptr[i])) {}
|
||||
}
|
||||
curwin->w_cursor.lnum = pos->lnum;
|
||||
curwin->w_cursor.col = i;
|
||||
if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) {
|
||||
curwin->w_cursor = *pos;
|
||||
}
|
||||
i = get_indent();
|
||||
curwin->w_cursor = old_pos;
|
||||
if (State & VREPLACE_FLAG) {
|
||||
change_indent(INDENT_SET, i, false, true);
|
||||
} else {
|
||||
set_indent(i, SIN_CHANGED);
|
||||
}
|
||||
} else if (curwin->w_cursor.col > 0) {
|
||||
// when inserting '{' after "O" reduce indent, but not
|
||||
// more than indent of previous line
|
||||
temp = true;
|
||||
if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) {
|
||||
old_pos = curwin->w_cursor;
|
||||
i = get_indent();
|
||||
while (curwin->w_cursor.lnum > 1) {
|
||||
ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum)));
|
||||
|
||||
// ignore empty lines and lines starting with '#'.
|
||||
if (*ptr != '#' && *ptr != NUL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (get_indent() >= i) {
|
||||
temp = false;
|
||||
}
|
||||
curwin->w_cursor = old_pos;
|
||||
}
|
||||
if (temp) {
|
||||
shift_line(true, false, 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set indent of '#' always to 0
|
||||
if (curwin->w_cursor.col > 0 && can_si && c == '#' && inindent(0)) {
|
||||
// remember current indent for next line
|
||||
old_indent = get_indent();
|
||||
set_indent(0, SIN_CHANGED);
|
||||
}
|
||||
|
||||
// Adjust ai_col, the char at this position can be deleted.
|
||||
ai_col = MIN(ai_col, curwin->w_cursor.col);
|
||||
}
|
||||
|
||||
// Get the value that w_virtcol would have when 'list' is off.
|
||||
// Unless 'cpo' contains the 'L' flag.
|
||||
colnr_T get_nolist_virtcol(void)
|
||||
|
Reference in New Issue
Block a user