Skip to content

Commit

Permalink
chore: move wiki to docs (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
benlubas authored Nov 17, 2023
1 parent c11f6be commit f7871bd
Show file tree
Hide file tree
Showing 6 changed files with 419 additions and 13 deletions.
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ to Magma. As they say, I stand on the shoulders of giants.

https://github.com/benlubas/molten-nvim/assets/56943754/6266efa4-a6e4-46f1-8e15-96495a6b6fe8

## Features
## Feature Highlights

- Send code to run asynchronously in the jupyter kernel
- Supports any language with a Jupyter Kernel (in theory, they haven't all been tested)
Expand All @@ -16,14 +16,13 @@ https://github.com/benlubas/molten-nvim/assets/56943754/6266efa4-a6e4-46f1-8e15-
- See output in real time, without flicker
- Python virtual environment support
- Renders images, plots, and LaTeX to the terminal
- Very customizable

## Requirements

- NeoVim 9.4+
- Python 3.10+
- [image.nvim](https://github.com/3rd/image.nvim) is only required if you want to render images
- Required Python packages (can be installed in a venv. [read more](https://github.com/benlubas/molten-nvim/wiki/Virtual-Environments)):
- Required Python packages (can be installed in a venv. [read more](./docs/Virtual-Environments.md)):
- [`pynvim`](https://github.com/neovim/pynvim) (for the Remote Plugin API)
- [`jupyter_client`](https://github.com/jupyter/jupyter_client) (for interacting with Jupyter)
- Optional Python packages:
Expand All @@ -35,17 +34,19 @@ https://github.com/benlubas/molten-nvim/assets/56943754/6266efa4-a6e4-46f1-8e15-

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

**Note:** Python packages which are used only for the display of some specific kind of output are only imported when that output actually appears.
**Note:** Python packages which are used only for the display of some specific kind of output are
only imported when that output actually appears.

## Quick-start

I still recommend reading at least the Usage section of this README before getting started.
Configuration information is located in this README, there is more information about getting started
in these places:

[Probably Too Quick Start Guide](https://www.github.com/benlubas/molten-nvim/wiki/Probably-Too-Quick-Start-Guide)
[Probably Too Quick Start Guide](./docs/Probably-Too-Quick-Start-Guide.md)
or
[Not So Quick Start Guide](https://www.github.com/benlubas/molten-nvim/wiki/Not-So-Quick-Start-Guide)
[Not So Quick Start Guide](./docs/Not-So-Quick-Start-Guide.md)

The Wiki also contains more in depth setup information/guides.
The `docs/` folder also contains more in depth information about different ways to use the plugin.

## Usage

Expand Down Expand Up @@ -115,7 +116,7 @@ kernel
## Keybindings

The commands above should be mapped to keys for the best experience. There are more detailed setups
in the [Wiki](https://github.com/benlubas/molten-nvim/wiki), but here are some example bindings.
in the [Docs](./docs), but here are some example bindings.
Pay attention to `MoltenEvaluateVisual` and `MoltenEnterOutput`, as they need to be run in...odd
ways.

Expand Down Expand Up @@ -310,15 +311,20 @@ 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.
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 ImageMagick supports, though I've only
tested common formats
- `application/vnd.plotly.v1+json`: A Plotly figure. Rendered into a PNG with [Plotly](https://plotly.com/python/) + [Kaleido](https://github.com/plotly/Kaleido)
- `text/latex`: A LaTeX formula. Rendered into a PNG with [pnglatex](https://pypi.org/project/pnglatex/)
- `application/vnd.plotly.v1+json`: A Plotly figure. Rendered into a PNG with
[Plotly](https://plotly.com/python/) + [Kaleido](https://github.com/plotly/Kaleido)
- `text/latex`: A LaTeX formula. Rendered into a PNG with
[pnglatex](https://pypi.org/project/pnglatex/)

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!
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!
54 changes: 54 additions & 0 deletions docs/Advanced-Functionality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
This page will go over some of the more "advanced" ways you can use this plugin that aren't covered
in the other docs.

## Connecting to external kernels

Normally, Molten will launch the kernel for you, and close it for you when you exit neovim. However,
you may want to launch a kernel from somewhere else, and connect to it with Molten, and close neovim
while the kernel stays running. This is possible with Molten by specifying the connection file for
the running kernel. This is a JSON file that's printed in the console when starting a kernel with
the `jupyter kernel` command.

### Example

```bash
jupyter kernel --kernel=python3
# [KernelApp] Starting kernel 'molten'
# \/ this is the important part
# [KernelApp] Connection file: /home/benlubas/.local/share/jupyter/runtime/kernel-5094b45f-58e4-4fdc-9e68-baf52e7e76a9.json
# [KernelApp] To connect a client: --existing kernel-5094b45f-58e4-4fdc-9e68-baf52e7e76a9.json
# [IPKernelApp] WARNING | debugpy_stream undefined, debugging will not be enabled
```

Then, in neovim I can run the command: `:MoltenInit
/home/benlubas/.local/share/jupyter/runtime/kernel-5094b45f-58e4-4fdc-9e68-baf52e7e76a9.json` to
connect to that kernel. You can then run code on this kernel like normal. When you leave neovim, the
kernel will remain running.

You can also start the server with
```bash
jupyter console --kernel=python3 -f /tmp/your_path_here.json
```
in order to avoid having to copy paste the file path. But this requires jupyter-console to be
installed.

### Remote hosts

> [!NOTE]
> I've not tested this, but it should work
It's also possible to use this method to connect to remove jupyter kernels.

On the remote machine run:
```bash
jupyter console --kernel julia-1.7 --ip 1.2.3.4 -f /tmp/remote-julia.json
```
Again, you can also use `jupyter kernel --kernel=<kernel_name>` but the file path will be a lot
longer

Locally run:
```bash
scp 1.2.3.4:/tmp/remote-julia.json /tmp/remote-julia.json
```

And finally run `:MoltenInit /tmp/remote-julia.json` in neovim.
148 changes: 148 additions & 0 deletions docs/Not-So-Quick-Start-Guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Not So Quick Start Guide

This will walk you through the install, light configuration, and basic usage! It's a little less
than quick in the interest of explaining what's necessary and what's not.

## Installation

### Dependencies

This plugin has many dependencies if you would like the full experience. Most of these dependencies
are optional and are only necessary if you would like image support.

#### Image.nvim

[Image.nvim](https://github.com/3rd/image.nvim) is a neovim plugin that provides an api for
rendering images. Rending images in the terminal is not the most straight forward thing in the
world. As such, I'd recommend clicking that link, configuring image.nvim, making sure it works
with their builtin markdown integration, and then coming back here to finish setting up Molten.

##### After Image.nvim is working

There are a few image.nvim config options that will dramatically improve your experience. Here is
a sample configuration that leaves out the document integrations (note if you want to disable these,
please see the [image.nvim](https://github.com/3rd/image.nvim) readme.

```lua
-- image nvim options table. Pass to `require('image').setup`
{
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", "" },
},
```

**Important**: `max_width` and `max_height` _must_ be set, or large images can cause your terminal
to crash. I recommend the values 100 and 12, that feels natural to me, but feel free to increase or
decrease as you see fit (font size will make a large difference here).

Less important but still important: Setting `max_height_window_percentage` to `math.huge` is
necessary for Molten to render output windows at the correct dimensions. This value defaults to
50 or 60%, and for a plugin like Molten, which tries to display a window that's only as tall as it
needs to be, window percentage caps are problematic. Note that even setting this value to 100% is not
enough, as this can cause images to be resized instead of cropped when the molten output window is
partially off-screen, and the image is (until you scroll) taller than the window.


##### Pinning Image.nvim version

Image.nvim is still in it's early stages, and as such, breaks more often than other plugins. For the
most reliable experience with Molten, you should pin the version of image.nvim that you use.

Different package managers allow for pinning versions differently, so please refer to your package
manager's documentation if you don't use Lazy.

> [!NOTE]
> Note that I will always use the latest version of image.nvim, and will try to keep this doc up to
> date with the last working version. But if you're having issues with the version listed here,
> please first try the latest image.nvim version, and then open an issue or pr.
```lua
version = "1.1.0",
```

#### Python Deps

**Note**: It's recommended that you install python packages in a virtual environment as outlined in
the [venv guide](Virtual-Environments)

**Absolutely necessary python packages:**
- [`pynvim`](https://github.com/neovim/pynvim) (for the Remote Plugin API)
- [`jupyter_client`](https://github.com/jupyter/jupyter_client) (for interacting with Jupyter)

**Packages only required for their specific image support:**
- [`cairosvg`](https://cairosvg.org/) (for displaying transparent SVG images)
- If you don't have cariosvg installed, we fallback to image.nvim's svg support, which uses the
ImageMagic library. From what I've gathered, this library has differing levels of support for
SVGs with transparent backgrounds. So I'd recommend trying to get away without cairo, and only
installing it if you notice an issue.
- [`pnglatex`](https://pypi.org/project/pnglatex/) (for displaying TeX formulas)
- Note that this has additional, non-pip, dependencies. You need a TeX distribution installed on
your machine as well as the following executables: `pdftopnm`, `pnmtopng`, `pdfcrop` which you
can find through your system package manager.
- `plotly` and `kaleido` (for displaying Plotly figures)
- In order to render plotly figures you might also needed `nbformat` installed in the project
venv, unfortunately installing it in the neovim venv did not work (see [venv
guide](Virtual-Environments))
- `pyperclip` if you want to use `molten_copy_output`

#### .NET Deps
- `dotnet tool install -g Microsoft.dotnet-interactive`
- `dotnet interactive jupyter install`

> [!NOTE]
> I personally do not use .NET (nor have I ever), all the tooling for .NET is working in theory, but
> hasn't been tested by myself. This is something Magma supported, and there's no reason that it
> shouldn't still work, but I'll be able to provide limited help here.
### Sample Lazy.nvim Config

```lua
return {
{
"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
vim.g.molten_auto_open_output = false
end,
},
{
-- see the image.nvim readme for more information about configuring this plugin
"3rd/image.nvim",
opts = {
backend = "kitty", -- whatever backend you would like to use
max_width = 100,
max_height = 12,
max_height_window_percentage = math.huge,
max_width_window_percentage = math.huge,
window_overlap_clear_enabled = true, -- toggles images when windows are overlapped
window_overlap_clear_ft_ignore = { "cmp_menu", "cmp_docs", "" },
},
}
},
```

### A Note on Remote Plugins

Molten is a remote plugin. This means that the first time you install, and after you update Molten
you need to run the `:UpdateRemotePlugins` command in Neovim. This can be done with some package
mangers (like Lazy for example) automatically.

But if things aren't working, make sure that you run that command and then restart your editor.

### Customize

The README is the best resource for customization info. Additionally, you'll want to setup some
keybinds for common commands like `:MoltenEvaluateVisual`, more information about doing this is also
in the README!

77 changes: 77 additions & 0 deletions docs/Notebook-Setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Notebook Setup

There are a few different ways to use this plugin. This file will focus on the main way that I use
it: To edit Jupyter Notebook Files...kind of.

I don't need to edit and share `ipynb` file very often. I only have to submit a homework assignment
once in a while. So I pull down a notebook file, convert it to markdown, work on it for a week or
two, and then convert it back right before submitting.

## Quarto

[Quarto](https://quarto.org/) is, at its core, a tool for writing and publishing literate
programming documents, or just any markdown document really. It's built on top of Pandoc, and so can
render markdown to pdf, html, or any format that Pandoc supports.

`quarto convert some_notebook.ipynb --to my_notebook.qmd` will convert a notebook into a "quarto
markdown" file, which is a nice plain-text format that you can work with in neovim.

Quarto also has its own neovim plugin: [quarto-nvim](https://github.com/quarto-dev/quarto-nvim).
I use this plugin primarily for its integration with
[otter.nvim](https://github.com/jmbuhr/otter.nvim), which enables LSP features in the markdown
document, but this is also a very easy way to render markdown files that you're working on in
neovim.

### Alternatives

There are other ways to edit Jupyter notebook files in Neovim. Most notably
[Jupytext](https://github.com/mwouts/jupytext) with
[jupytext.vim](https://github.com/goerz/jupytext.vim). This will let you open a normal `.ipynb`
file, convert it automatically to plain-text and display it in a temporary buffer, and then convert
it back again when you write. This has worked very well for me the few times that I've used it.


There is also the [NotebookNavigator](https://github.com/GCBallesteros/NotebookNavigator.nvim)
plugin, which allows you to turn python files into notebooks with comment delimiters. The plugin
comes with a few qol features, and while molten support isn't officially part of the plugin at the
time of writing, it's being worked on, and there's nothing stopping you from just using molten's
builtin run methods.

## Code Running

Obviously we're going to use Molten for this, but there is some extra setup we can do to get more of
a Notebook experience. The concept of "Code Cell" still exists in Markdown documents, and often
you'll want to run an entire cell or all the cells above the current one. The easiest way to do this
is with a little bit of lua scripting.

### Quarto Code Runner

[quarto_code_runner.lua](https://github.com/benlubas/.dotfiles/blob/d6c540b6c9fe740c18876b2e43cbfcc6aa70fcf9/nvim/lua/benlubas/quarto_code_runner.lua)
is a small script that I've written to help easily run code in a `qmd` document.

It uses Molten to send code from a quarto buffer to a running kernel.


For now, this is just a very quick script that I threw together, I plan to improve it in the
future. Anyone is welcome to take and modify this code for their own purposes, so if you would like
to have a similar setup, just grab the file above, and throw it into your config.

#### Run mappings

Using the functions from the file above, we can setup mappings like this:

```lua
vim.keymap.set("n", "<localleader>rc", M.run_cell,
{ desc = "run code cell", buffer = true })
vim.keymap.set("n", "<localleader>ra", M.run_all_above,
{ desc = "run all code cells above the cursor", buffer = true })
vim.keymap.set("n", "<localleader>rl", M.run_line,
{ desc = "run line", buffer = true })
```

_These mappings only work inside of code blocks in quarto documents_

We get two mappings for running code by the cell, and another mapping for running code by line. Note
that Molten ships with a command `:MoltenEvaluateLine` which also runs a line of code. The
difference here is that `quarto_code_runner.run_line` is aware of code cells, and will not try to
run lines outside of a code cell.
Loading

0 comments on commit f7871bd

Please sign in to comment.