你的 .emacs 里有啥?

Posted

技术标签:

【中文标题】你的 .emacs 里有啥?【英文标题】:What's in your .emacs?你的 .emacs 里有什么? 【发布时间】:2010-09-14 07:45:03 【问题描述】:

我最近换了几次电脑,在某处我丢失了我的 .emacs。我正在尝试重新构建它,但是当我这样做时,我想我会选择其他人使用的其他好的配置。

那么,如果您使用 Emacs,您的 .emacs 中有什么内容?

我的现在很贫瘠,只包含:

    全局字体锁定模式! (global-font-lock-mode 1) 我个人对缩进、制表符和空格的偏好。 使用 cperl-mode 代替 perl-mode。 编译的快捷方式。

你认为什么有用?

【问题讨论】:

任何拥有 4 行 .emacs 文件的人都是可疑的。 @A. Rex:关于不丢失您的 .emacs 文件...有几种选择:最近有些人为他们的配置文件设置了 DVCS,因此只需“推送”和 tadaaaa:免费在线备份。但我觉得这有点牵强,更喜欢更简单的方法:我只是将我的(文本)配置文件附加到我的 GMail 帐户中的电子邮件(我为 GMail 启用了 POP,这样我也可以离线备份我的电子邮件) .有趣的是,我昨天对我的 .emacs 做了另一个“GMAil 备份”:) 【参考方案1】:
(put 'erase-buffer 'disabled nil)
(put 'downcase-region 'disabled nil)
(set-variable 'visible-bell t)
(set-variable 'tool-bar-mode nil)
(set-variable 'menu-bar-mode nil)

(setq load-path (cons (expand-file-name "/usr/share/doc/git-core/contrib/emacs") load-path))
 (require 'vc-git)
 (when (featurep 'vc-git) (add-to-list 'vc-handled-backends 'git))
 (require 'git)
 (autoload 'git-blame-mode "git-blame"
           "Minor mode for incremental blame for Git." t)

【讨论】:

【参考方案2】:

你可以看这里:http://www.dotemacs.de/

而且我的 .emacs 也很长,无法将其放在这里,因此它会使答案不太易读。无论如何,如果你希望我可以发送给你。

我还建议您阅读以下内容:http://steve.yegge.googlepages.com/my-dot-emacs-file

【讨论】:

【参考方案3】:

以下是一些我已经依赖的键映射:

(global-set-key [(control \,)] 'goto-line)
(global-set-key [(control \.)] 'call-last-kbd-macro)
(global-set-key [(control tab)] 'indent-region)
(global-set-key [(control j)] 'join-line)
(global-set-key [f1] 'man)
(global-set-key [f2] 'igrep-find)
(global-set-key [f3] 'isearch-forward)
(global-set-key [f4] 'next-error)
(global-set-key [f5] 'gdb)
(global-set-key [f6] 'compile)
(global-set-key [f7] 'recompile)
(global-set-key [f8] 'shell)
(global-set-key [f9] 'find-next-matching-tag)
(global-set-key [f11] 'list-buffers)
(global-set-key [f12] 'shell)

其他一些杂项,主要用于 C++ 开发:

;; Use C++ mode for .h files (instead of plain-old C mode)
(setq auto-mode-alist (cons '("\\.h$" . c++-mode) auto-mode-alist))

;; Use python-mode for SCons files
(setq auto-mode-alist (cons '("SConstruct" . python-mode) auto-mode-alist))
(setq auto-mode-alist (cons '("SConscript" . python-mode) auto-mode-alist))

;; Parse CppUnit failure reports in compilation-mode
(require 'compile)
(setq compilation-error-regexp-alist
      (cons '("\\(!!!FAILURES!!!\nTest Results:\nRun:[^\n]*\n\n\n\\)?\\([0-9]+\\)) test: \\([^(]+\\)(F) line: \\([0-9]+\\) \\([^ \n]+\\)" 5 4)
            compilation-error-regexp-alist))

;; Enable cmake-mode from http://www.cmake.org/Wiki/CMake_Emacs_mode_patch_for_comment_formatting
(require 'cmake-mode)
(setq auto-mode-alist
      (append '(("CMakeLists\\.txt\\'" . cmake-mode)
                ("\\.cmake\\'" . cmake-mode))
              auto-mode-alist))

;; "M-x reload-buffer" will revert-buffer without requiring confirmation
(defun reload-buffer ()
  "revert-buffer without confirmation"
  (interactive)
  (revert-buffer t t))

【讨论】:

【参考方案4】:

这不是整个套件和 kaboodle,但它是我收集的一些更有用的 sn-ps:

(defadvice show-paren-function (after show-matching-paren-offscreen
                                      activate)
  "If the matching paren is offscreen, show the matching line in the                               
echo area. Has no effect if the character before point is not of                                   
the syntax class ')'."
  (interactive)
  (let ((matching-text nil))
    ;; Only call `blink-matching-open' if the character before point                               
    ;; is a close parentheses type character. Otherwise, there's not                               
    ;; really any point, and `blink-matching-open' would just echo                                 
    ;; "Mismatched parentheses", which gets really annoying.                                       
    (if (char-equal (char-syntax (char-before (point))) ?\))
        (setq matching-text (blink-matching-open)))
    (if (not (null matching-text))
        (message matching-text))))

;;;;;;;;;;;;;;;
;; UTF-8
;;;;;;;;;;;;;;;;;;;;
;; set up unicode
(prefer-coding-system       'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
;; This from a japanese individual.  I hope it works.
(setq default-buffer-file-coding-system 'utf-8)
;; From Emacs wiki
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
;; Wwindows clipboard is UTF-16LE 
(set-clipboard-coding-system 'utf-16le-dos)


(defun jonnay-timestamp ()
  "Spit out the current time"
  (interactive)
  (insert (format-time-string "%Y-%m-%d")))

(defun jonnay-sign ()
  "spit out my name, email and the current time"
  (interactive)
  (insert "-- Jonathan Arkell (jonathana@criticalmass.com)")
  (jonnay-timestamp))


;; Cygwin requires some seriosu setting up to work the way i likes it
(message "Setting up Cygwin...")
(let* ((cygwin-root "c:")
       (cygwin-bin (concat cygwin-root "/bin"))
       (gambit-bin "/usr/local/Gambit-C/4.0b22/bin/")
       (snow-bin "/usr/local/snow/current/bin")
       (mysql-bin "/wamp/bin/mysql/mysql5.0.51a/bin/"))
   (setenv "PATH" (concat cygwin-bin ";" ;
                          snow-bin ";" 
                          gambit-bin ";"
                          mysql-bin ";"
                          ".;")  
           (getenv "PATH"))
   (setq exec-path (cons cygwin-bin exec-path)))

(setq shell-file-name "bash")
(setq explicit-shell-file-name "bash")

(require 'cygwin-mount)
(cygwin-mount-activate)
(message "Setting up Cygwin...Done")


; Completion isn't perfect, but close
(defun my-shell-setup ()
   "For Cygwin bash under Emacs 20+"
   (setq comint-scroll-show-maximum-output 'this)
   (setq comint-completion-addsuffix t)
   (setq comint-eol-on-send t)
   (setq w32-quote-process-args ?\")
   (make-variable-buffer-local 'comint-completion-addsuffix))

(setq shell-mode-hook 'my-shell-setup)
(add-hook 'emacs-startup-hook 'cygwin-shell)


; Change how home key works
(global-set-key [home] 'beginning-or-indentation)
(substitute-key-definition 'beginning-of-line 'beginning-or-indentation global-map)


(defun yank-and-down ()
  "Yank the text and go down a line."
  (interactive)
  (yank)
  (exchange-point-and-mark)
  (next-line))

(defun kill-syntax (&optional arg)
  "Kill ARG sets of syntax characters after point."
  (interactive "p")
  (let ((arg (or arg 1))
    (inc (if (and arg (< arg 0)) 1 -1))
    (opoint (point)))
    (while (not (= arg 0))
      (if (> arg 0)
      (skip-syntax-forward (string (char-syntax (char-after))))
    (skip-syntax-backward (string (char-syntax (char-before)))))
      (setq arg (+ arg inc)))
    (kill-region opoint (point))))

(defun kill-syntax-backward (&optional arg)
  "Kill ARG sets of syntax characters preceding point."
  (interactive "p")
  (kill-syntax (- 0 (or arg 1))))

(global-set-key [(control shift y)] 'yank-and-down)
(global-set-key [(shift backspace)] 'kill-syntax-backward)
(global-set-key [(shift delete)] 'kill-syntax)


(defun insert-file-name (arg filename)
  "Insert name of file FILENAME into buffer after point.
  Set mark after the inserted text.

  Prefixed with \\[universal-argument], expand the file name to
  its fully canocalized path.

  See `expand-file-name'."
  ;; Based on insert-file in Emacs -- ashawley 2008-09-26
  (interactive "*P\nfInsert file name: ")
  (if arg
      (insert (expand-file-name filename))
      (insert filename)))

(defun kill-ring-save-filename ()
  "Copy the current filename to the kill ring"
  (interactive)
  (kill-new (buffer-file-name)))

(defun insert-file-name ()
  "Insert the name of the current file."
  (interactive)
  (insert (buffer-file-name)))

(defun insert-directory-name ()
  "Insert the name of the current directory"
  (interactive)
  (insert (file-name-directory (buffer-file-name))))

(defun jonnay-toggle-debug ()
  "Toggle debugging by toggling icicles, and debug on error"
  (interactive)
  (toggle-debug-on-error)
  (icicle-mode))


(defvar programming-modes
  '(emacs-lisp-mode scheme-mode lisp-mode c-mode c++-mode 
    objc-mode latex-mode plain-tex-mode java-mode
    php-mode css-mode js2-mode nxml-mode nxhtml-mode)
  "List of modes related to programming")

; Text-mate style indenting
(defadvice yank (after indent-region activate)
  (if (member major-mode programming-modes)
      (indent-region (region-beginning) (region-end) nil)))

【讨论】:

感谢您帮助我恢复了 20 年前从同事和主管那里复制的“show-paren-function”!【参考方案5】:

我使用 paredit 来轻松 (e)lisp 处理和 ido 模式 minibuffer 完成。

【讨论】:

【参考方案6】:

我有这个将yesno 提示更改为yn 提示:

(fset 'yes-or-no-p 'y-or-n-p)

我有这些来启动 Emacs,而没有像我从 this question 那里得到的那样“大张旗鼓”。

(setq inhibit-startup-echo-area-message t)
(setq inhibit-startup-message t)

Steve Yegge's 函数可以重命名您正在编辑的文件及其相应的缓冲区:

(defun rename-file-and-buffer (new-name)
  "Renames both current buffer and file it's visiting to NEW-NAME."
  (interactive "sNew name: ")
  (let ((name (buffer-name))
 (filename (buffer-file-name)))
    (if (not filename)
 (message "Buffer '%s' is not visiting a file!" name)
      (if (get-buffer new-name)
   (message "A buffer named '%s' already exists!" new-name)
 (progn
   (rename-file name new-name 1)
   (rename-buffer new-name)
   (set-visited-file-name new-name)
   (set-buffer-modified-p nil))))))

【讨论】:

【参考方案7】:

我最喜欢的sn-p。 Emacs 中的终极亮点:

;; real lisp hackers use the lambda character
;; courtesy of stefan monnier on c.l.l
(defun sm-lambda-mode-hook ()
  (font-lock-add-keywords
   nil `(("\\<lambda\\>"
   (0 (progn (compose-region (match-beginning 0) (match-end 0)
        ,(make-char 'greek-iso8859-7 107))
      nil))))))
(add-hook 'emacs-lisp-mode-hook 'sm-lambda-mode-hook)
(add-hook 'lisp-interactive-mode-hook 'sm-lamba-mode-hook)
(add-hook 'scheme-mode-hook 'sm-lambda-mode-hook)

所以您在编辑 lisp/scheme 时会看到以下内容:

(global-set-key "^Cr" '(λ () (interactive) (revert-buffer t t nil)))

【讨论】:

(眼睛向后仰,Cheeso 摔倒,紧张症) 不,终极的视觉糖果是能够为 every 模式做那种事情:pretty-mode! (更新版本见github)【参考方案8】:

在 Emacs 中刷新您正在编辑的网页

(defun moz-connect()
  (interactive)
  (make-comint "moz-buffer" (cons "127.0.0.1" "4242"))
  (global-set-key "\C-x\C-g" '(lambda () 
                (interactive)
                (save-buffer)
                (comint-send-string "*moz-buffer*" "this.BrowserReload()\n"))))

与http://hyperstruct.net/projects/mozlab结合使用

【讨论】:

【参考方案9】:

可以证明非常有用的一件事:在它变得太大之前,尝试将其拆分为多个文件以执行各种任务:我的 .emacs 只是设置我的加载路径并加载一堆文件 - 我已经拥有了所有mode-configs.el 中我的模式特定设置,keys.el 中的键绑定等等

【讨论】:

【参考方案10】:

我还有很多其他的已经提到了,但我认为这些是绝对必要的:

(transient-mark-mode 1) ; makes the region visible
(line-number-mode 1)    ; makes the line number show up
(column-number-mode 1)  ; makes the column number show up

【讨论】:

【参考方案11】:

这块对我来说是最重要的:

(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

不过,我一直不清楚它们之间的区别。货物崇拜,我猜......

【讨论】:

【参考方案12】:

使用ultimate dotfiles site。在此处添加您的“.emacs”。阅读其他人的“.emacs”。

【讨论】:

已接受,因为在某种意义上它包含了所有其他答案。 =)【参考方案13】:

您可以在 my site 上找到我的配置(在 html 和 tar'ed 存档中)。它包含许多不同模式的设置

【讨论】:

【参考方案14】:

我使用 webjump 设置了一些方便的网页和搜索快捷方式

(require 'webjump)
(global-set-key [f2] 'webjump)
(setq webjump-sites
      (append '(
        ("Reddit Search" .
         [simple-query "www.reddit.com" "http://www.reddit.com/search?q=" ""])
        ("Google Image Search" .
         [simple-query "images.google.com" "images.google.com/images?hl=en&q=" ""])
        ("Flickr Search" .
         [simple-query "www.flickr.com" "flickr.com/search/?q=" ""])
        ("Astar algorithm" . 
         "http://www.heyes-jones.com/astar")
        )
          webjump-sample-sites))

关于这里如何工作的博客文章

http://justinsboringpage.blogspot.com/2009/02/search-reddit-flickr-and-google-from.html

我也推荐这些:

(setq visible-bell t) ; no beeping

(setq transient-mark-mode t) ; visually show region

(setq line-number-mode t) ; show line numbers

(setq global-font-lock-mode 1) ; everything should use fonts

(setq font-lock-maximum-decoration t)

我也去掉了一些多余的 gui 东西

  (if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
  (if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
  (if (fboundp 'menu-bar-mode) (menu-bar-mode -1)))

【讨论】:

【参考方案15】:

一行修改加载路径 一行加载我的初始化库 一行加载我的 emacs 初始化文件

当然,“emacs 初始化文件”非常多,每个特定的东西一个,以确定的顺序加载。

【讨论】:

【参考方案16】:

这个问题很难回答,因为每个人使用 Emacs 的目的都不同。

此外,更好的做法可能是亲吻您的 dotmacs。由于 Easy Customization Interface 在 Emacs 的模式中得到广泛支持,您应该将所有自定义存储在您的 custom-file 中(这可能是您的 dotmacs 中的一个单独位置),对于 dotemacs,仅将加载路径设置放入其中、包需要、钩子和键绑定。一旦你开始使用Emacs Starter Kit,一大堆有用的设置也可能会从你的 dotmacs 中删除。

【讨论】:

【参考方案17】:

我的.emacs只有127行,这里是最有用的小sn-ps:

;; keep backup files neatly out of the way in .~/
(setq backup-directory-alist '(("." . ".~")))

这使得我在目录中发现杂乱无章的 *~ 文件进入一个特殊的目录,在这种情况下是 .~

;; uniquify changes conflicting buffer names from file<2> etc
(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified
(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers

这设置了 uniquify ,它使用尽可能多的文件的整个路径将多个文件具有相同名称时获得的那些丑陋的文件 等缓冲区名称更改为一个更整洁、明确的名称。

就是这样......其余的都是相当标准的东西,我相信每个人都知道。

【讨论】:

【参考方案18】:

emacs-starter-kit 作为基础,然后我添加了..vimpulse.elwhitespace.elyasnippettextmate.elnewsticker.el

在我的 ~/.emacs.d/$USERNAME.el (dbr.el) 文件中:

(add-to-list 'load-path (concat dotfiles-dir "/vendor/"))

;; Snippets
(add-to-list 'load-path "~/.emacs.d/vendor/yasnippet/")
(require 'yasnippet)

(yas/initialize)
(yas/load-directory "~/.emacs.d/vendor/yasnippet/snippets")

;; TextMate module
(require 'textmate)
(textmate-mode 'on)

;; Whitespace module
(require 'whitespace)
(add-hook 'ruby-mode-hook 'whitespace-mode)
(add-hook 'python-mode-hook 'whitespace-mode)

;; Misc
(flyspell-mode 'on)
(setq viper-mode t)
(require 'viper)
(require 'vimpulse)

;; IM
(eval-after-load 'rcirc '(require 'rcirc-color))
(setq rcirc-default-nick "_dbr")
(setq rcirc-default-user-name "_dbr")
(setq rcirc-default-user-full-name "_dbr")

(require 'jabber)

;;; Google Talk account
(custom-set-variables
 '(jabber-connection-type (quote ssl))
 '(jabber-network-server "talk.google.com")
 '(jabber-port 5223)
 '(jabber-server "mysite.tld")
 '(jabber-username "myusername"))

;; Theme
(color-theme-zenburn)

;; Key bindings
(global-set-key (kbd "M-z") 'undo)
(global-set-key (kbd "M-s") 'save-buffer)
(global-set-key (kbd "M-S-z") 'redo)

【讨论】:

【参考方案19】:

始终将我的配置保存在 svn http://my-trac.assembla.com/ez-conf/browser/emacs.d

【讨论】:

【参考方案20】:

读完这篇文章后,我认为最好有一个简单的站点来进行最好的 .emacs 修改。随时在这里发布和投票:

http://dotemacs.slinkset.com/

【讨论】:

【参考方案21】:

我尽量保持我的 .emacs 井井有条。配置将始终在进行中,但我开始对整体结构感到满意。

所有东西都在~/.elisp 下,这是一个受版本控制的目录(如果感兴趣的话,我使用 git)。 ~/.emacs 只是指向 ~/.elisp/dotemacs,它本身只是加载 ~/.elisp/cfg/init。该文件依次通过require 导入各种配置文件。这意味着配置文件需要表现得像模式:他们导入他们依赖的东西,他们provide自己在文件的末尾,例如(provide 'my-ibuffer-cfg)。我在我的配置中定义的所有标识符前面加上my-

我根据模式/主题/任务组织配置,而不是根据它们的技术含义,例如我没有有一个单独的配置文件,其中定义了所有键绑定或面。

我的init.el 定义了以下钩子,以确保 Emacs 在保存时重新编译配置文件(编译后的 Elisp 加载速度更快,但我不想手动执行此步骤):

;; byte compile config file if changed
(add-hook 'after-save-hook
          '(lambda ()
                   (when (string-match
                          (concat (expand-file-name "~/.elisp/cfg/") ".*\.el$")
                          buffer-file-name)
           (byte-compile-file buffer-file-name))))

这是~/.elisp的目录结构:

~/.elisp/todo.org:组织模式文件,我在其中跟踪仍需要完成的事情(+ 愿望清单项目)。

~/.elisp/dotemacs~/.emacs 的符号链接目标,加载 ~/.elisp/cfg/init

~/.elisp/cfg:我自己的配置文件。

~/.elisp/modes:仅包含单个文件的模式。

~/.elisp/packages:带有 lisp、文档和可能的资源文件的复杂模式。

我使用 GNU Emacs,那个版本没有真正支持包。因此我手动组织它们,通常是这样的: ~/.elisp/packages/foobar-0.1.3 是包的根目录。子目录 lisp 包含所有 lisp 文件,info 是文档所在的位置。 ~/.elisp/packages/foobar 是一个符号链接,它指向当前使用的软件包版本,因此我在更新某些内容时不需要更改我的配置文件。对于某些软件包,我保留了一个 ~/.elisp/packages/foobar.installation 文件,我在其中记录了安装过程。出于性能原因,我在新安装的包中编译所有 elisp 文件,默认情况下应该不是这种情况。

【讨论】:

【参考方案22】:

这是我自己的一些东西:

以 ISO 8601 格式插入日期:

(defun insertdate ()
  (interactive)
  (insert (format-time-string "%Y-%m-%d")))

(global-set-key [(f5)] 'insertdate)

对于 C++ 程序员,创建一个类骨架(类的名称将与没有扩展名的文件名相同):

(defun createclass ()
  (interactive)
  (setq classname (file-name-sans-extension (file-name-nondirectory   buffer-file-name)))
  (insert 
"/**
  * " classname".h 
  *
  * Author: Your Mom
  * Modified: " (format-time-string "%Y-%m-%d") "
  * Licence: GNU GPL
  */
#ifndef "(upcase classname)"
#define "(upcase classname)"

class " classname "

  public:
    "classname"();
    ~"classname"();

  private:

;
#endif
"))

自动创建右括号:

(setq skeleton-pair t)
(setq skeleton-pair-on-word t)
(global-set-key (kbd "[") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "(") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "") 'skeleton-pair-insert-maybe) 
(global-set-key (kbd "<") 'skeleton-pair-insert-maybe)

【讨论】:

【参考方案23】:

对于Scala 编码员

;; Load the ensime lisp code... http://github.com/aemoncannon/ensime
(add-to-list 'load-path "ENSIME_ROOT/elisp/")
(require 'ensime)
;; This step causes the ensime-mode to be started whenever ;; scala-mode is started for a buffer. You may have to customize this step ;; if you're not using the standard scala mode.
(add-hook 'scala-mode-hook 'ensime-scala-mode-hook)
;; MINI HOWTO:  ;; Open .scala file. M-x ensime (once per project)

【讨论】:

【参考方案24】:

https://b7j0c.org/stuff/dotemacs.html

【讨论】:

【参考方案25】:

我是 emacs 新手,在我的 .emacs 文件中有

缩进配置 颜色主题 php模式、coffee模式和js2模式 ido模式

【讨论】:

【参考方案26】:

FWIW,我的 .emacs 在这里:

http://svn.red-bean.com/repos/kfogel/trunk/.emacs

【讨论】:

【参考方案27】:

很多东西:https://github.com/tavisrudd/emacs.d

el-get 使管理它和依赖关系变得更加容易:https://github.com/tavisrudd/emacs.d/blob/master/dss-init-el-get.el

【讨论】:

【参考方案28】:

请参阅 EmacsWiki 的 DotEmacs 类别。它提供了许多指向解决此问题的页面的链接。

【讨论】:

【参考方案29】:

多年来,我的 emacs 配置已经变得相当大,那里有很多对我有用的东西,但如果我有两个功能,那可能就是那些。

定义 C-x UP 和 C-x DOWN 移动当前行或向下保持光标在正确的位置:

;Down/UP the current line
(global-set-key '[(control x) (up)] 'my-up-line)
(global-set-key '[(control x) (down)] 'my-down-line)
(defun my-down-line()
  (interactive)
  (let ((col (current-column)))
    (forward-line 1)
    (transpose-lines 1)
    (forward-line -1)
    (forward-char col)
    )
  )

(defun my-up-line()
  (interactive)
  (let ((col (current-column)))
    (transpose-lines 1)
    (forward-line -2)
    (forward-char col)
    )
  )

【讨论】:

以上是关于你的 .emacs 里有啥?的主要内容,如果未能解决你的问题,请参考以下文章

文件、编辑、选项等菜单在 Emacs 23 上不起作用,有啥想法吗?

学习如何学习emacs

Emacs资料

使用 Emacs 进行社交并跟踪你的待办事项列表 | Linux 中国

“Emacs 游戏机”完全指南 | Linux 中国

你的 IDE 太重了,试试 Emacs吧!