emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r117560: Merge from emacs-24; up to r117395


From: Glenn Morris
Subject: [Emacs-diffs] trunk r117560: Merge from emacs-24; up to r117395
Date: Mon, 21 Jul 2014 06:03:47 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 117560 [merge]
revision-id: address@hidden
parent: address@hidden
parent: address@hidden
committer: Glenn Morris <address@hidden>
branch nick: trunk
timestamp: Mon 2014-07-21 02:03:08 -0400
message:
  Merge from emacs-24; up to r117395
modified:
  doc/emacs/ChangeLog            changelog-20091113204419-o5vbwnq5f7feedwu-6227
  doc/emacs/emacs.texi           emacs.texi-20091113204419-o5vbwnq5f7feedwu-6246
  etc/NEWS                       news-20100311060928-aoit31wvzf25yr1z-1
  lisp/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-1432
  lisp/bindings.el               
bindings.el-20091113204419-o5vbwnq5f7feedwu-1013
  lisp/bs.el                     bs.el-20091113204419-o5vbwnq5f7feedwu-1737
  lisp/buff-menu.el              buffmenu.el-20091113204419-o5vbwnq5f7feedwu-197
  lisp/dired.el                  dired.el-20091113204419-o5vbwnq5f7feedwu-482
  lisp/files.el                  files.el-20091113204419-o5vbwnq5f7feedwu-265
  lisp/progmodes/hideif.el       hideif.el-20091113204419-o5vbwnq5f7feedwu-39
  lisp/progmodes/python.el       python.el-20091113204419-o5vbwnq5f7feedwu-3008
  lisp/view.el                   view.el-20091113204419-o5vbwnq5f7feedwu-100
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/macfont.h                  macfont.h-20130915173740-04lgloz0557bz98l-1
  src/macfont.m                  macfont.m-20130915173740-04lgloz0557bz98l-2
  src/nsterm.h                   nsterm.h-20091113204419-o5vbwnq5f7feedwu-8746
  src/nsterm.m                   nsterm.m-20091113204419-o5vbwnq5f7feedwu-8747
  src/w16select.c                
w16select.c-20091113204419-o5vbwnq5f7feedwu-1103
  src/w32select.c                w32select.c-20091113204419-o5vbwnq5f7feedwu-949
  src/xdisp.c                    xdisp.c-20091113204419-o5vbwnq5f7feedwu-240
  test/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-8588
  test/automated/python-tests.el 
