summaryrefslogtreecommitdiff
path: root/sdn.cpp
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-09-28 01:13:06 +0200
committerPřemysl Eric Janouch <p@janouch.name>2020-09-28 01:45:56 +0200
commit5759df156b0314a4bc8a87ac7a1c8c909a3275d4 (patch)
tree184414bcfbdd6fe562a81d349d39f0ed848869ea /sdn.cpp
parent91df92f49a82d082c864274e0d75858876833340 (diff)
downloadsdn-5759df156b0314a4bc8a87ac7a1c8c909a3275d4.tar.gz
sdn-5759df156b0314a4bc8a87ac7a1c8c909a3275d4.tar.xz
sdn-5759df156b0314a4bc8a87ac7a1c8c909a3275d4.zip
Support tilde expansion in the "chdir" action
The tilde may be escaped, and this first escape may be escaped as well, so all paths should be expressable. All will just work(TM) for those who need it, and those who start filenames with backslashes are begging to have their foot shot. It appears that even Shift JIS, Big5, GB 18030, and GBK are compatible with Unix paths, meaning they don't redefine the slash (0x2F), so I'm okay with my direct multibyte string handling in unknown locales. Legacy stuff smells.
Diffstat (limited to 'sdn.cpp')
-rw-r--r--sdn.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/sdn.cpp b/sdn.cpp
index f7b19b5..4d243e2 100644
--- a/sdn.cpp
+++ b/sdn.cpp
@@ -113,6 +113,28 @@ fun split (const string &s, const string &sep) -> vector<string> {
vector<string> result; split (s, sep, result); return result;
}
+fun untilde (const string &path) -> string {
+ if (path.empty ())
+ return path;
+
+ string tail = path.substr (1);
+ if (path[0] == '\\')
+ return tail;
+ if (path[1] != '~')
+ return path;
+
+ // If there is something between the ~ and the first / (or the EOS)
+ if (size_t until_slash = tail.find ('/')) {
+ if (const auto *pw = getpwnam (tail.substr (0, until_slash).c_str ()))
+ return pw->pw_dir + tail.substr (until_slash);
+ } else if (const auto *home = getenv ("HOME")) {
+ return home + tail;
+ } else if (const auto *pw = getpwuid (getuid ())) {
+ return pw->pw_dir + tail;
+ }
+ return path;
+}
+
fun needs_shell_quoting (const string &v) -> bool {
// IEEE Std 1003.1 sh + the exclamation mark because of csh/bash
// history expansion, implicitly also the NUL character
@@ -1223,7 +1245,7 @@ fun handle (wint_t c) -> bool {
case ACTION_CHDIR:
g.editor = L"chdir";
g.editor_on_confirm = [] {
- change_dir (to_mb (g.editor_line));
+ change_dir (untilde (to_mb (g.editor_line)));
};
break;
case ACTION_PARENT:
@@ -1233,10 +1255,7 @@ fun handle (wint_t c) -> bool {
change_dir (g.start_dir);
break;
case ACTION_GO_HOME:
- if (const auto *home = getenv ("HOME"))
- change_dir (home);
- else if (const auto *pw = getpwuid (getuid ()))
- change_dir (pw->pw_dir);
+ change_dir (untilde ("~"));
break;
case ACTION_SEARCH: