aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/indent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/indent.c')
-rw-r--r--src/nvim/indent.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index efbfea33aa..fb277b25fd 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -13,6 +13,7 @@
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/mark.h"
+#include "nvim/extmark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
@@ -55,7 +56,8 @@ int get_indent_buf(buf_T *buf, linenr_T lnum)
// Count the size (in window cells) of the indent in line "ptr", with
// 'tabstop' at "ts".
// If @param list is TRUE, count only screen size for tabs.
-int get_indent_str(char_u *ptr, int ts, int list)
+int get_indent_str(const char_u *ptr, int ts, int list)
+ FUNC_ATTR_NONNULL_ALL
{
int count = 0;
@@ -88,6 +90,7 @@ int get_indent_str(char_u *ptr, int ts, int list)
// SIN_CHANGED: call changed_bytes() if the line was changed.
// SIN_INSERT: insert the indent in front of the line.
// SIN_UNDO: save line for undo before changing it.
+// SIN_NOMARK: don't move extmarks (because just after ml_append or something)
// @param size measured in spaces
// Returns true if the line was changed.
int set_indent(int size, int flags)
@@ -205,6 +208,7 @@ int set_indent(int size, int flags)
// If 'preserveindent' and 'expandtab' are both set keep the original
// characters and allocate accordingly. We will fill the rest with spaces
// after the if (!curbuf->b_p_et) below.
+ int skipcols = 0; // number of columns (in bytes) that were presved
if (orig_char_len != -1) {
int newline_size; // = orig_char_len + size - ind_done + line_len
STRICT_ADD(orig_char_len, size, &newline_size, int);
@@ -219,6 +223,7 @@ int set_indent(int size, int flags)
ind_len = orig_char_len + todo;
p = oldline;
s = newline;
+ skipcols = orig_char_len;
while (orig_char_len > 0) {
*s++ = *p++;
@@ -263,6 +268,7 @@ int set_indent(int size, int flags)
ind_done++;
}
*s++ = *p++;
+ skipcols++;
}
// Fill to next tabstop with a tab, if possible.
@@ -290,6 +296,13 @@ int set_indent(int size, int flags)
// Replace the line (unless undo fails).
if (!(flags & SIN_UNDO) || (u_savesub(curwin->w_cursor.lnum) == OK)) {
ml_replace(curwin->w_cursor.lnum, newline, false);
+ if (!(flags & SIN_NOMARK)) {
+ extmark_splice(curbuf,
+ (int)curwin->w_cursor.lnum-1, skipcols,
+ 0, (int)(p-oldline) - skipcols,
+ 0, (int)(s-newline) - skipcols,
+ kExtmarkUndo);
+ }
if (flags & SIN_CHANGED) {
changed_bytes(curwin->w_cursor.lnum, 0);
@@ -363,12 +376,12 @@ int get_number_indent(linenr_T lnum)
* parameters into account. Window must be specified, since it is not
* necessarily always the current one.
*/
-int get_breakindent_win(win_T *wp, char_u *line)
- FUNC_ATTR_NONNULL_ARG(1)
+int get_breakindent_win(win_T *wp, const char_u *line)
+ FUNC_ATTR_NONNULL_ALL
{
static int prev_indent = 0; // Cached indent value.
static long prev_ts = 0; // Cached tabstop value.
- static char_u *prev_line = NULL; // cached pointer to line.
+ static const char_u *prev_line = NULL; // cached pointer to line.
static varnumber_T prev_tick = 0; // Changedtick of cached value.
int bri = 0;
// window width minus window margin space, i.e. what rests for text
@@ -377,7 +390,7 @@ int get_breakindent_win(win_T *wp, char_u *line)
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
? number_width(wp) + 1 : 0);
- /* used cached indent, unless pointer or 'tabstop' changed */
+ // used cached indent, unless pointer or 'tabstop' changed
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|| prev_tick != buf_get_changedtick(wp->w_buffer)) {
prev_line = line;
@@ -385,23 +398,24 @@ int get_breakindent_win(win_T *wp, char_u *line)
prev_tick = buf_get_changedtick(wp->w_buffer);
prev_indent = get_indent_str(line, (int)wp->w_buffer->b_p_ts, wp->w_p_list);
}
- bri = prev_indent + wp->w_p_brishift;
+ bri = prev_indent + wp->w_briopt_shift;
- /* indent minus the length of the showbreak string */
- if (wp->w_p_brisbr)
+ // indent minus the length of the showbreak string
+ if (wp->w_briopt_sbr) {
bri -= vim_strsize(p_sbr);
-
- /* Add offset for number column, if 'n' is in 'cpoptions' */
+ }
+ // Add offset for number column, if 'n' is in 'cpoptions'
bri += win_col_off2(wp);
- /* never indent past left window margin */
- if (bri < 0)
+ // never indent past left window margin
+ if (bri < 0) {
bri = 0;
- /* always leave at least bri_min characters on the left,
- * if text width is sufficient */
- else if (bri > eff_wwidth - wp->w_p_brimin)
- bri = (eff_wwidth - wp->w_p_brimin < 0)
- ? 0 : eff_wwidth - wp->w_p_brimin;
+ } else if (bri > eff_wwidth - wp->w_briopt_min) {
+ // always leave at least bri_min characters on the left,
+ // if text width is sufficient
+ bri = (eff_wwidth - wp->w_briopt_min < 0)
+ ? 0 : eff_wwidth - wp->w_briopt_min;
+ }
return bri;
}