aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/_editor.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/_editor.lua')
-rw-r--r--runtime/lua/vim/_editor.lua107
1 files changed, 33 insertions, 74 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index e00d512a2a..6f701e9ae9 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -535,55 +535,6 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive)
return region
end
---- Gets the content of the visual selection.
----
---- The result is either a string or, if {list} is `true`, a list of strings.
---- If not in any |visual-mode|, `nil` is returned.
----
---- @param list boolean|nil
---- Return a list of strings instead of a string. See |getreg()|.
---- Defaults to `false`.
---- @param append_empty boolean|nil
---- Append an empty string to the result when in |linewise-visual| mode and {list} is `true`.
---- This will preserve the trailing newline of the selection when the result is concatenated with `"\n"`.
---- Defaults to `false`.
---- @return string|table
-function vim.get_visual_selection(list, append_empty)
- list = list or false
- append_empty = append_empty or false
-
- local mode = vim.api.nvim_get_mode().mode
- if mode ~= 'v' and mode ~= 'V' and mode:byte() ~= 22 then
- return nil
- end
-
- local reg_name_unnamed = '"'
- local reg_name_yank = '0'
-
- local reg_info_unnamed = vim.fn.getreginfo(reg_name_unnamed)
- local reg_info_yank = vim.fn.getreginfo(reg_name_yank)
- local opt_clipboard = vim.o.clipboard
- local opt_report = vim.o.report
-
- vim.o.clipboard = ''
- vim.o.report = vim.v.maxcol
-
- vim.api.nvim_feedkeys('y', 'nx', false)
-
- local yanked = vim.fn.getreg(reg_name_yank, 1, list)
-
- vim.fn.setreg(reg_name_unnamed, reg_info_unnamed)
- vim.fn.setreg(reg_name_yank, reg_info_yank)
- vim.o.clipboard = opt_clipboard
- vim.o.report = opt_report
-
- if list and append_empty and mode == 'V' then
- table.insert(yanked, '')
- end
-
- return yanked
-end
-
--- Defers calling {fn} until {timeout} ms passes.
---
--- Use to do a one-shot timer that calls {fn}
@@ -1034,7 +985,7 @@ end
--- Defaults to "Nvim".
---@param backtrace boolean|nil Prints backtrace. Defaults to true.
---
----@return Deprecated message, or nil if no message was shown.
+---@return string|nil # Deprecated message, or nil if no message was shown.
function vim.deprecate(name, alternative, version, plugin, backtrace)
local msg = ('%s is deprecated'):format(name)
plugin = plugin or 'Nvim'
@@ -1049,9 +1000,7 @@ function vim.deprecate(name, alternative, version, plugin, backtrace)
if displayed and backtrace ~= false then
vim.notify(debug.traceback('', 2):sub(2), vim.log.levels.WARN)
end
- if displayed then
- return msg
- end
+ return displayed and msg or nil
end
--- Create builtin mappings (incl. menus).
@@ -1060,27 +1009,37 @@ function vim._init_default_mappings()
-- mappings
---@private
- local function _search_for_visual_selection(search_prefix)
- if search_prefix ~= '/' and search_prefix ~= '?' then
- return
+ local function region_chunks(region)
+ local chunks = {}
+ local maxcol = vim.v.maxcol
+ for line, cols in vim.spairs(region) do
+ local endcol = cols[2] == maxcol and -1 or cols[2]
+ local chunk = vim.api.nvim_buf_get_text(0, line, cols[1], line, endcol, {})[1]
+ table.insert(chunks, chunk)
end
- -- Escape these characters
- local replacements = {
- [search_prefix] = [[\]] .. search_prefix,
- [ [[\]] ] = [[\\]],
- ['\t'] = [[\t]],
- ['\n'] = [[\n]],
- }
- local pattern = '[' .. table.concat(vim.tbl_keys(replacements), '') .. ']'
- local visual_selection = vim.get_visual_selection(false)
- local escaped_visual_selection = string.gsub(visual_selection, pattern, replacements)
- local search_cmd = search_prefix .. [[\V]] .. escaped_visual_selection .. '\n'
+ return chunks
+ end
+
+ ---@private
+ local function _visual_search(cmd)
+ assert(cmd == '/' or cmd == '?')
+ vim.api.nvim_feedkeys('\27', 'nx', true) -- Escape visual mode.
+ local region = vim.region(0, "'<", "'>", vim.fn.visualmode(), vim.o.selection == 'inclusive')
+ local chunks = region_chunks(region)
+ local esc_chunks = vim
+ .iter(chunks)
+ :map(function(v)
+ return vim.fn.escape(v, [[/\]])
+ end)
+ :totable()
+ local esc_pat = table.concat(esc_chunks, [[\n]])
+ local search_cmd = ([[%s\V%s%s]]):format(cmd, esc_pat, '\n')
vim.api.nvim_feedkeys(search_cmd, 'nx', true)
end
---@private
local function map(mode, lhs, rhs)
- vim.keymap.set(mode, lhs, rhs, { noremap = true, desc = 'Nvim builtin' })
+ vim.keymap.set(mode, lhs, rhs, { desc = 'Nvim builtin' })
end
map('n', 'Y', 'y$')
@@ -1088,12 +1047,12 @@ function vim._init_default_mappings()
map('n', '<C-L>', '<Cmd>nohlsearch<Bar>diffupdate<Bar>normal! <C-L><CR>')
map('i', '<C-U>', '<C-G>u<C-U>')
map('i', '<C-W>', '<C-G>u<C-W>')
- map('x', '*', function()
- _search_for_visual_selection('/')
- end)
- map('x', '#', function()
- _search_for_visual_selection('?')
- end)
+ vim.keymap.set('x', '*', function()
+ _visual_search('/')
+ end, { desc = 'Nvim builtin', silent = true })
+ vim.keymap.set('x', '#', function()
+ _visual_search('?')
+ end, { desc = 'Nvim builtin', silent = true })
-- Use : instead of <Cmd> so that ranges are supported. #19365
map('n', '&', ':&&<CR>')