How can I script vim to run perltidy on a buffer?

后端 未结 6 1317
终归单人心
终归单人心 2021-02-02 00:42

At my current job, we have coding-style standards that are different from the ones I normally follow. Fortunately, we have a canned RC file for perltidy that I can

相关标签:
6条回答
  • 2021-02-02 00:49

    Instead of creating a new keyboard shortcut, how about replacing the meaning of the = command which is already in people's finger memory for indenting stuff? Yes, perlcritic does more than just indent but when you use perlcritic anyways, then you probably don't want to go back to the inferior "just indent" = command. So lets overwrite it!

    filetype plugin indent on
    autocmd FileType perl setlocal equalprg=perltidy
    

    And now we can use = just like before but with the added functionality of perlcritic that goes beyond just indenting lines:

    ==   run perlcritic on the current line
    5==  run perlcritic on five lines
    =i{  Re-indent the 'inner block', i.e. the contents of the block
    =a{  Re-indent 'a block', i.e. block and containing braces
    =2a{ Re-indent '2 blocks', i.e. this block and containing block
    gg=G run perlcritic on the entire buffer
    

    And the best part is, that you don't have to learn any new shortcuts but can continue using the ones you already used with more power. :)

    0 讨论(0)
  • 2021-02-02 00:51

    Taking hobbs' answer a step further, you can map that command to a shortcut key:

    command -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
    noremap <C-F6> :Tidy<CR>
    

    And another step further: Only map the command when you're in a Perl buffer (since you probably wouldn't want to run perltidy on any other language):

    autocmd BufRead,BufNewFile *.pl,*.plx,*.pm command! -range=% -nargs=* Tidy <line1>,<line2>!perltidy -q
    autocmd BufRead,BufNewFile *.pl,*.plx,*.pm noremap <C-F6> :Tidy<CR>
    

    Now you can press Ctrl-F6 without an active selection to format the whole file, or with an active selection to format just that section.

    0 讨论(0)
  • 2021-02-02 00:58

    The command to filter the entire buffer through an external program is:

    :%!command
    

    Put the following in ~/.vimrc to bind it to Ctrl-F6 in normal mode:

    :nmap <C-F6> :%!command<CR>
    

    For added fun:

    :au Filetype perl nmap <C-F6> :%!command<CR>
    

    This will only map the filter if editing a Perl file.

    0 讨论(0)
  • 2021-02-02 01:03

    After trying @hobbs answer I noticed that when filtering the entire buffer through perltidy the cursor returned to byte 1, and I had to make a mental note of the original line number so I could go back after :Tidy completed.

    So building on @hobbs' and @Ignacio's answers, I added the following to my .vimrc:

    "define :Tidy command to run perltidy on visual selection || entire buffer"
    command -range=% -nargs=* Tidy <line1>,<line2>!perltidy
    
    "run :Tidy on entire buffer and return cursor to (approximate) original position"
    fun DoTidy()
        let l = line(".")
        let c = col(".")
        :Tidy
        call cursor(l, c)
    endfun
    
    "shortcut for normal mode to run on entire buffer then return to current line"
    au Filetype perl nmap <F2> :call DoTidy()<CR>
    
    "shortcut for visual mode to run on the current visual selection"
    au Filetype perl vmap <F2> :Tidy<CR>
    

    (closing " added to comments for SO syntax highlighting purposes (not required, but valid vim syntax))

    DoTidy() will return the cursor to its original position plus or minus at most X bytes, where X is the number of bytes added/removed by perltidy relative to the original cursor position. But this is fairly trivial as long as you keep things tidy :).

    [Vim version: 7.2]

    EDIT: Updated DoTidy() to incorporate @mikew's comment for readability and for compatibility with Vim 7.0

    0 讨论(0)
  • 2021-02-02 01:11

    My tidy command:

    command -range=% -nargs=* Tidy <line1>,<line2>!
      \perltidy (your default options go here) <args>
    

    If you use a visual selection or provide a range then it will tidy the selected range, otherwise it will use the whole file. You can put a set of default options (if you have any) at the point where I wrote (your default options go here), but any arguments that you provide to :Tidy will be appended to the perltidy commandline, overriding your defaults. (If you use a .perltidyrc you might not have default args -- that's fine -- but then again you might want to have a default like --profile=vim that sets up defaults only for when you're working in vim. Whatever works.)

    0 讨论(0)
  • 2021-02-02 01:11

    I'm used to select text using line oriented visual Shift+V and then I press : an I have !perltidy -pbp -et4 somewhere in history so I hit once or more up arrow .

    0 讨论(0)
提交回复
热议问题