Skip to content

Commit

Permalink
Merge branch 'add-N-macro'
Browse files Browse the repository at this point in the history
Add %N macro that prevents detaching viewers from current session.

Thanks to emorozov.
  • Loading branch information
xaizek committed Oct 7, 2021
2 parents 3d322db + 09b8ee5 commit fb2c924
Show file tree
Hide file tree
Showing 16 changed files with 82 additions and 19 deletions.
5 changes: 4 additions & 1 deletion ChangeLog
@@ -1,8 +1,11 @@
0.12 to current

Add 'autocd' option. Makes invalid :commands be interpreted as an
Added 'autocd' option. Makes invalid :commands be interpreted as an
implicit :cd command. Thanks to Taras Halturin (a.k.a. halturin).

Added %N macro that prevents detaching viewers from current session.
Thanks to emorozov.

0.12-beta to 0.12 (2021-09-29)

Made :VifmCs of the plugin handle 24-bit colors.
Expand Down
1 change: 1 addition & 0 deletions THANKS
Expand Up @@ -72,6 +72,7 @@ Egor Gumenyuk (boo1ean)
einhander
elricbk
emarsk
emorozov
Factorial Prime
Fang (peromage)
filterfalse
Expand Down
5 changes: 4 additions & 1 deletion data/man/vifm.1
@@ -1,4 +1,4 @@
.TH VIFM 1 "October 5, 2021" "vifm 0.12"
.TH VIFM 1 "October 7, 2021" "vifm 0.12"
.\" ---------------------------------------------------------------------------
.SH NAME
.\" ---------------------------------------------------------------------------
Expand Down Expand Up @@ -3355,6 +3355,9 @@ Same as %s, but splits vertically.
.BI %n
Forbid use of terminal multiplexer to run the command.
.TP
.BI %N
Do not detach viewer from terminal session (leaves `/dev/tty` available).
.TP
.BI %i
Completely ignore command output. For background jobs this suppresses error
dialogs, while still storing errors internally for viewing via :jobs menu.
Expand Down
5 changes: 4 additions & 1 deletion data/vim/doc/app/vifm-app.txt
@@ -1,4 +1,4 @@
*vifm-app.txt* For Vifm version 0.12 Last change: 2021 Oct 5
*vifm-app.txt* For Vifm version 0.12 Last change: 2021 Oct 7

Email for bugs and suggestions: <xaizek@posteo.net>

Expand Down Expand Up @@ -2769,6 +2769,9 @@ The command macros may be used in user commands.
%v same as %s, but splits vertically.
*vifm-%n*
%n forbid use of terminal multiplexer to run the command.
*vifm-%N*
%N do not detach viewer from terminal session (leaves `/dev/tty`
available).
*vifm-%i*
%i completely ignore command output. For background jobs this
suppresses error dialogs, while still storing errors
Expand Down
12 changes: 11 additions & 1 deletion src/background.c
Expand Up @@ -908,6 +908,8 @@ launch_external(const char cmd[], BgJobFlags flags, ShellRequester by)
const int merge_streams = (capture_output && (flags & BJF_MERGE_STREAMS));

#ifndef _WIN32
const int keep_session = (flags & BJF_KEEP_SESSION);

pid_t pid;
int input_pipe[2];
int output_pipe[2];
Expand Down Expand Up @@ -1019,9 +1021,17 @@ launch_external(const char cmd[], BgJobFlags flags, ShellRequester by)
}
}

if(keep_session)
{
if(setpgid(0, 0) == -1)
{
perror("setpgid");
_Exit(EXIT_FAILURE);
}
}
/* setsid() creates process group as well and doesn't work if current
* process is a group leader, so don't do setpgid(). */
if(setsid() == (pid_t)-1)
else if(setsid() == (pid_t)-1)
{
perror("setsid");
_Exit(EXIT_FAILURE);
Expand Down
1 change: 1 addition & 0 deletions src/background.h
Expand Up @@ -54,6 +54,7 @@ typedef enum
BJF_SUPPLY_INPUT = 1 << 2, /* Open a pipe for standard input stream. */
BJF_CAPTURE_OUT = 1 << 3, /* Capture output stream(s). */
BJF_MERGE_STREAMS = 1 << 4, /* Merge error stream into output stream. */
BJF_KEEP_SESSION = 1 << 5, /* Do not detach from terminal session. */
}
BgJobFlags;

