mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 02:31:03 -08:00
Fix dedenters and electric colon handling.
* lisp/progmodes/python.el (python-rx-constituents): Add dedenter and block-ender. (python-indent-dedenters, python-indent-block-enders): Delete. (python-indent-context): Return new case for dedenter-statement. (python-indent-calculate-indentation): Handle new case. (python-indent-calculate-levels): Fix levels calculation for dedenter statements. (python-indent-post-self-insert-function): Fix colon handling. (python-info-dedenter-opening-block-message): New function. (python-indent-line): Use it. (python-info-closing-block) (python-info-closing-block-message): Remove. (python-info-dedenter-opening-block-position) (python-info-dedenter-opening-block-positions) (python-info-dedenter-statement-p): New functions. * test/automated/python-tests.el (python-indent-block-enders-1) (python-indent-block-enders-2): Fix tests. (python-indent-block-enders-3) (python-indent-block-enders-4) (python-indent-block-enders-5) (python-indent-dedenters-1) (python-indent-dedenters-2): Remove tests. (python-indent-dedenters-1) (python-indent-dedenters-2) (python-indent-dedenters-3) (python-indent-dedenters-4) (python-indent-dedenters-5) (python-indent-dedenters-6) (python-indent-dedenters-7) (python-info-dedenter-opening-block-position-1) (python-info-dedenter-opening-block-position-2) (python-info-dedenter-opening-block-position-3) (python-info-dedenter-opening-block-positions-1) (python-info-dedenter-opening-block-positions-2) (python-info-dedenter-opening-block-positions-3) (python-info-dedenter-opening-block-positions-4) (python-info-dedenter-opening-block-positions-5) (python-info-dedenter-opening-block-message-1) (python-info-dedenter-opening-block-message-2) (python-info-dedenter-opening-block-message-3) (python-info-dedenter-opening-block-message-4) (python-info-dedenter-opening-block-message-5) (python-info-dedenter-statement-p-1) (python-info-dedenter-statement-p-2) (python-info-dedenter-statement-p-3) (python-info-dedenter-statement-p-4) (python-info-dedenter-statement-p-5): New tests. Fixes: debbugs:15163
This commit is contained in:
parent
d8899d09b9
commit
fded0b4a15
4 changed files with 814 additions and 193 deletions
|
|
@ -1,3 +1,23 @@
|
|||
2014-07-09 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
Fix dedenters and electric colon handling. (Bug#15163)
|
||||
|
||||
* progmodes/python.el
|
||||
(python-rx-constituents): Add dedenter and block-ender.
|
||||
(python-indent-dedenters, python-indent-block-enders): Delete.
|
||||
(python-indent-context): Return new case for dedenter-statement.
|
||||
(python-indent-calculate-indentation): Handle new case.
|
||||
(python-indent-calculate-levels): Fix levels calculation for
|
||||
dedenter statements.
|
||||
(python-indent-post-self-insert-function): Fix colon handling.
|
||||
(python-info-dedenter-opening-block-message): New function.
|
||||
(python-indent-line): Use it.
|
||||
(python-info-closing-block)
|
||||
(python-info-closing-block-message): Remove.
|
||||
(python-info-dedenter-opening-block-position)
|
||||
(python-info-dedenter-opening-block-positions)
|
||||
(python-info-dedenter-statement-p): New functions.
|
||||
|
||||
2014-07-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* progmodes/sh-script.el (sh-smie-sh-rules): Don't align with a && in
|
||||
|
|
|
|||
|
|
@ -322,6 +322,13 @@
|
|||
(or "def" "class" "if" "elif" "else" "try"
|
||||
"except" "finally" "for" "while" "with")
|
||||
symbol-end))
|
||||
(dedenter . ,(rx symbol-start
|
||||
(or "elif" "else" "except" "finally")
|
||||
symbol-end))
|
||||
(block-ender . ,(rx symbol-start
|
||||
(or
|
||||
"break" "continue" "pass" "raise" "return")
|
||||
symbol-end))
|
||||
(decorator . ,(rx line-start (* space) ?@ (any letter ?_)
|
||||
(* (any word ?_))))
|
||||
(defun . ,(rx symbol-start (or "def" "class") symbol-end))
|
||||
|
|
@ -631,18 +638,6 @@ It makes underscores and dots word constituent chars.")
|
|||
(defvar python-indent-levels '(0)
|
||||
"Levels of indentation available for `python-indent-line-function'.")
|
||||
|
||||
(defvar python-indent-dedenters '("else" "elif" "except" "finally")
|
||||
"List of words that should be dedented.
|
||||
These make `python-indent-calculate-indentation' subtract the value of
|
||||
`python-indent-offset'.")
|
||||
|
||||
(defvar python-indent-block-enders
|
||||
'("break" "continue" "pass" "raise" "return")
|
||||
"List of words that mark the end of a block.
|
||||
These make `python-indent-calculate-indentation' subtract the
|
||||
value of `python-indent-offset' when `python-indent-context' is
|
||||
AFTER-LINE.")
|
||||
|
||||
(defun python-indent-guess-indent-offset ()
|
||||
"Guess and set `python-indent-offset' for the current buffer."
|
||||
(interactive)
|
||||
|
|
@ -693,6 +688,7 @@ Where status can be any of the following symbols:
|
|||
* after-backslash: Previous line ends in a backslash
|
||||
* after-beginning-of-block: Point is after beginning of block
|
||||
* after-line: Point is after normal line
|
||||
* dedenter-statement: Point is on a dedenter statement.
|
||||
* no-indent: Point is at beginning of buffer or other special case
|
||||
START is the buffer position where the sexp starts."
|
||||
(save-restriction
|
||||
|
|
@ -747,6 +743,8 @@ START is the buffer position where the sexp starts."
|
|||
(when (looking-at (python-rx block-start))
|
||||
(point-marker)))))
|
||||
'after-beginning-of-block)
|
||||
((when (setq start (python-info-dedenter-statement-p))
|
||||
'dedenter-statement))
|
||||
;; After normal line
|
||||
((setq start (save-excursion
|
||||
(back-to-indentation)
|
||||
|
|
@ -777,8 +775,7 @@ START is the buffer position where the sexp starts."
|
|||
(goto-char context-start)
|
||||
(+ (current-indentation) python-indent-offset))
|
||||
;; When after a simple line just use previous line
|
||||
;; indentation, in the case current line starts with a
|
||||
;; `python-indent-dedenters' de-indent one level.
|
||||
;; indentation.
|
||||
(`after-line
|
||||
(let* ((pair (save-excursion
|
||||
(goto-char context-start)
|
||||
|
|
@ -786,25 +783,27 @@ START is the buffer position where the sexp starts."
|
|||
(current-indentation)
|
||||
(python-info-beginning-of-block-p))))
|
||||
(context-indentation (car pair))
|
||||
(after-block-start-p (cdr pair))
|
||||
;; TODO: Separate block enders into its own case.
|
||||
(adjustment
|
||||
(if (or (save-excursion
|
||||
(back-to-indentation)
|
||||
(and
|
||||
;; De-indent only when dedenters are not
|
||||
;; next to a block start. This allows
|
||||
;; one-liner constructs such as:
|
||||
;; if condition: print "yay"
|
||||
;; else: print "wry"
|
||||
(not after-block-start-p)
|
||||
(looking-at (regexp-opt python-indent-dedenters))))
|
||||
(save-excursion
|
||||
(python-util-forward-comment -1)
|
||||
(python-nav-beginning-of-statement)
|
||||
(looking-at (regexp-opt python-indent-block-enders))))
|
||||
(if (save-excursion
|
||||
(python-util-forward-comment -1)
|
||||
(python-nav-beginning-of-statement)
|
||||
(looking-at (python-rx block-ender)))
|
||||
python-indent-offset
|
||||
0)))
|
||||
(- context-indentation adjustment)))
|
||||
;; When point is on a dedenter statement, search for the
|
||||
;; opening block that corresponds to it and use its
|
||||
;; indentation. If no opening block is found just remove
|
||||
;; indentation as this is an invalid python file.
|
||||
(`dedenter-statement
|
||||
(let ((block-start-point
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
(save-excursion
|
||||
(if (not block-start-point)
|
||||
0
|
||||
(goto-char block-start-point)
|
||||
(current-indentation)))))
|
||||
;; When inside of a string, do nothing. just use the current
|
||||
;; indentation. XXX: perhaps it would be a good idea to
|
||||
;; invoke standard text indentation here
|
||||
|
|
@ -931,16 +930,25 @@ START is the buffer position where the sexp starts."
|
|||
|
||||
(defun python-indent-calculate-levels ()
|
||||
"Calculate `python-indent-levels' and reset `python-indent-current-level'."
|
||||
(let* ((indentation (python-indent-calculate-indentation))
|
||||
(remainder (% indentation python-indent-offset))
|
||||
(steps (/ (- indentation remainder) python-indent-offset)))
|
||||
(setq python-indent-levels (list 0))
|
||||
(dotimes (step steps)
|
||||
(push (* python-indent-offset (1+ step)) python-indent-levels))
|
||||
(when (not (eq 0 remainder))
|
||||
(push (+ (* python-indent-offset steps) remainder) python-indent-levels))
|
||||
(setq python-indent-levels (nreverse python-indent-levels))
|
||||
(setq python-indent-current-level (1- (length python-indent-levels)))))
|
||||
(if (not (python-info-dedenter-statement-p))
|
||||
(let* ((indentation (python-indent-calculate-indentation))
|
||||
(remainder (% indentation python-indent-offset))
|
||||
(steps (/ (- indentation remainder) python-indent-offset)))
|
||||
(setq python-indent-levels (list 0))
|
||||
(dotimes (step steps)
|
||||
(push (* python-indent-offset (1+ step)) python-indent-levels))
|
||||
(when (not (eq 0 remainder))
|
||||
(push (+ (* python-indent-offset steps) remainder) python-indent-levels)))
|
||||
(setq python-indent-levels
|
||||
(or
|
||||
(mapcar (lambda (pos)
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(current-indentation)))
|
||||
(python-info-dedenter-opening-block-positions))
|
||||
(list 0))))
|
||||
(setq python-indent-current-level (1- (length python-indent-levels))
|
||||
python-indent-levels (nreverse python-indent-levels)))
|
||||
|
||||
(defun python-indent-toggle-levels ()
|
||||
"Toggle `python-indent-current-level' over `python-indent-levels'."
|
||||
|
|
@ -989,7 +997,7 @@ equal to
|
|||
(indent-to next-indent)
|
||||
(goto-char starting-pos))
|
||||
(and follow-indentation-p (back-to-indentation)))
|
||||
(python-info-closing-block-message))
|
||||
(python-info-dedenter-opening-block-message))
|
||||
|
||||
(defun python-indent-line-function ()
|
||||
"`indent-line-function' for Python mode.
|
||||
|
|
@ -1125,14 +1133,7 @@ the line will be re-indented automatically if needed."
|
|||
(eolp)
|
||||
(not (equal ?: (char-before (1- (point)))))
|
||||
(not (python-syntax-comment-or-string-p)))
|
||||
(let ((indentation (current-indentation))
|
||||
(calculated-indentation (python-indent-calculate-indentation)))
|
||||
(python-info-closing-block-message)
|
||||
(when (> indentation calculated-indentation)
|
||||
(save-excursion
|
||||
(indent-line-to calculated-indentation)
|
||||
(when (not (python-info-closing-block-message))
|
||||
(indent-line-to indentation)))))))))
|
||||
(python-indent-line)))))
|
||||
|
||||
|
||||
;;; Navigation
|
||||
|
|
@ -3450,49 +3451,88 @@ parent defun name."
|
|||
(and (python-info-end-of-statement-p)
|
||||
(python-info-statement-ends-block-p)))
|
||||
|
||||
(defun python-info-closing-block ()
|
||||
"Return the point of the block the current line closes."
|
||||
(let ((closing-word (save-excursion
|
||||
(back-to-indentation)
|
||||
(current-word)))
|
||||
(indentation (current-indentation)))
|
||||
(when (member closing-word python-indent-dedenters)
|
||||
(save-excursion
|
||||
(forward-line -1)
|
||||
(while (and (> (current-indentation) indentation)
|
||||
(not (bobp))
|
||||
(not (back-to-indentation))
|
||||
(forward-line -1)))
|
||||
(back-to-indentation)
|
||||
(cond
|
||||
((not (equal indentation (current-indentation))) nil)
|
||||
((string= closing-word "elif")
|
||||
(when (member (current-word) '("if" "elif"))
|
||||
(point-marker)))
|
||||
((string= closing-word "else")
|
||||
(when (member (current-word) '("if" "elif" "except" "for" "while"))
|
||||
(point-marker)))
|
||||
((string= closing-word "except")
|
||||
(when (member (current-word) '("try"))
|
||||
(point-marker)))
|
||||
((string= closing-word "finally")
|
||||
(when (member (current-word) '("except" "else"))
|
||||
(point-marker))))))))
|
||||
(define-obsolete-function-alias
|
||||
'python-info-closing-block
|
||||
'python-info-dedenter-opening-block-position "24.4")
|
||||
|
||||
(defun python-info-closing-block-message (&optional closing-block-point)
|
||||
"Message the contents of the block the current line closes.
|
||||
With optional argument CLOSING-BLOCK-POINT use that instead of
|
||||
recalculating it calling `python-info-closing-block'."
|
||||
(let ((point (or closing-block-point (python-info-closing-block))))
|
||||
(defun python-info-dedenter-opening-block-position ()
|
||||
"Return the point of the closest block the current line closes.
|
||||
Returns nil if point is not on a dedenter statement or no opening
|
||||
block can be detected. The latter case meaning current file is
|
||||
likely an invalid python file."
|
||||
(let ((positions (python-info-dedenter-opening-block-positions))
|
||||
(indentation (current-indentation))
|
||||
(position))
|
||||
(while (and (not position)
|
||||
positions)
|
||||
(save-excursion
|
||||
(goto-char (car positions))
|
||||
(if (<= (current-indentation) indentation)
|
||||
(setq position (car positions))
|
||||
(setq positions (cdr positions)))))
|
||||
position))
|
||||
|
||||
(defun python-info-dedenter-opening-block-positions ()
|
||||
"Return points of blocks the current line may close sorted by closer.
|
||||
Returns nil if point is not on a dedenter statement or no opening
|
||||
block can be detected. The latter case meaning current file is
|
||||
likely an invalid python file."
|
||||
(save-excursion
|
||||
(let ((dedenter-pos (python-info-dedenter-statement-p)))
|
||||
(when dedenter-pos
|
||||
(goto-char dedenter-pos)
|
||||
(let* ((pairs '(("elif" "elif" "if")
|
||||
("else" "if" "elif" "except" "for" "while")
|
||||
("except" "except" "try")
|
||||
("finally" "else" "except" "try")))
|
||||
(dedenter (match-string-no-properties 0))
|
||||
(possible-opening-blocks (cdr (assoc-string dedenter pairs)))
|
||||
(collected-indentations)
|
||||
(opening-blocks))
|
||||
(catch 'exit
|
||||
(while (python-nav--syntactically
|
||||
(lambda ()
|
||||
(re-search-backward (python-rx block-start) nil t))
|
||||
#'<)
|
||||
(let ((indentation (current-indentation)))
|
||||
(when (and (not (memq indentation collected-indentations))
|
||||
(or (not collected-indentations)
|
||||
(< indentation (apply #'min collected-indentations))))
|
||||
(setq collected-indentations
|
||||
(cons indentation collected-indentations))
|
||||
(when (member (match-string-no-properties 0)
|
||||
possible-opening-blocks)
|
||||
(setq opening-blocks (cons (point) opening-blocks))))
|
||||
(when (zerop indentation)
|
||||
(throw 'exit nil)))))
|
||||
;; sort by closer
|
||||
(nreverse opening-blocks))))))
|
||||
|
||||
(define-obsolete-function-alias
|
||||
'python-info-closing-block-message
|
||||
'python-info-dedenter-opening-block-message "24.4")
|
||||
|
||||
(defun python-info-dedenter-opening-block-message ()
|
||||
"Message the first line of the block the current statement closes."
|
||||
(let ((point (python-info-dedenter-opening-block-position)))
|
||||
(when point
|
||||
(save-restriction
|
||||
(widen)
|
||||
(message "Closes %s" (save-excursion
|
||||
(goto-char point)
|
||||
(back-to-indentation)
|
||||
(buffer-substring
|
||||
(point) (line-end-position))))))))
|
||||
|
||||
(defun python-info-dedenter-statement-p ()
|
||||
"Return point if current statement is a dedenter.
|
||||
Sets `match-data' to the keyword that starts the dedenter
|
||||
statement."
|
||||
(save-excursion
|
||||
(python-nav-beginning-of-statement)
|
||||
(when (and (not (python-syntax-context-type))
|
||||
(looking-at (python-rx dedenter)))
|
||||
(point))))
|
||||
|
||||
(defun python-info-line-ends-backslash-p (&optional line-number)
|
||||
"Return non-nil if current line ends with backslash.
|
||||
With optional argument LINE-NUMBER, check that line instead."
|
||||
|
|
|
|||
|
|
@ -1,3 +1,40 @@
|
|||
2014-07-09 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
* automated/python-tests.el
|
||||
(python-indent-block-enders-1)
|
||||
(python-indent-block-enders-2): Fix tests.
|
||||
(python-indent-block-enders-3)
|
||||
(python-indent-block-enders-4)
|
||||
(python-indent-block-enders-5)
|
||||
(python-indent-dedenters-1)
|
||||
(python-indent-dedenters-2): Remove tests.
|
||||
(python-indent-dedenters-1)
|
||||
(python-indent-dedenters-2)
|
||||
(python-indent-dedenters-3)
|
||||
(python-indent-dedenters-4)
|
||||
(python-indent-dedenters-5)
|
||||
(python-indent-dedenters-6)
|
||||
(python-indent-dedenters-7)
|
||||
(python-info-dedenter-opening-block-position-1)
|
||||
(python-info-dedenter-opening-block-position-2)
|
||||
(python-info-dedenter-opening-block-position-3)
|
||||
(python-info-dedenter-opening-block-positions-1)
|
||||
(python-info-dedenter-opening-block-positions-2)
|
||||
(python-info-dedenter-opening-block-positions-3)
|
||||
(python-info-dedenter-opening-block-positions-4)
|
||||
(python-info-dedenter-opening-block-positions-5)
|
||||
(python-info-dedenter-opening-block-message-1)
|
||||
(python-info-dedenter-opening-block-message-2)
|
||||
(python-info-dedenter-opening-block-message-3)
|
||||
(python-info-dedenter-opening-block-message-4)
|
||||
(python-info-dedenter-opening-block-message-5)
|
||||
(python-info-dedenter-statement-p-1)
|
||||
(python-info-dedenter-statement-p-2)
|
||||
(python-info-dedenter-statement-p-3)
|
||||
(python-info-dedenter-statement-p-4)
|
||||
(python-info-dedenter-statement-p-5): New tests.
|
||||
|
||||
|
||||
2014-07-01 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
* automated/python-tests.el
|
||||
|
|
|
|||
|
|
@ -435,79 +435,6 @@ def foo(a, b, c={
|
|||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 4))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-1 ()
|
||||
"Check all dedenters."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
def foo(a, b, c):
|
||||
if a:
|
||||
print (a)
|
||||
elif b:
|
||||
print (b)
|
||||
else:
|
||||
try:
|
||||
print (c.pop())
|
||||
except (IndexError, AttributeError):
|
||||
print (c)
|
||||
finally:
|
||||
print ('nor a, nor b are true')
|
||||
"
|
||||
(python-tests-look-at "if a:")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "print (a)")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "elif b:")
|
||||
(should (eq (car (python-indent-context)) 'after-line))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "print (b)")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "else:")
|
||||
(should (eq (car (python-indent-context)) 'after-line))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "try:")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "print (c.pop())")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 12))
|
||||
(python-tests-look-at "except (IndexError, AttributeError):")
|
||||
(should (eq (car (python-indent-context)) 'after-line))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "print (c)")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 12))
|
||||
(python-tests-look-at "finally:")
|
||||
(should (eq (car (python-indent-context)) 'after-line))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "print ('nor a, nor b are true')")
|
||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
||||
(should (= (python-indent-calculate-indentation) 12))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-2 ()
|
||||
"Check one-liner block special case.."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
cond = True
|
||||
if cond:
|
||||
|
||||
if cond: print 'True'
|
||||
else: print 'False'
|
||||
|
||||
else:
|
||||
return
|
||||
"
|
||||
(python-tests-look-at "else: print 'False'")
|
||||
;; When a block has code after ":" it's just considered a simple
|
||||
;; line as that's a common thing to happen in one-liners.
|
||||
(should (eq (car (python-indent-context)) 'after-line))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "else:")
|
||||
(should (eq (car (python-indent-context)) 'after-line))
|
||||
(should (= (python-indent-calculate-indentation) 0))))
|
||||
|
||||
(ert-deftest python-indent-after-backslash-1 ()
|
||||
"The most common case."
|
||||
(python-tests-with-temp-buffer
|
||||
|
|
@ -575,9 +502,9 @@ objects = Thing.objects.all() \\\\
|
|||
(should (= (python-indent-calculate-indentation) 0))))
|
||||
|
||||
(ert-deftest python-indent-block-enders-1 ()
|
||||
"Test `python-indent-block-enders' value honoring."
|
||||
"Test de-indentation for pass keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
"
|
||||
Class foo(object):
|
||||
|
||||
def bar(self):
|
||||
|
|
@ -589,17 +516,17 @@ Class foo(object):
|
|||
else:
|
||||
pass
|
||||
"
|
||||
(python-tests-look-at "3)")
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "pass")
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 8))))
|
||||
(python-tests-look-at "3)")
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "pass")
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 8))))
|
||||
|
||||
(ert-deftest python-indent-block-enders-2 ()
|
||||
"Test `python-indent-block-enders' value honoring."
|
||||
"Test de-indentation for return keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
"
|
||||
Class foo(object):
|
||||
'''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
||||
|
||||
|
|
@ -612,10 +539,177 @@ Class foo(object):
|
|||
2,
|
||||
3)
|
||||
"
|
||||
(python-tests-look-at "def")
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "if")
|
||||
(should (= (python-indent-calculate-indentation) 8))))
|
||||
(python-tests-look-at "def")
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "if")
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(python-tests-look-at "return")
|
||||
(should (= (python-indent-calculate-indentation) 12))
|
||||
(goto-char (point-max))
|
||||
(should (= (python-indent-calculate-indentation) 8))))
|
||||
|
||||
(ert-deftest python-indent-block-enders-3 ()
|
||||
"Test de-indentation for continue keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
for element in lst:
|
||||
if element is None:
|
||||
continue
|
||||
"
|
||||
(python-tests-look-at "if")
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "continue")
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 4))))
|
||||
|
||||
(ert-deftest python-indent-block-enders-4 ()
|
||||
"Test de-indentation for break keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
for element in lst:
|
||||
if element is None:
|
||||
break
|
||||
"
|
||||
(python-tests-look-at "if")
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "break")
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 4))))
|
||||
|
||||
(ert-deftest python-indent-block-enders-5 ()
|
||||
"Test de-indentation for raise keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
for element in lst:
|
||||
if element is None:
|
||||
raise ValueError('Element cannot be None')
|
||||
"
|
||||
(python-tests-look-at "if")
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "raise")
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(forward-line 1)
|
||||
(should (= (python-indent-calculate-indentation) 4))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-1 ()
|
||||
"Test de-indentation for the elif keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
finally:
|
||||
cleanup()
|
||||
elif
|
||||
"
|
||||
(python-tests-look-at "elif\n")
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (equal (python-indent-calculate-levels) '(0)))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-2 ()
|
||||
"Test de-indentation for the else keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
except IOError:
|
||||
msg = 'Error saving to disk'
|
||||
message(msg)
|
||||
logger.exception(msg)
|
||||
except Exception:
|
||||
if hide_details:
|
||||
logger.exception('Unhandled exception')
|
||||
else
|
||||
finally:
|
||||
data.free()
|
||||
"
|
||||
(python-tests-look-at "else\n")
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(should (equal (python-indent-calculate-levels) '(0 4 8)))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-3 ()
|
||||
"Test de-indentation for the except keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
except
|
||||
"
|
||||
(python-tests-look-at "except\n")
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(should (equal (python-indent-calculate-levels) '(4)))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-4 ()
|
||||
"Test de-indentation for the finally keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
finally
|
||||
"
|
||||
(python-tests-look-at "finally\n")
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(should (equal (python-indent-calculate-levels) '(4)))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-5 ()
|
||||
"Test invalid levels are skipped in a complex example."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
except IOError:
|
||||
msg = 'Error saving to disk'
|
||||
message(msg)
|
||||
logger.exception(msg)
|
||||
finally:
|
||||
if cleanup:
|
||||
do_cleanup()
|
||||
else
|
||||
"
|
||||
(python-tests-look-at "else\n")
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 8))
|
||||
(should (equal (python-indent-calculate-levels) '(0 8)))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-6 ()
|
||||
"Test indentation is zero when no opening block for dedenter."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
# if save:
|
||||
write_to_disk(data)
|
||||
else
|
||||
"
|
||||
(python-tests-look-at "else\n")
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (equal (python-indent-calculate-levels) '(0)))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-7 ()
|
||||
"Test indentation case from Bug#15163."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if a:
|
||||
if b:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
"
|
||||
(python-tests-look-at "else:" 2)
|
||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (equal (python-indent-calculate-levels) '(0)))))
|
||||
|
||||
|
||||
;;; Navigation
|
||||
|
|
@ -2428,9 +2522,9 @@ if width == 0 and height == 0 and \\\\
|
|||
(python-util-forward-comment -1)
|
||||
(should (python-info-end-of-block-p))))
|
||||
|
||||
(ert-deftest python-info-closing-block-1 ()
|
||||
(ert-deftest python-info-dedenter-opening-block-position-1 ()
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
"
|
||||
if request.user.is_authenticated():
|
||||
try:
|
||||
profile = request.user.get_profile()
|
||||
|
|
@ -2445,26 +2539,26 @@ if request.user.is_authenticated():
|
|||
profile.views += 1
|
||||
profile.save()
|
||||
"
|
||||
(python-tests-look-at "try:")
|
||||
(should (not (python-info-closing-block)))
|
||||
(python-tests-look-at "except Profile.DoesNotExist:")
|
||||
(should (= (python-tests-look-at "try:" -1 t)
|
||||
(python-info-closing-block)))
|
||||
(python-tests-look-at "else:")
|
||||
(should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
|
||||
(python-info-closing-block)))
|
||||
(python-tests-look-at "if profile.stats:")
|
||||
(should (not (python-info-closing-block)))
|
||||
(python-tests-look-at "else:")
|
||||
(should (= (python-tests-look-at "if profile.stats:" -1 t)
|
||||
(python-info-closing-block)))
|
||||
(python-tests-look-at "finally:")
|
||||
(should (= (python-tests-look-at "else:" -2 t)
|
||||
(python-info-closing-block)))))
|
||||
(python-tests-look-at "try:")
|
||||
(should (not (python-info-dedenter-opening-block-position)))
|
||||
(python-tests-look-at "except Profile.DoesNotExist:")
|
||||
(should (= (python-tests-look-at "try:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
(python-tests-look-at "else:")
|
||||
(should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
(python-tests-look-at "if profile.stats:")
|
||||
(should (not (python-info-dedenter-opening-block-position)))
|
||||
(python-tests-look-at "else:")
|
||||
(should (= (python-tests-look-at "if profile.stats:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
(python-tests-look-at "finally:")
|
||||
(should (= (python-tests-look-at "else:" -2 t)
|
||||
(python-info-dedenter-opening-block-position)))))
|
||||
|
||||
(ert-deftest python-info-closing-block-2 ()
|
||||
(ert-deftest python-info-dedenter-opening-block-position-2 ()
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
"
|
||||
if request.user.is_authenticated():
|
||||
profile = Profile.objects.get_or_create(user=request.user)
|
||||
if profile.stats:
|
||||
|
|
@ -2475,10 +2569,440 @@ data = {
|
|||
}
|
||||
'else'
|
||||
"
|
||||
(python-tests-look-at "'else': 'do it'")
|
||||
(should (not (python-info-closing-block)))
|
||||
(python-tests-look-at "'else'")
|
||||
(should (not (python-info-closing-block)))))
|
||||
(python-tests-look-at "'else': 'do it'")
|
||||
(should (not (python-info-dedenter-opening-block-position)))
|
||||
(python-tests-look-at "'else'")
|
||||
(should (not (python-info-dedenter-opening-block-position)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-position-3 ()
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
except IOError:
|
||||
msg = 'Error saving to disk'
|
||||
message(msg)
|
||||
logger.exception(msg)
|
||||
except Exception:
|
||||
if hide_details:
|
||||
logger.exception('Unhandled exception')
|
||||
else
|
||||
finally:
|
||||
data.free()
|
||||
"
|
||||
(python-tests-look-at "try:")
|
||||
(should (not (python-info-dedenter-opening-block-position)))
|
||||
|
||||
(python-tests-look-at "except IOError:")
|
||||
(should (= (python-tests-look-at "try:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
|
||||
(python-tests-look-at "except Exception:")
|
||||
(should (= (python-tests-look-at "except IOError:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
|
||||
(python-tests-look-at "if hide_details:")
|
||||
(should (not (python-info-dedenter-opening-block-position)))
|
||||
|
||||
;; check indentation modifies the detected opening block
|
||||
(python-tests-look-at "else")
|
||||
(should (= (python-tests-look-at "if hide_details:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
|
||||
(indent-line-to 8)
|
||||
(should (= (python-tests-look-at "if hide_details:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
|
||||
(indent-line-to 4)
|
||||
(should (= (python-tests-look-at "except Exception:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))
|
||||
|
||||
(indent-line-to 0)
|
||||
(should (= (python-tests-look-at "if save:" -1 t)
|
||||
(python-info-dedenter-opening-block-position)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-positions-1 ()
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if save:
|
||||
try:
|
||||
write_to_disk(data)
|
||||
except IOError:
|
||||
msg = 'Error saving to disk'
|
||||
message(msg)
|
||||
logger.exception(msg)
|
||||
except Exception:
|
||||
if hide_details:
|
||||
logger.exception('Unhandled exception')
|
||||
else
|
||||
finally:
|
||||
data.free()
|
||||
"
|
||||
(python-tests-look-at "try:")
|
||||
(should (not (python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "except IOError:")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "try:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "except Exception:")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "except IOError:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "if hide_details:")
|
||||
(should (not (python-info-dedenter-opening-block-positions)))
|
||||
|
||||
;; check indentation does not modify the detected opening blocks
|
||||
(python-tests-look-at "else")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "if hide_details:" -1 t)
|
||||
(python-tests-look-at "except Exception:" -1 t)
|
||||
(python-tests-look-at "if save:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(indent-line-to 8)
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "if hide_details:" -1 t)
|
||||
(python-tests-look-at "except Exception:" -1 t)
|
||||
(python-tests-look-at "if save:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(indent-line-to 4)
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "if hide_details:" -1 t)
|
||||
(python-tests-look-at "except Exception:" -1 t)
|
||||
(python-tests-look-at "if save:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(indent-line-to 0)
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "if hide_details:" -1 t)
|
||||
(python-tests-look-at "except Exception:" -1 t)
|
||||
(python-tests-look-at "if save:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-positions-2 ()
|
||||
"Test detection of opening blocks for elif."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if var:
|
||||
if var2:
|
||||
something()
|
||||
elif var3:
|
||||
something_else()
|
||||
elif
|
||||
"
|
||||
(python-tests-look-at "elif var3:")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "if var2:" -1 t)
|
||||
(python-tests-look-at "if var:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "elif\n")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "elif var3:" -1 t)
|
||||
(python-tests-look-at "if var:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-positions-3 ()
|
||||
"Test detection of opening blocks for else."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
if var:
|
||||
if var2:
|
||||
something()
|
||||
elif var3:
|
||||
something_else()
|
||||
else
|
||||
|
||||
if var4:
|
||||
while var5:
|
||||
var4.pop()
|
||||
else
|
||||
|
||||
for value in var6:
|
||||
if value > 0:
|
||||
print value
|
||||
else
|
||||
"
|
||||
(python-tests-look-at "else\n")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "elif var3:" -1 t)
|
||||
(python-tests-look-at "if var:" -1 t)
|
||||
(python-tests-look-at "except:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "else\n")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "while var5:" -1 t)
|
||||
(python-tests-look-at "if var4:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "else\n")
|
||||
(should
|
||||
(equal (list
|
||||
(python-tests-look-at "if value > 0:" -1 t)
|
||||
(python-tests-look-at "for value in var6:" -1 t)
|
||||
(python-tests-look-at "if var4:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-positions-4 ()
|
||||
"Test detection of opening blocks for except."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except ValueError:
|
||||
something_else()
|
||||
except
|
||||
"
|
||||
(python-tests-look-at "except ValueError:")
|
||||
(should
|
||||
(equal (list (python-tests-look-at "try:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "except\n")
|
||||
(should
|
||||
(equal (list (python-tests-look-at "except ValueError:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-positions-5 ()
|
||||
"Test detection of opening blocks for finally."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
finally
|
||||
|
||||
try:
|
||||
something_else()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
finally
|
||||
|
||||
try:
|
||||
something_else_else()
|
||||
except Exception:
|
||||
logger.exception('something else went wrong')
|
||||
else:
|
||||
print ('all good')
|
||||
finally
|
||||
"
|
||||
(python-tests-look-at "finally\n")
|
||||
(should
|
||||
(equal (list (python-tests-look-at "try:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "finally\n")
|
||||
(should
|
||||
(equal (list (python-tests-look-at "except:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
|
||||
(python-tests-look-at "finally\n")
|
||||
(should
|
||||
(equal (list (python-tests-look-at "else:" -1 t))
|
||||
(python-info-dedenter-opening-block-positions)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-message-1 ()
|
||||
"Test dedenters inside strings are ignored."
|
||||
(python-tests-with-temp-buffer
|
||||
"'''
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
'''
|
||||
"
|
||||
(python-tests-look-at "except\n")
|
||||
(should (not (python-info-dedenter-opening-block-message)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-message-2 ()
|
||||
"Test except keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
"
|
||||
(python-tests-look-at "except:")
|
||||
(should (string=
|
||||
"Closes try:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))
|
||||
(end-of-line)
|
||||
(should (string=
|
||||
"Closes try:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-message-3 ()
|
||||
"Test else keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
else:
|
||||
logger.debug('all good')
|
||||
"
|
||||
(python-tests-look-at "else:")
|
||||
(should (string=
|
||||
"Closes except:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))
|
||||
(end-of-line)
|
||||
(should (string=
|
||||
"Closes except:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-message-4 ()
|
||||
"Test finally keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
else:
|
||||
logger.debug('all good')
|
||||
finally:
|
||||
clean()
|
||||
"
|
||||
(python-tests-look-at "finally:")
|
||||
(should (string=
|
||||
"Closes else:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))
|
||||
(end-of-line)
|
||||
(should (string=
|
||||
"Closes else:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))))
|
||||
|
||||
(ert-deftest python-info-dedenter-opening-block-message-5 ()
|
||||
"Test elif keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if a:
|
||||
something()
|
||||
elif b:
|
||||
"
|
||||
(python-tests-look-at "elif b:")
|
||||
(should (string=
|
||||
"Closes if a:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))
|
||||
(end-of-line)
|
||||
(should (string=
|
||||
"Closes if a:"
|
||||
(substring-no-properties
|
||||
(python-info-dedenter-opening-block-message))))))
|
||||
|
||||
|
||||
(ert-deftest python-info-dedenter-statement-p-1 ()
|
||||
"Test dedenters inside strings are ignored."
|
||||
(python-tests-with-temp-buffer
|
||||
"'''
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
'''
|
||||
"
|
||||
(python-tests-look-at "except\n")
|
||||
(should (not (python-info-dedenter-statement-p)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-statement-p-2 ()
|
||||
"Test except keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
"
|
||||
(python-tests-look-at "except:")
|
||||
(should (= (point) (python-info-dedenter-statement-p)))
|
||||
(end-of-line)
|
||||
(should (= (save-excursion
|
||||
(back-to-indentation)
|
||||
(point))
|
||||
(python-info-dedenter-statement-p)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-statement-p-3 ()
|
||||
"Test else keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
else:
|
||||
logger.debug('all good')
|
||||
"
|
||||
(python-tests-look-at "else:")
|
||||
(should (= (point) (python-info-dedenter-statement-p)))
|
||||
(end-of-line)
|
||||
(should (= (save-excursion
|
||||
(back-to-indentation)
|
||||
(point))
|
||||
(python-info-dedenter-statement-p)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-statement-p-4 ()
|
||||
"Test finally keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
try:
|
||||
something()
|
||||
except:
|
||||
logger.exception('something went wrong')
|
||||
else:
|
||||
logger.debug('all good')
|
||||
finally:
|
||||
clean()
|
||||
"
|
||||
(python-tests-look-at "finally:")
|
||||
(should (= (point) (python-info-dedenter-statement-p)))
|
||||
(end-of-line)
|
||||
(should (= (save-excursion
|
||||
(back-to-indentation)
|
||||
(point))
|
||||
(python-info-dedenter-statement-p)))))
|
||||
|
||||
(ert-deftest python-info-dedenter-statement-p-5 ()
|
||||
"Test elif keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if a:
|
||||
something()
|
||||
elif b:
|
||||
"
|
||||
(python-tests-look-at "elif b:")
|
||||
(should (= (point) (python-info-dedenter-statement-p)))
|
||||
(end-of-line)
|
||||
(should (= (save-excursion
|
||||
(back-to-indentation)
|
||||
(point))
|
||||
(python-info-dedenter-statement-p)))))
|
||||
|
||||
(ert-deftest python-info-line-ends-backslash-p-1 ()
|
||||
(python-tests-with-temp-buffer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue