mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #229 from mitchellh/linux-jump
Allow setting "jump_to_prompt" binding in config, bind on Linux, and easier shell integration on Linux
This commit is contained in:
37
README.md
37
README.md
@ -123,11 +123,6 @@ Ghostty supports some features that require shell integration. I am aiming
|
|||||||
to support many of the features that
|
to support many of the features that
|
||||||
[Kitty supports for shell integration](https://sw.kovidgoyal.net/kitty/shell-integration/).
|
[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:
|
The currently support shell integration features in Ghostty:
|
||||||
|
|
||||||
* We do not confirm close for windows where the cursor is at a prompt.
|
* 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
|
* The `scroll_to_prompt` keybinding can be used to scroll the terminal window
|
||||||
forward and back through prompts.
|
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
|
## Roadmap and Status
|
||||||
|
|
||||||
The high-level ambitious plan for the project, in order:
|
The high-level ambitious plan for the project, in order:
|
||||||
|
@ -480,6 +480,18 @@ pub const Config = struct {
|
|||||||
.{ .key = .right, .mods = .{ .ctrl = true, .alt = true } },
|
.{ .key = .right, .mods = .{ .ctrl = true, .alt = true } },
|
||||||
.{ .goto_split = .right },
|
.{ .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
|
// Cmd+N for goto tab N
|
||||||
|
@ -124,6 +124,14 @@ pub fn parse(input: []const u8) !Binding {
|
|||||||
break :action @unionInit(Action, field.name, value);
|
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,
|
else => unreachable,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -418,3 +426,19 @@ test "parse: action with enum" {
|
|||||||
try testing.expectEqual(Action.SplitDirection.right, binding.action.new_split);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -533,10 +533,18 @@ 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_key = "GHOSTTY_RESOURCES_DIR";
|
||||||
if (resources_dir) |dir| {
|
const resources_dir = if (env.get(resources_key)) |dir| dir: {
|
||||||
try env.put("GHOSTTY_RESOURCES_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
|
// 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
|
||||||
|
Reference in New Issue
Block a user