Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
db3da22
feat: 代码片段 (snippets)
qianmoQ Jun 5, 2026
3864b60
refactor: 代码片段改存 SQLite 数据库
qianmoQ Jun 5, 2026
54dd86b
refactor: 全部配置改用 SQLite 键值存储,移除 localStorage
qianmoQ Jun 5, 2026
d4d9c3a
feat: AI 代码预测进行中状态提示
qianmoQ Jun 5, 2026
1f64485
feat: 幽灵补全显示时提示「Tab 接受 · Esc 取消」
qianmoQ Jun 5, 2026
ff2fe19
feat: 应用 AI 代码前先弹差异预览确认
qianmoQ Jun 5, 2026
44cb6c2
feat: 集成终端
qianmoQ Jun 5, 2026
b5b0921
fix: 终端固定深色配色
qianmoQ Jun 5, 2026
3a7fe26
fix: 终端改为布局内停靠面板,拖拽高度时编辑区/目录自适应
qianmoQ Jun 5, 2026
1af8761
feat: 状态栏显示光标位置(行:列)与选中字符数
qianmoQ Jun 5, 2026
81f01e5
feat: 最近文件优先(Cmd+P)
qianmoQ Jun 5, 2026
bd2ab0a
feat: AI 格式化代码
qianmoQ Jun 5, 2026
1d8618e
feat: 终端多标签
qianmoQ Jun 5, 2026
01cf914
fix: 终端收起保留会话,chrome 统一深色
qianmoQ Jun 5, 2026
5204afc
feat: 面包屑路径导航
qianmoQ Jun 5, 2026
1698281
fix: 面包屑包含根文件夹名,根目录下文件不再只剩单段
qianmoQ Jun 5, 2026
fd157b4
fix: 仅编辑器布局的头部也显示面包屑
qianmoQ Jun 5, 2026
bb738a7
fix: 编辑器头部不换行,面包屑过长横向滚动
qianmoQ Jun 5, 2026
d700079
fix: 面包屑横向滚动隐藏滚动条
qianmoQ Jun 5, 2026
de7f2ea
feat: 新增 JSON/XML/YAML/Markdown/纯文本 语言插件
qianmoQ Jun 5, 2026
1bcaf3e
feat: 文本类语言的 CodeMirror 高亮与图标兜底
qianmoQ Jun 5, 2026
72f3a02
feat: 新增语言图标,YAML 支持 .yml 后缀
qianmoQ Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
"@codemirror/lang-html": "^6.4.9",
"@codemirror/lang-java": "^6.0.2",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/lang-php": "^6.0.2",
"@codemirror/lang-python": "^6.2.1",
"@codemirror/lang-rust": "^6.0.2",
"@codemirror/lang-xml": "^6.1.0",
"@codemirror/lang-yaml": "^6.1.3",
"@codemirror/language": "^6.11.2",
"@codemirror/legacy-modes": "^6.5.1",
"@codemirror/state": "^6.5.2",
Expand All @@ -32,6 +35,8 @@
"@tauri-apps/plugin-shell": "^2.3.0",
"@uiw/codemirror-themes-all": "^4.24.2",
"@vueuse/core": "^13.6.0",
"@xterm/addon-fit": "^0.11.0",
"@xterm/xterm": "^6.0.0",
"codemirror": "^6.0.2",
"lodash-es": "^4.17.21",
"lucide-vue-next": "^0.539.0",
Expand Down
4 changes: 4 additions & 0 deletions public/icons/json.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/icons/markdown.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/icons/text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/icons/xml.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/icons/yaml.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
155 changes: 151 additions & 4 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ futures-util = "0.3"
rfd = "0.15"
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs" }
async-trait = "0.1"
portable-pty = "0.8"
zip = "2.2.2"
flate2 = "1.0"
tar = "0.4"
Expand Down
73 changes: 73 additions & 0 deletions src-tauri/src/kv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use crate::execution::get_codeforge_db_path;
use rusqlite::{Connection, params};
use std::collections::HashMap;
use std::sync::Mutex as StdMutex;
use tauri::State;

/// 通用键值存储,存于同一个 codeforge.sqlite 库。
/// 用于替代前端 localStorage,集中持久化所有应用配置/状态。
pub struct KvStore {
conn: StdMutex<Connection>,
}

impl KvStore {
pub fn new() -> Result<Self, String> {
let db_path = get_codeforge_db_path()?;
let conn = Connection::open(&db_path).map_err(|e| format!("打开数据库失败: {}", e))?;
let _ = conn.pragma_update(None, "journal_mode", "WAL");
conn.execute(
"CREATE TABLE IF NOT EXISTS kv_store (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
)",
[],
)
.map_err(|e| format!("初始化键值表失败: {}", e))?;

Ok(Self {
conn: StdMutex::new(conn),
})
}
}

/// 读取所有键值(启动时一次性载入到前端缓存)
#[tauri::command]
pub async fn kv_get_all(state: State<'_, KvStore>) -> Result<HashMap<String, String>, String> {
let conn = state.conn.lock().map_err(|_| "数据库锁错误".to_string())?;
let mut stmt = conn
.prepare("SELECT key, value FROM kv_store")
.map_err(|e| format!("查询键值失败: {}", e))?;
let rows = stmt
.query_map([], |row| {
Ok((row.get::<_, String>(0)?, row.get::<_, String>(1)?))
})
.map_err(|e| format!("读取键值失败: {}", e))?;
let mut map = HashMap::new();
for r in rows {
let (k, v) = r.map_err(|e| format!("读取键值失败: {}", e))?;
map.insert(k, v);
}
Ok(map)
}

/// 写入一个键值
#[tauri::command]
pub async fn kv_set(key: String, value: String, state: State<'_, KvStore>) -> Result<(), String> {
let conn = state.conn.lock().map_err(|_| "数据库锁错误".to_string())?;
conn.execute(
"INSERT INTO kv_store (key, value) VALUES (?1, ?2)
ON CONFLICT(key) DO UPDATE SET value=?2",
params![key, value],
)
.map_err(|e| format!("保存键值失败: {}", e))?;
Ok(())
}

/// 删除一个键
#[tauri::command]
pub async fn kv_delete(key: String, state: State<'_, KvStore>) -> Result<(), String> {
let conn = state.conn.lock().map_err(|_| "数据库锁错误".to_string())?;
conn.execute("DELETE FROM kv_store WHERE key = ?1", params![key])
.map_err(|e| format!("删除键值失败: {}", e))?;
Ok(())
}
Loading
Loading