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 9bd364e0a9ec2a22bf85d3a5413f4cc65cf5ff33

Add 'fileoptions' option to fine-tune :file menu
The only "hidemissing" value allows skiping missing programs.

Thanks to aksr.

Closes https://github.com/vifm/vifm/issues/1031.
Author: xaizek
Author date (UTC): 2026-10-01 12:36
Committer name: xaizek
Committer date (UTC): 2026-10-01 13:01
Parent(s): 75dd1539eaa0d8f175412aebd717150f5f5b16a8
Signing key: 99DC5E4DB05F6BE2
Tree: 7e58a2641710ae2b0732fafe987f419aafcfb221
File Lines added Lines deleted
ChangeLog 3 0
data/man/vifm.1 12 1
data/vim/doc/app/vifm-app.txt 11 1
data/vim/syntax/vifm.vim 14 14
src/cfg/config.c 2 0
src/cfg/config.h 3 0
src/cfg/info.c 3 0
src/cmd_handlers.c 1 1
src/menus/filetypes_menu.c 31 11
src/menus/filetypes_menu.h 1 1
src/modes/normal.c 2 1
src/opt_handlers.c 79 0
src/tags.c 1 0
tests/menus/filetypes.c 69 2
tests/misc/options.c 27 0
tests/test-data/syntax-highlight/syntax.vifm 2 0
File ChangeLog changed (mode: 100644) (index fc7346acb..824f71528)
70 70
71 71 Added -focus parameter to :split and :vsplit. Thanks to agguser. Added -focus parameter to :split and :vsplit. Thanks to agguser.
72 72
73 Added 'fileoptions' option to allow hiding missing programs in the :file
74 menu. Thanks to aksr.
75
73 76 Updated utf8proc to v2.11.3. Updated utf8proc to v2.11.3.
74 77
75 78 Made documentation on which :commands can have comments a bit more Made documentation on which :commands can have comments a bit more
File data/man/vifm.1 changed (mode: 100644) (index 6c83631eb..353235d87)
1 .TH VIFM 1 "28 September 2026" "vifm 0.15"
1 .TH VIFM 1 "1 October 2026" "vifm 0.15"
2 2 .\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
3 3 .SH NAME .SH NAME
4 4 .\" --------------------------------------------------------------------------- .\" ---------------------------------------------------------------------------
 
... ... default: false
4516 4516 .br .br
4517 4517 With this option turned on you can run partially entered commands with With this option turned on you can run partially entered commands with
4518 4518 unambiguous beginning using :! (e.g. :!Te instead of :!Terminal or :!Te<tab>). unambiguous beginning using :! (e.g. :!Te instead of :!Terminal or :!Te<tab>).
4519 .TP
4520 .BI 'fileoptions'
4521 type: string list
4522 .br
4523 default: ""
4524 .br
4525 Fine-tunes the behaviour of the :file menu.
4526
4527 item used for
4528 hidemissing omitting entries with handlers, that were found to not exist
4529
4519 4530 .TP .TP
4520 4531 .BI "'fillchars' 'fcs'" .BI "'fillchars' 'fcs'"
4521 4532 type: string list type: string list
File data/vim/doc/app/vifm-app.txt changed (mode: 100644) (index c91fb954a..1fb6c06fb)
1 *vifm-app.txt* For Vifm version 0.15 Last change: 2026 September 28
1 *vifm-app.txt* For Vifm version 0.15 Last change: 2026 October 1
2 2
3 3 Email for bugs and suggestions: <xaizek@posteo.net> Email for bugs and suggestions: <xaizek@posteo.net>
4 4
 
