2 * vim:ts=4:sw=4:expandtab
4 * i3 - an improved dynamic tiling window manager
5 * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
7 * cmdparse.l: the lexer for commands you send to i3 (or bind on keys)
12 %option noyy_top_state
18 #include "cmdparse.tab.h"
26 #define YY_DECL int yylex (struct context *context)
28 #define YY_USER_ACTION { \
29 context->first_column = cmdyycolumn; \
30 context->last_column = cmdyycolumn+yyleng-1; \
31 cmdyycolumn += yyleng; \
34 /* macro to first eat whitespace, then expect a string */
35 #define WS_STRING do { \
36 yy_push_state(WANT_STRING); \
37 yy_push_state(EAT_WHITESPACE); \
44 /* handle everything up to \n as a string */
46 /* eat a whitespace, then go to the next state on the stack */
48 /* handle a quoted string or everything up to the next whitespace */
61 /* This is called when a new line is lexed. We only want the
62 * first line to match to go into state BUFFER_LINE */
63 if (context->line_number == 0) {
64 context->line_number = 1;
66 yy_push_state(BUFFER_LINE);
70 <BUFFER_LINE>^[^\r\n]*/{EOL}? {
72 context->line_copy = sstrdup(yytext);
80 /* The next/prev/back_and_forth tokens are here to recognize them *before*
81 * handling strings ('workspace' command). While flex uses the longest
82 * match, in case of a tie the order of rules becomes relevant. Since the
83 * input is fully consumed (these are the last tokens), it comes to a tie.
85 next { BEGIN(INITIAL); return TOK_NEXT; }
86 prev { BEGIN(INITIAL); return TOK_PREV; }
87 next_on_output { BEGIN(INITIAL); return TOK_NEXT_ON_OUTPUT; }
88 prev_on_output { BEGIN(INITIAL); return TOK_PREV_ON_OUTPUT; }
89 back_and_forth { BEGIN(INITIAL); return TOK_BACK_AND_FORTH; }
91 /* MOVE is the state after a 'move' token was processed. We need this state
92 * to skip some tokens (for making the commands clearer) and to properly
93 * move to the MOVE_WS state. */
94 <MOVE>to { /* eat this token */ }
95 <MOVE>window { /* eat this token */ }
96 <MOVE>container { /* eat this token */ }
97 <MOVE>workspace { yy_pop_state(); yy_push_state(MOVE_WS); yy_push_state(EAT_WHITESPACE); return TOK_WORKSPACE; }
98 <MOVE>scratchpad { yy_pop_state(); return TOK_SCRATCHPAD; }
99 <MOVE>output { yy_pop_state(); return TOK_OUTPUT; }
100 <MOVE>up { yy_pop_state(); return TOK_UP; }
101 <MOVE>down { yy_pop_state(); return TOK_DOWN; }
102 <MOVE>left { yy_pop_state(); return TOK_LEFT; }
103 <MOVE>right { yy_pop_state(); return TOK_RIGHT; }
105 /* MOVE_WS is the state after a 'workspace' token was processed in the MOVE
106 * state. We need a separate state to deal with the fact that the old
107 * 'move workspace <ws>' command needs to be supported (the new command is
108 * 'move to workspace') while we also need to support
109 * 'move workspace to output <output>'. */
110 <MOVE_WS>to { yy_pop_state(); return TOK_TO; }
111 <MOVE_WS>[^t] { yy_pop_state(); yy_push_state(WANT_STRING); yyless(0); }
113 <WANT_STRING>\"[^\"]+\" {
116 char *copy = sstrdup(yytext+1);
117 copy[strlen(copy)-1] = '\0';
118 cmdyylval.string = copy;
121 <WANT_QSTRING>\"[^\"]+\" {
124 char *copy = sstrdup(yytext+1);
125 copy[strlen(copy)-1] = '\0';
126 cmdyylval.string = copy;
130 <WANT_STRING>[^;\n]+ { BEGIN(INITIAL); cmdyylval.string = sstrdup(yytext); return STR; }
132 <EAT_WHITESPACE>[;\n] { BEGIN(INITIAL); return ';'; }
133 <EAT_WHITESPACE>[ \t]* { yy_pop_state(); }
135 [ \t]* { /* ignore whitespace */ ; }
136 <EXEC>--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; }
137 <EXEC>. { printf("anything else: *%s*\n", yytext); yyless(0); yy_pop_state(); yy_pop_state(); }
138 exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOK_EXEC; }
139 exit { return TOK_EXIT; }
140 reload { return TOK_RELOAD; }
141 restart { return TOK_RESTART; }
142 kill { return TOK_KILL; }
143 window { return TOK_WINDOW; }
144 container { return TOK_CONTAINER; }
145 client { return TOK_CLIENT; }
146 fullscreen { return TOK_FULLSCREEN; }
147 global { return TOK_GLOBAL; }
148 layout { return TOK_LAYOUT; }
149 default { return TOK_DEFAULT; }
150 stacked { return TOK_STACKED; }
151 stacking { return TOK_STACKED; }
152 tabbed { return TOK_TABBED; }
153 border { return TOK_BORDER; }
154 normal { return TOK_NORMAL; }
155 none { return TOK_NONE; }
156 1pixel { return TOK_1PIXEL; }
157 mode { BEGIN(WANT_QSTRING); return TOK_MODE; }
158 tiling { return TOK_TILING; }
159 floating { return TOK_FLOATING; }
160 toggle { return TOK_TOGGLE; }
161 mode_toggle { return TOK_MODE_TOGGLE; }
162 workspace { WS_STRING; return TOK_WORKSPACE; }
163 output { WS_STRING; return TOK_OUTPUT; }
164 focus { return TOK_FOCUS; }
165 move { yy_push_state(MOVE); return TOK_MOVE; }
166 open { return TOK_OPEN; }
167 scratchpad { return TOK_SCRATCHPAD; }
168 show { return TOK_SHOW; }
169 split { return TOK_SPLIT; }
170 horizontal { return TOK_HORIZONTAL; }
171 vertical { return TOK_VERTICAL; }
172 up { return TOK_UP; }
173 down { return TOK_DOWN; }
174 left { return TOK_LEFT; }
175 right { return TOK_RIGHT; }
176 parent { return TOK_PARENT; }
177 child { return TOK_CHILD; }
178 resize { return TOK_RESIZE; }
179 shrink { return TOK_SHRINK; }
180 grow { return TOK_GROW; }
181 px { return TOK_PX; }
182 or { return TOK_OR; }
183 ppt { return TOK_PPT; }
184 to { return TOK_TO; }
185 nop { WS_STRING; return TOK_NOP; }
186 append_layout { WS_STRING; return TOK_APPEND_LAYOUT; }
187 mark { WS_STRING; return TOK_MARK; }
189 enable { return TOK_ENABLE; }
190 true { return TOK_ENABLE; }
191 yes { return TOK_ENABLE; }
192 disable { return TOK_DISABLE; }
193 false { return TOK_DISABLE; }
194 no { return TOK_DISABLE; }
196 class { BEGIN(WANT_QSTRING); return TOK_CLASS; }
197 instance { BEGIN(WANT_QSTRING); return TOK_INSTANCE; }
198 window_role { BEGIN(WANT_QSTRING); return TOK_WINDOW_ROLE; }
199 id { BEGIN(WANT_QSTRING); return TOK_ID; }
200 con_id { BEGIN(WANT_QSTRING); return TOK_CON_ID; }
201 con_mark { BEGIN(WANT_QSTRING); return TOK_MARK; }
202 title { BEGIN(WANT_QSTRING); return TOK_TITLE; }
204 [0-9]+ { cmdyylval.number = atoi(yytext); return NUMBER; }
206 . { return (int)yytext[0]; }
209 while (yy_start_stack_ptr > 0)