Sec.Ret.Team

导航

Emacs 相关资料翻译

Archived entries from file c:/Users/NormalWork/Desktop/orgArchive/Blogs/EmacsRelatedTranslated.org

37 Document Viewing

Origin Article

DocView mode 是浏览DVI,PostScript(PS),PDF,OpenDocument和Microsoft Office文档的主模式,
提供了例如切断,缩放和文档内查找等功能,通过gs(GhostScript)或者mudraw/pdfdraw和其他工具1将文档转换为图片,然后将图片显示出来。

当你访问一个可通过Emacs查看的文档时,Emacs自动使用DocView模式2,有一个例外是,当你访问一个PostScript文件,Emacs会切换到PS 模式,但是
emacs也会启用DocView minormode,可通过C-c C-c(doc-view-toggle-display)来切换两种模式。

当访问一个可以被Emacs预览,但是一些必要的工具未安装的时候,你会被询问是否已plain text来显示文档内容,这样
DocView minormode就启用了。

也可以通过M-x doc-view-mode显式地启用DocView mode。

结束一个DocView Buffer,k(doc-view-kill-proc-and-buffer), q(quit-window)

EmacsrelatedTranslation

Spacemacs 配置层(Configuration Layer)(layers作为专有名词可不做翻译)

Original Article

简介

这篇文章希望可以给想要自己写配置层的人一些指导,无论是自己只用还是还是上传。根据layers如何工作
和Spacemacs如何加载packages来解释一些比较容易混淆的问题.

Nomenclature(术语)

层和包,如何理解?
包(Packages):
一系列Elisp 文件的集合,提供一些功能。包可能会有包仓库例如ELPA,MELPA或者第三方如github
提供,也可以直接本地编写存储。

层(Layer):
可启用或禁用的一套配置集单位,一个layer通常是将一个或多个package集成在一起,加上glue configuration
code(粘合代码),使每个package能互相协同。

在写一个配置层之前,可以先考虑你要达到什么目的。是否已经有单个package实现了这个功能,你想将这个
功能整合进Spacemacs,如果是那么你可以写一个layer,如果你想实现一个新功能,你可以考虑险些一个package
然后再写一个layer去使用它。

Emacs加载过程

