xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
Commit c69fa76fa347b901f89ae223a921b315d3e5152c

Change 'extpromptpath' to 'extprompt'
The options's type was changed from boolean to set. This is to allow
future extensions in this area without introducing a family of trivial
options.
Author: xaizek
Author date (UTC): 2025-12-20 16:15
Committer name: xaizek
Committer date (UTC): 2025-12-20 16:37
Parent(s): ab4fabd1b26feaff54c6b96347d96cb108921b62
Signing key: 99DC5E4DB05F6BE2
Tree: e9c2dee6b9db78dfc13e1941fa28f5924a267bc0
File Lines added Lines deleted
ChangeLog 3 2
data/man/vifm.1 9 6
data/vim/doc/app/vifm-app.txt 10 7
data/vim/syntax/vifm.vim 7 7
src/cfg/config.c 1 1
src/cfg/config.h 11 3
src/cfg/info.c 2 1
src/fops_common.c 1 1
src/opt_handlers.c 15 7
src/tags.c 1 1
tests/misc/integration.c 46 0
tests/misc/options.c 20 0
tests/test-data/syntax-highlight/syntax.vifm 2 0
File ChangeLog changed (mode: 100644) (index 18051648b..64b7d42b0)
27 27 Added optional "next" and "prev" actions to :view command to switch Added optional "next" and "prev" actions to :view command to switch
28 28 default previewer for the current and similar files. default previewer for the current and similar files.
29 29
30 Added extpromptpath option to open path input boxes in external editor.
31 Patch by Kaspars Vandans.
30 Added 'extprompt' option to allow opening path input boxes in external
31 editor automatically when "path" value is included in the value. Patch by
32 Kaspars Vandans.
32 33
33 34 Updated utf8proc to v2.10.0. Updated utf8proc to v2.10.0.
34 35
File data/man/vifm.1 changed (mode: 100644) (index 7085e2a3e..6bcef844a)
1 .TH VIFM 1 "10 December 2025" "vifm 0.15"
1 .TH VIFM 1 "20 December 2025" "vifm 0.15"
2 2 .\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
3 3 .SH NAME .SH NAME
4 4 .\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
 
... ... default: false
4319 4319 .br .br
4320 4320 Whether dot files are shown in the view. Can be controlled with z* bindings. Whether dot files are shown in the view. Can be controlled with z* bindings.
4321 4321 .TP .TP
4322 .BI "'extpromptpath'"
4323 type: boolean
4322 .BI 'extprompt'
4323 type: set
4324 4324 .br .br
4325 default: false
4325 default:
4326 4326 .br .br
4327 When vifm prompts to amend paths or file names, use the external editor instead
4328 of the built-in line-prompt. This may happen, for example, during renaming.
4327 When vifm should use the external editor instead of the built-in line-prompt.
4328
4329 Possible values:
4330 \- path \- prompt to amend paths or file names (this may happen, for example,
4331 during renaming)
4329 4332 .TP .TP
4330 4333 .BI 'fastrun' .BI 'fastrun'
4331 4334 type: boolean type: boolean
File data/vim/doc/app/vifm-app.txt changed (mode: 100644) (index afbea1eb5..10ad21679)
1 *vifm-app.txt* For Vifm version 0.15 Last change: 2025 December 10
1 *vifm-app.txt* For Vifm version 0.15 Last change: 2025 December 20
2 2
3 3 Email for bugs and suggestions: <xaizek@posteo.net> Email for bugs and suggestions: <xaizek@posteo.net>
4 4
 
