Allow reversing the sort

This commit is contained in:
Přemysl Eric Janouch 2018-11-02 17:25:10 +01:00
parent f3fffe4b25
commit 232ecffa2d
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 35 additions and 11 deletions

38
sdn.cpp
View File

@ -29,6 +29,7 @@
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <tuple>
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
@ -376,7 +377,7 @@ enum { ALT = 1 << 24, SYM = 1 << 25 }; // Outside the range of Unicode
XX(UP) XX(DOWN) XX(TOP) XX(BOTTOM) XX(PAGE_PREVIOUS) XX(PAGE_NEXT) \ XX(UP) XX(DOWN) XX(TOP) XX(BOTTOM) XX(PAGE_PREVIOUS) XX(PAGE_NEXT) \
XX(SCROLL_UP) XX(SCROLL_DOWN) XX(CHDIR) XX(GO_START) XX(GO_HOME) \ XX(SCROLL_UP) XX(SCROLL_DOWN) XX(CHDIR) XX(GO_START) XX(GO_HOME) \
XX(SEARCH) XX(RENAME) XX(RENAME_PREFILL) \ XX(SEARCH) XX(RENAME) XX(RENAME_PREFILL) \
XX(TOGGLE_FULL) XX(REDRAW) XX(RELOAD) \ XX(TOGGLE_FULL) XX(REVERSE_SORT) XX(REDRAW) XX(RELOAD) \
XX(INPUT_ABORT) XX(INPUT_CONFIRM) XX(INPUT_B_DELETE) XX(INPUT_ABORT) XX(INPUT_CONFIRM) XX(INPUT_B_DELETE)
#define XX(name) ACTION_ ## name, #define XX(name) ACTION_ ## name,
@ -403,6 +404,7 @@ static map<wint_t, action> g_normal_actions {
{'/', ACTION_SEARCH}, {'s', ACTION_SEARCH}, {'/', ACTION_SEARCH}, {'s', ACTION_SEARCH},
{ALT | 'e', ACTION_RENAME_PREFILL}, {'e', ACTION_RENAME}, {ALT | 'e', ACTION_RENAME_PREFILL}, {'e', ACTION_RENAME},
{'t', ACTION_TOGGLE_FULL}, {ALT | 't', ACTION_TOGGLE_FULL}, {'t', ACTION_TOGGLE_FULL}, {ALT | 't', ACTION_TOGGLE_FULL},
{'R', ACTION_REVERSE_SORT},
{CTRL 'L', ACTION_REDRAW}, {'r', ACTION_RELOAD}, {CTRL 'L', ACTION_REDRAW}, {'r', ACTION_RELOAD},
}; };
static map<wint_t, action> g_input_actions { static map<wint_t, action> g_input_actions {
@ -443,12 +445,6 @@ struct entry {
enum { MODES, USER, GROUP, SIZE, MTIME, FILENAME, COLUMNS }; enum { MODES, USER, GROUP, SIZE, MTIME, FILENAME, COLUMNS };
ncstring cols[COLUMNS]; ncstring cols[COLUMNS];
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);
}
}; };
struct level { struct level {
@ -464,6 +460,7 @@ static struct {
int offset, cursor; ///< Scroll offset and cursor position int offset, cursor; ///< Scroll offset and cursor position
bool full_view; ///< Show extended information bool full_view; ///< Show extended information
bool gravity; ///< Entries are shoved to the bottom bool gravity; ///< Entries are shoved to the bottom
bool reverse_sort; ///< Reverse sort
int max_widths[entry::COLUMNS]; ///< Column widths int max_widths[entry::COLUMNS]; ///< Column widths
wstring message; ///< Message for the user wstring message; ///< Message for the user
@ -689,6 +686,16 @@ fun update () {
refresh (); refresh ();
} }
fun operator< (const entry &e1, const entry &e2) -> bool {
auto t1 = make_tuple (e1.filename != "..", !S_ISDIR (e1.info.st_mode));
auto t2 = make_tuple (e2.filename != "..", !S_ISDIR (e2.info.st_mode));
if (t1 != t2)
return t1 < t2;
return g.reverse_sort
? e2.filename < e1.filename
: e1.filename < e2.filename;
}
fun reload () { fun reload () {
g.unames.clear(); g.unames.clear();
while (auto *ent = getpwent ()) g.unames.emplace(ent->pw_uid, ent->pw_name); while (auto *ent = getpwent ()) g.unames.emplace(ent->pw_uid, ent->pw_name);
@ -698,6 +705,11 @@ fun reload () {
while (auto *ent = getgrent ()) g.gnames.emplace(ent->gr_gid, ent->gr_name); while (auto *ent = getgrent ()) g.gnames.emplace(ent->gr_gid, ent->gr_name);
endgrent(); endgrent();
string anchor;
if (!g.entries.empty ())
anchor = g.entries[g.cursor].filename;
auto old_cwd = g.cwd;
auto now = time (NULL); g.now = *localtime (&now); auto now = time (NULL); g.now = *localtime (&now);
char buf[4096]; g.cwd = getcwd (buf, sizeof buf); char buf[4096]; g.cwd = getcwd (buf, sizeof buf);
@ -712,6 +724,11 @@ fun reload () {
sort (begin (g.entries), end (g.entries)); sort (begin (g.entries), end (g.entries));
g.out_of_date = false; g.out_of_date = false;
if (g.cwd == old_cwd && !anchor.empty ()) {
for (size_t i = 0; i < g.entries.size (); i++)
if (g.entries[i].filename == anchor)
g.cursor = i;
}
for (int col = 0; col < entry::COLUMNS; col++) { for (int col = 0; col < entry::COLUMNS; col++) {
auto &longest = g.max_widths[col] = 0; auto &longest = g.max_widths[col] = 0;
for (const auto &entry : g.entries) for (const auto &entry : g.entries)
@ -980,6 +997,10 @@ fun handle (wint_t c) -> bool {
case ACTION_TOGGLE_FULL: case ACTION_TOGGLE_FULL:
g.full_view = !g.full_view; g.full_view = !g.full_view;
break; break;
case ACTION_REVERSE_SORT:
g.reverse_sort = !g.reverse_sort;
reload ();
break;
case ACTION_REDRAW: case ACTION_REDRAW:
clear (); clear ();
break; break;
@ -1244,6 +1265,8 @@ fun load_config () {
g.full_view = tokens.size () > 1 && tokens.at (1) == "1"; g.full_view = tokens.size () > 1 && tokens.at (1) == "1";
else if (tokens.front () == "gravity") else if (tokens.front () == "gravity")
g.gravity = tokens.size () > 1 && tokens.at (1) == "1"; g.gravity = tokens.size () > 1 && tokens.at (1) == "1";
else if (tokens.front () == "reverse-sort")
g.reverse_sort = tokens.size () > 1 && tokens.at (1) == "1";
else if (tokens.front () == "history") else if (tokens.front () == "history")
load_history_level (tokens); load_history_level (tokens);
} }
@ -1256,6 +1279,7 @@ fun save_config () {
write_line (*config, {"full-view", g.full_view ? "1" : "0"}); write_line (*config, {"full-view", g.full_view ? "1" : "0"});
write_line (*config, {"gravity", g.gravity ? "1" : "0"}); write_line (*config, {"gravity", g.gravity ? "1" : "0"});
write_line (*config, {"reverse-sort", g.reverse_sort ? "1" : "0"});
char hostname[256]; char hostname[256];
if (gethostname (hostname, sizeof hostname)) if (gethostname (hostname, sizeof hostname))