如何用 Cursor 高效编程
# 我用Cursor编码30天——真正有效的实战经验
你肯定有过这种体验:盯着TypeScript错误提示下那条红色波浪线,明明见过上百次,却还是记不住带嵌套泛型的`Omit`确切语法。三个月前的我就是这样,直到我开始使用Cursor,从此再也不想在复杂项目中用回普通VS Code了。
但关键在于:Cursor并非魔法。第一周我把它当成高级自动补全工具,结果收获了一堆垃圾代码。经过30天刻意练习,我终于找到了真正省时的模式——以及那些纯属浪费时间的功能。
## 关键设置
首先,基础配置要到位。我在macOS上运行Cursor 0.45.x,但同样适用于Windows/Linux。安装后,我立即修改了两个大多数教程忽略的设置:
1. **关闭"自动补全"内联建议**(设置 > 编辑器 > Cursor > 补全:关闭)。那些不断闪现的幽灵文本让我每个按键都要自我怀疑。现在我只在需要时按`Ctrl+K`触发内联生成。
2. **启用"应用编辑"模式**(Cmd+Shift+P > "Cursor:切换应用编辑")。这让Cursor直接修改你的代码,而不是仅显示差异对比。极大节省时间。
## 80/20法则:两个真正实用的命令
经过30天实践,我总结出两个能处理80%日常工作的命令:
### 1. `Cmd+K`:"修复代码块"命令
这是你的核心武器。选中代码块,按`Cmd+K`,告诉Cursor要做什么。以下是我正在开发的React项目实例:
```typescript
// 我选中了这堆乱码:
const handleSubmit = async (e) => {
e.preventDefault()
const data = new FormData(e.target)
const body = {}
for (let [key, val] of data.entries()) {
body[key] = val
}
// ...还有50行手动验证代码...
}
```
我输入:"重构为使用react-hook-form配合zod验证,处理加载状态,并添加错误边界"
Cursor在4秒内生成了:
```typescript
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
type FormData = z.infer<typeof schema>
const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<FormData>({
resolver: zodResolver(schema)
})
const onSubmit: SubmitHandler<FormData> = async (data) => {
try {
setError(null)
await api.login(data)
toast.success('登录成功!')
} catch (err) {
setError(err instanceof Error ? err.message : '登录失败')
}
}
```
**诀窍**:明确指定你想要的库和模式。只说"重构"会得到通用代码,而"重构为使用react-hook-form配合zod"才能得到生产级代码。
### 2. `Cmd+L`:"解释这段代码"命令
这其实是隐藏的最强功能。在处理陌生代码库或遗留项目时,我经常使用它。
示例:我在调试一个使用`__getattr__`的Python脚本,逻辑难以理解:
```python
class ConfigProxy:
def __init__(self, config):
self._config = config
def __getattr__(self, name):
if name.startswith('_'):
return super().__getattr__(name)
return self._config.get(name, None)
```
我选中后问:"解释这个模式,并展示如何为Pyright添加正确的类型提示"
Cursor的回答出乎意料地详尽——它解释了代理模式,指出`__getattr__`在属性缺失时会导致无限递归,并给出了带`Protocol`的类型化版本:
```python
from typing import Any, Protocol
class ConfigProtocol(Protocol):
def get(self, key: str, default: Any = None) -> Any: ...
class TypedConfigProxy:
def __init__(self, config: ConfigProtocol):
self._config = config
def __getattr__(self, name: str) -> Any:
if name.startswith('_'):
raise AttributeError(name)
return self._config.get(name, None)
```
**诀窍**:在类型化语言中,务必要求"类型提示"或"正确类型化"。除非你特别要求,Cursor默认生成无类型代码。
## 改变我工作流程的模式
我现在开发新功能的标准流程:
1. **编写描述功能的注释**(而非实现细节)
2. **选中注释**并按`Cmd+K`
3. **仔细审查生成的代码**——总能发现至少一个遗漏的边界情况
4. **通过后续提示迭代优化**,如"添加网络故障错误处理"或"处理空数组情况"
最近项目实例:
```typescript
// 我写的注释:
// 获取用户数据的函数,缓存5分钟,
// 并实现stale-while-revalidate模式
// Cursor经过3次迭代后生成:
const userCache = new Map<string, { data: User; timestamp: number }>()
const CACHE_TTL = 5 * 60 * 1000
async function getUser(id: string): Promise<User> {
const cached = userCache.get(id)
const isStale = cached && Date.now() - cached.timestamp > CACHE_TTL
if (cached && !isStale) {
return cached.data
}
// Stale-while-revalidate:立即返回过期数据,后台刷新
if (cached && isStale) {
fetchUser(id).then(data => {
userCache.set(id, { data, timestamp: Date.now() })
})
return cached.data
}
const user = await fetchUser(id)
userCache.set(id, { data: user, timestamp: Date.now() })
return user
}
```
## Cursor的短板(及应对策略)
我遇到三个主要痛点:
**1. 虚构API。** Cursor曾生成使用不存在的`useMemo`依赖数组的代码(与当前React版本不符)。**对策**:始终对照实际依赖文档验证生成代码。
**2. 大型重构表现糟糕。** 我曾尝试让它"将Redux存储转换为Zustand"跨5个文件,结果产生了混乱的导入和缺失的状态切片。**对策**:逐文件进行重构,并明确说明目标模式。
**3. 难以适应项目特定规范。** 我的团队数据库列用`snake_case`,TypeScript用`camelCase`。Cursor始终生成`camelCase`。**对策**:在项目根目录添加`.cursorrules`系统提示文件,包含你的规范:
```
# .cursorrules
- TypeScript变量使用camelCase
- 数据库列名使用snake_case
- 优先使用async/await而非.then()
- 错误处理:始终使用try/catch配合类型化错误
```
## 真正的效率提升秘诀
最大的时间节省不是代码生成——而是**调试辅助**。遇到晦涩的错误信息时,我会将其复制到Cursor聊天窗口(`Cmd+L`)并附上相关代码块。这在以下场景为我节省了大量时间:
- **TypeScript类型错误**:"类型'X'不可分配给类型'Y'" → Cursor解释类型不匹配并建议修复
- **React渲染问题**:"超过最大更新深度" → Cursor识别useEffect依赖中的无限循环
- **API集成错误**:"无法读取未定义的属性" → Cursor追踪异步代码找到空引用
## 下一步行动
不要试图一次性使用所有Cursor功能。以下是你的7天计划:
**第1-2天**:仅使用`Cmd+K`进行内联代码生成。不使用聊天、解释或编排器。
**第3-4天**:添加`Cmd+L`用于调试和解释不熟悉的代码。仍不使用编排器。
**第5-7天**:在项目中添加`.cursorrules`,并尝试使用编排器进行多文件编辑。
7天后,你将形成真正有效模式的肌肉记忆。当不可避免地遇到虚构代码或糟糕重构时,你会清楚知道何时信任Cursor,何时自己编写代码。
现在就去打开你一直回避的那个文件,选中最丑陋的函数,按下`Cmd+K`。未来的你一定会感谢现在的决定。