Thursday, May 7, 2015

Edit Vim command lines like an Emacs-using pro

Certain things of the tip type and of the time-saving variety, when applicable to one’s Operating System of Choice, are too useful to forgo in favor of strict allegiance to The Other One True Editor. This I say by way of preface before pointing out how you can make use of (what turn out to be) very helpful Emacs-oriented shortcuts in your own local Vim instance.

It has been pointed out to me—I believe by means of an O’Reilly video series, Mac OS X Productivity Tips for Developers, which features sirs Tim Berglund and Matthew McCullough (I recommend this series, if you are an OS X user)—that certain Emacs-based key bindings involving the moving of cursors are actually built into OS X as it is. The two that I’ve been using most since I realized this are <c-a> (Ctrl+a) and <c-e> (Ctrl+e), which move the cursor to either the beginning (<c-a>) or end (<c-e>) of the text you’ve entered.

You need not be an OS X user to find these useful outside of Emacs, of course. If you’ve switched from The One True Editor to The Other One True Editor, or even if you haven’t but still want to edit command lines in Vim, you may be interested in the following mappings, which are available from :help emacs-keys and which I just discovered recently while perusing tips.txt, as I recommended last time:

" start of line
:cnoremap <c-a>        <home>
" back one character
:cnoremap <c-b>        <left>
" delete character under cursor
:cnoremap <c-d>        <del>
" end of line
:cnoremap <c-e>        <end>
" forward one character
:cnoremap <c-f>        <right>
" recall newer command-line
:cnoremap <c-n>        <down>
" recall previous (older) command-line
:cnoremap <c-p>        <up>
" back one word
:cnoremap <esc><c-b>    <s-left>
" forward one word
:cnoremap <esc><c-f>    <s-right>


That is all taken directly from tips.txt. Quite splendid stuff; I wouldn’t necessarily use all of those, but at least I can now have <c-a> and <c-e> in Vim’s command line, with the others also there in case they should prove useful.

Tuesday, May 5, 2015

Counting occurrences of a string in Vim

On Stack Overflow, Chase T. points out a most useful item in the Vim help, which relates to counting phrases (strings) in the current buffer, which is usually the current file, which is typically long enough that you’d want a command to save you the trouble of just reading through it yourself looking for matches. I will readily admit that string counting is something I don’t do enough to remember how to do without Googling, and yet which I do just enough that I’ve had to Google it more than once. Mayhap this will help me next time?

Toward the point.

The item is count-items, as in :help count-items. The command is simple enough: it’s none other than :s!

As example:

:%s/sympathy/&/gn

35 matches on 35 lines

:%s/sympathy with sounds/&/gn

1 match on 1 line

(Yes, I’m still using Sir Cowper for an example. His Life is now out, in many splendid ebook formats, by the way—go get it from Gutenberg.org yourself.)

When we last saw :s (:substitute), we didn’t cover every aspect of its operation, for example its flags (we were mostly interested in how it operated on a range). For help in understanding the particular :s incantation used here, we can go to :help :s_flags, or more particularly :help sub-replace-special. There we see:

When the {string} starts with "\=" it is evaluated as an expression, see sub-replace-expression.  You can use that for complex replacement or special characters.

Otherwise these characters in {string} have a special meaning:


[…]

magic    nomagic     action    ~
  &      \&          replaced with the whole matched pattern


The & simply stands for the term we’re searching for, so that if we were actually replacing the term, it would replace it with the term itself. We add the n flag to prevent a substitution, but to see that this is indeed how it works, you can go ahead and run the search command without the n:

 :%s/sympathy with sounds/&/g

You should see nothing happen. If that’s not sufficient to convince you that Something Changed, try running u (undo).

So n tells the command not to replace a match. What else does it do? And why are we getting the number of matches after running the command when normally :s does not tell us how many there were?

[n]    Report the number of matches, do not actually substitute.

