-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.vim
177 lines (149 loc) · 3.75 KB
/
plugin.vim
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
""" Helpers
function! s:StoreCurPos()
if g:xi_preserve_curpos == 1
if exists("*getcurpos")
let s:cur = getcurpos()
else
let s:cur = getpos('.')
endif
endif
endfunction
function! s:RestoreCurPos()
if g:xi_preserve_curpos == 1
call setpos('.', s:cur)
endif
endfunction
function! s:FlashVisualSelection(msg)
" Redraw to show current visual selection, and sleep
redraw
execute "sleep " . g:xi_flash_duration . " m"
" Then leave visual mode
silent execute "normal! vv"
endfunction
" Guess correct number of spaces to indent
" (tabs are not allowed)
function! s:GetIndentString()
return repeat(" ", 4)
endfunction
" Teplace tabs by spaces
function! s:TabToSpaces(text)
return substitute(a:text, " ", s:GetIndentString(), "g")
endfunction
" Check if line is commented out
function! s:IsComment(line)
return (match(a:line, "^[ \t]*#.*") >= 0)
endfunction
" Remove commented out lines
function! s:RemoveLineComments(lines)
let l:i = 0
let l:len = len(a:lines)
let l:ret = []
while l:i < l:len
if !s:IsComment(a:lines[l:i])
call add(l:ret, a:lines[l:i])
endif
let l:i += 1
endwhile
return l:ret
endfunction
" Change string into array of lines
function! s:Lines(text)
return split(a:text, "\n")
endfunction
" Change lines back into text
function! s:Unlines(lines)
return join(a:lines, "\n") . "\n"
endfunction
function! s:EscapeText(text)
let l:lines = s:Lines(s:TabToSpaces(a:text))
let l:lines = s:RemoveLineComments(l:lines)
let l:result = s:Unlines(l:lines)
echom l:result
" return an array, regardless
if type(l:result) == type("")
return [l:result]
else
return l:result
end
endfunction
function! s:Truncate(string, num)
let letters = split(a:string, '\zs')
return join(letters[:a:num], "")
endfunction
""" Main Functions
let g:xi_out_buffer = []
function! xi#plugin#OutHandler(_job_id, data, event) dict
" Do nothing
"echom join(a:data, "\n")
endfunction
function! xi#plugin#ErrHandler(_job_id, data, event)
echohl ErrorMsg
echom join(a:data, "\n")
echohl None
endfunction
function! xi#plugin#Start()
if exists("g:xi_job") && g:xi_job > 0
echo 'Xi already started.'
else
let g:xi_job = xi#job#start([g:xi_repl], {
\'on_stdout': function('xi#plugin#OutHandler'),
\'on_stderr': function('xi#plugin#ErrHandler'),
\})
if g:xi_job == -2
echoerr "No support for async jobs. Cannot start Xi :("
elseif g:xi_job > 0
echom 'Xi started'
else
echom 'Xi failed to start'
unlet g:xi_job
endif
endif
endfunction
function! xi#plugin#Stop()
if exists("g:xi_job")
call xi#job#stop(g:xi_job)
unlet g:xi_job
echom "Xi stopped"
else
echo "Xi is not running"
endif
endfunction
function! xi#plugin#Eval(message)
if !exists("g:xi_job")
call xi#plugin#Start()
endif
let trunc_msg = s:Truncate(a:message, 20)
echo trunc_msg
let l:lines = s:EscapeText(a:message)
for line in l:lines
call xi#job#send(g:xi_job, line . "\n")
endfor
endfunction
function! xi#plugin#EvalSimple(message)
if !exists("g:xi_job")
call xi#plugin#Start()
endif
echom a:message
call xi#job#send(g:xi_job, a:message . "\n")
endfunction
function! xi#plugin#EvalParagraph()
call s:StoreCurPos()
silent execute "normal! vipy<cr>"
let l:content = getreg('')
call xi#plugin#Eval(l:content)
silent execute "normal! '[V']"
call s:FlashVisualSelection(l:content)
call s:RestoreCurPos()
endfunction
function! xi#plugin#EvalSelection() range
silent execute a:firstline . ',' . a:lastline . 'yank'
let l:content = getreg('')
call xi#plugin#Eval(l:content)
endfunction
function! xi#plugin#Hush()
if exists("g:xi_job")
call xi#plugin#EvalSimple("hush")
else
echo "Xi is not running"
endif
endfunction