mirror of
https://github.com/esm7/obsidian-vimrc-support.git
synced 2026-07-22 05:00:25 +00:00
feat: define and expose obsidian-specific vim commands
jumpToNextHeading: g] jumpToPreviousHeading: g[
This commit is contained in:
parent
4657923eb3
commit
ab1a283aa1
3 changed files with 92 additions and 1 deletions
20
main.ts
20
main.ts
|
|
@ -1,5 +1,7 @@
|
|||
import * as keyFromAccelerator from 'keyboardevent-from-electron-accelerator';
|
||||
import { EditorSelection, Notice, App, MarkdownView, Plugin, PluginSettingTab, Setting, TFile } from 'obsidian';
|
||||
import { App, EditorSelection, MarkdownView, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
||||
import { jumpToNextHeading, jumpToPreviousHeading } from './motions/jumpToHeading';
|
||||
import { moveDownSkipFold, moveUpSkipFold } from './motions/moveAndSkipFold';
|
||||
|
||||
declare const CodeMirror: any;
|
||||
|
||||
|
|
@ -257,6 +259,7 @@ export default class VimrcPlugin extends Plugin {
|
|||
var cmEditor = this.getCodeMirror(view);
|
||||
if (cmEditor && !this.codeMirrorVimObject.loadedVimrc) {
|
||||
this.defineBasicCommands(this.codeMirrorVimObject);
|
||||
this.defineObsidianVimMotions(this.codeMirrorVimObject);
|
||||
this.defineSendKeys(this.codeMirrorVimObject);
|
||||
this.defineObCommand(this.codeMirrorVimObject);
|
||||
this.defineSurround(this.codeMirrorVimObject);
|
||||
|
|
@ -367,6 +370,21 @@ export default class VimrcPlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
defineObsidianVimMotions(vimObject: any) {
|
||||
vimObject.defineMotion('jumpToNextHeading', jumpToNextHeading);
|
||||
vimObject.mapCommand('g]', 'motion', 'jumpToNextHeading');
|
||||
|
||||
vimObject.defineMotion('jumpToPreviousHeading', jumpToPreviousHeading);
|
||||
vimObject.mapCommand('g[', 'motion', 'jumpToPreviousHeading');
|
||||
|
||||
vimObject.defineMotion('moveUpSkipFold', moveUpSkipFold);
|
||||
vimObject.mapCommand('zk', 'motion', 'moveUpSkipFold');
|
||||
|
||||
vimObject.defineEx('moveDownSkipFold', moveDownSkipFold);
|
||||
vimObject.mapCommand('zj', 'motion', 'moveDownSkipFold');
|
||||
}
|
||||
|
||||
defineSendKeys(vimObject: any) {
|
||||
vimObject.defineEx('sendkeys', '', async (cm: any, params: any) => {
|
||||
if (!params?.args?.length) {
|
||||
|
|
|
|||
54
motions/jumpToHeading.ts
Normal file
54
motions/jumpToHeading.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { Editor, EditorPosition } from "obsidian";
|
||||
|
||||
export function jumpToNextHeading(
|
||||
cm: Editor,
|
||||
{ line, ch }: EditorPosition,
|
||||
motionArgs: { repeat: number }
|
||||
): EditorPosition {
|
||||
const { repeat } = motionArgs;
|
||||
const noteContent = cm.getValue();
|
||||
const nextContentLines = noteContent.split("\n").slice(line + 1);
|
||||
const nextHeadingIdx =
|
||||
getNthHeadingIndex(nextContentLines, repeat) + line + 1;
|
||||
if (nextHeadingIdx === -1) {
|
||||
return { line, ch };
|
||||
}
|
||||
return { line: nextHeadingIdx, ch: 0 };
|
||||
}
|
||||
|
||||
export function jumpToPreviousHeading(
|
||||
cm: Editor,
|
||||
{ line, ch }: EditorPosition,
|
||||
motionArgs: { repeat: number }
|
||||
): EditorPosition {
|
||||
const { repeat } = motionArgs;
|
||||
const noteContent = cm.getValue();
|
||||
const isAlreadyOnHeading = cm.getLine(line).startsWith("#");
|
||||
const lastIdxToConsider = isAlreadyOnHeading ? line - 1 : line;
|
||||
const previousContentLines = noteContent
|
||||
.split("\n")
|
||||
.slice(0, lastIdxToConsider + 1)
|
||||
.reverse();
|
||||
const previousHeadingIdx = getNthHeadingIndex(previousContentLines, repeat);
|
||||
if (previousHeadingIdx === -1) {
|
||||
return { line, ch };
|
||||
}
|
||||
return { line: lastIdxToConsider - previousHeadingIdx, ch: 0 };
|
||||
}
|
||||
|
||||
function getNthHeadingIndex(contentLines: string[], n: number): number {
|
||||
let numHeadingsFound = 0;
|
||||
let currHeadingIndex = -1;
|
||||
for (let i = 0; i < contentLines.length; i++) {
|
||||
const headingRegex = /^#+ /;
|
||||
if (!headingRegex.test(contentLines[i])) {
|
||||
continue;
|
||||
}
|
||||
currHeadingIndex = i;
|
||||
numHeadingsFound++;
|
||||
if (numHeadingsFound === n) {
|
||||
return currHeadingIndex;
|
||||
}
|
||||
}
|
||||
return currHeadingIndex;
|
||||
}
|
||||
19
motions/moveAndSkipFold.ts
Normal file
19
motions/moveAndSkipFold.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { Editor, EditorPosition } from "obsidian";
|
||||
|
||||
export function moveUpSkipFold(
|
||||
cm: Editor,
|
||||
{ line, ch }: EditorPosition,
|
||||
motionArgs: { repeat: number }
|
||||
): EditorPosition {
|
||||
// TODO: Implement this
|
||||
return { line, ch };
|
||||
}
|
||||
|
||||
export function moveDownSkipFold(
|
||||
cm: Editor,
|
||||
{ line, ch }: EditorPosition,
|
||||
motionArgs: { repeat: number }
|
||||
): EditorPosition {
|
||||
// TODO: Implement this
|
||||
return { line, ch };
|
||||
}
|
||||
Loading…
Reference in a new issue