From 05132fead8cab4b689b0d9473f3541ed28b3cefd Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Fri, 12 Aug 2022 23:54:21 +0200 Subject: [PATCH 01/28] Create a script to convert keymap_extras/keymap_*.h from qmk_firmware for use in the configurator. --- .../convert_keymap_extras_header.js | 444 ++++++++++++++++++ 1 file changed, 444 insertions(+) create mode 100644 src/i18n/keymap_extras/convert_keymap_extras_header.js diff --git a/src/i18n/keymap_extras/convert_keymap_extras_header.js b/src/i18n/keymap_extras/convert_keymap_extras_header.js new file mode 100644 index 0000000000..e2b27b5512 --- /dev/null +++ b/src/i18n/keymap_extras/convert_keymap_extras_header.js @@ -0,0 +1,444 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +const fs = require('fs'); + +// Taken from https://invisible-characters.com/ +const invisibleChar2readableName = new Map([ + ['\u0009', 'Tab'], + ['\u0020', 'Space'], + ['\u00A0', 'No-break space'], + ['\u00AD', 'Soft hyphen'], + ['\u034F', 'Combining grapheme joiner'], + ['\u061C', 'Arabic letter mark'], + ['\u115F', 'Hangul choseong filler'], + ['\u1160', 'Hangul jungseong filler'], + ['\u17B4', 'Khmer vowel inherent aq'], + ['\u17B5', 'Khmer vowel inherent aa'], + ['\u180E', 'Mongolian vowel separator'], + ['\u2000', 'En quad'], + ['\u2001', 'Em quad'], + ['\u2002', 'En space'], + ['\u2003', 'Em space'], + ['\u2004', 'Three-per-em space'], + ['\u2005', 'Four-per-em space'], + ['\u2006', 'Six-per-em space'], + ['\u2007', 'Figure space'], + ['\u2008', 'Punctuation space'], + ['\u2009', 'Thin space'], + ['\u200A', 'Hair space'], + ['\u200B', 'Zero width space'], + ['\u200C', 'Zero width non-joiner'], + ['\u200D', 'Zero width joiner'], + ['\u200E', 'Left-to-right mark'], + ['\u200F', 'Right-to-left mark'], + ['\u202F', 'Narrow no-break space'], + ['\u205F', 'Medium mathematical space'], + ['\u2060', 'Word joiner'], + ['\u2061', 'Function application'], + ['\u2062', 'Invisible times'], + ['\u2063', 'Invisible separator'], + ['\u2064', 'Invisible plus'], + ['\u206A', 'Inhibit symmetric swapping'], + ['\u206B', 'Activate symmetric swapping'], + ['\u206C', 'Inhibit arabic form shaping'], + ['\u206D', 'Activate arabic form shaping'], + ['\u206E', 'National digit shapes'], + ['\u206F', 'Nominal digit shapes'], + ['\u3000', 'Ideographic space'], + ['\u2800', 'Braille pattern blank'], + ['\u3164', 'Hangul filler'], + ['\uFEFF', 'Zero width no-break space'], + ['\uFFA0', 'Halfwidth hangul filler'], + ['\u1D159', 'Musical symbol null notehead'], + ['\u1D173', 'Musical symbol begin beam'], + ['\u1D174', 'Musical symbol end beam'], + ['\u1D175', 'Musical symbol begin tie'], + ['\u1D176', 'Musical symbol end tie'], + ['\u1D177', 'Musical symbol begin slur'], + ['\u1D178', 'Musical symbol end slur'], + ['\u1D179', 'Musical symbol begin phrase'], + ['\u1D17A', 'Musical symbol end phrase'] +]); + +const shiftedKc2shiftedAlias = new Map([ + ['S(KC_GRV)', 'KC_TILD'], + ['S(KC_1)', 'KC_EXLM'], + ['S(KC_2)', 'KC_AT'], + ['S(KC_3)', 'KC_HASH'], + ['S(KC_4)', 'KC_DLR'], + ['S(KC_5)', 'KC_PERC'], + ['S(KC_6)', 'KC_CIRC'], + ['S(KC_7)', 'KC_AMPR'], + ['S(KC_8)', 'KC_ASTR'], + ['S(KC_9)', 'KC_LPRN'], + ['S(KC_0)', 'KC_RPRN'], + ['S(KC_MINS)', 'KC_UNDS'], + ['S(KC_EQL)', 'KC_PLUS'], + ['S(KC_LBRC)', 'KC_LCBR'], + ['S(KC_RBRC)', 'KC_RCBR'], + ['S(KC_COMM)', 'KC_LABK'], + ['S(KC_DOT)', 'KC_RABK'], + ['S(KC_SCLN)', 'KC_COLN'], + ['S(KC_BSLS)', 'KC_PIPE'], + ['S(KC_COMM)', 'KC_LT'], + ['S(KC_DOT)', 'KC_GT'], + ['S(KC_SLSH)', 'KC_QUES'], + ['S(KC_QUOT)', 'KC_DQUO'] +]); + +const intlAliasPattern = '\\w+'; +const macroExpansionPattern = '[\\w\\(\\)]+'; +const commentPattern = '.*$'; +const kcAliasDefRegExp = new RegExp( + `# *define +(${intlAliasPattern}) +(${macroExpansionPattern}) *// *(${commentPattern})` +); + +function extractBasicKc(kc) { + if (!kc.includes('(')) { + // Not a modded keycode string. + return kc; + } + return kc.slice(kc.lastIndexOf('(') + 1, kc.indexOf(')')).trim(); +} + +function translateToUS(kc, intl2us) { + const basicKc = extractBasicKc(kc); + const basicUSKc = intl2us.get(basicKc) || basicKc; + if (!basicUSKc.includes('KC_')) { + console.error('State of intl2us:'); + console.error(intl2us); + if (!intl2us.has(basicKc)) { + throw new Error(`US translation of "${basicKc}" not found in intl2us!`); + } else { + throw new Error( + `${basicKc} gets translated as ${basicUSKc}, in intl2us, but this is not actually a valid US keycode!` + ); + } + } + return kc.replace(basicKc, basicUSKc); +} + +function computeIntl2US(lines) { + let intl2us = new Map(); + for (const aliasDefinition of lines.filter((line) => + kcAliasDefRegExp.test(line) + )) { + const [fullMatch, intlAlias, macroExpansion] = + kcAliasDefRegExp.exec(aliasDefinition); + const usAlias = translateToUS(macroExpansion, intl2us); + intl2us.set(intlAlias, usAlias); + } + return intl2us; +} + +function parseComment(comment) { + // String.prototype.trim is not acceptable because it trims ALL whitespace characters; + // it doesn't limit itself to U+20 SPACE. + const trimSpaces = (str) => /^ *(.*?) *$/.exec(str)[1]; + const clarificationIndex = + comment.indexOf('(') === -1 ? comment.length : comment.indexOf('('); + let [keysym, clarification] = [ + comment.slice(0, clarificationIndex), + comment.slice(clarificationIndex) + ].map(trimSpaces); + if (keysym.length === 0 && clarification.length > 0) { + // There can't be a clarification without a keysym. + // Notably, this is what catches the case where the comment is just ")". + // Meaning that the keysym of this keycode is the opening parenthesis. + [keysym, clarification] = [clarification, keysym]; + } + return [keysym, clarification]; +} + +function computeKcInfo(lines, intl2us) { + let kcInfo = new Map(); + for (const aliasDefinition of lines.filter((line) => + kcAliasDefRegExp.test(line) + )) { + const [fullMatch, intlAlias, macroExpansion, comment] = + kcAliasDefRegExp.exec(aliasDefinition); + const [keysym, clarification] = parseComment(comment); + let readableKeysym = keysym; + // This obscure-looking regular expression is used to detect unicode characters + // pertaining to the [Marking, non-spacing](https://www.fileformat.info/info/unicode/category/Mn/list.htm) general category. + // This category includes characters such as COMBINING HORN which can, surprisingly enough, combine with the (double) quote + // character used to start a string in the generated output, and thus ruin the entire syntax. + // + // For an example of a keymap_extras header containing those characters, check out keymap_bepo.h + const markingNonSpacingRegExp = /(\p{gc=Mn})/gu; + if (markingNonSpacingRegExp.test(keysym)) { + const dottedCircle = '\u25cc'; + readableKeysym = keysym.replaceAll( + markingNonSpacingRegExp, + dottedCircle + '$1' + ); + } else if (keysym.length === 1 && invisibleChar2readableName.has(keysym)) { + readableKeysym = invisibleChar2readableName.get(keysym); + } + if (keysym.length > 1) { + console.error( + `Warning: parsing the line below associated a keysym of length greater than 1 (${keysym}) to ${intlAlias} aka ${macroExpansion}. This may cause the key legend text to overflow.` + ); + console.error(fullMatch); + } + // aka the hover tip + const title = (intlAlias + ' ' + clarification).trimEnd(); + const usMacroExpansion = translateToUS(macroExpansion, intl2us); + kcInfo.set(usMacroExpansion, { + intlAlias, + clarification, + title, + keysym: readableKeysym, + name: readableKeysym + }); + const shiftedKcRegExp = /^(?:S|LSFT)\(\w+\)$/; + if (shiftedKcRegExp.test(macroExpansion)) { + if (shiftedKc2shiftedAlias.has(usMacroExpansion)) { + kcInfo.set( + shiftedKc2shiftedAlias.get(usMacroExpansion), + kcInfo.get(usMacroExpansion) + ); + } + const basicKc = extractBasicKc(macroExpansion); + const basicUSKc = translateToUS(basicKc, intl2us); + if (kcInfo.has(basicUSKc)) { + const basicKcInfo = kcInfo.get(basicUSKc); + basicKcInfo.name = readableKeysym + '\n' + basicKcInfo.name; + } else if (!basicKc.startsWith('KC_')) { + console.error('State of kcInfo:'); + console.error(kcInfo); + throw new Error( + 'Encountered the definition of a shifted keycode before having read the definition of the corresponding basic keycode first, when reading the following line.\n' + + fullMatch + ); + } + } + } + return kcInfo; +} + +function stringify(usAlias, kcInfoObject) { + // Important to surround the usAlias with quotes because it may contain parentheses. + const stringified = `'${usAlias}': ${JSON.stringify(kcInfoObject, [ + 'name', + 'title' + ])},`; + if (stringified.includes('undefined')) { + throw new Error( + `Failed to stringify the kcInfoObject associated to ${usAlias}:\n${stringified}` + ); + } + return stringified; +} + +function convertLine(line, kcInfo, intl2us) { + if (line.includes('clang-format off')) { + return 'export default {'; + } + + const copyrightRegExp = /(^.*)Copyright .*$/; + if (copyrightRegExp.test(line)) { + let [fullMatch, beforeCopyrightWord] = copyrightRegExp.exec(line); + return ( + beforeCopyrightWord + + 'Copyright ' + + new Date().getFullYear() + + ' - Generated by convert_keymap_extras_header.js' + ); + } + + const nonDefineDirectiveRegExp = /^#\s*(?!define)/; + if (nonDefineDirectiveRegExp.test(line)) { + return ''; + } + + if (kcAliasDefRegExp.test(line)) { + let keycodeObjectLine = ''; + let [fullMatch, intlAlias, macroExpansion, comment] = + kcAliasDefRegExp.exec(line); + const usMacroExpansion = translateToUS(macroExpansion, intl2us); + let kcInfoLine = stringify(usMacroExpansion, kcInfo.get(usMacroExpansion)); + if (shiftedKc2shiftedAlias.has(usMacroExpansion)) { + const shiftedAlias = shiftedKc2shiftedAlias.get(usMacroExpansion); + kcInfoLine += + '\n' + stringify(shiftedAlias, kcInfo.get(usMacroExpansion)); + } + if (kcInfoLine.includes('undefined')) { + throw new Error( + 'Parsing error occured for the following line:\n' + fullMatch + ); + } + return kcInfoLine; + } + + return line; +} + +function generateMissingKcBsls(kcInfo) { + // If no explicit mapping for KC_BSLS exist, as is the case for many ISO layouts, fall + // back to the KC_NUHS mapping. + if (kcInfo.has('KC_BSLS')) { + return ''; + } + if (!kcInfo.has('KC_NUHS')) { + throw new Error( + 'The input file is missing a mapping to both KC_BSLS and KC_NUHS. At least one of them must be mapped to an locale alias!' + ); + } + const kcNuhsInfo = kcInfo.get('KC_NUHS'); + const shiftedNuhsInfo = kcInfo.get('S(KC_NUHS)'); + // Copy the KC_NUHS kc info object but replace the associated intl alias with KC_BSLS/KC_PIPE. + // Since it is pointless to repeat the US kc alias in the title, we only keep the clarification. + const kcBslsInfo = { + ...kcNuhsInfo, + intlAlias: 'KC_BSLS', + title: kcNuhsInfo.clarification + }; + const kcPipeInfo = { + ...shiftedNuhsInfo, + intlAlias: 'KC_PIPE', + title: shiftedNuhsInfo.clarification + }; + kcInfo.set('KC_BSLS', kcBslsInfo); + kcInfo.set('S(KC_BSLS)', kcPipeInfo); + kcInfo.set('KC_PIPE', kcPipeInfo); + let bslsInfoLines = stringify('KC_BSLS', kcBslsInfo) + '\n'; + bslsInfoLines += stringify('S(KC_BSLS)', kcPipeInfo) + '\n'; + bslsInfoLines += stringify('KC_PIPE', kcPipeInfo); + return bslsInfoLines; +} + +function generateMissingKcNuhs(kcInfo) { + // If no explicit mapping for KC_NUHS exist, as is the case for many ANSI layouts, fall + // back to the KC_BSLS mapping. + if (kcInfo.has('KC_NUHS')) { + return ''; + } + if (!kcInfo.has('KC_BSLS')) { + throw new Error( + 'The input file is missing a mapping to both KC_BSLS and KC_NUHS. At least one of them must be mapped to an locale alias!' + ); + } + const kcBslsInfo = kcInfo.get('KC_BSLS'); + const kcPipeInfo = kcInfo.get('S(KC_BSLS)'); + // Copy the KC_BSLS kc info object but replace the associated intl alias with KC_NUHS. + // Since it is pointless to repeat the US kc alias in the title, we only keep the clarification. + const kcNuhsInfo = { + ...kcBslsInfo, + intlAlias: 'KC_NUHS', + title: kcBslsInfo.clarification + }; + const shiftedNuhsInfo = { + ...kcPipeInfo, + intlAlias: 'S(KC_NUHS)', + title: kcPipeInfo.clarification + }; + kcInfo.set('KC_NUHS', kcNuhsInfo); + kcInfo.set('S(KC_NUHS)', shiftedNuhsInfo); + let nuhsInfoLines = stringify('KC_NUHS', kcNuhsInfo) + '\n'; + nuhsInfoLines += stringify('S(KC_NUHS)', shiftedNuhsInfo); + return nuhsInfoLines; +} + +function generateMissingShiftedAliasKcInfo(kcInfo) { + let ret = ''; + for (const [shiftedKc, shiftedAlias] of shiftedKc2shiftedAlias.entries()) { + if (kcInfo.has(shiftedAlias)) { + continue; + } + const shiftedAliasKcInfo = { + ...(kcInfo.get(shiftedKc) || kcInfo.get(extractBasicKc(shiftedKc))) + }; + shiftedAliasKcInfo.title = `S(${shiftedAliasKcInfo.title})`; + const letterRegExp = /^\p{L}$/u; + if (letterRegExp.test(shiftedAliasKcInfo.keysym)) { + shiftedAliasKcInfo.title += ` (capital ${shiftedAliasKcInfo.keysym})`; + } + ret += stringify(shiftedAlias, shiftedAliasKcInfo) + '\n'; + } + return ret; +} + +function generateSpaceCadetKcInfo(kc, kcInfo) { + const spaceCadetKeycodeRegExp = /([LR])([GASC])P([OC])/; + let [fullMatch, handedness, modifier, variant] = + spaceCadetKeycodeRegExp.exec(kc); + const table = new Map([ + ['L', 'Left'], + ['R', 'Right'], + ['G', 'GUI'], + ['A', 'Alt'], + ['C', 'Control'], + ['S', 'Shift'] + ]); + const tapKc = variant === 'C' ? 'S(KC_0)' : 'S(KC_9)'; + const keysym = (kcInfo.get(tapKc) || kcInfo.get(extractBasicKc(tapKc))) + .keysym; + const spaceCadetInfo = { + name: `${handedness}${modifier} / ${keysym}`, + title: `${table.get(handedness)} ${table.get( + modifier + )} when held, ${keysym} when tapped` + }; + return stringify(kc, spaceCadetInfo); +} + +if (process.argv.length <= 1 || process.argv.at(-1).endsWith('.js')) { + throw new Error( + 'No input file given as argument! Make sure to specify the path to the keymap_extras header file you wish to convert when calling this script.' + ); +} + +fs.readFile(process.argv.at(-1), 'utf8', function (err, data) { + if (err) { + console.error(err.stack); + } else { + const fileLines = data.replaceAll('(backslash)', '\\').split(/\r\n|\r|\n/); + let intl2us = computeIntl2US(fileLines); + const kcInfo = computeKcInfo(fileLines, intl2us); + if (kcInfo.size === 0) { + throw new Error( + 'No keycode mappings found! Make sure that the input file contains lines in the format of `#define // `.' + ); + } + let convertedLines = fileLines.map((line) => + convertLine(line, kcInfo, intl2us) + ); + console.log(convertedLines.join('\n')); + console.log('/* Other keys */'); + console.log(generateMissingKcBsls(kcInfo)); + console.log(generateMissingKcNuhs(kcInfo)); + console.log(generateMissingShiftedAliasKcInfo(kcInfo)); + spaceCadetKeycodes = [ + 'KC_LSPO', + 'KC_RSPC', + 'KC_LCPO', + 'KC_RCPC', + 'KC_LAPO', + 'KC_RAPC' + ]; + for (const spaceCadetKc of spaceCadetKeycodes) { + console.log(generateSpaceCadetKcInfo(spaceCadetKc, kcInfo)); + } + console.log(''); + const grvKeysym = kcInfo.get('KC_GRV').keysym; + const tildeKeysym = kcInfo.has('S(KC_GRV)') + ? kcInfo.get('S(KC_GRV)').keysym + : grvKeysym; + if (tildeKeysym !== grvKeysym) { + console.log( + stringify('QK_GESC', { + name: `${grvKeysym} / ${tildeKeysym}\nEsc`, + title: `Esc normally, but ${grvKeysym} when GUI is active or ${tildeKeysym} when Shift is active` + }) + ); + } else { + console.log( + stringify('QK_GESC', { + name: `${grvKeysym}\nEsc`, + title: `Esc normally, but ${grvKeysym} when Shift or GUI is active` + }) + ); + } + console.log('}'); + } +}); From 685ef101fcca3bae4363ccbf8ed691104443ad4d Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Fri, 12 Aug 2022 23:57:52 +0200 Subject: [PATCH 02/28] Generate LUTs for US, UK, RU and DE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manually added Ctrl → Strg for keymap_german.js --- src/i18n/keymap_extras/keymap_german.js | 190 +++++++++++++++++++++++ src/i18n/keymap_extras/keymap_russian.js | 167 ++++++++++++++++++++ src/i18n/keymap_extras/keymap_uk.js | 184 ++++++++++++++++++++++ src/i18n/keymap_extras/keymap_us.js | 129 +++++++++++++++ 4 files changed, 670 insertions(+) create mode 100644 src/i18n/keymap_extras/keymap_german.js create mode 100644 src/i18n/keymap_extras/keymap_russian.js create mode 100644 src/i18n/keymap_extras/keymap_uk.js create mode 100644 src/i18n/keymap_extras/keymap_us.js diff --git a/src/i18n/keymap_extras/keymap_german.js b/src/i18n/keymap_extras/keymap_german.js new file mode 100644 index 0000000000..7cc5f4929d --- /dev/null +++ b/src/i18n/keymap_extras/keymap_german.js @@ -0,0 +1,190 @@ +/* Copyright 2022 - Generated by convert_keymap_extras_header.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + /* + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ Ü │ + │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ # │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ < │ Y │ X │ C │ V │ B │ N │ M │ , │ . │ - │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + KC_GRV: { name: '°\n^', title: 'DE_CIRC (dead)' }, + KC_1: { name: '!\n1', title: 'DE_1' }, + KC_2: { name: '"\n2', title: 'DE_2' }, + KC_3: { name: '§\n3', title: 'DE_3' }, + KC_4: { name: '$\n4', title: 'DE_4' }, + KC_5: { name: '%\n5', title: 'DE_5' }, + KC_6: { name: '&\n6', title: 'DE_6' }, + KC_7: { name: '/\n7', title: 'DE_7' }, + KC_8: { name: '(\n8', title: 'DE_8' }, + KC_9: { name: ')\n9', title: 'DE_9' }, + KC_0: { name: '=\n0', title: 'DE_0' }, + KC_MINS: { name: '?\nß', title: 'DE_SS' }, + KC_EQL: { name: '`\n´', title: 'DE_ACUT (dead)' }, + // Row 2 + KC_Q: { name: 'Q', title: 'DE_Q' }, + KC_W: { name: 'W', title: 'DE_W' }, + KC_E: { name: 'E', title: 'DE_E' }, + KC_R: { name: 'R', title: 'DE_R' }, + KC_T: { name: 'T', title: 'DE_T' }, + KC_Y: { name: 'Z', title: 'DE_Z' }, + KC_U: { name: 'U', title: 'DE_U' }, + KC_I: { name: 'I', title: 'DE_I' }, + KC_O: { name: 'O', title: 'DE_O' }, + KC_P: { name: 'P', title: 'DE_P' }, + KC_LBRC: { name: 'Ü', title: 'DE_UDIA' }, + KC_RBRC: { name: '*\n+', title: 'DE_PLUS' }, + // Row 3 + KC_A: { name: 'A', title: 'DE_A' }, + KC_S: { name: 'S', title: 'DE_S' }, + KC_D: { name: 'D', title: 'DE_D' }, + KC_F: { name: 'F', title: 'DE_F' }, + KC_G: { name: 'G', title: 'DE_G' }, + KC_H: { name: 'H', title: 'DE_H' }, + KC_J: { name: 'J', title: 'DE_J' }, + KC_K: { name: 'K', title: 'DE_K' }, + KC_L: { name: 'L', title: 'DE_L' }, + KC_SCLN: { name: 'Ö', title: 'DE_ODIA' }, + KC_QUOT: { name: 'Ä', title: 'DE_ADIA' }, + KC_NUHS: { name: "'\n#", title: 'DE_HASH' }, + // Row 4 + KC_NUBS: { name: '>\n<', title: 'DE_LABK' }, + KC_Z: { name: 'Y', title: 'DE_Y' }, + KC_X: { name: 'X', title: 'DE_X' }, + KC_C: { name: 'C', title: 'DE_C' }, + KC_V: { name: 'V', title: 'DE_V' }, + KC_B: { name: 'B', title: 'DE_B' }, + KC_N: { name: 'N', title: 'DE_N' }, + KC_M: { name: 'M', title: 'DE_M' }, + KC_COMM: { name: ';\n,', title: 'DE_COMM' }, + KC_DOT: { name: ':\n.', title: 'DE_DOT' }, + KC_SLSH: { name: '_\n-', title: 'DE_MINS' }, + + /* Shifted symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ° │ ! │ " │ § │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ * │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ │ │ ' │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ > │ │ │ │ │ │ │ │ ; │ : │ _ │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'S(KC_GRV)': { name: '°', title: 'DE_DEG' }, + KC_TILD: { name: '°', title: 'DE_DEG' }, + 'S(KC_1)': { name: '!', title: 'DE_EXLM' }, + KC_EXLM: { name: '!', title: 'DE_EXLM' }, + 'S(KC_2)': { name: '"', title: 'DE_DQUO' }, + KC_AT: { name: '"', title: 'DE_DQUO' }, + 'S(KC_3)': { name: '§', title: 'DE_SECT' }, + KC_HASH: { name: '§', title: 'DE_SECT' }, + 'S(KC_4)': { name: '$', title: 'DE_DLR' }, + KC_DLR: { name: '$', title: 'DE_DLR' }, + 'S(KC_5)': { name: '%', title: 'DE_PERC' }, + KC_PERC: { name: '%', title: 'DE_PERC' }, + 'S(KC_6)': { name: '&', title: 'DE_AMPR' }, + KC_CIRC: { name: '&', title: 'DE_AMPR' }, + 'S(KC_7)': { name: '/', title: 'DE_SLSH' }, + KC_AMPR: { name: '/', title: 'DE_SLSH' }, + 'S(KC_8)': { name: '(', title: 'DE_LPRN' }, + KC_ASTR: { name: '(', title: 'DE_LPRN' }, + 'S(KC_9)': { name: ')', title: 'DE_RPRN' }, + KC_LPRN: { name: ')', title: 'DE_RPRN' }, + 'S(KC_0)': { name: '=', title: 'DE_EQL' }, + KC_RPRN: { name: '=', title: 'DE_EQL' }, + 'S(KC_MINS)': { name: '?', title: 'DE_QUES' }, + KC_UNDS: { name: '?', title: 'DE_QUES' }, + 'S(KC_EQL)': { name: '`', title: 'DE_GRV (dead)' }, + KC_PLUS: { name: '`', title: 'DE_GRV (dead)' }, + // Row 2 + 'S(KC_RBRC)': { name: '*', title: 'DE_ASTR' }, + KC_RCBR: { name: '*', title: 'DE_ASTR' }, + // Row 3 + 'S(KC_NUHS)': { name: "'", title: 'DE_QUOT' }, + // Row 4 + 'S(KC_NUBS)': { name: '>', title: 'DE_RABK' }, + 'S(KC_COMM)': { name: ';', title: 'DE_SCLN' }, + KC_LT: { name: ';', title: 'DE_SCLN' }, + 'S(KC_DOT)': { name: ':', title: 'DE_COLN' }, + KC_GT: { name: ':', title: 'DE_COLN' }, + 'S(KC_SLSH)': { name: '_', title: 'DE_UNDS' }, + KC_QUES: { name: '_', title: 'DE_UNDS' }, + + /* AltGr symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ │ │ ² │ ³ │ │ │ │ { │ [ │ ] │ } │ \ │ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ @ │ │ € │ │ │ │ │ │ │ │ │ ~ │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ | │ │ │ │ │ │ │ µ │ │ │ │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'ALGR(KC_2)': { name: '²', title: 'DE_SUP2' }, + 'ALGR(KC_3)': { name: '³', title: 'DE_SUP3' }, + 'ALGR(KC_7)': { name: '{', title: 'DE_LCBR' }, + 'ALGR(KC_8)': { name: '[', title: 'DE_LBRC' }, + 'ALGR(KC_9)': { name: ']', title: 'DE_RBRC' }, + 'ALGR(KC_0)': { name: '}', title: 'DE_RCBR' }, + 'ALGR(KC_MINS)': { name: '\\', title: 'DE_BSLS' }, + // Row 2 + 'ALGR(KC_Q)': { name: '@', title: 'DE_AT' }, + 'ALGR(KC_E)': { name: '€', title: 'DE_EURO' }, + 'ALGR(KC_RBRC)': { name: '~', title: 'DE_TILD' }, + // Row 4 + 'ALGR(KC_NUBS)': { name: '|', title: 'DE_PIPE' }, + 'ALGR(KC_M)': { name: 'µ', title: 'DE_MICR' }, + + /* Other keys */ + KC_BSLS: { name: "'\n#", title: '' }, + 'S(KC_BSLS)': { name: "'", title: '' }, + KC_PIPE: { name: "'", title: '' }, + + KC_LCBR: { name: 'Ü', title: 'S(DE_UDIA) (capital Ü)' }, + KC_COLN: { name: 'Ö', title: 'S(DE_ODIA) (capital Ö)' }, + KC_DQUO: { name: 'Ä', title: 'S(DE_ADIA) (capital Ä)' }, + + KC_LSPO: { name: 'LS / )', title: 'Left Shift when held, ) when tapped' }, + KC_RSPC: { name: 'RS / =', title: 'Right Shift when held, = when tapped' }, + KC_LCPO: { name: 'LC / )', title: 'Left Control when held, ) when tapped' }, + KC_RCPC: { name: 'RC / =', title: 'Right Control when held, = when tapped' }, + KC_LAPO: { name: 'LA / )', title: 'Left Alt when held, ) when tapped' }, + KC_RAPC: { name: 'RA / =', title: 'Right Alt when held, = when tapped' }, + + QK_GESC: { + name: '^ / °\nEsc', + title: 'Esc normally, but ^ when GUI is active or ° when Shift is active' + }, + + KC_LCTL: { name: 'Left Strg' }, + KC_RCTL: { name: 'Right Strg' } +}; diff --git a/src/i18n/keymap_extras/keymap_russian.js b/src/i18n/keymap_extras/keymap_russian.js new file mode 100644 index 0000000000..1941a476f1 --- /dev/null +++ b/src/i18n/keymap_extras/keymap_russian.js @@ -0,0 +1,167 @@ +/* Copyright 2022 - Generated by convert_keymap_extras_header.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + /* + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ Ё │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ Й │ Ц │ У │ К │ Е │ Н │ Г │ Ш │ Щ │ З │ Х │ Ъ │ \ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ + * │ │ Ф │ Ы │ В │ А │ П │ Р │ О │ Л │ Д │ Ж │ Э │ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ + * │ │ Я │ Ч │ С │ М │ И │ Т │ Ь │ Б │ Ю │ . │ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + KC_GRV: { name: 'Ё', title: 'RU_YO' }, + KC_1: { name: '!\n1', title: 'RU_1' }, + KC_2: { name: '"\n2', title: 'RU_2' }, + KC_3: { name: '№\n3', title: 'RU_3' }, + KC_4: { name: ';\n4', title: 'RU_4' }, + KC_5: { name: '%\n5', title: 'RU_5' }, + KC_6: { name: ':\n6', title: 'RU_6' }, + KC_7: { name: '?\n7', title: 'RU_7' }, + KC_8: { name: '*\n8', title: 'RU_8' }, + KC_9: { name: '(\n9', title: 'RU_9' }, + KC_0: { name: ')\n0', title: 'RU_0' }, + KC_MINS: { name: '_\n-', title: 'RU_MINS' }, + KC_EQL: { name: '+\n=', title: 'RU_EQL' }, + // Row 2 + KC_Q: { name: 'Й', title: 'RU_SHTI' }, + KC_W: { name: 'Ц', title: 'RU_TSE' }, + KC_E: { name: 'У', title: 'RU_U' }, + KC_R: { name: 'К', title: 'RU_KA' }, + KC_T: { name: 'Е', title: 'RU_IE' }, + KC_Y: { name: 'Н', title: 'RU_EN' }, + KC_U: { name: 'Г', title: 'RU_GHE' }, + KC_I: { name: 'Ш', title: 'RU_SHA' }, + KC_O: { name: 'Щ', title: 'RU_SHCH' }, + KC_P: { name: 'З', title: 'RU_ZE' }, + KC_LBRC: { name: 'Х', title: 'RU_HA' }, + KC_RBRC: { name: 'Ъ', title: 'RU_HARD' }, + KC_BSLS: { name: '/\n\\', title: 'RU_BSLS' }, + // Row 3 + KC_A: { name: 'Ф', title: 'RU_EF' }, + KC_S: { name: 'Ы', title: 'RU_YERU' }, + KC_D: { name: 'В', title: 'RU_VE' }, + KC_F: { name: 'А', title: 'RU_A' }, + KC_G: { name: 'П', title: 'RU_PE' }, + KC_H: { name: 'Р', title: 'RU_ER' }, + KC_J: { name: 'О', title: 'RU_O' }, + KC_K: { name: 'Л', title: 'RU_EL' }, + KC_L: { name: 'Д', title: 'RU_DE' }, + KC_SCLN: { name: 'Ж', title: 'RU_ZHE' }, + KC_QUOT: { name: 'Э', title: 'RU_E' }, + // Row 4 + KC_Z: { name: 'Я', title: 'RU_YA' }, + KC_X: { name: 'Ч', title: 'RU_CHE' }, + KC_C: { name: 'С', title: 'RU_ES' }, + KC_V: { name: 'М', title: 'RU_EM' }, + KC_B: { name: 'И', title: 'RU_I' }, + KC_N: { name: 'Т', title: 'RU_TE' }, + KC_M: { name: 'Ь', title: 'RU_SOFT' }, + KC_COMM: { name: 'Б', title: 'RU_BE' }, + KC_DOT: { name: 'Ю', title: 'RU_YU' }, + KC_SLSH: { name: ',\n.', title: 'RU_DOT' }, + + /* Shifted symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ │ ! │ " │ № │ ; │ % │ : │ ? │ * │ ( │ ) │ _ │ + │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ / │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ + * │ │ │ │ │ │ │ │ │ │ │ , │ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'S(KC_1)': { name: '!', title: 'RU_EXLM' }, + KC_EXLM: { name: '!', title: 'RU_EXLM' }, + 'S(KC_2)': { name: '"', title: 'RU_DQUO' }, + KC_AT: { name: '"', title: 'RU_DQUO' }, + 'S(KC_3)': { name: '№', title: 'RU_NUM' }, + KC_HASH: { name: '№', title: 'RU_NUM' }, + 'S(KC_4)': { name: ';', title: 'RU_SCLN' }, + KC_DLR: { name: ';', title: 'RU_SCLN' }, + 'S(KC_5)': { name: '%', title: 'RU_PERC' }, + KC_PERC: { name: '%', title: 'RU_PERC' }, + 'S(KC_6)': { name: ':', title: 'RU_COLN' }, + KC_CIRC: { name: ':', title: 'RU_COLN' }, + 'S(KC_7)': { name: '?', title: 'RU_QUES' }, + KC_AMPR: { name: '?', title: 'RU_QUES' }, + 'S(KC_8)': { name: '*', title: 'RU_ASTR' }, + KC_ASTR: { name: '*', title: 'RU_ASTR' }, + 'S(KC_9)': { name: '(', title: 'RU_LPRN' }, + KC_LPRN: { name: '(', title: 'RU_LPRN' }, + 'S(KC_0)': { name: ')', title: 'RU_RPRN' }, + KC_RPRN: { name: ')', title: 'RU_RPRN' }, + 'S(KC_MINS)': { name: '_', title: 'RU_UNDS' }, + KC_UNDS: { name: '_', title: 'RU_UNDS' }, + 'S(KC_EQL)': { name: '+', title: 'RU_PLUS' }, + KC_PLUS: { name: '+', title: 'RU_PLUS' }, + // Row 2 + 'S(KC_BSLS)': { name: '/', title: 'RU_SLSH' }, + KC_PIPE: { name: '/', title: 'RU_SLSH' }, + // Row 4 + 'S(KC_SLSH)': { name: ',', title: 'RU_COMM' }, + KC_QUES: { name: ',', title: 'RU_COMM' }, + + /* AltGr symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ │ │ │ │ │ │ │ │ ₽ │ │ │ │ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'ALGR(KC_8)': { name: '₽', title: 'RU_RUBL' }, + + /* Other keys */ + + KC_NUHS: { name: '/\n\\', title: '' }, + 'S(KC_NUHS)': { name: '/', title: '' }, + KC_TILD: { name: 'Ё', title: 'S(RU_YO) (capital Ё)' }, + KC_LCBR: { name: 'Х', title: 'S(RU_HA) (capital Х)' }, + KC_RCBR: { name: 'Ъ', title: 'S(RU_HARD) (capital Ъ)' }, + KC_LT: { name: 'Б', title: 'S(RU_BE) (capital Б)' }, + KC_GT: { name: 'Ю', title: 'S(RU_YU) (capital Ю)' }, + KC_COLN: { name: 'Ж', title: 'S(RU_ZHE) (capital Ж)' }, + KC_DQUO: { name: 'Э', title: 'S(RU_E) (capital Э)' }, + + KC_LSPO: { name: 'LS / (', title: 'Left Shift when held, ( when tapped' }, + KC_RSPC: { name: 'RS / )', title: 'Right Shift when held, ) when tapped' }, + KC_LCPO: { name: 'LC / (', title: 'Left Control when held, ( when tapped' }, + KC_RCPC: { name: 'RC / )', title: 'Right Control when held, ) when tapped' }, + KC_LAPO: { name: 'LA / (', title: 'Left Alt when held, ( when tapped' }, + KC_RAPC: { name: 'RA / )', title: 'Right Alt when held, ) when tapped' }, + + QK_GESC: { + name: 'Ё\nEsc', + title: 'Esc normally, but Ё when Shift or GUI is active' + } +}; diff --git a/src/i18n/keymap_extras/keymap_uk.js b/src/i18n/keymap_extras/keymap_uk.js new file mode 100644 index 0000000000..4598d053d5 --- /dev/null +++ b/src/i18n/keymap_extras/keymap_uk.js @@ -0,0 +1,184 @@ +/* Copyright 2022 - Generated by convert_keymap_extras_header.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + /* + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ \ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + KC_GRV: { name: '¬\n`', title: 'UK_GRV' }, + KC_1: { name: '!\n1', title: 'UK_1' }, + KC_2: { name: '"\n2', title: 'UK_2' }, + KC_3: { name: '£\n3', title: 'UK_3' }, + KC_4: { name: '$\n4', title: 'UK_4' }, + KC_5: { name: '%\n5', title: 'UK_5' }, + KC_6: { name: '^\n6', title: 'UK_6' }, + KC_7: { name: '&\n7', title: 'UK_7' }, + KC_8: { name: '*\n8', title: 'UK_8' }, + KC_9: { name: '(\n9', title: 'UK_9' }, + KC_0: { name: ')\n0', title: 'UK_0' }, + KC_MINS: { name: '_\n-', title: 'UK_MINS' }, + KC_EQL: { name: '+\n=', title: 'UK_EQL' }, + // Row 2 + KC_Q: { name: 'Q', title: 'UK_Q' }, + KC_W: { name: 'W', title: 'UK_W' }, + KC_E: { name: 'E', title: 'UK_E' }, + KC_R: { name: 'R', title: 'UK_R' }, + KC_T: { name: 'T', title: 'UK_T' }, + KC_Y: { name: 'Y', title: 'UK_Y' }, + KC_U: { name: 'U', title: 'UK_U' }, + KC_I: { name: 'I', title: 'UK_I' }, + KC_O: { name: 'O', title: 'UK_O' }, + KC_P: { name: 'P', title: 'UK_P' }, + KC_LBRC: { name: '{\n[', title: 'UK_LBRC' }, + KC_RBRC: { name: '}\n]', title: 'UK_RBRC' }, + // Row 3 + KC_A: { name: 'A', title: 'UK_A' }, + KC_S: { name: 'S', title: 'UK_S' }, + KC_D: { name: 'D', title: 'UK_D' }, + KC_F: { name: 'F', title: 'UK_F' }, + KC_G: { name: 'G', title: 'UK_G' }, + KC_H: { name: 'H', title: 'UK_H' }, + KC_J: { name: 'J', title: 'UK_J' }, + KC_K: { name: 'K', title: 'UK_K' }, + KC_L: { name: 'L', title: 'UK_L' }, + KC_SCLN: { name: ':\n;', title: 'UK_SCLN' }, + KC_QUOT: { name: "@\n'", title: 'UK_QUOT' }, + KC_NUHS: { name: '~\n#', title: 'UK_HASH' }, + // Row 4 + KC_NUBS: { name: '|\n\\', title: 'UK_BSLS' }, + KC_Z: { name: 'Z', title: 'UK_Z' }, + KC_X: { name: 'X', title: 'UK_X' }, + KC_C: { name: 'C', title: 'UK_C' }, + KC_V: { name: 'V', title: 'UK_V' }, + KC_B: { name: 'B', title: 'UK_B' }, + KC_N: { name: 'N', title: 'UK_N' }, + KC_M: { name: 'M', title: 'UK_M' }, + KC_COMM: { name: '<\n,', title: 'UK_COMM' }, + KC_DOT: { name: '>\n.', title: 'UK_DOT' }, + KC_SLSH: { name: '?\n/', title: 'UK_SLSH' }, + + /* Shifted symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ { │ } │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ │ │ │ │ │ │ │ │ │ : │ @ │ ~ │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ | │ │ │ │ │ │ │ │ < │ > │ ? │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'S(KC_GRV)': { name: '¬', title: 'UK_NOT' }, + KC_TILD: { name: '¬', title: 'UK_NOT' }, + 'S(KC_1)': { name: '!', title: 'UK_EXLM' }, + KC_EXLM: { name: '!', title: 'UK_EXLM' }, + 'S(KC_2)': { name: '"', title: 'UK_DQUO' }, + KC_AT: { name: '"', title: 'UK_DQUO' }, + 'S(KC_3)': { name: '£', title: 'UK_PND' }, + KC_HASH: { name: '£', title: 'UK_PND' }, + 'S(KC_4)': { name: '$', title: 'UK_DLR' }, + KC_DLR: { name: '$', title: 'UK_DLR' }, + 'S(KC_5)': { name: '%', title: 'UK_PERC' }, + KC_PERC: { name: '%', title: 'UK_PERC' }, + 'S(KC_6)': { name: '^', title: 'UK_CIRC' }, + KC_CIRC: { name: '^', title: 'UK_CIRC' }, + 'S(KC_7)': { name: '&', title: 'UK_AMPR' }, + KC_AMPR: { name: '&', title: 'UK_AMPR' }, + 'S(KC_8)': { name: '*', title: 'UK_ASTR' }, + KC_ASTR: { name: '*', title: 'UK_ASTR' }, + 'S(KC_9)': { name: '(', title: 'UK_LPRN' }, + KC_LPRN: { name: '(', title: 'UK_LPRN' }, + 'S(KC_0)': { name: ')', title: 'UK_RPRN' }, + KC_RPRN: { name: ')', title: 'UK_RPRN' }, + 'S(KC_MINS)': { name: '_', title: 'UK_UNDS' }, + KC_UNDS: { name: '_', title: 'UK_UNDS' }, + 'S(KC_EQL)': { name: '+', title: 'UK_PLUS' }, + KC_PLUS: { name: '+', title: 'UK_PLUS' }, + // Row 2 + 'S(KC_LBRC)': { name: '{', title: 'UK_LCBR' }, + KC_LCBR: { name: '{', title: 'UK_LCBR' }, + 'S(KC_RBRC)': { name: '}', title: 'UK_RCBR' }, + KC_RCBR: { name: '}', title: 'UK_RCBR' }, + // Row 3 + 'S(KC_SCLN)': { name: ':', title: 'UK_COLN' }, + KC_COLN: { name: ':', title: 'UK_COLN' }, + 'S(KC_QUOT)': { name: '@', title: 'UK_AT' }, + KC_DQUO: { name: '@', title: 'UK_AT' }, + 'S(KC_NUHS)': { name: '~', title: 'UK_TILD' }, + // Row 4 + 'S(KC_NUBS)': { name: '|', title: 'UK_PIPE' }, + 'S(KC_COMM)': { name: '<', title: 'UK_LABK' }, + KC_LT: { name: '<', title: 'UK_LABK' }, + 'S(KC_DOT)': { name: '>', title: 'UK_RABK' }, + KC_GT: { name: '>', title: 'UK_RABK' }, + 'S(KC_SLSH)': { name: '?', title: 'UK_QUES' }, + KC_QUES: { name: '?', title: 'UK_QUES' }, + + /* AltGr symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ¦ │ │ │ │ € │ │ │ │ │ │ │ │ │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ É │ │ │ │ Ú │ Í │ Ó │ │ │ │ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ + * │ │ Á │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ │ │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'ALGR(KC_GRV)': { name: '¦', title: 'UK_BRKP' }, + 'ALGR(KC_4)': { name: '€', title: 'UK_EURO' }, + // Row 2 + 'ALGR(KC_E)': { name: 'É', title: 'UK_EACU' }, + 'ALGR(KC_U)': { name: 'Ú', title: 'UK_UACU' }, + 'ALGR(KC_I)': { name: 'Í', title: 'UK_IACU' }, + 'ALGR(KC_O)': { name: 'Ó', title: 'UK_OACU' }, + // Row 3 + 'ALGR(KC_A)': { name: 'Á', title: 'UK_AACU' }, + + /* Other keys */ + KC_BSLS: { name: '~\n#', title: '' }, + 'S(KC_BSLS)': { name: '~', title: '' }, + KC_PIPE: { name: '~', title: '' }, + + KC_LSPO: { name: 'LS / (', title: 'Left Shift when held, ( when tapped' }, + KC_RSPC: { name: 'RS / )', title: 'Right Shift when held, ) when tapped' }, + KC_LCPO: { name: 'LC / (', title: 'Left Control when held, ( when tapped' }, + KC_RCPC: { name: 'RC / )', title: 'Right Control when held, ) when tapped' }, + KC_LAPO: { name: 'LA / (', title: 'Left Alt when held, ( when tapped' }, + KC_RAPC: { name: 'RA / )', title: 'Right Alt when held, ) when tapped' }, + + QK_GESC: { + name: '` / ¬\nEsc', + title: 'Esc normally, but ` when GUI is active or ¬ when Shift is active' + } +}; diff --git a/src/i18n/keymap_extras/keymap_us.js b/src/i18n/keymap_extras/keymap_us.js new file mode 100644 index 0000000000..7c56c2ac2e --- /dev/null +++ b/src/i18n/keymap_extras/keymap_us.js @@ -0,0 +1,129 @@ +export default { + KC_ESC: { name: 'Esc', title: '' }, + KC_F1: { name: 'F1', title: '' }, + KC_F2: { name: 'F2', title: '' }, + KC_F3: { name: 'F3', title: '' }, + KC_F4: { name: 'F4', title: '' }, + KC_F5: { name: 'F5', title: '' }, + KC_F6: { name: 'F6', title: '' }, + KC_F7: { name: 'F7', title: '' }, + KC_F8: { name: 'F8', title: '' }, + KC_F9: { name: 'F9', title: '' }, + KC_F10: { name: 'F10', title: '' }, + KC_F11: { name: 'F11', title: '' }, + KC_F12: { name: 'F12', title: '' }, + KC_PSCR: { name: 'Print Screen', title: '' }, + KC_SCRL: { name: 'Scroll Lock', title: '' }, + KC_PAUS: { name: 'Pause', title: '' }, + KC_GRV: { name: '~\n`', title: '' }, + KC_1: { name: '!\n1', title: '' }, + KC_2: { name: '@\n2', title: '' }, + KC_3: { name: '#\n3', title: '' }, + KC_4: { name: '$\n4', title: '' }, + KC_5: { name: '%\n5', title: '' }, + KC_6: { name: '^\n6', title: '' }, + KC_7: { name: '&\n7', title: '' }, + KC_8: { name: '*\n8', title: '' }, + KC_9: { name: '(\n9', title: '' }, + KC_0: { name: ')\n0', title: '' }, + KC_MINS: { name: '_\n-', title: '' }, + KC_EQL: { name: '+\n=', title: '' }, + KC_BSPC: { name: 'Back Space', title: '' }, + KC_INS: { name: 'Insert', title: '' }, + KC_HOME: { name: 'Home', title: '' }, + KC_PGUP: { name: 'Page Up', title: '' }, + KC_NUM: { name: 'Num Lock', title: '' }, + KC_PSLS: { name: '/', title: '' }, + KC_PAST: { name: '*', title: '' }, + KC_PMNS: { name: '-', title: '' }, + KC_TAB: { name: 'Tab', title: '' }, + KC_Q: { name: 'q', title: '' }, + KC_W: { name: 'w', title: '' }, + KC_E: { name: 'e', title: '' }, + KC_R: { name: 'r', title: '' }, + KC_T: { name: 't', title: '' }, + KC_Y: { name: 'y', title: '' }, + KC_U: { name: 'u', title: '' }, + KC_I: { name: 'i', title: '' }, + KC_O: { name: 'o', title: '' }, + KC_P: { name: 'p', title: '' }, + KC_LBRC: { name: '{\n[', title: '' }, + KC_RBRC: { name: '}\n]', title: '' }, + KC_BSLS: { name: '|\n\\', title: '' }, + KC_DEL: { name: 'Delete', title: '' }, + KC_END: { name: 'End', title: '' }, + KC_PGDN: { name: 'Page Down', title: '' }, + KC_P7: { name: '7', title: '' }, + KC_P8: { name: '8', title: '' }, + KC_P9: { name: '9', title: '' }, + KC_PPLS: { name: '+', title: '' }, + KC_CAPS: { name: 'Caps Lock', title: '' }, + KC_A: { name: 'a', title: '' }, + KC_S: { name: 's', title: '' }, + KC_D: { name: 'd', title: '' }, + KC_F: { name: 'f', title: '' }, + KC_G: { name: 'g', title: '' }, + KC_H: { name: 'h', title: '' }, + KC_J: { name: 'j', title: '' }, + KC_K: { name: 'k', title: '' }, + KC_L: { name: 'l', title: '' }, + KC_SCLN: { name: ':\n;', title: '' }, + KC_QUOT: { name: '"\n\'', keys: "'", title: '' }, + KC_ENT: { name: 'Enter', title: '' }, + KC_P4: { name: '4', title: '' }, + KC_P5: { name: '5', title: '' }, + KC_P6: { name: '6', title: '' }, + KC_PCMM: { name: ',', title: '' }, + KC_LSFT: { name: 'Left Shift', title: '' }, + KC_Z: { name: 'z', title: '' }, + KC_X: { name: 'x', title: '' }, + KC_C: { name: 'c', title: '' }, + KC_V: { name: 'v', title: '' }, + KC_B: { name: 'b', title: '' }, + KC_N: { name: 'n', title: '' }, + KC_M: { name: 'm', title: '' }, + KC_COMM: { name: '<\n,', title: '' }, + KC_DOT: { name: '>\n.', title: '' }, + KC_SLSH: { name: '?\n/', title: '' }, + KC_RSFT: { name: 'Right Shift', title: '' }, + KC_UP: { name: 'Up', title: '' }, + KC_P1: { name: '1', title: '' }, + KC_P2: { name: '2', title: '' }, + KC_P3: { name: '3', title: '' }, + KC_PEQL: { name: '=', title: '' }, + KC_LCTL: { name: 'Left Ctrl', title: '' }, + KC_LGUI: { name: 'Left OS', title: '' }, + KC_LALT: { name: 'Left Alt', title: '' }, + KC_SPC: { name: 'Space', title: '' }, + KC_RALT: { name: 'Right Alt', title: '' }, + KC_RGUI: { name: 'Right OS', title: '' }, + KC_APP: { name: 'Menu', title: 'Context Menu' }, + KC_RCTL: { name: 'Right Ctrl', title: '' }, + KC_LEFT: { name: 'Left', title: '' }, + KC_DOWN: { name: 'Down', title: '' }, + KC_RGHT: { name: 'Right', title: '' }, + KC_P0: { name: '0', title: '' }, + KC_PDOT: { name: '.', title: '' }, + KC_PENT: { name: 'Enter', title: '' }, + KC_TILD: { name: '~', title: '' }, + KC_EXLM: { name: '!', title: '' }, + KC_AT: { name: '@', title: '' }, + KC_HASH: { name: '#', title: '' }, + KC_DLR: { name: '$', title: '' }, + KC_PERC: { name: '%', title: '' }, + KC_CIRC: { name: '^', title: '' }, + KC_AMPR: { name: '&', title: '' }, + KC_ASTR: { name: '*', title: '' }, + KC_LPRN: { name: '(', title: '' }, + KC_RPRN: { name: ')', title: '' }, + KC_UNDS: { name: '_', title: '' }, + KC_PLUS: { name: '+', title: '' }, + KC_LCBR: { name: '{', title: '' }, + KC_RCBR: { name: '}', title: '' }, + KC_LT: { name: '<', title: '' }, + KC_GT: { name: '>', title: '' }, + KC_COLN: { name: ':', title: '' }, + KC_PIPE: { name: '|', title: '' }, + KC_QUES: { name: '?', title: '' }, + KC_DQUO: { name: '"', title: '' } +}; From db0707db95e7a5f9fb3c2edb5ea922c838c04db0 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Fri, 12 Aug 2022 23:58:44 +0200 Subject: [PATCH 03/28] Export keymap_extras LUTs with metadata --- src/i18n/keymap_extras/index.js | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/i18n/keymap_extras/index.js diff --git a/src/i18n/keymap_extras/index.js b/src/i18n/keymap_extras/index.js new file mode 100644 index 0000000000..d843992a17 --- /dev/null +++ b/src/i18n/keymap_extras/index.js @@ -0,0 +1,60 @@ +import us from './keymap_us'; +import uk from './keymap_uk'; +import german from './keymap_german'; +import russian from './keymap_russian'; + +/* ==Template== + * keymap_: { + * + * prefix: (string) 2-letter code, + * + * sendstring: (string) The name of the associated sendstring header file if it exists. + * This is important for the "host_language" field of keymap.json in case text macros are used. + * + * isANSI: (boolean) True if the layout is ANSI, false if not. + * + * locales: (array[string]) List of locales, as defined in RFC 5646, closely tied to this OS keyboard layout. + * This can be useful to guess the OS keyboard layout in use based on the user's preferred locale. + * + * keycodeLUT: (Object) An object mapping US keycode aliases like "KC_A" or "KC_DLR" or even + * "QK_GESC" to a keycode object containing properties such as "name" (aka the key legends to display) and + * "title" (aka the extra information shown when hovering over the key). + * } + */ + +export default { + keymap_us: { + prefix: 'KC', + // Special scenario where sendstring is an empty string not because there is no associated + // sendstring header file but because this is the default. + sendstring: '', + isANSI: true, + locales: ['en-US', 'en'], + keycodeLUT: us + }, + keymap_uk: { + prefix: 'UK', + sendstring: 'uk', + isANSI: false, + locales: ['en-UK', 'en-GB', 'en'], + keycodeLUT: uk + }, + keymap_german: { + // Note: qmk_firmware also contains a separate `keymap_german_mac_iso.h` header file, + // but its only difference with the `keymap_german.h` header is the AltGr/Option layer. + // The QMK Configurator doesn't show the AltGr legends anyways so there is no point in + // including the Mac ISO version. + prefix: 'DE', + sendstring: 'german', + isANSI: false, + locales: ['de-GE', 'de-AU', 'de'], + keycodeLUT: german + }, + keymap_russian: { + prefix: 'RU', + sendstring: '', + isANSI: true, + locales: ['ru-RU', 'ru'], + keycodeLUT: russian + } +}; From 6862ff9fdbce96b7ffe15fb6dcbb75fe090bc581 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 13 Aug 2022 00:00:49 +0200 Subject: [PATCH 04/28] Add support for intl key legends based on the host keyboard layout This is the main commit of PR #1161. --- src/components/SettingsPanel.vue | 59 ++++++++++++------- src/i18n/de.csv | 8 ++- src/i18n/en.csv | 8 ++- src/i18n/es.csv | 8 ++- src/i18n/fr.csv | 8 ++- src/i18n/it.csv | 8 ++- src/i18n/ja.csv | 8 ++- src/i18n/ms.csv | 8 ++- src/i18n/pl-PL.csv | 8 ++- src/i18n/pt-BR.csv | 8 ++- src/i18n/ru.csv | 8 ++- src/i18n/zh-CN.csv | 8 ++- src/i18n/zh.csv | 8 ++- src/store/modules/app/actions.js | 5 ++ src/store/modules/app/mutations.js | 3 + src/store/modules/app/state.js | 10 +++- src/store/modules/keycodes/index.js | 88 +++++++++++++++++++++-------- 17 files changed, 192 insertions(+), 69 deletions(-) diff --git a/src/components/SettingsPanel.vue b/src/components/SettingsPanel.vue index 569f659f8c..8ecfaf1ef0 100644 --- a/src/components/SettingsPanel.vue +++ b/src/components/SettingsPanel.vue @@ -91,6 +91,28 @@ +
+ +
+
+ +
-
- -
-
- -
{{ helpText }}
@@ -157,7 +161,8 @@ export default { ...mapState('app', [ 'tutorialEnabled', 'configuratorSettings', - 'languages' + 'languages', + 'osKeyboardLayouts' ]), language: { get() { @@ -166,6 +171,14 @@ export default { async set(value) { await this.changeLanguage(value); } + }, + osKeyboardLayout: { + get() { + return this.configuratorSettings.osKeyboardLayout; + }, + async set(value) { + await this.changeOSKeyboardLayout(value); + } } }, methods: { @@ -174,6 +187,7 @@ export default { ...mapActions('app', [ 'toggleDarkMode', 'changeLanguage', + 'changeOSKeyboardLayout', 'toggleClearLayerDefault', 'toggleIso' ]), @@ -203,12 +217,15 @@ export default { case 'language': this.helpText = this.$t('settingsPanel.language.help'); break; - case 'clearLayer': - this.helpText = this.$t('settingsPanel.clearLayer.help'); + case 'osKeyboardLayout': + this.helpText = this.$t('settingsPanel.osKeyboardLayout.help'); break; case 'iso': this.helpText = this.$t('settingsPanel.iso.help'); break; + case 'clearLayer': + this.helpText = this.$t('settingsPanel.clearLayer.help'); + break; } if (this.clearTextTimer) { diff --git a/src/i18n/de.csv b/src/i18n/de.csv index 2fc0d6cd1a..eed9e8c086 100644 --- a/src/i18n/de.csv +++ b/src/i18n/de.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,strg + alt + u settingsPanel:fastInput:help,"Gib die Tasten über die Tastatur ein, ohne auf die einzelnen Positionen zu klicken" settingsPanel:fastInput:label,Schnelle Eingabe settingsPanel:fastInput:title,strg + alt + f -settingsPanel:iso:help,ISO-Legenden standardmäßig anzeigen -settingsPanel:iso:label,Verwenden Sie ISO-Schlüssellegenden +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,Deutsch (Deutschland & Österreich) +settingsPanel:osKeyboardLayout:label:keymap_russian,Russisch +settingsPanel:osKeyboardLayout:label:keymap_uk,Englisch (UK) +settingsPanel:osKeyboardLayout:label:keymap_us,Englisch (US) +settingsPanel:osKeyboardLayout:title, settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/en.csv b/src/i18n/en.csv index b57f040b41..08a9def2b5 100644 --- a/src/i18n/en.csv +++ b/src/i18n/en.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,Input keys via keyboard without clicking each position. settingsPanel:fastInput:label,Fast Input settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,Display ISO legends by default -settingsPanel:iso:label,Use ISO key legends +settingsPanel:osKeyboardLayout:title,Host Keyboard Layout +settingsPanel:osKeyboardLayout:help,Change the key legends to match with your host keyboard layout. +settingsPanel:osKeyboardLayout:label:keymap_us,English (US) +settingsPanel:osKeyboardLayout:label:keymap_uk,English (UK) +settingsPanel:osKeyboardLayout:label:keymap_german,German (Germany & Austria) +settingsPanel:osKeyboardLayout:label:keymap_russian,Russian settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help,Change the language of the user interface diff --git a/src/i18n/es.csv b/src/i18n/es.csv index 422614a178..3574956c08 100644 --- a/src/i18n/es.csv +++ b/src/i18n/es.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,Ingresar teclas por medio del teclado sin hacer click en cada posición. settingsPanel:fastInput:label,Entrada rápida settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,Mostrar leyendas ISO de forma predeterminada -settingsPanel:iso:label,Utilice leyendas clave ISO +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,Alemán (Alemania y Austria) +settingsPanel:osKeyboardLayout:label:keymap_russian,Ruso +settingsPanel:osKeyboardLayout:label:keymap_uk,Inglés (Reino Unido) +settingsPanel:osKeyboardLayout:label:keymap_us,Inglés (Estados Unidos) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/fr.csv b/src/i18n/fr.csv index b530b2dcf4..6bf78f8d7a 100644 --- a/src/i18n/fr.csv +++ b/src/i18n/fr.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,Permet d'entrer les touches via votre clavier sans cliquer sur chaque position. settingsPanel:fastInput:label,Entrée Rapide settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,Afficher les légendes ISO par défaut -settingsPanel:iso:label,Utiliser les légendes des clés ISO +settingsPanel:osKeyboardLayout:title,Disposition des touches du système d'opération +settingsPanel:osKeyboardLayout:help,Change les légendes des touches pour qu'elles collent avec la disposition des touches du système. +settingsPanel:osKeyboardLayout:label:keymap_german,Allemand (Allemagne & Autriche) +settingsPanel:osKeyboardLayout:label:keymap_russian,Russe +settingsPanel:osKeyboardLayout:label:keymap_uk,Anglais (Royaume-Uni) +settingsPanel:osKeyboardLayout:label:keymap_us,Anglais (États-Unis) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/it.csv b/src/i18n/it.csv index 2f1a6830da..2729b07938 100644 --- a/src/i18n/it.csv +++ b/src/i18n/it.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,Ctrl + Alt + U settingsPanel:fastInput:help,Inserire i tasti tramite la tastiera senza fare clic su ogni posizione. settingsPanel:fastInput:label,Ingresso rapido settingsPanel:fastInput:title,Ctrl + Alt + F -settingsPanel:iso:help,Visualizza le legende ISO automaticamente -settingsPanel:iso:label,Usa le legende delle chiavi ISO +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,Tedesco (Germania e Austria) +settingsPanel:osKeyboardLayout:label:keymap_russian,Russo +settingsPanel:osKeyboardLayout:label:keymap_uk,Inglese (Regno Unito) +settingsPanel:osKeyboardLayout:label:keymap_us,Inglese (US) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help,Cambia lingua dell'interfaccia utente diff --git a/src/i18n/ja.csv b/src/i18n/ja.csv index 3ea4da19db..cf9977ab6c 100644 --- a/src/i18n/ja.csv +++ b/src/i18n/ja.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,各位置をクリックせずキーボードでキーを入力する settingsPanel:fastInput:label,高速入力 settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,デフォルトでISO凡例を表示 -settingsPanel:iso:label,ISOキーの凡例を使用する +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,ドイツ語(ドイツ・オーストリア) +settingsPanel:osKeyboardLayout:label:keymap_russian,ロシア語 +settingsPanel:osKeyboardLayout:label:keymap_uk,英語 (UK) +settingsPanel:osKeyboardLayout:label:keymap_us,英語 (US) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help,ユーザインタフェースの言語を変更する diff --git a/src/i18n/ms.csv b/src/i18n/ms.csv index fd7360d627..54d1c50bd0 100644 --- a/src/i18n/ms.csv +++ b/src/i18n/ms.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,Masukkan kekunci melalui papan kekunci tanpa klik setiap posisi. settingsPanel:fastInput:label,Input cepat settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,Paparkan lagenda ISO secara lalai -settingsPanel:iso:label,Gunakan lagenda kunci ISO +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german, +settingsPanel:osKeyboardLayout:label:keymap_russian, +settingsPanel:osKeyboardLayout:label:keymap_uk, +settingsPanel:osKeyboardLayout:label:keymap_us, settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/pl-PL.csv b/src/i18n/pl-PL.csv index 1c38d04365..56fb745ddd 100644 --- a/src/i18n/pl-PL.csv +++ b/src/i18n/pl-PL.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,Ctrl + Alt + U settingsPanel:fastInput:help,Autmatyczne podświetlanie kolejnego klawisza po zdefiniowaniu funkcji poprzedniego. settingsPanel:fastInput:label,Szybkie wprowadzanie settingsPanel:fastInput:title,Ctrl + Alt + F -settingsPanel:iso:help,Domyślnie wyświetlaj legendy ISO -settingsPanel:iso:label,Użyj legendy kluczy ISO +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,Niemiecki (Niemcy i Austria) +settingsPanel:osKeyboardLayout:label:keymap_russian,Rosyjski +settingsPanel:osKeyboardLayout:label:keymap_uk,Angielski (UK) +settingsPanel:osKeyboardLayout:label:keymap_us,Angielski (US) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/pt-BR.csv b/src/i18n/pt-BR.csv index c1a8790b48..9faf29ce8e 100644 --- a/src/i18n/pt-BR.csv +++ b/src/i18n/pt-BR.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,Entrada de comandos a partir do teclado sem clicar em outra posição. settingsPanel:fastInput:label,Entrada rápida settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,Exibir legendas ISO por padrão -settingsPanel:iso:label,Use as legendas da chave ISO +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,Alemão (Alemanha e Áustria) +settingsPanel:osKeyboardLayout:label:keymap_russian,Russo +settingsPanel:osKeyboardLayout:label:keymap_uk,Inglês (Reino Unido) +settingsPanel:osKeyboardLayout:label:keymap_us,Inglês (EUA) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/ru.csv b/src/i18n/ru.csv index 97616c9fbf..853caea030 100644 --- a/src/i18n/ru.csv +++ b/src/i18n/ru.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,Ввод клавиш через клавиатуру без необходимости нажимать на каждую позицию settingsPanel:fastInput:label,Быстрый ввод settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,Отображать легенды ISO по умолчанию -settingsPanel:iso:label,Используйте ключевые легенды ISO +settingsPanel:osKeyboardLayout:title,Раскладка клавиатуры операционной системы +settingsPanel:osKeyboardLayout:help,Изменяет легенды клавиш в соответствии с раскладкой клавиатуры операционной системы. +settingsPanel:osKeyboardLayout:label:keymap_german,Немецкий (Германия и Австрия) +settingsPanel:osKeyboardLayout:label:keymap_russian,Русский +settingsPanel:osKeyboardLayout:label:keymap_uk,Английский (Великобритания) +settingsPanel:osKeyboardLayout:label:keymap_us,Английский (США) settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/i18n/zh-CN.csv b/src/i18n/zh-CN.csv index 056b56bdad..b8fbf8eac4 100644 --- a/src/i18n/zh-CN.csv +++ b/src/i18n/zh-CN.csv @@ -111,8 +111,12 @@ settingsPanel:displaySizes:title,ctrl + alt + u settingsPanel:fastInput:help,直接通过键盘输入键位 settingsPanel:fastInput:label,快速输入 settingsPanel:fastInput:title,ctrl + alt + f -settingsPanel:iso:help,默认显示 ISO 图例 -settingsPanel:iso:label,使用 ISO 密钥图例 +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german,德语(德国和奥地利) +settingsPanel:osKeyboardLayout:label:keymap_russian,俄语 +settingsPanel:osKeyboardLayout:label:keymap_uk,英语(英国) +settingsPanel:osKeyboardLayout:label:keymap_us,英语(美国) settingsPanel:kcno:label, settingsPanel:kctrns:label, settingsPanel:language:help,更改用户界面语言 diff --git a/src/i18n/zh.csv b/src/i18n/zh.csv index bbfede5992..2f83561f32 100644 --- a/src/i18n/zh.csv +++ b/src/i18n/zh.csv @@ -109,8 +109,12 @@ settingsPanel:displaySizes:title, settingsPanel:fastInput:help, settingsPanel:fastInput:label, settingsPanel:fastInput:title, -settingsPanel:iso:help, -settingsPanel:iso:label, +settingsPanel:osKeyboardLayout:title, +settingsPanel:osKeyboardLayout:help, +settingsPanel:osKeyboardLayout:label:keymap_german, +settingsPanel:osKeyboardLayout:label:keymap_russian, +settingsPanel:osKeyboardLayout:label:keymap_uk, +settingsPanel:osKeyboardLayout:label:keymap_us, settingsPanel:kcno:label,KC_NO settingsPanel:kctrns:label,KC_TRNS settingsPanel:language:help, diff --git a/src/store/modules/app/actions.js b/src/store/modules/app/actions.js index c6d5e65142..ef881f403e 100644 --- a/src/store/modules/app/actions.js +++ b/src/store/modules/app/actions.js @@ -136,6 +136,11 @@ const actions = { commit('setCurrentLanguage', lang); await dispatch('saveConfiguratorSettings'); }, + async changeOSKeyboardLayout({ dispatch, commit }, osLayout) { + commit('setOSKeyboardLayout', osLayout); + this.commit('keycodes/changeKeyLegends'); + await dispatch('saveConfiguratorSettings'); + }, // if init state we just load and not toggling async toggleDarkMode({ commit, state, dispatch }, init) { let darkStatus = state.configuratorSettings.darkmodeEnabled; diff --git a/src/store/modules/app/mutations.js b/src/store/modules/app/mutations.js index c120cbfe43..6cd62214f3 100644 --- a/src/store/modules/app/mutations.js +++ b/src/store/modules/app/mutations.js @@ -181,6 +181,9 @@ const mutations = { setDarkmode(state, value) { state.configuratorSettings.darkmodeEnabled = value; }, + setOSKeyboardLayout(state, value) { + state.configuratorSettings.osKeyboardLayout = value; + }, setIso(state, value) { state.configuratorSettings.iso = value; }, diff --git a/src/store/modules/app/state.js b/src/store/modules/app/state.js index e799b0fd97..a2f42e7981 100644 --- a/src/store/modules/app/state.js +++ b/src/store/modules/app/state.js @@ -15,7 +15,8 @@ function setDefaultConfiguratorSettings() { favoriteKeyboard: '', favoriteColor: '', clearLayerDefault: false, - iso: false + iso: false, + osKeyboardLayout: 'keymap_us' }; localStorageSet(CONSTS.configuratorSettings, JSON.stringify(initialConfig)); return initialConfig; @@ -75,6 +76,13 @@ const state = { { value: 'ja', label: '日本語' }, { value: 'zh-CN', label: '简体中文' } ], + osKeyboardLayouts: [ + // The labels are translatable strings + 'keymap_us', + 'keymap_uk', + 'keymap_german', + 'keymap_russian' + ], snowflakes: false }; diff --git a/src/store/modules/keycodes/index.js b/src/store/modules/keycodes/index.js index 6f3c213f1f..1023be2769 100644 --- a/src/store/modules/keycodes/index.js +++ b/src/store/modules/keycodes/index.js @@ -6,15 +6,19 @@ import settings from './kb-settings'; import media from './app-media-mouse'; import steno from './steno'; import store from '@/store'; +import keymapExtras from '@/i18n/keymap_extras'; -const keycodeLayout = { - ANSI: [...ansi, ...iso_jis], - ISO: [...iso_jis, ...ansi], - normal: [...quantum, ...settings, ...media] +const keycodePickerTabLayout = { + ANSI_ISO: [...ansi, ...iso_jis], + ISO_ANSI: [...iso_jis, ...ansi], + special: [...quantum, ...settings, ...media] }; const state = { - keycodes: [...keycodeLayout.ANSI, ...keycodeLayout.normal], + keycodes: [ + ...keycodePickerTabLayout.ANSI_ISO, + ...keycodePickerTabLayout.special + ], searchFilter: '', searchCounters: { ANSI: 0, @@ -27,17 +31,55 @@ const state = { active: 'ANSI' }; -function isISO() { - return store.state.app.configuratorSettings.iso; +function getOSKeyboardLayout() { + const fallbackOSKeyboardLayout = 'keymap_us'; + return ( + store.state.app.configuratorSettings.osKeyboardLayout || + fallbackOSKeyboardLayout + ); } -function generateKeycodes(isIso, isSteno) { +function isANSI() { + return keymapExtras[getOSKeyboardLayout()].isANSI; +} + +function toLocaleKeycode(keycodeLUT, keycodeObject) { + console.assert(!isUndefined(keycodeLUT)); + if ( + !Object.keys(keycodeObject).includes('name') || + !Object.keys(keycodeObject).includes('code') + ) { + // Not an object describing a keyboard key; return as is + return keycodeObject; + } + if (keycodeLUT[keycodeObject.code]) { + // Clone in a shallow manner the original keycodeObject object and + // override the name, title, and possibly other fields + return { ...keycodeObject, ...keycodeLUT[keycodeObject.code] }; + } else { + return keycodeObject; + } +} + +function generateKeycodes(osKeyboardLayout, isSteno) { + store.state.app.configuratorSettings.iso = !isANSI(); const keycodes = [ - ...(isIso ? keycodeLayout.ISO : keycodeLayout.ANSI), - ...keycodeLayout.normal, + ...(isANSI() + ? keycodePickerTabLayout.ANSI_ISO + : keycodePickerTabLayout.ISO_ANSI), + ...keycodePickerTabLayout.special, ...(isSteno ? steno : []) ]; - return keycodes; + if (!Object.keys(keymapExtras).includes(getOSKeyboardLayout())) { + console.log( + `${getOSKeyboardLayout()} is not a valid OS keyboard layout value!` + ); + return keycodes; + } + const { keycodeLUT } = keymapExtras[getOSKeyboardLayout()]; + return keycodes.map((keycodeObject) => + toLocaleKeycode(keycodeLUT, keycodeObject) + ); } const getters = { @@ -76,22 +118,22 @@ const mutations = { }, enableSteno(state) { state.steno = true; - state.keycodes = generateKeycodes(isISO(), state.steno); + state.keycodes = generateKeycodes(getOSKeyboardLayout(), state.steno); }, disableSteno(state) { state.steno = false; - state.keycodes = generateKeycodes(isISO(), state.steno); - }, - enableIso(state) { - state.keycodes = generateKeycodes(isISO(), state.steno); - if (state.active === 'ANSI') { - state.active = 'ISO/JIS'; - } + state.keycodes = generateKeycodes(getOSKeyboardLayout(), state.steno); }, - disableIso(state) { - state.keycodes = generateKeycodes(isISO(), state.steno); - if (state.active === 'ISO/JIS') { - state.active = 'ANSI'; + changeKeyLegends(state) { + state.keycodes = generateKeycodes(getOSKeyboardLayout(), state.steno); + if (isANSI()) { + if (state.active === 'ISO/JIS') { + state.active = 'ANSI'; + } + } else { + if (state.active === 'ANSI') { + state.active = 'ISO/JIS'; + } } }, setSearchFilter(state, newVal) { From 02fb83508415f42b87df466635ac88dc34e1e151 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 13 Aug 2022 00:01:45 +0200 Subject: [PATCH 05/28] Prettify default quantum keycodes info --- src/store/modules/keycodes/quantum.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/store/modules/keycodes/quantum.js b/src/store/modules/keycodes/quantum.js index fc81500f49..90c5921582 100644 --- a/src/store/modules/keycodes/quantum.js +++ b/src/store/modules/keycodes/quantum.js @@ -392,37 +392,37 @@ export default [ { label: 'Special action keys', width: 'label' }, { - name: 'Esc/~', + name: '` / ~\nEsc', code: 'QK_GESC', - title: 'Esc normally, but ~ when Shift or GUI is pressed' + title: 'Esc normally, but ` when GUI is active or ~ when Shift is active' }, { - name: 'LS/(', + name: 'LS / (', code: 'KC_LSPO', title: 'Left Shift when held, ( when tapped' }, { - name: 'RS/)', + name: 'RS / )', code: 'KC_RSPC', title: 'Right Shift when held, ) when tapped' }, { - name: 'LC/(', + name: 'LC / (', code: 'KC_LCPO', title: 'Left Control when held, ( when tapped' }, { - name: 'RC/)', + name: 'RC / )', code: 'KC_RCPC', title: 'Right Control when held, ) when tapped' }, { - name: 'LA/(', + name: 'LA / (', code: 'KC_LAPO', title: 'Left Alt when held, ( when tapped' }, { - name: 'RA/)', + name: 'RA / )', code: 'KC_RAPC', title: 'Right Alt when held, ) when tapped' }, From c1a24f610bdb42ba05942e237ddec8f57f85c70c Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 13 Aug 2022 17:57:34 +0200 Subject: [PATCH 06/28] Refactor KC_NUHS/KC_BSLS gen funcs --- .../convert_keymap_extras_header.js | 98 ++++++------------- 1 file changed, 32 insertions(+), 66 deletions(-) mode change 100644 => 100755 src/i18n/keymap_extras/convert_keymap_extras_header.js diff --git a/src/i18n/keymap_extras/convert_keymap_extras_header.js b/src/i18n/keymap_extras/convert_keymap_extras_header.js old mode 100644 new mode 100755 index e2b27b5512..c03b2e86d3 --- a/src/i18n/keymap_extras/convert_keymap_extras_header.js +++ b/src/i18n/keymap_extras/convert_keymap_extras_header.js @@ -273,70 +273,38 @@ function convertLine(line, kcInfo, intl2us) { return line; } -function generateMissingKcBsls(kcInfo) { - // If no explicit mapping for KC_BSLS exist, as is the case for many ISO layouts, fall - // back to the KC_NUHS mapping. - if (kcInfo.has('KC_BSLS')) { - return ''; - } - if (!kcInfo.has('KC_NUHS')) { - throw new Error( - 'The input file is missing a mapping to both KC_BSLS and KC_NUHS. At least one of them must be mapped to an locale alias!' - ); - } - const kcNuhsInfo = kcInfo.get('KC_NUHS'); - const shiftedNuhsInfo = kcInfo.get('S(KC_NUHS)'); - // Copy the KC_NUHS kc info object but replace the associated intl alias with KC_BSLS/KC_PIPE. - // Since it is pointless to repeat the US kc alias in the title, we only keep the clarification. - const kcBslsInfo = { - ...kcNuhsInfo, - intlAlias: 'KC_BSLS', - title: kcNuhsInfo.clarification - }; - const kcPipeInfo = { - ...shiftedNuhsInfo, - intlAlias: 'KC_PIPE', - title: shiftedNuhsInfo.clarification - }; - kcInfo.set('KC_BSLS', kcBslsInfo); - kcInfo.set('S(KC_BSLS)', kcPipeInfo); - kcInfo.set('KC_PIPE', kcPipeInfo); - let bslsInfoLines = stringify('KC_BSLS', kcBslsInfo) + '\n'; - bslsInfoLines += stringify('S(KC_BSLS)', kcPipeInfo) + '\n'; - bslsInfoLines += stringify('KC_PIPE', kcPipeInfo); - return bslsInfoLines; -} - -function generateMissingKcNuhs(kcInfo) { - // If no explicit mapping for KC_NUHS exist, as is the case for many ANSI layouts, fall - // back to the KC_BSLS mapping. - if (kcInfo.has('KC_NUHS')) { - return ''; - } - if (!kcInfo.has('KC_BSLS')) { - throw new Error( - 'The input file is missing a mapping to both KC_BSLS and KC_NUHS. At least one of them must be mapped to an locale alias!' - ); +function generateMissingANSISOkeys(kcInfo) { + const fallbackKc = kcInfo.has('KC_BSLS') ? 'KC_BSLS' : 'KC_NUHS'; + const missingKcs = ['KC_BSLS', 'KC_NUHS', 'KC_NUBS'].filter( + (kc) => !kcInfo.has(kc) + ); + let missingKcInfoLines = []; + for (const missingKc of missingKcs) { + baseKcInfo = kcInfo.get(fallbackKc); + shiftedKcInfo = kcInfo.get(`S(${fallbackKc})`) || baseKcInfo; + if (baseKcInfo === undefined || shiftedKcInfo === undefined) { + throw new Error( + 'The input file is missing a mapping to both KC_BSLS and KC_NUHS. At least one of them must be mapped to a locale alias!' + ); + } + // Copy the KC_NUHS kc info object but replace the associated intl alias with KC_BSLS/KC_PIPE. + // Since it is pointless to repeat the US kc alias in the title, we only keep the clarification. + const missingKcInfo = { + ...baseKcInfo, + intlAlias: fallbackKc, + title: baseKcInfo.clarification + }; + const missingShiftedKcInfo = { + ...shiftedKcInfo, + intlAlias: fallbackKc, + title: shiftedKcInfo.clarification + }; + kcInfo.set(missingKc, missingKcInfo); + kcInfo.set(`S(${missingKc})`, missingShiftedKcInfo); + missingKcInfoLines.push(stringify(missingKc, missingKcInfo)); + missingKcInfoLines.push(stringify(`S(${missingKc})`, missingShiftedKcInfo)); } - const kcBslsInfo = kcInfo.get('KC_BSLS'); - const kcPipeInfo = kcInfo.get('S(KC_BSLS)'); - // Copy the KC_BSLS kc info object but replace the associated intl alias with KC_NUHS. - // Since it is pointless to repeat the US kc alias in the title, we only keep the clarification. - const kcNuhsInfo = { - ...kcBslsInfo, - intlAlias: 'KC_NUHS', - title: kcBslsInfo.clarification - }; - const shiftedNuhsInfo = { - ...kcPipeInfo, - intlAlias: 'S(KC_NUHS)', - title: kcPipeInfo.clarification - }; - kcInfo.set('KC_NUHS', kcNuhsInfo); - kcInfo.set('S(KC_NUHS)', shiftedNuhsInfo); - let nuhsInfoLines = stringify('KC_NUHS', kcNuhsInfo) + '\n'; - nuhsInfoLines += stringify('S(KC_NUHS)', shiftedNuhsInfo); - return nuhsInfoLines; + return missingKcInfoLines.join('\n'); } function generateMissingShiftedAliasKcInfo(kcInfo) { @@ -405,9 +373,7 @@ fs.readFile(process.argv.at(-1), 'utf8', function (err, data) { ); console.log(convertedLines.join('\n')); console.log('/* Other keys */'); - console.log(generateMissingKcBsls(kcInfo)); - console.log(generateMissingKcNuhs(kcInfo)); - console.log(generateMissingShiftedAliasKcInfo(kcInfo)); + console.log(generateMissingANSISOkeys(kcInfo)); spaceCadetKeycodes = [ 'KC_LSPO', 'KC_RSPC', From 841e99175892214063479d6892294f46c808c1f9 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sun, 14 Aug 2022 21:45:40 +0200 Subject: [PATCH 07/28] Warn if keysym.length > 3 No need to warn if keysym.length is 1 or 2 --- src/i18n/keymap_extras/convert_keymap_extras_header.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/keymap_extras/convert_keymap_extras_header.js b/src/i18n/keymap_extras/convert_keymap_extras_header.js index c03b2e86d3..4d66c2552d 100755 --- a/src/i18n/keymap_extras/convert_keymap_extras_header.js +++ b/src/i18n/keymap_extras/convert_keymap_extras_header.js @@ -174,9 +174,9 @@ function computeKcInfo(lines, intl2us) { } else if (keysym.length === 1 && invisibleChar2readableName.has(keysym)) { readableKeysym = invisibleChar2readableName.get(keysym); } - if (keysym.length > 1) { + if (keysym.length > 3) { console.error( - `Warning: parsing the line below associated a keysym of length greater than 1 (${keysym}) to ${intlAlias} aka ${macroExpansion}. This may cause the key legend text to overflow.` + `Warning: parsing the line below associated a keysym of length greater than 3 (${keysym}) to ${intlAlias} aka ${macroExpansion}. This may cause the key legend text to overflow.` ); console.error(fullMatch); } From cde87dbf17edb69fd84008466c05004746920be8 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sun, 14 Aug 2022 21:49:28 +0200 Subject: [PATCH 08/28] Use intlAlias for title of missing shifted aliases --- src/i18n/keymap_extras/convert_keymap_extras_header.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/i18n/keymap_extras/convert_keymap_extras_header.js b/src/i18n/keymap_extras/convert_keymap_extras_header.js index 4d66c2552d..dbd56059e9 100755 --- a/src/i18n/keymap_extras/convert_keymap_extras_header.js +++ b/src/i18n/keymap_extras/convert_keymap_extras_header.js @@ -291,12 +291,10 @@ function generateMissingANSISOkeys(kcInfo) { // Since it is pointless to repeat the US kc alias in the title, we only keep the clarification. const missingKcInfo = { ...baseKcInfo, - intlAlias: fallbackKc, title: baseKcInfo.clarification }; const missingShiftedKcInfo = { ...shiftedKcInfo, - intlAlias: fallbackKc, title: shiftedKcInfo.clarification }; kcInfo.set(missingKc, missingKcInfo); @@ -316,7 +314,7 @@ function generateMissingShiftedAliasKcInfo(kcInfo) { const shiftedAliasKcInfo = { ...(kcInfo.get(shiftedKc) || kcInfo.get(extractBasicKc(shiftedKc))) }; - shiftedAliasKcInfo.title = `S(${shiftedAliasKcInfo.title})`; + shiftedAliasKcInfo.title = `S(${shiftedAliasKcInfo.intlAlias})`; const letterRegExp = /^\p{L}$/u; if (letterRegExp.test(shiftedAliasKcInfo.keysym)) { shiftedAliasKcInfo.title += ` (capital ${shiftedAliasKcInfo.keysym})`; @@ -374,6 +372,7 @@ fs.readFile(process.argv.at(-1), 'utf8', function (err, data) { console.log(convertedLines.join('\n')); console.log('/* Other keys */'); console.log(generateMissingANSISOkeys(kcInfo)); + console.log(generateMissingShiftedAliasKcInfo(kcInfo)); spaceCadetKeycodes = [ 'KC_LSPO', 'KC_RSPC', From 6a75bd79928d7ab08cf6d64934a0bac31b1660dd Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Thu, 18 Aug 2022 19:47:59 +0200 Subject: [PATCH 09/28] Remove en-UK --- src/i18n/keymap_extras/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/keymap_extras/index.js b/src/i18n/keymap_extras/index.js index d843992a17..bffb702c3d 100644 --- a/src/i18n/keymap_extras/index.js +++ b/src/i18n/keymap_extras/index.js @@ -36,7 +36,7 @@ export default { prefix: 'UK', sendstring: 'uk', isANSI: false, - locales: ['en-UK', 'en-GB', 'en'], + locales: ['en-GB', 'en'], keycodeLUT: uk }, keymap_german: { From 0e8253140245d6a0f70107bf490da3da1be67dfe Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Thu, 18 Aug 2022 22:16:42 +0200 Subject: [PATCH 10/28] Handle KC_PIPE exceptionally in generateMissingShiftedAliasKcInfo --- src/i18n/keymap_extras/convert_keymap_extras_header.js | 9 ++++++++- src/i18n/keymap_extras/keymap_german.js | 3 +-- src/i18n/keymap_extras/keymap_russian.js | 3 ++- src/i18n/keymap_extras/keymap_uk.js | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/i18n/keymap_extras/convert_keymap_extras_header.js b/src/i18n/keymap_extras/convert_keymap_extras_header.js index dbd56059e9..1da2bc7e5f 100755 --- a/src/i18n/keymap_extras/convert_keymap_extras_header.js +++ b/src/i18n/keymap_extras/convert_keymap_extras_header.js @@ -314,7 +314,14 @@ function generateMissingShiftedAliasKcInfo(kcInfo) { const shiftedAliasKcInfo = { ...(kcInfo.get(shiftedKc) || kcInfo.get(extractBasicKc(shiftedKc))) }; - shiftedAliasKcInfo.title = `S(${shiftedAliasKcInfo.intlAlias})`; + // In virtue of `generateMissingANSISOkeys`, the intlAlias of the kc info object associated + // to S(KC_BSLS)/KC_PIPE is already a shifted keycode to begin with, no need to surround it + // with `S()`. + if (shiftedAlias === 'KC_PIPE') { + shiftedAliasKcInfo.title = shiftedAliasKcInfo.intlAlias; + } else { + shiftedAliasKcInfo.title = `S(${shiftedAliasKcInfo.intlAlias})`; + } const letterRegExp = /^\p{L}$/u; if (letterRegExp.test(shiftedAliasKcInfo.keysym)) { shiftedAliasKcInfo.title += ` (capital ${shiftedAliasKcInfo.keysym})`; diff --git a/src/i18n/keymap_extras/keymap_german.js b/src/i18n/keymap_extras/keymap_german.js index 7cc5f4929d..e25025d8e6 100644 --- a/src/i18n/keymap_extras/keymap_german.js +++ b/src/i18n/keymap_extras/keymap_german.js @@ -167,10 +167,9 @@ export default { /* Other keys */ KC_BSLS: { name: "'\n#", title: '' }, 'S(KC_BSLS)': { name: "'", title: '' }, - KC_PIPE: { name: "'", title: '' }, - KC_LCBR: { name: 'Ü', title: 'S(DE_UDIA) (capital Ü)' }, KC_COLN: { name: 'Ö', title: 'S(DE_ODIA) (capital Ö)' }, + KC_PIPE: { name: "'", title: 'DE_QUOT' }, KC_DQUO: { name: 'Ä', title: 'S(DE_ADIA) (capital Ä)' }, KC_LSPO: { name: 'LS / )', title: 'Left Shift when held, ) when tapped' }, diff --git a/src/i18n/keymap_extras/keymap_russian.js b/src/i18n/keymap_extras/keymap_russian.js index 1941a476f1..6a77666a3f 100644 --- a/src/i18n/keymap_extras/keymap_russian.js +++ b/src/i18n/keymap_extras/keymap_russian.js @@ -142,9 +142,10 @@ export default { 'ALGR(KC_8)': { name: '₽', title: 'RU_RUBL' }, /* Other keys */ - KC_NUHS: { name: '/\n\\', title: '' }, 'S(KC_NUHS)': { name: '/', title: '' }, + KC_NUBS: { name: '/\n\\', title: '' }, + 'S(KC_NUBS)': { name: '/', title: '' }, KC_TILD: { name: 'Ё', title: 'S(RU_YO) (capital Ё)' }, KC_LCBR: { name: 'Х', title: 'S(RU_HA) (capital Х)' }, KC_RCBR: { name: 'Ъ', title: 'S(RU_HARD) (capital Ъ)' }, diff --git a/src/i18n/keymap_extras/keymap_uk.js b/src/i18n/keymap_extras/keymap_uk.js index 4598d053d5..dfad145caa 100644 --- a/src/i18n/keymap_extras/keymap_uk.js +++ b/src/i18n/keymap_extras/keymap_uk.js @@ -168,7 +168,7 @@ export default { /* Other keys */ KC_BSLS: { name: '~\n#', title: '' }, 'S(KC_BSLS)': { name: '~', title: '' }, - KC_PIPE: { name: '~', title: '' }, + KC_PIPE: { name: '~', title: 'UK_TILD' }, KC_LSPO: { name: 'LS / (', title: 'Left Shift when held, ( when tapped' }, KC_RSPC: { name: 'RS / )', title: 'Right Shift when held, ) when tapped' }, From 4a6e0e6581906302f808b26729a994aeaf41fbd2 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Thu, 18 Aug 2022 22:24:39 +0200 Subject: [PATCH 11/28] Comment and organise keymap_us.js --- src/i18n/keymap_extras/keymap_us.js | 209 ++++++++++++++++------------ 1 file changed, 120 insertions(+), 89 deletions(-) diff --git a/src/i18n/keymap_extras/keymap_us.js b/src/i18n/keymap_extras/keymap_us.js index 7c56c2ac2e..39813ee995 100644 --- a/src/i18n/keymap_extras/keymap_us.js +++ b/src/i18n/keymap_extras/keymap_us.js @@ -1,20 +1,34 @@ +/* Copyright 2022 - Generated by convert_keymap_extras_header.js + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + export default { - KC_ESC: { name: 'Esc', title: '' }, - KC_F1: { name: 'F1', title: '' }, - KC_F2: { name: 'F2', title: '' }, - KC_F3: { name: 'F3', title: '' }, - KC_F4: { name: 'F4', title: '' }, - KC_F5: { name: 'F5', title: '' }, - KC_F6: { name: 'F6', title: '' }, - KC_F7: { name: 'F7', title: '' }, - KC_F8: { name: 'F8', title: '' }, - KC_F9: { name: 'F9', title: '' }, - KC_F10: { name: 'F10', title: '' }, - KC_F11: { name: 'F11', title: '' }, - KC_F12: { name: 'F12', title: '' }, - KC_PSCR: { name: 'Print Screen', title: '' }, - KC_SCRL: { name: 'Scroll Lock', title: '' }, - KC_PAUS: { name: 'Pause', title: '' }, + /* + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ + * │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ + * │ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 KC_GRV: { name: '~\n`', title: '' }, KC_1: { name: '!\n1', title: '' }, KC_2: { name: '@\n2', title: '' }, @@ -28,102 +42,119 @@ export default { KC_0: { name: ')\n0', title: '' }, KC_MINS: { name: '_\n-', title: '' }, KC_EQL: { name: '+\n=', title: '' }, - KC_BSPC: { name: 'Back Space', title: '' }, - KC_INS: { name: 'Insert', title: '' }, - KC_HOME: { name: 'Home', title: '' }, - KC_PGUP: { name: 'Page Up', title: '' }, - KC_NUM: { name: 'Num Lock', title: '' }, - KC_PSLS: { name: '/', title: '' }, - KC_PAST: { name: '*', title: '' }, - KC_PMNS: { name: '-', title: '' }, - KC_TAB: { name: 'Tab', title: '' }, - KC_Q: { name: 'q', title: '' }, - KC_W: { name: 'w', title: '' }, - KC_E: { name: 'e', title: '' }, - KC_R: { name: 'r', title: '' }, - KC_T: { name: 't', title: '' }, - KC_Y: { name: 'y', title: '' }, - KC_U: { name: 'u', title: '' }, - KC_I: { name: 'i', title: '' }, - KC_O: { name: 'o', title: '' }, - KC_P: { name: 'p', title: '' }, + // Row 2 + KC_Q: { name: 'Q', title: '' }, + KC_W: { name: 'W', title: '' }, + KC_E: { name: 'E', title: '' }, + KC_R: { name: 'R', title: '' }, + KC_T: { name: 'T', title: '' }, + KC_Y: { name: 'Y', title: '' }, + KC_U: { name: 'U', title: '' }, + KC_I: { name: 'I', title: '' }, + KC_O: { name: 'O', title: '' }, + KC_P: { name: 'P', title: '' }, KC_LBRC: { name: '{\n[', title: '' }, KC_RBRC: { name: '}\n]', title: '' }, KC_BSLS: { name: '|\n\\', title: '' }, - KC_DEL: { name: 'Delete', title: '' }, - KC_END: { name: 'End', title: '' }, - KC_PGDN: { name: 'Page Down', title: '' }, - KC_P7: { name: '7', title: '' }, - KC_P8: { name: '8', title: '' }, - KC_P9: { name: '9', title: '' }, - KC_PPLS: { name: '+', title: '' }, - KC_CAPS: { name: 'Caps Lock', title: '' }, - KC_A: { name: 'a', title: '' }, - KC_S: { name: 's', title: '' }, - KC_D: { name: 'd', title: '' }, - KC_F: { name: 'f', title: '' }, - KC_G: { name: 'g', title: '' }, - KC_H: { name: 'h', title: '' }, - KC_J: { name: 'j', title: '' }, - KC_K: { name: 'k', title: '' }, - KC_L: { name: 'l', title: '' }, + // Row 3 + KC_A: { name: 'A', title: '' }, + KC_S: { name: 'S', title: '' }, + KC_D: { name: 'D', title: '' }, + KC_F: { name: 'F', title: '' }, + KC_G: { name: 'G', title: '' }, + KC_H: { name: 'H', title: '' }, + KC_J: { name: 'J', title: '' }, + KC_K: { name: 'K', title: '' }, + KC_L: { name: 'L', title: '' }, KC_SCLN: { name: ':\n;', title: '' }, - KC_QUOT: { name: '"\n\'', keys: "'", title: '' }, - KC_ENT: { name: 'Enter', title: '' }, - KC_P4: { name: '4', title: '' }, - KC_P5: { name: '5', title: '' }, - KC_P6: { name: '6', title: '' }, - KC_PCMM: { name: ',', title: '' }, - KC_LSFT: { name: 'Left Shift', title: '' }, - KC_Z: { name: 'z', title: '' }, - KC_X: { name: 'x', title: '' }, - KC_C: { name: 'c', title: '' }, - KC_V: { name: 'v', title: '' }, - KC_B: { name: 'b', title: '' }, - KC_N: { name: 'n', title: '' }, - KC_M: { name: 'm', title: '' }, + KC_QUOT: { name: '"\n\'', title: '' }, + // Row 4 + KC_Z: { name: 'Z', title: '' }, + KC_X: { name: 'X', title: '' }, + KC_C: { name: 'C', title: '' }, + KC_V: { name: 'V', title: '' }, + KC_B: { name: 'B', title: '' }, + KC_N: { name: 'N', title: '' }, + KC_M: { name: 'M', title: '' }, KC_COMM: { name: '<\n,', title: '' }, KC_DOT: { name: '>\n.', title: '' }, KC_SLSH: { name: '?\n/', title: '' }, - KC_RSFT: { name: 'Right Shift', title: '' }, - KC_UP: { name: 'Up', title: '' }, - KC_P1: { name: '1', title: '' }, - KC_P2: { name: '2', title: '' }, - KC_P3: { name: '3', title: '' }, - KC_PEQL: { name: '=', title: '' }, - KC_LCTL: { name: 'Left Ctrl', title: '' }, - KC_LGUI: { name: 'Left OS', title: '' }, - KC_LALT: { name: 'Left Alt', title: '' }, - KC_SPC: { name: 'Space', title: '' }, - KC_RALT: { name: 'Right Alt', title: '' }, - KC_RGUI: { name: 'Right OS', title: '' }, - KC_APP: { name: 'Menu', title: 'Context Menu' }, - KC_RCTL: { name: 'Right Ctrl', title: '' }, - KC_LEFT: { name: 'Left', title: '' }, - KC_DOWN: { name: 'Down', title: '' }, - KC_RGHT: { name: 'Right', title: '' }, - KC_P0: { name: '0', title: '' }, - KC_PDOT: { name: '.', title: '' }, - KC_PENT: { name: 'Enter', title: '' }, + + /* Shifted symbols + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ + * │ │ │ │ │ │ │ │ │ │ │ │ { │ } │ | │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ + * │ │ │ │ │ │ │ │ │ │ │ : │ " │ │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ + * │ │ │ │ │ │ │ │ │ < │ > │ ? │ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ + * │ │ │ │ │ │ │ │ │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ + */ + // Row 1 + 'S(KC_GRV)': { name: '~', title: '' }, KC_TILD: { name: '~', title: '' }, + 'S(KC_1)': { name: '!', title: '' }, KC_EXLM: { name: '!', title: '' }, + 'S(KC_2)': { name: '@', title: '' }, KC_AT: { name: '@', title: '' }, + 'S(KC_3)': { name: '#', title: '' }, KC_HASH: { name: '#', title: '' }, + 'S(KC_4)': { name: '$', title: '' }, KC_DLR: { name: '$', title: '' }, + 'S(KC_5)': { name: '%', title: '' }, KC_PERC: { name: '%', title: '' }, + 'S(KC_6)': { name: '^', title: '' }, KC_CIRC: { name: '^', title: '' }, + 'S(KC_7)': { name: '&', title: '' }, KC_AMPR: { name: '&', title: '' }, + 'S(KC_8)': { name: '*', title: '' }, KC_ASTR: { name: '*', title: '' }, + 'S(KC_9)': { name: '(', title: '' }, KC_LPRN: { name: '(', title: '' }, + 'S(KC_0)': { name: ')', title: '' }, KC_RPRN: { name: ')', title: '' }, + 'S(KC_MINS)': { name: '_', title: '' }, KC_UNDS: { name: '_', title: '' }, + 'S(KC_EQL)': { name: '+', title: '' }, KC_PLUS: { name: '+', title: '' }, + // Row 2 + 'S(KC_LBRC)': { name: '{', title: '' }, KC_LCBR: { name: '{', title: '' }, + 'S(KC_RBRC)': { name: '}', title: '' }, KC_RCBR: { name: '}', title: '' }, + 'S(KC_BSLS)': { name: '|', title: '' }, + KC_PIPE: { name: '|', title: '' }, + // Row 3 + 'S(KC_SCLN)': { name: ':', title: '' }, + KC_COLN: { name: ':', title: '' }, + 'S(KC_QUOT)': { name: '"', title: '' }, + KC_DQUO: { name: '"', title: '' }, + // Row 4 + 'S(KC_COMM)': { name: '<', title: '' }, KC_LT: { name: '<', title: '' }, + 'S(KC_DOT)': { name: '>', title: '' }, KC_GT: { name: '>', title: '' }, - KC_COLN: { name: ':', title: '' }, - KC_PIPE: { name: '|', title: '' }, + 'S(KC_SLSH)': { name: '?', title: '' }, KC_QUES: { name: '?', title: '' }, - KC_DQUO: { name: '"', title: '' } + + /* Other keys */ + KC_NUHS: { name: '|\n\\', title: '' }, + 'S(KC_NUHS)': { name: '|', title: '' }, + KC_NUBS: { name: '|\n\\', title: '' }, + 'S(KC_NUBS)': { name: '|', title: '' }, + + KC_LSPO: { name: 'LS / (', title: 'Left Shift when held, ( when tapped' }, + KC_RSPC: { name: 'RS / )', title: 'Right Shift when held, ) when tapped' }, + KC_LCPO: { name: 'LC / (', title: 'Left Control when held, ( when tapped' }, + KC_RCPC: { name: 'RC / )', title: 'Right Control when held, ) when tapped' }, + KC_LAPO: { name: 'LA / (', title: 'Left Alt when held, ( when tapped' }, + KC_RAPC: { name: 'RA / )', title: 'Right Alt when held, ) when tapped' }, + + QK_GESC: { + name: '` / ~\nEsc', + title: 'Esc normally, but ` when GUI is active or ~ when Shift is active' + } }; From fc54838791a85bc0d07f2a513749e36ead928d43 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Thu, 18 Aug 2022 23:28:26 +0200 Subject: [PATCH 12/28] Locale-aware sort of the OS keyboard layouts by their labels. --- src/components/SettingsPanel.vue | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/SettingsPanel.vue b/src/components/SettingsPanel.vue index 8ecfaf1ef0..b06a15fb3d 100644 --- a/src/components/SettingsPanel.vue +++ b/src/components/SettingsPanel.vue @@ -105,7 +105,7 @@ v-model="osKeyboardLayout" >