├── screenshot.png ├── zellij-config.kdl ├── plugins ├── makefile.nu ├── ai.nu ├── exit.nu ├── init.nu └── yazi.nu ├── layout.kdl ├── helix.nu ├── flake.nix ├── flake.lock ├── run.nu └── README.md /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EmeraldPandaTurtle/zellix/HEAD/screenshot.png -------------------------------------------------------------------------------- /zellij-config.kdl: -------------------------------------------------------------------------------- 1 | on_force_close "quit" 2 | session_serialization false 3 | theme "catppuccin-mocha" 4 | pane_frames false 5 | -------------------------------------------------------------------------------- /plugins/makefile.nu: -------------------------------------------------------------------------------- 1 | export def init-makefile [] {} 2 | 3 | def main [] { 4 | try { ferrite } 5 | print "Press To Continue!" 6 | input -n 1 -s 7 | } 8 | -------------------------------------------------------------------------------- /plugins/ai.nu: -------------------------------------------------------------------------------- 1 | export def init-ai [] {} 2 | 3 | def --wrapped main [...args] { 4 | zellij run -c -f -- aichat ...$args 5 | } 6 | 7 | def --wrapped "main pane" [...args] { 8 | zellij run -c -d right -- aichat ...$args 9 | } 10 | -------------------------------------------------------------------------------- /plugins/exit.nu: -------------------------------------------------------------------------------- 1 | 2 | # Use this file to delete data that may not be deleted automatically 3 | # This would include any files that are temporary that aren't stored in the ZELLIX_TMP Folder. 4 | # In this example, nothing needs to be run. 5 | def main [] { } 6 | -------------------------------------------------------------------------------- /layout.kdl: -------------------------------------------------------------------------------- 1 | layout { 2 | default_tab_template { 3 | children 4 | pane size=1 borderless=true { 5 | plugin location="zellij:compact-bar" 6 | } 7 | } 8 | tab name="editor" focus=true { 9 | pane focus=true { 10 | name "editor" 11 | command "nu" 12 | args "-c" "nu ($env.ZELLIX_PATH + \"/helix.nu\")" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /plugins/init.nu: -------------------------------------------------------------------------------- 1 | use yazi.nu * 2 | use ai.nu * 3 | use makefile.nu * 4 | use bacon.nu * 5 | 6 | # Use this file to initialize any plugins and systems you need! 7 | # 8 | # The main use of this should be to 9 | # create files that would be used for config/data. 10 | def main [] { 11 | init-yazi 12 | init-ai 13 | init-makefile 14 | init-bacon 15 | } 16 | -------------------------------------------------------------------------------- /helix.nu: -------------------------------------------------------------------------------- 1 | try { nu ($env.ZELLIX_MOD + "/init.nu") } 2 | 3 | # Open helix at the given filepath. 4 | hx $env.ZELLIX_OPEN 5 | 6 | # Run exit code for the selected modules 7 | # This is a try block because exit.nu shouldn't be required 8 | try { nu ($env.ZELLIX_MOD + "/exit.nu") } 9 | 10 | # Kill the session, closing other panes as soon as helix closes 11 | zellij kill-session $env.ZELLIX_SESSION 12 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "nixpkgs"; 4 | flake-utils.url = "flake-utils"; 5 | }; 6 | 7 | outputs = { nixpkgs, flake-utils, ... }: 8 | flake-utils.lib.eachDefaultSystem (system: 9 | let 10 | pkgs = import nixpkgs { inherit system; }; 11 | in 12 | { 13 | packages.zl = pkgs.writeTextFile { 14 | name = "zl"; 15 | executable = true; 16 | destination = "/bin/zl"; 17 | text = 18 | builtins.readFile ./run.nu; 19 | }; 20 | } 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /plugins/yazi.nu: -------------------------------------------------------------------------------- 1 | # This is an example system to allow for the use of yazi as a 2 | # filepicker that supports multiple files, opening folders, 3 | # and re-opening the picker at the current path instead of the root project path. 4 | 5 | # This command can not do anything that would be temporary. 6 | # Example: Adding an Environment Variable here would not persist. 7 | export def init-yazi [] { 8 | } 9 | 10 | def main [current_buffer] { 11 | print $current_buffer 12 | mut current_path = $current_buffer | str join; 13 | if $current_path == "scratch" { 14 | $current_path = "./" 15 | } 16 | 17 | # Open yazi at the current path, and print the selected files to stdout. 18 | let paths = yazi --chooser-file=/dev/stdout $current_path 19 | 20 | # Split the files by rows. 21 | let command = ($paths | each {|line| $line | split row "\n"}) 22 | 23 | # Check if no files were selected, and exit if none are. 24 | if ($command | get 0 | str trim | is-empty) { 25 | exit 0 26 | } 27 | 28 | # Join the list of filepaths we had above to support writing the paths to helix. 29 | let command_str = $command | str join " " 30 | 31 | # Set up the string for the actual command. 32 | let run = ":open " + $command_str 33 | 34 | zellij action toggle-floating-panes # Select Helix In The System 35 | zellij action write 27 # Exit To Normal Mode 36 | zellij action write-chars $run # Write actual Command 37 | zellij action write 13 # Press Enter to run the command 38 | } 39 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "id": "flake-utils", 17 | "type": "indirect" 18 | } 19 | }, 20 | "nixpkgs": { 21 | "locked": { 22 | "lastModified": 0, 23 | "narHash": "sha256-NGqpVVxNAHwIicXpgaVqJEJWeyqzoQJ9oc8lnK9+WC4=", 24 | "path": "/nix/store/pgg4vm83q0kr4hxzcwhdgdiv2yfnh3dw-source", 25 | "type": "path" 26 | }, 27 | "original": { 28 | "id": "nixpkgs", 29 | "type": "indirect" 30 | } 31 | }, 32 | "root": { 33 | "inputs": { 34 | "flake-utils": "flake-utils", 35 | "nixpkgs": "nixpkgs" 36 | } 37 | }, 38 | "systems": { 39 | "locked": { 40 | "lastModified": 1681028828, 41 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 42 | "owner": "nix-systems", 43 | "repo": "default", 44 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 45 | "type": "github" 46 | }, 47 | "original": { 48 | "owner": "nix-systems", 49 | "repo": "default", 50 | "type": "github" 51 | } 52 | } 53 | }, 54 | "root": "root", 55 | "version": 7 56 | } 57 | -------------------------------------------------------------------------------- /run.nu: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nu 2 | def setup-files [session] { 3 | let path = "/tmp/zellix/" + $session 4 | 5 | # Ensure the session folder actually got deleted 6 | try { rm -r $path } 7 | 8 | # Create the session folder. 9 | mkdir $path 10 | } 11 | 12 | def main [config_path, filepath?, session?] { 13 | # Find the path of the zelix command. 14 | let path = $config_path 15 | $env.ZELLIX_PATH = $path 16 | 17 | let session = match $session { 18 | # Create a crazy, random set of characters for the session name 19 | null => (random chars --length 10) 20 | 21 | # Just use what was put for the session name. 22 | _ => $session 23 | } 24 | 25 | # Allow for zellix to function like the `hx` command, accepting a filepath if wanted. 26 | let filepath = match $filepath { 27 | null => ("./"), 28 | _ => $filepath 29 | } 30 | $env.ZELLIX_OPEN = $filepath 31 | 32 | # Create useful environment variables for users. 33 | $env.ZELLIX_SESSION = $session 34 | $env.ZELLIX_TMP = "/tmp/zellix/" + $session 35 | $env.ZELLIX_MOD = $env.ZELLIX_PATH + "/plugins" 36 | 37 | # Set up the tmp folder for the zellix session. 38 | setup-files $session 39 | 40 | # Set Layout And Config Paths for the zellij session 41 | let layout_path = $env.ZELLIX_PATH + "/layout.kdl" 42 | let config_path = $env.ZELLIX_PATH + "/zellij-config.kdl" 43 | 44 | # Create the zellij session 45 | zellij -s $session -n $layout_path -c $config_path 46 | 47 | # Delete The Session Folder 48 | rm -r $env.ZELLIX_TMP 49 | 50 | # Thank the user! 51 | print $"(ansi cb)Thank you for using Zellix!(ansi reset)" 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zellix 2 | A Simple, [NuShell](https://nushell.sh) Based "Plugin" system for Helix using the power of Zellij! 3 | ![screenshot](screenshot.png) 4 | 5 | # What does it do? 6 | Under the hood, it creates a special zellij session, focued on using auto-closing panes to support windows in helix. 7 | 8 | # Installation 9 | If you don't want to run the directory directly, you can install it using `ln` and `chmod`. First, navigate to the directory where `run.nu` is located. 10 | Run 11 | ```nu 12 | chmod +x run.sh 13 | ``` 14 | in your terminal to make the file runnable. Next, use 15 | ```nu 16 | ln -s run.sh ~/.local/bin/zellix` 17 | ``` 18 | to link run.nu to your local bin directory, then, to run, just use `zellix path/to/module` to run instead of having to use `nu ./run.nu path/to/module`. 19 | 20 | # Usage 21 | In order to actually run the system, you must run the shell file with the following parameters. 22 | `module`: The location of the actual module path, this is just a folder, which will be added to the environment to support using any module folder. 23 | `path`: An *optional* path for helix to open into. This is the same as typing `hx {file}` 24 | 25 | A simple example run, if currently inside of the cloned repository, you can run the program like this 26 | ```nu 27 | nu ./run.nu example/ 28 | ``` 29 | This will run the code with the example folder as the module. 30 | 31 | If you just want to try out zellix, clone the repository, ensure you have `zellij` and `helix` installed. 32 | Then, if you want to try out my configuration, you will need at least one of either `yazi` or `aichat`. 33 | You'll want to edit your helix configuration to use the following in a keybind, or you can run it in helix by pasting it. 34 | `:sh zellij run -c -f -x 10% -y 10% --width 80% --height 80% -- nu $ZELLIX_MOD/yazi.nu` Will run the yazi program, and replacing `yazi.nu` with `ai.nu` 35 | will run the AI Moudle. 36 | 37 | if you want to try how i use it, the following will add keybinds for both yazi and the ai module. 38 | ```toml 39 | [keys.normal.space.f] 40 | f = "file_picker" 41 | t = ":sh zellij run -c -f -x 10% -y 10% --width 80% --height 80% -- nu $ZELLIX_MOD/yazi.nu" 42 | 43 | [keys.normal.space.l] 44 | a = ":sh zellij run -c -f -x 10% -y 10% --width 80% --height 80% -- nu $ZELLIX_MOD/ai.nu" 45 | ``` 46 | 47 | ## Example Configuration 48 | Personally, I use nix with this, but the configuration is still very simple. 49 | Look at the [example](example), which I use for my daily driver with helix using 50 | [my dotfile configuration](https://github.com/TheEmeraldBee/PixelNix) with nixos and nix-darwin! 51 | 52 | # Creating Plugins 53 | For information on how to create plugins, check out the [wiki](https://github.com/TheEmeraldBee/zellix/wiki)! 54 | 55 | # Why does this exist? 56 | At the time of writing this, there is no plugin system for helix, and I dislike the configuration of neovim, 57 | so I created this to satiate my desire for more than just an editor systems that can still be controlled through my editor. 58 | 59 | # Wrote something awesome? 60 | Put in a pull request adding a link to a repository containing the code, and I'll look at pulling it in! 61 | 62 | # Awesome zellix 63 | - **Crickets** Get writing some awesome stuff. 64 | 65 | # Contributing 66 | At this time, the [example](example) directory is not accepting pull requests, 67 | as it is my personal usage of this system. But the core itself is welcome to changes to support more custom systems, as well 68 | as eventually gaining some form of library to better support easier creation of plugins! 69 | 70 | # WARNING 71 | At this time, this is a very rough implementation that hasn't been fully tested. 72 | If you choose to use this, please report **any** bugs you find during usage, and I will fix them ASAP. 73 | --------------------------------------------------------------------------------