better-word-count/src/main.ts

137 lines
4 KiB
TypeScript
Raw Normal View History

import { MarkdownView, Plugin, TFile, WorkspaceSidedock } from "obsidian";
import { BetterWordCountSettingsTab } from "./settings/settings-tab";
import { BetterWordCountSettings } from "./settings/settings";
2020-11-09 13:33:44 +00:00
import { StatusBar } from "./status-bar";
export default class BetterWordCount extends Plugin {
public recentlyTyped: boolean;
public statusBar: StatusBar;
2020-11-10 14:23:28 +00:00
public currentFile: TFile;
public settings: BetterWordCountSettings;
2020-11-09 13:33:44 +00:00
async onload() {
2020-11-09 13:33:44 +00:00
let statusBarEl = this.addStatusBarItem();
this.statusBar = new StatusBar(statusBarEl);
this.recentlyTyped = false;
this.settings = (await this.loadData()) || new BetterWordCountSettings();
this.addSettingTab(new BetterWordCountSettingsTab(this.app, this));
2020-11-09 13:33:44 +00:00
this.registerEvent(
this.app.workspace.on("file-open", this.onFileOpen, this)
);
this.registerEvent(
this.app.workspace.on("quick-preview", this.onQuickPreview, this)
);
2020-11-10 14:19:55 +00:00
this.registerInterval(
window.setInterval(async () => {
let activeLeaf = this.app.workspace.activeLeaf;
2020-11-10 14:23:28 +00:00
2020-11-10 14:19:55 +00:00
if (!activeLeaf || !(activeLeaf.view instanceof MarkdownView)) {
return;
}
let editor = activeLeaf.view.sourceMode.cmEditor;
if (editor.somethingSelected()) {
let content: string = editor.getSelection();
this.updateWordCount(content);
this.recentlyTyped = false;
} else if (
2020-11-10 14:23:28 +00:00
this.currentFile &&
this.currentFile.extension === "md" &&
2020-11-10 14:19:55 +00:00
!this.recentlyTyped
) {
2020-11-11 09:32:20 +00:00
const contents = await this.app.vault.cachedRead(this.currentFile);
2020-11-10 14:19:55 +00:00
this.updateWordCount(contents);
} else if (!this.recentlyTyped) {
this.updateWordCount("");
}
}, 500)
);
2020-11-09 13:33:44 +00:00
let activeLeaf = this.app.workspace.activeLeaf;
let files: TFile[] = this.app.vault.getMarkdownFiles();
files.forEach((file) => {
2020-11-11 09:47:44 +00:00
if (file.basename === activeLeaf.getDisplayText()) {
2020-11-09 13:33:44 +00:00
this.onFileOpen(file);
}
});
}
async onFileOpen(file: TFile) {
2020-11-10 14:23:28 +00:00
this.currentFile = file;
2020-11-09 13:33:44 +00:00
if (file && file.extension === "md") {
const contents = await this.app.vault.cachedRead(file);
2020-11-10 14:19:55 +00:00
this.recentlyTyped = true;
2020-11-09 13:33:44 +00:00
this.updateWordCount(contents);
} else {
this.updateWordCount("");
}
}
onQuickPreview(file: TFile, contents: string) {
2020-11-10 14:23:28 +00:00
this.currentFile = file;
2020-11-09 13:33:44 +00:00
const leaf = this.app.workspace.activeLeaf;
2020-11-09 13:33:44 +00:00
if (leaf && leaf.view.getViewType() === "markdown") {
this.recentlyTyped = true;
this.updateWordCount(contents);
}
}
updateWordCount(text: string) {
let words: number = 0;
2020-11-09 13:33:44 +00:00
const matches = text.match(
/[a-zA-Z0-9_\u0392-\u03c9\u00c0-\u00ff\u0600-\u06ff]+|[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/gm
);
if (matches) {
for (let i = 0; i < matches.length; i++) {
if (matches[i].charCodeAt(0) > 19968) {
words += matches[i].length;
} else {
words += 1;
}
}
}
2021-01-19 16:40:22 +00:00
// Thanks to Extract Highlights plugin and AngelusDomini
// Also https://stackoverflow.com/questions/5553410
const sentences: number = (
(text || "").match(
/[^.!?\s][^.!?]*(?:[.!?](?!['"]?\s|$)[^.!?]*)*[.!?]?['"]?(?=\s|$)/gm
) || []
).length;
let displayText: string = "";
if (this.settings.showWords) {
displayText =
displayText +
this.settings.wordsPrefix +
words +
this.settings.wordsSuffix;
}
if (this.settings.showCharacters) {
displayText =
displayText +
this.settings.charactersPrefix +
text.length +
this.settings.charactersSuffix;
}
if (this.settings.showSentences) {
displayText =
displayText +
this.settings.sentencesPrefix +
sentences +
this.settings.sentencesSuffix;
}
this.statusBar.displayText(displayText);
2020-11-09 13:33:44 +00:00
}
}