nvim-telescope / telescope.nvim

Find, Filter, Preview, Pick. All lua, all the time.
MIT License
15.43k stars 824 forks source link

Unable to paste multiline text into telescope's input box #2882

Open shibisuriya opened 7 months ago

shibisuriya commented 7 months ago

Description

I have copied a multiline text using 'yit', this yanks everything that is written within a

in my case... I want to search the content using telescope to know if this piece of code exists somewhere else as well in the codebase or not... I am using kickerstarter.nvim btw.

Neovim version

NVIM v0.9.4
Build type: Release
LuaJIT 2.1.1700008891

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/opt/homebrew/Cellar/neovim/0.9.4/share/nvim"

Run :checkhealth for more info

Operating system and version

macos montery v12.5

Telescope version / branch / rev

    version 0.1.5         tag     0.1.5         branch  0.1.x

checkhealth telescope

==============================================================================
telescope: require("telescope.health").check()

Checking for required plugins ~
- OK plenary installed.
- OK nvim-treesitter installed.

Checking external dependencies ~
- OK rg: found ripgrep 14.0.3
- WARNING fd: not found. Install [sharkdp/fd](https://github.com/sharkdp/fd) for extended capabilities

===== Installed extensions ===== ~

Telescope Extension: `fzf` ~
- OK lib working as expected
- OK file_sorter correctly configured
- OK generic_sorter correctly configured

Steps to reproduce

Expected behavior

No response

Actual behavior

I want be able to search multiline text that was copied using telescope.nvim.

Minimal config

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvim/site]]
local package_root = '/tmp/nvim/site/pack'
local install_path = package_root .. '/packer/start/packer.nvim'
local function load_plugins()
  require('packer').startup {
    {
      'wbthomason/packer.nvim',
      {
        'nvim-telescope/telescope.nvim',
        requires = {
          'nvim-lua/plenary.nvim',
          { 'nvim-telescope/telescope-fzf-native.nvim', run = 'make' },
        },
      },
      -- ADD PLUGINS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
    },
    config = {
      package_root = package_root,
      compile_path = install_path .. '/plugin/packer_compiled.lua',
      display = { non_interactive = true },
    },
  }
end
_G.load_config = function()
  require('telescope').setup()
  require('telescope').load_extension('fzf')
  -- ADD INIT.LUA SETTINGS THAT ARE _NECESSARY_ FOR REPRODUCING THE ISSUE
end
if vim.fn.isdirectory(install_path) == 0 then
  print("Installing Telescope and dependencies.")
  vim.fn.system { 'git', 'clone', '--depth=1', 'https://github.com/wbthomason/packer.nvim', install_path }
end
load_plugins()
require('packer').sync()
vim.cmd [[autocmd User PackerComplete ++once echo "Ready!" | lua load_config()]]
jamestrew commented 7 months ago

Hmm.. the prompt buffer is using buftype='prompt' and by design it only works on a single line basis. What you're trying to do is probably possible if all newline characters were converting to their escape characters on paste. This would require overwriting the default paste behavior.

But still live_grep (which is what I assume you're trying to use), doesn't support multi-line search by default. You can pass an option to enable it but i don't know how common of a need something like this is...

Also what is command+v? is that p remapped?

shibisuriya commented 7 months ago

1) I don't know if I have remapped command-v to p, but pressing the 'p' key pastes the text in the default register to the buffer.

2) What is the way to convert all newline character line to their escape sequence equalient when pasting text into telescope input?

3) I understand that it doesn't work by default, I would like to know what settings should I apply to telescope.nvim to make this possible.

Thank you.

shibisuriya commented 7 months ago

I am using kickerstarter.nvim, this is my config => https://github.com/shibisuriya/nvim/blob/main/init.lua, I have just made slight config to kickerstarter.nvim...

jamestrew commented 7 months ago

What is the way to convert all newline character line to their escape sequence equalient when pasting text into telescope input?

This doesn't exist in telescope. Maybe we can add it? I don't feel strongly about it. But it seems like p to paste into the prompt buffer has some quirks to it due to how vim handles prompt buffers so I'm feeling a little shaky about building things around the idea of pasting into the prompt buffer.

I understand that it doesn't work by default, I would like to know what settings should I apply to telescope.nvim to make this possible.

With live_grep and grep_string, you can pass --multiline to the additional_args option for those pickers. :h telescope.builtin.live_grep

