Skip to content

Commit 99105c6

Browse files
authored
Improve codesearch experience (#41)
* Improve codesearch feedback * Add PID to CreateScope request * Update for query options * Allow autocompletion of codesearch bazelrc lines * Use 0.9.5 bzl release
1 parent 0d267c4 commit 99105c6

11 files changed

Lines changed: 112 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Change Log
22

3+
## 0.6.5 (Sun Nov 1 2020)
4+
5+
- Update bzl to include codesearch fixes/improvements.
6+
- Allow multiple bzl instances to run without file locking.
7+
38
## 0.6.4 (Mon Oct 25 2020)
49

510
- Fix https://github.com/stackb/bazel-stack-vscode/issues/36.

docs/searching.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,13 @@ index is stored (this is printed as the final output line during indexing).
5858

5959
Indexes are stored within the outputBase of a workspace, so a `bazel clean` will
6060
also remove all codesearch indexes.
61+
62+
## Options
63+
64+
You can add command line options to the `bazel query` using `--` to terminate
65+
the query expression from the options. For example, this uses the
66+
`--noimplicit_deps` option:
67+
68+
```
69+
codesearch deps(//...) -- --noimplicit_deps
70+
```

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "bazel-stack-vscode",
33
"displayName": "bazel-stack-vscode",
44
"description": "Bazel Support for Visual Studio Code",
5-
"version": "0.6.4",
5+
"version": "0.6.5",
66
"publisher": "StackBuild",
77
"license": "Apache-2.0",
88
"icon": "stackb-full.png",
@@ -198,7 +198,7 @@
198198
},
199199
"bsv.bzl.server.github-release": {
200200
"type": "string",
201-
"default": "0.9.4",
201+
"default": "0.9.5",
202202
"description": "The github release tag of the bzl release to download"
203203
},
204204
"bsv.bzl.server.command": {

proto/codesearch.proto

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ message CreateScopeRequest {
3030
// The contents of the file, if they are guaranteed to be short.
3131
BazelQuery bazel_query = 5;
3232
}
33+
34+
// PID of the workspace bazel server, if known
35+
int32 pid = 6;
3336
}
3437

3538
message BazelQuery {
@@ -44,6 +47,10 @@ message BazelQuery {
4447
bool bazel_internal = 4;
4548
// if true, exclude the default workspace when constructing a universal query
4649
bool exclude_default = 5;
50+
// command line options for the query
51+
repeated string options = 7;
52+
// the command ('query' or 'cquery' - if empty default to 'query')
53+
string command = 8;
4754
}
4855

4956
message CreateScopeResponse { repeated string progress = 1; }

src/bazelrc/flags.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ function getCommandNameFromLine(text: string): string | undefined {
208208
if (isBazelCommand(match[1])) {
209209
return match[1];
210210
}
211+
// special case to support bzl codesearch. Alias 'codesearch' to 'query'
212+
if (match[1] === 'codesearch') {
213+
return 'query';
214+
}
211215
}
212216
return undefined;
213217
}

src/bzl/codesearch/codelens.ts

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as grpc from '@grpc/grpc-js';
2+
import { Duration } from 'luxon';
23
import * as vscode from 'vscode';
34
import { event } from 'vscode-common';
45
import { CommandCodeLensProvider } from '../../api';
@@ -154,6 +155,22 @@ export class CodeSearchCodeLens implements CommandCodeLensProvider, vscode.Dispo
154155

155156
async createScope(opts: CodesearchIndexOptions, client: BzlCodesearch, ws: Workspace, output: OutputChannel): Promise<void> {
156157

158+
let command = 'query';
159+
const query: string[] = [];
160+
const options: string[] = [];
161+
let sink = query;
162+
for (let i = 0; i < opts.args.length; i++) {
163+
const arg = opts.args[i];
164+
if (i === 0 && (arg === 'query' || arg === 'cquery')) {
165+
command = arg;
166+
continue;
167+
}
168+
if (arg === '--') {
169+
sink = options;
170+
continue;
171+
}
172+
sink.push(arg);
173+
}
157174
const queryExpression = opts.args.join(' ');
158175
const scopeName = md5Hash(queryExpression);
159176

@@ -162,17 +179,20 @@ export class CodeSearchCodeLens implements CommandCodeLensProvider, vscode.Dispo
162179
outputBase: ws.outputBase,
163180
name: scopeName,
164181
bazelQuery: {
165-
expression: queryExpression,
182+
command: command,
183+
expression: query.join(' '),
184+
options: options,
166185
},
167186
};
168187

