Skip to content

Commit

Permalink
vim without search / ex commands (#565)
Browse files Browse the repository at this point in the history
  • Loading branch information
bummoblizard committed Jan 12, 2024
1 parent a8313ba commit 60eb17d
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 1 deletion.
12 changes: 12 additions & 0 deletions Code.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,10 @@
945D4F2D2B4B3FED00DE0DBA /* libinstrument.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 945D4E1E2B4B173100DE0DBA /* libinstrument.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
945D4F2E2B4B3FED00DE0DBA /* libjawt.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 945D4E1F2B4B173100DE0DBA /* libjawt.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
945D4F2F2B4B3FED00DE0DBA /* liblcms.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 945D4E202B4B173100DE0DBA /* liblcms.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
945D4F552B50F54600DE0DBA /* VimModeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945D4F542B50F54600DE0DBA /* VimModeLabel.swift */; };
945D4F562B50F54600DE0DBA /* VimModeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945D4F542B50F54600DE0DBA /* VimModeLabel.swift */; };
945D4F582B50F55800DE0DBA /* VimKeyBufferLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945D4F572B50F55800DE0DBA /* VimKeyBufferLabel.swift */; };
945D4F592B50F55800DE0DBA /* VimKeyBufferLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945D4F572B50F55800DE0DBA /* VimKeyBufferLabel.swift */; };
9469AC9C26A33D52003F569F /* php.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9469AC9A26A33D19003F569F /* php.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
94795C452931489C0057C12F /* ActivityBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94795C442931489C0057C12F /* ActivityBar.swift */; };
94795C462931489C0057C12F /* ActivityBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94795C442931489C0057C12F /* ActivityBar.swift */; };
Expand Down Expand Up @@ -1676,6 +1680,8 @@
945D4E1F2B4B173100DE0DBA /* libjawt.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = libjawt.framework; sourceTree = "<group>"; };
945D4E202B4B173100DE0DBA /* liblcms.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = liblcms.framework; sourceTree = "<group>"; };
945D4E212B4B173700DE0DBA /* java-8-openjdk */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "java-8-openjdk"; path = "Java/java-8-openjdk"; sourceTree = "<group>"; };
945D4F542B50F54600DE0DBA /* VimModeLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VimModeLabel.swift; sourceTree = "<group>"; };
945D4F572B50F55800DE0DBA /* VimKeyBufferLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VimKeyBufferLabel.swift; sourceTree = "<group>"; };
945E7E3727CA79C900BA1D95 /* NodeMobile.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = NodeMobile.xcframework; path = Resources/NodeJS/NodeMobile.xcframework; sourceTree = "<group>"; };
9469AC9A26A33D19003F569F /* php.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = php.xcframework; sourceTree = "<group>"; };
94795C442931489C0057C12F /* ActivityBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityBar.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2773,6 +2779,8 @@
9FD0FAEF2938A14C007170F5 /* EncodingMenu.swift */,
9FA122632A8B2A8C00E7B417 /* EditorReadOnlyLabel.swift */,
9FA122662A8B2AC300E7B417 /* EditorLineColumnIndicator.swift */,
945D4F542B50F54600DE0DBA /* VimModeLabel.swift */,
945D4F572B50F55800DE0DBA /* VimKeyBufferLabel.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -3267,6 +3275,7 @@
942E32082808805F00233441 /* SearchUnsupportedSection.swift in Sources */,
94A347BE293DE24B00A59658 /* hiddenSystemOverlays.swift in Sources */,
9F3C2DC92918A31000BFF14C /* hiddenScrollableContentBackground.swift in Sources */,
945D4F592B50F55800DE0DBA /* VimKeyBufferLabel.swift in Sources */,
9FC03E6A291F303900DECD1B /* Utilities.swift in Sources */,
9419695D280316C7008AAEB2 /* TopBar.swift in Sources */,
9419695E280316C7008AAEB2 /* EditorKeyboardToolBar.swift in Sources */,
Expand Down Expand Up @@ -3320,6 +3329,7 @@
9419697B280316C7008AAEB2 /* FTPFileSystemProvider.swift in Sources */,
9F170D022A89CEB800D6D7C1 /* String+throwingRemovingPercentEncoding.swift in Sources */,
94FA8978292FB86700163800 /* PDFViewerExtension.swift in Sources */,
945D4F562B50F54600DE0DBA /* VimModeLabel.swift in Sources */,
9FAE499C292F530B00B1B962 /* SourceControlAuxiliaryExtension.swift in Sources */,
9419697C280316C7008AAEB2 /* View+cornerRadius.swift in Sources */,
9419697E280316C7008AAEB2 /* MonacoIntellisenseExtension.swift in Sources */,
Expand Down Expand Up @@ -3438,6 +3448,7 @@
942E32072808805F00233441 /* SearchUnsupportedSection.swift in Sources */,
94A347BD293DE24B00A59658 /* hiddenSystemOverlays.swift in Sources */,
9F3C2DC82918A31000BFF14C /* hiddenScrollableContentBackground.swift in Sources */,
945D4F582B50F55800DE0DBA /* VimKeyBufferLabel.swift in Sources */,
9FC03E69291F303900DECD1B /* Utilities.swift in Sources */,
94D721DF268DA2B8007A63BD /* TopBar.swift in Sources */,
9438C9A225CBD25F00335E82 /* EditorKeyboardToolBar.swift in Sources */,
Expand Down Expand Up @@ -3491,6 +3502,7 @@
941969292802AB64008AAEB2 /* FTPFileSystemProvider.swift in Sources */,
9F170D012A89CEB800D6D7C1 /* String+throwingRemovingPercentEncoding.swift in Sources */,
94FA8977292FB86700163800 /* PDFViewerExtension.swift in Sources */,
945D4F552B50F54600DE0DBA /* VimModeLabel.swift in Sources */,
9FAE499B292F530B00B1B962 /* SourceControlAuxiliaryExtension.swift in Sources */,
94A777B7257B6A43008FE7B2 /* View+cornerRadius.swift in Sources */,
949B3CBB25DBCCDC00BC83B5 /* MonacoIntellisenseExtension.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions CodeApp/Localization/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@
"settings.editor.font.reset" = "Standard";
"settings.editor.font.ligatures" = "Schrift Ligaturen";
"settings.editor.font.show_all_fonts" = "Alle Schriftarten anzeigen";
"settings.editor.vim.enabled" = "Vim aktiviert";
"settings.explorer.confirm_before_delete" = "Bestätigen Sie vor dem Löschen";
"settings.explorer.show_hidden_files" = "Versteckte Dateien anzeigen";
"panels.no_panel_selected" = "Kein Panel ausgewählt";
Expand Down
1 change: 1 addition & 0 deletions CodeApp/Localization/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ are licensed under [BSD-3-Clause License](https://en.wikipedia.org/wiki/BSD_lice
"settings.editor.font.reset" = "Reset to default";
"settings.editor.font.ligatures" = "Font Ligatures";
"settings.editor.font.show_all_fonts" = "Show All Fonts";
"settings.editor.vim.enabled" = "Vim Mode";
"settings.explorer.confirm_before_delete" = "Confirm Before Deleting";
"settings.explorer.show_hidden_files" = "Show Hidden Files";
"panels.no_panel_selected" = "No panel selected";
Expand Down
1 change: 1 addition & 0 deletions CodeApp/Localization/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@
"settings.editor.font.reset" = "デフォルトにリセット";
"settings.editor.font.ligatures" = "フォント合字";
"settings.editor.font.show_all_fonts" = "すべてのフォントを表示";
"settings.editor.vim.enabled" = "Vim キーバインディングを有効にする";
"settings.explorer.confirm_before_delete" = "削除する前に確認する";
"settings.explorer.show_hidden_files" = "隠しファイルを表示";
"panels.no_panel_selected" = "パネルが選択されていません";
Expand Down
1 change: 1 addition & 0 deletions CodeApp/Localization/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@
"settings.editor.font.reset" = "기본값";
"settings.editor.font.ligatures" = "글꼴 합자";
"settings.editor.font.show_all_fonts" = "모든 글꼴 표시";
"settings.editor.vim.enabled" = "Vim 편집기 활성화";
"settings.explorer.confirm_before_delete" = "삭제하기 전에 확인";
"settings.explorer.show_hidden_files" = "숨김 파일 표시";
"panels.no_panel_selected" = "패널이 선택되지 않았습니다.";
Expand Down
1 change: 1 addition & 0 deletions CodeApp/Localization/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@
"settings.editor.font.reset" = "重置";
"settings.editor.font.ligatures" = "合字";
"settings.editor.font.show_all_fonts" = "显示所有字体";
"settings.editor.vim.enabled" = "启用 Vim";
"settings.explorer.confirm_before_delete" = "删除前确认";
"settings.explorer.show_hidden_files" = "显示隐藏文件";
"panels.no_panel_selected" = "没有选中的面板";
Expand Down
15 changes: 15 additions & 0 deletions CodeApp/Managers/MonacoEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct MonacoEditor: UIViewRepresentable {
@AppStorage("editorSpellCheckEnabled") var editorSpellCheckEnabled = false
@AppStorage("editorSpellCheckOnContentChanged") var editorSpellCheckOnContentChanged = true
@AppStorage("stateRestorationEnabled") var stateRestorationEnabled = true
@AppStorage("editor.vim.enabled") var editorVimEnabled: Bool = false
@SceneStorage("activeEditor.monaco.state") var activeEditorMonacoState: String?

let monacoWebView = WebViewBase()
Expand Down Expand Up @@ -116,6 +117,8 @@ struct MonacoEditor: UIViewRepresentable {
"editor.updateOptions({renderWhitespace: '\(String(renderWhitespaceOptions[renderWhitespace]).lowercased())'})"
)
executeJavascript(command: "editor.updateOptions({wordWrap: '\(editorWordWrap)'})")

executeJavascript(command: "toggleVimMode(\(editorVimEnabled))")
}

func removeAllModel() {
Expand Down Expand Up @@ -394,6 +397,14 @@ struct MonacoEditor: UIViewRepresentable {
}
}

private func dispatchNotificationEvent(event: String, userInfo: [AnyHashable: Any]?) {
var userInfo = userInfo ?? [:]
userInfo["sceneIdentifier"] = control.App.sceneIdentifier
NotificationCenter.default.post(
name: Notification.Name(event), object: nil,
userInfo: userInfo)
}

func userContentController(
_ userContentController: WKUserContentController, didReceive message: WKScriptMessage
) {
Expand Down Expand Up @@ -513,6 +524,10 @@ struct MonacoEditor: UIViewRepresentable {

}
}
// Vim related events
case "vim.mode.change", "vim.keybuffer.set", "vim.visible.set", "vim.close.input",
"vim.claer":
dispatchNotificationEvent(event: event, userInfo: result)

default:
print("[Error] \(event) not handled")
Expand Down
3 changes: 3 additions & 0 deletions CodeApp/Managers/WebViewBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class WebViewBase: KBWebViewBase {
config.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
config.preferences.setValue(true, forKey: "shouldAllowUserInstalledFonts")
super.init(frame: .zero, configuration: config)
if #available(iOS 16.4, *) {
self.isInspectable = true
}
}

required init?(coder: NSCoder) {
Expand Down
6 changes: 6 additions & 0 deletions CodeApp/Views/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct SettingsView: View {
@AppStorage("communityTemplatesEnabled") var communityTemplatesEnabled = true
@AppStorage("showAllFonts") var showAllFonts = false
@AppStorage("remoteShouldResolveHomePath") var remoteShouldResolveHomePath = false
@AppStorage("editor.vim.enabled") var editorVimEnabled: Bool = false

@State var showsEraseAlert: Bool = false
@State var showReceiptInformation: Bool = false
Expand Down Expand Up @@ -134,6 +135,11 @@ struct SettingsView: View {

Section(header: Text(NSLocalizedString("Editor", comment: ""))) {

Toggle("settings.editor.vim.enabled", isOn: $editorVimEnabled)
.onChange(of: editorVimEnabled) { _ in
App.monacoInstance.applyUserOptions()
}

NavigationLink(
destination: SettingsFontPicker(
showAllFonts: showAllFonts,
Expand Down
2 changes: 1 addition & 1 deletion Dependencies/monaco-textmate.bundle/app.bundle.js

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions Dependencies/monaco-textmate.bundle/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,64 @@
var previousDecoration = [];

let devicehasCursor = false;
let vimMode = null;

class VimStatusBarAdpator {
constructor(node, editor, sanitizer) {
console.log("Constuctor called");
window.webkit.messageHandlers.toggleMessageHandler.postMessage({
Event: "vim.mode.change",
newMode: "--NORMAL--",
});
}

setMode(ev){
let mode = `--${ev.mode.toUpperCase()}--`;
if (ev.mode === "visual") {
if (ev.subMode === "linewise") {
mode = "--VISUAL LINE--";
} else if (ev.subMode === "blockwise") {
mode = "--VISUAL BLOCK--";
} else {
mode = "--VISUAL--";
}
}
window.webkit.messageHandlers.toggleMessageHandler.postMessage({
Event: "vim.mode.change",
newMode: mode,
});
}

setKeyBuffer(key) {
window.webkit.messageHandlers.toggleMessageHandler.postMessage({
Event: "vim.keybuffer.set",
buffer: key,
});
}

toggleVisibility(isVisible) {
window.webkit.messageHandlers.toggleMessageHandler.postMessage({
Event: "vim.visible.set",
isVisible: isVisible,
});
}

closeInput() {
window.webkit.messageHandlers.toggleMessageHandler.postMessage({
Event: "vim.close.input"
});
}

clear(){
window.webkit.messageHandlers.toggleMessageHandler.postMessage({
Event: "vim.clear",
});
}

setSec(text, callback, options) {
// TODO: Handle prompt to enable ex commands and search
}
}

setTimeout(() => {
if (typeof editor === "undefined") {
Expand Down Expand Up @@ -628,6 +686,16 @@
if (!model) return;
editor.setModel(model);
}

function toggleVimMode(enabled){
if (enabled) {
if (vimMode) {return};
vimMode = initVimMode(editor, true, VimStatusBarAdpator);
}else {
vimMode?.dispose();
vimMode = null;
}
}
</script>
</body>
</html>
15 changes: 15 additions & 0 deletions Extensions/MonacoEditor/MonacoEditorExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,23 @@ class MonacoEditorAuxiliaryExtension: CodeAppExtension {
positionPreference: .right,
positionPrecedence: Int.max - 2
)
let vimKeyBufferStatusBarItem = StatusBarItem(
extensionID: MONACO_EDITOR_EXTENSION_ID,
view: AnyView(VimKeyBufferLabel()),
shouldDisplay: { app.activeEditor is TextEditorInstance },
positionPreference: .right,
positionPrecedence: Int.min
)
let vimModeStatusBarItem = StatusBarItem(
extensionID: MONACO_EDITOR_EXTENSION_ID,
view: AnyView(VimModeLabel()),
shouldDisplay: { app.activeEditor is TextEditorInstance },
positionPreference: .left,
positionPrecedence: Int.min
)
for item in [
encodingStatusBarItem, lineColumnIndicatorStatusBarItem, readOnlyStatusBarItem,
vimKeyBufferStatusBarItem, vimModeStatusBarItem,
] {
contribution.statusBar.registerItem(item: item)
}
Expand Down
46 changes: 46 additions & 0 deletions Extensions/MonacoEditor/Views/VimKeyBufferLabel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// VimKeyBufferLabel.swift
// Code
//
// Created by Ken Chung on 12/01/2024.
//

import SwiftUI

struct VimKeyBufferLabel: View {
@EnvironmentObject var App: MainApp
@State var keyBuffer = ""

var body: some View {
Text(keyBuffer)
.onReceive(
NotificationCenter.default.publisher(
for: Notification.Name("vim.keybuffer.set"),
object: nil),
perform: { notification in
guard
let sceneIdentifier =
notification.userInfo?["sceneIdentifier"] as? UUID,
sceneIdentifier == App.sceneIdentifier
else { return }

if let newKeyBuffer = notification.userInfo?["buffer"] as? String {
keyBuffer = newKeyBuffer
}
}
)
.onReceive(
NotificationCenter.default.publisher(
for: Notification.Name("vim.clear"),
object: nil),
perform: { notification in
guard
let sceneIdentifier =
notification.userInfo?["sceneIdentifier"] as? UUID,
sceneIdentifier == App.sceneIdentifier
else { return }

keyBuffer = ""
})
}
}
47 changes: 47 additions & 0 deletions Extensions/MonacoEditor/Views/VimModeLabel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// VimModeLabel.swift
// Code
//
// Created by Ken Chung on 12/01/2024.
//

import SwiftUI

struct VimModeLabel: View {
@EnvironmentObject var App: MainApp
@State var mode = "--NORMAL--"
@AppStorage("editor.vim.enabled") var editorVimEnabled: Bool = false

var body: some View {
Text(editorVimEnabled ? mode : "")
.onReceive(
NotificationCenter.default.publisher(
for: Notification.Name("vim.mode.change"),
object: nil),
perform: { notification in
guard
let sceneIdentifier =
notification.userInfo?["sceneIdentifier"] as? UUID,
sceneIdentifier == App.sceneIdentifier
else { return }

if let newMode = notification.userInfo?["newMode"] as? String {
mode = newMode
}
}
)
.onReceive(
NotificationCenter.default.publisher(
for: Notification.Name("vim.clear"),
object: nil),
perform: { notification in
guard
let sceneIdentifier =
notification.userInfo?["sceneIdentifier"] as? UUID,
sceneIdentifier == App.sceneIdentifier
else { return }

mode = ""
})
}
}

0 comments on commit 60eb17d

Please sign in to comment.