summaryrefslogtreecommitdiff
path: root/sdn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sdn.cpp')
-rw-r--r--sdn.cpp129
1 files changed, 63 insertions, 66 deletions
diff --git a/sdn.cpp b/sdn.cpp
index adafc54..568fffc 100644
--- a/sdn.cpp
+++ b/sdn.cpp
@@ -71,6 +71,46 @@ fun to_mb (const wstring &wide) -> string {
return mb;
}
+fun prefix_length (const wstring &in, const wstring &of) -> int {
+ int score = 0;
+ for (size_t i = 0; i < of.size () && in.size () >= i && in[i] == of[i]; i++)
+ score++;
+ return score;
+}
+
+fun shell_escape (const string &v) -> string {
+ string result;
+ for (auto c : v)
+ if (c == '\'')
+ result += "'\\''";
+ else
+ result += c;
+ return "'" + result + "'";
+}
+
+fun decode_type (mode_t m) -> wchar_t {
+ if (S_ISDIR (m)) return L'd'; if (S_ISBLK (m)) return L'b';
+ if (S_ISCHR (m)) return L'c'; if (S_ISLNK (m)) return L'l';
+ if (S_ISFIFO (m)) return L'p'; if (S_ISSOCK (m)) return L's';
+ return L'-';
+}
+
+/// Return the modes of a file in the usual stat/ls format
+fun decode_mode (mode_t m) -> wstring {
+ return { decode_type (m),
+ L"r-"[!(m & S_IRUSR)],
+ L"w-"[!(m & S_IWUSR)],
+ ((m & S_ISUID) ? L"sS" : L"x-")[!(m & S_IXUSR)],
+ L"r-"[!(m & S_IRGRP)],
+ L"w-"[!(m & S_IWGRP)],
+ ((m & S_ISGID) ? L"sS" : L"x-")[!(m & S_IXGRP)],
+ L"r-"[!(m & S_IROTH)],
+ L"w-"[!(m & S_IWOTH)],
+ ((m & S_ISVTX) ? L"tT" : L"x-")[!(m & S_IXOTH)],
+ };
+}
+
+// XXX: maybe we should try to remove this function
fun print (const wstring &wide, int limit) -> int {
int total_width = 0;
for (wchar_t w : wide) {
@@ -90,23 +130,6 @@ fun print (const wstring &wide, int limit) -> int {
return total_width;
}
-fun prefix (const wstring &in, const wstring &of) -> int {
- int score = 0;
- for (size_t i = 0; i < of.size () && in.size () >= i && in[i] == of[i]; i++)
- score++;
- return score;
-}
-
-fun shell_escape (const string &v) -> string {
- string result;
- for (auto c : v)
- if (c == '\'')
- result += "'\\''";
- else
- result += c;
- return "'" + result + "'";
-}
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
using ncstring = basic_string<cchar_t>;
@@ -141,71 +164,44 @@ fun print_nc (const ncstring &nc, int limit) -> int {
#define CTRL 31 &
struct entry {
- string filename;
- struct stat info;
- bool operator< (const entry &other) {
+ string filename; struct stat info;
+ auto operator< (const entry &other) -> bool {
auto a = S_ISDIR (info.st_mode);
auto b = S_ISDIR (other.info.st_mode);
return (a && !b) || (a == b && filename < other.filename);
}
};
-// Between std and ncurses, make at least the globals stand out
static struct {
- string cwd;
- vector<entry> entries;
- int offset, cursor;
- string chosen;
- bool chosen_full;
- int inotify_fd, inotify_wd = -1;
- bool out_of_date;
-
- bool full_view;
-
- wchar_t editor;
- wstring editor_line;
-} g;
+ string cwd; // Current working directory
+ vector<entry> entries; // Current directory entries
+ int offset, cursor; // Scroll offset and cursor position
+ bool full_view; // Whether to show extended information
-fun inline visible_lines () -> int { return max (0, LINES - 2); }
+ string chosen; // Chosen item for the command line
+ bool chosen_full; // Use the full path
-fun make_mode (mode_t m) -> wstring {
- auto type = L'-';
- if (S_ISDIR (m)) type = L'd';
- if (S_ISBLK (m)) type = L'b';
- if (S_ISCHR (m)) type = L'c';
- if (S_ISLNK (m)) type = L'l';
- if (S_ISFIFO (m)) type = L'p';
- if (S_ISSOCK (m)) type = L's';
-
- wstring mode = {type};
- mode += L"r-"[!(m & S_IRUSR)];
- mode += L"w-"[!(m & S_IWUSR)];
- mode += ((m & S_ISUID) ? L"sS" : L"x-")[!(m & S_IXUSR)];
- mode += L"r-"[!(m & S_IRGRP)];
- mode += L"w-"[!(m & S_IWGRP)];
- mode += ((m & S_ISGID) ? L"sS" : L"x-")[!(m & S_IXGRP)];
- mode += L"r-"[!(m & S_IROTH)];
- mode += L"w-"[!(m & S_IWOTH)];
- mode += ((m & S_ISVTX) ? L"tT" : L"x-")[!(m & S_IXOTH)];
- return mode;
-}
+ int inotify_fd, inotify_wd = -1; // File watch
+ bool out_of_date; // Entries may be out of date
+
+ wchar_t editor; // Prompt character for editing
+ wstring editor_line; // Current user input
+} g;
fun make_row (const entry &entry) -> vector<ncstring> {
vector<ncstring> result;
const auto &info = entry.info;
- result.push_back (apply_attrs (make_mode (info.st_mode), 0));
+ result.push_back (apply_attrs (decode_mode (info.st_mode), 0));
- if (auto u = getpwuid (info.st_uid)) {
+ if (auto u = getpwuid (info.st_uid))
result.push_back (apply_attrs (to_wide (u->pw_name), 0));
- } else {
+ else
result.push_back (apply_attrs (to_wstring (info.st_uid), 0));
- }
- if (auto g = getgrgid (info.st_gid)) {
+ if (auto g = getgrgid (info.st_gid))
result.push_back (apply_attrs (to_wide (g->gr_name), 0));
- } else {
+ else
result.push_back (apply_attrs (to_wstring (info.st_gid), 0));
- }
// TODO: human-readable
result.push_back (apply_attrs (to_wstring (info.st_size), 0));
@@ -224,6 +220,8 @@ fun make_row (const entry &entry) -> vector<ncstring> {
return result;
}
+fun inline visible_lines () -> int { return max (0, LINES - 2); }
+
fun update () {
erase ();
@@ -267,8 +265,7 @@ fun update () {
}
fun reload () {
- char buf[4096];
- g.cwd = getcwd (buf, sizeof buf);
+ char buf[4096]; g.cwd = getcwd (buf, sizeof buf);
auto dir = opendir (".");
g.entries.clear ();
@@ -300,7 +297,7 @@ fun search (const wstring &needle) {
int best = g.cursor, best_n = 0;
for (int i = 0; i < int (g.entries.size ()); i++) {
auto o = (i + g.cursor) % g.entries.size ();
- int n = prefix (to_wide (g.entries[o].filename), needle);
+ int n = prefix_length (to_wide (g.entries[o].filename), needle);
if (n > best_n) {
best = o;
best_n = n;