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:
Jan Edmund Lazo
2025-07-10 23:16:33 -04:00
parent 441d222c0d
commit fadbc0e717
9 changed files with 518 additions and 513 deletions

View File

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