mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-26 10:49:33 +00:00
Merge from emacs-24; up to 2014-06-25T10:17:41Z!rgm@gnu.org
This commit is contained in:
commit
190644a011
@ -1,3 +1,7 @@
|
|||||||
|
2014-07-21 Glenn Morris <rgm@gnu.org>
|
||||||
|
|
||||||
|
* emacs.texi (Intro): Workaround makeinfo 4 @acronym bug. (Bug#18040)
|
||||||
|
|
||||||
2014-07-09 Juri Linkov <juri@jurta.org>
|
2014-07-09 Juri Linkov <juri@jurta.org>
|
||||||
|
|
||||||
* search.texi (Regexp Search): Update lax space matching that is
|
* search.texi (Regexp Search): Update lax space matching that is
|
||||||
|
@ -1476,7 +1476,16 @@ Neal Ziring, Teodor Zlatanov, and Detlev Zundel.
|
|||||||
|
|
||||||
You are reading about GNU Emacs, the GNU incarnation of the
|
You are reading about GNU Emacs, the GNU incarnation of the
|
||||||
advanced, self-documenting, customizable, extensible editor Emacs.
|
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
|
||||||
|
@c Workaround makeinfo 4 bug.
|
||||||
|
@c http://lists.gnu.org/archive/html/bug-texinfo/2004-08/msg00009.html
|
||||||
|
@iftex
|
||||||
|
@acronym{GNU, @acronym{GNU}'s Not Unix}
|
||||||
|
@end iftex
|
||||||
|
@ifnottex
|
||||||
|
@acronym{GNU, GNU's Not Unix}
|
||||||
|
@end ifnottex
|
||||||
|
is not silent.)
|
||||||
|
|
||||||
We call Emacs @dfn{advanced} because it can do much more than simple
|
We call Emacs @dfn{advanced} because it can do much more than simple
|
||||||
insertion and deletion of text. It can control subprocesses, indent
|
insertion and deletion of text. It can control subprocesses, indent
|
||||||
|
16
etc/NEWS
16
etc/NEWS
@ -870,6 +870,22 @@ display a "Homepage" header.)
|
|||||||
** In Prolog mode, `prolog-use-smie' has been removed,
|
** In Prolog mode, `prolog-use-smie' has been removed,
|
||||||
along with the non-SMIE indentation code.
|
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
|
** Remember
|
||||||
|
|
||||||
*** The new command `remember-notes' creates a buffer that is saved on exit.
|
*** The new command `remember-notes' creates a buffer that is saved on exit.
|
||||||
|
@ -1,3 +1,67 @@
|
|||||||
|
2014-07-21 Glenn Morris <rgm@gnu.org>
|
||||||
|
|
||||||
|
* 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 <fgallina@gnu.org>
|
||||||
|
|
||||||
|
* 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 <monnier@iro.umontreal.ca>
|
2014-07-21 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||||
|
|
||||||
* emacs-lisp/smie.el (smie-config--guess-1): Split from
|
* emacs-lisp/smie.el (smie-config--guess-1): Split from
|
||||||
|
@ -36,7 +36,7 @@ corresponding to the mode line clicked."
|
|||||||
|
|
||||||
|
|
||||||
(defun mode-line-toggle-read-only (event)
|
(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")
|
(interactive "e")
|
||||||
(with-selected-window (posn-window (event-start event))
|
(with-selected-window (posn-window (event-start event))
|
||||||
(read-only-mode 'toggle)))
|
(read-only-mode 'toggle)))
|
||||||
|
@ -954,7 +954,7 @@ Default is `bs--current-sort-function'."
|
|||||||
|
|
||||||
(defun bs-toggle-readonly ()
|
(defun bs-toggle-readonly ()
|
||||||
"Toggle read-only status for buffer on current line.
|
"Toggle read-only status for buffer on current line.
|
||||||
Uses function `toggle-read-only'."
|
Uses function `read-only-mode'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(with-current-buffer (bs--current-buffer)
|
(with-current-buffer (bs--current-buffer)
|
||||||
(read-only-mode 'toggle))
|
(read-only-mode 'toggle))
|
||||||
|
@ -539,7 +539,7 @@ The current window remains selected."
|
|||||||
|
|
||||||
(defun Buffer-menu-toggle-read-only ()
|
(defun Buffer-menu-toggle-read-only ()
|
||||||
"Toggle read-only status of buffer on this line.
|
"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)
|
(interactive)
|
||||||
(let ((read-only
|
(let ((read-only
|
||||||
(with-current-buffer (Buffer-menu-buffer t)
|
(with-current-buffer (Buffer-menu-buffer t)
|
||||||
|
@ -2015,7 +2015,7 @@ Actual changes in files cannot be undone by Emacs."))
|
|||||||
"Edit Dired buffer with Wdired, or make it read-only.
|
"Edit Dired buffer with Wdired, or make it read-only.
|
||||||
If the current buffer can be edited with Wdired, (i.e. the major
|
If the current buffer can be edited with Wdired, (i.e. the major
|
||||||
mode is `dired-mode'), call `wdired-change-to-wdired-mode'.
|
mode is `dired-mode'), call `wdired-change-to-wdired-mode'.
|
||||||
Otherwise, call `toggle-read-only'."
|
Otherwise, toggle `read-only-mode'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (derived-mode-p 'dired-mode)
|
(if (derived-mode-p 'dired-mode)
|
||||||
(wdired-change-to-wdired-mode)
|
(wdired-change-to-wdired-mode)
|
||||||
|
@ -564,7 +564,7 @@ A value of nil means ignore them; anything else means query."
|
|||||||
In fact, this means that all read-only buffers normally have
|
In fact, this means that all read-only buffers normally have
|
||||||
View mode enabled, including buffers that are read-only because
|
View mode enabled, including buffers that are read-only because
|
||||||
you visit a file you cannot alter, and buffers you make read-only
|
you visit a file you cannot alter, and buffers you make read-only
|
||||||
using \\[toggle-read-only]."
|
using \\[read-only-mode]."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'view)
|
:group 'view)
|
||||||
|
|
||||||
@ -1502,7 +1502,7 @@ file names with wildcards."
|
|||||||
(defun find-file-read-only (filename &optional wildcards)
|
(defun find-file-read-only (filename &optional wildcards)
|
||||||
"Edit file FILENAME but don't allow changes.
|
"Edit file FILENAME but don't allow changes.
|
||||||
Like \\[find-file], but marks buffer as read-only.
|
Like \\[find-file], but marks buffer as read-only.
|
||||||
Use \\[toggle-read-only] to permit editing."
|
Use \\[read-only-mode] to permit editing."
|
||||||
(interactive
|
(interactive
|
||||||
(find-file-read-args "Find file read-only: "
|
(find-file-read-args "Find file read-only: "
|
||||||
(confirm-nonexistent-file-or-buffer)))
|
(confirm-nonexistent-file-or-buffer)))
|
||||||
@ -1511,7 +1511,7 @@ Use \\[toggle-read-only] to permit editing."
|
|||||||
(defun find-file-read-only-other-window (filename &optional wildcards)
|
(defun find-file-read-only-other-window (filename &optional wildcards)
|
||||||
"Edit file FILENAME in another window but don't allow changes.
|
"Edit file FILENAME in another window but don't allow changes.
|
||||||
Like \\[find-file-other-window], but marks buffer as read-only.
|
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
|
(interactive
|
||||||
(find-file-read-args "Find file read-only other window: "
|
(find-file-read-args "Find file read-only other window: "
|
||||||
(confirm-nonexistent-file-or-buffer)))
|
(confirm-nonexistent-file-or-buffer)))
|
||||||
@ -1520,7 +1520,7 @@ Use \\[toggle-read-only] to permit editing."
|
|||||||
(defun find-file-read-only-other-frame (filename &optional wildcards)
|
(defun find-file-read-only-other-frame (filename &optional wildcards)
|
||||||
"Edit file FILENAME in another frame but don't allow changes.
|
"Edit file FILENAME in another frame but don't allow changes.
|
||||||
Like \\[find-file-other-frame], but marks buffer as read-only.
|
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
|
(interactive
|
||||||
(find-file-read-args "Find file read-only other frame: "
|
(find-file-read-args "Find file read-only other frame: "
|
||||||
(confirm-nonexistent-file-or-buffer)))
|
(confirm-nonexistent-file-or-buffer)))
|
||||||
|
@ -188,6 +188,9 @@ Effective only if `hide-ifdef-expand-reinclusion-protection' is t."
|
|||||||
|
|
||||||
(define-key map "\C-q" 'hide-ifdef-toggle-read-only)
|
(define-key map "\C-q" 'hide-ifdef-toggle-read-only)
|
||||||
(define-key map "\C-w" 'hide-ifdef-toggle-shadowing)
|
(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
|
(substitute-key-definition
|
||||||
'toggle-read-only 'hide-ifdef-toggle-outside-read-only map)
|
'toggle-read-only 'hide-ifdef-toggle-outside-read-only map)
|
||||||
map)
|
map)
|
||||||
@ -1789,7 +1792,7 @@ It does not do the work that's pointless to redo on a recursive entry."
|
|||||||
(force-mode-line-update))
|
(force-mode-line-update))
|
||||||
|
|
||||||
(defun hide-ifdef-toggle-outside-read-only ()
|
(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)
|
(interactive)
|
||||||
(setq hif-outside-read-only (not hif-outside-read-only))
|
(setq hif-outside-read-only (not hif-outside-read-only))
|
||||||
(message "Read only %s"
|
(message "Read only %s"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
;; Author: Fabián E. Gallina <fabian@anue.biz>
|
;; Author: Fabián E. Gallina <fabian@anue.biz>
|
||||||
;; URL: https://github.com/fgallina/python.el
|
;; URL: https://github.com/fgallina/python.el
|
||||||
;; Version: 0.24.2
|
;; Version: 0.24.4
|
||||||
;; Maintainer: emacs-devel@gnu.org
|
;; Maintainer: emacs-devel@gnu.org
|
||||||
;; Created: Jul 2010
|
;; Created: Jul 2010
|
||||||
;; Keywords: languages
|
;; Keywords: languages
|
||||||
@ -62,57 +62,80 @@
|
|||||||
;; (add-hook 'python-mode-hook
|
;; (add-hook 'python-mode-hook
|
||||||
;; (lambda () (setq forward-sexp-function nil)))
|
;; (lambda () (setq forward-sexp-function nil)))
|
||||||
|
|
||||||
;; Shell interaction: is provided and allows you to execute easily any
|
;; Shell interaction: is provided and allows opening Python shells
|
||||||
;; block of code of your current buffer in an inferior Python process.
|
;; 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
|
;; Shell completion: hitting tab will try to complete the current
|
||||||
;; word. Shell completion is implemented in a manner that if you
|
;; word. Shell completion is implemented in such way that if you
|
||||||
;; change the `python-shell-interpreter' to any other (for example
|
;; change the `python-shell-interpreter' it should be possible to
|
||||||
;; IPython) it should be easy to integrate another way to calculate
|
;; integrate custom logic to calculate completions. To achieve this
|
||||||
;; completions. You just need to specify your custom
|
;; you just need to set `python-shell-completion-setup-code' and
|
||||||
;; `python-shell-completion-setup-code' and
|
;; `python-shell-completion-string-code'. The default provided code,
|
||||||
;; `python-shell-completion-string-code'.
|
;; enables autocompletion for both CPython and IPython (and ideally
|
||||||
|
;; any readline based Python shell). This code depends on the
|
||||||
;; 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
|
|
||||||
;; readline module, so if you are using some Operating System that
|
;; readline module, so if you are using some Operating System that
|
||||||
;; bundles Python without it (like Windows) just install the
|
;; bundles Python without it (like Windows), installing pyreadline
|
||||||
;; pyreadline from http://ipython.scipy.org/moin/PyReadline/Intro and
|
;; from URL `http://ipython.scipy.org/moin/PyReadline/Intro' should
|
||||||
;; you should be good to go.
|
;; 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
|
;; Shell virtualenv support: The shell also contains support for
|
||||||
;; virtualenvs and other special environment modifications thanks to
|
;; virtualenvs and other special environment modifications thanks to
|
||||||
@ -211,7 +234,9 @@
|
|||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(require 'ansi-color)
|
(require 'ansi-color)
|
||||||
|
(require 'cl-lib)
|
||||||
(require 'comint)
|
(require 'comint)
|
||||||
|
(require 'json)
|
||||||
|
|
||||||
;; Avoid compiler warnings
|
;; Avoid compiler warnings
|
||||||
(defvar view-return-to-alist)
|
(defvar view-return-to-alist)
|
||||||
@ -1705,33 +1730,60 @@ position, else returns nil."
|
|||||||
:type 'string
|
:type 'string
|
||||||
:group 'python)
|
:group 'python)
|
||||||
|
|
||||||
(defcustom python-shell-prompt-regexp ">>> "
|
(defcustom python-shell-interpreter-interactive-arg "-i"
|
||||||
"Regular expression matching top-level input prompt of Python shell.
|
"Interpreter argument to force it to run interactively."
|
||||||
It should not contain a caret (^) at the beginning."
|
|
||||||
:type 'string
|
:type 'string
|
||||||
:group 'python
|
:version "24.4")
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom python-shell-prompt-block-regexp "[.][.][.] "
|
(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.
|
||||||
|
It should not contain a caret (^) at the beginning."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom python-shell-prompt-block-regexp "\\.\\.\\. "
|
||||||
"Regular expression matching block input prompt of Python shell.
|
"Regular expression matching block input prompt of Python shell.
|
||||||
It should not contain a caret (^) at the beginning."
|
It should not contain a caret (^) at the beginning."
|
||||||
:type 'string
|
:type 'string)
|
||||||
:group 'python
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom python-shell-prompt-output-regexp ""
|
(defcustom python-shell-prompt-output-regexp ""
|
||||||
"Regular expression matching output prompt of Python shell.
|
"Regular expression matching output prompt of Python shell.
|
||||||
It should not contain a caret (^) at the beginning."
|
It should not contain a caret (^) at the beginning."
|
||||||
:type 'string
|
:type 'string)
|
||||||
:group 'python
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
|
(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
|
||||||
"Regular expression matching pdb input prompt of Python shell.
|
"Regular expression matching pdb input prompt of Python shell.
|
||||||
It should not contain a caret (^) at the beginning."
|
It should not contain a caret (^) at the beginning."
|
||||||
:type 'string
|
:type 'string)
|
||||||
:group 'python
|
|
||||||
:safe 'stringp)
|
|
||||||
|
|
||||||
(defcustom python-shell-enable-font-lock t
|
(defcustom python-shell-enable-font-lock t
|
||||||
"Should syntax highlighting be enabled in the Python shell buffer?
|
"Should syntax highlighting be enabled in the Python shell buffer?
|
||||||
@ -1801,6 +1853,167 @@ virtualenv."
|
|||||||
:type '(alist string)
|
:type '(alist string)
|
||||||
:group 'python)
|
: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)
|
(defun python-shell-get-process-name (dedicated)
|
||||||
"Calculate the appropriate process name for inferior Python process.
|
"Calculate the appropriate process name for inferior Python process.
|
||||||
If DEDICATED is t and the variable `buffer-file-name' is non-nil
|
If DEDICATED is t and the variable `buffer-file-name' is non-nil
|
||||||
@ -1823,10 +2036,10 @@ uniqueness for different types of configurations."
|
|||||||
python-shell-internal-buffer-name
|
python-shell-internal-buffer-name
|
||||||
(md5
|
(md5
|
||||||
(concat
|
(concat
|
||||||
(python-shell-parse-command)
|
python-shell-interpreter
|
||||||
python-shell-prompt-regexp
|
python-shell-interpreter-args
|
||||||
python-shell-prompt-block-regexp
|
python-shell--prompt-calculated-input-regexp
|
||||||
python-shell-prompt-output-regexp
|
python-shell--prompt-calculated-output-regexp
|
||||||
(mapconcat #'symbol-value python-shell-setup-codes "")
|
(mapconcat #'symbol-value python-shell-setup-codes "")
|
||||||
(mapconcat #'identity python-shell-process-environment "")
|
(mapconcat #'identity python-shell-process-environment "")
|
||||||
(mapconcat #'identity python-shell-extra-pythonpaths "")
|
(mapconcat #'identity python-shell-extra-pythonpaths "")
|
||||||
@ -1920,12 +2133,19 @@ initialization of the interpreter via `python-shell-setup-codes'
|
|||||||
variable.
|
variable.
|
||||||
|
|
||||||
\(Type \\[describe-mode] in the process buffer for a list of commands.)"
|
\(Type \\[describe-mode] in the process buffer for a list of commands.)"
|
||||||
(and python-shell--parent-buffer
|
(let ((interpreter python-shell-interpreter)
|
||||||
(python-util-clone-local-variables python-shell--parent-buffer))
|
(args python-shell-interpreter-args))
|
||||||
(setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)"
|
(when python-shell--parent-buffer
|
||||||
python-shell-prompt-regexp
|
(python-util-clone-local-variables python-shell--parent-buffer))
|
||||||
python-shell-prompt-block-regexp
|
;; Users can override default values for these vars when calling
|
||||||
python-shell-prompt-pdb-regexp))
|
;; `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"))
|
(setq mode-line-process '(":%s"))
|
||||||
(make-local-variable 'comint-output-filter-functions)
|
(make-local-variable 'comint-output-filter-functions)
|
||||||
(add-hook 'comint-output-filter-functions
|
(add-hook 'comint-output-filter-functions
|
||||||
@ -1988,10 +2208,20 @@ killed."
|
|||||||
(exec-path (python-shell-calculate-exec-path)))
|
(exec-path (python-shell-calculate-exec-path)))
|
||||||
(when (not (comint-check-proc proc-buffer-name))
|
(when (not (comint-check-proc proc-buffer-name))
|
||||||
(let* ((cmdlist (split-string-and-unquote cmd))
|
(let* ((cmdlist (split-string-and-unquote cmd))
|
||||||
|
(interpreter (car cmdlist))
|
||||||
|
(args (cdr cmdlist))
|
||||||
(buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
|
(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))
|
(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
|
(with-current-buffer buffer
|
||||||
(inferior-python-mode))
|
(inferior-python-mode))
|
||||||
(accept-process-output process)
|
(accept-process-output process)
|
||||||
@ -2063,8 +2293,12 @@ startup."
|
|||||||
"Return inferior Python process for current buffer."
|
"Return inferior Python process for current buffer."
|
||||||
(get-buffer-process (python-shell-get-buffer)))
|
(get-buffer-process (python-shell-get-buffer)))
|
||||||
|
|
||||||
(defun python-shell-get-or-create-process ()
|
(defun python-shell-get-or-create-process (&optional cmd dedicated show)
|
||||||
"Get or create an inferior Python process for current buffer and return it."
|
"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))
|
(let* ((dedicated-proc-name (python-shell-get-process-name t))
|
||||||
(dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
|
(dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
|
||||||
(global-proc-name (python-shell-get-process-name nil))
|
(global-proc-name (python-shell-get-process-name nil))
|
||||||
@ -2072,7 +2306,11 @@ startup."
|
|||||||
(dedicated-running (comint-check-proc dedicated-proc-buffer-name))
|
(dedicated-running (comint-check-proc dedicated-proc-buffer-name))
|
||||||
(global-running (comint-check-proc global-proc-buffer-name)))
|
(global-running (comint-check-proc global-proc-buffer-name)))
|
||||||
(when (and (not dedicated-running) (not global-running))
|
(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 dedicated-running t)
|
||||||
(setq global-running t)))
|
(setq global-running t)))
|
||||||
;; Always prefer dedicated
|
;; Always prefer dedicated
|
||||||
@ -2155,10 +2393,13 @@ detecting a prompt at the end of the buffer."
|
|||||||
(when (string-match
|
(when (string-match
|
||||||
;; XXX: It seems on OSX an extra carriage return is attached
|
;; XXX: It seems on OSX an extra carriage return is attached
|
||||||
;; at the end of output, this handles that too.
|
;; at the end of output, this handles that too.
|
||||||
(format "\r?\n\\(?:%s\\|%s\\|%s\\)$"
|
(concat
|
||||||
python-shell-prompt-regexp
|
"\r?\n"
|
||||||
python-shell-prompt-block-regexp
|
;; Remove initial caret from calculated regexp
|
||||||
python-shell-prompt-pdb-regexp)
|
(replace-regexp-in-string
|
||||||
|
(rx string-start ?^) ""
|
||||||
|
python-shell--prompt-calculated-input-regexp)
|
||||||
|
"$")
|
||||||
python-shell-output-filter-buffer)
|
python-shell-output-filter-buffer)
|
||||||
;; Output ends when `python-shell-output-filter-buffer' contains
|
;; Output ends when `python-shell-output-filter-buffer' contains
|
||||||
;; the prompt attached at the end of it.
|
;; the prompt attached at the end of it.
|
||||||
@ -2166,10 +2407,10 @@ detecting a prompt at the end of the buffer."
|
|||||||
python-shell-output-filter-buffer
|
python-shell-output-filter-buffer
|
||||||
(substring python-shell-output-filter-buffer
|
(substring python-shell-output-filter-buffer
|
||||||
0 (match-beginning 0)))
|
0 (match-beginning 0)))
|
||||||
(when (and (> (length python-shell-prompt-output-regexp) 0)
|
(when (string-match
|
||||||
(string-match (concat "^" python-shell-prompt-output-regexp)
|
python-shell--prompt-calculated-output-regexp
|
||||||
python-shell-output-filter-buffer))
|
python-shell-output-filter-buffer)
|
||||||
;; Some shells, like iPython might append a prompt before the
|
;; Some shells, like IPython might append a prompt before the
|
||||||
;; output, clean that.
|
;; output, clean that.
|
||||||
(setq python-shell-output-filter-buffer
|
(setq python-shell-output-filter-buffer
|
||||||
(substring python-shell-output-filter-buffer (match-end 0)))))
|
(substring python-shell-output-filter-buffer (match-end 0)))))
|
||||||
@ -2379,23 +2620,35 @@ This function takes the list of setup code to send from the
|
|||||||
|
|
||||||
(defcustom python-shell-completion-setup-code
|
(defcustom python-shell-completion-setup-code
|
||||||
"try:
|
"try:
|
||||||
import readline
|
import readline, rlcompleter
|
||||||
except ImportError:
|
except ImportError:
|
||||||
def __COMPLETER_all_completions(text): []
|
def __PYTHON_EL_get_completions(text):
|
||||||
|
return []
|
||||||
else:
|
else:
|
||||||
import rlcompleter
|
def __PYTHON_EL_get_completions(text):
|
||||||
readline.set_completer(rlcompleter.Completer().complete)
|
|
||||||
def __COMPLETER_all_completions(text):
|
|
||||||
import sys
|
|
||||||
completions = []
|
completions = []
|
||||||
try:
|
try:
|
||||||
i = 0
|
splits = text.split()
|
||||||
while True:
|
is_module = splits and splits[0] in ('from', 'import')
|
||||||
res = readline.get_completer()(text, i)
|
is_ipython = getattr(
|
||||||
if not res: break
|
__builtins__, '__IPYTHON__',
|
||||||
i += 1
|
getattr(__builtins__, '__IPYTHON__active', False))
|
||||||
completions.append(res)
|
if is_module:
|
||||||
except NameError:
|
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
|
pass
|
||||||
return completions"
|
return completions"
|
||||||
"Code used to setup completion in inferior Python processes."
|
"Code used to setup completion in inferior Python processes."
|
||||||
@ -2403,24 +2656,18 @@ else:
|
|||||||
:group 'python)
|
:group 'python)
|
||||||
|
|
||||||
(defcustom python-shell-completion-string-code
|
(defcustom python-shell-completion-string-code
|
||||||
"';'.join(__COMPLETER_all_completions('''%s'''))\n"
|
"';'.join(__PYTHON_EL_get_completions('''%s'''))\n"
|
||||||
"Python code used to get a string of completions separated by semicolons."
|
"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
|
:type 'string
|
||||||
:group 'python)
|
:group 'python)
|
||||||
|
|
||||||
(defcustom python-shell-completion-module-string-code ""
|
(define-obsolete-variable-alias
|
||||||
"Python code used to get completions separated by semicolons for imports.
|
'python-shell-completion-module-string-code
|
||||||
|
'python-shell-completion-string-code
|
||||||
For IPython v0.11, add the following line to
|
"24.4"
|
||||||
`python-shell-completion-setup-code':
|
"Completion string code must also autocomplete modules.")
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
(defcustom python-shell-completion-pdb-string-code
|
(defcustom python-shell-completion-pdb-string-code
|
||||||
"';'.join(globals().keys() + locals().keys())"
|
"';'.join(globals().keys() + locals().keys())"
|
||||||
@ -2443,33 +2690,23 @@ LINE is used to detect the context on how to complete given INPUT."
|
|||||||
(re-search-backward "^")
|
(re-search-backward "^")
|
||||||
(python-util-forward-comment)
|
(python-util-forward-comment)
|
||||||
(point))))))
|
(point))))))
|
||||||
(completion-context
|
(completion-code
|
||||||
;; Check whether a prompt matches a pdb string, an import
|
;; Check whether a prompt matches a pdb string, an import
|
||||||
;; statement or just the standard prompt and use the
|
;; statement or just the standard prompt and use the
|
||||||
;; correct python-shell-completion-*-code string
|
;; correct python-shell-completion-*-code string
|
||||||
(cond ((and (> (length python-shell-completion-pdb-string-code) 0)
|
(cond ((and (> (length python-shell-completion-pdb-string-code) 0)
|
||||||
(string-match
|
(string-match
|
||||||
(concat "^" python-shell-prompt-pdb-regexp) prompt))
|
(concat "^" python-shell-prompt-pdb-regexp) prompt))
|
||||||
'pdb)
|
python-shell-completion-pdb-string-code)
|
||||||
((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)
|
|
||||||
((string-match
|
((string-match
|
||||||
(concat "^" python-shell-prompt-regexp) prompt)
|
python-shell--prompt-calculated-input-regexp prompt)
|
||||||
'default)
|
python-shell-completion-string-code)
|
||||||
(t nil)))
|
(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
|
(input
|
||||||
(if (eq completion-context 'import)
|
(if (string-match
|
||||||
(replace-regexp-in-string "^[ \t]+" "" line)
|
(python-rx (+ space) (or "from" "import") space)
|
||||||
|
line)
|
||||||
|
line
|
||||||
input)))
|
input)))
|
||||||
(and completion-code
|
(and completion-code
|
||||||
(> (length input) 0)
|
(> (length input) 0)
|
||||||
@ -3710,6 +3947,10 @@ returned as is."
|
|||||||
""
|
""
|
||||||
string))
|
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 ()
|
(defun python-electric-pair-string-delimiter ()
|
||||||
(when (and electric-pair-mode
|
(when (and electric-pair-mode
|
||||||
@ -3794,8 +4035,6 @@ returned as is."
|
|||||||
,(lambda (_arg)
|
,(lambda (_arg)
|
||||||
(python-nav-end-of-defun)) nil))
|
(python-nav-end-of-defun)) nil))
|
||||||
|
|
||||||
(set (make-local-variable 'mode-require-final-newline) t)
|
|
||||||
|
|
||||||
(set (make-local-variable 'outline-regexp)
|
(set (make-local-variable 'outline-regexp)
|
||||||
(python-rx (* space) block-start))
|
(python-rx (* space) block-start))
|
||||||
(set (make-local-variable 'outline-heading-end-regexp) ":[^\n]*\n")
|
(set (make-local-variable 'outline-heading-end-regexp) ":[^\n]*\n")
|
||||||
|
@ -491,12 +491,12 @@ Entry to view-mode runs the normal hook `view-mode-hook'."
|
|||||||
(defun view--disable ()
|
(defun view--disable ()
|
||||||
(remove-hook 'change-major-mode-hook 'view--disable t)
|
(remove-hook 'change-major-mode-hook 'view--disable t)
|
||||||
(and view-overlay (delete-overlay view-overlay))
|
(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
|
;; 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.
|
;; will reenable View mode.
|
||||||
;; Canceling View mode in any other way should cancel that, too,
|
;; 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)
|
(if (local-variable-p 'view-read-only)
|
||||||
(kill-local-variable 'view-read-only))
|
(kill-local-variable 'view-read-only))
|
||||||
(if (boundp 'Helper-return-blurb)
|
(if (boundp 'Helper-return-blurb)
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
2014-07-21 Jan Djärv <jan.h.d@swipnet.se>
|
||||||
|
|
||||||
|
* 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 <eliz@gnu.org>
|
||||||
|
|
||||||
|
* w32select.c (setup_windows_coding_system): Apply
|
||||||
|
CODING_ANNOTATION_MASK to the common_flags member of struct
|
||||||
|
coding_system. Reported by martin rudalics <rudalics@gmx.at>.
|
||||||
|
|
||||||
|
* 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 <rudalics@gmx.at>.
|
||||||
|
|
||||||
|
* 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 <dmantipov@yandex.ru>
|
2014-07-20 Dmitry Antipov <dmantipov@yandex.ru>
|
||||||
|
|
||||||
* frame.h (struct frame) [USE_X_TOOLKIT]: New member shell_position.
|
* frame.h (struct frame) [USE_X_TOOLKIT]: New member shell_position.
|
||||||
|
@ -144,4 +144,5 @@ typedef const struct _EmacsScreenFont *ScreenFontRef; /* opaque */
|
|||||||
|
|
||||||
extern void mac_register_font_driver (struct frame *f);
|
extern void mac_register_font_driver (struct frame *f);
|
||||||
extern void *macfont_get_nsctfont (struct font *font);
|
extern void *macfont_get_nsctfont (struct font *font);
|
||||||
|
extern void macfont_update_antialias_threshold (void);
|
||||||
|
|
||||||
|
@ -728,7 +728,7 @@ static void mac_font_get_glyphs_for_variants (CFDataRef, UTF32Char,
|
|||||||
|
|
||||||
static CGFloat macfont_antialias_threshold;
|
static CGFloat macfont_antialias_threshold;
|
||||||
|
|
||||||
static void
|
void
|
||||||
macfont_update_antialias_threshold (void)
|
macfont_update_antialias_threshold (void)
|
||||||
{
|
{
|
||||||
int threshold;
|
int threshold;
|
||||||
|
@ -111,6 +111,7 @@ typedef float EmacsCGFloat;
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
- (void)logNotification: (NSNotification *)notification;
|
- (void)logNotification: (NSNotification *)notification;
|
||||||
|
- (void)antialiasThresholdDidChange:(NSNotification *)notification;
|
||||||
- (void)sendEvent: (NSEvent *)theEvent;
|
- (void)sendEvent: (NSEvent *)theEvent;
|
||||||
- (void)showPreferencesWindow: (id)sender;
|
- (void)showPreferencesWindow: (id)sender;
|
||||||
- (BOOL) openFile: (NSString *)fileName;
|
- (BOOL) openFile: (NSString *)fileName;
|
||||||
|
21
src/nsterm.m
21
src/nsterm.m
@ -4670,9 +4670,30 @@ - (void)applicationDidFinishLaunching: (NSNotification *)notification
|
|||||||
((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES;
|
((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES;
|
||||||
#endif
|
#endif
|
||||||
[NSApp setServicesProvider: NSApp];
|
[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);
|
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:
|
/* Termination sequences:
|
||||||
C-x C-c:
|
C-x C-c:
|
||||||
|
@ -600,7 +600,7 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat
|
|||||||
coding.mode |= CODING_MODE_LAST_BLOCK;
|
coding.mode |= CODING_MODE_LAST_BLOCK;
|
||||||
/* We explicitly disable composition handling because selection
|
/* We explicitly disable composition handling because selection
|
||||||
data should not contain any composition sequence. */
|
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);
|
decode_coding_object (&coding, Qnil, 0, 0, truelen, truelen, Qt);
|
||||||
ret = coding.dst_object;
|
ret = coding.dst_object;
|
||||||
Vlast_coding_system_used = CODING_ID_NAME (coding.id);
|
Vlast_coding_system_used = CODING_ID_NAME (coding.id);
|
||||||
|
@ -670,7 +670,7 @@ setup_windows_coding_system (Lisp_Object coding_system,
|
|||||||
which both apply to ISO6429 only. We don't know if these really
|
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
|
need to be unset on Windows, but it probably doesn't hurt
|
||||||
either. */
|
either. */
|
||||||
coding->mode &= ~CODING_ANNOTATION_MASK;
|
coding->common_flags &= ~CODING_ANNOTATION_MASK;
|
||||||
coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
|
coding->mode |= CODING_MODE_LAST_BLOCK | CODING_MODE_SAFE_ENCODING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
src/xdisp.c
31
src/xdisp.c
@ -3034,6 +3034,7 @@ init_iterator (struct it *it, struct window *w,
|
|||||||
getting overlays and face properties from that position. */
|
getting overlays and face properties from that position. */
|
||||||
if (charpos >= BUF_BEG (current_buffer))
|
if (charpos >= BUF_BEG (current_buffer))
|
||||||
{
|
{
|
||||||
|
it->stop_charpos = charpos;
|
||||||
it->end_charpos = ZV;
|
it->end_charpos = ZV;
|
||||||
eassert (charpos == BYTE_TO_CHAR (bytepos));
|
eassert (charpos == BYTE_TO_CHAR (bytepos));
|
||||||
IT_CHARPOS (*it) = charpos;
|
IT_CHARPOS (*it) = charpos;
|
||||||
@ -4546,7 +4547,24 @@ handle_invisible_prop (struct it *it)
|
|||||||
&& get_overlay_strings (it, it->stop_charpos))
|
&& get_overlay_strings (it, it->stop_charpos))
|
||||||
{
|
{
|
||||||
handled = HANDLED_RECOMPUTE_PROPS;
|
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)
|
else if (display_ellipsis_p)
|
||||||
{
|
{
|
||||||
@ -9351,7 +9369,7 @@ move_it_vertically_backward (struct it *it, int dy)
|
|||||||
|
|
||||||
/* Estimate how many newlines we must move back. */
|
/* Estimate how many newlines we must move back. */
|
||||||
nlines = max (1, dy / default_line_pixel_height (it->w));
|
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;
|
pos_limit = BEGV;
|
||||||
else
|
else
|
||||||
pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
|
pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
|
||||||
@ -9606,7 +9624,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
|
|||||||
/* Go back -DVPOS buffer lines, but no farther than -DVPOS full
|
/* Go back -DVPOS buffer lines, but no farther than -DVPOS full
|
||||||
screen lines, and reseat the iterator there. */
|
screen lines, and reseat the iterator there. */
|
||||||
start_charpos = IT_CHARPOS (*it);
|
start_charpos = IT_CHARPOS (*it);
|
||||||
if (it->line_wrap == TRUNCATE)
|
if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
|
||||||
pos_limit = BEGV;
|
pos_limit = BEGV;
|
||||||
else
|
else
|
||||||
pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
|
pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
|
||||||
@ -12847,6 +12865,13 @@ hscroll_window_tree (Lisp_Object window)
|
|||||||
h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
|
h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
|
||||||
|
|
||||||
if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
|
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
|
/* For left-to-right rows, hscroll when cursor is either
|
||||||
(i) inside the right hscroll margin, or (ii) if it is
|
(i) inside the right hscroll margin, or (ii) if it is
|
||||||
inside the left margin and the window is already
|
inside the left margin and the window is already
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
2014-07-21 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||||
|
|
||||||
|
* 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 <monnier@iro.umontreal.ca>
|
2014-07-21 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||||
|
|
||||||
* automated/advice-tests.el (advice-test-call-interactively): Make sure
|
* automated/advice-tests.el (advice-test-call-interactively): Make sure
|
||||||
@ -48,7 +82,7 @@
|
|||||||
|
|
||||||
* automated/python-tests.el (python-tests-self-insert): New function.
|
* automated/python-tests.el (python-tests-self-insert): New function.
|
||||||
(python-triple-quote-pairing): Use it.
|
(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 <fgallina@gnu.org>
|
2014-06-30 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||||
|
|
||||||
|
@ -1773,8 +1773,8 @@ Using `python-shell-interpreter' and
|
|||||||
(proc-name (python-shell-get-process-name nil))
|
(proc-name (python-shell-get-process-name nil))
|
||||||
(shell-buffer
|
(shell-buffer
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"" (python-shell-make-comint
|
"" (python-shell-make-comint
|
||||||
(python-shell-parse-command) proc-name)))
|
(python-shell-parse-command) proc-name)))
|
||||||
(process (get-buffer-process shell-buffer)))
|
(process (get-buffer-process shell-buffer)))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(progn
|
(progn
|
||||||
@ -1794,8 +1794,8 @@ Using `python-shell-interpreter' and
|
|||||||
(proc-name (python-shell-internal-get-process-name))
|
(proc-name (python-shell-internal-get-process-name))
|
||||||
(shell-buffer
|
(shell-buffer
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
"" (python-shell-make-comint
|
"" (python-shell-make-comint
|
||||||
(python-shell-parse-command) proc-name nil t)))
|
(python-shell-parse-command) proc-name nil t)))
|
||||||
(process (get-buffer-process shell-buffer)))
|
(process (get-buffer-process shell-buffer)))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(progn
|
(progn
|
||||||
@ -1806,6 +1806,79 @@ Using `python-shell-interpreter' and
|
|||||||
(should (string= (buffer-name) (format " *%s*" proc-name)))))
|
(should (string= (buffer-name) (format " *%s*" proc-name)))))
|
||||||
(kill-buffer shell-buffer))))
|
(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 ()
|
(ert-deftest python-shell-get-process-1 ()
|
||||||
"Check dedicated shell process preference over global."
|
"Check dedicated shell process preference over global."
|
||||||
(skip-unless (executable-find python-tests-shell-interpreter))
|
(skip-unless (executable-find python-tests-shell-interpreter))
|
||||||
@ -1840,54 +1913,370 @@ Using `python-shell-interpreter' and
|
|||||||
(ignore-errors (kill-buffer dedicated-shell-buffer))))))
|
(ignore-errors (kill-buffer dedicated-shell-buffer))))))
|
||||||
|
|
||||||
(ert-deftest python-shell-get-or-create-process-1 ()
|
(ert-deftest python-shell-get-or-create-process-1 ()
|
||||||
"Check shell process creation fallback."
|
"Check shell dedicated process creation."
|
||||||
:expected-result :failed
|
(skip-unless (executable-find python-tests-shell-interpreter))
|
||||||
(python-tests-with-temp-file
|
(python-tests-with-temp-file
|
||||||
""
|
""
|
||||||
;; XXX: Break early until we can skip stuff. We need to mimic
|
(let* ((python-shell-interpreter
|
||||||
;; user interaction because `python-shell-get-or-create-process'
|
(executable-find python-tests-shell-interpreter))
|
||||||
;; asks for all arguments interactively when a shell process
|
(use-dialog-box)
|
||||||
;; doesn't exist.
|
(dedicated-process-name (python-shell-get-process-name t))
|
||||||
(should nil)
|
(dedicated-process
|
||||||
(let* ((python-shell-interpreter
|
(python-shell-get-or-create-process python-shell-interpreter t))
|
||||||
(executable-find python-tests-shell-interpreter))
|
(dedicated-shell-buffer (process-buffer dedicated-process)))
|
||||||
(use-dialog-box)
|
(unwind-protect
|
||||||
(dedicated-process-name (python-shell-get-process-name t))
|
(progn
|
||||||
(dedicated-process (python-shell-get-or-create-process))
|
(set-process-query-on-exit-flag dedicated-process nil)
|
||||||
(dedicated-shell-buffer (process-buffer dedicated-process)))
|
;; should be dedicated.
|
||||||
(unwind-protect
|
(should (equal (process-name dedicated-process)
|
||||||
(progn
|
dedicated-process-name))
|
||||||
(set-process-query-on-exit-flag dedicated-process nil)
|
(kill-buffer dedicated-shell-buffer)
|
||||||
;; Prefer dedicated if not buffer exist.
|
;; Check there are no processes for current buffer.
|
||||||
(should (equal (process-name dedicated-process)
|
(should (not (python-shell-get-process))))
|
||||||
dedicated-process-name))
|
(ignore-errors (kill-buffer dedicated-shell-buffer))))))
|
||||||
(kill-buffer dedicated-shell-buffer)
|
|
||||||
;; No buffer available.
|
(ert-deftest python-shell-get-or-create-process-2 ()
|
||||||
(should (not (python-shell-get-process))))
|
"Check shell global process creation."
|
||||||
(ignore-errors (kill-buffer dedicated-shell-buffer))))))
|
(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 ()
|
(ert-deftest python-shell-internal-get-or-create-process-1 ()
|
||||||
"Check internal shell process creation fallback."
|
"Check internal shell process creation fallback."
|
||||||
(skip-unless (executable-find python-tests-shell-interpreter))
|
(skip-unless (executable-find python-tests-shell-interpreter))
|
||||||
(python-tests-with-temp-file
|
(python-tests-with-temp-file
|
||||||
""
|
""
|
||||||
(should (not (process-live-p (python-shell-internal-get-process-name))))
|
(should (not (process-live-p (python-shell-internal-get-process-name))))
|
||||||
(let* ((python-shell-interpreter
|
(let* ((python-shell-interpreter
|
||||||
(executable-find python-tests-shell-interpreter))
|
(executable-find python-tests-shell-interpreter))
|
||||||
(internal-process-name (python-shell-internal-get-process-name))
|
(internal-process-name (python-shell-internal-get-process-name))
|
||||||
(internal-process (python-shell-internal-get-or-create-process))
|
(internal-process (python-shell-internal-get-or-create-process))
|
||||||
(internal-shell-buffer (process-buffer internal-process)))
|
(internal-shell-buffer (process-buffer internal-process)))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(progn
|
(progn
|
||||||
(set-process-query-on-exit-flag internal-process nil)
|
(set-process-query-on-exit-flag internal-process nil)
|
||||||
(should (equal (process-name internal-process)
|
(should (equal (process-name internal-process)
|
||||||
internal-process-name))
|
internal-process-name))
|
||||||
(should (equal internal-process
|
(should (equal internal-process
|
||||||
(python-shell-internal-get-or-create-process)))
|
(python-shell-internal-get-or-create-process)))
|
||||||
;; No user buffer available.
|
;; Assert the internal process is not a user process
|
||||||
(should (not (python-shell-get-process)))
|
(should (not (python-shell-get-process)))
|
||||||
(kill-buffer internal-shell-buffer))
|
(kill-buffer internal-shell-buffer))
|
||||||
(ignore-errors (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
|
;;; Shell completion
|
||||||
@ -3230,8 +3619,6 @@ def foo(a, b, c):
|
|||||||
(python-shell-extra-pythonpaths "/home/user/pylib/")
|
(python-shell-extra-pythonpaths "/home/user/pylib/")
|
||||||
(python-shell-completion-setup-code
|
(python-shell-completion-setup-code
|
||||||
. "from IPython.core.completerlib import module_completion")
|
. "from IPython.core.completerlib import module_completion")
|
||||||
(python-shell-completion-module-string-code
|
|
||||||
. "';'.join(module_completion('''%s'''))\n")
|
|
||||||
(python-shell-completion-string-code
|
(python-shell-completion-string-code
|
||||||
. "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
|
. "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
|
||||||
(python-shell-virtualenv-path
|
(python-shell-virtualenv-path
|
||||||
@ -3269,6 +3656,11 @@ def foo(a, b, c):
|
|||||||
(python-util-forward-comment -1)
|
(python-util-forward-comment -1)
|
||||||
(should (= (point) (point-min)))))
|
(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
|
;;; Electricity
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user