Skip to content
1 change: 1 addition & 0 deletions configuration.nix
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ isMaximal: {
undotree.enable = isMaximal;
nvim-biscuits.enable = isMaximal;
grug-far-nvim.enable = isMaximal;
jupynvim.enable = false;

motion = {
hop.enable = true;
Expand Down
8 changes: 8 additions & 0 deletions docs/manual/release-notes/rl-26.12.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,11 @@
- `formatter/conform-nvim/presets/ruff`: fix `indent-width` option whose key
name was not recognized by `ruff format`, which in turn exited with an unknown
key error.

[jack-thesparrow](https://github.com/jack-thesparrow)

- Added {option}`vim.utility.jupynvim.enable` for [jupynvim], a Jupyter notebook
interface for Neovim with a native Rust backend. The default notebook
keybindings are exposed under `vim.utility.jupynvim.mappings`.

[jupynvim]: https://github.com/sheng-tse/jupynvim
37 changes: 37 additions & 0 deletions flake/pkgs/by-name/jupynvim-core/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
lib,
pins,
rustPlatform,
stdenv,
pkgs,
...
}: let
# From npins
pin = pins.jupynvim;

version = pin.revision;
src = pkgs.fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = pin.revision;
sha256 = pin.hash;
};
in
rustPlatform.buildRustPackage (finalAttrs: {
pname = "jupynvim-core";
inherit version src;

sourceRoot = "${finalAttrs.src.name}/core";

cargoHash = "sha256-cZKHYCFtzU1ULNp7TY/4/l6SrzGF3ghnBF5y5nvxuWw=";

doCheck = false;

env.RUSTFLAGS = lib.optionalString stdenv.hostPlatform.isDarwin "-C link-arg=-undefined -C link-arg=dynamic_lookup";

meta = {
description = "Native backend for jupynvim, a Jupyter notebook interface for Neovim";
homepage = "https://github.com/sheng-tse/jupynvim";
license = lib.licenses.mit;
mainProgram = "jupynvim-core";
};
})
Comment thread
jack-thesparrow marked this conversation as resolved.
36 changes: 36 additions & 0 deletions flake/pkgs/by-name/jupynvim/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
lib,
callPackage,
pins,
pkgs,
vimUtils,
...
}: let
# From npins
pin = pins.jupynvim;

version = pin.revision;
src = pkgs.fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = pin.revision;
sha256 = pin.hash;
};

jupynvim-core = callPackage ../jupynvim-core/package.nix {};
in
vimUtils.buildVimPlugin {
pname = "jupynvim";
inherit version src;

doCheck = false;

postInstall = ''
install -Dm755 ${jupynvim-core}/bin/jupynvim-core $out/core/target/release/jupynvim-core
'';

meta = {
description = "Jupyter notebooks in Neovim with a native Rust backend";
homepage = "https://github.com/sheng-tse/jupynvim";
license = lib.licenses.mit;
};
}
1 change: 1 addition & 0 deletions modules/plugins/utility/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
./icon-picker
./images
./grug-far-nvim
./jupynvim
./leetcode-nvim
./mkdir
./motion
Expand Down
66 changes: 66 additions & 0 deletions modules/plugins/utility/jupynvim/config.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
config,
lib,
...
}: let
inherit (lib.attrsets) recursiveUpdate;
inherit (lib.modules) mkIf;

