Skip to content

Commit 0ee9d16

Browse files
author
Akos Kitta
committed
fuzzy board search.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
1 parent 2f3fe27 commit 0ee9d16

File tree

9 files changed

+32
-17
lines changed

9 files changed

+32
-17
lines changed

arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,7 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un
170170
bind(BoardsServiceClient).toDynamicValue(async context => {
171171
const client = context.container.get(BoardsServiceClientImpl);
172172
const service = context.container.get<BoardsService>(BoardsService);
173-
const [attachedBoards, availablePorts] = await Promise.all([
174-
service.getAttachedBoards(),
175-
service.getAvailablePorts()
176-
]);
177-
client.init({ attachedBoards, availablePorts });
173+
await client.init(service);
178174
WebSocketConnectionProvider.createProxy(context.container, BoardsServicePath, client);
179175
return client;
180176
}).inSingletonScope();

arduino-ide-extension/src/browser/boards/boards-config.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export class BoardsConfig extends React.Component<BoardsConfig.Props, BoardsConf
127127
}
128128

129129
protected queryBoards = (options: { query?: string } = {}): Promise<Array<Board & { packageName: string }>> => {
130-
return this.props.boardsService.searchBoards(options);
130+
return this.props.boardsServiceClient.searchBoards(options);
131131
}
132132

133133
protected get availablePorts(): Promise<Port[]> {

arduino-ide-extension/src/browser/boards/boards-service-client-impl.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { MessageService } from '@theia/core/lib/common/message-service';
55
import { StorageService } from '@theia/core/lib/browser/storage-service';
66
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
77
import { RecursiveRequired } from '../../common/types';
8-
import { BoardsServiceClient, AttachedBoardsChangeEvent, BoardInstalledEvent, Board, Port, BoardUninstalledEvent } from '../../common/protocol';
8+
import { BoardsServiceClient, AttachedBoardsChangeEvent, BoardInstalledEvent, Board, Port, BoardUninstalledEvent, BoardsService } from '../../common/protocol';
99
import { BoardsConfig } from './boards-config';
1010
import { naturalCompare } from '../../common/utils';
1111

@@ -40,6 +40,7 @@ export class BoardsServiceClientImpl implements BoardsServiceClient, FrontendApp
4040
protected _attachedBoards: Board[] = []; // This does not contain the `Unknown` boards. They're visible from the available ports only.
4141
protected _availablePorts: Port[] = [];
4242
protected _availableBoards: AvailableBoard[] = [];
43+
protected boardsService: BoardsService;
4344

4445
/**
4546
* Event when the state of the attached/detached boards has changed. For instance, the user have detached a physical board.
@@ -65,7 +66,12 @@ export class BoardsServiceClientImpl implements BoardsServiceClient, FrontendApp
6566
* When the FE connects to the BE, the BE stets the known boards and ports.\
6667
* This is a DI workaround for not being able to inject the service into the client.
6768
*/
68-
init({ attachedBoards, availablePorts }: { attachedBoards: Board[], availablePorts: Port[] }): void {
69+
async init(boardsService: BoardsService): Promise<void> {
70+
this.boardsService = boardsService;
71+
const [attachedBoards, availablePorts] = await Promise.all([
72+
this.boardsService.getAttachedBoards(),
73+
this.boardsService.getAvailablePorts()
74+
]);
6975
this._attachedBoards = attachedBoards;
7076
this._availablePorts = availablePorts;
7177
this.reconcileAvailableBoards().then(() => this.tryReconnect());
@@ -157,6 +163,20 @@ export class BoardsServiceClientImpl implements BoardsServiceClient, FrontendApp
157163
}
158164
}
159165

166+
async searchBoards({ query, cores }: { query?: string, cores?: string[] }): Promise<Array<Board & { packageName: string }>> {
167+
const boards = await this.boardsService.allBoards({});
168+
const coresFilter = !!cores && cores.length
169+
? ((toFilter: { packageName: string }) => cores.some(core => core === toFilter.packageName))
170+
: () => true;
171+
const fuzzyFilter = !!query
172+
? ((toFilter: Board) => !!monaco.filters.matchesFuzzy(query, toFilter.name, true))
173+
: () => true
174+
return boards
175+
.filter(coresFilter)
176+
.filter(fuzzyFilter)
177+
.sort(Board.compare)
178+
}
179+
160180
get boardsConfig(): BoardsConfig.Config {
161181
return this._boardsConfig;
162182
}

arduino-ide-extension/src/browser/boards/quick-open/boards-quick-open-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenM
159159
const selectedBoard = availableBoards.filter(AvailableBoard.hasPort).find(({ selected }) => selected);
160160
const [configs, boards] = await Promise.all([
161161
selectedBoard && selectedBoard.fqbn ? this.configStore.getConfig(selectedBoard.fqbn) : Promise.resolve([]),
162-
this.boardsService.searchBoards({})
162+
this.boardsService.allBoards({})
163163
]);
164164
this.allBoards = Board.decorateBoards(selectedBoard, boards)
165165
.filter(board => !availableBoards.some(availableBoard => Board.sameAs(availableBoard, board)));

arduino-ide-extension/src/browser/style/index.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@import './list-widget.css';
2-
@import './board-select-dialog.css';
2+
@import './boards-config-dialog.css';
33
@import './main.css';
44
@import './monitor.css';
55
@import './arduino-select.css';

arduino-ide-extension/src/common/protocol/boards-service.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ export interface BoardsService extends Installable<BoardsPackage>, Searchable<Bo
6868
getBoardDetails(options: { fqbn: string }): Promise<BoardDetails>;
6969
getBoardPackage(options: { id: string }): Promise<BoardsPackage | undefined>;
7070
getContainerBoardPackage(options: { fqbn: string }): Promise<BoardsPackage | undefined>;
71-
searchBoards(options: { query?: string }): Promise<Array<Board & { packageName: string }>>;
71+
// The CLI cannot do fuzzy search. This method provides all boards and we do the fuzzy search (with monaco) on the frontend.
72+
// https://github.com/arduino/arduino-cli/issues/629
73+
allBoards(options: {}): Promise<Array<Board & { packageName: string }>>;
7274
}
7375

7476
export interface Port {

arduino-ide-extension/src/node/boards-service-impl.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -261,13 +261,10 @@ export class BoardsServiceImpl implements BoardsService {
261261
return packages.find(({ boards }) => boards.some(({ fqbn }) => fqbn === expectedFqbn));
262262
}
263263

264-
async searchBoards(options: { query?: string }): Promise<Array<Board & { packageName: string }>> {
265-
const query = (options.query || '').toLocaleLowerCase();
264+
async allBoards(options: {}): Promise<Array<Board & { packageName: string }>> {
266265
const results = await this.search(options);
267266
return results.map(item => item.boards.map(board => ({ ...board, packageName: item.name })))
268-
.reduce((acc, curr) => acc.concat(curr), [])
269-
.filter(board => board.name.toLocaleLowerCase().indexOf(query) !== -1)
270-
.sort(Board.compare);
267+
.reduce((acc, curr) => acc.concat(curr), []);
271268
}
272269

273270
async search(options: { query?: string }): Promise<BoardsPackage[]> {

arduino-ide-extension/src/test/browser/boards-service-client-impl.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ export class MockBoardsService implements BoardsService {
268268
throw new Error('Method not implemented.');
269269
}
270270

271-
searchBoards(): Promise<Array<Board & { packageName: string; }>> {
271+
allBoards(): Promise<Array<Board & { packageName: string; }>> {
272272
throw new Error('Method not implemented.');
273273
}
274274

0 commit comments

Comments
 (0)