1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
" Matlab indent file
" Language: Matlab
" Maintainer: Fabrice Guy <fabrice.guy at gmail dot com>
" Last Change: 2008 Oct 15
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
let s:onlySubfunctionExists = 0
setlocal indentexpr=GetMatlabIndent()
setlocal indentkeys=!,o,O=end,=case,=else,=elseif,=otherwise,=catch
" Only define the function once.
if exists("*GetMatlabIndent")
finish
endif
function! s:IsMatlabContinuationLine(lnum)
let continuationLine = 0
if a:lnum > 0
let pnbline = getline(prevnonblank(a:lnum))
" if we have the line continuation operator (... at the end of a line or
" ... followed by a comment) it may be a line continuation
if pnbline =~ '\.\.\.\s*$' || pnbline =~ '\.\.\.\s*%.*$'
let continuationLine = 1
" but if the ... are part of a string or a comment, it is not a
" continuation line
let col = match(pnbline, '\.\.\.\s*$')
if col == -1
let col = match(pnbline, '\.\.\.\s*%.*$')
endif
if has('syntax_items')
if synIDattr(synID(prevnonblank(a:lnum), col + 1, 1), "name") =~ "matlabString" ||
\ synIDattr(synID(prevnonblank(a:lnum), col + 1, 1), "name") =~ "matlabComment"
let continuationLine = 0
endif
endif
endif
endif
return continuationLine
endfunction
function GetMatlabIndent()
" Find a non-blank line above the current line.
let plnum = prevnonblank(v:lnum - 1)
" If the previous line is a continuation line, get the beginning of the block to
" use the indent of that line
if s:IsMatlabContinuationLine(plnum - 1)
while s:IsMatlabContinuationLine(plnum - 1)
let plnum = plnum - 1
endwhile
endif
" At the start of the file use zero indent.
if plnum == 0
return 0
endif
let curind = indent(plnum)
if s:IsMatlabContinuationLine(v:lnum - 1)
let curind = curind + &sw
endif
" Add a 'shiftwidth' after classdef, properties, switch, methods, events,
" function, if, while, for, otherwise, case, tic, try, catch, else, elseif
if getline(plnum) =~ '^\s*\(classdef\|properties\|switch\|methods\|events\|function\|if\|while\|for\|otherwise\|case\|tic\|try\|catch\|else\|elseif\)\>'
let curind = curind + &sw
" In Matlab we have different kind of functions
" - the main function (the function with the same name than the filename)
" - the nested functions
" - the functions defined in methods (for classes)
" - subfunctions
" For the moment the main function (located line 1) doesn't produce any indentation in the
" code (default behavior in the Matlab editor) and the other kind of
" functions indent the code
if getline(plnum) =~ '^\s*\function\>'
" If it is the main function
if plnum == 1
" look for a matching end :
" - if we find a matching end everything is fine
" - if not, then all other functions are subfunctions
normal %
if getline(line('.')) =~ '^\s*end'
let s:onlySubfunctionExists = 0
else
let s:onlySubfunctionExists = 1
endif
normal %
let curind = curind - &sw
else
" it is a subfunction without matching end : dedent
if s:onlySubfunctionExists
let curind = curind - &sw
endif
endif
endif
endif
" Subtract a 'shiftwidth' on a else, elseif, end, catch, otherwise, case,
" toc
if getline(v:lnum) =~ '^\s*\(else\|elseif\|end\|catch\|otherwise\|case\|toc\)\>'
let curind = curind - &sw
endif
" No indentation in a subfunction
if getline(v:lnum) =~ '^\s*\function\>' && s:onlySubfunctionExists
let curind = curind - &sw
endif
" First case after a switch : indent
if getline(v:lnum) =~ '^\s*case'
while plnum > 0 && (getline(plnum) =~ '^\s*%' || getline(plnum) =~ '^\s*$')
let plnum = plnum - 1
endwhile
if getline(plnum) =~ '^\s*switch'
let curind = indent(plnum) + &sw
endif
endif
" end in a switch / end block : dedent twice
" we use the matchit script to know if this end is the end of a switch block
if exists("b:match_words")
if getline(v:lnum) =~ '^\s*end'
normal %
if getline(line('.')) =~ "switch"
let curind = curind - &sw
endif
normal %
end
end
return curind
endfunction
" vim:sw=2
|