Hacker News new | past | comments | ask | show | jobs | submit login
Steve Losh's .vimrc (bitbucket.org/sjl)
178 points by earnubs on Nov 18, 2011 | hide | past | favorite | 99 comments



For those wondering who Steve Losh is. He's the creator of a few vim projects and is writing "Learn VimScript The Hard Way".

http://stevelosh.com/projects/


I didn't know this was possible:

    " Resize splits when the window is resized
    au VimResized * exe "normal! \<c-w>="
That's really handy. Also, this part made me smile:

    " Heresy
    inoremap <c-a> <esc>I
    inoremap <c-e> <esc>A


(I love both editors)

That's something disgusting about Vim - mapping to other keys instead of commands. In Emacs its much nicer IMO:

    (global-set-key (kbd "C-a") 'beginning-of-line)


Disgusting but practical. I already know the keys on the right because I use them every day. If it were a function I'd have to look it up first.


Is there a Vim equivalent of Emacs's C-h k followed by the key combo, which basically says, "Tell me what the official command name is for this keystroke?"


I don't know of anything quite like that but the help can be searched by key, though only for the default key combinations, e.g. ":h i^a" would show the docs for the ctrl-a command in insert mode.

Note though that vim really doesn't have commands the same way as emacs does. That's why you generally see assigning one key combination to another instead of some "command name."


You can bind a key to a command too. However, mapping to keys allows you to create your own. To give you a crude example, you could map a key to go down 5 times (5j). A real example would be more complicated for some specific task -- jump to other window, maxmimize it, go down to 5th line or some bookmark, etc.


Mapping to keys lets one map to the first part of a key sequence as opposed to the whole sequence/command name.


"C-w =" equalizes the size of splits. That works fine if you already had them near-equal, but I frequently shrink or maximize split windows, and I don't want them equalizing every time the window resizes.


You could bind a key to :setlocal winfixwidth, and press that when you want a certain window to not be resized.

Or just not worry about it at all -- each person has their own way of working with Vim.


Having paired with many people who have loaded Emacs keybindings into Vim, this made me laugh.

But serious talk:

Unless someone has loaded Emacs keybindings, shouldn't <C-a> be used to increment a number (even a hexadecimal one)? How is that heresy? Not having <C-a> makes several macros difficult.


The comment is cute, but doesn't it make more sense to just map to End itself since A is essentially a shortcut for <End>a

  inoremap <C-e> <End>
Technical note: I's behavior changes depending on 'cpo' so you can't just map it to <C-o>^.


Huh, I never thought of that. I always use A to get to the end of the line, so I never touch the End key. Good idea.


You use $ too sometimes?


I think that having all of this in one file is too crazy. I suggest putting some of the stuff in the appropriate files in ftplugins, etc in your ~/.vim directory.


Some of this definitely belongs in separate files.

The problem is that most of these are things I came up with when, during the middle of coding, I thought "oh, this would be really nice". So I just switched to my vimrc, added it, and got back to working, instead of thinking about where to put it, creating new files, etc.

Every so often I'll go through and clean it up. I just haven't gotten around to it for a long time since it works perfectly fine as is.


If you want to learn how to do this yourself, let Steve know here: http://leanpub.com/learnvimscriptthehardway


    function! NyanMe() " {{{ ...
I very much hope that's just there as an easter egg for those of us who read to the bottom.


Actually I'm planning on splicing it into MakeGreen, so instead of getting a green bar when my tests pass I get Nyan Cat flying across my window. Maybe over Thanksgiving weekend I'll get around to it.

Edit: Also, if anyone can show me how to draw an ASCII-art Nyan Cat in one line of text that would be awesome. Nothing I tried looked recognizable.


how bout 2 lines? http://jsfiddle.net/MHj9N/


Ascii Nyan cat!! Thank-you! My mind just melted.


This plugin[0] apparently plays an ascii version 'bad apple' music video. Inside vim.

Go figure.

[0] http://www.vim.org/scripts/script.php?script_id=3477


1.9 MB compressed...


Seems like vim is finally getting its own Nyan Mode? (http://nyan-mode.buildsomethingamazing.com).


That's one thing that worries me about using vim full-time: if I become reliant on a .vimrc or a set of plugins to use vim effectively, but I'm on a computer that doesn't have my .vimrc on it, I'm doomed.


I feel exactly the opposite. The previous editors that I used required configuration through a menu system. I wouldn't have known how to take that with me elsewhere.

With Vim, all my configuration is in files, which can be backed up. I have them in a dotfiles repo on Github. As I make tweaks, I regularly pull and push from my various computers and they are always up to date. If I'm on a computer that doesn't have my .vimrc, I'm just a `git pull` away from having it. (Same goes for zsh config, etc.)

The most likely time for me not to have my .vimrc is when sshing into a server, in which case I can use stock vim just fine. If my main editor were a GUI, I wouldn't have it available at all, so I think Vim has a leg up in that, too.


By the way, if you're ever confused about what behavior is native and what comes from your config, use the `-u "NONE"` option to run vanilla vim (or macvim or gvim).


you can get around this by editing remote files with your vim over scp http://vim.wikia.com/wiki/Editing_remote_files_via_scp_in_vi...


I do the same thing. But I also have customized branches to work with my config. I will usually make new commits on the computer-specific branch and then cherry pick the commits to master and then rebase the computer-specific branch on top of master. This can get a little repetitive and result in my computer-specific branches getting very out of date so I wrote a bash script called git-update to streamline this process for me. Here's the code:

https://github.com/axelson/git-update


This is why people place them on github or bitbucket. So it is very easy to clone the repo locally and then use the .vimrc. It is something you only have to do once per machine.


I totally agree. Personally I take the Robert De Niro approach:

"...become attached to nothing in life that you can't walk away from in 30 seconds if you spot the "Heat" around the corner."

Except I apply this to customised/complicated software rather than "things" in my life.


On all my machines ~/.vimrc and friends are symlinked out from my Dropbox folder.


This is what I do as well. To make thinks simpler, I use this script to automatically create the symlinks (if they are not already existant). If you put it in your `.zshrc`, you can run the command `dropbox-update-dotfiles` to make or update the symlinks. Not that this makes use of `zsh` extensions, so it requires adaptation to use with bash.

  dropbox-update-dotfiles () {
    src="$HOME/Dropbox/dotfiles"
    dst="$HOME"
  
    if [[ ! -d "$src" ]]; then
      print "Directory $src not found."
    fi
  
    for f in "$src"/*~*(.swp|~|.pyc)(D); do
      if [[ -h "$dst/${f:t}" ]]; then
        # exists as symlink
      elif [[ -e "$dst/${f:t}" ]]; then
        print "WARNING: ${f:t} exists, but is not a symlink."
      else
        ln -sv "$f" "$dst"
      fi
    done
  }


I use zsh too, but did something similar that should also work in bash: http://naleid.com/blog/2011/10/03/using-dropbox-to-share-you...

I link my dot files as well as Documents, Pictures, Music, and Desktop directories that are also normally controlled by OSX. Having those shared across multiple computers is awesome. Sit down at a computer, and it's there.

I also have my zsh files checked in to bitbucket (https://bitbucket.org/tednaleid/shared-zshrc/) so even if the computer doesn't have dropbox (like many of the linux servers I have access to), as long as it has mercurial, I can clone the repo and be ready to go.


Does that computer have a network connection? Just store your plugins and settings in a git repo (a good idea anyway) and pull them down on whatever machine you're using.


This is what I do. I can clone a git repo, run an install script, and have my typical vim setup running in a trivial amount of time.


Same here.

    cd
    hg clone http://bitbucket.org/sjl/dotfiles .dotfiles
    ln -s `pwd`/.dotfiles/vim/.vimrc ~/.vimrc
    cd -
My full Vim config is now installed, plugins included thanks to Mercurial's subrepos.

But really, I don't find myself editing files directly on servers all that often. And when I do I usually prefer bcvi anyway, because I can use MacVim instead of Vim through a terminal (which I hate because of all the shadowed keys).


Rather than type in the symbolic link commands, I just have a config script that I run (also checked into version control) that will move the old .vim directory, .bashrc, and other files out of the way, and install links to the version controlled file instead. Easy.



I've basically memorized my .vimrc and .gvimrc files from retyping them over and over again, but then I take the approach of using the standard configuration when possible and only customizing the minimum required, so it's not as bad as it sounds.

The power of VIM as an effective and consistent text editor is far more important to me than the power of VIM as a highly configurable editor.


This is why I stick pretty close to stock vim - I use it on too many remote systems to worry about keeping my environment consistent. I could automate something, and maybe when our sysadmin finishes integrating puppet into our servers I can use that, but in the meantime, my .vimrc is just syntax highlighting and tab settings.


Even in new computer without net connection vanilla vim is good enough for editing. When sit in an alien computer with vanilla vim. At first I put these lines in .vimrc

   set nocp
   set hidden
   set ts=2
   set sw=2
   set autoindent
   set incsearch
   filetype on
   filetype plugin on
   map <C-J> <C-W>j
   map <C-K> <C-W>k
   map <C-l> <C-W>l
   map <C-h> <C-W>h
For buffer management, combination of :ls, :b and :b# does the job well enough, compiling command-t plugin isn't necessary :). For listing of files there is :sexplore . For code browsing there is plain old ctags. There you go, almost 90% of environment created. Other things like surround or snipets support would be better. But I don't use them most of the time :).


echo set ts=3 > ~/.vimrc echo "Toggle search highlighting on and off with F5 >> ~/.vimrc echo map "<F5> : set hls\!<bar>set hsl?<CR>" >> ~/.vimrc

Everything else is gravy for me. While an extended rc is handy and I often store one where I can get to it, if I'm just editing a couple of files, vanilla + the tab size I want and a shortcut to highlighting search terms gets me going. YMMV

I tried to get into emacs, but I kept coming back to vim. Probably because the first editor I really used was a version of 'ed' back when I played MUDs.


Enter is actually a good candidate for something like that:

  " turn off highlighted results (set nohlsearch) when pressing enter.
  " just pressing n or N will turn the highlight back again
  nnoremap <cr> :noh <cr>
https://github.com/sce/dotfiles


I run

    wget -qO - bit.ly/newbox | sh
or

    curl -Ls bit.ly/newbox | sh
and am up and running. No sweat. I keep this stuff in Dropbox too, just in case.


That's a huge amount of trust you've placed in bit.ly, and in insecure http. You might at least consider typing out https://bit.ly/newbox so that you only have to trust bit.ly. Better yet, memorize the URL that bit.ly links to.

Also, why do you symlink your dotfiles into your cloned git repo, rather than just checking out the git repo as ~? Personally, I just move the .git directory from the clone to ~, and then "git checkout -f".


I'm lazy and don't want to type out the github URL, but you're right I should place the redirection under my control and use HTTPS. Honestly though I cannot think of a single reason why anyone would want to hijack my script. I don't do anything very interesting that would make my machine a lucrative target for that sort of malicious activity. I'm a very small fish in a massive pond.

Also due to laziness I don't want to add a bunch of stuff to .gitignore, or add * and then add exceptions. I like having the symlinks.



Just watch out that you don't get a 404 one day and end up piping a whole lot of error screen HTML into your shell, it could have wildly unpredictable results.


On foreign machines I'm rarely doing anything complicated enough where not having my .vimrc is noticeable. If I'm going to be spending a lot of time working on something, then it isn't a problem to either use my local machine or sshfs the remote server and work on it from my local editor.

I try and keep my .vimrc limited to configuration and enhancement and not change how the core works. Things like rebinding builtin actions will never be seen in my .vimrc.


I've had that concern as well but have not found it to be a problem in practice. For one thing, it's not hard to go back to default vim if you're on a different system. For another, it's usually not that hard to copy your .vimrc over if you're going to stay awhile.


What editor do you use now?


Really? You are doomed because you don't have some extra configuration niceties? Basic vim editing is not enough?

Then I have to ask: what exactly are you doing in that other computer?

If it's just some temporary sysadmin stuff and the like, then you surely can get by with the basic vim functionality.

Now, If you're gonna be using that other computer for a longer period, then why not just add your .vimrc there? With github, bitbucket, dropbox et al you can have your configuration pushed to the other computer in seconds.

I also find that with everybody having laptops these days, the need to use some "other computer" is much less frequent.


vimscript really is an abomination. vim users of the world unite! and create a proper macro language for your editor. and no: running an external python/ruby/brainfuck process does not count.


I dunno, I think the Python interface is adequate. Not great, but gets the job done. I write almost all my Vim scripts in Python.


Using Python and other runtimes is often kind of slow - it's not a huge deal but if you have a lot of this stuff in your config, then vim might start up only like 8 times faster than Eclipse.

The other thing is that the Vim API you use in these other languages is pretty much Vimscript anyway.

For me, Vimscript is basically a normal imperative language in the general neighborhood of perl and shell... I agree it is more awkward to write than Python, particularly with escaping. But it's a decent DSL for configuring text editors, and Python isn't as much.


The two advantages of using Python for me are being able to use utilities I've already written, and the comprehensive standard library.

For example, I wrote a macro to split long Python function calls into multiple lines, and I could access a parsing function that I already wrote, along with Python's own compile() to detect when I've parsed a complete expression (yes, this one is Python-specific).

I also wrote a macro to submit the current file to a private pastebin, and AFAIK you can't make web requests with Vimscript.


Here's a commented version of my .vimrc, which is modeled after Steve's, albeit nowhere near as comprehensive. (Looks like I lost it's fixed width in the paste? Sorry!)

http://pastebin.com/jJQFxQpR

For me it's a lot quicker to reference comments than the :help entry for each option. Thought it might help others who are creating/modifying their .vimrc.

And of course, thanks Steve for continuing to share your stuff. I'm in love with Vim, and a lot of that's thanks to you.


Here is the code in a more readable gist without fixed width:

https://gist.github.com/1377245


If anyone stumbles on this problem when grabbing the Clojure configs, I found that the TurnOnClojureFolding() method was missing: https://bitbucket.org/sjl/dotfiles/src/27ec8da23760/vim/.vim...

But, a bit of Googling will find it (works pretty well, too): http://writequit.org/blog/?p=413


I'm sure I've seen this in vim, but I can't find it now. Isn't there a statusline config item that shows any pending command prefix chars you've typed?


I think you want :set showcmd—"Show partial command in the last line of the screen".


THAT'S IT! My long lost friend is back! Thank you!


I also have a huge vim configuration: https://github.com/sashahart/.vim

I highly recommend putting your vim configuration on github or similar, you don't have to worry about losing your config and it gets easier for everyone to learn the new tricks


I'm stealing "nnoremap <CR> o<ESC>" immediately. Thanks!


    nnoremap <leader>ev <C-w>s<C-w>j<C-w>L:e $MYVIMRC<cr>
:vsplit $MYVIMRC and so on would work the same way, but more obviously, and without depending on the placement of split windows.


What do the triple open and close curly braces represent?


They're fold markers. When I open my vimrc in Vim it looks like this: http://d.pr/YKCM


Why doesn't my Vim fold things automatically? What options am I missing?


Either

    set foldmethod=marker
Or put this modeline at the top of your .vimrc:

    " vim: foldmethod=marker foldlevel=0


`foldmethod` and friends.

There are a bunch of different methods for folding (indentation, manual markers, custom syntax-based folding, etc), and which one you want usually depends on the file type.

I have a bunch of autocommands for different files that set the foldmethod appropriately. For example:

    augroup ft_vim
        au!

        au FileType vim setlocal foldmethod=marker foldmarker={{{,}}}
    augroup END

    augroup ft_js
        au!

        au FileType javascript setlocal foldmethod=marker foldmarker={,}
    augroup END
This makes Vim fold using markers for Vim and Javascript files. The Vim markers are the usual {{{ and }}}, but Javascript has it's own "built-in" markers we can take advantage of, so it uses { and }.



inoremap # X<BS>#

This has been annoying me forever, but I never got around to fixing it. Not sure how the solution works, but it does!


This is probably b/c you're using 'smartindent' or 'cindent' all the time. Don't. The former is deprecated by the latter and they're only for C-like syntax--hence why # belongs in column 0. If you want filetype-specific indenting, you just need "filetype indent on".


It's (sort of) explained in :help smartindent.


I find semicolon and comma to be very useful so I am surprised when I see people remap them or use them as leader.


I love reading these files and finding something new to use. gdefault is definite going in.


Ugh. Be careful with that, since actually giving a /g has the effect of toggling the behaviour all together.

From :help 'gdefault':-

    :help 'gdefault'
    'gdefault' 'gd'		boolean	(default off)
    global
    {not in Vi}
    When on, the ":substitute" flag 'g' is default on.  This means that
    all matches in a line are substituted instead of one.  When a 'g' flag
    is given to a ":substitute" command, this will toggle the substitution
    of all or one match.  See |complex-change|.

    command		'gdefault' on	'gdefault' off	~
    :s///		  subst. all	  subst. one
    :s///g		  subst. one	  subst. all
    :s///gg		  subst. all	  subst. one
While not quite documented under ":help :s_flags", two 'g' flags cancel each other out. This also applies to 'gdefault'.

Also, be aware that this may break a huge amount of scripts out there, should you decide to use it as some (hard to debug) issues are caused because of it.


I've had this set for a while now and haven't noticed any scripts breaking. It's far more common for scripts to break because I'm remapped something and they used 'nmap' instead of 'nnoremap' or 'normal' instead of 'normal!'.

Whenever a script breaks, I bite the bullet and fix it, fork it on Github, switch my dotfiles repo to use my fork and send a pull request. If they merge my fix I switch my dotfiles repo back.

It's a pain in the ass, but I like to think that it helps other Vim users a little bit.


I like PulseCursorLine, but I wonder why only on N and n? (e.g. not on *)


Because I have Vim set up to not move at all when I press star, so there's no point in pulsing the line:

    " Don't move on *
    nnoremap * *<c-o>


Does this affect performance in any way? 1k+ lines is quite a lot.


In any way? Of course.

But my laptop has 8 gigabytes of RAM, a solid state hard drive, and four processor cores.

I can run Minecraft at the highest settings while accidentally leaving a Linux VM running in the background. Loading a 1.5k vimrc file is barely a blip on the processor graph.


vimrc affects startup time, but like any program it isn't the lines but the work done which will make it slow or fast. How slowly does your computer read a 1000-line text file? vim is fast, setting some parameters in vimrc doesn't change that. Avoiding configuration that will make your life easier out of fears about performance is premature optimization.

If you have a ton of autocmds for frequent events, things can slow down. I also find that things can get slow when LOTS of calls are made to a language other than Vimscript.

But fundamentally, run Eclipse and Netbeans and gedit and emacs - vim should compare favorably even with a ton of config.

If you want to actually profile your startup time, try this on a recent version of vim: vim --startuptime=vim.log


In my experience a huge .vimrc loading tons of plugins is not much. It's completely dwarfed by the overhead of starting X11 gvim, for example.


God bless nvi.

I will never understand why people go out of their way to write and maintain such monster configuration files.

Learning core/traditional vi gets one a long way, instead of delusioning themselves with false cleverness and productivity.


I don't think that the author wrote his 1200 lines of .vimrc in one sit. More likely it's years of accumulated 1-2 line additions and removals.

My vimrc has slowly accumulated, I add 1 or 2 new keybinds every now and then and I might remove them later if I notice they don't suit my workflow. Most of my changed keybindings are related to making Vim usable with my native keyboard layout (finnish/swedish).

Also per-language additions accumulate over time. The author seems to have put all settings for all file types in the same file.

Learning standard Vi gets you a long way, but sometimes adding or changing a keybind will make things work more fluently.


My point was, time better spent is coding, not dicking around (and relying) on .vimrc.

We often forgot about the essence of things such as typing the actual code or words, and focus on tools. Better investment is learning how to properly type than having countless little helpers which are nothing more than debt.

Increasing complexity in all areas of life really is troublesome.


I think you're thinking about it backwards. It's usually not thinking "what could I tweak today" that results in adding something to .vimrc. It's "I keep doing this a lot / this feel uncomfortable, maybe there's an easier way" that results in changes. And if you take time to actually implement it, that's a good indication it was worth the tweak.

Let's say you work with splits a lot. Sure you could press ctrl+w all the time, but it's a bit annoying. Rebinding doesn't take much time, but makes it (in the presented example) actually simpler. So did it waste time? A minute or so. Does it make life easier? A little bit. Did the "coding time" suffer? Who cares about a minute or so ;)


There is no dichotomous distinction between coding and using vim to automate tasks. The latter is part of the former - no different from using q or @ or .


I think it is all about productivity and if he feels or thinks he is more productive with these additions then it is really good for him. I don't think anyone should use plain vim because it's 'way it should be done'.


Sometimes we don't realize things. I was using Vim before. I loved it, tweaking it all the time, thinking it helped me to achieve various things faster etc.

When I switched to nvi I realized how wrong I was. My .nexrc contains less than ten lines. There is no syntax highlighting. I was also forced to learn real vi properly. When you do such things amazing things happen.


"""Learning core/traditional vi gets one a long way, instead of delusioning themselves with false cleverness and productivity."""

Sure, you know a lot more than me what makes me productive in my text editor use.

And that is traditional vi. Sure no need to go beyond that. Oh, and 640K should be enough for everybody.


Anyone who knows who sjl is could have easily found his vimrc through his website. According to the bitbucket history, the file has been hosted there since at least 2009.


Which doesn't make it less useful. And for those of use who don't know sjl, this was useful.


Did I say it wasn't useful? Maybe you missed my point.

I could post a link to a perldoc page for some builtin function, and that would be useful, and it's probably been around for awhile, and probably nobody knows who wrote it. Would you defend that too?


Can we now have a long discussion about profanity in dotfiles?


    " ta gueule !
    set noerrorbells
    if has('autocmd')
      autocmd GUIEnter * set vb t_vb=
    endif
    set noerrorbells
    set visualbell
    set t_vb=


There should be more of it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: