Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In vim, is there a way to set "very magic" permanently and globally?

Tags:

vim

I use "very magic" for regexp searches (i.e. /\v or %s/\v) but I wish I could set some option so I don't have to include \v anymore, anywhere. Is there a way to do this?

like image 585
bgaluszka Avatar asked Sep 21 '10 12:09

bgaluszka


3 Answers

Not directly, however you can always use a mapping:

:nnoremap / /\v
:cnoremap %s/ %s/\v

Even if you could set 'very magic' in the way you can set nomagic, you really wouldn't want to as it would break pretty much every plugin in existence.

Edit

See also this page.

like image 135
DrAl Avatar answered Nov 16 '22 16:11

DrAl


EDIT2: I just discovered this plugin, which may be better than the remapping solutions (which seem to have some unavoidable drawbacks; see below). I haven't tested it yet, though, so I don't know if it behaves exactly as desired.

http://www.vim.org/scripts/script.php?script_id=4849

EDIT3: I've been using the plugin for about a year and a half, and I love it. It still interferes with search history, however (see below), and it also breaks incsearch, so I have the following in my Vim config:

" Since I use incsearch:
let g:VeryMagic = 0
nnoremap / /\v
nnoremap ? ?\v
vnoremap / /\v
vnoremap ? ?\v
" If I type // or ??, I don't EVER want \v, since I'm repeating the previous
" search.
noremap // //
noremap ?? ??
" no-magic searching
noremap /v/ /\V
noremap ?V? ?\V

" Turn on all other features.
let g:VeryMagicSubstituteNormalise = 1
let g:VeryMagicSubstitute = 1
let g:VeryMagicGlobal = 1
let g:VeryMagicVimGrep = 1
let g:VeryMagicSearchArg = 1
let g:VeryMagicFunction = 1
let g:VeryMagicHelpgrep = 1
let g:VeryMagicRange = 1
let g:VeryMagicEscapeBackslashesInSearchArg = 1
let g:SortEditArgs = 1

I used DrAI's suggestion for a while, but found it frustrating in practice because of the following behavior:

If you type the following: /{pattern} :%s//{replacement}

...then, without this mapping, you can see what you're about to replace before you do a replacement. But with the remapping, you suddenly have s/\v/ instead of s//; this matches eveything in the file, which is obviously wrong.

Fortunately, the s command itself has an alternative form that uses very magic for its search. So here are the mappings I'm currently using in my .vimrc:

nnoremap / /\v
vnoremap / /\v
cnoremap %s/ %smagic/
cnoremap >s/ >smagic/ 
nnoremap :g/ :g/\v
nnoremap :g// :g//

Note that just mapping s/ leads to problems when attempting to use a pattern that ends in s; similarly, mapping g/ would create problems when using patterns ending in g. Note that the :g/ and :g// mappings prevent Vim from showing the command immediately.

EDIT: Unfortunately, there does not appear to be a "magic" version of :global, which is why the seemingly-superfluous mapping of :g// is used to ensure that the global command can use the previous search pattern.

Another drawback is that these remappings interfere with search history. As an example, consider using * to search for the next occurrence of the word under the cursor. This causes Vim to search for the pattern \<[word]\>, which does not start with \v. Without the remappings described above, typing / and pressing the up arrow will recall that search pattern. With the remappings, however, after typing /, you must delete the automatically-inserted \v before pressing the up arrow in order to recall that pattern.

like image 36
Kyle Strand Avatar answered Nov 16 '22 17:11

Kyle Strand


To reply to the answer above as I can't comment yet, from How to make substitute() use another magic mode?, the vim docs and my own testing, smagic (and sm) only enters magic mode and not very magic mode.

                        *:snomagic* *:sno*
:[range]sno[magic] ...  Same as `:substitute`, but always use 'nomagic'.
            {not in Vi} 

                        *:smagic* *:sm*
:[range]sm[agic] ...    Same as `:substitute`, but always use 'magic'.
            {not in Vi}

For example, one should ('s turn into )'s in a file with :%sm/(/)/g and not :%sm/\(/\)/g, which shows the following for me

E54: Unmatched \(
E54: Unmatched \(
E476: Invalid command

Instead, to enter very magic mode, one should use \v in the search expression of substitute (i.e. :%s/\v\(/\)/g) (Please correct me if I've messed up, I am quite new to Vim)

like image 1
Anonymous Avatar answered Nov 16 '22 16:11

Anonymous