Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a97a3f3

Browse files
committed
First round of changes, mostly subprocess stuff.
(py-execute-file): Better interaction with comint. Set comint-scroll-to-bottom-on-output to t. Wrapper buffer change in unwind-protect in case process filter fails. (py-shell): Start Python with -i flag to fix tty problem on Windows; presumably -- not yet tested. (py-clear-queue): New function to clear the pending exec file queue. Not currently keybound. (py-execute-region, py-execute-buffer): Added optional async flag (use via C-u prefix) to execute the region in a new asynchrous buffer, even if the Python shell is running. (py-append-to-process-buffer): Removed as obsolete. Comint provides this functionality. Removed fbound test defun of match-string. All modern X/Emacsen have this function.
1 parent bfa9f13 commit a97a3f3

1 file changed

Lines changed: 129 additions & 138 deletions

File tree

Misc/python-mode.el

Lines changed: 129 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44

55
;; Author: 1995-1997 Barry A. Warsaw
66
;; 1992-1994 Tim Peters
7-
;; Maintainer: [email protected]
8-
;; Created: Feb 1992
9-
;; Version: 3.0
10-
;; Keywords: python languages oop
7+
;; Maintainer: [email protected]
8+
;; Created: Feb 1992
9+
;; Keywords: python languages oop
1110

1211
(defconst py-version "3.0"
1312
"`python-mode' version number.")
@@ -32,10 +31,10 @@
3231

3332
;; python-mode.el is currently distributed with XEmacs 19 and XEmacs
3433
;; 20. Since this file is not GPL'd it is not distributed with Emacs,
35-
;; but it is compatible with the EOL 19 series and current 20 series
36-
;; Emacsen. By default, in XEmacs when you visit a .py file, it is
37-
;; put in Python mode. In Emacs, you need to add the following to
38-
;; your .emacs file (you don't need this for XEmacs):
34+
;; but it is compatible with 19.34 and the current 20 series Emacsen.
35+
;; By default, in XEmacs when you visit a .py file, it is put in
36+
;; Python mode. In Emacs, you need to add the following to your
37+
;; .emacs file (you don't need this for XEmacs):
3938
;;
4039
;; (autoload 'python-mode "python-mode" "Python editing mode." t)
4140
;; (setq auto-mode-alist
@@ -854,110 +853,32 @@ Electric behavior is inhibited inside a string or comment."
854853
)))))
855854

856855

