Ted's Blog

Happy coding

emacs的定制&LISP包的加载

一、emacs的启动配置文件

    emacs配置文件的文件名为“.emacs.el“或“.emacs“。它们通常位于计算机的 $HOME 目录,如果是MS Windows (Windows 2000, Windows XP以上),默认是 c:\Documents and Settings\username\Application Data\,这个适用于 Emacs22 以上的版本。Emacs21 默认的 $HOME 目录在 C:\ 。当然也可以通过环境变量 $HOME 重新设置,总之在比较大众化的操作系统中,你都可以通过C-x C-f ~/.emacs 来编辑您的个性化配置文件。
    “.emacs”文件其实是一个LISP程序脚本。emacs编辑器通过运行该文件中的脚本来对自身进行初始化。因此,“.emacs”文件的语法与就是LISP程序语言相同

补充:

1. 只有当插件被 emacs 成功加载了,我们才能使用该插件提供的函数

2. (require 'ecb):该函数首先会判断插件是否已经被加载,如果没有,则使用 load 函数来从 lisp目录中加载插件


二、快捷键的定制

  1. 键位映射图:多个按键绑定构成的一个集合。Emacs中有两类映射图:(1).全局影射图:对所有模式的编辑缓冲区都起作用的按键映射图 (2).局部映射图:对具体的编辑模式起作用的映射图。例如:c模式、文本模式等。当按下某个按键时,Emacs会首先查看当前编辑缓冲区的局部映射图里有没有对它进行定义。如果没有,就会查找全局映射图。如果找到了与按键对应的定义项,那么按键关联的命令就会被执行。
  2. 如果自定义的快捷键与系统中默认的快捷键冲突,则系统中默认的快捷键将会被替换

定制方法:

(1).(define-key keymap "keystroke" 'command-name):将快捷键定义保存到指定的keymap中
(2).(global-set-key "keystroke" 'command):只能将快捷键定义保存到全局keymap射图中
(3).(local-set-key "keystroke" 'command-name):只能将按键绑定到局部映射图中。每种编辑模式都对应了一张局部映射图。
(4).keystroke字符串中,必须使用\C来代表字符Ctrl,\M来代表字符Alt

三、设置emacs内部变量

setq函数用来设置emacs内部变量,其使用方法如下:

(setq auto-save-interval 800)

四、LISP初识

a. 数据类型

  1. t:true
  2. nil:false
  3. 字符串:使用""括起来
  4. 字符:以?开头。例如:?x代表字符x
  5. 标志符:以'开头。例如:表示函数名时使用‘command-name

补:LISP语言中的语句以“(”来表示语句的开始,以“)”来表示语句的结束

b. 函数的定义

defun关键字:用来定义LISP函数。

(defun my-cpp-mode()

(define-key c++-mode-map [return] 'newline-and-indent)

(define-key c++-mode-map [(control c) (c)] 'compile)

(interactive)

(c-set-style "K&R")

(c-toggle-auto-state)

(c-toggle-hungry-state)

(setq c-basic-offset 4)

(imenu-add-menubar-index)

(which-function-mode)

)

c. 常用函数

  1. add-hook:该函数用来将某个函数与指定的模式绑定,当emacs进入相应的模式时,将自动调用与该模式绑定的函数。例如:(add-hook 'c++-mode-hook 'my-cpp-mode)
  2. require:该函数检测在当前emacs会话中是否加载了指定的插件,如果没有,则使用load函数来从系统的LISP目录中加载指定的插件。例如:(require 'session):从lisp-path中加载session.el文件

五、加载LISP包

  1. emacs编辑器的主要功能是使用LISP编程语言来写的,因此我们可以往emacs中加载LISP包来为emacs添加更多的功能。LISP语言是一种解释型语言,其程序文件的扩展名为*.el。
  2. c-h p:查看当前emacs会话所加载的LISP包
  3. 在".emacs“文件中使用require函数来加载指定的LISP包。例如:(require 'session):加载session包
  4. *scratch*缓冲区可以用来进行LISP代码的测试。首先,将LISP语句复制到该缓冲区中,然后将光标移动LISP语句的末尾,最后,使用C-x C-e来执行该LISP语句
  5. 系统默认的LISP包的目录为:“/usr/share/emacs/site-lisp”。安装LISP包时只需要将其复制到该目录下即可。

emacs的使用

一、emacs编辑器简介

     emacs编辑器是由C语言和LISP语言编写的。LISP(链表处理语言)是由约翰·麦卡锡在1960年左右创造的一种基于λ演算的函数式编程语言。 我们可以使用LISP来扩展emacs,从而为emacs添加更多的命令。(补:emacs -nw:以命令行的方式来运行emacs,而不启动GUI界面)



* 自动保存功能

      如果你已经修改了一个文件,但是还没来得及存盘你的计算机就罢工了,那么你所做的修改就很可能会丢失。为了避免这样的不幸发生,Emacs 会定期将正在编辑的文件写入一个“自动保存”文件中。自动保存文件的文件名的头尾各有一个“#”字符,比如你正在编辑的文件叫“hello.c”,那么它 的自动保存文件就叫“#hello.c#”。这个文件会在正常存盘之后被 Emacs 删除。
      所以,假如不幸真的发生了,你大可以从容地打开原来的文件(注意不是自动保存文件)然后输入 M-x recover file<Return> 来恢复你的自动保存文件。在提示确认的时候,输入 yes<Return>。


* 其他

  1. 当emacs失去响应时,C-g命令可用来结束纸条命令的执行。其功能相当于Shell中的Ctrl+C
  2. 有一些 Emacs 命令被“禁用”了,以避免初学者在不了解其确切功能的情况下误用而造成麻烦。如果你用到了一个被禁用的命令,Emacs 会显示一个提示消息,告诉你这个命令到底是干什么的,询问你是否要继续,并在得到你的肯定之后再执行这命令


二、emacs编辑器的界面

1. 编辑区
    用来进行文本编辑的区域。


2. 回显区

      如果 Emacs 发现你输入多字符命令的节奏很慢,它会在窗格的下方称为“回显区”的地方给你提示。回显区位于屏幕的最下面一行。



3. 状态栏

  1. 位于回显区正上方的一行被称为“状态栏”。状态栏最开头的星号(*)表示你已经对文字做过改动。刚刚打开的文件肯定没有被改动过,所以状态栏上显示的不是星号而是短线(-)。
  2. 状态栏中的小括号用来指明当前使用的编辑模式,默认是fundamental(主模式),emacs的主模式包括了文本模式以及编辑程序源码的Lisp模式等。


三、emacs所能提供的工作环境

  1. emacs可以执行Shell命令
  2. emacs可以作为Directory Editor(Dired)
  3. emacs可以编辑、编译以及调试程序
  4. emacs可以编辑其它主机上的文档
  5. emacs可以打印文件
  6. emacs具有年历(Calendar)以及日记功能
  7. emacs可以用来阅读man page和info文档
  8. emacs可以收发电子邮件
  9. emacs可以阅读网络上的电子布告栏(GNUS)
  10. emacs具有版本控制的功能(CVS)
  11. emacs可以提供娱乐环境(游戏功能)

    emacs所提供的这些功能,都是先唤起代表此功能的模式(mode)。emacs的模式,分成主要模式(major mode)与次要模式(minor mode)。每一次只能使用一个主模式,而且主模式是必须要的。在一个主模式下,俄可以搭配一个以上的次要模式。使用次要模式相当于启用了该次要模式所对应的插件。



四、emacs命令

  1. emacs中的每一个命令都有一个命令名,命令名就是该命令所对应的LISP函数的函数名。在emacs中,我们可以为这些命令配置快捷键,从而达到快速调用命令的目的。
  2. .使用emacs来执行命令的方法有两种:(1).使用Ctrl键 (2).使用Meta键。所有emacs命令都可以用Meta键表示出来,键盘上如果没有Meta键,则可以用Alt键或ESC键来代替。常用的emacs命令通常会有一个快捷键与之相连。快捷键通常是以Ctrl来开头(C-x C-c)。如果要使用Meta键来表达与“Ctrl-x Ctrl-c”相同的效果,则使用“M-x save-buffers-kill-emacs”。使用Meta键,可以利用emacs的completion功能。使用emacs的completion功能的方法是将部分字符串键入后,再按下TAB、SPACE或?键即可。
       (1).TAB键:尽可能将其的字填满。
       (2).SPACE键:将分隔符(-)之前的字填满。
       (3).?:将所有可能的completion选择都列出来。
  3. 由于emacs中所有的命令都有一个命令名(LISP函数的函数名),因此,我们可以使用“M-x 命令名”来调用emacs中的所有的命令。


* 基本光标控制

  1. C-v:向下翻屏,与PageDown效果相同(v-> vertical)
  2. M-v:向上翻屏,与PageUp效果相同
  3. C-l:重绘屏幕,并将光标所在行置于屏幕的中央
  4. C-b:光标向前移动一格(b->backward)
  5. C-f:光标向后移动一格(f->forward)
  6. C-p:光标向前移动一行(p->previous)
  7. C-n:光标向后移动一行(n->next)
  8. M-b:光标向前移动一个单词
  9. M-f:光标向后移动一个单词
  10. C-a:光标移动到行首
  11. C-e:光标移动到行尾
  12. M-<:光标移动到文章的开头(注意:“<”的输入要shift键,实际为Alt+Shift+<)
  13. M->:光标移动到文章的结尾
  14. C-u:给命令传递参数。例如:“C-u 2 C-d”表示删除两个字符
  15. M-x goto-line n RET:调到第n行


* 编辑命令

  1. C-d:删除光标后的一个字符
  2. C-k:删除从光标到行尾的字符(k->killl)
  3. C-x u:Undo(想要redo,随便输入一个字符,在Undo)
  4. C-SPC、C-@、M-x set-mark-command:设置mark
  5. C-x h:将整个缓冲区设置为区域
  6. C-w:将区域的文本删除,并放入yanking ring中。区域指的是从mark到point(光标所处的位置称为point)之间的文本
  7. M-w:复制区域到yanking ring中
  8. C-y:将yanking ring中最后一个区域插入当前缓冲区
  9. M-j:回车并且到下一行产生适当的缩进
  10. M-m:将光标移动到当前行的第一个非空白字符上
  11. M-;:产生通用注释
  12. M-x comment-region:把块注释掉
  13. M-x kill-comment:消除注释


* 查找与替换

  1. C-s:向后搜索,光标将停在第一个匹配的字符串处。再按一次C-s将继续搜索下一个匹配的字符串。如果要停止搜索,则使用C-g,此时光标将会回到搜索开始的位置
  2. C-r:向前搜索
  3. M-x replace-string:替换


* 文件操作

  1. C-x c-f:打开文件,如果文件不存在则创建
  2. C-x C-s:保存文件。第一次存盘时,emacs会将文件重命名来备份。重命令的规则通常是在原文件名后加上一个“~”字符。如果要关闭emacs的自动备份功能,使用 M-x customize-variable <Return> make-backup-files <Return>
  3. C-x C-w:将文件“另存为”
  4. C-x C-v:打开一个新文件,并关闭当前缓冲区
  5. C-x C-r:以只读的方式打开文件
  6. C-x i:将文件插入光标当前位置


* 缓冲区

  1. Emacs 把每个编辑中的文件都放在一个称为“缓冲区(buffer)”的地方。每打开一个文件,Emacs 就在其内部开辟一个缓冲区用来保存打开的文件的数据。ESC ESC ESC命令可以用来退出打开的小缓冲区,比如:命令提示窗格等
  2. C-x C-b   列出当前所有的缓冲区(b->buffer)
  3. C-x b 缓冲区名:切换到指定的缓冲区(例如:C-x b M<tab>:切换到以M开头的缓冲区)
  4. C-x s:保存emacs中所有的缓冲区(s->save)
  5. C-x right:切换到下一个缓冲区
  6. C-x left:切换到前一个缓冲区
  7. C-x C-c:退出emacs,并询问用户是否保存
  8. C-x k:关闭缓冲区
  9. C-z:将emacs挂起,然后回到Shell中,并不退出emacs。之后,我们可以使用%emacs或fg命令来回到emacs



* 窗口

Emacs 可以有多个窗格,每个窗格显示不同的文字。

  1. C-x 0:关闭光标所在的窗口
  2. C-x 1:保留光标所在的窗格,并将其扩大到整个屏幕,同时关掉所有其它的窗格
  3. C-x 2:水平分割当前窗口
  4. C-x 3:垂直分割当前窗口
  5. C-x o:在emacs的窗格中进行切换(o->other)
  6. C-M-v:滚动下方的窗格。一般在我们使用下方的窗格进行参考,而又不想将光标切换到下一个窗格时使用



* 使用帮助

  1. C-h c 快捷键:显示快捷键的简要说明
  2. C-h k 快捷键:显示快捷键所对应的命令名及其详细说明
  3. C-h a 关键字:显示包含有指定关键字的命令
  4. C-h i:查看Info文档



* 在emacs中运行shell命令

  1. M-! cmd RET:打开一个名为“*Shell Command Output*“的窗口,并把该命令的执行结果显示在其中。按下”C-x 1“组合键可以关闭这个窗口。由于Shell命令的输出是在一个编辑缓冲区里,因此我们可以对它进行编辑、保存等操作。
  2. M-| cmd RET:运行Shell命令,并使用编辑窗口中选定的区域作为该Shell命令的输入,然后可以选择是否用该Shell命令的输出来替换编辑窗口中选中的区域。
  3. C-u M-! cmd RET:执行一条Shell命令,并将其输出放到编辑区中光标所在的位置处,而不将其输出到”Shell Command Output“窗口。
  4. M-x shell:运行一个子Shell,该子Shell对应于emacs中的一个名为”*Shell*"的缓冲区,此后,我们就可以交互式的运行Shell命令了。
  5. M-x term:运行一个子Shell,该子Shell对应于emacs中的一个名为“*Terminal*”的缓冲区。使用该命令获得的子Shell是一个完整的Shell的模拟,与我们直接在Shell中操作没有什么差别。
  6. M-x eshell:运行emacs shell。该Shell为emacs自己实现的一个shell,而前面运行的shell都为系统中的shell程序(例如:/bin/csh等)。我们可以通过设置变量shell-file-name来设置emacs所使用的默认shell


* Dired功能

  1. emacs的Dired(Directory Editor)功能使emacs缓冲区能够用来显示目录列表,并可以用来进入目录的子目录。Dired缓冲区是只读的,不能够被修改。
  2. C-x d:进入Dired



* emacs配置文件

    emacs配置文件通常位于计算机的 $HOME 目录,如果是 MS Windows (Windows 2000, Windows XP以上),默认是 c:\Documents and Settings\username\Application Data\,这个适用于 Emacs22 以上的版本。Emacs21 默认的 $HOME 目录在 C:\ 。当然也可以通过环境变量 $HOME 重新设置,总之在比较大众化的操作系统中,你都可以通过C-x C-f ~/.emacs 来编辑您的个性化配置文件。

;;显示时间

(display-time)

;;显示行号

(column-number-mode t)

(show-paren-mode t)

;;设置TAB宽度为4

(setq default-tab-width 4)

;;以下设置缩进

(setq c-indent-level 4)

(setq c-continued-statement-offset 4)

(setq c-brace-offset -4)

(setq c-argdecl-indent 4)

(setq c-label-offset -4)

(setq c-basic-offset 4)

(global-set-key "\C-m" 'reindent-then-newline-and-indent)

(setq indent-tabs-mode nil)

(setq standard-indent 4)

;;开启语法高亮。

(global-font-lock-mode 1)

;;设置默认工作目录

(setq default-directory "/home/test/source/")

;; 去掉滚动条

(set-scroll-bar-mode nil)

;;关闭开启画面

(setq inhibit-startup-message t)

(setq indent-tabs-mode t)

;;不产生备份文件

(setq make-backup-files nil)

;;设置自定义变量

(custom-set-variables

'(column-number-mode t)

'(current-language-environment "UTF-8")

'(display-time-mode t)

'(ecb-options-version "2.32")

'(mouse-1-click-in-non-selected-windows t)

'(mouse-drag-copy-region t)

'(mouse-yank-at-point t)

'(save-place t nil (saveplace))

'(show-paren-mode t)

'(transient-mark-mode t))

(custom-set-faces

;;选择小工具栏图标

(tool-bar-mode -1)


*

Emacs Tips n Tricks for Everybody

Home

Emacs Tips n Tricks for Everybody

This web-page is not yet complete. Several pieces of LISP-code require explanations — I'll add them as I get time.

To try out a code snippet, just add it to your .emacs, re-start emacs and see if any error messages appear (visit the *messages* window in emacs. Alternately, if you're familiar with the basic syntax of LISP, you could position your cursor after a closing parenthesis (the end of a LISP expression) and press C-x C-e (ctrl-x followed by ctrl-e). This would "evaluate" the expression, thereby "executing" the command. Of course, to execute the command automatically every time you start emacs, you would have to add it to your .emacs.

Removing Annoyances


(setq inhibit-startup-message t) will inhibit startup messages.

(setq require-final-newline t) will make the last line end in a carriage return.

(fset 'yes-or-no-p 'y-or-n-p) will allow you to type just "y" instead of "yes" when you exit.

(setq next-line-add-newlines nil) will disallow creation of new lines when you press the "arrow-down key" at end of the buffer.

General Embellishments


(setq modifier-keys-are-sticky t) will make ctrl, shift, alt "sticky" in xemacs. (Does anybody know how to do this in emacs?) With sticky-keys, you dont have to hold down the ctrl/shift/alt key and another key simultaneosly. For example, to type ctrl-a, you'd have to tap on the 'ctrl'-key, followed by a tap on the 'a'-key. This feature is useful for folks with sore wrists/hands.

(setq message-log-max 512) will reduce the number of messages that appear in the "*Messages*" window to 512.

(setq display-time-day-and-date t) (display-time) will make the display of date and time persistent.

(require 'paren) (show-paren-mode t) will highlight matching parentheses next to cursor.

(setq-default indent-tabs-mode nil) will introduce spaces instead of tabs by default.

(setq-default truncate-lines t) will trucate lines if they are too long.

(setq-default truncate-partial-width-windows nil) will trucate even when screen is split into multiple windows.

(require 'auto-show) (auto-show-mode 1) (setq-default auto-show-mode t) load auto-show (shows lines when cursor moves to right of long line).

(auto-show-make-point-visible) will position the cursor to end of output in shell mode.

(auto-show-make-point-visible) will position cursor to end of output in shell mode automatically.

(transient-mark-mode t) will highlight region between point and mark.

(setq query-replace-highlight t) will highlight during query.

(setq search-highlight t) highlight incremental search

(setq default-major-mode 'text-mode) will make text-mode default.

(global-font-lock-mode t t) means that we want fontification in all modes.

(setq font-lock-maximum-decoration t) denotes our interest in maximum possible fontification.

(type-break-mode) get intermittent messages to stop typing

 

(setq enable-recursive-minibuffers t) ;; allow recursive editing in minibuffer
(resize-minibuffer-mode 1)            ;; minibuffer gets resized if it becomes too big
(follow-mode t)                       ;; follow-mode allows easier editing of long files 

 

(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse)

 

; Moving cursor down at bottom scrolls only a single line, not half page
(setq scroll-step 1)
(setq scroll-conservatively 5)
(global-set-key [delete] 'delete-char)

 

(set-background-color "dark slate gray")
(set-foreground-color "blanched almond")

C-mode with Fewer Key-strokes


(setq kill-whole-line t) will make "Ctrl-k" kills an entire line if the cursor is at the beginning of line -- very useful.

(setq c-hungry-delete-key t) will delete "hungrily" in C mode! Use it to see what it does -- very useful.

(setq c-auto-newline 1) will let emacs put in a "carriage-return" for you automatically after left curly braces, right curly braces, and semi-colons in "C mode" -- very useful.

 

(add-hook 'c-mode-common-hook
          '(lambda ()
             (turn-on-auto-fill)
             (setq fill-column 80)
             (setq comment-column 60)
             (modify-syntax-entry ?_ "w")       ; now '_' is not considered a word-delimiter
             (c-set-style "ellemtel")           ; set indentation style
             (local-set-key [(control tab)]     ; move to next tempo mark
                            'tempo-forward-mark)
             ))

 

(setq auto-mode-alist
      (append '(("\\.h$" . c++-mode)) auto-mode-alist))

 

(global-set-key [f12]         'dabbrev-expand)
(define-key esc-map [f12]     'dabbrev-completion)

With the above global key-bindings, it is possible to press 'f12' (you could change this to any other key you want) and automagically, a partial string gets expanded. For example, if you have typed "mylon" and press 'F12', "mylon" will get replaced by "MyLongIdentifierName" if that string exists somewhere in your set of buffers.

 

;; "funky stuff" ;; proceed with caution

(setq my-key-pairs
      '((?! ?1) (?@ ?2) (?# ?3) (?$ ?4) (?% ?5)
        (?^ ?6) (?& ?7) (?* ?8) (?( ?9) (?) ?0)
        (?- ?_) (?\" ?') (?{ ?[) (?} ?])         ; (?| ?\\)
        ))
        
(defun my-key-swap (key-pairs)
  (if (eq key-pairs nil)
      (message "Keyboard zapped!! Shift-F10 to restore!")
      (progn
        (keyboard-translate (caar key-pairs)  (cadar key-pairs)) 
        (keyboard-translate (cadar key-pairs) (caar key-pairs))
        (my-key-swap (cdr key-pairs))
        )
    ))

(defun my-key-restore (key-pairs)
  (if (eq key-pairs nil)
      (message "Keyboard restored!! F10 to Zap!")
      (progn
        (keyboard-translate (caar key-pairs)  (caar key-pairs))
        (keyboard-translate (cadar key-pairs) (cadar key-pairs))
        (my-key-restore (cdr key-pairs))
        )
    ))

The above function "swaps" the numeric keys with the respective characters (e.g., '*' with '8' and '(' with '9'). Why? It appears to me that the upper row of characters is used more often in C/C++. So we need fewer key-strokes (the 'Shift' is avoided) with the swappings in place. 'F10' and 'Shift-F10' allow u to toggle between these key-swaps.

 

;; "funky stuff" ;; proceed with caution

(defun my-editing-function (first last len)
  (interactive)
  (if (and (boundp 'major-mode)
           (member major-mode (list 'c-mode 'c++-mode 'gud-mode 'fundamental-mode 'ruby-mode))
           (= len 0)
           (> (point) 4)
           (= first (- (point) 1)))      
      (cond
       ((and (string-equal (buffer-substring (point) (- (point) 2)) "__")
             (not (string-equal (buffer-substring (point) (- (point) 3)) "___")))
        (progn (delete-backward-char 2) (insert-char ?- 1) (insert-char ?> 1)))

       ((string-equal (buffer-substring (point) (- (point) 3)) "->_")
        (progn (delete-backward-char 3) (insert-char ?_ 3)))
       
       ((and (string-equal (buffer-substring (point) (- (point) 2)) "..")
             (not (string-equal (buffer-substring (point) (- (point) 3)) "...")))
        (progn (delete-backward-char 2) (insert-char ?[ 1) (insert-char ?] 1) (backward-char 1))) 

       ((and (> (point-max) (point))
             (string-equal (buffer-substring (+ (point) 1) (- (point) 2)) "[.]"))
        (progn (forward-char 1) (delete-backward-char 3) (insert-char ?. 1) (insert-char ?. 1) ))
       )      
    nil))
       
(add-hook 'after-change-functions 'my-editing-function)

The function above is funky but useful. Having swapped the pairs ('[', '{'), ('-', '_') and (']', '}'), in order to type "->", we need to type four characters ('Shift' followed by '-' followed by 'Shift' followed by '>'). With the above code, all you need to type is two underscores: '__'). Automagically, they are converted into '->'). Similarly, two successive dots '..' are translated into '[]' (for array indexing). I find that these combinations improve my code-typing speed significantly.

shell-mode Improvements


(setq comint-buffer-maximum-size 10240) set maximum-buffer size for shell-mode (useful if some program that you're debugging spews out large amounts of output).

(add-hook 'comint-output-filter-functions 'comint-truncate-buffer) will truncate shell buffer to comint-buffer-maximum-size.

(add-hook 'comint-output-filter-functions 'comint-watch-for-password-prompt) will disalllow passwords to be shown in clear text (this is useful, for example, if you use the shell and then, login/telnet/ftp/scp etc. to other machines).

(add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m) will remove ctrl-m from shell output.

 

(add-hook 'shell-mode-hook
	  '(lambda ()
             (local-set-key [home]        ; move to beginning of line, after prompt  
                            'comint-bol)
	     (local-set-key [up]          ; cycle backward through command history
                            '(lambda () (interactive)
                               (if (comint-after-pmark-p)
                                   (comint-previous-input 1)
                                 (previous-line 1))))
	     (local-set-key [down]        ; cycle forward through command history
                            '(lambda () (interactive)
                               (if (comint-after-pmark-p)
                                   (comint-next-input 1)
                                 (forward-line 1))))
             ))

 

;; shell-toggle.el stuff

(autoload 'shell-toggle "shell-toggle" 
  "Toggles between the *shell* buffer and whatever buffer you are editing." t) 
(autoload 'shell-toggle-cd "shell-toggle" 
  "Pops up a shell-buffer and insert a \"cd \" command." t)
(global-set-key [f4] 'shell-toggle)
(global-set-key [C-f4] 'shell-toggle-cd)

 

;; protbuf.el
(load "protbuf")
(protect-process-buffer-from-kill-mode 1 "shell-first")

;; ssh.el

(load "ssh") will load ssh.el

gud-mode (debugging with gdb)


 

(add-hook 'gud-mode-hook
	  '(lambda ()
             (local-set-key [home]        ; move to beginning of line, after prompt
                            'comint-bol)
	     (local-set-key [up]          ; cycle backward through command history
                            '(lambda () (interactive)
                               (if (comint-after-pmark-p)
                                   (comint-previous-input 1)
                                 (previous-line 1))))
	     (local-set-key [down]        ; cycle forward through command history
                            '(lambda () (interactive)
                               (if (comint-after-pmark-p)
                                   (comint-next-input 1)
                                 (forward-line 1))))
             ))

Global key-bindings (Hot-keys)


 

;; global key bindings
(global-set-key [C-delete]    'kill-word)
(global-set-key [C-backspace] 'backward-kill-word)
(global-set-key [home]        'beginning-of-line)
(global-set-key [end]         'end-of-line)
(global-set-key [C-home]      'beginning-of-buffer)
(global-set-key [C-end]       'end-of-buffer)
(global-set-key [f1]          'find-file)
(global-set-key [f2]          '(lambda () (interactive) (progn (fill-paragraph 1) (save-buffer))))
(global-set-key [f3]          'manual-entry)
(global-set-key [f4]          'shell)
(global-set-key [f5]          '(lambda () (interactive) (kill-buffer (current-buffer))))
(global-set-key [S-f7]        'compile)
(global-set-key [f7]          'next-error)
(global-set-key [C-f7]        'kill-compilation)
(global-set-key [f8]          'other-window)
(global-set-key [S-right]     'other-window)
(global-set-key [S-left]      'other-window)
(global-set-key [f9]          'save-buffer)
(global-set-key [f10]         '(lambda () (interactive) (my-key-swap    my-key-pairs)))
(global-set-key [S-f10]       '(lambda () (interactive) (my-key-restore my-key-pairs)))
(global-set-key [f12]         'dabbrev-expand)
(define-key esc-map [f12]     'dabbrev-completion)
; for my pc @ home
(global-set-key [M-backspace] 'dabbrev-expand)
;; (global-set-key [S-f12]       'my-vm-without-new-frame)
(global-set-key [C-f12]       'save-buffers-kill-emacs)
;; some machines have SunF37 instead of f12
(global-set-key [SunF37]      'dabbrev-expand)
(define-key esc-map [SunF37]  'dabbrev-completion)
;; (global-set-key [S-SunF37]    'my-vm-without-new-frame)
(global-set-key [C-SunF37]    'save-buffers-kill-emacs)
(global-set-key "\C-x\C-b"    'electric-buffer-list)
; Make Emacs use "newline-and-indent" when you hit the Enter key so
; that you don't need to keep using TAB to align yourself when coding.
(global-set-key "\C-m"        'newline-and-indent)
; capitalize current word (for example, C constants)
(global-set-key "\M-u"        '(lambda () (interactive) (backward-word 1) (upcase-word 1)))

 

;; pager.el stuff
(require 'pager)
(global-set-key "\C-v"     'pager-page-down)
(global-set-key [next]     'pager-page-down)
(global-set-key "\ev"      'pager-page-up)
(global-set-key [prior]    'pager-page-up)
(global-set-key '[M-up]    'pager-row-up)
(global-set-key '[M-kp-8]  'pager-row-up)
(global-set-key '[M-down]  'pager-row-down)
(global-set-key '[M-kp-2]  'pager-row-down)

Using Abbreviations and Auto-Capitalization


 

;; Abbreviations

;; M-x edit-abbrevs        allows editing of abbrevs
;; M-x write-abbrev-file   will save abbrevs to file
;; C-x a i l               allows us to define a local abbrev
;; M-x abbrev-mode         turns abbrev-mode on/off

;; set name of abbrev file with .el extension
(setq abbrev-file-name "~/.abbrevs.el")

(setq-default abbrev-mode t)
(setq save-abbrevs t)
;; we want abbrev mode in all modes (does not seem to work)
;; (abbrev-mode 1)
;; quietly read the abbrev file
;; (quietly-read-abbrev-file)
(if (file-exists-p  abbrev-file-name) (quietly-read-abbrev-file abbrev-file-name))

 

; auto-capitalize stuff
(autoload 'auto-capitalize-mode "auto-capitalize"
  "Toggle `auto-capitalize' minor mode in this buffer." t)
(autoload 'turn-on-auto-capitalize-mode "auto-capitalize"
  "Turn on `auto-capitalize' minor mode in this buffer." t)
(autoload 'enable-auto-capitalize-mode "auto-capitalize"
  "Enable `auto-capitalize' minor mode in this buffer." t)
(add-hook 'text-mode-hook 'turn-on-auto-capitalize-mode)
(setq auto-capitalize-words '("I" "Rajeev" "Nautiyal" "Sanjeev" "Uma"))

Latex Improvements


(setq auto-mode-alist (cons '("\\.tex$" . latex-mode) auto-mode-alist)) means that .tex files should be handled by latex-mode.

 

(setq tex-mode-hook
   '(lambda ()
      (auto-fill-mode 1)
      ))

 

(setq latex-mode-hook
   '(lambda ()
      (auto-fill-mode 1)
      ))

 

(autoload 'reftex-mode    "reftex" "RefTeX Minor Mode" t)
(autoload 'turn-on-reftex "reftex" "RefTeX Minor Mode" t)

(add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
;  (add-hook 'latex-mode-hook 'turn-on-reftex)) ; with Emacs latex mode

(setq reftex-enable-partial-scans t)
(setq reftex-save-parse-info t)
(setq reftex-use-multiple-selection-buffers t)

;; To integrate with AUCTeX, use 
(setq reftex-plug-into-AUCTeX t)

text-mode Improvements


 

(add-hook 'text-mode-hook
          '(lambda ()
             (turn-on-auto-fill)
             (auto-fill-mode 1)
             ))

ruby-mode Improvements


 

    (autoload 'ruby-mode "ruby-mode"
      "Mode for editing ruby source files")
    (setq auto-mode-alist
          (append '(("\\.rb$" . ruby-mode)) auto-mode-alist))
    (setq interpreter-mode-alist (append '(("ruby" . ruby-mode))
    				     interpreter-mode-alist))
    (autoload 'run-ruby "inf-ruby"
      "Run an inferior Ruby process")
    (autoload 'inf-ruby-keys "inf-ruby"
      "Set local key defs for inf-ruby in ruby-mode")
    (add-hook 'ruby-mode-hook
          '(lambda ()
             (inf-ruby-keys)
    ))

(autoload 'rubydb "rubydb3x" "Ruby debugger" t)

VM-mode Improvements


 

; ----- VM --------
(autoload 'vm "~/emacs/vm" "Start VM on your primary inbox." t)
(autoload 'vm-visit-folder "~/emacs/vm" "Start VM on an arbitrary folder." t)
(autoload 'vm-mail "~/emacs/vm" "Send a mail message using VM." t)
(autoload 'vm-submit-bug-report "~/emacs/vm" "Send a bug report about VM." t)
(setq vm-preview-lines nil)
(setq vm-highlighted-header-regexp '"^From\\|^Subject")
(setq vm-preview-read-messages t)

Emacs-lisp-mode Improvements


 

(add-hook 'emacs-lisp-mode-hook
          '(lambda ()
             (modify-syntax-entry ?- "w")       ; now '-' is not considered a word-delimiter
             ))

tempo-mode for Faster Coding in C/C++


 

;; This is a way to hook tempo into cc-mode
(defvar c-tempo-tags nil
  "Tempo tags for C mode")
(defvar c++-tempo-tags nil
  "Tempo tags for C++ mode")

;;; C-Mode Templates and C++-Mode Templates (uses C-Mode Templates also)
(require 'tempo)
(setq tempo-interactive t)

(add-hook 'c-mode-hook
          '(lambda ()
             (local-set-key [f11] 'tempo-complete-tag)
             (tempo-use-tag-list 'c-tempo-tags)
             ))
(add-hook 'c++-mode-hook
          '(lambda ()
             (local-set-key [f11] 'tempo-complete-tag)
             (tempo-use-tag-list 'c-tempo-tags)
             (tempo-use-tag-list 'c++-tempo-tags)
             ))

;;; Preprocessor Templates (appended to c-tempo-tags)

(tempo-define-template "c-include"
		       '("include <" r ".h>" > n
			 )
		       "include"
		       "Insert a #include <> statement"
		       'c-tempo-tags)

(tempo-define-template "c-ifdef"
		       '("ifdef " (p "ifdef-clause: " clause) > n> p n
			 "#else /* !(" (s clause) ") */" n> p n
			 "#endif /* " (s clause)" */" n>

			 )
		       "ifdef"
		       "Insert a #ifdef #else #endif statement"
		       'c-tempo-tags)

(tempo-define-template "c-ifndef"
		       '("ifndef " (p "ifndef-clause: " clause) > n
			 "#define " (s clause) n> p n
			 "#endif /* " (s clause)" */" n>
			 )
		       "ifndef"
		       "Insert a #ifndef #define #endif statement"
		       'c-tempo-tags)
;;; C-Mode Templates

(tempo-define-template "c-if"
		       '(> "if (" (p "if-clause: " clause) ")" n>
                           "{" > n>

                           > r n
                           "}" > n>
                           )
		       "if"
		       "Insert a C if statement"
		       'c-tempo-tags)

(tempo-define-template "c-else"
		       '(> "else" n>
                           "{" > n>
                           > r n
                           "}" > n>

                           )
		       "else"
		       "Insert a C else statement"
		       'c-tempo-tags)

(tempo-define-template "c-if-else"
		       '(> "if (" (p "if-clause: " clause) ")"  n>
                           "{" > n
                           > r n
                           "}" > n
                           "else" > n
                           "{" > n>

                           > r n
                           "}" > n>
                           )
		       "ifelse"
		       "Insert a C if else statement"
		       'c-tempo-tags)

(tempo-define-template "c-while"
		       '(> "while (" (p "while-clause: " clause) ")" >  n>
                           "{" > n
                           > r n
                           "}" > n>

                           )
		       "while"
		       "Insert a C while statement"
		       'c-tempo-tags)

(tempo-define-template "c-for"
		       '(> "for (" (p "for-clause: " clause) ")" >  n>
                           "{" > n
                           > r n
                           "}" > n>
                           )
		       "for"
		       "Insert a C for statement"
		       'c-tempo-tags)

(tempo-define-template "c-for-i"
		       '(> "for (" (p "variable: " var) " = 0; " (s var)
                           " < "(p "upper bound: " ub)"; " (s var) "++)" >  n>

                           "{" > n
                           > r n
                           "}" > n>
                           )
		       "fori"
		       "Insert a C for loop: for(x = 0; x < ..; x++)"
		       'c-tempo-tags)

(tempo-define-template "c-main"
		       '(> "int main(int argc, char *argv[])" >  n>

                           "{" > n>
                           > r n
                           > "return 0 ;" n>
                           > "}" > n>

                           )
		       "main"
		       "Insert a C main statement"
		       'c-tempo-tags)

(tempo-define-template "c-if-malloc"
		       '(> (p "variable: " var) " = ("
                           (p "type: " type) " *) malloc (sizeof(" (s type)
                           ") * " (p "nitems: " nitems) ") ;" n>
                           > "if (" (s var) " == NULL)" n>
                           > "error_exit (\"" (buffer-name) ": " r ": Failed to malloc() " (s var) " \") ;" n>
                           )
		       "ifmalloc"
		       "Insert a C if (malloc...) statement"
		       'c-tempo-tags)

(tempo-define-template "c-if-calloc"
		       '(> (p "variable: " var) " = ("
                           (p "type: " type) " *) calloc (sizeof(" (s type)
                           "), " (p "nitems: " nitems) ") ;" n>

                           > "if (" (s var) " == NULL)" n>
                           > "error_exit (\"" (buffer-name) ": " r ": Failed to calloc() " (s var) " \") ;" n>
                           )
		       "ifcalloc"
		       "Insert a C if (calloc...) statement"
		       'c-tempo-tags)

(tempo-define-template "c-switch"
		       '(> "switch (" (p "switch-condition: " clause) ")" n>
                           "{" >  n>

                           "case " (p "first value: ") ":" > n> p n
                           "break;" > n> p n
                           "default:" > n> p n
                           "break;" > n
                           "}" > n>

                           )
		       "switch"
		       "Insert a C switch statement"
		       'c-tempo-tags)

(tempo-define-template "c-case"
		       '(n "case " (p "value: ") ":" > n> p n
			   "break;" > n> p
			   )
		       "case"
		       "Insert a C case statement"
		       'c-tempo-tags)

(tempo-define-template "c++-class"
		       '("class " (p "classname: " class) p > n>
                         " {" > n
                         "public:" > n
                         "" > n
			 "protected:" > n
                         "" > n
			 "private:" > n
                         "" > n
			 "};" > n
			 )
		       "class"
		       "Insert a class skeleton"
		       'c++-tempo-tags)

Startup


(split-window-horizontally)   ;; want two windows at startup 
(other-window 1)              ;; move to other window
(shell)                       ;; start a shell
(rename-buffer "shell-first") ;; rename it
(other-window 1)              ;; move back to first window 
(my-key-swap my-key-pairs)    ;; zap keyboard

The above code will split the Emacs window into two, and start the shell in one of them. The last line invokes (my-key-swap my-key-pairs) which toggles some keys (search for "my-key-swap" on this page to locate its definition).


Last update: 11 Mar 2004 by Gurmeet Singh Manku

Emacs Tips & Tricks

Emacs Tips & Tricks
Power tools for Emacs users

April 2007
Geotechnical Software Services

 

This document is available at http://geosoft.no/development/emacs.html

 


 

Basic Tips & Tricks

 

Emacs initialization

When Emacs is launched, a specific initialization file is read. The initialization file can contain Emacs personal preferences like the functions and key bindings examples in this document. In addition it can contain default state settings for Emacs variables. Some examples are given below.

(setq default-frame-alist (append (list
  '(width  . 81)  ; Width set to 81 characters
  '(height . 40)) ; Height set to 60 lines
  default-frame-alist))

(setq inhibit-startup-message   t)   ; Don't want any startup message
(setq make-backup-files         nil) ; Don't want any backup files
(setq auto-save-list-file-name  nil) ; Don't want any .saves files
(setq auto-save-default         nil) ; Don't want any auto saving

(setq search-highlight           t) ; Highlight search object
(setq query-replace-highlight    t) ; Highlight query object
(setq mouse-sel-retain-highlight t) ; Keep mouse high-lightening

(set-face-background 'region "yellow") ; Set region background color
(set-background-color        "wheat3") ; Set emacs bg color

In the MS-Windows environment the initialization file should be called _EMACS and should be put in the root directory. In UNIX based systems the file should be called .emacs and should be put in the personal home directory.

 

Key bindings

For maximum typing and editing efficiency, as many keyboard keys as possible should be bound directly to Emacs functions. Some are already bound when Emacs is installed, but the great variety of keyboards and operating systems available makes it difficult for the Emacs team to pre bind functions in general.

To bind a function to a key, include a statement of the form

(global-set-key key-name 'function-name)

in the initialization file. key-name is either given as an actual name within brackets like [f1] for the F1 function key, or as "\C-q" or "\M-q" for a Control-key or Escape-key sequence respectively.

Remember that function that are not bound to a specific key or key sequence (actually this includes most functions) can always be accessed by typing

Esc-x function-name

This document gives many examples of possible Emacs key bindings. Since the name of the keys may differ between keyboards and operating systems, the following approach can be used to find the name of a specific key. Enter

Esc-x describe-key

and hit the key (or key combination) in question. This will reveal the name of the key as well as the function it is currently bound to.

 

Complete word

Emacs includes a very useful concept called complete word. Whenever in the minibuffer, it is always possible to hit the space bar to let Emacs try to complete the current input. This can save many key strokes and a lot of time.

For instance when looking for a file one can give one letter of a directory or a file name and, in case it is unique, Emacs will fill in the rest automatically. If it is not unique, Emacs will fill in as much as possible and return the different possible completions to let you choose between them.

 

The Emacs region

Emacs includes a powerful concept called a region. A region is like a marked area in a conventional word processor, but more useful in the way Emacs functions can be applied to it directly, for instance for sorting just a few lines of a file, or for printing a portion of a file.

A region is set implicitly by many Emacs functions, but can be set manually as well using Ctrl-Space. This specifies the current cursor position as one end of the region, called the mark. The cursor can then be moved around and its position will specify the other end of the region.

 

Cut, copy and paste key bindings

Based on the description of a region above, defining the common functions Cut, Copy and Paste on the region becomes very useful. The functions should be bound to keys for easy access, for instance like:

(global-set-key [f5] 'copy-region-as-kill) ; Copy
(global-set-key [f6] 'kill-region)         ; Cut
(global-set-key [f7] 'yank)                ; Paste

An element that is cut or copied this way is put into something called the kill-ring. Calling the yank function always pastes the last entry from the kill-ring. However, after the yank function as called, it is possible to replace the pasted text by the second last entry in the ring and so on by calling the yank-pop (by default boud to the Esc-y key) function repeatedly. In effect, all cut/copy operations of the session is registered, and are easily accessible through this simple sequence of key strokes.

 

Column handling

A feature that are missing in most editors and word processors is the possibility to cut/copy and paste a vertical region of a file. In Emacs this is simple. The column to cut or copy is marked as a region as described above. It can then be cut calling the function kill-rectangle and re-pasted by yank-rectangle

 

Navigation key bindings

These are the basic navigation keys. Many keyboard come with two sets of these keys, so each function is bound once for each key. Some of these functions are usually already bound when Emacs is installed.

(global-set-key [kp-home]  'beginning-of-buffer) ; [Home]
(global-set-key [home]     'beginning-of-buffer) ; [Home]
(global-set-key [kp-end]   'end-of-buffer)       ; [End]
(global-set-key [end]      'end-of-buffer)       ; [End]
(global-set-key [kp-prior] 'my-scroll-down)      ; [PgUp]
(global-set-key [prior]    'my-scroll-down)      ; [PgUp]
(global-set-key [kp-next]  'my-scroll-up)        ; [PgDn]
(global-set-key [next]     'my-scroll-up)        ; [PgDn]

 

Undo

Emacs has the most amazing undo facility. Anything you have typed since your session began is registered and can be undone. Since this obviously is a very useful function it should be bound directly to a key. Using the keypad [-] (subtraction) key for this purpose is convenient since it indicates the nature of the operation as well as being located so far away that it isn't easily accessed by accident.

(global-set-key [kp-subtract] 'undo) ; [Undo]

 

Insert/overwrite mode

By default Emacs run in insert mode. This state can be toggled with overwrite mode, and is best bound to the Insert key(s) on the keyboard.

(global-set-key [insert]    'overwrite-mode) ; [Ins]
(global-set-key [kp-insert] 'overwrite-mode) ; [Ins]

 

Goto line

To go to a specific line can be useful, especially when Emacs is used for programming. This common function can be bound to Ctrl-L by:

(global-set-key "\C-l" 'goto-line) ; [Ctrl]-[L]

 

Window splitting

The Emacs window can be split so that is can display two or more buffers at the same time. This can be useful when comparing two files, or when editing two files simultaneously. Functions for managing window splits:

(global-set-key [f2] 'split-window-vertically)
(global-set-key [f1] 'remove-split)

 

Frames

As well as displaying more than one buffer in a window, Emacs can also display more than one window (or frames as it is called in Emacs terminology). Creating and deleting frames can conveniently be done by binding the the functions as follows:

(global-set-key "\C-f" 'make-frame)   ; [Ctrl]-[F]
(global-set-key "\M-f" 'delete-frame) ; [ESC]-[F]

 

Getting information

Emacs contains lots of features and possibilities and it can be difficult to comprehend and utilize it all. However, Emacs comes with full documentation included. One of the more useful functions is apropos:

[ESC]-x apropos

This command prompts for a name or a concept and will return list of all functions or variables that relates to the entry given. This is a very useful approach for getting to know Emacs and the possibilities it contains.

Given an Emacs function or a variable it can sometimes be difficult to know exactly what it does. An explanation of a function or a variable can be obtained by:

[ESC]-x describe-function
[ESC]-x describe-variable

They will prompt for a name and return a comprehensive description of it.

Similarly, as described above

[ESC]-x describe-key

prompts for a key and returns the name of the key and the function it is currently bound to.

 


 

File Finder

This extension to the powerful Emacs complete-word facility is the major time saver for the frequent Emacs user. It is used within the find-file function and makes it possible to enter a given directory in the minibuffer by just entering a predefined two- to four letter sequence followed by the space key. Three different paths are given in the example below. The list can however be extended indefinetly.

(defun geosoft-parse-minibuffer ()
  ;; Extension to the complete word facility of the minibuffer
  (interactive)
  (backward-char 4)
  (setq found t)
  (cond
     ; local directories
     ((looking-at "..cd") (setq directory "c:/users/john/"))
     ((looking-at ".doc") (setq directory "c:/users/john/documents/"))
     ((looking-at "java") (setq directory "c:/users/john/src/java/"))
     (t (setq found nil)))
  (cond (found (beginning-of-line)
                (kill-line)
                (insert directory))
         (t     (forward-char 4)
                (minibuffer-complete))))

The function is made an extension to the minibuffer complete-word function by:

(define-key minibuffer-local-completion-map " " 'geosoft-parse-minibuffer)

 


 

Buffer Switcher

After a file has been loaded once, it is available in an Emacs buffer. Emacs is installed with lots of clever functions for fast retrieval of buffers. The function below is different however. It makes it possible to browse through the buffer list by single key-strokes only. It is also clever in its handling of the buffer stack in the way that the most frequent visited buffers (i.e. files) always are at the top of the stack.

(defvar LIMIT 1)
(defvar time 0)
(defvar mylist nil)

(defun time-now ()
   (car (cdr (current-time))))

(defun bubble-buffer ()
   (interactive)
   (if (or (> (- (time-now) time) LIMIT) (null mylist))
       (progn (setq mylist (copy-alist (buffer-list)))
          (delq (get-buffer " *Minibuf-0*") mylist)
          (delq (get-buffer " *Minibuf-1*") mylist)))
   (bury-buffer (car mylist))
   (setq mylist (cdr mylist))
   (setq newtop (car mylist))
   (switch-to-buffer (car mylist))
   (setq rest (cdr (copy-alist mylist)))
   (while rest
     (bury-buffer (car rest))
     (setq rest (cdr rest)))
   (setq time (time-now)))

The function is bound to a function key (for instance F4) by:

(global-set-key [f4] 'bubble-buffer)

When you are definitely done with a buffer (i.e. a file) it can be convinient to remove it from the buffer stack. To silently remove the current buffer from the stack (and retrieve the next one on the stack), bind the following function to the Ctrl-Del key.

(defun geosoft-kill-buffer ()
   ;; Kill default buffer without the extra emacs questions
   (interactive)
   (kill-buffer (buffer-name))
   (set-name))

Bind by:

(global-set-key [C-delete] 'geosoft-kill-buffer)
(global-set-key [C-kp-delete] 'geosoft-kill-buffer)

 


 

Navigator

For fast navigation within an Emacs buffer it is necessary to be able to move swiftly between words. The functions below change the default Emacs behavour on this point slightly, to make them a lot more usable.

Note the way that the underscore character is treated. This is convinient behaviour in programming. Other domains may have different requirements, and these functions should be easy to modify in this respect.

(defun geosoft-forward-word ()
   ;; Move one word forward. Leave the pointer at start of word
   ;; instead of emacs default end of word. Treat _ as part of word
   (interactive)
   (forward-char 1)
   (backward-word 1)
   (forward-word 2)
   (backward-word 1)
   (backward-char 1)
   (cond ((looking-at "_") (forward-char 1) (geosoft-forward-word))
         (t (forward-char 1))))

(defun geosoft-backward-word ()
   ;; Move one word backward. Leave the pointer at start of word
   ;; Treat _ as part of word
   (interactive)
   (backward-word 1)
   (backward-char 1)
   (cond ((looking-at "_") (geosoft-backward-word))
         (t (forward-char 1))))

Bind the functions to Ctrl-Left and Ctrl-Right with:

(global-set-key [C-right] 'geosoft-forward-word)
(global-set-key [C-left] 'geosoft-backward-word)

 


 

Scroller

Scrolling without moving the cursor can be achieved by the functions:

(defun scroll-down-keep-cursor ()
   ;; Scroll the text one line down while keeping the cursor
   (interactive)
   (scroll-down 1))

(defun scroll-up-keep-cursor ()
   ;; Scroll the text one line up while keeping the cursor
   (interactive)
   (scroll-up 1))

Bind the functions to the /-key and the *-key (on the numeric keypad) with:

(global-set-key [kp-divide] 'scroll-down-keep-cursor)
(global-set-key [kp-multiply] 'scroll-up-keep-cursor)

 


 

Emacs for Programmers

 

Modes

During editing Emacs can be set in different modes. The mode has some knowledge about the structure of the document the user is working on, and can assist on the organization, formatting and editing of this.

This is particularly helpful when Emacs is used for programming, since programming languages in general has rigid sets of restrictions regarding document structure. For instance, programming statements are normally indented according to specific rules, and if the mode know the rules, it can do the indentation for the user automatically.

There exists modes for all major and minor programming languages and most types of documents such as HTML, Perl scripts, shell scripts, Unix Makefiles, CSS etc. The mode is automatically set by Emacs based on the name or the extension of the file edited.

 

Color coding

A very useful feature is Emacs' ability to render text with different colors and fonts. Emacs packages for color coding analyse the structure of the text and color the text according to the structure. For instance can programming comments get one color, reserved words a different color, function definitions yet another and so on.

A popular color coding package that comes with the standard Emacs distribution is hilite. To use it, include the following statement in the initialization file:

(load "hilit19")

During editing, it is in general impossible for the color coding package to color the text since the structure of the edited part of the document may not yet be complete. Beacuase of this, it is handy to be able to refresh the color coding manually. This is done with the function hilit-highlight-buffer which can be bound to a key combination for convenience.

 

Including predefined element skeletons

Many of the text elements that are used in programming has a standard form based on common skeletons. The ability to include skeletons like these with a single keystroke can be very useful and time efficient.

For instance, declaration and documentation comments in Java follow the rules dictated by the javadoc automatic documentation system. A typical javadoc method comment will look something like this:

/**
 *
 * Returns the character at the specified index. An index
 * ranges from <code>0</code> to <code>length()-1&</code>
 *
 * @param       index of the desired character
 * @return      the desired character
 * @exeption    StringIndexOutOfRangeExeption
 *              if the index is not in the range <code>0</code>
 *              to <code>length()-1&</code>.
 * @see         java.lang.Character#charValue()
 */
public char charAt(int index) {
   ...
}

To create a skeleton that can be included directly into a java source file, include the following LISP function in the Emacs initialization file:

(defun javadoc-method-comment ()
  ;; Insert a javadoc method comment at the cursor position
  (interactive)
  (insert
"/**
 *
 *
 *
 *
 * @param
 * @return
 * @exeption
 * @see
 */
")/
  (previous-line 8)
  (end-of-line))

The function can be bound to a key by for instance:

(define-key java-mode-map [f9] 'javadoc-method-comment)

So hitting F9 will in effect include a javadoc method comment skeleton at the cursor position and move the cursor to the position within the comment where the description should start.

Along the same lines it is easy to predefine a large number of code elements, for instance while loops, if-then-else constructions, file headers etc. and make them available by single key strokes or key combinations.

 


 

Emacs Links