... ... default: false
3775 3775 With this option turned on you can run partially entered commands with With this option turned on you can run partially entered commands with
3776 3776 unambiguous beginning using :! (e.g. :!Te instead of :!Terminal or :!Te<tab>). unambiguous beginning using :! (e.g. :!Te instead of :!Terminal or :!Te<tab>).
3777 3777
3778 *vifm-'fileoptions'*
3779 fileoptions
3780 type: string list
3781 default: ""
3782
3783 Fine-tunes the behaviour of the |vifm-:file| menu.
3784
3785 item used for~
3786 hidemissing omitting entries with handlers, that were found to not exist
3787
3778 3788 *vifm-'fillchars'* *vifm-'fcs'* *vifm-'fillchars'* *vifm-'fcs'*
3779 3789 fillchars fcs fillchars fcs
3780 3790 type: string list type: string list
File data/vim/syntax/vifm.vim changed (mode: 100644) (index b2e0d3b33..8a2dbdbbd)
1 1 " vifm syntax file " vifm syntax file
2 2 " Maintainer: xaizek <xaizek@posteo.net> " Maintainer: xaizek <xaizek@posteo.net>
3 " Last Change: September 2, 2026
3 " Last Change: October 1, 2026
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 extprompt fastrun fillchars
164 \ fcs findprg followlinks fusehome gdefault grepprg histcursor history hi
165 \ hloptions hlsearch hls iec ignorecase ic iooptions incsearch is keepsel
166 \ laststatus lines locateprg ls lsoptions lsview mediaprg milleroptions
167 \ millerview mintimeoutlen mouse navoptions number nu numberwidth nuw
168 \ previewoptions previewprg quickview relativenumber rnu rulerformat ruf
169 \ runexec scrollbind scb scrolloff sessionoptions ssop so sort sortgroups
170 \ sortorder sortnumbers shell sh shellflagcmd shcf shortmess shm showtabline
171 \ stal sizefmt slowfs smartcase scs statusline stl suggestoptions syncregs
172 \ syscalls tablabel tabline tabprefix tabscope tabstop tabsuffix tal timefmt
173 \ timeoutlen title tm trash trashdir ts tuioptions to uioptions undolevels
174 \ ul vicmd viewcolumns vifminfo vimhelp vixcmd wildinc wildmenu wmnu
175 \ wildstyle wordchars wrap wrapscan ws
163 \ cvoptions deleteprg dotdirs dotfiles dirsize extprompt fastrun fileoptions
164 \ fillchars fcs findprg followlinks fusehome gdefault grepprg histcursor
165 \ history hi hloptions hlsearch hls iec ignorecase ic iooptions incsearch is
166 \ keepsel laststatus lines locateprg ls lsoptions lsview mediaprg
167 \ milleroptions millerview mintimeoutlen mouse navoptions number nu
168 \ numberwidth nuw previewoptions previewprg quickview relativenumber rnu
169 \ rulerformat ruf runexec scrollbind scb scrolloff sessionoptions ssop so
170 \ sort sortgroups sortorder sortnumbers shell sh shellflagcmd shcf shortmess
171 \ shm showtabline stal sizefmt slowfs smartcase scs statusline stl
172 \ suggestoptions syncregs syscalls tablabel tabline tabprefix tabscope
173 \ tabstop tabsuffix tal timefmt timeoutlen title tm trash trashdir ts
174 \ tuioptions to uioptions undolevels ul vicmd viewcolumns vifminfo vimhelp
175 \ vixcmd wildinc wildmenu wmnu wildstyle wordchars wrap wrapscan ws
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
File src/cfg/config.c changed (mode: 100644) (index 6fba58087..e09d2d076)
... ... cfg_init(void)
260 260 cfg.ch_pos_on = CHPOS_STARTUP | CHPOS_DIRMARK | CHPOS_ENTER; cfg.ch_pos_on = CHPOS_STARTUP | CHPOS_DIRMARK | CHPOS_ENTER;
261 261
262 262 cfg.ext_prompt = EP_NONE; cfg.ext_prompt = EP_NONE;
263
264 cfg.hide_missing_progs = 0;
263 265 } }
264 266
265 267 void void
File src/cfg/config.h changed (mode: 100644) (index b32157611..516c99b81)
... ... typedef struct config_t
413 413
414 414 /* When to open external editor instead of builtin command-line. */ /* When to open external editor instead of builtin command-line. */
415 415 int ext_prompt; /* Bit mask of EP_* (ExtPrompt enum). */ int ext_prompt; /* Bit mask of EP_* (ExtPrompt enum). */
416
417 /* Settings related to :file menu. */
418 int hide_missing_progs; /* Don't list programs deemed to not be present. */
416 419 } }
417 420 config_t; config_t;
418 421
File src/cfg/info.c changed (mode: 100644) (index 145f85d85..4a2fcff67)
... ... store_global_options(JSON_Object *root)
2377 2377 append_dstr(options, format_str("wordchars=%s", append_dstr(options, format_str("wordchars=%s",
2378 2378 escape_spaces(vle_opts_get("wordchars", OPT_GLOBAL)))); escape_spaces(vle_opts_get("wordchars", OPT_GLOBAL))));
2379 2379 append_dstr(options, format_str("%swrap", cfg.wrap_quick_view ? "" : "no")); append_dstr(options, format_str("%swrap", cfg.wrap_quick_view ? "" : "no"));
2380
2381 append_dstr(options, format_str("fileoptions=%s",
2382 escape_spaces(vle_opts_get("fileoptions", OPT_GLOBAL))));
2380 2383 } }
2381 2384
2382 2385 /* Serializes view-specific options into JSON table. */ /* Serializes view-specific options into JSON table. */
File src/cmd_handlers.c changed (mode: 100644) (index 4cd2d78df..9f672e0fa)
... ... file_cmd(const cmd_info_t *cmd_info)
2467 2467 if(cmd_info->argc == 0) if(cmd_info->argc == 0)
2468 2468 { {
2469 2469 cmds_preserve_selection(); cmds_preserve_selection();
2470 return show_file_menu(curr_view, cmd_info->bg) != 0;
2470 return show_file_menu(curr_view, cfg.hide_missing_progs, cmd_info->bg) != 0;
2471 2471 } }
2472 2472
2473 2473 if(rn_open_with_match(curr_view, cmd_info->argv[0], cmd_info->bg) != 0) if(rn_open_with_match(curr_view, cmd_info->argv[0], cmd_info->bg) != 0)
File src/menus/filetypes_menu.c changed (mode: 100644) (index d966c1148..9baac0e67)
... ... static void fill_menu_from_records(menu_data_t *m,
51 51 static int max_desc_len(const assoc_records_t *records); static int max_desc_len(const assoc_records_t *records);
52 52
53 53 int int
54 show_file_menu(view_t *view, int background)
54 show_file_menu(view_t *view, int present_only, int background)
55 55 { {
56 56 static menu_data_t m; static menu_data_t m;
57 57
 
... ... show_file_menu(view_t *view, int background)
83 83
84 84 for(i = 0; i < ft.count; ++i) for(i = 0; i < ft.count; ++i)
85 85 { {
86 const int present = ft_exists(ft.list[i].command);
87 if(present_only && !present)
88 {
89 continue;
90 }
91
86 92 (void)add_to_string_array(&m.data, m.len, ft.list[i].command); (void)add_to_string_array(&m.data, m.len, ft.list[i].command);
87 const char *entry =
88 form_filetype_menu_entry(ft.list[i], max_len, /*present=*/-1);
93 const char *entry = form_filetype_menu_entry(ft.list[i], max_len, present);
89 94 m.len = add_to_string_array(&m.items, m.len, entry); m.len = add_to_string_array(&m.items, m.len, entry);
90 95 } }
91 96
92 97 #ifdef ENABLE_DESKTOP_FILES #ifdef ENABLE_DESKTOP_FILES
93 /* Add empty line separator if there is at least one other item of either
94 * kind. */
95 if(ft.count > 0 || magic.count > 0)
96 {
97 (void)add_to_string_array(&m.data, m.len, NONE_PSEUDO_PROG.command);
98 m.len = add_to_string_array(&m.items, m.len, "");
99 }
98 /* Always add empty line separator and handle the case when it's the only line
99 * below. */
100 (void)add_to_string_array(&m.data, m.len, NONE_PSEUDO_PROG.command);
101 m.len = add_to_string_array(&m.items, m.len, "");
100 102 #endif #endif
101 103
102 104 ft_assoc_records_free(&ft); ft_assoc_records_free(&ft);
103 105
104 106 for(i = 0; i < magic.count; ++i) for(i = 0; i < magic.count; ++i)
105 107 { {
108 const int present = ft_exists(magic.list[i].command);
109 if(present_only && !present)
110 {
111 continue;
112 }
113
106 114 (void)add_to_string_array(&m.data, m.len, magic.list[i].command); (void)add_to_string_array(&m.data, m.len, magic.list[i].command);
107 115 const char *entry = const char *entry =
108 form_filetype_menu_entry(magic.list[i], max_len, /*present=*/-1);
116 form_filetype_menu_entry(magic.list[i], max_len, present);
109 117 m.len = add_to_string_array(&m.items, m.len, entry); m.len = add_to_string_array(&m.items, m.len, entry);
110 118 } }
111 119
120 #ifdef ENABLE_DESKTOP_FILES
121 /* There is nothing but the separator, drop it. */
122 if(m.len == 1)
123 {
124 free_string_array(m.items, m.len);
125 free_string_array(m.data, m.len);
126 m.items = NULL;
127 m.data = NULL;
128 m.len = 0;
129 }
130 #endif
131
112 132 return menus_enter(&m, view); return menus_enter(&m, view);
113 133 } }
114 134
File src/menus/filetypes_menu.h changed (mode: 100644) (index bd9089f31..1fe64f21f)
... ... struct view_t;
24 24
25 25 /* Displays file handler picking menu. Returns non-zero if status bar message /* Displays file handler picking menu. Returns non-zero if status bar message
26 26 * should be saved. */ * should be saved. */
27 int show_file_menu(struct view_t *view, int background);
27 int show_file_menu(struct view_t *view, int present_only, int background);
28 28
29 29 /* Displays menu with list of programs registered for specified file name. /* Displays menu with list of programs registered for specified file name.
30 30 * Returns non-zero if status bar message should be saved. */ * Returns non-zero if status bar message should be saved. */
File src/modes/normal.c changed (mode: 100644) (index c20a3f0c3..64cd57dc5)
... ... handle_mouse_event(key_info_t key_info, keys_info_t *keys_info)
2419 2419 if(list_pos >= 0) if(list_pos >= 0)
2420 2420 { {
2421 2421 fpos_set_pos(curr_view, list_pos); fpos_set_pos(curr_view, list_pos);
2422 curr_stats.save_msg = show_file_menu(curr_view, 0);
2422 curr_stats.save_msg =
2423 show_file_menu(curr_view, cfg.hide_missing_progs, /*background=*/0);
2423 2424 } }
2424 2425 } }
2425 2426 else if(e.bstate & BUTTON4_PRESSED) else if(e.bstate & BUTTON4_PRESSED)
File src/opt_handlers.c changed (mode: 100644) (index 65afbf505..b75bccb3c)
... ... static void uni_handler(const char name[], optval_t val, OPT_SCOPE scope);
86 86 static void init_classify(optval_t *val); static void init_classify(optval_t *val);
87 87 static void init_cpoptions(optval_t *val); static void init_cpoptions(optval_t *val);
88 88 static void init_dirsize(optval_t *val); static void init_dirsize(optval_t *val);
89 static void init_fileoptions(optval_t *val);
89 90 static void init_fillchars(optval_t *val); static void init_fillchars(optval_t *val);
90 91 static void init_hloptions(optval_t *val); static void init_hloptions(optval_t *val);
91 92 static const char * to_endpoint(int i, char buffer[]); static const char * to_endpoint(int i, char buffer[]);
 
