为 Swift 开发配置 Emacs

Emacs 是一款高度可定制的文本编辑器,其起源于 Digital Equipment Corporation TECO 编辑器的宏包。多年来,出现过许多类 Emacs 编辑器和衍生产品,但本指南将专注于 GNU Emacs

本指南将引导您完成为 Swift 开发设置全新安装的 Emacs;它不假定任何特定的操作系统,但在相关情况下可能会提供特定于系统的提示,以帮助您入门。本指南也不旨在教您使用 Emacs;如果您想学习 Emacs,请尝试此资源:Emacs 导览

本指南假设您为了学习目的已经安装了 Swift;如果尚未安装,请在继续之前按照 Swift 网站上适用于您平台的安装说明进行操作。

安装 Emacs

GNU Emacs 网站上提供了通用的安装说明。下面给出了一些常用平台的具体说明。

macOS

Emacs for Mac OS X 网站提供了标准 Mac 磁盘映像中的通用二进制文件。从该网站下载映像,打开它并将其拖到您的 Applications 文件夹是为 macOS 开发安装原生 Emacs 的最简单方法。

Microsoft Windows

您可以从附近的 GNU 镜像GNU 主 FTP 服务器下载适用于 Windows 的 GNU Emacs。最简单的方法可能是运行 emacs-<version>-installer.exe 可执行文件,这将安装 Emacs 并为您设置一些快捷方式。

基于 Debian 的 Linux(包括 Ubuntu)

在提示符下,输入

$ sudo apt-get install emacs

或者,如果您在服务器系统或容器上执行此操作,且不打算使用 GUI,则输入

$ sudo apt-get install emacs-nox

基于 RedHat 的 Linux (RHEL、Centos、Fedora)

在提示符下,输入

$ sudo dnf install emacs

(在较旧的版本中,您可能需要使用 yum 而不是 dnf,但如果可用,后者是更新、更好的选择。)

配置 Emacs

Emacs 老手可能还记得手动下载和安装 Lisp 包,但现在最好使用包管理器。我们还将配置 MELPA,这是一个流行的 Emacs 包仓库。为此,请打开 Emacs,输入 C-x C-f ~/.emacs 并按 Enter 键。然后将以下内容添加到您的 .emacs 文件中

;;; Add MELPA as a package source
(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

我们还将设置 use-package,因为如果您希望能够将 ~/.emacs 复制到新机器并使其正常工作,这将简化包安装。为此,请添加

;;; Bootstrap `use-package'
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))

稍后我们将需要能够找到 sourcekit-lsp;这取决于 Swift 的安装位置,因此让我们添加一个 Lisp 函数来执行此操作

;;; Locate sourcekit-lsp
(defun find-sourcekit-lsp ()
  (or (executable-find "sourcekit-lsp")
      (and (eq system-type 'darwin)
           (string-trim (shell-command-to-string "xcrun -f sourcekit-lsp")))
      "/usr/local/swift/usr/bin/sourcekit-lsp"))

接下来,我们将安装一些有用的包

;;; Packages we want installed for Swift development

;; .editorconfig file support
(use-package editorconfig
    :ensure t
    :config (editorconfig-mode +1))

;; Swift editing support
(use-package swift-mode
    :ensure t
    :mode "\\.swift\\'"
    :interpreter "swift")

;; Rainbow delimiters makes nested delimiters easier to understand
(use-package rainbow-delimiters
    :ensure t
    :hook ((prog-mode . rainbow-delimiters-mode)))

;; Company mode (completion)
(use-package company
    :ensure t
    :config
    (global-company-mode +1))

;; Used to interface with swift-lsp.
(use-package lsp-mode
    :ensure t
    :commands lsp
    :hook ((swift-mode . lsp)))

;; lsp-mode's UI modules
(use-package lsp-ui
    :ensure t)

;; sourcekit-lsp support
(use-package lsp-sourcekit
    :ensure t
    :after lsp-mode
    :custom
    (lsp-sourcekit-executable (find-sourcekit-lsp) "Find sourcekit-lsp"))

我们还将添加几个包,使外观更漂亮、更现代化;如果您愿意,您也可以安装主题或更改字体——自定义 Emacs 的可能性几乎是无限的

;; Powerline
(use-package powerline
  :ensure t
  :config
  (powerline-default-theme))

;; Spaceline
(use-package spaceline
  :ensure t
  :after powerline
  :config
  (spaceline-emacs-theme))

最后,让我们关闭启动画面,因为我们不希望每次启动 Emacs 时都看到它,并且我们还将禁用工具栏

;;; Don't display the start screen
(setq inhibit-startup-screen t)

;;; Disable the toolbar
(tool-bar-mode -1)

输入 C-x C-s 以保存您的新 .emacs 文件,然后重启 Emacs。

结论

我们已经成功设置了 Emacs 以编辑 Swift 代码,它具有语法高亮显示、与 SourceKit-LSP 的集成,并支持现代最佳实践,例如使用 .editorconfig 文件,以允许项目轻松设置自己的制表符宽度和格式首选项。

文件

这是一个完整的 .emacs 文件,其中包含完整的配置

;;; Add MELPA as a package source
(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

;;; Bootstrap `use-package'
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))

;;; Locate sourcekit-lsp
(defun find-sourcekit-lsp ()
  (or (executable-find "sourcekit-lsp")
      (and (eq system-type 'darwin)
           (string-trim (shell-command-to-string "xcrun -f sourcekit-lsp")))
      "/usr/local/swift/usr/bin/sourcekit-lsp"))

;;; Packages we want installed for Swift development

;; .editorconfig file support
(use-package editorconfig
    :ensure t
    :config (editorconfig-mode +1))

;; Swift editing support
(use-package swift-mode
    :ensure t
    :mode "\\.swift\\'"
    :interpreter "swift")

;; Rainbow delimiters makes nested delimiters easier to understand
(use-package rainbow-delimiters
    :ensure t
    :hook ((prog-mode . rainbow-delimiters-mode)))

;; Company mode (completion)
(use-package company
    :ensure t
    :config
    (global-company-mode +1))

;; Used to interface with swift-lsp.
(use-package lsp-mode
    :ensure t
    :commands lsp
    :hook ((swift-mode . lsp)))

;; lsp-mode's UI modules
(use-package lsp-ui
    :ensure t)

;; sourcekit-lsp support
(use-package lsp-sourcekit
    :ensure t
    :after lsp-mode
    :custom
    (lsp-sourcekit-executable (find-sourcekit-lsp) "Find sourcekit-lsp"))

;; Powerline
(use-package powerline
  :ensure t
  :config
  (powerline-default-theme))

;; Spaceline
(use-package spaceline
  :ensure t
  :after powerline
  :config
  (spaceline-emacs-theme))

;;; Don't display the start screen
(setq inhibit-startup-screen t)

;;; Disable the toolbar
(tool-bar-mode -1)