From 3434a4f145c52a112a077955bca38aa9ab551232 Mon Sep 17 00:00:00 2001 From: Luke Leppan Date: Thu, 24 Feb 2022 15:02:26 +0200 Subject: [PATCH] Fix #35 #32 #33 --- .gitignore | 2 +- README.md | 2 + manifest.json | 2 +- package.json | 14 ++- rollup.config.js | 29 +++++- src/main.ts | 214 +++++++++++++++++++++++++++++------------- src/status/manager.ts | 1 + tsconfig.json | 3 +- 8 files changed, 198 insertions(+), 69 deletions(-) diff --git a/.gitignore b/.gitignore index 10185d8..38fe731 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,5 @@ main.js *.js.map test-vault/ *.zip - +.DS_Store dist/ \ No newline at end of file diff --git a/README.md b/README.md index 1c8647e..f04f39a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/lukeleppan/better-word-count/Build%20Release?logo=github&style=for-the-badge) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/lukeleppan/better-word-count?style=for-the-badge) ![GitHub All Releases](https://img.shields.io/github/downloads/lukeleppan/better-word-count/total?style=for-the-badge) +**IMPORTANT NOTICE:** Due to the introduction of the new Live Preview feature, this plugin needed to be almost entirely rewritten. Currently the plugin only displays the only the word and character count with selecting text features. ALL other features have been scrapped and will be ported in future updates. **DO NOT UPDATE** If you want to use the legacy editor since their is no backwards compatibility yet (I know I'm lazy but I wanted to release the fix, its been too long). + This plugin is the same as the built-in **Word Count** plugin, except when you select text, it will count the selected word instead of the whole document. I recommend turning off the built-in **Word Count** because this plugin is designed to replace that. This plugin also has the ability to store statistics about your vault. ![Better Count Word](https://raw.githubusercontent.com/lukeleppan/better-word-count/master/assets/better-word-count.gif) diff --git a/manifest.json b/manifest.json index 4a1d349..3e3dfbd 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "better-word-count", "name": "Better Word Count", - "version": "0.7.7", + "version": "0.7.8", "description": "Counts the words of selected text in the editor.", "author": "Luke Leppan", "authorUrl": "https://lukeleppan.com", diff --git a/package.json b/package.json index 226df4f..a57e2fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "better-word-count", - "version": "0.7.7", + "version": "0.7.8", "description": "Counts the words of selected text in the editor.", "main": "main.js", "scripts": { @@ -19,6 +19,18 @@ "author": "Luke Leppan", "license": "MIT", "devDependencies": { + "@codemirror/text": "^0.19.6", + "@codemirror/commands": "^0.19.0", + "@codemirror/fold": "0.19.0", + "@codemirror/history": "^0.19.0", + "@codemirror/language": "^0.19.0", + "@codemirror/matchbrackets": "^0.19.0", + "@codemirror/panel": "^0.19.0", + "@codemirror/rangeset": "^0.19.0", + "@codemirror/search": "^0.19.0", + "@codemirror/state": "^0.19.0", + "@codemirror/stream-parser": "^0.19.0", + "@codemirror/view": "^0.19.0", "@rollup/plugin-commonjs": "^15.1.0", "@rollup/plugin-node-resolve": "^9.0.0", "@rollup/plugin-typescript": "^6.0.0", diff --git a/rollup.config.js b/rollup.config.js index eb6d451..1806df4 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -14,7 +14,34 @@ export default { format: 'cjs', exports: 'default' }, - external: ['obsidian'], + external: [ + "obsidian", + "electron", + "codemirror", + "@codemirror/autocomplete", + "@codemirror/closebrackets", + "@codemirror/collab", + "@codemirror/commands", + "@codemirror/comment", + "@codemirror/fold", + "@codemirror/gutter", + "@codemirror/highlight", + "@codemirror/history", + "@codemirror/language", + "@codemirror/lint", + "@codemirror/matchbrackets", + "@codemirror/panel", + "@codemirror/rangeset", + "@codemirror/rectangular-selection", + "@codemirror/search", + "@codemirror/state", + "@codemirror/stream-parser", + "@codemirror/text", + "@codemirror/tooltip", + "@codemirror/view", + "@lezer/common", + "@lezer/lr", + ], plugins: [ typescript(), nodeResolve({ browser: true }), diff --git a/src/main.ts b/src/main.ts index 0a9347b..8e7abca 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,72 +1,89 @@ -import { Plugin, TFile, addIcon, WorkspaceLeaf } from "obsidian"; -import { BetterWordCountSettingsTab } from "./settings/settings-tab"; -import { BetterWordCountSettings, DEFAULT_SETTINGS } from "./settings/settings"; -import { StatusBar } from "./status/bar"; -import { STATS_ICON, STATS_ICON_NAME, VIEW_TYPE_STATS } from "./constants"; +import { Plugin, TFile, addIcon, WorkspaceLeaf, MarkdownEditView, MarkdownView, MarkdownSourceView, editorViewField, editorEditorField, Notice } from "obsidian"; +// import { BetterWordCountSettingsTab } from "./settings/settings-tab"; +// import { BetterWordCountSettings, DEFAULT_SETTINGS } from "./settings/settings"; +// import { StatusBar } from "./status/bar"; +// import { STATS_ICON, STATS_ICON_NAME, VIEW_TYPE_STATS } from "./constants"; // import StatsView from "./view/view"; -import { DataManager } from "./data/manager"; -import { BarManager } from "./status/manager"; -import type CodeMirror from "codemirror"; +// import { DataManager } from "./data/manager"; +// import { BarManager } from "./status/manager"; + +// import {} from "@codemirror/text"; +import {EditorState, StateEffect, StateField, Transaction} from "@codemirror/state"; + +// import type CodeMirror from "codemirror"; +import { Decoration, DecorationSet, EditorView } from "@codemirror/view"; +import { StatusBar } from "./status/bar"; export default class BetterWordCount extends Plugin { - public statusBar: StatusBar; - public currentFile: TFile; - public settings: BetterWordCountSettings; + public static statusBar: StatusBar; + // public currentFile: TFile; + // public settings: BetterWordCountSettings; // public view: StatsView; - public dataManager: DataManager; - public barManager: BarManager; + // public dataManager: DataManager; + // public barManager: BarManager; - onunload(): void { - this.app.workspace - .getLeavesOfType(VIEW_TYPE_STATS) - .forEach((leaf) => leaf.detach()); - } + // onunload(): void { + // this.app.workspace + // .getLeavesOfType(VIEW_TYPE_STATS) + // .forEach((leaf) => leaf.detach()); + // } - async onload() { - this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData()); - this.addSettingTab(new BetterWordCountSettingsTab(this.app, this)); + onload() { + this.createCMExtension(); let statusBarEl = this.addStatusBarItem(); - this.statusBar = new StatusBar(statusBarEl); - this.barManager = new BarManager( - this.statusBar, - this.settings, - this.app.vault, - this.app.metadataCache - ); + BetterWordCount.statusBar = new StatusBar(statusBarEl); - if (this.settings.collectStats) { - this.dataManager = new DataManager( - this.app.vault, - this.app.metadataCache - ); - } + // this.settings = Object.assign(DEFAULT_SETTINGS, await this.loadData()); + // this.addSettingTab(new BetterWordCountSettingsTab(this.app, this)); - this.registerEvent( - this.app.workspace.on("active-leaf-change", this.activeLeafChange, this) - ); + // let statusBarElTest = this.addStatusBarItem(); + // statusBarElTest.setText("§l§aTest§r"); + // let statusBarEl = this.addStatusBarItem(); + // this.statusBar = new StatusBar(statusBarEl); + // this.statusBar.displayText("Awesome"); + // this.barManager = new BarManager( + // this.statusBar, + // this.settings, + // this.app.vault, + // this.app.metadataCache + // ); - this.registerCodeMirror((cm: CodeMirror.Editor) => { - cm.on("cursorActivity", (cm: CodeMirror.Editor) => - this.barManager.cursorActivity(cm) - ); - }); + // if (this.settings.collectStats) { + // this.dataManager = new DataManager( + // this.app.vault, + // this.app.metadataCache + // ); + // } - if (this.settings.collectStats) { - this.registerEvent( - this.app.workspace.on( - "quick-preview", - this.dataManager.debounceChange, - this.dataManager - ) - ); + // this.registerEvent( + // this.app.workspace.on("active-leaf-change", this.activeLeafChange, this) + // ); - this.registerInterval( - window.setInterval(() => { - this.dataManager.setTotalStats(); - }, 1000 * 60) - ); - } + // this.registerCodeMirror((cm: CodeMirror.Editor) => { + // cm.on("cursorActivity", (cm: CodeMirror.Editor) => + // this.barManager.cursorActivity(cm) + // ); + // }); + + + + + // if (this.settings.collectStats) { + // this.registerEvent( + // this.app.workspace.on( + // "quick-preview", + // this.dataManager.debounceChange, + // this.dataManager + // ) + // ); + + // this.registerInterval( + // window.setInterval(() => { + // this.dataManager.setTotalStats(); + // }, 1000 * 60) + // ); + // } // addIcon(STATS_ICON_NAME, STATS_ICON); @@ -93,15 +110,15 @@ export default class BetterWordCount extends Plugin { // } } - activeLeafChange(leaf: WorkspaceLeaf) { - if (!(leaf.view.getViewType() === "markdown")) { - this.barManager.updateAltStatusBar(); - } - } + // activeLeafChange(leaf: WorkspaceLeaf) { + // if (!(leaf.view.getViewType() === "markdown")) { + // this.barManager.updateAltStatusBar(); + // } + // } - async saveSettings(): Promise { - await this.saveData(this.settings); - } + // async saveSettings(): Promise { + // await this.saveData(this.settings); + // } // initLeaf(): void { // if (this.app.workspace.getLeavesOfType(VIEW_TYPE_STATS).length) { @@ -111,4 +128,73 @@ export default class BetterWordCount extends Plugin { // type: VIEW_TYPE_STATS, // }); // } + + + createCMExtension() { + + const cmStateField = StateField.define({ + create(state: EditorState) { + return Decoration.none; + }, + update(effects: DecorationSet, tr: Transaction) { + let text = ""; + const selection = tr.newSelection.main; + if (selection.empty) { + const textIter = tr.newDoc.iter(); + while (!textIter.done) { + text = text + textIter.next().value; + } + } else { + const textIter = tr.newDoc.iterRange(selection.from, selection.to); + while (!textIter.done) { + text = text + textIter.next().value; + } + } + + BetterWordCount.updateStatusBar(text); + + return effects; + }, + + provide: (f: any) => EditorView.decorations.from(f), + }); + + this.registerEditorExtension(cmStateField); + } + + static updateStatusBar(text: string) { + const words = this.getWordCount(text); + const chars = this.getCharacterCount(text); + + this.statusBar.displayText(`${words} words ${chars} characters`); + } + + static getWordCount(text: string): number { + const spaceDelimitedChars = + /A-Za-z\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC/ + .source; + const nonSpaceDelimitedWords = + /\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u4E00-\u9FD5/.source; + + const nonSpaceDelimitedWordsOther = + /[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u4E00-\u9FD5]{1}/ + .source; + + const pattern = new RegExp( + [ + `(?:[0-9]+(?:(?:,|\\.)[0-9]+)*|[\\-${spaceDelimitedChars}])+`, + nonSpaceDelimitedWords, + nonSpaceDelimitedWordsOther, + ].join("|"), + "g" + ); + return (text.match(pattern) || []).length; + } + + static getCharacterCount(text: string): number { + return text.length; + } + + } + diff --git a/src/status/manager.ts b/src/status/manager.ts index 655432e..7695e2e 100644 --- a/src/status/manager.ts +++ b/src/status/manager.ts @@ -148,6 +148,7 @@ export class BarManager { } cursorActivity(cm: CodeMirror.Editor) { + console.log("detected cursor activity"); if (cm.somethingSelected()) { if (this.settings.countComments) { this.deboucer(cleanComments(cm.getSelection())); diff --git a/tsconfig.json b/tsconfig.json index 86fe244..4e80ae2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,7 @@ "importHelpers": true // "lib": ["dom", "es5", "scripthost", "es2015"] }, - "include": ["**/*.ts"], + // "include": ["**/*.ts"], + "include": ["**/main.ts", "**/bar.ts"], "exclude": ["node_modules/*"] }