Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
107 changes: 107 additions & 0 deletions docs/src/content/release/26.3.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
title: 26.3.0
---

CodeForge v26.3.0 是一次以**调试、AI、数据与工作区**为核心的大版本:把一套基于 DAP 的**可视化调试器**装进编辑器,覆盖 Python / Go / Rust / C / C++;扩展**选中代码的 AI 解释·重构·测试**与代码库上下文对话;带来**结果导出、ER 图、交互式事务**等数据库能力;引入**多根工作区**与大量编辑器生产力功能(.editorconfig、自动换行、缩进参考线、专注模式、置顶标签、文件树定位等)。

CodeForge v26.3.0 is a major release centered on **debugging, AI, data and workspaces**: a DAP-based **visual debugger** built into the editor for Python / Go / Rust / C / C++; expanded **AI explain·refactor·test** on selected code plus codebase-aware chat; richer database tooling (**result export, ER diagrams, interactive transactions**); and a new **multi-root workspace** alongside many editor productivity features (.editorconfig, word wrap, indent guides, Zen mode, pinned tabs, reveal-in-tree, and more).

---

## 📦 版本信息 | Release Information

- **项目地址 | Repository**:https://github.com/devlive-community/codeforge
- **官方网站 | Official Website**:https://codeforge.devlive.org/
- **版本号 | Version**:v26.3.0
- **发布日期 | Release Date**:2026年6月29日 | June 29, 2026

---

## 🐞 可视化调试(DAP)| Visual Debugging

基于调试适配器协议(DAP)的**图形化调试**,无需切到命令行:
A graphical debugger built on the Debug Adapter Protocol — no terminal needed:

- **断点**:行断点、**条件断点**、**异常断点**,执行行高亮
- **调用栈 / 变量 / 监视 / 求值**面板,**调试控制台**与**悬停求值**
- **会话控制**:继续 / 暂停 / 单步进入·跳过·跳出 / 重启 / 停止,调试工具栏
- **支持语言**:Python(debugpy)、Go(delve)、Rust · C · C++(lldb-dap,先编译后调试)
- **设置页一键安装调试适配器**,状态栏实时调试指示

Breakpoints (line / **conditional** / **exception**) with current-line highlight; call stack, variables, watch & evaluate panels, a **debug console** and **hover evaluation**; full session control and a debug toolbar; languages **Python (debugpy), Go (delve), Rust·C·C++ (lldb-dap, build-then-debug)**; one-click **adapter installation** from settings and a status-bar debug indicator.

---

## 🏃 运行 · 测试 · 任务 | Run, Test & Tasks

- **运行测试** - 自动识别项目类型并选用对应测试命令
- **运行任务 / 构建预设** - 在集成终端中执行常用命令
- **发送选区到终端** - 把选中代码片段一键送入终端运行

**Run tests** (auto-detecting project type), **run task / build presets** in the integrated terminal, and **send selection to terminal**.

---

## 🤖 AI 能力增强 | AI

- **选中代码 → AI 解释 / 重构 / 生成测试**,结果以差异预览确认后再应用
- **AI 对话挂接代码库上下文**,回答更贴合当前项目
- **AI 生成提交信息** - 基于**已暂存 diff** 生成,贴合本次实际提交内容

AI **explain / refactor / generate-tests** on a selection (applied via diff preview), **codebase-aware chat**, and **AI commit messages** generated from the **staged diff**.

---

## 🗄 数据库 · SQL | Database & SQL

- **查询结果导出** - 导出为 **JSON / Excel**
- **ER 图** - 由 schema 自动生成实体关系图;MySQL 未选库时可**内联选择数据库**
- **交互式事务** - SQLite / DuckDB / MySQL / Postgres 的 **BEGIN / COMMIT / ROLLBACK** 全程图形化
- **执行历史收藏** - 常用执行记录可收藏、按收藏过滤

Export results to **JSON / Excel**, generate **ER diagrams** from schema (with inline DB picker for MySQL), **interactive transactions** (begin/commit/rollback) across SQLite·DuckDB·MySQL·Postgres, and **favorites** in execution history.

---

