Emacs高手修炼手册(v1.0,2022)

·  阅读 1714

© 第253页图灵笔记,2020 -

原始视频地址:www.bilibili.com/video/BV13g…

Emacs初体验

教程简介

最初视频版本的理念(其中带*的也是文字版的理念):

  • *带领认识Emacs这款传说中的编辑器
  • 每节课五分钟左右,没有废话,干货
  • *每节课一个技巧或知识点,轻松学习
  • *对笔者也是个学习的过程,共同进步
  • *新手视角,向老鸟学习,向高手迈进

Emacs简介

  • 讲解的版本是GNU Emacs,非其他的衍生版本
  • GNU Emacs于1984年,Richard Stallman发起并维护
  • GNU顶级项目
  • 竞争对手VIM,VSCode等
  • 跨平台,内核解释器C写成,通过ELisp语言进行扩展

Emacs安装

Windows

建议使用ScoopChocolatey等包管理器安装。

scoop bucket add extras
scoop install emacs
复制代码
choco install emacs
复制代码

或者也可以直接在Emacs官网进行下载解压使用。

www.gnu.org/software/em…

或者下载测试版(版本比较新,其实功能也挺稳定):alpha.gnu.org/gnu/emacs/p…

Linux

建议使用分发版自带的包管理器进行安装,如:

# Ubuntu / Debian
sudo apt install emacs

# Fedora
sudo dnf install emacs

# Arch
sudo pacman -S emacs
复制代码

或者也可以通过官网下载源代码编译安装。

www.gnu.org/software/em…

macOS

建议使用Homebrew包管理器进行安装。

brew install --cask emacs
复制代码

或者也可以在官网通过下载后拖动到Applications目录中即可使用。

www.gnu.org/software/em…

Emacs版本

截止到本文编写的时候:

  • 最新版本:28.1 (2022年4月4日)
  • 开发中不稳定版本:29.0.50

最初的教程以27.2为演示版本,同时兼容28/29版本(所以在使用本教程的时候,完全可以直接使用最新的28.1)。安装前可查看包管理器安装的是否是对应版本。

注:随着时间的推移,笔者从2022年初开始将版本普遍提高到了28.1+。

# Windows
scoop info emacs

# Linux
apt info emacs
dnf info emacs

# macOS
brew info emacs
复制代码

启动Emacs,然后查看版本。 M-x emacs-version

或者在命令行中查看版本。 emacs --version

Emacs初识

emacs-interface.png 绿色:菜单栏

红色:工具栏

黄色:编辑区域

蓝色:状态栏

紫色:交互区域(输出信息,M-x操作等)

基本操作速记

别太多,先学习一点点光标的移动。

  • C,代表CTRL
  • M,代表Meta键,往往是ALT(部分键盘是ESC)

光标移动,形成肌肉记忆之前可通过速记法来记忆:

  • C-n,下一行(速记:Nextline)
  • C-p,前一行(速记:Previous line)
  • C-f,向前移动一个字符(速记:Forward)
  • C-b,向后退一个字符(速记:Backforward)
  • C-k,从光标位置到末尾删掉(速记:Kill)
  • C-a,回到行首(速记:a是字母表的开始)
  • C-e,去往行尾(速记:End of line)
  • M - <,回到编辑区域最开始位置(速记:<)
  • M - >,去往编辑区域最后的位置(速记:>)
  • C-v,向下翻一屏
  • M-v,向上翻一屏

自带文档

C-h t ;速记 Help Tutorial

查看快捷键的含义:

C-h k ;速记 Help Keybind

查看函数的定义以及快捷键绑定:

C-h f ;速记 Help Function

对外观做点改变

图形化配置 M-x customize

  • 菜单栏 menu-bar-mode
  • 工具栏 tool-bar-mode
  • 滚动条 scroll-bar-mode

体验下用配置文件配置

创建文件 ~/.emacs 并写入一下内容:

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
复制代码

