diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/buffer.c | 18 | ||||
-rw-r--r-- | src/nvim/api/ui_events.in.h | 2 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 6 | ||||
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 8 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 10 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 15 | ||||
-rw-r--r-- | src/nvim/screen.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_perl.vim | 225 | ||||
-rw-r--r-- | src/nvim/testdir/test_window_cmd.vim | 42 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 40 | ||||
-rw-r--r-- | src/nvim/ui_bridge.c | 1 | ||||
-rw-r--r-- | src/nvim/version.c | 2 |
13 files changed, 356 insertions, 16 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index cc9dd51cf6..5290011325 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -1535,17 +1535,17 @@ Boolean nvim_buf_del_extmark(Buffer buffer, /// like signs and marks do. /// /// Namespaces are used for batch deletion/updating of a set of highlights. To -/// create a namespace, use |nvim_create_namespace| which returns a namespace +/// create a namespace, use |nvim_create_namespace()| which returns a namespace /// id. Pass it in to this function as `ns_id` to add highlights to the /// namespace. All highlights in the same namespace can then be cleared with -/// single call to |nvim_buf_clear_namespace|. If the highlight never will be +/// single call to |nvim_buf_clear_namespace()|. If the highlight never will be /// deleted by an API call, pass `ns_id = -1`. /// /// As a shorthand, `ns_id = 0` can be used to create a new namespace for the /// highlight, the allocated id is then returned. If `hl_group` is the empty /// string no highlight is added, but a new `ns_id` is still returned. This is /// supported for backwards compatibility, new code should use -/// |nvim_create_namespace| to create a new empty namespace. +/// |nvim_create_namespace()| to create a new empty namespace. /// /// @param buffer Buffer handle, or 0 for current buffer /// @param ns_id namespace to use or -1 for ungrouped highlight @@ -1647,7 +1647,7 @@ void nvim_buf_clear_namespace(Buffer buffer, /// Clears highlights and virtual text from namespace and range of lines /// -/// @deprecated use |nvim_buf_clear_namespace|. +/// @deprecated use |nvim_buf_clear_namespace()|. /// /// @param buffer Buffer handle, or 0 for current buffer /// @param ns_id Namespace to clear, or -1 to clear all. @@ -1711,11 +1711,11 @@ free_exit: /// begin one cell (|lcs-eol| or space) after the ordinary text. /// /// Namespaces are used to support batch deletion/updating of virtual text. -/// To create a namespace, use |nvim_create_namespace|. Virtual text is -/// cleared using |nvim_buf_clear_namespace|. The same `ns_id` can be used for -/// both virtual text and highlights added by |nvim_buf_add_highlight|, both -/// can then be cleared with a single call to |nvim_buf_clear_namespace|. If the -/// virtual text never will be cleared by an API call, pass `ns_id = -1`. +/// To create a namespace, use |nvim_create_namespace()|. Virtual text is +/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for +/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both +/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If +/// the virtual text never will be cleared by an API call, pass `ns_id = -1`. /// /// As a shorthand, `ns_id = 0` can be used to create a new namespace for the /// virtual text, the allocated id is then returned. diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index ab31db39e9..ef5e90bf5c 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -36,6 +36,8 @@ void set_title(String title) FUNC_API_SINCE(3); void set_icon(String icon) FUNC_API_SINCE(3); +void screenshot(String path) + FUNC_API_SINCE(7) FUNC_API_REMOTE_IMPL; void option_set(String name, Object value) FUNC_API_SINCE(4) FUNC_API_BRIDGE_IMPL; // Stop event is not exported as such, represented by EOF in the msgpack stream. diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index fbd6511161..632f55f49a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2627,3 +2627,9 @@ void nvim__put_attr(Integer id, Integer start_row, Integer start_col, decorations_add_luahl_attr(attr, (int)start_row, (colnr_T)start_col, (int)end_row, (colnr_T)end_col); } + +void nvim__screenshot(String path) + FUNC_API_FAST +{ + ui_call_screenshot(path); +} diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index be16ddd7f6..372c950825 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -256,6 +256,7 @@ return { py3eval={args=1}, pyeval={args=1}, pyxeval={args=1}, + perleval={args=1}, range={args={1, 3}}, readdir={args={1, 2}}, readfile={args={1, 3}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index ac560124bf..f4d9db53c4 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6374,6 +6374,14 @@ static void f_pyxeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +/// +/// "perleval()" function +/// +static void f_perleval(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + script_host_eval("perl", argvars, rettv); +} + /* * "range()" function */ diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 252af409c0..a01f92df27 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1927,13 +1927,19 @@ return { command='perl', flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN, RESTRICT), addr_type=ADDR_LINES, - func='ex_script_ni', + func='ex_perl', }, { command='perldo', flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, RESTRICT), addr_type=ADDR_LINES, - func='ex_ni', + func='ex_perldo', + }, + { + command='perlfile', + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, RESTRICT), + addr_type=ADDR_LINES, + func='ex_perlfile', }, { command='pedit', diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 636fc96bde..3e169f7a4e 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -935,6 +935,21 @@ void ex_pydo3(exarg_T *eap) script_host_do_range("python3", eap); } +void ex_perl(exarg_T *eap) +{ + script_host_execute("perl", eap); +} + +void ex_perlfile(exarg_T *eap) +{ + script_host_execute_file("perl", eap); +} + +void ex_perldo(exarg_T *eap) +{ + script_host_do_range("perl", eap); +} + // Command line expansion for :profile. static enum { PEXP_SUBCMD, ///< expand :profile sub-commands diff --git a/src/nvim/screen.c b/src/nvim/screen.c index c68a90d6e3..fde6b1ceeb 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -6211,7 +6211,7 @@ void win_grid_alloc(win_T *wp) || grid->Rows != rows || grid->Columns != cols) { if (want_allocation) { - grid_alloc(grid, rows, cols, wp->w_grid.valid, wp->w_grid.valid); + grid_alloc(grid, rows, cols, wp->w_grid.valid, false); grid->valid = true; } else { // Single grid mode, all rendering will be redirected to default_grid. diff --git a/src/nvim/testdir/test_perl.vim b/src/nvim/testdir/test_perl.vim new file mode 100644 index 0000000000..2343f389fa --- /dev/null +++ b/src/nvim/testdir/test_perl.vim @@ -0,0 +1,225 @@ +" Tests for Perl interface + +if !has('perl') || has('win32') + finish +endif + +perl $SIG{__WARN__} = sub { die "Unexpected warnings from perl: @_" }; + +func Test_change_buffer() + call setline(line('$'), ['1 line 1']) + perl VIM::DoCommand("normal /^1\n") + perl $curline = VIM::Eval("line('.')") + perl $curbuf->Set($curline, "1 changed line 1") + call assert_equal('1 changed line 1', getline('$')) +endfunc + +func Test_evaluate_list() + call setline(line('$'), ['2 line 2']) + perl VIM::DoCommand("normal /^2\n") + perl $curline = VIM::Eval("line('.')") + let l = ["abc", "def"] + perl << EOF + $l = VIM::Eval("l"); + $curbuf->Append($curline, $l); +EOF +endfunc + +funct Test_VIM_Blob() + call assert_equal('0z', perleval('VIM::Blob("")')) + "call assert_equal('0z31326162', 'VIM::Blob("12ab")'->perleval()) + call assert_equal('0z00010203', perleval('VIM::Blob("\x00\x01\x02\x03")')) + call assert_equal('0z8081FEFF', perleval('VIM::Blob("\x80\x81\xfe\xff")')) +endfunc + +func Test_buffer_Delete() + new + call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) + perl $curbuf->Delete(7) + perl $curbuf->Delete(2, 5) + perl $curbuf->Delete(10) + call assert_equal(['a', 'f', 'h'], getline(1, '$')) + bwipe! +endfunc + +func Test_buffer_Append() + new + perl $curbuf->Append(1, '1') + perl $curbuf->Append(2, '2', '3', '4') + call assert_equal(['', '1', '2', '3', '4'], getline(1, '$')) + perl @l = ('5' ..'7') + perl $curbuf->Append(0, @l) + call assert_equal(['5', '6', '7', '', '1', '2', '3', '4'], getline(1, '$')) + bwipe! +endfunc + +func Test_buffer_Set() + new + call setline(1, ['1', '2', '3', '4', '5']) + perl $curbuf->Set(2, 'a', 'b', 'c') + perl $curbuf->Set(4, 'A', 'B', 'C') + call assert_equal(['1', 'a', 'b', 'A', 'B'], getline(1, '$')) + bwipe! +endfunc + +func Test_buffer_Get() + new + call setline(1, ['1', '2', '3', '4']) + call assert_equal('2:3', perleval('join(":", $curbuf->Get(2, 3))')) + bwipe! +endfunc + +func Test_buffer_Count() + new + call setline(1, ['a', 'b', 'c']) + call assert_equal(3, perleval('$curbuf->Count()')) + bwipe! +endfunc + +func Test_buffer_Name() + new + call assert_equal('', perleval('$curbuf->Name()')) + bwipe! + new Xfoo + call assert_equal('Xfoo', perleval('$curbuf->Name()')) + bwipe! +endfunc + +func Test_buffer_Number() + call assert_equal(bufnr('%'), perleval('$curbuf->Number()')) +endfunc + +func Test_window_Cursor() + new + call setline(1, ['line1', 'line2']) + perl $curwin->Cursor(2, 3) + call assert_equal('2:3', perleval('join(":", $curwin->Cursor())')) + " Col is numbered from 0 in Perl, and from 1 in Vim script. + call assert_equal([0, 2, 4, 0], getpos('.')) + bwipe! +endfunc + +func Test_window_SetHeight() + new + perl $curwin->SetHeight(2) + call assert_equal(2, winheight(0)) + bwipe! +endfunc + +func Test_VIM_Windows() + new + " VIM::Windows() without argument in scalar and list context. + perl $winnr = VIM::Windows() + perl @winlist = VIM::Windows() + perl $curbuf->Append(0, $winnr, scalar(@winlist)) + call assert_equal(['2', '2', ''], getline(1, '$')) + + "" VIM::Windows() with window number argument. + perl (VIM::Windows(VIM::Eval('winnr()')))[0]->Buffer()->Set(1, 'bar') + call assert_equal('bar', getline(1)) + bwipe! +endfunc + +func Test_VIM_Buffers() + new Xbar + " VIM::Buffers() without argument in scalar and list context. + perl $nbuf = VIM::Buffers() + perl @buflist = VIM::Buffers() + + " VIM::Buffers() with argument. + perl $curbuf = (VIM::Buffers('Xbar'))[0] + perl $curbuf->Append(0, $nbuf, scalar(@buflist)) + call assert_equal(['2', '2', ''], getline(1, '$')) + bwipe! +endfunc + +func Test_perleval() + call assert_false(perleval('undef')) + + "" scalar + call assert_equal(0, perleval('0')) + call assert_equal(2, perleval('2')) + call assert_equal(-2, perleval('-2')) + if has('float') + call assert_equal(2.5, perleval('2.5')) + else + call assert_equal(2, perleval('2.5')) + end + + call assert_equal('abc', perleval('"abc"')) + + "" ref + call assert_equal([], perleval('[]')) + call assert_equal(['word', 42, [42],{}], perleval('["word", 42, [42], {}]')) + + call assert_equal({}, perleval('{}')) + call assert_equal({'foo': 'bar'}, perleval('{foo => "bar"}')) + + perl our %h; our @a; + let a = perleval('[\%h, \%h, \@a, \@a]') + echo a + call assert_equal(a[0], a[1]) + call assert_equal(a[2], a[3]) + perl undef %h; undef @a; + + call assert_equal('*VIM', perleval('"*VIM"')) +endfunc + +func Test_perldo() + sp __TEST__ + exe 'read ' g:testname + perldo s/perl/vieux_chameau/g + 1 + call assert_false(search('\Cperl')) + bw! + + " Check deleting lines does not trigger ml_get error. + new + call setline(1, ['one', 'two', 'three']) + perldo VIM::DoCommand("%d_") + bwipe! + + "" Check switching to another buffer does not trigger ml_get error. + new + let wincount = winnr('$') + call setline(1, ['one', 'two', 'three']) + perldo VIM::DoCommand("new") + call assert_equal(wincount + 1, winnr('$')) + bwipe! + bwipe! +endfunc + +func Test_VIM_package() + perl VIM::DoCommand('let l:var = "foo"') + call assert_equal(l:var, 'foo') + + set noet + perl VIM::SetOption('et') + call assert_true(&et) +endfunc + +func Test_set_cursor() + " Check that setting the cursor position works. + new + call setline(1, ['first line', 'second line']) + normal gg + perldo $curwin->Cursor(1, 5) + call assert_equal([1, 6], [line('.'), col('.')]) + + " Check that movement after setting cursor position keeps current column. + normal j + call assert_equal([2, 6], [line('.'), col('.')]) +endfunc + +" Test for various heredoc syntax +func Test_perl_heredoc() + perl << END +VIM::DoCommand('let s = "A"') +END + perl << +VIM::DoCommand('let s ..= "B"') +. + call assert_equal('AB', s) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index aaa291f87d..9f47ee2904 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -841,4 +841,46 @@ func Test_winnr() only | tabonly endfunc +func Test_window_resize() + " Vertical :resize (absolute, relative, min and max size). + vsplit + vert resize 8 + call assert_equal(8, winwidth(0)) + vert resize +2 + call assert_equal(10, winwidth(0)) + vert resize -2 + call assert_equal(8, winwidth(0)) + vert resize + call assert_equal(&columns - 2, winwidth(0)) + vert resize 0 + call assert_equal(1, winwidth(0)) + vert resize 99999 + call assert_equal(&columns - 2, winwidth(0)) + + %bwipe! + + " Horizontal :resize (with absolute, relative size, min and max size). + split + resize 8 + call assert_equal(8, winheight(0)) + resize +2 + call assert_equal(10, winheight(0)) + resize -2 + call assert_equal(8, winheight(0)) + resize + call assert_equal(&lines - 4, winheight(0)) + resize 0 + call assert_equal(1, winheight(0)) + resize 99999 + call assert_equal(&lines - 4, winheight(0)) + + " :resize with explicit window number. + let other_winnr = winnr('j') + exe other_winnr .. 'resize 10' + call assert_equal(10, winheight(other_winnr)) + call assert_equal(&lines - 10 - 3, winheight(0)) + + %bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 3b71066094..dde17726fd 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -108,6 +108,7 @@ typedef struct { bool cork, overflow; bool cursor_color_changed; bool is_starting; + FILE *screenshot; cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; HlAttrs clear_attrs; kvec_t(HlAttrs) attrs; @@ -167,6 +168,7 @@ UI *tui_start(void) ui->suspend = tui_suspend; ui->set_title = tui_set_title; ui->set_icon = tui_set_icon; + ui->screenshot = tui_screenshot; ui->option_set= tui_option_set; ui->raw_line = tui_raw_line; @@ -412,6 +414,7 @@ static void tui_main(UIBridgeData *bridge, UI *ui) data->bridge = bridge; data->loop = &tui_loop; data->is_starting = true; + data->screenshot = NULL; kv_init(data->invalid_regions); signal_watcher_init(data->loop, &data->winch_handle, ui); signal_watcher_init(data->loop, &data->cont_handle, data); @@ -1317,6 +1320,31 @@ static void tui_set_icon(UI *ui, String icon) { } +static void tui_screenshot(UI *ui, String path) +{ + TUIData *data = ui->data; + UGrid *grid = &data->grid; + flush_buf(ui); + grid->row = 0; + grid->col = 0; + + FILE *f = fopen(path.data, "w"); + data->screenshot = f; + fprintf(f, "%d,%d\n", grid->height, grid->width); + unibi_out(ui, unibi_clear_screen); + for (int i = 0; i < grid->height; i++) { + cursor_goto(ui, i, 0); + for (int j = 0; j < grid->width; j++) { + print_cell(ui, &grid->cells[i][j]); + } + } + flush_buf(ui); + data->screenshot = NULL; + + fclose(f); +} + + static void tui_option_set(UI *ui, String name, Object value) { TUIData *data = ui->data; @@ -2054,9 +2082,15 @@ static void flush_buf(UI *ui) } } - uv_write(&req, STRUCT_CAST(uv_stream_t, &data->output_handle), - bufs, (unsigned)(bufp - bufs), NULL); - uv_run(&data->write_loop, UV_RUN_DEFAULT); + if (data->screenshot) { + for (size_t i = 0; i < (size_t)(bufp - bufs); i++) { + fwrite(bufs[i].base, bufs[i].len, 1, data->screenshot); + } + } else { + uv_write(&req, STRUCT_CAST(uv_stream_t, &data->output_handle), + bufs, (unsigned)(bufp - bufs), NULL); + uv_run(&data->write_loop, UV_RUN_DEFAULT); + } data->bufpos = 0; data->overflow = false; } diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 9a1988739c..25f45b8fe6 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -61,6 +61,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.suspend = ui_bridge_suspend; rv->bridge.set_title = ui_bridge_set_title; rv->bridge.set_icon = ui_bridge_set_icon; + rv->bridge.screenshot = ui_bridge_screenshot; rv->bridge.option_set = ui_bridge_option_set; rv->bridge.raw_line = ui_bridge_raw_line; rv->bridge.inspect = ui_bridge_inspect; diff --git a/src/nvim/version.c b/src/nvim/version.c index bf80de6026..d6d933245b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -464,7 +464,7 @@ static const int included_patches[] = { 1457, 1456, // 1455, - // 1454, + 1454, 1453, 1452, 1451, |