Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

[emacs] RFC live formating / tidying while I type

by LanX (Cardinal)
on Sep 08, 2016 at 19:32 UTC ( #1171430=perlmeditation: print w/replies, xml ) Need Help??


I always wanted to have live formatting as I type Perl code.

The usual advice to pipe a text selection through perltidy is just too slow, and furthermore you might want to have only a visible snippet formatted to keep control, and tidy can fail here (emacs is mostly very tolerant)

The following code called with M-x my-indent-block is re-indenting the surrounding block you are in. The devadvice binds it to the cperls electric-semi feature which automatically does a return and and indentation of the following line (see M-x customize-group RET cperl-autoinsert-details for details)


for my$scalar(1..10){print"$scalar"."txt";}
for my $scalar (1..10) { print"$scalar"."txt"; }
NB: this is work progress but it's by far faster than perltidy
(defun my-indent-block () "reindent surroundig expression" (interactive) (save-excursion (backward-up-list) (cperl-indent-exp) ) ) (defadvice cperl-electric-semi (after my-electric-indent-context) "indent whole context surrounding block/context" (my-indent-block) ) (add-hook 'cperl-mode-hook (lambda () (local-set-key (kbd "M-C-q") 'my-indent-block ) ) )

  • Defadvice is a kind of wrapping, I tried to bind it to cperl-indent-line to always indent the whole block whenever and indentation is triggered (there are many ways to do so in cperl-mode) but this is causing an infinite recursion , since cperl-indent-exp calls cperl-indent-line. (this is for sure solvable with some kind of flag, but I'm tired now :)
  • Toplevel In filescope this doesn't work cause there is no up-list! Thats good, because I didn't want to reindent distant code, without visual control. But it's still pretty easy in elisp to catch the error and to react otherwise, one option is to just reindent one paragraph or the whole file if that option is set.
Natural keybindings

cperl-indent-exp is normally bound to M-C-q , but is only useful after you've put the cursor in front of the block to highlight (here the for ), that's why I remapped it to work from inside the block.

M-q should be the far better choice ( I hate 3+ finger combinations). In cperl-mode it's bound to cperl-fill-paragraph which wraps text to 80 colums ONLY in POD, here-docs or comments, but isn't useful in code! ( well as long as you are not trying to obfuscate )

But now I'm not sure how to combine the old cperl-heuristic to distinguish between code and text with this new features, without patching cperl.

Nice to have for my-indent-block
  • repeated manual calls should format ever bigger surrounding blocks till reaching the file-scope. (It's pretty easy to check the last command for repetition)
  • automatic delete-trailing-whitespace inside the block would be nice too (easy)
  • deleting unnecessary trailing empty lines at the block end
  • the cperl's indentation doesn't reformat spaces inside brackets or around operators (see print) yet
  • the cperl's indentation doesn't align = and => yet *
  • any other formating feature from perltidy I forgot



    *) there is align-current for regions, but it's reg-ex based fails with nested structures

    my $a = { a => 1, b => { c => 3, } };

    but with the semantic information of cperl's parsing it's possible to distinguish between the different levels of =>.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

  • Replies are listed 'Best First'.
    Re: [emacs] RFC live formating / tidying while I type
    by zakame (Pilgrim) on Sep 14, 2016 at 06:22 UTC
        Thanks, I'll check this out! :)

        Do you use it?

        Looks a bit too aggressive for me, I don't want Emacs to block while I type.

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

          I usually turn it on explicitly rather than globally enabled (I previously left on but found my aggressive-indent-excluded-modes growing...) Curious about it blocking though, unless there's a lot of backtracking in Emacs' state going on...

    Log In?

    What's my password?
    Create A New User
    Node Status?
    node history
    Node Type: perlmeditation [id://1171430]
    Approved by marto
    Front-paged by marto
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (6)
    As of 2020-07-07 16:39 GMT
    Find Nodes?
      Voting Booth?

      No recent polls found