From 1fa830cc739c593030f8de31f75aad79053ae6e9 Mon Sep 17 00:00:00 2001 From: ilk Date: Thu, 16 May 2024 23:59:02 +0300 Subject: [PATCH] feat(shell-integration): add automatic integration for Elvish Fish automatic integration taken as an example. Just like fish, Elvish checks `XDG_DATA_DIRS` for its modules. Thus, Fish integration in zig is reused, and integration in Elvish now removes `GHOSTTY_FISH_XDG_DIR` environment variable on launch. --- src/config/Config.zig | 1 + src/shell-integration/README.md | 14 +++++++++++- .../elvish/lib/ghostty-integration.elv | 7 +++--- src/termio/shell_integration.zig | 22 +++++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/config/Config.zig b/src/config/Config.zig index 2d540e895..b6400ff9f 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -3414,6 +3414,7 @@ pub const ShellIntegration = enum { bash, fish, zsh, + elvish, }; /// Shell integration features diff --git a/src/shell-integration/README.md b/src/shell-integration/README.md index c27b45891..2ad83169a 100644 --- a/src/shell-integration/README.md +++ b/src/shell-integration/README.md @@ -19,9 +19,20 @@ its normal startup files, which becomes our script's responsibility (along with disabling POSIX mode). Bash shell integration can also be sourced manually from `bash/ghostty.bash`. - ### Elvish +For [Elvish](https://elv.sh), `$GHOSTTY_RESOURCES_DIR/src/shell-integration` +contains an `./elvish/lib/ghostty-integration.elv` file. + +Elvish, on startup, searches for paths defined in `XDG_DATA_DIRS` +variable for `./elvish/lib/*.elv` files and imports them. They are thus +made available for use as modules by way of `use `. + +Ghostty launches Elvish, passing the environment with `XDG_DATA_DIRS`prepended +with `$GHOSTTY_RESOURCES_DIR/src/shell-integration`. It contains +`./elvish/lib/ghostty-integration.elv`. The user can then import it +by `use ghostty-integration`, which will run the integration routines. + The [Elvish](https://elv.sh) shell integration is supported by the community and is not officially supported by Ghostty. We distribute it for ease of access and use but do not provide support for it. @@ -43,3 +54,4 @@ For `zsh`, Ghostty sets `ZDOTDIR` so that it loads our configuration from the `zsh` directory. The existing `ZDOTDIR` is retained so that after loading the Ghostty shell integration the normal Zsh loading sequence occurs. + diff --git a/src/shell-integration/elvish/lib/ghostty-integration.elv b/src/shell-integration/elvish/lib/ghostty-integration.elv index 6af878ba5..9e7f0bd5f 100644 --- a/src/shell-integration/elvish/lib/ghostty-integration.elv +++ b/src/shell-integration/elvish/lib/ghostty-integration.elv @@ -1,6 +1,6 @@ { fn restore-xdg-dirs { - var integration-dir = $E:GHOSTTY_FISH_XDG_DIR + var integration-dir = $E:GHOSTTY_INTEGRATION_DIR var xdg-dirs = [(str:split ':' $E:XDG_DATA_DIRS)] var len = (count $xdg-dirs) @@ -27,9 +27,9 @@ } else { set-env XDG_DATA_DIRS (str:join ':' $xdg-dirs) } - unset-env GHOSTTY_FISH_XDG_DIR + unset-env GHOSTTY_INTEGRATION_DIR } - if (and (has-env GHOSTTY_FISH_XDG_DIR) (has-env XDG_DATA_DIRS)) { + if (and (has-env GHOSTTY_INTEGRATION_DIR) (has-env XDG_DATA_DIRS)) { restore-xdg-dirs } } @@ -117,4 +117,3 @@ edit:add-var sudo~ $sudo-with-terminfo~ } } - diff --git a/src/termio/shell_integration.zig b/src/termio/shell_integration.zig index fb57595f0..e05c57a0f 100644 --- a/src/termio/shell_integration.zig +++ b/src/termio/shell_integration.zig @@ -12,6 +12,7 @@ pub const Shell = enum { bash, fish, zsh, + elvish, }; /// The result of setting up a shell integration. @@ -47,6 +48,7 @@ pub fn setup( .bash => "bash", .fish => "fish", .zsh => "zsh", + .elvish => "elvish", } else exe: { // The command can include arguments. Look for the first space // and use the basename of the first part as the command's exe. @@ -76,6 +78,14 @@ pub fn setup( }; } + if (std.mem.eql(u8, "elvish", exe)) { + try setupElvish(alloc_arena, resource_dir, env); + break :shell .{ + .shell = .elvish, + .command = command, + }; + } + if (std.mem.eql(u8, "zsh", exe)) { try setupZsh(resource_dir, env); break :shell .{ @@ -452,6 +462,18 @@ fn setupFish( } } +/// Setup the Elvish automatic shell integration. +/// This reuses integration primitives of Fish, as Elvish also +/// loads config in XDG_DATA_DIRS (except it imports +/// "./elvish/lib/*.elv" files). +fn setupElvish( + alloc_arena: Allocator, + resource_dir: []const u8, + env: *EnvMap, +) !void { + try setupFish(alloc_arena, resource_dir, env); +} + /// Setup the zsh automatic shell integration. This works by setting /// ZDOTDIR to our resources dir so that zsh will load our config. This /// config then loads the true user config.