Barry> My suggestion would be to try rebinding it. It seems like you
Barry> know enough about how to do that and what to look for in
Barry> breakage, and probably also how to fix such breakage. Speaking
Barry> solely for myself, I think we would accept patches that allowed
Barry> python-mode to work either way, perhaps keyed off a new
Barry> configuration variable (py- historical-underscore-behavior-
>> p ?).
Some years ago I decided I hated the SF "slick" but ever-changing and
script-laden website and would not use it for projects. Now I needed
to log in to post the patch, but of course I didn't remember my password,
and efforts to retrieve it only reminded me why I hated it so :)
All of which is a round-about way of saying, the patch is enclosed.
It is against the svn trunk version of python-mode.el.
--- ./python-mode.el 2007-05-02 23:10:11.000000000 -0400
+++ /home/itz/python-mode.el 2007-05-03 00:05:35.000000000 -0400
@@ -370,6 +370,17 @@
:type 'boolean
:group 'python)
+(defcustom py-hysterical-underscore t
+ "*If true (default), underscore character has word syntax class.
+
+According to the Python authorities this is due to the famed historical
+reasons. Set it to nil if you value consistency with other parts of
+Emacs. This will give the underscore the symbol class and so make it
+possible, for example, to quickly yank or complete `foobar_method' into
+your buffer, then replace just the second word to get `foobar_property'."
+ :type 'boolean
+ :group 'python)
+
;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
@@ -501,7 +512,7 @@
'("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t)
))
"Additional expressions to highlight in Python mode.")
-(put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))
+(put 'python-mode 'font-lock-defaults '(python-font-lock-keywords (?_ . "w")))
;; have to bind py-file-queue before installing the kill-emacs-hook
(defvar py-file-queue nil
@@ -754,7 +765,8 @@
;; py-backward-into-nomenclature instead. This doesn't help in all
;; situations where you'd want the different behavior
;; (e.g. backward-kill-word).
- (modify-syntax-entry ?\_ "w" py-mode-syntax-table)
+ (if py-hysterical-underscore
+ (modify-syntax-entry ?\_ "w" py-mode-syntax-table))
;; Both single quote and double quote are string delimiters
(modify-syntax-entry ?\' "\"" py-mode-syntax-table)
(modify-syntax-entry ?\" "\"" py-mode-syntax-table)
@@ -765,6 +777,15 @@
(modify-syntax-entry ?\n ">" py-mode-syntax-table)
)
+;; An auxiliary syntax table which always places underscore in the word class,
+;; to faciliate keyword matching
+(defvar py-keyword-match-syntax-table nil
+ "Syntax table used to match Python keywords.")
+(when (not py-keyword-match-syntax-table)
+ (setq py-keyword-match-syntax-table
+ (copy-syntax-table py-mode-syntax-table))
+ (modify-syntax-entry ?_ "w" py-keyword-match-syntax-table))
+
;; An auxiliary syntax table which places underscore and dot in the
;; symbol class for simplicity
(defvar py-dotted-expression-syntax-table nil
@@ -1190,7 +1211,7 @@
(setq major-mode 'python-mode
mode-name "Python"
local-abbrev-table python-mode-abbrev-table
- font-lock-defaults '(python-font-lock-keywords)
+ font-lock-defaults '(python-font-lock-keywords nil nil ((?_ . "w")))
paragraph-separate "^[ \t]*$"
paragraph-start "^[ \t]*$"
require-final-newline t
@@ -2655,7 +2676,8 @@
(zerop (current-column))
(looking-at start-re))
(end-of-line))
- (if (re-search-backward start-re nil 'move count)
+ (if (with-syntax-table py-keyword-match-syntax-table
+ (re-search-backward start-re nil 'move count))
(goto-char (match-beginning 0)))))
;; Backwards compatibility
@@ -2699,7 +2721,8 @@
(t "def")))
(state 'not-found))
;; move point to start of appropriate def/class
- (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one
+ (if (with-syntax-table py-keyword-match-syntax-table
+ (looking-at (concat "[ \t]*" which "\\>"))) ; already on one
(setq state 'at-beginning)
;; else see if py-beginning-of-def-or-class hits container
(if (and (py-beginning-of-def-or-class class)
@@ -2708,7 +2731,8 @@
(setq state 'at-end)
;; else search forward
(goto-char start)
- (if (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move)
+ (if (with-syntax-table py-keyword-match-syntax-table
+ (re-search-forward (concat "^[ \t]*" which "\\>") nil 'move))
(progn (setq state 'at-beginning)
(beginning-of-line)))))
(cond
@@ -2924,13 +2948,15 @@
(interactive "p")
(let ((case-fold-search nil))
(if (> arg 0)
- (re-search-forward
- "\\(\\W\\|[_]\\)*\\([A-Z]*[a-z0-9]*\\)"
- (point-max) t arg)
+ (with-syntax-table py-keyword-match-syntax-table
+ (re-search-forward
+ "\\(\\W\\|[_]\\)*\\([A-Z]*[a-z0-9]*\\)"
+ (point-max) t arg))
(while (and (< arg 0)
- (re-search-backward
- "\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\(\\W\\|[_]\\)\\w+"
- (point-min) 0))
+ (with-syntax-table py-keyword-match-syntax-table
+ (re-search-backward
+ "\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\(\\W\\|[_]\\)\\w+"
+ (point-min) 0)))
(forward-char 1)
(setq arg (1+ arg)))))
(py-keep-region-active))
@@ -3383,7 +3409,8 @@
;; places to start parsing to see whether where we started is
;; at a non-zero nesting level. It may be slow for people who
;; write huge code blocks or huge lists ... tough beans.
- (re-search-backward py-parse-state-re nil 'move)
+ (with-syntax-table py-keyword-match-syntax-table
+ (re-search-backward py-parse-state-re nil 'move))
(beginning-of-line)
;; In XEmacs, we have a much better way to test for whether
;; we're in a triple-quoted string or not. Emacs does not
@@ -3536,7 +3563,8 @@
(py-goto-initial-line)
(back-to-indentation)
(prog1
- (looking-at (concat py-block-closing-keywords-re "\\>"))
+ (with-syntax-table py-keyword-match-syntax-table
+ (looking-at (concat py-block-closing-keywords-re "\\>")))
(goto-char here))))
(defun py-goto-beyond-block ()
@@ -3595,7 +3623,8 @@
(py-goto-initial-line)
(let* ((re (concat "[ \t]*" key "\\>"))
(case-fold-search nil) ; let* so looking-at sees this
- (found (looking-at re))
+ (found (with-syntax-table py-keyword-match-syntax-table
+ (looking-at re)))
(dead nil))
(while (not (or found dead))
(condition-case nil ; in case no enclosing block
@@ -3619,7 +3648,8 @@
`Keyword' is defined (essentially) as the regular expression
([a-z]+). Returns nil if none was found."
(let ((case-fold-search nil))
- (if (looking-at "[ \t]*\\([a-z]+\\)\\>")
+ (if (with-syntax-table py-keyword-match-syntax-table
+ (looking-at "[ \t]*\\([a-z]+\\)\\>"))
(intern (buffer-substring (match-beginning 1) (match-end 1)))
nil)))
--
This line is completely ham.
_______________________________________________
Python-mode mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-mode