I'm using the awesome https://github.com/tpope/vim-surround plugin to surround words with parenthesis, for example I often use: viws<space><space> to surround a word with spaces.
What I'm missing is the opposite of this, that is, deleting surrounding spaces around a word.
The most common use for me is function arguments like
foo(bar) vs foo( bar ) depending on code style.
Does anyone know a nice way to do this?
Note: This solution requires the surround plugin referenced in the question.
For your specific situation you could do the following:
cs()
This changes foo( bar ) to foo(bar), however, it is not a general solution to your problem.
I often productively procrastinate in search of vim plugins too, when I could just define a mapping for this.
nnoremap <leader>dd F<space>xf<space>x
EDIT more information
<leader> common key for user defined mappings (, is a good one)
dd combination to use (any other mnemonic one will suffice)
F<space>x search backwards for a space, then remove it
f<space>x search forwards for a space, then remove it
Maybe just BXElx in normal mode.
In fact, perfect solution for me is the mapping provided by #puk, but using the keys #sarnold expected in the first place (what one would expect from surround plugin if it implemented this).
This is:
nnoremap ds<space> F<space>xf<space>x
Related
I'm trying to duplicate the functionality in vim of IDEs like IntelliJ that do the following, letting | be the cursor:
I type an open paren: (
It automatically closes it and puts my cursor in the middle: (|)
I type some text in the middle: (Some text here|)
I type a close paren, and rather than inserting a close paren, it simply moves my cursor over the already inserted one: (some text here)|
I have the following set of remappings that duplicate the functionality of 1-3 and when I just type ():
inoremap ( ()<Esc>i
inoremap () ()<Esc>i
It seems I need a way to detect if the character after my cursor is a ) in order to make a function to do what I want in 4. Does vim support this?
There are many pitfalls to implement this functionality properly; several plugins have attempted to do this. At least you should check them out to learn what they did; maybe one of them already fulfills all of your requirements! You'll find a complete discussion of implementation details, and a list of plugins at Automatically append closing characters.
I don't believe you can do this through a simple map since you would need to incorporate some conditional logic to decide when and when not to add the closing parenthesis. Instead, you would have to define a function to do the heavy lifting and then map the closing parenthesis to call the function. Vim's help has some information about functions, but I've found this page to be an invaluable resource: http://learnvimscriptthehardway.stevelosh.com/
That said, there are number of vim plugins out there that already perform this type of functionality. The one that I use is called "auto-pairs" and can be found here: https://github.com/jiangmiao/auto-pairs. As a bonus, you can see the code if you're actually interested in how it works as opposed to just being interested in having the functionality itself.
Try this code
inoremap <expr> ) getline('.')[col('.') -1] == ')' ? "\<Right>" : ')'
But I recommend to use plugin, because such settings make your vimrc in confusion.
I like vim-smartchr and vim-smartinput
https://github.com/kana/vim-smartchr
https://github.com/kana/vim-smartinput
How to set the abbreviation for a specific word that contains special character like ":,;'." etc., for instance, I want to set an abbreviation for std::map to std::map
:ab std::map std::map<string,int>
is not working
The abbreviation trigger text has restrictions: it has to be of either full-id, end-id, or non-id type (basically, which characters are keywords; see :help abbreviations for details).
For the C / C++ filetypes, the colon : normally is not part of 'iskeyword', that's causing the E474 error. As it's not recommended to mess with that setting (it affects navigation, syntax highlighting, etc.), you have to drop / replace it from the abbreviation:
:ab stdmap std::map<string,int>
The solution I proposed in Using backslashes in vim abbreviations should be adaptable to your case. You will have to adapt the test getline('.')[col('.')-2]=='\' to something like getline('.')[:col('.')-2] =~ '.*std::$' (untested)
But, honestly, you should consider using a snippet engine instead, there are plenty.
I'm writing a lot of RST lately and I would like the % keystroke to match between grave accent (i.e. backtick) characters.
`The cursor is at the |vertical line`
and then hitting % moves the cursor as shown
`The cursor is at the vertical line|`
I have tried setting the b:match_words for the matchit plugin but that doesn't help.
Any tips appreciated.
Forgive me for tooting my own horn, but I am an expert on the matchit plugin.
Although it is designed to extend the built-in matching functionality, matchit extends it in several ways. For one, it allows you to match regular expressions, not just single characters. You can get very good results by using vim's start-of-word and end-of-word patterns:
:let b:match_words='`\<:\>`'
This certainly works on the one-line example you gave. Similarly, you might decide that the starting ` usually does not have a non-whitespace character before it, and the closing one is not followed by a non-whitespace character. (If that is too many negatives, then "This is markup" usually starts a new line or follows a space or tab; and it is usually followed by the end of a line or a space or tab.) Then you could use
:let b:match_words='\S\#<!`:`\S\#!'
The matchit plugin tries to live up to vim's design goals, including :help design-documented. The standard vim distribution includes both matchit.vim (the script) and matchit.txt in $VIMRUNTIME/macros/. You can either read the documentation there or follow the instructions at :help matchit-install and browse the documentation with :help.
Under :help b:match_words, it says,
Tips: Be careful that your initial pattern does not match your final pattern.
This is because, when you bang on the % key, the script has to be able to figure out whether it is on the starting pattern or the ending pattern. The only information it has to make this decision is what you have told it in b:match_words.
The matchit plugin is designed to work similar to the built-in % command and as such suffers some of the same limitations. In particular, from :help 'matchpairs':
Only character pairs are allowed that are different, thus you cannot
jump between two double quotes.
Thus, this works as expected (but not as you want):
:let b:match_words="`:'"
But this does not work:
:let b:match_words="`:`"
For some suggestions how to pair identical delimiters with matchit in common prose or markup files, such as rst, see my repository.
I can't get "â" to be written. I can write "Â" though (carrot + capital A).
Any other accent can be written as in any other text editor.
Any suggestions?
Thank you in advance.
You may want to look at the :digraph comamnd in Vim. It will show you the combinations to use with <C-k> to make accented characters. In your case, you want <C-k> followed by a>.
Note: <C-k> means "Control + k" whereas a> means the letter "a" followed by a ">" (greater than sign).
If you are using a latin keyboard layout and are unable to directly type the accented character, check if there is any mapping using it:
:verbose imap â
If so, just remap the command to another key.
<C-K>a^ works for me in Vim 7.3.
You could use digraphs, as pointed out on other answers. But this kind of diacritical character is very common on some languages. If that is true for you, you could set the keymap option:
:set keymap=accents
The list of characters added by this option can be seen in $VIM\keymap\accents.vim.
That being said, this should be working without this option. It is possible that you are with some problem with the value your 'enconding' option, as mentioned here.
First look at digraphs, as mentioned before.
But just to be thorough, and because I haven't seen it mentioned yet, note that any unicode character at all can be inserted via <C-v>uXXXX<cr> (where XXXX is the hexadecimal code point number of the character.) More on this at :help i_^v
For a list of code point values for different characters, try:
https://en.wikipedia.org/wiki/List_of_Unicode_characters
Or use a handy Perl script called unum, which lets you search characters by name, and other fun stuff.
EDIT: markup fix
running VIM-7.0.237 on CentOS-5.6. I have a large C code base with tags generated with ctags-5.6, there are functions with the same name defined in several places and I remember back when I used vim-6.3, I could jump over those multiple definitions easily -- VIM used to suggest me what definition I want to jump at. Now with vim-7 it gives me only first.
Is there a way to have a old-style behavior? Thanks.
PS. I have a default VIM configuration.
You can either precede the command with a count to jump to a specific match or use
:ts {identifier}. It will list the tags available for the given identifier.
You may find the ctrlrctrlw command
(et similars) useful to insert the word under cursor. A map may help you with
it.
nnoremap \] :ts <c-r><c-w><CR>
Use g] (g$ on french azerty keyboards) to display a list of definitions.