-
Notifications
You must be signed in to change notification settings - Fork 263
/
vis-std.lua
163 lines (137 loc) · 4.51 KB
/
vis-std.lua
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
-- standard vis event handlers
vis.events.subscribe(vis.events.INIT, function()
local package_exist = function(name)
for _, searcher in ipairs(package.searchers or package.loaders) do
local loader = searcher(name)
if type(loader) == 'function' then
return true
end
end
return false
end
if not package_exist('lpeg') then
vis:info('WARNING: could not find lpeg module')
elseif not package_exist('lexer') then
vis:info('WARNING: could not find lexer module')
else
vis.lexers = require('lexer')
end
vis:command("set theme ".. (vis.ui.colors <= 16 and "default-16" or "default-256"))
end)
vis.events.subscribe(vis.events.THEME_CHANGE, function(name)
if name ~= nil then
local theme = 'themes/'..name
package.loaded[theme] = nil
require(theme)
end
if vis.lexers then vis.lexers.lexers = {} end
for win in vis:windows() do
win.syntax = win.syntax;
end
end)
vis.events.subscribe(vis.events.WIN_SYNTAX, function(win, name)
local lexers = vis.lexers
if not lexers.load then return false end
win:style_define(win.STYLE_DEFAULT, lexers.STYLE_DEFAULT or '')
win:style_define(win.STYLE_CURSOR, lexers.STYLE_CURSOR or '')
win:style_define(win.STYLE_CURSOR_PRIMARY, lexers.STYLE_CURSOR_PRIMARY or '')
win:style_define(win.STYLE_CURSOR_LINE, lexers.STYLE_CURSOR_LINE or '')
win:style_define(win.STYLE_SELECTION, lexers.STYLE_SELECTION or '')
win:style_define(win.STYLE_LINENUMBER, lexers.STYLE_LINENUMBER or '')
win:style_define(win.STYLE_COLOR_COLUMN, lexers.STYLE_COLOR_COLUMN or '')
if name == nil then return true end
local lexer = lexers.load(name)
if not lexer then return false end
for token_name, id in pairs(lexer._TOKENSTYLES) do
local style = lexers['STYLE_'..string.upper(token_name)] or lexer._EXTRASTYLES[token_name]
win:style_define(id, style)
end
return true
end)
vis.events.subscribe(vis.events.WIN_HIGHLIGHT, function(win, horizon_max)
if win.syntax == nil or vis.lexers == nil then return end
local lexer = vis.lexers.load(win.syntax)
if lexer == nil then return end
-- TODO: improve heuristic for initial style
local viewport = win.viewport
if not viewport then return end
local horizon = viewport.start < horizon_max and viewport.start or horizon_max
local view_start = viewport.start
local lex_start = viewport.start - horizon
local token_start = lex_start
viewport.start = token_start
local data = win.file:content(viewport)
local token_styles = lexer._TOKENSTYLES
local tokens = lexer:lex(data, 1)
for i = 1, #tokens, 2 do
local token_end = lex_start + tokens[i+1] - 1
if token_end >= view_start then
local name = tokens[i]
local style = token_styles[name]
if style ~= nil then
win:style(style, token_start, token_end)
end
end
token_start = token_end
end
end)
local modes = {
[vis.modes.NORMAL] = '',
[vis.modes.OPERATOR_PENDING] = '',
[vis.modes.VISUAL] = 'VISUAL',
[vis.modes.VISUAL_LINE] = 'VISUAL-LINE',
[vis.modes.INSERT] = 'INSERT',
[vis.modes.REPLACE] = 'REPLACE',
}
vis.events.subscribe(vis.events.WIN_STATUS, function(win)
local left_parts = {}
local right_parts = {}
local file = win.file
local cursor = win.cursor
local mode = modes[vis.mode]
if mode ~= '' and vis.win == win then
table.insert(left_parts, mode)
end
table.insert(left_parts, (file.name or '[No Name]') ..
(file.modified and ' [+]' or '') .. (vis.recording and ' @' or ''))
if file.newlines == "crlf" then
table.insert(right_parts, "␍␊")
end
if #win.cursors > 1 then
table.insert(right_parts, cursor.number..'/'..#win.cursors)
end
local size = file.size
table.insert(right_parts, (size == 0 and "0" or math.ceil(cursor.pos/size*100)).."%")
if not win.large then
local col = cursor.col
table.insert(right_parts, cursor.line..', '..col)
if size > 33554432 or col > 65536 then
win.large = true
end
end
local left = ' ' .. table.concat(left_parts, " » ") .. ' '
local right = ' ' .. table.concat(right_parts, " « ") .. ' '
win:status(left, right);
end)
-- additional default keybindings
vis:map(vis.modes.INSERT, "<C-k>", function(keys)
if #keys < 2 then
return -1 -- need more input
end
local file = io.popen(string.format("vis-digraph '%s' 2>&1", keys:gsub("'", "'\\''")))
local output = file:read('*all')
local success, msg, status = file:close()
if success then
if vis.mode == vis.modes.INSERT then
vis:insert(output)
elseif vis.mode == vis.modes.REPLACE then
vis:replace(output)
end
elseif msg == 'exit' then
if status == 2 then
return -1 -- prefix need more input
end
vis:info(output)
end
return #keys
end, "Insert digraph")