diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 0160f79e..d39cdeff 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-attach-session.c,v 1.30 2009-07-28 22:12:16 tcunha Exp $ */ +/* $Id: cmd-attach-session.c,v 1.31 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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 98a48074..21c7902a 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-new-session.c,v 1.49 2009-07-28 22:12:16 tcunha Exp $ */ +/* $Id: cmd-new-session.c,v 1.50 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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 b9d8d47c..6c2d11ba 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-option.c,v 1.70 2009-07-28 22:12:16 tcunha Exp $ */ +/* $Id: cmd-set-option.c,v 1.71 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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 00331c32..995ce163 100644 --- a/cmd-string.c +++ b/cmd-string.c @@ -1,4 +1,4 @@ -/* $Id: cmd-string.c,v 1.21 2009-07-14 06:54:38 nicm Exp $ */ +/* $Id: cmd-string.c,v 1.22 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -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.c b/tmux.c index b867a6fd..5ccd5887 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.153 2009-07-30 20:32:05 tcunha Exp $ */ +/* $Id: tmux.c,v 1.154 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -376,6 +376,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 edab6ab7..717c7f8a 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.401 2009-07-30 20:57:39 tcunha Exp $ */ +/* $Id: tmux.h,v 1.402 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1129,7 +1129,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 *); @@ -1152,7 +1152,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 04388512..09c249fd 100644 --- a/tty-term.c +++ b/tty-term.c @@ -1,4 +1,4 @@ -/* $Id: tty-term.c,v 1.24 2009-08-09 12:06:25 tcunha Exp $ */ +/* $Id: tty-term.c,v 1.25 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -19,12 +19,15 @@ #include #include +#include +#include #include #include +#include #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 548b1ad1..e6998857 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.119 2009-07-28 22:41:38 tcunha Exp $ */ +/* $Id: tty.c,v 1.120 2009-08-09 15:26:24 tcunha Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -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);