config: add 'pipe-selected' key binding

This works just like pipe-visible and pipe-scrollback, but pipes the
user-selected text, if any, to the external tool.

Closes #51
This commit is contained in:
Daniel Eklöf 2020-07-31 17:02:53 +02:00
parent 33e25e7f93
commit 639a61abd8
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 43 additions and 13 deletions

View file

@ -22,6 +22,9 @@
(https://codeberg.org/dnkl/foot/issues/42). (https://codeberg.org/dnkl/foot/issues/42).
* Key bindings in _scollback search_ mode are now configurable. * Key bindings in _scollback search_ mode are now configurable.
* `--check-config` command line option. * `--check-config` command line option.
* **pipe-selected** key binding. Works like **pipe-visible** and
**pipe-scrollback**, but only pipes the currently selected text, if
any (https://codeberg.org/dnkl/foot/issues/51).
### Deprecated ### Deprecated

View file

@ -66,6 +66,7 @@ static const char *const binding_action_map[] = {
[BIND_ACTION_FULLSCREEN] = "fullscreen", [BIND_ACTION_FULLSCREEN] = "fullscreen",
[BIND_ACTION_PIPE_SCROLLBACK] = "pipe-scrollback", [BIND_ACTION_PIPE_SCROLLBACK] = "pipe-scrollback",
[BIND_ACTION_PIPE_VIEW] = "pipe-visible", [BIND_ACTION_PIPE_VIEW] = "pipe-visible",
[BIND_ACTION_PIPE_SELECTED] = "pipe-selected",
}; };
static_assert(ALEN(binding_action_map) == BIND_ACTION_COUNT, static_assert(ALEN(binding_action_map) == BIND_ACTION_COUNT,

View file

@ -251,11 +251,11 @@ e.g. *search-start=none*.
*fullscreen* *fullscreen*
Toggles the fullscreen state. Default: _not bound_. Toggles the fullscreen state. Default: _not bound_.
*pipe-visible*, *pipe-scrollback* *pipe-visible*, *pipe-scrollback*, *pipe-selected*
Pipes the currently visible text, or the entire scrollback, to an Pipes the currently visible text, the entire scrollback, or the
external tool. The syntax for this option is a bit special; the currently selected text to an external tool. The syntax for this
first part of the value is the command to execute enclosed in option is a bit special; the first part of the value is the
"[]", followed by the binding(s). command to execute enclosed in "[]", followed by the binding(s).
You can configure multiple pipes as long as the command strings You can configure multiple pipes as long as the command strings
are different and the key bindings are unique. are different and the key bindings are unique.

2
footrc
View file

@ -64,6 +64,8 @@
# fullscreen=none # fullscreen=none
# pipe-visible=[sh -c "xurls | bemenu | xargs -r firefox"] none # pipe-visible=[sh -c "xurls | bemenu | xargs -r firefox"] none
# pipe-scrollback=[sh -c "xurls | bemenu | xargs -r firefox"] none # pipe-scrollback=[sh -c "xurls | bemenu | xargs -r firefox"] none
# pipe-selected=[xargs -r firefox] none
[search-bindings] [search-bindings]
# cancel=Control+g Escape # cancel=Control+g Escape

27
input.c
View file

@ -145,7 +145,8 @@ execute_binding(struct seat *seat, struct terminal *term,
break; break;
case BIND_ACTION_PIPE_SCROLLBACK: case BIND_ACTION_PIPE_SCROLLBACK:
case BIND_ACTION_PIPE_VIEW: { case BIND_ACTION_PIPE_VIEW:
case BIND_ACTION_PIPE_SELECTED: {
if (pipe_argv == NULL) if (pipe_argv == NULL)
break; break;
@ -171,9 +172,27 @@ execute_binding(struct seat *seat, struct terminal *term,
goto pipe_err; goto pipe_err;
} }
bool success = action == BIND_ACTION_PIPE_SCROLLBACK bool success;
? term_scrollback_to_text(term, &text, &len) switch (action) {
: term_view_to_text(term, &text, &len); case BIND_ACTION_PIPE_SCROLLBACK:
success = term_scrollback_to_text(term, &text, &len);
break;
case BIND_ACTION_PIPE_VIEW:
success = term_view_to_text(term, &text, &len);
break;
case BIND_ACTION_PIPE_SELECTED:
text = selection_to_text(term);
success = text != NULL;
len = text != NULL ? strlen(text) : 0;
break;
default:
assert(false);
success = false;
break;
}
if (!success) if (!success)
goto pipe_err; goto pipe_err;

View file

@ -204,9 +204,12 @@ extract_one_const_wrapper(struct terminal *term,
return extract_one(term, row, cell, col, data); return extract_one(term, row, cell, col, data);
} }
static char * char *
extract_selection(const struct terminal *term) selection_to_text(const struct terminal *term)
{ {
if (term->selection.end.row == -1)
return NULL;
struct extraction_context *ctx = extract_begin(term->selection.kind); struct extraction_context *ctx = extract_begin(term->selection.kind);
if (ctx == NULL) if (ctx == NULL)
return NULL; return NULL;
@ -873,7 +876,7 @@ selection_to_clipboard(struct seat *seat, struct terminal *term, uint32_t serial
return; return;
/* Get selection as a string */ /* Get selection as a string */
char *text = extract_selection(term); char *text = selection_to_text(term);
if (!text_to_clipboard(seat, term, text, serial)) if (!text_to_clipboard(seat, term, text, serial))
free(text); free(text);
} }
@ -1074,7 +1077,7 @@ selection_to_primary(struct seat *seat, struct terminal *term, uint32_t serial)
return; return;
/* Get selection as a string */ /* Get selection as a string */
char *text = extract_selection(term); char *text = selection_to_text(term);
if (!text_to_primary(seat, term, text, serial)) if (!text_to_primary(seat, term, text, serial))
free(text); free(text);
} }

View file

@ -30,6 +30,7 @@ void selection_mark_word(
void selection_mark_row( void selection_mark_row(
struct seat *seat, struct terminal *term, int row, uint32_t serial); struct seat *seat, struct terminal *term, int row, uint32_t serial);
char *selection_to_text(const struct terminal *term);
void selection_to_clipboard( void selection_to_clipboard(
struct seat *seat, struct terminal *term, uint32_t serial); struct seat *seat, struct terminal *term, uint32_t serial);
void selection_from_clipboard( void selection_from_clipboard(

View file

@ -41,6 +41,7 @@ enum bind_action_normal {
BIND_ACTION_FULLSCREEN, BIND_ACTION_FULLSCREEN,
BIND_ACTION_PIPE_SCROLLBACK, BIND_ACTION_PIPE_SCROLLBACK,
BIND_ACTION_PIPE_VIEW, BIND_ACTION_PIPE_VIEW,
BIND_ACTION_PIPE_SELECTED,
BIND_ACTION_COUNT, BIND_ACTION_COUNT,
}; };