重启Emacs看看实际的效果。

Emacs配置初体验

认识配置文件

Emacs配置文件的位置,会按照一下顺序去查找:

  1. ~/.emacs
  2. ~/.emacs.d
  3. ~/.config/emacs/init.el

第一个是一个单一文件配置;第二个更符合工程化;第三个仅适用于≥27的版本。

教程会从第一个入手,逐渐变为第二种的模式。

为什么不用大牛配置

  • 大牛配置有哪些
  1. Spacemacs
  2. Centaur Emacs
  3. Doom Emacs
  4. Steve Purcell
  5. redguardtoo(陈斌,一年成为emacs高手作者)
  6. ……
  • 我的建议
  1. 当然建议用大牛配置,大牛的配置是最优,而且经历了时间和项目考验的,就算你将来不日常使用,学习价值也非常大。
  2. 为什么不用:你一定是经历了很长的使用后才该有这样的想法,想学习,想配置,了解了Emacs后想打造一些属于自己的东西的时候。而且强烈建议你以大牛的配置为基础进行增减。

我的配置 github.com/cabins/emac…

第一行emacs配置代码

已经体验了关掉菜单栏、工具栏、滚动条等。现在尝试关掉启动界面:

(setq inhibit-startup-screen t)
复制代码

重启Emacs看看?

软件源

  • 什么是软件源,你安装第三方插件的来源(或许叫插件源更合理?)。
  • 为什么要用软件源,不同的软件源有不同的软件包,所以为了找到更多的需要的包。
  • 为什么要改成国内的软件源,有些软件源可能无法访问,有些软件源在国内连接的时候可能速度不理想。
