From 7df566060c6ca4acbd7b42c1b40adf6058e49982 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 18 Aug 2019 22:25:03 +0200 Subject: lua/stdlib: cleanup --- src/nvim/lua/vim.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 46c96b455f..9854496415 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -8,8 +8,8 @@ -- -- Guideline: "If in doubt, put it in the runtime". -- --- Most functions should live directly on `vim.`, not sub-modules. The only --- "forbidden" names are those claimed by legacy `if_lua`: +-- Most functions should live directly in `vim.`, not in submodules. +-- The only "forbidden" names are those claimed by legacy `if_lua`: -- $ vim -- :lua for k,v in pairs(vim) do print(k) end -- buffer @@ -161,6 +161,16 @@ local function inspect(object, options) -- luacheck: no unused error(object, options) -- Stub for gen_vimdoc.py end +--- Defers the wrapped callback until the Nvim API is safe to call. +--- +--@see |vim-loop-callbacks| +local function schedule_wrap(cb) + return (function (...) + local args = {...} + vim.schedule(function() cb(unpack(args)) end) + end) +end + local function __index(t, key) if key == 'inspect' then t.inspect = require('vim.inspect') @@ -172,16 +182,6 @@ local function __index(t, key) end end ---- Defers the wrapped callback until when the nvim API is safe to call. ---- ---- See |vim-loop-callbacks| -local function schedule_wrap(cb) - return (function (...) - local args = {...} - vim.schedule(function() cb(unpack(args)) end) - end) -end - local module = { _update_package_paths = _update_package_paths, _os_proc_children = _os_proc_children, -- cgit From 6d277f43a287d62c10fb1ed8d93247ddf4a437d9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 18 Aug 2019 22:55:54 +0200 Subject: TUI/paste: define paste function as Lua builtin - Define in Lua so that it is compiled-in (available with `-u NONE`). TODO: Eventually we will want a 'pastefunc' option or some other way to override the default paste handler. --- src/nvim/lua/vim.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 9854496415..922878d6ce 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -93,6 +93,23 @@ local function _os_proc_children(ppid) return children end +-- Default paste function. +local function _paste(data) + -- local eof = (data == {''}) + local curline = vim.api.nvim_call_function('line', {'.'}) + vim.api.nvim_buf_set_lines( + 0, + curline, + curline, + false, + data) + vim.api.nvim_call_function('cursor', {curline + #data, 1}) + -- if eof then + -- vim.api.nvim_command('redraw') + -- end + return 0 +end + -- TODO(ZyX-I): Create compatibility layer. --{{{1 package.path updater function -- Last inserted paths. Used to clear out items from package.[c]path when they @@ -186,6 +203,7 @@ local module = { _update_package_paths = _update_package_paths, _os_proc_children = _os_proc_children, _os_proc_info = _os_proc_info, + _paste = _paste, _system = _system, schedule_wrap = schedule_wrap, } -- cgit From 68ea9a7c8a7a74ec6ec9782528527cf70b92a376 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 19 Aug 2019 00:18:41 +0200 Subject: TUI/paste: always flush on paste mode-change Flush input before entering, not only when leaving, paste mode. Else there could be pending input which will erroneously be sent to the paste handler. --- src/nvim/lua/vim.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 922878d6ce..47feba0f85 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -96,17 +96,19 @@ end -- Default paste function. local function _paste(data) -- local eof = (data == {''}) - local curline = vim.api.nvim_call_function('line', {'.'}) + local curline = vim.api.nvim_call_function('line', {'.'}) - 1 vim.api.nvim_buf_set_lines( 0, curline, curline, false, data) - vim.api.nvim_call_function('cursor', {curline + #data, 1}) + vim.api.nvim_call_function( + 'cursor', + {curline + #data, 9999999}) + -- TODO: do not redraw (slow!) until paste is finished. -- if eof then - -- vim.api.nvim_command('redraw') - -- end + vim.api.nvim_command('redraw') return 0 end -- cgit From 4389401a7c82ca43a3634f65f57815af06fe9abd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 19 Aug 2019 00:41:58 +0200 Subject: paste: abort paste if handler does not return true --- src/nvim/lua/vim.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 47feba0f85..54fce47fd0 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -109,7 +109,7 @@ local function _paste(data) -- TODO: do not redraw (slow!) until paste is finished. -- if eof then vim.api.nvim_command('redraw') - return 0 + return true -- Paste will not continue if not returning `true`. end -- TODO(ZyX-I): Create compatibility layer. -- cgit From abd55be19a2f1443cfffb8d4953f86f32efe40aa Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 19 Aug 2019 01:01:40 +0200 Subject: paste: fixup tests --- src/nvim/lua/vim.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 54fce47fd0..e20fc1472e 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -96,7 +96,7 @@ end -- Default paste function. local function _paste(data) -- local eof = (data == {''}) - local curline = vim.api.nvim_call_function('line', {'.'}) - 1 + local curline = vim.api.nvim_call_function('line', {'.'}) vim.api.nvim_buf_set_lines( 0, curline, -- cgit From f99caa755c84788f0e2e9959ccad7c4539fb4927 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 19 Aug 2019 01:14:06 +0200 Subject: paste: use chansend() in Terminal-mode --- src/nvim/lua/vim.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index e20fc1472e..49eb99c81a 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -95,15 +95,23 @@ end -- Default paste function. local function _paste(data) + local call = vim.api.nvim_call_function + local mode = call('mode', {}) + if mode == 't' then + call('chansend', + {vim.api.nvim_buf_get_option(0, 'channel'), data}) + return true + end + -- local eof = (data == {''}) - local curline = vim.api.nvim_call_function('line', {'.'}) + local curline = call('line', {'.'}) vim.api.nvim_buf_set_lines( 0, curline, curline, false, data) - vim.api.nvim_call_function( + call( 'cursor', {curline + #data, 9999999}) -- TODO: do not redraw (slow!) until paste is finished. -- cgit From 5a2894d67753b408ada3b89c1b7fbd9152977203 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 20 Aug 2019 01:21:27 +0200 Subject: paste: use nvim_put() --- src/nvim/lua/vim.lua | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 49eb99c81a..6759e4436b 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -94,26 +94,14 @@ local function _os_proc_children(ppid) end -- Default paste function. -local function _paste(data) +local function _paste(lines) + -- local eof = (lines == {''}) local call = vim.api.nvim_call_function local mode = call('mode', {}) - if mode == 't' then - call('chansend', - {vim.api.nvim_buf_get_option(0, 'channel'), data}) - return true - end - - -- local eof = (data == {''}) local curline = call('line', {'.'}) - vim.api.nvim_buf_set_lines( - 0, - curline, - curline, - false, - data) - call( - 'cursor', - {curline + #data, 9999999}) + -- vim.api.nvim_set_option('paste', true) + vim.api.nvim_put(lines, 'c', false) + -- vim.api.nvim_set_option('paste', false) -- TODO: do not redraw (slow!) until paste is finished. -- if eof then vim.api.nvim_command('redraw') -- cgit From 93e5f0235b8e85423d0284231661ba4b0d7caa07 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 20 Aug 2019 23:53:13 +0200 Subject: API: nvim_put: "follow" parameter --- src/nvim/lua/vim.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 6759e4436b..0b94417b3e 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -100,7 +100,7 @@ local function _paste(lines) local mode = call('mode', {}) local curline = call('line', {'.'}) -- vim.api.nvim_set_option('paste', true) - vim.api.nvim_put(lines, 'c', false) + vim.api.nvim_put(lines, 'c', true, true) -- vim.api.nvim_set_option('paste', false) -- TODO: do not redraw (slow!) until paste is finished. -- if eof then -- cgit From 5ae6849517d2a025c3359e771ac1e01a68ec24c8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 21 Aug 2019 01:55:12 +0200 Subject: paste: phases, dots - Send `phase` parameter to the paste handler. - Redraw at intervals and when paste terminates. - Show "..." throbber during paste to indicate activity. --- src/nvim/lua/vim.lua | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 0b94417b3e..dca61d814a 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -94,19 +94,39 @@ local function _os_proc_children(ppid) end -- Default paste function. -local function _paste(lines) - -- local eof = (lines == {''}) - local call = vim.api.nvim_call_function - local mode = call('mode', {}) - local curline = call('line', {'.'}) - -- vim.api.nvim_set_option('paste', true) - vim.api.nvim_put(lines, 'c', true, true) - -- vim.api.nvim_set_option('paste', false) - -- TODO: do not redraw (slow!) until paste is finished. - -- if eof then - vim.api.nvim_command('redraw') - return true -- Paste will not continue if not returning `true`. -end +local _paste = (function() + local tdots = 0 + local tredraw = 0 + local tick = 0 + return function(lines, phase) + local call = vim.api.nvim_call_function + local now = vim.loop.now() + if phase == 1 then + tdots = now + tredraw = now + tick = 0 + if (call('mode', {})):find('[vV]') then + vim.api.nvim_feedkeys('', 'n', false) + end + end + vim.api.nvim_put(lines, 'c', true, true) + if (now - tredraw >= 1000) or phase == 1 or phase == 3 then + tredraw = now + vim.api.nvim_command('redraw') + vim.api.nvim_command('redrawstatus') + end + if (now - tdots >= 100) then + local dots = ('.'):rep(tick % 4) + tdots = now + tick = tick + 1 + vim.api.nvim_command(('echo "%s"'):format(dots)) + end + if phase == 3 then + vim.api.nvim_command('echo ""') + end + return true -- Paste will not continue if not returning `true`. + end +end)() -- TODO(ZyX-I): Create compatibility layer. --{{{1 package.path updater function -- cgit From eacc70fb3ebae6d76112ab10647a42339f5f223f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 24 Aug 2019 13:54:27 +0200 Subject: API: nvim_paste --- src/nvim/lua/vim.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index dca61d814a..637a4baf33 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -105,9 +105,10 @@ local _paste = (function() tdots = now tredraw = now tick = 0 - if (call('mode', {})):find('[vV]') then - vim.api.nvim_feedkeys('', 'n', false) - end + -- TODO + -- if mode == 'i' or mode == 'R' then + -- nvim_cancel() + -- end end vim.api.nvim_put(lines, 'c', true, true) if (now - tredraw >= 1000) or phase == 1 or phase == 3 then @@ -119,6 +120,8 @@ local _paste = (function() local dots = ('.'):rep(tick % 4) tdots = now tick = tick + 1 + -- Use :echo because Lua print('') is a no-op, and we want to clear the + -- message when there are zero dots. vim.api.nvim_command(('echo "%s"'):format(dots)) end if phase == 3 then -- cgit From bfc5a18f4b6cb4bc2335440254c346d731063b46 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 24 Aug 2019 14:01:09 +0200 Subject: paste: insert text "before" cursor in Insert-mode --- src/nvim/lua/vim.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 637a4baf33..59438c8667 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -101,6 +101,7 @@ local _paste = (function() return function(lines, phase) local call = vim.api.nvim_call_function local now = vim.loop.now() + local mode = call('mode', {}):sub(1,1) if phase == 1 then tdots = now tredraw = now @@ -110,7 +111,11 @@ local _paste = (function() -- nvim_cancel() -- end end - vim.api.nvim_put(lines, 'c', true, true) + if mode == 'i' or mode == 'R' then + vim.api.nvim_put(lines, 'c', false, true) + else + vim.api.nvim_put(lines, 'c', true, true) + end if (now - tredraw >= 1000) or phase == 1 or phase == 3 then tredraw = now vim.api.nvim_command('redraw') -- cgit From 5b41070c639f979023178042bea8e5fcc8a898fe Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 25 Aug 2019 10:20:38 +0200 Subject: paste: implement redo (AKA dot-repeat) - Normal-mode redo idiom(?): prepend "i" and append ESC. - Insert-mode only needs AppendToRedobuffLit(). - Cmdline-mode: only paste the first line. --- src/nvim/lua/vim.lua | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 59438c8667..05951fbd0f 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -93,35 +93,32 @@ local function _os_proc_children(ppid) return children end --- Default paste function. +-- Default nvim_paste() handler. local _paste = (function() - local tdots = 0 - local tredraw = 0 - local tick = 0 + local tdots, tredraw, tick, got_line1 = 0, 0, 0, false return function(lines, phase) local call = vim.api.nvim_call_function local now = vim.loop.now() local mode = call('mode', {}):sub(1,1) - if phase == 1 then - tdots = now - tredraw = now - tick = 0 - -- TODO - -- if mode == 'i' or mode == 'R' then - -- nvim_cancel() - -- end + if phase < 2 then -- Reset flags. + tdots, tredraw, tick, got_line1 = now, now, 0, false end - if mode == 'i' or mode == 'R' then + if mode == 'c' and not got_line1 then -- cmdline-mode: paste only 1 line. + got_line1 = (#lines > 1) + vim.api.nvim_set_option('paste', true) -- For nvim_input(). + local line1, _ = string.gsub(lines[1], '[\r\n\012\027]', ' ') + vim.api.nvim_input(line1) -- Scrub "\r". + elseif mode == 'i' or mode == 'R' then vim.api.nvim_put(lines, 'c', false, true) else vim.api.nvim_put(lines, 'c', true, true) end - if (now - tredraw >= 1000) or phase == 1 or phase == 3 then + if (now - tredraw >= 1000) or phase == -1 or phase > 2 then tredraw = now vim.api.nvim_command('redraw') vim.api.nvim_command('redrawstatus') end - if (now - tdots >= 100) then + if phase ~= -1 and (now - tdots >= 100) then local dots = ('.'):rep(tick % 4) tdots = now tick = tick + 1 @@ -129,8 +126,9 @@ local _paste = (function() -- message when there are zero dots. vim.api.nvim_command(('echo "%s"'):format(dots)) end - if phase == 3 then + if phase == -1 or phase == 3 then vim.api.nvim_command('echo ""') + vim.api.nvim_set_option('paste', false) end return true -- Paste will not continue if not returning `true`. end -- cgit From 87389c6a57cf9fa91746503c479cdbea348030b9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 27 Aug 2019 05:19:25 +0200 Subject: paste: make vim.paste() "public" --- src/nvim/lua/vim.lua | 96 +++++++++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 42 deletions(-) (limited to 'src/nvim/lua/vim.lua') diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 05951fbd0f..fd34b8545d 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -93,47 +93,6 @@ local function _os_proc_children(ppid) return children end --- Default nvim_paste() handler. -local _paste = (function() - local tdots, tredraw, tick, got_line1 = 0, 0, 0, false - return function(lines, phase) - local call = vim.api.nvim_call_function - local now = vim.loop.now() - local mode = call('mode', {}):sub(1,1) - if phase < 2 then -- Reset flags. - tdots, tredraw, tick, got_line1 = now, now, 0, false - end - if mode == 'c' and not got_line1 then -- cmdline-mode: paste only 1 line. - got_line1 = (#lines > 1) - vim.api.nvim_set_option('paste', true) -- For nvim_input(). - local line1, _ = string.gsub(lines[1], '[\r\n\012\027]', ' ') - vim.api.nvim_input(line1) -- Scrub "\r". - elseif mode == 'i' or mode == 'R' then - vim.api.nvim_put(lines, 'c', false, true) - else - vim.api.nvim_put(lines, 'c', true, true) - end - if (now - tredraw >= 1000) or phase == -1 or phase > 2 then - tredraw = now - vim.api.nvim_command('redraw') - vim.api.nvim_command('redrawstatus') - end - if phase ~= -1 and (now - tdots >= 100) then - local dots = ('.'):rep(tick % 4) - tdots = now - tick = tick + 1 - -- Use :echo because Lua print('') is a no-op, and we want to clear the - -- message when there are zero dots. - vim.api.nvim_command(('echo "%s"'):format(dots)) - end - if phase == -1 or phase == 3 then - vim.api.nvim_command('echo ""') - vim.api.nvim_set_option('paste', false) - end - return true -- Paste will not continue if not returning `true`. - end -end)() - -- TODO(ZyX-I): Create compatibility layer. --{{{1 package.path updater function -- Last inserted paths. Used to clear out items from package.[c]path when they @@ -202,6 +161,59 @@ local function inspect(object, options) -- luacheck: no unused error(object, options) -- Stub for gen_vimdoc.py end +--- Paste handler, invoked by |nvim_paste()| when a conforming UI +--- (such as the |TUI|) pastes text into the editor. +--- +--@see |paste| +--- +--@param lines |readfile()|-style list of lines to paste. |channel-lines| +--@param phase -1: "non-streaming" paste: the call contains all lines. +--- If paste is "streamed", `phase` indicates the stream state: +--- - 1: starts the paste (exactly once) +--- - 2: continues the paste (zero or more times) +--- - 3: ends the paste (exactly once) +--@returns false if client should cancel the paste. +local function paste(lines, phase) end -- luacheck: no unused +paste = (function() + local tdots, tredraw, tick, got_line1 = 0, 0, 0, false + return function(lines, phase) + local call = vim.api.nvim_call_function + local now = vim.loop.now() + local mode = call('mode', {}):sub(1,1) + if phase < 2 then -- Reset flags. + tdots, tredraw, tick, got_line1 = now, now, 0, false + end + if mode == 'c' and not got_line1 then -- cmdline-mode: paste only 1 line. + got_line1 = (#lines > 1) + vim.api.nvim_set_option('paste', true) -- For nvim_input(). + local line1, _ = string.gsub(lines[1], '[\r\n\012\027]', ' ') + vim.api.nvim_input(line1) -- Scrub "\r". + elseif mode == 'i' or mode == 'R' then + vim.api.nvim_put(lines, 'c', false, true) + else + vim.api.nvim_put(lines, 'c', true, true) + end + if (now - tredraw >= 1000) or phase == -1 or phase > 2 then + tredraw = now + vim.api.nvim_command('redraw') + vim.api.nvim_command('redrawstatus') + end + if phase ~= -1 and (now - tdots >= 100) then + local dots = ('.'):rep(tick % 4) + tdots = now + tick = tick + 1 + -- Use :echo because Lua print('') is a no-op, and we want to clear the + -- message when there are zero dots. + vim.api.nvim_command(('echo "%s"'):format(dots)) + end + if phase == -1 or phase == 3 then + vim.api.nvim_command('echo ""') + vim.api.nvim_set_option('paste', false) + end + return true -- Paste will not continue if not returning `true`. + end +end)() + --- Defers the wrapped callback until the Nvim API is safe to call. --- --@see |vim-loop-callbacks| @@ -227,8 +239,8 @@ local module = { _update_package_paths = _update_package_paths, _os_proc_children = _os_proc_children, _os_proc_info = _os_proc_info, - _paste = _paste, _system = _system, + paste = paste, schedule_wrap = schedule_wrap, } -- cgit