File src/cmd_completion.c changed (mode: 100644) (index 9eda1c771..9b0c01a60) |
... |
... |
static void complete_wingo(const char str[]); |
119 |
119 |
static int wingo_sorter(const char a[], const char b[]); |
static int wingo_sorter(const char a[], const char b[]); |
120 |
120 |
static const char * skip_number(const char str[]); |
static const char * skip_number(const char str[]); |
121 |
121 |
static void complete_winrun(const char str[]); |
static void complete_winrun(const char str[]); |
|
122 |
|
static void complete_view(const char str[]); |
122 |
123 |
static void complete_from_string_list(const char str[], const char *items[][2], |
static void complete_from_string_list(const char str[], const char *items[][2], |
123 |
124 |
size_t item_count, int ignore_case); |
size_t item_count, int ignore_case); |
124 |
125 |
static void complete_command_name(const char beginning[]); |
static void complete_command_name(const char beginning[]); |
|
... |
... |
non_path_completion(completion_data_t *data) |
322 |
323 |
}; |
}; |
323 |
324 |
complete_from_string_list(arg, lines, ARRAY_LEN(lines), /*ignore_case=*/0); |
complete_from_string_list(arg, lines, ARRAY_LEN(lines), /*ignore_case=*/0); |
324 |
325 |
} |
} |
|
326 |
|
else if(id == COM_VIEW) |
|
327 |
|
{ |
|
328 |
|
if(!emark) |
|
329 |
|
{ |
|
330 |
|
complete_view(arg); |
|
331 |
|
} |
|
332 |
|
} |
325 |
333 |
else |
else |
326 |
334 |
{ |
{ |
327 |
335 |
return -1; |
return -1; |
|
... |
... |
complete_winrun(const char str[]) |
1124 |
1132 |
complete_from_string_list(str, win_marks, ARRAY_LEN(win_marks), 0); |
complete_from_string_list(str, win_marks, ARRAY_LEN(win_marks), 0); |
1125 |
1133 |
} |
} |
1126 |
1134 |
|
|
|
1135 |
|
/* Completes the first argument of :view. */ |
|
1136 |
|
static void |
|
1137 |
|
complete_view(const char str[]) |
|
1138 |
|
{ |
|
1139 |
|
static const char *lines[][2] = { |
|
1140 |
|
{ "next", "make the next previewer the default one" }, |
|
1141 |
|
{ "prev", "make the last previewer the default one" }, |
|
1142 |
|
}; |
|
1143 |
|
complete_from_string_list(str, lines, ARRAY_LEN(lines), /*ignore_case=*/0); |
|
1144 |
|
} |
|
1145 |
|
|
1127 |
1146 |
/* Performs str completion using items in the list of length item_count. */ |
/* Performs str completion using items in the list of length item_count. */ |
1128 |
1147 |
static void |
static void |
1129 |
1148 |
complete_from_string_list(const char str[], const char *items[][2], |
complete_from_string_list(const char str[], const char *items[][2], |
File src/cmd_handlers.c changed (mode: 100644) (index 5a21128f5..b99cd3c8a) |
... |
... |
const cmd_add_t cmds_list[] = { |
936 |
936 |
.descr = "display version information", |
.descr = "display version information", |
937 |
937 |
.flags = HAS_COMMENT, |
.flags = HAS_COMMENT, |
938 |
938 |
.handler = &vifm_cmd, .min_args = 0, .max_args = 0, }, |
.handler = &vifm_cmd, .min_args = 0, .max_args = 0, }, |
939 |
|
{ .name = "view", .abbr = "vie", .id = -1, |
|
|
939 |
|
{ .name = "view", .abbr = "vie", .id = COM_VIEW, |
940 |
940 |
.descr = "control visibility of preview", |
.descr = "control visibility of preview", |
941 |
941 |
.flags = HAS_EMARK | HAS_COMMENT, |
.flags = HAS_EMARK | HAS_COMMENT, |
942 |
|
.handler = &view_cmd, .min_args = 0, .max_args = 0, }, |
|
|
942 |
|
.handler = &view_cmd, .min_args = 0, .max_args = 1, }, |
943 |
943 |
{ .name = "vifm", .abbr = NULL, .id = -1, |
{ .name = "vifm", .abbr = NULL, .id = -1, |
944 |
944 |
.descr = "display version information", |
.descr = "display version information", |
945 |
945 |
.flags = HAS_COMMENT, |
.flags = HAS_COMMENT, |
|
... |
... |
unselect_cmd(const cmd_info_t *cmd_info) |
5355 |
5355 |
return (error ? CMDS_ERR_CUSTOM : 0); |
return (error ? CMDS_ERR_CUSTOM : 0); |
5356 |
5356 |
} |
} |
5357 |
5357 |
|
|
|
5358 |
|
/* Enables/disables/toggles quickview and switches viewers. */ |
5358 |
5359 |
static int |
static int |
5359 |
5360 |
view_cmd(const cmd_info_t *cmd_info) |
view_cmd(const cmd_info_t *cmd_info) |
5360 |
5361 |
{ |
{ |
5361 |
5362 |
cmds_preserve_selection(); |
cmds_preserve_selection(); |
5362 |
5363 |
|
|
5363 |
|
if((!curr_stats.preview.on || cmd_info->emark) && !qv_can_show()) |
|
|
5364 |
|
if(cmd_info->emark && cmd_info->argc != 0) |
5364 |
5365 |
{ |
{ |
|
5366 |
|
ui_sb_err("No arguments are allowed if you use \"!\""); |
5365 |
5367 |
return CMDS_ERR_CUSTOM; |
return CMDS_ERR_CUSTOM; |
5366 |
5368 |
} |
} |
5367 |
|
if(curr_stats.preview.on && cmd_info->emark) |
|
|
5369 |
|
|
|
5370 |
|
if(cmd_info->argc == 0) |
5368 |
5371 |
{ |
{ |
|
5372 |
|
if((!curr_stats.preview.on || cmd_info->emark) && !qv_can_show()) |
|
5373 |
|
{ |
|
5374 |
|
return CMDS_ERR_CUSTOM; |
|
5375 |
|
} |
|
5376 |
|
if(curr_stats.preview.on && cmd_info->emark) |
|
5377 |
|
{ |
|
5378 |
|
return 0; |
|
5379 |
|
} |
|
5380 |
|
qv_toggle(); |
5369 |
5381 |
return 0; |
return 0; |
5370 |
5382 |
} |
} |
5371 |
|
qv_toggle(); |
|
5372 |
|
return 0; |
|
|
5383 |
|
|
|
5384 |
|
if(strcmp(cmd_info->argv[0], "prev") != 0 && |
|
5385 |
|
strcmp(cmd_info->argv[0], "next") != 0) |
|
5386 |
|
{ |
|
5387 |
|
ui_sb_errf("Unexpected action: %s", cmd_info->argv[0]); |
|
5388 |
|
return CMDS_ERR_CUSTOM; |
|
5389 |
|
} |
|
5390 |
|
|
|
5391 |
|
char *typed_fpath = get_typed_entry_fpath(get_current_entry(curr_view)); |
|
5392 |
|
if(typed_fpath == NULL) |
|
5393 |
|
{ |
|
5394 |
|
show_error_msg("Memory Error", "Unable to allocate enough memory"); |
|
5395 |
|
return 0; |
|
5396 |
|
} |
|
5397 |
|
|
|
5398 |
|
assoc_records_t viewers = ft_get_all_viewers(typed_fpath); |
|
5399 |
|
if(viewers.count == 0) |
|
5400 |
|
{ |
|
5401 |
|
free(typed_fpath); |
|
5402 |
|
ft_assoc_records_free(&viewers); |
|
5403 |
|
ui_sb_msg("No viewers for the current file"); |
|
5404 |
|
return 1; |
|
5405 |
|
} |
|
5406 |
|
|
|
5407 |
|
if(viewers.count != 1) |
|
5408 |
|
{ |
|
5409 |
|
if(strcmp(cmd_info->argv[0], "next") == 0) |
|
5410 |
|
{ |
|
5411 |
|
ft_move_viewer_cycle_next(typed_fpath); |
|
5412 |
|
} |
|
5413 |
|
else |
|
5414 |
|
{ |
|
5415 |
|
ft_move_viewer_cycle_prev(typed_fpath); |
|
5416 |
|
} |
|
5417 |
|
|
|
5418 |
|
ft_assoc_records_free(&viewers); |
|
5419 |
|
viewers = ft_get_all_viewers(typed_fpath); |
|
5420 |
|
|
|
5421 |
|
stats_redraw_later(); |
|
5422 |
|
|
|
5423 |
|
if(viewers.count == 0) |
|
5424 |
|
{ |
|
5425 |
|
free(typed_fpath); |
|
5426 |
|
ft_assoc_records_free(&viewers); |
|
5427 |
|
show_error_msg("Memory Error", "Unable to allocate enough memory"); |
|
5428 |
|
return 0; |
|
5429 |
|
} |
|
5430 |
|
} |
|
5431 |
|
|
|
5432 |
|
const char *text = viewers.list[0].description; |
|
5433 |
|
if(is_null_or_empty(text)) |
|
5434 |
|
{ |
|
5435 |
|
text = viewers.list[0].command; |
|
5436 |
|
} |
|
5437 |
|
ui_sb_msgf("Top viewer (out of %d): %s", viewers.count, text); |
|
5438 |
|
|
|
5439 |
|
ft_assoc_records_free(&viewers); |
|
5440 |
|
free(typed_fpath); |
|
5441 |
|
return 1; |
5373 |
5442 |
} |
} |
5374 |
5443 |
|
|
5375 |
5444 |
static int |
static int |
File src/filetype.c changed (mode: 100644) (index 13d6bf38b..2c8d98982) |
... |
... |
reordering_data_t; |
63 |
63 |
static const char * find_existing_cmd(const assoc_list_t *record_list, |
static const char * find_existing_cmd(const assoc_list_t *record_list, |
64 |
64 |
const char file[]); |
const char file[]); |
65 |
65 |
static assoc_record_t find_existing_cmd_record(const assoc_records_t *records); |
static assoc_record_t find_existing_cmd_record(const assoc_records_t *records); |
|
66 |
|
static int pick_out_until_last(const char file[], reordering_data_t *d); |
66 |
67 |
static void make_pivot_first(reordering_data_t *d); |
static void make_pivot_first(reordering_data_t *d); |
|
68 |
|
static void make_pivot_last(reordering_data_t *d); |
67 |
69 |
static int pick_out_until_first(const char file[], const char viewer[], |
static int pick_out_until_first(const char file[], const char viewer[], |
68 |
70 |
reordering_data_t *d); |
reordering_data_t *d); |
69 |
71 |
static int split_assoc(assoc_t *assoc, int at_record_idx, assoc_t *out_prefix); |
static int split_assoc(assoc_t *assoc, int at_record_idx, assoc_t *out_prefix); |
|
... |
... |
ft_move_viewer_to_top(const char file[], const char viewer[]) |
238 |
240 |
DA_REMOVE_ALL(d.prefix); |
DA_REMOVE_ALL(d.prefix); |
239 |
241 |
} |
} |
240 |
242 |
|
|
|
243 |
|
void |
|
244 |
|
ft_move_viewer_cycle_prev(const char file[]) |
|
245 |
|
{ |
|
246 |
|
reordering_data_t d = {}; |
|
247 |
|
|
|
248 |
|
/* |
|
249 |
|
* Overall approach: |
|
250 |
|
* 1. Find the last entry with an existing program record. |
|
251 |
|
* 2. Move all of its matching predecessors to the end of the list. |
|
252 |
|
* 3. Special case: if that record is not the first one, cut the entry at it |
|
253 |
|
* and make it last. |
|
254 |
|
*/ |
|
255 |
|
if(pick_out_until_last(file, &d) == 0) |
|
256 |
|
{ |
|
257 |
|
make_pivot_first(&d); |
|
258 |
|
} |
|
259 |
|
|
|
260 |
|
free(d.list); |
|
261 |
|
DA_REMOVE_ALL(d.prefix); |
|
262 |
|
} |
|
263 |
|
|
|
264 |
|
/* Finds the last matching entry in the list of viewers that's also present. |
|
265 |
|
* Collects all entries that match file and precede the found entry in |
|
266 |
|
* d->prefix. Returns zero on successfully finding a viewer. */ |
|
267 |
|
static int |
|
268 |
|
pick_out_until_last(const char file[], reordering_data_t *d) |
|
269 |
|
{ |
|
270 |
|
int l; |
|
271 |
|
for(l = fileviewers.count - 1; l >= 0; --l) |
|
272 |
|
{ |
|
273 |
|
assoc_t *assoc = &fileviewers.list[l]; |
|
274 |
|
|
|
275 |
|
if(!mg_match(&assoc->mg, file)) |
|
276 |
|
{ |
|
277 |
|
continue; |
|
278 |
|
} |
|
279 |
|
|
|
280 |
|
for(d->k = assoc->records.count - 1; d->k >= 0; --d->k) |
|
281 |
|
{ |
|
282 |
|
if(ft_exists(assoc->records.list[d->k].command)) |
|
283 |
|
{ |
|
284 |
|
break; |
|
285 |
|
} |
|
286 |
|
} |
|
287 |
|
|
|
288 |
|
if(d->k >= 0) |
|
289 |
|
{ |
|
290 |
|
break; |
|
291 |
|
} |
|
292 |
|
} |
|
293 |
|
|
|
294 |
|
if(l < 0) |
|
295 |
|
{ |
|
296 |
|
/* No present viewers for the file. */ |
|
297 |
|
return 1; |
|
298 |
|
} |
|
299 |
|
|
|
300 |
|
/* The new list needs to have room for an extra element in case a matching |
|
301 |
|
* entry needs to be split in two. */ |
|
302 |
|
d->list = malloc((fileviewers.count + 1)*sizeof(*d->list)); |
|
303 |
|
if(d->list == NULL) |
|
304 |
|
{ |
|
305 |
|
return 1; |
|
306 |
|
} |
|
307 |
|
|
|
308 |
|
/* Make the last entry the top one by moving all matching predecessors |
|
309 |
|
* directly below it (rotate matching viewers around the last of them). */ |
|
310 |
|
for(d->i = 0, d->j = 0; d->i < l; ++d->i) |
|
311 |
|
{ |
|
312 |
|
assoc_t *assoc = &fileviewers.list[d->i]; |
|
313 |
|
|
|
314 |
|
if(!mg_match(&assoc->mg, file)) |
|
315 |
|
{ |
|
316 |
|
d->list[d->j++] = *assoc; |
|
317 |
|
continue; |
|
318 |
|
} |
|
319 |
|
|
|
320 |
|
assoc_t *another = DA_EXTEND(d->prefix); |
|
321 |
|
if(another == NULL) |
|
322 |
|
{ |
|
323 |
|
return 1; |
|
324 |
|
} |
|
325 |
|
|
|
326 |
|
*another = *assoc; |
|
327 |
|
DA_COMMIT(d->prefix); |
|
328 |
|
} |
|
329 |
|
|
|
330 |
|
return 0; |
|
331 |
|
} |
|
332 |
|
|
241 |
333 |
/* Makes a "pivot" element the first one among subset of matching file viewers. |
/* Makes a "pivot" element the first one among subset of matching file viewers. |
242 |
334 |
* This is done by putting the element, the tail of the original list and all |
* This is done by putting the element, the tail of the original list and all |
243 |
335 |
* subset elements in front of the pivot in the right order. */ |
* subset elements in front of the pivot in the right order. */ |
|
... |
... |
make_pivot_first(reordering_data_t *d) |
278 |
370 |
} |
} |
279 |
371 |
} |
} |
280 |
372 |
|
|
|
373 |
|
void |
|
374 |
|
ft_move_viewer_cycle_next(const char file[]) |
|
375 |
|
{ |
|
376 |
|
reordering_data_t d = {}; |
|
377 |
|
|
|
378 |
|
/* |
|
379 |
|
* Overall approach: |
|
380 |
|
* 1. Find the first entry with an existing program record. |
|
381 |
|
* 2. Move it after the last matching entry. |
|
382 |
|
* 3. Special case: if the record is not the last one, cut the entry after |
|
383 |
|
* the record and move only this prefix. |
|
384 |
|
*/ |
|
385 |
|
if(pick_out_until_first(file, /*viewer=*/NULL, &d) == 0) |
|
386 |
|
{ |
|
387 |
|
make_pivot_last(&d); |
|
388 |
|
} |
|
389 |
|
|
|
390 |
|
free(d.list); |
|
391 |
|
DA_REMOVE_ALL(d.prefix); |
|
392 |
|
} |
|
393 |
|
|
|
394 |
|
/* Makes a "pivot" element the last one among subset of matching file viewers. |
|
395 |
|
* This is done by putting the element, the tail of the original list and all |
|
396 |
|
* subset elements in front of the pivot in the right order. */ |
|
397 |
|
static void |
|
398 |
|
make_pivot_last(reordering_data_t *d) |
|
399 |
|
{ |
|
400 |
|
assoc_t last_item; |
|
401 |
|
int need_split = (d->k != fileviewers.list[d->i].records.count - 1); |
|
402 |
|
if(need_split) |
|
403 |
|
{ |
|
404 |
|
/* The viewer is not the last in the list, so split the association at |
|
405 |
|
* the viewer. The code below ensures the viewer will be at the new top |
|
406 |
|
* for the subset matching this file and then the prefix will be |
|
407 |
|
* appended-> */ |
|
408 |
|
if(split_assoc(&fileviewers.list[d->i], d->k + 1, &last_item) != 0) |
|
409 |
|
{ |
|
410 |
|
return; |
|
411 |
|
} |
|
412 |
|
} |
|
413 |
|
else |
|
414 |
|
{ |
|
415 |
|
last_item = fileviewers.list[d->i++]; |
|
416 |
|
} |
|
417 |
|
|
|
418 |
|
mem_cpy(&d->list[d->j], &fileviewers.list[d->i], fileviewers.count - d->i, |
|
419 |
|
sizeof(d->list[0])); |
|
420 |
|
d->j += fileviewers.count - d->i; |
|
421 |
|
|
|
422 |
|
mem_cpy(&d->list[d->j], &d->prefix[0], DA_SIZE(d->prefix), |
|
423 |
|
sizeof(d->prefix[0])); |
|
424 |
|
d->j += DA_SIZE(d->prefix); |
|
425 |
|
|
|
426 |
|
free(fileviewers.list); |
|
427 |
|
fileviewers.list = d->list; |
|
428 |
|
d->list = NULL; |
|
429 |
|
|
|
430 |
|
if(need_split) |
|
431 |
|
{ |
|
432 |
|
assert(d->j == fileviewers.count); |
|
433 |
|
fileviewers.list[fileviewers.count++] = last_item; |
|
434 |
|
} |
|
435 |
|
else |
|
436 |
|
{ |
|
437 |
|
assert(d->j == fileviewers.count - 1); |
|
438 |
|
fileviewers.list[d->j] = last_item; |
|
439 |
|
} |
|
440 |
|
} |
|
441 |
|
|
281 |
442 |
/* Finds a matching entry in the list of viewers either by checking for its |
/* Finds a matching entry in the list of viewers either by checking for its |
282 |
443 |
* existence (viewer is NULL) or by matching it against a passed in string |
* existence (viewer is NULL) or by matching it against a passed in string |
283 |
444 |
* (viewer is not NULL). Collects all entries matching file in d->prefix array |
* (viewer is not NULL). Collects all entries matching file in d->prefix array |
File tests/filetype/viewers.c changed (mode: 100644) (index 73f3107ed..8262a752e) |
12 |
12 |
#include "../../src/utils/string_array.h" |
#include "../../src/utils/string_array.h" |
13 |
13 |
#include "test.h" |
#include "test.h" |
14 |
14 |
|
|
|
15 |
|
static int name_based_exists(const char name[]); |
|
16 |
|
|
15 |
17 |
static int |
static int |
16 |
18 |
prog1_available(const char name[]) |
prog1_available(const char name[]) |
17 |
19 |
{ |
{ |
|
... |
... |
TEST(viewer_kind) |
145 |
147 |
assert_int_equal(VK_GRAPHICAL, ft_viewer_kind("echo %px %py %pw %ph %%pd")); |
assert_int_equal(VK_GRAPHICAL, ft_viewer_kind("echo %px %py %pw %ph %%pd")); |
146 |
148 |
} |
} |
147 |
149 |
|
|
|
150 |
|
TEST(viewer_topping_1file_2separate_viewers) |
|
151 |
|
{ |
|
152 |
|
assoc_viewers("*.tar.bz2", "prog1"); |
|
153 |
|
assoc_viewers("*.tar.bz2", "prog2"); |
|
154 |
|
|
|
155 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
156 |
|
|
|
157 |
|
/* Already the top one. */ |
|
158 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog1"); |
|
159 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
160 |
|
|
|
161 |
|
/* Swap the order. */ |
|
162 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
163 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
164 |
|
|
|
165 |
|
/* Swap the order again. */ |
|
166 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
167 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
168 |
|
} |
|
169 |
|
|
|
170 |
|
TEST(viewer_topping_1file_2joined_viewers) |
|
171 |
|
{ |
|
172 |
|
assoc_viewers("*.tar.bz2", "prog1, prog2"); |
|
173 |
|
|
|
174 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
175 |
|
|
|
176 |
|
/* Already the top one. */ |
|
177 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog1"); |
|
178 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
179 |
|
|
|
180 |
|
/* Swap the order. */ |
|
181 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
182 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
183 |
|
|
|
184 |
|
/* Swap the order again. */ |
|
185 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
186 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
187 |
|
} |
|
188 |
|
|
|
189 |
|
TEST(viewer_topping_2files_2joined_viewers) |
|
190 |
|
{ |
|
191 |
|
assoc_viewers("*.tar.bz2,*.zip", "prog1, prog2"); |
|
192 |
|
|
|
193 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
194 |
|
assert_string_equal("prog1", ft_get_viewer("archive.zip")); |
|
195 |
|
|
|
196 |
|
/* Already the top one. */ |
|
197 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog1"); |
|
198 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
199 |
|
assert_string_equal("prog1", ft_get_viewer("archive.zip")); |
|
200 |
|
|
|
201 |
|
/* Swap the order. */ |
|
202 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
203 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
204 |
|
assert_string_equal("prog2", ft_get_viewer("archive.zip")); |
|
205 |
|
|
|
206 |
|
/* Swap the order again. */ |
|
207 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
208 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
209 |
|
assert_string_equal("prog2", ft_get_viewer("archive.zip")); |
|
210 |
|
} |
|
211 |
|
|
|
212 |
|
TEST(viewer_topping_2files_mixed_viewers) |
|
213 |
|
{ |
|
214 |
|
assoc_viewers("*.tar.bz2,*.zip", "prog1, prog2"); |
|
215 |
|
assoc_viewers("*.zip", "prog4"); |
|
216 |
|
assoc_viewers("*.tar.bz2", "prog3"); |
|
217 |
|
assoc_viewers("*", "defprog"); |
|
218 |
|
|
|
219 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
220 |
|
assert_string_equal("prog1", ft_get_viewer("archive.zip")); |
|
221 |
|
|
|
222 |
|
/* Already the top one. */ |
|
223 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog1"); |
|
224 |
|
assert_string_equal("prog1", ft_get_viewer("archive.tar.bz2")); |
|
225 |
|
assert_string_equal("prog1", ft_get_viewer("archive.zip")); |
|
226 |
|
|
|
227 |
|
/* Swap the order. */ |
|
228 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog3"); |
|
229 |
|
assert_string_equal("prog3", ft_get_viewer("archive.tar.bz2")); |
|
230 |
|
assert_string_equal("prog4", ft_get_viewer("archive.zip")); |
|
231 |
|
|
|
232 |
|
/* Swap the order again. */ |
|
233 |
|
ft_move_viewer_to_top("archive.tar.bz2", "prog2"); |
|
234 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
235 |
|
assert_string_equal("prog4", ft_get_viewer("archive.zip")); |
|
236 |
|
} |
|
237 |
|
|
|
238 |
|
TEST(viewer_cycling_1file_overlap_next) |
|
239 |
|
{ |
|
240 |
|
assoc_viewers("{*.png}", "unrelated"); |
|
241 |
|
assoc_viewers("{*.tar.bz2},{*.tar.*},{*.bz2}", "prog,prog2"); |
|
242 |
|
assoc_viewers("{*}", "defprog"); |
|
243 |
|
|
|
244 |
|
assert_string_equal("unrelated", ft_get_viewer("file.png")); |
|
245 |
|
assert_string_equal("prog", ft_get_viewer("archive.tar.bz2")); |
|
246 |
|
|
|
247 |
|
ft_move_viewer_cycle_next("archive.tar.bz2"); |
|
248 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
249 |
|
ft_move_viewer_cycle_next("archive.tar.bz2"); |
|
250 |
|
assert_string_equal("defprog", ft_get_viewer("archive.tar.bz2")); |
|
251 |
|
ft_move_viewer_cycle_next("archive.tar.bz2"); |
|
252 |
|
assert_string_equal("prog", ft_get_viewer("archive.tar.bz2")); |
|
253 |
|
ft_move_viewer_cycle_next("archive.tar.bz2"); |
|
254 |
|
assert_string_equal("prog2", ft_get_viewer("archive.tar.bz2")); |
|
255 |
|
|
|
256 |
|
/* Verifying that nothing unexpected has happened to this file. */ |
|
257 |
|
assert_string_equal("unrelated", ft_get_viewer("file.png")); |
|
258 |
|
} |
|
259 |
|
|
|
260 |
|
TEST(viewer_cycling_1file_overlap_prev) |
|
261 |
|
{ |
|
262 |
|
assoc_viewers("{*.png}", "unrelated"); |
|
263 |
|
assoc_viewers("{*.tar.bz2},{*.tar.*},{*.bz2}", "prog"); |
|
264 |
|
assoc_viewers("{*}", "defprog"); |
|
265 |
|
|
|
266 |
|
assert_string_equal("unrelated", ft_get_viewer("file.png")); |
|
267 |
|
assert_string_equal("prog", ft_get_viewer("archive.tar.bz2")); |
|
268 |
|
|
|
269 |
|
ft_move_viewer_cycle_prev("archive.tar.bz2"); |
|
270 |
|
assert_string_equal("defprog", ft_get_viewer("archive.tar.bz2")); |
|
271 |
|
ft_move_viewer_cycle_prev("archive.tar.bz2"); |
|
272 |
|
assert_string_equal("prog", ft_get_viewer("archive.tar.bz2")); |
|
273 |
|
ft_move_viewer_cycle_prev("archive.tar.bz2"); |
|
274 |
|
assert_string_equal("defprog", ft_get_viewer("archive.tar.bz2")); |
|
275 |
|
|
|
276 |
|
/* Verifying that nothing unexpected has happened to this file. */ |
|
277 |
|
assert_string_equal("unrelated", ft_get_viewer("file.png")); |
|
278 |
|
} |
|
279 |
|
|
|
280 |
|
TEST(viewer_cycling_1file_overlap) |
|
281 |
|
{ |
|
282 |
|
assoc_viewers("{*.mp3}", "prog1"); |
|
283 |
|
assoc_viewers("{*.mp3}", "prog2"); |
|
284 |
|
assoc_viewers("{*}", "defprog"); |
|
285 |
|
|
|
286 |
|
assert_string_equal("prog1", ft_get_viewer("file.mp3")); |
|
287 |
|
|
|
288 |
|
/* Forwards. */ |
|
289 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
290 |
|
assert_string_equal("prog2", ft_get_viewer("file.mp3")); |
|
291 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
292 |
|
assert_string_equal("defprog", ft_get_viewer("file.mp3")); |
|
293 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
294 |
|
assert_string_equal("prog1", ft_get_viewer("file.mp3")); |
|
295 |
|
|
|
296 |
|
/* Backwards. */ |
|
297 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
298 |
|
assert_string_equal("defprog", ft_get_viewer("file.mp3")); |
|
299 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
300 |
|
assert_string_equal("prog2", ft_get_viewer("file.mp3")); |
|
301 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
302 |
|
assert_string_equal("prog1", ft_get_viewer("file.mp3")); |
|
303 |
|
} |
|
304 |
|
|
|
305 |
|
TEST(viewer_reordering_1file_missing_viewers) |
|
306 |
|
{ |
|
307 |
|
ft_init(&name_based_exists); |
|
308 |
|
|
|
309 |
|
assoc_viewers("{*.mp3}", "m1"); |
|
310 |
|
assoc_viewers("{*.mp3}", "p2"); |
|
311 |
|
assoc_viewers("{*.mp3}", "p3"); |
|
312 |
|
|
|
313 |
|
assert_string_equal("p2", ft_get_viewer("file.mp3")); |
|
314 |
|
|
|
315 |
|
/* Forwards. */ |
|
316 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
317 |
|
assert_string_equal("p3", ft_get_viewer("file.mp3")); |
|
318 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
319 |
|
assert_string_equal("p2", ft_get_viewer("file.mp3")); |
|
320 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
321 |
|
assert_string_equal("p3", ft_get_viewer("file.mp3")); |
|
322 |
|
ft_init(NULL); |
|
323 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
324 |
|
assert_string_equal("m1", ft_get_viewer("file.mp3")); |
|
325 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
326 |
|
assert_string_equal("p2", ft_get_viewer("file.mp3")); |
|
327 |
|
|
|
328 |
|
ft_init(&name_based_exists); |
|
329 |
|
|
|
330 |
|
/* Backwards. */ |
|
331 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
332 |
|
assert_string_equal("p3", ft_get_viewer("file.mp3")); |
|
333 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
334 |
|
assert_string_equal("p2", ft_get_viewer("file.mp3")); |
|
335 |
|
ft_init(NULL); |
|
336 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
337 |
|
assert_string_equal("m1", ft_get_viewer("file.mp3")); |
|
338 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
339 |
|
assert_string_equal("p3", ft_get_viewer("file.mp3")); |
|
340 |
|
ft_move_viewer_cycle_prev("file.mp3"); |
|
341 |
|
assert_string_equal("p2", ft_get_viewer("file.mp3")); |
|
342 |
|
|
|
343 |
|
ft_init(&name_based_exists); |
|
344 |
|
|
|
345 |
|
/* To the top. */ |
|
346 |
|
ft_move_viewer_to_top("file.mp3", "p3"); |
|
347 |
|
assert_string_equal("p3", ft_get_viewer("file.mp3")); |
|
348 |
|
ft_init(NULL); |
|
349 |
|
ft_move_viewer_cycle_next("file.mp3"); |
|
350 |
|
assert_string_equal("m1", ft_get_viewer("file.mp3")); |
|
351 |
|
ft_init(&name_based_exists); |
|
352 |
|
assert_string_equal("p2", ft_get_viewer("file.mp3")); |
|
353 |
|
} |
|
354 |
|
|
|
355 |
|
TEST(viewer_reordering_file_with_no_viewers) |
|
356 |
|
{ |
|
357 |
|
assoc_viewers("{*.png}", "unrelated"); |
|
358 |
|
|
|
359 |
|
assert_string_equal("unrelated", ft_get_viewer("file.png")); |
|
360 |
|
|
|
361 |
|
ft_move_viewer_cycle_prev("archive.tar.bz2"); |
|
362 |
|
assert_string_equal(NULL, ft_get_viewer("archive.tar.bz2")); |
|
363 |
|
ft_move_viewer_cycle_next("archive.tar.bz2"); |
|
364 |
|
assert_string_equal(NULL, ft_get_viewer("archive.tar.bz2")); |
|
365 |
|
ft_move_viewer_to_top("archive.tar.bz2", "nope"); |
|
366 |
|
assert_string_equal(NULL, ft_get_viewer("archive.tar.bz2")); |
|
367 |
|
|
|
368 |
|
/* Verifying that nothing unexpected has happened to this file. */ |
|
369 |
|
assert_string_equal("unrelated", ft_get_viewer("file.png")); |
|
370 |
|
} |
|
371 |
|
|
|
372 |
|
static int |
|
373 |
|
name_based_exists(const char name[]) |
|
374 |
|
{ |
|
375 |
|
/* 'p' for "present". */ |
|
376 |
|
return (name[0] == 'p'); |
|
377 |
|
} |
|
378 |
|
|
148 |
379 |
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
149 |
380 |
/* vim: set cinoptions+=t0 filetype=c : */ |
/* vim: set cinoptions+=t0 filetype=c : */ |