summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-10-02 16:31:36 +0200
committerPřemysl Eric Janouch <p@janouch.name>2020-10-02 16:35:12 +0200
commitcf80a155017c2eecf506ac155c98aed5e962b4a0 (patch)
treed9e3b8cb56e28952768df05d7937e317d64fcf17
parent2d6d0582a13c8efff113837851b496e9b39e7b23 (diff)
downloadsdn-cf80a155017c2eecf506ac155c98aed5e962b4a0.tar.gz
sdn-cf80a155017c2eecf506ac155c98aed5e962b4a0.tar.xz
sdn-cf80a155017c2eecf506ac155c98aed5e962b4a0.zip
Survive a removed CWD, as well as an empty root
All the omitted error checking sometimes sucks a lot, and I need to include it later anyway.
-rw-r--r--sdn.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/sdn.cpp b/sdn.cpp
index 9073025..5549beb 100644
--- a/sdn.cpp
+++ b/sdn.cpp
@@ -791,6 +791,11 @@ fun operator< (const entry &e1, const entry &e2) -> bool {
return a.filename < b.filename;
}
+fun at_cursor () -> const entry & {
+ static entry invalid;
+ return g.cursor >= int (g.entries.size ()) ? invalid : g.entries[g.cursor];
+}
+
fun reload (bool keep_anchor) {
g.unames.clear();
while (auto *ent = getpwent ())
@@ -803,8 +808,8 @@ fun reload (bool keep_anchor) {
endgrent();
string anchor;
- if (keep_anchor && !g.entries.empty ())
- anchor = g.entries.at (g.cursor).filename;
+ if (keep_anchor)
+ anchor = at_cursor ().filename;
auto now = time (NULL); g.now = *localtime (&now);
auto dir = opendir (".");
@@ -832,8 +837,8 @@ fun reload (bool keep_anchor) {
longest = max (longest, compute_width (entry.cols[col]));
}
- g.cursor = min (g.cursor, int (g.entries.size ()) - 1);
- g.offset = min (g.offset, int (g.entries.size ()) - 1);
+ g.cursor = max (0, min (g.cursor, int (g.entries.size ()) - 1));
+ g.offset = max (0, min (g.offset, int (g.entries.size ()) - 1));
if (g.inotify_wd != -1)
inotify_rm_watch (g.inotify_fd, g.inotify_wd);
@@ -986,16 +991,16 @@ fun search (const wstring &needle) {
}
fun fix_cursor_and_offset () {
- g.cursor = max (g.cursor, 0);
g.cursor = min (g.cursor, int (g.entries.size ()) - 1);
+ g.cursor = max (g.cursor, 0);
// Decrease the offset when more items can suddenly fit
int pushable = visible_lines () - (int (g.entries.size ()) - g.offset);
g.offset -= max (pushable, 0);
// Make sure the cursor is visible
- g.offset = max (g.offset, 0);
g.offset = min (g.offset, int (g.entries.size ()) - 1);
+ g.offset = max (g.offset, 0);
if (g.offset > g.cursor)
g.offset = g.cursor;
@@ -1040,7 +1045,7 @@ fun pop_levels (const string& old_cwd) {
}
fix_cursor_and_offset ();
- if (!anchor.empty () && g.entries[g.cursor].filename != anchor)
+ if (!anchor.empty () && at_cursor ().filename != anchor)
search (to_wide (anchor));
}
@@ -1112,7 +1117,7 @@ fun change_dir (const string &path) {
return;
}
- level last {g.offset, g.cursor, g.cwd, g.entries[g.cursor].filename};
+ level last {g.offset, g.cursor, g.cwd, at_cursor ().filename};
g.cwd = full_path;
bool same_path = last.path == g.cwd;
reload (same_path);
@@ -1128,8 +1133,11 @@ fun change_dir (const string &path) {
// Roughly follows the POSIX description of the PWD environment variable
fun initial_cwd () -> string {
- char cwd[4096] = ""; getcwd (cwd, sizeof cwd);
- const char *pwd = getenv ("PWD");
+ char cwd[4096] = ""; const char *pwd = getenv ("PWD");
+ if (!getcwd (cwd, sizeof cwd)) {
+ show_message (strerror (errno));
+ return pwd;
+ }
if (!pwd || pwd[0] != '/' || strlen (pwd) >= PATH_MAX)
return cwd;
@@ -1198,7 +1206,7 @@ fun handle (wint_t c) -> bool {
c = WEOF;
}
- const auto &current = g.entries[g.cursor];
+ const auto &current = at_cursor ();
bool is_directory =
S_ISDIR (current.info.st_mode) ||
S_ISDIR (current.target_info.st_mode);
@@ -1300,7 +1308,7 @@ fun handle (wint_t c) -> bool {
search (g.editor_line);
};
g.editor_on_confirm = [] {
- choose (g.entries[g.cursor]);
+ choose (at_cursor ());
};
break;
case ACTION_RENAME_PREFILL:
@@ -1310,7 +1318,7 @@ fun handle (wint_t c) -> bool {
g.editor = L"rename";
g.editor_on_confirm = [] {
auto mb = to_mb (g.editor_line);
- rename (g.entries[g.cursor].filename.c_str (), mb.c_str ());
+ rename (at_cursor ().filename.c_str (), mb.c_str ());
reload (true);
};
break;
@@ -1642,7 +1650,7 @@ fun save_config () {
to_string (i->offset), to_string (i->cursor), i->filename});
write_line (*config, {"history", hostname, ppid, g.cwd,
to_string (g.offset), to_string (g.cursor),
- g.entries[g.cursor].filename});
+ at_cursor ().filename});
}
int main (int argc, char *argv[]) {