Skip to content

feat(custom-keymap): Custom Keymap Style (@thewickest) #6375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
131cd68
feat: add custom keymaps style
thewickest Feb 19, 2025
73f2e9b
Merge branch 'master' into feature/custom-keymap
thewickest Feb 21, 2025
1fc7da3
feature: basic custom layout function. Many things to do still
thewickest Feb 21, 2025
beb25e4
Merge branch 'master' into feature/custom-keymap
thewickest Feb 21, 2025
5b8d5c8
feature: logic for custom keymap
thewickest Feb 24, 2025
f1e612e
To lowercase when style letter is dynamic
thewickest Feb 24, 2025
b651c80
Merge branch 'master' into feature/custom-keymap
thewickest Feb 28, 2025
f15eaef
feature: save custom keymap into database
thewickest Feb 28, 2025
9abde67
fix: wrong data key
thewickest Feb 28, 2025
4b75a76
fix: missing function when loading the settings
thewickest Mar 1, 2025
677d24c
feat: save keymap as object
thewickest Mar 4, 2025
865ce7e
Merge branch master into feature/custom-keymap
thewickest Mar 4, 2025
ef29e67
feat(custom-keymap): nullness
thewickest Mar 5, 2025
7c13009
Merge branch 'master' into feature/custom-keymap
thewickest Mar 5, 2025
74f2d3b
feat(custom-keymap): keycode for quot
thewickest Mar 6, 2025
73dbf68
feat(custom-keymap): proper apos or quote keycode
thewickest Mar 6, 2025
9977a5f
feat(custom-keymap): add custom keymap textarea style
thewickest Mar 8, 2025
e6148eb
feat(custom-keymap): remove comment
thewickest Mar 8, 2025
d2ef77e
impr(custom-keymap): move data keys to other side and remove comments
thewickest Mar 8, 2025
8b77e02
fix(custom-keymap): set textarea value correctly
thewickest Mar 9, 2025
e5062ab
fix(custom-keymap): fix wrong config setting
thewickest Mar 13, 2025
e1870d6
Merge branch 'master' into feature/custom-keymap
thewickest Mar 13, 2025
b5cdfd9
feat(custom-keymap): fix wrong custom keymap setup
thewickest Mar 13, 2025
557e97b
feat(custom-keymap): fix custom keymap showing up when other style
thewickest Mar 13, 2025
71d4f43
refactor(custom-keymap): refactor function that creates the custom ke…
thewickest Mar 14, 2025
4d679af
fix(custom-keymap): typo
thewickest Mar 14, 2025
1454336
fix(custom-keymap): fixing duplicate types for the keymapcustom
thewickest Mar 16, 2025
cd7d044
feat(custom-keymap): add commandline config
thewickest Mar 18, 2025
01e1fb4
feat(custom-keymap): add string sanitation
thewickest Mar 18, 2025
83ebe41
feat(custom-keymap): add inline styles for non-unit keys
thewickest Mar 19, 2025
dcfbd7b
fix(custom-keymap): use parseWithSchem from library
thewickest Mar 20, 2025
9f335d0
perf(custom-keymap): improve inline styles for non-oneunit keys
thewickest Mar 20, 2025
8952594
refactor(custom-keymap): improve string sanitation
thewickest Mar 21, 2025
b84e3a7
refactor(custom-keymap): json string sanitation
thewickest Mar 21, 2025
ab345cb
fix(custom-keymp): fix keyboard style
thewickest Mar 24, 2025
2086d9c
fix(custom-keymp): fix shift tracker
thewickest Mar 24, 2025
c46529d
Merge branch 'master' into feature/custom-keymap
thewickest Mar 27, 2025
1b1f681
refator(custom-keymap): center keymap
thewickest Mar 27, 2025
7dc66ac
feat(custom-keymap): adding subgroups for the commanline
thewickest Mar 29, 2025
5b6ee72
Merge branch 'master' into feature/custom-keymap
thewickest Apr 12, 2025
7757baf
feat(custom-keymap): support raw and json formats
thewickest Apr 12, 2025
3f40776
fix(custom-keymap): fix single command line for keymap custom
thewickest Apr 12, 2025
34f2d22
Merge branch master into feature/custom-keymap
thewickest Apr 17, 2025
7303a47
fix(custom-keymap): fix lint errors
thewickest Apr 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions frontend/src/html/pages/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,20 @@
<button data-config-value="split_matrix">split matrix</button>
<button data-config-value="steno">steno</button>
<button data-config-value="steno_matrix">steno matrix</button>
<button data-config-value="custom">custom</button>
</div>
</div>
<div class="section fullWidth" data-config-name="keymapCustom">
<div class="inputs">
<div class="textareaAndButton">
<textarea
class="textarea"
placeholder="place here the KLE keymap..."
></textarea>
<button class="save no-auto-handle">
<i class="fas fa-save fa-fw"></i>
</button>
</div>
</div>
</div>
<div class="section fullWidth" data-config-name="keymapLegendStyle">
Expand Down
18 changes: 18 additions & 0 deletions frontend/src/styles/keymap.scss
Original file line number Diff line number Diff line change
Expand Up @@ -544,4 +544,22 @@
position: relative;
}
}
&.custom {
.r1,
.r2,
.r3,
.r4,
.r5,
.r6 {
justify-content: center;
display: flex;
grid-template-columns: none;
}

.keymapSplitSpacer {
display: block;
width: 2rem;
height: 2rem;
}
}
}
23 changes: 23 additions & 0 deletions frontend/src/styles/settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,29 @@
}
}

