mirror of
https://github.com/tmux/tmux.git
synced 2026-05-31 06:36:18 +00:00
Merge branch 'master' into floating_panes
This commit is contained in:
@@ -41,6 +41,10 @@ endif
|
|||||||
AM_CPPFLAGS += -DDEBUG
|
AM_CPPFLAGS += -DDEBUG
|
||||||
endif
|
endif
|
||||||
AM_CPPFLAGS += -iquote.
|
AM_CPPFLAGS += -iquote.
|
||||||
|
if IS_ASAN
|
||||||
|
AM_CFLAGS += -fsanitize=address
|
||||||
|
AM_LDFLAGS += -fsanitize=address
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Set flags for Solaris.
|
# Set flags for Solaris.
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct session *s;
|
struct session *s;
|
||||||
struct window_pane *wp = target->wp, *swp;
|
struct window_pane *wp = target->wp, *swp;
|
||||||
u_int tty_ox, tty_oy, tty_sx, tty_sy;
|
u_int tty_ox, tty_oy, tty_sx, tty_sy;
|
||||||
|
int line_numbers;
|
||||||
|
|
||||||
if (args_has(args, 'q')) {
|
if (args_has(args, 'q')) {
|
||||||
window_pane_reset_mode_all(wp);
|
window_pane_reset_mode_all(wp);
|
||||||
@@ -86,10 +87,15 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
swp = source->wp;
|
swp = source->wp;
|
||||||
else
|
else
|
||||||
swp = wp;
|
swp = wp;
|
||||||
|
line_numbers = 1;
|
||||||
|
if (event != NULL && KEYC_IS_MOUSE(event->key))
|
||||||
|
line_numbers = 0;
|
||||||
if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) {
|
if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) {
|
||||||
|
window_copy_set_line_numbers(wp, line_numbers);
|
||||||
if (args_has(args, 'M'))
|
if (args_has(args, 'M'))
|
||||||
window_copy_start_drag(c, &event->m);
|
window_copy_start_drag(c, &event->m);
|
||||||
}
|
} else
|
||||||
|
window_copy_set_line_numbers(wp, line_numbers);
|
||||||
if (args_has(args, 'u'))
|
if (args_has(args, 'u'))
|
||||||
window_copy_pageup(wp, 0);
|
window_copy_pageup(wp, 0);
|
||||||
if (args_has(args, 'd'))
|
if (args_has(args, 'd'))
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||||
item, &cause);
|
item, &cause);
|
||||||
} else if (args_has(args, 'p')) {
|
} else if (args_has(args, 'p')) {
|
||||||
size = args_strtonum_and_expand(args, 'l', 0, 100, item,
|
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
|
||||||
&cause);
|
&cause);
|
||||||
if (cause == NULL)
|
if (cause == NULL)
|
||||||
size = curval * size / 100;
|
size = curval * size / 100;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
tmp = args_get(args, 's');
|
tmp = args_get(args, 's');
|
||||||
if (tmp != NULL) {
|
if (tmp != NULL) {
|
||||||
name = format_single(item, tmp, c, NULL, NULL, NULL);
|
name = format_single(item, tmp, c, NULL, NULL, NULL);
|
||||||
newname = session_check_name(name);
|
newname = clean_name(name, "#:.");
|
||||||
if (newname == NULL) {
|
if (newname == NULL) {
|
||||||
cmdq_error(item, "invalid session: %s", name);
|
cmdq_error(item, "invalid session: %s", name);
|
||||||
free(name);
|
free(name);
|
||||||
@@ -142,7 +142,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
else if (groupwith != NULL)
|
else if (groupwith != NULL)
|
||||||
prefix = xstrdup(groupwith->name);
|
prefix = xstrdup(groupwith->name);
|
||||||
else {
|
else {
|
||||||
prefix = session_check_name(group);
|
prefix = clean_name(group, "#:.");
|
||||||
if (prefix == NULL) {
|
if (prefix == NULL) {
|
||||||
cmdq_error(item, "invalid session group: %s",
|
cmdq_error(item, "invalid session group: %s",
|
||||||
group);
|
group);
|
||||||
|
|||||||
10
cmd-parse.y
10
cmd-parse.y
@@ -37,6 +37,8 @@ static void printflike(1,2) yyerror(const char *, ...);
|
|||||||
static char *yylex_token(int);
|
static char *yylex_token(int);
|
||||||
static char *yylex_format(void);
|
static char *yylex_format(void);
|
||||||
|
|
||||||
|
#define CMD_PARSE_MAX_ENVIRON_LEN 16384
|
||||||
|
|
||||||
struct cmd_parse_scope {
|
struct cmd_parse_scope {
|
||||||
int flag;
|
int flag;
|
||||||
TAILQ_ENTRY (cmd_parse_scope) entry;
|
TAILQ_ENTRY (cmd_parse_scope) entry;
|
||||||
@@ -232,6 +234,10 @@ assignment : EQUALS
|
|||||||
flag = flag && scope->flag;
|
flag = flag && scope->flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($1) > CMD_PARSE_MAX_ENVIRON_LEN) {
|
||||||
|
yyerror("environment variable is too long");
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
if ((~flags & CMD_PARSE_PARSEONLY) && flag)
|
if ((~flags & CMD_PARSE_PARSEONLY) && flag)
|
||||||
environ_put(global_environ, $1, 0);
|
environ_put(global_environ, $1, 0);
|
||||||
free($1);
|
free($1);
|
||||||
@@ -250,6 +256,10 @@ hidden_assignment : HIDDEN EQUALS
|
|||||||
flag = flag && scope->flag;
|
flag = flag && scope->flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($2) > CMD_PARSE_MAX_ENVIRON_LEN) {
|
||||||
|
yyerror("environment variable is too long");
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
if ((~flags & CMD_PARSE_PARSEONLY) && flag)
|
if ((~flags & CMD_PARSE_PARSEONLY) && flag)
|
||||||
environ_put(global_environ, $2, ENVIRON_HIDDEN);
|
environ_put(global_environ, $2, ENVIRON_HIDDEN);
|
||||||
free($2);
|
free($2);
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
cmdq_error(item, "fork error: %s", strerror(errno));
|
cmdq_error(item, "fork error: %s", strerror(errno));
|
||||||
|
|
||||||
|
close(pipe_fd[0]);
|
||||||
|
close(pipe_fd[1]);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
char *newname, *tmp;
|
char *newname, *tmp;
|
||||||
|
|
||||||
tmp = format_single_from_target(item, args_string(args, 0));
|
tmp = format_single_from_target(item, args_string(args, 0));
|
||||||
newname = session_check_name(tmp);
|
newname = clean_name(tmp, "#:.");
|
||||||
if (newname == NULL) {
|
if (newname == NULL) {
|
||||||
cmdq_error(item, "invalid session: %s", tmp);
|
cmdq_error(item, "invalid session: %s", tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|||||||
@@ -198,8 +198,17 @@ cmd_run_shell_timer(__unused int fd, __unused short events, void* arg)
|
|||||||
}
|
}
|
||||||
if (job_run(cmd, 0, NULL, NULL, cdata->s, cdata->cwd, NULL,
|
if (job_run(cmd, 0, NULL, NULL, cdata->s, cdata->cwd, NULL,
|
||||||
cmd_run_shell_callback, cmd_run_shell_free, cdata,
|
cmd_run_shell_callback, cmd_run_shell_free, cdata,
|
||||||
cdata->flags, -1, -1) == NULL)
|
cdata->flags, -1, -1) == NULL) {
|
||||||
|
if (cdata->item == NULL)
|
||||||
|
status_message_set(c, -1, 1, 0, 0,
|
||||||
|
"failed to run command: %s", cmd);
|
||||||
|
else {
|
||||||
|
cmdq_error(cdata->item,
|
||||||
|
"failed to run command: %s", cmd);
|
||||||
|
cmdq_continue(cdata->item);
|
||||||
|
}
|
||||||
cmd_run_shell_free(cdata);
|
cmd_run_shell_free(cdata);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
compat.h
3
compat.h
@@ -463,6 +463,9 @@ int utf8proc_wctomb(char *, wchar_t);
|
|||||||
#ifdef NEED_FUZZING
|
#ifdef NEED_FUZZING
|
||||||
/* tmux.c */
|
/* tmux.c */
|
||||||
#define main __weak main
|
#define main __weak main
|
||||||
|
#define regcomp(preg, pattern, cflags) (0)
|
||||||
|
#define regexec(preg, string, nmatch, pmatch, eflags) (REG_NOMATCH)
|
||||||
|
#define regfree(preg) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* getopt.c */
|
/* getopt.c */
|
||||||
|
|||||||
@@ -73,6 +73,15 @@ AC_ARG_ENABLE(
|
|||||||
)
|
)
|
||||||
AM_CONDITIONAL(IS_OPTIMIZED, test "x$enable_optimizations" = xyes)
|
AM_CONDITIONAL(IS_OPTIMIZED, test "x$enable_optimizations" = xyes)
|
||||||
|
|
||||||
|
# Is this --enable-asan?
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
asan,
|
||||||
|
AS_HELP_STRING(--enable-asan, enable ASAN build flags),
|
||||||
|
,
|
||||||
|
enable_asan=no
|
||||||
|
)
|
||||||
|
AM_CONDITIONAL(IS_ASAN, test "x$enable_asan" = xyes)
|
||||||
|
|
||||||
# Is this a static build?
|
# Is this a static build?
|
||||||
AC_ARG_ENABLE(
|
AC_ARG_ENABLE(
|
||||||
static,
|
static,
|
||||||
|
|||||||
@@ -207,10 +207,12 @@ control_free_sub(struct control_state *cs, struct control_sub *csub)
|
|||||||
|
|
||||||
RB_FOREACH_SAFE(csp, control_sub_panes, &csub->panes, csp1) {
|
RB_FOREACH_SAFE(csp, control_sub_panes, &csub->panes, csp1) {
|
||||||
RB_REMOVE(control_sub_panes, &csub->panes, csp);
|
RB_REMOVE(control_sub_panes, &csub->panes, csp);
|
||||||
|
free(csp->last);
|
||||||
free(csp);
|
free(csp);
|
||||||
}
|
}
|
||||||
RB_FOREACH_SAFE(csw, control_sub_windows, &csub->windows, csw1) {
|
RB_FOREACH_SAFE(csw, control_sub_windows, &csub->windows, csw1) {
|
||||||
RB_REMOVE(control_sub_windows, &csub->windows, csw);
|
RB_REMOVE(control_sub_windows, &csub->windows, csw);
|
||||||
|
free(csw->last);
|
||||||
free(csw);
|
free(csw);
|
||||||
}
|
}
|
||||||
free(csub->last);
|
free(csub->last);
|
||||||
@@ -298,6 +300,7 @@ control_reset_offsets(struct client *c)
|
|||||||
struct control_pane *cp, *cp1;
|
struct control_pane *cp, *cp1;
|
||||||
|
|
||||||
RB_FOREACH_SAFE(cp, control_panes, &cs->panes, cp1) {
|
RB_FOREACH_SAFE(cp, control_panes, &cs->panes, cp1) {
|
||||||
|
control_discard_pane(c, cp);
|
||||||
RB_REMOVE(control_panes, &cs->panes, cp);
|
RB_REMOVE(control_panes, &cs->panes, cp);
|
||||||
free(cp);
|
free(cp);
|
||||||
}
|
}
|
||||||
@@ -352,6 +355,9 @@ control_set_pane_off(struct client *c, struct window_pane *wp)
|
|||||||
struct control_pane *cp;
|
struct control_pane *cp;
|
||||||
|
|
||||||
cp = control_add_pane(c, wp);
|
cp = control_add_pane(c, wp);
|
||||||
|
control_discard_pane(c, cp);
|
||||||
|
memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
|
||||||
|
memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
|
||||||
cp->flags |= CONTROL_PANE_OFF;
|
cp->flags |= CONTROL_PANE_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
file.c
21
file.c
@@ -804,7 +804,7 @@ file_read_cancel(struct client_files *files, struct imsg *imsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a write ready message (server). */
|
/* Handle a write ready message (server). */
|
||||||
void
|
int
|
||||||
file_write_ready(struct client_files *files, struct imsg *imsg)
|
file_write_ready(struct client_files *files, struct imsg *imsg)
|
||||||
{
|
{
|
||||||
struct msg_write_ready *msg = imsg->data;
|
struct msg_write_ready *msg = imsg->data;
|
||||||
@@ -812,19 +812,20 @@ file_write_ready(struct client_files *files, struct imsg *imsg)
|
|||||||
struct client_file find, *cf;
|
struct client_file find, *cf;
|
||||||
|
|
||||||
if (msglen != sizeof *msg)
|
if (msglen != sizeof *msg)
|
||||||
fatalx("bad MSG_WRITE_READY size");
|
return (-1);
|
||||||
find.stream = msg->stream;
|
find.stream = msg->stream;
|
||||||
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
||||||
return;
|
return (0);
|
||||||
if (msg->error != 0) {
|
if (msg->error != 0) {
|
||||||
cf->error = msg->error;
|
cf->error = msg->error;
|
||||||
file_fire_done(cf);
|
file_fire_done(cf);
|
||||||
} else
|
} else
|
||||||
file_push(cf);
|
file_push(cf);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle read data message (server). */
|
/* Handle read data message (server). */
|
||||||
void
|
int
|
||||||
file_read_data(struct client_files *files, struct imsg *imsg)
|
file_read_data(struct client_files *files, struct imsg *imsg)
|
||||||
{
|
{
|
||||||
struct msg_read_data *msg = imsg->data;
|
struct msg_read_data *msg = imsg->data;
|
||||||
@@ -834,10 +835,10 @@ file_read_data(struct client_files *files, struct imsg *imsg)
|
|||||||
size_t bsize = msglen - sizeof *msg;
|
size_t bsize = msglen - sizeof *msg;
|
||||||
|
|
||||||
if (msglen < sizeof *msg)
|
if (msglen < sizeof *msg)
|
||||||
fatalx("bad MSG_READ_DATA size");
|
return (-1);
|
||||||
find.stream = msg->stream;
|
find.stream = msg->stream;
|
||||||
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
||||||
return;
|
return (0);
|
||||||
|
|
||||||
log_debug("file %d read %zu bytes", cf->stream, bsize);
|
log_debug("file %d read %zu bytes", cf->stream, bsize);
|
||||||
if (cf->error == 0 && !cf->closed) {
|
if (cf->error == 0 && !cf->closed) {
|
||||||
@@ -847,10 +848,11 @@ file_read_data(struct client_files *files, struct imsg *imsg)
|
|||||||
} else
|
} else
|
||||||
file_fire_read(cf);
|
file_fire_read(cf);
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a read done message (server). */
|
/* Handle a read done message (server). */
|
||||||
void
|
int
|
||||||
file_read_done(struct client_files *files, struct imsg *imsg)
|
file_read_done(struct client_files *files, struct imsg *imsg)
|
||||||
{
|
{
|
||||||
struct msg_read_done *msg = imsg->data;
|
struct msg_read_done *msg = imsg->data;
|
||||||
@@ -858,12 +860,13 @@ file_read_done(struct client_files *files, struct imsg *imsg)
|
|||||||
struct client_file find, *cf;
|
struct client_file find, *cf;
|
||||||
|
|
||||||
if (msglen != sizeof *msg)
|
if (msglen != sizeof *msg)
|
||||||
fatalx("bad MSG_READ_DONE size");
|
return (-1);
|
||||||
find.stream = msg->stream;
|
find.stream = msg->stream;
|
||||||
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
if ((cf = RB_FIND(client_files, files, &find)) == NULL)
|
||||||
return;
|
return (0);
|
||||||
|
|
||||||
log_debug("file %d read done", cf->stream);
|
log_debug("file %d read done", cf->stream);
|
||||||
cf->error = msg->error;
|
cf->error = msg->error;
|
||||||
file_fire_done(cf);
|
file_fire_done(cf);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
78
format.c
78
format.c
@@ -120,6 +120,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
|||||||
/* Limit on recursion. */
|
/* Limit on recursion. */
|
||||||
#define FORMAT_LOOP_LIMIT 100
|
#define FORMAT_LOOP_LIMIT 100
|
||||||
|
|
||||||
|
/* Limit on time taken (milliseconds). */
|
||||||
|
#define FORMAT_TIME_LIMIT 100
|
||||||
|
|
||||||
/* Format expand flags. */
|
/* Format expand flags. */
|
||||||
#define FORMAT_EXPAND_TIME 0x1
|
#define FORMAT_EXPAND_TIME 0x1
|
||||||
#define FORMAT_EXPAND_NOJOBS 0x2
|
#define FORMAT_EXPAND_NOJOBS 0x2
|
||||||
@@ -169,9 +172,11 @@ RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
|
|||||||
struct format_expand_state {
|
struct format_expand_state {
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
u_int loop;
|
u_int loop;
|
||||||
|
uint64_t start_time;
|
||||||
|
int flags;
|
||||||
|
|
||||||
time_t time;
|
time_t time;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
int flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Format modifier. */
|
/* Format modifier. */
|
||||||
@@ -292,6 +297,7 @@ format_copy_state(struct format_expand_state *to,
|
|||||||
to->time = from->time;
|
to->time = from->time;
|
||||||
memcpy(&to->tm, &from->tm, sizeof to->tm);
|
memcpy(&to->tm, &from->tm, sizeof to->tm);
|
||||||
to->flags = from->flags|flags;
|
to->flags = from->flags|flags;
|
||||||
|
to->start_time = from->start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format job update callback. */
|
/* Format job update callback. */
|
||||||
@@ -4155,15 +4161,33 @@ found:
|
|||||||
return (found);
|
return (found);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if format has not taken too long. */
|
||||||
|
static int
|
||||||
|
format_check_time(struct format_expand_state *es)
|
||||||
|
{
|
||||||
|
uint64_t t = get_timer();
|
||||||
|
|
||||||
|
if (t - es->start_time < FORMAT_TIME_LIMIT)
|
||||||
|
return (1);
|
||||||
|
t -= es->start_time;
|
||||||
|
|
||||||
|
format_log(es, "reached time limit (%llu)", (unsigned long long)t);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Unescape escaped characters. */
|
/* Unescape escaped characters. */
|
||||||
static char *
|
static char *
|
||||||
format_unescape(const char *s)
|
format_unescape(struct format_expand_state *es, const char *s)
|
||||||
{
|
{
|
||||||
char *out, *cp;
|
char *out, *cp;
|
||||||
int brackets = 0;
|
int brackets = 0;
|
||||||
|
|
||||||
cp = out = xmalloc(strlen(s) + 1);
|
cp = out = xmalloc(strlen(s) + 1);
|
||||||
for (; *s != '\0'; s++) {
|
for (; *s != '\0'; s++) {
|
||||||
|
if (!format_check_time(es)){
|
||||||
|
free(out);
|
||||||
|
return (xstrdup(""));
|
||||||
|
}
|
||||||
if (*s == '#' && s[1] == '{')
|
if (*s == '#' && s[1] == '{')
|
||||||
brackets++;
|
brackets++;
|
||||||
if (brackets == 0 &&
|
if (brackets == 0 &&
|
||||||
@@ -4182,13 +4206,17 @@ format_unescape(const char *s)
|
|||||||
|
|
||||||
/* Remove escaped characters. */
|
/* Remove escaped characters. */
|
||||||
static char *
|
static char *
|
||||||
format_strip(const char *s)
|
format_strip(struct format_expand_state *es, const char *s)
|
||||||
{
|
{
|
||||||
char *out, *cp;
|
char *out, *cp;
|
||||||
int brackets = 0;
|
int brackets = 0;
|
||||||
|
|
||||||
cp = out = xmalloc(strlen(s) + 1);
|
cp = out = xmalloc(strlen(s) + 1);
|
||||||
for (; *s != '\0'; s++) {
|
for (; *s != '\0'; s++) {
|
||||||
|
if (!format_check_time(es)){
|
||||||
|
free(out);
|
||||||
|
return (xstrdup(""));
|
||||||
|
}
|
||||||
if (*s == '#' && s[1] == '{')
|
if (*s == '#' && s[1] == '{')
|
||||||
brackets++;
|
brackets++;
|
||||||
if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
|
if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
|
||||||
@@ -4204,13 +4232,16 @@ format_strip(const char *s)
|
|||||||
return (out);
|
return (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Skip until end. */
|
/* Skip until end. */
|
||||||
const char *
|
static const char *
|
||||||
format_skip(const char *s, const char *end)
|
format_skip1(struct format_expand_state *es, const char *s, const char *end)
|
||||||
{
|
{
|
||||||
int brackets = 0;
|
int brackets = 0;
|
||||||
|
|
||||||
for (; *s != '\0'; s++) {
|
for (; *s != '\0'; s++) {
|
||||||
|
if (es != NULL && !format_check_time(es))
|
||||||
|
return (NULL);
|
||||||
if (*s == '#' && s[1] == '{')
|
if (*s == '#' && s[1] == '{')
|
||||||
brackets++;
|
brackets++;
|
||||||
if (*s == '#' &&
|
if (*s == '#' &&
|
||||||
@@ -4229,6 +4260,13 @@ format_skip(const char *s, const char *end)
|
|||||||
return (s);
|
return (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip until end. */
|
||||||
|
const char *
|
||||||
|
format_skip(const char *s, const char *end)
|
||||||
|
{
|
||||||
|
return (format_skip1(NULL, s, end));
|
||||||
|
}
|
||||||
|
|
||||||
/* Return left and right alternatives separated by commas. */
|
/* Return left and right alternatives separated by commas. */
|
||||||
static int
|
static int
|
||||||
format_choose(struct format_expand_state *es, const char *s, char **left,
|
format_choose(struct format_expand_state *es, const char *s, char **left,
|
||||||
@@ -4237,7 +4275,7 @@ format_choose(struct format_expand_state *es, const char *s, char **left,
|
|||||||
const char *cp;
|
const char *cp;
|
||||||
char *left0, *right0;
|
char *left0, *right0;
|
||||||
|
|
||||||
cp = format_skip(s, ",");
|
cp = format_skip1(es, s, ",");
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
left0 = xstrndup(s, cp - s);
|
left0 = xstrndup(s, cp - s);
|
||||||
@@ -4368,7 +4406,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
|||||||
|
|
||||||
/* Single argument with no wrapper character. */
|
/* Single argument with no wrapper character. */
|
||||||
if (!ispunct((u_char)cp[1]) || cp[1] == '-') {
|
if (!ispunct((u_char)cp[1]) || cp[1] == '-') {
|
||||||
end = format_skip(cp + 1, ":;");
|
end = format_skip1(es, cp + 1, ":;");
|
||||||
if (end == NULL)
|
if (end == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -4391,7 +4429,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
|||||||
cp++;
|
cp++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
end = format_skip(cp + 1, last);
|
end = format_skip1(es, cp + 1, last);
|
||||||
if (end == NULL)
|
if (end == NULL)
|
||||||
break;
|
break;
|
||||||
cp++;
|
cp++;
|
||||||
@@ -4505,7 +4543,7 @@ format_bool_op_n(struct format_expand_state *es, const char *fmt, int and)
|
|||||||
cp1 = fmt;
|
cp1 = fmt;
|
||||||
|
|
||||||
while (and ? result : !result) {
|
while (and ? result : !result) {
|
||||||
cp2 = format_skip(cp1, ",");
|
cp2 = format_skip1(es, cp1, ",");
|
||||||
|
|
||||||
if (cp2 == NULL)
|
if (cp2 == NULL)
|
||||||
raw = xstrdup(cp1);
|
raw = xstrdup(cp1);
|
||||||
@@ -5085,7 +5123,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
else if (fm->argc >= 2 &&
|
else if (fm->argc >= 2 &&
|
||||||
strchr(fm->argv[0], 'f') != NULL) {
|
strchr(fm->argv[0], 'f') != NULL) {
|
||||||
free(time_format);
|
free(time_format);
|
||||||
time_format = format_strip(fm->argv[1]);
|
time_format = format_strip(es, fm->argv[1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
@@ -5201,7 +5239,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
/* Is this a literal string? */
|
/* Is this a literal string? */
|
||||||
if (modifiers & FORMAT_LITERAL) {
|
if (modifiers & FORMAT_LITERAL) {
|
||||||
format_log(es, "literal string is '%s'", copy);
|
format_log(es, "literal string is '%s'", copy);
|
||||||
value = format_unescape(copy);
|
value = format_unescape(es, copy);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5277,6 +5315,12 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
else {
|
else {
|
||||||
value = xstrdup("");
|
value = xstrdup("");
|
||||||
for (i = 0; i < nrep; i++) {
|
for (i = 0; i < nrep; i++) {
|
||||||
|
if (!format_check_time(es)) {
|
||||||
|
free(right);
|
||||||
|
free(left);
|
||||||
|
free(value);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
xasprintf(&new, "%s%s", value, left);
|
xasprintf(&new, "%s%s", value, left);
|
||||||
free(value);
|
free(value);
|
||||||
value = new;
|
value = new;
|
||||||
@@ -5348,7 +5392,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
*/
|
*/
|
||||||
cp = copy + 1;
|
cp = copy + 1;
|
||||||
while (1) {
|
while (1) {
|
||||||
cp2 = format_skip(cp, ",");
|
cp2 = format_skip1(es, cp, ",");
|
||||||
if (cp2 == NULL) {
|
if (cp2 == NULL) {
|
||||||
format_log(es,
|
format_log(es,
|
||||||
"no condition matched in '%s'; using last "
|
"no condition matched in '%s'; using last "
|
||||||
@@ -5383,7 +5427,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cp = cp2 + 1;
|
cp = cp2 + 1;
|
||||||
cp2 = format_skip(cp, ",");
|
cp2 = format_skip1(es, cp, ",");
|
||||||
if (format_true(found)) {
|
if (format_true(found)) {
|
||||||
format_log(es, "condition '%s' is true",
|
format_log(es, "condition '%s' is true",
|
||||||
condition);
|
condition);
|
||||||
@@ -5551,7 +5595,7 @@ format_expand1(struct format_expand_state *es, const char *fmt)
|
|||||||
int ch, brackets;
|
int ch, brackets;
|
||||||
char expanded[8192];
|
char expanded[8192];
|
||||||
|
|
||||||
if (fmt == NULL || *fmt == '\0')
|
if (fmt == NULL || *fmt == '\0' || !format_check_time(es))
|
||||||
return (xstrdup(""));
|
return (xstrdup(""));
|
||||||
|
|
||||||
if (es->loop == FORMAT_LOOP_LIMIT) {
|
if (es->loop == FORMAT_LOOP_LIMIT) {
|
||||||
@@ -5633,7 +5677,7 @@ format_expand1(struct format_expand_state *es, const char *fmt)
|
|||||||
fmt += n + 1;
|
fmt += n + 1;
|
||||||
continue;
|
continue;
|
||||||
case '{':
|
case '{':
|
||||||
ptr = format_skip((char *)fmt - 2, "}");
|
ptr = format_skip1(es, (char *)fmt - 2, "}");
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
break;
|
break;
|
||||||
n = ptr - fmt;
|
n = ptr - fmt;
|
||||||
@@ -5656,7 +5700,7 @@ format_expand1(struct format_expand_state *es, const char *fmt)
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
if (*ptr == '[') {
|
if (*ptr == '[') {
|
||||||
style_end = format_skip(fmt - 2, "]");
|
style_end = format_skip1(es, fmt - 2, "]");
|
||||||
format_log(es, "found #*%zu[", n);
|
format_log(es, "found #*%zu[", n);
|
||||||
while (len - off < n + 2) {
|
while (len - off < n + 2) {
|
||||||
buf = xreallocarray(buf, 2, len);
|
buf = xreallocarray(buf, 2, len);
|
||||||
@@ -5720,6 +5764,7 @@ format_expand_time(struct format_tree *ft, const char *fmt)
|
|||||||
memset(&es, 0, sizeof es);
|
memset(&es, 0, sizeof es);
|
||||||
es.ft = ft;
|
es.ft = ft;
|
||||||
es.flags = FORMAT_EXPAND_TIME;
|
es.flags = FORMAT_EXPAND_TIME;
|
||||||
|
es.start_time = get_timer();
|
||||||
return (format_expand1(&es, fmt));
|
return (format_expand1(&es, fmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5732,6 +5777,7 @@ format_expand(struct format_tree *ft, const char *fmt)
|
|||||||
memset(&es, 0, sizeof es);
|
memset(&es, 0, sizeof es);
|
||||||
es.ft = ft;
|
es.ft = ft;
|
||||||
es.flags = 0;
|
es.flags = 0;
|
||||||
|
es.start_time = get_timer();
|
||||||
return (format_expand1(&es, fmt));
|
return (format_expand1(&es, fmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,19 +122,13 @@ sixel_set_pixel(struct sixel_image *si, u_int x, u_int y, u_int c)
|
|||||||
static int
|
static int
|
||||||
sixel_parse_write(struct sixel_image *si, u_int ch)
|
sixel_parse_write(struct sixel_image *si, u_int ch)
|
||||||
{
|
{
|
||||||
struct sixel_line *sl;
|
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
if (sixel_parse_expand_lines(si, si->dy + 6) != 0)
|
|
||||||
return (1);
|
|
||||||
sl = &si->lines[si->dy];
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
if (sixel_parse_expand_line(si, sl, si->dx + 1) != 0)
|
if (ch & (1 << i)) {
|
||||||
|
if (sixel_set_pixel(si, si->dx, si->dy + i, si->dc))
|
||||||
return (1);
|
return (1);
|
||||||
if (ch & (1 << i))
|
}
|
||||||
sl->data[si->dx] = si->dc;
|
|
||||||
sl++;
|
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
7
image.c
7
image.c
@@ -53,14 +53,12 @@ image_log(struct image *im, const char* from, const char* fmt, ...)
|
|||||||
static void
|
static void
|
||||||
image_free(struct image *im)
|
image_free(struct image *im)
|
||||||
{
|
{
|
||||||
struct screen *s = im->s;
|
|
||||||
|
|
||||||
image_log(im, __func__, NULL);
|
image_log(im, __func__, NULL);
|
||||||
|
|
||||||
TAILQ_REMOVE(&all_images, im, all_entry);
|
TAILQ_REMOVE(&all_images, im, all_entry);
|
||||||
all_images_count--;
|
all_images_count--;
|
||||||
|
|
||||||
TAILQ_REMOVE(&s->images, im, entry);
|
TAILQ_REMOVE(im->list, im, entry);
|
||||||
sixel_free(im->data);
|
sixel_free(im->data);
|
||||||
free(im->fallback);
|
free(im->fallback);
|
||||||
free(im);
|
free(im);
|
||||||
@@ -137,7 +135,8 @@ image_store(struct screen *s, struct sixel_image *si)
|
|||||||
image_fallback(&im->fallback, im->sx, im->sy);
|
image_fallback(&im->fallback, im->sx, im->sy);
|
||||||
|
|
||||||
image_log(im, __func__, NULL);
|
image_log(im, __func__, NULL);
|
||||||
TAILQ_INSERT_TAIL(&s->images, im, entry);
|
im->list = &s->images;
|
||||||
|
TAILQ_INSERT_TAIL(im->list, im, entry);
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&all_images, im, all_entry);
|
TAILQ_INSERT_TAIL(&all_images, im, all_entry);
|
||||||
if (++all_images_count == MAX_IMAGE_COUNT)
|
if (++all_images_count == MAX_IMAGE_COUNT)
|
||||||
|
|||||||
5
input.c
5
input.c
@@ -2663,13 +2663,10 @@ input_exit_osc(struct input_ctx *ictx)
|
|||||||
input_osc_4(ictx, p);
|
input_osc_4(ictx, p);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
if (utf8_isvalid(p)) {
|
if (screen_set_path(sctx->s, p) && wp != NULL) {
|
||||||
screen_set_path(sctx->s, p);
|
|
||||||
if (wp != NULL) {
|
|
||||||
server_redraw_window_borders(wp->window);
|
server_redraw_window_borders(wp->window);
|
||||||
server_status_window(wp->window);
|
server_status_window(wp->window);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
input_osc_8(ictx, p);
|
input_osc_8(ictx, p);
|
||||||
|
|||||||
@@ -474,6 +474,10 @@ key_bindings_init(void)
|
|||||||
"bind -n MouseDown1Status { if -F '#{&&:#{pane_active},#{!#{pane_minimised_flag}}}' { minimise-pane -t= } { switch-client -t= } }",
|
"bind -n MouseDown1Status { if -F '#{&&:#{pane_active},#{!#{pane_minimised_flag}}}' { minimise-pane -t= } { switch-client -t= } }",
|
||||||
"bind -n C-MouseDown1Status { swap-window -t@ }",
|
"bind -n C-MouseDown1Status { swap-window -t@ }",
|
||||||
|
|
||||||
|
/* Mouse button 1 down on default pane-border-format */
|
||||||
|
"bind -n MouseDown1Control9 { display-menu -t= -xM -yM -O -T 'Kill pane #{pane_index}?' 'Yes' 'y' { kill-pane -t= } 'No' 'n' {}}",
|
||||||
|
"bind -n MouseDown1Control8 { resize-pane -Z }",
|
||||||
|
|
||||||
/* Mouse wheel down on status line. */
|
/* Mouse wheel down on status line. */
|
||||||
"bind -n WheelDownStatus { next-window }",
|
"bind -n WheelDownStatus { next-window }",
|
||||||
|
|
||||||
@@ -506,7 +510,7 @@ key_bindings_init(void)
|
|||||||
"bind -Tcopy-mode C-b { send -X cursor-left }",
|
"bind -Tcopy-mode C-b { send -X cursor-left }",
|
||||||
"bind -Tcopy-mode C-g { send -X clear-selection }",
|
"bind -Tcopy-mode C-g { send -X clear-selection }",
|
||||||
"bind -Tcopy-mode C-k { send -X copy-pipe-end-of-line-and-cancel }",
|
"bind -Tcopy-mode C-k { send -X copy-pipe-end-of-line-and-cancel }",
|
||||||
"bind -Tcopy-mode C-l { send -X cursor-centre-vertical }",
|
"bind -Tcopy-mode C-l { send -X recentre-top-bottom }",
|
||||||
"bind -Tcopy-mode M-l { send -X cursor-centre-horizontal }",
|
"bind -Tcopy-mode M-l { send -X cursor-centre-horizontal }",
|
||||||
"bind -Tcopy-mode C-n { send -X cursor-down }",
|
"bind -Tcopy-mode C-n { send -X cursor-down }",
|
||||||
"bind -Tcopy-mode C-p { send -X cursor-up }",
|
"bind -Tcopy-mode C-p { send -X cursor-up }",
|
||||||
@@ -515,6 +519,7 @@ key_bindings_init(void)
|
|||||||
"bind -Tcopy-mode C-v { send -X page-down }",
|
"bind -Tcopy-mode C-v { send -X page-down }",
|
||||||
"bind -Tcopy-mode C-w { send -X copy-pipe-and-cancel }",
|
"bind -Tcopy-mode C-w { send -X copy-pipe-and-cancel }",
|
||||||
"bind -Tcopy-mode Escape { send -X cancel }",
|
"bind -Tcopy-mode Escape { send -X cancel }",
|
||||||
|
"bind -Tcopy-mode C-[ { send -X cancel }",
|
||||||
"bind -Tcopy-mode Space { send -X page-down }",
|
"bind -Tcopy-mode Space { send -X page-down }",
|
||||||
"bind -Tcopy-mode , { send -X jump-reverse }",
|
"bind -Tcopy-mode , { send -X jump-reverse }",
|
||||||
"bind -Tcopy-mode \\; { send -X jump-again }",
|
"bind -Tcopy-mode \\; { send -X jump-again }",
|
||||||
@@ -588,6 +593,7 @@ key_bindings_init(void)
|
|||||||
"bind -Tcopy-mode-vi C-v { send -X rectangle-toggle }",
|
"bind -Tcopy-mode-vi C-v { send -X rectangle-toggle }",
|
||||||
"bind -Tcopy-mode-vi C-y { send -X scroll-up }",
|
"bind -Tcopy-mode-vi C-y { send -X scroll-up }",
|
||||||
"bind -Tcopy-mode-vi Escape { send -X clear-selection }",
|
"bind -Tcopy-mode-vi Escape { send -X clear-selection }",
|
||||||
|
"bind -Tcopy-mode-vi C-[ { send -X clear-selection }",
|
||||||
"bind -Tcopy-mode-vi Space { send -X begin-selection }",
|
"bind -Tcopy-mode-vi Space { send -X begin-selection }",
|
||||||
"bind -Tcopy-mode-vi '$' { send -X end-of-line }",
|
"bind -Tcopy-mode-vi '$' { send -X end-of-line }",
|
||||||
"bind -Tcopy-mode-vi , { send -X jump-reverse }",
|
"bind -Tcopy-mode-vi , { send -X jump-reverse }",
|
||||||
|
|||||||
@@ -183,13 +183,14 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int npanes, ncells, sx = 0, sy = 0;
|
u_int npanes, ncells, sx = 0, sy = 0;
|
||||||
u_short csum;
|
u_short csum;
|
||||||
|
int n;
|
||||||
|
|
||||||
/* Check validity. */
|
/* Check validity. */
|
||||||
if (sscanf(layout, "%hx,", &csum) != 1) {
|
if (sscanf(layout, "%hx,%n", &csum, &n) != 1 || n != 5) {
|
||||||
*cause = xstrdup("invalid layout");
|
*cause = xstrdup("invalid layout");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
layout += 5;
|
layout += n;
|
||||||
if (csum != layout_checksum(layout)) {
|
if (csum != layout_checksum(layout)) {
|
||||||
*cause = xstrdup("invalid layout");
|
*cause = xstrdup("invalid layout");
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|||||||
1
menu.c
1
menu.c
@@ -471,6 +471,7 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
|
|||||||
case '\r':
|
case '\r':
|
||||||
goto chosen;
|
goto chosen;
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
|
case '['|KEYC_CTRL:
|
||||||
case 'c'|KEYC_CTRL:
|
case 'c'|KEYC_CTRL:
|
||||||
case 'g'|KEYC_CTRL:
|
case 'g'|KEYC_CTRL:
|
||||||
case 'q':
|
case 'q':
|
||||||
|
|||||||
@@ -301,6 +301,8 @@ mode_tree_clear_tagged(struct mode_tree_list *mtl)
|
|||||||
void
|
void
|
||||||
mode_tree_up(struct mode_tree_data *mtd, int wrap)
|
mode_tree_up(struct mode_tree_data *mtd, int wrap)
|
||||||
{
|
{
|
||||||
|
if (mtd->line_size == 0)
|
||||||
|
return;
|
||||||
if (mtd->current == 0) {
|
if (mtd->current == 0) {
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
mtd->current = mtd->line_size - 1;
|
mtd->current = mtd->line_size - 1;
|
||||||
@@ -317,6 +319,8 @@ mode_tree_up(struct mode_tree_data *mtd, int wrap)
|
|||||||
int
|
int
|
||||||
mode_tree_down(struct mode_tree_data *mtd, int wrap)
|
mode_tree_down(struct mode_tree_data *mtd, int wrap)
|
||||||
{
|
{
|
||||||
|
if (mtd->line_size == 0)
|
||||||
|
return (0);
|
||||||
if (mtd->current == mtd->line_size - 1) {
|
if (mtd->current == mtd->line_size - 1) {
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
mtd->current = 0;
|
mtd->current = 0;
|
||||||
@@ -363,6 +367,8 @@ mode_tree_swap(struct mode_tree_data *mtd, int direction)
|
|||||||
void *
|
void *
|
||||||
mode_tree_get_current(struct mode_tree_data *mtd)
|
mode_tree_get_current(struct mode_tree_data *mtd)
|
||||||
{
|
{
|
||||||
|
if (mtd->line_size == 0)
|
||||||
|
return (NULL);
|
||||||
return (mtd->line_list[mtd->current].item->itemdata);
|
return (mtd->line_list[mtd->current].item->itemdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,6 +439,8 @@ mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if (mtd->current >= mtd->line_size) {
|
if (mtd->current >= mtd->line_size) {
|
||||||
|
if (mtd->line_size == 0)
|
||||||
|
return (0);
|
||||||
mtd->current = mtd->line_size - 1;
|
mtd->current = mtd->line_size - 1;
|
||||||
if (mtd->current > mtd->height - 1)
|
if (mtd->current > mtd->height - 1)
|
||||||
mtd->offset = mtd->current - mtd->height + 1;
|
mtd->offset = mtd->current - mtd->height + 1;
|
||||||
@@ -1276,6 +1284,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
switch (*key) {
|
switch (*key) {
|
||||||
case 'q':
|
case 'q':
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
|
case '['|KEYC_CTRL:
|
||||||
case 'g'|KEYC_CTRL:
|
case 'g'|KEYC_CTRL:
|
||||||
return (1);
|
return (1);
|
||||||
case KEYC_F1:
|
case KEYC_F1:
|
||||||
|
|||||||
4
names.c
4
names.c
@@ -166,7 +166,9 @@ parse_window_name(const char *in)
|
|||||||
|
|
||||||
if (*name == '/')
|
if (*name == '/')
|
||||||
name = basename(name);
|
name = basename(name);
|
||||||
name = xstrdup(name);
|
name = clean_name(name, "#");
|
||||||
free(copy);
|
free(copy);
|
||||||
|
if (name == NULL)
|
||||||
|
return (xstrdup(""));
|
||||||
return (name);
|
return (name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ static const char *options_table_extended_keys_format_list[] = {
|
|||||||
static const char *options_table_allow_passthrough_list[] = {
|
static const char *options_table_allow_passthrough_list[] = {
|
||||||
"off", "on", "all", NULL
|
"off", "on", "all", NULL
|
||||||
};
|
};
|
||||||
|
static const char *options_table_copy_mode_line_numbers_list[] = {
|
||||||
|
"off", "default", "absolute", "relative", "hybrid", NULL
|
||||||
|
};
|
||||||
|
|
||||||
/* Status line format. */
|
/* Status line format. */
|
||||||
#define OPTIONS_TABLE_STATUS_FORMAT1 \
|
#define OPTIONS_TABLE_STATUS_FORMAT1 \
|
||||||
@@ -1176,7 +1179,7 @@ const struct options_table_entry options_table[] = {
|
|||||||
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||||
.default_str = "#[align=right]"
|
.default_str = "#[align=right]"
|
||||||
"#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}"
|
"#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}"
|
||||||
"[#{scroll_position}/#{history_size}]"
|
"[#{copy_position}/#{copy_position_limit}]"
|
||||||
"#{?search_timed_out, (timed out),"
|
"#{?search_timed_out, (timed out),"
|
||||||
"#{?search_count, (#{search_count}"
|
"#{?search_count, (#{search_count}"
|
||||||
"#{?search_count_partial,+,} results),}}",
|
"#{?search_count_partial,+,} results),}}",
|
||||||
@@ -1201,6 +1204,32 @@ const struct options_table_entry options_table[] = {
|
|||||||
.text = "Style of selection in copy mode."
|
.text = "Style of selection in copy mode."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "copy-mode-current-line-number-style",
|
||||||
|
.type = OPTIONS_TABLE_STRING,
|
||||||
|
.scope = OPTIONS_TABLE_WINDOW,
|
||||||
|
.default_str = "fg=yellow",
|
||||||
|
.flags = OPTIONS_TABLE_IS_STYLE,
|
||||||
|
.separator = ",",
|
||||||
|
.text = "Style of current line number in copy mode."
|
||||||
|
},
|
||||||
|
|
||||||
|
{ .name = "copy-mode-line-number-style",
|
||||||
|
.type = OPTIONS_TABLE_STRING,
|
||||||
|
.scope = OPTIONS_TABLE_WINDOW,
|
||||||
|
.default_str = "fg=white,dim",
|
||||||
|
.flags = OPTIONS_TABLE_IS_STYLE,
|
||||||
|
.separator = ",",
|
||||||
|
.text = "Style of line numbers in copy mode."
|
||||||
|
},
|
||||||
|
|
||||||
|
{ .name = "copy-mode-line-numbers",
|
||||||
|
.type = OPTIONS_TABLE_CHOICE,
|
||||||
|
.scope = OPTIONS_TABLE_WINDOW,
|
||||||
|
.choices = options_table_copy_mode_line_numbers_list,
|
||||||
|
.default_num = 0,
|
||||||
|
.text = "Line number mode in copy mode."
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "fill-character",
|
{ .name = "fill-character",
|
||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.scope = OPTIONS_TABLE_WINDOW,
|
.scope = OPTIONS_TABLE_WINDOW,
|
||||||
@@ -1326,7 +1355,14 @@ const struct options_table_entry options_table[] = {
|
|||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||||
.default_str = "#{?pane_active,#[reverse],}#{pane_index}#[default] "
|
.default_str = "#{?pane_active,#[reverse],}#{pane_index}#[default] "
|
||||||
"\"#{pane_title}\"",
|
"\"#{pane_title}\""
|
||||||
|
"#{?#{mouse},"
|
||||||
|
"#[align=right]"
|
||||||
|
"#[range=control|8]["
|
||||||
|
"#{?#{window_zoomed_flag},u,z}"
|
||||||
|
"]#[norange]"
|
||||||
|
"#[range=control|9][x]#[norange]"
|
||||||
|
",}",
|
||||||
.text = "Format of text in the pane status lines."
|
.text = "Format of text in the pane status lines."
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1473,6 +1509,28 @@ const struct options_table_entry options_table[] = {
|
|||||||
"A value of 0 means no limit."
|
"A value of 0 means no limit."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "tree-mode-preview-format",
|
||||||
|
.type = OPTIONS_TABLE_STRING,
|
||||||
|
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||||
|
.default_str = "#{?pane_format,"
|
||||||
|
"#{pane_index}:#{pane_title},"
|
||||||
|
"#{window_index}:#{window_name}}",
|
||||||
|
.text = "Format of the preview indicator in tree mode."
|
||||||
|
},
|
||||||
|
|
||||||
|
{ .name = "tree-mode-preview-style",
|
||||||
|
.type = OPTIONS_TABLE_STRING,
|
||||||
|
.scope = OPTIONS_TABLE_WINDOW,
|
||||||
|
.default_str = "fg=#{?#{||:"
|
||||||
|
"#{&&:#{pane_format},#{pane_active}},"
|
||||||
|
"#{&&:#{window_format},#{window_active}}},"
|
||||||
|
"#{display-panes-active-colour},"
|
||||||
|
"#{display-panes-colour}}",
|
||||||
|
.flags = OPTIONS_TABLE_IS_STYLE,
|
||||||
|
.separator = ",",
|
||||||
|
.text = "Style of preview indicator in tree mode."
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "window-active-style",
|
{ .name = "window-active-style",
|
||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||||
|
|||||||
33
paste.c
33
paste.c
@@ -204,6 +204,7 @@ int
|
|||||||
paste_rename(const char *oldname, const char *newname, char **cause)
|
paste_rename(const char *oldname, const char *newname, char **cause)
|
||||||
{
|
{
|
||||||
struct paste_buffer *pb, *pb_new;
|
struct paste_buffer *pb, *pb_new;
|
||||||
|
char *name;
|
||||||
|
|
||||||
if (cause != NULL)
|
if (cause != NULL)
|
||||||
*cause = NULL;
|
*cause = NULL;
|
||||||
@@ -219,23 +220,33 @@ paste_rename(const char *oldname, const char *newname, char **cause)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = clean_name(newname, "");
|
||||||
|
if (name == NULL) {
|
||||||
|
if (cause != NULL)
|
||||||
|
xasprintf(cause, "invalid buffer name: %s", newname);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
pb = paste_get_name(oldname);
|
pb = paste_get_name(oldname);
|
||||||
if (pb == NULL) {
|
if (pb == NULL) {
|
||||||
if (cause != NULL)
|
if (cause != NULL)
|
||||||
xasprintf(cause, "no buffer %s", oldname);
|
xasprintf(cause, "no buffer %s", oldname);
|
||||||
|
free(name);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pb_new = paste_get_name(newname);
|
pb_new = paste_get_name(name);
|
||||||
if (pb_new == pb)
|
if (pb_new == pb) {
|
||||||
|
free(name);
|
||||||
return (0);
|
return (0);
|
||||||
|
}
|
||||||
if (pb_new != NULL)
|
if (pb_new != NULL)
|
||||||
paste_free(pb_new);
|
paste_free(pb_new);
|
||||||
|
|
||||||
RB_REMOVE(paste_name_tree, &paste_by_name, pb);
|
RB_REMOVE(paste_name_tree, &paste_by_name, pb);
|
||||||
|
|
||||||
free(pb->name);
|
free(pb->name);
|
||||||
pb->name = xstrdup(newname);
|
pb->name = name;
|
||||||
|
|
||||||
if (pb->automatic)
|
if (pb->automatic)
|
||||||
paste_num_automatic--;
|
paste_num_automatic--;
|
||||||
@@ -244,7 +255,7 @@ paste_rename(const char *oldname, const char *newname, char **cause)
|
|||||||
RB_INSERT(paste_name_tree, &paste_by_name, pb);
|
RB_INSERT(paste_name_tree, &paste_by_name, pb);
|
||||||
|
|
||||||
notify_paste_buffer(oldname, 1);
|
notify_paste_buffer(oldname, 1);
|
||||||
notify_paste_buffer(newname, 0);
|
notify_paste_buffer(pb->name, 0);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -257,6 +268,7 @@ int
|
|||||||
paste_set(char *data, size_t size, const char *name, char **cause)
|
paste_set(char *data, size_t size, const char *name, char **cause)
|
||||||
{
|
{
|
||||||
struct paste_buffer *pb, *old;
|
struct paste_buffer *pb, *old;
|
||||||
|
char *newname;
|
||||||
|
|
||||||
if (cause != NULL)
|
if (cause != NULL)
|
||||||
*cause = NULL;
|
*cause = NULL;
|
||||||
@@ -276,9 +288,16 @@ paste_set(char *data, size_t size, const char *name, char **cause)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newname = clean_name(name, "");
|
||||||
|
if (newname == NULL) {
|
||||||
|
if (cause != NULL)
|
||||||
|
xasprintf(cause, "invalid buffer name: %s", name);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
pb = xmalloc(sizeof *pb);
|
pb = xmalloc(sizeof *pb);
|
||||||
|
|
||||||
pb->name = xstrdup(name);
|
pb->name = newname;
|
||||||
|
|
||||||
pb->data = data;
|
pb->data = data;
|
||||||
pb->size = size;
|
pb->size = size;
|
||||||
@@ -288,13 +307,13 @@ paste_set(char *data, size_t size, const char *name, char **cause)
|
|||||||
|
|
||||||
pb->created = time(NULL);
|
pb->created = time(NULL);
|
||||||
|
|
||||||
if ((old = paste_get_name(name)) != NULL)
|
if ((old = paste_get_name(pb->name)) != NULL)
|
||||||
paste_free(old);
|
paste_free(old);
|
||||||
|
|
||||||
RB_INSERT(paste_name_tree, &paste_by_name, pb);
|
RB_INSERT(paste_name_tree, &paste_by_name, pb);
|
||||||
RB_INSERT(paste_time_tree, &paste_by_time, pb);
|
RB_INSERT(paste_time_tree, &paste_by_time, pb);
|
||||||
|
|
||||||
notify_paste_buffer(name, 0);
|
notify_paste_buffer(pb->name, 0);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ You should see the Greek word 'kosme': "κόσμε"
|
|||||||
2.3.2 U-0000E000 = ee 80 80 = "" |
|
2.3.2 U-0000E000 = ee 80 80 = "" |
|
||||||
2.3.3 U-0000FFFD = ef bf bd = "<22>" |
|
2.3.3 U-0000FFFD = ef bf bd = "<22>" |
|
||||||
2.3.4 U-0010FFFF = f4 8f bf bf = "" |
|
2.3.4 U-0010FFFF = f4 8f bf bf = "" |
|
||||||
2.3.5 U-00110000 = f4 90 80 80 = "<22>" |
|
2.3.5 U-00110000 = f4 90 80 80 = "<22><EFBFBD><EFBFBD><EFBFBD>" |
|
||||||
|
|
|
|
||||||
3 Malformed sequences |
|
3 Malformed sequences |
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -739,7 +739,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
|
|||||||
if (ctx->statustop)
|
if (ctx->statustop)
|
||||||
yoff += ctx->statuslines;
|
yoff += ctx->statuslines;
|
||||||
|
|
||||||
for (i=0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
if (ri->nx == 0)
|
if (ri->nx == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
58
screen.c
58
screen.c
@@ -36,6 +36,8 @@ struct screen_sel {
|
|||||||
u_int ex;
|
u_int ex;
|
||||||
u_int ey;
|
u_int ey;
|
||||||
|
|
||||||
|
u_int clipx;
|
||||||
|
|
||||||
struct grid_cell cell;
|
struct grid_cell cell;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -245,19 +247,28 @@ screen_set_cursor_colour(struct screen *s, int colour)
|
|||||||
int
|
int
|
||||||
screen_set_title(struct screen *s, const char *title)
|
screen_set_title(struct screen *s, const char *title)
|
||||||
{
|
{
|
||||||
if (!utf8_isvalid(title))
|
char *new_title;
|
||||||
|
|
||||||
|
new_title = clean_name(title, "#");
|
||||||
|
if (new_title == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
free(s->title);
|
free(s->title);
|
||||||
s->title = xstrdup(title);
|
s->title = new_title;
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set screen path. */
|
/* Set screen path. */
|
||||||
void
|
int
|
||||||
screen_set_path(struct screen *s, const char *path)
|
screen_set_path(struct screen *s, const char *path)
|
||||||
{
|
{
|
||||||
|
char *new_path;
|
||||||
|
|
||||||
|
new_path = clean_name(path, "#");
|
||||||
|
if (new_path == NULL)
|
||||||
|
return (0);
|
||||||
free(s->path);
|
free(s->path);
|
||||||
utf8_stravis(&s->path, path, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
s->path = new_path;
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Push the current title onto the stack. */
|
/* Push the current title onto the stack. */
|
||||||
@@ -266,6 +277,16 @@ screen_push_title(struct screen *s)
|
|||||||
{
|
{
|
||||||
struct screen_title_entry *title_entry;
|
struct screen_title_entry *title_entry;
|
||||||
|
|
||||||
|
log_debug("%s: %u", __func__, s->ntitles);
|
||||||
|
|
||||||
|
while (s->ntitles >= 10) {
|
||||||
|
title_entry = TAILQ_LAST(s->titles, screen_titles);
|
||||||
|
free(title_entry->text);
|
||||||
|
TAILQ_REMOVE(s->titles, title_entry, entry);
|
||||||
|
free(title_entry);
|
||||||
|
s->ntitles--;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->titles == NULL) {
|
if (s->titles == NULL) {
|
||||||
s->titles = xmalloc(sizeof *s->titles);
|
s->titles = xmalloc(sizeof *s->titles);
|
||||||
TAILQ_INIT(s->titles);
|
TAILQ_INIT(s->titles);
|
||||||
@@ -273,6 +294,7 @@ screen_push_title(struct screen *s)
|
|||||||
title_entry = xmalloc(sizeof *title_entry);
|
title_entry = xmalloc(sizeof *title_entry);
|
||||||
title_entry->text = xstrdup(s->title);
|
title_entry->text = xstrdup(s->title);
|
||||||
TAILQ_INSERT_HEAD(s->titles, title_entry, entry);
|
TAILQ_INSERT_HEAD(s->titles, title_entry, entry);
|
||||||
|
s->ntitles++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -286,14 +308,15 @@ screen_pop_title(struct screen *s)
|
|||||||
|
|
||||||
if (s->titles == NULL)
|
if (s->titles == NULL)
|
||||||
return;
|
return;
|
||||||
|
log_debug("%s: %u", __func__, s->ntitles);
|
||||||
|
|
||||||
title_entry = TAILQ_FIRST(s->titles);
|
title_entry = TAILQ_FIRST(s->titles);
|
||||||
if (title_entry != NULL) {
|
if (title_entry != NULL) {
|
||||||
screen_set_title(s, title_entry->text);
|
free(s->title);
|
||||||
|
s->title = title_entry->text;
|
||||||
TAILQ_REMOVE(s->titles, title_entry, entry);
|
TAILQ_REMOVE(s->titles, title_entry, entry);
|
||||||
free(title_entry->text);
|
|
||||||
free(title_entry);
|
free(title_entry);
|
||||||
|
s->ntitles--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +479,8 @@ screen_resize_y(struct screen *s, u_int sy, int eat_empty, u_int *cy)
|
|||||||
/* Set selection. */
|
/* Set selection. */
|
||||||
void
|
void
|
||||||
screen_set_selection(struct screen *s, u_int sx, u_int sy,
|
screen_set_selection(struct screen *s, u_int sx, u_int sy,
|
||||||
u_int ex, u_int ey, u_int rectangle, int modekeys, struct grid_cell *gc)
|
u_int ex, u_int ey, u_int rectangle, u_int clipx, int modekeys,
|
||||||
|
struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
if (s->sel == NULL)
|
if (s->sel == NULL)
|
||||||
s->sel = xcalloc(1, sizeof *s->sel);
|
s->sel = xcalloc(1, sizeof *s->sel);
|
||||||
@@ -470,6 +494,7 @@ screen_set_selection(struct screen *s, u_int sx, u_int sy,
|
|||||||
s->sel->sy = sy;
|
s->sel->sy = sy;
|
||||||
s->sel->ex = ex;
|
s->sel->ex = ex;
|
||||||
s->sel->ey = ey;
|
s->sel->ey = ey;
|
||||||
|
s->sel->clipx = clipx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear selection. */
|
/* Clear selection. */
|
||||||
@@ -497,6 +522,8 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
|
|||||||
|
|
||||||
if (sel == NULL || sel->hidden)
|
if (sel == NULL || sel->hidden)
|
||||||
return (0);
|
return (0);
|
||||||
|
if (px < sel->clipx)
|
||||||
|
return (0);
|
||||||
|
|
||||||
if (sel->rectangle) {
|
if (sel->rectangle) {
|
||||||
if (sel->sy < sel->ey) {
|
if (sel->sy < sel->ey) {
|
||||||
@@ -649,6 +676,9 @@ void
|
|||||||
screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
|
screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
|
||||||
{
|
{
|
||||||
u_int sx, sy;
|
u_int sx, sy;
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
struct image *im;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SCREEN_IS_ALTERNATE(s))
|
if (SCREEN_IS_ALTERNATE(s))
|
||||||
return;
|
return;
|
||||||
@@ -665,6 +695,8 @@ screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
|
|||||||
|
|
||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
TAILQ_CONCAT(&s->saved_images, &s->images, entry);
|
TAILQ_CONCAT(&s->saved_images, &s->images, entry);
|
||||||
|
TAILQ_FOREACH(im, &s->saved_images, entry)
|
||||||
|
im->list = &s->saved_images;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
grid_view_clear(s->grid, 0, 0, sx, sy, 8);
|
grid_view_clear(s->grid, 0, 0, sx, sy, 8);
|
||||||
@@ -678,6 +710,9 @@ void
|
|||||||
screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
|
screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
|
||||||
{
|
{
|
||||||
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
struct image *im;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the current size is different, temporarily resize to the old size
|
* If the current size is different, temporarily resize to the old size
|
||||||
@@ -724,6 +759,8 @@ screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
|
|||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
image_free_all(s);
|
image_free_all(s);
|
||||||
TAILQ_CONCAT(&s->images, &s->saved_images, entry);
|
TAILQ_CONCAT(&s->images, &s->saved_images, entry);
|
||||||
|
TAILQ_FOREACH(im, &s->images, entry)
|
||||||
|
im->list = &s->images;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s->cx > screen_size_x(s) - 1)
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
@@ -762,6 +799,8 @@ screen_mode_to_string(int mode)
|
|||||||
strlcat(tmp, "CURSOR_BLINKING,", sizeof tmp);
|
strlcat(tmp, "CURSOR_BLINKING,", sizeof tmp);
|
||||||
if (mode & MODE_CURSOR_VERY_VISIBLE)
|
if (mode & MODE_CURSOR_VERY_VISIBLE)
|
||||||
strlcat(tmp, "CURSOR_VERY_VISIBLE,", sizeof tmp);
|
strlcat(tmp, "CURSOR_VERY_VISIBLE,", sizeof tmp);
|
||||||
|
if (mode & MODE_CURSOR_BLINKING_SET)
|
||||||
|
strlcat(tmp, "CURSOR_BLINKING_SET,", sizeof tmp);
|
||||||
if (mode & MODE_MOUSE_UTF8)
|
if (mode & MODE_MOUSE_UTF8)
|
||||||
strlcat(tmp, "MOUSE_UTF8,", sizeof tmp);
|
strlcat(tmp, "MOUSE_UTF8,", sizeof tmp);
|
||||||
if (mode & MODE_MOUSE_SGR)
|
if (mode & MODE_MOUSE_SGR)
|
||||||
@@ -782,6 +821,9 @@ screen_mode_to_string(int mode)
|
|||||||
strlcat(tmp, "KEYS_EXTENDED_2,", sizeof tmp);
|
strlcat(tmp, "KEYS_EXTENDED_2,", sizeof tmp);
|
||||||
if (mode & MODE_THEME_UPDATES)
|
if (mode & MODE_THEME_UPDATES)
|
||||||
strlcat(tmp, "THEME_UPDATES,", sizeof tmp);
|
strlcat(tmp, "THEME_UPDATES,", sizeof tmp);
|
||||||
|
if (mode & MODE_SYNC)
|
||||||
|
strlcat(tmp, "SYNC,", sizeof tmp);
|
||||||
|
if (*tmp != '\0')
|
||||||
tmp[strlen(tmp) - 1] = '\0';
|
tmp[strlen(tmp) - 1] = '\0';
|
||||||
return (tmp);
|
return (tmp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ static void server_client_check_redraw(struct client *);
|
|||||||
static void server_client_check_modes(struct client *);
|
static void server_client_check_modes(struct client *);
|
||||||
static void server_client_set_title(struct client *);
|
static void server_client_set_title(struct client *);
|
||||||
static void server_client_set_path(struct client *);
|
static void server_client_set_path(struct client *);
|
||||||
|
static void server_client_set_progress_bar(struct client *);
|
||||||
static void server_client_reset_state(struct client *);
|
static void server_client_reset_state(struct client *);
|
||||||
static void server_client_update_latest(struct client *);
|
static void server_client_update_latest(struct client *);
|
||||||
static void server_client_dispatch(struct imsg *, void *);
|
static void server_client_dispatch(struct imsg *, void *);
|
||||||
@@ -2142,6 +2143,7 @@ server_client_check_redraw(struct client *c)
|
|||||||
server_client_set_title(c);
|
server_client_set_title(c);
|
||||||
server_client_set_path(c);
|
server_client_set_path(c);
|
||||||
}
|
}
|
||||||
|
server_client_set_progress_bar(c);
|
||||||
screen_redraw_screen(c);
|
screen_redraw_screen(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2208,6 +2210,23 @@ server_client_set_path(struct client *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set client progress bar. */
|
||||||
|
static void
|
||||||
|
server_client_set_progress_bar(struct client *c)
|
||||||
|
{
|
||||||
|
struct session *s = c->session;
|
||||||
|
struct progress_bar *pane_pb;
|
||||||
|
|
||||||
|
if (s->curw == NULL)
|
||||||
|
return;
|
||||||
|
pane_pb = &s->curw->window->active->base.progress_bar;
|
||||||
|
if (pane_pb->state == c->progress_bar.state &&
|
||||||
|
pane_pb->progress == c->progress_bar.progress)
|
||||||
|
return;
|
||||||
|
memcpy(&c->progress_bar, pane_pb, sizeof c->progress_bar);
|
||||||
|
tty_set_progress_bar(&c->tty, &c->progress_bar);
|
||||||
|
}
|
||||||
|
|
||||||
/* Dispatch message from client. */
|
/* Dispatch message from client. */
|
||||||
static void
|
static void
|
||||||
server_client_dispatch(struct imsg *imsg, void *arg)
|
server_client_dispatch(struct imsg *imsg, void *arg)
|
||||||
@@ -2302,13 +2321,16 @@ server_client_dispatch(struct imsg *imsg, void *arg)
|
|||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
case MSG_WRITE_READY:
|
case MSG_WRITE_READY:
|
||||||
file_write_ready(&c->files, imsg);
|
if (file_write_ready(&c->files, imsg) != 0)
|
||||||
|
goto bad;
|
||||||
break;
|
break;
|
||||||
case MSG_READ:
|
case MSG_READ:
|
||||||
file_read_data(&c->files, imsg);
|
if (file_read_data(&c->files, imsg) != 0)
|
||||||
|
goto bad;
|
||||||
break;
|
break;
|
||||||
case MSG_READ_DONE:
|
case MSG_READ_DONE:
|
||||||
file_read_done(&c->files, imsg);
|
if (file_read_done(&c->files, imsg) != 0)
|
||||||
|
goto bad;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
session.c
18
session.c
@@ -229,24 +229,6 @@ session_destroy(struct session *s, int notify, const char *from)
|
|||||||
session_remove_ref(s, __func__);
|
session_remove_ref(s, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanitize session name. */
|
|
||||||
char *
|
|
||||||
session_check_name(const char *name)
|
|
||||||
{
|
|
||||||
char *copy, *cp, *new_name;
|
|
||||||
|
|
||||||
if (*name == '\0')
|
|
||||||
return (NULL);
|
|
||||||
copy = xstrdup(name);
|
|
||||||
for (cp = copy; *cp != '\0'; cp++) {
|
|
||||||
if (*cp == ':' || *cp == '.')
|
|
||||||
*cp = '_';
|
|
||||||
}
|
|
||||||
utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
|
||||||
free(copy);
|
|
||||||
return (new_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lock session if it has timed out. */
|
/* Lock session if it has timed out. */
|
||||||
static void
|
static void
|
||||||
session_lock_timer(__unused int fd, __unused short events, void *arg)
|
session_lock_timer(__unused int fd, __unused short events, void *arg)
|
||||||
|
|||||||
8
spawn.c
8
spawn.c
@@ -82,6 +82,7 @@ spawn_window(struct spawn_context *sc, char **cause)
|
|||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
int idx = sc->idx;
|
int idx = sc->idx;
|
||||||
u_int sx, sy, xpixel, ypixel;
|
u_int sx, sy, xpixel, ypixel;
|
||||||
|
char *name;
|
||||||
|
|
||||||
spawn_log(__func__, sc);
|
spawn_log(__func__, sc);
|
||||||
|
|
||||||
@@ -180,8 +181,11 @@ spawn_window(struct spawn_context *sc, char **cause)
|
|||||||
if (~sc->flags & SPAWN_RESPAWN) {
|
if (~sc->flags & SPAWN_RESPAWN) {
|
||||||
free(w->name);
|
free(w->name);
|
||||||
if (sc->name != NULL) {
|
if (sc->name != NULL) {
|
||||||
w->name = format_single(item, sc->name, c, s, NULL,
|
name = format_single(item, sc->name, c, s, NULL, NULL);
|
||||||
NULL);
|
w->name = clean_name(name, "#");
|
||||||
|
free(name);
|
||||||
|
if (w->name == NULL)
|
||||||
|
w->name = xstrdup("");
|
||||||
options_set_number(w->options, "automatic-rename", 0);
|
options_set_number(w->options, "automatic-rename", 0);
|
||||||
} else
|
} else
|
||||||
w->name = default_window_name(w);
|
w->name = default_window_name(w);
|
||||||
|
|||||||
101
status.c
101
status.c
@@ -689,10 +689,13 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
|||||||
|
|
||||||
server_client_clear_overlay(c);
|
server_client_clear_overlay(c);
|
||||||
|
|
||||||
if (fs != NULL)
|
if (fs != NULL) {
|
||||||
ft = format_create_from_state(NULL, c, fs);
|
ft = format_create_from_state(NULL, c, fs);
|
||||||
else
|
cmd_find_copy_state(&c->prompt_state, fs);
|
||||||
|
} else {
|
||||||
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||||
|
cmd_find_clear_state(&c->prompt_state, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (input == NULL)
|
if (input == NULL)
|
||||||
input = "";
|
input = "";
|
||||||
@@ -701,7 +704,6 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
|||||||
status_prompt_clear(c);
|
status_prompt_clear(c);
|
||||||
status_push_screen(c);
|
status_push_screen(c);
|
||||||
|
|
||||||
c->prompt_formats = ft;
|
|
||||||
c->prompt_string = xstrdup (msg);
|
c->prompt_string = xstrdup (msg);
|
||||||
|
|
||||||
if (flags & PROMPT_NOFORMAT)
|
if (flags & PROMPT_NOFORMAT)
|
||||||
@@ -737,6 +739,7 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
|||||||
|
|
||||||
if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT))
|
if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT))
|
||||||
cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
|
cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
|
||||||
|
format_free(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove status line prompt. */
|
/* Remove status line prompt. */
|
||||||
@@ -752,9 +755,6 @@ status_prompt_clear(struct client *c)
|
|||||||
free(c->prompt_last);
|
free(c->prompt_last);
|
||||||
c->prompt_last = NULL;
|
c->prompt_last = NULL;
|
||||||
|
|
||||||
format_free(c->prompt_formats);
|
|
||||||
c->prompt_formats = NULL;
|
|
||||||
|
|
||||||
free(c->prompt_string);
|
free(c->prompt_string);
|
||||||
c->prompt_string = NULL;
|
c->prompt_string = NULL;
|
||||||
|
|
||||||
@@ -774,13 +774,19 @@ status_prompt_clear(struct client *c)
|
|||||||
void
|
void
|
||||||
status_prompt_update(struct client *c, const char *msg, const char *input)
|
status_prompt_update(struct client *c, const char *msg, const char *input)
|
||||||
{
|
{
|
||||||
|
struct format_tree *ft;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
if (cmd_find_valid_state(&c->prompt_state))
|
||||||
|
ft = format_create_from_state(NULL, c, &c->prompt_state);
|
||||||
|
else
|
||||||
|
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||||
|
|
||||||
free(c->prompt_string);
|
free(c->prompt_string);
|
||||||
c->prompt_string = xstrdup(msg);
|
c->prompt_string = xstrdup(msg);
|
||||||
|
|
||||||
free(c->prompt_buffer);
|
free(c->prompt_buffer);
|
||||||
tmp = format_expand_time(c->prompt_formats, input);
|
tmp = format_expand_time(ft, input);
|
||||||
c->prompt_buffer = utf8_fromcstr(tmp);
|
c->prompt_buffer = utf8_fromcstr(tmp);
|
||||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
@@ -788,6 +794,7 @@ status_prompt_update(struct client *c, const char *msg, const char *input)
|
|||||||
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
|
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
|
||||||
|
|
||||||
c->flags |= CLIENT_REDRAWSTATUS;
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
|
format_free(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */
|
/* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */
|
||||||
@@ -846,11 +853,13 @@ status_prompt_redraw(struct client *c)
|
|||||||
struct status_line *sl = &c->status;
|
struct status_line *sl = &c->status;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
|
struct options *oo = s->options;
|
||||||
struct screen old_screen;
|
struct screen old_screen;
|
||||||
u_int i, lines, offset, left, start, width, n;
|
u_int i, lines, offset, left, start, width, n;
|
||||||
u_int pcursor, pwidth, promptline;
|
u_int pcursor, pwidth, promptline;
|
||||||
u_int ax, aw;
|
u_int ax, aw;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
|
struct format_tree *ft;
|
||||||
const char *msgfmt;
|
const char *msgfmt;
|
||||||
char *expanded, *prompt, *tmp;
|
char *expanded, *prompt, *tmp;
|
||||||
|
|
||||||
@@ -863,12 +872,17 @@ status_prompt_redraw(struct client *c)
|
|||||||
lines = 1;
|
lines = 1;
|
||||||
screen_init(sl->active, c->tty.sx, lines, 0);
|
screen_init(sl->active, c->tty.sx, lines, 0);
|
||||||
|
|
||||||
|
if (cmd_find_valid_state(&c->prompt_state))
|
||||||
|
ft = format_create_from_state(NULL, c, &c->prompt_state);
|
||||||
|
else
|
||||||
|
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
|
||||||
|
|
||||||
n = options_get_number(s->options, "prompt-cursor-colour");
|
n = options_get_number(s->options, "prompt-cursor-colour");
|
||||||
sl->active->default_ccolour = n;
|
sl->active->default_ccolour = n;
|
||||||
if (c->prompt_mode == PROMPT_COMMAND)
|
if (c->prompt_mode == PROMPT_COMMAND)
|
||||||
n = options_get_number(s->options, "prompt-command-cursor-style");
|
n = options_get_number(oo, "prompt-command-cursor-style");
|
||||||
else
|
else
|
||||||
n = options_get_number(s->options, "prompt-cursor-style");
|
n = options_get_number(oo, "prompt-cursor-style");
|
||||||
screen_set_cursor_style(n, &sl->active->default_cstyle,
|
screen_set_cursor_style(n, &sl->active->default_cstyle,
|
||||||
&sl->active->default_mode);
|
&sl->active->default_mode);
|
||||||
|
|
||||||
@@ -877,28 +891,29 @@ status_prompt_redraw(struct client *c)
|
|||||||
promptline = lines - 1;
|
promptline = lines - 1;
|
||||||
|
|
||||||
if (c->prompt_mode == PROMPT_COMMAND)
|
if (c->prompt_mode == PROMPT_COMMAND)
|
||||||
style_apply(&gc, s->options, "message-command-style", NULL);
|
style_apply(&gc, oo, "message-command-style", NULL);
|
||||||
else
|
else
|
||||||
style_apply(&gc, s->options, "message-style", NULL);
|
style_apply(&gc, oo, "message-style", NULL);
|
||||||
|
|
||||||
status_prompt_area(c, &ax, &aw);
|
status_prompt_area(c, &ax, &aw);
|
||||||
|
|
||||||
tmp = utf8_tocstr(c->prompt_buffer);
|
tmp = utf8_tocstr(c->prompt_buffer);
|
||||||
format_add(c->prompt_formats, "prompt-input", "%s", tmp);
|
format_add(ft, "prompt-input", "%s", tmp);
|
||||||
prompt = format_expand_time(c->prompt_formats, c->prompt_string);
|
prompt = format_expand_time(ft, c->prompt_string);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set #{message} to the prompt string and expand message-format.
|
* Set #{message} to the prompt string and expand message-format.
|
||||||
* format_draw handles fill, alignment, and decorations in one call.
|
* format_draw handles fill, alignment, and decorations in one call.
|
||||||
*/
|
*/
|
||||||
format_add(c->prompt_formats, "message", "%s", prompt);
|
format_add(ft, "message", "%s", prompt);
|
||||||
format_add(c->prompt_formats, "command_prompt", "%d",
|
format_add(ft, "command_prompt", "%d",
|
||||||
c->prompt_mode == PROMPT_COMMAND);
|
c->prompt_mode == PROMPT_COMMAND);
|
||||||
msgfmt = options_get_string(s->options, "message-format");
|
msgfmt = options_get_string(oo, "message-format");
|
||||||
expanded = format_expand_time(c->prompt_formats, msgfmt);
|
expanded = format_expand_time(ft, msgfmt);
|
||||||
|
free(prompt);
|
||||||
|
|
||||||
start = format_width(prompt);
|
start = format_width(expanded);
|
||||||
if (start > aw)
|
if (start > aw)
|
||||||
start = aw;
|
start = aw;
|
||||||
|
|
||||||
@@ -972,6 +987,49 @@ status_prompt_space(const struct utf8_data *ud)
|
|||||||
return (*ud->data == ' ');
|
return (*ud->data == ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static key_code
|
||||||
|
status_prompt_keypad_key(key_code key)
|
||||||
|
{
|
||||||
|
if (key & KEYC_MASK_MODIFIERS)
|
||||||
|
return (key);
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case KEYC_KP_SLASH:
|
||||||
|
return ('/');
|
||||||
|
case KEYC_KP_STAR:
|
||||||
|
return ('*');
|
||||||
|
case KEYC_KP_MINUS:
|
||||||
|
return ('-');
|
||||||
|
case KEYC_KP_SEVEN:
|
||||||
|
return ('7');
|
||||||
|
case KEYC_KP_EIGHT:
|
||||||
|
return ('8');
|
||||||
|
case KEYC_KP_NINE:
|
||||||
|
return ('9');
|
||||||
|
case KEYC_KP_PLUS:
|
||||||
|
return ('+');
|
||||||
|
case KEYC_KP_FOUR:
|
||||||
|
return ('4');
|
||||||
|
case KEYC_KP_FIVE:
|
||||||
|
return ('5');
|
||||||
|
case KEYC_KP_SIX:
|
||||||
|
return ('6');
|
||||||
|
case KEYC_KP_ONE:
|
||||||
|
return ('1');
|
||||||
|
case KEYC_KP_TWO:
|
||||||
|
return ('2');
|
||||||
|
case KEYC_KP_THREE:
|
||||||
|
return ('3');
|
||||||
|
case KEYC_KP_ENTER:
|
||||||
|
return ('\r');
|
||||||
|
case KEYC_KP_ZERO:
|
||||||
|
return ('0');
|
||||||
|
case KEYC_KP_PERIOD:
|
||||||
|
return ('.');
|
||||||
|
}
|
||||||
|
return (key);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translate key from vi to emacs. Return 0 to drop key, 1 to process the key
|
* Translate key from vi to emacs. Return 0 to drop key, 1 to process the key
|
||||||
* as an emacs key; return 2 to append to the buffer.
|
* as an emacs key; return 2 to append to the buffer.
|
||||||
@@ -1010,6 +1068,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
*new_key = key;
|
*new_key = key;
|
||||||
return (1);
|
return (1);
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
|
case '['|KEYC_CTRL:
|
||||||
c->prompt_mode = PROMPT_COMMAND;
|
c->prompt_mode = PROMPT_COMMAND;
|
||||||
if (c->prompt_index != 0)
|
if (c->prompt_index != 0)
|
||||||
c->prompt_index--;
|
c->prompt_index--;
|
||||||
@@ -1042,6 +1101,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
c->flags |= CLIENT_REDRAWSTATUS;
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
return (0);
|
return (0);
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
|
case '['|KEYC_CTRL:
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1383,6 +1443,9 @@ status_prompt_key(struct client *c, key_code key)
|
|||||||
}
|
}
|
||||||
size = utf8_strlen(c->prompt_buffer);
|
size = utf8_strlen(c->prompt_buffer);
|
||||||
|
|
||||||
|
key &= ~KEYC_MASK_FLAGS;
|
||||||
|
key = status_prompt_keypad_key(key);
|
||||||
|
|
||||||
if (c->prompt_flags & PROMPT_NUMERIC) {
|
if (c->prompt_flags & PROMPT_NUMERIC) {
|
||||||
if (key >= '0' && key <= '9')
|
if (key >= '0' && key <= '9')
|
||||||
goto append_key;
|
goto append_key;
|
||||||
@@ -1392,7 +1455,6 @@ status_prompt_key(struct client *c, key_code key)
|
|||||||
free(s);
|
free(s);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
key &= ~KEYC_MASK_FLAGS;
|
|
||||||
|
|
||||||
if (c->prompt_flags & (PROMPT_SINGLE|PROMPT_QUOTENEXT)) {
|
if (c->prompt_flags & (PROMPT_SINGLE|PROMPT_QUOTENEXT)) {
|
||||||
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE)
|
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE)
|
||||||
@@ -1607,6 +1669,7 @@ process_key:
|
|||||||
free(s);
|
free(s);
|
||||||
break;
|
break;
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
|
case '['|KEYC_CTRL:
|
||||||
case 'c'|KEYC_CTRL:
|
case 'c'|KEYC_CTRL:
|
||||||
case 'g'|KEYC_CTRL:
|
case 'g'|KEYC_CTRL:
|
||||||
if (c->prompt_inputcb(c, c->prompt_data, NULL, 1) == 0)
|
if (c->prompt_inputcb(c, c->prompt_data, NULL, 1) == 0)
|
||||||
|
|||||||
91
tmux.1
91
tmux.1
@@ -2228,6 +2228,11 @@ Turn off rectangle selection mode.
|
|||||||
.Xc
|
.Xc
|
||||||
Toggle rectangle selection mode.
|
Toggle rectangle selection mode.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic recentre\-top\-bottom
|
||||||
|
(emacs : C-l)
|
||||||
|
.Xc
|
||||||
|
Cycles the current line between centre, top, and bottom.
|
||||||
|
.It Xo
|
||||||
.Ic refresh\-from\-pane
|
.Ic refresh\-from\-pane
|
||||||
(vi: r)
|
(vi: r)
|
||||||
(emacs: r)
|
(emacs: r)
|
||||||
@@ -4664,6 +4669,8 @@ mouse sequences.
|
|||||||
Supports the OSC 7 working directory extension.
|
Supports the OSC 7 working directory extension.
|
||||||
.It overline
|
.It overline
|
||||||
Supports the overline SGR attribute.
|
Supports the overline SGR attribute.
|
||||||
|
.It progressbar
|
||||||
|
Supports the OSC 9;4 progress bar extension.
|
||||||
.It rectfill
|
.It rectfill
|
||||||
Supports the DECFRA rectangle fill escape sequence.
|
Supports the DECFRA rectangle fill escape sequence.
|
||||||
.It RGB
|
.It RGB
|
||||||
@@ -5357,17 +5364,6 @@ section.
|
|||||||
.It Ic copy\-mode\-position\-format Ar format
|
.It Ic copy\-mode\-position\-format Ar format
|
||||||
Format of the position indicator in copy mode.
|
Format of the position indicator in copy mode.
|
||||||
.Pp
|
.Pp
|
||||||
.It Xo Ic mode\-keys
|
|
||||||
.Op Ic vi | emacs
|
|
||||||
.Xc
|
|
||||||
Use vi or emacs-style key bindings in copy mode.
|
|
||||||
The default is emacs, unless
|
|
||||||
.Ev VISUAL
|
|
||||||
or
|
|
||||||
.Ev EDITOR
|
|
||||||
contains
|
|
||||||
.Ql vi .
|
|
||||||
.Pp
|
|
||||||
.It Ic copy\-mode\-position\-style Ar style
|
.It Ic copy\-mode\-position\-style Ar style
|
||||||
Set the style of the position indicator in copy mode.
|
Set the style of the position indicator in copy mode.
|
||||||
For how to specify
|
For how to specify
|
||||||
@@ -5384,6 +5380,63 @@ see the
|
|||||||
.Sx STYLES
|
.Sx STYLES
|
||||||
section.
|
section.
|
||||||
.Pp
|
.Pp
|
||||||
|
.It Ic copy\-mode\-current\-line\-number\-style Ar style
|
||||||
|
Set style of current line number in copy mode.
|
||||||
|
For how to specify
|
||||||
|
.Ar style ,
|
||||||
|
see the
|
||||||
|
.Sx STYLES
|
||||||
|
section.
|
||||||
|
.Pp
|
||||||
|
.It Ic copy\-mode\-line\-number\-style Ar style
|
||||||
|
Set style of line numbers in copy mode.
|
||||||
|
For how to specify
|
||||||
|
.Ar style ,
|
||||||
|
see the
|
||||||
|
.Sx STYLES
|
||||||
|
section.
|
||||||
|
.Pp
|
||||||
|
.It Xo Ic copy\-mode\-line\-numbers
|
||||||
|
.Op Ic off | default | absolute | relative | hybrid
|
||||||
|
.Xc
|
||||||
|
Show line numbers in copy mode.
|
||||||
|
.Ic off
|
||||||
|
hides line numbers,
|
||||||
|
.Ic default
|
||||||
|
shows line numbers matching the copy mode position indicator and
|
||||||
|
.Ic goto\-line ,
|
||||||
|
.Ic absolute
|
||||||
|
shows absolute line numbers,
|
||||||
|
.Ic relative
|
||||||
|
shows line numbers relative to the cursor, and
|
||||||
|
.Ic hybrid
|
||||||
|
shows the current line number as absolute and other line numbers as
|
||||||
|
relative.
|
||||||
|
With
|
||||||
|
.Ic off
|
||||||
|
or
|
||||||
|
.Ic default ,
|
||||||
|
the position indicator and
|
||||||
|
.Ic goto\-line
|
||||||
|
use the same numbering;
|
||||||
|
with
|
||||||
|
.Ic absolute ,
|
||||||
|
.Ic relative
|
||||||
|
and
|
||||||
|
.Ic hybrid ,
|
||||||
|
they use absolute line numbers.
|
||||||
|
.Pp
|
||||||
|
.It Xo Ic mode\-keys
|
||||||
|
.Op Ic vi | emacs
|
||||||
|
.Xc
|
||||||
|
Use vi or emacs-style key bindings in copy mode.
|
||||||
|
The default is emacs, unless
|
||||||
|
.Ev VISUAL
|
||||||
|
or
|
||||||
|
.Ev EDITOR
|
||||||
|
contains
|
||||||
|
.Ql vi .
|
||||||
|
.Pp
|
||||||
.It Ic mode\-style Ar style
|
.It Ic mode\-style Ar style
|
||||||
Set window modes style.
|
Set window modes style.
|
||||||
For how to specify
|
For how to specify
|
||||||
@@ -5628,6 +5681,17 @@ A value of 0 (the default) means no limit.
|
|||||||
When a limit is set, panes are arranged to not exceed this number of columns,
|
When a limit is set, panes are arranged to not exceed this number of columns,
|
||||||
with additional panes stacked in extra rows.
|
with additional panes stacked in extra rows.
|
||||||
.Pp
|
.Pp
|
||||||
|
.It Ic tree\-mode\-preview\-format Ar format
|
||||||
|
Format of the preview indicator in tree mode.
|
||||||
|
.Pp
|
||||||
|
.It Ic tree\-mode\-preview\-style Ar style
|
||||||
|
Set the style of the preview indicator in tree mode.
|
||||||
|
For how to specify
|
||||||
|
.Ar style ,
|
||||||
|
see the
|
||||||
|
.Sx STYLES
|
||||||
|
section.
|
||||||
|
.Pp
|
||||||
.It Ic window\-status\-activity\-style Ar style
|
.It Ic window\-status\-activity\-style Ar style
|
||||||
Set status line style for windows with an activity alert.
|
Set status line style for windows with an activity alert.
|
||||||
For how to specify
|
For how to specify
|
||||||
@@ -6533,6 +6597,8 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
||||||
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
||||||
.It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
|
.It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
|
||||||
|
.It Li "copy_position" Ta "" Ta "Position shown in the copy mode indicator"
|
||||||
|
.It Li "copy_position_limit" Ta "" Ta "Limit shown in the copy mode indicator"
|
||||||
.It Li "current_file" Ta "" Ta "Current configuration file"
|
.It Li "current_file" Ta "" Ta "Current configuration file"
|
||||||
.It Li "cursor_character" Ta "" Ta "Character at cursor in pane"
|
.It Li "cursor_character" Ta "" Ta "Character at cursor in pane"
|
||||||
.It Li "cursor_colour" Ta "" Ta "Cursor colour in pane"
|
.It Li "cursor_colour" Ta "" Ta "Cursor colour in pane"
|
||||||
@@ -7493,7 +7559,6 @@ Display a popup running
|
|||||||
when omitted) on
|
when omitted) on
|
||||||
.Ar target\-client .
|
.Ar target\-client .
|
||||||
A popup is a rectangular box drawn over the top of any panes.
|
A popup is a rectangular box drawn over the top of any panes.
|
||||||
Panes are not updated while a popup is present.
|
|
||||||
If the command is run inside an existing popup, that popup is modified.
|
If the command is run inside an existing popup, that popup is modified.
|
||||||
Only the
|
Only the
|
||||||
.Fl b ,
|
.Fl b ,
|
||||||
@@ -8081,6 +8146,8 @@ $ printf \[aq]\e033[4 q\[aq]
|
|||||||
If
|
If
|
||||||
.Em Se
|
.Em Se
|
||||||
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
|
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
|
||||||
|
.It Em \&Spb
|
||||||
|
Set the state and progress for the OSC9;4 progress bar.
|
||||||
.It Em \&Swd
|
.It Em \&Swd
|
||||||
Set the opening sequence for the working directory notification.
|
Set the opening sequence for the working directory notification.
|
||||||
The sequence is terminated using the standard
|
The sequence is terminated using the standard
|
||||||
|
|||||||
17
tmux.c
17
tmux.c
@@ -281,6 +281,23 @@ get_timer(void)
|
|||||||
return ((ts.tv_sec * 1000ULL) + (ts.tv_nsec / 1000000ULL));
|
return ((ts.tv_sec * 1000ULL) + (ts.tv_nsec / 1000000ULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
clean_name(const char *name, const char* forbid)
|
||||||
|
{
|
||||||
|
char *copy, *cp, *new_name;
|
||||||
|
|
||||||
|
if (*name == '\0' || !utf8_isvalid(name))
|
||||||
|
return (NULL);
|
||||||
|
copy = xstrdup(name);
|
||||||
|
for (cp = copy; *cp != '\0'; cp++) {
|
||||||
|
if (strchr(forbid, *cp) != NULL)
|
||||||
|
*cp = '_';
|
||||||
|
}
|
||||||
|
utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
||||||
|
free(copy);
|
||||||
|
return (new_name);
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
sig2name(int signo)
|
sig2name(int signo)
|
||||||
{
|
{
|
||||||
|
|||||||
23
tmux.h
23
tmux.h
@@ -638,6 +638,7 @@ enum tty_code_code {
|
|||||||
TTYC_SMUL,
|
TTYC_SMUL,
|
||||||
TTYC_SMULX,
|
TTYC_SMULX,
|
||||||
TTYC_SMXX,
|
TTYC_SMXX,
|
||||||
|
TTYC_SPB,
|
||||||
TTYC_SXL,
|
TTYC_SXL,
|
||||||
TTYC_SS,
|
TTYC_SS,
|
||||||
TTYC_SWD,
|
TTYC_SWD,
|
||||||
@@ -970,8 +971,10 @@ struct image {
|
|||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
TAILQ_ENTRY (image) all_entry;
|
struct images *list;
|
||||||
TAILQ_ENTRY (image) entry;
|
TAILQ_ENTRY (image) entry;
|
||||||
|
|
||||||
|
TAILQ_ENTRY (image) all_entry;
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(images, image);
|
TAILQ_HEAD(images, image);
|
||||||
#endif
|
#endif
|
||||||
@@ -1005,6 +1008,7 @@ struct screen {
|
|||||||
char *title;
|
char *title;
|
||||||
char *path;
|
char *path;
|
||||||
struct screen_titles *titles;
|
struct screen_titles *titles;
|
||||||
|
u_int ntitles;
|
||||||
|
|
||||||
struct grid *grid; /* grid data */
|
struct grid *grid; /* grid data */
|
||||||
|
|
||||||
@@ -2035,6 +2039,7 @@ struct client {
|
|||||||
char *title;
|
char *title;
|
||||||
char *path;
|
char *path;
|
||||||
const char *cwd;
|
const char *cwd;
|
||||||
|
struct progress_bar progress_bar;
|
||||||
|
|
||||||
char *term_name;
|
char *term_name;
|
||||||
int term_features;
|
int term_features;
|
||||||
@@ -2144,8 +2149,8 @@ struct client {
|
|||||||
struct event message_timer;
|
struct event message_timer;
|
||||||
|
|
||||||
char *prompt_string;
|
char *prompt_string;
|
||||||
struct format_tree *prompt_formats;
|
|
||||||
struct utf8_data *prompt_buffer;
|
struct utf8_data *prompt_buffer;
|
||||||
|
struct cmd_find_state prompt_state;
|
||||||
char *prompt_last;
|
char *prompt_last;
|
||||||
size_t prompt_index;
|
size_t prompt_index;
|
||||||
prompt_input_cb prompt_inputcb;
|
prompt_input_cb prompt_inputcb;
|
||||||
@@ -2380,6 +2385,7 @@ int checkshell(const char *);
|
|||||||
void setblocking(int, int);
|
void setblocking(int, int);
|
||||||
char *shell_argv0(const char *, int);
|
char *shell_argv0(const char *, int);
|
||||||
uint64_t get_timer(void);
|
uint64_t get_timer(void);
|
||||||
|
char *clean_name(const char *, const char *);
|
||||||
const char *sig2name(int);
|
const char *sig2name(int);
|
||||||
const char *find_cwd(void);
|
const char *find_cwd(void);
|
||||||
const char *find_home(void);
|
const char *find_home(void);
|
||||||
@@ -2674,6 +2680,7 @@ void tty_repeat_requests(struct tty *, int);
|
|||||||
void tty_stop_tty(struct tty *);
|
void tty_stop_tty(struct tty *);
|
||||||
void tty_set_title(struct tty *, const char *);
|
void tty_set_title(struct tty *, const char *);
|
||||||
void tty_set_path(struct tty *, const char *);
|
void tty_set_path(struct tty *, const char *);
|
||||||
|
void tty_set_progress_bar(struct tty *, struct progress_bar *);
|
||||||
void tty_default_attributes(struct tty *, const struct grid_cell *,
|
void tty_default_attributes(struct tty *, const struct grid_cell *,
|
||||||
struct colour_palette *, u_int, struct hyperlinks *);
|
struct colour_palette *, u_int, struct hyperlinks *);
|
||||||
void tty_update_mode(struct tty *, int, struct screen *);
|
void tty_update_mode(struct tty *, int, struct screen *);
|
||||||
@@ -3009,9 +3016,9 @@ void file_write_data(struct client_files *, struct imsg *);
|
|||||||
void file_write_close(struct client_files *, struct imsg *);
|
void file_write_close(struct client_files *, struct imsg *);
|
||||||
void file_read_open(struct client_files *, struct tmuxpeer *, struct imsg *,
|
void file_read_open(struct client_files *, struct tmuxpeer *, struct imsg *,
|
||||||
int, int, client_file_cb, void *);
|
int, int, client_file_cb, void *);
|
||||||
void file_write_ready(struct client_files *, struct imsg *);
|
int file_write_ready(struct client_files *, struct imsg *);
|
||||||
void file_read_data(struct client_files *, struct imsg *);
|
int file_read_data(struct client_files *, struct imsg *);
|
||||||
void file_read_done(struct client_files *, struct imsg *);
|
int file_read_done(struct client_files *, struct imsg *);
|
||||||
void file_read_cancel(struct client_files *, struct imsg *);
|
void file_read_cancel(struct client_files *, struct imsg *);
|
||||||
|
|
||||||
/* server.c */
|
/* server.c */
|
||||||
@@ -3353,14 +3360,14 @@ void screen_set_default_cursor(struct screen *, struct options *);
|
|||||||
void screen_set_cursor_style(u_int, enum screen_cursor_style *, int *);
|
void screen_set_cursor_style(u_int, enum screen_cursor_style *, int *);
|
||||||
void screen_set_cursor_colour(struct screen *, int);
|
void screen_set_cursor_colour(struct screen *, int);
|
||||||
int screen_set_title(struct screen *, const char *);
|
int screen_set_title(struct screen *, const char *);
|
||||||
void screen_set_path(struct screen *, const char *);
|
int screen_set_path(struct screen *, const char *);
|
||||||
void screen_push_title(struct screen *);
|
void screen_push_title(struct screen *);
|
||||||
void screen_pop_title(struct screen *);
|
void screen_pop_title(struct screen *);
|
||||||
void screen_set_progress_bar(struct screen *, enum progress_bar_state, int);
|
void screen_set_progress_bar(struct screen *, enum progress_bar_state, int);
|
||||||
void screen_resize(struct screen *, u_int, u_int, int);
|
void screen_resize(struct screen *, u_int, u_int, int);
|
||||||
void screen_resize_cursor(struct screen *, u_int, u_int, int, int, int);
|
void screen_resize_cursor(struct screen *, u_int, u_int, int, int, int);
|
||||||
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
|
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
|
||||||
u_int, int, struct grid_cell *);
|
u_int, u_int, int, struct grid_cell *);
|
||||||
void screen_clear_selection(struct screen *);
|
void screen_clear_selection(struct screen *);
|
||||||
void screen_hide_selection(struct screen *);
|
void screen_hide_selection(struct screen *);
|
||||||
int screen_check_selection(struct screen *, u_int, u_int);
|
int screen_check_selection(struct screen *, u_int, u_int);
|
||||||
@@ -3605,6 +3612,7 @@ char *window_copy_get_line(struct window_pane *, u_int);
|
|||||||
int window_copy_get_current_offset(struct window_pane *, u_int *,
|
int window_copy_get_current_offset(struct window_pane *, u_int *,
|
||||||
u_int *);
|
u_int *);
|
||||||
char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
|
char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
|
||||||
|
void window_copy_set_line_numbers(struct window_pane *, int);
|
||||||
|
|
||||||
/* window-option.c */
|
/* window-option.c */
|
||||||
extern const struct window_mode window_customize_mode;
|
extern const struct window_mode window_customize_mode;
|
||||||
@@ -3666,7 +3674,6 @@ struct session *session_create(const char *, const char *, const char *,
|
|||||||
void session_destroy(struct session *, int, const char *);
|
void session_destroy(struct session *, int, const char *);
|
||||||
void session_add_ref(struct session *, const char *);
|
void session_add_ref(struct session *, const char *);
|
||||||
void session_remove_ref(struct session *, const char *);
|
void session_remove_ref(struct session *, const char *);
|
||||||
char *session_check_name(const char *);
|
|
||||||
void session_update_activity(struct session *, struct timeval *);
|
void session_update_activity(struct session *, struct timeval *);
|
||||||
struct session *session_next_session(struct session *, struct sort_criteria *);
|
struct session *session_next_session(struct session *, struct sort_criteria *);
|
||||||
struct session *session_previous_session(struct session *,
|
struct session *session_previous_session(struct session *,
|
||||||
|
|||||||
@@ -357,6 +357,17 @@ static const struct tty_feature tty_feature_sixel = {
|
|||||||
TERM_SIXEL
|
TERM_SIXEL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Terminal supports the OSC 9;4 progress bar. */
|
||||||
|
static const char *const tty_feature_progressbar_capabilities[] = {
|
||||||
|
"Spb=\\E]9;4;%p1%d;%p2%d\\E\\\\",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
static const struct tty_feature tty_feature_progressbar = {
|
||||||
|
"progressbar",
|
||||||
|
tty_feature_progressbar_capabilities,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
/* Available terminal features. */
|
/* Available terminal features. */
|
||||||
static const struct tty_feature *const tty_features[] = {
|
static const struct tty_feature *const tty_features[] = {
|
||||||
&tty_feature_256,
|
&tty_feature_256,
|
||||||
@@ -372,6 +383,7 @@ static const struct tty_feature *const tty_features[] = {
|
|||||||
&tty_feature_mouse,
|
&tty_feature_mouse,
|
||||||
&tty_feature_osc7,
|
&tty_feature_osc7,
|
||||||
&tty_feature_overline,
|
&tty_feature_overline,
|
||||||
|
&tty_feature_progressbar,
|
||||||
&tty_feature_rectfill,
|
&tty_feature_rectfill,
|
||||||
&tty_feature_rgb,
|
&tty_feature_rgb,
|
||||||
&tty_feature_sixel,
|
&tty_feature_sixel,
|
||||||
@@ -490,7 +502,8 @@ tty_default_features(int *feat, const char *name, u_int version)
|
|||||||
"focus,"
|
"focus,"
|
||||||
"overline,"
|
"overline,"
|
||||||
"usstyle,"
|
"usstyle,"
|
||||||
"hyperlinks"
|
"hyperlinks,"
|
||||||
|
"progressbar"
|
||||||
},
|
},
|
||||||
{ .name = "rxvt-unicode",
|
{ .name = "rxvt-unicode",
|
||||||
.features = "256,"
|
.features = "256,"
|
||||||
@@ -508,13 +521,23 @@ tty_default_features(int *feat, const char *name, u_int version)
|
|||||||
"margins,"
|
"margins,"
|
||||||
"usstyle,"
|
"usstyle,"
|
||||||
"sync,"
|
"sync,"
|
||||||
"osc7,hyperlinks"
|
"osc7,"
|
||||||
|
"hyperlinks,"
|
||||||
|
"progressbar"
|
||||||
},
|
},
|
||||||
{ .name = "foot",
|
{ .name = "foot",
|
||||||
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||||
"cstyle,"
|
"cstyle,"
|
||||||
"extkeys"
|
"extkeys"
|
||||||
},
|
},
|
||||||
|
{ .name = "WezTerm",
|
||||||
|
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||||
|
"ccolour,"
|
||||||
|
"cstyle,"
|
||||||
|
"extkeys,"
|
||||||
|
"focus,"
|
||||||
|
"usstyle"
|
||||||
|
},
|
||||||
{ .name = "XTerm",
|
{ .name = "XTerm",
|
||||||
/*
|
/*
|
||||||
* xterm also supports DECSLRM and DECFRA, but they can be
|
* xterm also supports DECSLRM and DECFRA, but they can be
|
||||||
|
|||||||
@@ -1640,6 +1640,8 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
|
|||||||
tty_default_features(features, "mintty", 0);
|
tty_default_features(features, "mintty", 0);
|
||||||
else if (strncmp(tmp, "foot(", 5) == 0)
|
else if (strncmp(tmp, "foot(", 5) == 0)
|
||||||
tty_default_features(features, "foot", 0);
|
tty_default_features(features, "foot", 0);
|
||||||
|
else if (strncmp(tmp, "WezTerm ", 7) == 0)
|
||||||
|
tty_default_features(features, "WezTerm", 0);
|
||||||
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
|
log_debug("%s: received extended DA %.*s", c->name, (int)*size, buf);
|
||||||
|
|
||||||
free(c->term_type);
|
free(c->term_type);
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
|||||||
[TTYC_SMULX] = { TTYCODE_STRING, "Smulx" },
|
[TTYC_SMULX] = { TTYCODE_STRING, "Smulx" },
|
||||||
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
|
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
|
||||||
[TTYC_SMXX] = { TTYCODE_STRING, "smxx" },
|
[TTYC_SMXX] = { TTYCODE_STRING, "smxx" },
|
||||||
|
[TTYC_SPB] = { TTYCODE_STRING, "Spb" },
|
||||||
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
|
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
|
||||||
[TTYC_SWD] = { TTYCODE_STRING, "Swd" },
|
[TTYC_SWD] = { TTYCODE_STRING, "Swd" },
|
||||||
[TTYC_SYNC] = { TTYCODE_STRING, "Sync" },
|
[TTYC_SYNC] = { TTYCODE_STRING, "Sync" },
|
||||||
|
|||||||
7
tty.c
7
tty.c
@@ -3315,3 +3315,10 @@ tty_clipboard_query(struct tty *tty)
|
|||||||
evtimer_add(&tty->clipboard_timer, &tv);
|
evtimer_add(&tty->clipboard_timer, &tv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_set_progress_bar(struct tty *tty, struct progress_bar *pb)
|
||||||
|
{
|
||||||
|
if (tty_term_has(tty->term, TTYC_SPB))
|
||||||
|
tty_putcode_ii(tty, TTYC_SPB, pb->state, pb->progress);
|
||||||
|
}
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ window_clock_draw_screen(struct window_mode_entry *wme)
|
|||||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
gc.flags |= GRID_FLAG_NOPALETTE;
|
gc.flags |= GRID_FLAG_NOPALETTE;
|
||||||
gc.bg = colour;
|
gc.bg = colour;
|
||||||
|
gc.fg = colour;
|
||||||
for (ptr = tim; *ptr != '\0'; ptr++) {
|
for (ptr = tim; *ptr != '\0'; ptr++) {
|
||||||
if (*ptr >= '0' && *ptr <= '9')
|
if (*ptr >= '0' && *ptr <= '9')
|
||||||
idx = *ptr - '0';
|
idx = *ptr - '0';
|
||||||
@@ -299,7 +300,7 @@ window_clock_draw_screen(struct window_mode_entry *wme)
|
|||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
screen_write_cursormove(&ctx, x + i, y + j, 0);
|
screen_write_cursormove(&ctx, x + i, y + j, 0);
|
||||||
if (window_clock_table[idx][j][i])
|
if (window_clock_table[idx][j][i])
|
||||||
screen_write_putc(&ctx, &gc, ' ');
|
screen_write_putc(&ctx, &gc, '#');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x += 6;
|
x += 6;
|
||||||
|
|||||||
420
window-copy.c
420
window-copy.c
@@ -52,6 +52,12 @@ static void window_copy_redraw_lines(struct window_mode_entry *, u_int,
|
|||||||
u_int);
|
u_int);
|
||||||
static void window_copy_redraw_screen(struct window_mode_entry *);
|
static void window_copy_redraw_screen(struct window_mode_entry *);
|
||||||
static void window_copy_style_changed(struct window_mode_entry *);
|
static void window_copy_style_changed(struct window_mode_entry *);
|
||||||
|
static int window_copy_line_number_mode(struct window_mode_entry *);
|
||||||
|
static int window_copy_line_number_is_absolute(struct window_mode_entry *);
|
||||||
|
static int window_copy_line_numbers_active(struct window_mode_entry *);
|
||||||
|
static u_int window_copy_line_number_width(struct window_mode_entry *);
|
||||||
|
static u_int window_copy_cursor_offset(struct window_mode_entry *, u_int, u_int);
|
||||||
|
static u_int window_copy_cursor_unoffset(struct window_mode_entry *, u_int, u_int);
|
||||||
static void window_copy_write_line(struct window_mode_entry *,
|
static void window_copy_write_line(struct window_mode_entry *,
|
||||||
struct screen_write_ctx *, u_int);
|
struct screen_write_ctx *, u_int);
|
||||||
static void window_copy_write_lines(struct window_mode_entry *,
|
static void window_copy_write_lines(struct window_mode_entry *,
|
||||||
@@ -207,6 +213,14 @@ enum window_copy_cmd_clear {
|
|||||||
WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum window_copy_line_numbers {
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_OFF,
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_DEFAULT,
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE,
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_RELATIVE,
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_HYBRID,
|
||||||
|
};
|
||||||
|
|
||||||
struct window_copy_cmd_state {
|
struct window_copy_cmd_state {
|
||||||
struct window_mode_entry *wme;
|
struct window_mode_entry *wme;
|
||||||
struct args *args;
|
struct args *args;
|
||||||
@@ -264,6 +278,7 @@ struct window_copy_mode_data {
|
|||||||
int rectflag; /* in rectangle copy mode? */
|
int rectflag; /* in rectangle copy mode? */
|
||||||
int scroll_exit; /* exit on scroll to end? */
|
int scroll_exit; /* exit on scroll to end? */
|
||||||
int hide_position; /* hide position marker */
|
int hide_position; /* hide position marker */
|
||||||
|
int line_numbers;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SEL_CHAR, /* select one char at a time */
|
SEL_CHAR, /* select one char at a time */
|
||||||
@@ -271,6 +286,13 @@ struct window_copy_mode_data {
|
|||||||
SEL_LINE, /* select one line at a time */
|
SEL_LINE, /* select one line at a time */
|
||||||
} selflag;
|
} selflag;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RECENTRE_TOP,
|
||||||
|
RECENTRE_MIDDLE,
|
||||||
|
RECENTRE_BOTTOM,
|
||||||
|
} recentre_state;
|
||||||
|
u_int recentre_line;
|
||||||
|
|
||||||
const char *separators; /* word separators */
|
const char *separators; /* word separators */
|
||||||
|
|
||||||
u_int dx; /* drag start position */
|
u_int dx; /* drag start position */
|
||||||
@@ -427,6 +449,7 @@ window_copy_common_init(struct window_mode_entry *wme)
|
|||||||
|
|
||||||
data->jumptype = WINDOW_COPY_OFF;
|
data->jumptype = WINDOW_COPY_OFF;
|
||||||
data->jumpchar = NULL;
|
data->jumpchar = NULL;
|
||||||
|
data->line_numbers = 1;
|
||||||
|
|
||||||
screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0);
|
screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0);
|
||||||
screen_set_default_cursor(&data->screen, global_w_options);
|
screen_set_default_cursor(&data->screen, global_w_options);
|
||||||
@@ -463,9 +486,12 @@ window_copy_init(struct window_mode_entry *wme,
|
|||||||
data->scroll_exit = args_has(args, 'e');
|
data->scroll_exit = args_has(args, 'e');
|
||||||
data->hide_position = args_has(args, 'H');
|
data->hide_position = args_has(args, 'H');
|
||||||
|
|
||||||
if (base->hyperlinks != NULL)
|
if (base->hyperlinks != NULL) {
|
||||||
|
hyperlinks_free(data->screen.hyperlinks);
|
||||||
data->screen.hyperlinks = hyperlinks_copy(base->hyperlinks);
|
data->screen.hyperlinks = hyperlinks_copy(base->hyperlinks);
|
||||||
data->screen.cx = data->cx;
|
}
|
||||||
|
data->screen.cx = window_copy_cursor_offset(wme, data->cx,
|
||||||
|
screen_size_x(&data->screen));
|
||||||
data->screen.cy = data->cy;
|
data->screen.cy = data->cy;
|
||||||
data->mx = data->cx;
|
data->mx = data->cx;
|
||||||
data->my = screen_hsize(data->backing) + data->cy - data->oy;
|
data->my = screen_hsize(data->backing) + data->cy - data->oy;
|
||||||
@@ -474,9 +500,13 @@ window_copy_init(struct window_mode_entry *wme,
|
|||||||
screen_write_start(&ctx, &data->screen);
|
screen_write_start(&ctx, &data->screen);
|
||||||
for (i = 0; i < screen_size_y(&data->screen); i++)
|
for (i = 0; i < screen_size_y(&data->screen); i++)
|
||||||
window_copy_write_line(wme, &ctx, i);
|
window_copy_write_line(wme, &ctx, i);
|
||||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
screen_write_cursormove(&ctx, window_copy_cursor_offset(wme, data->cx,
|
||||||
|
screen_size_x(&data->screen)), data->cy, 0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
|
||||||
|
data->recentre_state = RECENTRE_MIDDLE;
|
||||||
|
data->recentre_line = 0;
|
||||||
|
|
||||||
return (&data->screen);
|
return (&data->screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,6 +521,7 @@ window_copy_view_init(struct window_mode_entry *wme,
|
|||||||
|
|
||||||
data = window_copy_common_init(wme);
|
data = window_copy_common_init(wme);
|
||||||
data->viewmode = 1;
|
data->viewmode = 1;
|
||||||
|
data->line_numbers = 0;
|
||||||
|
|
||||||
data->backing = xmalloc(sizeof *data->backing);
|
data->backing = xmalloc(sizeof *data->backing);
|
||||||
screen_init(data->backing, sx, screen_size_y(base), UINT_MAX);
|
screen_init(data->backing, sx, screen_size_y(base), UINT_MAX);
|
||||||
@@ -937,12 +968,22 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
|
|||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
u_int hsize = screen_hsize(data->backing);
|
u_int hsize = screen_hsize(data->backing);
|
||||||
|
u_int position, limit;
|
||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
|
|
||||||
gl = grid_get_line(data->backing->grid, hsize - data->oy);
|
gl = grid_get_line(data->backing->grid, hsize - data->oy);
|
||||||
format_add(ft, "top_line_time", "%llu", (unsigned long long)gl->time);
|
format_add(ft, "top_line_time", "%llu", (unsigned long long)gl->time);
|
||||||
|
|
||||||
format_add(ft, "scroll_position", "%d", data->oy);
|
format_add(ft, "scroll_position", "%d", data->oy);
|
||||||
|
if (window_copy_line_number_is_absolute(wme)) {
|
||||||
|
position = hsize - data->oy + 1;
|
||||||
|
limit = hsize + screen_size_y(data->backing);
|
||||||
|
} else {
|
||||||
|
position = data->oy;
|
||||||
|
limit = hsize;
|
||||||
|
}
|
||||||
|
format_add(ft, "copy_position", "%u", position);
|
||||||
|
format_add(ft, "copy_position_limit", "%u", limit);
|
||||||
format_add(ft, "rectangle_toggle", "%d", data->rectflag);
|
format_add(ft, "rectangle_toggle", "%d", data->rectflag);
|
||||||
|
|
||||||
format_add(ft, "copy_cursor_x", "%d", data->cx);
|
format_add(ft, "copy_cursor_x", "%d", data->cx);
|
||||||
@@ -2769,6 +2810,62 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
|
|||||||
return (WINDOW_COPY_CMD_REDRAW);
|
return (WINDOW_COPY_CMD_REDRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum window_copy_cmd_action
|
||||||
|
window_copy_cmd_recentre_top_bottom(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_mode_entry *wme = cs->wme;
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
u_int cy = data->cy, oy = data->oy;
|
||||||
|
u_int sy = screen_size_y(&data->screen) - 1;
|
||||||
|
u_int sm = sy / 2, backing_row;
|
||||||
|
enum { MIDDLE, TOP, BOTTOM } target;
|
||||||
|
|
||||||
|
backing_row = screen_hsize(data->backing) + cy - data->oy;
|
||||||
|
if (data->recentre_line != backing_row) {
|
||||||
|
data->recentre_state = RECENTRE_MIDDLE;
|
||||||
|
data->recentre_line = backing_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (data->recentre_state) {
|
||||||
|
case RECENTRE_MIDDLE:
|
||||||
|
data->recentre_state = RECENTRE_TOP;
|
||||||
|
target = MIDDLE;
|
||||||
|
break;
|
||||||
|
case RECENTRE_TOP:
|
||||||
|
data->recentre_state = RECENTRE_BOTTOM;
|
||||||
|
target = TOP;
|
||||||
|
break;
|
||||||
|
case RECENTRE_BOTTOM:
|
||||||
|
default:
|
||||||
|
data->recentre_state = RECENTRE_MIDDLE;
|
||||||
|
target = BOTTOM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
oy = data->oy;
|
||||||
|
switch (target) {
|
||||||
|
case MIDDLE:
|
||||||
|
if (cy < sm)
|
||||||
|
window_copy_scroll_down(wme, sm - cy);
|
||||||
|
else if (cy > sm)
|
||||||
|
window_copy_scroll_up(wme, cy - sm);
|
||||||
|
if (data->oy != oy)
|
||||||
|
data->cy = cy + (data->oy - oy);
|
||||||
|
break;
|
||||||
|
case TOP:
|
||||||
|
window_copy_scroll_up(wme, cy);
|
||||||
|
data->cy = cy - (oy - data->oy);
|
||||||
|
break;
|
||||||
|
case BOTTOM:
|
||||||
|
window_copy_scroll_down(wme, sy - cy);
|
||||||
|
data->cy = cy + (data->oy - oy);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
window_copy_update_selection(wme, 0, 0);
|
||||||
|
|
||||||
|
return (WINDOW_COPY_CMD_REDRAW);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *command;
|
const char *command;
|
||||||
u_int minargs;
|
u_int minargs;
|
||||||
@@ -3153,6 +3250,12 @@ static const struct {
|
|||||||
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
.clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||||
.f = window_copy_cmd_previous_word
|
.f = window_copy_cmd_previous_word
|
||||||
},
|
},
|
||||||
|
{ .command = "recentre-top-bottom",
|
||||||
|
.args = { "", 0, 0, NULL },
|
||||||
|
.flags = WINDOW_COPY_CMD_FLAG_READONLY,
|
||||||
|
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
|
||||||
|
.f = window_copy_cmd_recentre_top_bottom
|
||||||
|
},
|
||||||
{ .command = "rectangle-on",
|
{ .command = "rectangle-on",
|
||||||
.args = { "", 0, 0, NULL },
|
.args = { "", 0, 0, NULL },
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
@@ -4471,15 +4574,28 @@ window_copy_goto_line(struct window_mode_entry *wme, const char *linestr)
|
|||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
u_int hsize = screen_hsize(data->backing);
|
||||||
|
u_int line;
|
||||||
int lineno;
|
int lineno;
|
||||||
|
|
||||||
lineno = strtonum(linestr, -1, INT_MAX, &errstr);
|
lineno = strtonum(linestr, -1, INT_MAX, &errstr);
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
return;
|
return;
|
||||||
if (lineno < 0 || (u_int)lineno > screen_hsize(data->backing))
|
|
||||||
lineno = screen_hsize(data->backing);
|
|
||||||
|
|
||||||
|
if (window_copy_line_number_is_absolute(wme)) {
|
||||||
|
if (lineno <= 0)
|
||||||
|
line = 1;
|
||||||
|
else if ((u_int)lineno > hsize + 1)
|
||||||
|
line = hsize + 1;
|
||||||
|
else
|
||||||
|
line = lineno;
|
||||||
|
data->oy = hsize - (line - 1);
|
||||||
|
} else {
|
||||||
|
if (lineno < 0 || (u_int)lineno > hsize)
|
||||||
|
lineno = hsize;
|
||||||
data->oy = lineno;
|
data->oy = lineno;
|
||||||
|
}
|
||||||
|
|
||||||
window_copy_update_selection(wme, 1, 0);
|
window_copy_update_selection(wme, 1, 0);
|
||||||
window_copy_redraw_screen(wme);
|
window_copy_redraw_screen(wme);
|
||||||
}
|
}
|
||||||
@@ -4628,7 +4744,7 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
window_copy_write_one(struct window_mode_entry *wme,
|
window_copy_write_one(struct window_mode_entry *wme,
|
||||||
struct screen_write_ctx *ctx, u_int py, u_int fy, u_int nx,
|
struct screen_write_ctx *ctx, u_int px, u_int py, u_int fy, u_int nx,
|
||||||
const struct grid_cell *mgc, const struct grid_cell *cgc,
|
const struct grid_cell *mgc, const struct grid_cell *cgc,
|
||||||
const struct grid_cell *mkgc)
|
const struct grid_cell *mkgc)
|
||||||
{
|
{
|
||||||
@@ -4637,7 +4753,7 @@ window_copy_write_one(struct window_mode_entry *wme,
|
|||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
u_int fx;
|
u_int fx;
|
||||||
|
|
||||||
screen_write_cursormove(ctx, 0, py, 0);
|
screen_write_cursormove(ctx, px, py, 0);
|
||||||
for (fx = 0; fx < nx; fx++) {
|
for (fx = 0; fx < nx; fx++) {
|
||||||
grid_get_cell(gd, fx, fy, &gc);
|
grid_get_cell(gd, fx, fy, &gc);
|
||||||
if (fx + gc.data.width <= nx) {
|
if (fx + gc.data.width <= nx) {
|
||||||
@@ -4648,6 +4764,116 @@ window_copy_write_one(struct window_mode_entry *wme,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
window_copy_line_number_mode(struct window_mode_entry *wme)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = wme->wp;
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
struct options *oo = wp->window->options;
|
||||||
|
|
||||||
|
if (!data->line_numbers)
|
||||||
|
return (WINDOW_COPY_LINE_NUMBERS_OFF);
|
||||||
|
return (options_get_number(oo, "copy-mode-line-numbers"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
window_copy_line_number_is_absolute(struct window_mode_entry *wme)
|
||||||
|
{
|
||||||
|
switch (window_copy_line_number_mode(wme)) {
|
||||||
|
case WINDOW_COPY_LINE_NUMBERS_ABSOLUTE:
|
||||||
|
case WINDOW_COPY_LINE_NUMBERS_RELATIVE:
|
||||||
|
case WINDOW_COPY_LINE_NUMBERS_HYBRID:
|
||||||
|
return (1);
|
||||||
|
case WINDOW_COPY_LINE_NUMBERS_OFF:
|
||||||
|
case WINDOW_COPY_LINE_NUMBERS_DEFAULT:
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
fatalx("bad line number mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
window_copy_line_numbers_active(struct window_mode_entry *wme)
|
||||||
|
{
|
||||||
|
return (window_copy_line_number_mode(wme) !=
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
window_copy_line_number_width(struct window_mode_entry *wme)
|
||||||
|
{
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
u_int lines, digits;
|
||||||
|
|
||||||
|
if (!window_copy_line_numbers_active(wme))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
lines = screen_hsize(data->backing) + screen_size_y(data->backing) + 1;
|
||||||
|
digits = 1;
|
||||||
|
while (lines >= 10) {
|
||||||
|
lines /= 10;
|
||||||
|
digits++;
|
||||||
|
}
|
||||||
|
if (digits < 3)
|
||||||
|
digits = 3;
|
||||||
|
return (digits + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
window_copy_cursor_offset(struct window_mode_entry *wme, u_int cx, u_int sx)
|
||||||
|
{
|
||||||
|
u_int width = window_copy_line_number_width(wme);
|
||||||
|
u_int content;
|
||||||
|
|
||||||
|
if (width == 0)
|
||||||
|
return (cx);
|
||||||
|
if (width >= sx)
|
||||||
|
content = 1;
|
||||||
|
else
|
||||||
|
content = sx - width;
|
||||||
|
if (cx >= content)
|
||||||
|
return (sx - 1);
|
||||||
|
return (width + cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_int
|
||||||
|
window_copy_cursor_unoffset(struct window_mode_entry *wme, u_int vx, u_int sx)
|
||||||
|
{
|
||||||
|
u_int width = window_copy_line_number_width(wme);
|
||||||
|
u_int content;
|
||||||
|
|
||||||
|
if (width == 0)
|
||||||
|
return (vx);
|
||||||
|
if (width >= sx)
|
||||||
|
content = 1;
|
||||||
|
else
|
||||||
|
content = sx - width;
|
||||||
|
if (vx < width)
|
||||||
|
return (0);
|
||||||
|
vx -= width;
|
||||||
|
if (vx >= content)
|
||||||
|
return (content - 1);
|
||||||
|
return (vx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_copy_set_line_numbers(struct window_pane *wp, int enabled)
|
||||||
|
{
|
||||||
|
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
|
||||||
|
struct window_copy_mode_data *data;
|
||||||
|
|
||||||
|
if (wme == NULL)
|
||||||
|
return;
|
||||||
|
if (wme->mode != &window_copy_mode)
|
||||||
|
return;
|
||||||
|
data = wme->data;
|
||||||
|
if (data == NULL)
|
||||||
|
return;
|
||||||
|
if (data->line_numbers == enabled)
|
||||||
|
return;
|
||||||
|
data->line_numbers = enabled;
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
window_copy_get_current_offset(struct window_pane *wp, u_int *offset,
|
window_copy_get_current_offset(struct window_pane *wp, u_int *offset,
|
||||||
u_int *size)
|
u_int *size)
|
||||||
@@ -4673,12 +4899,23 @@ window_copy_write_line(struct window_mode_entry *wme,
|
|||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
struct options *oo = wp->window->options;
|
struct options *oo = wp->window->options;
|
||||||
struct grid_cell gc, mgc, cgc, mkgc;
|
struct grid_cell gc, mgc, cgc, mkgc, ln_gc, cur_ln_gc;
|
||||||
u_int sx = screen_size_x(s);
|
u_int sx = screen_size_x(s);
|
||||||
u_int hsize = screen_hsize(data->backing);
|
u_int hsize = screen_hsize(data->backing);
|
||||||
|
u_int width;
|
||||||
|
u_int absolute, line_number, content_sx;
|
||||||
const char *value;
|
const char *value;
|
||||||
char *expanded;
|
char *expanded;
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
|
int current, mode;
|
||||||
|
|
||||||
|
width = window_copy_line_number_width(wme);
|
||||||
|
if (width >= sx)
|
||||||
|
content_sx = 1;
|
||||||
|
else if (width != 0)
|
||||||
|
content_sx = sx - width;
|
||||||
|
else
|
||||||
|
content_sx = sx;
|
||||||
|
|
||||||
ft = format_create_defaults(NULL, NULL, NULL, NULL, wp);
|
ft = format_create_defaults(NULL, NULL, NULL, NULL, wp);
|
||||||
|
|
||||||
@@ -4690,24 +4927,52 @@ window_copy_write_line(struct window_mode_entry *wme,
|
|||||||
cgc.flags |= GRID_FLAG_NOPALETTE;
|
cgc.flags |= GRID_FLAG_NOPALETTE;
|
||||||
style_apply(&mkgc, oo, "copy-mode-mark-style", ft);
|
style_apply(&mkgc, oo, "copy-mode-mark-style", ft);
|
||||||
mkgc.flags |= GRID_FLAG_NOPALETTE;
|
mkgc.flags |= GRID_FLAG_NOPALETTE;
|
||||||
|
if (width != 0) {
|
||||||
|
style_apply(&ln_gc, oo, "copy-mode-line-number-style", ft);
|
||||||
|
ln_gc.flags |= GRID_FLAG_NOPALETTE;
|
||||||
|
style_apply(&cur_ln_gc, oo,
|
||||||
|
"copy-mode-current-line-number-style", ft);
|
||||||
|
cur_ln_gc.flags |= GRID_FLAG_NOPALETTE;
|
||||||
|
current = (py == data->cy);
|
||||||
|
absolute = hsize - data->oy + py + 1;
|
||||||
|
mode = window_copy_line_number_mode(wme);
|
||||||
|
if (mode == WINDOW_COPY_LINE_NUMBERS_DEFAULT) {
|
||||||
|
if (py < data->oy)
|
||||||
|
line_number = data->oy - py;
|
||||||
|
else
|
||||||
|
line_number = py - data->oy;
|
||||||
|
} else if (mode == WINDOW_COPY_LINE_NUMBERS_ABSOLUTE)
|
||||||
|
line_number = absolute;
|
||||||
|
else if (mode == WINDOW_COPY_LINE_NUMBERS_HYBRID && current)
|
||||||
|
line_number = absolute;
|
||||||
|
else if (py > data->cy)
|
||||||
|
line_number = py - data->cy;
|
||||||
|
else
|
||||||
|
line_number = data->cy - py;
|
||||||
|
screen_write_cursormove(ctx, 0, py, 0);
|
||||||
|
screen_write_nputs(ctx, width, current ? &cur_ln_gc : &ln_gc,
|
||||||
|
"%*u ", (int)width - 1, line_number);
|
||||||
|
}
|
||||||
|
|
||||||
window_copy_write_one(wme, ctx, py, hsize - data->oy + py,
|
window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py,
|
||||||
screen_size_x(s), &mgc, &cgc, &mkgc);
|
content_sx, &mgc, &cgc, &mkgc);
|
||||||
|
|
||||||
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
|
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
|
||||||
value = options_get_string(oo, "copy-mode-position-format");
|
value = options_get_string(oo, "copy-mode-position-format");
|
||||||
if (*value != '\0') {
|
if (*value != '\0') {
|
||||||
expanded = format_expand(ft, value);
|
expanded = format_expand(ft, value);
|
||||||
if (*expanded != '\0') {
|
if (*expanded != '\0') {
|
||||||
screen_write_cursormove(ctx, 0, 0, 0);
|
screen_write_cursormove(ctx, width, 0, 0);
|
||||||
format_draw(ctx, &gc, sx, expanded, NULL, 0);
|
format_draw(ctx, &gc, content_sx, expanded,
|
||||||
|
NULL, 0);
|
||||||
}
|
}
|
||||||
free(expanded);
|
free(expanded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (py == data->cy && data->cx == screen_size_x(s)) {
|
if (py == data->cy && data->cx >= content_sx) {
|
||||||
screen_write_cursormove(ctx, screen_size_x(s) - 1, py, 0);
|
screen_write_cursormove(ctx, window_copy_cursor_offset(wme,
|
||||||
|
data->cx, screen_size_x(s)), py, 0);
|
||||||
screen_write_putc(ctx, &grid_default_cell, '$');
|
screen_write_putc(ctx, &grid_default_cell, '$');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4757,13 +5022,28 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
|||||||
{
|
{
|
||||||
struct window_pane *wp = wme->wp;
|
struct window_pane *wp = wme->wp;
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
struct screen *s = &data->screen;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
|
if (window_copy_line_number_width(wme) != 0) {
|
||||||
|
screen_write_start(&ctx, &data->screen);
|
||||||
|
for (i = py; i < py + ny; i++)
|
||||||
|
window_copy_write_line(wme, &ctx, i);
|
||||||
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||||
|
data->cy, 0);
|
||||||
|
screen_write_stop(&ctx);
|
||||||
|
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
for (i = py; i < py + ny; i++)
|
for (i = py; i < py + ny; i++)
|
||||||
window_copy_write_line(wme, &ctx, i);
|
window_copy_write_line(wme, &ctx, i);
|
||||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)), data->cy,
|
||||||
|
0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||||
@@ -4882,17 +5162,42 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy)
|
|||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
u_int old_cx, old_cy;
|
u_int old_cx, old_cy, width, content_sx;
|
||||||
|
|
||||||
old_cx = data->cx; old_cy = data->cy;
|
old_cx = data->cx; old_cy = data->cy;
|
||||||
data->cx = cx; data->cy = cy;
|
data->cx = cx; data->cy = cy;
|
||||||
|
if (window_copy_line_numbers_active(wme)) {
|
||||||
|
width = window_copy_line_number_width(wme);
|
||||||
|
|
||||||
|
if (s->sel != NULL || data->lineflag != LINE_SEL_NONE ||
|
||||||
|
old_cy != data->cy) {
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (width >= screen_size_x(s))
|
||||||
|
content_sx = 1;
|
||||||
|
else
|
||||||
|
content_sx = screen_size_x(s) - width;
|
||||||
|
if (old_cx >= content_sx || data->cx >= content_sx) {
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||||
|
data->cy, 0);
|
||||||
|
screen_write_stop(&ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (old_cx == screen_size_x(s))
|
if (old_cx == screen_size_x(s))
|
||||||
window_copy_redraw_lines(wme, old_cy, 1);
|
window_copy_redraw_lines(wme, old_cy, 1);
|
||||||
if (data->cx == screen_size_x(s))
|
if (data->cx == screen_size_x(s))
|
||||||
window_copy_redraw_lines(wme, data->cy, 1);
|
window_copy_redraw_lines(wme, data->cy, 1);
|
||||||
else {
|
else {
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||||
|
data->cy, 0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4967,7 +5272,7 @@ window_copy_set_selection(struct window_mode_entry *wme, int may_redraw,
|
|||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
struct options *oo = wp->window->options;
|
struct options *oo = wp->window->options;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
u_int sx, sy, cy, endsx, endsy;
|
u_int sx, sy, cy, endsx, endsy, clipx;
|
||||||
int startrelpos, endrelpos;
|
int startrelpos, endrelpos;
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
|
|
||||||
@@ -4995,8 +5300,15 @@ window_copy_set_selection(struct window_mode_entry *wme, int may_redraw,
|
|||||||
style_apply(&gc, oo, "copy-mode-selection-style", ft);
|
style_apply(&gc, oo, "copy-mode-selection-style", ft);
|
||||||
gc.flags |= GRID_FLAG_NOPALETTE;
|
gc.flags |= GRID_FLAG_NOPALETTE;
|
||||||
format_free(ft);
|
format_free(ft);
|
||||||
|
clipx = window_copy_line_number_width(wme);
|
||||||
|
if (clipx >= screen_size_x(s))
|
||||||
|
clipx = screen_size_x(s) - 1;
|
||||||
|
if (window_copy_line_numbers_active(wme)) {
|
||||||
|
sx = window_copy_cursor_offset(wme, sx, screen_size_x(s));
|
||||||
|
endsx = window_copy_cursor_offset(wme, endsx, screen_size_x(s));
|
||||||
|
}
|
||||||
screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag,
|
screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag,
|
||||||
data->modekeys, &gc);
|
clipx, data->modekeys, &gc);
|
||||||
|
|
||||||
if (data->rectflag && may_redraw) {
|
if (data->rectflag && may_redraw) {
|
||||||
/*
|
/*
|
||||||
@@ -5152,12 +5464,20 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix,
|
|||||||
{
|
{
|
||||||
struct window_pane *wp = wme->wp;
|
struct window_pane *wp = wme->wp;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
|
int redraw = 0;
|
||||||
|
|
||||||
if (set_clip &&
|
if (set_clip &&
|
||||||
options_get_number(global_options, "set-clipboard") != 0) {
|
options_get_number(global_options, "set-clipboard") != 0) {
|
||||||
|
if (window_copy_line_numbers_active(wme) &&
|
||||||
|
(wp->flags & PANE_REDRAW)) {
|
||||||
|
/* Clear PANE_REDRAW so clipboard write not skipped. */
|
||||||
|
redraw = PANE_REDRAW;
|
||||||
|
wp->flags &= ~PANE_REDRAW;
|
||||||
|
}
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_setselection(&ctx, "", buf, len);
|
screen_write_setselection(&ctx, "", buf, len);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
|
wp->flags |= redraw;
|
||||||
notify_pane("pane-set-clipboard", wp);
|
notify_pane("pane-set-clipboard", wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5180,6 +5500,7 @@ window_copy_pipe_run(struct window_mode_entry *wme, struct session *s,
|
|||||||
if (cmd != NULL && *cmd != '\0') {
|
if (cmd != NULL && *cmd != '\0') {
|
||||||
job = job_run(cmd, 0, NULL, NULL, s, NULL, NULL, NULL, NULL,
|
job = job_run(cmd, 0, NULL, NULL, s, NULL, NULL, NULL, NULL,
|
||||||
NULL, JOB_NOWAIT, -1, -1);
|
NULL, JOB_NOWAIT, -1, -1);
|
||||||
|
if (job != NULL)
|
||||||
bufferevent_write(job_get_event(job), buf, *len);
|
bufferevent_write(job_get_event(job), buf, *len);
|
||||||
}
|
}
|
||||||
return (buf);
|
return (buf);
|
||||||
@@ -5930,6 +6251,32 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
|||||||
if (data->searchmark != NULL && !data->timeout)
|
if (data->searchmark != NULL && !data->timeout)
|
||||||
window_copy_search_marks(wme, NULL, data->searchregex, 1);
|
window_copy_search_marks(wme, NULL, data->searchregex, 1);
|
||||||
window_copy_update_selection(wme, 0, 0);
|
window_copy_update_selection(wme, 0, 0);
|
||||||
|
if (window_copy_line_numbers_active(wme)) {
|
||||||
|
if (window_copy_line_number_mode(wme) !=
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
screen_write_start(&ctx, &data->screen);
|
||||||
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
|
screen_write_deleteline(&ctx, ny, 8);
|
||||||
|
window_copy_write_lines(wme, &ctx, screen_size_y(s) - ny, ny);
|
||||||
|
window_copy_write_line(wme, &ctx, 0);
|
||||||
|
if (screen_size_y(s) > 1)
|
||||||
|
window_copy_write_line(wme, &ctx, 1);
|
||||||
|
if (screen_size_y(s) > 3)
|
||||||
|
window_copy_write_line(wme, &ctx, screen_size_y(s) - 2);
|
||||||
|
if (s->sel != NULL && screen_size_y(s) > ny) {
|
||||||
|
window_copy_write_line(wme, &ctx,
|
||||||
|
screen_size_y(s) - ny - 1);
|
||||||
|
}
|
||||||
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||||
|
data->cy, 0);
|
||||||
|
screen_write_stop(&ctx);
|
||||||
|
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
@@ -5942,7 +6289,9 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
|||||||
window_copy_write_line(wme, &ctx, screen_size_y(s) - 2);
|
window_copy_write_line(wme, &ctx, screen_size_y(s) - 2);
|
||||||
if (s->sel != NULL && screen_size_y(s) > ny)
|
if (s->sel != NULL && screen_size_y(s) > ny)
|
||||||
window_copy_write_line(wme, &ctx, screen_size_y(s) - ny - 1);
|
window_copy_write_line(wme, &ctx, screen_size_y(s) - ny - 1);
|
||||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)), data->cy,
|
||||||
|
0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||||
}
|
}
|
||||||
@@ -5967,6 +6316,27 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
|||||||
if (data->searchmark != NULL && !data->timeout)
|
if (data->searchmark != NULL && !data->timeout)
|
||||||
window_copy_search_marks(wme, NULL, data->searchregex, 1);
|
window_copy_search_marks(wme, NULL, data->searchregex, 1);
|
||||||
window_copy_update_selection(wme, 0, 0);
|
window_copy_update_selection(wme, 0, 0);
|
||||||
|
if (window_copy_line_numbers_active(wme)) {
|
||||||
|
if (window_copy_line_number_mode(wme) !=
|
||||||
|
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
screen_write_start(&ctx, &data->screen);
|
||||||
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
|
screen_write_insertline(&ctx, ny, 8);
|
||||||
|
window_copy_write_lines(wme, &ctx, 0, ny);
|
||||||
|
if (s->sel != NULL && screen_size_y(s) > ny)
|
||||||
|
window_copy_write_line(wme, &ctx, ny);
|
||||||
|
else if (ny == 1)
|
||||||
|
window_copy_write_line(wme, &ctx, 1);
|
||||||
|
screen_write_cursormove(&ctx,
|
||||||
|
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||||
|
data->cy, 0);
|
||||||
|
screen_write_stop(&ctx);
|
||||||
|
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
screen_write_start_pane(&ctx, wp, NULL);
|
screen_write_start_pane(&ctx, wp, NULL);
|
||||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||||
@@ -5976,7 +6346,8 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
|||||||
window_copy_write_line(wme, &ctx, ny);
|
window_copy_write_line(wme, &ctx, ny);
|
||||||
else if (ny == 1) /* nuke position */
|
else if (ny == 1) /* nuke position */
|
||||||
window_copy_write_line(wme, &ctx, 1);
|
window_copy_write_line(wme, &ctx, 1);
|
||||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
screen_write_cursormove(&ctx, window_copy_cursor_offset(wme, data->cx,
|
||||||
|
screen_size_x(s)), data->cy, 0);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||||
}
|
}
|
||||||
@@ -6004,6 +6375,7 @@ window_copy_move_mouse(struct mouse_event *m)
|
|||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct window_mode_entry *wme;
|
struct window_mode_entry *wme;
|
||||||
u_int x, y;
|
u_int x, y;
|
||||||
|
struct window_copy_mode_data *data;
|
||||||
|
|
||||||
wp = cmd_mouse_pane(m, NULL, NULL);
|
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
@@ -6017,6 +6389,8 @@ window_copy_move_mouse(struct mouse_event *m)
|
|||||||
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
data = wme->data;
|
||||||
|
x = window_copy_cursor_unoffset(wme, x, screen_size_x(&data->screen));
|
||||||
window_copy_update_cursor(wme, x, y);
|
window_copy_update_cursor(wme, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6047,6 +6421,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
|
|||||||
c->tty.mouse_drag_release = window_copy_drag_release;
|
c->tty.mouse_drag_release = window_copy_drag_release;
|
||||||
|
|
||||||
data = wme->data;
|
data = wme->data;
|
||||||
|
x = window_copy_cursor_unoffset(wme, x, screen_size_x(&data->screen));
|
||||||
yg = screen_hsize(data->backing) + y - data->oy;
|
yg = screen_hsize(data->backing) + y - data->oy;
|
||||||
if (x < data->selrx || x > data->endselrx || yg != data->selry)
|
if (x < data->selrx || x > data->endselrx || yg != data->selry)
|
||||||
data->selflag = SEL_CHAR;
|
data->selflag = SEL_CHAR;
|
||||||
@@ -6104,6 +6479,7 @@ window_copy_drag_update(struct client *c, struct mouse_event *m)
|
|||||||
|
|
||||||
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
return;
|
return;
|
||||||
|
x = window_copy_cursor_unoffset(wme, x, screen_size_x(&data->screen));
|
||||||
old_cx = data->cx;
|
old_cx = data->cx;
|
||||||
old_cy = data->cy;
|
old_cy = data->cy;
|
||||||
|
|
||||||
@@ -6141,6 +6517,8 @@ window_copy_drag_release(struct client *c, struct mouse_event *m)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
data = wme->data;
|
data = wme->data;
|
||||||
|
if (window_copy_line_numbers_active(wme))
|
||||||
|
window_copy_drag_update(c, m);
|
||||||
evtimer_del(&data->dragtimer);
|
evtimer_del(&data->dragtimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
112
window-tree.c
112
window-tree.c
@@ -411,44 +411,49 @@ static void
|
|||||||
window_tree_draw_label(struct screen_write_ctx *ctx, u_int px, u_int py,
|
window_tree_draw_label(struct screen_write_ctx *ctx, u_int px, u_int py,
|
||||||
u_int sx, u_int sy, const struct grid_cell *gc, const char *label)
|
u_int sx, u_int sy, const struct grid_cell *gc, const char *label)
|
||||||
{
|
{
|
||||||
size_t len;
|
u_int width, ox, oy;
|
||||||
u_int ox, oy;
|
char *new_label = NULL;
|
||||||
|
|
||||||
len = strlen(label);
|
if (sx < 5 || sy < 3)
|
||||||
if (sx == 0 || sy == 1 || len > sx)
|
|
||||||
return;
|
return;
|
||||||
ox = (sx - len + 1) / 2;
|
width = format_width(label);
|
||||||
|
if (width > sx - 4) {
|
||||||
|
label = new_label = format_trim_left(label, sx - 4);
|
||||||
|
width = format_width(new_label);
|
||||||
|
}
|
||||||
|
if (width == 0)
|
||||||
|
return;
|
||||||
|
ox = (sx - width + 1) / 2;
|
||||||
oy = (sy + 1) / 2;
|
oy = (sy + 1) / 2;
|
||||||
|
|
||||||
if (ox > 1 && ox + len < sx - 1 && sy >= 3) {
|
screen_write_cursormove(ctx, px + ox - 2, py + oy - 1, 0);
|
||||||
screen_write_cursormove(ctx, px + ox - 1, py + oy - 1, 0);
|
screen_write_box(ctx, width + 4, 3, BOX_LINES_DEFAULT,
|
||||||
screen_write_box(ctx, len + 2, 3, BOX_LINES_DEFAULT, NULL,
|
NULL, NULL);
|
||||||
NULL);
|
screen_write_cursormove(ctx, px + ox - 1, py + oy, 0);
|
||||||
}
|
screen_write_clearcharacter(ctx, width + 2, 8);
|
||||||
screen_write_cursormove(ctx, px + ox, py + oy, 0);
|
screen_write_cursormove(ctx, px + ox, py + oy, 0);
|
||||||
screen_write_puts(ctx, gc, "%s", label);
|
format_draw(ctx, gc, width, label, NULL, 0);
|
||||||
|
free(new_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
|
window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
|
||||||
struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
||||||
{
|
{
|
||||||
struct options *oo = s->options;
|
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
u_int cx = ctx->s->cx, cy = ctx->s->cy;
|
u_int cx = ctx->s->cx, cy = ctx->s->cy;
|
||||||
u_int loop, total, visible, each, width, offset;
|
u_int loop, total, visible, each, width, offset;
|
||||||
u_int current, start, end, remaining, i;
|
u_int current, start, end, remaining, i;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
int colour, active_colour, left, right;
|
int left, right;
|
||||||
char *label;
|
char *label;
|
||||||
|
const char *format;
|
||||||
|
struct format_tree *ft;
|
||||||
|
struct options *oo;
|
||||||
|
|
||||||
total = winlink_count(&s->windows);
|
total = winlink_count(&s->windows);
|
||||||
|
|
||||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
|
||||||
colour = options_get_number(oo, "display-panes-colour");
|
|
||||||
active_colour = options_get_number(oo, "display-panes-active-colour");
|
|
||||||
|
|
||||||
if (sx / total < 24) {
|
if (sx / total < 24) {
|
||||||
visible = sx / 24;
|
visible = sx / 24;
|
||||||
if (visible == 0)
|
if (visible == 0)
|
||||||
@@ -528,11 +533,13 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
w = wl->window;
|
w = wl->window;
|
||||||
|
oo = w->options;
|
||||||
|
|
||||||
if (wl == s->curw)
|
ft = format_create(NULL, NULL, FORMAT_WINDOW|w->id, 0);
|
||||||
gc.fg = active_colour;
|
format_defaults(ft, NULL, s, wl, NULL);
|
||||||
else
|
|
||||||
gc.fg = colour;
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
|
style_apply(&gc, oo, "tree-mode-preview-style", ft);
|
||||||
|
|
||||||
if (left)
|
if (left)
|
||||||
offset = 3 + (i * each);
|
offset = 3 + (i * each);
|
||||||
@@ -546,17 +553,19 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
|
|||||||
screen_write_cursormove(ctx, cx + offset, cy, 0);
|
screen_write_cursormove(ctx, cx + offset, cy, 0);
|
||||||
screen_write_preview(ctx, &w->active->base, width, sy);
|
screen_write_preview(ctx, &w->active->base, width, sy);
|
||||||
|
|
||||||
xasprintf(&label, " %u:%s ", wl->idx, w->name);
|
format = options_get_string(oo, "tree-mode-preview-format");
|
||||||
if (strlen(label) > width) {
|
if (*format != '\0') {
|
||||||
free(label);
|
label = format_expand(ft, format);
|
||||||
xasprintf(&label, " %u ", wl->idx);
|
if (*label != '\0') {
|
||||||
|
window_tree_draw_label(ctx, cx + offset, cy,
|
||||||
|
width, sy, &gc, label);
|
||||||
}
|
}
|
||||||
window_tree_draw_label(ctx, cx + offset, cy, width, sy, &gc,
|
|
||||||
label);
|
|
||||||
free(label);
|
free(label);
|
||||||
|
}
|
||||||
|
|
||||||
if (loop != end - 1) {
|
if (loop != end - 1) {
|
||||||
screen_write_cursormove(ctx, cx + offset + width, cy, 0);
|
screen_write_cursormove(ctx, cx + offset + width, cy,
|
||||||
|
0);
|
||||||
screen_write_vline(ctx, sy, 0, 0);
|
screen_write_vline(ctx, sy, 0, 0);
|
||||||
}
|
}
|
||||||
loop++;
|
loop++;
|
||||||
@@ -567,23 +576,22 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
|
window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
|
||||||
struct window *w, struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
struct winlink *wl, struct screen_write_ctx *ctx, u_int sx, u_int sy)
|
||||||
{
|
{
|
||||||
struct options *oo = s->options;
|
struct window *w = wl->window;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int cx = ctx->s->cx, cy = ctx->s->cy;
|
u_int cx = ctx->s->cx, cy = ctx->s->cy;
|
||||||
u_int loop, total, visible, each, width, offset;
|
u_int loop, total, visible, each, width, offset;
|
||||||
u_int current, start, end, remaining, i, pane_idx;
|
u_int current, start, end, remaining, i;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
int colour, active_colour, left, right;
|
int left, right;
|
||||||
char *label;
|
char *label;
|
||||||
|
const char *format;
|
||||||
|
struct format_tree *ft;
|
||||||
|
struct options *oo;
|
||||||
|
|
||||||
total = window_count_panes(w, 1);
|
total = window_count_panes(w, 1);
|
||||||
|
|
||||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
|
||||||
colour = options_get_number(oo, "display-panes-colour");
|
|
||||||
active_colour = options_get_number(oo, "display-panes-active-colour");
|
|
||||||
|
|
||||||
if (sx / total < 24) {
|
if (sx / total < 24) {
|
||||||
visible = sx / 24;
|
visible = sx / 24;
|
||||||
if (visible == 0)
|
if (visible == 0)
|
||||||
@@ -662,11 +670,13 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
|
|||||||
loop++;
|
loop++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
oo = wp->options;
|
||||||
|
|
||||||
if (wp == w->active)
|
ft = format_create(NULL, NULL, FORMAT_PANE|wp->id, 0);
|
||||||
gc.fg = active_colour;
|
format_defaults(ft, NULL, s, wl, wp);
|
||||||
else
|
|
||||||
gc.fg = colour;
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
|
style_apply(&gc, oo, "tree-mode-preview-style", ft);
|
||||||
|
|
||||||
if (left)
|
if (left)
|
||||||
offset = 3 + (i * each);
|
offset = 3 + (i * each);
|
||||||
@@ -680,15 +690,19 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
|
|||||||
screen_write_cursormove(ctx, cx + offset, cy, 0);
|
screen_write_cursormove(ctx, cx + offset, cy, 0);
|
||||||
screen_write_preview(ctx, &wp->base, width, sy);
|
screen_write_preview(ctx, &wp->base, width, sy);
|
||||||
|
|
||||||
if (window_pane_index(wp, &pane_idx) != 0)
|
format = options_get_string(oo, "tree-mode-preview-format");
|
||||||
pane_idx = loop;
|
if (*format != '\0') {
|
||||||
xasprintf(&label, " %u ", pane_idx);
|
label = format_expand(ft, format);
|
||||||
window_tree_draw_label(ctx, cx + offset, cy, each, sy, &gc,
|
if (*label != '\0') {
|
||||||
label);
|
window_tree_draw_label(ctx, cx + offset, cy,
|
||||||
|
width, sy, &gc, label);
|
||||||
|
}
|
||||||
free(label);
|
free(label);
|
||||||
|
}
|
||||||
|
|
||||||
if (loop != end - 1) {
|
if (loop != end - 1) {
|
||||||
screen_write_cursormove(ctx, cx + offset + width, cy, 0);
|
screen_write_cursormove(ctx, cx + offset + width, cy,
|
||||||
|
0);
|
||||||
screen_write_vline(ctx, sy, 0, 0);
|
screen_write_vline(ctx, sy, 0, 0);
|
||||||
}
|
}
|
||||||
loop++;
|
loop++;
|
||||||
@@ -703,10 +717,10 @@ window_tree_draw(void *modedata, void *itemdata, struct screen_write_ctx *ctx,
|
|||||||
{
|
{
|
||||||
struct window_tree_itemdata *item = itemdata;
|
struct window_tree_itemdata *item = itemdata;
|
||||||
struct session *sp;
|
struct session *sp;
|
||||||
struct winlink *wlp;
|
struct winlink *wl;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
window_tree_pull_item(item, &sp, &wlp, &wp);
|
window_tree_pull_item(item, &sp, &wl, &wp);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -717,7 +731,7 @@ window_tree_draw(void *modedata, void *itemdata, struct screen_write_ctx *ctx,
|
|||||||
window_tree_draw_session(modedata, sp, ctx, sx, sy);
|
window_tree_draw_session(modedata, sp, ctx, sx, sy);
|
||||||
break;
|
break;
|
||||||
case WINDOW_TREE_WINDOW:
|
case WINDOW_TREE_WINDOW:
|
||||||
window_tree_draw_window(modedata, sp, wlp->window, ctx, sx, sy);
|
window_tree_draw_window(modedata, sp, wl, ctx, sx, sy);
|
||||||
break;
|
break;
|
||||||
case WINDOW_TREE_PANE:
|
case WINDOW_TREE_PANE:
|
||||||
screen_write_preview(ctx, &wp->base, sx, sy);
|
screen_write_preview(ctx, &wp->base, sx, sy);
|
||||||
|
|||||||
13
window.c
13
window.c
@@ -407,9 +407,14 @@ window_remove_ref(struct window *w, const char *from)
|
|||||||
void
|
void
|
||||||
window_set_name(struct window *w, const char *new_name)
|
window_set_name(struct window *w, const char *new_name)
|
||||||
{
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
name = clean_name(new_name, "#");
|
||||||
|
if (name != NULL) {
|
||||||
free(w->name);
|
free(w->name);
|
||||||
utf8_stravis(&w->name, new_name, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
w->name = name;
|
||||||
notify_window("window-renamed", w);
|
notify_window("window-renamed", w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2132,13 +2137,15 @@ struct style_range *
|
|||||||
window_pane_border_status_get_range(struct window_pane *wp, u_int x, u_int y)
|
window_pane_border_status_get_range(struct window_pane *wp, u_int x, u_int y)
|
||||||
{
|
{
|
||||||
struct style_ranges *srs;
|
struct style_ranges *srs;
|
||||||
struct window *w = wp->window;
|
struct window *w;
|
||||||
struct options *wo = w->options;
|
struct options *wo;
|
||||||
u_int line;
|
u_int line;
|
||||||
int pane_status;
|
int pane_status;
|
||||||
|
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
w = wp->window;
|
||||||
|
wo = w->options;
|
||||||
srs = &wp->border_status_line.ranges;
|
srs = &wp->border_status_line.ranges;
|
||||||
|
|
||||||
pane_status = options_get_number(wo, "pane-border-status");
|
pane_status = options_get_number(wo, "pane-border-status");
|
||||||
|
|||||||
Reference in New Issue
Block a user