Merge pull request #2 from qmk/develop

Develop
This commit is contained in:
bwisn 2022-03-06 11:29:48 +01:00 committed by GitHub
commit 9c76065188
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 62 additions and 84 deletions

View File

@ -35,4 +35,4 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.SPACES_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET_KEY }}
AWS_S3_ENDPOINT: https://nyc3.digitaloceanspaces.com
SOURCE_DIR: 'api_data'
SOURCE_DIR: '.build/api_data'

View File

@ -35,4 +35,4 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.SPACES_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET_KEY }}
AWS_S3_ENDPOINT: https://nyc3.digitaloceanspaces.com
SOURCE_DIR: 'api_data'
SOURCE_DIR: '.build/api_data'

View File

@ -1 +0,0 @@
theme: jekyll-theme-cayman

View File

@ -3,7 +3,7 @@
{
# Format:
# <config.h key>: {"info_key": <info.json key>, ["value_type": <value_type>], ["to_json": <true/false>], ["to_c": <true/false>]}
# value_type: one of "array", "array.int", "bool", "int", "hex", "list", "mapping"
# value_type: one of "array", "array.int", "bool", "int", "hex", "list", "mapping", "str", "raw"
# to_json: Default `true`. Set to `false` to exclude this mapping from info.json
# to_c: Default `true`. Set to `false` to exclude this mapping from config.h
# warn_duplicate: Default `true`. Set to `false` to turn off warning when a value exists in both places
@ -17,7 +17,7 @@
"DEVICE_VER": {"info_key": "usb.device_ver", "value_type": "hex"},
# TODO: Replace ^^^ with vvv
#"DEVICE_VER": {"info_key": "usb.device_version", "value_type": "bcd_version"},
"DESCRIPTION": {"info_key": "keyboard_folder", "to_json": false},
"DESCRIPTION": {"info_key": "keyboard_folder", "value_type": "str", "to_json": false},
"DIODE_DIRECTION": {"info_key": "diode_direction"},
"FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
"DYNAMIC_KEYMAP_EEPROM_MAX_ADDR": {"info_key": "dynamic_keymap.eeprom_max_addr", "value_type": "int"},

View File

@ -3,7 +3,7 @@
{
# Format:
# <rules.mk key>: {"info_key": <info.json key>, ["value_type": <value_type>], ["to_json": <true/false>], ["to_c": <true/false>]}
# value_type: one of "array", "array.int", "bool", "int", "list", "hex", "mapping"
# value_type: one of "array", "array.int", "bool", "int", "list", "hex", "mapping", "str", "raw"
# to_json: Default `true`. Set to `false` to exclude this mapping from info.json
# to_c: Default `true`. Set to `false` to exclude this mapping from rules.mk
# warn_duplicate: Default `true`. Set to `false` to turn off warning when a value exists in both places
@ -20,6 +20,6 @@
"MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"},
"NO_USB_STARTUP_CHECK": {"info_key": "usb.no_startup_check", "value_type": "bool"},
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "value_type": "str", "to_c": false},
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"}
}

View File