169188
output.clear();
170189
output.show();
190+
output.appendLine(`Indexing ${queryExpression}...`);
171191

172192
return vscode.window.withProgress<void>(
173193
{
174194
location: vscode.ProgressLocation.Notification,
175-
title: `Indexing ${queryExpression}`,
195+
title: `Indexing ${queryExpression}...`,
176196
cancellable: false,
177197
}, async (progress: vscode.Progress<{ message: string | undefined }>, token: vscode.CancellationToken): Promise<void> => {
178198

@@ -232,11 +252,11 @@ export class CodeSearchCodeLens implements CommandCodeLensProvider, vscode.Dispo
232252
cwd: ws.cwd,
233253
outputBase: ws.outputBase,
234254
name: scopeName,
235-
});
255+
});
236256
} catch (err) {
237257
if (err.code !== grpc.status.NOT_FOUND) {
238258
const e: grpc.ServiceError = err as grpc.ServiceError;
239-
vscode.window.showErrorMessage(`${e.message} (${e.code})`);
259+
vscode.window.showErrorMessage(`${e.message} (${e.code})`);
240260
}
241261
}
242262

@@ -252,27 +272,45 @@ export class CodeSearchCodeLens implements CommandCodeLensProvider, vscode.Dispo
252272
);
253273

254274
queryDidChange(async (q) => {
275+
const start = Date.now();
276+
255277
if (!q.line) {
256-
panel.onDidChangeHTMLSummary.fire('');
278+
panel.onDidChangeHTMLSummary.fire('Searching ' + queryExpression);
257279
panel.onDidChangeHTMLResults.fire('');
258280
return;
259281
}
260282

283+
panel.onDidChangeHTMLSummary.fire('Working...');
284+
panel.onDidChangeHTMLResults.fire('<progress></progress>');
285+
const timeoutID = setTimeout(() => {
286+
panel.onDidChangeHTMLSummary.fire('Timed out.');
287+
panel.onDidChangeHTMLResults.fire('');
288+
}, 1000);
289+
261290
try {
262291
const result = await client.searchScope({
263292
scopeName: scopeName,
264293
query: q,
265294
});
266-
panel.onDidChangeHTMLSummary.fire(await this.renderer.renderSummary(result));
267-
panel.onDidChangeHTMLResults.fire(await this.renderer.renderResults(result, ws));
295+
clearTimeout(timeoutID);
296+
panel.onDidChangeHTMLSummary.fire('Rendering results...');
297+
const resultsHTML = await this.renderer.renderResults(result, ws);
298+
let summaryHTML = await this.renderer.renderSummary(q, result);
299+
const dur = Duration.fromMillis(Date.now() - start);
300+
summaryHTML += ` [${dur.milliseconds} ms]`;
301+
panel.onDidChangeHTMLSummary.fire(summaryHTML);
302+
panel.onDidChangeHTMLResults.fire(resultsHTML);
268303
} catch (e) {
304+
clearTimeout(timeoutID);
269305
const err = e as grpc.ServiceError;
270306
panel.onDidChangeHTMLSummary.fire(err.message);
271307
panel.onDidChangeHTMLResults.fire('');
272308
}
273309
});
274310

275-
return this.renderSearchPanel(ws, queryExpression, scope, panel, query, queryChangeEmitter);
311+
await this.renderSearchPanel(ws, queryExpression, scope, panel, query, queryChangeEmitter);
312+
313+
panel.onDidChangeHTMLSummary.fire('Searching ' + queryExpression);
276314
}
277315

278316
async renderSearchPanel(ws: Workspace, queryExpression: string, scope: Scope | undefined, panel: CodesearchRenderProvider, query: Query, queryChangeEmitter: vscode.EventEmitter<Query>): Promise<void> {
@@ -282,7 +320,7 @@ export class CodeSearchCodeLens implements CommandCodeLensProvider, vscode.Dispo
282320
files = Long.fromValue(scope.size || 0).toInt();
283321
if (scope.createdAt) {
284322
lastIndexed = getRelativeDateFromTimestamp(scope.createdAt);
285-
}
323+
}
286324
}
287325

