refactor(paste): do not print dots in cmdline mode

This commit is contained in:
zeertzjq 2022-03-06 06:56:24 +08:00
parent bfb7754442
commit 21ba2d81a8

View File

@ -157,60 +157,64 @@ do
---@returns false if client should cancel the paste. ---@returns false if client should cancel the paste.
function vim.paste(lines, phase) function vim.paste(lines, phase)
local now = vim.loop.now() local now = vim.loop.now()
local mode = vim.api.nvim_get_mode().mode local is_first_chunk = phase < 2
local is_cmdline = vim.fn.getcmdtype() ~= '' if is_first_chunk then -- Reset flags.
if phase < 2 then -- Reset flags.
tdots, tick, got_line1 = now, 0, false tdots, tick, got_line1 = now, 0, false
elseif not is_cmdline then end
-- Note: mode doesn't always start with "c" in cmdline mode, so use getcmdtype() instead.
if vim.fn.getcmdtype() ~= '' then -- cmdline-mode: paste only 1 line.
if not got_line1 then
got_line1 = (#lines > 1)
vim.api.nvim_set_option('paste', true) -- For nvim_input().
local line1 = lines[1]:gsub('<', '<lt>'):gsub('[\r\n\012\027]', ' ') -- Scrub.
vim.api.nvim_input(line1)
vim.api.nvim_set_option('paste', false)
end
return true
end
local mode = vim.api.nvim_get_mode().mode
if not is_first_chunk then
vim.api.nvim_command('undojoin') vim.api.nvim_command('undojoin')
end end
if is_cmdline and not got_line1 then -- cmdline-mode: paste only 1 line. if mode:find('^i') or mode:find('^n?t') then -- Insert mode or Terminal buffer
got_line1 = (#lines > 1) vim.api.nvim_put(lines, 'c', false, true)
vim.api.nvim_set_option('paste', true) -- For nvim_input(). elseif phase < 2 and mode:find('^R') and not mode:find('^Rv') then -- Replace mode
local line1 = lines[1]:gsub('<', '<lt>'):gsub('[\r\n\012\027]', ' ') -- Scrub. -- TODO: implement Replace mode streamed pasting
vim.api.nvim_input(line1) -- TODO: support Virtual Replace mode
vim.api.nvim_set_option('paste', false) local nchars = 0
elseif not is_cmdline then for _, line in ipairs(lines) do
if mode:find('^i') or mode:find('^n?t') then -- Insert mode or Terminal buffer nchars = nchars + line:len()
vim.api.nvim_put(lines, 'c', false, true)
elseif phase < 2 and mode:find('^R') and not mode:find('^Rv') then -- Replace mode
-- TODO: implement Replace mode streamed pasting
-- TODO: support Virtual Replace mode
local nchars = 0
for _, line in ipairs(lines) do
nchars = nchars + line:len()
end
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
local bufline = vim.api.nvim_buf_get_lines(0, row-1, row, true)[1]
local firstline = lines[1]
firstline = bufline:sub(1, col)..firstline
lines[1] = firstline
-- FIXME: #lines can be 0
lines[#lines] = lines[#lines]..bufline:sub(col + nchars + 1, bufline:len())
vim.api.nvim_buf_set_lines(0, row-1, row, false, lines)
elseif mode:find('^[nvV\22sS\19]') then -- Normal or Visual or Select mode
if mode:find('^n') then -- Normal mode
vim.api.nvim_put(lines, 'c', true, false)
else -- Visual or Select mode
vim.api.nvim_command([[exe "silent normal! \<Del>"]])
local del_start = vim.fn.getpos("'[")
local cursor_pos = vim.fn.getpos('.')
if mode:find('^[VS]') then -- linewise
if cursor_pos[2] < del_start[2] then -- replacing lines at eof
-- create a new line
vim.api.nvim_put({''}, 'l', true, true)
end
vim.api.nvim_put(lines, 'c', false, false)
else
-- paste after cursor when replacing text at eol, otherwise paste before cursor
vim.api.nvim_put(lines, 'c', cursor_pos[3] < del_start[3], false)
end
end
-- put cursor at the end of the text instead of one character after it
vim.fn.setpos('.', vim.fn.getpos("']"))
else -- Don't know what to do in other modes
return false
end end
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
local bufline = vim.api.nvim_buf_get_lines(0, row-1, row, true)[1]
local firstline = lines[1]
firstline = bufline:sub(1, col)..firstline
lines[1] = firstline
-- FIXME: #lines can be 0
lines[#lines] = lines[#lines]..bufline:sub(col + nchars + 1, bufline:len())
vim.api.nvim_buf_set_lines(0, row-1, row, false, lines)
elseif mode:find('^[nvV\22sS\19]') then -- Normal or Visual or Select mode
if mode:find('^n') then -- Normal mode
vim.api.nvim_put(lines, 'c', true, false)
else -- Visual or Select mode
vim.api.nvim_command([[exe "silent normal! \<Del>"]])
local del_start = vim.fn.getpos("'[")
local cursor_pos = vim.fn.getpos('.')
if mode:find('^[VS]') then -- linewise
if cursor_pos[2] < del_start[2] then -- replacing lines at eof
-- create a new line
vim.api.nvim_put({''}, 'l', true, true)
end
vim.api.nvim_put(lines, 'c', false, false)
else
-- paste after cursor when replacing text at eol, otherwise paste before cursor
vim.api.nvim_put(lines, 'c', cursor_pos[3] < del_start[3], false)
end
end
-- put cursor at the end of the text instead of one character after it
vim.fn.setpos('.', vim.fn.getpos("']"))
else -- Don't know what to do in other modes
return false
end end
if phase ~= -1 and (now - tdots >= 100) then if phase ~= -1 and (now - tdots >= 100) then
local dots = ('.'):rep(tick % 4) local dots = ('.'):rep(tick % 4)