From ef5d75e328ce443541c148405b3af685547a10be Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 5 Aug 2023 21:31:34 -0700 Subject: [PATCH 1/4] input: support assigning integer binding action values This enables jump_to_prompt --- src/input/Binding.zig | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/input/Binding.zig b/src/input/Binding.zig index e3a66527d..4dec02d6f 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -124,6 +124,14 @@ pub fn parse(input: []const u8) !Binding { break :action @unionInit(Action, field.name, value); }, + .Int => { + const idx = colonIdx orelse return Error.InvalidFormat; + const param = actionRaw[idx + 1 ..]; + const value = std.fmt.parseInt(field.type, param, 10) catch + return Error.InvalidFormat; + break :action @unionInit(Action, field.name, value); + }, + else => unreachable, }, } @@ -418,3 +426,19 @@ test "parse: action with enum" { try testing.expectEqual(Action.SplitDirection.right, binding.action.new_split); } } + +test "parse: action with int" { + const testing = std.testing; + + // parameter + { + const binding = try parse("a=jump_to_prompt:-1"); + try testing.expect(binding.action == .jump_to_prompt); + try testing.expectEqual(@as(i16, -1), binding.action.jump_to_prompt); + } + { + const binding = try parse("a=jump_to_prompt:10"); + try testing.expect(binding.action == .jump_to_prompt); + try testing.expectEqual(@as(i16, 10), binding.action.jump_to_prompt); + } +} From 2840062ad5048a7db86fbf72d6fcc81f9d2418f6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 5 Aug 2023 21:32:30 -0700 Subject: [PATCH 2/4] bind shift+ to jump_to_prompt back/forward, respectively --- src/config.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/config.zig b/src/config.zig index 7d2a7fc24..e812cbec8 100644 --- a/src/config.zig +++ b/src/config.zig @@ -480,6 +480,18 @@ pub const Config = struct { .{ .key = .right, .mods = .{ .ctrl = true, .alt = true } }, .{ .goto_split = .right }, ); + + // Semantic prompts + try result.keybind.set.put( + alloc, + .{ .key = .page_up, .mods = .{ .shift = true } }, + .{ .jump_to_prompt = -1 }, + ); + try result.keybind.set.put( + alloc, + .{ .key = .page_down, .mods = .{ .shift = true } }, + .{ .jump_to_prompt = 1 }, + ); } { // Cmd+N for goto tab N From 321be2d5ad223a451b63acd8229a7adc5598b6cf Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 5 Aug 2023 21:38:32 -0700 Subject: [PATCH 3/4] termio: respect GHOSTTY_RESOURCES_DIR --- src/termio/Exec.zig | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 88881299a..79f368282 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -533,10 +533,18 @@ const Subprocess = struct { // Get our bundled resources directory, if it exists. We use this // for terminfo, shell-integration, etc. - const resources_dir = try resourcesDir(alloc); - if (resources_dir) |dir| { - try env.put("GHOSTTY_RESOURCES_DIR", dir); - } + const resources_key = "GHOSTTY_RESOURCES_DIR"; + const resources_dir = if (env.get(resources_key)) |dir| dir: { + log.info("using Ghostty resources dir from env var: {s}", .{dir}); + break :dir dir; + } else if (try resourcesDir(alloc)) |dir| dir: { + log.info("found Ghostty resources dir: {s}", .{dir}); + try env.put(resources_key, dir); + break :dir dir; + } else dir: { + log.warn("Ghostty resources dir not found, some features disabled", .{}); + break :dir null; + }; // 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 From 247ddd227d8d80d0d6855309472fe062002fd36b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 5 Aug 2023 21:43:51 -0700 Subject: [PATCH 4/4] update README with shell integration instructions --- README.md | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 888fcbb9f..f2da7bba4 100644 --- a/README.md +++ b/README.md @@ -123,11 +123,6 @@ Ghostty supports some features that require shell integration. I am aiming to support many of the features that [Kitty supports for shell integration](https://sw.kovidgoyal.net/kitty/shell-integration/). -Ghostty will automatically inject the shell integration code for `zsh` and -`fish`. Other shells are not supported. You can also manually load them -in many cases (see `src/shell-integration`). **If you want to disable this feature,** -set `shell-integration = none` in your configuration file. - The currently support shell integration features in Ghostty: * We do not confirm close for windows where the cursor is at a prompt. @@ -136,6 +131,38 @@ The currently support shell integration features in Ghostty: * The `scroll_to_prompt` keybinding can be used to scroll the terminal window forward and back through prompts. +#### Shell Integration Installation and Verification + +**On macOS,** Ghostty will automatically inject the shell integration code for `zsh` and +`fish`. Other shells are not supported. You can also manually load them +in many cases (see `src/shell-integration`). **If you want to disable this feature,** +set `shell-integration = none` in your configuration file. + +**On Linux,** automatic shell integration requires that you set the +`GHOSTTY_RESOURCES_DIR` environment variable to point to the +`zig-out/share` directory after building Ghostty from source. +To validate this directory the file `$GHOSTTY_RESOURCES_DIR/terminfo/ghostty.terminfo` +should exist. + +To verify shell integration is working, look for the following log lines: + +``` +info(io_exec): using Ghostty resources dir from env var: /Applications/Ghostty.app/Contents/Resources +info(io_exec): shell integration automatically injected shell=termio.shell_integration.Shell.fish +``` + +If you see any of the following, something is not working correctly. +The main culprit is usually that `GHOSTTY_RESOURCES_DIR` is not pointing +to the right place. + +``` +ghostty terminfo not found, using xterm-256color + +or + +shell could not be detected, no automatic shell integration will be injected +``` + ## Roadmap and Status The high-level ambitious plan for the project, in order: