Git Product home page Git Product logo

molten-nvim's Introduction

Molten

Molten is a fork of Magma, a plugin for running code interactively with the jupyter kernel. Molten provides an excellent repl-like experience, and an incredible notebook-like experience in neovim.

Molten.Demo.mp4

Feature Highlights

  • Send code to run asynchronously in the jupyter kernel
  • See output below the code in real time, without flicker, as virtual text or in a floating window (or both)
  • Renders images, plots, and LaTeX in neovim
  • Take input from stdin with vim.ui.input
  • Send code from multiple buffers to the same kernel
  • Send code from the same buffer to multiple kernels
  • Supports any language with a Jupyter Kernel (in theory, they haven't all been tested)
  • Python virtual environment support
  • Import and Export outputs to and from jupyter notebook files

Requirements

  • NeoVim 9.4+
  • Python 3.10+
  • image.nvim is only required for the image.nvim image provider
  • wezterm.nvim is only required for the wezterm image provider
  • Required Python packages (can be installed in a venv. read more):
  • Optional Python packages:
    • cairosvg (for displaying SVG images with transparency)
      • If you don't need transparency, image.nvim can render svg images perfectly fine
    • pnglatex (for displaying TeX formulas)
    • plotly and kaleido (for displaying Plotly figures)
    • pyperclip if you want to use molten_copy_output
    • nbformat for importing and exporting output to jupyter notebooks files
    • pillow for opening images with :MoltenImagePopup

You can run :checkhealth to see what you have installed.

Note: Optional python packages are only imported when they're used.

Quick-start

Configuration information is located further down in this README.

To setup molten for editing Jupyter Notebook files, see Notebook Setup.

Usage

Start by initializing a kernel. This kernel will get a kernel_id which is most commonly just the name of the kernel. If you try to initialize two kernels with the same name, the second one will be named kernel_name_n where n is the total number of kernels that are already initialized.

You execute code by sending it to a kernel, specified by its kernel_id (this is handled automatically if there is only one option).

When you execute some code, it will create a cell. You can recognize a cell because it will be highlighted when your cursor is in it.

A cell is delimited using two extmarks (see :h api-extended-marks), so each cell will adjust when editing text within its boundaries.

When your cursor is in a cell (i.e., you have an active cell), a floating window may be shown below the cell, reporting output. This is the floating output window. (To see more about whether a window is shown or not, see :MoltenShowOutput and g:molten_auto_open_output). When you cursor is not in any cell, no cell is active. When your cursor leaves a cell, its floating output window will close.

Output may also be displayed as virtual text below a cell. Virtual text output will stay there until you re-run the cell or delete the cell.

Overlapping cells are not allowed. If you create an overlapping cell, the old cell will be deleted.

The output window has a header, containing the execution count and execution state (i.e., whether the cell is waiting to be run, running, has finished successfully or has finished with an error). Below the header, output is shown.

Jupyter provides a rich set of outputs. To see what we can currently handle, see Output Chunks.

Commands

These user commands are the main interface to the plugin. It is recommended to map most of them to keys, as explained in Keybindings.

Here is a list of the commands and their arguments. Args in [] are optional, args in "" are literal.

When the kernel argument is specified as optional the command behaves in the following way:

  • if the kernel is specified, send the code to that kernel
  • else if there is only one active kernel for the current buffer, send the code to that kernel
  • else if there is more than one active kernel for the current buffer, prompt the user for the kernel

Some commands will prompt for a kernel when they require one, but no kernel is attached to the buffer. This is configurable with the molten_auto_init_behavior option.

Command Arguments Description
MoltenInfo none Show information about the state of the plugin, initialization status, available kernels, and running kernels
MoltenInit ["shared"] [kernel] Initialize a kernel for the current buffer. If shared is passed as the first value, this buffer will use an already running kernel. If no kernel is given, prompts the user.
MoltenDeinit none De-initialize the current buffer's runtime and molten instance. (called automatically on vim close/buffer unload)
MoltenGoto [n] Go to the nth code cell n defaults to 1 (1 indexed)
MoltenNext [n] Go to the next code cell, or jump n code cells n defaults to 1. Values wrap. Negative values move backwards
MoltenPrev [n] like Next but backwards
MoltenEvaluateLine [kernel] Evaluate the current line
MoltenEvaluateVisual [kernel] Evaluate the visual selection (cannot be called with a range!)
MoltenEvaluateOperator [kernel] Evaluate text selected by the following operator. see Keybindings for useage
MoltenEvaluateArgument [kernel] code Evaluate given code in the given kernel
MoltenReevaluateCell none Re-evaluate the active cell (including new code) with the same kernel that it was originally evaluated with
MoltenDelete none Delete the active cell (does nothing if there is no active cell)
MoltenShowOutput none Shows the output window for the active cell
MoltenHideOutput none Hide currently open output window
MoltenEnterOutput none Move into the active cell's output window. Opens but does not enter the output if it's not open. must be called with noautocmd (see Keybindings for example)
MoltenInterrupt [kernel] Sends a keyboard interrupt to the kernel which stops any currently running code. (does nothing if there's no current output)
MoltenOpenInBrowser none Open the current output in the browser. Currently this only supports cells with 'text/html' outputs, configured with molten_auto_open_html_in_browser and molten_open_cmd
MoltenImagePopup none Open an image from the current output with python's Image.show(). This will use your system's default image viewer, this behavior can happen automatically (see: molten_auto_image_popup)
MoltenRestart [!] [kernel] Shuts down a restarts the kernel. Deletes all outputs if used with a bang
MoltenSave [path] [kernel] Save the current cells and evaluated outputs into a JSON file. When path is specified, save the file to path, otherwise save to g:molten_save_path. currently only saves one kernel per file
MoltenLoad ["shared"] [path] Loads cell locations and output from a JSON file generated by MoltenSave. path functions the same as MoltenSave. If shared is specified, the buffer shares an already running kernel.
MoltenExportOutput [!] [path] [kernel] Export outputs from the current buffer and kernel to a jupyter notebook (.ipynb) at the given path. read more
MoltenImportOutput [path] [kernel] Import outputs from a jupyter notebook (.ipynb). read more

Keybindings

The commands above should be mapped to keys for the best experience.

Pay attention to MoltenEvaluateVisual and MoltenEnterOutput, as they need to be run in...odd ways.

Minimum Suggested

vim.keymap.set("n", "<localleader>mi", ":MoltenInit<CR>",
    { silent = true, desc = "Initialize the plugin" })
vim.keymap.set("n", "<localleader>e", ":MoltenEvaluateOperator<CR>",
    { silent = true, desc = "run operator selection" })
vim.keymap.set("n", "<localleader>rl", ":MoltenEvaluateLine<CR>",
    { silent = true, desc = "evaluate line" })
vim.keymap.set("n", "<localleader>rr", ":MoltenReevaluateCell<CR>",
    { silent = true, desc = "re-evaluate cell" })
vim.keymap.set("v", "<localleader>r", ":<C-u>MoltenEvaluateVisual<CR>gv",
    { silent = true, desc = "evaluate visual selection" })

Other example mappings

vim.keymap.set("n", "<localleader>rd", ":MoltenDelete<CR>",
    { silent = true, desc = "molten delete cell" })
vim.keymap.set("n", "<localleader>oh", ":MoltenHideOutput<CR>",
    { silent = true, desc = "hide output" })
vim.keymap.set("n", "<localleader>os", ":noautocmd MoltenEnterOutput<CR>",
    { silent = true, desc = "show/enter output" })

Configuration

Configuration is done with variables. Below you'll find a table of all the potential configuration variable, their values, and a brief description.

the default value is wrapped in ()

Variable Values Description
g:molten_auto_image_popup true | (false) When true, cells that produce an image output will open the image output automatically with python's Image.show()
g:molten_auto_init_behavior "raise" | ("init") When set to "raise" commands which would otherwise ask for a kernel when they're run without a running kernel will instead raise an exception. Useful for other plugins that want to use pcall and do their own error handling
g:molten_auto_open_html_in_browser true | (false) Automatically open HTML outputs in a browser. related: molten_open_cmd
g:molten_auto_open_output (true) | false Automatically open the floating output window when your cursor moves into a cell
g:molten_cover_empty_lines true | (false) The output window and virtual text will be shown just below the last line of code in the cell.
g:molten_cover_lines_starting_with ({}) | array of str When cover_empty_lines is true, also covers lines starting with these strings
g:molten_copy_output true | (false) Copy evaluation output to clipboard automatically (requires pyperclip)
g:molten_enter_output_behavior ("open_then_enter") | "open_and_enter" | "no_open" The behavior of MoltenEnterOutput
g:molten_image_provider ("none") | "image.nvim" | "wezterm" | How images are displayed see Images for more details
g:molten_open_cmd (nil) | Any command Defaults to xdg-open on Linux, open on Darwin, and start on Windows. But you can override it to whatever you want. The command is called like: subprocess.run([open_cmd, filepath])
g:molten_output_crop_border (true) | false 'crops' the bottom border of the output window when it would otherwise just sit at the bottom of the screen
g:molten_output_show_exec_time (true) | false Shows the current amount of time since the cell has begun execution
g:molten_output_show_more true | (false) When the window can't display the entire contents of the output buffer, shows the number of extra lines in the window footer (requires nvim 10.0+ and a window border)
g:molten_output_virt_lines true | (false) Pad the main buffer with virtual lines so the floating window doesn't cover anything while it's open
g:molten_output_win_border ({ "", "โ”", "", "" }) | any value for border in :h nvim_open_win() Some border features will not work if you don't specify your border as a table. see border option of :h nvim_open_win()
g:molten_output_win_cover_gutter (true) | false Should the output window cover the gutter (numbers and sign col), or not. If you change this, you probably also want to change molten_output_win_style
g:molten_output_win_hide_on_leave (true) | false After leaving the output window (via :q or switching windows), do not attempt to redraw the output window
g:molten_output_win_max_height (999999) | int Max height of the output window
g:molten_output_win_max_width (999999) | int Max width of the output window
g:molten_output_win_style (false) | "minimal" Value passed to the style option in :h nvim_open_win()
g:molten_save_path (stdpath("data").."/molten") | any path to a folder Where to save/load data with :MoltenSave and :MoltenLoad
g:molten_split_direction ("right") | "left" | "top" | "bottom" | Direction of the terminal split created by wezterm. Only applies if g:molten_image_provider = "wezterm"
g:molten_split_size (40) | int (0-100) % size of the screen dedicated to the output window. Only applies if g:molten_image_provider = "wezterm"
g:molten_tick_rate (500) | int How often (in ms) we poll the kernel for updates. Determines how quickly the ui will update, if you want a snappier experience, you can set this to 150 or 200
g:molten_use_border_highlights true | (false) When true, uses different highlights for output border depending on the state of the cell (running, done, error). see highlights
g:molten_limit_output_chars (1000000) | int Limit on the number of chars in an output. If you're lagging your editor with too much output text, decrease it
g:molten_virt_lines_off_by_1 true | (false) Allows the output window to cover exactly one line of the regular buffer when output_virt_lines is true, also effects where virt_text_output is displayed. (useful for running code in a markdown file where that covered line will just be ```)
g:molten_virt_text_output true | (false) When true, show output as virtual text below the cell, virtual text stays after leaving the cell. When true, output window doesn't open automatically on run. Effected by virt_lines_off_by_1
g:molten_virt_text_max_lines (12) | int Max height of the virtual text
g:molten_wrap_output true | (false) Wrap output text
[DEBUG] g:molten_show_mimetype_debug true | (false) Before any non-iostream output chunk, the mime-type for that output chunk is shown. Meant for debugging/plugin devlopment

Images

Molten has two image providers, image.nvim or wezterm:

  • image.nvim requires the image.nvim plugin (and it's dependencies). It renders images in neovim inline with other cell output. This creates a better experience, but it can be buggy with large numbers of images, and it does not work on Windows.

  • wezterm requires the wezterm.nvim plugin (and the wezterm terminal emulator). It renders images in a wezterm split pane using wezterm's imgcat program. This method is significantly less buggy with large numbers of images and works on Windows, but it doesn't keep images next to the code they came from.

    • Cannot be used with g:molten_auto_open_output = true
    • Configurable with the g:molten_split_direction and g:molten_split_size options.
    • Currently, the wezterm image provider does not integrate with tmux. There are issues with allowing images to passing through tmux to wezterm. If you are using tmux, you will need to use the image.nvim image provider.

Status Line

Molten provides a few functions that you can use to see information in your status line. These are listed below:

require('molten.status').initialized() -- "Molten" or "" based on initialization information
require('molten.status').kernels() -- "kernel1 kernel2" list of kernels attached to buffer or ""
require('molten.status').all_kernels() -- same as kernels, but will show all kernels

The way these are used will vary based on status line plugin. So please refer to your status line plugin to figure out how to use them.

Highlights

You can change highlights like so:

-- see :h nvim_set_hl for what to put in place of ...
-- I would recommend using the `link` option to link the values to colors from your color scheme
vim.api.nvim_set_hl(0, "MoltenOutputBorder", { ... })

Here is a complete list of the highlight groups that Molten uses, and their default values

  • MoltenOutputBorder = FloatBorder: default output window border
  • MoltenOutputBorderFail = MoltenOutputBorder: border of a failed output window
  • MoltenOutputBorderSuccess = MoltenOutputBorder: border of a successfully run output window
  • MoltenOutputWin = NormalFloat: the innards of the output window
  • MoltenOutputWinNC = MoltenOutputWin: a "Non-Current" output window
  • MoltenOutputFooter = FloatFooter: the "x more lines" text
  • MoltenCell = CursorLine: applied to code that makes up a cell
  • MoltenVirtualText = Comment: output that is rendered as virtual text

Autocommands

We provide some User autocommands (see :help User) for further customization. They are:

  • MoltenInitPre: runs right before MoltenInit initialization happens for a buffer
  • MoltenInitPost: runs right after MoltenInit initialization happens for a buffer
  • MoltenDeinitPre: runs right before MoltenDeinit de-initialization happens for a buffer
  • MoltenDeinitPost: runs right after MoltenDeinit de-initialization happens for a buffer
  • MoltenKernelReady: runs when a kernel is ready for the first time. data field has the kernel_id
Lua Usage

Here is an example of attaching molten specific mappings to the buffer after initialization:

vim.api.nvim_create_autocmd("User", {
  pattern = "MoltenInitPost",
  callback = function()
    vim.keymap.set("v", "<localleader>r", ":<C-u>MoltenEvaluateVisual<CR>gv",
      { desc = "execute visual selection", buffer = true, silent = true })
    -- ... more mappings
  end,
})

Similarly, you could remove these mappings on MoltenDeinitPost


For MoltenKernelReady you can get the kernel id like this:

-- ...
  callback = function(e)
    print("Kernel id: " .. e.data.kernel_id)
  end
-- ...

Functions

Molten exposes some functionality through vim functions. These are mostly for plugin authors and people who want some custom behavior.

MoltenEvaluateRange

MoltenEvaluateRange(start_line, end_line, [start_col, end_col]) - evaluates the code between the given line numbers and column numbers.

  • ranges are inclusive and the indexing 1 based
  • columns are optional, when omitted the entire line is captured
  • passing -1 for end_col will use the last col on the line
  • passing 0 for all other positions will use the last line/col
  • The values are used to create extmarks, and the strict option is set to false. See :h nvim_buf_set_extmark() and then options > strict. This means passing 10 when there are only 5 lines in the buffer does result in an error.
-- run lines 1 through 23 (inclusive):
vim.fn.MoltenEvaluateRange(1, 23)

-- run code starting with col 4 on line 1, and ending with the last col on line 3
vim.fn.MoltenEvaluateRange(1, 3, 4, -1)

Additionally, this function can take a kernel_id as the first argument. When a string is given as the first argument, it's assumed to be a kernel_id.

-- run lines 1 through 23 (inclusive) with the python3 kernel
vim.fn.MoltenEvaluateRange("python3", 1, 23)

-- run code starting with col 4 on line 1, and ending with col 20 on line 3 with the R kernel
vim.fn.MoltenEvaluateRange("ir", 1, 3, 4, 20)

When there are multiple kernels attached to the buffer, and this function is called without a kernel_id, the user will be prompted for a kernel with vim.ui.select

MoltenUpdateOption

Because Molten is a remote plugin, options are loaded and cached at initialization. This avoids making an unnecessary number of RPC calls if we were to fetch configuration values every time we needed to use them. This comes with the trade-off of not being able to update config values on the fly... can you see where this is going.

This function lets you update a configuration value after initialization, and the new value will take effect immediately.

You can specify option names with or without the "molten" prefix.

-- these are the same!
vim.fn.MoltenUpdateOption("auto_open_output", true)
vim.fn.MoltenUpdateOption("molten_auto_open_output", true)
MoltenRunningKernels

Return a list of the currently running kernels' IDs. Takes one argument, when true, returns only kernels running in the current buffer. Otherwise, returns all running kernel_ids.

vim.fn.MoltenRunningKernels(true) -- list buf local kernel ids
vim.fn.MoltenRunningKernels(false) -- list all kernel ids
MoltenAvailableKernels

Returns a list of kernel names that molten is aware of.

vim.fn.MoltenAvailableKernels()
MoltenDefineCell

Takes in a start line, and end line, and a kernel and creates a code cell in the current buffer associated with that kernel. Does not run the code or create/open an output window.

for compatibility reasons, if there is only one active kernel, you do not need to pass the kernel argument

-- Creates a cell from line 5 to line 10 associated with the python3 kernel
vim.fn.MoltenDefineCell(5, 10, 'python3')

Output Chunks

In the Jupyter protocol, most output-related messages provide a dictionary of mime-types which can be used to display the data. Theoretically, a text/plain field (i.e., plain text) is always present, so we (theoretically) always have that fallback.

Here is a list of the currently handled mime-types:

  • text/plain: Plain text. Shown as text in the output window's buffer.
  • image/*: Molten attempts to render any image mimetype by sending it to image.nvim. In theory, this means that Molten can handle any image format that image.nvim supports, though I've only tested common formats
    • Images are also viewable outside of the terminal with :MoltenImagePopup
  • application/vnd.plotly.v1+json: A Plotly figure. Rendered into a PNG with Plotly + Kaleido
  • text/latex: A LaTeX formula. Rendered into a PNG with pnglatex
  • text/html: via the :MoltenOpenInBrowser command.

This already provides quite a bit of basic functionality, but if you find a use case for a mime-type that isn't currently supported, feel free to open an issue and/or PR!

Thanks

  • @dccsillag and everyone who has contributed to magma-nvim
  • @3rd and everyone who has contributed to image.nvim

molten-nvim's People

Contributors

akthe-at avatar andnig avatar benlubas avatar beyarkay avatar dccsillag avatar gallavee avatar github-actions[bot] avatar johnedchristensen avatar lkhphuc avatar loipesmas avatar meatballs avatar mrbober avatar rchhong avatar tbung avatar tillerburr avatar tzachar avatar usmcamp0811 avatar v3rganz avatar vinnymeller avatar whiteblackgoose avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

molten-nvim's Issues

[Bug] pyenv causes issues with image rendering

  • OS: MacOs Ventura 13.2
  • NeoVim Version: NVIM v0.9.4
  • Kitty Terminal Version: 0.31.0

Description

There is no image in the output, even though everything else is correctly displaying.
image

I believe I have everything properly installed
image
and image.nvim works just fine with the test that they provide:
image

The issue is a lot like #7 on image.nvim repo. However, the fix/troubleshooting steps on that issue did not pertain to my issue with molten-nvim.

I am using a minimal test config file for neovim so that variables can be isolated (I didn't use a color scheme in the screenshots because I thought that might be the issue, but I added it back because it looks better)

-- Example for configuring Neovim to load user-installed installed Lua rocks:
package.path = package.path .. ";" .. vim.fn.expand("$HOME") .. "/.luarocks/share/lua/5.1/?/init.lua;"
package.path = package.path .. ";" .. vim.fn.expand("$HOME") .. "/.luarocks/share/lua/5.1/?.lua;"

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "https://github.com/folke/lazy.nvim.git",
        "--branch=stable", -- latest stable release
        lazypath,
    })
end
vim.opt.rtp:prepend(lazypath)

-- install plugins
local plugins = {
    {  "folke/tokyonight.nvim",},
    {
        "benlubas/molten-nvim",
        version = "^1.0.0", -- use version <2.0.0 to avoid breaking changes
        dependencies = { "3rd/image.nvim" },
        build = ":UpdateRemotePlugins",
        init = function()
            -- these are examples, not defaults. Please see the readme
            vim.g.molten_image_provider = "image.nvim"
            vim.g.molten_output_win_max_height = 20
        end,
    },
    { "3rd/image.nvim",
    opts = {
        backend = "kitty", -- Kitty will provide the best experience, but you need a compatible terminal
        integrations = {}, -- do whatever you want with image.nvim's integrations
        max_width = 100, -- tweak to preference
        max_height = 12, -- ^
        max_height_window_percentage = math.huge, -- this is necessary for a good experience
        max_width_window_percentage = math.huge,
        window_overlap_clear_enabled = true,
        window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "" },
    },
    version = "1.1.0", },
    {
        "nvim-treesitter/nvim-treesitter",
        build = ":TSUpdate",
        config = function()
            require("nvim-treesitter.configs").setup({
                ensure_installed = {
                    "markdown",
                    "markdown_inline",
                },
            })
        end,
    },
}
require("lazy").setup(plugins)

vim.cmd.colorscheme("tokyonight")

Reproduction Steps

I am running python 3.12.1 currently. But I have also tried this with 3.11. Here are the python packages I have installed

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
plotly = "*"
numpy = "*"
matplotlib = "*"
pynvim = "*"
jupyter-client = "*"
pillow = "*"
cairosvg = "*"
pnglatex = "*"
pyperclip = "*"
kaleido = "*"
notebook = "*"
nbformat = "*"

[requires]
python_version = "3.12"
python_full_version = "3.12.1"

For these current screenshots open up NeoVim with the slim config file

nvim -u minimal_config.lua .

run the python file to test the plotting behavior

import matplotlib.pyplot as plt
import numpy as np

# Create some data
x = np.linspace(0, 10, 100)
y = np.sin(x)

# Create the plot
plt.plot(x, y)

Expected Behavior

I expect that the plot would be drawn in the output box. I have tried changing settings in Molten but nothing I have tried has fixed the issue. If I am doing anything wrong let me know. I guess it seems like the issue would be Molten if image.nvim is able to output images with the exact same config.

[Bug] Displayed images don't respond to adding/removing lines

Description

When you have an image shown as a virtual output, adding or removing a newline above or below the image knocks it out of place, the only way to get it back is by re-running the cell or restoring the lines back to how they were before.

There is a similar issue with open output windows that could be solved at the same time.

Reproduction Steps

run a cell with image output
add a line above it

Expected Behavior

Image positions should update when new lines are added or removed. This is probably a use case for change tick, and I can just run it in the molten tick function. I'm not sure.

[Bug] Code Cells and Dynamic Positions Incompatible with f-strings

  • OS: Ubuntu
  • NeoVim Version: v0.9.4
  • Python Version: 3.12.0
  • Python is installed with: Virtual Environment
  • Health checks - OK
`:checkhealth molten`

image

`:checkhealth provider` (the python parts)

image

Description

I'm starting to work on #101 and in order to familiarize myself with the code more, I log lots of little things. To do so, I generally use the f"{var=}" syntax to use var=... formatting. I found that using a CodeCell or DynamicPosition in an f-string produces the __repr__ version

For instance, using

self.nvim.out_write(f"{span=}\n")

produces the following notification:

image

Whereas, using

self.nvim.out_write(f"{span=!s}\n")

produces
image

Reproduction Steps

Use a Code Cell or Dynamic position in an f-string and run a cell. I used self.nvim.out_write(f"{span=}\n") at

if buf.number not in [b.number for b in self.buffers]:
return
if span.begin.lineno == span.end.lineno:
self.nvim.funcs.nvim_buf_add_highlight(
.

Expected Behavior

A more helpful __repr__ that shows the non-default version, i.e. the memory address of the object.

[Bug] `:UpdateRemotePlugins` failing, not an editor command

  • OS: macOS 13.6.1 (M1)
  • NeoVim Version:
- NVIM v0.9.2
- Build type: Release
- LuaJIT 2.1.0-beta3

Description

Running :UpdateRemotePlugins results in the error message E492: Not an editor command: UpdateRemotePlugins, even though all requirements are installed correctly.

Reproduction Steps

  • Install molten via lazy by adding { "benlubas/molten-nvim" }
  • shut down nvim
  • activate virtual environment in a project
  • pip install ipykernel jupyter pynvim
  • start nvim
  • run :UpdateRemotePlugins

Expected Behavior

:UpdateRemotePlugins should work


Context: This is the output of checkhealth:

Python 3 provider (optional) ~
- Using: g:python3_host_prog = "/Users/chrisgrieser/repos/axelrod-prisoner-dilemma/.venv/bin/python"
- Executable: /Users/chrisgrieser/repos/axelrod-prisoner-dilemma/.venv/bin/python
- Python version: 3.11.6
- pynvim version: 0.4.3
- OK Latest pynvim is installed.

Python virtualenv ~
- $VIRTUAL_ENV is set to: /Users/chrisgrieser/repos/axelrod-prisoner-dilemma/.venv
- Python version: 3.11.6
- OK $VIRTUAL_ENV provides :!python.

[Bug] nbformat needed to install

  • OS: arch
  • NeoVim Version: v0.9.4

Description

Went thought the venv guide https://github.com/benlubas/molten-nvim/blob/main/docs/Virtual-Environments.md, but wasn't able to use any molten commands afterwords. Manually running :UpdateRemotePlugins showed an error coming from missing the nbformat package. Installing that package in my base venv resolved the issue.

Reproduction Steps

Follow venv guide on a fresh install.

Expected Behavior

Working install after following guide.

[Bug] Output window height doesn't match image size

Copying context from #105:

Also, plot renderings is a bit strange: very small and huge padding below.

image

This is my configuration

local M = {
    "benlubas/molten-nvim",
    version = "^1.0.0",
    build = ":UpdateRemotePlugins",
    event = "VimEnter",
    init = function()
        -- this is an example, not a default. Please see the readme for more configuration options
        vim.g.molten_image_provider = "image.nvim"
        require("v3rganz.keymaps").molten_keymaps()
    end
}
local M = {
    "3rd/image.nvim",
    event = "BufRead",
    config = function ()
        require("image").setup {
            backend = "kitty",
            integrations = {
                markdown = {
                    enabled = true,
                    clear_in_insert_mode = false,
                    download_remote_images = true,
                    only_render_image_at_cursor = false,
                    filetypes = { "markdown", "vimwiki", "quarto" }, -- markdown extensions (ie. quarto) can go here
                },
            },
            max_width = 1024,
            max_height = 1024,
            max_width_window_percentage = math.huge,
            max_height_window_percentage = math.huge,
            window_overlap_clear_enabled = true,
            window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "" },
        }
    end,
    dependencies = {
        -- need for image magick lua support
        {
            "theHamsta/nvim_rocks",
            event = "VeryLazy",
            build = env .. "pip3 install --user hererocks && python3 -mhererocks . -j2.1.0-beta3 -r3.0.0 && cp nvim_rocks.lua lua",
            config = function()
                require("nvim_rocks").ensure_installed({ "magick" })
            end
        }
    }
}

[Bug] Image output disappears after modifying/switching buffer or creating any window

  • OS: macOS 12.4
  • NeoVim Version: 0.9.4
  • Python Version: 3.11.4
  • Python is installed with: native or brew
  • Health checks
- OK NeoVim >=0.9
- OK Python >=3.10
- OK Python module pynvim found
- OK Python module jupyter-client found
- WARNING Optional python module cairosvg not found
  - ADVICE:
    - pip install cairosvg
- OK Python module pnglatex found
- OK Python module plotly found
- OK Python module kaleido found
- OK Python module pyperclip found
- OK Python module nbformat found

Description

If cell has image output, it disappears (for all such cells) after any of these actions:

  • buffer modified (not only inside cell).
  • switched to other buffer and
  • lsp-hover is called or any window created (like :h)

MoltenEnterOutput still shows correct output with image

Reproduction Steps

molten.mov
  1. Create cell with image output
  2. Evaluate cell
  3. Modify buffer / call lsp-hover / switch buffer
  4. Images disappear

Expected Behavior

Image outputs remain.

Typo in plugin description

In GitHub description (right sidebar) it says

Fork of molten-nvim with

however, it should say "Fork of magma.nvim". (Cannot make a PR, since it's the GitHub description.)

[Help] [Molten] Not in cell

I have a quarto document and some Python cells. Molten is not able to recognize a cell. When using the commands like :MoltenNext, :MoltenPrev, and :MoltenReevaluateCell, it gives an error, [Molten] Not in cell. Do I need to set cell delimiters here?

Screenshot_20231128_221014
Screenshot_20231128_220939
Screenshot_20231128_221258

[Feature Request] Have multiple running clients in the same buffer

Currently, we can have multiple buffers associated with each running kernel, but we can only have one running kernel per buffer.

In some cases (ie. when running code in a notebook file like quarto), it's possible to have multiple code cells with different languages, and you may want to run them both.

The current best way to do that would be to run all the code in language one, switch kernels (and lose all the language one output), then run all the code in language two.

implementation

Implementing this would require changes to some core areas of Molten. It is 100% necessary that the current way of using the plugin does not change at all.

initialization

My first thought was to create another variant of :MoltenInit similar to how we have :MoltenInit shared <kernel> we could have :MoltenInit add <kernel> to add a new kernel to the current buffer.

But after thinking about it a little more, why not just change the default behavior of :MoltenInit <kernel> when there is already a kernel running. I know this could be seen as a breaking change, but initializing twice was never supported, it was just undefined behavior.

running code

This then begs the question of how does Molten know which kernel to send the code to for a command like :MoltenEvaluateLine?

Solution:

  • MoltenEvaluate* commands take an optional kernel param
  • if there is only one kernel attached to the buffer, send the code to that kernel
  • if there is more than one kernel attached to the current buffer, prompt the user to select which one they should send that code to

save/load

Saving a molten buffer currently saves a single kernel name. We would have to move the kernel information into each code cell, and then restore this information separately as well.

OR

We could only save one kernel at a time.. this would probably be a worse user experience, but at the same time a much easier change to implement, and a less breaking change. I'm also not really sure that people would be using this command anyway given that no one using Magma had filed an issue about it being broken for months

other commands

All of these commands are affected in the same way: they need to take a kernel name, or prompt the user if there's more than one kernel and no name is specified.

  • :MoltenInterrupt
  • :MoltenRestart

MoltenDeinit is a special case. I'm going to have this one shut down an entire buffer and everything associated with it for the time being. I might change this before this feature releases. But for ease of development, I don't foresee people caring that much about shutting down one kernel at a time.

autocommands

Autocommands like (de)init(pre/post) could potentially be called more than once now. I think this is just something that has to be documented. There should be a way to call the autocommand callback with an argument that's the name of the kernel that was (de)initialized.

enter output

This command would become very problematic if there were to be more than one code cell active at a time. In order to prevent this, we should make sure that code cells from different kernels cannot overlap. This is something that would have to be checked each time code is run.

TODOs

  • Add new function, MoltenUpdateOption to the readme
  • multi buffer support
  • Change Border Configuration option to take any value that can be passed to nvim open win border option
  • Setup the Wiki
    • Quickstart guide
    • Python Virtual environment setup
    • Setups/Integrations guides (ie. quarto, and quarto code runner)
  • Create a feature test file
    • Write contributing.md and mention the feature test file
  • Output window redraw optimizations to remove flicker when:
    • The main window is scrolled and output moves
    • More output is added to the buffer
  • Output can show an image that overlaps the status bar
  • A couple image.nvim bugs
  • Inherited a broken save/load system that I'd like to fix
  • When you're in the output window and quit it, your cursor leaves, but it reopens. This is slightly annoying. Should be configurable.
  • :MoltenHideOutput doesn't work from within the output
  • Windows aren't disappearing on window changed
  • Render a "more output" footer or something when the window is shorter than the buffer contents

[Help] How to deal with outputs

Hi, thanks for developing molten -- it is a great plugin. I have been playing with molten recently, but cannot find a good way to interact with the outputs, mainly:

  1. Cannot copy text from output. Seems that outputs are shown in a unfocusable floating window, so <C-w><C-w> does not bring me to that window, and every time I move my cursor near the window, it disappears.
  2. Cannot save images from output.
  3. If the code block is higher than my screen, I have to scroll to the end to see the outputs, and I have to be careful because if I scroll over the block, the output window will disappear and I have to :MoltenShowOutput to see it.
  4. Ouputs are not displayed like what is shown in the demo video in README, instead they are shown in floating windows. I prefer the output style in the demo video, how can I achieve that?

I have looked through the doc of magma and molten but failed to find a solution to the problems above. Could you help me figure out a solution?


EDIT: I discovered :MoltenEnterOutput, which can (partly) answer the first question, but get this error when I run this command:

image

The output window is already shown when I run :MoltenEnterOutput

Also it would be greate if molten expose a function like molten_output_visible(), so that user can use the same keybinding to show and enter the output, somewhat like how K works for LSP hover window:

local function open_or_enter_output()
    if molten_output_visible() then
        molten_output_enter()
    else
        molten_output_open()
    end
end

[Bug] Deleting entire cell code doesn't remove its output

Execute a code cell.
Execute the last line of the code cell.
Delete the last line of the code cell.

There are now two virt text outputs, and one of them is "orphaned" b/c it was attached to the last line of the cell which is now gone.

This is unique to virtual text.

Plots are Broken

  • OS: NixOS
:version                                                                                                                                                                             
NVIM v0.9.1                                                                                                                                                                          
Build type: Release                                                                                                                                                                  
LuaJIT 2.1.0-beta3                                                                                                                                                                   
                                                                                                                                                                                     
   system vimrc file: "$VIM/sysinit.vim"                                                                                                                                             
  fall-back for $VIM: "/nix/store/grcfjxsgxjajc1ws6ip2jkkhd238dx77-neovim-unwrapped-0.9.1/share/nvim"                                                                                

Run :checkhealth for more info

==============================================================================
molten: require("molten.health").check()

molten-nvim ~
- OK NeoVim >=0.9
- OK Python >=3.10
- OK Python package pynvim found
- OK Python package jupyter-client found
- OK Python package cairosvg found
- OK Python package pnglatex found
- OK Python package plotly found
- OK Python package kaleido found
- OK Python package pyperclip found

==============================================================================

image

image

image

Description

Trying to get plots to display, but I get an error. It seems like the variable or what not that is suppose to be returned to run the math command on is returning a null maybe... ยฏ_(ใƒ„)_/ยฏ

the Image plugin works like a charm so I don't think I misconfigured any of the dependencies.

Reproduction Steps

my exact config can be run with Nix like this:

nix run gitlab:usmcamp0811/campground-nvim/molten-issue

Open a Julia file run using Plots; plot(rand(10))

you will get a big wall of red text. This is the problem.

One likely cause could be that something is looking for a program at a specific location and because I am using Nix that path isn't there but I'm not sure what it could be.

[Feature Request] output_keep_open option

I'm using the molten_output_virt_lines option and I think I'd be nice if we could sort of "always show" the output cells, using the virtual lines, similar to an actual Jupyter Notebook. It'd allow, for instance, comparisons between different cell outputs. I'm not really aware of an alternative within the neovim ecosystem.

[Bug] Images are placed above virtual text in virt text output after they're imported

Description

When importing images (either from a ipynb or from the magma output format) images seem to be placed above the heading virtual text after scrolling past the output. This results in the text showing up at the bottom of the output, and the image also shos up at the bottom b/c images will just always assume they're the last thing on the line, that's an image.nvim bug that I should fix one day, but whatever.

Reproduction Steps

Produce an image output, and save it :MoltenSave. Make sure you're using virtual text outputs.

Deinit, then :MoltenLoad. Image shows up like this:

image

Expected Behavior

It should render like this (and it does until I scroll past it for some reason):

image

I think that molten isn't recognizing the virtual text as rendered or done, and it's getting re-rendered somehow, which places it after the image

[Bug] g:molten_virt_lines_off_by_1 doesn't take effect

  • OS: macOS Ventura 13.0
  • NeoVim Version: 0.9.2

Description

Changing the value of `g:molten_virt_lines_off_by_1 has no impact over the window positioning.

Reproduction Steps

Switching between the two following configurations has no impact on how the output window is displayed.

return {
  "benlubas/molten-nvim",
  build = ":UpdateRemotePlugins",
  init = function()
      vim.g.molten_virt_lines_off_by_1 = true
  end,
}
return {
  "benlubas/molten-nvim",
  build = ":UpdateRemotePlugins",
  init = function()
      vim.g.molten_virt_lines_off_by_1 = false
  end,
}

Expected Behavior

When said parameter is true the output window should move one line up to cover the last line of the buffer.

[Feature Request] List Running Kernels

When running with multiple kernels at once, it's hard to keep track of them. Which ones are running in the current buffer? Which ones are running period? No way to know without changing the state of the plugin.

Two things that I want to do here...

  1. A way to show running kernels in the status line
  2. A command to list the running kernels (either all of them or just the ones running in the current buffer.

[Bug] MoltenEvaluateRange fails if end_line is past the end of the buffer

  • OS:Ubuntu
  • NeoVim Version:0.9.4

Description

This was discovered by @GCBallesteros in the GCBallesteros/NotebookNavigator.nvim#25.
While trying to use the runner, if the end_line argument is past the buffer, it gets an "Invalid 'line': out of range" error

Reproduction Steps

The following are the only contents of the notebook:

#%%
print('hello')

Config (lazy.nvim):

{
	"benlubas/molten.nvim",
	version = "^1.0.0",
	build = ":UpdateRemotePlugins",
	init = function()
		vim.keymap.set("n","<leader>mt",":lua vim.fn.MoltenEvaluateRange(1,4)<CR>")
	end,
}

After running :MoltenInit, you can run the above command and you will receive the following error:

image

Expected Behavior

The cell executes without erroring. Not sure how to implement, possibly a check if end_line is after the end of the current buffer and use the last line of the buffer instead of the passed argument.

[Bug] Exporting to ipynb with comments at the end of the line

MacOS
nvim 9.4

Description

Exporting outputs that have code cells with comments at the end of the line causes cells to not match up. Need to investigate a little further to figure out the cause of that.

Reproduction Steps

create a jupyter notebook with this cell

print("hi") # problem

open in nvim, run with molten, try to export the cell. Cell contents don't match.

Print statement debugging to the rescue. Though I'm not sure why this would be a problem right now

[Help] Questions regarding demo & overall usage experience

Hello, I tried molten first time today. I have never had experience with notebooks in nvim before. First impressions are very good and promising.
However, I can't understand how can I do some basic things, which were demonstrated in the video attached to the readme.

  • Currently my cell outputs are only shown when the cursor hovers chunk of code being executed. I don't want it to disappear after I move cursor away. How can I configure it this way?
  • There is an options to execute line of code, and operator like <MoltenEvaluateOperator>j20, which is usable, but clearly not the smoothest workflow for cell execution. Is there an option to execute entire cell? I noticed that in demo it seems to be working this way.

[Bug] Running a cell again before it finishes

Description

Specifically by overwriting the cell with a new one in the same place.

This causes:

  • assertions about cell status not being DONE to fail
  • the next run cell will render output from the cell that we ran twice (this one is really weird)
  • possibly others?

Reproduction Steps

Run a cell like:

import time
for _ in range(100):
  print("-", end="")
  time.sleep(0.1)

and while it's still running, run it again by running the same code, so that it creates an overlapping cell (and therefore deleting the old one). Then run a new cell with different output, and see the same output from before.

Expected Behavior

Not that

[Bug] large output slows down editor with floating window

Description

When opening a floating output window that contains a lot of output text, the editor slows down a ton.

Reproduction Steps

I notice this when printing and opening a corpus for data science. An easy way to reproduce would be to just to a string in a loop.

Expected Behavior

Other notebook editors deal with this by simply truncating output that's longer than a certain length.

I think that a better first step would be to make sure we're caching the output buffer text. I'm not sure that we're currently doing that.

[feature request] Configurable Tick Rate

I noticed that the "tick rate" set at 500 can make molten feel a little slower than it needs to be. Lowering it to 250 doesn't seem to have a performance impact, and reduces the time between code finishing and showing up on screen which can lead to a much better experience.

I'm able to set it as low as 100 without apparent performance issues and running code feels way better.

[Bug] Exporting Progress bar output

When exporting progress bars, the text isn't truncated in the same way that it is when we display it in the buffer. This leads to the output chunks displaying differently when they're run vs when they're exported (and then reimported, but that part doesn't matter as much. The outputs look weird in jupyter lab too).

after run:
image

after exported:
image

[Feature Request] Export outputs to .ipynb files

Currently, a large pain point of using molten + some tool to convert Jupyter notebooks to plaintext is the inability to save output from molten in a shareable format (ie. .ipynb).

Proposed solution to this:

The :MoltenExport command.

This would work in a similar way to :MoltenSave, but it would look for an existing ipynb file that matches the name of the currently open file and alters it (or maybe makes a copy), so that it contains the output stored by molten.

concerns

I have many.

  • does the Jupyter file format change? are there multiple versions? How often do they change if at all?
  • How do we match up different cells? We could match the code but then different code cells containing the same code could be confused.
  • How can we make this conversion tool agnostic? I'd like this to work with jupytext and quarto documents. They both store information about cells differently, and I don't really want to have to parse these out.
    • comments will probably have to be ignored b/c quarto uses them for metadata
  • This is probably going to be a fragile feature, I should definitely make that clear.
  • can we save mimetypes that molten doesn't actually display? If I get an HTML output, ideally it could be saved despite not being rendered.

addressing concerns

Now that I've done some reading

  • Yes, there are multiple versions. If we just rely on nbformat, I think this issue more or less goes away.
  • This is the hardest part probably. I'm pretty sure that simply using the code cell position in conjunction with the code content will work in all or nearly all cases.
  • I'm sure this is something that will be tweaked as more people start to use it
  • agree
  • yeah this is possible, on the surface it seems like it might be very simple b/c we already save everything.

[Feature Request] Add command for running current code block / code blocks above / code blocks below

Hi, thanks for making this plugin, it is a huge addition to my jupyter notebook workflow.

Being able to evaluate the current code block quickly is an essential part of a fluent experience with jupyter notebook, but there's no easy way to do this with molten-nvim.

Currently, we have to select the code block manually and call :MoltenEvaluateVisual, which feels clunky. I tried the setup using treesitter text object introduced in https://github.com/benlubas/molten-nvim/blob/main/docs/Notebook-Setup.md#jupytext, but it only select a python block instead of the whole block in the markdown file:

image

What is hope to achieve is:

  1. Pressing <CR> (without selection) inside a python code block will run that code block through jupyter kernel
  2. Selecting a region in code block and then pressing <CR> will run the selected code only, this is already possible using :MoltenEvaluateVisual
  3. <CR> mapping should be buffer-local, i.e. only set for buffers that have molten attached
  4. Add other commands that runs all code blocks above / below the current block, like what we can do in jupyter lab or vscode

[Feature Request] Variable Explorer

It would be great to have a variable explorer in Molten. This could help users see what code they've already run, and have access to the state of their code.

One of the main downfalls (in my opinion) of notebook style programming is that you can write some code that takes an already defined variable and modifies it. But if you run that block more than once without realizing, you've now fudged your variable state and all your numbers from then on out are incorrect until you rerun your notebook.

Having a variable explorer open would fix this issue.

implementation

If this plugin only supported python, this could be as simple as running the %whos IPython magic command to get the variable state whenever the use runs code. However. This is just something IPython implements, and is not a general feature of the Jupyter Kernel. As such, other kernels do not how this implemented, and we can't rely on it.

Jupyter client apparently implements an inspect-variables command (?) that should give us variable information as well. I'd imagine this is supported by a wider range of jupyter clients (though I'd be surprised if all of them supported it).

[Bug] Error Output I/O

This causes some crashes right now, which produce walls of red text, I have a fix for that, but these are still not either exported or imported properly (or both).

[Bug] Images aren't shown in output window when virt output is on

  • NeoVim Version: stable 0.9.4

Description

When virtual text output is enabled, images are rendered in the main buffer, however, they don't show up in the output window when it's opened

Reproduction Steps

  • enable molten_virt_text_output
  • run a cell with image output
  • open it's output window

[Feature Request] Importing output chunks from ipynb files

The compliment to the :MoltenExportOutput command, would import outputs from an ipynb file into molten.

This is useful for quickly checking the output in a notebook without having to recompute everything.

This should behave in a similar way to MoltenExportOutput when there's cell incompatibility issues.

[Bug] Output window off by one with tabline

  • OS: macOS Ventura 13.0
  • NeoVim Version: 0.9.2

Description

The position of the output window is off by one.

image

The Molten cell on the image above does not cover the last # before the output window.

Reproduction Steps

Run with the following config:

return {
  "benlubas/molten-nvim",
  build = ":UpdateRemotePlugins",
  init = function()
    -- this ended up not mattering  
	-- vim.g.molten_virt_lines_off_by_1 = false
  end,
}
  • Create a new tab :tabnew
  • run a chunk of code
  • observe output window shows up 1 line too low

Expected Behavior

Output window should be immediately below the last of the cell when g:molten_virt_lines_off_by_1=false and should cover the last line when the latter is set to true. even when there is a tabline present.

[Feature Request] `:MoltenOpenInBrowser`

Essentially this issue from Magma, which requests a way to handle HTML output chunks by sending them to a web browser

Implementation

  1. When an output cell has an HTML output chunk you can run :MoltenOpenInBrowser while in the chunk to open the output in a web browser
  2. There should be a configuration variable to enable automatically opening output in a browser as soon as the cell finished running.

[Bug] Images not rendering with default floating window output

  • OS: Arch Linux (kernel 6.6.10-arch1-1)
  • NeoVim Version: NVIM v0.9.5
  • Python Version: 3.11.6
  • Python is installed with: System Python
  • Health checks
`:checkhealth molten`
molten-nvim ~
- OK NeoVim >=0.9
- OK Python >=3.10
- OK Python module pynvim found
- OK Python module jupyter-client found
- OK Python module cairosvg found
- WARNING Optional python module pnglatex not found
  - ADVICE:
    - pip install pnglatex
- OK Python module plotly found
- OK Python module kaleido found
- OK Python module pyperclip found
- OK Python module nbformat found
`:checkhealth provider` (the python parts)
Python 3 provider (optional) ~
- `g:python3_host_prog` is not set.  Searching for python3 in the environment.
- Executable: /usr/bin/python3
- Python version: 3.11.6
- pynvim version: 0.5.0
- OK Latest pynvim is installed.

Python virtualenv ~
- OK no $VIRTUAL_ENV

Description

When using the default floating windows to display outputs, images do not appear.

Screenshot_20240107_154232

If I add plt.show() at the end the output simply changes for "Done". I also tried not using subplots, with and without an explicit plt.figure(), but none of those worked.

The issue is fairly similar to #92, although pyenv is not involved, so I tried the minimal config provided by @bpnordin and the issue persisted. I also tried some of the solutions proposed there (adding a new line below the sent snippet, entering the output, scrolling with <C-e> and <C-y>).

After exploring the docs a bit more, I tried some of the options in the notebook setup guide. Setting vim.g.molten_virt_text_output = true is the only way I found to display the image. Personally I'm happy with this fix, but I guess it does not address the root of the issue.

Minimal config from issue #92
-- Example for configuring Neovim to load user-installed installed Lua rocks:
package.path = package.path .. ";" .. vim.fn.expand("$HOME") .. "/.luarocks/share/lua/5.1/?/init.lua;"
package.path = package.path .. ";" .. vim.fn.expand("$HOME") .. "/.luarocks/share/lua/5.1/?.lua;"

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "https://github.com/folke/lazy.nvim.git",
        "--branch=stable", -- latest stable release
        lazypath,
    })
