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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
" MNV filetype plugin file.
" Language: Lua
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainer: Max Ischenko <mfi@ukr.net>
" Contributor: Dorai Sitaram <ds26@gte.com>
" C.D. MacEachern <craig.daniel.maceachern@gmail.com>
" Tyler Miller <tmillr@proton.me>
" Phạm Bình An <phambinhanctb2004@gmail.com>
" @konfekt
" Last Change: 2025 Apr 04
" 2025 May 06 by MNV Project update 'path' setting #17267
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
" keep in sync with syntax/lua.mnv
if !exists("lua_version")
" Default is lua 5.3
let lua_version = 5
let lua_subversion = 3
elseif !exists("lua_subversion")
" lua_version exists, but lua_subversion doesn't. In this case set it to 0
let lua_subversion = 0
endif
let s:cpo_save = &cpo
set cpo&mnv
setlocal comments=:---,:--
setlocal commentstring=--\ %s
setlocal formatoptions-=t formatoptions+=croql
setlocal path-=. " Lua doesn't support importing module in path related to current file like JS
let &l:define = '\<function\|\<local\%(\s\+function\)\='
let &l:include = '\<\%(\%(do\|load\)file\|require\)\s*('
setlocal includeexpr=s:LuaInclude(v:fname)
setlocal suffixesadd=.lua
let b:undo_ftplugin = "setl cms< com< def< fo< inc< inex< sua< pa<"
if exists("loaded_matchit") && !exists("b:match_words")
let b:match_ignorecase = 0
let b:match_words =
\ '\<\%(do\|function\|if\)\>:' ..
\ '\<\%(return\|else\|elseif\)\>:' ..
\ '\<end\>,' ..
\ '\<repeat\>:\<until\>,' ..
\ '\%(--\)\=\[\(=*\)\[:]\1]'
let b:undo_ftplugin ..= " | unlet! b:match_words b:match_ignorecase"
endif
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
let b:browsefilter = "Lua Source Files (*.lua)\t*.lua\n"
if has("win32")
let b:browsefilter ..= "All Files (*.*)\t*\n"
else
let b:browsefilter ..= "All Files (*)\t*\n"
endif
let b:undo_ftplugin ..= " | unlet! b:browsefilter"
endif
if has("folding") && get(g:, "lua_folding", 0)
setlocal foldmethod=expr
setlocal foldexpr=s:LuaFold()
let b:lua_lasttick = -1
let b:undo_ftplugin ..= " | setl foldexpr< foldmethod< | unlet! b:lua_lasttick b:lua_foldlists"
endif
" The rest of the file needs to be :sourced only once per MNV session
if exists("s:loaded_lua") || &cp
let &cpo = s:cpo_save
unlet s:cpo_save
finish
endif
let s:loaded_lua = 1
function s:LuaInclude(fname) abort
let lua_ver = str2float(printf("%d.%02d", g:lua_version, g:lua_subversion))
let fname = tr(a:fname, '.', '/')
let paths = lua_ver >= 5.03 ? [fname .. ".lua", fname .. "/init.lua"] : [fname .. ".lua"]
for path in paths
if filereadable(path)
return path
endif
endfor
return fname
endfunction
let s:patterns = [
\ ['do', 'end'],
\ ['if\s+.+\s+then', 'end'],
\ ['repeat', 'until\s+.+'],
\ ['for\s+.+\s+do', 'end'],
\ ['while\s+.+\s+do', 'end'],
\ ['function.+', 'end'],
\ ['return\s+function.+', 'end'],
\ ['local\s+function\s+.+', 'end'],
\ ]
function s:LuaFold() abort
if b:lua_lasttick == b:changedtick
return b:lua_foldlists[v:lnum - 1]
endif
let b:lua_lasttick = b:changedtick
let b:lua_foldlists = []
let foldlist = []
let buf = getline(1, "$")
for line in buf
for t in s:patterns
let open = 0
let end = 0
let tagopen = '\v^\s*' .. t[0] ..'\s*$'
let tagend = '\v^\s*' .. t[1] ..'\s*$'
if line =~# tagopen
call add(foldlist, t)
let open = 1
break
elseif line =~# tagend
if len(foldlist) > 0 && line =~# foldlist[-1][1]
call remove(foldlist, -1)
let end = 1
else
let foldlist = []
endif
break
endif
endfor
let prefix = ""
if open == 1 | let prefix = ">" | endif
if end == 1 | let prefix = "<" | endif
let b:lua_foldlists += [prefix..(len(foldlist) + end)]
endfor
return b:lua_foldlists[v:lnum - 1]
endfunction
if !has('mnv9script')
let &cpo = s:cpo_save
unlet s:cpo_save
finish
endif
delfunction! s:LuaFold
def s:LuaFold(): string
if b:lua_lasttick == b:changedtick
return b:lua_foldlists[v:lnum - 1]
endif
b:lua_lasttick = b:changedtick
b:lua_foldlists = []
var foldlist = []
var buf = getline(1, "$")
for line in buf
var open = 0
var end = 0
for t in patterns
var tagopen = '\v^\s*' .. t[0] .. '\s*$'
var tagend = '\v^\s*' .. t[1] .. '\s*$'
if line =~# tagopen
add(foldlist, t)
open = 1
break
elseif line =~# tagend
if len(foldlist) > 0 && line =~# foldlist[-1][1]
end = 1
remove(foldlist, -1)
else
foldlist = []
endif
break
endif
endfor
var prefix = ""
if open == 1 | prefix = ">" | endif
if end == 1 | prefix = "<" | endif
b:lua_foldlists += [prefix .. (len(foldlist) + end)]
endfor
return b:lua_foldlists[v:lnum - 1]
enddef
let &cpo = s:cpo_save
unlet s:cpo_save
" mnv: nowrap sw=2 sts=2 ts=8 noet:
|