Skip to content

Commit 91efb6d

Browse files
Support fuzzy search (#82)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 96cbfa6 commit 91efb6d

File tree

5 files changed

+24
-18
lines changed

5 files changed

+24
-18
lines changed

cli.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const cli = meow(`
2424
2525
Run without arguments to use the interactive mode.
2626
In interactive mode, 🚦n% indicates high CPU usage and 🐏n% indicates high memory usage.
27+
Supports fuzzy search in the interactive mode.
2728
2829
The process name is case insensitive.
2930
`, {

interactive.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import cliTruncate from 'cli-truncate';
99
import {allPortsWithPid} from 'pid-port';
1010
import fkill from 'fkill';
1111
import processExists from 'process-exists';
12+
import FuzzySearch from 'fuzzy-search';
1213

1314
const isWindows = process.platform === 'win32';
1415
const commandLineMargins = 4;
@@ -43,16 +44,6 @@ const processExited = async (pid, timeout) => {
4344
return !exists;
4445
};
4546

46-
const nameFilter = (input, process_) => {
47-
const isPort = input[0] === ':';
48-
49-
if (isPort) {
50-
return process_.ports.find(port => port.startsWith(input.slice(1)));
51-
}
52-
53-
return process_.name.toLowerCase().includes(input.toLowerCase());
54-
};
55-
5647
const preferNotMatching = matches => (a, b) => {
5748
const aMatches = matches(a);
5849
return matches(b) === aMatches ? 0 : (aMatches ? 1 : -1);
@@ -99,22 +90,24 @@ const preferHeurisicallyInterestingProcesses = (a, b) => {
9990
};
10091

10192
const filterProcesses = (input, processes, flags) => {
102-
const filters = {
103-
name: process_ => input ? nameFilter(input, process_) : true,
104-
verbose: process_ => input ? (isWindows ? process_.name : process_.cmd).toLowerCase().includes(input.toLowerCase()) : true,
105-
};
106-
10793
const memoryThreshold = flags.verbose ? 0 : 1;
10894
const cpuThreshold = flags.verbose ? 0 : 3;
10995

110-
return processes
96+
const filteredProcesses = new FuzzySearch(
97+
processes,
98+
[flags.verbose && !isWindows ? 'cmd' : 'name'],
99+
{
100+
caseSensitive: false,
101+
},
102+
)
103+
.search(input);
104+
105+
return filteredProcesses
111106
.filter(process_ => !(
112107
process_.name.endsWith('-helper')
113108
|| process_.name.endsWith('Helper')
114109
|| process_.name.endsWith('HelperApp')
115110
))
116-
// eslint-disable-next-line unicorn/no-array-callback-reference
117-
.filter(flags.verbose ? filters.verbose : filters.name)
118111
.sort(preferHeurisicallyInterestingProcesses)
119112
.map(process_ => {
120113
const renderPercentage = percents => {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"cli-truncate": "^3.1.0",
4747
"esc-exit": "^3.0.0",
4848
"fkill": "^8.0.0",
49+
"fuzzy-search": "^3.2.1",
4950
"inquirer": "^8.2.0",
5051
"inquirer-autocomplete-prompt": "^1.4.0",
5152
"meow": "^10.1.1",

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ $ fkill --help
7171
7272
Run without arguments to use the interactive interface.
7373
In interactive mode, 🚦n% indicates high CPU usage and 🐏n% indicates high memory usage.
74+
Supports fuzzy search in the interactive mode.
7475
7576
The process name is case insensitive.
7677
```

test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import process from 'node:process';
12
import childProcess from 'node:child_process';
23
import test from 'ava';
34
import execa from 'execa';
@@ -23,6 +24,15 @@ test('pid', async t => {
2324
await noopProcessKilled(t, pid);
2425
});
2526

27+
// TODO: Remove the if-statement when https://github.com/nodejs/node/issues/35503 is fixed.
28+
if (process.platform === 'darwin') {
29+
test('fuzzy search', async t => {
30+
const pid = await noopProcess({title: '!noo00oop@'});
31+
await execa('./cli.js', ['o00oop@']);
32+
await noopProcessKilled(t, pid);
33+
});
34+
}
35+
2636
test('kill from port', async t => {
2737
const port = await getPort();
2838
const {pid} = childProcess.spawn('node', ['fixture.js', port]);

0 commit comments

Comments
 (0)