Menu

#302 Use the last column

v3.8
closed-fixed
None
v3.7
5
2015-03-24
2014-11-14
No

joe doesn't use the last column. On one hand it looks ugly, on another hand it's a waste of useful screen real estate.

Many other apps are able to use that, including the bottom right corner, e.g. tmux's default status bar, mc's button bar (if the screen is a bit narrower than 80) etc.

In all terminals I've seen, the cursor doesn't wrap to the next line when a character is printed, instead it stays there. Therefore printing in the last column, including the botton right corner without causing the screen to scroll, is a trivial thing to do.

If there's a terminal that would scroll, there's still a possible workaround: (assuming 80 columns) print the first 78 characters, followed by the 80th, then move the cursor back, print '\e[@' which inserts a space pushing the rest to the right (moving that character to its proper place) and finally print thte 79th character. (I'm not sure how to detect terminals that need and do indeed support this workaround. Maybe it's just enough to detect such terminals and fall back to one less column. Maybe you don't have to care about them at all. Maybe such terminals don't even exist anymore, I don't know.)

See a modified version of joe at https://code.google.com/p/pts-mini-gpl/source/browse/trunk/joe-p37 which somehow implements this.

Discussion

  • Egmont Koblinger

    Here's a first patch. The most important bits of the documentation are inside the patch.

    It's to some extent based on the aforementioned branch. I've cleaned it up, fixed a few things, and omitted the char insertion way of printing to the right column for terminals that immediately wrap the cursor upon reaching the rightmost column, reverting to one less column then. I did this because every graphical terminal I've encountered, plus the Linux console all don't wrap, so this complicated code of char insertion (especially with CJK handling) is of very little practical use.

    For multi-column menus I also addressed some suspicious off-by-ones. I went for the design that here we still don't want to use the rightmost column because the cursor sometimes stands there (after the text itself), so every column is of "width+1" character wide, "width" being the width of the longest label, and 1 space separating them or terminating the last one, potentially holding the cursor. So with terminals where we don't print to the rightmost column these menues end up not using the 2 rightmost ones, as I believe they did so far anyways.

    In all modern terminals, joe should use all the columns with this patch. To test legacy terminals, try TERM=ansi, or any other where "infocmp -C" doesn't report the "xn" capability.

    The changes to eraeol() deserve two comments.

    • There's an internal two-dimensional array of w*h size, s[w] and a[w] used to access the cell belonging to the last unused column, which were probably uninitialized or I don't know what (unless I totally miss something here). Now they'd overflow and access the 1st char of the next row, or for the last row actually address beyond the array. I also don't quite get what the whole intent was.

    • Joe preferred to emit up to 2 spaces to erase, rather than the escape sequence \e[K, because 1 or 2 spaces is fewer bytes than 3. However, in modern graphical terminals this often resulted in these spaces ended up in the copy-paste buffer after highlighting that part. For better copy-paste experience, it's better to always print \e[K even if it's more bytes, beucase then those spaces that were emitted to erase other characters won't end up in the buffer.

    With these two in mind, it seemed to be better to just drop that optimization attempt.

     
  • Egmont Koblinger

    Same for current mercurial for convenience

     
  • John J. Jordan

    John J. Jordan - 2015-02-17

    This looks pretty good. Nice work adapting this (and of course to pts :-).

    My only question in the code is in regards to this:

       /* TODO: move computation of ss & aa here */
    

    Is this as straightforward as it looks? (Move 'if (t->ce)' to the top of the method do everything else in 'else')

     
  • Egmont Koblinger

    I guess so, they're no longer used in the t->ce branch which is executed for almost every terminal.

    What I'm a bit worried about is I have a commented out fixupcursor() somewhere, maybe that should be enabled for a while until we completely understand when this method should be called. It should be harmless. Or at least the patch should undergo quite some testing. Anyway, I'll be using my joe with this patch and let you know if I encounter any problems.

     
  • John J. Jordan

    John J. Jordan - 2015-02-17

    From a cursory look... It's probably best left in there. This appears to fix up the corner case where the terminal state says the cursor is one past the last column (and actually, I'd like to see that be >= instead of ==). Ensuring that we always leave the outatr function (which writes pretty much everything to the screen) in a good state sounds right to me. The other one in cposs gets called earlier in outatr which would fix up the state from the previous call... assuming we didn't write anything to the terminal inbetween :-)

     
  • Joe Allen

    Joe Allen - 2015-03-14

    The patch looks good to me so I applied it to hg [17bc0c].
    It's so weird seeing JOE using the 80th column :-)

     

    Related

    Commit: [17bc0c]

  • Joe Allen

    Joe Allen - 2015-03-14
    • status: open --> closed
     
  • Egmont Koblinger

    Thanks!

    I'm sure you'll get used to it just a matter of years :)

     
  • John J. Jordan

    John J. Jordan - 2015-03-24
    • status: closed --> closed-fixed
    • assigned_to: Egmont Koblinger
    • Applies To: --> v3.7
    • Group: Unknown --> v3.8
     

Log in to post a comment.