Expand Down
5 changes: 5 additions & 0 deletions src/macros.c
Expand Up @@ -262,6 +262,9 @@ expand_macros_i(const char command[], const char args[], MacroFlags *flags,
case 'n': /* Forbid using of terminal multiplexer, even if active. */
ma_flags_set(flags, MF_NO_TERM_MUX);
break;
case 'N': /* Do not run command in a separate terminal session. */
ma_flags_set(flags, MF_KEEP_SESSION);
break;
case 'm': /* Use menu. */
ma_flags_set(flags, MF_MENU_OUTPUT);
break;
Expand Down Expand Up @@ -873,6 +876,8 @@ ma_flags_to_str(MacroFlags flags)
case MF_IGNORE: return "%i";
case MF_NO_TERM_MUX: return "%n";

case MF_KEEP_SESSION: return "%N";

case MF_PIPE_FILE_LIST: return "%Pl";
case MF_PIPE_FILE_LIST_Z: return "%Pz";
}
Expand Down
2 changes: 2 additions & 0 deletions src/macros.h
Expand Up @@ -50,6 +50,8 @@ typedef enum
MF_IGNORE, /* Completely ignore command output. */
MF_NO_TERM_MUX, /* Forbid using terminal multiplexer, even if active. */

MF_KEEP_SESSION, /* Don't detach command from terminal session. */

/* Second set of mutually exclusive flags. */
MF_SECOND_SET_ = 0x10,

Expand Down
9 changes: 6 additions & 3 deletions src/modes/view.c
Expand Up @@ -1133,9 +1133,12 @@ get_view_data(modview_info_t *vi, const char file_to_view[])
}
else
{
char *expanded = (viewer == NULL ? NULL : qv_expand_viewer(viewer));
lines = vcache_lookup(file_to_view, expanded, MF_NONE, kind, INT_MAX,
VC_SYNC, &error);
MacroFlags flags = MF_NONE;
char *expanded = (viewer == NULL)
? NULL
: qv_expand_viewer(curr_view, viewer, &flags);
lines = vcache_lookup(file_to_view, expanded, flags, kind, INT_MAX, VC_SYNC,
&error);
free(expanded);
}

Expand Down
1 change: 1 addition & 0 deletions src/tags.c
Expand Up @@ -12,6 +12,7 @@ const char *tags[] = {
"vifm-%IU",
"vifm-%Iu",
"vifm-%M",
"vifm-%N",
"vifm-%Pl",
"vifm-%Pz",
"vifm-%S",
Expand Down
21 changes: 12 additions & 9 deletions src/ui/quickview.c
Expand Up @@ -423,9 +423,12 @@ get_lines(const quickview_cache_t *cache)

const char *error;

char *expanded = (cache->viewer == NULL) ? NULL
: qv_expand_viewer(cache->viewer);
strlist_t lines = vcache_lookup(cache->path, expanded, MF_NONE, cache->kind,
MacroFlags flags = MF_NONE;
char *expanded = (cache->viewer == NULL)
? NULL
: qv_expand_viewer(cache->pa.source, cache->viewer, &flags);

strlist_t lines = vcache_lookup(cache->path, expanded, flags, cache->kind,
cache->max_lines, VC_ASYNC, &error);
free(expanded);

Expand Down Expand Up @@ -833,21 +836,21 @@ qv_hide(void)
}
}

/* Returns a pointer to newly allocated memory, which should be released by the
* caller. */
char *
qv_expand_viewer(const char viewer[])
qv_expand_viewer(view_t *view, const char viewer[], MacroFlags *flags)
{
ma_flags_set(flags, MF_NONE);

char *result;
if(strchr(viewer, '%') == NULL)
{
char *escaped = shell_like_escape(get_current_file_name(curr_view), 0);
char *escaped = shell_like_escape(get_current_file_name(view), 0);
result = format_str("%s %s", viewer, escaped);
free(escaped);
}
else
{
result = ma_expand(viewer, NULL, NULL, 1);
result = ma_expand(viewer, NULL, flags, 1);
}
return result;
}
Expand Down Expand Up @@ -882,7 +885,7 @@ qv_cleanup_area(const preview_area_t *parea, const char cmd[])
curr_stats.preview.clearing = 1;
curr_stats.preview_hint = parea;

