Addresses the partial ports listed in docs/rewrite/notes/review-completeness-codex.md (details in docs/rewrite/notes/gaps-X2.md): - Flatpak: the exit watcher no longer consumes the host command; a shared FlatpakSignalHandle lets closing a surface still SIGHUP the host process group. - Child environment is byte-preserving end to end (ghostty_os::EnvMap of OsStrings) and Snap paths are filtered like filterSnapPaths. - argv handling no longer panics on non-UTF-8 arguments. - URI percent-decoding keeps raw bytes; OSC 7 pwd is passed through without lossy conversion. - Keybinding comparison/hashing uses full Unicode case folding from a table generated from CaseFolding.txt (Unicode 17.0.0). - Link regexes set Oniguruma's whole-search retry limit through the new minimal ghostty-onig crate (one SAFETY-commented FFI call). - OSC 9 NUL-capacity check ordering matches Zig. - Wayland registry binds/clears globals advertised after startup. - Custom shaders may pass sampler2D to helper functions (naga adapter). - +list-themes preview renders OSC 8 links, styled underlines and follows color-scheme reports. Also includes the inspector's integration edits in shared files (renderer state hook, termio VT recording, core/apprt-gtk wiring), X1's config/input/cli additions for completion generation, and a fix for a race in the termio backpressure test (it wrote before `stty raw` applied, so the cooked line discipline dropped bytes past MAX_CANON). Test Plan: - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings
149 lines
4.3 KiB
Rust
149 lines
4.3 KiB
Rust
//! This module is a help generator for keybind actions documentation.
|
|
//! It can generate documentation in different formats (plaintext for CLI,
|
|
//! markdown for website) while maintaining consistent content.
|
|
//! (ZIG/src/input/helpgen_actions.zig)
|
|
//!
|
|
//! The docs themselves live in [`ActionKey::docs`] (the Zig version reads
|
|
//! them from the build-time generated `help_strings`).
|
|
|
|
use crate::binding::ActionKey;
|
|
|
|
/// Format options for generating keybind actions documentation
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum Format {
|
|
/// Plain text output with indentation
|
|
Plaintext,
|
|
/// Markdown formatted output
|
|
Markdown,
|
|
}
|
|
|
|
impl Format {
|
|
fn format_field_name(self, w: &mut String, field_name: &str) {
|
|
match self {
|
|
Format::Plaintext => {
|
|
w.push_str(field_name);
|
|
w.push_str(":\n");
|
|
}
|
|
Format::Markdown => {
|
|
w.push_str("## `");
|
|
w.push_str(field_name);
|
|
w.push_str("`\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
fn format_doc_line(self, w: &mut String, line: &str) {
|
|
match self {
|
|
Format::Plaintext => {
|
|
w.push_str(" ");
|
|
w.push_str(line);
|
|
w.push('\n');
|
|
}
|
|
Format::Markdown => {
|
|
w.push_str(line);
|
|
w.push('\n');
|
|
}
|
|
}
|
|
}
|
|
|
|
fn header(self) -> Option<&'static str> {
|
|
match self {
|
|
Format::Plaintext => None,
|
|
Format::Markdown => Some(
|
|
"---\n\
|
|
title: Keybinding Action Reference\n\
|
|
description: Reference of all Ghostty keybinding actions.\n\
|
|
editOnGithubLink: https://github.com/ghostty-org/ghostty/edit/main/src/input/Binding.zig\n\
|
|
---\n\
|
|
\n\
|
|
This is a reference of all Ghostty keybinding actions.\n\
|
|
\n\
|
|
\n",
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Generate keybind actions documentation with the specified format
|
|
pub fn generate(writer: &mut String, format: Format, show_docs: bool) {
|
|
if let Some(header) = format.header() {
|
|
writer.push_str(header);
|
|
}
|
|
|
|
let mut stream = String::new();
|
|
|
|
for &key in ActionKey::ALL {
|
|
let name = key.name();
|
|
if name.starts_with('_') {
|
|
continue;
|
|
}
|
|
|
|
// Write previously stored doc comment below all related actions
|
|
// (every action has a doc comment).
|
|
if show_docs {
|
|
writer.push_str(&stream);
|
|
writer.push('\n');
|
|
stream.clear();
|
|
}
|
|
|
|
if show_docs {
|
|
format.format_field_name(writer, name);
|
|
} else {
|
|
writer.push_str(name);
|
|
writer.push('\n');
|
|
}
|
|
|
|
if show_docs {
|
|
let mut iter = key.help_string().split('\n').peekable();
|
|
while let Some(s) = iter.next() {
|
|
// If it is the last line and empty, then skip it.
|
|
if iter.peek().is_none() && s.is_empty() {
|
|
continue;
|
|
}
|
|
format.format_doc_line(&mut stream, s);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write any remaining buffered documentation
|
|
if !stream.is_empty() {
|
|
writer.push_str(&stream);
|
|
}
|
|
}
|
|
|
|
/// Convenience: generate into a fresh string.
|
|
pub fn generate_string(format: Format, show_docs: bool) -> String {
|
|
let mut s = String::new();
|
|
generate(&mut s, format, show_docs);
|
|
s
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn plaintext_with_docs_lists_all_actions() {
|
|
let s = generate_string(Format::Plaintext, true);
|
|
assert!(s.starts_with("\nignore:\n"));
|
|
assert!(s.contains("ignore:\n Ignore this key combination.\n"));
|
|
for &k in ActionKey::ALL {
|
|
assert!(s.contains(&format!("{}:\n", k.name())));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn names_only() {
|
|
let s = generate_string(Format::Plaintext, false);
|
|
assert_eq!(s.lines().count(), ActionKey::ALL.len());
|
|
assert_eq!(s.lines().next(), Some("ignore"));
|
|
}
|
|
|
|
#[test]
|
|
fn markdown_header_and_field() {
|
|
let s = generate_string(Format::Markdown, true);
|
|
assert!(s.starts_with("---\ntitle: Keybinding Action Reference\n"));
|
|
assert!(s.contains("## `unbind`\n"));
|
|
}
|
|
}
|