xC: quote text coming from a bracketed paste
Not having this has caused me much annoyance over the years.
This commit is contained in:
parent
92ac13f3c6
commit
5165f76b7c
42
xC.c
42
xC.c
@ -2445,6 +2445,10 @@ static struct config_schema g_config_behaviour[] =
|
|||||||
{ .name = "editor_command",
|
{ .name = "editor_command",
|
||||||
.comment = "VIM: \"vim +%Bgo %F\", Emacs: \"emacs -nw +%L:%C %F\"",
|
.comment = "VIM: \"vim +%Bgo %F\", Emacs: \"emacs -nw +%L:%C %F\"",
|
||||||
.type = CONFIG_ITEM_STRING },
|
.type = CONFIG_ITEM_STRING },
|
||||||
|
{ .name = "process_pasted_text",
|
||||||
|
.comment = "Normalize newlines and quote the command prefix in pastes",
|
||||||
|
.type = CONFIG_ITEM_BOOLEAN,
|
||||||
|
.default_ = "on" },
|
||||||
{ .name = "date_change_line",
|
{ .name = "date_change_line",
|
||||||
.comment = "Input to strftime(3) for the date change line",
|
.comment = "Input to strftime(3) for the date change line",
|
||||||
.type = CONFIG_ITEM_STRING,
|
.type = CONFIG_ITEM_STRING,
|
||||||
@ -12624,8 +12628,6 @@ process_input (struct app_context *ctx, char *user_input)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct strv lines = strv_make ();
|
struct strv lines = strv_make ();
|
||||||
|
|
||||||
// XXX: this interprets commands in pasted text
|
|
||||||
cstr_split (input, "\r\n", false, &lines);
|
cstr_split (input, "\r\n", false, &lines);
|
||||||
for (size_t i = 0; i < lines.len; i++)
|
for (size_t i = 0; i < lines.len; i++)
|
||||||
(void) process_input_utf8 (ctx,
|
(void) process_input_utf8 (ctx,
|
||||||
@ -14234,6 +14236,40 @@ done:
|
|||||||
|
|
||||||
#define BRACKETED_PASTE_LIMIT 102400 ///< How much text can be pasted
|
#define BRACKETED_PASTE_LIMIT 102400 ///< How much text can be pasted
|
||||||
|
|
||||||
|
static bool
|
||||||
|
insert_paste (struct app_context *ctx, char *paste, size_t len)
|
||||||
|
{
|
||||||
|
if (!get_config_boolean (ctx->config.root, "behaviour.process_pasted_text"))
|
||||||
|
return CALL_ (ctx->input, insert, paste);
|
||||||
|
|
||||||
|
// Without ICRNL, which Editline keeps but Readline doesn't,
|
||||||
|
// the terminal sends newlines as carriage returns (seen on urxvt)
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
if (paste[i] == '\r')
|
||||||
|
paste[i] = '\n';
|
||||||
|
|
||||||
|
int position = 0;
|
||||||
|
char *input = CALL_ (ctx->input, get_line, &position);
|
||||||
|
bool quote_first_slash = !position || strchr ("\r\n", input[position - 1]);
|
||||||
|
free (input);
|
||||||
|
|
||||||
|
// Executing commands by accident is much more common than pasting them
|
||||||
|
// intentionally, although the latter may also have security consequences
|
||||||
|
struct str processed = str_make ();
|
||||||
|
str_reserve (&processed, len);
|
||||||
|
for (size_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (paste[i] == '/'
|
||||||
|
&& ((!i && quote_first_slash) || (i && paste[i - 1] == '\n')))
|
||||||
|
str_append_c (&processed, paste[i]);
|
||||||
|
str_append_c (&processed, paste[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = CALL_ (ctx->input, insert, processed.str);
|
||||||
|
str_free (&processed);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_bracketed_paste (const struct pollfd *fd, struct app_context *ctx)
|
process_bracketed_paste (const struct pollfd *fd, struct app_context *ctx)
|
||||||
{
|
{
|
||||||
@ -14258,7 +14294,7 @@ process_bracketed_paste (const struct pollfd *fd, struct app_context *ctx)
|
|||||||
(int) (text_len = BRACKETED_PASTE_LIMIT));
|
(int) (text_len = BRACKETED_PASTE_LIMIT));
|
||||||
|
|
||||||
buf->str[text_len] = '\0';
|
buf->str[text_len] = '\0';
|
||||||
if (CALL_ (ctx->input, insert, buf->str))
|
if (insert_paste (ctx, buf->str, text_len))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
Loading…
Reference in New Issue
Block a user