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..e38ab42 100644 --- a/src/window.c +++ b/src/window.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "ratpoison.h" @@ -283,31 +284,62 @@ find_window_number (int n) } rp_window * -find_window_name (char *name, int exact_match) +find_window_name (char *name, int match_type) { - rp_window_elem *cur; - - if (!exact_match) + typedef int (*compare_window_name_function) + (const char *name1, const char *name2, size_t length); + compare_window_name_function my_compare; + size_t compare_length = MAX_WINDOW_NAME_LENGTH; + switch(match_type) { - list_for_each_entry (cur, &rp_current_group->mapped_windows, node) - { - if (str_comp (name, window_name (cur->win), strlen (name))) - return cur->win; - } + case MATCH_EXACT: + my_compare = strncmp; + break; + case MATCH_IGNORECASE: + my_compare = strncasecmp; + break; + case MATCH_PREFIX: + my_compare = strncmp; + compare_length = strlen(name); + break; + case MATCH_IGNORECASE | MATCH_PREFIX: + my_compare = strncasecmp; + compare_length = strlen(name); + break; + default: + my_compare = strncmp; } - else + // number of the currently selected window + int current_win_number = current_window() ? current_window()->number : 0; + rp_window_elem *cur; + + int may_return = 1; + if (defaults.select_style == SELECT_PREFER_NOTSELECTED) + may_return = 0; + + 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) + if (!my_compare (name, window_name(cur->win), 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);