mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38: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:
@@ -957,118 +957,6 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Copy the indent from ptr to the current line (and fill to size).
|
||||
/// Leaves the cursor on the first non-blank in the line.
|
||||
///
|
||||
/// @return true if the line was changed.
|
||||
bool copy_indent(int size, char *src)
|
||||
{
|
||||
char *p = NULL;
|
||||
char *line = NULL;
|
||||
int ind_len;
|
||||
int line_len = 0;
|
||||
int tab_pad;
|
||||
|
||||
// Round 1: compute the number of characters needed for the indent
|
||||
// Round 2: copy the characters.
|
||||
for (int round = 1; round <= 2; round++) {
|
||||
int todo = size;
|
||||
ind_len = 0;
|
||||
int ind_done = 0;
|
||||
int ind_col = 0;
|
||||
char *s = src;
|
||||
|
||||
// Count/copy the usable portion of the source line.
|
||||
while (todo > 0 && ascii_iswhite(*s)) {
|
||||
if (*s == TAB) {
|
||||
tab_pad = tabstop_padding(ind_done,
|
||||
curbuf->b_p_ts,
|
||||
curbuf->b_p_vts_array);
|
||||
|
||||
// Stop if this tab will overshoot the target.
|
||||
if (todo < tab_pad) {
|
||||
break;
|
||||
}
|
||||
todo -= tab_pad;
|
||||
ind_done += tab_pad;
|
||||
ind_col += tab_pad;
|
||||
} else {
|
||||
todo--;
|
||||
ind_done++;
|
||||
ind_col++;
|
||||
}
|
||||
ind_len++;
|
||||
|
||||
if (p != NULL) {
|
||||
*p++ = *s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
// Fill to next tabstop with a tab, if possible.
|
||||
tab_pad = tabstop_padding(ind_done, curbuf->b_p_ts, curbuf->b_p_vts_array);
|
||||
|
||||
if ((todo >= tab_pad) && !curbuf->b_p_et) {
|
||||
todo -= tab_pad;
|
||||
ind_len++;
|
||||
ind_col += tab_pad;
|
||||
|
||||
if (p != NULL) {
|
||||
*p++ = TAB;
|
||||
}
|
||||
}
|
||||
|
||||
// Add tabs required for indent.
|
||||
if (!curbuf->b_p_et) {
|
||||
while (true) {
|
||||
tab_pad = tabstop_padding(ind_col,
|
||||
curbuf->b_p_ts,
|
||||
curbuf->b_p_vts_array);
|
||||
if (todo < tab_pad) {
|
||||
break;
|
||||
}
|
||||
todo -= tab_pad;
|
||||
ind_len++;
|
||||
ind_col += tab_pad;
|
||||
if (p != NULL) {
|
||||
*p++ = TAB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Count/add spaces required for indent.
|
||||
while (todo > 0) {
|
||||
todo--;
|
||||
ind_len++;
|
||||
|
||||
if (p != NULL) {
|
||||
*p++ = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
// Allocate memory for the result: the copied indent, new indent
|
||||
// and the rest of the line.
|
||||
line_len = get_cursor_line_len() + 1;
|
||||
assert(ind_len + line_len >= 0);
|
||||
size_t line_size;
|
||||
STRICT_ADD(ind_len, line_len, &line_size, size_t);
|
||||
line = xmalloc(line_size);
|
||||
p = line;
|
||||
}
|
||||
}
|
||||
|
||||
// Append the original line
|
||||
memmove(p, get_cursor_line_ptr(), (size_t)line_len);
|
||||
|
||||
// Replace the line
|
||||
ml_replace(curwin->w_cursor.lnum, line, false);
|
||||
|
||||
// Put the cursor after the indent.
|
||||
curwin->w_cursor.col = ind_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// open_line: Add a new line below or above the current line.
|
||||
///
|
||||
/// For MODE_VREPLACE state, we only add a new line when we get to the end of
|
||||
|
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)
|
||||
|
@@ -777,20 +777,6 @@ static void f_charcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
get_col(argvars, rettv, true);
|
||||
}
|
||||
|
||||
/// "cindent(lnum)" function
|
||||
static void f_cindent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
pos_T pos = curwin->w_cursor;
|
||||
linenr_T lnum = tv_get_lnum(argvars);
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
rettv->vval.v_number = get_c_indent();
|
||||
curwin->w_cursor = pos;
|
||||
} else {
|
||||
rettv->vval.v_number = -1;
|
||||
}
|
||||
}
|
||||
|
||||
win_T *get_optional_window(typval_T *argvars, int idx)
|
||||
{
|
||||
if (argvars[idx].v_type == VAR_UNKNOWN) {
|
||||
@@ -3246,17 +3232,6 @@ static void f_hostname(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
rettv->vval.v_string = xstrdup(hostname);
|
||||
}
|
||||
|
||||
/// "indent()" function
|
||||
static void f_indent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
const linenr_T lnum = tv_get_lnum(argvars);
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||
rettv->vval.v_number = get_indent_lnum(lnum);
|
||||
} else {
|
||||
rettv->vval.v_number = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// "index()" function
|
||||
static void f_index(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
@@ -4415,20 +4390,6 @@ static void f_line2byte(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
}
|
||||
}
|
||||
|
||||
/// "lispindent(lnum)" function
|
||||
static void f_lispindent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
const pos_T pos = curwin->w_cursor;
|
||||
const linenr_T lnum = tv_get_lnum(argvars);
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
rettv->vval.v_number = get_lisp_indent();
|
||||
curwin->w_cursor = pos;
|
||||
} else {
|
||||
rettv->vval.v_number = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// "localtime()" function
|
||||
static void f_localtime(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "nvim/edit.h"
|
||||
#include "nvim/errors.h"
|
||||
#include "nvim/eval.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/eval/typval_defs.h"
|
||||
#include "nvim/ex_cmds_defs.h"
|
||||
#include "nvim/ex_docmd.h"
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/message.h"
|
||||
#include "nvim/move.h"
|
||||
#include "nvim/ops.h"
|
||||
#include "nvim/option.h"
|
||||
#include "nvim/option_defs.h"
|
||||
#include "nvim/option_vars.h"
|
||||
@@ -276,7 +278,7 @@ void tabstop_fromto(colnr_T start_col, colnr_T end_col, int ts_arg, const colnr_
|
||||
}
|
||||
|
||||
/// See if two tabstop arrays contain the same values.
|
||||
bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2)
|
||||
static bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2)
|
||||
{
|
||||
if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) {
|
||||
return false;
|
||||
@@ -977,12 +979,482 @@ bool inindent(int extra)
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Handle reindenting a block of lines.
|
||||
void op_reindent(oparg_T *oap, Indenter how)
|
||||
{
|
||||
int i = 0;
|
||||
linenr_T first_changed = 0;
|
||||
linenr_T last_changed = 0;
|
||||
linenr_T start_lnum = curwin->w_cursor.lnum;
|
||||
|
||||
// Don't even try when 'modifiable' is off.
|
||||
if (!MODIFIABLE(curbuf)) {
|
||||
emsg(_(e_modifiable));
|
||||
return;
|
||||
}
|
||||
|
||||
// Save for undo. Do this once for all lines, much faster than doing this
|
||||
// for each line separately, especially when undoing.
|
||||
if (u_savecommon(curbuf, start_lnum - 1, start_lnum + oap->line_count,
|
||||
start_lnum + oap->line_count, false) == OK) {
|
||||
int amount;
|
||||
for (i = oap->line_count - 1; i >= 0 && !got_int; i--) {
|
||||
// it's a slow thing to do, so give feedback so there's no worry
|
||||
// that the computer's just hung.
|
||||
|
||||
if (i > 1
|
||||
&& (i % 50 == 0 || i == oap->line_count - 1)
|
||||
&& oap->line_count > p_report) {
|
||||
smsg(0, _("%" PRId64 " lines to indent... "), (int64_t)i);
|
||||
}
|
||||
|
||||
// Be vi-compatible: For lisp indenting the first line is not
|
||||
// indented, unless there is only one line.
|
||||
if (i != oap->line_count - 1 || oap->line_count == 1
|
||||
|| how != get_lisp_indent) {
|
||||
char *l = skipwhite(get_cursor_line_ptr());
|
||||
if (*l == NUL) { // empty or blank line
|
||||
amount = 0;
|
||||
} else {
|
||||
amount = how(); // get the indent for this line
|
||||
}
|
||||
if (amount >= 0 && set_indent(amount, 0)) {
|
||||
// did change the indent, call changed_lines() later
|
||||
if (first_changed == 0) {
|
||||
first_changed = curwin->w_cursor.lnum;
|
||||
}
|
||||
last_changed = curwin->w_cursor.lnum;
|
||||
}
|
||||
}
|
||||
curwin->w_cursor.lnum++;
|
||||
curwin->w_cursor.col = 0; // make sure it's valid
|
||||
}
|
||||
}
|
||||
|
||||
// put cursor on first non-blank of indented line
|
||||
curwin->w_cursor.lnum = start_lnum;
|
||||
beginline(BL_SOL | BL_FIX);
|
||||
|
||||
// Mark changed lines so that they will be redrawn. When Visual
|
||||
// highlighting was present, need to continue until the last line. When
|
||||
// there is no change still need to remove the Visual highlighting.
|
||||
if (last_changed != 0) {
|
||||
changed_lines(curbuf, first_changed, 0,
|
||||
oap->is_VIsual ? start_lnum + oap->line_count
|
||||
: last_changed + 1, 0, true);
|
||||
} else if (oap->is_VIsual) {
|
||||
redraw_curbuf_later(UPD_INVERTED);
|
||||
}
|
||||
|
||||
if (oap->line_count > p_report) {
|
||||
i = oap->line_count - (i + 1);
|
||||
smsg(0, NGETTEXT("%" PRId64 " line indented ", "%" PRId64 " lines indented ", i), (int64_t)i);
|
||||
}
|
||||
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
|
||||
// set '[ and '] marks
|
||||
curbuf->b_op_start = oap->start;
|
||||
curbuf->b_op_end = oap->end;
|
||||
}
|
||||
}
|
||||
|
||||
/// @return true if lines starting with '#' should be left aligned.
|
||||
bool preprocs_left(void)
|
||||
{
|
||||
return ((curbuf->b_p_si && !curbuf->b_p_cin)
|
||||
|| (curbuf->b_p_cin && in_cinkeys('#', ' ', true)
|
||||
&& curbuf->b_ind_hash_comment == 0));
|
||||
}
|
||||
|
||||
/// @return true if the conditions are OK for smart indenting.
|
||||
bool may_do_si(void)
|
||||
{
|
||||
return curbuf->b_p_si && !curbuf->b_p_cin && *curbuf->b_p_inde == NUL && !p_paste;
|
||||
}
|
||||
|
||||
// Try to do some very smart auto-indenting.
|
||||
// Used when inserting a "normal" character.
|
||||
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);
|
||||
}
|
||||
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy the indent from ptr to the current line (and fill to size).
|
||||
/// Leaves the cursor on the first non-blank in the line.
|
||||
///
|
||||
/// @return true if the line was changed.
|
||||
bool copy_indent(int size, char *src)
|
||||
{
|
||||
char *p = NULL;
|
||||
char *line = NULL;
|
||||
int ind_len;
|
||||
int line_len = 0;
|
||||
int tab_pad;
|
||||
|
||||
// Round 1: compute the number of characters needed for the indent
|
||||
// Round 2: copy the characters.
|
||||
for (int round = 1; round <= 2; round++) {
|
||||
int todo = size;
|
||||
ind_len = 0;
|
||||
int ind_done = 0;
|
||||
int ind_col = 0;
|
||||
char *s = src;
|
||||
|
||||
// Count/copy the usable portion of the source line.
|
||||
while (todo > 0 && ascii_iswhite(*s)) {
|
||||
if (*s == TAB) {
|
||||
tab_pad = tabstop_padding(ind_done,
|
||||
curbuf->b_p_ts,
|
||||
curbuf->b_p_vts_array);
|
||||
|
||||
// Stop if this tab will overshoot the target.
|
||||
if (todo < tab_pad) {
|
||||
break;
|
||||
}
|
||||
todo -= tab_pad;
|
||||
ind_done += tab_pad;
|
||||
ind_col += tab_pad;
|
||||
} else {
|
||||
todo--;
|
||||
ind_done++;
|
||||
ind_col++;
|
||||
}
|
||||
ind_len++;
|
||||
|
||||
if (p != NULL) {
|
||||
*p++ = *s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
// Fill to next tabstop with a tab, if possible.
|
||||
tab_pad = tabstop_padding(ind_done, curbuf->b_p_ts, curbuf->b_p_vts_array);
|
||||
|
||||
if ((todo >= tab_pad) && !curbuf->b_p_et) {
|
||||
todo -= tab_pad;
|
||||
ind_len++;
|
||||
ind_col += tab_pad;
|
||||
|
||||
if (p != NULL) {
|
||||
*p++ = TAB;
|
||||
}
|
||||
}
|
||||
|
||||
// Add tabs required for indent.
|
||||
if (!curbuf->b_p_et) {
|
||||
while (true) {
|
||||
tab_pad = tabstop_padding(ind_col,
|
||||
curbuf->b_p_ts,
|
||||
curbuf->b_p_vts_array);
|
||||
if (todo < tab_pad) {
|
||||
break;
|
||||
}
|
||||
todo -= tab_pad;
|
||||
ind_len++;
|
||||
ind_col += tab_pad;
|
||||
if (p != NULL) {
|
||||
*p++ = TAB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Count/add spaces required for indent.
|
||||
while (todo > 0) {
|
||||
todo--;
|
||||
ind_len++;
|
||||
|
||||
if (p != NULL) {
|
||||
*p++ = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
// Allocate memory for the result: the copied indent, new indent
|
||||
// and the rest of the line.
|
||||
line_len = get_cursor_line_len() + 1;
|
||||
assert(ind_len + line_len >= 0);
|
||||
size_t line_size;
|
||||
STRICT_ADD(ind_len, line_len, &line_size, size_t);
|
||||
line = xmalloc(line_size);
|
||||
p = line;
|
||||
}
|
||||
}
|
||||
|
||||
// Append the original line
|
||||
memmove(p, get_cursor_line_ptr(), (size_t)line_len);
|
||||
|
||||
// Replace the line
|
||||
ml_replace(curwin->w_cursor.lnum, line, false);
|
||||
|
||||
// Put the cursor after the indent.
|
||||
curwin->w_cursor.col = ind_len;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Give a "resulting text too long" error and maybe set got_int.
|
||||
static void emsg_text_too_long(void)
|
||||
{
|
||||
@@ -1474,3 +1946,28 @@ void fix_indent(void)
|
||||
do_c_expr_indent();
|
||||
}
|
||||
}
|
||||
|
||||
/// "indent()" function
|
||||
void f_indent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
const linenr_T lnum = tv_get_lnum(argvars);
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||
rettv->vval.v_number = get_indent_lnum(lnum);
|
||||
} else {
|
||||
rettv->vval.v_number = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// "lispindent(lnum)" function
|
||||
void f_lispindent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
const pos_T pos = curwin->w_cursor;
|
||||
const linenr_T lnum = tv_get_lnum(argvars);
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
rettv->vval.v_number = get_lisp_indent();
|
||||
curwin->w_cursor = pos;
|
||||
} else {
|
||||
rettv->vval.v_number = -1;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/normal_defs.h"
|
||||
#include "nvim/pos_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/types_defs.h" // IWYU pragma: keep
|
||||
|
||||
@@ -14,6 +15,8 @@ enum {
|
||||
SIN_NOMARK = 8, ///< don't adjust extmarks
|
||||
};
|
||||
|
||||
typedef int (*Indenter)(void);
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "indent.h.generated.h"
|
||||
#endif
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "nvim/charset.h"
|
||||
#include "nvim/cursor.h"
|
||||
#include "nvim/edit.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/globals.h"
|
||||
#include "nvim/indent.h"
|
||||
#include "nvim/indent_c.h"
|
||||
@@ -3932,3 +3933,17 @@ void do_c_expr_indent(void)
|
||||
fixthisline(get_c_indent);
|
||||
}
|
||||
}
|
||||
|
||||
/// "cindent(lnum)" function
|
||||
void f_cindent(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
pos_T pos = curwin->w_cursor;
|
||||
linenr_T lnum = tv_get_lnum(argvars);
|
||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
rettv->vval.v_number = get_c_indent();
|
||||
curwin->w_cursor = pos;
|
||||
} else {
|
||||
rettv->vval.v_number = -1;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "nvim/eval/typval_defs.h"
|
||||
#include "nvim/pos_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/types_defs.h" // IWYU pragma: keep
|
||||
|
||||
|
@@ -723,84 +723,6 @@ static void block_insert(oparg_T *oap, const char *s, size_t slen, bool b_insert
|
||||
changed_lines(curbuf, oap->start.lnum + 1, 0, oap->end.lnum + 1, 0, true);
|
||||
}
|
||||
|
||||
/// Handle reindenting a block of lines.
|
||||
void op_reindent(oparg_T *oap, Indenter how)
|
||||
{
|
||||
int i = 0;
|
||||
linenr_T first_changed = 0;
|
||||
linenr_T last_changed = 0;
|
||||
linenr_T start_lnum = curwin->w_cursor.lnum;
|
||||
|
||||
// Don't even try when 'modifiable' is off.
|
||||
if (!MODIFIABLE(curbuf)) {
|
||||
emsg(_(e_modifiable));
|
||||
return;
|
||||
}
|
||||
|
||||
// Save for undo. Do this once for all lines, much faster than doing this
|
||||
// for each line separately, especially when undoing.
|
||||
if (u_savecommon(curbuf, start_lnum - 1, start_lnum + oap->line_count,
|
||||
start_lnum + oap->line_count, false) == OK) {
|
||||
int amount;
|
||||
for (i = oap->line_count - 1; i >= 0 && !got_int; i--) {
|
||||
// it's a slow thing to do, so give feedback so there's no worry
|
||||
// that the computer's just hung.
|
||||
|
||||
if (i > 1
|
||||
&& (i % 50 == 0 || i == oap->line_count - 1)
|
||||
&& oap->line_count > p_report) {
|
||||
smsg(0, _("%" PRId64 " lines to indent... "), (int64_t)i);
|
||||
}
|
||||
|
||||
// Be vi-compatible: For lisp indenting the first line is not
|
||||
// indented, unless there is only one line.
|
||||
if (i != oap->line_count - 1 || oap->line_count == 1
|
||||
|| how != get_lisp_indent) {
|
||||
char *l = skipwhite(get_cursor_line_ptr());
|
||||
if (*l == NUL) { // empty or blank line
|
||||
amount = 0;
|
||||
} else {
|
||||
amount = how(); // get the indent for this line
|
||||
}
|
||||
if (amount >= 0 && set_indent(amount, 0)) {
|
||||
// did change the indent, call changed_lines() later
|
||||
if (first_changed == 0) {
|
||||
first_changed = curwin->w_cursor.lnum;
|
||||
}
|
||||
last_changed = curwin->w_cursor.lnum;
|
||||
}
|
||||
}
|
||||
curwin->w_cursor.lnum++;
|
||||
curwin->w_cursor.col = 0; // make sure it's valid
|
||||
}
|
||||
}
|
||||
|
||||
// put cursor on first non-blank of indented line
|
||||
curwin->w_cursor.lnum = start_lnum;
|
||||
beginline(BL_SOL | BL_FIX);
|
||||
|
||||
// Mark changed lines so that they will be redrawn. When Visual
|
||||
// highlighting was present, need to continue until the last line. When
|
||||
// there is no change still need to remove the Visual highlighting.
|
||||
if (last_changed != 0) {
|
||||
changed_lines(curbuf, first_changed, 0,
|
||||
oap->is_VIsual ? start_lnum + oap->line_count
|
||||
: last_changed + 1, 0, true);
|
||||
} else if (oap->is_VIsual) {
|
||||
redraw_curbuf_later(UPD_INVERTED);
|
||||
}
|
||||
|
||||
if (oap->line_count > p_report) {
|
||||
i = oap->line_count - (i + 1);
|
||||
smsg(0, NGETTEXT("%" PRId64 " line indented ", "%" PRId64 " lines indented ", i), (int64_t)i);
|
||||
}
|
||||
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
|
||||
// set '[ and '] marks
|
||||
curbuf->b_op_start = oap->start;
|
||||
curbuf->b_op_end = oap->end;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the last expression line here, for repeating.
|
||||
static char *expr_line = NULL;
|
||||
|
||||
@@ -3738,14 +3660,6 @@ void adjust_cursor_eol(void)
|
||||
}
|
||||
}
|
||||
|
||||
/// @return true if lines starting with '#' should be left aligned.
|
||||
bool preprocs_left(void)
|
||||
{
|
||||
return ((curbuf->b_p_si && !curbuf->b_p_cin)
|
||||
|| (curbuf->b_p_cin && in_cinkeys('#', ' ', true)
|
||||
&& curbuf->b_ind_hash_comment == 0));
|
||||
}
|
||||
|
||||
/// @return the character name of the register with the given number
|
||||
int get_register_name(int num)
|
||||
{
|
||||
|
@@ -33,8 +33,6 @@ struct block_def {
|
||||
colnr_T start_char_vcols; ///< number of vcols of pre-block char
|
||||
};
|
||||
|
||||
typedef int (*Indenter)(void);
|
||||
|
||||
/// flags for do_put()
|
||||
enum {
|
||||
PUT_FIXINDENT = 1, ///< make indent look nice
|
||||
|
Reference in New Issue
Block a user