mirror of
https://gitlab.com/aviortheking/code-stats-vscode.git
synced 2025-06-07 15:59:54 +00:00
Change detection and tracking.
This commit is contained in:
parent
69f89cc4c4
commit
cb048907f3
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
out
|
||||
node_modules
|
||||
node_modules
|
||||
.vscode-test/
|
||||
|
@ -11,14 +11,11 @@
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:codestats.sayHello"
|
||||
"*"
|
||||
],
|
||||
"main": "./out/src/code-stats",
|
||||
"contributes": {
|
||||
"commands": [{
|
||||
"command": "codestats.sayHello",
|
||||
"title": "Code::Stats"
|
||||
}]
|
||||
"commands": []
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "tsc -p ./",
|
||||
|
@ -1,34 +1,17 @@
|
||||
"use strict";
|
||||
// the module 'vscode' contains the VS Code extensibility API
|
||||
// import the module and reference it with the alias vscode in your code below
|
||||
import * as vscode from "vscode";
|
||||
import { ExtensionContext } from "vscode";
|
||||
import { XpCounter } from "./xp-counter";
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
export function activate(context: ExtensionContext): void {
|
||||
console.log("Activating code-stats-vscode");
|
||||
|
||||
// use the console to output diagnostic information (console.log) and errors (console.error)
|
||||
// this line of code will only be executed once when your extension is activated
|
||||
console.log("Congratulations, your extension \"code-stats-vscode\" is now active!");
|
||||
let controller: XpCounter = new XpCounter();
|
||||
|
||||
// the command has been defined in the package.json file
|
||||
// now provide the implementation of the command with registerCommand
|
||||
// the commandId parameter must match the command field in package.json
|
||||
let disposable: vscode.Disposable = vscode.commands.registerCommand("codestats.sayHello", () => {
|
||||
var editor: vscode.TextEditor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selection: vscode.Selection = editor.selection;
|
||||
var text: string = editor.document.getText(selection);
|
||||
|
||||
vscode.window.showInformationMessage("Selected characters: " + text.length);
|
||||
});
|
||||
|
||||
context.subscriptions.push(disposable);
|
||||
// add to a list of disposables which are disposed when this extension is deactivated.
|
||||
context.subscriptions.push(controller);
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
export function deactivate() {
|
||||
}
|
||||
export function deactivate(): void {
|
||||
console.log("Deactivating code-stats-vscode");
|
||||
}
|
||||
|
28
src/pulse.ts
Normal file
28
src/pulse.ts
Normal file
@ -0,0 +1,28 @@
|
||||
export class Pulse {
|
||||
xps: Map < string, number > ;
|
||||
|
||||
constructor() {
|
||||
console.log("Creating Pulse");
|
||||
this.xps = new Map < string, number > ();
|
||||
}
|
||||
|
||||
public getXP(language: string): number {
|
||||
let xp: number = this.xps.get(language);
|
||||
|
||||
if (xp === null || xp === undefined) {
|
||||
return 0;
|
||||
} else {
|
||||
return xp;
|
||||
}
|
||||
}
|
||||
|
||||
public addXP(language: string, amount: number): void {
|
||||
let xp: number = this.getXP(language);
|
||||
|
||||
xp += amount;
|
||||
|
||||
this.xps.set(language, xp);
|
||||
|
||||
// console.log(`Added ${amount} of XP to ${language}, total is now ${xp}`);
|
||||
}
|
||||
}
|
20
src/utils.ts
Normal file
20
src/utils.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// converted to ts from https://github.com/Nicd/code-stats-atom/blob/master/lib/utils.js
|
||||
export function getISOTimestamp(date: Date): string {
|
||||
const offset: number = -date.getTimezoneOffset();
|
||||
const prefix: string = (offset >= 0) ? "+" : "-";
|
||||
|
||||
function pad(num: number): string {
|
||||
const norm: number = Math.abs(Math.floor(num));
|
||||
|
||||
return ((norm < 10) ? "0" : "") + norm;
|
||||
}
|
||||
|
||||
return date.getFullYear() +
|
||||
"-" + pad(date.getMonth() + 1) +
|
||||
"-" + pad(date.getDate()) +
|
||||
"T" + pad(date.getHours()) +
|
||||
":" + pad(date.getMinutes()) +
|
||||
":" + pad(date.getSeconds()) +
|
||||
prefix + pad(offset / 60) +
|
||||
pad(offset % 60);
|
||||
}
|
72
src/xp-counter.ts
Normal file
72
src/xp-counter.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { Disposable, workspace, window, StatusBarItem, TextDocument, StatusBarAlignment, TextDocumentChangeEvent, Range } from "vscode";
|
||||
import { Pulse } from "./pulse";
|
||||
|
||||
export class XpCounter {
|
||||
private combinedDisposable: Disposable;
|
||||
private statusBarItem: StatusBarItem;
|
||||
private pulse: Pulse;
|
||||
private languages: Array<string> = ["typescript", "javascript"];
|
||||
private changeCount: number = 0;
|
||||
|
||||
constructor() {
|
||||
console.log(`Supported languages for Code::Stats are ${this.languages}`);
|
||||
this.pulse = new Pulse();
|
||||
|
||||
if (!this.statusBarItem) {
|
||||
this.statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
|
||||
}
|
||||
|
||||
let subscriptions: Disposable[] = [];
|
||||
workspace.onDidChangeTextDocument(this.onTextDocumentChanged, this, subscriptions);
|
||||
this.combinedDisposable = Disposable.from(...subscriptions);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.combinedDisposable.dispose();
|
||||
this.statusBarItem.dispose();
|
||||
}
|
||||
|
||||
private onTextDocumentChanged(event: TextDocumentChangeEvent): void {
|
||||
let changeCount: number = 0;
|
||||
for (let change of event.contentChanges) {
|
||||
changeCount += this.determineChangeCount(change.range);
|
||||
}
|
||||
this.updateXpCount(event.document, changeCount);
|
||||
}
|
||||
|
||||
private determineChangeCount(range: Range): number {
|
||||
if (range === null || range === undefined ) {
|
||||
return 0;
|
||||
}
|
||||
// console.log(`L${range.start.line}C${range.start.character} to L${range.end.line}C${range.end.character}`);
|
||||
if (range.start.line === range.end.line) {
|
||||
if (range.start.character === range.end.character) {
|
||||
return 1;
|
||||
} else {
|
||||
console.log(`L${range.start.line}C${range.start.character} to L${range.end.line}C${range.end.character}`);
|
||||
return range.end.character - range.start.character;
|
||||
}
|
||||
}
|
||||
// todo detect multiline changes
|
||||
return 1;
|
||||
}
|
||||
|
||||
public updateXpCount(document: TextDocument, changeCount: number): void {
|
||||
// only update xp if one of supported languages
|
||||
if (this.isSupportedLanguage(document.languageId)) {
|
||||
this.pulse.addXP(document.languageId, changeCount);
|
||||
// this.statusBarItem.text = this.changeCount !== 1 ?
|
||||
// ` C::S ${this.changeCount} Words` : "$(pencil) C::S 1 Word";
|
||||
this.statusBarItem.text = `C::S $(pencil) ${this.pulse.getXP(document.languageId)}`;
|
||||
this.statusBarItem.show();
|
||||
} else {
|
||||
this.statusBarItem.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private isSupportedLanguage(language: string): boolean {
|
||||
// todo: check supported languages
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +1,53 @@
|
||||
//
|
||||
// Note: This example test is leveraging the Mocha test framework.
|
||||
// Please refer to their documentation on https://mochajs.org/ for help.
|
||||
//
|
||||
import * as assert from "assert";
|
||||
|
||||
// The module 'assert' provides assertion methods from node
|
||||
import * as assert from 'assert';
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
import * as vscode from "vscode";
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
import * as codestats from "../src/code-stats";
|
||||
import { Pulse } from "../src/pulse";
|
||||
|
||||
// You can import and use all API from the 'vscode' module
|
||||
// as well as import your extension to test it
|
||||
import * as vscode from 'vscode';
|
||||
import * as myExtension from '../src/code-stats';
|
||||
suite("code-stats-vscode extension tests", () => {
|
||||
test("Initialized Pulse is empty", () => {
|
||||
let pulse: Pulse = new Pulse();
|
||||
const language: string = "typescript";
|
||||
|
||||
// Defines a Mocha test suite to group tests of similar kind together
|
||||
suite("Extension Tests", () => {
|
||||
let initialXP: number = pulse.getXP(language);
|
||||
|
||||
// Defines a Mocha unit test
|
||||
test("Something 1", () => {
|
||||
assert.equal(-1, [1, 2, 3].indexOf(5));
|
||||
assert.equal(-1, [1, 2, 3].indexOf(0));
|
||||
assert.equal(initialXP, 0);
|
||||
});
|
||||
|
||||
test("Add XP to Pulse", () => {
|
||||
let pulse: Pulse = new Pulse();
|
||||
|
||||
const language1: string = "typescript";
|
||||
const language2: string = "javascript";
|
||||
const language3: string = "coffeescript";
|
||||
const addedXP: number = 1000;
|
||||
|
||||
let xp1: number = pulse.getXP(language1);
|
||||
let xp2: number = pulse.getXP(language2);
|
||||
let xp3: number = pulse.getXP(language3);
|
||||
assert.equal(xp1, 0);
|
||||
assert.equal(xp2, 0);
|
||||
assert.equal(xp3, 0);
|
||||
|
||||
pulse.addXP(language1, addedXP);
|
||||
xp1 = pulse.getXP(language1);
|
||||
xp2 = pulse.getXP(language2);
|
||||
xp3 = pulse.getXP(language3);
|
||||
|
||||
assert.equal(xp1, addedXP);
|
||||
assert.equal(xp2, 0);
|
||||
assert.equal(xp3, 0);
|
||||
|
||||
pulse.addXP(language1, addedXP);
|
||||
pulse.addXP(language2, addedXP);
|
||||
xp1 = pulse.getXP(language1);
|
||||
xp2 = pulse.getXP(language2);
|
||||
xp3 = pulse.getXP(language3);
|
||||
|
||||
assert.equal(xp1, 2 * addedXP);
|
||||
assert.equal(xp2, addedXP);
|
||||
assert.equal(xp3, 0);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user