.textareaAndButton {
display: grid;
grid-template-columns: 1fr;
gap: 0.5rem;
margin-bottom: 0.5rem;

span {
display: flex;
gap: 0.5rem;
}
.button {
height: auto;

.fas {
margin-right: 0rem;
}
}
.textarea {
height: 200px;
resize: none;
}
}

.rangeGroup {
display: grid;
grid-template-columns: auto 1fr;
Expand Down
34 changes: 34 additions & 0 deletions frontend/src/ts/commandline/lists/keymap-style.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { KeymapCustom } from "@monkeytype/contracts/schemas/configs";
import * as UpdateConfig from "../../config";
import { Command, CommandsSubgroup } from "../types";
import { stringToKeymap } from "../../utils/custom-keymap";
import * as TestLogic from "../../test/test-logic";

const subgroup: CommandsSubgroup = {
title: "Keymap style...",
Expand Down Expand Up @@ -61,6 +64,37 @@ const subgroup: CommandsSubgroup = {
UpdateConfig.setKeymapStyle("steno_matrix");
},
},
{
id: "setKeymapStyleCustom",
display: "custom...",
configValue: "custom",
icon: "fa-keyboard",
subgroup: {
title: "Set custom keymap?",
configKey: "keymapCustom",
list: [
{
id: "setKeymapStyleCustomNew",
display: "new keymap",
input: true,
exec: ({ input }) => {
if (input === undefined || input === "") return;
const keymap: KeymapCustom = stringToKeymap(input);
UpdateConfig.setKeymapCustom(keymap);
UpdateConfig.setKeymapStyle("custom");
TestLogic.restart();
},
},
{
id: "setKeymapStyleCustomLoad",
display: "load keymap",
exec: () => {
UpdateConfig.setKeymapStyle("custom");
},
},
],
},
},
],
};

Expand Down
30 changes: 21 additions & 9 deletions frontend/src/ts/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
typedKeys,
} from "./utils/misc";
import * as ConfigSchemas from "@monkeytype/contracts/schemas/configs";
import { Config } from "@monkeytype/contracts/schemas/configs";
import { Config, KeymapCustom } from "@monkeytype/contracts/schemas/configs";
import { Mode, ModeSchema } from "@monkeytype/contracts/schemas/shared";
import { Language, LanguageSchema } from "@monkeytype/contracts/schemas/util";
import { LocalStorageWithSchema } from "./utils/local-storage-with-schema";
Expand Down Expand Up @@ -1762,15 +1762,26 @@ export function setLayout(
return true;
}

// export function setSavedLayout(layout: string, nosave?: boolean): boolean {
// if (layout === null || layout === undefined) {
// layout = "qwerty";
// }
// config.savedLayout = layout;
// setLayout(layout, nosave);
export function setKeymapCustom(
keymapCustom: KeymapCustom,
nosave?: boolean
): boolean {
if (
!isConfigValueValid(
"keymap custom",
keymapCustom,
ConfigSchemas.KeymapCustomSchema
)
)
return false;

//better validation for the custom keymap
config.keymapCustom = keymapCustom;
saveToLocalStorage("keymapCustom", nosave);
ConfigEvent.dispatch("keymapCustom", config.keymapCustom, nosave);

// return true;
// }
return true;
}

