Skip to content

jawatech/jawatech.github.io

Repository files navigation

Project Emacgelion (中文)

0. why ?

well… because it would be cool to see emacs run in a web browser, or run with nodejs Project Emacgelion 誕生於2016年1月21日,是嘗試將 Emacs 的核心部分以 javascript 改寫,以執行在 nodejs 及各種瀏覽器的計劃。<br> Project Emacgelion is an attempt to rewrite the core of Emacs with javascript to make Emacs run under nodejs and modern web browsers.

  • 嘗試以 javascript 改寫 emacs ,並且以 nodejs 執行
  • 此一專案是嘗試儘量貼近 emacs 本身的原有功能,以本地端檔案操作為主,以便驗證改寫的功能
  • 為完成上述之任務,必需取得/了解 emacs 的原始碼、建置過程、啟動過程

1.1 取得 emacs 原始碼 @ http://ftpmirror.gnu.org/emacs/

以下以 emacs 24.5 為例

解壓指令 tar zxvf emacs-24.5.tar.gz

http://blog.gtwang.org/linux/linux-why-are-tar-archive-formats-switching-to-xz-compression-to-replace-bzip2-and-what-about-gzip/

1.2 building emacs

Ubuntu安装Emacs出现依赖问题(dependency)及解决方案

sudo apt-get install libgif-dev

參考 http://www.linuxidc.com/Linux/2014-08/104975.htm

執行步驟

  • $ ./configure
  • $ make
  • $ sudo make install prefix=/usr/local/stow/emacs
  • $ cd /usr/local/stow
  • $ stow emacs
使用 stow 來安裝多個版本的 emacs @ http://www.gnu.org/software/stow/

說明 http://www.gnu.org/software/stow/manual/stow.html

1.3 Starting Up Emacs

http://www.gnu.org/software/emacs/manual/html_node/elisp/Startup-Summary.html#Startup-Summary

emacs 的啟動流程,這在選擇性的實作 emacs 時很重要,才能知道該優先實作那些部分

  • 嘗試以 javascript 改寫 lisp interpreter ,並且以 nodejs 執行
  • 此一專案為最基本的工作,必需能寫出取代 temacs 的程式,才有機會完成 Project Emacgelion 其它的兩個專案
  • 根據統計, temacs 包含以 C 寫的函數 1061 個,呼叫外部函數 2384 個(包含 library,以及巨集等);另有以 DEFUN 巨集定義的 lisp 函數 1298 個。

jdp/lisp-ish.js @ gist

https://gist.github.com/jdp/1063999

根據對 nodejs 本身所寫的 repl.js 的分析,可以發現它使用了 readline 模組,而普天之下的 lisp interpreter/compiler 實作,只有這位仁兄這樣幹了。它的內部處理末必見得是最好,但是最合乎 nodejs 的概念–非同步/異步/事件導向。結合 kanaka/mal 相信是比較合理的發展方向。

kanaka/mal @ github (73/2104/416)

https://github.com/kanaka/mal

他的思考比 Peter Norvig 又更高階、更抽象了,把實作分成10步,很清晰、很好了解

files

step*.js

原程式使用了無限循環的迴圈,失去了 nodejs 原有的 nonblocking 式呼叫的精神, 因此預計使用實作 EventEmitter 的各種事件生產者來改寫。 Step0 中使用的即是 readline 函式庫。

core.js

Add a new file core.qx and define an associative data structure ns (namespace) that maps symbols to functions. Move the numeric function definitions into this structure.

types.js
reader.js
printer.js

Add support to printer.qx to print functions values. A string literal like “#” is sufficient.

node_readline.js

從命令行讀入指令。 原程式呼叫了 blocking 的 api ,本專案使用 nodejs 的原生 api 來進行 nonblocking 的呼叫,效果非常好,程式碼也更精簡。

jq_readline.js
interop.js
env.js

special forms

http://hyperpolyglot.org/lisp side-by-side reference sheet

http://www.gnu.org/software/emacs/manual/html_node/elisp/Special-Forms.html

