Compare commits

...

3 Commits

Author SHA1 Message Date
6e879c9db9
Defer keypad() invocation 2018-10-24 10:23:37 +02:00
45f79abf9c
Load users, groups and current time once per refresh
Avoids plenty of costly syscalls per loaded entry.
2018-10-24 10:23:26 +02:00
1b74b1976a
Update copyright years 2018-10-24 07:45:23 +02:00
2 changed files with 35 additions and 16 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2017, Přemysl Janouch <p@janouch.name>
Copyright (c) 2017 - 2018, Přemysl Janouch <p@janouch.name>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

49
sdn.cpp
View File

@ -1,7 +1,7 @@
//
// sdn: simple directory navigator
//
// Copyright (c) 2017, Přemysl Janouch <p@janouch.name>
// Copyright (c) 2017 - 2018, Přemysl Janouch <p@janouch.name>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted.
@ -319,6 +319,12 @@ static struct {
map<int, chtype> ls_colors; ///< LS_COLORS decoded
map<string, chtype> ls_exts; ///< LS_COLORS file extensions
// Refreshed by reload():
map<uid_t, string> unames; ///< User names by UID
map<gid_t, string> gnames; ///< Group names by GID
struct tm now; ///< Current local time for display
} g;
fun ls_format (const string &filename, const struct stat &info) -> chtype {
@ -384,15 +390,15 @@ fun make_row (const string &filename, const struct stat &info) -> row {
mode += L"+";
r.cols[row::MODES] = apply_attrs (mode, 0);
auto user = to_wstring (info.st_uid);
if (auto u = getpwuid (info.st_uid))
user = to_wide (u->pw_name);
r.cols[row::USER] = apply_attrs (user, 0);
auto usr = g.unames.find (info.st_uid);
r.cols[row::USER] = (usr != g.unames.end ())
? apply_attrs (to_wide (usr->second), 0)
: apply_attrs (to_wstring (info.st_uid), 0);
auto group = to_wstring (info.st_gid);
if (auto g = getgrgid (info.st_gid))
group = to_wide (g->gr_name);
r.cols[row::GROUP] = apply_attrs (group, 0);
auto grp = g.gnames.find (info.st_gid);
r.cols[row::GROUP] = (grp != g.unames.end ())
? apply_attrs (to_wide (grp->second), 0)
: apply_attrs (to_wstring (info.st_gid), 0);
auto size = to_wstring (info.st_size);
if (info.st_size >> 40) size = to_wstring (info.st_size >> 40) + L"T";
@ -401,13 +407,10 @@ fun make_row (const string &filename, const struct stat &info) -> row {
else if (info.st_size >> 10) size = to_wstring (info.st_size >> 10) + L"K";
r.cols[row::SIZE] = apply_attrs (size, 0);
auto now = time (NULL);
auto now_year = localtime (&now)->tm_year;
char buf[32] = "";
auto tm = localtime (&info.st_mtime);
strftime (buf, sizeof buf,
(tm->tm_year == now_year) ? "%b %e %H:%M" : "%b %e %Y", tm);
(tm->tm_year == g.now.tm_year) ? "%b %e %H:%M" : "%b %e %Y", tm);
r.cols[row::MTIME] = apply_attrs (to_wide (buf), 0);
// TODO: show symlink target: check st_mode/DT_*, readlink
@ -463,6 +466,15 @@ fun update () {
}
fun reload () {
g.unames.clear();
while (auto *ent = getpwent ()) g.unames.emplace(ent->pw_uid, ent->pw_name);
endpwent();
g.gnames.clear();
while (auto *ent = getgrent ()) g.gnames.emplace(ent->gr_gid, ent->gr_name);
endgrent();
auto now = time (NULL); g.now = *localtime (&now);
char buf[4096]; g.cwd = getcwd (buf, sizeof buf);
auto dir = opendir (".");
@ -802,8 +814,7 @@ int main (int argc, char *argv[]) {
}
locale::global (locale (""));
if (!initscr () || cbreak () == ERR || noecho () == ERR || nonl () == ERR
|| halfdelay (1) == ERR || keypad (stdscr, TRUE) == ERR) {
if (!initscr () || cbreak () == ERR || noecho () == ERR || nonl () == ERR) {
cerr << "cannot initialize screen" << endl;
return 1;
}
@ -813,6 +824,14 @@ int main (int argc, char *argv[]) {
g.start_dir = g.cwd;
update ();
// Invoking keypad() earlier would make ncurses flush its output buffer,
// which would worsen start-up flickering
if (halfdelay (1) == ERR || keypad (stdscr, TRUE) == ERR) {
endwin ();
cerr << "cannot initialize screen" << endl;
return 1;
}
wint_t c;
while (1) {
inotify_check ();