export function setFontSize(
fontSize: ConfigSchemas.FontSize,
Expand Down Expand Up @@ -2046,6 +2057,7 @@ export async function apply(
setKeymapLayout(configObj.keymapLayout, true);
setKeymapShowTopRow(configObj.keymapShowTopRow, true);
setKeymapSize(configObj.keymapSize, true);
setKeymapCustom(configObj.keymapCustom, true);
setFontFamily(configObj.fontFamily, true);
setSmoothCaret(configObj.smoothCaret, true);
setCodeUnindentOnBackspace(configObj.codeUnindentOnBackspace, true);
Expand Down
48 changes: 48 additions & 0 deletions frontend/src/ts/constants/data-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
export const dataKeys: { [key: string]: string } = {
a: "aA",
b: "bB",
c: "cC",
d: "dD",
e: "eE",
f: "fF",
g: "gG",
h: "hH",
i: "iI",
j: "jJ",
k: "kK",
l: "lL",
m: "mM",
n: "nN",
o: "oO",
p: "pP",
q: "qQ",
r: "rR",
s: "sS",
t: "tT",
u: "uU",
v: "vV",
w: "wW",
x: "xX",
y: "yY",
z: "zZ",
1: "1!",
2: "2@",
3: "3#",
4: "4$",
5: "5%",
6: "6^",
7: "7&",
8: "8*",
9: "9(",
0: "0)",
"-": "-_",
"=": "=+",
"[": "[{",
"]": "]}",
"\\": "\\|",
";": ";:",
"&apos;": "&apos;&quot;",
",": ",<",
".": ".>",
"/": "/?",
};
1 change: 1 addition & 0 deletions frontend/src/ts/constants/default-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const obj = {
keymapLayout: "overrideSync",
keymapShowTopRow: "layout",
keymapSize: 1,
keymapCustom: [[]],
fontFamily: "Roboto_Mono",
smoothLineScroll: false,
alwaysShowDecimalPlaces: false,
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/ts/elements/keymap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import * as ShiftTracker from "../test/shift-tracker";
import * as AltTracker from "../test/alt-tracker";
import * as KeyConverter from "../utils/key-converter";
import { getActiveFunboxNames } from "../test/funbox/list";
import { getCustomKeymapSyle } from "../utils/custom-keymap";
import { KeymapCustom, Layout } from "@monkeytype/contracts/schemas/configs";

const stenoKeys: JSONData.Layout = {
keymapShowTopRow: true,
Expand Down Expand Up @@ -416,6 +418,13 @@ export async function refresh(
});
}

if (Config.keymapStyle === "custom") {
const {
keymapCustom,
layout,
}: { keymapCustom: KeymapCustom; layout: Layout } = Config;
keymapElement = getCustomKeymapSyle(keymapCustom, layout);
}
$("#keymap").html(keymapElement);

$("#keymap").removeClass("staggered");
Expand All @@ -425,6 +434,7 @@ export async function refresh(
$("#keymap").removeClass("alice");
$("#keymap").removeClass("steno");
$("#keymap").removeClass("steno_matrix");
$("#keymap").removeClass("custom");
$("#keymap").addClass(Config.keymapStyle);
} catch (e) {
if (e instanceof Error) {
Expand Down
73 changes: 72 additions & 1 deletion frontend/src/ts/pages/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as CustomBackgroundFilter from "../elements/custom-background-filter";
import {
ConfigValue,
CustomBackgroundSchema,
KeymapCustom,
} from "@monkeytype/contracts/schemas/configs";
import {
getAllFunboxes,
Expand All @@ -33,6 +34,7 @@ import { getActiveFunboxNames } from "../test/funbox/list";
import { SnapshotPreset } from "../constants/default-snapshot";
import { LayoutsList } from "../constants/layouts";
import { DataArrayPartial } from "slim-select/store";
import { keymapToString, stringToKeymap } from "../utils/custom-keymap";

type SettingsGroups<T extends ConfigValue> = Record<string, SettingsGroup<T>>;

Expand Down Expand Up @@ -91,6 +93,9 @@ async function initGroups(): Promise<void> {
$(".pageSettings .section[data-config-name='keymapSize']").addClass(
"hidden"
);
$(".pageSettings .section[data-config-name='keymapCustom']").addClass(
"hidden"
);
} else {
$(".pageSettings .section[data-config-name='keymapStyle']").removeClass(
"hidden"
Expand All @@ -107,13 +112,29 @@ async function initGroups(): Promise<void> {
$(".pageSettings .section[data-config-name='keymapSize']").removeClass(
"hidden"
);
if (Config.keymapStyle === "custom") {
$(
".pageSettings .section[data-config-name='keymapCustom']"
).removeClass("hidden");
}
}
}
) as SettingsGroup<ConfigValue>;
groups["keymapMatrix"] = new SettingsGroup(
"keymapStyle",
UpdateConfig.setKeymapStyle,
"button"
"button",
() => {
if (Config.keymapStyle !== "custom") {
$(".pageSettings .section[data-config-name='keymapCustom']").addClass(
"hidden"
);
} else {
$(
".pageSettings .section[data-config-name='keymapCustom']"
).removeClass("hidden");
}
}
) as SettingsGroup<ConfigValue>;
groups["keymapLayout"] = new SettingsGroup(
"keymapLayout",
Expand Down Expand Up @@ -339,6 +360,11 @@ async function initGroups(): Promise<void> {
UpdateConfig.setFontSize,
"button"
) as SettingsGroup<ConfigValue>;
groups["keymapCustom"] = new SettingsGroup(
"keymapCustom",
UpdateConfig.setKeymapCustom,
"button"
) as SettingsGroup<ConfigValue>;
groups["maxLineWidth"] = new SettingsGroup(
"maxLineWidth",
UpdateConfig.setMaxLineWidth,
Expand Down Expand Up @@ -503,6 +529,16 @@ async function fillSettingsPage(): Promise<void> {
".pageSettings .section[data-config-name='keymapLayout'] select"
) as Element;

if (Config.keymapStyle !== "custom") {
$(".pageSettings .section[data-config-name='keymapCustom']").addClass(
"hidden"
);
} else {
$(".pageSettings .section[data-config-name='keymapCustom']").removeClass(
"hidden"
);
}

let layoutHtml = '<option value="default">off</option>';
let keymapLayoutHtml = '<option value="overrideSync">emulator sync</option>';

Expand Down Expand Up @@ -678,6 +714,9 @@ async function fillSettingsPage(): Promise<void> {
$(".pageSettings .section[data-config-name='fontSize'] input").val(
Config.fontSize
);
$(".pageSettings .section[data-config-name='keymapCustom'] textarea").val(
keymapToString(Config.keymapCustom)
);

$(".pageSettings .section[data-config-name='maxLineWidth'] input").val(
Config.maxLineWidth
Expand Down Expand Up @@ -1202,6 +1241,38 @@ $(
}
});

$(
".pageSettings .section[data-config-name='keymapCustom'] .textareaAndButton button.save"
).on("click", () => {
const stringValue = $(
".pageSettings .section[data-config-name='keymapCustom'] .textareaAndButton textarea"
).val() as string;
const keymap: KeymapCustom = stringToKeymap(stringValue);
const didConfigSave = UpdateConfig.setKeymapCustom(keymap);
if (didConfigSave) {
Notifications.add("Saved", 1, {
duration: 1,
});
}
});

$(
".pageSettings .section[data-config-name='keymapCustom'] .textareaAndButton textarea"
).on("keypress", (e) => {
if (e.key === "Enter") {
const stringValue = $(
".pageSettings .section[data-config-name='keymapCustom'] .textareaAndButton textarea"
).val() as string;
const keymap: KeymapCustom = stringToKeymap(stringValue);
const didConfigSave = UpdateConfig.setKeymapCustom(keymap);
if (didConfigSave) {
Notifications.add("Saved", 1, {
duration: 1,
});
}
}
});

$(
".pageSettings .section[data-config-name='tapeMargin'] .inputAndButton button.save"
).on("click", () => {
Expand Down
Loading