folke / flash.nvim

Navigate your code with search labels, enhanced character motions and Treesitter integration
Apache License 2.0
2.22k stars 27 forks source link

feature: Jump marks after <CR> to prevent accidental normal-mode input #314

Open x3rAx opened 4 months ago

x3rAx commented 4 months ago

Did you check the docs?

Is your feature request related to a problem? Please describe.

I really like the idea of having jump marks after I insert a search term but I regularly run into a situation where I want to search for something, the searched word does not exist and while I type my search, a jump mark with a matching character exists. What happens then is, that the cursor jumps to the jump mark and the rest of the keys I type get treated as normal mode keys.

For example consider an empty file:

What happens here is that there is no matching word house but after searching for h, a jump mark o exists. When typing o the cursor is moved to the position of that search result and the search exits. Then the next char u just issues undo and our precious sentence disappears. :sad

Describe the solution you'd like

Add an option that allows to show jump marks during search but only navigate to them after pressing the Enter key.

This solution is my favorite (compared to the alternatives below) since I believe it combines the best parts of both alternatives without real disadvantages:

The user would search for whatever they want to search and just as it is currently, the search marks will be shown. However, search marks will only be active after the user has hit the Enter key, indicating that their search is over.

By showing the marks during search, the user can already prepare for typing a jump mark letter after pressing Enter but they do not unintentionally end their search.

To get rid of the jump marks (in case the first result was already the one the user wanted to go to), I imagine the user can then either press Esc or just press Enter again.

One last thing: The think chars n and N should not be used for jump marks in this case. This allows the user to jump to the next / previous result as usual.

Describe alternatives you've considered

  1. Add a, configurable delay before showing jump marks (also hide them again when the user starts to type more characters that are not a jump mark character, then after the delay, show them again)
  2. Suppress keystrokes for a configurable time after moving the cursor to a jump mark (Esc could allow to skip the delay)

Alternative 1 would allow for searching anything without the "risk" of moving the cursor to somewhere unexpected but the user would have to wait for a moment for marks to appear.

Alternative 2 allows for jumping to the result directly but would prevent them from rapidly continuing to edit since they must wait for the delay. However, the delay could be skipped by pressing Esc for example, so the user just has to get used to pressing Esc after using a jump mark.

Additional context

I'm using the LazyVim config (thanks btw, I really love it :heart:)

OS: NixOS

$ nvim --version
NVIM v0.9.4
Build type: Release
LuaJIT 2.1.1693350652

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "
/nix/store/g8ywwhvf14qywy1zfg1fqyzylw4jj81x-neovim-unwrapped-0.9.4/share/nvim
"
artfulrobot commented 4 months ago

+1 I love this plugin, but I keep destroying my code because I hit a label by accident, or the search terminates early and I don't notice.

This happens when I mistype a search; or search for something that doesn't exist. e.g. if I have text like windows7 in my document and I search windowsxp then I've quietly transpsoed :rofl: two characters; I might not notice I've done it.

I like the idea of needing to press Enter to use the labels.

I also think that when a search doesn't match anything, the search mode should not be terminated. My ideas for what happens when the pattern doesn't match (no idea what is achievable)

  1. you can continue typing the pattern, but (obvs) there's nothing highlighted - as without this plugin.
  2. as 1 but the command prompt goes red, or, better, the bits that don't match go red.
  3. your extra keystrokes are not shown: I don't like this one because it means your search for house finds houston.

Incidentally, my workaround for this at the mo is:

{                                                                                                                                                  
  "folke/flash.nvim",
  ...                                                                                                                                      
  keys = {                                                                                                                                                                                    
    { "g/", mode = { "n", "x" }, function() require("flash").toggle(true); vim.api.nvim_feedkeys('/', 'n', true) end, desc = "Start Flash Search" }
    { "/", mode = { "n", "x", "v" }, function() require("flash").toggle(false); vim.api.nvim_feedkeys('/', 'n', true) end, desc = "Normal search" }
  },                                                                                                                                               
},                                                                                                                                                 

Which means / works as vanilla search, and g/ triggers a flash-enabled search.

Obviously I could just try to get used to flash-search all the time, but I've been using vim for many many years (omg it's decades, how did that happen!)

vinoff commented 4 months ago

I am having this exact same issue, it is infuriating.

I also couldn't find an easy way to disable flash search all-together. Is it not possible to disable flash search while having enabled "normal" flash?

