Last active
November 3, 2024 13:07
-
-
Save PEZ/9ddc84f43f017cfa2c64efe81b02e057 to your computer and use it in GitHub Desktop.
Joyride script for adding fuzzy search in files with instant previews to VS Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns fuzzy | |
(:require ["vscode" :as vscode] | |
[clojure.string :as string] | |
[joyride.core :as joyride] | |
[promesa.core :as p])) | |
(defn- get-configured-exclude-patterns! [] | |
(->> ["search.exclude" "files.exclude"] | |
(mapcat (fn [config-key] | |
(-> (.get (vscode/workspace.getConfiguration) config-key) | |
(js/Object.entries) | |
(.filter (fn [[_k v]] v)) | |
(.map (fn [[k _v]] k))))) | |
set)) | |
(defn- make-exclude-pattern! [] | |
(str "{" (string/join "," (get-configured-exclude-patterns!)) "}")) | |
(defn- find-files!+ [] | |
(p/let [excludes (make-exclude-pattern!)] | |
(vscode/workspace.findFiles "**/*" excludes))) | |
(defn- uri->line-items!+ [max-file-loc uri] | |
(p/let [data (vscode/workspace.fs.readFile uri) | |
relative-path (vscode/workspace.asRelativePath uri)] | |
(if (.includes data 0) ; Excludes binary files | |
[] | |
(let [lines (-> data (.toString "utf8") (.split "\n"))] | |
(if (and max-file-loc | |
(> (count lines) max-file-loc)) | |
(do | |
(.appendLine (joyride/output-channel) (str "Excluding: " relative-path " (too many lines:" (count lines) ")")) | |
[]) | |
(keep-indexed (fn [idx line] | |
(when-not (string/blank? line) | |
#js {:label (str (.trim line) " - " relative-path) | |
:detail (str relative-path ", Line: " (inc idx)) | |
:uri uri | |
:range (vscode/Range. idx (.search line #"\S") idx (count line))})) | |
lines)))))) | |
(defn- uris->line-items!+ [max-file-loc uris] | |
(p/let [line-items (p/all (map (partial uri->line-items!+ max-file-loc) uris))] | |
(apply concat line-items))) | |
(def ^:private !decorated-editor (atom nil)) | |
(def line-decoration-type | |
(vscode/window.createTextEditorDecorationType #js {:backgroundColor "rgba(255,255,255,0.15)"})) | |
(defn- clear-decorations! [editor] | |
(.setDecorations editor line-decoration-type #js [])) | |
(defn- highlight-item! [item preview?] | |
(when (some-> item .-range) | |
(p/let [document (vscode/workspace.openTextDocument (.-uri item)) | |
editor (vscode/window.showTextDocument document #js {:preview preview? :preserveFocus preview?}) | |
range (.-range item)] | |
(.revealRange editor range vscode/TextEditorRevealType.InCenter) | |
(clear-decorations! editor) | |
(if preview? | |
(do | |
(.setDecorations editor line-decoration-type #js [range]) | |
(reset! !decorated-editor editor)) | |
(set! (.-selection editor) | |
(vscode/Selection. (.-start range) (.-start range))))))) | |
(defn show-search-box! [max-file-loc] | |
(p/let [uris (find-files!+) | |
all-items (uris->line-items!+ max-file-loc uris) | |
loc-item #js {:label "$(list-ordered)" | |
:description (str "Workspace LOC: " (count all-items))} | |
quick-pick (vscode/window.createQuickPick)] | |
(set! (.-items quick-pick) (into-array (concat [loc-item] all-items))) | |
(set! (.-title quick-pick) "Fuzzy file search") | |
(set! (.-placeHolder quick-pick) "Use `foo*bar` to match `foo<whatever>bar`") | |
(set! (.-matchOnDetail quick-pick) true) | |
(doto quick-pick | |
(.onDidChangeActive (fn [active-items] | |
(highlight-item! (first active-items) true))) | |
(.onDidAccept (fn [_e] | |
(highlight-item! (first (.-selectedItems quick-pick)) false) | |
(.dispose quick-pick))) | |
(.onDidHide (fn [_e] | |
(.dispose quick-pick) | |
(when-let [editor @!decorated-editor] | |
(clear-decorations! editor)))) | |
(.show)))) | |
(when (= (joyride/invoked-script) joyride/*file*) | |
(show-search-box! nil)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"key": "ctrl+alt+f", | |
"command": "joyride.runCode", | |
"args": "(require 'fuzzy :reload) (fuzzy/show-search-box! 3000)" | |
}, |
A scrappy fiddle of a Joyride script that uses VS Code fuzzy search for quickpick menus to implement a quick file content search UI.
It is snappy for up to 10K LOC on my Mac, and a bit beyond that. But at 100K it starts to lag. Mostly VS Codes fuzzy search that lags here, so it may improve when VS Code improves.
There are basically two mechanisms to mitigate this:
- It uses your settings for files and search excludes to avoid indexing to many lines (also avoid finding stuff you are not interested in.).
- The
fuzzy/show-search-box!
function takes an argument for max file size (in lines-of-code) to include. In the Joyride output channel any files excluded by this filter are reported. You can use this to get hints of what may be lacking in your search excludes settings.
It is amazing. Thank you so much!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
joyride-fuzzy-searcher.mp4