Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Vim for PerlMonks nodes

by gmax (Abbot)
on Jun 29, 2003 at 19:59 UTC ( [id://270014] : perlmeditation . print w/replies, xml ) Need Help??

In a recent post, it was discussed the possibility of having offline previewing for PM nodes.

While everybody agrees that no such thing is possible, I would like to share my personal method for writing posts.

It is based on Vim, my editor of choice.

Basically, the method consists in creating a new syntax file, where to embed perl syntax into HTML syntax, and adding a few instructions to deal with PM links. Of course, being offline, it does not show the correctness of real links, but at least it can warn you if something is wrong.

An example

Here is how my screen looks like when I am writing a PM node. Notice the Perl code happily highlighted in full details, so that I have a minimum of syntax checking even if the code is untested.

My apologies for the ones who are using the dark theme to view this page. I know that it does not show at its best. However, it is not supposed to be a mandatory color set, just an example.

<h3>PM highlighting</h3>
<p>This is a chunk of normal text.</p>

# This is (untested) Perl code
my $x = 0xDEADBEEF;
my @many = map { $_ * $_ } (1 .. $x);

<p> This is a
<a href="">normal link</a> </p>

<p> This is a [id://123456|PerlMonks tag].  </p>

<p> Notice how this unescaped $array_element[0] is shown
immediately as a PM link, so that
<i>it doesn't escape</i> my attention </p>

<p> Instead, if I use <code>$array[0]</code>
I know that I am on the right track ...  </p>

This example was made with Vim's TOhtml function.

How to do it

In Unix systems, where you usually don't have access to Vim syntax files (normally found at /usr/share/vim/vimXX/syntax), you can create your own syntax files in your home directory.

  1. Create two directories "~/.vim" and "~/.vim/syntax".
  2. in ".vim", add a file named filetype.vim, containing the following lines
    " --- cut ---------------------- " my filetype file if exists("did_load_filetypes") finish endif augroup filetypedetect au! BufRead,BufNewFile *.PM setfiletype PM augroup END " --- cut ----------------------
  3. In the directory "~/.vim/syntax", create a file PM.vim, containing
    " ---- cut --------------------- " Vim syntax file " Language: PM " Maintainer: noone " Last Change: 2003 Jun 26 " Load the HTML syntax. runtime! syntax/html.vim " UPDATE - (Thanks to zakb) unlet b:current_syntax " add Perl extensions :syntax include @Perl syntax/perl.vim :syntax region htmlPerl start="< code >" end="< /code >" contains=@Per +l keepend " remove spaces around code tags ! let b:current_syntax = "html" :syntax region PMlink start="\[" end ="\]" if version >= 508 || !exists("did_PM_syn_init") if version < 508 let did_PM_syn_init = 1 command -nargs=+ HiLink hi link <args> else command -nargs=+ HiLink hi def link <args> endif HiLink PMlink Underlined delcommand HiLink endif let b:current_syntax = "PM" " vim: ts=8 " --- cut ----------------------
    Don't forget to remove the spaces that I added around the code tags in this example, to avoid clashes with the real code tags around the code.
  4. In Windows, unless you are using cygwin, you can't apply this recipe. However, usually you have access to the syntax files (c:\vim\vimXX\syntax\). Therefore you can modify directly html.vim and filetypes.vim (in the upper dir). In html.vim, add the perl extension towards the end, just before the "let b:current_syntax ..." line. In filetype.vim, add a line saying
    au! BufRead,BufNewFile *.PM setfiletype PM
    just close to any other similar line. In Windows, since filenames are not case sensitive, you may want to change *.PM into *.PMonks, to avoid confusion with *.pm, which are Perl modules.
  5. Now, whenever you create or open a file with extension .PM (uppercase, or .PMonks in Windows), you can enjoy the PerlMonks highlighting.

This method has been tested on Linux (Mandrake and Debian) with Vim 6.1 and 6.2 and on Windows XP with Gvim 6.2 and Vim 6.2 under cygwin.

Update (1)
The method depicted here is not something I have invented overnight. :) It is a standard procedure adopted for syntax files whenever you need to insert the syntax of a language inside another one. For example, C's syntax is embedded into C++'s, POD's into Perl's, and so on.
However, you can use the ~/.vim/syntax directory to override the effects of Vim's syntax when you are not satisfied with the normal one. For example, I have an account on a Debian box, but I don't have root privileges. I am satisfied with the version of Vim (6.1) installed there, but I would like to have the updated syntax files that came with Vim 6.2. Therefore I copied my favorite syntax files into ~/.vim/syntax and I now have full control on them, since Vim searches for syntax files first in my home directory and then in /usr/share/vim.

further reading

For more on Vim with Perl, please refer to TVSET's excellent article.

Note I was not certain where to post this node. It is not Code, nor does belong to Cool Uses for Perl. It is not even a Discussion, because I am not proposing something that will change the Monastery. It looks sort of off-topic-but-faintly-related to me, so I guess Meditations is OK.

Update (2)
Thanks to zakb for the helpful hint. Adding the unlet statement makes it work in a system where it previously didn't. Fixed.

 _  _ _  _  
(_|| | |(_|><

Replies are listed 'Best First'.
Re: Vim for PerlMonks nodes
by TVSET (Chaplain) on Jun 29, 2003 at 22:24 UTC
    Excellent! And the timing is perfect, since I was thinking about implementing exactly what you did and exactly the way you did it. ++ :)

    PS: Not to mention having my name typed by the GrandMaster of Vim :)

    Leonid Mamtchenkov aka TVSET

Re: Vim for PerlMonks nodes
by zakb (Pilgrim) on Jun 30, 2003 at 10:43 UTC

    Update: gmax says it works with colons, and it works for me; in fact, it works either way (with colons / without).

    Update2:The reason it fails for some is because recent versions of syntax/perl.vim check to see if b:current_syntax is defined, and if so exit.

    You need to put unlet b:current_syntax before the syntax include line.

    I think the reason it's not working for some people is hat the syntax lines in step 3 should not be prefixed by colons ':'.


    " add Perl extensions :syntax include @Perl syntax/perl.vim :syntax region htmlPerl start="< code >" end="< /code >" contains=@Per +l keepend " remove spaces around code tags ! let b:current_syntax = "html" syntax region PMlink start="\[" end ="\]"


    " add Perl extensions syntax include @Perl syntax/perl.vim syntax region htmlPerl start="< code >" end="< /code >" contains=@Perl + keepend " remove spaces around code tags ! let b:current_syntax = "html" syntax region PMlink start="\[" end ="\]"

    Not forgetting, of course, to remove the spaces.

Re: Vim for PerlMonks nodes
by Coruscate (Sexton) on Jun 30, 2003 at 04:38 UTC

    Everything works for me except that text between code tags does not have perl syntax highlighting. Yes, I did remove the spaces. Yes, I do have the perl syntax file (':set syntax=perl' gives me my lovely perl highlights). Version information follows:

    If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, please reply to this node or /msg me to inform me as to what is wrong with the post, so that I may update the node to the best of my ability.

      I had the same problem, and I found a workaround.

      Put the "add Perl extension" stuff in html.vim directly and you'll get the syntax working for Perl as well.

      I have no idea why it works, but it does!