Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 1 | " Vim indent file |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 2 | " Language: Clojure |
| 3 | " Author: Meikel Brandmeyer <mb@kotka.de> |
| 4 | " URL: http://kotka.de/projects/clojure/vimclojure.html |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 5 | " |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 6 | " Maintainer: Sung Pae <self@sungpae.com> |
| 7 | " URL: https://github.com/guns/vim-clojure-static |
| 8 | " License: Same as Vim |
Bram Moolenaar | 438f67a | 2014-01-07 06:09:28 +0100 | [diff] [blame] | 9 | " Last Change: 16 December 2013 |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 10 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 11 | " TODO: Indenting after multibyte characters is broken: |
| 12 | " (let [Δ (if foo |
| 13 | " bar ; Indent error |
| 14 | " baz)]) |
| 15 | |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 16 | if exists("b:did_indent") |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 17 | finish |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 18 | endif |
| 19 | let b:did_indent = 1 |
| 20 | |
| 21 | let s:save_cpo = &cpo |
| 22 | set cpo&vim |
| 23 | |
| 24 | let b:undo_indent = 'setlocal autoindent< smartindent< lispwords< expandtab< softtabstop< shiftwidth< indentexpr< indentkeys<' |
| 25 | |
| 26 | setlocal noautoindent nosmartindent |
| 27 | setlocal softtabstop=2 shiftwidth=2 expandtab |
| 28 | setlocal indentkeys=!,o,O |
| 29 | |
| 30 | if exists("*searchpairpos") |
| 31 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 32 | if !exists('g:clojure_maxlines') |
| 33 | let g:clojure_maxlines = 100 |
| 34 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 35 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 36 | if !exists('g:clojure_fuzzy_indent') |
| 37 | let g:clojure_fuzzy_indent = 1 |
| 38 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 39 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 40 | if !exists('g:clojure_fuzzy_indent_patterns') |
| 41 | let g:clojure_fuzzy_indent_patterns = ['^with', '^def', '^let'] |
| 42 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 43 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 44 | if !exists('g:clojure_fuzzy_indent_blacklist') |
| 45 | let g:clojure_fuzzy_indent_blacklist = ['-fn$', '\v^with-%(meta|out-str|loading-context)$'] |
| 46 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 47 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 48 | if !exists('g:clojure_special_indent_words') |
| 49 | let g:clojure_special_indent_words = 'deftype,defrecord,reify,proxy,extend-type,extend-protocol,letfn' |
| 50 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 51 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 52 | if !exists('g:clojure_align_multiline_strings') |
| 53 | let g:clojure_align_multiline_strings = 0 |
| 54 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 55 | |
Bram Moolenaar | 438f67a | 2014-01-07 06:09:28 +0100 | [diff] [blame] | 56 | if !exists('g:clojure_align_subforms') |
| 57 | let g:clojure_align_subforms = 0 |
| 58 | endif |
| 59 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 60 | function! s:SynIdName() |
| 61 | return synIDattr(synID(line("."), col("."), 0), "name") |
| 62 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 63 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 64 | function! s:CurrentChar() |
| 65 | return getline('.')[col('.')-1] |
| 66 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 67 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 68 | function! s:CurrentWord() |
| 69 | return getline('.')[col('.')-1 : searchpos('\v>', 'n', line('.'))[1]-2] |
| 70 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 71 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 72 | function! s:IsParen() |
| 73 | return s:CurrentChar() =~ '\v[\(\)\[\]\{\}]' && |
| 74 | \ s:SynIdName() !~? '\vstring|regex|comment|character' |
| 75 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 76 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 77 | " Returns 1 if string matches a pattern in 'patterns', which may be a |
| 78 | " list of patterns, or a comma-delimited string of implicitly anchored |
| 79 | " patterns. |
| 80 | function! s:MatchesOne(patterns, string) |
| 81 | let list = type(a:patterns) == type([]) |
| 82 | \ ? a:patterns |
| 83 | \ : map(split(a:patterns, ','), '"^" . v:val . "$"') |
| 84 | for pat in list |
| 85 | if a:string =~ pat | return 1 | endif |
| 86 | endfor |
| 87 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 88 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 89 | function! s:MatchPairs(open, close, stopat) |
| 90 | " Stop only on vector and map [ resp. {. Ignore the ones in strings and |
| 91 | " comments. |
| 92 | if a:stopat == 0 |
| 93 | let stopat = max([line(".") - g:clojure_maxlines, 0]) |
| 94 | else |
| 95 | let stopat = a:stopat |
| 96 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 97 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 98 | let pos = searchpairpos(a:open, '', a:close, 'bWn', "!s:IsParen()", stopat) |
| 99 | return [pos[0], virtcol(pos)] |
| 100 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 101 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 102 | function! s:ClojureCheckForStringWorker() |
| 103 | " Check whether there is the last character of the previous line is |
| 104 | " highlighted as a string. If so, we check whether it's a ". In this |
| 105 | " case we have to check also the previous character. The " might be the |
| 106 | " closing one. In case the we are still in the string, we search for the |
| 107 | " opening ". If this is not found we take the indent of the line. |
| 108 | let nb = prevnonblank(v:lnum - 1) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 109 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 110 | if nb == 0 |
| 111 | return -1 |
| 112 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 113 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 114 | call cursor(nb, 0) |
| 115 | call cursor(0, col("$") - 1) |
| 116 | if s:SynIdName() !~? "string" |
| 117 | return -1 |
| 118 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 119 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 120 | " This will not work for a " in the first column... |
| 121 | if s:CurrentChar() == '"' |
| 122 | call cursor(0, col("$") - 2) |
| 123 | if s:SynIdName() !~? "string" |
| 124 | return -1 |
| 125 | endif |
| 126 | if s:CurrentChar() != '\\' |
| 127 | return -1 |
| 128 | endif |
| 129 | call cursor(0, col("$") - 1) |
| 130 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 131 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 132 | let p = searchpos('\(^\|[^\\]\)\zs"', 'bW') |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 133 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 134 | if p != [0, 0] |
| 135 | return p[1] - 1 |
| 136 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 137 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 138 | return indent(".") |
| 139 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 140 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 141 | function! s:CheckForString() |
| 142 | let pos = getpos('.') |
| 143 | try |
| 144 | let val = s:ClojureCheckForStringWorker() |
| 145 | finally |
| 146 | call setpos('.', pos) |
| 147 | endtry |
| 148 | return val |
| 149 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 150 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 151 | function! s:ClojureIsMethodSpecialCaseWorker(position) |
| 152 | " Find the next enclosing form. |
| 153 | call search('\S', 'Wb') |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 154 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 155 | " Special case: we are at a '(('. |
| 156 | if s:CurrentChar() == '(' |
| 157 | return 0 |
| 158 | endif |
| 159 | call cursor(a:position) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 160 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 161 | let nextParen = s:MatchPairs('(', ')', 0) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 162 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 163 | " Special case: we are now at toplevel. |
| 164 | if nextParen == [0, 0] |
| 165 | return 0 |
| 166 | endif |
| 167 | call cursor(nextParen) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 168 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 169 | call search('\S', 'W') |
| 170 | if g:clojure_special_indent_words =~ '\<' . s:CurrentWord() . '\>' |
| 171 | return 1 |
| 172 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 173 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 174 | return 0 |
| 175 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 176 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 177 | function! s:IsMethodSpecialCase(position) |
| 178 | let pos = getpos('.') |
| 179 | try |
| 180 | let val = s:ClojureIsMethodSpecialCaseWorker(a:position) |
| 181 | finally |
| 182 | call setpos('.', pos) |
| 183 | endtry |
| 184 | return val |
| 185 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 186 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 187 | function! GetClojureIndent() |
| 188 | " Get rid of special case. |
| 189 | if line(".") == 1 |
| 190 | return 0 |
| 191 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 192 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 193 | " We have to apply some heuristics here to figure out, whether to use |
| 194 | " normal lisp indenting or not. |
| 195 | let i = s:CheckForString() |
| 196 | if i > -1 |
| 197 | return i + !!g:clojure_align_multiline_strings |
| 198 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 199 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 200 | call cursor(0, 1) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 201 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 202 | " Find the next enclosing [ or {. We can limit the second search |
| 203 | " to the line, where the [ was found. If no [ was there this is |
| 204 | " zero and we search for an enclosing {. |
| 205 | let paren = s:MatchPairs('(', ')', 0) |
| 206 | let bracket = s:MatchPairs('\[', '\]', paren[0]) |
| 207 | let curly = s:MatchPairs('{', '}', bracket[0]) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 208 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 209 | " In case the curly brace is on a line later then the [ or - in |
| 210 | " case they are on the same line - in a higher column, we take the |
| 211 | " curly indent. |
| 212 | if curly[0] > bracket[0] || curly[1] > bracket[1] |
| 213 | if curly[0] > paren[0] || curly[1] > paren[1] |
| 214 | return curly[1] |
| 215 | endif |
| 216 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 217 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 218 | " If the curly was not chosen, we take the bracket indent - if |
| 219 | " there was one. |
| 220 | if bracket[0] > paren[0] || bracket[1] > paren[1] |
| 221 | return bracket[1] |
| 222 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 223 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 224 | " There are neither { nor [ nor (, ie. we are at the toplevel. |
| 225 | if paren == [0, 0] |
| 226 | return 0 |
| 227 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 228 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 229 | " Now we have to reimplement lispindent. This is surprisingly easy, as |
| 230 | " soon as one has access to syntax items. |
| 231 | " |
| 232 | " - Check whether we are in a special position after a word in |
| 233 | " g:clojure_special_indent_words. These are special cases. |
| 234 | " - Get the next keyword after the (. |
| 235 | " - If its first character is also a (, we have another sexp and align |
| 236 | " one column to the right of the unmatched (. |
| 237 | " - In case it is in lispwords, we indent the next line to the column of |
| 238 | " the ( + sw. |
| 239 | " - If not, we check whether it is last word in the line. In that case |
| 240 | " we again use ( + sw for indent. |
| 241 | " - In any other case we use the column of the end of the word + 2. |
| 242 | call cursor(paren) |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 243 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 244 | if s:IsMethodSpecialCase(paren) |
| 245 | return paren[1] + &shiftwidth - 1 |
| 246 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 247 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 248 | " In case we are at the last character, we use the paren position. |
| 249 | if col("$") - 1 == paren[1] |
| 250 | return paren[1] |
| 251 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 252 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 253 | " In case after the paren is a whitespace, we search for the next word. |
| 254 | call cursor(0, col('.') + 1) |
| 255 | if s:CurrentChar() == ' ' |
| 256 | call search('\v\S', 'W') |
| 257 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 258 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 259 | " If we moved to another line, there is no word after the (. We |
| 260 | " use the ( position for indent. |
| 261 | if line(".") > paren[0] |
| 262 | return paren[1] |
| 263 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 264 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 265 | " We still have to check, whether the keyword starts with a (, [ or {. |
| 266 | " In that case we use the ( position for indent. |
| 267 | let w = s:CurrentWord() |
| 268 | if stridx('([{', w[0]) > -1 |
| 269 | return paren[1] |
| 270 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 271 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 272 | " Test words without namespace qualifiers and leading reader macro |
| 273 | " metacharacters. |
| 274 | " |
| 275 | " e.g. clojure.core/defn and #'defn should both indent like defn. |
| 276 | let ww = substitute(w, "\\v%(.*/|[#'`~@^,]*)(.*)", '\1', '') |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 277 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 278 | if &lispwords =~ '\V\<' . ww . '\>' |
| 279 | return paren[1] + &shiftwidth - 1 |
| 280 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 281 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 282 | if g:clojure_fuzzy_indent |
| 283 | \ && !s:MatchesOne(g:clojure_fuzzy_indent_blacklist, ww) |
| 284 | \ && s:MatchesOne(g:clojure_fuzzy_indent_patterns, ww) |
| 285 | return paren[1] + &shiftwidth - 1 |
| 286 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 287 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 288 | call search('\v\_s', 'cW') |
| 289 | call search('\v\S', 'W') |
| 290 | if paren[0] < line(".") |
Bram Moolenaar | 438f67a | 2014-01-07 06:09:28 +0100 | [diff] [blame] | 291 | return paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1) |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 292 | endif |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 293 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 294 | call search('\v\S', 'bW') |
| 295 | return virtcol(".") + 1 |
| 296 | endfunction |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 297 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 298 | setlocal indentexpr=GetClojureIndent() |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 299 | |
| 300 | else |
| 301 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 302 | " In case we have searchpairpos not available we fall back to |
| 303 | " normal lisp indenting. |
| 304 | setlocal indentexpr= |
| 305 | setlocal lisp |
| 306 | let b:undo_indent .= '| setlocal lisp<' |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 307 | |
| 308 | endif |
| 309 | |
| 310 | " Specially indented symbols from clojure.core and clojure.test. |
| 311 | " |
| 312 | " Clojure symbols are indented in the defn style when they: |
| 313 | " |
| 314 | " * Define vars and anonymous functions |
| 315 | " * Create new lexical scopes or scopes with altered environments |
| 316 | " * Create conditional branches from a predicate function or value |
| 317 | " |
| 318 | " The arglists for these functions are generally in the form of [x & body]; |
| 319 | " Functions that accept a flat list of forms do not treat the first argument |
| 320 | " specially and hence are not indented specially. |
| 321 | |
| 322 | " Definitions |
| 323 | setlocal lispwords= |
| 324 | setlocal lispwords+=bound-fn |
| 325 | setlocal lispwords+=def |
| 326 | setlocal lispwords+=definline |
| 327 | setlocal lispwords+=definterface |
| 328 | setlocal lispwords+=defmacro |
| 329 | setlocal lispwords+=defmethod |
| 330 | setlocal lispwords+=defmulti |
| 331 | setlocal lispwords+=defn |
| 332 | setlocal lispwords+=defn- |
| 333 | setlocal lispwords+=defonce |
| 334 | setlocal lispwords+=defprotocol |
| 335 | setlocal lispwords+=defrecord |
| 336 | setlocal lispwords+=defstruct |
| 337 | setlocal lispwords+=deftest " clojure.test |
| 338 | setlocal lispwords+=deftest- " clojure.test |
| 339 | setlocal lispwords+=deftype |
| 340 | setlocal lispwords+=extend |
| 341 | setlocal lispwords+=extend-protocol |
| 342 | setlocal lispwords+=extend-type |
| 343 | setlocal lispwords+=fn |
| 344 | setlocal lispwords+=ns |
| 345 | setlocal lispwords+=proxy |
| 346 | setlocal lispwords+=reify |
| 347 | setlocal lispwords+=set-test " clojure.test |
| 348 | |
| 349 | " Binding forms |
| 350 | setlocal lispwords+=as-> |
| 351 | setlocal lispwords+=binding |
| 352 | setlocal lispwords+=doall |
| 353 | setlocal lispwords+=dorun |
| 354 | setlocal lispwords+=doseq |
| 355 | setlocal lispwords+=dotimes |
| 356 | setlocal lispwords+=doto |
| 357 | setlocal lispwords+=for |
| 358 | setlocal lispwords+=if-let |
| 359 | setlocal lispwords+=let |
| 360 | setlocal lispwords+=letfn |
| 361 | setlocal lispwords+=locking |
| 362 | setlocal lispwords+=loop |
| 363 | setlocal lispwords+=testing " clojure.test |
| 364 | setlocal lispwords+=when-first |
| 365 | setlocal lispwords+=when-let |
| 366 | setlocal lispwords+=with-bindings |
| 367 | setlocal lispwords+=with-in-str |
| 368 | setlocal lispwords+=with-local-vars |
| 369 | setlocal lispwords+=with-open |
| 370 | setlocal lispwords+=with-precision |
| 371 | setlocal lispwords+=with-redefs |
| 372 | setlocal lispwords+=with-redefs-fn |
| 373 | setlocal lispwords+=with-test " clojure.test |
| 374 | |
| 375 | " Conditional branching |
| 376 | setlocal lispwords+=case |
| 377 | setlocal lispwords+=cond-> |
| 378 | setlocal lispwords+=cond->> |
| 379 | setlocal lispwords+=condp |
| 380 | setlocal lispwords+=if |
| 381 | setlocal lispwords+=if-not |
| 382 | setlocal lispwords+=when |
| 383 | setlocal lispwords+=when-not |
| 384 | setlocal lispwords+=while |
| 385 | |
| 386 | " Exception handling |
| 387 | setlocal lispwords+=catch |
Bram Moolenaar | fa13eef | 2013-02-06 17:34:04 +0100 | [diff] [blame] | 388 | |
| 389 | let &cpo = s:save_cpo |
| 390 | unlet! s:save_cpo |
| 391 | |
Bram Moolenaar | baca7f7 | 2013-09-22 14:42:24 +0200 | [diff] [blame] | 392 | " vim:sts=8:sw=8:ts=8:noet |