From 3ac69071c2b30ee8e7c2df0c65d5b1f7f8514867 Mon Sep 17 00:00:00 2001 From: Vladyslav Sitalo Date: Tue, 25 Jun 2024 18:09:48 -0400 Subject: [PATCH 1/3] SRS and completion from vim normal mode --- .../vim-mode/commands/edit-commands.ts | 37 +++++++++++++++++++ src/ts/core/features/vim-mode/index.ts | 2 + src/ts/core/roam/block.ts | 2 +- src/ts/core/roam/roam-db.ts | 5 +++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/ts/core/features/vim-mode/commands/edit-commands.ts diff --git a/src/ts/core/features/vim-mode/commands/edit-commands.ts b/src/ts/core/features/vim-mode/commands/edit-commands.ts new file mode 100644 index 00000000..0d0aa07b --- /dev/null +++ b/src/ts/core/features/vim-mode/commands/edit-commands.ts @@ -0,0 +1,37 @@ +import {nmap} from 'src/core/features/vim-mode/vim' +import {RoamBlock} from 'src/core/features/vim-mode/roam/roam-block' +import {SRSSignal, SRSSignals} from 'src/core/srs/scheduler' +import {AnkiScheduler} from 'src/core/srs/AnkiScheduler' +import {SM2Node} from 'src/core/srs/SM2Node' +import {RoamDb} from 'src/core/roam/roam-db' +import {getBlockUid} from 'src/core/roam/block' + +const getBlockText = (uid: string): string => { + const block = RoamDb.getBlockByUid(uid) + return block[':block/string'] +} + +function selectedUid() { + const htmlId = RoamBlock.selected().id + return getBlockUid(htmlId) +} + +const rescheduleSelectedNote = (signal: SRSSignal) => { + console.log('rescheduleSelectedNote', signal) + const uid = selectedUid() + const originalText = getBlockText(uid) + RoamDb.updateBlockText(uid, new AnkiScheduler().schedule(new SM2Node(originalText), signal).text) +} + +const markDone = () => { + const uid = selectedUid() + const originalText = getBlockText(uid) + RoamDb.updateBlockText(uid, '{{[[DONE]]}} ' + originalText) +} + +export const EditCommands = [ + nmap('cmd+enter', 'Mark done', markDone), + ...SRSSignals.map(it => + nmap(`ctrl+shift+${it}`, `Reschedule Current Note (${SRSSignal[it]})`, () => rescheduleSelectedNote(it)) + ), +] diff --git a/src/ts/core/features/vim-mode/index.ts b/src/ts/core/features/vim-mode/index.ts index f6c1df78..26d1bdad 100644 --- a/src/ts/core/features/vim-mode/index.ts +++ b/src/ts/core/features/vim-mode/index.ts @@ -11,6 +11,7 @@ import {BlockManipulationCommands} from 'src/core/features/vim-mode/commands/blo import {RoamBlock} from 'src/core/features/vim-mode/roam/roam-block' import {HintCommands} from 'src/core/features/vim-mode/commands/hint-commands' import {Browser} from 'src/core/common/browser' +import {EditCommands} from 'src/core/features/vim-mode/commands/edit-commands' export const config: Feature = { id: 'block_navigation_mode', @@ -28,6 +29,7 @@ export const config: Feature = { ...VisualCommands, ...BlockManipulationCommands, ...HintCommands, + ...EditCommands, ], } diff --git a/src/ts/core/roam/block.ts b/src/ts/core/roam/block.ts index 53bc9855..7efdc70a 100644 --- a/src/ts/core/roam/block.ts +++ b/src/ts/core/roam/block.ts @@ -17,4 +17,4 @@ export const copyBlockReference = (htmlBlockId: string | undefined) => { // An empirical observation: const UID_LENGTH = 9 // Uid is the id Roam uses, blockId is the id of the html element -const getBlockUid = (htmlBlockId: string): string => htmlBlockId.substr(htmlBlockId?.length - UID_LENGTH) +export const getBlockUid = (htmlBlockId: string): string => htmlBlockId.substr(htmlBlockId?.length - UID_LENGTH) diff --git a/src/ts/core/roam/roam-db.ts b/src/ts/core/roam/roam-db.ts index 907265ae..d30988a5 100644 --- a/src/ts/core/roam/roam-db.ts +++ b/src/ts/core/roam/roam-db.ts @@ -34,6 +34,11 @@ export const RoamDb = { return this.queryFirst('[:find ?e :in $ ?a :where [?e :block/uid ?a]]', uid) }, + updateBlockText(uid: string, newText: string) { + // @ts-ignore + runInPageContext((...args: any[]) => window.roamAlphaAPI.updateBlock(...args), {block: {uid, string: newText}}) + }, + getAllPages(): RoamPage[] { return this.query( '[:find ?uid ?title :where [?page :node/title ?title] [?page :block/uid ?uid]]' From 005c6170895a016eb9c0656d740d0a4d2104ef63 Mon Sep 17 00:00:00 2001 From: Vladyslav Sitalo Date: Wed, 26 Jun 2024 23:27:40 -0400 Subject: [PATCH 2/3] Add vim normal mode inc/dec dates --- src/ts/core/features/inc-dec-value.ts | 10 ++++++---- .../vim-mode/commands/edit-commands.ts | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/ts/core/features/inc-dec-value.ts b/src/ts/core/features/inc-dec-value.ts index 0265afcd..9bd653bd 100644 --- a/src/ts/core/features/inc-dec-value.ts +++ b/src/ts/core/features/inc-dec-value.ts @@ -3,7 +3,7 @@ import {RoamDate} from '../roam/date' import {Roam} from '../roam/roam' import {RoamNode, Selection} from '../roam/roam-node' -const createModifier = (change: number) => (num: number) => num + change +export const createModifier = (change: number) => (num: number) => num + change export const config: Feature = { id: 'incDec', @@ -62,7 +62,7 @@ const nameInsideBrackets = (text: string, cursor: number): string => const nameIsDate = (pageName: string): boolean => pageName.match(RoamDate.regex) !== null -const modifyDate = (date: Date, modifier: (input: number) => number): Date => { +export const modifyDate = (date: Date, modifier: (input: number) => number): Date => { const newDate = new Date(date) newDate.setDate(modifier(date.getDate())) return newDate @@ -92,9 +92,11 @@ export const modify = (modifier: (input: number) => number) => { const numberStr = left + right const numberStartedAt = node.text.substring(0, cursor)?.match(/[0-9]*$/)?.index! - let number = modifier(parseInt(numberStr)) + const newNumber = modifier(parseInt(numberStr, 10)) newValue = - node.text.substring(0, numberStartedAt) + number + node.text.substring(numberStartedAt + numberStr.length) + node.text.substring(0, numberStartedAt) + + newNumber + + node.text.substring(numberStartedAt + numberStr.length) } else if (datesInContent && datesInContent.length === 1) { // e.g. Lor|em ipsum [[January 3rd, 2020]] 123 newValue = node.text.replace( diff --git a/src/ts/core/features/vim-mode/commands/edit-commands.ts b/src/ts/core/features/vim-mode/commands/edit-commands.ts index 0d0aa07b..075c6dbd 100644 --- a/src/ts/core/features/vim-mode/commands/edit-commands.ts +++ b/src/ts/core/features/vim-mode/commands/edit-commands.ts @@ -5,6 +5,8 @@ import {AnkiScheduler} from 'src/core/srs/AnkiScheduler' import {SM2Node} from 'src/core/srs/SM2Node' import {RoamDb} from 'src/core/roam/roam-db' import {getBlockUid} from 'src/core/roam/block' +import {RoamDate} from 'src/core/roam/date' +import {createModifier, modifyDate} from 'src/core/features/inc-dec-value' const getBlockText = (uid: string): string => { const block = RoamDb.getBlockByUid(uid) @@ -29,9 +31,27 @@ const markDone = () => { RoamDb.updateBlockText(uid, '{{[[DONE]]}} ' + originalText) } +const modifyBlockDate = (modifier: (input: number) => number) => { + const uid = selectedUid() + const originalText = getBlockText(uid) + + const datesInContent = originalText.match(RoamDate.regex) + if (!datesInContent || datesInContent.length !== 1) return + + RoamDb.updateBlockText( + uid, + originalText.replace( + datesInContent[0], + RoamDate.formatPage(modifyDate(RoamDate.parseFromReference(datesInContent[0]), modifier)) + ) + ) +} + export const EditCommands = [ nmap('cmd+enter', 'Mark done', markDone), ...SRSSignals.map(it => nmap(`ctrl+shift+${it}`, `Reschedule Current Note (${SRSSignal[it]})`, () => rescheduleSelectedNote(it)) ), + nmap('ctrl+alt+up', 'Increment Date', () => modifyBlockDate(createModifier(1))), + nmap('ctrl+alt+down', 'Decrement Date', () => modifyBlockDate(createModifier(-1))), ] From 25a410047649e84961913ed63a62592aad089ec0 Mon Sep 17 00:00:00 2001 From: Vladyslav Sitalo Date: Thu, 27 Jun 2024 01:32:37 -0400 Subject: [PATCH 3/3] Update mark done to do toggle similar to native functionality --- .../features/vim-mode/commands/edit-commands.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/ts/core/features/vim-mode/commands/edit-commands.ts b/src/ts/core/features/vim-mode/commands/edit-commands.ts index 075c6dbd..1ae6d98a 100644 --- a/src/ts/core/features/vim-mode/commands/edit-commands.ts +++ b/src/ts/core/features/vim-mode/commands/edit-commands.ts @@ -25,10 +25,19 @@ const rescheduleSelectedNote = (signal: SRSSignal) => { RoamDb.updateBlockText(uid, new AnkiScheduler().schedule(new SM2Node(originalText), signal).text) } -const markDone = () => { +const toggleDone = () => { const uid = selectedUid() const originalText = getBlockText(uid) - RoamDb.updateBlockText(uid, '{{[[DONE]]}} ' + originalText) + let newText = originalText + if (originalText.startsWith('{{[[DONE]]}} ')) { + newText = originalText.replace('{{[[DONE]]}} ', '') + } else if (originalText.startsWith('{{[[TODO]]}} ')) { + newText = originalText.replace('{{[[TODO]]}} ', '{{[[DONE]]}} ') + } else { + newText = '{{[[DONE]]}} ' + originalText + } + + RoamDb.updateBlockText(uid, newText) } const modifyBlockDate = (modifier: (input: number) => number) => { @@ -48,7 +57,7 @@ const modifyBlockDate = (modifier: (input: number) => number) => { } export const EditCommands = [ - nmap('cmd+enter', 'Mark done', markDone), + nmap('cmd+enter', 'Toggle done', toggleDone), ...SRSSignals.map(it => nmap(`ctrl+shift+${it}`, `Reschedule Current Note (${SRSSignal[it]})`, () => rescheduleSelectedNote(it)) ),