## 📁 多根工作区与导航 | Multi-root Workspace & Navigation

- **多根工作区** - 在主目录之外**挂载多个文件夹**,各根为可折叠分区、标题吸顶
- **各根独立 Git 徽标**,根标题右键可**新建 / 移除**
- **跨全部根的搜索 / 替换**,以及目录右键**在文件夹中搜索**
- **在文件树中定位当前文件**(可选切换文件时自动定位)、**一键折叠所有文件夹**
- **面包屑分段下拉** - 点击层级快速切换同级文件、钻入子目录

Mount **multiple folders** as collapsible, sticky-header roots; **per-root Git badges**; new-file / remove from a root's context menu; **search & replace across all roots** plus **find-in-folder**; **reveal active file in the tree** (with optional auto-reveal) and **collapse-all**; and a **breadcrumb dropdown** to jump between sibling files.

---

## ✍️ 编辑器体验 | Editor Experience

- **.editorconfig 支持** - 按文件应用缩进,保存时**去除行尾空白 / 补末尾换行**
- **自动换行**(Alt+Z)、**缩进参考线**、**专注模式**(隐藏周边面板沉浸编辑)
- **符号大纲** - 按层级缩进显示,打开即定位光标所在符号
- **状态栏缩进指示** - 点击快速切换空格 / 制表符与缩进宽度
- **文本命令** - 排序行、大小写转换、删除重复行、去除行尾空白、**复制为 Markdown 代码块**
- **与剪贴板比较** - 把当前内容和剪贴板做差异对比

`.editorconfig` support (indent + trim-trailing / final-newline on save), **word wrap** (Alt+Z), **indent guides**, **Zen mode**, a hierarchical **symbol outline** that lands on the cursor's symbol, a clickable **indentation indicator**, text commands (sort / case / dedupe / trim / **copy as Markdown**), and **compare-with-clipboard**.

---

## 🗂 标签与 Git | Tabs & Git

- **重新打开已关闭标签**(Mod+Shift+T)、**置顶标签**
- 标签右键 - 在文件树中定位 / 在文件管理器显示 / 复制路径与相对路径
- **自定义 .gitignore 模板** - 设置页管理,独立存储
- **远程永久链接** - 复制 / 在浏览器打开当前文件指定行的 GitHub·Gitee·GitLab 链接
- **状态栏当前分支** - 点击直达 Git 面板

**Reopen closed tab** & **pin tab**, a richer tab context menu, custom **.gitignore templates**, **remote permalinks** (copy / open current line on GitHub·Gitee·GitLab), and a **status-bar branch** indicator.

---

## 📥 立即下载 | Download Now

