summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-attach-session.c6
-rw-r--r--cmd-new-session.c6
-rw-r--r--cmd-set-option.c3
-rw-r--r--cmd-string.c3
-rw-r--r--tmux.138
-rw-r--r--tmux.c2
-rw-r--r--tmux.h4
-rw-r--r--tty-term.c99
-rw-r--r--tty.c5
9 files changed, 137 insertions, 29 deletions
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 3278ea7f..4604ee27 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -43,7 +43,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct client *c;
- char *cause;
+ char *overrides, *cause;
u_int i;
if (ARRAY_LENGTH(&sessions) == 0) {
@@ -80,7 +80,9 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
- if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
+ overrides =
+ options_get_string(&s->options, "terminal-overrides");
+ if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "terminal open failed: %s", cause);
xfree(cause);
return (-1);
diff --git a/cmd-new-session.c b/cmd-new-session.c
index ea2e5b12..c1ba6e30 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -108,7 +108,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_new_session_data *data = self->data;
struct session *s;
- char *cmd, *cwd, *cause;
+ char *overrides, *cmd, *cwd, *cause;
int detached;
u_int sx, sy;
@@ -147,7 +147,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
- if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
+ overrides =
+ options_get_string(&global_s_options, "terminal-overrides");
+ if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
xfree(cause);
return (-1);
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 2e3ca734..5c2d5870 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -77,7 +77,8 @@ const struct set_option_entry set_option_table[] = {
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
- { "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
+ { "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
+ { "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
diff --git a/cmd-string.c b/cmd-string.c
index 9ba399b2..c12ac1d7 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -215,6 +215,9 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
switch (ch = cmd_string_getc(s, p)) {
case EOF:
goto error;
+ case 'e':
+ ch = '\033';
+ break;
case 'r':
ch = '\r';
break;
diff --git a/tmux.1 b/tmux.1
index 1f361d17..e60424d3 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1418,6 +1418,44 @@ and
.Ic status-right
strings as UTF-8; notably, this is important for wide characters.
This option defaults to off.
+.It Xo Ic terminal-overrides
+.Ar string
+.Xc
+Contains a list of entries which override terminal descriptions read using
+.Xr terminfo 5 .
+.Ar string
+is a comma-separated list of items each a colon-separated string made up of a
+terminal type pattern (matched using
+.Xr fnmatch 3 )
+and a set of
+.Em name=value
+entries.
+.Pp
+For example, to set the
+.Ql clear
+.Xr terminfo 5
+entry to
+.Ql \ee[H\ee[2J
+for all terminal types and the
+.Ql dch1
+entry to
+.Ql \ee[P
+for the
+.Ql rxvt
+terminal type, the option could be set to the string:
+.Bd -literal -offset indent
+"*:clear=\ee[H\ee[2J,rxvt:dch1=\ee[P"
+.Ed
+.Pp
+The terminal entry value is passed through
+.Xr strunvis 3
+before interpretation.
+The default value forcibly corrects the
+.Ql colors
+entry for terminals which support 88 or 256 colours:
+.Bd -literal -offset indent
+"*88col*:colors=88,*256col*:colors=256"
+.Ed
.It Xo Ic visual-activity
.Op Ic on | Ic off
.Xc
diff --git a/tmux.c b/tmux.c
index dd7b83f5..ff1bd4c4 100644
--- a/tmux.c
+++ b/tmux.c
@@ -367,6 +367,8 @@ main(int argc, char **argv)
options_set_number(&global_s_options, "status-utf8", 1);
else
options_set_number(&global_s_options, "status-utf8", 0);
+ options_set_string(&global_s_options,
+ "terminal-overrides", "*88col*:colors=88,*256col*:colors=256");
options_set_number(&global_s_options, "visual-activity", 0);
options_set_number(&global_s_options, "visual-bell", 0);
options_set_number(&global_s_options, "visual-content", 0);
diff --git a/tmux.h b/tmux.h
index 62a2dac0..37686e13 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1130,7 +1130,7 @@ void tty_detect_utf8(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int);
void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
-int tty_open(struct tty *, char **);
+int tty_open(struct tty *, const char *, char **);
void tty_close(struct tty *, int);
void tty_free(struct tty *, int);
void tty_write(void (*)(struct tty *, struct tty_ctx *), struct tty_ctx *);
@@ -1153,7 +1153,7 @@ void tty_cmd_reverseindex(struct tty *, struct tty_ctx *);
/* tty-term.c */
extern struct tty_terms tty_terms;
extern struct tty_term_code_entry tty_term_codes[NTTYCODE];
-struct tty_term *tty_term_find(char *, int, char **);
+struct tty_term *tty_term_find(char *, int, const char *, char **);
void tty_term_free(struct tty_term *);
int tty_term_has(struct tty_term *, enum tty_code_code);
const char *tty_term_string(struct tty_term *, enum tty_code_code);
diff --git a/tty-term.c b/tty-term.c
index c8b47783..2813be61 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -19,12 +19,15 @@
#include <sys/types.h>
#include <curses.h>
+#include <fnmatch.h>
+#include <stdlib.h>
#include <string.h>
#include <term.h>
+#include <vis.h>
#include "tmux.h"
-void tty_term_quirks(struct tty_term *);
+void tty_term_override(struct tty_term *, const char *);
char *tty_term_strip(const char *);
struct tty_terms tty_terms = SLIST_HEAD_INITIALIZER(tty_terms);
@@ -140,27 +143,87 @@ tty_term_strip(const char *s)
}
void
-tty_term_quirks(struct tty_term *term)
+tty_term_override(struct tty_term *term, const char *overrides)
{
- if (strncmp(term->name, "rxvt", 4) == 0) {
- /* rxvt supports dch1 but some termcap files do not have it. */
- if (!tty_term_has(term, TTYC_DCH1)) {
- term->codes[TTYC_DCH1].type = TTYCODE_STRING;
- term->codes[TTYC_DCH1].value.string = xstrdup("\033[P");
+ struct tty_term_code_entry *ent;
+ struct tty_code *code;
+ char *termnext, *termstr, *entnext, *entstr;
+ char *s, *ptr, *val;
+ const char *errstr;
+ u_int i;
+ int n, removeflag;
+
+ s = xstrdup(overrides);
+
+ termnext = s;
+ while ((termstr = strsep(&termnext, ",")) != NULL) {
+ entnext = termstr;
+
+ entstr = strsep(&entnext, ":");
+ if (entstr == NULL || entnext == NULL)
+ continue;
+ if (fnmatch(entstr, term->name, 0) != 0)
+ continue;
+ while ((entstr = strsep(&entnext, ":")) != NULL) {
+ if (*entstr == '\0')
+ continue;
+
+ val = NULL;
+ removeflag = 0;
+ if ((ptr = strchr(entstr, '=')) != NULL) {
+ *ptr++ = '\0';
+ val = xstrdup(ptr);
+ if (strunvis(val, ptr) == NULL) {
+ xfree(val);
+ val = xstrdup(ptr);
+ }
+ } else if (entstr[strlen(entstr) - 1] == '@') {
+ entstr[strlen(entstr) - 1] = '\0';
+ removeflag = 1;
+ }
+
+ for (i = 0; i < NTTYCODE; i++) {
+ ent = &tty_term_codes[i];
+ if (strcmp(entstr, ent->name) != 0)
+ continue;
+ code = &term->codes[ent->code];
+
+ if (removeflag) {
+ code->type = TTYCODE_NONE;
+ continue;
+ }
+ switch (ent->type) {
+ case TTYCODE_NONE:
+ break;
+ case TTYCODE_STRING:
+ xfree(code->value.string);
+ code->value.string = xstrdup(val);
+ code->type = ent->type;
+ break;
+ case TTYCODE_NUMBER:
+ n = strtonum(val, 0, INT_MAX, &errstr);
+ if (errstr != NULL)
+ break;
+ code->value.number = n;
+ code->type = ent->type;
+ break;
+ case TTYCODE_FLAG:
+ code->value.flag = 1;
+ code->type = ent->type;
+ break;
+ }
+ }
+
+ if (val != NULL)
+ xfree(val);
}
}
- if (strncmp(term->name, "xterm", 5) == 0) {
- /* xterm supports ich1 but some termcaps omit it. */
- if (!tty_term_has(term, TTYC_ICH1)) {
- term->codes[TTYC_ICH1].type = TTYCODE_STRING;
- term->codes[TTYC_ICH1].value.string = xstrdup("\033[@");
- }
- }
+ xfree(s);
}
struct tty_term *
-tty_term_find(char *name, int fd, char **cause)
+tty_term_find(char *name, int fd, const char *overrides, char **cause)
{
struct tty_term *term;
struct tty_term_code_entry *ent;
@@ -235,7 +298,7 @@ tty_term_find(char *name, int fd, char **cause)
break;
}
}
- tty_term_quirks(term);
+ tty_term_override(term, overrides);
/* Delete curses data. */
del_curterm(cur_term);
@@ -297,12 +360,8 @@ tty_term_find(char *name, int fd, char **cause)
*/
if (tty_term_number(term, TTYC_COLORS) == 256)
term->flags |= TERM_256COLOURS;
- if (strstr(name, "256col") != NULL) /* XXX HACK */
- term->flags |= TERM_256COLOURS;
if (tty_term_number(term, TTYC_COLORS) == 88)
term->flags |= TERM_88COLOURS;
- if (strstr(name, "88col") != NULL) /* XXX HACK */
- term->flags |= TERM_88COLOURS;
/*
* Terminals without xenl (eat newline glitch) wrap at at $COLUMNS - 1
diff --git a/tty.c b/tty.c
index 48b10f7d..d3a4ba1d 100644
--- a/tty.c
+++ b/tty.c
@@ -57,7 +57,7 @@ tty_init(struct tty *tty, char *path, char *term)
}
int
-tty_open(struct tty *tty, char **cause)
+tty_open(struct tty *tty, const char *overrides, char **cause)
{
int mode;
@@ -79,7 +79,8 @@ tty_open(struct tty *tty, char **cause)
else
tty->log_fd = -1;
- if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL)
+ tty->term = tty_term_find(tty->termname, tty->fd, overrides, cause);
+ if (tty->term == NULL)
goto error;
tty->in = buffer_create(BUFSIZ);