aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-server/src/output
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-server/src/output
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-server/src/output')
-rw-r--r--zellij-server/src/output/mod.rs38
-rw-r--r--zellij-server/src/output/unit/output_tests.rs10
2 files changed, 40 insertions, 8 deletions
diff --git a/zellij-server/src/output/mod.rs b/zellij-server/src/output/mod.rs
index 0b23d9bb..180514ae 100644
--- a/zellij-server/src/output/mod.rs
+++ b/zellij-server/src/output/mod.rs
@@ -66,6 +66,7 @@ fn write_changed_styles(
current_character_styles: CharacterStyles,
chunk_changed_colors: Option<[Option<AnsiCode>; 256]>,
link_handler: Option<&std::cell::Ref<LinkHandler>>,
+ osc8_hyperlinks: bool,
vte_output: &mut String,
) -> Result<()> {
let err_context = "failed to format changed styles to VTE string";
@@ -73,10 +74,14 @@ fn write_changed_styles(
if let Some(new_styles) =
character_styles.update_and_return_diff(&current_character_styles, chunk_changed_colors)
{
- if let Some(osc8_link) =
- link_handler.and_then(|l_h| l_h.output_osc8(new_styles.link_anchor))
- {
- write!(vte_output, "{}{}", new_styles, osc8_link).context(err_context)?;
+ if osc8_hyperlinks {
+ if let Some(osc8_link) =
+ link_handler.and_then(|l_h| l_h.output_osc8(new_styles.link_anchor))
+ {
+ write!(vte_output, "{}{}", new_styles, osc8_link).context(err_context)?;
+ } else {
+ write!(vte_output, "{}", new_styles).context(err_context)?;
+ }
} else {
write!(vte_output, "{}", new_styles).context(err_context)?;
}
@@ -89,6 +94,7 @@ fn serialize_chunks_with_newlines(
_sixel_chunks: Option<&Vec<SixelImageChunk>>, // TODO: fix this sometime
link_handler: Option<&mut Rc<RefCell<LinkHandler>>>,
styled_underlines: bool,
+ osc8_hyperlinks: bool,
max_size: Option<Size>,
) -> Result<String> {
let err_context = || "failed to serialize input chunks".to_string();
@@ -129,6 +135,7 @@ fn serialize_chunks_with_newlines(
current_character_styles,
chunk_changed_colors,
link_handler.as_ref(),
+ osc8_hyperlinks,
&mut vte_output,
)
.with_context(err_context)?;
@@ -144,6 +151,7 @@ fn serialize_chunks(
link_handler: Option<&mut Rc<RefCell<LinkHandler>>>,
sixel_image_store: Option<&mut SixelImageStore>,
styled_underlines: bool,
+ osc8_hyperlinks: bool,
max_size: Option<Size>,
) -> Result<String> {
let err_context = || "failed to serialize input chunks".to_string();
@@ -186,6 +194,7 @@ fn serialize_chunks(
current_character_styles,
chunk_changed_colors,
link_handler.as_ref(),
+ osc8_hyperlinks,
&mut vte_output,
)
.with_context(err_context)?;
@@ -297,6 +306,7 @@ pub struct Output {
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
floating_panes_stack: Option<FloatingPanesStack>,
styled_underlines: bool,
+ osc8_hyperlinks: bool,
pane_render_report: PaneRenderReport,
cursor_coordinates: Option<(usize, usize)>,
}
@@ -306,11 +316,13 @@ impl Output {
sixel_image_store: Rc<RefCell<SixelImageStore>>,
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
styled_underlines: bool,
+ osc8_hyperlinks: bool,
) -> Self {
Output {
sixel_image_store,
character_cell_size,
styled_underlines,
+ osc8_hyperlinks,
..Default::default()
}
}
@@ -474,6 +486,7 @@ impl Output {
self.link_handler.as_mut(),
Some(&mut self.sixel_image_store.borrow_mut()),
self.styled_underlines,
+ self.osc8_hyperlinks,
None, // No size constraints for regular rendering
)
.with_context(err_context)?,
@@ -541,6 +554,7 @@ impl Output {
self.link_handler.as_mut(),
Some(&mut self.sixel_image_store.borrow_mut()),
self.styled_underlines,
+ self.osc8_hyperlinks,
max_size,
)
.with_context(err_context)?,
@@ -1083,7 +1097,12 @@ impl OutputBuffer {
self.changed_lines.clear();
self.should_update_all_lines = false;
}
- pub fn serialize(&self, viewport: &[Row], max_size: Option<Size>) -> Result<String> {
+ pub fn serialize(
+ &self,
+ viewport: &[Row],
+ osc8_hyperlinks: bool,
+ max_size: Option<Size>,
+ ) -> Result<String> {
let mut chunks = Vec::new();
for (line_index, line) in viewport.iter().enumerate() {
let terminal_characters =
@@ -1093,7 +1112,14 @@ impl OutputBuffer {
let y = line_index;
chunks.push(CharacterChunk::new(terminal_characters, x, y));
}
- serialize_chunks_with_newlines(chunks, None, None, self.styled_underlines, max_size)
+ serialize_chunks_with_newlines(
+ chunks,
+ None,
+ None,
+ self.styled_underlines,
+ osc8_hyperlinks,
+ max_size,
+ )
}
pub fn changed_chunks_in_viewport(
&self,
diff --git a/zellij-server/src/output/unit/output_tests.rs b/zellij-server/src/output/unit/output_tests.rs
index caa42ef4..4a25748d 100644
--- a/zellij-server/src/output/unit/output_tests.rs
+++ b/zellij-server/src/output/unit/output_tests.rs
@@ -15,7 +15,13 @@ fn create_test_output() -> Output {
width: 10,
})));
let styled_underlines = true;
- Output::new(sixel_image_store, character_cell_size, styled_underlines)
+ let osc8_hyperlinks = true;
+ Output::new(
+ sixel_image_store,
+ character_cell_size,
+ styled_underlines,
+ osc8_hyperlinks,
+ )
}
/// Helper to create a simple CharacterChunk with text
@@ -846,7 +852,7 @@ fn test_output_buffer_serialize() {
let row = Row::from_columns(columns);
let viewport = vec![row];
- let result = buffer.serialize(&viewport, None).unwrap();
+ let result = buffer.serialize(&viewport, true, None).unwrap();
// Should contain the character and newlines/carriage returns
assert!(result.contains('A'), "Serialized output should contain 'A'");