xC: improve backlog helper capabilities

Snippets now receive positional parameters in the form of the buffer's
name in the locale encoding, and a filename if applicable
(we keep passing stdin along with the filename, which happens to
work out well for less(1)).

The default value of the configuration option also no longer uses
the "long prompt", which used to unhelpfully tell position in terms
of lines, but rather sets its own prompt that counts pages,
and makes sure to indicate the source buffer.

The main motivation behind this change is to make the 'v' command
work in less(1).  LESSSECURE must be omitted from the snippet
for this to work.

Bump liberty to receive a config parser that allows for less
convoluted escaping.
This commit is contained in:
Přemysl Eric Janouch 2022-08-14 13:22:07 +02:00
parent 2f7fbcdc5d
commit 49d9980662
Signed by: p
GPG Key ID: A0420B94F92B9493
3 changed files with 22 additions and 13 deletions

2
NEWS
View File

@ -1,5 +1,7 @@
Unreleased Unreleased
* xC: improved backlog helper integration capabilities
* xC: made it show WALLOPS messages, as PRIVMSG for the server buffer * xC: made it show WALLOPS messages, as PRIVMSG for the server buffer
* xD: implemented WALLOPS, choosing to make it target even non-operators * xD: implemented WALLOPS, choosing to make it target even non-operators

@ -1 +1 @@
Subproject commit 1b9d89cab3bb1df73c58ccd8528eafd21a8c6e40 Subproject commit f545be725df9195a5b5897ad95a0220acf10f148

31
xC.c
View File

@ -2480,9 +2480,11 @@ static struct config_schema g_config_behaviour[] =
.default_ = "1000", .default_ = "1000",
.on_change = on_config_backlog_limit_change }, .on_change = on_config_backlog_limit_change },
{ .name = "backlog_helper", { .name = "backlog_helper",
.comment = "Shell command to display a buffer's history", .comment = "Shell command to page buffer history (args: name [path])",
.type = CONFIG_ITEM_STRING, .type = CONFIG_ITEM_STRING,
.default_ = "\"LESSSECURE=1 less -M -R +Gb\"" }, .default_ = "`name=$(echo \"$1\" | sed 's/[%?:.]/\\\\&/g'); "
"prompt='?f%F:'$name'. ?db- page %db?L of %D. .(?eEND:?PB%PB\\%..)'; "
"LESSSECURE=1 less +Gb -Ps\"$prompt\" \"${2:--R}\"`" },
{ .name = "backlog_helper_strip_formatting", { .name = "backlog_helper_strip_formatting",
.comment = "Strip formatting from backlog helper input", .comment = "Strip formatting from backlog helper input",
.type = CONFIG_ITEM_BOOLEAN, .type = CONFIG_ITEM_BOOLEAN,
@ -13366,15 +13368,19 @@ input_editor_cleanup (struct app_context *ctx)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void static void
launch_backlog_helper (struct app_context *ctx, int backlog_fd) launch_backlog_helper (struct app_context *ctx, int backlog_fd,
const char *name, const char *path)
{ {
hard_assert (!ctx->running_backlog_helper); hard_assert (!ctx->running_backlog_helper);
switch (spawn_helper_child (ctx)) switch (spawn_helper_child (ctx))
{ {
case 0: case 0:
dup2 (backlog_fd, STDIN_FILENO); dup2 (backlog_fd, STDIN_FILENO);
execl ("/bin/sh", "/bin/sh", "-c", get_config_string char *localized_name =
(ctx->config.root, "behaviour.backlog_helper"), NULL); iconv_xstrdup (ctx->term_from_utf8, (char *) name, -1, NULL);
execl ("/bin/sh", "/bin/sh", "-c",
get_config_string (ctx->config.root, "behaviour.backlog_helper"),
PROGRAM_NAME, localized_name, path, NULL);
print_error ("%s: %s", print_error ("%s: %s",
"Failed to launch backlog helper", strerror (errno)); "Failed to launch backlog helper", strerror (errno));
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
@ -13419,7 +13425,7 @@ display_backlog (struct app_context *ctx, int flush_opts)
rewind (backlog); rewind (backlog);
set_cloexec (fileno (backlog)); set_cloexec (fileno (backlog));
launch_backlog_helper (ctx, fileno (backlog)); launch_backlog_helper (ctx, fileno (backlog), buffer->name, NULL);
fclose (backlog); fclose (backlog);
return true; return true;
} }
@ -13447,24 +13453,25 @@ on_display_full_log (int count, int key, void *user_data)
(void) key; (void) key;
struct app_context *ctx = user_data; struct app_context *ctx = user_data;
char *path = buffer_get_log_path (ctx->current_buffer); struct buffer *buffer = ctx->current_buffer;
char *path = buffer_get_log_path (buffer);
FILE *full_log = fopen (path, "rb"); FILE *full_log = fopen (path, "rb");
free (path);
if (!full_log) if (!full_log)
{ {
log_global_error (ctx, "Failed to open log file for #s: #l", log_global_error (ctx, "Failed to open log file for #s: #l",
ctx->current_buffer->name, strerror (errno)); ctx->current_buffer->name, strerror (errno));
free (path);
return false; return false;
} }
if (ctx->current_buffer->log_file) if (buffer->log_file)
// The regular flush will log any error eventually // The regular flush will log any error eventually
(void) fflush (ctx->current_buffer->log_file); (void) fflush (buffer->log_file);
set_cloexec (fileno (full_log)); set_cloexec (fileno (full_log));
launch_backlog_helper (ctx, fileno (full_log)); launch_backlog_helper (ctx, fileno (full_log), buffer->name, path);
fclose (full_log); fclose (full_log);
free (path);
return true; return true;
} }