Ha ha! It turns out that this is basically just a nifty addition to our trusty search-and-replace command—something to let us know how many times a phrase would be replaced. Lacking any dedicated expression-counting command as we are, it also happens to be our best means of counting occurrences of a string in Vim.


For further fun: Note the filename of the help file in which we find :help count-items. It is:

tips.txt

with the explanatory heading:

Tips and ideas for using Vim

Earthquakes and hotcakes! (This is being written by Mr. Moolenaar himself, after all.) It may not be the hugest file in Vim’s help set, but give it a peek nonetheless.

Thursday, March 5, 2015

Two plugins which (you and) I will be looking into

Not much time to collect philosophizings for here have I had so instead, have links to two plugins which I have both tried briefly and failed to yet try for long enough:

  1. cmdalias. This is by Hari Krishna Dara and the short version of its story is that it replaces :cabbrev for you, or rather gives you a wrapper function which, as I understand it, creates aliases (to replace “abbreviations” as :cabbrev creates) and only allows those to be expanded when they begin a command at the Vim command line.

    I toyed with this briefly—obviously it would relate to the trick #2 of my five weird tricks, and I do use those abbreviations but I was not able (in my brief experimenting with it) to set up a suitable replacement using cmdalias. I am perfectly willing to put that down to my lack of time spent on it rather than the plugin itself for now, so I may yet post on how you can replace that trick’s code.

  2.  Seek. By Vic Goldfeld, this creates a motion using s. (I mention this one in the book, by the way, as a good source, code-wise, of inspiration for new plugin authors.) The motion takes two characters and moves the cursor to where they appear in the current line (so it’s like a more-specific f). I don’t doubt that this is useful in practice, but I use s a lot to a replace text, and was having some difficulty reconciling Seek with my current customs in that regard. More work is needed here, since Seek does consider such use (and has had more thought put into it by its author so far than by me as a user).


So. Try those out yourself (I command you), and hopefully I will have more to say about them in future postings. Meantime, happy Vimming!

Tuesday, March 3, 2015

Two of my most-used Vim mappings (yo)

I’ve been complaining (sometimes misdirecting my complaints) about this being broken for a while now, so perhaps as I have it working again now I might as well give it a Shout-Out.™

One of the cool things to result from my recent re-upgrade to Vim 7.4 was the return of the * clipboard. I have these two (well, four, with the comments) lines in my .vimrc:

" In visual mode, use Y to copy to system clipboard
vnoremap Y "*y

" In normal mode, do the same with the current line
nnoremap Y "*yy


They might explain themselves (well, with the comments), no? In case they don’t: They map the Y key so that it yanks text into the * register. This register represents Vim’s view of your OS’s clipboard… it’s a little hard to get from the docs, but here is from clipboard under :help quotestar:

There is a special register for storing this selection, it is the "* register.  Nothing is put in here unless the information about what text is selected is about to change (e.g. with a left mouse click somewhere), or when another application wants to paste the selected text.  Then the text is put in the "* register.  For example, to cut a line and make it the current selection/put it on the clipboard:

    "*dd

Similarly, when you want to paste a selection from another application, e.g., by clicking the middle mouse button, the selection is put in the "* register first, and then 'put' like any other register.  For example, to put the selection (contents of the clipboard):

    "*p


(I copied that using my Y mapping! Hee, hee!)

This was not working for me on pre-7.4 Vim, but it is on post-7.4. Also, I do not know what the hubbub seems to be about left mouse clicks or middle mouse buttons; I just use a keyboard-derived visual selection in Vim. So what this means is that I can select text using v or V (Vim’s visual mode, either linewise or characterwise), hit Y, and then Cmd+V into TextEdit, or Messages or Blogger via Firefox. (I’m on a Mac.)

This is hugely helpful, since I prefer to deal with text from inside Vim (and I use terminal Vim), but then of course text is often needed elsewhere and to be dealt with from within other apps. My terminal emulator (iTerm2, although I don’t know that I use any of its distinguishing-from-Terminal features) was always more or less a first-class application in this regard, but not its Vim; with these mappings making use of this register, I can copy from Vim and then paste into primitive text-handling facilities unaware of its existence anything.

