Get the first command output on screen and the last scrolled one
This commit is contained in:
@@ -93,8 +93,13 @@ instead. If you want line wrap markers as well, use ``screen-ansi``
|
|||||||
or just ``screen``. For the scrollback buffer as well, use
|
or just ``screen``. For the scrollback buffer as well, use
|
||||||
``history``, ``ansi-history`` or ``screen-history``. To get
|
``history``, ``ansi-history`` or ``screen-history``. To get
|
||||||
the currently selected text, use ``selection``. To get the output
|
the currently selected text, use ``selection``. To get the output
|
||||||
|
of the first command run in the shell on screen, use ``first-output``
|
||||||
|
or ``first-output-ansi`` or ``first-output-screen-ansi``. To get the output
|
||||||
of the last command run in the shell, use ``output`` or ``output-ansi``
|
of the last command run in the shell, use ``output`` or ``output-ansi``
|
||||||
or ``output-screen-ansi``. Note that using ``output`` requires
|
or ``output-screen-ansi``. To get the first command output below the last
|
||||||
|
scrolled position via scroll_to_prompt, use ``last-visited-output`` or
|
||||||
|
``last-visited-output-ansi`` or ``last-visited-output-screen-ansi``. Note that
|
||||||
|
using ``first-output`` or ``output`` or ``last-visited-output`` requires
|
||||||
:ref:`shell_integration`.
|
:ref:`shell_integration`.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -110,10 +110,18 @@ def data_for_at(w: Optional[Window], arg: str, add_wrap_markers: bool = False) -
|
|||||||
return as_text(as_ansi=True, alternate_screen=True)
|
return as_text(as_ansi=True, alternate_screen=True)
|
||||||
if arg == '@ansi_alternate_scrollback':
|
if arg == '@ansi_alternate_scrollback':
|
||||||
return as_text(as_ansi=True, alternate_screen=True, add_history=True)
|
return as_text(as_ansi=True, alternate_screen=True, add_history=True)
|
||||||
|
if arg == '@first_cmd_output_on_screen':
|
||||||
|
return w.first_cmd_output_on_screen(add_wrap_markers=add_wrap_markers)
|
||||||
|
if arg == '@ansi_first_cmd_output_on_screen':
|
||||||
|
return w.first_cmd_output_on_screen(as_ansi=True, add_wrap_markers=add_wrap_markers)
|
||||||
if arg == '@last_cmd_output':
|
if arg == '@last_cmd_output':
|
||||||
return w.last_cmd_output(add_wrap_markers=add_wrap_markers)
|
return w.last_cmd_output(add_wrap_markers=add_wrap_markers)
|
||||||
if arg == '@ansi_last_cmd_output':
|
if arg == '@ansi_last_cmd_output':
|
||||||
return w.last_cmd_output(as_ansi=True, add_wrap_markers=add_wrap_markers)
|
return w.last_cmd_output(as_ansi=True, add_wrap_markers=add_wrap_markers)
|
||||||
|
if arg == '@last_visited_cmd_output':
|
||||||
|
return w.last_visited_cmd_output(add_wrap_markers=add_wrap_markers)
|
||||||
|
if arg == '@ansi_last_visited_cmd_output':
|
||||||
|
return w.last_visited_cmd_output(as_ansi=True, add_wrap_markers=add_wrap_markers)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -1314,9 +1322,15 @@ class Boss:
|
|||||||
data = sel.encode('utf-8') if sel else None
|
data = sel.encode('utf-8') if sel else None
|
||||||
elif type_of_input is None:
|
elif type_of_input is None:
|
||||||
data = None
|
data = None
|
||||||
|
elif type_of_input in ('first-output', 'first-output-screen', 'first-output-screen-ansi', 'first-output-ansi'):
|
||||||
|
q = type_of_input.split('-')
|
||||||
|
data = w.first_cmd_output_on_screen(as_ansi='ansi' in q, add_wrap_markers='screen' in q).encode('utf-8')
|
||||||
elif type_of_input in ('output', 'output-screen', 'output-screen-ansi', 'output-ansi'):
|
elif type_of_input in ('output', 'output-screen', 'output-screen-ansi', 'output-ansi'):
|
||||||
q = type_of_input.split('-')
|
q = type_of_input.split('-')
|
||||||
data = w.last_cmd_output(as_ansi='ansi' in q, add_wrap_markers='screen' in q).encode('utf-8')
|
data = w.last_cmd_output(as_ansi='ansi' in q, add_wrap_markers='screen' in q).encode('utf-8')
|
||||||
|
elif type_of_input in ('last-visited-output', 'last-visited-output-screen', 'last-visited-output-screen-ansi', 'last-visited-output-ansi'):
|
||||||
|
q = type_of_input.split('-')
|
||||||
|
data = w.last_visited_cmd_output(as_ansi='ansi' in q, add_wrap_markers='screen' in q).encode('utf-8')
|
||||||
else:
|
else:
|
||||||
raise ValueError(f'Unknown type_of_input: {type_of_input}')
|
raise ValueError(f'Unknown type_of_input: {type_of_input}')
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1120,7 +1120,9 @@ class Screen:
|
|||||||
pass
|
pass
|
||||||
as_text_non_visual = as_text
|
as_text_non_visual = as_text
|
||||||
as_text_alternate = as_text
|
as_text_alternate = as_text
|
||||||
|
first_cmd_output_on_screen = as_text
|
||||||
last_cmd_output = as_text
|
last_cmd_output = as_text
|
||||||
|
last_visited_cmd_output = as_text
|
||||||
|
|
||||||
def scroll_until_cursor(self) -> None:
|
def scroll_until_cursor(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -123,15 +123,17 @@ computers (for example, over ssh) or as other users.
|
|||||||
--stdin-source
|
--stdin-source
|
||||||
type=choices
|
type=choices
|
||||||
default=none
|
default=none
|
||||||
choices=none,@selection,@screen,@screen_scrollback,@alternate,@alternate_scrollback,@last_cmd_output
|
choices=none,@selection,@screen,@screen_scrollback,@alternate,@alternate_scrollback,@first_cmd_output_on_screen,@last_cmd_output,@last_visited_cmd_output
|
||||||
Pass the screen contents as :code:`STDIN` to the child process. :code:`@selection` is
|
Pass the screen contents as :code:`STDIN` to the child process. :code:`@selection` is
|
||||||
the currently selected text. :code:`@screen` is the contents of the currently active
|
the currently selected text. :code:`@screen` is the contents of the currently active
|
||||||
window. :code:`@screen_scrollback` is the same as :code:`@screen`, but includes the
|
window. :code:`@screen_scrollback` is the same as :code:`@screen`, but includes the
|
||||||
scrollback buffer as well. :code:`@alternate` is the secondary screen of the current
|
scrollback buffer as well. :code:`@alternate` is the secondary screen of the current
|
||||||
active window. For example if you run a full screen terminal application, the
|
active window. For example if you run a full screen terminal application, the
|
||||||
secondary screen will be the screen you return to when quitting the
|
secondary screen will be the screen you return to when quitting the application.
|
||||||
application. :code:`@last_cmd_output` is the output from the last command run in the shell,
|
:code:`@first_cmd_output_on_screen` is the output from the first command run in the shell on screen,
|
||||||
this needs :ref:`shell_integration` to work.
|
:code:`@last_cmd_output` is the output from the last command run in the shell,
|
||||||
|
:code:`@last_visited_cmd_output` is the first output below the last scrolled position via
|
||||||
|
scroll_to_prompt, this three needs :ref:`shell_integration` to work.
|
||||||
|
|
||||||
|
|
||||||
--stdin-add-formatting
|
--stdin-add-formatting
|
||||||
@@ -322,7 +324,8 @@ def launch(
|
|||||||
if opts.stdin_source != 'none':
|
if opts.stdin_source != 'none':
|
||||||
q = str(opts.stdin_source)
|
q = str(opts.stdin_source)
|
||||||
if opts.stdin_add_formatting:
|
if opts.stdin_add_formatting:
|
||||||
if q in ('@screen', '@screen_scrollback', '@alternate', '@alternate_scrollback'):
|
if q in ('@screen', '@screen_scrollback', '@alternate', '@alternate_scrollback',
|
||||||
|
'@first_cmd_output_on_screen', '@last_cmd_output', '@last_visited_cmd_output'):
|
||||||
q = '@ansi_' + q[1:]
|
q = '@ansi_' + q[1:]
|
||||||
if opts.stdin_add_line_wrap_markers:
|
if opts.stdin_add_line_wrap_markers:
|
||||||
q += '_wrap'
|
q += '_wrap'
|
||||||
|
|||||||
@@ -3032,6 +3032,10 @@ of the last command run in the shell using the :doc:`launch` function.
|
|||||||
For example, the following opens the output in less in an overlay window::
|
For example, the following opens the output in less in an overlay window::
|
||||||
|
|
||||||
map f1 launch --stdin-source=@last_cmd_output --stdin-add-formatting --type=overlay less +G -R
|
map f1 launch --stdin-source=@last_cmd_output --stdin-add-formatting --type=overlay less +G -R
|
||||||
|
|
||||||
|
To get the first command output on the screen, use :code:`@first_cmd_output_on_screen`.
|
||||||
|
To get the first command output below the last scrolled position via scroll_to_prompt, use
|
||||||
|
:code:`@last_visited_cmd_output`.
|
||||||
''')
|
''')
|
||||||
egr() # }}}
|
egr() # }}}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ class GetText(RemoteCommand):
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
match: The tab to focus
|
match: The tab to focus
|
||||||
extent: One of :code:`screen`, :code:`last_cmd_output`, :code:`all`, or :code:`selection`
|
extent: One of :code:`screen`, :code:`first_cmd_output_on_screen`, :code:`last_cmd_output`, \
|
||||||
|
:code:`last_visited_cmd_output`, :code:`all`, or :code:`selection`
|
||||||
ansi: Boolean, if True send ANSI formatting codes
|
ansi: Boolean, if True send ANSI formatting codes
|
||||||
cursor: Boolean, if True send cursor position/style as ANSI codes
|
cursor: Boolean, if True send cursor position/style as ANSI codes
|
||||||
wrap_markers: Boolean, if True add wrap markers to output
|
wrap_markers: Boolean, if True add wrap markers to output
|
||||||
@@ -28,11 +29,14 @@ class GetText(RemoteCommand):
|
|||||||
options_spec = MATCH_WINDOW_OPTION + '''\n
|
options_spec = MATCH_WINDOW_OPTION + '''\n
|
||||||
--extent
|
--extent
|
||||||
default=screen
|
default=screen
|
||||||
choices=screen, all, selection, last_cmd_output
|
choices=screen, all, selection, first_cmd_output_on_screen, last_cmd_output, last_visited_cmd_output
|
||||||
What text to get. The default of :code:`screen` means all text currently on the screen.
|
What text to get. The default of :code:`screen` means all text currently on the screen.
|
||||||
:code:`all` means all the screen+scrollback and :code:`selection` means the
|
:code:`all` means all the screen+scrollback and :code:`selection` means the
|
||||||
currently selected text. Finally, :code:`last_cmd_output` means the output of the last
|
currently selected text. :code:`first_cmd_output_on_screen` means the output of the first
|
||||||
command that was run in the window, which requires :ref:`shell_integration` to be enabled.
|
command that was run in the window on screen. :code:`last_cmd_output` means
|
||||||
|
the output of the last command that was run in the window. :code:`last_visited_cmd_output` means
|
||||||
|
the first command output below the last scrolled position via scroll_to_prompt. The last three
|
||||||
|
requires :ref:`shell_integration` to be enabled.
|
||||||
|
|
||||||
|
|
||||||
--ansi
|
--ansi
|
||||||
@@ -73,11 +77,21 @@ If specified get text from the window this command is run in, rather than the ac
|
|||||||
window = self.windows_for_match_payload(boss, window, payload_get)[0]
|
window = self.windows_for_match_payload(boss, window, payload_get)[0]
|
||||||
if payload_get('extent') == 'selection':
|
if payload_get('extent') == 'selection':
|
||||||
ans = window.text_for_selection()
|
ans = window.text_for_selection()
|
||||||
|
elif payload_get('extent') == 'first_cmd_output_on_screen':
|
||||||
|
ans = window.first_cmd_output_on_screen(
|
||||||
|
as_ansi=bool(payload_get('ansi')),
|
||||||
|
add_wrap_markers=bool(payload_get('wrap_markers')),
|
||||||
|
)
|
||||||
elif payload_get('extent') == 'last_cmd_output':
|
elif payload_get('extent') == 'last_cmd_output':
|
||||||
ans = window.last_cmd_output(
|
ans = window.last_cmd_output(
|
||||||
as_ansi=bool(payload_get('ansi')),
|
as_ansi=bool(payload_get('ansi')),
|
||||||
add_wrap_markers=bool(payload_get('wrap_markers')),
|
add_wrap_markers=bool(payload_get('wrap_markers')),
|
||||||
)
|
)
|
||||||
|
elif payload_get('extent') == 'last_visited_cmd_output':
|
||||||
|
ans = window.last_visited_cmd_output(
|
||||||
|
as_ansi=bool(payload_get('ansi')),
|
||||||
|
add_wrap_markers=bool(payload_get('wrap_markers')),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
ans = window.as_text(
|
ans = window.as_text(
|
||||||
as_ansi=bool(payload_get('ansi')),
|
as_ansi=bool(payload_get('ansi')),
|
||||||
|
|||||||
136
kitty/screen.c
136
kitty/screen.c
@@ -2646,6 +2646,7 @@ as_text_alternate(Screen *self, PyObject *args) {
|
|||||||
typedef struct OutputOffset {
|
typedef struct OutputOffset {
|
||||||
Screen *screen;
|
Screen *screen;
|
||||||
int start;
|
int start;
|
||||||
|
unsigned num_lines;
|
||||||
} OutputOffset;
|
} OutputOffset;
|
||||||
|
|
||||||
static Line*
|
static Line*
|
||||||
@@ -2654,37 +2655,122 @@ get_line_from_offset(void *x, int y) {
|
|||||||
return range_line_(r->screen, r->start + y);
|
return range_line_(r->screen, r->start + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
find_cmd_output(Screen *self, OutputOffset *oo, index_type start_y, unsigned int scrolled_by, int direction, bool on_screen_only) {
|
||||||
|
bool found_prompt = false, found_output = false, found_next_prompt = false;
|
||||||
|
int start = 0, end = 0;
|
||||||
|
int y1 = start_y - scrolled_by, y2 = y1;
|
||||||
|
const int upward_limit = -self->historybuf->count;
|
||||||
|
const int downward_limit = self->lines - 1;
|
||||||
|
const int screen_limit = -scrolled_by + downward_limit;
|
||||||
|
|
||||||
|
// find around
|
||||||
|
if (direction == 0) {
|
||||||
|
Line *line = range_line_(self, y1);
|
||||||
|
if (line->attrs.prompt_kind == PROMPT_START) {
|
||||||
|
found_prompt = true;
|
||||||
|
// change direction to downwards to find command output
|
||||||
|
direction = 1;
|
||||||
|
} else if (line->attrs.prompt_kind == OUTPUT_START) {
|
||||||
|
found_output = true; start = y1;
|
||||||
|
found_prompt = true;
|
||||||
|
// keep finding the first output start upwards
|
||||||
|
}
|
||||||
|
y1--; y2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find upwards
|
||||||
|
if (direction <= 0) {
|
||||||
|
// find around: only needs to find the first output start
|
||||||
|
// find upwards: find prompt after the output, and the first output
|
||||||
|
while (y1 >= upward_limit) {
|
||||||
|
Line *line = range_line_(self, y1);
|
||||||
|
if (line->attrs.prompt_kind == PROMPT_START) {
|
||||||
|
if (direction == 0) {
|
||||||
|
// find around: stop at prompt start
|
||||||
|
start = y1 + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
found_next_prompt = true; end = y1;
|
||||||
|
} else if (line->attrs.prompt_kind == OUTPUT_START) {
|
||||||
|
start = y1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
y1--;
|
||||||
|
}
|
||||||
|
if (y1 < upward_limit) {
|
||||||
|
start = upward_limit;
|
||||||
|
} else {
|
||||||
|
// resizing screen can cause multiple consecutive output start lines,
|
||||||
|
// so find the first one
|
||||||
|
while (start > upward_limit) {
|
||||||
|
Line *line = range_line_(self, start - 1);
|
||||||
|
if (line->attrs.prompt_kind != OUTPUT_START) break;
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found_output = true;
|
||||||
|
found_prompt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find downwards
|
||||||
|
if (direction >= 0) {
|
||||||
|
while (y2 <= downward_limit) {
|
||||||
|
if (on_screen_only && !found_output && y2 > screen_limit) break;
|
||||||
|
Line *line = range_line_(self, y2);
|
||||||
|
if (line->attrs.prompt_kind == PROMPT_START) {
|
||||||
|
if (!found_prompt) found_prompt = true;
|
||||||
|
else if (found_output && !found_next_prompt) {
|
||||||
|
found_next_prompt = true; end = y2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (line->attrs.prompt_kind == OUTPUT_START && found_prompt && !found_output) {
|
||||||
|
found_output = true; start = y2;
|
||||||
|
}
|
||||||
|
y2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_next_prompt) {
|
||||||
|
oo->num_lines = end - start;
|
||||||
|
} else if (found_output) {
|
||||||
|
oo->num_lines = (direction < 0 ? start_y : downward_limit) - start;
|
||||||
|
} else return false;
|
||||||
|
oo->start = start;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
first_cmd_output_on_screen(Screen *self, PyObject *args) {
|
||||||
|
if (self->linebuf != self->main_linebuf) return PyUnicode_FromString("");
|
||||||
|
|
||||||
|
OutputOffset oo = {.screen=self};
|
||||||
|
if (find_cmd_output(self, &oo, 0, self->scrolled_by, 1, true)) {
|
||||||
|
return as_text_generic(args, &oo, get_line_from_offset, oo.num_lines, &self->as_ansi_buf);
|
||||||
|
}
|
||||||
|
return PyUnicode_FromString("");
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
last_cmd_output(Screen *self, PyObject *args) {
|
last_cmd_output(Screen *self, PyObject *args) {
|
||||||
if (self->linebuf != self->main_linebuf) return PyUnicode_FromString("");
|
if (self->linebuf != self->main_linebuf) return PyUnicode_FromString("");
|
||||||
|
|
||||||
OutputOffset oo = {.screen=self};
|
OutputOffset oo = {.screen=self};
|
||||||
unsigned num_lines = 0;
|
if (find_cmd_output(self, &oo, self->cursor->y, self->scrolled_by, -1, false)) {
|
||||||
int prompt_pos = self->cursor->y, y = self->cursor->y;
|
return as_text_generic(args, &oo, get_line_from_offset, oo.num_lines, &self->as_ansi_buf);
|
||||||
const int limit = -self->historybuf->count;
|
|
||||||
while (y >= limit) {
|
|
||||||
Line *line = range_line_(self, y);
|
|
||||||
if (line->attrs.prompt_kind == PROMPT_START) prompt_pos = y;
|
|
||||||
if (line->attrs.prompt_kind == OUTPUT_START) {
|
|
||||||
oo.start = y;
|
|
||||||
num_lines = prompt_pos - y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
y--;
|
|
||||||
}
|
}
|
||||||
if (y < limit) {
|
return PyUnicode_FromString("");
|
||||||
oo.start = limit;
|
}
|
||||||
num_lines = prompt_pos - limit;
|
|
||||||
} else {
|
static PyObject*
|
||||||
// resizing screen can cause multiple consecutive output start lines,
|
last_visited_cmd_output(Screen *self, PyObject *args) {
|
||||||
// so find the first one
|
if (self->linebuf != self->main_linebuf || self->last_visited_prompt_scrolled_by > self->historybuf->count) return PyUnicode_FromString("");
|
||||||
while (oo.start > limit) {
|
|
||||||
Line *line = range_line_(self, oo.start - 1);
|
OutputOffset oo = {.screen=self};
|
||||||
if (line->attrs.prompt_kind != OUTPUT_START) break;
|
if (find_cmd_output(self, &oo, 0, self->last_visited_prompt_scrolled_by, 0, false)) {
|
||||||
oo.start--; num_lines++;
|
return as_text_generic(args, &oo, get_line_from_offset, oo.num_lines, &self->as_ansi_buf);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return as_text_generic(args, &oo, get_line_from_offset, num_lines, &self->as_ansi_buf);
|
return PyUnicode_FromString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3677,7 +3763,9 @@ static PyMethodDef methods[] = {
|
|||||||
MND(as_text, METH_VARARGS)
|
MND(as_text, METH_VARARGS)
|
||||||
MND(as_text_non_visual, METH_VARARGS)
|
MND(as_text_non_visual, METH_VARARGS)
|
||||||
MND(as_text_alternate, METH_VARARGS)
|
MND(as_text_alternate, METH_VARARGS)
|
||||||
|
MND(first_cmd_output_on_screen, METH_VARARGS)
|
||||||
MND(last_cmd_output, METH_VARARGS)
|
MND(last_cmd_output, METH_VARARGS)
|
||||||
|
MND(last_visited_cmd_output, METH_VARARGS)
|
||||||
MND(tab, METH_NOARGS)
|
MND(tab, METH_NOARGS)
|
||||||
MND(backspace, METH_NOARGS)
|
MND(backspace, METH_NOARGS)
|
||||||
MND(linefeed, METH_NOARGS)
|
MND(linefeed, METH_NOARGS)
|
||||||
|
|||||||
@@ -1041,11 +1041,21 @@ class Window:
|
|||||||
) -> str:
|
) -> str:
|
||||||
return as_text(self.screen, as_ansi, add_history, add_wrap_markers, alternate_screen, add_cursor)
|
return as_text(self.screen, as_ansi, add_history, add_wrap_markers, alternate_screen, add_cursor)
|
||||||
|
|
||||||
|
def first_cmd_output_on_screen(self, as_ansi: bool = False, add_wrap_markers: bool = False) -> str:
|
||||||
|
lines: List[str] = []
|
||||||
|
self.screen.first_cmd_output_on_screen(lines.append, as_ansi, add_wrap_markers)
|
||||||
|
return ''.join(lines)
|
||||||
|
|
||||||
def last_cmd_output(self, as_ansi: bool = False, add_wrap_markers: bool = False) -> str:
|
def last_cmd_output(self, as_ansi: bool = False, add_wrap_markers: bool = False) -> str:
|
||||||
lines: List[str] = []
|
lines: List[str] = []
|
||||||
self.screen.last_cmd_output(lines.append, as_ansi, add_wrap_markers)
|
self.screen.last_cmd_output(lines.append, as_ansi, add_wrap_markers)
|
||||||
return ''.join(lines)
|
return ''.join(lines)
|
||||||
|
|
||||||
|
def last_visited_cmd_output(self, as_ansi: bool = False, add_wrap_markers: bool = False) -> str:
|
||||||
|
lines: List[str] = []
|
||||||
|
self.screen.last_visited_cmd_output(lines.append, as_ansi, add_wrap_markers)
|
||||||
|
return ''.join(lines)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cwd_of_child(self) -> Optional[str]:
|
def cwd_of_child(self) -> Optional[str]:
|
||||||
return self.child.foreground_cwd or self.child.current_cwd
|
return self.child.foreground_cwd or self.child.current_cwd
|
||||||
@@ -1075,6 +1085,16 @@ class Window:
|
|||||||
cursor_on_screen = self.screen.scrolled_by < self.screen.lines - self.screen.cursor.y
|
cursor_on_screen = self.screen.scrolled_by < self.screen.lines - self.screen.cursor.y
|
||||||
get_boss().display_scrollback(self, data['text'], data['input_line_number'], report_cursor=cursor_on_screen)
|
get_boss().display_scrollback(self, data['text'], data['input_line_number'], report_cursor=cursor_on_screen)
|
||||||
|
|
||||||
|
@ac('cp', '''
|
||||||
|
Show output from the first shell command on screen in a pager like less
|
||||||
|
|
||||||
|
Requires :ref:`shell_integration` to work
|
||||||
|
''')
|
||||||
|
def show_first_command_output_on_screen(self) -> None:
|
||||||
|
text = self.first_cmd_output_on_screen(as_ansi=True, add_wrap_markers=True)
|
||||||
|
text = text.replace('\r\n', '\n').replace('\r', '\n')
|
||||||
|
get_boss().display_scrollback(self, text, title='First command output on screen', report_cursor=False)
|
||||||
|
|
||||||
@ac('cp', '''
|
@ac('cp', '''
|
||||||
Show output from the last shell command in a pager like less
|
Show output from the last shell command in a pager like less
|
||||||
|
|
||||||
@@ -1085,6 +1105,16 @@ class Window:
|
|||||||
text = text.replace('\r\n', '\n').replace('\r', '\n')
|
text = text.replace('\r\n', '\n').replace('\r', '\n')
|
||||||
get_boss().display_scrollback(self, text, title='Last command output', report_cursor=False)
|
get_boss().display_scrollback(self, text, title='Last command output', report_cursor=False)
|
||||||
|
|
||||||
|
@ac('cp', '''
|
||||||
|
Show the first output below the last scrolled position via scroll_to_prompt in a pager like less
|
||||||
|
|
||||||
|
Requires :ref:`shell_integration` to work
|
||||||
|
''')
|
||||||
|
def show_last_visited_command_output(self) -> None:
|
||||||
|
text = self.last_visited_cmd_output(as_ansi=True, add_wrap_markers=True)
|
||||||
|
text = text.replace('\r\n', '\n').replace('\r', '\n')
|
||||||
|
get_boss().display_scrollback(self, text, title='Last visited command output', report_cursor=False)
|
||||||
|
|
||||||
def paste_bytes(self, text: Union[str, bytes]) -> None:
|
def paste_bytes(self, text: Union[str, bytes]) -> None:
|
||||||
# paste raw bytes without any processing
|
# paste raw bytes without any processing
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
|
|||||||
@@ -957,6 +957,11 @@ class TestScreen(BaseTest):
|
|||||||
self.assertTrue(s.scroll_to_prompt())
|
self.assertTrue(s.scroll_to_prompt())
|
||||||
self.ae(str(s.visual_line(0)), '$ 1')
|
self.ae(str(s.visual_line(0)), '$ 1')
|
||||||
|
|
||||||
|
def fco():
|
||||||
|
a = []
|
||||||
|
s.first_cmd_output_on_screen(a.append)
|
||||||
|
return ''.join(a)
|
||||||
|
|
||||||
def lco():
|
def lco():
|
||||||
a = []
|
a = []
|
||||||
s.last_cmd_output(a.append)
|
s.last_cmd_output(a.append)
|
||||||
@@ -965,6 +970,7 @@ class TestScreen(BaseTest):
|
|||||||
s = self.create_screen()
|
s = self.create_screen()
|
||||||
s.draw('abcd'), s.index(), s.carriage_return()
|
s.draw('abcd'), s.index(), s.carriage_return()
|
||||||
s.draw('12'), s.index(), s.carriage_return()
|
s.draw('12'), s.index(), s.carriage_return()
|
||||||
|
self.ae(fco(), '')
|
||||||
self.ae(lco(), 'abcd\n12')
|
self.ae(lco(), 'abcd\n12')
|
||||||
s = self.create_screen()
|
s = self.create_screen()
|
||||||
mark_prompt(), s.draw('$ 0')
|
mark_prompt(), s.draw('$ 0')
|
||||||
@@ -973,4 +979,5 @@ class TestScreen(BaseTest):
|
|||||||
s.draw('abcd'), s.index(), s.carriage_return()
|
s.draw('abcd'), s.index(), s.carriage_return()
|
||||||
s.draw('12'), s.index(), s.carriage_return()
|
s.draw('12'), s.index(), s.carriage_return()
|
||||||
mark_prompt(), s.draw('$ 1')
|
mark_prompt(), s.draw('$ 1')
|
||||||
|
self.ae(fco(), 'abcd\n12')
|
||||||
self.ae(lco(), 'abcd\n12')
|
self.ae(lco(), 'abcd\n12')
|
||||||
|
|||||||
Reference in New Issue
Block a user