... ... default: false
3590 3590
3591 3591 Whether dot files are shown in the view. Can be controlled with z* bindings. Whether dot files are shown in the view. Can be controlled with z* bindings.
3592 3592
3593 *vifm-'extpromptpath'*
3594 extpromptpath
3595 type: boolean
3596 default: false
3593 *vifm-'extprompt'*
3594 extprompt
3595 type: set
3596 default:
3597
3598 When vifm should use the external editor instead of the built-in line-prompt.
3597 3599
3598 When vifm prompts to amend paths, use the external editor instead of the
3599 built-in line-prompt. This may happen, for example, during renaming.
3600 Possible values:
3601 - path - prompt to amend paths or file names (this may happen, for example,
3602 during renaming)
3600 3603
3601 3604 *vifm-'fastrun'* *vifm-'fastrun'*
3602 3605 fastrun fastrun
File data/vim/syntax/vifm.vim changed (mode: 100644) (index bebad2d8e..a1433b583)
1 1 " vifm syntax file " vifm syntax file
2 2 " Maintainer: xaizek <xaizek@posteo.net> " Maintainer: xaizek <xaizek@posteo.net>
3 " Last Change: December 10, 2025
3 " Last Change: December 20, 2025
4 4 " Inspired By: Vim syntax file by Dr. Charles E. Campbell, Jr. " Inspired By: Vim syntax file by Dr. Charles E. Campbell, Jr.
5 5
6 6 if exists('b:current_syntax') if exists('b:current_syntax')
 
... ... syntax match vifmHiGroups contained
160 160 " Options " Options
161 161 syntax keyword vifmOption contained aproposprg autocd autochpos caseoptions syntax keyword vifmOption contained aproposprg autocd autochpos caseoptions
162 162 \ cdpath cd chaselinks classify columns co confirm cf cpoptions cpo \ cdpath cd chaselinks classify columns co confirm cf cpoptions cpo
163 \ cvoptions deleteprg dotdirs dotfiles dirsize extpromptpath fastrun fillchars fcs findprg
164 \ followlinks fusehome gdefault grepprg histcursor history hi hloptions
165 \ hlsearch hls iec ignorecase ic iooptions incsearch is laststatus lines
166 \ locateprg ls lsoptions lsview mediaprg milleroptions millerview
163 \ cvoptions deleteprg dotdirs dotfiles dirsize extprompt fastrun fillchars
164 \ fcs findprg followlinks fusehome gdefault grepprg histcursor history hi
165 \ hloptions hlsearch hls iec ignorecase ic iooptions incsearch is laststatus
166 \ lines locateprg ls lsoptions lsview mediaprg milleroptions millerview
167 167 \ mintimeoutlen mouse navoptions number nu numberwidth nuw previewoptions \ mintimeoutlen mouse navoptions number nu numberwidth nuw previewoptions
168 168 \ previewprg quickview relativenumber rnu rulerformat ruf runexec scrollbind \ previewprg quickview relativenumber rnu rulerformat ruf runexec scrollbind
169 169 \ scb scrolloff sessionoptions ssop so sort sortgroups sortorder sortnumbers \ scb scrolloff sessionoptions ssop so sort sortgroups sortorder sortnumbers
 
... ... syntax keyword vifmOption contained aproposprg autocd autochpos caseoptions
176 176
177 177 " Disabled boolean options " Disabled boolean options
178 178 syntax keyword vifmOption contained noautocd noautochpos nocf nochaselinks syntax keyword vifmOption contained noautocd noautochpos nocf nochaselinks
179 \ nodotfiles noextpromptpath nofastrun nofollowlinks nohlsearch nohls noiec noignorecase
179 \ nodotfiles nofastrun nofollowlinks nohlsearch nohls noiec noignorecase
180 180 \ noic noincsearch nois nolaststatus nols nolsview nomillerview nonumber \ noic noincsearch nois nolaststatus nols nolsview nomillerview nonumber
181 181 \ nonu noquickview norelativenumber nornu noscrollbind noscb norunexec \ nonu noquickview norelativenumber nornu noscrollbind noscb norunexec
182 182 \ nosmartcase noscs nosortnumbers nosyscalls notitle notrash novimhelp \ nosmartcase noscs nosortnumbers nosyscalls notitle notrash novimhelp
 