Tip #984 on the venerable Vim Tips Wiki covers this, with additional and related discussion.

Thursday, February 26, 2015

First Step In Z Shell (AKA “Give Me a Prompt or Give Me bash”)

published by Suby

Ironic, isn’t it, that for the prompt being maybe the coolest and flashiest thing that you always hear about Z shell (zsh), when you first switch from bash you get this:

Scrooge-and-Marley%

So it’s giving us the computer name (or hostname), and then uses a % as delimiter before our input begins (where bash uses a $). This, by itself and with nothing else to recommend it to our collective impressionability, is not exactly what we in the geosciences* call “earth-shattering stuff.”

This is more like what I normally saw as the prompt (on OS X) when I was on bash:

Scrooge-and-Marley:bookshelf ebenezer$

Let’s start simple and just try to replicate that on zsh for now.

Ye Olde prompt string


The relevant setting (or “parameter”), in both bash and zsh, is PS1 (zsh also allows PROMPT). Both shells have a nice array of special characters which we can use, escaped, to represent various bits of info which we want in our command prompt (the prompt string). My old OS X bash prompt used three, which are listed under PROMPTING in the man page for bash:

h    the hostname up to the first `.'
W    the basename of the current working directory,
     with $HOME abbreviated with a tilde
u    the username of the current user

In bash, these are escaped with a \, so this would have been the value of PS1 there:

\h:\W \u\$

Or, quoted as we could set it with export:

export PS1='\h:\W \u\$ '

So now to make that, but in zsh.

The new prompt string (New Look, Same Different Taste)


zsh has a huge manual, which (as it explains in man zsh—that acts as a sort of index) is broken out into different sections. The relevant one here is:

man zshparam

…except that it turns out it’s not. Well, it sort of is. Here’s what it says for PS1:

       PS1 <S>
              The primary prompt string, printed before a command is read.  It undergoes a special form of expansion before being displayed; see EXPANSION OF PROMPT SEQUENCES in  zsh-misc(1).  The default is `%m%# '.


So, to man zshmisc!

