python.el: New non-global state dependent indentation engine.
Fixes: debbugs:18319 Fixes: debbugs:19595 * lisp/progmodes/python.el (python-syntax-comment-or-string-p): Accept PPSS as argument. (python-syntax-closing-paren-p): New function. (python-indent-current-level) (python-indent-levels): Mark obsolete. (python-indent-context): Return more context cases. (python-indent--calculate-indentation) (python-indent--calculate-levels): New functions. (python-indent-calculate-levels): Use them. (python-indent-calculate-indentation, python-indent-line): (python-indent-line-function): Rewritten to use new API. (python-indent-dedent-line): Simplify logic. (python-indent-dedent-line-backspace): Use `unless`. (python-indent-toggle-levels): Delete function. * test/automated/python-tests.el (python-indent-pep8-1) (python-indent-pep8-2, python-indent-pep8-3) (python-indent-after-comment-1, python-indent-after-comment-2) (python-indent-inside-paren-1, python-indent-inside-paren-2) (python-indent-after-block-1, python-indent-after-block-2) (python-indent-after-backslash-1, python-indent-after-backslash-2) (python-indent-after-backslash-3, python-indent-block-enders-1) (python-indent-block-enders-2, python-indent-block-enders-3) (python-indent-block-enders-4, python-indent-block-enders-5) (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-indent-dedenters-8): Fix tests. (python-indent-base-case, python-indent-after-block-3) (python-indent-after-backslash-5, python-indent-inside-paren-3) (python-indent-inside-paren-4, python-indent-inside-paren-5) (python-indent-inside-paren-6, python-indent-inside-string-1) (python-indent-inside-string-2, python-indent-inside-string-3) (python-indent-dedent-line-backspace-1): New Tests.
This commit is contained in:
parent
3b23e6a702
commit
5485e3e5b2
4 changed files with 825 additions and 471 deletions
|
@ -1,3 +1,23 @@
|
||||||
|
2015-01-26 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||||
|
|
||||||
|
python.el: New non-global state dependent indentation engine.
|
||||||
|
(Bug#18319, Bug#19595)
|
||||||
|
|
||||||
|
* progmodes/python.el (python-syntax-comment-or-string-p): Accept
|
||||||
|
PPSS as argument.
|
||||||
|
(python-syntax-closing-paren-p): New function.
|
||||||
|
(python-indent-current-level)
|
||||||
|
(python-indent-levels): Mark obsolete.
|
||||||
|
(python-indent-context): Return more context cases.
|
||||||
|
(python-indent--calculate-indentation)
|
||||||
|
(python-indent--calculate-levels): New functions.
|
||||||
|
(python-indent-calculate-levels): Use them.
|
||||||
|
(python-indent-calculate-indentation, python-indent-line):
|
||||||
|
(python-indent-line-function): Rewritten to use new API.
|
||||||
|
(python-indent-dedent-line): Simplify logic.
|
||||||
|
(python-indent-dedent-line-backspace): Use `unless`.
|
||||||
|
(python-indent-toggle-levels): Delete function.
|
||||||
|
|
||||||
2015-01-22 Wolfgang Jenkner <wjenkner@inode.at>
|
2015-01-22 Wolfgang Jenkner <wjenkner@inode.at>
|
||||||
|
|
||||||
* calc/calc-units.el (math-units-in-expr-p)
|
* calc/calc-units.el (math-units-in-expr-p)
|
||||||
|
|
|
@ -447,9 +447,14 @@ The type returned can be `comment', `string' or `paren'."
|
||||||
((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
|
((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
|
||||||
((nth 1 ppss) 'paren))))
|
((nth 1 ppss) 'paren))))
|
||||||
|
|
||||||
(defsubst python-syntax-comment-or-string-p ()
|
(defsubst python-syntax-comment-or-string-p (&optional ppss)
|
||||||
"Return non-nil if point is inside 'comment or 'string."
|
"Return non-nil if PPSS is inside 'comment or 'string."
|
||||||
(nth 8 (syntax-ppss)))
|
(nth 8 (or ppss (syntax-ppss))))
|
||||||
|
|
||||||
|
(defsubst python-syntax-closing-paren-p ()
|
||||||
|
"Return non-nil if char after point is a closing paren."
|
||||||
|
(= (syntax-class (syntax-after (point)))
|
||||||
|
(syntax-class (string-to-syntax ")"))))
|
||||||
|
|
||||||
(define-obsolete-function-alias
|
(define-obsolete-function-alias
|
||||||
'python-info-ppss-context #'python-syntax-context "24.3")
|
'python-info-ppss-context #'python-syntax-context "24.3")
|
||||||
|
@ -671,10 +676,28 @@ It makes underscores and dots word constituent chars.")
|
||||||
'python-guess-indent 'python-indent-guess-indent-offset "24.3")
|
'python-guess-indent 'python-indent-guess-indent-offset "24.3")
|
||||||
|
|
||||||
(defvar python-indent-current-level 0
|
(defvar python-indent-current-level 0
|
||||||
"Current indentation level `python-indent-line-function' is using.")
|
"Deprecated var available for compatibility.")
|
||||||
|
|
||||||
(defvar python-indent-levels '(0)
|
(defvar python-indent-levels '(0)
|
||||||
"Levels of indentation available for `python-indent-line-function'.")
|
"Deprecated var available for compatibility.")
|
||||||
|
|
||||||
|
(make-obsolete-variable
|
||||||
|
'python-indent-current-level
|
||||||
|
"The indentation API changed to avoid global state.
|
||||||
|
The function `python-indent-calculate-levels' does not use it
|
||||||
|
anymore. If you were defadvising it and or depended on this
|
||||||
|
variable for indentation customizations, refactor your code to
|
||||||
|
work on `python-indent-calculate-indentation' instead."
|
||||||
|
"24.5")
|
||||||
|
|
||||||
|
(make-obsolete-variable
|
||||||
|
'python-indent-levels
|
||||||
|
"The indentation API changed to avoid global state.
|
||||||
|
The function `python-indent-calculate-levels' does not use it
|
||||||
|
anymore. If you were defadvising it and or depended on this
|
||||||
|
variable for indentation customizations, refactor your code to
|
||||||
|
work on `python-indent-calculate-indentation' instead."
|
||||||
|
"24.5")
|
||||||
|
|
||||||
(defun python-indent-guess-indent-offset ()
|
(defun python-indent-guess-indent-offset ()
|
||||||
"Guess and set `python-indent-offset' for the current buffer."
|
"Guess and set `python-indent-offset' for the current buffer."
|
||||||
|
@ -714,356 +737,358 @@ It makes underscores and dots word constituent chars.")
|
||||||
python-indent-offset)))))))
|
python-indent-offset)))))))
|
||||||
|
|
||||||
(defun python-indent-context ()
|
(defun python-indent-context ()
|
||||||
"Get information on indentation context.
|
"Get information about the current indentation context.
|
||||||
Context information is returned with a cons with the form:
|
Context is returned in a cons with the form (STATUS . START).
|
||||||
(STATUS . START)
|
|
||||||
|
|
||||||
Where status can be any of the following symbols:
|
STATUS can be one of the following:
|
||||||
|
|
||||||
* after-comment: When current line might continue a comment block
|
keyword
|
||||||
* inside-paren: If point in between (), {} or []
|
-------
|
||||||
* inside-string: If point is inside a string
|
|
||||||
* after-backslash: Previous line ends in a backslash
|
:after-comment
|
||||||
* after-beginning-of-block: Point is after beginning of block
|
- Point is after a comment line.
|
||||||
* after-line: Point is after normal line
|
- START is the position of the \"#\" character.
|
||||||
* dedenter-statement: Point is on a dedenter statement.
|
:inside-string
|
||||||
* no-indent: Point is at beginning of buffer or other special case
|
- Point is inside string.
|
||||||
START is the buffer position where the sexp starts."
|
- START is the position of the first quote that starts it.
|
||||||
|
:no-indent
|
||||||
|
- No possible indentation case matches.
|
||||||
|
- START is always zero.
|
||||||
|
|
||||||
|
:inside-paren
|
||||||
|
- Fallback case when point is inside paren.
|
||||||
|
- START is the first non space char position *after* the open paren.
|
||||||
|
:inside-paren-at-closing-nested-paren
|
||||||
|
- Point is on a line that contains a nested paren closer.
|
||||||
|
- START is the position of the open paren it closes.
|
||||||
|
:inside-paren-at-closing-paren
|
||||||
|
- Point is on a line that contains a paren closer.
|
||||||
|
- START is the position of the open paren.
|
||||||
|
:inside-paren-newline-start
|
||||||
|
- Point is inside a paren with items starting in their own line.
|
||||||
|
- START is the position of the open paren.
|
||||||
|
:inside-paren-newline-start-from-block
|
||||||
|
- Point is inside a paren with items starting in their own line
|
||||||
|
from a block start.
|
||||||
|
- START is the position of the open paren.
|
||||||
|
|
||||||
|
:after-backslash
|
||||||
|
- Fallback case when point is after backslash.
|
||||||
|
- START is the char after the position of the backslash.
|
||||||
|
:after-backslash-assignment-continuation
|
||||||
|
- Point is after a backslashed assignment.
|
||||||
|
- START is the char after the position of the backslash.
|
||||||
|
:after-backslash-block-continuation
|
||||||
|
- Point is after a backslashed block continuation.
|
||||||
|
- START is the char after the position of the backslash.
|
||||||
|
:after-backslash-dotted-continuation
|
||||||
|
- Point is after a backslashed dotted continuation. Previous
|
||||||
|
line must contain a dot to align with.
|
||||||
|
- START is the char after the position of the backslash.
|
||||||
|
:after-backslash-first-line
|
||||||
|
- First line following a backslashed continuation.
|
||||||
|
- START is the char after the position of the backslash.
|
||||||
|
|
||||||
|
:after-block-end
|
||||||
|
- Point is after a line containing a block ender.
|
||||||
|
- START is the position where the ender starts.
|
||||||
|
:after-block-start
|
||||||
|
- Point is after a line starting a block.
|
||||||
|
- START is the position where the block starts.
|
||||||
|
:after-line
|
||||||
|
- Point is after a simple line.
|
||||||
|
- START is the position where the previous line starts.
|
||||||
|
:at-dedenter-block-start
|
||||||
|
- Point is on a line starting a dedenter block.
|
||||||
|
- START is the position where the dedenter block starts."
|
||||||
(save-restriction
|
(save-restriction
|
||||||
(widen)
|
(widen)
|
||||||
(let ((ppss (save-excursion (beginning-of-line) (syntax-ppss)))
|
(let ((ppss (save-excursion
|
||||||
(start))
|
(beginning-of-line)
|
||||||
(cons
|
(syntax-ppss))))
|
||||||
(cond
|
(cond
|
||||||
;; Beginning of buffer
|
;; Beginning of buffer.
|
||||||
((save-excursion
|
((= (line-number-at-pos) 1)
|
||||||
(goto-char (line-beginning-position))
|
(cons :no-indent 0))
|
||||||
(bobp))
|
;; Comment continuation (maybe).
|
||||||
'no-indent)
|
((save-excursion
|
||||||
;; Comment continuation
|
(when (and
|
||||||
((save-excursion
|
(or
|
||||||
(when (and
|
(python-info-current-line-comment-p)
|
||||||
(or
|
(python-info-current-line-empty-p))
|
||||||
(python-info-current-line-comment-p)
|
(forward-comment -1)
|
||||||
(python-info-current-line-empty-p))
|
(python-info-current-line-comment-p))
|
||||||
(progn
|
(cons :after-comment (point)))))
|
||||||
(forward-comment -1)
|
;; Inside a string.
|
||||||
(python-info-current-line-comment-p)))
|
((let ((start (python-syntax-context 'string ppss)))
|
||||||
(setq start (point))
|
(when start
|
||||||
'after-comment)))
|
(cons :inside-string start))))
|
||||||
;; Inside string
|
;; Inside a paren.
|
||||||
((setq start (python-syntax-context 'string ppss))
|
((let* ((start (python-syntax-context 'paren ppss))
|
||||||
'inside-string)
|
(starts-in-newline
|
||||||
;; Inside a paren
|
(when start
|
||||||
((setq start (python-syntax-context 'paren ppss))
|
(save-excursion
|
||||||
'inside-paren)
|
(goto-char start)
|
||||||
;; After backslash
|
(forward-char)
|
||||||
((setq start (when (not (or (python-syntax-context 'string ppss)
|
(not
|
||||||
(python-syntax-context 'comment ppss)))
|
(= (line-number-at-pos)
|
||||||
(let ((line-beg-pos (line-number-at-pos)))
|
(progn
|
||||||
(python-info-line-ends-backslash-p
|
(python-util-forward-comment)
|
||||||
(1- line-beg-pos)))))
|
(line-number-at-pos))))))))
|
||||||
'after-backslash)
|
(when start
|
||||||
;; After beginning of block
|
(cond
|
||||||
((setq start (save-excursion
|
;; Current line only holds the closing paren.
|
||||||
(when (progn
|
((save-excursion
|
||||||
(back-to-indentation)
|
(skip-syntax-forward " ")
|
||||||
(python-util-forward-comment -1)
|
(when (and (python-syntax-closing-paren-p)
|
||||||
(equal (char-before) ?:))
|
(progn
|
||||||
;; Move to the first block start that's not in within
|
(forward-char 1)
|
||||||
;; a string, comment or paren and that's not a
|
(not (python-syntax-context 'paren))))
|
||||||
;; continuation line.
|
(cons :inside-paren-at-closing-paren start))))
|
||||||
(while (and (re-search-backward
|
;; Current line only holds a closing paren for nested.
|
||||||
(python-rx block-start) nil t)
|
((save-excursion
|
||||||
(or
|
(back-to-indentation)
|
||||||
(python-syntax-context-type)
|
(python-syntax-closing-paren-p))
|
||||||
(python-info-continuation-line-p))))
|
(cons :inside-paren-at-closing-nested-paren start))
|
||||||
(when (looking-at (python-rx block-start))
|
;; This line starts from a opening block in its own line.
|
||||||
(point-marker)))))
|
((save-excursion
|
||||||
'after-beginning-of-block)
|
(goto-char start)
|
||||||
((when (setq start (python-info-dedenter-statement-p))
|
(when (and
|
||||||
'dedenter-statement))
|
starts-in-newline
|
||||||
;; After normal line
|
(save-excursion
|
||||||
((setq start (save-excursion
|
(back-to-indentation)
|
||||||
|
(looking-at (python-rx block-start))))
|
||||||
|
(cons
|
||||||
|
:inside-paren-newline-start-from-block start))))
|
||||||
|
(starts-in-newline
|
||||||
|
(cons :inside-paren-newline-start start))
|
||||||
|
;; General case.
|
||||||
|
(t (cons :inside-paren
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (1+ start))
|
||||||
|
(skip-syntax-forward "(" 1)
|
||||||
|
(skip-syntax-forward " ")
|
||||||
|
(point))))))))
|
||||||
|
;; After backslash.
|
||||||
|
((let ((start (when (not (python-syntax-comment-or-string-p ppss))
|
||||||
|
(python-info-line-ends-backslash-p
|
||||||
|
(1- (line-number-at-pos))))))
|
||||||
|
(when start
|
||||||
|
(cond
|
||||||
|
;; Continuation of dotted expression.
|
||||||
|
((save-excursion
|
||||||
|
(back-to-indentation)
|
||||||
|
(when (eq (char-after) ?\.)
|
||||||
|
;; Move point back until it's not inside a paren.
|
||||||
|
(while (prog2
|
||||||
|
(forward-line -1)
|
||||||
|
(and (not (bobp))
|
||||||
|
(python-syntax-context 'paren))))
|
||||||
|
(goto-char (line-end-position))
|
||||||
|
(while (and (search-backward
|
||||||
|
"." (line-beginning-position) t)
|
||||||
|
(python-syntax-context-type)))
|
||||||
|
;; Ensure previous statement has dot to align with.
|
||||||
|
(when (and (eq (char-after) ?\.)
|
||||||
|
(not (python-syntax-context-type)))
|
||||||
|
(cons :after-backslash-dotted-continuation (point))))))
|
||||||
|
;; Continuation of block definition.
|
||||||
|
((let ((block-continuation-start
|
||||||
|
(python-info-block-continuation-line-p)))
|
||||||
|
(when block-continuation-start
|
||||||
|
(save-excursion
|
||||||
|
(goto-char block-continuation-start)
|
||||||
|
(re-search-forward
|
||||||
|
(python-rx block-start (* space))
|
||||||
|
(line-end-position) t)
|
||||||
|
(cons :after-backslash-block-continuation (point))))))
|
||||||
|
;; Continuation of assignment.
|
||||||
|
((let ((assignment-continuation-start
|
||||||
|
(python-info-assignment-continuation-line-p)))
|
||||||
|
(when assignment-continuation-start
|
||||||
|
(save-excursion
|
||||||
|
(goto-char assignment-continuation-start)
|
||||||
|
(cons :after-backslash-assignment-continuation (point))))))
|
||||||
|
;; First line after backslash continuation start.
|
||||||
|
((save-excursion
|
||||||
|
(goto-char start)
|
||||||
|
(when (or (= (line-number-at-pos) 1)
|
||||||
|
(not (python-info-beginning-of-backslash
|
||||||
|
(1- (line-number-at-pos)))))
|
||||||
|
(cons :after-backslash-first-line start))))
|
||||||
|
;; General case.
|
||||||
|
(t (cons :after-backslash start))))))
|
||||||
|
;; After beginning of block.
|
||||||
|
((let ((start (save-excursion
|
||||||
(back-to-indentation)
|
(back-to-indentation)
|
||||||
(skip-chars-backward (rx (or whitespace ?\n)))
|
(python-util-forward-comment -1)
|
||||||
|
(when (equal (char-before) ?:)
|
||||||
|
(python-nav-beginning-of-block)))))
|
||||||
|
(when start
|
||||||
|
(cons :after-block-start start))))
|
||||||
|
;; At dedenter statement.
|
||||||
|
((let ((start (python-info-dedenter-statement-p)))
|
||||||
|
(when start
|
||||||
|
(cons :at-dedenter-block-start start))))
|
||||||
|
;; After normal line.
|
||||||
|
((let ((start (save-excursion
|
||||||
|
(back-to-indentation)
|
||||||
|
(skip-chars-backward " \t\n")
|
||||||
(python-nav-beginning-of-statement)
|
(python-nav-beginning-of-statement)
|
||||||
(point-marker)))
|
(point))))
|
||||||
'after-line)
|
(when start
|
||||||
;; Do not indent
|
(if (save-excursion
|
||||||
(t 'no-indent))
|
(python-util-forward-comment -1)
|
||||||
start))))
|
(python-nav-beginning-of-statement)
|
||||||
|
(looking-at (python-rx block-ender)))
|
||||||
|
(cons :after-block-end start)
|
||||||
|
(cons :after-line start)))))
|
||||||
|
;; Default case: do not indent.
|
||||||
|
(t (cons :no-indent 0))))))
|
||||||
|
|
||||||
(defun python-indent-calculate-indentation ()
|
(defun python-indent--calculate-indentation ()
|
||||||
"Calculate correct indentation offset for the current line."
|
"Internal implementation of `python-indent-calculate-indentation'.
|
||||||
(let* ((indentation-context (python-indent-context))
|
May return an integer for the maximum possible indentation at
|
||||||
(context-status (car indentation-context))
|
current context or a list of integers. The latter case is only
|
||||||
(context-start (cdr indentation-context)))
|
happening for :at-dedenter-block-start context since the
|
||||||
(save-restriction
|
possibilities can be narrowed to especific indentation points."
|
||||||
(widen)
|
(save-restriction
|
||||||
(save-excursion
|
(widen)
|
||||||
(pcase context-status
|
(save-excursion
|
||||||
(`no-indent 0)
|
(pcase (python-indent-context)
|
||||||
(`after-comment
|
(`(:no-indent . ,_) 0)
|
||||||
(goto-char context-start)
|
(`(,(or :after-line
|
||||||
(current-indentation))
|
:after-comment
|
||||||
;; When point is after beginning of block just add one level
|
:inside-string
|
||||||
;; of indentation relative to the context-start
|
:after-backslash
|
||||||
(`after-beginning-of-block
|
:inside-paren-at-closing-paren
|
||||||
(goto-char context-start)
|
:inside-paren-at-closing-nested-paren) . ,start)
|
||||||
(+ (current-indentation) python-indent-offset))
|
;; Copy previous indentation.
|
||||||
;; When after a simple line just use previous line
|
(goto-char start)
|
||||||
;; indentation.
|
(current-indentation))
|
||||||
(`after-line
|
(`(,(or :after-block-start
|
||||||
(let* ((pair (save-excursion
|
:after-backslash-first-line
|
||||||
(goto-char context-start)
|
:inside-paren-newline-start) . ,start)
|
||||||
(cons
|
;; Add one indentation level.
|
||||||
(current-indentation)
|
(goto-char start)
|
||||||
(python-info-beginning-of-block-p))))
|
(+ (current-indentation) python-indent-offset))
|
||||||
(context-indentation (car pair))
|
(`(,(or :inside-paren
|
||||||
;; TODO: Separate block enders into its own case.
|
:after-backslash-block-continuation
|
||||||
(adjustment
|
:after-backslash-assignment-continuation
|
||||||
(if (save-excursion
|
:after-backslash-dotted-continuation) . ,start)
|
||||||
(python-util-forward-comment -1)
|
;; Use the column given by the context.
|
||||||
(python-nav-beginning-of-statement)
|
(goto-char start)
|
||||||
(looking-at (python-rx block-ender)))
|
(current-column))
|
||||||
python-indent-offset
|
(`(:after-block-end . ,start)
|
||||||
0)))
|
;; Subtract one indentation level.
|
||||||
(- context-indentation adjustment)))
|
(goto-char start)
|
||||||
;; When point is on a dedenter statement, search for the
|
(- (current-indentation) python-indent-offset))
|
||||||
;; opening block that corresponds to it and use its
|
(`(:at-dedenter-block-start . ,_)
|
||||||
;; indentation. If no opening block is found just remove
|
;; List all possible indentation levels from opening blocks.
|
||||||
;; indentation as this is an invalid python file.
|
(let ((opening-block-start-points
|
||||||
(`dedenter-statement
|
(python-info-dedenter-opening-block-positions)))
|
||||||
(let ((block-start-point
|
(if (not opening-block-start-points)
|
||||||
(python-info-dedenter-opening-block-position)))
|
0 ; if not found default to first column
|
||||||
(save-excursion
|
(mapcar (lambda (pos)
|
||||||
(if (not block-start-point)
|
(save-excursion
|
||||||
0
|
(goto-char pos)
|
||||||
(goto-char block-start-point)
|
(current-indentation)))
|
||||||
(current-indentation)))))
|
opening-block-start-points))))
|
||||||
;; When inside of a string, do nothing. just use the current
|
(`(,(or :inside-paren-newline-start-from-block) . ,start)
|
||||||
;; indentation. XXX: perhaps it would be a good idea to
|
;; Add two indentation levels to make the suite stand out.
|
||||||
;; invoke standard text indentation here
|
(goto-char start)
|
||||||
(`inside-string
|
(+ (current-indentation) (* python-indent-offset 2)))))))
|
||||||
(goto-char context-start)
|
|
||||||
(current-indentation))
|
(defun python-indent--calculate-levels (indentation)
|
||||||
;; After backslash we have several possibilities.
|
"Calculate levels list given INDENTATION.
|
||||||
(`after-backslash
|
Argument INDENTATION can either be an integer or a list of
|
||||||
(cond
|
integers. Levels are returned in ascending order, and in the
|
||||||
;; Check if current line is a dot continuation. For this
|
case INDENTATION is a list, this order is enforced."
|
||||||
;; the current line must start with a dot and previous
|
(if (listp indentation)
|
||||||
;; line must contain a dot too.
|
(sort (copy-sequence indentation) #'<)
|
||||||
((save-excursion
|
(let* ((remainder (% indentation python-indent-offset))
|
||||||
(back-to-indentation)
|
(steps (/ (- indentation remainder) python-indent-offset))
|
||||||
(when (looking-at "\\.")
|
(levels (mapcar (lambda (step)
|
||||||
;; If after moving one line back point is inside a paren it
|
(* python-indent-offset step))
|
||||||
;; needs to move back until it's not anymore
|
(number-sequence steps 0 -1))))
|
||||||
(while (prog2
|
(reverse
|
||||||
(forward-line -1)
|
(if (not (zerop remainder))
|
||||||
(and (not (bobp))
|
(cons indentation levels)
|
||||||
(python-syntax-context 'paren))))
|
levels)))))
|
||||||
(goto-char (line-end-position))
|
|
||||||
(while (and (re-search-backward
|
(defun python-indent--previous-level (levels indentation)
|
||||||
"\\." (line-beginning-position) t)
|
"Return previous level from LEVELS relative to INDENTATION."
|
||||||
(python-syntax-context-type)))
|
(let* ((levels (sort (copy-sequence levels) #'>))
|
||||||
(if (and (looking-at "\\.")
|
(default (car levels)))
|
||||||
(not (python-syntax-context-type)))
|
(catch 'return
|
||||||
;; The indentation is the same column of the
|
(dolist (level levels)
|
||||||
;; first matching dot that's not inside a
|
(when (funcall #'< level indentation)
|
||||||
;; comment, a string or a paren
|
(throw 'return level)))
|
||||||
(current-column)
|
default)))
|
||||||
;; No dot found on previous line, just add another
|
|
||||||
;; indentation level.
|
(defun python-indent-calculate-indentation (&optional previous)
|
||||||
(+ (current-indentation) python-indent-offset)))))
|
"Calculate indentation.
|
||||||
;; Check if prev line is a block continuation
|
Get indentation of PREVIOUS level when argument is non-nil.
|
||||||
((let ((block-continuation-start
|
Return the max level of the cycle when indentation reaches the
|
||||||
(python-info-block-continuation-line-p)))
|
minimum."
|
||||||
(when block-continuation-start
|
(let* ((indentation (python-indent--calculate-indentation))
|
||||||
;; If block-continuation-start is set jump to that
|
(levels (python-indent--calculate-levels indentation)))
|
||||||
;; marker and use first column after the block start
|
(if previous
|
||||||
;; as indentation value.
|
(python-indent--previous-level levels (current-indentation))
|
||||||
(goto-char block-continuation-start)
|
(apply #'max levels))))
|
||||||
(re-search-forward
|
|
||||||
(python-rx block-start (* space))
|
(defun python-indent-line (&optional previous)
|
||||||
(line-end-position) t)
|
"Internal implementation of `python-indent-line-function'.
|
||||||
(current-column))))
|
Use the PREVIOUS level when argument is non-nil, otherwise indent
|
||||||
;; Check if current line is an assignment continuation
|
to the maxium available level. When indentation is the minimum
|
||||||
((let ((assignment-continuation-start
|
possible and PREVIOUS is non-nil, cycle back to the maximum
|
||||||
(python-info-assignment-continuation-line-p)))
|
level."
|
||||||
(when assignment-continuation-start
|
(let ((follow-indentation-p
|
||||||
;; If assignment-continuation is set jump to that
|
;; Check if point is within indentation.
|
||||||
;; marker and use first column after the assignment
|
(and (<= (line-beginning-position) (point))
|
||||||
;; operator as indentation value.
|
(>= (+ (line-beginning-position)
|
||||||
(goto-char assignment-continuation-start)
|
(current-indentation))
|
||||||
(current-column))))
|
(point)))))
|
||||||
(t
|
(save-excursion
|
||||||
(forward-line -1)
|
(indent-line-to
|
||||||
(goto-char (python-info-beginning-of-backslash))
|
(python-indent-calculate-indentation previous))
|
||||||
(if (save-excursion
|
(python-info-dedenter-opening-block-message))
|
||||||
(and
|
(when follow-indentation-p
|
||||||
(forward-line -1)
|
(back-to-indentation))))
|
||||||
(goto-char
|
|
||||||
(or (python-info-beginning-of-backslash) (point)))
|
|
||||||
(python-info-line-ends-backslash-p)))
|
|
||||||
;; The two previous lines ended in a backslash so we must
|
|
||||||
;; respect previous line indentation.
|
|
||||||
(current-indentation)
|
|
||||||
;; What happens here is that we are dealing with the second
|
|
||||||
;; line of a backslash continuation, in that case we just going
|
|
||||||
;; to add one indentation level.
|
|
||||||
(+ (current-indentation) python-indent-offset)))))
|
|
||||||
;; When inside a paren there's a need to handle nesting
|
|
||||||
;; correctly
|
|
||||||
(`inside-paren
|
|
||||||
(cond
|
|
||||||
;; If current line closes the outermost open paren use the
|
|
||||||
;; current indentation of the context-start line.
|
|
||||||
((save-excursion
|
|
||||||
(skip-syntax-forward "\s" (line-end-position))
|
|
||||||
(when (and (looking-at (regexp-opt '(")" "]" "}")))
|
|
||||||
(progn
|
|
||||||
(forward-char 1)
|
|
||||||
(not (python-syntax-context 'paren))))
|
|
||||||
(goto-char context-start)
|
|
||||||
(current-indentation))))
|
|
||||||
;; If open paren is contained on a line by itself add another
|
|
||||||
;; indentation level, else look for the first word after the
|
|
||||||
;; opening paren and use it's column position as indentation
|
|
||||||
;; level.
|
|
||||||
((let* ((content-starts-in-newline)
|
|
||||||
(indent
|
|
||||||
(save-excursion
|
|
||||||
(if (setq content-starts-in-newline
|
|
||||||
(progn
|
|
||||||
(goto-char context-start)
|
|
||||||
(forward-char)
|
|
||||||
(save-restriction
|
|
||||||
(narrow-to-region
|
|
||||||
(line-beginning-position)
|
|
||||||
(line-end-position))
|
|
||||||
(python-util-forward-comment))
|
|
||||||
(looking-at "$")))
|
|
||||||
(+ (current-indentation) python-indent-offset)
|
|
||||||
(current-column)))))
|
|
||||||
;; Adjustments
|
|
||||||
(cond
|
|
||||||
;; If current line closes a nested open paren de-indent one
|
|
||||||
;; level.
|
|
||||||
((progn
|
|
||||||
(back-to-indentation)
|
|
||||||
(looking-at (regexp-opt '(")" "]" "}"))))
|
|
||||||
(- indent python-indent-offset))
|
|
||||||
;; If the line of the opening paren that wraps the current
|
|
||||||
;; line starts a block add another level of indentation to
|
|
||||||
;; follow new pep8 recommendation. See: http://ur1.ca/5rojx
|
|
||||||
((save-excursion
|
|
||||||
(when (and content-starts-in-newline
|
|
||||||
(progn
|
|
||||||
(goto-char context-start)
|
|
||||||
(back-to-indentation)
|
|
||||||
(looking-at (python-rx block-start))))
|
|
||||||
(+ indent python-indent-offset))))
|
|
||||||
(t indent)))))))))))
|
|
||||||
|
|
||||||
(defun python-indent-calculate-levels ()
|
(defun python-indent-calculate-levels ()
|
||||||
"Calculate `python-indent-levels' and reset `python-indent-current-level'."
|
"Return possible indentation levels."
|
||||||
(if (or (python-info-continuation-line-p)
|
(python-indent--calculate-levels
|
||||||
(not (python-info-dedenter-statement-p)))
|
(python-indent--calculate-indentation)))
|
||||||
;; XXX: This asks for a refactor. Even if point is on a
|
|
||||||
;; dedenter statement, it could be multiline and in that case
|
|
||||||
;; the continuation lines should be indented with normal rules.
|
|
||||||
(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'."
|
|
||||||
(setq python-indent-current-level (1- python-indent-current-level))
|
|
||||||
(when (< python-indent-current-level 0)
|
|
||||||
(setq python-indent-current-level (1- (length python-indent-levels)))))
|
|
||||||
|
|
||||||
(defun python-indent-line (&optional force-toggle)
|
|
||||||
"Internal implementation of `python-indent-line-function'.
|
|
||||||
Uses the offset calculated in
|
|
||||||
`python-indent-calculate-indentation' and available levels
|
|
||||||
indicated by the variable `python-indent-levels' to set the
|
|
||||||
current indentation.
|
|
||||||
|
|
||||||
When the variable `last-command' is equal to one of the symbols
|
|
||||||
inside `python-indent-trigger-commands' or FORCE-TOGGLE is
|
|
||||||
non-nil it cycles levels indicated in the variable
|
|
||||||
`python-indent-levels' by setting the current level in the
|
|
||||||
variable `python-indent-current-level'.
|
|
||||||
|
|
||||||
When the variable `last-command' is not equal to one of the
|
|
||||||
symbols inside `python-indent-trigger-commands' and FORCE-TOGGLE
|
|
||||||
is nil it calculates possible indentation levels and saves them
|
|
||||||
in the variable `python-indent-levels'. Afterwards it sets the
|
|
||||||
variable `python-indent-current-level' correctly so offset is
|
|
||||||
equal to
|
|
||||||
(nth python-indent-current-level python-indent-levels)"
|
|
||||||
(or
|
|
||||||
(and (or (and (memq this-command python-indent-trigger-commands)
|
|
||||||
(eq last-command this-command))
|
|
||||||
force-toggle)
|
|
||||||
(not (equal python-indent-levels '(0)))
|
|
||||||
(or (python-indent-toggle-levels) t))
|
|
||||||
(python-indent-calculate-levels))
|
|
||||||
(let* ((starting-pos (point-marker))
|
|
||||||
(indent-ending-position
|
|
||||||
(+ (line-beginning-position) (current-indentation)))
|
|
||||||
(follow-indentation-p
|
|
||||||
(or (bolp)
|
|
||||||
(and (<= (line-beginning-position) starting-pos)
|
|
||||||
(>= indent-ending-position starting-pos))))
|
|
||||||
(next-indent (nth python-indent-current-level python-indent-levels)))
|
|
||||||
(unless (= next-indent (current-indentation))
|
|
||||||
(beginning-of-line)
|
|
||||||
(delete-horizontal-space)
|
|
||||||
(indent-to next-indent)
|
|
||||||
(goto-char starting-pos))
|
|
||||||
(and follow-indentation-p (back-to-indentation)))
|
|
||||||
(python-info-dedenter-opening-block-message))
|
|
||||||
|
|
||||||
(defun python-indent-line-function ()
|
(defun python-indent-line-function ()
|
||||||
"`indent-line-function' for Python mode.
|
"`indent-line-function' for Python mode.
|
||||||
See `python-indent-line' for details."
|
When the variable `last-command' is equal to one of the symbols
|
||||||
(python-indent-line))
|
inside `python-indent-trigger-commands' it cycles possible
|
||||||
|
indentation levels from right to left."
|
||||||
|
(python-indent-line
|
||||||
|
(and (memq this-command python-indent-trigger-commands)
|
||||||
|
(eq last-command this-command))))
|
||||||
|
|
||||||
(defun python-indent-dedent-line ()
|
(defun python-indent-dedent-line ()
|
||||||
"De-indent current line."
|
"De-indent current line."
|
||||||
(interactive "*")
|
(interactive "*")
|
||||||
(when (and (not (python-syntax-comment-or-string-p))
|
(when (and (not (bolp))
|
||||||
(<= (point-marker) (save-excursion
|
(not (python-syntax-comment-or-string-p))
|
||||||
(back-to-indentation)
|
(= (+ (line-beginning-position)
|
||||||
(point-marker)))
|
(current-indentation))
|
||||||
(> (current-column) 0))
|
(point)))
|
||||||
(python-indent-line t)
|
(python-indent-line t)
|
||||||
t))
|
t))
|
||||||
|
|
||||||
(defun python-indent-dedent-line-backspace (arg)
|
(defun python-indent-dedent-line-backspace (arg)
|
||||||
"De-indent current line.
|
"De-indent current line.
|
||||||
Argument ARG is passed to `backward-delete-char-untabify' when
|
Argument ARG is passed to `backward-delete-char-untabify' when
|
||||||
point is not in between the indentation."
|
point is not in between the indentation."
|
||||||
(interactive "*p")
|
(interactive "*p")
|
||||||
(when (not (python-indent-dedent-line))
|
(unless (python-indent-dedent-line)
|
||||||
(backward-delete-char-untabify arg)))
|
(backward-delete-char-untabify arg)))
|
||||||
|
|
||||||
(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
|
(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
|
||||||
|
|
||||||
(defun python-indent-region (start end)
|
(defun python-indent-region (start end)
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
2015-01-26 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||||
|
|
||||||
|
* automated/python-tests.el (python-indent-pep8-1)
|
||||||
|
(python-indent-pep8-2, python-indent-pep8-3)
|
||||||
|
(python-indent-after-comment-1, python-indent-after-comment-2)
|
||||||
|
(python-indent-inside-paren-1, python-indent-inside-paren-2)
|
||||||
|
(python-indent-after-block-1, python-indent-after-block-2)
|
||||||
|
(python-indent-after-backslash-1, python-indent-after-backslash-2)
|
||||||
|
(python-indent-after-backslash-3, python-indent-block-enders-1)
|
||||||
|
(python-indent-block-enders-2, python-indent-block-enders-3)
|
||||||
|
(python-indent-block-enders-4, python-indent-block-enders-5)
|
||||||
|
(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-indent-dedenters-8): Fix tests.
|
||||||
|
(python-indent-base-case, python-indent-after-block-3)
|
||||||
|
(python-indent-after-backslash-5, python-indent-inside-paren-3)
|
||||||
|
(python-indent-inside-paren-4, python-indent-inside-paren-5)
|
||||||
|
(python-indent-inside-paren-6, python-indent-inside-string-1)
|
||||||
|
(python-indent-inside-string-2, python-indent-inside-string-3)
|
||||||
|
(python-indent-dedent-line-backspace-1): New Tests.
|
||||||
|
|
||||||
2015-01-24 Glenn Morris <rgm@gnu.org>
|
2015-01-24 Glenn Morris <rgm@gnu.org>
|
||||||
|
|
||||||
* automated/regexp-tests.el: Require regexp-opt, which is
|
* automated/regexp-tests.el: Require regexp-opt, which is
|
||||||
|
|
|
@ -174,13 +174,13 @@ aliqua."
|
||||||
foo = long_function_name(var_one, var_two,
|
foo = long_function_name(var_one, var_two,
|
||||||
var_three, var_four)
|
var_three, var_four)
|
||||||
"
|
"
|
||||||
(should (eq (car (python-indent-context)) 'no-indent))
|
(should (eq (car (python-indent-context)) :no-indent))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "foo = long_function_name(var_one, var_two,")
|
(python-tests-look-at "foo = long_function_name(var_one, var_two,")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "var_three, var_four)")
|
(python-tests-look-at "var_three, var_four)")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 25))))
|
(should (= (python-indent-calculate-indentation) 25))))
|
||||||
|
|
||||||
(ert-deftest python-indent-pep8-2 ()
|
(ert-deftest python-indent-pep8-2 ()
|
||||||
|
@ -192,19 +192,22 @@ def long_function_name(
|
||||||
var_four):
|
var_four):
|
||||||
print (var_one)
|
print (var_one)
|
||||||
"
|
"
|
||||||
(should (eq (car (python-indent-context)) 'no-indent))
|
(should (eq (car (python-indent-context)) :no-indent))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "def long_function_name(")
|
(python-tests-look-at "def long_function_name(")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "var_one, var_two, var_three,")
|
(python-tests-look-at "var_one, var_two, var_three,")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-newline-start-from-block))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "var_four):")
|
(python-tests-look-at "var_four):")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-newline-start-from-block))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "print (var_one)")
|
(python-tests-look-at "print (var_one)")
|
||||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-pep8-3 ()
|
(ert-deftest python-indent-pep8-3 ()
|
||||||
|
@ -215,18 +218,34 @@ foo = long_function_name(
|
||||||
var_one, var_two,
|
var_one, var_two,
|
||||||
var_three, var_four)
|
var_three, var_four)
|
||||||
"
|
"
|
||||||
(should (eq (car (python-indent-context)) 'no-indent))
|
(should (eq (car (python-indent-context)) :no-indent))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "foo = long_function_name(")
|
(python-tests-look-at "foo = long_function_name(")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "var_one, var_two,")
|
(python-tests-look-at "var_one, var_two,")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "var_three, var_four)")
|
(python-tests-look-at "var_three, var_four)")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-base-case ()
|
||||||
|
"Check base case does not trigger errors."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
|
||||||
|
"
|
||||||
|
(goto-char (point-min))
|
||||||
|
(should (eq (car (python-indent-context)) :no-indent))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-after-comment-1 ()
|
(ert-deftest python-indent-after-comment-1 ()
|
||||||
"The most simple after-comment case that shouldn't fail."
|
"The most simple after-comment case that shouldn't fail."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
|
@ -240,23 +259,23 @@ class Blag(object):
|
||||||
# with the exception with which the first child failed.
|
# with the exception with which the first child failed.
|
||||||
"
|
"
|
||||||
(python-tests-look-at "# We only complete")
|
(python-tests-look-at "# We only complete")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "# terminal state")
|
(python-tests-look-at "# terminal state")
|
||||||
(should (eq (car (python-indent-context)) 'after-comment))
|
(should (eq (car (python-indent-context)) :after-comment))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "# with the exception")
|
(python-tests-look-at "# with the exception")
|
||||||
(should (eq (car (python-indent-context)) 'after-comment))
|
(should (eq (car (python-indent-context)) :after-comment))
|
||||||
;; This one indents relative to previous block, even given the fact
|
;; This one indents relative to previous block, even given the fact
|
||||||
;; that it was under-indented.
|
;; that it was under-indented.
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "# terminal state" -1)
|
(python-tests-look-at "# terminal state" -1)
|
||||||
;; It doesn't hurt to check again.
|
;; It doesn't hurt to check again.
|
||||||
(should (eq (car (python-indent-context)) 'after-comment))
|
(should (eq (car (python-indent-context)) :after-comment))
|
||||||
(python-indent-line)
|
(python-indent-line)
|
||||||
(should (= (current-indentation) 8))
|
(should (= (current-indentation) 8))
|
||||||
(python-tests-look-at "# with the exception")
|
(python-tests-look-at "# with the exception")
|
||||||
(should (eq (car (python-indent-context)) 'after-comment))
|
(should (eq (car (python-indent-context)) :after-comment))
|
||||||
;; Now everything should be lined up.
|
;; Now everything should be lined up.
|
||||||
(should (= (python-indent-calculate-indentation) 8))))
|
(should (= (python-indent-calculate-indentation) 8))))
|
||||||
|
|
||||||
|
@ -275,33 +294,33 @@ now_we_do_mess_cause_this_is_not_a_comment = 1
|
||||||
# yeah, that.
|
# yeah, that.
|
||||||
"
|
"
|
||||||
(python-tests-look-at "# I don't do much")
|
(python-tests-look-at "# I don't do much")
|
||||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "return arg")
|
(python-tests-look-at "return arg")
|
||||||
;; Comment here just gets ignored, this line is not a comment so
|
;; Comment here just gets ignored, this line is not a comment so
|
||||||
;; the rules won't apply here.
|
;; the rules won't apply here.
|
||||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "# This comment is badly")
|
(python-tests-look-at "# This comment is badly")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
;; The return keyword moves indentation backwards 4 spaces, but
|
;; The return keyword moves indentation backwards 4 spaces, but
|
||||||
;; let's assume this comment was placed there because the user
|
;; let's assume this comment was placed there because the user
|
||||||
;; wanted to (manually adding spaces or whatever).
|
;; wanted to (manually adding spaces or whatever).
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "# but we won't mess")
|
(python-tests-look-at "# but we won't mess")
|
||||||
(should (eq (car (python-indent-context)) 'after-comment))
|
(should (eq (car (python-indent-context)) :after-comment))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
;; Behave the same for blank lines: potentially a comment.
|
;; Behave the same for blank lines: potentially a comment.
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (eq (car (python-indent-context)) 'after-comment))
|
(should (eq (car (python-indent-context)) :after-comment))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "now_we_do_mess")
|
(python-tests-look-at "now_we_do_mess")
|
||||||
;; Here is where comment indentation starts to get ignored and
|
;; Here is where comment indentation starts to get ignored and
|
||||||
;; where the user can't freely indent anymore.
|
;; where the user can't freely indent anymore.
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "# yeah, that.")
|
(python-tests-look-at "# yeah, that.")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))))
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-inside-paren-1 ()
|
(ert-deftest python-indent-inside-paren-1 ()
|
||||||
|
@ -325,49 +344,53 @@ data = {
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
(python-tests-look-at "data = {")
|
(python-tests-look-at "data = {")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "'key':")
|
(python-tests-look-at "'key':")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "{")
|
(python-tests-look-at "{")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "'objlist': [")
|
(python-tests-look-at "'objlist': [")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "{")
|
(python-tests-look-at "{")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 12))
|
(should (= (python-indent-calculate-indentation) 12))
|
||||||
(python-tests-look-at "'pk': 1,")
|
(python-tests-look-at "'pk': 1,")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 16))
|
(should (= (python-indent-calculate-indentation) 16))
|
||||||
(python-tests-look-at "'name': 'first',")
|
(python-tests-look-at "'name': 'first',")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 16))
|
(should (= (python-indent-calculate-indentation) 16))
|
||||||
(python-tests-look-at "},")
|
(python-tests-look-at "},")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-at-closing-nested-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 12))
|
(should (= (python-indent-calculate-indentation) 12))
|
||||||
(python-tests-look-at "{")
|
(python-tests-look-at "{")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 12))
|
(should (= (python-indent-calculate-indentation) 12))
|
||||||
(python-tests-look-at "'pk': 2,")
|
(python-tests-look-at "'pk': 2,")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 16))
|
(should (= (python-indent-calculate-indentation) 16))
|
||||||
(python-tests-look-at "'name': 'second',")
|
(python-tests-look-at "'name': 'second',")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 16))
|
(should (= (python-indent-calculate-indentation) 16))
|
||||||
(python-tests-look-at "}")
|
(python-tests-look-at "}")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-at-closing-nested-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 12))
|
(should (= (python-indent-calculate-indentation) 12))
|
||||||
(python-tests-look-at "]")
|
(python-tests-look-at "]")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-at-closing-nested-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "}")
|
(python-tests-look-at "}")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-at-closing-nested-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "}")
|
(python-tests-look-at "}")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 0))))
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-inside-paren-2 ()
|
(ert-deftest python-indent-inside-paren-2 ()
|
||||||
|
@ -384,43 +407,121 @@ data = {'key': {
|
||||||
}}
|
}}
|
||||||
"
|
"
|
||||||
(python-tests-look-at "data = {")
|
(python-tests-look-at "data = {")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "'objlist': [")
|
(python-tests-look-at "'objlist': [")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "{'pk': 1,")
|
(python-tests-look-at "{'pk': 1,")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "'name': 'first'},")
|
(python-tests-look-at "'name': 'first'},")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 9))
|
(should (= (python-indent-calculate-indentation) 9))
|
||||||
(python-tests-look-at "{'pk': 2,")
|
(python-tests-look-at "{'pk': 2,")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "'name': 'second'}")
|
(python-tests-look-at "'name': 'second'}")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 9))
|
(should (= (python-indent-calculate-indentation) 9))
|
||||||
(python-tests-look-at "]")
|
(python-tests-look-at "]")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-at-closing-nested-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "}}")
|
(python-tests-look-at "}}")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context))
|
||||||
|
:inside-paren-at-closing-nested-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "}")
|
(python-tests-look-at "}")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 0))))
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-paren-3 ()
|
||||||
|
"The simplest case possible."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
data = ('these',
|
||||||
|
'are',
|
||||||
|
'the',
|
||||||
|
'tokens')
|
||||||
|
"
|
||||||
|
(python-tests-look-at "data = ('these',")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-paren-4 ()
|
||||||
|
"Respect indentation of first column."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
data = [ [ 'these', 'are'],
|
||||||
|
['the', 'tokens' ] ]
|
||||||
|
"
|
||||||
|
(python-tests-look-at "data = [ [ 'these', 'are'],")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 9))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-paren-5 ()
|
||||||
|
"Test when :inside-paren initial parens are skipped in context start."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
while ((not some_condition) and
|
||||||
|
another_condition):
|
||||||
|
do_something_interesting(
|
||||||
|
with_some_arg)
|
||||||
|
"
|
||||||
|
(python-tests-look-at "while ((not some_condition) and")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 7))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-paren-6 ()
|
||||||
|
"This should be aligned.."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
CHOICES = (('some', 'choice'),
|
||||||
|
('another', 'choice'),
|
||||||
|
('more', 'choices'))
|
||||||
|
"
|
||||||
|
(python-tests-look-at "CHOICES = (('some', 'choice'),")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 11))
|
||||||
|
(forward-line 1)
|
||||||
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
|
(should (= (python-indent-calculate-indentation) 11))))
|
||||||
|
|
||||||
(ert-deftest python-indent-after-block-1 ()
|
(ert-deftest python-indent-after-block-1 ()
|
||||||
"The most simple after-block case that shouldn't fail."
|
"The most simple after-block case that shouldn't fail."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
def foo(a, b, c=True):
|
def foo(a, b, c=True):
|
||||||
"
|
"
|
||||||
(should (eq (car (python-indent-context)) 'no-indent))
|
(should (eq (car (python-indent-context)) :no-indent))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-after-block-2 ()
|
(ert-deftest python-indent-after-block-2 ()
|
||||||
|
@ -432,9 +533,28 @@ def foo(a, b, c={
|
||||||
}):
|
}):
|
||||||
"
|
"
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-after-block-3 ()
|
||||||
|
"A weird (malformed) sample, usually found in python shells."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
In [1]:
|
||||||
|
def func():
|
||||||
|
pass
|
||||||
|
|
||||||
|
In [2]:
|
||||||
|
something
|
||||||
|
"
|
||||||
|
(python-tests-look-at "pass")
|
||||||
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "something")
|
||||||
|
(end-of-line)
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-after-backslash-1 ()
|
(ert-deftest python-indent-after-backslash-1 ()
|
||||||
"The most common case."
|
"The most common case."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
|
@ -444,16 +564,16 @@ from foo.bar.baz import something, something_1 \\\\
|
||||||
something_4, something_5
|
something_4, something_5
|
||||||
"
|
"
|
||||||
(python-tests-look-at "from foo.bar.baz import something, something_1")
|
(python-tests-look-at "from foo.bar.baz import something, something_1")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at "something_2 something_3,")
|
(python-tests-look-at "something_2 something_3,")
|
||||||
(should (eq (car (python-indent-context)) 'after-backslash))
|
(should (eq (car (python-indent-context)) :after-backslash-first-line))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "something_4, something_5")
|
(python-tests-look-at "something_4, something_5")
|
||||||
(should (eq (car (python-indent-context)) 'after-backslash))
|
(should (eq (car (python-indent-context)) :after-backslash))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))))
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-after-backslash-2 ()
|
(ert-deftest python-indent-after-backslash-2 ()
|
||||||
|
@ -471,40 +591,104 @@ objects = Thing.objects.all() \\\\
|
||||||
.values_list()
|
.values_list()
|
||||||
"
|
"
|
||||||
(python-tests-look-at "objects = Thing.objects.all()")
|
(python-tests-look-at "objects = Thing.objects.all()")
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(python-tests-look-at ".filter(")
|
(python-tests-look-at ".filter(")
|
||||||
(should (eq (car (python-indent-context)) 'after-backslash))
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-backslash-dotted-continuation))
|
||||||
(should (= (python-indent-calculate-indentation) 23))
|
(should (= (python-indent-calculate-indentation) 23))
|
||||||
(python-tests-look-at "type='toy',")
|
(python-tests-look-at "type='toy',")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 27))
|
(should (= (python-indent-calculate-indentation) 27))
|
||||||
(python-tests-look-at "status='bought'")
|
(python-tests-look-at "status='bought'")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 27))
|
(should (= (python-indent-calculate-indentation) 27))
|
||||||
(python-tests-look-at ") \\\\")
|
(python-tests-look-at ") \\\\")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 23))
|
(should (= (python-indent-calculate-indentation) 23))
|
||||||
(python-tests-look-at ".aggregate(")
|
(python-tests-look-at ".aggregate(")
|
||||||
(should (eq (car (python-indent-context)) 'after-backslash))
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-backslash-dotted-continuation))
|
||||||
(should (= (python-indent-calculate-indentation) 23))
|
(should (= (python-indent-calculate-indentation) 23))
|
||||||
(python-tests-look-at "Sum('amount')")
|
(python-tests-look-at "Sum('amount')")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
|
||||||
(should (= (python-indent-calculate-indentation) 27))
|
(should (= (python-indent-calculate-indentation) 27))
|
||||||
(python-tests-look-at ") \\\\")
|
(python-tests-look-at ") \\\\")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 23))
|
(should (= (python-indent-calculate-indentation) 23))
|
||||||
(python-tests-look-at ".values_list()")
|
(python-tests-look-at ".values_list()")
|
||||||
(should (eq (car (python-indent-context)) 'after-backslash))
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-backslash-dotted-continuation))
|
||||||
(should (= (python-indent-calculate-indentation) 23))
|
(should (= (python-indent-calculate-indentation) 23))
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (eq (car (python-indent-context)) 'after-line))
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
(should (= (python-indent-calculate-indentation) 0))))
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-after-backslash-3 ()
|
||||||
|
"Backslash continuation from block start."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
with open('/path/to/some/file/you/want/to/read') as file_1, \\\\
|
||||||
|
open('/path/to/some/file/being/written', 'w') as file_2:
|
||||||
|
file_2.write(file_1.read())
|
||||||
|
"
|
||||||
|
(python-tests-look-at
|
||||||
|
"with open('/path/to/some/file/you/want/to/read') as file_1, \\\\")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(python-tests-look-at
|
||||||
|
"open('/path/to/some/file/being/written', 'w') as file_2")
|
||||||
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-backslash-block-continuation))
|
||||||
|
(should (= (python-indent-calculate-indentation) 5))
|
||||||
|
(python-tests-look-at "file_2.write(file_1.read())")
|
||||||
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-after-backslash-4 ()
|
||||||
|
"Backslash continuation from assignment."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
super_awful_assignment = some_calculation() and \\\\
|
||||||
|
another_calculation() and \\\\
|
||||||
|
some_final_calculation()
|
||||||
|
"
|
||||||
|
(python-tests-look-at
|
||||||
|
"super_awful_assignment = some_calculation() and \\\\")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(python-tests-look-at "another_calculation() and \\\\")
|
||||||
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-backslash-assignment-continuation))
|
||||||
|
(should (= (python-indent-calculate-indentation) 25))
|
||||||
|
(python-tests-look-at "some_final_calculation()")
|
||||||
|
(should (eq (car (python-indent-context)) :after-backslash))
|
||||||
|
(should (= (python-indent-calculate-indentation) 25))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-after-backslash-5 ()
|
||||||
|
"Dotted continuation bizarre example."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
def delete_all_things():
|
||||||
|
Thing \\\\
|
||||||
|
.objects.all() \\\\
|
||||||
|
.delete()
|
||||||
|
"
|
||||||
|
(python-tests-look-at "Thing \\\\")
|
||||||
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at ".objects.all() \\\\")
|
||||||
|
(should (eq (car (python-indent-context)) :after-backslash-first-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
|
(python-tests-look-at ".delete()")
|
||||||
|
(should (eq (car (python-indent-context))
|
||||||
|
:after-backslash-dotted-continuation))
|
||||||
|
(should (= (python-indent-calculate-indentation) 16))))
|
||||||
|
|
||||||
(ert-deftest python-indent-block-enders-1 ()
|
(ert-deftest python-indent-block-enders-1 ()
|
||||||
"Test de-indentation for pass keyword."
|
"Test de-indentation for pass keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
Class foo(object):
|
Class foo(object):
|
||||||
|
|
||||||
def bar(self):
|
def bar(self):
|
||||||
|
@ -516,17 +700,18 @@ Class foo(object):
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
"
|
"
|
||||||
(python-tests-look-at "3)")
|
(python-tests-look-at "3)")
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "pass")
|
(python-tests-look-at "pass")
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (= (python-indent-calculate-indentation) 8))))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))))
|
||||||
|
|
||||||
(ert-deftest python-indent-block-enders-2 ()
|
(ert-deftest python-indent-block-enders-2 ()
|
||||||
"Test de-indentation for return keyword."
|
"Test de-indentation for return keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
Class foo(object):
|
Class foo(object):
|
||||||
'''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
'''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
||||||
|
|
||||||
|
@ -539,64 +724,68 @@ Class foo(object):
|
||||||
2,
|
2,
|
||||||
3)
|
3)
|
||||||
"
|
"
|
||||||
(python-tests-look-at "def")
|
(python-tests-look-at "def")
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "if")
|
(python-tests-look-at "if")
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(python-tests-look-at "return")
|
(python-tests-look-at "return")
|
||||||
(should (= (python-indent-calculate-indentation) 12))
|
(should (= (python-indent-calculate-indentation) 12))
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(should (= (python-indent-calculate-indentation) 8))))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
|
(should (= (python-indent-calculate-indentation) 8))))
|
||||||
|
|
||||||
(ert-deftest python-indent-block-enders-3 ()
|
(ert-deftest python-indent-block-enders-3 ()
|
||||||
"Test de-indentation for continue keyword."
|
"Test de-indentation for continue keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
for element in lst:
|
for element in lst:
|
||||||
if element is None:
|
if element is None:
|
||||||
continue
|
continue
|
||||||
"
|
"
|
||||||
(python-tests-look-at "if")
|
(python-tests-look-at "if")
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "continue")
|
(python-tests-look-at "continue")
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-block-enders-4 ()
|
(ert-deftest python-indent-block-enders-4 ()
|
||||||
"Test de-indentation for break keyword."
|
"Test de-indentation for break keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
for element in lst:
|
for element in lst:
|
||||||
if element is None:
|
if element is None:
|
||||||
break
|
break
|
||||||
"
|
"
|
||||||
(python-tests-look-at "if")
|
(python-tests-look-at "if")
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "break")
|
(python-tests-look-at "break")
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-block-enders-5 ()
|
(ert-deftest python-indent-block-enders-5 ()
|
||||||
"Test de-indentation for raise keyword."
|
"Test de-indentation for raise keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
for element in lst:
|
for element in lst:
|
||||||
if element is None:
|
if element is None:
|
||||||
raise ValueError('Element cannot be None')
|
raise ValueError('Element cannot be None')
|
||||||
"
|
"
|
||||||
(python-tests-look-at "if")
|
(python-tests-look-at "if")
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(python-tests-look-at "raise")
|
(python-tests-look-at "raise")
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(should (= (python-indent-calculate-indentation) 4))))
|
(should (eq (car (python-indent-context)) :after-block-end))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-1 ()
|
(ert-deftest python-indent-dedenters-1 ()
|
||||||
"Test de-indentation for the elif keyword."
|
"Test de-indentation for the elif keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
if save:
|
if save:
|
||||||
try:
|
try:
|
||||||
write_to_disk(data)
|
write_to_disk(data)
|
||||||
|
@ -604,15 +793,15 @@ if save:
|
||||||
cleanup()
|
cleanup()
|
||||||
elif
|
elif
|
||||||
"
|
"
|
||||||
(python-tests-look-at "elif\n")
|
(python-tests-look-at "elif\n")
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(should (equal (python-indent-calculate-levels) '(0)))))
|
(should (= (python-indent-calculate-indentation t) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-2 ()
|
(ert-deftest python-indent-dedenters-2 ()
|
||||||
"Test de-indentation for the else keyword."
|
"Test de-indentation for the else keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
if save:
|
if save:
|
||||||
try:
|
try:
|
||||||
write_to_disk(data)
|
write_to_disk(data)
|
||||||
|
@ -627,43 +816,50 @@ if save:
|
||||||
finally:
|
finally:
|
||||||
data.free()
|
data.free()
|
||||||
"
|
"
|
||||||
(python-tests-look-at "else\n")
|
(python-tests-look-at "else\n")
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(should (equal (python-indent-calculate-levels) '(0 4 8)))))
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 4))
|
||||||
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 0))
|
||||||
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 8))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-3 ()
|
(ert-deftest python-indent-dedenters-3 ()
|
||||||
"Test de-indentation for the except keyword."
|
"Test de-indentation for the except keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
if save:
|
if save:
|
||||||
try:
|
try:
|
||||||
write_to_disk(data)
|
write_to_disk(data)
|
||||||
except
|
except
|
||||||
"
|
"
|
||||||
(python-tests-look-at "except\n")
|
(python-tests-look-at "except\n")
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(should (equal (python-indent-calculate-levels) '(4)))))
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-4 ()
|
(ert-deftest python-indent-dedenters-4 ()
|
||||||
"Test de-indentation for the finally keyword."
|
"Test de-indentation for the finally keyword."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
if save:
|
if save:
|
||||||
try:
|
try:
|
||||||
write_to_disk(data)
|
write_to_disk(data)
|
||||||
finally
|
finally
|
||||||
"
|
"
|
||||||
(python-tests-look-at "finally\n")
|
(python-tests-look-at "finally\n")
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 4))
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
(should (equal (python-indent-calculate-levels) '(4)))))
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-5 ()
|
(ert-deftest python-indent-dedenters-5 ()
|
||||||
"Test invalid levels are skipped in a complex example."
|
"Test invalid levels are skipped in a complex example."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
if save:
|
if save:
|
||||||
try:
|
try:
|
||||||
write_to_disk(data)
|
write_to_disk(data)
|
||||||
|
@ -676,29 +872,31 @@ if save:
|
||||||
do_cleanup()
|
do_cleanup()
|
||||||
else
|
else
|
||||||
"
|
"
|
||||||
(python-tests-look-at "else\n")
|
(python-tests-look-at "else\n")
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 8))
|
(should (= (python-indent-calculate-indentation) 8))
|
||||||
(should (equal (python-indent-calculate-levels) '(0 8)))))
|
(should (= (python-indent-calculate-indentation t) 0))
|
||||||
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 8))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-6 ()
|
(ert-deftest python-indent-dedenters-6 ()
|
||||||
"Test indentation is zero when no opening block for dedenter."
|
"Test indentation is zero when no opening block for dedenter."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
try:
|
try:
|
||||||
# if save:
|
# if save:
|
||||||
write_to_disk(data)
|
write_to_disk(data)
|
||||||
else
|
else
|
||||||
"
|
"
|
||||||
(python-tests-look-at "else\n")
|
(python-tests-look-at "else\n")
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(should (equal (python-indent-calculate-levels) '(0)))))
|
(should (= (python-indent-calculate-indentation t) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-7 ()
|
(ert-deftest python-indent-dedenters-7 ()
|
||||||
"Test indentation case from Bug#15163."
|
"Test indentation case from Bug#15163."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"
|
"
|
||||||
if a:
|
if a:
|
||||||
if b:
|
if b:
|
||||||
pass
|
pass
|
||||||
|
@ -706,10 +904,10 @@ if a:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
"
|
"
|
||||||
(python-tests-look-at "else:" 2)
|
(python-tests-look-at "else:" 2)
|
||||||
(should (eq (car (python-indent-context)) 'dedenter-statement))
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
(should (= (python-indent-calculate-indentation) 0))
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
(should (equal (python-indent-calculate-levels) '(0)))))
|
(should (= (python-indent-calculate-indentation t) 0))))
|
||||||
|
|
||||||
(ert-deftest python-indent-dedenters-8 ()
|
(ert-deftest python-indent-dedenters-8 ()
|
||||||
"Test indentation for Bug#18432."
|
"Test indentation for Bug#18432."
|
||||||
|
@ -721,10 +919,99 @@ if (a == 1 or
|
||||||
elif (a == 3 or
|
elif (a == 3 or
|
||||||
a == 4):
|
a == 4):
|
||||||
"
|
"
|
||||||
|
(python-tests-look-at "elif (a == 3 or")
|
||||||
|
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(should (= (python-indent-calculate-indentation t) 0))
|
||||||
(python-tests-look-at "a == 4):\n")
|
(python-tests-look-at "a == 4):\n")
|
||||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
(should (eq (car (python-indent-context)) :inside-paren))
|
||||||
(should (= (python-indent-calculate-indentation) 6))
|
(should (= (python-indent-calculate-indentation) 6))
|
||||||
(should (equal (python-indent-calculate-levels) '(0 4 6)))))
|
(python-indent-line)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 4))
|
||||||
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 0))
|
||||||
|
(python-indent-line t)
|
||||||
|
(should (= (python-indent-calculate-indentation t) 6))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-string-1 ()
|
||||||
|
"Test indentation for strings."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
multiline = '''
|
||||||
|
bunch
|
||||||
|
of
|
||||||
|
lines
|
||||||
|
'''
|
||||||
|
"
|
||||||
|
(python-tests-look-at "multiline = '''")
|
||||||
|
(should (eq (car (python-indent-context)) :after-line))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(python-tests-look-at "bunch")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(python-tests-look-at "of")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(python-tests-look-at "lines")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))
|
||||||
|
(python-tests-look-at "'''")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 0))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-string-2 ()
|
||||||
|
"Test indentation for docstrings."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
def fn(a, b, c=True):
|
||||||
|
'''docstring
|
||||||
|
bunch
|
||||||
|
of
|
||||||
|
lines
|
||||||
|
'''
|
||||||
|
"
|
||||||
|
(python-tests-look-at "'''docstring")
|
||||||
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "bunch")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "of")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "lines")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "'''")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
|
(ert-deftest python-indent-inside-string-3 ()
|
||||||
|
"Test indentation for nested strings."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
def fn(a, b, c=True):
|
||||||
|
some_var = '''
|
||||||
|
bunch
|
||||||
|
of
|
||||||
|
lines
|
||||||
|
'''
|
||||||
|
"
|
||||||
|
(python-tests-look-at "some_var = '''")
|
||||||
|
(should (eq (car (python-indent-context)) :after-block-start))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "bunch")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "of")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "lines")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))
|
||||||
|
(python-tests-look-at "'''")
|
||||||
|
(should (eq (car (python-indent-context)) :inside-string))
|
||||||
|
(should (= (python-indent-calculate-indentation) 4))))
|
||||||
|
|
||||||
(ert-deftest python-indent-electric-colon-1 ()
|
(ert-deftest python-indent-electric-colon-1 ()
|
||||||
"Test indentation case from Bug#18228."
|
"Test indentation case from Bug#18228."
|
||||||
|
|
Loading…
Add table
Reference in a new issue