... ... syntax keyword vifmOption contained noautocd noautochpos nocf nochaselinks
184 184
185 185 " Inverted boolean options " Inverted boolean options
186 186 syntax keyword vifmOption contained invautocd invautochpos invcf invchaselinks syntax keyword vifmOption contained invautocd invautochpos invcf invchaselinks
187 \ invdotfiles invextpromptpath invfastrun invfollowlinks invhlsearch invhls inviec
187 \ invdotfiles invfastrun invfollowlinks invhlsearch invhls inviec
188 188 \ invignorecase invic invincsearch invis invlaststatus invls invlsview \ invignorecase invic invincsearch invis invlaststatus invls invlsview
189 189 \ invmillerview invnumber invnu invquickview invrelativenumber invrnu \ invmillerview invnumber invnu invquickview invrelativenumber invrnu
190 190 \ invscrollbind invscb invrunexec invsmartcase invscs invsortnumbers \ invscrollbind invscb invrunexec invsmartcase invscs invsortnumbers
File src/cfg/config.c changed (mode: 100644) (index f36145561..5bf4e55a3)
... ... cfg_init(void)
258 258 cfg.auto_ch_pos = 1; cfg.auto_ch_pos = 1;
259 259 cfg.ch_pos_on = CHPOS_STARTUP | CHPOS_DIRMARK | CHPOS_ENTER; cfg.ch_pos_on = CHPOS_STARTUP | CHPOS_DIRMARK | CHPOS_ENTER;
260 260
261 cfg.ext_prompt_path = 0;
261 cfg.ext_prompt = EP_NONE;
262 262 } }
263 263
264 264 void void
File src/cfg/config.h changed (mode: 100644) (index 75628337e..5b4aa7961)
... ... typedef enum
171 171 } }
172 172 ColorWhat; ColorWhat;
173 173
174 /* Conditions to open external editor instead of builtin command-line. */
175 typedef enum
176 {
177 EP_NONE = 0, /* Never. */
178 EP_PATH = 1 << 0, /* On path/filename amendment prompts. */
179 NUM_EXT_PROMPT = 1 /* Number of options for compile checks. */
180 }
181 ExtPrompt;
182
174 183 /* File decoration description. */ /* File decoration description. */
175 184 typedef struct typedef struct
176 185 { {
 
... ... typedef struct config_t
399 408 int auto_ch_pos; /* Weird option that drops positions from histories. */ int auto_ch_pos; /* Weird option that drops positions from histories. */
400 409 int ch_pos_on; /* List of cases when historical cursor position is used. */ int ch_pos_on; /* List of cases when historical cursor position is used. */
401 410
402 /* Whether to open path/filename amendment prompts in external editor
403 * automatically. */
404 int ext_prompt_path;
411 /* When to open external editor instead of builtin command-line. */
412 int ext_prompt; /* Bit mask of EP_* (ExtPrompt enum). */
405 413 } }
406 414 config_t; config_t;
407 415
File src/cfg/info.c changed (mode: 100644) (index a8ae6578b..19c331505)
... ... store_global_options(JSON_Object *root)
2254 2254 escape_spaces(vle_opts_get("cpoptions", OPT_GLOBAL)))); escape_spaces(vle_opts_get("cpoptions", OPT_GLOBAL))));
2255 2255 append_dstr(options, format_str("deleteprg=%s", append_dstr(options, format_str("deleteprg=%s",
2256 2256 escape_spaces(cfg.delete_prg))); escape_spaces(cfg.delete_prg)));
2257 append_dstr(options, format_str("extprompt=%s",
2258 escape_spaces(vle_opts_get("extprompt", OPT_GLOBAL))));
2257 2259 append_dstr(options, format_str("%sfastrun", cfg.fast_run ? "" : "no")); append_dstr(options, format_str("%sfastrun", cfg.fast_run ? "" : "no"));
2258 2260 append_dstr(options, format_str("fillchars+=vborder:%s,hborder:%s", append_dstr(options, format_str("fillchars+=vborder:%s,hborder:%s",
2259 2261 escape_spaces(cfg.vborder_filler), escape_spaces(cfg.vborder_filler),
 
... ... store_global_options(JSON_Object *root)
2372 2374 append_dstr(options, format_str("wordchars=%s", append_dstr(options, format_str("wordchars=%s",
2373 2375 escape_spaces(vle_opts_get("wordchars", OPT_GLOBAL)))); escape_spaces(vle_opts_get("wordchars", OPT_GLOBAL))));
2374 2376 append_dstr(options, format_str("%swrap", cfg.wrap_quick_view ? "" : "no")); append_dstr(options, format_str("%swrap", cfg.wrap_quick_view ? "" : "no"));
2375 append_dstr(options, format_str("%sextpromptpath", cfg.ext_prompt_path ? "" : "no"));
2376 2377 } }
2377 2378
2378 2379 /* Serializes view-specific options into JSON table. */ /* Serializes view-specific options into JSON table. */
File src/fops_common.c changed (mode: 100644) (index d10761eaa..f8ebba764)
... ... void
1439 1439 fops_prompt_path(const char prompt[], const char path[], fo_prompt_cb cb, fops_prompt_path(const char prompt[], const char path[], fo_prompt_cb cb,
1440 1440 void *cb_arg, fo_complete_cmd_func complete) void *cb_arg, fo_complete_cmd_func complete)
1441 1441 { {
1442 if(cfg.ext_prompt_path)
1442 if(cfg.ext_prompt & EP_PATH)
1443 1443 { {
1444 1444 fops_extedit_path(path, cb, cb_arg); fops_extedit_path(path, cb, cb_arg);
1445 1445 } }
File src/opt_handlers.c changed (mode: 100644) (index e29ce667f..4b666cad7)
... ... static void cvoptions_handler(OPT_OP op, optval_t val);
133 133 static void deleteprg_handler(OPT_OP op, optval_t val); static void deleteprg_handler(OPT_OP op, optval_t val);
134 134 static void dirsize_handler(OPT_OP op, optval_t val); static void dirsize_handler(OPT_OP op, optval_t val);
135 135 static void dotdirs_handler(OPT_OP op, optval_t val); static void dotdirs_handler(OPT_OP op, optval_t val);
136 static void extpromptpath_handler(OPT_OP op, optval_t val);
136 static void extprompt_handler(OPT_OP op, optval_t val);
137 137 static void fastrun_handler(OPT_OP op, optval_t val); static void fastrun_handler(OPT_OP op, optval_t val);
138 138 static void fillchars_handler(OPT_OP op, optval_t val); static void fillchars_handler(OPT_OP op, optval_t val);
139 139 static void load_fillchars(void); static void load_fillchars(void);
 
... ... static const char *dotdirs_vals[][2] = {
299 299 }; };
300 300 ARRAY_GUARD(dotdirs_vals, NUM_DOT_DIRS); ARRAY_GUARD(dotdirs_vals, NUM_DOT_DIRS);
301 301
302 /* Possible values of 'extprompt'. */
303 static const char *extprompt_vals[][2] = {
304 [BIT(EP_PATH)] = { "path", "on path/filename amendment prompts" },
305 };
306 ARRAY_GUARD(extprompt_vals, NUM_EXT_PROMPT);
307
302 308 /* Possible values of 'histcursor'. */ /* Possible values of 'histcursor'. */
303 309 static const char *histcursor_vals[][2] = { static const char *histcursor_vals[][2] = {
304 310 [BIT(CHPOS_STARTUP)] = { "startup", "initial view loading on startup" }, [BIT(CHPOS_STARTUP)] = { "startup", "initial view loading on startup" },
 
... ... options[] = {
651 657 OPT_SET, ARRAY_LEN(dotdirs_vals), dotdirs_vals, &dotdirs_handler, NULL, OPT_SET, ARRAY_LEN(dotdirs_vals), dotdirs_vals, &dotdirs_handler, NULL,
652 658 { .ref.set_items = &cfg.dot_dirs }, { .ref.set_items = &cfg.dot_dirs },
653 659 }, },
660 { "extprompt", "", "when to open external editor instead of command-line",
661 OPT_SET, ARRAY_LEN(extprompt_vals), extprompt_vals,
662 &extprompt_handler, NULL,
663 { .ref.set_items = &cfg.ext_prompt },
664 },
654 665 { "fastrun", "", "autocomplete unambiguous prefixes for :!", { "fastrun", "", "autocomplete unambiguous prefixes for :!",
655 666 OPT_BOOL, 0, NULL, &fastrun_handler, NULL, OPT_BOOL, 0, NULL, &fastrun_handler, NULL,
656 667 { .ref.bool_val = &cfg.fast_run }, { .ref.bool_val = &cfg.fast_run },
 
... ... options[] = {
927 938 OPT_BOOL, 0, NULL, &wrapscan_handler, NULL, OPT_BOOL, 0, NULL, &wrapscan_handler, NULL,
928 939 { .ref.bool_val = &cfg.wrap_scan }, { .ref.bool_val = &cfg.wrap_scan },
929 940 }, },
930 { "extpromptpath", "", "open path/file name input in external editor",
931 OPT_BOOL, 0, NULL, &extpromptpath_handler, NULL,
932 { .ref.bool_val = &cfg.ext_prompt_path },
933 },
934 941
935 942 /* Local options must be grouped here. */ /* Local options must be grouped here. */
936 943 { "dotfiles", "", "show dot files", { "dotfiles", "", "show dot files",
 
... ... dotdirs_handler(OPT_OP op, optval_t val)
2155 2162 update_screen(UT_FULL); update_screen(UT_FULL);
2156 2163 } }
2157 2164
2165 /* Assigns new value for 'extprompt' option. */
2158 2166 static void static void
2159 extpromptpath_handler(OPT_OP op, optval_t val)
2167 extprompt_handler(OPT_OP op, optval_t val)
2160 2168 { {
2161 cfg.ext_prompt_path = val.bool_val;
2169 cfg.ext_prompt = val.set_items;
2162 2170 } }
2163 2171
2164 2172 static void static void
File src/tags.c changed (mode: 100644) (index 90210c38d..eba344ade)
... ... const char *tags[] = {
59 59 "vifm-'dirsize'", "vifm-'dirsize'",
60 60 "vifm-'dotdirs'", "vifm-'dotdirs'",
61 61 "vifm-'dotfiles'", "vifm-'dotfiles'",
62 "vifm-'extpromptpath'",
62 "vifm-'extprompt'",
63 63 "vifm-'fastrun'", "vifm-'fastrun'",
64 64 "vifm-'fcs'", "vifm-'fcs'",
65 65 "vifm-'fillchars'", "vifm-'fillchars'",
File tests/misc/integration.c changed (mode: 100644) (index c261e566b..18840dc51)
22 22 #include "../../src/utils/str.h" #include "../../src/utils/str.h"
23 23 #include "../../src/event_loop.h" #include "../../src/event_loop.h"
24 24 #include "../../src/filelist.h" #include "../../src/filelist.h"
25 #include "../../src/fops_rename.h"
25 26 #include "../../src/status.h" #include "../../src/status.h"
26 27
27 28 SETUP() SETUP()
 
... ... TEST(externally_edited_local_filter_is_applied, IF(not_windows))
293 294 restore_cwd(saved_cwd); restore_cwd(saved_cwd);
294 295 } }
295 296
297 TEST(extprompt_rename, IF(not_windows))
298 {
299 undo_setup();
300
301 curr_view = &lwin;
302 view_setup(&lwin);
303 lwin.columns = columns_create();
304
305 cfg.ext_prompt = EP_PATH;
306 opt_handlers_setup();
307
308 create_file(SANDBOX_PATH "/old-name");
309
310 /* Capture state of the directory with "old-name" file. */
311 make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "", NULL);
312 load_dir_list(&lwin, 0);
313
314 update_string(&cfg.shell, "/bin/sh");
315 stats_update_shell_type(cfg.shell);
316
317 create_executable(SANDBOX_PATH "/script");
318 make_file(SANDBOX_PATH "/script",
319 "#!/bin/sh\n"
320 "echo new-name > $3");
321
322 char script_path[PATH_MAX + 1];
323 make_abs_path(script_path, sizeof(script_path), SANDBOX_PATH, "script", NULL);
324 update_string(&cfg.vi_command, script_path);
325
326 fops_rename_current(&lwin, /*name_only=*/0);
327
328 remove_file(SANDBOX_PATH "/script");
329 no_remove_file(SANDBOX_PATH "/old-name");
330 remove_file(SANDBOX_PATH "/new-name");
331
332 view_teardown(&lwin);
333
334 vle_keys_reset();
335 opt_handlers_teardown();
336 columns_teardown();
337 undo_teardown();
338
339 cfg.ext_prompt = EP_NONE;
340 }
341
296 342 TEST(title_support_is_detected_correctly) TEST(title_support_is_detected_correctly)
297 343 { {
298 344 static char *XTERM_LIKE[] = { static char *XTERM_LIKE[] = {
File tests/misc/options.c changed (mode: 100644) (index f557ffc06..784ed1ddd)
... ... TEST(uioptions)
731 731 assert_false(cfg.always_show_io_details); assert_false(cfg.always_show_io_details);
732 732 } }
733 733
734 TEST(extprompt)
735 {
736 assert_int_equal(EP_NONE, cfg.ext_prompt);
737
738 assert_success(cmds_dispatch("set extprompt=path", &lwin, CIT_COMMAND));
739 assert_int_equal(EP_PATH, cfg.ext_prompt);
740
741 assert_success(cmds_dispatch("set extprompt=", &lwin, CIT_COMMAND));
742 assert_int_equal(EP_NONE, cfg.ext_prompt);
743
744 assert_success(cmds_dispatch("set extprompt=path", &lwin, CIT_COMMAND));
745 assert_int_equal(EP_PATH, cfg.ext_prompt);
746
747 /* Unknown values of set options are discarded (intentionally?). */
748 ui_sb_msg("");
749 assert_success(cmds_dispatch("set extprompt=bad", &lwin, CIT_COMMAND));
750 assert_int_equal(EP_NONE, cfg.ext_prompt);
751 assert_string_equal("", ui_sb_last());
752 }
753
734 754 static void static void
735 755 print_func(const char buf[], int offset, AlignType align, print_func(const char buf[], int offset, AlignType align,
736 756 const char full_column[], const format_info_t *info) const char full_column[], const format_info_t *info)
File tests/test-data/syntax-highlight/syntax.vifm changed (mode: 100644) (index fd05c67bb..c4f8be768)
... ... hi WildBox
613 613 " "hloptions" should be highlighted as 'option' " "hloptions" should be highlighted as 'option'
614 614 " "wildinc" should be highlighted as 'option' " "wildinc" should be highlighted as 'option'
615 615 " "uioptions" should be highlighted as 'option' " "uioptions" should be highlighted as 'option'
616 " "extprompt" should be highlighted as 'option'
616 617 set dotfiles nodotfiles invdotfiles dotfiles! set dotfiles nodotfiles invdotfiles dotfiles!
617 618 set caseoptions set caseoptions
618 619 set sizefmt set sizefmt
 
... ... set tabline tal
639 640 set hloptions set hloptions
640 641 set wildinc set wildinc
641 642 set uioptions set uioptions
643 set extprompt
642 644
643 645 " "echo" and "call" should be highlighted as :command " "echo" and "call" should be highlighted as :command
644 646 " "chooseopt" should be highlighted as builtin function " "chooseopt" should be highlighted as builtin function
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master