Skip to content

Commit

Permalink
remove select_keys, just allow direct access to pre_yank and post_yank.
Browse files Browse the repository at this point in the history
  • Loading branch information
L3MON4D3 committed Aug 20, 2024
1 parent 2c35ca7 commit 0edaebd
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 25 deletions.
33 changes: 30 additions & 3 deletions DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -3494,6 +3494,33 @@ It is also possible to get/set the source of a snippet via API:
generated by `debug.get_info(*, "Sl")` (at least `"Sl"`, it may also contain
more info).

# Selection

Many snippets use the `$TM_SELECTED_TEXT` or (for LuaSnip, preferably
`LS_SELECT_RAW` or `LS_SELECT_DEDENT`) variable, which has to be populated by
selecting and then yanking (and usually also cutting) text from the buffer
before expanding.

By default, this is disabled (as to not pollute keybindings which may be used
for something else), so one has to
* either set `cut_selection_keys` in `setup` (see
[Config-Options](#config-options)).
* or map `ls.cut_keys` as the rhs of a mapping
* or manually configure the keybinding. For this, create a new keybinding that
1. `<Esc>`es to NORMAL (to populate the `<` and `>`-markers)
2. calls `luasnip.pre_yank(<namedreg>)`
3. yanks text to some named register `<namedreg>`
4. calls `luasnip.post_yank(<namedreg>)`
Take care that the yanking actually takes place between the two calls. One way
to ensure this is to call the two functions via `<cmd>lua ...<Cr>`:
```lua
vim.keymap.set("v", "<Tab>", [[<Esc><cmd>lua require("luasnip.util.select").pre_yank("z")<Cr>gv"zs<cmd>lua require('luasnip.util.select').post_yank("z")<Cr>]])
```
The reason for this specific order is to allow us to take a snapshot of
registers (in the pre-callback), and then restore them (in the post-callback)
(so that we may get the visual selection directly from the register, which
seems to be the most foolproof way of doing this).

# Config-Options

These are the settings you can provide to `luasnip.setup()`:
Expand Down Expand Up @@ -3531,10 +3558,10 @@ These are the settings you can provide to `luasnip.setup()`:
`'InsertLeave'`, to react to changes done in Insert mode) should work just
fine (alternatively, this can also be mapped using
`<Plug>luasnip-delete-check`).
- `store_selection_keys`: Mapping for populating `TM_SELECTED_TEXT` and related
- `cut_selection_keys`: Mapping for populating `TM_SELECTED_TEXT` and related
variables (not set by default).
If you want to set this mapping yourself, map `ls.select_keys` (not a
function, actually a string/key-combination) as a rhs.
See [Selection](#selection) for more infos.
- `store_selection_keys` (deprecated): same as `cut_selection_keys`
- `enable_autosnippets`: Autosnippets are disabled by default to minimize
performance penalty if unused. Set to `true` to enable.
- `ext_opts`: Additional options passed to extmarks. Can be used to add
Expand Down
11 changes: 1 addition & 10 deletions lua/luasnip/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,7 @@ c = {
string.format(
[[xnoremap <silent> %s %s]],
session.config.cut_selection_keys,
require("luasnip.util.select").select_keys
)
)
end
if session.config.copy_selection_keys then
vim.cmd(
string.format(
[[xnoremap <silent> %s %s]],
session.config.copy_selection_keys,
require("luasnip.util.select").copy_keys
require("luasnip.util.select").cut_keys
)
)
end
Expand Down
1 change: 0 additions & 1 deletion lua/luasnip/default_config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ return {
delete_check_events = nil,

-- preserve default of store_selection_keys.
copy_selection_keys = nil,
cut_selection_keys = nil,

ext_opts = {
Expand Down
7 changes: 5 additions & 2 deletions lua/luasnip/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -844,8 +844,11 @@ local ls_lazy = {
config = function() return require("luasnip.config") end,
multi_snippet = function() return require("luasnip.nodes.multiSnippet").new_multisnippet end,
snippet_source = function() return require("luasnip.session.snippet_collection.source") end,
select_keys = function() return require("luasnip.util.select").select_keys end,
copy_keys = function() return require("luasnip.util.select").copy_keys end
cut_keys = function() return require("luasnip.util.select").cut_keys end,
-- keep select_keys for backwards-compatibility.
select_keys = function() return require("luasnip.util.select").cut_keys end,
pre_yank = function() return require("luasnip.util.select").pre_yank end,
post_yank = function() return require("luasnip.util.select").post_yank end,
}

ls = lazy_table({
Expand Down
14 changes: 6 additions & 8 deletions lua/luasnip/util/select.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,19 @@ end

-- subtle: `:lua` exits VISUAL, which means that the '< '>-marks will be set correctly!
-- Afterwards, we can just use <cmd>lua, which does not change the mode.
M.select_keys =
[[:lua require("luasnip.util.select").pre_cut()<Cr>gv"zs<cmd>lua require('luasnip.util.select').post_cut("z")<Cr>]]
M.copy_keys =
[[:lua require("luasnip.util.select").pre_cut()<Cr>gv"zy<cmd>lua require('luasnip.util.select').post_cut("z")<Cr>]]
M.cut_keys =
[[<Esc><cmd>lua require("luasnip.util.select").pre_yank("z")<Cr>gv"zs<cmd>lua require('luasnip.util.select').post_yank("z")<Cr>]]

local saved_registers
local lines
local start_line, start_col, end_line, end_col
local mode
function M.pre_cut()
function M.pre_yank(yank_register)
-- store registers so we don't change any of them.
-- "" is affected since we perform a cut (s), 1-9 also (although :h
-- quote_number seems to state otherwise for cuts to specific registers..?).
saved_registers =
store_registers("", "1", "2", "3", "4", "5", "6", "7", "8", "9", "z")
store_registers("", "1", "2", "3", "4", "5", "6", "7", "8", "9", yank_register)

-- store data needed for de-indenting lines.
start_line = vim.fn.line("'<") - 1
Expand All @@ -85,9 +83,9 @@ function M.pre_cut()
mode = vim.fn.visualmode()
end

function M.post_cut(register_name)
function M.post_yank(yank_register)
-- remove trailing newline.
local chunks = vim.split(vim.fn.getreg(register_name):gsub("\n$", ""), "\n")
local chunks = vim.split(vim.fn.getreg(yank_register):gsub("\n$", ""), "\n")

-- make sure to restore the registers to the state they were before cutting.
restore_registers(saved_registers)
Expand Down
45 changes: 44 additions & 1 deletion tests/integration/select_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe("Selection", function()
)
end)

it("works via manual keybinding.", function()
it("works via manual keybinding (deprecated api).", function()
exec_lua([[
vim.keymap.set({"x"}, "p", ls.select_keys, {silent = true})
]])
Expand All @@ -64,6 +64,49 @@ describe("Selection", function()
{2:-- INSERT --} |]],
})
end)
it("works via manual keybinding.", function()
exec_lua([[
vim.keymap.set({"x"}, "p", ls.cut_keys, {silent = true})
]])
feed("iasdf qwer<Esc>v^p")
exec_lua([[ls.lsp_expand(".$LS_SELECT_RAW.")]])
screen:expect({
grid = [[
.asdf qwer.^ |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]],
})
end)
it("works via manual custom keybinding.", function()
exec_lua([=[
vim.keymap.set({"x"}, "y", [[<Esc><cmd>lua ls.pre_yank("d")<cr>gv"dy<cmd>lua ls.post_yank("d")<cr>]], {silent = true})
]=])
feed("iasdf qwer<Esc>v^y")
screen:expect({
grid = [[
^asdf qwer |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|]]
})
exec_lua([[ls.lsp_expand(".$LS_SELECT_RAW.")]])
screen:expect({
grid = [[
.asdf qwer.^asdf qwer |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{2:-- INSERT --} |]]})
end)

it("works with linewise-selection.", function()
feed("iasdf qwer<Cr>asdf qwer<Cr>asdf qwer<Esc>Vkk<Tab>")
Expand Down

0 comments on commit 0edaebd

Please sign in to comment.