... ... static void dirsize_handler(OPT_OP op, optval_t val);
135 136 static void dotdirs_handler(OPT_OP op, optval_t val); static void dotdirs_handler(OPT_OP op, optval_t val);
136 137 static void extprompt_handler(OPT_OP op, optval_t val); static void extprompt_handler(OPT_OP op, optval_t val);
137 138 static void fastrun_handler(OPT_OP op, optval_t val); static void fastrun_handler(OPT_OP op, optval_t val);
139 static void fileoptions_handler(OPT_OP op, optval_t val);
140 static void load_fileoptions(void);
138 141 static void fillchars_handler(OPT_OP op, optval_t val); static void fillchars_handler(OPT_OP op, optval_t val);
139 142 static void load_fillchars(void); static void load_fillchars(void);
140 143 static void findprg_handler(OPT_OP op, optval_t val); static void findprg_handler(OPT_OP op, optval_t val);
 
... ... static const char *extprompt_vals[][2] = {
306 309 }; };
307 310 ARRAY_GUARD(extprompt_vals, NUM_EXT_PROMPT); ARRAY_GUARD(extprompt_vals, NUM_EXT_PROMPT);
308 311
312 /* Possible values of 'fileoptions' option. */
313 static const char *fileoptions_enum[][2] = {
314 { "hidemissing", "Don't list handlers which aren't present" },
315 };
316
309 317 /* Possible values of 'histcursor'. */ /* Possible values of 'histcursor'. */
310 318 static const char *histcursor_vals[][2] = { static const char *histcursor_vals[][2] = {
311 319 [BIT(CHPOS_STARTUP)] = { "startup", "initial view loading on startup" }, [BIT(CHPOS_STARTUP)] = { "startup", "initial view loading on startup" },
 
... ... options[] = {
667 675 OPT_BOOL, 0, NULL, &fastrun_handler, NULL, OPT_BOOL, 0, NULL, &fastrun_handler, NULL,
668 676 { .ref.bool_val = &cfg.fast_run }, { .ref.bool_val = &cfg.fast_run },
669 677 }, },
678 { "fileoptions", "", ":file options",
679 OPT_STRLIST, ARRAY_LEN(fileoptions_enum), fileoptions_enum,
680 &fileoptions_handler, NULL,
681 { .init = &init_fileoptions },
682 },
670 683 { "fillchars", "fcs", "fillers for interface parts", { "fillchars", "fcs", "fillers for interface parts",
671 684 OPT_STRLIST, ARRAY_LEN(fillchars_enum), fillchars_enum, &fillchars_handler, OPT_STRLIST, ARRAY_LEN(fillchars_enum), fillchars_enum, &fillchars_handler,
672 685 NULL, NULL,
 
... ... init_dirsize(optval_t *val)
1186 1199 val->enum_item = (cfg.view_dir_size == VDS_SIZE ? 0 : 1); val->enum_item = (cfg.view_dir_size == VDS_SIZE ? 0 : 1);
1187 1200 } }
1188 1201
1202 /* Initializes 'fileoptions' option. */
1203 static void
1204 init_fileoptions(optval_t *val)
1205 {
1206 static char buf[128];
1207
1208 buf[0] = '\0';
1209 if(cfg.hide_missing_progs)
1210 snprintf(buf, sizeof(buf), "hidemissing");
1211
1212 val->str_val = buf;
1213 }
1214
1189 1215 /* Initializes 'fillchars' option. */ /* Initializes 'fillchars' option. */
1190 1216 static void static void
1191 1217 init_fillchars(optval_t *val) init_fillchars(optval_t *val)
 
... ... fastrun_handler(OPT_OP op, optval_t val)
2188 2214 cfg.fast_run = val.bool_val; cfg.fast_run = val.bool_val;
2189 2215 } }
2190 2216
2217 /* Handles new value for 'fileoptions' option. */
2218 static void
2219 fileoptions_handler(OPT_OP op, optval_t val)
2220 {
2221 char *new_val = strdup(val.str_val);
2222 if(new_val == NULL)
2223 {
2224 load_fileoptions();
2225 return;
2226 }
2227
2228 char *part = new_val, *state = NULL;
2229
2230 int hide_missing_progs = 0;
2231
2232 int error = 0;
2233 while((part = split_and_get(part, ',', &state)) != NULL)
2234 {
2235 if(starts_with_lit(part, "hidemissing"))
2236 {
2237 hide_missing_progs = 1;
2238 }
2239 else
2240 {
2241 error = 1;
2242 break_at(part, ':');
2243 vle_tb_append_linef(vle_err, "Unknown key for 'fileoptions' option: %s",
2244 part);
2245 break;
2246 }
2247 }
2248 free(new_val);
2249
2250 if(!error)
2251 {
2252 cfg.hide_missing_progs = hide_missing_progs;
2253 }
2254
2255 /* In case of error, restore previous value, otherwise reload it anyway to
2256 * remove any duplicates. */
2257 load_fileoptions();
2258 }
2259
2260 /* Sets value of 'fileoptions' option by composing it from the current
2261 * configuration. */
2262 static void
2263 load_fileoptions(void)
2264 {
2265 optval_t val;
2266 init_fileoptions(&val);
2267 vle_opts_assign("fileoptions", val, OPT_GLOBAL);
2268 }
2269
2191 2270 /* Handles new value for 'fillchars' option. */ /* Handles new value for 'fillchars' option. */
2192 2271 static void static void
2193 2272 fillchars_handler(OPT_OP op, optval_t val) fillchars_handler(OPT_OP op, optval_t val)
File src/tags.c changed (mode: 100644) (index c03cff231..3e05641c1)
... ... const char *tags[] = {
62 62 "vifm-'extprompt'", "vifm-'extprompt'",
63 63 "vifm-'fastrun'", "vifm-'fastrun'",
64 64 "vifm-'fcs'", "vifm-'fcs'",
65 "vifm-'fileoptions'",
65 66 "vifm-'fillchars'", "vifm-'fillchars'",
66 67 "vifm-'findprg'", "vifm-'findprg'",
67 68 "vifm-'followlinks'", "vifm-'followlinks'",
File tests/menus/filetypes.c changed (mode: 100644) (index 9a703b3da..67b83da3b)
1 1 #include <stic.h> #include <stic.h>
2 2
3 3 #include <stddef.h> /* NULL */ #include <stddef.h> /* NULL */
4 #include <string.h> /* strcpy() */
5 4
6 5 #include <test-utils.h> #include <test-utils.h>
7 6
7 #include "../../src/cfg/config.h"
8 8 #include "../../src/compat/fs_limits.h" #include "../../src/compat/fs_limits.h"
9 9 #include "../../src/engine/keys.h" #include "../../src/engine/keys.h"
10 10 #include "../../src/engine/mode.h" #include "../../src/engine/mode.h"
 
14 14 #include "../../src/modes/wk.h" #include "../../src/modes/wk.h"
15 15 #include "../../src/ui/ui.h" #include "../../src/ui/ui.h"
16 16 #include "../../src/utils/fs.h" #include "../../src/utils/fs.h"
17 #include "../../src/utils/str.h"
17 18 #include "../../src/cmd_core.h" #include "../../src/cmd_core.h"
18 19 #include "../../src/filelist.h" #include "../../src/filelist.h"
19 20 #include "../../src/filetype.h" #include "../../src/filetype.h"
20 21 #include "../../src/status.h" #include "../../src/status.h"
21 22
23 static int fake_prog_exists(const char name[]);
24 static void setup_file_test(void);
25
22 26 static line_stats_t *stats; static line_stats_t *stats;
23 27 static char cwd[PATH_MAX + 1]; static char cwd[PATH_MAX + 1];
24 28
 
... ... SETUP_ONCE()
28 32
29 33 assert_non_null(get_cwd(cwd, sizeof(cwd))); assert_non_null(get_cwd(cwd, sizeof(cwd)));
30 34
31 ft_init(NULL);
35 ft_init(&fake_prog_exists);
32 36 } }
33 37
34 38 SETUP() SETUP()
 