Emacs lispsemantics(if diff.)kanaka/malsemantics(if diff.) / step
and
catchcatch*step 9
condcondstep 8
condition-case
defconst
defvar
functionfn*step 4
ifIf the evaluated condition is non-nil,ifstep 4. If the result (condition) is anything
then-form is evaluated and the result returned.(step 4)other than nil or false , then evaluate the second parameter
www.gnu.org/software/emacs/manual/html_node/elisp/Conditionals.html#Conditionals(third element of the list) and return the result.
interactive
lamdafn*step 4
let
let*let*step 3
ororstep 8
progndostep 4
quotequote
backquote`quasiquote`
,@splice-unquotem ~@
,unquote???~
save-current-buffer
save-excursion
save-restriction
setqdef!step 3
setq-default
track-mouse
unwind-protect
while

mishoo/SLip @ github (12/119/13)

https://github.com/mishoo/SLip http://lisperator.net/slip/

一個 lisp REPL ,被用來當成 browser 的腳本語言,上次活動是3年前

ammarm08/lisp-interpreter

https://github.com/ammarm08/lisp-interpreter

這個專案在這幾個禮拜都還有活動,看來滿有潛力的

lis.py

http://norvig.com/lispy.html

我想接下來的很多專案都基於 Peter Norvig 的這篇文章:

https://github.com/djfdev/jedi

https://github.com/jes5199/brid.js/ 處理 JSON 而非 S-Expression ,概念是相同的,雖然已經是4年前的;有個網頁可以執行

https://github.com/nidhinpdevan/Lisp-interpreter

https://github.com/chirs/slug

https://github.com/inexorabletash/jisp 網頁版的不妨一試,才135行…

maryrosecook/littlelisp

https://github.com/maryrosecook/littlelisp https://www.youtube.com/watch?v=hqnTvuvXPCc

這個版本是兩年前的,明確使用了 node.js ,如果 mishoo/SLip 專案不合適的話,本專案就會是個很好的起點

(我覺得會寫程式的女生真是很吃香…)

joeattueyi/joelisp-js @ github

https://github.com/joeattueyi/joelisp-js

這個版本是一年前的,明確使用了 node.js ,如果 mishoo/SLip 專案不合適的話,本專案就會是個很好的起點

Kraks/lisp.js/ @ github

https://github.com/Kraks/lisp.js/

ditto

dolymood/lisp.js

https://github.com/dolymood/lisp.js

這個專案滿有趣的,雖然已經是3年前的,不過文件寫得不錯,而且是中文

Choltz95/microlispjs

https://github.com/Choltz95/microlispjs

這個版本是6個月前的,明確使用了 jquery ,沒有使用 node.js ,而是在網頁中執行

lispy2

http://norvig.com/lispy2.html

更多的擴展,加入更多語法元素;我想接下來的很多專案都基於 Peter Norvig 的這篇文章:

https://github.com/jhlagado/lispy2js 看來也是網頁版,需以 bower 安裝

nidhinp/Lisp-Interpreter @ github

https://github.com/nidhinp/Lisp-Interpreter

“Lisp Interpreter in JavaScript”

