如何在Linux上通过CLI或代码获取VS Code最近打开的文件/文件夹/工作区
实现VS Code最近工作区搜索(Arch Linux + Hyprland)
一、先搞定最近记录的获取
VS Code在Linux下的最近打开记录存在SQLite数据库~/.config/Code/User/globalStorage/state.vscdb,也可以直接用CLI命令提取:
- 优先用VS Code自带CLI命令(部分版本支持,输出更简洁):
code --list-recent-workspaces
- 如果CLI命令不生效,直接解析SQLite数据库:
sqlite3 ~/.config/Code/User/globalStorage/state.vscdb "SELECT value FROM ItemTable WHERE key='history.recentlyOpenedPathsList'"
得到JSON数据后,用jq解析提取entries数组里的path字段,再过滤掉已删除的无效路径即可。
二、方案1:Shell脚本 + Rofi/Wofi(Wayland适配)
步骤1:编写记录提取脚本
创建~/.local/bin/code-recent.sh,内容如下:
#!/bin/bash # 尝试用CLI命令获取最近记录 if command -v code &> /dev/null; then recent_paths=$(code --list-recent-workspaces 2>/dev/null) # CLI失败则用SQLite解析 if [ -z "$recent_paths" ]; then json_data=$(sqlite3 ~/.config/Code/User/globalStorage/state.vscdb "SELECT value FROM ItemTable WHERE key='history.recentlyOpenedPathsList'") recent_paths=$(echo "$json_data" | jq -r '.entries[]?.path' | grep -v '^null$' | sort -u) fi else echo "VS Code未安装" exit 1 fi # 过滤不存在的路径 valid_paths=() while read -r path; do [ -e "$path" ] && valid_paths+=("$path") done <<< "$recent_paths" # 输出「显示名|完整路径」格式,方便启动器解析 for path in "${valid_paths[@]}"; do echo "$(basename "$path")|$path" done
给脚本加执行权限:chmod +x ~/.local/bin/code-recent.sh
步骤2:绑定快捷键到Hyprland
编辑~/.config/hypr/hyprland.conf,添加快捷键绑定:
# 用Rofi调用脚本(Xwayland兼容) bind = $mainMod, O, exec, ~/.local/bin/code-recent.sh | rofi -dmenu -p "VS Code Recent" -sep "|" -format d | xargs code # 用Wayland原生的wofi(推荐Hyprland使用) bind = $mainMod, O, exec, ~/.local/bin/code-recent.sh | wofi --dmenu -p "VS Code Recent" --separator "|" --format d | xargs code
按Super+O即可调出搜索框,选中条目后直接用VS Code打开对应工作区/文件夹。
三、方案2:在zlaunch中用Rust实现
步骤1:添加依赖到Cargo.toml
[dependencies] sqlite = "0.31.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" dirs = "5.0.1"
步骤2:编写记录读取逻辑
use sqlite::Connection; use serde::Deserialize; use std::fs; use dirs::home_dir; #[derive(Debug, Deserialize)] struct RecentlyOpened { entries: Vec<Entry>, } #[derive(Debug, Deserialize)] struct Entry { path: Option<String>, } fn get_code_recent_paths() -> Vec<String> { let db_path = home_dir().unwrap().join(".config/Code/User/globalStorage/state.vscdb"); if !db_path.exists() { return Vec::new(); } let conn = match Connection::open(db_path) { Ok(c) => c, Err(_) => return Vec::new(), }; let mut stmt = match conn.prepare("SELECT value FROM ItemTable WHERE key='history.recentlyOpenedPathsList'") { Ok(s) => s, Err(_) => return Vec::new(), }; let json_str = match stmt.iter().unwrap().next() { Some(row) => match row.unwrap().get::<String>(0) { Ok(s) => s, Err(_) => return Vec::new(), }, None => return Vec::new(), }; let opened: RecentlyOpened = match serde_json::from_str(&json_str) { Ok(o) => o, Err(_) => return Vec::new(), }; opened.entries .into_iter() .filter_map(|e| e.path) .filter(|p| fs::metadata(p).is_ok()) .collect() }
步骤3:集成到zlaunch搜索源
假设zlaunch有SearchSource trait,实现该源并注册:
// 适配zlaunch的搜索结果结构 struct SearchResult { title: String, description: String, action: Box<dyn Fn() -> ()>, } trait SearchSource { fn search(&self, query: &str) -> Vec<SearchResult>; } struct CodeRecentSource; impl SearchSource for CodeRecentSource { fn search(&self, query: &str) -> Vec<SearchResult> { let paths = get_code_recent_paths(); paths.into_iter() .filter(|p| p.to_lowercase().contains(query.to_lowercase().as_str())) .map(|p| SearchResult { title: p.split('/').last().unwrap_or(&p).to_string(), description: p.clone(), action: Box::new(move || { let _ = std::process::Command::new("code") .arg(&p) .spawn(); }), }) .collect() } } // 将该源注册到zlaunch的搜索系统 // zlaunch::register_source(CodeRecentSource);
步骤4:编译使用
编译zlaunch并替换原有版本,之后在zlaunch中输入关键词就能搜索到VS Code最近工作区,选中即可打开。
内容的提问来源于stack exchange,提问作者BowenDean
相关产品推荐
相关产品推荐

