diff options
| author | Glenn Morris | 2014-07-12 10:53:29 -0700 |
|---|---|---|
| committer | Glenn Morris | 2014-07-12 10:53:29 -0700 |
| commit | b39c4d7b33952e0125fbefbcb3d9f528b6570f40 (patch) | |
| tree | 17fd0630dacfe29b0c2486b9f5c923293e872a70 | |
| parent | 2a0bae50e3611a6bd2d584f7a85677b74f1aa71b (diff) | |
| parent | fb02552638b0c653bfc3d269d879fdffba37bd31 (diff) | |
| download | emacs-b39c4d7b33952e0125fbefbcb3d9f528b6570f40.tar.gz emacs-b39c4d7b33952e0125fbefbcb3d9f528b6570f40.zip | |
Merge from emacs-24; up to 2014-06-22T05:00:14Z!dmantipov@yandex.ru
| -rw-r--r-- | ChangeLog | 4 | ||||
| -rw-r--r-- | Makefile.in | 5 | ||||
| -rw-r--r-- | etc/PROBLEMS | 32 | ||||
| -rw-r--r-- | lib-src/ChangeLog | 4 | ||||
| -rw-r--r-- | lib-src/etags.c | 3 | ||||
| -rw-r--r-- | lisp/ChangeLog | 38 | ||||
| -rw-r--r-- | lisp/faces.el | 7 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 204 | ||||
| -rw-r--r-- | lisp/vc/log-edit.el | 78 | ||||
| -rw-r--r-- | lisp/vc/vc-dispatcher.el | 2 | ||||
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/w32fns.c | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 5 | ||||
| -rw-r--r-- | src/xfns.c | 12 | ||||
| -rw-r--r-- | test/ChangeLog | 30 | ||||
| -rw-r--r-- | test/automated/python-tests.el | 750 |
16 files changed, 943 insertions, 247 deletions
| @@ -1,3 +1,7 @@ | |||
| 1 | 2014-07-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * Makefile.in (install-arch-indep): Avoid readdir race (Bug#17971). | ||
| 4 | |||
| 1 | 2014-07-10 Dmitry Antipov <dmantipov@yandex.ru> | 5 | 2014-07-10 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 6 | ||
| 3 | * configure.ac: Check whether sys/sysinfo.h provides | 7 | * 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} | |||
| 594 | [ -z "${GZIP_PROG}" ] || { \ | 594 | [ -z "${GZIP_PROG}" ] || { \ |
| 595 | echo "Compressing *.el ..." && \ | 595 | echo "Compressing *.el ..." && \ |
| 596 | cd "$(DESTDIR)${lispdir}" && \ | 596 | cd "$(DESTDIR)${lispdir}" && \ |
| 597 | find . -name '*.elc' -exec $(SHELL) -c \ | 597 | for f in `find . -name "*.elc" -print | sed 's/.elc$$/.el/'`; do \ |
| 598 | '${GZIP_PROG} -9n `expr "$$1" : "\\(.*\\)c"`' dummy '{}' ';'; \ | 598 | ${GZIP_PROG} -9n "$$f"; \ |
| 599 | done; \ | ||
| 599 | } | 600 | } |
| 600 | -chmod -R a+r "$(DESTDIR)${datadir}/emacs/${version}" ${COPYDESTS} | 601 | -chmod -R a+r "$(DESTDIR)${datadir}/emacs/${version}" ${COPYDESTS} |
| 601 | 602 | ||
diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 98e19d3e760..ed41ddf65a3 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS | |||
| @@ -1931,6 +1931,16 @@ MSDN: | |||
| 1931 | includes a short description of MSLU and a link where it can be | 1931 | includes a short description of MSLU and a link where it can be |
| 1932 | downloaded. | 1932 | downloaded. |
| 1933 | 1933 | ||
| 1934 | ** Emacs refuses to start on Windows 9X because ctime64 function is missing | ||
| 1935 | |||
| 1936 | This is a sign that Emacs was compiled with MinGW runtime version | ||
| 1937 | 4.0.x or later. These versions of runtime call in their startup code | ||
| 1938 | the ctime64 function, which does not exist in MSVCRT.DLL, the C | ||
| 1939 | runtime shared library, distributed with Windows 9X. | ||
| 1940 | |||
| 1941 | A workaround is to build Emacs with MinGW runtime 3.x (the latest | ||
| 1942 | version is 3.20). | ||
| 1943 | |||
| 1934 | ** A few seconds delay is seen at startup and for many file operations | 1944 | ** A few seconds delay is seen at startup and for many file operations |
| 1935 | 1945 | ||
| 1936 | This happens when the Net Logon service is enabled. During Emacs | 1946 | 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 | |||
| 1965 | switch, which will force Emacs to load libgcc_s_dw2-1.dll on startup, | 1975 | switch, which will force Emacs to load libgcc_s_dw2-1.dll on startup, |
| 1966 | ahead of any optional DLLs loaded on-demand later in the session. | 1976 | ahead of any optional DLLs loaded on-demand later in the session. |
| 1967 | 1977 | ||
| 1978 | ** File selection dialog opens in incorrect directories | ||
| 1979 | |||
| 1980 | Invoking the file selection dialog on Windows 7 or later shows a | ||
| 1981 | directory that is different from what was passed to `read-file-name' | ||
| 1982 | or `x-file-dialog' via their arguments. | ||
| 1983 | |||
| 1984 | This is due to a deliberate change in behavior of the file selection | ||
| 1985 | dialogs introduced in Windows 7. It is explicitly described in the | ||
| 1986 | MSDN documentation of the GetOpenFileName API used by Emacs to pop up | ||
| 1987 | the file selection dialog. For the details, see | ||
| 1988 | |||
| 1989 | http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839%28v=vs.85%29.aspx | ||
| 1990 | |||
| 1991 | The dialog shows the last directory in which the user selected a file | ||
| 1992 | in a previous invocation of the dialog with the same initial | ||
| 1993 | directory. | ||
| 1994 | |||
| 1995 | You can reset this "memory" of that directory by invoking the file | ||
| 1996 | selection dialog with a different initial directory. | ||
| 1997 | |||
| 1968 | ** PATH can contain unexpanded environment variables | 1998 | ** PATH can contain unexpanded environment variables |
| 1969 | 1999 | ||
| 1970 | Old releases of TCC (version 9) and 4NT (up to version 8) do not correctly | 2000 | 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 | |||
| 2098 | non-US timezones. This is due to over-simplistic handling of | 2128 | non-US timezones. This is due to over-simplistic handling of |
| 2099 | daylight savings switchovers by the Windows libraries. | 2129 | daylight savings switchovers by the Windows libraries. |
| 2100 | 2130 | ||
| 2101 | ** Files larger than 4GB report wrong size | 2131 | ** Files larger than 4GB report wrong size in a 32-bit Windows build |
| 2102 | 2132 | ||
| 2103 | Files larger than 4GB cause overflow in the size (represented as a | 2133 | Files larger than 4GB cause overflow in the size (represented as a |
| 2104 | 32-bit integer) reported by `file-attributes'. This affects Dired as | 2134 | 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 @@ | |||
| 1 | 2014-07-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * etags.c (Lisp_functions): Also record cl-defun etc. (Bug#17965) | ||
| 4 | |||
| 1 | 2014-06-26 Glenn Morris <rgm@gnu.org> | 5 | 2014-06-26 Glenn Morris <rgm@gnu.org> |
| 2 | 6 | ||
| 3 | * Makefile.in (blessmail): Depend on lisp/mail/blessmail.el. | 7 | * 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) | |||
| 4747 | } | 4747 | } |
| 4748 | } | 4748 | } |
| 4749 | 4749 | ||
| 4750 | if (strneq (dbp + 1, "cl-", 3) || strneq (dbp + 1, "CL-", 3)) | ||
| 4751 | dbp += 3; | ||
| 4752 | |||
| 4750 | if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3)) | 4753 | if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3)) |
| 4751 | { | 4754 | { |
| 4752 | dbp = skip_non_spaces (dbp); | 4755 | 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 @@ | |||
| 1 | 2014-07-12 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix bug: C-x v v discarded existing log message (Bug#17884). | ||
| 4 | * vc/vc-dispatcher.el (vc-log-edit): | ||
| 5 | Don't clobber an already-existing log message. | ||
| 6 | |||
| 7 | 2014-07-12 Glenn Morris <rgm@gnu.org> | ||
| 8 | |||
| 9 | * vc/log-edit.el (log-edit-changelog-entries): | ||
| 10 | Check for a visited-but-never-saved ChangeLog. | ||
| 11 | |||
| 12 | 2014-07-12 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 13 | |||
| 14 | * vc/log-edit.el (log-edit-changelog-entries): Don't both visiting | ||
| 15 | a non-existing file (bug#17970). | ||
| 16 | |||
| 17 | * faces.el (face-name): Undo last change. | ||
| 18 | (x-resolve-font-name): Don't call face-name (bug#17956). | ||
| 19 | |||
| 20 | 2014-07-12 Fabián Ezequiel Gallina <fgallina@gnu.org> | ||
| 21 | |||
| 22 | Fix dedenters and electric colon handling. (Bug#15163) | ||
| 23 | * progmodes/python.el | ||
| 24 | (python-rx-constituents): Add dedenter and block-ender. | ||
| 25 | (python-indent-dedenters, python-indent-block-enders): Delete. | ||
| 26 | (python-indent-context): Return new case for dedenter-statement. | ||
| 27 | (python-indent-calculate-indentation): Handle new case. | ||
| 28 | (python-indent-calculate-levels): Fix levels calculation for | ||
| 29 | dedenter statements. | ||
| 30 | (python-indent-post-self-insert-function): Fix colon handling. | ||
| 31 | (python-info-dedenter-opening-block-message): New function. | ||
| 32 | (python-indent-line): Use it. | ||
| 33 | (python-info-closing-block) | ||
| 34 | (python-info-closing-block-message): Remove. | ||
| 35 | (python-info-dedenter-opening-block-position) | ||
| 36 | (python-info-dedenter-opening-block-positions) | ||
| 37 | (python-info-dedenter-statement-p): New functions. | ||
| 38 | |||
| 1 | 2014-07-11 Dmitry Antipov <dmantipov@yandex.ru> | 39 | 2014-07-11 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 40 | ||
| 3 | * files.el (out-of-memory-warning-percentage): New defcustom. | 41 | * 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." | |||
| 370 | 370 | ||
| 371 | (defun face-name (face) | 371 | (defun face-name (face) |
| 372 | "Return the name of face FACE." | 372 | "Return the name of face FACE." |
| 373 | (check-face face) | 373 | (symbol-name (check-face face))) |
| 374 | (if (symbolp face) | ||
| 375 | (symbol-name face) | ||
| 376 | face)) | ||
| 377 | 374 | ||
| 378 | 375 | ||
| 379 | (defun face-all-attributes (face &optional frame) | 376 | (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 | |||
| 2749 | contains wildcards. | 2746 | contains wildcards. |
| 2750 | Given optional arguments FACE and FRAME, return a font which is | 2747 | Given optional arguments FACE and FRAME, return a font which is |
| 2751 | also the same size as FACE on FRAME, or fail." | 2748 | also the same size as FACE on FRAME, or fail." |
| 2752 | (when face | ||
| 2753 | (setq face (face-name face))) | ||
| 2754 | (and (eq frame t) | 2749 | (and (eq frame t) |
| 2755 | (setq frame nil)) | 2750 | (setq frame nil)) |
| 2756 | (if pattern | 2751 | (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 @@ | |||
| 321 | (or "def" "class" "if" "elif" "else" "try" | 321 | (or "def" "class" "if" "elif" "else" "try" |
| 322 | "except" "finally" "for" "while" "with") | 322 | "except" "finally" "for" "while" "with") |
| 323 | symbol-end)) | 323 | symbol-end)) |
| 324 | (dedenter . ,(rx symbol-start | ||
| 325 | (or "elif" "else" "except" "finally") | ||
| 326 | symbol-end)) | ||
| 327 | (block-ender . ,(rx symbol-start | ||
| 328 | (or | ||
| 329 | "break" "continue" "pass" "raise" "return") | ||
| 330 | symbol-end)) | ||
| 324 | (decorator . ,(rx line-start (* space) ?@ (any letter ?_) | 331 | (decorator . ,(rx line-start (* space) ?@ (any letter ?_) |
| 325 | (* (any word ?_)))) | 332 | (* (any word ?_)))) |
| 326 | (defun . ,(rx symbol-start (or "def" "class") symbol-end)) | 333 | (defun . ,(rx symbol-start (or "def" "class") symbol-end)) |
| @@ -630,18 +637,6 @@ It makes underscores and dots word constituent chars.") | |||
| 630 | (defvar python-indent-levels '(0) | 637 | (defvar python-indent-levels '(0) |
| 631 | "Levels of indentation available for `python-indent-line-function'.") | 638 | "Levels of indentation available for `python-indent-line-function'.") |
| 632 | 639 | ||
| 633 | (defvar python-indent-dedenters '("else" "elif" "except" "finally") | ||
| 634 | "List of words that should be dedented. | ||
| 635 | These make `python-indent-calculate-indentation' subtract the value of | ||
| 636 | `python-indent-offset'.") | ||
| 637 | |||
| 638 | (defvar python-indent-block-enders | ||
| 639 | '("break" "continue" "pass" "raise" "return") | ||
| 640 | "List of words that mark the end of a block. | ||
| 641 | These make `python-indent-calculate-indentation' subtract the | ||
| 642 | value of `python-indent-offset' when `python-indent-context' is | ||
| 643 | AFTER-LINE.") | ||
| 644 | |||
| 645 | (defun python-indent-guess-indent-offset () | 640 | (defun python-indent-guess-indent-offset () |
| 646 | "Guess and set `python-indent-offset' for the current buffer." | 641 | "Guess and set `python-indent-offset' for the current buffer." |
| 647 | (interactive) | 642 | (interactive) |
| @@ -692,6 +687,7 @@ Where status can be any of the following symbols: | |||
| 692 | * after-backslash: Previous line ends in a backslash | 687 | * after-backslash: Previous line ends in a backslash |
| 693 | * after-beginning-of-block: Point is after beginning of block | 688 | * after-beginning-of-block: Point is after beginning of block |
| 694 | * after-line: Point is after normal line | 689 | * after-line: Point is after normal line |
| 690 | * dedenter-statement: Point is on a dedenter statement. | ||
| 695 | * no-indent: Point is at beginning of buffer or other special case | 691 | * no-indent: Point is at beginning of buffer or other special case |
| 696 | START is the buffer position where the sexp starts." | 692 | START is the buffer position where the sexp starts." |
| 697 | (save-restriction | 693 | (save-restriction |
| @@ -746,6 +742,8 @@ START is the buffer position where the sexp starts." | |||
| 746 | (when (looking-at (python-rx block-start)) | 742 | (when (looking-at (python-rx block-start)) |
| 747 | (point-marker))))) | 743 | (point-marker))))) |
| 748 | 'after-beginning-of-block) | 744 | 'after-beginning-of-block) |
| 745 | ((when (setq start (python-info-dedenter-statement-p)) | ||
| 746 | 'dedenter-statement)) | ||
| 749 | ;; After normal line | 747 | ;; After normal line |
| 750 | ((setq start (save-excursion | 748 | ((setq start (save-excursion |
| 751 | (back-to-indentation) | 749 | (back-to-indentation) |
| @@ -776,8 +774,7 @@ START is the buffer position where the sexp starts." | |||
| 776 | (goto-char context-start) | 774 | (goto-char context-start) |
| 777 | (+ (current-indentation) python-indent-offset)) | 775 | (+ (current-indentation) python-indent-offset)) |
| 778 | ;; When after a simple line just use previous line | 776 | ;; When after a simple line just use previous line |
| 779 | ;; indentation, in the case current line starts with a | 777 | ;; indentation. |
| 780 | ;; `python-indent-dedenters' de-indent one level. | ||
| 781 | (`after-line | 778 | (`after-line |
| 782 | (let* ((pair (save-excursion | 779 | (let* ((pair (save-excursion |
| 783 | (goto-char context-start) | 780 | (goto-char context-start) |
| @@ -785,25 +782,27 @@ START is the buffer position where the sexp starts." | |||
| 785 | (current-indentation) | 782 | (current-indentation) |
| 786 | (python-info-beginning-of-block-p)))) | 783 | (python-info-beginning-of-block-p)))) |
| 787 | (context-indentation (car pair)) | 784 | (context-indentation (car pair)) |
| 788 | (after-block-start-p (cdr pair)) | 785 | ;; TODO: Separate block enders into its own case. |
| 789 | (adjustment | 786 | (adjustment |
| 790 | (if (or (save-excursion | 787 | (if (save-excursion |
| 791 | (back-to-indentation) | 788 | (python-util-forward-comment -1) |
| 792 | (and | 789 | (python-nav-beginning-of-statement) |
| 793 | ;; De-indent only when dedenters are not | 790 | (looking-at (python-rx block-ender))) |
| 794 | ;; next to a block start. This allows | ||
| 795 | ;; one-liner constructs such as: | ||
| 796 | ;; if condition: print "yay" | ||
| 797 | ;; else: print "wry" | ||
| 798 | (not after-block-start-p) | ||
| 799 | (looking-at (regexp-opt python-indent-dedenters)))) | ||
| 800 | (save-excursion | ||
| 801 | (python-util-forward-comment -1) | ||
| 802 | (python-nav-beginning-of-statement) | ||
| 803 | (looking-at (regexp-opt python-indent-block-enders)))) | ||
| 804 | python-indent-offset | 791 | python-indent-offset |
| 805 | 0))) | 792 | 0))) |
| 806 | (- context-indentation adjustment))) | 793 | (- context-indentation adjustment))) |
| 794 | ;; When point is on a dedenter statement, search for the | ||
| 795 | ;; opening block that corresponds to it and use its | ||
| 796 | ;; indentation. If no opening block is found just remove | ||
| 797 | ;; indentation as this is an invalid python file. | ||
| 798 | (`dedenter-statement | ||
| 799 | (let ((block-start-point | ||
| 800 | (python-info-dedenter-opening-block-position))) | ||
| 801 | (save-excursion | ||
| 802 | (if (not block-start-point) | ||
| 803 | 0 | ||
| 804 | (goto-char block-start-point) | ||
| 805 | (current-indentation))))) | ||
| 807 | ;; When inside of a string, do nothing. just use the current | 806 | ;; When inside of a string, do nothing. just use the current |
| 808 | ;; indentation. XXX: perhaps it would be a good idea to | 807 | ;; indentation. XXX: perhaps it would be a good idea to |
| 809 | ;; invoke standard text indentation here | 808 | ;; invoke standard text indentation here |
| @@ -930,16 +929,25 @@ START is the buffer position where the sexp starts." | |||
| 930 | 929 | ||
| 931 | (defun python-indent-calculate-levels () | 930 | (defun python-indent-calculate-levels () |
| 932 | "Calculate `python-indent-levels' and reset `python-indent-current-level'." | 931 | "Calculate `python-indent-levels' and reset `python-indent-current-level'." |
| 933 | (let* ((indentation (python-indent-calculate-indentation)) | 932 | (if (not (python-info-dedenter-statement-p)) |
| 934 | (remainder (% indentation python-indent-offset)) | 933 | (let* ((indentation (python-indent-calculate-indentation)) |
| 935 | (steps (/ (- indentation remainder) python-indent-offset))) | 934 | (remainder (% indentation python-indent-offset)) |
| 936 | (setq python-indent-levels (list 0)) | 935 | (steps (/ (- indentation remainder) python-indent-offset))) |
| 937 | (dotimes (step steps) | 936 | (setq python-indent-levels (list 0)) |
| 938 | (push (* python-indent-offset (1+ step)) python-indent-levels)) | 937 | (dotimes (step steps) |
| 939 | (when (not (eq 0 remainder)) | 938 | (push (* python-indent-offset (1+ step)) python-indent-levels)) |
| 940 | (push (+ (* python-indent-offset steps) remainder) python-indent-levels)) | 939 | (when (not (eq 0 remainder)) |
| 941 | (setq python-indent-levels (nreverse python-indent-levels)) | 940 | (push (+ (* python-indent-offset steps) remainder) python-indent-levels))) |
| 942 | (setq python-indent-current-level (1- (length python-indent-levels))))) | 941 | (setq python-indent-levels |
| 942 | (or | ||
| 943 | (mapcar (lambda (pos) | ||
| 944 | (save-excursion | ||
| 945 | (goto-char pos) | ||
| 946 | (current-indentation))) | ||
| 947 | (python-info-dedenter-opening-block-positions)) | ||
| 948 | (list 0)))) | ||
| 949 | (setq python-indent-current-level (1- (length python-indent-levels)) | ||
| 950 | python-indent-levels (nreverse python-indent-levels))) | ||
| 943 | 951 | ||
| 944 | (defun python-indent-toggle-levels () | 952 | (defun python-indent-toggle-levels () |
| 945 | "Toggle `python-indent-current-level' over `python-indent-levels'." | 953 | "Toggle `python-indent-current-level' over `python-indent-levels'." |
| @@ -988,7 +996,7 @@ equal to | |||
| 988 | (indent-to next-indent) | 996 | (indent-to next-indent) |
| 989 | (goto-char starting-pos)) | 997 | (goto-char starting-pos)) |
| 990 | (and follow-indentation-p (back-to-indentation))) | 998 | (and follow-indentation-p (back-to-indentation))) |
| 991 | (python-info-closing-block-message)) | 999 | (python-info-dedenter-opening-block-message)) |
| 992 | 1000 | ||
| 993 | (defun python-indent-line-function () | 1001 | (defun python-indent-line-function () |
| 994 | "`indent-line-function' for Python mode. | 1002 | "`indent-line-function' for Python mode. |
| @@ -1124,14 +1132,7 @@ the line will be re-indented automatically if needed." | |||
| 1124 | (eolp) | 1132 | (eolp) |
| 1125 | (not (equal ?: (char-before (1- (point))))) | 1133 | (not (equal ?: (char-before (1- (point))))) |
| 1126 | (not (python-syntax-comment-or-string-p))) | 1134 | (not (python-syntax-comment-or-string-p))) |
| 1127 | (let ((indentation (current-indentation)) | 1135 | (python-indent-line))))) |
| 1128 | (calculated-indentation (python-indent-calculate-indentation))) | ||
| 1129 | (python-info-closing-block-message) | ||
| 1130 | (when (> indentation calculated-indentation) | ||
| 1131 | (save-excursion | ||
| 1132 | (indent-line-to calculated-indentation) | ||
| 1133 | (when (not (python-info-closing-block-message)) | ||
| 1134 | (indent-line-to indentation))))))))) | ||
| 1135 | 1136 | ||
| 1136 | 1137 | ||
| 1137 | ;;; Navigation | 1138 | ;;; Navigation |
| @@ -3454,49 +3455,88 @@ parent defun name." | |||
| 3454 | (and (python-info-end-of-statement-p) | 3455 | (and (python-info-end-of-statement-p) |
| 3455 | (python-info-statement-ends-block-p))) | 3456 | (python-info-statement-ends-block-p))) |
| 3456 | 3457 | ||
| 3457 | (defun python-info-closing-block () | 3458 | (define-obsolete-function-alias |
| 3458 | "Return the point of the block the current line closes." | 3459 | 'python-info-closing-block |
| 3459 | (let ((closing-word (save-excursion | 3460 | 'python-info-dedenter-opening-block-position "24.4") |
| 3460 | (back-to-indentation) | 3461 | |
| 3461 | (current-word))) | 3462 | (defun python-info-dedenter-opening-block-position () |
| 3462 | (indentation (current-indentation))) | 3463 | "Return the point of the closest block the current line closes. |
| 3463 | (when (member closing-word python-indent-dedenters) | 3464 | Returns nil if point is not on a dedenter statement or no opening |
| 3465 | block can be detected. The latter case meaning current file is | ||
| 3466 | likely an invalid python file." | ||
| 3467 | (let ((positions (python-info-dedenter-opening-block-positions)) | ||
| 3468 | (indentation (current-indentation)) | ||
| 3469 | (position)) | ||
| 3470 | (while (and (not position) | ||
| 3471 | positions) | ||
| 3464 | (save-excursion | 3472 | (save-excursion |
| 3465 | (forward-line -1) | 3473 | (goto-char (car positions)) |
| 3466 | (while (and (> (current-indentation) indentation) | 3474 | (if (<= (current-indentation) indentation) |
| 3467 | (not (bobp)) | 3475 | (setq position (car positions)) |
| 3468 | (not (back-to-indentation)) | 3476 | (setq positions (cdr positions))))) |
| 3469 | (forward-line -1))) | 3477 | position)) |
| 3470 | (back-to-indentation) | 3478 | |
| 3471 | (cond | 3479 | (defun python-info-dedenter-opening-block-positions () |
| 3472 | ((not (equal indentation (current-indentation))) nil) | 3480 | "Return points of blocks the current line may close sorted by closer. |
| 3473 | ((string= closing-word "elif") | 3481 | Returns nil if point is not on a dedenter statement or no opening |
| 3474 | (when (member (current-word) '("if" "elif")) | 3482 | block can be detected. The latter case meaning current file is |
| 3475 | (point-marker))) | 3483 | likely an invalid python file." |
| 3476 | ((string= closing-word "else") | 3484 | (save-excursion |
| 3477 | (when (member (current-word) '("if" "elif" "except" "for" "while")) | 3485 | (let ((dedenter-pos (python-info-dedenter-statement-p))) |
| 3478 | (point-marker))) | 3486 | (when dedenter-pos |
| 3479 | ((string= closing-word "except") | 3487 | (goto-char dedenter-pos) |
| 3480 | (when (member (current-word) '("try")) | 3488 | (let* ((pairs '(("elif" "elif" "if") |
| 3481 | (point-marker))) | 3489 | ("else" "if" "elif" "except" "for" "while") |
| 3482 | ((string= closing-word "finally") | 3490 | ("except" "except" "try") |
| 3483 | (when (member (current-word) '("except" "else")) | 3491 | ("finally" "else" "except" "try"))) |
| 3484 | (point-marker)))))))) | 3492 | (dedenter (match-string-no-properties 0)) |
| 3485 | 3493 | (possible-opening-blocks (cdr (assoc-string dedenter pairs))) | |
| 3486 | (defun python-info-closing-block-message (&optional closing-block-point) | 3494 | (collected-indentations) |
| 3487 | "Message the contents of the block the current line closes. | 3495 | (opening-blocks)) |
| 3488 | With optional argument CLOSING-BLOCK-POINT use that instead of | 3496 | (catch 'exit |
| 3489 | recalculating it calling `python-info-closing-block'." | 3497 | (while (python-nav--syntactically |
| 3490 | (let ((point (or closing-block-point (python-info-closing-block)))) | 3498 | (lambda () |
| 3499 | (re-search-backward (python-rx block-start) nil t)) | ||
| 3500 | #'<) | ||
| 3501 | (let ((indentation (current-indentation))) | ||
| 3502 | (when (and (not (memq indentation collected-indentations)) | ||
| 3503 | (or (not collected-indentations) | ||
| 3504 | (< indentation (apply #'min collected-indentations)))) | ||
| 3505 | (setq collected-indentations | ||
| 3506 | (cons indentation collected-indentations)) | ||
| 3507 | (when (member (match-string-no-properties 0) | ||
| 3508 | possible-opening-blocks) | ||
| 3509 | (setq opening-blocks (cons (point) opening-blocks)))) | ||
| 3510 | (when (zerop indentation) | ||
| 3511 | (throw 'exit nil))))) | ||
| 3512 | ;; sort by closer | ||
| 3513 | (nreverse opening-blocks)))))) | ||
| 3514 | |||
| 3515 | (define-obsolete-function-alias | ||
| 3516 | 'python-info-closing-block-message | ||
| 3517 | 'python-info-dedenter-opening-block-message "24.4") | ||
| 3518 | |||
| 3519 | (defun python-info-dedenter-opening-block-message () | ||
| 3520 | "Message the first line of the block the current statement closes." | ||
| 3521 | (let ((point (python-info-dedenter-opening-block-position))) | ||
| 3491 | (when point | 3522 | (when point |
| 3492 | (save-restriction | 3523 | (save-restriction |
| 3493 | (widen) | 3524 | (widen) |
| 3494 | (message "Closes %s" (save-excursion | 3525 | (message "Closes %s" (save-excursion |
| 3495 | (goto-char point) | 3526 | (goto-char point) |
| 3496 | (back-to-indentation) | ||
| 3497 | (buffer-substring | 3527 | (buffer-substring |
| 3498 | (point) (line-end-position)))))))) | 3528 | (point) (line-end-position)))))))) |
| 3499 | 3529 | ||
| 3530 | (defun python-info-dedenter-statement-p () | ||
| 3531 | "Return point if current statement is a dedenter. | ||
| 3532 | Sets `match-data' to the keyword that starts the dedenter | ||
| 3533 | statement." | ||
| 3534 | (save-excursion | ||
| 3535 | (python-nav-beginning-of-statement) | ||
| 3536 | (when (and (not (python-syntax-context-type)) | ||
| 3537 | (looking-at (python-rx dedenter))) | ||
| 3538 | (point)))) | ||
| 3539 | |||
| 3500 | (defun python-info-line-ends-backslash-p (&optional line-number) | 3540 | (defun python-info-line-ends-backslash-p (&optional line-number) |
| 3501 | "Return non-nil if current line ends with backslash. | 3541 | "Return non-nil if current line ends with backslash. |
| 3502 | With optional argument LINE-NUMBER, check that line instead." | 3542 | 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 | |||
| 905 | ;; that memoizing which is undesired here. | 905 | ;; that memoizing which is undesired here. |
| 906 | (setq change-log-default-name nil) | 906 | (setq change-log-default-name nil) |
| 907 | (find-change-log))))) | 907 | (find-change-log))))) |
| 908 | (with-current-buffer (find-file-noselect changelog-file-name) | 908 | (when (or (find-buffer-visiting changelog-file-name) |
| 909 | (unless (eq major-mode 'change-log-mode) (change-log-mode)) | 909 | (file-exists-p changelog-file-name)) |
| 910 | (goto-char (point-min)) | 910 | (with-current-buffer (find-file-noselect changelog-file-name) |
| 911 | (if (looking-at "\\s-*\n") (goto-char (match-end 0))) | 911 | (unless (eq major-mode 'change-log-mode) (change-log-mode)) |
| 912 | (if (not (log-edit-changelog-ours-p)) | 912 | (goto-char (point-min)) |
| 913 | (list (current-buffer)) | 913 | (if (looking-at "\\s-*\n") (goto-char (match-end 0))) |
| 914 | (save-restriction | 914 | (if (not (log-edit-changelog-ours-p)) |
| 915 | (log-edit-narrow-changelog) | 915 | (list (current-buffer)) |
| 916 | (goto-char (point-min)) | 916 | (save-restriction |
| 917 | 917 | (log-edit-narrow-changelog) | |
| 918 | ;; Search for the name of FILE relative to the ChangeLog. If that | 918 | (goto-char (point-min)) |
| 919 | ;; doesn't occur anywhere, they're not using full relative | 919 | |
| 920 | ;; filenames in the ChangeLog, so just look for FILE; we'll accept | 920 | ;; Search for the name of FILE relative to the ChangeLog. If that |
| 921 | ;; some false positives. | 921 | ;; doesn't occur anywhere, they're not using full relative |
| 922 | (let ((pattern (file-relative-name | 922 | ;; filenames in the ChangeLog, so just look for FILE; we'll accept |
| 923 | file (file-name-directory changelog-file-name)))) | 923 | ;; some false positives. |
| 924 | (if (or (string= pattern "") | 924 | (let ((pattern (file-relative-name |
| 925 | (not (save-excursion | 925 | file (file-name-directory changelog-file-name)))) |
| 926 | (search-forward pattern nil t)))) | 926 | (if (or (string= pattern "") |
| 927 | (setq pattern (file-name-nondirectory file))) | 927 | (not (save-excursion |
| 928 | 928 | (search-forward pattern nil t)))) | |
| 929 | (setq pattern (concat "\\(^\\|[^[:alnum:]]\\)" | 929 | (setq pattern (file-name-nondirectory file))) |
| 930 | (regexp-quote pattern) | 930 | |
| 931 | "\\($\\|[^[:alnum:]]\\)")) | 931 | (setq pattern (concat "\\(^\\|[^[:alnum:]]\\)" |
| 932 | 932 | (regexp-quote pattern) | |
| 933 | (let (texts | 933 | "\\($\\|[^[:alnum:]]\\)")) |
| 934 | (pos (point))) | 934 | |
| 935 | (while (and (not (eobp)) (re-search-forward pattern nil t)) | 935 | (let (texts |
| 936 | (let ((entry (log-edit-changelog-entry))) | 936 | (pos (point))) |
| 937 | (if (< (elt entry 1) (max (1+ pos) (point))) | 937 | (while (and (not (eobp)) (re-search-forward pattern nil t)) |
| 938 | ;; This is not relevant, actually. | 938 | (let ((entry (log-edit-changelog-entry))) |
| 939 | nil | 939 | (if (< (elt entry 1) (max (1+ pos) (point))) |
| 940 | (push entry texts)) | 940 | ;; This is not relevant, actually. |
| 941 | ;; Make sure we make progress. | 941 | nil |
| 942 | (setq pos (max (1+ pos) (elt entry 1))) | 942 | (push entry texts)) |
| 943 | (goto-char pos))) | 943 | ;; Make sure we make progress. |
| 944 | 944 | (setq pos (max (1+ pos) (elt entry 1))) | |
| 945 | (cons (current-buffer) texts)))))))) | 945 | (goto-char pos))) |
| 946 | |||
| 947 | (cons (current-buffer) texts))))))))) | ||
| 946 | 948 | ||
| 947 | (defun log-edit-changelog-insert-entries (buffer beg end &rest files) | 949 | (defun log-edit-changelog-insert-entries (buffer beg end &rest files) |
| 948 | "Insert the text from BUFFER between BEG and END. | 950 | "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." | |||
| 596 | (setq default-directory | 596 | (setq default-directory |
| 597 | (buffer-local-value 'default-directory vc-parent-buffer)) | 597 | (buffer-local-value 'default-directory vc-parent-buffer)) |
| 598 | (log-edit 'vc-finish-logentry | 598 | (log-edit 'vc-finish-logentry |
| 599 | t | 599 | (= (point-min) (point-max)) |
| 600 | `((log-edit-listfun . (lambda () | 600 | `((log-edit-listfun . (lambda () |
| 601 | ;; FIXME: Should expand the list | 601 | ;; FIXME: Should expand the list |
| 602 | ;; for directories. | 602 | ;; for directories. |
diff --git a/src/ChangeLog b/src/ChangeLog index 9d5dff49166..47b0927bbb7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,15 @@ | |||
| 1 | 2014-07-12 Eli Zaretskii <eliz@gnu.org> | 1 | 2014-07-12 Eli Zaretskii <eliz@gnu.org> |
| 2 | 2 | ||
| 3 | * xdisp.c (display_line): Don't call FETCH_BYTE with argument less | ||
| 4 | than 1. (Bug#17962) | ||
| 5 | |||
| 6 | * w32fns.c (Fx_file_dialog): Mention in the doc string the | ||
| 7 | behavior on Windows 7 and later when the function is repeatedly | ||
| 8 | invoked with the same value of DIR. (Bug#17950) | ||
| 9 | |||
| 10 | * xfns.c (Fx_file_dialog) [USE_MOTIF, USE_GTK]: Update the doc | ||
| 11 | string to match the one in w32fns.c. | ||
| 12 | |||
| 3 | * minibuf.c (read_minibuf_noninteractive) [WINDOWSNT]: Switch | 13 | * minibuf.c (read_minibuf_noninteractive) [WINDOWSNT]: Switch |
| 4 | stdin to binary mode only if it is connected to a terminal. | 14 | stdin to binary mode only if it is connected to a terminal. |
| 5 | 15 | ||
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. | |||
| 6394 | 6394 | ||
| 6395 | This function is only defined on NS, MS Windows, and X Windows with the | 6395 | This function is only defined on NS, MS Windows, and X Windows with the |
| 6396 | Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. | 6396 | Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. |
| 6397 | Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | 6397 | Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. |
| 6398 | On Windows 7 and later, the file selection dialog "remembers" the last | ||
| 6399 | directory where the user selected a file, and will open that directory | ||
| 6400 | instead of DIR on subsequent invocations of this function with the same | ||
| 6401 | value of DIR as in previous invocations; this is standard Windows behavior. */) | ||
| 6398 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) | 6402 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) |
| 6399 | { | 6403 | { |
| 6400 | /* Filter index: 1: All Files, 2: Directories only */ | 6404 | /* 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) | |||
| 20494 | row->truncated_on_right_p = 1; | 20494 | row->truncated_on_right_p = 1; |
| 20495 | it->continuation_lines_width = 0; | 20495 | it->continuation_lines_width = 0; |
| 20496 | reseat_at_next_visible_line_start (it, 0); | 20496 | reseat_at_next_visible_line_start (it, 0); |
| 20497 | row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; | 20497 | if (IT_BYTEPOS (*it) <= BEG_BYTE) |
| 20498 | row->ends_at_zv_p = true; | ||
| 20499 | else | ||
| 20500 | row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n'; | ||
| 20498 | break; | 20501 | break; |
| 20499 | } | 20502 | } |
| 20500 | } | 20503 | } |
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. | |||
| 5705 | 5705 | ||
| 5706 | This function is only defined on NS, MS Windows, and X Windows with the | 5706 | This function is only defined on NS, MS Windows, and X Windows with the |
| 5707 | Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. | 5707 | Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. |
| 5708 | Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | 5708 | Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. |
| 5709 | On Windows 7 and later, the file selection dialog "remembers" the last | ||
| 5710 | directory where the user selected a file, and will open that directory | ||
| 5711 | instead of DIR on subsequent invocations of this function with the same | ||
| 5712 | value of DIR as in previous invocations; this is standard Windows behavior. */) | ||
| 5709 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, | 5713 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, |
| 5710 | Lisp_Object mustmatch, Lisp_Object only_dir_p) | 5714 | Lisp_Object mustmatch, Lisp_Object only_dir_p) |
| 5711 | { | 5715 | { |
| @@ -5877,7 +5881,11 @@ or directory must exist. | |||
| 5877 | 5881 | ||
| 5878 | This function is only defined on NS, MS Windows, and X Windows with the | 5882 | This function is only defined on NS, MS Windows, and X Windows with the |
| 5879 | Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. | 5883 | Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored. |
| 5880 | Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | 5884 | Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. |
| 5885 | On Windows 7 and later, the file selection dialog "remembers" the last | ||
| 5886 | directory where the user selected a file, and will open that directory | ||
| 5887 | instead of DIR on subsequent invocations of this function with the same | ||
| 5888 | value of DIR as in previous invocations; this is standard Windows behavior. */) | ||
| 5881 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) | 5889 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) |
| 5882 | { | 5890 | { |
| 5883 | struct frame *f = SELECTED_FRAME (); | 5891 | 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 @@ | |||
| 1 | 2014-07-12 Fabián Ezequiel Gallina <fgallina@gnu.org> | ||
| 2 | |||
| 3 | * automated/python-tests.el (python-indent-block-enders-1) | ||
| 4 | (python-indent-block-enders-2): Fix tests. | ||
| 5 | (python-indent-block-enders-3, python-indent-block-enders-4) | ||
| 6 | (python-indent-block-enders-5, python-indent-dedenters-1) | ||
| 7 | (python-indent-dedenters-2): Remove tests. | ||
| 8 | (python-indent-dedenters-1, python-indent-dedenters-2) | ||
| 9 | (python-indent-dedenters-3, python-indent-dedenters-4) | ||
| 10 | (python-indent-dedenters-5, python-indent-dedenters-6) | ||
| 11 | (python-indent-dedenters-7) | ||
| 12 | (python-info-dedenter-opening-block-position-1) | ||
| 13 | (python-info-dedenter-opening-block-position-2) | ||
| 14 | (python-info-dedenter-opening-block-position-3) | ||
| 15 | (python-info-dedenter-opening-block-positions-1) | ||
| 16 | (python-info-dedenter-opening-block-positions-2) | ||
| 17 | (python-info-dedenter-opening-block-positions-3) | ||
| 18 | (python-info-dedenter-opening-block-positions-4) | ||
| 19 | (python-info-dedenter-opening-block-positions-5) | ||
| 20 | (python-info-dedenter-opening-block-message-1) | ||
| 21 | (python-info-dedenter-opening-block-message-2) | ||
| 22 | (python-info-dedenter-opening-block-message-3) | ||
| 23 | (python-info-dedenter-opening-block-message-4) | ||
| 24 | (python-info-dedenter-opening-block-message-5) | ||
| 25 | (python-info-dedenter-statement-p-1) | ||
| 26 | (python-info-dedenter-statement-p-2) | ||
| 27 | (python-info-dedenter-statement-p-3) | ||
| 28 | (python-info-dedenter-statement-p-4) | ||
| 29 | (python-info-dedenter-statement-p-5): New tests. | ||
| 30 | |||
| 1 | 2014-07-08 Stefan Monnier <monnier@iro.umontreal.ca> | 31 | 2014-07-08 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 32 | ||
| 3 | * indent/perl.perl: Add indentation pattern for hash-table entries. | 33 | * 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={ | |||
| 435 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | 435 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) |
| 436 | (should (= (python-indent-calculate-indentation) 4)))) | 436 | (should (= (python-indent-calculate-indentation) 4)))) |
| 437 | 437 | ||
| 438 | (ert-deftest python-indent-dedenters-1 () | ||
| 439 | "Check all dedenters." | ||
| 440 | (python-tests-with-temp-buffer | ||
| 441 | " | ||
| 442 | def foo(a, b, c): | ||
| 443 | if a: | ||
| 444 | print (a) | ||
| 445 | elif b: | ||
| 446 | print (b) | ||
| 447 | else: | ||
| 448 | try: | ||
| 449 | print (c.pop()) | ||
| 450 | except (IndexError, AttributeError): | ||
| 451 | print (c) | ||
| 452 | finally: | ||
| 453 | print ('nor a, nor b are true') | ||
| 454 | " | ||
| 455 | (python-tests-look-at "if a:") | ||
| 456 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 457 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 458 | (python-tests-look-at "print (a)") | ||
| 459 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 460 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 461 | (python-tests-look-at "elif b:") | ||
| 462 | (should (eq (car (python-indent-context)) 'after-line)) | ||
| 463 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 464 | (python-tests-look-at "print (b)") | ||
| 465 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 466 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 467 | (python-tests-look-at "else:") | ||
| 468 | (should (eq (car (python-indent-context)) 'after-line)) | ||
| 469 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 470 | (python-tests-look-at "try:") | ||
| 471 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 472 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 473 | (python-tests-look-at "print (c.pop())") | ||
| 474 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 475 | (should (= (python-indent-calculate-indentation) 12)) | ||
| 476 | (python-tests-look-at "except (IndexError, AttributeError):") | ||
| 477 | (should (eq (car (python-indent-context)) 'after-line)) | ||
| 478 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 479 | (python-tests-look-at "print (c)") | ||
| 480 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 481 | (should (= (python-indent-calculate-indentation) 12)) | ||
| 482 | (python-tests-look-at "finally:") | ||
| 483 | (should (eq (car (python-indent-context)) 'after-line)) | ||
| 484 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 485 | (python-tests-look-at "print ('nor a, nor b are true')") | ||
| 486 | (should (eq (car (python-indent-context)) 'after-beginning-of-block)) | ||
| 487 | (should (= (python-indent-calculate-indentation) 12)))) | ||
| 488 | |||
| 489 | (ert-deftest python-indent-dedenters-2 () | ||
| 490 | "Check one-liner block special case.." | ||
| 491 | (python-tests-with-temp-buffer | ||
| 492 | " | ||
| 493 | cond = True | ||
| 494 | if cond: | ||
| 495 | |||
| 496 | if cond: print 'True' | ||
| 497 | else: print 'False' | ||
| 498 | |||
| 499 | else: | ||
| 500 | return | ||
| 501 | " | ||
| 502 | (python-tests-look-at "else: print 'False'") | ||
| 503 | ;; When a block has code after ":" it's just considered a simple | ||
| 504 | ;; line as that's a common thing to happen in one-liners. | ||
| 505 | (should (eq (car (python-indent-context)) 'after-line)) | ||
| 506 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 507 | (python-tests-look-at "else:") | ||
| 508 | (should (eq (car (python-indent-context)) 'after-line)) | ||
| 509 | (should (= (python-indent-calculate-indentation) 0)))) | ||
| 510 | |||
| 511 | (ert-deftest python-indent-after-backslash-1 () | 438 | (ert-deftest python-indent-after-backslash-1 () |
| 512 | "The most common case." | 439 | "The most common case." |
| 513 | (python-tests-with-temp-buffer | 440 | (python-tests-with-temp-buffer |
| @@ -575,9 +502,9 @@ objects = Thing.objects.all() \\\\ | |||
| 575 | (should (= (python-indent-calculate-indentation) 0)))) | 502 | (should (= (python-indent-calculate-indentation) 0)))) |
| 576 | 503 | ||
| 577 | (ert-deftest python-indent-block-enders-1 () | 504 | (ert-deftest python-indent-block-enders-1 () |
| 578 | "Test `python-indent-block-enders' value honoring." | 505 | "Test de-indentation for pass keyword." |
| 579 | (python-tests-with-temp-buffer | 506 | (python-tests-with-temp-buffer |
| 580 | " | 507 | " |
| 581 | Class foo(object): | 508 | Class foo(object): |
| 582 | 509 | ||
| 583 | def bar(self): | 510 | def bar(self): |
| @@ -589,17 +516,17 @@ Class foo(object): | |||
| 589 | else: | 516 | else: |
| 590 | pass | 517 | pass |
| 591 | " | 518 | " |
| 592 | (python-tests-look-at "3)") | 519 | (python-tests-look-at "3)") |
| 593 | (forward-line 1) | 520 | (forward-line 1) |
| 594 | (should (= (python-indent-calculate-indentation) 8)) | 521 | (should (= (python-indent-calculate-indentation) 8)) |
| 595 | (python-tests-look-at "pass") | 522 | (python-tests-look-at "pass") |
| 596 | (forward-line 1) | 523 | (forward-line 1) |
| 597 | (should (= (python-indent-calculate-indentation) 8)))) | 524 | (should (= (python-indent-calculate-indentation) 8)))) |
| 598 | 525 | ||
| 599 | (ert-deftest python-indent-block-enders-2 () | 526 | (ert-deftest python-indent-block-enders-2 () |
| 600 | "Test `python-indent-block-enders' value honoring." | 527 | "Test de-indentation for return keyword." |
| 601 | (python-tests-with-temp-buffer | 528 | (python-tests-with-temp-buffer |
| 602 | " | 529 | " |
| 603 | Class foo(object): | 530 | Class foo(object): |
| 604 | '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do | 531 | '''raise lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do |
| 605 | 532 | ||
| @@ -612,10 +539,177 @@ Class foo(object): | |||
| 612 | 2, | 539 | 2, |
| 613 | 3) | 540 | 3) |
| 614 | " | 541 | " |
| 615 | (python-tests-look-at "def") | 542 | (python-tests-look-at "def") |
| 616 | (should (= (python-indent-calculate-indentation) 4)) | 543 | (should (= (python-indent-calculate-indentation) 4)) |
| 617 | (python-tests-look-at "if") | 544 | (python-tests-look-at "if") |
| 618 | (should (= (python-indent-calculate-indentation) 8)))) | 545 | (should (= (python-indent-calculate-indentation) 8)) |
| 546 | (python-tests-look-at "return") | ||
| 547 | (should (= (python-indent-calculate-indentation) 12)) | ||
| 548 | (goto-char (point-max)) | ||
| 549 | (should (= (python-indent-calculate-indentation) 8)))) | ||
| 550 | |||
| 551 | (ert-deftest python-indent-block-enders-3 () | ||
| 552 | "Test de-indentation for continue keyword." | ||
| 553 | (python-tests-with-temp-buffer | ||
| 554 | " | ||
| 555 | for element in lst: | ||
| 556 | if element is None: | ||
| 557 | continue | ||
| 558 | " | ||
| 559 | (python-tests-look-at "if") | ||
| 560 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 561 | (python-tests-look-at "continue") | ||
| 562 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 563 | (forward-line 1) | ||
| 564 | (should (= (python-indent-calculate-indentation) 4)))) | ||
| 565 | |||
| 566 | (ert-deftest python-indent-block-enders-4 () | ||
| 567 | "Test de-indentation for break keyword." | ||
| 568 | (python-tests-with-temp-buffer | ||
| 569 | " | ||
| 570 | for element in lst: | ||
| 571 | if element is None: | ||
| 572 | break | ||
| 573 | " | ||
| 574 | (python-tests-look-at "if") | ||
| 575 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 576 | (python-tests-look-at "break") | ||
| 577 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 578 | (forward-line 1) | ||
| 579 | (should (= (python-indent-calculate-indentation) 4)))) | ||
| 580 | |||
| 581 | (ert-deftest python-indent-block-enders-5 () | ||
| 582 | "Test de-indentation for raise keyword." | ||
| 583 | (python-tests-with-temp-buffer | ||
| 584 | " | ||
| 585 | for element in lst: | ||
| 586 | if element is None: | ||
| 587 | raise ValueError('Element cannot be None') | ||
| 588 | " | ||
| 589 | (python-tests-look-at "if") | ||
| 590 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 591 | (python-tests-look-at "raise") | ||
| 592 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 593 | (forward-line 1) | ||
| 594 | (should (= (python-indent-calculate-indentation) 4)))) | ||
| 595 | |||
| 596 | (ert-deftest python-indent-dedenters-1 () | ||
| 597 | "Test de-indentation for the elif keyword." | ||
| 598 | (python-tests-with-temp-buffer | ||
| 599 | " | ||
| 600 | if save: | ||
| 601 | try: | ||
| 602 | write_to_disk(data) | ||
| 603 | finally: | ||
| 604 | cleanup() | ||
| 605 | elif | ||
| 606 | " | ||
| 607 | (python-tests-look-at "elif\n") | ||
| 608 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 609 | (should (= (python-indent-calculate-indentation) 0)) | ||
| 610 | (should (equal (python-indent-calculate-levels) '(0))))) | ||
| 611 | |||
| 612 | (ert-deftest python-indent-dedenters-2 () | ||
| 613 | "Test de-indentation for the else keyword." | ||
| 614 | (python-tests-with-temp-buffer | ||
| 615 | " | ||
| 616 | if save: | ||
| 617 | try: | ||
| 618 | write_to_disk(data) | ||
| 619 | except IOError: | ||
| 620 | msg = 'Error saving to disk' | ||
| 621 | message(msg) | ||
| 622 | logger.exception(msg) | ||
| 623 | except Exception: | ||
| 624 | if hide_details: | ||
| 625 | logger.exception('Unhandled exception') | ||
| 626 | else | ||
| 627 | finally: | ||
| 628 | data.free() | ||
| 629 | " | ||
| 630 | (python-tests-look-at "else\n") | ||
| 631 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 632 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 633 | (should (equal (python-indent-calculate-levels) '(0 4 8))))) | ||
| 634 | |||
| 635 | (ert-deftest python-indent-dedenters-3 () | ||
| 636 | "Test de-indentation for the except keyword." | ||
| 637 | (python-tests-with-temp-buffer | ||
| 638 | " | ||
| 639 | if save: | ||
| 640 | try: | ||
| 641 | write_to_disk(data) | ||
| 642 | except | ||
| 643 | " | ||
| 644 | (python-tests-look-at "except\n") | ||
| 645 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 646 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 647 | (should (equal (python-indent-calculate-levels) '(4))))) | ||
| 648 | |||
| 649 | (ert-deftest python-indent-dedenters-4 () | ||
| 650 | "Test de-indentation for the finally keyword." | ||
| 651 | (python-tests-with-temp-buffer | ||
| 652 | " | ||
| 653 | if save: | ||
| 654 | try: | ||
| 655 | write_to_disk(data) | ||
| 656 | finally | ||
| 657 | " | ||
| 658 | (python-tests-look-at "finally\n") | ||
| 659 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 660 | (should (= (python-indent-calculate-indentation) 4)) | ||
| 661 | (should (equal (python-indent-calculate-levels) '(4))))) | ||
| 662 | |||
| 663 | (ert-deftest python-indent-dedenters-5 () | ||
| 664 | "Test invalid levels are skipped in a complex example." | ||
| 665 | (python-tests-with-temp-buffer | ||
| 666 | " | ||
| 667 | if save: | ||
| 668 | try: | ||
| 669 | write_to_disk(data) | ||
| 670 | except IOError: | ||
| 671 | msg = 'Error saving to disk' | ||
| 672 | message(msg) | ||
| 673 | logger.exception(msg) | ||
| 674 | finally: | ||
| 675 | if cleanup: | ||
| 676 | do_cleanup() | ||
| 677 | else | ||
| 678 | " | ||
| 679 | (python-tests-look-at "else\n") | ||
| 680 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 681 | (should (= (python-indent-calculate-indentation) 8)) | ||
| 682 | (should (equal (python-indent-calculate-levels) '(0 8))))) | ||
| 683 | |||
| 684 | (ert-deftest python-indent-dedenters-6 () | ||
| 685 | "Test indentation is zero when no opening block for dedenter." | ||
| 686 | (python-tests-with-temp-buffer | ||
| 687 | " | ||
| 688 | try: | ||
| 689 | # if save: | ||
| 690 | write_to_disk(data) | ||
| 691 | else | ||
| 692 | " | ||
| 693 | (python-tests-look-at "else\n") | ||
| 694 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 695 | (should (= (python-indent-calculate-indentation) 0)) | ||
| 696 | (should (equal (python-indent-calculate-levels) '(0))))) | ||
| 697 | |||
| 698 | (ert-deftest python-indent-dedenters-7 () | ||
| 699 | "Test indentation case from Bug#15163." | ||
| 700 | (python-tests-with-temp-buffer | ||
| 701 | " | ||
| 702 | if a: | ||
| 703 | if b: | ||
| 704 | pass | ||
| 705 | else: | ||
| 706 | pass | ||
| 707 | else: | ||
| 708 | " | ||
| 709 | (python-tests-look-at "else:" 2) | ||
| 710 | (should (eq (car (python-indent-context)) 'dedenter-statement)) | ||
| 711 | (should (= (python-indent-calculate-indentation) 0)) | ||
| 712 | (should (equal (python-indent-calculate-levels) '(0))))) | ||
| 619 | 713 | ||
| 620 | 714 | ||
| 621 | ;;; Navigation | 715 | ;;; Navigation |
| @@ -2428,9 +2522,9 @@ if width == 0 and height == 0 and \\\\ | |||
| 2428 | (python-util-forward-comment -1) | 2522 | (python-util-forward-comment -1) |
| 2429 | (should (python-info-end-of-block-p)))) | 2523 | (should (python-info-end-of-block-p)))) |
| 2430 | 2524 | ||
| 2431 | (ert-deftest python-info-closing-block-1 () | 2525 | (ert-deftest python-info-dedenter-opening-block-position-1 () |
| 2432 | (python-tests-with-temp-buffer | 2526 | (python-tests-with-temp-buffer |
| 2433 | " | 2527 | " |
| 2434 | if request.user.is_authenticated(): | 2528 | if request.user.is_authenticated(): |
| 2435 | try: | 2529 | try: |
| 2436 | profile = request.user.get_profile() | 2530 | profile = request.user.get_profile() |
| @@ -2445,26 +2539,26 @@ if request.user.is_authenticated(): | |||
| 2445 | profile.views += 1 | 2539 | profile.views += 1 |
| 2446 | profile.save() | 2540 | profile.save() |
| 2447 | " | 2541 | " |
| 2448 | (python-tests-look-at "try:") | 2542 | (python-tests-look-at "try:") |
| 2449 | (should (not (python-info-closing-block))) | 2543 | (should (not (python-info-dedenter-opening-block-position))) |
| 2450 | (python-tests-look-at "except Profile.DoesNotExist:") | 2544 | (python-tests-look-at "except Profile.DoesNotExist:") |
| 2451 | (should (= (python-tests-look-at "try:" -1 t) | 2545 | (should (= (python-tests-look-at "try:" -1 t) |
| 2452 | (python-info-closing-block))) | 2546 | (python-info-dedenter-opening-block-position))) |
| 2453 | (python-tests-look-at "else:") | 2547 | (python-tests-look-at "else:") |
| 2454 | (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t) | 2548 | (should (= (python-tests-look-at "except Profile.DoesNotExist:" -1 t) |
| 2455 | (python-info-closing-block))) | 2549 | (python-info-dedenter-opening-block-position))) |
| 2456 | (python-tests-look-at "if profile.stats:") | 2550 | (python-tests-look-at "if profile.stats:") |
| 2457 | (should (not (python-info-closing-block))) | 2551 | (should (not (python-info-dedenter-opening-block-position))) |
| 2458 | (python-tests-look-at "else:") | 2552 | (python-tests-look-at "else:") |
| 2459 | (should (= (python-tests-look-at "if profile.stats:" -1 t) | 2553 | (should (= (python-tests-look-at "if profile.stats:" -1 t) |
| 2460 | (python-info-closing-block))) | 2554 | (python-info-dedenter-opening-block-position))) |
| 2461 | (python-tests-look-at "finally:") | 2555 | (python-tests-look-at "finally:") |
| 2462 | (should (= (python-tests-look-at "else:" -2 t) | 2556 | (should (= (python-tests-look-at "else:" -2 t) |
| 2463 | (python-info-closing-block))))) | 2557 | (python-info-dedenter-opening-block-position))))) |
| 2464 | 2558 | ||
| 2465 | (ert-deftest python-info-closing-block-2 () | 2559 | (ert-deftest python-info-dedenter-opening-block-position-2 () |
| 2466 | (python-tests-with-temp-buffer | 2560 | (python-tests-with-temp-buffer |
| 2467 | " | 2561 | " |
| 2468 | if request.user.is_authenticated(): | 2562 | if request.user.is_authenticated(): |
| 2469 | profile = Profile.objects.get_or_create(user=request.user) | 2563 | profile = Profile.objects.get_or_create(user=request.user) |
| 2470 | if profile.stats: | 2564 | if profile.stats: |
| @@ -2475,10 +2569,440 @@ data = { | |||
| 2475 | } | 2569 | } |
| 2476 | 'else' | 2570 | 'else' |
| 2477 | " | 2571 | " |
| 2478 | (python-tests-look-at "'else': 'do it'") | 2572 | (python-tests-look-at "'else': 'do it'") |
| 2479 | (should (not (python-info-closing-block))) | 2573 | (should (not (python-info-dedenter-opening-block-position))) |
| 2480 | (python-tests-look-at "'else'") | 2574 | (python-tests-look-at "'else'") |
| 2481 | (should (not (python-info-closing-block))))) | 2575 | (should (not (python-info-dedenter-opening-block-position))))) |
| 2576 | |||
| 2577 | (ert-deftest python-info-dedenter-opening-block-position-3 () | ||
| 2578 | (python-tests-with-temp-buffer | ||
| 2579 | " | ||
| 2580 | if save: | ||
| 2581 | try: | ||
| 2582 | write_to_disk(data) | ||
| 2583 | except IOError: | ||
| 2584 | msg = 'Error saving to disk' | ||
| 2585 | message(msg) | ||
| 2586 | logger.exception(msg) | ||
| 2587 | except Exception: | ||
| 2588 | if hide_details: | ||
| 2589 | logger.exception('Unhandled exception') | ||
| 2590 | else | ||
| 2591 | finally: | ||
| 2592 | data.free() | ||
| 2593 | " | ||
| 2594 | (python-tests-look-at "try:") | ||
| 2595 | (should (not (python-info-dedenter-opening-block-position))) | ||
| 2596 | |||
| 2597 | (python-tests-look-at "except IOError:") | ||
| 2598 | (should (= (python-tests-look-at "try:" -1 t) | ||
| 2599 | (python-info-dedenter-opening-block-position))) | ||
| 2600 | |||
| 2601 | (python-tests-look-at "except Exception:") | ||
| 2602 | (should (= (python-tests-look-at "except IOError:" -1 t) | ||
| 2603 | (python-info-dedenter-opening-block-position))) | ||
| 2604 | |||
| 2605 | (python-tests-look-at "if hide_details:") | ||
| 2606 | (should (not (python-info-dedenter-opening-block-position))) | ||
| 2607 | |||
| 2608 | ;; check indentation modifies the detected opening block | ||
| 2609 | (python-tests-look-at "else") | ||
| 2610 | (should (= (python-tests-look-at "if hide_details:" -1 t) | ||
| 2611 | (python-info-dedenter-opening-block-position))) | ||
| 2612 | |||
| 2613 | (indent-line-to 8) | ||
| 2614 | (should (= (python-tests-look-at "if hide_details:" -1 t) | ||
| 2615 | (python-info-dedenter-opening-block-position))) | ||
| 2616 | |||
| 2617 | (indent-line-to 4) | ||
| 2618 | (should (= (python-tests-look-at "except Exception:" -1 t) | ||
| 2619 | (python-info-dedenter-opening-block-position))) | ||
| 2620 | |||
| 2621 | (indent-line-to 0) | ||
| 2622 | (should (= (python-tests-look-at "if save:" -1 t) | ||
| 2623 | (python-info-dedenter-opening-block-position))))) | ||
| 2624 | |||
| 2625 | (ert-deftest python-info-dedenter-opening-block-positions-1 () | ||
| 2626 | (python-tests-with-temp-buffer | ||
| 2627 | " | ||
| 2628 | if save: | ||
| 2629 | try: | ||
| 2630 | write_to_disk(data) | ||
| 2631 | except IOError: | ||
| 2632 | msg = 'Error saving to disk' | ||
| 2633 | message(msg) | ||
| 2634 | logger.exception(msg) | ||
| 2635 | except Exception: | ||
| 2636 | if hide_details: | ||
| 2637 | logger.exception('Unhandled exception') | ||
| 2638 | else | ||
| 2639 | finally: | ||
| 2640 | data.free() | ||
| 2641 | " | ||
| 2642 | (python-tests-look-at "try:") | ||
| 2643 | (should (not (python-info-dedenter-opening-block-positions))) | ||
| 2644 | |||
| 2645 | (python-tests-look-at "except IOError:") | ||
| 2646 | (should | ||
| 2647 | (equal (list | ||
| 2648 | (python-tests-look-at "try:" -1 t)) | ||
| 2649 | (python-info-dedenter-opening-block-positions))) | ||
| 2650 | |||
| 2651 | (python-tests-look-at "except Exception:") | ||
| 2652 | (should | ||
| 2653 | (equal (list | ||
| 2654 | (python-tests-look-at "except IOError:" -1 t)) | ||
| 2655 | (python-info-dedenter-opening-block-positions))) | ||
| 2656 | |||
| 2657 | (python-tests-look-at "if hide_details:") | ||
| 2658 | (should (not (python-info-dedenter-opening-block-positions))) | ||
| 2659 | |||
| 2660 | ;; check indentation does not modify the detected opening blocks | ||
| 2661 | (python-tests-look-at "else") | ||
| 2662 | (should | ||
| 2663 | (equal (list | ||
| 2664 | (python-tests-look-at "if hide_details:" -1 t) | ||
| 2665 | (python-tests-look-at "except Exception:" -1 t) | ||
| 2666 | (python-tests-look-at "if save:" -1 t)) | ||
| 2667 | (python-info-dedenter-opening-block-positions))) | ||
| 2668 | |||
| 2669 | (indent-line-to 8) | ||
| 2670 | (should | ||
| 2671 | (equal (list | ||
| 2672 | (python-tests-look-at "if hide_details:" -1 t) | ||
| 2673 | (python-tests-look-at "except Exception:" -1 t) | ||
| 2674 | (python-tests-look-at "if save:" -1 t)) | ||
| 2675 | (python-info-dedenter-opening-block-positions))) | ||
| 2676 | |||
| 2677 | (indent-line-to 4) | ||
| 2678 | (should | ||
| 2679 | (equal (list | ||
| 2680 | (python-tests-look-at "if hide_details:" -1 t) | ||
| 2681 | (python-tests-look-at "except Exception:" -1 t) | ||
| 2682 | (python-tests-look-at "if save:" -1 t)) | ||
| 2683 | (python-info-dedenter-opening-block-positions))) | ||
| 2684 | |||
| 2685 | (indent-line-to 0) | ||
| 2686 | (should | ||
| 2687 | (equal (list | ||
| 2688 | (python-tests-look-at "if hide_details:" -1 t) | ||
| 2689 | (python-tests-look-at "except Exception:" -1 t) | ||
| 2690 | (python-tests-look-at "if save:" -1 t)) | ||
| 2691 | (python-info-dedenter-opening-block-positions))))) | ||
| 2692 | |||
| 2693 | (ert-deftest python-info-dedenter-opening-block-positions-2 () | ||
| 2694 | "Test detection of opening blocks for elif." | ||
| 2695 | (python-tests-with-temp-buffer | ||
| 2696 | " | ||
| 2697 | if var: | ||
| 2698 | if var2: | ||
| 2699 | something() | ||
| 2700 | elif var3: | ||
| 2701 | something_else() | ||
| 2702 | elif | ||
| 2703 | " | ||
| 2704 | (python-tests-look-at "elif var3:") | ||
| 2705 | (should | ||
| 2706 | (equal (list | ||
| 2707 | (python-tests-look-at "if var2:" -1 t) | ||
| 2708 | (python-tests-look-at "if var:" -1 t)) | ||
| 2709 | (python-info-dedenter-opening-block-positions))) | ||
| 2710 | |||
| 2711 | (python-tests-look-at "elif\n") | ||
| 2712 | (should | ||
| 2713 | (equal (list | ||
| 2714 | (python-tests-look-at "elif var3:" -1 t) | ||
| 2715 | (python-tests-look-at "if var:" -1 t)) | ||
| 2716 | (python-info-dedenter-opening-block-positions))))) | ||
| 2717 | |||
| 2718 | (ert-deftest python-info-dedenter-opening-block-positions-3 () | ||
| 2719 | "Test detection of opening blocks for else." | ||
| 2720 | (python-tests-with-temp-buffer | ||
| 2721 | " | ||
| 2722 | try: | ||
| 2723 | something() | ||
| 2724 | except: | ||
| 2725 | if var: | ||
| 2726 | if var2: | ||
| 2727 | something() | ||
| 2728 | elif var3: | ||
| 2729 | something_else() | ||
| 2730 | else | ||
| 2731 | |||
| 2732 | if var4: | ||
| 2733 | while var5: | ||
| 2734 | var4.pop() | ||
| 2735 | else | ||
| 2736 | |||
| 2737 | for value in var6: | ||
| 2738 | if value > 0: | ||
| 2739 | print value | ||
| 2740 | else | ||
| 2741 | " | ||
| 2742 | (python-tests-look-at "else\n") | ||
| 2743 | (should | ||
| 2744 | (equal (list | ||
| 2745 | (python-tests-look-at "elif var3:" -1 t) | ||
| 2746 | (python-tests-look-at "if var:" -1 t) | ||
| 2747 | (python-tests-look-at "except:" -1 t)) | ||
| 2748 | (python-info-dedenter-opening-block-positions))) | ||
| 2749 | |||
| 2750 | (python-tests-look-at "else\n") | ||
| 2751 | (should | ||
| 2752 | (equal (list | ||
| 2753 | (python-tests-look-at "while var5:" -1 t) | ||
| 2754 | (python-tests-look-at "if var4:" -1 t)) | ||
| 2755 | (python-info-dedenter-opening-block-positions))) | ||
| 2756 | |||
| 2757 | (python-tests-look-at "else\n") | ||
| 2758 | (should | ||
| 2759 | (equal (list | ||
| 2760 | (python-tests-look-at "if value > 0:" -1 t) | ||
| 2761 | (python-tests-look-at "for value in var6:" -1 t) | ||
| 2762 | (python-tests-look-at "if var4:" -1 t)) | ||
| 2763 | (python-info-dedenter-opening-block-positions))))) | ||
| 2764 | |||
| 2765 | (ert-deftest python-info-dedenter-opening-block-positions-4 () | ||
| 2766 | "Test detection of opening blocks for except." | ||
| 2767 | (python-tests-with-temp-buffer | ||
| 2768 | " | ||
| 2769 | try: | ||
| 2770 | something() | ||
| 2771 | except ValueError: | ||
| 2772 | something_else() | ||
| 2773 | except | ||
| 2774 | " | ||
| 2775 | (python-tests-look-at "except ValueError:") | ||
| 2776 | (should | ||
| 2777 | (equal (list (python-tests-look-at "try:" -1 t)) | ||
| 2778 | (python-info-dedenter-opening-block-positions))) | ||
| 2779 | |||
| 2780 | (python-tests-look-at "except\n") | ||
| 2781 | (should | ||
| 2782 | (equal (list (python-tests-look-at "except ValueError:" -1 t)) | ||
| 2783 | (python-info-dedenter-opening-block-positions))))) | ||
| 2784 | |||
| 2785 | (ert-deftest python-info-dedenter-opening-block-positions-5 () | ||
| 2786 | "Test detection of opening blocks for finally." | ||
| 2787 | (python-tests-with-temp-buffer | ||
| 2788 | " | ||
| 2789 | try: | ||
| 2790 | something() | ||
| 2791 | finally | ||
| 2792 | |||
| 2793 | try: | ||
| 2794 | something_else() | ||
| 2795 | except: | ||
| 2796 | logger.exception('something went wrong') | ||
| 2797 | finally | ||
| 2798 | |||
| 2799 | try: | ||
| 2800 | something_else_else() | ||
| 2801 | except Exception: | ||
| 2802 | logger.exception('something else went wrong') | ||
| 2803 | else: | ||
| 2804 | print ('all good') | ||
| 2805 | finally | ||
| 2806 | " | ||
| 2807 | (python-tests-look-at "finally\n") | ||
| 2808 | (should | ||
| 2809 | (equal (list (python-tests-look-at "try:" -1 t)) | ||
| 2810 | (python-info-dedenter-opening-block-positions))) | ||
| 2811 | |||
| 2812 | (python-tests-look-at "finally\n") | ||
| 2813 | (should | ||
| 2814 | (equal (list (python-tests-look-at "except:" -1 t)) | ||
| 2815 | (python-info-dedenter-opening-block-positions))) | ||
| 2816 | |||
| 2817 | (python-tests-look-at "finally\n") | ||
| 2818 | (should | ||
| 2819 | (equal (list (python-tests-look-at "else:" -1 t)) | ||
| 2820 | (python-info-dedenter-opening-block-positions))))) | ||
| 2821 | |||
| 2822 | (ert-deftest python-info-dedenter-opening-block-message-1 () | ||
| 2823 | "Test dedenters inside strings are ignored." | ||
| 2824 | (python-tests-with-temp-buffer | ||
| 2825 | "''' | ||
| 2826 | try: | ||
| 2827 | something() | ||
| 2828 | except: | ||
| 2829 | logger.exception('something went wrong') | ||
| 2830 | ''' | ||
| 2831 | " | ||
| 2832 | (python-tests-look-at "except\n") | ||
| 2833 | (should (not (python-info-dedenter-opening-block-message))))) | ||
| 2834 | |||
| 2835 | (ert-deftest python-info-dedenter-opening-block-message-2 () | ||
| 2836 | "Test except keyword." | ||
| 2837 | (python-tests-with-temp-buffer | ||
| 2838 | " | ||
| 2839 | try: | ||
| 2840 | something() | ||
| 2841 | except: | ||
| 2842 | logger.exception('something went wrong') | ||
| 2843 | " | ||
| 2844 | (python-tests-look-at "except:") | ||
| 2845 | (should (string= | ||
| 2846 | "Closes try:" | ||
| 2847 | (substring-no-properties | ||
| 2848 | (python-info-dedenter-opening-block-message)))) | ||
| 2849 | (end-of-line) | ||
| 2850 | (should (string= | ||
| 2851 | "Closes try:" | ||
| 2852 | (substring-no-properties | ||
| 2853 | (python-info-dedenter-opening-block-message)))))) | ||
| 2854 | |||
| 2855 | (ert-deftest python-info-dedenter-opening-block-message-3 () | ||
| 2856 | "Test else keyword." | ||
| 2857 | (python-tests-with-temp-buffer | ||
| 2858 | " | ||
| 2859 | try: | ||
| 2860 | something() | ||
| 2861 | except: | ||
| 2862 | logger.exception('something went wrong') | ||
| 2863 | else: | ||
| 2864 | logger.debug('all good') | ||
| 2865 | " | ||
| 2866 | (python-tests-look-at "else:") | ||
| 2867 | (should (string= | ||
| 2868 | "Closes except:" | ||
| 2869 | (substring-no-properties | ||
| 2870 | (python-info-dedenter-opening-block-message)))) | ||
| 2871 | (end-of-line) | ||
| 2872 | (should (string= | ||
| 2873 | "Closes except:" | ||
| 2874 | (substring-no-properties | ||
| 2875 | (python-info-dedenter-opening-block-message)))))) | ||
| 2876 | |||
| 2877 | (ert-deftest python-info-dedenter-opening-block-message-4 () | ||
| 2878 | "Test finally keyword." | ||
| 2879 | (python-tests-with-temp-buffer | ||
| 2880 | " | ||
| 2881 | try: | ||
| 2882 | something() | ||
| 2883 | except: | ||
| 2884 | logger.exception('something went wrong') | ||
| 2885 | else: | ||
| 2886 | logger.debug('all good') | ||
| 2887 | finally: | ||
| 2888 | clean() | ||
| 2889 | " | ||
| 2890 | (python-tests-look-at "finally:") | ||
| 2891 | (should (string= | ||
| 2892 | "Closes else:" | ||
| 2893 | (substring-no-properties | ||
| 2894 | (python-info-dedenter-opening-block-message)))) | ||
| 2895 | (end-of-line) | ||
| 2896 | (should (string= | ||
| 2897 | "Closes else:" | ||
| 2898 | (substring-no-properties | ||
| 2899 | (python-info-dedenter-opening-block-message)))))) | ||
| 2900 | |||
| 2901 | (ert-deftest python-info-dedenter-opening-block-message-5 () | ||
| 2902 | "Test elif keyword." | ||
| 2903 | (python-tests-with-temp-buffer | ||
| 2904 | " | ||
| 2905 | if a: | ||
| 2906 | something() | ||
| 2907 | elif b: | ||
| 2908 | " | ||
| 2909 | (python-tests-look-at "elif b:") | ||
| 2910 | (should (string= | ||
| 2911 | "Closes if a:" | ||
| 2912 | (substring-no-properties | ||
| 2913 | (python-info-dedenter-opening-block-message)))) | ||
| 2914 | (end-of-line) | ||
| 2915 | (should (string= | ||
| 2916 | "Closes if a:" | ||
| 2917 | (substring-no-properties | ||
| 2918 | (python-info-dedenter-opening-block-message)))))) | ||
| 2919 | |||
| 2920 | |||
| 2921 | (ert-deftest python-info-dedenter-statement-p-1 () | ||
| 2922 | "Test dedenters inside strings are ignored." | ||
| 2923 | (python-tests-with-temp-buffer | ||
| 2924 | "''' | ||
| 2925 | try: | ||
| 2926 | something() | ||
| 2927 | except: | ||
| 2928 | logger.exception('something went wrong') | ||
| 2929 | ''' | ||
| 2930 | " | ||
| 2931 | (python-tests-look-at "except\n") | ||
| 2932 | (should (not (python-info-dedenter-statement-p))))) | ||
| 2933 | |||
| 2934 | (ert-deftest python-info-dedenter-statement-p-2 () | ||
| 2935 | "Test except keyword." | ||
| 2936 | (python-tests-with-temp-buffer | ||
| 2937 | " | ||
| 2938 | try: | ||
| 2939 | something() | ||
| 2940 | except: | ||
| 2941 | logger.exception('something went wrong') | ||
| 2942 | " | ||
| 2943 | (python-tests-look-at "except:") | ||
| 2944 | (should (= (point) (python-info-dedenter-statement-p))) | ||
| 2945 | (end-of-line) | ||
| 2946 | (should (= (save-excursion | ||
| 2947 | (back-to-indentation) | ||
| 2948 | (point)) | ||
| 2949 | (python-info-dedenter-statement-p))))) | ||
| 2950 | |||
| 2951 | (ert-deftest python-info-dedenter-statement-p-3 () | ||
| 2952 | "Test else keyword." | ||
| 2953 | (python-tests-with-temp-buffer | ||
| 2954 | " | ||
| 2955 | try: | ||
| 2956 | something() | ||
| 2957 | except: | ||
| 2958 | logger.exception('something went wrong') | ||
| 2959 | else: | ||
| 2960 | logger.debug('all good') | ||
| 2961 | " | ||
| 2962 | (python-tests-look-at "else:") | ||
| 2963 | (should (= (point) (python-info-dedenter-statement-p))) | ||
| 2964 | (end-of-line) | ||
| 2965 | (should (= (save-excursion | ||
| 2966 | (back-to-indentation) | ||
| 2967 | (point)) | ||
| 2968 | (python-info-dedenter-statement-p))))) | ||
| 2969 | |||
| 2970 | (ert-deftest python-info-dedenter-statement-p-4 () | ||
| 2971 | "Test finally keyword." | ||
| 2972 | (python-tests-with-temp-buffer | ||
| 2973 | " | ||
| 2974 | try: | ||
| 2975 | something() | ||
| 2976 | except: | ||
| 2977 | logger.exception('something went wrong') | ||
| 2978 | else: | ||
| 2979 | logger.debug('all good') | ||
| 2980 | finally: | ||
| 2981 | clean() | ||
| 2982 | " | ||
| 2983 | (python-tests-look-at "finally:") | ||
| 2984 | (should (= (point) (python-info-dedenter-statement-p))) | ||
| 2985 | (end-of-line) | ||
| 2986 | (should (= (save-excursion | ||
| 2987 | (back-to-indentation) | ||
| 2988 | (point)) | ||
| 2989 | (python-info-dedenter-statement-p))))) | ||
| 2990 | |||
| 2991 | (ert-deftest python-info-dedenter-statement-p-5 () | ||
| 2992 | "Test elif keyword." | ||
| 2993 | (python-tests-with-temp-buffer | ||
| 2994 | " | ||
| 2995 | if a: | ||
| 2996 | something() | ||
| 2997 | elif b: | ||
| 2998 | " | ||
| 2999 | (python-tests-look-at "elif b:") | ||
| 3000 | (should (= (point) (python-info-dedenter-statement-p))) | ||
| 3001 | (end-of-line) | ||
| 3002 | (should (= (save-excursion | ||
| 3003 | (back-to-indentation) | ||
| 3004 | (point)) | ||
| 3005 | (python-info-dedenter-statement-p))))) | ||
| 2482 | 3006 | ||
| 2483 | (ert-deftest python-info-line-ends-backslash-p-1 () | 3007 | (ert-deftest python-info-line-ends-backslash-p-1 () |
| 2484 | (python-tests-with-temp-buffer | 3008 | (python-tests-with-temp-buffer |