Saturday, November 24, 2007

Friday, November 16, 2007

[Emacs Tips] 注释

M-x comment-dwim (Do What I Mean) 是最聪明的一种注释方式。如果已经选定了区域,那么就是注释或者反注释;如果没有选定区域,那么就是在这行末尾添加注释。

默认的键绑定是 M-;

注释还可以选择不同的模式,不同注释符号,在不同的编程语言模式下都不同。

控制注释符号的是变量 comment-start 和 comment-end,用 C-h v 查看,用例如 (setq comment-start "//") 修改。

变量 comment-style 控制注释的样式。可以用例如 (setq comment-style 'box) 修改。
以下是各种注释风格的示例。

int main()
{
/* this is a comment line. */
/* comment style 'plain */

/* this is a comment line. */
/* comment style 'indent */

/* this is a comment line. */
/* comment style 'aligned */

/* this is a comment line.
* comment style 'multi-line */

/*
* this is a comment line.
* comment style 'extra-line
*/

/***************************/
/* this is a comment line. */
/* comment style 'box */
/***************************/

/****************************
* this is a comment line. *
* comment style 'box-multi *
****************************/
}
再提供一个直接注释一行的函数。有时候比 comment-dwim 更有效。有选中区域的话就是注释或反注释这个区域;反之注释或者反注释光标所在的行。
(defun huangq-comment-dwim (&optional n)
"Comment do-what-i-mean"
(interactive "p")
(apply 'comment-or-uncomment-region
(if (and mark-active transient-mark-mode)
(list (region-beginning) (region-end))
(if (> n 0)
(list (line-beginning-position) (line-end-position n))
(list (line-beginning-position n) (line-end-position))))))

[Emacs Tips] 插入相邻一行的字符

类似于 VIM 插入状态下的 C-y 和 C-e,也就是插入光标所在上一行或者下一行的字符。
例如: VIM 插入状态下的 C-y 和 C-e,也就是插入光标所在上一行或者下一行的字符。

写程序的时候还是挺有用的
;;;###autoload
(defun my-insert-char-next-line (arg)
"insert char below the cursor"
(interactive "p")
(let ((col (current-column))
char)
(setq char
(save-excursion
(forward-line arg)
(move-to-column col)
(if (= (current-column) col)
(char-after))))
(if char
(insert-char char 1)
(message (concat "Can't get charactor in "
(if (< arg 0)
"previous"
"next")
(progn (setq arg (abs arg))
(if (= arg 1) ""
(concat " " (number-to-string arg))))
" line.")))))

;;;###autoload
(defun my-insert-char-prev-line (arg)
"insert char above the cursor"
(interactive "p")
(my-insert-char-next-line (- arg)))
用的键绑定是 C-x (C-x )
(global-set-key (kbd "C-)") 'my-insert-char-next-line)
(global-set-key (kbd "C-(") 'my-insert-char-prev-line)

Wednesday, November 14, 2007

[Emacs Tips] isearch 查找 (2)

注:有些函数非原创,因为年代长久,很难找到出处,就不一一注明了。

一些加快查找速度的函数。

1. 查找选定区域的内容。Emacs 有无数用来选定 (mark) 的函数,所以选定容易,但是没有直接查找选定内容的函数。下面这个函数提供此功能,按 F3 就是 isearch 当前选定的词,继续按 C-s 就可以查找了。

(defvar my-isearch-string nil)
(setq my-isearch-string "")

(defun my-isearch-region-forward ()
"isearch region if mark is acktive"
(interactive)
(if mark-active
(let ((beg (region-beginning))
(end (region-end)))
(setq my-isearch-string (filter-buffer-substring beg end nil))
(deactivate-mark)
(if (> (length my-isearch-string) 0)
(progn
(goto-char beg)
(isearch-update-ring my-isearch-string)
(add-hook 'isearch-mode-end-hook 'my-isearch-end-hook)
(isearch-mode t) ;hack isearch-forward
(isearch-repeat 'forward)
(message "%s" isearch-string)))) ;print debug msg
(if (> (length my-isearch-string) 0)
(progn
(isearch-repeat 'forward))
(message "no region selected")
)))

(global-set-key (kbd "<f3>") 'my-isearch-region-forward)

(defun my-isearch-end-hook ()
(remove-hook 'isearch-mode-end-hook 'my-isearch-end-hook)
(setq my-isearch-string ""))


2. 查找当前词,类似于 VIM 的 *,这里用的键绑定是 C-* .

(defvar my-isearch-word "")

(defun my-isearch-word ()
  (interactive)
  (when (not mark-active)
    (let (word-beg word-end)
      (unless (looking-at "\\<")
        (if (eq (char-syntax (char-after)) ?w)
            (backward-word)
          (and (forward-word) (backward-word)))
        )
      (setq word-beg (point))
      (forward-word)
      (setq word-end (point))
      (setq my-isearch-word (filter-buffer-substring word-beg word-end nil t))
      (backward-word)
      )
    (when (> (length my-isearch-word) 0)
      (setq my-isearch-word (concat "\\<" my-isearch-word "\\>"))
      (isearch-update-ring my-isearch-word t)
      (add-hook 'isearch-mode-end-hook 'my-isearch-word-end-hook)
      (isearch-mode t t)
      (isearch-repeat 'forward)
      (message "%s" isearch-string))))

(global-set-key (kbd "C-*") 'my-isearch-word)

(defun my-isearch-word-end-hook ()
  (remove-hook 'isearch-mode-end-hook 'my-isearch-word-end-hook)
  (setq my-isearch-word ""))

Tuesday, November 13, 2007

[Emacs Tips] isearch 查找 (1)

isearch (C-s) 是 Emacs 里最常用的查找方式,也是目前为止我在各种软件里,编辑器里用过最舒服的查找方式。

首先这是 incremental search,也就是递增方式的搜索,一边输入一边就开始查找了;
其次有 lazy highlight 功能,低亮显示 buffer 里所有找到的词。
这个功能是由 isearch-lazy-highlight 这个变量控制的,用 C-h v isearch-lazy-highlight 查看这个变量目前是不是真 t。



isearch-mode 也有很多键绑定,用 C-h f isearch-mode 查看。
具体就不详细写了。最常用的 C-w ,查找当前的词。(明天再给出一个更快更方便的查找方式)

建议可以试试相关的 Elisp 插件 color-moccor.el
用了这个以后可以在 isearch 里敲 M-o,列出文件里的搜索结果; 或者 M-O (大写o) 列出所有 buffer 里的对应结果。

[Emacs Tips] 复制一行

从今天开始打算每天用中文介绍一个 Emacs 小技巧。都是很小的技巧而已。

首先是快速复制一行。基本思想是,光标在哪一行就复制哪一行,不用选定区域。如果区域已经选定了,那么就复制区域。类似于 VIM 的yy。

仍旧使用 M-w 的键绑定,和原先的习惯差不多。使用前提是启用了 transient-mark-mode,即高亮选定区域。实际使用中发现每行开头的空格一点用都没有,而且很碍事,所以今天改了一下,一般从第一个非空格的字符开始复制。

这里提供几个函数。
huangq-save-one-line 是复制一行;如果有参数,则从第一个不是空格的字符开始复制。
huangq-kill-ring-save 如果选定了区域,则复制区域;否则复制行。
huangq-save-line-dwim 如果选定了区域,复制区域;否则从第一个不是空格的字符开始复制。

最后是键绑定:
(global-set-key (kbd "M-w") 'huangq-save-line-dwim)

函数的实现:
;;;###autoload
(defun huangq-save-one-line (&optional arg)
"save one line. If ARG, save one line from first non-white."
(interactive "P")
(save-excursion
(if arg
(progn
(back-to-indentation)
(kill-ring-save (point) (line-end-position)))
(kill-ring-save (line-beginning-position) (line-end-position)))))

;;;###autoload
(defun huangq-kill-ring-save (&optional n)
"If region is active, copy region. Otherwise, copy line."
(interactive "p")
(if (and mark-active transient-mark-mode)
(kill-ring-save (region-beginning) (region-end))
(if (> n 0)
(kill-ring-save (line-beginning-position) (line-end-position n))
(kill-ring-save (line-beginning-position n) (line-end-position)))))

;;;###autoload
(defun huangq-save-line-dwim (&optional arg)
"If region is active, copy region.
If ARG is nil, copy line from first non-white.
If ARG is numeric, copy ARG lines.
If ARG is non-numeric, copy line from beginning of the current line."
(interactive "P")
(if (and mark-active transient-mark-mode)
;; mark-active, save region
(kill-ring-save (region-beginning) (region-end))
(if arg
(if (numberp arg)
;; numeric arg, save ARG lines
(huangq-kill-ring-save arg)
;; other ARG, save current line
(huangq-save-one-line))
;; no ARG, save current line from first non-white
(huangq-save-one-line t))))

Friday, November 02, 2007

flymake mode

How can I miss this wonderful feature until now?

Flymake is amazing. See the screenshot:


What you need is only a Makefile with an extra target "check-syntax":
check-syntax:
    gcc -o nul -Wall -Wextra -fsyntax-only $(CHK_SOURCES)

And of course type "M-x flymake-mode" when needed.

You can also customize the error and warning face in .emacs like:
(require 'flymake nil t)
(when (featurep 'flymake)
(set-face-background 'flymake-errline "LightPink")
(set-face-foreground 'flymake-errline "DarkRed")
(set-face-bold-p 'flymake-errline t)
(set-face-background 'flymake-warnline "LightBlue2")
(set-face-foreground 'flymake-warnline "DarkBlue")
(set-face-bold-p 'flymake-warnline t))

Search word at point in Emacs

查找光标上的单词

The default i-search command in Emacs is C-s, and then type the word you want to search. If your cursor is current on the beginning of the word, then you can type C-s C-w. This is case insensitive.

If you want to look for the exact word, then you can use the following code. Type C-* and search the word at the point. It works just like the Star * in VIM.

(defvar my-isearch-word "")

(defun my-isearch-word ()
(interactive)
(when (not mark-active)
(let (word-beg word-end)
(unless (looking-at "\\<")
(if (eq (char-syntax (char-after)) ?w)
(backward-word)
(and (forward-word) (backward-word)))
)
(setq word-beg (point))
(forward-word)
(setq word-end (point))
(setq my-isearch-word (filter-buffer-substring word-beg word-end nil t))
(backward-word)
)
(when (> (length my-isearch-word) 0)
(setq my-isearch-word (concat "\\<" my-isearch-word "\\>"))
(isearch-update-ring my-isearch-word t)
(add-hook 'isearch-mode-end-hook 'my-isearch-word-end-hook)
(isearch-mode t t)
(isearch-repeat 'forward)
(message "%s" isearch-string))))

(global-set-key (kbd "C-*") 'my-isearch-word)

Monday, September 10, 2007

It's All Text! - A wonderful Firefox extension

It's All Text! is a Firefox extension. With this extension you can edit the text area in a webpage using external editors, e.g. Emacs, VIM, Notepad ... etc.

After installed this extension, restarted Firefox, there will be a small "edit" button at the right bottom corner of a text edit area. For example, Gmail compose message, blogger input box, or comment area. Assign an external editor in the preference of It's All Text!, click this "edit" button or right click on the text area and select It's All Text!, you will be switched to the editor. Type anything and save the file, the text will be copied back to the text edit area in the webpage.

This is a really amazing feature I was looking for since long ago. Under Windows I use a bat file to start emacsclient:

d:\Emacs\bin\emacsclientw.exe -f "PATHTO\.emacs.d\server\server" -a "d:\Emacs\bin\runemacs.exe" -n %1

Select this bat file as the editor for It's All Text!

Of course you need to start server in Emacs first. Add this line into your .emacs file:

(server-start)


Have fun!

Maybe later we can post blog using emacs-muse with this Firefox extension more conveniently. We'll see.

Saturday, August 18, 2007

URLs for Google Maps

It's really convenient to use Google Maps to find specific locations and route. But it's very slow to load the home page of Google Maps every time. However, like Google, it is possible to type the link address directly to find a location in Google Maps. For example, to find Marienplatz 1, you can use the following URL directly:
http://maps.google.de/maps?hl=en&q=Marienplatz%201%2C%20Munich

It is quite neat to use this feature combined with Firefox Bookmark Keyword. You can save http://maps.google.de/maps?hl=en&q=%s as Firefox Bookmark, and name the Keyword of this bookmark as gmap. The next time, you can directly type "gmap Marienplatz 1 Munich" in the Firefox address bar to find this location in Google Maps. Even more, you can type "gmap from Marienplatz 1 Munich to Olympiapark Munich" to find the route.

And here are the other parameters of the URL:

lat and lon: q=48.1374740601+11.5754375458
Comment for info window: (City Hall Munich)
Zoom Level: &z=18
language of map (en=english, fr=french, de=germany): &hl=en
map type (0=street map, k=satellite, h=hybrid): &t=k

The complete URL example:
http://maps.google.de/maps?hl=en&amp;amp;q=48.1374740601+11.5754375458+(City Hall Munich)&t=k&z=18


All Google Maps Parameters:
http://mapki.com/index.php?title=Google_Map_Parameters