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

Reply via email to