-
-
Notifications
You must be signed in to change notification settings - Fork 167
-
I'm adding support to org-mode code bloc evaluation to my plugin sniprun. (Currently on the dev branch, so the binary has to be compiled locally)
I though you might find it interesting, and maybe, who knows, usable?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 5 comments 14 replies
-
I'm definitely interested! I'll give it a try in following days, and then I'll add it to docs/readme. Thanks!
Beta Was this translation helpful? Give feedback.
All reactions
-
Don't hesitate to submit feeback and request (especially since it's not released yet) !
Beta Was this translation helpful? Give feedback.
All reactions
-
(btw) recently released sniprun v0.5.10 has support for orgmode in stable.
(minus some convenience things having to do with lower/uppercase markers, inline outputing and converting a final return to 'print' that are still in dev)
I don't think I will get down to it with the long and complex OrgMode specification though, like accepting input/arguments... 😅 too much work
Beta Was this translation helpful? Give feedback.
All reactions
-
Hey, sorry for not testing this yet. I got sick so didn't do much work last week. I hope I'll give it a try this week.
Beta Was this translation helpful? Give feedback.
All reactions
-
Haha, no worries, take care of yourself
It's not like I need feedback anyway, my coming here just a freebie for your project if you think sniprun is interesting
Beta Was this translation helpful? Give feedback.
All reactions
-
@michaelb I feel a little dumb, but how do I use this in orgmode? I wasn't able to find any documentation around it, and I tried with this org content:
* TODO Testing
#+BEGIN_SRC lua
print('Test')
#+END_SRC
Tried running :SnipRun
in the block, tried selecting whole block and running visually :'<,'>SnipRun
, tried selecting only the print statement and running visually :'<,'>SnipRun
, but I get Failed to determine language of code bloc
every time.
Beta Was this translation helpful? Give feedback.
All reactions
-
I feel a little dumb
please don't, this kind of failure is definitively due to me not documenting the feature well enough
I think this specific thing is due to the whole thing being indented? (Is this allowed in OrgMode?). Aside from that it should be okay
Beta Was this translation helpful? Give feedback.
All reactions
-
Yeah, removing indentation makes it work. Orgmode allows indentation on these, so you can remove that limitation.
Beta Was this translation helpful? Give feedback.
All reactions
-
Okay, will do :-)
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Works like a charm! Added it to readme to plugins section. Thanks!
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 1
-
@michaelb is it possible to add the org #+RESULTS:
block to the file using the API output?
Beta Was this translation helpful? Give feedback.
All reactions
-
Yes (but).
but: it's not an official feature, and won't be one. The neovim 0.6+ way may be to use virtual lines, however, you may want to have an actual, editable, savable line with the results.
In this case, someone has actually done that; for markdown though. I think you'll have to at least modify the code bloc delimiters ( ``` in markdown): michaelb/sniprun#111 (comment)
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks! That's very useful. I will see if I can tweak it to work with org. I am not yet very familiar with lua but I will give it a try over the holidays.
Beta Was this translation helpful? Give feedback.
All reactions
-
@michaelb I have managed to adapt the script that you shared with me such that it prints the output to the org file. Under the #+Results
affiliated keyword.
Click to check the code
local ok, sa = pcall(require, "sniprun.api") if not ok then error("Snipun not installed") end local M = {} local code_block = {} M.setup = { parse_pattern = { code_opening = [[\v^#\+(BEGIN_SRC|begin_src)]], code_closing = [[\v^#\+(END_SRC|end_src)]], -- #+RESULTS is an affiliated keyword -- it can precede any element, except those listed in the manual -- for now I use a simple regex that should detect the end of a fixed -- delimited block, a table or an unnested block -- https://orgmode.org/worg/dev/org-syntax.html#Affiliated_keywords result_opening = [[\v^#\+(RESULTS|results):]], result_closing = [[^\(\([:|]\|#+END_\).*\)\?\n\([:|]\s\?\)\@!]], }, result_block_name = "#+RESULTS:", } function parse_block (opening, closing) local save_cursor = vim.fn.getpos('.') -- get line number of beginning of code block -- we want to go to the beginning of the block to avoid matching between two blocks local blk_beg_line_nr = vim.fn.search(opening, "bcW") if blk_beg_line_nr == 0 then print("Not in a block") return end -- get line number of closing of code block local blk_end_line_nr = vim.fn.search(closing, "nW") if blk_end_line_nr == 0 then print("Not in a block") return end print(blk_beg_line_nr, blk_end_line_nr) vim.fn.setpos(".", save_cursor) if blk_end_line_nr < save_cursor[2] then print("Not in a block") return end return { blk_beg_line_nr = blk_beg_line_nr, blk_end_line_nr = blk_end_line_nr } end function insert_result (result) result = vim.fn.split(result, "\n") for i = 1, #result do result[i] = ": " .. result[i] end local save_cursor = vim.fn.getpos('.') -- remove existing results if present vim.fn.setpos(".", { 0, code_block.blk_end_line_nr + 1, 1, 0 }) non_empty_line_nr = vim.fn.search([[\S]], "W") result_block = parse_block(M.setup.parse_pattern.result_opening, M.setup.parse_pattern.result_closing) if result_block then vim.fn.deletebufline(vim.fn.bufname(), result_block.blk_beg_line_nr, result_block.blk_end_line_nr) end if vim.fn.getline(code_block.blk_end_line_nr + 1) ~= '' then vim.fn.append(code_block.blk_end_line_nr, '') end vim.fn.append(code_block.blk_end_line_nr + 1, M.setup.result_block_name) if #result > 0 then vim.fn.append(code_block.blk_end_line_nr + 2, result) end if vim.fn.getline(code_block.blk_end_line_nr + 2 + #result + 1) ~= '' then vim.fn.append(code_block.blk_end_line_nr + 2 + #result, '') end vim.fn.setpos(".", save_cursor) code_block = {} end function M.snip_org_run () code_block = parse_block(M.setup.parse_pattern.code_opening, M.setup.parse_pattern.code_closing) if code_block then config_values = require"sniprun".config_values original_display = config_values["display"] original_display[#original_display + 1] = "Api" config_values["display"] = { "Api" } sa.run_range(code_block.blk_beg_line_nr, code_block.blk_end_line_nr, nil, config_values) config_values["display"] = original_display end end function api_listener (d) if d.status == "ok" then insert_result(d.message) elseif d.status == "error" then print("Error: ", d.message) end end sa.register_listener(api_listener) return M
Unfortunately, the API listener is not called when there is a multi-line result. All my attempts were unsuccessful when fixing this problem. Any help to get this fixed would be appreciated.
I think there might be something wrong with the backend because the following return:
:lua require'sniprun.api'.run_string('print(1+2)\nprint(4+5)', 'python', {display = {'Classic'}}) 3 9 Press ENTER or type command to continue
Whereas, the following returns nothing
:lua require'sniprun.api'.run_string('print(1+2)\nprint(4+5)', 'python', {display = {'Api'}})
But, the following returns
:lua require'sniprun.api'.run_string('print(1+2)', 'python', {display = {'Api'}}) Sniprun: No listener registered
Beta Was this translation helpful? Give feedback.
All reactions
-
I'll look into it when I can (rather sooner than later I hope), though it's a bit strange: Sniprun shouldn't even know about the number of lines in the output...
With some luck it'll be a trivial corner case, as this part clearly lack decent testing
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2
-
Well it's been a while and I (presumably) didn't receive notifications for all this time.
It appears the issue described about multi-line output in Api has been solved, and your script works quite well for the (quite simple) cases I can think of.
I intentionnally let some leeway to things I may not find 'natural' (errors displayed only in the command area, or printing the range of the results when ok, for example) but that probably match your design decisions.
We can probably mark this discussion as 'solved'
Beta Was this translation helpful? Give feedback.
All reactions
-
That's awesome! It was worth the wait. I can confirm that the basic examples I set up are working perfectly. It's now my turn to polish the script a bit to add more babel-like functionalities to org in neovim. Btw, what was causing the problem?
Beta Was this translation helpful? Give feedback.
All reactions
-
well actually I haven't the slightest clue.
I probably half-fixed (read: broke) this just after we last exchanged messages, and then a user probably opened an issue and I finished (fixed) it, but forgot to report back
About mutli-lines output breaking the API, I'd bet my money on bad escaping (of newline characters), since it rings a bell from a few month ago, and that would explain how even the lua code broke.
Though, I also opened this discussion at the very moment sniprun supported orgmode, and there have been countless occasions to polish/bugfix both orgmode support and sniprun itself since then, so these various improvements might also have helped.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks for the explanation! Bad escaping easily sneaks in the wrong places.
Beta Was this translation helpful? Give feedback.