mirror of
https://github.com/jheddings/obsidian-stomp.git
synced 2026-07-22 06:44:59 +00:00
Co-authored-by: Renovate Bot <renovate@whitesourcesoftware.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
129 lines
3.4 KiB
TypeScript
129 lines
3.4 KiB
TypeScript
import { MarkdownPreviewView, MarkdownView, Plugin } from "obsidian";
|
|
import { StompSettingsTab } from "./settings";
|
|
import { Logger, LogLevel, PluginConfig } from "obskit";
|
|
import { SCROLL_COMMANDS, ScrollController } from "./controller";
|
|
import { findBindingByKey, StompPluginSettings } from "./config";
|
|
|
|
const DEFAULT_SETTINGS: StompPluginSettings = {
|
|
logLevel: LogLevel.ERROR,
|
|
commandBindings: [],
|
|
|
|
pageScrollSettings: {
|
|
scrollDuration: 0.25,
|
|
scrollAmount: 50,
|
|
},
|
|
|
|
quickScrollSettings: {
|
|
scrollDuration: 0.1,
|
|
scrollAmount: 95,
|
|
},
|
|
|
|
sectionScrollSettings: {
|
|
scrollDuration: 0.5,
|
|
edgeInset: 0,
|
|
stopAtH1: true,
|
|
stopAtH2: true,
|
|
stopAtHR: true,
|
|
stopAtCustom: [],
|
|
},
|
|
|
|
autoScrollSettings: {
|
|
scrollSpeed: 100, // pixels per second
|
|
},
|
|
};
|
|
|
|
const config = new PluginConfig<StompPluginSettings>({
|
|
defaults: DEFAULT_SETTINGS,
|
|
migrations: [
|
|
// v0 → v1: rename edge scroll command IDs
|
|
(data) => {
|
|
const renames: Record<string, string> = {
|
|
"stomp-edge-scroll-up": "stomp-edge-scroll-top",
|
|
"stomp-edge-scroll-down": "stomp-edge-scroll-bottom",
|
|
};
|
|
|
|
const bindings = (data.commandBindings ?? []) as Array<{ commandId: string }>;
|
|
for (const binding of bindings) {
|
|
if (binding.commandId in renames) {
|
|
binding.commandId = renames[binding.commandId];
|
|
}
|
|
}
|
|
},
|
|
],
|
|
});
|
|
|
|
export default class StompPlugin extends Plugin {
|
|
settings!: StompPluginSettings;
|
|
|
|
private controller!: ScrollController;
|
|
|
|
private logger: Logger = Logger.getLogger("main");
|
|
|
|
async onload() {
|
|
await this.loadSettings();
|
|
|
|
this.addSettingTab(new StompSettingsTab(this.app, this));
|
|
|
|
SCROLL_COMMANDS.forEach((c) => {
|
|
this.addCommand({
|
|
id: c.id,
|
|
name: c.name,
|
|
callback: () => void this.controller.executeCommand(c.id),
|
|
});
|
|
});
|
|
|
|
this.registerDomEvent(activeDocument, "keydown", this.handleKeyDown, { capture: true });
|
|
|
|
this.logger.info("Plugin loaded");
|
|
}
|
|
|
|
onunload() {
|
|
this.logger.info("Plugin unloaded");
|
|
}
|
|
|
|
async loadSettings() {
|
|
this.settings = await config.load(this);
|
|
|
|
this.applySettings();
|
|
}
|
|
|
|
async saveSettings() {
|
|
await config.save(this, this.settings);
|
|
|
|
this.applySettings();
|
|
}
|
|
|
|
private applySettings() {
|
|
Logger.setGlobalLogLevel(this.settings.logLevel);
|
|
|
|
this.controller = new ScrollController(this.app, this.settings);
|
|
}
|
|
|
|
private handleKeyDown = (evt: KeyboardEvent) => {
|
|
if (!this.hasActiveView()) {
|
|
return true;
|
|
}
|
|
|
|
this.logger.debug(`Received key event: ${evt.key}`);
|
|
|
|
const binding = findBindingByKey(this.settings, evt.key);
|
|
|
|
if (!binding) {
|
|
return true;
|
|
}
|
|
|
|
evt.preventDefault();
|
|
evt.stopPropagation();
|
|
evt.stopImmediatePropagation();
|
|
|
|
this.logger.debug(`Processing key binding [${evt.key}] : ${binding.commandId}`);
|
|
void this.controller.executeCommand(binding.commandId);
|
|
|
|
return false;
|
|
};
|
|
|
|
hasActiveView(): boolean {
|
|
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
|
return activeView !== null && activeView.currentMode instanceof MarkdownPreviewView;
|
|
}
|
|
}
|