update fixing the build of the app
This commit is contained in:
+25
-19
@@ -1,4 +1,3 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { relative, sep } from 'node:path'
|
||||
import { getConfig } from './config'
|
||||
@@ -6,18 +5,23 @@ import { getConfig } from './config'
|
||||
/** ripgrep is the single source of "what files are in the project": it powers
|
||||
* content search, the file-name list, AND the Explorer tree / content index
|
||||
* (via fs-service) — so gitignore + files.exclude are honored everywhere the
|
||||
* same way. Substring (fixed-string), smart-case search. */
|
||||
const require = createRequire(import.meta.url)
|
||||
|
||||
let rgPath: string | null = null
|
||||
try {
|
||||
rgPath = (require('@vscode/ripgrep') as { rgPath: string }).rgPath
|
||||
// When packaged the binary is unpacked from the asar; rgPath still points
|
||||
// inside app.asar, so redirect it. No-op in dev (path has no app.asar).
|
||||
if (rgPath) rgPath = rgPath.replace(/\bapp\.asar\b/, 'app.asar.unpacked')
|
||||
} catch (e) {
|
||||
console.error('[helder] @vscode/ripgrep unavailable:', (e as Error).message)
|
||||
}
|
||||
* same way. Substring (fixed-string), smart-case search.
|
||||
*
|
||||
* @vscode/ripgrep ships as ESM, so load it with dynamic import() (works for
|
||||
* ESM and CJS) and cache the resolved binary path. */
|
||||
const rgPathPromise: Promise<string | null> = (async () => {
|
||||
try {
|
||||
const mod = await import('@vscode/ripgrep')
|
||||
let p = (mod as { rgPath: string }).rgPath
|
||||
// When packaged the binary is unpacked from the asar; rgPath still points
|
||||
// inside app.asar, so redirect it. No-op in dev (path has no app.asar).
|
||||
if (p) p = p.replace(/\bapp\.asar\b/, 'app.asar.unpacked')
|
||||
return p || null
|
||||
} catch (e) {
|
||||
console.error('[helder] @vscode/ripgrep unavailable:', (e as Error).message)
|
||||
return null
|
||||
}
|
||||
})()
|
||||
|
||||
export interface ContentHit { no: number; ln: string; ix: number }
|
||||
export interface ContentGroup { path: string; hits: ContentHit[] }
|
||||
@@ -31,8 +35,8 @@ const BASE_IGNORE = [
|
||||
const MAX_FILES = 400
|
||||
const MAX_LINE = 1000
|
||||
|
||||
export function rgAvailable(): boolean {
|
||||
return !!rgPath
|
||||
export async function rgAvailable(): Promise<boolean> {
|
||||
return !!(await rgPathPromise)
|
||||
}
|
||||
|
||||
/** Glob/ignore args derived from config (files.exclude, files.followGitignore). */
|
||||
@@ -49,9 +53,10 @@ function toRel(root: string, p: string): string {
|
||||
return relative(root, p).split(sep).join('/')
|
||||
}
|
||||
|
||||
export function searchContent(root: string, query: string): Promise<ContentGroup[]> {
|
||||
export async function searchContent(root: string, query: string): Promise<ContentGroup[]> {
|
||||
const rgPath = await rgPathPromise
|
||||
if (!rgPath || query.trim().length < 2) return []
|
||||
return new Promise((resolve) => {
|
||||
if (!rgPath || query.trim().length < 2) return resolve([])
|
||||
const child = spawn(rgPath, [
|
||||
'--json', '--fixed-strings', '--smart-case', '--hidden',
|
||||
'--max-count', '50', '--max-columns', '2000',
|
||||
@@ -90,9 +95,10 @@ export function searchContent(root: string, query: string): Promise<ContentGroup
|
||||
|
||||
/** All project files (relative paths), honoring gitignore + excludes. Includes
|
||||
* dotfiles (--hidden) so .env etc. show up unless ignored. */
|
||||
export function listFiles(root: string): Promise<string[]> {
|
||||
export async function listFiles(root: string): Promise<string[]> {
|
||||
const rgPath = await rgPathPromise
|
||||
if (!rgPath) return []
|
||||
return new Promise((resolve) => {
|
||||
if (!rgPath) return resolve([])
|
||||
const child = spawn(rgPath, ['--files', '--hidden', ...ignoreArgs(), '--', root])
|
||||
let buf = ''
|
||||
const out: string[] = []
|
||||
|
||||
Reference in New Issue
Block a user