cfg = config.vim.utility.jupynvim;
in {
config = mkIf cfg.enable {
vim = {
lazy.plugins.jupynvim = {
package = "jupynvim";
setupModule = "jupynvim";
event = [
{
event = "BufReadCmd";
pattern = "*.ipynb";
}
{
event = "BufNewFile";
pattern = "*.ipynb";
}
];
setupOpts =
recursiveUpdate
{
keymaps = {
run_advance = cfg.mappings.runAdvance;
run_stay = cfg.mappings.runStay;
run_advance_alt = cfg.mappings.runAdvanceAlt;
run_all = cfg.mappings.runAll;
run_above = cfg.mappings.runAbove;
run_below = cfg.mappings.runBelow;
add_above = cfg.mappings.addAbove;
add_below = cfg.mappings.addBelow;
delete_cell = cfg.mappings.deleteCell;
move_up = cfg.mappings.moveUp;
move_down = cfg.mappings.moveDown;
to_markdown = cfg.mappings.toMarkdown;
to_code = cfg.mappings.toCode;
pick_kernel = cfg.mappings.pickKernel;
start_kernel = cfg.mappings.startKernel;
stop_kernel = cfg.mappings.stopKernel;
interrupt_kernel = cfg.mappings.interruptKernel;
restart_kernel = cfg.mappings.restartKernel;
clear_output = cfg.mappings.clearOutput;
clear_all = cfg.mappings.clearAll;
next_cell = cfg.mappings.nextCell;
prev_cell = cfg.mappings.prevCell;
next_image = cfg.mappings.nextImage;
prev_image = cfg.mappings.prevImage;
enter_output_dn = cfg.mappings.enterOutputDn;
enter_output_up = cfg.mappings.enterOutputUp;
save_image = cfg.mappings.saveImage;
delete_image = cfg.mappings.deleteImage;
refresh = cfg.mappings.refresh;
open_link = cfg.mappings.openLink;
};
}
cfg.setupOpts;
};
};
};
}
6 changes: 6 additions & 0 deletions modules/plugins/utility/jupynvim/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
imports = [
./jupynvim.nix
./config.nix
];
}
124 changes: 124 additions & 0 deletions modules/plugins/utility/jupynvim/jupynvim.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) nullOr str bool enum ints listOf;
inherit (lib.nvim.types) mkPluginSetupOption;
inherit (config.vim.lib) mkMappingOption;
in {
options.vim.utility.jupynvim = {
enable = mkEnableOption ''
jupynvim, a Jupyter notebook interface for Neovim with a native Rust backend.
See <https://github.com/sheng-tse/jupynvim#configuration> for all configuration options.
'';

setupOpts = mkPluginSetupOption "jupynvim" {
log_level = mkOption {
type = enum ["trace" "debug" "info" "warn" "error"];
default = "info";
description = "Verbosity for both the Rust backend and the Lua frontend.";
};

image_renderer = mkOption {
type = enum ["placeholder" "kitty" "chafa"];
default = "placeholder";
description = ''
How code-cell outputs and embedded markdown images are rendered.

* `placeholder` - uses the Kitty Unicode placeholder protocol. The image is
anchored to buffer text and stays put when scrolling. Required for animated
GIFs.
* `kitty` - uses direct kitty placement. Lives at fixed screen coordinates and
does not follow scroll.
* `chafa` - an ASCII-art fallback for terminals without graphics support.
'';
};

image_rows = mkOption {
type = ints.u16;
default = 16;
description = "Inline image grid size in terminal cells (rows).";
};

image_cols = mkOption {
type = ints.u16;
default = 48;
description = "Inline image grid size in terminal cells (cols).";
};

core_path = mkOption {
type = nullOr str;
default = null;
description = ''
Override the path to the `jupynvim-core` binary. Auto-detected from the
plugin directory if unset.
'';
};

disable_default_keymaps = mkOption {
type = bool;
default = false;
description = "Skip the entire default keymap set if you want to bind everything yourself.";
};

auto_venv = mkOption {
type = bool;
default = true;
description = ''
Walk up from the notebook's directory to find a `.venv` and use its interpreter
as the kernel when `ipykernel` is installed there.
'';
};

lsp_blocklist = mkOption {
type = listOf str;
default = [];
description = ''
LSP servers to skip on jupynvim buffers. Useful for servers that misbehave on
`.ipynb` URIs without advertising notebook capability.
'';
};

smooth_scroll = mkOption {
type = bool;
default = false;
description = "Restore animated (smooth) scrolling inside notebook buffers.";
};
};

mappings = {
runAdvance = mkMappingOption "Run the current cell and advance to the next one" "<S-CR>";
runStay = mkMappingOption "Run the current cell and stay on it" "<C-CR>";
runAdvanceAlt = mkMappingOption "Run the current cell and advance (alternative binding)" "<leader>nr";
runAll = mkMappingOption "Run all cells" "<leader>nR";
runAbove = mkMappingOption "Run all cells above the cursor" "<leader>nA";
runBelow = mkMappingOption "Run all cells below the cursor" "<leader>nB";
addAbove = mkMappingOption "Add a cell above the cursor" "<leader>na";
addBelow = mkMappingOption "Add a cell below the cursor" "<leader>nb";
deleteCell = mkMappingOption "Delete the current cell" ("<leader>n" + "d");
moveUp = mkMappingOption "Move the current cell up" "<leader>nk";
moveDown = mkMappingOption "Move the current cell down" "<leader>nj";
toMarkdown = mkMappingOption "Convert the current cell to markdown" "<leader>nm";
toCode = mkMappingOption "Convert the current cell to code" "<leader>ny";
pickKernel = mkMappingOption "Pick a kernel for the notebook" "<leader>nK";
startKernel = mkMappingOption "Start the notebook kernel" "<leader>ns";
stopKernel = mkMappingOption "Stop the notebook kernel" "<leader>nS";
interruptKernel = mkMappingOption "Interrupt the kernel" "<leader>ni";
restartKernel = mkMappingOption "Restart the kernel" "<leader>nx";
clearOutput = mkMappingOption "Clear the current cell's output" "<leader>nc";
clearAll = mkMappingOption "Clear all cell outputs" "<leader>nC";
nextCell = mkMappingOption "Jump to the next cell" "]c";
prevCell = mkMappingOption "Jump to the previous cell" "[c";
nextImage = mkMappingOption "Jump to the next image cell" "]i";
prevImage = mkMappingOption "Jump to the previous image cell" "[i";
enterOutputDn = mkMappingOption "Enter the output below the cursor" "<C-j>";
enterOutputUp = mkMappingOption "Enter the output above the cursor" "<C-k>";
saveImage = mkMappingOption "Save the cell image" "<leader>nI";
deleteImage = mkMappingOption "Delete the cell image" "<leader>nD";
refresh = mkMappingOption "Refresh the notebook display" "<leader>nL";
openLink = mkMappingOption "Open the link under the cursor" "gx";
};
};
}
2 changes: 1 addition & 1 deletion modules/wrapper/build/config.nix
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
# Get plugins built from source from self.packages
# If adding a new plugin to be built from source, it must also be inherited
# here.
inherit (inputs.self.packages.${pkgs.stdenv.system}) blink-cmp avante-nvim cord-nvim;
inherit (inputs.self.packages.${pkgs.stdenv.system}) blink-cmp avante-nvim cord-nvim jupynvim;
};

buildConfigPlugins = plugins:
Expand Down
13 changes: 13 additions & 0 deletions npins/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,19 @@
"url": "https://github.com/lukas-reineke/indent-blankline.nvim/archive/d28a3f70721c79e3c5f6693057ae929f3d9c0a03.tar.gz",
"hash": "sha256-Vc79ff416uJFqKH8zlM1y208SxaQGpQPqGVbiz5Vflg="
},
"jupynvim": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "sheng-tse",
"repo": "jupynvim"
},
"branch": "main",
"submodules": false,
"revision": "47a31d9a7bcbe1f68a8cc245f28382ad9df11b65",
"url": "https://github.com/sheng-tse/jupynvim/archive/47a31d9a7bcbe1f68a8cc245f28382ad9df11b65.tar.gz",
"hash": "sha256-DJinRfxOoSj8xnWUnpPd14mA8zMQmLhavmJsUz4h2XQ="
},
"kulala-nvim": {
"type": "GitRelease",
"repository": {
Expand Down
Loading