... ... TEST(unknown_key_is_ignored)
109 113 (void)vle_keys_exec(WK_ESC); (void)vle_keys_exec(WK_ESC);
110 114 } }
111 115
116 TEST(file_can_show_missing_entries)
117 {
118 setup_file_test();
119
120 assert_success(cmds_dispatch1("file", &lwin, CIT_COMMAND));
121
122 assert_true(menu_get_current()->len >= 3);
123 assert_string_equal(" no-cat", menu_get_current()->items[0]);
124 assert_string_equal("[present] cat", menu_get_current()->items[1]);
125 assert_string_equal(" no-echo", menu_get_current()->items[2]);
126 if(menu_get_current()->len > 3)
127 {
128 assert_int_equal(4, menu_get_current()->len);
129 /* Separator. */
130 assert_string_equal("", menu_get_current()->items[3]);
131 }
132
133 (void)vle_keys_exec(WK_ESC);
134 }
135
136 TEST(file_can_hide_missing_entries)
137 {
138 cfg.hide_missing_progs = 1;
139
140 setup_file_test();
141
142 assert_success(cmds_dispatch1("file", &lwin, CIT_COMMAND));
143
144 assert_true(menu_get_current()->len >= 1);
145 assert_string_equal("[present] cat", menu_get_current()->items[0]);
146 if(menu_get_current()->len > 1)
147 {
148 assert_int_equal(2, menu_get_current()->len);
149 /* Separator. */
150 assert_string_equal("", menu_get_current()->items[1]);
151 }
152
153 (void)vle_keys_exec(WK_ESC);
154
155 cfg.hide_missing_progs = 0;
156 }
157
112 158 TEST(pseudo_entry_is_always_present_for_directories) TEST(pseudo_entry_is_always_present_for_directories)
113 159 { {
114 160 assoc_programs("{bla-*/}", "abc-run %c", 0, 0); assoc_programs("{bla-*/}", "abc-run %c", 0, 0);
 
... ... TEST(fileviewers_menu)
153 199 (void)vle_keys_exec(WK_ESC); (void)vle_keys_exec(WK_ESC);
154 200 } }
155 201
202 static int
203 fake_prog_exists(const char name[])
204 {
205 return !starts_with_lit(name, "no-");
206 }
207
208 static void
209 setup_file_test(void)
210 {
211 dir_entry_t *entry = get_current_entry(&lwin);
212
213 update_string(&entry->name, "test-file");
214 entry->type = FT_REG;
215
216 assert_success(cmds_dispatch("filetype test-file no-cat", &lwin,
217 CIT_COMMAND));
218 assert_success(cmds_dispatch("filetype test-file cat", &lwin, CIT_COMMAND));
219 assert_success(cmds_dispatch("filetype test-file no-echo", &lwin,
220 CIT_COMMAND));
221 }
222
156 223 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
157 224 /* vim: set cinoptions+=t0 : */ /* vim: set cinoptions+=t0 : */
File tests/misc/options.c changed (mode: 100644) (index 9bb084c2b..41d8f68a4)
... ... TEST(keepsel)
768 768 assert_true(cfg.keep_sel); assert_true(cfg.keep_sel);
769 769 } }
770 770
771 TEST(fileoptions)
772 {
773 /* Setting. */
774 assert_success(cmds_dispatch1("set fileoptions=hidemissing", &lwin,
775 CIT_COMMAND));
776 assert_true(cfg.hide_missing_progs);
777
778 /* Clearing. */
779 assert_success(cmds_dispatch1("set fileoptions=", &lwin, CIT_COMMAND));
780 assert_false(cfg.hide_missing_progs);
781
782 /* Wrong value is reported, intermediate state is discarded. */
783 ui_sb_msg("");
784 assert_failure(cmds_dispatch1("set fileoptions=hidemissing,bad", &lwin,
785 CIT_COMMAND));
786 assert_string_equal("Unknown key for 'fileoptions' option: bad",
787 ui_sb_last());
788 assert_false(cfg.hide_missing_progs);
789
790 /* Values are deduplicated. */
791 ui_sb_msg("");
792 assert_success(cmds_dispatch1("set fileoptions=hidemissing,hidemissing",
793 &lwin, CIT_COMMAND));
794 assert_failure(cmds_dispatch1("set fileoptions", &lwin, CIT_COMMAND));
795 assert_string_equal(" fileoptions=hidemissing", ui_sb_last());
796 }
797
771 798 static void static void
772 799 print_func(const char buf[], int offset, AlignType align, print_func(const char buf[], int offset, AlignType align,
773 800 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 9e1d0d0cd..be2b6ea7a)
... ... hi WildBox
625 625 " "uioptions" should be highlighted as 'option' " "uioptions" should be highlighted as 'option'
626 626 " "extprompt" should be highlighted as 'option' " "extprompt" should be highlighted as 'option'
627 627 " "keepsel", "nokeepsel" and "invkeepsel" should be highlighted as 'option' " "keepsel", "nokeepsel" and "invkeepsel" should be highlighted as 'option'
628 " "fileoptions" should be highlighted as 'option'
628 629 set dotfiles nodotfiles invdotfiles dotfiles! set dotfiles nodotfiles invdotfiles dotfiles!
629 630 set caseoptions set caseoptions
630 631 set sizefmt set sizefmt
 
... ... set wildinc
653 654 set uioptions set uioptions
654 655 set extprompt set extprompt
655 656 set keepsel nokeepsel invkeepsel keepsel! set keepsel nokeepsel invkeepsel keepsel!
657 set fileoptions
656 658
657 659 " "echo" and "call" should be highlighted as :command " "echo" and "call" should be highlighted as :command
658 660 " "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