Compare commits

...

3 Commits

Author SHA1 Message Date
Přemysl Eric Janouch f3fffe4b25
Add an action to quit without chdir
Also fixed ACTION_CHOOSE_FULL to quote properly.
2018-11-02 15:50:58 +01:00
Přemysl Eric Janouch 77313663a3
Update README 2018-11-02 15:40:56 +01:00
Přemysl Eric Janouch 5f2eaa88e0
Create the config directory if needed 2018-11-02 15:37:56 +01:00
2 changed files with 19 additions and 16 deletions

View File

@ -11,8 +11,8 @@ commands. It enables you to:
can be simply forwarded if it is to be edited. What's more, it will always can be simply forwarded if it is to be edited. What's more, it will always
be obvious whether the navigator is running. be obvious whether the navigator is running.
Development has just started and the only supported platform is Linux. The only supported platform is Linux. I wanted to try a different, simpler
I wanted to try a different, simpler approach here. approach here, and the end result is very friendly to tinkering.
Building Building
-------- --------

31
sdn.cpp
View File

@ -38,6 +38,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <grp.h> #include <grp.h>
#include <libgen.h>
#include <sys/inotify.h> #include <sys/inotify.h>
#include <sys/xattr.h> #include <sys/xattr.h>
@ -252,9 +253,11 @@ fun xdg_config_find (const string &suffix) -> unique_ptr<ifstream> {
fun xdg_config_write (const string &suffix) -> unique_ptr<fstream> { fun xdg_config_write (const string &suffix) -> unique_ptr<fstream> {
auto dir = xdg_config_home (); auto dir = xdg_config_home ();
if (dir[0] == '/') { if (dir[0] == '/') {
// TODO: try to create the end directory auto path = dir + "/" PROJECT_NAME "/" + suffix;
if (fstream fs {dir + "/" PROJECT_NAME "/" + suffix, if (!fork ())
fstream::in | fstream::out | fstream::trunc}) _exit (-execlp ("mkdir", "mkdir", "-p",
dirname (strdup (path.c_str ())), NULL));
if (fstream fs {path, fstream::in | fstream::out | fstream::trunc})
return make_unique<fstream> (move (fs)); return make_unique<fstream> (move (fs));
} }
return nullptr; return nullptr;
@ -368,7 +371,8 @@ enum { ALT = 1 << 24, SYM = 1 << 25 }; // Outside the range of Unicode
#define KEY(name) (SYM | KEY_ ## name) #define KEY(name) (SYM | KEY_ ## name)
#define CTRL 31 & #define CTRL 31 &
#define ACTIONS(XX) XX(NONE) XX(CHOOSE) XX(CHOOSE_FULL) XX(HELP) XX(QUIT) \ #define ACTIONS(XX) XX(NONE) XX(HELP) XX(QUIT) XX(QUIT_NO_CHDIR) \
XX(CHOOSE) XX(CHOOSE_FULL) \
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) \
@ -386,8 +390,9 @@ static const char *g_action_names[] = {ACTIONS(XX)};
static map<wint_t, action> g_normal_actions { static map<wint_t, action> g_normal_actions {
{ALT | '\r', ACTION_CHOOSE_FULL}, {ALT | KEY (ENTER), ACTION_CHOOSE_FULL}, {ALT | '\r', ACTION_CHOOSE_FULL}, {ALT | KEY (ENTER), ACTION_CHOOSE_FULL},
{'\r', ACTION_CHOOSE}, {KEY (ENTER), ACTION_CHOOSE}, {'h', ACTION_HELP}, {'\r', ACTION_CHOOSE}, {KEY (ENTER), ACTION_CHOOSE}, {'h', ACTION_HELP},
{'q', ACTION_QUIT}, {ALT | 'q', ACTION_QUIT_NO_CHDIR},
// M-o ought to be the same shortcut the navigator is launched with // M-o ought to be the same shortcut the navigator is launched with
{ALT | 'o', ACTION_QUIT}, {'q', ACTION_QUIT}, {ALT | 'o', ACTION_QUIT},
{'k', ACTION_UP}, {CTRL 'p', ACTION_UP}, {KEY (UP), ACTION_UP}, {'k', ACTION_UP}, {CTRL 'p', ACTION_UP}, {KEY (UP), ACTION_UP},
{'j', ACTION_DOWN}, {CTRL 'n', ACTION_DOWN}, {KEY (DOWN), ACTION_DOWN}, {'j', ACTION_DOWN}, {CTRL 'n', ACTION_DOWN}, {KEY (DOWN), ACTION_DOWN},
{'g', ACTION_TOP}, {ALT | '<', ACTION_TOP}, {KEY (HOME), ACTION_TOP}, {'g', ACTION_TOP}, {ALT | '<', ACTION_TOP}, {KEY (HOME), ACTION_TOP},
@ -465,7 +470,7 @@ 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
bool chosen_full; ///< Use the full path bool no_chdir; ///< Do not tell the shell to chdir
int inotify_fd, inotify_wd = -1; ///< File watch int inotify_fd, inotify_wd = -1; ///< File watch
bool out_of_date; ///< Entries may be out of date bool out_of_date; ///< Entries may be out of date
@ -896,8 +901,8 @@ fun handle (wint_t c) -> bool {
auto i = g_normal_actions.find (c); auto i = g_normal_actions.find (c);
switch (i == g_normal_actions.end () ? ACTION_NONE : i->second) { switch (i == g_normal_actions.end () ? ACTION_NONE : i->second) {
case ACTION_CHOOSE_FULL: case ACTION_CHOOSE_FULL:
g.chosen_full = true; g.chosen = g.cwd + "/" + current.filename;
g.chosen = current.filename; g.no_chdir = true;
return false; return false;
case ACTION_CHOOSE: case ACTION_CHOOSE:
if (choose (current)) if (choose (current))
@ -906,6 +911,9 @@ fun handle (wint_t c) -> bool {
case ACTION_HELP: case ACTION_HELP:
show_help (); show_help ();
return true; return true;
case ACTION_QUIT_NO_CHDIR:
g.no_chdir = true;
return false;
case ACTION_QUIT: case ACTION_QUIT:
return false; return false;
@ -1326,12 +1334,7 @@ int main (int argc, char *argv[]) {
// We can't portably create a standard stream from an FD, so modify the FD // We can't portably create a standard stream from an FD, so modify the FD
dup2 (output_fd, STDOUT_FILENO); dup2 (output_fd, STDOUT_FILENO);
if (g.chosen_full) { if (g.cwd != g.start_dir && !g.no_chdir)
auto full_path = g.cwd + "/" + g.chosen;
cout << "local insert=" << shell_escape (full_path) << endl;
return 0;
}
if (g.cwd != g.start_dir)
cout << "local cd=" << shell_escape (g.cwd) << endl; cout << "local cd=" << shell_escape (g.cwd) << endl;
if (!g.chosen.empty ()) if (!g.chosen.empty ())
cout << "local insert=" << shell_escape (g.chosen) << endl; cout << "local insert=" << shell_escape (g.chosen) << endl;