mirror of
https://github.com/tmux/tmux.git
synced 2025-04-01 13:18:49 +00:00
Merge branch 'obsd-master' into master
This commit is contained in:
commit
0cd5ed9e9b
28
cfg.c
28
cfg.c
@ -27,12 +27,15 @@
|
|||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
struct client *cfg_client;
|
struct client *cfg_client;
|
||||||
static char *cfg_file;
|
|
||||||
int cfg_finished;
|
int cfg_finished;
|
||||||
static char **cfg_causes;
|
static char **cfg_causes;
|
||||||
static u_int cfg_ncauses;
|
static u_int cfg_ncauses;
|
||||||
static struct cmdq_item *cfg_item;
|
static struct cmdq_item *cfg_item;
|
||||||
|
|
||||||
|
int cfg_quiet = 1;
|
||||||
|
char **cfg_files;
|
||||||
|
u_int cfg_nfiles;
|
||||||
|
|
||||||
static enum cmd_retval
|
static enum cmd_retval
|
||||||
cfg_client_done(__unused struct cmdq_item *item, __unused void *data)
|
cfg_client_done(__unused struct cmdq_item *item, __unused void *data)
|
||||||
{
|
{
|
||||||
@ -59,19 +62,11 @@ cfg_done(__unused struct cmdq_item *item, __unused void *data)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
set_cfg_file(const char *path)
|
|
||||||
{
|
|
||||||
free(cfg_file);
|
|
||||||
cfg_file = xstrdup(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
start_cfg(void)
|
start_cfg(void)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c;
|
||||||
char **paths;
|
u_int i;
|
||||||
u_int i, n;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration files are loaded without a client, so commands are run
|
* Configuration files are loaded without a client, so commands are run
|
||||||
@ -89,15 +84,12 @@ start_cfg(void)
|
|||||||
cmdq_append(c, cfg_item);
|
cmdq_append(c, cfg_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_file == NULL) {
|
for (i = 0; i < cfg_nfiles; i++) {
|
||||||
expand_paths(TMUX_CONF, &paths, &n);
|
if (cfg_quiet)
|
||||||
for (i = 0; i < n; i++) {
|
load_cfg(cfg_files[i], c, NULL, CMD_PARSE_QUIET, NULL);
|
||||||
load_cfg(paths[i], c, NULL, CMD_PARSE_QUIET, NULL);
|
else
|
||||||
free(paths[i]);
|
load_cfg(cfg_files[i], c, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
free(paths);
|
|
||||||
} else
|
|
||||||
load_cfg(cfg_file, c, NULL, 0, NULL);
|
|
||||||
|
|
||||||
cmdq_append(NULL, cmdq_get_callback(cfg_done, NULL));
|
cmdq_append(NULL, cmdq_get_callback(cfg_done, NULL));
|
||||||
}
|
}
|
||||||
|
23
format.c
23
format.c
@ -1412,6 +1412,26 @@ format_cb_client_written(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback for config_files. */
|
||||||
|
static void *
|
||||||
|
format_cb_config_files(__unused struct format_tree *ft)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
size_t slen = 0;
|
||||||
|
u_int i;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
for (i = 0; i < cfg_nfiles; i++) {
|
||||||
|
n = strlen(cfg_files[i]) + 1;
|
||||||
|
s = xrealloc(s, slen + n + 1);
|
||||||
|
slen += xsnprintf(s + slen, n + 1, "%s,", cfg_files[i]);
|
||||||
|
}
|
||||||
|
if (s == NULL)
|
||||||
|
return (xstrdup(""));
|
||||||
|
s[slen - 1] = '\0';
|
||||||
|
return (s);
|
||||||
|
}
|
||||||
|
|
||||||
/* Callback for cursor_flag. */
|
/* Callback for cursor_flag. */
|
||||||
static void *
|
static void *
|
||||||
format_cb_cursor_flag(struct format_tree *ft)
|
format_cb_cursor_flag(struct format_tree *ft)
|
||||||
@ -2569,6 +2589,9 @@ static const struct format_table_entry format_table[] = {
|
|||||||
{ "client_written", FORMAT_TABLE_STRING,
|
{ "client_written", FORMAT_TABLE_STRING,
|
||||||
format_cb_client_written
|
format_cb_client_written
|
||||||
},
|
},
|
||||||
|
{ "config_files", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_config_files
|
||||||
|
},
|
||||||
{ "cursor_character", FORMAT_TABLE_STRING,
|
{ "cursor_character", FORMAT_TABLE_STRING,
|
||||||
format_cb_cursor_character
|
format_cb_cursor_character
|
||||||
},
|
},
|
||||||
|
1
tmux.1
1
tmux.1
@ -4763,6 +4763,7 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "buffer_name" Ta "" Ta "Name of buffer"
|
.It Li "buffer_name" Ta "" Ta "Name of buffer"
|
||||||
.It Li "buffer_sample" Ta "" Ta "Sample of start of buffer"
|
.It Li "buffer_sample" Ta "" Ta "Sample of start of buffer"
|
||||||
.It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes"
|
.It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes"
|
||||||
|
.It Li "config_files" Ta "" Ta "List of configuration files loaded"
|
||||||
.It Li "client_activity" Ta "" Ta "Time client last had activity"
|
.It Li "client_activity" Ta "" Ta "Time client last had activity"
|
||||||
.It Li "client_cell_height" Ta "" Ta "Height of each client cell in pixels"
|
.It Li "client_cell_height" Ta "" Ta "Height of each client cell in pixels"
|
||||||
.It Li "client_cell_width" Ta "" Ta "Width of each client cell in pixels"
|
.It Li "client_cell_width" Ta "" Ta "Width of each client cell in pixels"
|
||||||
|
33
tmux.c
33
tmux.c
@ -138,11 +138,12 @@ expand_path(const char *path, const char *home)
|
|||||||
return (xstrdup(path));
|
return (xstrdup(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
expand_paths(const char *s, char ***paths, u_int *n)
|
expand_paths(const char *s, char ***paths, u_int *n, int ignore_errors)
|
||||||
{
|
{
|
||||||
const char *home = find_home();
|
const char *home = find_home();
|
||||||
char *copy, *next, *tmp, resolved[PATH_MAX], *expanded;
|
char *copy, *next, *tmp, resolved[PATH_MAX], *expanded;
|
||||||
|
char *path;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
*paths = NULL;
|
*paths = NULL;
|
||||||
@ -158,20 +159,26 @@ expand_paths(const char *s, char ***paths, u_int *n)
|
|||||||
if (realpath(expanded, resolved) == NULL) {
|
if (realpath(expanded, resolved) == NULL) {
|
||||||
log_debug("%s: realpath(\"%s\") failed: %s", __func__,
|
log_debug("%s: realpath(\"%s\") failed: %s", __func__,
|
||||||
expanded, strerror(errno));
|
expanded, strerror(errno));
|
||||||
|
if (ignore_errors) {
|
||||||
free(expanded);
|
free(expanded);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
path = expanded;
|
||||||
|
} else {
|
||||||
|
path = xstrdup(resolved);
|
||||||
free(expanded);
|
free(expanded);
|
||||||
|
}
|
||||||
for (i = 0; i < *n; i++) {
|
for (i = 0; i < *n; i++) {
|
||||||
if (strcmp(resolved, (*paths)[i]) == 0)
|
if (strcmp(path, (*paths)[i]) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != *n) {
|
if (i != *n) {
|
||||||
log_debug("%s: duplicate path: %s", __func__, resolved);
|
log_debug("%s: duplicate path: %s", __func__, path);
|
||||||
|
free(path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*paths = xreallocarray(*paths, (*n) + 1, sizeof *paths);
|
*paths = xreallocarray(*paths, (*n) + 1, sizeof *paths);
|
||||||
(*paths)[(*n)++] = xstrdup(resolved);
|
(*paths)[(*n)++] = path;
|
||||||
}
|
}
|
||||||
free(copy);
|
free(copy);
|
||||||
}
|
}
|
||||||
@ -189,7 +196,7 @@ make_label(const char *label, char **cause)
|
|||||||
label = "default";
|
label = "default";
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
|
|
||||||
expand_paths(TMUX_SOCK, &paths, &n);
|
expand_paths(TMUX_SOCK, &paths, &n, 1);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
xasprintf(cause, "no suitable socket path");
|
xasprintf(cause, "no suitable socket path");
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -320,10 +327,11 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char *path = NULL, *label = NULL;
|
char *path = NULL, *label = NULL;
|
||||||
char *cause, **var;
|
char *cause, **var;
|
||||||
const char *s, *shell, *cwd;
|
const char *s, *cwd;
|
||||||
int opt, keys, feat = 0;
|
int opt, keys, feat = 0;
|
||||||
uint64_t flags = 0;
|
uint64_t flags = 0;
|
||||||
const struct options_table_entry *oe;
|
const struct options_table_entry *oe;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL &&
|
if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL &&
|
||||||
setlocale(LC_CTYPE, "C.UTF-8") == NULL) {
|
setlocale(LC_CTYPE, "C.UTF-8") == NULL) {
|
||||||
@ -339,6 +347,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (**argv == '-')
|
if (**argv == '-')
|
||||||
flags = CLIENT_LOGIN;
|
flags = CLIENT_LOGIN;
|
||||||
|
expand_paths(TMUX_CONF, &cfg_files, &cfg_nfiles, 1);
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "2c:CDdf:lL:NqS:T:uUvV")) != -1) {
|
while ((opt = getopt(argc, argv, "2c:CDdf:lL:NqS:T:uUvV")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@ -358,7 +367,11 @@ main(int argc, char **argv)
|
|||||||
flags |= CLIENT_CONTROL;
|
flags |= CLIENT_CONTROL;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
set_cfg_file(optarg);
|
for (i = 0; i < cfg_nfiles; i++)
|
||||||
|
free(cfg_files[i]);
|
||||||
|
free(cfg_files);
|
||||||
|
expand_paths(optarg, &cfg_files, &cfg_nfiles, 0);
|
||||||
|
cfg_quiet = 0;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
printf("%s %s\n", getprogname(), getversion());
|
printf("%s %s\n", getprogname(), getversion());
|
||||||
@ -450,8 +463,8 @@ main(int argc, char **argv)
|
|||||||
* The default shell comes from SHELL or from the user's passwd entry
|
* The default shell comes from SHELL or from the user's passwd entry
|
||||||
* if available.
|
* if available.
|
||||||
*/
|
*/
|
||||||
shell = getshell();
|
options_set_string(global_s_options, "default-shell", 0, "%s",
|
||||||
options_set_string(global_s_options, "default-shell", 0, "%s", shell);
|
getshell());
|
||||||
|
|
||||||
/* Override keys to vi if VISUAL or EDITOR are set. */
|
/* Override keys to vi if VISUAL or EDITOR are set. */
|
||||||
if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
|
if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
|
||||||
|
6
tmux.h
6
tmux.h
@ -1888,7 +1888,6 @@ const char *sig2name(int);
|
|||||||
const char *find_cwd(void);
|
const char *find_cwd(void);
|
||||||
const char *find_home(void);
|
const char *find_home(void);
|
||||||
const char *getversion(void);
|
const char *getversion(void);
|
||||||
void expand_paths(const char *, char ***, u_int *);
|
|
||||||
|
|
||||||
/* proc.c */
|
/* proc.c */
|
||||||
struct imsg;
|
struct imsg;
|
||||||
@ -1908,13 +1907,14 @@ pid_t proc_fork_and_daemon(int *);
|
|||||||
/* cfg.c */
|
/* cfg.c */
|
||||||
extern int cfg_finished;
|
extern int cfg_finished;
|
||||||
extern struct client *cfg_client;
|
extern struct client *cfg_client;
|
||||||
|
extern char **cfg_files;
|
||||||
|
extern u_int cfg_nfiles;
|
||||||
|
extern int cfg_quiet;
|
||||||
void start_cfg(void);
|
void start_cfg(void);
|
||||||
int load_cfg(const char *, struct client *, struct cmdq_item *, int,
|
int load_cfg(const char *, struct client *, struct cmdq_item *, int,
|
||||||
struct cmdq_item **);
|
struct cmdq_item **);
|
||||||
int load_cfg_from_buffer(const void *, size_t, const char *,
|
int load_cfg_from_buffer(const void *, size_t, const char *,
|
||||||
struct client *, struct cmdq_item *, int, struct cmdq_item **);
|
struct client *, struct cmdq_item *, int, struct cmdq_item **);
|
||||||
void set_cfg_file(const char *);
|
|
||||||
const char *get_cfg_file(void);
|
|
||||||
void printflike(1, 2) cfg_add_cause(const char *, ...);
|
void printflike(1, 2) cfg_add_cause(const char *, ...);
|
||||||
void cfg_print_causes(struct cmdq_item *);
|
void cfg_print_causes(struct cmdq_item *);
|
||||||
void cfg_show_causes(struct session *);
|
void cfg_show_causes(struct session *);
|
||||||
|
@ -73,6 +73,8 @@ static int window_copy_search_marks(struct window_mode_entry *,
|
|||||||
static void window_copy_clear_marks(struct window_mode_entry *);
|
static void window_copy_clear_marks(struct window_mode_entry *);
|
||||||
static void window_copy_move_left(struct screen *, u_int *, u_int *, int);
|
static void window_copy_move_left(struct screen *, u_int *, u_int *, int);
|
||||||
static int window_copy_is_lowercase(const char *);
|
static int window_copy_is_lowercase(const char *);
|
||||||
|
static void window_copy_search_back_overlap(struct grid *, regex_t *,
|
||||||
|
u_int *, u_int *, u_int *, u_int);
|
||||||
static int window_copy_search_jump(struct window_mode_entry *,
|
static int window_copy_search_jump(struct window_mode_entry *,
|
||||||
struct grid *, struct grid *, u_int, u_int, u_int, int, int,
|
struct grid *, struct grid *, u_int, u_int, u_int, int, int,
|
||||||
int, int, u_int *);
|
int, int, u_int *);
|
||||||
@ -2912,6 +2914,48 @@ window_copy_is_lowercase(const char *ptr)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle backward wrapped regex searches with overlapping matches. In this case
|
||||||
|
* find the longest overlapping match from previous wrapped lines.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
window_copy_search_back_overlap(struct grid *gd, regex_t *preg, u_int *ppx,
|
||||||
|
u_int *psx, u_int *ppy, u_int endline)
|
||||||
|
{
|
||||||
|
u_int endx, endy, oldendx, oldendy, px, py, sx;
|
||||||
|
int found = 1;
|
||||||
|
|
||||||
|
oldendx = *ppx + *psx;
|
||||||
|
oldendy = *ppy - 1;
|
||||||
|
while (oldendx > gd->sx - 1) {
|
||||||
|
oldendx -= gd->sx;
|
||||||
|
oldendy++;
|
||||||
|
}
|
||||||
|
endx = oldendx;
|
||||||
|
endy = oldendy;
|
||||||
|
px = *ppx;
|
||||||
|
py = *ppy;
|
||||||
|
while (found && px == 0 && py - 1 > endline &&
|
||||||
|
grid_get_line(gd, py - 2)->flags & GRID_LINE_WRAPPED &&
|
||||||
|
endx == oldendx && endy == oldendy) {
|
||||||
|
py--;
|
||||||
|
found = window_copy_search_rl_regex(gd, &px, &sx, py - 1, 0,
|
||||||
|
gd->sx, preg);
|
||||||
|
if (found) {
|
||||||
|
endx = px + sx;
|
||||||
|
endy = py - 1;
|
||||||
|
while (endx > gd->sx - 1) {
|
||||||
|
endx -= gd->sx;
|
||||||
|
endy++;
|
||||||
|
}
|
||||||
|
if (endx == oldendx && endy == oldendy) {
|
||||||
|
*ppx = px;
|
||||||
|
*ppy = py;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for text stored in sgd starting from position fx,fy up to endline. If
|
* Search for text stored in sgd starting from position fx,fy up to endline. If
|
||||||
* found, jump to it. If cis then ignore case. The direction is 0 for searching
|
* found, jump to it. If cis then ignore case. The direction is 0 for searching
|
||||||
@ -2964,6 +3008,10 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
|
|||||||
if (regex) {
|
if (regex) {
|
||||||
found = window_copy_search_rl_regex(gd,
|
found = window_copy_search_rl_regex(gd,
|
||||||
&px, &sx, i - 1, 0, fx + 1, ®);
|
&px, &sx, i - 1, 0, fx + 1, ®);
|
||||||
|
if (found) {
|
||||||
|
window_copy_search_back_overlap(gd,
|
||||||
|
®, &px, &sx, &i, endline);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
found = window_copy_search_rl(gd, sgd,
|
found = window_copy_search_rl(gd, sgd,
|
||||||
&px, i - 1, 0, fx + 1, cis);
|
&px, i - 1, 0, fx + 1, cis);
|
||||||
@ -3048,6 +3096,12 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex,
|
|||||||
if (found) {
|
if (found) {
|
||||||
window_copy_search_marks(wme, &ss, regex, visible_only);
|
window_copy_search_marks(wme, &ss, regex, visible_only);
|
||||||
if (foundlen != 0) {
|
if (foundlen != 0) {
|
||||||
|
/* Adjust for wrapped lines eating one right. */
|
||||||
|
i = data->cx + foundlen;
|
||||||
|
while (i > gd->sx - 1) {
|
||||||
|
i -= gd->sx;
|
||||||
|
window_copy_cursor_right(wme, 1);
|
||||||
|
}
|
||||||
for (i = 0; i < foundlen; i++)
|
for (i = 0; i < foundlen; i++)
|
||||||
window_copy_cursor_right(wme, 1);
|
window_copy_cursor_right(wme, 1);
|
||||||
}
|
}
|
||||||
@ -3164,8 +3218,11 @@ again:
|
|||||||
if (window_copy_search_mark_at(data, px, py, &b) == 0) {
|
if (window_copy_search_mark_at(data, px, py, &b) == 0) {
|
||||||
if (b + width > gd->sx * gd->sy)
|
if (b + width > gd->sx * gd->sy)
|
||||||
width = (gd->sx * gd->sy) - b;
|
width = (gd->sx * gd->sy) - b;
|
||||||
for (i = b; i < b + width; i++)
|
for (i = b; i < b + width; i++) {
|
||||||
|
if (data->searchmark[i] != 0)
|
||||||
|
continue;
|
||||||
data->searchmark[i] = data->searchgen;
|
data->searchmark[i] = data->searchgen;
|
||||||
|
}
|
||||||
if (data->searchgen == UCHAR_MAX)
|
if (data->searchgen == UCHAR_MAX)
|
||||||
data->searchgen = 1;
|
data->searchgen = 1;
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user