Cursor 上手快,但大多数人卡在同一个地方:不是模型不行,是没搞清三个模式各管什么、没把项目上下文喂对。这篇把 Tab、Composer、Inline Edit 的分工讲清,再说 .cursorrules 怎么写,最后列几个高频误区。

三个模式各管一段

判断写进第一句:改动小用 Tab 或 Inline Edit,跨文件用 Composer,别指望一个模式通吃。

Tab 补全是逐行甚至多行的自动补全,写函数体、样板代码、测试最顺手。它靠的是「猜你接下来写什么」,所以你要给它方向——先写函数签名和一句注释,Tab 顺着往下填,比直接让它从零写稳。

Inline Edit(Cmd+K)是选中一段代码,描述一句改动,它只改选中的范围。加个 prop、改个返回值、重构一个函数,用这个最快。

Composer(Cmd+I,全屏 Cmd+Shift+I)能读多个文件、跨文件改、跑命令。重命名一个贯穿多层的字段、加一个跨文件的功能,交给它。用 Composer 时记得 @ 文件点名,不然它会猜——猜错路径、改错文件的概率不低。

Composer 怎么喂上下文

Composer 的产出质量,几乎由上下文决定。三个手段:@ 具体文件(@src/lib/auth.ts)、@ 文档(@Prisma docs)、@codebase(全库语义搜索)。@codebase 依赖代码库索引,索引没建完或没建对,搜出来就漏。

还有一个很多人忽略的:打开你要改的文件再让 Composer 动。Cursor 会把已打开文件当优先上下文,这比在 prompt 里描述半天「就是那个文件」可靠得多。多文件编辑时,逐个文件看 diff、逐个 Accept,别一把 Accept All。

.cursorrules 怎么写

.cursorrules 是放在项目根目录的文件,Cursor 会把它注入每次 AI 请求。它回答的是「这个项目有什么约定、不许干什么」。写好了,AI 每次生成都在你的框架里;不写,它每次都得猜你用 Zustand 还是 Redux、Tailwind 还是 CSS Modules。

# 项目约定
- 前端 Next.js App Router,不用 Pages Router。
- 状态用 zustand,不用 redux。
- 样式用 Tailwind,不引 CSS 文件。
- 类型严格模式,禁止 any。
- 测试文件放源码旁,命名 *.test.ts。
- 提交前必须 `npm run lint && npm test` 全绿。

反面也重要:别写「写干净的代码」这种自明的话,别塞几十条让模型根本记不住。留真正有区分度的约定。

配套一个 .cursorignore,把生成目录排除出索引,索引准了 @codebase 才准:

node_modules
.next
dist
coverage
*.min.js

代码库索引与模型切换

还有一个被低估的设置是代码库索引。Cursor 要从你打开项目的根目录开始建索引,索引完成前 @codebase 搜不准;node_modules、dist 这类生成目录要在 .cursorignore 里排除,否则索引又慢又脏。模型也能按任务切——Tab 补全用默认的快速模型就够,规划重构、长上下文分析再换重模型,别一条道用到底。

几个高频误区

一是写一大段 prompt 然后直接 Accept All。正确做法是给方向、看第一轮输出、对不满意的部分追加指令、逐个 Accept。二是简单改动也用 Composer——单文件改五行用 Inline Edit 更快,Composer 的优势在跨文件,不在单文件。三是没 commit 就开 Composer 跑大改,它一次可能动十几个文件,没有提交点回滚都难。四是拒绝一切「看起来差不多」的 diff,宁可重试 prompt 也不要把错的改对。

还有两个容易混的。Chat 面板(Cmd+L)只问答、不改文件,Composer(Cmd+I)才生成并落地改动,拿 Chat 让它改代码,只会得到一段没落地的解释。多文件编辑改错文件也是高频坑——两个文件同名时 Composer 会猜,先 @ 精确路径再下指令。

最后一条是提示词本身:模糊的「修一下这个 bug」远不如「在 X 模块里修这个 null 问题,参考 Y 模块怎么处理的」。把文件、行为、约束说具体,Cursor 才对得起那个订阅费。