TheDamian has asked for the wisdom of the Perl Monks concerning the following question:

I'm currently finishing up my new book (Perl Best Practices, O'Reilly) and I'm writing an appendix showing how to set up certain editor facilities that make Perl programming easier.

As a dedicated vim user, I can handle that side of things fine, but when it comes to Emacs, I'm Escape-Meta-Alt-Control-Stupid.

I would be very grateful (and would be sure to acknowledge in the book) if some of my learned fellow monks who are fluent in both vim and Emacs could offer me a consensus on the best way to translate the following .vimrc configurations into something suitable for a user's .emacs file.

The first pastes in a handy pair of lines for debugging...

:iab dbg use Data::Dumper qw( Dumper );^Mwarn Dumper [];^[hi

The second set load prefab document templates from a standard location...

:iab stdappt ^?^[:r ~/.application_template^M :iab stdmodt ^?^[:r ~/.module_template^M :iab stddoct ^?^[:r ~/.documentation_template^M

The third sets sane tab-stoppage...

set tabstop=4 "An indentation level every four columns" set expandtab "Convert all tabs typed into spaces" set shiftwidth=4 "Indent/outdent by four columns" set shiftround "Always indent/outdent to the nearest tabstop"

If anyone would like to suggest better vim solutions as well, I'd be doubly grateful.

And I'll also happily consider adding in the equivalent config advice for other major editors (e.g. UltraEdit, BBEdit, TextWrangler) if anyone feels competent to offer it.



Replies are listed 'Best First'.
Vim Settings for Perl
by Smylers (Pilgrim) on Mar 23, 2005 at 11:01 UTC

    I gave a talk on Vim tips and tricks for Perl programmers at YAPC Europe in Belfast last year. Here's some of the useful config I mentioned.

    • Activate the Perl-filetype settings that come with Vim for many types of files, including Perl code:

      filetype plugin on

      You can put your own config that you want applying only to Perl files in ~/.vim/after/ftplugin/perl.vim; this will be applied after the system-wide settings (so can override them). You should use setlocal rather than set in such files, so that any settings don't 'leak out' to windows that are opened later for other types of files.

    • Indenting — I have these directly in my ~/.vimrc, applying to all filetypes:

      filetype indent on " per-filetype config set tabstop=8 set expandtab set smarttab set shiftwidth=4 " or 2 or whatever set shiftround set autoindent

      Note that smarttab means that BkSpc at the beginning of the line will outdent by one level (not just delete a single space character), so that Tab and BkSpc together 'feel' like they're operating on tab characters, even though only spaces appear in your file. I leave tabstop set at 8, since that makes it more obvious when other people give you files with nasty tab characters in them!.

    • Navigating between files — put this in your ~/.vim/after/ftplugin/perl.vim and then when the cursor is on a module name (such as File::Temp) you can press Ctrl+W f to open the source (...wherever/lib/File/ of that module in a split window, or gf to load it in the current window:

      setlocal isfname+=:
    • Mappings — keystrokes to execute common commands. Save and check syntax with _c:

      nnoremap <buffer> <silent> _c :w<Enter>:!perl -wc %<Enter>

      Look up docs function under cusor with _f:

      nnoremap <buffer> <silent> _f :perldoc -f <cword><Enter>

      Look up docs for module under cusor with _m:

      nnoremap <buffer> <silent> _m :perldoc <cword><Enter>

      Tidy selected lines (or entire file) with _t:

      nnoremap <buffer> <silent> _t :%!perltidy -q<Enter> vnoremap <buffer> <silent> _t :!perltidy -q<Enter>

      If you're using Vim's own gui (not running it in a terminal window) then running perldoc may try to invoke a pager that can't cope with the limited facilities available. I have these in my ~/.gvimrc to use Less and make it behave itself:

      let $PAGER = 'less' let $LESS = 'dQFe'

    If anybody would like the full paper or slides, please mail me on and ask.

      I like having perldoc output to a split window, and I wanted to output module documentation if you were on a 'use Module;' line, so I recently came up with this (my vim-foo could probably be better):
      function! PerlDoc() normal yy let l:this = @ if match(l:this, '^ *\(use\|require\) ') >= 0 exe ':new' exe ':resize' let l:this = substitute(l:this, '^ *\(use\|require\) *', "", "") let l:this = substitute(l:this, ";.*", "", "") let l:this = substitute(l:this, " .*", "", "") exe ':0r!perldoc -t ' . l:this exe ':0' return endif normal yiw exe ':new' exe ':resize' exe ':0r!perldoc -t -f ' . @ exe ':0' endfunction "Display docs for built-in functions when cursor is on function name "or for modules when cursor is on 'use' or 'require' line. map ,h :call PerlDoc()<CR>:set nomod<CR>:set filetype=man<CR>:echo "pe +rldoc"<CR>
      Updated. (I knew nothing about Vim programming before I started took a couple of hours to come up with the first version of this, so comments, etc., welcome).
      Update: Added set nomod.
      Update: Added filetype, C-M=>CR, echo message
      Update: added -t
Re: Desparately seeking a bilingual vim/Emacs expert
by jmcnamara (Monsignor) on Mar 23, 2005 at 09:22 UTC

    Here is a minimal usable .emacs file for Perl programming.
    ;; Use cperl mode instead of the default perl mode (defalias 'perl-mode 'cperl-mode) ;; Turn syntax highlighting on (global-font-lock-mode 1) ;; 4 space indent in cperl mode (setq cperl-indent-level 4) ;; Insert spaces instead of tabs (setq-default indent-tabs-mode nil)

    It is better to use Ilya's cperl mode than the default perl mode. The syntax highlighting is optional but recommended. The last two commands set the indent level and the tab expansion. Combined with cperl mode these replicate the vi tab stop behaviour.

    It may also be worth adding a link to the Emacs Wiki which is a great source of information.


      Yes, I agree that cperl is the right mode to use. I use it daily in XEmacs.

      I've also been using mmm-mode regularly to edit HTML::Mason files, with the mode (and syntax highlighting and background) changing between blocks of html and perl.

      I also like your brief version of the tab definitions. However, while I'm not sure exactly what the tab key does in vim perl, cperl's default tab definition took me a bit of getting used to - particularly in that by default hitting tab at the end of a line indents the whole line appropriately instead of moving to the righ to get ready for a comment.

      It might be worth noting that

      (setq-default cperl-tab-always-indent nil)
      tells cperl that tab means indent when the cursor is to the left of the text, otherwise it means "insert-tab" - though I believe that's still different from the shift-tab defined as "tab-to-tab-stop" which I use more often.

      As far as Damian's named macros for inserting a specific chunk of text or loading a specific template, I'd suggest something like the following.

      ; A named function to insert some specific text. (defun my-insert-stuff () "documentation string" (interactive "*") ; "*" => error if read-only (insert "This is the text to insert. ") ) ; Set it to a specific keystroke combo. (global-set-key [(control c) m] 'my-insert-stuff) ; Load a specific template in a new unattached buffer. (defun template-one () "documentation string" ; For help and info. (interactive) ; Make this user accessible. (switch-to-buffer "template-one") (insert-file "~/template_one") ) ; It too could be set to some specific key combination. (global-set-key [(control c) o] 'template-one)
      Finally, you might be amused by these definitions. for », «, ¥
      ;;; ---- some "unicode" perl6 stuff ;; The numeric codes are base 10 from iso-8869-1. ;; Keys are control-c followed by control-(>, <, y), ;; without the shift key (global-set-key [(control c) (control ?.)] '(lambda () (interactive "*") (insert 187))) (global-set-key [(control c) (control ?,)] '(lambda () (interactive "*") (insert 171))) (global-set-key [(control c) (control ?y)] '(lambda () (interactive "*") (insert 165)))


      Jim Mahoney

      update: fixed a typo; "control" not "crontol"

        That's exactly what I was looking for. Thank-you, Jim!

        And yes, I'm sure those non-ASCII set-keys will come in very handy later this year! Damian

        (Deleted. Duplicate.)
Re: Desparately seeking a bilingual vim/Emacs expert
by jhourcle (Prior) on Mar 23, 2005 at 05:27 UTC

    I can help with the BBEdit settings, provided I understand the .vimrc commands correctly.

    For BBEdit 7.x (I'll have to check 8.x from work, as I don't have it installed at home)

    Update: For those first four, it might be easiest to just provide a tarball that unpacks as (or anything else that ends in .pl, that users can drop into their glossary folder.

    Update 2: You could also save the templates using Save As ... -> Save as Stationery, and then saving them in /Applications/BBEdit 7.1.2/BBEdit Support/Stationery

    Update 3:BBEdit 8.x:

    Okay, I've done all I think I can to justify my 'distinguised beta site' listing in 'About BBEdit' ... I'll drop a line to supprt, to see if they can answer the last one. (and for TextWrangler)

    Update 4: I've written it up in a more unified way, and included TextWrangler 2.0 :

Re: Desparately seeking a bilingual vim/Emacs expert
by InfiniteLoop (Hermit) on Mar 23, 2005 at 08:12 UTC
    Try the abbrev-mode. Here is the sample code that you can stick in an .emacs file, which enables the abbrev-mode and sets up some global abbreviations:
    (abbrev-mode 1) (define-abbrev-table 'global-abbrev-table '( ("dbg" "use Data::Dumper qw( Dumper );^Mwarn Dumper[];^[hi" nil 1) ))
    I found that it is better to add a hook to the preferred editing made, to enable abbreviation mode, like:
    (add-hook 'text-mode-hook (lambda () (abbrev-mode 1)))
    This enables the abbreviation mode while editing text files. Also you can enbale the abbrev mode by typing: M-x abbrev-mode
    For the pre-fab documents, try using auto-insert. This mode can work on the file extensions, this link gives more info

    For tab stops etc, use cperl-mode.
      That's really helpful. Thank-you!


Re: Desparately seeking a bilingual vim/Emacs expert
by Limbic~Region (Chancellor) on Mar 23, 2005 at 13:42 UTC
Re: Desparately seeking a bilingual vim/Emacs expert
by artist (Parson) on Mar 23, 2005 at 14:09 UTC
    As a dedicated vim user, I can handle that side of things fine, but when it comes to Emacs, I'm Escape-Meta-Alt-Control-Stupid.
    I used vi for 7 years. It took me only 7 days to learn emacs. I have been using emacs ever since. I think that cperl-mode is the best. You can integrate the perldoc, keyword-help, function-help, etags, (i)menu of subroutines, debugger etc. With advanced usages, you might be able to integrate perlmonks, cpan, online perldoc, perl mailing list... Now that's what I am looking for easeness.

Re: Desparately seeking a bilingual vim/Emacs expert
by Fletch (Chancellor) on Mar 23, 2005 at 13:43 UTC

    Aside from abbrevs, there's also skeleton mode (and the similar Tempo mode) which can let you just "fill in the blanks" or stick in an empty skeleton with marks left at the interesting points (depending on how you set things up).

Re: Desparately seeking a bilingual vim/Emacs expert
by jplindstrom (Monsignor) on Mar 23, 2005 at 10:14 UTC
    *shameless plug*

    If you happen to mention UltraEdit (or gVim or EditPlus etc) you may also want to mention Perl Oasis which is loosely integrated with those editors.


Re: Desparately seeking a bilingual vim/Emacs expert
by ForgotPasswordAgain (Curate) on Mar 24, 2005 at 13:34 UTC

    I'm not sure there are exact mappings between vim and emacs, since they use different concepts.

    1. I have several macro-like functions which I've defined for Perl programming convenience. For example, this creates a new sub:

      (defun perl-sub (name) "Insert a new subroutine" (interactive "*sName: ") (insert "sub {\n\n\n\n}\n") (previous-line 4) (indent-for-tab-command) (insert "my () = @_;") (search-backward "sub ") (goto-char (match-end 0)) (insert name) (search-forward "("))

      It prompts for the sub name, then outputs a bare subroutine with "my () = @_;" on the first line and putting the cursor inside the `my' list. You can then call this function with `ESC x perl-sub'; you could also bind it to key command, for example (global-set-key [f3] 'perl-sub), then you can just hit the F3 key to do it. Modifying this to output Data::Dumper stuff (good idea) would be straight-forward.

    2. I'm not sure what document templates are for. You could easily include a file with `C-x i', though, or use the above "macro" technique.

    3. For indenting, I have this inside (custom-set-variables):

      '(cperl-close-paren-offset -4) '(cperl-continued-statement-offset 2) '(cperl-indent-level 4) '(cperl-indent-parens-as-block t) '(cperl-label-offset 0) '(cperl-tab-always-indent t)

      That gets pretty close to (tab) indenting consistently with what I think is the style seen in most Perl books and documentation.

      Modifying this to output Data::Dumper stuff (good idea) would be straight-forward.
      Here's my attempt. I'd be very grateful if someone who knows Emacs could actually try it.
      (defun perl-dbg (name) "Insert a debugging print statement" (insert "use Data::Dumper qw( Dumper );\nwarn Dumper [ ]\n") (search-backward "[ ")
      I'm not sure what document templates are for.
      The idea is that you hit a key, and the editor pastes in a template from another file. Any suggestions for how to do that would be greatly appreciated.
      For indenting, I have this inside (custom-set-variables):
      I'm guessing:
      '(cperl-close-paren-offset -4)
      Outdent 4 columns on a closing paren?

      '(cperl-continued-statement-offset 2)
      Indent 2 columns when a statement wraps?

      '(cperl-indent-level 4)
      Indent four columns per indentation level?

      '(cperl-indent-parens-as-block t)
      Indent parens like blocks?

      '(cperl-label-offset 0)
      Put labels in the zeroth column?

      '(cperl-tab-always-indent t)
      Convert tabs to spaces?

      Could someone knowledgeable confirm (or correct) those guesses?

        (defun perl-dbg () "Insert a debugging print statement" (interactive) (insert "use Data::Dumper qw( Dumper );\nwarn Dumper [ ];\n") (search-backward "[ ")) (global-set-key "\C-c\C-p" 'perl-dbg)
        Then typing CTL-C CTL-p inserts this text:
        use Data::Dumper qw( Dumper ); warn Dumper [ ];
        and leaves the cursor under the [ character. I wasn't sure if you wanted to prompt for the name of the variable(s) to dump, so I changed (defun perl-dbg (name) to (defun perl-dbg (). The statement (interactive) makes it interactive, so that it can be bound to a key combination. Here's a version that prompts for a variable name (or names):
        (defun perl-dbg (name) "Insert a debugging print statement" (interactive "svariable to dump: ") (insert "use Data::Dumper qw( Dumper );\nwarn Dumper ") (insert name) (insert ";\n"))
        There are probably better ways to handle strings in Emacs-Lisp, but I've only recently started playing with it.
Re: Desparately seeking a bilingual vim/Emacs expert
by polettix (Vicar) on Apr 05, 2005 at 10:23 UTC
    At the risk of being slightly off-topic, I would also share my 2c Emacs tip with you. I've put this hook to call perltidy (pressing F6) in my .emacs:
    (defun my-cperl-hook () "What to run when cperl-mode is turned on" ;; Function to call perltidy (defun perltidy-whole-buffer () "Filter the current buffer through perltidy" (interactive) (shell-command-on-region (point-min) (point-max) "perltidy -st" nil 1 shell-command-default-error-buffer ) ) ;; Bind key (define-key cperl-mode-map [f6] 'perltidy-whole-buffer) )
    The hook has to be added to the correct customisation variable as well:
    (custom-set-variables ;; custom-set-variables was added by Custom -- don't edit or cut/pas +te it! ;; Your init file should contain only one such instance. ;; ... '(cperl-mode-hook (quote (my-cperl-hook))) )
    Of course, s/cperl/perl/g if you don't want to use cperl.

    Flavio (perl -e "print(scalar(reverse('ti.xittelop@oivalf')))")

    Don't fool yourself.

      The following snippet steals the regular C-x C-s to automatically perltidy as well. I added a different definition for perltidy-whole-buffer so that the input point is restored to be somewhere near where it was originally. I also added a check to see if the buffer has been modifed before calling out to perltidy.

      (add-to-list 'cperl-mode-hook (lambda () (substitute-key-definition 's +ave-buffer 'cperl-save-buffer cperl-mode-map global-map))) (defun cperl-save-buffer (&optional args) (interactive "p") (if (buffer-modified-p) (perltidy-buffer)) (save-buffer t)) (defun perltidy-buffer () (interactive) (let ((orig-point (point))) (shell-command-on-region (point-min) (point-max) "perltidy -st" nil t shell-command-default-error-buffer) (goto-char (if (<= orig-point (point-max)) orig-point (point-max)))))
Re: Desparately seeking a bilingual vim/Emacs expert
by leriksen (Curate) on Mar 29, 2005 at 02:07 UTC
    Even _more_ things you may want to consider for x?emacs (what gates from hell have you opened now TheDamian !!)
    ;;display the current time (plus a seconds ticker) in the mode bar of +the frame (display-time) (custom-set-variables ;; syntax highlighter changes background colour of expression from ope +ning brace to closing brace '(paren-mode (quote sexp) nil (paren)) ;;indent the line the appropriate amount when the author hits the ';' +key (but only in perl code) '(cperl-autoindent-on-semi t) ;;show column numbers for all modes '(column-number-mode t) ;;show line number in all modes '(line-number-mode t) ;; always turn on highlighting for all modes '(font-lock-mode t nil (font-lock))) ;; I dont like the default Cperl colours for hashes and comments - you + can set them this way. Makes comments really stand out on a grey or +black ackground. (custom-set-faces '(cperl-hash-face ((((class color) (background light)) (:foreground " +Red" :bold t)))) '(font-lock-comment-face ((((class color) (background light)) (:foreg +round "blue4" :background "white"))))) is better to be approximately right than precisely wrong. - Warren Buffet

Re: Desparately seeking a bilingual vim/Emacs expert
by stefp (Vicar) on Mar 26, 2005 at 19:10 UTC
    I hope you will talk of perldb in your book. Having such a windowed debug environment in emacs is invaluable.
    ...Except for modules that do a lot of string evals like source filters.

    -- stefp

      Is the a home page you can point me at (so I can point the readers at it)?



        I am afraid not. emacs shines and sucks in the same way perl5 does. Does the job. Too old, too much history.

        But it is not so daunting. Here is a quick 101 to use emacs for debugging and light editing.

        Until recently, I think that emacs did not include the last version of cperl. This resulted in haphazard hightlighting. Once a perl file is loaded, one can check the cperl version by typing C-h v cperl-version. It must be the same that the most recent file in Currently it is 7.32. If one is root he can adds it to his site specific directory A common place is /usr/share/emacs/site-lisp. Other wise he can add it to a personal elisp directory and he will load it by adding (load-file "elisp/cperl.el") in in .emacs file

        Perl debugging is part of the grand unified debugger scheme gud.el written by the inevitable esr. This is used to debug with gdb too. In my system the file is at /usr/share/emacs/21.3/lisp/gud.el where one can find the perl specific stuff by grepping "perldb".

        You run a session with the command

          M-x perldb RET your_filename
        You get two buffers in your frame. One is the file currently debugged. The other is the debugging session where you get to use all the commands described in the perldebug pod file. So that's known territory.

        You can also interact directly in the perl file buffer thanks to gud-minor-mode. A minor mode adds functionalities to the major mode by adding key-bindings.

        You can get all the bindings of the said buffer using C-h C-b. I paste the binding concerning the gud minor mode. Using the minor binding of the perl file avoid to clutter the debug window by explicit commands.

        C-x SPC		gud-break
        C-x C-a C-p	gud-print
        C-x C-a C-r	gud-cont
        C-x C-a C-n	gud-next
        C-x C-a C-s	gud-step
        C-x C-a C-d	gud-remove
        C-x C-a C-b	gud-break
        C-x C-a C-l	gud-refresh
        One can scroll a buffer using the mouse.

        Here is a list of minimal keybindings for people that want to use emacs for debbugging and minor edition while wanting to go mouseless.

        C-x o   allows to cycle the caret thru all the buffers
        C-x b   list all the buffer in the meacs session.
               In that buffer ENTER  selects a file
        C-x w  write the current file
        C-x q  toggle the read-only mode. Because so many binding do
               something it can be a good stopping gap.
        ^H i gets to the info files
        Here is a chart for moving in progressively coarser granularity from the current position.
        In the vertical axis : char, word, begin/end of line
        In the horizontal axis : line, begin/end of subroutine
        C-a <--- M-b <-- C-b  <-- .  --> C-f --> M-f --> C-e
        M-x woman is nicer the M-x man but slower to start :)
        ...because it compiles the list of man files to provide completion.

        -- stefp