emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r117524: Merge from emacs-24; up to r117375


From: Glenn Morris
Subject: [Emacs-diffs] trunk r117524: Merge from emacs-24; up to r117375
Date: Sat, 12 Jul 2014 17:54:11 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 117524 [merge]
revision-id: address@hidden
parent: address@hidden
parent: address@hidden
committer: Glenn Morris <address@hidden>
branch nick: trunk
timestamp: Sat 2014-07-12 10:53:29 -0700
message:
  Merge from emacs-24; up to r117375
modified:
  ChangeLog                      changelog-20091113204419-o5vbwnq5f7feedwu-1538
  Makefile.in                    makefile.in-20091113204419-o5vbwnq5f7feedwu-446
  etc/PROBLEMS                   problems-20091113204419-o5vbwnq5f7feedwu-1498
  lib-src/ChangeLog              changelog-20091113204419-o5vbwnq5f7feedwu-1608
  lib-src/etags.c                etags.c-20091113204419-o5vbwnq5f7feedwu-216
  lisp/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-1432
  lisp/faces.el                  faces.el-20091113204419-o5vbwnq5f7feedwu-562
  lisp/progmodes/python.el       python.el-20091113204419-o5vbwnq5f7feedwu-3008
  lisp/vc/log-edit.el            logedit.el-20091113204419-o5vbwnq5f7feedwu-1776
  lisp/vc/vc-dispatcher.el       
vcdispatcher.el-20091113204419-o5vbwnq5f7feedwu-8662
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/w32fns.c                   w32fns.c-20091113204419-o5vbwnq5f7feedwu-945
  src/xdisp.c                    xdisp.c-20091113204419-o5vbwnq5f7feedwu-240
  src/xfns.c                     xfns.c-20091113204419-o5vbwnq5f7feedwu-274
  test/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-8588
  test/automated/python-tests.el 
pythontests.el-20130220195218-kqcioz3fssz9hwe1-1
=== modified file 'ChangeLog'
--- a/ChangeLog 2014-07-10 12:33:35 +0000
+++ b/ChangeLog 2014-07-12 17:53:29 +0000
@@ -1,3 +1,7 @@
+2014-07-12  Paul Eggert  <address@hidden>
+
+       * Makefile.in (install-arch-indep): Avoid readdir race (Bug#17971).
+
 2014-07-10  Dmitry Antipov  <address@hidden>
 
        * configure.ac: Check whether sys/sysinfo.h provides

=== modified file 'Makefile.in'
--- a/Makefile.in       2014-06-27 00:41:23 +0000
+++ b/Makefile.in       2014-07-12 17:53:29 +0000
@@ -594,8 +594,9 @@
        [ -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}
 

=== modified file 'etc/PROBLEMS'
--- a/etc/PROBLEMS      2014-06-15 00:06:30 +0000
+++ b/etc/PROBLEMS      2014-07-12 17:53:29 +0000
@@ -1931,6 +1931,16 @@
 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 @@
 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 @@
 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

=== modified file 'lib-src/ChangeLog'
--- a/lib-src/ChangeLog 2014-06-26 06:18:53 +0000
+++ b/lib-src/ChangeLog 2014-07-12 17:53:29 +0000
@@ -1,3 +1,7 @@
+2014-07-12  Paul Eggert  <address@hidden>
+
+       * etags.c (Lisp_functions): Also record cl-defun etc. (Bug#17965)
+
 2014-06-26  Glenn Morris  <address@hidden>
 
        * Makefile.in (blessmail): Depend on lisp/mail/blessmail.el.

=== modified file 'lib-src/etags.c'
--- a/lib-src/etags.c   2014-01-01 07:43:34 +0000
+++ b/lib-src/etags.c   2014-07-12 16:26:54 +0000
@@ -4747,6 +4747,9 @@
            }
        }
 
+      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);

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2014-07-11 12:19:58 +0000
+++ b/lisp/ChangeLog    2014-07-12 17:53:29 +0000
@@ -1,3 +1,41 @@
+2014-07-12  Paul Eggert  <address@hidden>
+
+       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  <address@hidden>
+
+       * vc/log-edit.el (log-edit-changelog-entries):
+       Check for a visited-but-never-saved ChangeLog.
+
+2014-07-12  Stefan Monnier  <address@hidden>
+
+       * 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  <address@hidden>
+
+       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  <address@hidden>
 
        * files.el (out-of-memory-warning-percentage): New defcustom.

