Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??


I would like to share my experience of using a powerful editor to manipulate Perl files. Since I consider myself a demanding user, I heartily appreciate every feature that makes me type less and produce more. The tips presented here range from trivial to black magic but all have in common the fact that they are now part of my editing habits and it would be very painful for me to shift to any editor that offers less than that.
Vim is a multi-platform text editor, a clone of the venerable *NIX vi. Its name stands for Vi improved and it turns out that it has a really huge range of features.
As a text editor, Vim is suitable to write almost everything, but we are interested only on some of its features related to editing Perl scripts.
This short introduction does not cover all the editor features, for which there is a 370 pages manual, but just focus on some useful tips to improve your daily chores.
This is not a tutorial for Vim. There are plenty of them (the first one in the program itself) and teaching Vim would go beyond the purpose of this text.
This text deals with Vim version 6. Most of what I am presenting is also available in version 5.8, which was the previous stable version of Vim. The real difference, as long as we (programmers) are concerned, are:
- the manual has been reorganized and now there is a comprehensive user manual, organized by editing tasks, rather than editing features; - a new feature for folding text can make much easier to work with long, complex files.

Vim is the programmer's friend. Has been designed and implemented by a C programmer who knows what the daily problems are. But it has also dedicated features for Perl, Python and Ruby programmers.
It comes with an internal script language that can automate any editing task.
As many powerful tools, its learning curve is quite steep. I was not intrigued by its cryptic interface when I started working in Unix. But if you can get past the first obstacle, your effort will be rewarded. Vim is an agile editor that can work, as a minimum, with less than 400 KB of data storage and limited memory, while offering a vast collection of quick and powerful features.

Making your scripts more readable

The first aspect of using Vim with a Perl script is syntax highlighting. Your script is colored in various way, making evident the different components of the language. Variables, functions, quoted text, regular expressions, numbers and comments are represented with various colors, giving you an immediate feeling of what you are writing. It is like having an on-line compiler that can tell you immediately if you mistyped something.
It will save you quite a lot of edit-run-fix cycles. You will catch simple errors just as you type them.

Let the editor help you

Word completion is another feature that will avoid misspelling of repeating words. You type the beginning of a word, and then press "CTRL P". The first word that matches your starting text will appear at the cursor. If more than one words are available, the status line will inform you of that, and you can recall the next matching word by repeating the command.
Matching pairs is a built-in feature that tells you if you are correctly matching parentheses, brackets and braces. While you are entering text, whenever you type a closing symbol (")]}>"), Vim will show you the corresponding opening one ("([{<"), by sending the cursor for half a second to it. If the pairs are unbalanced (more closing than opening symbols) it will beep. After typing, or when reading someone else's script, if you want to check a matching pair, you can put your cursor on a opening or closing symbol and hit the "%" key. A priceless feature when you are dealing with nested parentheses.

Task automation

Vim's script is a full featured language that you can use to create new functions or to modify existing ones. However, you don't need to learn yet another language to deal with repeating tasks. Vim lets you record a stream of text and/or commands that can be repeated at will. For example, if you want to record a complex function template, you type "q" and another letter, let's say "t" and then start doing what it needs to be done. When you are finished, you press "q" again and the macro is recorded into buffer "t". To replay what you have recorded, press "@t" and all your actions are repeated starting from the current cursor position.
A clean explanation can be found in Vim's help, by typing
:h q while in command mode.
The map and ab[breviation] commands allow you to create quick macros using only editing commands, without using the script language.

Advanced readability

Highlighted syntax is great, but sometimes is not that useful. We often use the Perl DBI to communicate to a database, using another language, SQL, which has different keywords and syntax. Whenever we write SQL, its appearance is flattened inside quoted text.
Vim can give you a hand, through Embedded syntax. You can define an alternative set of rules to highlight SQL. Let's see how and then we'll comment its meaning.
Find your syntax file for Perl. In *NIX it should be
Towards the end of the file, before the line
let b:current_syntax = "perl"
insert the following:
syn include @Sql <sfile>:p:h/sql.vim syn region perlSQL start="qq{" end="}" contains=@Sql keepend syn region perlSQL start="qq\[" end="\]" contains=@Sql keepend syn region perlSQL start="<<SQL" end="^SQL" contains=@Sql keepend
You should become system administrator to be able to edit such file.
These instructions tell Vim to treat anyhthing within "qq{" and "}" as SQL code, whose syntax is described in the file "sql.vim" in the same directory. The same treatment is reserved to SQL code within "qq[]" or in here documents starting with "<<SQL".
I am using different delimiters, so I will be able to write statements like the following:
my $sql1 = qq{ SELECT fieldname FROM $tab_array[0] WHERE otherfield = ( ? ) }; my $sql2 = qq[ SELECT fieldname FROM $tab_hash{$current} WHERE otherfield = ( ? ) ];
When I want to use qq to double quote normal Perl code, I just add a space between the operator and the braces:
my $sign = qq {DO NOT SELECT FROM MY TABLE !}
Another useful application of the same feature is to embed Perl code inside HTML.
You can enter similar statements inside the HTML.vim file, to instruct vim to consider text between <code> and </code> as Perl. Then, writing a post for PerlMonks is going to be much easier. ;)

