Skip to content

Commit 5296ee8

Browse files
committed
Clean up source code comments and improve token calculation progress notifications
- when crunching token counts, show real progress bar - when crunching token counts, don't show numbers (done, total files), progress bar is enough - increase the debounce time to 3 seconds - remove redundant comments └── apps └── editor └── src └── context ├── context-initialization.ts ├── helpers │ ├── get-all-workspace-files.ts │ └── get-selected-files.ts ├── providers │ ├── open-editors │ │ └── open-editors-provider.ts │ ├── selected-files │ │ └── selected-files-provider.ts │ └── workspace │ ├── modules │ │ ├── index.ts │ │ └── token-calculator.ts │ └── workspace-provider.ts ├── shared-context-state.ts └── utils └── shrink-file ├── index.ts ├── languages │ ├── c-style.ts │ ├── css.ts │ ├── html.ts │ ├── jsx.ts │ ├── python.ts │ ├── ruby.ts │ └── sql.ts ├── shrink-file.spec.ts ├── shrink-file.ts └── test-cases ├── c-style │ ├── input.txt │ └── output.txt ├── css │ ├── input.txt │ └── output.txt ├── html │ ├── input.txt │ └── output.txt ├── jsx │ ├── input.txt │ └── output.txt ├── python │ ├── input.txt │ └── output.txt ├── ruby │ ├── input.txt │ └── output.txt ├── scss │ ├── input.txt │ └── output.txt └── sql ├── input.txt └── output.txt
1 parent 5729bc0 commit 5296ee8

11 files changed

Lines changed: 257 additions & 196 deletions

File tree

‎apps/editor/src/context/context-initialization.ts‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ export const context_initialization = async (
177177
}
178178
})
179179

180-
// Fix for issue when the collapsed item has some of its children selected
181180
view.onDidCollapseElement(() => {
182181
workspace_provider!.refresh()
183182
})
@@ -328,7 +327,6 @@ export const context_initialization = async (
328327
})
329328
)
330329

331-
// Update badge when tabs change with debouncing to avoid multiple updates
332330
let tab_change_timeout: NodeJS.Timeout | null = null
333331
extension_context.subscriptions.push(
334332
vscode.window.tabGroups.onDidChangeTabs(() => {
@@ -372,10 +370,9 @@ export const context_initialization = async (
372370
})
373371
)
374372

375-
// Also schedule a delayed update for initial badge display
376373
setTimeout(() => {
377374
update_view_badges()
378-
}, 1000) // Wait for 1 second to ensure VS Code has fully loaded
375+
}, 1000)
379376

380377
return {
381378
workspace_provider,

‎apps/editor/src/context/providers/open-editors/open-editors-provider.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ export class OpenEditorsProvider
101101
}
102102
)
103103

