Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Neovim: better selection/copy support #2322

Open
saidelike opened this issue May 4, 2024 · 1 comment
Open

Neovim: better selection/copy support #2322

saidelike opened this issue May 4, 2024 · 1 comment
Labels
app-neovim Issues related to neovim support

Comments

@saidelike
Copy link
Collaborator

Scenario 1

  • double clicking on the 789abcdef entry with the mouse selects it as expected (see screenshot below)
  • doing ctr+c saves 789abcdef in the clipboard, as expected
  • however, saying copy this saves 789abcde in the clipboard (notice the missing f at the end)

image

Scenario 2 (same as scenario 1)

  • dragging the mouse from the first character 7 up to the last character f in order to select it (see screenshot below)
  • doing ctr+c saves 789abcdef in the clipboard, as expected
  • however, saying copy this saves 789abcde in the clipboard (notice the missing f at the end)

image

Scenario 3

Now at the moment, the way we select from cursorless behaves differently:

  • saying take last paint row 2 selects one more character (notice the extra "space" at the end, even if there is no space on the line)
  • PROBLEM: doing ctr+c saves 789abcdef\n in the clipboard (notices the extra newline at the end)
  • saying copy this saves 789abcdef in the clipboard (so includes the f but no extra space)

image

Scenario 4

  • saying copy last paint row 2 saves 789abcdef to the clipboard so it saves the right thing.

Solution / Idea

It seems we could solve it by:

  • selecting one less character in visual mode (to mimic what happens when double clicking). It will also render better visualy?
  • then, when we issue a copy command, it seems we need to select one more character than what is shown

Then we would have the following behaviours

  • if we move the cursor in normal mode (with mouse or keyboard or going up/down/left/right with voice), it is the same as not selecting anything, then the cursor will actually be on top of a character (and not between 2 characters like in insert mode). And so saying take this will select the token since it is an empty selection. Can be a bit misleading but I can get used to it

image

  • if we select 2 characters with the mouse, and issue ctrl+c, it saves 78 as expected

image

  • in order to select a single character with the mouse, it is actually doable by selecting 2 characters and then dragging back to 1 character. Then issuing ctrl+c saves 7

image

@saidelike saidelike mentioned this issue May 4, 2024
1 task
@auscompgeek auscompgeek added the app-neovim Issues related to neovim support label May 5, 2024
@saidelike
Copy link
Collaborator Author

Not sure they would be useful, but a few other functions that would allow selecting the range alternatively to select_range()

some of them were attempts to make it working in the terminal mode, but we don't need that anymore because we are actually switching to normal terminal mode before calling select_range()

-- https://github.com/nvim-treesitter/nvim-treesitter/blob/master/lua/nvim-treesitter/ts_utils.lua#L278
-- another example is :map <c-a> <Cmd>lua require("talon.cursorless").select_range2(4, 0, 4, 38)<Cr>
-- NOTE: works for any mode (n,i,v,nt) except in t mode
function M.select_range2(start_row, start_col, end_row, end_col, selection_mode)
  local v_table = { charwise = 'v', linewise = 'V', blockwise = '<C-v>' }
  selection_mode = selection_mode or 'charwise'

  -- Normalise selection_mode
  if vim.tbl_contains(vim.tbl_keys(v_table), selection_mode) then
    selection_mode = v_table[selection_mode]
  end

  -- enter visual mode if normal or operator-pending (no) mode
  -- Why? According to https://learnvimscriptthehardway.stevelosh.com/chapters/15.html
  --   If your operator-pending mapping ends with some text visually selected, Vim will operate on that text.
  --   Otherwise, Vim will operate on the text between the original cursor position and the new position.
  local mode = vim.api.nvim_get_mode()
  if mode.mode ~= selection_mode then
    -- Call to `nvim_replace_termcodes()` is needed for sending appropriate command to enter blockwise mode
    selection_mode = vim.api.nvim_replace_termcodes(selection_mode, true, true, true)
    vim.api.nvim_cmd({ cmd = 'normal', bang = true, args = { selection_mode } }, {})
  end

  vim.api.nvim_win_set_cursor(0, { start_row, start_col })
  vim.cmd('normal! o')
  vim.api.nvim_win_set_cursor(0, { end_row, end_col })
end

-- another example is :map <c-a> <Cmd>lua require("talon.cursorless").select_range3(4, 0, 4, 38)<Cr>
-- NOTE: works for any mode (n,i,v,nt) except in t mode
function M.select_range3(start_x, start_y, end_x, end_y)
  -- print('select_range()')
  -- print(('start_x=%d, start_y=%d, end_x=%d, end_y=%d'):format(start_x, start_y, end_x, end_y))
  local key = vim.api.nvim_replace_termcodes('<c-\\>', true, true, true)
  vim.api.nvim_feedkeys(key, 't', false)
  local key2 = vim.api.nvim_replace_termcodes('<c-n>', true, true, true)
  vim.api.nvim_feedkeys(key2, 't', false)
  vim.cmd([[normal! :noh]])
  vim.api.nvim_win_set_cursor(0, { start_x, start_y })
  -- vim.cmd([[normal v]])
  vim.cmd([[normal v]])
  vim.api.nvim_win_set_cursor(0, { end_x, end_y })
end

-- another example is :map <c-a> <Cmd>lua require("talon.cursorless").select_range4(4, 0, 4, 38)<Cr>
-- another example is :tmap <c-a> <Cmd>lua require("talon.cursorless").select_range4(4, 0, 4, 38)<Cr>
-- https://vi.stackexchange.com/questions/11893/exiting-back-to-normal-mode-in-terminal-buffer-from-vimscript
function M.select_range4(start_x, start_y, end_x, end_y)
  -- print('select_range4()')
  vim.cmd([[normal! <C-\><C-N>]])
  vim.api.nvim_win_set_cursor(0, { start_x, start_y })
  vim.cmd([[normal v]])
  vim.api.nvim_win_set_cursor(0, { end_x, end_y })
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
app-neovim Issues related to neovim support
Projects
None yet
Development

No branches or pull requests

2 participants