288326
let heading = `codesearch <span class="text-hl">${files}</span> files, last indexed <span class="text-hl">${lastIndexed}</span>`;
@@ -309,7 +347,7 @@ export class CodeSearchCodeLens implements CommandCodeLensProvider, vscode.Dispo
309347
label: 'Query',
310348
type: 'text',
311349
name: 'number',
312-
placeholder: `Search ${queryExpression}`,
350+
placeholder: 'Search expression',
313351
display: 'inline-block',
314352
size: 40,
315353
autofocus: true,

src/bzl/codesearch/renderer.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { MergedSearchResult } from '../../proto/build/stack/codesearch/v1beta1/M
1414
import { Bounds } from '../../proto/livegrep/Bounds';
1515
import { CodeSearchResult } from '../../proto/livegrep/CodeSearchResult';
1616
import { FileResult } from '../../proto/livegrep/FileResult';
17+
import { Query } from '../../proto/livegrep/Query';
1718
import { SearchResult } from '../../proto/livegrep/SearchResult';
1819
import { CodeHighlighter, getLanguageId } from './highlighter';
1920
import path = require('path');
@@ -40,14 +41,18 @@ export class CodesearchRenderer {
4041
}
4142
}
4243

43-
public async renderSummary(result: CodeSearchResult): Promise<string> {
44+
public async renderSummary(query: Query, result: CodeSearchResult): Promise<string> {
45+
const atLimit = query.maxMatches === result.results?.length;
4446
let html = '';
4547
if (result.results) {
46-
html += `<span>${result.results?.length} match${result.results.length > 1 ? 'es' : ''}</span>`;
48+
html += `<span>${result.results?.length}${atLimit ? '+' : ''} match${result.results.length > 1 ? 'es' : ''}</span>`;
4749
}
4850
if (result.fileResults) {
4951
html += ` (<span>${result.fileResults?.length} filename match${result.fileResults.length > 1 ? 'es' : ''}</span>)`;
5052
}
53+
if (html === '') {
54+
html = 'No results.';
55+
}
5156
return html;
5257
}
5358

src/proto/build/stack/codesearch/v1beta1/BazelQuery.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ export interface BazelQuery {
2323
* if true, exclude the default workspace when constructing a universal query
2424
*/
2525
'excludeDefault'?: (boolean);
26+
/**
27+
* command line options for the query
28+
*/
29+
'options'?: (string)[];
30+
/**
31+
* the command ('query' or 'cquery' - if empty default to 'query')
32+
*/
33+
'command'?: (string);
2634
}
2735

2836
export interface BazelQuery__Output {
@@ -47,4 +55,12 @@ export interface BazelQuery__Output {
4755
* if true, exclude the default workspace when constructing a universal query
4856
*/
4957
'excludeDefault': (boolean);
58+
/**
59+
* command line options for the query
60+
*/
61+
'options': (string)[];
62+
/**
63+
* the command ('query' or 'cquery' - if empty default to 'query')
64+
*/
65+
'command': (string);
5066
}

src/proto/build/stack/codesearch/v1beta1/CreateScopeRequest.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export interface CreateScopeRequest {
1111
* The contents of the file, if they are guaranteed to be short.
1212
*/
1313
'bazelQuery'?: (_build_stack_codesearch_v1beta1_BazelQuery);
14+
/**
15+
* PID of the workspace bazel server, if known
16+
*/
17+
'pid'?: (number);
1418
'expression'?: "bazelQuery";
1519
}
1620

@@ -23,5 +27,9 @@ export interface CreateScopeRequest__Output {
2327
* The contents of the file, if they are guaranteed to be short.
2428
*/
2529
'bazelQuery'?: (_build_stack_codesearch_v1beta1_BazelQuery__Output);
30+
/**
31+
* PID of the workspace bazel server, if known
32+
*/
33+
'pid': (number);
2634
'expression': "bazelQuery";
2735
}

0 commit comments

Comments
 (0)