summaryrefslogtreecommitdiffstats
path: root/cmd.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2012-01-31 15:52:21 +0000
committerNicholas Marriott <nicm@openbsd.org>2012-01-31 15:52:21 +0000
commit908a22e41ce9b33156ee2fa7a68bd585033cf3a3 (patch)
tree218d3848ddddab98ee5021e11dc73865e1a05743 /cmd.c
parent49a5a587ec6c99e4030d51cb65f04d49c87e3c31 (diff)
Provide defined ways to set the various default-path possibilities: ~
for home directory, . for server start directory, - for session start directory and empty for the pane's working directory (the default). All can also be used as part of a relative path (eg -/foo). Also provide -c flags to neww and splitw to override default-path setting. Based on a diff from sthen. ok sthen
Diffstat (limited to 'cmd.c')
-rw-r--r--cmd.c87
1 files changed, 68 insertions, 19 deletions
diff --git a/cmd.c b/cmd.c
index 9656ae4f..5e2abfec 100644
--- a/cmd.c
+++ b/cmd.c
@@ -21,6 +21,7 @@
#include <fnmatch.h>
#include <paths.h>
+#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -1251,34 +1252,82 @@ cmd_template_replace(char *template, const char *s, int idx)
return (buf);
}
-/* Return the default path for a new pane. */
+/*
+ * Return the default path for a new pane, using the given path or the
+ * default-path option if it is NULL. Several special values are accepted: the
+ * empty string or relative path for the current pane's working directory, ~
+ * for the user's home, - for the session working directory, . for the tmux
+ * server's working directory. The default on failure is the session's working
+ * directory.
+ */
const char *
-cmd_get_default_path(struct cmd_ctx *ctx)
+cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd)
{
- const char *cwd;
struct session *s;
- struct window_pane *wp;
struct environ_entry *envent;
+ const char *root;
+ char tmp[MAXPATHLEN];
+ struct passwd *pw;
+ int n;
+ size_t skip;
+ static char path[MAXPATHLEN];
if ((s = cmd_current_session(ctx, 0)) == NULL)
return (NULL);
- cwd = options_get_string(&s->options, "default-path");
- if ((cwd[0] == '~' && cwd[1] == '\0') || !strcmp(cwd, "$HOME")) {
- envent = environ_find(&global_environ, "HOME");
- if (envent != NULL && *envent->value != '\0')
- return envent->value;
- cwd = "";
- }
- if (*cwd == '\0') {
- if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
- return (ctx->cmdclient->cwd);
- if (ctx->curclient != NULL) {
- wp = s->curw->window->active;
- if ((cwd = get_proc_cwd(wp->pid)) != NULL)
- return (cwd);
+ if (cwd == NULL)
+ cwd = options_get_string(&s->options, "default-path");
+
+ skip = 1;
+ if (strcmp(cwd, "$HOME") == 0 || strncmp(cwd, "$HOME/", 6) == 0) {
+ /* User's home directory - $HOME. */
+ skip = 5;
+ goto find_home;
+ } else if (cwd[0] == '~' && (cwd[1] == '\0' || cwd[1] == '/')) {
+ /* User's home directory - ~. */
+ goto find_home;
+ } else if (cwd[0] == '-' && (cwd[1] == '\0' || cwd[1] == '/')) {
+ /* Session working directory. */
+ root = s->cwd;
+ goto complete_path;
+ } else if (cwd[0] == '.' && (cwd[1] == '\0' || cwd[1] == '/')){
+ /* Server working directory. */
+ if (getcwd(tmp, sizeof tmp) != NULL) {
+ root = tmp;
+ goto complete_path;
}
return (s->cwd);
+ } else if (*cwd == '/') {
+ /* Absolute path. */
+ return (cwd);
+ } else {
+ /* Empty or relative path. */
+ if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
+ root = ctx->cmdclient->cwd;
+ else if (ctx->curclient != NULL)
+ root = get_proc_cwd(s->curw->window->active->pid);
+ else
+ return (s->cwd);
+ skip = 0;
+ goto complete_path;
}
- return (cwd);
+
+ return (s->cwd);
+
+find_home:
+ envent = environ_find(&global_environ, "HOME");
+ if (envent != NULL && *envent->value != '\0')
+ root = envent->value;
+ else if ((pw = getpwuid(getuid())) != NULL)
+ root = pw->pw_dir;
+ else
+ return (s->cwd);
+
+complete_path:
+ if (root[skip] == '\0')
+ return (root);
+ n = snprintf(path, sizeof path, "%s/%s", root, cwd + skip);
+ if (n > 0 && (size_t)n < sizeof path)
+ return (path);
+ return (s->cwd);
}