@wangyaoshen/remux 0.3.8-dev.29e114b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +38 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +28 -0
- package/.github/dependabot.yml +33 -0
- package/.github/workflows/ci.yml +65 -0
- package/.github/workflows/deploy.yml +65 -0
- package/.github/workflows/publish.yml +312 -0
- package/.github/workflows/release-please.yml +21 -0
- package/.gitmodules +3 -0
- package/.nvmrc +1 -0
- package/.release-please-manifest.json +3 -0
- package/CLAUDE.md +104 -0
- package/Dockerfile +23 -0
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/apps/ios/Config/signing.xcconfig +4 -0
- package/apps/ios/Package.swift +26 -0
- package/apps/ios/Remux.xcodeproj/project.pbxproj +477 -0
- package/apps/ios/Remux.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/Contents.json +23 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_1024x1024.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_120x120.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_152x152.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_167x167.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_180x180.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_20x20.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_29x29.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_40x40.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_58x58.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_60x60.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_76x76.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_80x80.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/AppIcon.appiconset/icon_87x87.png +0 -0
- package/apps/ios/Sources/Remux/Assets.xcassets/Contents.json +6 -0
- package/apps/ios/Sources/Remux/Extensions/FaceIDManager.swift +29 -0
- package/apps/ios/Sources/Remux/Extensions/InspectCache.swift +66 -0
- package/apps/ios/Sources/Remux/MainTabView.swift +32 -0
- package/apps/ios/Sources/Remux/Remux.entitlements +8 -0
- package/apps/ios/Sources/Remux/RemuxiOSApp.swift +14 -0
- package/apps/ios/Sources/Remux/RootView.swift +130 -0
- package/apps/ios/Sources/Remux/Views/Control/ControlView.swift +102 -0
- package/apps/ios/Sources/Remux/Views/Inspect/InspectView.swift +98 -0
- package/apps/ios/Sources/Remux/Views/Live/LiveTerminalView.swift +132 -0
- package/apps/ios/Sources/Remux/Views/Now/NowView.swift +173 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/ManualConnectView.swift +55 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/OnboardingView.swift +70 -0
- package/apps/ios/Sources/Remux/Views/Onboarding/QRScannerView.swift +92 -0
- package/apps/ios/Sources/Remux/Views/Settings/MeView.swift +136 -0
- package/apps/macos/Package.swift +37 -0
- package/apps/macos/Resources/shell-integration/bash/bash-preexec.sh +382 -0
- package/apps/macos/Resources/shell-integration/bash/ghostty.bash +315 -0
- package/apps/macos/Resources/shell-integration/elvish/lib/ghostty-integration.elv +191 -0
- package/apps/macos/Resources/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish +246 -0
- package/apps/macos/Resources/shell-integration/nushell/vendor/autoload/ghostty.nu +110 -0
- package/apps/macos/Resources/shell-integration/zsh/.zshenv +61 -0
- package/apps/macos/Resources/shell-integration/zsh/ghostty-integration +458 -0
- package/apps/macos/Resources/terminfo/67/ghostty +0 -0
- package/apps/macos/Resources/terminfo/78/xterm-ghostty +0 -0
- package/apps/macos/Sources/Remux/AppDelegate.swift +257 -0
- package/apps/macos/Sources/Remux/CrashReporter.swift +210 -0
- package/apps/macos/Sources/Remux/FinderIntegration.swift +117 -0
- package/apps/macos/Sources/Remux/GhosttyConfig.swift +311 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/ShortcutAction.swift +115 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/ShortcutSettingsView.swift +271 -0
- package/apps/macos/Sources/Remux/KeyboardShortcuts/StoredShortcut.swift +149 -0
- package/apps/macos/Sources/Remux/MainContentView.swift +308 -0
- package/apps/macos/Sources/Remux/MenuBarManager.swift +275 -0
- package/apps/macos/Sources/Remux/NotificationManager.swift +145 -0
- package/apps/macos/Sources/Remux/PortScanner.swift +152 -0
- package/apps/macos/Sources/Remux/RemuxApp.swift +13 -0
- package/apps/macos/Sources/Remux/SSHDetector.swift +151 -0
- package/apps/macos/Sources/Remux/SessionPersistence.swift +226 -0
- package/apps/macos/Sources/Remux/SocketController.swift +258 -0
- package/apps/macos/Sources/Remux/UpdateChecker.swift +152 -0
- package/apps/macos/Sources/Remux/Views/CommandPalette.swift +198 -0
- package/apps/macos/Sources/Remux/Views/ConnectionView.swift +84 -0
- package/apps/macos/Sources/Remux/Views/InspectView.swift +127 -0
- package/apps/macos/Sources/Remux/Views/SettingsView.swift +77 -0
- package/apps/macos/Sources/Remux/Views/Sidebar/SidebarView.swift +410 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/BrowserPanel.swift +193 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/MarkdownPanel.swift +277 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/PanelProtocol.swift +14 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/SplitNode.swift +149 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/SplitView.swift +234 -0
- package/apps/macos/Sources/Remux/Views/SplitTree/TerminalPanel.swift +26 -0
- package/apps/macos/Sources/Remux/Views/TabBarView.swift +94 -0
- package/apps/macos/Sources/Remux/Views/Terminal/ClipboardHelper.swift +101 -0
- package/apps/macos/Sources/Remux/Views/Terminal/CopyModeOverlay.swift +325 -0
- package/apps/macos/Sources/Remux/Views/Terminal/GhosttyNativeTerminalView.swift +39 -0
- package/apps/macos/Sources/Remux/Views/Terminal/GhosttyNativeView.swift +559 -0
- package/apps/macos/Sources/Remux/Views/Terminal/SurfaceSearchOverlay.swift +109 -0
- package/apps/macos/Sources/Remux/Views/Terminal/TerminalContainerView.swift +95 -0
- package/apps/macos/Sources/Remux/Views/Terminal/TerminalRelay.swift +117 -0
- package/build.mjs +33 -0
- package/native/android/DecodeGoldenPayloads.kt +487 -0
- package/native/android/ProtocolModels.kt +188 -0
- package/native/ios/DecodeGoldenPayloads.swift +711 -0
- package/native/ios/ProtocolModels.swift +200 -0
- package/package.json +45 -0
- package/packages/RemuxKit/Package.swift +27 -0
- package/packages/RemuxKit/Sources/RemuxKit/Device/DeviceManager.swift +27 -0
- package/packages/RemuxKit/Sources/RemuxKit/Models/ProtocolModels.swift +206 -0
- package/packages/RemuxKit/Sources/RemuxKit/Networking/MessageRouter.swift +108 -0
- package/packages/RemuxKit/Sources/RemuxKit/Networking/RemuxConnection.swift +395 -0
- package/packages/RemuxKit/Sources/RemuxKit/State/RemuxState.swift +188 -0
- package/packages/RemuxKit/Sources/RemuxKit/Storage/KeychainStore.swift +142 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/GhosttyBridge.swift +145 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/GhosttyTerminalView.swift +35 -0
- package/packages/RemuxKit/Sources/RemuxKit/Terminal/Resources/ghostty-terminal.html +91 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/ConnectionIntegrationTest.swift +74 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/KeychainStoreTests.swift +81 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/ProtocolModelsTests.swift +179 -0
- package/packages/RemuxKit/Tests/RemuxKitTests/RemuxStateTests.swift +62 -0
- package/playwright.config.ts +17 -0
- package/pnpm-lock.yaml +1588 -0
- package/pty-daemon.js +303 -0
- package/release-please-config.json +14 -0
- package/scripts/auto-deploy.sh +46 -0
- package/scripts/build-dmg.sh +121 -0
- package/scripts/build-ghostty-kit.sh +43 -0
- package/scripts/check-active-terminology.mjs +132 -0
- package/scripts/setup-ci-secrets.sh +80 -0
- package/scripts/sync-ghostty-web.sh +28 -0
- package/scripts/upload-testflight.sh +100 -0
- package/server.js +7074 -0
- package/src/adapters/agent-events.ts +246 -0
- package/src/adapters/claude-code.ts +158 -0
- package/src/adapters/codex.ts +210 -0
- package/src/adapters/generic-shell.ts +58 -0
- package/src/adapters/index.ts +15 -0
- package/src/adapters/registry.ts +99 -0
- package/src/adapters/types.ts +41 -0
- package/src/auth.ts +174 -0
- package/src/e2ee.ts +236 -0
- package/src/git-service.ts +168 -0
- package/src/message-buffer.ts +137 -0
- package/src/pty-daemon.ts +357 -0
- package/src/push.ts +127 -0
- package/src/renderers.ts +455 -0
- package/src/server.ts +2407 -0
- package/src/service.ts +226 -0
- package/src/session.ts +978 -0
- package/src/store.ts +1422 -0
- package/src/team.ts +123 -0
- package/src/tunnel.ts +126 -0
- package/src/types.d.ts +50 -0
- package/src/vt-tracker.ts +188 -0
- package/src/workspace-head.ts +144 -0
- package/src/workspace.ts +153 -0
- package/src/ws-handler.ts +1526 -0
- package/start.ps1 +83 -0
- package/tests/adapters.test.js +171 -0
- package/tests/auth.test.js +243 -0
- package/tests/codex-adapter.test.js +535 -0
- package/tests/durable-stream.test.js +153 -0
- package/tests/e2e/app.spec.js +530 -0
- package/tests/e2ee.test.js +325 -0
- package/tests/message-buffer.test.js +245 -0
- package/tests/message-routing.test.js +305 -0
- package/tests/pty-daemon.test.js +346 -0
- package/tests/push.test.js +281 -0
- package/tests/renderers.test.js +391 -0
- package/tests/search-shell.test.js +499 -0
- package/tests/server.test.js +882 -0
- package/tests/service.test.js +267 -0
- package/tests/store.test.js +369 -0
- package/tests/tunnel.test.js +67 -0
- package/tests/workspace-head.test.js +116 -0
- package/tests/workspace.test.js +417 -0
- package/tsconfig.backend.json +11 -0
- package/tsconfig.json +15 -0
- package/tui/client/client_test.go +125 -0
- package/tui/client/connection.go +342 -0
- package/tui/client/host_manager.go +141 -0
- package/tui/config/cache.go +81 -0
- package/tui/config/config.go +53 -0
- package/tui/config/config_test.go +89 -0
- package/tui/go.mod +32 -0
- package/tui/go.sum +50 -0
- package/tui/main.go +261 -0
- package/tui/tests/integration_test.go +283 -0
- package/tui/ui/model.go +310 -0
- package/vitest.config.js +10 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
{
|
|
2
|
+
use platform
|
|
3
|
+
use str
|
|
4
|
+
|
|
5
|
+
# Clean up XDG_DATA_DIRS by removing GHOSTTY_SHELL_INTEGRATION_XDG_DIR
|
|
6
|
+
if (and (has-env GHOSTTY_SHELL_INTEGRATION_XDG_DIR) (has-env XDG_DATA_DIRS)) {
|
|
7
|
+
set-env XDG_DATA_DIRS (str:replace $E:GHOSTTY_SHELL_INTEGRATION_XDG_DIR":" "" $E:XDG_DATA_DIRS)
|
|
8
|
+
unset-env GHOSTTY_SHELL_INTEGRATION_XDG_DIR
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
# List of enabled shell integration features
|
|
12
|
+
var features = [(str:split ',' $E:GHOSTTY_SHELL_FEATURES)]
|
|
13
|
+
|
|
14
|
+
# State tracking for semantic prompt sequences
|
|
15
|
+
# Values: 'prompt-start', 'pre-exec', 'post-exec'
|
|
16
|
+
fn set-prompt-state {|new| set-env __ghostty_prompt_state $new }
|
|
17
|
+
|
|
18
|
+
fn mark-prompt-start {
|
|
19
|
+
if (not-eq $E:__ghostty_prompt_state 'prompt-start') {
|
|
20
|
+
printf "\e]133;D;aid="$pid"\a"
|
|
21
|
+
}
|
|
22
|
+
set-prompt-state 'prompt-start'
|
|
23
|
+
printf "\e]133;A;aid="$pid"\a"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn mark-output-start {|_|
|
|
27
|
+
set-prompt-state 'pre-exec'
|
|
28
|
+
printf "\e]133;C\a"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn mark-output-end {|cmd-info|
|
|
32
|
+
set-prompt-state 'post-exec'
|
|
33
|
+
|
|
34
|
+
var exit-status = 0
|
|
35
|
+
|
|
36
|
+
# in case of error: retrieve exit status,
|
|
37
|
+
# unless does not exist (= builtin function failure), then default to 1
|
|
38
|
+
if (not-eq $nil $cmd-info[error]) {
|
|
39
|
+
set exit-status = 1
|
|
40
|
+
|
|
41
|
+
if (has-key $cmd-info[error] reason) {
|
|
42
|
+
if (has-key $cmd-info[error][reason] exit-status) {
|
|
43
|
+
set exit-status = $cmd-info[error][reason][exit-status]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
printf "\e]133;D;"$exit-status";aid="$pid"\a"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# NOTE: OSC 133;B (end of prompt, start of input) cannot be reliably
|
|
52
|
+
# implemented at the script level in Elvish. The prompt function's output is
|
|
53
|
+
# escaped, and writing to /dev/tty has timing issues because Elvish renders
|
|
54
|
+
# its prompts on a background thread. Full semantic prompt support requires a
|
|
55
|
+
# native implementation: https://github.com/elves/elvish/pull/1917
|
|
56
|
+
|
|
57
|
+
fn sudo-with-terminfo {|@args|
|
|
58
|
+
var sudoedit = $false
|
|
59
|
+
for arg $args {
|
|
60
|
+
if (str:has-prefix $arg --) {
|
|
61
|
+
if (eq $arg --edit) {
|
|
62
|
+
set sudoedit = $true
|
|
63
|
+
break
|
|
64
|
+
}
|
|
65
|
+
} elif (str:has-prefix $arg -) {
|
|
66
|
+
if (str:contains (str:trim-prefix $arg -) e) {
|
|
67
|
+
set sudoedit = $true
|
|
68
|
+
break
|
|
69
|
+
}
|
|
70
|
+
} elif (not (str:contains $arg =)) {
|
|
71
|
+
break
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (not $sudoedit) { set args = [ --preserve-env=TERMINFO $@args ] }
|
|
76
|
+
(external sudo) $@args
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fn ssh-integration {|@args|
|
|
80
|
+
var ssh-term = "xterm-256color"
|
|
81
|
+
var ssh-opts = []
|
|
82
|
+
|
|
83
|
+
# Configure environment variables for remote session
|
|
84
|
+
if (has-value $features ssh-env) {
|
|
85
|
+
set ssh-opts = (conj $ssh-opts ^
|
|
86
|
+
-o "SetEnv COLORTERM=truecolor" ^
|
|
87
|
+
-o "SendEnv TERM_PROGRAM TERM_PROGRAM_VERSION")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (has-value $features ssh-terminfo) {
|
|
91
|
+
var ssh-user = ""
|
|
92
|
+
var ssh-hostname = ""
|
|
93
|
+
|
|
94
|
+
# Parse ssh config
|
|
95
|
+
for line [((external ssh) -G $@args)] {
|
|
96
|
+
var parts = [(str:fields $line)]
|
|
97
|
+
if (> (count $parts) 1) {
|
|
98
|
+
var ssh-key = $parts[0]
|
|
99
|
+
var ssh-value = $parts[1]
|
|
100
|
+
if (eq $ssh-key user) {
|
|
101
|
+
set ssh-user = $ssh-value
|
|
102
|
+
} elif (eq $ssh-key hostname) {
|
|
103
|
+
set ssh-hostname = $ssh-value
|
|
104
|
+
}
|
|
105
|
+
if (and (not-eq $ssh-user "") (not-eq $ssh-hostname "")) {
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (not-eq $ssh-hostname "") {
|
|
112
|
+
var ghostty = $E:GHOSTTY_BIN_DIR/"ghostty"
|
|
113
|
+
var ssh-target = $ssh-user"@"$ssh-hostname
|
|
114
|
+
|
|
115
|
+
# Check if terminfo is already cached
|
|
116
|
+
if (bool ?($ghostty +ssh-cache --host=$ssh-target)) {
|
|
117
|
+
set ssh-term = "xterm-ghostty"
|
|
118
|
+
} elif (has-external infocmp) {
|
|
119
|
+
var ssh-terminfo = ((external infocmp) -0 -x xterm-ghostty 2>/dev/null | slurp)
|
|
120
|
+
|
|
121
|
+
if (not-eq $ssh-terminfo "") {
|
|
122
|
+
echo "Setting up xterm-ghostty terminfo on "$ssh-hostname"..." >&2
|
|
123
|
+
|
|
124
|
+
use os
|
|
125
|
+
var ssh-cpath-dir = (os:temp-dir "ghostty-ssh-"$ssh-user".*")
|
|
126
|
+
var ssh-cpath = $ssh-cpath-dir"/socket"
|
|
127
|
+
|
|
128
|
+
if (bool ?(echo $ssh-terminfo | (external ssh) $@ssh-opts -o ControlMaster=yes -o ControlPath=$ssh-cpath -o ControlPersist=60s $@args '
|
|
129
|
+
infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
|
|
130
|
+
command -v tic >/dev/null 2>&1 || exit 1
|
|
131
|
+
mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
|
|
132
|
+
exit 1
|
|
133
|
+
' 2>/dev/null)) {
|
|
134
|
+
set ssh-term = "xterm-ghostty"
|
|
135
|
+
set ssh-opts = (conj $ssh-opts -o ControlPath=$ssh-cpath)
|
|
136
|
+
|
|
137
|
+
# Cache successful installation
|
|
138
|
+
$ghostty +ssh-cache --add=$ssh-target >/dev/null
|
|
139
|
+
} else {
|
|
140
|
+
echo "Warning: Failed to install terminfo." >&2
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
echo "Warning: Could not generate terminfo data." >&2
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
echo "Warning: ghostty command not available for cache management." >&2
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
with [E:TERM = $ssh-term] {
|
|
152
|
+
(external ssh) $@ssh-opts $@args
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
defer {
|
|
157
|
+
mark-prompt-start
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
set edit:before-readline = (conj $edit:before-readline $mark-prompt-start~)
|
|
161
|
+
set edit:after-readline = (conj $edit:after-readline $mark-output-start~)
|
|
162
|
+
set edit:after-command = (conj $edit:after-command $mark-output-end~)
|
|
163
|
+
|
|
164
|
+
if (str:contains $E:GHOSTTY_SHELL_FEATURES "cursor") {
|
|
165
|
+
var cursor = "5" # blinking bar
|
|
166
|
+
if (has-value $features cursor:steady) {
|
|
167
|
+
set cursor = "6" # steady bar
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
fn beam { printf "\e["$cursor" q" }
|
|
171
|
+
fn reset { printf "\e[0 q" }
|
|
172
|
+
set edit:before-readline = (conj $edit:before-readline $beam~)
|
|
173
|
+
set edit:after-readline = (conj $edit:after-readline {|_| reset })
|
|
174
|
+
}
|
|
175
|
+
if (and (has-value $features path) (has-env GHOSTTY_BIN_DIR)) {
|
|
176
|
+
if (not (has-value $paths $E:GHOSTTY_BIN_DIR)) {
|
|
177
|
+
set paths = [$@paths $E:GHOSTTY_BIN_DIR]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (and (has-value $features sudo) (not-eq "" $E:TERMINFO) (has-external sudo)) {
|
|
181
|
+
edit:add-var sudo~ $sudo-with-terminfo~
|
|
182
|
+
}
|
|
183
|
+
if (and (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-) (has-external ssh)) {
|
|
184
|
+
edit:add-var ssh~ $ssh-integration~
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Report changes to the current directory.
|
|
188
|
+
fn report-pwd { printf "\e]7;kitty-shell-cwd://%s%s\a" (platform:hostname) $pwd }
|
|
189
|
+
set after-chdir = (conj $after-chdir {|_| report-pwd })
|
|
190
|
+
report-pwd
|
|
191
|
+
}
|
package/apps/macos/Resources/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# This shell script aims to be written in a way where it can't really fail
|
|
2
|
+
# or all failure scenarios are handled, so that we never leave the shell in
|
|
3
|
+
# a weird state. If you find a way to break this, please report a bug!
|
|
4
|
+
|
|
5
|
+
function ghostty_restore_xdg_data_dir -d "restore the original XDG_DATA_DIR value"
|
|
6
|
+
# If we don't have our own data dir then we don't need to do anything.
|
|
7
|
+
if not set -q GHOSTTY_SHELL_INTEGRATION_XDG_DIR
|
|
8
|
+
return
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# If the data dir isn't set at all then we don't need to do anything.
|
|
12
|
+
if not set -q XDG_DATA_DIRS
|
|
13
|
+
return
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# We need to do this so that XDG_DATA_DIRS turns into an array.
|
|
17
|
+
set --function --path xdg_data_dirs "$XDG_DATA_DIRS"
|
|
18
|
+
|
|
19
|
+
# If our data dir is in the list then remove it.
|
|
20
|
+
if set --function index (contains --index "$GHOSTTY_SHELL_INTEGRATION_XDG_DIR" $xdg_data_dirs)
|
|
21
|
+
set --erase --function xdg_data_dirs[$index]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Re-export our data dir
|
|
25
|
+
if set -q xdg_data_dirs[1]
|
|
26
|
+
set --global --export --unpath XDG_DATA_DIRS "$xdg_data_dirs"
|
|
27
|
+
else
|
|
28
|
+
set --erase --global XDG_DATA_DIRS
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
set --erase GHOSTTY_SHELL_INTEGRATION_XDG_DIR
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
function ghostty_exit -d "exit the shell integration setup"
|
|
35
|
+
functions -e ghostty_restore_xdg_data_dir
|
|
36
|
+
functions -e ghostty_exit
|
|
37
|
+
exit 0
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# We always try to restore the XDG data dir
|
|
41
|
+
ghostty_restore_xdg_data_dir
|
|
42
|
+
|
|
43
|
+
# If we aren't interactive or we've already run, don't run.
|
|
44
|
+
status --is-interactive || ghostty_exit
|
|
45
|
+
|
|
46
|
+
# We do the full setup on the first prompt render. We do this so that other
|
|
47
|
+
# shell integrations that setup the prompt and modify things are able to run
|
|
48
|
+
# first. We want to run _last_.
|
|
49
|
+
function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|
50
|
+
functions -e __ghostty_setup
|
|
51
|
+
|
|
52
|
+
set --local features (string split , $GHOSTTY_SHELL_FEATURES)
|
|
53
|
+
|
|
54
|
+
# Parse the fish version for feature detection.
|
|
55
|
+
# Default to 0.0 if version is unavailable or malformed.
|
|
56
|
+
set -l fish_major 0
|
|
57
|
+
set -l fish_minor 0
|
|
58
|
+
if set -q version[1]
|
|
59
|
+
set -l fish_ver (string match -r '(\d+)\.(\d+)' -- $version[1])
|
|
60
|
+
if set -q fish_ver[2]; and test -n "$fish_ver[2]"
|
|
61
|
+
set fish_major "$fish_ver[2]"
|
|
62
|
+
end
|
|
63
|
+
if set -q fish_ver[3]; and test -n "$fish_ver[3]"
|
|
64
|
+
set fish_minor "$fish_ver[3]"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Our OSC133A (prompt start) sequence. If we're using Fish >= 4.1
|
|
69
|
+
# then it supports click_events so we enable that.
|
|
70
|
+
set -g __ghostty_prompt_start_mark "\e]133;A\a"
|
|
71
|
+
if test "$fish_major" -gt 4; or test "$fish_major" -eq 4 -a "$fish_minor" -ge 1
|
|
72
|
+
set -g __ghostty_prompt_start_mark "\e]133;A;click_events=1\a"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if string match -q 'cursor*' -- $features
|
|
76
|
+
set -l cursor 5 # blinking bar
|
|
77
|
+
contains cursor:steady $features && set cursor 6 # steady bar
|
|
78
|
+
|
|
79
|
+
# Change the cursor to a beam on prompt.
|
|
80
|
+
function __ghostty_set_cursor_beam --on-event fish_prompt -V cursor -d "Set cursor shape"
|
|
81
|
+
if not functions -q fish_vi_cursor_handle
|
|
82
|
+
echo -en "\e[$cursor q"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
function __ghostty_reset_cursor --on-event fish_preexec -d "Reset cursor shape"
|
|
86
|
+
if not functions -q fish_vi_cursor_handle
|
|
87
|
+
echo -en "\e[0 q"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Add Ghostty binary to PATH if the path feature is enabled
|
|
93
|
+
if contains path $features; and test -n "$GHOSTTY_BIN_DIR"
|
|
94
|
+
fish_add_path --global --path --append "$GHOSTTY_BIN_DIR"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# When using sudo shell integration feature, ensure $TERMINFO is set
|
|
98
|
+
# and `sudo` is not already a function or alias
|
|
99
|
+
if contains sudo $features; and test -n "$TERMINFO"; and test file = (type -t sudo 2> /dev/null; or echo "x")
|
|
100
|
+
# Wrap `sudo` command to ensure Ghostty terminfo is preserved
|
|
101
|
+
function sudo -d "Wrap sudo to preserve terminfo"
|
|
102
|
+
set --function sudo_has_sudoedit_flags no
|
|
103
|
+
for arg in $argv
|
|
104
|
+
# Check if argument is '-e' or '--edit' (sudoedit flags)
|
|
105
|
+
if string match -q -- -e "$arg"; or string match -q -- --edit "$arg"
|
|
106
|
+
set --function sudo_has_sudoedit_flags yes
|
|
107
|
+
break
|
|
108
|
+
end
|
|
109
|
+
# Check if argument is neither an option nor a key-value pair
|
|
110
|
+
if not string match -r -q -- "^-" "$arg"; and not string match -r -q -- "=" "$arg"
|
|
111
|
+
break
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
if test "$sudo_has_sudoedit_flags" = yes
|
|
115
|
+
command sudo $argv
|
|
116
|
+
else
|
|
117
|
+
command sudo --preserve-env=TERMINFO $argv
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# SSH Integration
|
|
123
|
+
set -l features (string split ',' -- "$GHOSTTY_SHELL_FEATURES")
|
|
124
|
+
if contains ssh-env $features; or contains ssh-terminfo $features
|
|
125
|
+
function ssh --wraps=ssh --description "SSH wrapper with Ghostty integration"
|
|
126
|
+
set -l features (string split ',' -- "$GHOSTTY_SHELL_FEATURES")
|
|
127
|
+
set -l ssh_term xterm-256color
|
|
128
|
+
set -l ssh_opts
|
|
129
|
+
|
|
130
|
+
# Configure environment variables for remote session
|
|
131
|
+
if contains ssh-env $features
|
|
132
|
+
set -a ssh_opts -o "SetEnv COLORTERM=truecolor"
|
|
133
|
+
set -a ssh_opts -o "SendEnv TERM_PROGRAM TERM_PROGRAM_VERSION"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Install terminfo on remote host if needed
|
|
137
|
+
if contains ssh-terminfo $features
|
|
138
|
+
set -l ssh_user
|
|
139
|
+
set -l ssh_hostname
|
|
140
|
+
|
|
141
|
+
for line in (command ssh -G $argv 2>/dev/null)
|
|
142
|
+
set -l parts (string split ' ' -- $line)
|
|
143
|
+
if test (count $parts) -ge 2
|
|
144
|
+
switch $parts[1]
|
|
145
|
+
case user
|
|
146
|
+
set ssh_user $parts[2]
|
|
147
|
+
case hostname
|
|
148
|
+
set ssh_hostname $parts[2]
|
|
149
|
+
end
|
|
150
|
+
if test -n "$ssh_user"; and test -n "$ssh_hostname"
|
|
151
|
+
break
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
if test -n "$ssh_hostname"
|
|
157
|
+
set -l ssh_target "$ssh_user@$ssh_hostname"
|
|
158
|
+
|
|
159
|
+
# Check if terminfo is already cached
|
|
160
|
+
if test -x "$GHOSTTY_BIN_DIR/ghostty"; and "$GHOSTTY_BIN_DIR/ghostty" +ssh-cache --host="$ssh_target" >/dev/null 2>&1
|
|
161
|
+
set ssh_term xterm-ghostty
|
|
162
|
+
else if command -q infocmp
|
|
163
|
+
set -l ssh_terminfo
|
|
164
|
+
set -l ssh_cpath_dir
|
|
165
|
+
set -l ssh_cpath
|
|
166
|
+
|
|
167
|
+
set ssh_terminfo "$(infocmp -0 -x xterm-ghostty 2>/dev/null)"
|
|
168
|
+
|
|
169
|
+
if test -n "$ssh_terminfo"
|
|
170
|
+
echo "Setting up xterm-ghostty terminfo on $ssh_hostname..." >&2
|
|
171
|
+
|
|
172
|
+
set ssh_cpath_dir (mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null; or echo "/tmp/ghostty-ssh-$ssh_user."(random))
|
|
173
|
+
set ssh_cpath "$ssh_cpath_dir/socket"
|
|
174
|
+
|
|
175
|
+
if echo "$ssh_terminfo" | command ssh $ssh_opts -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s $argv '
|
|
176
|
+
infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
|
|
177
|
+
command -v tic >/dev/null 2>&1 || exit 1
|
|
178
|
+
mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
|
|
179
|
+
exit 1
|
|
180
|
+
' 2>/dev/null
|
|
181
|
+
set ssh_term xterm-ghostty
|
|
182
|
+
set -a ssh_opts -o "ControlPath=$ssh_cpath"
|
|
183
|
+
|
|
184
|
+
# Cache successful installation
|
|
185
|
+
if test -x "$GHOSTTY_BIN_DIR/ghostty"
|
|
186
|
+
"$GHOSTTY_BIN_DIR/ghostty" +ssh-cache --add="$ssh_target" >/dev/null 2>&1; or true
|
|
187
|
+
end
|
|
188
|
+
else
|
|
189
|
+
echo "Warning: Failed to install terminfo." >&2
|
|
190
|
+
end
|
|
191
|
+
else
|
|
192
|
+
echo "Warning: Could not generate terminfo data." >&2
|
|
193
|
+
end
|
|
194
|
+
else
|
|
195
|
+
echo "Warning: ghostty command not available for cache management." >&2
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Execute SSH with TERM environment variable
|
|
201
|
+
TERM="$ssh_term" command ssh $ssh_opts $argv
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Setup prompt marking
|
|
206
|
+
function __ghostty_mark_prompt_start --on-event fish_prompt --on-event fish_posterror
|
|
207
|
+
# If we never got the output end event, then we need to send it now.
|
|
208
|
+
if test "$__ghostty_prompt_state" != prompt-start
|
|
209
|
+
echo -en "\e]133;D\a"
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
set --global __ghostty_prompt_state prompt-start
|
|
213
|
+
echo -en $__ghostty_prompt_start_mark
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
function __ghostty_mark_output_start --on-event fish_preexec
|
|
217
|
+
set --global __ghostty_prompt_state pre-exec
|
|
218
|
+
echo -en "\e]133;C\a"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
function __ghostty_mark_output_end --on-event fish_postexec
|
|
222
|
+
set --global __ghostty_prompt_state post-exec
|
|
223
|
+
echo -en "\e]133;D;$status\a"
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Report pwd. This is actually built-in to fish but only for terminals
|
|
227
|
+
# that match an allowlist and that isn't us.
|
|
228
|
+
function __update_cwd_osc --on-variable PWD -d 'Notify capable terminals when $PWD changes'
|
|
229
|
+
if status --is-command-substitution || set -q INSIDE_EMACS
|
|
230
|
+
return
|
|
231
|
+
end
|
|
232
|
+
printf \e\]7\;file://%s%s\a $hostname (string escape --style=url $PWD)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Enable fish to handle reflow because Ghostty clears the prompt on resize.
|
|
236
|
+
set --global fish_handle_reflow 1
|
|
237
|
+
|
|
238
|
+
# Initial calls for first prompt
|
|
239
|
+
if string match -q 'cursor*' -- $features
|
|
240
|
+
__ghostty_set_cursor_beam
|
|
241
|
+
end
|
|
242
|
+
__ghostty_mark_prompt_start
|
|
243
|
+
__update_cwd_osc
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
ghostty_exit
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Ghostty shell integration
|
|
2
|
+
export module ghostty {
|
|
3
|
+
def has_feature [feature: string] {
|
|
4
|
+
$feature in ($env.GHOSTTY_SHELL_FEATURES | default "" | split row ',')
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
# Wrap `ssh` with Ghostty TERMINFO support
|
|
8
|
+
export def --wrapped ssh [...args] {
|
|
9
|
+
mut ssh_env = {}
|
|
10
|
+
mut ssh_opts = []
|
|
11
|
+
|
|
12
|
+
# `ssh-env`: use xterm-256color and propagate COLORTERM/TERM_PROGRAM vars
|
|
13
|
+
if (has_feature "ssh-env") {
|
|
14
|
+
$ssh_env.TERM = "xterm-256color"
|
|
15
|
+
$ssh_opts = [
|
|
16
|
+
"-o" "SetEnv COLORTERM=truecolor"
|
|
17
|
+
"-o" "SendEnv TERM_PROGRAM TERM_PROGRAM_VERSION"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# `ssh-terminfo`: auto-install xterm-ghostty terminfo on remote hosts
|
|
22
|
+
if (has_feature "ssh-terminfo") {
|
|
23
|
+
let ghostty = ($env.GHOSTTY_BIN_DIR? | default "") | path join "ghostty"
|
|
24
|
+
|
|
25
|
+
let ssh_cfg = ^ssh -G ...$args
|
|
26
|
+
| lines
|
|
27
|
+
| parse "{key} {value}"
|
|
28
|
+
| where key in ["user" "hostname"]
|
|
29
|
+
| select key value
|
|
30
|
+
| transpose -rd
|
|
31
|
+
| default {user: $env.USER hostname: "localhost"}
|
|
32
|
+
let ssh_id = $"($ssh_cfg.user)@($ssh_cfg.hostname)"
|
|
33
|
+
|
|
34
|
+
if (^$ghostty "+ssh-cache" $"--host=($ssh_id)" | complete | $in.exit_code == 0) {
|
|
35
|
+
$ssh_env.TERM = "xterm-ghostty"
|
|
36
|
+
} else {
|
|
37
|
+
$ssh_env.TERM = "xterm-256color"
|
|
38
|
+
|
|
39
|
+
let terminfo = try {
|
|
40
|
+
^infocmp -0 -x xterm-ghostty
|
|
41
|
+
} catch {
|
|
42
|
+
print -e "infocmp failed, using xterm-256color"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ($terminfo | is-not-empty) {
|
|
46
|
+
print $"Setting up xterm-ghostty terminfo on ($ssh_cfg.hostname)..."
|
|
47
|
+
|
|
48
|
+
let ctrl_path = (
|
|
49
|
+
mktemp -td $"ghostty-ssh-($ssh_cfg.user).XXXXXX"
|
|
50
|
+
| path join "socket"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
let remote_args = $ssh_opts ++ [
|
|
54
|
+
"-o" "ControlMaster=yes"
|
|
55
|
+
"-o" $"ControlPath=($ctrl_path)"
|
|
56
|
+
"-o" "ControlPersist=60s"
|
|
57
|
+
] ++ $args
|
|
58
|
+
|
|
59
|
+
$terminfo | ^ssh ...$remote_args '
|
|
60
|
+
infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
|
|
61
|
+
command -v tic >/dev/null 2>&1 || exit 1
|
|
62
|
+
mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
|
|
63
|
+
exit 1'
|
|
64
|
+
| complete
|
|
65
|
+
| if $in.exit_code == 0 {
|
|
66
|
+
^$ghostty "+ssh-cache" $"--add=($ssh_id)" e>| print -e
|
|
67
|
+
$ssh_env.TERM = "xterm-ghostty"
|
|
68
|
+
$ssh_opts = ($ssh_opts ++ ["-o" $"ControlPath=($ctrl_path)"])
|
|
69
|
+
} else {
|
|
70
|
+
print -e "terminfo install failed, using xterm-256color"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let ssh_args = $ssh_opts ++ $args
|
|
77
|
+
with-env $ssh_env {
|
|
78
|
+
^ssh ...$ssh_args
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Wrap `sudo` to preserve Ghostty's TERMINFO environment variable
|
|
83
|
+
export def --wrapped sudo [...args] {
|
|
84
|
+
mut sudo_args = $args
|
|
85
|
+
|
|
86
|
+
if (has_feature "sudo") {
|
|
87
|
+
# Extract just the sudo options (before the command)
|
|
88
|
+
let sudo_options = (
|
|
89
|
+
$args | take until {|arg|
|
|
90
|
+
not (($arg | str starts-with "-") or ($arg | str contains "="))
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Prepend TERMINFO preservation flag if not using sudoedit
|
|
95
|
+
if (not ("-e" in $sudo_options or "--edit" in $sudo_options)) {
|
|
96
|
+
$sudo_args = ($args | prepend "--preserve-env=TERMINFO")
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
^sudo ...$sudo_args
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Clean up XDG_DATA_DIRS by removing GHOSTTY_SHELL_INTEGRATION_XDG_DIR
|
|
105
|
+
if 'GHOSTTY_SHELL_INTEGRATION_XDG_DIR' in $env {
|
|
106
|
+
if 'XDG_DATA_DIRS' in $env {
|
|
107
|
+
$env.XDG_DATA_DIRS = ($env.XDG_DATA_DIRS | str replace $"($env.GHOSTTY_SHELL_INTEGRATION_XDG_DIR):" "")
|
|
108
|
+
}
|
|
109
|
+
hide-env GHOSTTY_SHELL_INTEGRATION_XDG_DIR
|
|
110
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Based on (started as) a copy of Kitty's zsh integration. Kitty is
|
|
2
|
+
# distributed under GPLv3, so this file is also distributed under GPLv3.
|
|
3
|
+
# The license header is reproduced below:
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
# This script is sourced automatically by zsh when ZDOTDIR is set to this
|
|
19
|
+
# directory. It therefore assumes it's running within our shell integration
|
|
20
|
+
# environment and should not be sourced manually (unlike ghostty-integration).
|
|
21
|
+
#
|
|
22
|
+
# This file can get sourced with aliases enabled. To avoid alias expansion
|
|
23
|
+
# we quote everything that can be quoted. Some aliases will still break us
|
|
24
|
+
# though.
|
|
25
|
+
|
|
26
|
+
# Restore the original ZDOTDIR value if GHOSTTY_ZSH_ZDOTDIR is set.
|
|
27
|
+
# Otherwise, unset the ZDOTDIR that was set during shell injection.
|
|
28
|
+
if [[ -n "${GHOSTTY_ZSH_ZDOTDIR+X}" ]]; then
|
|
29
|
+
'builtin' 'export' ZDOTDIR="$GHOSTTY_ZSH_ZDOTDIR"
|
|
30
|
+
'builtin' 'unset' 'GHOSTTY_ZSH_ZDOTDIR'
|
|
31
|
+
else
|
|
32
|
+
'builtin' 'unset' 'ZDOTDIR'
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Use try-always to have the right error code.
|
|
36
|
+
{
|
|
37
|
+
# Zsh treats unset ZDOTDIR as if it was HOME. We do the same.
|
|
38
|
+
#
|
|
39
|
+
# Source the user's .zshenv before sourcing ghostty-integration because the
|
|
40
|
+
# former might set fpath and other things without which ghostty-integration
|
|
41
|
+
# won't work.
|
|
42
|
+
#
|
|
43
|
+
# Use typeset in case we are in a function with warn_create_global in
|
|
44
|
+
# effect. Unlikely but better safe than sorry.
|
|
45
|
+
'builtin' 'typeset' _ghostty_file=${ZDOTDIR-$HOME}"/.zshenv"
|
|
46
|
+
# Zsh ignores unreadable rc files. We do the same.
|
|
47
|
+
# Zsh ignores rc files that are directories, and so does source.
|
|
48
|
+
[[ ! -r "$_ghostty_file" ]] || 'builtin' 'source' '--' "$_ghostty_file"
|
|
49
|
+
} always {
|
|
50
|
+
if [[ -o 'interactive' ]]; then
|
|
51
|
+
# ${(%):-%x} is the path to the current file.
|
|
52
|
+
# On top of it we add :A:h to get the directory.
|
|
53
|
+
'builtin' 'typeset' _ghostty_file="${${(%):-%x}:A:h}"/ghostty-integration
|
|
54
|
+
if [[ -r "$_ghostty_file" ]]; then
|
|
55
|
+
'builtin' 'autoload' '-Uz' '--' "$_ghostty_file"
|
|
56
|
+
"${_ghostty_file:t}"
|
|
57
|
+
'builtin' 'unfunction' '--' "${_ghostty_file:t}"
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
'builtin' 'unset' '_ghostty_file'
|
|
61
|
+
}
|