From c0a0af313396020782d541a32d44b1e4984976f9 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Thu, 18 Feb 2021 11:07:57 +0100 Subject: [PATCH] fix(compatibility): do not forward tabs to the terminal (#190) * fix(compatibility): do not forward tabs to the terminal * style(fmt): rustfmt --- src/client/panes/grid.rs | 13 ++++ src/client/panes/terminal_pane.rs | 7 +- src/tests/fixtures/exa_plus_omf_theme | Bin 0 -> 15802 bytes src/tests/integration/compatibility.rs | 29 +++++++++ ...lity__display_tab_characters_properly.snap | 6 +- ...on__compatibility__exa_plus_omf_theme.snap | 61 ++++++++++++++++++ ...__compatibility__fish_paste_multiline.snap | 6 +- 7 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 src/tests/fixtures/exa_plus_omf_theme create mode 100644 src/tests/integration/snapshots/zellij__tests__integration__compatibility__exa_plus_omf_theme.snap diff --git a/src/client/panes/grid.rs b/src/client/panes/grid.rs index 6dfc3140..f2aa848c 100644 --- a/src/client/panes/grid.rs +++ b/src/client/panes/grid.rs @@ -3,6 +3,8 @@ use std::{ fmt::{self, Debug, Formatter}, }; +static TABSTOP_WIDTH: usize = 8; // TODO: is this always right? + use crate::panes::terminal_character::{ CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER, }; @@ -172,6 +174,17 @@ impl Grid { height: rows, } } + pub fn advance_to_next_tabstop(&mut self, styles: CharacterStyles) { + let columns_until_next_tabstop = TABSTOP_WIDTH - (self.cursor.x % TABSTOP_WIDTH); + let columns_until_screen_end = self.width - self.cursor.x; + let columns_to_advance = + std::cmp::min(columns_until_next_tabstop, columns_until_screen_end); + let mut empty_character = EMPTY_TERMINAL_CHARACTER; + empty_character.styles = styles; + for _ in 0..columns_to_advance { + self.add_character(empty_character) + } + } fn cursor_canonical_line_index(&self) -> usize { let mut cursor_canonical_line_index = 0; let mut canonical_lines_traversed = 0; diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs index e00b323d..e35c2097 100644 --- a/src/client/panes/terminal_pane.rs +++ b/src/client/panes/terminal_pane.rs @@ -412,12 +412,7 @@ impl vte::Perform for TerminalPane { } 9 => { // tab - let terminal_tab_character = TerminalCharacter { - character: '\t', - styles: self.pending_styles, - }; - // TODO: handle better with line wrapping - self.grid.add_character(terminal_tab_character); + self.grid.advance_to_next_tabstop(self.pending_styles); } 10 => { // 0a, newline diff --git a/src/tests/fixtures/exa_plus_omf_theme b/src/tests/fixtures/exa_plus_omf_theme new file mode 100644 index 0000000000000000000000000000000000000000..e3d5ba60f7ac5966c5a3300be6cd40e8a3635069 GIT binary patch literal 15802 zcmeHO&2HO95caL10X=~(JoZq@qD0w_4YWuUCvel)MSj|YQ3NY;CDPjE5+r3uKJ)=v zpnZ+r`c8S0ezT-#*`!=5iX8=@4>GhI&U`aFTn~mn#%U`*0fZI%zNnU(s zCLT9Okc*LB^X!Lir(=6t%};XN>LU;~MPyfg{PU0Rvj}8i z>B--BoGfzL6&0BCm`Ta}ARGSp&%YRd**x2~2lMN8M_QeO?%sjjNu}VR)!855U)LUN z2?+Np3HKpYS@cn6{;|Aa;P!;y1+G8XTJV9?bmurfO-+jBla%a|@A;kGyI}7Q9>IA_ ziaFxN1i$-6_*>Zs<=m}jNT;Bn3>2c`gV%sbTmH-=>Bq6Jg1C9skw_t1zVWYk{^ecF zqx{P=mT>cxa{ZCd-F)$`uOR) zx5prq1(AVM49w)%zBQ_ODEAa)-7L^SJs+?tu-r8$Q)#s!T#22T( z9KAkyaxyr&r}VQbKEVZKKOGN_PTt%XEW54OuQe8y*GEsDy&`z&y7FanuJG_?aN@|> zEO`6r(wD(Y@Z-Ug%|f{F1AJBp+bI*R#CFPV1kh5pQzl!p9ldzf zY)3OjP@9_VWW4&pc5$V@_BGp~HwQJ_dEl2kg?)RrwR3B>qqn-{KNf|k)of>l7mKCq zA2#bX+sXH>`ep9YH?zwExbbWU8`ZSBv&qGs;;#9Q;!aVxW;=Nn=k>B;lq%MC%5JRL zP9ETenonKZq2KFUktr5(YPM6e9ppfv)LGYdZd8z0TTKev;W>$@Ydc+8*LL*Lg~e+6 z-HUKt+j+=S9@ku=uI=d4F>8P1XW!;zXQPj@;dDXu+D=h;DcdO%UAeYXrX=6uRj%!n zX<50pQ&h6Fwo@irskT#g<1)5WCR^8b%3s&jC)u(Cf++XYC)xBl$yJ$Q)m_~6&*{QJ zgu1p<*LD`p$gX)pw(&Lulm&^P_BXMBP)=9I{71^!RGZu369ZoAS=O zYFFYx*9b-nL~cF5_Nb-Ennz@zrKlLsJ+u^IS}ds~?B6;HxGoC#X2}~$ZW+kB#|p4| zJ%WWlGmFWtTxX)84p6RhkHK9IJ%(Tx=puw-BX(32dT1|fY%_oC zCAi3?I`>>g168J)e0je!vw-ysIg#I>LQgNF^A;UL`_MlzTv`$oFB1F<*emK(~t>> zCCroDB|$jlJ1vKiN;O0lq@eLR!R3JYBosn9jgw3;53ey&A4r6YSOw>fM=^@0u}4PL zhg6L*=0T#A7E^-Bp$jnaOmsWLfIObMamWLQVmkI&K+uCJoTi8-Y?3I}*mj2J$_rqF zWD-nwGDX~!!*#3@?s$O;*_a`^*^C?GU^<&{b`CL$q5(aW5fBg@Qvrj}rQ8vNzc3x* zYKj+qKYl_srHUf7he9mElw~$U9z`>nk0er41k6#R5eE#H`eO~lW0BxGQ*>&P+$HD9 zIh&Cv>=?eQF^AKLP))~U?lQEXIx{^?&8aX4qv32UnLxrA#-&e9s<>~=VHA#^Gl%hn zUwDWlTyd3zs!JqWOFzPpO^YBHMch~#xKuEjqLU8lXTFrceE#D_-iW;1ui zeYohV>DY_e%rGXAAHzKd{zIr02P{N94C9K2-VCATjvypZZ$xT1oTbL_^-3oWJf+m0 b=YSD2WQs(t%va_5fPA-lKQOp{@g?eie{GWz literal 0 HcmV?d00001 diff --git a/src/tests/integration/compatibility.rs b/src/tests/integration/compatibility.rs index 213d2bbb..e0233022 100644 --- a/src/tests/integration/compatibility.rs +++ b/src/tests/integration/compatibility.rs @@ -507,3 +507,32 @@ pub fn top_and_quit() { get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); assert_snapshot!(snapshot_before_quit); } + +#[test] +pub fn exa_plus_omf_theme() { + // this tests that we handle a tab delimited table properly + // without overriding the previous content + // this is a potential bug because the \t character is a goto + // if we forwarded it as is to the terminal, we would be skipping + // over existing on-screen content without deleting it, so we must + // convert it to spaces + let fake_win_size = PositionAndSize { + columns: 235, + rows: 56, + x: 0, + y: 0, + }; + let fixture_name = "exa_plus_omf_theme"; + let mut fake_input_output = get_fake_os_input(&fake_win_size, fixture_name); + fake_input_output.add_terminal_input(&[&COMMAND_TOGGLE, &QUIT]); + start(Box::new(fake_input_output.clone()), CliArgs::default()); + let output_frames = fake_input_output + .stdout_writer + .output_frames + .lock() + .unwrap(); + let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size); + let snapshot_before_quit = + get_next_to_last_snapshot(snapshots).expect("could not find snapshot"); + assert_snapshot!(snapshot_before_quit); +} diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap index ff52b200..8af4cae0 100644 --- a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__display_tab_characters_properly.snap @@ -10,12 +10,12 @@ expression: snapshot_before_quit Disk usage: df: /run/user/1000/doc: Operation not permitted - / 321G / 514G 66% - /efi 27M / 96M 28% + / 321G / 514G 66% + /efi 27M / 96M 28% Network: - wlp2s0 192.168.0.3 + wlp2s0 192.168.0.3 [I] [20:07] kingdom:mosaic (main) | █ diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__exa_plus_omf_theme.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__exa_plus_omf_theme.snap new file mode 100644 index 00000000..b09189f4 --- /dev/null +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__exa_plus_omf_theme.snap @@ -0,0 +1,61 @@ +--- +source: src/tests/integration/compatibility.rs +expression: snapshot_before_quit + +--- +.rw-r--r-- 3.3k aram 11 Jan 16:09 CODE_OF_CONDUCT.md +.rw-r--r-- 3.5k aram 17 Feb 16:06 CONTRIBUTING.md +drwxr-xr-x - aram 10 Feb 11:53 default-tiles +drwxr-xr-x - aram 10 Feb 11:53 docs +.rw-r--r-- 2.1k aram 10 Feb 11:53 GOVERNANCE.md +.rw-r--r-- 1.1k aram 10 Feb 11:53 LICENSE.md +.rw-r--r-- 4.7k aram 17 Feb 16:06 README.md +drwxr-xr-x - aram 17 Feb 16:06 src +drwxr-xr-x - aram 17 Feb 16:08 target +drwxr-xr-x - aram 17 Feb 16:06 zellij-tile +⋊> ~/c/zellij on main ⨯ ll 10:27:45 +Permissions Size User Date Modified Name +drwxr-xr-x - aram 11 Feb 14:04 assets +.rwxr-xr-x 596 aram 17 Feb 16:06 build-all.sh +.rw-r--r-- 1.4k aram 17 Feb 16:06 build.rs +.rw-r--r-- 56k aram 17 Feb 16:07 Cargo.lock +.rw-r--r-- 2.1k aram 17 Feb 16:06 Cargo.toml +.rw-r--r-- 3.3k aram 11 Jan 16:09 CODE_OF_CONDUCT.md +.rw-r--r-- 3.5k aram 17 Feb 16:06 CONTRIBUTING.md +drwxr-xr-x - aram 10 Feb 11:53 default-tiles +drwxr-xr-x - aram 10 Feb 11:53 docs +.rw-r--r-- 2.1k aram 10 Feb 11:53 GOVERNANCE.md +.rw-r--r-- 1.1k aram 10 Feb 11:53 LICENSE.md +.rw-r--r-- 4.7k aram 17 Feb 16:06 README.md +drwxr-xr-x - aram 17 Feb 16:06 src +drwxr-xr-x - aram 17 Feb 16:08 target +drwxr-xr-x - aram 17 Feb 16:06 zellij-tile +⋊> ~/c/zellij on main ⨯ omf theme 10:27:45 +Installed: +agnoster chain default plain + +Available: +agnoster eden lavender scorphish +aight emoji-powerline lolfish separation +ays es mars shellder +batman fishbone mish simple-ass-prompt +beloglazov fishface mokou simplevi +bira fishy-drupal mtahmed slavic-cat +bobthefish fisk nai spacefish +bongnoster fox nelsonjchen sushi +boxfish gentoo neolambda syl20bnr +budspencer gianu numist taktoa +cbjohnson gitstatus ocean technopagan +chain gnuykeaj one toaster +clearance godfather pastfish tomita +cmorrell graystatus perryh trout +coffeeandcode harleen plain tweetjay +cor idan pure uggedal +cyan integral pygmalion will +dangerous jacaetevha random wolf-theme +default johanson randomrussel yimmy +dmorrell kawasaki redfish zeit +doughsay krisleech red-snapper zephyr +eclm l robbyrussell zish +edan lambda sashimi +⋊> ~/c/zellij on main ⨯ █ 10:27:46 diff --git a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap index 08f59e5a..3a983165 100644 --- a/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap +++ b/src/tests/integration/snapshots/zellij__tests__integration__compatibility__fish_paste_multiline.snap @@ -10,12 +10,12 @@ expression: snapshot_before_quit Disk usage: df: /run/user/1000/doc: Operation not permitted - / 295G / 514G 61% - /efi 27M / 96M 28% + / 295G / 514G 61% + /efi 27M / 96M 28% Network: - wlp2s0 192.168.0.3 + wlp2s0 192.168.0.3 [I] [21:58] kingdom:mosaic (main) | echo -ne (\ df -l -h | grep -E 'dev/(xvda|sd|mapper)' | \