diff --git a/.gitignore b/.gitignore index 8e5962e..e63219d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ out -node_modules \ No newline at end of file +node_modules +package-lock.json +*.vsix diff --git a/README.md b/README.md index 80251cb..f505a1b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ This is a simple extension that illustrates a number of concepts when it comes t ## Functionality -It's pretty simple open up a `Markdown` file and the status bar will have an auto-updating wordcount in it... +It's pretty simple open up a `Markdown` file and the status bar will have an auto-updating wordcount in it. It also... + +* Counts number of words highlighted +* Offers other counting data such as characters (excluding spaces), sentences (basic full stop counting) and paragraphs + ![Word Count in status bar](images/wordcount.gif) diff --git a/extension.ts b/extension.ts index 41fca5b..1fb178d 100644 --- a/extension.ts +++ b/extension.ts @@ -1,6 +1,6 @@ // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below -import {window, workspace, commands, Disposable, ExtensionContext, StatusBarAlignment, StatusBarItem, TextDocument} from 'vscode'; +import {window, workspace, commands, Disposable, ExtensionContext, StatusBarAlignment, StatusBarItem, TextDocument, Selection} from 'vscode'; // this method is called when your extension is activated. activation is // controlled by the activation events defined in package.json @@ -14,10 +14,32 @@ export function activate(ctx: ExtensionContext) { let wordCounter = new WordCounter(); let controller = new WordCounterController(wordCounter); + // define the command to view the summary of the word count + let summaryCommand = commands.registerCommand('wordcount.viewSummary',() => { + // Get the current text editor + let editor = window.activeTextEditor; + if (!editor) { + return; + } + + let doc = editor.document; + let sel = editor.selection; + let mode = sel == undefined || sel.isEmpty ? "Total" : "Selection" + window.showInformationMessage(` + ${mode}: | + Words: ${wordCounter._getWordCount(doc, sel)} | + Characters (without spaces): ${wordCounter._getCharCount(doc, sel)} | + Sentences: ${wordCounter._getSentenceCount(doc, sel)} | + Paragraphs: ${wordCounter._getParagraphCount(doc, sel)} + `); + }); + + // add to a list of disposables which are disposed when this extension // is deactivated again. ctx.subscriptions.push(controller); ctx.subscriptions.push(wordCounter); + ctx.subscriptions.push(summaryCommand); } export class WordCounter { @@ -29,6 +51,7 @@ export class WordCounter { // Create as needed if (!this._statusBarItem) { this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left); + this._statusBarItem.command = 'wordcount.viewSummary'; } // Get the current text editor @@ -39,26 +62,28 @@ export class WordCounter { } let doc = editor.document; + let sel = editor.selection; // Only update status if an MD file if (doc.languageId === "markdown") { - let wordCount = this._getWordCount(doc); + let wordCount = this._getWordCount(doc, sel); // Update the status bar - this._statusBarItem.text = wordCount !== 1 ? `$(pencil) ${wordCount} Words` : '$(pencil) 1 Word'; + this._statusBarItem.text = sel === undefined || sel.isEmpty ? `${wordCount} Words` : `${wordCount} Selected`; this._statusBarItem.show(); } else { this._statusBarItem.hide(); } } - public _getWordCount(doc: TextDocument): number { - let docContent = doc.getText(); + public _getWordCount(doc: TextDocument, sel?: Selection): number { + let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel); // Parse out unwanted whitespace so the split is accurate docContent = docContent.replace(/(< ([^>]+)<)/g, '').replace(/\s+/g, ' '); docContent = docContent.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); let wordCount = 0; + if (docContent != "") { wordCount = docContent.split(" ").length; } @@ -66,6 +91,50 @@ export class WordCounter { return wordCount; } + //this function counts the number of characters in the main content of the document + public _getCharCount(doc: TextDocument, sel?: Selection): number { + let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel); + + // Parse out unwanted whitespace so the split is accurate + docContent = docContent.replace(/(< ([^>]+)<)/g, '').replace(/\s+/g, ''); + docContent = docContent.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + docContent = docContent.replace(' ', '') + let charCount = 0; + if (docContent != "") { + charCount = docContent.length; + } + + return charCount; + } + + //this function counts the number of sentences across the document by just looking at the number of + // full stops. + public _getSentenceCount(doc: TextDocument, sel?: Selection): number { + let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel); + let sentenceCount = 0; + if (docContent != "") { + sentenceCount = docContent.split(".").length - 1; + } + + return sentenceCount; + } + + //this function counts the number of paragraphs across the document by defining a paragraph as characters split by + // two or more new lines + public _getParagraphCount(doc: TextDocument, sel?: Selection): number { + let docContent = sel === undefined || sel.isEmpty ? doc.getText() : doc.getText(sel); + docContent += "\r\n\r\n" /* Added so trailing newlines at the end of the document + can be factored out regardless if the user inputted it or not. Otherwise, + if the user leaves 2 trailing newlines, the program will split it and add both + sides to the counter. */ + let paragraphCount = 0; + if (docContent != "") { + paragraphCount = docContent.split(/[^\r\n][\r\n]{4}[\s\n\r]*/).length - 1; + } + + return paragraphCount; + } + public dispose() { this._statusBarItem.dispose(); } diff --git a/package.json b/package.json index ab4747c..72a41ff 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,14 @@ "vscode": "0.10.x" }, "main": "./out/extension", + "contributes": { + "commands": [ + { + "command": "wordcount.viewSummary", + "title": "View Word Count Summary" + } + ] + }, "scripts": { "vscode:prepublish": "node ./node_modules/vscode/bin/compile", "compile": "node ./node_modules/vscode/bin/compile -watch -p ./" @@ -35,4 +43,4 @@ "vscode": "0.10.x", "typescript": "^1.6.2" } -} \ No newline at end of file +}