mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-15 17:00:26 +00:00
Merge from origin/emacs-24
9664def
Signal a file-error from directory-files on MS-Windows (Bug#19701)fd4e65e
Added missing test for previous commit5485e3e5
python.el: New non-global state dependent indentation engine.3b23e6a
Fix the description of --insert command-line option (Bug#19694)7a7e594
Add a cross-reference in ELisp manual. (Bug#19668)b4f4075
Fixes: debbugs:1966083b3c31
* test/automated/regexp-tests.el: Require regexp-opt Conflicts: lisp/progmodes/python.el
This commit is contained in:
commit
95a2cb24b0
@ -1,3 +1,8 @@
|
||||
2015-01-26 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* cmdargs.texi (Action Arguments): Clarify into which buffer
|
||||
'--insert' inserts. (Bug#19694)
|
||||
|
||||
2015-01-21 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* programs.texi (Custom C Indent): Fix a typo. (Bug#19647)
|
||||
|
@ -165,9 +165,12 @@ Evaluate Lisp expression @var{expression}.
|
||||
@item --insert=@var{file}
|
||||
@opindex --insert
|
||||
@cindex insert file contents, command-line argument
|
||||
Insert the contents of @var{file} into the @file{*scratch*} buffer
|
||||
(@pxref{Lisp Interaction}). This is like what @kbd{M-x insert-file}
|
||||
does (@pxref{Misc File Ops}).
|
||||
Insert the contents of @var{file} into the buffer that is current when
|
||||
this command-line argument is processed. Usually, this is the
|
||||
@file{*scratch*} buffer (@pxref{Lisp Interaction}), but if arguments
|
||||
earlier on the command line visit files or switch buffers, that might
|
||||
be a different buffer. The effect of this command-line argument is
|
||||
like what @kbd{M-x insert-file} does (@pxref{Misc File Ops}).
|
||||
|
||||
@item --kill
|
||||
@opindex --kill
|
||||
|
@ -1,3 +1,8 @@
|
||||
2015-01-24 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* searching.texi (Regexp Search): Add a cross-reference to "Syntax
|
||||
of Regexps". (Bug#19668)
|
||||
|
||||
2015-01-21 Daniel Koning <dk@danielkoning.com> (tiny change)
|
||||
|
||||
* commands.texi (Drag Events, Motion Events, Event Examples)
|
||||
|
@ -988,10 +988,11 @@ list of characters @var{chars}.
|
||||
@cindex searching for regexp
|
||||
|
||||
In GNU Emacs, you can search for the next match for a regular
|
||||
expression either incrementally or not. For incremental search
|
||||
commands, see @ref{Regexp Search, , Regular Expression Search, emacs,
|
||||
The GNU Emacs Manual}. Here we describe only the search functions
|
||||
useful in programs. The principal one is @code{re-search-forward}.
|
||||
expression (@pxref{Syntax of Regexps}) either incrementally or not.
|
||||
For incremental search commands, see @ref{Regexp Search, , Regular
|
||||
Expression Search, emacs, The GNU Emacs Manual}. Here we describe
|
||||
only the search functions useful in programs. The principal one is
|
||||
@code{re-search-forward}.
|
||||
|
||||
These search functions convert the regular expression to multibyte if
|
||||
the buffer is multibyte; they convert the regular expression to unibyte
|
||||
|
@ -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-21 Daniel Koning <dk@danielkoning.com> (tiny change)
|
||||
|
||||
* subr.el (posnp): Correct docstring of `posnp'.
|
||||
|
@ -463,9 +463,14 @@ The type returned can be `comment', `string' or `paren'."
|
||||
((nth 8 ppss) (if (nth 4 ppss) 'comment 'string))
|
||||
((nth 1 ppss) 'paren))))
|
||||
|
||||
(defsubst python-syntax-comment-or-string-p ()
|
||||
"Return non-nil if point is inside 'comment or 'string."
|
||||
(nth 8 (syntax-ppss)))
|
||||
(defsubst python-syntax-comment-or-string-p (&optional ppss)
|
||||
"Return non-nil if PPSS is inside 'comment or 'string."
|
||||
(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
|
||||
'python-info-ppss-context #'python-syntax-context "24.3")
|
||||
@ -704,11 +709,28 @@ It makes underscores and dots word constituent chars.")
|
||||
'python-guess-indent 'python-indent-guess-indent-offset "24.3")
|
||||
|
||||
(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)
|
||||
"Levels of indentation available for `python-indent-line-function'.
|
||||
Can also be `noindent' if automatic indentation can't be used.")
|
||||
"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 ()
|
||||
"Guess and set `python-indent-offset' for the current buffer."
|
||||
@ -748,362 +770,358 @@ Can also be `noindent' if automatic indentation can't be used.")
|
||||
python-indent-offset)))))))
|
||||
|
||||
(defun python-indent-context ()
|
||||
"Get information on indentation context.
|
||||
Context information is returned with a cons with the form:
|
||||
(STATUS . START)
|
||||
"Get information about the current indentation context.
|
||||
Context is returned in a cons with the form (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
|
||||
* inside-paren: If point in between (), {} or []
|
||||
* inside-string: If point is inside a string
|
||||
* 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."
|
||||
keyword
|
||||
-------
|
||||
|
||||
:after-comment
|
||||
- Point is after a comment line.
|
||||
- START is the position of the \"#\" character.
|
||||
:inside-string
|
||||
- Point is inside string.
|
||||
- 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
|
||||
(widen)
|
||||
(let ((ppss (save-excursion (beginning-of-line) (syntax-ppss)))
|
||||
(start))
|
||||
(cons
|
||||
(cond
|
||||
;; Beginning of buffer
|
||||
((save-excursion
|
||||
(goto-char (line-beginning-position))
|
||||
(bobp))
|
||||
'no-indent)
|
||||
;; Comment continuation
|
||||
((save-excursion
|
||||
(when (and
|
||||
(or
|
||||
(python-info-current-line-comment-p)
|
||||
(python-info-current-line-empty-p))
|
||||
(progn
|
||||
(forward-comment -1)
|
||||
(python-info-current-line-comment-p)))
|
||||
(setq start (point))
|
||||
'after-comment)))
|
||||
;; Inside string
|
||||
((setq start (python-syntax-context 'string ppss))
|
||||
'inside-string)
|
||||
;; Inside a paren
|
||||
((setq start (python-syntax-context 'paren ppss))
|
||||
'inside-paren)
|
||||
;; After backslash
|
||||
((setq start (when (not (or (python-syntax-context 'string ppss)
|
||||
(python-syntax-context 'comment ppss)))
|
||||
(let ((line-beg-pos (line-number-at-pos)))
|
||||
(python-info-line-ends-backslash-p
|
||||
(1- line-beg-pos)))))
|
||||
'after-backslash)
|
||||
;; After beginning of block
|
||||
((setq start (save-excursion
|
||||
(when (progn
|
||||
(back-to-indentation)
|
||||
(python-util-forward-comment -1)
|
||||
(equal (char-before) ?:))
|
||||
;; Move to the first block start that's not in within
|
||||
;; a string, comment or paren and that's not a
|
||||
;; continuation line.
|
||||
(while (and (re-search-backward
|
||||
(python-rx block-start) nil t)
|
||||
(or
|
||||
(python-syntax-context-type)
|
||||
(python-info-continuation-line-p))))
|
||||
(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
|
||||
(let ((ppss (save-excursion
|
||||
(beginning-of-line)
|
||||
(syntax-ppss))))
|
||||
(cond
|
||||
;; Beginning of buffer.
|
||||
((= (line-number-at-pos) 1)
|
||||
(cons :no-indent 0))
|
||||
;; Comment continuation (maybe).
|
||||
((save-excursion
|
||||
(when (and
|
||||
(or
|
||||
(python-info-current-line-comment-p)
|
||||
(python-info-current-line-empty-p))
|
||||
(forward-comment -1)
|
||||
(python-info-current-line-comment-p))
|
||||
(cons :after-comment (point)))))
|
||||
;; Inside a string.
|
||||
((let ((start (python-syntax-context 'string ppss)))
|
||||
(when start
|
||||
(cons :inside-string start))))
|
||||
;; Inside a paren.
|
||||
((let* ((start (python-syntax-context 'paren ppss))
|
||||
(starts-in-newline
|
||||
(when start
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(forward-char)
|
||||
(not
|
||||
(= (line-number-at-pos)
|
||||
(progn
|
||||
(python-util-forward-comment)
|
||||
(line-number-at-pos))))))))
|
||||
(when start
|
||||
(cond
|
||||
;; Current line only holds the closing paren.
|
||||
((save-excursion
|
||||
(skip-syntax-forward " ")
|
||||
(when (and (python-syntax-closing-paren-p)
|
||||
(progn
|
||||
(forward-char 1)
|
||||
(not (python-syntax-context 'paren))))
|
||||
(cons :inside-paren-at-closing-paren start))))
|
||||
;; Current line only holds a closing paren for nested.
|
||||
((save-excursion
|
||||
(back-to-indentation)
|
||||
(python-syntax-closing-paren-p))
|
||||
(cons :inside-paren-at-closing-nested-paren start))
|
||||
;; This line starts from a opening block in its own line.
|
||||
((save-excursion
|
||||
(goto-char start)
|
||||
(when (and
|
||||
starts-in-newline
|
||||
(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)
|
||||
(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)
|
||||
(point-marker)))
|
||||
'after-line)
|
||||
;; Do not indent
|
||||
(t 'no-indent))
|
||||
start))))
|
||||
(point))))
|
||||
(when start
|
||||
(if (save-excursion
|
||||
(python-util-forward-comment -1)
|
||||
(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 ()
|
||||
"Calculate correct indentation offset for the current line.
|
||||
Returns `noindent' if the indentation does not depend on Python syntax,
|
||||
such as in strings."
|
||||
(let* ((indentation-context (python-indent-context))
|
||||
(context-status (car indentation-context))
|
||||
(context-start (cdr indentation-context)))
|
||||
(save-restriction
|
||||
(widen)
|
||||
(save-excursion
|
||||
(pcase context-status
|
||||
(`no-indent 0)
|
||||
(`after-comment
|
||||
(goto-char context-start)
|
||||
(current-indentation))
|
||||
;; When point is after beginning of block just add one level
|
||||
;; of indentation relative to the context-start
|
||||
(`after-beginning-of-block
|
||||
(goto-char context-start)
|
||||
(+ (current-indentation) python-indent-offset))
|
||||
;; When after a simple line just use previous line
|
||||
;; indentation.
|
||||
(`after-line
|
||||
(let* ((pair (save-excursion
|
||||
(goto-char context-start)
|
||||
(cons
|
||||
(current-indentation)
|
||||
(python-info-beginning-of-block-p))))
|
||||
(context-indentation (car pair))
|
||||
;; TODO: Separate block enders into its own case.
|
||||
(adjustment
|
||||
(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
|
||||
(`inside-string 'noindent)
|
||||
;; After backslash we have several possibilities.
|
||||
(`after-backslash
|
||||
(cond
|
||||
;; Check if current line is a dot continuation. For this
|
||||
;; the current line must start with a dot and previous
|
||||
;; line must contain a dot too.
|
||||
((save-excursion
|
||||
(back-to-indentation)
|
||||
(when (looking-at "\\.")
|
||||
;; If after moving one line back point is inside a paren it
|
||||
;; needs to move back until it's not anymore
|
||||
(while (prog2
|
||||
(forward-line -1)
|
||||
(and (not (bobp))
|
||||
(python-syntax-context 'paren))))
|
||||
(goto-char (line-end-position))
|
||||
(while (and (re-search-backward
|
||||
"\\." (line-beginning-position) t)
|
||||
(python-syntax-context-type)))
|
||||
(if (and (looking-at "\\.")
|
||||
(not (python-syntax-context-type)))
|
||||
;; The indentation is the same column of the
|
||||
;; first matching dot that's not inside a
|
||||
;; comment, a string or a paren
|
||||
(current-column)
|
||||
;; No dot found on previous line, just add another
|
||||
;; indentation level.
|
||||
(+ (current-indentation) python-indent-offset)))))
|
||||
;; Check if prev line is a block continuation
|
||||
((let ((block-continuation-start
|
||||
(python-info-block-continuation-line-p)))
|
||||
(when block-continuation-start
|
||||
;; If block-continuation-start is set jump to that
|
||||
;; marker and use first column after the block start
|
||||
;; as indentation value.
|
||||
(goto-char block-continuation-start)
|
||||
(re-search-forward
|
||||
(python-rx block-start (* space))
|
||||
(line-end-position) t)
|
||||
(current-column))))
|
||||
;; Check if current line is an assignment continuation
|
||||
((let ((assignment-continuation-start
|
||||
(python-info-assignment-continuation-line-p)))
|
||||
(when assignment-continuation-start
|
||||
;; If assignment-continuation is set jump to that
|
||||
;; marker and use first column after the assignment
|
||||
;; operator as indentation value.
|
||||
(goto-char assignment-continuation-start)
|
||||
(current-column))))
|
||||
(t
|
||||
(forward-line -1)
|
||||
(goto-char (python-info-beginning-of-backslash))
|
||||
(if (save-excursion
|
||||
(and
|
||||
(forward-line -1)
|
||||
(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-indentation ()
|
||||
"Internal implementation of `python-indent-calculate-indentation'.
|
||||
May return an integer for the maximum possible indentation at
|
||||
current context or a list of integers. The latter case is only
|
||||
happening for :at-dedenter-block-start context since the
|
||||
possibilities can be narrowed to especific indentation points."
|
||||
(save-restriction
|
||||
(widen)
|
||||
(save-excursion
|
||||
(pcase (python-indent-context)
|
||||
(`(:no-indent . ,_) 0)
|
||||
(`(,(or :after-line
|
||||
:after-comment
|
||||
:inside-string
|
||||
:after-backslash
|
||||
:inside-paren-at-closing-paren
|
||||
:inside-paren-at-closing-nested-paren) . ,start)
|
||||
;; Copy previous indentation.
|
||||
(goto-char start)
|
||||
(current-indentation))
|
||||
(`(,(or :after-block-start
|
||||
:after-backslash-first-line
|
||||
:inside-paren-newline-start) . ,start)
|
||||
;; Add one indentation level.
|
||||
(goto-char start)
|
||||
(+ (current-indentation) python-indent-offset))
|
||||
(`(,(or :inside-paren
|
||||
:after-backslash-block-continuation
|
||||
:after-backslash-assignment-continuation
|
||||
:after-backslash-dotted-continuation) . ,start)
|
||||
;; Use the column given by the context.
|
||||
(goto-char start)
|
||||
(current-column))
|
||||
(`(:after-block-end . ,start)
|
||||
;; Subtract one indentation level.
|
||||
(goto-char start)
|
||||
(- (current-indentation) python-indent-offset))
|
||||
(`(:at-dedenter-block-start . ,_)
|
||||
;; List all possible indentation levels from opening blocks.
|
||||
(let ((opening-block-start-points
|
||||
(python-info-dedenter-opening-block-positions)))
|
||||
(if (not opening-block-start-points)
|
||||
0 ; if not found default to first column
|
||||
(mapcar (lambda (pos)
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(current-indentation)))
|
||||
opening-block-start-points))))
|
||||
(`(,(or :inside-paren-newline-start-from-block) . ,start)
|
||||
;; Add two indentation levels to make the suite stand out.
|
||||
(goto-char start)
|
||||
(+ (current-indentation) (* python-indent-offset 2)))))))
|
||||
|
||||
(defun python-indent--calculate-levels (indentation)
|
||||
"Calculate levels list given INDENTATION.
|
||||
Argument INDENTATION can either be an integer or a list of
|
||||
integers. Levels are returned in ascending order, and in the
|
||||
case INDENTATION is a list, this order is enforced."
|
||||
(if (listp indentation)
|
||||
(sort (copy-sequence indentation) #'<)
|
||||
(let* ((remainder (% indentation python-indent-offset))
|
||||
(steps (/ (- indentation remainder) python-indent-offset))
|
||||
(levels (mapcar (lambda (step)
|
||||
(* python-indent-offset step))
|
||||
(number-sequence steps 0 -1))))
|
||||
(reverse
|
||||
(if (not (zerop remainder))
|
||||
(cons indentation levels)
|
||||
levels)))))
|
||||
|
||||
(defun python-indent--previous-level (levels indentation)
|
||||
"Return previous level from LEVELS relative to INDENTATION."
|
||||
(let* ((levels (sort (copy-sequence levels) #'>))
|
||||
(default (car levels)))
|
||||
(catch 'return
|
||||
(dolist (level levels)
|
||||
(when (funcall #'< level indentation)
|
||||
(throw 'return level)))
|
||||
default)))
|
||||
|
||||
(defun python-indent-calculate-indentation (&optional previous)
|
||||
"Calculate indentation.
|
||||
Get indentation of PREVIOUS level when argument is non-nil.
|
||||
Return the max level of the cycle when indentation reaches the
|
||||
minimum."
|
||||
(let* ((indentation (python-indent--calculate-indentation))
|
||||
(levels (python-indent--calculate-levels indentation)))
|
||||
(if previous
|
||||
(python-indent--previous-level levels (current-indentation))
|
||||
(apply #'max levels))))
|
||||
|
||||
(defun python-indent-line (&optional previous)
|
||||
"Internal implementation of `python-indent-line-function'.
|
||||
Use the PREVIOUS level when argument is non-nil, otherwise indent
|
||||
to the maxium available level. When indentation is the minimum
|
||||
possible and PREVIOUS is non-nil, cycle back to the maximum
|
||||
level."
|
||||
(let ((follow-indentation-p
|
||||
;; Check if point is within indentation.
|
||||
(and (<= (line-beginning-position) (point))
|
||||
(>= (+ (line-beginning-position)
|
||||
(current-indentation))
|
||||
(point)))))
|
||||
(save-excursion
|
||||
(indent-line-to
|
||||
(python-indent-calculate-indentation previous))
|
||||
(python-info-dedenter-opening-block-message))
|
||||
(when follow-indentation-p
|
||||
(back-to-indentation))))
|
||||
|
||||
(defun python-indent-calculate-levels ()
|
||||
"Calculate `python-indent-levels' and reset `python-indent-current-level'."
|
||||
(if (or (python-info-continuation-line-p)
|
||||
(not (python-info-dedenter-statement-p)))
|
||||
;; 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)))
|
||||
(if (not (numberp indentation))
|
||||
(setq python-indent-levels indentation)
|
||||
(let* ((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))))
|
||||
(when (listp python-indent-levels)
|
||||
(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)"
|
||||
(if (and (or (and (memq this-command python-indent-trigger-commands)
|
||||
(eq last-command this-command))
|
||||
force-toggle)
|
||||
(not (equal python-indent-levels '(0))))
|
||||
(if (listp python-indent-levels)
|
||||
(python-indent-toggle-levels))
|
||||
(python-indent-calculate-levels))
|
||||
(if (eq python-indent-levels 'noindent)
|
||||
python-indent-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)))
|
||||
"Return possible indentation levels."
|
||||
(python-indent--calculate-levels
|
||||
(python-indent--calculate-indentation)))
|
||||
|
||||
(defun python-indent-line-function ()
|
||||
"`indent-line-function' for Python mode.
|
||||
See `python-indent-line' for details."
|
||||
(python-indent-line))
|
||||
When the variable `last-command' is equal to one of the symbols
|
||||
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 ()
|
||||
"De-indent current line."
|
||||
(interactive "*")
|
||||
(when (and (not (python-syntax-comment-or-string-p))
|
||||
(<= (point) (save-excursion
|
||||
(back-to-indentation)
|
||||
(point)))
|
||||
(> (current-column) 0))
|
||||
(python-indent-line t)
|
||||
t))
|
||||
(when (and (not (bolp))
|
||||
(not (python-syntax-comment-or-string-p))
|
||||
(= (+ (line-beginning-position)
|
||||
(current-indentation))
|
||||
(point)))
|
||||
(python-indent-line t)
|
||||
t))
|
||||
|
||||
(defun python-indent-dedent-line-backspace (arg)
|
||||
"De-indent current line.
|
||||
Argument ARG is passed to `backward-delete-char-untabify' when
|
||||
point is not in between the indentation."
|
||||
(interactive "*p")
|
||||
(when (not (python-indent-dedent-line))
|
||||
(unless (python-indent-dedent-line)
|
||||
(backward-delete-char-untabify arg)))
|
||||
|
||||
(put 'python-indent-dedent-line-backspace 'delete-selection 'supersede)
|
||||
|
||||
(defun python-indent-region (start end)
|
||||
|
@ -1,3 +1,16 @@
|
||||
2015-01-27 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* dired.c (directory_files_internal) [WINDOWSNT]: If readdir
|
||||
returns NULL and errno is ENOTDIR, behave as if opendir failed to
|
||||
open the directory. (Bug#19701)
|
||||
|
||||
* w32.c (sys_readdir): If FindFirstFile fails because the
|
||||
directory doesn't exist, set errno to ENOTDIR.
|
||||
|
||||
2015-01-24 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* nsterm.m (drawRect:): Add block/unblock_input (Bug#19660).
|
||||
|
||||
2015-01-21 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Fix coding.c subscript error
|
||||
|
13
src/dired.c
13
src/dired.c
@ -238,6 +238,19 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
|
||||
QUIT;
|
||||
continue;
|
||||
}
|
||||
#ifdef WINDOWSNT
|
||||
/* The MS-Windows implementation of 'opendir' doesn't
|
||||
actually open a directory until the first call to
|
||||
'readdir'. If 'readdir' fails to open the directory, it
|
||||
sets errno to ENOTDIR; we convert it here to ENOENT so
|
||||
that the error message is similar to what happens on
|
||||
Posix hosts in such cases. */
|
||||
if (errno == ENOTDIR)
|
||||
{
|
||||
errno = ENOENT;
|
||||
report_file_error ("Opening directory", directory);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6773,7 +6773,9 @@ - (void)drawRect: (NSRect)rect
|
||||
return;
|
||||
|
||||
ns_clear_frame_area (emacsframe, x, y, width, height);
|
||||
block_input ();
|
||||
expose_frame (emacsframe, x, y, width, height);
|
||||
unblock_input ();
|
||||
|
||||
/*
|
||||
drawRect: may be called (at least in OS X 10.5) for invisible
|
||||
|
17
src/w32.c
17
src/w32.c
@ -3433,7 +3433,22 @@ sys_readdir (DIR *dirp)
|
||||
}
|
||||
|
||||
if (dir_find_handle == INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
{
|
||||
switch (GetLastError ())
|
||||
{
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
case ERROR_ACCESS_DENIED:
|
||||
case ERROR_INVALID_DRIVE:
|
||||
case ERROR_BAD_NETPATH:
|
||||
/* This special value will be noticed by
|
||||
directory_files_internal, which see. */
|
||||
errno = ENOTDIR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (w32_unicode_filenames)
|
||||
{
|
||||
|
@ -1,3 +1,30 @@
|
||||
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>
|
||||
|
||||
* automated/regexp-tests.el: Require regexp-opt, which is
|
||||
not preloaded --without-x.
|
||||
|
||||
2015-01-26 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* automated/cl-generic-tests.el: Try and make sure cl-lib is not
|
||||
|
@ -174,13 +174,13 @@ aliqua."
|
||||
foo = long_function_name(var_one, var_two,
|
||||
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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(ert-deftest python-indent-pep8-2 ()
|
||||
@ -192,19 +192,22 @@ def long_function_name(
|
||||
var_four):
|
||||
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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(ert-deftest python-indent-pep8-3 ()
|
||||
@ -215,18 +218,34 @@ foo = long_function_name(
|
||||
var_one, var_two,
|
||||
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))
|
||||
(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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(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 ()
|
||||
"The most simple after-comment case that shouldn't fail."
|
||||
(python-tests-with-temp-buffer
|
||||
@ -240,23 +259,23 @@ class Blag(object):
|
||||
# with the exception with which the first child failed.
|
||||
"
|
||||
(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))
|
||||
(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))
|
||||
(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
|
||||
;; that it was under-indented.
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-tests-look-at "# terminal state" -1)
|
||||
;; 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)
|
||||
(should (= (current-indentation) 8))
|
||||
(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.
|
||||
(should (= (python-indent-calculate-indentation) 8))))
|
||||
|
||||
@ -275,33 +294,33 @@ now_we_do_mess_cause_this_is_not_a_comment = 1
|
||||
# yeah, that.
|
||||
"
|
||||
(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))
|
||||
(python-tests-look-at "return arg")
|
||||
;; Comment here just gets ignored, this line is not a comment so
|
||||
;; 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))
|
||||
(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
|
||||
;; let's assume this comment was placed there because the user
|
||||
;; wanted to (manually adding spaces or whatever).
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(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))
|
||||
;; Behave the same for blank lines: potentially a comment.
|
||||
(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))
|
||||
(python-tests-look-at "now_we_do_mess")
|
||||
;; Here is where comment indentation starts to get ignored and
|
||||
;; 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))
|
||||
(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))))
|
||||
|
||||
(ert-deftest python-indent-inside-paren-1 ()
|
||||
@ -325,49 +344,53 @@ 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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(ert-deftest python-indent-inside-paren-2 ()
|
||||
@ -384,43 +407,121 @@ data = {'key': {
|
||||
}}
|
||||
"
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(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 ()
|
||||
"The most simple after-block case that shouldn't fail."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
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))
|
||||
(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))))
|
||||
|
||||
(ert-deftest python-indent-after-block-2 ()
|
||||
@ -432,9 +533,28 @@ def foo(a, b, c={
|
||||
}):
|
||||
"
|
||||
(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))))
|
||||
|
||||
(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 ()
|
||||
"The most common case."
|
||||
(python-tests-with-temp-buffer
|
||||
@ -444,16 +564,16 @@ from foo.bar.baz import something, something_1 \\\\
|
||||
something_4, something_5
|
||||
"
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(ert-deftest python-indent-after-backslash-2 ()
|
||||
@ -471,40 +591,104 @@ objects = Thing.objects.all() \\\\
|
||||
.values_list()
|
||||
"
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))
|
||||
(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))))
|
||||
|
||||
(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 ()
|
||||
"Test de-indentation for pass keyword."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
"
|
||||
Class foo(object):
|
||||
|
||||
def bar(self):
|
||||
@ -516,17 +700,18 @@ 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 (eq (car (python-indent-context)) :after-block-end))
|
||||
(should (= (python-indent-calculate-indentation) 8))))
|
||||
|
||||
(ert-deftest python-indent-block-enders-2 ()
|
||||
"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
|
||||
|
||||
@ -539,64 +724,68 @@ 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 "return")
|
||||
(should (= (python-indent-calculate-indentation) 12))
|
||||
(goto-char (point-max))
|
||||
(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 (eq (car (python-indent-context)) :after-block-end))
|
||||
(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))))
|
||||
(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 (eq (car (python-indent-context)) :after-block-end))
|
||||
(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))))
|
||||
(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 (eq (car (python-indent-context)) :after-block-end))
|
||||
(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))))
|
||||
(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 (eq (car (python-indent-context)) :after-block-end))
|
||||
(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)
|
||||
@ -604,15 +793,15 @@ if save:
|
||||
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)))))
|
||||
(python-tests-look-at "elif\n")
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (= (python-indent-calculate-indentation t) 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)
|
||||
@ -627,43 +816,50 @@ if save:
|
||||
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)))))
|
||||
(python-tests-look-at "else\n")
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 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 ()
|
||||
"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)))))
|
||||
(python-tests-look-at "except\n")
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-indent-line t)
|
||||
(should (= (python-indent-calculate-indentation t) 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)))))
|
||||
(python-tests-look-at "finally\n")
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 4))
|
||||
(python-indent-line t)
|
||||
(should (= (python-indent-calculate-indentation) 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)
|
||||
@ -676,29 +872,31 @@ if save:
|
||||
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)))))
|
||||
(python-tests-look-at "else\n")
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 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 ()
|
||||
"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)))))
|
||||
(python-tests-look-at "else\n")
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (= (python-indent-calculate-indentation t) 0))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-7 ()
|
||||
"Test indentation case from Bug#15163."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
"
|
||||
if a:
|
||||
if b:
|
||||
pass
|
||||
@ -706,10 +904,10 @@ if a:
|
||||
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)))))
|
||||
(python-tests-look-at "else:" 2)
|
||||
(should (eq (car (python-indent-context)) :at-dedenter-block-start))
|
||||
(should (= (python-indent-calculate-indentation) 0))
|
||||
(should (= (python-indent-calculate-indentation t) 0))))
|
||||
|
||||
(ert-deftest python-indent-dedenters-8 ()
|
||||
"Test indentation for Bug#18432."
|
||||
@ -721,10 +919,99 @@ if (a == 1 or
|
||||
elif (a == 3 or
|
||||
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")
|
||||
(should (eq (car (python-indent-context)) 'inside-paren))
|
||||
(should (eq (car (python-indent-context)) :inside-paren))
|
||||
(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 ()
|
||||
"Test indentation case from Bug#18228."
|
||||
@ -1802,6 +2089,23 @@ def f():
|
||||
(python-nav-backward-up-list)
|
||||
(should (looking-at "def f():"))))
|
||||
|
||||
(ert-deftest python-indent-dedent-line-backspace-1 ()
|
||||
"Check de-indentation on first call. Bug#18319."
|
||||
(python-tests-with-temp-buffer
|
||||
"
|
||||
if True:
|
||||
x ()
|
||||
if False:
|
||||
"
|
||||
(python-tests-look-at "if False:")
|
||||
(call-interactively #'python-indent-dedent-line-backspace)
|
||||
(should (zerop (current-indentation)))
|
||||
;; XXX: This should be a call to `undo' but it's triggering errors.
|
||||
(insert " ")
|
||||
(should (= (current-indentation) 4))
|
||||
(call-interactively #'python-indent-dedent-line-backspace)
|
||||
(should (zerop (current-indentation)))))
|
||||
|
||||
|
||||
;;; Shell integration
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'regexp-opt)
|
||||
|
||||
(ert-deftest regexp-test-regexp-opt ()
|
||||
"Test the `compilation-error-regexp-alist' regexps.
|
||||
The test data is in `compile-tests--test-regexps-data'."
|
||||
|
Loading…
Reference in New Issue
Block a user