From 2bf5314ca358dda6035edae0466b309f2ef6b31f Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 19 Jan 2026 16:55:36 +0800 Subject: [PATCH 01/13] build(zmk): import urchin keymap --- .github/workflows/build-zmk-firmware.yml | 173 +++++++++++++++++++++++ zmk/build.yaml | 23 +++ zmk/keymap_italian.h | 122 ++++++++++++++++ zmk/urchin.conf | 30 ++++ zmk/urchin.json | 46 ++++++ zmk/urchin.keymap | 165 +++++++++++++++++++++ zmk/west.yml | 27 ++++ 7 files changed, 586 insertions(+) create mode 100644 .github/workflows/build-zmk-firmware.yml create mode 100644 zmk/build.yaml create mode 100644 zmk/keymap_italian.h create mode 100644 zmk/urchin.conf create mode 100644 zmk/urchin.json create mode 100644 zmk/urchin.keymap create mode 100644 zmk/west.yml diff --git a/.github/workflows/build-zmk-firmware.yml b/.github/workflows/build-zmk-firmware.yml new file mode 100644 index 00000000..f0819ae3 --- /dev/null +++ b/.github/workflows/build-zmk-firmware.yml @@ -0,0 +1,173 @@ +name: Reusable user config build + +on: [push, pull_request, workflow_dispatch] + +jobs: + matrix: + runs-on: ubuntu-22.04 + name: Fetch Build Keyboards + outputs: + build_matrix: ${{ env.build_matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Fetch Build Matrix + run: | + echo "build_matrix=$(yq -oj -I0 'zmk/build.yaml')" >> $GITHUB_ENV + yq -oj "zmk/build.yaml" + + build: + runs-on: ubuntu-latest + container: + image: zmkfirmware/zmk-build-arm:stable + needs: matrix + name: Build + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.matrix.outputs.build_matrix) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create build directory + run: | + echo "build_dir=$(mktemp -d)" >> $GITHUB_ENV + + - name: Prepare variables + shell: bash -x {0} + env: + board: ${{ matrix.board }} + shield: ${{ matrix.shield }} + artifact_name: ${{ matrix.artifact-name }} + snippet: ${{ matrix.snippet }} + run: | + if [ -e zephyr/module.yml ]; then + export zmk_load_arg=" -DZMK_EXTRA_MODULES='${GITHUB_WORKSPACE}'" + new_tmp_dir="${TMPDIR:-/tmp}/zmk-config" + mkdir -p "${new_tmp_dir}" + echo "base_dir=${new_tmp_dir}" >> $GITHUB_ENV + else + echo "base_dir=${GITHUB_WORKSPACE}" >> $GITHUB_ENV + fi + + if [ -n "${snippet}" ]; then + extra_west_args="-S \"${snippet}\"" + fi + + echo "zephyr_version=${ZEPHYR_VERSION}" >> $GITHUB_ENV + echo "extra_west_args=${extra_west_args}" >> $GITHUB_ENV + echo "extra_cmake_args=${shield:+-DSHIELD=\"$shield\"}${zmk_load_arg}" >> $GITHUB_ENV + echo "display_name=${shield:+$shield - }${board}" >> $GITHUB_ENV + echo "artifact_name=${artifact_name:-${shield:+$shield-}${board//\//_}-zmk}" >> $GITHUB_ENV + + - name: Copy config files to isolated temporary directory + run: | + if [ "${{ env.base_dir }}" != "${GITHUB_WORKSPACE}" ]; then + mkdir "${{ env.base_dir }}/zmk" + cp -R zmk/* "${{ env.base_dir }}/zmk/" + fi + + - name: Cache west modules + uses: actions/cache@v4 + continue-on-error: true + env: + cache_name: cache-zephyr-${{ env.zephyr_version }}-modules + with: + path: | + ${{ env.base_dir }}/modules/ + ${{ env.base_dir }}/tools/ + ${{ env.base_dir }}/zephyr/ + ${{ env.base_dir }}/bootloader/ + ${{ env.base_dir }}/zmk/ + key: ${{ runner.os }}-build-${{ env.cache_name }}-${{ hashFiles('**/west.yml', '**/build.yaml') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache_name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: West Init + working-directory: ${{ env.base_dir }} + run: west init -l "${{ env.base_dir }}/zmk" + + - name: West Update + working-directory: ${{ env.base_dir }} + run: west update --fetch-opt=--filter=tree:0 + + - name: Check ZMK revision + working-directory: ${{ env.base_dir }} + run: | + zmk_revision=$(west list -f "{revision}" zmk) + echo "zmk_revision=${zmk_revision}" >> $GITHUB_ENV + echo "ZMK revision: ${zmk_revision}" + + - name: West Zephyr export + working-directory: ${{ env.base_dir }} + run: west zephyr-export + + - name: West Build (${{ env.display_name }}) + working-directory: ${{ env.base_dir }} + shell: sh -x {0} + run: west build -s zmk/app -d "${{ env.build_dir }}" -b "${{ matrix.board }}" ${{ env.extra_west_args }} -- -DZMK_CONFIG=${{ env.base_dir }}/zmk ${{ env.extra_cmake_args }} ${{ matrix.cmake-args }} + + - name: Warn about building from main if build fails + if: failure() && env.zmk_revision == 'main' + run: | + echo "# Consider Pinning ZMK" >> $GITHUB_STEP_SUMMARY + echo "Your recent build failure might be the result of breaking changes made to ZMK's main branch." >> $GITHUB_STEP_SUMMARY + echo "Consider [pinning your ZMK version](https://zmk.dev/blog/2025/06/20/pinned-zmk) to a release for increased stability." >> $GITHUB_STEP_SUMMARY + echo "See also the [list of released versions](https://github.com/zmkfirmware/zmk/releases)." >> $GITHUB_STEP_SUMMARY + echo "If you wish to stay on main, check the most recent pending release PR for breaking changes. [Our blog](https://zmk.dev/blog) may have upgrade information if breaking changes are significant." >> $GITHUB_STEP_SUMMARY + + - name: ${{ env.display_name }} Kconfig file + run: | + if [ -f "${{ env.build_dir }}/zephyr/.config" ] + then + grep -v -e "^#" -e "^$" "${{ env.build_dir }}/zephyr/.config" | sort + else + echo "No Kconfig output" + fi + if: ${{ !cancelled() }} + + - name: ${{ env.display_name }} Devicetree file + run: | + if [ -f "${{ env.build_dir }}/zephyr/zephyr.dts" ] + then + cat "${{ env.build_dir }}/zephyr/zephyr.dts" + elif [ -f "${{ env.build_dir }}/zephyr/zephyr.dts.pre" ] + then + cat -s "${{ env.build_dir }}/zephyr/zephyr.dts.pre" + else + echo "No Devicetree output" + fi + if: ${{ !cancelled() }} + + - name: Rename artifacts + shell: sh -x {0} + run: | + mkdir "${{ env.build_dir }}/artifacts" + if [ -f "${{ env.build_dir }}/zephyr/zmk.uf2" ] + then + cp "${{ env.build_dir }}/zephyr/zmk.uf2" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.uf2" + elif [ -f "${{ env.build_dir }}/zephyr/zmk.bin" ] + then + cp "${{ env.build_dir }}/zephyr/zmk.bin" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.bin" + fi + + - name: Archive (${{ env.display_name }}) + uses: actions/upload-artifact@v4 + with: + name: artifact-${{ env.artifact_name }} + path: ${{ env.build_dir }}/artifacts + + merge: + runs-on: ubuntu-latest + needs: build + name: Merge Output Artifacts + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@v4 + with: + name: firmware + pattern: artifact-* + delete-merged: true diff --git a/zmk/build.yaml b/zmk/build.yaml new file mode 100644 index 00000000..7515ab2a --- /dev/null +++ b/zmk/build.yaml @@ -0,0 +1,23 @@ +# This file generates the GitHub Actions matrix +# For simple board + shield combinations, add them +# to the top level board and shield arrays, for more +# control, add individual board + shield combinations to +# the `include` property, e.g: +# +# board: [ "nice_nano_v2" ] +# shield: [ "corne_left", "corne_right" ] +# include: +# - board: bdn9_rev2 +# - board: nice_nano_v2 +# shield: reviung41 +# +--- +include: + - board: nice_nano_v2 + shield: urchin_left nice_view_adapter nice_view_gem + snippet: studio-rpc-usb-uart + cmake-args: -DCONFIG_ZMK_STUDIO=y + - board: nice_nano_v2 + shield: urchin_right nice_view_adapter nice_view_gem + - board: nice_nano_v2 + shield: settings_reset diff --git a/zmk/keymap_italian.h b/zmk/keymap_italian.h new file mode 100644 index 00000000..1587d84f --- /dev/null +++ b/zmk/keymap_italian.h @@ -0,0 +1,122 @@ +/** + * This file includes custom keycodes for the italian input language setting. + * If you only type in english, you can delete this file and it's import. + * If you wish to replace this file with your preferred language, use + * the qmk version as reference: + * https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras +*/ + + +/* + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ \ │ │ │ │ │ │ │ │ │ │ │ ' │ ì │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ è │ + │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ ò │ à │ ù │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ < │ │ │ │ │ │ │ │ , │ . │ - │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ +// Row 1 +#define IT_BSLH GRAVE // backslash +#define IT_SQUOT MINUS // ' +#define IT_IGRV EQUAL // ì +// Row 2 +#define IT_EGRV LBKT // è +#define IT_PLUS SLASH // + +// Row 3 +#define IT_OGRV SEMI // ò +#define IT_AGRV APOS // à +#define IT_UGRV NON_US_HASH // ù +// Row 4 +#define IT_LESS NON_US_BSLH // < +#define IT_MINUS RBKT // - + +/* Shifted symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ | │ ! │ " │ £ │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ^ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ é │ * │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ ç │ ° │ § │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ > │ │ │ │ │ │ │ │ ; │ : │ _ │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ +// Row 1 +#define IT_PIPE LS(GRAVE) // | +#define IT_EXCL LS(N1) // ! +#define IT_DQUOT LS(N2) // " +#define IT_PND LS(N3) // £ +#define IT_USD LS(N4) // $ +#define IT_PERC LS(N5) // % +#define IT_AND LS(N6) // & +#define IT_FSLH LS(N7) // / +#define IT_LPAR LS(N8) // ( +#define IT_RPAR LS(N9) // ) +#define IT_EQL LS(N0) // = +#define IT_QUES LS(MINUS) // ? +#define IT_CARET LS(EQUAL) // ^ +// Row 2 +#define IT_EACU LS(LBKT) // é +#define IT_AST LS(RBKT) // * +// Row 3 +#define IT_CCED LS(SEMI) // ç +#define IT_DEG LS(APOS) // ° +#define IT_SECT LS(NON_US_HASH) // § +// Row 4 +#define IT_GREAT LS(NON_US_BSLH) // > +#define IT_UNDER LS(SLASH) // _ + +/* AltGr symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ € │ │ │ │ │ │ │ │ [ │ ] │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ @ │ # │ │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ +// Row 2 +#define IT_EUR RA(E) // € +#define IT_LBKT RA(LBKT) // [ +#define IT_RBKT RA(RBKT) // ] +// Row 3 +#define IT_AT RA(SEMI) // @ +#define IT_HASH RA(APOS) // # + +/* Shift+AltGr symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ { │ } │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ +// Row 2 +#define IT_LBRC LS(RA(LBKT)) // { +#define IT_RBRC LS(RA(RBKT)) // } + +/** + * Personalized symbols. + * + * These symbols are not part of the default italian input. + * I use a custom windows keymap to input them. +*/ +#define IT_BKTK RA(MINUS) // ` +#define IT_TILDE RA(EQUAL) // ~ +#define IT_CEGR RA(LS(E)) // È diff --git a/zmk/urchin.conf b/zmk/urchin.conf new file mode 100644 index 00000000..55f5c11b --- /dev/null +++ b/zmk/urchin.conf @@ -0,0 +1,30 @@ +# enable bluetooth +CONFIG_BT=y + +# increase bluetooth signal power +CONFIG_BT_CTLR_TX_PWR_PLUS_8=y + +# enable deep sleep support +CONFIG_ZMK_SLEEP=y + +# the keyboard disconnects from bluetooth. +# uses very little power, but it may take +# a few seconds to reconnect after waking. +# 1.800.000 ms = 30 minutes +CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=1800000 + +# "Eager Debouncing" +# Trying to lower the input lag. +# CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=1 +# CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=5 + +# --- DISPLAY SETTINGS --- + +# enable display +CONFIG_ZMK_DISPLAY=y +# custom status screen (nice-view-gem) +CONFIG_ZMK_DISPLAY_STATUS_SCREEN_CUSTOM=y +# turn off gem animation to save battery +CONFIG_NICE_VIEW_GEM_ANIMATION=n + +# source: https://github.com/M165437/nice-view-gem/blob/main/README.md diff --git a/zmk/urchin.json b/zmk/urchin.json new file mode 100644 index 00000000..15798f7f --- /dev/null +++ b/zmk/urchin.json @@ -0,0 +1,46 @@ +{ + "layouts": { + "default_transform": { + "layout": [ + { "row": 0, "col": 0, "x": -2, "y": 0.75 }, + { "row": 0, "col": 1, "x": -1, "y": 0 }, + { "row": 0, "col": 2, "x": 0, "y": -0.25 }, + { "row": 0, "col": 3, "x": 1, "y": 0 }, + { "row": 0, "col": 4, "x": 2, "y": 0.25 }, + { "row": 0, "col": 5, "x": 6, "y": 0.25 }, + { "row": 0, "col": 6, "x": 7, "y": 0 }, + { "row": 0, "col": 7, "x": 8, "y": -0.25 }, + { "row": 0, "col": 8, "x": 9, "y": 0 }, + { "row": 0, "col": 9, "x": 10, "y": 0.5 }, + + { "row": 1, "col": 0, "x": -2, "y": 1.75 }, + { "row": 1, "col": 1, "x": -1, "y": 1 }, + { "row": 1, "col": 2, "x": 0, "y": 0.75 }, + { "row": 1, "col": 3, "x": 1, "y": 1 }, + { "row": 1, "col": 4, "x": 2, "y": 1.25 }, + { "row": 1, "col": 5, "x": 6, "y": 1.25 }, + { "row": 1, "col": 6, "x": 7, "y": 1 }, + { "row": 1, "col": 7, "x": 8, "y": 0.75 }, + { "row": 1, "col": 8, "x": 9, "y": 1 }, + { "row": 1, "col": 9, "x": 10, "y": 1.5 }, + + { "row": 2, "col": 0, "x": -2, "y": 2.75 }, + { "row": 2, "col": 1, "x": -1, "y": 2 }, + { "row": 2, "col": 2, "x": 0, "y": 1.75 }, + { "row": 2, "col": 3, "x": 1, "y": 2 }, + { "row": 2, "col": 4, "x": 2, "y": 2.25 }, + { "row": 2, "col": 5, "x": 6, "y": 2.25 }, + { "row": 2, "col": 6, "x": 7, "y": 2 }, + { "row": 2, "col": 7, "x": 8, "y": 1.75 }, + { "row": 2, "col": 8, "x": 9, "y": 2 }, + { "row": 2, "col": 9, "x": 10, "y": 2.5 }, + + { "row": 3, "col": 3, "x": 0.5, "y": 3.75, "r": 15, "rx": 2.98, "ry": 8.395 }, + { "row": 3, "col": 4, "x": 0.75, "y": 3.5, "r": 30, "rx": 1.73, "ry": 7.895 }, + { "row": 3, "col": 5, "x": 7.75, "y": 4, "r": -30, "rx": 6.48, "ry": 9.145 }, + { "row": 3, "col": 6, "x": 7.5, "y": 3.57, "r": -15, "rx": 6.73, "ry": 8.395 } + ] + } + }, + "sensors": [] +} diff --git a/zmk/urchin.keymap b/zmk/urchin.keymap new file mode 100644 index 00000000..83c8a774 --- /dev/null +++ b/zmk/urchin.keymap @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020 duckyb + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include "keymap_italian.h" + +// Layer definitions +#define BASE 0 +#define SYM 1 +#define EXT 2 +#define FNC 3 +#define SYM2 4 +#define ACCENT 5 +#define SETTINGS 6 +// ----------------- + +&sk { + // don't release mods on other mods presses + ignore-modifiers; +}; + + +/ { + behaviors { + // Enables holding the first mod-tap key + // by performing a tap-release-hold sequence. + // To use it: "&qt KEYCODE1 KEYCODE2" + qt: quick_tap { + compatible = "zmk,behavior-hold-tap"; + label = "QUICK_TAP"; + #binding-cells = <2>; + flavor = "hold-preferred"; + tapping-term-ms = <200>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + }; + }; + + macros { + // sometimes my device thinks a modifier is being held down + // pressing all modifiers fixes it. + unstick: unstick { + label = "ZM_unstick"; + compatible = "zmk,behavior-macro"; + #binding-cells = <0>; + bindings = <&kp LSHIFT &kp RSHIFT &kp LCTRL &kp RCTRL &kp LALT &kp RALT &kp LGUI &kp RGUI>; + }; + }; + + combos { + compatible = "zmk,combos"; + // both right thumb keys + combo_accent { + timeout-ms = <200>; + key-positions = <32 33>; + bindings = <&mo ACCENT>; + }; + // internal-left & external-right thumb keys + combo_sym2 { + timeout-ms = <200>; + key-positions = <31 33>; + bindings = <&mo SYM2>; + }; + // both left thumb keys + combo_settings { + timeout-ms = <200>; + key-positions = <30 31>; + bindings = <&mo SETTINGS>; + }; + // left index & middle fingers (home-row) + // hold control & space for Adobe workflow + combo_ctrl_space { + timeout-ms = <200>; + key-positions = <12 13>; + bindings = <&kp LC(SPACE)>; + layers = ; + }; + }; + + keymap { + compatible = "zmk,keymap"; + // Base alpha layer + default_layer { + label = "Base"; + bindings = < + &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P + &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp IT_OGRV + &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp IT_UGRV + &mo EXT &qt LSHIFT SPACE &kp SPACE &sl SYM + >; + }; + + // Numbers and high frequency symbols + sym_layer { + label = "Sym."; + bindings = < + &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 + &kp IT_LESS &kp IT_USD &kp IT_LPAR &kp IT_LBRC &kp IT_LBKT &kp IT_EQL &kp IT_QUES &kp IT_SQUOT &kp IT_MINUS &kp IT_AST + &kp IT_GREAT &kp IT_PERC &kp IT_RPAR &kp IT_RBRC &kp IT_RBKT &kp IT_AT &kp IT_EXCL &kp IT_DQUOT &kp IT_PLUS &kp IT_FSLH + &mo FNC &mo SYM2 &trans &trans + >; + }; + + // Main modifiers and arrow keys + ext_layer { + label = "Mods"; + bindings = < + &kp ESC &kp C_PREV &kp C_PP &kp C_NEXT &kp C_PAUSE &kp PG_UP &kp HOME &kp UP &kp END &kp CAPS + &sk LALT &sk LGUI &sk LSHIFT &sk LCTRL &kp RALT &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp DEL + &kp LC(Z) &kp LC(X) &kp LC(C) &kp TAB &kp LC(V) &kp LC(BSPC) &kp BSPC &trans &trans &trans + &trans &kp LCTRL &kp ENTER &mo FNC + >; + }; + + // Function keys with modifiers + fnc_layer { + label = "FRow"; + bindings = < + &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 + &sk LALT &sk LGUI &sk LSHIFT &sk LCTRL &kp RALT &kp F11 &kp F12 &kp PRINTSCREEN &trans &trans + &none &none &none &none &none &none &none &none &none &none + &none &none &none &none + >; + }; + + // Low frequency symbols. + symbols_2_layer { + label = "Sym.2"; + bindings = < + &kp IT_CARET &kp IT_UNDER &kp IT_PND &kp IT_EUR &kp IT_HASH &none &none &none &none &none + &kp IT_BKTK &kp IT_TILDE &kp IT_BSLH &kp IT_PIPE &kp IT_AND &none &none &none &none &none + &none &none &kp IT_SECT &kp IT_CCED &kp IT_DEG &none &none &none &none &none + &none &none &none &none + >; + }; + + // Used to type regional accents. + accent_layer { + label = "Accent"; + bindings = < + &none &none &none &kp IT_CEGR &none &none &none &none &none &none + &kp IT_AGRV &kp IT_IGRV &kp IT_OGRV &kp IT_EGRV &kp IT_EACU &none &none &none &none &none + &none &none &none &kp IT_UGRV &none &none &none &none &none &none + &none &none &none &none + >; + }; + + // Used to change the keyboard's settings. + settings_layer { + label = "Sett."; + bindings = < + &bootloader &none &none &bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 3 &none &unstick &none &bootloader + &none &none &none &none &bt BT_SEL 1 &bt BT_SEL 4 &none &none &none &none + &studio_unlock &none &none &none &bt BT_SEL 2 &bt BT_SEL 5 &none &none &none &studio_unlock + &none &none &none &none + >; + }; + }; +}; diff --git a/zmk/west.yml b/zmk/west.yml new file mode 100644 index 00000000..b55dacd9 --- /dev/null +++ b/zmk/west.yml @@ -0,0 +1,27 @@ +manifest: + remotes: + # zmk official + - name: zmkfirmware + url-base: https://github.com/zmkfirmware + # bravekarma + - name: caksoylar + url-base: https://github.com/caksoylar + # kyek / duckyb + - name: duckyb + url-base: https://github.com/duckyb + # nice-view-gem + - name: m165437 + url-base: https://github.com/M165437 + projects: + - name: zmk + remote: zmkfirmware + revision: v0.3.0 + import: app/west.yml + - name: urchin-zmk-module + remote: duckyb + revision: main + - name: nice-view-gem + remote: m165437 + revision: main + self: + path: config From 9af02cb0e670bc9b997089201108f2a89d3e764c Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 19 Jan 2026 17:50:00 +0800 Subject: [PATCH 02/13] chore(zmk): reset to current config --- zmk/urchin.keymap | 168 +++++++--------------------------------------- 1 file changed, 23 insertions(+), 145 deletions(-) diff --git a/zmk/urchin.keymap b/zmk/urchin.keymap index 83c8a774..c9bec645 100644 --- a/zmk/urchin.keymap +++ b/zmk/urchin.keymap @@ -1,165 +1,43 @@ -/* - * Copyright (c) 2020 duckyb - * - * SPDX-License-Identifier: MIT - */ - #include #include -#include #include #include "keymap_italian.h" -// Layer definitions -#define BASE 0 -#define SYM 1 -#define EXT 2 -#define FNC 3 -#define SYM2 4 -#define ACCENT 5 -#define SETTINGS 6 -// ----------------- - -&sk { - // don't release mods on other mods presses - ignore-modifiers; -}; - +// template { +// bindings = < +// &none &none &none &none &none &none &none &none &none &none +// &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL +// &none &none &none &none &none &none &none &none &none &none +// &none &none &none &none +// >; */ +// }; */ / { - behaviors { - // Enables holding the first mod-tap key - // by performing a tap-release-hold sequence. - // To use it: "&qt KEYCODE1 KEYCODE2" - qt: quick_tap { - compatible = "zmk,behavior-hold-tap"; - label = "QUICK_TAP"; - #binding-cells = <2>; - flavor = "hold-preferred"; - tapping-term-ms = <200>; - quick-tap-ms = <200>; - bindings = <&kp>, <&kp>; - }; - }; - - macros { - // sometimes my device thinks a modifier is being held down - // pressing all modifiers fixes it. - unstick: unstick { - label = "ZM_unstick"; - compatible = "zmk,behavior-macro"; - #binding-cells = <0>; - bindings = <&kp LSHIFT &kp RSHIFT &kp LCTRL &kp RCTRL &kp LALT &kp RALT &kp LGUI &kp RGUI>; - }; - }; - - combos { - compatible = "zmk,combos"; - // both right thumb keys - combo_accent { - timeout-ms = <200>; - key-positions = <32 33>; - bindings = <&mo ACCENT>; - }; - // internal-left & external-right thumb keys - combo_sym2 { - timeout-ms = <200>; - key-positions = <31 33>; - bindings = <&mo SYM2>; - }; - // both left thumb keys - combo_settings { - timeout-ms = <200>; - key-positions = <30 31>; - bindings = <&mo SETTINGS>; - }; - // left index & middle fingers (home-row) - // hold control & space for Adobe workflow - combo_ctrl_space { - timeout-ms = <200>; - key-positions = <12 13>; - bindings = <&kp LC(SPACE)>; - layers = ; - }; - }; - keymap { compatible = "zmk,keymap"; - // Base alpha layer - default_layer { - label = "Base"; + layer_0 { bindings = < - &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P - &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp IT_OGRV - &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp IT_UGRV - &mo EXT &qt LSHIFT SPACE &kp SPACE &sl SYM + &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P + &mt LCTRL A &mt LGUI S &mt LALT D &mt LSHIFT F &kp G &kp H &mt RSHIFT J &mt RALT K &mt RGUI L &mt RCTRL SEMICOLON + &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH + &none < 1 SPACE < 2 BACKSPACE &none >; }; - - // Numbers and high frequency symbols - sym_layer { - label = "Sym."; - bindings = < - &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 - &kp IT_LESS &kp IT_USD &kp IT_LPAR &kp IT_LBRC &kp IT_LBKT &kp IT_EQL &kp IT_QUES &kp IT_SQUOT &kp IT_MINUS &kp IT_AST - &kp IT_GREAT &kp IT_PERC &kp IT_RPAR &kp IT_RBRC &kp IT_RBKT &kp IT_AT &kp IT_EXCL &kp IT_DQUOT &kp IT_PLUS &kp IT_FSLH - &mo FNC &mo SYM2 &trans &trans - >; - }; - - // Main modifiers and arrow keys - ext_layer { - label = "Mods"; - bindings = < - &kp ESC &kp C_PREV &kp C_PP &kp C_NEXT &kp C_PAUSE &kp PG_UP &kp HOME &kp UP &kp END &kp CAPS - &sk LALT &sk LGUI &sk LSHIFT &sk LCTRL &kp RALT &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp DEL - &kp LC(Z) &kp LC(X) &kp LC(C) &kp TAB &kp LC(V) &kp LC(BSPC) &kp BSPC &trans &trans &trans - &trans &kp LCTRL &kp ENTER &mo FNC - >; - }; - - // Function keys with modifiers - fnc_layer { - label = "FRow"; - bindings = < - &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 - &sk LALT &sk LGUI &sk LSHIFT &sk LCTRL &kp RALT &kp F11 &kp F12 &kp PRINTSCREEN &trans &trans - &none &none &none &none &none &none &none &none &none &none - &none &none &none &none - >; - }; - - // Low frequency symbols. - symbols_2_layer { - label = "Sym.2"; + layer_1 { bindings = < - &kp IT_CARET &kp IT_UNDER &kp IT_PND &kp IT_EUR &kp IT_HASH &none &none &none &none &none - &kp IT_BKTK &kp IT_TILDE &kp IT_BSLH &kp IT_PIPE &kp IT_AND &none &none &none &none &none - &none &none &kp IT_SECT &kp IT_CCED &kp IT_DEG &none &none &none &none &none - &none &none &none &none + &none &none &none &none &none &none &none &none &none &none + &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL + &none &none &none &none &none &none &none &none &none &none + &none &none &none &none >; }; - - // Used to type regional accents. - accent_layer { - label = "Accent"; + layer_2 { bindings = < - &none &none &none &kp IT_CEGR &none &none &none &none &none &none - &kp IT_AGRV &kp IT_IGRV &kp IT_OGRV &kp IT_EGRV &kp IT_EACU &none &none &none &none &none - &none &none &none &kp IT_UGRV &none &none &none &none &none &none - &none &none &none &none + &none &none &none &none &none &none &none &none &none &none + &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL + &none &none &none &none &none &none &none &none &none &none + &none &kp TAB &none &none >; }; - - // Used to change the keyboard's settings. - settings_layer { - label = "Sett."; - bindings = < - &bootloader &none &none &bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 3 &none &unstick &none &bootloader - &none &none &none &none &bt BT_SEL 1 &bt BT_SEL 4 &none &none &none &none - &studio_unlock &none &none &none &bt BT_SEL 2 &bt BT_SEL 5 &none &none &none &studio_unlock - &none &none &none &none - >; - }; }; }; From 75df13ba08bc26fb65e05f3d20429d76cd52f317 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 19 Jan 2026 17:55:18 +0800 Subject: [PATCH 03/13] amend workflow vars --- .github/workflows/build-zmk-firmware.yml | 30 +++++++++++++++++------- {zmk => urchin}/build.yaml | 0 {zmk => urchin}/keymap_italian.h | 0 {zmk => urchin}/urchin.conf | 0 {zmk => urchin}/urchin.json | 0 {zmk => urchin}/urchin.keymap | 0 {zmk => urchin}/west.yml | 0 7 files changed, 21 insertions(+), 9 deletions(-) rename {zmk => urchin}/build.yaml (100%) rename {zmk => urchin}/keymap_italian.h (100%) rename {zmk => urchin}/urchin.conf (100%) rename {zmk => urchin}/urchin.json (100%) rename {zmk => urchin}/urchin.keymap (100%) rename {zmk => urchin}/west.yml (100%) diff --git a/.github/workflows/build-zmk-firmware.yml b/.github/workflows/build-zmk-firmware.yml index f0819ae3..6b78435e 100644 --- a/.github/workflows/build-zmk-firmware.yml +++ b/.github/workflows/build-zmk-firmware.yml @@ -2,6 +2,12 @@ name: Reusable user config build on: [push, pull_request, workflow_dispatch] +env: + BUILD_MATRIX_PATH: "urchin/build.yaml" + CONFIG_PATH: "urchin" + FALLBACK_BINARY: "bin" + ARCHIVE_NAME: "firmware" + jobs: matrix: runs-on: ubuntu-22.04 @@ -14,8 +20,8 @@ jobs: - name: Fetch Build Matrix run: | - echo "build_matrix=$(yq -oj -I0 'zmk/build.yaml')" >> $GITHUB_ENV - yq -oj "zmk/build.yaml" + echo "build_matrix=$(yq -oj -I0 '${{ env.BUILD_MATRIX_PATH }}')" >> $GITHUB_ENV + yq -oj "${{ env.BUILD_MATRIX_PATH }}" build: runs-on: ubuntu-latest @@ -27,6 +33,12 @@ jobs: fail-fast: false matrix: ${{ fromJson(needs.matrix.outputs.build_matrix) }} steps: + - name: Act Workaround # https://github.com/nektos/act/issues/973 + if: ${{ env.ACT }} + run: | + apt-get update && apt-get install -y curl unzip + curl -fsSL https://deb.nodesource.com/setup_22.x | bash && apt install -y nodejs + - name: Checkout uses: actions/checkout@v4 @@ -64,8 +76,8 @@ jobs: - name: Copy config files to isolated temporary directory run: | if [ "${{ env.base_dir }}" != "${GITHUB_WORKSPACE}" ]; then - mkdir "${{ env.base_dir }}/zmk" - cp -R zmk/* "${{ env.base_dir }}/zmk/" + mkdir "${{ env.base_dir }}/${{ env.CONFIG_PATH }}" + cp -R ${{ env.CONFIG_PATH }}/* "${{ env.base_dir }}/${{ env.CONFIG_PATH }}/" fi - name: Cache west modules @@ -88,7 +100,7 @@ jobs: - name: West Init working-directory: ${{ env.base_dir }} - run: west init -l "${{ env.base_dir }}/zmk" + run: west init -l "${{ env.base_dir }}/${{ env.CONFIG_PATH }}" - name: West Update working-directory: ${{ env.base_dir }} @@ -108,7 +120,7 @@ jobs: - name: West Build (${{ env.display_name }}) working-directory: ${{ env.base_dir }} shell: sh -x {0} - run: west build -s zmk/app -d "${{ env.build_dir }}" -b "${{ matrix.board }}" ${{ env.extra_west_args }} -- -DZMK_CONFIG=${{ env.base_dir }}/zmk ${{ env.extra_cmake_args }} ${{ matrix.cmake-args }} + run: west build -s zmk/app -d "${{ env.build_dir }}" -b "${{ matrix.board }}" ${{ env.extra_west_args }} -- -DZMK_CONFIG=${{ env.base_dir }}/${{ env.CONFIG_PATH }} ${{ env.extra_cmake_args }} ${{ matrix.cmake-args }} - name: Warn about building from main if build fails if: failure() && env.zmk_revision == 'main' @@ -149,9 +161,9 @@ jobs: if [ -f "${{ env.build_dir }}/zephyr/zmk.uf2" ] then cp "${{ env.build_dir }}/zephyr/zmk.uf2" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.uf2" - elif [ -f "${{ env.build_dir }}/zephyr/zmk.bin" ] + elif [ -f "${{ env.build_dir }}/zephyr/zmk.${{ env.FALLBACK_BINARY }}" ] then - cp "${{ env.build_dir }}/zephyr/zmk.bin" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.bin" + cp "${{ env.build_dir }}/zephyr/zmk.${{ env.FALLBACK_BINARY }}" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.${{ env.FALLBACK_BINARY }}" fi - name: Archive (${{ env.display_name }}) @@ -168,6 +180,6 @@ jobs: - name: Merge Artifacts uses: actions/upload-artifact/merge@v4 with: - name: firmware + name: ${{ env.ARCHIVE_NAME }} pattern: artifact-* delete-merged: true diff --git a/zmk/build.yaml b/urchin/build.yaml similarity index 100% rename from zmk/build.yaml rename to urchin/build.yaml diff --git a/zmk/keymap_italian.h b/urchin/keymap_italian.h similarity index 100% rename from zmk/keymap_italian.h rename to urchin/keymap_italian.h diff --git a/zmk/urchin.conf b/urchin/urchin.conf similarity index 100% rename from zmk/urchin.conf rename to urchin/urchin.conf diff --git a/zmk/urchin.json b/urchin/urchin.json similarity index 100% rename from zmk/urchin.json rename to urchin/urchin.json diff --git a/zmk/urchin.keymap b/urchin/urchin.keymap similarity index 100% rename from zmk/urchin.keymap rename to urchin/urchin.keymap diff --git a/zmk/west.yml b/urchin/west.yml similarity index 100% rename from zmk/west.yml rename to urchin/west.yml From 840012b1e9a182dc0600d4ef3b3155449c4d3616 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 19 Jan 2026 18:08:17 +0800 Subject: [PATCH 04/13] add combnos --- urchin/urchin.keymap | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/urchin/urchin.keymap b/urchin/urchin.keymap index c9bec645..d7dc7305 100644 --- a/urchin/urchin.keymap +++ b/urchin/urchin.keymap @@ -12,7 +12,34 @@ // >; */ // }; */ +&mt { + flavor = "tap-preferred"; +}; + / { + combos { + compatible = "zmk,combos"; + combo_left_return { + timeout-ms = <50>; + key-positions = <11 12>; + bindings = <&kp RETURN>; + }; + combo_left_esc { + timeout-ms = <50>; + key-positions = <10 11 12 13>; + bindings = <&kp ESC>; + }; + combo_right_return { + timeout-ms = <50>; + key-positions = <17 18>; + bindings = <&kp RETURN>; + }; + combo_right_esc { + timeout-ms = <50>; + key-positions = <16 17 18 19>; + bindings = <&kp ESC>; + }; + }; keymap { compatible = "zmk,keymap"; layer_0 { From 142361f8052e64cd5f6a51523f9a8dfb8aa75e93 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 19 Jan 2026 18:34:21 +0800 Subject: [PATCH 05/13] add sym --- urchin/keymap_italian.h | 122 ---------------------------------------- urchin/urchin.keymap | 44 +++++++-------- 2 files changed, 21 insertions(+), 145 deletions(-) delete mode 100644 urchin/keymap_italian.h diff --git a/urchin/keymap_italian.h b/urchin/keymap_italian.h deleted file mode 100644 index 1587d84f..00000000 --- a/urchin/keymap_italian.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * This file includes custom keycodes for the italian input language setting. - * If you only type in english, you can delete this file and it's import. - * If you wish to replace this file with your preferred language, use - * the qmk version as reference: - * https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras -*/ - - -/* - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ \ │ │ │ │ │ │ │ │ │ │ │ ' │ ì │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ è │ + │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ │ │ │ │ │ │ │ │ │ ò │ à │ ù │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ < │ │ │ │ │ │ │ │ , │ . │ - │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 1 -#define IT_BSLH GRAVE // backslash -#define IT_SQUOT MINUS // ' -#define IT_IGRV EQUAL // ì -// Row 2 -#define IT_EGRV LBKT // è -#define IT_PLUS SLASH // + -// Row 3 -#define IT_OGRV SEMI // ò -#define IT_AGRV APOS // à -#define IT_UGRV NON_US_HASH // ù -// Row 4 -#define IT_LESS NON_US_BSLH // < -#define IT_MINUS RBKT // - - -/* Shifted symbols - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ | │ ! │ " │ £ │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ^ │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ é │ * │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ │ │ │ │ │ │ │ │ │ ç │ ° │ § │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ > │ │ │ │ │ │ │ │ ; │ : │ _ │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 1 -#define IT_PIPE LS(GRAVE) // | -#define IT_EXCL LS(N1) // ! -#define IT_DQUOT LS(N2) // " -#define IT_PND LS(N3) // £ -#define IT_USD LS(N4) // $ -#define IT_PERC LS(N5) // % -#define IT_AND LS(N6) // & -#define IT_FSLH LS(N7) // / -#define IT_LPAR LS(N8) // ( -#define IT_RPAR LS(N9) // ) -#define IT_EQL LS(N0) // = -#define IT_QUES LS(MINUS) // ? -#define IT_CARET LS(EQUAL) // ^ -// Row 2 -#define IT_EACU LS(LBKT) // é -#define IT_AST LS(RBKT) // * -// Row 3 -#define IT_CCED LS(SEMI) // ç -#define IT_DEG LS(APOS) // ° -#define IT_SECT LS(NON_US_HASH) // § -// Row 4 -#define IT_GREAT LS(NON_US_BSLH) // > -#define IT_UNDER LS(SLASH) // _ - -/* AltGr symbols - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ € │ │ │ │ │ │ │ │ [ │ ] │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ │ │ │ │ │ │ │ │ │ @ │ # │ │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 2 -#define IT_EUR RA(E) // € -#define IT_LBKT RA(LBKT) // [ -#define IT_RBKT RA(RBKT) // ] -// Row 3 -#define IT_AT RA(SEMI) // @ -#define IT_HASH RA(APOS) // # - -/* Shift+AltGr symbols - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ { │ } │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 2 -#define IT_LBRC LS(RA(LBKT)) // { -#define IT_RBRC LS(RA(RBKT)) // } - -/** - * Personalized symbols. - * - * These symbols are not part of the default italian input. - * I use a custom windows keymap to input them. -*/ -#define IT_BKTK RA(MINUS) // ` -#define IT_TILDE RA(EQUAL) // ~ -#define IT_CEGR RA(LS(E)) // È diff --git a/urchin/urchin.keymap b/urchin/urchin.keymap index d7dc7305..efd80df5 100644 --- a/urchin/urchin.keymap +++ b/urchin/urchin.keymap @@ -1,16 +1,5 @@ #include #include -#include -#include "keymap_italian.h" - -// template { -// bindings = < -// &none &none &none &none &none &none &none &none &none &none -// &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL -// &none &none &none &none &none &none &none &none &none &none -// &none &none &none &none -// >; */ -// }; */ &mt { flavor = "tap-preferred"; @@ -44,27 +33,36 @@ compatible = "zmk,keymap"; layer_0 { bindings = < - &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P - &mt LCTRL A &mt LGUI S &mt LALT D &mt LSHIFT F &kp G &kp H &mt RSHIFT J &mt RALT K &mt RGUI L &mt RCTRL SEMICOLON - &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH - &none < 1 SPACE < 2 BACKSPACE &none + &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P + &mt LCTRL A &mt LGUI S &mt LALT D &mt LSHIFT F &kp G &kp H &mt RSHIFT J &mt RALT K &mt RGUI L &mt RCTRL SEMICOLON + &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH + &none < 1 SPACE < 2 BACKSPACE &none >; }; layer_1 { bindings = < - &none &none &none &none &none &none &none &none &none &none - &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL - &none &none &none &none &none &none &none &none &none &none - &none &none &none &none + &none &none &none &none &none &kp HOME &kp PG_DN &kp PG_UP &kp END &kp DEL + &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL + &none &none &none &none &none &none &none &none &none &kp INS + &none &none &none &none >; }; layer_2 { bindings = < - &none &none &none &none &none &none &none &none &none &none - &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL - &none &none &none &none &none &none &none &none &none &none - &none &kp TAB &none &none + &kp NUMBER_1 &kp NUMBER_2 &kp NUMBER_3 &kp NUMBER_4 &kp NUMBER_5 &kp NUMBER_6 &kp NUMBER_7 &kp NUMBER_8 &kp NUMBER_9 &kp NUMBER_0 + &kp LCTRL &kp LGUI &kp LALT &mt LSHIFT LBKT &kp RBKT &kp PIPE &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL + &kp LS(N9) &kp LS(N0) &kp EQUAL &kp PLUS &kp MINUS &kp BACKSLASH &kp SINGLE_QUOTE &kp DOUBLE_QUOTES &kp TILDE &kp GRAVE + &none &kp TAB &none &none >; }; }; }; + +// template { +// bindings = < +// &none &none &none &none &none &none &none &none &none &none +// &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &none &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL +// &none &none &none &none &none &none &none &none &none &none +// &none &none &none &none +// >; +// }; */ From ddb7d0e998d60482d2404765553b019baeb7a6d2 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 19 Jan 2026 18:55:14 +0800 Subject: [PATCH 06/13] add layers 3 and 4 --- urchin/urchin.keymap | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/urchin/urchin.keymap b/urchin/urchin.keymap index efd80df5..2a25e57f 100644 --- a/urchin/urchin.keymap +++ b/urchin/urchin.keymap @@ -44,7 +44,7 @@ &none &none &none &none &none &kp HOME &kp PG_DN &kp PG_UP &kp END &kp DEL &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL &none &none &none &none &none &none &none &none &none &kp INS - &none &none &none &none + &none &none &mo 3 &none >; }; layer_2 { @@ -52,7 +52,23 @@ &kp NUMBER_1 &kp NUMBER_2 &kp NUMBER_3 &kp NUMBER_4 &kp NUMBER_5 &kp NUMBER_6 &kp NUMBER_7 &kp NUMBER_8 &kp NUMBER_9 &kp NUMBER_0 &kp LCTRL &kp LGUI &kp LALT &mt LSHIFT LBKT &kp RBKT &kp PIPE &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL &kp LS(N9) &kp LS(N0) &kp EQUAL &kp PLUS &kp MINUS &kp BACKSLASH &kp SINGLE_QUOTE &kp DOUBLE_QUOTES &kp TILDE &kp GRAVE - &none &kp TAB &none &none + &none < 3 TAB &none &none + >; + }; + layer_3 { + bindings = < + &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 + &kp LCTRL &kp LGUI &mt LALT F11 &kp LSHIFT &none &tog 4 &kp RSHIFT &mt RALT F12 &kp RGUI &kp RCTRL + &none &none &none &none &none &none &none &none &none &none + &none &none &none &none + >; + }; + layer_4 { + bindings = < + &kp LALT &kp Q &kp W &kp E &kp R &none &none &none &none &none + &kp LSHIFT &kp A &kp S &kp D &kp F &none &none &none &none &none + &kp LCTRL &kp Z &kp X &kp C &kp V &none &none &none &none &none + &kp ESC &kp SPACE &tog 4 &none >; }; }; From 99622d188571bbfe84d800f100e8489b886d7fee Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Tue, 20 Jan 2026 17:02:01 +0800 Subject: [PATCH 07/13] fix: amend left right bracket --- urchin/urchin.keymap | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/urchin/urchin.keymap b/urchin/urchin.keymap index 2a25e57f..c77dc756 100644 --- a/urchin/urchin.keymap +++ b/urchin/urchin.keymap @@ -33,42 +33,42 @@ compatible = "zmk,keymap"; layer_0 { bindings = < - &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P - &mt LCTRL A &mt LGUI S &mt LALT D &mt LSHIFT F &kp G &kp H &mt RSHIFT J &mt RALT K &mt RGUI L &mt RCTRL SEMICOLON - &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH - &none < 1 SPACE < 2 BACKSPACE &none + &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P + &mt LCTRL A &mt LGUI S &mt LALT D &mt LSHIFT F &kp G &kp H &mt RSHIFT J &mt RALT K &mt RGUI L &mt RCTRL SEMICOLON + &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH + &none < 1 SPACE < 2 BACKSPACE &none >; }; layer_1 { bindings = < - &none &none &none &none &none &kp HOME &kp PG_DN &kp PG_UP &kp END &kp DEL - &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL - &none &none &none &none &none &none &none &none &none &kp INS - &none &none &mo 3 &none + &none &none &none &none &none &kp HOME &kp PG_DN &kp PG_UP &kp END &kp DEL + &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL + &none &none &none &none &none &none &none &none &none &kp INS + &none &none &mo 3 &none >; }; layer_2 { bindings = < - &kp NUMBER_1 &kp NUMBER_2 &kp NUMBER_3 &kp NUMBER_4 &kp NUMBER_5 &kp NUMBER_6 &kp NUMBER_7 &kp NUMBER_8 &kp NUMBER_9 &kp NUMBER_0 - &kp LCTRL &kp LGUI &kp LALT &mt LSHIFT LBKT &kp RBKT &kp PIPE &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL - &kp LS(N9) &kp LS(N0) &kp EQUAL &kp PLUS &kp MINUS &kp BACKSLASH &kp SINGLE_QUOTE &kp DOUBLE_QUOTES &kp TILDE &kp GRAVE - &none < 3 TAB &none &none + &kp NUMBER_1 &kp NUMBER_2 &kp NUMBER_3 &kp NUMBER_4 &kp NUMBER_5 &kp NUMBER_6 &kp NUMBER_7 &kp NUMBER_8 &kp NUMBER_9 &kp NUMBER_0 + &kp LCTRL &kp LGUI &mt LALT LBKT &mt LSHIFT RBKT &none &kp PIPE &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL + &kp LS(N9) &kp LS(N0) &kp EQUAL &kp PLUS &kp MINUS &kp BACKSLASH &kp SINGLE_QUOTE &kp DOUBLE_QUOTES &kp TILDE &kp GRAVE + &none < 3 TAB &none &none >; }; layer_3 { bindings = < - &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 - &kp LCTRL &kp LGUI &mt LALT F11 &kp LSHIFT &none &tog 4 &kp RSHIFT &mt RALT F12 &kp RGUI &kp RCTRL - &none &none &none &none &none &none &none &none &none &none - &none &none &none &none + &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 + &kp LCTRL &kp LGUI &mt LALT F11 &kp LSHIFT &none &tog 4 &kp RSHIFT &mt RALT F12 &kp RGUI &kp RCTRL + &none &none &none &none &none &none &none &none &none &none + &none &none &none &none >; }; layer_4 { bindings = < - &kp LALT &kp Q &kp W &kp E &kp R &none &none &none &none &none - &kp LSHIFT &kp A &kp S &kp D &kp F &none &none &none &none &none - &kp LCTRL &kp Z &kp X &kp C &kp V &none &none &none &none &none - &kp ESC &kp SPACE &tog 4 &none + &kp LALT &kp Q &kp W &kp E &kp R &none &none &none &none &none + &kp LSHIFT &kp A &kp S &kp D &kp F &none &none &none &none &none + &kp LCTRL &kp Z &kp X &kp C &kp V &none &none &none &none &none + &kp ESC &kp SPACE &tog 4 &none >; }; }; @@ -76,9 +76,9 @@ // template { // bindings = < -// &none &none &none &none &none &none &none &none &none &none -// &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &none &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL -// &none &none &none &none &none &none &none &none &none &none -// &none &none &none &none +// &none &none &none &none &none &none &none &none &none &none +// &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &none &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL +// &none &none &none &none &none &none &none &none &none &none +// &none &none &none &none // >; // }; */ From 37a14b2ac48ade4bc91a8c0690f23875363f71cf Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Fri, 23 Jan 2026 13:21:19 +0800 Subject: [PATCH 08/13] add alt esc caps gui return and move num/fn to homerow --- urchin/urchin.keymap | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/urchin/urchin.keymap b/urchin/urchin.keymap index c77dc756..e9171b7f 100644 --- a/urchin/urchin.keymap +++ b/urchin/urchin.keymap @@ -36,7 +36,7 @@ &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &mt LCTRL A &mt LGUI S &mt LALT D &mt LSHIFT F &kp G &kp H &mt RSHIFT J &mt RALT K &mt RGUI L &mt RCTRL SEMICOLON &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH - &none < 1 SPACE < 2 BACKSPACE &none + &mt LSHIFT ESC < 1 SPACE < 2 BACKSPACE &mt RGUI RETURN >; }; layer_1 { @@ -44,23 +44,23 @@ &none &none &none &none &none &kp HOME &kp PG_DN &kp PG_UP &kp END &kp DEL &kp LCTRL &kp LGUI &kp LALT &kp LSHIFT &none &kp LEFT &mt RSHIFT DOWN &mt RALT UP &mt RGUI RIGHT &kp RCTRL &none &none &none &none &none &none &none &none &none &kp INS - &none &none &mo 3 &none + &mt LSHIFT ESC &none &mo 3 &mt RGUI RETURN >; }; layer_2 { bindings = < - &kp NUMBER_1 &kp NUMBER_2 &kp NUMBER_3 &kp NUMBER_4 &kp NUMBER_5 &kp NUMBER_6 &kp NUMBER_7 &kp NUMBER_8 &kp NUMBER_9 &kp NUMBER_0 - &kp LCTRL &kp LGUI &mt LALT LBKT &mt LSHIFT RBKT &none &kp PIPE &kp RSHIFT &kp RALT &kp RGUI &kp RCTRL + &none &none &kp LBKT &kp RBKT &none &kp PIPE &none &none &none &none + &mt LCTRL N1 &mt LGUI N2 &mt LALT N3 &mt LSHIFT N4 &kp N5 &kp N6 &mt RSHIFT N7 &mt RALT N8 &mt RGUI N9 &kp N0 &kp LS(N9) &kp LS(N0) &kp EQUAL &kp PLUS &kp MINUS &kp BACKSLASH &kp SINGLE_QUOTE &kp DOUBLE_QUOTES &kp TILDE &kp GRAVE - &none < 3 TAB &none &none + &mt LSHIFT ESC &kp TAB &none &mt RGUI RETURN >; }; layer_3 { bindings = < - &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 - &kp LCTRL &kp LGUI &mt LALT F11 &kp LSHIFT &none &tog 4 &kp RSHIFT &mt RALT F12 &kp RGUI &kp RCTRL &none &none &none &none &none &none &none &none &none &none - &none &none &none &none + &mt LCTRL F1 &mt LGUI F2 &mt LALT F3 &mt LSHIFT F4 &kp F5 &kp F6 &mt RSHIFT F7 &mt RALT F8 &mt RGUI F9 &kp F10 + &none &none &kp F11 &none &none &none &none &kp F12 &none &tog 4 + &mt LSHIFT ESC &none &none &mt RGUI RETURN >; }; layer_4 { From 3d0cd4fd6bf8f2271d35a587ee91e0215811432c Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Fri, 6 Feb 2026 16:42:12 +0800 Subject: [PATCH 09/13] chore(zmk): rename to zmk-config --- .github/workflows/build-zmk-firmware.yml | 4 ++-- {urchin => zmk-config}/build.yaml | 0 {urchin => zmk-config}/urchin.conf | 0 {urchin => zmk-config}/urchin.json | 0 {urchin => zmk-config}/urchin.keymap | 0 {urchin => zmk-config}/west.yml | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename {urchin => zmk-config}/build.yaml (100%) rename {urchin => zmk-config}/urchin.conf (100%) rename {urchin => zmk-config}/urchin.json (100%) rename {urchin => zmk-config}/urchin.keymap (100%) rename {urchin => zmk-config}/west.yml (100%) diff --git a/.github/workflows/build-zmk-firmware.yml b/.github/workflows/build-zmk-firmware.yml index 6b78435e..7dac3864 100644 --- a/.github/workflows/build-zmk-firmware.yml +++ b/.github/workflows/build-zmk-firmware.yml @@ -3,8 +3,8 @@ name: Reusable user config build on: [push, pull_request, workflow_dispatch] env: - BUILD_MATRIX_PATH: "urchin/build.yaml" - CONFIG_PATH: "urchin" + BUILD_MATRIX_PATH: "zmk-config/build.yaml" + CONFIG_PATH: "zmk-config" FALLBACK_BINARY: "bin" ARCHIVE_NAME: "firmware" diff --git a/urchin/build.yaml b/zmk-config/build.yaml similarity index 100% rename from urchin/build.yaml rename to zmk-config/build.yaml diff --git a/urchin/urchin.conf b/zmk-config/urchin.conf similarity index 100% rename from urchin/urchin.conf rename to zmk-config/urchin.conf diff --git a/urchin/urchin.json b/zmk-config/urchin.json similarity index 100% rename from urchin/urchin.json rename to zmk-config/urchin.json diff --git a/urchin/urchin.keymap b/zmk-config/urchin.keymap similarity index 100% rename from urchin/urchin.keymap rename to zmk-config/urchin.keymap diff --git a/urchin/west.yml b/zmk-config/west.yml similarity index 100% rename from urchin/west.yml rename to zmk-config/west.yml From 44548f59027421e167ca591d313b4a2b4f2ee603 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Fri, 6 Feb 2026 16:49:48 +0800 Subject: [PATCH 10/13] feat(zmk): add volume and media keys --- zmk-config/urchin.keymap | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/zmk-config/urchin.keymap b/zmk-config/urchin.keymap index e9171b7f..c9f8c318 100644 --- a/zmk-config/urchin.keymap +++ b/zmk-config/urchin.keymap @@ -28,6 +28,12 @@ key-positions = <16 17 18 19>; bindings = <&kp ESC>; }; + combo_mute { + timeout-ms = <50>; + key-positions = <8 9>; + bindings = <&kp C_MUTE>; + layers = <3 4>; + }; }; keymap { compatible = "zmk,keymap"; @@ -57,7 +63,7 @@ }; layer_3 { bindings = < - &none &none &none &none &none &none &none &none &none &none + &none &none &none &none &none &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_NEXT &kp C_PLAY_PAUSE &mt LCTRL F1 &mt LGUI F2 &mt LALT F3 &mt LSHIFT F4 &kp F5 &kp F6 &mt RSHIFT F7 &mt RALT F8 &mt RGUI F9 &kp F10 &none &none &kp F11 &none &none &none &none &kp F12 &none &tog 4 &mt LSHIFT ESC &none &none &mt RGUI RETURN @@ -65,7 +71,7 @@ }; layer_4 { bindings = < - &kp LALT &kp Q &kp W &kp E &kp R &none &none &none &none &none + &kp LALT &kp Q &kp W &kp E &kp R &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_NEXT &kp C_PLAY_PAUSE &kp LSHIFT &kp A &kp S &kp D &kp F &none &none &none &none &none &kp LCTRL &kp Z &kp X &kp C &kp V &none &none &none &none &none &kp ESC &kp SPACE &tog 4 &none From 0c316837e1ac47ac98825261866b38e0ae0cf28c Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Fri, 6 Feb 2026 16:56:08 +0800 Subject: [PATCH 11/13] chore(zmk): pin nice-view-gem to 0.3.0 --- zmk-config/west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmk-config/west.yml b/zmk-config/west.yml index b55dacd9..5e6c578d 100644 --- a/zmk-config/west.yml +++ b/zmk-config/west.yml @@ -22,6 +22,6 @@ manifest: revision: main - name: nice-view-gem remote: m165437 - revision: main + revision: v0.3.0 self: path: config From 3f0c15c21d65569a712426050761fdcc85edd128 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Fri, 6 Feb 2026 17:10:51 +0800 Subject: [PATCH 12/13] fix(zmk): make tab activate layer 3 --- zmk-config/urchin.keymap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmk-config/urchin.keymap b/zmk-config/urchin.keymap index c9f8c318..44be38cf 100644 --- a/zmk-config/urchin.keymap +++ b/zmk-config/urchin.keymap @@ -58,7 +58,7 @@ &none &none &kp LBKT &kp RBKT &none &kp PIPE &none &none &none &none &mt LCTRL N1 &mt LGUI N2 &mt LALT N3 &mt LSHIFT N4 &kp N5 &kp N6 &mt RSHIFT N7 &mt RALT N8 &mt RGUI N9 &kp N0 &kp LS(N9) &kp LS(N0) &kp EQUAL &kp PLUS &kp MINUS &kp BACKSLASH &kp SINGLE_QUOTE &kp DOUBLE_QUOTES &kp TILDE &kp GRAVE - &mt LSHIFT ESC &kp TAB &none &mt RGUI RETURN + &mt LSHIFT ESC < 3 TAB &none &mt RGUI RETURN >; }; layer_3 { From 842a60cc137db5a19732a70dd5937bbfa9d7308d Mon Sep 17 00:00:00 2001 From: Lumen Date: Fri, 6 Feb 2026 17:33:01 +0800 Subject: [PATCH 13/13] chore(ci): scope zmk workflow to config Harden the build workflow for zizmor and add act to the gha dev shell. --- .github/workflows/build-zmk-firmware.yml | 125 ++++++++++++++--------- nix/outputs/devShells.nix | 1 + zmk-config/build.yaml | 2 +- 3 files changed, 76 insertions(+), 52 deletions(-) diff --git a/.github/workflows/build-zmk-firmware.yml b/.github/workflows/build-zmk-firmware.yml index 7dac3864..83658260 100644 --- a/.github/workflows/build-zmk-firmware.yml +++ b/.github/workflows/build-zmk-firmware.yml @@ -1,6 +1,16 @@ name: Reusable user config build -on: [push, pull_request, workflow_dispatch] +on: + push: + paths: + - "zmk-config/**" + pull_request: + paths: + - "zmk-config/**" + workflow_dispatch: + +permissions: + contents: read env: BUILD_MATRIX_PATH: "zmk-config/build.yaml" @@ -13,17 +23,22 @@ jobs: runs-on: ubuntu-22.04 name: Fetch Build Keyboards outputs: - build_matrix: ${{ env.build_matrix }} + build_matrix: ${{ env.BUILD_MATRIX }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Fetch Build Matrix run: | - echo "build_matrix=$(yq -oj -I0 '${{ env.BUILD_MATRIX_PATH }}')" >> $GITHUB_ENV - yq -oj "${{ env.BUILD_MATRIX_PATH }}" + echo "BUILD_MATRIX=$(yq -oj -I0 \"${BUILD_MATRIX_PATH}\")" >> "$GITHUB_ENV" + yq -oj "${BUILD_MATRIX_PATH}" build: + permissions: + actions: write + contents: read runs-on: ubuntu-latest container: image: zmkfirmware/zmk-build-arm:stable @@ -40,11 +55,13 @@ jobs: curl -fsSL https://deb.nodesource.com/setup_22.x | bash && apt install -y nodejs - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false - name: Create build directory run: | - echo "build_dir=$(mktemp -d)" >> $GITHUB_ENV + echo "BUILD_DIR=$(mktemp -d)" >> $GITHUB_ENV - name: Prepare variables shell: bash -x {0} @@ -55,43 +72,43 @@ jobs: snippet: ${{ matrix.snippet }} run: | if [ -e zephyr/module.yml ]; then - export zmk_load_arg=" -DZMK_EXTRA_MODULES='${GITHUB_WORKSPACE}'" + zmk_load_arg=" -DZMK_EXTRA_MODULES='${GITHUB_WORKSPACE}'" new_tmp_dir="${TMPDIR:-/tmp}/zmk-config" mkdir -p "${new_tmp_dir}" - echo "base_dir=${new_tmp_dir}" >> $GITHUB_ENV + echo "BASE_DIR=${new_tmp_dir}" >> $GITHUB_ENV else - echo "base_dir=${GITHUB_WORKSPACE}" >> $GITHUB_ENV + echo "BASE_DIR=${GITHUB_WORKSPACE}" >> $GITHUB_ENV fi if [ -n "${snippet}" ]; then extra_west_args="-S \"${snippet}\"" fi - echo "zephyr_version=${ZEPHYR_VERSION}" >> $GITHUB_ENV - echo "extra_west_args=${extra_west_args}" >> $GITHUB_ENV - echo "extra_cmake_args=${shield:+-DSHIELD=\"$shield\"}${zmk_load_arg}" >> $GITHUB_ENV - echo "display_name=${shield:+$shield - }${board}" >> $GITHUB_ENV - echo "artifact_name=${artifact_name:-${shield:+$shield-}${board//\//_}-zmk}" >> $GITHUB_ENV + echo "ZEPHYR_VERSION=${ZEPHYR_VERSION}" >> $GITHUB_ENV + echo "EXTRA_WEST_ARGS=${extra_west_args}" >> $GITHUB_ENV + echo "EXTRA_CMAKE_ARGS=${shield:+-DSHIELD=\"$shield\"}${zmk_load_arg}" >> $GITHUB_ENV + echo "DISPLAY_NAME=${shield:+$shield - }${board}" >> $GITHUB_ENV + echo "ARTIFACT_NAME=${artifact_name:-${shield:+$shield-}${board//\//_}-zmk}" >> $GITHUB_ENV - name: Copy config files to isolated temporary directory run: | - if [ "${{ env.base_dir }}" != "${GITHUB_WORKSPACE}" ]; then - mkdir "${{ env.base_dir }}/${{ env.CONFIG_PATH }}" - cp -R ${{ env.CONFIG_PATH }}/* "${{ env.base_dir }}/${{ env.CONFIG_PATH }}/" + if [ "${BASE_DIR}" != "${GITHUB_WORKSPACE}" ]; then + mkdir "${BASE_DIR}/${CONFIG_PATH}" + cp -R "${CONFIG_PATH}"/* "${BASE_DIR}/${CONFIG_PATH}/" fi - name: Cache west modules - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 continue-on-error: true env: - cache_name: cache-zephyr-${{ env.zephyr_version }}-modules + cache_name: cache-zephyr-${{ env.ZEPHYR_VERSION }}-modules with: path: | - ${{ env.base_dir }}/modules/ - ${{ env.base_dir }}/tools/ - ${{ env.base_dir }}/zephyr/ - ${{ env.base_dir }}/bootloader/ - ${{ env.base_dir }}/zmk/ + ${{ env.BASE_DIR }}/modules/ + ${{ env.BASE_DIR }}/tools/ + ${{ env.BASE_DIR }}/zephyr/ + ${{ env.BASE_DIR }}/bootloader/ + ${{ env.BASE_DIR }}/zmk/ key: ${{ runner.os }}-build-${{ env.cache_name }}-${{ hashFiles('**/west.yml', '**/build.yaml') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache_name }}- @@ -99,28 +116,31 @@ jobs: ${{ runner.os }}- - name: West Init - working-directory: ${{ env.base_dir }} - run: west init -l "${{ env.base_dir }}/${{ env.CONFIG_PATH }}" + working-directory: ${{ env.BASE_DIR }} + run: west init -l "${BASE_DIR}/${CONFIG_PATH}" - name: West Update - working-directory: ${{ env.base_dir }} + working-directory: ${{ env.BASE_DIR }} run: west update --fetch-opt=--filter=tree:0 - name: Check ZMK revision - working-directory: ${{ env.base_dir }} + working-directory: ${{ env.BASE_DIR }} run: | zmk_revision=$(west list -f "{revision}" zmk) echo "zmk_revision=${zmk_revision}" >> $GITHUB_ENV echo "ZMK revision: ${zmk_revision}" - name: West Zephyr export - working-directory: ${{ env.base_dir }} + working-directory: ${{ env.BASE_DIR }} run: west zephyr-export - - name: West Build (${{ env.display_name }}) - working-directory: ${{ env.base_dir }} + - name: West Build (${{ env.DISPLAY_NAME }}) + working-directory: ${{ env.BASE_DIR }} shell: sh -x {0} - run: west build -s zmk/app -d "${{ env.build_dir }}" -b "${{ matrix.board }}" ${{ env.extra_west_args }} -- -DZMK_CONFIG=${{ env.base_dir }}/${{ env.CONFIG_PATH }} ${{ env.extra_cmake_args }} ${{ matrix.cmake-args }} + run: west build -s zmk/app -d "${BUILD_DIR}" -b "${MATRIX_BOARD}" ${EXTRA_WEST_ARGS} -- -DZMK_CONFIG=${BASE_DIR}/${CONFIG_PATH} ${EXTRA_CMAKE_ARGS} ${MATRIX_CMAKE_ARGS} + env: + MATRIX_BOARD: ${{ matrix.board }} + MATRIX_CMAKE_ARGS: ${{ matrix.cmake-args }} - name: Warn about building from main if build fails if: failure() && env.zmk_revision == 'main' @@ -131,24 +151,24 @@ jobs: echo "See also the [list of released versions](https://github.com/zmkfirmware/zmk/releases)." >> $GITHUB_STEP_SUMMARY echo "If you wish to stay on main, check the most recent pending release PR for breaking changes. [Our blog](https://zmk.dev/blog) may have upgrade information if breaking changes are significant." >> $GITHUB_STEP_SUMMARY - - name: ${{ env.display_name }} Kconfig file + - name: ${{ env.DISPLAY_NAME }} Kconfig file run: | - if [ -f "${{ env.build_dir }}/zephyr/.config" ] + if [ -f "${BUILD_DIR}/zephyr/.config" ] then - grep -v -e "^#" -e "^$" "${{ env.build_dir }}/zephyr/.config" | sort + grep -v -e "^#" -e "^$" "${BUILD_DIR}/zephyr/.config" | sort else echo "No Kconfig output" fi if: ${{ !cancelled() }} - - name: ${{ env.display_name }} Devicetree file + - name: ${{ env.DISPLAY_NAME }} Devicetree file run: | - if [ -f "${{ env.build_dir }}/zephyr/zephyr.dts" ] + if [ -f "${BUILD_DIR}/zephyr/zephyr.dts" ] then - cat "${{ env.build_dir }}/zephyr/zephyr.dts" - elif [ -f "${{ env.build_dir }}/zephyr/zephyr.dts.pre" ] + cat "${BUILD_DIR}/zephyr/zephyr.dts" + elif [ -f "${BUILD_DIR}/zephyr/zephyr.dts.pre" ] then - cat -s "${{ env.build_dir }}/zephyr/zephyr.dts.pre" + cat -s "${BUILD_DIR}/zephyr/zephyr.dts.pre" else echo "No Devicetree output" fi @@ -157,28 +177,31 @@ jobs: - name: Rename artifacts shell: sh -x {0} run: | - mkdir "${{ env.build_dir }}/artifacts" - if [ -f "${{ env.build_dir }}/zephyr/zmk.uf2" ] + mkdir "${BUILD_DIR}/artifacts" + if [ -f "${BUILD_DIR}/zephyr/zmk.uf2" ] then - cp "${{ env.build_dir }}/zephyr/zmk.uf2" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.uf2" - elif [ -f "${{ env.build_dir }}/zephyr/zmk.${{ env.FALLBACK_BINARY }}" ] + cp "${BUILD_DIR}/zephyr/zmk.uf2" "${BUILD_DIR}/artifacts/${ARTIFACT_NAME}.uf2" + elif [ -f "${BUILD_DIR}/zephyr/zmk.${FALLBACK_BINARY}" ] then - cp "${{ env.build_dir }}/zephyr/zmk.${{ env.FALLBACK_BINARY }}" "${{ env.build_dir }}/artifacts/${{ env.artifact_name }}.${{ env.FALLBACK_BINARY }}" + cp "${BUILD_DIR}/zephyr/zmk.${FALLBACK_BINARY}" "${BUILD_DIR}/artifacts/${ARTIFACT_NAME}.${FALLBACK_BINARY}" fi - - name: Archive (${{ env.display_name }}) - uses: actions/upload-artifact@v4 + - name: Archive (${{ env.DISPLAY_NAME }}) + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: - name: artifact-${{ env.artifact_name }} - path: ${{ env.build_dir }}/artifacts + name: artifact-${{ env.ARTIFACT_NAME }} + path: ${{ env.BUILD_DIR }}/artifacts merge: + permissions: + actions: write + contents: read runs-on: ubuntu-latest needs: build name: Merge Output Artifacts steps: - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 + uses: actions/upload-artifact/merge@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: ${{ env.ARCHIVE_NAME }} pattern: artifact-* diff --git a/nix/outputs/devShells.nix b/nix/outputs/devShells.nix index 2d890d9f..8e87da39 100644 --- a/nix/outputs/devShells.nix +++ b/nix/outputs/devShells.nix @@ -14,6 +14,7 @@ gha = ciBaseInputs ++ (with pkgs; [ + act gh zizmor ]); diff --git a/zmk-config/build.yaml b/zmk-config/build.yaml index 7515ab2a..42b1b851 100644 --- a/zmk-config/build.yaml +++ b/zmk-config/build.yaml @@ -14,7 +14,7 @@ --- include: - board: nice_nano_v2 - shield: urchin_left nice_view_adapter nice_view_gem + shield: urchin_left nice_view_adapter nice_view_gem snippet: studio-rpc-usb-uart cmake-args: -DCONFIG_ZMK_STUDIO=y - board: nice_nano_v2