char *expanded = qv_expand_viewer(cmd);
char *expanded = qv_expand_viewer(parea->view, cmd, NULL);
if(vlua_handler_cmd(curr_stats.vlua, expanded))
{
char path[PATH_MAX + 1];
Expand Down
6 changes: 5 additions & 1 deletion src/ui/quickview.h
Expand Up @@ -23,6 +23,7 @@
#include <stddef.h> /* size_t */
#include <stdio.h> /* FILE */

#include "../macros.h"
#include "colors.h"

struct dir_entry_t;
Expand Down Expand Up @@ -64,7 +65,10 @@ void qv_toggle(void);
/* Quits preview pane or view modes. */
void qv_hide(void);

char * qv_expand_viewer(const char viewer[]);
/* Expands viewer for the view. The flags parameter can be NULL. Returns a
* pointer to newly allocated memory, which should be released by the caller. */
char * qv_expand_viewer(struct view_t *view, const char viewer[],
MacroFlags *flags);

/* Performs view clearing with the given command, which can be NULL in which
* case only internal clearing is done. */
Expand Down
7 changes: 6 additions & 1 deletion src/vcache.c
Expand Up @@ -173,7 +173,7 @@ vcache_lookup(const char full_path[], const char viewer[], MacroFlags flags,
replace_string(&non_cache.path, full_path);
update_string(&non_cache.viewer, viewer);

non_cache.lines = view_entry(&non_cache, MF_NONE, error);
non_cache.lines = view_entry(&non_cache, flags, error);
wait_async_finish(&non_cache);

return non_cache.lines;
Expand Down Expand Up @@ -719,6 +719,11 @@ view_external(vcache_entry_t *centry, MacroFlags flags, const char **error)
bg_flags |= BJF_SUPPLY_INPUT;
}

if(ma_flags_present(flags, MF_KEEP_SESSION))
{
bg_flags |= BJF_KEEP_SESSION;
}

centry->job = bg_run_external_job(centry->viewer, bg_flags);
if(centry->job == NULL)
{
Expand Down
8 changes: 8 additions & 0 deletions tests/misc/expand_macros.c
Expand Up @@ -285,6 +285,11 @@ TEST(good_flag_macros)
assert_int_equal(MF_SPLIT_VERT, flags);
free(expanded);

expanded = ma_expand("%N echo log", "", &flags, 0);
assert_string_equal(" echo log", expanded);
assert_int_equal(MF_KEEP_SESSION, flags);
free(expanded);

expanded = ma_expand("%Pl echo log", "", &flags, 0);
assert_string_equal(" echo log", expanded);
assert_int_equal(MF_PIPE_FILE_LIST, flags);
Expand Down Expand Up @@ -715,9 +720,12 @@ TEST(flags_to_str)
assert_string_equal("%IU", ma_flags_to_str(MF_VERYCUSTOMVIEW_IOUTPUT));

assert_string_equal("%s", ma_flags_to_str(MF_SPLIT));
assert_string_equal("%v", ma_flags_to_str(MF_SPLIT_VERT));
assert_string_equal("%i", ma_flags_to_str(MF_IGNORE));
assert_string_equal("%n", ma_flags_to_str(MF_NO_TERM_MUX));

assert_string_equal("%N", ma_flags_to_str(MF_KEEP_SESSION));

assert_string_equal("%Pl", ma_flags_to_str(MF_PIPE_FILE_LIST));
assert_string_equal("%Pz", ma_flags_to_str(MF_PIPE_FILE_LIST_Z));
}
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/quickview.c
Expand Up @@ -109,7 +109,7 @@ TEST(preview_is_closed_on_request)
TEST(macros_are_expanded_for_viewer)
{
strcpy(curr_view->curr_dir, "echo");
char *expanded = qv_expand_viewer("%d 1");
char *expanded = qv_expand_viewer(curr_view, "%d 1", /*macros=*/NULL);
assert_string_equal("echo 1", expanded);
free(expanded);
}
Expand Down
11 changes: 11 additions & 0 deletions tests/misc/vcache.c
Expand Up @@ -149,6 +149,17 @@ TEST(can_use_custom_viewer)
assert_string_equal("text", lines.items[0]);
}

TEST(can_run_viewer_in_current_session)
{
/* Not sure how to test that session hasn't changed without writing a test
* program. */
strlist_t lines = vcache_lookup(TEST_DATA_PATH "/read/", "echo text",
MF_KEEP_SESSION, VK_TEXTUAL, 1, VC_SYNC, &error);
assert_string_equal(NULL, error);
assert_int_equal(1, lines.nitems);
assert_string_equal("text", lines.items[0]);
}

TEST(single_file_data_is_cached)
{
strlist_t lines1, lines2;
Expand Down

0 comments on commit fb2c924

Please sign in to comment.