mirror of
https://github.com/elisspace/ObsidianTweaks.git
synced 2026-08-29 15:44:02 +00:00
Version 0.2.0
This commit is contained in:
28
README.md
28
README.md
@@ -13,11 +13,21 @@ They are all set to <kbd>Blank</kbd> by default.
|
||||
### Hotkeys
|
||||
| Recommended hotkey | Action |
|
||||
| --- | --- |
|
||||
| <kbd>Alt</kbd> + <kbd>←</kbd> | Move Selection Left |
|
||||
| <kbd>Alt</kbd> + <kbd>→</kbd> | Move Selection Right |
|
||||
| <kbd>Blank</kbd> | Toggle Better Bold (asterisks) |
|
||||
| <kbd>Ctrl</kbd> + <kbd>B</kbd> | Toggle Better Bold (underscores) |
|
||||
| <kbd>Blank</kbd> | Toggle Better Italics (asterisks) |
|
||||
| <kbd>Ctrl</kbd> + <kbd>I</kbd> | Toggle Better Italics (underscores) |
|
||||
| <kbd>Blank</kbd> | Toggle Better Code |
|
||||
| <kbd>CTRL</kbd> + <kbd>/</kbd> | Toggle Better Comment |
|
||||
| <kbd>Blank</kbd> | Toggle Better Highlight |
|
||||
| <kbd>Blank</kbd> | Toggle Better Strikethrough |
|
||||
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>A</kbd> | Select Current Line(s) |
|
||||
| <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>↑</kbd> | Copy Current Line(s) Up |
|
||||
| <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>↓</kbd> | Copy Current Line(s) Down |
|
||||
| <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>←</kbd> | Copy Current Line(s) Left |
|
||||
| <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>→</kbd> | Copy Current Line(s) Right |
|
||||
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>A</kbd> | Select Current Line(s) |
|
||||
| <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>1</kbd> | Toggle Heading - H1 |
|
||||
| <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>2</kbd> | Toggle Heading - H2 |
|
||||
| <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>3</kbd> | Toggle Heading - H3 |
|
||||
@@ -25,6 +35,22 @@ They are all set to <kbd>Blank</kbd> by default.
|
||||
| <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>5</kbd> | Toggle Heading - H5 |
|
||||
| <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>6</kbd> | Toggle Heading - H6 |
|
||||
|
||||
### Move selection
|
||||
|
||||
Move selection does not support going across lines. This seems unnecessary and
|
||||
is really messy to implement.
|
||||
### Better Toggles
|
||||
|
||||
The default toggles in Obsidian can be quite wonky and do not always
|
||||
work well. The toggles implemented here should always return to the
|
||||
same state when toggled twice.
|
||||
|
||||
They also do nice word-wrapping for you.
|
||||
|
||||
Additionally __Bold__ and _Italics_ are implemented with underscores as well
|
||||
as asterisks. Simply bind the command you want.
|
||||
|
||||
Math toggles are also included.
|
||||
## Philosophy
|
||||
|
||||
- By default no features are enabled. You can enable the features you want.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-tweaks",
|
||||
"name": "Obsidian Tweaks",
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"minAppVersion": "0.12.3",
|
||||
"description": "A small plugin that implements some sorely missed features.",
|
||||
"author": "Jeppe Klitgaard",
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
{
|
||||
"name": "obsidian-tweaks",
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"description": "A small plugin that implements some sorely missed features.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "rollup --config rollup.config.js -w",
|
||||
"build": "rollup --config rollup.config.js --environment BUILD:production"
|
||||
},
|
||||
"keywords": ["obsidian"],
|
||||
"keywords": [
|
||||
"obsidian"
|
||||
],
|
||||
"author": "Jeppe Klitgaard",
|
||||
"license": "Unlicense",
|
||||
"devDependencies": {
|
||||
@@ -15,6 +17,8 @@
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-typescript": "^8.2.1",
|
||||
"@types/node": "^14.14.37",
|
||||
"auto": "^10.29.3",
|
||||
"auto-plugin-obsidian": "^0.1.4",
|
||||
"obsidian": "^0.12.0",
|
||||
"rollup": "^2.32.1",
|
||||
"tslib": "^2.2.0",
|
||||
|
||||
93
src/BetterFormatting.ts
Executable file
93
src/BetterFormatting.ts
Executable file
@@ -0,0 +1,93 @@
|
||||
import { App, EditorPosition, MarkdownView, Editor } from "obsidian"
|
||||
import ObsidianTweaksPlugin from "./main"
|
||||
import { Direction } from "./Constants"
|
||||
|
||||
|
||||
export class BetterFormatting {
|
||||
public app: App
|
||||
private plugin: ObsidianTweaksPlugin
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
this.app = app
|
||||
this.plugin = plugin
|
||||
}
|
||||
|
||||
toggleWrapper(symbolStart: string, symbolEnd: string): void {
|
||||
// Principle:
|
||||
// Toggling twice == no-op
|
||||
// This is not trivial to achieve :(
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!activeView) {
|
||||
return
|
||||
}
|
||||
|
||||
const editor = activeView.editor
|
||||
|
||||
let anchor = editor.getCursor("from")
|
||||
let head = editor.getCursor("to")
|
||||
|
||||
let wordStart: EditorPosition
|
||||
let wordEnd: EditorPosition
|
||||
|
||||
wordStart = editor.cm.findWordAt(anchor).anchor
|
||||
wordEnd = editor.cm.findWordAt(head).head
|
||||
|
||||
let textToWrap = editor.getRange(wordStart, wordEnd)
|
||||
|
||||
if (textToWrap.trim() === "") {
|
||||
wordStart = anchor
|
||||
wordEnd = anchor
|
||||
|
||||
let charBefore = editor.getRange(
|
||||
{line: wordStart.line, ch: wordStart.ch - 1},
|
||||
{line: wordStart.line, ch: wordStart.ch},
|
||||
)
|
||||
|
||||
// We should've wrapped a whole word more but CM word selection
|
||||
// is weird.
|
||||
// Let's fix
|
||||
if (charBefore.trim() !== "") {
|
||||
wordStart = editor.cm.findWordAt(
|
||||
{line: wordStart.line, ch: wordStart.ch - 1})
|
||||
.anchor
|
||||
|
||||
}
|
||||
|
||||
// Update textToWrap again
|
||||
textToWrap = editor.getRange(wordStart, wordEnd)
|
||||
|
||||
}
|
||||
|
||||
let alreadyWrapped = (
|
||||
textToWrap.startsWith(symbolStart) &&
|
||||
textToWrap.endsWith(symbolEnd)
|
||||
)
|
||||
|
||||
let newText: string
|
||||
if (alreadyWrapped) {
|
||||
newText = textToWrap.substring(symbolStart.length, textToWrap.length - symbolEnd.length)
|
||||
} else {
|
||||
newText = symbolStart + textToWrap + symbolEnd
|
||||
}
|
||||
|
||||
editor.replaceRange(
|
||||
newText,
|
||||
{line: wordStart.line, ch: wordStart.ch},
|
||||
{line: wordEnd.line, ch: wordEnd.ch},
|
||||
)
|
||||
|
||||
if (alreadyWrapped) {
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: anchor.ch - symbolStart.length},
|
||||
{line: head.line, ch: head.ch - symbolStart.length}
|
||||
)
|
||||
} else {
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: anchor.ch + symbolStart.length},
|
||||
{line: head.line, ch: head.ch + symbolStart.length}
|
||||
)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
8
src/Constants.ts
Executable file
8
src/Constants.ts
Executable file
@@ -0,0 +1,8 @@
|
||||
export const DEBUG_HEAD = "Obsidean Tweaks: "
|
||||
|
||||
export enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
@@ -1,89 +1,85 @@
|
||||
import { App, EditableFileView, Editor, MarkdownView } from "obsidian";
|
||||
import ObsidianTweaksPlugin from "./main";
|
||||
import { DEBUG_HEAD } from "./constants";
|
||||
import { App, MarkdownView } from "obsidian"
|
||||
import ObsidianTweaksPlugin from "main"
|
||||
import { Direction } from "Constants"
|
||||
|
||||
export enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
|
||||
export class DirectionalCopy {
|
||||
public app: App;
|
||||
private plugin: ObsidianTweaksPlugin;
|
||||
public app: App
|
||||
private plugin: ObsidianTweaksPlugin
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
this.app = app
|
||||
this.plugin = plugin
|
||||
}
|
||||
|
||||
directionalCopy(direction: Direction): void {
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!activeView) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
let anchor = activeView.editor.getCursor("from");
|
||||
let head = activeView.editor.getCursor("to");
|
||||
const editor = activeView.editor
|
||||
|
||||
let headLength = activeView.editor.getLine(head.line).length;
|
||||
let anchor = editor.getCursor("from")
|
||||
let head = editor.getCursor("to")
|
||||
|
||||
let textToCopyVertical = activeView.editor.getRange(
|
||||
let headLength = editor.getLine(head.line).length
|
||||
|
||||
let textToCopyVertical = editor.getRange(
|
||||
{line: anchor.line, ch: 0},
|
||||
{line: head.line, ch: headLength}
|
||||
)
|
||||
|
||||
// Copy up
|
||||
if (direction === Direction.Up) {
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
textToCopyVertical + '\n',
|
||||
{line: anchor.line, ch: 0}
|
||||
);
|
||||
activeView.editor.setSelection(
|
||||
)
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: anchor.ch},
|
||||
{line: head.line, ch: head.ch},
|
||||
);
|
||||
)
|
||||
}
|
||||
// Copy down
|
||||
else if (direction === Direction.Down) {
|
||||
let addedLines = head.line - anchor.line;
|
||||
let addedLines = head.line - anchor.line
|
||||
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
'\n' + textToCopyVertical,
|
||||
{line: head.line, ch: headLength}
|
||||
);
|
||||
activeView.editor.setSelection(
|
||||
)
|
||||
editor.setSelection(
|
||||
{line: anchor.line + addedLines + 1, ch: anchor.ch},
|
||||
{line: head.line + addedLines + 1, ch: head.ch},
|
||||
);
|
||||
)
|
||||
}
|
||||
// Copy left
|
||||
else if (direction === Direction.Left) {
|
||||
let textToCopy = activeView.editor.getSelection();
|
||||
let textToCopy = editor.getSelection()
|
||||
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
textToCopy,
|
||||
{line: anchor.line, ch: anchor.ch}
|
||||
);
|
||||
activeView.editor.setSelection(
|
||||
)
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: anchor.ch},
|
||||
{line: head.line, ch: head.ch},
|
||||
);
|
||||
)
|
||||
}
|
||||
// Copy right
|
||||
else if (direction === Direction.Right) {
|
||||
let textToCopy = activeView.editor.getSelection();
|
||||
let textToCopy = editor.getSelection()
|
||||
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
textToCopy,
|
||||
{line: anchor.line, ch: anchor.ch}
|
||||
);
|
||||
)
|
||||
}
|
||||
else {
|
||||
console.log(DEBUG_HEAD + "Something went wrong...");
|
||||
this.plugin.debug("Something went wrong...")
|
||||
}
|
||||
|
||||
return;
|
||||
return
|
||||
}
|
||||
}
|
||||
101
src/DirectionalMove.ts
Executable file
101
src/DirectionalMove.ts
Executable file
@@ -0,0 +1,101 @@
|
||||
import { App, EditorPosition, MarkdownView, Editor } from "obsidian"
|
||||
import ObsidianTweaksPlugin from "./main"
|
||||
import { Direction } from "./Constants"
|
||||
|
||||
|
||||
export class DirectionalMove {
|
||||
public app: App
|
||||
private plugin: ObsidianTweaksPlugin
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
this.app = app
|
||||
this.plugin = plugin
|
||||
}
|
||||
|
||||
directionalMove(direction: Direction): void {
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!activeView) {
|
||||
return
|
||||
}
|
||||
|
||||
// We need to use cm directly to get control of change origins.
|
||||
// In the future Obsidian API will likely include support for this.
|
||||
const editor = activeView.editor.cm
|
||||
|
||||
let selection = editor.getSelection()
|
||||
|
||||
let anchor = editor.getCursor("from")
|
||||
let head = editor.getCursor("to")
|
||||
|
||||
// Move left
|
||||
if (direction === Direction.Left) {
|
||||
if (anchor.ch - 1 < 0) {
|
||||
this.plugin.debug("Moving across lines is not supported.")
|
||||
return
|
||||
}
|
||||
|
||||
let nextChar = editor.getRange(
|
||||
{line: anchor.line, ch: anchor.ch - 1},
|
||||
{line: anchor.line, ch: anchor.ch},
|
||||
)
|
||||
|
||||
editor.replaceRange(
|
||||
nextChar,
|
||||
{line: head.line, ch: head.ch - 1},
|
||||
{line: head.line, ch: head.ch},
|
||||
"+tweakMoveLeft",
|
||||
)
|
||||
|
||||
editor.replaceRange(
|
||||
selection,
|
||||
{line: anchor.line, ch: anchor.ch - 1},
|
||||
{line: head.line, ch: head.ch - 1},
|
||||
"+tweakMoveLeft",
|
||||
)
|
||||
|
||||
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: anchor.ch - 1},
|
||||
{line: head.line, ch: head.ch - 1},
|
||||
{origin: "tweakMoveLeft"},
|
||||
)
|
||||
|
||||
} else if (direction === Direction.Right) {
|
||||
if (head.ch + 1 > editor.getLine(head.line).length) {
|
||||
this.plugin.debug("Moving across lines is not supported.")
|
||||
return
|
||||
}
|
||||
|
||||
let nextChar = editor.getRange(
|
||||
{line: head.line, ch: head.ch},
|
||||
{line: head.line, ch: head.ch + 1},
|
||||
)
|
||||
|
||||
editor.replaceRange(
|
||||
nextChar,
|
||||
{line: anchor.line, ch: anchor.ch},
|
||||
{line: anchor.line, ch: anchor.ch + 1},
|
||||
"+tweakMoveLeft",
|
||||
)
|
||||
|
||||
editor.replaceRange(
|
||||
selection,
|
||||
{line: anchor.line, ch: anchor.ch + 1},
|
||||
{line: head.line, ch: head.ch + 1},
|
||||
"+tweakMoveLeft",
|
||||
)
|
||||
|
||||
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: anchor.ch + 1},
|
||||
{line: head.line, ch: head.ch + 1},
|
||||
{origin: "tweakMoveLeft"},
|
||||
)
|
||||
|
||||
} else {
|
||||
this.plugin.debug("Something went wrong...")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import { App, MarkdownView } from "obsidian";
|
||||
import ObsidianTweaksPlugin from "./main";
|
||||
|
||||
export class SelectLine {
|
||||
public app: App;
|
||||
private plugin: ObsidianTweaksPlugin;
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
selectLine(): void {
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (!activeView) {
|
||||
return;
|
||||
}
|
||||
|
||||
var anchor = activeView.editor.getCursor("from");
|
||||
var head = activeView.editor.getCursor("to");
|
||||
|
||||
var headLength = activeView.editor.getLine(head.line).length;
|
||||
|
||||
// Modifying and passing the EditorPosition objects does not work
|
||||
// reliably.
|
||||
// Use this approach instead.
|
||||
activeView.editor.setSelection(
|
||||
{line: anchor.line, ch: 0},
|
||||
{line: head.line, ch: headLength}
|
||||
)
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
68
src/SelectionHelper.ts
Executable file
68
src/SelectionHelper.ts
Executable file
@@ -0,0 +1,68 @@
|
||||
import { App, MarkdownView } from "obsidian"
|
||||
import ObsidianTweaksPlugin from "./main"
|
||||
|
||||
export class SelectionHelper {
|
||||
public app: App
|
||||
private plugin: ObsidianTweaksPlugin
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
this.app = app
|
||||
this.plugin = plugin
|
||||
}
|
||||
|
||||
selectLine(): void {
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!activeView) {
|
||||
return
|
||||
}
|
||||
|
||||
const editor = activeView.editor
|
||||
|
||||
var anchor = editor.getCursor("from")
|
||||
var head = editor.getCursor("to")
|
||||
|
||||
var headLength = editor.getLine(head.line).length
|
||||
|
||||
// Modifying and passing the EditorPosition objects does not work
|
||||
// reliably.
|
||||
// Use this approach instead.
|
||||
editor.setSelection(
|
||||
{line: anchor.line, ch: 0},
|
||||
{line: head.line, ch: headLength}
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
selectWord(): void {
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!activeView) {
|
||||
return
|
||||
}
|
||||
|
||||
const editor = activeView.editor
|
||||
|
||||
let anchor = editor.getCursor("from")
|
||||
let head = editor.getCursor("to")
|
||||
|
||||
// If next char is a space, we want to grab a whole new word.
|
||||
let nextChar = editor.getRange(
|
||||
head,
|
||||
{line: head.line, ch: head.ch + 1}
|
||||
)
|
||||
|
||||
if (nextChar === " ") {
|
||||
head = {line: head.line, ch: head.ch + 1}
|
||||
}
|
||||
|
||||
let wordStart = editor.cm.findWordAt(anchor).anchor
|
||||
let wordEnd = editor.cm.findWordAt(head).head
|
||||
|
||||
editor.setSelection(
|
||||
{line: wordStart.line, ch: wordStart.ch},
|
||||
{line: wordEnd.line, ch: wordEnd.ch}
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
43
src/Settings.ts
Executable file
43
src/Settings.ts
Executable file
@@ -0,0 +1,43 @@
|
||||
import { App, PluginSettingTab, Setting } from "obsidian"
|
||||
import ObsidianTweaksPlugin from "./main"
|
||||
|
||||
export interface ObsidianTweaksSettings {
|
||||
debug: boolean
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: ObsidianTweaksSettings = {
|
||||
debug: false
|
||||
}
|
||||
|
||||
export class ObsidianTweaksSettingTab extends PluginSettingTab {
|
||||
public app: App
|
||||
private plugin: ObsidianTweaksPlugin
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
super(app, plugin)
|
||||
this.plugin = plugin
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let {containerEl} = this
|
||||
let desc: DocumentFragment
|
||||
|
||||
containerEl.empty()
|
||||
|
||||
containerEl.createEl('h2', {text: 'Obsidian Tweaks'})
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Debug mode")
|
||||
.setDesc("Whether to output debug logging to console")
|
||||
.addToggle(toggle => {
|
||||
toggle
|
||||
.setValue(this.plugin.settings.debug)
|
||||
.onChange(debug => {
|
||||
this.plugin.settings.debug = debug
|
||||
this.plugin.saveSettings()
|
||||
|
||||
this.display()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { App, EditableFileView, Editor, MarkdownView } from "obsidian";
|
||||
import ObsidianTweaksPlugin from "./main";
|
||||
import { App, MarkdownView } from "obsidian"
|
||||
import ObsidianTweaksPlugin from "./main"
|
||||
|
||||
export enum Heading {
|
||||
H1 = 1,
|
||||
@@ -11,12 +11,12 @@ export enum Heading {
|
||||
}
|
||||
|
||||
export class ToggleHeading {
|
||||
public app: App;
|
||||
private plugin: ObsidianTweaksPlugin;
|
||||
public app: App
|
||||
private plugin: ObsidianTweaksPlugin
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
this.app = app
|
||||
this.plugin = plugin
|
||||
}
|
||||
|
||||
toggleHeading(heading: Heading): void {
|
||||
@@ -25,45 +25,47 @@ export class ToggleHeading {
|
||||
// 2: Currently this heading text. Remove the heading.
|
||||
// 3: Currently some other heading. Remove the heading and set this heading.
|
||||
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!activeView) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
var headingText = "#".repeat(heading);
|
||||
var anchor = activeView.editor.getCursor("from");
|
||||
const editor = activeView.editor
|
||||
|
||||
var lineText = activeView.editor.getLine(anchor.line);
|
||||
var headingText = "#".repeat(heading)
|
||||
var anchor = editor.getCursor("from")
|
||||
|
||||
var regex: RegExp = /^((#*) )?.*/;
|
||||
var matches = regex.exec(lineText);
|
||||
var lineText = editor.getLine(anchor.line)
|
||||
|
||||
var regex: RegExp = /^((#*) )?.*/
|
||||
var matches = regex.exec(lineText)
|
||||
|
||||
if (matches[2] !== undefined) {
|
||||
// Some heading
|
||||
if (matches[2] === headingText) {
|
||||
// Option 2
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
'',
|
||||
{line: anchor.line, ch: 0},
|
||||
{line: anchor.line, ch: matches[2].length + 1}
|
||||
)
|
||||
return;
|
||||
return
|
||||
} else {
|
||||
// Option 3
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
headingText + " ",
|
||||
{line: anchor.line, ch: 0},
|
||||
{line: anchor.line, ch: matches[2].length + 1}
|
||||
)
|
||||
return;
|
||||
return
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
activeView.editor.replaceRange(
|
||||
editor.replaceRange(
|
||||
headingText + " ",
|
||||
{line: anchor.line, ch: 0},
|
||||
)
|
||||
return;
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1 +1,8 @@
|
||||
export const DEBUG_HEAD = "Obsidean Tweaks: ";
|
||||
export const DEBUG_HEAD = "Obsidean Tweaks: "
|
||||
|
||||
export enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
217
src/main.ts
217
src/main.ts
@@ -1,141 +1,234 @@
|
||||
import { App, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
||||
import { SelectLine } from 'SelectLine';
|
||||
import { DirectionalCopy, Direction } from 'DirectionalCopy';
|
||||
import { ToggleHeading, Heading } from 'ToggleHeading';
|
||||
|
||||
interface ObsidianTweaksSettings {
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: ObsidianTweaksSettings = {
|
||||
}
|
||||
import { App, Plugin, PluginSettingTab, Setting } from 'obsidian'
|
||||
import { SelectionHelper } from 'SelectionHelper'
|
||||
import { BetterFormatting } from 'BetterFormatting'
|
||||
import { DirectionalMove } from 'DirectionalMove'
|
||||
import { DirectionalCopy } from 'DirectionalCopy'
|
||||
import { ToggleHeading, Heading } from 'ToggleHeading'
|
||||
import { DEBUG_HEAD, Direction } from 'Constants'
|
||||
import { DEFAULT_SETTINGS, ObsidianTweaksSettings, ObsidianTweaksSettingTab} from 'Settings'
|
||||
|
||||
export default class ObsidianTweaksPlugin extends Plugin {
|
||||
public settings: ObsidianTweaksSettings;
|
||||
public settings: ObsidianTweaksSettings
|
||||
|
||||
private selectLine: SelectLine;
|
||||
private directionalCopy: DirectionalCopy;
|
||||
private toggleHeading: ToggleHeading;
|
||||
private selectionHelper: SelectionHelper
|
||||
private betterFormatting: BetterFormatting
|
||||
private directionalMove: DirectionalMove
|
||||
private directionalCopy: DirectionalCopy
|
||||
private toggleHeading: ToggleHeading
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
console.log("Loading Obsidian Tweaks...")
|
||||
await this.loadSettings()
|
||||
|
||||
this.selectLine = new SelectLine(this.app, this);
|
||||
this.directionalCopy = new DirectionalCopy(this.app, this);
|
||||
this.toggleHeading = new ToggleHeading(this.app, this);
|
||||
this.selectionHelper = new SelectionHelper(this.app, this)
|
||||
this.betterFormatting = new BetterFormatting(this.app, this)
|
||||
this.directionalMove = new DirectionalMove(this.app, this)
|
||||
this.directionalCopy = new DirectionalCopy(this.app, this)
|
||||
this.toggleHeading = new ToggleHeading(this.app, this)
|
||||
|
||||
// Select line
|
||||
// SelectionHelper
|
||||
this.addCommand({
|
||||
id: 'select-line',
|
||||
name: 'Select Current Line(s)',
|
||||
callback: () => {
|
||||
this.selectLine.selectLine();
|
||||
this.selectionHelper.selectLine()
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'select-word',
|
||||
name: 'Select Current Word(s)',
|
||||
callback: () => {
|
||||
this.selectionHelper.selectWord()
|
||||
}
|
||||
})
|
||||
|
||||
// Better formatting
|
||||
this.addCommand({
|
||||
id: 'better-formatting-bold-underscore',
|
||||
name: 'Better Toggle Bold (underscores)',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("__", "__")
|
||||
}
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'better-formatting-bold-asterisk',
|
||||
name: 'Better Toggle Bold (asterisks)',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("**", "**")
|
||||
}
|
||||
})
|
||||
|
||||
this.addCommand({
|
||||
id: 'better-formatting-italics-underscore',
|
||||
name: 'Better Toggle Italics (underscore)',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("_", "_")
|
||||
}
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'better-formatting-italics-asterisk',
|
||||
name: 'Better Toggle Italics (asterisk)',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("*", "*")
|
||||
}
|
||||
})
|
||||
|
||||
this.addCommand({
|
||||
id: 'better-formatting-code',
|
||||
name: 'Better Toggle Code',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("`", "`")
|
||||
}
|
||||
})
|
||||
|
||||
this.addCommand({
|
||||
id: 'better-formatting-comment',
|
||||
name: 'Better Toggle Comment',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("%%", "%%")
|
||||
}
|
||||
})
|
||||
|
||||
this.addCommand({
|
||||
id: 'better-formatting-highlight',
|
||||
name: 'Better Toggle Highlight',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("==", "==")
|
||||
}
|
||||
})
|
||||
|
||||
this.addCommand({
|
||||
id: 'better-formatting-strikethrough',
|
||||
name: 'Better Toggle Strikethrough',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("~~", "~~")
|
||||
}
|
||||
})
|
||||
|
||||
this.addCommand({
|
||||
id: 'better-formatting-math-inline',
|
||||
name: 'Better Toggle Math (Inline)',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("$", "$")
|
||||
}
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'better-formatting-math-block',
|
||||
name: 'Better Toggle Math (Block)',
|
||||
callback: () => {
|
||||
this.betterFormatting.toggleWrapper("$$", "$$")
|
||||
}
|
||||
})
|
||||
|
||||
// Directional Move
|
||||
this.addCommand({
|
||||
id: 'move-left',
|
||||
name: 'Move Selection Left',
|
||||
callback: () => {
|
||||
this.directionalMove.directionalMove(Direction.Left)
|
||||
}
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'move-right',
|
||||
name: 'Move Selection Right',
|
||||
callback: () => {
|
||||
this.directionalMove.directionalMove(Direction.Right)
|
||||
}
|
||||
})
|
||||
|
||||
// Directional Copy
|
||||
this.addCommand({
|
||||
id: 'copy-line-up',
|
||||
name: 'Copy Current Line(s) Up',
|
||||
callback: () => {
|
||||
this.directionalCopy.directionalCopy(Direction.Up);
|
||||
this.directionalCopy.directionalCopy(Direction.Up)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'copy-line-down',
|
||||
name: 'Copy Current Line(s) Down',
|
||||
callback: () => {
|
||||
this.directionalCopy.directionalCopy(Direction.Down);
|
||||
this.directionalCopy.directionalCopy(Direction.Down)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'copy-line-left',
|
||||
name: 'Copy Current Line(s) Left',
|
||||
callback: () => {
|
||||
this.directionalCopy.directionalCopy(Direction.Left);
|
||||
this.directionalCopy.directionalCopy(Direction.Left)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'copy-line-right',
|
||||
name: 'Copy Current Line(s) Right',
|
||||
callback: () => {
|
||||
this.directionalCopy.directionalCopy(Direction.Right);
|
||||
this.directionalCopy.directionalCopy(Direction.Right)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Set heading
|
||||
this.addCommand({
|
||||
id: 'toggle-heading-1',
|
||||
name: 'Toggle Heading - H1',
|
||||
callback: () => {
|
||||
this.toggleHeading.toggleHeading(Heading.H1);
|
||||
this.toggleHeading.toggleHeading(Heading.H1)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'toggle-heading-2',
|
||||
name: 'Toggle Heading - H2',
|
||||
callback: () => {
|
||||
this.toggleHeading.toggleHeading(Heading.H2);
|
||||
this.toggleHeading.toggleHeading(Heading.H2)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'toggle-heading-3',
|
||||
name: 'Toggle Heading - H3',
|
||||
callback: () => {
|
||||
this.toggleHeading.toggleHeading(Heading.H3);
|
||||
this.toggleHeading.toggleHeading(Heading.H3)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'toggle-heading-4',
|
||||
name: 'Toggle Heading - H4',
|
||||
callback: () => {
|
||||
this.toggleHeading.toggleHeading(Heading.H4);
|
||||
this.toggleHeading.toggleHeading(Heading.H4)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'toggle-heading-5',
|
||||
name: 'Toggle Heading - H5',
|
||||
callback: () => {
|
||||
this.toggleHeading.toggleHeading(Heading.H5);
|
||||
this.toggleHeading.toggleHeading(Heading.H5)
|
||||
}
|
||||
});
|
||||
})
|
||||
this.addCommand({
|
||||
id: 'toggle-heading-6',
|
||||
name: 'Toggle Heading - H6',
|
||||
callback: () => {
|
||||
this.toggleHeading.toggleHeading(Heading.H6);
|
||||
this.toggleHeading.toggleHeading(Heading.H6)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
this.addSettingTab(new ObsidianTweaksSettingTab(this.app, this))
|
||||
}
|
||||
|
||||
onunload() {
|
||||
console.log("Unloading Obsidian Tweaks...")
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData())
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
await this.saveData(this.settings)
|
||||
}
|
||||
|
||||
debug(str: string) {
|
||||
if (this.settings.debug) {
|
||||
console.log(DEBUG_HEAD + str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SampleSettingTab extends PluginSettingTab {
|
||||
plugin: ObsidianTweaksPlugin;
|
||||
|
||||
constructor(app: App, plugin: ObsidianTweaksPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let {containerEl} = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl('h2', {text: 'Obsidian Tweaks'});
|
||||
|
||||
containerEl.createEl('p', {text: 'Currently nothing here!'});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"0.2.0": "0.12.3",
|
||||
"0.1.1": "0.12.3",
|
||||
"0.1.0": "0.12.3"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user