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 352298f641a4fcc3a62ffe47eb8a1fe1e109ee06

Fix incorrect cursor positioning on file deletion
Specifically on removing elements from custom view with local filter.

Was broken by 14440fe4bb6e40f07748d1bfd1392e2622d6e8b4.
Author: xaizek
Author date (UTC): 2017-06-15 20:14
Committer name: xaizek
Committer date (UTC): 2017-06-15 20:41
Parent(s): 7ee0c47766cdb4efcc6de9e1141bf202f17f8086
Signing key: 99DC5E4DB05F6BE2
Tree: 5c93f940b3d5c04b656bca0fa4075b1d8fa0d263
File Lines added Lines deleted
ChangeLog 3 0
src/filelist.c 12 2
tests/misc/flist_custom.c 48 0
File ChangeLog changed (mode: 100644) (index 5ab4f016a..016050f86)
39 39 Fixed restoring of excluded items from custom view if local filter isn't Fixed restoring of excluded items from custom view if local filter isn't
40 40 empty. Thanks to filterfalse. empty. Thanks to filterfalse.
41 41
42 Fixed incorrect cursor positioning on removing elements from custom view
43 with local filter.
44
42 45 0.8.2 to 0.9-beta 0.8.2 to 0.9-beta
43 46
44 47 Removed -Werror in tests from non-developer builds. Removed -Werror in tests from non-developer builds.
File src/filelist.c changed (mode: 100644) (index 0be60b56c..9cdbbce7d)
... ... populate_custom_view(FileView *view, int reload)
1659 1659 { {
1660 1660 if(custom_list_is_incomplete(view)) if(custom_list_is_incomplete(view))
1661 1661 { {
1662 /* Load initial list of custom entries if it's available. */
1662 char selected_path[PATH_MAX];
1663 get_current_full_path(view, sizeof(selected_path), selected_path);
1664
1665 /* Replacing list of entries invalidates cursor position, so we remember
1666 * previously selected file and try to position at it again. */
1663 1667 replace_dir_entries(view, &view->dir_entry, &view->list_rows, replace_dir_entries(view, &view->dir_entry, &view->list_rows,
1664 1668 view->local_filter.entries, view->local_filter.entry_count); view->local_filter.entries, view->local_filter.entry_count);
1669
1670 (void)set_position_by_path(view, selected_path);
1665 1671 } }
1666 1672
1667 1673 (void)zap_entries(view, view->dir_entry, &view->list_rows, (void)zap_entries(view, view->dir_entry, &view->list_rows,
 
... ... zap_entries(FileView *view, dir_entry_t *entries, int *count, zap_filter filter,
1932 1938 fentry_free(view, &entry[k]); fentry_free(view, &entry[k]);
1933 1939 } }
1934 1940
1935 if(view->list_pos >= i && view->list_pos < i + nremoved)
1941 /* If we're removing file from main list of entries and cursor is right on
1942 * this file, move cursor at position this file would take in resulting
1943 * list. */
1944 if(entries == view->dir_entry && view->list_pos >= i &&
1945 view->list_pos < i + nremoved)
1936 1946 { {
1937 1947 view->list_pos = j; view->list_pos = j;
1938 1948 } }
File tests/misc/flist_custom.c changed (mode: 100644) (index 063e9fad4..8ff0b1897)
... ... TEST(loading_cv_resets_search_results)
718 718 assert_int_equal(0, lwin.matches); assert_int_equal(0, lwin.matches);
719 719 } }
720 720
721 TEST(cursor_is_positioned_close_to_disappeared_file)
722 {
723 make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), SANDBOX_PATH, "", cwd);
724 assert_success(chdir(SANDBOX_PATH));
725 create_file("1");
726 create_file("2");
727 create_file("3");
728 create_file("4");
729 create_file("5");
730 create_file("6");
731
732 filters_view_reset(&lwin);
733
734 flist_custom_start(&lwin, "test");
735 flist_custom_add(&lwin, "1");
736 flist_custom_add(&lwin, "2");
737 flist_custom_add(&lwin, "3");
738 flist_custom_add(&lwin, "4");
739 flist_custom_add(&lwin, "5");
740 flist_custom_add(&lwin, "6");
741 assert_true(flist_custom_finish(&lwin, CV_REGULAR, 0) == 0);
742 assert_int_equal(6, lwin.list_rows);
743
744 local_filter_apply(&lwin, "[4-6]");
745 load_dir_list(&lwin, 1);
746 assert_int_equal(3, lwin.list_rows);
747
748 lwin.list_pos = 2;
749 assert_success(unlink("6"));
750 /* This reloads view zipping removed and filtered-out files. It should try to
751 * stay close to original position. */
752 load_dir_list(&lwin, 1);
753 assert_int_equal(2, lwin.list_rows);
754
755 /* Both 2 and 1 are valid answers, list_pos is automatically corrected. */
756 assert_true(lwin.list_pos == 1 || lwin.list_pos == 2);
757
758 filter_dispose(&lwin.manual_filter);
759 filter_dispose(&lwin.auto_filter);
760
761 assert_success(chdir(SANDBOX_PATH));
762 assert_success(unlink("1"));
763 assert_success(unlink("2"));
764 assert_success(unlink("3"));
765 assert_success(unlink("4"));
766 assert_success(unlink("5"));
767 }
768
721 769 static void static void
722 770 column_line_print(const void *data, int column_id, const char buf[], column_line_print(const void *data, int column_id, const char buf[],
723 771 size_t offset, AlignType align, const char full_column[]) size_t offset, AlignType align, const char full_column[])
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