Emacs Lisp 簡介

洋蔥工作室

Emacs Lisp 基本介紹

  • 一種程式語言
  • Lisp 來自於 LISt Processing,使用括號來代表 List
  • Emacs Lisp 是 Common Lisp 的一種方言,跟 Common Lisp 有些不同
  • Emacs 使用 Emacs Lisp 來擴充編輯器的功能

YouTube 影片

如何在 Emacs 環境下使用

buffer-file-name 

(+ 1 2 3)

(+ (* 2 3)
   (/ 4 2))

(message "this is help")
(format "Hello World!~")
(print "Print to mini buffer")
(insert " ; insert this  text")

有關 List

(list 'my (+ 1 1) "son")

(quote (1 2 3))
'(1 2 4)

(car '(1 2 4))
(cdr '(1 4 6))
(cons 1 '(2 5))
'(1 . (2 5))
(cons '(2 5) 1)
'(" this is " .  "a text")
(cadr '(superman batman aquamen flash joker))
(nth 2 '(superman batman aquament flash))

(member 'b '(a b c))
(member '(a) '((a) (z)))
(memq '(a) '((a) (z)))

(defvar superman (list :name "Superman" :secret-id "Clark Kent"))
(format "%s" superman)

ELisp 的變數

(defvar *nums* '(2 4 6))
(push 1 *nums*)

(set 'some-list '(a b c))
some-list

(cons 'z some-list)
(cons some-list 'z)

(eq some-list '(a b c))
(eql some-list '(a b c))
(equal some-list '(a b c))

(setq my-list '(3 4 5))
my-list

(setf (cdr my-list) 10)
(setq another-list (cons my-list 7))
(let ((a 1) (b 3))
  (format "now a is %d and b is %d" a b))
a                                          ;; a is not within global lexical scope

(let* ((a 1) (b (+ a 2)))
  (format "now a is %d and b is %d" a b))

函數

(defun say-hello ()
  (message "Hello World"))

(say-hello)
(functionp 'say-hello)
;; optional args
(defun print-list (&optional x y z &rest ns)
  (format "%s"  (list x y z ns)))

(print-list)
(func-arity 'print-list)
(print-list 1 2)
(print-list 1 2 3 4 5 6)

(cl-flet ((double-it (num)
                  (* num 2)))
  (double-it 10))

;; multiple return value
(defun squares (num)
  (values (expt num 2) (expt num 3)))

(multiple-value-bind (a b) (squares 2)
  (format "%d  and %d" a b))

將函數當作參數

(apply #'+  '(1 2 3))
(funcall #'+ '(1 2 3))
(funcall #'+ 1 2 3)

(defun times-3 (x) (* x 3))
(defun times-4 (x) (* x 4))
(defun multiples (multi-func max-num)
  (dotimes (x max-num)
    (print (format "%d: %d" x (funcall multi-func x))))        ; funcall to invoke pass-in function
  )

(multiples #'times-3 10)
(multiples #'times-4 10)

匿名及高階函數

;;
;; anonymous function
;;
(lambda (x) (* x x x))
((lambda (x) (* x x x)) 5)
(fset 'cube (lambda(x) (* x x x)))     ; set symbol to function object
(cube 4)

;;
;; high order functions
;;
(mapcar 'upcase '("foo" "bar" "baz"))
(mapcar (lambda (x) (* x x)) '(2 3 5))

巨集 (macro)

(setf *age* 16)
(if (>= *age* 16)
    (progn
      (print "You are over 16")
      (print "You are ok to drive")
      (terpri)
      ))

(defmacro ifit (condition &rest body)
  `(if, condition (progn ,@body) (print "Can not drive")))

(ifit (>= *age* 16)
      (print "Your are over 16")
      (print "Time to Drive")
      (terpri))

程式流程控制

;; if
(defun odd-or-even (x)
  (if (= 0 (% x 2))
      "even"
    "odd"))

(odd-or-even 3)
(odd-or-even 4)

;; cond
(defun pick-word (n)
  (cond
   ((= n 1) "gold")
   ((= n 2) "silver")
   ((= n 3) "bronz")
   (t "winner")))

(pick-word 3)
(pick-word 33)

程式流程控制

;; for-loop
(loop for x from 1 to 10
      do (print x))

(dotimes (y 12)
  (print y))

;; recursive
(defun factorial (n)
  (if (< n 1)
  1
  (* n (factorial (- n 1)))))

(factorial 3)
(factorial 10)

程式範例 quicksort

(require 'cl)
(defun quicksort (list)
  "quick sort using elisp"
  (when list
    (let ( (p (car list))  (xs (cdr list) )  )
      (let ((lesser (remove-if-not (lambda (x) (< x p)) xs))
            (greater (remove-if-not (lambda (x) (>= x p)) xs)))
        (append (quicksort lesser) (list p) (quicksort greater)))
      )
    )
  )

(quicksort '(3 6 2 9 7 5))

跟 Emacs 相關

(global-set-key (kbd "M-#") 'sort-lines)

major-mode

(add-hook 'c-mode-common-hook
          (lambda ()
            (local-set-key (kbd "<f5>") 'recompile)
            ))

幫助

(kbd "C-h ?")
;; C-h k
(describe-key (kbd "C-h k"))
;; C-h a
(apropos-command "region" )
;; C-h f
(describe-function 'quicksort)
;; C-h v
(describe-variable 'path-separator)
;; C-h m
(describe-mode)
;; C-h C-h
(help-for-help)
;; build in elisp programming language introduction 
(info "(eintro) Top")
;; build in elisp
(info "(elisp) Top")