EDIT: For those wanting to disable, like me, here is how you do it:

            modes = {
                search = {
                    enabled = false,
                },
            },
bbinet commented 3 months ago

I'm also regularly facing this annoyance, and I think the suggestion from @x3rAx would be great to avoid jumping by mistake.

We could also imagine using a modifier (Control or Alt) instead of the Enter key to actually jump to a letter only when the modifier was used. What do think?

bbinet commented 3 months ago

It seems that this feature is already there using trigger config : see #254 Or see <C-s> alternative is #256

x3rAx commented 3 months ago

The trigger config seems to be what I want, but I can't get it to work with <CR>. For example, if I set it to a, I can type my search, press a, press the label, and the cursor jumps to the search result, but if I set it to <CR>, as soon as I hit enter, the search ends, the labels disappear, and the first result is selected.

The <C-s> method is not an option because it a) toggles the labels on/off for all subsequent searches and b) adds an extra delay where I have to recognize the label character before I can type it. What I mean by a) is that if I start a search with labels disabled, then press <C-s> to display the labels, and press the label to accept a search result, the labels are still enabled for the next search. So I'd have to disable them first when I start my next search => I'd have to type /<C-s>my search term<C-s>b (where b is the label) for each search.

x3rAx commented 3 months ago

After just 5 minutes I've encountered an issue with the trigger option: I've now set it to ; because I figured that this is a character that I do not often type into a search. However, when the search result is not currently visible, the editor scrolls down to the first match and displays the labels. When I then press ;, the editor jumps back up to the position it was before (since it still uses the ; as search input and now does not find any match with trailing ;). When that happens, all jump labels are gone.

avegancafe commented 3 months ago

I'm not gonna lie, I'm not 100% sure how people use this plugin as it's implemented without this feature haha. Do people just type their searches really really slowly? I'm constantly accidentally mutating my code with this plugin installed.

For example, in normal mode if I run a search with /logStruct, and the pattern lo doesn't match anything, after I type the g in the search, flash will terminate search mode and will send the rest of the query to normal mode, which when typing Struct in normal mode clears my entire line I'm on, and inserts truct instead. That seems... odd

avegancafe commented 3 months ago

That being said, I just tried this again and I swear to god that used to be the behavior and it's since changed 😱

vinoff commented 3 months ago

That being said, I just tried this again and I swear to god that used to be the behavior and it's since changed 😱

What used to be the behavior and what is the behavior now? Because I am still having the issue you mentioned, i.e., can't use the search function of this plugin.

avegancafe commented 3 months ago

@vinoff before, if I was typing a search query that didn't match anything, as soon as I typed a letter that would result in no results being shown, flash.nvim would exit search mode and go back to normal mode and just start sending the rest of the search query as normal mode commands. This is of course super frustrating, as I would constantly accidentally modify my code when I was trying to search for something that didn't exist in the current buffer.

Now, it works as I would have expected-- if I search for something that doesn't exist in the buffer, I can still use labels while partially filling out the query that does match, but it doesn't quit and go back to normal mode even after running a query that doesn't match anything

pejrich commented 2 months ago

@avegancafe The behavior you describe is now it works for regular search /, but not how it works for flash jump s(in the readme). / will just continue entering your keypresses into the search, but s/jump will terminate once a letter fails to continue a valid search, and put you in normal mode, either where you are, or after a jump if your typo also happens to be a jump label.

avegancafe commented 2 months ago

Well alright then haha, I guess this plugin just isn't for me then. Thanks @pejrich !

mycf commented 2 months ago

好吧,哈哈,我想这个插件不适合我。谢谢@pejrich!

can help you


      vim.api.nvim_create_autocmd("CmdlineEnter", {
        pattern = "*",
        callback = function()
          require("flash").toggle(false)
        end,
      })

      vim.api.nvim_create_autocmd("CmdlineLeave", {
        pattern = "*",
        callback = function()
          require("flash").toggle(true)
        end,
      })
sid-6581 commented 1 month ago

@avegancafe The behavior you describe is now it works for regular search /, but not how it works for flash jump s(in the readme). / will just continue entering your keypresses into the search, but s/jump will terminate once a letter fails to continue a valid search, and put you in normal mode, either where you are, or after a jump if your typo also happens to be a jump label.

I worked around the accidental jump thing by switching to only uppercase labels for searches, but I haven't found a solution for terminating the search once there are no matches, in non-search modes. Is that possible? I'd prefer to be able to backspace and correct potential mistakes instead of having to start the search all over again.