summaryrefslogtreecommitdiff
path: root/sdn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sdn.cpp')
-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,