aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-01-22 11:45:16 +0100
committerGitHub <noreply@github.com>2026-01-22 11:45:16 +0100
commit81ca742a694fdfebc8efcb0a01490744f259a4e1 (patch)
treea664d17442ba601f541d36c5890775e8549b29b1 /zellij-utils/src
parentFix breaking panes behavior (#4622) (diff)
downloadsl0ppij-81ca742a694fdfebc8efcb0a01490744f259a4e1.tar.gz
sl0ppij-81ca742a694fdfebc8efcb0a01490744f259a4e1.tar.xz
sl0ppij-81ca742a694fdfebc8efcb0a01490744f259a4e1.zip
Allow disabling OSC8 link generation (#4624)
* implementation * rustfmt * add pr
Diffstat (limited to 'zellij-utils/src')
-rw-r--r--zellij-utils/src/client_server_contract/common_types.proto1
-rw-r--r--zellij-utils/src/input/options.rs9
-rw-r--r--zellij-utils/src/ipc/protobuf_conversion.rs2
-rw-r--r--zellij-utils/src/ipc/tests/roundtrip_tests.rs1
-rw-r--r--zellij-utils/src/kdl/mod.rs57
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap7
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap7
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap1
16 files changed, 93 insertions, 0 deletions
diff --git a/zellij-utils/src/client_server_contract/common_types.proto b/zellij-utils/src/client_server_contract/common_types.proto
index 1be7c4c9..ce66881a 100644
--- a/zellij-utils/src/client_server_contract/common_types.proto
+++ b/zellij-utils/src/client_server_contract/common_types.proto
@@ -1023,6 +1023,7 @@ message Options {
optional string web_server_key = 37;
optional bool enforce_https_for_localhost = 38;
optional string post_command_discovery_hook = 39;
+ optional bool osc8_hyperlinks = 40;
}
enum OnForceClose {
diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs
index e9035dc1..6def4a88 100644
--- a/zellij-utils/src/input/options.rs
+++ b/zellij-utils/src/input/options.rs
@@ -108,6 +108,11 @@ pub struct Options {
#[serde(default)]
pub copy_on_select: Option<bool>,
+ /// Enable OSC8 hyperlink output (true or false)
+ #[clap(long, value_parser)]
+ #[serde(default)]
+ pub osc8_hyperlinks: Option<bool>,
+
/// Explicit full path to open the scrollback editor (default is $EDITOR or $VISUAL)
#[clap(long, value_parser)]
pub scrollback_editor: Option<PathBuf>,
@@ -287,6 +292,7 @@ impl Options {
let copy_command = other.copy_command.or_else(|| self.copy_command.clone());
let copy_clipboard = other.copy_clipboard.or(self.copy_clipboard);
let copy_on_select = other.copy_on_select.or(self.copy_on_select);
+ let osc8_hyperlinks = other.osc8_hyperlinks.or(self.osc8_hyperlinks);
let scrollback_editor = other
.scrollback_editor
.or_else(|| self.scrollback_editor.clone());
@@ -345,6 +351,7 @@ impl Options {
copy_command,
copy_clipboard,
copy_on_select,
+ osc8_hyperlinks,
scrollback_editor,
session_name,
attach_to_session,
@@ -408,6 +415,7 @@ impl Options {
let copy_command = other.copy_command.or_else(|| self.copy_command.clone());
let copy_clipboard = other.copy_clipboard.or(self.copy_clipboard);
let copy_on_select = other.copy_on_select.or(self.copy_on_select);
+ let osc8_hyperlinks = other.osc8_hyperlinks.or(self.osc8_hyperlinks);
let scrollback_editor = other
.scrollback_editor
.or_else(|| self.scrollback_editor.clone());
@@ -462,6 +470,7 @@ impl Options {
copy_command,
copy_clipboard,
copy_on_select,
+ osc8_hyperlinks,
scrollback_editor,
session_name,
attach_to_session,
diff --git a/zellij-utils/src/ipc/protobuf_conversion.rs b/zellij-utils/src/ipc/protobuf_conversion.rs
index 5d06cbe5..7810d4ef 100644
--- a/zellij-utils/src/ipc/protobuf_conversion.rs
+++ b/zellij-utils/src/ipc/protobuf_conversion.rs
@@ -579,6 +579,7 @@ impl From<crate::input::options::Options>
crate::input::options::Clipboard::Primary => ProtoClipboard::Primary as i32,
}),
copy_on_select: options.copy_on_select,
+ osc8_hyperlinks: options.osc8_hyperlinks,
scrollback_editor: options
.scrollback_editor
.map(|p| p.to_string_lossy().to_string()),
@@ -664,6 +665,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Options>
})
.transpose()?,
copy_on_select: options.copy_on_select,
+ osc8_hyperlinks: options.osc8_hyperlinks,
scrollback_editor: options.scrollback_editor.map(std::path::PathBuf::from),
session_name: options.session_name,
attach_to_session: options.attach_to_session,
diff --git a/zellij-utils/src/ipc/tests/roundtrip_tests.rs b/zellij-utils/src/ipc/tests/roundtrip_tests.rs
index 1c928e6b..5e2e000a 100644
--- a/zellij-utils/src/ipc/tests/roundtrip_tests.rs
+++ b/zellij-utils/src/ipc/tests/roundtrip_tests.rs
@@ -447,6 +447,7 @@ fn test_client_messages() {
copy_command: Some("copy_command".to_owned()),
copy_clipboard: Some(Clipboard::System),
copy_on_select: Some(true),
+ osc8_hyperlinks: Some(true),
scrollback_editor: Some(PathBuf::from("scrollback_editor")),
session_name: Some("session_name".to_owned()),
attach_to_session: Some(true),
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index 3567145d..0780aa2a 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -2616,6 +2616,9 @@ impl Options {
};
let copy_on_select =
kdl_property_first_arg_as_bool_or_error!(kdl_options, "copy_on_select").map(|(v, _)| v);
+ let osc8_hyperlinks =
+ kdl_property_first_arg_as_bool_or_error!(kdl_options, "osc8_hyperlinks")
+ .map(|(v, _)| v);
let scrollback_editor =
kdl_property_first_arg_as_string_or_error!(kdl_options, "scrollback_editor")
.map(|(string, _entry)| PathBuf::from(string));
@@ -2715,6 +2718,7 @@ impl Options {
copy_command,
copy_clipboard,
copy_on_select,
+ osc8_hyperlinks,
scrollback_editor,
session_name,
attach_to_session,
@@ -2774,6 +2778,36 @@ impl Options {
None
}
}
+ fn osc8_hyperlinks_to_kdl(&self, add_comments: bool) -> Option<KdlNode> {
+ let comment_text = format!(
+ "{}\n{}\n{}\n{}\n{}\n{}",
+ " ",
+ "// Enable OSC8 hyperlink output",
+ "// Options:",
+ "// - true (Default)",
+ "// - false",
+ "// ",
+ );
+
+ let create_node = |node_value: bool| -> KdlNode {
+ let mut node = KdlNode::new("osc8_hyperlinks");
+ node.push(KdlValue::Bool(node_value));
+ node
+ };
+ if let Some(osc8_hyperlinks) = self.osc8_hyperlinks {
+ let mut node = create_node(osc8_hyperlinks);
+ if add_comments {
+ node.set_leading(format!("{}\n", comment_text));
+ }
+ Some(node)
+ } else if add_comments {
+ let mut node = create_node(true);
+ node.set_leading(format!("{}\n// ", comment_text));
+ Some(node)
+ } else {
+ None
+ }
+ }
fn theme_to_kdl(&self, add_comments: bool) -> Option<KdlNode> {
let comment_text = format!(
"{}\n{}\n{}\n{}",
@@ -3896,6 +3930,9 @@ impl Options {
if let Some(simplified_ui_node) = self.simplified_ui_to_kdl(add_comments) {
nodes.push(simplified_ui_node);
}
+ if let Some(osc8_hyperlinks_node) = self.osc8_hyperlinks_to_kdl(add_comments) {
+ nodes.push(osc8_hyperlinks_node);
+ }
if let Some(theme_node) = self.theme_to_kdl(add_comments) {
nodes.push(theme_node);
}
@@ -6822,3 +6859,23 @@ fn bare_config_from_default_assets_to_string_with_comments() {
);
insta::assert_snapshot!(fake_config_stringified);
}
+
+#[test]
+fn osc8_hyperlinks_config_parsing() {
+ let config_with_osc8_disabled = r#"
+ osc8_hyperlinks false
+ "#;
+ let config = Config::from_kdl(config_with_osc8_disabled, None).unwrap();
+ assert_eq!(config.options.osc8_hyperlinks, Some(false));
+
+ let config_with_osc8_enabled = r#"
+ osc8_hyperlinks true
+ "#;
+ let config = Config::from_kdl(config_with_osc8_enabled, None).unwrap();
+ assert_eq!(config.options.osc8_hyperlinks, Some(true));
+
+ // Test serialization roundtrip
+ let serialized = config.to_string(false);
+ let deserialized = Config::from_kdl(&serialized, None).unwrap();
+ assert_eq!(deserialized.options.osc8_hyperlinks, Some(true));
+}
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
index c9d93654..6767921f 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
@@ -297,6 +297,13 @@ web_client {
//
// simplified_ui true
+// Enable OSC8 hyperlink output
+// Options:
+// - true (Default)
+// - false
+//
+// osc8_hyperlinks true
+
// Choose the theme that is specified in the themes section.
// Default: default
//
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
index 468a97dd..2a6a6a9f 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
@@ -10,6 +10,13 @@ expression: fake_document.to_string()
//
simplified_ui true
+// Enable OSC8 hyperlink output
+// Options:
+// - true (Default)
+// - false
+//
+// osc8_hyperlinks true
+
// Choose the theme that is specified in the themes section.
// Default: default
//
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
index 61969ae2..90e16136 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
@@ -21,6 +21,7 @@ Options {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
index 5d88e791..1a977a04 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
@@ -21,6 +21,7 @@ Options {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
index e0acdc93..15447ff4 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
@@ -19,6 +19,7 @@ Options {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
index 80f17bd6..437a0c56 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
@@ -6012,6 +6012,7 @@ Config {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
index e1e6b5e2..be893c70 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
@@ -6012,6 +6012,7 @@ Config {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
index 2ff6c915..94b90bde 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
@@ -106,6 +106,7 @@ Config {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
index aa0fe763..ca0ddf5c 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
@@ -21,6 +21,7 @@ Options {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
index c9d4c32a..7fc5882a 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
@@ -6012,6 +6012,7 @@ Config {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
index 98ebf1bb..48a25d83 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
@@ -6012,6 +6012,7 @@ Config {
copy_command: None,
copy_clipboard: None,
copy_on_select: None,
+ osc8_hyperlinks: None,
scrollback_editor: None,
session_name: None,
attach_to_session: None,