aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--cmake.deps/CMakeLists.txt4
-rw-r--r--runtime/lua/man.lua16
-rw-r--r--runtime/lua/vim/filetype.lua1
-rw-r--r--runtime/nvim.appdata.xml3
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/drawline.c13
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval.lua68
-rw-r--r--src/nvim/eval/vars.c2
-rw-r--r--src/nvim/file_search.c2
-rw-r--r--src/nvim/getchar.c2
-rw-r--r--src/nvim/main.c5
-rw-r--r--src/nvim/memline.c5
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/normal.c4
-rw-r--r--src/nvim/os/fs.c6
-rw-r--r--src/nvim/regexp_bt.c2
-rw-r--r--src/nvim/regexp_nfa.c2
-rw-r--r--src/nvim/screen.c11
-rw-r--r--src/nvim/sign.c2
-rw-r--r--src/nvim/sign_defs.h6
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/spellfile.c2
-rw-r--r--src/nvim/spellsuggest.c2
-rw-r--r--src/nvim/syntax.c2
-rw-r--r--src/nvim/testdir/test_filetype.vim1
-rw-r--r--src/nvim/testdir/test_visual.vim11
-rw-r--r--src/nvim/tui/tui.c5
-rw-r--r--src/nvim/ui_client.c29
-rw-r--r--src/nvim/version.c6
-rw-r--r--test/functional/api/extmark_spec.lua8
-rw-r--r--test/functional/plugin/man_spec.lua6
-rw-r--r--test/functional/terminal/tui_spec.lua6
-rw-r--r--test/functional/ui/statuscolumn_spec.lua21
35 files changed, 174 insertions, 91 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ca1e2caa7..9c0d999ab8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -397,10 +397,7 @@ if(BUSTED_PRG)
configure_file(
${CMAKE_SOURCE_DIR}/test/cmakeconfig/paths.lua.in
- ${CMAKE_BINARY_DIR}/test/cmakeconfig/paths.lua.gen)
- file(GENERATE
- OUTPUT ${CMAKE_BINARY_DIR}/test/cmakeconfig/paths.lua
- INPUT ${CMAKE_BINARY_DIR}/test/cmakeconfig/paths.lua.gen)
+ ${CMAKE_BINARY_DIR}/test/cmakeconfig/paths.lua)
add_custom_target(functionaltest
COMMAND ${CMAKE_COMMAND}
diff --git a/cmake.deps/CMakeLists.txt b/cmake.deps/CMakeLists.txt
index 2b906023a6..90ae91463d 100644
--- a/cmake.deps/CMakeLists.txt
+++ b/cmake.deps/CMakeLists.txt
@@ -194,8 +194,8 @@ set(TREESITTER_LUA_SHA256 930d0370dc15b66389869355c8e14305b9ba7aafd36edbfdb468c8
set(TREESITTER_VIM_URL https://github.com/vigoux/tree-sitter-viml/archive/55ff1b080c09edeced9b748cf4c16d0b49d17fb9.tar.gz)
set(TREESITTER_VIM_SHA256 1b1cd39e33c8fb02fa7fe3977e844883c2a8508a7edd621f2d21e39a9aeefa92)
-set(TREESITTER_HELP_URL https://github.com/neovim/tree-sitter-vimdoc/archive/ce20f13c3f12506185754888feaae3f2ad54c287.tar.gz)
-set(TREESITTER_HELP_SHA256 2b8b166438cce66064aab56a744430b1f44871f43e47f70b51246d14bb826609)
+set(TREESITTER_HELP_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v1.3.0.tar.gz)
+set(TREESITTER_HELP_SHA256 f33f6d49c7d71feb2fd68ef2b2684da150f9f8e486ad9726213631d673942331)
set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/eb970a83a107cbaba52e31588355c0b09b3a308a.tar.gz)
set(TREESITTER_SHA256 58063721182f182fb9ec5481794f2ba594e52d6c2497e0214570535054dfc78d)
diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua
index 732a4ab92e..0956022ac6 100644
--- a/runtime/lua/man.lua
+++ b/runtime/lua/man.lua
@@ -149,15 +149,21 @@ local function highlight_line(line, linenr)
if overstrike then
local last_hl = hls[#hls]
if char == prev_char then
- if char == '_' and attr == UNDERLINE and last_hl and last_hl.final == byte then
- -- This underscore is in the middle of an underlined word
- attr = UNDERLINE
+ if char == '_' and attr == ITALIC and last_hl and last_hl.final == byte then
+ -- This underscore is in the middle of an italic word
+ attr = ITALIC
else
attr = BOLD
end
elseif prev_char == '_' then
- -- char is underlined
- attr = UNDERLINE
+ -- Even though underline is strictly what this should be. <bs>_ was used by nroff to
+ -- indicate italics which wasn't possible on old typewriters so underline was used. Modern
+ -- terminals now support italics so lets use that now.
+ -- See:
+ -- - https://unix.stackexchange.com/questions/274658/purpose-of-ascii-text-with-overstriking-file-format/274795#274795
+ -- - https://cmd.inp.nsk.su/old/cmd2/manuals/unix/UNIX_Unleashed/ch08.htm
+ -- attr = UNDERLINE
+ attr = ITALIC
elseif prev_char == '+' and char == 'o' then
-- bullet (overstrike text '+^Ho')
attr = BOLD
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index d1a84fcecf..8144731b09 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -385,6 +385,7 @@ local extension = {
['m4gl'] = 'fgl',
['4gl'] = 'fgl',
['4gh'] = 'fgl',
+ fir = 'firrtl',
fish = 'fish',
focexec = 'focexec',
fex = 'focexec',
diff --git a/runtime/nvim.appdata.xml b/runtime/nvim.appdata.xml
index 7411a7190a..7d2ea49df4 100644
--- a/runtime/nvim.appdata.xml
+++ b/runtime/nvim.appdata.xml
@@ -26,9 +26,12 @@
</screenshots>
<releases>
+ <release date="2023-02-02" version="0.8.3"/>
<release date="2022-12-29" version="0.8.2"/>
<release date="2022-11-14" version="0.8.1"/>
<release date="2022-09-30" version="0.8.0"/>
+ <release date="2022-06-26" version="0.7.2"/>
+ <release date="2022-06-26" version="0.7.1"/>
<release date="2022-04-15" version="0.7.0"/>
<release date="2021-12-31" version="0.6.1"/>
<release date="2021-11-30" version="0.6.0"/>
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index f01edd1ad2..4c99191170 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -1392,6 +1392,7 @@ struct window_S {
int w_prev_fraction_row;
linenr_T w_nrwidth_line_count; // line count when ml_nrwidth_width was computed.
+ linenr_T w_statuscol_line_count; // line count when 'statuscolumn' width was computed.
int w_nrwidth_width; // nr of chars to print line count.
qf_info_T *w_llist; // Location list for this window
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index e24d86b353..01ff207c2b 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -412,7 +412,6 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i
bool use_cul = use_cursor_line_sign(wp, lnum);
int virtnum = row - startrow - filler_lines;
- set_vim_var_nr(VV_VIRTNUM, virtnum);
// When called the first time for line "lnum" set num_attr
if (stcp->num_attr == 0) {
stcp->num_attr = sign_num_attr ? sign_num_attr
@@ -437,6 +436,18 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i
}
stcp->sign_text[i] = NULL;
+ // When a buffer's line count has changed, make a best estimate for the full
+ // width of the status column by building with "w_nrwidth_line_count". Add
+ // potentially truncated width and rebuild before drawing anything.
+ if (wp->w_statuscol_line_count != wp->w_nrwidth_line_count) {
+ wp->w_statuscol_line_count = wp->w_nrwidth_line_count;
+ set_vim_var_nr(VV_VIRTNUM, 0);
+ build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, stcp->width,
+ ' ', stcp->text, &stcp->hlrec, stcp);
+ stcp->width += stcp->truncate;
+ }
+ set_vim_var_nr(VV_VIRTNUM, virtnum);
+
int width = build_statuscol_str(wp, lnum, relnum, stcp->width,
' ', stcp->text, &stcp->hlrec, stcp);
// Force a redraw in case of error or when truncated
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 095d73f53f..96df6a3044 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1483,7 +1483,7 @@ static void init_prompt(int cmdchar_todo)
}
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
coladvance(MAXCOL);
- changed_bytes(curbuf->b_ml.ml_line_count, 0);
+ inserted_bytes(curbuf->b_ml.ml_line_count, 0, 0, (colnr_T)strlen(prompt));
}
// Insert always starts after the prompt, allow editing text after it.
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index c17a44b990..9a5ab51c71 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -26,7 +26,7 @@ return {
acos={args=1, base=1, float_func="acos"}, -- WJMc
add={args=2, base=1},
['and']={args=2, base=1},
- api_info={},
+ api_info={fast=true},
append={args=2, base=2},
appendbufline={args=3, base=3},
argc={args={0, 1}},
@@ -64,14 +64,14 @@ return {
bufwinid={args=1, base=1},
bufwinnr={args=1, base=1},
byte2line={args=1, base=1},
- byteidx={args=2, base=1},
- byteidxcomp={args=2, base=1},
+ byteidx={args=2, base=1, fast=true},
+ byteidxcomp={args=2, base=1, fast=true},
call={args={2, 3}, base=1},
ceil={args=1, base=1, float_func="ceil"},
changenr={},
chanclose={args={1, 2}},
chansend={args=2},
- char2nr={args={1, 2}, base=1},
+ char2nr={args={1, 2}, base=1, fast=true},
charclass={args=1, base=1},
charcol={args={1, 2}, base=1},
charidx={args={2, 3}, base=1},
@@ -100,7 +100,7 @@ return {
deletebufline={args={2,3}, base=1},
dictwatcheradd={args=3},
dictwatcherdel={args=3},
- did_filetype={},
+ did_filetype={fast=true},
diff_filler={args=1, base=1},
diff_hlID={args=2, base=1},
digraph_get={args=1, base=1},
@@ -108,11 +108,11 @@ return {
digraph_set={args=2, base=1},
digraph_setlist={args=1, base=1},
empty={args=1, base=1},
- environ={},
- escape={args=2, base=1},
+ environ={fast=true},
+ escape={args=2, base=1, fast=true},
eval={args=1, base=1},
eventhandler={},
- executable={args=1, base=1},
+ executable={args=1, base=1, fast=true},
execute={args={1, 2}, base=1},
exepath={args=1, base=1},
exists={args=1, base=1},
@@ -122,8 +122,8 @@ return {
extend={args={2, 3}, base=1},
feedkeys={args={1, 2}, base=1},
file_readable={args=1, base=1, func='f_filereadable'}, -- obsolete
- filereadable={args=1, base=1},
- filewritable={args=1, base=1},
+ filereadable={args=1, base=1, fast=true},
+ filewritable={args=1, base=1, fast=true},
filter={args=2, base=1},
finddir={args={1, 3}, base=1},
findfile={args={1, 3}, base=1},
@@ -131,8 +131,8 @@ return {
float2nr={args=1, base=1},
floor={args=1, base=1, float_func="floor"},
fmod={args=2, base=1},
- fnameescape={args=1, base=1},
- fnamemodify={args=2, base=1},
+ fnameescape={args=1, base=1, fast=true},
+ fnamemodify={args=2, base=1, fast=true},
foldclosed={args=1, base=1},
foldclosedend={args=1, base=1},
foldlevel={args=1, base=1},
@@ -167,17 +167,17 @@ return {
getcwd={args={0, 2}, base=1},
getenv={args=1, base=1},
getfontname={args={0, 1}},
- getfperm={args=1, base=1},
- getfsize={args=1, base=1},
- getftime={args=1, base=1},
- getftype={args=1, base=1},
+ getfperm={args=1, base=1, fast=true},
+ getfsize={args=1, base=1, fast=true},
+ getftime={args=1, base=1, fast=true},
+ getftype={args=1, base=1, fast=true},
getjumplist={args={0, 2}, base=1},
getline={args={1, 2}, base=1},
getloclist={args={1, 2}},
getmarklist={args={0, 1}, base=1},
getmatches={args={0, 1}},
getmousepos={},
- getpid={},
+ getpid={fast=true},
getpos={args=1, base=1},
getqflist={args={0, 1}},
getreg={args={0, 3}, base=1},
@@ -208,7 +208,7 @@ return {
histnr={args=1, base=1},
hlID={args=1, base=1},
hlexists={args=1, base=1},
- hostname={},
+ hostname={fast=true},
iconv={args=3, base=1, fast=true},
indent={args=1, base=1},
index={args={2, 4}, base=1},
@@ -221,7 +221,7 @@ return {
insert={args={2, 3}, base=1},
interrupt={args=0},
invert={args=1, base=1},
- isdirectory={args=1, base=1},
+ isdirectory={args=1, base=1, fast=true},
isinf={args=1, base=1},
islocked={args=1, base=1},
isnan={args=1, base=1},
@@ -300,13 +300,13 @@ return {
reg_executing={},
reg_recording={},
reg_recorded={},
- reltime={args={0, 2}, base=1},
- reltimefloat={args=1, base=1},
- reltimestr={args=1, base=1},
+ reltime={args={0, 2}, base=1, fast=true},
+ reltimefloat={args=1, base=1, fast=true},
+ reltimestr={args=1, base=1, fast=true},
remove={args={2, 3}, base=1},
rename={args=2, base=1},
- ['repeat']={args=2, base=1},
- resolve={args=1, base=1},
+ ['repeat']={args=2, base=1, fast=true},
+ resolve={args=1, base=1, fast=true},
reverse={args=1, base=1},
round={args=1, base=1, float_func="round"},
rpcnotify={args=varargs(2)},
@@ -374,24 +374,24 @@ return {
split={args={1, 3}, base=1},
sqrt={args=1, base=1, float_func="sqrt"},
srand={args={0, 1}, base=1},
- stdpath={args=1},
+ stdpath={args=1, fast=true},
str2float={args=1, base=1},
str2list={args={1, 2}, base=1},
str2nr={args={1, 3}, base=1},
strcharlen={args=1, base=1},
- strcharpart={args={2, 3}, base=1},
+ strcharpart={args={2, 3}, base=1, fast=true},
strchars={args={1, 2}, base=1},
strdisplaywidth={args={1, 2}, base=1},
strftime={args={1, 2}, base=1},
strgetchar={args=2, base=1},
- stridx={args={2, 3}, base=1},
+ stridx={args={2, 3}, base=1, fast=true},
string={args=1, base=1},
strlen={args=1, base=1},
- strpart={args={2, 4}, base=1},
+ strpart={args={2, 4}, base=1, fast=true},
strptime={args=2, base=1},
strridx={args={2, 3}, base=1},
- strtrans={args=1, base=1},
- strwidth={args=1, base=1},
+ strtrans={args=1, base=1, fast=true},
+ strwidth={args=1, base=1, fast=true},
submatch={args={1, 2}, base=1},
substitute={args=4, base=1},
swapinfo={args=1, base=1},
@@ -419,12 +419,12 @@ return {
timer_start={args={2, 3}, base=1},
timer_stop={args=1, base=1},
timer_stopall={args=0},
- tolower={args=1, base=1},
- toupper={args=1, base=1},
+ tolower={args=1, base=1, fast=true},
+ toupper={args=1, base=1, fast=true},
tr={args=3, base=1},
trim={args={1, 3}, base=1},
trunc={args=1, base=1, float_func="trunc"},
- type={args=1, base=1},
+ type={args=1, base=1, fast=true},
undofile={args=1, base=1},
undotree={},
uniq={args={1, 3}, base=1},
@@ -447,7 +447,7 @@ return {
win_splitmove={args={2, 3}, base=1},
winbufnr={args=1, base=1},
wincol={},
- windowsversion={},
+ windowsversion={fast=true},
winheight={args=1, base=1},
winlayout={args={0, 1}, base=1},
winline={},
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index 3e593151fc..9ed245d6c4 100644
--- a/src/nvim/eval/vars.c
+++ b/src/nvim/eval/vars.c
@@ -1347,7 +1347,7 @@ void set_var_const(const char *name, const size_t name_len, typval_T *const tv,
// Make sure dict is valid
assert(dict != NULL);
- v = xmalloc(sizeof(dictitem_T) + strlen(varname));
+ v = xmalloc(offsetof(dictitem_T, di_key) + strlen(varname) + 1);
STRCPY(v->di_key, varname);
if (hash_add(ht, (char *)v->di_key) == FAIL) {
xfree(v);
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index e236f23895..a0435afd65 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1092,7 +1092,7 @@ static int ff_check_visited(ff_visited_T **visited_list, char *fname, char *wc_p
}
// New file/dir. Add it to the list of visited files/dirs.
- vp = xmalloc(sizeof(ff_visited_T) + strlen(ff_expand_buffer));
+ vp = xmalloc(offsetof(ff_visited_T, ffv_fname) + strlen(ff_expand_buffer) + 1);
if (!url) {
vp->file_id_valid = true;
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 51554fea22..8ed9381bca 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -252,7 +252,7 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle
} else {
len = (size_t)slen;
}
- buffblock_T *p = xmalloc(sizeof(buffblock_T) + len);
+ buffblock_T *p = xmalloc(offsetof(buffblock_T, b_str) + len + 1);
buf->bh_space = len - (size_t)slen;
xstrlcpy(p->b_str, s, (size_t)slen + 1);
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 8df82c710a..e26922bf8e 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -811,6 +811,11 @@ void preserve_exit(void)
really_exiting = true;
// Ignore SIGHUP while we are already exiting. #9274
signal_reject_deadly();
+
+ if (ui_client_channel_id) {
+ os_exit(1);
+ }
+
os_errmsg(IObuff);
os_errmsg("\n");
ui_flush();
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 10a8195e7a..b3fc64a68c 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -149,7 +149,7 @@ struct data_block {
#define DB_INDEX_MASK (~DB_MARKED)
#define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry
-#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) // size of data block header
+#define HEADER_SIZE (offsetof(DATA_BL, db_index)) // size of data block header
enum {
B0_FNAME_SIZE_ORG = 900, // what it was in older versions
@@ -2720,7 +2720,8 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
PTR_BL *pp = hp->bh_data;
pp->pb_id = PTR_ID;
pp->pb_count = 0;
- pp->pb_count_max = (uint16_t)((mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1);
+ pp->pb_count_max
+ = (uint16_t)((mfp->mf_page_size - offsetof(PTR_BL, pb_pointer)) / sizeof(PTR_EN));
return hp;
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 7f29b19031..3b3dfcd5b6 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -2514,7 +2514,7 @@ static void store_sb_text(char **sb_str, char *s, int attr, int *sb_col, int fin
}
if (s > *sb_str) {
- mp = xmalloc((sizeof(msgchunk_T) + (size_t)(s - *sb_str)));
+ mp = xmalloc(offsetof(msgchunk_T, sb_text) + (size_t)(s - *sb_str) + 1);
mp->sb_eol = (char)finish;
mp->sb_msg_col = *sb_col;
mp->sb_attr = attr;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 58a18ca5a8..b88cfb8926 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -5072,9 +5072,13 @@ static void nv_visual(cmdarg_T *cap)
curwin->w_curswant = MAXCOL;
coladvance(MAXCOL);
} else if (VIsual_mode == Ctrl_V) {
+ // Update curswant on the original line, that is where "col" is valid.
+ linenr_T lnum = curwin->w_cursor.lnum;
+ curwin->w_cursor.lnum = VIsual.lnum;
update_curswant_force();
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
curwin->w_curswant += resel_VIsual_vcol * (int)cap->count0 - 1;
+ curwin->w_cursor.lnum = lnum;
coladvance(curwin->w_curswant);
} else {
curwin->w_set_curswant = true;
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 302faa8140..6157341ec9 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -146,11 +146,7 @@ bool os_isdir(const char *name)
return false;
}
- if (!S_ISDIR(mode)) {
- return false;
- }
-
- return true;
+ return S_ISDIR(mode);
}
/// Check what `name` is:
diff --git a/src/nvim/regexp_bt.c b/src/nvim/regexp_bt.c
index 1b32447d77..af3d93f7c4 100644
--- a/src/nvim/regexp_bt.c
+++ b/src/nvim/regexp_bt.c
@@ -2862,7 +2862,7 @@ static regprog_T *bt_regcomp(uint8_t *expr, int re_flags)
}
// Allocate space.
- bt_regprog_T *r = xmalloc(sizeof(bt_regprog_T) + (size_t)regsize);
+ bt_regprog_T *r = xmalloc(offsetof(bt_regprog_T, program) + (size_t)regsize);
r->re_in_use = false;
// Second pass: emit code.
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 93b03f0632..ea59e7d464 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -7511,7 +7511,7 @@ static regprog_T *nfa_regcomp(uint8_t *expr, int re_flags)
post2nfa(postfix, post_ptr, true);
// allocate the regprog with space for the compiled regexp
- size_t prog_size = sizeof(nfa_regprog_T) + sizeof(nfa_state_T) * (size_t)(nstate - 1);
+ size_t prog_size = offsetof(nfa_regprog_T, state) + sizeof(nfa_state_T) * (size_t)nstate;
prog = xmalloc(prog_size);
state_ptr = prog->state;
prog->re_in_use = false;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ebff52cd69..05da6e0ef1 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -768,7 +768,6 @@ void comp_col(void)
/// Otherwise it depends on 'numberwidth' and the line count.
int number_width(win_T *wp)
{
- int n;
linenr_T lnum;
if (wp->w_p_rnu && !wp->w_p_nu) {
@@ -784,17 +783,13 @@ int number_width(win_T *wp)
}
wp->w_nrwidth_line_count = lnum;
- // make best estimate for 'statuscolumn'
+ // reset for 'statuscolumn'
if (*wp->w_p_stc != NUL) {
- char buf[MAXPATHL];
- wp->w_nrwidth_width = 0;
- n = build_statuscol_str(wp, lnum, 0, 0, NUL, buf, NULL, NULL);
- n = MAX(n, (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw);
- wp->w_nrwidth_width = MIN(n, MAX_NUMBERWIDTH);
+ wp->w_nrwidth_width = (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw;
return wp->w_nrwidth_width;
}
- n = 0;
+ int n = 0;
do {
lnum /= 10;
n++;
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index d0c093d93a..00e282b76e 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -103,7 +103,7 @@ static signgroup_T *sign_group_ref(const char *groupname)
hi = hash_lookup(&sg_table, (char *)groupname, strlen(groupname), hash);
if (HASHITEM_EMPTY(hi)) {
// new group
- group = xmalloc(sizeof(signgroup_T) + strlen(groupname));
+ group = xmalloc(offsetof(signgroup_T, sg_name) + strlen(groupname) + 1);
STRCPY(group->sg_name, groupname);
group->sg_refcount = 1;
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index 16e783aab7..7aa06ce48a 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -10,9 +10,9 @@
// Sign group
typedef struct signgroup_S {
- uint16_t sg_refcount; // number of signs in this group
- int sg_next_sign_id; // next sign id for this group
- char sg_name[1]; // sign group name
+ int sg_next_sign_id; ///< next sign id for this group
+ uint16_t sg_refcount; ///< number of signs in this group
+ char sg_name[1]; ///< sign group name, actually longer
} signgroup_T;
// Macros to get the sign group structure from the group name
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 8e18be5bd1..2204cda169 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1745,7 +1745,7 @@ void count_common_word(slang_T *lp, char *word, int len, uint8_t count)
const size_t p_len = strlen(p);
hashitem_T *hi = hash_lookup(&lp->sl_wordcount, (const char *)p, p_len, hash);
if (HASHITEM_EMPTY(hi)) {
- wc = xmalloc(sizeof(wordcount_T) + p_len);
+ wc = xmalloc(offsetof(wordcount_T, wc_word) + p_len + 1);
memcpy(wc->wc_word, p, p_len + 1);
wc->wc_count = count;
hash_add_item(&lp->sl_wordcount, hi, (char *)wc->wc_word, hash);
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 44414ca1a5..7b124ae6b6 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -3855,7 +3855,7 @@ static void *getroom(spellinfo_T *spin, size_t len, bool align)
if (bl == NULL || (size_t)bl->sb_used + len > SBLOCKSIZE) {
// Allocate a block of memory. It is not freed until much later.
- bl = xcalloc(1, (sizeof(sblock_T) + SBLOCKSIZE));
+ bl = xcalloc(1, offsetof(sblock_T, sb_data) + SBLOCKSIZE + 1);
bl->sb_next = spin->si_blocks;
spin->si_blocks = bl;
bl->sb_used = 0;
diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c
index 22add418a0..54b6f552b5 100644
--- a/src/nvim/spellsuggest.c
+++ b/src/nvim/spellsuggest.c
@@ -2828,7 +2828,7 @@ static void add_sound_suggest(suginfo_T *su, char *goodword, int score, langp_T
hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len,
hash);
if (HASHITEM_EMPTY(hi)) {
- sft = xmalloc(sizeof(sftword_T) + goodword_len);
+ sft = xmalloc(offsetof(sftword_T, sft_word) + goodword_len + 1);
sft->sft_score = (int16_t)score;
memcpy(sft->sft_word, goodword, goodword_len + 1);
hash_add_item(&slang->sl_sounddone, hi, (char *)sft->sft_word, hash);
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 05c570e52f..49b63ad324 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -3736,7 +3736,7 @@ static void add_keyword(char *const name, const int id, const int flags,
sizeof(name_folded))
: name;
- keyentry_T *const kp = xmalloc(sizeof(keyentry_T) + strlen(name_ic));
+ keyentry_T *const kp = xmalloc(offsetof(keyentry_T, keyword) + strlen(name_ic) + 1);
STRCPY(kp->keyword, name_ic);
kp->k_syn.id = (int16_t)id;
kp->k_syn.inc_tag = current_syn_inc_tag;
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 88c25ab115..7b5ec22dd4 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -199,6 +199,7 @@ let s:filename_checks = {
\ 'fennel': ['file.fnl'],
\ 'fetchmail': ['.fetchmailrc'],
\ 'fgl': ['file.4gl', 'file.4gh', 'file.m4gl'],
+ \ 'firrtl': ['file.fir'],
\ 'fish': ['file.fish'],
\ 'focexec': ['file.fex', 'file.focexec'],
\ 'form': ['file.frm'],
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index 14d62089cf..1e9629c2c4 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -1319,6 +1319,17 @@ func Test_visual_block_with_substitute()
endfunc
func Test_visual_reselect_with_count()
+ enew
+ call setline(1, ['aaaaaa', '✗ bbbb', '✗ bbbb'])
+ exe "normal! 2Gw\<C-V>jed"
+ exe "normal! gg0lP"
+ call assert_equal(['abbbbaaaaa', '✗bbbb ', '✗ '], getline(1, '$'))
+
+ exe "normal! 1vr."
+ call assert_equal(['a....aaaaa', '✗.... ', '✗ '], getline(1, '$'))
+
+ bwipe!
+
" this was causing an illegal memory access
let lines =<< trim END
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index a50e44f7a3..f760e99262 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -458,6 +458,9 @@ static void tui_terminal_stop(TUIData *tui)
void tui_stop(TUIData *tui)
{
+ if (tui->stopped) {
+ return;
+ }
tui_terminal_stop(tui);
stream_set_blocking(tui->input.in_fd, true); // normalize stream (#2598)
tinput_destroy(&tui->input);
@@ -1344,6 +1347,7 @@ static void show_verbose_terminfo(TUIData *tui)
static void suspend_event(void **argv)
{
TUIData *tui = argv[0];
+ ui_client_detach();
bool enable_mouse = tui->mouse_enabled;
tui_terminal_stop(tui);
stream_set_blocking(tui->input.in_fd, true); // normalize stream (#2598)
@@ -1356,6 +1360,7 @@ static void suspend_event(void **argv)
tui_mouse_on(tui);
}
stream_set_blocking(tui->input.in_fd, false); // libuv expects this
+ ui_client_attach(tui->width, tui->height, tui->term);
}
#endif
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index 378c0e4831..b5c8dff412 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -23,6 +23,7 @@
#include "nvim/ui_client.h"
static TUIData *tui = NULL;
+static bool ui_client_is_remote = false;
// uncrustify:off
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -66,13 +67,8 @@ uint64_t ui_client_start_server(int argc, char **argv)
return channel->id;
}
-void ui_client_run(bool remote_ui)
- FUNC_ATTR_NORETURN
+void ui_client_attach(int width, int height, char *term)
{
- int width, height;
- char *term;
- tui = tui_start(&width, &height, &term);
-
MAXSIZE_TEMP_ARRAY(args, 3);
ADD_C(args, INTEGER_OBJ(width));
ADD_C(args, INTEGER_OBJ(height));
@@ -82,14 +78,14 @@ void ui_client_run(bool remote_ui)
PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true));
PUT_C(opts, "ext_termcolors", BOOLEAN_OBJ(true));
if (term) {
- PUT(opts, "term_name", STRING_OBJ(cstr_to_string(term)));
+ PUT_C(opts, "term_name", STRING_OBJ(cstr_as_string(term)));
}
if (ui_client_bg_response != kNone) {
bool is_dark = (ui_client_bg_response == kTrue);
PUT_C(opts, "term_background", STRING_OBJ(cstr_as_string(is_dark ? "dark" : "light")));
}
PUT_C(opts, "term_colors", INTEGER_OBJ(t_colors));
- if (!remote_ui) {
+ if (!ui_client_is_remote) {
PUT_C(opts, "stdin_tty", BOOLEAN_OBJ(stdin_isatty));
PUT_C(opts, "stdout_tty", BOOLEAN_OBJ(stdout_isatty));
if (ui_client_forward_stdin) {
@@ -100,6 +96,23 @@ void ui_client_run(bool remote_ui)
rpc_send_event(ui_client_channel_id, "nvim_ui_attach", args);
ui_client_attached = true;
+}
+
+void ui_client_detach(void)
+{
+ rpc_send_event(ui_client_channel_id, "nvim_ui_detach", (Array)ARRAY_DICT_INIT);
+ ui_client_attached = false;
+}
+
+void ui_client_run(bool remote_ui)
+ FUNC_ATTR_NORETURN
+{
+ ui_client_is_remote = remote_ui;
+ int width, height;
+ char *term;
+ tui = tui_start(&width, &height, &term);
+
+ ui_client_attach(width, height, term);
// os_exit() will be invoked when the client channel detaches
while (true) {
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 11f1d6695e..3324ac2a94 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -795,7 +795,7 @@ static const int included_patches[] = {
1702,
1701,
// 1700,
- // 1699,
+ 1699,
1698,
1697,
1696,
@@ -1361,7 +1361,7 @@ static const int included_patches[] = {
// 1136,
1135,
1134,
- // 1133,
+ 1133,
1132,
1131,
1130,
@@ -1674,7 +1674,7 @@ static const int included_patches[] = {
823,
822,
821,
- // 820,
+ 820,
819,
818,
817,
diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua
index 00f5b25b8a..9902826c72 100644
--- a/test/functional/api/extmark_spec.lua
+++ b/test/functional/api/extmark_spec.lua
@@ -1454,6 +1454,14 @@ describe('API/extmarks', function()
}} }, get_extmarks(ns, 0, -1, {details=true}))
end)
+ it('in prompt buffer', function()
+ feed('dd')
+ local id = set_extmark(ns, marks[1], 0, 0, {})
+ curbufmeths.set_option('buftype', 'prompt')
+ feed('i<esc>')
+ eq({{id, 0, 2}}, get_extmarks(ns, 0, -1))
+ end)
+
it('can get details', function()
set_extmark(ns, marks[1], 0, 0, {
end_col = 0,
diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua
index c6c7d2b03d..58da059be6 100644
--- a/test/functional/plugin/man_spec.lua
+++ b/test/functional/plugin/man_spec.lua
@@ -59,7 +59,7 @@ describe(':Man', function()
screen:expect([[
^this {b:is} {b:a} test |
- with {u:overstruck} text |
+ with {i:overstruck} text |
{eob:~ }|
{eob:~ }|
|
@@ -98,7 +98,7 @@ describe(':Man', function()
screen:expect([[
^this {b:is} {b:あ} test |
- with {u:överstrũck} te{i:xt¶} |
+ with {i:överstrũck} te{i:xt¶} |
{eob:~ }|
{eob:~ }|
|
@@ -115,7 +115,7 @@ describe(':Man', function()
screen:expect([[
{b:^_begins} |
{b:mid_dle} |
- {u:mid_dle} |
+ {i:mid_dle} |
{eob:~ }|
|
]])
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index b28728057f..1d9e7b8e11 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -14,6 +14,7 @@ local clear = helpers.clear
local command = helpers.command
local dedent = helpers.dedent
local exec = helpers.exec
+local exec_lua = helpers.exec_lua
local testprg = helpers.testprg
local retry = helpers.retry
local nvim_prog = helpers.nvim_prog
@@ -1506,6 +1507,11 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]]}
end)
+
+ it('no assert failure on deadly signal #21896', function()
+ exec_lua([[vim.loop.kill(vim.fn.jobpid(vim.bo.channel), 'sigterm')]])
+ screen:expect({any = '%[Process exited 1%]'})
+ end)
end)
describe('TUI', function()
diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua
index ae3b95fb0f..3233e6cd19 100644
--- a/test/functional/ui/statuscolumn_spec.lua
+++ b/test/functional/ui/statuscolumn_spec.lua
@@ -439,7 +439,7 @@ describe('statuscolumn', function()
vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {
virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} })
]])
- feed('lh') -- force update wcol/row
+ feed('lh') -- force update cursor row
screen:expect([[
4 aaaaa |
5 aaaaa |
@@ -458,5 +458,24 @@ describe('statuscolumn', function()
]])
command('set stc=') -- also for the default sign column
screen:expect_unchanged()
+ -- 'statuscolumn' is not too wide with custom (bogus) fold column
+ command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]])
+ feed('Gd10Ggg<C-l>')
+ screen:expect([[
+ 1 ^aaaaa |
+ 2 aaaaa |
+ 3 aaaaa |
+ 4 aaaaa |
+ 5 aaaaa |
+ 6 aaaaa |
+ 7 aaaaa |
+ virt |
+ ---------8 aaaaa |
+ virt |
+ ---------9 aaaaa |
+ ~ |
+ ~ |
+ |
+ ]])
end)
end)