aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/clint.py7
-rw-r--r--src/nvim/api/buffer.c52
-rw-r--r--src/nvim/buffer.c9
-rw-r--r--src/nvim/buffer_defs.h3
-rw-r--r--src/nvim/charset.c2
-rw-r--r--src/nvim/cursor.c5
-rw-r--r--src/nvim/diff.c22
-rw-r--r--src/nvim/digraph.c2
-rw-r--r--src/nvim/edit.c273
-rw-r--r--src/nvim/eval.c35
-rw-r--r--src/nvim/ex_cmds.c187
-rw-r--r--src/nvim/ex_docmd.c22
-rw-r--r--src/nvim/ex_getln.c53
-rw-r--r--src/nvim/farsi.c2
-rw-r--r--src/nvim/fold.c442
-rw-r--r--src/nvim/getchar.c14
-rw-r--r--src/nvim/globals.h20
-rw-r--r--src/nvim/hardcopy.c139
-rw-r--r--src/nvim/hardcopy.h13
-rw-r--r--src/nvim/macros.h2
-rw-r--r--src/nvim/mark.c2
-rw-r--r--src/nvim/mbyte.c6
-rw-r--r--src/nvim/mbyte.h1
-rw-r--r--src/nvim/memline.c2
-rw-r--r--src/nvim/menu.c25
-rw-r--r--src/nvim/message.c40
-rw-r--r--src/nvim/misc1.c168
-rw-r--r--src/nvim/mouse.c13
-rw-r--r--src/nvim/normal.c14
-rw-r--r--src/nvim/ops.c147
-rw-r--r--src/nvim/option.c104
-rw-r--r--src/nvim/options.lua6
-rw-r--r--src/nvim/quickfix.c11
-rw-r--r--src/nvim/regexp.c109
-rw-r--r--src/nvim/regexp_nfa.c14
-rw-r--r--src/nvim/screen.c118
-rw-r--r--src/nvim/search.c110
-rw-r--r--src/nvim/spell.c277
-rw-r--r--src/nvim/state.c6
-rw-r--r--src/nvim/syntax.c917
-rw-r--r--src/nvim/syntax.h1
-rw-r--r--src/nvim/syntax_defs.h32
-rw-r--r--src/nvim/testdir/Makefile2
-rw-r--r--src/nvim/testdir/runtest.vim1
-rw-r--r--src/nvim/testdir/setup.vim1
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_compiler.vim49
-rw-r--r--src/nvim/testdir/test_getvar.vim104
-rw-r--r--src/nvim/testdir/test_highlight.vim535
-rw-r--r--src/nvim/testdir/test_quickfix.vim33
-rw-r--r--src/nvim/testdir/test_visual.vim125
-rw-r--r--src/nvim/testdir/test_window_cmd.vim90
-rw-r--r--src/nvim/testdir/view_util.vim21
-rw-r--r--src/nvim/undo.c9
-rw-r--r--src/nvim/window.c64
55 files changed, 2653 insertions, 1809 deletions
diff --git a/src/clint.py b/src/clint.py
index c0cedc0e5b..9fd93ce143 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -3299,6 +3299,13 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
error(filename, linenum, 'readability/bool', 4,
'Use %s instead of %s.' % (token.lower(), token))
+ # Detect MAYBE
+ match = Search(r'\b(MAYBE)\b', line)
+ if match:
+ token = match.group(1)
+ error(filename, linenum, 'readability/bool', 4,
+ 'Use kNONE from TriState instead of %s.' % token)
+
# Detect preincrement/predecrement
match = Match(r'^\s*(?:\+\+|--)', line)
if match:
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 8ff24b877e..67a4b70c9e 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -31,11 +31,27 @@
# include "api/buffer.c.generated.h"
#endif
+
+/// \defgroup api-buffer
+///
+/// Unloaded Buffers:~
+///
+/// Buffers may be unloaded by the |:bunload| command or the buffer's
+/// |'bufhidden'| option. When a buffer is unloaded its file contents are freed
+/// from memory and vim cannot operate on the buffer lines until it is reloaded
+/// (usually by opening the buffer again in a new window). API methods such as
+/// |nvim_buf_get_lines()| and |nvim_buf_line_count()| will be affected.
+///
+/// You can use |nvim_buf_is_loaded()| or |nvim_buf_line_count()| to check
+/// whether a buffer is loaded.
+
+
/// Gets the buffer line count
///
/// @param buffer Buffer handle
/// @param[out] err Error details, if any
-/// @return Line count
+/// @return Line count, or \`0` if the buffer has been unloaded (see
+/// |api-buffer|).
Integer nvim_buf_line_count(Buffer buffer, Error *err)
FUNC_API_SINCE(1)
{
@@ -45,6 +61,11 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err)
return 0;
}
+ // return sentinel value if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return 0;
+ }
+
return buf->b_ml.ml_line_count;
}
@@ -205,7 +226,8 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
/// @param end Last line index (exclusive)
/// @param strict_indexing Whether out-of-bounds should be an error.
/// @param[out] err Error details, if any
-/// @return Array of lines
+/// @return Array of lines. If the buffer has been unloaded then an empty array
+/// will be returned instead. (See |api-buffer|.)
ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
Buffer buffer,
Integer start,
@@ -221,6 +243,11 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
return rv;
}
+ // return sentinel value if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return rv;
+ }
+
bool oob = false;
start = normalize_index(buf, start, &oob);
end = normalize_index(buf, end, &oob);
@@ -745,10 +772,27 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err)
}
}
-/// Checks if a buffer is valid
+/// Checks if a buffer is valid and loaded. See |api-buffer| for more info
+/// about unloaded buffers.
+///
+/// @param buffer Buffer handle
+/// @return true if the buffer is valid and loaded, false otherwise.
+Boolean nvim_buf_is_loaded(Buffer buffer)
+ FUNC_API_SINCE(5)
+{
+ Error stub = ERROR_INIT;
+ buf_T *buf = find_buffer_by_handle(buffer, &stub);
+ api_clear_error(&stub);
+ return buf && buf->b_ml.ml_mfp != NULL;
+}
+
+/// Checks if a buffer is valid.
+///
+/// @note Even if a buffer is valid it may have been unloaded. See |api-buffer|
+/// for more info about unloaded buffers.
///
/// @param buffer Buffer handle
-/// @return true if the buffer is valid, false otherwise
+/// @return true if the buffer is valid, false otherwise.
Boolean nvim_buf_is_valid(Buffer buffer)
FUNC_API_SINCE(1)
{
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index a8d29a3a53..71e04ec0fb 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -3220,10 +3220,11 @@ int build_stl_str_hl(
// Get the byte value now, in case we need it below. This is more
// efficient than making a copy of the line.
int byteval;
- if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr))
+ if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr)) {
byteval = 0;
- else
- byteval = (*mb_ptr2char)(line_ptr + wp->w_cursor.col);
+ } else {
+ byteval = utf_ptr2char(line_ptr + wp->w_cursor.col);
+ }
int groupdepth = 0;
@@ -3603,7 +3604,7 @@ int build_stl_str_hl(
// Store the current buffer number as a string variable
vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum);
- set_internal_string_var((char_u *)"actual_curbuf", tmp);
+ set_internal_string_var((char_u *)"g:actual_curbuf", tmp);
buf_T *o_curbuf = curbuf;
win_T *o_curwin = curwin;
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 057f99e341..9ff62a80af 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -94,6 +94,7 @@ typedef struct {
typedef struct window_S win_T;
typedef struct wininfo_S wininfo_T;
typedef struct frame_S frame_T;
+typedef uint16_t disptick_T; // display tick type
// for struct memline (it needs memfile_T)
#include "nvim/memline_defs.h"
@@ -425,7 +426,7 @@ typedef struct {
synstate_T *b_sst_firstfree;
int b_sst_freecount;
linenr_T b_sst_check_lnum;
- uint16_t b_sst_lasttick; /* last display tick */
+ disptick_T b_sst_lasttick; // last display tick
// for spell checking
garray_T b_langp; // list of pointers to slang_T, see spell.c
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 231bff26e8..f1b3be6b46 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1379,7 +1379,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
ptr = ml_get_buf(wp->w_buffer, pos->lnum, false);
if (pos->col < (colnr_T)STRLEN(ptr)) {
- int c = (*mb_ptr2char)(ptr + pos->col);
+ int c = utf_ptr2char(ptr + pos->col);
if ((c != TAB) && vim_isprintc(c)) {
endadd = (colnr_T)(char2cells(c) - 1);
if (coladd > endadd) {
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 177f167d74..0fda941a51 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -476,9 +476,7 @@ bool leftcol_changed(void)
int gchar_cursor(void)
{
- if (has_mbyte)
- return (*mb_ptr2char)(get_cursor_pos_ptr());
- return (int)*get_cursor_pos_ptr();
+ return utf_ptr2char(get_cursor_pos_ptr());
}
/*
@@ -507,4 +505,3 @@ char_u *get_cursor_pos_ptr(void)
return ml_get_buf(curbuf, curwin->w_cursor.lnum, false) +
curwin->w_cursor.col;
}
-
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 61e0b76558..8699c16351 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -48,9 +48,9 @@ static int diff_flags = DIFF_FILLER;
#define LBUFLEN 50 // length of line in diff file
-// TRUE when "diff -a" works, FALSE when it doesn't work, MAYBE when not
-// checked yet
-static int diff_a_works = MAYBE;
+// kTrue when "diff -a" works, kFalse when it doesn't work,
+// kNone when not checked yet
+static TriState diff_a_works = kNone;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -686,9 +686,9 @@ void ex_diffupdate(exarg_T *eap)
// there are differences.
// May try twice, first with "-a" and then without.
int io_error = false;
- bool ok = false;
+ TriState ok = kFalse;
for (;;) {
- ok = false;
+ ok = kFalse;
FILE *fd = mch_fopen(tmp_orig, "w");
if (fd == NULL) {
@@ -722,7 +722,7 @@ void ex_diffupdate(exarg_T *eap)
}
if (STRNCMP(linebuf, "1c1", 3) == 0) {
- ok = TRUE;
+ ok = kTrue;
}
}
fclose(fd);
@@ -739,7 +739,7 @@ void ex_diffupdate(exarg_T *eap)
}
// If we checked if "-a" works already, break here.
- if (diff_a_works != MAYBE) {
+ if (diff_a_works != kNone) {
break;
}
diff_a_works = ok;
@@ -755,7 +755,7 @@ void ex_diffupdate(exarg_T *eap)
EMSG(_("E810: Cannot read or write temp files"));
}
EMSG(_("E97: Cannot create diffs"));
- diff_a_works = MAYBE;
+ diff_a_works = kNone;
goto theend;
}
@@ -830,7 +830,7 @@ static void diff_file(const char *const tmp_orig, const char *const tmp_new,
* differences are of no use. Ignore errors, diff returns
* non-zero when differences have been found. */
vim_snprintf(cmd, len, "diff %s%s%s%s%s %s",
- diff_a_works ? "-a " : "",
+ diff_a_works == kFalse ? "" : "-a ",
"",
(diff_flags & DIFF_IWHITE) ? "-b " : "",
(diff_flags & DIFF_ICASE) ? "-i " : "",
@@ -1486,7 +1486,7 @@ int diff_check(win_T *wp, linenr_T lnum)
}
// A closed fold never has filler lines.
- if (hasFoldingWin(wp, lnum, NULL, NULL, TRUE, NULL)) {
+ if (hasFoldingWin(wp, lnum, NULL, NULL, true, NULL)) {
return 0;
}
@@ -1793,7 +1793,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin)
check_topfill(towin, false);
(void)hasFoldingWin(towin, towin->w_topline, &towin->w_topline,
- NULL, TRUE, NULL);
+ NULL, true, NULL);
}
/// This is called when 'diffopt' is changed.
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index 218a3f0604..c0915224e5 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.c
@@ -1536,7 +1536,7 @@ static int getexactdigraph(int char1, int char2, int meta_char)
to = string_convert(&vc, buf, &len);
if (to != NULL) {
- retval = (*mb_ptr2char)(to);
+ retval = utf_ptr2char(to);
xfree(to);
}
(void)convert_setup(&vc, NULL, NULL);
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index bf80f12bd0..0d99aa8fb2 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -227,7 +227,7 @@ static int last_insert_skip; /* nr of chars in front of previous insert */
static int new_insert_skip; /* nr of chars in front of current insert */
static int did_restart_edit; /* "restart_edit" when calling edit() */
-static int can_cindent; /* may do cindenting on this line */
+static bool can_cindent; // may do cindenting on this line
static int old_indent = 0; /* for ^^D command in insert mode */
@@ -240,10 +240,10 @@ static int ins_need_undo; /* call u_save() before inserting a
char. Set when edit() is called.
after that arrow_used is used. */
-static int did_add_space = FALSE; /* auto_format() added an extra space
- under the cursor */
-static int dont_sync_undo = false; // CTRL-G U prevents syncing undo
- // for the next left/right cursor
+static bool did_add_space = false; // auto_format() added an extra space
+ // under the cursor
+static TriState dont_sync_undo = kFalse; // CTRL-G U prevents syncing undo
+ // for the next left/right cursor
static linenr_T o_lnum = 0;
@@ -595,10 +595,10 @@ static int insert_check(VimState *state)
s->lastc = s->c; // remember previous char for CTRL-D
// After using CTRL-G U the next cursor key will not break undo.
- if (dont_sync_undo == MAYBE) {
- dont_sync_undo = true;
+ if (dont_sync_undo == kNone) {
+ dont_sync_undo = kTrue;
} else {
- dont_sync_undo = false;
+ dont_sync_undo = kFalse;
}
return 1;
@@ -997,7 +997,7 @@ static int insert_handle_key(InsertState *s)
if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) {
ins_s_left();
} else {
- ins_left(dont_sync_undo == false);
+ ins_left(dont_sync_undo == kFalse);
}
break;
@@ -1010,7 +1010,7 @@ static int insert_handle_key(InsertState *s)
if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) {
ins_s_right();
} else {
- ins_right(dont_sync_undo == false);
+ ins_right(dont_sync_undo == kFalse);
}
break;
@@ -1766,8 +1766,8 @@ change_indent (
/* We only put back the new line up to the cursor */
new_line[curwin->w_cursor.col] = NUL;
- /* Put back original line */
- ml_replace(curwin->w_cursor.lnum, orig_line, FALSE);
+ // Put back original line
+ ml_replace(curwin->w_cursor.lnum, orig_line, false);
curwin->w_cursor.col = orig_col;
/* Backspace from cursor to start of line */
@@ -2311,24 +2311,14 @@ static void ins_compl_longest_match(compl_T *match)
p = compl_leader;
s = match->cp_str;
while (*p != NUL) {
- if (has_mbyte) {
- c1 = mb_ptr2char(p);
- c2 = mb_ptr2char(s);
- } else {
- c1 = *p;
- c2 = *s;
- }
- if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2))
- : (c1 != c2)) {
+ c1 = utf_ptr2char(p);
+ c2 = utf_ptr2char(s);
+
+ if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2)) : (c1 != c2)) {
break;
}
- if (has_mbyte) {
- MB_PTR_ADV(p);
- MB_PTR_ADV(s);
- } else {
- ++p;
- ++s;
- }
+ MB_PTR_ADV(p);
+ MB_PTR_ADV(s);
}
if (*p != NUL) {
@@ -4456,7 +4446,7 @@ static int ins_complete(int c, bool enable_pum)
int save_w_wrow;
int save_w_leftcol;
int insert_match;
- int save_did_ai = did_ai;
+ const bool save_did_ai = did_ai;
compl_direction = ins_compl_key2dir(c);
insert_match = ins_compl_use_match(c);
@@ -4464,12 +4454,13 @@ static int ins_complete(int c, bool enable_pum)
if (!compl_started) {
/* First time we hit ^N or ^P (in a row, I mean) */
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
- if (stop_arrow() == FAIL)
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
+ if (stop_arrow() == FAIL) {
return FAIL;
+ }
line = ml_get(curwin->w_cursor.lnum);
curs_col = curwin->w_cursor.col;
@@ -5269,10 +5260,10 @@ insertchar (
}
end_comment_pending = NUL;
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
// If there's any pending input, grab up to INPUT_BUFLEN at once.
// This speeds up normal text input considerably.
@@ -5367,7 +5358,7 @@ internal_format (
{
int cc;
int save_char = NUL;
- int haveto_redraw = FALSE;
+ bool haveto_redraw = false;
int fo_ins_blank = has_format_option(FO_INS_BLANK);
int fo_multibyte = has_format_option(FO_MBYTE_BREAK);
int fo_white_par = has_format_option(FO_WHITE_PAR);
@@ -5655,13 +5646,13 @@ internal_format (
curwin->w_cursor.col = len;
}
- haveto_redraw = TRUE;
- can_cindent = TRUE;
- /* moved the cursor, don't autoindent or cindent now */
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ haveto_redraw = true;
+ can_cindent = true;
+ // moved the cursor, don't autoindent or cindent now
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
line_breakcheck();
}
@@ -5702,8 +5693,8 @@ auto_format (
pos = curwin->w_cursor;
old = get_cursor_line_ptr();
- /* may remove added space */
- check_auto_format(FALSE);
+ // may remove added space
+ check_auto_format(false);
/* Don't format in Insert mode when the cursor is on a trailing blank, the
* user might insert normal text next. Also skip formatting when "1" is
@@ -5769,12 +5760,13 @@ auto_format (
pnew = vim_strnsave(new, len + 2);
pnew[len] = ' ';
pnew[len + 1] = NUL;
- ml_replace(curwin->w_cursor.lnum, pnew, FALSE);
- /* remove the space later */
- did_add_space = TRUE;
- } else
- /* may remove added space */
- check_auto_format(FALSE);
+ ml_replace(curwin->w_cursor.lnum, pnew, false);
+ // remove the space later
+ did_add_space = true;
+ } else {
+ // may remove added space
+ check_auto_format(false);
+ }
}
check_cursor();
@@ -5785,9 +5777,8 @@ auto_format (
* delete it now. The space must be under the cursor, just after the insert
* position.
*/
-static void
-check_auto_format (
- int end_insert /* TRUE when ending Insert mode */
+static void check_auto_format(
+ bool end_insert // true when ending Insert mode
)
{
int c = ' ';
@@ -5795,19 +5786,19 @@ check_auto_format (
if (did_add_space) {
cc = gchar_cursor();
- if (!WHITECHAR(cc))
- /* Somehow the space was removed already. */
- did_add_space = FALSE;
- else {
+ if (!WHITECHAR(cc)) {
+ // Somehow the space was removed already.
+ did_add_space = false;
+ } else {
if (!end_insert) {
inc_cursor();
c = gchar_cursor();
dec_cursor();
}
if (c != NUL) {
- /* The space is no longer at the end of the line, delete it. */
- del_char(FALSE);
- did_add_space = FALSE;
+ // The space is no longer at the end of the line, delete it.
+ del_char(false);
+ did_add_space = false;
}
}
}
@@ -6032,8 +6023,8 @@ stop_insert (
}
}
- /* If a space was inserted for auto-formatting, remove it now. */
- check_auto_format(TRUE);
+ // If a space was inserted for auto-formatting, remove it now.
+ check_auto_format(true);
/* If we just did an auto-indent, remove the white space from the end
* of the line, and put the cursor back.
@@ -6052,10 +6043,12 @@ stop_insert (
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
--curwin->w_cursor.col;
cc = gchar_cursor();
- if (!ascii_iswhite(cc))
+ if (!ascii_iswhite(cc)) {
break;
- if (del_char(TRUE) == FAIL)
- break; /* should not happen */
+ }
+ if (del_char(true) == FAIL) {
+ break; // should not happen
+ }
}
if (curwin->w_cursor.lnum != tpos.lnum)
curwin->w_cursor = tpos;
@@ -6080,10 +6073,10 @@ stop_insert (
}
}
}
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
/* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are
* now in a different buffer. */
@@ -6197,12 +6190,10 @@ int oneright(void)
/* Adjust for multi-wide char (excluding TAB) */
ptr = get_cursor_pos_ptr();
- coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(
- (*mb_ptr2char)(ptr)
- ))
- ? ptr2cells(ptr) : 1));
- curwin->w_set_curswant = TRUE;
- /* Return OK if the cursor moved, FAIL otherwise (at window edge). */
+ coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ?
+ ptr2cells(ptr) : 1));
+ curwin->w_set_curswant = true;
+ // Return OK if the cursor moved, FAIL otherwise (at window edge).
return (prevpos.col != curwin->w_cursor.col
|| prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL;
}
@@ -6257,10 +6248,10 @@ int oneleft(void)
/* Adjust for multi-wide char (not a TAB) */
ptr = get_cursor_pos_ptr();
- if (*ptr != TAB && vim_isprintc(
- (*mb_ptr2char)(ptr)
- ) && ptr2cells(ptr) > 1)
+ if (*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))
+ && ptr2cells(ptr) > 1) {
curwin->w_cursor.coladd = 0;
+ }
}
curwin->w_set_curswant = TRUE;
@@ -6709,8 +6700,8 @@ static void replace_do_bs(int limit_col)
* text aligned. */
curwin->w_cursor.col += ins_len;
while (vcol > orig_vcols && gchar_cursor() == ' ') {
- del_char(FALSE);
- ++orig_vcols;
+ del_char(false);
+ orig_vcols++;
}
curwin->w_cursor.col -= ins_len;
}
@@ -7174,7 +7165,7 @@ static void ins_ctrl_g(void)
case 'U':
// Allow one left/right cursor movement with the next char,
// without breaking undo.
- dont_sync_undo = MAYBE;
+ dont_sync_undo = kNone;
break;
/* Unknown CTRL-G command, reserved for future expansion. */
@@ -7452,46 +7443,55 @@ static void ins_shift(int c, int lastc)
*/
if (c == Ctrl_D && (lastc == '0' || lastc == '^')
&& curwin->w_cursor.col > 0) {
- --curwin->w_cursor.col;
- (void)del_char(FALSE); /* delete the '^' or '0' */
- /* In Replace mode, restore the characters that '^' or '0' replaced. */
- if (State & REPLACE_FLAG)
+ curwin->w_cursor.col--;
+ (void)del_char(false); // delete the '^' or '0'
+ // In Replace mode, restore the characters that '^' or '0' replaced.
+ if (State & REPLACE_FLAG) {
replace_pop_ins();
- if (lastc == '^')
- old_indent = get_indent(); /* remember curr. indent */
+ }
+ if (lastc == '^') {
+ old_indent = get_indent(); // remember curr. indent
+ }
change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
} else
change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
- if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL)
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
- can_cindent = FALSE; /* no cindenting after ^D or ^T */
+ if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) {
+ did_ai = false;
+ }
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
+ can_cindent = false; // no cindenting after ^D or ^T
}
static void ins_del(void)
{
- int temp;
-
- if (stop_arrow() == FAIL)
+ if (stop_arrow() == FAIL) {
return;
- if (gchar_cursor() == NUL) { /* delete newline */
- temp = curwin->w_cursor.col;
+ }
+ if (gchar_cursor() == NUL) { // delete newline
+ const int temp = curwin->w_cursor.col;
if (!can_bs(BS_EOL) // only if "eol" included
|| do_join(2, false, true, false, false) == FAIL) {
vim_beep(BO_BS);
} else {
curwin->w_cursor.col = temp;
+ // Adjust orig_line_count in case more lines have been deleted than
+ // have been added. That makes sure, that open_line() later
+ // can access all buffer lines correctly
+ if (State & VREPLACE_FLAG
+ && orig_line_count > curbuf->b_ml.ml_line_count) {
+ orig_line_count = curbuf->b_ml.ml_line_count;
+ }
}
} else if (del_char(false) == FAIL) { // delete char under cursor
vim_beep(BO_BS);
}
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
AppendCharToRedobuff(K_DEL);
}
@@ -7509,8 +7509,9 @@ static void ins_bs_one(colnr_T *vcolp)
if (curwin->w_cursor.lnum != Insstart.lnum
|| curwin->w_cursor.col >= Insstart.col)
replace_do_bs(-1);
- } else
- (void)del_char(FALSE);
+ } else {
+ (void)del_char(false);
+ }
}
/// Handle Backspace, delete-word and delete-line in Insert mode.
@@ -7658,7 +7659,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
State = oldState;
}
}
- did_ai = FALSE;
+ did_ai = false;
} else {
/*
* Delete character(s) before the cursor.
@@ -7774,16 +7775,16 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
else {
const bool l_enc_utf8 = enc_utf8;
const int l_p_deco = p_deco;
- if (l_enc_utf8 && l_p_deco)
+ if (l_enc_utf8 && l_p_deco) {
(void)utfc_ptr2char(get_cursor_pos_ptr(), cpc);
- (void)del_char(FALSE);
- /*
- * If there are combining characters and 'delcombine' is set
- * move the cursor back. Don't back up before the base
- * character.
- */
- if (l_enc_utf8 && l_p_deco && cpc[0] != NUL)
+ }
+ (void)del_char(false);
+ // If there are combining characters and 'delcombine' is set
+ // move the cursor back. Don't back up before the base
+ // character.
+ if (l_enc_utf8 && l_p_deco && cpc[0] != NUL) {
inc_cursor();
+ }
if (revins_chars) {
revins_chars--;
revins_legal++;
@@ -7862,7 +7863,7 @@ static void ins_mouse(int c)
curwin = new_curwin;
curbuf = curwin->w_buffer;
}
- can_cindent = TRUE;
+ can_cindent = true;
}
/* redraw status lines (in case another window became active) */
@@ -7871,20 +7872,20 @@ static void ins_mouse(int c)
static void ins_mousescroll(int dir)
{
- pos_T tpos;
- win_T *old_curwin = curwin;
- int did_scroll = FALSE;
-
- tpos = curwin->w_cursor;
+ win_T *const old_curwin = curwin;
+ bool did_scroll = false;
+ pos_T tpos = curwin->w_cursor;
if (mouse_row >= 0 && mouse_col >= 0) {
- int row, col;
-
- row = mouse_row;
- col = mouse_col;
+ int row = mouse_row;
+ int col = mouse_col;
- /* find the window at the pointer coordinates */
- curwin = mouse_find_win(&row, &col);
+ // find the window at the pointer coordinates
+ win_T *const wp = mouse_find_win(&row, &col);
+ if (wp == NULL) {
+ return;
+ }
+ curwin = wp;
curbuf = curwin->w_buffer;
}
if (curwin == old_curwin)
@@ -7903,7 +7904,7 @@ static void ins_mousescroll(int dir)
} else {
mouse_scroll_horiz(dir);
}
- did_scroll = TRUE;
+ did_scroll = true;
}
curwin->w_redr_status = TRUE;
@@ -7921,7 +7922,7 @@ static void ins_mousescroll(int dir)
if (!equalpos(curwin->w_cursor, tpos)) {
start_arrow(&tpos);
- can_cindent = TRUE;
+ can_cindent = true;
}
}
@@ -7954,7 +7955,7 @@ static void ins_left(bool end_change)
} else {
vim_beep(BO_CRSR);
}
- dont_sync_undo = false;
+ dont_sync_undo = kFalse;
}
static void ins_home(int c)
@@ -8039,7 +8040,7 @@ static void ins_right(bool end_change)
} else {
vim_beep(BO_CRSR);
}
- dont_sync_undo = false;
+ dont_sync_undo = kFalse;
}
static void ins_s_right(void)
@@ -8389,8 +8390,8 @@ static bool ins_eol(int c)
has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0,
old_indent);
old_indent = 0;
- can_cindent = TRUE;
- /* When inserting a line the cursor line must never be in a closed fold. */
+ can_cindent = true;
+ // When inserting a line the cursor line must never be in a closed fold.
foldOpenCursor();
return !i;
@@ -8494,7 +8495,7 @@ int ins_copychar(linenr_T lnum)
if ((colnr_T)temp > curwin->w_virtcol)
ptr = prev_ptr;
- c = (*mb_ptr2char)(ptr);
+ c = utf_ptr2char(ptr);
if (c == NUL) {
vim_beep(BO_COPY);
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 3843245070..9765b04922 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1186,7 +1186,7 @@ int call_vim_function(
const char_u *func,
int argc,
const char_u *const *const argv,
- int safe, // use the sandbox
+ bool safe, // use the sandbox
int str_arg_only, // all arguments are strings
typval_T *rettv
)
@@ -1276,9 +1276,9 @@ varnumber_T call_func_retnr(char_u *func, int argc,
///
/// @return [allocated] NULL when calling function fails, allocated string
/// otherwise.
-char *call_func_retstr(const char *const func, const int argc,
- const char_u *const *const argv,
- const bool safe)
+char *call_func_retstr(const char *const func, int argc,
+ const char_u *const *argv,
+ bool safe)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
@@ -1302,8 +1302,8 @@ char *call_func_retstr(const char *const func, const int argc,
///
/// @return [allocated] NULL when calling function fails or return tv is not a
/// List, allocated List otherwise.
-void *call_func_retlist(char_u *func, int argc, const char_u *const *const argv,
- int safe)
+void *call_func_retlist(char_u *func, int argc, const char_u *const *argv,
+ bool safe)
{
typval_T rettv;
@@ -9493,6 +9493,9 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/* Find the window at the mouse coordinates and compute the
* text position. */
win = mouse_find_win(&row, &col);
+ if (win == NULL) {
+ return;
+ }
(void)mouse_comp_pos(win, &row, &col, &lnum);
for (wp = firstwin; wp != win; wp = wp->w_next)
++winnr;
@@ -10207,32 +10210,34 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *oldcurwin;
- tabpage_T *tp, *oldtabpage;
- dictitem_T *v;
+ tabpage_T *oldtabpage;
bool done = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
const char *const varname = tv_get_string_chk(&argvars[1]);
- tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
if (tp != NULL && varname != NULL) {
// Set tp to be our tabpage, temporarily. Also set the window to the
// first window in the tabpage, otherwise the window is not valid.
- win_T *window = tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin;
+ win_T *const window = tp == curtab || tp->tp_firstwin == NULL
+ ? firstwin
+ : tp->tp_firstwin;
if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
// look up the variable
// Let gettabvar({nr}, "") return the "t:" dictionary.
- v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
- varname, strlen(varname), false);
+ const dictitem_T *const v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
+ varname, strlen(varname),
+ false);
if (v != NULL) {
tv_copy(&v->di_tv, rettv);
done = true;
}
}
- /* restore previous notion of curwin */
- restore_win(oldcurwin, oldtabpage, TRUE);
+ // restore previous notion of curwin
+ restore_win(oldcurwin, oldtabpage, true);
}
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
@@ -15893,7 +15898,7 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
while (charidx >= 0 && byteidx < len) {
if (charidx == 0) {
- rettv->vval.v_number = mb_ptr2char((const char_u *)str + byteidx);
+ rettv->vval.v_number = utf_ptr2char((const char_u *)str + byteidx);
break;
}
charidx--;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 176df58fb9..1420a9aae4 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -716,11 +716,13 @@ void ex_retab(exarg_T *eap)
memmove(new_line + start_col + len,
ptr + col, (size_t)(old_len - col + 1));
ptr = new_line + start_col;
- for (col = 0; col < len; col++)
+ for (col = 0; col < len; col++) {
ptr[col] = (col < num_tabs) ? '\t' : ' ';
- ml_replace(lnum, new_line, FALSE);
- if (first_line == 0)
+ }
+ ml_replace(lnum, new_line, false);
+ if (first_line == 0) {
first_line = lnum;
+ }
last_line = lnum;
ptr = new_line;
col = start_col + len;
@@ -1598,6 +1600,7 @@ void ex_file(exarg_T *eap)
// print full file name if :cd used
fileinfo(false, false, eap->forceit);
}
+ redraw_tabline = true;
}
/*
@@ -3624,7 +3627,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
// before the cursor.
len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line);
curwin->w_cursor.col += len_change;
- ml_replace(lnum, new_line, FALSE);
+ ml_replace(lnum, new_line, false);
}
search_match_lines = regmatch.endpos[0].lnum
@@ -3666,9 +3669,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
msg_col = 0;
gotocmdline(TRUE);
- /* restore the line */
- if (orig_line != NULL)
- ml_replace(lnum, orig_line, FALSE);
+ // restore the line
+ if (orig_line != NULL) {
+ ml_replace(lnum, orig_line, false);
+ }
}
need_wait_return = FALSE; /* no hit-return prompt */
@@ -3925,9 +3929,10 @@ skip:
prev_matchcol = (colnr_T)STRLEN(sub_firstline)
- prev_matchcol;
- if (u_savesub(lnum) != OK)
+ if (u_savesub(lnum) != OK) {
break;
- ml_replace(lnum, new_start, TRUE);
+ }
+ ml_replace(lnum, new_start, true);
if (nmatch_tl > 0) {
/*
@@ -4913,11 +4918,7 @@ void fix_help_buffer(void)
{
linenr_T lnum;
char_u *line;
- int in_example = FALSE;
- int len;
- char_u *fname;
- char_u *p;
- char_u *rt;
+ bool in_example = false;
// Set filetype to "help".
if (STRCMP(curbuf->b_p_ft, "help") != 0) {
@@ -4927,9 +4928,9 @@ void fix_help_buffer(void)
}
if (!syntax_present(curwin)) {
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
- line = ml_get_buf(curbuf, lnum, FALSE);
- len = (int)STRLEN(line);
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) {
+ line = ml_get_buf(curbuf, lnum, false);
+ const size_t len = STRLEN(line);
if (in_example && len > 0 && !ascii_iswhite(line[0])) {
/* End of example: non-white or '<' in first column. */
if (line[0] == '<') {
@@ -4937,14 +4938,14 @@ void fix_help_buffer(void)
line = ml_get_buf(curbuf, lnum, TRUE);
line[0] = ' ';
}
- in_example = FALSE;
+ in_example = false;
}
if (!in_example && len > 0) {
if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' ')) {
/* blank-out a '>' in the last column (start of example) */
line = ml_get_buf(curbuf, lnum, TRUE);
line[len - 1] = ' ';
- in_example = TRUE;
+ in_example = true;
} else if (line[len - 1] == '~') {
/* blank-out a '~' at the end of line (header marker) */
line = ml_get_buf(curbuf, lnum, TRUE);
@@ -4958,7 +4959,7 @@ void fix_help_buffer(void)
* In the "help.txt" and "help.abx" file, add the locally added help
* files. This uses the very first line in the help file.
*/
- fname = path_tail(curbuf->b_fname);
+ char_u *const fname = path_tail(curbuf->b_fname);
if (fnamecmp(fname, "help.txt") == 0
|| (fnamencmp(fname, "help.", 5) == 0
&& ASCII_ISALPHA(fname[5])
@@ -4973,17 +4974,15 @@ void fix_help_buffer(void)
/* Go through all directories in 'runtimepath', skipping
* $VIMRUNTIME. */
- p = p_rtp;
+ char_u *p = p_rtp;
while (*p != NUL) {
copy_option_part(&p, NameBuff, MAXPATHL, ",");
- rt = (char_u *)vim_getenv("VIMRUNTIME");
+ char_u *const rt = (char_u *)vim_getenv("VIMRUNTIME");
if (rt != NULL
&& path_full_compare(rt, NameBuff, false) != kEqualFiles) {
int fcount;
char_u **fnames;
- FILE *fd;
char_u *s;
- int fi;
vimconv_T vc;
char_u *cp;
@@ -5001,29 +5000,24 @@ void fix_help_buffer(void)
if (gen_expand_wildcards(1, buff_list, &fcount,
&fnames, EW_FILE|EW_SILENT) == OK
&& fcount > 0) {
- int i1;
- int i2;
- char_u *f1;
- char_u *f2;
- char_u *t1;
- char_u *e1;
- char_u *e2;
-
- /* If foo.abx is found use it instead of foo.txt in
- * the same directory. */
- for (i1 = 0; i1 < fcount; ++i1) {
- for (i2 = 0; i2 < fcount; ++i2) {
- if (i1 == i2)
+ // If foo.abx is found use it instead of foo.txt in
+ // the same directory.
+ for (int i1 = 0; i1 < fcount; i1++) {
+ for (int i2 = 0; i2 < fcount; i2++) {
+ if (i1 == i2) {
continue;
- if (fnames[i1] == NULL || fnames[i2] == NULL)
+ }
+ if (fnames[i1] == NULL || fnames[i2] == NULL) {
continue;
- f1 = fnames[i1];
- f2 = fnames[i2];
- t1 = path_tail(f1);
- if (fnamencmp(f1, f2, t1 - f1) != 0)
+ }
+ const char_u *const f1 = fnames[i1];
+ const char_u *const f2 = fnames[i2];
+ const char_u *const t1 = path_tail(f1);
+ if (fnamencmp(f1, f2, t1 - f1) != 0) {
continue;
- e1 = vim_strrchr(t1, '.');
- e2 = vim_strrchr(path_tail(f2), '.');
+ }
+ const char_u *const e1 = vim_strrchr(t1, '.');
+ const char_u *const e2 = vim_strrchr(path_tail(f2), '.');
if (e1 == NULL || e2 == NULL) {
continue;
}
@@ -5044,10 +5038,12 @@ void fix_help_buffer(void)
}
}
}
- for (fi = 0; fi < fcount; ++fi) {
- if (fnames[fi] == NULL)
+ for (int fi = 0; fi < fcount; fi++) {
+ if (fnames[fi] == NULL) {
continue;
- fd = mch_fopen((char *)fnames[fi], "r");
+ }
+
+ FILE *const fd = mch_fopen((char *)fnames[fi], "r");
if (fd == NULL) {
continue;
}
@@ -5055,9 +5051,9 @@ void fix_help_buffer(void)
if (IObuff[0] == '*'
&& (s = vim_strchr(IObuff + 1, '*'))
!= NULL) {
- int this_utf = MAYBE;
- /* Change tag definition to a
- * reference and remove <CR>/<NL>. */
+ TriState this_utf = kNone;
+ // Change tag definition to a
+ // reference and remove <CR>/<NL>.
IObuff[0] = '|';
*s = '|';
while (*s != NUL) {
@@ -5067,13 +5063,12 @@ void fix_help_buffer(void)
* above 127 is found and no
* illegal byte sequence is found.
*/
- if (*s >= 0x80 && this_utf != FALSE) {
- int l;
-
- this_utf = TRUE;
- l = utf_ptr2len(s);
- if (l == 1)
- this_utf = FALSE;
+ if (*s >= 0x80 && this_utf != kFalse) {
+ this_utf = kTrue;
+ const int l = utf_ptr2len(s);
+ if (l == 1) {
+ this_utf = kFalse;
+ }
s += l - 1;
}
++s;
@@ -5082,18 +5077,20 @@ void fix_help_buffer(void)
* conversion to the current
* 'encoding' may be required. */
vc.vc_type = CONV_NONE;
- convert_setup(&vc, (char_u *)(
- this_utf == TRUE ? "utf-8"
- : "latin1"), p_enc);
- if (vc.vc_type == CONV_NONE)
- /* No conversion needed. */
+ convert_setup(
+ &vc,
+ (char_u *)(this_utf == kTrue ? "utf-8" : "latin1"),
+ p_enc);
+ if (vc.vc_type == CONV_NONE) {
+ // No conversion needed.
cp = IObuff;
- else {
- /* Do the conversion. If it fails
- * use the unconverted text. */
+ } else {
+ // Do the conversion. If it fails
+ // use the unconverted text.
cp = string_convert(&vc, IObuff, NULL);
- if (cp == NULL)
+ if (cp == NULL) {
cp = IObuff;
+ }
}
convert_setup(&vc, NULL, NULL);
@@ -5138,22 +5135,16 @@ void ex_viusage(exarg_T *eap)
/// @param tagname Name of the tags file ("tags" for English, "tags-fr" for
/// French)
/// @param add_help_tags Whether to add the "help-tags" tag
-static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
- bool add_help_tags)
+static void helptags_one(char_u *const dir, const char_u *const ext,
+ const char_u *const tagfname, const bool add_help_tags)
{
- FILE *fd_tags;
- FILE *fd;
garray_T ga;
int filecount;
char_u **files;
char_u *p1, *p2;
- int fi;
char_u *s;
- char_u *fname;
- int utf8 = MAYBE;
- int this_utf8;
- int firstline;
- int mix = FALSE; /* detected mixed encodings */
+ TriState utf8 = kNone;
+ bool mix = false; // detected mixed encodings
// Find all *.txt files.
size_t dirlen = STRLCPY(NameBuff, dir, sizeof(NameBuff));
@@ -5186,7 +5177,8 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
EMSG(_(e_fnametoolong));
return;
}
- fd_tags = mch_fopen((char *)NameBuff, "w");
+
+ FILE *const fd_tags = mch_fopen((char *)NameBuff, "w");
if (fd_tags == NULL) {
EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
FreeWild(filecount, files);
@@ -5209,44 +5201,44 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
/*
* Go over all the files and extract the tags.
*/
- for (fi = 0; fi < filecount && !got_int; ++fi) {
- fd = mch_fopen((char *)files[fi], "r");
+ for (int fi = 0; fi < filecount && !got_int; fi++) {
+ FILE *const fd = mch_fopen((char *)files[fi], "r");
if (fd == NULL) {
EMSG2(_("E153: Unable to open %s for reading"), files[fi]);
continue;
}
- fname = files[fi] + dirlen + 1;
+ const char_u *const fname = files[fi] + dirlen + 1;
- firstline = TRUE;
+ bool firstline = true;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
if (firstline) {
- /* Detect utf-8 file by a non-ASCII char in the first line. */
- this_utf8 = MAYBE;
- for (s = IObuff; *s != NUL; ++s)
+ // Detect utf-8 file by a non-ASCII char in the first line.
+ TriState this_utf8 = kNone;
+ for (s = IObuff; *s != NUL; s++) {
if (*s >= 0x80) {
- int l;
-
- this_utf8 = TRUE;
- l = utf_ptr2len(s);
+ this_utf8 = kTrue;
+ const int l = utf_ptr2len(s);
if (l == 1) {
- /* Illegal UTF-8 byte sequence. */
- this_utf8 = FALSE;
+ // Illegal UTF-8 byte sequence.
+ this_utf8 = kFalse;
break;
}
s += l - 1;
}
- if (this_utf8 == MAYBE) /* only ASCII characters found */
- this_utf8 = FALSE;
- if (utf8 == MAYBE) /* first file */
+ }
+ if (this_utf8 == kNone) { // only ASCII characters found
+ this_utf8 = kFalse;
+ }
+ if (utf8 == kNone) { // first file
utf8 = this_utf8;
- else if (utf8 != this_utf8) {
+ } else if (utf8 != this_utf8) {
EMSG2(_(
"E670: Mix of help file encodings within a language: %s"),
files[fi]);
mix = !got_int;
got_int = TRUE;
}
- firstline = FALSE;
+ firstline = false;
}
p1 = vim_strchr(IObuff, '*'); /* find first '*' */
while (p1 != NULL) {
@@ -5316,8 +5308,9 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
}
}
- if (utf8 == TRUE)
+ if (utf8 == kTrue) {
fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n");
+ }
/*
* Write the tags into the file.
@@ -5653,7 +5646,7 @@ void ex_sign(exarg_T *eap)
// Count cells and check for non-printable chars
cells = 0;
for (s = arg; s < p; s += (*mb_ptr2len)(s)) {
- if (!vim_isprintc((*mb_ptr2char)(s))) {
+ if (!vim_isprintc(utf_ptr2char(s))) {
break;
}
cells += (*mb_ptr2cells)(s);
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 97369c50d9..3d3d02fd71 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -2899,11 +2899,7 @@ const char * set_one_cmd_context(
xp->xp_pattern = skipwhite((const char_u *)arg);
p = (const char *)xp->xp_pattern;
while (*p != NUL) {
- if (has_mbyte) {
- c = mb_ptr2char((const char_u *)p);
- } else {
- c = (uint8_t)(*p);
- }
+ c = utf_ptr2char((const char_u *)p);
if (c == '\\' && p[1] != NUL) {
p++;
} else if (c == '`') {
@@ -2921,19 +2917,11 @@ const char * set_one_cmd_context(
|| ascii_iswhite(c)) {
len = 0; /* avoid getting stuck when space is in 'isfname' */
while (*p != NUL) {
- if (has_mbyte) {
- c = mb_ptr2char((const char_u *)p);
- } else {
- c = *p;
- }
+ c = utf_ptr2char((const char_u *)p);
if (c == '`' || vim_isfilec_or_wc(c)) {
break;
}
- if (has_mbyte) {
- len = (size_t)(*mb_ptr2len)((const char_u *)p);
- } else {
- len = 1;
- }
+ len = (size_t)utfc_ptr2len((const char_u *)p);
MB_PTR_ADV(p);
}
if (in_quote) {
@@ -7395,7 +7383,7 @@ static void ex_operators(exarg_T *eap)
oa.end.lnum = eap->line2;
oa.line_count = eap->line2 - eap->line1 + 1;
oa.motion_type = kMTLineWise;
- virtual_op = false;
+ virtual_op = kFalse;
if (eap->cmdidx != CMD_yank) { // position cursor for undo
setpcmark();
curwin->w_cursor.lnum = eap->line1;
@@ -7426,7 +7414,7 @@ static void ex_operators(exarg_T *eap)
op_shift(&oa, FALSE, eap->amount);
break;
}
- virtual_op = MAYBE;
+ virtual_op = kNone;
ex_may_print(eap);
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index fd11acff84..1810056a4a 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -201,7 +201,10 @@ static Array cmdline_block = ARRAY_DICT_INIT;
/*
* Type used by call_user_expand_func
*/
-typedef void *(*user_expand_func_T)(char_u *, int, char_u **, int);
+typedef void *(*user_expand_func_T)(const char_u *,
+ int,
+ const char_u * const *,
+ bool);
static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */
@@ -3324,16 +3327,11 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
/* Locate start of last word in the cmd buffer. */
for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) {
- if (has_mbyte) {
- len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
- if (!vim_iswordc(mb_ptr2char(w - len)))
- break;
- w -= len;
- } else {
- if (!vim_iswordc(w[-1]))
- break;
- --w;
+ len = utf_head_off(ccline.cmdbuff, w - 1) + 1;
+ if (!vim_iswordc(utf_ptr2char(w - len))) {
+ break;
}
+ w -= len;
}
len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
@@ -3834,24 +3832,13 @@ ExpandOne (
// Find longest common part
if (mode == WILD_LONGEST && xp->xp_numfiles > 0) {
- size_t len;
- size_t mb_len = 1;
- int c0;
- int ci;
+ size_t len = 0;
- for (len = 0; xp->xp_files[0][len]; len += mb_len) {
- if (has_mbyte) {
- mb_len = (* mb_ptr2len)(&xp->xp_files[0][len]);
- c0 = (* mb_ptr2char)(&xp->xp_files[0][len]);
- } else {
- c0 = xp->xp_files[0][len];
- }
- for (i = 1; i < xp->xp_numfiles; ++i) {
- if (has_mbyte) {
- ci =(* mb_ptr2char)(&xp->xp_files[i][len]);
- } else {
- ci = xp->xp_files[i][len];
- }
+ for (size_t mb_len; xp->xp_files[0][len]; len += mb_len) {
+ mb_len = utfc_ptr2len(&xp->xp_files[0][len]);
+ int c0 = utf_ptr2char(&xp->xp_files[0][len]);
+ for (i = 1; i < xp->xp_numfiles; i++) {
+ int ci = utf_ptr2char(&xp->xp_files[i][len]);
if (p_fic && (xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_FILES
@@ -5046,7 +5033,10 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
ccline.cmdprompt = NULL;
current_SID = xp->xp_scriptID;
- ret = user_expand_func(xp->xp_arg, 3, args, FALSE);
+ ret = user_expand_func(xp->xp_arg,
+ 3,
+ (const char_u * const *)args,
+ false);
ccline = save_ccline;
current_SID = save_current_SID;
@@ -5062,11 +5052,12 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
*/
static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
{
- char_u *e;
- garray_T ga;
+ char_u *e;
+ garray_T ga;
char_u *const retstr = call_user_expand_func(
(user_expand_func_T)call_func_retstr, xp, num_file, file);
+
if (retstr == NULL) {
return FAIL;
}
@@ -6093,7 +6084,7 @@ static int open_cmdwin(void)
/* Replace the empty last line with the current command-line and put the
* cursor there. */
- ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
+ ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, true);
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
curwin->w_cursor.col = ccline.cmdpos;
changed_line_abv_curs();
diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c
index 6de84fbf4d..9862c50ab9 100644
--- a/src/nvim/farsi.c
+++ b/src/nvim/farsi.c
@@ -1081,7 +1081,7 @@ int fkmap(int c)
if (gchar_cursor() == _LAM) {
chg_l_toXor_X();
- del_char(FALSE);
+ del_char(false);
AppendCharToRedobuff(K_BS);
if (!p_ri) {
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index ef8750d061..b00c45413a 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -44,14 +44,14 @@
* The info stored in both growarrays is the same: An array of fold_T.
*/
typedef struct {
- linenr_T fd_top; /* first line of fold; for nested fold
- * relative to parent */
- linenr_T fd_len; /* number of lines in the fold */
- garray_T fd_nested; /* array of nested folds */
- char fd_flags; /* see below */
- char fd_small; /* TRUE, FALSE or MAYBE: fold smaller than
- 'foldminlines'; MAYBE applies to nested
- folds too */
+ linenr_T fd_top; // first line of fold; for nested fold
+ // relative to parent
+ linenr_T fd_len; // number of lines in the fold
+ garray_T fd_nested; // array of nested folds
+ char fd_flags; // see below
+ TriState fd_small; // kTrue, kFalse, or kNone: fold smaller than
+ // 'foldminlines'; kNone applies to nested
+ // folds too
} fold_T;
#define FD_OPEN 0 /* fold is open (nested ones can be closed) */
@@ -76,8 +76,8 @@ typedef struct {
this line (copy of "end" of prev. line) */
} fline_T;
-/* Flag is set when redrawing is needed. */
-static int fold_changed;
+// Flag is set when redrawing is needed.
+static bool fold_changed;
/* Function used by foldUpdateIEMSRecurse */
typedef void (*LevelGetter)(fline_T *);
@@ -147,29 +147,27 @@ int hasAnyFolding(win_T *win)
*/
bool hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp)
{
- return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);
+ return hasFoldingWin(curwin, lnum, firstp, lastp, true, NULL);
}
/* hasFoldingWin() {{{2 */
bool hasFoldingWin(
- win_T *win,
- linenr_T lnum,
- linenr_T *firstp,
- linenr_T *lastp,
- int cache, /* when TRUE: use cached values of window */
- foldinfo_T *infop /* where to store fold info */
+ win_T *const win,
+ const linenr_T lnum,
+ linenr_T *const firstp,
+ linenr_T *const lastp,
+ const bool cache, // when true: use cached values of window
+ foldinfo_T *const infop // where to store fold info
)
{
- int had_folded = FALSE;
+ bool had_folded = false;
linenr_T first = 0;
linenr_T last = 0;
linenr_T lnum_rel = lnum;
- int x;
fold_T *fp;
int level = 0;
- int use_level = FALSE;
- int maybe_small = FALSE;
- garray_T *gap;
+ bool use_level = false;
+ bool maybe_small = false;
int low_level = 0;
checkupdate(win);
@@ -187,7 +185,7 @@ bool hasFoldingWin(
* First look in cached info for displayed lines. This is probably
* the fastest, but it can only be used if the entry is still valid.
*/
- x = find_wl_entry(win, lnum);
+ const int x = find_wl_entry(win, lnum);
if (x >= 0) {
first = win->w_lines[x].wl_lnum;
last = win->w_lines[x].wl_lastlnum;
@@ -199,7 +197,7 @@ bool hasFoldingWin(
/*
* Recursively search for a fold that contains "lnum".
*/
- gap = &win->w_folds;
+ garray_T *gap = &win->w_folds;
for (;; ) {
if (!foldFind(gap, lnum_rel, &fp))
break;
@@ -274,14 +272,11 @@ int foldLevel(linenr_T lnum)
return foldLevelWin(curwin, lnum);
}
-/* lineFolded() {{{2 */
-/*
- * Low level function to check if a line is folded. Doesn't use any caching.
- * Return TRUE if line is folded.
- * Return FALSE if line is not folded.
- * Return MAYBE if the line is folded when next to a folded line.
- */
-int lineFolded(win_T *win, linenr_T lnum)
+// lineFolded() {{{2
+// Low level function to check if a line is folded. Doesn't use any caching.
+// Return true if line is folded.
+// Return false if line is not folded.
+bool lineFolded(win_T *const win, const linenr_T lnum)
{
return foldedCount(win, lnum, NULL) != 0;
}
@@ -299,8 +294,9 @@ long foldedCount(win_T *win, linenr_T lnum, foldinfo_T *infop)
{
linenr_T last;
- if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop))
+ if (hasFoldingWin(win, lnum, NULL, &last, false, infop)) {
return (long)(last - lnum + 1);
+ }
return 0;
}
@@ -649,7 +645,7 @@ void foldCreate(linenr_T start, linenr_T end)
if (!use_level)
curwin->w_fold_manual = true;
fp->fd_flags = FD_CLOSED;
- fp->fd_small = MAYBE;
+ fp->fd_small = kNone;
/* redraw */
changed_window_setting();
@@ -663,36 +659,31 @@ void foldCreate(linenr_T start, linenr_T end)
* When "end" is not 0, delete all folds from "start" to "end".
* When "recursive" is TRUE delete recursively.
*/
-void
-deleteFold(
- linenr_T start,
- linenr_T end,
- int recursive,
- int had_visual // TRUE when Visual selection used
+void deleteFold(
+ const linenr_T start,
+ const linenr_T end,
+ const int recursive,
+ const bool had_visual // true when Visual selection used
)
{
- garray_T *gap;
fold_T *fp;
- garray_T *found_ga;
fold_T *found_fp = NULL;
linenr_T found_off = 0;
- int use_level;
- int maybe_small = FALSE;
+ bool maybe_small = false;
int level = 0;
linenr_T lnum = start;
- linenr_T lnum_off;
- int did_one = FALSE;
+ bool did_one = false;
linenr_T first_lnum = MAXLNUM;
linenr_T last_lnum = 0;
checkupdate(curwin);
while (lnum <= end) {
- /* Find the deepest fold for "start". */
- gap = &curwin->w_folds;
- found_ga = NULL;
- lnum_off = 0;
- use_level = FALSE;
+ // Find the deepest fold for "start".
+ garray_T *gap = &curwin->w_folds;
+ garray_T *found_ga = NULL;
+ linenr_T lnum_off = 0;
+ bool use_level = false;
for (;; ) {
if (!foldFind(gap, lnum - lnum_off, &fp))
break;
@@ -728,7 +719,7 @@ deleteFold(
parseMarker(curwin);
deleteFoldMarkers(found_fp, recursive, found_off);
}
- did_one = TRUE;
+ did_one = true;
/* redraw window */
changed_window_setting();
@@ -787,8 +778,8 @@ void foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
(void)foldFind(&wp->w_folds, top, &fp);
while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len
&& fp->fd_top < bot) {
- fp->fd_small = MAYBE;
- ++fp;
+ fp->fd_small = kNone;
+ fp++;
}
if (foldmethodIsIndent(wp)
@@ -831,44 +822,34 @@ void foldUpdateAll(win_T *win)
redraw_win_later(win, NOT_VALID);
}
-/* foldMoveTo() {{{2 */
-/*
- * If "updown" is FALSE: Move to the start or end of the fold.
- * If "updown" is TRUE: move to fold at the same level.
- * If not moved return FAIL.
- */
-int
-foldMoveTo(
- int updown,
- int dir, // FORWARD or BACKWARD
- long count
+// foldMoveTo() {{{2
+//
+// If "updown" is false: Move to the start or end of the fold.
+// If "updown" is true: move to fold at the same level.
+// If not moved return FAIL.
+int foldMoveTo(
+ const bool updown,
+ const int dir, // FORWARD or BACKWARD
+ const long count
)
{
- long n;
int retval = FAIL;
- linenr_T lnum_off;
- linenr_T lnum_found;
linenr_T lnum;
- int use_level;
- int maybe_small;
- garray_T *gap;
fold_T *fp;
- int level;
- int last;
checkupdate(curwin);
- /* Repeat "count" times. */
- for (n = 0; n < count; ++n) {
- /* Find nested folds. Stop when a fold is closed. The deepest fold
- * that moves the cursor is used. */
- lnum_off = 0;
- gap = &curwin->w_folds;
- use_level = FALSE;
- maybe_small = FALSE;
- lnum_found = curwin->w_cursor.lnum;
- level = 0;
- last = FALSE;
+ // Repeat "count" times.
+ for (long n = 0; n < count; n++) {
+ // Find nested folds. Stop when a fold is closed. The deepest fold
+ // that moves the cursor is used.
+ linenr_T lnum_off = 0;
+ garray_T *gap = &curwin->w_folds;
+ bool use_level = false;
+ bool maybe_small = false;
+ linenr_T lnum_found = curwin->w_cursor.lnum;
+ int level = 0;
+ bool last = false;
for (;; ) {
if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp)) {
if (!updown)
@@ -886,14 +867,15 @@ foldMoveTo(
}
/* don't look for contained folds, they will always move
* the cursor too far. */
- last = TRUE;
+ last = true;
}
if (!last) {
/* Check if this fold is closed. */
if (check_closed(curwin, fp, &use_level, level,
- &maybe_small, lnum_off))
- last = TRUE;
+ &maybe_small, lnum_off)) {
+ last = true;
+ }
/* "[z" and "]z" stop at closed fold */
if (last && !updown)
@@ -1306,25 +1288,21 @@ static void foldOpenNested(fold_T *fpr)
}
}
-/* deleteFoldEntry() {{{2 */
-/*
- * Delete fold "idx" from growarray "gap".
- * When "recursive" is TRUE also delete all the folds contained in it.
- * When "recursive" is FALSE contained folds are moved one level up.
- */
-static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
+// deleteFoldEntry() {{{2
+// Delete fold "idx" from growarray "gap".
+// When "recursive" is true also delete all the folds contained in it.
+// When "recursive" is false contained folds are moved one level up.
+static void deleteFoldEntry(garray_T *const gap, const int idx,
+ const bool recursive)
{
- fold_T *fp;
- int i;
- fold_T *nfp;
-
- fp = (fold_T *)gap->ga_data + idx;
+ fold_T *fp = (fold_T *)gap->ga_data + idx;
if (recursive || GA_EMPTY(&fp->fd_nested)) {
- /* recursively delete the contained folds */
+ // recursively delete the contained folds
deleteFoldRecurse(&fp->fd_nested);
- --gap->ga_len;
- if (idx < gap->ga_len)
- memmove(fp, fp + 1, sizeof(fold_T) * (size_t)(gap->ga_len - idx));
+ gap->ga_len--;
+ if (idx < gap->ga_len) {
+ memmove(fp, fp + 1, sizeof(*fp) * (size_t)(gap->ga_len - idx));
+ }
} else {
/* Move nested folds one level up, to overwrite the fold that is
* deleted. */
@@ -1334,22 +1312,24 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
/* Get "fp" again, the array may have been reallocated. */
fp = (fold_T *)gap->ga_data + idx;
- /* adjust fd_top and fd_flags for the moved folds */
- nfp = (fold_T *)fp->fd_nested.ga_data;
- for (i = 0; i < moved; ++i) {
+ // adjust fd_top and fd_flags for the moved folds
+ fold_T *nfp = (fold_T *)fp->fd_nested.ga_data;
+ for (int i = 0; i < moved; i++) {
nfp[i].fd_top += fp->fd_top;
if (fp->fd_flags == FD_LEVEL)
nfp[i].fd_flags = FD_LEVEL;
- if (fp->fd_small == MAYBE)
- nfp[i].fd_small = MAYBE;
+ if (fp->fd_small == kNone) {
+ nfp[i].fd_small = kNone;
+ }
}
- /* move the existing folds down to make room */
- if (idx + 1 < gap->ga_len)
+ // move the existing folds down to make room
+ if (idx + 1 < gap->ga_len) {
memmove(fp + moved, fp + 1,
- sizeof(fold_T) * (size_t)(gap->ga_len - (idx + 1)));
- /* move the contained folds one level up */
- memmove(fp, nfp, sizeof(fold_T) * (size_t)moved);
+ sizeof(*fp) * (size_t)(gap->ga_len - (idx + 1)));
+ }
+ // move the contained folds one level up
+ memmove(fp, nfp, sizeof(*fp) * (size_t)moved);
xfree(nfp);
gap->ga_len += moved - 1;
}
@@ -1429,14 +1409,15 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
fp->fd_top += amount_after;
} else {
if (fp->fd_top >= top && last <= line2) {
- /* 4. fold completely contained in range */
+ // 4. fold completely contained in range
if (amount == MAXLNUM) {
- /* Deleting lines: delete the fold completely */
- deleteFoldEntry(gap, i, TRUE);
- --i; /* adjust index for deletion */
- --fp;
- } else
+ // Deleting lines: delete the fold completely
+ deleteFoldEntry(gap, i, true);
+ i--; // adjust index for deletion
+ fp--;
+ } else {
fp->fd_top += amount;
+ }
} else {
if (fp->fd_top < top) {
/* 2 or 3: need to correct nested folds too */
@@ -1505,36 +1486,40 @@ static int getDeepestNestingRecurse(garray_T *gap)
/*
* Check if a fold is closed and update the info needed to check nested folds.
*/
-static int
-check_closed(
- win_T *win,
- fold_T *fp,
- int *use_levelp, // TRUE: outer fold had FD_LEVEL
- int level, // folding depth
- int *maybe_smallp, // TRUE: outer this had fd_small == MAYBE
- linenr_T lnum_off // line number offset for fp->fd_top
+static bool check_closed(
+ win_T *const win,
+ fold_T *const fp,
+ bool *const use_levelp, // true: outer fold had FD_LEVEL
+ const int level, // folding depth
+ bool *const maybe_smallp, // true: outer this had fd_small == kNone
+ const linenr_T lnum_off // line number offset for fp->fd_top
)
{
- int closed = FALSE;
+ bool closed = false;
/* Check if this fold is closed. If the flag is FD_LEVEL this
* fold and all folds it contains depend on 'foldlevel'. */
if (*use_levelp || fp->fd_flags == FD_LEVEL) {
- *use_levelp = TRUE;
- if (level >= win->w_p_fdl)
- closed = TRUE;
- } else if (fp->fd_flags == FD_CLOSED)
- closed = TRUE;
-
- /* Small fold isn't closed anyway. */
- if (fp->fd_small == MAYBE)
- *maybe_smallp = TRUE;
+ *use_levelp = true;
+ if (level >= win->w_p_fdl) {
+ closed = true;
+ }
+ } else if (fp->fd_flags == FD_CLOSED) {
+ closed = true;
+ }
+
+ // Small fold isn't closed anyway.
+ if (fp->fd_small == kNone) {
+ *maybe_smallp = true;
+ }
if (closed) {
- if (*maybe_smallp)
- fp->fd_small = MAYBE;
+ if (*maybe_smallp) {
+ fp->fd_small = kNone;
+ }
checkSmall(win, fp, lnum_off);
- if (fp->fd_small == TRUE)
- closed = FALSE;
+ if (fp->fd_small == kTrue) {
+ closed = false;
+ }
}
return closed;
}
@@ -1545,43 +1530,38 @@ check_closed(
*/
static void
checkSmall(
- win_T *wp,
- fold_T *fp,
- linenr_T lnum_off // offset for fp->fd_top
+ win_T *const wp,
+ fold_T *const fp,
+ const linenr_T lnum_off // offset for fp->fd_top
)
{
- int count;
- int n;
-
- if (fp->fd_small == MAYBE) {
- /* Mark any nested folds to maybe-small */
+ if (fp->fd_small == kNone) {
+ // Mark any nested folds to maybe-small
setSmallMaybe(&fp->fd_nested);
- if (fp->fd_len > curwin->w_p_fml)
- fp->fd_small = FALSE;
- else {
- count = 0;
- for (n = 0; n < fp->fd_len; ++n) {
+ if (fp->fd_len > curwin->w_p_fml) {
+ fp->fd_small = kFalse;
+ } else {
+ int count = 0;
+ for (int n = 0; n < fp->fd_len; n++) {
count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
if (count > curwin->w_p_fml) {
- fp->fd_small = FALSE;
+ fp->fd_small = kFalse;
return;
}
}
- fp->fd_small = TRUE;
+ fp->fd_small = kTrue;
}
}
}
-/* setSmallMaybe() {{{2 */
-/*
- * Set small flags in "gap" to MAYBE.
- */
+// setSmallMaybe() {{{2
+// Set small flags in "gap" to kNone.
static void setSmallMaybe(garray_T *gap)
{
fold_T *fp = (fold_T *)gap->ga_data;
- for (int i = 0; i < gap->ga_len; ++i) {
- fp[i].fd_small = MAYBE;
+ for (int i = 0; i < gap->ga_len; i++) {
+ fp[i].fd_small = kNone;
}
}
@@ -1707,7 +1687,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
assert(p >= line);
memcpy(newline, line, (size_t)(p - line));
STRCPY(newline + (p - line), p + len);
- ml_replace(lnum, newline, FALSE);
+ ml_replace(lnum, newline, false);
}
break;
}
@@ -1783,12 +1763,13 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
if (text != NULL) {
/* Replace unprintable characters, if there are any. But
* replace a TAB with a space. */
- for (p = text; *p != NUL; ++p) {
- int len;
+ for (p = text; *p != NUL; p++) {
+ int len = utfc_ptr2len(p);
- if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) {
- if (!vim_isprintc((*mb_ptr2char)(p)))
+ if (len > 1) {
+ if (!vim_isprintc(utf_ptr2char(p))) {
break;
+ }
p += len - 1;
} else if (*p == TAB)
*p = ' ';
@@ -1896,13 +1877,10 @@ void foldtext_cleanup(char_u *str)
* Update the folding for window "wp", at least from lines "top" to "bot".
* Return TRUE if any folds did change.
*/
-static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
+static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
{
- linenr_T start;
- linenr_T end;
fline_T fline;
void (*getlevel)(fline_T *);
- int level;
fold_T *fp;
/* Avoid problems when being called recursively. */
@@ -1928,12 +1906,13 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
bot += diff_context;
}
- /* When deleting lines at the end of the buffer "top" can be past the end
- * of the buffer. */
- if (top > wp->w_buffer->b_ml.ml_line_count)
+ // When deleting lines at the end of the buffer "top" can be past the end
+ // of the buffer.
+ if (top > wp->w_buffer->b_ml.ml_line_count) {
top = wp->w_buffer->b_ml.ml_line_count;
+ }
- fold_changed = FALSE;
+ fold_changed = false;
fline.wp = wp;
fline.off = 0;
fline.lvl = 0;
@@ -1954,8 +1933,8 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
/* Need to get the level of the line above top, it is used if there is
* no marker at the top. */
if (top > 1) {
- /* Get the fold level at top - 1. */
- level = foldLevelWin(wp, top - 1);
+ // Get the fold level at top - 1.
+ const int level = foldLevelWin(wp, top - 1);
/* The fold may end just above the top, check for that. */
fline.lnum = top - 1;
@@ -2031,11 +2010,12 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
}
}
- start = fline.lnum;
- end = bot;
- /* Do at least one line. */
- if (start > end && end < wp->w_buffer->b_ml.ml_line_count)
+ linenr_T start = fline.lnum;
+ linenr_T end = bot;
+ // Do at least one line.
+ if (start > end && end < wp->w_buffer->b_ml.ml_line_count) {
end = start;
+ }
while (!got_int) {
/* Always stop at the end of the file ("end" can be past the end of
* the file). */
@@ -2126,22 +2106,21 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
* Returns bot, which may have been increased for lines that also need to be
* updated as a result of a detected change in the fold.
*/
-static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
- linenr_T startlnum, fline_T *flp,
- LevelGetter getlevel,
- linenr_T bot,
- char topflags /* containing fold flags */
- )
+static linenr_T foldUpdateIEMSRecurse(
+ garray_T *const gap, const int level, const linenr_T startlnum,
+ fline_T *const flp, LevelGetter getlevel, linenr_T bot,
+ const char topflags // containing fold flags
+)
{
linenr_T ll;
fold_T *fp = NULL;
fold_T *fp2;
int lvl = level;
linenr_T startlnum2 = startlnum;
- linenr_T firstlnum = flp->lnum; /* first lnum we got */
+ const linenr_T firstlnum = flp->lnum; // first lnum we got
int i;
- int finish = FALSE;
- linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
+ bool finish = false;
+ const linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
int concat;
/*
@@ -2309,8 +2288,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
* found. */
if (getlevel == foldlevelMarker
|| getlevel == foldlevelExpr
- || getlevel == foldlevelSyntax)
- finish = TRUE;
+ || getlevel == foldlevelSyntax) {
+ finish = true;
+ }
}
if (fp->fd_top == startlnum && concat) {
i = (int)(fp - (fold_T *)gap->ga_data);
@@ -2325,19 +2305,18 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
break;
}
if (fp->fd_top >= startlnum) {
- /* A fold that starts at or after startlnum and stops
- * before the new fold must be deleted. Continue
- * looking for the next one. */
- deleteFoldEntry(gap,
- (int)(fp - (fold_T *)gap->ga_data), TRUE);
+ // A fold that starts at or after startlnum and stops
+ // before the new fold must be deleted. Continue
+ // looking for the next one.
+ deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true);
} else {
/* A fold has some lines above startlnum, truncate it
* to stop just above startlnum. */
fp->fd_len = startlnum - fp->fd_top;
foldMarkAdjustRecurse(&fp->fd_nested,
- (linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
- (linenr_T)MAXLNUM, 0L);
- fold_changed = TRUE;
+ (linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
+ (linenr_T)MAXLNUM, 0L);
+ fold_changed = true;
}
} else {
/* Insert new fold. Careful: ga_data may be NULL and it
@@ -2361,14 +2340,15 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
flp->wp->w_fold_manual = true;
} else
fp->fd_flags = (fp - 1)->fd_flags;
- fp->fd_small = MAYBE;
- /* If using the "marker", "expr" or "syntax" method, we
- * need to continue until the end of the fold is found. */
+ fp->fd_small = kNone;
+ // If using the "marker", "expr" or "syntax" method, we
+ // need to continue until the end of the fold is found.
if (getlevel == foldlevelMarker
|| getlevel == foldlevelExpr
- || getlevel == foldlevelSyntax)
- finish = TRUE;
- fold_changed = TRUE;
+ || getlevel == foldlevelSyntax) {
+ finish = true;
+ }
+ fold_changed = true;
break;
}
}
@@ -2387,12 +2367,11 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
* Check "fp" for safety.
*/
if (lvl > level && fp != NULL) {
- /*
- * There is a nested fold, handle it recursively.
- */
- /* At least do one line (can happen when finish is TRUE). */
- if (bot < flp->lnum)
+ // There is a nested fold, handle it recursively.
+ // At least do one line (can happen when finish is true).
+ if (bot < flp->lnum) {
bot = flp->lnum;
+ }
/* Line numbers in the nested fold are relative to the start of
* this fold. */
@@ -2454,8 +2433,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
/* Current fold at least extends until lnum. */
if (fp->fd_len < flp->lnum - fp->fd_top) {
fp->fd_len = flp->lnum - fp->fd_top;
- fp->fd_small = MAYBE;
- fold_changed = TRUE;
+ fp->fd_small = kNone;
+ fold_changed = true;
}
/* Delete contained folds from the end of the last one found until where
@@ -2482,8 +2461,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
foldSplit(gap, i, flp->lnum, bot);
fp = (fold_T *)gap->ga_data + i;
}
- } else
+ } else {
fp->fd_len = flp->lnum - fp->fd_top;
+ }
fold_changed = true;
}
}
@@ -2502,7 +2482,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
(linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum));
fp2->fd_len -= flp->lnum - fp2->fd_top;
fp2->fd_top = flp->lnum;
- fold_changed = TRUE;
+ fold_changed = true;
}
if (lvl >= level) {
@@ -2511,8 +2491,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
}
break;
}
- fold_changed = TRUE;
- deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
+ fold_changed = true;
+ deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
}
/* Need to redraw the lines we inspected, which might be further down than
@@ -2548,36 +2528,32 @@ static void foldInsert(garray_T *gap, int i)
* The caller must first have taken care of any nested folds from "top" to
* "bot"!
*/
-static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
+static void foldSplit(garray_T *const gap, const int i, const linenr_T top,
+ const linenr_T bot)
{
- fold_T *fp;
fold_T *fp2;
- garray_T *gap1;
- garray_T *gap2;
- int idx;
- int len;
/* The fold continues below bot, need to split it. */
foldInsert(gap, i + 1);
- fp = (fold_T *)gap->ga_data + i;
+ fold_T *const fp = (fold_T *)gap->ga_data + i;
fp[1].fd_top = bot + 1;
// check for wrap around (MAXLNUM, and 32bit)
assert(fp[1].fd_top > bot);
fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top);
fp[1].fd_flags = fp->fd_flags;
- fp[1].fd_small = MAYBE;
- fp->fd_small = MAYBE;
+ fp[1].fd_small = kNone;
+ fp->fd_small = kNone;
/* Move nested folds below bot to new fold. There can't be
* any between top and bot, they have been removed by the caller. */
- gap1 = &fp->fd_nested;
- gap2 = &fp[1].fd_nested;
+ garray_T *const gap1 = &fp->fd_nested;
+ garray_T *const gap2 = &fp[1].fd_nested;
(void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2));
- len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
+ const int len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
if (len > 0) {
ga_grow(gap2, len);
- for (idx = 0; idx < len; ++idx) {
+ for (int idx = 0; idx < len; idx++) {
((fold_T *)gap2->ga_data)[idx] = fp2[idx];
((fold_T *)gap2->ga_data)[idx].fd_top
-= fp[1].fd_top - fp->fd_top;
@@ -2586,7 +2562,7 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
gap1->ga_len -= len;
}
fp->fd_len = top - fp->fd_top;
- fold_changed = TRUE;
+ fold_changed = true;
}
/* foldRemove() {{{2 */
@@ -2848,8 +2824,8 @@ static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2)
}
fp1->fd_len += fp2->fd_len;
- deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
- fold_changed = TRUE;
+ deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
+ fold_changed = true;
}
/* foldlevelIndent() {{{2 */
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 563608dd1d..b57e1f6558 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -439,7 +439,10 @@ void flush_buffers(int flush_typeahead)
;
typebuf.tb_off = MAXMAPLEN;
typebuf.tb_len = 0;
- } else { /* remove mapped characters at the start only */
+ // Reset the flag that text received from a client or from feedkeys()
+ // was inserted in the typeahead buffer.
+ typebuf_was_filled = false;
+ } else { // remove mapped characters at the start only
typebuf.tb_off += typebuf.tb_maplen;
typebuf.tb_len -= typebuf.tb_maplen;
}
@@ -698,7 +701,7 @@ static int read_redo(int init, int old_redo)
buf[i] = (char_u)c;
if (i == n - 1) { // last byte of a character
if (n != 1) {
- c = (*mb_ptr2char)(buf);
+ c = utf_ptr2char(buf);
}
break;
}
@@ -1077,9 +1080,10 @@ void del_typebuf(int len, int offset)
/* Reset the flag that text received from a client or from feedkeys()
* was inserted in the typeahead buffer. */
- typebuf_was_filled = FALSE;
- if (++typebuf.tb_change_cnt == 0)
+ typebuf_was_filled = false;
+ if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
+ }
}
/*
@@ -1482,7 +1486,7 @@ int vgetc(void)
}
}
no_mapping--;
- c = (*mb_ptr2char)(buf);
+ c = utf_ptr2char(buf);
}
break;
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index d9103f516c..a31f6950e9 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -191,7 +191,7 @@ EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */
EXTERN int exec_from_reg INIT(= FALSE); /* executing register */
-EXTERN int screen_cleared INIT(= FALSE); /* screen has been cleared */
+EXTERN TriState screen_cleared INIT(= kFalse); // screen has been cleared
/*
* When '$' is included in 'cpoptions' option set:
@@ -604,7 +604,7 @@ EXTERN pos_T where_paste_started;
* reset when any other editing is done on the line. If an <ESC> or <RETURN>
* is received, and did_ai is TRUE, the line is truncated.
*/
-EXTERN int did_ai INIT(= FALSE);
+EXTERN bool did_ai INIT(= false);
/*
* Column of first char after autoindent. 0 when no autoindent done. Used
@@ -632,19 +632,19 @@ EXTERN int did_syncbind INIT(= FALSE);
* This flag is set when a smart indent has been performed. When the next typed
* character is a '{' the inserted tab will be deleted again.
*/
-EXTERN int did_si INIT(= FALSE);
+EXTERN bool did_si INIT(= false);
/*
* This flag is set after an auto indent. If the next typed character is a '}'
* one indent will be removed.
*/
-EXTERN int can_si INIT(= FALSE);
+EXTERN bool can_si INIT(= false);
/*
* This flag is set after an "O" command. If the next typed character is a '{'
* one indent will be removed.
*/
-EXTERN int can_si_back INIT(= FALSE);
+EXTERN bool can_si_back INIT(= false);
// w_cursor before formatting text.
EXTERN pos_T saved_cursor INIT(= INIT_POS_T(0, 0, 0));
@@ -942,8 +942,8 @@ EXTERN int no_hlsearch INIT(= FALSE);
EXTERN linenr_T printer_page_num;
-EXTERN int typebuf_was_filled INIT(= FALSE); /* received text from client
- or from feedkeys() */
+EXTERN bool typebuf_was_filled INIT(= false); // received text from client
+ // or from feedkeys()
#ifdef BACKSLASH_IN_FILENAME
@@ -952,9 +952,9 @@ EXTERN char psepcN INIT(= '/'); // abnormal path separator character
EXTERN char pseps[2] INIT(= { '\\', 0 }); // normal path separator string
#endif
-/* Set to TRUE when an operator is being executed with virtual editing, MAYBE
- * when no operator is being executed, FALSE otherwise. */
-EXTERN int virtual_op INIT(= MAYBE);
+// Set to kTrue when an operator is being executed with virtual editing
+// kNone when no operator is being executed, kFalse otherwise.
+EXTERN TriState virtual_op INIT(= kNone);
/* Display tick, incremented for each call to update_screen() */
EXTERN disptick_T display_tick INIT(= 0);
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index e1eb8f0251..a2f48f46aa 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -134,9 +134,9 @@ static int current_syn_id;
#define PRCOLOR_BLACK 0
#define PRCOLOR_WHITE 0xffffff
-static int curr_italic;
-static int curr_bold;
-static int curr_underline;
+static TriState curr_italic;
+static TriState curr_bold;
+static TriState curr_underline;
static uint32_t curr_bg;
static uint32_t curr_fg;
static int page_count;
@@ -417,7 +417,8 @@ static void prt_set_bg(uint32_t bg)
}
}
-static void prt_set_font(int bold, int italic, int underline)
+static void prt_set_font(const TriState bold, const TriState italic,
+ const TriState underline)
{
if (curr_bold != bold
|| curr_italic != italic
@@ -429,34 +430,32 @@ static void prt_set_font(int bold, int italic, int underline)
}
}
-/*
- * Print the line number in the left margin.
- */
-static void prt_line_number(prt_settings_T *psettings, int page_line, linenr_T lnum)
+// Print the line number in the left margin.
+static void prt_line_number(prt_settings_T *const psettings,
+ const int page_line, const linenr_T lnum)
{
- int i;
- char_u tbuf[20];
-
prt_set_fg(psettings->number.fg_color);
prt_set_bg(psettings->number.bg_color);
prt_set_font(psettings->number.bold, psettings->number.italic,
- psettings->number.underline);
- mch_print_start_line(TRUE, page_line);
+ psettings->number.underline);
+ mch_print_start_line(true, page_line);
- /* Leave two spaces between the number and the text; depends on
- * PRINT_NUMBER_WIDTH. */
- sprintf((char *)tbuf, "%6ld", (long)lnum);
- for (i = 0; i < 6; i++)
+ // Leave two spaces between the number and the text; depends on
+ // PRINT_NUMBER_WIDTH.
+ char_u tbuf[20];
+ snprintf((char *)tbuf, sizeof(tbuf), "%6ld", (long)lnum);
+ for (int i = 0; i < 6; i++) {
(void)mch_print_text_out(&tbuf[i], 1);
+ }
- if (psettings->do_syntax)
- /* Set colors for next character. */
+ if (psettings->do_syntax) {
+ // Set colors for next character.
current_syn_id = -1;
- else {
- /* Set colors and font back to normal. */
+ } else {
+ // Set colors and font back to normal.
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(FALSE, FALSE, FALSE);
+ prt_set_font(kFalse, kFalse, kFalse);
}
}
@@ -499,22 +498,20 @@ int prt_get_unit(int idx)
return u;
}
-/*
- * Print the page header.
- */
-static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum)
+// Print the page header.
+static void prt_header(prt_settings_T *const psettings, const int pagenum,
+ const linenr_T lnum)
{
int width = psettings->chars_per_line;
- int page_line;
- char_u *tbuf;
- char_u *p;
- /* Also use the space for the line number. */
- if (prt_use_number())
+ // Also use the space for the line number.
+ if (prt_use_number()) {
width += PRINT_NUMBER_WIDTH;
+ }
assert(width >= 0);
- tbuf = xmalloc((size_t)width + IOSIZE);
+ const size_t tbuf_size = (size_t)width + IOSIZE;
+ char_u *tbuf = xmalloc(tbuf_size);
if (*p_header != NUL) {
linenr_T tmp_lnum, tmp_topline, tmp_botline;
@@ -543,38 +540,40 @@ static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum)
curwin->w_cursor.lnum = tmp_lnum;
curwin->w_topline = tmp_topline;
curwin->w_botline = tmp_botline;
- } else
- sprintf((char *)tbuf, _("Page %d"), pagenum);
+ } else {
+ snprintf((char *)tbuf, tbuf_size, _("Page %d"), pagenum);
+ }
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(TRUE, FALSE, FALSE);
+ prt_set_font(kTrue, kFalse, kFalse);
- /* Use a negative line number to indicate printing in the top margin. */
- page_line = 0 - prt_header_height();
- mch_print_start_line(TRUE, page_line);
- for (p = tbuf; *p != NUL; ) {
- int l = (*mb_ptr2len)(p);
+ // Use a negative line number to indicate printing in the top margin.
+ int page_line = 0 - prt_header_height();
+ mch_print_start_line(true, page_line);
+ for (char_u *p = tbuf; *p != NUL; ) {
+ const int l = (*mb_ptr2len)(p);
assert(l >= 0);
if (mch_print_text_out(p, (size_t)l)) {
- ++page_line;
- if (page_line >= 0) /* out of room in header */
+ page_line++;
+ if (page_line >= 0) { // out of room in header
break;
- mch_print_start_line(TRUE, page_line);
+ }
+ mch_print_start_line(true, page_line);
}
p += l;
}
xfree(tbuf);
- if (psettings->do_syntax)
- /* Set colors for next character. */
+ if (psettings->do_syntax) {
+ // Set colors for next character.
current_syn_id = -1;
- else {
- /* Set colors and font back to normal. */
+ } else {
+ // Set colors and font back to normal.
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(FALSE, FALSE, FALSE);
+ prt_set_font(kFalse, kFalse, kFalse);
}
}
@@ -640,21 +639,19 @@ void ex_hardcopy(exarg_T *eap)
else
settings.do_syntax = settings.has_color;
- /* Set up printing attributes for line numbers */
+ // Set up printing attributes for line numbers
settings.number.fg_color = PRCOLOR_BLACK;
settings.number.bg_color = PRCOLOR_WHITE;
- settings.number.bold = FALSE;
- settings.number.italic = TRUE;
- settings.number.underline = FALSE;
- /*
- * Syntax highlighting of line numbers.
- */
- if (prt_use_number() && settings.do_syntax) {
- int id;
+ settings.number.bold = kFalse;
+ settings.number.italic = kTrue;
+ settings.number.underline = kFalse;
- id = syn_name2id((char_u *)"LineNr");
- if (id > 0)
+ // Syntax highlighting of line numbers.
+ if (prt_use_number() && settings.do_syntax) {
+ int id = syn_name2id((char_u *)"LineNr");
+ if (id > 0) {
id = syn_get_final_id(id);
+ }
prt_get_attr(id, &settings.number, settings.modec);
}
@@ -672,13 +669,13 @@ void ex_hardcopy(exarg_T *eap)
/* Set colors and font to normal. */
curr_bg = 0xffffffff;
curr_fg = 0xffffffff;
- curr_italic = MAYBE;
- curr_bold = MAYBE;
- curr_underline = MAYBE;
+ curr_italic = kNone;
+ curr_bold = kNone;
+ curr_underline = kNone;
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(FALSE, FALSE, FALSE);
+ prt_set_font(kFalse, kFalse, kFalse);
current_syn_id = -1;
jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present
@@ -841,7 +838,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
tab_spaces = ppos->lead_spaces;
}
- mch_print_start_line(0, page_line);
+ mch_print_start_line(false, page_line);
line = ml_get(ppos->file_line);
/*
@@ -1266,8 +1263,8 @@ static int prt_do_moveto;
static int prt_need_font;
static int prt_font;
static int prt_need_underline;
-static int prt_underline;
-static int prt_do_underline;
+static TriState prt_underline;
+static TriState prt_do_underline;
static int prt_need_fgcol;
static uint32_t prt_fgcol;
static int prt_need_bgcol;
@@ -2855,7 +2852,7 @@ int mch_print_begin_page(char_u *str)
/* We have reset the font attributes, force setting them again. */
curr_bg = 0xffffffff;
curr_fg = 0xffffffff;
- curr_bold = MAYBE;
+ curr_bold = kNone;
return !prt_file_error;
}
@@ -2868,11 +2865,12 @@ int mch_print_blank_page(void)
static double prt_pos_x = 0;
static double prt_pos_y = 0;
-void mch_print_start_line(int margin, int page_line)
+void mch_print_start_line(const bool margin, const int page_line)
{
prt_pos_x = prt_left_margin;
- if (margin)
+ if (margin) {
prt_pos_x -= prt_number_width;
+ }
prt_pos_y = prt_top_margin - prt_first_line_height -
page_line * prt_line_height;
@@ -3059,7 +3057,8 @@ int mch_print_text_out(char_u *const textp, size_t len)
return need_break;
}
-void mch_print_set_font(int iBold, int iItalic, int iUnderline)
+void mch_print_set_font(const TriState iBold, const TriState iItalic,
+ const TriState iUnderline)
{
int font = 0;
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index a70b20e6f5..c6a3321b08 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -2,10 +2,11 @@
#define NVIM_HARDCOPY_H
#include <stdint.h>
-#include <stdlib.h> // for size_t
+#include <stdlib.h> // for size_t
-#include "nvim/types.h" // for char_u
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include "nvim/globals.h" // for TriState
+#include "nvim/types.h" // for char_u
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/*
* Structure to hold printing color and font attributes.
@@ -13,9 +14,9 @@
typedef struct {
uint32_t fg_color;
uint32_t bg_color;
- int bold;
- int italic;
- int underline;
+ TriState bold;
+ TriState italic;
+ TriState underline;
int undercurl;
} prt_text_attr_T;
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index 7eb58bea2a..b02af723b4 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -126,7 +126,7 @@
# define MB_CHARLEN(p) mb_charlen(p)
# define MB_CHAR2LEN(c) mb_char2len(c)
-# define PTR2CHAR(p) mb_ptr2char(p)
+# define PTR2CHAR(p) utf_ptr2char(p)
# define RESET_BINDING(wp) (wp)->w_p_scb = FALSE; (wp)->w_p_crb = FALSE
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 49e60b5166..b9c91de2a8 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1470,7 +1470,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
// double-wide character.
if (lp->coladd == 1
&& p[lp->col] != TAB
- && vim_isprintc((*mb_ptr2char)(p + lp->col))
+ && vim_isprintc(utf_ptr2char(p + lp->col))
&& ptr2cells(p + lp->col) > 1) {
lp->coladd = 0;
}
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 65a1a8246c..7c196831ba 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -674,7 +674,7 @@ int mb_ptr2char_adv(const char_u **const pp)
{
int c;
- c = (*mb_ptr2char)(*pp);
+ c = utf_ptr2char(*pp);
*pp += (*mb_ptr2len)(*pp);
return c;
}
@@ -687,7 +687,7 @@ int mb_cptr2char_adv(const char_u **pp)
{
int c;
- c = (*mb_ptr2char)(*pp);
+ c = utf_ptr2char(*pp);
*pp += utf_ptr2len(*pp);
return c;
}
@@ -1714,7 +1714,7 @@ void mb_check_adjust_col(void *win_)
// Reset `coladd` when the cursor would be on the right half of a
// double-wide character.
if (win->w_cursor.coladd == 1 && p[win->w_cursor.col] != TAB
- && vim_isprintc((*mb_ptr2char)(p + win->w_cursor.col))
+ && vim_isprintc(utf_ptr2char(p + win->w_cursor.col))
&& ptr2cells(p + win->w_cursor.col) > 1) {
win->w_cursor.coladd = 0;
}
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 99aadcacad..a21c08c7fe 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -54,7 +54,6 @@ enum { MAX_MCO = 6 };
#define mb_ptr2cells_len utf_ptr2cells_len
#define mb_char2cells utf_char2cells
#define mb_off2cells utf_off2cells
-#define mb_ptr2char utf_ptr2char
#define mb_head_off utf_head_off
/// Flags for vimconv_T
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 84ceaf0973..9a1e61d40b 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -2378,7 +2378,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int message)
)
set_keep_msg((char_u *)_(no_lines_msg), 0);
- i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
+ i = ml_replace((linenr_T)1, (char_u *)"", true);
buf->b_ml.ml_flags |= ML_EMPTY;
return i;
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 968962c894..a56aa82f39 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -63,8 +63,8 @@ ex_menu(exarg_T *eap)
char_u *p;
int i;
long pri_tab[MENUDEPTH + 1];
- int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu
- * disable */
+ TriState enable = kNone; // kTrue for "menu enable",
+ // kFalse for "menu disable
vimmenu_T menuarg;
modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
@@ -133,10 +133,10 @@ ex_menu(exarg_T *eap)
* Check for "disable" or "enable" argument.
*/
if (STRNCMP(arg, "enable", 6) == 0 && ascii_iswhite(arg[6])) {
- enable = TRUE;
+ enable = kTrue;
arg = skipwhite(arg + 6);
} else if (STRNCMP(arg, "disable", 7) == 0 && ascii_iswhite(arg[7])) {
- enable = FALSE;
+ enable = kFalse;
arg = skipwhite(arg + 7);
}
@@ -160,22 +160,21 @@ ex_menu(exarg_T *eap)
/*
* If there is only a menu name, display menus with that name.
*/
- if (*map_to == NUL && !unmenu && enable == MAYBE) {
+ if (*map_to == NUL && !unmenu && enable == kNone) {
show_menus(menu_path, modes);
goto theend;
- } else if (*map_to != NUL && (unmenu || enable != MAYBE)) {
+ } else if (*map_to != NUL && (unmenu || enable != kNone)) {
EMSG(_(e_trailing));
goto theend;
}
- if (enable != MAYBE) {
- /*
- * Change sensitivity of the menu.
- * For the PopUp menu, remove a menu for each mode separately.
- * Careful: menu_nable_recurse() changes menu_path.
- */
- if (STRCMP(menu_path, "*") == 0) /* meaning: do all menus */
+ if (enable != kNone) {
+ // Change sensitivity of the menu.
+ // For the PopUp menu, remove a menu for each mode separately.
+ // Careful: menu_nable_recurse() changes menu_path.
+ if (STRCMP(menu_path, "*") == 0) { // meaning: do all menus
menu_path = (char_u *)"";
+ }
if (menu_is_popup(menu_path)) {
for (i = 0; i < MENU_INDEX_TIP; ++i)
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 46fc9115b4..947cd0735e 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1219,7 +1219,7 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
// Don't include composing chars after the end.
mb_l = utfc_ptr2len_len((char_u *)str, len + 1);
if (mb_l > 1) {
- c = (*mb_ptr2char)((char_u *)str);
+ c = utf_ptr2char((char_u *)str);
if (vim_isprintc(c)) {
// Printable multi-byte char: count the cells.
retval += (*mb_ptr2cells)((char_u *)str);
@@ -1480,7 +1480,7 @@ void msg_prt_line(char_u *s, int list)
col += (*mb_ptr2cells)(s);
char buf[MB_MAXBYTES + 1];
if (lcs_nbsp != NUL && list
- && (mb_ptr2char(s) == 160 || mb_ptr2char(s) == 0x202f)) {
+ && (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) {
mb_char2bytes(lcs_nbsp, (char_u *)buf);
buf[(*mb_ptr2len)((char_u *)buf)] = NUL;
} else {
@@ -2866,14 +2866,12 @@ do_dialog (
// Make the character lowercase, as chars in "hotkeys" are.
c = mb_tolower(c);
retval = 1;
- for (i = 0; hotkeys[i]; ++i) {
- if (has_mbyte) {
- if ((*mb_ptr2char)(hotkeys + i) == c)
- break;
- i += (*mb_ptr2len)(hotkeys + i) - 1;
- } else if (hotkeys[i] == c)
+ for (i = 0; hotkeys[i]; i++) {
+ if (utf_ptr2char(hotkeys + i) == c) {
break;
- ++retval;
+ }
+ i += utfc_ptr2len(hotkeys + i) - 1;
+ retval++;
}
if (hotkeys[i])
break;
@@ -2905,25 +2903,13 @@ copy_char (
int lowercase /* make character lower case */
)
{
- int len;
- int c;
-
- if (has_mbyte) {
- if (lowercase) {
- c = mb_tolower((*mb_ptr2char)(from));
- return (*mb_char2bytes)(c, to);
- } else {
- len = (*mb_ptr2len)(from);
- memmove(to, from, (size_t)len);
- return len;
- }
- } else {
- if (lowercase)
- *to = (char_u)TOLOWER_LOC(*from);
- else
- *to = *from;
- return 1;
+ if (lowercase) {
+ int c = mb_tolower(utf_ptr2char(from));
+ return utf_char2bytes(c, to);
}
+ int len = utfc_ptr2len(from);
+ memmove(to, from, (size_t)len);
+ return len;
}
#define HAS_HOTKEY_LEN 30
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 684f486c04..84d8c995a6 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -165,8 +165,8 @@ open_line (
*p_extra = NUL;
}
- u_clearline(); /* cannot do "U" command when adding lines */
- did_si = FALSE;
+ u_clearline(); // cannot do "U" command when adding lines
+ did_si = false;
ai_col = 0;
/*
@@ -286,8 +286,8 @@ open_line (
* checking for "if" and the like.
*/
if (last_char == '{') {
- did_si = TRUE; /* do indent */
- no_si = TRUE; /* don't delete it when '{' typed */
+ did_si = true; // do indent
+ no_si = true; // don't delete it when '{' typed
}
/*
* Look for "if" and the like, use 'cinwords'.
@@ -296,7 +296,7 @@ open_line (
*/
else if (last_char != ';' && last_char != '}'
&& cin_is_cinword(ptr))
- did_si = TRUE;
+ did_si = true;
}
} else { // dir == BACKWARD
// Skip preprocessor directives, unless they are
@@ -320,17 +320,19 @@ open_line (
}
}
p = skipwhite(ptr);
- if (*p == '}') /* if line starts with '}': do indent */
- did_si = TRUE;
- else /* can delete indent when '{' typed */
- can_si_back = TRUE;
+ if (*p == '}') { // if line starts with '}': do indent
+ did_si = true;
+ } else { // can delete indent when '{' typed
+ can_si_back = true;
+ }
}
curwin->w_cursor = old_cursor;
}
- if (do_si)
- can_si = TRUE;
+ if (do_si) {
+ can_si = true;
+ }
- did_ai = TRUE;
+ did_ai = true;
}
/*
@@ -665,7 +667,7 @@ open_line (
}
}
- did_si = can_si = FALSE;
+ did_si = can_si = false;
} else if (comment_end != NULL) {
// We have finished a comment, so we don't use the leader.
// If this was a C-comment and 'ai' or 'si' is set do a normal
@@ -699,17 +701,17 @@ open_line (
replace_push(NUL); /* end of extra blanks */
if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES)) {
while ((*p_extra == ' ' || *p_extra == '\t')
- && (!enc_utf8
- || !utf_iscomposing(utf_ptr2char(p_extra + 1)))
- ) {
- if (REPLACE_NORMAL(State))
+ && !utf_iscomposing(utf_ptr2char(p_extra + 1))) {
+ if (REPLACE_NORMAL(State)) {
replace_push(*p_extra);
- ++p_extra;
- ++less_cols_off;
+ }
+ p_extra++;
+ less_cols_off++;
}
}
- if (*p_extra != NUL)
- did_ai = FALSE; /* append some text, don't truncate now */
+ if (*p_extra != NUL) {
+ did_ai = false; // append some text, don't truncate now
+ }
/* columns for marks adjusted for removed columns */
less_cols = (int)(p_extra - saved_line);
@@ -736,7 +738,7 @@ open_line (
}
STRCAT(leader, p_extra);
p_extra = leader;
- did_ai = TRUE; /* So truncating blanks works with comments */
+ did_ai = true; // So truncating blanks works with comments
less_cols -= lead_len;
} else
end_comment_pending = NUL; /* turns out there was no leader */
@@ -769,7 +771,7 @@ open_line (
(void)u_save_cursor(); /* errors are ignored! */
vr_lines_changed++;
}
- ml_replace(curwin->w_cursor.lnum, p_extra, TRUE);
+ ml_replace(curwin->w_cursor.lnum, p_extra, true);
changed_bytes(curwin->w_cursor.lnum, 0);
curwin->w_cursor.lnum--;
did_append = FALSE;
@@ -812,8 +814,9 @@ open_line (
}
}
newcol += curwin->w_cursor.col;
- if (no_si)
- did_si = FALSE;
+ if (no_si) {
+ did_si = false;
+ }
}
/*
@@ -828,12 +831,13 @@ open_line (
if (dir == FORWARD) {
if (trunc_line || (State & INSERT)) {
- /* truncate current line at cursor */
+ // truncate current line at cursor
saved_line[curwin->w_cursor.col] = NUL;
- /* Remove trailing white space, unless OPENLINE_KEEPTRAIL used. */
- if (trunc_line && !(flags & OPENLINE_KEEPTRAIL))
+ // Remove trailing white space, unless OPENLINE_KEEPTRAIL used.
+ if (trunc_line && !(flags & OPENLINE_KEEPTRAIL)) {
truncate_spaces(saved_line);
- ml_replace(curwin->w_cursor.lnum, saved_line, FALSE);
+ }
+ ml_replace(curwin->w_cursor.lnum, saved_line, false);
saved_line = NULL;
if (did_append) {
changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
@@ -909,8 +913,8 @@ open_line (
/* Put new line in p_extra */
p_extra = vim_strsave(get_cursor_line_ptr());
- /* Put back original line */
- ml_replace(curwin->w_cursor.lnum, next_line, FALSE);
+ // Put back original line
+ ml_replace(curwin->w_cursor.lnum, next_line, false);
/* Insert new stuff into line again */
curwin->w_cursor.col = 0;
@@ -1203,16 +1207,15 @@ int get_last_leader_offset(char_u *line, char_u **flags)
/*
* Return the number of window lines occupied by buffer line "lnum".
*/
-int plines(linenr_T lnum)
+int plines(const linenr_T lnum)
{
- return plines_win(curwin, lnum, TRUE);
+ return plines_win(curwin, lnum, true);
}
-int
-plines_win (
- win_T *wp,
- linenr_T lnum,
- int winheight /* when TRUE limit to window height */
+int plines_win(
+ win_T *const wp,
+ const linenr_T lnum,
+ const bool winheight // when true limit to window height
)
{
/* Check for filler lines above this buffer line. When folded the result
@@ -1220,34 +1223,34 @@ plines_win (
return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
}
-int plines_nofill(linenr_T lnum)
+int plines_nofill(const linenr_T lnum)
{
- return plines_win_nofill(curwin, lnum, TRUE);
+ return plines_win_nofill(curwin, lnum, true);
}
-int
-plines_win_nofill (
- win_T *wp,
- linenr_T lnum,
- int winheight /* when TRUE limit to window height */
+int plines_win_nofill(
+ win_T *const wp,
+ const linenr_T lnum,
+ const bool winheight // when true limit to window height
)
{
- int lines;
-
- if (!wp->w_p_wrap)
+ if (!wp->w_p_wrap) {
return 1;
+ }
- if (wp->w_width == 0)
+ if (wp->w_width == 0) {
return 1;
+ }
- /* A folded lines is handled just like an empty line. */
- /* NOTE: Caller must handle lines that are MAYBE folded. */
- if (lineFolded(wp, lnum) == TRUE)
+ // A folded lines is handled just like an empty line.
+ if (lineFolded(wp, lnum)) {
return 1;
+ }
- lines = plines_win_nofold(wp, lnum);
- if (winheight > 0 && lines > wp->w_height)
+ const int lines = plines_win_nofold(wp, lnum);
+ if (winheight && lines > wp->w_height) {
return wp->w_height;
+ }
return lines;
}
@@ -1347,11 +1350,12 @@ int plines_m_win(win_T *wp, linenr_T first, linenr_T last)
++count; /* count 1 for "+-- folded" line */
first += x;
} else {
- if (first == wp->w_topline)
- count += plines_win_nofill(wp, first, TRUE) + wp->w_topfill;
- else
- count += plines_win(wp, first, TRUE);
- ++first;
+ if (first == wp->w_topline) {
+ count += plines_win_nofill(wp, first, true) + wp->w_topfill;
+ } else {
+ count += plines_win(wp, first, true);
+ }
+ first++;
}
}
return count;
@@ -1494,8 +1498,8 @@ void ins_char_bytes(char_u *buf, size_t charlen)
p[i] = ' ';
}
- /* Replace the line in the buffer. */
- ml_replace(lnum, newp, FALSE);
+ // Replace the line in the buffer.
+ ml_replace(lnum, newp, false);
// mark the buffer as changed and prepare for displaying
changed_bytes(lnum, (colnr_T)col);
@@ -1508,7 +1512,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
&& msg_silent == 0
&& !ins_compl_active()
) {
- showmatch(mb_ptr2char(buf));
+ showmatch(utf_ptr2char(buf));
}
if (!p_ri || (State & REPLACE_FLAG)) {
@@ -1545,19 +1549,17 @@ void ins_str(char_u *s)
memmove(newp, oldp, (size_t)col);
memmove(newp + col, s, (size_t)newlen);
memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1));
- ml_replace(lnum, newp, FALSE);
+ ml_replace(lnum, newp, false);
changed_bytes(lnum, col);
curwin->w_cursor.col += newlen;
}
-/*
- * Delete one character under the cursor.
- * If "fixpos" is TRUE, don't leave the cursor on the NUL after the line.
- * Caller must have prepared for undo.
- *
- * return FAIL for failure, OK otherwise
- */
-int del_char(int fixpos)
+// Delete one character under the cursor.
+// If "fixpos" is true, don't leave the cursor on the NUL after the line.
+// Caller must have prepared for undo.
+//
+// return FAIL for failure, OK otherwise
+int del_char(bool fixpos)
{
if (has_mbyte) {
/* Make sure the cursor is at the start of a character. */
@@ -1663,8 +1665,9 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
memmove(newp, oldp, (size_t)col);
}
memmove(newp + col, oldp + col + count, (size_t)movelen);
- if (!was_alloced)
- ml_replace(lnum, newp, FALSE);
+ if (!was_alloced) {
+ ml_replace(lnum, newp, false);
+ }
/* mark the buffer as changed and prepare for displaying */
changed_bytes(lnum, curwin->w_cursor.col);
@@ -1745,11 +1748,7 @@ del_lines (
int gchar_pos(pos_T *pos)
{
- char_u *ptr = ml_get_pos(pos);
-
- if (has_mbyte)
- return (*mb_ptr2char)(ptr);
- return (int)*ptr;
+ return utf_ptr2char(ml_get_pos(pos));
}
/*
@@ -2385,12 +2384,12 @@ int get_keystroke(void)
}
break;
}
- if (has_mbyte) {
- if (MB_BYTE2LEN(n) > len)
- continue; /* more bytes to get */
- buf[len >= buflen ? buflen - 1 : len] = NUL;
- n = (*mb_ptr2char)(buf);
+ if (MB_BYTE2LEN(n) > len) {
+ // more bytes to get.
+ continue;
}
+ buf[len >= buflen ? buflen - 1 : len] = NUL;
+ n = utf_ptr2char(buf);
#ifdef UNIX
if (n == intr_char)
n = ESC;
@@ -2479,7 +2478,7 @@ int prompt_for_number(int *mouse_used)
save_cmdline_row = cmdline_row;
cmdline_row = 0;
save_State = State;
- State = CMDLINE;
+ State = ASKMORE; // prevents a screen update when using a timer
i = get_number(TRUE, mouse_used);
if (KeyTyped) {
@@ -2836,4 +2835,3 @@ int goto_im(void)
{
return p_im && stuff_empty() && typebuf_typed();
}
-
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 8c615f52e7..3c792326a4 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -125,6 +125,9 @@ retnomove:
// find the window where the row is in
wp = mouse_find_win(&row, &col);
+ if (wp == NULL) {
+ return IN_UNKNOWN;
+ }
dragwin = NULL;
// winpos and height may change in win_enter()!
if (row >= wp->w_height) { // In (or below) status line
@@ -427,6 +430,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
// Find the window at screen position "*rowp" and "*colp". The positions are
// updated to become relative to the top-left of the window.
+// Returns NULL when something is wrong.
win_T *mouse_find_win(int *rowp, int *colp)
{
frame_T *fp;
@@ -450,7 +454,14 @@ win_T *mouse_find_win(int *rowp, int *colp)
}
}
}
- return fp->fr_win;
+ // When using a timer that closes a window the window might not actually
+ // exist.
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp == fp->fr_win) {
+ return wp;
+ }
+ }
+ return NULL;
}
/*
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 570368991a..225fe4aa9a 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2015,7 +2015,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
default:
clearopbeep(oap);
}
- virtual_op = MAYBE;
+ virtual_op = kNone;
if (!gui_yank) {
/*
* if 'sol' not set, go back to old column for some commands
@@ -2090,7 +2090,7 @@ static void op_colon(oparg_T *oap)
*/
static void op_function(oparg_T *oap)
{
- int save_virtual_op = virtual_op;
+ const TriState save_virtual_op = virtual_op;
if (*p_opfunc == NUL)
EMSG(_("E774: 'operatorfunc' is empty"));
@@ -2113,7 +2113,7 @@ static void op_function(oparg_T *oap)
// Reset virtual_op so that 'virtualedit' can be changed in the
// function.
- virtual_op = MAYBE;
+ virtual_op = kNone;
(void)call_func_retnr(p_opfunc, 1, argv, false);
@@ -3994,8 +3994,12 @@ static void nv_mousescroll(cmdarg_T *cap)
row = mouse_row;
col = mouse_col;
- /* find the window at the pointer coordinates */
- curwin = mouse_find_win(&row, &col);
+ // find the window at the pointer coordinates
+ win_T *const wp = mouse_find_win(&row, &col);
+ if (wp == NULL) {
+ return;
+ }
+ curwin = wp;
curbuf = curwin->w_buffer;
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 67171cb27e..7defde731a 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -310,30 +310,32 @@ void shift_line(
*/
static void shift_block(oparg_T *oap, int amount)
{
- int left = (oap->op_type == OP_LSHIFT);
- int oldstate = State;
- int total;
- char_u *newp, *oldp;
- int oldcol = curwin->w_cursor.col;
- int p_sw = get_sw_value(curbuf);
- int p_ts = (int)curbuf->b_p_ts;
+ const bool left = (oap->op_type == OP_LSHIFT);
+ const int oldstate = State;
+ char_u *newp;
+ const int oldcol = curwin->w_cursor.col;
+ const int p_sw = get_sw_value(curbuf);
+ const int p_ts = (int)curbuf->b_p_ts;
struct block_def bd;
int incr;
- colnr_T ws_vcol;
int i = 0, j = 0;
- int len;
- int old_p_ri = p_ri;
+ const int old_p_ri = p_ri;
p_ri = 0; /* don't want revins in indent */
- State = INSERT; /* don't want REPLACE for State */
- block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
- if (bd.is_short)
+ State = INSERT; // don't want REPLACE for State
+ block_prep(oap, &bd, curwin->w_cursor.lnum, true);
+ if (bd.is_short) {
return;
+ }
+
+ // total is number of screen columns to be inserted/removed
+ int total = (int)((unsigned)amount * (unsigned)p_sw);
+ if ((total / p_sw) != amount) {
+ return; // multiplication overflow
+ }
- /* total is number of screen columns to be inserted/removed */
- total = amount * p_sw;
- oldp = get_cursor_line_ptr();
+ char_u *const oldp = get_cursor_line_ptr();
if (!left) {
/*
@@ -342,8 +344,8 @@ static void shift_block(oparg_T *oap, int amount)
* 3. Divvy into TABs & spp
* 4. Construct new string
*/
- total += bd.pre_whitesp; /* all virtual WS up to & incl a split TAB */
- ws_vcol = bd.start_vcol - bd.pre_whitesp;
+ total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
+ colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
if (bd.startspaces) {
if (has_mbyte) {
if ((*mb_ptr2len)(bd.textstart) == 1) {
@@ -372,8 +374,8 @@ static void shift_block(oparg_T *oap, int amount)
j = total;
/* if we're splitting a TAB, allow for it */
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
- len = (int)STRLEN(bd.textstart) + 1;
- newp = (char_u *) xmalloc((size_t)(bd.textcol + i + j + len));
+ const int len = (int)STRLEN(bd.textstart) + 1;
+ newp = (char_u *)xmalloc((size_t)(bd.textcol + i + j + len));
memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
memmove(newp, oldp, (size_t)bd.textcol);
memset(newp + bd.textcol, TAB, (size_t)i);
@@ -390,10 +392,7 @@ static void shift_block(oparg_T *oap, int amount)
size_t fill; // nr of spaces that replace a TAB
size_t new_line_len; // the length of the line after the
// block shift
- colnr_T block_space_width;
- colnr_T shift_amount;
char_u *non_white = bd.textstart;
- colnr_T non_white_col;
/*
* Firstly, let's find the first non-whitespace character that is
@@ -410,19 +409,20 @@ static void shift_block(oparg_T *oap, int amount)
MB_PTR_ADV(non_white);
}
- /* The character's column is in "bd.start_vcol". */
- non_white_col = bd.start_vcol;
+ // The character's column is in "bd.start_vcol".
+ colnr_T non_white_col = bd.start_vcol;
while (ascii_iswhite(*non_white)) {
incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
non_white_col += incr;
}
- block_space_width = non_white_col - oap->start_vcol;
- /* We will shift by "total" or "block_space_width", whichever is less.
- */
- shift_amount = (block_space_width < total ? block_space_width : total);
+ const colnr_T block_space_width = non_white_col - oap->start_vcol;
+ // We will shift by "total" or "block_space_width", whichever is less.
+ const colnr_T shift_amount = block_space_width < total
+ ? block_space_width
+ : total;
// The column to which we will shift the text.
destination_col = non_white_col - shift_amount;
@@ -454,7 +454,7 @@ static void shift_block(oparg_T *oap, int amount)
fill = (size_t)(destination_col - verbatim_copy_width);
assert(verbatim_copy_end - oldp >= 0);
- size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp);
+ const size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp);
// The replacement line will consist of:
// - the beginning of the original line up to "verbatim_copy_end",
// - "fill" number of spaces,
@@ -466,8 +466,8 @@ static void shift_block(oparg_T *oap, int amount)
memset(newp + verbatim_diff, ' ', fill);
STRMOVE(newp + verbatim_diff + fill, non_white);
}
- /* replace the line */
- ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ // replace the line
+ ml_replace(curwin->w_cursor.lnum, newp, false);
changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol);
State = oldstate;
curwin->w_cursor.col = oldcol;
@@ -561,7 +561,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
offset += count;
STRMOVE(newp + offset, oldp);
- ml_replace(lnum, newp, FALSE);
+ ml_replace(lnum, newp, false);
if (lnum == oap->end.lnum) {
/* Set "']" mark to the end of the block instead of the end of
@@ -1427,10 +1427,11 @@ int op_delete(oparg_T *oap)
return FAIL;
}
- for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum) {
- block_prep(oap, &bd, lnum, TRUE);
- if (bd.textlen == 0) /* nothing to delete */
+ for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) {
+ block_prep(oap, &bd, lnum, true);
+ if (bd.textlen == 0) { // nothing to delete
continue;
+ }
/* Adjust cursor position for tab replaced by spaces and 'lbr'. */
if (lnum == curwin->w_cursor.lnum) {
@@ -1473,9 +1474,9 @@ int op_delete(oparg_T *oap)
}
if (u_save_cursor() == FAIL)
return FAIL;
- if (curbuf->b_p_ai) { /* don't delete indent */
- beginline(BL_WHITE); /* cursor on first non-white */
- did_ai = TRUE; /* delete the indent when ESC hit */
+ if (curbuf->b_p_ai) { // don't delete indent
+ beginline(BL_WHITE); // cursor on first non-white
+ did_ai = true; // delete the indent when ESC hit
ai_col = curwin->w_cursor.col;
} else
beginline(0); /* cursor in column 0 */
@@ -1656,11 +1657,12 @@ int op_replace(oparg_T *oap, int c)
*/
if (oap->motion_type == kMTBlockWise) {
bd.is_MAX = (curwin->w_curswant == MAXCOL);
- for (; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) {
- curwin->w_cursor.col = 0; /* make sure cursor position is valid */
- block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
- if (bd.textlen == 0 && (!virtual_op || bd.is_MAX))
- continue; /* nothing to replace */
+ for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) {
+ curwin->w_cursor.col = 0; // make sure cursor position is valid
+ block_prep(oap, &bd, curwin->w_cursor.lnum, true);
+ if (bd.textlen == 0 && (!virtual_op || bd.is_MAX)) {
+ continue; // nothing to replace
+ }
/* n == number of extra chars required
* If we split a TAB, it may be replaced by several characters.
@@ -1747,8 +1749,8 @@ int op_replace(oparg_T *oap, int c)
after_p = (char_u *)xmalloc(after_p_len);
memmove(after_p, oldp, after_p_len);
}
- /* replace the line */
- ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ // replace the line
+ ml_replace(curwin->w_cursor.lnum, newp, false);
if (after_p != NULL) {
ml_append(curwin->w_cursor.lnum++, after_p, (int)after_p_len, false);
appended_lines_mark(curwin->w_cursor.lnum, 1L);
@@ -1852,7 +1854,7 @@ void op_tilde(oparg_T *oap)
for (; pos.lnum <= oap->end.lnum; pos.lnum++) {
int one_change;
- block_prep(oap, &bd, pos.lnum, FALSE);
+ block_prep(oap, &bd, pos.lnum, false);
pos.col = bd.textcol;
one_change = swapchars(oap->op_type, &pos, bd.textlen);
did_change |= one_change;
@@ -1956,7 +1958,7 @@ int swapchar(int op_type, pos_T *pos)
/* Special handling of German sharp s: change to "SS". */
curwin->w_cursor = *pos;
- del_char(FALSE);
+ del_char(false);
ins_char('S');
ins_char('S');
curwin->w_cursor = sp;
@@ -2030,8 +2032,8 @@ void op_insert(oparg_T *oap, long count1)
--curwin->w_cursor.col;
ve_flags = old_ve_flags;
}
- /* Get the info about the block before entering the text */
- block_prep(oap, &bd, oap->start.lnum, TRUE);
+ // Get the info about the block before entering the text
+ block_prep(oap, &bd, oap->start.lnum, true);
firstline = ml_get(oap->start.lnum) + bd.textcol;
if (oap->op_type == OP_APPEND)
firstline += bd.textlen;
@@ -2119,7 +2121,7 @@ void op_insert(oparg_T *oap, long count1)
* tabs. Get the starting column again and correct the length.
* Don't do this when "$" used, end-of-line will have changed.
*/
- block_prep(oap, &bd2, oap->start.lnum, TRUE);
+ block_prep(oap, &bd2, oap->start.lnum, true);
if (!bd.is_MAX || bd2.textlen < bd.textlen) {
if (oap->op_type == OP_APPEND) {
pre_textlen += bd2.textlen - bd.textlen;
@@ -2178,7 +2180,7 @@ int op_change(oparg_T *oap)
if (!p_paste && curbuf->b_p_si
&& !curbuf->b_p_cin
)
- can_si = TRUE; /* It's like opening a new line, do si */
+ can_si = true; // It's like opening a new line, do si
}
/* First delete the text in the region. In an empty buffer only need to
@@ -2239,7 +2241,7 @@ int op_change(oparg_T *oap)
STRLCPY(ins_text, firstline + bd.textcol, ins_len + 1);
for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
linenr++) {
- block_prep(oap, &bd, linenr, TRUE);
+ block_prep(oap, &bd, linenr, true);
if (!bd.is_short || virtual_op) {
pos_T vpos;
@@ -2263,7 +2265,7 @@ int op_change(oparg_T *oap)
offset += ins_len;
oldp += bd.textcol;
STRMOVE(newp + offset, oldp);
- ml_replace(linenr, newp, FALSE);
+ ml_replace(linenr, newp, false);
}
}
check_cursor();
@@ -3117,10 +3119,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
ptr += yanklen;
}
STRMOVE(ptr, oldp + col);
- ml_replace(lnum, newp, FALSE);
- /* Place cursor on last putted char. */
+ ml_replace(lnum, newp, false);
+ // Place cursor on last putted char.
if (lnum == curwin->w_cursor.lnum) {
- /* make sure curwin->w_virtcol is updated */
+ // make sure curwin->w_virtcol is updated
changed_cline_bef_curs();
curwin->w_cursor.col += (colnr_T)(totlen - 1);
}
@@ -3164,7 +3166,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
memmove(newp, oldp, (size_t)col);
/* append to first line */
memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
- ml_replace(lnum, newp, FALSE);
+ ml_replace(lnum, newp, false);
curwin->w_cursor.lnum = lnum;
i = 1;
@@ -3620,9 +3622,9 @@ int do_join(size_t count,
curr = skipwhite(curr);
if (*curr != ')' && currsize != 0 && endcurr1 != TAB
&& (!has_format_option(FO_MBYTE_JOIN)
- || (mb_ptr2char(curr) < 0x100 && endcurr1 < 0x100))
+ || (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100))
&& (!has_format_option(FO_MBYTE_JOIN2)
- || mb_ptr2char(curr) < 0x100 || endcurr1 < 0x100)
+ || utf_ptr2char(curr) < 0x100 || endcurr1 < 0x100)
) {
/* don't add a space if the line is ending in a space */
if (endcurr1 == ' ')
@@ -3639,18 +3641,12 @@ int do_join(size_t count,
sumsize += currsize + spaces[t];
endcurr1 = endcurr2 = NUL;
if (insert_space && currsize > 0) {
- if (has_mbyte) {
- cend = curr + currsize;
+ cend = curr + currsize;
+ MB_PTR_BACK(curr, cend);
+ endcurr1 = utf_ptr2char(cend);
+ if (cend > curr) {
MB_PTR_BACK(curr, cend);
- endcurr1 = (*mb_ptr2char)(cend);
- if (cend > curr) {
- MB_PTR_BACK(curr, cend);
- endcurr2 = (*mb_ptr2char)(cend);
- }
- } else {
- endcurr1 = *(curr + currsize - 1);
- if (currsize > 1)
- endcurr2 = *(curr + currsize - 2);
+ endcurr2 = utf_ptr2char(cend);
}
}
line_breakcheck();
@@ -3693,7 +3689,7 @@ int do_join(size_t count,
curr = skipwhite(curr);
currsize = (int)STRLEN(curr);
}
- ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ ml_replace(curwin->w_cursor.lnum, newp, false);
if (setmark) {
// Set the '] mark.
@@ -4245,7 +4241,8 @@ int paragraph_start(linenr_T lnum)
* - start/endspaces is the number of columns of the first/last yanked char
* that are to be yanked.
*/
-static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, int is_del)
+static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
+ bool is_del)
{
int incr = 0;
char_u *pend;
@@ -5382,8 +5379,8 @@ void cursor_pos_info(dict_T *dict)
switch (l_VIsual_mode) {
case Ctrl_V:
virtual_op = virtual_active();
- block_prep(&oparg, &bd, lnum, 0);
- virtual_op = MAYBE;
+ block_prep(&oparg, &bd, lnum, false);
+ virtual_op = kNone;
s = bd.textstart;
len = (long)bd.textlen;
break;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 50c172b580..8e2264c6a7 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2703,7 +2703,7 @@ did_set_string_option (
if (*p != NUL)
x2 = *p++;
if (*p != NUL) {
- x3 = mb_ptr2char(p);
+ x3 = utf_ptr2char(p);
p += mb_ptr2len(p);
}
if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ',')) {
@@ -6406,22 +6406,25 @@ static void langmap_set(void)
++p;
break;
}
- if (p[0] == '\\' && p[1] != NUL)
- ++p;
- from = (*mb_ptr2char)(p);
+ if (p[0] == '\\' && p[1] != NUL) {
+ p++;
+ }
+ from = utf_ptr2char(p);
to = NUL;
if (p2 == NULL) {
MB_PTR_ADV(p);
if (p[0] != ',') {
- if (p[0] == '\\')
- ++p;
- to = (*mb_ptr2char)(p);
+ if (p[0] == '\\') {
+ p++;
+ }
+ to = utf_ptr2char(p);
}
} else {
if (p2[0] != ',') {
- if (p2[0] == '\\')
- ++p2;
- to = (*mb_ptr2char)(p2);
+ if (p2[0] == '\\') {
+ p2++;
+ }
+ to = utf_ptr2char(p2);
}
}
if (to == NUL) {
@@ -6846,66 +6849,37 @@ int get_sts_value(void)
*/
void find_mps_values(int *initc, int *findc, int *backwards, int switchit)
{
- char_u *ptr;
+ char_u *ptr = curbuf->b_p_mps;
- ptr = curbuf->b_p_mps;
while (*ptr != NUL) {
- if (has_mbyte) {
- char_u *prev;
-
- if (mb_ptr2char(ptr) == *initc) {
- if (switchit) {
- *findc = *initc;
- *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
- *backwards = TRUE;
- } else {
- *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
- *backwards = FALSE;
- }
- return;
- }
- prev = ptr;
- ptr += mb_ptr2len(ptr) + 1;
- if (mb_ptr2char(ptr) == *initc) {
- if (switchit) {
- *findc = *initc;
- *initc = mb_ptr2char(prev);
- *backwards = FALSE;
- } else {
- *findc = mb_ptr2char(prev);
- *backwards = TRUE;
- }
- return;
- }
- ptr += mb_ptr2len(ptr);
- } else {
- if (*ptr == *initc) {
- if (switchit) {
- *backwards = TRUE;
- *findc = *initc;
- *initc = ptr[2];
- } else {
- *backwards = FALSE;
- *findc = ptr[2];
- }
- return;
+ if (utf_ptr2char(ptr) == *initc) {
+ if (switchit) {
+ *findc = *initc;
+ *initc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1);
+ *backwards = true;
+ } else {
+ *findc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1);
+ *backwards = false;
}
- ptr += 2;
- if (*ptr == *initc) {
- if (switchit) {
- *backwards = FALSE;
- *findc = *initc;
- *initc = ptr[-2];
- } else {
- *backwards = TRUE;
- *findc = ptr[-2];
- }
- return;
+ return;
+ }
+ char_u *prev = ptr;
+ ptr += utfc_ptr2len(ptr) + 1;
+ if (utf_ptr2char(ptr) == *initc) {
+ if (switchit) {
+ *findc = *initc;
+ *initc = utf_ptr2char(prev);
+ *backwards = false;
+ } else {
+ *findc = utf_ptr2char(prev);
+ *backwards = true;
}
- ++ptr;
+ return;
+ }
+ ptr += utfc_ptr2len(ptr);
+ if (*ptr == ',') {
+ ptr++;
}
- if (*ptr == ',')
- ++ptr;
}
}
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 5ae306e00e..7cd11e5c31 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -2044,9 +2044,9 @@ return {
vi_def=true,
varname='p_sp',
defaults={
- condition='UNIX',
- if_true={vi="| tee"},
- if_false={vi=">"},
+ condition='WIN32',
+ if_true={vi=">%s 2>&1"},
+ if_false={vi="| tee"},
}
},
{
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 664dd3e968..4308c4e87e 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1044,10 +1044,12 @@ qf_init_ext(
if (newlist || qi->qf_curlist == qi->qf_listcount) {
// make place for a new list
qf_new_list(qi, qf_title);
- } else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
+ } else {
// Adding to existing list, use last entry.
adding = true;
- old_last = qi->qf_lists[qi->qf_curlist].qf_last;
+ if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
+ old_last = qi->qf_lists[qi->qf_curlist].qf_last;
+ }
}
// Use the local value of 'errorformat' if it's set.
@@ -2885,6 +2887,7 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
qf_update_win_titlevar(qi);
qf_fill_buffer(qi, buf, old_last);
+ buf_inc_changedtick(buf);
if (old_last == NULL) {
(void)qf_win_pos_update(qi, 0);
@@ -4209,7 +4212,8 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (qi->qf_lists[qf_idx].qf_ctx != NULL) {
di = tv_dict_item_alloc_len(S_LEN("context"));
tv_copy(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
- if (tv_dict_add(retdict, di) == FAIL) {
+ status = tv_dict_add(retdict, di);
+ if (status == FAIL) {
tv_dict_item_free(di);
}
} else {
@@ -4398,6 +4402,7 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)
typval_T *ctx = xcalloc(1, sizeof(typval_T));
tv_copy(&di->di_tv, ctx);
qi->qf_lists[qf_idx].qf_ctx = ctx;
+ retval = OK;
}
return retval;
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index d76da62c6d..be6c43493b 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -772,13 +772,9 @@ static int get_equi_class(char_u **pp)
char_u *p = *pp;
if (p[1] == '=') {
- if (has_mbyte)
- l = (*mb_ptr2len)(p + 2);
+ l = (*mb_ptr2len)(p + 2);
if (p[l + 2] == '=' && p[l + 3] == ']') {
- if (has_mbyte)
- c = mb_ptr2char(p + 2);
- else
- c = p[2];
+ c = utf_ptr2char(p + 2);
*pp += l + 4;
return c;
}
@@ -1107,13 +1103,9 @@ static int get_coll_element(char_u **pp)
char_u *p = *pp;
if (p[0] != NUL && p[1] == '.') {
- if (has_mbyte)
- l = (*mb_ptr2len)(p + 2);
+ l = utfc_ptr2len(p + 2);
if (p[l + 2] == '.' && p[l + 3] == ']') {
- if (has_mbyte)
- c = mb_ptr2char(p + 2);
- else
- c = p[2];
+ c = utf_ptr2char(p + 2);
*pp += l + 4;
return c;
}
@@ -1299,10 +1291,7 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags)
}
if (OP(scan) == EXACTLY) {
- if (has_mbyte)
- r->regstart = (*mb_ptr2char)(OPERAND(scan));
- else
- r->regstart = *OPERAND(scan);
+ r->regstart = utf_ptr2char(OPERAND(scan));
} else if (OP(scan) == BOW
|| OP(scan) == EOW
|| OP(scan) == NOTHING
@@ -1310,10 +1299,7 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags)
|| OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE) {
char_u *regnext_scan = regnext(scan);
if (OP(regnext_scan) == EXACTLY) {
- if (has_mbyte)
- r->regstart = (*mb_ptr2char)(OPERAND(regnext_scan));
- else
- r->regstart = *OPERAND(regnext_scan);
+ r->regstart = utf_ptr2char(OPERAND(regnext_scan));
}
}
@@ -2412,20 +2398,16 @@ collection:
break;
}
} else {
- if (has_mbyte) {
- int len;
-
- /* produce a multibyte character, including any
- * following composing characters */
- startc = mb_ptr2char(regparse);
- len = (*mb_ptr2len)(regparse);
- if (enc_utf8 && utf_char2len(startc) != len)
- startc = -1; /* composing chars */
- while (--len >= 0)
- regc(*regparse++);
- } else {
- startc = *regparse++;
- regc(startc);
+ // produce a multibyte character, including any
+ // following composing characters.
+ startc = utf_ptr2char(regparse);
+ int len = utfc_ptr2len(regparse);
+ if (utf_char2len(startc) != len) {
+ // composing chars
+ startc = -1;
+ }
+ while (--len >= 0) {
+ regc(*regparse++);
}
}
}
@@ -2906,17 +2888,13 @@ static int peekchr(void)
* Next character can never be (made) magic?
* Then backslashing it won't do anything.
*/
- if (has_mbyte)
- curchr = (*mb_ptr2char)(regparse + 1);
- else
- curchr = c;
+ curchr = utf_ptr2char(regparse + 1);
}
break;
}
default:
- if (has_mbyte)
- curchr = (*mb_ptr2char)(regparse);
+ curchr = utf_ptr2char(regparse);
}
return curchr;
@@ -3466,12 +3444,7 @@ static long bt_regexec_both(char_u *line,
/* If there is a "must appear" string, look for it. */
if (prog->regmust != NULL) {
- int c;
-
- if (has_mbyte)
- c = (*mb_ptr2char)(prog->regmust);
- else
- c = *prog->regmust;
+ int c = utf_ptr2char(prog->regmust);
s = line + col;
// This is used very often, esp. for ":global". Use two versions of
@@ -3502,16 +3475,11 @@ static long bt_regexec_both(char_u *line,
/* Simplest case: Anchored match need be tried only once. */
if (prog->reganch) {
- int c;
-
- if (has_mbyte)
- c = (*mb_ptr2char)(regline + col);
- else
- c = regline[col];
+ int c = utf_ptr2char(regline + col);
if (prog->regstart == NUL
|| prog->regstart == c
|| (rex.reg_ic
- && (((enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
+ && (utf_fold(prog->regstart) == utf_fold(c)
|| (c < 255 && prog->regstart < 255
&& mb_tolower(prog->regstart) == mb_tolower(c))))) {
retval = regtry(prog, col);
@@ -3858,12 +3826,10 @@ regmatch (
} else if (rex.reg_line_lbr && WITH_NL(op) && *reginput == '\n') {
ADVANCE_REGINPUT();
} else {
- if (WITH_NL(op))
+ if (WITH_NL(op)) {
op -= ADD_NL;
- if (has_mbyte)
- c = (*mb_ptr2char)(reginput);
- else
- c = *reginput;
+ }
+ c = utf_ptr2char(reginput);
switch (op) {
case BOL:
if (reginput != regline)
@@ -5473,8 +5439,8 @@ do_class:
}
} else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
scan++;
- } else if (has_mbyte && (len = (*mb_ptr2len)(scan)) > 1) {
- if ((cstrchr(opnd, (*mb_ptr2char)(scan)) == NULL) == testval) {
+ } else if ((len = utfc_ptr2len(scan)) > 1) {
+ if ((cstrchr(opnd, utf_ptr2char(scan)) == NULL) == testval) {
break;
}
scan += len;
@@ -6782,18 +6748,18 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
}
c = *src++;
}
- } else if (has_mbyte)
- c = mb_ptr2char(src - 1);
-
- /* Write to buffer, if copy is set. */
- if (func_one != (fptr_T)NULL)
- /* Turbo C complains without the typecast */
+ } else {
+ c = utf_ptr2char(src - 1);
+ }
+ // Write to buffer, if copy is set.
+ if (func_one != NULL) {
func_one = (fptr_T)(func_one(&cc, c));
- else if (func_all != (fptr_T)NULL)
- /* Turbo C complains without the typecast */
+ } else if (func_all != NULL) {
func_all = (fptr_T)(func_all(&cc, c));
- else /* just copy */
+ } else {
+ // just copy
cc = c;
+ }
if (has_mbyte) {
int totlen = mb_ptr2len(src - 1);
@@ -6878,10 +6844,7 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
}
dst += 2;
} else {
- if (has_mbyte)
- c = mb_ptr2char(s);
- else
- c = *s;
+ c = utf_ptr2char(s);
if (func_one != (fptr_T)NULL)
/* Turbo C complains without the typecast */
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 2eb0ca9313..deef3042d2 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -5030,16 +5030,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
* Run for each character.
*/
for (;; ) {
- int curc;
- int clen;
-
- if (has_mbyte) {
- curc = (*mb_ptr2char)(reginput);
- clen = (*mb_ptr2len)(reginput);
- } else {
- curc = *reginput;
- clen = 1;
- }
+ int curc = utf_ptr2char(reginput);
+ int clen = utfc_ptr2len(reginput);
if (curc == NUL) {
clen = 0;
go_to_nextline = false;
@@ -5501,7 +5493,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// We don't care about the order of composing characters.
// Get them into cchars[] first.
while (len < clen) {
- mc = mb_ptr2char(reginput + len);
+ mc = utf_ptr2char(reginput + len);
cchars[ccount++] = mc;
len += mb_char2len(mc);
if (ccount == MAX_MCO)
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 9f0d8a5080..f7fdc6060d 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -783,16 +783,18 @@ static void win_update(win_T *wp)
}
}
- (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, TRUE, NULL);
- if (mod_top > lnumt)
+ (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, true, NULL);
+ if (mod_top > lnumt) {
mod_top = lnumt;
+ }
- /* Now do the same for the bottom line (one above mod_bot). */
- --mod_bot;
- (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, TRUE, NULL);
- ++mod_bot;
- if (mod_bot < lnumb)
+ // Now do the same for the bottom line (one above mod_bot).
+ mod_bot--;
+ (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, true, NULL);
+ mod_bot++;
+ if (mod_bot < lnumb) {
mod_bot = lnumb;
+ }
}
/* When a change starts above w_topline and the end is below
@@ -833,12 +835,13 @@ static void win_update(win_T *wp)
type = VALID;
}
- /* Trick: we want to avoid clearing the screen twice. screenclear() will
- * set "screen_cleared" to TRUE. The special value MAYBE (which is still
- * non-zero and thus not FALSE) will indicate that screenclear() was not
- * called. */
- if (screen_cleared)
- screen_cleared = MAYBE;
+ // Trick: we want to avoid clearing the screen twice. screenclear() will
+ // set "screen_cleared" to kTrue. The special value kNone (which is still
+ // non-zero and thus not kFalse) will indicate that screenclear() was not
+ // called.
+ if (screen_cleared) {
+ screen_cleared = kNone;
+ }
/*
* If there are no changes on the screen that require a complete redraw,
@@ -875,7 +878,7 @@ static void win_update(win_T *wp)
++j;
if (j >= wp->w_height - 2)
break;
- (void)hasFoldingWin(wp, ln, NULL, &ln, TRUE, NULL);
+ (void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL);
}
} else
j = wp->w_lines[0].wl_lnum - wp->w_topline;
@@ -987,7 +990,7 @@ static void win_update(win_T *wp)
* when it won't get updated below. */
if (wp->w_p_diff && bot_start > 0)
wp->w_lines[0].wl_size =
- plines_win_nofill(wp, wp->w_topline, TRUE)
+ plines_win_nofill(wp, wp->w_topline, true)
+ wp->w_topfill;
}
}
@@ -999,14 +1002,16 @@ static void win_update(win_T *wp)
if (mid_start == 0) {
mid_end = wp->w_height;
if (ONE_WINDOW) {
- /* Clear the screen when it was not done by win_del_lines() or
- * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
- * then. */
- if (screen_cleared != TRUE)
+ // Clear the screen when it was not done by win_del_lines() or
+ // win_ins_lines() above, "screen_cleared" is kFalse or kNone
+ // then.
+ if (screen_cleared != kTrue) {
screenclear();
- /* The screen was cleared, redraw the tab pages line. */
- if (redraw_tabline)
+ }
+ // The screen was cleared, redraw the tab pages line.
+ if (redraw_tabline) {
draw_tabline();
+ }
}
}
@@ -1014,8 +1019,9 @@ static void win_update(win_T *wp)
* cleared (only happens for the first window) or when screenclear()
* was called directly above, "must_redraw" will have been set to
* NOT_VALID, need to reset it here to avoid redrawing twice. */
- if (screen_cleared == TRUE)
+ if (screen_cleared == kTrue) {
must_redraw = 0;
+ }
} else {
/* Not VALID or INVERTED: redraw all lines. */
mid_start = 0;
@@ -1303,15 +1309,15 @@ static void win_update(win_T *wp)
/* Able to count old number of rows: Count new window
* rows, and may insert/delete lines */
j = idx;
- for (l = lnum; l < mod_bot; ++l) {
- if (hasFoldingWin(wp, l, NULL, &l, TRUE, NULL))
- ++new_rows;
- else if (l == wp->w_topline)
- new_rows += plines_win_nofill(wp, l, TRUE)
- + wp->w_topfill;
- else
- new_rows += plines_win(wp, l, TRUE);
- ++j;
+ for (l = lnum; l < mod_bot; l++) {
+ if (hasFoldingWin(wp, l, NULL, &l, true, NULL)) {
+ new_rows++;
+ } else if (l == wp->w_topline) {
+ new_rows += plines_win_nofill(wp, l, true) + wp->w_topfill;
+ } else {
+ new_rows += plines_win(wp, l, true);
+ }
+ j++;
if (new_rows > wp->w_height - row - 2) {
/* it's getting too much, must redraw the rest */
new_rows = 9999;
@@ -1441,12 +1447,13 @@ static void win_update(win_T *wp)
}
wp->w_lines[idx].wl_lnum = lnum;
- wp->w_lines[idx].wl_valid = TRUE;
- if (row > wp->w_height) { /* past end of screen */
- /* we may need the size of that too long line later on */
- if (dollar_vcol == -1)
- wp->w_lines[idx].wl_size = plines_win(wp, lnum, TRUE);
- ++idx;
+ wp->w_lines[idx].wl_valid = true;
+ if (row > wp->w_height) { // past end of screen
+ // we may need the size of that too long line later on
+ if (dollar_vcol == -1) {
+ wp->w_lines[idx].wl_size = plines_win(wp, lnum, true);
+ }
+ idx++;
break;
}
if (dollar_vcol == -1)
@@ -2190,7 +2197,7 @@ win_line (
match_T *shl; // points to search_hl or a match
int shl_flag; // flag to indicate whether search_hl
// has been processed or not
- int prevcol_hl_flag; // flag to indicate whether prevcol
+ bool prevcol_hl_flag; // flag to indicate whether prevcol
// equals startcol of search_hl or one
// of the matches
int prev_c = 0; // previous Arabic character
@@ -3019,6 +3026,12 @@ win_line (
if (shl != &search_hl && cur != NULL)
cur = cur->next;
}
+ // Only highlight one character after the last column.
+ if (*ptr == NUL
+ && (did_line_attr >= 1
+ || (wp->w_p_list && lcs_eol_one == -1))) {
+ search_attr = 0;
+ }
}
if (diff_hlf != (hlf_T)0) {
@@ -3294,8 +3307,7 @@ win_line (
did_emsg = FALSE;
syntax_attr = get_syntax_attr((colnr_T)v - 1,
- has_spell ? &can_spell :
- NULL, FALSE);
+ has_spell ? &can_spell : NULL, false);
if (did_emsg) {
wp->w_s->b_syn_error = TRUE;
@@ -3668,7 +3680,9 @@ win_line (
// don't do search HL for the rest of the line
if ((line_attr_lowprio || line_attr)
- && char_attr == search_attr && col > 0) {
+ && char_attr == search_attr
+ && (did_line_attr > 1
+ || (wp->w_p_list && lcs_eol > 0))) {
char_attr = line_attr;
}
if (diff_hlf == HLF_TXD) {
@@ -3827,9 +3841,12 @@ win_line (
|| lnum == VIsual.lnum
|| lnum == curwin->w_cursor.lnum)
&& c == NUL)
- /* highlight 'hlsearch' match at end of line */
- || (prevcol_hl_flag == TRUE && did_line_attr <= 1)
- )) {
+ // highlight 'hlsearch' match at end of line
+ || (prevcol_hl_flag
+ && !(wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && !(wp == curwin && VIsual_active))
+ && diff_hlf == (hlf_T)0
+ && did_line_attr <= 1))) {
int n = 0;
if (wp->w_p_rl) {
@@ -5521,10 +5538,12 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
&& re_multiline(shl->rm.regprog)) {
if (shl->first_lnum == 0) {
for (shl->first_lnum = lnum;
- shl->first_lnum > wp->w_topline; --shl->first_lnum)
- if (hasFoldingWin(wp, shl->first_lnum - 1,
- NULL, NULL, TRUE, NULL))
+ shl->first_lnum > wp->w_topline;
+ shl->first_lnum--) {
+ if (hasFoldingWin(wp, shl->first_lnum - 1, NULL, NULL, true, NULL)) {
break;
+ }
+ }
}
if (cur != NULL) {
cur->pos.cur = 0;
@@ -5797,7 +5816,8 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
// TODO(bfredl): The relevant caller should do this
if (row == Rows - 1) { // overwritten the command line
redraw_cmdline = true;
- if (c1 == ' ' && c2 == ' ') {
+ if (start_col == 0 && end_col == Columns
+ && c1 == ' ' && c2 == ' ' && attr == 0) {
clear_cmdline = false; // command line has been cleared
}
if (start_col == 0) {
@@ -6068,7 +6088,7 @@ static void screenclear2(void)
ui_call_grid_clear(1); // clear the display
clear_cmdline = false;
mode_displayed = false;
- screen_cleared = true; // can use contents of ScreenLines now
+ screen_cleared = kTrue; // can use contents of ScreenLines now
win_rest_invalid(firstwin);
redraw_cmdline = TRUE;
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 578d1fd35a..95929f0eb4 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1120,8 +1120,8 @@ int do_search(
msgbuf = xmalloc(STRLEN(p) + 40);
{
msgbuf[0] = dirc;
- if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) {
- /* Use a space to draw the composing char on. */
+ if (utf_iscomposing(utf_ptr2char(p))) {
+ // Use a space to draw the composing char on.
msgbuf[1] = ' ';
STRCPY(msgbuf + 2, p);
} else
@@ -1549,37 +1549,31 @@ static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
{
- static pos_T pos; /* current search position */
- int findc = 0; /* matching brace */
- int c;
- int count = 0; /* cumulative number of braces */
- int backwards = false; /* init for gcc */
- int raw_string = false; /* search for raw string */
- int inquote = false; /* true when inside quotes */
- char_u *linep; /* pointer to current line */
+ static pos_T pos; // current search position
+ int findc = 0; // matching brace
+ int count = 0; // cumulative number of braces
+ int backwards = false; // init for gcc
+ bool raw_string = false; // search for raw string
+ bool inquote = false; // true when inside quotes
char_u *ptr;
- int do_quotes; /* check for quotes in current line */
- int at_start; /* do_quotes value at start position */
- int hash_dir = 0; /* Direction searched for # things */
- int comment_dir = 0; /* Direction searched for comments */
- pos_T match_pos; /* Where last slash-star was found */
- int start_in_quotes; /* start position is in quotes */
- int traveled = 0; /* how far we've searched so far */
- int ignore_cend = FALSE; /* ignore comment end */
- int cpo_match; /* vi compatible matching */
- int cpo_bsl; /* don't recognize backslashes */
- int match_escaped = 0; /* search for escaped match */
- int dir; /* Direction to search */
- int comment_col = MAXCOL; /* start of / / comment */
- int lispcomm = FALSE; /* inside of Lisp-style comment */
- int lisp = curbuf->b_p_lisp; /* engage Lisp-specific hacks ;) */
+ int hash_dir = 0; // Direction searched for # things
+ int comment_dir = 0; // Direction searched for comments
+ int traveled = 0; // how far we've searched so far
+ bool ignore_cend = false; // ignore comment end
+ int match_escaped = 0; // search for escaped match
+ int dir; // Direction to search
+ int comment_col = MAXCOL; // start of / / comment
+ bool lispcomm = false; // inside of Lisp-style comment
+ bool lisp = curbuf->b_p_lisp; // engage Lisp-specific hacks ;)
pos = curwin->w_cursor;
pos.coladd = 0;
- linep = ml_get(pos.lnum);
+ char_u *linep = ml_get(pos.lnum); // pointer to current line
- cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
- cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
+ // vi compatible matching
+ bool cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
+ // don't recognize backslashes
+ bool cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
/* Direction to search when initc is '/', '*' or '#' */
if (flags & FM_BACKWARD)
@@ -1748,13 +1742,16 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
- /* This is just guessing: when 'rightleft' is set, search for a matching
- * paren/brace in the other direction. */
- if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
+ // This is just guessing: when 'rightleft' is set, search for a matching
+ // paren/brace in the other direction.
+ if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) {
backwards = !backwards;
+ }
- do_quotes = -1;
- start_in_quotes = MAYBE;
+ int do_quotes = -1; // check for quotes in current line
+ int at_start; // do_quotes value at start position
+ TriState start_in_quotes = kNone; // start position is in quotes
+ pos_T match_pos; // Where last slash-star was found
clearpos(&match_pos);
/* backward search: Check if this line contains a single-line comment */
@@ -1762,8 +1759,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|| lisp
)
comment_col = check_linecomment(linep);
- if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col)
- lispcomm = TRUE; /* find match inside this comment */
+ if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) {
+ lispcomm = true; // find match inside this comment
+ }
while (!got_int) {
/*
* Go to the next position, forward or backward. We could use
@@ -1925,26 +1923,29 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* one for a '\' at the end.
*/
if (!do_quotes) {
- inquote = FALSE;
+ inquote = false;
if (ptr[-1] == '\\') {
do_quotes = 1;
- if (start_in_quotes == MAYBE) {
- /* Do we need to use at_start here? */
- inquote = TRUE;
- start_in_quotes = TRUE;
- } else if (backwards)
- inquote = TRUE;
+ if (start_in_quotes == kNone) {
+ // Do we need to use at_start here?
+ inquote = true;
+ start_in_quotes = kTrue;
+ } else if (backwards) {
+ inquote = true;
+ }
}
if (pos.lnum > 1) {
ptr = ml_get(pos.lnum - 1);
if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\') {
do_quotes = 1;
- if (start_in_quotes == MAYBE) {
+ if (start_in_quotes == kNone) {
inquote = at_start;
- if (inquote)
- start_in_quotes = TRUE;
- } else if (!backwards)
- inquote = TRUE;
+ if (inquote) {
+ start_in_quotes = kTrue;
+ }
+ } else if (!backwards) {
+ inquote = true;
+ }
}
/* ml_get() only keeps one line, need to get linep again */
@@ -1952,8 +1953,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
}
- if (start_in_quotes == MAYBE)
- start_in_quotes = FALSE;
+ if (start_in_quotes == kNone) {
+ start_in_quotes = kFalse;
+ }
/*
* If 'smartmatch' is set:
@@ -1966,13 +1968,13 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* inquote if the number of quotes in a line is even, unless this
* line or the previous one ends in a '\'. Complicated, isn't it?
*/
- c = PTR2CHAR(linep + pos.col);
+ const int c = PTR2CHAR(linep + pos.col);
switch (c) {
case NUL:
/* at end of line without trailing backslash, reset inquote */
if (pos.col == 0 || linep[pos.col - 1] != '\\') {
- inquote = FALSE;
- start_in_quotes = FALSE;
+ inquote = false;
+ start_in_quotes = kFalse;
}
break;
@@ -1987,7 +1989,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
if ((((int)pos.col - 1 - col) & 1) == 0) {
inquote = !inquote;
- start_in_quotes = FALSE;
+ start_in_quotes = kFalse;
}
}
break;
@@ -2039,7 +2041,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
/* Check for match outside of quotes, and inside of
* quotes when the start is also inside of quotes. */
- if ((!inquote || start_in_quotes == TRUE)
+ if ((!inquote || start_in_quotes == kTrue)
&& (c == initc || c == findc)) {
int col, bslcnt = 0;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index cb03257878..1cb679245b 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1956,7 +1956,7 @@ static int count_syllables(slang_T *slang, char_u *word)
skip = false;
} else {
// No recognized syllable item, at least a syllable char then?
- c = mb_ptr2char(p);
+ c = utf_ptr2char(p);
len = (*mb_ptr2len)(p);
if (vim_strchr(slang->sl_syllable, c) == NULL)
skip = false; // No, search for next syllable
@@ -2271,7 +2271,7 @@ static void use_midword(slang_T *lp, win_T *wp)
int c, l, n;
char_u *bp;
- c = mb_ptr2char(p);
+ c = utf_ptr2char(p);
l = (*mb_ptr2len)(p);
if (c < 256 && l <= 2)
wp->w_s->b_spell_ismw[c] = true;
@@ -2597,16 +2597,18 @@ static bool spell_iswordp(char_u *p, win_T *wp)
if (wp->w_s->b_spell_ismw[*p])
s = p + 1; // skip a mid-word character
} else {
- c = mb_ptr2char(p);
+ c = utf_ptr2char(p);
if (c < 256 ? wp->w_s->b_spell_ismw[c]
: (wp->w_s->b_spell_ismw_mb != NULL
- && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL))
+ && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL)) {
s = p + l;
+ }
}
- c = mb_ptr2char(s);
- if (c > 255)
+ c = utf_ptr2char(s);
+ if (c > 255) {
return spell_mb_isword_class(mb_get_class(s), wp);
+ }
return spelltab.st_isw[c];
}
@@ -2617,16 +2619,11 @@ static bool spell_iswordp(char_u *p, win_T *wp)
// Unlike spell_iswordp() this doesn't check for "midword" characters.
bool spell_iswordp_nmw(const char_u *p, win_T *wp)
{
- int c;
-
- if (has_mbyte) {
- c = mb_ptr2char(p);
- if (c > 255) {
- return spell_mb_isword_class(mb_get_class(p), wp);
- }
- return spelltab.st_isw[c];
+ int c = utf_ptr2char(p);
+ if (c > 255) {
+ return spell_mb_isword_class(mb_get_class(p), wp);
}
- return spelltab.st_isw[*p];
+ return spelltab.st_isw[c];
}
// Returns true if word class indicates a word character.
@@ -2944,7 +2941,7 @@ void spell_suggest(int count)
memmove(p, line, c);
STRCPY(p + c, stp->st_word);
STRCAT(p, sug.su_badptr + stp->st_orglen);
- ml_replace(curwin->w_cursor.lnum, p, FALSE);
+ ml_replace(curwin->w_cursor.lnum, p, false);
curwin->w_cursor.col = c;
// For redo we use a change-word command.
@@ -3062,7 +3059,7 @@ void ex_spellrepall(exarg_T *eap)
memmove(p, line, curwin->w_cursor.col);
STRCPY(p + curwin->w_cursor.col, repl_to);
STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from));
- ml_replace(curwin->w_cursor.lnum, p, FALSE);
+ ml_replace(curwin->w_cursor.lnum, p, false);
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
if (curwin->w_cursor.lnum != prev_lnum) {
@@ -4300,14 +4297,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
&& utf_iscomposing(utf_ptr2char(fword
+ sp->ts_fcharstart))) {
sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP;
- } else if (!soundfold
- && slang->sl_has_map
- && similar_chars(slang,
- mb_ptr2char(tword
- + sp->ts_twordlen
- - sp->ts_tcharlen),
- mb_ptr2char(fword
- + sp->ts_fcharstart))) {
+ } else if (
+ !soundfold
+ && slang->sl_has_map
+ && similar_chars(
+ slang,
+ utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
+ utf_ptr2char(fword + sp->ts_fcharstart))) {
// For a similar character adjust score from
// SCORE_SUBST to SCORE_SIMILAR.
sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
@@ -4315,8 +4311,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
} else if (sp->ts_isdiff == DIFF_INSERT
&& sp->ts_twordlen > sp->ts_tcharlen) {
p = tword + sp->ts_twordlen - sp->ts_tcharlen;
- c = mb_ptr2char(p);
- if (enc_utf8 && utf_iscomposing(c)) {
+ c = utf_ptr2char(p);
+ if (utf_iscomposing(c)) {
// Inserting a composing char doesn't
// count that much.
sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
@@ -4327,7 +4323,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// tree (might seem illogical but does
// give better scores).
MB_PTR_BACK(tword, p);
- if (c == mb_ptr2char(p)) {
+ if (c == utf_ptr2char(p)) {
sp->ts_score -= SCORE_INS - SCORE_INSDUP;
}
}
@@ -4388,19 +4384,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// score if the same character is following "nn" -> "n". It's
// a bit illogical for soundfold tree but it does give better
// results.
- if (has_mbyte) {
- c = mb_ptr2char(fword + sp->ts_fidx);
- stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
- if (enc_utf8 && utf_iscomposing(c)) {
- stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
- } else if (c == mb_ptr2char(fword + stack[depth].ts_fidx)) {
- stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
- }
- } else {
- ++stack[depth].ts_fidx;
- if (fword[sp->ts_fidx] == fword[sp->ts_fidx + 1])
- stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
+ c = utf_ptr2char(fword + sp->ts_fidx);
+ stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
+ if (utf_iscomposing(c)) {
+ stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
+ } else if (c == utf_ptr2char(fword + stack[depth].ts_fidx)) {
+ stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
}
+
break;
}
// FALLTHROUGH
@@ -4515,22 +4506,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
break;
}
- if (has_mbyte) {
- n = MB_CPTR2LEN(p);
- c = mb_ptr2char(p);
- if (p[n] == NUL)
- c2 = NUL;
- else if (!soundfold && !spell_iswordp(p + n, curwin))
- c2 = c; // don't swap non-word char
- else
- c2 = mb_ptr2char(p + n);
+ n = MB_CPTR2LEN(p);
+ c = utf_ptr2char(p);
+ if (p[n] == NUL) {
+ c2 = NUL;
+ } else if (!soundfold && !spell_iswordp(p + n, curwin)) {
+ c2 = c; // don't swap non-word char
} else {
- if (p[1] == NUL)
- c2 = NUL;
- else if (!soundfold && !spell_iswordp(p + 1, curwin))
- c2 = c; // don't swap non-word char
- else
- c2 = p[1];
+ c2 = utf_ptr2char(p + n);
}
// When the second character is NUL we can't swap.
@@ -4550,9 +4533,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (c2 != NUL && TRY_DEEPER(su, stack, depth, SCORE_SWAP)) {
go_deeper(stack, depth, SCORE_SWAP);
#ifdef DEBUG_TRIEWALK
- sprintf(changename[depth], "%.*s-%s: swap %c and %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- c, c2);
+ snprintf(changename[depth], sizeof(changename[0]),
+ "%.*s-%s: swap %c and %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c, c2);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP;
@@ -4576,38 +4560,25 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNSWAP:
// Undo the STATE_SWAP swap: "21" -> "12".
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_PTR2LEN(p);
- c = mb_ptr2char(p + n);
- memmove(p + MB_PTR2LEN(p + n), p, n);
- mb_char2bytes(c, p);
- } else {
- c = *p;
- *p = p[1];
- p[1] = c;
- }
+ n = MB_PTR2LEN(p);
+ c = utf_ptr2char(p + n);
+ memmove(p + MB_PTR2LEN(p + n), p, n);
+ mb_char2bytes(c, p);
+
// FALLTHROUGH
case STATE_SWAP3:
// Swap two bytes, skipping one: "123" -> "321". We change
// "fword" here, it's changed back afterwards at STATE_UNSWAP3.
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_CPTR2LEN(p);
- c = mb_ptr2char(p);
- fl = MB_CPTR2LEN(p + n);
- c2 = mb_ptr2char(p + n);
- if (!soundfold && !spell_iswordp(p + n + fl, curwin))
- c3 = c; // don't swap non-word char
- else
- c3 = mb_ptr2char(p + n + fl);
+ n = MB_CPTR2LEN(p);
+ c = utf_ptr2char(p);
+ fl = MB_CPTR2LEN(p + n);
+ c2 = utf_ptr2char(p + n);
+ if (!soundfold && !spell_iswordp(p + n + fl, curwin)) {
+ c3 = c; // don't swap non-word char
} else {
- c = *p;
- c2 = p[1];
- if (!soundfold && !spell_iswordp(p + 2, curwin))
- c3 = c; // don't swap non-word char
- else
- c3 = p[2];
+ c3 = utf_ptr2char(p + n + fl);
}
// When characters are identical: "121" then SWAP3 result is
@@ -4651,22 +4622,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNSWAP3:
// Undo STATE_SWAP3: "321" -> "123"
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_PTR2LEN(p);
- c2 = mb_ptr2char(p + n);
- fl = MB_PTR2LEN(p + n);
- c = mb_ptr2char(p + n + fl);
- tl = MB_PTR2LEN(p + n + fl);
- memmove(p + fl + tl, p, n);
- mb_char2bytes(c, p);
- mb_char2bytes(c2, p + tl);
- p = p + tl;
- } else {
- c = *p;
- *p = p[2];
- p[2] = c;
- ++p;
- }
+ n = MB_PTR2LEN(p);
+ c2 = utf_ptr2char(p + n);
+ fl = MB_PTR2LEN(p + n);
+ c = utf_ptr2char(p + n + fl);
+ tl = MB_PTR2LEN(p + n + fl);
+ memmove(p + fl + tl, p, n);
+ mb_char2bytes(c, p);
+ mb_char2bytes(c2, p + tl);
+ p = p + tl;
if (!soundfold && !spell_iswordp(p, curwin)) {
// Middle char is not a word char, skip the rotate. First and
@@ -4690,21 +4654,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp->ts_state = STATE_UNROT3L;
++depth;
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_CPTR2LEN(p);
- c = mb_ptr2char(p);
- fl = MB_CPTR2LEN(p + n);
- fl += MB_CPTR2LEN(p + n + fl);
- memmove(p, p + n, fl);
- mb_char2bytes(c, p + fl);
- stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
- } else {
- c = *p;
- *p = p[1];
- p[1] = p[2];
- p[2] = c;
- stack[depth].ts_fidxtry = sp->ts_fidx + 3;
- }
+ n = MB_CPTR2LEN(p);
+ c = utf_ptr2char(p);
+ fl = MB_CPTR2LEN(p + n);
+ fl += MB_CPTR2LEN(p + n + fl);
+ memmove(p, p + n, fl);
+ utf_char2bytes(c, p + fl);
+ stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
} else {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI;
@@ -4714,19 +4670,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNROT3L:
// Undo ROT3L: "231" -> "123"
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_PTR2LEN(p);
- n += MB_PTR2LEN(p + n);
- c = mb_ptr2char(p + n);
- tl = MB_PTR2LEN(p + n);
- memmove(p + tl, p, n);
- mb_char2bytes(c, p);
- } else {
- c = p[2];
- p[2] = p[1];
- p[1] = *p;
- *p = c;
- }
+ n = MB_PTR2LEN(p);
+ n += MB_PTR2LEN(p + n);
+ c = utf_ptr2char(p + n);
+ tl = MB_PTR2LEN(p + n);
+ memmove(p + tl, p, n);
+ mb_char2bytes(c, p);
// Rotate three bytes right: "123" -> "312". We change "fword"
// here, it's changed back afterwards at STATE_UNROT3R.
@@ -4742,21 +4691,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp->ts_state = STATE_UNROT3R;
++depth;
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_CPTR2LEN(p);
- n += MB_CPTR2LEN(p + n);
- c = mb_ptr2char(p + n);
- tl = MB_CPTR2LEN(p + n);
- memmove(p + tl, p, n);
- mb_char2bytes(c, p);
- stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
- } else {
- c = p[2];
- p[2] = p[1];
- p[1] = *p;
- *p = c;
- stack[depth].ts_fidxtry = sp->ts_fidx + 3;
- }
+ n = MB_CPTR2LEN(p);
+ n += MB_CPTR2LEN(p + n);
+ c = utf_ptr2char(p + n);
+ tl = MB_CPTR2LEN(p + n);
+ memmove(p + tl, p, n);
+ mb_char2bytes(c, p);
+ stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
} else {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI;
@@ -4766,19 +4707,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNROT3R:
// Undo ROT3R: "312" -> "123"
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- c = mb_ptr2char(p);
- tl = MB_PTR2LEN(p);
- n = MB_PTR2LEN(p + tl);
- n += MB_PTR2LEN(p + tl + n);
- memmove(p, p + tl, n);
- mb_char2bytes(c, p + n);
- } else {
- c = *p;
- *p = p[1];
- p[1] = p[2];
- p[2] = c;
- }
+ c = utf_ptr2char(p);
+ tl = MB_PTR2LEN(p);
+ n = MB_PTR2LEN(p + tl);
+ n += MB_PTR2LEN(p + tl + n);
+ memmove(p, p + tl, n);
+ mb_char2bytes(c, p + n);
+
// FALLTHROUGH
case STATE_REP_INI:
@@ -5604,25 +5539,29 @@ static bool similar_chars(slang_T *slang, int c1, int c2)
if (c1 >= 256) {
buf[mb_char2bytes(c1, buf)] = 0;
hi = hash_find(&slang->sl_map_hash, buf);
- if (HASHITEM_EMPTY(hi))
+ if (HASHITEM_EMPTY(hi)) {
m1 = 0;
- else
- m1 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
- } else
+ } else {
+ m1 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+ }
+ } else {
m1 = slang->sl_map_array[c1];
- if (m1 == 0)
+ }
+ if (m1 == 0) {
return false;
-
+ }
if (c2 >= 256) {
buf[mb_char2bytes(c2, buf)] = 0;
hi = hash_find(&slang->sl_map_hash, buf);
- if (HASHITEM_EMPTY(hi))
+ if (HASHITEM_EMPTY(hi)) {
m2 = 0;
- else
- m2 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
- } else
+ } else {
+ m2 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+ }
+ } else {
m2 = slang->sl_map_array[c2];
+ }
return m1 == m2;
}
@@ -5659,11 +5598,9 @@ add_suggestion (
break;
MB_PTR_BACK(goodword, pgood);
MB_PTR_BACK(su->su_badptr, pbad);
- if (has_mbyte) {
- if (mb_ptr2char(pgood) != mb_ptr2char(pbad))
- break;
- } else if (*pgood != *pbad)
+ if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) {
break;
+ }
}
if (badlen == 0 && goodlen == 0)
@@ -7608,5 +7545,3 @@ int expand_spelling(linenr_T lnum, char_u *pat, char_u ***matchp)
*matchp = ga.ga_data;
return ga.ga_len;
}
-
-
diff --git a/src/nvim/state.c b/src/nvim/state.c
index a4b394c9e4..5921bd45bf 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -73,13 +73,13 @@ getkey:
}
}
-/// Return TRUE if in the current mode we need to use virtual.
-int virtual_active(void)
+/// Return true if in the current mode we need to use virtual.
+bool virtual_active(void)
{
// While an operator is being executed we return "virtual_op", because
// VIsual_active has already been reset, thus we can't check for "block"
// being used.
- if (virtual_op != MAYBE) {
+ if (virtual_op != kNone) {
return virtual_op;
}
return ve_flags == VE_ALL
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index ff47e443f9..d7c23742ba 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -53,7 +53,7 @@ static bool did_syntax_onoff = false;
struct hl_group {
char_u *sg_name; ///< highlight group name
char_u *sg_name_u; ///< uppercase of sg_name
- int sg_cleared; ///< "hi clear" was used
+ bool sg_cleared; ///< "hi clear" was used
int sg_attr; ///< Screen attr @see ATTR_ENTRY
int sg_link; ///< link to this highlight group ID
int sg_set; ///< combination of flags in \ref SG_SET
@@ -62,7 +62,7 @@ struct hl_group {
int sg_cterm; ///< "cterm=" highlighting attr
int sg_cterm_fg; ///< terminal fg color number + 1
int sg_cterm_bg; ///< terminal bg color number + 1
- int sg_cterm_bold; ///< bold attr was set for light color
+ bool sg_cterm_bold; ///< bold attr was set for light color
// for RGB UIs
int sg_gui; ///< "gui=" highlighting attributes
///< (combination of \ref HlAttrFlags)
@@ -115,42 +115,42 @@ static int hl_attr_table[] =
{HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE,
HL_INVERSE, 0};
-/*
- * The patterns that are being searched for are stored in a syn_pattern.
- * A match item consists of one pattern.
- * A start/end item consists of n start patterns and m end patterns.
- * A start/skip/end item consists of n start patterns, one skip pattern and m
- * end patterns.
- * For the latter two, the patterns are always consecutive: start-skip-end.
- *
- * A character offset can be given for the matched text (_m_start and _m_end)
- * and for the actually highlighted text (_h_start and _h_end).
- */
+// The patterns that are being searched for are stored in a syn_pattern.
+// A match item consists of one pattern.
+// A start/end item consists of n start patterns and m end patterns.
+// A start/skip/end item consists of n start patterns, one skip pattern and m
+// end patterns.
+// For the latter two, the patterns are always consecutive: start-skip-end.
+//
+// A character offset can be given for the matched text (_m_start and _m_end)
+// and for the actually highlighted text (_h_start and _h_end).
+//
+// Note that ordering of members is optimized to reduce padding.
typedef struct syn_pattern {
- char sp_type; /* see SPTYPE_ defines below */
- char sp_syncing; /* this item used for syncing */
- int sp_flags; /* see HL_ defines below */
- int sp_cchar; /* conceal substitute character */
- struct sp_syn sp_syn; /* struct passed to in_id_list() */
- short sp_syn_match_id; /* highlight group ID of pattern */
- char_u *sp_pattern; /* regexp to match, pattern */
- regprog_T *sp_prog; /* regexp to match, program */
+ char sp_type; // see SPTYPE_ defines below
+ bool sp_syncing; // this item used for syncing
+ int16_t sp_syn_match_id; // highlight group ID of pattern
+ int16_t sp_off_flags; // see below
+ int sp_offsets[SPO_COUNT]; // offsets
+ int sp_flags; // see HL_ defines below
+ int sp_cchar; // conceal substitute character
+ int sp_ic; // ignore-case flag for sp_prog
+ int sp_sync_idx; // sync item index (syncing only)
+ int sp_line_id; // ID of last line where tried
+ int sp_startcol; // next match in sp_line_id line
+ int16_t *sp_cont_list; // cont. group IDs, if non-zero
+ int16_t *sp_next_list; // next group IDs, if non-zero
+ struct sp_syn sp_syn; // struct passed to in_id_list()
+ char_u *sp_pattern; // regexp to match, pattern
+ regprog_T *sp_prog; // regexp to match, program
syn_time_T sp_time;
- int sp_ic; /* ignore-case flag for sp_prog */
- short sp_off_flags; /* see below */
- int sp_offsets[SPO_COUNT]; /* offsets */
- short *sp_cont_list; /* cont. group IDs, if non-zero */
- short *sp_next_list; /* next group IDs, if non-zero */
- int sp_sync_idx; /* sync item index (syncing only) */
- int sp_line_id; /* ID of last line where tried */
- int sp_startcol; /* next match in sp_line_id line */
} synpat_T;
typedef struct syn_cluster_S {
- char_u *scl_name; /* syntax cluster name */
- char_u *scl_name_u; /* uppercase of scl_name */
- short *scl_list; /* IDs in this syntax cluster */
+ char_u *scl_name; // syntax cluster name
+ char_u *scl_name_u; // uppercase of scl_name
+ int16_t *scl_list; // IDs in this syntax cluster
} syn_cluster_T;
/*
@@ -159,27 +159,27 @@ typedef struct syn_cluster_S {
* (The end positions have the column number of the next char)
*/
typedef struct state_item {
- int si_idx; /* index of syntax pattern or
- KEYWORD_IDX */
- int si_id; /* highlight group ID for keywords */
- int si_trans_id; /* idem, transparency removed */
- int si_m_lnum; /* lnum of the match */
- int si_m_startcol; /* starting column of the match */
- lpos_T si_m_endpos; /* just after end posn of the match */
- lpos_T si_h_startpos; /* start position of the highlighting */
- lpos_T si_h_endpos; /* end position of the highlighting */
- lpos_T si_eoe_pos; /* end position of end pattern */
- int si_end_idx; /* group ID for end pattern or zero */
- int si_ends; /* if match ends before si_m_endpos */
- int si_attr; /* attributes in this state */
- long si_flags; /* HL_HAS_EOL flag in this state, and
- * HL_SKIP* for si_next_list */
- int si_seqnr; /* sequence number */
- int si_cchar; /* substitution character for conceal */
- short *si_cont_list; /* list of contained groups */
- short *si_next_list; /* nextgroup IDs after this item ends */
- reg_extmatch_T *si_extmatch; /* \z(...\) matches from start
- * pattern */
+ int si_idx; // index of syntax pattern or
+ // KEYWORD_IDX
+ int si_id; // highlight group ID for keywords
+ int si_trans_id; // idem, transparency removed
+ int si_m_lnum; // lnum of the match
+ int si_m_startcol; // starting column of the match
+ lpos_T si_m_endpos; // just after end posn of the match
+ lpos_T si_h_startpos; // start position of the highlighting
+ lpos_T si_h_endpos; // end position of the highlighting
+ lpos_T si_eoe_pos; // end position of end pattern
+ int si_end_idx; // group ID for end pattern or zero
+ int si_ends; // if match ends before si_m_endpos
+ int si_attr; // attributes in this state
+ long si_flags; // HL_HAS_EOL flag in this state, and
+ // HL_SKIP* for si_next_list
+ int si_seqnr; // sequence number
+ int si_cchar; // substitution character for conceal
+ int16_t *si_cont_list; // list of contained groups
+ int16_t *si_next_list; // nextgroup IDs after this item ends
+ reg_extmatch_T *si_extmatch; // \z(...\) matches from start
+ // pattern
} stateitem_T;
/*
@@ -187,14 +187,14 @@ typedef struct state_item {
* very often.
*/
typedef struct {
- int flags; /* flags for contained and transparent */
- int keyword; /* TRUE for ":syn keyword" */
- int *sync_idx; /* syntax item for "grouphere" argument, NULL
- if not allowed */
- char has_cont_list; /* TRUE if "cont_list" can be used */
- short *cont_list; /* group IDs for "contains" argument */
- short *cont_in_list; /* group IDs for "containedin" argument */
- short *next_list; /* group IDs for "nextgroup" argument */
+ int flags; // flags for contained and transparent
+ bool keyword; // true for ":syn keyword"
+ int *sync_idx; // syntax item for "grouphere" argument, NULL
+ // if not allowed
+ bool has_cont_list; // true if "cont_list" can be used
+ int16_t *cont_list; // group IDs for "contains" argument
+ int16_t *cont_in_list; // group IDs for "containedin" argument
+ int16_t *next_list; // group IDs for "nextgroup" argument
} syn_opt_arg_T;
typedef struct {
@@ -318,9 +318,10 @@ static int keepend_level = -1;
static char msg_no_items[] = N_("No Syntax items defined for this buffer");
-#define KEYWORD_IDX -1 /* value of si_idx for keywords */
-#define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all
- but contained groups */
+// value of si_idx for keywords
+#define KEYWORD_IDX -1
+// valid of si_cont_list for containing all but contained groups
+#define ID_LIST_ALL (int16_t *)-1
static int next_seqnr = 1; /* value to use for si_seqnr */
@@ -363,9 +364,9 @@ static int current_state_stored = 0; /* TRUE if stored current state
static int current_finished = 0; /* current line has been finished */
static garray_T current_state /* current stack of state_items */
= GA_EMPTY_INIT_VALUE;
-static short *current_next_list = NULL; /* when non-zero, nextgroup list */
-static int current_next_flags = 0; /* flags for current_next_list */
-static int current_line_id = 0; /* unique number for current line */
+static int16_t *current_next_list = NULL; // when non-zero, nextgroup list
+static int current_next_flags = 0; // flags for current_next_list
+static int current_line_id = 0; // unique number for current line
#define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx]
@@ -1525,32 +1526,26 @@ int syntax_check_changed(linenr_T lnum)
*/
static bool
syn_finish_line(
- bool syncing // called for syncing
+ const bool syncing // called for syncing
)
{
- stateitem_T *cur_si;
- colnr_T prev_current_col;
-
while (!current_finished) {
- (void)syn_current_attr(syncing, FALSE, NULL, FALSE);
- /*
- * When syncing, and found some item, need to check the item.
- */
+ (void)syn_current_attr(syncing, false, NULL, false);
+
+ // When syncing, and found some item, need to check the item.
if (syncing && current_state.ga_len) {
- /*
- * Check for match with sync item.
- */
- cur_si = &CUR_STATE(current_state.ga_len - 1);
+ // Check for match with sync item.
+ const stateitem_T *const cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_idx >= 0
&& (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
& (HL_SYNC_HERE|HL_SYNC_THERE))) {
return true;
}
- /* syn_current_attr() will have skipped the check for an item
- * that ends here, need to do that now. Be careful not to go
- * past the NUL. */
- prev_current_col = current_col;
+ // syn_current_attr() will have skipped the check for an item
+ // that ends here, need to do that now. Be careful not to go
+ // past the NUL.
+ const colnr_T prev_current_col = current_col;
if (syn_getcurline()[current_col] != NUL) {
current_col++;
}
@@ -1573,9 +1568,9 @@ syn_finish_line(
*/
int
get_syntax_attr(
- colnr_T col,
- bool *can_spell,
- int keep_state /* keep state of char at "col" */
+ const colnr_T col,
+ bool *const can_spell,
+ const bool keep_state // keep state of char at "col"
)
{
int attr = 0;
@@ -1609,9 +1604,9 @@ get_syntax_attr(
* Skip from the current column to "col", get the attributes for "col".
*/
while (current_col <= col) {
- attr = syn_current_attr(FALSE, TRUE, can_spell,
- current_col == col ? keep_state : FALSE);
- ++current_col;
+ attr = syn_current_attr(false, true, can_spell,
+ current_col == col ? keep_state : false);
+ current_col++;
}
return attr;
@@ -1620,42 +1615,37 @@ get_syntax_attr(
/*
* Get syntax attributes for current_lnum, current_col.
*/
-static int
-syn_current_attr(
- int syncing, // When 1: called for syncing
- int displaying, // result will be displayed
- bool *can_spell, // return: do spell checking
- int keep_state // keep syntax stack afterwards
+static int syn_current_attr(
+ const bool syncing, // When true: called for syncing
+ const bool displaying, // result will be displayed
+ bool *const can_spell, // return: do spell checking
+ const bool keep_state // keep syntax stack afterwards
)
{
- int syn_id;
- lpos_T endpos; /* was: char_u *endp; */
- lpos_T hl_startpos; /* was: int hl_startcol; */
+ lpos_T endpos; // was: char_u *endp;
+ lpos_T hl_startpos; // was: int hl_startcol;
lpos_T hl_endpos;
- lpos_T eos_pos; /* end-of-start match (start region) */
- lpos_T eoe_pos; /* end-of-end pattern */
- int end_idx; /* group ID for end pattern */
- synpat_T *spp;
+ lpos_T eos_pos; // end-of-start match (start region)
+ lpos_T eoe_pos; // end-of-end pattern
+ int end_idx; // group ID for end pattern
stateitem_T *cur_si, *sip = NULL;
int startcol;
int endcol;
long flags;
int cchar;
- short *next_list;
- int found_match; /* found usable match */
- static int try_next_column = FALSE; /* must try in next col */
- int do_keywords;
+ int16_t *next_list;
+ bool found_match; // found usable match
+ static bool try_next_column = false; // must try in next col
regmmatch_T regmatch;
lpos_T pos;
- int lc_col;
reg_extmatch_T *cur_extmatch = NULL;
char_u buf_chartab[32]; // chartab array for syn iskeyword
char_u *line; // current line. NOTE: becomes invalid after
// looking for a pattern match!
- /* variables for zero-width matches that have a "nextgroup" argument */
- int keep_next_list;
- int zero_width_next_list = FALSE;
+ // variables for zero-width matches that have a "nextgroup" argument
+ bool keep_next_list;
+ bool zero_width_next_list = false;
garray_T zero_width_next_ga;
/*
@@ -1690,13 +1680,13 @@ syn_current_attr(
*/
if (try_next_column) {
next_match_idx = -1;
- try_next_column = FALSE;
+ try_next_column = false;
}
- /* Only check for keywords when not syncing and there are some. */
- do_keywords = !syncing
- && (syn_block->b_keywtab.ht_used > 0
- || syn_block->b_keywtab_ic.ht_used > 0);
+ // Only check for keywords when not syncing and there are some.
+ const bool do_keywords = !syncing
+ && (syn_block->b_keywtab.ht_used > 0
+ || syn_block->b_keywtab_ic.ht_used > 0);
/* Init the list of zero-width matches with a nextlist. This is used to
* avoid matching the same item in the same position twice. */
@@ -1711,9 +1701,9 @@ syn_current_attr(
* column.
*/
do {
- found_match = FALSE;
- keep_next_list = FALSE;
- syn_id = 0;
+ found_match = false;
+ keep_next_list = false;
+ int syn_id = 0;
/*
* 1. Check for a current state.
@@ -1806,7 +1796,7 @@ syn_current_attr(
next_match_idx = 0; /* no match in this line yet */
next_match_col = MAXCOL;
for (int idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) {
- spp = &(SYN_ITEMS(syn_block)[idx]);
+ synpat_T *const spp = &(SYN_ITEMS(syn_block)[idx]);
if ( spp->sp_syncing == syncing
&& (displaying || !(spp->sp_flags & HL_DISPLAY))
&& (spp->sp_type == SPTYPE_MATCH
@@ -1827,13 +1817,14 @@ syn_current_attr(
continue;
spp->sp_line_id = current_line_id;
- lc_col = current_col - spp->sp_offsets[SPO_LC_OFF];
- if (lc_col < 0)
+ colnr_T lc_col = current_col - spp->sp_offsets[SPO_LC_OFF];
+ if (lc_col < 0) {
lc_col = 0;
+ }
regmatch.rmm_ic = spp->sp_ic;
regmatch.regprog = spp->sp_prog;
- int r = syn_regexec(&regmatch, current_lnum, (colnr_T)lc_col,
+ int r = syn_regexec(&regmatch, current_lnum, lc_col,
IF_SYN_TIME(&spp->sp_time));
spp->sp_prog = regmatch.regprog;
if (!r) {
@@ -1872,7 +1863,7 @@ syn_current_attr(
* column, because it may match from there.
*/
if (did_match_already(idx, &zero_width_next_ga)) {
- try_next_column = TRUE;
+ try_next_column = true;
continue;
}
@@ -1934,9 +1925,9 @@ syn_current_attr(
* If an empty string is matched, may need
* to try matching again at next column.
*/
- if (regmatch.startpos[0].col
- == regmatch.endpos[0].col)
- try_next_column = TRUE;
+ if (regmatch.startpos[0].col == regmatch.endpos[0].col) {
+ try_next_column = true;
+ }
continue;
}
}
@@ -1981,8 +1972,8 @@ syn_current_attr(
&& lspp->sp_next_list != NULL) {
current_next_list = lspp->sp_next_list;
current_next_flags = lspp->sp_flags;
- keep_next_list = TRUE;
- zero_width_next_list = TRUE;
+ keep_next_list = true;
+ zero_width_next_list = true;
/* Add the index to a list, so that we can check
* later that we don't match it again (and cause an
@@ -2025,8 +2016,9 @@ syn_current_attr(
*/
current_next_list = NULL;
next_match_idx = -1;
- if (!zero_width_next_list)
- found_match = TRUE;
+ if (!zero_width_next_list) {
+ found_match = true;
+ }
}
} while (found_match);
@@ -2931,39 +2923,35 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
* The caller must check if a keyword can start at startcol.
* Return its ID if found, 0 otherwise.
*/
-static int
-check_keyword_id(
- char_u *line,
- int startcol, /* position in line to check for keyword */
- int *endcolp, /* return: character after found keyword */
- long *flagsp, /* return: flags of matching keyword */
- short **next_listp, /* return: next_list of matching keyword */
- stateitem_T *cur_si, /* item at the top of the stack */
- int *ccharp /* conceal substitution char */
+static int check_keyword_id(
+ char_u *const line,
+ const int startcol, // position in line to check for keyword
+ int *const endcolp, // return: character after found keyword
+ long *const flagsp, // return: flags of matching keyword
+ int16_t **const next_listp, // return: next_list of matching keyword
+ stateitem_T *const cur_si, // item at the top of the stack
+ int *const ccharp // conceal substitution char
)
{
- char_u *kwp;
- int kwlen;
- char_u keyword[MAXKEYWLEN + 1]; /* assume max. keyword len is 80 */
-
- /* Find first character after the keyword. First character was already
- * checked. */
- kwp = line + startcol;
- kwlen = 0;
+ // Find first character after the keyword. First character was already
+ // checked.
+ char_u *const kwp = line + startcol;
+ int kwlen = 0;
do {
- if (has_mbyte)
+ if (has_mbyte) {
kwlen += (*mb_ptr2len)(kwp + kwlen);
- else
- ++kwlen;
+ } else {
+ kwlen++;
+ }
} while (vim_iswordp_buf(kwp + kwlen, syn_buf));
- if (kwlen > MAXKEYWLEN)
+ if (kwlen > MAXKEYWLEN) {
return 0;
+ }
- /*
- * Must make a copy of the keyword, so we can add a NUL and make it
- * lowercase.
- */
+ // Must make a copy of the keyword, so we can add a NUL and make it
+ // lowercase.
+ char_u keyword[MAXKEYWLEN + 1]; // assume max. keyword len is 80
STRLCPY(keyword, kwp, kwlen + 1);
keyentry_T *kp = NULL;
@@ -3321,12 +3309,10 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
EMSG2(_("E391: No such syntax cluster: %s"), arg);
break;
} else {
- /*
- * We can't physically delete a cluster without changing
- * the IDs of other clusters, so we do the next best thing
- * and make it empty.
- */
- short scl_id = id - SYNID_CLUSTER;
+ // We can't physically delete a cluster without changing
+ // the IDs of other clusters, so we do the next best thing
+ // and make it empty.
+ int scl_id = id - SYNID_CLUSTER;
xfree(SYN_CLSTR(curwin->w_s)[scl_id].scl_list);
SYN_CLSTR(curwin->w_s)[scl_id].scl_list = NULL;
@@ -3349,7 +3335,7 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
/*
* Clear one syntax group for the current buffer.
*/
-static void syn_clear_one(int id, int syncing)
+static void syn_clear_one(const int id, const bool syncing)
{
synpat_T *spp;
@@ -3491,8 +3477,8 @@ syn_cmd_list(
/*
* No argument: List all group IDs and all syntax clusters.
*/
- for (int id = 1; id <= highlight_ga.ga_len && !got_int; ++id) {
- syn_list_one(id, syncing, FALSE);
+ for (int id = 1; id <= highlight_ga.ga_len && !got_int; id++) {
+ syn_list_one(id, syncing, false);
}
for (int id = 0; id < curwin->w_s->b_syn_clusters.ga_len && !got_int; ++id) {
syn_list_cluster(id);
@@ -3511,10 +3497,11 @@ syn_cmd_list(
syn_list_cluster(id - SYNID_CLUSTER);
} else {
int id = syn_namen2id(arg, (int)(arg_end - arg));
- if (id == 0)
+ if (id == 0) {
EMSG2(_(e_nogroup), arg);
- else
- syn_list_one(id, syncing, TRUE);
+ } else {
+ syn_list_one(id, syncing, true);
+ }
}
arg = skipwhite(arg_end);
}
@@ -3558,14 +3545,12 @@ static int last_matchgroup;
*/
static void
syn_list_one(
- int id,
- int syncing, /* when TRUE: list syncing items */
- int link_only /* when TRUE; list link-only too */
+ const int id,
+ const bool syncing, // when true: list syncing items
+ const bool link_only // when true; list link-only too
)
{
- int attr;
- int did_header = FALSE;
- synpat_T *spp;
+ bool did_header = false;
static struct name_list namelist1[] =
{
{HL_DISPLAY, "display"},
@@ -3588,23 +3573,26 @@ syn_list_one(
{0, NULL}
};
- attr = HL_ATTR(HLF_D); // highlight like directories
+ const int attr = HL_ATTR(HLF_D); // highlight like directories
- /* list the keywords for "id" */
+ // list the keywords for "id"
if (!syncing) {
- did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, FALSE, attr);
+ did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, false, attr);
did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab_ic,
- did_header, attr);
+ did_header, attr);
}
- /* list the patterns for "id" */
- for (int idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; ++idx) {
- spp = &(SYN_ITEMS(curwin->w_s)[idx]);
- if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
+ // list the patterns for "id"
+ for (int idx = 0;
+ idx < curwin->w_s->b_syn_patterns.ga_len && !got_int;
+ idx++) {
+ const synpat_T *const spp = &(SYN_ITEMS(curwin->w_s)[idx]);
+ if (spp->sp_syn.id != id || spp->sp_syncing != syncing) {
continue;
+ }
(void)syn_list_header(did_header, 999, id);
- did_header = TRUE;
+ did_header = true;
last_matchgroup = 0;
if (spp->sp_type == SPTYPE_MATCH) {
put_pattern("match", ' ', spp, attr);
@@ -3695,15 +3683,13 @@ static void syn_list_cluster(int id)
}
}
-static void put_id_list(const char *name,
- short *list, // NOLINT(runtime/int)
- int attr)
+static void put_id_list(const char *const name,
+ const int16_t *const list,
+ const int attr)
{
- short *p;
-
msg_puts_attr(name, attr);
msg_putchar('=');
- for (p = list; *p; ++p) {
+ for (const int16_t *p = list; *p; p++) {
if (*p >= SYNID_ALLBUT && *p < SYNID_TOP) {
if (p[1]) {
msg_puts("ALLBUT");
@@ -3715,7 +3701,7 @@ static void put_id_list(const char *name,
} else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) {
msg_puts("CONTAINED");
} else if (*p >= SYNID_CLUSTER) {
- short scl_id = *p - SYNID_CLUSTER;
+ int scl_id = *p - SYNID_CLUSTER;
msg_putchar('@');
msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name);
@@ -3727,12 +3713,10 @@ static void put_id_list(const char *name,
msg_putchar(' ');
}
-static void put_pattern(char *s, int c, synpat_T *spp, int attr)
+static void put_pattern(const char *const s, const int c,
+ const synpat_T *const spp, const int attr)
{
- long n;
- int mask;
- int first;
- static char *sepchars = "/+=-#@\"|'^&";
+ static const char *const sepchars = "/+=-#@\"|'^&";
int i;
/* May have to write "matchgroup=group" */
@@ -3761,10 +3745,10 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
msg_outtrans(spp->sp_pattern);
msg_putchar(sepchars[i]);
- /* output any pattern options */
- first = TRUE;
- for (i = 0; i < SPO_COUNT; ++i) {
- mask = (1 << i);
+ // output any pattern options
+ bool first = true;
+ for (i = 0; i < SPO_COUNT; i++) {
+ const int mask = (1 << i);
if (!(spp->sp_off_flags & (mask + (mask << SPO_COUNT)))) {
continue;
}
@@ -3772,7 +3756,7 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
msg_putchar(','); // Separate with commas.
}
msg_puts(spo_name_tab[i]);
- n = spp->sp_offsets[i];
+ const long n = spp->sp_offsets[i];
if (i != SPO_LC_OFF) {
if (spp->sp_off_flags & mask)
msg_putchar('s');
@@ -3781,47 +3765,40 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
if (n > 0)
msg_putchar('+');
}
- if (n || i == SPO_LC_OFF)
+ if (n || i == SPO_LC_OFF) {
msg_outnum(n);
- first = FALSE;
+ }
+ first = false;
}
msg_putchar(' ');
}
-/*
- * List or clear the keywords for one syntax group.
- * Return TRUE if the header has been printed.
- */
-static int
-syn_list_keywords(
- int id,
- hashtab_T *ht,
- int did_header, /* header has already been printed */
- int attr
+// List or clear the keywords for one syntax group.
+// Return true if the header has been printed.
+static bool syn_list_keywords(
+ const int id,
+ const hashtab_T *const ht,
+ bool did_header, // header has already been printed
+ const int attr
)
{
int outlen;
- hashitem_T *hi;
- keyentry_T *kp;
- int todo;
int prev_contained = 0;
- short *prev_next_list = NULL;
- short *prev_cont_in_list = NULL;
+ const int16_t *prev_next_list = NULL;
+ const int16_t *prev_cont_in_list = NULL;
int prev_skipnl = 0;
int prev_skipwhite = 0;
int prev_skipempty = 0;
- /*
- * Unfortunately, this list of keywords is not sorted on alphabet but on
- * hash value...
- */
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) {
+ // Unfortunately, this list of keywords is not sorted on alphabet but on
+ // hash value...
+ size_t todo = ht->ht_used;
+ for (const hashitem_T *hi = ht->ht_array; todo > 0 && !got_int; hi++) {
if (HASHITEM_EMPTY(hi)) {
continue;
}
- --todo;
- for (kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) {
+ todo--;
+ for (keyentry_T *kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) {
if (kp->k_syn.id == id) {
if (prev_contained != (kp->flags & HL_CONTAINED)
|| prev_skipnl != (kp->flags & HL_SKIPNL)
@@ -3841,7 +3818,7 @@ syn_list_keywords(
prev_skipwhite = 0;
prev_skipempty = 0;
}
- did_header = TRUE;
+ did_header = true;
if (prev_contained != (kp->flags & HL_CONTAINED)) {
msg_puts_attr("contained", attr);
msg_putchar(' ');
@@ -3952,19 +3929,19 @@ static void clear_keywtab(hashtab_T *ht)
/// @param flags flags for this keyword
/// @param cont_in_list containedin for this keyword
/// @param next_list nextgroup for this keyword
-static void add_keyword(char_u *name,
- int id,
- int flags,
- short *cont_in_list,
- short *next_list,
- int conceal_char)
+static void add_keyword(char_u *const name,
+ const int id,
+ const int flags,
+ int16_t *const cont_in_list,
+ int16_t *const next_list,
+ const int conceal_char)
{
char_u name_folded[MAXKEYWLEN + 1];
- char_u *name_ic = (curwin->w_s->b_syn_ic)
- ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded))
- : name;
+ const char_u *const name_ic = (curwin->w_s->b_syn_ic)
+ ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded))
+ : name;
- keyentry_T *kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic));
+ keyentry_T *const kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic));
STRCPY(kp->keyword, name_ic);
kp->k_syn.id = id;
kp->k_syn.inc_tag = current_syn_inc_tag;
@@ -3976,11 +3953,12 @@ static void add_keyword(char_u *name,
}
kp->next_list = copy_id_list(next_list);
- hash_T hash = hash_hash(kp->keyword);
- hashtab_T *ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic
- : &curwin->w_s->b_keywtab;
- hashitem_T *hi = hash_lookup(ht, (const char *)kp->keyword,
- STRLEN(kp->keyword), hash);
+ const hash_T hash = hash_hash(kp->keyword);
+ hashtab_T *const ht = (curwin->w_s->b_syn_ic)
+ ? &curwin->w_s->b_keywtab_ic
+ : &curwin->w_s->b_keywtab;
+ hashitem_T *const hi = hash_lookup(ht, (const char *)kp->keyword,
+ STRLEN(kp->keyword), hash);
// even though it looks like only the kp->keyword member is
// being used here, vim uses some pointer trickery to get the orignal
@@ -4123,13 +4101,9 @@ get_syn_options(
return NULL;
}
} else if (flagtab[fidx].argtype == 11 && arg[5] == '=') {
- /* cchar=? */
- if (has_mbyte) {
- *conceal_char = mb_ptr2char(arg + 6);
- arg += mb_ptr2len(arg + 6) - 1;
- } else {
- *conceal_char = arg[6];
- }
+ // cchar=?
+ *conceal_char = utf_ptr2char(arg + 6);
+ arg += mb_ptr2len(arg + 6) - 1;
if (!vim_isprintc_strict(*conceal_char)) {
EMSG(_("E844: invalid cchar value"));
return NULL;
@@ -4191,8 +4165,8 @@ static void syn_incl_toplevel(int id, int *flagsp)
return;
*flagsp |= HL_CONTAINED;
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) {
- /* We have to alloc this, because syn_combine_list() will free it. */
- short *grp_list = xmalloc(2 * sizeof(short));
+ // We have to alloc this, because syn_combine_list() will free it.
+ int16_t *grp_list = xmalloc(2 * sizeof(*grp_list));
int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER;
grp_list[0] = id;
@@ -4407,9 +4381,9 @@ syn_cmd_match(
/* Get options before the pattern */
syn_opt_arg.flags = 0;
- syn_opt_arg.keyword = FALSE;
+ syn_opt_arg.keyword = false;
syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL;
- syn_opt_arg.has_cont_list = TRUE;
+ syn_opt_arg.has_cont_list = true;
syn_opt_arg.cont_list = NULL;
syn_opt_arg.cont_in_list = NULL;
syn_opt_arg.next_list = NULL;
@@ -4529,9 +4503,9 @@ syn_cmd_region(
init_syn_patterns();
syn_opt_arg.flags = 0;
- syn_opt_arg.keyword = FALSE;
+ syn_opt_arg.keyword = false;
syn_opt_arg.sync_idx = NULL;
- syn_opt_arg.has_cont_list = TRUE;
+ syn_opt_arg.has_cont_list = true;
syn_opt_arg.cont_list = NULL;
syn_opt_arg.cont_in_list = NULL;
syn_opt_arg.next_list = NULL;
@@ -4709,30 +4683,25 @@ syn_cmd_region(
}
}
-/*
- * A simple syntax group ID comparison function suitable for use in qsort()
- */
-static int syn_compare_stub(const void *v1, const void *v2)
+// A simple syntax group ID comparison function suitable for use in qsort()
+static int syn_compare_stub(const void *const v1, const void *const v2)
{
- const short *s1 = v1;
- const short *s2 = v2;
+ const int16_t *const s1 = v1;
+ const int16_t *const s2 = v2;
return *s1 > *s2 ? 1 : *s1 < *s2 ? -1 : 0;
}
-/*
- * Combines lists of syntax clusters.
- * *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
- */
-static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
+// Combines lists of syntax clusters.
+// *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
+static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
+ const int list_op)
{
- int count1 = 0;
- int count2 = 0;
- short *g1;
- short *g2;
- short *clstr = NULL;
- int count;
- int round;
+ size_t count1 = 0;
+ size_t count2 = 0;
+ const int16_t *g1;
+ const int16_t *g2;
+ int16_t *clstr = NULL;
/*
* Handle degenerate cases.
@@ -4749,27 +4718,25 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
return;
}
- for (g1 = *clstr1; *g1; g1++)
- ++count1;
- for (g2 = *clstr2; *g2; g2++)
- ++count2;
+ for (g1 = *clstr1; *g1; g1++) {
+ count1++;
+ }
+ for (g2 = *clstr2; *g2; g2++) {
+ count2++;
+ }
- /*
- * For speed purposes, sort both lists.
- */
- qsort(*clstr1, (size_t)count1, sizeof(short), syn_compare_stub);
- qsort(*clstr2, (size_t)count2, sizeof(short), syn_compare_stub);
+ // For speed purposes, sort both lists.
+ qsort(*clstr1, count1, sizeof(**clstr1), syn_compare_stub);
+ qsort(*clstr2, count2, sizeof(**clstr2), syn_compare_stub);
- /*
- * We proceed in two passes; in round 1, we count the elements to place
- * in the new list, and in round 2, we allocate and populate the new
- * list. For speed, we use a mergesort-like method, adding the smaller
- * of the current elements in each list to the new list.
- */
- for (round = 1; round <= 2; round++) {
+ // We proceed in two passes; in round 1, we count the elements to place
+ // in the new list, and in round 2, we allocate and populate the new
+ // list. For speed, we use a mergesort-like method, adding the smaller
+ // of the current elements in each list to the new list.
+ for (int round = 1; round <= 2; round++) {
g1 = *clstr1;
g2 = *clstr2;
- count = 0;
+ int count = 0;
/*
* First, loop through the lists until one of them is empty.
@@ -4821,7 +4788,7 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
clstr = NULL;
break;
}
- clstr = xmalloc((count + 1) * sizeof(short));
+ clstr = xmalloc((count + 1) * sizeof(*clstr));
clstr[count] = 0;
}
}
@@ -4926,9 +4893,7 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
char_u *arg = eap->arg;
char_u *group_name_end;
char_u *rest;
- int scl_id;
- short *clstr_list;
- int got_clstr = FALSE;
+ bool got_clstr = false;
int opt_len;
int list_op;
@@ -4939,9 +4904,10 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
rest = get_group_name(arg, &group_name_end);
if (rest != NULL) {
- scl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
- if (scl_id == 0)
+ int scl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
+ if (scl_id == 0) {
return;
+ }
scl_id -= SYNID_CLUSTER;
for (;; ) {
@@ -4960,7 +4926,7 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
} else
break;
- clstr_list = NULL;
+ int16_t *clstr_list = NULL;
if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL) {
EMSG2(_(e_invarg2), rest);
break;
@@ -5218,35 +5184,28 @@ static void syn_cmd_sync(exarg_T *eap, int syncing)
*/
static int
get_id_list(
- char_u **arg,
- int keylen, // length of keyword
- int16_t **list, // where to store the resulting list, if not
- // NULL, the list is silently skipped!
- int skip
+ char_u **const arg,
+ const int keylen, // length of keyword
+ int16_t **const list, // where to store the resulting list, if not
+ // NULL, the list is silently skipped!
+ const bool skip
)
{
char_u *p = NULL;
char_u *end;
- int round;
- int count;
int total_count = 0;
- short *retval = NULL;
- char_u *name;
+ int16_t *retval = NULL;
regmatch_T regmatch;
int id;
- int failed = FALSE;
-
- /*
- * We parse the list twice:
- * round == 1: count the number of items, allocate the array.
- * round == 2: fill the array with the items.
- * In round 1 new groups may be added, causing the number of items to
- * grow when a regexp is used. In that case round 1 is done once again.
- */
- for (round = 1; round <= 2; ++round) {
- /*
- * skip "contains"
- */
+ bool failed = false;
+
+ // We parse the list twice:
+ // round == 1: count the number of items, allocate the array.
+ // round == 2: fill the array with the items.
+ // In round 1 new groups may be added, causing the number of items to
+ // grow when a regexp is used. In that case round 1 is done once again.
+ for (int round = 1; round <= 2; round++) {
+ // skip "contains"
p = skipwhite(*arg + keylen);
if (*p != '=') {
EMSG2(_("E405: Missing equal sign: %s"), *arg);
@@ -5258,14 +5217,12 @@ get_id_list(
break;
}
- /*
- * parse the arguments after "contains"
- */
- count = 0;
+ // parse the arguments after "contains"
+ int count = 0;
do {
- for (end = p; *end && !ascii_iswhite(*end) && *end != ','; ++end)
- ;
- name = xmalloc((int)(end - p + 3)); /* leave room for "^$" */
+ for (end = p; *end && !ascii_iswhite(*end) && *end != ','; end++) {
+ }
+ char_u *const name = xmalloc((int)(end - p + 3)); // leave room for "^$"
STRLCPY(name + 1, p, end - p + 1);
if ( STRCMP(name + 1, "ALLBUT") == 0
|| STRCMP(name + 1, "ALL") == 0
@@ -5273,7 +5230,7 @@ get_id_list(
|| STRCMP(name + 1, "CONTAINED") == 0) {
if (TOUPPER_ASC(**arg) != 'C') {
EMSG2(_("E407: %s not allowed here"), name + 1);
- failed = TRUE;
+ failed = true;
xfree(name);
break;
}
@@ -5309,7 +5266,7 @@ get_id_list(
STRCAT(name, "$");
regmatch.regprog = vim_regcomp(name, RE_MAGIC);
if (regmatch.regprog == NULL) {
- failed = TRUE;
+ failed = true;
xfree(name);
break;
}
@@ -5340,7 +5297,7 @@ get_id_list(
xfree(name);
if (id == 0) {
EMSG2(_("E409: Unknown group name: %s"), p);
- failed = TRUE;
+ failed = true;
break;
}
if (id > 0) {
@@ -5363,8 +5320,8 @@ get_id_list(
if (failed)
break;
if (round == 1) {
- retval = xmalloc((count + 1) * sizeof(short));
- retval[count] = 0; /* zero means end of the list */
+ retval = xmalloc((count + 1) * sizeof(*retval));
+ retval[count] = 0; // zero means end of the list
total_count = count;
}
}
@@ -5386,20 +5343,18 @@ get_id_list(
/*
* Make a copy of an ID list.
*/
-static short *copy_id_list(short *list)
+static int16_t *copy_id_list(const int16_t *const list)
{
- int len;
- int count;
- short *retval;
-
- if (list == NULL)
+ if (list == NULL) {
return NULL;
+ }
- for (count = 0; list[count]; ++count)
- ;
- len = (count + 1) * sizeof(short);
- retval = xmalloc(len);
- memmove(retval, list, (size_t)len);
+ int count;
+ for (count = 0; list[count]; count++) {
+ }
+ const size_t len = (count + 1) * sizeof(int16_t);
+ int16_t *const retval = xmalloc(len);
+ memmove(retval, list, len);
return retval;
}
@@ -6385,6 +6340,90 @@ int load_colors(char_u *name)
return retval;
}
+static char *(color_names[28]) = {
+ "Black", "DarkBlue", "DarkGreen", "DarkCyan",
+ "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
+ "Gray", "Grey", "LightGray", "LightGrey",
+ "DarkGray", "DarkGrey",
+ "Blue", "LightBlue", "Green", "LightGreen",
+ "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
+ "LightMagenta", "Yellow", "LightYellow", "White", "NONE" };
+ // indices:
+ // 0, 1, 2, 3,
+ // 4, 5, 6, 7,
+ // 8, 9, 10, 11,
+ // 12, 13,
+ // 14, 15, 16, 17,
+ // 18, 19, 20, 21, 22,
+ // 23, 24, 25, 26, 27
+static int color_numbers_16[28] = { 0, 1, 2, 3,
+ 4, 5, 6, 6,
+ 7, 7, 7, 7,
+ 8, 8,
+ 9, 9, 10, 10,
+ 11, 11, 12, 12, 13,
+ 13, 14, 14, 15, -1 };
+// for xterm with 88 colors...
+static int color_numbers_88[28] = { 0, 4, 2, 6,
+ 1, 5, 32, 72,
+ 84, 84, 7, 7,
+ 82, 82,
+ 12, 43, 10, 61,
+ 14, 63, 9, 74, 13,
+ 75, 11, 78, 15, -1 };
+// for xterm with 256 colors...
+static int color_numbers_256[28] = { 0, 4, 2, 6,
+ 1, 5, 130, 130,
+ 248, 248, 7, 7,
+ 242, 242,
+ 12, 81, 10, 121,
+ 14, 159, 9, 224, 13,
+ 225, 11, 229, 15, -1 };
+// for terminals with less than 16 colors...
+static int color_numbers_8[28] = { 0, 4, 2, 6,
+ 1, 5, 3, 3,
+ 7, 7, 7, 7,
+ 0+8, 0+8,
+ 4+8, 4+8, 2+8, 2+8,
+ 6+8, 6+8, 1+8, 1+8, 5+8,
+ 5+8, 3+8, 3+8, 7+8, -1 };
+
+// Lookup the "cterm" value to be used for color with index "idx" in
+// color_names[].
+// "boldp" will be set to TRUE or FALSE for a foreground color when using 8
+// colors, otherwise it will be unchanged.
+int lookup_color(const int idx, const bool foreground, TriState *const boldp)
+{
+ int color = color_numbers_16[idx];
+
+ // Use the _16 table to check if it's a valid color name.
+ if (color < 0) {
+ return -1;
+ }
+
+ if (t_colors == 8) {
+ // t_Co is 8: use the 8 colors table
+ color = color_numbers_8[idx];
+ if (foreground) {
+ // set/reset bold attribute to get light foreground
+ // colors (on some terminals, e.g. "linux")
+ if (color & 8) {
+ *boldp = kTrue;
+ } else {
+ *boldp = kFalse;
+ }
+ }
+ color &= 7; // truncate to 8 colors
+ } else if (t_colors == 16) {
+ color = color_numbers_8[idx];
+ } else if (t_colors == 88) {
+ color = color_numbers_88[idx];
+ } else if (t_colors >= 256) {
+ color = color_numbers_256[idx];
+ }
+ return color;
+}
+
/// Handle ":highlight" command
///
@@ -6408,12 +6447,14 @@ void do_highlight(const char *line, const bool forceit, const bool init)
int attr;
int id;
int idx;
- int dodefault = FALSE;
- int doclear = FALSE;
- int dolink = FALSE;
- int error = FALSE;
+ struct hl_group item_before;
+ bool dodefault = false;
+ bool doclear = false;
+ bool dolink = false;
+ bool error = false;
int color;
bool is_normal_group = false; // "Normal" group
+ bool did_highlight_changed = false;
// If no argument, list current highlighting.
if (ends_excmd((uint8_t)(*line))) {
@@ -6496,19 +6537,22 @@ void do_highlight(const char *line, const bool forceit, const bool init)
if (sourcing_name == NULL && !dodefault) {
EMSG(_("E414: group has settings, highlight link ignored"));
}
- } else {
- if (!init)
+ } else if (HL_TABLE()[from_id - 1].sg_link != to_id
+ || HL_TABLE()[from_id - 1].sg_scriptID != current_SID
+ || HL_TABLE()[from_id - 1].sg_cleared) {
+ if (!init) {
HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
+ }
HL_TABLE()[from_id - 1].sg_link = to_id;
HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
HL_TABLE()[from_id - 1].sg_cleared = false;
redraw_all_later(SOME_VALID);
+
+ // Only call highlight changed() once after multiple changes
+ need_highlight_changed = true;
}
}
- // Only call highlight_changed() once, after sourcing a syntax file.
- need_highlight_changed = true;
-
return;
}
@@ -6544,13 +6588,16 @@ void do_highlight(const char *line, const bool forceit, const bool init)
return;
}
+ // Make a copy so we can check if any attribute actually changed
+ item_before = HL_TABLE()[idx];
is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0);
// Clear the highlighting for ":hi clear {group}" and ":hi clear".
if (doclear || (forceit && init)) {
highlight_clear(idx);
- if (!doclear)
+ if (!doclear) {
HL_TABLE()[idx].sg_set = 0;
+ }
}
char *key = NULL;
@@ -6651,7 +6698,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
HL_TABLE()[idx].sg_set |= SG_CTERM;
}
HL_TABLE()[idx].sg_cterm = attr;
- HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ HL_TABLE()[idx].sg_cterm_bold = false;
}
} else if (*key == 'G') {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
@@ -6673,7 +6720,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
* flag was set for a light color, reset it now */
if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) {
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
- HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ HL_TABLE()[idx].sg_cterm_bold = false;
}
if (ascii_isdigit(*arg)) {
@@ -6695,60 +6742,6 @@ void do_highlight(const char *line, const bool forceit, const bool init)
break;
}
} else {
- static const char *color_names[] = {
- "Black", "DarkBlue", "DarkGreen", "DarkCyan",
- "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
- "Gray", "Grey",
- "LightGray", "LightGrey", "DarkGray", "DarkGrey",
- "Blue", "LightBlue", "Green", "LightGreen",
- "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
- "LightMagenta", "Yellow", "LightYellow", "White",
- "NONE"
- };
- static const int color_numbers_16[] = {
- 0, 1, 2, 3,
- 4, 5, 6, 6,
- 7, 7,
- 7, 7, 8, 8,
- 9, 9, 10, 10,
- 11, 11, 12, 12, 13,
- 13, 14, 14, 15,
- -1
- };
- // For xterm with 88 colors:
- static int color_numbers_88[] = {
- 0, 4, 2, 6,
- 1, 5, 32, 72,
- 84, 84,
- 7, 7, 82, 82,
- 12, 43, 10, 61,
- 14, 63, 9, 74, 13,
- 75, 11, 78, 15,
- -1
- };
- // For xterm with 256 colors:
- static int color_numbers_256[] = {
- 0, 4, 2, 6,
- 1, 5, 130, 130,
- 248, 248,
- 7, 7, 242, 242,
- 12, 81, 10, 121,
- 14, 159, 9, 224, 13,
- 225, 11, 229, 15,
- -1
- };
- // For terminals with less than 16 colors:
- static int color_numbers_8[28] = {
- 0, 4, 2, 6,
- 1, 5, 3, 3,
- 7, 7,
- 7, 7, 0+8, 0+8,
- 4+8, 4+8, 2+8, 2+8,
- 6+8, 6+8, 1+8, 1+8, 5+8,
- 5+8, 3+8, 3+8, 7+8,
- -1
- };
-
// Reduce calls to STRICMP a bit, it can be slow.
off = TOUPPER_ASC(*arg);
for (i = ARRAY_SIZE(color_names); --i >= 0; ) {
@@ -6764,32 +6757,16 @@ void do_highlight(const char *line, const bool forceit, const bool init)
break;
}
- // Use the _16 table to check if it's a valid color name.
- color = color_numbers_16[i];
- if (color >= 0) {
- if (t_colors == 8) {
- // t_Co is 8: use the 8 colors table.
- color = color_numbers_8[i];
- if (key[5] == 'F') {
- /* set/reset bold attribute to get light foreground
- * colors (on some terminals, e.g. "linux") */
- if (color & 8) {
- HL_TABLE()[idx].sg_cterm |= HL_BOLD;
- HL_TABLE()[idx].sg_cterm_bold = true;
- } else {
- HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
- }
- }
- color &= 7; // truncate to 8 colors
- } else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) {
- if (t_colors == 88) {
- color = color_numbers_88[i];
- } else if (t_colors >= 256) {
- color = color_numbers_256[i];
- } else {
- color = color_numbers_8[i];
- }
- }
+ TriState bold = kNone;
+ color = lookup_color(i, key[5] == 'F', &bold);
+
+ // set/reset bold attribute to get light foreground
+ // colors (on some terminals, e.g. "linux")
+ if (bold == kTrue) {
+ HL_TABLE()[idx].sg_cterm |= HL_BOLD;
+ HL_TABLE()[idx].sg_cterm_bold = true;
+ } else if (bold == kFalse) {
+ HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
}
}
// Add one to the argument, to avoid zero. Zero is used for
@@ -6828,8 +6805,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
} else if (strcmp(key, "GUIFG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
xfree(HL_TABLE()[idx].sg_rgb_fg_name);
if (strcmp(arg, "NONE")) {
@@ -6846,8 +6824,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
} else if (STRCMP(key, "GUIBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
xfree(HL_TABLE()[idx].sg_rgb_bg_name);
if (STRCMP(arg, "NONE") != 0) {
@@ -6864,8 +6843,9 @@ void do_highlight(const char *line, const bool forceit, const bool init)
}
} else if (strcmp(key, "GUISP") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
xfree(HL_TABLE()[idx].sg_rgb_sp_name);
if (strcmp(arg, "NONE") != 0) {
@@ -6917,17 +6897,23 @@ void do_highlight(const char *line, const bool forceit, const bool init)
// redraw below will still handle usages of guibg=fg etc.
ui_default_colors_set();
}
+ did_highlight_changed = true;
+ redraw_all_later(NOT_VALID);
} else {
set_hl_attr(idx);
}
HL_TABLE()[idx].sg_scriptID = current_SID;
- redraw_all_later(NOT_VALID);
}
xfree(key);
xfree(arg);
- // Only call highlight_changed() once, after sourcing a syntax file
- need_highlight_changed = true;
+ // Only call highlight_changed() once, after a sequence of highlight
+ // commands, and only if an attribute actually changed
+ if (memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0
+ && !did_highlight_changed) {
+ redraw_all_later(NOT_VALID);
+ need_highlight_changed = true;
+ }
}
#if defined(EXITFREE)
@@ -6980,7 +6966,7 @@ static void highlight_clear(int idx)
HL_TABLE()[idx].sg_attr = 0;
HL_TABLE()[idx].sg_cterm = 0;
- HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ HL_TABLE()[idx].sg_cterm_bold = false;
HL_TABLE()[idx].sg_cterm_fg = 0;
HL_TABLE()[idx].sg_cterm_bg = 0;
HL_TABLE()[idx].sg_gui = 0;
@@ -7008,12 +6994,10 @@ static void highlight_clear(int idx)
#define LIST_INT 3
/// @}
-static void highlight_list_one(int id)
+static void highlight_list_one(const int id)
{
- struct hl_group *sgp;
- int didh = FALSE;
-
- sgp = &HL_TABLE()[id - 1]; /* index is ID minus one */
+ struct hl_group *const sgp = &HL_TABLE()[id - 1]; // index is ID minus one
+ bool didh = false;
didh = highlight_list_arg(id, didh, LIST_ATTR,
sgp->sg_cterm, NULL, "cterm");
@@ -7050,24 +7034,24 @@ static void highlight_list_one(int id)
/// @param type one of \ref LIST_XXX
/// @param iarg integer argument used if \p type == LIST_INT
/// @param sarg string used if \p type == LIST_STRING
-static int highlight_list_arg(int id, int didh, int type, int iarg,
- char_u *sarg, const char *name)
+static bool highlight_list_arg(
+ const int id, bool didh, const int type, int iarg,
+ char_u *const sarg, const char *const name)
{
char_u buf[100];
- char_u *ts;
- int i;
- if (got_int)
- return FALSE;
+ if (got_int) {
+ return false;
+ }
if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) {
- ts = buf;
- if (type == LIST_INT)
- sprintf((char *)buf, "%d", iarg - 1);
- else if (type == LIST_STRING)
+ char_u *ts = buf;
+ if (type == LIST_INT) {
+ snprintf((char *)buf, sizeof(buf), "%d", iarg - 1);
+ } else if (type == LIST_STRING) {
ts = sarg;
- else { /* type == LIST_ATTR */
+ } else { // type == LIST_ATTR
buf[0] = NUL;
- for (i = 0; hl_attr_table[i] != 0; ++i) {
+ for (int i = 0; hl_attr_table[i] != 0; i++) {
if (iarg & hl_attr_table[i]) {
if (buf[0] != NUL)
xstrlcat((char *)buf, ",", 100);
@@ -7077,9 +7061,8 @@ static int highlight_list_arg(int id, int didh, int type, int iarg,
}
}
- (void)syn_list_header(didh,
- (int)(vim_strsize(ts) + STRLEN(name) + 1), id);
- didh = TRUE;
+ (void)syn_list_header(didh, (int)(vim_strsize(ts) + STRLEN(name) + 1), id);
+ didh = true;
if (!got_int) {
if (*name != NUL) {
MSG_PUTS_ATTR(name, HL_ATTR(HLF_D));
@@ -7197,11 +7180,11 @@ const char *highlight_color(const int id, const char *const what,
/// @param outlen length of string that comes
/// @param id highlight group id
/// @return true when started a new line.
-static int
-syn_list_header(int did_header, int outlen, int id)
+static bool syn_list_header(const bool did_header, const int outlen,
+ const int id)
{
int endcol = 19;
- int newline = TRUE;
+ bool newline = true;
if (!did_header) {
msg_putchar('\n');
@@ -7212,11 +7195,13 @@ syn_list_header(int did_header, int outlen, int id)
endcol = 15;
} else if (msg_col + outlen + 1 >= Columns) {
msg_putchar('\n');
- if (got_int)
- return TRUE;
+ if (got_int) {
+ return true;
+ }
} else {
- if (msg_col >= endcol) /* wrap around is like starting a new line */
- newline = FALSE;
+ if (msg_col >= endcol) { // wrap around is like starting a new line
+ newline = false;
+ }
}
if (msg_col >= endcol) /* output at least one space */
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index f8282955a6..9fbad74f64 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -3,6 +3,7 @@
#include <stdbool.h>
+#include "nvim/globals.h"
#include "nvim/buffer_defs.h"
#include "nvim/ex_cmds_defs.h"
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index 63089a62af..5ee0611d58 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -14,13 +14,11 @@ typedef struct syn_state synstate_T;
#include "nvim/buffer_defs.h"
#include "nvim/regexp_defs.h"
-typedef unsigned short disptick_T; /* display tick type */
-
/* struct passed to in_id_list() */
struct sp_syn {
- int inc_tag; /* ":syn include" unique tag */
- short id; /* highlight group ID of item */
- short *cont_in_list; /* cont.in group IDs, if non-zero */
+ int inc_tag; // ":syn include" unique tag
+ int16_t id; // highlight group ID of item
+ int16_t *cont_in_list; // cont.in group IDs, if non-zero
};
/*
@@ -29,12 +27,12 @@ struct sp_syn {
typedef struct keyentry keyentry_T;
struct keyentry {
- keyentry_T *ke_next; /* next entry with identical "keyword[]" */
- struct sp_syn k_syn; /* struct passed to in_id_list() */
- short *next_list; /* ID list for next match (if non-zero) */
+ keyentry_T *ke_next; // next entry with identical "keyword[]"
+ struct sp_syn k_syn; // struct passed to in_id_list()
+ int16_t *next_list; // ID list for next match (if non-zero)
int flags;
- int k_char; /* conceal substitute character */
- char_u keyword[1]; /* actually longer */
+ int k_char; // conceal substitute character
+ char_u keyword[1]; // actually longer
};
/*
@@ -59,13 +57,13 @@ struct syn_state {
bufstate_T sst_stack[SST_FIX_STATES]; /* short state stack */
garray_T sst_ga; /* growarray for long state stack */
} sst_union;
- int sst_next_flags; /* flags for sst_next_list */
- int sst_stacksize; /* number of states on the stack */
- short *sst_next_list; /* "nextgroup" list in this state
- * (this is a copy, don't free it! */
- disptick_T sst_tick; /* tick when last displayed */
- linenr_T sst_change_lnum; /* when non-zero, change in this line
- * may have made the state invalid */
+ int sst_next_flags; // flags for sst_next_list
+ int sst_stacksize; // number of states on the stack
+ int16_t *sst_next_list; // "nextgroup" list in this state
+ // (this is a copy, don't free it!
+ disptick_T sst_tick; // tick when last displayed
+ linenr_T sst_change_lnum; // when non-zero, change in this line
+ // may have made the state invalid
};
#endif // NVIM_SYNTAX_DEFS_H
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 0379235ec0..361db47fc7 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -60,12 +60,14 @@ NEW_TESTS ?= \
test_fnameescape.res \
test_fold.res \
test_ga.res \
+ test_getvar.res \
test_glob2regpat.res \
test_gf.res \
test_gn.res \
test_hardcopy.res \
test_help_tagjump.res \
test_hide.res \
+ test_highlight.res \
test_history.res \
test_hlsearch.res \
test_increment.res \
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index 8014b76af7..44c01cfeff 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -243,6 +243,7 @@ let s:flaky = [
\ 'Test_quoteplus()',
\ 'Test_quotestar()',
\ 'Test_reltime()',
+ \ 'Test_repeat_three()',
\ 'Test_terminal_composing_unicode()',
\ 'Test_terminal_redir_file()',
\ 'Test_terminal_tmap()',
diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim
index f3cc7da70f..51bf8ce0fc 100644
--- a/src/nvim/testdir/setup.vim
+++ b/src/nvim/testdir/setup.vim
@@ -33,4 +33,5 @@ if has('win32')
let $TERM = ''
let &shell = empty($COMSPEC) ? exepath('cmd.exe') : $COMSPEC
set shellcmdflag=/s/c shellxquote=\" shellredir=>%s\ 2>&1
+ let &shellpipe = &shellredir
endif
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index d026221dac..238dbe8d90 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -4,6 +4,7 @@
source test_assign.vim
source test_cd.vim
source test_changedtick.vim
+source test_compiler.vim
source test_cursor_func.vim
source test_ex_undo.vim
source test_ex_z.vim
diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim
new file mode 100644
index 0000000000..84fba0f9a4
--- /dev/null
+++ b/src/nvim/testdir/test_compiler.vim
@@ -0,0 +1,49 @@
+" Test the :compiler command
+
+func Test_compiler()
+ if !executable('perl')
+ return
+ endif
+
+ e Xfoo.pl
+ compiler perl
+ call assert_equal('perl', b:current_compiler)
+ call assert_fails('let g:current_compiler', 'E121:')
+
+ call setline(1, ['#!/usr/bin/perl -w', 'use strict;', 'my $foo=1'])
+ w!
+ call feedkeys(":make\<CR>\<CR>", 'tx')
+ call assert_fails('clist', 'E42:')
+
+ call setline(1, ['#!/usr/bin/perl -w', 'use strict;', '$foo=1'])
+ w!
+ call feedkeys(":make\<CR>\<CR>", 'tx')
+ let a=execute('clist')
+ call assert_match("\n 1 Xfoo.pl:3: Global symbol \"\$foo\" "
+ \ . "requires explicit package name", a)
+
+ call delete('Xfoo.pl')
+ bw!
+endfunc
+
+func Test_compiler_without_arg()
+ let a=split(execute('compiler'))
+ call assert_match(expand('^.*runtime/compiler/ant.vim$'), a[0])
+ call assert_match(expand('^.*runtime/compiler/bcc.vim$'), a[1])
+ call assert_match(expand('^.*runtime/compiler/xmlwf.vim$'), a[-1])
+endfunc
+
+func Test_compiler_completion()
+ call feedkeys(":compiler \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('^"compiler ant bcc .* xmlwf$', @:)
+
+ call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"compiler pbx perl php pylint pyunit', @:)
+
+ call feedkeys(":compiler! p\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"compiler! pbx perl php pylint pyunit', @:)
+endfunc
+
+func Test_compiler_error()
+ call assert_fails('compiler doesnotexist', 'E666:')
+endfunc
diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim
new file mode 100644
index 0000000000..d6b6b69aa8
--- /dev/null
+++ b/src/nvim/testdir/test_getvar.vim
@@ -0,0 +1,104 @@
+" Tests for getwinvar(), gettabvar() and gettabwinvar().
+func Test_var()
+ " Use strings to test for memory leaks. First, check that in an empty
+ " window, gettabvar() returns the correct value
+ let t:testvar='abcd'
+ call assert_equal('abcd', gettabvar(1, 'testvar'))
+ call assert_equal('abcd', gettabvar(1, 'testvar'))
+
+ " test for getwinvar()
+ let w:var_str = "Dance"
+ let def_str = "Chance"
+ call assert_equal('Dance', getwinvar(1, 'var_str'))
+ call assert_equal('Dance', getwinvar(1, 'var_str', def_str))
+ call assert_equal({'var_str': 'Dance'}, getwinvar(1, ''))
+ call assert_equal({'var_str': 'Dance'}, getwinvar(1, '', def_str))
+ unlet w:var_str
+ call assert_equal('Chance', getwinvar(1, 'var_str', def_str))
+ call assert_equal({}, getwinvar(1, ''))
+ call assert_equal({}, getwinvar(1, '', def_str))
+ call assert_equal('', getwinvar(9, ''))
+ call assert_equal('Chance', getwinvar(9, '', def_str))
+ call assert_equal(0, getwinvar(1, '&nu'))
+ call assert_equal(0, getwinvar(1, '&nu', 1))
+ unlet def_str
+
+ " test for gettabvar()
+ tabnew
+ tabnew
+ let t:var_list = [1, 2, 3]
+ let t:other = 777
+ let def_list = [4, 5, 6, 7]
+ tabrewind
+ call assert_equal([1, 2, 3], gettabvar(3, 'var_list'))
+ call assert_equal([1, 2, 3], gettabvar(3, 'var_list', def_list))
+ call assert_equal({'var_list': [1, 2, 3], 'other': 777}, gettabvar(3, ''))
+ call assert_equal({'var_list': [1, 2, 3], 'other': 777},
+ \ gettabvar(3, '', def_list))
+
+ tablast
+ unlet t:var_list
+ tabrewind
+ call assert_equal([4, 5, 6, 7], gettabvar(3, 'var_list', def_list))
+ call assert_equal('', gettabvar(9, ''))
+ call assert_equal([4, 5, 6, 7], gettabvar(9, '', def_list))
+ call assert_equal('', gettabvar(3, '&nu'))
+ call assert_equal([4, 5, 6, 7], gettabvar(3, '&nu', def_list))
+ unlet def_list
+ tabonly
+
+ " test for gettabwinvar()
+ tabnew
+ tabnew
+ tabprev
+ split
+ split
+ wincmd w
+ vert split
+ wincmd w
+ let w:var_dict = {'dict': 'tabwin'}
+ let def_dict = {'dict2': 'newval'}
+ wincmd b
+ tabrewind
+ call assert_equal({'dict': 'tabwin'}, gettabwinvar(2, 3, 'var_dict'))
+ call assert_equal({'dict': 'tabwin'},
+ \ gettabwinvar(2, 3, 'var_dict', def_dict))
+ call assert_equal({'var_dict': {'dict': 'tabwin'}}, gettabwinvar(2, 3, ''))
+ call assert_equal({'var_dict': {'dict': 'tabwin'}},
+ \ gettabwinvar(2, 3, '', def_dict))
+
+ tabnext
+ 3wincmd w
+ unlet w:var_dict
+ tabrewind
+ call assert_equal({'dict2': 'newval'},
+ \ gettabwinvar(2, 3, 'var_dict', def_dict))
+ call assert_equal({}, gettabwinvar(2, 3, ''))
+ call assert_equal({}, gettabwinvar(2, 3, '', def_dict))
+ call assert_equal("", gettabwinvar(2, 9, ''))
+ call assert_equal({'dict2': 'newval'}, gettabwinvar(2, 9, '', def_dict))
+ call assert_equal('', gettabwinvar(9, 3, ''))
+ call assert_equal({'dict2': 'newval'}, gettabwinvar(9, 3, '', def_dict))
+
+ unlet def_dict
+
+ call assert_equal('', gettabwinvar(2, 3, '&nux'))
+ call assert_equal(1, gettabwinvar(2, 3, '&nux', 1))
+ tabonly
+endfunc
+
+" It was discovered that "gettabvar()" would fail if called from within the
+" tabline when the user closed a window. This test confirms the fix.
+func Test_gettabvar_in_tabline()
+ let t:var_str = 'value'
+
+ set tabline=%{assert_equal('value',gettabvar(1,'var_str'))}
+ set showtabline=2
+
+ " Simulate the user opening a split (which becomes window #1) and then
+ " closing the split, which triggers the redrawing of the tabline.
+ leftabove split
+ redrawstatus!
+ close
+ redrawstatus!
+endfunc
diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim
new file mode 100644
index 0000000000..33df79581c
--- /dev/null
+++ b/src/nvim/testdir/test_highlight.vim
@@ -0,0 +1,535 @@
+" Tests for ":highlight" and highlighting.
+
+source view_util.vim
+
+func Test_highlight()
+ " basic test if ":highlight" doesn't crash
+ highlight
+ hi Search
+
+ " test setting colors.
+ " test clearing one color and all doesn't generate error or warning
+ silent! hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
+ silent! hi Group2 term= cterm=
+ hi Group3 term=underline cterm=bold
+
+ let res = split(execute("hi NewGroup"), "\n")[0]
+ " filter ctermfg and ctermbg, the numbers depend on the terminal
+ let res = substitute(res, 'ctermfg=\d*', 'ctermfg=2', '')
+ let res = substitute(res, 'ctermbg=\d*', 'ctermbg=3', '')
+ call assert_equal("NewGroup xxx cterm=italic ctermfg=2 ctermbg=3",
+ \ res)
+ call assert_equal("Group2 xxx cleared",
+ \ split(execute("hi Group2"), "\n")[0])
+ call assert_equal("Group3 xxx cterm=bold",
+ \ split(execute("hi Group3"), "\n")[0])
+
+ hi clear NewGroup
+ call assert_equal("NewGroup xxx cleared",
+ \ split(execute("hi NewGroup"), "\n")[0])
+ call assert_equal("Group2 xxx cleared",
+ \ split(execute("hi Group2"), "\n")[0])
+ hi Group2 NONE
+ call assert_equal("Group2 xxx cleared",
+ \ split(execute("hi Group2"), "\n")[0])
+ hi clear
+ call assert_equal("Group3 xxx cleared",
+ \ split(execute("hi Group3"), "\n")[0])
+ call assert_fails("hi Crash term='asdf", "E475:")
+endfunc
+
+function! HighlightArgs(name)
+ return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
+endfunction
+
+function! IsColorable()
+ return has('gui_running') || str2nr(&t_Co) >= 8
+endfunction
+
+function! HiCursorLine()
+ let hiCursorLine = HighlightArgs('CursorLine')
+ if has('gui_running')
+ let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
+ let hi_ul = 'hi CursorLine gui=underline guibg=NONE'
+ let hi_bg = 'hi CursorLine gui=NONE ' . guibg
+ else
+ let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE'
+ let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
+ endif
+ return [hiCursorLine, hi_ul, hi_bg]
+endfunction
+
+function! Check_lcs_eol_attrs(attrs, row, col)
+ let save_lcs = &lcs
+ set list
+
+ call assert_equal(a:attrs, ScreenAttrs(a:row, a:col)[0])
+
+ set nolist
+ let &lcs = save_lcs
+endfunction
+
+func Test_highlight_eol_with_cursorline()
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 20)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ " expected:
+ " 'abcd '
+ " ^^^^ ^^^^^ no highlight
+ " ^ 'Search' highlight
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
+ call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9])
+ call assert_notequal(attrs0[0], attrs0[4])
+
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'abcd '
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
+ call assert_equal(attrs0[4], attrs[4])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[5], attrs[5])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_vertsplit()
+ if !has('vertsplit')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 5)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ let expected = "abcd |abcd "
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ " expected:
+ " 'abcd |abcd '
+ " ^^^^ ^^^^^^^^^ no highlight
+ " ^ 'Search' highlight
+ " ^ 'VertSplit' highlight
+ let attrs0 = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
+ call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14])
+ call assert_notequal(attrs0[0], attrs0[4])
+ call assert_notequal(attrs0[0], attrs0[5])
+ call assert_notequal(attrs0[4], attrs0[5])
+
+ setlocal cursorline
+
+ " expected:
+ " 'abcd |abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^ 'VertSplit' highlight
+ " ^^^^^^^^^ no highlight
+
+ " underline
+ exe hi_ul
+
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ let attrs = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
+ call assert_equal(attrs0[5:14], attrs[5:14])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[0], attrs[5])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs[5], attrs[6])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 15)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ let attrs = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
+ call assert_equal(attrs0[5:14], attrs[5:14])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[0], attrs[5])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs[5], attrs[6])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_equal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 15)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_rightleft()
+ if !has('rightleft')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ setlocal rightleft
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " ' dcba'
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
+ call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5])
+ call assert_notequal(attrs[9], attrs[5])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[9], attrs[9])
+ call assert_notequal(attrs0[5], attrs[5])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " ' dcba'
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
+ call assert_equal(repeat([attrs[4]], 5), attrs[0:4])
+ call assert_equal(attrs0[5], attrs[5])
+ call assert_notequal(attrs[9], attrs[5])
+ call assert_notequal(attrs[5], attrs[4])
+ call assert_notequal(attrs0[9], attrs[9])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_linewrap()
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ call setline(1, [repeat('a', 51) . 'bcd', ''])
+ call matchadd('Search', '\n')
+
+ setlocal wrap
+ normal! gg$
+ let attrs0 = ScreenAttrs(5, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(5, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 5, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'abcd '
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(5, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
+ call assert_equal(attrs0[4], attrs[4])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[5], attrs[5])
+ call Check_lcs_eol_attrs(attrs, 5, 10)
+ endif
+
+ setlocal nocursorline nowrap
+ normal! gg$
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'aaabcd '
+ " ^^^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[6], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'aaabcd '
+ " ^^^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[7], attrs[7])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_sign()
+ if !has('signs')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ sign define Sign text=>>
+ exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " '>>abcd '
+ " ^^ sign
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_notequal(attrs[2], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[6], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " '>>abcd '
+ " ^^ sign
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[2], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[7], attrs[7])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ sign unplace 1
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_breakindent()
+ if !has('linebreak')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
+ call setline(1, ' ' . repeat('a', 9) . 'bcd')
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(2, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " ' >bcd '
+ " ^^^ breakindent and showbreak
+ " ^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(2, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_equal(attrs0[0], attrs[0])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[2], attrs[3])
+ call assert_notequal(attrs[3], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[3], attrs[3])
+ call assert_notequal(attrs0[6], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 2, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " ' >bcd '
+ " ^^^ breakindent and showbreak
+ " ^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(2, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[0], attrs[0])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[2], attrs[3])
+ call assert_notequal(attrs[3], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[3], attrs[3])
+ call assert_notequal(attrs0[7], attrs[7])
+ call Check_lcs_eol_attrs(attrs, 2, 10)
+ endif
+
+ call CloseWindow()
+ set showbreak=
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_on_diff()
+ call setline(1, ['abcd', ''])
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+
+ diffthis
+ botright new
+ diffthis
+
+ " expected:
+ " ' abcd '
+ " ^^ sign
+ " ^^^^ ^^^ 'DiffAdd' highlight
+ " ^ 'Search' highlight
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal(repeat([attrs[2]], 3), attrs[7:9])
+ call assert_equal(attrs0[4], attrs[6])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[2], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ bwipe!
+ diffoff
+endfunc
+
+func Test_termguicolors()
+ if !exists('+termguicolors')
+ return
+ endif
+ if has('vtp') && !has('vcon')
+ " Win32: 'guicolors' doesn't work without virtual console.
+ call assert_fails('set termguicolors', 'E954:')
+ return
+ endif
+
+ " Basic test that setting 'termguicolors' works with one color.
+ set termguicolors
+ redraw
+ set t_Co=1
+ redraw
+ set t_Co=0
+ redraw
+endfunc
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 8d2c61f6f0..33abb69ca6 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -1702,7 +1702,8 @@ func Xproperty_tests(cchar)
Xopen
wincmd p
call g:Xsetlist([{'filename':'foo', 'lnum':27}])
- call g:Xsetlist([], 'a', {'title' : 'Sample'})
+ let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
+ call assert_equal(0, s)
let d = g:Xgetlist({"title":1})
call assert_equal('Sample', d.title)
@@ -1756,7 +1757,8 @@ func Xproperty_tests(cchar)
endif
" Context related tests
- call g:Xsetlist([], 'a', {'context':[1,2,3]})
+ let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
+ call assert_equal(0, s)
call test_garbagecollect_now()
let d = g:Xgetlist({'context':1})
call assert_equal([1,2,3], d.context)
@@ -1821,8 +1823,9 @@ func Xproperty_tests(cchar)
" Test for setting/getting items
Xexpr ""
let qfprev = g:Xgetlist({'nr':0})
- call g:Xsetlist([], ' ', {'title':'Green',
+ let s = g:Xsetlist([], ' ', {'title':'Green',
\ 'items' : [{'filename':'F1', 'lnum':10}]})
+ call assert_equal(0, s)
let qfcur = g:Xgetlist({'nr':0})
call assert_true(qfcur.nr == qfprev.nr + 1)
let l = g:Xgetlist({'items':1})
@@ -2242,3 +2245,27 @@ func Test_resize_from_copen()
augroup! QF_Test
endtry
endfunc
+
+" Tests for the quickfix buffer b:changedtick variable
+func Xchangedtick_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ new | only
+
+ Xexpr "" | Xexpr "" | Xexpr ""
+
+ Xopen
+ Xolder
+ Xolder
+ Xaddexpr "F1:10:Line10"
+ Xaddexpr "F2:20:Line20"
+ call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
+ call g:Xsetlist([], 'f')
+ call assert_equal(8, getbufvar('%', 'changedtick'))
+ Xclose
+endfunc
+
+func Test_changedtick()
+ call Xchangedtick_tests('c')
+ call Xchangedtick_tests('l')
+endfunc
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index 0f2e7e493e..756a455ebd 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -17,6 +17,14 @@ func Test_block_shift_multibyte()
q!
endfunc
+func Test_block_shift_overflow()
+ " This used to cause a multiplication overflow followed by a crash.
+ new
+ normal ii
+ exe "normal \<C-V>876543210>"
+ q!
+endfunc
+
func Test_Visual_ctrl_o()
new
call setline(1, ['one', 'two', 'three'])
@@ -118,9 +126,34 @@ func Test_blockwise_visual()
enew!
endfunc
+" Test swapping corners in blockwise visual mode with o and O
+func Test_blockwise_visual_o_O()
+ enew!
+
+ exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
+ exe "norm! gvO\<Esc>ra"
+ exe "norm! gvO\<Esc>rb"
+ exe "norm! gvo\<C-c>rc"
+ exe "norm! gvO\<C-c>rd"
+
+ call assert_equal(['..........',
+ \ '...c d..',
+ \ '... ..',
+ \ '...a b..',
+ \ '..........'], getline(1, '$'))
+
+ enew!
+endfun
+
" Test Virtual replace mode.
func Test_virtual_replace()
throw 'skipped: TODO: '
+ if exists('&t_kD')
+ let save_t_kD = &t_kD
+ endif
+ if exists('&t_kb')
+ let save_t_kb = &t_kb
+ endif
exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
enew!
exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
@@ -151,4 +184,96 @@ func Test_virtual_replace()
call assert_equal(['AB......CDEFGHI.Jkl',
\ 'AB IJKLMNO QRst'], getline(12, 13))
enew!
+ set noai bs&vim
+ if exists('save_t_kD')
+ let &t_kD = save_t_kD
+ endif
+ if exists('save_t_kb')
+ let &t_kb = save_t_kb
+ endif
+endfunc
+
+" Test Virtual replace mode.
+func Test_virtual_replace2()
+ enew!
+ set bs=2
+ exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
+ call cursor(1,1)
+ " Test 1: Test that del deletes the newline
+ exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
+ call assert_equal(['0 1',
+ \ 'A',
+ \ 'BCDEFGHIJ',
+ \ ' KL',
+ \ 'MNO',
+ \ 'PQR',
+ \ ], getline(1, 6))
+ " Test 2:
+ " a newline is not deleted, if no newline has been added in virtual replace mode
+ %d_
+ call setline(1, ['abcd', 'efgh', 'ijkl'])
+ call cursor(2,1)
+ exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
+ call assert_equal(['abcd',
+ \ '123h',
+ \ 'ijkl'], getline(1, '$'))
+ " Test 3:
+ " a newline is deleted, if a newline has been inserted before in virtual replace mode
+ %d_
+ call setline(1, ['abcd', 'efgh', 'ijkl'])
+ call cursor(2,1)
+ exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
+ call assert_equal(['abcd',
+ \ '1234',
+ \ 'ijkl'], getline(1, '$'))
+ " Test 4:
+ " delete add a newline, delete it, add it again and check undo
+ %d_
+ call setline(1, ['abcd', 'efgh', 'ijkl'])
+ call cursor(2,1)
+ " break undo sequence explicitly
+ let &ul = &ul
+ exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
+ let &ul = &ul
+ call assert_equal(['abcd',
+ \ '123456',
+ \ ''], getline(1, '$'))
+ norm! u
+ call assert_equal(['abcd',
+ \ 'efgh',
+ \ 'ijkl'], getline(1, '$'))
+ " clean up
+ %d_
+ set bs&vim
+endfunc
+
+" Test for Visual mode not being reset causing E315 error.
+func TriggerTheProblem()
+ " At this point there is no visual selection because :call reset it.
+ " Let's restore the selection:
+ normal gv
+ '<,'>del _
+ try
+ exe "normal \<Esc>"
+ catch /^Vim\%((\a\+)\)\=:E315/
+ echom 'Snap! E315 error!'
+ let g:msg = 'Snap! E315 error!'
+ endtry
+endfunc
+
+func Test_visual_mode_reset()
+ set belloff=all
+ enew
+ let g:msg = "Everything's fine."
+ enew
+ setl buftype=nofile
+ call append(line('$'), 'Delete this line.')
+
+ " NOTE: this has to be done by a call to a function because executing :del
+ " the ex-way will require the colon operator which resets the visual mode
+ " thus preventing the problem:
+ exe "normal! GV:call TriggerTheProblem()\<CR>"
+ call assert_equal("Everything's fine.", g:msg)
+
+ set belloff&
endfunc
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index 139d29a48b..ad60c8d3c7 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -17,7 +17,7 @@ func Test_window_cmd_ls0_with_split()
endfunc
func Test_window_cmd_cmdwin_with_vsp()
- let efmt='Expected 0 but got %d (in ls=%d, %s window)'
+ let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
for v in range(0, 2)
exec "set ls=" . v
vsplit
@@ -417,4 +417,92 @@ func Test_window_newtab()
endfunc
+" Tests for adjusting window and contents
+func GetScreenStr(row)
+ let str = ""
+ for c in range(1,3)
+ let str .= nr2char(screenchar(a:row, c))
+ endfor
+ return str
+endfunc
+
+func Test_window_contents()
+ enew! | only | new
+ call setline(1, range(1,256))
+
+ exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(1, line("w0"))
+ call assert_equal('1 ', s3)
+
+ exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(50, line("w0"))
+ call assert_equal('50 ', s3)
+
+ exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(59, line("w0"))
+ call assert_equal('59 ', s3)
+
+ bwipeout!
+ call test_garbagecollect_now()
+endfunc
+
+func Test_access_freed_mem()
+ " This was accessing freed memory
+ au * 0 vs xxx
+ arg 0
+ argadd
+ all
+ all
+ au!
+ bwipe xxx
+endfunc
+
+func Test_visual_cleared_after_window_split()
+ new | only!
+ let smd_save = &showmode
+ set showmode
+ let ls_save = &laststatus
+ set laststatus=1
+ call setline(1, ['a', 'b', 'c', 'd', ''])
+ norm! G
+ exe "norm! kkvk"
+ redraw
+ exe "norm! \<C-W>v"
+ redraw
+ " check if '-- VISUAL --' disappeared from command line
+ let columns = range(1, &columns)
+ let cmdlinechars = map(columns, 'nr2char(screenchar(&lines, v:val))')
+ let cmdline = join(cmdlinechars, '')
+ let cmdline_ltrim = substitute(cmdline, '^\s*', "", "")
+ let mode_shown = substitute(cmdline_ltrim, '\s*$', "", "")
+ call assert_equal('', mode_shown)
+ let &showmode = smd_save
+ let &laststatus = ls_save
+ bwipe!
+endfunc
+
+func Test_winrestcmd()
+ 2split
+ 3vsplit
+ let a = winrestcmd()
+ call assert_equal(2, winheight(0))
+ call assert_equal(3, winwidth(0))
+ wincmd =
+ call assert_notequal(2, winheight(0))
+ call assert_notequal(3, winwidth(0))
+ exe a
+ call assert_equal(2, winheight(0))
+ call assert_equal(3, winwidth(0))
+ only
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim
index eb92630761..29ea073f97 100644
--- a/src/nvim/testdir/view_util.vim
+++ b/src/nvim/testdir/view_util.vim
@@ -1,5 +1,10 @@
" Functions about view shared by several tests
+" Only load this script once.
+if exists('*ScreenLines')
+ finish
+endif
+
" ScreenLines(lnum, width) or
" ScreenLines([start, end], width)
function! ScreenLines(lnum, width) abort
@@ -18,6 +23,22 @@ function! ScreenLines(lnum, width) abort
return lines
endfunction
+function! ScreenAttrs(lnum, width) abort
+ redraw!
+ if type(a:lnum) == v:t_list
+ let start = a:lnum[0]
+ let end = a:lnum[1]
+ else
+ let start = a:lnum
+ let end = a:lnum
+ endif
+ let attrs = []
+ for l in range(start, end)
+ let attrs += [map(range(1, a:width), 'screenattr(l, v:val)')]
+ endfor
+ return attrs
+endfunction
+
function! NewWindow(height, width) abort
exe a:height . 'new'
exe a:width . 'vsp'
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 2055b4879e..f4eb50b3b5 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2233,10 +2233,11 @@ static void u_undoredo(int undo, bool do_buf_event)
* If the file is empty, there is an empty line 1 that we
* should get rid of, by replacing it with the new line
*/
- if (empty_buffer && lnum == 0)
- ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
- else
+ if (empty_buffer && lnum == 0) {
+ ml_replace((linenr_T)1, uep->ue_array[i], true);
+ } else {
ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
+ }
xfree(uep->ue_array[i]);
}
xfree((char_u *)uep->ue_array);
@@ -2902,7 +2903,7 @@ void u_undoline(void)
curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
return;
oldp = u_save_line(curbuf->b_u_line_lnum);
- ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
+ ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true);
changed_bytes(curbuf->b_u_line_lnum, 0);
xfree(curbuf->b_u_line_ptr);
curbuf->b_u_line_ptr = oldp;
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 274bf72f3b..8239061a0c 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2296,6 +2296,9 @@ winframe_remove (
if (frp2->fr_win != NULL)
frp2->fr_win->w_frame = frp2->fr_parent;
frp = frp2->fr_parent;
+ if (topframe->fr_child == frp2) {
+ topframe->fr_child = frp;
+ }
xfree(frp2);
frp2 = frp->fr_parent;
@@ -2317,6 +2320,9 @@ winframe_remove (
break;
}
}
+ if (topframe->fr_child == frp) {
+ topframe->fr_child = frp2;
+ }
xfree(frp);
}
}
@@ -2959,7 +2965,6 @@ static int win_alloc_firstwin(win_T *oldwin)
topframe = curwin->w_frame;
topframe->fr_width = Columns;
topframe->fr_height = Rows - p_ch;
- topframe->fr_win = curwin;
return OK;
}
@@ -3970,18 +3975,20 @@ win_remove (
tabpage_T *tp /* tab page "win" is in, NULL for current */
)
{
- if (wp->w_prev != NULL)
+ if (wp->w_prev != NULL) {
wp->w_prev->w_next = wp->w_next;
- else if (tp == NULL)
- firstwin = wp->w_next;
- else
+ } else if (tp == NULL) {
+ firstwin = curtab->tp_firstwin = wp->w_next;
+ } else {
tp->tp_firstwin = wp->w_next;
- if (wp->w_next != NULL)
+ }
+ if (wp->w_next != NULL) {
wp->w_next->w_prev = wp->w_prev;
- else if (tp == NULL)
- lastwin = wp->w_prev;
- else
+ } else if (tp == NULL) {
+ lastwin = curtab->tp_lastwin = wp->w_prev;
+ } else {
tp->tp_lastwin = wp->w_prev;
+ }
}
/*
@@ -4015,12 +4022,18 @@ static void frame_insert(frame_T *before, frame_T *frp)
*/
static void frame_remove(frame_T *frp)
{
- if (frp->fr_prev != NULL)
+ if (frp->fr_prev != NULL) {
frp->fr_prev->fr_next = frp->fr_next;
- else
+ } else {
frp->fr_parent->fr_child = frp->fr_next;
- if (frp->fr_next != NULL)
+ // special case: topframe->fr_child == frp
+ if (topframe->fr_child == frp) {
+ topframe->fr_child = frp->fr_next;
+ }
+ }
+ if (frp->fr_next != NULL) {
frp->fr_next->fr_prev = frp->fr_prev;
+ }
}
@@ -4848,8 +4861,8 @@ void scroll_to_fraction(win_T *wp, int prev_height)
sline = wp->w_wrow - line_size;
if (sline >= 0) {
- /* Make sure the whole cursor line is visible, if possible. */
- int rows = plines_win(wp, lnum, FALSE);
+ // Make sure the whole cursor line is visible, if possible.
+ const int rows = plines_win(wp, lnum, false);
if (sline > wp->w_height - rows) {
sline = wp->w_height - rows;
@@ -4884,12 +4897,13 @@ void scroll_to_fraction(win_T *wp, int prev_height)
--sline;
break;
}
- --lnum;
- if (lnum == wp->w_topline)
- line_size = plines_win_nofill(wp, lnum, TRUE)
+ lnum--;
+ if (lnum == wp->w_topline) {
+ line_size = plines_win_nofill(wp, lnum, true)
+ wp->w_topfill;
- else
- line_size = plines_win(wp, lnum, TRUE);
+ } else {
+ line_size = plines_win(wp, lnum, true);
+ }
sline -= line_size;
}
@@ -5488,12 +5502,10 @@ int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage
return OK;
}
-/*
- * Restore current tabpage and window saved by switch_win(), if still valid.
- * When "no_display" is TRUE the display won't be affected, no redraw is
- * triggered.
- */
-void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
+// Restore current tabpage and window saved by switch_win(), if still valid.
+// When "no_display" is true the display won't be affected, no redraw is
+// triggered.
+void restore_win(win_T *save_curwin, tabpage_T *save_curtab, bool no_display)
{
if (save_curtab != NULL && valid_tabpage(save_curtab)) {
if (no_display) {
@@ -5608,7 +5620,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
m->match.rmm_maxcol = 0;
m->conceal_char = 0;
if (conceal_char != NULL) {
- m->conceal_char = (*mb_ptr2char)((const char_u *)conceal_char);
+ m->conceal_char = utf_ptr2char((const char_u *)conceal_char);
}
// Set up position matches