Elisp

string

concat

1
2
3
4
(setq str1 "Hello, ")
(setq str2 "world!")

(setq result (concat str1 str2))

loop

for

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
(dotimes (i 5)
  (message "Iteration %d" i))
;; Iteration 0
;; Iteration 1
;; Iteration 2
;; Iteration 3
;; Iteration 4

(dolist (item '(1 2 3 4 5))
  (message "Item: %d" item))

;; Item: 1
;; Item: 2
;; Item: 3
;; Item: 4
;; Item: 5

equal

eq

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
(eq 'foo 'foo)
;  ⇒ t


(eq ?A ?A)
;; ⇒ t


(eq 3.0 3.0)
;; ⇒ nil
;; Equal floats may or may not be the same object.

(eq "asdf" "asdf")
;; ⇒ nil

(eq [(1 2) 3] [(1 2) 3])
;; ⇒ nil

(eq (point-marker) (point-marker))
;; ⇒ nil

equal

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
(equal "asdf" "asdf")
;; ⇒ t


(equal [(1 2) 3] [(1 2) 3])
;; ⇒ t


(equal (point-marker) (point-marker))
;; ⇒ t

list

add-to-list

1
2
3
4
5
(setq my-list '(1 2 3))
(add-to-list 'my-list 4)
;; Result: my-list is now (1 2 3 4)
(add-to-list 'my-list 2)
;; Result: my-list remains (1 2 3 4) since 2 is already in the list

remove from list

1
2
3
(setq my-list '(1 2 3 2 4))
(setq my-list (remove 2 my-list))
;; Result: my-list is now (1 3 4) since all occurrences of 2 are removed

switch

pcase

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
(pcase system-type
  ;; GNU/Linux or WSL
  (gnu/linux
   (message "This is GNU/Linux"))

  ;; macOS
  (darwin
   (message "This is macOS"))

  ;; Windows
  (windows-nt
   (message "This is Windows"))

  ;; BSDs
  (berkeley-unix
    (message "This is a BSD"))

  ;; Other operating system
  (_
   (message "Unknown operating system")))

regex

match

1
2
3
4
(let ((text "Hello, my email is user@example.com ????"))
  (if (string-match "\\(user@example.com\\)" text)
      (message "Found email address: %s" (match-string 1 text))
    (message "Email address not found")))

non-greedy

use ?

1
2
3
4
(let ((text "This is a test <foo>bar</foo> test"))
  (if (string-match "<.*?>" text)
      (message "Greedy match: %s" (match-string 0 text))
    (message "No match")))

defun

  • defun define function

    1
    2
    3
    4
    
    (defun function-name (args)
    (interactive "...")
    ...
    )
  • interactive code: reference

interactive

  • 通过 interactive 可以把一个函数变成一个可交互的命令
  • interactive 的命令才可以通过 M-x 执行, 类似把这个函数对用户 public

file

get parent directory

1
(file-name-directory buffer-file-name)

file name without suffix

1
(file-name-sans-extension (buffer-name))

lexical-binding

  • with ;; -*- lexical-binding: t -*- in the first line, emacs use lexical scope

Binding

  • A binding is a correspondence between a name and its value.
  • In Lisp you can create a binding using ‘let’

    • a binding made by ‘let’ lasts until the end of the ‘let’ form.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
        (let ((a 1))
          (let ((a 2))
            (let ((a 3))
              (print a))
            (print a))
          (print a))
        ;; ==> 3
        ;;     2
        ;;     1

Dynamic Binding Vs Lexical Binding

  • Lexical and dynamic binding refer to how variables are looked up by their names.
  • Two regimes for handling variable binding emerged:
  • dynamic

    • All variable names and their values live in one global table.
  • lexical

    • Each binding scope (function, let syntax, …) creates a new table of variable names and values, organised in a hierarchy called “the environment”.

mode

major mode

get major mode

1
major-mode
org-mode

get major mode keymap

1
(current-local-map)

keymap

create keymap

  • (make-keymap) full keymap with nil binding
  • (make-sparse-keymap) empty keymap
1
2
  (let ((keymap (make-keymap))
        (sparse-keymap (make-sparse-keymap))))

suppress-keymap

  • changes the contents of the full keymap keymap by remapping self-insert-command to the command undefined

    1
    2
    3
    4
    
    (let ((map (make-sparse-keymap)))
      (suppress-keymap map)
      (keymap-set map "q" 'quit-window)
      map)

unbind key

1
(define-key keymap key-sequence nil)

priority

  1. overriding-terminal-local-map
  2. overriding-local-map
  3. text property 'keymap
  4. emulation-mode-map-alists
  5. minor-mode-overriding-map-alist
  6. minor-mode-map-alist (Minor Mode)
  7. text property 'local-map
  8. (current-local-map) (Major Mode)
  9. (current-global-map) (Global Map)

minor-mode

check if active

1
(bound-and-true-p which-key-mode)

list

range

1
(number-sequence ?a ?z)

in list

1
(member 1 (number-sequence 2 3))

loop

dotimes

1
2
(dotimes (it 10)
  (message "%s" it))

dolist

1
2
(dolist (elem (number-sequence 0 10))
  (print elem))

hotkeys

KeymapFunction
C-M-fforward-sexp (coresponding bracket)
C-M-bbackward-sexp (coresponding bracket)

org-mode

KeymapFunction
C-c -add - ahead of current line

buffer & window

get

  • 可以通过 (get-buffer BUFFER_NAME) / (get-buffer-window 直接拿到 buffer / window
  • 可以不存在的话是 nil

switch

  • window 的话可以用 ace-windowaw-switch-to-window WINDOW_NAME

function

functionkeyfunctionality
file-exists-pnilfile exisit
file-name-directorynilget the directory of a file
buffer-file-namenilcurrent buffer/file name
backward-up-listC-M-uupper level element (method -> class)

GPG

keeping your secrets encrypted on your file system is an easy way of keeping your secrets secret

  • Gpg(GNU Privacy Guard) is natively supported in emacs called EasyPG
  • 只用一个gpg key管理所有加密文件和链接
  • 可以不用每次输密码获取 root 权限

authinfo

  • auth-sources 变量指定 authinfo 文件
  • 格式 machine <HOST> login <ACCOUNT> port <PORT> password <PASSWORD>

    • example machine localhost login root port sudo password rootpasswd123
  • shell access gpg2 -q --for-your-eyes-only --no-tty -d ~/.authinfo.gpg | sed -n 's,^machine gmail.com .*password \([^ ]*\).*,\1,p'

Creating a key

  • gpg --gen-key

font

describe char

  • display current char info
1
C-u C-x =

align

  • 第一次知道 C-u M-x 调用的命令跟直接 M-x 调用的还是不一样的
  • C-u M-x align-regexp 使用的是更高级的 align-regexp

    • regexp: match the place you are interested in aligning; to do it, one of its parenthesis groups will be extended with spaces, or shortened by deleting characters
    • parenthesis group: choose which one
    • spacing: if the group is shorter than this, spaces will be added to it; if it's longer, characters will be deleted from it, starting at the end (unless it's longer for the purposes of alignment, of course)
    • repeat: well, this is obvious, I think
    • justify: non-blank characters inside the group won't be deleted, and necessary spaces will be added/deleted from the left. On your second case, try: regexp \([0-9]+\), group -1.
    • column (instead of spacing): align to that fixed column (of course, it doesn't work well with “repeat”).

debug

debug function

  • M-x debug-on-entry 设置入口
  • 直接运行函数
  • cancel-debug-on-entry

keymap

ShortcutFunction
dstep through
ccontinue(step out)

on error

1
(setq debug-on-error t)

bugs

poll freeze

1
in poll () at /usr/lib/libc.so.6

search by value

  • apropos-value

package

unload

1
(unload-feature 'miao)