benlubas / molten-nvim

A neovim plugin for interactively running code with the jupyter kernel. Fork of magma-nvim with improvements in image rendering, performance, and more
GNU General Public License v3.0
531 stars 30 forks source link

[Help] Notebook is blank upon opening #231

Closed myrrhkhan closed 3 weeks ago

myrrhkhan commented 3 weeks ago

The issue

I'm trying to open a notebook with molten.nvim, using the setup guide. Only stuff I haven't done is the treesitter stuff at the bottom. However, when I open the notebook, it shows a blank screen (see image). Any idea how to fix the error? Let me know what other stuff is worth providing as well.

Setup + Result

molten.lua

molten.lua ```lua return { "benlubas/molten-nvim", dependencies = { "3rd/image.nvim", "GCBallesteros/jupytext.nvim", "quarto-dev/quarto-nvim", }, build = ":UpdateRemotePlugins", init = function() vim.g.molten_auto_open_output = false vim.g.molten_image_provider = "image.nvim" vim.g.molten_output_win_max_height = 20 vim.g.molten_wrap_output = true vim.g.molten_virt_text_output = true vim.g.molten_virt_lines_off_by_1 = true end, config = function() vim.g.molten_virt_text_output = true -- automatically import output chunks from a jupyter notebook -- tries to find a kernel that matches the kernel in the jupyter notebook -- falls back to a kernel that matches the name of the active venv (if any) local imb = function(e) -- init molten buffer vim.schedule(function() local kernels = vim.fn.MoltenAvailableKernels() local try_kernel_name = function() local metadata = vim.json.decode(io.open(e.file, "r"):read("a"))["metadata"] return metadata.kernelspec.name end local ok, kernel_name = pcall(try_kernel_name) if not ok or not vim.tbl_contains(kernels, kernel_name) then kernel_name = nil local venv = os.getenv("VIRTUAL_ENV") if venv ~= nil then kernel_name = string.match(venv, "/.+/(.+)") end end if kernel_name ~= nil and vim.tbl_contains(kernels, kernel_name) then vim.cmd(("MoltenInit %s"):format(kernel_name)) end vim.cmd("MoltenImportOutput") end) end -- automatically import output chunks from a jupyter notebook vim.api.nvim_create_autocmd("BufAdd", { pattern = { "*.ipynb" }, callback = imb, }) -- we have to do this as well so that we catch files opened like nvim ./hi.ipynb vim.api.nvim_create_autocmd("BufEnter", { pattern = { "*.ipynb" }, callback = function(e) if vim.api.nvim_get_vvar("vim_did_enter") ~= 1 then imb(e) end end, }) -- automatically export output chunks to a jupyter notebook on write vim.api.nvim_create_autocmd("BufWritePost", { pattern = { "*.ipynb" }, callback = function() if require("molten.status").initialized() == "Molten" then vim.cmd("MoltenExportOutput!") end end, }) -- change the configuration when editing a python file vim.api.nvim_create_autocmd("BufEnter", { pattern = "*.py", callback = function(e) if string.match(e.file, ".otter.") then return end if require("molten.status").initialized() == "Molten" then -- this is kinda a hack... vim.fn.MoltenUpdateOption("virt_lines_off_by_1", false) vim.fn.MoltenUpdateOption("virt_text_output", false) else vim.g.molten_virt_lines_off_by_1 = false vim.g.molten_virt_text_output = false end end, }) -- Undo those config changes when we go back to a markdown or quarto file vim.api.nvim_create_autocmd("BufEnter", { pattern = { "*.qmd", "*.md", "*.ipynb" }, callback = function(e) if string.match(e.file, ".otter.") then return end if require("molten.status").initialized() == "Molten" then vim.fn.MoltenUpdateOption("virt_lines_off_by_1", true) vim.fn.MoltenUpdateOption("virt_text_output", true) else vim.g.molten_virt_lines_off_by_1 = true vim.g.molten_virt_text_output = true end end, }) vim.keymap.set("n", "mi", ":MoltenInit", { silent = true, desc = "Initialize the plugin" }) vim.keymap.set( "n", "mr", ":MoltenEvaluateOperator", { silent = true, desc = "run operator selection" } ) vim.keymap.set("n", "mrl", ":MoltenEvaluateLine", { silent = true, desc = "evaluate line" }) vim.keymap.set("n", "mrr", ":MoltenReevaluateCell", { silent = true, desc = "re-evaluate cell" }) vim.keymap.set( "v", "mrv", ":MoltenEvaluateVisualgv", { silent = true, desc = "evaluate visual selection" } ) vim.keymap.set("n", "md", ":MoltenDelete", { silent = true, desc = "molten delete cell" }) vim.keymap.set("n", "mh", ":MoltenHideOutput", { silent = true, desc = "hide output" }) vim.keymap.set( "n", "mo", ":noautocmd MoltenEnterOutput", { silent = true, desc = "show/enter output" } ) vim.keymap.set( "n", "mb", ":MoltenOpenInBrowser", { desc = "open output in browser", silent = true } ) vim.keymap.set("n", "mnc", ":MoltenNext", { silent = true, desc = "molten next cell" }) vim.keymap.set("n", "mpk", ":MoltenPrev", { silent = true, desc = "molten prev cell" }) vim.keymap.set("n", "mr", ":MoltenRestart", { silent = true, desc = "molten restart" }) -- Provide a command to create a blank new Python notebook -- note: the metadata is needed for Jupytext to understand how to parse the notebook. -- if you use another language than Python, you should change it in the template. local default_notebook = [[ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython" }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 5 } ]] local function new_notebook(filename) local path = filename .. ".ipynb" local file = io.open(path, "w") if file then file:write(default_notebook) file:close() vim.cmd("edit " .. path) else print("Error: Could not open new notebook file for writing.") end end vim.api.nvim_create_user_command("NewNotebook", function(opts) new_notebook(opts.args) end, { nargs = 1, complete = "file", }) end, } ```

