mirror of
https://github.com/talwrii/plugin-repl.git
synced 2026-07-22 11:40:27 +00:00
various - add jump method. Change selection behaviour
This commit is contained in:
parent
aab00fb213
commit
a101c2aff9
3 changed files with 121 additions and 21 deletions
21
README.md
21
README.md
|
|
@ -79,6 +79,7 @@ Various convenience functions are provided:
|
|||
* `mark()` - Return the cursor position at the beginning of the selection
|
||||
* `pointMin()` - Return the minimum cursor in the buffer
|
||||
* `pointMax()` - Return the maximun cursor in the buffer
|
||||
* `jump(p: CursorPoint)` - Jump to this point
|
||||
* `forwardChar(count?: number)` - Move count (or one) character forward
|
||||
* `selection()` - Get the text contained in the selection
|
||||
|
||||
|
|
@ -165,6 +166,26 @@ dv = getDv()
|
|||
dv.pages().filter((x) => x.file.path == "templates/daily.md")[0].file.lists[0]
|
||||
```
|
||||
|
||||
## Templater support
|
||||
The [Templater](https://github.com/SilentVoid13/Templater) provides functionality to insert javascript. If you have installed Templater you can use
|
||||
the async `templater_expand` function to expand template strings.
|
||||
|
||||
This creates a command that inserts a files tags using a template.
|
||||
```
|
||||
newCommand(async function templater_example() {
|
||||
insert(await templater_expand("The files tags: <% tp.file.tags %>"))
|
||||
})
|
||||
```
|
||||
|
||||
If you want to expand a template for a file you can use `readFile`
|
||||
|
||||
```
|
||||
newCommand(async function templater_from_file() {
|
||||
insert(await templater_expand(await readFile("myTemplate")))
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
## Importing modules
|
||||
Modules in Obsidian work in an interesting way that makes installing from NPM a little tricky. There is a [technical explanation here](https://github.com/talwrii/plugin-repl-imports#technical).
|
||||
|
||||
|
|
|
|||
70
main.ts
70
main.ts
|
|
@ -3,8 +3,8 @@ import {
|
|||
MarkdownPostProcessorContext, Command
|
||||
} from 'obsidian';
|
||||
|
||||
import { execFileSync } from 'child_process'
|
||||
import { parse as shellParse } from 'shell-quote';
|
||||
import { execFileSync, execSync } from 'child_process'
|
||||
import { parse as shellParse, quote as shellQuote } from 'shell-quote';
|
||||
import { expandRegionWithRegexp } from './editorUtils'
|
||||
|
||||
|
||||
|
|
@ -22,6 +22,7 @@ import { promptString } from './prompt'
|
|||
import { promptCommand } from './promptCommand'
|
||||
import { popup } from './popup'
|
||||
import { openSetting } from './settings'
|
||||
import { templater_expand } from './templater'
|
||||
|
||||
|
||||
export default class ReplPlugin extends Plugin {
|
||||
|
|
@ -102,10 +103,15 @@ export default class ReplPlugin extends Plugin {
|
|||
}
|
||||
|
||||
updateScopeApp() {
|
||||
let path = this.app.workspace.getLeaf().view.path
|
||||
this.scope.add("repl", this)
|
||||
// @ts-ignore path does exist
|
||||
let path = this.app.workspace.getLeaf().view.path
|
||||
// @ts-ignore
|
||||
let frontmatter = this.app.metadataCache.getFileCache(this.app.workspace.getLeaf().view.file)["frontmatter"]
|
||||
|
||||
this.scope.add("repl", this)
|
||||
this.scope.add("path", path)
|
||||
|
||||
this.scope.add("frontmatter", frontmatter)
|
||||
//@ts-ignore
|
||||
let vaultPath = this.app.vault.adapter.basePath
|
||||
this.scope.add("vaultPath", vaultPath)
|
||||
|
|
@ -153,7 +159,7 @@ export default class ReplPlugin extends Plugin {
|
|||
)
|
||||
this.addToScopeWithDoc(
|
||||
"runProc", runProc,
|
||||
"(s: string) or (['prog', 'arg1', 'args2']) run a program and return its output"
|
||||
"(s: string) or (['prog', 'arg1', 'args2']) run a program and return its output. To send "
|
||||
)
|
||||
this.addToScopeWithDoc(
|
||||
"newCommand", this.makeNewCommand(),
|
||||
|
|
@ -194,11 +200,6 @@ export default class ReplPlugin extends Plugin {
|
|||
"(title: string, content: string) Add the content to the note with a titel"
|
||||
)
|
||||
|
||||
this.addToScopeWithDoc(
|
||||
"getDv", getDv.bind(null, this.app),
|
||||
"Get hold of the dataview object for querying pages"
|
||||
|
||||
)
|
||||
this.addToScopeWithDoc(
|
||||
"message", message,
|
||||
"(msg: string) Popup a message with a notification message msg"
|
||||
|
|
@ -216,6 +217,17 @@ export default class ReplPlugin extends Plugin {
|
|||
"openUrl", openUrl,
|
||||
"(url: string) Open this url in a browser "
|
||||
)
|
||||
|
||||
|
||||
this.addToScopeWithDoc(
|
||||
"getDv", getDv.bind(null, this.app),
|
||||
"Get hold of the dataview object for querying pages"
|
||||
)
|
||||
this.addToScopeWithDoc(
|
||||
"templater_expand", templater_expand.bind(null, this.app),
|
||||
"If templater is installed, expand the templater string and return the result."
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
updateScopeEditor(editor: Editor, view: MarkdownView) {
|
||||
|
|
@ -268,6 +280,10 @@ export default class ReplPlugin extends Plugin {
|
|||
"pointMax", pointMax.bind(null, editor),
|
||||
"Returns the cursor positoin at the beginning of the note"
|
||||
)
|
||||
this.addToScopeWithDoc(
|
||||
"jump", jump.bind(null, editor),
|
||||
"Jump to the given point."
|
||||
)
|
||||
this.addToScopeWithDoc(
|
||||
"selection", selection.bind(null, editor),
|
||||
"Returns the text of the selection."
|
||||
|
|
@ -290,13 +306,18 @@ export default class ReplPlugin extends Plugin {
|
|||
makeNewCommand() {
|
||||
const plugin = this
|
||||
function newCommand(f: any) {
|
||||
let commandName = f.name.replaceAll("_", " ")
|
||||
plugin.addCommand({
|
||||
id: f.name,
|
||||
name: f.name.replaceAll("_", " "),
|
||||
name: commandName,
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
plugin.updateScopeApp()
|
||||
plugin.updateScopeEditor(editor, view)
|
||||
plugin.scope.run(f)
|
||||
try {
|
||||
plugin.scope.run(f)
|
||||
} catch (e) {
|
||||
message(`${commandName} failed: ${e.message}`)
|
||||
}
|
||||
}
|
||||
});
|
||||
return f
|
||||
|
|
@ -361,21 +382,27 @@ export default class ReplPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
function openFile(app: any, name: string) {
|
||||
app.workspace.openLinkText(name)
|
||||
async function openFile(app: any, name: string) {
|
||||
await app.workspace.openLinkText(name)
|
||||
}
|
||||
|
||||
function plugin(app: any, name: string) {
|
||||
return app.plugins.plugins[name]
|
||||
}
|
||||
|
||||
function runProc(commandAndArgs: string | Array<string>): string {
|
||||
function runProc(commandAndArgs: string | Array<string>, input?: string): string {
|
||||
if (typeof commandAndArgs === "string") {
|
||||
const command = shellParse(commandAndArgs) as string[]
|
||||
return runProc(command)
|
||||
return runProc(command, input)
|
||||
}
|
||||
|
||||
if (input == undefined) {
|
||||
const [command, ...args] = commandAndArgs
|
||||
return execFileSync(command, args).toString()
|
||||
} else {
|
||||
let quoted = shellQuote(commandAndArgs)
|
||||
return execSync(quoted, { input: input }).toString()
|
||||
}
|
||||
const [command, ...args] = commandAndArgs
|
||||
return execFileSync(command, args).toString()
|
||||
}
|
||||
|
||||
function dir(obj: any) {
|
||||
|
|
@ -407,9 +434,6 @@ function lineAtPoint(editor: Editor) {
|
|||
|
||||
function selection(editor: Editor) {
|
||||
const selection = editor.getSelection()
|
||||
if (selection === "") {
|
||||
throw Error("No text is selected")
|
||||
}
|
||||
return selection
|
||||
}
|
||||
|
||||
|
|
@ -493,6 +517,10 @@ function pointMax(editor: Editor) {
|
|||
return { line: lastLine, ch: lastChar }
|
||||
}
|
||||
|
||||
function jump(editor: Editor, position: EditorPosition) {
|
||||
return editor.setCursor(position)
|
||||
}
|
||||
|
||||
function pointMin(): EditorPosition {
|
||||
return { line: 0, ch: 0 }
|
||||
}
|
||||
|
|
|
|||
51
popup.ts
Normal file
51
popup.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { App, Editor, Modal, Setting } from 'obsidian'
|
||||
|
||||
export function popup(app: App, editor: Editor, message: string): Promise<void> {
|
||||
const position = editor.getCursor()
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
try {
|
||||
new Popup(app, message, resolve).open()
|
||||
editor.setCursor(position)
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export class Popup extends Modal {
|
||||
constructor(app: App, msg: string, resolve: () => void) {
|
||||
super(app);
|
||||
|
||||
const el = new DocumentFragment()
|
||||
const pre = el.createEl("pre")
|
||||
pre.appendText(msg)
|
||||
|
||||
this.setContent(el)
|
||||
new Setting(this.contentEl).addButton((btn) => {
|
||||
btn.setButtonText("OK")
|
||||
|
||||
const popup = this
|
||||
|
||||
let keyDown = false;
|
||||
function done() {
|
||||
popup.close()
|
||||
resolve()
|
||||
return true
|
||||
}
|
||||
|
||||
btn.buttonEl.addEventListener("keydown", (_) => {
|
||||
keyDown = true
|
||||
})
|
||||
|
||||
btn.buttonEl.addEventListener('click', (_) => {
|
||||
return done()
|
||||
})
|
||||
|
||||
btn.buttonEl.addEventListener("keyup", (_) => {
|
||||
if (keyDown) {
|
||||
return done()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue