Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Per Bothner
specifications
Commits
43f2bf68
Commit
43f2bf68
authored
Sep 29, 2019
by
Per Bothner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update specification and add scripts.
parent
f19a6c1a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
176 additions
and
33 deletions
+176
-33
proposals/semantic-prompts.md
proposals/semantic-prompts.md
+62
-33
shell-integration.bash
shell-integration.bash
+34
-0
shell-integration.fish
shell-integration.fish
+55
-0
shell-integration.zsh
shell-integration.zsh
+25
-0
No files found.
proposals/semantic-prompts.md
View file @
43f2bf68
...
...
@@ -14,7 +14,7 @@ where each _command_ is a sequence of _user input_ (one or more lines typed by t
The input lines will usually contain _prompt_ sections emitted
by the application, usually at the beginning of the first line.
This protoc
a
l defines a way for an application to specify to a terminal
This protoc
o
l defines a way for an application to specify to a terminal
the start and end of commands and their parts: input, prompt, and output.
This can enable useful features like visual separation/highlighting
of commands; folding (a button to hide long command output);
...
...
@@ -28,11 +28,6 @@ Other similar prior art is known for
[
XMLterm
](
www.xml.com/pub/2000/06/07/xmlterm/index.html
)
,
and
[
GraphTerm
](
https://github.com/mitotic/graphterm
)
.
**Issue:**
: The protocol needs to be tested, to see
how well it supports various shells.
Especially needing testing are handling of multi-line inputs, and right prompts.
[
DomTerm
](
https://domterm.org
)
will be used for prototyping.
# Detail
A command sequence may be nested withing the output section of
...
...
@@ -55,9 +50,10 @@ application; if that is unavailable, the name of the application.
> First do a _fresh-line_.
> Then start a new command, and enter prompt mode: Subsequent text
> (until a `OSC "133;B"` or `OSC "133;I"` command) is a prompt string.
> (until a `OSC "133;B"` or `OSC "133;I"` command) is a prompt string
> (as if followed by `OSC 133;P;k=i\007`).
> Applicable options: `aid`, `cl
ick-move`, `repaint
`.
> Applicable options: `aid`, `cl`.
`OSC "133;N"`
_options_
`"\007"`
...
...
@@ -67,18 +63,20 @@ application; if that is unavailable, the name of the application.
> (as well as any other commands nested more deeply).
> If no `aid` is specified, treat as an `aid` whose value is the empty string.
> Applicable options: `aid`, `cl
ick-move`, `repaint
`.
> Applicable options: `aid`, `cl`.
`OSC "133;P"`
_options_
`"\007"`
> Start of secondary prompt. This is used for multi-line prompts,
> right-side prompts, and prompts for continuation lines.
> Explicit start of prompt. Optional after an `A` or `N` command.
> The `k` (kind) option specifies the type of prompt:
> regular primary prompt (`k=i` or default),
> right-side prompts (`k=r`), or prompts for continuation lines (`k=c`).
> Applicable options: `kind
`
.
> Applicable options: `
k` (
kind
)
.
`OSC "133;B"`
_options_
`"\007"`
> End of prompt and start of user input, terminated
> by a `OSC "133;C"`.
> by a `OSC "133;C"`
or another prompt (`OSC "133;P"`)
.
`OSC "133;I"`
_options_
`"\007"`
> End of prompt and start of user input, terminated
...
...
@@ -95,7 +93,9 @@ application; if that is unavailable, the name of the application.
> Applicable options: `aid`, `cancel`.
`OSC "133;D"`
[
`";"`
_exit-code_]
`"\007"`
> Same as `OSC "133;Z"` [`";exitcode="` _exit-code_]`"\007"`.
> Same as `OSC "133;Z"` [`";err="` _exit-code_]`"\007"`
> (except that a zero _exit-code_ is equivalet to `OSC "133;Z\007"`
> without the _exit-code_).
> For backward compatibility with Iterm2/FinalTerm.
## General options syntax
...
...
@@ -123,13 +123,18 @@ A terminal must ignore an _option_ whose _option-name_ it doesn't recognize.
> A command was cancelled before execution started, for example by
> typing ctrl-c on Unix-like systems (sending `SIGINT`) during input editing.
`e
xitcode
=`
_value_
`e
rr
=`
_value_
> Only applicable to a `OSC "133;Z"`command.
> Specifies an integer value that reports
> an exit code from the command. This should be a non-negative integer,
> where 0 means successful completion, and non-zero for failure.
> Specifies a string value that reports an error code from the command.
> Note that any non-empty _value_ should be displayed as an error, even 0.
> A non-error is indicated by a missing `err` option or en empty _value_.
> This generality is to support command processors that don't
> follow the standard Unix convention of 0 for success.
> For a Unix-like shells, on success (zero exit code) there should be
> no `err` option or an empty `err` option;
> on failure (non-zero exit code), _value) should be the exit code.
`cl
ick-move
=`
_value_
`cl=`
_value_
> This option is defined for `A` or `N` commands.
...
...
@@ -142,23 +147,23 @@ A terminal must ignore an _option_ whose _option-name_ it doesn't recognize.
> especially for beginners, who are often surprised when a mouse
> click doesn't move the cursor.
> The _value_ can be one of `line`, `m
ulti
`, `v
move
`, or `
vmove+
`,
> The _value_ can be one of `line`, `m`, `v`, or `
w
`,
> specifying what kind of cursor key sequences are handled by the application.
> The value `line` allows motion within single input line, using
> using standard left/right arrow escape sequences
> (or overridden by `'move-keys`). Only a single left/right sequence
> should be emitted for double-width characters.
> The value `m
ulti`
allows movement between different lines
> The value `m
` (for "multiple")
allows movement between different lines
> (in the same group), but only using left/right arrow escape sequences.
> The values `v
move
` or `
vmove+
` is like `m
ulti
` but cursor up/down should
> The values `v` or `
w
` is like `m` but cursor up/down should
> be used.
> Using `
vmove+
` specifies that that there are no spurious spaces
> Using `
w
` specifies that that there are no spurious spaces
> (written by the application though not typed by the user)
> at the end of the line, _and_ that the application editor handles
> "smart vertical movement". (This means that moving 2 lines up from
> character position 20, where the intermediate line is 15 characters wide
> and the destination line is 18 characters wide, ends at position 18.)
> If `v
mode
` is specified instead of `
vmode+
` then the terminal
> If `v` is specified instead of `
w
` then the terminal
> should be more conservative when moving between lines:
> It should move the cursor left to the start of line, then emit the needed
> up or down sequences, then move the cursor right to the clicked destination.
...
...
@@ -171,15 +176,13 @@ A terminal must ignore an _option_ whose _option-name_ it doesn't recognize.
> The defaults are the standard arrow-key sequences: `CSI D` etc.
> (_Note:_ this is an example where allowing quoted strings would be useful.)
`repaint`
> Used before repainting the active input line(s): Clear the
> input area of data and re-use it.
`kind=`
_prompt_kind_
`k=`
_prompt_kind_
> Specify the kind of prompt sequence.
> Currently `right` is the only specified _prompt_kind_.
> When reflowing lines with a `right` prompt, a terminal may optionally
> adjust spacing so the `right` prompt stays at the right end of the line.
> A normal left first-line prompt has kind `i` (initial), which is the default.
> Continuation prompts have kind `c` (continuation).
> A right-aligned prompt has kind `r` (right).
> When reflowing lines with a `r` prompt, a terminal may optionally
> adjust spacing so the right prompt stays at the right end of the line.
## Input lines
...
...
@@ -246,7 +249,7 @@ line-wrap indicators to be correct.
Many terminals re-flow long (wrapped) lines when the containing
window changes size. It is recommended that terminal should _not_
re-flow the current input area when the cursor is in the area.
The reason is that most input editors will repain
g
the input area
The reason is that most input editors will repain
t
the input area
on windows resize, and inconsistencies are possible if both
terminal and application try to re-flow, as there is no easy synchronization.
...
...
@@ -284,6 +287,32 @@ like column position, but double-width characters only count one.)
If the count is positive, that many _right_ sequences (by default
`CSI C`
)
are sent; if negative, that many _left_ sequences (by default
`CSI D`
).
## Omitted-newline sequence
Both fish and zsh emit after a command finishes special strings
to deal with output that does not end with a newline.
These strings have no effect for output that (correctly) ends with a newline,
but otherwise they append a special marker, and add the missing newline.
Such "omitted-newline" sequences can be emitted before or after the
end-of-commmand sequence (
`D`
or
`Z`
), but must be emitted before
the next start-of-command seuqnec (
`A`
or
`N`
).
Note that re-flow due to making the window narrower may
cause an extra undesired blank line.
A _fresh-line_ sequence (
`L`
) does not have that downside, but
it doesn't have a way to specify a marker.
# Resources
## Bash
[
Initialization script for bash (the Bourne-Again SHell)
](
./shell-integration.bash
)
## DomTerm
[
DomTerm
](
https://domterm.org
)
implements the latest version of this specification.
# Open Questions
See the paragraphs starting with
**Issue:**
.
shell-integration.bash
0 → 100755
View file @
43f2bf68
#source /home/bothner/DomTerm/tools/bash-preexec.sh
thisfile
=
"
$BASH_SOURCE
"
case
"
$thisfile
"
in
""
)
echo
"installation error - can't find path to
$0
"
;
exit
-1
;;
/
*
)
;;
*
)
thisfile
=
"
$PWD
/
$thisfile
"
;;
esac
while
test
-L
"
$thisfile
"
;
do
thisfile
=
$(
readlink
-f
"
$thisfile
"
)
;
done
source
`
dirname
"
$thisfile
"
`
/bash-preexec.sh
#PS1='\[\e]133;P\a\]'$PS1'\[\e]133;B\a\e]122;> \a\]'
#PS1='\[\e]133]A;repaint;aid='"$BASHPID"'\a\e]133;P\a\]'$PS1'\[\e]133;B\a\e]122;> \a\]'
function
__prompt_precmd
()
{
local
ret
=
"
$?
"
local
err
=
`
if
test
"
$ret
"
!=
"0"
;
then
echo
";err=
$ret
"
;
fi
`
_PROMPT_SAVE_PS1
=
"
$PS1
"
_PROMPT_SAVE_PS2
=
"
$PS2
"
PS1
=
'\[\e]133;P;k=i\a\]'
$PS1
'\[\e]133;B\a\e]122;> \a\]'
PS2
=
'\[\e]133;P;k=c\a\]'
$PS2
'\[\e]133;B\a\]'
if
test
"
$_prompt_executing
"
=
"1"
then
printf
"
\0
33]133;Z%s;aid=%s
\0
07"
"
$err
"
"
$BASHPID
"
fi
printf
"
\0
33]133;A;cl=m;aid=%s
\0
07"
"
$BASHPID
"
_prompt_executing
=
0
}
function
__prompt_preexec
()
{
PS1
=
"
$_PROMPT_SAVE_PS1
"
PS2
=
"
$_PROMPT_SAVE_PS2
"
printf
"
\0
33]133;C;
\0
07"
_prompt_executing
=
1
}
preexec_functions+
=(
__prompt_preexec
)
precmd_functions+
=(
__prompt_precmd
)
shell-integration.fish
0 → 100644
View file @
43f2bf68
if status --is-interactive
set _fishprompt_aid "fish"$fish_pid
set _fishprompt_started 0
# empty if running; or a numeric exit code; or CANCEL
set _fishprompt_postexec ""
functions -c fish_prompt _fishprompt_saved_prompt
set _fishprompt_prompt_count 0
set _fishprompt_disp_count 0
function _fishprompt_start --on-event fish_prompt
set _fishprompt_prompt_count (math $_fishprompt_prompt_count + 1)
# don't use post-exec, because it is called *before* omitted-newline output
if [ -n "$_fishprompt_postexec" ]
set ret (if test "$_fishprompt_postexec" != "0"; echo ";err=$_fishprompt_postexec"; end)
printf "\033]133;Z%s;aid=%s\007" "$ret" $_fishprompt_aid
end
printf "\033]133;A;aid=%s;cl=m\007" $_fishprompt_aid
end
function fish_prompt
set _fishprompt_disp_count (math $_fishprompt_disp_count + 1)
printf "\033]133;P;k=i\007%b\033]133;B\007" (string join "\n" (_fishprompt_saved_prompt))
set _fishprompt_started 1
set _fishprompt_postexec ""
end
function _fishprompt_preexec --on-event fish_preexec
if [ "$_fishprompt_started" = "1" ]
printf "\033]133;C;\007"
end
set _fishprompt_started 0
end
function _fishprompt_postexec --on-event fish_postexec
set _fishprompt_postexec $status
end
function __fishprompt_cancel --on-event fish_cancel
set _fishprompt_postexec CANCEL
_fishprompt_start
end
function _fishprompt_exit --on-process %self
if [ "$_fishprompt_started" = "1" ]
printf "\033]133;Z;aid=%s\007" $_fishprompt_aid
end
end
if functions -q fish_right_prompt
functions -c fish_right_prompt _fishprompt_saved_right_prompt
function fish_right_prompt
printf "\033]133;P;k=r\007%b\033]133;B\007" (string join "\n" (_fishprompt_saved_right_prompt))
end
end
end
shell-integration.zsh
0 → 100755
View file @
43f2bf68
#PS1='\[\e]133;P\a\]'$PS1'\[\e]133;B\a\e]122;> \a\]'
#PS1='\[\e]133]A;repaint;aid='"$BASHPID"'\a\e]133;P\a\]'$PS1'\[\e]133;B\a\e]122;> \a\]'
function
__prompt_precmd
()
{
local
ret
=
"
$?
"
local
err
=
`
if
test
"
$ret
"
!=
"0"
;
then
echo
";err=
$ret
"
;
fi
`
_PROMPT_SAVE_PS1
=
"
$PS1
"
_PROMPT_SAVE_PS2
=
"
$PS2
"
PS1
=
$'%{
\e
]133;P;k=i
\a
%}'
$PS1
$'%{
\e
]133;B
\a\e
]122;>
\a
%}'
PS2
=
$'%{
\e
]133;P;k=c
\a
%}'
$PS2
$'%{
\e
]133;B
\a
%}'
if
test
"
$_prompt_executing
"
=
"1"
then
printf
"
\0
33]133;Z%s;aid=%s
\0
07"
"
$err
"
"
$$
"
fi
printf
"
\0
33]133;A;cl=m;aid=%s
\0
07"
"
$$
"
_prompt_executing
=
0
}
function
__prompt_preexec
()
{
PS1
=
"
$_PROMPT_SAVE_PS1
"
PS2
=
"
$_PROMPT_SAVE_PS2
"
printf
"
\0
33]133;C;
\0
07"
_prompt_executing
=
1
}
preexec_functions+
=(
__prompt_preexec
)
precmd_functions+
=(
__prompt_precmd
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment