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 ""))

No comments: