I'd like to have vim (after pressing Ctrl+]) look up tags containing special characters like $ or #. I can do it with the :tag command (e.g., tag $some$symbol) but it doesn't work with Ctrl+].
How can I configure what vim treats as an identifier?
Looking at :help CTRL-], it says:
CTRL-] Jump to the definition of the keyword under the
cursor. Same as ":tag {name}", where {name} is the
keyword under or after cursor.
From there, one might find :help 'iskeyword', or end up with :help word, which explains:
A word consists of a sequence of letters, digits and underscores, or a
sequence of other non-blank characters, separated with white space (spaces,
tabs, ). This can be changed with the 'iskeyword' option. An empty line
is also considered to be a word.
Therefore, you need to add $ to the 'iskeyword' option:
:setlocal iskeyword+=$
Making that permanent
The 'iskeyword' option is local to buffer, and many syntax scripts rely on correct settings for highlighting. Therefore, it's not recommended to change this globally for all filetypes (with :set, in your ~/.vimrc).
Instead, you should identify the (few) filetype(s) were you need this, and then define this only locally.
Put the corresponding :setlocal command into ~/.vim/after/ftplugin/{filetype}.vim, where {filetype} is the actual filetype (e.g. java). (This requires that you have :filetype plugin on; use of the after directory allows you to override any default filetype settings done by $VIMRUNTIME/ftplugin/{filetype}.vim.)
Alternatively, you could define an :autocmd FileType {filetype} setlocal iskeyword+=$ directly in your ~/.vimrc, but this tends to become unwieldy once you have many customizations.
Related
I often write LaTeX using Vim. And I have been taught that one can comment a number of selected lines (in visual mode) using the following command:
:'<,'>s!^!%!
And similarly, one may uncomment lines in visual mode by using this command:
:'<,'>s!^%!!
Here, '%' denotes the commenting symbol for LaTeX. But I would very much like to make a shortcut to make it easier for myself to use these commands. For instance a keybinding or some sort of function so that I do not have to remember this syntax. How does one do that?
First, there are several commenter plugins, that do this very well, and those are generic (and often extensible) so that they work for any filetype, not just Latex:
NERD Commenter plugin
tComment plugin
commentary.vim plugin
are just a few popular plugins.
Custom mapping
That said, it's a good learning experience to develop a mapping on your own. Here's how:
First, mappings are just instructions that when certain key(s) are pressed, Vim translates them into other keys (on the right-hand side). Your mapping is for visual mode, so the command is :vmap. What do you normally do? You select the lines to be commented, and press :; Vim automatically inserts the '<,'> for you. You write the :s command, and conclude by pressing Enter.
Translation:
vmap <Leader>c :s!^!%!<CR>
The <Leader> is a configurable, unused key, defaulting to backslash. So, your mapping is invoked by pressing \ and then C. Put that into your ~/.vimrc to make it permanent, and you're done. Wait! There's more.
Advanced mappings
First, you should use :vnoremap; it makes the mapping immune to remapping and recursion.
Second, that mapping is global, but it applies only to the Latex filetype. So, it should apply only to Latex buffers; there's the <buffer> modifier for that.
You can define that for certain filetypes by prepending :autocmd Filetype tex ..., and put that into your ~/.vimrc. But that gets unwieldy as you add mappings and other settings for various filetypes. Better put the commands into ~/.vim/ftplugin/tex_mappings.vim. (This requires that you have :filetype plugin on.)
vnoremap <buffer> <Leader>c :s!^!%!<CR>
Technically, you should use <LocalLeader> instead of <Leader>. They default to the same key, but the distinction allows to use a different prefix key for buffer-local mappings (only if you need / like).
Let's add the alternative mapping for uncommenting, triggered via \ and Shift + C:
vnoremap <buffer> <LocalLeader>c :s!^!%!<CR>
vnoremap <buffer> <LocalLeader>C :s!^%!!<CR>
Note that you could combine both into one, using :help sub-replace-expression with a conditional expression. If anything here is over your head, don't worry. You should be using one of the mentioned plugins, anyway :-)
When I type w as for next word in vim, vim decides what is a word by searching the character set set by command :set iskeyword+=. I want to specify this settings per file type, so when I have >>= in haskell, it is interpreted as a word, but when I have <td>Field</td> in html it is not a whole word.
How can I do this in vim?
If you only want to enable an option for certain filetypes, use :setlocal option=value instead, and put the corresponding :setlocal commands into ~/.vim/after/ftplugin/{filetype}.vim, where {filetype} is the actual filetype (e.g. java). (This requires that you have :filetype plugin on; use of the after directory allows you to override any default filetype settings done by $VIMRUNTIME/ftplugin/{filetype}.vim.)
Alternatively, you could define an :autocmd FileType {filetype} setlocal option=value directly in your ~/.vimrc, but this tends to become unwieldy once you have many customizations.
I've got a file (LaTeX) which contains lines I wish to comment out.
The regex that I use after visually-selecting the relevant block is :s/^/%/g, which works fine. However, vim then highlights every matching occurrence of the first part of the regular expression used in the replace, (highlights the first character on the beginning of every line).
The selection changes if I do another search, or another search-and-replace, but I can't work out how to turn it off without doing a 'useless' search.
It's particularly annoying if I search for whitespace (because having every '' highlighted in a text file is visually annoying).
How do I de-select the matching strings after the search-and-replace has been completed?
:nohlsearch will stop highlighting it but keep it as the active search pattern. (It will start being highlighted on n etc.)
:let #/="" will clear the search pattern register (so that n etc. won't work).
A common thing I've seen in Vim is map <Leader><Space> :noh<CR>; this has the result that (assuming the default leader, backslash) \Space will stop highlighting the current match.
Just search for a string that is not on the page:
/poop
:nohlsearch will remove highlighting from the current search. Highlighting will return on your next search.
:set nohlsearch will disable highlighting for your current vim session.
If you want to disable highlighting completely, add :set nohlsearch to your .vimrc
Add that to your vimrc, and once done - press in my case <,> + enter to stop highlighting
map <silent> <leader><cr> :noh<cr>
I have a bad habit of using the 'home' key to go back to the beginning of a line. As I recently started using vim I noticed that when I press the home key on a lined that is indented, it returns me to the very beginning of the line. In Notepad++ (the editor I used to use) it would return me to the beginning of the code on that line, right after the indent.
Is there some way to replicate this behavior in vim? Usually, when I'm pressing home it's in the Insert mode for me to (usually) stick a variable there.
I have set smartindent in my vimrc, with set noautoindent as a "tips" page told me to make sure to disable autoindent (although it didn't seem to be enabled in the first place - perhaps that option is extraneous.)
There are two usual ways to go to the "beginning" of a line in Vim:
0 (zero) go to the first column of text
^ go to the first non-whitespace on the line
I find that using 0w is usually the most convenient way for me to go to the first nonblank character on a line, it's the same number of keys as ^ and is easier to reach. (Of course, if there are no leading spaces on the line, don't press w.)
You could remap Home to be the same as ^ (the docs say Home's default function is equivalent to the movement command 1|):
:map <Home> ^
:imap <Home> <Esc>^i
Which should make the insert mode mapping be equivalent to escaping out of insert mode, pressing ^ and then returning to insert mode. I don't know about the best method of mapping a motion command for use inside insert mode, so this may break something, but it seems to work.
As to your indentation settings, they shouldn't have an effect on movement controls, but I also think you probably would prefer to have them set differently. autoindent just keeps your current indentation for new lines (so if you place 4 spaces at the beginning of a line, after you press return your new line will also have 4 spaces placed in front of it). I don't know why you wouldn't want that, since it's pretty useful in pretty much any programming language, or even just freeform text. smartindent on the other hand implements a couple of hard-coded lightly C-ish indentation rules, like indenting after an opening {, and deindenting after a closing }, but doesn't automatically carry over indentation from previous lines. The docs recommend keeping autoindent on if you use smartindent.
However, smartindent is useless for languages that don't meet its hard-coded rules, or even actively harmful (like when it automatically removes indentation from any line starting with a '#', which it thinks is a preprocessor directive but is wrong for python programmers trying to write an indented comment).
So vim also includes a more advanced indentation mode, filetype indentation, which allows flexible indentation rules on a per-language/filetype basis and is the preferred indentation mode for most people (even for C-like languages). If you do use filetype indentation, it's best to turn off smartindent (otherwise it can interfere with the filetype indentation, like moving all comment lines to column 0 in python files).
Personally, I always have autoindent on, use filetype when available, and never use smartindent. My .vimrc includes:
set autoindent " doesn't interfere with filetype indents, and is useful for text
if has("autocmd")
" Enable file type detection and indentation
filetype plugin indent on
set nosmartindent
endif
I imagine there's something you could do to have smartindent turned on only when filetype indenting doesn't exist for a filetype, if you're editing that many different C-like languages with no filetype indentation available.
Here’s what I have in my .vimrc. This maps Home to move to the beginning of the
text if you are anywhere in the line, and column 0 if you are at the beginning
of the text.
function ExtendedHome()
let column = col('.')
normal! ^
if column == col('.')
normal! 0
endif
endfunction
noremap <silent> <Home> :call ExtendedHome()<CR>
inoremap <silent> <Home> <C-O>:call ExtendedHome()<CR>
Note: I am using a keyboard layout that maps Home to Alt Gr+A, that why I’m using this. If you have to leave the letter field of your keyboard to reach Home, you should probably go to normal mode instead.
You could also use _ in Normal mode to go to the first non-whitespace character of the current line. You can also use a count with this motion.
_ <underscore> [count] - 1 lines downward,
on the first non-blank character linewise.
Try pressing 0 (also see :help 0)
also, this might help:
:imap <C-Home> <esc>0a
I used textmate to work with ruby code for over one year. Recently I switched to using mvim. When I open some of the files in mvim I get empty blocks. Look at this picture to get a feel for it.
Any idea on how to get rid of them?
Thanks
Others have explained that this could either be a search highlighting spaces or tabs or (more likely) it could be highlight designed to show up mixed indentation (particularly useful in python for what it's worth). I find this very useful personally.
Anyway, there are a number of options to sort out your highlighting depending on the cause:
To clean end of line spaces (as mentioned by chaos), use something like:
:%s/ \+//
Probably the most useful one: tidy up the tabbing:
If you're using spaces for indentation:
:set expandtab
:retab
If you're using tabs:
:set noexpandtab
:retab!
If you're using tabs for indentation and spaces elsewhere:
:set expandtab
:retab
:set noexpandtab
:execute '%s#^\( \{'.&ts.'}\)\+#\=repeat("\t", len(submatch(0))/'.&ts.')#'
I have the last line mapped to a command called :RetabIndents. All of those assume that your tabstop setting is correct (it should be set with set ts=2 based on your picture). Personally, I'd also recommend keeping shiftwidth equal to tabstop, so set ts=2 sw=2.
You may also be able to get away with a simple gg=G (auto-indent the whole file). However, this won't work in some languages (in particular python as there's no way for any editor to know which lines should be indented to which level).
To switch off search-based highlighting temporarily:
:noh
Or permanently (put this in .vimrc):
:set nohlsearch
Or a quick shortcut for when you've used it and don't want it anymore:
:nnoremap <ESC> :noh<CR><ESC>
To switch off indent highlighting, you'll have to identify which highlighting group is used, which is a little complicated and is probably easiest to just read your .vimrc, but if you really want to search for it, move the cursor to one of the highlighted characters and enter (taken from here):
:echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">"<CR>
You can then clear the highlighting group by searching for the name that is reported on the command line in your .vim/.vimrc/_vimrc/vimfiles configuration and commenting out anything relevant.
For more information
:help :s
:help 'expandtab'
:help :retab
:help :execute
:help 'tabstop'
:help :noh
:help 'hlsearch'
It's looks like highlighting of redundant whitespace (see line 214 for example)
Is there anything in your .vimrc along the lines of..
highlight RedundantSpaces ctermbg=grey guibg=grey
match RedundantSpaces /\s\+$\| \+\ze\t/
..try commenting it out, and seeing if this fixes the problem
I guess the reason it's highlighting the indentation is vim is configured to expect tabs, no spaces (or vice versa) - again make sure your .vimrc is setup correctly (say, using soft-tabs)
It looks like you might have a search pattern stored that highlights spaces at the beginning of the line: /^ + and your highlight color is light gray.
To get rid of it, try searching for something else: /asdf<ENTER>.
If you want to get rid of hanging spaces on the ends of lines (they always annoy the hell out of me, honestly), this command will strip them from a given file:
:%s/ *$//
As Seth mentioned, these are spaces. Essentially, mvim is showing you the spaces that are placed in your file by coloring them grey instead of black.
Personally, I think this is a feature, you can use this highlighting scheme to identify where you may have trailing spaces, and can use it to make your code look neater.
You could probably get it to go away by adjusting the highlighting options.