104 lines
2.1 KiB
TypeScript
104 lines
2.1 KiB
TypeScript
import { ripgrep } from "ripgrep"
|
|
|
|
function env() {
|
|
const env = Object.fromEntries(
|
|
Object.entries(process.env).filter((item): item is [string, string] => item[1] !== undefined),
|
|
)
|
|
delete env.RIPGREP_CONFIG_PATH
|
|
return env
|
|
}
|
|
|
|
function opts(cwd: string) {
|
|
return {
|
|
env: env(),
|
|
preopens: { ".": cwd },
|
|
}
|
|
}
|
|
|
|
type Run = {
|
|
kind: "files" | "search"
|
|
cwd: string
|
|
args: string[]
|
|
}
|
|
|
|
function text(input: unknown) {
|
|
if (typeof input === "string") return input
|
|
if (input instanceof ArrayBuffer) return Buffer.from(input).toString()
|
|
if (ArrayBuffer.isView(input)) return Buffer.from(input.buffer, input.byteOffset, input.byteLength).toString()
|
|
return String(input)
|
|
}
|
|
|
|
function error(input: unknown) {
|
|
if (input instanceof Error) {
|
|
return {
|
|
message: input.message,
|
|
name: input.name,
|
|
stack: input.stack,
|
|
}
|
|
}
|
|
|
|
return {
|
|
message: String(input),
|
|
}
|
|
}
|
|
|
|
function clean(file: string) {
|
|
return file.replace(/^\.[\\/]/, "")
|
|
}
|
|
|
|
onmessage = async (evt: MessageEvent<Run>) => {
|
|
const msg = evt.data
|
|
|
|
try {
|
|
if (msg.kind === "search") {
|
|
const ret = await ripgrep(msg.args, {
|
|
buffer: true,
|
|
...opts(msg.cwd),
|
|
})
|
|
postMessage({
|
|
type: "result",
|
|
code: ret.code ?? 0,
|
|
stdout: ret.stdout ?? "",
|
|
stderr: ret.stderr ?? "",
|
|
})
|
|
return
|
|
}
|
|
|
|
let buf = ""
|
|
let err = ""
|
|
const out = {
|
|
write(chunk: unknown) {
|
|
buf += text(chunk)
|
|
const lines = buf.split(/\r?\n/)
|
|
buf = lines.pop() || ""
|
|
for (const line of lines) {
|
|
if (line) postMessage({ type: "line", line: clean(line) })
|
|
}
|
|
},
|
|
}
|
|
const stderr = {
|
|
write(chunk: unknown) {
|
|
err += text(chunk)
|
|
},
|
|
}
|
|
|
|
const ret = await ripgrep(msg.args, {
|
|
stdout: out,
|
|
stderr,
|
|
...opts(msg.cwd),
|
|
})
|
|
|
|
if (buf) postMessage({ type: "line", line: clean(buf) })
|
|
postMessage({
|
|
type: "done",
|
|
code: ret.code ?? 0,
|
|
stderr: err,
|
|
})
|
|
} catch (err) {
|
|
postMessage({
|
|
type: "error",
|
|
error: error(err),
|
|
})
|
|
}
|
|
}
|