On 19.1.2020 12:44, Richard Ulmer wrote:
Hi, when using a $PS1, which has more than one line, `less --no-init` cuts of some lines at the top, when it quits. This is especially annyoing when using `git diff` and `git show`. For example, `echo "foo\nbar" | less --no-init --quit-if-one-screen` with a two-line $PS1 leads to terminal content like this: .-------------------. | bar | | ~ | | ~ | | PS1 line 1 | | PS1 line 2$ | `-------------------'
Here I am thinking what can be so useful to see after each command run on multiple lines of PS1.......................
I think, that using an environment variable like $PS1_LINES to inform less about a multiline $PS1, would be a solution for the problem. This is what I came up with: Index: usr.bin/less/funcs.h =================================================================== RCS file: /cvs/src/usr.bin/less/funcs.h,v retrieving revision 1.25 diff -u -p -u -r1.25 funcs.h --- usr.bin/less/funcs.h 2 Sep 2019 14:07:45 -0000 1.25 +++ usr.bin/less/funcs.h 19 Jan 2020 11:23:56 -0000 @@ -30,6 +30,7 @@ void ring_bell(void); void do_clear(void); void clear_eol(void); void clear_bot(void); +void clear_above_bot(int); void at_enter(int); void at_exit(void); void at_switch(int); Index: usr.bin/less/main.c =================================================================== RCS file: /cvs/src/usr.bin/less/main.c,v retrieving revision 1.37 diff -u -p -u -r1.37 main.c --- usr.bin/less/main.c 28 Jun 2019 05:44:09 -0000 1.37 +++ usr.bin/less/main.c 19 Jan 2020 11:23:56 -0000 @@ -47,6 +47,7 @@ extern char *tags; extern char *tagoption; extern int jump_sline; extern int less_is_more; +extern int ps1_lines; extern int missing_cap; extern int know_dumb; extern int quit_if_one_screen; @@ -102,6 +103,9 @@ main(int argc, char *argv[]) } } + if ((s = lgetenv("PS1_LINES")) != NULL) + ps1_lines = atoi(s); + /* * Process command line arguments and LESS environment arguments. * Command line arguments override environment arguments. @@ -383,8 +387,10 @@ quit(int status) edit(NULL); if (!secure) save_cmdhist(); - if (any_display && is_tty) + if (any_display && is_tty) { clear_bot(); + clear_above_bot(ps1_lines - 1); + } deinit(); flush(1); raw_mode(0); Index: usr.bin/less/opttbl.c =================================================================== RCS file: /cvs/src/usr.bin/less/opttbl.c,v retrieving revision 1.19 diff -u -p -u -r1.19 opttbl.c --- usr.bin/less/opttbl.c 17 Sep 2016 15:06:41 -0000 1.19 +++ usr.bin/less/opttbl.c 19 Jan 2020 11:23:56 -0000 @@ -53,6 +53,7 @@ int opt_use_backslash; /* Use backslash int hilite_search; /* Highlight matched search patterns? */ int less_is_more = 0; /* Make compatible with POSIX more */ +int ps1_lines = 1; /* Height of the primary prompt */ /* * Long option names. Index: usr.bin/less/screen.c =================================================================== RCS file: /cvs/src/usr.bin/less/screen.c,v retrieving revision 1.25 diff -u -p -u -r1.25 screen.c --- usr.bin/less/screen.c 3 Sep 2019 23:08:42 -0000 1.25 +++ usr.bin/less/screen.c 19 Jan 2020 11:23:56 -0000 @@ -34,6 +34,7 @@ static char *sc_lower_left, /* Cursor to last line, first column */ *sc_return, /* Cursor to beginning of current line */ *sc_move, /* General cursor positioning */ + *sc_up, /* Cursor up one line */ *sc_clear, /* Clear screen */ *sc_eol_clear, /* Clear to end of line */ *sc_eos_clear, /* Clear to end of screen */ @@ -87,6 +88,7 @@ extern int tty; extern int top_scroll; extern int oldbot; extern int hilite_search; +extern int ps1_lines; /* * Change terminal to "raw mode", or restore to "normal" mode. @@ -414,6 +416,10 @@ get_term(void) } sc_lower_left = cheaper(t1, t2, "\r"); + sc_up = cursor_up; + if (ps1_lines > 1 && sc_up == NULL) + missing_cap = 1; + /* * Get carriage return string. */ @@ -699,6 +705,20 @@ clear_bot(void) at_exit(); clear_eol_bot(); at_enter(saved_attrmode); + } +} + +/* + * Clear n lines above the bottom line of the display. + * The cursor must be set to the beginning of the bottom line before. + */ +void +clear_above_bot(int n) +{ + int i; + for (i = 0; i < n; i++) { + tputs(sc_up, 1, putchr); + tputs(sc_eol_clear, 1, putchr); } }