aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2007-09-10 20:02:31 +0000
committerStefan Monnier2007-09-10 20:02:31 +0000
commit308114ef9f06dd70ad50983a0c2504e064dadd52 (patch)
tree9d1124adc5a839903f1771e5d0554306777b7f88
parentb4f92cff9a60f70b0de780fe637a40583140944f (diff)
downloademacs-308114ef9f06dd70ad50983a0c2504e064dadd52.tar.gz
emacs-308114ef9f06dd70ad50983a0c2504e064dadd52.zip
Merge changes from Dave Love's v2007-Sep-10.
(python-font-lock-keywords): Update to the 2.5 version of the language. (python-quote-syntax): Let-bind font-lock-syntactic-keywords to nil. (python-backspace): Only behave funny in code. (python-compilation-regexp-alist): Add PDB stack trace regexp. (inferior-python-mode): Add PDB prompt regexp. (python-fill-paragraph): Refine the fenced-string regexp. (python-find-imports): Handle imports spanning several lines. (python-mode): Add `class' to hideshow support.
-rw-r--r--lisp/ChangeLog12
-rw-r--r--lisp/progmodes/python.el111
2 files changed, 78 insertions, 45 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 055cdc75af3..c3d8fd8b92d 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,15 @@
12007-09-10 Dave Love <fx@gnu.org>
2
3 * progmodes/python.el: Merge changes from Dave Love's v2007-Sep-10.
4 (python-font-lock-keywords): Update to the 2.5 version of the language.
5 (python-quote-syntax): Let-bind font-lock-syntactic-keywords to nil.
6 (python-backspace): Only behave funny in code.
7 (python-compilation-regexp-alist): Add PDB stack trace regexp.
8 (inferior-python-mode): Add PDB prompt regexp.
9 (python-fill-paragraph): Refine the fenced-string regexp.
10 (python-find-imports): Handle imports spanning several lines.
11 (python-mode): Add `class' to hideshow support.
12
12007-09-08 Stefan Monnier <monnier@iro.umontreal.ca> 132007-09-08 Stefan Monnier <monnier@iro.umontreal.ca>
2 14
3 * pcvs.el (cvs-mode-add-change-log-entry-other-window): Use 15 * pcvs.el (cvs-mode-add-change-log-entry-other-window): Use
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 7c1abaf223d..2d386e109d9 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1,4 +1,4 @@
1;;; python.el --- silly walks for Python 1;;; python.el --- silly walks for Python -*- coding: iso-8859-1 -*-
2 2
3;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 3;; Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 4
@@ -89,17 +89,17 @@
89 89
90(defvar python-font-lock-keywords 90(defvar python-font-lock-keywords
91 `(,(rx symbol-start 91 `(,(rx symbol-start
92 ;; From v 2.4 reference. 92 ;; From v 2.5 reference, § keywords.
93 ;; def and class dealt with separately below 93 ;; def and class dealt with separately below
94 (or "and" "assert" "break" "continue" "del" "elif" "else" 94 (or "and" "as" "assert" "break" "continue" "del" "elif" "else"
95 "except" "exec" "finally" "for" "from" "global" "if" 95 "except" "exec" "finally" "for" "from" "global" "if"
96 "import" "in" "is" "lambda" "not" "or" "pass" "print" 96 "import" "in" "is" "lambda" "not" "or" "pass" "print"
97 "raise" "return" "try" "while" "yield" 97 "raise" "return" "try" "while" "with" "yield"
98 ;; Future keywords
99 "as" "None" "with"
100 ;; Not real keywords, but close enough to be fontified as such 98 ;; Not real keywords, but close enough to be fontified as such
101 "self" "True" "False") 99 "self" "True" "False")
102 symbol-end) 100 symbol-end)
101 (,(rx symbol-start "None" symbol-end) ; See § Keywords in 2.5 manual.
102 . font-lock-constant-face)
103 ;; Definitions 103 ;; Definitions
104 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) 104 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_))))
105 (1 font-lock-keyword-face) (2 font-lock-type-face)) 105 (1 font-lock-keyword-face) (2 font-lock-type-face))
@@ -151,7 +151,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
151 (cond 151 (cond
152 ;; Consider property for the last char if in a fenced string. 152 ;; Consider property for the last char if in a fenced string.
153 ((= n 3) 153 ((= n 3)
154 (let ((syntax (syntax-ppss))) 154 (let* ((font-lock-syntactic-keywords nil)
155 (syntax (syntax-ppss)))
155 (when (eq t (nth 3 syntax)) ; after unclosed fence 156 (when (eq t (nth 3 syntax)) ; after unclosed fence
156 (goto-char (nth 8 syntax)) ; fence position 157 (goto-char (nth 8 syntax)) ; fence position
157 (skip-chars-forward "uUrR") ; skip any prefix 158 (skip-chars-forward "uUrR") ; skip any prefix
@@ -163,8 +164,9 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
163 (= (match-beginning 1) (match-end 1))) ; prefix is null 164 (= (match-beginning 1) (match-end 1))) ; prefix is null
164 (and (= n 1) ; prefix 165 (and (= n 1) ; prefix
165 (/= (match-beginning 1) (match-end 1)))) ; non-empty 166 (/= (match-beginning 1) (match-end 1)))) ; non-empty
166 (unless (nth 3 (syntax-ppss)) 167 (let ((font-lock-syntactic-keywords nil))
167 (eval-when-compile (string-to-syntax "|")))) 168 (unless (nth 3 (syntax-ppss))
169 (eval-when-compile (string-to-syntax "|")))))
168 ;; Otherwise (we're in a non-matching string) the property is 170 ;; Otherwise (we're in a non-matching string) the property is
169 ;; nil, which is OK. 171 ;; nil, which is OK.
170 ))) 172 )))
@@ -348,7 +350,7 @@ comments and strings, or that point is within brackets/parens."
348 (error nil)))))))) 350 (error nil))))))))
349 351
350(defun python-comment-line-p () 352(defun python-comment-line-p ()
351 "Return non-nil if current line has only a comment." 353 "Return non-nil iff current line has only a comment."
352 (save-excursion 354 (save-excursion
353 (end-of-line) 355 (end-of-line)
354 (when (eq 'comment (syntax-ppss-context (syntax-ppss))) 356 (when (eq 'comment (syntax-ppss-context (syntax-ppss)))
@@ -356,7 +358,7 @@ comments and strings, or that point is within brackets/parens."
356 (looking-at (rx (or (syntax comment-start) line-end)))))) 358 (looking-at (rx (or (syntax comment-start) line-end))))))
357 359
358(defun python-blank-line-p () 360(defun python-blank-line-p ()
359 "Return non-nil if current line is blank." 361 "Return non-nil iff current line is blank."
360 (save-excursion 362 (save-excursion
361 (beginning-of-line) 363 (beginning-of-line)
362 (looking-at "\\s-*$"))) 364 (looking-at "\\s-*$")))
@@ -850,7 +852,7 @@ multi-line bracketed expressions."
850 "Skip out of any nested brackets. 852 "Skip out of any nested brackets.
851Skip forward if FORWARD is non-nil, else backward. 853Skip forward if FORWARD is non-nil, else backward.
852If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point. 854If SYNTAX is non-nil it is the state returned by `syntax-ppss' at point.
853Return non-nil if skipping was done." 855Return non-nil iff skipping was done."
854 (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss)))) 856 (let ((depth (syntax-ppss-depth (or syntax (syntax-ppss))))
855 (forward (if forward -1 1))) 857 (forward (if forward -1 1)))
856 (unless (zerop depth) 858 (unless (zerop depth)
@@ -1075,13 +1077,15 @@ just insert a single colon."
1075 1077
1076(defun python-backspace (arg) 1078(defun python-backspace (arg)
1077 "Maybe delete a level of indentation on the current line. 1079 "Maybe delete a level of indentation on the current line.
1078Do so if point is at the end of the line's indentation. 1080Do so if point is at the end of the line's indentation outside
1081strings and comments.
1079Otherwise just call `backward-delete-char-untabify'. 1082Otherwise just call `backward-delete-char-untabify'.
1080Repeat ARG times." 1083Repeat ARG times."
1081 (interactive "*p") 1084 (interactive "*p")
1082 (if (or (/= (current-indentation) (current-column)) 1085 (if (or (/= (current-indentation) (current-column))
1083 (bolp) 1086 (bolp)
1084 (python-continuation-line-p)) 1087 (python-continuation-line-p)
1088 (python-in-string/comment))
1085 (backward-delete-char-untabify arg) 1089 (backward-delete-char-untabify arg)
1086 ;; Look for the largest valid indentation which is smaller than 1090 ;; Look for the largest valid indentation which is smaller than
1087 ;; the current indentation. 1091 ;; the current indentation.
@@ -1182,6 +1186,10 @@ local value.")
1182 1 2) 1186 1 2)
1183 (,(rx " in file " (group (1+ not-newline)) " on line " 1187 (,(rx " in file " (group (1+ not-newline)) " on line "
1184 (group (1+ digit))) 1188 (group (1+ digit)))
1189 1 2)
1190 ;; pdb stack trace
1191 (,(rx line-start "> " (group (1+ (not (any "(\"<"))))
1192 "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
1185 1 2)) 1193 1 2))
1186 "`compilation-error-regexp-alist' for inferior Python.") 1194 "`compilation-error-regexp-alist' for inferior Python.")
1187 1195
@@ -1191,7 +1199,7 @@ local value.")
1191 (define-key map "\C-c\C-l" 'python-load-file) 1199 (define-key map "\C-c\C-l" 'python-load-file)
1192 (define-key map "\C-c\C-v" 'python-check) 1200 (define-key map "\C-c\C-v" 'python-check)
1193 ;; Note that we _can_ still use these commands which send to the 1201 ;; Note that we _can_ still use these commands which send to the
1194 ;; Python process even at the prompt provided we have a normal prompt, 1202 ;; Python process even at the prompt iff we have a normal prompt,
1195 ;; i.e. '>>> ' and not '... '. See the comment before 1203 ;; i.e. '>>> ' and not '... '. See the comment before
1196 ;; python-send-region. Fixme: uncomment these if we address that. 1204 ;; python-send-region. Fixme: uncomment these if we address that.
1197 1205
@@ -1237,7 +1245,7 @@ For running multiple processes in multiple buffers, see `run-python' and
1237 ;; Still required by `comint-redirect-send-command', for instance 1245 ;; Still required by `comint-redirect-send-command', for instance
1238 ;; (and we need to match things like `>>> ... >>> '): 1246 ;; (and we need to match things like `>>> ... >>> '):
1239 (set (make-local-variable 'comint-prompt-regexp) 1247 (set (make-local-variable 'comint-prompt-regexp)
1240 (rx line-start (1+ (and (repeat 3 (any ">.")) " ")))) 1248 (rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " "))))
1241 (set (make-local-variable 'compilation-error-regexp-alist) 1249 (set (make-local-variable 'compilation-error-regexp-alist)
1242 python-compilation-regexp-alist) 1250 python-compilation-regexp-alist)
1243 (compilation-shell-minor-mode 1)) 1251 (compilation-shell-minor-mode 1))
@@ -1729,47 +1737,57 @@ The criterion is either a match for `jython-mode' via
1729 (jython-mode))))))) 1737 (jython-mode)))))))
1730 1738
1731(defun python-fill-paragraph (&optional justify) 1739(defun python-fill-paragraph (&optional justify)
1732 "`fill-paragraph-function' handling comments and multi-line strings. 1740 "`fill-paragraph-function' handling multi-line strings and possibly comments.
1733If any of the current line is a comment, fill the comment or the 1741If any of the current line is in or at the end of a multi-line string,
1734paragraph of it that point is in, preserving the comment's 1742fill the string or the paragraph of it that point is in, preserving
1735indentation and initial comment characters. Similarly if the end 1743the strings's indentation."
1736of the current line is in or at the end of a multi-line string.
1737Otherwise, do nothing."
1738 (interactive "P") 1744 (interactive "P")
1739 (or (fill-comment-paragraph justify) 1745 (or (fill-comment-paragraph justify)
1740 ;; The `paragraph-start' and `paragraph-separate' variables
1741 ;; don't allow us to delimit the last paragraph in a multi-line
1742 ;; string properly, so narrow to the string and then fill around
1743 ;; (the end of) the current line.
1744 (save-excursion 1746 (save-excursion
1745 (end-of-line) 1747 (end-of-line)
1746 (let* ((syntax (syntax-ppss)) 1748 (let* ((syntax (syntax-ppss))
1747 (orig (point)) 1749 (orig (point))
1748 (start (nth 8 syntax)) 1750 start end)
1749 end) 1751 (cond ((nth 4 syntax) ; comment. fixme: loses with trailing one
1750 (cond ((eq t (nth 3 syntax)) ; in fenced string 1752 (let (fill-paragraph-function)
1751 (goto-char (nth 8 syntax)) ; string start 1753 (fill-paragraph justify)))
1754 ;; The `paragraph-start' and `paragraph-separate'
1755 ;; variables don't allow us to delimit the last
1756 ;; paragraph in a multi-line string properly, so narrow
1757 ;; to the string and then fill around (the end of) the
1758 ;; current line.
1759 ((eq t (nth 3 syntax)) ; in fenced string
1760 (goto-char (nth 8 syntax)) ; string start
1761 (setq start (line-beginning-position))
1752 (setq end (condition-case () ; for unbalanced quotes 1762 (setq end (condition-case () ; for unbalanced quotes
1753 (progn (forward-sexp) (point)) 1763 (progn (forward-sexp)
1764 (- (point) 3))
1754 (error (point-max))))) 1765 (error (point-max)))))
1755 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced 1766 ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced string
1756 ; string
1757 (forward-char) 1767 (forward-char)
1758 (setq end (point)) 1768 (setq end (point))
1759 (condition-case () 1769 (condition-case ()
1760 (progn (backward-sexp) 1770 (progn (backward-sexp)
1761 (setq start (point))) 1771 (setq start (line-beginning-position)))
1762 (error (setq end nil))))) 1772 (error nil))))
1763 (when end 1773 (when end
1764 (save-restriction 1774 (save-restriction
1765 (narrow-to-region start end) 1775 (narrow-to-region start end)
1766 (goto-char orig) 1776 (goto-char orig)
1767 (let ((paragraph-separate 1777 ;; Avoid losing leading and trailing newlines in doc
1768 ;; Make sure that fenced-string delimiters that stand 1778 ;; strings written like:
1769 ;; on their own line stay there. 1779 ;; """
1770 (concat "[ \t]*['\"]+[ \t]*$\\|" paragraph-separate))) 1780 ;; ...
1771 (fill-paragraph justify)))))) 1781 ;; """
1772 t)) 1782 (let* ((paragraph-separate
1783 (concat ".*\\s|\"\"$" ; newline after opening quotes
1784 "\\|\\(?:" paragraph-separate "\\)"))
1785 (paragraph-start
1786 (concat ".*\\s|\"\"[ \t]*[^ \t].*" ; not newline after
1787 ; opening quotes
1788 "\\|\\(?:" paragraph-separate "\\)"))
1789 (fill-paragraph-function))
1790 (fill-paragraph justify))))))) t)
1773 1791
1774(defun python-shift-left (start end &optional count) 1792(defun python-shift-left (start end &optional count)
1775 "Shift lines in region COUNT (the prefix arg) columns to the left. 1793 "Shift lines in region COUNT (the prefix arg) columns to the left.
@@ -1866,9 +1884,12 @@ Uses `python-beginning-of-block', `python-end-of-block'."
1866 (goto-char (point-min)) 1884 (goto-char (point-min))
1867 (while (re-search-forward "^import\\>\\|^from\\>" nil t) 1885 (while (re-search-forward "^import\\>\\|^from\\>" nil t)
1868 (unless (syntax-ppss-context (syntax-ppss)) 1886 (unless (syntax-ppss-context (syntax-ppss))
1869 (push (buffer-substring (line-beginning-position) 1887 (let ((start (line-beginning-position)))
1870 (line-beginning-position 2)) 1888 ;; Skip over continued lines.
1871 lines))) 1889 (while (and (eq ?\\ (char-before (line-end-position)))
1890 (= 0 (forward-line 1))))
1891 (push (buffer-substring start (line-beginning-position 2))
1892 lines))))
1872 (setq python-imports 1893 (setq python-imports
1873 (if lines 1894 (if lines
1874 (apply #'concat 1895 (apply #'concat
@@ -2259,7 +2280,7 @@ with skeleton expansions for compound statement templates.
2259 ;; since it isn't (can't be) indentation-based. Also hide-level 2280 ;; since it isn't (can't be) indentation-based. Also hide-level
2260 ;; doesn't seem to work properly. 2281 ;; doesn't seem to work properly.
2261 (add-to-list 'hs-special-modes-alist 2282 (add-to-list 'hs-special-modes-alist
2262 `(python-mode "^\\s-*def\\>" nil "#" 2283 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
2263 ,(lambda (arg) 2284 ,(lambda (arg)
2264 (python-end-of-defun) 2285 (python-end-of-defun)
2265 (skip-chars-backward " \t\n")) 2286 (skip-chars-backward " \t\n"))