-
-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to configure the markdown interpreter? #111
Comments
Hi! About the first thing, that's currently not possible. (The association filetype<=>interpeters is hardcoded, and though you would probably be able to modify sniprun to handle that, it's cumbersome etc...) Making allowing sniprun to understand that markdown.pandoc == markdown was a feature that crossed my mind but i never implemented it. It shouldn't be too hard though, I'll give it a look soon, and push v1.0.3 About your second question, you can use sniprun inside a code block, but it will only run your visual selection (or the current line if none). There's a doc at
(Github flavored markdown) that explains the designed behavior |
@michaelb, thanks for the reply. I hope you will give executing code blocks in markdown some priority. This is probably one of the features I want yearn from emac's org-mode so much. I find the idea of documenting code with markdown blocks really appealing. Of course, this could be done with comments, but markdown gives you more options. I have actually written a small script that can run inside a markdown code block, and either display the result in the command line or paste it underneath the code block. At the moment, there's no caching of variables or the displaying the results inline, as you're doing. I'd have to look at your code to see how to do it. |
What do you mean ? executing code bloc in markdown already works What doesn't work for sure is executing code in a markdown.pandoc file, which is what i'll try to fix. Could you explain what is the issue exactly ? (desired/expected vs actual behavior?) Nota bene:
'caching of variables' is only available for REPL-enabled languages (see
There are other display options if you want to :-) |
v1.0.3 is up, there is an example in the readme (configuration section) that should help you adjust your configuration) :-) |
@michaelb, thanks for fixing it. It now works! I feel there's one small thing left that I wonder if you'd be able to add to the plugin. In org-mode, there's the ability to display the result of the code block in a block underneath the code block you're executing. For example: a = 1
b = 2
print(a+b) Executing the above code block produces the code block below:
|
I'm not able to do that cleanly enough that i'd be ok to integrate with sniprun. IMO, inserting real text into a buffer is too error-prone HOWEVER, it may be possible to do it yourself: there are two options:
|
If it's not too much to ask, can you provide an example of how to capture the output from the display api? |
There is a link in the readme (API in display options) to the file ressources/api.md that contains such an example |
@medwatt I got a mail with some questions about a bug (displaying n-times the result when using the API), but I can't seem to find the corresponding comment here. Did you delete it ? / did you fix your issue (if so could you share your solution)? |
@michaelb, the code I came up with is given below. It seems to work fine. Maybe, you can improve upon it if you see fit. There are two minor issues I noticed:
local present, sa = pcall(require, 'sniprun.api')
if not present then
print("Warning: Snipun not installed")
end
local fn = vim.fn
local result = {}
local M = {}
M.setup = {
parse_pattern = {
opening = [[\v^\s{-}```\s{-}%(\{\.)?\zs(\w+)]],
closing = [[\v^\s{-}```]],
},
result_block_name = 'RESULTS',
runners = {
python = 'python3',
},
}
-- use language name for language runner
setmetatable(M.setup.runners, {__index = function (_, k) return k end})
local function ParseBlock()
-- get line number of beginning of code block
local blk_beg_line_nr = fn.search(M.setup.parse_pattern.opening, 'bnW')
if blk_beg_line_nr == 0 then
print('Not in a Markdown code block')
return
end
-- get line number of closing of code block
local blk_end_line_nr = fn.search(M.setup.parse_pattern.closing, 'nW')
if blk_end_line_nr == 0 then
print('Not in a Markdown code block')
return
end
-- check if block is empty
local src = fn.getline(blk_beg_line_nr + 1, blk_end_line_nr - 1)
local count = 0
for i, line in ipairs(src) do
if not line:find('^[%s]*$') then break end
count = i
end
if count == #src then print("Code block is empty") return end
-- get indentation level of code block
local col_num = fn.match(fn.getline(blk_beg_line_nr), '```')
-- remove indentation
if col_num > 0 then
for i, line in ipairs(src) do
src[i] = line:sub(col_num + 1)
end
end
-- get block language
local language = fn.matchstr(fn.getline(blk_beg_line_nr), M.setup.parse_pattern.opening)
result = {
src = src,
language = language,
blk_beg_line_nr = blk_beg_line_nr,
blk_end_line_nr = blk_end_line_nr,
col_num = col_num,
}
return result
end
local function InsertResult(message)
message = fn.split(message, '\n')
if #message > 0 then
local save_cursor = fn.getpos('.')
-- remove existing results if present
if fn.match(fn.getline(result.blk_end_line_nr + 2), '```' .. M.setup.result_block_name) >= 0 then
fn.cursor(result.blk_end_line_nr + 3, 0)
local end_result_block_line = fn.search('```', 'cW')
if end_result_block_line then
if fn.getline(end_result_block_line + 1) == '' then
fn.deletebufline(fn.bufname('%'), result.blk_end_line_nr + 2, end_result_block_line + 1)
else
fn.deletebufline(fn.bufname('%'), result.blk_end_line_nr + 2, end_result_block_line)
end
end
end
-- add result in a block
fn.append(result.blk_end_line_nr, '')
fn.append(result.blk_end_line_nr + 1, '```' .. M.setup.result_block_name)
fn.append(result.blk_end_line_nr + 2, message)
fn.append(result.blk_end_line_nr + 2 + #message, '```')
-- indent the result block correctly
local line_indent = fn.indent(result.blk_beg_line_nr)
if line_indent > 0 then
local norm_cmd = string.format("%s,%snormal! >>", result.blk_end_line_nr + 1, result.blk_end_line_nr + #message + 3)
for _=1, math.floor(line_indent / vim.bo.tabstop) do
vim.cmd(norm_cmd)
end
end
-- restore the cursor position
fn.setpos('.', save_cursor)
else
print("Block ran successfully")
end
result = {}
end
function M.RunCodeBlock()
result = ParseBlock()
local lang_runner = M.setup.runners[result.language]
local message = fn.system(lang_runner, result.src)
InsertResult(message)
end
if present then
function M.RunCodeBlockSnipRun()
result = ParseBlock()
sa.run_range(result.blk_beg_line_nr+1, result.blk_end_line_nr-1, result.language)
end
local function api_listener(d)
if d.status == 'ok' then
InsertResult(d.message)
elseif d.status == 'error' then
print("Error: ", d.message)
end
end
sa.register_listener(api_listener)
end
return M |
Thanks!
I noticed that as well for some python interpreters / matplotlib figures, it was quirky enough getting those to work at all😅. Putting plt.show() twice is obviously not a good solution, but maybe using a different python intepreter would solve this issue? I'll investigate your issue n°3 but I would be surprised if I were able to find the root issue and fix it. Well done anyway!! |
I was looking for a way to run code blocks in markdown and came upon this plugin. It didn't run at first. It turns out that was because I was using markdown syntax file that requires the markdown filetype to change to markdown.pandoc. Changing the file type back to markdown works.
My first question is, how do I make sniprun work when the filetype is changed to markdown.pandoc.
My section question is why can't I put the cursor anywhere inside the code block and have the code block evaluated?
The text was updated successfully, but these errors were encountered: