Kakoune: Case insensitive incremental search

Created on 23 Mar 2018  ·  13Comments  ·  Source: mawww/kakoune

Inserting a (?i) expression every time before the search condition makes it ugly.
Could you add a config option to use case insensitive (or smart case would be even better) search by default?

Most helpful comment

@aver-d's idea is going to be tricky to implement because hooks do not "return" anything.

I think my ideal way to solve that problem would be to have the prompt command powerful enough so that you could use it to trigger search while still keeping incremental support. Currently it will work for non incremental search (:prompt case-insensitive-search: %{execute-keys "/%val{text}<ret>"}) but that will fail for incremental use cases (And quick testing triggered some crashes that I need to investigate).

All 13 comments

(?i) is the preferred way, and its insertion can easily be automated by mapping / to /(?i). I tend to limit options that might change default behaviour to things that are arguably filetype specific (like additional word characters), user preferences should not be able to change the meaning of basic commands if we want scripting to be predicitible.

Smart case search would nice, and I think it could make sense to bake that into the regex engine, now that we have full control of it.

What about having a search command that would open the search prompt, but it could accept options like -case_insensitive, or -smartcase? This wouldn't modify the behavior of the /, <a-/> etc. keys.
This could also temporarily override the incremental search settings with an -incremental=true/false switch.

Another possibility would be to have bindings to toggle these options when a regex prompt is open. For example, <c-i> toggles case insensitiveness, <c-n> toggles dot-matches-newline...

You get consistent scripting, without the ugliness of prepending flags to the regex itself.

There's also:

map global prompt <tab> (?i)

It will insert (?i) when tab is hit, the only thing is that it will do that for any prompt, not only the regex ones.

@lenormf It is ugly and less readable. Also, there is another problem with bindings that inserts (?i) in the prompt. I use fast keyboard autorepeat. If I notice that I messed up the regex, and I want to delete and start again, I can't press backspace for a longer time, because it would delete the regex flag also, and in that case, I would have to type it in again, or exit search mode, and restart (or press Tab - if it is only deleted partially: (?, it don't work, only the two other solution) (so where is the ”faster in less keystrokes” slogan?).

I think a BeforeRegexCompile hook would be helpful.

The general idea would be that each time the search/select input changes, the user would have an opportunity to perform some transformation to whatever is typed at the command line – perhaps in a command passed %val{regex}, with an updated regex then being set in some way.

(?i) could be prepended, or checked for uppercase to do smart case, or wrapped as \Q%val{regex}\E. The transformed form of an accepted regex would remain in history, but it was originally written in a clean way.

But the hook would also allow people to explore using their own interesting transformations for which it'd be awkward or impossible to put into endless config variables. A simple example might be normalization of Latin characters a -> [aäáàå].

I still dont see what the problem is here, is it just that you dont want (?i) to be part of the regex ? Autoinserting it is easy, so I do not think this would be a problem. And I am not keen on adding a new feature to provide something we already have.

map global / /(?i) is all you need to enable case insensitive search by default. Adding a search command would go against Kakoune's design, as searching is clearly normal mode's responsibility, not command mode, and eventual control of the default search regex content can easily be achieved with a user mode:

declare-user-mode search
map -docstring "case insensitive search" global search i '/(?i)'
map -docstring "case sensitive search" global search I '/'
... whatever other search modes you'd like
map global normal / ':enter-user-mode search<ret>'

@mawww The only problem with (?i) is that (as I wrote above) I have to care to not to delete it when I delete from the prompt. So it requires more keystrokes. So it breaks the less keystrokes concept.
A search command could be mapped to keys.

What do you think about @aver-d's idea?

@aver-d's idea is going to be tricky to implement because hooks do not "return" anything.

I think my ideal way to solve that problem would be to have the prompt command powerful enough so that you could use it to trigger search while still keeping incremental support. Currently it will work for non incremental search (:prompt case-insensitive-search: %{execute-keys "/%val{text}<ret>"}) but that will fail for incremental use cases (And quick testing triggered some crashes that I need to investigate).

@mawww Implementing it with an enhanced prompt command also seems good.
Maybe with a PromptKey hook?

Could we close this?

Could someone summarize the current state of this question? Is map global / /(?i) still the best approach?

I believe this solves all the issues raised here:

# 1. Case-insensitive search by default:
# Just insert "(?i)" when opening the search prompt
map global normal "/" "/(?i)"

# 2. Change to case-sensitive search:
# Hit <c-u> to delete "(?i)" in the prompt

# 3. Deleting search query while keeping case-insensitive search:
# Map a key, in this example "<c-U">, to clear the prompt and re-insert "(?i)"
map global prompt "<c-U>" "<c-u>(?i)"

EDIT: You can also specify search-only mappings by doing something like this:

define-command mysearch %{
  map window prompt "<c-y>" "do what you want here"
  execute-keys "/"
  hook -group mysearch -once window ModeChange pop:prompt:.* %{
    unmap window prompt "<c-y>"
    remove-hooks window mysearch
  }
}

map global normal "/" ": mysearch<ret>"
  • Map whatever keys you want using map window prompt ..., and then unmap them in the hook.
  • Customize the default behavior of search by changing the execute-keys line (e.g. change it to "/(?i)")
Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexherbo2 picture alexherbo2  ·  3Comments

valerdi picture valerdi  ·  4Comments

radare picture radare  ·  3Comments

lenormf picture lenormf  ·  4Comments

alexherbo2 picture alexherbo2  ·  4Comments