Re: select patch
Johannes Altmanninger <[email protected]> Fri, 20 Jun 2014 14:17:01 +0200
| Newsgroups | gmane.comp.window-managers.ratpoison.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Jeff,
Thanks for you patience.
The function pointer seems to work in a test program, but I get this
warning:
gcc -o test test.c
test.c: In function ‘main’:
test.c:9:45: warning: initialization from incompatible pointer type
compare_window_name_function my_compare = strncmp;
^
Meanwhile, I have done the following
I have commented out the read_window() function since it is not used
anywhere, and it calls find_window_name(), which works a bit different now.
cmd_select works now as expected:
first it tries to find an exact match
then a case-insensitive match
then a prefix match
and finally a case-insensitive prefix match
Then the first match is selected.
I have added the "selectstyle" setting that can be set to "simple" or
"cycle"
If it is on "cycle", the program looks for a matching window as
described above,
but if the window is the same as the currently selected it tries to find
another one within the current match_level
(so if you have 2 windows named "Foo" and "foobar", then "select foo"
will only match "Foo")
I have attached the current diff, it works now as expected.
I have defined the MATCH constants in window.h since find_window_name()
is the only thing using them, should they be put elsewhere? (they look a
bit odd)
Now I am gonna try to refactor find_window_name() . How can I get rid of
the warning above?
On 06/20/2014 12:56 PM, Jeff Abrahamson wrote:
> Hi, Johannes.
>
> Using char curname[MAX_WINDOW_NAME_LENGTH] is easiest. This is called
> stack allocation, and has the advantage that it is automatically
> cleaned up when the scope exits.
>
> A function pointer is just a variable to which you assign a pointer.
> Using typedefs helps immensely to get it right. I think you're
> close, but I'd need to check with a compiler to make sure I haven't
> myself made a syntax error. Something like
>
> typedef int (*compare_window_name_function)(char *name1, char
> *name2, int length);
> compare_window_name_function my_compare = strcmp;
>
> if((*my_compare)(a_name, another_name, 10)) { printf("yeah!\n"); }
>
>
> (I haven't compiled that, it's probably slightly wrong.)
>
>
> Jeff Abrahamson
> +33 6 24 40 01 57 <-- brièvement indisponible le 4 juillet
> +44 7920 594 255 <-- will change 18 July
>
> http://jeff.purple.com/
> http://blog.purple.com/jeff/
_______________________________________________
Ratpoison-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/ratpoison-devel
select.diff
(text/x-patch, 9.6 KB)
diff --git a/src/actions.c b/src/actions.c
index 7579101..6b35f37 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -81,6 +81,7 @@ static cmdret * set_topkmap (struct cmdarg **args);
static cmdret * set_historysize (struct cmdarg **args);
static cmdret * set_historycompaction (struct cmdarg **args);
static cmdret * set_historyexpansion (struct cmdarg **args);
+static cmdret * set_selectstyle (struct cmdarg **args);
LIST_HEAD(set_vars);
@@ -150,6 +151,7 @@ init_set_vars(void)
add_set_var ("historysize", set_historysize, 1, "", arg_NUMBER);
add_set_var ("historycompaction", set_historycompaction, 1, "", arg_NUMBER);
add_set_var ("historyexpansion", set_historyexpansion, 1, "", arg_NUMBER);
+ add_set_var ("selectstyle", set_selectstyle, 1, "", arg_STRING);
}
/* rp_keymaps is ratpoison's list of keymaps. */
@@ -1412,10 +1414,13 @@ cmd_select (int interactive UNUSED, struct cmdarg **args)
else
/* try by name */
{
- rp_window *win = find_window_name (str, 1);
-
+ rp_window *win = find_window_name (str, MATCH_EXACT);
+ if (!win)
+ win = find_window_name (str, MATCH_IGNORECASE);
+ if (!win)
+ win = find_window_name (str, MATCH_PREFIX);
if (!win)
- win = find_window_name (str, 0);
+ win = find_window_name (str, MATCH_IGNORECASE | MATCH_PREFIX);
if (win)
{
@@ -1885,55 +1890,55 @@ read_frame (struct sbuf *s, struct cmdarg **arg)
return cmdret_new (RET_FAILURE, "frame not found");
}
-static cmdret *
-read_window (struct argspec *spec, struct sbuf *s, struct cmdarg **arg)
-{
- rp_window *win = NULL;
- char *name;
- int n;
-
- if (s)
- name = xstrdup (sbuf_get (s));
- else
- name = get_input (spec->prompt, hist_WINDOW, window_completions);
-
- if (name)
- {
- /* try by number */
- if ((n = string_to_positive_int (name)) >= 0)
- {
- rp_window_elem *elem = group_find_window_by_number (rp_current_group, n);
- if (elem)
- win = elem->win;
- }
- else
- /* try by name */
- {
- win = find_window_name (name, 1);
- if (win == NULL)
- win = find_window_name (name, 0);
- }
-
- if (win)
- {
- *arg = xmalloc (sizeof(struct cmdarg));
- (*arg)->type = arg_WINDOW;
- (*arg)->arg.win = win;
- (*arg)->string = name;
- return NULL;
- }
- else
- {
- free (name);
- *arg = NULL;
- return cmdret_new (RET_SUCCESS, NULL);
- }
- }
-
- /* user abort. */
- *arg = NULL;
- return cmdret_new (RET_SUCCESS, NULL);
-}
+//static cmdret *
+//read_window (struct argspec *spec, struct sbuf *s, struct cmdarg **arg)
+//{
+// rp_window *win = NULL;
+// char *name;
+// int n;
+//
+// if (s)
+// name = xstrdup (sbuf_get (s));
+// else
+// name = get_input (spec->prompt, hist_WINDOW, window_completions);
+//
+// if (name)
+// {
+// /* try by number */
+// if ((n = string_to_positive_int (name)) >= 0)
+// {
+// rp_window_elem *elem = group_find_window_by_number (rp_current_group, n);
+// if (elem)
+// win = elem->win;
+// }
+// else
+// /* try by name */
+// {
+// win = find_window_name (name, 1);
+// if (win == NULL)
+// win = find_window_name (name, 0);
+// }
+//
+// if (win)
+// {
+// *arg = xmalloc (sizeof(struct cmdarg));
+// (*arg)->type = arg_WINDOW;
+// (*arg)->arg.win = win;
+// (*arg)->string = name;
+// return NULL;
+// }
+// else
+// {
+// free (name);
+// *arg = NULL;
+// return cmdret_new (RET_SUCCESS, NULL);
+// }
+// }
+//
+// /* user abort. */
+// *arg = NULL;
+// return cmdret_new (RET_SUCCESS, NULL);
+//}
static int
parse_wingravity (char *data)
@@ -2237,9 +2242,9 @@ read_arg (struct argspec *spec, struct sbuf *s, struct cmdarg **arg, const char
case arg_SHELLCMD:
ret = read_shellcmd (spec, s, arg, command_name);
break;
- case arg_WINDOW:
- ret = read_window (spec, s, arg);
- break;
+ //case arg_WINDOW:
+ // ret = read_window (spec, s, arg);
+ // break;
case arg_FRAME:
ret = read_frame (s, arg);
break;
@@ -2460,7 +2465,7 @@ arg_free (struct cmdarg *arg)
case arg_REST:
case arg_STRING:
case arg_NUMBER:
- case arg_WINDOW:
+ //case arg_WINDOW:
case arg_FRAME:
case arg_COMMAND:
case arg_SHELLCMD:
@@ -5684,6 +5689,25 @@ set_maxundos (struct cmdarg **args)
return cmdret_new (RET_SUCCESS, NULL);
}
+static cmdret *
+set_selectstyle (struct cmdarg **args)
+{
+ if (args[0] == NULL)
+ return cmdret_new (RET_SUCCESS, "%s",
+ defaults.select_style == SELECT_SIMPLE
+ ? "simple"
+ : "cycle"
+ );
+
+ if (!strncmp ("simple", ARG_STRING(0), 6))
+ defaults.select_style = SELECT_SIMPLE;
+ else if (!strncmp ("cycle", ARG_STRING(0), 5))
+ defaults.select_style = SELECT_PREFER_NOTSELECTED;
+ else
+ return cmdret_new (RET_FAILURE, "set selectstyle: invalid argument");
+ return cmdret_new (RET_SUCCESS, NULL);
+}
+
cmdret *
cmd_cnext (int interactive, struct cmdarg **args)
{
diff --git a/src/actions.h b/src/actions.h
index 519c1a7..2c15826 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -34,7 +34,7 @@ enum argtype { arg_REST,
arg_NUMBER,
arg_STRING,
arg_FRAME,
- arg_WINDOW,
+ //arg_WINDOW,
arg_COMMAND,
arg_SHELLCMD,
arg_KEYMAP,
diff --git a/src/data.h b/src/data.h
index f4bd185..01a8f1a 100644
--- a/src/data.h
+++ b/src/data.h
@@ -275,6 +275,9 @@ struct rp_defaults
/* Frame indicator format */
char *frame_fmt;
+
+ /* How the select command behaves */
+ int select_style;
};
/* Information about a child process. */
diff --git a/src/globals.h b/src/globals.h
index 1fb7e0f..db864fc 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -76,6 +76,11 @@
#define UNUSED
#endif
+#define MAX_WINDOW_NAME_LENGTH 0x04ff
+
+#define SELECT_SIMPLE 0
+#define SELECT_PREFER_NOTSELECTED 1
+
/* The list of groups. */
extern struct list_head rp_groups;
diff --git a/src/main.c b/src/main.c
index 52dbcce..7d3e191 100644
--- a/src/main.c
+++ b/src/main.c
@@ -599,6 +599,7 @@ init_defaults (void)
defaults.history_expansion = False;
defaults.frame_selectors = xstrdup ("");
defaults.maxundos = 20;
+ defaults.select_style = SELECT_SIMPLE ;
}
int
diff --git a/src/window.c b/src/window.c
index de9032a..7289bf3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "ratpoison.h"
@@ -283,31 +284,61 @@ find_window_number (int n)
}
rp_window *
-find_window_name (char *name, int exact_match)
+find_window_name (char *name, int match_type)
{
+ int compare_length, i;
+ char local_name[strlen(name)];
+ strcpy(local_name, name);
+ compare_length = (MATCH_PREFIX & match_type)
+ ? strlen(local_name)
+ : MAX_WINDOW_NAME_LENGTH ;
+
+ if(MATCH_IGNORECASE & match_type)
+ {
+ for(i=0; i<strlen(local_name); i++)
+ local_name[i] = toupper (local_name[i]);
+ }
+
rp_window_elem *cur;
+ char curname[MAX_WINDOW_NAME_LENGTH];
+ int current_win_number = 0;
+ rp_window *w = current_window();
+ if (w)
+ current_win_number = w->number;
+
+ int may_return = 1;
+ if (defaults.select_style == SELECT_PREFER_NOTSELECTED)
+ may_return = 0;
- if (!exact_match)
+ rp_window *first_match = NULL;
+
+ list_for_each_entry (cur, &rp_current_group->mapped_windows, node)
{
- list_for_each_entry (cur, &rp_current_group->mapped_windows, node)
+ strcpy(curname, window_name(cur->win));
+ if(MATCH_IGNORECASE & match_type)
{
- if (str_comp (name, window_name (cur->win), strlen (name)))
- return cur->win;
+ for(i=0; i<strlen(curname); i++)
+ curname[i] = toupper (curname[i]);
}
- }
- else
- {
- list_for_each_entry (cur, &rp_current_group->mapped_windows, node)
+ if (!strncmp (local_name, curname, compare_length))
{
- if (!strcmp (name, window_name (cur->win)))
- return cur->win;
+ if (may_return)
+ {
+ return cur->win;
+ }
+ else
+ {
+ if(cur->win->number == current_win_number)
+ may_return = 1;
+ if(!first_match)
+ first_match = cur->win;
+ }
}
}
-
- /* didn't find it */
- return NULL;
+ 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..aff1bc9 100644
--- a/src/window.h
+++ b/src/window.h
@@ -40,7 +40,10 @@ char *window_name (rp_window *win);
/* int goto_window_name (char *name); */
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 (char *name, int match_type);
+#define MATCH_EXACT 0x0000
+#define MATCH_PREFIX 0x0001
+#define MATCH_IGNORECASE 0x0002
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);