Skip to content

Commit 29c28ba

Browse files
authored
Add Shortcuts support (#107)
* Add Shortcuts support * Better naming * Improve comments * Improve README.md * Update screenshots
1 parent c4ea89e commit 29c28ba

File tree

16 files changed

+370
-5
lines changed

16 files changed

+370
-5
lines changed

CoreEditor/src/bridge/web/core.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { WebModule } from '../webModule';
2-
import { resetEditor, clearEditor, getEditorText, insertText, markEditorDirty } from '../../core';
2+
import { ReplaceGranularity, resetEditor, clearEditor, getEditorText, insertText, replaceText, markEditorDirty } from '../../core';
33

44
/**
55
* @shouldExport true
@@ -11,6 +11,7 @@ export interface WebModuleCore extends WebModule {
1111
clearEditor(): void;
1212
getEditorText(): string;
1313
insertText({ text, from, to }: { text: string; from: CodeGen_Int; to: CodeGen_Int }): void;
14+
replaceText({ text, granularity }: { text: string; granularity: ReplaceGranularity }): void;
1415
markEditorDirty({ isDirty }: { isDirty: boolean }): void;
1516
}
1617

@@ -31,6 +32,10 @@ export class WebModuleCoreImpl implements WebModuleCore {
3132
insertText(text, from, to);
3233
}
3334

35+
replaceText({ text, granularity }: { text: string; granularity: ReplaceGranularity }): void {
36+
replaceText(text, granularity);
37+
}
38+
3439
markEditorDirty({ isDirty }: { isDirty: boolean }): void {
3540
markEditorDirty(isDirty);
3641
}

CoreEditor/src/core.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import { EditorView } from '@codemirror/view';
22
import { extensions } from './extensions';
33
import { editingState } from './common/store';
4+
import replaceSelections from './modules/commands/replaceSelections';
45

56
import * as styling from './styling/config';
67
import * as themes from './styling/themes';
78
import * as history from './modules/history';
89
import * as lineEndings from './modules/lineEndings';
910
import * as completion from './modules/completion';
1011

12+
export enum ReplaceGranularity {
13+
wholeDocument = 'wholeDocument',
14+
selection = 'selection',
15+
}
16+
1117
/**
1218
* Reset the editor to the initial state.
1319
*
@@ -93,6 +99,17 @@ export function insertText(text: string, from: number, to: number) {
9399
});
94100
}
95101

102+
export function replaceText(text: string, granularity: ReplaceGranularity) {
103+
switch (granularity) {
104+
case ReplaceGranularity.wholeDocument:
105+
insertText(text, 0, window.editor.state.doc.length);
106+
break;
107+
case ReplaceGranularity.selection:
108+
replaceSelections(text);
109+
break;
110+
}
111+
}
112+
96113
export function markEditorDirty(isDirty: boolean) {
97114
editingState.isDirty = isDirty;
98115
}

MarkEdit.xcodeproj/project.pbxproj

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
873D6438295FEF220095DEF7 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 873D643A295FEF220095DEF7 /* Localizable.strings */; };
4040
874823CE29B0BD980067EC49 /* TextCompletion in Frameworks */ = {isa = PBXBuildFile; productRef = 874823CD29B0BD980067EC49 /* TextCompletion */; };
4141
874AAE2E2959F197000E0E84 /* EditorReplacePanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874AAE2D2959F197000E0E84 /* EditorReplacePanel.swift */; };
42+
874BE6F429BB37FA002F83BA /* IntentProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874BE6F329BB37FA002F83BA /* IntentProvider.swift */; };
43+
874BE6F729BB57AC002F83BA /* IntentError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874BE6F629BB57AC002F83BA /* IntentError.swift */; };
44+
874BE6FB29BB5804002F83BA /* AppIntent+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874BE6FA29BB5804002F83BA /* AppIntent+Extension.swift */; };
45+
874BE70229BB5889002F83BA /* GetFileContentIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874BE70129BB5889002F83BA /* GetFileContentIntent.swift */; };
46+
874BE70829BB62BA002F83BA /* CreateNewDocumentIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874BE70729BB62BA002F83BA /* CreateNewDocumentIntent.swift */; };
47+
874BE70E29BB73CA002F83BA /* UpdateFileContentIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874BE70D29BB73CA002F83BA /* UpdateFileContentIntent.swift */; };
4248
8752CEB6295B2F8800BA9D5B /* EditorPanelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8752CEB5295B2F8800BA9D5B /* EditorPanelView.swift */; };
4349
876578FA2993853500A1388A /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 876578F92993853500A1388A /* index.html */; };
4450
8767BBAF295A8BA500BFACAE /* EditorViewController+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8767BBAE295A8BA500BFACAE /* EditorViewController+UI.swift */; };
@@ -140,6 +146,12 @@
140146
873D643D295FEF370095DEF7 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
141147
8743B26229593B2000F83DAE /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = "<group>"; };
142148
874AAE2D2959F197000E0E84 /* EditorReplacePanel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorReplacePanel.swift; sourceTree = "<group>"; };
149+
874BE6F329BB37FA002F83BA /* IntentProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentProvider.swift; sourceTree = "<group>"; };
150+
874BE6F629BB57AC002F83BA /* IntentError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentError.swift; sourceTree = "<group>"; };
151+
874BE6FA29BB5804002F83BA /* AppIntent+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppIntent+Extension.swift"; sourceTree = "<group>"; };
152+
874BE70129BB5889002F83BA /* GetFileContentIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetFileContentIntent.swift; sourceTree = "<group>"; };
153+
874BE70729BB62BA002F83BA /* CreateNewDocumentIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateNewDocumentIntent.swift; sourceTree = "<group>"; };
154+
874BE70D29BB73CA002F83BA /* UpdateFileContentIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateFileContentIntent.swift; sourceTree = "<group>"; };
143155
8752CEB5295B2F8800BA9D5B /* EditorPanelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorPanelView.swift; sourceTree = "<group>"; };
144156
876578F92993853500A1388A /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = index.html; path = "CoreEditor/src/@light/dist/index.html"; sourceTree = SOURCE_ROOT; };
145157
8767BBAE295A8BA500BFACAE /* EditorViewController+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditorViewController+UI.swift"; sourceTree = "<group>"; };
@@ -283,6 +295,7 @@
283295
873D6403295FD2FF0095DEF7 /* Main */,
284296
870A51C429470D830095C7EB /* Editor */,
285297
870F1797298577A000003DA7 /* Panels */,
298+
874BE6F229BB37D5002F83BA /* Shortcuts */,
286299
8780AC0A29822C5500065EF4 /* Settings */,
287300
87850C8429482A6A00D1A952 /* Extensions */,
288301
);
@@ -354,6 +367,35 @@
354367
name = Frameworks;
355368
sourceTree = "<group>";
356369
};
370+
874BE6F229BB37D5002F83BA /* Shortcuts */ = {
371+
isa = PBXGroup;
372+
children = (
373+
874BE6FD29BB581E002F83BA /* Intents */,
374+
874BE6F929BB57FA002F83BA /* Extensions */,
375+
874BE6F629BB57AC002F83BA /* IntentError.swift */,
376+
874BE6F329BB37FA002F83BA /* IntentProvider.swift */,
377+
);
378+
path = Shortcuts;
379+
sourceTree = "<group>";
380+
};
381+
874BE6F929BB57FA002F83BA /* Extensions */ = {
382+
isa = PBXGroup;
383+
children = (
384+
874BE6FA29BB5804002F83BA /* AppIntent+Extension.swift */,
385+
);
386+
path = Extensions;
387+
sourceTree = "<group>";
388+
};
389+
874BE6FD29BB581E002F83BA /* Intents */ = {
390+
isa = PBXGroup;
391+
children = (
392+
874BE70729BB62BA002F83BA /* CreateNewDocumentIntent.swift */,
393+
874BE70129BB5889002F83BA /* GetFileContentIntent.swift */,
394+
874BE70D29BB73CA002F83BA /* UpdateFileContentIntent.swift */,
395+
);
396+
path = Intents;
397+
sourceTree = "<group>";
398+
};
357399
8767BBAC295A893200BFACAE /* Controllers */ = {
358400
isa = PBXGroup;
359401
children = (
@@ -590,18 +632,23 @@
590632
buildActionMask = 2147483647;
591633
files = (
592634
8725E0822977EF46006A4961 /* EditorViewController+Toolbar.swift in Sources */,
635+
874BE6F429BB37FA002F83BA /* IntentProvider.swift in Sources */,
636+
874BE70E29BB73CA002F83BA /* UpdateFileContentIntent.swift in Sources */,
593637
8780AC202982A2DD00065EF4 /* WindowSettingsView.swift in Sources */,
594638
87BD071229699A290053EF5F /* EditorViewController+Preview.swift in Sources */,
595639
873D6402295FCC3E0095DEF7 /* AppResources.swift in Sources */,
596640
870A51BC294702AF0095C7EB /* AppDelegate.swift in Sources */,
597641
8780AC1E2982A2C900065EF4 /* EditorSettingsView.swift in Sources */,
598642
8767BBB5295AD62700BFACAE /* EditorReplaceButtons.swift in Sources */,
599643
87BDF6E42976C97100548079 /* EditorViewController+GotoLine.swift in Sources */,
644+
874BE6FB29BB5804002F83BA /* AppIntent+Extension.swift in Sources */,
600645
87F2B5F429ACF56E0027103E /* EditorViewController+Completion.swift in Sources */,
601646
8772E385294AC60D00111E83 /* EditorReusePool.swift in Sources */,
602647
8709C69E29B4412F009EABB5 /* AssistantSettingsView.swift in Sources */,
648+
874BE70229BB5889002F83BA /* GetFileContentIntent.swift in Sources */,
603649
870F17662984D2C000003DA7 /* EditorViewController+LineEndings.swift in Sources */,
604650
8790B6EC297036B2000DFC1A /* EditorWindow.swift in Sources */,
651+
874BE6F729BB57AC002F83BA /* IntentError.swift in Sources */,
605652
87AA1224296560AE00BE4719 /* EditorViewController+HyperLink.swift in Sources */,
606653
8725E0802977EEB3006A4961 /* EditorToolbarItems.swift in Sources */,
607654
870A51B9294702AF0095C7EB /* EditorViewController.swift in Sources */,
@@ -625,6 +672,7 @@
625672
8767BBAF295A8BA500BFACAE /* EditorViewController+UI.swift in Sources */,
626673
87AAEDF52958258C00C8E61C /* EditorFindPanel+UI.swift in Sources */,
627674
87A73AB5294C4B48006A710E /* EditorFindPanel.swift in Sources */,
675+
874BE70829BB62BA002F83BA /* CreateNewDocumentIntent.swift in Sources */,
628676
870A51BD294702AF0095C7EB /* EditorDocument.swift in Sources */,
629677
8780AC182982554800065EF4 /* SettingTabs.swift in Sources */,
630678
87F2B61429AF2F3A0027103E /* NSSpellChecker+Extension.swift in Sources */,

MarkEditKit/Sources/Bridge/Web/Generated/WebBridgeCore.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ public final class WebBridgeCore {
5757
webView?.invoke(path: "webModules.core.insertText", message: message, completion: completion)
5858
}
5959

60+
public func replaceText(text: String, granularity: ReplaceGranularity, completion: ((Result<Void, WKWebView.InvokeError>) -> Void)? = nil) {
61+
struct Message: Encodable {
62+
let text: String
63+
let granularity: ReplaceGranularity
64+
}
65+
66+
let message = Message(
67+
text: text,
68+
granularity: granularity
69+
)
70+
71+
webView?.invoke(path: "webModules.core.replaceText", message: message, completion: completion)
72+
}
73+
6074
public func markEditorDirty(isDirty: Bool, completion: ((Result<Void, WKWebView.InvokeError>) -> Void)? = nil) {
6175
struct Message: Encodable {
6276
let isDirty: Bool
@@ -69,3 +83,8 @@ public final class WebBridgeCore {
6983
webView?.invoke(path: "webModules.core.markEditorDirty", message: message, completion: completion)
7084
}
7185
}
86+
87+
public enum ReplaceGranularity: String, Codable {
88+
case wholeDocument = "wholeDocument"
89+
case selection = "selection"
90+
}

MarkEditMac/Resources/zh-Hans.lproj/Localizable.strings

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,21 @@
5252
/* Label for word completion options */
5353
"Completion:" = "单词补全:";
5454

55+
/* No comment provided by engineer. */
56+
"Content" = "内容";
57+
5558
/* Phrase used in CodeMirror to indicate control character */
5659
"Control Character" = "控制字符";
5760

5861
/* Toolbar item to copy pandoc command */
5962
"Copy Pandoc Command" = "拷贝 Pandoc 指令";
6063

64+
/* No comment provided by engineer. */
65+
"Create a new document, with an optional parameter to specify the initial content." = "新建一个文档,可通过一个可选参数来指定初始内容。";
66+
67+
/* No comment provided by engineer. */
68+
"Create New Document" = "创建新文档";
69+
6170
/* Always use dark mode for the app */
6271
"Dark" = "深色";
6372

@@ -106,9 +115,18 @@
106115
/* Window title for general settings */
107116
"General" = "通用";
108117

118+
/* No comment provided by engineer. */
119+
"Get File Content" = "获取文件内容";
120+
121+
/* No comment provided by engineer. */
122+
"Get file content of the active document, throws an error if no editor is opened." = "获取当前活跃文档的内容,没有打开的编辑器时将抛出异常。";
123+
109124
/* Placeholder text for goto line window */
110125
"Go to Line" = "跳转到行";
111126

127+
/* No comment provided by engineer. */
128+
"Granularity" = "粒度";
129+
112130
/* Option for guessed words suggestion */
113131
"Guessed words" = "猜测的单词";
114132

@@ -124,6 +142,9 @@
124142
/* Press tab key to indent more */
125143
"Indents more" = "增加缩进";
126144

145+
/* No comment provided by engineer. */
146+
"Initial Content" = "初始内容";
147+
127148
/* Toolbar item to insert code */
128149
"Insert Code" = "插入代码";
129150

@@ -172,12 +193,18 @@
172193
/* Line endings used on macOS and Unix */
173194
"macOS / Unix (LF)" = "macOS / Unix (LF)";
174195

196+
/* No comment provided by engineer. */
197+
"Missing active document to proceed." = "没有活跃的文档来进行下一步。";
198+
175199
/* Never show invisibles */
176200
"Never" = "从不";
177201

178202
/* Menu item: create a new document */
179203
"New Document" = "新建文档";
180204

205+
/* No comment provided by engineer. */
206+
"New Document with ${initialContent}" = "使用 ${initialContent} 新建文档";
207+
181208
/* Behavior when creating new windows */
182209
"New Window Behavior:" = "新窗口行为:";
183210

@@ -235,6 +262,9 @@
235262
/* Replace mode in search menu */
236263
"Replace" = "替换";
237264

265+
/* No comment provided by engineer. */
266+
"Save Changes" = "保存改动";
267+
238268
/* Menu item: select all occurrences */
239269
"Select All Occurrences" = "选择所有相同项";
240270

@@ -319,6 +349,18 @@
319349
/* Phrase used in CodeMirror to indicate unfolded lines */
320350
"Unfolded Lines" = "展开的行";
321351

352+
/* No comment provided by engineer. */
353+
"Update File Content" = "更新文件内容";
354+
355+
/* No comment provided by engineer. */
356+
"Update file content of the active document, throws an error if no editor is opened." = "更新当前活跃文档的内容,没有打开的编辑器时将抛出异常。";
357+
358+
/* No comment provided by engineer. */
359+
"Update file with ${content}" = "使用 ${content} 更新文件";
360+
361+
/* No comment provided by engineer. */
362+
"Whole Document" = "整个文档";
363+
322364
/* Toggle whole word search */
323365
"Whole Word" = "整词查找";
324366

MarkEditMac/Resources/zh-Hant.lproj/Localizable.strings

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,21 @@
5252
/* Label for word completion options */
5353
"Completion:" = "單字補全:";
5454

55+
/* No comment provided by engineer. */
56+
"Content" = "內容";
57+
5558
/* Phrase used in CodeMirror to indicate control character */
5659
"Control Character" = "控制字元";
5760

5861
/* Toolbar item to copy pandoc command */
5962
"Copy Pandoc Command" = "拷貝 Pandoc 指令";
6063

64+
/* No comment provided by engineer. */
65+
"Create a new document, with an optional parameter to specify the initial content." = "新建一個文件,可透過一個可選變數來指定初始內容。";
66+
67+
/* No comment provided by engineer. */
68+
"Create New Document" = "建立新文件";
69+
6170
/* Always use dark mode for the app */
6271
"Dark" = "深色";
6372

@@ -106,9 +115,18 @@
106115
/* Window title for general settings */
107116
"General" = "一般";
108117

118+
/* No comment provided by engineer. */
119+
"Get File Content" = "獲取文件內容";
120+
121+
/* No comment provided by engineer. */
122+
"Get file content of the active document, throws an error if no editor is opened." = "獲取當前活躍文件的內容,沒有開啟的編輯器時將丟擲異常。";
123+
109124
/* Placeholder text for goto line window */
110125
"Go to Line" = "跳轉到行";
111126

127+
/* No comment provided by engineer. */
128+
"Granularity" = "粒度";
129+
112130
/* Option for guessed words suggestion */
113131
"Guessed words" = "猜測的單字";
114132

@@ -124,6 +142,9 @@
124142
/* Press tab key to indent more */
125143
"Indents more" = "增加縮排";
126144

145+
/* No comment provided by engineer. */
146+
"Initial Content" = "初始內容";
147+
127148
/* Toolbar item to insert code */
128149
"Insert Code" = "插入程式碼";
129150

@@ -172,12 +193,18 @@
172193
/* Line endings used on macOS and Unix */
173194
"macOS / Unix (LF)" = "macOS / Unix (LF)";
174195

196+
/* No comment provided by engineer. */
197+
"Missing active document to proceed." = "沒有活躍的文件來進行下一步。";
198+
175199
/* Never show invisibles */
176200
"Never" = "從不";
177201

178202
/* Menu item: create a new document */
179203
"New Document" = "新增文件";
180204

205+
/* No comment provided by engineer. */
206+
"New Document with ${initialContent}" = "使用 ${initialContent} 新增文件";
207+
181208
/* Behavior when creating new windows */
182209
"New Window Behavior:" = "新視窗行為:";
183210

@@ -235,6 +262,9 @@
235262
/* Replace mode in search menu */
236263
"Replace" = "取代";
237264

265+
/* No comment provided by engineer. */
266+
"Save Changes" = "儲存改動";
267+
238268
/* Menu item: select all occurrences */
239269
"Select All Occurrences" = "選擇所有相同項";
240270

@@ -319,6 +349,18 @@
319349
/* Phrase used in CodeMirror to indicate unfolded lines */
320350
"Unfolded Lines" = "展開的行";
321351

352+
/* No comment provided by engineer. */
353+
"Update File Content" = "更新文件內容";
354+
355+
/* No comment provided by engineer. */
356+
"Update file content of the active document, throws an error if no editor is opened." = "更新當前活躍文件的內容,沒有開啟的編輯器時將丟擲異常。";
357+
358+
/* No comment provided by engineer. */
359+
"Update file with ${content}" = "使用 ${content} 更新文件";
360+
361+
/* No comment provided by engineer. */
362+
"Whole Document" = "整個文件";
363+
322364
/* Toggle whole word search */
323365
"Whole Word" = "整詞尋找";
324366

0 commit comments

Comments
 (0)