mirror of
https://github.com/white7292/obsidian-hd-unfilled-stats-highlighter.git
synced 2026-07-22 04:34:38 +00:00
Initial commit. v0.0.1
This commit is contained in:
parent
0b5e5a2f6e
commit
2fc6645f04
3 changed files with 3890 additions and 100 deletions
207
main.ts
207
main.ts
|
|
@ -1,89 +1,99 @@
|
|||
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
||||
import { App, MarkdownView, Plugin, PluginSettingTab, Setting } from "obsidian";
|
||||
|
||||
// Remember to rename these classes and interfaces!
|
||||
|
||||
interface MyPluginSettings {
|
||||
mySetting: string;
|
||||
interface EmptyStatsHighlighterSettings {
|
||||
unfilledStatPrefix: string;
|
||||
templatesDirectory: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: MyPluginSettings = {
|
||||
mySetting: 'default'
|
||||
}
|
||||
const DEFAULT_SETTINGS: EmptyStatsHighlighterSettings = {
|
||||
unfilledStatPrefix: "==",
|
||||
templatesDirectory: "Templates",
|
||||
};
|
||||
|
||||
export default class MyPlugin extends Plugin {
|
||||
settings: MyPluginSettings;
|
||||
export default class EmptyStatsHighlighter extends Plugin {
|
||||
settings: EmptyStatsHighlighterSettings;
|
||||
|
||||
// Runs whenever the user starts using the plugin in Obsidian.
|
||||
// This is where you'll configure most of the plugin's capabilities.
|
||||
// This function is also called when the plugin is updated.
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
// This creates an icon in the left ribbon.
|
||||
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
|
||||
// Called when the user clicks the icon.
|
||||
new Notice('This is a notice!');
|
||||
});
|
||||
// Perform additional things with the ribbon
|
||||
ribbonIconEl.addClass('my-plugin-ribbon-class');
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new SettingsTab(this.app, this));
|
||||
|
||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||
const statusBarItemEl = this.addStatusBarItem();
|
||||
statusBarItemEl.setText('Status Bar Text');
|
||||
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
this.registerDomEvent(document, "click", (evt: MouseEvent) => {
|
||||
// console.log("click", evt);
|
||||
|
||||
// This adds a simple command that can be triggered anywhere
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal-simple',
|
||||
name: 'Open sample modal (simple)',
|
||||
callback: () => {
|
||||
new SampleModal(this.app).open();
|
||||
}
|
||||
});
|
||||
// This adds an editor command that can perform some operation on the current editor instance
|
||||
this.addCommand({
|
||||
id: 'sample-editor-command',
|
||||
name: 'Sample editor command',
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
console.log(editor.getSelection());
|
||||
editor.replaceSelection('Sample Editor Command');
|
||||
}
|
||||
});
|
||||
// This adds a complex command that can check whether the current state of the app allows execution of the command
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal-complex',
|
||||
name: 'Open sample modal (complex)',
|
||||
checkCallback: (checking: boolean) => {
|
||||
// Conditions to check
|
||||
const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (markdownView) {
|
||||
// If checking is true, we're simply "checking" if the command can be run.
|
||||
// If checking is false, then we want to actually perform the operation.
|
||||
if (!checking) {
|
||||
new SampleModal(this.app).open();
|
||||
const activeFile = this.app.workspace.getActiveFile();
|
||||
|
||||
if (
|
||||
!activeFile?.path.contains(
|
||||
`${this.settings.templatesDirectory}/`
|
||||
)
|
||||
) {
|
||||
const view =
|
||||
this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
|
||||
// Make sure the user is editing a Markdown file.
|
||||
if (view) {
|
||||
const editor = view.editor;
|
||||
if (editor) {
|
||||
for (let i = 0; i < editor.lineCount(); i++) {
|
||||
const line = editor.getLine(i);
|
||||
|
||||
if (
|
||||
!line.startsWith(
|
||||
this.settings.unfilledStatPrefix
|
||||
) &&
|
||||
line.match("^.*\\: $")
|
||||
) {
|
||||
editor.setLine(
|
||||
i,
|
||||
`${this.settings.unfilledStatPrefix}${line}`
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
line.startsWith(
|
||||
this.settings.unfilledStatPrefix
|
||||
) &&
|
||||
!line.match("^.*\\: $")
|
||||
) {
|
||||
editor.setLine(
|
||||
i,
|
||||
line.substring(
|
||||
this.settings.unfilledStatPrefix.length
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This command will only show up in Command Palette when the check function returns true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
|
||||
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
console.log('click', evt);
|
||||
});
|
||||
|
||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
this.registerInterval(
|
||||
window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000)
|
||||
);
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
||||
}
|
||||
// Runs when the plugin is disabled.
|
||||
// Any resources that your plugin is using must be released here to avoid
|
||||
// affecting the performance of Obsidian after your plugin has been disabled.
|
||||
onunload() {}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
this.settings = Object.assign(
|
||||
{},
|
||||
DEFAULT_SETTINGS,
|
||||
await this.loadData()
|
||||
);
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
|
|
@ -91,47 +101,54 @@ export default class MyPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
class SampleModal extends Modal {
|
||||
constructor(app: App) {
|
||||
super(app);
|
||||
}
|
||||
class SettingsTab extends PluginSettingTab {
|
||||
plugin: EmptyStatsHighlighter;
|
||||
|
||||
onOpen() {
|
||||
const {contentEl} = this;
|
||||
contentEl.setText('Woah!');
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const {contentEl} = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
||||
class SampleSettingTab extends PluginSettingTab {
|
||||
plugin: MyPlugin;
|
||||
|
||||
constructor(app: App, plugin: MyPlugin) {
|
||||
constructor(app: App, plugin: EmptyStatsHighlighter) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
const {containerEl} = this;
|
||||
const { containerEl } = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl('h2', {text: 'Settings for my awesome plugin.'});
|
||||
containerEl.createEl("h2", {
|
||||
text: "Empty Stats Highlighter Settings",
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Setting #1')
|
||||
.setDesc('It\'s a secret')
|
||||
.addText(text => text
|
||||
.setPlaceholder('Enter your secret')
|
||||
.setValue(this.plugin.settings.mySetting)
|
||||
.onChange(async (value) => {
|
||||
console.log('Secret: ' + value);
|
||||
this.plugin.settings.mySetting = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
.setName("Unfilled Stat Prefix")
|
||||
.setDesc("Prefixes stats that haven't been filled out yet.")
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("Prefix")
|
||||
.setValue(this.plugin.settings.unfilledStatPrefix)
|
||||
.onChange(async (value) => {
|
||||
// const oldPrefix =
|
||||
// this.plugin.settings.unfilledStatPrefix;
|
||||
|
||||
this.plugin.settings.unfilledStatPrefix = value;
|
||||
await this.plugin.saveSettings();
|
||||
|
||||
// TODO: Remove old prefixes.
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Templates Directory Name")
|
||||
.setDesc(
|
||||
"The folder that contains your templates (we won't highlight files here)."
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("Directory")
|
||||
.setValue(this.plugin.settings.templatesDirectory)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.templatesDirectory = value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"id": "obsidian-sample-plugin",
|
||||
"name": "Sample Plugin",
|
||||
"version": "1.0.0",
|
||||
"id": "obsidian-hd-empty-stats-highlighter",
|
||||
"name": "Empty Stats Highlighter",
|
||||
"version": "0.0.1",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",
|
||||
"author": "Obsidian",
|
||||
"description": "The Unfilled Stats Highlighter is a practical Obsidian plugin designed to streamline your stat/habit tracking process by automatically identifying and prefixing unfilled stats, making them easier to spot and fill out. This plugin is perfect for users who frequently work with templates and require a quick and easy way to locate and complete missing information.",
|
||||
"author": "HynesDevelopment",
|
||||
"authorUrl": "https://obsidian.md",
|
||||
"fundingUrl": "https://obsidian.md/pricing",
|
||||
"isDesktopOnly": false
|
||||
|
|
|
|||
3773
package-lock.json
generated
Normal file
3773
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue