Skip to content

Commit

Permalink
Yet more string detection fixes and slight code clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
axvr committed Apr 28, 2023
1 parent e573da7 commit 242dc9d
Showing 1 changed file with 24 additions and 23 deletions.
47 changes: 24 additions & 23 deletions indent/clojure.vim
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,26 @@ function! s:Conf(opt, default)
return get(b:, a:opt, get(g:, a:opt, a:default))
endfunction

function! s:ShouldAlignMultiLineStrings()
" Possible Values: (default is 0)
" -1: Indent of 0, along left edge, like traditional Lisps.
" 0: Indent in alignment with string start delimiter.
" 1: Indent in alignment with end of the string start delimiter.
return s:Conf('clojure_align_multiline_strings', 0)
function! s:EqualsOperatorInEffect()
" Returns 1 when the previous operator used is "=" and is currently in
" effect (i.e. "state" includes "o").
return v:operator ==# '=' && state('o') ==# 'o'
endfunction

function! s:GetStringIndent(delim_pos, regex)
" Mimic multi-line string indentation behaviour in VS Code and Emacs.
let m = mode()
if m ==# 'i' || (m ==# 'n' && ! (v:operator ==# '=' && state('o') ==# 'o'))
" If in insert mode, or (in normal mode and last operator is
" not "=" and is not currently active.
let rule = s:ShouldAlignMultiLineStrings()
if m ==# 'i' || (m ==# 'n' && ! s:EqualsOperatorInEffect())
" If in insert mode, or normal mode but "=" is not in effect.
let rule = s:Conf('clojure_align_multiline_strings', 0)
if rule == -1
return 0 " No indent.
" Indent along left edge, like traditional Lisps.
return 0
elseif rule == 1
" Align with start of delimiter.
" Indent in alignment with end of the string start delimiter.
return a:delim_pos[1]
else
" Align with end of delimiter.
" Indent in alignment with string start delimiter.
return a:delim_pos[1] - (a:regex ? 2 : 1)
endif
else
Expand All @@ -86,27 +84,30 @@ function! s:CheckPair(name, start, end, SkipFn)
endif
endfunction

function! s:GetClojureIndent()
" Move cursor to the first column of the line we want to indent.
call cursor(v:lnum, 1)

if empty(getline(v:lnum))
function! s:GetCurrentSynName(lnum)
if empty(getline(a:lnum))
" Improves the accuracy of string detection when a newline is
" entered while in insert mode.
let strline = v:lnum - 1
let synname = s:GetSynIdName(strline, strlen(getline(strline)))
let strline = a:lnum - 1
return s:GetSynIdName(strline, strlen(getline(strline)))
else
let synname = s:GetSynIdName(v:lnum, 1)
return s:GetSynIdName(a:lnum, 1)
endif
endfunction

function! s:GetClojureIndent()
" Move cursor to the first column of the line we want to indent.
call cursor(v:lnum, 1)

let s:best_match = ['top', [0, 0]]

let synname = s:GetCurrentSynName(v:lnum)
if synname =~? 'string'
call s:CheckPair('str', '"', '"', function('<SID>NotStringDelimiter'))
" Sometimes, string highlighting does not kick in correctly,
" until after this first "s:CheckPair" call, so we have to
" detect and attempt an automatic correction.
call s:CheckPair('str', '"', '"', function('<SID>NotStringDelimiter'))
let new_synname = s:GetSynIdName(v:lnum, 1)
let new_synname = s:GetCurrentSynName(v:lnum)
if new_synname !=# synname
echoerr 'Misdetected string! Retrying...'
let s:best_match = ['top', [0, 0]]
Expand Down

0 comments on commit 242dc9d

Please sign in to comment.