-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathvim-textmate.lua
More file actions
375 lines (319 loc) · 9.45 KB
/
vim-textmate.lua
File metadata and controls
375 lines (319 loc) · 9.45 KB
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
local cpath = package.cpath
local module_path = vim.fn.expand("~/.vim/lua/vim-textmate/")
function exists(file)
local ok, err, code = os.rename(file, file)
if not ok then
if code == 13 then
return true
end
end
return ok, err
end
function isdir(path)
return exists(path.."/")
end
if not isdir(module_path) then
module_path = vim.fn.expand("~/.vim/bundle/vim-textmate/")
end
if not isdir(module_path) then
module_path = vim.fn.expand("~/.vim/dein/vim-textmate/")
end
if not isdir(module_path) then
module_path = vim.fn.expand("~/.vim/plugged/vim-textmate/")
end
package.cpath = cpath .. ";" .. module_path .. "?.so"
local ok, module = pcall(require, "textmate")
if not ok then
local target_path = module_path
print("Configuring textmate module...\n")
os.execute("make prebuild -C " .. target_path)
print("Compiling textmate module...\n")
os.execute("make build -C " .. target_path)
ok, module = pcall(require, "textmate")
if not ok then
print("error compiling vim-textmate")
end
end
package.cpath = cpath
local script_version = "0.1"
module.highlight_set_extensions_dir(vim.fn.expand(module_path .. "/extensions"))
module.highlight_set_extensions_dir(vim.fn.expand("~/.vscode/extensions/"))
module.highlight_set_extensions_dir(vim.fn.expand("~/.editor/extensions/"))
local debug_scopes = false
local enable_highlighting = true
local enable_textmate_color_fidelity = true
local props = {}
local _buffers = {}
local function setup(parameters) end
local function buffers(id)
if not _buffers[id] then
_buffers[id] = {
number = id,
last_count = 0,
langid = nil,
}
end
return _buffers[id]
end
local scope_hl_map = {
{ "type", "StorageClass" },
{ "storage.type", "Identifier" },
{ "constant", "Constant" },
{ "constant.numeric", "Number" },
{ "constant.character", "Character" },
{ "primitive", "Boolean" },
{ "variable", "StorageClass" },
{ "keyword", "Define" },
{ "declaration", "Conditional" },
{ "control", "Conditional" },
{ "operator", "Operator" },
{ "directive", "PreProc" },
{ "require", "Include" },
{ "import", "Include" },
{ "function", "Function" },
{ "struct", "Structure" },
{ "class", "Structure" },
{ "modifier", "Boolean" },
{ "namespace", "StorageClass" },
{ "scope", "StorageClass" },
{ "name.type", "StorageClass" },
-- { "name.type", "Variable" },
{ "tag", "Tag" },
{ "name.tag", "StorageClass" },
{ "attribute", "StorageClass" },
-- { "attribute", "Variable" },
{ "property", "StorageClass" },
-- { "property", "Variable" },
{ "heading", "markdownH1" },
{ "string", "String" },
{ "string.other", "Label" },
{ "comment", "Comment" },
}
function txmt_highlight_line(n, l)
local b = buffers(vim.buffer().number)
vim.command("call prop_clear(" .. n .. "," .. n .. ", { 'bufnr': " .. b.number .. "})")
if not enable_highlighting then
return
end
local langid = b.langid
if not langid then
langid = module.highlight_load_language(vim.fn.expand("%"))
b.langid = langid
end
if langid == -1 then
return
end
local r = vim.window().line
local c = vim.window().column
module.highlight_set_language(langid)
local t = module.highlight_line(l, n, langid, b.number)
for i, style in ipairs(t) do
local start = math.floor(style[1])
local length = math.floor(style[2])
local scope = style[3]
if debug_scopes and r == n and (c - 1) >= start and (c - 1) < start + length then
print(scope)
end
local hl = nil
-- render with colors
if enable_textmate_color_fidelity then
local rr = style[4] -- rgb color
local gg = style[5]
local bb = style[6]
local aa = style[7] -- nearest color index
local bold = style[8]
local italic = style[9]
local underline = style[10]
local attribs = ""
local term = {}
local terms = ""
if rr > 0 then
if bold == 1 then
table.insert(term, "bold")
attribs = attribs .. "b"
end
if italic == 1 then
table.insert(term, "italic")
attribs = attribs .. "i"
end
-- if underline == 1 then
-- table.insert(term, "underline")
-- attribs = attribs .. "u"
-- end
if #term > 0 then
terms = " cterm=" .. table.concat(term, ",")
end
local clr = string.format("%02x%02x%02x", rr, gg, bb)
if clr and clr:len() < 8 then
hl = clr .. attribs
if not props[hl] then
vim.command("highlight " .. hl .. terms .. " ctermfg=" .. math.floor(aa) .. " guifg=#" .. clr)
end
end
end
end
-- render with color schemes
if not enable_textmate_color_fidelity then
for j, map in ipairs(scope_hl_map) do
if string.find(scope, map[1]) then
hl = map[2]
end
end
end
if hl then
if not props[hl] then
vim.command("call prop_type_add('" .. hl .. "', { 'highlight': '" .. hl .. "', 'priority': 0 })")
props[hl] = true
end
vim.command(
"call prop_add(" .. n .. "," .. (start + 1) .. ", { 'length': " .. length .. ", 'type': '" .. hl .. "'})"
)
end
end
end
function txmt_highlight_current_line()
txmt_highlight_line(vim.window().line, vim.buffer()[vim.window().line])
end
function txmt_highlight_current_buffer(no_limit, make_dirty)
local b = buffers(vim.buffer().number)
if make_dirty then
module.highlight_make_doc_dirty(b.number)
end
local r = vim.window().line
local c = vim.window().column
local lc = #vim.buffer()
local sr = vim.window().height -- screen rows
b.last_count = lc
local ls = r - sr
local le = r + sr
if ls < 1 then
ls = 1
end
if le > lc then
le = lc
end
local dirty_count = 0
for i = ls, le - 1, 1 do
if module.highlight_is_line_dirty(i, b.number) ~= 0 then
local line = vim.buffer()[i]
txmt_highlight_line(i, line)
dirty_count = dirty_count + 1
if no_limit ~= true and dirty_count > (sr * 1.4) then
break
end
end
end
if debug_scopes then
txmt_highlight_current_line()
end
end
function txmt_on_text_changed()
local b = buffers(vim.buffer().number)
local lc = b.last_count
local count = #vim.buffer()
local changed_lines = 1
local nr = vim.window().line - 1
local diff = count - lc
if diff > 0 then
changed_lines = diff
for nr = 0, diff, 1 do
module.highlight_add_block(nr, b.number)
end
end
if diff < 0 then
changed_lines = -diff
for nr = 0, -diff, 1 do
module.highlight_remove_block(nr, b.number)
end
end
for cl = 0, changed_lines, 1 do
module.highlight_make_line_dirty(nr + cl, b.number)
end
txmt_highlight_current_buffer(true)
end
function txmt_on_delete_buffer()
local n = vim.buffer().number
if _buffers[n] then
_buffers[n] = nil
module.highlight_remove_doc(n)
end
end
function txmt_info()
local b = buffers(vim.buffer().number)
if script_version == module.highlight_module_version then
print("version: " .. script_version)
else
print("warning script & module versions do not match")
print("script version: " .. script_version)
print("module version: " .. module.highlight_module_version)
end
print("file: " .. vim.fn.expand("%"))
if b.langid and b.langid ~= -1 then
local info = module.highlight_language_info(b.langid)
print("language: " .. info[1] .. "\ngrammar: " .. info[2])
end
end
function txmt_info_languages()
local s = {}
local languages = module.highlight_languages()
for i, lang in ipairs(languages) do
table.insert(s, lang[1])
end
print("languages available:\n")
print(table.concat(s, ", "))
end
function txmt_info_themes()
local s = {}
local themes = module.highlight_themes()
for i, thm in ipairs(themes) do
table.insert(s, thm[1])
end
print("themes available:\n")
print(table.concat(s, ", "))
end
function txmt_set_theme(thm)
if string.len(thm) > 1 and string.sub(thm, 1, 1) == '"' then
thm = string.sub(thm, 2, string.len(thm) - 1)
end
module.highlight_load_theme(thm)
enable_textmate_color_fidelity = true
--vim.command("syn off")
txmt_highlight_current_buffer(true, true)
end
function txmt_debug_scopes()
if debug_scopes then
debug_scopes = false
else
debug_scopes = true
end
end
function txmt_enable_color_fidelity()
if enable_textmate_color_fidelity then
enable_textmate_color_fidelity = false
else
enable_textmate_color_fidelity = true
end
end
function txmt_enable(args)
enable_highlighting = args
if not enable_highlighting then
txmt_on_delete_buffer()
end
txmt_highlight_current_buffer(true, true)
end
vim.command("syn on")
vim.command("au CursorMoved,CursorMovedI * :lua txmt_highlight_current_buffer()")
vim.command("au CursorHold,CursorHoldI * :lua txmt_highlight_current_buffer()")
vim.command("au TextChanged,TextChangedI * :lua txmt_on_text_changed()")
vim.command("au BufEnter * :lua txmt_highlight_current_buffer(true, true)")
vim.command("au BufDelete * :lua txmt_on_delete_buffer()")
vim.command("command TxmtInfo 0 % :lua txmt_info()")
vim.command("command TxmtInfoLanguages 0 % :lua txmt_info_languages()")
vim.command("command TxmtInfoThemes 0 % :lua txmt_info_themes()")
vim.command("command TxmtSetTheme 1 % :lua txmt_set_theme(<q-args>)")
vim.command("command TxmtDebugScopes 0 % :lua txmt_debug_scopes()")
vim.command("command TxmtEnable 0 % :lua txmt_enable(true)")
vim.command("command TxmtDisable 0 % :lua txmt_enable(false)")
return {
setup = setup,
}