FnList 函数列表
极速、轻量的函数导航面板。 打开工程立刻看到当前文件的函数、宏、类型与全局变量 ——
不用等语言服务,不用装依赖,全程离线。
英文简介见文末 → English summary ↓(面板界面目前为中文)
30 秒上手
- 安装后,点左侧活动栏的 FnList 图标打开面板(快捷键
⌃⌥L,Windows / Linux 是 Ctrl+Alt+L)
- 打开一个
.c / .h / .py 文件 —— 面板立刻列出它的函数、宏、类型与全局变量,不需要任何配置
- 点列表里的名字,光标跳过去;在代码里移动光标,列表自动高亮你所在的函数
就这三步。搜索和置顶书签(见下文)会在你用熟之后自然派上用场。
面板长什么样
从上到下三块:
- 搜索与排序工具栏 —— 搜索框空闲时,最右端显示版本号;聚焦搜索或输入内容时它让位
- 置顶模块 —— 你钉住的书签,没有置顶时自动隐藏,不占地方
- 函数列表 —— 文件名行固定在列表顶部、不随滚动,右端是该文件的符号数
(搜索时显示「命中 / 共 N」;鼠标悬停可看整个工程的符号与文件总数)
图标与配色区分符号类型,取自 VSCode 官方 codicon、与自带大纲同源:
| 图标 |
含义 |
| 实心立方体 |
函数定义 |
| 空心轮廓 +「声明」标签 |
函数原型(只有声明、没有函数体) |
| 常量方框 |
宏(带参宏显示参数名,如 MIN (a, b)) |
| 结构方块 |
类型(struct / enum / class / typedef) |
| 变量括号 |
全局变量 |
函数签名只保留参数类型:(device_t *dev, block_set_t *blocks) 显示为 (device_t *, block_set_t *),
长名字也能完整显示;无参函数显示 (void) 而不是空括号。
日常功能
跳转与跟随
- 列表显示当前活动标签页里的代码文件,切文件自动跟着换,不用手动刷新
- 单击以预览标签打开、焦点留在列表;双击打开常驻标签并进入编辑器
- 光标跟随:在代码里移动光标,列表自动高亮所在函数并滚动到可见处(切换高亮带柔和缓动)
- 对比视图(git diff / 时间线)里点函数只移动光标,不会把你弹出对比
- 切到设置页、欢迎页这类非代码页面、或关掉所有文件时,列表清空并说明原因 —— 与 VSCode 自带大纲的行为一致
- 滚动做了专门的流畅性优化(虚拟滚动),上千符号的文件也丝滑
搜索
- 搜当前文件的符号:函数、变量、宏、类型都能搜到
- 包含匹配、不区分大小写:搜
read 会命中 read_stream、ReadBuffer
- 搜索框内按
↑ ↓ 翻找历史,最多 10 条,去重后最近的在最前
Esc 一键清空搜索;搜索只过滤符号列表,置顶区始终完整显示
置顶(书签)
- 任意行都能置顶:光标在函数起始行就记该函数,否则记该行内容
- 两个作用域:当前文件置顶(只在那个文件显示)/ 跨文件置顶(本工作区所有文件都能看到)
- 置顶区固定在面板顶部,不随列表滚动 —— 翻到列表深处也能随手点
- 改代码后按名字自动重绑行号,函数上下移动不失联
- 函数被删 / 改名 → 标「函数不存在」;文件被删 / 重命名 → 标「文件不存在」。
两种情况书签都保留、灰显不可点,函数或文件回来后自动恢复
- 置顶随当前工作区存储 —— 换工作区打开、目录改名、换机器都不会跟随
- 一键清除:置顶栏右侧的按钮点一下清空全部置顶(所有文件、两种作用域),
随即弹出可点的「撤销」,误点也能一键找回
快捷键
| 命令 |
macOS |
Windows / Linux |
| 搜索函数(聚焦面板搜索框) |
⌃⌥F |
Ctrl+Alt+F |
| 置顶 / 取消置顶当前行(当前文件) |
⌃⌥B |
Ctrl+Alt+B |
| 置顶 / 取消置顶当前行(本工作区跨文件) |
⌃⌥⇧B |
Ctrl+Alt+Shift+B |
| 打开函数列表 |
⌃⌥L |
Ctrl+Alt+L |
不碰鼠标也行:列表内 ↑ ↓ 移动高亮、Enter 跳转。
自定义快捷键
键位走 VSCode 标准机制,插件不做任何锁定,改键与恢复默认都原生支持。
注意:改键在「键盘快捷方式」面板,不是「设置」页(设置里只能改参数,改不了键):
- 打开面板:左下角齿轮 ⚙ → 键盘快捷方式;或菜单 Code → 设置 → 键盘快捷方式;
快捷键是和弦——macOS 按
⌘K 松开再按 ⌘S,Windows / Linux 按 Ctrl+K 松开再按 Ctrl+S
- 改键:面板里搜索
FnList → 双击命令 → 按下新组合(例如 Alt+N)→ 回车,立即生效
- 一键恢复默认:面板里右键命令 → 重置键位,即回到默认;想整体还原,
打开
keybindings.json 删掉自己加的条目即可
- 「置顶 / 取消置顶」是开关式:同一键按第二次即取消(与 VSCode 切换注释同习惯)
- 「重建索引」「查看被跳过的文件」没有默认键,可在同一面板自行绑定
支持的语言与已知取舍
面板的秒出、零依赖、离线可用,靠的是自带启发式扫描器(直接读源码,不依赖语言服务)。
代价是准确度低于语言服务,因此默认只索引验证过的语言:
- C / C++(含 h / hpp / cc / cxx 等别名):宏修饰签名(
API_EXPORT void fn(void))、
C++ 类外定义、__attribute__ 尾缀、extern "C" 包裹、K&R 风格函数、嵌套注释与字符串屏蔽
- Python:
def / class
已知边界(是设计取舍,不是 bug):
- 只收顶层符号,类 / 结构体内的方法不收(例如 Java / C# 工程只会列出类名)
- 条件编译只特判
#if 0:死分支隐藏;#elif 不求值,非 #if 0 的条件(如 #if 1)两个分支都会显示
- 其它语言(Go、Rust、TypeScript、Swift 等)可在
fnlist.includeExtensions 自行添加,
属尽力识别:带类型注解的声明可能被认成变量名,漏检时也没有提示
- 拿不准时与 VSCode 自带大纲对照:大纲有、本面板没有 → 大概率是上述边界;
两边都没有 → 才值得当 bug 报
设置
| 设置项 |
默认值 |
说明 |
fnlist.includeExtensions |
C/C++ 家族与 py(17 项) |
需要索引的文件扩展名;其它语言可自行添加(尽力识别) |
fnlist.excludeGlobs |
[] |
额外排除的 glob,例如 **/third_party/** |
fnlist.maxFileKB |
300 |
超过该大小的文件后台跳过;当前打开的文件放宽到 10 倍(约 3MB),超过仍跳过 |
fnlist.maxFiles |
50000 |
扫描文件数上限 |
fnlist.retainFiles |
2000 |
符号表保留上限(超出按最久未使用淘汰) |
性能
- 零依赖:纯 JavaScript,无第三方包、无编译步骤、无网络请求
- 后台有界并发索引(8 路,逐个让出事件循环):实测 600 个文件扫描期间最长停顿 11ms,不卡输入
- 增量更新:文件改动即时重解析;与全量扫描共用同一套排除规则(
excludeGlobs、
files.exclude、search.exclude 及内置的 node_modules / build 等)
- 内存有上界:与符号数线性相关(约 0.3 KB/符号),超出保留上限按最久未使用淘汰,
当前文件与置顶文件永不淘汰;面板查询是纯内存过滤,工程再大也在 0.05ms 量级
- 超大文件降级透明:超过
fnlist.maxFileKB 的文件后台跳过并在界面提示「跳过 N 个大文件」,
点击可查看清单;当前打开的文件在 10 倍阈值(约 3MB)内始终全量解析
隐私
全部处理都在本地完成:只读取工作区内的源文件,不联网、不上传任何代码。
English
FnList is a fast, lightweight function list for VS Code. Open a project and the panel
immediately shows the functions, macros, types and globals of the current file — no language
server, no dependencies, no network requests. It also gives you per-file / per-workspace pins,
search history, cursor follow and smooth virtual scrolling.
The panel UI is in Chinese — this extension is Chinese-only at the moment, and the
documentation above is Chinese for that reason. This summary is here so English readers can
see what the extension does before installing.
- Symbols of the current file — functions, macros, types (struct / enum / class / typedef)
and global variables. "Current file" means the code file in the active tab: in a comparison
view (timeline / git diff) it is the editable side, while a non-code tab or no open file
at all leaves the panel empty and tells you why
- Pins (bookmarks) — pin any line, with two scopes: this file, or this workspace (visible
from every file). Stored per workspace, and re-bound by name when code moves
- Search — substring match, case-insensitive;
↑ ↓ inside the box walks up to 10 recent
queries
- Click / double-click a symbol — single click opens it as a preview tab and keeps focus in
the list; double click opens a permanent tab and focuses the editor. When the target file is
already the file of the active tab (including the working copy inside a diff view), the
cursor is simply moved and you are not pulled out of the comparison
- Keys —
⌃⌥F search, ⌃⌥B pin in this file, ⌃⌥⇧B pin in this workspace, ⌃⌥L open the
panel (Ctrl+Alt+… on Windows / Linux); all of them are rebindable in Keyboard Shortcuts
- Languages — C / C++ and Python are verified; others can be added through
fnlist.includeExtensions (best-effort heuristics). Only top-level symbols are collected:
methods inside a class or struct are not listed
- Privacy — everything runs locally; it only reads source files in your workspace and never
uploads code
Settings: fnlist.includeExtensions, fnlist.excludeGlobs, fnlist.maxFileKB,
fnlist.maxFiles, fnlist.retainFiles.