aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/provider/clipboard.vim12
-rw-r--r--scripts/genvimvim.lua2
-rw-r--r--src/nvim/ascii.h2
-rw-r--r--src/nvim/buffer.c6
-rw-r--r--src/nvim/ops.c5
-rw-r--r--src/nvim/testdir/test_visual.vim22
-rw-r--r--src/nvim/tui/tui.c31
-rw-r--r--src/nvim/window.c37
-rw-r--r--test/functional/legacy/memory_usage_spec.lua32
-rw-r--r--test/functional/provider/clipboard_spec.lua14
-rw-r--r--third-party/CMakeLists.txt5
11 files changed, 133 insertions, 35 deletions
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index 07f37d604f..dea79f21f0 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -156,7 +156,14 @@ function! s:clipboard.get(reg) abort
elseif s:selections[a:reg].owner > 0
return s:selections[a:reg].data
end
- return s:try_cmd(s:paste[a:reg])
+
+ let clipboard_data = s:try_cmd(s:paste[a:reg])
+ if match(&clipboard, '\v(unnamed|unnamedplus)') >= 0 && get(s:selections[a:reg].data, 0, []) == clipboard_data
+ " When system clipboard return is same as our cache return the cache
+ " as it contains regtype information
+ return s:selections[a:reg].data
+ end
+ return clipboard_data
endfunction
function! s:clipboard.set(lines, regtype, reg) abort
@@ -175,6 +182,9 @@ function! s:clipboard.set(lines, regtype, reg) abort
if s:cache_enabled == 0
call s:try_cmd(s:copy[a:reg], a:lines)
+ "Cache it anyway we can compare it later to get regtype of the yank
+ let s:selections[a:reg] = copy(s:selection)
+ let s:selections[a:reg].data = [a:lines, a:regtype]
return 0
end
diff --git a/scripts/genvimvim.lua b/scripts/genvimvim.lua
index ccd5489fdc..2c3701bf0c 100644
--- a/scripts/genvimvim.lua
+++ b/scripts/genvimvim.lua
@@ -123,7 +123,7 @@ end
w('\n\nsyn case match')
local vimfun_start = 'syn keyword vimFuncName contained '
w('\n\n' .. vimfun_start)
-funcs = mpack.unpack(io.open(funcs_file):read("*all"))
+funcs = mpack.unpack(io.open(funcs_file, 'rb'):read("*all"))
local started = 0
for name, def in pairs(funcs) do
if name then
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index 7e4dee3d34..f41068ea70 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -31,9 +31,7 @@
#define CSI 0x9b // Control Sequence Introducer
#define CSI_STR "\233"
#define DCS 0x90 // Device Control String
-#define DCS_STR "\033P"
#define STERM 0x9c // String Terminator
-#define STERM_STR "\033\\"
#define POUND 0xA3
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 0b72dd1885..f1f32076bf 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -840,11 +840,7 @@ static void clear_wininfo(buf_T *buf)
while (buf->b_wininfo != NULL) {
wip = buf->b_wininfo;
buf->b_wininfo = wip->wi_next;
- if (wip->wi_optset) {
- clear_winopt(&wip->wi_opt);
- deleteFoldRecurse(buf, &wip->wi_folds);
- }
- xfree(wip);
+ free_wininfo(wip, buf);
}
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 04a8fc8499..855f63ba7b 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -2719,10 +2719,13 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
// Copy a block range into a register.
// If "exclude_trailing_space" is set, do not copy trailing whitespaces.
-static void yank_copy_line(yankreg_T *reg, const struct block_def *bd,
+static void yank_copy_line(yankreg_T *reg, struct block_def *bd,
size_t y_idx, bool exclude_trailing_space)
FUNC_ATTR_NONNULL_ALL
{
+ if (exclude_trailing_space) {
+ bd->endspaces = 0;
+ }
int size = bd->startspaces + bd->endspaces + bd->textlen;
assert(size >= 0);
char_u *pnew = xmallocz((size_t)size);
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
index a40b0236e0..b7c5717bd2 100644
--- a/src/nvim/testdir/test_visual.vim
+++ b/src/nvim/testdir/test_visual.vim
@@ -1,5 +1,8 @@
" Tests for various Visual modes.
+source shared.vim
+source check.vim
+
func Test_block_shift_multibyte()
" Uses double-wide character.
split
@@ -1060,5 +1063,24 @@ func Test_visual_put_in_block_using_zy_and_zp()
bwipe!
endfunc
+func Test_visual_put_blockedit_zy_and_zp()
+ new
+
+ call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
+ exe "normal! gg0\<c-v>2j$zy"
+ norm! 5gg0zP
+ call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
+ "
+ " now with blockmode editing
+ sil %d
+ :set ve=block
+ call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
+ exe "normal! gg0\<c-v>2j$zy"
+ norm! 5gg0zP
+ call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
+ set ve&vim
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index fd83681aed..6e885279a9 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -52,21 +52,18 @@
#define OUTBUF_SIZE 0xffff
#define TOO_MANY_EVENTS 1000000
-#define STARTS_WITH(str, prefix) (strlen(str) >= (sizeof(prefix) - 1) \
- && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
-#define TMUX_WRAP(is_tmux, seq) ((is_tmux) \
- ? DCS_STR "tmux;\x1b" seq STERM_STR : seq)
-#define SCREEN_TMUX_WRAP(is_screen, is_tmux, seq) \
- ((is_screen) \
- ? DCS_STR seq STERM_STR : (is_tmux) \
- ? DCS_STR "tmux;\x1b" seq STERM_STR : seq)
+#define STARTS_WITH(str, prefix) \
+ (strlen(str) >= (sizeof(prefix) - 1) \
+ && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
+#define TMUX_WRAP(is_tmux, seq) \
+ ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
#define LINUXSET0C "\x1b[?0c"
#define LINUXSET1C "\x1b[?1c"
#ifdef NVIM_UNIBI_HAS_VAR_FROM
#define UNIBI_SET_NUM_VAR(var, num) \
do { \
- (var) = unibi_var_from_num((num)); \
+ (var) = unibi_var_from_num((num)); \
} while (0)
#else
#define UNIBI_SET_NUM_VAR(var, num) (var).i = (num);
@@ -301,12 +298,6 @@ static void terminfo_start(UI *ui)
data->invis, sizeof data->invis);
// Set 't_Co' from the result of unibilium & fix_terminfo.
t_colors = unibi_get_num(data->ut, unibi_max_colors);
- // Ask the terminal to send us the background color.
- // If get_bg is sent at the same time after enter_ca_mode, tmux will not send
- // get_bg to the host terminal. To avoid this, send get_bg before
- // enter_ca_mode.
- data->input.waiting_for_bg_response = 5;
- unibi_out_ext(ui, data->unibi_ext.get_bg);
// Enter alternate screen, save title, and clear.
// NOTE: Do this *before* changing terminal settings. #6433
unibi_out(ui, unibi_enter_ca_mode);
@@ -314,6 +305,9 @@ static void terminfo_start(UI *ui)
unibi_out_ext(ui, data->unibi_ext.save_title);
unibi_out(ui, unibi_keypad_xmit);
unibi_out(ui, unibi_clear_screen);
+ // Ask the terminal to send us the background color.
+ data->input.waiting_for_bg_response = 5;
+ unibi_out_ext(ui, data->unibi_ext.get_bg);
// Enable bracketed paste
unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
@@ -335,7 +329,6 @@ static void terminfo_start(UI *ui)
uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
uv_pipe_open(&data->output_handle.pipe, data->out_fd);
}
-
flush_buf(ui);
}
@@ -1780,10 +1773,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
#define XTERM_SETAB_16 \
"\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m"
- data->unibi_ext.get_bg =
- (int)unibi_add_ext_str(ut, "ext.get_bg",
- SCREEN_TMUX_WRAP((screen && !tmux), tmux,
- "\x1b]11;?\x07"));
+ data->unibi_ext.get_bg = (int)unibi_add_ext_str(ut, "ext.get_bg",
+ "\x1b]11;?\x07");
// Terminals with 256-colour SGR support despite what terminfo says.
if (unibi_get_num(ut, unibi_max_colors) < 256) {
diff --git a/src/nvim/window.c b/src/nvim/window.c
index aea60fe24c..d051e8e467 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4597,6 +4597,18 @@ static win_T *win_alloc(win_T *after, int hidden)
}
+// Free one wininfo_T.
+void
+free_wininfo(wininfo_T *wip, buf_T *bp)
+{
+ if (wip->wi_optset) {
+ clear_winopt(&wip->wi_opt);
+ deleteFoldRecurse(bp, &wip->wi_folds);
+ }
+ xfree(wip);
+}
+
+
/*
* Remove window 'wp' from the window list and free the structure.
*/
@@ -4647,9 +4659,30 @@ win_free (
/* Remove the window from the b_wininfo lists, it may happen that the
* freed memory is re-used for another window. */
FOR_ALL_BUFFERS(buf) {
- for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
- if (wip->wi_win == wp)
+ for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) {
+ if (wip->wi_win == wp) {
+ wininfo_T *wip2;
+
+ // If there already is an entry with "wi_win" set to NULL it
+ // must be removed, it would never be used.
+ for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) {
+ if (wip2->wi_win == NULL) {
+ if (wip2->wi_next != NULL) {
+ wip2->wi_next->wi_prev = wip2->wi_prev;
+ }
+ if (wip2->wi_prev == NULL) {
+ buf->b_wininfo = wip2->wi_next;
+ } else {
+ wip2->wi_prev->wi_next = wip2->wi_next;
+ }
+ free_wininfo(wip2, buf);
+ break;
+ }
+ }
+
wip->wi_win = NULL;
+ }
+ }
}
clear_matches(wp);
diff --git a/test/functional/legacy/memory_usage_spec.lua b/test/functional/legacy/memory_usage_spec.lua
index 97ac96804e..0f2d77093a 100644
--- a/test/functional/legacy/memory_usage_spec.lua
+++ b/test/functional/legacy/memory_usage_spec.lua
@@ -166,4 +166,36 @@ describe('memory usage', function()
check_result({before=before, after=after, last=last},
pcall(ok, last.last < upper))
end)
+
+ it('releases memory when closing windows when folds exist', function()
+ local pid = eval('getpid()')
+ source([[
+ new
+ " Insert lines
+ call nvim_buf_set_lines(0, 0, 0, v:false, repeat([''], 999))
+ " Create folds
+ normal! gg
+ for _ in range(500)
+ normal! zfjj
+ endfor
+ ]])
+ poke_eventloop()
+ local before = monitor_memory_usage(pid)
+ source([[
+ " Split and close window multiple times
+ for _ in range(1000)
+ split
+ close
+ endfor
+ ]])
+ poke_eventloop()
+ local after = monitor_memory_usage(pid)
+ source('bwipe!')
+ poke_eventloop()
+ -- Allow for an increase of 5% in memory usage, which accommodates minor fluctuation,
+ -- but is small enough that if memory were not released (prior to PR #14884), the test
+ -- would fail.
+ local upper = before.last * 1.05
+ check_result({before=before, after=after}, pcall(ok, after.last <= upper))
+ end)
end)
diff --git a/test/functional/provider/clipboard_spec.lua b/test/functional/provider/clipboard_spec.lua
index 2c681eb9d8..e5e21f11a6 100644
--- a/test/functional/provider/clipboard_spec.lua
+++ b/test/functional/provider/clipboard_spec.lua
@@ -506,6 +506,20 @@ describe('clipboard (with fake clipboard.vim)', function()
feed('p')
eq('textstar', meths.get_current_line())
end)
+
+ it('Block paste works currectly', function()
+ insert([[
+ aabbcc
+ ddeeff
+ ]])
+ feed('gg^<C-v>') -- Goto start of top line enter visual block mode
+ feed('3ljy^k') -- yank 4x2 block & goto initial location
+ feed('P') -- Paste it infront
+ expect([[
+ aabbaabbcc
+ ddeeddeeff
+ ]])
+ end)
end)
describe('clipboard=unnamedplus', function()
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index f9da7c497a..e8999bf1ed 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -209,9 +209,8 @@ set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc891
set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/5aa0bbb.tar.gz)
set(TREESITTER_C_SHA256 a5dcb37460d83002dfae7f9a208170ddbc9a047f231b9d6b75da7d36d707db2f)
-# This is a bit after 0.19.5 because it fixes issues with queries
-set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/6ed42747a4e0faee9b65edbbacc86ed0caeae05c.zip)
-set(TREESITTER_SHA256 07b8d090ae856d4ea8a494c08900271545d44af2558278a27693f9a47d9e75e3)
+set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.20.0.tar.gz)
+set(TREESITTER_SHA256 4a8070b9de17c3b8096181fe8530320ab3e8cca685d8bee6a3e8d164b5fb47da)
if(USE_BUNDLED_UNIBILIUM)
include(BuildUnibilium)