Recently I was searching for a fuzzy-finding plugin to make working with projects a little easier. I posted a quick hack that I still use every now and then, however I’ve recently discovered a rather new plugin called CtrlP.
For the uninitiated, fuzzy-finding plugins allow you to open a file by only typing enough pieces of the path to uniquely identify a file. Sometimes this is as little as one or two characters. I wasn’t really sold on this behavior until I tried using them at work where we have many files with similar names. A plugin like this makes dealing with such situations much easier to deal with than tab-completion alone.
CtrlP is written entirely in vimscript. This is a big plus for me because many of the machines at work aren’t built with +python or +ruby which some of the other fuzzy-finding plugins require. Although it’s written in vimscript it caches directory and filenames for larger directories and can be configured to always use a cache. This means it’s quite slow on first launch in larger directories but is very fast on subsequent calls.
Another big plus is the configurability CtrlP offers. There are (currently) 22 options provided to configure everything from mappings to how caching should work. You can even delegate the file indexing out to a faster external mechanism if you so choose.
Couple all of this with an active and responsive developer that provides excellent documentation and you’ve got my current favorite script.
Published on September 12, 2011 Comments
· · ·
I’ve never liked the fact that vim doesn’t allow users to define
commands that start with a lowercase letter. Every time I create one I
end up having to also make a cnoreabbrev that lets me use my lowercase
version. This has the ugly side effect of having text transform as you
type. It also will make the cursor jump around if you’re doing more
than changing the case of things. For example:
cnoreabbrev ack ack<c-\>esubstitute(getcmdline(), '^ack\>', 'Ack!', '')<enter>
This allows me to type “:ack ” and have it automatically change to
“:Ack! ” as soon as I press <space>. The text changes automatically
and my cursor jumps to the right two spaces instead of just one.
Obviously this is a small inconvenience but it is an annoying one for
me.
I have come up with a bit of a hacky workaround for this that allows more transparency and I thought I’d share in case someone out there is as stubborn as me. The following function will run a substitution on the current command line:
function! CommandLineSubstitute() let cl = getcmdline() if exists('g:command_line_substitutes') for [k, v] in g:command_line_substitutes if match(cl, k) == 0 let cl = substitute(cl, k, v, "") break endif endfor endif return cl endfunction
This function reads search/replace pairs from a global variable you set
in your .vimrc. That global variable looks something like this:
" note that line continuation is only possible without 'C' in 'cpoptions' let g:command_line_substitutes = [ \ ['^ack ', 'Ack! '], \ ['^ee \(.\+\)', 'e **/\1*'], \ ['^h ', 'vertical help '], \]
The last thing we need to do is a single map to call this function
whenever we press <enter> on the command line:
cnoremap <enter> <c-\>eCommandLineSubstitute()<enter><enter>
While this configuration is a bit ugly, it saves me the inconvenience of having a bunch of abbreviations lying around and makes the substitution transparent to me.
I’ve only been using this for a few hours but I haven’t hit any issues thus far. If you try this out and have problems or if you know of a way to simplify it please let me know in the comments.
Published on August 03, 2011 Comments
· · ·
I recently realized I have been using a very simple replacement for the
Command-T/Fuzzy Finder type plugins for quite some time,
however I had never made it convenient for myself to do so. Today I
pushed a small change to my .vimrc that I think will make things a
little easier for me.
nnoremap <leader>ff :e **/*<left> nnoremap <leader>fp :<c-p><left>
The first map allows me to quickly search for a file (by partial name)
anywhere under the current directory using <leader>ff. If there are
multiple files found that match the glob, vim will throw E77. If that
happens I can use <leader>fp to load the previous fuzzy-find on the
command line with my cursor where it needs to be for me to make the
search more specific.
Obviously this solution is nowhere near as complete as a plugin dedicated to this task, however it’s as complete as I need it to be.
Published on August 01, 2011 Comments
· · ·
I’m posting this because I’m tired of forgetting and having to ask this over and over again in IRC. Hopefully it will also help someone else speed up their work flow.
Many people are familiar with the special $_ parameter that is set to the
last argument of the previous command. It makes things like the following a
little quicker:
$ echo "foo" > foo $ mv foo bar $ cat $_ foo
I have always stumbled, however, in this case:
$ echo "foo" > bar $ cat $_ cat: foo: No such file or directory
The solution is to use the !$ history expansion rather than the $_
parameter.
$ echo "foo" > bar $ cat !$ cat bar bar
Published on July 10, 2011 Comments
· · ·
Often times I find myself editing a file and I suddenly realize I need to look up some data from some other file. Until today, I would normally do something along the lines of the following:
:sp path/to/file<C-w><C-w>I continue editing my original file. When I find I no longer need the reference file, I need to switch to it and kill its window:
<C-w><C-w>:qThere is a better way. pedit path/to/file (or :ped if you’re lazy
like me) will open a split window just as before, but cuts out the
middle commands. Focus stays on the file I was working on with my
cursor unmoved. The same scenario with :pedit is:
:ped /path/to/file:pcFour steps cut to two. This is why I use vim.
Published on October 10, 2010 Comments
· · ·
Have you ever used vim to edit a large file and found yourself setting marks in a few areas to quickly jump between them? I have, and I find it highly annoying to have to remember those marks. Luckily, vim has a few tricks up it’s sleeve that make jumping around a little faster.
Firstly, see :help changelist and :help jumplist.
The changelist (obviously?) stores a list of recent changes to the file.
You can even browse the list with :changes. You can jump back and
forth through the changelist with g; and g,.
Similarly, the jumplist stores a list of jumps (:jumps) that you can
navigate around using Ctrl+o and Ctrl+i.
The biggest difference I’ve noticed here is that the jumplist stores jumps across files whereas the changelist does not. Both of these features may be influenced by viminfo settings, but the default behavior is quite comfortable.
Have any other tips about jumping between sections of a file? If so, let me know.
Published on November 16, 2009 Comments
· · ·
A while back I posted a tip about how to quickly comment out a block of lines in vim. Since then I’ve gotten even more lazy and found an even quicker way that involves much less effort on my part. I think this originally came from a vim tip that I CBA to find now, so I’m reposting here to spread the love.
First, add a simple function to do the work:
" Toggle comments on a visual block function! CommentLines() try execute ":s@^".g:StartComment." @\@g" execute ":s@ ".g:EndComment."$@@g" catch execute ":s@^@".g:StartComment." @g" execute ":s@$@ ".g:EndComment."@g" endtry endfunction
This function comments starting at the beginning of the line. You can modify this behavior to suit your needs by changing the regular expression.
Next you’ll need to set the comment characters for the language you’re working in. My preferred way is to use autocmds to set these based on the current filetype.
" Set comment characters for common languages autocmd FileType python,sh,bash,zsh,ruby,perl let StartComment="#" | let EndComment="" autocmd FileType html let StartComment="<!--" | let EndComment="-->" autocmd FileType php,cpp,javascript let StartComment="//" | let EndComment="" autocmd FileType c,css let StartComment="/*" | let EndComment="*/" autocmd FileType vim let StartComment="\"" | let EndComment="" autocmd FileType ini let StartComment=";" | let EndComment=""
That’s it! Optionally (do this, really it’s stupid not to), you can add a keymap to quickly call our function.
vmap <Leader>c :call CommentLines()<CR>
Now to use this function, just select a visual block and hit your keymap to toggle comments on that block. Voila!
Note: If you need anything more complex than what this tip provides, check out the NERD Commenter. Everything I’ve read about it suggest that it’s excellent.
Published on September 22, 2009 Comments
· · ·
I’ve posted a follow up to this tip that details a quicker way to comment in vim by using a simple function. Check it out here.
From the “holy crap why didn’t I find this before” category…
When editing in vim, if you find you need to comment out a block of code, try the following:
Ctrl+v to enter Visual Block modeI to enter Insert mode before the first non-blank character on the lineEsc to get back to Normal mode.You can follow similar steps to uncomment the same block,Ctrl+v to
highlight the comment characters followed by x or any deletion command
to remove the comment.
Published on February 12, 2009 Comments