/* $OpenBSD$ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <fnmatch.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
#include <unistd.h>
#include "tmux.h"
#define CMD_FIND_PREFER_UNATTACHED 0x1
#define CMD_FIND_QUIET 0x2
#define CMD_FIND_WINDOW_INDEX 0x4
#define CMD_FIND_DEFAULT_MARKED 0x8
#define CMD_FIND_EXACT_SESSION 0x10
#define CMD_FIND_EXACT_WINDOW 0x20
enum cmd_find_type {
CMD_FIND_PANE,
CMD_FIND_WINDOW,
CMD_FIND_SESSION,
};
struct cmd_find_state {
struct cmd_q *cmdq;
int flags;
struct cmd_find_state *current;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
int idx;
};
struct session *cmd_find_try_TMUX(struct client *, struct window *);
int cmd_find_client_better(struct client *, struct client *);
struct client *cmd_find_best_client(struct client **, u_int);
int cmd_find_session_better(struct session *, struct session *,
int);
struct session *cmd_find_best_session(struct session **, u_int, int);
int cmd_find_best_session_with_window(struct cmd_find_state *);
int cmd_find_best_winlink_with_window(struct cmd_find_state *);
int cmd_find_current_session_with_client(struct cmd_find_state *);
int cmd_find_current_session(struct cmd_find_state *);
struct client *cmd_find_current_client(struct cmd_q *);
const char *cmd_find_map_table(const char *[][2], const char *);
int cmd_find_get_session(struct cmd_find_state *, const char *);
int cmd_find_get_window(struct cmd_find_state *, const char *);
int cmd_find_get_window_with_session(struct cmd_find_state *, const char *);
int cmd_find_get_window_with_pane(struct cmd_find_state *);
int cmd_find_get_pane(struct cmd_find_state *, const char *);
int cmd_find_get_pane_with_session(struct cmd_find_state *, const char *);
int cmd_find_get_pane_with_window(struct cmd_find_state *, const char *);
void cmd_find_clear_state(struct cmd_find_state *, struct cmd_q *, int);
void cmd_find_log_state(const char *, const char *, struct cmd_find_state *);
struct cmd_find_state *cmd_find_target(struct cmd_q *, const char *,
enum cmd_find_type, int);
const char *cmd_find_session_table[][2] = {
{ NULL, NULL }
};
const char *cmd_find_window_table[][2] = {
{ "{start}", "^" },
{ "{last}", "!" },
{ "{end}", "$" },
{ "{next}", "+" },
{ "{previous}", "-" },
{ NULL, NULL }
};
const char *cmd_find_pane_table[][2] = {
{ "{last}", "!" },
{ "{next}", "+" },
{ "{previous}", "-" },
{ "{top}", "top" },
{ "{bottom}", "bottom" },
{ "{left}", "left" },
{ "{right}", "right" },
{ "{top-left}", "top-left" },
{ "{top-right}", "top-right" },
{ "{bottom-left}", "bottom-left" },
{ "{bottom-right}", "bottom-right" },
{ "{up-of}", "{up-of}" },
{ "{down-of}", "{down-of}" },
{ "{left-of}", "{left-of}" },
{ "{right-of}", "{right-of}" },
{ NULL, NULL }
};
/* Get session from TMUX if present. */
struct session *
cmd_find_try_TMUX(struct client *c, struct window *w)
{
struct environ_entry *envent;
char tmp[256];
long long pid;
u_int session;
struct session *s;
envent = environ_find(&c->environ, "TMUX");
if (envent == NULL)
return (NULL);
if (sscanf(envent->value, "%255[^,],%lld,%d", tmp, &pid, &session) != 3)
return (NULL);
if (pid != getpid())
return (NULL);
log_debug("client %p TMUX is %s (session @%u)", c, envent->value,
session);
s = session_find_by_id(session);
if (s == NULL || (w != NULL && !session_has(s, w)))
return (NULL);
return (s);
}
/* Is this client better? */
int
cmd_find_client_better(struct client *c, struct client *than)
{
if (than == NULL)
return (1);
return (timercmp(&c->activity_time, &a
|