Interactive resize squishes tabs. #508

Closed
opened 5 months ago by brocellous · 5 comments

Steps to reproduce:

  1. echo "1\t2\t3\t4\t5"
  2. Perform an interactive resize to shrink the window by dragging the left border inwards.
  3. Reset foot to the original window size.

Expected: text remains in it's own column
Actual: text "falls" left like a rotated tetris game until the tabs completely disappear. The effect remains even after the window size is reset.

Steps to reproduce: 1. `echo "1\t2\t3\t4\t5"` 2. Perform an interactive resize to shrink the window by dragging the left border inwards. 3. Reset foot to the original window size. Expected: text remains in it's own column Actual: text "falls" left like a rotated tetris game until the tabs completely disappear. The effect remains even after the window size is reset.
Owner

Ah, yes. The problem is the way we handle \t when it's printed - it simply moves the cursor to the next tab stop without actually printing anything to the grid.

While this may sound very strange, it's actually not. For example, try the following in XTerm:

✓ daniel@mini ~% echo "1\t2  3\b5"    
1       2  5
✓ daniel@mini ~% echo "1\t2  3\b\t5"
1       2  3    5

Anyway, this behavior, when combined with the reflow logic that squishes empty cells (done to improve the handling of e.g. right-side "prompts"), results in what you're seeing.

Another problem with tabs is when you copy them - they will typically result in spaces being copied.

I think what we should do is write a \t to the grid when we receive a \t. That will allow grid parsing code to act on it. Then re-write the reflow code to translate tabs to the reflowed grid's tab stops.

Ah, yes. The problem is the way we handle `\t` when it's printed - it simply moves the cursor to the next tab stop without actually printing anything to the grid. While this may sound _very_ strange, it's actually not. For example, try the following in XTerm: ```sh ✓ daniel@mini ~% echo "1\t2 3\b5" 1 2 5 ✓ daniel@mini ~% echo "1\t2 3\b\t5" 1 2 3 5 ``` Anyway, this behavior, when combined with the reflow logic that squishes empty cells (done to improve the handling of e.g. right-side "prompts"), results in what you're seeing. Another problem with tabs is when you copy them - they will typically result in spaces being copied. I think what we should do is write a `\t` to the grid when we receive a `\t`. That will allow grid parsing code to act on it. Then re-write the reflow code to translate tabs to the reflowed grid's tab stops.
dnkl added the
bug
label 5 months ago
Owner

I think what we should do is write a \t to the grid when we receive a \t

Nope, can't do that... (the 5 should still be visible, right after the 3)

✓ daniel@mini ~/src/foot/bld/debug% echo "1\t2\t35\b\t4"
1	      2	      3	      4

Perhaps store it as a flag in the cell's attributes 🤔

I'll go seek inspiration in other terminal emulators.

> I think what we should do is write a \t to the grid when we receive a \t Nope, can't do that... (the 5 should still be visible, right after the 3) ``` ✓ daniel@mini ~/src/foot/bld/debug% echo "1\t2\t35\b\t4" 1 2 3 4 ``` Perhaps store it as a flag in the cell's attributes 🤔 I'll go seek inspiration in other terminal emulators.
Owner

Looks like the common thing to do is check the cell range from where we currently are, to the next tab stop. If all cells are empty, or spaces, write a \t to the current cell.

Then move the cursor to the next tab stop.

If there is anything else already printed somewhere in that cell range, only move the cursor, don't write a \t.

Just one example of this, this time from urxvt. Running this (move cursor back to the '3' before tabbing to '4'):

echo '1\t2\t3\b\t4\t5'

results in this when copied out:

1\t2\t3    4\t5 
Looks like the common thing to do is check the cell range from where we currently are, to the next tab stop. If all cells are empty, or spaces, write a `\t` to the current cell. _Then_ move the cursor to the next tab stop. If there is anything else already printed somewhere in that cell range, _only_ move the cursor, don't write a `\t`. Just one example of this, this time from urxvt. Running this (move cursor back to the '3' before tabbing to '4'): ```sh echo '1\t2\t3\b\t4\t5' ``` results in this when copied out: ``` 1\t2\t3 4\t5 ```
Owner

As part of #504, I'll most likely remove the heuristics that removes empty cells between non-empty cells. This was added to better handle zsh-style "right-side" prompts.

But given that it now both prevents us from further performance improvements in text reflow, and breaks tabs, it makes sense to remove it.

That will partly fix this issue. It'll still break if you shrink the window so that the 5 is reflowed to the next row, and then increase the window size again.

As part of https://codeberg.org/dnkl/foot/issues/504, I'll most likely remove the heuristics that removes empty cells between non-empty cells. This was added to better handle zsh-style "right-side" prompts. But given that it now both prevents us from further performance improvements in text reflow, **and** breaks tabs, it makes sense to remove it. That will partly fix this issue. It'll still break if you shrink the window so that the `5` is reflowed to the next row, and then increase the window size again.
dnkl added this to the 1.8.0 milestone 5 months ago
Owner

With #504 now being merged, tabs are handled better than before. But as already mentioned, a character (following a tab) that has been reflowed to the "next" line is still "squished" when the window size is increased again.

With #504 now being merged, tabs are handled better than before. But as already mentioned, a character (following a tab) that has been reflowed to the "next" line is still "squished" when the window size is increased again.
dnkl referenced this issue from a commit 5 months ago
dnkl closed this issue 5 months ago
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.