converting a search to a replace in vim

I just googled something I’ve always wanted to know how to do in vim, and was surprised how quickly I found the answer.

In vim, there are separate modes for searching and commands. This generally works well as they have separate completion buffers and since I do them a lot, it keeps my command history from cluttering up my search history and vice versa. The area where I’ve wished that they were unified is when I want to convert from a search to a substitution expression. Normally in vim you do search expressions in search mode and command expressions in command mode. For example, if I wanted to search for trailing whitespace I might type:

/\s\s*

If I want to replace it with an empty string through the whole file I might type:

:%s/\s\s*//g

I can’t remove the / at the front of the command line with a backspace and replace it with a colon, so until I learned the tip I’m about to reveal I had to retype it. No longer.

The StackOverflow answer I found for the query, Convert vim / search to search and replace without retyping regular expression, suggests this remarkably simple technique:

You can type

/search_term

and then

:%s/<ctrl-r>// etc

where you actually press ctrl+r and then / to insert the search term.

It works! No longer do I desire for search and command modes to be unified.

vim’s lcd command

I find vim’s :lcd command to be quite useful. For a long time I didn’t use it, mainly because I didn’t understand how it works.

First, using it is simple. It works just like :cd. You type :lcd path/to/directory in command mode. The path is relative to the current directory, so :lcd .., :lcd ~/Desktop, and :lcd /etc/apache2 all work.

The :lcd command changes the path of the current window. The current window is the current frame within the current tab. Now, what’s really neat, is that a new window (created from commands such as :sp and :tabedit) gets the local directory of the window it’s created from.

Most plugins respect it. Both Command-T and ack.vim search within the local current directory. Another plugin, fugitive, bases its commands on the git repository of the current file so it works smoothly with different local directories as well.

Bang commands (like :!cp README.md ~/Desktop) also use the local current directory.

Finally, after using it for a while it gets easy to tell which directory I’m in. The status line displays the path of the current file based on the local current directory, so if I know where the current file is I can quickly figure out where the local current directory is.

I used it the other day with bundle show to dig through the source of two dependencies of my Rails project to better understand them.

If you use vim and haven’t got in the habit of using :lcd I highly recommend it. If you use another editor and wish it handled working in multiple directories gracefully, consider giving vim a shot!

vim: change current directory

I like using the excellent FuzzyFinder plugin for vim. It’s usefulness is heavily dependent on keeping the current directory what I want, though, because otherwise I could do a lot of drilling. I found that I needed a better way of changing directories. What I wanted most of the time was a way to change to the directory of the current file.

I found this while searching for a way to switch to the current directory. I’m not sure whether I picked the same mapping as the author.

map ,C :cd %:p:h<CR>

Admittedly, I’m not sure where the :p:h comes from, but it works well. A couple of months after I found this, I made a second mapping for lcd. Additionally, because I want to lcd to the current directory more often, I made lcd the more convenient remapping.

map ,c :lcd %:p:h<CR>
map ,C :cd %:p:h<CR>

A word about lcd: it changes the directory for the current window, not the current buffer. This sounded obvious to me after I figured it out, but prior to then I thought it was tied to the buffer it’s invoked on and buffers spawned from that buffer.

Another thing I’d like to learn is how to change to the global directory when a local directory is set (or remove the current local directory).

vim: remapping cc to ?

I used to dread having to search backward in vim, because that meant scrunching my right pinky and ring finger next to each other to hit ?. So I remapped it. I used cc because I don’t use cc to change lines—I use S for that (it does the same thing). It’s much easier for me to hit cc than to hit ?, and since c is in the bottom row along with the / key it’s not hard for me to remember to use it.

The remapping is simple:

map cc ?.

After mapping this, I realized that the downside to having a funky vim setup is that I can’t have someone else who knows vim type in my window very easily. I am thinking of making pair and unpair commands that turn off and on my funky keymaps, respectively. Rather than duplicate the mapping code, I’ll just call unpair in my .vimrc file.

I am still using MacVim with my enter key mapped to escape. I use shift-enter or enter followed by o to insert multiple lines. I switched back to the normal setup for a while before realizing that the number of one-line inserts I make far outweighs the number of multiline inserts I make. I have found that is the best way for me not to have to reach for the esc key (I use ctrl all the time and have my caps lock key mapped to ctrl, so mapping caps lock to esc was out of the question).

