Fixes #319
parent
53bf098579
commit
e7728c2d2a
|
@ -7,6 +7,7 @@ export type AppEvent =
|
|||
| "minieditor:complete"
|
||||
| "page:load"
|
||||
| "editor:init"
|
||||
| "editor:modeswitch"
|
||||
| "plugs:loaded";
|
||||
|
||||
export type QueryProviderEvent = {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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(() => {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue