mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-04 00:47:01 +01:00
scratch: a drawer of notes taken in passing, kept as documents later
Q lowers the scratchpad from under the bar over whatever is on screen, as the desktop lowers its own. Its notes have no name or place; each is written in the vim editor and saves itself. K (:keep [title]) makes the note under the cursor a document in the folder being browsed, titled by its first line, and takes it off the pad. :scratch <text> jots one from the command line. The notes ride along in backups and whole-workspace exports. The card description's editor is now TextEditor, shared by both.
This commit is contained in:
1 parent
3c4c383f72
commit
ac3ad166e5
18 files changed
+782
-24
No files matched your search
+89
-2
@@ -18,6 +18,7 @@
|
||||
import Trash, { purgeTrashed, restoreTrashed } from './lib/Trash.svelte'
|
||||
import Backlinks, { openBacklink } from './lib/Backlinks.svelte'
|
||||
import CardSheet from './lib/CardSheet.svelte'
|
||||
import Scratch from './lib/Scratch.svelte'
|
||||
import History, { moveHistory, restoreShown } from './lib/History.svelte'
|
||||
import Actions from './lib/Actions.svelte'
|
||||
import Prompt from './lib/Prompt.svelte'
|
||||
@@ -793,6 +794,74 @@
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The scratchpad's keys, while it is down and its note is not being
|
||||
* written: the list keys over its notes. It sits over whatever was on
|
||||
* screen, so nothing else hears a key until it is raised again.
|
||||
*/
|
||||
function scratchKey(event: KeyboardEvent): boolean {
|
||||
const key = event.key
|
||||
const previous = pending
|
||||
pending = ''
|
||||
const last = Math.max(workspace.scratchNotes.length - 1, 0)
|
||||
if (previous === 'g' && key === 'g') return (workspace.scratchCursor = 0), true
|
||||
if (previous === 'd' && key === 'd') {
|
||||
const note = workspace.scratchNote
|
||||
if (note) {
|
||||
void (async () => {
|
||||
if (await workspace.ask('drop this scratch note?')) await workspace.guard(() => workspace.dropScratchNote())
|
||||
})()
|
||||
}
|
||||
return true
|
||||
}
|
||||
switch (key) {
|
||||
case 'g':
|
||||
case 'd':
|
||||
pending = key
|
||||
return true
|
||||
case 'j':
|
||||
case 'ArrowDown':
|
||||
workspace.scratchCursor = Math.min(workspace.scratchCursor + 1, last)
|
||||
return true
|
||||
case 'k':
|
||||
case 'ArrowUp':
|
||||
workspace.scratchCursor = Math.max(workspace.scratchCursor - 1, 0)
|
||||
return true
|
||||
case 'G':
|
||||
workspace.scratchCursor = last
|
||||
return true
|
||||
case 'o':
|
||||
case 'O':
|
||||
case 'c':
|
||||
workspace.newScratchNote()
|
||||
return true
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'a':
|
||||
case 'Enter':
|
||||
workspace.editScratchNote()
|
||||
return true
|
||||
case 'K':
|
||||
void workspace.guard(() => workspace.keepScratchNote())
|
||||
return true
|
||||
case ':':
|
||||
cmdGlobal = false
|
||||
cmdline = ':'
|
||||
return true
|
||||
case '?':
|
||||
void runCommand('help')
|
||||
return true
|
||||
case 'Q':
|
||||
case 'q':
|
||||
case 'Escape':
|
||||
void workspace.closeScratch()
|
||||
return true
|
||||
default:
|
||||
// Nothing under the drawer hears a key while it is down.
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function isTypingTarget(target: EventTarget | null) {
|
||||
const node = target as HTMLElement | null
|
||||
return (
|
||||
@@ -807,7 +876,8 @@
|
||||
function onkeydown(event: KeyboardEvent) {
|
||||
if (event.key === 's' && (event.metaKey || event.ctrlKey)) {
|
||||
event.preventDefault()
|
||||
if (workspace.describing) void workspace.guard(() => workspace.saveDescription())
|
||||
if (workspace.scratchEditing) void workspace.guard(() => workspace.saveScratchNote())
|
||||
else if (workspace.describing) void workspace.guard(() => workspace.saveDescription())
|
||||
else if (workspace.open) void workspace.guard(() => workspace.save())
|
||||
return
|
||||
}
|
||||
@@ -828,6 +898,19 @@
|
||||
|
||||
// The command line over an overlay — `D` in the agenda — keeps its keys.
|
||||
const listening = cmdline === null && !isTypingTarget(event.target)
|
||||
// `Q`, a quick note: the scratchpad lowered from anywhere a key is not
|
||||
// being typed — a letter, since a backtick is a dead key on many layouts.
|
||||
if (event.key === 'Q' && listening && !workspace.scratchOpen && workspace.overlay === 'none' && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
||||
event.preventDefault()
|
||||
void workspace.guard(() => workspace.toggleScratch())
|
||||
return
|
||||
}
|
||||
if (workspace.scratchOpen && !workspace.scratchEditing && workspace.overlay === 'none' && listening && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
||||
if (scratchKey(event)) {
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (workspace.overlay === 'card' && !workspace.describing && listening && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
||||
if (cardKey(event)) {
|
||||
event.preventDefault()
|
||||
@@ -894,7 +977,7 @@
|
||||
|
||||
if (event.key === 'Escape') {
|
||||
// The description's editor has had its Esc; the sheet stays up under it.
|
||||
if (workspace.describing) return
|
||||
if (workspace.describing || workspace.scratchEditing) return
|
||||
if (workspace.overlay !== 'none') {
|
||||
workspace.overlay = 'none'
|
||||
return
|
||||
@@ -1370,6 +1453,10 @@
|
||||
<CommandLine initial={cmdline} global={cmdGlobal} close={() => ((cmdline = null), (cmdGlobal = false))} />
|
||||
{/if}
|
||||
|
||||
{#if workspace.scratchOpen}
|
||||
<Scratch />
|
||||
{/if}
|
||||
|
||||
<Prompt />
|
||||
<SecretPrompt />
|
||||
|
||||
|
||||
Reference in new issue
Block a user