From 63a1c9b450edb93235d91f785ddb8bbd3dc9417a Mon Sep 17 00:00:00 2001 From: Evan Zhou Date: Sun, 7 Apr 2024 14:25:30 -0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Improved=20Formatting=20functionali?= =?UTF-8?q?ty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/format.ts | 78 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/api/format.ts b/src/api/format.ts index 1f5b2a5..1410e8e 100644 --- a/src/api/format.ts +++ b/src/api/format.ts @@ -266,25 +266,59 @@ const getChanges = (changeDetails: ChangeDetails) => { return formatInline(changeDetails) } -export const format = ([state]: InkInternal.Store, formatType: Ink.EnumString, { selection: maybeSelection }: Ink.Instance.FormatOptions = {}) => { - const { editor } = state() - const formatDefinition = formatting[formatType] - const selection = getSelection({ editor, formatDefinition, selection: maybeSelection }) - const node = getNode(editor, formatDefinition, selection) - const changeDetails: ChangeDetails = { - editor, - formatDefinition, - node, - selection, - } - const changes = getChanges(changeDetails) - const offset = changes.reduce((total, change: { from: number, insert: string, to?: number }) => { - const offset = change.insert.length - ((change.to || change.from) - change.from) - - return total + offset - }, 0) - - const updates = state().editor.state.update({ changes, selection: { head: selection.start, anchor: selection.end + offset } }) - - state().editor.dispatch(updates) -} +export const format = ( + [state]: InkInternal.Store, + formatType: Ink.EnumString, + { selection: maybeSelection }: Ink.Instance.FormatOptions = {} +) => { + const { editor } = state(); + const formatDefinition = formatting[formatType]; + const selection = getSelection({ + editor, + formatDefinition, + selection: maybeSelection, + }); + + // Check if the selection is empty + if (selection.start === selection.end) { + // Insert the prefix and suffix around the cursor + const changes = [ + { from: selection.start, insert: formatDefinition.prefix }, + { from: selection.start, insert: formatDefinition.suffix }, + ]; + const cursorPosition = selection.start + formatDefinition.prefix.length; + const updates = state().editor.state.update({ + changes, + selection: { head: cursorPosition, anchor: cursorPosition }, + }); + + state().editor.dispatch(updates); + state().editor.focus(); + } else { + const node = getNode(editor, formatDefinition, selection); + const changeDetails: ChangeDetails = { + editor, + formatDefinition, + node, + selection, + }; + const changes = getChanges(changeDetails); + const offset = changes.reduce( + (total, change: { from: number; insert: string; to?: number }) => { + const offset = + change.insert.length - ((change.to || change.from) - change.from); + + return total + offset; + }, + 0 + ); + + const updates = state().editor.state.update({ + changes, + selection: { head: selection.start, anchor: selection.end + offset }, + }); + + state().editor.dispatch(updates); + state().editor.focus(); + } +};