Skip to content

Commit 0d87f75

Browse files
committed
Refactor keyword search into a reusable utility and fix typo in README
1 parent df356b7 commit 0d87f75

4 files changed

Lines changed: 67 additions & 93 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Code Web Chat is a free and open-source (FOSS), independent AI coding toolkit fo
2929

3030
## Introduction
3131

32-
With its focus on context engineering, CWC lets you pick all the necessary files, includnig useful examples, with engineer's intent. Such steered model doesn't need time consuming planning, makes all edits in a single request, and is as accurate as can get. The tool is a perfect companion for all kinds of coding tasks; from tedious refactors to complex features.
32+
With its focus on context engineering, CWC lets you pick all the necessary files, includnig useful examples, with engineer's intent. Such steered model welcomes simple prompts, makes all edits in a single request, and is as accurate as can get. The tool is a perfect companion for all kinds of coding tasks; from tedious refactors to complex features.
3333

3434
When pair-programming with Code Web Chat you foster codebase understanding, iterate on changes that are easy to review, and enter the flow state like in the good old days!
3535

‎apps/editor/src/commands/apply-context-command/sources/check-all-with-keywords-source.ts‎

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as vscode from 'vscode'
22
import * as path from 'path'
3-
import * as fs from 'fs'
43
import { WorkspaceProvider } from '../../../context/providers/workspace/workspace-provider'
54
import { dictionary } from '@shared/constants/dictionary'
65
import { Logger } from '@shared/utils/logger'
76
import { LAST_CONTEXT_MERGE_REPLACE_OPTION_STATE_KEY } from '../../../constants/state-keys'
7+
import { search_files_by_keywords } from '../../../utils/search-files-by-keywords'
88

99
export const handle_check_all_with_keywords_source = async (
1010
workspace_provider: WorkspaceProvider,
@@ -82,52 +82,7 @@ export const handle_check_all_with_keywords_source = async (
8282
all_files.push(...files)
8383
}
8484

85-
const matched_files: string[] = []
86-
87-
await vscode.window.withProgress(
88-
{
89-
location: vscode.ProgressLocation.Notification,
90-
title: `Searching for keywords: ${keywords.join(', ')}...`,
91-
cancellable: true
92-
},
93-
async (progress, token) => {
94-
const total = all_files.length
95-
let processed = 0
96-
const increment = (1 / total) * 100
97-
98-
for (const file_path of all_files) {
99-
if (token.isCancellationRequested) break
100-
101-
try {
102-
// Skip large files (> 1MB) to avoid performance issues
103-
const stats = await fs.promises.stat(file_path)
104-
if (stats.size > 1024 * 1024) {
105-
processed++
106-
progress.report({
107-
increment,
108-
message: `${processed}/${total}`
109-
})
110-
continue
111-
}
112-
113-
const content = await fs.promises.readFile(file_path, 'utf-8')
114-
const content_lower = content.toLowerCase()
115-
116-
if (keywords.some((k) => content_lower.includes(k))) {
117-
matched_files.push(file_path)
118-
}
119-
} catch (error) {
120-
// Ignore read errors (binary files, permissions, etc.)
121-
}
122-
123-
processed++
124-
progress.report({
125-
increment,
126-
message: `${processed}/${total}`
127-
})
128-
}
129-
}
130-
)
85+
const matched_files = await search_files_by_keywords(all_files, keywords)
13186

13287
if (matched_files.length == 0) {
13388
vscode.window.showInformationMessage(

‎apps/editor/src/commands/check-all-with-keywords.ts‎

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as vscode from 'vscode'
22
import * as path from 'path'
3-
import * as fs from 'fs'
43
import { WorkspaceProvider } from '../context/providers/workspace/workspace-provider'
54
import { Logger } from '@shared/utils/logger'
65
import { LAST_CONTEXT_MERGE_REPLACE_OPTION_STATE_KEY } from '../constants/state-keys'
76
import { dictionary } from '@shared/constants/dictionary'
7+
import { search_files_by_keywords } from '../utils/search-files-by-keywords'
88

99
export const check_all_with_keywords_command = (
1010
workspace_provider: WorkspaceProvider,
@@ -69,51 +69,10 @@ export const check_all_with_keywords_command = (
6969
if (keywords.length == 0) return
7070

7171
const all_files = await workspace_provider.find_all_files(folder_path)
72-
const matched_files: string[] = []
73-
74-
await vscode.window.withProgress(
75-
{
76-
location: vscode.ProgressLocation.Notification,
77-
title: `Searching for keywords: ${keywords.join(', ')}...`,
78-
cancellable: true
79-
},
80-
async (progress, token) => {
81-
const total = all_files.length
82-
let processed = 0
83-
const increment = (1 / total) * 100
84-
85-
for (const file_path of all_files) {
86-
if (token.isCancellationRequested) break
8772

88-
try {
89-
// Skip large files (> 1MB)
90-
const stats = await fs.promises.stat(file_path)
91-
if (stats.size > 1024 * 1024) {
92-
processed++
93-
progress.report({
94-
increment,
95-
message: `${processed}/${total}`
96-
})
97-
continue
98-
}
99-
100-
const content = await fs.promises.readFile(file_path, 'utf-8')
101-
const content_lower = content.toLowerCase()
102-
103-
if (keywords.some((k) => content_lower.includes(k))) {
104-
matched_files.push(file_path)
105-
}
106-
} catch (error) {
107-
// Ignore read errors
108-
}
109-
110-
processed++
111-
progress.report({
112-
increment,
113-
message: `${processed}/${total}`
114-
})
115-
}
116-
}
73+
const matched_files = await search_files_by_keywords(
74+
all_files,
75+
keywords
11776
)
11877

11978
if (matched_files.length == 0) {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import * as vscode from 'vscode'
2+
import * as path from 'path'
3+
import * as fs from 'fs'
4+
5+
export const search_files_by_keywords = async (
6+
files: string[],
7+
keywords: string[],
8+
progress?: vscode.Progress<{ message?: string; increment?: number }>,
9+
token?: vscode.CancellationToken
10+
): Promise<string[]> => {
11+
const matched_files: string[] = []
12+
const total = files.length
13+
let processed = 0
14+
const increment = total > 0 ? (1 / total) * 100 : 0
15+
16+
for (const file_path of files) {
17+
if (token?.isCancellationRequested) break
18+
19+
try {
20+
const file_name_lower = path.basename(file_path).toLowerCase()
21+
if (keywords.some((k) => file_name_lower.includes(k))) {
22+
matched_files.push(file_path)
23+
processed++
24+
progress?.report({
25+
increment,
26+
message: `${processed}/${total}`
27+
})
28+
continue
29+
}
30+
31+
// Skip large files (> 1MB) to avoid performance issues
32+
const stats = await fs.promises.stat(file_path)
33+
if (stats.size > 1024 * 1024) {
34+
processed++
35+
progress?.report({
36+
increment,
37+
message: `${processed}/${total}`
38+
})
39+
continue
40+
}
41+
42+
const content = await fs.promises.readFile(file_path, 'utf-8')
43+
const content_lower = content.toLowerCase()
44+
45+
if (keywords.some((k) => content_lower.includes(k))) {
46+
matched_files.push(file_path)
47+
}
48+
} catch (error) {
49+
// Ignore read errors (binary files, permissions, etc.)
50+
}
51+
52+
processed++
53+
progress?.report({
54+
increment,
55+
message: `${processed}/${total}`
56+
})
57+
}
58+
59+
return matched_files
60+
}

0 commit comments

Comments
 (0)