Compare commits

..

No commits in common. "9a12fd80213c985fc91ee75854918523106377f3" and "e60ffeeb206b177211249e26e2cb113e4e302d79" have entirely different histories.

2 changed files with 26 additions and 50 deletions

View File

@ -52,11 +52,9 @@ To start using this navigator, put the following in your .zshrc:
.... ....
sdn-navigate () { sdn-navigate () {
# ... possibly zle-line-init # ... possibly zle-line-init
while eval "`sdn`"; do eval "`sdn`"
[ -z "$cd" ] || cd "$cd" [ -z "$cd" ] || cd "$cd"
[ -z "$insert" ] || LBUFFER="$LBUFFER$insert " [ -z "$insert" ] || LBUFFER="$LBUFFER$insert "
[ -z "$helper" ] && break
eval "exec </dev/tty; $helper" || break
zle reset-prompt zle reset-prompt
# ... possibly zle-line-finish # ... possibly zle-line-finish
} }
@ -67,22 +65,19 @@ bindkey '\eo' sdn-navigate
bash bash
---- ----
Here we can't reset the prompt from within a `bind -x` handler but there is Here we can't reset the prompt from within a `bind -x` handler but there is
an acceptable workaround that sadly submits a blank line: an acceptable workaround:
.... ....
sdn-navigate () { sdn-navigate () {
SDN_L=$READLINE_LINE SDN_P=$READLINE_POINT SDN_L=$READLINE_LINE SDN_P=$READLINE_POINT
READLINE_LINE= READLINE_LINE=
while eval "`sdn`"; do eval "`sdn`"
[[ -z "$cd" ]] || cd "$cd" [[ -z "$cd" ]] || cd "$cd"
[[ -z "$insert" ]] || { [[ -z "$insert" ]] || {
SDN_L="${SDN_L:0:$SDN_P}$insert ${SDN_L:$SDN_P}" SDN_L="${SDN_L:0:$SDN_P}$insert ${SDN_L:$SDN_P}"
((SDN_P=SDN_P+${#insert}+1)) ((SDN_P=SDN_P+${#insert}+1))
} }
[[ -z "$helper" ]] && break
eval "$helper" || break
done
} }
sdn-restore () { sdn-restore () {
READLINE_LINE=$SDN_L READLINE_POINT=$SDN_P READLINE_LINE=$SDN_L READLINE_POINT=$SDN_P

51
sdn.cpp
View File

@ -504,7 +504,6 @@ static struct {
bool gravity; ///< Entries are shoved to the bottom bool gravity; ///< Entries are shoved to the bottom
bool reverse_sort; ///< Reverse sort bool reverse_sort; ///< Reverse sort
bool show_hidden; ///< Show hidden files bool show_hidden; ///< Show hidden files
bool ext_helpers; ///< Launch helpers externally
int max_widths[entry::COLUMNS]; ///< Column widths int max_widths[entry::COLUMNS]; ///< Column widths
int sort_column = entry::FILENAME; ///< Sorting column int sort_column = entry::FILENAME; ///< Sorting column
int sort_flash_ttl; ///< Sorting column flash TTL int sort_flash_ttl; ///< Sorting column flash TTL
@ -513,7 +512,6 @@ static struct {
int message_ttl; ///< Time to live for the message int message_ttl; ///< Time to live for the message
string chosen; ///< Chosen item for the command line string chosen; ///< Chosen item for the command line
string ext_helper; ///< External helper to run
bool no_chdir; ///< Do not tell the shell to chdir bool no_chdir; ///< Do not tell the shell to chdir
bool quitting; ///< Whether we should quit already bool quitting; ///< Whether we should quit already
@ -786,7 +784,7 @@ fun operator< (const entry &e1, const entry &e2) -> bool {
return a.filename < b.filename; return a.filename < b.filename;
} }
fun reload (bool keep_anchor) { fun reload (const string &old_cwd) {
g.unames.clear(); g.unames.clear();
while (auto *ent = getpwent ()) while (auto *ent = getpwent ())
g.unames.emplace (ent->pw_uid, ent->pw_name); g.unames.emplace (ent->pw_uid, ent->pw_name);
@ -798,8 +796,8 @@ fun reload (bool keep_anchor) {
endgrent(); endgrent();
string anchor; string anchor;
if (keep_anchor && !g.entries.empty ()) if (!g.entries.empty ())
anchor = g.entries.at (g.cursor).filename; anchor = g.entries[g.cursor].filename;
auto now = time (NULL); g.now = *localtime (&now); auto now = time (NULL); g.now = *localtime (&now);
auto dir = opendir ("."); auto dir = opendir (".");
@ -816,7 +814,7 @@ fun reload (bool keep_anchor) {
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 (!anchor.empty ()) { if (g.cwd == old_cwd && !anchor.empty ()) {
for (size_t i = 0; i < g.entries.size (); i++) for (size_t i = 0; i < g.entries.size (); i++)
if (g.entries[i].filename == anchor) if (g.entries[i].filename == anchor)
g.cursor = i; g.cursor = i;
@ -844,20 +842,8 @@ fun show_message (const string &message, int ttl = 30) {
} }
fun run_program (initializer_list<const char*> list, const string &filename) { fun run_program (initializer_list<const char*> list, const string &filename) {
if (g.ext_helpers) {
// XXX: this doesn't try them all out, though it shouldn't make any
// noticeable difference
const char *found = nullptr;
for (auto program : list)
if ((found = program))
break;
g.ext_helper = "/bin/sh -c " +
shell_escape (string (found) + " " + shell_escape (filename));
g.quitting = true;
return;
}
endwin (); endwin ();
switch (pid_t child = fork ()) { switch (pid_t child = fork ()) {
int status; int status;
case -1: case -1:
@ -867,8 +853,8 @@ fun run_program (initializer_list<const char*> list, const string &filename) {
setpgid (0, 0); setpgid (0, 0);
tcsetpgrp (STDOUT_FILENO, getpgid (0)); tcsetpgrp (STDOUT_FILENO, getpgid (0));
for (auto program : list) for (auto pager : list)
if (program) execl ("/bin/sh", "/bin/sh", "-c", (string (program) if (pager) execl ("/bin/sh", "/bin/sh", "-c", (string (pager)
+ " " + shell_escape (filename)).c_str (), NULL); + " " + shell_escape (filename)).c_str (), NULL);
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
default: default:
@ -1103,13 +1089,12 @@ fun change_dir (const string &path) {
auto old_cwd = g.cwd; auto old_cwd = g.cwd;
level last {g.offset, g.cursor, old_cwd, g.entries[g.cursor].filename}; level last {g.offset, g.cursor, old_cwd, g.entries[g.cursor].filename};
g.cwd = full_path; g.cwd = full_path;
bool same_path = old_cwd == g.cwd; reload (old_cwd);
reload (same_path);
if (is_ancestor_dir (last.path, g.cwd)) { if (is_ancestor_dir (last.path, g.cwd)) {
g.levels.push_back (last); g.levels.push_back (last);
g.offset = g.cursor = 0; g.offset = g.cursor = 0;
} else if (!same_path) { } else {
pop_levels (); pop_levels ();
} }
} }
@ -1221,12 +1206,12 @@ fun handle (wint_t c) -> bool {
case ACTION_SORT_LEFT: case ACTION_SORT_LEFT:
g.sort_column = (g.sort_column + entry::COLUMNS - 1) % entry::COLUMNS; g.sort_column = (g.sort_column + entry::COLUMNS - 1) % entry::COLUMNS;
g.sort_flash_ttl = 2; g.sort_flash_ttl = 2;
reload (true); reload (g.cwd);
break; break;
case ACTION_SORT_RIGHT: case ACTION_SORT_RIGHT:
g.sort_column = (g.sort_column + entry::COLUMNS + 1) % entry::COLUMNS; g.sort_column = (g.sort_column + entry::COLUMNS + 1) % entry::COLUMNS;
g.sort_flash_ttl = 2; g.sort_flash_ttl = 2;
reload (true); reload (g.cwd);
break; break;
case ACTION_UP: case ACTION_UP:
@ -1299,7 +1284,7 @@ fun handle (wint_t c) -> bool {
g.editor_on_confirm = [] { g.editor_on_confirm = [] {
auto mb = to_mb (g.editor_line); auto mb = to_mb (g.editor_line);
rename (g.entries[g.cursor].filename.c_str (), mb.c_str ()); rename (g.entries[g.cursor].filename.c_str (), mb.c_str ());
reload (true); reload (g.cwd);
}; };
break; break;
@ -1308,17 +1293,17 @@ fun handle (wint_t c) -> bool {
break; break;
case ACTION_REVERSE_SORT: case ACTION_REVERSE_SORT:
g.reverse_sort = !g.reverse_sort; g.reverse_sort = !g.reverse_sort;
reload (true); reload (g.cwd);
break; break;
case ACTION_SHOW_HIDDEN: case ACTION_SHOW_HIDDEN:
g.show_hidden = !g.show_hidden; g.show_hidden = !g.show_hidden;
reload (true); reload (g.cwd);
break; break;
case ACTION_REDRAW: case ACTION_REDRAW:
clear (); clear ();
break; break;
case ACTION_RELOAD: case ACTION_RELOAD:
reload (true); reload (g.cwd);
break; break;
default: default:
if (c != KEY (RESIZE) && c != WEOF) if (c != KEY (RESIZE) && c != WEOF)
@ -1584,8 +1569,6 @@ fun load_config () {
g.reverse_sort = tokens.at (1) == "1"; g.reverse_sort = tokens.at (1) == "1";
else if (tokens.front () == "show-hidden" && tokens.size () > 1) else if (tokens.front () == "show-hidden" && tokens.size () > 1)
g.show_hidden = tokens.at (1) == "1"; g.show_hidden = tokens.at (1) == "1";
else if (tokens.front () == "ext-helpers" && tokens.size () > 1)
g.ext_helpers = tokens.at (1) == "1";
else if (tokens.front () == "sort-column" && tokens.size () > 1) else if (tokens.front () == "sort-column" && tokens.size () > 1)
g.sort_column = stoi (tokens.at (1)); g.sort_column = stoi (tokens.at (1));
else if (tokens.front () == "history") else if (tokens.front () == "history")
@ -1602,7 +1585,6 @@ fun save_config () {
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"}); write_line (*config, {"reverse-sort", g.reverse_sort ? "1" : "0"});
write_line (*config, {"show-hidden", g.show_hidden ? "1" : "0"}); write_line (*config, {"show-hidden", g.show_hidden ? "1" : "0"});
write_line (*config, {"ext-helpers", g.ext_helpers ? "1" : "0"});
write_line (*config, {"sort-column", to_string (g.sort_column)}); write_line (*config, {"sort-column", to_string (g.sort_column)});
@ -1653,7 +1635,7 @@ int main (int argc, char *argv[]) {
load_colors (); load_colors ();
g.start_dir = g.cwd = initial_cwd (); g.start_dir = g.cwd = initial_cwd ();
reload (false); reload (g.cwd);
pop_levels (); pop_levels ();
update (); update ();
@ -1691,6 +1673,5 @@ int main (int argc, char *argv[]) {
cout << "local cd=" << endl; cout << "local cd=" << endl;
cout << "local insert=" << shell_escape (g.chosen) << endl; cout << "local insert=" << shell_escape (g.chosen) << endl;
cout << "local helper=" << shell_escape (g.ext_helper) << endl;
return 0; return 0;
} }