aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-09-29 02:36:03 +0200
committerPřemysl Eric Janouch <p@janouch.name>2020-09-29 03:39:13 +0200
commit93172797e1f36c7447e136f11d09c46d6e77d2ef (patch)
tree12ae2bdf5e5d795aa205716ed17e1cd104f5178b
parent1507f2dff9d5a70c8c20bbda88c29e81ff70c211 (diff)
downloadsdn-93172797e1f36c7447e136f11d09c46d6e77d2ef.tar.gz
sdn-93172797e1f36c7447e136f11d09c46d6e77d2ef.tar.xz
sdn-93172797e1f36c7447e136f11d09c46d6e77d2ef.zip
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.
-rw-r--r--sdn.cpp44
1 files changed, 26 insertions, 18 deletions
diff --git a/sdn.cpp b/sdn.cpp
index 0003616..f3af9bf 100644
--- a/sdn.cpp
+++ b/sdn.cpp
@@ -1004,7 +1004,19 @@ fun is_ancestor_dir (const string &ancestor, const string &of) -> bool {
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 ();
while (i != g.levels.rend () && !is_ancestor_dir (i->path, g.cwd)) {
if (i->path == g.cwd) {
@@ -1015,6 +1027,13 @@ fun pop_levels () {
i++;
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 ();
if (!anchor.empty () && g.entries[g.cursor].filename != anchor)
search (to_wide (anchor));
@@ -1047,18 +1066,6 @@ fun absolutize (const string &abs_base, const string &path) -> string {
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.
// HOME and CDPATH handling is ommitted.
fun change_dir (const string &path) {
@@ -1105,11 +1112,12 @@ fun change_dir (const string &path) {
bool same_path = last.path == g.cwd;
reload (same_path);
- if (is_ancestor_dir (last.path, g.cwd)) {
- g.levels.push_back (last);
+ if (!same_path) {
g.offset = g.cursor = 0;
- } else if (!same_path) {
- pop_levels ();
+ if (is_ancestor_dir (last.path, g.cwd))
+ g.levels.push_back (last);
+ else
+ pop_levels (last.path);
}
}
@@ -1653,7 +1661,7 @@ int main (int argc, char *argv[]) {
load_colors ();
g.start_dir = g.cwd = initial_cwd ();
reload (false);
- pop_levels ();
+ pop_levels (g.cwd);
update ();
// Invoking keypad() earlier would make ncurses flush its output buffer,