end
vim.opt.rtp:prepend(lazypath)

-- install plugins
local plugins = {
    {  "folke/tokyonight.nvim",},
    {
        "benlubas/molten-nvim",
        version = "^1.0.0", -- use version <2.0.0 to avoid breaking changes
        dependencies = { "3rd/image.nvim" },
        build = ":UpdateRemotePlugins",
        init = function()
            -- these are examples, not defaults. Please see the readme
            vim.g.molten_image_provider = "image.nvim"
            vim.g.molten_output_win_max_height = 20
        end,
    },
    { "3rd/image.nvim",
    opts = {
        backend = "kitty", -- Kitty will provide the best experience, but you need a compatible terminal
        integrations = {}, -- do whatever you want with image.nvim's integrations
        max_width = 100, -- tweak to preference
        max_height = 12, -- ^
        max_height_window_percentage = math.huge, -- this is necessary for a good experience
        max_width_window_percentage = math.huge,
        window_overlap_clear_enabled = true,
        window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "" },
    },
    version = "1.1.0", },
    {
        "nvim-treesitter/nvim-treesitter",
        build = ":TSUpdate",
        config = function()
            require("nvim-treesitter.configs").setup({
                ensure_installed = {
                    "markdown",
                    "markdown_inline",
                },
            })
        end,
    },
}
require("lazy").setup(plugins)

