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 cc97740ad291d48caae8bc3989493514b3dad8ad

Avoid views scrolling unnecessarily
That happened in response to file-system changes that add or remove
files before the first visible line.

Thanks to justpretending2.

Closes <https://github.com/vifm/vifm/issues/1027>.
Author: xaizek
Author date (UTC): 2026-10-04 13:09
Committer name: xaizek
Committer date (UTC): 2026-10-17 15:58
Parent(s): 8283029e356d9b90f2235cb463f5dd14f7312171
Signing key: 99DC5E4DB05F6BE2
Tree: 54dfa65685c63cf7bcf8ed264cfbcf6f4b52a1fe
File Lines added Lines deleted
ChangeLog 4 0
src/filelist.c 6 0
tests/misc/flist_reload.c 19 0
File ChangeLog changed (mode: 100644) (index db6be36a4..ff5255a56)
162 162
163 163 Slightly improve documentation of "columncount:" in 'lsoptions'. Slightly improve documentation of "columncount:" in 'lsoptions'.
164 164
165 Avoid views scrolling unnecessarily in response to file-system changes
166 that add or remove files before the first visible line. Thanks to
167 justpretending2.
168
165 169 Fixed 'trashdir' with "%r" on BSD-like systems (those with getmntinfo() Fixed 'trashdir' with "%r" on BSD-like systems (those with getmntinfo()
166 170 instead of getmntent() API). The regression was apparently introduced in instead of getmntent() API). The regression was apparently introduced in
167 171 v0.9.1-beta. Thanks to sublimal. v0.9.1-beta. Thanks to sublimal.
File src/filelist.c changed (mode: 100644) (index cd327efa2..806c2540b)
... ... merge_lists(view_t *view, dir_entry_t *entries, int len)
2448 2448 int i; int i;
2449 2449 int closest_dist; int closest_dist;
2450 2450 const int prev_pos = view->list_pos; const int prev_pos = view->list_pos;
2451 const int top_delta = view->list_pos - view->top_line;
2451 2452 trie_t *prev_names = trie_create(/*free_func=*/NULL); trie_t *prev_names = trie_create(/*free_func=*/NULL);
2452 2453
2453 2454 for(i = 0; i < len; ++i) for(i = 0; i < len; ++i)
 
... ... merge_lists(view_t *view, dir_entry_t *entries, int len)
2480 2481 closest_dist = correct_pos(view, i, dist, closest_dist); closest_dist = correct_pos(view, i, dist, closest_dist);
2481 2482 } }
2482 2483
2484 /* When possible, preserve relative placement of the current entry in the
2485 * view. Drawing code should handle out-of-range values (e.g., negative ones)
2486 * fine. */
2487 view->top_line = view->list_pos - top_delta;
2488
2483 2489 trie_free(prev_names); trie_free(prev_names);
2484 2490 } }
2485 2491
File tests/misc/flist_reload.c changed (mode: 100644) (index 5b721653f..0eb304ea0)
... ... TEST(selection_is_preserved)
95 95 assert_int_equal(2, view->selected_files); assert_int_equal(2, view->selected_files);
96 96 } }
97 97
98 TEST(top_line_is_not_shifted_unnecessarily)
99 {
100 view->window_rows = 4;
101 view->top_line = 2;
102 view->list_pos = 3;
103 remove_dir("0");
104 remove_dir("1");
105
106 assert_string_equal("2", view->dir_entry[view->top_line].name);
107 assert_string_equal("3", view->dir_entry[view->list_pos].name);
108
109 populate_dir_list(view, /*reload=*/1);
110
111 assert_int_equal(0, view->top_line);
112 assert_int_equal(1, view->list_pos);
113 assert_string_equal("2", view->dir_entry[view->top_line].name);
114 assert_string_equal("3", view->dir_entry[view->list_pos].name);
115 }
116
98 117 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
99 118 /* vim: set cinoptions+=t0 filetype=c : */ /* vim: set cinoptions+=t0 filetype=c : */
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