I have ctrl-J and ctrl-K mapped to insert blank lines, and use them whenever I can remember to do so. I took the code from the Vim Tips Wiki, and switched the Ctrl for Alt in the remappings, so Ctrl inserts and Alt deletes. I use the command for inserting more than to deleting because I find it easy enough to just go down a line and hit dd than to remember to use a custom remapping.

A brief journey back into to emacs-land

In an earlier post, I said that I am no longer going to deny myself the pleasure of dabbling in different editors. It was my interpretation of the “use one editor; use it well” mantra I got from the pragmatic programmers. It was probably a misinterpretation of it. They also would recommend using the best tool for the job, and how can you know what the best tool for the job is without learning about all the alternatives? And, in the case of text editors, it’s practically impossible to know every one of them well enough to judge which is best.

One day I was feeling frustrated with vim, so I fired up emacs. I wanted to remind myself of one thing it has that vim lacks—the ability to view/edit a single buffer in multiple frames. Pretty nifty, really. If you’re unfamiliar with the terminology, in Emacs a frame is a top-level window (think JFrame), and a window is a split within a frame, or the whole frame if it isn’t split. In MacVim, each frame has its own vim instance with its own set of buffers, so you can’t view the same buffer in two different frames, which would be nice for having a big frame and a frame that can sit alongside other windows. In emacs it works without a hitch.

While I was in emacs, I noticed something else I like about it—the scratch buffer. In vim there’s a blank buffer that shows up when you start it, but it seems like vim would rather pretend it’s not there. If you delete a buffer, it closes any window (i. e. split view) that is associated with it, unless there is only one window in the frame, in which case it grudgingly shows the scratch buffer (or the last buffer if there’s another buffer still open).

I can think a couple of things that I gained from this experience. First, I can see that there are other developers who can sympathize with my experiences. If I ever get frustrated with vim, I can take refuge in the emacs community. Same for when I got frustrated with emacs and became a vimmer. Second, I was able to take the scratch concept and apply it to another part of my computing experience. I created a directory in my home directory called “scratch”. It’s going to be my new temporary working directory. I had one called sandbox but the name never quite felt right and I never got in the habit of using it.

I don’t know which editor I’ll be using a year from now. But for now, it’s vim, for the most part. I do want to try out SLIME and see how viable Viper-mode (vim emulation in emacs) is, though.

vim and the enter key

This is just a quick update on how I’m using the enter key in vim. The sticky shift-enter key configuration didn’t work out for me. After pressing shift-enter once, I found that I would press shift-enter again, expecting it to create a newline. I wound up just remapping <CR&Gt; to <Esc>, and using shift-enter to insert newlines, or pressing enter and then “o” or “O” to create a new line above or below the current line. I use the latter option most. The only time it doesn’t work is when I need to split a line into two. For that I use shift-enter.

Shift-enter doesn’t work when using vim in a terminal, so the remapping doesn’t work quite as well in the terminal. I use it anyway, though. I should remap something to split a line into two, but so far I haven’t. I use vim in the gui (MacVim) most of the time. The couple of times I’ve had to split a line in the command line, I’ve hit:

  • D to delete the rest of the line and yank it
  • o to open a new line
  • Enter to get out of insert mode (since it’s remapped to Esc)
  • p to paste the rest of the line, that I deleted earlier

…which is terrible. If I start using command-line vim more often I’ll add a mapping for it.

This might seem like a pain, but for me it beats reaching for the Esc key. YMMV.

Update: zenzike pointed out in the comments that if you remap CR (the enter key) in the terminal, Control-CR still inserts a newline. So you could use Control-CR to insert a newline if CR was remapped to Esc. Unfortunately, this doesn’t work for me in OS X’s terminal or in iTerm by default. It does, however, work in gnome terminal running under Ubuntu on VMWare Fusion. I’m not sure why it doesn’t work in either of the two OS X terminal programs. I would be curious to learn why it doesn’t work and how to fix it, though, as this otherwise a very nice solution.

vim and vimperator, a few weeks later

A few weeks ago, I started using vim as my main text editor. Soon after that, I installed the vimperator Firefox extension on my main computer. A few days into the use of these two tools, I was really excited about both of them. It takes more than a few days for me to know whether I’m comfortable with using a particular piece of software regularly, though.