(setq package-archives
      '(("melpa" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
        ("gnu" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
        ("org" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))
复制代码

安装第一个emacs扩展

安装扩展前,需要先刷新软件源的索引。

;;个别时候会出现签名检验失败
(setq package-check-signature nil) 

;; 初始化软件包管理器
(require 'package)
(unless (bound-and-true-p package--initialized)
    (package-initialize))

;; 刷新软件源索引
(unless package-archive-contents
    (package-refresh-contents))

;; 第一个扩展插件:use-package,用来批量统一管理软件包
(unless (package-installed-p 'use-package)
    (package-refresh-contents)
    (package-install 'use-package))
复制代码

使用use-package管理扩展

  • 什么是use-package
  • 怎么用

最简洁的格式

(use-package restart-emacs)
复制代码

常用的格式

(use-package SOME-PACKAGE-NAME
             :ensure t ; 是否一定要确保已安装
             :defer t ; 是否要延迟加载,很多时候可以加速Emacs的启动速度
             :init (setq ...) ; 初始化配置
             :config (...) ; 初始化后的基本配置参数
             :bind (...) ; 快捷按键绑定
             :hook (...) ; hook的绑定
             )
复制代码

建议添加的配置:

;; `use-package-always-ensure' 避免每个软件包都需要加 ":ensure t" 
;; `use-package-always-defer' 避免每个软件包都需要加 ":defer t" 
(setq use-package-always-ensure t
      use-package-always-defer t
      use-package-enable-imenu-support t
      use-package-expand-minimally t)
复制代码

更换个主题

最初教程演示采用的主题是 gruvbox-theme

(use-package gruvbox-theme
             :init (load-theme 'gruvbox-dark-soft t))
复制代码

最初教程顺便配置一个好看一点的Mode Line

(use-package smart-mode-line
  :init
  (setq sml/no-confirm-load-theme t
        sml/theme 'respectful)
  (sml/setup))
复制代码

但后来我还是倾向于使用内置的modus主题(28+),审美这东西,还是看你自己的爱好。

工程化管理配置(1)功能拆分

到此为止,在~/.emacs 中配置了很多的内容,开始显得很乱:

  • 初始化Elpa
  • 安装扩展
  • 添加主题

是时候分类处理了。就像一个开发项目那样。尝试着把配置按照功能不同拆分成不同的文件。如:

  • lisp/init-elpa.el用于存放Elpa和Package初始化
  • lisp/init-package.el用于存放安装的扩展
  • lisp/init-ui.el用于存放界面主题相关配置
  • 如何在初始化文件中把它们联系在一起(调用)?

工程化管理配置(2)文件加载与调用

先设置加载的目标目录到 load-path 中。

(add-to-list 'load-path (expand-file-name (concat user-emacs-directory "lisp")))
复制代码

各个文件通过 provide 暴露对外调用的名称。如:

(provide 'init-ui)
复制代码

然后在 init.el 文件中通过 require 调用:

(require 'init-ui)
复制代码

关于自定义的配置

建议写入一个单独的文件,对外开源的时候,该文件不被提交到Git中。如,custom.el

(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
复制代码

这样就会把通过图形界面做的一些配置,写入到这里了。

操作系统判断

后面的部分配置会因操作系统不同而产生不同配置代码,所以有必要对操作系统进行判断。

(defconst *is-mac* (eq system-type 'darwin))
(defconst *is-linux* (eq system-type 'gnu/linux))
(defconst *is-windows* (or (eq system-type 'ms-dos) (eq system-type 'windows-nt)))
复制代码

其中Windows的判断还可以放的宽一点:

(defconst *is-windows* (memq system-type '(ms-dos windows-nt cygwin)))
复制代码

macOS平台将Command键映射为Meta

对于Mac键盘来说,Command键距离x的位置与Windows键盘更相近,所以习惯上可以修改这个按键映射为Meta,如果你不需要这个设置,可以不用管。

(when *is-mac* (setq mac-command-modifier 'meta)
               (setq mac-option-modifier 'none))
复制代码

通过修改字体解决Windows上Emacs的卡顿

方案是修改字体,最初的版本中我会建议你这样修改字体:

font-v1.png

现在的方案中我会推荐你这样修改字体:

(defvar cn-fonts-list '("黑体" "STHeiti" "微软雅黑" "文泉译微米黑")
  "定义使用的中文字体候选列表.")

(defvar en-fonts-list '("Cascadia Code" "Courier New" "Monaco" "Ubuntu Mono")
  "定义使用的英文字体候选列表.")

(defvar emoji-fonts-list '("Apple Color Emoji" "Segoe UI Emoji" "Noto Color Emoji" "Symbola" "Symbol")
  "定义使用Emoji字体候选列表.")

;;;###autoload
(defun tenon--font-setup ()
  "Font setup."

  (interactive)
  (let* ((cf (tenon--available-font cn-fonts-list))
	     (ef (tenon--available-font en-fonts-list))
         (em (tenon--available-font emoji-fonts-list)))
    (when ef
      (dolist (face '(default fixed-pitch fixed-pitch-serif variable-pitch))
	    (set-face-attribute face nil :family ef)))
    (when em
      (dolist (charset `(unicode unicode-bmp ,(if (> emacs-major-version 27) 'emoji 'symbol)))
        (set-fontset-font t charset em nil 'prepend)))
    (when cf
      (dolist (charset '(kana han cjk-misc bopomofo))
	    (set-fontset-font t charset cf))
      (setq face-font-rescale-alist
	        (mapcar (lambda (item) (cons item 1.2)) `(,cf ,em))))))
复制代码

你可以在你的custom.el中设置cn-fonts-list来自定义字体,而不需要改写配置代码,配置中的字体仅做兜底使用。

建议增加的一点启动配置

设置系统的编码,避免各处的乱码。我最初的教程中是建议你这样写:

(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq default-buffer-file-coding-system 'utf-8)
复制代码

其实,最新的配置里面我会推荐你这样写。这两行代码足够了。

(prefer-coding-system 'utf-8)
(unless *is-windows*
    (set-selection-coding-system 'utf-8))
复制代码

设置垃圾回收阈值,加速启动速度。

(setq gc-cons-threshold most-positive-fixnum)
复制代码

测试启动耗时

通过 benchmark-init 包进行启动耗时的测量。

(use-package benchmark-init
             :init (benchmark-init/activate)
             :hook (after-init . benchmark-init/deactivate))
复制代码

启动完成后可以执行:

M-x benchmark-init/show-durations-tree 或者 M-x benchmark-init/show-durations-tabulated来查看启动的耗时细节。

中断命令输入

C-g在输入任何命令的时候,可随时通过该快捷键放弃命令的继续键入。

用y/n来代替yes/no

(defalias 'yes-or-no-p 'y-or-n-p)
复制代码

为了项目管理的统一化,可以用如下的use-package写法(其实完全没有必要,就一行代码,不要过度包装):

(use-package emacs
             :config (defalias 'yes-or-no-p 'y-or-n-p))
复制代码

显示行号

行号的类型

从Emacs 26开始,自带了行号显示功能,可以通过设置display-line-numbers-type变量的值,来改变行号的类型。可取值有:

  • relative,相对行号
  • visual,可视化行号
  • t

行号配置(不一定非要用use-package,只保留config后面两行即可)

(add-hook 'prog-mode-hook 'display-line-numbers-mode)
复制代码

Emacs文本编辑

文本编辑之选中/复制/剪切/粘贴

选中

  • 方法一,使用鼠标拖动选中
  • 方法二,标记开始位置,然后通过移动光标到结束位置

复制 M-w

剪切 C-w

粘贴 C-y ;; 速记 Yank

文本编辑之删除

场景一:从光标位置到行尾的删除

C-k

场景二:删除当前行

我最初的视频教程中认为默认没有这样的快捷键,可以安装一个扩展来实现,crux,该扩展提供了包含该场景在内的一系列优化快捷命令。

(use-package crux 
             :bind ("C-c k" . crux-smart-kill-line))
复制代码

但其实是有这样的快捷按键的,C-S-<Backspace> (kill-whole-line)。

场景三:一次性删除到前/后面的第一个非空字符(删除连续的空白)

通过hungry-delete扩展实现,该功能。

(use-package hungry-delete
  :bind (("C-c DEL" . hungry-delete-backward)
         ("C-c d" . hungry-delete-forward)))
复制代码

文本编辑之行/区域上下移动

在VSCode或Jetbrains家族的编辑器中,上下移动行/块是非常容易的,但原生的Emacs没有提供这样的功能。可通过插件drag-stuff来辅助实现。

(use-package drag-stuff
             :bind (("<M-up>" . drag-stuff-up)
                    ("<M-down>" . drag-stuff-down)))
复制代码

或者使用move-dup插件:

(use-package move-dup
             :hook (after-init . global-move-dup-mode))
复制代码

文本编辑之原生搜索/替换

Emacs原生提供了强大的搜索和替换功能。

  • 当前位置到文档结尾的搜索 C-s

  • 当前位置到文档开始的搜索 C-r

  • 替换 M-%

替换时按下y确认替换,n跳过本处的替换,!全部替换。

文本编辑之强化搜索

著名的ivy-counsel-swiper三剑客,就是为了强化搜索(同时优化了一系列Minibuffer的操作)。

swiper.png

文本编辑之自动补全

Emacs界补全两大垄断插件,Auto-Complete和Company(Complete Anything)。时代和特性原因,Company呈现压倒性优势。

我最早的代码建议你这样写:

company-v1.png

最新的代码我会建议你这样写:

(use-package company
  :hook (after-init . global-company-mode)
  :config (setq company-minimum-prefix-length 1
                company-show-quick-access t))
复制代码

文本编辑之语法检查

最初的教程中我建议你使用Flycheck,而不是Flymake,受其他的大牛以及历史的影响。但如今我还是建议你使用内置的Flymake,因为它已经非常好用了。

(use-package flymake
  :hook (prog-mode . flymake-mode)
  :config
  (global-set-key (kbd "M-n") #'flymake-goto-next-error)
  (global-set-key (kbd "M-p") #'flymake-goto-prev-error))
复制代码

文本编辑之行排序

M-x sort-lines

文本编辑之顺序更换

光标前后两个字符互换 C-t

光标前后两个单词互换 M-t

文本编辑之字数统计

整个Buffer统计

M-= 或者 M-x count-words-region

选中区域统计

先选中需要统计的区域,然后执行 M-x count-words

Emacs常用插件

crux优化Emacs常用操作

  • 优化版的回到行首
  • 快速打开Emacs配置文件
  • 快速连接两行等
(use-package crux
  :bind (("C-a" . 'crux-move-beginning-of-line)
         ("C-c ^" . 'crux-top-join-line)
         ("C-x ," . 'crux-find-user-init-file)
         ("C-c k" . 'crux-smart-kill-line)))
复制代码

其实,快速回到行首这个功能我现在更推荐你使用C-a以及M-m。这样的快捷按键既是内置,而且明确。

如何记忆越来越长的快捷键

如果你不喜欢用鼠标在菜单栏点击的化,你其实可以用Which-Key这款插件来辅助你“记忆”。

(use-package which-key
  :defer nil
  :config (which-key-mode))
复制代码

当你按下一个按键时,它会提示你下一个按键的含义。并等待你去按下。

Emacs窗口管理

窗口管理之Buffer管理

Buffer切换

C-x b

杀死当前Buffer

C-x k

批量管理Buffer

C-x C-b ;; 进入Buffer列表

  • d ;; 标记删除
  • u ;; 取消当前行标记
  • U ;; 取消全部标记
  • x ;; 执行操作
  • ? ;; 查看按键帮助

窗口管理之MiniBuffer交互优化

显示在左下角的MiniBuffer移动视线范围大,移动到中央位置,更合适一些。

posframe.png

窗口管理之分屏

开启横向分屏 C-x 3

开启纵向分屏 C-x 2

只保留当前分屏 C-x 1

关闭当前分屏 C-x 0

窗口管理之分屏宽度调整

增加高度 C-x ^

增加/减少宽度 C-x { C-x }

窗口管理之快速切换分屏

默认可通过以下快捷键进行窗口的循环跳转: C-x o

当分屏很多的时候效率非常低。通过ace-window可快速进行窗口间的跳转。类似的插件较多,但该款为最佳方案。

(use-package ace-window 
             :bind (("M-o" . 'ace-window)))
复制代码

ace.png

窗口管理之Tab标签页管理

C-x t 后面继续输入

  • 2 ;; 新建Tab
  • 1 ;; 关闭其它Tab
  • 0 ;; 关闭当前Tab
  • b ;; 在新Tab中打开Buffer

编程语言

eglot实现IDE

github.com/joaotavora/…

在Emacs编程的世界里,快速实现IDE,有两种方案,分别是这一节的eglot以及下一节的lsp-mode。关于两者的对比可能会形成非常大量的文字。此处我挑选几个典型的来说明一下:

  • eglot比较轻量级,lsp-mode相对比较重
  • eglot无第三方依赖,lsp-mode有非常多的第三方依赖
  • eglot实现的功能够用,但不丰富;lsp-mode功能非常丰富

所以两者我都会进行讲解,使用哪个的选择权留给读者。

如果你只是想体验一下,其实可以通过 package-install 的方式安装eglot,然后进入到某一个编程语言的文件中,通过 M-x eglot来启动。而如果你像我一样喜欢它,则下面的配置供你参考。

(use-package eglot
  :hook ((c-mode
          c++-mode
          go-mode
          java-mode
          js-mode
          python-mode
          rust-mode
          web-mode) . eglot-ensure)
  :bind (("C-c e f" . #'eglot-format)
         ("C-c e a" . #'eglot-code-actions)
         ("C-c e i" . #'eglot-code-action-organize-imports)
         ("C-c e q" . #'eglot-code-action-quickfix))
  :config
  ;; (setq eglot-ignored-server-capabilities '(:documentHighlightProvider))
  (add-to-list 'eglot-server-programs '(web-mode "vls"))
  (defun eglot-actions-before-save()
    (add-hook 'before-save-hook
              (lambda ()
                (call-interactively #'eglot-format)
                (call-interactively #'eglot-code-action-organize-imports))))
  (add-hook 'eglot--managed-mode-hook #'eglot-actions-before-save))
复制代码

上面是我的eglot的配置,添加了我日常使用的一些编程语言、快捷按键以及一些自动格式化与自动保存/管理导入的包的配置。

注意:你一定要先安装对应的language-server,并配置好环境变量。例如对c/cpp来说就需要是ccls或者clangd,对于rust来说,就需要是rust-analyzer,对于go来说就是gopls。

lsp-mode实现IDE

lsp-mode的配置相对来说也差不多。但是它有非常丰富的特性可配置。下图是一个比较简化的配置。

(use-package lsp-mode
  :commands (lsp lsp-deferred)
  :init
  (defun lsp-save-actions ()
    "LSP actions before save."
    (add-hook 'before-save-hook #'lsp-organize-imports t t)
	(add-hook 'before-save-hook #'lsp-format-buffer t t))
  :hook ((lsp-mode . #'lsp-enable-which-key-integration)
         (lsp-mode . #'lsp-save-actions)
         ((c-mode
           c++-mode
           go-mode
           java-mode
           js-mode
           python-mode
           rust-mode
           web-mode) . lsp-deferred))
  :config
  (setq lsp-auto-guess-root t
	    lsp-headerline-breadcrumb-enable nil
	    lsp-keymap-prefix "C-c l"
	    lsp-log-io nil)
  (define-key lsp-mode-map (kbd "C-c l") lsp-command-map))
复制代码

更多的配置可参考官网:github.com/emacs-lsp/l…

同样的,你也需要提前安装好language-server并配置好环境变量。

由于lsp-mode的丰富性,你还可以安装lsp-ui来提升图形操作的体验:

(use-package lsp-ui
    :after lsp-mode
    :init
    (setq lsp-ui-doc-include-signature t
	      lsp-ui-doc-position 'at-point
          lsp-ui-sideline-ignore-duplicate t)
    (add-hook 'lsp-mode-hook 'lsp-ui-mode)
    (add-hook 'lsp-ui-mode-hook 'lsp-modeline-code-actions-mode)
    :config
    (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
    (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references))
复制代码

对于调试的场景,你还可以安装dap-mode以及对应的调试器来使用:

(use-package dap-mode
    :init
    (add-hook 'lsp-mode-hook 'dap-mode)
    (add-hook 'dap-mode-hook 'dap-ui-mode)
    (add-hook 'dap-mode-hook 'dap-tooltip-mode)
    ;;   (add-hook 'python-mode-hook (lambda() (require 'dap-python)))
    ;;   (add-hook 'go-mode-hook (lambda() (require 'dap-go)))
    ;;   (add-hook 'java-mode-hook (lambda() (require 'dap-java)))
    )
复制代码

看上去lsp-mode是不是比eglot丰富更多?但你也要注意,在一些机器上,尤其是Windows机器,lsp-mode会出现卡顿等性能问题,而eglot基本不会。

Java特殊配置

使用了上面的LSP客户端后,一般的环境应该很容易配置或者无需配置,例如gopls,pylsp等,但也有一些编程语言的服务器需要一些额外的配置。例如c/c++的情况下,例如Java的情况。

Java的语言服务器是来自Eclipse的jdtls,最新版本的jdtls提供了一个可执行的文件,对于非Windows环境,只要把这个bin目录放到环境变量中即可。但他们提供的可执行脚本是基于Python写成的,这在Windows上无法变成可执行文件。

所以你需要额外生成一个可执行文件,或者自己写一个jdtls.bat的适合Windows的可执行文件。

@echo off

set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

cd /d %~dp0

java^
    -Declipse.application=org.eclipse.jdt.ls.core.id1^
    -Dosgi.bundles.defaultStartLevel=4^
    -Declipse.product=org.eclipse.jdt.ls.core.product^
    -Dosgi.checkConfiguration=true^
    -Dosgi.sharedConfiguration.area=../config_win^
    -Dosgi.sharedConfiguration.area.readOnly=true^
    -Dosgi.configuration.cascaded=true^
    -noverify^
    -Xms1G^
    --add-modules=ALL-SYSTEM^
    --add-opens java.base/java.util=ALL-UNNAMED^
    --add-opens java.base/java.lang=ALL-UNNAMED^
    -jar ../plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar^
    %CMD_LINE_ARGS%

复制代码

或者使用pyinstaller --onefile来生成(源代码如下)。

import os
import sys

if getattr(sys, "frozen", False):
    dir_path = os.path.dirname(os.path.dirname(os.path.abspath(sys.executable)))
else:
    dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

cmd = (
    "java"
    " -Declipse.application=org.eclipse.jdt.ls.core.id1"
    " -Dosgi.bundles.defaultStartLevel=4"
    " -Declipse.product=org.eclipse.jdt.ls.core.product"
    " -Dosgi.checkConfiguration=true"
    f" -Dosgi.sharedConfiguration.area={dir_path}/config_win"
    " -Dosgi.sharedConfiguration.area.readOnly=true"
    " -Dosgi.configuration.cascaded=true"
    " -noverify"
    " -Xms1G"
    " --add-modules=ALL-SYSTEM"
    " --add-opens java.base/java.util=ALL-UNNAMED"
    " --add-opens java.base/java.lang=ALL-UNNAMED"
    f" -jar {dir_path}/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar"
    f" {' '.join(sys.argv[1:])}"
)

os.system(cmd)
复制代码

针对Windows

很久以来,很多人对在Windows下使用Emacs的体验,给的评价并不高。包括我。经过了一段时间的折腾之后,我想说的是,没有我们说的那么差。它可能无法与Linux/macOS下的体验进行媲美,但绝对可以日常使用,甚至有可能成为你的主力编辑器。

一般来说,Windows下需要解决几个方面的问题就可以了:

  • 字体,这是卡顿的罪魁祸首
  • 如果你喜欢mactype这样的插件,一定记得把emacs排除掉,非常明显的解决卡顿
  • 部分插件替代,例如用VC替代magit,例如用内置的project代替projectile等
  • Windows也可以使用daemon

结束语

之所以会重写,而且以后还会继续不断的升级(这就是为什么这篇已经加上了版本号的原因),更多的还是希望自己对Emacs的使用和理解,能够保持更新,同时希望把这些更新带给更多的初学者,以及有需要的人。交更多的志同道合的朋友。

不出意外,我后面应该会**一年出一个大版本**,虽然可能更新的内容不多。而且基本上,后面会融合更多的《Emacs轻奢之路》的内容(如果你感兴趣,可以阅读那一本小册)。我觉得那是使用Emacs的必经之路。如果你喜欢,可以保持对我以及这两个系列的关注。同时我也欢迎有更多的内容补充进来,欢迎给我提意见/建议。

发布版本历史:

  • v0.1,视频版本,2020年3月起陆续发布
  • v1.0,当前版本,2022年4月
分类:
开发工具
标签:
分类:
开发工具
标签:
收藏成功!
已添加到「」, 点击更改