From 06a4c3e1c870cf37ef35c4d528fd23c66d5ca260 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 7 Jul 2018 01:18:19 +1200 Subject: Add heredoc support to Vim Perl indent plugin This anchors lines in a Perl heredoc with no indent until it sees the terminating word. It works really well. --- vim/indent/perl.vim | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/vim/indent/perl.vim b/vim/indent/perl.vim index 51e8b26c..604b836b 100644 --- a/vim/indent/perl.vim +++ b/vim/indent/perl.vim @@ -10,6 +10,22 @@ let b:did_indent = 1 setlocal indentexpr=GetPerlIndent() setlocal indentkeys=o,O,0},0),0] +" Build patterns for heredoc indenting; note that we detect indented heredocs +" with tildes like <<~EOF, but we don't treat them any differently; note also +" a semicolon is required +let s:heredoc_word = '\I\i*' +let s:heredoc_open = '<<\~\?' + \ . '\(' + \ . '\\\?' . s:heredoc_word + \ . '\|' + \ . "'" . s:heredoc_word . "'" + \ . '\|' + \ . '"' . s:heredoc_word . '"' + \ . '\|' + \ . '`' . s:heredoc_word . '`' + \ . '\)' + \ . '.*\ . ';\s*$' + " Define indent function function! GetPerlIndent() @@ -19,9 +35,42 @@ function! GetPerlIndent() return 0 endif - " Get line properties + " Heredoc detection; start at top of buffer + let l:hn = 0 + while l:hn < v:lnum + let l:hl = getline(l:hn) + + " If we're not in a heredoc and not in a comment ... + if !exists('l:hw') && l:hl !~# '^\s*#' + + " Line opens with a heredoc + let l:hm = matchstr(l:hl, s:heredoc_open) + + " Store the heredoc word and make this our indent reference + if strlen(l:hm) + let l:hw = matchstr(l:hm, s:heredoc_word) + let l:pn = l:hn + endif + + " If we are in a heredoc and we found the token word, finish it + elseif exists('l:hw') && l:hl =~# '^'.l:hw.'\>' + unlet l:hw + endif + + " Bump the loop index + let l:hn = l:hn + 1 + + endwhile + + " If we ended up in a heredoc, return 0 for the indent. + if exists('l:hw') + return 0 + endif + + " Get current line properties let l:cl = getline(v:lnum) - let l:ci = indent(l:cn) + + " Get data of previous non-blank and non-heredoc line let l:pl = getline(l:pn) let l:pi = indent(l:pn) -- cgit v1.2.3