diff --git a/cfg.c b/cfg.c
index 84be3967..3ef46e66 100644
--- a/cfg.c
+++ b/cfg.c
@@ -27,12 +27,15 @@
 #include "tmux.h"
 
 struct client		 *cfg_client;
-static char		 *cfg_file;
 int			  cfg_finished;
 static char		**cfg_causes;
 static u_int		  cfg_ncauses;
 static struct cmdq_item	 *cfg_item;
 
+int                       cfg_quiet = 1;
+char                    **cfg_files;
+u_int                     cfg_nfiles;
+
 static enum cmd_retval
 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);
 }
 
-void
-set_cfg_file(const char *path)
-{
-	free(cfg_file);
-	cfg_file = xstrdup(path);
-}
-
 void
 start_cfg(void)
 {
 	struct client	 *c;
-	char		**paths;
-	u_int		  i, n;
+	u_int		  i;
 
 	/*
 	 * Configuration files are loaded without a client, so commands are run
@@ -89,15 +84,12 @@ start_cfg(void)
 		cmdq_append(c, cfg_item);
 	}
 
-	if (cfg_file == NULL) {
-		expand_paths(TMUX_CONF, &paths, &n);
-		for (i = 0; i < n; i++) {
-			load_cfg(paths[i], c, NULL, CMD_PARSE_QUIET, NULL);
-			free(paths[i]);
-		}
-		free(paths);
-	} else
-		load_cfg(cfg_file, c, NULL, 0, NULL);
+	for (i = 0; i < cfg_nfiles; i++) {
+		if (cfg_quiet)
+			load_cfg(cfg_files[i], c, NULL, CMD_PARSE_QUIET, NULL);
+		else
+			load_cfg(cfg_files[i], c, NULL, 0, NULL);
+	}
 
 	cmdq_append(NULL, cmdq_get_callback(cfg_done, NULL));
 }
diff --git a/format.c b/format.c
index e18e7852..c350683d 100644
--- a/format.c
+++ b/format.c
@@ -1412,6 +1412,26 @@ format_cb_client_written(struct format_tree *ft)
 	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. */
 static void *
 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,
 	  format_cb_client_written
 	},
+	{ "config_files", FORMAT_TABLE_STRING,
+	  format_cb_config_files
+	},
 	{ "cursor_character", FORMAT_TABLE_STRING,
 	  format_cb_cursor_character
 	},
diff --git a/tmux.1 b/tmux.1
index ac143a6f..4d844fef 100644
--- a/tmux.1
+++ b/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_sample" Ta "" Ta "Sample of start of buffer"
 .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_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"
diff --git a/tmux.c b/tmux.c
index ef8ff384..d1471ab3 100644
--- a/tmux.c
+++ b/tmux.c
@@ -138,11 +138,12 @@ expand_path(const char *path, const char *home)
 	return (xstrdup(path));
 }
 
-void
-expand_paths(const char *s, char ***paths, u_int *n)
+static void
+expand_paths(const char *s, char ***paths, u_int *n, int ignore_errors)
 {
 	const char	*home = find_home();
 	char		*copy, *next, *tmp, resolved[PATH_MAX], *expanded;
+	char		*path;
 	u_int		 i;
 
 	*paths = NULL;
@@ -158,20 +159,26 @@ expand_paths(const char *s, char ***paths, u_int *n)
 		if (realpath(expanded, resolved) == NULL) {
 			log_debug("%s: realpath(\"%s\") failed: %s", __func__,
 			    expanded, strerror(errno));
+			if (ignore_errors) {
+				free(expanded);
+				continue;
+			}
+			path = expanded;
+		} else {
+			path = xstrdup(resolved);
 			free(expanded);
-			continue;
 		}
-		free(expanded);
 		for (i = 0; i < *n; i++) {
-			if (strcmp(resolved, (*paths)[i]) == 0)
+			if (strcmp(path, (*paths)[i]) == 0)
 				break;
 		}
 		if (i != *n) {
-			log_debug("%s: duplicate path: %s", __func__, resolved);
+			log_debug("%s: duplicate path: %s", __func__, path);
+			free(path);
 			continue;
 		}
 		*paths = xreallocarray(*paths, (*n) + 1, sizeof *paths);
-		(*paths)[(*n)++] = xstrdup(resolved);
+		(*paths)[(*n)++] = path;
 	}
 	free(copy);
 }