857-
;;; Functions that execute Python commands in a subprocess
858-
;;;###autoload
859-
(defun py-shell ()
860-
"Start an interactive Python interpreter in another window.
861-
This is like Shell mode, except that Python is running in the window
862-
instead of a shell. See the `Interactive Shell' and `Shell Mode'
863-
sections of the Emacs manual for details, especially for the key
864-
bindings active in the `*Python*' buffer.
865-
866-
See the docs for variable `py-scroll-buffer' for info on scrolling
867-
behavior in the process window.
868-
869-
Warning: Don't use an interactive Python if you change sys.ps1 or
870-
sys.ps2 from their default values, or if you're running code that
871-
prints `>>> ' or `... ' at the start of a line. `python-mode' can't
872-
distinguish your output from Python's output, and assumes that `>>> '
873-
at the start of a line is a prompt from Python. Similarly, the Emacs
874-
Shell mode code assumes that both `>>> ' and `... ' at the start of a
875-
line are Python prompts. Bad things can happen if you fool either
876-
mode.
877-
878-
Warning: If you do any editing *in* the process buffer *while* the
879-
buffer is accepting output from Python, do NOT attempt to `undo' the
880-
changes. Some of the output (nowhere near the parts you changed!) may
881-
be lost if you do. This appears to be an Emacs bug, an unfortunate
882-
interaction between undo and process filters; the same problem exists in
883-
non-Python process buffers using the default (Emacs-supplied) process
884-
filter."
885-
;; BAW - should undo be disabled in the python process buffer, if
886-
;; this bug still exists?
887-
(interactive)
888-
(require 'comint)
889-
(switch-to-buffer-other-window (make-comint "Python" py-python-command))
890-
(make-local-variable 'comint-prompt-regexp)
891-
(setq comint-prompt-regexp "^>>> \\|^[.][.][.] ")
892-
(set-process-filter (get-buffer-process (current-buffer)) nil)
893-
(set-syntax-table py-mode-syntax-table)
894-
(local-set-key [tab] 'self-insert-command))
895-
896-
(defun py-execute-region (start end)
897-
"Send the region between START and END to a Python interpreter.
898-
If there is a *Python* process it is used.
899-
900-
Hint: If you want to execute part of a Python file several times
901-
\(e.g., perhaps you're developing a function and want to flesh it out
902-
a bit at a time), use `\\[narrow-to-region]' to restrict the buffer to
903-
the region of interest, and send the code to a *Python* process via
904-
`\\[py-execute-buffer]' instead.
905-
906-
Following are subtleties to note when using a *Python* process:
907-
908-
If a *Python* process is used, the region is copied into a temporary
909-
file (in directory `py-temp-directory'), and an `execfile' command is
910-
sent to Python naming that file. If you send regions faster than
911-
Python can execute them, `python-mode' will save them into distinct
912-
temp files, and execute the next one in the queue the next time it
913-
sees a `>>> ' prompt from Python. Each time this happens, the process
914-
buffer is popped into a window (if it's not already in some window) so
915-
you can see it, and a comment of the form
916-
917-
\t## working on region in file <name> ...
918-
919-
is inserted at the end.
920-
921-
Caution: No more than 26 regions can be pending at any given time.
922-
This limit is (indirectly) inherited from libc's mktemp(3).
923-
`python-mode' does not try to protect you from exceeding the limit.
924-
It's extremely unlikely that you'll get anywhere close to the limit in
925-
practice, unless you're trying to be a jerk <grin>.
926-
927-
See the `\\[py-shell]' docs for additional warnings."
928-
(interactive "r")
929-
(or (< start end)
930-
(error "Region is empty"))
931-
(let ((pyproc (get-process "Python"))
932-
fname)
933-
(if (null pyproc)
934-
(let ((outbuf "*Python Output*"))
935-
(shell-command-on-region start end py-python-command outbuf)
936-
(save-excursion
937-
(set-buffer outbuf)
938-
;; TBD: ???
939-
(goto-char (point-max))))
940-
;; else feed it thru a temp file
941-
(setq fname (py-make-temp-name))
942-
(write-region start end fname nil 'no-msg)
943-
(setq py-file-queue (append py-file-queue (list fname)))
944-
(if (cdr py-file-queue)
945-
(message "File %s queued for execution" fname)
946-
;; else
947-
(py-execute-file pyproc fname)))))
948-
949-
(defun py-execute-file (pyproc fname)
950-
(py-append-to-process-buffer
951-
pyproc
952-
(format "## working on region in file %s ...\n" fname))
953-
(process-send-string pyproc (format "execfile('%s')\n" fname)))
856+
;; Python subprocess utilities and filters
857+
(defun py-execute-file (proc filename)
858+
;; Send a properly formatted execfile('FILENAME') to the underlying
859+
;; Python interpreter process FILENAME. Make that process's buffer
860+
;; visible and force display. Also make comint believe the user
861+
;; typed this string so that kill-output-from-shell does The Right
862+
;; Thing.
863+
(let ((curbuf (current-buffer))
864+
(procbuf (process-buffer proc))
865+
(comint-scroll-to-bottom-on-output t)
866+
(msg (format "## working on region in file %s...\n" filename))
867+
(cmd (format "execfile('%s')\n" filename)))
868+
(unwind-protect
869+
(progn
870+
(set-buffer procbuf)
871+
(goto-char (point-max))
872+
(move-marker (process-mark proc) (point))
873+
(funcall (process-filter proc) proc msg))
874+
(set-buffer curbuf))
875+
(process-send-string proc cmd)))
954876

955877
(defun py-process-filter (pyproc string)
956878
(let ((curbuf (current-buffer))
957879
(pbuf (process-buffer pyproc))
958880
(pmark (process-mark pyproc))
959881
file-finished)
960-
961882
;; make sure we switch to a different buffer at least once. if we
962883
;; *don't* do this, then if the process buffer is in the selected
963884
;; window, and point is before the end, and lots of output is
@@ -1017,16 +938,114 @@ See the `\\[py-shell]' docs for additional warnings."
1017938
))
1018939
(set-buffer curbuf))))
1019940

1020-
(defun py-execute-buffer ()
941+
942+
;;; Subprocess commands
943+
944+
;;;###autoload
945+
(defun py-shell ()
946+
"Start an interactive Python interpreter in another window.
947+
This is like Shell mode, except that Python is running in the window
948+
instead of a shell. See the `Interactive Shell' and `Shell Mode'
949+
sections of the Emacs manual for details, especially for the key
950+
bindings active in the `*Python*' buffer.
951+
952+
See the docs for variable `py-scroll-buffer' for info on scrolling
953+
behavior in the process window.
954+
955+
Warning: Don't use an interactive Python if you change sys.ps1 or
956+
sys.ps2 from their default values, or if you're running code that
957+
prints `>>> ' or `... ' at the start of a line. `python-mode' can't
958+
distinguish your output from Python's output, and assumes that `>>> '
959+
at the start of a line is a prompt from Python. Similarly, the Emacs
960+
Shell mode code assumes that both `>>> ' and `... ' at the start of a
961+
line are Python prompts. Bad things can happen if you fool either
962+
mode.
963+
964+
Warning: If you do any editing *in* the process buffer *while* the
965+
buffer is accepting output from Python, do NOT attempt to `undo' the
966+
changes. Some of the output (nowhere near the parts you changed!) may
967+
be lost if you do. This appears to be an Emacs bug, an unfortunate
968+
interaction between undo and process filters; the same problem exists in
969+
non-Python process buffers using the default (Emacs-supplied) process
970+
filter."
971+
;; BAW - should undo be disabled in the python process buffer, if
972+
;; this bug still exists?
973+
(interactive)
974+
(require 'comint)
975+
(switch-to-buffer-other-window (make-comint "Python" py-python-command "-i"))
976+
(make-local-variable 'comint-prompt-regexp)
977+
(setq comint-prompt-regexp "^>>> \\|^[.][.][.] ")
978+
(set-process-filter (get-buffer-process (current-buffer)) 'py-process-filter)
979+
(set-syntax-table py-mode-syntax-table)
980+
(local-set-key [tab] 'self-insert-command))
981+
982+
983+
(defun py-clear-queue ()
984+
"Clear the queue of temporary files waiting to execute."
985+
(interactive)
986+
(let ((n (length py-file-queue)))
987+
(mapcar 'delete-file py-file-queue)
988+
(setq py-file-queue nil)
989+
(message "%d pending files de-queued." n)))
990+
991+
(defun py-execute-region (start end &optional async)
992+
"Execute the the region in a Python interpreter.
993+
The region is first copied into a temporary file (in the directory
994+
`py-temp-directory'). If there is no Python interpreter shell
995+
running, this file is executed synchronously using
996+
`shell-command-on-region'. If the program is long running, use an
997+
optional \\[universal-argument] to run the command asynchronously in
998+
its own buffer.
999+
1000+
If the Python interpreter shell is running, the region is execfile()'d
1001+
in that shell. If you try to execute regions too quickly,
1002+
`python-mode' will queue them up and execute them one at a time when
1003+
it sees a `>>> ' prompt from Python. Each time this happens, the
1004+
process buffer is popped into a window (if it's not already in some
1005+
window) so you can see it, and a comment of the form
1006+
1007+
\t## working on region in file <name>...
1008+
1009+
is inserted at the end. See also the command `py-clear-queue'."
1010+
(interactive "r\nP")
1011+
(or (< start end)
1012+
(error "Region is empty"))
1013+
(let* ((proc (get-process "Python"))
1014+
(temp (make-temp-name "python"))
1015+
(file (concat (file-name-as-directory py-temp-directory) temp))
1016+
(outbuf "*Python Output*"))
1017+
(write-region start end file nil 'nomsg)
1018+
(cond
1019+
;; always run the code in it's own asynchronous subprocess
1020+
(async
1021+
(let* ((buf (generate-new-buffer-name "*Python Output*")))
1022+
(start-process "Python" buf py-python-command "-u" file)
1023+
(pop-to-buffer buf)
1024+
))
1025+
;; if the Python interpreter shell is running, queue it up for
1026+
;; execution there.
1027+
(proc
1028+
;; use the existing python shell
1029+
(if (not py-file-queue)
1030+
(py-execute-file proc file)
1031+
(push file py-file-queue)
1032+
(message "File %s queued for execution" file))
1033+
)
1034+
(t
1035+
;; otherwise either run it synchronously in a subprocess
1036+
(shell-command-on-region start end py-python-command outbuf)
1037+
))))
1038+
1039+
;; Code execution command
1040+
(defun py-execute-buffer (&optional async)
10211041
"Send the contents of the buffer to a Python interpreter.
10221042
If there is a *Python* process buffer it is used. If a clipping
10231043
restriction is in effect, only the accessible portion of the buffer is
10241044
sent. A trailing newline will be supplied if needed.
10251045
10261046
See the `\\[py-execute-region]' docs for an account of some subtleties."
1027-
(interactive)
1028-
(py-execute-region (point-min) (point-max)))
1029-
1047+
(interactive "P")
1048+
(py-execute-region (point-min) (point-max) async))
10301049

10311050

10321051
;; Functions for Python style indentation
@@ -2363,10 +2382,6 @@ local bindings to py-newline-and-indent."))
23632382
(intern (buffer-substring (match-beginning 1) (match-end 1)))
23642383
nil)))
23652384

2366-
(defun py-make-temp-name ()
2367-
(make-temp-name
2368-
(concat (file-name-as-directory py-temp-directory) "python")))
2369-
23702385
(defun py-delete-file-silently (fname)
23712386
(condition-case nil
23722387
(delete-file fname)
@@ -2378,30 +2393,6 @@ local bindings to py-newline-and-indent."))
23782393
(py-delete-file-silently (car py-file-queue))
23792394
(setq py-file-queue (cdr py-file-queue)))))
23802395

2381-
;; make PROCESS's buffer visible, append STRING to it, and force
2382-
;; display; also make shell-mode believe the user typed this string,
2383-
;; so that kill-output-from-shell and show-output-from-shell work
2384-
;; "right"
2385-
(defun py-append-to-process-buffer (process string)
2386-
(let ((cbuf (current-buffer))
2387-
(pbuf (process-buffer process))
2388-
(py-scroll-process-buffer t))
2389-
(set-buffer pbuf)
2390-
(goto-char (point-max))
2391-
(move-marker (process-mark process) (point))
2392-
(funcall (process-filter process) process string)
2393-
(set-buffer cbuf))
2394-
(sit-for 0))
2395-
2396-
;; older Emacsen don't have this function
2397-
(if (not (fboundp 'match-string))
2398-
(defun match-string (n)
2399-
(let ((beg (match-beginning n))
2400-
(end (match-end n)))
2401-
(if (and beg end)
2402-
(buffer-substring beg end)
2403-
nil))))
2404-
24052396
(defun py-current-defun ()
24062397
;; tell add-log.el how to find the current function/method/variable
24072398
(save-excursion

0 commit comments

Comments
 (0)