[BACK]Return to cmd-find-window.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/cmd-find-window.c between version 1.42 and 1.43

version 1.42, 2017/05/29 18:06:34 version 1.43, 2017/05/30 21:44:59
Line 18 
Line 18 
   
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <fnmatch.h>  
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  
   
 #include "tmux.h"  #include "tmux.h"
   
Line 28 
Line 26 
  * Find window containing text.   * Find window containing text.
  */   */
   
 #define FIND_WINDOW_TEMPLATE                                    \  
         "#{window_index}: #{window_name} "                      \  
         "[#{window_width}x#{window_height}] "                   \  
         "(#{window_panes} panes) #{window_find_matches}"  
   
 static enum cmd_retval  cmd_find_window_exec(struct cmd *, struct cmdq_item *);  static enum cmd_retval  cmd_find_window_exec(struct cmd *, struct cmdq_item *);
   
 static void             cmd_find_window_callback(struct window_choose_data *);  
   
 /* Flags for determining matching behavior. */  
 #define CMD_FIND_WINDOW_BY_TITLE   0x1  
 #define CMD_FIND_WINDOW_BY_CONTENT 0x2  
 #define CMD_FIND_WINDOW_BY_NAME    0x4  
   
 #define CMD_FIND_WINDOW_ALL             \  
         (CMD_FIND_WINDOW_BY_TITLE |     \  
          CMD_FIND_WINDOW_BY_CONTENT |   \  
          CMD_FIND_WINDOW_BY_NAME)  
   
 const struct cmd_entry cmd_find_window_entry = {  const struct cmd_entry cmd_find_window_entry = {
         .name = "find-window",          .name = "find-window",
         .alias = "findw",          .alias = "findw",
   
         .args = { "F:CNt:T", 1, 4 },          .args = { "CNt:T", 1, 1 },
         .usage = "[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",          .usage = "[-CNT] " CMD_TARGET_PANE_USAGE " match-string",
   
         .target = { 't', CMD_FIND_WINDOW, 0 },          .target = { 't', CMD_FIND_PANE, 0 },
   
         .flags = 0,          .flags = 0,
         .exec = cmd_find_window_exec          .exec = cmd_find_window_exec
 };  };
   
 struct cmd_find_window_data {  
         struct winlink  *wl;  
         char            *list_ctx;  
         u_int            pane_id;  
         TAILQ_ENTRY(cmd_find_window_data) entry;  
 };  
 TAILQ_HEAD(cmd_find_window_list, cmd_find_window_data);  
   
 static u_int    cmd_find_window_match_flags(struct args *);  
 static void     cmd_find_window_match(struct cmd_find_window_list *, int,  
                     struct winlink *, const char *, const char *);  
   
 static u_int  
 cmd_find_window_match_flags(struct args *args)  
 {  
         u_int   match_flags = 0;  
   
         /* Turn on flags based on the options. */  
         if (args_has(args, 'T'))  
                 match_flags |= CMD_FIND_WINDOW_BY_TITLE;  
         if (args_has(args, 'C'))  
                 match_flags |= CMD_FIND_WINDOW_BY_CONTENT;  
         if (args_has(args, 'N'))  
                 match_flags |= CMD_FIND_WINDOW_BY_NAME;  
   
         /* If none of the flags were set, default to matching anything. */  
         if (match_flags == 0)  
                 match_flags = CMD_FIND_WINDOW_ALL;  
   
         return (match_flags);  
 }  
   
 static void  
 cmd_find_window_match(struct cmd_find_window_list *find_list,  
     int match_flags, struct winlink *wl, const char *str,  
     const char *searchstr)  
 {  
         struct cmd_find_window_data     *find_data;  
         struct window_pane              *wp;  
         u_int                            i, line;  
         char                            *sres;  
   
         find_data = xcalloc(1, sizeof *find_data);  
   
         i = 0;  
         TAILQ_FOREACH(wp, &wl->window->panes, entry) {  
                 i++;  
   
                 if ((match_flags & CMD_FIND_WINDOW_BY_NAME) &&  
                     fnmatch(searchstr, wl->window->name, 0) == 0) {  
                         find_data->list_ctx = xstrdup("");  
                         break;  
                 }  
   
                 if ((match_flags & CMD_FIND_WINDOW_BY_TITLE) &&  
                     fnmatch(searchstr, wp->base.title, 0) == 0) {  
                         xasprintf(&find_data->list_ctx,  
                             "pane %u title: \"%s\"", i - 1, wp->base.title);  
                         break;  
                 }  
   
                 if (match_flags & CMD_FIND_WINDOW_BY_CONTENT &&  
                     (sres = window_pane_search_old(wp, str, &line)) != NULL) {  
                         xasprintf(&find_data->list_ctx,  
                             "pane %u line %u: \"%s\"", i - 1, line + 1, sres);  
                         free(sres);  
                         break;  
                 }  
         }  
   
         if (find_data->list_ctx != NULL) {  
                 find_data->wl = wl;  
                 find_data->pane_id = i - 1;  
                 TAILQ_INSERT_TAIL(find_list, find_data, entry);  
         } else  
                 free(find_data);  
 }  
   
 static enum cmd_retval  static enum cmd_retval
 cmd_find_window_exec(struct cmd *self, struct cmdq_item *item)  cmd_find_window_exec(struct cmd *self, struct cmdq_item *item)
 {  {
         struct args                     *args = self->args;          struct args             *args = self->args, *new_args;
         struct cmd_find_state           *current = &item->shared->current;          struct window_pane      *wp = item->target.wp;
         struct client                   *c = cmd_find_client(item, NULL, 1);          const char              *s = args->argv[0];
         struct window_choose_data       *cdata;          char                    *filter, *argv = { NULL };
         struct session                  *s = item->target.s;          int                      C, N, T;
         struct winlink                  *wl = item->target.wl, *wm;  
         struct cmd_find_window_list      find_list;  
         struct cmd_find_window_data     *find_data;  
         struct cmd_find_window_data     *find_data1;  
         char                            *str, *searchstr;  
         const char                      *template;  
         u_int                            i, match_flags;  
   
         if (c == NULL) {          C = args_has(args, 'C');
                 cmdq_error(item, "no client available");          N = args_has(args, 'N');
                 return (CMD_RETURN_ERROR);          T = args_has(args, 'T');
         }  
   
         if ((template = args_get(args, 'F')) == NULL)          if (!C && !N && !T)
                 template = FIND_WINDOW_TEMPLATE;                  C = N = T = 1;
   
         match_flags = cmd_find_window_match_flags(args);          if (C && N && T) {
         str = args->argv[0];                  xasprintf(&filter,
                       "#{||:"
                       "#{C:%s},#{||:#{m:*%s*,#{window_name}},"
                       "#{m:*%s*,#{pane_title}}}}",
                       s, s, s);
           } else if (C && N) {
                   xasprintf(&filter,
                       "#{||:#{C:%s},#{m:*%s*,#{window_name}}}",
                       s, s);
           } else if (C && T) {
                   xasprintf(&filter,
                       "#{||:#{C:%s},#{m:*%s*,#{pane_title}}}",
                       s, s);
           } else if (N && T) {
                   xasprintf(&filter,
                       "#{||:#{m:*%s*,#{window_name}},#{m:*%s*,#{pane_title}}}",
                       s, s);
           } else if (C)
                   xasprintf(&filter, "#{C:%s}", s);
           else if (N)
                   xasprintf(&filter, "#{m:*%s*,#{window_name}}", s);
           else if (T)
                   xasprintf(&filter, "#{m:*%s*,#{pane_title}}", s);
   
         TAILQ_INIT(&find_list);          new_args = args_parse("", 1, &argv);
           args_set(new_args, 'f', filter);
   
         xasprintf(&searchstr, "*%s*", str);          window_pane_set_mode(wp, &window_tree_mode, &item->target, new_args);
         RB_FOREACH(wm, winlinks, &s->windows)  
             cmd_find_window_match(&find_list, match_flags, wm, str, searchstr);  
         free(searchstr);  
   
         if (TAILQ_EMPTY(&find_list)) {          args_free(new_args);
                 cmdq_error(item, "no windows matching: %s", str);          free(filter);
                 return (CMD_RETURN_ERROR);  
         }  
   
         if (TAILQ_NEXT(TAILQ_FIRST(&find_list), entry) == NULL) {  
                 if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0) {  
                         cmd_find_from_session(current, s);  
                         server_redraw_session(s);  
                 }  
                 recalculate_sizes();  
                 goto out;  
         }  
   
         if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)  
                 goto out;  
   
         i = 0;  
         TAILQ_FOREACH(find_data, &find_list, entry) {  
                 cdata = window_choose_data_create(TREE_OTHER, c, c->session);  
                 cdata->idx = find_data->wl->idx;  
                 cdata->wl = find_data->wl;  
   
                 cdata->ft_template = xstrdup(template);  
                 cdata->pane_id = find_data->pane_id;  
   
                 format_add(cdata->ft, "line", "%u", i);  
                 format_add(cdata->ft, "window_find_matches", "%s",  
                     find_data->list_ctx);  
                 format_defaults(cdata->ft, NULL, s, find_data->wl, NULL);  
   
                 window_choose_add(wl->window->active, cdata);  
   
                 i++;  
         }  
   
         window_choose_ready(wl->window->active, 0, cmd_find_window_callback);  
   
 out:  
         TAILQ_FOREACH_SAFE(find_data, &find_list, entry, find_data1) {  
                 free(find_data->list_ctx);  
                 TAILQ_REMOVE(&find_list, find_data, entry);  
                 free(find_data);  
         }  
         return (CMD_RETURN_NORMAL);          return (CMD_RETURN_NORMAL);
 }  
   
 static void  
 cmd_find_window_callback(struct window_choose_data *cdata)  
 {  
         struct session          *s;  
         struct window_pane      *wp;  
   
         if (cdata == NULL)  
                 return;  
   
         s = cdata->start_session;  
         if (!session_alive(s))  
                 return;  
   
         wp = window_pane_at_index(cdata->wl->window, cdata->pane_id);  
         if (wp != NULL && window_pane_visible(wp))  
                 window_set_active_pane(cdata->wl->window, wp);  
   
         if (session_select(s, cdata->idx) == 0) {  
                 server_redraw_session(s);  
                 recalculate_sizes();  
         }  
 }  }

Legend:
Removed from v.1.42  
changed lines
  Added in v.1.43