Set cursor to child when going to parent dir
That is, if it's missing from our history. This makes for a more consistent experience when traversing the filesystem. Arguably, it's only good for when 'h' is bound to the 'parent' action. Also make sure that the offset and cursor are reset when the path is changed.
This commit is contained in:
parent
1507f2dff9
commit
93172797e1
44
sdn.cpp
44
sdn.cpp
|
@ -1004,7 +1004,19 @@ fun is_ancestor_dir (const string &ancestor, const string &of) -> bool {
|
||||||
return of[ancestor.length ()] == '/' || (ancestor == "/" && ancestor != of);
|
return of[ancestor.length ()] == '/' || (ancestor == "/" && ancestor != of);
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pop_levels () {
|
/// If `path` is equal to the `current` directory, or lies underneath it,
|
||||||
|
/// return it as a relative path
|
||||||
|
fun relativize (string current, const string &path) -> string {
|
||||||
|
if (current == path)
|
||||||
|
return ".";
|
||||||
|
if (current.back () != '/')
|
||||||
|
current += '/';
|
||||||
|
if (!strncmp (current.c_str (), path.c_str (), current.length ()))
|
||||||
|
return path.substr (current.length ());
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pop_levels (const string& old_cwd) {
|
||||||
string anchor; auto i = g.levels.rbegin ();
|
string anchor; auto i = g.levels.rbegin ();
|
||||||
while (i != g.levels.rend () && !is_ancestor_dir (i->path, g.cwd)) {
|
while (i != g.levels.rend () && !is_ancestor_dir (i->path, g.cwd)) {
|
||||||
if (i->path == g.cwd) {
|
if (i->path == g.cwd) {
|
||||||
|
@ -1015,6 +1027,13 @@ fun pop_levels () {
|
||||||
i++;
|
i++;
|
||||||
g.levels.pop_back ();
|
g.levels.pop_back ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't pick up bullshit from foreign history entries, especially for /
|
||||||
|
if (is_ancestor_dir (g.cwd, old_cwd)) {
|
||||||
|
auto subpath = relativize (g.cwd, old_cwd);
|
||||||
|
anchor = subpath.substr (0, subpath.find ('/'));
|
||||||
|
}
|
||||||
|
|
||||||
fix_cursor_and_offset ();
|
fix_cursor_and_offset ();
|
||||||
if (!anchor.empty () && g.entries[g.cursor].filename != anchor)
|
if (!anchor.empty () && g.entries[g.cursor].filename != anchor)
|
||||||
search (to_wide (anchor));
|
search (to_wide (anchor));
|
||||||
|
@ -1047,18 +1066,6 @@ fun absolutize (const string &abs_base, const string &path) -> string {
|
||||||
return abs_base + "/" + path;
|
return abs_base + "/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `path` is equal to the `current` directory, or lies underneath it,
|
|
||||||
/// return it as a relative path
|
|
||||||
fun relativize (string current, const string &path) -> string {
|
|
||||||
if (current == path)
|
|
||||||
return ".";
|
|
||||||
if (current.back () != '/')
|
|
||||||
current += '/';
|
|
||||||
if (!strncmp (current.c_str (), path.c_str (), current.length ()))
|
|
||||||
return path.substr (current.length ());
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Roughly follows the POSIX description of `cd -L` because of symlinks.
|
// Roughly follows the POSIX description of `cd -L` because of symlinks.
|
||||||
// HOME and CDPATH handling is ommitted.
|
// HOME and CDPATH handling is ommitted.
|
||||||
fun change_dir (const string &path) {
|
fun change_dir (const string &path) {
|
||||||
|
@ -1105,11 +1112,12 @@ fun change_dir (const string &path) {
|
||||||
bool same_path = last.path == g.cwd;
|
bool same_path = last.path == g.cwd;
|
||||||
reload (same_path);
|
reload (same_path);
|
||||||
|
|
||||||
if (is_ancestor_dir (last.path, g.cwd)) {
|
if (!same_path) {
|
||||||
g.levels.push_back (last);
|
|
||||||
g.offset = g.cursor = 0;
|
g.offset = g.cursor = 0;
|
||||||
} else if (!same_path) {
|
if (is_ancestor_dir (last.path, g.cwd))
|
||||||
pop_levels ();
|
g.levels.push_back (last);
|
||||||
|
else
|
||||||
|
pop_levels (last.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1653,7 +1661,7 @@ int main (int argc, char *argv[]) {
|
||||||
load_colors ();
|
load_colors ();
|
||||||
g.start_dir = g.cwd = initial_cwd ();
|
g.start_dir = g.cwd = initial_cwd ();
|
||||||
reload (false);
|
reload (false);
|
||||||
pop_levels ();
|
pop_levels (g.cwd);
|
||||||
update ();
|
update ();
|
||||||
|
|
||||||
// Invoking keypad() earlier would make ncurses flush its output buffer,
|
// Invoking keypad() earlier would make ncurses flush its output buffer,
|
||||||
|
|
Loading…
Reference in New Issue