aboutsummaryrefslogtreecommitdiff
path: root/vim/indent
diff options
context:
space:
mode:
Diffstat (limited to 'vim/indent')
-rw-r--r--vim/indent/perl.vim53
1 files 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)