vim.cmd.colorscheme("tokyonight")

Reproduction Steps

Running this snippet using the config above is enough to reproduce on my side. I was able to reproduce using the system Python (which is the one I use as neovim provider) as well as a virtual environment.

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1,2,3,4])
Pip freeze output of a simple venv I used to reproduce
annotated-types==0.6.0
asttokens==2.4.1
attrs==23.2.0
black==23.12.1
click==8.1.7
colorama==0.4.6
comm==0.2.1
contourpy==1.2.0
copier==9.1.0
cycler==0.12.1
debugpy==1.8.0
decorator==5.1.1
dunamai==1.19.0
executing==2.0.1
fastjsonschema==2.19.1
flake8==7.0.0
flake8-bugbear==23.12.2
fonttools==4.47.0
funcy==2.0
ipdb==0.13.13
ipykernel==6.28.0
ipython==8.19.0
isort==5.13.2
jedi==0.19.1
Jinja2==3.1.2
jinja2-ansible-filters==1.3.2
jsonschema==4.20.0
jsonschema-specifications==2023.12.1
jupyter_client==8.6.0
jupyter_core==5.7.0
jupytext==1.16.0
kiwisolver==1.4.5
markdown-it-py==3.0.0
MarkupSafe==2.1.3
matplotlib==3.8.2
matplotlib-inline==0.1.6
mccabe==0.7.0
mdit-py-plugins==0.4.0
mdurl==0.1.2
mypy-extensions==1.0.0
nbformat==5.9.2
nest-asyncio==1.5.8
numpy==1.26.3
packaging==23.2
parso==0.8.3
pathspec==0.12.1
pexpect==4.9.0
pillow==10.2.0
platformdirs==4.1.0
plumbum==1.8.2
prompt-toolkit==3.0.43
psutil==5.9.7
ptyprocess==0.7.0
pure-eval==0.2.2
pycodestyle==2.11.1
pydantic==2.5.3
pydantic_core==2.14.6
pyflakes==3.2.0
Pygments==2.17.2
pyparsing==3.1.1
PyQt5==5.15.10
PyQt5-Qt5==5.15.2
PyQt5-sip==12.13.0
python-dateutil==2.8.2
PyYAML==6.0.1
pyyaml-include==1.3.2
pyzmq==25.1.2
questionary==1.10.0
referencing==0.32.1
rpds-py==0.16.2
six==1.16.0
stack-data==0.6.3
toml==0.10.2
tornado==6.4
traitlets==5.14.1
typing_extensions==4.9.0
wcwidth==0.2.13