Exporting readability

You are pleased with your highlighted syntax and you would like to use it for a seminar, or to publish your latest brilliant code on your website. However, when the Perl script leaves your editor, it is back in boring black an white.
Fortunately, Vim comes with a script to export the currently highlighted file into a fully formatted HTML file. No sweat. Just enter this command while in command mode:
:runtime! syntax/2html.vim
And you'll have a file with the same name as the original, plus the ".html" extension, ready to astound your audience.
It is a slow procedure and the result file is quite big, but you can't have it all, can you?

More advanced features: Perl tags

Whoever has experience of C programming in *NIX should have come across the "ctags" program. In simplified terms, it is a mapping program that will read the source files and produce an index of function and variable names. Several editors can recognize such indexes and, when you point at a name in your source file they can, upon request, open the related file and show you that variable/function.
Vim offers the same service for Perl files. Distributed with Vim there is a script named "", which can analyze a list of files and create a "tags" index. After this process, all identifiers in your scripts become hyper-textual. You can put your cursor on a function name, press "CTRL ]" and Vim will open the relevant file and find that function for you. When you want to come back to your original script, "CTRL T" will beam you back.

Wizardry: editing with Perl

Vim is a fully featured editor. It supports extended regular expressions, even though its syntax is different from Perl's. It would be nice to use the same syntax within your code and when you write it as well. Also, sometimes you would like to enter some Perl instructions to manipulate your text. On the other hand, when writing a script to manipulate a complex text, you would just love to have a handler to the innards of the editor, so that you can combine Perl code with multiple text buffers, undo features, windows resizing and so on.
Vim lets you do that. All you need is to get the source code and recompile the editor with the appropriate option (requires Perl 5.004 or later already installed before you compile).
# ./configure --enable-perlinterp # make # make install
Now from Vim command mode you can enter the :perl {cmd} command and execute any Perl instruction. Or you can use the [range]:perldo {cmd} which will execute command for each line in the range, with default to the whole text in the editor.
There are dozens of functions available to interface Vim to your Perl's code. You can get full details from Vim's help, entering h perl
Think about the possibilities:
You can use the "tr///" operator on a range of lines, instead of being limited to Vim's "s///" (which, let's not forget, uses the old syntax full of chopsticks like s/\<\(this\) \(that\)\>/\2 \1/ instead of s/\b(this) (that)\b/\2 \1/). Or you can sort a range of lines with a customized Perl function, without leaving your editor.
Or you can even test snippets of your code, to see if they give you the expected result, still within the editor.
You should be dying to see some examples and here we go:
First, a customizable word count
:perl $count = 0 :perldo $count += split /[;_<> ]/, $_ :perl VIM::Msg($count)
Then, a special sorting routine, getting text from the editor's current buffer and writing back to it:
:perl @lines = sort {$a <=> $b} $curbuf->Get(1 .. 15) :perl $curbuf->Set(1, @lines)
Or, in short,
:perl $curbuf->Set(1, sort {$a <=> $b} $curbuf->Get(1 .. 15))
Finally, we can combine using Perl's RegEx syntax with Vim's range facilities. This example applies the substitution pattern from row 10 to 30, and then uses the "tr///" operator to delete all non hexadecimal characters from lines 40-45.
:10,30perldo s/\b(:?Monks|advocates)\b/PerlMonks/ :40,45perldo tr/A-F0-9//cd
I am sure that some of the Monks must have watering mouths at this code, especially the ones with a knack for one-liners.


Despite circumstantial evidence of the contrary, I am not advocating for Vim. Everyone is free of using the editor that best suits one's purposes. For my side, as an experienced programmer, I chose Vim for the great flexibility and some of the advanced features that I presented here.

Note to non-Vim users Please don't take this post as a challenge against your favorite editor. I am talking about Vim because I know how to use it (or, at least, I have been using it confidently for long enough), trying to be helpful.
I would appreciate if someone could match the same advice for other editors, not in the spirit of "mine is smarter than yours" but just to offer the same range of features to the community.

I hope I have provided some useful ideas.

update Title changed following crazyinsomniac advice.
 _  _ _  _  
(_|| | |(_|><

In reply to Editing features for advanced users by gmax

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others romping around the Monastery: (10)
    As of 2014-07-28 06:55 GMT
    Find Nodes?
      Voting Booth?

      My favorite superfluous repetitious redundant duplicative phrase is:

      Results (191 votes), past polls