Smokes your problems, coughs fresh air.

Tag: VIM

XSel, for command-line operations on X selections

Since I first learned that Windowmaker installs two command-line tools, wxcopy and wxpaste, to play around with X selections, I have wanted to be able to make and use X selections from my Bash shell. wxcopy and wxpaste never did what I expected them to do, so I gave up until recently I learned about all the different X selections.

By default, wxcopy and wxpaste operate on the CUT_BUFFER[n] selections. These are deprecated. That’s why I could never make it work, because modern applications use only CLIPBOARD and SELECTION. So, wxcopy is pretty useless (unless its used to copy something to paste with wxpaste). With this knowledge wxcopy does seem useful thanks to its -selection [selection-name] flag, but this doesn’t seem to work; I only get the contents of CUT_BUFFER. This is not how the feature is advertised:

-selection [selection-name]
The data will be copied from the named selection. If cutting from the selection fails, the cutbuffer will be used. The default value for the selection name is PRIMARY.

Enter XSel

Fortunately, there’s XSel by Conrad Parker, a program which made him passionately hate the ICCCM.

XSel does exactly what it advertises. I’m actually surprised that I never heard of it before. It’s available in Gentoo, Debian and Ubuntu, so it’s a breeze to install.

Among its features are: --append, --follow, --clear, --delete (very weird, but logical if you understand X IPC), --primary, --secondary, --clipboard, --keep, and --exchange. Read the man page for more. It’s an excellent read.

One of the places where I’m going to use this tool is when copy-pasting to and from VIM. I really like how this compares to using :insert or :r!cat</dev/tty and then using the pointer to paste (or (Shift+)Insert with my custom XTerm config). Now, to paste something in VIM, I can simply type:

:r!xsel

I use the following to copy any amount of text from VIM. This works much better than fooling around with the mouse:

:'>,'> !tee >(xsel -i)

The '>,'> range is entered automatically if you press : while in visual (selection) mode. You could enter any range there, or even % to select the whole file. To copy to the CLIPBOARD instead of the PRIMARY, use xsel -i -b in the above example.

If someone know of a way to make VIM pipe something to a program without replacing the given range with that program’s output, I could simplify this…

Pasting in Vim

When you want to paste in Vim, you want vim to not use indenting, because that messes up your code. I used to use :insert, but on some machines, it would still indent. I discovered the :set paste command, which works quite well.

VIM insert mode shortcuts

A few months back, I stumbled upon a blog post with some interesting VIM shortcuts for within insert mode.

  • Ctrl+t and Ctrl-d adjust the current line indent one level to the right and left, respectively.
  • Ctrl+w deletes the last word. I already use this one a lot because it’s the same as in Readline’s Emacs mode (which I prefer over its vi mode).
  • Ctrl+u deleted all the way to the first non-whitespace character.

But the best stuff was in the comments:

  • Ctrl+o enters normal mode for just one command and then returns to insert mode. I find myself very often going to normal mode ‘temporarily’. This should make these occasions pass quicker.
  • Ctrl+y repeats the character at this position from the line above in this line. Ctrl+e does the same for the line below.
  • Ctrl+x Ctrl+l can be used to copy a whole line, allowing you to cycle through the lines with Ctrl+P and Ctrl+N.

VIM tips for editing prose

I was transcribing a draft for a manuscript. Using VIM, of course. But, I found my VIM skills to be lacking somewhat, enough to become sufficiently annoyed to investigate the holes.

Word wrapping

The first thing that I wanted to learn to remember was how to control word wrapping and, especially, how to rewrap text.

I had noticed already that on my current machine, VIM enables word wrapping by default for .txt files. I liked this, except I had forgotten long ago (or never properly remembered) how to rewrap lines. This can be done with gq. gq operates on the current selection or on the argument (a number of words/characters/sentences/paragraphs/etc).

Soon, I decided to turn my .txt into a simple TeX file (to be able to add annotations using TeX comments). This disabled the word wrapping, so I had to find the setting to control this. There's actually two settings:

  • wrapmargin defines how close the text may approach the right edge of the VIM window before it starts wrapping,
  • whereas textwidth tells VIM to start wrapping when a fixed number of characters is approached.

Because VIM doesn't do wrapping by default for .tex files, I added the following modeline to the bottom of my draft:

% vim: set textwidth=80 spelllang=nl:

Note that I find 80 characters way too small for most programming tasks, but very convenient as a width for reading prose from a screen. On occasion, I've even used width: 80ex; in the CSS of a website.

Sentences and paragraphs

A few movement commands that I've never used enough to remember well are {/} and (/). } and { are used to move a paragraph forward or backward, respectively;) and ( are used to move a whole sentence forward or backward. This is particularly useful while editing prose.

To quickly select a paragraph, for example, you can easily move to the beginning of the paragraph using {, press v to start a selection and go to the end of the paragraph with } (or type 2} to also select the next).

If you want to delete a sentence, go to the start of the sentence (using either ( or )) and type d). It’s as easy as that.