shibisuriya commented 7 months ago

I am using this...

vim.keymap.set('n', 'fg', function() require('telescope.builtin').live_grep({ additional_args = function() return { "--multiline" } end }) end, { desc = '[S]earch by [G]rep' })

Doesn't work...

jamestrew commented 7 months ago

Can you be more descriptive about what's not working? Remember, you still can't just paste a multiline block into the buffer. But --multiline will let you search like foo\nbar

otomist commented 6 months ago

Running into the same issues. Can't seem to paste using os clipboard or p in normal mode. Would love to see this feature!

shibisuriya commented 6 months ago

@jamestrew image Technically the function\n should grep the two entires in the file... But it doesn't...

shibisuriya commented 6 months ago

Is there any work around for this, I feel like this is a very basic and essential function for any text editor....

I am unable to copy a bunch of html lines from chrome's inspect and search for them in the codebase... I am switching to vs code for this purpose then coming back to nvim to continue work...

jamestrew commented 6 months ago

@jamestrew image Technically the function\n should grep the two entires in the file... But it doesn't...

you need to escape the parentheses. function\(\)\n. This works for me with --multiline.

jamestrew commented 6 months ago

With the way telescope uses a prompt-buffer, this isn't a trivial problem for telescope I think. We're kind of limited to a single line prompt, which disallows literal newlines (need to convert \n to \\n) but interaction between --multiline and --fixed-strings (to allow for not escaping regex special chars), creates a ton of compatibility issues.

I think we can have a workaround for pasting, but the multiline search is a bit tricky to get cleanly currently.

Not saying this won't ever be possible with telescope but there might be existing neovim plugins that handle this workflow better. Sorry.

jamestrew commented 6 months ago

workaround for pasting

require("telescope").setup({
  defaults = {
    mappings = {
      n = {
        ["p"] = function(prompt_bufnr)
          local current_picker = action_state.get_current_picker(prompt_bufnr)
          local text = vim.fn.getreg('+'):gsub("\n", "\\n") -- which register depends on clipboard option
          current_picker:set_prompt(text, false)
        end,
      },
    },
  },
})
ArnaudDelgerie commented 2 months ago

@shibisuriya @jamestrew I don't think it's a good way, but it works.

local function live_grep_visual()
    local saved_reg = vim.fn.getreg('a')
    local saved_regtype = vim.fn.getregtype('a')

    vim.cmd('normal! "ay')
    local text = vim.fn.getreg('a')
    vim.fn.setreg('a', saved_reg, saved_regtype)

    require('telescope.builtin').live_grep({
        additional_args = {'--multiline'},
        default_text = text:gsub('\n', '\\n'):gsub('([%(%).%%%+%-%*%?%[%]%^%$%\\%{%}%|])', '\\%1'):gsub('\\\\n', '\\n'),
    })
end

return {
    'nvim-telescope/telescope.nvim',
    tag = '0.1.8',
    dependencies = {'nvim-lua/plenary.nvim', 'sharkdp/fd'},
    config = function()
        vim.keymap.set('v', '<leader>ft', live_grep_visual, {noremap = true, silent = true})
    end
}

With this solution you can select one or more lines in visual mode and search for them using <leader>ft. The "--fixed-strings" option is not used, but all "special characters" are escaped. The only "problem" is that if you perform a search containing 3 lines, the result will appear three times. By the way, if anyone has a solution to group these three results into one, I'm interested.

sorry for my bad English

shibisuriya commented 1 month ago

Thank you @ArnaudDelgerie!! This works, but it is becoming annoying when I am working on a huge codebase, if my search query contains 3 lines of text, the same result is appearing thrice...

shibisuriya commented 1 month ago

@jamestrew is there any way to convert 3 results into 1? Also are there any plugins that your recommend for this workflow alone (searching multi line strings in a codebase)...

jamestrew commented 1 month ago

@shibisuriya

is there any way to convert 3 results into 1?

there is, I think this PR will address this but it's been pending a neovim 0.2 release so it won't be available for a while I don't think https://github.com/nvim-telescope/telescope.nvim/pull/2536

Also are there any plugins that your recommend for this workflow alone (searching multi line strings in a codebase)...

I'm not aware of any that will let you just paste a multiline text into a search. Maybe try grug-far? This issue might have some answers https://github.com/MagicDuck/grug-far.nvim/issues/198