pythontests.el-20130220195218-kqcioz3fssz9hwe1-1
=== modified file 'doc/emacs/ChangeLog'
--- a/doc/emacs/ChangeLog       2014-07-09 02:04:12 +0000
+++ b/doc/emacs/ChangeLog       2014-07-21 06:03:08 +0000
@@ -1,3 +1,7 @@
+2014-07-21  Glenn Morris  <address@hidden>
+
+       * emacs.texi (Intro): Workaround makeinfo 4 @acronym bug.  (Bug#18040)
+
 2014-07-09  Juri Linkov  <address@hidden>
 
        * search.texi (Regexp Search): Update lax space matching that is

=== modified file 'doc/emacs/emacs.texi'
--- a/doc/emacs/emacs.texi      2014-06-10 02:20:31 +0000
+++ b/doc/emacs/emacs.texi      2014-07-21 06:03:08 +0000
@@ -1476,7 +1476,16 @@
 
   You are reading about GNU Emacs, the GNU incarnation of the
 advanced, self-documenting, customizable, extensible editor Emacs.
-(The @samp{G} in @acronym{GNU, @acronym{GNU}'s Not Unix} is not silent.)
+(The @samp{G} in
address@hidden Workaround makeinfo 4 bug.
address@hidden 
http://lists.gnu.org/archive/html/bug-texinfo/2004-08/msg00009.html
address@hidden
address@hidden, @acronym{GNU}'s Not Unix}
address@hidden iftex
address@hidden
address@hidden, GNU's Not Unix}
address@hidden ifnottex
+is not silent.)
 
   We call Emacs @dfn{advanced} because it can do much more than simple
 insertion and deletion of text.  It can control subprocesses, indent

=== modified file 'etc/NEWS'
--- a/etc/NEWS  2014-07-11 09:33:06 +0000
+++ b/etc/NEWS  2014-07-21 06:03:08 +0000
@@ -870,6 +870,22 @@
 ** In Prolog mode, `prolog-use-smie' has been removed,
 along with the non-SMIE indentation code.
 
+** Python mode
+
+*** Out of the box support for CPython, iPython and readline based shells.
+**** `python-shell-completion-module-string-code` is no longer used.
+
+*** Automatic shell prompt detection.  New user options:
+**** `python-shell-interpreter-interactive-arg'.
+**** `python-shell-prompt-detect-enabled'.
+**** `python-shell-prompt-detect-failure-warning'.
+**** `python-shell-prompt-input-regexps'.
+**** `python-shell-prompt-output-regexps'.
+
+*** Python shell support for remote hosts via tramp.
+
+*** Correct display of line numbers for code sent to the Python shell.
+
 ** Remember
 
 *** The new command `remember-notes' creates a buffer that is saved on exit.

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2014-07-21 01:58:43 +0000
+++ b/lisp/ChangeLog    2014-07-21 06:03:08 +0000
@@ -1,3 +1,67 @@
+2014-07-21  Glenn Morris  <address@hidden>
+
+       * progmodes/hideif.el (hide-ifdef-mode-submap):
+       Also substitute read-only-mode.
+       * bindings.el (mode-line-toggle-read-only):
+       * bs.el (bs-toggle-readonly):
+       * buff-menu.el (Buffer-menu-toggle-read-only):
+       * dired.el (dired-toggle-read-only):
+       * files.el (view-read-only, find-file-read-only)
+       (find-file-read-only-other-window)
+       (find-file-read-only-other-frame):
+       * progmodes/hideif.el (hide-ifdef-toggle-outside-read-only):
+       Doc fixes re toggle-read-only.
+
+2014-07-21  Fabián Ezequiel Gallina  <address@hidden>
+
+       * progmodes/python.el: Add comment about pipe buffering and
+       solutions for missing/delayed output in inferior Python shells.
+       (Bug#17304)
+
+       * progmodes/python.el (python-mode): Don't set
+       mode-require-final-newline.  (Bug#17990)
+
+       Make python.el work with IPython automatically.  (Bug#15510)
+       * progmodes/python.el:
+       (python-shell-completion-setup-code): New value supporting iPython.
+       (python-shell-completion-string-code): New value supporting iPython.
+       (python-shell-completion-get-completions): Use them.
+       (python-shell-completion-module-string-code): Make obsolete.
+       (python-shell-prompt-input-regexps)
+       (python-shell-prompt-output-regexps): Add safeguard for ipdb.
+       (python-shell-output-filter): Fix comment typo.
+
+       Fix Python shell prompts detection for remote hosts.
+       * progmodes/python.el (python-shell-prompt-detect): Replace
+       call-process with process-file and make it more robust.
+
+       Autodetect Python shell prompts.  (Bug#17370)
+       * progmodes/python.el:
+       (python-shell-interpreter-interactive-arg)
+       (python-shell-prompt-detect-enabled)
+       (python-shell-prompt-detect-failure-warning)
+       (python-shell-prompt-input-regexps)
+       (python-shell-prompt-output-regexps): New vars.
+       (python-shell-prompt-calculated-input-regexp)
+       (python-shell-prompt-calculated-output-regexp): New vars.
+       (python-shell-get-process-name)
+       (python-shell-internal-get-process-name)
+       (python-shell-output-filter)
+       (python-shell-completion-get-completions): Use them.
+       (python-shell-prompt-detect)
+       (python-shell-prompt-validate-regexps): New functions.
+       (python-shell-prompt-set-calculated-regexps): New function.
+       (inferior-python-mode): Use it.  Also honor overriden
+       python-shell-interpreter and python-shell-interpreter-args.
+       (python-shell-make-comint): Honor overriden
+       python-shell-interpreter and python-shell-interpreter-args.
+       (python-shell-get-or-create-process): Make it testable by allowing
+       to call run-python non-interactively.
+       (python-util-valid-regexp-p): New function.
+       (python-shell-prompt-regexp, python-shell-prompt-block-regexp)
+       (python-shell-prompt-output-regexp)
+       (python-shell-prompt-pdb-regexp): Use it as defcustom :safe.
+
 2014-07-21  Stefan Monnier  <address@hidden>
 
        * emacs-lisp/smie.el (smie-config--guess-1): Split from

=== modified file 'lisp/bindings.el'
--- a/lisp/bindings.el  2014-07-13 14:49:59 +0000
+++ b/lisp/bindings.el  2014-07-21 05:38:17 +0000
@@ -36,7 +36,7 @@
 
 
 (defun mode-line-toggle-read-only (event)
-  "Like `toggle-read-only', for the mode-line."
+  "Like toggling `read-only-mode', for the mode-line."
   (interactive "e")
   (with-selected-window (posn-window (event-start event))
     (read-only-mode 'toggle)))

=== modified file 'lisp/bs.el'
--- a/lisp/bs.el        2014-05-29 03:45:29 +0000
+++ b/lisp/bs.el        2014-07-21 06:03:08 +0000
@@ -954,7 +954,7 @@
 
 (defun bs-toggle-readonly ()
   "Toggle read-only status for buffer on current line.
-Uses function `toggle-read-only'."
+Uses function `read-only-mode'."
   (interactive)
   (with-current-buffer (bs--current-buffer)
     (read-only-mode 'toggle))

=== modified file 'lisp/buff-menu.el'
--- a/lisp/buff-menu.el 2014-02-10 01:34:22 +0000
+++ b/lisp/buff-menu.el 2014-07-21 05:38:17 +0000
@@ -539,7 +539,7 @@
 
 (defun Buffer-menu-toggle-read-only ()
   "Toggle read-only status of buffer on this line.
-This behaves like invoking \\[toggle-read-only] in that buffer."
+This behaves like invoking \\[read-only-mode] in that buffer."
   (interactive)
   (let ((read-only
          (with-current-buffer (Buffer-menu-buffer t)

=== modified file 'lisp/dired.el'
--- a/lisp/dired.el     2014-07-08 08:02:50 +0000
+++ b/lisp/dired.el     2014-07-21 06:03:08 +0000
@@ -2015,7 +2015,7 @@
   "Edit Dired buffer with Wdired, or make it read-only.
 If the current buffer can be edited with Wdired, (i.e. the major
 mode is `dired-mode'), call `wdired-change-to-wdired-mode'.
-Otherwise, call `toggle-read-only'."
+Otherwise, toggle `read-only-mode'."
   (interactive)
   (if (derived-mode-p 'dired-mode)
       (wdired-change-to-wdired-mode)

=== modified file 'lisp/files.el'
--- a/lisp/files.el     2014-07-11 12:19:58 +0000
+++ b/lisp/files.el     2014-07-21 06:03:08 +0000
@@ -564,7 +564,7 @@
 In fact, this means that all read-only buffers normally have
 View mode enabled, including buffers that are read-only because
 you visit a file you cannot alter, and buffers you make read-only
-using \\[toggle-read-only]."
+using \\[read-only-mode]."
   :type 'boolean
   :group 'view)
 
@@ -1502,7 +1502,7 @@
 (defun find-file-read-only (filename &optional wildcards)
   "Edit file FILENAME but don't allow changes.
 Like \\[find-file], but marks buffer as read-only.
-Use \\[toggle-read-only] to permit editing."
+Use \\[read-only-mode] to permit editing."
   (interactive
    (find-file-read-args "Find file read-only: "
                         (confirm-nonexistent-file-or-buffer)))
@@ -1511,7 +1511,7 @@
 (defun find-file-read-only-other-window (filename &optional wildcards)
   "Edit file FILENAME in another window but don't allow changes.
 Like \\[find-file-other-window], but marks buffer as read-only.
-Use \\[toggle-read-only] to permit editing."
+Use \\[read-only-mode] to permit editing."
   (interactive
    (find-file-read-args "Find file read-only other window: "
                         (confirm-nonexistent-file-or-buffer)))
@@ -1520,7 +1520,7 @@
 (defun find-file-read-only-other-frame (filename &optional wildcards)
   "Edit file FILENAME in another frame but don't allow changes.
 Like \\[find-file-other-frame], but marks buffer as read-only.
-Use \\[toggle-read-only] to permit editing."
+Use \\[read-only-mode] to permit editing."
   (interactive
    (find-file-read-args "Find file read-only other frame: "
                         (confirm-nonexistent-file-or-buffer)))

=== modified file 'lisp/progmodes/hideif.el'
--- a/lisp/progmodes/hideif.el  2014-07-07 08:59:32 +0000
+++ b/lisp/progmodes/hideif.el  2014-07-21 06:03:08 +0000
@@ -189,6 +189,9 @@
     (define-key map "\C-q" 'hide-ifdef-toggle-read-only)
     (define-key map "\C-w" 'hide-ifdef-toggle-shadowing)
     (substitute-key-definition
+     'read-only-mode 'hide-ifdef-toggle-outside-read-only map)
+    ;; `toggle-read-only' is obsoleted by `read-only-mode'.
+    (substitute-key-definition
      'toggle-read-only 'hide-ifdef-toggle-outside-read-only map)
     map)
   "Keymap used by `hide-ifdef-mode' under `hide-ifdef-mode-prefix-key'.")
@@ -1789,7 +1792,7 @@
   (force-mode-line-update))
 
 (defun hide-ifdef-toggle-outside-read-only ()
-  "Replacement for `toggle-read-only' within Hide-Ifdef mode."
+  "Replacement for `read-only-mode' within Hide-Ifdef mode."
   (interactive)
   (setq hif-outside-read-only (not hif-outside-read-only))
   (message "Read only %s"

=== modified file 'lisp/progmodes/python.el'
--- a/lisp/progmodes/python.el  2014-07-12 17:53:29 +0000
+++ b/lisp/progmodes/python.el  2014-07-21 06:03:08 +0000
@@ -4,7 +4,7 @@
 
 ;; Author: Fabián E. Gallina <address@hidden>
 ;; URL: https://github.com/fgallina/python.el
-;; Version: 0.24.2
+;; Version: 0.24.4
 ;; Maintainer: address@hidden
 ;; Created: Jul 2010
 ;; Keywords: languages
@@ -62,57 +62,80 @@
 ;; (add-hook 'python-mode-hook
 ;;           (lambda () (setq forward-sexp-function nil)))
 
-;; Shell interaction: is provided and allows you to execute easily any
-;; block of code of your current buffer in an inferior Python process.
+;; Shell interaction: is provided and allows opening Python shells
+;; inside Emacs and executing any block of code of your current buffer
+;; in that inferior Python process.
+
+;; Besides that only the standard CPython (2.x and 3.x) shell and
+;; IPython are officially supported out of the box, the interaction
+;; should support any other readline based Python shells as well
+;; (e.g. Jython and Pypy have been reported to work).  You can change
+;; your default interpreter and commandline arguments by setting the
+;; `python-shell-interpreter' and `python-shell-interpreter-args'
+;; variables.  This example enables IPython globally:
+
+;; (setq python-shell-interpreter "ipython"
+;;       python-shell-interpreter-args "-i")
+
+;; Using the "console" subcommand to start IPython in server-client
+;; mode is known to fail intermittently due a bug on IPython itself
+;; (see URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18052#27').
+;; There seems to be a race condition in the IPython server (A.K.A
+;; kernel) when code is sent while it is still initializing, sometimes
+;; causing the shell to get stalled.  With that said, if an IPython
+;; kernel is already running, "console --existing" seems to work fine.
+
+;; Running IPython on Windows needs more tweaking.  The way you should
+;; set `python-shell-interpreter' and `python-shell-interpreter-args'
+;; is as follows (of course you need to modify the paths according to
+;; your system):
+
+;; (setq python-shell-interpreter "C:\\Python27\\python.exe"
+;;       python-shell-interpreter-args
+;;       "-i C:\\Python27\\Scripts\\ipython-script.py")
+
+;; If you are experiencing missing or delayed output in your shells,
+;; that's likely caused by your Operating System's pipe buffering
+;; (e.g. this is known to happen running CPython 3.3.4 in Windows 7.
+;; See URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17304').  To
+;; fix this, using CPython's "-u" commandline argument or setting the
+;; "PYTHONUNBUFFERED" environment variable should help: See URL
+;; `https://docs.python.org/3/using/cmdline.html#cmdoption-u'.
+
+;; The interaction relies upon having prompts for input (e.g. ">>> "
+;; and "... " in standard Python shell) and output (e.g. "Out[1]: " in
+;; IPython) detected properly.  Failing that Emacs may hang but, in
+;; the case that happens, you can recover with \\[keyboard-quit].  To
+;; avoid this issue, a two-step prompt autodetection mechanism is
+;; provided: the first step is manual and consists of a collection of
+;; regular expressions matching common prompts for Python shells
+;; stored in `python-shell-prompt-input-regexps' and
+;; `python-shell-prompt-output-regexps', and dir-local friendly vars
+;; `python-shell-prompt-regexp', `python-shell-prompt-block-regexp',
+;; `python-shell-prompt-output-regexp' which are appended to the
+;; former automatically when a shell spawns; the second step is
+;; automatic and depends on the `python-shell-prompt-detect' helper
+;; function.  See its docstring for details on global variables that
+;; modify its behavior.
 
 ;; Shell completion: hitting tab will try to complete the current
-;; word.  Shell completion is implemented in a manner that if you
-;; change the `python-shell-interpreter' to any other (for example
-;; IPython) it should be easy to integrate another way to calculate
-;; completions.  You just need to specify your custom
-;; `python-shell-completion-setup-code' and
-;; `python-shell-completion-string-code'.
-
-;; Here is a complete example of the settings you would use for
-;; iPython 0.11:
-
-;; (setq
-;;  python-shell-interpreter "ipython"
-;;  python-shell-interpreter-args ""
-;;  python-shell-prompt-regexp "In \\[[0-9]+\\]: "
-;;  python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
-;;  python-shell-completion-setup-code
-;;    "from IPython.core.completerlib import module_completion"
-;;  python-shell-completion-module-string-code
-;;    "';'.join(module_completion('''%s'''))\n"
-;;  python-shell-completion-string-code
-;;    "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
-
-;; For iPython 0.10 everything would be the same except for
-;; `python-shell-completion-string-code' and
-;; `python-shell-completion-module-string-code':
-
-;; (setq python-shell-completion-string-code
-;;       "';'.join(__IP.complete('''%s'''))\n"
-;;       python-shell-completion-module-string-code "")
-
-;; Unfortunately running iPython on Windows needs some more tweaking.
-;; The way you must set `python-shell-interpreter' and
-;; `python-shell-interpreter-args' is as follows:
-
-;; (setq
-;;  python-shell-interpreter "C:\\Python27\\python.exe"
-;;  python-shell-interpreter-args
-;;  "-i C:\\Python27\\Scripts\\ipython-script.py")
-
-;; That will spawn the iPython process correctly (Of course you need
-;; to modify the paths according to your system).
-
-;; Please note that the default completion system depends on the
+;; word.  Shell completion is implemented in such way that if you
+;; change the `python-shell-interpreter' it should be possible to
+;; integrate custom logic to calculate completions.  To achieve this
+;; you just need to set `python-shell-completion-setup-code' and
+;; `python-shell-completion-string-code'.  The default provided code,
+;; enables autocompletion for both CPython and IPython (and ideally
+;; any readline based Python shell).  This code depends on the
 ;; readline module, so if you are using some Operating System that
-;; bundles Python without it (like Windows) just install the
-;; pyreadline from http://ipython.scipy.org/moin/PyReadline/Intro and
-;; you should be good to go.
+;; bundles Python without it (like Windows), installing pyreadline
+;; from URL `http://ipython.scipy.org/moin/PyReadline/Intro' should
+;; suffice.  To troubleshoot why you are not getting any completions
+;; you can try the following in your Python shell:
+
+;; >>> import readline, rlcompleter
+
+;; If you see an error, then you need to either install pyreadline or
+;; setup custom code that avoids that dependency.
 
 ;; Shell virtualenv support: The shell also contains support for
 ;; virtualenvs and other special environment modifications thanks to
@@ -211,7 +234,9 @@
 ;;; Code:
 
 (require 'ansi-color)
+(require 'cl-lib)
 (require 'comint)
+(require 'json)
 
 ;; Avoid compiler warnings
 (defvar view-return-to-alist)
@@ -1705,33 +1730,60 @@
   :type 'string
   :group 'python)
 
+(defcustom python-shell-interpreter-interactive-arg "-i"
+  "Interpreter argument to force it to run interactively."
+  :type 'string
+  :version "24.4")
+
+(defcustom python-shell-prompt-detect-enabled t
+  "Non-nil enables autodetection of interpreter prompts."
+  :type 'boolean
+  :safe 'booleanp
+  :version "24.4")
+
+(defcustom python-shell-prompt-detect-failure-warning t
+  "Non-nil enables warnings when detection of prompts fail."
+  :type 'boolean
+  :safe 'booleanp
+  :version "24.4")
+
+(defcustom python-shell-prompt-input-regexps
+  '(">>> " "\\.\\.\\. "                 ; Python
+    "In \\[[0-9]+\\]: "                 ; IPython
+    ;; Using ipdb outside IPython may fail to cleanup and leave static
+    ;; IPython prompts activated, this adds some safeguard for that.
+    "In : " "\\.\\.\\.: ")
+  "List of regular expressions matching input prompts."
+  :type '(repeat string)
+  :version "24.4")
+
+(defcustom python-shell-prompt-output-regexps
+  '(""                                  ; Python
+    "Out\\[[0-9]+\\]: "                 ; IPython
+    "Out :")                            ; ipdb safeguard
+  "List of regular expressions matching output prompts."
+  :type '(repeat string)
+  :version "24.4")
+
 (defcustom python-shell-prompt-regexp ">>> "
-  "Regular expression matching top-level input prompt of Python shell.
+  "Regular expression matching top level input prompt of Python shell.
 It should not contain a caret (^) at the beginning."
-  :type 'string
-  :group 'python
-  :safe 'stringp)
+  :type 'string)
 
-(defcustom python-shell-prompt-block-regexp "[.][.][.] "
+(defcustom python-shell-prompt-block-regexp "\\.\\.\\. "
   "Regular expression matching block input prompt of Python shell.
 It should not contain a caret (^) at the beginning."
-  :type 'string
-  :group 'python
-  :safe 'stringp)
+  :type 'string)
 
 (defcustom python-shell-prompt-output-regexp ""
   "Regular expression matching output prompt of Python shell.
 It should not contain a caret (^) at the beginning."
-  :type 'string
-  :group 'python
-  :safe 'stringp)
+  :type 'string)
 
 (defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
   "Regular expression matching pdb input prompt of Python shell.
 It should not contain a caret (^) at the beginning."
-  :type 'string
-  :group 'python
-  :safe 'stringp)
+  :type 'string)
 
 (defcustom python-shell-enable-font-lock t
   "Should syntax highlighting be enabled in the Python shell buffer?
@@ -1801,6 +1853,167 @@
   :type '(alist string)
   :group 'python)
 
+(defvar python-shell--prompt-calculated-input-regexp nil
+  "Calculated input prompt regexp for inferior python shell.
+Do not set this variable directly, instead use
+`python-shell-prompt-set-calculated-regexps'.")
+
+(defvar python-shell--prompt-calculated-output-regexp nil
+  "Calculated output prompt regexp for inferior python shell.
+Do not set this variable directly, instead use
+`python-shell-set-prompt-regexp'.")
+
+(defun python-shell-prompt-detect ()
+  "Detect prompts for the current `python-shell-interpreter'.
+When prompts can be retrieved successfully from the
+`python-shell-interpreter' run with
+`python-shell-interpreter-interactive-arg', returns a list of
+three elements, where the first two are input prompts and the
+last one is an output prompt.  When no prompts can be detected
+and `python-shell-prompt-detect-failure-warning' is non-nil,
+shows a warning with instructions to avoid hangs and returns nil.
+When `python-shell-prompt-detect-enabled' is nil avoids any
+detection and just returns nil."
+  (when python-shell-prompt-detect-enabled
+    (let* ((process-environment (python-shell-calculate-process-environment))
+           (exec-path (python-shell-calculate-exec-path))
+           (code (concat
+                  "import sys\n"
+                  "ps = [getattr(sys, 'ps%s' % i, '') for i in range(1,4)]\n"
+                  ;; JSON is built manually for compatibility
+                  "ps_json = '\\n[\"%s\", \"%s\", \"%s\"]\\n' % tuple(ps)\n"
+                  "print (ps_json)\n"
+                  "sys.exit(0)\n"))
+           (output
+            (with-temp-buffer
+              ;; TODO: improve error handling by using
+              ;; `condition-case' and displaying the error message to
+              ;; the user in the no-prompts warning.
+              (ignore-errors
+                (let ((code-file (python-shell--save-temp-file code)))
+                  ;; Use `process-file' as it is remote-host friendly.
+                  (process-file
+                   (executable-find python-shell-interpreter)
+                   code-file
+                   '(t nil)
+                   nil
+                   python-shell-interpreter-interactive-arg)
+                  ;; Try to cleanup
+                  (delete-file code-file)))
+              (buffer-string)))
+           (prompts
+            (catch 'prompts
+              (dolist (line (split-string output "\n" t))
+                (let ((res
+                       ;; Check if current line is a valid JSON array
+                       (and (string= (substring line 0 2) "[\"")
+                            (ignore-errors
+                              ;; Return prompts as a list, not vector
+                              (append (json-read-from-string line) nil)))))
+                  ;; The list must contain 3 strings, where the first
+                  ;; is the input prompt, the second is the block
+                  ;; prompt and the last one is the output prompt.  The
+                  ;; input prompt is the only one that can't be empty.
+                  (when (and (= (length res) 3)
+                             (cl-every #'stringp res)
+                             (not (string= (car res) "")))
+                    (throw 'prompts res))))
+              nil)))
+      (when (and (not prompts)
+                 python-shell-prompt-detect-failure-warning)
+        (warn
+         (concat
+          "Python shell prompts cannot be detected.\n"
+          "If your emacs session hangs when starting python shells\n"
+          "recover with `keyboard-quit' and then try fixing the\n"
+          "interactive flag for your interpreter by adjusting the\n"
+          "`python-shell-interpreter-interactive-arg' or add regexps\n"
+          "matching shell prompts in the directory-local friendly vars:\n"
+          "  + `python-shell-prompt-regexp'\n"
+          "  + `python-shell-prompt-block-regexp'\n"
+          "  + `python-shell-prompt-output-regexp'\n"
+          "Or alternatively in:\n"
+          "  + `python-shell-prompt-input-regexps'\n"
+          "  + `python-shell-prompt-output-regexps'")))
+      prompts)))
+
+(defun python-shell-prompt-validate-regexps ()
+  "Validate all user provided regexps for prompts.
+Signals `user-error' if any of these vars contain invalid
+regexps: `python-shell-prompt-regexp',
+`python-shell-prompt-block-regexp',
+`python-shell-prompt-pdb-regexp',
+`python-shell-prompt-output-regexp',
+`python-shell-prompt-input-regexps',
+`python-shell-prompt-output-regexps'."
+  (dolist (symbol (list 'python-shell-prompt-input-regexps
+                        'python-shell-prompt-output-regexps
+                        'python-shell-prompt-regexp
+                        'python-shell-prompt-block-regexp
+                        'python-shell-prompt-pdb-regexp
+                        'python-shell-prompt-output-regexp))
+    (dolist (regexp (let ((regexps (symbol-value symbol)))
+                      (if (listp regexps)
+                          regexps
+                        (list regexps))))
+      (when (not (python-util-valid-regexp-p regexp))
+        (user-error "Invalid regexp %s in `%s'"
+                    regexp symbol)))))
+
+(defun python-shell-prompt-set-calculated-regexps ()
+  "Detect and set input and output prompt regexps.
+Build and set the values for `python-shell-input-prompt-regexp'
+and `python-shell-output-prompt-regexp' using the values from
+`python-shell-prompt-regexp', `python-shell-prompt-block-regexp',
+`python-shell-prompt-pdb-regexp',
+`python-shell-prompt-output-regexp',
+`python-shell-prompt-input-regexps',
+`python-shell-prompt-output-regexps' and detected prompts from
+`python-shell-prompt-detect'."
+  (when (not (and python-shell--prompt-calculated-input-regexp
+                  python-shell--prompt-calculated-output-regexp))
+    (let* ((detected-prompts (python-shell-prompt-detect))
+           (input-prompts nil)
+           (output-prompts nil)
+           (build-regexp
+            (lambda (prompts)
+              (concat "^\\("
+                      (mapconcat #'identity
+                                 (sort prompts
+                                       (lambda (a b)
+                                         (let ((length-a (length a))
+                                               (length-b (length b)))
+                                           (if (= length-a length-b)
+                                               (string< a b)
+                                             (> (length a) (length b))))))
+                                 "\\|")
+                      "\\)"))))
+      ;; Validate ALL regexps
+      (python-shell-prompt-validate-regexps)
+      ;; Collect all user defined input prompts
+      (dolist (prompt (append python-shell-prompt-input-regexps
+                              (list python-shell-prompt-regexp
+                                    python-shell-prompt-block-regexp
+                                    python-shell-prompt-pdb-regexp)))
+        (cl-pushnew prompt input-prompts :test #'string=))
+      ;; Collect all user defined output prompts
+      (dolist (prompt (cons python-shell-prompt-output-regexp
+                            python-shell-prompt-output-regexps))
+        (cl-pushnew prompt output-prompts :test #'string=))
+      ;; Collect detected prompts if any
+      (when detected-prompts
+        (dolist (prompt (butlast detected-prompts))
+          (setq prompt (regexp-quote prompt))
+          (cl-pushnew prompt input-prompts :test #'string=))
+        (cl-pushnew (regexp-quote
+                     (car (last detected-prompts)))
+                    output-prompts :test #'string=))
+      ;; Set input and output prompt regexps from collected prompts
+      (setq python-shell--prompt-calculated-input-regexp
+            (funcall build-regexp input-prompts)
+            python-shell--prompt-calculated-output-regexp
+            (funcall build-regexp output-prompts)))))
+
 (defun python-shell-get-process-name (dedicated)
   "Calculate the appropriate process name for inferior Python process.
 If DEDICATED is t and the variable `buffer-file-name' is non-nil
@@ -1823,10 +2036,10 @@
           python-shell-internal-buffer-name
           (md5
            (concat
-            (python-shell-parse-command)
-            python-shell-prompt-regexp
-            python-shell-prompt-block-regexp
-            python-shell-prompt-output-regexp
+            python-shell-interpreter
+            python-shell-interpreter-args
+            python-shell--prompt-calculated-input-regexp
+            python-shell--prompt-calculated-output-regexp
             (mapconcat #'symbol-value python-shell-setup-codes "")
             (mapconcat #'identity python-shell-process-environment "")
             (mapconcat #'identity python-shell-extra-pythonpaths "")
@@ -1920,12 +2133,19 @@
 variable.
 
 \(Type \\[describe-mode] in the process buffer for a list of commands.)"
-  (and python-shell--parent-buffer
-       (python-util-clone-local-variables python-shell--parent-buffer))
-  (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
-                                     python-shell-prompt-regexp
-                                     python-shell-prompt-block-regexp
-                                     python-shell-prompt-pdb-regexp))
+  (let ((interpreter python-shell-interpreter)
+        (args python-shell-interpreter-args))
+    (when python-shell--parent-buffer
+      (python-util-clone-local-variables python-shell--parent-buffer))
+    ;; Users can override default values for these vars when calling
+    ;; `run-python'.  This ensures new values let-bound in
+    ;; `python-shell-make-comint' are locally set.
+    (set (make-local-variable 'python-shell-interpreter) interpreter)
+    (set (make-local-variable 'python-shell-interpreter-args) args))
+  (set (make-local-variable 'python-shell--prompt-calculated-input-regexp) nil)
+  (set (make-local-variable 'python-shell--prompt-calculated-output-regexp) 
nil)
+  (python-shell-prompt-set-calculated-regexps)
+  (setq comint-prompt-regexp python-shell--prompt-calculated-input-regexp)
   (setq mode-line-process '(":%s"))
   (make-local-variable 'comint-output-filter-functions)
   (add-hook 'comint-output-filter-functions
@@ -1988,10 +2208,20 @@
            (exec-path (python-shell-calculate-exec-path)))
       (when (not (comint-check-proc proc-buffer-name))
         (let* ((cmdlist (split-string-and-unquote cmd))
+               (interpreter (car cmdlist))
+               (args (cdr cmdlist))
                (buffer (apply #'make-comint-in-buffer proc-name 
proc-buffer-name
-                              (car cmdlist) nil (cdr cmdlist)))
+                              interpreter nil args))
                (python-shell--parent-buffer (current-buffer))
-               (process (get-buffer-process buffer)))
+               (process (get-buffer-process buffer))
+               ;; As the user may have overriden default values for
+               ;; these vars on `run-python', let-binding them allows
+               ;; to have the new right values in all setup code
+               ;; that's is done in `inferior-python-mode', which is
+               ;; important, especially for prompt detection.
+               (python-shell-interpreter interpreter)
+               (python-shell-interpreter-args
+                (mapconcat #'identity args " ")))
           (with-current-buffer buffer
             (inferior-python-mode))
           (accept-process-output process)
@@ -2063,8 +2293,12 @@
   "Return inferior Python process for current buffer."
   (get-buffer-process (python-shell-get-buffer)))
 
-(defun python-shell-get-or-create-process ()
-  "Get or create an inferior Python process for current buffer and return it."
+(defun python-shell-get-or-create-process (&optional cmd dedicated show)
+  "Get or create an inferior Python process for current buffer and return it.
+Arguments CMD, DEDICATED and SHOW are those of `run-python' and
+are used to start the shell.  If those arguments are not
+provided, `run-python' is called interactively and the user will
+be asked for their values."
   (let* ((dedicated-proc-name (python-shell-get-process-name t))
          (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
          (global-proc-name  (python-shell-get-process-name nil))
@@ -2072,7 +2306,11 @@
          (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
          (global-running (comint-check-proc global-proc-buffer-name)))
     (when (and (not dedicated-running) (not global-running))
-      (if (call-interactively 'run-python)
+      (if (if (not cmd)
+              ;; XXX: Refactor code such that calling `run-python'
+              ;; interactively is not needed anymore.
+              (call-interactively 'run-python)
+            (run-python cmd dedicated show))
           (setq dedicated-running t)
         (setq global-running t)))
     ;; Always prefer dedicated
@@ -2155,10 +2393,13 @@
   (when (string-match
          ;; XXX: It seems on OSX an extra carriage return is attached
          ;; at the end of output, this handles that too.
-         (format "\r?\n\\(?:%s\\|%s\\|%s\\)$"
-                 python-shell-prompt-regexp
-                 python-shell-prompt-block-regexp
-                 python-shell-prompt-pdb-regexp)
+         (concat
+          "\r?\n"
+          ;; Remove initial caret from calculated regexp
+          (replace-regexp-in-string
+           (rx string-start ?^) ""
+           python-shell--prompt-calculated-input-regexp)
+          "$")
          python-shell-output-filter-buffer)
     ;; Output ends when `python-shell-output-filter-buffer' contains
     ;; the prompt attached at the end of it.
@@ -2166,10 +2407,10 @@
           python-shell-output-filter-buffer
           (substring python-shell-output-filter-buffer
                      0 (match-beginning 0)))
-    (when (and (> (length python-shell-prompt-output-regexp) 0)
-               (string-match (concat "^" python-shell-prompt-output-regexp)
-                             python-shell-output-filter-buffer))
-      ;; Some shells, like iPython might append a prompt before the
+    (when (string-match
+           python-shell--prompt-calculated-output-regexp
+           python-shell-output-filter-buffer)
+      ;; Some shells, like IPython might append a prompt before the
       ;; output, clean that.
       (setq python-shell-output-filter-buffer
             (substring python-shell-output-filter-buffer (match-end 0)))))
@@ -2379,23 +2620,35 @@
 
 (defcustom python-shell-completion-setup-code
   "try:
-    import readline
+    import readline, rlcompleter
 except ImportError:
-    def __COMPLETER_all_completions(text): []
+    def __PYTHON_EL_get_completions(text):
+        return []
 else:
-    import rlcompleter
-    readline.set_completer(rlcompleter.Completer().complete)
-    def __COMPLETER_all_completions(text):
-        import sys
+    def __PYTHON_EL_get_completions(text):
         completions = []
         try:
-            i = 0
-            while True:
-                res = readline.get_completer()(text, i)
-                if not res: break
-                i += 1
-                completions.append(res)
-        except NameError:
+            splits = text.split()
+            is_module = splits and splits[0] in ('from', 'import')
+            is_ipython = getattr(
+                __builtins__, '__IPYTHON__',
+                getattr(__builtins__, '__IPYTHON__active', False))
+            if is_module:
+                from IPython.core.completerlib import module_completion
+                completions = module_completion(text.strip())
+            elif is_ipython and getattr(__builtins__, '__IP', None):
+                completions = __IP.complete(text)
+            elif is_ipython and getattr(__builtins__, 'get_ipython', None):
+                completions = get_ipython().Completer.all_completions(text)
+            else:
+                i = 0
+                while True:
+                    res = readline.get_completer()(text, i)
+                    if not res:
+                        break
+                    i += 1
+                    completions.append(res)
+        except:
             pass
         return completions"
   "Code used to setup completion in inferior Python processes."
@@ -2403,24 +2656,18 @@
   :group 'python)
 
 (defcustom python-shell-completion-string-code
-  "';'.join(__COMPLETER_all_completions('''%s'''))\n"
-  "Python code used to get a string of completions separated by semicolons."
-  :type 'string
-  :group 'python)
-
-(defcustom python-shell-completion-module-string-code ""
-  "Python code used to get completions separated by semicolons for imports.
-
-For IPython v0.11, add the following line to
-`python-shell-completion-setup-code':
-
-from IPython.core.completerlib import module_completion
-
-and use the following as the value of this variable:
-
-';'.join(module_completion('''%s'''))\n"
-  :type 'string
-  :group 'python)
+  "';'.join(__PYTHON_EL_get_completions('''%s'''))\n"
+  "Python code used to get a string of completions separated by semicolons.
+The string passed to the function is the current python name or
+the full statement in the case of imports."
+  :type 'string
+  :group 'python)
+
+(define-obsolete-variable-alias
+  'python-shell-completion-module-string-code
+  'python-shell-completion-string-code
+  "24.4"
+  "Completion string code must also autocomplete modules.")
 
 (defcustom python-shell-completion-pdb-string-code
   "';'.join(globals().keys() + locals().keys())"
@@ -2443,33 +2690,23 @@
                  (re-search-backward "^")
                  (python-util-forward-comment)
                  (point))))))
-         (completion-context
+         (completion-code
           ;; Check whether a prompt matches a pdb string, an import
           ;; statement or just the standard prompt and use the
           ;; correct python-shell-completion-*-code string
           (cond ((and (> (length python-shell-completion-pdb-string-code) 0)
                       (string-match
                        (concat "^" python-shell-prompt-pdb-regexp) prompt))
-                 'pdb)
-                ((and (>
-                       (length python-shell-completion-module-string-code) 0)
-                      (string-match
-                       (concat "^" python-shell-prompt-regexp) prompt)
-                      (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
-                 'import)
+                 python-shell-completion-pdb-string-code)
                 ((string-match
-                  (concat "^" python-shell-prompt-regexp) prompt)
-                 'default)
+                  python-shell--prompt-calculated-input-regexp prompt)
+                 python-shell-completion-string-code)
                 (t nil)))
-         (completion-code
-          (pcase completion-context
-            (`pdb python-shell-completion-pdb-string-code)
-            (`import python-shell-completion-module-string-code)
-            (`default python-shell-completion-string-code)
-            (_ nil)))
          (input
-          (if (eq completion-context 'import)
-              (replace-regexp-in-string "^[ \t]+" "" line)
+          (if (string-match
+               (python-rx (+ space) (or "from" "import") space)
+               line)
+              line
             input)))
     (and completion-code
          (> (length input) 0)
@@ -3710,6 +3947,10 @@
    ""
    string))
 
+(defun python-util-valid-regexp-p (regexp)
+  "Return non-nil if REGEXP is valid."
+  (ignore-errors (string-match regexp "") t))
+
 
 (defun python-electric-pair-string-delimiter ()
   (when (and electric-pair-mode
@@ -3794,8 +4035,6 @@
                              ,(lambda (_arg)
                                 (python-nav-end-of-defun)) nil))
 
-  (set (make-local-variable 'mode-require-final-newline) t)
-
   (set (make-local-variable 'outline-regexp)
        (python-rx (* space) block-start))
   (set (make-local-variable 'outline-heading-end-regexp) ":[^\n]*\n")

=== modified file 'lisp/view.el'
--- a/lisp/view.el      2014-01-01 07:43:34 +0000
+++ b/lisp/view.el      2014-07-21 05:38:17 +0000
@@ -491,12 +491,12 @@
 (defun view--disable ()
   (remove-hook 'change-major-mode-hook 'view--disable t)
   (and view-overlay (delete-overlay view-overlay))
-  ;; Calling toggle-read-only while View mode is enabled
+  ;; Calling read-only-mode while View mode is enabled
   ;; sets view-read-only to t as a buffer-local variable
-  ;; after exiting View mode.  That arranges that the next toggle-read-only
+  ;; after exiting View mode.  That arranges that the next read-only-mode
   ;; will reenable View mode.
   ;; Canceling View mode in any other way should cancel that, too,
-  ;; so that View mode stays off if toggle-read-only is called.
+  ;; so that View mode stays off if read-only-mode is called.
   (if (local-variable-p 'view-read-only)
       (kill-local-variable 'view-read-only))
   (if (boundp 'Helper-return-blurb)

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2014-07-20 16:14:58 +0000
+++ b/src/ChangeLog     2014-07-21 06:03:08 +0000
@@ -1,3 +1,37 @@
+2014-07-21  Jan Djärv  <address@hidden>
+
+       * nsterm.m (applicationDidFinishLaunching:): Call
+       antialiasThresholdDidChange, register for antialias changes (Bug#17534).
+       (antialiasThresholdDidChange:): New method for EmacsApp.
+
+       * nsterm.h (EmacsApp): Add antialiasThresholdDidChange.
+
+       * macfont.m (macfont_update_antialias_threshold): Remove static.
+
+       * macfont.h (macfont_update_antialias_threshold): Declare.
+
+2014-07-21  Eli Zaretskii  <address@hidden>
+
+       * w32select.c (setup_windows_coding_system): Apply
+       CODING_ANNOTATION_MASK to the common_flags member of struct
+       coding_system.  Reported by martin rudalics <address@hidden>.
+
+       * w16select.c (Fw16_get_clipboard_data): Apply
+       CODING_ANNOTATION_MASK to the common_flags member of struct
+       coding_system.
+
+       * xdisp.c (init_iterator): Initialize it->stop_charpos to the
+       buffer position where we are to start the iteration.
+       (handle_invisible_prop): Record in it->stop_charpos the position
+       where the invisible text ends.  (Bug#18035)
+       (hscroll_window_tree): Don't try hscrolling windows whose cursor
+       row has zero buffer position as their start position.  Reported by
+       martin rudalics <address@hidden>.
+
+       * xdisp.c (move_it_vertically_backward, move_it_by_lines): Prevent
+       infinite looping in redisplay when display lines don't have enough
+       space to display even a single character.  (Bug#18036)
+
 2014-07-20  Dmitry Antipov  <address@hidden>
 
        * frame.h (struct frame) [USE_X_TOOLKIT]: New member shell_position.

=== modified file 'src/macfont.h'
--- a/src/macfont.h     2014-01-01 07:43:34 +0000
+++ b/src/macfont.h     2014-07-20 13:18:47 +0000
@@ -144,4 +144,5 @@
 
 extern void mac_register_font_driver (struct frame *f);
 extern void *macfont_get_nsctfont (struct font *font);
+extern void macfont_update_antialias_threshold (void);
 

=== modified file 'src/macfont.m'
--- a/src/macfont.m     2014-07-08 14:50:45 +0000
+++ b/src/macfont.m     2014-07-21 06:03:08 +0000
@@ -728,7 +728,7 @@
 
 static CGFloat macfont_antialias_threshold;
 
-static void
+void
 macfont_update_antialias_threshold (void)
 {
   int threshold;

=== modified file 'src/nsterm.h'
--- a/src/nsterm.h      2014-06-30 18:44:56 +0000
+++ b/src/nsterm.h      2014-07-21 06:03:08 +0000
@@ -111,6 +111,7 @@
 #endif
 }
 - (void)logNotification: (NSNotification *)notification;
+- (void)antialiasThresholdDidChange:(NSNotification *)notification;
 - (void)sendEvent: (NSEvent *)theEvent;
 - (void)showPreferencesWindow: (id)sender;
 - (BOOL) openFile: (NSString *)fileName;

=== modified file 'src/nsterm.m'
--- a/src/nsterm.m      2014-07-16 08:45:22 +0000
+++ b/src/nsterm.m      2014-07-21 06:03:08 +0000
@@ -4670,9 +4670,30 @@
   ((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES;
 #endif
   [NSApp setServicesProvider: NSApp];
+
+  [self antialiasThresholdDidChange:nil];
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+  [[NSNotificationCenter defaultCenter]
+    addObserver:self
+       selector:@selector(antialiasThresholdDidChange:)
+          name:NSAntialiasThresholdChangedNotification
+        object:nil];
+#endif
+#endif
+
   ns_send_appdefined (-2);
 }
 
+- (void)antialiasThresholdDidChange:(NSNotification *)notification
+{
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+  macfont_update_antialias_threshold ();
+#endif
+#endif
+}
+
 
 /* Termination sequences:
     C-x C-c:

=== modified file 'src/w16select.c'
--- a/src/w16select.c   2014-01-01 07:43:34 +0000
+++ b/src/w16select.c   2014-07-17 15:40:18 +0000
@@ -600,7 +600,7 @@
       coding.mode |= CODING_MODE_LAST_BLOCK;
       /* We explicitly disable composition handling because selection
         data should not contain any composition sequence.  */
-      coding.mode &= CODING_ANNOTATION_MASK;
+      coding.common_flags &= ~CODING_ANNOTATION_MASK;
       decode_coding_object (&coding, Qnil, 0, 0, truelen, truelen, Qt);
       ret = coding.dst_object;
       Vlast_coding_system_used = CODING_ID_NAME (coding.id);

=== modified file 'src/w32select.c'
--- a/src/w32select.c   2014-01-01 07:43:34 +0000
+++ b/src/w32select.c   2014-07-17 15:37:48 +0000
@@ -670,7 +670,7 @@
      which both apply to ISO6429 only.  We don't know if these really
      need to be unset on Windows, but it probably doesn't hurt
      either.  */
-  coding->mode &= ~CODING_ANNOTATION_MASK;
+  coding->common_flags &= ~CODING_ANNOTATION_MASK;
   coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
 }
 

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2014-07-16 17:06:12 +0000
+++ b/src/xdisp.c       2014-07-21 06:03:08 +0000
@@ -3034,6 +3034,7 @@
      getting overlays and face properties from that position.  */
   if (charpos >= BUF_BEG (current_buffer))
     {
+      it->stop_charpos = charpos;
       it->end_charpos = ZV;
       eassert (charpos == BYTE_TO_CHAR (bytepos));
       IT_CHARPOS (*it) = charpos;
@@ -4546,7 +4547,24 @@
              && get_overlay_strings (it, it->stop_charpos))
            {
              handled = HANDLED_RECOMPUTE_PROPS;
-             it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
+             if (it->sp > 0)
+               {
+                 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
+                 /* The call to get_overlay_strings above recomputes
+                    it->stop_charpos, but it only considers changes
+                    in properties and overlays beyond iterator's
+                    current position.  This causes us to miss changes
+                    that happen exactly where the invisible property
+                    ended.  So we play it safe here and force the
+                    iterator to check for potential stop positions
+                    immediately after the invisible text.  Note that
+                    if get_overlay_strings returns non-zero, it
+                    normally also pushed the iterator stack, so we
+                    need to update the stop position in the slot
+                    below the current one.  */
+                 it->stack[it->sp - 1].stop_charpos
+                   = CHARPOS (it->stack[it->sp - 1].current.pos);
+               }
            }
          else if (display_ellipsis_p)
             {
@@ -9351,7 +9369,7 @@
 
   /* Estimate how many newlines we must move back.  */
   nlines = max (1, dy / default_line_pixel_height (it->w));
-  if (it->line_wrap == TRUNCATE)
+  if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
     pos_limit = BEGV;
   else
     pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
@@ -9606,7 +9624,7 @@
       /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
         screen lines, and reseat the iterator there.  */
       start_charpos = IT_CHARPOS (*it);
-      if (it->line_wrap == TRUNCATE)
+      if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
        pos_limit = BEGV;
       else
        pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
@@ -12847,6 +12865,13 @@
          h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
 
          if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
+             /* In some pathological cases, like restoring a window
+                configuration into a frame that is much smaller than
+                the one from which the configuration was saved, we
+                get glyph rows whose start and end have zero buffer
+                positions, which we cannot handle below.  Just skip
+                such windows.  */
+             && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
              /* For left-to-right rows, hscroll when cursor is either
                 (i) inside the right hscroll margin, or (ii) if it is
                 inside the left margin and the window is already

=== modified file 'test/ChangeLog'
--- a/test/ChangeLog    2014-07-21 01:34:03 +0000
+++ b/test/ChangeLog    2014-07-21 06:03:08 +0000
@@ -1,3 +1,37 @@
+2014-07-21  Fabián Ezequiel Gallina  <address@hidden>
+
+       * automated/python-tests.el:
+       (python-util-clone-local-variables-1): Fix test.
+
+       * automated/python-tests.el (python-shell-make-comint-1):
+       (python-shell-make-comint-2): Fix indentation.
+       (python-shell-make-comint-3)
+       (python-shell-make-comint-4): New tests.
+       (python-shell-get-or-create-process-1): Fix test.
+       (python-shell-get-or-create-process-2)
+       (python-shell-get-or-create-process-3): New tests.
+       (python-shell-internal-get-or-create-process-1): Fix test.
+       (python-shell-prompt-detect-1): New test.
+       (python-shell-prompt-detect-2): New test.  (Bug#17370)
+       (python-shell-prompt-detect-3)
+       (python-shell-prompt-detect-4)
+       (python-shell-prompt-detect-5)
+       (python-shell-prompt-detect-6)
+       (python-shell-prompt-validate-regexps-1)
+       (python-shell-prompt-validate-regexps-2)
+       (python-shell-prompt-validate-regexps-3)
+       (python-shell-prompt-validate-regexps-4)
+       (python-shell-prompt-validate-regexps-5)
+       (python-shell-prompt-validate-regexps-6)
+       (python-shell-prompt-validate-regexps-7)
+       (python-shell-prompt-set-calculated-regexps-1)
+       (python-shell-prompt-set-calculated-regexps-2)
+       (python-shell-prompt-set-calculated-regexps-3)
+       (python-shell-prompt-set-calculated-regexps-4)
+       (python-shell-prompt-set-calculated-regexps-5)
+       (python-shell-prompt-set-calculated-regexps-6)
+       (python-util-valid-regexp-p-1): New tests.
+
 2014-07-21  Stefan Monnier  <address@hidden>
 
        * automated/advice-tests.el (advice-test-call-interactively): Make sure
@@ -48,7 +82,7 @@
 
        * automated/python-tests.el (python-tests-self-insert): New function.
        (python-triple-quote-pairing): Use it.
-       (python-util-forward-comment-1): New test. (Bug#17658)
+       (python-parens-electric-indent-1): New test. (Bug#17658)
 
 2014-06-30  Fabián Ezequiel Gallina  <address@hidden>
 

=== modified file 'test/automated/python-tests.el'
--- a/test/automated/python-tests.el    2014-07-09 03:55:53 +0000
+++ b/test/automated/python-tests.el    2014-07-20 18:12:30 +0000
@@ -1773,8 +1773,8 @@
          (proc-name (python-shell-get-process-name nil))
          (shell-buffer
           (python-tests-with-temp-buffer
-              "" (python-shell-make-comint
-                  (python-shell-parse-command) proc-name)))
+           "" (python-shell-make-comint
+               (python-shell-parse-command) proc-name)))
          (process (get-buffer-process shell-buffer)))
     (unwind-protect
         (progn
@@ -1794,8 +1794,8 @@
          (proc-name (python-shell-internal-get-process-name))
          (shell-buffer
           (python-tests-with-temp-buffer
-              "" (python-shell-make-comint
-                  (python-shell-parse-command) proc-name nil t)))
+           "" (python-shell-make-comint
+               (python-shell-parse-command) proc-name nil t)))
          (process (get-buffer-process shell-buffer)))
     (unwind-protect
         (progn
@@ -1806,6 +1806,79 @@
             (should (string= (buffer-name) (format " *%s*" proc-name)))))
       (kill-buffer shell-buffer))))
 
+(ert-deftest python-shell-make-comint-3 ()
+  "Check comint creation with overriden python interpreter and args.
+The command passed to `python-shell-make-comint' as argument must
+locally override global values set in `python-shell-interpreter'
+and `python-shell-interpreter-args' in the new shell buffer."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((python-shell-setup-codes nil)
+         (python-shell-interpreter "interpreter")
+         (python-shell-interpreter-args "--some-args")
+         (proc-name (python-shell-get-process-name nil))
+         (interpreter-override
+          (concat (executable-find python-tests-shell-interpreter) " " "-i"))
+         (shell-buffer
+          (python-tests-with-temp-buffer
+           "" (python-shell-make-comint interpreter-override proc-name nil)))
+         (process (get-buffer-process shell-buffer)))
+    (unwind-protect
+        (progn
+          (set-process-query-on-exit-flag process nil)
+          (should (process-live-p process))
+          (with-current-buffer shell-buffer
+            (should (eq major-mode 'inferior-python-mode))
+            (should (string= python-shell-interpreter
+                             (executable-find python-tests-shell-interpreter)))
+            (should (string= python-shell-interpreter-args "-i"))))
+      (kill-buffer shell-buffer))))
+
+(ert-deftest python-shell-make-comint-4 ()
+  "Check shell calculated prompts regexps are set."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((process-environment process-environment)
+         (python-shell-setup-codes nil)
+         (python-shell-interpreter
+          (executable-find python-tests-shell-interpreter))
+         (python-shell-interpreter-args "-i")
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled t)
+         (python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
+         (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
+         (python-shell-prompt-regexp "in")
+         (python-shell-prompt-block-regexp "block")
+         (python-shell-prompt-pdb-regexp "pdf")
+         (python-shell-prompt-output-regexp "output")
+         (startup-code (concat "import sys\n"
+                               "sys.ps1 = 'py> '\n"
+                               "sys.ps2 = '..> '\n"
+                               "sys.ps3 = 'out '\n"))
+         (startup-file (python-shell--save-temp-file startup-code))
+         (proc-name (python-shell-get-process-name nil))
+         (shell-buffer
+          (progn
+            (setenv "PYTHONSTARTUP" startup-file)
+            (python-tests-with-temp-buffer
+             "" (python-shell-make-comint
+                 (python-shell-parse-command) proc-name nil))))
+         (process (get-buffer-process shell-buffer)))
+    (unwind-protect
+        (progn
+          (set-process-query-on-exit-flag process nil)
+          (should (process-live-p process))
+          (with-current-buffer shell-buffer
+            (should (eq major-mode 'inferior-python-mode))
+            (should (string=
+                     python-shell--prompt-calculated-input-regexp
+                     (concat "^\\(extralargeinputprompt\\|\\.\\.> \\|"
+                             "block\\|py> \\|pdf\\|sml\\|in\\)")))
+            (should (string=
+                     python-shell--prompt-calculated-output-regexp
+                     "^\\(extralargeoutputprompt\\|output\\|out \\|sml\\)"))))
+      (delete-file startup-file)
+      (kill-buffer shell-buffer))))
+
 (ert-deftest python-shell-get-process-1 ()
   "Check dedicated shell process preference over global."
   (skip-unless (executable-find python-tests-shell-interpreter))
@@ -1840,54 +1913,370 @@
         (ignore-errors (kill-buffer dedicated-shell-buffer))))))
 
 (ert-deftest python-shell-get-or-create-process-1 ()
-  "Check shell process creation fallback."
-  :expected-result :failed
-  (python-tests-with-temp-file
-      ""
-    ;; XXX: Break early until we can skip stuff.  We need to mimic
-    ;; user interaction because `python-shell-get-or-create-process'
-    ;; asks for all arguments interactively when a shell process
-    ;; doesn't exist.
-    (should nil)
-    (let* ((python-shell-interpreter
-            (executable-find python-tests-shell-interpreter))
-           (use-dialog-box)
-           (dedicated-process-name (python-shell-get-process-name t))
-           (dedicated-process (python-shell-get-or-create-process))
-           (dedicated-shell-buffer (process-buffer dedicated-process)))
-      (unwind-protect
-          (progn
-            (set-process-query-on-exit-flag dedicated-process nil)
-            ;; Prefer dedicated if not buffer exist.
-            (should (equal (process-name dedicated-process)
-                           dedicated-process-name))
-            (kill-buffer dedicated-shell-buffer)
-            ;; No buffer available.
-            (should (not (python-shell-get-process))))
-        (ignore-errors (kill-buffer dedicated-shell-buffer))))))
+  "Check shell dedicated process creation."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (python-tests-with-temp-file
+   ""
+   (let* ((python-shell-interpreter
+           (executable-find python-tests-shell-interpreter))
+          (use-dialog-box)
+          (dedicated-process-name (python-shell-get-process-name t))
+          (dedicated-process
+           (python-shell-get-or-create-process python-shell-interpreter t))
+          (dedicated-shell-buffer (process-buffer dedicated-process)))
+     (unwind-protect
+         (progn
+           (set-process-query-on-exit-flag dedicated-process nil)
+           ;; should be dedicated.
+           (should (equal (process-name dedicated-process)
+                          dedicated-process-name))
+           (kill-buffer dedicated-shell-buffer)
+           ;; Check there are no processes for current buffer.
+           (should (not (python-shell-get-process))))
+       (ignore-errors (kill-buffer dedicated-shell-buffer))))))
+
+(ert-deftest python-shell-get-or-create-process-2 ()
+  "Check shell global process creation."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (python-tests-with-temp-file
+   ""
+   (let* ((python-shell-interpreter
+           (executable-find python-tests-shell-interpreter))
+          (use-dialog-box)
+          (process-name (python-shell-get-process-name nil))
+          (process
+           (python-shell-get-or-create-process python-shell-interpreter))
+          (shell-buffer (process-buffer process)))
+     (unwind-protect
+         (progn
+           (set-process-query-on-exit-flag process nil)
+           ;; should be global.
+           (should (equal (process-name process) process-name))
+           (kill-buffer shell-buffer)
+           ;; Check there are no processes for current buffer.
+           (should (not (python-shell-get-process))))
+       (ignore-errors (kill-buffer dedicated-shell-buffer))))))
+
+(ert-deftest python-shell-get-or-create-process-3 ()
+  "Check shell dedicated/global process preference."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (python-tests-with-temp-file
+   ""
+   (let* ((python-shell-interpreter
+           (executable-find python-tests-shell-interpreter))
+          (use-dialog-box)
+          (dedicated-process-name (python-shell-get-process-name t))
+          (global-process)
+          (dedicated-process))
+     (unwind-protect
+         (progn
+           ;; Create global process
+           (run-python python-shell-interpreter nil)
+           (setq global-process (get-buffer-process "*Python*"))
+           (should global-process)
+           (set-process-query-on-exit-flag global-process nil)
+           ;; Create dedicated process
+           (run-python python-shell-interpreter t)
+           (setq dedicated-process (get-process dedicated-process-name))
+           (should dedicated-process)
+           (set-process-query-on-exit-flag dedicated-process nil)
+           ;; Prefer dedicated.
+           (should (equal (python-shell-get-or-create-process)
+                          dedicated-process))
+           ;; Kill the dedicated so the global takes over.
+           (kill-buffer (process-buffer dedicated-process))
+           ;; Detect global.
+           (should (equal (python-shell-get-or-create-process) global-process))
+           ;; Kill the global.
+           (kill-buffer (process-buffer global-process))
+           ;; Check there are no processes for current buffer.
+           (should (not (python-shell-get-process))))
+       (ignore-errors (kill-buffer dedicated-shell-buffer))))))
 
 (ert-deftest python-shell-internal-get-or-create-process-1 ()
   "Check internal shell process creation fallback."
   (skip-unless (executable-find python-tests-shell-interpreter))
   (python-tests-with-temp-file
-      ""
-    (should (not (process-live-p (python-shell-internal-get-process-name))))
-    (let* ((python-shell-interpreter
-            (executable-find python-tests-shell-interpreter))
-           (internal-process-name (python-shell-internal-get-process-name))
-           (internal-process (python-shell-internal-get-or-create-process))
-           (internal-shell-buffer (process-buffer internal-process)))
-      (unwind-protect
-          (progn
-            (set-process-query-on-exit-flag internal-process nil)
-            (should (equal (process-name internal-process)
-                           internal-process-name))
-            (should (equal internal-process
-                           (python-shell-internal-get-or-create-process)))
-            ;; No user buffer available.
-            (should (not (python-shell-get-process)))
-            (kill-buffer internal-shell-buffer))
-        (ignore-errors (kill-buffer internal-shell-buffer))))))
+   ""
+   (should (not (process-live-p (python-shell-internal-get-process-name))))
+   (let* ((python-shell-interpreter
+           (executable-find python-tests-shell-interpreter))
+          (internal-process-name (python-shell-internal-get-process-name))
+          (internal-process (python-shell-internal-get-or-create-process))
+          (internal-shell-buffer (process-buffer internal-process)))
+     (unwind-protect
+         (progn
+           (set-process-query-on-exit-flag internal-process nil)
+           (should (equal (process-name internal-process)
+                          internal-process-name))
+           (should (equal internal-process
+                          (python-shell-internal-get-or-create-process)))
+           ;; Assert the internal process is not a user process
+           (should (not (python-shell-get-process)))
+           (kill-buffer internal-shell-buffer))
+       (ignore-errors (kill-buffer internal-shell-buffer))))))
+
+(ert-deftest python-shell-prompt-detect-1 ()
+  "Check prompt autodetection."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let ((process-environment process-environment))
+    ;; Ensure no startup file is enabled
+    (setenv "PYTHONSTARTUP" "")
+    (should python-shell-prompt-detect-enabled)
+    (should (equal (python-shell-prompt-detect) '(">>> " "... " "")))))
+
+(ert-deftest python-shell-prompt-detect-2 ()
+  "Check prompt autodetection with startup file.  Bug#17370."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((process-environment process-environment)
+         (startup-code (concat "import sys\n"
+                               "sys.ps1 = 'py> '\n"
+                               "sys.ps2 = '..> '\n"
+                               "sys.ps3 = 'out '\n"))
+         (startup-file (python-shell--save-temp-file startup-code)))
+    (unwind-protect
+        (progn
+          ;; Ensure startup file is enabled
+          (setenv "PYTHONSTARTUP" startup-file)
+          (should python-shell-prompt-detect-enabled)
+          (should (equal (python-shell-prompt-detect) '("py> " "..> " "out 
"))))
+      (ignore-errors (delete-file startup-file)))))
+
+(ert-deftest python-shell-prompt-detect-3 ()
+  "Check prompts are not autodetected when feature is disabled."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let ((process-environment process-environment)
+        (python-shell-prompt-detect-enabled nil))
+    ;; Ensure no startup file is enabled
+    (should (not python-shell-prompt-detect-enabled))
+    (should (not (python-shell-prompt-detect)))))
+
+(ert-deftest python-shell-prompt-detect-4 ()
+  "Check warning is shown when detection fails."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((process-environment process-environment)
+         ;; Trigger failure by removing prompts in the startup file
+         (startup-code (concat "import sys\n"
+                               "sys.ps1 = ''\n"
+                               "sys.ps2 = ''\n"
+                               "sys.ps3 = ''\n"))
+         (startup-file (python-shell--save-temp-file startup-code)))
+    (unwind-protect
+        (progn
+          (kill-buffer (get-buffer-create "*Warnings*"))
+          (should (not (get-buffer "*Warnings*")))
+          (setenv "PYTHONSTARTUP" startup-file)
+          (should python-shell-prompt-detect-failure-warning)
+          (should python-shell-prompt-detect-enabled)
+          (should (not (python-shell-prompt-detect)))
+          (should (get-buffer "*Warnings*")))
+      (ignore-errors (delete-file startup-file)))))
+
+(ert-deftest python-shell-prompt-detect-5 ()
+  "Check disabled warnings are not shown when detection fails."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((process-environment process-environment)
+         (startup-code (concat "import sys\n"
+                               "sys.ps1 = ''\n"
+                               "sys.ps2 = ''\n"
+                               "sys.ps3 = ''\n"))
+         (startup-file (python-shell--save-temp-file startup-code))
+         (python-shell-prompt-detect-failure-warning nil))
+    (unwind-protect
+        (progn
+          (kill-buffer (get-buffer-create "*Warnings*"))
+          (should (not (get-buffer "*Warnings*")))
+          (setenv "PYTHONSTARTUP" startup-file)
+          (should (not python-shell-prompt-detect-failure-warning))
+          (should python-shell-prompt-detect-enabled)
+          (should (not (python-shell-prompt-detect)))
+          (should (not (get-buffer "*Warnings*"))))
+      (ignore-errors (delete-file startup-file)))))
+
+(ert-deftest python-shell-prompt-detect-6 ()
+  "Warnings are not shown when detection is disabled."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((process-environment process-environment)
+         (startup-code (concat "import sys\n"
+                               "sys.ps1 = ''\n"
+                               "sys.ps2 = ''\n"
+                               "sys.ps3 = ''\n"))
+         (startup-file (python-shell--save-temp-file startup-code))
+         (python-shell-prompt-detect-failure-warning t)
+         (python-shell-prompt-detect-enabled nil))
+    (unwind-protect
+        (progn
+          (kill-buffer (get-buffer-create "*Warnings*"))
+          (should (not (get-buffer "*Warnings*")))
+          (setenv "PYTHONSTARTUP" startup-file)
+          (should python-shell-prompt-detect-failure-warning)
+          (should (not python-shell-prompt-detect-enabled))
+          (should (not (python-shell-prompt-detect)))
+          (should (not (get-buffer "*Warnings*"))))
+      (ignore-errors (delete-file startup-file)))))
+
+(ert-deftest python-shell-prompt-validate-regexps-1 ()
+  "Check `python-shell-prompt-input-regexps' are validated."
+  (let* ((python-shell-prompt-input-regexps '("\\("))
+         (error-data (should-error (python-shell-prompt-validate-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-input-regexps'"))))
+
+(ert-deftest python-shell-prompt-validate-regexps-2 ()
+  "Check `python-shell-prompt-output-regexps' are validated."
+  (let* ((python-shell-prompt-output-regexps '("\\("))
+         (error-data (should-error (python-shell-prompt-validate-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-output-regexps'"))))
+
+(ert-deftest python-shell-prompt-validate-regexps-3 ()
+  "Check `python-shell-prompt-regexp' is validated."
+  (let* ((python-shell-prompt-regexp "\\(")
+         (error-data (should-error (python-shell-prompt-validate-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-regexp'"))))
+
+(ert-deftest python-shell-prompt-validate-regexps-4 ()
+  "Check `python-shell-prompt-block-regexp' is validated."
+  (let* ((python-shell-prompt-block-regexp "\\(")
+         (error-data (should-error (python-shell-prompt-validate-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-block-regexp'"))))
+
+(ert-deftest python-shell-prompt-validate-regexps-5 ()
+  "Check `python-shell-prompt-pdb-regexp' is validated."
+  (let* ((python-shell-prompt-pdb-regexp "\\(")
+         (error-data (should-error (python-shell-prompt-validate-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-pdb-regexp'"))))
+
+(ert-deftest python-shell-prompt-validate-regexps-6 ()
+  "Check `python-shell-prompt-output-regexp' is validated."
+  (let* ((python-shell-prompt-output-regexp "\\(")
+         (error-data (should-error (python-shell-prompt-validate-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
+
+(ert-deftest python-shell-prompt-validate-regexps-7 ()
+  "Check default regexps are valid."
+  ;; should not signal error
+  (python-shell-prompt-validate-regexps))
+
+(ert-deftest python-shell-prompt-set-calculated-regexps-1 ()
+  "Check regexps are validated."
+  (let* ((python-shell-prompt-output-regexp '("\\("))
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled nil)
+         (error-data (should-error (python-shell-prompt-set-calculated-regexps)
+                                   :type 'user-error)))
+    (should
+     (string= (cadr error-data)
+              "Invalid regexp \\( in `python-shell-prompt-output-regexp'"))))
+
+(ert-deftest python-shell-prompt-set-calculated-regexps-2 ()
+  "Check `python-shell-prompt-input-regexps' are set."
+  (let* ((python-shell-prompt-input-regexps '("my" "prompt"))
+         (python-shell-prompt-output-regexps '(""))
+         (python-shell-prompt-regexp "")
+         (python-shell-prompt-block-regexp "")
+         (python-shell-prompt-pdb-regexp "")
+         (python-shell-prompt-output-regexp "")
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled nil))
+    (python-shell-prompt-set-calculated-regexps)
+    (should (string= python-shell--prompt-calculated-input-regexp
+                     "^\\(prompt\\|my\\|\\)"))))
+
+(ert-deftest python-shell-prompt-set-calculated-regexps-3 ()
+  "Check `python-shell-prompt-output-regexps' are set."
+  (let* ((python-shell-prompt-input-regexps '(""))
+         (python-shell-prompt-output-regexps '("my" "prompt"))
+         (python-shell-prompt-regexp "")
+         (python-shell-prompt-block-regexp "")
+         (python-shell-prompt-pdb-regexp "")
+         (python-shell-prompt-output-regexp "")
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled nil))
+    (python-shell-prompt-set-calculated-regexps)
+    (should (string= python-shell--prompt-calculated-output-regexp
+                     "^\\(prompt\\|my\\|\\)"))))
+
+(ert-deftest python-shell-prompt-set-calculated-regexps-4 ()
+  "Check user defined prompts are set."
+  (let* ((python-shell-prompt-input-regexps '(""))
+         (python-shell-prompt-output-regexps '(""))
+         (python-shell-prompt-regexp "prompt")
+         (python-shell-prompt-block-regexp "block")
+         (python-shell-prompt-pdb-regexp "pdb")
+         (python-shell-prompt-output-regexp "output")
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled nil))
+    (python-shell-prompt-set-calculated-regexps)
+    (should (string= python-shell--prompt-calculated-input-regexp
+                     "^\\(prompt\\|block\\|pdb\\|\\)"))
+    (should (string= python-shell--prompt-calculated-output-regexp
+                     "^\\(output\\|\\)"))))
+
+(ert-deftest python-shell-prompt-set-calculated-regexps-5 ()
+  "Check order of regexps (larger first)."
+  (let* ((python-shell-prompt-input-regexps '("extralargeinputprompt" "sml"))
+         (python-shell-prompt-output-regexps '("extralargeoutputprompt" "sml"))
+         (python-shell-prompt-regexp "in")
+         (python-shell-prompt-block-regexp "block")
+         (python-shell-prompt-pdb-regexp "pdf")
+         (python-shell-prompt-output-regexp "output")
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled nil))
+    (python-shell-prompt-set-calculated-regexps)
+    (should (string= python-shell--prompt-calculated-input-regexp
+                     "^\\(extralargeinputprompt\\|block\\|pdf\\|sml\\|in\\)"))
+    (should (string= python-shell--prompt-calculated-output-regexp
+                     "^\\(extralargeoutputprompt\\|output\\|sml\\)"))))
+
+(ert-deftest python-shell-prompt-set-calculated-regexps-6 ()
+  "Check detected prompts are included `regexp-quote'd."
+  (skip-unless (executable-find python-tests-shell-interpreter))
+  (let* ((python-shell-prompt-input-regexps '(""))
+         (python-shell-prompt-output-regexps '(""))
+         (python-shell-prompt-regexp "")
+         (python-shell-prompt-block-regexp "")
+         (python-shell-prompt-pdb-regexp "")
+         (python-shell-prompt-output-regexp "")
+         (python-shell--prompt-calculated-input-regexp nil)
+         (python-shell--prompt-calculated-output-regexp nil)
+         (python-shell-prompt-detect-enabled t)
+         (process-environment process-environment)
+         (startup-code (concat "import sys\n"
+                               "sys.ps1 = 'p.> '\n"
+                               "sys.ps2 = '..> '\n"
+                               "sys.ps3 = 'o.t '\n"))
+         (startup-file (python-shell--save-temp-file startup-code)))
+    (unwind-protect
+        (progn
+          (setenv "PYTHONSTARTUP" startup-file)
+          (python-shell-prompt-set-calculated-regexps)
+          (should (string= python-shell--prompt-calculated-input-regexp
+                           "^\\(\\.\\.> \\|p\\.> \\|\\)"))
+          (should (string= python-shell--prompt-calculated-output-regexp
+                           "^\\(o\\.t \\|\\)")))
+      (ignore-errors (delete-file startup-file)))))
 
 
 ;;; Shell completion
@@ -3230,8 +3619,6 @@
            (python-shell-extra-pythonpaths "/home/user/pylib/")
            (python-shell-completion-setup-code
             . "from IPython.core.completerlib import module_completion")
-           (python-shell-completion-module-string-code
-            . "';'.join(module_completion('''%s'''))\n")
            (python-shell-completion-string-code
             . "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
            (python-shell-virtualenv-path
@@ -3269,6 +3656,11 @@
    (python-util-forward-comment -1)
    (should (= (point) (point-min)))))
 
+(ert-deftest python-util-valid-regexp-p-1 ()
+  (should (python-util-valid-regexp-p ""))
+  (should (python-util-valid-regexp-p python-shell-prompt-regexp))
+  (should (not (python-util-valid-regexp-p "\\("))))
+
 
 ;;; Electricity
 


reply via email to

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