Emacs入门知识总结

  • 概述
  • Emacs相关
    • 基本概念
      • buffer
      • window
      • frame
      • ELisp
      • mode
      • 模式行mode line
      • Command
      • 快捷键
      • keymap
    • 文档查阅
    • 执行Elisp代码
    • 安装插件
    • 快捷键定制
  • Elisp相关
    • Elisp基本概念
      • Lisp列表
      • Lisp原子
      • 符号表达式
      • 引用
      • 符号名和函数定义
      • 特殊表
        • defun
        • let
        • if
        • save-excursion
    • Lisp解释器工作过程
      • 流程图
      • Lisp解释器对一个符号求值
      • message函数
      • 变量赋值
    • 函数
      • 常见的与缓冲区相关的函数
    • 小结

概述

刚接触Linux的时候一直学习的都是VIM,这个编辑器也是系统默认的,功能非常强大。我也根据网上教程把VIM打造成了IDE,但是没有实际地使用它阅读过代码。后来看到网上争论Emacs和VIM孰优孰劣,突然对Emacs也有了兴趣,最近一直在折腾Emacs。学习的感受可以用一个幽默段子来描述:听说emacs这个东西,试了一下,感觉就像记事本一样,没什么学习曲线,就是……咋也找不到退出的办法…… 网上也搜了一些相关教程以及一些配置,个人感觉如果想在配置过程中少受折磨还得了解点Elisp相关的知识,对自定义配置也能得心应手,不然配置出错了会一脸迷茫不知所措。以下几篇文章是我学习Emacs Lisp入门的时候做的备忘笔记。等对入门知识有了一些了解,可以根据自己的需求从网上搜集相关的插件进程定制。

Emacs相关

基本概念

buffer

缓冲区. Emacs并不直接对文件进行操作, 它是把文件加载进buffer, 用户直接操作buffer, 只有当用户确定把buffer中所做的修改写人文件时, Emacs才把buffer中的内容写入文件. buffer实际上就是一个内存缓冲区, 这和一般编辑器中都一样, 应该很好理解.

window

窗口. 由于Emacs很早就诞生了, 它的窗口概念和现在基于窗口的操作系统中的窗口概念不是一样的. Emacs中的窗口是用来显示buffer的一个区域. 它并不像操作系统中的窗口拥有自己的标题栏,系统菜单栏.

frame

Emacs中的frame就是操作系统中的窗口.buffer是文件的内存表示, windows则是显示buffer的区域, 一个frame中可以有多个window, Emacs则可以有多个frame.

ELisp

Emacs最基础的部分是用c写的,其他部分都是用Emacs Lisp语言写的,Emacs Lisp语言是基于lisp语言的. lisp是LISt Processor的缩写, 即链表处理语言, 所以lisp语言的操作都是基于链表的, 它的语法也是链表结构, 链表第一个元素表示函数名, 其他元素是参数, 比如通常语言中的a+b, 在lisp就是(+ a b)

mode

mode有major mode和minor mode之分, 每个缓冲区对应一个major mode, 也只有一个major mode, 但是可以有多个minor mode. Emacs对每一种文件都有一个mode.

  • 主模式(major mode)
    主模式决定了emacs对当前buffer编辑行为。一个buffer只能同时开启一个主模式,可以在mode line中查看当前buffer所使用的主模式。默认模式叫做Fundamental Mode,在该模式中没有太多的特殊设置,所有的变量一般也都被设置为默认值。 主模式一般由emacs自动选择,可以通过m-x command手动指定。c-h m查看当前主模式帮助信息和按键绑定。
    主模式可以大致分为三类:
    • 为普通文本文件而生的主模式(Test mode)
    • 为一些编程语言而生的主模式(C mode)
    • 为特殊用途而生的主模式(如Dired mode)
  • 辅模式(minor mode)
    和主模式最大的区别就是可以同时启用多个辅模式,默认情况下大多数辅模式是关闭的,只有少数辅模式是开启的。有些辅模式的作用范围是局部,只对某些buffer生效;有些辅模式的作用范围是全局,对整个emacs会话生效。
    常见的局部辅模式有:
    Abbre mode、Auto Fill mode、 Auto Save mode、Enriched mode、Flyspell mode等
    常见的全局辅模式有:
    Column Number mode、Delete Selection mode、Icomplete mode、Menu Bar mode、Tool Bar mode等
    主模式只能开启不能关闭,但是辅模式既可以开启也可以关闭:
    • m-x command开启辅模式,如果已经相应的辅模式已经开启,则会关闭相应的辅模式;
    • m-x number command,如果number <= 0则无条件关闭,如果number > 0则无条件开启相应的辅模式;
    • lisp语句中开启辅模式,如果参数为nil或者省略则无条件开启,如果有非nil参数则参考上一条;

