hacking-howto: describe the new commands parser
This commit is contained in:
parent
a59090ac2e
commit
fa4a909f34
|
@ -672,41 +672,122 @@ floating windows:
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
== User commands / commandmode (src/cmdparse.{l,y})
|
== User commands (parser-specs/commands.spec)
|
||||||
|
|
||||||
*********************************************************************************
|
In the configuration file and when using i3 interactively (with +i3-msg+, for
|
||||||
This section has not been updated for v4.0 yet, sorry! We wanted to release on
|
example), you use commands to make i3 do things, like focus a different window,
|
||||||
time, but we will update this soon. Please talk to us on IRC if you need to
|
set a window to fullscreen, and so on. An example command is +floating enable+,
|
||||||
know stuff *NOW* :).
|
which enables floating mode for the currently focused window. See the
|
||||||
*********************************************************************************
|
appropriate section in the link:userguide.html[User’s Guide] for a reference of
|
||||||
|
all commands.
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
In earlier versions of i3, interpreting these commands was done using lex and
|
||||||
|
yacc, but experience has shown that lex and yacc are not well suited for our
|
||||||
|
command language. Therefore, starting from version 4.2, we use a custom parser.
|
||||||
|
The input specification for this parser can be found in the file
|
||||||
|
+parser-specs/commands.spec+. Should you happen to use Vim as an editor, use
|
||||||
|
:source parser-specs/highlighting.vim to get syntax highlighting for this file
|
||||||
|
(highlighting files for other editors are welcome).
|
||||||
|
|
||||||
|
.Excerpt from commands.spec
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
state INITIAL:
|
||||||
|
'[' -> call cmd_criteria_init(); CRITERIA
|
||||||
|
'move' -> MOVE
|
||||||
|
'exec' -> EXEC
|
||||||
|
'workspace' -> WORKSPACE
|
||||||
|
'exit' -> call cmd_exit()
|
||||||
|
'restart' -> call cmd_restart()
|
||||||
|
'reload' -> call cmd_reload()
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
Like in vim, you can control i3 using commands. They are intended to be a
|
The input specification is written in an extremely simple format. The
|
||||||
powerful alternative to lots of shortcuts, because they can be combined. There
|
specification is then converted into C code by the Perl script
|
||||||
are a few special commands, which are the following:
|
generate-commands-parser.pl (the output file names begin with GENERATED and the
|
||||||
|
files are stored in the +include+ directory). The parser implementation
|
||||||
|
+src/commands_parser.c+ includes the generated C code at compile-time.
|
||||||
|
|
||||||
exec <command>::
|
The above excerpt from commands.spec illustrates nearly all features of our
|
||||||
Starts the given command by passing it to `/bin/sh`.
|
specification format: You describe different states and what can happen within
|
||||||
|
each state. State names are all-caps; the state in the above excerpt is called
|
||||||
|
INITIAL. A list of tokens and their actions (separated by an ASCII arrow)
|
||||||
|
follows. In the excerpt, all tokens are literals, that is, simple text strings
|
||||||
|
which will be compared with the input. An action is either the name of a state
|
||||||
|
in which the parser will transition into, or the keyword 'call', followed by
|
||||||
|
the name of a function (and optionally a state).
|
||||||
|
|
||||||
restart::
|
=== Example: The WORKSPACE state
|
||||||
Restarts i3 by executing `argv[0]` (the path with which you started i3) without
|
|
||||||
forking.
|
|
||||||
|
|
||||||
w::
|
Let’s have a look at the WORKSPACE state, which is a good example of all
|
||||||
"With". This is used to select a bunch of windows. Currently, only selecting
|
features. This is its definition:
|
||||||
the whole container in which the window is in, is supported by specifying "w".
|
|
||||||
|
|
||||||
f, s, d::
|
.WORKSPACE state (commands.spec)
|
||||||
Toggle fullscreen, stacking, default mode for the current window/container.
|
----------------------------------------------------------------
|
||||||
|
# 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)
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
The other commands are to be combined with a direction. The directions are h,
|
As you can see from the commands, there are multiple different valid variants
|
||||||
j, k and l, like in vim (h = left, j = down, k = up, l = right). When you just
|
of the workspace command:
|
||||||
specify the direction keys, i3 will move the focus in that direction. You can
|
|
||||||
provide "m" or "s" before the direction to move a window respectively or snap.
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
workspace <direction>::
|
||||||
|
The word 'workspace' can be followed by any of the tokens 'next',
|
||||||
|
'prev', 'next_on_output' or 'prev_on_output'. This command will
|
||||||
|
switch to the next or previous workspace (optionally on the same
|
||||||
|
output). +
|
||||||
|
There is one function called +cmd_workspace+, which is defined
|
||||||
|
in +src/commands.c+. It will handle this kind of command. To know which
|
||||||
|
direction was specified, the direction token is stored on the stack
|
||||||
|
with the name "direction", which is what the "direction = " means in
|
||||||
|
the beginning. +
|
||||||
|
|
||||||
|
NOTE: Note that you can specify multiple literals in the same line. This has
|
||||||
|
exactly the same effect as if you specified `direction =
|
||||||
|
'next_on_output' -> call cmd_workspace($direction)` and so forth. +
|
||||||
|
|
||||||
|
NOTE: Also note that the order of literals is important here: If 'next' were
|
||||||
|
ordered before 'next_on_output', then 'next_on_output' would never
|
||||||
|
match.
|
||||||
|
|
||||||
|
workspace back_and_forth::
|
||||||
|
This is a very simple case: When the literal 'back_and_forth' is found
|
||||||
|
in the input, the function +cmd_workspace_back_and_forth+ will be
|
||||||
|
called without parameters and the parser will return to the INITIAL
|
||||||
|
state (since no other state was specified).
|
||||||
|
workspace <name>::
|
||||||
|
In this case, the workspace command is followed by an arbitrary string,
|
||||||
|
possibly in quotes, for example "workspace 3" or "workspace bleh". +
|
||||||
|
This is the first time that the token is actually not a literal (not in
|
||||||
|
single quotes), but just called string. Other possible tokens are word
|
||||||
|
(the same as string, but stops matching at a whitespace) and end
|
||||||
|
(matches the end of the input).
|
||||||
|
|
||||||
|
=== Introducing a new command
|
||||||
|
|
||||||
|
The following steps have to be taken in order to properly introduce a new
|
||||||
|
command (or possibly extend an existing command):
|
||||||
|
|
||||||
|
1. Define a function beginning with +cmd_+ in the file +src/commands.c+. Copy
|
||||||
|
the prototype of an existing function.
|
||||||
|
2. After adding a comment on what the function does, copy the comment and
|
||||||
|
function definition to +include/commands.h+. Make the comment in the header
|
||||||
|
file use double asterisks to make doxygen pick it up.
|
||||||
|
3. Write a test case (or extend an existing test case) for your feature, see
|
||||||
|
link:testsuite.html[i3 testsuite]. For now, it is sufficient to simply call
|
||||||
|
your command in all the various possible ways.
|
||||||
|
4. Extend the parser specification in +parser-specs/commands.spec+. Run the
|
||||||
|
testsuite and see if your new function gets called with the appropriate
|
||||||
|
arguments for the appropriate input.
|
||||||
|
5. Actually implement the feature.
|
||||||
|
6. Document the feature in the link:userguide.html[User’s Guide].
|
||||||
|
|
||||||
== Moving containers
|
== Moving containers
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue