Parse multiple criteria in commands (+test), better error message for 'focus'

This commit is contained in:
Michael Stapelberg 2011-06-08 23:34:08 +02:00
parent d68e4710fe
commit 9aa7e5fbd6
3 changed files with 33 additions and 6 deletions

View File

@ -143,6 +143,7 @@ class { BEGIN(WANT_QSTRING); return TOK_CLASS; }
id { BEGIN(WANT_QSTRING); return TOK_ID; } id { BEGIN(WANT_QSTRING); return TOK_ID; }
con_id { BEGIN(WANT_QSTRING); return TOK_CON_ID; } con_id { BEGIN(WANT_QSTRING); return TOK_CON_ID; }
con_mark { BEGIN(WANT_QSTRING); return TOK_MARK; } con_mark { BEGIN(WANT_QSTRING); return TOK_MARK; }
title { BEGIN(WANT_QSTRING); return TOK_TITLE; }
[0-9]+ { cmdyylval.number = atoi(yytext); return NUMBER; } [0-9]+ { cmdyylval.number = atoi(yytext); return NUMBER; }

View File

@ -162,6 +162,7 @@ char *parse_cmd(const char *new) {
%token TOK_CLASS "class" %token TOK_CLASS "class"
%token TOK_ID "id" %token TOK_ID "id"
%token TOK_CON_ID "con_id" %token TOK_CON_ID "con_id"
%token TOK_TITLE "title"
%token <string> STR "<string>" %token <string> STR "<string>"
%token <number> NUMBER "<number>" %token <number> NUMBER "<number>"
@ -271,6 +272,11 @@ matchend:
; ;
criteria: criteria:
criteria criterion
| criterion
;
criterion:
TOK_CLASS '=' STR TOK_CLASS '=' STR
{ {
printf("criteria: class = %s\n", $3); printf("criteria: class = %s\n", $3);
@ -311,6 +317,11 @@ criteria:
printf("criteria: mark = %s\n", $3); printf("criteria: mark = %s\n", $3);
current_match.mark = $3; current_match.mark = $3;
} }
| TOK_TITLE '=' STR
{
printf("criteria: title = %s\n", $3);
current_match.title = $3;
}
; ;
operations: operations:
@ -381,20 +392,26 @@ focus:
{ {
owindow *current; owindow *current;
printf("should focus\n");
if (match_is_empty(&current_match)) { if (match_is_empty(&current_match)) {
/* TODO: better error message */ ELOG("You have to specify which window/container should be focused.\n");
LOG("Error: The focus command requires you to use some criteria.\n"); ELOG("Example: [class=\"urxvt\" title=\"irssi\"] focus\n");
asprintf(&json_output, "{\"success\":false, \"error\":\"You have to "
"specify which window/container should be focused\"}");
break; break;
} }
/* TODO: warning if the match contains more than one entry. does not int count = 0;
* make so much sense when focusing */
TAILQ_FOREACH(current, &owindows, owindows) { TAILQ_FOREACH(current, &owindows, owindows) {
LOG("focusing %p / %s\n", current->con, current->con->name); LOG("focusing %p / %s\n", current->con, current->con->name);
con_focus(current->con); con_focus(current->con);
count++;
} }
if (count > 1)
LOG("WARNING: Your criteria for the focus command matches %d containers, "
"while only exactly one container can be focused at a time.\n", count);
tree_render(); tree_render();
} }
| TOK_FOCUS direction | TOK_FOCUS direction

View File

@ -1,7 +1,7 @@
#!perl #!perl
# vim:ts=4:sw=4:expandtab # vim:ts=4:sw=4:expandtab
use i3test tests => 6; use i3test;
use X11::XCB qw(:all); use X11::XCB qw(:all);
use Digest::SHA1 qw(sha1_base64); use Digest::SHA1 qw(sha1_base64);
@ -65,4 +65,13 @@ is($focus, $top->id, "Top window focused");
$focus = focus_after(qq|[con_mark="$random_mark"] focus|); $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
is($focus, $mid->id, "goto worked"); is($focus, $mid->id, "goto worked");
# check that we can specify multiple criteria
$focus = focus_after('focus left');
is($focus, $top->id, "Top window focused");
$focus = focus_after(qq|[con_mark="$random_mark" con_mark="$random_mark"] focus|);
is($focus, $mid->id, "goto worked");
done_testing; done_testing;