Emacs 菜鸡教程

Emacs Buffer and Window

Emacs术语:Frame > Window > Buffer

Frame中装了多个Window,Window中包含子Window,Window显示Buffer。

Window

window是一个用来显示buffer的区域。Emacs Lisp里用一个特别的lisp对象表示。 举个例子,如下显示的window个数为3 window

Window相关函数

(count-windows &optional minibufer) 当前frame中的窗口数量

(delete-other-windows) 就是C-x 1

(split-window-vertically &optional size) (split-window-right) (split-window-below),用法:

(split-window-right (floor (* 0.68 (window-width))))

(other-window count) 估计就是有一个window-list,然后count就是从当前window从后数count个。count可以是负数,也就是向后数。用法:

(other-window 1)
(switch-to-buffer *装完x就跑*)
(other-window -1)

(window-list)获取当前窗口列表, 返回包含window对象的list。用法:

;; 获取当前所有window中的buffer名
(mapcar (lambda (w) (buffer-name (window-buffer w)))
                       (window-list))

Buffer

Buffer相关函数

(switch-to-buffer BUFFER-OR-NAME ...) 当没指定名字时,内部实现为C-x b。 把当前buffer换成另一个buffer(也就是现在的buffer会盖掉)

; 通常为切到一个window,然后switch-to-buffer
(switch-to-buffer "*banana*")

(switch-to-buffer-other-window NAME) 和上面的switch-to-buffer比较,不同点在于:在另一个window中切换buffer。 对于体验来说,多数情况会使用这个方法。

(buffer-name (window-buffer w))

  • window-buffer w返回w所指代的buffer对象,用
  • buffer-name获取名字。

例子

用王垠一篇文章里提到的例子学习下。

(defun scheme-split-window ()
  (cond
   ((= 1 (count-windows))
    (delete-other-windows)
    (split-window-vertically (floor (* 0.68 (window-height))))
    (other-window 1)
    (switch-to-buffer "*scheme*")
    (other-window 1))
   ((not (cl-find "*scheme*"
               (mapcar (lambda (w) (buffer-name (window-buffer w)))
                       (window-list))
               :test 'equal))
    (other-window 1)
    (switch-to-buffer "*scheme*")
    (other-window -1))))

详细解释

mapcar

map function sequence

See Mapping Functions in The GNU Emacs Lisp Reference Manual.

(mapcar '1+ [1 2 3])
;   => (2 3 4)
(mapcar (lambda (x) (+ x 1)) '(1 2 3))
;   => (2 3 4)
(mapcar 'car '((a b) (c d) (e f)))
;   => (a c e)

cl-find

See GNU Emacs Common Lisp Emulation. 居然还有拓展包...

cl-find item seq &key :test :test-not :key :start :end :from-end

关于后面这个可选参数的介绍可以看这里

:test后面为两个参数的函数。

(cl-find 3 '(1 2 3 4))

(cl-find "scheme" '("racket" "Java" "ruby" "scheme" "Python")
   :test 'equal)
(cl-find 20 '(1 10 100 1000)
         :test (lambda (x y) (<= x y)))
(cl-find 200 '(1 10 100 1000)           
         :test (lambda (x y) (<= x y)))