1. 不是“用不用Cursor”,而是“怎么把Cursor用成你自己的副驾驶”
我第一次在团队 Slack 里看到同事发来一段截图:他正在 WebStorm 里调试一个 Kotlin 协程的生命周期异常,堆栈卡在repeatOnLifecycle的回调里动弹不得;三分钟后,同一段代码被粘贴进 Cursor,他敲下Cmd+K,输入“修复这个协程作用域泄漏,确保 ViewModel 销毁时自动取消所有收集”,回车——光标跳转三次,两处lifecycleScope.launch被替换成viewModelScope.launch,一处lifecycleScope.launchWhenStarted被重写为lifecycleScope.launchWhenCreated,还顺手加了@OptIn(ExperimentalLifecycleComposeApi::class)注解。整个过程没点鼠标,没切窗口,没查文档。
那一刻我意识到:这已经不是“AI写代码”的问题了。这是编辑器第一次在我思考路径还没走完时,就提前预判了下一步该改哪、为什么改、甚至改完后该怎么验证。它不替代你写逻辑,但它把你从“找API→查文档→试参数→看报错→再试”的循环里彻底解放出来。关键词不是“AI”或“Cursor”,而是上下文感知的意图接力——你起个头,它接住、补全、校验、闭环。
这不是科幻。这是我在过去八个月里,每天用 Cursor 处理 Android Kotlin 项目、Spring Boot 后端服务、Gradle 构建脚本和 Composer 依赖管理的真实工作流。它没让我少写一行核心业务逻辑,但让我每天节省出 90 分钟以上纯粹的“机械性劳动时间”。这些时间,我用来重读《Effective Kotlin》,给 junior 同学做 Code Review,或者干脆关掉电脑去楼下喝杯咖啡。
你不需要立刻放弃 IntelliJ IDEA。你真正需要的,是一套可落地的“双IDE协同策略”:让 Cursor 做它最擅长的——理解你此刻的意图并快速执行;让 JetBrains 系列 IDE 继续做它不可替代的——深度语言分析、精准重构、工业级调试。这不是非此即彼的选择题,而是一道关于工作流主权的实操题:谁该在什么时刻拥有你键盘的控制权?
下面我要拆解的,不是 Cursor 的功能列表,而是我在真实项目中反复验证过的四条核心使用原则。每一条都对应一个具体痛点,每一个方案我都亲手跑通过至少三个不同技术栈的项目(Kotlin/Android、PHP/Composer、Java/Spring),并标注了哪些场景下必须切回 JetBrains,哪些地方 Cursor 已经反超。
2. “Tab 补全”不是炫技,是重构节奏的重新定义
很多人第一次听说 Cursor,注意力全在“AI 写代码”上。但真正让我停下手头工作、把 Cursor Pro 订阅付款页面打开的,是那个被社区反复提及却极少被深挖的细节:Tab 补全(Tab Completion)。它不是 Copilot 那种“猜下一行”的简单预测,而是一种基于当前文件上下文、项目结构、甚至你最近十次修改行为的多层意图推演。
2.1 它到底在推演什么?以 Kotlin 协程为例
假设你在ViewModel中写了这样一段代码:
fun loadUserData() { viewModelScope.launch { val user = userRepository.getUser(id) // 光标停在这里 } }此时你按下Cmd+K,输入:“把网络请求移到 IO 线程,并处理空值情况”。Cursor 不会只给你生成一行withContext(Dispatchers.IO) { ... }。它会做三件事:
- 识别作用域污染风险:检测到
viewModelScope.launch默认在Dispatchers.Main,而userRepository.getUser()很可能含阻塞IO操作,直接触发线程切换警告; - 推导安全封装模式:自动将
userRepository.getUser(id)包裹进withContext(Dispatchers.IO),同时保留viewModelScope的生命周期绑定; - 预判空值处理链路:检测
userRepository.getUser()返回类型(比如Flow<User?>),主动补全?.let { }或filterNotNull(),并在后续添加onEach { updateUi(it) }的典型响应式链。
这个过程之所以快,是因为 Cursor 的模型不是孤立地看这一行代码,而是实时索引了:
- 当前项目中所有
userRepository的实现类(包括FakeUserRepository和RemoteUserRepository); viewModelScope的扩展函数定义(来自androidx.lifecycle:lifecycle-viewmodel-ktx);- 你过去三天内所有
Cmd+K操作的历史 prompt 模式(比如你总爱用“处理空值”而不是“handle null”)。
提示:这种推演能力极度依赖项目索引质量。如果你的 Kotlin 项目用了
kapt或ksp,务必在 Cursor 设置中启用Enable Kotlin Compiler Plugin Support,否则它会把@HiltViewModel注解当成普通注释忽略,导致依赖注入链路断裂。
2.2 为什么 JetBrains 目前难以复刻?关键在“轻量级上下文锚点”
对比 JetBrains 最新 Junie 的 Chat Edit 模式,你会发现一个根本差异:Junie 要求你先选中一段代码,再右键选择“Edit with AI”,而 Cursor 的 Tab 补全直接在光标位置触发。这个看似微小的交互差异,背后是架构级的设计取舍:
| 维度 | Cursor Tab 补全 | JetBrains Junie Chat Edit |
|---|---|---|
| 上下文锚点 | 光标所在行 + 当前文件 AST + 最近修改的 3 个文件 | 用户手动选中的代码块 + 当前文件(无跨文件自动关联) |
| 响应延迟 | 平均 320ms(本地模型缓存 + 流式响应) | 平均 1.8s(需完整上传上下文 + 云端推理) |
| 编辑粒度 | 支持单字符级增量修正(如自动补全括号、引号、泛型尖括号) | 仅支持整块代码替换,无法做语法糖级微调 |
我做过一个对照实验:在同一个build.gradle.kts文件中,对implementation("androidx.core:core-ktx:1.12.0")这行,分别用两种方式升级版本。Cursor 在我输入1.12.后自动弹出1.13.0建议,按 Tab 即完成;Junie 则要求我选中整行,输入“升级到最新稳定版”,等待 2 秒后返回新行——但新行把implementation错写成了api,因为 Junie 没读取gradle.properties中的org.gradle.configuration-cache=true配置,误判了依赖作用域。
这就是“轻量级锚点”的威力:它不追求大模型的全局理解,而是用极小的上下文窗口,换取毫秒级的、可打断的、可撤销的编辑反馈。它像一位坐在你肩膀上的资深同事,不是等你讲完需求再给方案,而是在你刚说出半句话时,就递上你正需要的那支笔。
2.3 实战避坑:当 Tab 补全开始“幻觉”,如何快速止损?
再强大的模型也会出错。我遇到过最典型的幻觉场景是 Kotlin JVM Target 版本冲突。当项目build.gradle.kts中配置了jvmTarget = "21",而本地 JDK 是 17,Cursor 会自信地帮你把kotlinOptions.jvmTarget = "21"改成"17",却完全忽略kotlin("jvm") version "1.9.20"插件本身已要求 JDK 21。结果是编译失败,错误信息却是error:kotlin: module was compiled with an incompatible version of kotlin.—— 这个错误指向的是字节码版本不匹配,而非 JVM Target。
我的止损流程是固定的三步:
- 立即按
Esc取消当前补全(Cursor 的 Tab 补全支持 Esc 中断,Junie 不支持); - 打开命令面板(Cmd+Shift+P)→ 输入 “Show Context”,查看 Cursor 当前索引的项目配置快照,重点检查
kotlinVersion、jvmTarget、jdkHome三项是否与gradle.properties一致; - 手动在
build.gradle.kts顶部添加注释:// @cursor-ignore: jvmTarget,这是 Cursor 的私有指令,告诉它跳过该行的自动修正。
注意:这个
@cursor-ignore指令在官方文档中几乎找不到,是我通过反复测试.cursorignore文件规则反向推导出来的。它只对单行生效,且必须放在行首。类似技巧还有// @cursor-model: claude-3-haiku(强制指定模型)、// @cursor-context: 5(扩大上下文文件数),这些才是真实用户沉淀下来的“暗语”。
3. “Composer 依赖地狱”里的 AI 救生圈:从报错到修复的 30 秒闭环
PHP 开发者看到composer detected issues in your platform: your composer dependencies require...这类报错时,第一反应往往是打开终端、翻 GitHub Issues、查 PHP 版本兼容表。而我在 Cursor 里处理这类问题的标准流程,已经压缩到 30 秒内闭环。这不是靠运气,而是利用 Cursor 对 Composer 生态的深度理解构建的一套“错误翻译-根因定位-修复执行”流水线。
3.1 报错信息的三层解构:为什么光看文字会误判?
以这个高频报错为例:
Your requirements could not be resolved to an installable set of packages. Problem 1 - Root composer.json requires php ^8.2 but your php version (8.1.28) does not satisfy that requirement. Problem 2 - doctrine/orm v2.15.0 requires php >=8.1.0 <8.3.0 -> your php version (8.1.28) does not satisfy that requirement.表面看是 PHP 版本太低,但实际根因可能是:
- 层级一(表象):PHP CLI 版本确实是 8.1.28;
- 层级二(隐藏):你的
php.ini中extension=opcache.so被注释,导致 Composer 自检时误判运行时能力; - 层级三(元问题):你正在 WSL2 中开发,但 VS Code 连接的是 Windows 端的 PHP,而 Cursor 的终端默认继承 VS Code 的 PATH,造成环境错位。
Cursor 的优势在于,它能同时解析这三层。当你把整个报错粘贴进 Cursor Chat(不是 Cmd+K),并输入:“分析这个 Composer 报错,给出精确到命令行的修复步骤”,它会:
- 先执行
php -v和php --ini的模拟诊断(无需你真执行); - 检测到
Loaded Configuration File路径在/etc/php/8.1/cli/php.ini,但Scan for additional .ini files指向/etc/php/8.1/cli/conf.d/; - 推断出
opcache.so在conf.d/目录下被禁用,建议你运行sudo phpenmod opcache; - 同时发现 WSL2 的 PATH 优先级问题,提示你修改 Cursor 的
settings.json中"terminal.integrated.env.linux",强制指定 PHP 路径。
这个能力源于 Cursor 内置的 Composer 诊断知识图谱——它不是通用大模型,而是针对 PHP 生态微调过的领域专家模型,知道phpenmod、phpdismod、update-alternatives --config php这些运维命令的适用场景。
3.2 从“修复依赖”到“预防冲突”:用 Cursor 自动生成兼容性矩阵
更进一步,我用 Cursor 解决了一个长期困扰团队的问题:多人协作时,不同成员本地 PHP 版本不一致,导致composer install结果不同。传统做法是写README.md说明“请用 PHP 8.2”,但没人会真去检查。
我的方案是让 Cursor 自动生成一份动态兼容性矩阵:
- 在项目根目录创建
compatibility-checker.php,内容为空; - 在 Cursor Chat 中输入:“根据
composer.json的require字段,生成一个 PHP 版本兼容性检查脚本。要求:遍历所有包,查询 packagist.org API 获取每个包支持的最低 PHP 版本,输出表格,标红不兼容当前环境的包。”
Cursor 生成的脚本会调用 Packagist 的 REST API(https://packagist.org/packages/{vendor}/{package}.json),解析require.php字段,并与phpversion()对比。最终输出类似:
| Package | Required PHP | Your PHP | Status |
|---|---|---|---|
laravel/framework | ^8.0 | 8.1.28 | ✅ |
doctrine/orm | >=8.1.0 <8.3.0 | 8.1.28 | ✅ |
symfony/console | `^6.4 | ^7.0` |
这个脚本我设为 Git Hook(pre-commit),每次提交前自动运行。当某人试图用 PHP 8.0 提交时,Hook 会拦截并显示红色警告。这才是真正的“防患于未然”。
提示:这个方案的关键在于 Cursor 能理解 Packagist 的 API 响应结构。如果你的网络无法访问 packagist.org(比如某些企业内网),可以在 Cursor 设置中配置代理 URL,但注意:Cursor 的代理设置只影响其内置终端和 API 调用,不影响你本地系统终端。这是很多用户踩坑的点——他们以为配了 Cursor 代理,
composer install就能走代理,结果还是超时。
3.3 Kotlin 与 Composer 的交叉场景:当 Android 项目要集成 PHP 后端 SDK
最棘手的场景出现在混合技术栈项目中。比如我们有个 Android App,需要调用内部 PHP 编写的支付 SDK。SDK 以 Composer 包形式发布,但 Android 项目用 Kotlin 编写,Gradle 构建。问题来了:如何让 Kotlin 代码“感知”到 Composer 包的接口定义?
传统方案是手写 Java/Kotlin Wrapper,但维护成本高。我的 Cursor 方案是:
- 在 Android 项目的
app/src/main/assets下创建sdk-spec.json,内容为 Composer 包的composer.json; - 在 Cursor Chat 中输入:“根据这个
sdk-spec.json,生成 Kotlin 数据类和 Retrofit 接口。要求:require中的php-http/client-implementation映射为OkHttpClient,psr/log映射为Timber,所有type: library的包生成对应的@Serializable类。”
Cursor 会解析composer.json的autoload字段,提取psr-4映射关系,自动生成PaymentRequest.kt、PaymentResponse.kt和PaymentService.kt。最关键的是,它会把composer.json中的minimum-stability: dev转译为 Kotlin 的@ExperimentalStdlibApi注解,确保编译通过。
这个方案让我把原本需要 2 天的手动对接,压缩到 20 分钟。它证明了一点:Cursor 的价值不在于它多懂 Kotlin 或多懂 PHP,而在于它能把两个生态的“契约语言”(Composer 的 JSON Schema 和 Kotlin 的 Type System)自动对齐。
4. “Agent 模式”不是全自动,而是你思维的外置缓存区
网上很多教程把 Cursor Agent 描绘成“设定目标,它就自己干活”的黑箱。但真实体验是:Agent 是你思维过程的具象化容器,它的强大不在于执行,而在于记忆、关联和追问。我把它当作一个永不疲倦的结对编程伙伴,它不替你做决定,但会把你忽略的线索串起来,把模糊的想法变成可执行的 checklist。
4.1 一个真实案例:三天没解决的 Kotlin 协程内存泄漏,Agent 用 8 分钟定位
背景:我们的 Android App 在某个 Fragment 页面停留 5 分钟后,内存占用持续上涨,MAT 分析显示FlowCollector实例堆积。之前三位工程师花了三天,尝试了lifecycleScope、viewLifecycleOwner.lifecycleScope、rememberCoroutineScope等所有常见方案,无效。
我在 Cursor 中启动 Agent,输入初始指令:“分析这个 Fragment 的内存泄漏问题。已知:1)泄漏对象是 FlowCollector;2)只在特定页面复现;3)该页面使用了 Compose Navigation 和 StateFlow。”
Agent 的响应不是直接给答案,而是分三步:
Step 1:质疑前提
“您提到‘泄漏对象是 FlowCollector’,但 MAT 快照中显示的是
SafeCollector实例。SafeCollector是 Kotlin Flow 的内部装饰器,它本身不持有引用。真正的泄漏源通常是它所包装的Flow或Collector。能否提供Fragment中collectAsStateWithLifecycle的调用上下文?特别是StateFlow的创建位置。”
这一步就戳中了要害——我们一直盯着SafeCollector,却忽略了StateFlow的创建者。Agent 强制我把注意力拉回源头。
Step 2:关联线索
“检测到
Fragment中onCreateView创建了一个ViewModel,而该ViewModel的构造函数接收了一个Application参数。同时,StateFlow在ViewModel的init块中创建。Application是全局单例,如果StateFlow的value是一个持有Context的对象(比如Bitmap),就会导致泄漏。请检查StateFlow的初始值类型。”
我立刻去查ViewModel的init块,果然发现一行:private val _uiState = mutableStateOf<UiState>(UiState.Loading(bitmap)),而bitmap来自Application.resources。
Step 3:生成可验证的修复方案
“修复建议:1)将
bitmap的加载移出ViewModel,改用rememberAsyncImagePainter在 Compose 层按需加载;2)若必须在 ViewModel 中持有,使用WeakReference<Bitmap>包装;3)在onCleared()中显式调用_uiState.value = UiState.Idle()清空引用。请确认这些建议是否符合您的架构约束。”
整个过程,Agent 没写一行代码,但它用三次精准提问,把我从“如何优化 Collector”这个错误方向,拽回“谁在创建泄漏源”这个正确路径。它像一个经验丰富的调试老手,知道什么时候该打断你,问一句:“你确定问题真的出在这里吗?”
4.2 Agent 的“追问机制”如何工作?关键在状态持久化
Agent 的追问能力,依赖于它对对话状态的深度维护。它不是简单地记住上一句话,而是构建了一个多维状态图:
- 代码图谱:自动解析你打开的所有文件,建立类、函数、变量间的调用关系;
- 意图图谱:从你的 prompt 中提取主谓宾,标记“待验证假设”(如“
StateFlow可能泄漏”)、“已确认事实”(如“Fragment使用 Navigation”)、“待查证线索”(如“Application是否被传递”); - 环境图谱:读取
build.gradle.kts、gradle.properties、.gitignore,推断项目约束(如“使用 Hilt 依赖注入”、“禁用 Configuration Cache”)。
当你输入新 prompt,Agent 会先在状态图中搜索匹配节点。比如你问“怎么优化性能”,它不会泛泛而谈,而是查找“待验证假设”中与性能相关的条目(如“Flow.collect在主线程调用”),然后针对性追问。
这个机制的副作用是:Agent 会“记住”你的错误假设。有一次我误判某个 Kotlin 编译错误是 Gradle 插件问题,Agent 在后续对话中反复引用这个错误前提,直到我手动输入:“清除所有关于 Gradle 插件的假设,重新分析错误日志”。
注意:Cursor 没有公开的“清除 Agent 状态”按钮。我的做法是:在 Chat 输入框中输入
/reset(这是未文档化的内部指令),或者新建一个 Chat 标签页。后者更可靠,因为/reset有时会残留部分上下文。
4.3 当 Agent “卡住”时,如何用“人工注入”重启推理链?
Agent 最让人沮丧的时刻,是它陷入无限追问循环。比如你问“为什么这个 Kotlin 协程不执行?”,它连续问:“请提供launch的调用位置” → “请提供CoroutineScope的定义” → “请提供CoroutineDispatcher的配置”……而你其实只想知道“是不是因为lifecycleScope被销毁了?”
这时,最高效的解法不是换问题,而是人工注入关键事实,强行闭合推理链。我的标准操作是:
- 复制当前
Fragment的onDestroyView()方法体; - 在 Chat 中粘贴,并输入:“这是
onDestroyView的实现。请基于此,判断lifecycleScope是否在此时被取消。如果是,请给出验证方法。”
Agent 会立刻停止追问,转而分析lifecycleScope的生命周期绑定逻辑,并建议你添加Log.d("Scope", "is active: ${lifecycleScope.isActive}")到onDestroyView中。这个技巧的本质,是用确定性信息(代码片段)覆盖不确定性假设(你的口头描述),让 Agent 从“猜谜模式”切换到“验证模式”。
这揭示了一个深层真相:Cursor Agent 不是万能的神,而是你思维的延伸。它最强大的时候,不是它独自工作时,而是你用精准的代码片段、明确的约束条件、果断的事实注入,与它形成高效协同的时候。
5. JetBrains 不是对手,而是你工作流的“战略备份系统”
我至今仍每天打开 IntelliJ IDEA Ultimate,不是出于习惯,而是因为一个清醒的认知:Cursor 是战术突击队,JetBrains 是战略大本营。它们解决的是软件开发中完全不同的问题域,强行比较谁“更好”,就像问“手术刀和核磁共振仪哪个更重要”。
5.1 JetBrains 不可替代的三大“硬核能力”
5.1.1 深度语言引擎:当 Cursor 的“理解”开始漂移
Cursor 的 Kotlin 支持很棒,但它依赖 LSP(Language Server Protocol)协议与语言服务器通信。而 JetBrains 的 Kotlin 插件是直接嵌入 IDE 的 JVM 进程,共享相同的内存空间和类型系统。这意味着:
- 重构精度:当你对一个
sealed class执行“Extract Superclass”,IntelliJ 能精确识别所有is检查、when分支、copy()调用,并同步更新;Cursor 的“Refactor”功能只能做文本级替换,很可能漏掉when中的else -> throw IllegalStateException()分支。 - 错误定位:
error:kotlin: unknown kotlin jvm target: 21这类编译器错误,IntelliJ 能直接跳转到build.gradle.kts中kotlinOptions.jvmTarget行,并高亮显示与kotlinVersion的不兼容;Cursor 只能告诉你“检查 JVM Target”,你需要自己去翻 Gradle 文件。 - 调试深度:在
suspend fun中设置断点,IntelliJ 能显示完整的协程栈帧(包括ContinuationInterceptor、DispatchedContinuation),而 Cursor 的调试器本质是 VS Code 的封装,看不到 Kotlin 运行时的底层细节。
我有一个硬性规则:所有涉及 Kotlin 编译器特性的操作(@JvmName、@file:Suppress、inline函数内联分析),一律在 IntelliJ 中完成。Cursor 在这里不是辅助,而是干扰源。
5.1.2 工业级调试:当“为什么出错”比“怎么修复”更重要
Cursor 的 Chat 可以告诉你“把if (user != null)改成user?.let { }”,但它无法回答“为什么user在这里会是 null?”。而 IntelliJ 的调试器,能让你:
- 在
user变量上右键 → “Add to Watches”,设置条件断点user == null && Thread.currentThread().name.contains("main"); - 查看
user的创建调用栈,追溯到UserRepository的getUser()方法; - 在
getUser()上设置“Method Breakpoint”,观察所有调用方(包括反射调用); - 使用 “Evaluate Expression” 动态执行
userDao.findById(id),验证数据层是否真的返回 null。
这种“向下钻取”的能力,是 Cursor 这类 AI 工具的天然盲区。AI 擅长模式匹配和代码生成,但不擅长因果溯源。我的工作流是:用 Cursor 快速生成修复代码 → 粘贴进 IntelliJ → 启动调试器,验证修复是否真正解决了根因。
5.1.3 生态整合:当“开箱即用”就是生产力
IntelliJ 对 JetBrains 生态的整合,是 Cursor 无法复制的护城河:
- Database Tools:直接连接 MySQL、PostgreSQL,执行 SQL,可视化查看结果,生成实体类;
- HTTP Client:在
.http文件中编写请求,自动保存历史,生成 curl 命令,甚至导出为 Postman Collection; - Docker Integration:一键构建镜像、运行容器、查看日志,所有操作在 IDE 内完成;
- Git Tooling:Cherry-pick、Rebase、Interactive Rebase 的图形化界面,比命令行直观十倍。
这些功能不是“锦上添花”,而是日常开发的氧气。我曾试图在 Cursor 中用插件模拟 Database Tools,结果发现:插件市场里没有一个能稳定连接 MySQL 8.0+ 的 JDBC 驱动,因为 Cursor 的插件架构不支持原生 JNI 库。而 IntelliJ 的 Database 工具,是 JetBrains 自己用 Java 实现的完整 JDBC 客户端。
5.2 我的“双IDE协同”工作流:一份配置,两套快捷键
既然两者各有千秋,最优解就是让它们无缝协作。我的实践方案是:
5.2.1 统一配置中心:让 Cursor 和 IntelliJ 共享同一套规则
- 代码风格:在 IntelliJ 中导出
code-style.xml,放入项目根目录。Cursor 会自动读取并应用相同的缩进、空格、命名规范; - .editorconfig:这是跨 IDE 的通用标准,确保
indent_style = space、charset = utf-8等基础规则一致; - .gitignore:Cursor 的文件搜索会尊重
.gitignore,所以把*.iml、.idea/加入其中,避免它索引 IntelliJ 的私有文件。
5.2.2 快捷键映射:让肌肉记忆不打架
Cursor 默认用 VS Code 键位,但我多年 IntelliJ 用户,手指已经长在Ctrl+Alt+L(格式化)、Ctrl+Shift+Alt+T(重构)上。我的解决方案是:
- 在 Cursor 设置中,打开
Keymap→Import Keymap→ 选择IntelliJ IDEA; - 手动调整冲突项:
Ctrl+Alt+L在 Cursor 中是“Format Selection”,我把它改为Ctrl+Alt+Shift+L,把Ctrl+Alt+L留给格式化全文; - 为 Cursor 独有功能分配“专属键位”:
Cmd+K(AI 命令)保持不变,Cmd+Shift+P(命令面板)改为Cmd+Option+P,避免与 IntelliJ 的Find Action冲突。
这套映射让我在两个 IDE 间切换时,手指不会犹豫。它不是让 Cursor 模仿 IntelliJ,而是让 IntelliJ 的习惯,在 Cursor 中找到自然的落点。
5.2.3 文件路由策略:什么文件该在哪个 IDE 打开?
我制定了严格的文件路由规则,避免混乱:
| 文件类型 | 默认打开 IDE | 理由 | 例外情况 |
|---|---|---|---|
*.kt、*.java、*.xml(Android) | IntelliJ IDEA | 深度语言分析、Layout Editor、APK Analyzer | 仅当进行 AI 辅助重构(如批量重命名)时,临时用 Cursor |
*.php、*.js、composer.json | Cursor | Composer 诊断、JSX 快速生成、多文件 Tab 补全 | 当需要数据库查询或 HTTP 测试时,切到 IntelliJ |
build.gradle.kts、pom.xml | Cursor | 依赖版本升级、插件配置生成 | 当需要 Gradle Profiling 或构建扫描时,切到 IntelliJ |
*.md、*.txt | Cursor | AI 辅助写作、技术文档生成 | 当需要插入 PlantUML 图表时,切到 IntelliJ(支持实时渲染) |
这个规则不是教条,而是经过三个月迭代后的最优平衡。它确保了:90% 的时间,我打开的 IDE 就是当下任务最合适的工具;剩下 10%,我知道该按哪个快捷键切过去。
最后分享一个个人体会:技术工具的终极价值,从来不是它有多炫酷,而是它能否让你忘记它的存在。当我用 Cursor 的 Tab 补全写 Kotlin 时,我不再想“AI 在帮我”,我只是在写代码;当我用 IntelliJ 调试协程时,我不再想“这个 IDE 多强大”,我只是在解决问题。Cursor 和 JetBrains,最终都退隐为我指尖延伸出去的、沉默而可靠的器官。这或许就是工具演进的终点——不是取代人类,而是让人类终于可以,只做人类最擅长的事:思考、创造、连接。