Improved support for leading newline
* New modes that either print it only when it isn't the first line, or only add it (as well as a warning) if the last command didn't return a newline. * Overengineered af.
This commit is contained in:
parent
eeed7e79a1
commit
a595d71cbd
9 changed files with 149 additions and 11 deletions
12
README.md
12
README.md
|
@ -142,8 +142,16 @@ The `layout_*` variables control the prompt's layout and general appearance:
|
||||||
default this entry contains an empty string.
|
default this entry contains an empty string.
|
||||||
* `layout_input_always` determines whether the input line should be rendered
|
* `layout_input_always` determines whether the input line should be rendered
|
||||||
even if no generators are specified (`0` or `1`, default `0`).
|
even if no generators are specified (`0` or `1`, default `0`).
|
||||||
* `layout_empty_line` prints an empty line before the prompt's top line. This
|
* `layout_empty_line` determines how the prompt handles printing an empty line
|
||||||
prevents display problems when some command outputs a line without `\n`.
|
before the prompt's top line.
|
||||||
|
* When set to `0`, no extra line is drawn, and commands that do not end with
|
||||||
|
an EOL will cause the prompt's first line to be displayed incorrectly.
|
||||||
|
* When set to `1`, the prompt's top line will always be preceeded with an
|
||||||
|
empty line.
|
||||||
|
* When set to `2`, the prompt will be preceeded by an empty line unless it
|
||||||
|
is being drawn on the terminal's first line.
|
||||||
|
* When set to `3`, a newline will be added to the prompt if the last
|
||||||
|
command's output didn't end with a newline.
|
||||||
|
|
||||||
The `term_*` variables control the prompt's ability to change the terminal's
|
The `term_*` variables control the prompt's ability to change the terminal's
|
||||||
title and/or icon title:
|
title and/or icon title:
|
||||||
|
|
|
@ -33,8 +33,9 @@
|
||||||
] ,
|
] ,
|
||||||
# - Always generate input line?
|
# - Always generate input line?
|
||||||
layout_input_always => 0 ,
|
layout_input_always => 0 ,
|
||||||
# - Add an empty line before the prompt?
|
# - Add an empty line before the prompt? 0=no, 1=always, 2=not at the top
|
||||||
layout_empty_line => 0 ,
|
# of the terminal, 3=only if the previous command didn't finish with \n
|
||||||
|
layout_empty_line => 3 ,
|
||||||
|
|
||||||
# TERMINAL TITLE
|
# TERMINAL TITLE
|
||||||
# - Set title from the prompt? 0=no, 1=normal, 2=minimized, 3=both
|
# - Set title from the prompt? 0=no, 1=normal, 2=minimized, 3=both
|
||||||
|
|
101
gprompt.pl
101
gprompt.pl
|
@ -12,7 +12,7 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use utf8;
|
use utf8;
|
||||||
use open ':std', ':encoding(UTF-8)';
|
use open ':std', ':encoding(UTF-8)';
|
||||||
use POSIX qw(strftime);
|
use POSIX qw(strftime :termios_h);
|
||||||
use Cwd qw(abs_path getcwd);
|
use Cwd qw(abs_path getcwd);
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,8 +45,9 @@ our %CONFIG = (
|
||||||
layout_input => [ qw( userhost cwd ) ] ,
|
layout_input => [ qw( userhost cwd ) ] ,
|
||||||
# - Always generate input line?
|
# - Always generate input line?
|
||||||
layout_input_always => 0 ,
|
layout_input_always => 0 ,
|
||||||
# - Add an empty line before the prompt?
|
# - Add an empty line before the prompt? 0=no, 1=always, 2=not at the top
|
||||||
layout_empty_line => 0 ,
|
# of the terminal, 3=only if the previous command didn't finish with \n
|
||||||
|
layout_empty_line => 3 ,
|
||||||
|
|
||||||
# TERMINAL TITLE
|
# TERMINAL TITLE
|
||||||
# - Set title from the prompt? 0=no, 1=normal, 2=minimized, 3=both
|
# - Set title from the prompt? 0=no, 1=normal, 2=minimized, 3=both
|
||||||
|
@ -151,6 +152,13 @@ sub default_theme
|
||||||
'bg_ps2' => -2,
|
'bg_ps2' => -2,
|
||||||
ps2_suffix => ' : ' ,
|
ps2_suffix => ' : ' ,
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => '<NO EOL>' ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => 1 ,
|
||||||
|
'noeol_bg' => -1 ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
cwd_trunc => '...' ,
|
cwd_trunc => '...' ,
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
@ -302,6 +310,51 @@ sub set_color
|
||||||
return tput_sequence( "seta$type $index" );
|
return tput_sequence( "seta$type $index" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_cursor_pos
|
||||||
|
{
|
||||||
|
local $| = 1;
|
||||||
|
open(my $ttyIn, '<:bytes' , '/dev/tty');
|
||||||
|
open(my $ttyOut, '>:bytes' , '/dev/tty');
|
||||||
|
|
||||||
|
# Enable raw mode
|
||||||
|
my $term = POSIX::Termios->new;
|
||||||
|
my $ttyInFd = fileno $ttyIn;
|
||||||
|
$term->getattr($ttyInFd);
|
||||||
|
my $oTerm = $term ->getlflag;
|
||||||
|
$term->setlflag($oTerm & ~( ECHO | ECHOK | ICANON ));
|
||||||
|
$term->setcc(VTIME, 1);
|
||||||
|
$term->setattr($ttyInFd, TCSANOW);
|
||||||
|
|
||||||
|
# Read position
|
||||||
|
syswrite $ttyOut, "\033[6n", 4;
|
||||||
|
my ($input, $col, $line) = ("", "", "");
|
||||||
|
my $state = 0;
|
||||||
|
while (sysread $ttyIn, $input, 1) {
|
||||||
|
if ($state == 0) {
|
||||||
|
$state = 1 if $input eq '[';
|
||||||
|
} elsif ($state == 1) {
|
||||||
|
if ($input eq ';') {
|
||||||
|
$state = 2;
|
||||||
|
} else {
|
||||||
|
$line .= $input;
|
||||||
|
}
|
||||||
|
} elsif ($state == 2) {
|
||||||
|
last if $input eq 'R';
|
||||||
|
$col .= $input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable cooked mode
|
||||||
|
$term->setlflag($oTerm);
|
||||||
|
$term->setcc(VTIME, 0);
|
||||||
|
$term->setattr($ttyInFd, TCSANOW);
|
||||||
|
|
||||||
|
close $ttyIn;
|
||||||
|
close $ttyOut;
|
||||||
|
|
||||||
|
return $line, $col;
|
||||||
|
}
|
||||||
|
|
||||||
#}}}
|
#}}}
|
||||||
# Theming support -----------------------------------------------------------{{{
|
# Theming support -----------------------------------------------------------{{{
|
||||||
|
|
||||||
|
@ -593,6 +646,33 @@ sub render
|
||||||
#}}}
|
#}}}
|
||||||
# Prompt parts --------------------------------------------------------------{{{
|
# Prompt parts --------------------------------------------------------------{{{
|
||||||
|
|
||||||
|
sub gen_empty_line
|
||||||
|
{
|
||||||
|
my $lel = $CONFIG{layout_empty_line};
|
||||||
|
my $nl;
|
||||||
|
my $out = "";
|
||||||
|
if ($lel > 1) {
|
||||||
|
my ($line, $col) = get_cursor_pos;
|
||||||
|
$nl = ( $lel == 2 && $line != 1 ) || ( $lel == 3 && $col != 1 );
|
||||||
|
if ( $lel == 3 && $col != 1 ) {
|
||||||
|
$out .= render('input', {
|
||||||
|
content => [
|
||||||
|
{
|
||||||
|
style => themed 'noeol_style' ,
|
||||||
|
fg => themed 'noeol_fg' ,
|
||||||
|
bg => themed 'noeol_bg' ,
|
||||||
|
},
|
||||||
|
( themed 'noeol_text' )
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$nl = $lel
|
||||||
|
}
|
||||||
|
$out .= "\\n" if $nl;
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
sub gen_top_line
|
sub gen_top_line
|
||||||
{
|
{
|
||||||
my @left = @{ $CONFIG{layout_left} };
|
my @left = @{ $CONFIG{layout_left} };
|
||||||
|
@ -750,17 +830,24 @@ _gprompt_set_return() {
|
||||||
return "\${1:-0}"
|
return "\${1:-0}"
|
||||||
}
|
}
|
||||||
gprompt_command() {
|
gprompt_command() {
|
||||||
local cmd_status=\$?
|
_GPROMPT_PREV_STATUS=\$?
|
||||||
local jobs=(\$(jobs -p))
|
local jobs=(\$(jobs -p))
|
||||||
eval "\$_GPROMPT_PREVIOUS_PCMD"
|
eval "\$_GPROMPT_PREVIOUS_PCMD"
|
||||||
eval "\$( perl \Q$gpPath\E "rc:\$cmd_status" "jobs:\${#jobs[@]}" )"
|
eval "\$( perl \Q$gpPath\E "rc:\$_GPROMPT_PREV_STATUS" "jobs:\${#jobs[@]}" )"
|
||||||
_gprompt_set_return "\$cmd_status"
|
_gprompt_set_return "\$_GPROMPT_PREV_STATUS"
|
||||||
|
}
|
||||||
|
_gprompt_clear() {
|
||||||
|
clear -x
|
||||||
|
_gprompt_set_return "\${_GPROMPT_PREV_STATUS:-0}"
|
||||||
|
gprompt_command
|
||||||
|
echo -n "\${PS1\@P}\r"
|
||||||
}
|
}
|
||||||
shopt -s checkwinsize
|
shopt -s checkwinsize
|
||||||
if [[ \$PROMPT_COMMAND != *"gprompt_command"* ]]; then
|
if [[ \$PROMPT_COMMAND != *"gprompt_command"* ]]; then
|
||||||
_GPROMPT_PREVIOUS_PCMD="\$PROMPT_COMMAND"
|
_GPROMPT_PREVIOUS_PCMD="\$PROMPT_COMMAND"
|
||||||
PROMPT_COMMAND="gprompt_command"
|
PROMPT_COMMAND="gprompt_command"
|
||||||
fi
|
fi
|
||||||
|
bind -x \$'"\\C-l":_gprompt_clear'
|
||||||
EOF
|
EOF
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
@ -793,7 +880,7 @@ sub main
|
||||||
%TLEN = compute_trans_lengths;
|
%TLEN = compute_trans_lengths;
|
||||||
my $pg = gen_term_title;
|
my $pg = gen_term_title;
|
||||||
my $ps1 = $pg;
|
my $ps1 = $pg;
|
||||||
$ps1 .= "\\n" if $CONFIG{layout_empty_line};
|
$ps1 .= gen_empty_line;
|
||||||
$ps1 .= gen_top_line;
|
$ps1 .= gen_top_line;
|
||||||
my ( $ill , $ilt ) = gen_input_line;
|
my ( $ill , $ilt ) = gen_input_line;
|
||||||
$ps1 .= $ilt;
|
$ps1 .= $ilt;
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
'bg_ps2' => thref 'bg',
|
'bg_ps2' => thref 'bg',
|
||||||
ps2_suffix => '\b2\f3| ' ,
|
ps2_suffix => '\b2\f3| ' ,
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => '<NO EOL>' ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => thref 'fg3' ,
|
||||||
|
'noeol_bg' => thref 'bg3' ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
cwd_trunc => '...' ,
|
cwd_trunc => '...' ,
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
'bg_ps2' => thref 'bg',
|
'bg_ps2' => thref 'bg',
|
||||||
ps2_suffix => '\b2\f3| ' ,
|
ps2_suffix => '\b2\f3| ' ,
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => '<NO EOL>' ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => thref 'fg3' ,
|
||||||
|
'noeol_bg' => thref 'bg3' ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
cwd_trunc => '...' ,
|
cwd_trunc => '...' ,
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
'bg_ps2' => thref 'bg',
|
'bg_ps2' => thref 'bg',
|
||||||
'ps2_suffix' => "\\b2\\f3\x{250a} ",
|
'ps2_suffix' => "\\b2\\f3\x{250a} ",
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => "\x{b6}" ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => thref 'fg3' ,
|
||||||
|
'noeol_bg' => thref 'bg3' ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
'cwd_trunc' => "\x{2026}",
|
'cwd_trunc' => "\x{2026}",
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
'bg_ps2' => thref 'bg',
|
'bg_ps2' => thref 'bg',
|
||||||
'ps2_suffix' => "\\b2\\f3\x{250a} ",
|
'ps2_suffix' => "\\b2\\f3\x{250a} ",
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => "\x{b6}" ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => thref 'fg3' ,
|
||||||
|
'noeol_bg' => thref 'bg3' ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
'cwd_trunc' => "\x{2026}",
|
'cwd_trunc' => "\x{2026}",
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
|
|
@ -41,6 +41,13 @@
|
||||||
'bg_ps2' => 234,
|
'bg_ps2' => 234,
|
||||||
'ps2_suffix' => '\f0\b2'."\x{e0b0}".'\f2\b1'."\x{e0b0}".' ' ,
|
'ps2_suffix' => '\f0\b2'."\x{e0b0}".'\f2\b1'."\x{e0b0}".' ' ,
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => "\x{e0b0} \x{26a0} \x{e0b2}" ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => thref 'fg3' ,
|
||||||
|
'noeol_bg' => thref 'bg3' ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
'cwd_trunc' => "\x{2026}",
|
'cwd_trunc' => "\x{2026}",
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
|
|
@ -41,6 +41,13 @@
|
||||||
'bg_ps2' => 234,
|
'bg_ps2' => 234,
|
||||||
'ps2_suffix' => '\f0\b2'."\x{e0b0}".'\f2\b1'."\x{e0b0}".' ' ,
|
'ps2_suffix' => '\f0\b2'."\x{e0b0}".'\f2\b1'."\x{e0b0}".' ' ,
|
||||||
|
|
||||||
|
# Text appended to a line without EOL when layout_empty_line is 3
|
||||||
|
'noeol_text' => "\x{e0b0} \x{26a0} \x{e0b2}" ,
|
||||||
|
# Colors and style for the above text
|
||||||
|
'noeol_fg' => thref 'fg3' ,
|
||||||
|
'noeol_bg' => thref 'bg3' ,
|
||||||
|
'noeol_style' => 'b' ,
|
||||||
|
|
||||||
# Current working directory - Truncation string
|
# Current working directory - Truncation string
|
||||||
'cwd_trunc' => "\x{2026}",
|
'cwd_trunc' => "\x{2026}",
|
||||||
# Current working directory - Foreground / background colors
|
# Current working directory - Foreground / background colors
|
||||||
|
|
Loading…
Reference in a new issue