1- *assistant.nvim*
2- ==============================================================================
1+ ================================================================================
2+ INTRODUCTION *assistant.nvim*
33
4- A modern Neovim testing manager for competitive programmers. It comes with
5- various basic and advanced features that automate the testing workflow .
4+ Assistant.nvim is a modern neovim plugin for automating testing workflow for
5+ competitive programmers .
66
7- *assistant.nvim-installation*
8- ==============================================================================
7+ Getting started with assistant:
8+ 1. Run `:checkhealth assistant` to make sure is setup correctly.
9+ 2. Run `:Assistant` to launch plugin user interface.
910
10- Using | lazy.nvim | plugin manager:
11+ Explore | assistant.config | to customize assistant.
1112
12- >lua
13- {
14- "A7Lavinraj/assistant.nvim",
15- lazy = false, -- Start TCP listener on Neovim startup
16- keys = {
17- { "<leader> a", "<cmd> Assistant<cr> ", desc = "Assistant.nvim" }
18- },
19- opts = {} -- Config options
20- }
21- <
22-
23- *assistant.nvim-default-options*
24- ===============================================================================
2513
26- | assistant.nvim | comes with default options as follows:
14+ ================================================================================
15+ CONFIGURATION *assistant.config*
2716
17+ You can pass custom configuration to change assisant behaviour. Following are
18+ the default configuration for reference
2819>lua
29- {
30- mappings = { ... },
20+ local default = {
3121 commands = {
3222 python = {
33- extension = "py",
34- template = nil,
23+ extension = 'py' ,
3524 compile = nil,
3625 execute = {
37- main = " python3" ,
38- args = { " $FILENAME_WITH_EXTENSION" },
26+ main = ' python3' ,
27+ args = { ' $FILENAME_WITH_EXTENSION' },
3928 },
4029 },
4130 cpp = {
42- extension = "cpp",
43- template = nil,
31+ extension = 'cpp' ,
4432 compile = {
45- main = " g++" ,
46- args = { " $FILENAME_WITH_EXTENSION", "-o", " $FILENAME_WITHOUT_EXTENSION" },
33+ main = ' g++' ,
34+ args = { ' $FILENAME_WITH_EXTENSION', '-o', ' $FILENAME_WITHOUT_EXTENSION' },
4735 },
4836 execute = {
49- main = " ./$FILENAME_WITHOUT_EXTENSION" ,
37+ main = ' ./$FILENAME_WITHOUT_EXTENSION' ,
5038 args = nil,
5139 },
5240 },
5341 },
5442 ui = {
55- border = "rounded",
43+ diff_mode = false,
44+ border = 'rounded' ,
5645 },
5746 core = {
5847 process_budget = 5000,
@@ -61,4 +50,267 @@ Using |lazy.nvim| plugin manager:
6150 }
6251<
6352
53+ 1. An example to change default `port` on which assistant listen for browser:
54+ >lua
55+ require('assistant' ).setup({
56+ core = {
57+ port = 8000
58+ }
59+ })
60+ <
61+
62+ 2. An example to change default mappings for panel:
63+ >lua
64+ local actions = require('assistant.actions')
65+ require('assistant' ).setup({
66+ mappings = {
67+ panel = {
68+ n = {
69+ ['m'] = actions.toggle_cur_selection
70+ }
71+ }
72+ }
73+ })
74+ <
75+
76+ ================================================================================
77+ TCP SERVER *assistant.tcp*
78+
79+ It is a wrapper module which maintain a single tcp connection with browser. If
80+ more than one neovim instance are running at same time, then only latest neovim
81+ instance will get connected to browser.
82+
83+
84+ ================================================================================
85+ WIZARD *assistant.wizard*
86+
87+ Wizard is a plugin launcher which consists of following two core
88+ components:
89+ 1. | assistant.panel |
90+ 2. | assistant.previewer |
91+
92+ ┌───────────────────────────────┐┌───────────────────────────────────────┐
93+ │ ││ │
94+ │ ││ │
95+ │ ││ │
96+ │ ││ │
97+ │ (Panel) ││ (Previewer) │
98+ │ ││ │
99+ │ ││ │
100+ │ ││ │
101+ │ ││ │
102+ └───────────────────────────────┘└───────────────────────────────────────┘
103+
104+ Example of creating a wizard instance:
105+
106+ >lua
107+ require('assistant.lib.wizard').new({
108+ width = 0.85, -- width with respect to vim.o.columns
109+ height = 0.65, -- height with respect to vim.o.lines
110+ panel = require('assistant.lib.panel').new {
111+ -- custom panel options
112+ },
113+ previewer = require('assistant.lib.previewer').new {
114+ -- custom previewer options
115+ }
116+ }):show() -- launch the wizard with provided `panel` and `previewer`
117+ <
118+
119+
120+ ================================================================================
121+ PANEL *assistant.panel*
122+
123+ Panel is a core component of | assistant.wizard | which manages overview of
124+ available testcases, Below is an example of creating a simple panel:
125+ >lua
126+ require('assistant.lib.panel').new {
127+ canvas = require('assistant.lib.canvas').new {
128+ fn = function(bufnr)
129+ -- canvas.set function
130+ end,
131+ gn = function(bufnr, winid)
132+ -- canvas.get function
133+ end
134+ }
135+ }
136+ <
137+
138+ Panel takes an | assistant.canvas | which consists of two functions:
139+ 1. `setter` renders testcases in your defined format.
140+ 1. `getter` returns testcase ID on which cursor is currently holding on.
141+
142+ `getter` is optional while creating canvas but mandatory in case of panel.
143+
144+
145+ ================================================================================
146+ PREVIEWER *assistant.previewer*
147+
148+ Previewer is a core component of | assistant.wizard | which manages details of a
149+ testcase corresponding to the `testcase ID` provided by | assistant.panel | .
150+
151+ Example of creating previewer:
152+ >lua
153+ require('assistant.lib.previewer').new {
154+ canvas = require('assistant.lib.previewer').new {
155+ fn = function(bufnr, testcase)
156+ -- canvas.set function
157+ end,
158+ }
159+ }
160+ <
161+
162+ Previewer takes an | assistant.canvas | which consists of only one `setter`
163+ function which renders testcase details in your defined format. Unlike
164+ | assistant.panel | , | assistant.previewer | doesn't need any getter because there
165+ is nothing to be query from the previewer yet.
166+
167+
168+ ================================================================================
169+ CANVAS *assistant.canvas*
170+
171+ Canvas module handle two things:
172+ 1. Displays provided data in the corresponding buffers.
173+ 2. Query results from the same buffer where it displays data.
174+
175+ Exmaple of canvas for | assistant.panel | :
176+ >lua
177+ require('assistant.lib.canvas').new {
178+ fn = function(bufnr, testcases)
179+ local text = require('assistant.lib.text').new {}
180+ local gap = 5
181+ local get_group = setmetatable({ AC = 'AssistantSuccess', WA = 'AssistantFailure' }, {
182+ __index = function()
183+ return 'AssistantWarning'
184+ end,
185+ })
186+
187+ for i, testcase in ipairs(testcases or {}) do
188+ if testcase.selected then
189+ text:append(' ', 'AssistantFailure')
190+ else
191+ text:append(' ', 'AssistantParagraph')
192+ end
193+
194+ text:append(string.format('Testcase #%d', i), 'AssistantParagraph')
195+ text:append(string.rep(' ', gap), 'AssistantParagraph')
196+
197+ if testcase.status then
198+ text:append(testcase.status or 'UNKNOWN', get_group[testcase.status])
199+ end
200+
201+ text:append(string.rep(' ', gap), 'AssistantParagraph')
202+ if testcase.time_taken then
203+ text:append(string.format('%.3f', testcase.time_taken or 0), 'AssistantParagraph')
204+ end
205+
206+ if i < #testcases then
207+ text:nl()
208+ end
209+ end
210+
211+ text:render(bufnr)
212+ end,
213+ gn = function(bufnr, winid)
214+ if not (bufnr and vim.api.nvim_buf_is_valid(bufnr)) then
215+ return nil
216+ end
217+ local cursor_position = vim.api.nvim_win_get_cursor(winid)
218+ local current_line = vim.api.nvim_buf_get_lines(bufnr, cursor_position[1] - 1, cursor_position[1], false)
219+ return tonumber(current_line[1]:match '^%s*.+%s*Testcase #(%d+)')
220+ end,
221+ }
222+ <
223+
224+ Example of canvas for | assistant.previewer | :
225+ >lua
226+ require('assistant.lib.canvas').new {
227+ fn = function(bufnr, testcase)
228+ local utils = require 'assistant.utils'
229+ local text = require('assistant.lib.text').new {}
230+
231+ if testcase.input and #testcase.input ~= 0 then
232+ text:append('Input', 'AssistantHeading'):nl(2)
233+
234+ for _, line in ipairs(utils.slice_first_n_lines(testcase.input or '', 100)) do
235+ if line then
236+ text:append(line, 'AssistantParagraph'):nl()
237+ end
238+ end
239+
240+ text:nl()
241+ local _, cnt = string.gsub(testcase.input or '', '\n', '')
242+
243+ if cnt > 100 then
244+ text:append('-- REACHED MAXIMUM RENDER LIMIT --', 'AssistantFailure')
245+ end
246+ end
247+
248+ if testcase.output and #testcase.output ~= 0 then
249+ text:append('Expect', 'AssistantHeading'):nl(2)
250+
251+ for _, line in ipairs(utils.slice_first_n_lines(testcase.output or '', 100)) do
252+ if line then
253+ text:append(line, 'AssistantParagraph'):nl()
254+ end
255+ end
256+
257+ text:nl()
258+ local _, cnt = string.gsub(testcase.output or '', '\n', '')
259+
260+ if cnt > 100 then
261+ text:append('-- REACHED MAXIMUM RENDER LIMIT --', 'AssistantFailure')
262+ end
263+ end
264+
265+ if testcase.stdout and #testcase.stdout ~= 0 then
266+ text:append('Stdout', 'AssistantHeading'):nl(2)
267+
268+ if require('assistant.config').values.ui.diff_mode then
269+ for _, line in
270+ ipairs(require('assistant.algos.diff').get_higlighted_text(testcase.output, testcase.stdout))
271+ do
272+ if vim.tbl_isempty(line or {}) then
273+ text:nl()
274+ else
275+ text:append(line.str, line.hl)
276+ end
277+ end
278+ else
279+ for _, line in ipairs(utils.slice_first_n_lines(testcase.stdout, 100)) do
280+ if line then
281+ text:append(line, 'AssistantParagraph'):nl()
282+ end
283+ end
284+
285+ text:nl()
286+ local _, cnt = string.gsub(testcase.stdout or '', '\n', '')
287+
288+ if cnt > 100 then
289+ text:append('-- REACHED MAXIMUM RENDER LIMIT --', 'AssistantFailure')
290+ end
291+ end
292+ end
293+
294+ if testcase.stderr and #testcase.stderr ~= 0 then
295+ text:nl():append('Stderr', 'AssistantHeading'):nl(2)
296+
297+ for _, line in ipairs(utils.slice_first_n_lines(testcase.stderr, 100)) do
298+ if line then
299+ text:append(line, 'AssistantParagraph'):nl()
300+ end
301+ end
302+
303+ text:nl()
304+ local _, cnt = string.gsub(testcase.stderr or '', '\n', '')
305+
306+ if cnt > 100 then
307+ text:append('-- REACHED MAXIMUM RENDER LIMIT --', 'AssistantFailure')
308+ end
309+ end
310+
311+ text:render(bufnr)
312+ end,
313+ }
314+ <
315+
64316 vim:tw=78:ts=8:ft=help:norl:
0 commit comments