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/Temp.pm) 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 Smylers@stripey.com and ask.
Smylers
| [reply] [d/l] [select] |
|
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 this...it 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 | [reply] [d/l] |
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.
--
John.
| [reply] [d/l] |
|
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)))
Regards,
Jim Mahoney
update: fixed a typo; "control" not "crontol"
| [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
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 Perl.pl (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 :
| [reply] [d/l] [select] |
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.
| [reply] [d/l] [select] |
|
That's really helpful. Thank-you!
Damian
| [reply] |
Re: Desparately seeking a bilingual vim/Emacs expert
by Limbic~Region (Chancellor) on Mar 23, 2005 at 13:42 UTC
|
| [reply] |
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.
| [reply] |
Re: Desparately seeking a bilingual vim/Emacs expert
by Fletch (Bishop) 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).
| [reply] |
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.
/J
| [reply] |
Re: Desparately seeking a bilingual vim/Emacs expert
by ForgotPasswordAgain (Priest) 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.
-
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.
-
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.
-
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.
| [reply] [d/l] [select] |
|
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?
| [reply] [d/l] [select] |
|
(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. | [reply] [d/l] [select] |
|
|
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.
| [reply] [d/l] [select] |
|
(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)))))
| [reply] [d/l] |
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")))))
...it is better to be approximately right than precisely wrong. - Warren Buffet
| [reply] [d/l] |
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.
| [reply] |
|
Is the a home page you can point me at (so I can point the readers at it)?
Thanks,
Damian
| [reply] |
|
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
http://www.cpan.org/modules/by-module/CPAN/ILYAZ/cperl-mode.
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-M-a
|
C-p
C-a <--- M-b <-- C-b <-- . --> C-f --> M-f --> C-e
|
C-n
|
C-M-e
|
v
M-x woman is nicer the M-x man but slower to start :)
...because it compiles the list of man files to provide completion.
| [reply] [d/l] [select] |