pull/369/head
Zef Hemel 2023-01-23 18:52:17 +01:00
parent 53bf098579
commit e7728c2d2a
10 changed files with 102 additions and 27 deletions

View File

@ -7,6 +7,7 @@ export type AppEvent =
| "minieditor:complete"
| "page:load"
| "editor:init"
| "editor:modeswitch"
| "plugs:loaded";
export type QueryProviderEvent = {

View File

@ -2,13 +2,13 @@ import { findNodeOfType, traverseTree } from "$sb/lib/tree.ts";
import { markdown, space } from "$sb/silverbullet-syscall/mod.ts";
import * as YAML from "yaml";
export async function readYamlPage(
export async function readCodeBlockPage(
pageName: string,
allowedLanguages = ["yaml"],
): Promise<any> {
allowedLanguages?: string[],
): Promise<string | undefined> {
const text = await space.readPage(pageName);
const tree = await markdown.parseMarkdown(text);
let data: any = {};
let codeText: string | undefined;
traverseTree(tree, (t): boolean => {
// Find a fenced code block
@ -16,10 +16,13 @@ export async function readYamlPage(
return false;
}
const codeInfoNode = findNodeOfType(t, "CodeInfo");
if (!codeInfoNode) {
if (allowedLanguages && !codeInfoNode) {
return false;
}
if (!allowedLanguages.includes(codeInfoNode.children![0].text!)) {
if (
allowedLanguages &&
!allowedLanguages.includes(codeInfoNode!.children![0].text!)
) {
return false;
}
const codeTextNode = findNodeOfType(t, "CodeText");
@ -27,17 +30,27 @@ export async function readYamlPage(
// Honestly, this shouldn't happen
return false;
}
const codeText = codeTextNode.children![0].text!;
try {
data = YAML.parse(codeText);
} catch (e: any) {
console.error("YAML Page parser error", e);
throw new Error(`YAML Error: ${e.message}`);
}
codeText = codeTextNode.children![0].text!;
return true;
});
return data;
return codeText;
}
export async function readYamlPage(
pageName: string,
allowedLanguages = ["yaml"],
): Promise<any> {
const codeText = await readCodeBlockPage(pageName, allowedLanguages);
if (codeText === undefined) {
return undefined;
}
try {
return YAML.parse(codeText);
} catch (e: any) {
console.error("YAML Page parser error", e);
throw new Error(`YAML Error: ${e.message}`);
}
}
export async function writeYamlPage(

View File

@ -123,3 +123,8 @@ export function getUiOption(key: string): Promise<any> {
export function setUiOption(key: string, value: any): Promise<void> {
return syscall("editor.setUiOption", key, value);
}
// Vim specific
export function vimEx(exCommand: string): Promise<any> {
return syscall("editor.vimEx", exCommand);
}

View File

@ -22,10 +22,6 @@ functions:
path: "./editor.ts:setEditorMode"
events:
- editor:init
toggleVimMode:
path: "./editor.ts:toggleVimMode"
command:
name: "Editor: Toggle Vim Mode"
toggleDarkMode:
path: "./editor.ts:toggleDarkMode"
command:
@ -432,3 +428,15 @@ functions:
pageNamespace:
pattern: "💭 .+"
operation: getFileMeta
# Vim
toggleVimMode:
path: "./vim.ts:toggleVimMode"
command:
name: "Editor: Toggle Vim Mode"
loadVimRc:
path: "./vim.ts:loadVimRc"
command:
name: "Editor: Vim: Load VIMRC"
events:
- editor:modeswitch

View File

@ -10,13 +10,6 @@ export async function setEditorMode() {
}
}
export async function toggleVimMode() {
let vimMode = await clientStore.get("vimMode");
vimMode = !vimMode;
await editor.setUiOption("vimMode", vimMode);
await clientStore.set("vimMode", vimMode);
}
export async function toggleDarkMode() {
let darkMode = await clientStore.get("darkMode");
darkMode = !darkMode;

34
plugs/core/vim.ts Normal file
View File

@ -0,0 +1,34 @@
import { readCodeBlockPage } from "../../plug-api/lib/yaml_page.ts";
import { clientStore, editor } from "$sb/silverbullet-syscall/mod.ts";
export async function toggleVimMode() {
let vimMode = await clientStore.get("vimMode");
vimMode = !vimMode;
await editor.setUiOption("vimMode", vimMode);
await clientStore.set("vimMode", vimMode);
}
export async function loadVimRc() {
const vimMode = await editor.getUiOption("vimMode");
if (!vimMode) {
console.log("Not in vim mode");
return;
}
try {
const vimRc = await readCodeBlockPage("VIMRC");
if (vimRc) {
console.log("Now running vim ex commands from VIMRC");
const lines = vimRc.split("\n");
for (const line of lines) {
try {
console.log("Running vim ex command", line);
await editor.vimEx(line);
} catch (e: any) {
await editor.flashNotification(e.message, "error");
}
}
}
} catch (e: any) {
// No VIMRC page found
}
}

View File

@ -149,7 +149,6 @@ export class Editor {
// Runtime state (that doesn't make sense in viewState)
collabState?: CollabState;
// enableVimMode = false;
constructor(
space: Space,
@ -332,6 +331,7 @@ export class Editor {
}
});
// Need to find a nicer way of doing this stuff
if (this.builtinSettings.fontFamily) {
document.getElementById("sb-root")!.setAttribute(
"style",
@ -1067,6 +1067,7 @@ export class Editor {
useEffect(() => {
this.rebuildEditorState();
this.dispatchAppEvent("editor:modeswitch");
}, [viewState.uiOptions.vimMode]);
useEffect(() => {

View File

@ -1,5 +1,5 @@
import { Editor } from "../editor.tsx";
import { EditorView, Transaction } from "../deps.ts";
import { EditorView, Transaction, Vim, vimGetCm } from "../deps.ts";
import { SysCallMapping } from "../../plugos/system.ts";
import { FilterOption } from "../../common/types.ts";
@ -164,6 +164,10 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
value,
});
},
"editor.vimEx": (_ctx, exCommand: string) => {
const cm = vimGetCm(editor.editorView!)!;
return Vim.handleEx(cm, exCommand);
},
};
return syscalls;

View File

@ -1,6 +1,10 @@
An attempt at documenting the changes/new features introduced in each
release.
---
## Next
* Syntax highlighting for a bunch of new languages: PgSQL, Rust, CSS, Python, Protobuf, Shell, Swift, toml, XML, JSON, C, C++, Java, C#, Scala, Kotlin, ObjectiveC, ObjectiveC++ and Dart
* [[Vim]] support for VIMRC (see [[Vim]] documentation)
---
## 0.2.9

12
website/Vim.md Normal file
View File

@ -0,0 +1,12 @@
SilverBullet has a basic Vim mode. You can toggle it using the {[Editor: Toggle Vim Mode]} command.
In addition, it supports various ex commands that you can run as you would expect, for instance: `:imap jj <Esc>`.
## VIMRC
SilverBullet also has the ability to load a set of these ex command on boot. To use this functionality, create a page in your space named [[VIMRC]] and put a fenced code block in it (similar to how this is done in [[SETTINGS]]) with one ex command per line, for example:
```
imap jj <Esc>
```
To manually reload your [[VIMRC]] you can use the {[Editor: Vim: Load VIMRC]} command.