mirror of
https://github.com/heyman/heynote.git
synced 2025-06-28 13:31:38 +02:00
* Change so that keybindings are stored as lists, so that a key can be bound to ultiple commands (and commands can return false, to let another command execute).
* Implement ability to reorder user key bindings in settings.
This commit is contained in:
parent
edeb3aee4b
commit
7a2740ef19
1
assets/icons/drag-vertical-dark.svg
Normal file
1
assets/icons/drag-vertical-dark.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg"><circle cx="4.5" cy="2.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="4.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="6.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="8.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="10.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="12.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="2.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="4.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="6.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="8.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="10.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="12.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="2.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="4.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="6.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="8.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="10.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="12.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="2.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="4.5" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="6.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="8.499" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="10.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="12.498" fill="#e6e6e6" r=".6" class="fill-000000"></circle></svg>
|
After Width: | Height: | Size: 1.9 KiB |
1
assets/icons/drag-vertical-light.svg
Normal file
1
assets/icons/drag-vertical-light.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg"><circle cx="4.5" cy="2.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="4.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="6.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="8.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="10.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="4.5" cy="12.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="2.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="4.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="6.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="8.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="10.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="6.5" cy="12.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="2.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="4.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="6.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="8.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="10.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="8.499" cy="12.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="2.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="4.5" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="6.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="8.499" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="10.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle><circle cx="10.499" cy="12.498" fill="#b0b0b0" r=".6" class="fill-000000"></circle></svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -25,12 +25,15 @@ const schema = {
|
|||||||
"keymap": { "enum": ["default", "emacs"], default:"default" },
|
"keymap": { "enum": ["default", "emacs"], default:"default" },
|
||||||
"emacsMetaKey": { "enum": [null, "alt", "meta"], default: null },
|
"emacsMetaKey": { "enum": [null, "alt", "meta"], default: null },
|
||||||
"keyBindings": {
|
"keyBindings": {
|
||||||
"type": "object",
|
"type": "array",
|
||||||
"propertyNames": {
|
"items": {
|
||||||
"type": "string"
|
"type": "object",
|
||||||
},
|
"required": ["key", "command"],
|
||||||
"additionalProperties": {
|
"properties": {
|
||||||
"type": "string"
|
"key": { "type": "string" },
|
||||||
|
"command": { "type": "string" }
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -71,7 +74,7 @@ const defaults = {
|
|||||||
settings: {
|
settings: {
|
||||||
keymap: "default",
|
keymap: "default",
|
||||||
emacsMetaKey: isMac ? "meta" : "alt",
|
emacsMetaKey: isMac ? "meta" : "alt",
|
||||||
keyBindings: {},
|
keyBindings: [],
|
||||||
showLineNumberGutter: true,
|
showLineNumberGutter: true,
|
||||||
showFoldGutter: true,
|
showFoldGutter: true,
|
||||||
autoUpdate: true,
|
autoUpdate: true,
|
||||||
|
21
package-lock.json
generated
21
package-lock.json
generated
@ -13,7 +13,8 @@
|
|||||||
"electron-log": "^5.0.1",
|
"electron-log": "^5.0.1",
|
||||||
"fuzzysort": "^3.0.2",
|
"fuzzysort": "^3.0.2",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"semver": "^7.6.3"
|
"semver": "^7.6.3",
|
||||||
|
"vuedraggable": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/autocomplete": "^6.11.1",
|
"@codemirror/autocomplete": "^6.11.1",
|
||||||
@ -5565,6 +5566,12 @@
|
|||||||
"npm": ">= 3.0.0"
|
"npm": ">= 3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sortablejs": {
|
||||||
|
"version": "1.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
|
||||||
|
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
@ -6472,6 +6479,18 @@
|
|||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vuedraggable": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"sortablejs": "1.14.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/w3c-keyname": {
|
"node_modules/w3c-keyname": {
|
||||||
"version": "2.2.8",
|
"version": "2.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
"electron-log": "^5.0.1",
|
"electron-log": "^5.0.1",
|
||||||
"fuzzysort": "^3.0.2",
|
"fuzzysort": "^3.0.2",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"semver": "^7.6.3"
|
"semver": "^7.6.3",
|
||||||
|
"vuedraggable": "^4.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"keys",
|
"keys",
|
||||||
"command",
|
"command",
|
||||||
"isDefault",
|
"isDefault",
|
||||||
"isOverridden",
|
"source",
|
||||||
],
|
],
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
@ -19,9 +19,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<tr :class="{overridden:isOverridden}">
|
<tr>
|
||||||
<td class="source">
|
<td class="source">
|
||||||
{{ isDefault ? "Heynote" : "User" }}
|
{{ source }}
|
||||||
</td>
|
</td>
|
||||||
<td class="key">
|
<td class="key">
|
||||||
<template v-if="keys">
|
<template v-if="keys">
|
||||||
@ -37,6 +37,9 @@
|
|||||||
<button class="delete">Delete</button>
|
<button class="delete">Delete</button>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<td v-if="!isDefault" class="drag-handle"></td>
|
||||||
|
<td v-else></td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -57,6 +60,19 @@
|
|||||||
.unbound
|
.unbound
|
||||||
font-style: italic
|
font-style: italic
|
||||||
color: #999
|
color: #999
|
||||||
|
&.drag-handle
|
||||||
|
width: 24px
|
||||||
|
padding: 0
|
||||||
|
cursor: ns-resize
|
||||||
|
background-color: rgba(0,0,0, 0.02)
|
||||||
|
background-size: 20px
|
||||||
|
background-repeat: no-repeat
|
||||||
|
background-position: center center
|
||||||
|
background-image: url(@/assets/icons/drag-vertical-light.svg)
|
||||||
|
|
||||||
|
+dark-mode
|
||||||
|
background-color: rgba(0,0,0, 0.08)
|
||||||
|
background-image: url(@/assets/icons/drag-vertical-dark.svg)
|
||||||
button
|
button
|
||||||
padding: 0 10px
|
padding: 0 10px
|
||||||
height: 22px
|
height: 22px
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapState} from 'pinia'
|
import { mapState} from 'pinia'
|
||||||
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
import { DEFAULT_KEYMAP, EMACS_KEYMAP } from "@/src/editor/keymap"
|
import { DEFAULT_KEYMAP, EMACS_KEYMAP } from "@/src/editor/keymap"
|
||||||
import { useSettingsStore } from "@/src/stores/settings-store"
|
import { useSettingsStore } from "@/src/stores/settings-store"
|
||||||
@ -7,72 +8,77 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
"userKeys"
|
"userKeys",
|
||||||
|
"modelValue",
|
||||||
],
|
],
|
||||||
components: {
|
components: {
|
||||||
KeyBindRow,
|
KeyBindRow,
|
||||||
|
draggable,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
keymap: this.modelValue,
|
||||||
|
//fixedKeymap: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
/*const defaultKeymap = this.settings.keymap === "emacs" ? EMACS_KEYMAP : DEFAULT_KEYMAP
|
||||||
|
this.fixedKeymap = defaultKeymap.map((km) => {
|
||||||
|
return {
|
||||||
|
key: km.key,
|
||||||
|
command: km.command,
|
||||||
|
isDefault: true,
|
||||||
|
}
|
||||||
|
})*/
|
||||||
|
/*
|
||||||
|
const keymap = this.settings.keymap === "emacs" ? EMACS_KEYMAP : DEFAULT_KEYMAP
|
||||||
|
this.testKeymap = [
|
||||||
|
...this.userKeys,
|
||||||
|
{"key": "Mod-Enter", command: "yay"},
|
||||||
|
{"key": "Mod-Enter n", command: "nay"},
|
||||||
|
{"key": "Ctrl-o", command: null},
|
||||||
|
]
|
||||||
|
|
||||||
|
this.fixedKeymap = keymap.map((km) => {
|
||||||
|
return {
|
||||||
|
key: km.key,
|
||||||
|
command: km.command,
|
||||||
|
isDefault: true,
|
||||||
|
isOverridden: km.key in this.userKeys,
|
||||||
|
}
|
||||||
|
})*/
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSettingsStore, [
|
...mapState(useSettingsStore, [
|
||||||
"settings",
|
"settings",
|
||||||
]),
|
]),
|
||||||
|
|
||||||
keymapOld() {
|
fixedKeymap() {
|
||||||
const userKeys = [
|
const defaultKeymap = (this.settings.keymap === "emacs" ? EMACS_KEYMAP : []).map((km) => ({
|
||||||
{key: "Mod-Enter", command: null},
|
key: km.key,
|
||||||
]
|
command: km.command,
|
||||||
|
isDefault: true,
|
||||||
// merge default keymap with user keymap
|
source: "Emacs",
|
||||||
const defaultKeys = Object.fromEntries(DEFAULT_KEYMAP.map(km => [km.key, km.command]))
|
}))
|
||||||
let mergedKeys = {...defaultKeys, ...Object.fromEntries(userKeys.map(km => [km.key, km.command]))}
|
return defaultKeymap.concat(
|
||||||
|
DEFAULT_KEYMAP.map((km) => ({
|
||||||
|
key: km.key,
|
||||||
|
command: km.command,
|
||||||
//console.log("defaultKeys:", defaultKeys)
|
isDefault: true,
|
||||||
|
source: "Default",
|
||||||
return Object.entries(mergedKeys).map(([key, command]) => {
|
}))
|
||||||
return {
|
)
|
||||||
key: key,
|
|
||||||
command: command,
|
|
||||||
isDefault: defaultKeys[key] !== undefined && defaultKeys[key] === command,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
keymap() {
|
|
||||||
//const userKeys = {
|
|
||||||
// "Mod-Enter": null,
|
|
||||||
// "Mod-Shift-A": "test",
|
|
||||||
//}
|
|
||||||
|
|
||||||
const keymap = this.settings.keymap === "emacs" ? EMACS_KEYMAP : DEFAULT_KEYMAP
|
|
||||||
|
|
||||||
return [
|
|
||||||
...Object.entries(this.userKeys).map(([key, command]) => {
|
|
||||||
return {key, command}
|
|
||||||
}),
|
|
||||||
|
|
||||||
...keymap.map((km) => {
|
|
||||||
return {
|
|
||||||
key: km.key,
|
|
||||||
command: km.command,
|
|
||||||
isDefault: true,
|
|
||||||
isOverridden: km.key in this.userKeys,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
onDragEnd(event) {
|
||||||
|
console.log("onDragEnd", this.testKeymap)
|
||||||
|
this.$emit("update:modelValue", this.keymap)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -82,19 +88,41 @@
|
|||||||
<h2>Keyboard Bindings</h2>
|
<h2>Keyboard Bindings</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th></th>
|
||||||
<th>Source</th>
|
<th>Source</th>
|
||||||
<th>Key</th>
|
<th>Key</th>
|
||||||
<th>Command</th>
|
<th>Command</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
<KeyBindRow
|
<draggable
|
||||||
v-for="key in keymap"
|
v-model="keymap"
|
||||||
:key="key.key"
|
tag="tbody"
|
||||||
:keys="key.key"
|
group="keymap"
|
||||||
:command="key.command"
|
ghost-class="ghost"
|
||||||
:isOverridden="key.isOverridden"
|
handle=".drag-handle"
|
||||||
:isDefault="key.isDefault"
|
@start="drag=true"
|
||||||
/>
|
@end="onDragEnd"
|
||||||
|
item-key="key"
|
||||||
|
>
|
||||||
|
<template #item="{element}">
|
||||||
|
<KeyBindRow
|
||||||
|
:keys="element.key"
|
||||||
|
:command="element.command"
|
||||||
|
:isDefault="element.isDefault"
|
||||||
|
source="User"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</draggable>
|
||||||
|
<tbody>
|
||||||
|
<KeyBindRow
|
||||||
|
v-for="key in fixedKeymap"
|
||||||
|
:key="key.key"
|
||||||
|
:keys="key.key"
|
||||||
|
:command="key.command"
|
||||||
|
:isDefault="key.isDefault"
|
||||||
|
:source="key.source"
|
||||||
|
/>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -111,16 +139,31 @@
|
|||||||
border: 2px solid #f1f1f1
|
border: 2px solid #f1f1f1
|
||||||
+dark-mode
|
+dark-mode
|
||||||
background: #3c3c3c
|
background: #3c3c3c
|
||||||
|
background: #333
|
||||||
border: 2px solid #3c3c3c
|
border: 2px solid #3c3c3c
|
||||||
::v-deep(tr)
|
::v-deep(tr)
|
||||||
&:nth-child(2n)
|
background: #fff
|
||||||
background: #fff
|
border-bottom: 2px solid #f1f1f1
|
||||||
|
+dark-mode
|
||||||
|
background: #333
|
||||||
|
border-bottom: 2px solid #3c3c3c
|
||||||
|
&.ghost
|
||||||
|
background: #48b57e
|
||||||
|
color: #fff
|
||||||
+dark-mode
|
+dark-mode
|
||||||
background: #333
|
background: #1b6540
|
||||||
th
|
th
|
||||||
text-align: left
|
text-align: left
|
||||||
font-weight: 600
|
font-weight: 600
|
||||||
th, td
|
th, td
|
||||||
padding: 8px
|
padding: 8px
|
||||||
|
&.actions
|
||||||
|
padding: 6px
|
||||||
|
button
|
||||||
|
height: 20px
|
||||||
|
font-size: 11px
|
||||||
|
|
||||||
|
tbody
|
||||||
|
margin-bottom: 20px
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -86,6 +86,12 @@
|
|||||||
window.removeEventListener("keydown", this.onKeyDown);
|
window.removeEventListener("keydown", this.onKeyDown);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
keyBindings(newKeyBindings) {
|
||||||
|
this.updateSettings()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onKeyDown(event) {
|
onKeyDown(event) {
|
||||||
if (event.key === "Escape") {
|
if (event.key === "Escape") {
|
||||||
@ -98,7 +104,7 @@
|
|||||||
showLineNumberGutter: this.showLineNumberGutter,
|
showLineNumberGutter: this.showLineNumberGutter,
|
||||||
showFoldGutter: this.showFoldGutter,
|
showFoldGutter: this.showFoldGutter,
|
||||||
keymap: this.keymap,
|
keymap: this.keymap,
|
||||||
keyBindings: toRaw(this.keyBindings),
|
keyBindings: this.keyBindings.map((kb) => toRaw(kb)),
|
||||||
emacsMetaKey: window.heynote.platform.isMac ? this.metaKey : "alt",
|
emacsMetaKey: window.heynote.platform.isMac ? this.metaKey : "alt",
|
||||||
allowBetaVersions: this.allowBetaVersions,
|
allowBetaVersions: this.allowBetaVersions,
|
||||||
enableGlobalHotkey: this.enableGlobalHotkey,
|
enableGlobalHotkey: this.enableGlobalHotkey,
|
||||||
@ -369,6 +375,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<KeyboardBindings
|
<KeyboardBindings
|
||||||
:userKeys="keyBindings ? keyBindings : {}"
|
:userKeys="keyBindings ? keyBindings : {}"
|
||||||
|
v-model="keyBindings"
|
||||||
/>
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import { noteBlockExtension, blockLineNumbers, blockState, getActiveNoteBlock, t
|
|||||||
import { heynoteEvent, SET_CONTENT, DELETE_BLOCK, APPEND_BLOCK, SET_FONT } from "./annotation.js";
|
import { heynoteEvent, SET_CONTENT, DELETE_BLOCK, APPEND_BLOCK, SET_FONT } from "./annotation.js";
|
||||||
import { changeCurrentBlockLanguage, triggerCurrenciesLoaded, getBlockDelimiter, deleteBlock, selectAll } from "./block/commands.js"
|
import { changeCurrentBlockLanguage, triggerCurrenciesLoaded, getBlockDelimiter, deleteBlock, selectAll } from "./block/commands.js"
|
||||||
import { formatBlockContent } from "./block/format-code.js"
|
import { formatBlockContent } from "./block/format-code.js"
|
||||||
import { heynoteKeymap, DEFAULT_KEYMAP, EMACS_KEYMAP } from "./keymap.js"
|
import { getKeymapExtensions } from "./keymap.js"
|
||||||
import { heynoteCopyCut } from "./copy-paste"
|
import { heynoteCopyCut } from "./copy-paste"
|
||||||
import { languageDetection } from "./language-detection/autodetect.js"
|
import { languageDetection } from "./language-detection/autodetect.js"
|
||||||
import { autoSaveContent } from "./save.js"
|
import { autoSaveContent } from "./save.js"
|
||||||
@ -29,15 +29,6 @@ import { useHeynoteStore } from "../stores/heynote-store.js";
|
|||||||
import { useErrorStore } from "../stores/error-store.js";
|
import { useErrorStore } from "../stores/error-store.js";
|
||||||
|
|
||||||
|
|
||||||
function getKeymapExtensions(editor, keymap, keyBindings) {
|
|
||||||
return heynoteKeymap(
|
|
||||||
editor,
|
|
||||||
keymap === "emacs" ? EMACS_KEYMAP : DEFAULT_KEYMAP,
|
|
||||||
keyBindings,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class HeynoteEditor {
|
export class HeynoteEditor {
|
||||||
constructor({
|
constructor({
|
||||||
element,
|
element,
|
||||||
|
@ -3,30 +3,6 @@ import { Prec } from "@codemirror/state"
|
|||||||
|
|
||||||
import { HEYNOTE_COMMANDS } from "./commands.js"
|
import { HEYNOTE_COMMANDS } from "./commands.js"
|
||||||
|
|
||||||
|
|
||||||
function keymapFromSpec(specs, editor) {
|
|
||||||
return keymap.of(specs.map((spec) => {
|
|
||||||
let key = spec.key
|
|
||||||
if (key.indexOf("EmacsMeta") != -1) {
|
|
||||||
key = key.replace("EmacsMeta", editor.emacsMetaKey === "alt" ? "Alt" : "Meta")
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
key: key,
|
|
||||||
//preventDefault: true,
|
|
||||||
preventDefault: false,
|
|
||||||
run: (view) => {
|
|
||||||
//console.log("run()", spec.key, spec.command)
|
|
||||||
const command = HEYNOTE_COMMANDS[spec.command]
|
|
||||||
if (!command) {
|
|
||||||
console.error(`Command not found: ${spec.command} (${spec.key})`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return command(editor)(view)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const cmd = (key, command) => ({key, command})
|
const cmd = (key, command) => ({key, command})
|
||||||
const cmdShift = (key, command, shiftCommand) => {
|
const cmdShift = (key, command, shiftCommand) => {
|
||||||
return [
|
return [
|
||||||
@ -99,8 +75,6 @@ export const DEFAULT_KEYMAP = [
|
|||||||
cmd("Shift-Tab", "indentLess"),
|
cmd("Shift-Tab", "indentLess"),
|
||||||
//cmd("Alt-ArrowLeft", "cursorSubwordBackward"),
|
//cmd("Alt-ArrowLeft", "cursorSubwordBackward"),
|
||||||
//cmd("Alt-ArrowRight", "cursorSubwordForward"),
|
//cmd("Alt-ArrowRight", "cursorSubwordForward"),
|
||||||
cmd("Ctrl-Space", "toggleEmacsMarkMode"),
|
|
||||||
cmd("Ctrl-g", "emacsCancel"),
|
|
||||||
|
|
||||||
cmd("Mod-l", "openLanguageSelector"),
|
cmd("Mod-l", "openLanguageSelector"),
|
||||||
cmd("Mod-p", "openBufferSelector"),
|
cmd("Mod-p", "openBufferSelector"),
|
||||||
@ -146,27 +120,46 @@ export const EMACS_KEYMAP = [
|
|||||||
...cmdShift("Ctrl-f", "cursorCharRight", "selectCharRight"),
|
...cmdShift("Ctrl-f", "cursorCharRight", "selectCharRight"),
|
||||||
...cmdShift("Ctrl-a", "cursorLineStart", "selectLineStart"),
|
...cmdShift("Ctrl-a", "cursorLineStart", "selectLineStart"),
|
||||||
...cmdShift("Ctrl-e", "cursorLineEnd", "selectLineEnd"),
|
...cmdShift("Ctrl-e", "cursorLineEnd", "selectLineEnd"),
|
||||||
...DEFAULT_KEYMAP,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
function keymapFromSpec(specs, editor) {
|
||||||
|
return keymap.of(specs.map((spec) => {
|
||||||
|
let key = spec.key
|
||||||
|
if (key.indexOf("EmacsMeta") != -1) {
|
||||||
|
key = key.replace("EmacsMeta", editor.emacsMetaKey === "alt" ? "Alt" : "Meta")
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
key: key,
|
||||||
|
//preventDefault: true,
|
||||||
|
preventDefault: false,
|
||||||
|
run: (view) => {
|
||||||
|
//console.log("run()", spec.key, spec.command)
|
||||||
|
const command = HEYNOTE_COMMANDS[spec.command]
|
||||||
|
if (!command) {
|
||||||
|
console.error(`Command not found: ${spec.command} (${spec.key})`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return command(editor)(view)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function heynoteKeymap(editor, keymap, userKeymap) {
|
export function heynoteKeymap(editor, keymap, userKeymap) {
|
||||||
//return [
|
|
||||||
// keymapFromSpec([
|
|
||||||
// ...Object.entries(userKeymap).map(([key, command]) => cmd(key, command)),
|
|
||||||
// ...keymap,
|
|
||||||
// ], editor),
|
|
||||||
//]
|
|
||||||
|
|
||||||
// merge the default keymap with the custom keymap
|
|
||||||
const defaultKeys = Object.fromEntries(keymap.map(km => [km.key, km.command]))
|
|
||||||
//let mergedKeys = Object.entries({...defaultKeys, ...Object.fromEntries(userKeymap.map(km => [km.key, km.command]))}).map(([key, command]) => cmd(key, command))
|
|
||||||
let mergedKeys = Object.entries({...defaultKeys, ...userKeymap}).map(([key, command]) => cmd(key, command))
|
|
||||||
//console.log("userKeys:", userKeymap)
|
|
||||||
//console.log("mergedKeys:", mergedKeys)
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Prec.high(keymapFromSpec(mergedKeys, editor)),
|
keymapFromSpec([
|
||||||
|
...userKeymap,
|
||||||
|
...keymap,
|
||||||
|
], editor),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getKeymapExtensions(editor, keymap, keyBindings) {
|
||||||
|
return heynoteKeymap(
|
||||||
|
editor,
|
||||||
|
keymap === "emacs" ? EMACS_KEYMAP.concat(DEFAULT_KEYMAP) : DEFAULT_KEYMAP,
|
||||||
|
keyBindings,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user