diff --git a/Makefile.am b/Makefile.am index c1c3b11f..5465e829 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,8 +6,8 @@ CLEANFILES = tmate.1.mdoc tmate.1.man # Distribution tarball options. EXTRA_DIST = \ - CHANGES FAQ README TODO COPYING examples compat/*.[ch] \ - array.h compat.h tmux.h osdep-*.c mdoc2man.awk tmate.1 + CHANGES FAQ README TODO COPYING example_tmux.conf compat/*.[ch] \ + array.h compat.h tmux.h osdep-*.c xmalloc.h mdoc2man.awk tmate.1 dist-hook: make clean grep "^#found_debug=" configure @@ -66,7 +66,7 @@ if IS_SUNCC CFLAGS += -erroff=E_EMPTY_DECLARATION endif -# Set _LINUX_SOURCE_COMPAT for AIX for mallocing 0 bytes +# Set _LINUX_SOURCE_COMPAT for AIX for malloc(0). if IS_AIX DEFS += -D_LINUX_SOURCE_COMPAT=1 endif diff --git a/README b/README index 6a78fa2b..9141f240 100644 --- a/README +++ b/README @@ -8,7 +8,7 @@ This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris. tmux depends on libevent 2.x. Download it from: - http://www.monkey.org/~provos/libevent/ + http://libevent.org To build tmux from a release tarball, do: @@ -33,13 +33,17 @@ the source tree with: Some common questions are answered in the FAQ file and a more extensive (but slightly out of date) guide is available in the OpenBSD FAQ at http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO -file and some example configurations are in the examples directory. +file and an example configuration in example_tmux.conf. A vim(1) syntax file is available at: https://github.com/keith/tmux.vim https://raw.githubusercontent.com/keith/tmux.vim/master/syntax/tmux.vim +And a bash(1) completion file at: + + https://github.com/przepompownia/tmux-bash-completion + For debugging, running tmux with -v or -vv will generate server and client log files in the current directory. @@ -56,10 +60,7 @@ welcome. Please send by email to: tmux-users@googlegroups.com -This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under -the ISC license. Files under examples/ remain copyright their authors unless -otherwise stated in the file but permission has been received to distribute -them with tmux. All other files have a license and copyright notice at their -start. +This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under the +ISC license. All other files have a license and copyright notice at their start. -- Nicholas Marriott diff --git a/TODO b/TODO index b4b8231b..e0e3de6d 100644 --- a/TODO +++ b/TODO @@ -62,6 +62,20 @@ * command to toggle selection not to move it in copy-mode * regex searching * copy-pipe should have -x as well + * copy mode key bindings should just be a standard key table, using + something like "copy-mode start-selection"; it could use + command-prompt for search, goto, etc: + + bind -Temacs command-prompt -p'Search Up: ' 'copy-mode search-up %%' + + it'd need a separate lookup, because modes are per-pane, perhaps a + table() cb to give the table name ("vi" or "emacs"). anything in the + table fires the command, anything not in the table is injected as a + key + * searching in copy mode should unwrap lines, so if you seach for "foobar" + then it should be found even if it is now "foo\nbar" (if the WRAP flag + is set on the line) + * {} to go to next/previous blank line in copy mode - layout stuff * way to tag a layout as a number/name @@ -118,18 +132,8 @@ comes from config for new sessions and windows. likewise, panes and jobs and run-shell and lock command all start with slightly different environments - * multiline status line? + * multiline status line? separate command prompt and status line? * customizable command aliases * automatic pane logging * BCE? We are halfway there (output side is done for pane backgrounds), just need to change how screen/grid handles erase - * copy mode key bindings should just be a standard key table, using - something like "copy-mode start-selection"; it could use - command-prompt for search, goto, etc: - - bind -Temacs command-prompt -p'Search Up: ' 'copy-mode search-up %%' - - it'd need a separate lookup, because modes are per-pane, perhaps a - table() cb to give the table name ("vi" or "emacs"). anything in the - table fires the command, anything not in the table is injected as a - key diff --git a/alerts.c b/alerts.c index 536ea750..cca0d815 100644 --- a/alerts.c +++ b/alerts.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2015 Nicholas Marriott + * Copyright (c) 2015 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,6 +29,7 @@ int alerts_enabled(struct window *, int); void alerts_callback(int, short, void *); void alerts_reset(struct window *); +void alerts_run_hook(struct session *, struct winlink *, int); int alerts_check_all(struct session *, struct winlink *); int alerts_check_bell(struct session *, struct winlink *); int alerts_check_activity(struct session *, struct winlink *); @@ -55,8 +56,6 @@ alerts_callback(__unused int fd, __unused short events, __unused void *arg) RB_FOREACH(w, windows, &windows) { RB_FOREACH(s, sessions, &sessions) { - if (s->flags & SESSION_UNATTACHED) - continue; RB_FOREACH(wl, winlinks, &s->windows) { if (wl->window != w) continue; @@ -73,6 +72,22 @@ alerts_callback(__unused int fd, __unused short events, __unused void *arg) alerts_fired = 0; } +void +alerts_run_hook(struct session *s, struct winlink *wl, int flags) +{ + struct cmd_find_state fs; + + if (cmd_find_from_winlink(&fs, s, wl) != 0) + return; + + if (flags & WINDOW_BELL) + hooks_run(s->hooks, NULL, &fs, "alert-bell"); + if (flags & WINDOW_SILENCE) + hooks_run(s->hooks, NULL, &fs, "alert-silence"); + if (flags & WINDOW_ACTIVITY) + hooks_run(s->hooks, NULL, &fs, "alert-activity"); +} + int alerts_check_all(struct session *s, struct winlink *wl) { @@ -81,8 +96,10 @@ alerts_check_all(struct session *s, struct winlink *wl) alerts = alerts_check_bell(s, wl); alerts |= alerts_check_activity(s, wl); alerts |= alerts_check_silence(s, wl); - if (alerts != 0) + if (alerts != 0) { + alerts_run_hook(s, wl, alerts); server_status_session(s); + } return (alerts); } diff --git a/arguments.c b/arguments.c index 2042a0e9..d3a214cf 100644 --- a/arguments.c +++ b/arguments.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2010 Nicholas Marriott + * Copyright (c) 2010 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/array.h b/array.h index 671bea42..209de0c5 100644 --- a/array.h +++ b/array.h @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2006 Nicholas Marriott + * Copyright (c) 2006 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cfg.c b/cfg.c index 975b89a4..50882738 100644 --- a/cfg.c +++ b/cfg.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/client.c b/client.c index 3c878ca4..32a5afe6 100644 --- a/client.c +++ b/client.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-attach-session.c b/cmd-attach-session.c index bf829b21..18e50f65 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-bind-key.c b/cmd-bind-key.c index df3285f7..a829a2c5 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-break-pane.c b/cmd-break-pane.c index 33648a85..adb561d9 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,7 +35,7 @@ const struct cmd_entry cmd_break_pane_entry = { .alias = "breakp", .args = { "dPF:s:t:", 0, 0 }, - .usage = "[-dP] [-F format] " CMD_SRCDST_PANE_USAGE, + .usage = "[-dP] [-F format] [-s src-pane] [-t dst-window]", .sflag = CMD_PANE, .tflag = CMD_WINDOW_INDEX, diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c index 1f8fbfb2..90872e90 100644 --- a/cmd-choose-buffer.c +++ b/cmd-choose-buffer.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2010 Nicholas Marriott + * Copyright (c) 2010 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-choose-client.c b/cmd-choose-client.c index 7d5fc606..b9a24be6 100644 --- a/cmd-choose-client.c +++ b/cmd-choose-client.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-clear-history.c b/cmd-clear-history.c index 1236e7f1..62683ff6 100644 --- a/cmd-clear-history.c +++ b/cmd-clear-history.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 9200ada1..3ec22865 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 1a006ebb..beb4d7c8 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,6 +46,8 @@ const struct cmd_entry cmd_clock_mode_entry = { .args = { "t:", 0, 0 }, .usage = CMD_TARGET_PANE_USAGE, + .tflag = CMD_PANE, + .flags = 0, .exec = cmd_copy_mode_exec }; diff --git a/cmd-detach-client.c b/cmd-detach-client.c index daf9a5c6..80c6555f 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-display-panes.c b/cmd-display-panes.c index d8db4066..eed3611e 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-find-window.c b/cmd-find-window.c index eb940d8c..6324f26a 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-find.c b/cmd-find.c index 0e85152a..f95c143b 100644 --- a/cmd-find.c +++ b/cmd-find.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2015 Nicholas Marriott + * Copyright (c) 2015 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -400,6 +400,7 @@ int cmd_find_get_session(struct cmd_find_state *fs, const char *session) { struct session *s, *s_loop; + struct client *c; log_debug("%s: %s", __func__, session); @@ -416,6 +417,13 @@ cmd_find_get_session(struct cmd_find_state *fs, const char *session) if (fs->s != NULL) return (0); + /* Look for as a client. */ + c = cmd_find_client(NULL, session, 1); + if (c != NULL && c->session != NULL) { + fs->s = c->session; + return (0); + } + /* Stop now if exact only. */ if (fs->flags & CMD_FIND_EXACT_SESSION) return (-1); @@ -878,6 +886,22 @@ cmd_find_from_session(struct cmd_find_state *fs, struct session *s) return (0); } +/* Find state from a winlink. */ +int +cmd_find_from_winlink(struct cmd_find_state *fs, struct session *s, + struct winlink *wl) +{ + cmd_find_clear_state(fs, NULL, 0); + + fs->s = s; + fs->wl = wl; + fs->w = wl->window; + fs->wp = wl->window->active; + + cmd_find_log_state(__func__, fs); + return (0); +} + /* Find state from a window. */ int cmd_find_from_window(struct cmd_find_state *fs, struct window *w) @@ -906,15 +930,27 @@ cmd_find_from_pane(struct cmd_find_state *fs, struct window_pane *wp) return (0); } +/* Find current state. */ +int +cmd_find_current(struct cmd_find_state *fs, struct cmd_q *cmdq, int flags) +{ + cmd_find_clear_state(fs, cmdq, flags); + if (cmd_find_current_session(fs) != 0) { + if (~flags & CMD_FIND_QUIET) + cmdq_error(cmdq, "no current session"); + return (-1); + } + return (0); +} + /* * Split target into pieces and resolve for the given type. Fills in the given * state. Returns 0 on success or -1 on error. */ int -cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, - const char *target, enum cmd_find_type type, int flags) +cmd_find_target(struct cmd_find_state *fs, struct cmd_find_state *current, + struct cmd_q *cmdq, const char *target, enum cmd_find_type type, int flags) { - struct cmd_find_state current; struct mouse_event *m; char *colon, *period, *copy = NULL; const char *session, *window, *pane; @@ -934,15 +970,8 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, fs->current = &marked_pane; else if (cmd_find_valid_state(&cmdq->current)) fs->current = &cmdq->current; - else { - cmd_find_clear_state(¤t, cmdq, flags); - if (cmd_find_current_session(¤t) != 0) { - if (~flags & CMD_FIND_QUIET) - cmdq_error(cmdq, "no current session"); - goto error; - } - fs->current = ¤t; - } + else + fs->current = current; /* An empty or NULL target is the current. */ if (target == NULL || *target == '\0') @@ -1187,7 +1216,7 @@ cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet) const char *path; /* A NULL argument means the current client. */ - if (target == NULL) { + if (cmdq != NULL && target == NULL) { c = cmd_find_current_client(cmdq); if (c == NULL && !quiet) cmdq_error(cmdq, "no current client"); diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 229289cd..3e2a5251 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -73,14 +73,13 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq) struct format_tree *ft; const char *cwd; - cwd = wp->cwd; - if (cmdq->client != NULL && cmdq->client->session == NULL) cwd = cmdq->client->cwd; else if (s != NULL) cwd = s->cwd; else cwd = NULL; + ft = format_create(cmdq, 0); format_defaults(ft, NULL, s, wl, wp); shellcmd = format_expand(ft, args->argv[0]); diff --git a/cmd-join-pane.c b/cmd-join-pane.c index d75e5079..55c05ae5 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2011 George Nachman - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c index ffdee3b2..45010f1c 100644 --- a/cmd-kill-pane.c +++ b/cmd-kill-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-kill-server.c b/cmd-kill-server.c index 6f84e959..d1940c33 100644 --- a/cmd-kill-server.c +++ b/cmd-kill-server.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-kill-session.c b/cmd-kill-session.c index 4ca4e2c8..c77e45bb 100644 --- a/cmd-kill-session.c +++ b/cmd-kill-session.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-kill-window.c b/cmd-kill-window.c index 7a8e9fa6..9d388ce5 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list-buffers.c b/cmd-list-buffers.c index a6007c33..238b2776 100644 --- a/cmd-list-buffers.c +++ b/cmd-list-buffers.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list-clients.c b/cmd-list-clients.c index 75c6f570..f318ac18 100644 --- a/cmd-list-clients.c +++ b/cmd-list-clients.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 4abe2473..c3ace8de 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list-panes.c b/cmd-list-panes.c index da0e0962..76e06a71 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 1fde7f86..27e80dbc 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list-windows.c b/cmd-list-windows.c index dd05ea85..11a5fddf 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-list.c b/cmd-list.c index 59fc7796..e999c370 100644 --- a/cmd-list.c +++ b/cmd-list.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c index 6fd2a767..de76b855 100644 --- a/cmd-load-buffer.c +++ b/cmd-load-buffer.c @@ -73,9 +73,9 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_WAIT); } - if (c != NULL && c->session == NULL) + if (c != NULL && c->session == NULL && c->cwd != NULL) cwd = c->cwd; - else if ((s = c->session) != NULL) + else if ((s = c->session) != NULL && s->cwd != NULL) cwd = s->cwd; else cwd = "."; diff --git a/cmd-lock-server.c b/cmd-lock-server.c index 9cdd816f..01597169 100644 --- a/cmd-lock-server.c +++ b/cmd-lock-server.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-move-window.c b/cmd-move-window.c index bb33ab38..e756a638 100644 --- a/cmd-move-window.c +++ b/cmd-move-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-new-session.c b/cmd-new-session.c index f96003c7..357ffed1 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -68,13 +68,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c = cmdq->client; - struct session *s, *attach_sess; + struct session *s, *as; struct session *groupwith = cmdq->state.tflag.s; struct window *w; struct environ *env; struct termios tio, *tiop; const char *newname, *target, *update, *errstr, *template; - const char *path, *cwd, *to_free; + const char *path, *cwd, *to_free = NULL; char **argv, *cmd, *cause, *cp; int detached, already_attached, idx, argc; u_int sx, sy; @@ -100,7 +100,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "bad session name: %s", newname); return (CMD_RETURN_ERROR); } - if ((attach_sess = session_find(newname)) != NULL) { + if ((as = session_find(newname)) != NULL) { if (args_has(args, 'A')) { /* * This cmdq is now destined for @@ -108,7 +108,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) * will have already been prepared, copy this * session into its tflag so it can be used. */ - cmdq->state.tflag.s = attach_sess; + cmd_find_from_session(&cmdq->state.tflag, as); return (cmd_attach_session(cmdq, args_has(args, 'D'), 0, NULL, args_has(args, 'E'))); @@ -118,7 +118,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) } } - if ((target = args_get(args, 't')) == NULL) + if ((target = args_get(args, 't')) != NULL) { + if (groupwith == NULL) { + cmdq_error(cmdq, "no such session: %s", target); + goto error; + } + } else groupwith = NULL; /* Set -d if no client. */ @@ -132,13 +137,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) already_attached = 1; /* Get the new session working directory. */ - to_free = NULL; if (args_has(args, 'c')) { ft = format_create(cmdq, 0); format_defaults(ft, c, NULL, NULL, NULL); to_free = cwd = format_expand(ft, args_get(args, 'c')); format_free(ft); - } else if (c != NULL && c->session == NULL) + } else if (c != NULL && c->session == NULL && c->cwd != NULL) cwd = c->cwd; else cwd = "."; @@ -208,7 +212,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) if (!args_has(args, 't') && args->argc != 0) { argc = args->argc; argv = args->argv; - } else if (target == NULL) { + } else if (groupwith == NULL) { cmd = options_get_string(global_s_options, "default-command"); if (cmd != NULL && *cmd != '\0') { argc = 1; @@ -257,7 +261,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) * If a target session is given, this is to be part of a session group, * so add it to the group and synchronize. */ - if (args_has(args, 't')) { + if (groupwith != NULL) { session_group_add(groupwith, s); session_group_synchronize_to(s); session_select(s, RB_MIN(winlinks, &s->windows)->idx); diff --git a/cmd-new-window.c b/cmd-new-window.c index 33f68935..2a647b9f 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index ebf3a00f..e603c895 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c index 3830450c..d311e350 100644 --- a/cmd-pipe-pane.c +++ b/cmd-pipe-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-queue.c b/cmd-queue.c index 70f5d867..2cc714f7 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2013 Nicholas Marriott + * Copyright (c) 2013 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -210,7 +210,7 @@ cmdq_continue_one(struct cmd_q *cmdq) cmdq_guard(cmdq, "begin", flags); - if (cmd_prepare_state(cmd, cmdq) != 0) + if (cmd_prepare_state(cmd, cmdq, NULL) != 0) goto error; retval = cmd->entry->exec(cmd, cmdq); if (retval == CMD_RETURN_ERROR) diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c index 444e83fc..79e5aad0 100644 --- a/cmd-refresh-client.c +++ b/cmd-refresh-client.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-rename-session.c b/cmd-rename-session.c index 7fc6193d..b40f44f7 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-rename-window.c b/cmd-rename-window.c index 36c1bf31..a1f15eef 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index 09fe7e06..0d2f21cc 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -71,7 +71,6 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } - w = wl->window; if (args_has(args, 'Z')) { if (w->flags & WINDOW_ZOOMED) window_unzoom(w); diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c index 10196c3a..8b8df2a1 100644 --- a/cmd-respawn-pane.c +++ b/cmd-respawn-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * Copyright (c) 2011 Marcel P. Partap * * Permission to use, copy, modify, and distribute this software for any diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index b581f3f2..07385992 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c index 333258ea..22d43106 100644 --- a/cmd-rotate-window.c +++ b/cmd-rotate-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-run-shell.c b/cmd-run-shell.c index e857e9c9..0bd8fc59 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -93,7 +93,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq) else cwd = NULL; ft = format_create(cmdq, 0); - format_defaults(ft, NULL, s, wl, wp); + format_defaults(ft, cmdq->state.c, s, wl, wp); shellcmd = format_expand(ft, args->argv[0]); format_free(ft); diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index f8756587..56472565 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -97,9 +97,9 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) goto do_print; } - if (c != NULL && c->session == NULL) + if (c != NULL && c->session == NULL && c->cwd != NULL) cwd = c->cwd; - else if ((s = c->session) != NULL) + else if ((s = c->session) != NULL && s->cwd != NULL) cwd = s->cwd; else cwd = "."; diff --git a/cmd-select-layout.c b/cmd-select-layout.c index f7ed39d4..c9e563dd 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 02385a41..14d53d48 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-select-window.c b/cmd-select-window.c index 82acc859..78228067 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 7e206182..26f7a5ba 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c index 1494cf26..1f0cf3d8 100644 --- a/cmd-set-buffer.c +++ b/cmd-set-buffer.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-set-environment.c b/cmd-set-environment.c index f701d7d9..ba295ea6 100644 --- a/cmd-set-environment.c +++ b/cmd-set-environment.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -47,7 +47,7 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct environ *env; - const char *name, *value; + const char *name, *value, *target; name = args->argv[0]; if (*name == '\0') { @@ -64,10 +64,19 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) else value = args->argv[1]; - if (args_has(self->args, 'g') || cmdq->state.tflag.s == NULL) + if (args_has(self->args, 'g')) env = global_environ; - else + else { + if (cmdq->state.tflag.s == NULL) { + target = args_get(args, 't'); + if (target != NULL) + cmdq_error(cmdq, "no such session: %s", target); + else + cmdq_error(cmdq, "no current session"); + return (CMD_RETURN_ERROR); + } env = cmdq->state.tflag.s->environ; + } if (args_has(self->args, 'u')) { if (value != NULL) { diff --git a/cmd-set-option.c b/cmd-set-option.c index de173e18..83caad40 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -100,7 +100,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) struct client *c; const struct options_table_entry *oe; struct options *oo; - const char *optstr, *valstr; + const char *optstr, *valstr, *target; /* Get the option name and value. */ optstr = args->argv[0]; @@ -140,29 +140,29 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) else if (oe->scope == OPTIONS_TABLE_WINDOW) { if (args_has(self->args, 'g')) oo = global_w_options; - else { - if (wl == NULL) { - cmdq_error(cmdq, - "couldn't set '%s'%s", optstr, - (!args_has(args, 't') && !args_has(args, - 'g')) ? " need target window or -g" : ""); - return (CMD_RETURN_ERROR); - } + else if (wl == NULL) { + target = args_get(args, 't'); + if (target != NULL) { + cmdq_error(cmdq, "no such window: %s", + target); + } else + cmdq_error(cmdq, "no current window"); + return (CMD_RETURN_ERROR); + } else oo = wl->window->options; - } } else if (oe->scope == OPTIONS_TABLE_SESSION) { if (args_has(self->args, 'g')) oo = global_s_options; - else { - if (s == NULL) { - cmdq_error(cmdq, - "couldn't set '%s'%s", optstr, - (!args_has(args, 't') && !args_has(args, - 'g')) ? " need target session or -g" : ""); - return (CMD_RETURN_ERROR); - } + else if (s == NULL) { + target = args_get(args, 't'); + if (target != NULL) { + cmdq_error(cmdq, "no such session: %s", + target); + } else + cmdq_error(cmdq, "no current session"); + return (CMD_RETURN_ERROR); + } else oo = s->options; - } } else { cmdq_error(cmdq, "unknown table"); return (CMD_RETURN_ERROR); diff --git a/cmd-show-environment.c b/cmd-show-environment.c index 54baafe4..29e89274 100644 --- a/cmd-show-environment.c +++ b/cmd-show-environment.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -93,11 +93,28 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) struct args *args = self->args; struct environ *env; struct environ_entry *envent; + const char *target; - if (args_has(self->args, 'g') || cmdq->state.tflag.s == NULL) + if ((target = args_get(args, 't')) != NULL) { + if (cmdq->state.tflag.s == NULL) { + cmdq_error(cmdq, "no such session: %s", target); + return (CMD_RETURN_ERROR); + } + } + + if (args_has(self->args, 'g')) env = global_environ; - else + else { + if (cmdq->state.tflag.s == NULL) { + target = args_get(args, 't'); + if (target != NULL) + cmdq_error(cmdq, "no such session: %s", target); + else + cmdq_error(cmdq, "no current session"); + return (CMD_RETURN_ERROR); + } env = cmdq->state.tflag.s->environ; + } if (args->argc != 0) { envent = environ_find(env, args->argv[0]); diff --git a/cmd-show-messages.c b/cmd-show-messages.c index c80ccf16..fa796eed 100644 --- a/cmd-show-messages.c +++ b/cmd-show-messages.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-show-options.c b/cmd-show-options.c index e99574f8..322f532c 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -63,12 +63,13 @@ const struct cmd_entry cmd_show_window_options_entry = { enum cmd_retval cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct session *s = cmdq->state.tflag.s; - struct winlink *wl = cmdq->state.tflag.wl; - struct options *oo; - enum options_table_scope scope; - int quiet; + struct args *args = self->args; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct options *oo; + enum options_table_scope scope; + int quiet; + const char *target; if (args_has(self->args, 's')) { oo = global_options; @@ -78,13 +79,27 @@ cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq) scope = OPTIONS_TABLE_WINDOW; if (args_has(self->args, 'g')) oo = global_w_options; - else + else if (wl == NULL) { + target = args_get(args, 't'); + if (target != NULL) { + cmdq_error(cmdq, "no such window: %s", target); + } else + cmdq_error(cmdq, "no current window"); + return (CMD_RETURN_ERROR); + } else oo = wl->window->options; } else { scope = OPTIONS_TABLE_SESSION; if (args_has(self->args, 'g')) oo = global_s_options; - else + else if (s == NULL) { + target = args_get(args, 't'); + if (target != NULL) { + cmdq_error(cmdq, "no such session: %s", target); + } else + cmdq_error(cmdq, "no current session"); + return (CMD_RETURN_ERROR); + } else oo = s->options; } diff --git a/cmd-split-window.c b/cmd-split-window.c index 6be72753..fe5131f2 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-string.c b/cmd-string.c index 51554800..757d4cdb 100644 --- a/cmd-string.c +++ b/cmd-string.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index e4ba0a21..47495e0c 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -54,22 +54,18 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq) struct layout_cell *src_lc, *dst_lc; u_int sx, sy, xoff, yoff; - dst_wl = cmdq->state.tflag.wl; - dst_w = dst_wl->window; + dst_w = cmdq->state.tflag.wl->window; dst_wp = cmdq->state.tflag.wp; - src_wl = cmdq->state.sflag.wl; - src_w = src_wl->window; + src_w = cmdq->state.sflag.wl->window; src_wp = cmdq->state.sflag.wp; server_unzoom_window(dst_w); if (args_has(self->args, 'D')) { - src_wl = dst_wl; src_w = dst_w; src_wp = TAILQ_NEXT(dst_wp, entry); if (src_wp == NULL) src_wp = TAILQ_FIRST(&dst_w->panes); } else if (args_has(self->args, 'U')) { - src_wl = dst_wl; src_w = dst_w; src_wp = TAILQ_PREV(dst_wp, window_panes, entry); if (src_wp == NULL) diff --git a/cmd-swap-window.c b/cmd-swap-window.c index e1835820..14907d2d 100644 --- a/cmd-swap-window.c +++ b/cmd-swap-window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-switch-client.c b/cmd-switch-client.c index f27d1cff..b5ea97e5 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c index 8e89f21a..7452fd9f 100644 --- a/cmd-unbind-key.c +++ b/cmd-unbind-key.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/cmd-wait-for.c b/cmd-wait-for.c index 59f7dbfb..81b01627 100644 --- a/cmd-wait-for.c +++ b/cmd-wait-for.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2013 Nicholas Marriott + * Copyright (c) 2013 Nicholas Marriott * Copyright (c) 2013 Thiago de Arruda * * Permission to use, copy, modify, and distribute this software for any diff --git a/cmd.c b/cmd.c index 4b31b4b3..28efa0c5 100644 --- a/cmd.c +++ b/cmd.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -388,10 +388,23 @@ usage: } static int -cmd_prepare_state_flag(struct cmd_find_state *fs, enum cmd_entry_flag flag, - const char *target, struct cmd_q *cmdq) +cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag, + struct cmd_q *cmdq, struct cmd_q *parent) { - int targetflags, error; + int targetflags, error; + struct cmd_find_state *fs = NULL; + struct cmd_find_state *current = NULL; + struct cmd_find_state tmp; + + if (flag == CMD_NONE || + flag == CMD_CLIENT || + flag == CMD_CLIENT_CANFAIL) + return (0); + + if (c == 't') + fs = &cmdq->state.tflag; + else if (c == 's') + fs = &cmdq->state.sflag; if (flag == CMD_SESSION_WITHPANE) { if (target != NULL && target[strcspn(target, ":.")] != '\0') @@ -400,6 +413,55 @@ cmd_prepare_state_flag(struct cmd_find_state *fs, enum cmd_entry_flag flag, flag = CMD_SESSION; } + targetflags = 0; + switch (flag) { + case CMD_SESSION: + case CMD_SESSION_CANFAIL: + case CMD_SESSION_PREFERUNATTACHED: + if (flag == CMD_SESSION_CANFAIL) + targetflags |= CMD_FIND_QUIET; + if (flag == CMD_SESSION_PREFERUNATTACHED) + targetflags |= CMD_FIND_PREFER_UNATTACHED; + break; + case CMD_MOVEW_R: + flag = CMD_WINDOW_INDEX; + /* FALLTHROUGH */ + case CMD_WINDOW: + case CMD_WINDOW_CANFAIL: + case CMD_WINDOW_MARKED: + case CMD_WINDOW_INDEX: + if (flag == CMD_WINDOW_CANFAIL) + targetflags |= CMD_FIND_QUIET; + if (flag == CMD_WINDOW_MARKED) + targetflags |= CMD_FIND_DEFAULT_MARKED; + if (flag == CMD_WINDOW_INDEX) + targetflags |= CMD_FIND_WINDOW_INDEX; + break; + case CMD_PANE: + case CMD_PANE_CANFAIL: + case CMD_PANE_MARKED: + if (flag == CMD_PANE_CANFAIL) + targetflags |= CMD_FIND_QUIET; + if (flag == CMD_PANE_MARKED) + targetflags |= CMD_FIND_DEFAULT_MARKED; + break; + default: + fatalx("unknown %cflag %d", c, flag); + } + + log_debug("%s: flag %c %d %#x", __func__, c, flag, targetflags); + if (parent != NULL) { + if (c == 't') + current = &parent->state.tflag; + else if (c == 's') + current = &parent->state.sflag; + } else { + error = cmd_find_current(&tmp, cmdq, targetflags); + if (error != 0 && ~targetflags & CMD_FIND_QUIET) + return (-1); + current = &tmp; + } + switch (flag) { case CMD_NONE: case CMD_CLIENT: @@ -409,61 +471,42 @@ cmd_prepare_state_flag(struct cmd_find_state *fs, enum cmd_entry_flag flag, case CMD_SESSION_CANFAIL: case CMD_SESSION_PREFERUNATTACHED: case CMD_SESSION_WITHPANE: - targetflags = 0; - if (flag == CMD_SESSION_CANFAIL) - targetflags |= CMD_FIND_QUIET; - if (flag == CMD_SESSION_PREFERUNATTACHED) - targetflags |= CMD_FIND_PREFER_UNATTACHED; - - error = cmd_find_target(fs, cmdq, target, CMD_FIND_SESSION, - targetflags); - if (error != 0 && flag != CMD_SESSION_CANFAIL) + error = cmd_find_target(fs, current, cmdq, target, + CMD_FIND_SESSION, targetflags); + if (error != 0 && ~targetflags & CMD_FIND_QUIET) return (-1); break; case CMD_MOVEW_R: - error = cmd_find_target(fs, cmdq, target, CMD_FIND_SESSION, - CMD_FIND_QUIET); + error = cmd_find_target(fs, current, cmdq, target, + CMD_FIND_SESSION, CMD_FIND_QUIET); if (error == 0) break; - flag = CMD_WINDOW_INDEX; /* FALLTHROUGH */ case CMD_WINDOW: case CMD_WINDOW_CANFAIL: case CMD_WINDOW_MARKED: case CMD_WINDOW_INDEX: - targetflags = 0; - if (flag == CMD_WINDOW_CANFAIL) - targetflags |= CMD_FIND_QUIET; - if (flag == CMD_WINDOW_MARKED) - targetflags |= CMD_FIND_DEFAULT_MARKED; - if (flag == CMD_WINDOW_INDEX) - targetflags |= CMD_FIND_WINDOW_INDEX; - - error = cmd_find_target(fs, cmdq, target, CMD_FIND_WINDOW, - targetflags); - if (error != 0 && flag != CMD_WINDOW_CANFAIL) + error = cmd_find_target(fs, current, cmdq, target, + CMD_FIND_WINDOW, targetflags); + if (error != 0 && ~targetflags & CMD_FIND_QUIET) return (-1); break; case CMD_PANE: case CMD_PANE_CANFAIL: case CMD_PANE_MARKED: - targetflags = 0; - if (flag == CMD_PANE_CANFAIL) - targetflags |= CMD_FIND_QUIET; - if (flag == CMD_PANE_MARKED) - targetflags |= CMD_FIND_DEFAULT_MARKED; - - error = cmd_find_target(fs, cmdq, target, CMD_FIND_PANE, - targetflags); - if (error != 0 && flag != CMD_PANE_CANFAIL) + error = cmd_find_target(fs, current, cmdq, target, + CMD_FIND_PANE, targetflags); + if (error != 0 && ~targetflags & CMD_FIND_QUIET) return (-1); break; + default: + fatalx("unknown %cflag %d", c, flag); } return (0); } int -cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq) +cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq, struct cmd_q *parent) { const struct cmd_entry *entry = cmd->entry; struct cmd_state *state = &cmdq->state; @@ -503,14 +546,14 @@ cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq) s = args_get(cmd->args, 't'); log_debug("preparing -t state: target %s", s == NULL ? "none" : s); - error = cmd_prepare_state_flag(&state->tflag, entry->tflag, s, cmdq); + error = cmd_prepare_state_flag('t', s, entry->tflag, cmdq, parent); if (error != 0) return (error); s = args_get(cmd->args, 's'); log_debug("preparing -s state: target %s", s == NULL ? "none" : s); - error = cmd_prepare_state_flag(&state->sflag, entry->sflag, s, cmdq); + error = cmd_prepare_state_flag('s', s, entry->sflag, cmdq, parent); if (error != 0) return (error); diff --git a/colour.c b/colour.c index a56ddce9..b349e2a5 100644 --- a/colour.c +++ b/colour.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat.h b/compat.h index 6812e9a5..b2267d37 100644 --- a/compat.h +++ b/compat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/asprintf.c b/compat/asprintf.c index 09020b35..5ed1c48c 100644 --- a/compat/asprintf.c +++ b/compat/asprintf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Nicholas Marriott + * Copyright (c) 2006 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/cfmakeraw.c b/compat/cfmakeraw.c index 85b2c9bc..d8794081 100644 --- a/compat/cfmakeraw.c +++ b/compat/cfmakeraw.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013 Dagobert Michelsen - * Copyright (c) 2013 Nicholas Marriott + * Copyright (c) 2013 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/fgetln.c b/compat/fgetln.c index a5c2489d..0ad6378a 100644 --- a/compat/fgetln.c +++ b/compat/fgetln.c @@ -1,43 +1,26 @@ -/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */ - -/*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. +/* + * Copyright (c) 2015 Joerg Jung * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. + * 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. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * 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 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 +/* + * portable fgetln() version, NOT reentrant + */ -#include #include #include -#include +#include #include "tmux.h" @@ -45,41 +28,34 @@ char * fgetln(FILE *fp, size_t *len) { static char *buf = NULL; - static size_t bufsiz = 0; - char *ptr; + static size_t bufsz = 0; + size_t r = 0; + char *p; + int c, e; - - if (buf == NULL) { - bufsiz = BUFSIZ; - if ((buf = malloc(bufsiz)) == NULL) - return NULL; - } - - if (fgets(buf, bufsiz, fp) == NULL) + if (!fp || !len) { + errno = EINVAL; return NULL; - - *len = 0; - while ((ptr = strchr(&buf[*len], '\n')) == NULL) { - size_t nbufsiz = bufsiz + BUFSIZ; - char *nbuf = realloc(buf, nbufsiz); - - if (nbuf == NULL) { - int oerrno = errno; - free(buf); - errno = oerrno; - buf = NULL; - return NULL; - } else - buf = nbuf; - - *len = bufsiz; - if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) - return buf; - - bufsiz = nbufsiz; } - - *len = (ptr - buf) + 1; - return buf; + if (!buf) { + if (!(buf = calloc(1, BUFSIZ))) + return NULL; + bufsz = BUFSIZ; + } + while ((c = getc(fp)) != EOF) { + buf[r++] = c; + if (r == bufsz) { + if (!(p = reallocarray(buf, 2, bufsz))) { + e = errno; + free(buf); + errno = e; + buf = NULL, bufsz = 0; + return NULL; + } + buf = p, bufsz = 2 * bufsz; + } + if (c == '\n') + break; + } + return (*len = r) ? buf : NULL; } - diff --git a/compat/forkpty-aix.c b/compat/forkpty-aix.c index 6894aa44..2557ebf7 100644 --- a/compat/forkpty-aix.c +++ b/compat/forkpty-aix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/forkpty-hpux.c b/compat/forkpty-hpux.c index 59130e1b..09b27d08 100644 --- a/compat/forkpty-hpux.c +++ b/compat/forkpty-hpux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/forkpty-sunos.c b/compat/forkpty-sunos.c index 554e51ac..9abda46c 100644 --- a/compat/forkpty-sunos.c +++ b/compat/forkpty-sunos.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/openat.c b/compat/openat.c index 6b04eedc..d003e53d 100644 --- a/compat/openat.c +++ b/compat/openat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Nicholas Marriott + * Copyright (c) 2013 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/compat/setenv.c b/compat/setenv.c index 6c7d29ec..b16b08cf 100644 --- a/compat/setenv.c +++ b/compat/setenv.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2010 Dagobert Michelsen - * Copyright (c) 2010 Nicholas Marriott + * Copyright (c) 2010 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/configure.ac b/configure.ac index 6ff344e8..318e73cd 100644 --- a/configure.ac +++ b/configure.ac @@ -181,10 +181,17 @@ if test "x$found_curses" = xno; then fi # Look for utempter. -AC_CHECK_HEADER(utempter.h, have_utempter=yes, have_utempter=no) -if test "x$have_utempter" = xyes; then - AC_DEFINE(HAVE_UTEMPTER) - LIBS="$LIBS -lutempter" +AC_CHECK_HEADER(utempter.h, found_utempter=yes, found_utempter=no) +if test "x$found_utempter" = xyes; then + AC_SEARCH_LIBS( + utempter_add_record, + utempter, + found_utempter=yes, + found_utempter=no + ) + if test "x$found_utempter" = xyes; then + AC_DEFINE(HAVE_UTEMPTER) + fi fi PKG_CHECK_MODULES( diff --git a/control-notify.c b/control-notify.c index 11669e04..1218ecce 100644 --- a/control-notify.c +++ b/control-notify.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2012 Nicholas Marriott + * Copyright (c) 2012 Nicholas Marriott * Copyright (c) 2012 George Nachman * * Permission to use, copy, modify, and distribute this software for any diff --git a/control.c b/control.c index e799a4cb..f6dedca8 100644 --- a/control.c +++ b/control.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2012 Nicholas Marriott + * Copyright (c) 2012 Nicholas Marriott * Copyright (c) 2012 George Nachman * * Permission to use, copy, modify, and distribute this software for any diff --git a/environ.c b/environ.c index de560896..d855f8b5 100644 --- a/environ.c +++ b/environ.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -196,10 +196,10 @@ void environ_push(struct environ *env) { struct environ_entry *envent; - char **vp, *v; + char *v; - for (vp = environ; *vp != NULL; vp++) { - v = xstrdup(*vp); + while (*environ != NULL) { + v = xstrdup(*environ); v[strcspn(v, "=")] = '\0'; unsetenv(v); diff --git a/example_tmux.conf b/example_tmux.conf new file mode 100644 index 00000000..f659a3c2 --- /dev/null +++ b/example_tmux.conf @@ -0,0 +1,66 @@ +# +# Example .tmux.conf +# +# By Nicholas Marriott. Public domain. +# + +# Some tweaks to the status line +set -g status-bg green +set -g status-right "%H:%M" +set -g window-status-current-attr "underscore" + +# No bells at all +set -g bell-action none + +# Lock after 15 minutes +set -g lock-after-time 1800 + +# Keep windows around after they exit +set -g remain-on-exit on + +# Turn on xterm-keys so that additional function keys get escape sequences +set -g xterm-keys on + +# Change the prefix key to C-a +set -g prefix C-a +unbind C-b +bind C-a send-prefix + +# Turn the mouse on, but without copy mode dragging +set -g mouse on +unbind -n MouseDrag1Pane +unbind -temacs-copy MouseDrag1Pane + +# Some extra key bindings to select higher numbered windows +bind F1 selectw -t:10 +bind F2 selectw -t:11 +bind F3 selectw -t:12 +bind F4 selectw -t:13 +bind F5 selectw -t:14 +bind F6 selectw -t:15 +bind F7 selectw -t:16 +bind F8 selectw -t:17 +bind F9 selectw -t:18 +bind F10 selectw -t:19 +bind F11 selectw -t:20 +bind F12 selectw -t:21 + +# Keys to toggle monitoring activity in a window, and synchronize-panes +bind m set monitor-activity +bind y set synchronize-panes\; display 'synchronize-panes #{?synchronize-panes,on,off}' + +# Keys to hide and show a window name from the status line +bind '-' set window-status-format '#I'\; set window-status-current-format '#I' +bind '+' set window-status-format '#I:#W#F'\; set window-status-current-format '#I:#W#F' + +# Create a single default session +new -d -s0 -nirssi 'exec irssi' +set -t0:0 monitor-activity on +set -t0:0 aggressive-resize on +neww -d -ntodo 'exec emacs ~/TODO' +setw -t0:1 aggressive-resize on +neww -d -nmutt 'exec mutt' +setw -t0:2 aggressive-resize on +neww -d +neww -d +neww -d diff --git a/examples/bash_completion_tmux.sh b/examples/bash_completion_tmux.sh deleted file mode 100644 index 74728b91..00000000 --- a/examples/bash_completion_tmux.sh +++ /dev/null @@ -1,105 +0,0 @@ -# START tmux completion -# This file is in the public domain -# See: http://www.debian-administration.org/articles/317 for how to write more. -# Usage: Put "source bash_completion_tmux.sh" into your .bashrc -_tmux() -{ - local cur prev opts - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - - opts=" \ - attach-session \ - bind-key \ - break-pane \ - capture-pane \ - choose-client \ - choose-session \ - choose-window \ - clear-history \ - clock-mode \ - command-prompt \ - confirm-before \ - copy-buffer \ - copy-mode \ - delete-buffer \ - detach-client \ - display-message \ - display-panes \ - down-pane \ - find-window \ - has-session \ - if-shell \ - join-pane \ - kill-pane \ - kill-server \ - kill-session \ - kill-window \ - last-window \ - link-window \ - list-buffers \ - list-clients \ - list-commands \ - list-keys \ - list-panes \ - list-sessions \ - list-windows \ - load-buffer \ - lock-client \ - lock-server \ - lock-session \ - move-window \ - new-session \ - new-window \ - next-layout \ - next-window \ - paste-buffer \ - pipe-pane \ - previous-layout \ - previous-window \ - refresh-client \ - rename-session \ - rename-window \ - resize-pane \ - respawn-window \ - rotate-window \ - run-shell \ - save-buffer \ - select-layout \ - select-pane \ - select-prompt \ - select-window \ - send-keys \ - send-prefix \ - server-info \ - set-buffer \ - set-environment \ - set-option \ - set-window-option \ - show-buffer \ - show-environment \ - show-messages \ - show-options \ - show-window-options \ - source-file \ - split-window \ - start-server \ - suspend-client \ - swap-pane \ - swap-window \ - switch-client \ - unbind-key \ - unlink-window \ - up-pane" - - COMPREPLY=($(compgen -W "${opts}" -- ${cur})) - return 0 - -} -complete -F _tmux tmux - -# END tmux completion - - - diff --git a/examples/h-boetes.conf b/examples/h-boetes.conf deleted file mode 100644 index 2aa86dc5..00000000 --- a/examples/h-boetes.conf +++ /dev/null @@ -1,42 +0,0 @@ -# $Id: h-boetes.conf,v 1.2 2009-10-25 21:45:26 nicm Exp $ -# -# From Han Boetes. - -set -g default-command zsh -set -g status-right "#(uptime|awk '{print $11}') #(date)" - -# Statusbar properties. -set -g display-time 3000 -set -g status-bg black -set -g status-fg cyan -set-window-option -g window-status-current-attr bright,reverse -set-window-option -g window-status-current-bg cyan -set-window-option -g window-status-current-fg black - -# Use c-t instead of c-b as the prefix -unbind C-b -set -g prefix C-t -bind C-t send-prefix -bind t send-prefix - -# Bind function keys. -bind -n F1 select-window -t 1 -bind -n F2 select-window -t 2 -bind -n F3 select-window -t 3 -bind -n F4 select-window -t 4 -bind -n F5 select-window -t 5 -bind -n F6 select-window -t 6 -bind -n F7 select-window -t 7 -bind -n F8 select-window -t 8 - -# All new windows started at startup. -new emacs -neww irssi -neww mutt -neww -neww -neww -neww -neww - -select-window -t 1 diff --git a/examples/n-marriott.conf b/examples/n-marriott.conf deleted file mode 100644 index 6a047ec9..00000000 --- a/examples/n-marriott.conf +++ /dev/null @@ -1,110 +0,0 @@ -# $Id: n-marriott.conf,v 1.11 2009-11-24 19:03:59 nicm Exp $ -# -# By Nicholas Marriott. Public domain. - -# Default global options. -set -g status-bg green -set -g status-right "%H:%M" # %d-%b-%y -set -g bell-action none -set -g lock-after-time 1800 - -# Default global window options. -setw -g remain-on-exit on -setw -g window-status-current-attr "underscore" -#setw -g xterm-keys on - -# Prefix key. -set -g prefix C-a -unbind C-b -bind C-a send-prefix - -# Keys to switch session. -bind Q switchc -t0 -bind W switchc -t1 -bind E switchc -t2 - -# Other key bindings. -bind F1 selectw -t:10 -bind F2 selectw -t:11 -bind F3 selectw -t:12 -bind F4 selectw -t:13 -bind F5 selectw -t:14 -bind F6 selectw -t:15 -bind F7 selectw -t:16 -bind F8 selectw -t:17 -bind F9 selectw -t:18 -bind F10 selectw -t:19 -bind F11 selectw -t:20 -bind F12 selectw -t:21 - -bind m setw monitor-activity - -bind y setw force-width 81 -bind u setw force-width 0 - -bind -n F1 run-shell 'mpc toggle >/dev/null 2>&1' -bind -n F2 run-shell 'mpc' -bind -n F3 run-shell 'mpc prev >/dev/null 2>&1' -bind -n F4 run-shell 'mpc next >/dev/null 2>&1' -bind -n F5 run-shell 'mpc volume -5 >/dev/null 2>&1' -bind -n F6 run-shell 'mpc volume +5 >/dev/null 2>&1' - -# Hide and show window name from status line -bind '-' setw window-status-format '#I'\; setw window-status-current-format '#I' -bind '+' setw window-status-format '#I:#W#F'\; setw window-status-current-format '#I:#W#F' - -# First session. -new -d -s0 -nirssi 'exec ssh -t natalya exec sh ~/bin/tmux-start' -setw -t0:0 monitor-activity on -setw -t0:0 aggressive-resize on -set -t0 status-bg green -neww -d -ntodo 'exec emacs ~/TODO' -setw -t0:1 aggressive-resize on -neww -d -ntodo2 'exec emacs ~/TODO2' -setw -t0:2 aggressive-resize on -neww -d -nncmpc 'exec ncmpc -f ~/.ncmpc.conf' -setw -t0:3 aggressive-resize on -neww -d -nmutt 'exec mutt' -setw -t0:4 aggressive-resize on -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d - -# Second session. -new -d -s1 -set -t1 status-bg cyan -linkw -dk -t0 -s0:0 -linkw -dk -t1 -s0:1 -linkw -dk -t2 -s0:2 -linkw -dk -t3 -s0:3 -linkw -dk -t4 -s0:4 -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d - -# Third session. -new -d -s2 -set -t2 status-bg yellow -linkw -dk -t0 -s0:0 -linkw -dk -t1 -s0:1 -linkw -dk -t2 -s0:2 -linkw -dk -t3 -s0:3 -linkw -dk -t4 -s0:4 -neww -d -neww -d -neww -d -neww -d -neww -d -neww -d diff --git a/examples/screen-keys.conf b/examples/screen-keys.conf deleted file mode 100644 index ce149290..00000000 --- a/examples/screen-keys.conf +++ /dev/null @@ -1,102 +0,0 @@ -# $Id: screen-keys.conf,v 1.7 2010-07-31 11:39:13 nicm Exp $ -# -# By Nicholas Marriott. Public domain. -# -# This configuration file binds many of the common GNU screen key bindings to -# appropriate tmux key bindings. Note that for some key bindings there is no -# tmux analogue and also that this set omits binding some commands available in -# tmux but not in screen. -# -# Note this is only a selection of key bindings and they are in addition to the -# normal tmux key bindings. This is intended as an example not as to be used -# as-is. - -# Set the prefix to ^A. -unbind C-b -set -g prefix ^A -bind a send-prefix - -# Bind appropriate commands similar to screen. -# lockscreen ^X x -unbind ^X -bind ^X lock-server -unbind x -bind x lock-server - -# screen ^C c -unbind ^C -bind ^C new-window -unbind c -bind c new-window - -# detach ^D d -unbind ^D -bind ^D detach - -# displays * -unbind * -bind * list-clients - -# next ^@ ^N sp n -unbind ^@ -bind ^@ next-window -unbind ^N -bind ^N next-window -unbind " " -bind " " next-window -unbind n -bind n next-window - -# title A -unbind A -bind A command-prompt "rename-window %%" - -# other ^A -unbind ^A -bind ^A last-window - -# prev ^H ^P p ^? -unbind ^H -bind ^H previous-window -unbind ^P -bind ^P previous-window -unbind p -bind p previous-window -unbind BSpace -bind BSpace previous-window - -# windows ^W w -unbind ^W -bind ^W list-windows -unbind w -bind w list-windows - -# quit \ -unbind '\' -bind '\' confirm-before "kill-server" - -# kill K k -unbind K -bind K confirm-before "kill-window" -unbind k -bind k confirm-before "kill-window" - -# redisplay ^L l -unbind ^L -bind ^L refresh-client -unbind l -bind l refresh-client - -# split -v | -unbind | -bind | split-window - -# :kB: focus up -unbind Tab -bind Tab select-pane -t:.+ -unbind BTab -bind BTab select-pane -t:.- - -# " windowlist -b -unbind '"' -bind '"' choose-window diff --git a/examples/t-williams.conf b/examples/t-williams.conf deleted file mode 100644 index 0a2cc3f5..00000000 --- a/examples/t-williams.conf +++ /dev/null @@ -1,104 +0,0 @@ -# $Id: t-williams.conf,v 1.1 2009-11-02 18:59:28 nicm Exp $ -# -# ~/.tmux.conf - tmux terminal multiplexer config -# Thayer Williams (http://cinderwick.ca) -# "Feel free to do whatever you like with it." - -# I typically start tmux from ~/.xinitrc with the following: -# -# urxvt -e bash -c "tmux attach -d -t mysession" & -# -# and recall it any time thereafter with xbindkeys (Mod4+s): -# -# "urxvt -e bash -c 'tmux attach -d -t mysession'" -# m:0x50 + c:39 - - -# set prefix key to ctrl+a until I have time to adapt -unbind C-b -set -g prefix C-a - -# send the prefix to client inside window (ala nested sessions) -bind-key a send-prefix - -# toggle last window like screen -bind-key C-a last-window - -# confirm before killing a window or the server -bind-key k confirm kill-window -bind-key K confirm kill-server - -# toggle statusbar -bind-key b set-option status - -# ctrl+left/right cycles thru windows -bind-key -n C-right next -bind-key -n C-left prev - -# open a man page in new window -bind / command-prompt "split-window 'exec man %%'" - -# quick view of processes -bind '~' split-window "exec htop" - -# scrollback buffer n lines -set -g history-limit 5000 - -# listen for activity on all windows -set -g bell-action any - -# on-screen time for display-panes in ms -set -g display-panes-time 2000 - -# start window indexing at one instead of zero -set -g base-index 1 - -# enable wm window titles -set -g set-titles on - -# wm window title string (uses statusbar variables) -set -g set-titles-string "tmux.#I.#W" - -# session initialization -new -s mysession mutt -neww -t 2 -neww -d -t 3 -neww -d -t 5 mocp -neww -d -t 6 rtorrent -selectw -t 1 - -# statusbar -------------------------------------------------------------- - -set -g display-time 2000 - -# default statusbar colors -set -g status-fg white -set -g status-bg default -set -g status-attr default - -# default window title colors -set-window-option -g window-status-fg cyan -set-window-option -g window-status-bg default -set-window-option -g window-status-attr dim - -# active window title colors -set-window-option -g window-status-current-fg white -set-window-option -g window-status-current-bg default -set-window-option -g window-status-current-attr bright - -# command/message line colors -set -g message-fg white -set -g message-bg black -set -g message-attr bright - -# center align the window list -set -g status-justify centre - -# show some useful stats but only when tmux is started -# outside of Xorg, otherwise dwm statusbar shows these already -set -g status-right "" -set -g status-left "" -if '[ -z "$DISPLAY" ]' 'set -g status-left "[#[fg=green] #H #[default]]"' -if '[ -z "$DISPLAY" ]' 'set -g status-right "[ #[fg=magenta]#(cat /proc/loadavg | cut -d \" \" -f 1,2,3)#[default] ][ #[fg=cyan,bright]%a %Y-%m-%d %H:%M #[default]]"' -if '[ -z "$DISPLAY" ]' 'set -g status-right-length 50' - diff --git a/examples/vim-keys.conf b/examples/vim-keys.conf deleted file mode 100644 index d587d0bf..00000000 --- a/examples/vim-keys.conf +++ /dev/null @@ -1,36 +0,0 @@ -# $Id: vim-keys.conf,v 1.2 2010-09-18 09:36:15 nicm Exp $ -# -# vim-keys.conf, v1.2 2010/09/12 -# -# By Daniel Thau. Public domain. -# -# This configuration file binds many vi- and vim-like bindings to the -# appropriate tmux key bindings. Note that for many key bindings there is no -# tmux analogue. This is intended for tmux 1.3, which handles pane selection -# differently from the previous versions - -# split windows like vim -# vim's definition of a horizontal/vertical split is reversed from tmux's -bind s split-window -v -bind v split-window -h - -# move around panes with hjkl, as one would in vim after pressing ctrl-w -bind h select-pane -L -bind j select-pane -D -bind k select-pane -U -bind l select-pane -R - -# resize panes like vim -# feel free to change the "1" to however many lines you want to resize by, only -# one at a time can be slow -bind < resize-pane -L 1 -bind > resize-pane -R 1 -bind - resize-pane -D 1 -bind + resize-pane -U 1 - -# bind : to command-prompt like vim -# this is the default in tmux already -bind : command-prompt - -# vi-style controls for copy mode -setw -g mode-keys vi diff --git a/examples/xterm-keys.vim b/examples/xterm-keys.vim deleted file mode 100644 index 5672c26a..00000000 --- a/examples/xterm-keys.vim +++ /dev/null @@ -1,49 +0,0 @@ -" tmux.vim - Set xterm input codes passed by tmux -" Author: Mark Oteiza -" License: Public domain -" Description: Simple plugin that assigns some xterm(1)-style keys to escape -" sequences passed by tmux when "xterm-keys" is set to "on". Inspired by an -" example given by Chris Johnsen at: -" https://stackoverflow.com/a/15471820 -" -" Documentation: help:xterm-modifier-keys man:tmux(1) - -if exists("g:loaded_tmux") || &cp - finish -endif -let g:loaded_tmux = 1 - -function! s:SetXtermCapabilities() - set ttymouse=sgr - - execute "set =\e[1;*A" - execute "set =\e[1;*B" - execute "set =\e[1;*C" - execute "set =\e[1;*D" - - execute "set =\e[1;*H" - execute "set =\e[1;*F" - - execute "set =\e[2;*~" - execute "set =\e[3;*~" - execute "set =\e[5;*~" - execute "set =\e[6;*~" - - execute "set =\e[1;*P" - execute "set =\e[1;*Q" - execute "set =\e[1;*R" - execute "set =\e[1;*S" - - execute "set =\e[15;*~" - execute "set =\e[17;*~" - execute "set =\e[18;*~" - execute "set =\e[19;*~" - execute "set =\e[20;*~" - execute "set =\e[21;*~" - execute "set =\e[23;*~" - execute "set =\e[24;*~" -endfunction - -if exists('$TMUX') - call s:SetXtermCapabilities() -endif diff --git a/format.c b/format.c index f5440b42..8d816514 100644 --- a/format.c +++ b/format.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2011 Nicholas Marriott + * Copyright (c) 2011 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -711,7 +711,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, char *copy, *copy0, *endptr, *ptr, *found, *new, *value; char *from = NULL, *to = NULL; size_t valuelen, newlen, fromlen, tolen, used; - u_long limit = 0; + long limit = 0; int modifiers = 0, brackets; /* Make a copy of the key. */ @@ -723,8 +723,8 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, switch (copy[0]) { case '=': errno = 0; - limit = strtoul(copy + 1, &endptr, 10); - if (errno == ERANGE && limit == ULONG_MAX) + limit = strtol(copy + 1, &endptr, 10); + if (errno == ERANGE && (limit == LONG_MIN || limit == LONG_MAX)) break; if (*endptr != ':') break; @@ -840,10 +840,14 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, } /* Truncate the value if needed. */ - if (limit != 0) { + if (limit > 0) { new = utf8_trimcstr(value, limit); free(value); value = new; + } else if (limit < 0) { + new = utf8_rtrimcstr(value, -limit); + free(value); + value = new; } /* Expand the buffer and copy in the value. */ diff --git a/grid-view.c b/grid-view.c index f6708c89..0989f800 100644 --- a/grid-view.c +++ b/grid-view.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/grid.c b/grid.c index 579eb966..0be0254f 100644 --- a/grid.c +++ b/grid.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,7 +37,7 @@ /* Default grid cell data. */ const struct grid_cell grid_default_cell = { - 0, 0, 8, 8, { { ' ' }, 0, 1, 1 } + 0, 0, { .fg = 8 }, { .bg = 8 }, { { ' ' }, 0, 1, 1 } }; const struct grid_cell_entry grid_default_entry = { 0, { .data = { 0, 8, 8, ' ' } } @@ -284,6 +284,7 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) struct grid_line *gl; struct grid_cell_entry *gce; struct grid_cell *gcp; + int extended; if (grid_check_y(gd, py) != 0) return; @@ -293,8 +294,12 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) gl = &gd->linedata[py]; gce = &gl->celldata[px]; - if ((gce->flags & GRID_FLAG_EXTENDED) || gc->data.size != 1 || - gc->data.width != 1) { + extended = (gce->flags & GRID_FLAG_EXTENDED); + if (!extended && (gc->data.size != 1 || gc->data.width != 1)) + extended = 1; + if (!extended && (gc->flags & (GRID_FLAG_FGRGB|GRID_FLAG_BGRGB))) + extended = 1; + if (extended) { if (~gce->flags & GRID_FLAG_EXTENDED) { gl->extddata = xreallocarray(gl->extddata, gl->extdsize + 1, sizeof *gl->extddata); @@ -447,6 +452,12 @@ grid_string_cells_fg(const struct grid_cell *gc, int *values) values[n++] = 38; values[n++] = 5; values[n++] = gc->fg; + } else if (gc->flags & GRID_FLAG_FGRGB) { + values[n++] = 38; + values[n++] = 2; + values[n++] = gc->fg_rgb.r; + values[n++] = gc->fg_rgb.g; + values[n++] = gc->fg_rgb.b; } else { switch (gc->fg) { case 0: @@ -488,6 +499,12 @@ grid_string_cells_bg(const struct grid_cell *gc, int *values) values[n++] = 48; values[n++] = 5; values[n++] = gc->bg; + } else if (gc->flags & GRID_FLAG_BGRGB) { + values[n++] = 48; + values[n++] = 2; + values[n++] = gc->bg_rgb.r; + values[n++] = gc->bg_rgb.g; + values[n++] = gc->bg_rgb.b; } else { switch (gc->bg) { case 0: @@ -527,7 +544,7 @@ void grid_string_cells_code(const struct grid_cell *lastgc, const struct grid_cell *gc, char *buf, size_t len, int escape_c0) { - int oldc[16], newc[16], s[32]; + int oldc[64], newc[64], s[128]; size_t noldc, nnewc, n, i; u_int attr = gc->attr; u_int lastattr = lastgc->attr; diff --git a/input-keys.c b/input-keys.c index e3950d7f..3968b4ac 100644 --- a/input-keys.c +++ b/input-keys.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -136,6 +136,19 @@ const struct input_key_ent input_keys[] = { { KEYC_KP_PERIOD, ".", 0 }, }; +/* Split a character into two UTF-8 bytes. */ +static size_t +input_split2(u_int c, u_char *dst) +{ + if (c > 0x7f) { + dst[0] = (c >> 6) | 0xc0; + dst[1] = (c & 0x3f) | 0x80; + return (2); + } + dst[0] = c; + return (1); +} + /* Translate a key code into an output key sequence. */ void input_key(struct window_pane *wp, key_code key, struct mouse_event *m) @@ -251,10 +264,12 @@ input_key_mouse(struct window_pane *wp, struct mouse_event *m) len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c", m->sgr_b, x + 1, y + 1, m->sgr_type); } else if (wp->screen->mode & MODE_MOUSE_UTF8) { + if (m->b > 0x7ff - 32 || x > 0x7ff - 33 || y > 0x7ff - 33) + return; len = xsnprintf(buf, sizeof buf, "\033[M"); - len += utf8_split2(m->b + 32, &buf[len]); - len += utf8_split2(x + 33, &buf[len]); - len += utf8_split2(y + 33, &buf[len]); + len += input_split2(m->b + 32, &buf[len]); + len += input_split2(x + 33, &buf[len]); + len += input_split2(y + 33, &buf[len]); } else { if (m->b > 223) return; diff --git a/input.c b/input.c index 5bc53c26..15a4fb7e 100644 --- a/input.c +++ b/input.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -100,7 +100,7 @@ struct input_ctx { struct input_transition; int input_split(struct input_ctx *); int input_get(struct input_ctx *, u_int, int, int); -void input_reply(struct input_ctx *, const char *, ...); +void printflike(2, 3) input_reply(struct input_ctx *, const char *, ...); void input_set_state(struct window_pane *, const struct input_transition *); void input_reset_cell(struct input_ctx *); @@ -1635,18 +1635,20 @@ input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i) c = input_get(ictx, *i, 0, -1); if (c == -1) { if (fgbg == 38) { - gc->flags &= ~GRID_FLAG_FG256; + gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); gc->fg = 8; } else if (fgbg == 48) { - gc->flags &= ~GRID_FLAG_BG256; + gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB); gc->bg = 8; } } else { if (fgbg == 38) { gc->flags |= GRID_FLAG_FG256; + gc->flags &= ~GRID_FLAG_FGRGB; gc->fg = c; } else if (fgbg == 48) { gc->flags |= GRID_FLAG_BG256; + gc->flags &= ~GRID_FLAG_BGRGB; gc->bg = c; } } @@ -1657,7 +1659,7 @@ void input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i) { struct grid_cell *gc = &ictx->cell.cell; - int c, r, g, b; + int r, g, b; (*i)++; r = input_get(ictx, *i, 0, -1); @@ -1672,13 +1674,18 @@ input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i) if (b == -1 || b > 255) return; - c = colour_find_rgb(r, g, b); if (fgbg == 38) { - gc->flags |= GRID_FLAG_FG256; - gc->fg = c; + gc->flags &= ~GRID_FLAG_FG256; + gc->flags |= GRID_FLAG_FGRGB; + gc->fg_rgb.r = r; + gc->fg_rgb.g = g; + gc->fg_rgb.b = b; } else if (fgbg == 48) { - gc->flags |= GRID_FLAG_BG256; - gc->bg = c; + gc->flags &= ~GRID_FLAG_BG256; + gc->flags |= GRID_FLAG_BGRGB; + gc->bg_rgb.r = r; + gc->bg_rgb.g = g; + gc->bg_rgb.b = b; } } @@ -1760,11 +1767,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) case 35: case 36: case 37: - gc->flags &= ~GRID_FLAG_FG256; + gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); gc->fg = n - 30; break; case 39: - gc->flags &= ~GRID_FLAG_FG256; + gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); gc->fg = 8; break; case 40: @@ -1775,11 +1782,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) case 45: case 46: case 47: - gc->flags &= ~GRID_FLAG_BG256; + gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB); gc->bg = n - 40; break; case 49: - gc->flags &= ~GRID_FLAG_BG256; + gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB); gc->bg = 8; break; case 90: @@ -1790,7 +1797,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) case 95: case 96: case 97: - gc->flags &= ~GRID_FLAG_FG256; + gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); gc->fg = n; break; case 100: @@ -1801,7 +1808,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) case 105: case 106: case 107: - gc->flags &= ~GRID_FLAG_BG256; + gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB); gc->bg = n - 10; break; } @@ -1959,8 +1966,14 @@ input_utf8_close(struct input_ctx *ictx) { struct utf8_data *ud = &ictx->utf8data; - if (utf8_append(ud, ictx->ch) != UTF8_DONE) - fatalx("UTF-8 close invalid %#x", ictx->ch); + if (utf8_append(ud, ictx->ch) != UTF8_DONE) { + /* + * An error here could be invalid UTF-8 or it could be a + * nonprintable character for which we can't get the + * width. Drop it. + */ + return (0); + } log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size, (int)ud->size, ud->data, ud->width); diff --git a/job.c b/job.c index df828805..90685dbd 100644 --- a/job.c +++ b/job.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/key-bindings.c b/key-bindings.c index 47a7d867..0d13385d 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -68,12 +68,12 @@ void key_bindings_unref_table(struct key_table *table) { struct key_binding *bd; + struct key_binding *bd1; if (--table->references != 0) return; - while (!RB_EMPTY(&table->key_bindings)) { - bd = RB_ROOT(&table->key_bindings); + RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1) { RB_REMOVE(key_bindings, &table->key_bindings, bd); cmd_list_free(bd->cmdlist); free(bd); diff --git a/key-string.c b/key-string.c index 1ff3ca30..119035a0 100644 --- a/key-string.c +++ b/key-string.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -93,6 +93,9 @@ const struct { KEYC_MOUSE_STRING(MOUSEDRAG1, MouseDrag1), KEYC_MOUSE_STRING(MOUSEDRAG2, MouseDrag2), KEYC_MOUSE_STRING(MOUSEDRAG3, MouseDrag3), + KEYC_MOUSE_STRING(MOUSEDRAGEND1, MouseDragEnd1), + KEYC_MOUSE_STRING(MOUSEDRAGEND2, MouseDragEnd2), + KEYC_MOUSE_STRING(MOUSEDRAGEND3, MouseDragEnd3), KEYC_MOUSE_STRING(WHEELUP, WheelUp), KEYC_MOUSE_STRING(WHEELDOWN, WheelDown), }; @@ -149,6 +152,7 @@ key_string_lookup_string(const char *string) struct utf8_data ud; u_int i; enum utf8_state more; + wchar_t wc; /* Is this no key? */ if (strcasecmp(string, "None") == 0) @@ -185,8 +189,9 @@ key_string_lookup_string(const char *string) more = utf8_append(&ud, (u_char)string[i]); if (more != UTF8_DONE) return (KEYC_UNKNOWN); - key = utf8_combine(&ud); - return (key | modifiers); + if (utf8_combine(&ud, &wc) != UTF8_DONE) + return (KEYC_UNKNOWN); + return (wc | modifiers); } /* Otherwise look the key up in the table. */ diff --git a/layout-custom.c b/layout-custom.c index 3215c9a1..6aadc8ee 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2010 Nicholas Marriott + * Copyright (c) 2010 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/layout-set.c b/layout-set.c index 3ef82461..5ae96bd1 100644 --- a/layout-set.c +++ b/layout-set.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/layout.c b/layout.c index 1b15f76c..a609a85a 100644 --- a/layout.c +++ b/layout.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/log.c b/log.c index 21c7397d..7a653db7 100644 --- a/log.c +++ b/log.c @@ -1,7 +1,7 @@ /* $Id$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/mode-key.c b/mode-key.c index a47cda0b..aed161bb 100644 --- a/mode-key.c +++ b/mode-key.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -347,6 +347,7 @@ const struct mode_key_entry mode_key_vi_copy[] = { { KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP }, { KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN }, { KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION }, + { KEYC_MOUSEDRAGEND1_PANE, 0, MODEKEYCOPY_COPYSELECTION }, { 0, -1, 0 } }; @@ -495,6 +496,7 @@ const struct mode_key_entry mode_key_emacs_copy[] = { { KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP }, { KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN }, { KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION }, + { KEYC_MOUSEDRAGEND1_PANE, 0, MODEKEYCOPY_COPYSELECTION }, { 0, -1, 0 } }; diff --git a/names.c b/names.c index b0b85229..d236ab2b 100644 --- a/names.c +++ b/names.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/options-table.c b/options-table.c index 919b7127..254a2698 100644 --- a/options-table.c +++ b/options-table.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2011 Nicholas Marriott + * Copyright (c) 2011 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/options.c b/options.c index 02f0f957..df79ac4b 100644 --- a/options.c +++ b/options.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-aix.c b/osdep-aix.c index ef7d6c7e..e1ce4918 100644 --- a/osdep-aix.c +++ b/osdep-aix.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2011 Nicholas Marriott + * Copyright (c) 2011 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-cygwin.c b/osdep-cygwin.c index 9a3ea408..60630b33 100644 --- a/osdep-cygwin.c +++ b/osdep-cygwin.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-dragonfly.c b/osdep-dragonfly.c index f9b0efcf..879034e8 100644 --- a/osdep-dragonfly.c +++ b/osdep-dragonfly.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-freebsd.c b/osdep-freebsd.c index d7f419b8..067ba565 100644 --- a/osdep-freebsd.c +++ b/osdep-freebsd.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-hpux.c b/osdep-hpux.c index a6d75f94..16993b93 100644 --- a/osdep-hpux.c +++ b/osdep-hpux.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-linux.c b/osdep-linux.c index 00501efb..42712dea 100644 --- a/osdep-linux.c +++ b/osdep-linux.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-netbsd.c b/osdep-netbsd.c index 15686860..d8aa41b5 100644 --- a/osdep-netbsd.c +++ b/osdep-netbsd.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-openbsd.c b/osdep-openbsd.c index 414228b7..1de876a4 100644 --- a/osdep-openbsd.c +++ b/osdep-openbsd.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/osdep-unknown.c b/osdep-unknown.c index 9465db97..bc59f569 100644 --- a/osdep-unknown.c +++ b/osdep-unknown.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/paste.c b/paste.c index d43829a2..e4eae877 100644 --- a/paste.c +++ b/paste.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/proc.c b/proc.c index 729ffa15..6f611fc8 100644 --- a/proc.c +++ b/proc.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2015 Nicholas Marriott + * Copyright (c) 2015 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/resize.c b/resize.c index cf882570..7650eb06 100644 --- a/resize.c +++ b/resize.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/screen-redraw.c b/screen-redraw.c index 948d1fc2..c88c504b 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/screen-write.c b/screen-write.c index e53d3799..e58d744c 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -994,7 +994,9 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) utf8_copy(&tmp_gc.data, &gc->data); tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; - tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); + tmp_gc.flags = gc->flags; + tmp_gc.flags &= ~(GRID_FLAG_FGRGB|GRID_FLAG_BGRGB); + tmp_gc.flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmp_gc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); ttyctx.cell = &tmp_gc; diff --git a/screen.c b/screen.c index db9f52a6..e002b96e 100644 --- a/screen.c +++ b/screen.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/server-client.c b/server-client.c index f6d8c18a..a3045e3b 100644 --- a/server-client.c +++ b/server-client.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -406,8 +406,42 @@ server_client_check_mouse(struct client *c) c->tty.mouse_drag_update = NULL; c->tty.mouse_drag_release = NULL; + /* + * End a mouse drag by passing a MouseDragEnd key corresponding + * to the button that started the drag. + */ + switch (c->tty.mouse_drag_flag) { + case 1: + if (where == PANE) + key = KEYC_MOUSEDRAGEND1_PANE; + if (where == STATUS) + key = KEYC_MOUSEDRAGEND1_STATUS; + if (where == BORDER) + key = KEYC_MOUSEDRAGEND1_BORDER; + break; + case 2: + if (where == PANE) + key = KEYC_MOUSEDRAGEND2_PANE; + if (where == STATUS) + key = KEYC_MOUSEDRAGEND2_STATUS; + if (where == BORDER) + key = KEYC_MOUSEDRAGEND2_BORDER; + break; + case 3: + if (where == PANE) + key = KEYC_MOUSEDRAGEND3_PANE; + if (where == STATUS) + key = KEYC_MOUSEDRAGEND3_STATUS; + if (where == BORDER) + key = KEYC_MOUSEDRAGEND3_BORDER; + break; + default: + key = KEYC_MOUSE; + break; + } c->tty.mouse_drag_flag = 0; - return (KEYC_MOUSE); /* not a key, but still may want to pass */ + + return (key); } /* Convert to a key binding. */ @@ -447,7 +481,11 @@ server_client_check_mouse(struct client *c) } } - c->tty.mouse_drag_flag = 1; + /* + * Begin a drag by setting the flag to a non-zero value that + * corresponds to the mouse button in use. + */ + c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1; break; case WHEEL: if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) { diff --git a/server-fn.c b/server-fn.c index 915ebc68..a09a16fb 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/server.c b/server.c index df8d01c4..9affa75c 100644 --- a/server.c +++ b/server.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/session.c b/session.c index c19dfbea..b972ef55 100644 --- a/session.c +++ b/session.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/signal.c b/signal.c index eb512941..5ca0f77b 100644 --- a/signal.c +++ b/signal.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * Copyright (c) 2010 Romain Francoise * * Permission to use, copy, modify, and distribute this software for any diff --git a/status.c b/status.c index 6c66280a..fcb3a579 100644 --- a/status.c +++ b/status.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/style.c b/style.c index c00b0fee..151c2912 100644 --- a/style.c +++ b/style.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * Copyright (c) 2014 Tiago Cunha * * Permission to use, copy, modify, and distribute this software for any diff --git a/tmux.1 b/tmux.1 index f3c8066d..776b6faf 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,6 +1,6 @@ .\" $OpenBSD$ .\" -.\" Copyright (c) 2007 Nicholas Marriott +.\" Copyright (c) 2007 Nicholas Marriott .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -721,7 +721,7 @@ will set the session working directory (used for new windows) to .Pp If .Fl E -is used, +is used, the .Ic update-environment option will not be applied. .It Xo Ic detach-client @@ -857,13 +857,12 @@ with .Ar target-session . This means they share the same set of windows - all windows from .Ar target-session -are linked to the new session and any subsequent new windows or windows being -closed are applied to both sessions. +are linked to the new session, any new windows are linked to both sessions and +any windows closed removed from both sessions. The current and previous window and any session options remain independent and either session may be killed without affecting the other. -Giving .Fl n -or +and .Ar shell-command are invalid if .Fl t @@ -879,7 +878,7 @@ but a different format may be specified with .Pp If .Fl E -is used, +is used, the .Ic update-environment option will not be applied. .It Xo Ic refresh-client @@ -1254,7 +1253,7 @@ Commands related to windows and panes are as follows: .Op Fl dP .Op Fl F Ar format .Op Fl s Ar src-pane -.Op Fl t Ar dst-pane +.Op Fl t Ar dst-window .Xc .D1 (alias: Ic breakp ) Break @@ -2925,7 +2924,7 @@ and poor for interactive programs such as shells. .Op Ic on | off .Xc Allow programs to change the window name using a terminal escape -sequence (\\033k...\\033\\\\). +sequence (\eek...\ee\e\e). The default is on. .Pp .It Xo Ic alternate-screen @@ -3228,6 +3227,16 @@ Each hook has a .Em name . The following hooks are available: .Bl -tag -width "XXXXXXXXXXXXXXXX" +.It alert-activity +Run when a window has activity. +See +.Ic monitor-activity . +.It alert-bell +Run when a window has received a bell. +.It alert-silence +Run when a window has been silent. +See +.Ic monitor-silence . .It client-attached Run when a client is attached. .It client-detached @@ -3289,10 +3298,10 @@ for a pane border or for the status line). The following mouse events are available: .Bl -column "MouseDown1" "MouseDrag1" "WheelDown" -offset indent -.It Li "MouseDown1" Ta "MouseUp1" Ta "MouseDrag1" -.It Li "MouseDown2" Ta "MouseUp2" Ta "MouseDrag2" -.It Li "MouseDown3" Ta "MouseUp3" Ta "MouseDrag3" -.It Li "WheelUp" Ta "WheelDown" Ta "" +.It Li "MouseDown1" Ta "MouseUp1" Ta "MouseDrag1" Ta "MouseDragEnd1" +.It Li "MouseDown2" Ta "MouseUp2" Ta "MouseDrag2" Ta "MouseDragEnd2" +.It Li "MouseDown3" Ta "MouseUp3" Ta "MouseDrag3" Ta "MouseDragEnd3" +.It Li "WheelUp" Ta "WheelDown" Ta "" Ta "" .El .Pp Each should be suffixed with a location, for example @@ -3371,9 +3380,13 @@ if not. A limit may be placed on the length of the resultant string by prefixing it by an .Ql = , -a number and a colon, so -.Ql #{=10:pane_title} -will include at most the first 10 characters of the pane title. +a number and a colon. +Positive numbers count from the start of the string and negative from the end, +so +.Ql #{=5:pane_title} +will include at most the first 5 characters of the pane title, or +.Ql #{=-5:pane_title} +the last 5 characters. Prefixing a time variable with .Ql t: will convert it to a string, so if @@ -4019,7 +4032,7 @@ This command only works from outside .El .Sh TERMINFO EXTENSIONS .Nm -understands some extensions to +understands some unofficial extensions to .Xr terminfo 5 : .Bl -tag -width Ds .It Em Cs , Cr @@ -4043,10 +4056,12 @@ $ printf '\e033[4 q' If .Em Se is not set, \&Ss with argument 0 will be used to reset the cursor style instead. +.It Em \&Tc +Indicate that the terminal supports the +.Ql direct colour +RGB escape sequence (for example, \ee[38;2;255;255;255m). .It Em \&Ms -This sequence can be used by -.Nm -to store the current buffer in the host terminal's selection (clipboard). +Store the current buffer in the host terminal's selection (clipboard). See the .Em set-clipboard option above and the @@ -4243,4 +4258,4 @@ bind-key S command-prompt "new-window -n %1 'ssh %1'" .Sh SEE ALSO .Xr pty 4 .Sh AUTHORS -.An Nicholas Marriott Aq Mt nicm@users.sourceforge.net +.An Nicholas Marriott Aq Mt nicholas.marriott@gmail.com diff --git a/tmux.c b/tmux.c index eec04c93..0a7d88ff 100644 --- a/tmux.c +++ b/tmux.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -33,10 +35,6 @@ #include "tmux.h" #include "tmate.h" -#if defined(DEBUG) && defined(__OpenBSD__) -extern char *malloc_options; -#endif - struct options *global_options; /* server options */ struct options *global_s_options; /* session options */ struct options *global_w_options; /* window options */ @@ -202,9 +200,14 @@ main(int argc, char **argv) const char *s; int opt, flags, keys; -#if defined(DEBUG) && defined(__OpenBSD__) - malloc_options = (char *) "AFGJPX"; -#endif + if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) { + if (setlocale(LC_CTYPE, "") == NULL) + errx(1, "invalid LC_ALL, LC_CTYPE or LANG"); + s = nl_langinfo(CODESET); + if (strcasecmp(s, "UTF-8") != 0 && + strcasecmp(s, "UTF8") != 0) + errx(1, "need UTF-8 locale (LC_CTYPE) but have %s", s); + } setlocale(LC_TIME, ""); tzset(); diff --git a/tmux.h b/tmux.h index 1761c954..4fd1bbb0 100644 --- a/tmux.h +++ b/tmux.h @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef HAVE_UTEMPTER #include @@ -138,6 +139,9 @@ enum { KEYC_MOUSE_KEY(MOUSEDRAG1), KEYC_MOUSE_KEY(MOUSEDRAG2), KEYC_MOUSE_KEY(MOUSEDRAG3), + KEYC_MOUSE_KEY(MOUSEDRAGEND1), + KEYC_MOUSE_KEY(MOUSEDRAGEND2), + KEYC_MOUSE_KEY(MOUSEDRAGEND3), KEYC_MOUSE_KEY(WHEELUP), KEYC_MOUSE_KEY(WHEELDOWN), @@ -389,6 +393,7 @@ enum tty_code_code { TTYC_SMSO, /* enter_standout_mode, so */ TTYC_SMUL, /* enter_underline_mode, us */ TTYC_SS, /* set cursor style, Ss */ + TTYC_TC, /* 24-bit "true" colour, Tc */ TTYC_TSL, /* to_status_line, tsl */ TTYC_VPA, /* row_address, cv */ TTYC_XENL, /* eat_newline_glitch, xn */ @@ -656,16 +661,31 @@ enum utf8_state { #define GRID_FLAG_BG256 0x2 #define GRID_FLAG_PADDING 0x4 #define GRID_FLAG_EXTENDED 0x8 +#define GRID_FLAG_FGRGB 0x10 +#define GRID_FLAG_BGRGB 0x20 /* Grid line flags. */ #define GRID_LINE_WRAPPED 0x1 +/* Grid cell RGB colours. */ +struct grid_cell_rgb { + u_char r; + u_char g; + u_char b; +}; + /* Grid cell data. */ struct grid_cell { u_char flags; u_char attr; - u_char fg; - u_char bg; + union { + u_char fg; + struct grid_cell_rgb fg_rgb; + }; + union { + u_char bg; + struct grid_cell_rgb bg_rgb; + }; struct utf8_data data; }; @@ -1585,7 +1605,7 @@ extern struct client *cfg_client; void start_cfg(void); int load_cfg(const char *, struct cmd_q *, char **); void set_cfg_file(const char *); -void cfg_add_cause(const char *, ...); +void printflike(1, 2) cfg_add_cause(const char *, ...); void cfg_print_causes(struct cmd_q *); void cfg_show_causes(struct session *); @@ -1814,8 +1834,11 @@ long long args_strtonum(struct args *, u_char, long long, long long, char **); /* cmd-find.c */ -int cmd_find_target(struct cmd_find_state *, struct cmd_q *, - const char *, enum cmd_find_type, int); +int cmd_find_current(struct cmd_find_state *, struct cmd_q *, + int); +int cmd_find_target(struct cmd_find_state *, + struct cmd_find_state *, struct cmd_q *, const char *, + enum cmd_find_type, int); struct client *cmd_find_client(struct cmd_q *, const char *, int); void cmd_find_clear_state(struct cmd_find_state *, struct cmd_q *, int); @@ -1825,6 +1848,8 @@ void cmd_find_copy_state(struct cmd_find_state *, void cmd_find_log_state(const char *, struct cmd_find_state *); int cmd_find_from_session(struct cmd_find_state *, struct session *); +int cmd_find_from_winlink(struct cmd_find_state *, + struct session *, struct winlink *); int cmd_find_from_window(struct cmd_find_state *, struct window *); int cmd_find_from_pane(struct cmd_find_state *, struct window_pane *); @@ -1836,7 +1861,8 @@ char **cmd_copy_argv(int, char **); void cmd_free_argv(int, char **); char *cmd_stringify_argv(int, char **); struct cmd *cmd_parse(int, char **, const char *, u_int, char **); -int cmd_prepare_state(struct cmd *, struct cmd_q *); +int cmd_prepare_state(struct cmd *, struct cmd_q *, + struct cmd_q *); char *cmd_print(struct cmd *); int cmd_mouse_at(struct window_pane *, struct mouse_event *, u_int *, u_int *, int); @@ -2336,19 +2362,18 @@ void session_group_synchronize1(struct session *, struct session *); void session_renumber_windows(struct session *); /* utf8.c */ -u_int utf8_width(u_int); void utf8_set(struct utf8_data *, u_char); void utf8_copy(struct utf8_data *, const struct utf8_data *); enum utf8_state utf8_open(struct utf8_data *, u_char); enum utf8_state utf8_append(struct utf8_data *, u_char); -u_int utf8_combine(const struct utf8_data *); -enum utf8_state utf8_split(u_int, struct utf8_data *); -u_int utf8_split2(u_int, u_char *); +enum utf8_state utf8_combine(const struct utf8_data *, wchar_t *); +enum utf8_state utf8_split(wchar_t, struct utf8_data *); int utf8_strvis(char *, const char *, size_t, int); char *utf8_sanitize(const char *); struct utf8_data *utf8_fromcstr(const char *); char *utf8_tocstr(struct utf8_data *); u_int utf8_cstrwidth(const char *); +char *utf8_rtrimcstr(const char *, u_int); char *utf8_trimcstr(const char *, u_int); char *utf8_padcstr(const char *, u_int); diff --git a/tty-acs.c b/tty-acs.c index 5d03c3eb..7fd265d4 100644 --- a/tty-acs.c +++ b/tty-acs.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2010 Nicholas Marriott + * Copyright (c) 2010 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tty-keys.c b/tty-keys.c index 86839a17..105f99f7 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -477,6 +477,7 @@ tty_keys_next(struct tty *tty) struct utf8_data ud; enum utf8_state more; u_int i; + wchar_t wc; /* Get key buffer. */ buf = EVBUFFER_DATA(tty->event->input); @@ -552,7 +553,11 @@ first_key: more = utf8_append(&ud, (u_char)buf[i]); if (more != UTF8_DONE) goto discard_key; - key = utf8_combine(&ud); + + if (utf8_combine(&ud, &wc) != UTF8_DONE) + goto discard_key; + key = wc; + log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key); goto complete_key; } diff --git a/tty-term.c b/tty-term.c index 59438d3e..839e34ba 100644 --- a/tty-term.c +++ b/tty-term.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -254,6 +254,7 @@ const struct tty_term_code_entry tty_term_codes[] = { [TTYC_SMSO] = { TTYCODE_STRING, "smso" }, [TTYC_SMUL] = { TTYCODE_STRING, "smul" }, [TTYC_SS] = { TTYCODE_STRING, "Ss" }, + [TTYC_TC] = { TTYCODE_FLAG, "Tc" }, [TTYC_TSL] = { TTYCODE_STRING, "tsl" }, [TTYC_VPA] = { TTYCODE_STRING, "vpa" }, [TTYC_XENL] = { TTYCODE_FLAG, "xenl" }, diff --git a/tty.c b/tty.c index 9a4bfaa3..5a13e57b 100644 --- a/tty.c +++ b/tty.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -37,8 +37,15 @@ static int tty_log_fd = -1; void tty_read_callback(struct bufferevent *, void *); void tty_error_callback(struct bufferevent *, short, void *); +static int tty_same_fg(const struct grid_cell *, const struct grid_cell *); +static int tty_same_bg(const struct grid_cell *, const struct grid_cell *); +static int tty_same_colours(const struct grid_cell *, const struct grid_cell *); +static int tty_is_fg(const struct grid_cell *, int); +static int tty_is_bg(const struct grid_cell *, int); + void tty_set_italics(struct tty *); int tty_try_256(struct tty *, u_char, const char *); +int tty_try_rgb(struct tty *, const struct grid_cell_rgb *, const char *); void tty_colours(struct tty *, const struct grid_cell *); void tty_check_fg(struct tty *, struct grid_cell *); @@ -62,6 +69,74 @@ void tty_default_colours(struct grid_cell *, const struct window_pane *); #define tty_pane_full_width(tty, ctx) \ ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) +static int +tty_same_fg(const struct grid_cell *gc1, const struct grid_cell *gc2) +{ + int flags1, flags2; + + flags1 = (gc1->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)); + flags2 = (gc2->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)); + + if (flags1 != flags2) + return (0); + + if (flags1 & GRID_FLAG_FGRGB) { + if (gc1->fg_rgb.r != gc2->fg_rgb.r) + return (0); + if (gc1->fg_rgb.g != gc2->fg_rgb.g) + return (0); + if (gc1->fg_rgb.b != gc2->fg_rgb.b) + return (0); + return (1); + } + return (gc1->fg == gc2->fg); +} + +static int +tty_same_bg(const struct grid_cell *gc1, const struct grid_cell *gc2) +{ + int flags1, flags2; + + flags1 = (gc1->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)); + flags2 = (gc2->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)); + + if (flags1 != flags2) + return (0); + + if (flags1 & GRID_FLAG_BGRGB) { + if (gc1->bg_rgb.r != gc2->bg_rgb.r) + return (0); + if (gc1->bg_rgb.g != gc2->bg_rgb.g) + return (0); + if (gc1->bg_rgb.b != gc2->bg_rgb.b) + return (0); + return (1); + } + return (gc1->bg == gc2->bg); +} + +static int +tty_same_colours(const struct grid_cell *gc1, const struct grid_cell *gc2) +{ + return (tty_same_fg(gc1, gc2) && tty_same_bg(gc1, gc2)); +} + +static int +tty_is_fg(const struct grid_cell *gc, int c) +{ + if (gc->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)) + return (0); + return (gc->fg == c); +} + +static int +tty_is_bg(const struct grid_cell *gc, int c) +{ + if (gc->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)) + return (0); + return (gc->bg == c); +} + void tty_create_log(void) { @@ -1428,12 +1503,10 @@ void tty_colours(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell; - u_char fg = gc->fg, bg = gc->bg, flags = gc->flags; int have_ax, fg_default, bg_default; /* No changes? Nothing is necessary. */ - if (fg == tc->fg && bg == tc->bg && - ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) + if (tty_same_colours(gc, tc)) return; /* @@ -1442,8 +1515,8 @@ tty_colours(struct tty *tty, const struct grid_cell *gc) * case if only one is default need to fall onward to set the other * colour. */ - fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256)); - bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256)); + fg_default = tty_is_fg(gc, 8); + bg_default = tty_is_bg(gc, 8); if (fg_default || bg_default) { /* * If don't have AX but do have op, send sgr0 (op can't @@ -1456,48 +1529,54 @@ tty_colours(struct tty *tty, const struct grid_cell *gc) if (!have_ax && tty_term_has(tty->term, TTYC_OP)) tty_reset(tty); else { - if (fg_default && - (tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) { + if (fg_default && !tty_is_fg(tc, 8)) { if (have_ax) tty_puts(tty, "\033[39m"); - else if (tc->fg != 7 || - tc->flags & GRID_FLAG_FG256) + else if (!tty_is_fg(tc, 7)) tty_putcode1(tty, TTYC_SETAF, 7); tc->fg = 8; - tc->flags &= ~GRID_FLAG_FG256; + tc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); } - if (bg_default && - (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) { + if (bg_default && !tty_is_bg(tc, 8)) { if (have_ax) tty_puts(tty, "\033[49m"); - else if (tc->bg != 0 || - tc->flags & GRID_FLAG_BG256) + else if (!tty_is_bg(tc, 0)) tty_putcode1(tty, TTYC_SETAB, 0); tc->bg = 8; - tc->flags &= ~GRID_FLAG_BG256; + tc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB); } } } /* Set the foreground colour. */ - if (!fg_default && (fg != tc->fg || - ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) + if (!fg_default && !tty_same_fg(gc, tc)) tty_colours_fg(tty, gc); /* * Set the background colour. This must come after the foreground as * tty_colour_fg() can call tty_reset(). */ - if (!bg_default && (bg != tc->bg || - ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) + if (!bg_default && !tty_same_bg(gc, tc)) tty_colours_bg(tty, gc); } void tty_check_fg(struct tty *tty, struct grid_cell *gc) { - u_int colours; + struct grid_cell_rgb *rgb = &gc->fg_rgb; + u_int colours; + /* Is this a 24-bit colour? */ + if (gc->flags & GRID_FLAG_FGRGB) { + /* Not a 24-bit terminal? Translate to 256-colour palette. */ + if (!tty_term_flag(tty->term, TTYC_TC)) { + gc->flags &= ~GRID_FLAG_FGRGB; + gc->flags |= GRID_FLAG_FG256; + gc->fg = colour_find_rgb(rgb->r, rgb->g, rgb->b); + } + else + return; + } colours = tty_term_number(tty->term, TTYC_COLORS); /* Is this a 256-colour colour? */ @@ -1529,8 +1608,20 @@ tty_check_fg(struct tty *tty, struct grid_cell *gc) void tty_check_bg(struct tty *tty, struct grid_cell *gc) { - u_int colours; + struct grid_cell_rgb *rgb = &gc->bg_rgb; + u_int colours; + /* Is this a 24-bit colour? */ + if (gc->flags & GRID_FLAG_BGRGB) { + /* Not a 24-bit terminal? Translate to 256-colour palette. */ + if (!tty_term_flag(tty->term, TTYC_TC)) { + gc->flags &= ~GRID_FLAG_BGRGB; + gc->flags |= GRID_FLAG_BG256; + gc->bg = colour_find_rgb(rgb->r, rgb->g, rgb->b); + } + else + return; + } colours = tty_term_number(tty->term, TTYC_COLORS); /* Is this a 256-colour colour? */ @@ -1565,12 +1656,21 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc) u_char fg = gc->fg; char s[32]; + tc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); + + /* Is this a 24-bit colour? */ + if (gc->flags & GRID_FLAG_FGRGB) { + if (tty_try_rgb(tty, &gc->fg_rgb, "38") == 0) + goto save_fg; + /* Should not get here, already converted in tty_check_fg. */ + return; + } + /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_FG256) { - /* Try as 256 colours. */ if (tty_try_256(tty, fg, "38") == 0) goto save_fg; - /* Else already handled by tty_check_fg. */ + /* Should not get here, already converted in tty_check_fg. */ return; } @@ -1586,9 +1686,12 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc) save_fg: /* Save the new values in the terminal current cell. */ - tc->fg = fg; - tc->flags &= ~GRID_FLAG_FG256; - tc->flags |= gc->flags & GRID_FLAG_FG256; + if (gc->flags & GRID_FLAG_FGRGB) + memcpy(&tc->fg_rgb, &gc->fg_rgb, sizeof tc->fg_rgb); + else + tc->fg = fg; + tc->flags &= ~(GRID_FLAG_FGRGB|GRID_FLAG_FG256); + tc->flags |= (gc->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)); } void @@ -1598,12 +1701,19 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) u_char bg = gc->bg; char s[32]; + /* Is this a 24-bit colour? */ + if (gc->flags & GRID_FLAG_BGRGB) { + if (tty_try_rgb(tty, &gc->bg_rgb, "48") == 0) + goto save_bg; + /* Should not get here, already converted in tty_check_bg. */ + return; + } + /* Is this a 256-colour colour? */ if (gc->flags & GRID_FLAG_BG256) { - /* Try as 256 colours. */ if (tty_try_256(tty, bg, "48") == 0) goto save_bg; - /* Else already handled by tty_check_bg. */ + /* Should not get here, already converted in tty_check_bg. */ return; } @@ -1619,9 +1729,12 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc) save_bg: /* Save the new values in the terminal current cell. */ - tc->bg = bg; - tc->flags &= ~GRID_FLAG_BG256; - tc->flags |= gc->flags & GRID_FLAG_BG256; + if (gc->flags & GRID_FLAG_BGRGB) + memcpy(&tc->bg_rgb, &gc->bg_rgb, sizeof tc->bg_rgb); + else + tc->bg = bg; + tc->flags &= ~(GRID_FLAG_BGRGB|GRID_FLAG_BG256); + tc->flags |= (gc->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)); } int @@ -1661,6 +1774,20 @@ fallback: return (0); } +int +tty_try_rgb(struct tty *tty, const struct grid_cell_rgb *rgb, const char *type) +{ + char s[32]; + + if (!tty_term_flag(tty->term, TTYC_TC)) + return (-1); + + xsnprintf(s, sizeof s, "\033[%s;2;%hhu;%hhu;%hhum", type, rgb->r, + rgb->g, rgb->b); + tty_puts(tty, s); + return (0); +} + void tty_default_colours(struct grid_cell *gc, const struct window_pane *wp) { diff --git a/utf8.c b/utf8.c index ad99edce..c0407576 100644 --- a/utf8.c +++ b/utf8.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2008 Nicholas Marriott + * Copyright (c) 2008 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,332 +20,11 @@ #include #include +#include #include "tmux.h" -struct utf8_width_entry { - u_int first; - u_int last; - - int width; - - struct utf8_width_entry *left; - struct utf8_width_entry *right; -}; - -/* Sorted, then repeatedly split in the middle to balance the tree. */ -static struct utf8_width_entry utf8_width_table[] = { - { 0x00b41, 0x00b44, 0, NULL, NULL }, - { 0x008e4, 0x00902, 0, NULL, NULL }, - { 0x006d6, 0x006dd, 0, NULL, NULL }, - { 0x005c4, 0x005c5, 0, NULL, NULL }, - { 0x00591, 0x005bd, 0, NULL, NULL }, - { 0x00300, 0x0036f, 0, NULL, NULL }, - { 0x00483, 0x00489, 0, NULL, NULL }, - { 0x005bf, 0x005bf, 0, NULL, NULL }, - { 0x005c1, 0x005c2, 0, NULL, NULL }, - { 0x00610, 0x0061a, 0, NULL, NULL }, - { 0x00600, 0x00605, 0, NULL, NULL }, - { 0x005c7, 0x005c7, 0, NULL, NULL }, - { 0x0064b, 0x0065f, 0, NULL, NULL }, - { 0x0061c, 0x0061c, 0, NULL, NULL }, - { 0x00670, 0x00670, 0, NULL, NULL }, - { 0x007a6, 0x007b0, 0, NULL, NULL }, - { 0x006ea, 0x006ed, 0, NULL, NULL }, - { 0x006df, 0x006e4, 0, NULL, NULL }, - { 0x006e7, 0x006e8, 0, NULL, NULL }, - { 0x00711, 0x00711, 0, NULL, NULL }, - { 0x0070f, 0x0070f, 0, NULL, NULL }, - { 0x00730, 0x0074a, 0, NULL, NULL }, - { 0x0081b, 0x00823, 0, NULL, NULL }, - { 0x007eb, 0x007f3, 0, NULL, NULL }, - { 0x00816, 0x00819, 0, NULL, NULL }, - { 0x00829, 0x0082d, 0, NULL, NULL }, - { 0x00825, 0x00827, 0, NULL, NULL }, - { 0x00859, 0x0085b, 0, NULL, NULL }, - { 0x00a41, 0x00a42, 0, NULL, NULL }, - { 0x00981, 0x00981, 0, NULL, NULL }, - { 0x00941, 0x00948, 0, NULL, NULL }, - { 0x0093a, 0x0093a, 0, NULL, NULL }, - { 0x0093c, 0x0093c, 0, NULL, NULL }, - { 0x00951, 0x00957, 0, NULL, NULL }, - { 0x0094d, 0x0094d, 0, NULL, NULL }, - { 0x00962, 0x00963, 0, NULL, NULL }, - { 0x009e2, 0x009e3, 0, NULL, NULL }, - { 0x009c1, 0x009c4, 0, NULL, NULL }, - { 0x009bc, 0x009bc, 0, NULL, NULL }, - { 0x009cd, 0x009cd, 0, NULL, NULL }, - { 0x00a01, 0x00a02, 0, NULL, NULL }, - { 0x00a3c, 0x00a3c, 0, NULL, NULL }, - { 0x00ac1, 0x00ac5, 0, NULL, NULL }, - { 0x00a70, 0x00a71, 0, NULL, NULL }, - { 0x00a4b, 0x00a4d, 0, NULL, NULL }, - { 0x00a47, 0x00a48, 0, NULL, NULL }, - { 0x00a51, 0x00a51, 0, NULL, NULL }, - { 0x00a81, 0x00a82, 0, NULL, NULL }, - { 0x00a75, 0x00a75, 0, NULL, NULL }, - { 0x00abc, 0x00abc, 0, NULL, NULL }, - { 0x00ae2, 0x00ae3, 0, NULL, NULL }, - { 0x00ac7, 0x00ac8, 0, NULL, NULL }, - { 0x00acd, 0x00acd, 0, NULL, NULL }, - { 0x00b3c, 0x00b3c, 0, NULL, NULL }, - { 0x00b01, 0x00b01, 0, NULL, NULL }, - { 0x00b3f, 0x00b3f, 0, NULL, NULL }, - { 0x03190, 0x031ba, 2, NULL, NULL }, - { 0x017c9, 0x017d3, 0, NULL, NULL }, - { 0x00ec8, 0x00ecd, 0, NULL, NULL }, - { 0x00cc6, 0x00cc6, 0, NULL, NULL }, - { 0x00c3e, 0x00c40, 0, NULL, NULL }, - { 0x00b82, 0x00b82, 0, NULL, NULL }, - { 0x00b56, 0x00b56, 0, NULL, NULL }, - { 0x00b4d, 0x00b4d, 0, NULL, NULL }, - { 0x00b62, 0x00b63, 0, NULL, NULL }, - { 0x00bcd, 0x00bcd, 0, NULL, NULL }, - { 0x00bc0, 0x00bc0, 0, NULL, NULL }, - { 0x00c00, 0x00c00, 0, NULL, NULL }, - { 0x00c62, 0x00c63, 0, NULL, NULL }, - { 0x00c4a, 0x00c4d, 0, NULL, NULL }, - { 0x00c46, 0x00c48, 0, NULL, NULL }, - { 0x00c55, 0x00c56, 0, NULL, NULL }, - { 0x00cbc, 0x00cbc, 0, NULL, NULL }, - { 0x00c81, 0x00c81, 0, NULL, NULL }, - { 0x00cbf, 0x00cbf, 0, NULL, NULL }, - { 0x00dd2, 0x00dd4, 0, NULL, NULL }, - { 0x00d41, 0x00d44, 0, NULL, NULL }, - { 0x00ce2, 0x00ce3, 0, NULL, NULL }, - { 0x00ccc, 0x00ccd, 0, NULL, NULL }, - { 0x00d01, 0x00d01, 0, NULL, NULL }, - { 0x00d62, 0x00d63, 0, NULL, NULL }, - { 0x00d4d, 0x00d4d, 0, NULL, NULL }, - { 0x00dca, 0x00dca, 0, NULL, NULL }, - { 0x00e47, 0x00e4e, 0, NULL, NULL }, - { 0x00e31, 0x00e31, 0, NULL, NULL }, - { 0x00dd6, 0x00dd6, 0, NULL, NULL }, - { 0x00e34, 0x00e3a, 0, NULL, NULL }, - { 0x00eb4, 0x00eb9, 0, NULL, NULL }, - { 0x00eb1, 0x00eb1, 0, NULL, NULL }, - { 0x00ebb, 0x00ebc, 0, NULL, NULL }, - { 0x0105e, 0x01060, 0, NULL, NULL }, - { 0x00f8d, 0x00f97, 0, NULL, NULL }, - { 0x00f39, 0x00f39, 0, NULL, NULL }, - { 0x00f35, 0x00f35, 0, NULL, NULL }, - { 0x00f18, 0x00f19, 0, NULL, NULL }, - { 0x00f37, 0x00f37, 0, NULL, NULL }, - { 0x00f80, 0x00f84, 0, NULL, NULL }, - { 0x00f71, 0x00f7e, 0, NULL, NULL }, - { 0x00f86, 0x00f87, 0, NULL, NULL }, - { 0x01032, 0x01037, 0, NULL, NULL }, - { 0x00fc6, 0x00fc6, 0, NULL, NULL }, - { 0x00f99, 0x00fbc, 0, NULL, NULL }, - { 0x0102d, 0x01030, 0, NULL, NULL }, - { 0x0103d, 0x0103e, 0, NULL, NULL }, - { 0x01039, 0x0103a, 0, NULL, NULL }, - { 0x01058, 0x01059, 0, NULL, NULL }, - { 0x0135d, 0x0135f, 0, NULL, NULL }, - { 0x01085, 0x01086, 0, NULL, NULL }, - { 0x01071, 0x01074, 0, NULL, NULL }, - { 0x01082, 0x01082, 0, NULL, NULL }, - { 0x0109d, 0x0109d, 0, NULL, NULL }, - { 0x0108d, 0x0108d, 0, NULL, NULL }, - { 0x01100, 0x011ff, 2, NULL, NULL }, - { 0x01772, 0x01773, 0, NULL, NULL }, - { 0x01732, 0x01734, 0, NULL, NULL }, - { 0x01712, 0x01714, 0, NULL, NULL }, - { 0x01752, 0x01753, 0, NULL, NULL }, - { 0x017b7, 0x017bd, 0, NULL, NULL }, - { 0x017b4, 0x017b5, 0, NULL, NULL }, - { 0x017c6, 0x017c6, 0, NULL, NULL }, - { 0x01c2c, 0x01c33, 0, NULL, NULL }, - { 0x01a7f, 0x01a7f, 0, NULL, NULL }, - { 0x01a17, 0x01a18, 0, NULL, NULL }, - { 0x01920, 0x01922, 0, NULL, NULL }, - { 0x0180b, 0x0180e, 0, NULL, NULL }, - { 0x017dd, 0x017dd, 0, NULL, NULL }, - { 0x018a9, 0x018a9, 0, NULL, NULL }, - { 0x01932, 0x01932, 0, NULL, NULL }, - { 0x01927, 0x01928, 0, NULL, NULL }, - { 0x01939, 0x0193b, 0, NULL, NULL }, - { 0x01a60, 0x01a60, 0, NULL, NULL }, - { 0x01a56, 0x01a56, 0, NULL, NULL }, - { 0x01a1b, 0x01a1b, 0, NULL, NULL }, - { 0x01a58, 0x01a5e, 0, NULL, NULL }, - { 0x01a65, 0x01a6c, 0, NULL, NULL }, - { 0x01a62, 0x01a62, 0, NULL, NULL }, - { 0x01a73, 0x01a7c, 0, NULL, NULL }, - { 0x01b80, 0x01b81, 0, NULL, NULL }, - { 0x01b36, 0x01b3a, 0, NULL, NULL }, - { 0x01b00, 0x01b03, 0, NULL, NULL }, - { 0x01ab0, 0x01abe, 0, NULL, NULL }, - { 0x01b34, 0x01b34, 0, NULL, NULL }, - { 0x01b42, 0x01b42, 0, NULL, NULL }, - { 0x01b3c, 0x01b3c, 0, NULL, NULL }, - { 0x01b6b, 0x01b73, 0, NULL, NULL }, - { 0x01be6, 0x01be6, 0, NULL, NULL }, - { 0x01ba8, 0x01ba9, 0, NULL, NULL }, - { 0x01ba2, 0x01ba5, 0, NULL, NULL }, - { 0x01bab, 0x01bad, 0, NULL, NULL }, - { 0x01bed, 0x01bed, 0, NULL, NULL }, - { 0x01be8, 0x01be9, 0, NULL, NULL }, - { 0x01bef, 0x01bf1, 0, NULL, NULL }, - { 0x02329, 0x0232a, 2, NULL, NULL }, - { 0x01dc0, 0x01df5, 0, NULL, NULL }, - { 0x01ce2, 0x01ce8, 0, NULL, NULL }, - { 0x01cd0, 0x01cd2, 0, NULL, NULL }, - { 0x01c36, 0x01c37, 0, NULL, NULL }, - { 0x01cd4, 0x01ce0, 0, NULL, NULL }, - { 0x01cf4, 0x01cf4, 0, NULL, NULL }, - { 0x01ced, 0x01ced, 0, NULL, NULL }, - { 0x01cf8, 0x01cf9, 0, NULL, NULL }, - { 0x02060, 0x02064, 0, NULL, NULL }, - { 0x0200b, 0x0200f, 0, NULL, NULL }, - { 0x01dfc, 0x01dff, 0, NULL, NULL }, - { 0x0202a, 0x0202e, 0, NULL, NULL }, - { 0x02066, 0x0206f, 0, NULL, NULL }, - { 0x020d0, 0x020f0, 0, NULL, NULL }, - { 0x03001, 0x03029, 2, NULL, NULL }, - { 0x02e80, 0x02e99, 2, NULL, NULL }, - { 0x02d7f, 0x02d7f, 0, NULL, NULL }, - { 0x02cef, 0x02cf1, 0, NULL, NULL }, - { 0x02de0, 0x02dff, 0, NULL, NULL }, - { 0x02f00, 0x02fd5, 2, NULL, NULL }, - { 0x02e9b, 0x02ef3, 2, NULL, NULL }, - { 0x02ff0, 0x02ffb, 2, NULL, NULL }, - { 0x03099, 0x0309a, 0, NULL, NULL }, - { 0x0302e, 0x0303e, 2, NULL, NULL }, - { 0x0302a, 0x0302d, 0, NULL, NULL }, - { 0x03041, 0x03096, 2, NULL, NULL }, - { 0x03105, 0x0312d, 2, NULL, NULL }, - { 0x0309b, 0x030ff, 2, NULL, NULL }, - { 0x03131, 0x0318e, 2, NULL, NULL }, - { 0x10a3f, 0x10a3f, 0, NULL, NULL }, - { 0x0aa4c, 0x0aa4c, 0, NULL, NULL }, - { 0x0a825, 0x0a826, 0, NULL, NULL }, - { 0x0a490, 0x0a4c6, 2, NULL, NULL }, - { 0x03250, 0x032fe, 2, NULL, NULL }, - { 0x031f0, 0x0321e, 2, NULL, NULL }, - { 0x031c0, 0x031e3, 2, NULL, NULL }, - { 0x03220, 0x03247, 2, NULL, NULL }, - { 0x04e00, 0x09fcc, 2, NULL, NULL }, - { 0x03300, 0x04db5, 2, NULL, NULL }, - { 0x0a000, 0x0a48c, 2, NULL, NULL }, - { 0x0a6f0, 0x0a6f1, 0, NULL, NULL }, - { 0x0a674, 0x0a67d, 0, NULL, NULL }, - { 0x0a66f, 0x0a672, 0, NULL, NULL }, - { 0x0a69f, 0x0a69f, 0, NULL, NULL }, - { 0x0a806, 0x0a806, 0, NULL, NULL }, - { 0x0a802, 0x0a802, 0, NULL, NULL }, - { 0x0a80b, 0x0a80b, 0, NULL, NULL }, - { 0x0a9b6, 0x0a9b9, 0, NULL, NULL }, - { 0x0a947, 0x0a951, 0, NULL, NULL }, - { 0x0a8e0, 0x0a8f1, 0, NULL, NULL }, - { 0x0a8c4, 0x0a8c4, 0, NULL, NULL }, - { 0x0a926, 0x0a92d, 0, NULL, NULL }, - { 0x0a980, 0x0a982, 0, NULL, NULL }, - { 0x0a960, 0x0a97c, 2, NULL, NULL }, - { 0x0a9b3, 0x0a9b3, 0, NULL, NULL }, - { 0x0aa29, 0x0aa2e, 0, NULL, NULL }, - { 0x0a9bc, 0x0a9bc, 0, NULL, NULL }, - { 0x0a9e5, 0x0a9e5, 0, NULL, NULL }, - { 0x0aa35, 0x0aa36, 0, NULL, NULL }, - { 0x0aa31, 0x0aa32, 0, NULL, NULL }, - { 0x0aa43, 0x0aa43, 0, NULL, NULL }, - { 0x0fb1e, 0x0fb1e, 0, NULL, NULL }, - { 0x0aaf6, 0x0aaf6, 0, NULL, NULL }, - { 0x0aab7, 0x0aab8, 0, NULL, NULL }, - { 0x0aab0, 0x0aab0, 0, NULL, NULL }, - { 0x0aa7c, 0x0aa7c, 0, NULL, NULL }, - { 0x0aab2, 0x0aab4, 0, NULL, NULL }, - { 0x0aac1, 0x0aac1, 0, NULL, NULL }, - { 0x0aabe, 0x0aabf, 0, NULL, NULL }, - { 0x0aaec, 0x0aaed, 0, NULL, NULL }, - { 0x0ac00, 0x0d7a3, 2, NULL, NULL }, - { 0x0abe8, 0x0abe8, 0, NULL, NULL }, - { 0x0abe5, 0x0abe5, 0, NULL, NULL }, - { 0x0abed, 0x0abed, 0, NULL, NULL }, - { 0x0f900, 0x0fa6d, 2, NULL, NULL }, - { 0x0d800, 0x0dfff, 0, NULL, NULL }, - { 0x0fa70, 0x0fad9, 2, NULL, NULL }, - { 0x0fff9, 0x0fffb, 0, NULL, NULL }, - { 0x0fe30, 0x0fe52, 2, NULL, NULL }, - { 0x0fe10, 0x0fe19, 2, NULL, NULL }, - { 0x0fe00, 0x0fe0f, 0, NULL, NULL }, - { 0x0fe20, 0x0fe2d, 0, NULL, NULL }, - { 0x0fe68, 0x0fe6b, 2, NULL, NULL }, - { 0x0fe54, 0x0fe66, 2, NULL, NULL }, - { 0x0feff, 0x0feff, 0, NULL, NULL }, - { 0x10a01, 0x10a03, 0, NULL, NULL }, - { 0x102e0, 0x102e0, 0, NULL, NULL }, - { 0x101fd, 0x101fd, 0, NULL, NULL }, - { 0x10376, 0x1037a, 0, NULL, NULL }, - { 0x10a0c, 0x10a0f, 0, NULL, NULL }, - { 0x10a05, 0x10a06, 0, NULL, NULL }, - { 0x10a38, 0x10a3a, 0, NULL, NULL }, - { 0x11633, 0x1163a, 0, NULL, NULL }, - { 0x11236, 0x11237, 0, NULL, NULL }, - { 0x11100, 0x11102, 0, NULL, NULL }, - { 0x1107f, 0x11081, 0, NULL, NULL }, - { 0x11001, 0x11001, 0, NULL, NULL }, - { 0x10ae5, 0x10ae6, 0, NULL, NULL }, - { 0x11038, 0x11046, 0, NULL, NULL }, - { 0x110b9, 0x110ba, 0, NULL, NULL }, - { 0x110b3, 0x110b6, 0, NULL, NULL }, - { 0x110bd, 0x110bd, 0, NULL, NULL }, - { 0x11180, 0x11181, 0, NULL, NULL }, - { 0x1112d, 0x11134, 0, NULL, NULL }, - { 0x11127, 0x1112b, 0, NULL, NULL }, - { 0x11173, 0x11173, 0, NULL, NULL }, - { 0x1122f, 0x11231, 0, NULL, NULL }, - { 0x111b6, 0x111be, 0, NULL, NULL }, - { 0x11234, 0x11234, 0, NULL, NULL }, - { 0x11370, 0x11374, 0, NULL, NULL }, - { 0x11301, 0x11301, 0, NULL, NULL }, - { 0x112df, 0x112df, 0, NULL, NULL }, - { 0x112e3, 0x112ea, 0, NULL, NULL }, - { 0x11340, 0x11340, 0, NULL, NULL }, - { 0x1133c, 0x1133c, 0, NULL, NULL }, - { 0x11366, 0x1136c, 0, NULL, NULL }, - { 0x114c2, 0x114c3, 0, NULL, NULL }, - { 0x114ba, 0x114ba, 0, NULL, NULL }, - { 0x114b3, 0x114b8, 0, NULL, NULL }, - { 0x114bf, 0x114c0, 0, NULL, NULL }, - { 0x115bc, 0x115bd, 0, NULL, NULL }, - { 0x115b2, 0x115b5, 0, NULL, NULL }, - { 0x115bf, 0x115c0, 0, NULL, NULL }, - { 0x1d1aa, 0x1d1ad, 0, NULL, NULL }, - { 0x16b30, 0x16b36, 0, NULL, NULL }, - { 0x116ad, 0x116ad, 0, NULL, NULL }, - { 0x1163f, 0x11640, 0, NULL, NULL }, - { 0x1163d, 0x1163d, 0, NULL, NULL }, - { 0x116ab, 0x116ab, 0, NULL, NULL }, - { 0x116b7, 0x116b7, 0, NULL, NULL }, - { 0x116b0, 0x116b5, 0, NULL, NULL }, - { 0x16af0, 0x16af4, 0, NULL, NULL }, - { 0x1bca0, 0x1bca3, 0, NULL, NULL }, - { 0x1b000, 0x1b001, 2, NULL, NULL }, - { 0x16f8f, 0x16f92, 0, NULL, NULL }, - { 0x1bc9d, 0x1bc9e, 0, NULL, NULL }, - { 0x1d173, 0x1d182, 0, NULL, NULL }, - { 0x1d167, 0x1d169, 0, NULL, NULL }, - { 0x1d185, 0x1d18b, 0, NULL, NULL }, - { 0x2a700, 0x2b734, 2, NULL, NULL }, - { 0x1f210, 0x1f23a, 2, NULL, NULL }, - { 0x1e8d0, 0x1e8d6, 0, NULL, NULL }, - { 0x1d242, 0x1d244, 0, NULL, NULL }, - { 0x1f200, 0x1f202, 2, NULL, NULL }, - { 0x1f250, 0x1f251, 2, NULL, NULL }, - { 0x1f240, 0x1f248, 2, NULL, NULL }, - { 0x20000, 0x2a6d6, 2, NULL, NULL }, - { 0xe0020, 0xe007f, 0, NULL, NULL }, - { 0x2f800, 0x2fa1d, 2, NULL, NULL }, - { 0x2b740, 0x2b81d, 2, NULL, NULL }, - { 0xe0001, 0xe0001, 0, NULL, NULL }, - { 0xf0000, 0xffffd, 0, NULL, NULL }, - { 0xe0100, 0xe01ef, 0, NULL, NULL }, - { 0x100000, 0x10fffd, 0, NULL, NULL }, -}; -static struct utf8_width_entry *utf8_width_root = NULL; - -static void utf8_build(void); +static int utf8_width(wchar_t); /* Set a single character. */ void @@ -402,6 +81,9 @@ utf8_open(struct utf8_data *ud, u_char ch) enum utf8_state utf8_append(struct utf8_data *ud, u_char ch) { + wchar_t wc; + int width; + if (ud->have >= ud->size) fatalx("UTF-8 character overflow"); if (ud->size > sizeof ud->data) @@ -416,122 +98,59 @@ utf8_append(struct utf8_data *ud, u_char ch) if (ud->width == 0xff) return (UTF8_ERROR); - ud->width = utf8_width(utf8_combine(ud)); - return (UTF8_DONE); -} -/* Build UTF-8 width tree. */ -static void -utf8_build(void) -{ - struct utf8_width_entry **ptr, *item, *node; - u_int i; - - for (i = 0; i < nitems(utf8_width_table); i++) { - item = &utf8_width_table[i]; - - ptr = &utf8_width_root; - while (*ptr != NULL) { - node = *ptr; - if (item->last < node->first) - ptr = &node->left; - else if (item->first > node->last) - ptr = &node->right; - } - *ptr = item; - } -} - -/* Lookup width of UTF-8 data in tree. */ -u_int -utf8_width(u_int uc) -{ - struct utf8_width_entry *item; - - if (utf8_width_root == NULL) - utf8_build(); - - item = utf8_width_root; - while (item != NULL) { - if (uc < item->first) - item = item->left; - else if (uc > item->last) - item = item->right; - else - return (item->width); - } - return (1); -} - -/* Combine UTF-8 into 32-bit Unicode. */ -u_int -utf8_combine(const struct utf8_data *ud) -{ - u_int uc; - - uc = 0xfffd; - switch (ud->size) { - case 1: - uc = ud->data[0]; - break; - case 2: - uc = ud->data[1] & 0x3f; - uc |= (ud->data[0] & 0x1f) << 6; - break; - case 3: - uc = ud->data[2] & 0x3f; - uc |= (ud->data[1] & 0x3f) << 6; - uc |= (ud->data[0] & 0xf) << 12; - break; - case 4: - uc = ud->data[3] & 0x3f; - uc |= (ud->data[2] & 0x3f) << 6; - uc |= (ud->data[1] & 0x3f) << 12; - uc |= (ud->data[0] & 0x7) << 18; - break; - } - return (uc); -} - -/* Split 32-bit Unicode into UTF-8. */ -enum utf8_state -utf8_split(u_int uc, struct utf8_data *ud) -{ - if (uc < 0x7f) { - ud->size = 1; - ud->data[0] = uc; - } else if (uc < 0x7ff) { - ud->size = 2; - ud->data[0] = 0xc0 | ((uc >> 6) & 0x1f); - ud->data[1] = 0x80 | (uc & 0x3f); - } else if (uc < 0xffff) { - ud->size = 3; - ud->data[0] = 0xe0 | ((uc >> 12) & 0xf); - ud->data[1] = 0x80 | ((uc >> 6) & 0x3f); - ud->data[2] = 0x80 | (uc & 0x3f); - } else if (uc < 0x1fffff) { - ud->size = 4; - ud->data[0] = 0xf0 | ((uc >> 18) & 0x7); - ud->data[1] = 0x80 | ((uc >> 12) & 0x3f); - ud->data[2] = 0x80 | ((uc >> 6) & 0x3f); - ud->data[3] = 0x80 | (uc & 0x3f); - } else + if (utf8_combine(ud, &wc) != UTF8_DONE) return (UTF8_ERROR); - ud->width = utf8_width(uc); + if ((width = utf8_width(wc)) < 0) + return (UTF8_ERROR); + ud->width = width; + return (UTF8_DONE); } -/* Split a two-byte UTF-8 character. */ -u_int -utf8_split2(u_int uc, u_char *ptr) +/* Get width of Unicode character. */ +static int +utf8_width(wchar_t wc) { - if (uc > 0x7f) { - ptr[0] = (uc >> 6) | 0xc0; - ptr[1] = (uc & 0x3f) | 0x80; - return (2); + int width; + + width = wcwidth(wc); + if (width < 0 || width > 0xff) + return (-1); + return (width); +} + +/* Combine UTF-8 into Unicode. */ +enum utf8_state +utf8_combine(const struct utf8_data *ud, wchar_t *wc) +{ + switch (mbtowc(wc, ud->data, ud->size)) { + case -1: + mbtowc(NULL, NULL, MB_CUR_MAX); + return (UTF8_ERROR); + case 0: + return (UTF8_ERROR); + default: + return (UTF8_DONE); } - ptr[0] = uc; - return (1); +} + +/* Split Unicode into UTF-8. */ +enum utf8_state +utf8_split(wchar_t wc, struct utf8_data *ud) +{ + char s[MB_LEN_MAX]; + int slen; + + slen = wctomb(s, wc); + if (slen <= 0 || slen > (int)sizeof ud->data) + return (UTF8_ERROR); + + memcpy(ud->data, s, slen); + ud->size = slen; + + ud->width = utf8_width(wc); + return (UTF8_DONE); } /* @@ -723,6 +342,43 @@ utf8_trimcstr(const char *s, u_int width) return (out); } +/* Trim UTF-8 string to width. Caller frees. */ +char * +utf8_rtrimcstr(const char *s, u_int width) +{ + struct utf8_data *tmp, *next, *end; + char *out; + u_int at; + + tmp = utf8_fromcstr(s); + + for (end = tmp; end->size != 0; end++) + /* nothing */; + if (end == tmp) { + free(tmp); + return (xstrdup("")); + } + next = end - 1; + + at = 0; + for (;;) + { + if (at + next->width > width) { + next++; + break; + } + at += next->width; + + if (next == tmp) + break; + next--; + } + + out = utf8_tocstr(next); + free(tmp); + return (out); +} + /* Pad UTF-8 string to width. Caller frees. */ char * utf8_padcstr(const char *s, u_int width) diff --git a/window-choose.c b/window-choose.c index fdfc47a0..7a727aac 100644 --- a/window-choose.c +++ b/window-choose.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/window-clock.c b/window-clock.c index e8451f22..4cc58684 100644 --- a/window-clock.c +++ b/window-clock.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/window-copy.c b/window-copy.c index 6bc1eaf8..1ec8a45e 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -203,15 +203,80 @@ window_copy_pageup(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; - u_int n; + u_int n, ox, oy; + + oy = screen_hsize(data->backing) + data->cy - data->oy; + ox = window_copy_find_length(wp, oy); + + if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) + window_copy_other_end(wp); + + if (data->cx != ox) { + data->lastcx = data->cx; + data->lastsx = ox; + } + data->cx = data->lastcx; n = 1; if (screen_size_y(s) > 2) n = screen_size_y(s) - 2; + if (data->oy + n > screen_hsize(data->backing)) data->oy = screen_hsize(data->backing); else data->oy += n; + + if (!data->screen.sel.flag || !data->rectflag) { + u_int py = screen_hsize(data->backing) + data->cy - data->oy; + u_int px = window_copy_find_length(wp, py); + if ((data->cx >= data->lastsx && data->cx != px) || data->cx > px) + window_copy_cursor_end_of_line(wp); + } + + window_copy_update_selection(wp, 1); + window_copy_redraw_screen(wp); +} + +void +window_copy_pagedown(struct window_pane *wp) +{ + struct window_copy_mode_data *data = wp->modedata; + struct screen *s = &data->screen; + u_int n, ox, oy; + + oy = screen_hsize(data->backing) + data->cy - data->oy; + ox = window_copy_find_length(wp, oy); + + if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely) + window_copy_other_end(wp); + + if (data->cx != ox) { + data->lastcx = data->cx; + data->lastsx = ox; + } + data->cx = data->lastcx; + + n = 1; + if (screen_size_y(s) > 2) + n = screen_size_y(s) - 2; + + if (data->oy < n) + data->oy = 0; + else + data->oy -= n; + + if (!data->screen.sel.flag || !data->rectflag) { + u_int py = screen_hsize(data->backing) + data->cy - data->oy; + u_int px = window_copy_find_length(wp, py); + if ((data->cx >= data->lastsx && data->cx != px) || data->cx > px) + window_copy_cursor_end_of_line(wp); + } + + if (data->scroll_exit && data->oy == 0) { + window_pane_reset_mode(wp); + return; + } + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } @@ -358,21 +423,8 @@ window_copy_key(struct window_pane *wp, struct client *c, struct session *sess, window_copy_pageup(wp); break; case MODEKEYCOPY_NEXTPAGE: - n = 1; - if (screen_size_y(s) > 2) - n = screen_size_y(s) - 2; - for (; np != 0; np--) { - if (data->oy < n) - data->oy = 0; - else - data->oy -= n; - } - if (data->scroll_exit && data->oy == 0) { - window_pane_reset_mode(wp); - return; - } - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); + for (; np != 0; np--) + window_copy_pagedown(wp); break; case MODEKEYCOPY_HALFPAGEUP: n = screen_size_y(s) / 2; @@ -1654,11 +1706,13 @@ void window_copy_cursor_left(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; + u_int py; - if (data->cx == 0) { + py = screen_hsize(data->backing) + data->cy - data->oy; + if (data->cx == 0 && py > 0) { window_copy_cursor_up(wp, 0); window_copy_cursor_end_of_line(wp); - } else { + } else if (data->cx > 0) { window_copy_update_cursor(wp, data->cx - 1, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); @@ -1669,19 +1723,20 @@ void window_copy_cursor_right(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; - u_int px, py; + u_int px, py, yy; + py = screen_hsize(data->backing) + data->cy - data->oy; + yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; if (data->screen.sel.flag && data->rectflag) px = screen_size_x(&data->screen); else { - py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); } - if (data->cx >= px) { + if (data->cx >= px && py < yy) { window_copy_cursor_start_of_line(wp); window_copy_cursor_down(wp, 0); - } else { + } else if (data->cx < px) { window_copy_update_cursor(wp, data->cx + 1, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); @@ -2124,7 +2179,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m) return; c->tty.mouse_drag_update = window_copy_drag_update; - c->tty.mouse_drag_release = window_copy_drag_release; + c->tty.mouse_drag_release = NULL; /* will fire MouseUp key */ window_copy_update_cursor(wp, x, y); window_copy_start_selection(wp); @@ -2151,16 +2206,3 @@ window_copy_drag_update(__unused struct client *c, struct mouse_event *m) if (window_copy_update_selection(wp, 1)) window_copy_redraw_selection(wp, old_cy); } - -void -window_copy_drag_release(__unused struct client *c, struct mouse_event *m) -{ - struct window_pane *wp; - - wp = cmd_mouse_pane(m, NULL, NULL); - if (wp == NULL || wp->mode != &window_copy_mode) - return; - - window_copy_copy_selection(wp, NULL); - window_pane_reset_mode(wp); -} diff --git a/window-copy.h b/window-copy.h index b4269b32..243926b5 100644 --- a/window-copy.h +++ b/window-copy.h @@ -5,6 +5,7 @@ struct screen *window_copy_init(struct window_pane *); void window_copy_free(struct window_pane *); +void window_copy_pagedown(struct window_pane *); void window_copy_resize(struct window_pane *, u_int, u_int); void window_copy_key(struct window_pane *, struct client *, struct session *, key_code, struct mouse_event *); diff --git a/window.c b/window.c index 5ae76dfe..ca5618c7 100644 --- a/window.c +++ b/window.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2007 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -940,6 +941,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, #ifdef HAVE_UTEMPTER xsnprintf(s, sizeof s, "tmux(%lu).%%%u", (long) getpid(), wp->id); utempter_add_record(wp->fd, s); + kill(getpid(), SIGCHLD); #endif setblocking(wp->fd, 0); @@ -1128,6 +1130,8 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode) if ((s = wp->mode->init(wp)) != NULL) wp->screen = s; wp->flags |= (PANE_REDRAW|PANE_CHANGED); + + server_status_window(wp->window); return (0); } @@ -1142,6 +1146,8 @@ window_pane_reset_mode(struct window_pane *wp) wp->screen = &wp->base; wp->flags |= (PANE_REDRAW|PANE_CHANGED); + + server_status_window(wp->window); } void diff --git a/xmalloc.h b/xmalloc.h index d331ce99..0360b0d9 100644 --- a/xmalloc.h +++ b/xmalloc.h @@ -19,6 +19,10 @@ #ifndef XMALLOC_H #define XMALLOC_H +#if !defined(__bounded__) +# define __bounded__(x, y, z) +#endif + void *xmalloc(size_t); void *xcalloc(size_t, size_t); void *xrealloc(void *, size_t); diff --git a/xterm-keys.c b/xterm-keys.c index f1490fcc..7bfefd15 100644 --- a/xterm-keys.c +++ b/xterm-keys.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott + * Copyright (c) 2009 Nicholas Marriott * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above