模式行(mode line)

模式行是用来描述当前buffer状态的, 显示格式如下:
cs:ch-fr buf posline (major minor1 minor2 ...)
* cs,coding system,当前编码相关的状态;
* ch,change,表示文件修改状态;
* fr,frame name,表示frame的名字,终端程序默认显示为F1;
* buf,buffer name,表示buffer的名字,一般和关联的文件的名字相同;
* pos,position,表示当前显示的位置;
* line,表示光标所在的行;
* major,表示当前buffer使用的主模式,一个buffer只能同时关联一个主模式;
* minor,表示当前buffer使用的辅模式,一个buffer可以同时关联多个辅模式;

Command

你对Emacs所有的操作都是对Emacs的命令的调用。比如,你在text-mode里,当你按下任何字母键进行编辑的时候,实际上是调用的emacs的命令self-insert-command.

快捷键

通过组合按键序列实现快速调用Command。Emacs中Control键用C表示,Alt键用M表示, 即: C-c表示Control C, M-x表示Alt x.
除掉以Alt键开头的,比如Alt a,Emacs中的快捷键基本上都有一个前缀,Emacs中最多的快捷键前缀就是C-x,C-c,前缀表示,你不必要一起按下前缀和后缀,可以先按下前缀,Emacs会等待你按下剩余的快捷键,这样Emacs中的快捷键按起来非常的方便。

keymap

键盘映射. Emacs的快捷键是通过keymap来控制的. 有全局和局部的keymap. 每个mode都会有一个自己的局部的keymap, 局部的keymap会覆盖全局的keymap, 另外如果对应的major mode有开启的minor mode, 而且这个minor mode有keymap的话, 这个minor mode的keymap会覆盖major mode的keymap.

文档查阅

Emacs的文档非常丰富, 有Elisp自己的自文档, 还有更详细的info。 Elisp中的变量和函数都有文档,对于大多数情况都够用了.

功能 快捷键
查看变量的值和文档 C-h v (describe-variable)
查看函数的文档 C-h f (describe-function)
查看face的文档 M-x describe-face
查看某个mode的文档 C-h m (describe-mode)
查看某个快捷键对应的命令 C-h k (describe-key)
查看某个命令对应的快捷键 C-h w (where-is)
查看当前buffer所有的快捷键 C-h b (describe-bindings)
查看当前buffer中以某个快捷键序列开头的快捷键列表 <待查看的快捷键序列> C-h
查看函数的代码 find-function
查看变量的代码 find-variable
查看face的代码 find-face-definition
查看包含某个关键词的文档 M-x apropos

执行Elisp代码

  1. 在某条语句后面按C-x C-e (eval-last-sexp)可以执行那条语句
  2. M-x eval-buffer 可以执行当前buffer内的Elisp代码
  3. 选中一个region后, M-x eval-region可以执行这个region内的代码

安装插件

Emacs的插件一般都是一个以el为后缀名的文件, 把这个文件下载下来后放到一个目录, 比如~/emacs/lisps, 然后执行下面这两条语句:

