* [PATCH 1/2] Merge subword-mode and capitalized-words-mode
@ 2011-12-30 2:03 Daniel Colascione
2011-12-30 2:03 ` [PATCH 2/2] For better visibility, add subword-mode to options menu Daniel Colascione
2011-12-30 11:23 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Stefan Monnier
0 siblings, 2 replies; 10+ messages in thread
From: Daniel Colascione @ 2011-12-30 2:03 UTC (permalink / raw)
To: emacs-devel
subword-mode began life as part of cc-mode, but because it's
generally useful, it was extracted and made a generic part of
Emacs. subword-mode uses command remapping to achive its subword
motion, however, and this mechanism can't catch all kinds of word-
based motion, resulting in inconsistency.
capitalized-words-mode attempts to do what subword-mode does, but
using a hook added to C core for the purpose. This hook allows
capitalizd-words-mode to change all kinds of word-based motion
into subword motion. Unfortunately, capitalized-words-mode used
overly simplistic code that caused it to fail to properly move
over words like "fooBarBAZ"; subword-mode handles these words
properly. capitalized-words-mode is also disadvantaged by
a long and misleading name.
This patch merges subword-mode and capitalized-words-mode by
modifying subword-mode to use the core hook and marking
capitalized-words-mode as an obsolete alias for subword-mode.
This patch also includes an automated test for subword motion.
---
lisp/progmodes/cap-words.el | 98 ---------------------------------
lisp/progmodes/subword.el | 128 +++++++++++++++++++++++--------------------
test/automated/subword.el | 58 +++++++++++++++++++
3 files changed, 126 insertions(+), 158 deletions(-)
delete mode 100644 lisp/progmodes/cap-words.el
create mode 100644 test/automated/subword.el
diff --git a/lisp/progmodes/cap-words.el b/lisp/progmodes/cap-words.el
deleted file mode 100644
index d7b7dfe..0000000
--- a/lisp/progmodes/cap-words.el
+++ /dev/null
@@ -1,98 +0,0 @@
-;;; cap-words.el --- minor mode for motion in CapitalizedWordIdentifiers
-
-;; Copyright (C) 2002-2011 Free Software Foundation, Inc.
-
-;; Author: Dave Love <fx@gnu.org>
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Provides Capitalized Words minor mode for word movement in
-;; identifiers CapitalizedLikeThis.
-
-;; Note that the same effect could be obtained by frobbing the
-;; category of upper case characters to produce word boundaries, but
-;; the necessary processing isn't done for ASCII characters.
-
-;; Fixme: This doesn't work properly for mouse double clicks.
-
-;;; Code:
-
-(defun capitalized-find-word-boundary (pos limit)
- "Function for use in `find-word-boundary-function-table'.
-Looks for word boundaries before capitals."
- (save-excursion
- (goto-char pos)
- (let (case-fold-search)
- (if (<= pos limit)
- ;; Fixme: Are these regexps the best?
- (or (and (re-search-forward "\\=.\\w*[[:upper:]]"
- limit t)
- (progn (backward-char)
- t))
- (re-search-forward "\\>" limit t))
- (or (re-search-backward "[[:upper:]]\\w*\\=" limit t)
- (re-search-backward "\\<" limit t))))
- (point)))
-
-
-(defconst capitalized-find-word-boundary-function-table
- (let ((tab (make-char-table nil)))
- (set-char-table-range tab t #'capitalized-find-word-boundary)
- tab)
- "Assigned to `find-word-boundary-function-table' in Capitalized Words mode.")
-
-;;;###autoload
-(define-minor-mode capitalized-words-mode
- "Toggle Capitalized Words mode.
-With a prefix argument ARG, enable Capitalized Words mode if ARG
-is positive, and disable it otherwise. If called from Lisp,
-enable the mode if ARG is omitted or nil.
-
-Capitalized Words mode is a buffer-local minor mode. When
-enabled, a word boundary occurs immediately before an uppercase
-letter in a symbol. This is in addition to all the normal
-boundaries given by the syntax and category tables. There is no
-restriction to ASCII.
-
-E.g. the beginning of words in the following identifier are as marked:
-
- capitalizedWorDD
- ^ ^ ^^
-
-Note that these word boundaries only apply for word motion and
-marking commands such as \\[forward-word]. This mode does not affect word
-boundaries found by regexp matching (`\\>', `\\w' &c).
-
-This style of identifiers is common in environments like Java ones,
-where underscores aren't trendy enough. Capitalization rules are
-sometimes part of the language, e.g. Haskell, which may thus encourage
-such a style. It is appropriate to add `capitalized-words-mode' to
-the mode hook for programming language modes in which you encounter
-variables like this, e.g. `java-mode-hook'. It's unlikely to cause
-trouble if such identifiers aren't used.
-
-See also `glasses-mode' and `studlify-word'.
-Obsoletes `c-forward-into-nomenclature'."
- nil " Caps" nil :group 'programming
- (set (make-local-variable 'find-word-boundary-function-table)
- capitalized-find-word-boundary-function-table))
-
-(provide 'cap-words)
-
-;;; cap-words.el ends here
diff --git a/lisp/progmodes/subword.el b/lisp/progmodes/subword.el
index 9c61da8..817b305 100644
--- a/lisp/progmodes/subword.el
+++ b/lisp/progmodes/subword.el
@@ -1,4 +1,4 @@
-;;; subword.el --- Handling capitalized subwords in a nomenclature
+;;; subword.el --- Handling capitalized subwords in a nomenclature -*- lexical-binding: t -*-
;; Copyright (C) 2004-2011 Free Software Foundation, Inc.
@@ -25,8 +25,11 @@
;; useful in general and not tied to C and c-mode at all.
;; This package provides `subword' oriented commands and a minor mode
-;; (`subword-mode') that substitutes the common word handling
-;; functions with them.
+;; (`subword-mode') that changes the definition of a "word" so that
+;; Emacs will see subword bounaries as word boundaries in normal
+;; movement commands. Previously, `subword-mode' substituted the
+;; normal word-movement commands with the subword-oriented versions at
+;; the keymap level.
;; In spite of GNU Coding Standards, it is popular to name a symbol by
;; mixing uppercase and lowercase letters, e.g. "GtkWidget",
@@ -45,25 +48,6 @@
;; subwords in a nomenclature to move between them and to edit them as
;; words.
-;; In the minor mode, all common key bindings for word oriented
-;; commands are overridden by the subword oriented commands:
-
-;; Key Word oriented command Subword oriented command
-;; ============================================================
-;; M-f `forward-word' `subword-forward'
-;; M-b `backward-word' `subword-backward'
-;; M-@ `mark-word' `subword-mark'
-;; M-d `kill-word' `subword-kill'
-;; M-DEL `backward-kill-word' `subword-backward-kill'
-;; M-t `transpose-words' `subword-transpose'
-;; M-c `capitalize-word' `subword-capitalize'
-;; M-u `upcase-word' `subword-upcase'
-;; M-l `downcase-word' `subword-downcase'
-;;
-;; Note: If you have changed the key bindings for the word oriented
-;; commands in your .emacs or a similar place, the keys you've changed
-;; to are also used for the corresponding subword oriented commands.
-
;; To make the mode turn on automatically, put the following code in
;; your .emacs:
;;
@@ -76,22 +60,29 @@
;; the old `c-forward-into-nomenclature' originally contributed by
;; Terry_Glanfield dot Southern at rxuk dot xerox dot com.
-;; TODO: ispell-word.
-
;;; Code:
(defvar subword-mode-map
- (let ((map (make-sparse-keymap)))
- (dolist (cmd '(forward-word backward-word mark-word kill-word
- backward-kill-word transpose-words
- capitalize-word upcase-word downcase-word))
- (let ((othercmd (let ((name (symbol-name cmd)))
- (string-match "\\([[:alpha:]-]+\\)-word[s]?" name)
- (intern (concat "subword-" (match-string 1 name))))))
- (define-key map (vector 'remap cmd) othercmd)))
- map)
+ ;; Leave an empty keymap present so user customization that modify
+ ;; it keep working.
+ (make-sparse-keymap)
"Keymap used in `subword-mode' minor mode.")
+(defconst subword-find-word-boundary-function-table
+ (let ((tab (make-char-table nil)))
+ (set-char-table-range tab t #'subword-find-word-boundary)
+ tab)
+ "Assigned to `find-word-boundary-function-table' in `subword-mode'.")
+
+(defconst subword-empty-char-table
+ (make-char-table nil)
+ "Assigned to `find-word-boundary-function-table' while we're searching
+subwords in order to avoid unwanted reentrancy.")
+
+;;;###autoload
+(define-obsolete-function-alias
+ 'capitalized-words-mode 'subword-mode "24.1")
+
;;;###autoload
(define-minor-mode subword-mode
"Toggle subword movement and editing (Subword mode).
@@ -99,8 +90,8 @@ With a prefix argument ARG, enable Subword mode if ARG is
positive, and disable it otherwise. If called from Lisp, enable
the mode if ARG is omitted or nil.
-Subword mode is a buffer-local minor mode. Enabling it remaps
-word-based editing commands to subword-based commands that handle
+Subword mode is a buffer-local minor mode. Enabling it changes
+the definition of a word so that word-based commands stop inside
symbols with mixed uppercase and lowercase letters,
e.g. \"GtkWidget\", \"EmacsFrameClass\", \"NSGraphicsContext\".
@@ -114,14 +105,19 @@ called a `subword'. Here are some examples:
EmacsFrameClass => \"Emacs\", \"Frame\" and \"Class\"
NSGraphicsContext => \"NS\", \"Graphics\" and \"Context\"
-The subword oriented commands activated in this minor mode recognize
-subwords in a nomenclature to move between subwords and to edit them
-as words.
+When this mode is enabled, word-oriented commands recognize
+subwords in a nomenclature to move between subwords and treat
+them as words.
\\{subword-mode-map}"
nil
nil
- subword-mode-map)
+ subword-mode-map
+
+ (set (make-local-variable 'find-word-boundary-function-table)
+ (if subword-mode
+ subword-find-word-boundary-function-table
+ subword-empty-char-table)))
(define-obsolete-function-alias 'c-subword-mode 'subword-mode "23.2")
@@ -248,38 +244,50 @@ Optional argument ARG is the same as for `capitalize-word'."
(defun subword-forward-internal ()
(if (and
(save-excursion
- (let ((case-fold-search nil))
- (re-search-forward
- (concat "\\W*\\(\\([[:upper:]]*\\W?\\)[[:lower:][:digit:]]*\\)")
- nil t)))
+ (let ((case-fold-search nil))
+ (re-search-forward
+ (concat "\\W*\\(\\([[:upper:]]*\\W?\\)[[:lower:][:digit:]]*\\)")
+ nil t)))
(> (match-end 0) (point)))
(goto-char
(cond
- ((< 1 (- (match-end 2) (match-beginning 2)))
- (1- (match-end 2)))
- (t
- (match-end 0))))
+ ((< 1 (- (match-end 2) (match-beginning 2)))
+ (1- (match-end 2)))
+ (t
+ (match-end 0))))
(forward-word 1)))
-
(defun subword-backward-internal ()
(if (save-excursion
- (let ((case-fold-search nil))
- (re-search-backward
- (concat
- "\\(\\(\\W\\|[[:lower:][:digit:]]\\)\\([[:upper:]]+\\W*\\)"
- "\\|\\W\\w+\\)")
- nil t)))
+ (let ((case-fold-search nil))
+ (re-search-backward
+ (concat
+ "\\(\\(\\W\\|[[:lower:][:digit:]]\\)\\([[:upper:]]+\\W*\\)"
+ "\\|\\W\\w+\\)")
+ nil t)))
(goto-char
(cond
- ((and (match-end 3)
- (< 1 (- (match-end 3) (match-beginning 3)))
- (not (eq (point) (match-end 3))))
- (1- (match-end 3)))
- (t
- (1+ (match-beginning 0)))))
+ ((and (match-end 3)
+ (< 1 (- (match-end 3) (match-beginning 3)))
+ (not (eq (point) (match-end 3))))
+ (1- (match-end 3)))
+ (t
+ (1+ (match-beginning 0)))))
(backward-word 1)))
+(defun subword-find-word-boundary (pos limit)
+ (let ((find-word-boundary-function-table subword-empty-char-table))
+ (save-match-data
+ (save-excursion
+ (save-restriction
+ (if (< pos limit)
+ (progn
+ (narrow-to-region (point-min) limit)
+ (subword-forward-internal))
+ (narrow-to-region limit (point-max))
+ (subword-backward-internal))
+ (point))))))
+
\f
(provide 'subword)
diff --git a/test/automated/subword.el b/test/automated/subword.el
new file mode 100644
index 0000000..9e769cf
--- /dev/null
+++ b/test/automated/subword.el
@@ -0,0 +1,58 @@
+;;; vc-bzr.el --- tests for progmodes/subword.el
+
+;; Copyright (C) 2011 Free Software Foundation, Inc.
+
+;; Author: Daniel Colascione <dancol@dancol.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'subword)
+
+(ert-deftest subword-test-forward ()
+ "Test that motion in subword-mode stops at the right places."
+
+ (let* ((line "fooBarBAZ quXD g_TESTThingAbc word BLAH test")
+ (fwrd "* * * * * * * * * * * * *")
+ (bkwd "* * * * * * * * * * * * *"))
+
+ (with-temp-buffer
+ (subword-mode 1)
+ (insert line)
+
+ ;; Test forward motion.
+
+ (goto-char (point-min))
+ (let ((stops (make-string (length fwrd) ?\ )))
+ (while (progn
+ (aset stops (1- (point)) ?\*)
+ (not (eobp)))
+ (forward-word))
+ (should (equal stops fwrd)))
+
+ ;; Test backward motion.
+
+ (goto-char (point-max))
+ (let ((stops (make-string (length bkwd) ?\ )))
+ (while (progn
+ (aset stops (1- (point)) ?\*)
+ (not (bobp)))
+ (backward-word))
+ (should (equal stops bkwd))))))
--
1.7.5.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] For better visibility, add subword-mode to options menu
2011-12-30 2:03 [PATCH 1/2] Merge subword-mode and capitalized-words-mode Daniel Colascione
@ 2011-12-30 2:03 ` Daniel Colascione
2011-12-30 11:23 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Stefan Monnier
1 sibling, 0 replies; 10+ messages in thread
From: Daniel Colascione @ 2011-12-30 2:03 UTC (permalink / raw)
To: emacs-devel
---
| 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
--git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 9c020ff..e0bd1b9 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -34,6 +34,8 @@
;; From emulation/cua-base.el; used below
(defvar cua-enable-cua-keys)
+;; From progmodes/subword.el; used below
+(defvar global-subword-mode)
;; Don't clobber an existing menu-bar keymap, to preserve any menu-bar key
;; definitions made in loaddefs.el.
@@ -1295,6 +1297,12 @@ mail status in mode line"))
(:visible (and (boundp 'cua-enable-cua-keys)
(not cua-enable-cua-keys)))))
+ (define-key menu [subword-mode]
+ (menu-bar-make-mm-toggle
+ global-subword-mode
+ "Treat WordsWithCaps as separate words"
+ "Treat each capitalized part of a word as a separate word"))
+
(define-key menu [case-fold-search]
(menu-bar-make-toggle
toggle-case-fold-search case-fold-search
--
1.7.5.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2011-12-30 2:03 [PATCH 1/2] Merge subword-mode and capitalized-words-mode Daniel Colascione
2011-12-30 2:03 ` [PATCH 2/2] For better visibility, add subword-mode to options menu Daniel Colascione
@ 2011-12-30 11:23 ` Stefan Monnier
2012-01-04 15:54 ` Masatake YAMATO
1 sibling, 1 reply; 10+ messages in thread
From: Stefan Monnier @ 2011-12-30 11:23 UTC (permalink / raw)
To: Daniel Colascione; +Cc: emacs-devel
> +;;;###autoload
> +(define-obsolete-function-alias
> + 'capitalized-words-mode 'subword-mode "24.1")
Since 24.1 is already in feature freeze, these patches can't make it for
24.1. You could install your patches on the `pending' branch, but
better would be to wait for the trunk to be re-opened for non-bugfix
commits (hopefully within a couple months).
Stefan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2011-12-30 11:23 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Stefan Monnier
@ 2012-01-04 15:54 ` Masatake YAMATO
0 siblings, 0 replies; 10+ messages in thread
From: Masatake YAMATO @ 2012-01-04 15:54 UTC (permalink / raw)
To: monnier; +Cc: dancol, emacs-devel
>> +;;;###autoload
>> +(define-obsolete-function-alias
>> + 'capitalized-words-mode 'subword-mode "24.1")
>
> Since 24.1 is already in feature freeze, these patches can't make it for
> 24.1. You could install your patches on the `pending' branch, but
> better would be to wait for the trunk to be re-opened for non-bugfix
> commits (hopefully within a couple months).
Putting it to the bug tracker is another option, isn't it?
Masatake
>
> Stefan
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2012-08-07 17:03 [PATCH 0/2] Merge subword-mode and capitalized-words-mode; add to UI Daniel Colascione
@ 2012-08-07 17:03 ` Daniel Colascione
2012-08-07 18:33 ` Masatake YAMATO
2012-08-07 20:37 ` Stefan Monnier
0 siblings, 2 replies; 10+ messages in thread
From: Daniel Colascione @ 2012-08-07 17:03 UTC (permalink / raw)
To: emacs-devel
subword-mode began life as part of cc-mode, but because it's
generally useful, it was extracted and made a generic part of
Emacs. subword-mode uses command remapping to achive its subword
motion, however, and this mechanism can't catch all kinds of word-
based motion, resulting in inconsistency.
capitalized-words-mode attempts to do what subword-mode does, but
using a hook added to C core for the purpose. This hook allows
capitalizd-words-mode to change all kinds of word-based motion
into subword motion. Unfortunately, capitalized-words-mode used
overly simplistic code that caused it to fail to properly move
over words like "fooBarBAZ"; subword-mode handles these words
properly. capitalized-words-mode is also disadvantaged by
a long and misleading name.
This patch merges subword-mode and capitalized-words-mode by
modifying subword-mode to use the core hook and marking
capitalized-words-mode as an obsolete alias for subword-mode.
This patch also includes an automated test for subword motion.
---
lisp/progmodes/cap-words.el | 98 -------------------------------------------
lisp/progmodes/subword.el | 88 +++++++++++++++++++++-----------------
test/automated/subword.el | 58 +++++++++++++++++++++++++
3 files changed, 106 insertions(+), 138 deletions(-)
delete mode 100644 lisp/progmodes/cap-words.el
create mode 100644 test/automated/subword.el
diff --git a/lisp/progmodes/cap-words.el b/lisp/progmodes/cap-words.el
deleted file mode 100644
index 6d4d9f0..0000000
--- a/lisp/progmodes/cap-words.el
+++ /dev/null
@@ -1,98 +0,0 @@
-;;; cap-words.el --- minor mode for motion in CapitalizedWordIdentifiers
-
-;; Copyright (C) 2002-2012 Free Software Foundation, Inc.
-
-;; Author: Dave Love <fx@gnu.org>
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Provides Capitalized Words minor mode for word movement in
-;; identifiers CapitalizedLikeThis.
-
-;; Note that the same effect could be obtained by frobbing the
-;; category of upper case characters to produce word boundaries, but
-;; the necessary processing isn't done for ASCII characters.
-
-;; Fixme: This doesn't work properly for mouse double clicks.
-
-;;; Code:
-
-(defun capitalized-find-word-boundary (pos limit)
- "Function for use in `find-word-boundary-function-table'.
-Looks for word boundaries before capitals."
- (save-excursion
- (goto-char pos)
- (let (case-fold-search)
- (if (<= pos limit)
- ;; Fixme: Are these regexps the best?
- (or (and (re-search-forward "\\=.\\w*[[:upper:]]"
- limit t)
- (progn (backward-char)
- t))
- (re-search-forward "\\>" limit t))
- (or (re-search-backward "[[:upper:]]\\w*\\=" limit t)
- (re-search-backward "\\<" limit t))))
- (point)))
-
-
-(defconst capitalized-find-word-boundary-function-table
- (let ((tab (make-char-table nil)))
- (set-char-table-range tab t #'capitalized-find-word-boundary)
- tab)
- "Assigned to `find-word-boundary-function-table' in Capitalized Words mode.")
-
-;;;###autoload
-(define-minor-mode capitalized-words-mode
- "Toggle Capitalized Words mode.
-With a prefix argument ARG, enable Capitalized Words mode if ARG
-is positive, and disable it otherwise. If called from Lisp,
-enable the mode if ARG is omitted or nil.
-
-Capitalized Words mode is a buffer-local minor mode. When
-enabled, a word boundary occurs immediately before an uppercase
-letter in a symbol. This is in addition to all the normal
-boundaries given by the syntax and category tables. There is no
-restriction to ASCII.
-
-E.g. the beginning of words in the following identifier are as marked:
-
- capitalizedWorDD
- ^ ^ ^^
-
-Note that these word boundaries only apply for word motion and
-marking commands such as \\[forward-word]. This mode does not affect word
-boundaries found by regexp matching (`\\>', `\\w' &c).
-
-This style of identifiers is common in environments like Java ones,
-where underscores aren't trendy enough. Capitalization rules are
-sometimes part of the language, e.g. Haskell, which may thus encourage
-such a style. It is appropriate to add `capitalized-words-mode' to
-the mode hook for programming language modes in which you encounter
-variables like this, e.g. `java-mode-hook'. It's unlikely to cause
-trouble if such identifiers aren't used.
-
-See also `glasses-mode' and `studlify-word'.
-Obsoletes `c-forward-into-nomenclature'."
- nil " Caps" nil :group 'programming
- (set (make-local-variable 'find-word-boundary-function-table)
- capitalized-find-word-boundary-function-table))
-
-(provide 'cap-words)
-
-;;; cap-words.el ends here
diff --git a/lisp/progmodes/subword.el b/lisp/progmodes/subword.el
index 7d8dd43..735beb0 100644
--- a/lisp/progmodes/subword.el
+++ b/lisp/progmodes/subword.el
@@ -1,4 +1,4 @@
-;;; subword.el --- Handling capitalized subwords in a nomenclature
+;;; subword.el --- Handling capitalized subwords in a nomenclature -*- lexical-binding: t -*-
;; Copyright (C) 2004-2012 Free Software Foundation, Inc.
@@ -25,8 +25,11 @@
;; useful in general and not tied to C and c-mode at all.
;; This package provides `subword' oriented commands and a minor mode
-;; (`subword-mode') that substitutes the common word handling
-;; functions with them.
+;; (`subword-mode') that changes the definition of a "word" so that
+;; Emacs will see subword bounaries as word boundaries in normal
+;; movement commands. Previously, `subword-mode' substituted the
+;; normal word-movement commands with the subword-oriented versions at
+;; the keymap level.
;; In spite of GNU Coding Standards, it is popular to name a symbol by
;; mixing uppercase and lowercase letters, e.g. "GtkWidget",
@@ -45,25 +48,6 @@
;; subwords in a nomenclature to move between them and to edit them as
;; words.
-;; In the minor mode, all common key bindings for word oriented
-;; commands are overridden by the subword oriented commands:
-
-;; Key Word oriented command Subword oriented command
-;; ============================================================
-;; M-f `forward-word' `subword-forward'
-;; M-b `backward-word' `subword-backward'
-;; M-@ `mark-word' `subword-mark'
-;; M-d `kill-word' `subword-kill'
-;; M-DEL `backward-kill-word' `subword-backward-kill'
-;; M-t `transpose-words' `subword-transpose'
-;; M-c `capitalize-word' `subword-capitalize'
-;; M-u `upcase-word' `subword-upcase'
-;; M-l `downcase-word' `subword-downcase'
-;;
-;; Note: If you have changed the key bindings for the word oriented
-;; commands in your .emacs or a similar place, the keys you've changed
-;; to are also used for the corresponding subword oriented commands.
-
;; To make the mode turn on automatically, put the following code in
;; your .emacs:
;;
@@ -76,22 +60,29 @@
;; the old `c-forward-into-nomenclature' originally contributed by
;; Terry_Glanfield dot Southern at rxuk dot xerox dot com.
-;; TODO: ispell-word.
-
;;; Code:
(defvar subword-mode-map
- (let ((map (make-sparse-keymap)))
- (dolist (cmd '(forward-word backward-word mark-word kill-word
- backward-kill-word transpose-words
- capitalize-word upcase-word downcase-word))
- (let ((othercmd (let ((name (symbol-name cmd)))
- (string-match "\\([[:alpha:]-]+\\)-word[s]?" name)
- (intern (concat "subword-" (match-string 1 name))))))
- (define-key map (vector 'remap cmd) othercmd)))
- map)
+ ;; Leave an empty keymap present so user customization that modify
+ ;; it keep working.
+ (make-sparse-keymap)
"Keymap used in `subword-mode' minor mode.")
+(defconst subword-find-word-boundary-function-table
+ (let ((tab (make-char-table nil)))
+ (set-char-table-range tab t #'subword-find-word-boundary)
+ tab)
+ "Assigned to `find-word-boundary-function-table' in `subword-mode'.")
+
+(defconst subword-empty-char-table
+ (make-char-table nil)
+ "Assigned to `find-word-boundary-function-table' while we're searching
+subwords in order to avoid unwanted reentrancy.")
+
+;;;###autoload
+(define-obsolete-function-alias
+ 'capitalized-words-mode 'subword-mode "24.1")
+
;;;###autoload
(define-minor-mode subword-mode
"Toggle subword movement and editing (Subword mode).
@@ -99,8 +90,8 @@ With a prefix argument ARG, enable Subword mode if ARG is
positive, and disable it otherwise. If called from Lisp, enable
the mode if ARG is omitted or nil.
-Subword mode is a buffer-local minor mode. Enabling it remaps
-word-based editing commands to subword-based commands that handle
+Subword mode is a buffer-local minor mode. Enabling it changes
+the definition of a word so that word-based commands stop inside
symbols with mixed uppercase and lowercase letters,
e.g. \"GtkWidget\", \"EmacsFrameClass\", \"NSGraphicsContext\".
@@ -114,14 +105,19 @@ called a `subword'. Here are some examples:
EmacsFrameClass => \"Emacs\", \"Frame\" and \"Class\"
NSGraphicsContext => \"NS\", \"Graphics\" and \"Context\"
-The subword oriented commands activated in this minor mode recognize
-subwords in a nomenclature to move between subwords and to edit them
-as words.
+When this mode is enabled, word-oriented commands recognize
+subwords in a nomenclature to move between subwords and treat
+them as words.
\\{subword-mode-map}"
nil
nil
- subword-mode-map)
+ subword-mode-map
+
+ (set (make-local-variable 'find-word-boundary-function-table)
+ (if subword-mode
+ subword-find-word-boundary-function-table
+ subword-empty-char-table)))
(define-obsolete-function-alias 'c-subword-mode 'subword-mode "23.2")
@@ -261,7 +257,6 @@ Optional argument ARG is the same as for `capitalize-word'."
(match-end 0))))
(forward-word 1)))
-
(defun subword-backward-internal ()
(if (save-excursion
(let ((case-fold-search nil))
@@ -280,6 +275,19 @@ Optional argument ARG is the same as for `capitalize-word'."
(1+ (match-beginning 0)))))
(backward-word 1)))
+(defun subword-find-word-boundary (pos limit)
+ (let ((find-word-boundary-function-table subword-empty-char-table))
+ (save-match-data
+ (save-excursion
+ (save-restriction
+ (if (< pos limit)
+ (progn
+ (narrow-to-region (point-min) limit)
+ (subword-forward-internal))
+ (narrow-to-region limit (point-max))
+ (subword-backward-internal))
+ (point))))))
+
\f
(provide 'subword)
diff --git a/test/automated/subword.el b/test/automated/subword.el
new file mode 100644
index 0000000..9e769cf
--- /dev/null
+++ b/test/automated/subword.el
@@ -0,0 +1,58 @@
+;;; vc-bzr.el --- tests for progmodes/subword.el
+
+;; Copyright (C) 2011 Free Software Foundation, Inc.
+
+;; Author: Daniel Colascione <dancol@dancol.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'subword)
+
+(ert-deftest subword-test-forward ()
+ "Test that motion in subword-mode stops at the right places."
+
+ (let* ((line "fooBarBAZ quXD g_TESTThingAbc word BLAH test")
+ (fwrd "* * * * * * * * * * * * *")
+ (bkwd "* * * * * * * * * * * * *"))
+
+ (with-temp-buffer
+ (subword-mode 1)
+ (insert line)
+
+ ;; Test forward motion.
+
+ (goto-char (point-min))
+ (let ((stops (make-string (length fwrd) ?\ )))
+ (while (progn
+ (aset stops (1- (point)) ?\*)
+ (not (eobp)))
+ (forward-word))
+ (should (equal stops fwrd)))
+
+ ;; Test backward motion.
+
+ (goto-char (point-max))
+ (let ((stops (make-string (length bkwd) ?\ )))
+ (while (progn
+ (aset stops (1- (point)) ?\*)
+ (not (bobp)))
+ (backward-word))
+ (should (equal stops bkwd))))))
--
1.7.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2012-08-07 17:03 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Daniel Colascione
@ 2012-08-07 18:33 ` Masatake YAMATO
2012-08-07 20:43 ` Daniel Colascione
2012-08-07 20:37 ` Stefan Monnier
1 sibling, 1 reply; 10+ messages in thread
From: Masatake YAMATO @ 2012-08-07 18:33 UTC (permalink / raw)
To: dancol; +Cc: emacs-devel
> subword-mode began life as part of cc-mode, but because it's
> generally useful, it was extracted and made a generic part of
> Emacs. subword-mode uses command remapping to achive its subword
> motion, however, and this mechanism can't catch all kinds of word-
> based motion, resulting in inconsistency.
>
> capitalized-words-mode attempts to do what subword-mode does, but
> using a hook added to C core for the purpose. This hook allows
> capitalizd-words-mode to change all kinds of word-based motion
> into subword motion. Unfortunately, capitalized-words-mode used
> overly simplistic code that caused it to fail to properly move
> over words like "fooBarBAZ"; subword-mode handles these words
> properly. capitalized-words-mode is also disadvantaged by
> a long and misleading name.
>
> This patch merges subword-mode and capitalized-words-mode by
> modifying subword-mode to use the core hook and marking
> capitalized-words-mode as an obsolete alias for subword-mode.
>
> This patch also includes an automated test for subword motion.
Nice.
> -;; TODO: ispell-word.
> -
Does this mean subword-mode can handle ispell with your patch?
If yes, it is really nice.
If not, please keep the TODO item in the comment of the file.
> diff --git a/test/automated/subword.el b/test/automated/subword.el
> new file mode 100644
> index 0000000..9e769cf
> --- /dev/null
> +++ b/test/automated/subword.el
> @@ -0,0 +1,58 @@
> +;;; vc-bzr.el --- tests for progmodes/subword.el
This should be subword.el, shouldn't be?
Masatake YAMATO
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2012-08-07 17:03 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Daniel Colascione
2012-08-07 18:33 ` Masatake YAMATO
@ 2012-08-07 20:37 ` Stefan Monnier
1 sibling, 0 replies; 10+ messages in thread
From: Stefan Monnier @ 2012-08-07 20:37 UTC (permalink / raw)
To: Daniel Colascione; +Cc: emacs-devel
> subword-mode began life as part of cc-mode, but because it's
> generally useful, it was extracted and made a generic part of
> Emacs. subword-mode uses command remapping to achive its subword
> motion, however, and this mechanism can't catch all kinds of word-
> based motion, resulting in inconsistency.
> capitalized-words-mode attempts to do what subword-mode does, but
> using a hook added to C core for the purpose. This hook allows
> capitalizd-words-mode to change all kinds of word-based motion
> into subword motion. Unfortunately, capitalized-words-mode used
> overly simplistic code that caused it to fail to properly move
> over words like "fooBarBAZ"; subword-mode handles these words
> properly. capitalized-words-mode is also disadvantaged by
> a long and misleading name.
> This patch merges subword-mode and capitalized-words-mode by
> modifying subword-mode to use the core hook and marking
> capitalized-words-mode as an obsolete alias for subword-mode.
I like consolidation like that. But now, I wonder about bugs that can
be introduced by the pervasive impact of capitalized-words-mode.
My guess is that most of the potential problems we might bump into will
be the result of bugs that can also be triggered without
capitalized-words-mode (i.e. they just get triggered more easily with
capitalized-words-mode).
Stefan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2012-08-07 18:33 ` Masatake YAMATO
@ 2012-08-07 20:43 ` Daniel Colascione
2012-08-07 21:00 ` Daniel Colascione
2012-08-08 2:58 ` Eli Zaretskii
0 siblings, 2 replies; 10+ messages in thread
From: Daniel Colascione @ 2012-08-07 20:43 UTC (permalink / raw)
To: Masatake YAMATO; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 414 bytes --]
On 8/7/2012 11:33 AM, Masatake YAMATO wrote:
>
>> -;; TODO: ispell-word.
>> -
>
> Does this mean subword-mode can handle ispell with your patch?
> If yes, it is really nice.
> If not, please keep the TODO item in the comment of the file.
Good catch. (thing-at-point 'word) returns the right subword, but ispell has its
own ispell-get-word function. Can we just change ispell to use thing-at-point?
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2012-08-07 20:43 ` Daniel Colascione
@ 2012-08-07 21:00 ` Daniel Colascione
2012-08-08 2:58 ` Eli Zaretskii
1 sibling, 0 replies; 10+ messages in thread
From: Daniel Colascione @ 2012-08-07 21:00 UTC (permalink / raw)
To: Masatake YAMATO; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 811 bytes --]
On 8/7/2012 1:43 PM, Daniel Colascione wrote:
> On 8/7/2012 11:33 AM, Masatake YAMATO wrote:
>>
>>> -;; TODO: ispell-word.
>>> -
>>
>> Does this mean subword-mode can handle ispell with your patch?
>> If yes, it is really nice.
>> If not, please keep the TODO item in the comment of the file.
>
> Good catch. (thing-at-point 'word) returns the right subword, but ispell has its
> own ispell-get-word function. Can we just change ispell to use thing-at-point?
>
Another thing that doesn't work is regexp's word boundary support (\b and B\),
which only looks at syntax tables. I'm not sure about the best way to fix it,
though: do we really want to run arbitrary elisp inside the regex matcher? It
doesn't seem feasible to go add text properties everywhere there's a word
boundary either.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] Merge subword-mode and capitalized-words-mode
2012-08-07 20:43 ` Daniel Colascione
2012-08-07 21:00 ` Daniel Colascione
@ 2012-08-08 2:58 ` Eli Zaretskii
1 sibling, 0 replies; 10+ messages in thread
From: Eli Zaretskii @ 2012-08-08 2:58 UTC (permalink / raw)
To: Daniel Colascione; +Cc: yamato, emacs-devel
> Date: Tue, 07 Aug 2012 13:43:25 -0700
> From: Daniel Colascione <dancol@dancol.org>
> Cc: emacs-devel@gnu.org
>
> Good catch. (thing-at-point 'word) returns the right subword, but ispell has its
> own ispell-get-word function. Can we just change ispell to use thing-at-point?
ispell-get-word pays attention to variables that are customized per
dictionary, so I don't think the replacement is the way to go. How
about the other way around, at least as an option?
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-08-08 2:58 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-30 2:03 [PATCH 1/2] Merge subword-mode and capitalized-words-mode Daniel Colascione
2011-12-30 2:03 ` [PATCH 2/2] For better visibility, add subword-mode to options menu Daniel Colascione
2011-12-30 11:23 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Stefan Monnier
2012-01-04 15:54 ` Masatake YAMATO
-- strict thread matches above, loose matches on Subject: below --
2012-08-07 17:03 [PATCH 0/2] Merge subword-mode and capitalized-words-mode; add to UI Daniel Colascione
2012-08-07 17:03 ` [PATCH 1/2] Merge subword-mode and capitalized-words-mode Daniel Colascione
2012-08-07 18:33 ` Masatake YAMATO
2012-08-07 20:43 ` Daniel Colascione
2012-08-07 21:00 ` Daniel Colascione
2012-08-08 2:58 ` Eli Zaretskii
2012-08-07 20:37 ` Stefan Monnier
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.