mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Autocomplete popular package names (thanks @evanwashere)
This commit is contained in:
@@ -16,6 +16,18 @@ function __fish__get_bun_scripts
|
|||||||
string trim (string split '\n' (string split '\t' (bun getcompletes z)))
|
string trim (string split '\n' (string split '\t' (bun getcompletes z)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function __fish__get_bun_packages
|
||||||
|
if test (commandline -ct) != ""
|
||||||
|
set -lx SHELL fish
|
||||||
|
string split ' ' (bun getcompletes a (commandline -ct))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function __history_completions
|
||||||
|
set -l tokens (commandline --current-process --tokenize)
|
||||||
|
history --prefix (commandline) | string replace -r \^$tokens[1]\\s\* "" | string replace -r \^$tokens[2]\\s\* "" | string split ' '
|
||||||
|
end
|
||||||
|
|
||||||
function __fish__get_bun_bun_js_files
|
function __fish__get_bun_bun_js_files
|
||||||
string split ' ' (bun getcompletes j)
|
string split ' ' (bun getcompletes j)
|
||||||
end
|
end
|
||||||
@@ -129,9 +141,9 @@ complete -c bun \
|
|||||||
-n "not __fish_seen_subcommand_from $bun_builtin_cmds_without_pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts); and __fish_seen_subcommand_from install add remove;" -l 'cache-dir' -d 'Choose a cache directory (default: $HOME/.bun/install/cache)'
|
-n "not __fish_seen_subcommand_from $bun_builtin_cmds_without_pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts); and __fish_seen_subcommand_from install add remove;" -l 'cache-dir' -d 'Choose a cache directory (default: $HOME/.bun/install/cache)'
|
||||||
|
|
||||||
complete -c bun \
|
complete -c bun \
|
||||||
-n "not __fish_seen_subcommand_from $bun_builtin_cmds_without_pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts); and __fish_seen_subcommand_from add remove;" -d "Add a folder to package.json"
|
-n "not __fish_seen_subcommand_from $bun_builtin_cmds_without_pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts); and __fish_seen_subcommand_from add;" -d 'Popular' -a '(__fish__get_bun_packages)'
|
||||||
|
|
||||||
complete -c bun \
|
complete -c bun \
|
||||||
-n "not __fish_seen_subcommand_from $bun_builtin_cmds_without_pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts); and __fish_seen_subcommand_from add;" -F
|
-n "not __fish_seen_subcommand_from $bun_builtin_cmds_without_pm; and not __fish_seen_subcommand_from (__fish__get_bun_bins) (__fish__get_bun_scripts); and __fish_seen_subcommand_from add;" -d 'History' -a '(__history_completions)'
|
||||||
|
|
||||||
complete -c bun --no-files
|
complete -c bun --no-files
|
||||||
@@ -55,8 +55,9 @@ _bun() {
|
|||||||
ret=0
|
ret=0
|
||||||
|
|
||||||
case $state in
|
case $state in
|
||||||
package) ;;
|
package)
|
||||||
|
_bun_add_param_package_completion
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
;;
|
;;
|
||||||
@@ -497,6 +498,39 @@ _bun_run_param_script_completion() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_set_remove() {
|
||||||
|
comm -23 <(echo $1 | sort | tr " " "\n") <(echo $2 | sort | tr " " "\n") 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
_bun_add_param_package_completion() {
|
||||||
|
|
||||||
|
IFS=$'\n' inexact=($(history -n bun | grep -E "^bun add " | cut -c 9- | uniq))
|
||||||
|
IFS=$'\n' exact=($($inexact | grep -E "^$words[$CURRENT]"))
|
||||||
|
IFS=$'\n' packages=($(SHELL=zsh bun getcompletes a $words[$CURRENT]))
|
||||||
|
|
||||||
|
to_print=$inexact
|
||||||
|
if [ ! -z "$exact" -a "$exact" != " " ]; then
|
||||||
|
to_print=$exact
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$to_print" -a "$to_print" != " " ]; then
|
||||||
|
if [ ! -z "$packages" -a "$packages" != " " ]; then
|
||||||
|
_describe -1 -t to_print 'History' to_print
|
||||||
|
_describe -1 -t packages "Popular" packages
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
_describe -1 -t to_print 'History' to_print
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$packages" -a "$packages" != " " ]; then
|
||||||
|
_describe -1 -t packages "Popular" packages
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
__bun_dynamic_comp() {
|
__bun_dynamic_comp() {
|
||||||
local comp=""
|
local comp=""
|
||||||
|
|
||||||
|
|||||||
52
src/cli.zig
52
src/cli.zig
@@ -536,6 +536,8 @@ pub const HelpCommand = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AddCompletions = @import("./cli/add_completions.zig");
|
||||||
|
|
||||||
pub const PrintBundleCommand = struct {
|
pub const PrintBundleCommand = struct {
|
||||||
pub fn exec(ctx: Command.Context) !void {
|
pub fn exec(ctx: Command.Context) !void {
|
||||||
const entry_point = ctx.args.entry_points[0];
|
const entry_point = ctx.args.entry_points[0];
|
||||||
@@ -723,7 +725,7 @@ pub const Command = struct {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var prefilled_completions: [AddCompletions.biggest_list]string = undefined;
|
||||||
var completions = ShellCompletions{};
|
var completions = ShellCompletions{};
|
||||||
|
|
||||||
if (filter.len == 0) {
|
if (filter.len == 0) {
|
||||||
@@ -742,8 +744,54 @@ pub const Command = struct {
|
|||||||
completions = try RunCommand.completions(ctx, null, &reject_list, .bun_js);
|
completions = try RunCommand.completions(ctx, null, &reject_list, .bun_js);
|
||||||
} else if (strings.eqlComptime(filter[0], "z")) {
|
} else if (strings.eqlComptime(filter[0], "z")) {
|
||||||
completions = try RunCommand.completions(ctx, null, &reject_list, .script_and_descriptions);
|
completions = try RunCommand.completions(ctx, null, &reject_list, .script_and_descriptions);
|
||||||
}
|
} else if (strings.eqlComptime(filter[0], "a")) {
|
||||||
|
const FirstLetter = AddCompletions.FirstLetter;
|
||||||
|
const index = AddCompletions.index;
|
||||||
|
|
||||||
|
outer: {
|
||||||
|
if (filter.len > 1) {
|
||||||
|
const first_letter: FirstLetter = switch (filter[1][0]) {
|
||||||
|
'a' => FirstLetter.a,
|
||||||
|
'b' => FirstLetter.b,
|
||||||
|
'c' => FirstLetter.c,
|
||||||
|
'd' => FirstLetter.d,
|
||||||
|
'e' => FirstLetter.e,
|
||||||
|
'f' => FirstLetter.f,
|
||||||
|
'g' => FirstLetter.g,
|
||||||
|
'h' => FirstLetter.h,
|
||||||
|
'i' => FirstLetter.i,
|
||||||
|
'j' => FirstLetter.j,
|
||||||
|
'k' => FirstLetter.k,
|
||||||
|
'l' => FirstLetter.l,
|
||||||
|
'm' => FirstLetter.m,
|
||||||
|
'n' => FirstLetter.n,
|
||||||
|
'o' => FirstLetter.o,
|
||||||
|
'p' => FirstLetter.p,
|
||||||
|
'q' => FirstLetter.q,
|
||||||
|
'r' => FirstLetter.r,
|
||||||
|
's' => FirstLetter.s,
|
||||||
|
't' => FirstLetter.t,
|
||||||
|
'u' => FirstLetter.u,
|
||||||
|
'v' => FirstLetter.v,
|
||||||
|
'w' => FirstLetter.w,
|
||||||
|
'x' => FirstLetter.x,
|
||||||
|
'y' => FirstLetter.y,
|
||||||
|
'z' => FirstLetter.z,
|
||||||
|
else => break :outer,
|
||||||
|
};
|
||||||
|
const results = index.get(first_letter);
|
||||||
|
|
||||||
|
var prefilled_i: usize = 0;
|
||||||
|
for (results) |cur| {
|
||||||
|
if (cur.len == 0 or !strings.hasPrefix(cur, filter[1])) continue;
|
||||||
|
prefilled_completions[prefilled_i] = cur;
|
||||||
|
prefilled_i += 1;
|
||||||
|
if (prefilled_i >= prefilled_completions.len) break;
|
||||||
|
}
|
||||||
|
completions.commands = prefilled_completions[0..prefilled_i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
completions.print();
|
completions.print();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
9997
src/cli/add_completions.txt
Normal file
9997
src/cli/add_completions.txt
Normal file
File diff suppressed because it is too large
Load Diff
99
src/cli/add_completions.zig
Normal file
99
src/cli/add_completions.zig
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
pub const add_completions: []const u8 = @embedFile("add_completions.txt");
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const FirstLetter = enum(u8) {
|
||||||
|
a = 'a',
|
||||||
|
b = 'b',
|
||||||
|
c = 'c',
|
||||||
|
d = 'd',
|
||||||
|
e = 'e',
|
||||||
|
f = 'f',
|
||||||
|
g = 'g',
|
||||||
|
h = 'h',
|
||||||
|
i = 'i',
|
||||||
|
j = 'j',
|
||||||
|
k = 'k',
|
||||||
|
l = 'l',
|
||||||
|
m = 'm',
|
||||||
|
n = 'n',
|
||||||
|
o = 'o',
|
||||||
|
p = 'p',
|
||||||
|
q = 'q',
|
||||||
|
r = 'r',
|
||||||
|
s = 's',
|
||||||
|
t = 't',
|
||||||
|
u = 'u',
|
||||||
|
v = 'v',
|
||||||
|
w = 'w',
|
||||||
|
x = 'x',
|
||||||
|
y = 'y',
|
||||||
|
z = 'z',
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Index = std.EnumArray(FirstLetter, []const []const u8);
|
||||||
|
pub const index: Index = brk: {
|
||||||
|
var array: Index = Index.initFill(&[_][]const u8{});
|
||||||
|
|
||||||
|
var i: u8 = 'a';
|
||||||
|
var tokenizer = std.mem.tokenize(u8, add_completions, "\n");
|
||||||
|
var last_index: usize = 0;
|
||||||
|
var last_len: usize = 0;
|
||||||
|
while (i <= 'z') {
|
||||||
|
var init_tokenizer = tokenizer;
|
||||||
|
var count: usize = 0;
|
||||||
|
@setEvalBranchQuota(9999999);
|
||||||
|
while (init_tokenizer.next()) |pkg| {
|
||||||
|
if (pkg.len == 0) continue;
|
||||||
|
if (pkg[0] == i) {
|
||||||
|
count += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var record: [count][]const u8 = undefined;
|
||||||
|
var record_i: usize = 0;
|
||||||
|
var next_i = i + 1;
|
||||||
|
|
||||||
|
while (tokenizer.next()) |pkg| {
|
||||||
|
if (pkg.len == 0) continue;
|
||||||
|
|
||||||
|
if (pkg[0] == i) {
|
||||||
|
record[record_i] = pkg;
|
||||||
|
record_i += 1;
|
||||||
|
} else {
|
||||||
|
next_i = pkg[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array.set(@intToEnum(FirstLetter, i), &record);
|
||||||
|
|
||||||
|
@setEvalBranchQuota(999999);
|
||||||
|
i = next_i;
|
||||||
|
}
|
||||||
|
break :brk array;
|
||||||
|
};
|
||||||
|
pub const biggest_list: usize = brk: {
|
||||||
|
var a = index;
|
||||||
|
var iter = a.iterator();
|
||||||
|
var max: usize = 0;
|
||||||
|
while (iter.next()) |list| {
|
||||||
|
max = @maximum(list.value.len, max);
|
||||||
|
}
|
||||||
|
break :brk max;
|
||||||
|
};
|
||||||
|
|
||||||
|
const index_blob = "add_completions.index.blob";
|
||||||
|
|
||||||
|
test "entries" {
|
||||||
|
const items = index.get(FirstLetter.r);
|
||||||
|
var found_react = false;
|
||||||
|
for (items) |item| {
|
||||||
|
try std.testing.expectEqual(item[0], 'r');
|
||||||
|
if (std.mem.eql(u8, item, "react")) {
|
||||||
|
found_react = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try std.testing.expect(found_react);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user