🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

這是GitHub Copilot CLI 挑戰賽的參賽作品

「我為什麼要建造這個?」的時刻

事情是這樣的。凌晨兩點我還在搗鼓一個 Rust 專案(誰不想呢),試圖搞清楚DeserializeOwned到底是在哪裡實現的。程式碼庫大概有五萬行,17 個不同的impl區塊散落在各處…就像有人在跟程式碼玩捉迷藏一樣,分散在八個檔案裡。

我坐在那裡思考我的選擇:

  • 啟動 VSCode 了嗎?我的 SSH 連線延遲比我週一早上的反應速度還慢。

  • grep ?當然,如果我想瀏覽 400 行垃圾輸出的話。

  • 試試用正規表示式的ripgrep ?我寧願除錯段錯誤,也不想在凌晨兩點再寫一個正規表示式。

  • 煮杯咖啡,假裝問題不存在?這主意不錯…

但你知道嗎?我實在忍無可忍,決定採取行動。

於是我開發了Oracle——內建在終端機的程式碼檢查器,而且用起來還不錯。為了進一步展示它的功能,我借助 GitHub Copilot 完成了程式碼的建置、審查、清理、優化和除錯,所有這些工作都在不到三天的時間內完成。


我建造的

所以🔮 Oracle本質上是一個基於終端的Rust程式碼檢查器。你可以把它想像成…如果grep和VSCode生了個孩子,而這個孩子長大後特別擅長理解Rust程式碼。沒有臃腫的圖形介面,沒有佔用記憶體的瀏覽器標籤頁,只有你的終端執行各種酷炫的操作。

它的功能如下:

📦 深度程式碼分析

你看,它能解析所有內容。我指的是所有內容

  • 函數(帶有那些酷炫的 async/const/unsafe 標誌,以及所有參數和返回類型)

  • 結構體(每個欄位、每個衍生型別、所有泛型-無需再瞇著眼睛看程式碼來弄清楚欄位類型)

  • 枚舉(它會顯示所有變體及其欄位類型)

  • 特徵(方法、相關類型、超特徵、作品)

  • 實作區塊(包括常規實作區塊和 trait 實作區塊)

  • 模組、型別別名、常數、靜態變數…基本上,Rust 能定義的東西,Oracle 都能展示出來。

🔍 智能搜尋