quarto.lua

quarto.lua ```lua return { { -- requires plugins in lua/plugins/treesitter.lua and lua/plugins/lsp.lua -- for complete functionality (language features) "quarto-dev/quarto-nvim", ft = { "quarto", "markdown" }, dev = false, opts = {}, dependencies = { -- for language features in code cells -- configured in lua/plugins/lsp.lua and -- added as a nvim-cmp source in lua/plugins/completion.lua "jmbuhr/otter.nvim", }, config = function() local quarto = require("quarto") quarto.setup() vim.keymap.set("n", "qp", quarto.quartoPreview, { silent = true, noremap = true }) local runner = require("quarto.runner") vim.keymap.set("n", "nrc", runner.run_cell, { desc = "run cell", silent = true }) vim.keymap.set("n", "nra", runner.run_above, { desc = "run cell and above", silent = true }) vim.keymap.set("n", "nrA", runner.run_all, { desc = "run all cells", silent = true }) vim.keymap.set("n", "nrl", runner.run_line, { desc = "run line", silent = true }) vim.keymap.set("v", "nr", runner.run_range, { desc = "run visual range", silent = true }) vim.keymap.set("n", "nRA", function() runner.run_all(true) end, { desc = "run all cells of all languages", silent = true }) end, }, { -- directly open ipynb files as quarto docuements -- and convert back behind the scenes "GCBallesteros/jupytext.nvim", opts = { -- custom_language_formatting = { -- python = { -- extension = "qmd", -- style = "quarto", -- force_ft = "quarto", -- }, -- r = { -- extension = "qmd", -- style = "quarto", -- force_ft = "quarto", -- }, -- }, }, config = function() require("jupytext").setup({ style = "markdown", output_extension = "md", force_ft = "markdown", }) end, }, { -- send code from python/r/qmd documets to a terminal or REPL -- like ipython, R, bash "jpalardy/vim-slime", dev = false, init = function() vim.b["quarto_is_python_chunk"] = false Quarto_is_in_python_chunk = function() require("otter.tools.functions").is_otter_language_context("python") end vim.cmd([[ let g:slime_dispatch_ipython_pause = 100 function SlimeOverride_EscapeText_quarto(text) call v:lua.Quarto_is_in_python_chunk() if exists('g:slime_python_ipython') && len(split(a:text,"\n")) > 1 && b:quarto_is_python_chunk && !(exists('b:quarto_is_r_mode') && b:quarto_is_r_mode) return ["%cpaste -q\n", g:slime_dispatch_ipython_pause, a:text, "--", "\n"] else if exists('b:quarto_is_r_mode') && b:quarto_is_r_mode && b:quarto_is_python_chunk return [a:text, "\n"] else return [a:text] end end endfunction ]]) vim.g.slime_target = "neovim" vim.g.slime_no_mappings = true vim.g.slime_python_ipython = 1 end, config = function() vim.g.slime_input_pid = false vim.g.slime_suggest_default = true vim.g.slime_menu_config = false vim.g.slime_neovim_ignore_unlisted = true local function mark_terminal() local job_id = vim.b.terminal_job_id vim.print("job_id: " .. job_id) end local function set_terminal() vim.fn.call("slime#config", {}) end vim.keymap.set("n", "cm", mark_terminal, { desc = "[m]ark terminal" }) vim.keymap.set("n", "cs", set_terminal, { desc = "[s]et terminal" }) end, }, { -- paste an image from the clipboard or drag-and-drop "HakonHarnes/img-clip.nvim", event = "BufEnter", ft = { "markdown", "quarto", "latex" }, opts = { default = { dir_path = "img", }, filetypes = { markdown = { url_encode_path = true, template = "![$CURSOR]($FILE_PATH)", drag_and_drop = { download_images = false, }, }, quarto = { url_encode_path = true, template = "![$CURSOR]($FILE_PATH)", drag_and_drop = { download_images = false, }, }, }, }, config = function(_, opts) require("img-clip").setup(opts) vim.keymap.set("n", "ii", ":PasteImage", { desc = "insert [i]mage from clipboard" }) end, }, { -- preview equations "jbyuki/nabla.nvim", keys = { { "qm", ':lua require"nabla".toggle_virt()', desc = "toggle [m]ath equations" }, }, }, } ```

Error

image
benlubas commented 3 weeks ago

command not found: jupytext

you do not have jupytext installed/available in path

myrrhkhan commented 3 weeks ago

Ah, that'll do it, didn't run pip3 install jupytext, shoulda RTFM haha, thanks for the help!