If deleting the sentence fucked up the formatting of your paragraph, reformat by going to the beginning of the paragraph and typing gq}.

Proper punctuation and other special characters

TeX offers a method to construct special characters using plain ASCII source files. In the past, in my inability to properly configure everything for UTF-8, I’ve often made use of this. In TeX, \'e will be turned into é, \"i into ï, etc. This can be convenient, but it’s much more convenient to have an environment that’s properly configured for UTF-8. To enter special characters on my US keyboard layout (standard in The Netherlands), I’ve added compose:ralt to my XKB options. Using this option I can press Right Alt followed by a punctuation character, followed by a character to combine it with.

Clearly, constructing special characters on the level of X holds many advantages over having to do this differently for each and every application. This way I can also type in ë in this HTML <textarea> instead of having to type &euml;. (In HTML, it’s actually better to use a numeric character reference, such as &#235; instead of &euml;, because that doesn’t require the loading of the DTD, but that’s another rant altogether.)

If you don’t have an accommodating XKB configuration, it’s still possible to enter the characters directly at the VIM level. In VIM, :help digraph (see also the on-line HTML version) tells you everything about it. In short, use Control+K followed by a punctuation character, followed by a character to compose special characters in a way similar to X.

What’s very nice about VIM’s default setup is that it allows you to also easily create proper opening and closing single and double quotes. In TeX these are traditionally done using combinations of back-ticks (`) and apostrophes ('). TeX’s default behavior can be problematic, a good reason to switch to Unicode.

char.VIM digraphTeX
Ctrl+K, ", 6``
Ctrl+K, ", 9''
Ctrl+K, ', 6`
Ctrl+K, ', 9'

Something else that becomes very easy with VIM’s digraphs is entering proper punctuation characters, such as em/en dashes. These are done by following Ctrl+K with a hyphen and a capital N or M. In TeX these could already be done by simply entering two or three hyphens, but if you prefer it that way, you’re probably better of with the UniCycle plugin for VIM, which I personally don’t dig. Anyway, you’re running out of excuses to let -- appear in your production documents.

char.VIM digraphTeX
Ctrl+K, -, N--
Ctrl+K, -, M---

I have to admit that I’ve waited an awful long time before finding this out. I’m ashamed to tell you that I’ve often gone to Alan Wood’s Unicode resources to look up a character and copy/paste it into an application. 😳 Now, at least I don’t have to further embarrass myself when I’m using VIM.

What remains is to configure XKB in such a way that I don’t need to use VIM digraphs for punctuation. Then I will no longer need to use character references for punctuation at times like these, when I’m typing HTML/XML outside of VIM (or, worse, using copy/paste from VIM into this <textarea>, which I just did :oops:). Let’s see if I can get XKB to compose these using the same combinations as VIM. That is where I’ll continue my quest next time.

Editing Wikipedia/MediaWiki articles with VIM

Wikipedia has a number of tips for people who like to edit Wikipedia articles with VIM.

Of course, it all starts with opening an article in VIM. How I do this depends on my mood: I can open it by firing GVIM using Vimperator or I can mount the wiki with WikipediaFS. I prefer the latter.

Spell-checking

One tool that’s very convenient for editing large sections of prose is VIM’s built-in spell-checker. Example:

set textwidth=0
set spell spelllang=nl

Wrapping, matching and folding

There’s some more useful stuff that I copied to “ftplugin/mediawiki.vim” in “$HOME/.vim/“:

" Wikipedia articles often only have line-breaks at the end of each paragraph,
" a situation Vim by default doesn't handle as other text editors.
setlocal wrap linebreak
setlocal textwidth=0

" No auto-wrap at all
setlocal formatoptions-=tc formatoptions+=l
if v:version >= 602 | setlocal formatoptions-=a | endif

" Make navigation more amenable to the long wrapping lines.
noremap  k gk
noremap  j gj
noremap   gk
noremap   gj
noremap  0 g0
noremap  ^ g^
noremap  $ g$
noremap D dg$
noremap C cg$
noremap A g$a
inoremap   gk
inoremap   gj

" utf-8 should be set if not already done globally
setlocal fileencoding=utf-8
setlocal matchpairs+=<:>

" Treat lists, indented text and tables as comment lines and continue with the
" same formatting in the next line (i.e. insert the comment leader) when hitting
"  or using "o".
setlocal comments=n:#,n:*,n:\:,s:{\|,m:\|,ex:\|}
setlocal formatoptions+=roq

" match HTML tags (taken directly from $VIM/ftplugin/html.vim)
if exists("loaded_matchit")
    let b:match_ignorecase=0
    let b:match_skip = 's:Comment'
    let b:match_words = '<:>,' .
    \ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' .
    \ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' .
    \ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>'
endif

" Other useful mappings
" Insert a matching = automatically while starting a new header.
inoremap   = =(getline('.')==''\|\|getline('.')=~'^=\+$')?"==\Left>":"="

" Enable folding based on ==sections==
:set foldexpr=getline(v:lnum)=~'^\\(=\\+\\)[^=]\\+\\1\\(\\s*\\)\\=\\s*$'?\">\".(len(matchstr(getline(v:lnum),'^=\\+'))-1):\"=\"
:set fdm=expr

To have this automatically executed when opening files ending in .mw:

"autocmd BufRead,BufNewFile *.mw setfiletype mediawiki" > $HOME/.vim/ftdetect/mediawiki.vim

Syntax highlighting

Additionally, if you want to have syntax highlighting for MediaWiki articles, you can save this syntax file to $HOME/.vim/syntax/mediawiki.vim.

With Vimperator it almost feels as if I can control Firefox

Wednesday, after returning to Groningen from Barcelona, I saw Ying using Vimperator. I was sold immediately.

I like to use the keyboard. Point and click is not really my cup of tea. It just doesn’t work without a touch screen. (A while ago I had the opportunity to see an expensive tilt-able touch screen in action and I was quite impressed by how suddenly a GUI became less of a disaster.) I’m an avid VIM user. Although I’ve tried training myself to Emacs, I’ve never made the switch. Even if I would have, this wouldn’t have changed the fact that I’m a shell person, not a desktop person.

Editing in an external editor

I do a lot of writing from my web browser (Firefox). This is not the most enjoyable activity imaginable using the typical <textarea>. It’s not that HTML textareas are so bad, it’s just that I don’t like typing anything extensive without using VIM.

The It’s All Text! Firefox add-on is one way to solve this problem. It adds a small “edit” button to the bottom right of all textareas. (It also adds a context submenu, but this can only be used to edit the whole page’s source (which I found to be a little bit disappointing as I’d rather seen that this acted on just the textarea when going there from a textarea).) The button executes an external editor of choiseGVIM.

Using Vimperator, when in insert mode (inside a textarea), I just have to press Ctrl-i to execute GVIM. The It’s All Text! add-on has thus been deprecated.

Better WindowMaker integration

Due to my reluctance to switch to a tiling window manager, I’m still using WindowMaker. Starting Firefox in WindowMaker is a bit of a nuisance because the main window opens too far out beyond the top left of my workspace. The only way to change this is to tell it to start maximized. However, the main window and the dialogs have the same WM_CLASS and I was somehow annoyed with getting all the popups maximized as well.

Vimperator starts these windows within the browser tabs, so there’s no longer a good reason not to start Firefox maximized. This saves me another keystroke whenever I begin a new browsing session.

Modes

Normal mode
In normal mode, I can perform all navigational tasks quickly an concisely. Especially identifying and following links is revolutionary. No more remembering access keys for every web app. I can just press f and type a number. The View Access Keys extension is no longer necessary.
Insert mode
I had never considered how much a seperate insert mode would have made me feel more in control of Firefox. The fact that I can escape it and scroll a bit or follow a link before continuing to type is priceless.
Pass-through mode
There are many modern web applications such as Gmail that have keystrokes conflicting with Vimperator. The great thing about Vimperator is that it wins. But, by pressing Ctrl-z, you can make the web page win until you escape the mode.

There are more modes, but I’m not here to write a tutorial. 🙂

Scrolling

I have many of the scrolling options that I’m used to in VIM. Most importantly, I can scroll half a page instead of a whole page! Before, I’ve spent a lot of time mucking around trying to find out how to make Firefox do this and the only extension that seemed to be able to deliver was Firemacs which I shied away because it did away with many of Firefox’s default key bindings, which is ironic because Vimperator seems much more extreme in this regard. 😛

Flash focus

On thing that I would really like Vimperator to do is to disable Flash content from stealing focus. That would remedy the last type of situation where I simply don’t feel in control of my web browser.

VIM modelines for per-file configuration

The MediaWiki developers use tabs instead of spaces for indentation. This can be annoying for someone like me who has configured VIM to work with spaces by default—annoying because I don’t want to enter something like :set tabstop=4 noexpandtab shiftwidth=4 every time that I open a file. Adding different conditions for each project to my .vimrc is probably possible but not much fun.

The other minute, when I opened the sources of my Semantic Gallery extension for MediaWiki, I noticed that I had been mixing tabs and spaces again. So it was time to look up the VIM feature which allows you to put a configuration line in a comment at the bottom of a file. This quote is another perfect example of why it’s good practice to blog about such things. I remembered that the last time that I had wanted to do this, I could not find a useful search string at all and resorted to finding back an example in the code where I had first seen it and modifying that. Now, I thought I’d have to do the same, but from a quick googling I learned that I’m not the only one to use his blog as a memory extension. 🙂

Good. Hopefully, from now on, I’ll remember that this configuration-thingy-at-the-bottom-of-a-file is called a modeline, so that I can just enter :help modeline in VIM the next time that I forget where the colons have to go.

An example for when I do forget:

# vim:set ts=4 sw=4 noexpandtab:

This reminds me of my many searches for Heredoc syntax when I didn’t know that they were called Heredocs.

© 2024 BigSmoke

Theme by Anders NorenUp ↑