Initiating selection in replacement for Emacs' forward-word

时光毁灭记忆、已成空白 提交于 2019-12-11 04:21:47

问题


I want to replace Emacs' default forward-word and backward-word to operate more like Visual Studio's - which I find better suited to Perl programming. I first tried hacking the syntax table, without achieving the effect I wanted. Then I came up with the following:

(defconst perl-movement-stop-chars "a-zA-Z$@%_0-9'")
(defconst perl-movement-stop-pattern (concat "[" perl-movement-stop-chars "]"))
(defconst non-perl-movement-stop-pattern (concat "[^" perl-movement-stop-chars "]"))

(defun perl-forward-word ()
  (interactive)
  (if (looking-at perl-movement-stop-pattern)
      (progn
        (if (re-search-forward non-perl-movement-stop-pattern nil t)
            (backward-char)))
    (if (re-search-forward perl-movement-stop-pattern nil t)
        (backward-char))))

(defun perl-backward-word ()
  (interactive)
  (backward-char)
  (if (looking-at perl-movement-stop-pattern)
      (progn
        (if (re-search-backward non-perl-movement-stop-pattern nil t)
            (forward-char)))
    (if (re-search-backward perl-movement-stop-pattern nil t)
        (forward-char))))

(add-hook 'cperl-mode-hook
          (lambda()
            (local-set-key [C-right] 'perl-forward-word)
            (local-set-key [C-left] 'perl-backward-word)
            linum-mode))

This does what I want - nearly: I still have to handle the case when moving backward from inside the first word in the buffer. But that is not my question.

The problem with this is that the selection is not started when I type C-S-right, as it is when my hook is not installed (or in other modes). If I initiate the selection though (e.g. by hitting first S-right) my functions do extend it.

I know very, very little about elisp programming and I am just guessing my way here. I would appreciate a bit of help. Thanks...


回答1:


To get shift-select-mode working, you'll need to use (interactive "^"). Try C-h f interactive RET.

BTW, you can simplify your code considerably: to move forward, just (re-search-forward ".\\(\\_<\\|\\_>\\)" nil t) and to move backward, use (re-search-backward "\\(\\_<\\|\\_>\\)." nil t).




回答2:


I'm not sure exactly what you want, but I thought I'd offer this. I have a package which I call syntax-subword (available in Melpa). It makes word movement more fine-grained, to the point where I hardly ever move by characters, and use other solutions like isearch to move bigger distances.

From the comments:

;; This package provides `syntax-subword' minor mode, which extends
;; `subword-mode' to make word editing and motion more fine-grained.
;; Basically, it makes syntax changes, CamelCaseWords, and the normal
;; word boundaries the boundaries for word operations.  Here's an
;; example of where the cursor stops using `forward-word' in
;; `emacs-lisp-mode':
;;
;; (defun FooBar (arg) "doc string"
;; |     |      |    |     |      |  standard
;; |     |   |  |    |     |      |  subword-mode
;; ||    ||  |  |||  ||||  ||     || syntax-subword-mode
;; ||     |      ||  | ||   |     |  vim


来源:https://stackoverflow.com/questions/16034357/initiating-selection-in-replacement-for-emacs-forward-word

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!