這項搜尋功能其實相當聰明(恕我自誇一下):

  • 輸入時即時更新的模糊匹配(底層使用fuzzy-matcher

  • 它具有上下文感知功能,因此當您在「函數」標籤中時,它只會搜尋函數(無需再瀏覽無關內容)。

  • 你可以搜尋類似這樣的函數,會得到像serde::de::Deserialize這樣的完整路徑,而且它確實有效。

  • 依可見度(公開/私有/倉庫層級)篩選內容

📋依賴項檢查器

這部分挺酷的——它會讀取你的Cargo.toml並顯示以下內容:

  • 你的整個依賴關係樹視覺化效果很好。

  • 來自 crates.io 的即時資訊(描述、GitHub 星標數、授權資訊)

  • 所有安裝在~/.cargo/registry資料夾中的 crate

  • o開啟 docs.rs,按c開啟 crates.io-瞬間開啟瀏覽器標籤頁!

🎨 精美主題

看來我連在終端設備方面都很注重美觀:

  • 預設深色(簡潔專業)

  • Nord(如果你喜歡冷調藍色)

  • Catppuccin 摩卡(溫馨氣氛)

  • 德古拉(獻給喜歡戲劇的人)

  • t即可循環切換

⚡ 流暢的動畫

沒錯,我為一個命令列工具加入了動畫效果。不服來辯。

  • 選定的高光平滑淡入

  • 切換標籤時不會感到突兀

  • 滾動時感覺非常流暢(如絲般順滑)

  • 即時語法高亮顯示

說實話,我在動畫上花了太多時間,但它們確實讓使用體驗非常棒。

Oracle 檢查器面板


示範

GitHub 程式碼庫: github.com/yashksaini-coder/oracle

快速入門

# Install from source
git clone https://github.com/yashksaini-coder/oracle.git
cd oracle
cargo install --path .

# Run on any Rust project
oracle /path/to/rust/project

# Or analyze current directory
oracle

範例用法

# Inspect a famous crate
cargo new test_project
cd test_project
cargo add tokio

# Launch Oracle
oracle

# Now press:
# - Tab 4 times to get to Crates tab
# - Navigate to "tokio"
# - Press Enter
# - Search for "copy" with /
# - Browse copy methods and implementations

箱子演示


我使用 GitHub Copilot CLI 的經驗

好吧,坦白說:這是我第一個真正意義上的 Rust 專案,而且還涉及終端 UI。我之前從來沒接觸過 Ratatui,對syn工作原理一竅不通,基本上都是邊做邊摸索。

GitHub Copilot CLI 簡直就是我的橡皮鴨、我的 Stack Overflow 和一位耐心的資深開發人員的三合一工具。最棒的是什麼?我根本不用離開終端。

🎯副駕駛如何拯救了我的理智

1. 與syn Crate 搏鬥

Rust 的syn crate 解析 Rust 程式碼非常棒,但學習曲線也太陡峭了。我需要提取函數簽名、結構體字段、枚舉變體、所有 trait 的邊界……基本上所有東西。

我盯著那些文件,感覺自己像是在讀古希臘語,於是我就問了副駕駛:

gh copilot suggest "parse rust struct with syn crate extract all fields and visibility"

它直接給了我這個:

use syn::{ItemStruct, Fields};

fn analyze_struct(st: &ItemStruct) -> Vec<Field> {
    match &st.fields {
        Fields::Named(named) => {
            named.named.iter().map(|f| Field {
                name: f.ident.as_ref().unwrap().to_string(),
                ty: quote!(#ty).to_string(),
                visibility: parse_visibility(&f.vis),
            }).collect()
        }
        // ... Tuple and Unit variants
    }
}

它就是這麼奏效的。這成了解析其他所有內容的基礎——枚舉、特性、實現塊等等。我只是擴展了這個模式來處理所有其他的 Rust 元素類型。

說實話?這大概幫我省了8到10個小時對著syn藥物文件瞎琢磨。值了。


2. 讓TUI看起來不像垃圾

我想要一個外觀漂亮的介面。不僅要功能齊全,還要用起來賞心悅目。面板、邊框、流暢的滾動效果,所有細節都要到位。

問題:Ratatui 的佈局系統讓我頭痛。這些東西到底該怎麼排版?

問副駕駛: gh copilot explain "ratatui layout constraints horizontal vertical split"

它解釋說,佈局基本上就像樂高積木一樣——你可以用Constraint::PercentageConstraint::Length來組合它們,並將它們嵌套起來以建立複雜的 UI。這讓我豁然開朗。

然後我就想: gh copilot suggest "ratatui scrollable panel with borders and title"

回覆如下:

let block = Block::default()
    .borders(Borders::ALL)
    .title(" Inspector ");

let paragraph = Paragraph::new(lines)
    .block(block)
    .scroll((scroll_offset as u16, 0));

太棒了。它成了我檢查面板的核心。後來,我透過對scroll_offset進行插值並使用一些緩動函數,加入了動畫效果(因為我就是這麼喜歡精益求精)。


3. 讓搜尋感覺更流暢

我希望搜尋體驗能像 VSCode 的 Ctrl+P 一樣——你知道的,就是你直接開始輸入,然後瞬間就能看到結果。沒有延遲,沒有廢話。

問 Copilot: gh copilot suggest "rust fuzzy search crate with scoring"

它推薦使用SkimMatcherV2fuzzy-matcher 。以下是我最終的配置:

use fuzzy_matcher::skim::SkimMatcherV2;

let matcher = SkimMatcherV2::default();
let scored: Vec<_> = items
    .iter()
    .filter_map(|item| {
        matcher.fuzzy_match(&item.name, query)
            .map(|score| (item, score))
    })
    .collect();

scored.sort_by(|a, b| b.1.cmp(&a.1)); // Highest score first

你猜怎麼著?第一次就完美執行了。無需除錯,無需調整,就這麼……成功了。這種時刻在程式設計上實屬難得,值得慶祝。


4. 解析 Cargo.toml 檔案而不崩潰

依賴關係和 Cargo.toml 檔案很快就會變得非常複雜,尤其是在使用工作區和傳遞依賴關係時。我需要解析所有這些內容並建立一個合適的依賴關係樹。

我一直很害怕這部分,直到我問了: gh copilot explain "cargo metadata crate rust get all dependencies"

原來有個叫cargo_metadata的 crate(誰能想到呢?)可以產生結構化的 JSON 輸出。 Copilot 向我展示了這一點:

  • 如何取得根包

  • 如何遍歷依賴樹

  • 如何區分直接依賴與傳遞依賴

  • 如何處理工作區箱子

以下是結果:

use cargo_metadata::MetadataCommand;

let metadata = MetadataCommand::new()
    .manifest_path(&manifest_path)
    .exec()?;

let root = metadata.root_package();
let dependencies = root.dependencies.iter()
    .filter(|d| d.kind == DependencyKind::Normal)
    .collect();

簡潔明了,而且真的有效。我喜歡這樣的程式碼。


5. 獲取活體箱子資訊

我希望在使用者瀏覽依賴項時顯示真實的 crate 資訊——描述、GitHub 星標數、授權資訊等等。這意味著需要呼叫 crates.io API。

我完全沒有 Rust 非同步 HTTP 的經驗: gh copilot suggest "rust async http request to crates.io api"

Copilot 向我推薦了reqwest ,並向我展示了後台線程的阻塞客戶端模式:

use reqwest::blocking::Client;

fn fetch_crate_docs(name: &str) -> Option<CrateDoc> {
    let client = Client::new();
    let url = format!("https://crates.io/api/v1/crates/{}", name);

    let response = client.get(&url).send().ok()?;
    let json: serde_json::Value = response.json().ok()?;

    Some(CrateDoc {
        name: json["crate"]["name"].as_str()?.to_string(),
        description: json["crate"]["description"].as_str().map(String::from),
        // ...
    })
}

然後我還需要GitHub倉庫的統計資料,所以我問如何解析GitHub URL並呼叫他們的API。也成功實現了這一點。

crates.io + GitHub 的整個集成只花了一個晚上就完成了,而如果用其他方式集成,可能需要…我不知道,一周的時間閱讀 API 文件?


6. 跨平台路徑地獄

你知道什麼最煩人嗎?文件路徑。 Windows 使用反斜線,Unix 使用正斜杠,而我需要將檔案路徑轉換為模組路徑( src/analyzer/parser.rs["analyzer", "parser"] )。

Q: gh copilot suggest "rust strip src directory from pathbuf get module path"

入手了這件美物:

fn derive_module_path(path: &Path) -> Vec<String> {
    path.iter()
        .skip_while(|c| c != &"src")
        .skip(1) // Skip "src" itself
        .map(|c| c.to_string_lossy().to_string())
        .collect()
}

可在 Windows、macOS 和 Linux 系統上運作。無需#[cfg]配置。即插即用。


7. 讓動畫不爛

好吧,我在這裡有點得意忘形了。我想要的是流暢的滾動效果,而不是大多數用戶介面那種生硬的跳躍式滾動。

問副駕駛: gh copilot suggest "rust easing functions ease in out cubic"

它給了我經典的緩動公式:

pub fn ease_out(t: f64) -> f64 {
    1.0 - (1.0 - t).powi(3)
}

pub fn ease_in_out(t: f64) -> f64 {
    if t < 0.5 {
        4.0 * t * t * t
    } else {
        1.0 - (-2.0 * t + 2.0).powi(3) / 2.0
    }
}

8. 將 Copilot 整合到自身內部

這時我已經深陷其中,想看看自己能做到什麼程度,於是決定給它加入一個完全由 Copilot 驅動的 AI 聊天介面區域,你猜怎麼著…

它真的有效!讓 Copilot 建構並整合到我的工具中,這簡直太不可思議了。

Oracle Copilot 集成

將這些方法應用於滾動偏移插值,瞧!流暢無比的 60fps 滾動效果瞬間實現。對於一個命令列工具來說,這完全沒必要嗎?沒錯。但我還是這麼做了?沒錯。


那些幾乎讓我崩潰的事

Oracle 建置挑戰小組

挑戰 1:解析大型專案時避免終端凍結

問題:我嘗試在tokio程式碼庫(包含 200 多個檔案)上執行 Oracle,結果終端直接…卡住了。整整 10 秒。完全沒有響應。太糟糕了。

解決方案:

我把所有解析操作都移到了後台線程,這樣使用者介面就能保持回應。我還加入了一個帶有波浪動畫的啟動畫面(既然用戶需要等待,至少要讓它看起來美觀一些)。此外,我還預先計算了搜尋索引,這樣就不會出現卡頓了。

Copilot 幫我理清了執行緒模式,以及如何在不阻塞使用者介面的情況下顯示進度。簡直是顛覆性的。


挑戰二:讓搜尋感覺即時(即使並非如此)

問題:當需要搜尋超過 10,000 個專案時,每次按鍵都需要約 100 毫秒。這延遲非常明顯,而且感覺很卡頓。

解決方案:

  • 僅在目前標籤頁內搜尋(例如,在「函數」標籤頁中,則僅搜尋函數)。

  • 僅顯示前 50 個結果(反正也沒人會往後翻)

  • 使用fuzzy-matcher的大量評分功能(比逐一評分更快)。

  • 重複查詢的快取搜尋結果

  • 螢幕上僅顯示可見專案

結果如何?現在每次按鍵搜尋耗時不到 16 毫秒。這相當於 60 幀/秒的流暢度。非常流暢。


挑戰 3:GitHub 的速率限制是真實存在的

問題: GitHub API 將未經身份驗證的請求限制為每小時 60 次。我在測試 crates.io 功能時幾乎立即就達到了這個限制。

解決方案:

  • 新增對GITHUB_TOKEN環境變數的支援(經過驗證後每小時可獲得 5000 個代幣)

  • 每個 crate 的回應都已緩存,因此我們不會重複獲取。

  • 速率受限時的優雅回退(僅顯示“速率受限”而不是崩潰)

  • 給用戶加入了一條提示:“設定 GITHUB_TOKEN 以獲得更多請求”

Copilot 幫助我了解 GitHub API 的身份驗證流程以及如何解析速率限制標頭。現在好多了。


挑戰 4:不糟糕的可滾動內容

問題:選取一個專案後,檢查面板會顯示其所有詳細資訊。但如果文件很長怎麼辦?訊息會被截斷。這很不理想。

解決方案:

需要追蹤每個選定專案的滾動偏移量,綁定j/k和方向鍵上下滾動,內容溢出時顯示滾動條指示器,切換專案時重置滾動位置。

Copilot 向我展示了 Ratatui 的Scrollbar元件以及如何正確管理滾動狀態。現在用起來很棒。


為什麼可能真的想用它

🚀 速度很快(真的很快)

  • 不到 2 秒即可解析 200 多個文件

  • 搜尋響應速度極快(每次按鍵響應時間小於 16 毫秒)

  • 60fps動畫(是的,在終端機中)

  • 本機分析無需任何網路呼叫(您的程式碼永遠不會離開您的電腦)

🎨看起來不像垃圾

  • 4 個手工打造的主題(Nord 簡直完美)

  • 平滑滾動並帶有緩動效果(因為我有標準)

  • 上下文感知型使用者介面(函數顯示參數提示,結構體顯示欄位類型)

  • 專業文件格式

🔧 專為終端使用而設計

  • 透過 SSH 完美執行(無需圖形介面,無需 X 轉發之類的東西)

  • Vim風格的快捷鍵綁定( j/k萬歲)

  • 一條指令: oracle就這麼簡單。

  • 可透過cargo install安裝(一旦我將其發佈到 crates.io)。

📚 它真的理解 Rust

大多數程式碼搜尋工具其實就是功能更強大的 grep 指令。 Oracle:

  • 分析所有 Rust 項類型(函數、結構體、枚舉、trait、實作、模組)

  • 顯示合格路徑( serde::de::Deserialize運作正常)

  • 能夠正確處理可見性修改器。

  • 理解泛型、生命週期、特性邊界、async、const、unsafe——所有這些概念

它不僅會搜尋你的程式碼,還會理解你的程式碼。


我實際上如何使用這東西

在Oracle出現之前:

# Trying to find all trait implementations
rg "impl.*for" | less  # Scroll through 200 lines of noise

# Trying to understand a struct
rg "struct Config" -A 20 | grep "pub"  # Miss half the fields

# Finding function signatures
rg "pub fn connect"  # Get incomplete matches without parameters

使用 Oracle:

oracle
# Tab to Functions, type "connect", press Enter
# See:
#   - Full signature with all parameters and types
#   - Complete documentation
#   - Return type with error handling
#   - Source location (file + line number)
# Press 'o' to open in your editor

它速度快得多,而且沒那麼煩人。

另一個例子:你在專案中加入了tokio ,並且想要了解spawn工作原理。

舊方法:

  1. 克隆 tokio 倉庫

  2. grep 查找“pub fn spawn”

  3. 獲得 47 個匹配項

  4. 試著找出哪一個才是正確的。

  5. 放棄吧,直接去看文件。

使用 Oracle:

oracle ~/.cargo/registry/src/*/tokio-*
# Press 4 for Crates tab
# Navigate to "tokio", press Enter
# Type "spawn" in search
# See signature, docs, parameters, trait bounds
# Press 'o' for docs.rs if you want more details

節省時間:每次約 5 分鐘。

箱子選項卡演示


安裝與使用

安裝

# From source (recommended for now)
git clone https://github.com/yashksaini-coder/oracle.git
cd oracle
cargo install --path .

# Or use cargo directly (once published)
cargo install oracle-tui

用法

# Analyze current directory
oracle

# Analyze specific project
oracle ~/code/my-rust-project

# Set GitHub token for better crate.io API limits
export GITHUB_TOKEN=ghp_yourtoken
oracle

接下來會發生什麼(如果人們真的會使用它)

對未來的版本有一些想法:

  • 符號引用:顯示函數/類型實際使用的位置(這將非常有用)

  • 跳到定義:按任意鍵,開啟來源檔案並跳到指定行。

  • 巨集展開檢視器:看看那些晦澀難懂的巨集展開後會變成什麼樣子。

  • 呼叫圖視覺化:顯示哪些函數呼叫了哪些函數(可能會有點混亂,但很酷)

  • Git 整合:顯示每個專案最近的更改,例如“此函數在 3 天前進行了修改”

  • 匯出為 JSON/HTML:從程式碼庫產生靜態文件

  • LSP 整合:接取 rust-analytics 進行更深入的分析

時間方面我無法保證。這只是我因為一時煩躁而臨時拼湊起來的副業專案。


為什麼選擇 Rust?

效能:解析過程受 CPU 限制。 Rust 的零成本抽象表示解析速度快,無需垃圾回收暫停。

安全性:遍歷複雜抽象語法樹時未出現段錯誤。借用檢查器在開發過程中捕獲了 20 多個錯誤。

生態系: syn是 Rust 解析ratatui黃金標準。 ratatui 讓建造 TUI 變得真正有趣。

跨平台:一個二進位檔案即可在 Linux、macOS、Windows 上運作-無需 Python/Node 執行環境。


經驗教訓

1. TUI 狀態管理很難

同時管理焦點、捲動位置、搜尋狀態和動畫比管理 React 狀態要複雜得多。我不得不建造一個小型狀態機。

2.解析成本很高

即使使用syn的快速解析器,分析 200 多個檔案也需要時間。不得不進行優化:

  • 延遲載入(僅解析可見項)

  • 快取已解析結果

  • 繁重工作的背景線索

3.終端渲染很微妙

繪製頻率過高會導致畫面閃爍,繪製頻率過低則會感覺卡頓。最後找到了最佳平衡點:動畫執行時 60fps,空閒時 10fps。

4. Copilot CLI 是力量倍增器

說真的,讓人工智慧解釋syn模式、Ratatui佈局、非同步模式、緩動公式——所有這些都無需離開終端機——真是太不可思議了。


總結

是的,這就是 Oracle。我發展它是因為我對現有的工具感到不滿,在這個過程中,我學到了很多關於 Rust、TUI 和解析方面的知識。

GitHub Copilot CLI 簡直是我的救星。它就像一個人工智慧,能解釋syn模式、顯示 Ratatui 佈局、幫助我理解非同步模式,甚至提供緩動公式——所有這些都無需離開我的終端——簡直太棒了。它幫我節省了 30 多個小時閱讀文件和 Stack Overflow 的時間。

最終我得到了一個工具,現在我每天都在使用。每次複製新的 Rust 專案時,我都會先執行oracle來了解專案概況。這已經成為我工作流程的一部分了。

如果你使用 Rust,不妨試試。最壞的情況,你只是浪費了 2 分鐘安裝而已。最好的情況,它會改變你探索程式碼的方式。


連結:

任何反饋?發現bug?想要新增功能?請提交issue或留言。我都會認真閱讀。


這個專案是用太多的咖啡、Rust、Ratatui 和 GitHub Copilot CLI 建造的,它們絕對是傳奇。

{% cta link https://github.com/yashksaini-coder/oracle %} 星狀 Oracle {% endcta %}

如果你喜歡這篇文章,請考慮給它一個讚。這會讓我對自己的選擇感到欣慰。 ⭐

開發挑戰賽 #GitHub挑戰賽 #CLI #Rust #TUI #開源


原文出處:https://dev.to/yashksaini/i-built-a-tui-that-makes-rust-code-inspection-feel-like-magic-375k


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝21   💬3  
560
🥈
我愛JS
📝1   💬5   ❤️2
66
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付