@ -44,7 +44,7 @@ In other cases you should group like options together in an `object`. This is pa
In most cases you can add a simple mapping. These are maintained as JSON files in `data/mappings/info_config.json` and `data/mappings/info_rules.json`, and control mapping for `config.h` and `rules.mk`, respectively. Each mapping is keyed by the `config.h` or `rules.mk` variable, and the value is a hash with the following keys:
* `info_key`: (required) The location within `info.json` for this value. See below.
* `value_type`: (optional) Default `str`. The format for this variable's value. See below.
* `value_type`: (optional) Default `raw`. The format for this variable's value. See below.
* `to_json`: (optional) Default `true`. Set to `false` to exclude this mapping from info.json
* `to_c`: (optional) Default `true`. Set to `false` to exclude this mapping from config.h
* `warn_duplicate`: (optional) Default `true`. Set to `false` to turn off warning when a value exists in both places
@ -57,7 +57,7 @@ Under the hood we use [Dotty Dict](https://dotty-dict.readthedocs.io/en/latest/)
#### Value Types
By default we treat all values as simple strings. If your value is more complex you can use one of these types to intelligently parse the data:
By default we treat all values as unquoted "raw" data. If your value is more complex you can use one of these types to intelligently parse the data:
* `array`: A comma separated array of strings
* `array.int`: A comma separated array of integers
@ -65,6 +65,7 @@ By default we treat all values as simple strings. If your value is more complex
* `hex`: A number formatted as hex
* `list`: A space separate array of strings
* `mapping`: A hash of key/value pairs
* `str`: A quoted string literal
### Add code to extract it

View File

@ -230,17 +230,6 @@ send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻");
Example uses include sending Unicode strings when a key is pressed, as described in [Macros](feature_macros.md).
### `send_unicode_hex_string()` (Deprecated)
Similar to `send_unicode_string()`, but the characters are represented by their Unicode code points, written in hexadecimal and separated by spaces. For example, the table flip above would be achieved with:
```c
send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B");
```
An easy way to convert your Unicode string to this format is to use [this site](https://r12a.github.io/app-conversion/) and take the result in the "Hex/UTF-32" section.
## Additional Language Support
In `quantum/keymap_extras`, you'll see various language files — these work the same way as the ones for alternative layouts such as Colemak or BÉPO. When you include one of these language headers, you gain access to keycodes specific to that language / national layout. Such keycodes are defined by a 2-letter country/language code, followed by an underscore and a 4-letter abbreviation of the character to which the key corresponds. For example, including `keymap_french.h` and using `FR_UGRV` in your keymap will output `ù` when typed on a system with a native French AZERTY layout.

View File

@ -233,17 +233,6 @@ send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻");
使用例には、[Macros](ja/feature_macros.md) で説明されているように、キーが押された時に Unicode 文字列を送信することが含まれます。
### `send_unicode_hex_string()`
`send_unicode_string()` に似ていますが、文字は Unicode コードポイントで表され、16進数で記述され、空白で区切られています。例えば、上記のちゃぶ台返しは以下で表されます:
```c
send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B");
```
[このサイト](https://r12a.github.io/app-conversion/)で結果を "Hex/UTF-32" で受け取ることで、Unicode 文字列をこの形式に簡単に変換できます。
## 追加の言語サポート
`quantum/keymap_extras` には、様々な言語ファイルがあります — これらは Colemak または BÉPO のような代替レイアウトのファイルと同じように動作します。これらの言語ヘッダのいずれかを `#include` すると、その言語/国のレイアウトに固有のキーコードにアクセスできます。このようなキーコードは、2文字の国/言語コードの後に、アンダースコアとキーが対応する4文字の略語が続くことで定義されます。例えば、キーマップに `keymap_french.h` を含め、`FR_UGRV` を使うと、ネイティブのフランス語 AZERTY レイアウトを使うシステムで入力すると、`ù` が出力されます。

View File

@ -26,7 +26,6 @@
#define DEVICE_VER 0x0001
#define MANUFACTURER github.com/sowbug
#define PRODUCT 68-key keyboard
#define DESCRIPTION A 68-key keyboard based on 68keys.io
// key matrix size
#define MATRIX_ROWS 5

View File

@ -26,7 +26,6 @@
#define DEVICE_VER 0x0001
#define MANUFACTURER github.com/sowbug
#define PRODUCT ANSI TKL
#define DESCRIPTION A tenkeyless ANSI-layout keyboard
// key matrix size
#define MATRIX_ROWS 6

View File

@ -23,7 +23,6 @@
#define DEVICE_VER 0x0001
#define MANUFACTURER Unicomp/Purdea Andrei
#define PRODUCT Unicomp Spacesaver M
#define DESCRIPTION QMK firmware for the Unicomp Spacesaver M keyboard with a replacement Overnumpad controller
#define SERIAL_NUMBER "purdea.ro:overnumpad_controller"
/* key matrix size */

View File

@ -22,7 +22,6 @@
#define DEVICE_VER 0x0001
#define MANUFACTURER Xelus
#define PRODUCT Ninjin
#define DESCRIPTION Ninjin
/* key matrix size */
#define MATRIX_ROWS 6

View File

@ -1,7 +1,7 @@
"""This script automates the generation of the QMK API data.
"""
from pathlib import Path
from shutil import copyfile
import shutil
import json
from milc import cli
@ -12,28 +12,42 @@ from qmk.json_encoders import InfoJSONEncoder
from qmk.json_schema import json_load
from qmk.keyboard import find_readme, list_keyboards
TEMPLATE_PATH = Path('data/templates/api/')
BUILD_API_PATH = Path('.build/api_data/')
@cli.argument('-n', '--dry-run', arg_only=True, action='store_true', help="Don't write the data to disk.")
@cli.argument('-f', '--filter', arg_only=True, action='append', default=[], help="Filter the list of keyboards based on partial name matches the supplied value. May be passed multiple times.")
@cli.subcommand('Creates a new keymap for the keyboard of your choosing', hidden=False if cli.config.user.developer else True)
def generate_api(cli):
"""Generates the QMK API data.
"""
api_data_dir = Path('api_data')
v1_dir = api_data_dir / 'v1'
if BUILD_API_PATH.exists():
shutil.rmtree(BUILD_API_PATH)
shutil.copytree(TEMPLATE_PATH, BUILD_API_PATH)
v1_dir = BUILD_API_PATH / 'v1'
keyboard_all_file = v1_dir / 'keyboards.json' # A massive JSON containing everything
keyboard_list_file = v1_dir / 'keyboard_list.json' # A simple list of keyboard targets
keyboard_aliases_file = v1_dir / 'keyboard_aliases.json' # A list of historical keyboard names and their new name
keyboard_metadata_file = v1_dir / 'keyboard_metadata.json' # All the data configurator/via needs for initialization
usb_file = v1_dir / 'usb.json' # A mapping of USB VID/PID -> keyboard target
if not api_data_dir.exists():
api_data_dir.mkdir()
# Filter down when required
keyboard_list = list_keyboards()
if cli.args.filter:
kb_list = []
for keyboard_name in keyboard_list:
if any(i in keyboard_name for i in cli.args.filter):
kb_list.append(keyboard_name)
keyboard_list = kb_list
kb_all = {}
usb_list = {}
# Generate and write keyboard specific JSON files
for keyboard_name in list_keyboards():
for keyboard_name in keyboard_list:
kb_all[keyboard_name] = info_json(keyboard_name)
keyboard_dir = v1_dir / 'keyboards' / keyboard_name
keyboard_info = keyboard_dir / 'info.json'
@ -47,7 +61,7 @@ def generate_api(cli):
cli.log.debug('Wrote file %s', keyboard_info)
if keyboard_readme_src:
copyfile(keyboard_readme_src, keyboard_readme)
shutil.copyfile(keyboard_readme_src, keyboard_readme)
cli.log.debug('Copied %s -> %s', keyboard_readme_src, keyboard_readme)
if 'usb' in kb_all[keyboard_name]:

View File

@ -82,7 +82,7 @@ def generate_config_items(kb_info_json, config_h_lines):
for config_key, info_dict in info_config_map.items():
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')
to_config = info_dict.get('to_config', True)
if not to_config:
@ -110,6 +110,11 @@ def generate_config_items(kb_info_json, config_h_lines):
config_h_lines.append(f'#ifndef {key}')
config_h_lines.append(f'# define {key} {value}')
config_h_lines.append(f'#endif // {key}')
elif key_type == 'str':
config_h_lines.append('')
config_h_lines.append(f'#ifndef {config_key}')
config_h_lines.append(f'# define {config_key} "{config_value}"')
config_h_lines.append(f'#endif // {config_key}')
elif key_type == 'bcd_version':
(major, minor, revision) = config_value.split('.')
config_h_lines.append('')
@ -200,7 +205,7 @@ def generate_config_h(cli):
cli.args.output.parent.mkdir(parents=True, exist_ok=True)
if cli.args.output.exists():
cli.args.output.replace(cli.args.output.parent / (cli.args.output.name + '.bak'))
cli.args.output.write_text(config_h)
cli.args.output.write_text(config_h, encoding='utf-8')
if not cli.args.quiet:
cli.log.info('Wrote info_config.h to %s.', cli.args.output)

View File

@ -19,7 +19,7 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
return None
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')
try:
rules_value = kb_info_json[info_key]
@ -32,6 +32,8 @@ def process_mapping_rule(kb_info_json, rules_key, info_dict):
return f'{rules_key} ?= {"yes" if rules_value else "no"}'
elif key_type == 'mapping':
return '\n'.join([f'{key} ?= {value}' for key, value in rules_value.items()])
elif key_type == 'str':
return f'{rules_key} ?= "{rules_value}"'
return f'{rules_key} ?= {rules_value}'

View File

@ -411,7 +411,7 @@ def _extract_config_h(info_data):
for config_key, info_dict in info_config_map.items():
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')
try:
if config_key in config_c and info_dict.get('to_json', True):
@ -443,6 +443,9 @@ def _extract_config_h(info_data):
elif key_type == 'int':
dotty_info[info_key] = int(config_c[config_key])
elif key_type == 'str':
dotty_info[info_key] = config_c[config_key].strip('"')
elif key_type == 'bcd_version':
major = int(config_c[config_key][2:4])
minor = int(config_c[config_key][4])
@ -491,7 +494,7 @@ def _extract_rules_mk(info_data):
for rules_key, info_dict in info_rules_map.items():
info_key = info_dict['info_key']
key_type = info_dict.get('value_type', 'str')
key_type = info_dict.get('value_type', 'raw')
try:
if rules_key in rules and info_dict.get('to_json', True):
@ -523,6 +526,9 @@ def _extract_rules_mk(info_data):
elif key_type == 'int':
dotty_info[info_key] = int(rules[rules_key])
elif key_type == 'str':
dotty_info[info_key] = rules[rules_key].strip('"')
else:
dotty_info[info_key] = rules[rules_key]

View File

@ -244,7 +244,7 @@ def test_clean():
def test_generate_api():
result = check_subcommand('generate-api', '--dry-run')
result = check_subcommand('generate-api', '--dry-run', '--filter', 'handwired/pytest')
check_returncode(result)
@ -259,7 +259,7 @@ def test_generate_config_h():
result = check_subcommand('generate-config-h', '-kb', 'handwired/pytest/basic')
check_returncode(result)
assert '# define DEVICE_VER 0x0001' in result.stdout
assert '# define DESCRIPTION handwired/pytest/basic' in result.stdout
assert '# define DESCRIPTION "handwired/pytest/basic"' in result.stdout
assert '# define DIODE_DIRECTION COL2ROW' in result.stdout
assert '# define MANUFACTURER none' in result.stdout
assert '# define PRODUCT pytest' in result.stdout

View File

@ -18,6 +18,13 @@ COMPILEFLAGS += -ffunction-sections
COMPILEFLAGS += -fdata-sections
COMPILEFLAGS += -fpack-struct
COMPILEFLAGS += -fshort-enums
COMPILEFLAGS += -mcall-prologues
# Linker relaxation is only possible if
# link time optimizations are not enabled.
ifeq ($(strip $(LTO_ENABLE)), no)
COMPILEFLAGS += -mrelax
endif
ASFLAGS += $(AVR_ASFLAGS)
@ -28,7 +35,7 @@ CFLAGS += -fno-strict-aliasing
CXXFLAGS += $(COMPILEFLAGS)
CXXFLAGS += -fno-exceptions -std=c++11
LDFLAGS +=-Wl,--gc-sections
LDFLAGS += -Wl,--gc-sections
OPT_DEFS += -DF_CPU=$(F_CPU)UL

View File

@ -16,8 +16,6 @@
#include "process_unicode_common.h"
#include "eeprom.h"
#include <ctype.h>
#include <string.h>
unicode_config_t unicode_config;
uint8_t unicode_saved_mods;
@ -231,37 +229,6 @@ void register_unicode(uint32_t code_point) {
unicode_input_finish();
}
// clang-format off
void send_unicode_hex_string(const char *str) {
if (!str) {
return;
}
while (*str) {
// Find the next code point (token) in the string
for (; *str == ' '; str++); // Skip leading spaces
size_t n = strcspn(str, " "); // Length of the current token
char code_point[n+1];
strncpy(code_point, str, n); // Copy token into buffer
code_point[n] = '\0'; // Make sure it's null-terminated
// Normalize the code point: make all hex digits lowercase
for (char *p = code_point; *p; p++) {
*p = tolower((unsigned char)*p);
}
// Send the code point as a Unicode input string
unicode_input_start();
send_string(code_point);
unicode_input_finish();
str += n; // Move to the first ' ' (or '\0') after the current token
}
}
// clang-format on
// Borrowed from https://nullprogram.com/blog/2017/10/06/
static const char *decode_utf8(const char *str, int32_t *code_point) {
const char *next;

View File

@ -90,7 +90,6 @@ void register_hex(uint16_t hex);
void register_hex32(uint32_t hex);
void register_unicode(uint32_t code_point);
void send_unicode_hex_string(const char *str);
void send_unicode_string(const char *str);
bool process_unicode_common(uint16_t keycode, keyrecord_t *record);

View File

@ -1,3 +1,7 @@
# This is the `develop` branch!
See the [Breaking Changes](https://docs.qmk.fm/#/breaking_changes) document for more information.
# Quantum Mechanical Keyboard Firmware
[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags)