Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 20:53:29 +01:00
|
|
|
# vim:ts=2:sw=2:expandtab
|
|
|
|
#
|
|
|
|
# i3 - an improved dynamic tiling window manager
|
|
|
|
# © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
|
|
|
|
#
|
|
|
|
# parser-specs/commands.spec: Specification file for generate-command-parser.pl
|
|
|
|
# which will generate the appropriate header files for our C parser.
|
|
|
|
#
|
|
|
|
# Use :source highlighting.vim in vim to get syntax highlighting
|
|
|
|
# for this file.
|
|
|
|
|
|
|
|
state INITIAL:
|
|
|
|
# We have an end token here for all the commands which just call some
|
|
|
|
# function without using an explicit 'end' token.
|
|
|
|
end ->
|
|
|
|
'[' -> call cmd_criteria_init(); CRITERIA
|
|
|
|
'move' -> MOVE
|
|
|
|
'exec' -> EXEC
|
|
|
|
'exit' -> call cmd_exit()
|
|
|
|
'restart' -> call cmd_restart()
|
|
|
|
'reload' -> call cmd_reload()
|
|
|
|
'border' -> BORDER
|
|
|
|
'layout' -> LAYOUT
|
|
|
|
'append_layout' -> APPEND_LAYOUT
|
|
|
|
'workspace' -> WORKSPACE
|
|
|
|
'focus' -> FOCUS
|
|
|
|
'kill' -> KILL
|
|
|
|
'open' -> call cmd_open()
|
|
|
|
'fullscreen' -> FULLSCREEN
|
|
|
|
'split' -> SPLIT
|
|
|
|
'floating' -> FLOATING
|
|
|
|
'mark' -> MARK
|
|
|
|
'resize' -> RESIZE
|
|
|
|
'nop' -> NOP
|
|
|
|
'scratchpad' -> SCRATCHPAD
|
|
|
|
'mode' -> MODE
|
|
|
|
|
|
|
|
state CRITERIA:
|
|
|
|
ctype = 'class' -> CRITERION
|
|
|
|
ctype = 'instance' -> CRITERION
|
|
|
|
ctype = 'window_role' -> CRITERION
|
|
|
|
ctype = 'con_id' -> CRITERION
|
|
|
|
ctype = 'id' -> CRITERION
|
|
|
|
ctype = 'con_mark' -> CRITERION
|
|
|
|
ctype = 'title' -> CRITERION
|
|
|
|
']' -> call cmd_criteria_match_windows(); INITIAL
|
|
|
|
|
|
|
|
state CRITERION:
|
|
|
|
'=' -> CRITERION_STR
|
|
|
|
|
|
|
|
state CRITERION_STR:
|
|
|
|
cvalue = word
|
|
|
|
-> call cmd_criteria_add($ctype, $cvalue); CRITERIA
|
|
|
|
|
|
|
|
# exec [--no-startup-id] <command>
|
|
|
|
state EXEC:
|
|
|
|
nosn = '--no-startup-id'
|
|
|
|
->
|
|
|
|
command = string
|
|
|
|
-> call cmd_exec($nosn, $command)
|
|
|
|
|
2012-01-27 23:32:40 +01:00
|
|
|
# border normal|none|1pixel|toggle
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 20:53:29 +01:00
|
|
|
state BORDER:
|
|
|
|
border_style = 'normal', 'none', '1pixel', 'toggle'
|
|
|
|
-> call cmd_border($border_style)
|
|
|
|
|
2012-01-27 23:32:40 +01:00
|
|
|
# layout default|stacked|stacking|tabbed
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 20:53:29 +01:00
|
|
|
state LAYOUT:
|
|
|
|
layout_mode = 'default', 'stacked', 'stacking', 'tabbed'
|
|
|
|
-> call cmd_layout($layout_mode)
|
|
|
|
|
|
|
|
# append_layout <path>
|
|
|
|
state APPEND_LAYOUT:
|
|
|
|
path = string -> call cmd_append_layout($path)
|
|
|
|
|
|
|
|
# workspace next|prev|next_on_output|prev_on_output
|
|
|
|
# workspace back_and_forth
|
|
|
|
# workspace <name>
|
|
|
|
state WORKSPACE:
|
|
|
|
direction = 'next_on_output', 'prev_on_output', 'next', 'prev'
|
|
|
|
-> call cmd_workspace($direction)
|
|
|
|
'back_and_forth'
|
|
|
|
-> call cmd_workspace_back_and_forth()
|
|
|
|
workspace = string
|
|
|
|
-> call cmd_workspace_name($workspace)
|
|
|
|
|
|
|
|
# focus left|right|up|down
|
|
|
|
# focus output <output>
|
|
|
|
# focus tiling|floating|mode_toggle
|
|
|
|
# focus parent|child
|
|
|
|
# focus
|
|
|
|
state FOCUS:
|
|
|
|
direction = 'left', 'right', 'up', 'down'
|
|
|
|
-> call cmd_focus_direction($direction)
|
|
|
|
'output'
|
|
|
|
-> FOCUS_OUTPUT
|
|
|
|
window_mode = 'tiling', 'floating', 'mode_toggle'
|
|
|
|
-> call cmd_focus_window_mode($window_mode)
|
|
|
|
level = 'parent', 'child'
|
|
|
|
-> call cmd_focus_level($level)
|
|
|
|
end
|
|
|
|
-> call cmd_focus()
|
|
|
|
|
|
|
|
state FOCUS_OUTPUT:
|
|
|
|
output = string
|
|
|
|
-> call cmd_focus_output($output)
|
|
|
|
|
2012-01-27 23:32:40 +01:00
|
|
|
# kill [window|client]
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 20:53:29 +01:00
|
|
|
state KILL:
|
|
|
|
kill_mode = 'window', 'client'
|
|
|
|
-> call cmd_kill($kill_mode)
|
|
|
|
end
|
|
|
|
-> call cmd_kill($kill_mode)
|
|
|
|
|
2012-01-27 23:32:40 +01:00
|
|
|
# fullscreen [global]
|
Implement a new parser for commands. (+test)
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
2012-01-14 20:53:29 +01:00
|
|
|
state FULLSCREEN:
|
|
|
|
fullscreen_mode = 'global'
|
|
|
|
-> call cmd_fullscreen($fullscreen_mode)
|
|
|
|
end
|
|
|
|
-> call cmd_fullscreen($fullscreen_mode)
|
|
|
|
|
|
|
|
# split v|h|vertical|horizontal
|
|
|
|
state SPLIT:
|
|
|
|
direction = 'v', 'h', 'vertical', 'horizontal'
|
|
|
|
-> call cmd_split($direction)
|
|
|
|
|
|
|
|
# floating enable|disable|toggle
|
|
|
|
state FLOATING:
|
|
|
|
floating = 'enable', 'disable', 'toggle'
|
|
|
|
-> call cmd_floating($floating)
|
|
|
|
|
|
|
|
# mark <mark>
|
|
|
|
state MARK:
|
|
|
|
mark = string
|
|
|
|
-> call cmd_mark($mark)
|
|
|
|
|
|
|
|
# resize
|
|
|
|
state RESIZE:
|
|
|
|
way = 'grow', 'shrink'
|
|
|
|
-> RESIZE_DIRECTION
|
|
|
|
|
|
|
|
state RESIZE_DIRECTION:
|
|
|
|
direction = 'up', 'down', 'left', 'right'
|
|
|
|
-> RESIZE_PX
|
|
|
|
|
|
|
|
state RESIZE_PX:
|
|
|
|
resize_px = word
|
|
|
|
-> RESIZE_TILING
|
|
|
|
end
|
|
|
|
-> call cmd_resize($way, $direction, "10", "10")
|
|
|
|
|
|
|
|
state RESIZE_TILING:
|
|
|
|
'px'
|
|
|
|
->
|
|
|
|
'or'
|
|
|
|
-> RESIZE_TILING_OR
|
|
|
|
end
|
|
|
|
-> call cmd_resize($way, $direction, $resize_px, "10")
|
|
|
|
|
|
|
|
state RESIZE_TILING_OR:
|
|
|
|
'ppt'
|
|
|
|
->
|
|
|
|
resize_ppt = word
|
|
|
|
->
|
|
|
|
end
|
|
|
|
-> call cmd_resize($way, $direction, $resize_px, $resize_ppt)
|
|
|
|
|
|
|
|
# move <direction> [<pixels> [px]]
|
|
|
|
# move [window|container] [to] workspace <str>
|
|
|
|
# move [window|container] [to] output <str>
|
|
|
|
# move [window|container] [to] scratchpad
|
|
|
|
# move workspace to [output] <str>
|
|
|
|
# move scratchpad
|
|
|
|
state MOVE:
|
|
|
|
'window'
|
|
|
|
->
|
|
|
|
'container'
|
|
|
|
->
|
|
|
|
'to'
|
|
|
|
->
|
|
|
|
'workspace'
|
|
|
|
-> MOVE_WORKSPACE
|
|
|
|
'output'
|
|
|
|
-> MOVE_TO_OUTPUT
|
|
|
|
'scratchpad'
|
|
|
|
-> call cmd_move_scratchpad()
|
|
|
|
direction = 'left', 'right', 'up', 'down'
|
|
|
|
-> MOVE_DIRECTION
|
|
|
|
|
|
|
|
state MOVE_DIRECTION:
|
|
|
|
pixels = word
|
|
|
|
-> MOVE_DIRECTION_PX
|
|
|
|
end
|
|
|
|
-> call cmd_move_direction($direction, "10")
|
|
|
|
|
|
|
|
state MOVE_DIRECTION_PX:
|
|
|
|
'px'
|
|
|
|
-> call cmd_move_direction($direction, $pixels)
|
|
|
|
end
|
|
|
|
-> call cmd_move_direction($direction, $pixels)
|
|
|
|
|
|
|
|
state MOVE_WORKSPACE:
|
|
|
|
'to'
|
|
|
|
-> MOVE_WORKSPACE_TO_OUTPUT
|
|
|
|
workspace = 'next', 'prev', 'next_on_output', 'prev_on_output'
|
|
|
|
-> call cmd_move_con_to_workspace($workspace)
|
|
|
|
workspace = string
|
|
|
|
-> call cmd_move_con_to_workspace_name($workspace)
|
|
|
|
|
|
|
|
state MOVE_TO_OUTPUT:
|
|
|
|
output = string
|
|
|
|
-> call cmd_move_con_to_output($output)
|
|
|
|
|
|
|
|
state MOVE_WORKSPACE_TO_OUTPUT:
|
|
|
|
'output'
|
|
|
|
->
|
|
|
|
output = string
|
|
|
|
-> call cmd_move_workspace_to_output($output)
|
|
|
|
|
|
|
|
# mode <string>
|
|
|
|
state MODE:
|
|
|
|
mode = string
|
|
|
|
-> call cmd_mode($mode)
|
|
|
|
|
|
|
|
state NOP:
|
|
|
|
comment = string
|
|
|
|
-> call cmd_nop($comment)
|
|
|
|
|
|
|
|
state SCRATCHPAD:
|
|
|
|
'show'
|
|
|
|
-> call cmd_scratchpad_show()
|