( add-to-list 'load-path "~/emacs/lisps")
( require 'pluginname)

快捷键定制

全局绑定global-set-key, 绑定某个mode的快捷键用define-key. global-set-key的定义为:(global-set-key key command)
比如想把C-j绑定到”到达指定行上”(goto-line), 这样就可以了:
(global-set-key ( kbd "C-j") 'goto-line)

Elisp相关

Elisp基本概念

Lisp列表

由空格分隔的、由括号括起来的单词、数字或者其他列表。
例如(this list has (a list inside of it))是一个包含列表元素的列表,而(apple, banana, orange)由于使用了逗号来分隔不同的元素,所以不是一个有效的列表。

列表是用一系列成对的指针保存的。在这个成对的指针系列中,每一对指针的第一个指针要么指向一个原子,要么指向另外一个列表;而其第二个指针要么指向下一个指针对,要么指向符号nil表示列表结束。

Lisp原子

从语法角度不能再被分隔的元素被称为原子。在一个列表中,原子是由空格分隔,原子可以紧接着括号。
lisp中只有以下几种原子:
- 数字(比如“10”,“25”)
- 符号(比如“foo”,“+”)
- 串(双引号括起来的文本)
说明:多余的空格和换行符只不过是为了使人们易于阅读而设计的,当lisp读取表达式时会剔除所有多余的空格

符号表达式

原子和列表的书面表示都被称作符号表达式,即sexp。

引用

列表前面加单引号代表不要对这个列表做任何操作,将这种动作称为引用。如果列表前面没有引号,这个列表中的第一个符号会被当做函数,并把后续的元素当参数。

符号名和函数定义

符号名是临时用于定位函数或者一组指令的。

特殊表

用于实现特殊功能的符号。

defun

实现函数定义,语法格式如下:

(defun function-name (arguments...);参量列表,包含将要传送给这个函数的参量 "optional-documentation..." ;C-h f显示的内容 (interactive argument-passing-info); 是函数成为交互函数,用户键入`M-x`和函数名或者键入绑定的键序列也可以激活它。 body...)

interactive函数的不同选项,多个选项之间用\n隔开

选项 功能
p 告诉Emacs要传送一个前缀参量并用于函数的参量
r 告诉Emacs将位点所在区域的开始值和结束值作为函数的两个参量
B 告诉Emacs传递缓冲区的名字用于函数的参量
* 如果缓冲区是只读的就产生一个错误信号
c 传递一个字符用于函数的参量

let

定义局部变量,语法格式如下

(let ((variable value) ;变量列表,由一个符号或者一个两元素的列表组成,初始值被赋为nil (variable value) ...) body...) ;主题,由一个或者多个列表组成

if

用于条件判断,语法格式如下:

(if true-or-false-test (action-to-carry-out-if-test-is-true) (action-to-carry-out-if-test-not-true))

save-excursion

保存当前的位点、标记和当前缓冲去,以备执行函数后恢复使用,语法格式如下:

(save-execursion body...)

Lisp解释器工作过程

流程图

Created with Raphaël 2.1.0 开始 列表前面是否有单引号 什么都不做按原样显示列表 结束 列表的第一个元素是否对应一个函数定义 执行函数定义的指令 返回错误提示 yes no yes no

Lisp解释器对一个符号求值

只要这个符号前没有引号也没有括号包围他,Lisp解释器将试图像变量一样来去确定符号的值。试图对一个没有赋值的符号求值,将收到一个错误提示。
- Lisp解释器总是首先处理最内层的列表,对列表求值可能产生的结果有三种
* 返回列表本身
* 提示出错信息
* 将列表中的第一个符号当命令并执行该命令

message函数

(message "this message appears in the echo area!")
当直接使用message函数时,打印出来的文本是带引号的。这是因为由message函数返回的值将显示在回显区;而将其嵌入到一个函数中时,message打印出来的文本是作为一个附带效果出现的,以此不带引号。

变量赋值

  • 使用set函数,一般需要在参量的前面加上引号,表示我们不希望它们被求值。
  • 使用setq函数,与setq的不同之处只在于:
    1. 其第一个参量自动地带上单引号;
    2. setq函数允许在一个表达式中将几个不同的变量设置成不同的值。
  • 使用let函数

函数

常见的与缓冲区相关的函数

C-x C-e 对表达式求值,并在回显区域显示结果
C-u C-x C-e对表达式求值,并把结果显示在表达式后面

函数 功能
buffer-name 返回buffer的名字
buffer-file-name 返回buffer关联的文件的名字
current-buffer 返回当前buffer本身而不是名字
other-buffer 返回最近使用过的buffer本身而不是名字
switch-to-buffer 切换到另一个缓冲区,屏幕内容改变
set-buffer 切换计算机注意力到另一个buffer,屏幕显示内容并不改变
buffer-size 返回当前缓冲区的大小
point 返回光标在当前缓冲区的第几个字符
point-min 返回当前缓冲区中位点的最小值
point-max 返回当前缓冲区中位点的最大值

小结

  • Lisp
  • 0
  • (forwardparagraph)(+)
  • Lisp
  • Lisp

你可能感兴趣的:(linux,emacs)