diff options
-rw-r--r-- | usr.bin/tmux/cmd-new-window.c | 9 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-split-window.c | 9 | ||||
-rw-r--r-- | usr.bin/tmux/cmd.c | 89 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 15 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
5 files changed, 94 insertions, 32 deletions
diff --git a/usr.bin/tmux/cmd-new-window.c b/usr.bin/tmux/cmd-new-window.c index 32ba586f96f..307e882a3ff 100644 --- a/usr.bin/tmux/cmd-new-window.c +++ b/usr.bin/tmux/cmd-new-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-new-window.c,v 1.19 2012/01/20 19:54:07 nicm Exp $ */ +/* $OpenBSD: cmd-new-window.c,v 1.20 2012/01/31 15:52:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -30,8 +30,9 @@ int cmd_new_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_new_window_entry = { "new-window", "neww", - "adkn:Pt:", 0, 1, - "[-adk] [-n window-name] [-t target-window] [command]", + "ac:dkn:Pt:", 0, 1, + "[-adk] [-c start-directory] [-n window-name] [-t target-window] " + "[command]", 0, NULL, NULL, @@ -99,7 +100,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd = options_get_string(&s->options, "default-command"); else cmd = args->argv[0]; - cwd = cmd_get_default_path(ctx); + cwd = cmd_get_default_path(ctx, args_get(args, 'c')); if (idx == -1) idx = -1 - options_get_number(&s->options, "base-index"); diff --git a/usr.bin/tmux/cmd-split-window.c b/usr.bin/tmux/cmd-split-window.c index a9bbcb70698..b6466d6f641 100644 --- a/usr.bin/tmux/cmd-split-window.c +++ b/usr.bin/tmux/cmd-split-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-split-window.c,v 1.27 2012/01/20 19:54:07 nicm Exp $ */ +/* $OpenBSD: cmd-split-window.c,v 1.28 2012/01/31 15:52:21 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -33,8 +33,9 @@ int cmd_split_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_split_window_entry = { "split-window", "splitw", - "dl:hp:Pt:v", 0, 1, - "[-dhvP] [-p percentage|-l size] [-t target-pane] [command]", + "c:dl:hp:Pt:v", 0, 1, + "[-dhvP] [-c start-directory] [-p percentage|-l size] [-t target-pane] " + "[command]", 0, cmd_split_window_key_binding, NULL, @@ -78,7 +79,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd = options_get_string(&s->options, "default-command"); else cmd = args->argv[0]; - cwd = cmd_get_default_path(ctx); + cwd = cmd_get_default_path(ctx, args_get(args, 'c')); type = LAYOUT_TOPBOTTOM; if (args_has(args, 'h')) diff --git a/usr.bin/tmux/cmd.c b/usr.bin/tmux/cmd.c index 110943164ef..6352b340180 100644 --- a/usr.bin/tmux/cmd.c +++ b/usr.bin/tmux/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.60 2012/01/30 09:39:34 nicm Exp $ */ +/* $OpenBSD: cmd.c,v 1.61 2012/01/31 15:52:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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); } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 80a072fdc11..c1da1264c45 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.271 2012/01/30 20:48:28 jmc Exp $ +.\" $OpenBSD: tmux.1,v 1.272 2012/01/31 15:52:21 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 30 2012 $ +.Dd $Mdocdate: January 31 2012 $ .Dt TMUX 1 .Os .Sh NAME @@ -1224,6 +1224,7 @@ is moved to .Ar dst-window . .It Xo Ic new-window .Op Fl adkP +.Op Fl c Ar start-directory .Op Fl n Ar window-name .Op Fl t Ar target-window .Op Ar shell-command @@ -1254,6 +1255,15 @@ If is not specified, the value of the .Ic default-command option is used. +.Fl c +specifies the working directory in which the new window is created. +It may have an absolute path or one of the following values (or a subdirectory): +.Bl -column "XXXXXXXXXXXX" "XXXXXXXXXXXXXXXXXXXXXXXX" -offset indent +.It Li "Empty string" Ta "Current pane's directory" +.It Li "~" Ta "User's home directory" +.It Li "-" Ta "Where session was started" +.It Li "." Ta "Where server was started" +.El .Pp When the shell command completes, the window closes. See the @@ -1453,6 +1463,7 @@ and commands. .It Xo Ic split-window .Op Fl dhvP +.Op Fl c Ar start-directory .Oo Fl l .Ar size | .Fl p Ar percentage Oc diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 5c766fc8588..cd2741106b0 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.309 2012/01/30 09:39:34 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.310 2012/01/31 15:52:21 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1559,7 +1559,7 @@ int cmd_find_index( struct winlink *cmd_find_pane(struct cmd_ctx *, const char *, struct session **, struct window_pane **); char *cmd_template_replace(char *, const char *, int); -const char *cmd_get_default_path(struct cmd_ctx *ctx); +const char *cmd_get_default_path(struct cmd_ctx *, const char *); extern const struct cmd_entry *cmd_table[]; extern const struct cmd_entry cmd_attach_session_entry; extern const struct cmd_entry cmd_bind_key_entry; |