“Implementation of Peter Norvig’s Lisp Interpreter(http://norvig.com/lispy.html) in Javascript.”

samsonjs/elisp.js @ github (2/31/2)

https://github.com/samsonjs/elisp.js

“Emacs Lisp interpreter in JavaScript”

這位作者很規矩地遵守了 MIT license, 也有有寫出他的思路和步驟,而且特別提到了 ymacs ,上次活動是6年前

hraberg/deuce @ github (80/384/14)

https://github.com/hraberg/deuce

這是用現代版的 lisp ( Clojure ) 來重製 emacs 的專案。很可惜目前看來進度停在6個月前;不過很多文件都很值得參考。

nicferrier/emacs-ejit @ github (7/26/3)

https://github.com/nicferrier/emacs-ejit

“Ejit takes EmacsLisp and compiles it to Javascript.”

這裏面作者有寫出他的思路和步驟 ,上次活動是一年前

dogada/metajs @ github (7/37/4)

https://github.com/dogada/metajs

看作者的說明是滿不錯的,上次活動是兩年前

kiwanami/node-elparser @ github

https://github.com/kiwanami/node-elparser

單純就是個 parser ,上次活動是半年前

  • 嘗試將 emacs 放到瀏覽器中執行,並且連結雲端的檔案
  • 一個可以參考的專案是 paredit.js ,如果將它所使用的 ace editor 換成具有 richtext / collaborative edit 的元件,那麼就很有搞頭了… (不過 paredit 仍然不是一個 interpreter ,此功能交由下述子專案 elisp4js 來執行 )
  • 然而從另一個角度來看,因為行為和本地端的文字編輯器已經有所不同,因此改寫的部分可能會沒有現成的套件、文件供參
  • 初期的目標是以能顯示、執行 org mode 相關功能為主

這幾乎是成品了吧我想。

mishoo/ymacs @ github (40/310/52)

https://github.com/mishoo/ymacs http://www.ymacs.org/ 幾乎是成品的感覺,上次活動是9個月前

4. 使用的工具

bookmark+ @ elpa

這個外掛,功能非常之好,讓我可以找到3年前寫的 org mode 註解所指向的原始碼

分析原始碼間的靜態關係,另外安裝 cflow-mode.el 的話,還可得到語法高亮、進行跳轉

Cflow mode defined in `cflow-mode.el’: Major mode for viewing cflow output files.

`n’ and `p’ move to next and previous functions.

`f’ and `b’ move forward and backward at the same level, and `u’ goes up a level; `TAB’ toggles hiding the subtree at point.

If the variable `cflow-display-functions’ is non-nil, the current function is displayed in another window after each movement, and `SPC’ and `DEL’ scroll the other window (and on to the next function on reaching the end of it), and `1’ closes the other window.

If `cflow-display-functions’ is set to the symbol ‘narrowed, the window is narrowed to just that function.

Setting the variable `cflow-backtrack-invisible’ non-nil will ask to reveal, and continue from, a previous hidden section within a level, on reaching the end of the level. If set to the symbol ‘no-ask, it will do it without asking.

`?’ shows the call stack needed to get to the current line.

Key bindings are: key binding — -------

TAB cflow-hide-or-show-subtree SPC cflow-scroll-other-window 1 delete-other-windows ? cflow-get-stack E cflow-edit-out-full R cflow-recursion-next b cflow-backward-same-level d cflow-display-function-other-window f cflow-forward-same-level cflow-next-line o cflow-find-function-other-window p cflow-previous-line r cflow-recursion-root s cflow-find-function u cflow-up-level x cflow-goto-expand DEL cflow-scroll-other-window-down

emacs.cflow.png

chjj/blessed @ github

https://github.com/chjj/blessed

A high-level terminal interface library for node.js

emacs 中有些 termcap 相關的程式,看來有簡單的解法了

Project Emacgelion (English)

  • rewrite emacs with javascript and run with node.js (kinda like atom)
  • this subproject would try to mimic the authentic Emacs as much as possible.
  • will operate on local storage, thus validating against the authentic Emacs
  • to do so, it would be mandatory to understand the authentic Emacs’s source code, build process and startup process

building emacs

using stow

Starting Up Emacs

  • rewriting lisp interpreter with javascript, and run with nodejs
  • it’s the most basic task; ultimately a replacement of native temacs will be built

2.1 samsonjs/elisp.js @ github

MIT licensed and well documented strategies, and referral to ymacs

2.2 nicferrier/emacs-ejit @ github

well documented strategies

  • run emacs in a web browser, linking files in cloud storages
  • would be desirable if we can employ a richtext / collaborative editor
  • on the other hand, owing to the fundamental difference against the authentic Emacs, there may not be many documents
  • the first milestone would be to display and run org mode correctly

a good start.

4. tools used

4.1 bookmark+

will use bookmark+ with org mode to facilitate code comment / navigation

參考資料 / References

1. CLDP – Linux 中文文件計劃 @ http://linux.org.tw/CLDP/OLD/Emacs-Beginner-HOWTO.html

Introduction to Emacs Lisp Programming (以Emacs寫Lisp程式: 簡介)

著者: Robert J. Chassell

From the README file:

This is an elementary introduction to programming in Emacs Lisp for people who are not programmers, and who are not necessarily interested in programming, but who do want to customize or extend their computing environment. (譯文:本書是以Emacs Lisp開發程式的初級課程,用於教授非程式設計師、對程式設計 不一定感興趣但是想客製化或發展他們的電腦的環境的人。) 可以以匿名(anonymous)登入GNU FTP伺候器取得這本書的完整內容: ftp://prep.ai.mit.edu/gnu/emacs/.

評語:Emacs Lisp的極佳入門手冊–即使你不是專業程式設計師

The GNU Emacs Lisp Reference Manual

著者: Richard Stallman

發行者: The Free Software Foundation - http://www.fsf.org/

可以以匿名(anonymous)登入GNU FTP伺候器取得這本書的完整內容: ftp://prep.ai.mit.edu/gnu/emacs/.

評語:Emacs Lisp程式設計的終極指引。

2. 你是如何成为 Lisp 程序员的

http://blog.csdn.net/u013131455/article/details/48897329

Introduction to Emacs Lisp Programming

在龐大的Lisp家譜中, Emacs Lisp 不是Common Lisp,而是早期的MacLisp的一個直系後代, 同時在一些方面作了簡化和強化 。同時我開始閱讀Robert Chassell所著《Introduction to Emacs Lisp Programming》,Robert Chassell是斯托曼院士早年結識的戰友,也是自由軟件基金會的合創人之一,他很早就使用GNU Emacs,而且使用Emacs Lisp程序定制GNU Emacs,斯托曼友善地把 Robert Chassell 介紹給我認識 。這本書既是自由文檔 (可以從GNU的網站自由下載) ,又是自由軟件基金會出版社(GNU Press)的出版物 。等我讀完了這本書之後 ,我覺得這本書實在太美妙了,作者的文筆十分了不起(即使對於想學習英文寫作的人,幫助也應該很大),把這本 書介紹給其他人是完全值得的。我於是找了兩位翻譯人員(毛文濤博士和呂芳女士),把它譯成了中文,我則擔任了全書的編輯和審校工作。中文版質量很高,我很 滿意 ,它作為一本很偉大的編程入門書籍十分適合廣大讀者自學 (我認為讀者應該搞到一本閱讀) 。我至今還想自己動手翻譯這本書的第三版,可惜如今我很難再找 到當年那麼多的時間做編輯和審校之類的工作了。

GNU Emacs Lisp Reference Manual

閱讀完這本書之後,我意識到如果想使用 Emacs Lisp 開發非玩具級別的實際應用程序 ,那麼根據作者的推薦 ,自由軟件基金會出版的 《GNU Emacs Lisp Reference Manual》是必不可少的工具書 ,我打印了這份文檔的第2.4版本 ,厚厚的共四本 。後來這份文檔正式出版,從GNU網站上訂購的圖書升級到了2.6版 本,針對的是GNU Emacs version 21。我不太認同Eric Raymond在他的名著《The Art of Unix Programming》中對Emacs Lisp的評論,他以為Emacs Lisp只能為Emacs編輯器本身編寫控製程序,而趕不上其他腳本語言全面。實際上,我認為只要熟悉了Emacs Lisp的細節,其他任何腳本語言能完成的工作,都可以使用Emacs Lisp程序完成。我親眼看見斯托曼院士在GNU Emacs內完成電子郵件的編輯、收發等工作,不用Eric Raymond開發的fetchmail程序一樣幹得很好。我自己也利用Emacs Lisp編寫過CGI應用程序,效果也不錯。

Bob Glickstein曾經寫過一本《Writing GNU Emacs Extensions》,可以配合Robert Chassell的書與《GNU Emacs Lisp Reference Manual》,作為補充讀物。

Common Lisp: A Gentle Introduction to Symbolic Computation

讀了Robert Chassell的書之後,我開始花時間閱讀David Touretzky博士所著的《Common Lisp: A Gentle Introduction to Symbolic Computation》 ,這本書可以從互聯網上自由下載 ,讀者可以自行在萬維網上google得到它 。這也是一本偉大的Lisp著作 ,內容已經是基於 Common Lisp的,但是作者並沒有特意強調這一點 。我把下載的PDF文件打印出來 ,自己動手把打印出的文檔紙張裝訂成了兩卷手冊。我從這本書中得到的最大收穫是 我充分認識到Lisp中的一切都是對象:數字原子(numeric atoms)和符號原子(symbolic atoms)都是對象 。數字原子求值返回它自身的值,而符號原子則有名稱(name)、類型(type)、值(value)、秉性表(plist)和綁定 表(bindlist)。這五個字段可以放入一個數據結構中,並在實現中以C語言的struct表達。

Interpreting Lisp

在閱讀這些材料的同時,我又從網上找到了Gary Knott教授編寫的一份文檔,《Interpreting Lisp》 ,這份文檔篇幅不長 ,從來沒有正式出版成書。在這份文檔中,作者利用C語言編寫了一個微小的Lisp實現,非常接近於最初的Lisp實現。最可 貴的是他將實現的源代碼和盤托出。從這本書中,我清晰地看到瞭如何構造Lisp對象的結構,我開始認識到內存垃圾收集算法的重要性。在理解了David Touretzky博士所著的《Common Lisp: A Gentle Introduction to Symbolic Computation》 介紹的Lisp對象的結構基礎上 ,我明白了書中圖示的Lisp對像中若僅在結構設計時安排五個字段是不夠的,還需要有供垃圾回收 (GC,Garbage CCollector)模塊操作的字段才行。

3. Emacs是第一个人工生命 by KONG (霍犀子)

Emacs看起来像是一个其貌不扬的普通编辑器,但实际上却是个真正意义上 的IDE(Integrated Developing Environment),和Borland,Microsoft的 东西不同,Emacs对用户和程序员区别不大,也就是用户即程序员,程序员 即用户.这一点是这样实现的:Emacs有一个C编的硬核,像其它C语言编的 程序一样,这个硬核是不能轻易改变的,除非你有源码并且对系统内部有 较深刻的了解,即使有了这些条件也必须重新make,在运行Emacs时是不能 对这个硬核做任何代码上的修改的.安装过Emacs的人知道在安装过程中会 生成一个temacs可执行文件,这个temacs就是完全由C实现的硬核,它实现 的是LISP的链表解释机制和一些基本的LISP函数,比如在Emacs的 scratch (涂鸦) buffer里打入:

(symbol-function ‘car) <Ctrl-j>

系统会告诉你 #<subr car>

就是说car是个C实现的LISP函数,属于硬核的一部分,你不能改变它的函数 定义.

其实理论上说这个硬核完全可以最小化,只包含一些最最基本的函数,大概 用汇编就能够写出来.但为portability和performance起见,这个硬核用C 实现并包含了基本上所有的常见LISP函数.打个比方,就像逻辑运算一样, 尽管用NOT和AND就能够表示所有的逻辑运算,平常我们还是NOT,AND,OR齐上. temacs里有些LISP函数其实完全可以用一些更基本的LISP函数实现,但为了 速度,Richard Stallman还是把它们用C实现了,这样做的好处是速度快了, 坏处看完了下面你就明白了.

有了temacs,以后的事情就是在它的基础上滚雪球,不断地在temacs里eval LISP函数,temacs知道的越来越多,功能就会越来越强.Stallman选了几个 最基本的package,如文件操作等等,作为标准的部件,在install时就喂给 temacs,再把LISP可执行内存映象dump下来,这就是平常大家用的emacs了. 同样在*scratch*里打入: (symbol-function ‘find-file) <Ctrl-j>

结果可能是 (lambda (filename) ...............) 这就是经过eval而被temacs吸收的LISP函数;

也可能是 #[(filename) ................] 这是Stallman定义的一种LISP bytecode,用来提高LISP的运行效率,这种bytecode 一般比功能等价的C代码还是要慢一些,但和LISP的文本代码是一一对应的,并且速 度大大提高,必要时可以通过decompile恢复成LISP文本代码.猜测JAVA的bytecode 借鉴了不少LISP bytecode的技术,JAVA可以说是一个表面上C++词法风格、实际上 Object-oriented的type architecture加上LISP的run-time environment.JAVA Virtual Machine完全就是一台最新LISP Machine.

言归正传,经eval而被temacs吸收的LISP函数和那种#[subr …] C函数就不一样了, 你可以通过eval加入一些这样的函数,也可以通过unintern去掉一些这样的函数, 还可以现改函数定义略微增加或减少一些功能,这就把一个运行程序的部件当做一 个数据库一样可以任意剪裁,根据具体情况随意增加或减少它的功能.就像生物的 新陈代谢一样,汲取营养,排泄废物,所以说Emacs是个生物,唯一的遗憾是这个生 物还是个婴儿,不会自己觅食,需要用户喂它吃那些.el文件才行.

Internet上最大的.el文件库在 ftp://archive.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive/ 用户也可以自编或改编一些现成的.el文件以实现自己需要的功能.

.elc是byte-compile相应.el文件产生的byte-code文件,如何编写.el文件可参看 Emacs的online info manuals (C-h i)的Emacs Lisp reference.

用户可用load和autoload调入新的.el文件.当然调的越多Emacs就越吃内存,Emacs 有garbage-collect函数负责回收内存,硬核里有根据情况触发garbage-collect的机 制.

用户用的一切功能都是temacs + 其eval过的所有LISP函数 + 与Emacs配合的外部命令 (如gdb等)实现的.其中temacs里的链表解释机制是最灵魂的部分,从有LISP的那天起 就没变过,预eval的package可由安装者指定;与Emacs配合的外部命令可以是OS里的 任何输入输出可处理的命令,当然能像gdb那样和Emacs有所约定的更好;所eval的 LISP函数是最灵活的部分,用户可以随心所欲地configure,当然喜欢玩傻瓜机的人还 是离得远一点为好.

This section explains the steps involved in building the Emacs executable. You don’t have to know this material to build and install Emacs, since the makefiles do all these things automatically. This information is pertinent to Emacs developers.

Compilation of the C source files in the src directory produces an executable file called temacs , also called a bare impure Emacs. It contains the Emacs Lisp interpreter and I/O routines, but not the editing commands.

The command temacs -l loadup would run temacs and direct it to load loadup.el. The loadup library loads additional Lisp libraries, which set up the normal Emacs editing environment. After this step, the Emacs executable is no longer bare.

Because it takes some time to load the standard Lisp files, the temacs executable usually isn’t run directly by users. Instead, as one of the last steps of building Emacs, the command ‘temacs -batch -l loadup dump’ is run. The special ‘dump’ argument causes temacs to dump out an executable program, called emacs, which has all the standard Lisp files preloaded. (The ‘-batch’ argument prevents temacs from trying to initialize any of its data on the terminal, so that the tables of terminal information are empty in the dumped Emacs.)

The dumped emacs executable (also called a pure Emacs) is the one which is installed. The variable preloaded-file-list stores a list of the Lisp files preloaded into the dumped Emacs. If you port Emacs to a new operating system, and are not able to implement dumping, then Emacs must load loadup.el each time it starts.

You can specify additional files to preload by writing a library named site-load.el that loads them. You may need to rebuild Emacs with an added definition

#define SITELOAD_PURESIZE_EXTRA n to make n added bytes of pure space to hold the additional files; see src/puresize.h. (Try adding increments of 20000 until it is big enough.) However, the advantage of preloading additional files decreases as machines get faster. On modern machines, it is usually not advisable.

After loadup.el reads site-load.el, it finds the documentation strings for primitive and preloaded functions (and variables) in the file etc/DOC where they are stored, by calling Snarf-documentation (see Accessing Documentation).

You can specify other Lisp expressions to execute just before dumping by putting them in a library named site-init.el. This file is executed after the documentation strings are found.

If you want to preload function or variable definitions, there are three ways you can do this and make their documentation strings accessible when you subsequently run Emacs:

  • Arrange to scan these files when producing the etc/DOC file, and load them with site-load.el.
  • Load the files with site-init.el, then copy the files into the installation directory for Lisp files when you install Emacs.
  • Specify a nil value for byte-compile-dynamic-docstrings as a local variable in each of these files, and load them with either site-load.el or site-init.el. (This method has the drawback that the documentation strings take up space in Emacs all the time.)

It is not advisable to put anything in site-load.el or site-init.el that would alter any of the features that users expect in an ordinary unmodified Emacs. If you feel you must override normal features for your site, do it with default.el, so that users can override your changes if they wish. See Startup Summary. Note that if either site-load.el or site-init.el changes load-path, the changes will be lost after dumping. See Library Search. To make a permanent change to load-path, use the –enable-locallisppath option of configure.

In a package that can be preloaded, it is sometimes necessary (or useful) to delay certain evaluations until Emacs subsequently starts up. The vast majority of such cases relate to the values of customizable variables. For example, tutorial-directory is a variable defined in startup.el, which is preloaded. The default value is set based on data-directory. The variable needs to access the value of data-directory when Emacs starts, not when it is dumped, because the Emacs executable has probably been installed in a different location since it was dumped.

Function: custom-initialize-delay symbol value

This function delays the initialization of symbol to the next Emacs start. You normally use this function by specifying it as the :initialize property of a customizable variable. (The argument value is unused, and is provided only for compatibility with the form Custom expects.)

In the unlikely event that you need a more general functionality than custom-initialize-delay provides, you can use before-init-hook (see Startup Summary).

Function: dump-emacs to-file from-file

This function dumps the current state of Emacs into an executable file to-file. It takes symbols from from-file (this is normally the executable file temacs).

If you want to use this function in an Emacs that was already dumped, you must run Emacs with ‘-batch’.

38.1.1 Summary: Sequence of Actions at Startup

When Emacs is started up, it performs the following operations (see normal-top-level in startup.el):

  1. It adds subdirectories to load-path, by running the file named subdirs.el in each directory in the list. Normally, this file adds the directory’s subdirectories to the list, and those are scanned in their turn. The files subdirs.el are normally generated automatically when Emacs is installed.
  2. It loads any leim-list.el that it finds in the load-path directories. This file is intended for registering input methods. The search is only for any personal leim-list.el files that you may have created; it skips the directories containing the standard Emacs libraries (these should contain only a single leim-list.el file, which is compiled into the Emacs executable).
  3. It sets the variable before-init-time to the value of current-time (see Time of Day). It also sets after-init-time to nil, which signals to Lisp programs that Emacs is being initialized.
  4. It sets the language environment and the terminal coding system, if requested by environment variables such as LANG.
  5. It does some basic parsing of the command-line arguments.
  6. If not running in batch mode, it initializes the window system that the variable initial-window-system specifies (see initial-window-system). The initialization function for each supported window system is specified by window-system-initialization-alist. If the value of initial-window-system is windowsystem, then the appropriate initialization function is defined in the file term/windowsystem-win.el. This file should have been compiled into the Emacs executable when it was built.
  7. It runs the normal hook before-init-hook.
  8. If appropriate, it creates a graphical frame. This is not done if the options ‘–batch’ or ‘–daemon’ were specified.
  9. It initializes the initial frame’s faces, and sets up the menu bar and tool bar if needed. If graphical frames are supported, it sets up the tool bar even if the current frame is not a graphical one, since a graphical frame may be created later on.
  1. It use custom-reevaluate-setting to re-initialize the members of the list custom-delayed-init-variables. These are any pre-loaded user options whose default value depends on the run-time, rather than build-time, context. See custom-initialize-delay.
  2. It loads the library site-start, if it exists. This is not done if the options ‘-Q’ or ‘–no-site-file’ were specified.
  3. It loads your init file (see Init File). This is not done if the options ‘-q’, ‘-Q’, or ‘–batch’ were specified. If the ‘-u’ option was specified, Emacs looks for the init file in that user’s home directory instead.
  4. It loads the library default, if it exists. This is not done if inhibit-default-init is non-nil, nor if the options ‘-q’, ‘-Q’, or ‘–batch’ were specified.
  5. It loads your abbrevs from the file specified by abbrev-file-name, if that file exists and can be read (see abbrev-file-name). This is not done if the option ‘–batch’ was specified.
  6. If package-enable-at-startup is non-nil, it calls the function package-initialize to activate any optional Emacs Lisp package that has been installed. See Packaging Basics.
  7. It sets the variable after-init-time to the value of current-time. This variable was set to nil earlier; setting it to the current time signals that the initialization phase is over, and, together with before-init-time, provides the measurement of how long it took.
  8. It runs the normal hook after-init-hook.
  9. If the buffer scratch exists and is still in Fundamental mode (as it should be by default), it sets its major mode according to initial-major-mode.
  10. If started on a text terminal, it loads the terminal-specific Lisp library (see Terminal-Specific ), and runs the hook tty-setup-hook. This is not done in –batch mode, nor if term-file-prefix is nil.
  11. It displays the initial echo area message, unless you have suppressed that with inhibit-startup-echo-area-message.
  12. It processes any command-line options that were not handled earlier.
  13. It now exits if the option –batch was specified.
  14. If initial-buffer-choice is a string, it visits the file (or directory) with that name. If it is a function, it calls the function with no arguments and selects the buffer that it returns. If the scratch buffer exists and is empty, it inserts initial-scratch-message into that buffer.
  15. It runs emacs-startup-hook.
  16. It calls frame-notice-user-settings, which modifies the parameters of the selected frame according to whatever the init files specify.
  17. It runs window-setup-hook. The only difference between this hook and emacs-startup-hook is that this one runs after the previously mentioned modifications to the frame parameters.
  18. It displays the startup screen, which is a special buffer that contains information about copyleft and basic Emacs usage. This is not done if inhibit-startup-screen or initial-buffer-choice are non-nil, or if the ‘–no-splash’ or ‘-Q’ command-line options were specified.
  19. If the option –daemon was specified, it calls server-start and detaches from the controlling terminal. See Emacs Server in The GNU Emacs Manual.
  20. If started by the X session manager, it calls emacs-session-restore passing it as argument the ID of the previous session. See Session Management.

The following options affect some aspects of the startup sequence.

User Option: inhibit-startup-screen

This variable, if non-nil, inhibits the startup screen. In that case, Emacs typically displays the scratch buffer; but see initial-buffer-choice, below.

Do not set this variable in the init file of a new user, or in a way that affects more than one user, as that would prevent new users from receiving information about copyleft and basic Emacs usage.

inhibit-startup-message and inhibit-splash-screen are aliases for this variable.

User Option: initial-buffer-choice

If non-nil, this variable is a string that specifies a file or directory for Emacs to display after starting up, instead of the startup screen. If its value is a function, Emacs calls that function which must return a buffer which is then displayed. If its value is t, Emacs displays the scratch buffer.

User Option: inhibit-startup-echo-area-message

This variable controls the display of the startup echo area message. You can suppress the startup echo area message by adding text with this form to your init file:

(setq inhibit-startup-echo-area-message “your-login-name”)

Emacs explicitly checks for an expression as shown above in your init file; your login name must appear in the expression as a Lisp string constant. You can also use the Customize interface. Other methods of setting inhibit-startup-echo-area-message to the same value do not inhibit the startup message. This way, you can easily inhibit the message for yourself if you wish, but thoughtless copying of your init file will not inhibit the message for someone else.

User Option: initial-scratch-message

This variable, if non-nil, should be a string, which is inserted into the scratch buffer when Emacs starts up. If it is nil, the scratch buffer is empty.

The following command-line options affect some aspects of the startup sequence.

See Initial Options in The GNU Emacs Manual.

–no-splash

Do not display a splash screen.

–batch

Run without an interactive terminal. See Batch Mode.

–daemon

Do not initialize any display; just start a server in the background.

–no-init-file -q

Do not load either the init file, or the default library.

–no-site-file

Do not load the site-start library.

–quick -Q

Equivalent to ‘-q –no-site-file –no-splash’.