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