Skip to content

Commit

Permalink
Big reorganisation of command-line syntax.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicm committed Jun 5, 2008
1 parent ee1a7fd commit 0b9b873
Show file tree
Hide file tree
Showing 42 changed files with 911 additions and 1,522 deletions.
23 changes: 22 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
05 June 2008

* Completely reorganise command parsing. Much more common code in cmd-generic.c
and a new way of specifying windows, clients or sessions. Now, most commands
take a -t argument, which specifies a client, a session, or a window target.
Clients and sessions are given alone (sessions are fnmatch(3)d and
clients currently not), windows are give by (client|session):index. For
example, if a user is in session "1" window 0 on /dev/ttypi, these should all
be equivalent:

tmux renamew newname (current session and window)
tmux renamew -t: newname (current session and window)
tmux renamew -t:0 newname (current session, window 0)
tmux renamew -t0 newname (current session, window 0)
tmux renamew -t1:0 newname (session 1, window 0)
tmux renamew -t1: newname (session 1, current window)
tmux renamew -t/dev/ttypi newname (client /dev/ttypi's current
session and window)
tmux renamew -t/dev/ttypi: newname (client /dev/ttypi's current
session and window)
tmux renamew -t/dev/ttypi:0 newname (client /dev/ttypi's current
session, window 0)

* Infrastructure for printing arguments in list-keys output. Easy ones only for
now.

Expand Down Expand Up @@ -408,4 +429,4 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.

$Id: CHANGES,v 1.110 2008-06-05 16:35:31 nicm Exp $
$Id: CHANGES,v 1.111 2008-06-05 21:24:59 nicm Exp $
4 changes: 2 additions & 2 deletions GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# $Id: GNUmakefile,v 1.15 2008-06-05 05:04:47 nicm Exp $
# $Id: GNUmakefile,v 1.16 2008-06-05 21:25:00 nicm Exp $

.PHONY: clean

Expand All @@ -14,7 +14,7 @@ META?= \002
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
key-string.c key-bindings.c resize.c cmd.c cmd-generic.c \
key-string.c key-bindings.c resize.c arg.c cmd.c cmd-generic.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# $Id: Makefile,v 1.58 2008-06-04 17:54:26 nicm Exp $
# $Id: Makefile,v 1.59 2008-06-05 21:25:00 nicm Exp $

.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
Expand All @@ -18,7 +18,7 @@ META?= \002 # C-b
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
key-string.c key-bindings.c resize.c cmd.c cmd-generic.c \
key-string.c key-bindings.c resize.c arg.c cmd.c cmd-generic.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
Expand Down
8 changes: 0 additions & 8 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,3 @@
- each command should have a print op as well for list keys
- fix occasion start server problems
- test and fix wsvt25
- look again at stuff that doesn't use flags
swap-window
switch-client
audit for lookup window
link-window
look for dstidx
also lookup dstsess with find_session
---
192 changes: 192 additions & 0 deletions arg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/* $Id: arg.c,v 1.1 2008-06-05 21:25:00 nicm Exp $ */

/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <sys/types.h>

#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>

#include "tmux.h"

struct client *arg_lookup_client(const char *);
struct session *arg_lookup_session(const char *);

struct client *
arg_lookup_client(const char *name)
{
struct client *c;
u_int i;

for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && strcmp(name, c->tty.path) == 0)
return (c);
}

return (NULL);
}

struct session *
arg_lookup_session(const char *name)
{
struct session *s, *newest = NULL;
struct timespec *ts;
u_int i;

ts = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL || fnmatch(name, s->name, 0) != 0)
continue;

if (ts == NULL || timespeccmp(&s->ts, ts, >)) {
newest = s;
ts = &s->ts;
}
}

return (newest);
}

struct client *
arg_parse_client(const char *arg)
{
struct client *c;
char *arg2;
size_t n;

if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);

/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (arg2[n - 1] == ':')
arg2[n - 1] = '\0';

/* Try and lookup the client name. */
c = arg_lookup_client(arg2);
xfree(arg2);
return (c);
}

return (NULL);
}

struct session *
arg_parse_session(const char *arg)
{
struct session *s;
struct client *c;
char *arg2;
size_t n;

if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);

/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (arg2[n - 1] == ':')
arg2[n - 1] = '\0';

/* See if the argument matches a session. */
if ((s = arg_lookup_session(arg2)) != NULL) {
xfree(arg2);
return (s);
}

/* If not try a client. */
if ((c = arg_lookup_client(arg2)) != NULL) {
xfree(arg2);
return (c->session);
}
}

return (NULL);
}

int
arg_parse_window(const char *arg, struct session **s, int *idx)
{
char *arg2, *ptr;
const char *errstr;

*idx = -1;

/* Handle no argument or a single :. */
if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) {
*s = arg_parse_session(NULL);
return (0);
}

/* Find the separator if any. */
arg2 = xstrdup(arg);
ptr = strrchr(arg2, ':');

/*
* If it is first, this means no session name, so use current session
* and try to convert the rest as index.
*/
if (ptr == arg2) {
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}

xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}

/* If missing, try as an index, else lookup immediately. */
if (ptr == NULL) {
*idx = strtonum(arg2, 0, INT_MAX, &errstr);
if (errstr == NULL) {
/* This is good as an index; use current session. */
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}

*idx = -1;
goto lookup;
}

/* If last, strip it and look up as a session. */
if (ptr[1] == '\0') {
*ptr = '\0';
goto lookup;
}

/* Present but not first and not last. Break and convert both. */
*ptr = '\0';
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}

lookup:
/* Look up as session. */
*s = arg_parse_session(arg2);
xfree(arg2);
if (*s == NULL)
return (1);
return (0);
}
Loading

0 comments on commit 0b9b873

Please sign in to comment.