use ipython magic if possible and plain python otherwise

This commit is contained in:
Valentin Boettcher 2024-05-16 11:26:09 -04:00
parent cc4ae4f19b
commit 067e67ea7e
No known key found for this signature in database
GPG key ID: E034E12B7AF56ACE
2 changed files with 33 additions and 20 deletions

View file

@ -12,6 +12,9 @@ Python-vterm provides a major-mode for an inferior Python process (or REPL) that
The functionalities required for typical REPL interaction have been implemented. While I would like to keep this package simple, suggestions are always welcome.
It is automatically detected whether the repl runs =ipython= or another
interpreter and some functions use different functionalities based on
that information.
** Installation
Currently you can only install the package from github. With
~use-package~ and ~straight~ it looks as follows:
@ -125,7 +128,6 @@ C-c C-f python-vterm-run-current-function
C-c C-r python-vterm-send-run-buffer-file
Send a line to evaluate the buffer's file using ipython %run magic.
This is only useful when using ipython.
C-c C-d python-vterm-send-cd-to-buffer-directory
Send %cd function call to the Python REPL to change the current working
@ -171,8 +173,7 @@ C-c C-r vterm-reset-cursor-point
** TODO fix the automatic return
- most commands should accept a prefix that control whether the code
is exectued with =<enter>= or just pasted into the repl
** TODO detect interpreter
- this allows to avoid using ipython features in ptpython/python
** TODO overhaul session management
** TODO make an =in-repl-buffer= macro
** TODO make run-current-function a bit more intelligent
- detect if there are only arguments with default values

View file

@ -7,7 +7,7 @@
;; Created: May 11, 2024
;; URL: https://github.com/vale981/python-vterm.el
;; Package-Requires: ((emacs "25.1") (vterm "0.0.1"))
;; Version: 1.0.2
;; Version: 1.0.3
;; Keywords: languages, python
;; This file is not part of GNU Emacs.
@ -74,7 +74,9 @@ or an absolute path name, like /usr/local/bin/python
parameters may be used, like python -q")
(defvar-local python-vterm-silent-cells nil
"If non-nil, the PYTHON-VTERM-SEND-CURRENT-CELL will use ipythons `%run` magic to run a code cell.")
"If non-nil, the PYTHON-VTERM-SEND-CURRENT-CELL will use ipythons `%run` magic to run a code cell.
For plain python `exec(open(...).read())` is used.")
(defvar-local python-vterm-repl-script-buffer nil)
(defvar-local python-vterm-repl-interpreter :python
@ -132,8 +134,8 @@ If CONTEXT is given, it is used to set the working directory and the script buff
(while (not (python-vterm-repl-prompt-status))
(sit-for 0.1))
(setq python-vterm-repl-interpreter
(if (python-vterm--execute-script "is_ipython")
:ipython :python))))
(if (eq (python-vterm--execute-script "is_ipython") :false)
:python :ipython))))
new-buffer)
(add-function :filter-args (process-filter vterm--process)
@ -461,18 +463,26 @@ the main REPL, is used."
(deactivate-mark))
(python-vterm-send-current-line)))
(defun python-vterm--load-file (file &optional comment)
"Load the content of the file with FILE into the Python REPL buffer."
(if (eq python-vterm-repl-interpreter :ipython)
(format "%%run -i %s # %s" file (or comment ""))
(format "exec(open(\"%s\").read()) # %s" file comment)))
(defun python-vterm--send-maybe-silent (string &optional comment)
"Send STRING to the Python REPL buffer, possibly using `%run -i' with a temp file."
(if python-vterm-silent-cells
(let ((tmpfile (make-temp-file "python-vterm" nil ".py")))
(with-temp-file tmpfile
(insert string))
(python-vterm-paste-string (format "%%run -i %s # %s" tmpfile (or comment "")))
(run-with-timer 1 nil
(lambda (tmpfile)
(delete-file tmpfile))
tmpfile))
(python-vterm-paste-string string)))
(with-current-buffer (python-vterm-fellow-repl-buffer)
(if python-vterm-silent-cells
(let ((tmpfile (make-temp-file "python-vterm" nil ".py")))
(with-temp-file tmpfile
(insert string))
(python-vterm-paste-string (python-vterm--load-file tmpfile comment))
(run-with-timer 10 nil
(lambda (tmpfile)
(delete-file tmpfile))
tmpfile))
(python-vterm-paste-string string))))
(defun python-vterm-send-current-cell ()
"Send the current code \"cell\" to the Python REPL.
@ -529,17 +539,19 @@ If the function has no arguments, the function call is run immediately."
(defun python-vterm-send-run-buffer-file ()
"Run the current buffer file in the python vterm buffer.
This is equivalent to running `%run <buffer-file-name>` in the python vterm buffer."
This is equivalent to running `%run -i <buffer-file-name>` in the python vterm buffer."
(interactive)
(python-vterm-paste-string (concat "%run " (buffer-file-name))))
(python-vterm-paste-string (python-vterm--load-file buffer-file-name "load script buffer")))
(defun python-vterm-send-cd-to-buffer-directory ()
"Change the REPL's working directory to the directory of the buffer file."
(interactive)
(if buffer-file-name
(let ((buffer-directory (file-name-directory buffer-file-name)))
(python-vterm-paste-string (format "import os; os.chdir(\"%s\")" buffer-directory))
(with-current-buffer (python-vterm-fellow-repl-buffer)
(python-vterm-paste-string (if (eq python-vterm-repl-interpreter :ipython)
(format "%%cd %s" buffer-directory)
(format "import os; os.chdir(\"%s\")" buffer-directory)))
(setq default-directory buffer-directory)))
(message "The buffer is not associated with a directory.")))