gwsw / less

Less - text pager
http://greenwoodsoftware.com/less
Other
530 stars 85 forks source link

Support for the terminal title as part of the prompt string #504

Open grawity opened 2 months ago

grawity commented 2 months ago

Up to less v590, I used to (ab)use $MANLESS – which the man tool injects into $LESS as the -P option, for customizing the prompt – to additionally set the terminal title to the name of the manual page being shown. (This was a convenient way to do it because man automatically fills in the actual name(section) it's currently showing, which isn't known upfront so doing it from a shell alias would be troublesome.).

It wasn't a very good method (as it caused less to think that the prompt was twice as long as it was, leading to it getting prematurely truncated), but it worked well enough.

Basically I had an \e]0;$MAN_PN\a (ESC ] 0 ... BEL) as part of $MANLESS:

# approximately the default value of 'man -r'
export MANLESS="?ltline %lt?L/%L.:byte %bB?s/%s..?pB (%pB\\%). "

# put "manpage(section)" in the terminal title for xterm, in the less prompt otherwise
case $TERM in
    xterm*) export MANLESS="${MANLESS}$(printf '\e]0;$MAN_PN\a')";;
    tmux*)  export MANLESS="${MANLESS}$(printf '\ek$MAN_PN\e\\\\')";;
    *)  export MANLESS="\$MAN_PN ${MANLESS}";;
esac

This stopped working in less v591, which enabled ANSI formatting in the prompt, but as a consequence the whole ESC ]0; now gets thrown away and the rest remains visible in the prompt.

gwsw commented 3 weeks ago

This should be addressed now in the post659 branch (as of c86d29d736f841cad2a0315a9e58a1c023990f2d). The xterm case should work without doing anything special. The tmux case uses a non-standard \ek sequence to introduce the title string. As far as I can see, this does not conform to ECMA-48, which defines \ek as VPB (LINE POSITION BACKWARD). So to make that work, you will need to define an environment variable LESSANSIOSCCHARS=k.

grawity commented 3 weeks ago

Thanks, I'll give that a try. The tmux case is actually for its "window/tab name" (it uses the regular xterm one for the pane title) – I believe it copied \ek from GNU Screen.

avih commented 3 weeks ago

This should be addressed now in the post659 branch (as of c86d29d). Pass through all OSC escape sequences (not just OSC 8).

The commit message doesn't state whether this passthrough refers to everything - including arbitrary content, or only the prompt string - which is controlled by "less" and/or the user, and which the content shouldn't able to control (e.g. sneaking embedded sequences at the file name).

It also doesn't state whether this works by default, or only in -R mode, or only in -r mode, and it also doesn't add any relevant docs notes.

I'd think the commit passthrough any OSC in content too, because it refers to "not only OSC8" - which is typically a content thing.

I don't think it's a good idea to allow passthrough of arbitrary OSC sequences at the content.

OSC sequences can result in unexpected "less" behavior, for instance copying text into the clipboard (OSC 52), or indeed changing the terminal title, or enabling unsafe windows operations (OSC 6), and more, and I don't think the content should be allowed to do that, not even with -R (but -r should probably allow that because I think that's what it does - passthrough all sequences).

I think the best thing is to never passthrough arbitrary OSC sequences at the content - not even with -r.

Instead, "less" should only allow safe sequences by default (like OSC 8) in -R and -r modes, and maybe there should be an option --allow-unsafe-sequences, which only applies to -r mode, or some such.

gwsw commented 3 weeks ago

You're correct that this change passes through all OSC commands. I was unsure about whether that's a good idea for the reasons you mention. Perhaps rather than an option that allows all sequences as you suggest, there should be a finer-grained option or environment variable that lists the allowed sequences, like LESSANSIOSCALLOW=0,8,52 or something like that. I think this should apply only to -R. The -r option passes through all escape sequences without interpretation, so has always allowed all OSC commands, which is one reason why it is deprecated.

avih commented 3 weeks ago

like LESSANSIOSCALLOW=0,8,52 or something like that

Better than arbitrary passthrough.

There might be a need to split the scope, e.g. to allow the user to specify title OSC (or whatever they want) at the prompt, but not for the content with -R (or maybe just an option to set the title to the prompt?).

Also, the file name at the prompt should be escaped, or display as if it was binary content without -R (I don't know how it's handled currently).

I think it should first be an option (CLI) to override ohers, and if it doesn't exist, possibly take the value from some specific env var or a general one (LESS), and then the default (probably 0,8 for the prompt, only 8 for -R).

In general:

gwsw commented 3 weeks ago

Also, the file name at the prompt should be escaped, or display as if it was binary content without -R (I don't know how it's handled currently).

This was recently fixed. See #503 and changes 2a642a07d86f7f9484db18cd748bc521e71c997f and bf14bc4a61e59674cfd4d93a9f2cfcb902a5951d.

gwsw commented 2 weeks ago

I'm thinking of making these changes:

  1. In the prompt, pass through SGR sequences as well as all OSC sequences, even if -R is not set. Currently sequences are passed through in the prompt only if -R is set but that doesn't seem necessary. This would allow a colored prompt even if you want to view uninterpreted sequences in the content.
  2. Retain the LESSANSIOSCCHARS variable to specify nonstandard sequences that initiate an OSC sequence, like \ek in tmux.
  3. Add the LESSANSIOSCALLOW variable as mentioned above. It would contain a list of OSC numbers that are passed through if they occur in the content. It could also contain nonstandard letters (from LESSANSIOSCCHARS) which will also be passed through if they occur in the content (e.g. LESSANSIOSCCHARS=k and LESSANSIOSCALLOW=0,k would pass through \e]0... and \ek.... Without LESSANSIOSCALLOW, LESSANSIOSCCHARS would apply only to the prompt.
  4. I'm not sure if OSC 8 would always be allowed, or if setting LESSANSIOSCALLOW but omitting "8" would turn off OSC 8 pass through.
avih commented 2 weeks ago

I'm not very familiar with all these env vars, but I think it sounds reasonable.

Would there be a method to override these config values from the command line options? (excluding invocation such as LESSFOO=... less ...)