P.S.: Thanks for the plugin, it's really nice to have this workflow available directly in Neovim :)

[Feature Request] Smart auto init on first run

Currently, if the user tries to run a molten command without initialization, molten throws an error, but running :MoltenInit xxx manually on each file is cumbersome, especially when you have multiple notebooks and Python files opened.

The user experience can be significantly improved if we can ask the user to initialize molten the first time they try to run a command from molten. It should work like the jupyter notebook integration in vscode, where the user will be asked to choose a kernel if they haven't chosen one before running the code.

Additionally, when molten is initialized in a new buffer, it should automatically re-use an existing kernel if there is one attached to an old buffer with the same root directory instead of creating a new one. A root directory can be defined as the first directory that contains .git/, .editorconfig, or something else, similar to the root detection implemented in nvim-lspconfig. The root patterns should be configurable using a list global value, e.g. vim.g.molten_root_pattern = { '.git/', '.editorconfig' }.

Just some thoughts, I have spent hours looking at the code and trying to implement this feature but without success.

[Bug] wrap with virt text is buggy

  • NeoVim Version: 9.4

Description

When printing a long output and displaying as virtual text, sometimes the lines show up more than once, and they don't show up wrapped.

Reproduction Steps

print("x" * 100000)

Expected Behavior

This text should ideally be wrapped, and should definitely show up only once.

[Feature Request] Automatically define cells

It would be quite useful if cells were defined automatically when loading a file. This should be doable as cells tend to be within well defined blocks of text (e.g., between ``` lines in md or qmd). Then, we could have commands to create and remove cells, which insert these characters and define the cells' range.

What do you think?

[Feature Request] Configuration to Allow Offset of Output Window

While trying to integrate Molten into GCBallesteros/NotebookNavigator.nvim#25, we have some odd placement of the output window, mainly because we are using MoltenEvaluateRange with an extended cell. See GCBallesteros/NotebookNavigator.nvim#25 (comment) for an example. This leads to the output window being displayed just below the # %% cell marker of the next cell. For those unfamiliar, this may look like the output is for the incorrect cell.

I've tried using molten_virt_text_output and molten_virt_lines_off_by_1 in various states, but still have the same problem.

I guess what I'm asking is if you'd be interested in allowing the output to be shifted by some offset? I was messing around with Molten's code to get more familiar with nvim plugins and I have something that, in my limited testing, produces the desired output (from the fork https://github.com/TillerBurr/molten-nvim/tree/output-offset)

image
image

I can open a pull request, but I wanted to create an issue beforehand, so it's not like I opened a pull request implementing a feature that hasn't been discussed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.