@@ -189,7 +196,7 @@ make_label(const char *label, char **cause)
 		label = "default";
 	uid = getuid();
 
-	expand_paths(TMUX_SOCK, &paths, &n);
+	expand_paths(TMUX_SOCK, &paths, &n, 1);
 	if (n == 0) {
 		xasprintf(cause, "no suitable socket path");
 		return (NULL);
@@ -320,10 +327,11 @@ main(int argc, char **argv)
 {
 	char					*path = NULL, *label = NULL;
 	char					*cause, **var;
-	const char				*s, *shell, *cwd;
+	const char				*s, *cwd;
 	int					 opt, keys, feat = 0;
 	uint64_t				 flags = 0;
 	const struct options_table_entry	*oe;
+	u_int					 i;
 
 	if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL &&
 	    setlocale(LC_CTYPE, "C.UTF-8") == NULL) {
@@ -339,6 +347,7 @@ main(int argc, char **argv)
 
 	if (**argv == '-')
 		flags = CLIENT_LOGIN;
+	expand_paths(TMUX_CONF, &cfg_files, &cfg_nfiles, 1);
 
 	while ((opt = getopt(argc, argv, "2c:CDdf:lL:NqS:T:uUvV")) != -1) {
 		switch (opt) {
@@ -358,7 +367,11 @@ main(int argc, char **argv)
 				flags |= CLIENT_CONTROL;
 			break;
 		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;
  		case 'V':
 			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
 	 * if available.
 	 */
-	shell = getshell();
-	options_set_string(global_s_options, "default-shell", 0, "%s", shell);
+	options_set_string(global_s_options, "default-shell", 0, "%s",
+	    getshell());
 
 	/* Override keys to vi if VISUAL or EDITOR are set. */
 	if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
diff --git a/tmux.h b/tmux.h
index 7d08e0db..401bf82f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1888,7 +1888,6 @@ const char	*sig2name(int);
 const char	*find_cwd(void);
 const char	*find_home(void);
 const char	*getversion(void);
-void		 expand_paths(const char *, char ***, u_int *);
 
 /* proc.c */
 struct imsg;
@@ -1908,13 +1907,14 @@ pid_t	proc_fork_and_daemon(int *);
 /* cfg.c */
 extern int cfg_finished;
 extern struct client *cfg_client;
+extern char **cfg_files;
+extern u_int cfg_nfiles;
+extern int cfg_quiet;
 void	start_cfg(void);
 int	load_cfg(const char *, struct client *, struct cmdq_item *, int,
 	    struct cmdq_item **);
 int	load_cfg_from_buffer(const void *, size_t, const char *,
 	    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	cfg_print_causes(struct cmdq_item *);
 void	cfg_show_causes(struct session *);
diff --git a/window-copy.c b/window-copy.c
index 2f4b06e8..531431c8 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -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_move_left(struct screen *, u_int *, u_int *, int);
 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 *,
 		    struct grid *, struct grid *, u_int, u_int, u_int, int, int,
 		    int, int, u_int *);
@@ -2912,6 +2914,48 @@ window_copy_is_lowercase(const char *ptr)
 	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
  * 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) {
 				found = window_copy_search_rl_regex(gd,
 				    &px, &sx, i - 1, 0, fx + 1, &reg);
+				if (found) {
+					window_copy_search_back_overlap(gd,
+					    &reg, &px, &sx, &i, endline);
+				}
 			} else {
 				found = window_copy_search_rl(gd, sgd,
 				    &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) {
 		window_copy_search_marks(wme, &ss, regex, visible_only);
 		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++)
 				window_copy_cursor_right(wme, 1);
 		}
@@ -3164,8 +3218,11 @@ again:
 			if (window_copy_search_mark_at(data, px, py, &b) == 0) {
 				if (b + width > gd->sx * gd->sy)
 					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;
+				}
 				if (data->searchgen == UCHAR_MAX)
 					data->searchgen = 1;
 				else