diff options
author | sabetts <sabetts> | 2006-03-15 05:43:38 +0000 |
---|---|---|
committer | sabetts <sabetts> | 2006-03-15 05:43:38 +0000 |
commit | 9c9e71d4e681112668240c6c0c9715b8f77ed673 (patch) | |
tree | 0d818469f129c7f7aecf933c93599f77df00e651 /src | |
parent | 0d47aa583ef5ce0178de264f46fcb028c8592e53 (diff) | |
download | ratpoison-9c9e71d4e681112668240c6c0c9715b8f77ed673.zip |
(init_user_commands): add optional argument to "info"
(cmd_info): handle optional argument
* src/format.c: new file
* src/format.h: new file
* Makefile.am (ratpoison_SOURCES): add format.c and format.h
* src/actions.c (set_infofmt): new function
(wingravity_to_string): char * instead of static char * because needed in format.c
(cmd_info): use format_string
* src/actions.h (wingravity_to_string): add prototype
* src/data.h (info_fmt): new variable
* src/main.c (init_defaults): set a value for defaults.info_fmt
* src/ratpoison.h: include format.h
* src/windows.c (get_window_list): use format_string
(isdigit): remove function as the formatting is now done in format.c
(concat_width): likewise
(format_window_name): likewise
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/actions.c | 52 | ||||
-rw-r--r-- | src/actions.h | 1 | ||||
-rw-r--r-- | src/data.h | 1 | ||||
-rw-r--r-- | src/format.c | 291 | ||||
-rw-r--r-- | src/format.h | 27 | ||||
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/ratpoison.h | 1 | ||||
-rw-r--r-- | src/window.c | 147 |
9 files changed, 363 insertions, 162 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 500306f..c9fd5c9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## -## $Id: Makefile.am,v 1.22 2004/12/04 03:33:24 sabetts Exp $ +## $Id: Makefile.am,v 1.23 2006/03/15 05:43:38 sabetts Exp $ bin_PROGRAMS = ratpoison @@ -35,6 +35,8 @@ ratpoison_SOURCES = actions.c \ editor.h \ events.c \ events.h \ + format.c \ + format.h \ frame.c \ frame.h \ getopt.c \ diff --git a/src/actions.c b/src/actions.c index c41ac91..b756c41 100644 --- a/src/actions.c +++ b/src/actions.c @@ -62,6 +62,7 @@ static cmdret * set_barpadding (struct cmdarg **args); static cmdret * set_winliststyle (struct cmdarg **args); static cmdret * set_framesels (struct cmdarg **args); static cmdret * set_maxundos (struct cmdarg **args); +static cmdret * set_infofmt (struct cmdarg **args); LIST_HEAD(set_vars); @@ -113,6 +114,7 @@ init_set_vars() add_set_var ("barpadding", set_barpadding, 2, "", arg_NUMBER, "", arg_NUMBER); add_set_var ("winliststyle", set_winliststyle, 1, "", arg_STRING); add_set_var ("framesels", set_framesels, 1, "", arg_STRING); + add_set_var ("infofmt", set_infofmt, 1, "", arg_REST); } /* rp_keymaps is ratpoison's list of keymaps. */ @@ -218,7 +220,8 @@ init_user_commands() "Keymap: ", arg_KEYMAP); add_command ("hsplit", cmd_h_split, 1, 0, 0, "Split: ", arg_STRING); - add_command ("info", cmd_info, 0, 0, 0); + add_command ("info", cmd_info, 1, 0, 0, + "Format: ", arg_REST); add_command ("kill", cmd_kill, 0, 0, 0); add_command ("lastmsg", cmd_lastmsg, 0, 0, 0); add_command ("license", cmd_license, 0, 0, 0); @@ -1586,9 +1589,6 @@ exec_completions (char *str) /* Add our line to the list. */ elem = sbuf_new (0); sbuf_copy (elem, s); - /* The space is so when the user completes a space is - conveniently inserted after the command. */ - sbuf_concat (elem, " "); list_add_tail (&elem->node, head); sbuf_clear (line); @@ -3297,7 +3297,7 @@ cmd_rudeness (int interactive, struct cmdarg **args) return cmdret_new (RET_SUCCESS, NULL); } -static char * +char * wingravity_to_string (int g) { switch (g) @@ -3593,6 +3593,18 @@ set_waitcursor (struct cmdarg **args) } static cmdret * +set_infofmt (struct cmdarg **args) +{ + if (args[0] == NULL) + return cmdret_new (RET_SUCCESS, "%s", defaults.info_fmt); + + free (defaults.info_fmt); + defaults.info_fmt = xstrdup (ARG_STRING(0)); + + return cmdret_new (RET_SUCCESS, NULL); +} + +static cmdret * set_winfmt (struct cmdarg **args) { if (args[0] == NULL) @@ -3778,22 +3790,32 @@ cmd_unsetenv (int interactive, struct cmdarg **args) cmdret * cmd_info (int interactive, struct cmdarg **args) { - if (current_window() == NULL) - return cmdret_new (RET_SUCCESS, "(%d, %d) No window", - current_screen()->width, current_screen()->height); - else + struct sbuf *buf; + char *tmp; + if (current_window() != NULL) { rp_window *win = current_window(); rp_window_elem *win_elem; win_elem = group_find_window (&rp_current_group->mapped_windows, win); + if (!win_elem) + win_elem = group_find_window (&rp_current_group->unmapped_windows, win); + if (win_elem) - return cmdret_new (RET_SUCCESS, "(%d,%d) %d(%s)%s", win->width, win->height, - win_elem->number, window_name (win), - win->transient ? " Transient":""); - else - return cmdret_new (RET_SUCCESS, "(%d,%d) (%s)%s", win->width, win->height, - window_name (win), win->transient ? " Transient":""); + { + char *s; + + if (args[0] == NULL) + s = defaults.info_fmt; + else + s = ARG_STRING(0); + buf = sbuf_new (0); + format_string (s, win_elem, buf); + tmp = sbuf_free_struct (buf); + return cmdret_new (RET_SUCCESS, "%s", tmp); + } } + + return cmdret_new (RET_SUCCESS, "No window."); } /* Thanks to Gergely Nagy <algernon@debian.org> for the original diff --git a/src/actions.h b/src/actions.h index da329d2..9e323cf 100644 --- a/src/actions.h +++ b/src/actions.h @@ -215,6 +215,7 @@ void cmdret_free (cmdret *ret); void keymap_free (rp_keymap *map); void free_aliases (); void free_keymaps (); +char *wingravity_to_string (int g); rp_action* find_keybinding (KeySym keysym, int state, rp_keymap *map); rp_action* find_keybinding_by_action (char *action, rp_keymap *map); @@ -229,6 +229,7 @@ struct rp_defaults int wait_for_key_cursor; char *window_fmt; + char *info_fmt; /* Which name to use: wm_name, res_name, res_class. */ int win_name; diff --git a/src/format.c b/src/format.c new file mode 100644 index 0000000..bbe463c --- /dev/null +++ b/src/format.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2006 Antti Nykänen <aon@iki.fi> + * + * This file is part of ratpoison. + * + * ratpoison is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ratpoison is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "ratpoison.h" + +/* Function prototypes for format char expanders. */ +#define RP_FMT(fn) static void fmt_ ## fn (rp_window_elem *elem, struct sbuf *buf) +RP_FMT(framenum); +RP_FMT(lastaccess); +RP_FMT(name); +RP_FMT(number); +RP_FMT(resname); +RP_FMT(resclass); +RP_FMT(status); +RP_FMT(windowid); +RP_FMT(height); +RP_FMT(width); +RP_FMT(incheight); +RP_FMT(incwidth); +RP_FMT(gravity); +RP_FMT(screen); +RP_FMT(xinescreen); +RP_FMT(transient); + +struct fmt_item { + /* The format character */ + char fmt_char; + + /* Callback to return the expanded string. */ + void (*fmt_fn)(rp_window_elem *, struct sbuf *); +}; + +struct fmt_item fmt_items[] = { + { 'a', fmt_resname }, + { 'g', fmt_gravity }, + { 'h', fmt_height }, + { 'H', fmt_incheight }, + { 'c', fmt_resclass }, + { 'f', fmt_framenum }, + { 'i', fmt_windowid }, + { 'l', fmt_lastaccess }, + { 'n', fmt_number }, + { 's', fmt_status }, + { 'S', fmt_screen }, + { 't', fmt_name }, + { 'T', fmt_transient }, + { 'w', fmt_width }, + { 'W', fmt_incwidth }, + { 'x', fmt_xinescreen }, + { 0, NULL } +}; + +/* if width >= 0 then limit the width of s to width chars. */ +static void +concat_width (struct sbuf *buf, char *s, int width) +{ + if (width >= 0) + { + char *s1 = xsprintf ("%%.%ds", width); + char *s2 = xsprintf (s1, s); + sbuf_concat (buf, s2); + free (s1); + free (s2); + } + else + sbuf_concat (buf, s); +} + +void +format_string (char *fmt, rp_window_elem *win_elem, struct sbuf *buffer) +{ +#define STATE_READ 0 +#define STATE_NUMBER 1 +#define STATE_ESCAPE 2 + int state = STATE_READ; + char dbuf[10]; + int width = -1; + struct sbuf *retbuf; + int fip, found; + + retbuf = sbuf_new (0); + + for(; *fmt; fmt++) + { + if (*fmt == '%' && state == STATE_READ) + { + state = STATE_ESCAPE; + continue; + } + + if ((state == STATE_ESCAPE || state == STATE_NUMBER) && isdigit(*fmt)) + { + /* Accumulate the width one digit at a time. */ + if (state == STATE_ESCAPE) + width = 0; + width *= 10; + width += *fmt - '0'; + state = STATE_NUMBER; + continue; + } + + found = 0; + if (state == STATE_ESCAPE || state == STATE_NUMBER) + { + if (*fmt == '%') + sbuf_concat (buffer, "%"); + else + { + for (fip = 0; fmt_items[fip].fmt_char; fip++) + { + if (fmt_items[fip].fmt_char == *fmt) + { + sbuf_clear (retbuf); + fmt_items[fip].fmt_fn(win_elem, retbuf); + concat_width (buffer, sbuf_get (retbuf), width); + found = 1; + break; + } + } + if (!found) + { + sbuf_printf_concat (buffer, "%%%c", *fmt); + break; + } + } + state = STATE_READ; + width = -1; + } + else + { + /* Insert the character. */ + dbuf[0] = *fmt; + dbuf[1] = 0; + sbuf_concat (buffer, dbuf); + } + } + sbuf_free (retbuf); +#undef STATE_READ +#undef STATE_ESCAPE +#undef STATE_NUMBER +} + +static void +fmt_framenum (rp_window_elem *win_elem, struct sbuf *buf) +{ + if (win_elem->win->frame_number != EMPTY) + { + sbuf_printf_concat (buf, "%d", win_elem->win->frame_number); + } + else + sbuf_copy (buf, " "); +} + +static void +fmt_lastaccess (rp_window_elem *win_elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%d", win_elem->win->last_access); +} + +static void +fmt_name (rp_window_elem *win_elem, struct sbuf *buf) +{ + sbuf_copy(buf, window_name (win_elem->win)); +} + +static void +fmt_number (rp_window_elem *win_elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%d", win_elem->number); +} + +static void +fmt_resname (rp_window_elem *win_elem, struct sbuf *buf) +{ + if (win_elem->win->res_name) + sbuf_copy (buf, win_elem->win->res_name); + else + sbuf_copy (buf, "None"); +} + +static void +fmt_resclass (rp_window_elem *win_elem, struct sbuf *buf) +{ + if (win_elem->win->res_class) + sbuf_copy (buf, win_elem->win->res_class); + else + sbuf_copy (buf, "None"); +} + +static void +fmt_status (rp_window_elem *win_elem, struct sbuf *buf) +{ + rp_window *other_window; + + other_window = find_window_other (current_screen()); + if (win_elem->win == other_window) + sbuf_copy (buf, "+"); + else if (win_elem->win == current_window()) + sbuf_copy (buf, "*"); + else + sbuf_copy (buf, "-"); +} + +static void +fmt_windowid (rp_window_elem *elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%ld", (unsigned long)elem->win->w); +} + +static void +fmt_height (rp_window_elem *elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%d", elem->win->height); +} + +static void +fmt_width (rp_window_elem *elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%d", elem->win->width); +} + +static void +fmt_incheight (rp_window_elem *elem, struct sbuf *buf) +{ + int height; + height = elem->win->height; + + if (elem->win->hints->flags & PResizeInc) + height /= elem->win->hints->height_inc; + + sbuf_printf_concat (buf, "%d", height); +} + +static void +fmt_incwidth (rp_window_elem *elem, struct sbuf *buf) +{ + int width; + width = elem->win->width; + + if (elem->win->hints->flags & PResizeInc) + width /= elem->win->hints->width_inc; + + sbuf_printf_concat (buf, "%d", width); +} + +static void +fmt_gravity (rp_window_elem *elem, struct sbuf *buf) +{ + sbuf_copy (buf, wingravity_to_string (elem->win->gravity)); +} + +static void +fmt_screen (rp_window_elem *elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%d", elem->win->scr->screen_num); +} + +static void +fmt_xinescreen (rp_window_elem *elem, struct sbuf *buf) +{ + sbuf_printf_concat (buf, "%d", elem->win->scr->xine_screen_num); +} + +static void +fmt_transient (rp_window_elem *elem, struct sbuf *buf) +{ + if (elem->win->transient) + sbuf_concat (buf, "Transient"); +} diff --git a/src/format.h b/src/format.h new file mode 100644 index 0000000..83b6acb --- /dev/null +++ b/src/format.h @@ -0,0 +1,27 @@ +/* Prototypes for format functions. + * Copyright (C) 2006 Antti Nykänen <aon@iki.fi> + * + * This file is part of ratpoison. + * + * ratpoison is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ratpoison is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + */ + +#ifndef _RATPOISON_FORMAT_H +#define _RATPOISON_FORMAT_H 1 + +void format_string(char *fmt, rp_window_elem *win_elem, struct sbuf *buffer); + +#endif /* _RATPOISON_FORMAT_H */ @@ -499,6 +499,7 @@ init_defaults () defaults.wait_for_key_cursor = 1; defaults.window_fmt = xstrdup ("%n%s%t"); + defaults.info_fmt = xstrdup ("(%H, %W) %n(%t)"); defaults.win_name = WIN_NAME_TITLE; defaults.startup_message = 1; diff --git a/src/ratpoison.h b/src/ratpoison.h index 448e021..ea8ec65 100644 --- a/src/ratpoison.h +++ b/src/ratpoison.h @@ -87,6 +87,7 @@ extern XGCValues gv; #include "completions.h" #include "hook.h" #include "xinerama.h" +#include "format.h" void clean_up (); rp_screen *find_screen (Window w); diff --git a/src/window.c b/src/window.c index ad926f4..3d021a4 100644 --- a/src/window.c +++ b/src/window.c @@ -705,151 +705,6 @@ print_window_information (rp_group *group, rp_window *win) window_name(win), group->number); } -/* format options - %n - Window number - %s - Window status (current window, last window, etc) - %t - Window Name - %a - application name - %c - resource class - %i - X11 Window ID - %l - last access number - %f - print the frame number the window is in - - */ -static int -isdigit (ch) -{ - return ch >= '0' && ch <= '9'; -} - -/* if width >= 0 then limit the width of s to width chars. */ -static void -concat_width (struct sbuf *buf, char *s, int width) -{ - if (width >= 0) - { - char *s1 = xsprintf ("%%.%ds", width); - char *s2 = xsprintf (s1, s); - sbuf_concat (buf, s2); - free (s1); - free (s2); - } - else - sbuf_concat (buf, s); -} - -static void -format_window_name (char *fmt, rp_window_elem *win_elem, rp_window *other_win, - struct sbuf *buffer) -{ -#define STATE_READ 0 -#define STATE_ESCAPE 1 -#define STATE_NUMBER 2 - int state = STATE_READ; - char dbuf[10]; - int width = -1; - - for(; *fmt; fmt++) - { - if (*fmt == '%' && state == STATE_READ) - { - state = STATE_ESCAPE; - continue; - } - - if ((state == STATE_ESCAPE || state == STATE_NUMBER) && isdigit(*fmt)) - { - /* Accumulate the width one digit at a time. */ - if (state == STATE_ESCAPE) - width = 0; - width *= 10; - width += *fmt - '0'; - state = STATE_NUMBER; - continue; - } - - if (state == STATE_ESCAPE || state == STATE_NUMBER) - { - switch (*fmt) - { - case 'n': - snprintf (dbuf, 10, "%d", win_elem->number); - sbuf_concat (buffer, dbuf); - break; - - case 's': - if (win_elem->win == current_window()) - sbuf_concat (buffer, "*"); - else if (win_elem->win == other_win) - sbuf_concat (buffer, "+"); - else - sbuf_concat (buffer, "-"); - break; - - case 't': - concat_width (buffer, window_name (win_elem->win), width); - break; - - case 'a': - if (win_elem->win->res_name) - concat_width (buffer, win_elem->win->res_name, width); - else - concat_width (buffer, "None", width); - break; - - case 'c': - if (win_elem->win->res_class) - concat_width (buffer, win_elem->win->res_class, width); - else - concat_width (buffer, "None", width); - break; - - case 'i': - snprintf (dbuf, 9, "%ld", (unsigned long)win_elem->win->w); - sbuf_concat (buffer, dbuf); - break; - - case 'l': - snprintf (dbuf, 9, "%d", win_elem->win->last_access); - sbuf_concat (buffer, dbuf); - break; - - case 'f': - if (win_elem->win->frame_number != EMPTY) - { - snprintf (dbuf, 9, "%d", win_elem->win->frame_number); - sbuf_concat (buffer, dbuf); - } - else - sbuf_concat (buffer, " "); - break; - - case '%': - sbuf_concat (buffer, "%"); - break; - - default: - sbuf_printf_concat (buffer, "%%%c", *fmt); - break; - } - - /* Reset the 'escape' state. */ - state = STATE_READ; - width = -1; - } - else - { - /* Insert the character. */ - dbuf[0] = *fmt; - dbuf[1] = 0; - sbuf_concat (buffer, dbuf); - } - } -#undef STATE_READ -#undef STATE_ESCAPE -#undef STATE_NUMBER -} - /* get the window list and store it in buffer delimiting each window with delim. mark_start and mark_end will be filled with the text positions for the start and end of the current window. */ @@ -878,7 +733,7 @@ get_window_list (char *fmt, char *delim, struct sbuf *buffer, if (!delim) sbuf_concat (buffer, " "); - format_window_name (fmt, we, other_window, buffer); + format_string (fmt, we, buffer); /* A hack, pad the window with a space at the beginning and end if there is no delimiter. */ |