在 [GitHub Releases](https://github.com/devlive-community/codeforge/releases) 下载最新版本,或访问[官方网站](https://codeforge.devlive.org/)了解更多信息。

Download the latest version from [GitHub Releases](https://github.com/devlive-community/codeforge/releases), or visit the [Official Website](https://codeforge.devlive.org/) for more information.
45 changes: 3 additions & 42 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ import {useGitPermalink} from './composables/useGitPermalink'
import {useRevealInTree} from './composables/useRevealInTree'
import {useWorkspaceRoots} from './composables/useWorkspaceRoots'
import {useGitStatus} from './composables/useGitStatus'
import {useInlineDiff} from './composables/useInlineDiff'
import {useSessionTabs} from './composables/useSessionTabs'
import {useEditorContextMenu} from './composables/useEditorContextMenu'
import {useRunConfig} from './composables/useRunConfig'
Expand Down Expand Up @@ -579,7 +580,6 @@ import {useDbConnections} from './composables/useDbConnections'
import {useAiConfig} from './composables/useAiConfig'
import {setGhost, clearGhostIn, ghostActive} from './editor/aiComplete'
import {cursorInfo} from './editor/cursorInfo'
import {computeDiffMarkers, setDiffMarkers} from './editor/diffGutter'
import {setBreakpointData} from './editor/breakpointGutter'
import {useDebug} from './composables/useDebug'
import AiAssistant from './components/AiAssistant.vue'
Expand Down Expand Up @@ -1602,47 +1602,8 @@ const openGit = () => {
// 文件树 Git 徽标 + 当前分支(抽离到 useGitStatus);HEAD 变化时刷新差异基线
const {gitStatus, gitRepo, gitBranch, refreshGitStatus} = useGitStatus(rootDir, extraRoots, () => fetchBaseline())

// ===== 编辑器行内差异标记(vs HEAD)=====
// 当前文件在 HEAD 中的内容;null 表示无基线(新文件/非 git/未跟踪),不显示标记
const gitBaseline = ref<string | null>(null)

const fetchBaseline = async () => {
if (!rootDir.value || !currentFilePath.value || !currentFilePath.value.startsWith(rootDir.value)) {
gitBaseline.value = null
applyDiffMarkers()
return
}
const rel = currentFilePath.value.slice(rootDir.value.length + 1)
try {
const head = await invoke<{ exists: boolean, content: string }>('git_file_head', {
root: rootDir.value,
relPath: rel
})
gitBaseline.value = head.exists ? head.content : null
}
catch {
gitBaseline.value = null
}
applyDiffMarkers()
}

// 计算并派发标记到编辑器
const applyDiffMarkers = () => {
const view = editorView.value
if (!view) {
return
}
const markers = gitBaseline.value === null
? {changed: new Map(), deleted: new Set<number>()}
: computeDiffMarkers(gitBaseline.value, code.value)
view.dispatch({effects: setDiffMarkers.of(markers)})
}
const applyDiffMarkersDebounced = debounce(applyDiffMarkers, 250)

// 切换文件取新基线;编辑时重算;编辑器重挂时重新派发
watch(currentFilePath, () => fetchBaseline())
watch(code, () => applyDiffMarkersDebounced())
watch(editorView, () => applyDiffMarkers())
// ===== 编辑器行内差异标记(vs HEAD)抽离到 useInlineDiff =====
const {fetchBaseline} = useInlineDiff({editorView, code, rootDir, currentFilePath})

// ===== 断点(B1-P2):把当前文件的断点 + 执行行派发到编辑器 =====
const debug = useDebug()
Expand Down
57 changes: 57 additions & 0 deletions src/composables/useInlineDiff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 编辑器行内差异标记(当前内容 vs HEAD 基线)。
import {ref, watch, type Ref} from 'vue'
import {invoke} from '@tauri-apps/api/core'
import {debounce} from 'lodash-es'
import {computeDiffMarkers, setDiffMarkers} from '../editor/diffGutter'

interface Deps {
editorView: Ref<any>
code: Ref<string>
rootDir: Ref<string | null>
currentFilePath: Ref<string | null>
}

export function useInlineDiff({editorView, code, rootDir, currentFilePath}: Deps) {
// 当前文件在 HEAD 中的内容;null 表示无基线(新文件/非 git/未跟踪),不显示标记
const gitBaseline = ref<string | null>(null)

// 计算并派发标记到编辑器
const applyDiffMarkers = () => {
const view = editorView.value
if (!view) {
return
}
const markers = gitBaseline.value === null
? {changed: new Map(), deleted: new Set<number>()}
: computeDiffMarkers(gitBaseline.value, code.value)
view.dispatch({effects: setDiffMarkers.of(markers)})
}
const applyDiffMarkersDebounced = debounce(applyDiffMarkers, 250)

const fetchBaseline = async () => {
if (!rootDir.value || !currentFilePath.value || !currentFilePath.value.startsWith(rootDir.value)) {
gitBaseline.value = null
applyDiffMarkers()
return
}
const rel = currentFilePath.value.slice(rootDir.value.length + 1)
try {
const head = await invoke<{ exists: boolean, content: string }>('git_file_head', {
root: rootDir.value,
relPath: rel
})
gitBaseline.value = head.exists ? head.content : null
}
catch {
gitBaseline.value = null
}
applyDiffMarkers()
}

// 切换文件取新基线;编辑时重算;编辑器重挂时重新派发
watch(currentFilePath, () => fetchBaseline())
watch(code, () => applyDiffMarkersDebounced())
watch(editorView, () => applyDiffMarkers())

return {fetchBaseline}
}
Loading