要理解如果更好的实现一个配置层,首先要理解Emacs是如何加载代码的。

  1. Emacs lisp文件

    Emacs lisp 文件包含可悲执行的代码,当执行后,定义函数,宏,模式在这个Emacs Session里面就可用了。
    这个过程叫做加载一个elisp文件.

    一个主要的问题是如何确保所有正确的文件以正确的顺序被加载,另一个问题是确保不会有太多的文件被立即加载。
    这会让emacs的启动会非常慢,所以我们希望每个文件在需要的时候再加载,而不是里一次加载完。

    那么Emacs里面怎么做的,Spacemacs里面怎么做的呢?

    1. 加载文件

      最简单的方式是调用 load-file.

      (load-file "~/elisp/foo.el")
      

      这是最基础的方式,目录必须固定,并且Emacs不会去寻找byte-compiled .elc 文件,它只会加载
      你告诉他的文件。

  2. Features

    一种更好的方式是使用 features,feature 通常和el文件同名的符号,比如你有一个叫做my-feature.el
    的文件。

    ;;yourself code
    
    (provide 'my-feature)
    

    为了让Emacs加载这个文件,调用require:

    (require 'my-feature)
    

    require会检查my-feature是否已经加载,如果没有,emacs会查找my-feature.el 和 my-feature.elc
    当调用了 provide 之后,这个feature会被加入到一个已加载的features列表里,接下来调用require就不会做任何事情了。

    如果没有文件被找到,就会产生一个错误。

    在my-feature里也可以调用其它的require,这是一种保证依赖项加载的常用方式。

    加载路径:

    通过require加载文件的话,Emacs会去load path查找文件。你可以通过SPC h d v load-path查看load-path变量。

    要增加load path,只需要将路径push到这个列表就行了。e.g.

    (push "/some/path" load-path)
    
  3. 自动加载

    require相角于load-file是一种比较优雅的方式,他解决了文件按照正确的顺序加载的问题,
    在某种程度上也解决了elisp file的路径问题,但是在emacs启动的时候requere太多依然
    会让emacs启动很慢。

    Emacs通过auto-loading 来解决这个问题,当一个函数注册为auto-loading , 会提供一个空定义,
    当这个函数被调用的时候,包含这个函数的文件才会被加载,然后空函数被实际的函数代替,然后正常调用。

    终端用户只会看到一点微小的延迟,当auto-loading 函数被第一次加载的时候.

    要将一个函数注册为auto-loadable,调用 autoload:

    (autoload 'some-function "some-file")
    

    这会让Emacs不论什么时候调用some-function ,会先加载some-file.el。

    执行过上述代码后,你可以通过SPC h d f some-function来查看该函数,Emacs会告诉你这是一个
    auto-loaded函数,直到文件被加载起来,否则对这个函数其他东西一无所知。

    调用autoload可以选择性的包含更多信息,如果doc-string,是否可以interactively called,等等。
    这可以给终端用户提供更多信息而不用加载它。

    打开elpa文件夹,进入helm,找到helm-autoloads.el.它为helm里面所有文件设置了auto-load,
    但这个文件不是手写的,而是通过Helm代码的魔法注释自动生成的,如下:

    ;;;###autoload
    (defun my-function()
    ;; Source code...
    )
    

    Magic comment ;;;###autoload 告诉Emacs接下来的函数应该auto-loaded.这会自动生成autoload.

    可定义的都是可自动加载的,例如函数,宏,major mode,minor mode,groups,classes等等。

    Spacemacs重度使用auto-loading,几乎所有的东西都是需要的时候才加载。

  4. Eval after load

    通常我们需要在包加载过后配置他们,比如设置一些变量或者调用一些函数,对于require来说比较繁琐,
    因为它是立即加载的,但是对于autoloading来说就比较方便,因为配置代码也会延迟加载。(这部分没翻译好)
    This is trivial with require, because it loads immediately, but it can be tricky with autoloading, because the configuration code must also be deferred.

    Emacs使用 with-eval-after-load 来达到这个目的,使用方式如下:

    (with-eval-after-load  'helm
    ;;Code
    )
    

    这样当helm加载后,定义的代码回立即执行。

    with-eval-after-load是一个宏,不是一个函数,所以参数不需要引号。

  5. Use-package

    对于想要集合一个高效率配置的终端用户来说,有一个非常有用的包叫做 use-package,它提供了一个也叫做
    use-package的宏,使加载包的整个过程非常简洁高效。

    对效率有追求的layer作者推荐看看use-package的文档, 下面是一些例子:

    (use-package helm)
    

    这个等同于 (require 'helm)

     (use-package helm
    :defer t)
    

    这会延迟加载helm.

    (use-package helm
    :defer t
    :init
    ;; Code to execute before Helm is loaded
    :config
    ;;Code to execute after Helm is loaded.
    )
    

    一目了然的功能。

    (use-package helm
    :commands (helm-find-files helm-M-x))
    
    (use-package ruby-mode
    :mode "\\.rb\\'")
    

    这两个例子还需要理解一下

Layer解析

Layer就是存在于Spacemacs查找路径中的一个文件夹,包含了以下文件(按加载顺序列出):

Layers.el
声明另外的layer

packages.el
packages list和配置

funcs.el
所有在这个Layer使用的函数需要在这里声明。

config.el
layer配置

keybindings.el
通用的键绑定

另外,对于每一个本地包,应该在/local//这个文件夹里存有其源码。
在初始化这个包之前,Spacemacs会将这个文件夹加入到loadpath.

layers.el

这是第一个被加载的文件,其他layer可以在这里声明。
比如layer A 依赖layer B 的某些功能,那么在layer A的layers.el中,我们加入以下语句:

(configuration-layer/declare-layer 'B)

那么B layer就会被加载,就像将B加入了=dotspacemacs-configuration-layers= 变量一样。

packages.el

包含了这个layer所使用的packages 列表和对package的配置。

这个文件在layers.el后面加载。

必须定义一个叫做-packages的变量,包含了所有这个layer需要的package列表。

(defconst mylayer-packages
'(
;;Get the package from MELPA,ELPA,etc.
some-package
(some-package :location elpa)

;;A local package
(some-package :location local)

;;A package recipe
(some-package :location (recipe :fetcher github
                                :repo "some/repo"))

;;An excluded package 
(some-package :excluded t)
)

对于每一个包含的package,你或许需要定义以下函数,Spacemacs会按顺序调用来初始化packages.

  1. <layer>/pre-init-<package>
  2. <layer>/init-<package>
  3. <layer>/post-init-<package>

这些函数负责加载和配置packages,Spacemacs只会下载packages并放入loadpath.

Note:
如果没有layer为一个包定义初始化函数(init),那么这个包不会被安装。

funcs.el

包含这个Layer使用的所有函数

最好确保包会加载,再定义函数,如下:

   (when (configuration-layer/package-usedp 'my-package)
(defun spacemacs/my-package-enable () ...)
(defun spacemacs/my-package-disable () ...))

config.el

keybindings.el

包含通用键绑定。
通用表示不依赖于其他任何包,

Spacemacs加载过程

spacemacs加载过程总结如下:

  1. Spacemacs遍历所有启用的Layers,并运行他们的文件。首先 config.el 所引入的
    改变生效,然后是加载 func.elpackages.el , packages.el 不会带来
    任何改变,因为他只是定义了函数和变量。

  2. Spacemacs检查哪些包需要被下载安装

    • 被一个启用的Layer包含
    • 没有被其他启用的Layer排除
    • 没有被用户自己排除并且
    • 必须有至少一个/init- 函数定义

    如果一个包是用户的 dotspacemacs-additional-packages , 也会被安装

  3. 所有需要被安装的包以alphabetical的顺序安装。
    package.el built-in Emacs library is in charge of implicit dependencies. Installed packages not following the rules of 2. are removed as well as their dependencies if possible. (This last behavior is optional but default.)

  4. pre-init , init , post-init 按顺序执行。

    我们说如果一个Layer为一个包定义了 init 函数,那么这个Layer拥有这个包,
    如果只定义了 pre-initpost-init ,这不能说拥有这个包。

案例分析 auto-completion

spacemacs提供了一个 auto-completion Layer,它提供了多种模式下的
自动完成。通过包 company 来完成此功能,这个Layer拥有company包,所以定义了
函数 auto-completion/init-company

Footnotes

1 For PostScript files, GhostScript is a hard requirement. For DVI files, dvipdf or dvipdfm is needed. For OpenDocument and Microsoft Office documents, the unoconv tool is needed.

2 The needed external tools for the document type must be available, and Emacs must be running in a graphical frame and have PNG image support. If any of these requirements is not fulfilled, Emacs falls back to another major mode.

posted on 2016-12-20 20:49  Sec.Ret.Team  阅读(506)  评论(0编辑  收藏  举报