diff --git a/CoreEditor/src/bridge/web/search.ts b/CoreEditor/src/bridge/web/search.ts index 5713d77f..8263c406 100644 --- a/CoreEditor/src/bridge/web/search.ts +++ b/CoreEditor/src/bridge/web/search.ts @@ -6,6 +6,7 @@ import { updateQuery, updateHasSelection, selectAllOccurrences, + selectNextOccurrence, findNext, findPrevious, replaceNext, @@ -30,6 +31,7 @@ export interface WebModuleSearch extends WebModule { replaceNext(): void; replaceAll(): void; selectAllOccurrences(): void; + selectNextOccurrence(): void; numberOfMatches(): CodeGen_Int; } @@ -76,6 +78,10 @@ export class WebModuleSearchImpl implements WebModuleSearch { selectAllOccurrences(); } + selectNextOccurrence(): void { + selectNextOccurrence(); + } + numberOfMatches(): CodeGen_Int { return numberOfMatches(); } diff --git a/CoreEditor/src/modules/search/index.ts b/CoreEditor/src/modules/search/index.ts index 0318b0ea..7ec3525d 100644 --- a/CoreEditor/src/modules/search/index.ts +++ b/CoreEditor/src/modules/search/index.ts @@ -3,6 +3,7 @@ import { findNext as findNextCommand, findPrevious as findPreviousCommand, replaceNext as replaceNextCommand, + selectNextOccurrence as selectNextOccurrenceCommand, } from '@codemirror/search'; import { Command } from '@codemirror/view'; @@ -117,6 +118,10 @@ export function selectAllOccurrences() { } } +export function selectNextOccurrence() { + selectNextOccurrenceCommand(window.editor); +} + export function numberOfMatches(): CodeGen_Int { const query = getSearchQuery(window.editor.state); const ranges = rangesFromQuery(query); diff --git a/MarkEditKit/Sources/Bridge/Web/Generated/WebBridgeSearch.swift b/MarkEditKit/Sources/Bridge/Web/Generated/WebBridgeSearch.swift index 6e39c44b..e8561bd7 100644 --- a/MarkEditKit/Sources/Bridge/Web/Generated/WebBridgeSearch.swift +++ b/MarkEditKit/Sources/Bridge/Web/Generated/WebBridgeSearch.swift @@ -112,6 +112,10 @@ public final class WebBridgeSearch { webView?.invoke(path: "webModules.search.selectAllOccurrences", completion: completion) } + public func selectNextOccurrence(completion: ((Result) -> Void)? = nil) { + webView?.invoke(path: "webModules.search.selectNextOccurrence", completion: completion) + } + public func numberOfMatches() async throws -> Int { return try await withCheckedThrowingContinuation { continuation in webView?.invoke(path: "webModules.search.numberOfMatches") { result in diff --git a/MarkEditMac/Base.lproj/Main.storyboard b/MarkEditMac/Base.lproj/Main.storyboard index c4e1bf83..8aad24cb 100755 --- a/MarkEditMac/Base.lproj/Main.storyboard +++ b/MarkEditMac/Base.lproj/Main.storyboard @@ -574,6 +574,11 @@ Gw + + + + + diff --git a/MarkEditMac/Sources/Editor/Controllers/EditorViewController+Menu.swift b/MarkEditMac/Sources/Editor/Controllers/EditorViewController+Menu.swift index 9a484f38..ed27c865 100644 --- a/MarkEditMac/Sources/Editor/Controllers/EditorViewController+Menu.swift +++ b/MarkEditMac/Sources/Editor/Controllers/EditorViewController+Menu.swift @@ -333,6 +333,10 @@ extension EditorViewController { selectAllOccurrences() } + @IBAction func selectNextOccurrence(_ sender: Any?) { + selectNextOccurrence() + } + @IBAction func scrollToSelection(_ sender: Any?) { bridge.selection.scrollToSelection() } diff --git a/MarkEditMac/Sources/Editor/Controllers/EditorViewController+TextFinder.swift b/MarkEditMac/Sources/Editor/Controllers/EditorViewController+TextFinder.swift index e1997c58..e10a0c62 100644 --- a/MarkEditMac/Sources/Editor/Controllers/EditorViewController+TextFinder.swift +++ b/MarkEditMac/Sources/Editor/Controllers/EditorViewController+TextFinder.swift @@ -196,6 +196,10 @@ extension EditorViewController { bridge.search.selectAllOccurrences() } + func selectNextOccurrence() { + bridge.search.selectNextOccurrence() + } + func performSearchOperation(_ operation: SearchOperation) { bridge.search.performOperation(operation: operation) diff --git a/MarkEditMac/mul.lproj/Main.xcstrings b/MarkEditMac/mul.lproj/Main.xcstrings index 5aa979e0..a1587ef8 100644 --- a/MarkEditMac/mul.lproj/Main.xcstrings +++ b/MarkEditMac/mul.lproj/Main.xcstrings @@ -3745,6 +3745,30 @@ } } }, + "VIj-UD-bGA.title" : { + "comment" : "Class = \"NSMenuItem\"; title = \"Select Next Occurrence\"; ObjectID = \"VIj-UD-bGA\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Select Next Occurrence" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "选择下个相同项" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "選擇下個相同項" + } + } + } + }, "vmV-6d-7jI.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"vmV-6d-7jI\";", "extractionState" : "extracted_with_value",