mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
fish shell integration
This commit is contained in:
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
A535B9DA299C569B0017E2E4 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A535B9D9299C569B0017E2E4 /* ErrorView.swift */; };
|
||||||
|
A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */ = {isa = PBXBuildFile; fileRef = A545D1A12A5772CE006E0AE4 /* shell-integration */; };
|
||||||
A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; };
|
A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; };
|
||||||
A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB529B6F47F0055DE60 /* AppState.swift */; };
|
A55B7BB629B6F47F0055DE60 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB529B6F47F0055DE60 /* AppState.swift */; };
|
||||||
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB729B6F53A0055DE60 /* Package.swift */; };
|
A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB729B6F53A0055DE60 /* Package.swift */; };
|
||||||
@ -27,6 +28,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
|
A535B9D9299C569B0017E2E4 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
|
||||||
|
A545D1A12A5772CE006E0AE4 /* shell-integration */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "shell-integration"; path = "../zig-out/share/shell-integration"; sourceTree = "<group>"; };
|
||||||
A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = "<group>"; };
|
A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = "<group>"; };
|
||||||
A55B7BB529B6F47F0055DE60 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
|
A55B7BB529B6F47F0055DE60 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
|
||||||
A55B7BB729B6F53A0055DE60 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
A55B7BB729B6F53A0055DE60 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
|
||||||
@ -90,6 +92,7 @@
|
|||||||
A5A1F8862A489D7400D1E8BC /* Resources */ = {
|
A5A1F8862A489D7400D1E8BC /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A545D1A12A5772CE006E0AE4 /* shell-integration */,
|
||||||
A5A1F8842A489D6800D1E8BC /* terminfo */,
|
A5A1F8842A489D6800D1E8BC /* terminfo */,
|
||||||
);
|
);
|
||||||
name = Resources;
|
name = Resources;
|
||||||
@ -198,6 +201,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A545D1A22A5772CE006E0AE4 /* shell-integration in Resources */,
|
||||||
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */,
|
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */,
|
||||||
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */,
|
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */,
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,91 @@
|
|||||||
#!/bin/fish
|
#!/bin/fish
|
||||||
|
#
|
||||||
|
# This shell script aims to be written in a way where it can't really fail
|
||||||
|
# or all failure scenarios are handled, so that we never leave the shell in
|
||||||
|
# a weird state. If you find a way to break this, please report a bug!
|
||||||
|
|
||||||
echo GHOSTTY INTEGRATION LOADING
|
function ghostty_restore_xdg_data_dir -d "restore the original XDG_DATA_DIR value"
|
||||||
|
# If we don't have our own data dir then we don't need to do anything.
|
||||||
|
if not set -q GHOSTTY_FISH_XDG_DIR
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# If the data dir isn't set at all then we don't need to do anything.
|
||||||
|
if not set -q XDG_DATA_DIRS
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# We need to do this so that XDG_DATA_DIRS turns into an array.
|
||||||
|
set --function --path xdg_data_dirs "$XDG_DATA_DIRS"
|
||||||
|
|
||||||
|
# If our data dir is in the list then remove it.
|
||||||
|
if set --function index (contains --index "$GHOSTTY_FISH_XDG_DIR" $xdg_data_dirs)
|
||||||
|
set --erase --function xdg_data_dirs[$index]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Re-export our data dir
|
||||||
|
if set -q xdg_data_dirs[1]
|
||||||
|
set --global --export --unpath XDG_DATA_DIRS "$xdg_data_dirs"
|
||||||
|
else
|
||||||
|
set --erase --global XDG_DATA_DIRS
|
||||||
|
end
|
||||||
|
|
||||||
|
set --erase GHOSTTY_FISH_XDG_DIR
|
||||||
|
end
|
||||||
|
|
||||||
|
function ghostty_exit -d "exit the shell integration setup"
|
||||||
|
functions -e ghostty_restore_xdg_data_dir
|
||||||
|
functions -e ghostty_exit
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# We always try to restore the XDG data dir
|
||||||
|
ghostty_restore_xdg_data_dir
|
||||||
|
|
||||||
|
# If we aren't interactive or we've already run, don't run.
|
||||||
|
status --is-interactive || ghostty_exit
|
||||||
|
|
||||||
|
# We do the full setup on the first prompt render. We do this so that other
|
||||||
|
# shell integrations that setup the prompt and modify things are able to run
|
||||||
|
# first. We want to run _last_.
|
||||||
|
function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
||||||
|
functions -e __ghostty_setup
|
||||||
|
|
||||||
|
# Change the cursor to a beam on prompt.
|
||||||
|
function __ghostty_set_cursor_beam --on-event fish_prompt -d "Set cursor shape"
|
||||||
|
echo -en "\e[5 q"
|
||||||
|
end
|
||||||
|
function __ghostty_reset_cursor --on-event fish_preexec -d "Reset cursor shape"
|
||||||
|
echo -en "\e[0 q"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Setup prompt marking
|
||||||
|
function __ghostty_mark_prompt_start --on-event fish_prompt --on-event fish_cancel --on-event fish_posterror
|
||||||
|
# If we never got the output end event, then we need to send it now.
|
||||||
|
if test "$__ghostty_prompt_state" != prompt-start
|
||||||
|
echo -en "\e]133;D\a"
|
||||||
|
end
|
||||||
|
|
||||||
|
set --global __ghostty_prompt_state prompt-start
|
||||||
|
echo -en "\e]133;A\a"
|
||||||
|
end
|
||||||
|
|
||||||
|
function __ghostty_mark_output_start --on-event fish_preexec
|
||||||
|
set --global __ghostty_prompt_state pre-exec
|
||||||
|
echo -en "\e]133;C\a"
|
||||||
|
end
|
||||||
|
|
||||||
|
function __ghostty_mark_output_end --on-event fish_postexec
|
||||||
|
set --global __ghostty_prompt_state post-exec
|
||||||
|
echo -en "\e]133;D;$status\a"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Enable fish to handle reflow because Ghostty clears the prompt on resize.
|
||||||
|
set --global fish_handle_reflow 1
|
||||||
|
|
||||||
|
# Initial calls for first prompt
|
||||||
|
__ghostty_set_cursor_beam
|
||||||
|
__ghostty_mark_prompt_start
|
||||||
|
end
|
||||||
|
|
||||||
|
ghostty_exit
|
||||||
|
@ -530,6 +530,9 @@ const Subprocess = struct {
|
|||||||
// Get our bundled resources directory, if it exists. We use this
|
// Get our bundled resources directory, if it exists. We use this
|
||||||
// for terminfo, shell-integration, etc.
|
// for terminfo, shell-integration, etc.
|
||||||
const resources_dir = try resourcesDir(alloc);
|
const resources_dir = try resourcesDir(alloc);
|
||||||
|
if (resources_dir) |dir| {
|
||||||
|
try env.put("GHOSTTY_RESOURCES_DIR", dir);
|
||||||
|
}
|
||||||
|
|
||||||
// Set our TERM var. This is a bit complicated because we want to use
|
// Set our TERM var. This is a bit complicated because we want to use
|
||||||
// the ghostty TERM value but we want to only do that if we have
|
// the ghostty TERM value but we want to only do that if we have
|
||||||
|
@ -46,7 +46,7 @@ fn setupFish(
|
|||||||
// Set an env var so we can remove this from XDG_DATA_DIRS later.
|
// Set an env var so we can remove this from XDG_DATA_DIRS later.
|
||||||
// This happens in the shell integration config itself. We do this
|
// This happens in the shell integration config itself. We do this
|
||||||
// so that our modifications don't interfere with other commands.
|
// so that our modifications don't interfere with other commands.
|
||||||
try env.put("GHOSTTY_FISH_DIR", integ_dir);
|
try env.put("GHOSTTY_FISH_XDG_DIR", integ_dir);
|
||||||
|
|
||||||
if (env.get("XDG_DATA_DIRS")) |old| {
|
if (env.get("XDG_DATA_DIRS")) |old| {
|
||||||
// We have an old value, We need to prepend our value to it.
|
// We have an old value, We need to prepend our value to it.
|
||||||
@ -62,6 +62,7 @@ fn setupFish(
|
|||||||
"{s}{c}{s}",
|
"{s}{c}{s}",
|
||||||
.{ integ_dir, std.fs.path.delimiter, old },
|
.{ integ_dir, std.fs.path.delimiter, old },
|
||||||
);
|
);
|
||||||
|
|
||||||
try env.put("XDG_DATA_DIRS", prepended);
|
try env.put("XDG_DATA_DIRS", prepended);
|
||||||
} else {
|
} else {
|
||||||
// No XDG_DATA_DIRS set, we just set it our desired value.
|
// No XDG_DATA_DIRS set, we just set it our desired value.
|
||||||
|
Reference in New Issue
Block a user