# Emacs lisp
###### tags: `1121`
---
[TOC]
## lisp
- Generalized Variables
- (++ (car L))
- Common lisp style object oriented
- cl-defmethod
## Common
- alt-x(M-x)
- 直接輸入function名
- 呼叫此function
- 輸入describe-key
- 可搜尋任何指令
- 輸入where-is
- 可搜尋任何指令的位置
- describe-key -> Crtl-h + k
- where-is -> Ctrl-h + w
- describe-variable
- 搜尋variable
- describe-function
- 可搜尋任何function
- forward-char
- 鼠標往後移N格
- (forward-char &optional N) 直接執行此行,N為任意整數
- elisp-enable-lexical-binding
- 自動輸入;;; -*- lexical-binding: t; -*-
- search
- [grep](https://www.gnu.org/software/emacs/manual/html_node/emacs/Grep-Searching.html)
- You can find content in a file
- [locate](https://www.gnu.org/software/emacs/manual/html_node/elisp/Locating-Files.html)
- You can find file name
- [man](https://www.gnu.org/software/emacs/manual/html_node/emacs/Man-Page.html)
- You can find some command manual
- eval-last-sexp
- Ctrl-x Ctrl-e
- 輸入運算式並執行
- Ctrl-g
- 離開目前的指令(卡住時可以按)
- Ctrl-h
- F1
- 列出所有的key sequence
- Ctrl-x
- Ctrl-s
- save buffer
- F1 或 Ctrl-h
- 列出所有的key sequence
- Ctrl-u
- universal-argument
- shift-alt-:(ㄤ鍵)
- eval: 輸入任何運算式
- enter之後計算此運算式
- bind-keys
- ph/
- 虛擬空間
- * (in ELISP mode)
- 代表在命令列上一個暫存的 value or command
- byte-compile filename
- [byte compilation](https://www.gnu.org/software/emacs/manual/html_node/elisp/Byte-Compilation.html#Byte-Compilation)
- auto align lines
- [keyboard macro](https://www.gnu.org/software/emacs/manual/html_node/emacs/Keyboard-Macros.html)
## Function
```lisp=
(defun a(x)
(message "%s" (1+ x))
)
```
```lisp=
(set 'a 7) --- 7 (#o7, #x7, ?\C-g) -> a 的位置的值為7
(set 'x 'a) --- a -> x的位置的值為a的位置的值=7
(set x 13) --- 13 (#o15, #xd, ?\C-m) -> x的值為13
(setq x 13) <-> (set 'x 13) ---
```
```lisp=
(foo x) --- foo 參數
(defun foo ()) --- foo function
(defmacro foo ()) -> 執行此行會覆蓋前一個foo的function,但不會覆蓋foo參數
```
- 在命令列 search 'INS'
```lisp=
(defun foo ()
(interactive)
(let (case-fold-search)
(search-forward "INS")
))
// 執行後 alt-x + foo 呼叫此函式
```
- elt
```lisp=
/*
elt SEQUENCE N // sequence(list, array, vector, char-table, bool-table)
*/
(elt '(a list like this) 3) //--> this
(elt [a vector is not a cat] 5) //--> cat
(elt "我不會的" 2) //--> 26371
(insert 26371) //--> 在結尾輸入一個"會"字
with xxx = [ 'aaa' 'bbb' ... ] // vector
`
```
- 括號
```lisp=
error:
(let((x 7)
(y 8)
)
((+ x y))
)
correct:
(let((x 7)
(y 8)
)
(+ x y))
```
- True or False
- 'nil' --> FALSE
- else just output anything --> TRUE
- string-match-p(REGEXP STARTING &optional START)
- 第一個字串一定要有,第二個不一定要
- 檢測第一個是不是string,第二個包含在第一個字串的第幾個位置
- 'p' --> '?'
```lisp=
(string-match-p "[abc]" "b") //--> 0 (只要有output就是TRUE)
```
- string-match
```lisp=
```
- listp
- 是否為list
```lisp=
(listp '(2 3 3)) // --> t(TRUE)
(listp [2 9]) //--> nil(FALSE)
```
- atom
- 是否為atom(非list就是atom)
```lisp=
(atom 23) //--> t
(mapcar
'atom
'(23 "frd" '(a list) [a vec])) //--> (t t nil t)
```
- check-parens
- macro
```lisp=
(set x 'y')
(defun foo (var)
(insert (symbol-name var))
)
(foo x) // --> insert 'y'
(defmacro moo (var)
(insert (symbol-name var))
)
(moo x) // --> insert 'x'
(defmacro moo (var)
(insert (symbol-name var))
`(insert (symbol-name var))
)
(moo x) // --> insert 'xy'
```
- funcall
- funcall FUNCTION &rest ARGUMANTS
- ex.
```lisp=
(defun ph/add5 (x)
"add 5 to x"
(+ 5 x)
)
(ph/add5 7) #-> 12
(setq x 'ph/add5)
(funcall x 7) #->12
(funcall (list 'lambda '(x) '(+ x 5)) 7) #->12
(list 'lambda '(x) '(+ x 5)) 7) #->不會算出你想要的答案
## 可以看看
- ELISP
- EMACS
- CL
- LOOP
- SEQUENCE ARRAY VECTORS
## Lisp
### Cons cell
- |car|cdr|
- 
- cons
```lisp=
(con 1 (cons 2 nil)) # -> (1 2)
(list 1 2) # -> (1 2)
(list 1 2 (list 3 4 5)) #(1 2 (3 4 5))
```
- car & cdr
```lisp=
(car '(a b c d)) #--> a
(cdr '(a b c d)) #--> (b c d)
```
- cadr & cddr
- cadr
- (car(cdr ...))
- cddr
- (cdr(cdr ...))
- ```
(cadr '(a b c d)) # -> b
(cddr '(a b c d)) # -> (c d)
### not & null
- not
- (not '()) => t
- (not nil) => t
- (not t) => nil
- (not 1) => nil
- null
- (null '()) => t
- (null nil) => t
- (null t) => nil
- (null 1) => nil
### length
- output its length
- ex.
```lisp=
(length '(1 2 3)) #-> 3
(length "hello my baby") #->13
```
### if else、when、unless、cond
- if CONDICTION then else ...
- when CONDICTION then ...
- unless CONDCTION then
- cond
```lisp=
(defun foo (x)
(cond
((< x 5) 'small)
((< x 9) 'medium)
(t 'big)
))
(foo 4) -> small
(foo 6) -> medium
(foo 10)-> big
```
### loop
- excersize
- my-length
- use defun、if、null、cdr to output length
-
```lisp=
(defun my-length (x)
(if (null (cdr x))
1
(+ (my-length (cdr x)) 1)
)); try eval-defun with prefix argument.
(my-length '(1 2 3)) #-> 3
```
- while
-
```lisp=
(defun my-length/while (L)
(let ((len 0))
(while L
(setq len (1+len)
L (cdr L)
))
len
))
```
- dolist
```lisp=
(defun ny-length/shile (L)
(let ((len 0))
(dolist (_ L len)
(setq len (1+len))
(++ len)
)))
```
- random
- ex.0
```
(defun ph/random-uniform01 ()
(/ (random 2147483647) 2147483647)
```
- ex.1
```
(defun ph/probdistrib-with-params/geom (p)
(let ((i 1))
(while (< p (ph/random-uniform01))
(cl-incf i)
)
i
))
```
- ex.2
```
(defun ph/probdistrib-with-params/geom-p=.4 ()
(let ((i 1))
(while (< .4 (ph/random-uniform01))
(cl-incf i)
)
i
))
#cl-incf -> ++
```
- ex.3
```
(cl-loop
repeat 10
do
collect (ph/probdistrib-with-params/geom-p=.4)
)
```
- ex.4
```
(defun ph/probdistrib-with-params/geom-p=.4 ()
(cl-assert (<= 0 p 1) t)
(lambda ()
(let ((i 1))
(while (< ,p (ph/random-uniform01))
(cl-incf i)
)
i
)))
```
```
(defvar ph/quick-fox-words
(cl-map 'vector
'identity #給甚麼印甚麼(不作改變)
(split-string
"The quick brown foxjumps over th lazy dog"
" ")
))
```
- test 1
- use insert and mapcar
- write a functoin to insert a list of string to 目前浮標的位置
- ex. '("cat" "dog") --> inserts "catdog"
```
(defun insert-a-string (seq)
(if (null (car seq))
nil
(insert (car seq))
(insert-a-string (cdr seq))
)
)
```
```
(mapcar (insert '("cat" "dog")))
```
- test2
- use mapconcat
- insert space in between
- ex. '("cat" "dog") --> inserts "cat dog"
```
(defun insert-a-string (seq)
(if (null (car seq))
nil
(insert (car seq))
(insert " ")
(insert-a-string (cdr seq))
)
)
```
```
(mapconcat (insert '("cat" "dog")))
```
- html
- ex
```
(defun ph/html-close-tag-string (open-tag-string)
"Return closing tag for html tag OPEN-TAG-STRING,
for example: <b> --> </b>,
<pre class=\"b\"> --> </pre>"
(save-match-data
(if (string-match "<\\([^ ]+\\)" open-tag-string)
(match-string 1)
(error "bad open-tag-string: s%" open-tag-string)
)))
(string-match "a" "zaa")
```
- regular expression
- '\'
- ex1.
```
(insert "\[") -> [
(insert "\\[") -> \[
(insert "\\\[") -> \[
(insert "\\\\[") -> \\[
```
- ex2.
```
(string= "\\t" "\\\t") --> nil
(insert "\\t") -> \t
(insert "\\\t") -> \ (\t)
```
- ex3.
```
\a (a string in the file)
(re-search-forward "\\a") # 找字串"\a" -> fail
eval: re-search-forward "\\a" -> fail
M-x re-search-forward \a -> success and 屬標移到\a後面
```
- ex4.
```
M-x re-search-forward fred C-q C-j -->找換行符
"\n" --> 使用C-q C-j找換行符
```
- ex5.
```
\b --> 文字末端的control character(^H)
e\\b --> e\b
```
- '[]'
- ex1.
```
(re-search-forward "\[a-z]") --> 找a-z中任一個字母
```
- ex2.
```
"\[" --> [
```
- regexs in rx notation
- [pcre2el: convert between PCRE, Emacs and rx regexp syntax](https://github.com/joddie/pcre2el)
- query-replace-regex
- ex1.
```
M-x query-replace-regex </?[A-Z]+>
query-replace-regexp-with \,(downcase \&)
y -> yes
n -> no
```
- ex2. 呼叫ex1.的指令
```
(defun query-replace-regexp/fold-not ()
"Call query-replace-regex with case folding suppressed" -> 說明
(interactive) -> 指令
(let (case-fold-search)
(call-interactively #'query-replace-regexp)
))
```
- string-match
- ex1.
```
(string-match "cat" "adogcat") -> 4
(match-string 0 "adogcat") -> "cat"
```
- looking-back-p
- ex1.
```
(defun looking-back-p (regexp)
"Same as `looking-back' except this function does not change the match data."
(let ((inhibit-changing-match-data t))
(looking-back regexp)
))
(progn
(string-match "cat" "acat")
(match-string 0 "acat"))
(looking-back-p "(mat")
```
- view-last-regexp
- command-history
- compiling elisp
- compile
- native compile
- byte compile
- teacher'code to compiling
-
```lisp=
(defun ph/this-file-load (compile?)
"Load the file the current buffer is visiting.
Runs `check-parens' first, then `load-file'.
when COMPILE? given, also run `byte-compile-file'."
(interactive "P")
(ph/check-parens); See below, but you can simply use check-parens
(minibuffer-message "Check parens okay")
(if (not (buffer-file-name))
(error "Cannot load. Current buffer is not visiting a file")
(and ;; and here used to control flow
(buffer-modified-p)
(y-or-n-p "Save buffer before loading?")
(save-buffer)
)
(load-file (buffer-file-name))
(when compile?
(byte-compile-file (buffer-file-name))
(display-buffer "*Compile-Log*")
)))
```
### [lists](https://www.gnu.org/software/emacs/manual/html_node/elisp/Lists.html)
- [alist](https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html)
- ex.
```lisp=
[(D.dog) 78
(C.cat)]
```
- [plist](https://www.gnu.org/software/emacs/manual/html_node/elisp/Property-Lists.html)
- hash-table
- obarray
### homeworks
- hw1
- 楊輝三角形
- ```
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1```
- 參考函數
- defvar
- defun
- interactive
- or
- if
- ctrl-assert(debug)
- ctrl-loop
- erase-buffer(buffer=類似string東西)
- get-buffer-create
- pop-to-buffer
- concat
- format
- insert
- with-temp-buffer
-
```lisp=
(with-temp-buffer
(insert "a string")
(upcase-region (point-min)(point-max)) #轉大寫(buffer的範圍)
(buffer-string) #整個uffer轉為string type
)
#-> A STRING
```
- s-center
```lisp=
(insert "\n")
(s-center 5 "a")
```
- memoize
- 將算好的數存起來,再呼叫就不用再算一遍以節省時間
- up-using
- let
- make-hash-table
- gethash
- puthash
## someone's Project idea
- idea
- useful key binding(?)
- 編譯emacs(keyboard.c?)
- someone do before
- [pollard rho algorithm](https://zhuanlan.zhihu.com/p/267884783)
- 加速compile
## slime
- install in [here](https://slime.common-lisp.dev/) and [here](https://github.com/slime/slime)
- ECL
- ex.
```lisp=
```
## [onlisp](https://sep.turbifycdn.com/ty/cdn/paulgraham/onlisp.pdf?t=1688221954&)
# Final Project
## 提案
- 提案
- 解謎逃脫遊戲
- 逃脫遊戲
- 單人遊戲但可轉換視角
- 5~10關卡
- 透過文字呈現
- 相關遊戲
- 文字獄
- 紙嫁衣
- 投影片
- 
- 
- 
- 
- 
- 
- 
- 
- 
## 構想
- 構想
- 故事大綱
- 本故事情節皆為虛構,如有雷同純屬巧合。
- ==前世==(主視角)
- 孤兒院
- 1.你記事開始就在孤兒院生活,與小夥伴們相處愉快,院長等阿姨叔叔都對你很好,雖然沒有父母陪伴,但在孤兒院的日子很快樂。
- 報紙
- 電話
- 被領養
- 2.某天你被一個富豪領養了,富豪與太太雖然對你不上心,但資源及食衣住行都不錯,你對富豪心懷感激。
- 競爭關係
- 3.為了不辜負富豪對你的期望,以及與新的兩位兄長明裡暗裡競爭,在新的環境下你努力成長為一個優秀的金融管理人才,在社交圈上名聲極好。
- 財務報表
- 公司黑料
- 4.出社會後,你接手管理富豪的其中一個子公司,經營的有聲有色,這時突然有媒體爆料關於富豪及總公司的黑料,政府單位以貪汙為由起訴富豪及總公司,這時有人自稱為死者家屬,宣稱富豪謀財害命並提告富豪,警方介入調查,你以及你的子公司也連帶被調查。
- 律師電話
- 孤兒院電話
- 富豪電話
- 死刑審判
- 5.經過幾個月的調查,因證據確鑿富豪被判了死刑,富豪為了洗脫罪名,偽造證據將一切矛頭都指向你,並情緒勒索你應該要回報當初收養你的恩情,就這樣你承認了所有罪狀,不久後你迎來了死刑。
- 審判結果
- ==死後==
- 幽靈階段
- 6.槍聲響起之後,很快的你感到一陣暈眩,你發現你變成一縷幽魂,顯然你有餘願未了才留在人間,為了明白你的牽掛,你來到富豪身邊尋找線索,發現他竟然又去孤兒院領養一個孩子(你甚至頭七都還沒過),你感到一絲絲不對勁,而跑去觀察富豪所作所為。
- 領養手續
- 人影
- 尋找證據
- 7.這時你才發現原來富豪當初領養你就是預謀好的,富豪做了一堆壞事(之前媒體報的黑料只是其中之一),等東窗事發時找個替死鬼,替死鬼還會心懷感激接受。知道真相後,你猜想你的餘願是讓富豪接受屬於他的刑罰,而不再有下一個你,你跑去接近富豪新領養的孩子,但作為幽魂的你無法與人類直接溝通。
- 孩子
- 通靈師
- 接觸新領養的孩子
- 8.你透過機緣巧合找到通靈師幫忙牽線,==你從通靈師那裏得到了可以直接與人類溝通的法寶,你透過精心設計成功將法寶送到孩子手上(這裡可以想一下怎麼送到孩子手上)==,與孩子的第一次見面嚇到了孩子,耐心勸導之後,孩子終於願意聽你說話。
- 房間
- 法寶
- 9.孩子耐心聽完你說的話後,不大相信富豪是壞人,開始防備你,這時你將之前搜到的證據一一拿出來(由於幽靈體質無法拿到實體證據,只能透過你所見傳給孩子),孩子看到富豪曾做過這麼多壞事有一絲絲破防,但由於目前孩子還未曾受到富豪迫害,無法全心全意相信,孩子選擇半信半疑,因此你提出一個方法,向孩子證明富豪的領養是有企圖的。
- 富豪的秘密基地
- 10.你來到富豪的辦公室,富豪正在與下屬談話,你隱約聽到了"逃跑"、"懲罰"等詞彙,你為了聽清他們的話更靠近一點(你是幽魂具備隱身技能),並使用法寶實時直播給孩子看,你聽到富豪破口大罵是如何訓練這屆新人的,並說過幾天會親自去"永樂山莊"查看,到時候再出問題一定不可饒恕。
- 11.談話結束後,你回去找孩子說過幾天再聯絡,孩子對富豪所說的"永樂山莊"充滿好奇,因此欣然接受你的提議,你臨走前囑咐孩子不要把看到你的事說出去,並且把法寶隨身攜帶不要給任何人,孩子點點頭說"明白了!",你就放心離去了。
- 富豪行蹤
- 12.你連日觀察富豪一舉一動,終於看到富豪隻身驅車前往郊外,開始與孩子連麥直播,在經過九曲十八拐的山路之後,富豪將車停在山路邊,往山林裡徒步走去,不久後來到一處被大石頭封住的山洞,富豪在山洞前走了幾步==有規律的步伐==。
- 步伐
- 13."轟隆隆隆!",一道石門開啟,你跟上富豪進入山洞,山洞裡別有洞天,你看到四個大字"永樂山莊"掛在高聳的石牆上,石牆下又是一道防盜門,你看到富豪==輸入一串數字(9字鍵打永樂山莊)==。
- 匾額
- 面板
- 鍵盤
- 新人訓練現場
- 14.大門開啟,後面是一道紅毯,下屬們畢恭畢敬地迎接富豪,站在首位的總管為富豪領路前往新人訓練地。你來到像是地牢的地方,這裡陰暗潮濕甚至有股食物腐敗味,你看到一少年滿身是血,全身抽搐被綁在鐵椅上在接受電擊,==嘴裡念念有詞不知道在念叨甚麼(這裡可以作為其中一個謎題)==,富豪見怪不怪的看了少年一眼,詢問其他新人在哪裡,準備抽查新人訓練的成果如何,並前往下一個房間。
- 新人們
- 15.你趁著富豪在抽查新人時,悄悄靠近電擊椅上的少年,你聽到他一直喃喃自語重複"南無阿彌陀佛...南無阿彌陀佛...",正當你以為他是受到刺激才這麼求神拜佛時,突然聽到一句細碎的聲音"救救我...",這時你驚訝的問了句"你能看到我?",你看到他默默的點了點頭。
- 少年
- 拯救少年
- 16.你研究起電擊椅,發現椅子後有個面板,能控制電擊程度,但需要輸入密碼解鎖,你詢問少年知不知道密碼,他說他記得有聽到==小星星的的旋律(1155665),但不確定哪個數字對應哪個音,你試了試發現每按一個鍵,全部的鍵的音高就增加你按的數,而一開始數字1對應do的音,全部有1-7的鍵==。
- 頭緒
- 電擊椅
- 17.你成功打開面板將電擊關閉,並將少年鬆綁,正當你打算帶少年從正門闖出去,少年卻說他知道暗道,他會被抓到是為了要趁機將竊聽器粘到總管身上,竊取更多機密,他在這裡已經收集到差不多的資料,可以準備直接離開,只是需要先找出這個房間的暗門。
- 地牢
- 竊聽器
- 資料
- 18.==你觀察四周,發現天花板有張紙條,紙條上寫了一串小字"!£!$!&\(",而天花板各個角落分別有不同的數字按鈕。==
- 天花板
- 紙條
- 成功逃脫
- 19.暗門成功打開了,你再度將通信法寶拿出交給少年,希望若有後續進展能再連絡,少年欣然接受了,並動身離開。
- 你確認少年安全離開後,再度跟上富豪的腳步,盼望能發現甚麼致命性證據。
- 20.==這時富豪來到壁畫旁邊,這是一幅黑白壁畫,描繪著隕石撞地球的場景,璀璨的繁星、驚恐的人類、燃燒的大樹、湖泊的倒影以及遠方的山,你看到富豪依序點擊石塊後,暗門開啟了。==
- 壁畫
- 石塊
- 21.在一片漆黑過後,來到另一個房間,金碧輝煌的大廳掩飾了非法博弈場所的醜陋,原來富豪的大部分資產皆來自非法博弈及不人道的人口買賣。
- 提告富豪
- 22.拿到致命性證據,加上少年的助力,你與少年開始著手提告富豪,檢察官介入調查,七天後開庭。
- 23.本想打富豪措手不及,沒想到孩子出現在法庭上,承認自己在孤兒院時就覬覦富豪的財產,想盡一切辦法成為富豪的養子,並聯合少年偽造罪證以及富豪遺囑,在富豪身敗名裂並服死刑後,再順理成章繼承富豪的所有財產。
- 24.你疑惑之中,本想上前盤問孩子這麼做的理由,這時眼見孩子拿出法寶,並用力將其摔碎,你的心似乎也碎了一塊。這時右手邊傳來一聲咒語,瞬間你的整個靈魂被束縛在原地,且感覺靈魂要被撕碎。
- 魂飛魄散
- 25.你錯愕地看向右方,發現原來是通靈師將你捉了起來,你驚覺或許這一切都是富豪搞的鬼,看到富豪眼裡輕蔑的笑,你才明白一切都晚了。
- 26.面對通靈師的背叛,即將要魂飛魄散的你,最後不捨的看向孩子以及少年,緩緩地閉上了眼睛。
- ==重生==(少年視角)
- 夢醒
- 1.一陣渾沌之中,你聽到有人在呼喊你的名字。你醒來發現一切是那麼陌生又熟悉。你從機構中醒來,想到夢中同伴的枉死,你下定決心這次不能再錯了。
- 回想如何收集證據
- 手頭上的東西
- 2.你算了算時間,現在同伴還未被富豪領養,且你還未相識同伴,於是打算前往孤兒院尋找他。
- 日曆
- 搜尋孤兒院
- 混進孤兒院
- 3.你來到當初同伴所生活的孤兒院,四處遊走期盼能遇到他。
- 大廳
- 遊樂場
- 偶遇當初的同伴
- 你運氣很好,碰到了當初的同伴,你發現同伴看見你的眼神不單純。
- 同伴
- 原來同伴也有夢中的那段記憶,你與同伴開始復盤到底從哪裡開始錯了。
- 孩子
- 各種證據
- 通靈師
- 計畫
- 經過復盤,你與同伴認為通靈師或許知道甚麼,於是打算先去試探通靈師。
- 法會
- 通靈師的秘密
-
- 再次收集證據
- 人販子
- 再次回到永樂莊園
- 集結被富豪迫害的人民
- 收集人證
- 瓦解人民對富豪的信任
- 放出風聲
- 餘論風波
- 提告富豪
- 連署
- 勝訴
- 人證物證皆在,富豪無力反駁,即刻執行死刑。
- 後來
- 永樂莊園瓦解
- 富豪遺產造福社會
- 接手富豪產業
- 遊戲
- 法寶->該如何送到孩子手上
- 規律的步伐->透過規律推出下一步在哪並開門
- 9字鍵(拼音)->數字
- 少年的喃喃自語->暗門的密碼
- function
- 可以參考
- cl-lib-info, or common lisp tutorior(運用seq的部分)
- seq.el, or elisp info
- emacs內建的games
- M-x describe-function +遊戲名 => 可以去看一下人家怎麼寫的
- M-x descrive-function dunnet => adventure的檔
- cl-remove-if-not(?
- seq
- seq-elt
- seq-do
- seq-length
- seq-subseq
- seqp
- seq-into-sequence
- seq-into
- ==seq-filter==
- seq-copy
- seq-sort
- substring-no-propoties(取消預設字的屬性)
- prefix
- load-path
- require
- provide
- gamegrid.el
- manage file
- git
- ert
- package.el
- magit
- [org mode](https://orgmode.org/)
- M-x org-mode
- M-x describe-function org-mode -> 看看有關org-mode的key
- 可以了解功能,看看圖片怎麼呈現,或其他功能
- 也可以連接網頁
- with-temp-buffer
## DUNNET(GAME->ADVENTURE)
- dunnet
- function
- member
- The function member tests to see whether object is a member of list, comparing members with object using equal.
- If object is a member, member returns a list starting with its first occurrence in list.
- Otherwise, it returns nil.
- Compare this with memq:
- ```lisp=
(member '(2) '((1) (2))) ; (2) and (2) are equal.
⇒ ((2))
(memq '(2) '((1) (2))) ; The two (2)s need not be eq.
⇒ Unspecified; might be nil or (2).
;; Two strings with the same contents are equal.
(member "foo" '("foo" "bar"))
⇒ ("foo" "bar")
```
- menq
- This function tests to see whether object is a member of list.
- If it is, memq returns a list starting with the first occurrence of object.
- Otherwise, it returns nil.
- The letter ‘q’ in memq says that it uses eq to compare object against the elements of the list.
- ex.
- ```lisp=
(memq 'b '(a b c b a))
⇒ (b c b a)
```
- intern
- This function returns the interned symbol whose name is name.
- If there is no such symbol in the obarray obarray, intern creates a new one, adds it to the obarray, and returns it.
- If obarray is omitted, the value of the global variable obarray is used.
- ex.
- ```lisp=
(setq sym (intern "foo"))
⇒ foo
(eq sym 'foo)
⇒ t
(setq sym1 (intern "foo" other-obarray))
⇒ foo
(eq sym1 'foo)
⇒ nil
```
- ==Common Lisp note:==
- In Common Lisp, you can intern an existing symbol in an obarray.
- In Emacs Lisp, you cannot do this, because the argument to intern must be a string, not a symbol.
- aset
- **aset** array index object ¶
- This function sets the indexth element of array to be object. It returns object.
- ex.
- ```lisp=
(setq w (vector 'foo 'bar 'baz))
⇒ [foo bar baz]
(aset w 0 'fu)
⇒ fu
w
⇒ [fu bar baz]
;; copy-sequence copies the string to be modified later.
(setq x (copy-sequence "asdfasfd"))
⇒ "asdfasfd"
(aset x 3 ?Z)
⇒ 90
x
⇒ "asdZasfd"
```
- progn
- **progn** is a special form that causes each of its arguments to be evaluated in sequence and then returns the value of the last one.
- The preceding expressions are evaluated only for the side effects they perform.
- The values produced by them are discarded.
- The template for a progn expression is very simple:
- ```lisp=
(progn
body…)
```
- start
- bacth mode
- dun-batch-loop()
- ```lisp=
(defun dun-batch-loop ()
(setq dun-dead nil)
(setq dun-room 0)
(while (not dun-dead)
(if (eq dungeon-mode 'dungeon)
(progn
(if (not (= dun-room dun-current-room))
(progn
(dun-describe-room dun-current-room)
(setq dun-room dun-current-room)))
(dun-mprinc ">")
(setq dun-line (downcase (dun-read-line)))
(if (eq (dun-vparse dun-ignore dun-verblist dun-line) -1)
(dun-mprinc "I don't understand that.\n"))))))
```
- dun-vparse()
- ```lisp=
(defun dun-vparse (ignore verblist line)
"Parse a line passed in as a string.
Call the proper verb with the rest of the line passed in as a list."
(dun-mprinc "\n")
(setq dun-line-list (dun-listify-string (concat line " ")))
(dun-doverb ignore verblist (car dun-line-list) (cdr dun-line-list)))
```
- dunnet()
- ```lisp=
(defun dunnet ()
"Switch to *dungeon* buffer and start game."
(interactive)
(if noninteractive
(dun--batch)
(pop-to-buffer-same-window "*dungeon*")
(dun-mode)
(setq dun-dead nil)
(setq dun-room 0)
(dun-messages)))
```
- dun-messages()
- ```lisp=
(defun dun-messages ()
(if dun-dead
(text-mode)
(when (eq dungeon-mode 'dungeon)
(when (not (= dun-room dun-current-room))
(dun-describe-room dun-current-room)
(setq dun-room dun-current-room))
(dun-fix-screen)
(dun-mprinc ">"))))
```
- dun-describe-room()
- ```lisp=
(defun dun-describe-room (room)
"Give long description of room if haven't been there yet.
Otherwise short. Also give long if we were called with negative room number."
(if (and (not (member (abs room) dun-light-rooms))
(not (member obj-lamp dun-inventory))
(not (member obj-lamp (nth dun-current-room dun-room-objects))))
(dun-mprincl "It is pitch dark. You are likely to be eaten by a grue.")
(dun-mprincl (cadr (nth (abs room) dun-rooms)))
(if (and (and (or (member room dun-visited)
(string= dun-mode "dun-superb"))
(> room 0))
(not (string= dun-mode "long")))
nil
(dun-mprincl (car (nth (abs room) dun-rooms))))
(when (and (not (string= dun-mode "long"))
(not (member (abs room) dun-visited)))
(setq dun-visited (append (list (abs room)) dun-visited)))
(dolist (xobjs (nth dun-current-room dun-room-objects))
(cond
((= xobjs obj-special)
(dun-special-object))
((>= xobjs 0)
(dun-mprincl (car (nth xobjs dun-objects))))
((not (and (= xobjs obj-bus) dun-inbus))
(dun-mprincl (car (nth (abs xobjs) dun-perm-objects)))))
(when (and (= xobjs obj-jar) dun-jar)
(dun-mprincl "The jar contains:")
(dolist (x dun-jar)
(dun-mprincl " " (car (nth x dun-objects))))))
(if (and (member obj-bus (nth dun-current-room dun-room-objects)) dun-inbus)
(dun-mprincl "You are on the bus."))))
```
- dun-fix-screen()
- ```lisp=
(defun dun-fix-screen ()
"In window mode, keep screen from jumping by keeping last line at the bottom of the screen."
(interactive nil dun-mode)
(forward-line (- 0 (- (window-height) 2 )))
(set-window-start (selected-window) (point))
(goto-char (point-max)))
```
- dun-mprinc()
- ```lisp=
(defun dun-mprinc (&rest args)
"Print something out, in window mode."
(dolist (arg args)
(if (stringp arg)
(insert arg)
(insert (prin1-to-string arg)))))
```