summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Makefile.in5
-rw-r--r--etc/PROBLEMS32
-rw-r--r--lib-src/ChangeLog4
-rw-r--r--lib-src/etags.c3
-rw-r--r--lisp/ChangeLog38
-rw-r--r--lisp/faces.el7
-rw-r--r--lisp/progmodes/python.el204
-rw-r--r--lisp/vc/log-edit.el78
-rw-r--r--lisp/vc/vc-dispatcher.el2
-rw-r--r--src/ChangeLog10
-rw-r--r--src/w32fns.c6
-rw-r--r--src/xdisp.c5
-rw-r--r--src/xfns.c12
-rw-r--r--test/ChangeLog30
-rw-r--r--test/automated/python-tests.el750
16 files changed, 943 insertions, 247 deletions
diff --git a/ChangeLog b/ChangeLog
index f763607537f..5e6822737f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ * Makefile.in (install-arch-indep): Avoid readdir race (Bug#17971).
+
2014-07-10 Dmitry Antipov <dmantipov@yandex.ru>
* configure.ac: Check whether sys/sysinfo.h provides
diff --git a/Makefile.in b/Makefile.in
index 0fd9f980ca9..6b24147c8d3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -594,8 +594,9 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
[ -z "${GZIP_PROG}" ] || { \
echo "Compressing *.el ..." && \
cd "$(DESTDIR)${lispdir}" && \
- find . -name '*.elc' -exec $(SHELL) -c \
- '${GZIP_PROG} -9n `expr "$$1" : "\\(.*\\)c"`' dummy '{}' ';'; \
+ for f in `find . -name "*.elc" -print | sed 's/.elc$$/.el/'`; do \
+ ${GZIP_PROG} -9n "$$f"; \
+ done; \
}
-chmod -R a+r "$(DESTDIR)${datadir}/emacs/${version}" ${COPYDESTS}
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 98e19d3e760..ed41ddf65a3 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -1931,6 +1931,16 @@ MSDN:
includes a short description of MSLU and a link where it can be
downloaded.
+** Emacs refuses to start on Windows 9X because ctime64 function is missing
+
+This is a sign that Emacs was compiled with MinGW runtime version
+4.0.x or later. These versions of runtime call in their startup code
+the ctime64 function, which does not exist in MSVCRT.DLL, the C
+runtime shared library, distributed with Windows 9X.
+
+A workaround is to build Emacs with MinGW runtime 3.x (the latest
+version is 3.20).
+
** A few seconds delay is seen at startup and for many file operations
This happens when the Net Logon service is enabled. During Emacs
@@ -1965,6 +1975,26 @@ Another possibility is to rebuild Emacs with the -shared-libgcc
switch, which will force Emacs to load libgcc_s_dw2-1.dll on startup,
ahead of any optional DLLs loaded on-demand later in the session.
+** File selection dialog opens in incorrect directories
+
+Invoking the file selection dialog on Windows 7 or later shows a
+directory that is different from what was passed to `read-file-name'
+or `x-file-dialog' via their arguments.
+
+This is due to a deliberate change in behavior of the file selection
+dialogs introduced in Windows 7. It is explicitly described in the
+MSDN documentation of the GetOpenFileName API used by Emacs to pop up
+the file selection dialog. For the details, see
+
+ http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx
+
+The dialog shows the last directory in which the user selected a file
+in a previous invocation of the dialog with the same initial
+directory.
+
+You can reset this "memory" of that directory by invoking the file
+selection dialog with a different initial directory.
+
** PATH can contain unexpanded environment variables
Old releases of TCC (version 9) and 4NT (up to version 8) do not correctly
@@ -2098,7 +2128,7 @@ The function set-time-zone-rule gives incorrect results for many
non-US timezones. This is due to over-simplistic handling of
daylight savings switchovers by the Windows libraries.
-** Files larger than 4GB report wrong size
+** Files larger than 4GB report wrong size in a 32-bit Windows build
Files larger than 4GB cause overflow in the size (represented as a
32-bit integer) reported by `file-attributes'. This affects Dired as
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 64a73027915..3a7d128b905 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,7 @@
+2014-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ * etags.c (Lisp_functions): Also record cl-defun etc. (Bug#17965)
+
2014-06-26 Glenn Morris <rgm@gnu.org>
* Makefile.in (blessmail): Depend on lisp/mail/blessmail.el.
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 66e7fbb467f..5f1f99c4677 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -4747,6 +4747,9 @@ Lisp_functions (FILE *inf)
}
}
+ if (strneq (dbp + 1, "cl-", 3) || strneq (dbp + 1, "CL-", 3))
+ dbp += 3;
+
if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3))
{
dbp = skip_non_spaces (dbp);
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index faa5a3dffff..db1f0481d62 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,41 @@
+2014-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug: C-x v v discarded existing log message (Bug#17884).
+ * vc/vc-dispatcher.el (vc-log-edit):
+ Don't clobber an already-existing log message.
+
+2014-07-12 Glenn Morris <rgm@gnu.org>
+
+ * vc/log-edit.el (log-edit-changelog-entries):
+ Check for a visited-but-never-saved ChangeLog.
+
+2014-07-12 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * vc/log-edit.el (log-edit-changelog-entries): Don't both visiting
+ a non-existing file (bug#17970).
+
+ * faces.el (face-name): Undo last change.
+ (x-resolve-font-name): Don't call face-name (bug#17956).
+
+2014-07-12 Fabián Ezequiel Gallina <fgallina@gnu.org>
+
+ Fix dedenters and electric colon handling. (Bug#15163)
+ * progmodes/python.el
+ (python-rx-constituents): Add dedenter and block-ender.
+ (python-indent-dedenters, python-indent-block-enders): Delete.
+ (python-indent-context): Return new case for dedenter-statement.
+ (python-indent-calculate-indentation): Handle new case.
+ (python-indent-calculate-levels): Fix levels calculation for
+ dedenter statements.
+ (python-indent-post-self-insert-function): Fix colon handling.
+ (python-info-dedenter-opening-block-message): New function.
+ (python-indent-line): Use it.
+ (python-info-closing-block)
+ (python-info-closing-block-message): Remove.
+ (python-info-dedenter-opening-block-position)
+ (python-info-dedenter-opening-block-positions)
+ (python-info-dedenter-statement-p): New functions.
+
2014-07-11 Dmitry Antipov <dmantipov@yandex.ru>
* files.el (out-of-memory-warning-percentage): New defcustom.
diff --git a/lisp/faces.el b/lisp/faces.el
index bb77af0425e..d9239d9e1eb 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -370,10 +370,7 @@ If `inhibit-x-resources' is non-nil, this function does nothing."
(defun face-name (face)
"Return the name of face FACE."
- (check-face face)
- (if (symbolp face)
- (symbol-name face)
- face))
+ (symbol-name (check-face face)))
(defun face-all-attributes (face &optional frame)
@@ -2749,8 +2746,6 @@ If PATTERN is nil, return the name of the frame's base font, which never
contains wildcards.
Given optional arguments FACE and FRAME, return a font which is
also the same size as FACE on FRAME, or fail."
- (when face
- (setq face (face-name face)))
(and (eq frame t)
(setq frame nil))
(if pattern
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 065a182904f..1187636c663 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -321,6 +321,13 @@
(or "def" "class" "if" "elif" "else" "try"
"except" "finally" "for" "while" "with")
symbol-end))
+ (dedenter . ,(rx symbol-start
+ (or "elif" "else" "except" "finally")
+ symbol-end))
+ (block-ender . ,(rx symbol-start
+ (or
+ "break" "continue" "pass" "raise" "return")
+ symbol-end))
(decorator . ,(rx line-start (* space) ?@ (any letter ?_)
(* (any word ?_))))
(defun . ,(rx symbol-start (or "def" "class") symbol-end))
@@ -630,18 +637,6 @@ It makes underscores and dots word constituent chars.")
(defvar python-indent-levels '(0)
"Levels of indentation available for `python-indent-line-function'.")
-(defvar python-indent-dedenters '("else" "elif" "except" "finally")
- "List of words that should be dedented.
-These make `python-indent-calculate-indentation' subtract the value of
-`python-indent-offset'.")
-
-(defvar python-indent-block-enders
- '("break" "continue" "pass" "raise" "return")
- "List of words that mark the end of a block.
-These make `python-indent-calculate-indentation' subtract the
-value of `python-indent-offset' when `python-indent-context' is
-AFTER-LINE.")
-
(defun python-indent-guess-indent-offset ()
"Guess and set `python-indent-offset' for the current buffer."
(interactive)
@@ -692,6 +687,7 @@ Where status can be any of the following symbols:
* after-backslash: Previous line ends in a backslash
* after-beginning-of-block: Point is after beginning of block
* after-line: Point is after normal line
+ * dedenter-statement: Point is on a dedenter statement.
* no-indent: Point is at beginning of buffer or other special case
START is the buffer position where the sexp starts."
(save-restriction
@@ -746,6 +742,8 @@ START is the buffer position where the sexp starts."
(when (looking-at (python-rx block-start))
(point-marker)))))
'after-beginning-of-block)
+ ((when (setq start (python-info-dedenter-statement-p))
+ 'dedenter-statement))
;; After normal line
((setq start (save-excursion
(back-to-indentation)
@@ -776,8 +774,7 @@ START is the buffer position where the sexp starts."
(goto-char context-start)
(+ (current-indentation) python-indent-offset))
;; When after a simple line just use previous line
- ;; indentation, in the case current line starts with a
- ;; `python-indent-dedenters' de-indent one level.
+ ;; indentation.
(`after-line
(let* ((pair (save-excursion
(goto-char context-start)
@@ -785,25 +782,27 @@ START is the buffer position where the sexp starts."
(current-indentation)
(python-info-beginning-of-block-p))))
(context-indentation (car pair))
- (after-block-start-p (cdr pair))
+ ;; TODO: Separate block enders into its own case.
(adjustment
- (if (or (save-excursion
- (back-to-indentation)
- (and
- ;; De-indent only when dedenters are not
- ;; next to a block start. This allows
- ;; one-liner constructs such as:
- ;; if condition: print "yay"
- ;; else: print "wry"
- (not after-block-start-p)
- (looking-at (regexp-opt python-indent-dedenters))))
- (save-excursion
- (python-util-forward-comment -1)
- (python-nav-beginning-of-statement)
- (looking-at (regexp-opt python-indent-block-enders))))
+ (if (save-excursion
+ (python-util-forward-comment -1)
+ (python-nav-beginning-of-statement)
+ (looking-at (python-rx block-ender)))
python-indent-offset
0)))
(- context-indentation adjustment)))
+ ;; When point is on a dedenter statement, search for the
+ ;; opening block that corresponds to it and use its
+ ;; indentation. If no opening block is found just remove
+ ;; indentation as this is an invalid python file.
+ (`dedenter-statement
+ (let ((block-start-point
+ (python-info-dedenter-opening-block-position)))
+ (save-excursion
+ (if (not block-start-point)
+ 0
+ (goto-char block-start-point)
+ (current-indentation)))))
;; When inside of a string, do nothing. just use the current
;; indentation. XXX: perhaps it would be a good idea to
;; invoke standard text indentation here
@@ -930,16 +929,25 @@ START is the buffer position where the sexp starts."
(defun python-indent-calculate-levels ()
"Calculate `python-indent-levels' and reset `python-indent-current-level'."
- (let* ((indentation (python-indent-calculate-indentation))
- (remainder (% indentation python-indent-offset))
- (steps (/ (- indentation remainder) python-indent-offset)))
- (setq python-indent-levels (list 0))
- (dotimes (step steps)
- (push (* python-indent-offset (1+ step)) python-indent-levels))
- (when (not (eq 0 remainder))
- (push (+ (* python-indent-offset steps) remainder) python-indent-levels))
- (setq python-indent-levels (nreverse python-indent-levels))
- (setq python-indent-current-level (1- (length python-indent-levels)))))
+ (if (not (python-info-dedenter-statement-p))
+ (let* ((indentation (python-indent-calculate-indentation))
+ (remainder (% indentation python-indent-offset))
+ (steps (/ (- indentation remainder) python-indent-offset)))
+ (setq python-indent-levels (list 0))
+ (dotimes (step steps)
+ (push (* python-indent-offset (1+ step)) python-indent-levels))
+ (when (not (eq 0 remainder))
+ (push (+ (* python-indent-offset steps) remainder) python-indent-levels)))
+ (setq python-indent-levels
+ (or
+ (mapcar (lambda (pos)
+ (save-excursion
+ (goto-char pos)
+ (current-indentation)))
+ (python-info-dedenter-opening-block-positions))
+ (list 0))))
+ (setq python-indent-current-level (1- (length python-indent-levels))
+ python-indent-levels (nreverse python-indent-levels)))
(defun python-indent-toggle-levels ()
"Toggle `python-indent-current-level' over `python-indent-levels'."
@@ -988,7 +996,7 @@ equal to
(indent-to next-indent)
(goto-char starting-pos))
(and follow-indentation-p (back-to-indentation)))
- (python-info-closing-block-message))
+ (python-info-dedenter-opening-block-message))
(defun python-indent-line-function ()
"`indent-line-function' for Python mode.
@@ -1124,14 +1132,7 @@ the line will be re-indented automatically if needed."
(eolp)
(not (equal ?: (char-before (1- (point)))))
(not (python-syntax-comment-or-string-p)))
- (let ((indentation (current-indentation))
- (calculated-indentation (python-indent-calculate-indentation)))
- (python-info-closing-block-message)
- (when (> indentation calculated-indentation)
- (save-excursion
- (indent-line-to calculated-indentation)
- (when (not (python-info-closing-block-message))
- (indent-line-to indentation)))))))))
+ (python-indent-line)))))
;;; Navigation
@@ -3454,49 +3455,88 @@ parent defun name."
(and (python-info-end-of-statement-p)
(python-info-statement-ends-block-p)))
-(defun python-info-closing-block ()
- "Return the point of the block the current line closes."
- (let ((closing-word (save-excursion
- (back-to-indentation)
- (current-word)))
- (indentation (current-indentation)))
- (when (member closing-word python-indent-dedenters)
+(define-obsolete-function-alias
+ 'python-info-closing-block
+ 'python-info-dedenter-opening-block-position "24.4")
+
+(defun python-info-dedenter-opening-block-position ()
+ "Return the point of the closest block the current line closes.
+Returns nil if point is not on a dedenter statement or no opening
+block can be detected. The latter case meaning current file is
+likely an invalid python file."
+ (let ((positions (python-info-dedenter-opening-block-positions))
+ (indentation (current-indentation))
+ (position))
+ (while (and (not position)
+ positions)
(save-excursion
- (forward-line -1)
- (while (and (> (current-indentation) indentation)
- (not (bobp))
- (not (back-to-indentation))
- (forward-line -1)))
- (back-to-indentation)
- (cond
- ((not (equal indentation (current-indentation))) nil)
- ((string= closing-word "elif")
- (when (member (current-word) '("if" "elif"))
- (point-marker)))
- ((string= closing-word "else")
- (when (member (current-word) '("if" "elif" "except" "for" "while"))
- (point-marker)))
- ((string= closing-word "except")
- (when (member (current-word) '("try"))
- (point-marker)))
- ((string= closing-word "finally")
- (when (member (current-word) '("except" "else"))
- (point-marker))))))))
-
-(defun python-info-closing-block-message (&optional closing-block-point)
- "Message the contents of the block the current line closes.
-With optional argument CLOSING-BLOCK-POINT use that instead of
-recalculating it calling `python-info-closing-block'."
- (let ((point (or closing-block-point (python-info-closing-block))))
+ (goto-char (car positions))
+ (if (<= (current-indentation) indentation)
+ (setq position (car positions))
+ (setq positions (cdr positions)))))
+ position))
+
+(defun python-info-dedenter-opening-block-positions ()
+ "Return points of blocks the current line may close sorted by closer.
+Returns nil if point is not on a dedenter statement or no opening
+block can be detected. The latter case meaning current file is
+likely an invalid python file."
+ (save-excursion
+ (let ((dedenter-pos (python-info-dedenter-statement-p)))
+ (when dedenter-pos
+ (goto-char dedenter-pos)
+ (let* ((pairs '(("elif" "elif" "if")
+ ("else" "if" "elif" "except" "for" "while")
+ ("except" "except" "try")
+ ("finally" "else" "except" "try")))
+ (dedenter (match-string-no-properties 0))
+ (possible-opening-blocks (cdr (assoc-string dedenter pairs)))
+ (collected-indentations)
+ (opening-blocks))
+ (catch 'exit
+ (while (python-nav--syntactically
+ (lambda ()
+ (re-search-backward (python-rx block-start) nil t))
+ #'<)
+ (let ((indentation (current-indentation)))
+ (when (and (not (memq indentation collected-indentations))
+ (or (not collected-indentations)
+ (< indentation (apply #'min collected-indentations))))
+ (setq collected-indentations
+ (cons indentation collected-indentations))
+ (when (member (match-string-no-properties 0)
+ possible-opening-blocks)
+ (setq opening-blocks (cons (point) opening-blocks))))
+ (when (zerop indentation)
+ (throw 'exit nil)))))
+ ;; sort by closer
+ (nreverse opening-blocks))))))
+
+(define-obsolete-function-alias
+ 'python-info-closing-block-message
+ 'python-info-dedenter-opening-block-message "24.4")
+
+(defun python-info-dedenter-opening-block-message ()
+ "Message the first line of the block the current statement closes."
+ (let ((point (python-info-dedenter-opening-block-position)))
(when point
(save-restriction
(widen)
(message "Closes %s" (save-excursion
(goto-char point)
- (back-to-indentation)
(buffer-substring
(point) (line-end-position))))))))
+(defun python-info-dedenter-statement-p ()
+ "Return point if current statement is a dedenter.
+Sets `match-data' to the keyword that starts the dedenter
+statement."
+ (save-excursion
+ (python-nav-beginning-of-statement)
+ (when (and (not (python-syntax-context-type))
+ (looking-at (python-rx dedenter)))
+ (point))))
+
(defun python-info-line-ends-backslash-p (&optional line-number)
"Return non-nil if current line ends with backslash.
With optional argument LINE-NUMBER, check that line instead."
diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el
index 1d75411ec1f..3b03ee14c0b 100644
--- a/lisp/vc/log-edit.el
+++ b/lisp/vc/log-edit.el
@@ -905,44 +905,46 @@ where LOGBUFFER is the name of the ChangeLog buffer, and each
;; that memoizing which is undesired here.
(setq change-log-default-name nil)
(find-change-log)))))
- (with-current-buffer (find-file-noselect changelog-file-name)
- (unless (eq major-mode 'change-log-mode) (change-log-mode))
- (goto-char (point-min))
- (if (looking-at "\\s-*\n") (goto-char (match-end 0)))
- (if (not (log-edit-changelog-ours-p))
- (list (current-buffer))
- (save-restriction
- (log-edit-narrow-changelog)
- (goto-char (point-min))
-
- ;; Search for the name of FILE relative to the ChangeLog. If that
- ;; doesn't occur anywhere, they're not using full relative
- ;; filenames in the ChangeLog, so just look for FILE; we'll accept
- ;; some false positives.
- (let ((pattern (file-relative-name
- file (file-name-directory changelog-file-name))))
- (if (or (string= pattern "")
- (not (save-excursion
- (search-forward pattern nil t))))
- (setq pattern (file-name-nondirectory file)))
-
- (setq pattern (concat "\\(^\\|[^[:alnum:]]\\)"
- (regexp-quote pattern)
- "\\($\\|[^[:alnum:]]\\)"))
-
- (let (texts
- (pos (point)))
- (while (and (not (eobp)) (re-search-forward pattern nil t))
- (let ((entry (log-edit-changelog-entry)))
- (if (< (elt entry 1) (max (1+ pos) (point)))
- ;; This is not relevant, actually.
- nil
- (push entry texts))
- ;; Make sure we make progress.
- (setq pos (max (1+ pos) (elt entry 1)))
- (goto-char pos)))
-
- (cons (current-buffer) texts))))))))
+ (when (or (find-buffer-visiting changelog-file-name)
+ (file-exists-p changelog-file-name))
+ (with-current-buffer (find-file-noselect changelog-file-name)
+ (unless (eq major-mode 'change-log-mode) (change-log-mode))
+ (goto-char (point-min))
+ (if (looking-at "\\s-*\n") (goto-char (match-end 0)))
+ (if (not (log-edit-changelog-ours-p))
+ (list (current-buffer))
+ (save-restriction
+ (log-edit-narrow-changelog)
+ (goto-char (point-min))
+
+ ;; Search for the name of FILE relative to the ChangeLog. If that
+ ;; doesn't occur anywhere, they're not using full relative
+ ;; filenames in the ChangeLog, so just look for FILE; we'll accept
+ ;; some false positives.
+ (let ((pattern (file-relative-name
+ file (file-name-directory changelog-file-name))))
+ (if (or (string= pattern "")
+ (not (save-excursion
+ (search-forward pattern nil t))))
+ (setq pattern (file-name-nondirectory file)))
+
+ (setq pattern (concat "\\(^\\|[^[:alnum:]]\\)"
+ (regexp-quote pattern)
+ "\\($\\|[^[:alnum:]]\\)"))
+
+ (let (texts
+ (pos (point)))
+ (while (and (not (eobp)) (re-search-forward pattern nil t))
+ (let ((entry (log-edit-changelog-entry)))
+ (if (< (elt entry 1) (max (1+ pos) (point)))
+ ;; This is not relevant, actually.
+ nil
+ (push entry texts))
+ ;; Make sure we make progress.
+ (setq pos (max (1+ pos) (elt entry 1)))
+ (goto-char pos)))
+
+ (cons (current-buffer) texts)))))))))
(defun log-edit-changelog-insert-entries (buffer beg end &rest files)
"Insert the text from BUFFER between BEG and END.
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el
index a0efe023a1d..0445891ed55 100644
--- a/lisp/vc/vc-dispatcher.el
+++ b/lisp/vc/vc-dispatcher.el
@@ -596,7 +596,7 @@ NOT-URGENT means it is ok to continue if the user says not to save."
(setq default-directory
(buffer-local-value 'default-directory vc-parent-buffer))
(log-edit 'vc-finish-logentry
- t
+ (= (point-min) (point-max))
`((log-edit-listfun . (lambda ()
;; FIXME: Should expand the list
;; for directories.
diff --git a/src/ChangeLog b/src/ChangeLog
index 9d5dff49166..47b0927bbb7 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,15 @@
2014-07-12 Eli Zaretskii <eliz@gnu.org>
+ * xdisp.c (display_line): Don't call FETCH_BYTE with argument less
+ than 1. (Bug#17962)
+
+ * w32fns.c (Fx_file_dialog): Mention in the doc string the
+ behavior on Windows 7 and later when the function is repeatedly
+ invoked with the same value of DIR. (Bug#17950)
+
+ * xfns.c (Fx_file_dialog) [USE_MOTIF, USE_GTK]: Update the doc
+ string to match the one in w32fns.c.
+
* minibuf.c (read_minibuf_noninteractive) [WINDOWSNT]: Switch
stdin to binary mode only if it is connected to a terminal.
diff --git a/src/w32fns.c b/src/w32fns.c
index def9d8acb7a..b76c81fdf1f 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6394,7 +6394,11 @@ or directory must exist.
This function is only defined on NS, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
-Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
+Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
+On Windows 7 and later, the file selection dialog "remembers" the last
+directory where the user selected a file, and will open that directory
+instead of DIR on subsequent invocations of this function with the same
+value of DIR as in previous invocations; this is standard Windows behavior. */)
(Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
{
/* Filter index: 1: All Files, 2: Directories only */
diff --git a/src/xdisp.c b/src/xdisp.c
index 6b2fa4be846..b83a2855927 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -20494,7 +20494,10 @@ display_line (struct it *it)
row->truncated_on_right_p = 1;
it->continuation_lines_width = 0;
reseat_at_next_visible_line_start (it, 0);
- row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
+ if (IT_BYTEPOS (*it) <= BEG_BYTE)
+ row->ends_at_zv_p = true;
+ else
+ row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
break;
}
}
diff --git a/src/xfns.c b/src/xfns.c
index 1ecfadd88b7..08de79596a8 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5705,7 +5705,11 @@ or directory must exist.
This function is only defined on NS, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
-Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
+Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
+On Windows 7 and later, the file selection dialog "remembers" the last
+directory where the user selected a file, and will open that directory
+instead of DIR on subsequent invocations of this function with the same
+value of DIR as in previous invocations; this is standard Windows behavior. */)
(Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
Lisp_Object mustmatch, Lisp_Object only_dir_p)
{
@@ -5877,7 +5881,11 @@ or directory must exist.
This function is only defined on NS, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
-Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
+Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
+On Windows 7 and later, the file selection dialog "remembers" the last
+directory where the user selected a file, and will open that directory
+instead of DIR on subsequent invocations of this function with the same
+value of DIR as in previous invocations; this is standard Windows behavior. */)
(Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
{
struct frame *f = SELECTED_FRAME ();
diff --git a/test/ChangeLog b/test/ChangeLog
index d4e7f818f1c..6e2f89157e3 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,33 @@
+2014-07-12 Fabián Ezequiel Gallina <fgallina@gnu.org>
+
+ * automated/python-tests.el (python-indent-block-enders-1)
+ (python-indent-block-enders-2): Fix tests.
+ (python-indent-block-enders-3, python-indent-block-enders-4)
+ (python-indent-block-enders-5, python-indent-dedenters-1)
+ (python-indent-dedenters-2): Remove tests.
+ (python-indent-dedenters-1, python-indent-dedenters-2)
+ (python-indent-dedenters-3, python-indent-dedenters-4)
+ (python-indent-dedenters-5, python-indent-dedenters-6)
+ (python-indent-dedenters-7)
+ (python-info-dedenter-opening-block-position-1)
+ (python-info-dedenter-opening-block-position-2)
+ (python-info-dedenter-opening-block-position-3)
+ (python-info-dedenter-opening-block-positions-1)
+ (python-info-dedenter-opening-block-positions-2)
+ (python-info-dedenter-opening-block-positions-3)
+ (python-info-dedenter-opening-block-positions-4)
+ (python-info-dedenter-opening-block-positions-5)
+ (python-info-dedenter-opening-block-message-1)
+ (python-info-dedenter-opening-block-message-2)
+ (python-info-dedenter-opening-block-message-3)
+ (python-info-dedenter-opening-block-message-4)
+ (python-info-dedenter-opening-block-message-5)
+ (python-info-dedenter-statement-p-1)
+ (python-info-dedenter-statement-p-2)
+ (python-info-dedenter-statement-p-3)
+ (python-info-dedenter-statement-p-4)
+ (python-info-dedenter-statement-p-5): New tests.
+
2014-07-08 Stefan Monnier <monnier@iro.umontreal.ca>
* indent/perl.perl: Add indentation pattern for hash-table entries.
diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el
index a35242fe882..3a4eda36bfe 100644
--- a/test/automated/python-tests.el
+++ b/test/automated/python-tests.el
@@ -435,79 +435,6 @@ def foo(a, b, c={
(should (eq (car (python-indent-context)) 'after-beginning-of-block))
(should (= (python-indent-calculate-indentation) 4))))
-(ert-deftest python-indent-dedenters-1 ()
- "Check all dedenters."
- (python-tests-with-temp-buffer
- "
-def foo(a, b, c):
- if a:
- print (a)
- elif b:
- print (b)
- else:
- try:
- print (c.pop())
- except (IndexError, AttributeError):
- print (c)
- finally:
- print ('nor a, nor b are true')
-"
- (python-tests-look-at "if a:")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 4))
- (python-tests-look-at "print (a)")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 8))
- (python-tests-look-at "elif b:")
- (should (eq (car (python-indent-context)) 'after-line))
- (should (= (python-indent-calculate-indentation) 4))
- (python-tests-look-at "print (b)")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 8))
- (python-tests-look-at "else:")
- (should (eq (car (python-indent-context)) 'after-line))
- (should (= (python-indent-calculate-indentation) 4))
- (python-tests-look-at "try:")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 8))
- (python-tests-look-at "print (c.pop())")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 12))
- (python-tests-look-at "except (IndexError, AttributeError):")
- (should (eq (car (python-indent-context)) 'after-line))
- (should (= (python-indent-calculate-indentation) 8))
- (python-tests-look-at "print (c)")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 12))
- (python-tests-look-at "finally:")
- (should (eq (car (python-indent-context)) 'after-line))
- (should (= (python-indent-calculate-indentation) 8))
- (python-tests-look-at "print ('nor a, nor b are true')")
- (should (eq (car (python-indent-context)) 'after-beginning-of-block))
- (should (= (python-indent-calculate-indentation) 12))))
-
-(ert-deftest python-indent-dedenters-2 ()
- "Check one-liner block special case.."
- (python-tests-with-temp-buffer
- "
-cond = True
-if cond:
-
- if cond: print 'True'
-else: print 'False'
-
-else:
- return
-"
- (python-tests-look-at "else: print 'False'")
- ;; When a block has code after ":" it's just considered a simple
- ;; line as that's a common thing to happen in one-liners.
- (should (eq (car (python-indent-context)) 'after-line))
- (should (= (python-indent-calculate-indentation) 4))
- (python-tests-look-at "else:")
- (should (eq (car (python-indent-context)) 'after-line))
- (should (= (python-indent-calculate-indentation) 0))))
-
(ert-deftest python-indent-after-backslash-1 ()
"The most common case."
(python-tests-with-temp-buffer
@@ -575,9 +502,9 @@ objects = Thing.objects.all() \\\\
(should (= (python-indent-calculate-indentation) 0))))
(ert-deftest python-indent-block-enders-1 ()
- "Test `python-indent-block-enders' value honoring."
+ "Test de-indentation for pass keyword."
(python-tests-with-temp-buffer
- "
+ "
Class foo(object):
def bar(self):
@@ -589,17 +516,17 @@ Class foo(object):
else:
pass
"
- (python-tests-look-at "3)")
- (forward-line 1)
- (should (= (python-indent-calculate-indentation) 8))
- (python-tests-look-at "pass")
- (forward-line 1)
- (should (= (python-indent-calculate-indentation) 8))))
+ (python-tests-look-at "3)")
+ (forward-line 1)
+ (should (= (python-indent-calculate-indentation) 8))
+ (python-tests-look-at "pass")
+ (forward-line 1)
+ (should (= (python-indent-calculate-indentation) 8))))
(ert-deftest python-indent-block-enders-2 ()
- "Test `python-indent-block-enders' value honoring."
+ "Test de-indentation for return keyword."
(python-tests-with-temp-buffer
- "
+ "
Class foo(object):
'''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
@@ -612,10 +539,177 @@ Class foo(object):
2,
3)
"
- (python-tests-look-at "def")
- (should (= (python-indent-calculate-indentation) 4))
- (python-tests-look-at "if")
- (should (= (python-indent-calculate-indentation) 8))))
+ (python-tests-look-at "def")
+ (should (= (python-indent-calculate-indentation) 4))
+ (python-tests-look-at "if")
+ (should (= (python-indent-calculate-indentation) 8))
+ (python-tests-look-at "return")
+ (should (= (python-indent-calculate-indentation) 12))
+ (goto-char (point-max))
+ (should (= (python-indent-calculate-indentation) 8))))
+
+(ert-deftest python-indent-block-enders-3 ()
+ "Test de-indentation for continue keyword."
+ (python-tests-with-temp-buffer
+ "
+for element in lst:
+ if element is None:
+ continue
+"
+ (python-tests-look-at "if")
+ (should (= (python-indent-calculate-indentation) 4))
+ (python-tests-look-at "continue")
+ (should (= (python-indent-calculate-indentation) 8))
+ (forward-line 1)
+ (should (= (python-indent-calculate-indentation) 4))))
+
+(ert-deftest python-indent-block-enders-4 ()
+ "Test de-indentation for break keyword."
+ (python-tests-with-temp-buffer
+ "
+for element in lst:
+ if element is None:
+ break
+"
+ (python-tests-look-at "if")
+ (should (= (python-indent-calculate-indentation) 4))
+ (python-tests-look-at "break")
+ (should (= (python-indent-calculate-indentation) 8))
+ (forward-line 1)
+ (should (= (python-indent-calculate-indentation) 4))))
+
+(ert-deftest python-indent-block-enders-5 ()
+ "Test de-indentation for raise keyword."
+ (python-tests-with-temp-buffer
+ "
+for element in lst:
+ if element is None:
+ raise ValueError('Element cannot be None')
+"
+ (python-tests-look-at "if")
+ (should (= (python-indent-calculate-indentation) 4))
+ (python-tests-look-at "raise")
+ (should (= (python-indent-calculate-indentation) 8))
+ (forward-line 1)
+ (should (= (python-indent-calculate-indentation) 4))))
+
+(ert-deftest python-indent-dedenters-1 ()
+ "Test de-indentation for the elif keyword."
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ finally:
+ cleanup()
+ elif
+"
+ (python-tests-look-at "elif\n")
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 0))
+ (should (equal (python-indent-calculate-levels) '(0)))))
+
+(ert-deftest python-indent-dedenters-2 ()
+ "Test de-indentation for the else keyword."
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ except IOError:
+ msg = 'Error saving to disk'
+ message(msg)
+ logger.exception(msg)
+ except Exception:
+ if hide_details:
+ logger.exception('Unhandled exception')
+ else
+ finally:
+ data.free()
+"
+ (python-tests-look-at "else\n")
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 8))
+ (should (equal (python-indent-calculate-levels) '(0 4 8)))))
+
+(ert-deftest python-indent-dedenters-3 ()
+ "Test de-indentation for the except keyword."
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ except
+"
+ (python-tests-look-at "except\n")
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 4))
+ (should (equal (python-indent-calculate-levels) '(4)))))
+
+(ert-deftest python-indent-dedenters-4 ()
+ "Test de-indentation for the finally keyword."
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ finally
+"
+ (python-tests-look-at "finally\n")
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 4))
+ (should (equal (python-indent-calculate-levels) '(4)))))
+
+(ert-deftest python-indent-dedenters-5 ()
+ "Test invalid levels are skipped in a complex example."
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ except IOError:
+ msg = 'Error saving to disk'
+ message(msg)
+ logger.exception(msg)
+ finally:
+ if cleanup:
+ do_cleanup()
+ else
+"
+ (python-tests-look-at "else\n")
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 8))
+ (should (equal (python-indent-calculate-levels) '(0 8)))))
+
+(ert-deftest python-indent-dedenters-6 ()
+ "Test indentation is zero when no opening block for dedenter."
+ (python-tests-with-temp-buffer
+ "
+try:
+ # if save:
+ write_to_disk(data)
+ else
+"
+ (python-tests-look-at "else\n")
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 0))
+ (should (equal (python-indent-calculate-levels) '(0)))))
+
+(ert-deftest python-indent-dedenters-7 ()
+ "Test indentation case from Bug#15163."
+ (python-tests-with-temp-buffer
+ "
+if a:
+ if b:
+ pass
+ else:
+ pass
+ else:
+"
+ (python-tests-look-at "else:" 2)
+ (should (eq (car (python-indent-context)) 'dedenter-statement))
+ (should (= (python-indent-calculate-indentation) 0))
+ (should (equal (python-indent-calculate-levels) '(0)))))
;;; Navigation
@@ -2428,9 +2522,9 @@ if width == 0 and height == 0 and \\\\
(python-util-forward-comment -1)
(should (python-info-end-of-block-p))))
-(ert-deftest python-info-closing-block-1 ()
+(ert-deftest python-info-dedenter-opening-block-position-1 ()
(python-tests-with-temp-buffer
- "
+ "
if request.user.is_authenticated():
try:
profile = request.user.get_profile()
@@ -2445,26 +2539,26 @@ if request.user.is_authenticated():
profile.views += 1
profile.save()
"
- (python-tests-look-at "try:")
- (should (not (python-info-closing-block)))
- (python-tests-look-at "except Profile.DoesNotExist:")
- (should (= (python-tests-look-at "try:" -1 t)
- (python-info-closing-block)))
- (python-tests-look-at "else:")
- (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
- (python-info-closing-block)))
- (python-tests-look-at "if profile.stats:")
- (should (not (python-info-closing-block)))
- (python-tests-look-at "else:")
- (should (= (python-tests-look-at "if profile.stats:" -1 t)
- (python-info-closing-block)))
- (python-tests-look-at "finally:")
- (should (= (python-tests-look-at "else:" -2 t)
- (python-info-closing-block)))))
-
-(ert-deftest python-info-closing-block-2 ()
- (python-tests-with-temp-buffer
- "
+ (python-tests-look-at "try:")
+ (should (not (python-info-dedenter-opening-block-position)))
+ (python-tests-look-at "except Profile.DoesNotExist:")
+ (should (= (python-tests-look-at "try:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+ (python-tests-look-at "else:")
+ (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+ (python-tests-look-at "if profile.stats:")
+ (should (not (python-info-dedenter-opening-block-position)))
+ (python-tests-look-at "else:")
+ (should (= (python-tests-look-at "if profile.stats:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+ (python-tests-look-at "finally:")
+ (should (= (python-tests-look-at "else:" -2 t)
+ (python-info-dedenter-opening-block-position)))))
+
+(ert-deftest python-info-dedenter-opening-block-position-2 ()
+ (python-tests-with-temp-buffer
+ "
if request.user.is_authenticated():
profile = Profile.objects.get_or_create(user=request.user)
if profile.stats:
@@ -2475,10 +2569,440 @@ data = {
}
'else'
"
- (python-tests-look-at "'else': 'do it'")
- (should (not (python-info-closing-block)))
- (python-tests-look-at "'else'")
- (should (not (python-info-closing-block)))))
+ (python-tests-look-at "'else': 'do it'")
+ (should (not (python-info-dedenter-opening-block-position)))
+ (python-tests-look-at "'else'")
+ (should (not (python-info-dedenter-opening-block-position)))))
+
+(ert-deftest python-info-dedenter-opening-block-position-3 ()
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ except IOError:
+ msg = 'Error saving to disk'
+ message(msg)
+ logger.exception(msg)
+ except Exception:
+ if hide_details:
+ logger.exception('Unhandled exception')
+ else
+ finally:
+ data.free()
+"
+ (python-tests-look-at "try:")
+ (should (not (python-info-dedenter-opening-block-position)))
+
+ (python-tests-look-at "except IOError:")
+ (should (= (python-tests-look-at "try:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+
+ (python-tests-look-at "except Exception:")
+ (should (= (python-tests-look-at "except IOError:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+
+ (python-tests-look-at "if hide_details:")
+ (should (not (python-info-dedenter-opening-block-position)))
+
+ ;; check indentation modifies the detected opening block
+ (python-tests-look-at "else")
+ (should (= (python-tests-look-at "if hide_details:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+
+ (indent-line-to 8)
+ (should (= (python-tests-look-at "if hide_details:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+
+ (indent-line-to 4)
+ (should (= (python-tests-look-at "except Exception:" -1 t)
+ (python-info-dedenter-opening-block-position)))
+
+ (indent-line-to 0)
+ (should (= (python-tests-look-at "if save:" -1 t)
+ (python-info-dedenter-opening-block-position)))))
+
+(ert-deftest python-info-dedenter-opening-block-positions-1 ()
+ (python-tests-with-temp-buffer
+ "
+if save:
+ try:
+ write_to_disk(data)
+ except IOError:
+ msg = 'Error saving to disk'
+ message(msg)
+ logger.exception(msg)
+ except Exception:
+ if hide_details:
+ logger.exception('Unhandled exception')
+ else
+ finally:
+ data.free()
+"
+ (python-tests-look-at "try:")
+ (should (not (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "except IOError:")
+ (should
+ (equal (list
+ (python-tests-look-at "try:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "except Exception:")
+ (should
+ (equal (list
+ (python-tests-look-at "except IOError:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "if hide_details:")
+ (should (not (python-info-dedenter-opening-block-positions)))
+
+ ;; check indentation does not modify the detected opening blocks
+ (python-tests-look-at "else")
+ (should
+ (equal (list
+ (python-tests-look-at "if hide_details:" -1 t)
+ (python-tests-look-at "except Exception:" -1 t)
+ (python-tests-look-at "if save:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (indent-line-to 8)
+ (should
+ (equal (list
+ (python-tests-look-at "if hide_details:" -1 t)
+ (python-tests-look-at "except Exception:" -1 t)
+ (python-tests-look-at "if save:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (indent-line-to 4)
+ (should
+ (equal (list
+ (python-tests-look-at "if hide_details:" -1 t)
+ (python-tests-look-at "except Exception:" -1 t)
+ (python-tests-look-at "if save:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (indent-line-to 0)
+ (should
+ (equal (list
+ (python-tests-look-at "if hide_details:" -1 t)
+ (python-tests-look-at "except Exception:" -1 t)
+ (python-tests-look-at "if save:" -1 t))
+ (python-info-dedenter-opening-block-positions)))))
+
+(ert-deftest python-info-dedenter-opening-block-positions-2 ()
+ "Test detection of opening blocks for elif."
+ (python-tests-with-temp-buffer
+ "
+if var:
+ if var2:
+ something()
+ elif var3:
+ something_else()
+ elif
+"
+ (python-tests-look-at "elif var3:")
+ (should
+ (equal (list
+ (python-tests-look-at "if var2:" -1 t)
+ (python-tests-look-at "if var:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "elif\n")
+ (should
+ (equal (list
+ (python-tests-look-at "elif var3:" -1 t)
+ (python-tests-look-at "if var:" -1 t))
+ (python-info-dedenter-opening-block-positions)))))
+
+(ert-deftest python-info-dedenter-opening-block-positions-3 ()
+ "Test detection of opening blocks for else."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ if var:
+ if var2:
+ something()
+ elif var3:
+ something_else()
+ else
+
+if var4:
+ while var5:
+ var4.pop()
+ else
+
+ for value in var6:
+ if value > 0:
+ print value
+ else
+"
+ (python-tests-look-at "else\n")
+ (should
+ (equal (list
+ (python-tests-look-at "elif var3:" -1 t)
+ (python-tests-look-at "if var:" -1 t)
+ (python-tests-look-at "except:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "else\n")
+ (should
+ (equal (list
+ (python-tests-look-at "while var5:" -1 t)
+ (python-tests-look-at "if var4:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "else\n")
+ (should
+ (equal (list
+ (python-tests-look-at "if value > 0:" -1 t)
+ (python-tests-look-at "for value in var6:" -1 t)
+ (python-tests-look-at "if var4:" -1 t))
+ (python-info-dedenter-opening-block-positions)))))
+
+(ert-deftest python-info-dedenter-opening-block-positions-4 ()
+ "Test detection of opening blocks for except."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except ValueError:
+ something_else()
+ except
+"
+ (python-tests-look-at "except ValueError:")
+ (should
+ (equal (list (python-tests-look-at "try:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "except\n")
+ (should
+ (equal (list (python-tests-look-at "except ValueError:" -1 t))
+ (python-info-dedenter-opening-block-positions)))))
+
+(ert-deftest python-info-dedenter-opening-block-positions-5 ()
+ "Test detection of opening blocks for finally."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+ finally
+
+try:
+ something_else()
+except:
+ logger.exception('something went wrong')
+ finally
+
+try:
+ something_else_else()
+except Exception:
+ logger.exception('something else went wrong')
+else:
+ print ('all good')
+ finally
+"
+ (python-tests-look-at "finally\n")
+ (should
+ (equal (list (python-tests-look-at "try:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "finally\n")
+ (should
+ (equal (list (python-tests-look-at "except:" -1 t))
+ (python-info-dedenter-opening-block-positions)))
+
+ (python-tests-look-at "finally\n")
+ (should
+ (equal (list (python-tests-look-at "else:" -1 t))
+ (python-info-dedenter-opening-block-positions)))))
+
+(ert-deftest python-info-dedenter-opening-block-message-1 ()
+ "Test dedenters inside strings are ignored."
+ (python-tests-with-temp-buffer
+ "'''
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+'''
+"
+ (python-tests-look-at "except\n")
+ (should (not (python-info-dedenter-opening-block-message)))))
+
+(ert-deftest python-info-dedenter-opening-block-message-2 ()
+ "Test except keyword."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+"
+ (python-tests-look-at "except:")
+ (should (string=
+ "Closes try:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))
+ (end-of-line)
+ (should (string=
+ "Closes try:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))))
+
+(ert-deftest python-info-dedenter-opening-block-message-3 ()
+ "Test else keyword."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+else:
+ logger.debug('all good')
+"
+ (python-tests-look-at "else:")
+ (should (string=
+ "Closes except:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))
+ (end-of-line)
+ (should (string=
+ "Closes except:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))))
+
+(ert-deftest python-info-dedenter-opening-block-message-4 ()
+ "Test finally keyword."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+else:
+ logger.debug('all good')
+finally:
+ clean()
+"
+ (python-tests-look-at "finally:")
+ (should (string=
+ "Closes else:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))
+ (end-of-line)
+ (should (string=
+ "Closes else:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))))
+
+(ert-deftest python-info-dedenter-opening-block-message-5 ()
+ "Test elif keyword."
+ (python-tests-with-temp-buffer
+ "
+if a:
+ something()
+elif b:
+"
+ (python-tests-look-at "elif b:")
+ (should (string=
+ "Closes if a:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))
+ (end-of-line)
+ (should (string=
+ "Closes if a:"
+ (substring-no-properties
+ (python-info-dedenter-opening-block-message))))))
+
+
+(ert-deftest python-info-dedenter-statement-p-1 ()
+ "Test dedenters inside strings are ignored."
+ (python-tests-with-temp-buffer
+ "'''
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+'''
+"
+ (python-tests-look-at "except\n")
+ (should (not (python-info-dedenter-statement-p)))))
+
+(ert-deftest python-info-dedenter-statement-p-2 ()
+ "Test except keyword."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+"
+ (python-tests-look-at "except:")
+ (should (= (point) (python-info-dedenter-statement-p)))
+ (end-of-line)
+ (should (= (save-excursion
+ (back-to-indentation)
+ (point))
+ (python-info-dedenter-statement-p)))))
+
+(ert-deftest python-info-dedenter-statement-p-3 ()
+ "Test else keyword."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+else:
+ logger.debug('all good')
+"
+ (python-tests-look-at "else:")
+ (should (= (point) (python-info-dedenter-statement-p)))
+ (end-of-line)
+ (should (= (save-excursion
+ (back-to-indentation)
+ (point))
+ (python-info-dedenter-statement-p)))))
+
+(ert-deftest python-info-dedenter-statement-p-4 ()
+ "Test finally keyword."
+ (python-tests-with-temp-buffer
+ "
+try:
+ something()
+except:
+ logger.exception('something went wrong')
+else:
+ logger.debug('all good')
+finally:
+ clean()
+"
+ (python-tests-look-at "finally:")
+ (should (= (point) (python-info-dedenter-statement-p)))
+ (end-of-line)
+ (should (= (save-excursion
+ (back-to-indentation)
+ (point))
+ (python-info-dedenter-statement-p)))))
+
+(ert-deftest python-info-dedenter-statement-p-5 ()
+ "Test elif keyword."
+ (python-tests-with-temp-buffer
+ "
+if a:
+ something()
+elif b:
+"
+ (python-tests-look-at "elif b:")
+ (should (= (point) (python-info-dedenter-statement-p)))
+ (end-of-line)
+ (should (= (save-excursion
+ (back-to-indentation)
+ (point))
+ (python-info-dedenter-statement-p)))))
(ert-deftest python-info-line-ends-backslash-p-1 ()
(python-tests-with-temp-buffer