做异端中的异端 -- Emacs裸奔之路4: 你不需要IDE

确切地说,你不需要在IDE里面编写或者阅读代码。

IDE用于Render资源文件比较合适,但处理文本,并不划算。

这的文本文件,包括源代码,配置文件,文档等非二进制文件。

先说说IDE带的便利:

  • 函数或者变量的自动补全
  • 函数或者类定义的跳转

但这些便利,是有代价的。

IDE需要不断地扫描项目中的源码,这是一个词法与语法分析的过程,与编译过程类似,只是不产生机器码而已。

这是一个非常耗时的过程,使用过Android Studio或者Eclipse的同学应该体验深刻,项目启动时实在太慢了。

启动之后,文件已经有修改,特别是Git分支切换或者版本回滚时,整个机器卡壳几十秒钟是时常的事。

而且IDE还要求文件是可以编译的,如果项目外文件或者项目文件不完整,还不能实现这两个功能。

插一个真事,有一次搞ROS开发,ROS包基本都是Cpp与Python,关键是ROS没有IDE,而且开源的项目文件非常多,有几个同事就瞎眼了。

经常找不到代码在哪里,时不时要问我,哪个功能在哪里,就算知道代码也找不到文件。这就是长期依赖IDE的后果。

所以,为这样两个功能,把机器搞得龟速,值得吗?

解决方案

这个问题,要权衡利弊,以退为进 -- 放弃IDE,停止这种耗时扫描

对付文本文件,直接可以采用蛮力搜索。

具体地说,想找某个符号定义,直接在整个目录中搜索。对于库中的符号,第一次手输,之后使用字符串补全。

注意,这里对编程语言,项目能不能编译,是没有要求的。

看似暴力,但直接了当,逻辑简单,绿色无污染。

因为单个文本文件,很少会超过10M, 而整个项目的所有文本文件累计很少会超过50M。

grep整个目录通常就几秒的事情,而且大部分情况是一瞬间的事。

这样做的结果是:

  • 不再依赖于任何IDE
  • 不再依赖于项目管理
  • 不再受限于编程语言

这个思想不限于Emacs,我这前使用Vim也是这样干的。

不管Emacs还是Vim都是跨平台的,意味着你从Windows到Unix甚至Mac都是如履平地的。

有什么比这个更加有吸引力?

Vim可以使用Quickfix实现同样的功能。

这里只介绍Emacs的方案。

grep的关键一点是,可以反复地对结果进行筛选,这个非常非常重要。

想像一下grep一次给你1000条件记录,有多大意义?

但如果可以再次在这个1000中筛选,那就非常不一样。

简单反复筛选可以做到万里挑一!

举例

按这个思想,在QMK项目中,找程序入口,

这是一个相当规模的开源项目, 除去lib下的文件都有30000多个,这是wc统计的结果:

think@DESKTOP-70MSAQ1 MINGW64 /f/AA-MyWork/QMK/keychron/qmk_firmware (mykeyboard-v1)
$ git ls-files | wc -l
37042

从三万个文件中找出一个函数,并不容易:

  1. 搜索main, 得到7000多条记录

  2. 搜索.c以过滤非C文件:

  3. 搜索void int, 原因main函数的参数或返回值无非这两个

  4. 搜索全字匹配main:

至此,只有不到70项,可以肉眼找到程序入口了。

这个过程中的 所有buffer都是保留 ,意味着如果我第二步筛选的条件错了,还可以回到第一步结果中搜索,直到你满意。

这是包括Vim在内的很多软件无法做到的,但这个在试错过程中,又非常重要。

具体实现

代码非常简单,主要还是调用Emacs的grep与occur命令,再切换到结果窗口. 开头几行只为了保存历史。

(global-set-key (kbd (concat custom-user-prefix-key "/")) 'ich/grep)
(global-set-key (kbd (concat custom-user-prefix-key "l")) 'ich/occur)

  (defun ich/grep ( pattern directory )
    (interactive
     (list
      (custom/select-a-pattern "Please input a pattern (grep): ")
      (custom/select-a-directory "Please select a directory (grep): ")
      ) )

    (custom/search-history-add pattern)
    (custom/save-search-history)

    (setq old-directory default-directory)
    (cd directory)  
    (grep (concat "rg . -n -H --no-heading -i -e " pattern))
    (cd old-directory)  

    (setq find nil)
    (setq i 0)
    (while (and (not find) (< i (length (window-list))))
      (if (equal "*grep*" (buffer-name))
          (setq find t)
        (other-window 1))
      (setq i (1+ i)))

    (if find
        (quit-window))

    (switch-to-buffer "*grep*"))

  (defun ich/occur ( pattern )
    (interactive
     (list
      (custom/select-a-pattern "Please input a pattern (occur): ")))

    (custom/search-history-add pattern)
    (custom/save-search-history)

    (occur pattern)

    (setq find nil)
    (setq i 0)
    (while (and (not find) (< i (length (window-list))))
      (if (equal "*Occur*" (buffer-name))
          (setq find t)
        (other-window 1))
      (setq i (1+ i)))

    (if find
        (quit-window))

    (switch-to-buffer "*Occur*"))
相关推荐
天赐细莲1 小时前
(C语言) 8大翻译阶段
c语言·开发语言·c++·windows·微软·编辑器
帅得不敢出门1 小时前
vim插件管理器vim-plug替代vim-bundle
linux·编辑器·vim
键盘上的疯兔7 小时前
做异端中的异端 -- Emacs裸奔之路3: 上古神键Hyper
编辑器·emacs·qmk
IT猫咪酱15 小时前
【前端】vscode报错: 无法加载文件 D:\nodejs\node_global\yarn.ps1,因为在此系统上禁止运行脚本。
ide·vscode·编辑器
抛物线.19 小时前
解决 Vim 上下左右变成 ABCD 的问题
编辑器·vim·excel
折翅嘀皇虫1 天前
scxml editor插件在vscode中无法使用的问题
ide·vscode·编辑器
赛恩斯1 天前
vim 显示行数和删除内容操作
编辑器·vim·excel
Evaporator Core1 天前
Vim 高级操作与技巧指南
编辑器·vim·excel
键盘上的疯兔1 天前
做异端中的异端 -- Emacs裸奔之路1: Vim vs Emacs
编辑器·vim·emacs