Userspace support.

This commit is contained in:
Nick Brassel 2023-08-28 21:32:05 +10:00
parent 81ea4f9110
commit fb216c21fb
No known key found for this signature in database
11 changed files with 206 additions and 79 deletions

View File

@ -191,9 +191,20 @@ define PARSE_KEYBOARD
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.))) KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.))) KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.)))
ifneq ($(QMK_USERSPACE),)
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.)))
endif
KEYBOARD_LAYOUTS := $(shell $(QMK_BIN) list-layouts --keyboard $1) KEYBOARD_LAYOUTS := $(shell $(QMK_BIN) list-layouts --keyboard $1)
LAYOUT_KEYMAPS := LAYOUT_KEYMAPS :=
$$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/layouts/*/$$(LAYOUT)/*/.))))) $$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/layouts/*/$$(LAYOUT)/*/.)))))
ifneq ($(QMK_USERSPACE),)
$$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(QMK_USERSPACE)/layouts/$$(LAYOUT)/*/.)))))
endif
KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS)) KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS))
@ -423,8 +434,18 @@ clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
echo 'done.' echo 'done.'
.PHONY: distclean .PHONY: distclean distclean_qmk
distclean: clean distclean: distclean_qmk
distclean_qmk: clean
echo -n 'Deleting *.bin, *.hex, and *.uf2 ... ' echo -n 'Deleting *.bin, *.hex, and *.uf2 ... '
rm -f *.bin *.hex *.uf2 rm -f *.bin *.hex *.uf2
echo 'done.' echo 'done.'
ifneq ($(QMK_USERSPACE),)
.PHONY: distclean_userspace
distclean: distclean_userspace
distclean_userspace: clean
echo -n 'Deleting user overlay *.bin, *.hex, and *.uf2 ... '
rm -f $(QMK_USERSPACE)/*.bin $(QMK_USERSPACE)/*.hex $(QMK_USERSPACE)/*.uf2
echo 'done.'
endif

View File

@ -15,3 +15,22 @@ else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.json)","")
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_1)/keymap.json KEYMAP_JSON := $(MAIN_KEYMAP_PATH_1)/keymap.json
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1) KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
endif endif
ifneq ($(QMK_USERSPACE),)
ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.json)","")
KEYMAP_JSON := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.json
KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)
endif
endif

View File

@ -129,32 +129,57 @@ include $(BUILDDEFS_PATH)/build_json.mk
# Pull in keymap level rules.mk # Pull in keymap level rules.mk
ifeq ("$(wildcard $(KEYMAP_PATH))", "") ifeq ("$(wildcard $(KEYMAP_PATH))", "")
# Look through the possible keymap folders until we find a matching keymap.c # Look through the possible keymap folders until we find a matching keymap.c
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","") ifneq ($(QMK_USERSPACE),)
-include $(MAIN_KEYMAP_PATH_1)/rules.mk ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.c)","")
KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c -include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/rules.mk
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1) KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)/keymap.c
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","") KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_1)
-include $(MAIN_KEYMAP_PATH_2)/rules.mk else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.c)","")
KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c -include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/rules.mk
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2) KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)/keymap.c
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","") KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_2)
-include $(MAIN_KEYMAP_PATH_3)/rules.mk else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.c)","")
KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c -include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/rules.mk
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3) KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)/keymap.c
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","") KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_3)
-include $(MAIN_KEYMAP_PATH_4)/rules.mk else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.c)","")
KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c -include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/rules.mk
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4) KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)/keymap.c
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","") KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_4)
-include $(MAIN_KEYMAP_PATH_5)/rules.mk else ifneq ("$(wildcard $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.c)","")
KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c -include $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/rules.mk
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5) KEYMAP_C := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)/keymap.c
else ifneq ($(LAYOUTS),) KEYMAP_PATH := $(QMK_USERSPACE)/$(MAIN_KEYMAP_PATH_5)
# If we haven't found a keymap yet fall back to community layouts endif
include $(BUILDDEFS_PATH)/build_layout.mk endif
else ifeq ($(KEYMAP_PATH),)
$(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap) ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
# this state should never be reached -include $(MAIN_KEYMAP_PATH_1)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_2)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_3)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_4)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_5)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
else ifneq ($(LAYOUTS),)
# If we haven't found a keymap yet fall back to community layouts
include $(BUILDDEFS_PATH)/build_layout.mk
else
$(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
# this state should never be reached
endif
endif endif
endif endif
@ -359,6 +384,10 @@ ifeq ("$(USER_NAME)","")
endif endif
USER_PATH := users/$(USER_NAME) USER_PATH := users/$(USER_NAME)
ifneq ($(QMK_USERSPACE),)
USER_PATH := $(QMK_USERSPACE)/$(USER_PATH)
endif
# Pull in user level rules.mk # Pull in user level rules.mk
-include $(USER_PATH)/rules.mk -include $(USER_PATH)/rules.mk
ifneq ("$(wildcard $(USER_PATH)/config.h)","") ifneq ("$(wildcard $(USER_PATH)/config.h)","")

View File

@ -1,6 +1,10 @@
LAYOUTS_PATH := layouts LAYOUTS_PATH := layouts
LAYOUTS_REPOS := $(patsubst %/,%,$(sort $(dir $(wildcard $(LAYOUTS_PATH)/*/)))) LAYOUTS_REPOS := $(patsubst %/,%,$(sort $(dir $(wildcard $(LAYOUTS_PATH)/*/))))
ifneq ($(QMK_USERSPACE),)
LAYOUTS_REPOS += $(patsubst %/,%,$(QMK_USERSPACE)/$(LAYOUTS_PATH))
endif
define SEARCH_LAYOUTS_REPO define SEARCH_LAYOUTS_REPO
LAYOUT_KEYMAP_PATH := $$(LAYOUTS_REPO)/$$(LAYOUT)/$$(KEYMAP) LAYOUT_KEYMAP_PATH := $$(LAYOUTS_REPO)/$$(LAYOUT)/$$(KEYMAP)
LAYOUT_KEYMAP_JSON := $$(LAYOUT_KEYMAP_PATH)/keymap.json LAYOUT_KEYMAP_JSON := $$(LAYOUT_KEYMAP_PATH)/keymap.json

View File

@ -188,7 +188,7 @@ DFU_SUFFIX_ARGS ?=
elf: $(BUILD_DIR)/$(TARGET).elf elf: $(BUILD_DIR)/$(TARGET).elf
hex: $(BUILD_DIR)/$(TARGET).hex hex: $(BUILD_DIR)/$(TARGET).hex
uf2: $(BUILD_DIR)/$(TARGET).uf2 uf2: $(BUILD_DIR)/$(TARGET).uf2
cpfirmware: $(FIRMWARE_FORMAT) cpfirmware_qmk: $(FIRMWARE_FORMAT)
$(SILENT) || printf "Copying $(TARGET).$(FIRMWARE_FORMAT) to qmk_firmware folder" | $(AWK_CMD) $(SILENT) || printf "Copying $(TARGET).$(FIRMWARE_FORMAT) to qmk_firmware folder" | $(AWK_CMD)
$(COPY) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT) $(TARGET).$(FIRMWARE_FORMAT) && $(PRINT_OK) $(COPY) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT) $(TARGET).$(FIRMWARE_FORMAT) && $(PRINT_OK)
eep: $(BUILD_DIR)/$(TARGET).eep eep: $(BUILD_DIR)/$(TARGET).eep
@ -197,6 +197,15 @@ sym: $(BUILD_DIR)/$(TARGET).sym
LIBNAME=lib$(TARGET).a LIBNAME=lib$(TARGET).a
lib: $(LIBNAME) lib: $(LIBNAME)
cpfirmware: cpfirmware_qmk
ifneq ($(QMK_USERSPACE),)
cpfirmware: cpfirmware_userspace
cpfirmware_userspace: cpfirmware_qmk
$(SILENT) || printf "Copying $(TARGET).$(FIRMWARE_FORMAT) to user overlay folder" | $(AWK_CMD)
$(COPY) $(BUILD_DIR)/$(TARGET).$(FIRMWARE_FORMAT) $(QMK_USERSPACE)/$(TARGET).$(FIRMWARE_FORMAT) && $(PRINT_OK)
endif
# Display size of file, modifying the output so people don't mistakenly grab the hex output # Display size of file, modifying the output so people don't mistakenly grab the hex output
BINARY_SIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(SED) -e 's/\.build\/.*$$/$(TARGET).$(FIRMWARE_FORMAT)/g' BINARY_SIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(SED) -e 's/\.build\/.*$$/$(TARGET).$(FIRMWARE_FORMAT)/g'

View File

@ -7,7 +7,7 @@ from pathlib import Path
from subprocess import DEVNULL from subprocess import DEVNULL
from milc import cli from milc import cli
from qmk.constants import QMK_FIRMWARE from qmk.constants import QMK_FIRMWARE, QMK_USERSPACE
from qmk.commands import _find_make, get_make_parallel_args from qmk.commands import _find_make, get_make_parallel_args
from qmk.keyboard import resolve_keyboard from qmk.keyboard import resolve_keyboard
from qmk.search import search_keymap_targets from qmk.search import search_keymap_targets
@ -49,6 +49,11 @@ def mass_compile(cli):
builddir.mkdir(parents=True, exist_ok=True) builddir.mkdir(parents=True, exist_ok=True)
with open(makefile, "w") as f: with open(makefile, "w") as f:
userspace_suffix = ''
if Path(QMK_FIRMWARE).resolve() != Path(QMK_USERSPACE).resolve():
userspace_suffix = f'QMK_USERSPACE={Path(QMK_USERSPACE).resolve()}'
for target in sorted(targets): for target in sorted(targets):
keyboard_name = target[0] keyboard_name = target[0]
keymap_name = target[1] keymap_name = target[1]
@ -62,7 +67,7 @@ all: {keyboard_safe}_{keymap_name}_binary
{keyboard_safe}_{keymap_name}_binary: {keyboard_safe}_{keymap_name}_binary:
@rm -f "{build_log}" || true @rm -f "{build_log}" || true
@echo "Compiling QMK Firmware for target: '{keyboard_name}:{keymap_name}'..." >>"{build_log}" @echo "Compiling QMK Firmware for target: '{keyboard_name}:{keymap_name}'..." >>"{build_log}"
+@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/builddefs/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{keymap_name}" COLOR=true SILENT=false {' '.join(cli.args.env)} \\ +@$(MAKE) -C "{QMK_FIRMWARE}" -f "{QMK_FIRMWARE}/builddefs/build_keyboard.mk" KEYBOARD="{keyboard_name}" KEYMAP="{keymap_name}" COLOR=true SILENT=false {userspace_suffix} {' '.join(cli.args.env)} \\
>>"{build_log}" 2>&1 \\ >>"{build_log}" 2>&1 \\
|| cp "{build_log}" "{failed_log}" || cp "{build_log}" "{failed_log}"
@{{ grep '\[ERRORS\]' "{build_log}" >/dev/null 2>&1 && printf "Build %-64s \e[1;31m[ERRORS]\e[0m\\n" "{keyboard_name}:{keymap_name}" ; }} \\ @{{ grep '\[ERRORS\]' "{build_log}" >/dev/null 2>&1 && printf "Build %-64s \e[1;31m[ERRORS]\e[0m\\n" "{keyboard_name}:{keymap_name}" ; }} \\

View File

@ -9,7 +9,7 @@ from pathlib import Path
from milc import cli from milc import cli
import jsonschema import jsonschema
from qmk.constants import INTERMEDIATE_OUTPUT_PREFIX from qmk.constants import INTERMEDIATE_OUTPUT_PREFIX, QMK_FIRMWARE, QMK_USERSPACE
from qmk.json_schema import json_load, validate from qmk.json_schema import json_load, validate
@ -51,6 +51,9 @@ def create_make_target(target, dry_run=False, parallel=1, **env_vars):
for key, value in env_vars.items(): for key, value in env_vars.items():
env.append(f'{key}={value}') env.append(f'{key}={value}')
if Path(QMK_FIRMWARE).resolve() != Path(QMK_USERSPACE).resolve():
env.append(f'QMK_USERSPACE={Path(QMK_USERSPACE).resolve()}')
if cli.config.general.verbose: if cli.config.general.verbose:
env.append('VERBOSE=true') env.append('VERBOSE=true')

View File

@ -4,8 +4,11 @@ from os import environ
from datetime import date from datetime import date
from pathlib import Path from pathlib import Path
from milc import cli
# The root of the qmk_firmware tree. # The root of the qmk_firmware tree.
QMK_FIRMWARE = Path.cwd() QMK_FIRMWARE = Path.cwd()
QMK_USERSPACE = environ.get('QMK_USERSPACE') or cli.config.user.overlay_dir or QMK_FIRMWARE
# Upstream repo url # Upstream repo url
QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware' QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware'

View File

@ -36,7 +36,9 @@ base_path = os.path.join(os.getcwd(), "keyboards") + os.path.sep
def find_keyboard_from_dir(): def find_keyboard_from_dir():
"""Returns a keyboard name based on the user's current directory. """Returns a keyboard name based on the user's current directory.
""" """
relative_cwd = qmk.path.under_qmk_firmware() relative_cwd = qmk.path.under_qmk_userspace()
if not relative_cwd:
relative_cwd = qmk.path.under_qmk_firmware()
if relative_cwd and len(relative_cwd.parts) > 1 and relative_cwd.parts[0] == 'keyboards': if relative_cwd and len(relative_cwd.parts) > 1 and relative_cwd.parts[0] == 'keyboards':
# Attempt to extract the keyboard name from the current directory # Attempt to extract the keyboard name from the current directory

View File

@ -12,6 +12,7 @@ from pygments.token import Token
from pygments import lex from pygments import lex
import qmk.path import qmk.path
from qmk.constants import QMK_FIRMWARE, QMK_USERSPACE
from qmk.keyboard import find_keyboard_from_dir, keyboard_folder from qmk.keyboard import find_keyboard_from_dir, keyboard_folder
from qmk.errors import CppError from qmk.errors import CppError
from qmk.info import info_json from qmk.info import info_json
@ -195,29 +196,38 @@ def find_keymap_from_dir():
"""Returns `(keymap_name, source)` for the directory we're currently in. """Returns `(keymap_name, source)` for the directory we're currently in.
""" """
relative_cwd = qmk.path.under_qmk_firmware() def _impl_find_keymap_from_dir(relative_cwd):
if relative_cwd and len(relative_cwd.parts) > 1:
# If we're in `qmk_firmware/keyboards` and `keymaps` is in our path, try to find the keyboard name.
if relative_cwd.parts[0] == 'keyboards' and 'keymaps' in relative_cwd.parts:
current_path = Path('/'.join(relative_cwd.parts[1:])) # Strip 'keyboards' from the front
if relative_cwd and len(relative_cwd.parts) > 1: if 'keymaps' in current_path.parts and current_path.name != 'keymaps':
# If we're in `qmk_firmware/keyboards` and `keymaps` is in our path, try to find the keyboard name. while current_path.parent.name != 'keymaps':
if relative_cwd.parts[0] == 'keyboards' and 'keymaps' in relative_cwd.parts: current_path = current_path.parent
current_path = Path('/'.join(relative_cwd.parts[1:])) # Strip 'keyboards' from the front
if 'keymaps' in current_path.parts and current_path.name != 'keymaps': return current_path.name, 'keymap_directory'
while current_path.parent.name != 'keymaps':
current_path = current_path.parent
return current_path.name, 'keymap_directory' # If we're in `qmk_firmware/layouts` guess the name from the community keymap they're in
elif relative_cwd.parts[0] == 'layouts' and is_keymap_dir(relative_cwd):
return relative_cwd.name, 'layouts_directory'
# If we're in `qmk_firmware/layouts` guess the name from the community keymap they're in # If we're in `qmk_firmware/users` guess the name from the userspace they're in
elif relative_cwd.parts[0] == 'layouts' and is_keymap_dir(relative_cwd): elif relative_cwd.parts[0] == 'users':
return relative_cwd.name, 'layouts_directory' # Guess the keymap name based on which userspace they're in
return relative_cwd.parts[1], 'users_directory'
return None, None
# If we're in `qmk_firmware/users` guess the name from the userspace they're in if Path(QMK_FIRMWARE).resolve() != Path(QMK_USERSPACE).resolve():
elif relative_cwd.parts[0] == 'users': name, source = _impl_find_keymap_from_dir(qmk.path.under_qmk_userspace())
# Guess the keymap name based on which userspace they're in if name and source:
return relative_cwd.parts[1], 'users_directory' return name, source
return None, None name, source = _impl_find_keymap_from_dir(qmk.path.under_qmk_firmware())
if name and source:
return name, source
return (None, None)
def keymap_completer(prefix, action, parser, parsed_args): def keymap_completer(prefix, action, parser, parsed_args):
@ -418,21 +428,22 @@ def locate_keymap(keyboard, keymap):
raise KeyError('Invalid keyboard: ' + repr(keyboard)) raise KeyError('Invalid keyboard: ' + repr(keyboard))
# Check the keyboard folder first, last match wins # Check the keyboard folder first, last match wins
checked_dirs = ''
keymap_path = '' keymap_path = ''
for dir in keyboard_folder(keyboard).split('/'): for search_dir in [QMK_FIRMWARE, QMK_USERSPACE]:
if checked_dirs: checked_dirs = ''
checked_dirs = '/'.join((checked_dirs, dir)) for dir in keyboard_folder(keyboard).split('/'):
else: if checked_dirs:
checked_dirs = dir checked_dirs = '/'.join((checked_dirs, dir))
else:
checked_dirs = dir
keymap_dir = Path('keyboards') / checked_dirs / 'keymaps' keymap_dir = Path(search_dir) / Path('keyboards') / checked_dirs / 'keymaps'
if (keymap_dir / keymap / 'keymap.c').exists(): if (keymap_dir / keymap / 'keymap.c').exists():
keymap_path = keymap_dir / keymap / 'keymap.c' keymap_path = keymap_dir / keymap / 'keymap.c'
if (keymap_dir / keymap / 'keymap.json').exists(): if (keymap_dir / keymap / 'keymap.json').exists():
keymap_path = keymap_dir / keymap / 'keymap.json' keymap_path = keymap_dir / keymap / 'keymap.json'
if keymap_path: if keymap_path:
return keymap_path return keymap_path
@ -440,7 +451,11 @@ def locate_keymap(keyboard, keymap):
# Check community layouts as a fallback # Check community layouts as a fallback
info = info_json(keyboard) info = info_json(keyboard)
for community_parent in Path('layouts').glob('*/'): community_parents = list(Path('layouts').glob('*/'))
if Path(QMK_FIRMWARE).resolve() != Path(QMK_USERSPACE).resolve() and (Path(QMK_USERSPACE) / "layouts").exists():
community_parents.append(Path(QMK_USERSPACE) / "layouts")
for community_parent in community_parents:
for layout in info.get("community_layouts", []): for layout in info.get("community_layouts", []):
community_layout = community_parent / layout / keymap community_layout = community_parent / layout / keymap
if community_layout.exists(): if community_layout.exists():
@ -474,26 +489,30 @@ def list_keymaps(keyboard, c=True, json=True, additional_files=None, fullpath=Fa
""" """
names = set() names = set()
keyboards_dir = Path('keyboards')
kb_path = keyboards_dir / keyboard
# walk up the directory tree until keyboards_dir # walk up the directory tree until keyboards_dir
# and collect all directories' name with keymap.c file in it # and collect all directories' name with keymap.c file in it
while kb_path != keyboards_dir: for search_dir in [QMK_FIRMWARE, QMK_USERSPACE]:
keymaps_dir = kb_path / "keymaps" keyboards_dir = search_dir / Path('keyboards')
kb_path = keyboards_dir / keyboard
if keymaps_dir.is_dir(): while kb_path != keyboards_dir:
for keymap in keymaps_dir.iterdir(): keymaps_dir = kb_path / "keymaps"
if is_keymap_dir(keymap, c, json, additional_files): if keymaps_dir.is_dir():
keymap = keymap if fullpath else keymap.name for keymap in keymaps_dir.iterdir():
names.add(keymap) if is_keymap_dir(keymap, c, json, additional_files):
keymap = keymap if fullpath else keymap.name
names.add(keymap)
kb_path = kb_path.parent kb_path = kb_path.parent
# Check community layouts as a fallback # Check community layouts as a fallback
info = info_json(keyboard) info = info_json(keyboard)
for community_parent in Path('layouts').glob('*/'): community_parents = list(Path('layouts').glob('*/'))
if Path(QMK_FIRMWARE).resolve() != Path(QMK_USERSPACE).resolve() and (Path(QMK_USERSPACE) / "layouts").exists():
community_parents.append(Path(QMK_USERSPACE) / "layouts")
for community_parent in community_parents:
for layout in info.get("community_layouts", []): for layout in info.get("community_layouts", []):
cl_path = community_parent / layout cl_path = community_parent / layout
if cl_path.is_dir(): if cl_path.is_dir():

View File

@ -5,7 +5,7 @@ import os
import argparse import argparse
from pathlib import Path from pathlib import Path
from qmk.constants import MAX_KEYBOARD_SUBFOLDERS, QMK_FIRMWARE from qmk.constants import MAX_KEYBOARD_SUBFOLDERS, QMK_FIRMWARE, QMK_USERSPACE
from qmk.errors import NoSuchKeyboardError from qmk.errors import NoSuchKeyboardError
@ -30,6 +30,17 @@ def under_qmk_firmware():
return None return None
def under_qmk_userspace():
"""Returns a Path object representing the relative path under $QMK_USERSPACE, qmk root, or None.
"""
cwd = Path(os.environ['ORIG_CWD'])
try:
return cwd.relative_to(QMK_USERSPACE)
except ValueError:
return None
def keyboard(keyboard_name): def keyboard(keyboard_name):
"""Returns the path to a keyboard's directory relative to the qmk root. """Returns the path to a keyboard's directory relative to the qmk root.
""" """
@ -47,11 +58,13 @@ def keymaps(keyboard_name):
keyboard_folder = keyboard(keyboard_name) keyboard_folder = keyboard(keyboard_name)
found_dirs = [] found_dirs = []
for _ in range(MAX_KEYBOARD_SUBFOLDERS): for root_dir in [QMK_USERSPACE, QMK_FIRMWARE]:
if (keyboard_folder / 'keymaps').exists(): this_keyboard_folder = root_dir / keyboard_folder
found_dirs.append((keyboard_folder / 'keymaps').resolve()) for _ in range(MAX_KEYBOARD_SUBFOLDERS):
if (this_keyboard_folder / 'keymaps').exists():
found_dirs.append((this_keyboard_folder / 'keymaps').resolve())
keyboard_folder = keyboard_folder.parent this_keyboard_folder = this_keyboard_folder.parent
if len(found_dirs) > 0: if len(found_dirs) > 0:
return found_dirs return found_dirs