select patch

Johannes Altmanninger <[email protected]> Tue, 17 Jun 2014 18:41:37 +0200
Newsgroups gmane.comp.window-managers.ratpoison.devel
Message-ID <[email protected]>
The default "select" command (disregarding window numbers) selects the 
first exact match,
if there is none, the argument is matched against the beginning of each 
window name,
again selecting the first match.
I have shortcuts to select my each of my windows by their name, but 
sometimes i have more
than one window with the same name. I wrote a script to alternate 
between them but I think
it is more appropriate as a native feature.
The attached patch adds a function to find a window by name, if there is 
more than one returns
the match after the currently selected. The select command is changed to 
use this function.

I am pretty new to C, so please let me know if I am doing something 
horribly wrong.

Johannes Altmanninger

_______________________________________________
Ratpoison-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/ratpoison-devel
multiselect.diff (text/x-patch, 2.9 KB)
diff --git a/src/actions.c b/src/actions.c
index 7579101..0ea24b2 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -1412,10 +1412,16 @@ cmd_select (int interactive UNUSED, struct cmdarg **args)
       else
         /* try by name */
         {
+            /*
           rp_window *win = find_window_name (str, 1);
 
           if (!win)
             win = find_window_name (str, 0);
+            */
+          rp_window *win = find_window_name_next (str, 1);
+
+          if (!win)
+              win = find_window_name_next (str, 0);
 
           if (win)
             {
diff --git a/src/window.c b/src/window.c
index de9032a..57180f0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -308,6 +308,55 @@ find_window_name (char *name, int exact_match)
   return NULL;
 }
 
+rp_window *
+find_window_name_next (char *name, int exact_match)
+{
+    /*  get the first matching window
+     *  next to the currently selected window
+     *  (if there is no match after it,
+     *  then select first_match)
+     *  this is useful for alternating between
+     *  windows with the same name via select
+     */
+    rp_window_elem *cur;
+    rp_window *w = current_window();
+    int current_win_number = w ? w->number : 0;
+    rp_window *first_match = NULL;
+    int passed_current = 0;
+    if (!exact_match)
+      {
+        list_for_each_entry (cur, &rp_current_group->mapped_windows, node)
+          {
+            if (str_comp (name, window_name (cur->win), strlen (name)))
+              {
+                if (passed_current)
+                    return cur->win;
+                else if (cur->win->number == current_win_number)
+                    passed_current = 1;
+                if (!first_match)
+                    first_match = cur->win;
+              }
+          }
+      }
+    else
+      {
+        list_for_each_entry (cur, &rp_current_group->mapped_windows, node)
+          {
+            if (!strcmp (name, window_name (cur->win)))
+              {
+                if (passed_current)
+                    return cur->win;
+                else if (cur->win->number == current_win_number)
+                    passed_current = 1;
+                if (!first_match)
+                    first_match = cur->win;
+              }
+          }
+      }
+    
+    return first_match;
+}
+
 /* Return the previous window in the list. Assumes window is in the
    mapped window list. */
 rp_window*
diff --git a/src/window.h b/src/window.h
index fdd246c..9df3c3a 100644
--- a/src/window.h
+++ b/src/window.h
@@ -41,6 +41,7 @@ char *window_name (rp_window *win);
 rp_window *find_window_other (rp_screen *screen);
 rp_window *find_window_by_number (int n);
 rp_window *find_window_name (char *name, int exact_match);
+rp_window *find_window_name_next (char *name, int exact_match);
 rp_window *find_window_prev (rp_window *w);
 rp_window *find_window_prev_with_frame (rp_window *w);
 rp_window *find_window_next (rp_window *w);