mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Merge branch 'obsd-master'
Conflicts: tmux.1 window.c
This commit is contained in:
commit
e62e17d046
71
input.c
71
input.c
@ -93,6 +93,8 @@ struct input_ctx {
|
||||
|
||||
const struct input_state *state;
|
||||
|
||||
struct event timer;
|
||||
|
||||
/*
|
||||
* All input received since we were last in the ground state. Sent to
|
||||
* control clients on connection.
|
||||
@ -118,6 +120,7 @@ static void input_osc_104(struct window_pane *, const char *);
|
||||
/* Transition entry/exit handlers. */
|
||||
static void input_clear(struct input_ctx *);
|
||||
static void input_ground(struct input_ctx *);
|
||||
static void input_enter_dcs(struct input_ctx *);
|
||||
static void input_enter_osc(struct input_ctx *);
|
||||
static void input_exit_osc(struct input_ctx *);
|
||||
static void input_enter_apc(struct input_ctx *);
|
||||
@ -364,7 +367,7 @@ static const struct input_state input_state_csi_ignore = {
|
||||
/* dcs_enter state definition. */
|
||||
static const struct input_state input_state_dcs_enter = {
|
||||
"dcs_enter",
|
||||
input_clear, NULL,
|
||||
input_enter_dcs, NULL,
|
||||
input_state_dcs_enter_table
|
||||
};
|
||||
|
||||
@ -756,6 +759,30 @@ input_table_compare(const void *key, const void *value)
|
||||
return (strcmp(ictx->interm_buf, entry->interm));
|
||||
}
|
||||
|
||||
/*
|
||||
* Timer - if this expires then have been waiting for a terminator for too
|
||||
* long, so reset to ground.
|
||||
*/
|
||||
static void
|
||||
input_timer_callback(__unused int fd, __unused short events, void *arg)
|
||||
{
|
||||
struct input_ctx *ictx = arg;
|
||||
struct window_pane *wp = ictx->wp;
|
||||
|
||||
log_debug("%s: %%%u %s expired" , __func__, wp->id, ictx->state->name);
|
||||
input_reset(wp, 0);
|
||||
}
|
||||
|
||||
/* Start the timer. */
|
||||
static void
|
||||
input_start_timer(struct input_ctx *ictx)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 100000 };
|
||||
|
||||
event_del(&ictx->timer);
|
||||
event_add(&ictx->timer, &tv);
|
||||
}
|
||||
|
||||
/* Reset cell state to default. */
|
||||
static void
|
||||
input_reset_cell(struct input_ctx *ictx)
|
||||
@ -782,6 +809,8 @@ input_init(struct window_pane *wp)
|
||||
|
||||
ictx->since_ground = evbuffer_new();
|
||||
|
||||
evtimer_set(&ictx->timer, input_timer_callback, ictx);
|
||||
|
||||
input_reset(wp, 0);
|
||||
}
|
||||
|
||||
@ -791,6 +820,8 @@ input_free(struct window_pane *wp)
|
||||
{
|
||||
struct input_ctx *ictx = wp->ictx;
|
||||
|
||||
event_del(&ictx->timer);
|
||||
|
||||
free(ictx->input_buf);
|
||||
evbuffer_free(ictx->since_ground);
|
||||
|
||||
@ -815,14 +846,7 @@ input_reset(struct window_pane *wp, int clear)
|
||||
screen_write_stop(&ictx->ctx);
|
||||
}
|
||||
|
||||
*ictx->interm_buf = '\0';
|
||||
ictx->interm_len = 0;
|
||||
|
||||
*ictx->param_buf = '\0';
|
||||
ictx->param_len = 0;
|
||||
|
||||
*ictx->input_buf = '\0';
|
||||
ictx->input_len = 0;
|
||||
input_clear(ictx);
|
||||
|
||||
ictx->state = &input_state_ground;
|
||||
ictx->flags = 0;
|
||||
@ -997,6 +1021,8 @@ input_reply(struct input_ctx *ictx, const char *fmt, ...)
|
||||
static void
|
||||
input_clear(struct input_ctx *ictx)
|
||||
{
|
||||
event_del(&ictx->timer);
|
||||
|
||||
*ictx->interm_buf = '\0';
|
||||
ictx->interm_len = 0;
|
||||
|
||||
@ -1013,6 +1039,7 @@ input_clear(struct input_ctx *ictx)
|
||||
static void
|
||||
input_ground(struct input_ctx *ictx)
|
||||
{
|
||||
event_del(&ictx->timer);
|
||||
evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
|
||||
|
||||
if (ictx->input_space > INPUT_BUF_START) {
|
||||
@ -1842,6 +1869,16 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
||||
}
|
||||
}
|
||||
|
||||
/* DCS string started. */
|
||||
static void
|
||||
input_enter_dcs(struct input_ctx *ictx)
|
||||
{
|
||||
log_debug("%s", __func__);
|
||||
|
||||
input_clear(ictx);
|
||||
input_start_timer(ictx);
|
||||
}
|
||||
|
||||
/* DCS terminator (ST) received. */
|
||||
static int
|
||||
input_dcs_dispatch(struct input_ctx *ictx)
|
||||
@ -1871,6 +1908,7 @@ input_enter_osc(struct input_ctx *ictx)
|
||||
log_debug("%s", __func__);
|
||||
|
||||
input_clear(ictx);
|
||||
input_start_timer(ictx);
|
||||
}
|
||||
|
||||
/* OSC terminator (ST) received. */
|
||||
@ -1896,8 +1934,10 @@ input_exit_osc(struct input_ctx *ictx)
|
||||
switch (option) {
|
||||
case 0:
|
||||
case 2:
|
||||
screen_set_title(ictx->ctx.s, p);
|
||||
server_status_window(ictx->wp->window);
|
||||
if (utf8_isvalid(p)) {
|
||||
screen_set_title(ictx->ctx.s, p);
|
||||
server_status_window(ictx->wp->window);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
input_osc_4(ictx->wp, p);
|
||||
@ -1909,7 +1949,7 @@ input_exit_osc(struct input_ctx *ictx)
|
||||
input_osc_11(ictx->wp, p);
|
||||
break;
|
||||
case 12:
|
||||
if (*p != '?') /* ? is colour request */
|
||||
if (utf8_isvalid(p) && *p != '?') /* ? is colour request */
|
||||
screen_set_cursor_colour(ictx->ctx.s, p);
|
||||
break;
|
||||
case 52:
|
||||
@ -1935,6 +1975,7 @@ input_enter_apc(struct input_ctx *ictx)
|
||||
log_debug("%s", __func__);
|
||||
|
||||
input_clear(ictx);
|
||||
input_start_timer(ictx);
|
||||
}
|
||||
|
||||
/* APC terminator (ST) received. */
|
||||
@ -1945,6 +1986,8 @@ input_exit_apc(struct input_ctx *ictx)
|
||||
return;
|
||||
log_debug("%s: \"%s\"", __func__, ictx->input_buf);
|
||||
|
||||
if (!utf8_isvalid(ictx->input_buf))
|
||||
return;
|
||||
screen_set_title(ictx->ctx.s, ictx->input_buf);
|
||||
server_status_window(ictx->wp->window);
|
||||
}
|
||||
@ -1956,6 +1999,7 @@ input_enter_rename(struct input_ctx *ictx)
|
||||
log_debug("%s", __func__);
|
||||
|
||||
input_clear(ictx);
|
||||
input_start_timer(ictx);
|
||||
}
|
||||
|
||||
/* Rename terminator (ST) received. */
|
||||
@ -1968,9 +2012,10 @@ input_exit_rename(struct input_ctx *ictx)
|
||||
return;
|
||||
log_debug("%s: \"%s\"", __func__, ictx->input_buf);
|
||||
|
||||
if (!utf8_isvalid(ictx->input_buf))
|
||||
return;
|
||||
window_set_name(ictx->wp->window, ictx->input_buf);
|
||||
options_set_number(ictx->wp->window->options, "automatic-rename", 0);
|
||||
|
||||
server_status_window(ictx->wp->window);
|
||||
}
|
||||
|
||||
|
21
log.c
21
log.c
@ -61,12 +61,10 @@ log_open(const char *name)
|
||||
|
||||
if (log_level == 0)
|
||||
return;
|
||||
|
||||
if (log_file != NULL)
|
||||
fclose(log_file);
|
||||
log_close();
|
||||
|
||||
xasprintf(&path, "tmux-%s-%ld.log", name, (long)getpid());
|
||||
log_file = fopen(path, "w");
|
||||
log_file = fopen(path, "a");
|
||||
free(path);
|
||||
if (log_file == NULL)
|
||||
return;
|
||||
@ -75,6 +73,21 @@ log_open(const char *name)
|
||||
event_set_log_callback(log_event_cb);
|
||||
}
|
||||
|
||||
/* Toggle logging. */
|
||||
void
|
||||
log_toggle(const char *name)
|
||||
{
|
||||
if (log_level == 0) {
|
||||
log_level = 1;
|
||||
log_open(name);
|
||||
log_debug("log opened");
|
||||
} else {
|
||||
log_debug("log closed");
|
||||
log_level = 0;
|
||||
log_close();
|
||||
}
|
||||
}
|
||||
|
||||
/* Close logging. */
|
||||
void
|
||||
log_close(void)
|
||||
|
@ -685,8 +685,10 @@ mode_tree_run_command(struct client *c, struct cmd_find_state *fs,
|
||||
char *command, *cause;
|
||||
|
||||
command = cmd_template_replace(template, name, 1);
|
||||
if (command == NULL || *command == '\0')
|
||||
if (command == NULL || *command == '\0') {
|
||||
free(command);
|
||||
return;
|
||||
}
|
||||
|
||||
cmdlist = cmd_string_parse(command, NULL, 0, &cause);
|
||||
if (cmdlist == NULL) {
|
||||
|
6
proc.c
6
proc.c
@ -263,3 +263,9 @@ proc_kill_peer(struct tmuxpeer *peer)
|
||||
{
|
||||
peer->flags |= PEER_BAD;
|
||||
}
|
||||
|
||||
void
|
||||
proc_toggle_log(struct tmuxproc *tp)
|
||||
{
|
||||
log_toggle(tp->name);
|
||||
}
|
||||
|
@ -1390,7 +1390,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the selection the flag and set the cell. */
|
||||
/* Update the selected flag and set the cell. */
|
||||
selected = screen_check_selection(s, s->cx, s->cy);
|
||||
if (selected && (~gc->flags & GRID_FLAG_SELECTED)) {
|
||||
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
||||
|
3
screen.c
3
screen.c
@ -21,6 +21,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@ -107,7 +108,7 @@ void
|
||||
screen_set_title(struct screen *s, const char *title)
|
||||
{
|
||||
free(s->title);
|
||||
s->title = xstrdup(title);
|
||||
utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
||||
}
|
||||
|
||||
/* Resize screen. */
|
||||
|
5
server.c
5
server.c
@ -150,7 +150,7 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
|
||||
}
|
||||
close(pair[0]);
|
||||
|
||||
if (log_get_level() > 3)
|
||||
if (log_get_level() > 1)
|
||||
tty_create_log();
|
||||
if (pledge("stdio rpath wpath cpath fattr unix getpw recvfd proc exec "
|
||||
"tty ps", NULL) != 0)
|
||||
@ -364,6 +364,9 @@ server_signal(int sig)
|
||||
}
|
||||
server_add_accept(0);
|
||||
break;
|
||||
case SIGUSR2:
|
||||
proc_toggle_log(server_proc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
6
signal.c
6
signal.c
@ -29,6 +29,7 @@ static struct event ev_sigchld;
|
||||
static struct event ev_sigcont;
|
||||
static struct event ev_sigterm;
|
||||
static struct event ev_sigusr1;
|
||||
static struct event ev_sigusr2;
|
||||
static struct event ev_sigwinch;
|
||||
|
||||
void
|
||||
@ -59,6 +60,8 @@ set_signals(void (*handler)(int, short, void *), void *arg)
|
||||
signal_add(&ev_sigterm, NULL);
|
||||
signal_set(&ev_sigusr1, SIGUSR1, handler, arg);
|
||||
signal_add(&ev_sigusr1, NULL);
|
||||
signal_set(&ev_sigusr2, SIGUSR2, handler, arg);
|
||||
signal_add(&ev_sigusr2, NULL);
|
||||
signal_set(&ev_sigwinch, SIGWINCH, handler, arg);
|
||||
signal_add(&ev_sigwinch, NULL);
|
||||
}
|
||||
@ -92,6 +95,8 @@ clear_signals(int after_fork)
|
||||
fatal("sigaction failed");
|
||||
if (sigaction(SIGUSR1, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
if (sigaction(SIGUSR2, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
if (sigaction(SIGWINCH, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
} else {
|
||||
@ -100,6 +105,7 @@ clear_signals(int after_fork)
|
||||
event_del(&ev_sigcont);
|
||||
event_del(&ev_sigterm);
|
||||
event_del(&ev_sigusr1);
|
||||
event_del(&ev_sigusr2);
|
||||
event_del(&ev_sigwinch);
|
||||
}
|
||||
}
|
||||
|
21
tmux.1
21
tmux.1
@ -199,7 +199,6 @@ characters to the terminal it is running (if not, they are replaced by
|
||||
.Ql _ ) .
|
||||
.It Fl v
|
||||
Request verbose logging.
|
||||
This option may be specified multiple times for increasing verbosity.
|
||||
Log messages will be saved into
|
||||
.Pa tmux-client-PID.log
|
||||
and
|
||||
@ -211,6 +210,22 @@ is the PID of the server or client process.
|
||||
Report the
|
||||
.Nm
|
||||
version.
|
||||
.Pp
|
||||
If
|
||||
.Fl v
|
||||
is specified twice, an additional
|
||||
.Pa tmux-out-PID.log
|
||||
file is generated with a copy of everything
|
||||
.Nm
|
||||
writes to the terminal.
|
||||
.Pp
|
||||
The
|
||||
.Dv SIGUSR2
|
||||
signal may be sent to the
|
||||
.Nm
|
||||
server process to toggle logging between on (as if
|
||||
.Fl v
|
||||
was given) and off.
|
||||
.It Ar command Op Ar flags
|
||||
This specifies one of a set of commands used to control
|
||||
.Nm ,
|
||||
@ -1398,7 +1413,7 @@ The following keys may be used in tree mode:
|
||||
.It Li "t" Ta "Toggle if item is tagged"
|
||||
.It Li "T" Ta "Tag no items"
|
||||
.It Li "C-t" Ta "Tag all items"
|
||||
.It Li ":" Ta "Run a command for each tagged item"
|
||||
.It Li "\&:" Ta "Run a command for each tagged item"
|
||||
.It Li "f" Ta "Enter a format to filter items"
|
||||
.It Li "O" Ta "Change sort order"
|
||||
.It Li "q" Ta "Exit mode"
|
||||
@ -3742,7 +3757,7 @@ The flag is one of the following symbols appended to the window name:
|
||||
.It Li "*" Ta "Denotes the current window."
|
||||
.It Li "-" Ta "Marks the last window (previously selected)."
|
||||
.It Li "#" Ta "Window is monitored and activity has been detected."
|
||||
.It Li "!" Ta "A bell has occurred in the window."
|
||||
.It Li "\&!" Ta "A bell has occurred in the window."
|
||||
.It Li "~" Ta "The window has been silent for the monitor-silence interval."
|
||||
.It Li "M" Ta "The window contains the marked pane."
|
||||
.It Li "Z" Ta "The window's active pane is zoomed."
|
||||
|
3
tmux.h
3
tmux.h
@ -1497,6 +1497,7 @@ struct tmuxpeer *proc_add_peer(struct tmuxproc *, int,
|
||||
void (*)(struct imsg *, void *), void *);
|
||||
void proc_remove_peer(struct tmuxpeer *);
|
||||
void proc_kill_peer(struct tmuxpeer *);
|
||||
void proc_toggle_log(struct tmuxproc *);
|
||||
|
||||
/* cfg.c */
|
||||
extern int cfg_finished;
|
||||
@ -2321,6 +2322,7 @@ enum utf8_state utf8_open(struct utf8_data *, u_char);
|
||||
enum utf8_state utf8_append(struct utf8_data *, 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_isvalid(const char *);
|
||||
int utf8_strvis(char *, const char *, size_t, int);
|
||||
int utf8_stravis(char **, const char *, int);
|
||||
char *utf8_sanitize(const char *);
|
||||
@ -2342,6 +2344,7 @@ struct event_base *osdep_event_init(void);
|
||||
void log_add_level(void);
|
||||
int log_get_level(void);
|
||||
void log_open(const char *);
|
||||
void log_toggle(const char *);
|
||||
void log_close(void);
|
||||
void printflike(1, 2) log_debug(const char *, ...);
|
||||
__dead void printflike(1, 2) fatal(const char *, ...);
|
||||
|
2
tty.c
2
tty.c
@ -1848,7 +1848,7 @@ tty_check_fg(struct tty *tty, const struct window_pane *wp,
|
||||
*/
|
||||
if (~gc->flags & GRID_FLAG_NOPALETTE) {
|
||||
c = gc->fg;
|
||||
if (gc->fg < 8 && gc->attr & GRID_ATTR_BRIGHT)
|
||||
if (c < 8 && gc->attr & GRID_ATTR_BRIGHT)
|
||||
c += 90;
|
||||
if ((c = window_pane_get_palette(wp, c)) != -1)
|
||||
gc->fg = c;
|
||||
|
24
utf8.c
24
utf8.c
@ -232,6 +232,30 @@ utf8_stravis(char **dst, const char *src, int flag)
|
||||
return (len);
|
||||
}
|
||||
|
||||
/* Does this string contain anything that isn't valid UTF-8? */
|
||||
int
|
||||
utf8_isvalid(const char *s)
|
||||
{
|
||||
struct utf8_data ud;
|
||||
const char *end;
|
||||
enum utf8_state more;
|
||||
|
||||
end = s + strlen(s);
|
||||
while (s < end) {
|
||||
if ((more = utf8_open(&ud, *s)) == UTF8_MORE) {
|
||||
while (++s < end && more == UTF8_MORE)
|
||||
more = utf8_append(&ud, *s);
|
||||
if (more == UTF8_DONE)
|
||||
continue;
|
||||
return (0);
|
||||
}
|
||||
if (*s < 0x20 || *s > 0x7e)
|
||||
return (0);
|
||||
s++;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanitize a string, changing any UTF-8 characters to '_'. Caller should free
|
||||
* the returned string. Anything not valid printable ASCII or UTF-8 is
|
||||
|
Loading…
Reference in New Issue
Block a user