@@ -26,15 +26,15 @@ if not rawget(_L, 'Lua REPL') then _L['Lua REPL'] = 'L_ua REPL' end
2626-- @table env
2727-- @local
2828local env = setmetatable ({
29- print = function (...)
30- buffer :add_text (' --> ' )
31- local args = table.pack (... )
32- for i = 1 , args .n do
33- buffer :add_text (tostring (args [i ]))
34- if i < args .n then buffer :add_text (' \t ' ) end
35- end
36- buffer :new_line ()
37- end
29+ print = function (...)
30+ buffer :add_text (' --> ' )
31+ local args = table.pack (... )
32+ for i = 1 , args .n do
33+ buffer :add_text (tostring (args [i ]))
34+ if i < args .n then buffer :add_text (' \t ' ) end
35+ end
36+ buffer :new_line ()
37+ end
3838}, {__index = _G })
3939
4040--- Lua command history.
@@ -44,165 +44,165 @@ M.history = {pos = 0}
4444--- Evaluates as Lua code the current line or the text on the currently selected lines.
4545-- If the current line has a syntax error, it is ignored and treated as a line continuation.
4646function M .evaluate_repl ()
47- local s , e = buffer .selection_start , buffer .selection_end
48- local code , last_line
49- if s ~= e then -- use selected lines as code
50- local i , j = buffer :line_from_position (s ), buffer :line_from_position (e )
51- if i < j then
52- s = buffer :position_from_line (i )
53- if buffer .column [e ] > 1 then e = buffer :position_from_line (j + 1 ) end
54- end
55- code = buffer :text_range (s , e )
56- last_line = buffer :line_from_position (e )
57- else -- use line as input
58- code = buffer :get_cur_line ()
59- last_line = buffer :line_from_position (buffer .current_pos )
60- end
47+ local s , e = buffer .selection_start , buffer .selection_end
48+ local code , last_line
49+ if s ~= e then -- use selected lines as code
50+ local i , j = buffer :line_from_position (s ), buffer :line_from_position (e )
51+ if i < j then
52+ s = buffer :position_from_line (i )
53+ if buffer .column [e ] > 1 then e = buffer :position_from_line (j + 1 ) end
54+ end
55+ code = buffer :text_range (s , e )
56+ last_line = buffer :line_from_position (e )
57+ else -- use line as input
58+ code = buffer :get_cur_line ()
59+ last_line = buffer :line_from_position (buffer .current_pos )
60+ end
6161
62- local f , result = load (' return ' .. code , ' repl' , ' t' , env )
63- if not f then f , result = load (code , ' repl' , ' t' , env ) end
64- if not f and s == e then return false end -- multi-line chunk; propagate key
65- buffer :goto_pos (buffer .line_end_position [last_line ])
66- buffer :new_line ()
67- if f then result = select (2 , pcall (f )) end
68- if result then
69- buffer :add_text (' --> ' )
70- if type (result ) == ' table' then
71- -- Pretty-print tables like ui.command_entry does.
72- local items = {}
73- for k , v in pairs (result ) do items [# items + 1 ] = string.format (' %s = %s' , k , v ) end
74- table.sort (items )
75- result = string.format (' {%s}' , table.concat (items , ' , ' ))
76- if view .edge_column > 0 and # result > view .edge_column then
77- local indent = string.rep (' ' , buffer .tab_width )
78- result = string.format (' {\n %s%s\n }' , indent , table.concat (items , ' ,\n ' .. indent ))
79- end
80- end
81- buffer :add_text (tostring (result ):gsub (' (\r ?\n )' , ' %1--> ' ))
82- buffer :new_line ()
83- end
84- M .history [# M .history + 1 ] = code
85- M .history .pos = # M .history + 1
86- buffer :set_save_point ()
62+ local f , result = load (' return ' .. code , ' repl' , ' t' , env )
63+ if not f then f , result = load (code , ' repl' , ' t' , env ) end
64+ if not f and s == e then return false end -- multi-line chunk; propagate key
65+ buffer :goto_pos (buffer .line_end_position [last_line ])
66+ buffer :new_line ()
67+ if f then result = select (2 , pcall (f )) end
68+ if result then
69+ buffer :add_text (' --> ' )
70+ if type (result ) == ' table' then
71+ -- Pretty-print tables like ui.command_entry does.
72+ local items = {}
73+ for k , v in pairs (result ) do items [# items + 1 ] = string.format (' %s = %s' , k , v ) end
74+ table.sort (items )
75+ result = string.format (' {%s}' , table.concat (items , ' , ' ))
76+ if view .edge_column > 0 and # result > view .edge_column then
77+ local indent = string.rep (' ' , buffer .tab_width )
78+ result = string.format (' {\n %s%s\n }' , indent , table.concat (items , ' ,\n ' .. indent ))
79+ end
80+ end
81+ buffer :add_text (tostring (result ):gsub (' (\r ?\n )' , ' %1--> ' ))
82+ buffer :new_line ()
83+ end
84+ M .history [# M .history + 1 ] = code
85+ M .history .pos = # M .history + 1
86+ buffer :set_save_point ()
8787end
8888
8989--- Shows a set of Lua code completions for the current position.
9090function M .complete_lua ()
91- local line , pos = buffer :get_cur_line ()
92- local symbol , op , part = line :sub (1 , pos - 1 ):match (' ([%w_.]-)([%.:]?)([%w_]*)$' )
93- local ok , result = pcall ((load (string.format (' return (%s)' , symbol ), nil , ' t' , env )))
94- if (not ok or type (result ) ~= ' table' ) and symbol ~= ' ' then return end
95- local cmpls = {}
96- part = ' ^' .. part
97- if not ok or symbol == ' buffer' then
98- local sci = _SCINTILLA
99- local global_envs = not ok and {_G } or
100- (op == ' :' and {sci .functions } or {sci .properties , sci .constants })
101- for i = 1 , # global_envs do
102- for k in pairs (global_envs [i ]) do
103- if type (k ) == ' string' and k :find (part ) then cmpls [# cmpls + 1 ] = k end
104- end
105- end
106- else
107- for k , v in pairs (result ) do
108- if type (k ) == ' string' and k :find (part ) and (op == ' .' or type (v ) == ' function' ) then
109- cmpls [# cmpls + 1 ] = k
110- end
111- end
112- end
113- table.sort (cmpls )
114- buffer .auto_c_order = buffer .ORDER_PRESORTED
115- buffer :auto_c_show (# part - 1 , table.concat (cmpls , string.char (buffer .auto_c_separator )))
91+ local line , pos = buffer :get_cur_line ()
92+ local symbol , op , part = line :sub (1 , pos - 1 ):match (' ([%w_.]-)([%.:]?)([%w_]*)$' )
93+ local ok , result = pcall ((load (string.format (' return (%s)' , symbol ), nil , ' t' , env )))
94+ if (not ok or type (result ) ~= ' table' ) and symbol ~= ' ' then return end
95+ local cmpls = {}
96+ part = ' ^' .. part
97+ if not ok or symbol == ' buffer' then
98+ local sci = _SCINTILLA
99+ local global_envs = not ok and {_G } or
100+ (op == ' :' and {sci .functions } or {sci .properties , sci .constants })
101+ for i = 1 , # global_envs do
102+ for k in pairs (global_envs [i ]) do
103+ if type (k ) == ' string' and k :find (part ) then cmpls [# cmpls + 1 ] = k end
104+ end
105+ end
106+ else
107+ for k , v in pairs (result ) do
108+ if type (k ) == ' string' and k :find (part ) and (op == ' .' or type (v ) == ' function' ) then
109+ cmpls [# cmpls + 1 ] = k
110+ end
111+ end
112+ end
113+ table.sort (cmpls )
114+ buffer .auto_c_order = buffer .ORDER_PRESORTED
115+ buffer :auto_c_show (# part - 1 , table.concat (cmpls , string.char (buffer .auto_c_separator )))
116116end
117117
118118--- Cycle backward through command history, taking into account commands with multiple lines.
119119function M .cycle_history_prev ()
120- if buffer :auto_c_active () then
121- buffer :line_up ()
122- return
123- end
124- if M .history .pos <= 1 then return end
125- for _ in (M .history [M .history .pos ] or ' ' ):gmatch (' \n ' ) do
126- buffer :line_delete ()
127- buffer :delete_back ()
128- end
129- buffer :line_delete ()
130- M .history .pos = math.max (M .history .pos - 1 , 1 )
131- buffer :add_text (M .history [M .history .pos ])
120+ if buffer :auto_c_active () then
121+ buffer :line_up ()
122+ return
123+ end
124+ if M .history .pos <= 1 then return end
125+ for _ in (M .history [M .history .pos ] or ' ' ):gmatch (' \n ' ) do
126+ buffer :line_delete ()
127+ buffer :delete_back ()
128+ end
129+ buffer :line_delete ()
130+ M .history .pos = math.max (M .history .pos - 1 , 1 )
131+ buffer :add_text (M .history [M .history .pos ])
132132end
133133
134134--- Cycle forward through command history, taking into account commands with multiple lines.
135135function M .cycle_history_next ()
136- if buffer :auto_c_active () then
137- buffer :line_down ()
138- return
139- end
140- if M .history .pos >= # M .history then return end
141- for _ in (M .history [M .history .pos ] or ' ' ):gmatch (' \n ' ) do
142- buffer :line_delete ()
143- buffer :delete_back ()
144- end
145- buffer :line_delete ()
146- M .history .pos = math.min (M .history .pos + 1 , # M .history )
147- buffer :add_text (M .history [M .history .pos ])
136+ if buffer :auto_c_active () then
137+ buffer :line_down ()
138+ return
139+ end
140+ if M .history .pos >= # M .history then return end
141+ for _ in (M .history [M .history .pos ] or ' ' ):gmatch (' \n ' ) do
142+ buffer :line_delete ()
143+ buffer :delete_back ()
144+ end
145+ buffer :line_delete ()
146+ M .history .pos = math.min (M .history .pos + 1 , # M .history )
147+ buffer :add_text (M .history [M .history .pos ])
148148end
149149
150150--- Table of key bindings for the REPL.
151151M .keys = {} -- empty declaration to avoid LDoc processing
152152M .keys = {
153- [' \n ' ] = M .evaluate_repl , --
154- [' ctrl+ ' ] = M .complete_lua , --
155- [' ctrl+up' ] = M .cycle_history_prev , --
156- [' ctrl+down' ] = M .cycle_history_next , --
157- [' ctrl+p' ] = M .cycle_history_prev , --
158- [' ctrl+n' ] = M .cycle_history_next
153+ [' \n ' ] = M .evaluate_repl , --
154+ [' ctrl+ ' ] = M .complete_lua , --
155+ [' ctrl+up' ] = M .cycle_history_prev , --
156+ [' ctrl+down' ] = M .cycle_history_next , --
157+ [' ctrl+p' ] = M .cycle_history_prev , --
158+ [' ctrl+n' ] = M .cycle_history_next
159159}
160160
161161--- Register REPL keys.
162162local function register_keys ()
163- if not keys .lua [next (M .keys )] then
164- for key , f in pairs (M .keys ) do
165- keys .lua [key ] = function ()
166- if buffer ._type ~= ' [Lua REPL]' then return false end -- propagate
167- f ()
168- end
169- end
170- end
163+ if not keys .lua [next (M .keys )] then
164+ for key , f in pairs (M .keys ) do
165+ keys .lua [key ] = function ()
166+ if buffer ._type ~= ' [Lua REPL]' then return false end -- propagate
167+ f ()
168+ end
169+ end
170+ end
171171end
172172events .connect (events .RESET_AFTER , register_keys )
173173
174174--- Creates or switches to a Lua REPL.
175175-- If *new* is `true`, creates a new REPL even if one already exists.
176176-- @param new Flag that indicates whether or not to create a new REPL even if one already exists.
177177function M .open (new )
178- local repl_view , repl_buf = nil , nil
179- for i = 1 , # _VIEWS do
180- if _VIEWS [i ].buffer ._type == ' [Lua REPL]' then
181- repl_view = _VIEWS [i ]
182- break
183- end
184- end
185- for i = 1 , # _BUFFERS do
186- if _BUFFERS [i ]._type == ' [Lua REPL]' then
187- repl_buf = _BUFFERS [i ]
188- break
189- end
190- end
191- if new or not (repl_view or repl_buf ) then
192- buffer .new ()._type = ' [Lua REPL]'
193- buffer :set_lexer (' lua' )
194- buffer :add_text (' -- ' .. _L [' Lua REPL' ]:gsub (' [_&]' , ' ' ))
195- buffer :new_line ()
196- buffer :set_save_point ()
197- register_keys ()
198- else
199- if repl_view then
200- ui .goto_view (repl_view )
201- else
202- view :goto_buffer (repl_buf )
203- end
204- buffer :document_end () -- in case it's been scrolled in the meantime
205- end
178+ local repl_view , repl_buf = nil , nil
179+ for i = 1 , # _VIEWS do
180+ if _VIEWS [i ].buffer ._type == ' [Lua REPL]' then
181+ repl_view = _VIEWS [i ]
182+ break
183+ end
184+ end
185+ for i = 1 , # _BUFFERS do
186+ if _BUFFERS [i ]._type == ' [Lua REPL]' then
187+ repl_buf = _BUFFERS [i ]
188+ break
189+ end
190+ end
191+ if new or not (repl_view or repl_buf ) then
192+ buffer .new ()._type = ' [Lua REPL]'
193+ buffer :set_lexer (' lua' )
194+ buffer :add_text (' -- ' .. _L [' Lua REPL' ]:gsub (' [_&]' , ' ' ))
195+ buffer :new_line ()
196+ buffer :set_save_point ()
197+ register_keys ()
198+ else
199+ if repl_view then
200+ ui .goto_view (repl_view )
201+ else
202+ view :goto_buffer (repl_buf )
203+ end
204+ buffer :document_end () -- in case it's been scrolled in the meantime
205+ end
206206end
207207
208208-- Add REPL to Tools menu.
0 commit comments