Journal

By Steve Challis

Recent Entries

Archive

RSS/Atom

Home

Projects

@schallis

Emacs Fill Prefix in Vim

November 6th, 2010 — 3 Comments — Permalink

  • emacs
  • vim
  • fill-prefix

I was recently presented with the problem of adding consistent prefixes to paragraphs of text whilst respecting the text width setting, for example when responding to email you may wish to prefix text with the authors initials like so:

SC> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
SC> eiusmod tempor incididunt ut labore et dolore magna aliqua.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non.

As a Vim user, I searched for a way to do this automatically and the best I came up with was to set Vim to use the GNU fmt program (available in the coreutils package for us Mac users stuck with lesser BSD equivalents) e.g. :se formatprg=fmt\ -p\ SC\>. The downside to this is having to specify the prefix manually. Emacs has the ability to automatically set the fill prefix and use that prefix to format paragraphs. Since you can write Vim plugins in Python, I came up with the following:

function! FillPrefix()
py << EOF
import vim

cur_line = vim.current.line

if not cur_line:
    prefix = '' # Unset prefix if called on empty line
else:
    prefix = 'n:' + cur_line.split(' ')[0]

vim.command('set comments=%s' % prefix)
EOF
endfunction

This takes the first word from the line you called it on and sets that to the prefix. Now when you hit gq on a line with that prefix, it'll be wrapped with a consistent prefix and text width. My colleague and fellow workflow enthusiast, Affan, came up with a more Emacs-like alternative which uses the cursor position to determine the prefix:

function! SetQuotePrefixFromCursor() 
python << EOF
import vim

cursor_col = vim.current.window.cursor[1]
quote_prefix = vim.current.line[:cursor_col]

if quote_prefix:
   set_cmd = 'set comments=n:%s' % quote_prefix
else:
   set_cmd = 'set comments=' # Cancel quoting prefix

vim.command(set_cmd)
EOF
endfunction

I saved this as fillprefix.py in my .vim folder and bound the <leader>fp shortcut to it:

 nmap <silent> <leader>fp :call SetQuotePrefixFromCursor()<CR>

As a side note, autocompletion (C-x C-O) came in handy when exploring the Vim Python module, although oddly requires Emacs style C-n and C-p to navigate.

Discussion

  • Tom 2 years, 6 months ago

    A simple pure vim solution would be to use visual block mode to select the region before which you want to insert text, then press I (insert before) and type the prefix, and voila, it gets applied to all lines selected.

  • Steve Challis 2 years, 6 months ago

    Tom, yes that was what I initially tried but the problem is that it doesn't respect the text width, so if you have a line of length 79 and tw=80 then when you try to add a prefix you'll just get a mess.

    Also, manually adding it in means that when you later add more text, you have to add the prefix to the new lines. The script described in the post essentially expands upon the built in comments code which means that when a line gets wrapped, the prefix is automatically added.

    I may rewrite this in vimscript to make it compatible with any version of Vim but I was initially just looking for a quick and dirty solution!

  • Drew Neil 2 years, 6 months ago

    I would suggest the following modifications:

    if quote_prefix:
       set_cmd = 'setlocal comments+=n:%s' % quote_prefix
    else:
       set_cmd = 'setlocal comments-=n:%s' % quote_prefix
    

    This way you add or remove the quote_prefix to the comments list for the current buffer. If you have any other tokens in your comments list, then they should be preserved.

Comments on this post have now been closed.

Log in

Powered by Mumblr – a basic Django tumblelog application that uses MongoDB with MongoEngine. Fork it on Github. Designed and developed by Harry Marr and Steve Challis.

Unless otherwise noted, everything here is available under the Creative Commons Attribution-Share Alike 3.0 license. Sharing is fucking cool.

Home / Projects / Recent / Archive / RSS /