Keith Hanlan
Keith Hanlan

Reputation: 867

Vim - how can I use smartcase for / search but noic for * search?

I love smartcase and I love the * and # search commands. But I would prefer that the * and # search commands be case-sensitive while the / and ? search commands obey the smartcase heuristic.

Is there a setting hidden away somewhere that I haven't been able to find yet? I would rather not have to remap the * and # commands.

In summary: I want smartcase behaviour for / and ? but noic behaviour for * and #.

Thank you, Keith

Upvotes: 4

Views: 648

Answers (3)

RyanArr
RyanArr

Reputation: 93

Not exactly what you're looking for, but if you leave smartcase off and just prepend your / searches with \c when you want to ignore case, it's almost the same thing.

See the Case sensitivity section here

Edit: actually according to all the documentation I'm seeing what you want is the expected behavior, however testing it myself it looks like Vim is applying smartcase to * and # as well.

Upvotes: 5

Christian Brabandt
Christian Brabandt

Reputation: 8248

In summary: I want smartcase behaviour for / and ? but noic behaviour for * and #.

It is a bit tricky, since you do not exactly specify which of the options 'smartcase' and 'ignorecase' should apply for which commands. However note, that it is the default behaviour for the * and # commands to ignore the 'smartcase' option by default.

So perhaps setting :set smartcase noignorecase is already sufficient for you? Else you can be a bit more specific using CmdlineEnter and CmdlineLeave autocommands for the ? and / search commands:

:au CmdlineEnter /,\? :set noignorecase
:au CmdlineLeave /,\? :set ignorecase

(Something like this, adjust to taste). Note, this requires the CmdlineEnter and CmdlineLeave autocommands, that are only available in later 8.0 releases.

Upvotes: 3

Peter Rincker
Peter Rincker

Reputation: 45117

You can change the value of 'ignorecase' and 'smartcase' for * / # and for any ex-command and searching via / turn them back on via the CmdLineEnter autocmd event.

nnoremap <expr> * <SID>star_power('*')
nnoremap <expr> # <SID>star_power('#')
function! s:star_power(cmd)
    let [&ignorecase, &smartcase] = [0, 0]
  return a:cmd
endfunction

augroup StarPower
    autocmd!
    autocmd CmdLineEnter * let [&ignorecase, &smartcase] = [1, 1]
augroup END

Now if you do a * and then do any ex-command then the values of 'ignorecase' and 'smartcase' will change. This may not be desirable. You may want to do a getcmdtype() to restrict this to only / and ? modes or maybe maybe something more complex with CmdLineLeave and/or a timer.

Note: this requires a Vim 8.0.1206+ to support CmdLineEnter.

For more help see:

:h :map-expression
:h :let-&
:h :let-unpack
:h autocommand
:h :augroup
:h :autocmd
:h CmdLineEnter

Upvotes: 3

Related Questions