I’m still using vim every day, and I like it. It’s powerful, ergonomic, and customizable. There are a few annoyances. I still haven’t figured out how to properly configure Firefox to use MacVim as an external editor. Vim doesn’t support having multiple frames for a single instance of vim (emacs does). The official wiki, hosted by Wikia, has horrible ads, and I refuse to install an ad blocker, because I don’t want to turn a blind eye to virtual blight like the maintainers of vim have. Nevertheless, I’ve become quite comfortable with vim and will continue using it. While I’d like it much more if it didn’t have these annoyances, it has relatively few annoyances compared to some other editors I’ve tried, and the good things about it outweigh the bad.

My experience with Vimperator was different. As with vim, I really enjoyed using it at first. Over time, though, I found myself growing tired of it, even though it enabled me to browse faster. The biggest problem for me was that the commands only work if I’m in the normal mode, and it’s very easy to get thrown out of the normal mode. The two things that most often put me in the wrong mode were full-page Flash files and JavaScript that placed the focus in text boxes. Another issue was that I couldn’t easily use the keyboard to scroll in a div. I can’t easily do that with normal Firefox either, but Vimperator is supposed to make browsing with the keyboard easy, and it does it for the most part.

I uninstalled vimperator, but I miss its functionality. I’d like a lightweight extension that makes it easy to click links or jump between form fields with the keyboard. I don’t think that the vim input model is suitable for keyboard navigation within a browser, because the browser environment is too unpredictable. I’d like to see a couple of multi-key combinations that activate keyboard input, though. These would work inside of text fields. Flash would probably still break them some of the time, but to deal with that I could install FlashBlock.

I really enjoy trying out new development tools. I think the next thing I’ll try out is a visual CSS editor. Any suggestions?

Idea: Sticky Shift-Enter in vim

I set up vim to use enter to get out of insert mode. This prevents frequently having to reach for the escape key or use a multi-key combination. To insert a new line while in insert mode, I now use shift-enter.

An idea I had this morning is to make shift-enter swap the shift-enter and enter bindings. This way, if I’m in the mode of writing something new without manipulating text, I can push shift-enter once to enter a newline, then push enter for each additional newline, and push shift-enter when I’m done to get out of insert mode.
shift-enter

To implement it, I created a function that toggles the bindings, and added a call to the function to my bindings for <S-Enter>.

function ToggleEnterMappings()
  if mapcheck("<CR>", "i") == "<Esc>"
    iunmap <CR>
    inoremap <S-Enter> <C-o>:call ToggleEnterMappings()<CR><Esc>
  else
    inoremap <CR> <Esc>
    inoremap <S-Enter> <C-o>:call ToggleEnterMappings()<CR><CR>
  endif
endfunction
call ToggleEnterMappings()

Time will tell whether this is a good setup for me. I think if I do single-line inserts much more often than I do multi-line inserts it might.

How to really disable the bell in Vimperator

Yesterday I started trying out Vimperator, and so far I’m impressed. It’s a Firefox extension that puts a vim-like keyboard interface on top of Firefox.

After using it for a while, I wanted to turn the bell off, because I find it to be distracting. I turned to the documentation. I quickly found a visual bell option, but I find visual bells to be even more distracting. Then I saw the visual bell CSS style option, which can be set to an empty string for no bell at all. Bingo! Or so I thought.

It turns out that the page flickers when the bell is triggered. This is not the desired effect. So after searching the docs one more time, I unpacked a jar and poked around in the source code of Vimperator.

There’s a beep function in there. I changed the beep function to return false and Voila! It did nothing when you scrolled past the bottom or top of the page.

Rather than keep the code patched, though, I figured out how to implement my change in my ~/.vimperatorrc file. There’s a javascript command for executing a line of javascript. Vimperator’s beep function is in a global “liberator” object. Combining these two bits of knowledge, I came up with the following line which can be added to ~/.vimperatorrc:

javascript liberator.beep = function() { return false; }

It’s simple but it works. It would be nice if completely disabling the bell (including any visual artifacts) were built into Vimperator, but being able to fix it with a one-liner in the configuration file is the next best thing! Kudos to the Vimperator developers for writing code that’s easy to modify.

I’m not sure how often I’ll use Vimperator. I need to learn how easy it is to pass the input through to the current web page first. But it certainly seems to do a difficult job remarkably well!

Update: I started a Silencing and Disabling Bells WikiBook and put instructions for disabling bells in Vimperator, MacVim, and iTerm in it. Contributions welcome!