config: add pipe-command-output key-binding

This commit is contained in:
Daniel Eklöf 2022-12-08 11:45:23 +01:00
parent e9607de5ae
commit 1c70a84fde
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 99 additions and 5 deletions

View file

@ -111,6 +111,7 @@ static const char *const binding_action_map[] = {
[BIND_ACTION_PIPE_SCROLLBACK] = "pipe-scrollback",
[BIND_ACTION_PIPE_VIEW] = "pipe-visible",
[BIND_ACTION_PIPE_SELECTED] = "pipe-selected",
[BIND_ACTION_PIPE_COMMAND_OUTPUT] = "pipe-command-output",
[BIND_ACTION_SHOW_URLS_COPY] = "show-urls-copy",
[BIND_ACTION_SHOW_URLS_LAUNCH] = "show-urls-launch",
[BIND_ACTION_SHOW_URLS_PERSISTENT] = "show-urls-persistent",

View file

@ -227,7 +227,8 @@ execute_binding(struct seat *seat, struct terminal *term,
break;
/* FALLTHROUGH */
case BIND_ACTION_PIPE_VIEW:
case BIND_ACTION_PIPE_SELECTED: {
case BIND_ACTION_PIPE_SELECTED:
case BIND_ACTION_PIPE_COMMAND_OUTPUT: {
if (binding->aux->type != BINDING_AUX_PIPE)
return true;
@ -269,6 +270,10 @@ execute_binding(struct seat *seat, struct terminal *term,
len = text != NULL ? strlen(text) : 0;
break;
case BIND_ACTION_PIPE_COMMAND_OUTPUT:
success = term_command_output_to_text(term, &text, &len);
break;
default:
BUG("Unhandled action type");
success = false;

View file

@ -32,6 +32,7 @@ enum bind_action_normal {
BIND_ACTION_PIPE_SCROLLBACK,
BIND_ACTION_PIPE_VIEW,
BIND_ACTION_PIPE_SELECTED,
BIND_ACTION_PIPE_COMMAND_OUTPUT,
BIND_ACTION_SHOW_URLS_COPY,
BIND_ACTION_SHOW_URLS_LAUNCH,
BIND_ACTION_SHOW_URLS_PERSISTENT,

View file

@ -3613,7 +3613,7 @@ term_surface_kind(const struct terminal *term, const struct wl_surface *surface)
static bool
rows_to_text(const struct terminal *term, int start, int end,
char **text, size_t *len)
int col_start, int col_end, char **text, size_t *len)
{
struct extraction_context *ctx = extract_begin(SELECTION_NONE, true);
if (ctx == NULL)
@ -3626,15 +3626,20 @@ rows_to_text(const struct terminal *term, int start, int end,
const struct row *row = term->grid->rows[r];
xassert(row != NULL);
for (int c = 0; c < term->cols; c++)
const int c_end = r == end ? col_end : term->cols;
for (int c = col_start; c < c_end; c++) {
if (!extract_one(term, row, &row->cells[c], c, ctx))
goto out;
}
if (r == end)
break;
r++;
r &= grid_rows - 1;
col_start = 0;
}
out:
@ -3666,7 +3671,7 @@ term_scrollback_to_text(const struct terminal *term, char **text, size_t *len)
end += term->grid->num_rows;
}
return rows_to_text(term, start, end, text, len);
return rows_to_text(term, start, end, 0, term->cols, text, len);
}
bool
@ -3674,7 +3679,87 @@ term_view_to_text(const struct terminal *term, char **text, size_t *len)
{
int start = grid_row_absolute_in_view(term->grid, 0);
int end = grid_row_absolute_in_view(term->grid, term->rows - 1);
return rows_to_text(term, start, end, text, len);
return rows_to_text(term, start, end, 0, term->cols, text, len);
}
bool
term_command_output_to_text(const struct terminal *term, char **text, size_t *len)
{
int start_row = -1;
int end_row = -1;
int start_col = -1;
int end_col = -1;
const struct grid *grid = term->grid;
const int sb_end = grid_row_absolute(grid, term->rows - 1);
int r = (sb_end - 1 + grid->num_rows) & (grid->num_rows - 1);
while (start_row < 0 && r != sb_end) {
const struct row *row = grid->rows[r];
if (row == NULL)
break;
if (row->shell_integration.cmd_end >= 0) {
end_row = r;
end_col = row->shell_integration.cmd_end;
}
if (end_row >= 0 && row->shell_integration.cmd_start >= 0) {
start_row = r;
start_col = row->shell_integration.cmd_start;
}
r = (r - 1 + grid->num_rows) & (grid->num_rows - 1);
}
if (start_row < 0)
return false;
bool ret = rows_to_text(term, start_row, end_row, start_col, end_col, text, len);
if (!ret)
return false;
/*
* If the FTCS_COMMAND_FINISHED marker was emitted at the *first*
* column, then the *entire* previous line is part of the command
* output. *Including* the newline, if any.
*
* Since rows_to_text() doesnt extract the column
* FTCS_COMMAND_FINISHED was emitted at (that would be wrong -
* FTCS_COMMAND_FINISHED is emitted *after* the command output,
* not at its last character), the extraction logic will not see
* the last newline (this is true for all non-line-wise selection
* types), and the extracted text will *not* end with a newline.
*
* Here we try to compensate for that. Note that if end_col is
* not 0, then the command output only covers a partial row, and
* thus we do *not* want to append a newline.
*/
if (end_col > 0) {
/* Command output covers partial row - dont append newline */
return true;
}
int next_to_last_row = (end_row - 1 + grid->num_rows) & (grid->num_rows - 1);
const struct row *row = grid->rows[next_to_last_row];
/* Add newline if last row has a hard linebreak */
if (row->linebreak) {
char *new_text = xrealloc(*text, *len + 1 + 1);
if (new_text == NULL) {
/* Ignore failure - use text as is (without inserting newline) */
return true;
}
*text = new_text;
(*len)++;
(*text)[*len - 1] = '\n';
(*text)[*len] = '\0';
}
return true;
}
bool

View file

@ -847,6 +847,8 @@ bool term_scrollback_to_text(
const struct terminal *term, char **text, size_t *len);
bool term_view_to_text(
const struct terminal *term, char **text, size_t *len);
bool term_command_output_to_text(
const struct terminal *term, char **text, size_t *len);
bool term_ime_is_enabled(const struct terminal *term);
void term_ime_enable(struct terminal *term);