Skip to content

Commit e23f80c

Browse files
committed
Support for AI Coding category
1 parent c5dfd7e commit e23f80c

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

src/utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export class Utils {
109109

110110
public static isRemoteUri(uri: vscode.Uri): boolean {
111111
if (!uri) return false;
112-
return uri.scheme == 'vscode-remote';
112+
return uri.scheme === 'vscode-remote';
113113
}
114114

115115
public static apiUrlToDashboardUrl(url: string): string {
@@ -123,7 +123,12 @@ export class Utils {
123123

124124
public static isPullRequest(uri: vscode.Uri): boolean {
125125
if (!uri) return false;
126-
return uri.scheme == 'pr';
126+
return uri.scheme === 'pr';
127+
}
128+
129+
public static isAIChatSidebar(uri: vscode.Uri | undefined): boolean {
130+
if (!uri) return false;
131+
return uri.scheme === 'vscode-chat-code-block';
127132
}
128133

129134
public static getEditorName(): string {

src/wakatime.ts

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,14 @@ export class WakaTime {
3232
private lastHeartbeat: number = 0;
3333
private lastDebug: boolean = false;
3434
private lastCompile: boolean = false;
35+
private lastAICodeGenerating: boolean = false;
3536
private dedupe: FileSelectionMap = {};
3637
private debounceTimeoutId: any = null;
3738
private debounceMs = 50;
39+
private AIDebounceTimeoutId: any = null;
40+
private AIdebounceMs = 1000;
41+
private AIdebounceCount = 0;
42+
private AIpasteCount = 0;
3843
private dependencies: Dependencies;
3944
private options: Options;
4045
private logger: Logger;
@@ -48,6 +53,7 @@ export class WakaTime {
4853
private extensionPath: string;
4954
private isCompiling: boolean = false;
5055
private isDebugging: boolean = false;
56+
private isAICodeGenerating: boolean = false;
5157
private currentlyFocusedFile: string;
5258
private teamDevsForFileCache = {};
5359
private resourcesLocation: string;
@@ -414,6 +420,7 @@ export class WakaTime {
414420
// subscribe to selection change and editor activation events
415421
let subscriptions: vscode.Disposable[] = [];
416422
vscode.window.onDidChangeTextEditorSelection(this.onChangeSelection, this, subscriptions);
423+
vscode.workspace.onDidChangeTextDocument(this.onChangeTextDocument, this, subscriptions);
417424
vscode.window.onDidChangeActiveTextEditor(this.onChangeTab, this, subscriptions);
418425
vscode.workspace.onDidSaveTextDocument(this.onSave, this, subscriptions);
419426

@@ -460,6 +467,42 @@ export class WakaTime {
460467

461468
private onChangeSelection(e: vscode.TextEditorSelectionChangeEvent): void {
462469
if (e.kind === vscode.TextEditorSelectionChangeKind.Command) return;
470+
if (Utils.isAIChatSidebar(e.textEditor?.document?.uri)) {
471+
this.isAICodeGenerating = true;
472+
}
473+
this.onEvent(false);
474+
}
475+
476+
private onChangeTextDocument(e: vscode.TextDocumentChangeEvent): void {
477+
if (Utils.isAIChatSidebar(e.document?.uri)) {
478+
this.isAICodeGenerating = true;
479+
this.AIdebounceCount = 0;
480+
} else if (e.contentChanges.length === 1 && e.contentChanges?.[0].text.length > 1) {
481+
if (this.AIpasteCount > 1) {
482+
this.isAICodeGenerating = true;
483+
this.AIdebounceCount = 0;
484+
}
485+
this.AIpasteCount++;
486+
} else if (
487+
this.isAICodeGenerating &&
488+
e.contentChanges.length === 1 &&
489+
e.contentChanges?.[0].text.length === 1 &&
490+
e.contentChanges?.[0].text !== '\n' &&
491+
e.contentChanges?.[0].text !== '\r'
492+
) {
493+
this.AIdebounceCount++;
494+
clearTimeout(this.AIDebounceTimeoutId);
495+
this.AIDebounceTimeoutId = setTimeout(() => {
496+
if (this.AIdebounceCount > 1) {
497+
this.isAICodeGenerating = false;
498+
this.AIpasteCount = 0;
499+
}
500+
}, this.AIdebounceMs);
501+
} else if (this.isAICodeGenerating) {
502+
this.AIdebounceCount = 0;
503+
clearTimeout(this.AIDebounceTimeoutId);
504+
}
505+
if (!this.isAICodeGenerating) return;
463506
this.onEvent(false);
464507
}
465508

@@ -500,7 +543,8 @@ export class WakaTime {
500543
this.enoughTimePassed(time) ||
501544
this.lastFile !== file ||
502545
this.lastDebug !== this.isDebugging ||
503-
this.lastCompile !== this.isCompiling
546+
this.lastCompile !== this.isCompiling ||
547+
this.lastAICodeGenerating !== this.isAICodeGenerating
504548
) {
505549
this.sendHeartbeat(
506550
doc,
@@ -509,11 +553,13 @@ export class WakaTime {
509553
isWrite,
510554
this.isCompiling,
511555
this.isDebugging,
556+
this.isAICodeGenerating,
512557
);
513558
this.lastFile = file;
514559
this.lastHeartbeat = time;
515560
this.lastDebug = this.isDebugging;
516561
this.lastCompile = this.isCompiling;
562+
this.lastAICodeGenerating = this.isAICodeGenerating;
517563
}
518564
}
519565
}
@@ -528,10 +574,19 @@ export class WakaTime {
528574
isWrite: boolean,
529575
isCompiling: boolean,
530576
isDebugging: boolean,
577+
isAICoding: boolean,
531578
): Promise<void> {
532579
const apiKey = await this.options.getApiKey();
533580
if (apiKey) {
534-
await this._sendHeartbeat(doc, time, selection, isWrite, isCompiling, isDebugging);
581+
await this._sendHeartbeat(
582+
doc,
583+
time,
584+
selection,
585+
isWrite,
586+
isCompiling,
587+
isDebugging,
588+
isAICoding,
589+
);
535590
} else {
536591
await this.promptForApiKey();
537592
}
@@ -544,6 +599,7 @@ export class WakaTime {
544599
isWrite: boolean,
545600
isCompiling: boolean,
546601
isDebugging: boolean,
602+
isAICoding: boolean,
547603
): Promise<void> {
548604
if (!this.dependencies.isCliInstalled()) return;
549605

@@ -572,6 +628,8 @@ export class WakaTime {
572628
args.push('--category', 'debugging');
573629
} else if (isCompiling) {
574630
args.push('--category', 'building');
631+
} else if (isAICoding) {
632+
args.push('--category', 'ai coding');
575633
} else if (Utils.isPullRequest(doc.uri)) {
576634
args.push('--category', 'code reviewing');
577635
}

0 commit comments

Comments
 (0)