aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/_summary.md3
-rw-r--r--docs/cli.md114
-rw-r--r--docs/cli_configuration.md121
-rw-r--r--docs/cli_development.md175
-rw-r--r--docs/python_development.md45
-rw-r--r--docs/redirects.json4
6 files changed, 408 insertions, 54 deletions
diff --git a/docs/_summary.md b/docs/_summary.md
index 4e87d8f1f..233b2cdaa 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -9,6 +9,7 @@
9* [QMK Basics](README.md) 9* [QMK Basics](README.md)
10 * [QMK Introduction](getting_started_introduction.md) 10 * [QMK Introduction](getting_started_introduction.md)
11 * [QMK CLI](cli.md) 11 * [QMK CLI](cli.md)
12 * [QMK CLI Config](cli_configuration.md)
12 * [Contributing to QMK](contributing.md) 13 * [Contributing to QMK](contributing.md)
13 * [How to Use Github](getting_started_github.md) 14 * [How to Use Github](getting_started_github.md)
14 * [Getting Help](getting_started_getting_help.md) 15 * [Getting Help](getting_started_getting_help.md)
@@ -48,7 +49,7 @@
48 * [Useful Functions](ref_functions.md) 49 * [Useful Functions](ref_functions.md)
49 * [Configurator Support](reference_configurator_support.md) 50 * [Configurator Support](reference_configurator_support.md)
50 * [info.json Format](reference_info_json.md) 51 * [info.json Format](reference_info_json.md)
51 * [Python Development](python_development.md) 52 * [Python CLI Development](cli_development.md)
52 53
53* [Features](features.md) 54* [Features](features.md)
54 * [Basic Keycodes](keycodes_basic.md) 55 * [Basic Keycodes](keycodes_basic.md)
diff --git a/docs/cli.md b/docs/cli.md
index 4b8472b19..cb609e2a9 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -4,22 +4,70 @@ This page describes how to setup and use the QMK CLI.
4 4
5# Overview 5# Overview
6 6
7The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to help you work with QMK: 7The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
8 8
9* `qmk compile` 9* [Global CLI](#global-cli)
10* `qmk doctor` 10* [Local CLI](#local-cli)
11* [CLI Commands](#cli-commands)
11 12
12# Setup 13# Requirements
13 14
14Simply add the `qmk_firmware/bin` directory to your `PATH`. You can run the `qmk` commands from any directory. 15The CLI requires Python 3.5 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt).
16
17# Global CLI
18
19QMK provides an installable CLI that can be used to setup your QMK build environment, work with QMK, and which makes working with multiple copies of `qmk_firmware` easier. We recommend installing and updating this periodically.
20
21## Install Using Homebrew (macOS, some Linux)
22
23If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
24
25```
26brew tap qmk/qmk
27brew install qmk
28export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
29qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
30```
31
32## Install Using easy_install or pip
33
34If your system is not listed above you can install QMK manually. First ensure that you have python 3.5 (or later) installed and have installed pip. Then install QMK with this command:
35
36```
37pip3 install qmk
38export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
39qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
40```
41
42## Packaging For Other Operating Systems
43
44We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:
45
46* Follow best practices for your OS when they conflict with these guidelines
47 * Documment why in a comment when you do deviate
48* Install using a virtualenv
49* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`.
50
51# Local CLI
52
53If you do not want to use the global CLI there is a local CLI bundled with `qmk_firmware`. You can find it in `qmk_firmware/bin/qmk`. You can run the `qmk` command from any directory and it will always operate on that copy of `qmk_firmware`.
54
55**Example**:
15 56
16``` 57```
17export PATH=$PATH:$HOME/qmk_firmware/bin 58$ ~/qmk_firmware/bin/qmk hello
59Ψ Hello, World!
18``` 60```
19 61
20You may want to add this to your `.profile`, `.bash_profile`, `.zsh_profile`, or other shell startup scripts. 62## Local CLI Limitations
21 63
22# Commands 64There are some limitations to the local CLI compared to the global CLI:
65
66* The local CLI does not support `qmk setup` or `qmk clone`
67* The local CLI always operates on the same `qmk_firmware` tree, even if you have multiple repositories cloned.
68* The local CLI does not run in a virtualenv, so it's possible that dependencies will conflict
69
70# CLI Commands
23 71
24## `qmk compile` 72## `qmk compile`
25 73
@@ -46,3 +94,53 @@ This command formats C code using clang-format. Run it with no arguments to form
46``` 94```
47qmk cformat [file1] [file2] [...] [fileN] 95qmk cformat [file1] [file2] [...] [fileN]
48``` 96```
97
98## `qmk config`
99
100This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
101
102**Usage**:
103
104```
105qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
106```
107
108## `qmk doctor`
109
110This command examines your environment and alerts you to potential build or flash problems.
111
112**Usage**:
113
114```
115qmk doctor
116```
117
118## `qmk new-keymap`
119
120This command creates a new keymap based on a keyboard's existing default keymap.
121
122**Usage**:
123
124```
125qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
126```
127
128## `qmk pyformat`
129
130This command formats python code in `qmk_firmware`.
131
132**Usage**:
133
134```
135qmk pyformat
136```
137
138## `qmk pytest`
139
140This command runs the python test suite. If you make changes to python code you should ensure this runs successfully.
141
142**Usage**:
143
144```
145qmk pytest
146```
diff --git a/docs/cli_configuration.md b/docs/cli_configuration.md
new file mode 100644
index 000000000..ad9ff291c
--- /dev/null
+++ b/docs/cli_configuration.md
@@ -0,0 +1,121 @@
1# QMK CLI Configuration
2
3This document explains how `qmk config` works.
4
5# Introduction
6
7Configuration for QMK CLI is a key/value system. Each key consists of a subcommand and an argument name separated by a period. This allows for a straightforward and direct translation between config keys and the arguments they set.
8
9## Simple Example
10
11As an example let's look at the command `qmk compile --keyboard clueboard/66/rev4 --keymap default`.
12
13There are two command line arguments that could be read from configuration instead:
14
15* `compile.keyboard`
16* `compile.keymap`
17
18Let's set these now:
19
20```
21$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default
22compile.keyboard: None -> clueboard/66/rev4
23compile.keymap: None -> default
24Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
25```
26
27Now I can run `qmk compile` without specifying my keyboard and keymap each time.
28
29## Setting User Defaults
30
31Sometimes you want to share a setting between multiple commands. For example, multiple commands take the argument `--keyboard`. Rather than setting this value for every command you can set a user value which will be used by any command that takes that argument.
32
33Example:
34
35```
36$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default
37user.keyboard: None -> clueboard/66/rev4
38user.keymap: None -> default
39Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
40```
41
42# CLI Documentation (`qmk config`)
43
44The `qmk config` command is used to interact with the underlying configuration. When run with no argument it shows the current configuration. When arguments are supplied they are assumed to be configuration tokens, which are strings containing no spaces with the following form:
45
46 <subcommand|general|default>[.<key>][=<value>]
47
48## Setting Configuration Values
49
50You can set configuration values by putting an equal sign (=) into your config key. The key must always be the full `<section>.<key>` form.
51
52Example:
53
54```
55$ qmk config default.keymap=default
56default.keymap: None -> default
57Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
58```
59
60## Reading Configuration Values
61
62You can read configuration values for the entire configuration, a single key, or for an entire section. You can also specify multiple keys to display more than one value.
63
64### Entire Configuration Example
65
66 qmk config
67
68### Whole Section Example
69
70 qmk config compile
71
72### Single Key Example
73
74 qmk config compile.keyboard
75
76### Multiple Keys Example
77
78 qmk config user compile.keyboard compile.keymap
79
80## Deleting Configuration Values
81
82You can delete a configuration value by setting it to the special string `None`.
83
84Example:
85
86```
87$ qmk config default.keymap=None
88default.keymap: default -> None
89Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
90```
91
92## Multiple Operations
93
94You can combine multiple read and write operations into a single command. They will be executed and displayed in order:
95
96```
97$ qmk config compile default.keymap=default compile.keymap=None
98compile.keymap=skully
99compile.keyboard=clueboard/66_hotswap/gen1
100default.keymap: None -> default
101compile.keymap: skully -> None
102Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini'
103```
104
105# User Configuration Options
106
107| Key | Default Value | Description |
108|-----|---------------|-------------|
109| user.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) |
110| user.keymap | None | The keymap name (Example: `default`) |
111| user.name | None | The user's github username. |
112
113# All Configuration Options
114
115| Key | Default Value | Description |
116|-----|---------------|-------------|
117| compile.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) |
118| compile.keymap | None | The keymap name (Example: `default`) |
119| hello.name | None | The name to greet when run. |
120| new_keyboard.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) |
121| new_keyboard.keymap | None | The keymap name (Example: `default`) |
diff --git a/docs/cli_development.md b/docs/cli_development.md
new file mode 100644
index 000000000..f5c7ad139
--- /dev/null
+++ b/docs/cli_development.md
@@ -0,0 +1,175 @@
1# QMK CLI Development
2
3This document has useful information for developers wishing to write new `qmk` subcommands.
4
5# Overview
6
7The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None.
8
9# Subcommands
10
11[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code.
12
13Subcommands in the local CLI are always found in `qmk_firmware/lib/python/qmk/cli`.
14
15Let's start by looking at an example subcommand. This is `lib/python/qmk/cli/hello.py`:
16
17```python
18"""QMK Python Hello World
19
20This is an example QMK CLI script.
21"""
22from milc import cli
23
24
25@cli.argument('-n', '--name', default='World', help='Name to greet.')
26@cli.subcommand('QMK Hello World.')
27def hello(cli):
28 """Log a friendly greeting.
29 """
30 cli.log.info('Hello, %s!', cli.config.hello.name)
31```
32
33First we import the `cli` object from `milc`. This is how we interact with the user and control the script's behavior. We use `@cli.argument()` to define a command line flag, `--name`. This also creates a configuration variable named `hello.name` (and the corresponding `user.name`) which the user can set so they don't have to specify the argument. The `cli.subcommand()` decorator designates this function as a subcommand. The name of the subcommand will be taken from the name of the function.
34
35Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.5/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator.
36
37# User Interaction
38
39MILC and the QMK CLI have several nice tools for interacting with the user. Using these standard tools will allow you to colorize your text for easier interactions, and allow the user to control when and how that information is displayed and stored.
40
41## Printing Text
42
43There are two main methods for outputting text in a subcommand- `cli.log` and `cli.echo()`. They operate in similar ways but you should prefer to use `cli.log.info()` for most general purpose printing.
44
45You can use special tokens to colorize your text, to make it easier to understand the output of your program. See [Colorizing Text](#colorizing-text) below.
46
47Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.5/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example.
48
49You should never use the format operator (`%`) directly, always pass values as arguments.
50
51### Logging (`cli.log`)
52
53The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.5/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong.
54
55The default log level is `INFO`. If the user runs `qmk -v <subcommand>` the default log level will be set to `DEBUG`.
56
57| Function | Emoji |
58|----------|-------|
59| cli.log.critical | `{bg_red}{fg_white}¬_¬{style_reset_all}` |
60| cli.log.error | `{fg_red}☒{style_reset_all}` |
61| cli.log.warning | `{fg_yellow}⚠{style_reset_all}` |
62| cli.log.info | `{fg_blue}Ψ{style_reset_all}` |
63| cli.log.debug | `{fg_cyan}☐{style_reset_all}` |
64| cli.log.notset | `{style_reset_all}¯\\_(o_o)_/¯` |
65
66### Printing (`cli.echo`)
67
68Sometimes you simply need to print text outside of the log system. This is appropriate if you are outputting fixed data or writing out something that should never be logged. Most of the time you should prefer `cli.log.info()` over `cli.echo`.
69
70### Colorizing Text
71
72You can colorize the output of your text by including color tokens within text. Use color to highlight, not to convey information. Remember that the user can disable color, and your subcommand should still be usable if they do.
73
74You should generally avoid setting the background color, unless it's integral to what you are doing. Remember that users have a lot of preferences when it comes to their terminal color, so you should pick colors that work well against both black and white backgrounds.
75
76Colors prefixed with 'fg' will affect the foreground (text) color. Colors prefixed with 'bg' will affect the background color.
77
78| Color | Background | Extended Background | Foreground | Extended Foreground|
79|-------|------------|---------------------|------------|--------------------|
80| Black | {bg_black} | {bg_lightblack_ex} | {fg_black} | {fg_lightblack_ex} |
81| Blue | {bg_blue} | {bg_lightblue_ex} | {fg_blue} | {fg_lightblue_ex} |
82| Cyan | {bg_cyan} | {bg_lightcyan_ex} | {fg_cyan} | {fg_lightcyan_ex} |
83| Green | {bg_green} | {bg_lightgreen_ex} | {fg_green} | {fg_lightgreen_ex} |
84| Magenta | {bg_magenta} | {bg_lightmagenta_ex} | {fg_magenta} | {fg_lightmagenta_ex} |
85| Red | {bg_red} | {bg_lightred_ex} | {fg_red} | {fg_lightred_ex} |
86| White | {bg_white} | {bg_lightwhite_ex} | {fg_white} | {fg_lightwhite_ex} |
87| Yellow | {bg_yellow} | {bg_lightyellow_ex} | {fg_yellow} | {fg_lightyellow_ex} |
88
89There are also control sequences that can be used to change the behavior of
90ANSI output:
91
92| Control Sequences | Description |
93|-------------------|-------------|
94| {style_bright} | Make the text brighter |
95| {style_dim} | Make the text dimmer |
96| {style_normal} | Make the text normal (neither `{style_bright}` nor `{style_dim}`) |
97| {style_reset_all} | Reset all text attributes to default. (This is automatically added to the end of every string.) |
98| {bg_reset} | Reset the background color to the user's default |
99| {fg_reset} | Reset the foreground color to the user's default |
100
101# Arguments and Configuration
102
103QMK handles the details of argument parsing and configuration for you. When you add a new argument it is automatically incorporated into the config tree based on your subcommand's name and the long name of the argument. You can access this configuration in `cli.config`, using either attribute-style access (`cli.config.<subcommand>.<argument>`) or dictionary-style access (`cli.config['<subcommand>']['<argument>']`).
104
105Under the hood QMK uses [ConfigParser](https://docs.python.org/3/library/configparser.html) to store configurations. This gives us an easy and straightforward way to represent the configuration in a human-editable way. We have wrapped access to this configuration to provide some nicities that ConfigParser does not normally have.
106
107## Reading Configuration Values
108
109You can interact with `cli.config` in all the ways you'd normally expect. For example the `qmk compile` command gets the keyboard name from `cli.config.compile.keyboard`. It does not need to know whether that value came from the command line, an environment variable, or the configuration file.
110
111Iteration is also supported:
112
113```
114for section in cli.config:
115 for key in cli.config[section]:
116 cli.log.info('%s.%s: %s', section, key, cli.config[section][key])
117```
118
119## Setting Configuration Values
120
121You can set configuration values in the usual ways.
122
123Dictionary style:
124
125```
126cli.config['<section>']['<key>'] = <value>
127```
128
129Attribute style:
130
131```
132cli.config.<section>.<key> = <value>
133```
134
135## Deleting Configuration Values
136
137You can delete configuration values in the usual ways.
138
139Dictionary style:
140
141```
142del(cli.config['<section>']['<key>'])
143```
144
145Attribute style:
146
147```
148del(cli.config.<section>.<key>)
149```
150
151## Writing The Configuration File
152
153The configuration is not written out when it is changed. Most commands do not need to do this. We prefer to have the user change their configuration deliberitely using `qmk config`.
154
155You can use `cli.save_config()` to write out the configuration.
156
157## Excluding Arguments From Configuration
158
159Some arguments should not be propagated to the configuration file. These can be excluded by adding `arg_only=True` when creating the argument.
160
161Example:
162
163```
164@cli.argument('-o', '--output', arg_only=True, help='File to write to')
165@cli.argument('filename', arg_only=True, help='Configurator JSON file')
166@cli.subcommand('Create a keymap.c from a QMK Configurator export.')
167def json_keymap(cli):
168 pass
169```
170
171You will only be able to access these arguments using `cli.args`. For example:
172
173```
174cli.log.info('Reading from %s and writing to %s', cli.args.filename, cli.args.output)
175```
diff --git a/docs/python_development.md b/docs/python_development.md
deleted file mode 100644
index b976a7c0e..000000000
--- a/docs/python_development.md
+++ /dev/null
@@ -1,45 +0,0 @@
1# Python Development in QMK
2
3This document gives an overview of how QMK has structured its python code. You should read this before working on any of the python code.
4
5## Script directories
6
7There are two places scripts live in QMK: `qmk_firmware/bin` and `qmk_firmware/util`. You should use `bin` for any python scripts that utilize the `qmk` wrapper. Scripts that are standalone and not run very often live in `util`.
8
9We discourage putting anything into `bin` that does not utilize the `qmk` wrapper. If you think you have a good reason for doing so please talk to us about your use case.
10
11## Python Modules
12
13Most of the QMK python modules can be found in `qmk_firmware/lib/python`. This is the path that we append to `sys.path`.
14
15We have a module hierarchy under that path:
16
17* `qmk_firmware/lib/python`
18 * `milc.py` - The CLI library we use. Will be pulled out into its own module in the future.
19 * `qmk` - Code associated with QMK
20 * `cli` - Modules that will be imported for CLI commands.
21 * `errors.py` - Errors that can be raised within QMK apps
22 * `keymap.py` - Functions for working with keymaps
23
24## CLI Scripts
25
26We have a CLI wrapper that you should utilize for any user facing scripts. We think it's pretty easy to use and it gives you a lot of nice things for free.
27
28To use the wrapper simply place a module into `qmk_firmware/lib/python/qmk/cli`, and create a symlink to `bin/qmk` named after your module. Dashes in command names will be converted into dots so you can use hierarchy to manage commands.
29
30When `qmk` is run it checks to see how it was invoked. If it was invoked as `qmk` the module name is take from `sys.argv[1]`. If it was invoked as `qmk-<module-name>` then everything after the first dash is taken as the module name. Dashes and underscores are converted to dots, and then `qmk.cli` is prepended before the module is imported.
31
32The module uses `@cli.entrypoint()` and `@cli.argument()` decorators to define an entrypoint, which is where execution starts.
33
34## Example CLI Script
35
36We have provided a QMK Hello World script you can use as an example. To run it simply run `qmk hello` or `qmk-hello`. The source code is listed below.
37
38```
39from milc import cli
40
41@cli.argument('-n', '--name', default='World', help='Name to greet.')
42@cli.entrypoint('QMK Python Hello World.')
43def main(cli):
44 cli.echo('Hello, %s!', cli.config.general.name)
45```
diff --git a/docs/redirects.json b/docs/redirects.json
index 814518f40..651148c2c 100644
--- a/docs/redirects.json
+++ b/docs/redirects.json
@@ -43,6 +43,10 @@
43 { 43 {
44 "from": "unicode.html", 44 "from": "unicode.html",
45 "to": "feature_unicode.html" 45 "to": "feature_unicode.html"
46 },
47 {
48 "from": "python_development.html",
49 "to": "cli_development.html"
46 } 50 }
47 ] 51 ]
48} 52}