Under SIMPLE PROMPT ESCAPES, we have a list: the special characters which stand for informational bits in our prompt string. These are the three which correspond to our bash special characters:

       %m     The hostname up to the first `.'.  An integer may follow the `%' to specify how many components of the hostname are desired.  With a negative  integer,  trailing  components of the hostname are shown.

       %d
       /      Current working directory.  If an integer follows the `%', it specifies a number of trailing components of the current working directory to show; zero  means  the  whole path.  A negative integer specifies leading components, i.e. %-1d specifies the first component.


       %n     $USERNAME.

If you do not yet have a .zshrc, create one. This can be its first line:

PS1='%m:%1d %n$ '

We can see the % for escaping rather than \ (as bash uses), of course. Other than that, we have the hostname (%m), a literal colon (:), the first item in our current working directory path (%1d), a space, and then our username (%n) and a literal dollar sign ($).

The %d confused me for a bit (I am not a Nobel-winning rocket scientist). Using the example in the man page, I tried something like

PS1='%m:%-1d %n$ '

which gives us something like:

Scrooge-and-Marley:/Users ebenezer$

Yes, the first item is indeed the first. (Who would have thought? A Nobel-winning rocket scientist would have, for one.)

So there you have a familiar (if you’re a fellow switcher from bash) prompt. Obviously we’ve not really taken over the world here—this is just about (if you’re also on OS X) getting back to what you were used to—but we now know how to modify prompt strings, or at least one of them, in zsh. Stay tuned for more exciting updates in this space…

(I stole the title of this post from that of the excellent book by James Ward and Bruce Eckel, First Steps in Flex.)

* I am not in the geosciences.

Tuesday, February 24, 2015

A More Betterer Autosave In Vim

Run :version in your local Vim. What do you see?

Here are the first two lines I get:

:version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Feb 24 2015 14:04:47)

That 7.4 is the key thing.

I actually wrote in old time (December 2013, as I recall; this was on an older site) about a cool new(-ish) autocommand event, or rather a pair of events, which someone sent a patch to the vim_dev list about—they were not mentioned in the help file. I don’t know when the events were added, but in Vim 7.4, the help file situation was remedied, and now we have this as the help for TextChanged and TextChangedI:

                                                        TextChanged
TextChanged            After a change was made to the text in the
                       current buffer in Normal mode.  That is when
                       b:changedtick has changed.
                       Not triggered when there is typeahead or when
                       an operator is pending.
                       Careful: This is triggered very often, don't
                       do anything that the user does not expect or
                       that is slow.
                                                        TextChangedI
TextChangedI           After a change was made to the text in the
                       current buffer in Insert mode.
                       Not triggered when the popup menu is visible.
                       Otherwise the same as TextChanged.



I’ve (since writing that) upgraded to OS X Yosemite, and was back on its system Vim until today, in fact. (Its system Vim is a 7.3.) So I’d forgotten about these events, and was not even using an auto-saving trick for some time (until my last post, as it turns out). Then “Unknown” reminded me of the events (albeit indirectly) with a comment on that last post, “Save time in Vim NOW with these five weird tricks”, which mentioned an auto-saving autocommand as a bonus (sixth) trick:

Sadly auto-save a file when you leave insert mode doesn't do anything for edits made in normal mode (dd to delete a line etc)

(And yes, as you can see, I just upgraded to 7.4 again today. Yay Homebrew!)

I hereby, therefore, give you a new and improved (or at least improved) autocommand, Unknown! Here it is:

autocmd InsertLeave,TextChanged * if expand('%') != '' | update | endif

As the help text says, TextChanged watches for changes to the text (hmm—what a surprise!) when we’re in normal mode, which is where we do things such as dd, p, c, etc.; InsertLeave only notices that we’ve left insert mode (and thus lets us save all of the changes we made there, which is very nice of it). So the combined effect of the two events in this improved autocommand should be to take care of All Your Autosaving Needs (TM).

The one thing to keep in mind with this version is that, well, it saves after basically every change to the buffer. This means that after every accidental command or mis-pasted text, Vim will write the file. You can always undo it right afterwards, of course, if you notice it, but still. (Plus, as the help implies, this will cause our file to be saved quite often—normally we would consider this a Win, but if you’re the kind of Vimmist that’s doing 382,000,000,000 editing operations a second, who knows.)

So, I’m going to go with something like at the end of a recipe when they say “Salt to taste.” Try it out, and maybe it’ll prove massively helpful. (I’m trying it out again now myself.) Or, your taste might run more toward the old InsertLeave one (or even to not using an autosave at all—I would not understand that point of view myself, but to own his each).

Thursday, February 19, 2015

Save time in Vim NOW with these five weird tricks

[Yo. If you like these, check for additional tricks in the series: see posts labeled “Vim tips”.—Ed.]
It’s not just, as Alex, Mathias, and Andrew point out, that you can refactor your .vimrc (though, to be sure, you can—and probably should!). You can also niftily rework Vim, as it were, using this full-blown programming language to redirect its interface (your keyboard) in ways that save you time.

Here are five excellent ways to do that, which I’ve gradually come across in that unending fountain of Vim wisdom, the World-Wide Web. (Where I can recall a source, I’ve linked to it; also, I’ve sometimes tweaked such snippets for my own I’ll-have-you-to-know completely well-intentioned purposes.) Add the code from each to your .vimrc to try it out.

1. Exit insert mode without using Esc


inoremap jk <Esc>

This is for the “how can you possibly use Vim you’re always at the body shop for new pinky fingers you spend all day hitting Esc” crowd. Your right index finger is on the j key by default, right? And k is right next to that. So this is a brilliantly fast way to get back to normal mode, no Esc required.

Credit: This tactic is crazy-common among Vim masters, of course. I think I first came across the idea in Steve Losh’s epic “Coming Home To Vim”.

2. Allow mispelings when :wq-ing


cabbrev ew :wq
cabbrev qw :wq

:cabbrev is one of the abbreviation commands. It’s specific to commands, so that in the first word of each of these lines, when we type it, will be taken as the second word (the command—in this case, :wq).

3. Switch windows with two keystrokes


noremap <c-j> <c-w>j
noremap <c-k> <c-w>k
noremap <c-l> <c-w>l
noremap <c-h> <c-w>h

I use these all the time. Normally, to switch windows (split windows) in Vim, you have to do Ctrl+W and then a direction key (j, k, h, or l). This changes that to just Ctrl and then the direction.

Credit: Chris McKinnel’s Coderwall protip, “Speed up your already speedy Vim development”.

4. Enter command mode with one keystroke


nnoremap ; :
nnoremap : ;

Likewise this—now, instead of Shift+; to run a command, you can just hit the ; key. YOU’RE SAVING A KEYSTROKE!

(No, seriously—if you use the Vim command line as much throughout the day as I do, you’ll find that every such keystroke adds up. Use this. You’re quite welcome.)

Credit: Also Chris McKinnel.

5. Start an external command with a single bang


nnoremap ! :! 

To run an external command from within Vim, we just have to prepend ! at the Vim command line (as in :!date or :!ls). So that makes at least three keystrokes: (Shift+); and Shift+1—unless you use this mapping, in which case you can just hit Shift+1 in normal mode.

BONUS!

 

6. Auto-save a file when you leave insert mode


autocmd InsertLeave * if expand('%') != '' | update | endif

There are other ways to do this—I used to use something like this variation on #1 above:

inoremap jk <Esc>:w<cr>

Then I saw Romain Lafourcade recommending this autocommand on Stack Overflow, and switched to it right away. (A huge benefit of this approach: it catches, for example, when you leave insert mode via Ctrl+C—the InsertLeave event is triggered, as you might expect, whenever we leave insert mode.)

After the event (InsertLeave) and file pattern (*, or “any file”), we have an if statement which checks for something in the % special character.* If we’re editing a file, this will give us its filename; if not, it will return '' (an empty string). So we check for a non-empty string, and if we get one, we run :update (which saves the file only if it’s been modified—basically like a smarter :w). Then we end the if.

(Worth noting also is the | line separator. In VimL, this functions like the semicolon ; does in many other programming languages, denoting the end of a line and allowing us to continue our code all on the same line of the file, if we wish. We use it here to write all three lines of our autocommand’s code on the one autocommand line.)

UPDATE: See my newer post on this particular trick: “A More Betterer Autosave In Vim.”

And yourself?


What weird tricks do you have in your .vimrc?

* See :help cmdline-special for the whole list of those characters.

Wednesday, February 18, 2015

Required reading for the predated-by-Vim folks in the audience

For those of us newer than Vim to the business of text editing, it’s important to remember that vi was the editor which got the “most efficient manipulator of text possible” reputation. Vim is, after all, only “Vi IMproved.”

Watching an experienced VI user inspires awe. The cursor seems to follow their eyes. Unfortunately, it takes about two years of daily VI usage to get to that point because the learning curve is so daunting. If you’ve used it every day for 1 year and 364 days, you’ll still struggle.
— Neal Ford, The Productive Programmer

We hear from one such experienced user (Jim Dennis) in what I’d guess is one of the most-voted-for answers on Stack Overflow, in reply to the question “What is your most productive shortcut with Vim?”

The answer’s title, to the extent to which answers can have titles on Stack Overflow, is “Your problem with Vim is that you don't grok vi.” Go read it. It’s all good and there’s no part that particularly calls for quotation other than this at the end:

I've only scratched to surface of vi's power and none of what I've described here is even part of the "improvements" for which vim is named! All of what I've described here should work on any old copy of vi from 20 or 30 years ago.

Tuesday, February 17, 2015

How to use :helpgrep in Vim

Vim’s quickfix mode, in case you weren’t already familiar with it, is meant to assist error correction in a situation involving compilers and error messages. You can save compiler errors to a file and have Vim list each one, with line numbers, the easier to jump to it. Errors show up in the quickfix window (a horizontal split below whatever you were already working on).

Vim also has :grep (and :vimgrep) commands. These use the OS’s grep or grep equivalent (or Vim’s own “internal grep”) to find patterns (search patterns) in a file. They can make use of the same window:


Related to these commands is a cool one, :helpgrep, which is (as its name might suggest) a grep dedicated to searching Vim’s help. It’s simple to use—unlike other grep commands, it doesn’t require a filename, and instead searches all of the various Vim help files for whatever pattern you give it.

The cpoptions option can be (is) a tad mysterious. It’s one of the option strings (like concealcursor, which we discuss in the book), and each character in the string stands for a bit of vi behavior which Vim will support. To see each time that cpoptions is referred to in a help entry, we could run this:

:helpgrep cpoptions

(It’s important to note that in this example, “cpoptions” is a pattern—a Vim regex pattern—even despite the lack of escaped or special characters here.)

When I run the command, I am taken to line 810 of the help file for TwitVim (since I’ve installed that plugin and its help file has been added to my Vim). This is printed on the command line:

(1 of 17): like 'magic' is set and 'cpoptions' is empty. (Essentially, this is

That’s the line that the cursor was put on (810 of the help file).

From here, we can navigate through results using quickfix commands. (As in the Vim help, the bracketed parts of the commands are optional; you can enter just the non-bracketed part to save time.)

:cn[ext]
:cp[rev]
:cl[ist]
:cfir[st] (needs the ir to distinguish it from :cf, which is for :cfile, an error-related command)
:cla[st] (needs the a to distinguish it from :cl, which is for :clist)
:cw[indow]

:cl shows all of the results in “list” format (rather like :messages shows messages).

Notice the last one. When we’re running :helpgrep, :cw can open all of the results in a jump-enabling (and search-enabling!) window: the quickfix window.


Each entry (as you can see from the illustration) shows the name of the help file it’s in, the line and column numbers, and then the relevant line.

To jump to an entry, just hit Enter. The usual navigation commands apply in this buffer, too: you can j and k your way around if you wish, but also do not forget / and the power of Search To Navigate™!

Thursday, February 5, 2015

Is it VimL or Vimscript?

This one’s easy:

It’s VimL, because it’s neither!

Allow me, if you will, to explain.

On The Pragmatic Bookshelf’s page for The VimL Primer (click the “Details” tab to see it), there’s a Q&A I did regarding the book’s topic (the language we’re discussing). Here’s one part of it:

2. There’s no such thing as VimL! What is this book about?

This book is about Vim’s built-in scripting language, VimL. This language is also known as Vimscript. Depending on how you look at it, either VimL is an alternate name for Vimscript or Vimscript is an alternate name for VimL.

Actually, there’s no real official name for the language; the closest seems to be the two-word “Vim script.”…

What madness is this? It’s quite true! the official name is “Vim script”. See the manual at :help exception-handling for proof:

The Vim script language comprises an exception handling feature.…

Does that not convince you? Wikipedia—WIKIPEDIA!introduces the language thusly:

Vim script… is the scripting language built into Vim.

(Wikipedia does list “Vimscript” and “VimL” as alternate names.)

So how does that, as I say, mean that the name is VimL? See farther down in the Wikipedia article:

Vim script files are stored in plain text format and the file name extension is .vim.

What files? Script files, in Vim. No, maybe files in Vim’s scripting language. No, what about script files in general, but when Vim’s editing them…

I expect you can see that at which I am getting: this is a confusing name until you join the words or uppercase the “s” in “script.” And at the point at which we’re doing that, we’re already changing the official name. We can change it to whatever we want!

Thus the end of my answer:

The relatively new name “VimL” (“Vim Language”) has been gaining in popularity in rough correlation with the growth of the code-sharing site GitHub. Its use is a matter of preference, but I do find it more easily distinguishable from mentions of Vim scripts or of writing generic scripts using Vim (in search results, for instance). It’s a short, tolerably memorable name, a bit catchy, and what I use throughout this book.

The reality, of course, is that I can’t change the Vim manual (although I could change the Wikipedia page…). I am content with accepting that this is a scripting language, and I suppose it technically works to call it the obvious (“Vimscript”). But as long as we have a cool distinguishable alternate name, my vote (with the vote of the masses) is for VimL.

Tuesday, February 3, 2015

Vim ranges: an introduction

According to a study conducted in 2015 by the National Association of Search Engine Users’ Board Of Suddenly Saying “Hey, Let’s Check The Google Trends for Vim-Related Searches”, Google gets a fair number of Vim-related queries. The first that has to do with everyday Vim use (coming in fourth most-common, after “vim linux”, “vi vim”, and “windows vim”) is “replace vim”.

On the face of it that might look like the lunatic keyboard smashings of a madperson OK with switching from The Other One True Editor to Notepad or TextEdit or perhaps even Emacs. Google it, however, and the top results are all for replacing text in Vim. They’ll typically show you a variation on this command:

:%s/term/replacement/g

Here, the colon (:) starts a Vim command on the Vim command line. The s is the command (a shortened form of :substitute). term is the search term, replacement is the replacement text, and g is a flag (think “global”) which we’re giving the command. What in the blue blazes is %?!

That, dear fellow Vimmist, is a range.

The range as line numbers


A range is a line number or set of line numbers. Given to a Vim command, it limits the command’s effect to the lines in the range.

We’ll go ahead and use :s as an example, since it’s such a common range-accepting command. Let us say that we mistook ourselves for Johnson (William Cowper’s publisher), hadn’t realized that the year was not 1785, and were taking it upon ourselves to, using Vim, edit this bit from The Garden (Book III of The Task):

1  I see that all are wand'rers, gone astray,
2  Each in his own delusions; they are lost
3  In chace of fancied happiness, still woo'd
4  And never won. Dream after dream ensues;
5  And still they dream that they shall still succeed,
6  And still are disappointed. Rings the world
7  With the vain stir. I sum up half mankind,
8  And add two-thirds of the remaining half,
9  And find the total of their hopes and fears
10 Dreams, empty dreams.

This is basically perfect, so all we can do is make gratuitous modifications which reassure us of our editorial power. For example, we might change “still” to “yet”. To do that on only line 3, where it first shows up, we could run:

:3s/still/yet

But “still” occurs on four lines—from 3 to 6. What if we wanted to get back at the genius for a supposed overuse of the adverb, and replace it on lines 3 to 5?

Well, for one thing, we’d have to put that g flag back on (otherwise, we’d only get the first instance of “still” on line 5, which has two). But most importantly, we’d have to give :s a range with an ending line number. We could do this:

:3,5s/still/yet/g

The range as special characters representing line numbers


Did I say that a range is “a line number or set of line numbers” (hint: I did)? It turns out that that’s not all that can make up a range. There are a number of special characters which we can use to stand for line numbers, too. The full list is at :help :range, but I will steal the top three from there because they’re perhaps the most basically useful:

.    The current line

$    The last line

%    The full file

Aaaaaaaaaaand there we are. I never did explain what % meant, did I? I mean until just now. Just now I did. So there: when you see the :%s in a Vim tutorial somewhere, you know not only the order (yes, I used to always confuse the order of the % and s, because in the early days, all I knew was “this jumble of characters that I just Googled tells Vim to replace text”), but also what the % means (in this context—it’s also a motion).

If we were on line 3 and wanted to change those same occurrences of “still”, we could use the . to say “from this line to line 5”:

 :.,5s/still/yet/g

We could change from line 3 to the end of the file:

:.,$s/still/yet/g 

Although by that point, we might as well decide to, in a fit of rageful fury, destroy the world (in a manner of speaking) and change all occurrences across the entirety of the file:

:%s/still/yet/g

So those are some helpful placeholders for actual line numbers in a range. There’s a deal more to ranges than this; we’re going to get into just one more aspect.

The range as a pattern which depends on the content of the file such that it effectively bypasses the concept of line numbers nearly altogether


This has the potential to be really profoundly effective. Vim allows us to substitute search patterns for line numbers within our range.

Back to our example text. The | is our cursor:

1  I see that all are wand'rers, gone astray,
2  Each in his own delusions; they are lost
3  In chace of fancied happiness, still woo'd
4  And never won. Dream after dream ensues;
5  And still they dream that| they shall still succeed,
6  And still are disappointed. Rings the world
7  With the vain stir. I sum up half mankind,
8  And add two-thirds of the remaining half,
9  And find the total of their hopes and fears
10 Dreams, empty dreams.

Let’s go easy on Cowper, shall we? (He’s the genius, after all. We are only editors.) Let’s only change the first two occurrences of “still” to “yet”.

There are other ways to do this, but here’s how we’d do it using a pattern within a range. We’ll tell :s to only replace instances occurring between “chace” on line 3 and “shall” on line 5:

 :?chace?,/shall/s/still/yet

Now that looks a bit more complex. It’s quite simple though in actuality: ?chace? is a backwards search pattern (remember that in Vim, ? searches backwards), /shall/ is a regular search pattern, and then the command (s) follows with its arguments (still and yet).

For further reading


Juicy details are at :help cmdline-ranges. A user-friendly take, as that help section will tell you, is in the user manual at 10.3 (:help 10.3).

Monday, January 26, 2015

The VimL Primer is out!

This is only a little note to let you know that some time ago, The Pragmatic Programmers released The VimL Primer!


Yes, technically, it came out over a week ago. In my defense, I have not yet held a paper copy in my own hands and Amazon still says that it’s not been released.

But. Who cares about whether the noble residents of the world’s largest remaining rainforest consider it released? You can get it today from pragprog.com!

Here. Hear from a few of the brilliant folks who have read it:

“Ben’s book is an eye-opener: I’ve used Vim for years but ignored the power and flexibility it offers. Now I’m paying attention. The VimL Primer is a gentle, thoughtful introduction to a new world for Vim users.”
 — Michael Easter (Software developer, ScreenScape Networks)

“The VimL Primer does an incredible job of showing you how to take one of the most enduring text editors and extend it so that it becomes even more useful. Do you want to bend Vim to your will? This is where you start!”
 — Jared Richardson (Principal Consultant, Agile Artisans, Inc.)

“Everything you need to start working on the next popular Vim plugin.”
 — Mac Liaw (CTO, CylaTech.com, Inc.)


Why are you still here? Go get it already! :D

Tuesday, January 13, 2015

On writing a Vim syntax file — and coding in Swift with Vim

In the August 2014 issue of PragPub, there is an article written by yours truly (that is, myself) about writing a Vim syntax file. Syntax files, as the article explains, are what give you the cool highlighting you get in Vim for just about any language under the sun (and for quite a few under other sizable stars, as well). The language we use for an example is Swift, which Apple had just introduced a couple of months before this issue came out.

So anyway: You should get that issue. (Seriously. In spite of my contribution, it’s a good one.)

You can get a hold of the syntax file we write, too, as mentioned toward the end of the article. It’s a Swift syntax file, though, and it is not comprehensive by any stretch of the imagination, since it’s just an example for the article. For the Swift-using Vimmists in the audience (I applaud you), I recommend that you look at what toyamarinyon has at GitHub:

github.com/toyamarinyon/vim-swift

It’s a work of VimL genius and (if you’ve read the article) great for learning more.