Vim Tips Wiki

Ipkiss/Restoring part of an original tip

< User:Ipkiss

Revision as of 10:08, August 15, 2007 by Ipkiss (Talk | contribs)

1,616pages on
this wiki


To restore parts of the text from the original tips on, the idea is the following:

  • make a visual selection of some text (in a wiki tip)
  • transform this text into a clever regular expression matching the same text, but in the same format as it is in the original tip (this involves escaping some characters, replacing newlines with <br>, etc...)
  • find in the tip the text matching the clever regexp
  • transform this text back into what the wiki expects
  • replace the visual selection with the transformed text

This is very safe, because the regular expression is extremely precise, we cannot get bad matches (or more precisely, we can, but these matches would then be identical to the good match, modulo some whitespace/end of line).

For more efficiency of the script, I provide a ready-to-use package with all the tips from, to which I applied some post-processing, detailed at the bottom of this page. In particular I have removed all the embedded \r characters (see Using vim to edit tips to understand why they are problematic).


  • Add the following to the Wikipedia.vim ftplugin, or to your .vimrc:
function! GetOriginalIndent()
    let old_reg1 = @w
    let old_reg2 = @/
    let old_hidden = &hidden
        normal gv"wy
        " Get tip number
        let tip_line = search('^|id=\d\+$', "wn")
        if !tip_line
            echoerr "Could not find tip number"
        let tip_num = substitute(getline(tip_line), '.*=', "", "")
        " Open the tip
        set hidden
        exe "e " . g:vim_tips_dir . "/tip" . tip_num

        " Prepend a newline and escape special regexp characters
        let pattern = escape("\n" . @", '\\/.*$^~[]')
        " Escape html special characters the way they are expected on
        " tips
        let pattern = substitute(pattern, '&amp;', '\&', "g")
        let pattern = substitute(pattern, '"', '\&quot;', "g")
        " Match html code
        let pattern = substitute(pattern, " *\n *", '\\s*\\%(<br>\\)*\\%(\&nbsp;\\)*', "g")
        " Search the new pattern in the buffer from
        let line_num = search(pattern)
        if line_num
            let line = getline(line_num)
            let pos_begin = match(line, pattern)
            let pos_end = matchend(line, pattern, pos_begin)
            let html_text = line[pos_begin : pos_end - 1]
            " echoerr "Pattern not found in the tip from " . pattern
            echoerr "Pattern not found in the tip from, sorry"
        " Transform the html back into wiki format
        let final_text = substitute(html_text, "&nbsp;", ' ', "g")
        let final_text = substitute(final_text, "<br>", "\n", "g")
        " No need to escape quotes in the wiki...
        let final_text = substitute(final_text, "&quot;", '"', "g")
        " ... but we do need to restore &amp;
        let final_text = substitute(final_text, '&\(amp;\|gt;\|lt;\|#\d\+;\)\@!', '\&amp;', "g")
        let g:debug = final_text
        " Back to the original buffer
        " Replace selection with the final text
        let @w = final_text
        normal gv"wpdd'>ddk
        " Restore registers
        let @/ = old_reg2
        let @w = old_reg1
        let &hidden = old_hidden

vmap z <esc>:call GetOriginalIndent()<cr>
  • Define in your .vimrc a variable indicating where you extracted the tips (adapt the path, of course):
let g:vim_tips_dir = "~/vimtips"


  • Edit a tip with Vim on the wiki
  • Make a visual line selection (using V)
    • Do not use a character-wise or block-wise visual selection if you don't like bad surprises :)
    • Do not span the selection out of the tip itself, or out of one of the comments
    • Do not select the signatures in the comments
  • Hit z
  • Enjoy

If the script didn't manage to find the highlighted text in the original tip, it will output an error message and do nothing. You can of course undo the action of the script using u.


  • If you get the message "Could not find tip number", make sure that you have set the g:vim_tips_dir variable properly... and that you are really editing a tip migrated from!
  • If you get the message "Pattern not found in the tip from, sorry":
    • Make sure you did the visual selection as described in the Usage section above
    • Try with a smaller selection first (use gv to reselect the previous selection, and o to go from one side of the selection to the other one)
  • If there was no error, but the indentation is still bad, it's probably that the original tip on had a bad indentation already. Too bad... At least you may have fixed line spacing issues :)
  • You may get an extra empty line before or after the part of the text you restored. I am not sure whether it is a bug in the script or the effect described in :help v_p. I probably won't bother fixing this issue.
  • The script has been well tested, but if you detect a bug notify me and I will try to fix it.

Notes concerning the tips archive

Here is how the archive has been made:

  • download all the tips using wget
  • (optional) get rid of the empty ones (like this one)
  • open them all in a vim instance, and run:
:sil! bufdo %s/\r//g
:bufdo exe "norm gg0d/code\<cr>5i\<cr>"
:bufdo exe "norm /^<!-- finish off the framework -->$\<cr>dG5o"
:sil! bufdo %s/\(<br>\|&nbsp;\)\@<!\(&nbsp;\)\+/ /g
:sil! wqa

That's all.

Around Wikia's network

Random Wiki