Barry's version 2.30; some chages for triple quotes

This commit is contained in:
Guido van Rossum 1995-10-08 00:44:23 +00:00
parent 53f4524a92
commit 503b2e87c2

View file

@ -6,8 +6,8 @@
;; 1992-1994 Tim Peters ;; 1992-1994 Tim Peters
;; Maintainer: python-mode@python.org ;; Maintainer: python-mode@python.org
;; Created: Feb 1992 ;; Created: Feb 1992
;; Version: 2.26 ;; Version: 2.30
;; Last Modified: 1995/07/05 23:26:15 ;; Last Modified: 1995/09/19 20:01:42
;; Keywords: python editing language major-mode ;; Keywords: python editing language major-mode
;; This software is provided as-is, without express or implied ;; This software is provided as-is, without express or implied
@ -70,7 +70,7 @@
;; LCD Archive Entry: ;; LCD Archive Entry:
;; python-mode|Barry A. Warsaw|python-mode@python.org ;; python-mode|Barry A. Warsaw|python-mode@python.org
;; |Major mode for editing Python programs ;; |Major mode for editing Python programs
;; |1995/07/05 23:26:15|2.26| ;; |1995/09/19 20:01:42|2.30|
;;; Code: ;;; Code:
@ -86,6 +86,12 @@
Note that `\\[py-guess-indent-offset]' can usually guess a good value Note that `\\[py-guess-indent-offset]' can usually guess a good value
when you're editing someone else's Python code.") when you're editing someone else's Python code.")
(defvar py-align-multiline-strings-p t
"*Flag describing how multiline triple quoted strings are aligned.
When this flag is non-nil, continuation lines are lined up under the
preceding line's indentation. When this flag is nil, continuation
lines are aligned to column zero.")
(defvar py-block-comment-prefix "##" (defvar py-block-comment-prefix "##"
"*String used by `py-comment-region' to comment out a block of code. "*String used by `py-comment-region' to comment out a block of code.
This should follow the convention for non-indenting comment lines so This should follow the convention for non-indenting comment lines so
@ -407,6 +413,9 @@ py-beep-if-tab-change\tring the bell if tab-width is changed"
mode-name "Python" mode-name "Python"
local-abbrev-table python-mode-abbrev-table) local-abbrev-table python-mode-abbrev-table)
(use-local-map py-mode-map) (use-local-map py-mode-map)
;; Emacs 19 requires this
(if (or py-this-is-lucid-emacs-p py-this-is-emacs-19-p)
(setq comment-multi-line nil))
;; BAW -- style... ;; BAW -- style...
(mapcar (function (lambda (x) (mapcar (function (lambda (x)
(make-local-variable (car x)) (make-local-variable (car x))
@ -468,31 +477,39 @@ py-beep-if-tab-change\tring the bell if tab-width is changed"
(defun py-electric-colon (arg) (defun py-electric-colon (arg)
"Insert a colon. "Insert a colon.
In certain cases the line is outdented appropriately. If a numeric In certain cases the line is outdented appropriately. If a numeric
argument is provided, that many colons are inserted non-electrically." argument is provided, that many colons are inserted non-electrically.
Electric behavior is inhibited inside a string or comment."
(interactive "P") (interactive "P")
(self-insert-command (prefix-numeric-value arg)) (self-insert-command (prefix-numeric-value arg))
(save-excursion ;; are we in a string or comment?
(let ((here (point)) (if (save-excursion
(outdent 0) (let ((pps (parse-partial-sexp (save-excursion
(indent (py-compute-indentation))) (beginning-of-python-def-or-class)
(if (and (not arg) (point))
(py-outdent-p) (point))))
(= indent (save-excursion (not (or (nth 3 pps) (nth 4 pps)))))
(forward-line -1) (save-excursion
(py-compute-indentation))) (let ((here (point))
) (outdent 0)
(setq outdent py-indent-offset)) (indent (py-compute-indentation)))
;; Don't indent, only outdent. This assumes that any lines that (if (and (not arg)
;; are already outdented relative to py-compute-indentation were (py-outdent-p)
;; put there on purpose. Its highly annoying to have `:' indent (= indent (save-excursion
;; for you. Use TAB, C-c C-l or C-c C-r to adjust. TBD: Is (forward-line -1)
;; there a better way to determine this??? (py-compute-indentation)))
(if (< (current-indentation) indent) nil )
(goto-char here) (setq outdent py-indent-offset))
(beginning-of-line) ;; Don't indent, only outdent. This assumes that any lines that
(delete-horizontal-space) ;; are already outdented relative to py-compute-indentation were
(indent-to (- indent outdent)) ;; put there on purpose. Its highly annoying to have `:' indent
)))) ;; for you. Use TAB, C-c C-l or C-c C-r to adjust. TBD: Is
;; there a better way to determine this???
(if (< (current-indentation) indent) nil
(goto-char here)
(beginning-of-line)
(delete-horizontal-space)
(indent-to (- indent outdent))
)))))
(defun py-indent-right (arg) (defun py-indent-right (arg)
"Indent the line by one `py-indent-offset' level. "Indent the line by one `py-indent-offset' level.
@ -782,102 +799,109 @@ the new line indented."
(defun py-compute-indentation () (defun py-compute-indentation ()
(save-excursion (save-excursion
(beginning-of-line) (let ((pps (parse-partial-sexp (save-excursion
(cond (beginning-of-python-def-or-class)
;; are we on a continuation line? (point))
((py-continuation-line-p) (point))))
(let ((startpos (point)) (beginning-of-line)
(open-bracket-pos (py-nesting-level)) (cond
endpos searching found) ;; are we inside a string or comment?
(if open-bracket-pos ((or (nth 3 pps) (nth 4 pps))
(progn (save-excursion
;; align with first item in list; else a normal (if (not py-align-multiline-strings-p) 0
;; indent beyond the line with the open bracket ;; skip back over blank & non-indenting comment lines
(goto-char (1+ open-bracket-pos)) ; just beyond bracket ;; note: will skip a blank or non-indenting comment line
;; is the first list item on the same line? ;; that happens to be a continuation line too
(skip-chars-forward " \t") (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" nil 'move)
(if (null (memq (following-char) '(?\n ?# ?\\)))
; yes, so line up with it
(current-column)
;; first list item on another line, or doesn't exist yet
(forward-line 1)
(while (and (< (point) startpos)
(looking-at "[ \t]*[#\n\\\\]")) ; skip noise
(forward-line 1))
(if (< (point) startpos)
;; again mimic the first list item
(current-indentation)
;; else they're about to enter the first item
(goto-char open-bracket-pos)
(+ (current-indentation) py-indent-offset))))
;; else on backslash continuation line
(forward-line -1)
(if (py-continuation-line-p) ; on at least 3rd line in block
(current-indentation) ; so just continue the pattern
;; else started on 2nd line in block, so indent more.
;; if base line is an assignment with a start on a RHS,
;; indent to 2 beyond the leftmost "="; else skip first
;; chunk of non-whitespace characters on base line, + 1 more
;; column
(end-of-line)
(setq endpos (point) searching t)
(back-to-indentation) (back-to-indentation)
(setq startpos (point)) (current-column))))
;; look at all "=" from left to right, stopping at first ;; are we on a continuation line?
;; one not nested in a list or string ((py-continuation-line-p)
(while searching (let ((startpos (point))
(skip-chars-forward "^=" endpos) (open-bracket-pos (py-nesting-level))
(if (= (point) endpos) endpos searching found)
(setq searching nil) (if open-bracket-pos
(forward-char 1) (progn
(setq state (parse-partial-sexp startpos (point))) ;; align with first item in list; else a normal
(if (and (zerop (car state)) ; not in a bracket ;; indent beyond the line with the open bracket
(null (nth 3 state))) ; & not in a string (goto-char (1+ open-bracket-pos)) ; just beyond bracket
(progn ;; is the first list item on the same line?
(setq searching nil) ; done searching in any case (skip-chars-forward " \t")
(setq found (if (null (memq (following-char) '(?\n ?# ?\\)))
(not (or ; yes, so line up with it
(eq (following-char) ?=) (current-column)
(memq (char-after (- (point) 2)) ;; first list item on another line, or doesn't exist yet
'(?< ?> ?!))))))))) (forward-line 1)
(if (or (not found) ; not an assignment (while (and (< (point) startpos)
(looking-at "[ \t]*\\\\")) ; <=><spaces><backslash> (looking-at "[ \t]*[#\n\\\\]")) ; skip noise
(progn (forward-line 1))
(goto-char startpos) (if (< (point) startpos)
(skip-chars-forward "^ \t\n"))) ;; again mimic the first list item
(1+ (current-column)))))) (current-indentation)
;; else they're about to enter the first item
(goto-char open-bracket-pos)
(+ (current-indentation) py-indent-offset))))
;; not on a continuation line ;; else on backslash continuation line
(forward-line -1)
(if (py-continuation-line-p) ; on at least 3rd line in block
(current-indentation) ; so just continue the pattern
;; else started on 2nd line in block, so indent more.
;; if base line is an assignment with a start on a RHS,
;; indent to 2 beyond the leftmost "="; else skip first
;; chunk of non-whitespace characters on base line, + 1 more
;; column
(end-of-line)
(setq endpos (point) searching t)
(back-to-indentation)
(setq startpos (point))
;; look at all "=" from left to right, stopping at first
;; one not nested in a list or string
(while searching
(skip-chars-forward "^=" endpos)
(if (= (point) endpos)
(setq searching nil)
(forward-char 1)
(setq state (parse-partial-sexp startpos (point)))
(if (and (zerop (car state)) ; not in a bracket
(null (nth 3 state))) ; & not in a string
(progn
(setq searching nil) ; done searching in any case
(setq found
(not (or
(eq (following-char) ?=)
(memq (char-after (- (point) 2))
'(?< ?> ?!)))))))))
(if (or (not found) ; not an assignment
(looking-at "[ \t]*\\\\")) ; <=><spaces><backslash>
(progn
(goto-char startpos)
(skip-chars-forward "^ \t\n")))
(1+ (current-column))))))
;; if at start of restriction, or on a non-indenting comment line, ;; not on a continuation line
;; assume they intended whatever's there
((or (bobp) (looking-at "[ \t]*#[^ \t\n]"))
(current-indentation))
;; else indentation based on that of the statement that precedes ;; if at start of restriction, or on a non-indenting comment
;; us; use the first line of that statement to establish the base, ;; line, assume they intended whatever's there
;; in case the user forced a non-std indentation for the ((or (bobp) (looking-at "[ \t]*#[^ \t\n]"))
;; continuation lines (if any) (current-indentation))
(t
;; skip back over blank & non-indenting comment lines ;; else indentation based on that of the statement that
;; note: will skip a blank or non-indenting comment line that ;; precedes us; use the first line of that statement to
;; happens to be a continuation line too ;; establish the base, in case the user forced a non-std
(re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" ;; indentation for the continuation lines (if any)
nil 'move) (t
;; if we landed inside a string, go to the beginning of that ;; skip back over blank & non-indenting comment lines note:
;; string. this handles triple quoted, multi-line spanning ;; will skip a blank or non-indenting comment line that
;; strings. ;; happens to be a continuation line too
(let ((state (parse-partial-sexp (re-search-backward "^[ \t]*\\([^ \t\n#]\\|#[ \t\n]\\)" nil 'move)
(save-excursion (beginning-of-python-def-or-class) ;; if we landed inside a string, go to the beginning of that
(point)) ;; string. this handles triple quoted, multi-line spanning
(point)))) ;; strings.
(if (nth 3 state) (py-goto-initial-line)
(goto-char (nth 2 state)))) (if (py-statement-opens-block-p)
(py-goto-initial-line) (+ (current-indentation) py-indent-offset)
(if (py-statement-opens-block-p) (current-indentation)))))))
(+ (current-indentation) py-indent-offset)
(current-indentation))))))
(defun py-guess-indent-offset (&optional global) (defun py-guess-indent-offset (&optional global)
"Guess a good value for, and change, `py-indent-offset'. "Guess a good value for, and change, `py-indent-offset'.
@ -1964,7 +1988,7 @@ local bindings to py-newline-and-indent."))
(setq zmacs-region-stays t))) (setq zmacs-region-stays t)))
(defconst py-version "2.26" (defconst py-version "2.30"
"`python-mode' version number.") "`python-mode' version number.")
(defconst py-help-address "python-mode@python.org" (defconst py-help-address "python-mode@python.org"
"Address accepting submission of bug reports.") "Address accepting submission of bug reports.")