Emacs users: feedback on diffs between python-mode.el and python.el?

  • Thread starter Bruno Desthuilliers
  • Start date
R

Rob Wolfe

Alberto Griggio said:
Hello,


I agree too. I can't really say what's missing from python.el, but I'm
much more comfortable with python-mode.el. The triple-quote highlight is
better in python.el, but I was successful in porting it to
python-mode.el as well. Unfortunately, I don't have a clean diff, as I
did some other tweaks...

Many thanks for this suggestion.
Now python-mode.el works like a charm. So many years of frustration. :)

I just downloaded python-mode.el from svn:
http://svn.sourceforge.net/viewvc/python-mode/trunk/python-mode/

and applied this patch (code taken from python.el):

--- python-mode.el.org 2008-10-17 21:20:29.000000000 +0200
+++ python-mode.el 2008-10-17 21:23:13.000000000 +0200
@@ -500,6 +500,63 @@
'("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t)
))
"Additional expressions to highlight in Python mode.")
+
+(defconst python-font-lock-syntactic-keywords
+ ;; Make outer chars of matching triple-quote sequences into generic
+ ;; string delimiters. Fixme: Is there a better way?
+ `((,(rx (or line-start buffer-start
+ (not (syntax escape))) ; avoid escaped leading quote
+ (group (optional (any "uUrR"))) ; prefix gets syntax property
+ (optional (any "rR")) ; possible second prefix
+ (group (syntax string-quote)) ; maybe gets property
+ (backref 2) ; per first quote
+ (group (backref 2))) ; maybe gets property
+ (1 (python-quote-syntax 1))
+ (2 (python-quote-syntax 2))
+ (3 (python-quote-syntax 3)))))
+
+(defun python-quote-syntax (n)
+ "Put `syntax-table' property correctly on triple quote.
+Used for syntactic keywords. N is the match number (1, 2 or 3)."
+ ;; Given a triple quote, we have to check the context to know
+ ;; whether this is an opening or closing triple or whether it's
+ ;; quoted anyhow, and should be ignored. (For that we need to do
+ ;; the same job as `syntax-ppss' to be correct and it seems to be OK
+ ;; to use it here despite initial worries.) We also have to sort
+ ;; out a possible prefix -- well, we don't _have_ to, but I think it
+ ;; should be treated as part of the string.
+
+ ;; Test cases:
+ ;; ur"""ar""" x='"' # """
+ ;; x = ''' """ ' a
+ ;; '''
+ ;; x '"""' x """ \"""" x
+ ;; Fixme: """""" goes wrong (due to syntax-ppss not getting the string
+ ;; fence context).
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (cond
+ ;; Consider property for the last char if in a fenced string.
+ ((= n 3)
+ (let ((syntax (syntax-ppss)))
+ (when (eq t (nth 3 syntax)) ; after unclosed fence
+ (goto-char (nth 8 syntax)) ; fence position
+ (skip-chars-forward "uUrR") ; skip any prefix
+ ;; Is it a matching sequence?
+ (if (eq (char-after) (char-after (match-beginning 2)))
+ (eval-when-compile (string-to-syntax "|"))))))
+ ;; Consider property for initial char, accounting for prefixes.
+ ((or (and (= n 2) ; leading quote (not prefix)
+ (= (match-beginning 1) (match-end 1))) ; prefix is null
+ (and (= n 1) ; prefix
+ (/= (match-beginning 1) (match-end 1)))) ; non-empty
+ (unless (nth 3 (syntax-ppss))
+ (eval-when-compile (string-to-syntax "|"))))
+ ;; Otherwise (we're in a non-matching string) the property is
+ ;; nil, which is OK.
+ )))
+
+
(put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))

;; have to bind py-file-queue before installing the kill-emacs-hook
@@ -1189,7 +1246,10 @@
(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 nil nil
+ (font-lock-syntactic-keywords
+ . python-font-lock-syntactic-keywords))
+
paragraph-separate "^[ \t]*$"
paragraph-start "^[ \t]*$"
require-final-newline t
 
R

Rob Wolfe

Alberto Griggio said:
Hello,


I agree too. I can't really say what's missing from python.el, but I'm
much more comfortable with python-mode.el. The triple-quote highlight is
better in python.el, but I was successful in porting it to
python-mode.el as well. Unfortunately, I don't have a clean diff, as I
did some other tweaks...

Many thanks for this suggestion.
Now python-mode.el works like a charm. So many years of frustration. ;-)

I just downloaded python-mode.el from svn:
http://svn.sourceforge.net/viewvc/python-mode/trunk/python-mode/

and applied this patch (code taken from python.el):

--- python-mode.el.org 2008-10-17 21:20:29.000000000 +0200
+++ python-mode.el 2008-10-17 21:23:13.000000000 +0200
@@ -500,6 +500,63 @@
'("XXX\\|TODO\\|FIXME" 0 py-XXX-tag-face t)
))
"Additional expressions to highlight in Python mode.")
+
+(defconst python-font-lock-syntactic-keywords
+ ;; Make outer chars of matching triple-quote sequences into generic
+ ;; string delimiters. Fixme: Is there a better way?
+ `((,(rx (or line-start buffer-start
+ (not (syntax escape))) ; avoid escaped leading quote
+ (group (optional (any "uUrR"))) ; prefix gets syntax property
+ (optional (any "rR")) ; possible second prefix
+ (group (syntax string-quote)) ; maybe gets property
+ (backref 2) ; per first quote
+ (group (backref 2))) ; maybe gets property
+ (1 (python-quote-syntax 1))
+ (2 (python-quote-syntax 2))
+ (3 (python-quote-syntax 3)))))
+
+(defun python-quote-syntax (n)
+ "Put `syntax-table' property correctly on triple quote.
+Used for syntactic keywords. N is the match number (1, 2 or 3)."
+ ;; Given a triple quote, we have to check the context to know
+ ;; whether this is an opening or closing triple or whether it's
+ ;; quoted anyhow, and should be ignored. (For that we need to do
+ ;; the same job as `syntax-ppss' to be correct and it seems to be OK
+ ;; to use it here despite initial worries.) We also have to sort
+ ;; out a possible prefix -- well, we don't _have_ to, but I think it
+ ;; should be treated as part of the string.
+
+ ;; Test cases:
+ ;; ur"""ar""" x='"' # """
+ ;; x = ''' """ ' a
+ ;; '''
+ ;; x '"""' x """ \"""" x
+ ;; Fixme: """""" goes wrong (due to syntax-ppss not getting the string
+ ;; fence context).
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (cond
+ ;; Consider property for the last char if in a fenced string.
+ ((= n 3)
+ (let ((syntax (syntax-ppss)))
+ (when (eq t (nth 3 syntax)) ; after unclosed fence
+ (goto-char (nth 8 syntax)) ; fence position
+ (skip-chars-forward "uUrR") ; skip any prefix
+ ;; Is it a matching sequence?
+ (if (eq (char-after) (char-after (match-beginning 2)))
+ (eval-when-compile (string-to-syntax "|"))))))
+ ;; Consider property for initial char, accounting for prefixes.
+ ((or (and (= n 2) ; leading quote (not prefix)
+ (= (match-beginning 1) (match-end 1))) ; prefix is null
+ (and (= n 1) ; prefix
+ (/= (match-beginning 1) (match-end 1)))) ; non-empty
+ (unless (nth 3 (syntax-ppss))
+ (eval-when-compile (string-to-syntax "|"))))
+ ;; Otherwise (we're in a non-matching string) the property is
+ ;; nil, which is OK.
+ )))
+
+
(put 'python-mode 'font-lock-defaults '(python-font-lock-keywords))

;; have to bind py-file-queue before installing the kill-emacs-hook
@@ -1189,7 +1246,10 @@
(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 nil nil
+ (font-lock-syntactic-keywords
+ . python-font-lock-syntactic-keywords))
+
paragraph-separate "^[ \t]*$"
paragraph-start "^[ \t]*$"
require-final-newline t
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top