104-
// Initial auto-check of all open editors
105-
// We'll use setTimeout to ensure VS Code has fully loaded editors
106104
setTimeout(() => {
107105
this._initialized = true
108106
this._on_did_change_tree_data.fire()
@@ -417,7 +415,6 @@ export class OpenEditorsProvider
417415
}
418416

419417
clear_checks() {
420-
// Instead of clearing the map, explicitly set each open editor to unchecked
421418
const open_files = this._get_open_editors()
422419

423420
for (const uri of open_files) {

‎apps/editor/src/context/providers/workspace/modules/token-calculator.ts‎

Lines changed: 194 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ type TokenCountsCache = {
2323
}
2424
}
2525

26-
const SHOW_COUNTING_NOTIFICATION_DELAY_MS = 3000
27-
2826
const TOKEN_CACHE_FILE_NAME = 'token-counts-cache.json'
2927

3028
export class TokenCalculator implements vscode.Disposable {
@@ -40,6 +38,12 @@ export class TokenCalculator implements vscode.Disposable {
4038
private _token_cache_update_timeout: NodeJS.Timeout | null = null
4139
private _has_token_counts_cache_updated_once = false
4240

41+
private _progress_stack: {
42+
progress: vscode.Progress<{ message?: string; increment?: number }>
43+
total_files: number
44+
processed_files: number
45+
}[] = []
46+
4347
constructor(
4448
private _provider: IWorkspaceProvider,
4549
private _extension_context: vscode.ExtensionContext
@@ -89,9 +93,7 @@ export class TokenCalculator implements vscode.Disposable {
8993
files: this._flatten_tree(raw_cache[root].files || {})
9094
}
9195
}
92-
} catch {
93-
// Cache file might not exist yet or be corrupt
94-
}
96+
} catch {}
9597

9698
for (const root of this._provider.get_workspace_roots()) {
9799
if (this._session_cache[root]) {
@@ -105,7 +107,6 @@ export class TokenCalculator implements vscode.Disposable {
105107
}
106108
}
107109

108-
// Prune workspaces that no longer exist or were updated more than 3 months ago
109110
const three_months_ago = Date.now() - 90 * 24 * 60 * 60 * 1000
110111
for (const root in current_global_cache) {
111112
if (
@@ -164,34 +165,126 @@ export class TokenCalculator implements vscode.Disposable {
164165
this._update_token_counts_cache()
165166
}
166167

167-
public async with_token_counting_notification<T>(
168-
task: () => Promise<T>
169-
): Promise<T> {
170-
let notification_stopper: any = null
171-
172-
const timer = setTimeout(() => {
173-
vscode.window.withProgress(
174-
{
175-
location: vscode.ProgressLocation.Notification,
176-
title: dictionary.information_message.CRUNCHING_TOKEN_COUNTS,
177-
cancellable: false
178-
},
179-
async (_progress) => {
180-
return new Promise<void>((resolve) => {
181-
notification_stopper = resolve
182-
})
183-
}
184-
)
185-
}, SHOW_COUNTING_NOTIFICATION_DELAY_MS)
168+
private _report_progress() {
169+
for (const state of this._progress_stack) {
170+
if (state.total_files > 0) {
171+
state.processed_files++
172+
const increment = (1 / state.total_files) * 100
173+
state.progress.report({ increment })
174+
}
175+
}
176+
}
177+
178+
private async _count_uncached_files_in_dir(
179+
dir_path: string
180+
): Promise<number> {
181+
if (
182+
this._directory_token_counts.has(dir_path) &&
183+
this._directory_shrink_token_counts.has(dir_path)
184+
) {
185+
return 0
186+
}
186187

188+
let count = 0
187189
try {
188-
const result = await task()
190+
const workspace_root =
191+
this._provider.get_workspace_root_for_file(dir_path)
192+
if (!workspace_root) return 0
189193

190-
return result
191-
} finally {
192-
clearTimeout(timer)
193-
notification_stopper?.()
194+
const relative_dir_path = path.relative(workspace_root, dir_path)
195+
if (
196+
this._provider.is_excluded(
197+
relative_dir_path ? relative_dir_path + '/' : relative_dir_path
198+
)
199+
) {
200+
return 0
201+
}
202+
203+
const entries = await fs.promises.readdir(dir_path, {
204+
withFileTypes: true
205+
})
206+
for (const entry of entries) {
207+
if (entry.isSymbolicLink()) continue
208+
209+
const full_path = path.join(dir_path, entry.name)
210+
211+
const file_workspace_root =
212+
this._provider.get_workspace_root_for_file(full_path)
213+
if (file_workspace_root && file_workspace_root !== workspace_root) {
214+
continue
215+
}
216+
217+
const relative_path = path.relative(workspace_root, full_path)
218+
if (
219+
this._provider.is_excluded(
220+
entry.isDirectory() ? relative_path + '/' : relative_path
221+
)
222+
) {
223+
continue
224+
}
225+
226+
if (this._provider.is_ignored_by_patterns(full_path)) {
227+
continue
228+
}
229+
230+
if (entry.isDirectory()) {
231+
count += await this._count_uncached_files_in_dir(full_path)
232+
} else if (entry.isFile()) {
233+
if (
234+
!this._file_token_counts.has(full_path) ||
235+
!this._file_shrink_token_counts.has(full_path)
236+
) {
237+
count++
238+
}
239+
}
240+
}
241+
} catch {}
242+
return count
243+
}
244+
245+
public async with_token_counting_notification<T>(params: {
246+
dir_path?: string
247+
roots?: string[]
248+
task: () => Promise<T>
249+
}): Promise<T> {
250+
let total_uncached = 0
251+
252+
if (params.dir_path) {
253+
total_uncached = await this._count_uncached_files_in_dir(params.dir_path)
254+
} else if (params.roots) {
255+
for (const root of params.roots) {
256+
total_uncached += await this._count_uncached_files_in_dir(root)
257+
}
258+
}
259+
260+
if (total_uncached === 0) {
261+
return params.task()
194262
}
263+
264+
return vscode.window.withProgress(
265+
{
266+
location: vscode.ProgressLocation.Notification,
267+
title: dictionary.information_message.CRUNCHING_TOKEN_COUNTS,
268+
cancellable: false
269+
},
270+
async (progress) => {
271+
const progress_state = {
272+
progress,
273+
total_files: total_uncached,
274+
processed_files: 0
275+
}
276+
this._progress_stack.push(progress_state)
277+
278+
try {
279+
return await params.task()
280+
} finally {
281+
const index = this._progress_stack.indexOf(progress_state)
282+
if (index !== -1) {
283+
this._progress_stack.splice(index, 1)
284+
}
285+
}
286+
}
287+
)
195288
}
196289

197290
public invalidate_token_counts_for_file(changed_file_path: string) {
@@ -299,11 +392,10 @@ export class TokenCalculator implements vscode.Disposable {
299392
tokens,
300393
shrink_tokens
301394
)
395+
this._report_progress()
302396
return { total: tokens, shrink: shrink_tokens }
303397
}
304-
} catch {
305-
// Continue to calculate if stat fails
306-
}
398+
} catch {}
307399
}
308400

309401
try {
@@ -378,13 +470,15 @@ export class TokenCalculator implements vscode.Disposable {
378470
)
379471
}
380472

473+
this._report_progress()
381474
return { total: token_count, shrink: shrink_token_count }
382475
} catch (error) {
383476
Logger.error({
384477
function_name: 'calculate_file_tokens',
385478
message: `Error calculating tokens for ${file_path}`,
386479
data: error
387480
})
481+
this._report_progress()
388482
return { total: 0, shrink: 0 }
389483
}
390484
}
@@ -452,12 +546,10 @@ export class TokenCalculator implements vscode.Disposable {
452546
}
453547

454548
if (entry.isDirectory()) {
455-
// Recurse into subdirectory
456549
const counts = await this.calculate_directory_tokens(full_path)
457550
total_tokens += counts.total
458551
total_shrink_tokens += counts.shrink
459552
} else if (entry.isFile()) {
460-
// Add file tokens
461553
const counts = await this.calculate_file_tokens(full_path)
462554
total_tokens += counts.total
463555
total_shrink_tokens += counts.shrink
@@ -585,40 +677,86 @@ export class TokenCalculator implements vscode.Disposable {
585677
exclude_file_path?: string
586678
}): Promise<{ total: number; shrink: number }> {
587679
const checked_files = this._provider.get_checked_files()
588-
const result = { total: 0, shrink: 0 }
589680

681+
let total_uncached = 0
590682
for (const file_path of checked_files) {
683+
if (options?.exclude_file_path && file_path == options.exclude_file_path)
684+
continue
591685
try {
686+
const stat = fs.lstatSync(file_path)
687+
if (stat.isSymbolicLink() || stat.isDirectory()) continue
592688
if (
593-
options?.exclude_file_path &&
594-
file_path == options.exclude_file_path
689+
!this._file_token_counts.has(file_path) ||
690+
!this._file_shrink_token_counts.has(file_path)
595691
) {
596-
continue
692+
total_uncached++
597693
}
694+
} catch {}
695+
}
598696

599-
const stat = fs.lstatSync(file_path)
600-
if (stat.isSymbolicLink()) continue
697+
const task = async () => {
698+
const result = { total: 0, shrink: 0 }
699+
for (const file_path of checked_files) {
700+
try {
701+
if (
702+
options?.exclude_file_path &&
703+
file_path == options.exclude_file_path
704+
) {
705+
continue
706+
}
601707

602-
if (stat.isFile()) {
603-
if (this._file_token_counts.has(file_path)) {
604-
result.total += this._file_token_counts.get(file_path)!
605-
result.shrink += this._file_shrink_token_counts.get(file_path)!
606-
} else {
607-
const count = await this.calculate_file_tokens(file_path)
608-
result.total += count.total
609-
result.shrink += count.shrink
708+
const stat = fs.lstatSync(file_path)
709+
if (stat.isSymbolicLink()) continue
710+
711+
if (stat.isFile()) {
712+
if (this._file_token_counts.has(file_path)) {
713+
result.total += this._file_token_counts.get(file_path)!
714+
result.shrink += this._file_shrink_token_counts.get(file_path)!
715+
} else {
716+
const count = await this.calculate_file_tokens(file_path)
717+
result.total += count.total
718+
result.shrink += count.shrink
719+
}
610720
}
721+
} catch (error) {
722+
Logger.error({
723+
function_name: 'get_checked_files_token_count',
724+
message: `Error accessing file ${file_path} for token count`,
725+
data: error
726+
})
611727
}
612-
} catch (error) {
613-
Logger.error({
614-
function_name: 'get_checked_files_token_count',
615-
message: `Error accessing file ${file_path} for token count`,
616-
data: error
617-
})
618728
}
729+
return result
619730
}
620731

621-
return result
732+
if (total_uncached === 0) {
733+
return task()
734+
}
735+
736+
return vscode.window.withProgress(
737+
{
738+
location: vscode.ProgressLocation.Notification,
739+
title: dictionary.information_message.CRUNCHING_TOKEN_COUNTS,
740+
cancellable: false
741+
},
742+
async (progress) => {
743+
const progress_state = {
744+
progress,
745+
total_files: total_uncached,
746+
processed_files: 0
747+
}
748+
this._progress_stack.push(progress_state)
749+
750+
try {
751+
return await task()
752+
} finally {
753+
const index = this._progress_stack.indexOf(progress_state)
754+
if (index !== -1) {
755+
this._progress_stack.splice(index, 1)
756+
}
757+
}
758+
}
759+
)
622760
}
623761

624762
public dispose() {

0 commit comments

Comments
 (0)