=== modified file 'lisp/faces.el'
--- a/lisp/faces.el     2014-07-09 02:04:12 +0000
+++ b/lisp/faces.el     2014-07-12 17:53:29 +0000
@@ -370,10 +370,7 @@
 
 (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 @@
 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

=== modified file 'lisp/progmodes/python.el'
--- a/lisp/progmodes/python.el  2014-07-03 06:00:53 +0000
+++ b/lisp/progmodes/python.el  2014-07-12 17:53:29 +0000
@@ -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 @@
 (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 @@
  * 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 @@
                          (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 @@
            (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 @@
                            (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 @@
 
 (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 @@
       (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 @@
            (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 @@
   (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."

=== modified file 'lisp/vc/log-edit.el'
--- a/lisp/vc/log-edit.el       2014-07-01 15:15:03 +0000
+++ b/lisp/vc/log-edit.el       2014-07-10 18:09:04 +0000
@@ -905,44 +905,46 @@
              ;; 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.

=== modified file 'lisp/vc/vc-dispatcher.el'
--- a/lisp/vc/vc-dispatcher.el  2014-01-01 07:43:34 +0000
+++ b/lisp/vc/vc-dispatcher.el  2014-07-12 02:24:02 +0000
@@ -596,7 +596,7 @@
   (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.

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2014-07-12 07:47:40 +0000
+++ b/src/ChangeLog     2014-07-12 17:53:29 +0000
@@ -1,5 +1,15 @@
 2014-07-12  Eli Zaretskii  <address@hidden>
 
+       * 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.
 

=== modified file 'src/w32fns.c'
--- a/src/w32fns.c      2014-07-03 18:12:41 +0000
+++ b/src/w32fns.c      2014-07-12 17:53:29 +0000
@@ -6394,7 +6394,11 @@
 
 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  */

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2014-07-09 02:04:12 +0000
+++ b/src/xdisp.c       2014-07-12 17:53:29 +0000
@@ -20494,7 +20494,10 @@
          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;
        }
     }

=== modified file 'src/xfns.c'
--- a/src/xfns.c        2014-07-09 02:04:12 +0000
+++ b/src/xfns.c        2014-07-12 17:53:29 +0000
@@ -5705,7 +5705,11 @@
 
 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 @@
 
 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 ();

=== modified file 'test/ChangeLog'
--- a/test/ChangeLog    2014-07-08 16:51:35 +0000
+++ b/test/ChangeLog    2014-07-12 17:53:29 +0000
@@ -1,3 +1,33 @@
+2014-07-12  Fabián Ezequiel Gallina  <address@hidden>
+
+       * 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  <address@hidden>
 
        * indent/perl.perl: Add indentation pattern for hash-table entries.

=== modified file 'test/automated/python-tests.el'
--- a/test/automated/python-tests.el    2014-07-01 03:54:11 +0000
+++ b/test/automated/python-tests.el    2014-07-09 03:55:53 +0000
@@ -435,79 +435,6 @@
    (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 @@
    (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 @@
         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 @@
                     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 @@
    (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 @@
         profile.views += 1
         profile.save()
 "
-   (python-tests-look-at "try:")
-   (should (not (python-info-closing-block)))
-   (python-tests-look-at "except Profile.DoesNotExist:")
-   (should (= (python-tests-look-at "try:" -1 t)
-              (python-info-closing-block)))
-   (python-tests-look-at "else:")
-   (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
-              (python-info-closing-block)))
-   (python-tests-look-at "if profile.stats:")
-   (should (not (python-info-closing-block)))
-   (python-tests-look-at "else:")
-   (should (= (python-tests-look-at "if profile.stats:" -1 t)
-              (python-info-closing-block)))
-   (python-tests-look-at "finally:")
-   (should (= (python-tests-look-at "else:" -2 t)
-              (python-info-closing-block)))))
+    (python-tests-look-at "try:")
+    (should (not (python-info-dedenter-opening-block-position)))
+    (python-tests-look-at "except Profile.DoesNotExist:")
+    (should (= (python-tests-look-at "try:" -1 t)
+               (python-info-dedenter-opening-block-position)))
+    (python-tests-look-at "else:")
+    (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t)
+               (python-info-dedenter-opening-block-position)))
+    (python-tests-look-at "if profile.stats:")
+    (should (not (python-info-dedenter-opening-block-position)))
+    (python-tests-look-at "else:")
+    (should (= (python-tests-look-at "if profile.stats:" -1 t)
+               (python-info-dedenter-opening-block-position)))
+    (python-tests-look-at "finally:")
+    (should (= (python-tests-look-at "else:" -2 t)
+               (python-info-dedenter-opening-block-position)))))
 
-(ert-deftest python-info-closing-block-2 ()
+(ert-deftest python-info-dedenter-opening-block-position-2 ()
   (python-tests-with-temp-buffer
-   "
+      "
 if request.user.is_authenticated():
     profile = Profile.objects.get_or_create(user=request.user)
     if profile.stats:
@@ -2475,10 +2569,440 @@
 }
     '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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]