mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-19 06:57:57 +02:00
Compare commits
15 Commits
v0.47.4
...
copilot/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec2cc29de7 | ||
|
|
38dae45e07 | ||
|
|
9112d779d0 | ||
|
|
424d6f1ca4 | ||
|
|
0901fcbc21 | ||
|
|
6b2bb97cb5 | ||
|
|
285c576ddd | ||
|
|
e4e1ef0641 | ||
|
|
bdfcfc4fc2 | ||
|
|
1dc3730782 | ||
|
|
65e6a127ff | ||
|
|
3c648e42f6 | ||
|
|
9b218001a1 | ||
|
|
b43ca8fe31 | ||
|
|
98366076e1 |
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 10
|
||||
persist-credentials: false
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
CFLAGS: -funsigned-char
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 0 # needed for :commit: docs role
|
||||
persist-credentials: false
|
||||
@@ -145,7 +145,7 @@ jobs:
|
||||
KITTY_BUNDLE: 1
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 10
|
||||
persist-credentials: false
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 0 # needed for :commit: docs role
|
||||
persist-credentials: false
|
||||
@@ -204,7 +204,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 10
|
||||
persist-credentials: false
|
||||
|
||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4.36.0
|
||||
uses: github/codeql-action/init@v4.36.2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
trap-caching: false
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
run: python3 .github/workflows/ci.py build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4.36.0
|
||||
uses: github/codeql-action/analyze@v4.36.2
|
||||
|
||||
- name: Run govulncheck
|
||||
if: matrix.language == 'go'
|
||||
|
||||
4
.github/workflows/depscan.yml
vendored
4
.github/workflows/depscan.yml
vendored
@@ -22,13 +22,13 @@ jobs:
|
||||
KITTY_BUNDLE: 1
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 10
|
||||
persist-credentials: false
|
||||
|
||||
- name: Checkout bypy
|
||||
uses: actions/checkout@v6.0.2
|
||||
uses: actions/checkout@v6.0.3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
@@ -145,10 +145,10 @@
|
||||
},
|
||||
|
||||
{
|
||||
"name": "python 3.14.5",
|
||||
"name": "python 3.14.6",
|
||||
"unix": {
|
||||
"file_extension": "tar.xz",
|
||||
"hash": "sha256:7e32597b99e5d9a39abed35de4693fa169df3e5850d4c334337ffd6a19a36db6",
|
||||
"hash": "sha256:143b1dddefaec3bd2e21e3b839b34a2b7fb9842272883c576420d605e9f30c63",
|
||||
"urls": ["https://www.python.org/ftp/python/{version}/Python-{version}.{file_extension}"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -173,6 +173,11 @@ consumption to do the same tasks.
|
||||
Detailed list of changes
|
||||
-------------------------------------
|
||||
|
||||
0.50.0 [future]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- kitten @ get-text: Add support for :code:`alternate` and :code:`alternate_scrollback` extents to fetch text from the alternate screen buffer (:iss:`10165`)
|
||||
|
||||
0.47.4 [2026-06-15]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -96,7 +96,8 @@ polymorphic_string_as_utf8(id string) {
|
||||
characters = [string string];
|
||||
else
|
||||
characters = (NSString*) string;
|
||||
return [characters UTF8String];
|
||||
const char* ans = [characters UTF8String];
|
||||
return ans ? ans : "(nil)";
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -2023,6 +2024,10 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
|
||||
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
if (!string) {
|
||||
debug_input("\n\tinsertText: nil replacementRange: (%lu, %lu)\n", replacementRange.location, replacementRange.length);
|
||||
return;
|
||||
}
|
||||
const char *utf8 = polymorphic_string_as_utf8(string);
|
||||
debug_input("\n\tinsertText: %s replacementRange: (%lu, %lu)\n", utf8, replacementRange.location, replacementRange.length);
|
||||
if ([self hasMarkedText] && !is_ascii_control_char(utf8[0])) {
|
||||
|
||||
3
glfw/wl_init.c
vendored
3
glfw/wl_init.c
vendored
@@ -107,6 +107,9 @@ pointerHandleLeave(void* data UNUSED, struct wl_pointer* pointer UNUSED, uint32_
|
||||
// over the pointer for drag-and-drop). The matching button releases will
|
||||
// never be delivered to us.
|
||||
_glfw.wl.pointer_button_count = 0;
|
||||
// A DND grab taking over the pointer sends a leave, making this the
|
||||
// earliest proof that a just requested start_drag was accepted.
|
||||
_glfwWaylandConfirmDragSession();
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
if (!window) return;
|
||||
_glfw.wl.serial = serial;
|
||||
|
||||
15
glfw/wl_platform.h
vendored
15
glfw/wl_platform.h
vendored
@@ -434,6 +434,20 @@ typedef struct _GLFWlibraryWayland
|
||||
struct xdg_surface *toplevel_xdg_surface;
|
||||
struct xdg_toplevel *toplevel_xdg_toplevel;
|
||||
struct wl_buffer *toplevel_buffer;
|
||||
// wl_data_device.start_drag is silently ignored by compositors when
|
||||
// its serial does not match an active pointer implicit grab, which
|
||||
// can happen as drags are started asynchronously and the client side
|
||||
// view of the grab can be stale. A wl_display.sync issued right after
|
||||
// start_drag detects this: any compositor event proving the DND
|
||||
// session is live (wl_pointer.leave, wl_data_device.enter, any
|
||||
// wl_data_source event) is ordered before the sync callback, so if
|
||||
// the callback fires first the start_drag was dropped.
|
||||
struct wl_callback *start_confirmation;
|
||||
bool session_confirmed;
|
||||
// The drag toplevel was configured before the session was confirmed,
|
||||
// mapping it was deferred so it cannot end up as a stray regular
|
||||
// window if start_drag was silently ignored.
|
||||
bool toplevel_map_deferred;
|
||||
struct {
|
||||
const char *mime_type;
|
||||
int fd;
|
||||
@@ -487,6 +501,7 @@ void animateCursorImage(id_type timer_id, void *data);
|
||||
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape, struct wl_cursor_theme*);
|
||||
void destroy_data_offer(_GLFWWaylandDataOffer*);
|
||||
const char* _glfwWaylandCompositorName(void);
|
||||
void _glfwWaylandConfirmDragSession(void);
|
||||
|
||||
typedef struct wayland_cursor_shape {
|
||||
int which; const char *name;
|
||||
|
||||
78
glfw/wl_window.c
vendored
78
glfw/wl_window.c
vendored
@@ -2561,6 +2561,8 @@ update_drop_source_actions(_GLFWwindow *window, _GLFWWaylandDataOffer *offer) {
|
||||
static void
|
||||
drag_enter(void *data UNUSED, struct wl_data_device *wl_data_device UNUSED, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id) {
|
||||
debug_input("Drop entered\n");
|
||||
// an enter for a drag we started means the DND session is live
|
||||
_glfwWaylandConfirmDragSession();
|
||||
_GLFWWaylandDataOffer *offer = &_glfw.wl.drop_data_offer;
|
||||
mark_data_offer(offer, id);
|
||||
if (!offer->id) return;
|
||||
@@ -3164,9 +3166,7 @@ GLFWAPI bool glfwWaylandBeep(GLFWwindow *handle) {
|
||||
// Drag source {{{
|
||||
|
||||
static void
|
||||
drag_toplevel_xdg_surface_configure(void *data UNUSED, struct xdg_surface *surface, uint32_t serial) {
|
||||
debug_input("Drag toplevel surface configured\n");
|
||||
xdg_surface_ack_configure(surface, serial);
|
||||
map_drag_toplevel(void) {
|
||||
struct wl_buffer *buf = _glfw.wl.drag.toplevel_buffer;
|
||||
if (buf) {
|
||||
wl_surface_attach(_glfw.wl.drag.drag_icon, buf, 0, 0);
|
||||
@@ -3178,6 +3178,23 @@ drag_toplevel_xdg_surface_configure(void *data UNUSED, struct xdg_surface *surfa
|
||||
if (buf) wl_buffer_destroy(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_toplevel_xdg_surface_configure(void *data UNUSED, struct xdg_surface *surface, uint32_t serial) {
|
||||
debug_input("Drag toplevel surface configured\n");
|
||||
xdg_surface_ack_configure(surface, serial);
|
||||
if (_glfw.wl.drag.start_confirmation && !_glfw.wl.drag.session_confirmed) {
|
||||
// The compositor has not yet proven that it accepted start_drag. If
|
||||
// it silently ignored it (stale implicit grab serial), committing a
|
||||
// buffer now would map the toplevel as a stray regular window that
|
||||
// nothing ever destroys. Defer mapping until the session is
|
||||
// confirmed; if it never is, the toplevel is destroyed unmapped.
|
||||
debug_input("Deferring drag toplevel map until drag session is confirmed\n");
|
||||
_glfw.wl.drag.toplevel_map_deferred = true;
|
||||
return;
|
||||
}
|
||||
map_drag_toplevel();
|
||||
}
|
||||
|
||||
static const struct xdg_surface_listener drag_toplevel_xdg_surface_listener = {
|
||||
.configure = drag_toplevel_xdg_surface_configure,
|
||||
};
|
||||
@@ -3213,6 +3230,46 @@ cancel_drag2(GLFWDragEventType type, bool maybe_a_cancel) {
|
||||
|
||||
static void cancel_drag(GLFWDragEventType type) { cancel_drag2(type, false); }
|
||||
|
||||
void
|
||||
_glfwWaylandConfirmDragSession(void) {
|
||||
// Called on receipt of any compositor event that can only happen when a
|
||||
// DND session is actually live: the start_drag was not silently dropped.
|
||||
if (!_glfw.wl.drag.source || _glfw.wl.drag.session_confirmed) return;
|
||||
_glfw.wl.drag.session_confirmed = true;
|
||||
debug_input("Drag session confirmed as started by compositor\n");
|
||||
if (_glfw.wl.drag.toplevel_map_deferred) {
|
||||
_glfw.wl.drag.toplevel_map_deferred = false;
|
||||
map_drag_toplevel();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_start_confirmation_handle_done(void *data UNUSED, struct wl_callback *callback, uint32_t cb_data UNUSED) {
|
||||
if (callback != _glfw.wl.drag.start_confirmation) {
|
||||
// stale callback from a drag that was already cleaned up
|
||||
wl_callback_destroy(callback);
|
||||
return;
|
||||
}
|
||||
_glfw.wl.drag.start_confirmation = NULL;
|
||||
wl_callback_destroy(callback);
|
||||
if (!_glfw.wl.drag.session_confirmed) {
|
||||
// The compositor processed start_drag before this sync callback, and
|
||||
// an accepted start_drag synchronously produces events (pointer
|
||||
// leave, data device enter, data source events) that are ordered
|
||||
// before it. None arrived, so the compositor silently ignored
|
||||
// start_drag (no active implicit grab matching the serial). Without
|
||||
// this, the data source would never receive any event, leaking the
|
||||
// drag state forever and orphaning the drag toplevel as a stray
|
||||
// window.
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: start_drag was silently ignored by the compositor, cancelling drag");
|
||||
cancel_drag(GLFW_DRAG_CANCELLED);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener drag_start_confirmation_listener = {
|
||||
.done = drag_start_confirmation_handle_done,
|
||||
};
|
||||
|
||||
#define dr _glfw.wl.drag.data_requests[i]
|
||||
|
||||
static void
|
||||
@@ -3387,6 +3444,7 @@ drag_source_send(void *data UNUSED, struct wl_data_source *source UNUSED, const
|
||||
static void
|
||||
drag_source_target(void *data UNUSED, struct wl_data_source *source UNUSED, const char *mime_type) {
|
||||
debug_input("Drag source accepted MIME type: %s\n", mime_type);
|
||||
_glfwWaylandConfirmDragSession();
|
||||
_GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id);
|
||||
if (window) {
|
||||
GLFWDragEvent ev = {.type=GLFW_DRAG_ACCEPTED, .mime_type=mime_type};
|
||||
@@ -3397,6 +3455,7 @@ drag_source_target(void *data UNUSED, struct wl_data_source *source UNUSED, cons
|
||||
static void
|
||||
drag_source_action(void *data UNUSED, struct wl_data_source *source UNUSED, uint32_t dnd_action) {
|
||||
debug_input("Drag source action changed: %d\n", dnd_action);
|
||||
_glfwWaylandConfirmDragSession();
|
||||
_GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id);
|
||||
if (window) {
|
||||
GLFWDragOperationType op = GLFW_DRAG_OPERATION_GENERIC;
|
||||
@@ -3414,6 +3473,7 @@ drag_source_action(void *data UNUSED, struct wl_data_source *source UNUSED, uint
|
||||
static void
|
||||
drag_source_dnd_drop_performed(void *data UNUSED, struct wl_data_source *source UNUSED) {
|
||||
debug_input("Drag source drop performed\n");
|
||||
_glfwWaylandConfirmDragSession();
|
||||
_GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id);
|
||||
if (window) {
|
||||
GLFWDragEvent ev = {.type=GLFW_DRAG_DROPPED};
|
||||
@@ -3465,6 +3525,7 @@ _glfwPlatformCancelDrag(_GLFWwindow* window UNUSED) {
|
||||
|
||||
void
|
||||
_glfwPlatformFreeDragSourceData(void) {
|
||||
if (_glfw.wl.drag.start_confirmation) wl_callback_destroy(_glfw.wl.drag.start_confirmation);
|
||||
if (_glfw.wl.drag.drag_viewport) wp_viewport_destroy(_glfw.wl.drag.drag_viewport);
|
||||
if (_glfw.wl.drag.toplevel_drag) xdg_toplevel_drag_v1_destroy(_glfw.wl.drag.toplevel_drag);
|
||||
if (_glfw.wl.drag.toplevel_buffer) wl_buffer_destroy(_glfw.wl.drag.toplevel_buffer);
|
||||
@@ -3594,6 +3655,17 @@ _glfwPlatformStartDrag(_GLFWwindow* window, const GLFWimage* thumbnail) {
|
||||
|
||||
if (icon_buffer) wl_buffer_destroy(icon_buffer);
|
||||
|
||||
// The pointer_button_count check above uses the client side view of the
|
||||
// implicit grab, which can be stale: the button may already be released
|
||||
// with the release event still in flight, in which case the compositor
|
||||
// silently ignores start_drag and the data source never receives any
|
||||
// event. Detect that with a sync: an accepted start_drag synchronously
|
||||
// produces events ordered before the sync callback.
|
||||
_glfw.wl.drag.session_confirmed = false;
|
||||
_glfw.wl.drag.start_confirmation = wl_display_sync(_glfw.wl.display);
|
||||
if (_glfw.wl.drag.start_confirmation)
|
||||
wl_callback_add_listener(_glfw.wl.drag.start_confirmation, &drag_start_confirmation_listener, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
// }}}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -27,7 +27,7 @@ require (
|
||||
github.com/zeebo/xxh3 v1.1.0
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
|
||||
golang.org/x/image v0.42.0
|
||||
golang.org/x/sys v0.45.0
|
||||
golang.org/x/sys v0.46.0
|
||||
golang.org/x/text v0.38.0
|
||||
howett.net/plist v1.0.1
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@@ -80,8 +80,8 @@ golang.org/x/image v0.42.0 h1:1gSs6ehNWXLbkHBIPcWztk3D/6aIA/8hauiAYtlodVY=
|
||||
golang.org/x/image v0.42.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
|
||||
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -732,7 +732,7 @@ end:
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t
|
||||
static size_t
|
||||
disk_cache_clear_from_ram(PyObject *self_, bool(matches)(void*, void *key, unsigned keysz), void *data) {
|
||||
DiskCache *self = (DiskCache*)self_;
|
||||
size_t ans = 0;
|
||||
|
||||
@@ -16,7 +16,6 @@ PyObject* read_from_disk_cache_python(PyObject *self_, const void *key, size_t k
|
||||
bool disk_cache_wait_for_write(PyObject *self, monotonic_t timeout);
|
||||
size_t disk_cache_total_size(PyObject *self);
|
||||
size_t disk_cache_size_on_disk(PyObject *self);
|
||||
size_t disk_cache_clear_from_ram(PyObject *self_, bool(matches)(void* data, void *key, unsigned keysz), void*);
|
||||
size_t disk_cache_num_cached_in_ram(PyObject *self_);
|
||||
|
||||
static inline void* disk_cache_malloc_allocator(void *x, size_t sz) {
|
||||
|
||||
@@ -14,9 +14,10 @@ class GetText(RemoteCommand):
|
||||
|
||||
protocol_spec = __doc__ = '''
|
||||
match/str: The window to get text from
|
||||
extent/choices.screen.first_cmd_output_on_screen.last_cmd_output.last_visited_cmd_output.all.selection: \
|
||||
extent/choices.screen.first_cmd_output_on_screen.last_cmd_output.last_visited_cmd_output.all.selection.alternate.alternate_scrollback: \
|
||||
One of :code:`screen`, :code:`first_cmd_output_on_screen`, :code:`last_cmd_output`, \
|
||||
:code:`last_visited_cmd_output`, :code:`all`, or :code:`selection`
|
||||
:code:`last_visited_cmd_output`, :code:`all`, :code:`selection`, :code:`alternate`, \
|
||||
or :code:`alternate_scrollback`
|
||||
ansi/bool: Boolean, if True send ANSI formatting codes
|
||||
cursor/bool: Boolean, if True send cursor position/style as ANSI codes
|
||||
wrap_markers/bool: Boolean, if True add wrap markers to output
|
||||
@@ -28,7 +29,7 @@ class GetText(RemoteCommand):
|
||||
options_spec = MATCH_WINDOW_OPTION + '''\n
|
||||
--extent
|
||||
default=screen
|
||||
choices=screen, all, selection, first_cmd_output_on_screen, last_cmd_output, last_visited_cmd_output, last_non_empty_output
|
||||
choices=screen, all, selection, first_cmd_output_on_screen, last_cmd_output, last_visited_cmd_output, last_non_empty_output, alternate, alternate_scrollback
|
||||
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
|
||||
currently selected text. :code:`first_cmd_output_on_screen` means the output of the first
|
||||
@@ -37,6 +38,9 @@ the output of the last command that was run in the window. :code:`last_visited_c
|
||||
the first command output below the last scrolled position via scroll_to_prompt.
|
||||
:code:`last_non_empty_output` is the output from the last command run in the window that had
|
||||
some non empty output. The last four require :ref:`shell_integration` to be enabled.
|
||||
:code:`alternate` means the text in the screen that is not currently visible (if the terminal
|
||||
is in the main screen this is the secondary/alternate screen and vice versa).
|
||||
:code:`alternate_scrollback` is the same but also includes the scrollback buffer (if any).
|
||||
|
||||
|
||||
--ansi
|
||||
@@ -112,6 +116,14 @@ Get text from the window this command is run in, rather than the active window.
|
||||
as_ansi=bool(payload_get('ansi')),
|
||||
add_wrap_markers=bool(payload_get('wrap_markers')),
|
||||
)
|
||||
elif payload_get('extent') in ('alternate', 'alternate_scrollback'):
|
||||
ans = window.as_text(
|
||||
as_ansi=bool(payload_get('ansi')),
|
||||
add_history=payload_get('extent') == 'alternate_scrollback',
|
||||
add_cursor=bool(payload_get('cursor')),
|
||||
add_wrap_markers=bool(payload_get('wrap_markers')),
|
||||
alternate_screen=True,
|
||||
)
|
||||
else:
|
||||
ans = window.as_text(
|
||||
as_ansi=bool(payload_get('ansi')),
|
||||
|
||||
Reference in New Issue
Block a user