unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Liu Hui <liuhui1610@gmail.com>
To: "Basil L. Contovounesios" <basil@contovou.net>
Cc: kobarity <kobarity@gmail.com>, "Eli Zaretskii" <eliz@gnu.org>,
	"Mattias Engdegård" <mattias.engdegard@gmail.com>,
	68559@debbugs.gnu.org
Subject: bug#68559: [PATCH] Improve Python shell completion
Date: Mon, 11 Mar 2024 19:35:31 +0800	[thread overview]
Message-ID: <CAOQTW-MrJUKmnOGQGBRdX_OQpuyFek4ZUSarSdvVMbwiE2k3TQ@mail.gmail.com> (raw)
In-Reply-To: <87y1asybi4.fsf@epfl.ch>

[-- Attachment #1: Type: text/plain, Size: 1115 bytes --]

On Fri, Mar 8, 2024 at 11:44 PM Basil L. Contovounesios
<basil@contovou.net> wrote:
>
> Liu Hui [2024-03-06 18:14 +0800] wrote:
>
> > I have updated the patch.
>
> Thanks!  The build and tests succeed here, without skipped tests.
>
> > +                (unless (string-match-p "No readline support" output)
>
> Nit: why not plain 'string-search' instead of a regexp search?

Done.

> > -                   (string-match-p "ipython[23]?\\'" python-shell-interpreter)))))
> > +                   (or (string-match-p "ipython[23]?\\'" python-shell-interpreter)
> > +                       (string= python-shell-readline-completer-delims ""))))))
>
> Just curious: what does the empty string signify?
>
> [ If it's not just a dumb question, perhaps the meaning could be added
>   to the variable's docstring/commentary. ]

The empty string means no characters are considered delimiters and the
readline completion could consider the entire line of input without
breaking it into parts based on typical delimiters like spaces or
punctuation. The docstring is updated in the attached patch.

[-- Attachment #2: 0001-Detect-the-readline-support-for-Python-shell-complet.patch --]
[-- Type: text/x-patch, Size: 9024 bytes --]

From bb1f8f92d5cd3c19d404e023ab33315bfa8a535a Mon Sep 17 00:00:00 2001
From: Liu Hui <liuhui1610@gmail.com>
Date: Mon, 26 Feb 2024 18:46:36 +0800
Subject: [PATCH] Detect the readline support for Python shell completion

* lisp/progmodes/python.el
(python-shell-comint-watch-for-first-prompt-output-filter):
Detect the readline support.
(python-shell-readline-completer-delims): Update docstring.
(python-shell-completion-native-setup): Move the readline
detection code to ...
(python-shell-readline-detect): ... new function.
(python-shell-completion-native-turn-on-maybe): Skip if Python
has no readline support.
(python-shell-completion-at-point): Respect the delimiter of
readline completer in non-native completion.
* test/lisp/progmodes/python-tests.el
(python-shell-completion-at-point-1)
(python-shell-completion-at-point-native-1)
(python-completion-at-point-1, python-completion-at-point-2)
(python-completion-at-point-pdb-1)
(python-completion-at-point-while-running-1)
(python-completion-at-point-native-1)
(python-completion-at-point-native-2)
(python-completion-at-point-native-with-ffap-1)
(python-completion-at-point-native-with-eldoc-1): Skip tests if
Python has no readline support.
(python-shell-completion-at-point-jedi-completer): Add test for
non-native Python shell completion. (bug#68559)
---
 lisp/progmodes/python.el            | 29 ++++++++++++++++++++-------
 test/lisp/progmodes/python-tests.el | 31 ++++++++++++++++++++++++-----
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 587d0b36304..0ea0b918872 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -3601,6 +3601,7 @@ python-shell-comint-watch-for-first-prompt-output-filter
           (python-shell-send-string-no-output python-shell-eval-file-setup-code))
         (with-current-buffer (current-buffer)
           (let ((inhibit-quit nil))
+            (python-shell-readline-detect)
             (run-hooks 'python-shell-first-prompt-hook))))))
   output)
 
@@ -4439,7 +4440,23 @@ python-shell-completion-native-try-output-timeout
 
 (defvar python-shell-readline-completer-delims nil
   "Word delimiters used by the readline completer.
-It is automatically set by Python shell.")
+It is automatically set by Python shell.  An empty string means no
+characters are considered delimiters and the readline completion
+considers the entire line of input.  A value of nil means the Python
+shell has no readline support.")
+
+(defun python-shell-readline-detect ()
+  "Detect the readline support for Python shell completion."
+  (let* ((process (python-shell-get-process))
+         (output (python-shell-send-string-no-output "
+try:
+    import readline
+    print(readline.get_completer_delims())
+except:
+    print('No readline support')" process)))
+    (setq-local python-shell-readline-completer-delims
+                (unless (string-search "No readline support" output)
+                  (string-trim-right output)))))
 
 (defvar python-shell-completion-native-redirect-buffer
   " *Python completions redirect*"
@@ -4579,10 +4596,6 @@ python-shell-completion-native-setup
 __PYTHON_EL_native_completion_setup()" process)))
     (when (string-match-p "python\\.el: native completion setup loaded"
                           output)
-      (setq-local python-shell-readline-completer-delims
-                  (string-trim-right
-                   (python-shell-send-string-no-output
-                    "import readline; print(readline.get_completer_delims())")))
       (python-shell-completion-native-try))))
 
 (defun python-shell-completion-native-turn-off (&optional msg)
@@ -4611,7 +4624,8 @@ python-shell-completion-native-turn-on-maybe
       (cond
        ((python-shell-completion-native-interpreter-disabled-p)
         (python-shell-completion-native-turn-off msg))
-       ((python-shell-completion-native-setup)
+       ((and python-shell-readline-completer-delims
+             (python-shell-completion-native-setup))
         (when msg
           (message "Shell native completion is enabled.")))
        (t
@@ -4783,7 +4797,8 @@ python-shell-completion-at-point
                (with-current-buffer (process-buffer process)
                  (if python-shell-completion-native-enable
                      (string= python-shell-readline-completer-delims "")
-                   (string-match-p "ipython[23]?\\'" python-shell-interpreter)))))
+                   (or (string-match-p "ipython[23]?\\'" python-shell-interpreter)
+                       (string= python-shell-readline-completer-delims ""))))))
          (start
           (if (< (point) line-start)
               (point)
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 1ceee690cfb..e11440cdb5b 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -4783,6 +4783,7 @@ python-shell-completion-at-point-1
   (python-tests-with-temp-buffer-with-shell
    ""
    (python-shell-with-shell-buffer
+     (skip-unless python-shell-readline-completer-delims)
      (insert "import abc")
      (comint-send-input)
      (python-tests-shell-wait-for-prompt)
@@ -4797,6 +4798,7 @@ python-shell-completion-at-point-native-1
    ""
    (python-shell-completion-native-turn-on)
    (python-shell-with-shell-buffer
+     (skip-unless python-shell-readline-completer-delims)
      (insert "import abc")
      (comint-send-input)
      (python-tests-shell-wait-for-prompt)
@@ -4883,11 +4885,14 @@ python-shell-completion-at-point-jedi-completer
     (python-tests-with-temp-buffer-with-shell
      ""
      (python-shell-with-shell-buffer
-      (python-shell-completion-native-turn-on)
-      (skip-unless (string= python-shell-readline-completer-delims ""))
-      (python-tests--completion-module)
-      (python-tests--completion-parameters)
-      (python-tests--completion-extra-context)))))
+       (skip-unless (string= python-shell-readline-completer-delims ""))
+       (python-shell-completion-native-turn-off)
+       (python-tests--completion-module)
+       (python-tests--completion-parameters)
+       (python-shell-completion-native-turn-on)
+       (python-tests--completion-module)
+       (python-tests--completion-parameters)
+       (python-tests--completion-extra-context)))))
 
 (ert-deftest python-shell-completion-at-point-ipython ()
   "Check if Python shell completion works for IPython."
@@ -4924,6 +4929,8 @@ python-completion-at-point-1
 import abc
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
      (goto-char (point-max))
@@ -4940,6 +4947,8 @@ python-completion-at-point-2
 import abc
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
      (python-shell-with-shell-buffer
@@ -4959,6 +4968,8 @@ python-completion-at-point-pdb-1
 print('Hello')
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
      (goto-char (point-max))
@@ -4975,6 +4986,8 @@ python-completion-at-point-while-running-1
 time.sleep(3)
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-send-buffer)
      (goto-char (point-max))
      (insert "time.")
@@ -4987,6 +5000,8 @@ python-completion-at-point-native-1
 import abc
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-completion-native-turn-on)
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
@@ -5004,6 +5019,8 @@ python-completion-at-point-native-2
 import abc
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-completion-native-turn-on)
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
@@ -5020,6 +5037,8 @@ python-completion-at-point-native-with-ffap-1
 import abc
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-completion-native-turn-on)
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
@@ -5036,6 +5055,8 @@ python-completion-at-point-native-with-eldoc-1
 import abc
 "
    (let ((inhibit-message t))
+     (python-shell-with-shell-buffer
+       (skip-unless python-shell-readline-completer-delims))
      (python-shell-completion-native-turn-on)
      (python-shell-send-buffer)
      (python-tests-shell-wait-for-prompt)
-- 
2.25.1


  reply	other threads:[~2024-03-11 11:35 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-18  4:48 bug#68559: [PATCH] Improve Python shell completion Liu Hui
2024-01-18  6:39 ` Eli Zaretskii
2024-01-21  9:34   ` kobarity
2024-01-23 11:31     ` Liu Hui
2024-01-23 14:15       ` kobarity
2024-01-24 10:07         ` Liu Hui
2024-01-25 15:38           ` kobarity
2024-01-26 10:12             ` Liu Hui
2024-01-28 13:22               ` kobarity
2024-01-29 13:15                 ` kobarity
2024-02-01  9:52                   ` Eli Zaretskii
2024-02-01 14:39                     ` kobarity
2024-02-01 15:02                       ` Liu Hui
2024-02-04 12:09                 ` Liu Hui
2024-02-04 14:35                   ` kobarity
2024-02-05 15:03                     ` Liu Hui
2024-02-06  1:25                       ` Liu Hui
2024-02-06 15:12                         ` kobarity
2024-02-07 13:22                           ` Liu Hui
2024-02-07 15:19                             ` kobarity
2024-02-08 12:13                               ` Eli Zaretskii
2024-02-08 13:33                                 ` Liu Hui
2024-02-08 13:46                                   ` Eli Zaretskii
2024-02-08 14:16                                     ` Liu Hui
2024-02-08 16:43                                       ` Eli Zaretskii
2024-02-15 14:43 ` Mattias Engdegård
2024-02-15 16:37   ` Eli Zaretskii
2024-02-15 16:48     ` Eli Zaretskii
2024-02-15 17:21       ` Mattias Engdegård
2024-02-19 13:18       ` Basil L. Contovounesios
2024-02-20  4:46         ` Liu Hui
2024-02-20 13:15           ` Basil L. Contovounesios
2024-02-21 10:00             ` Liu Hui
2024-02-21 14:55               ` Basil L. Contovounesios
2024-02-22 10:31                 ` Liu Hui
2024-02-22 13:56                   ` Basil L. Contovounesios
2024-02-23 13:07                     ` Liu Hui
2024-02-28 14:47                       ` Basil L. Contovounesios
2024-02-16  4:06     ` Liu Hui
2024-02-16  7:41       ` Eli Zaretskii
2024-02-16 12:51         ` Eli Zaretskii
2024-02-16  3:24   ` Liu Hui
2024-02-16  9:34     ` kobarity
2024-02-16 11:45       ` Mattias Engdegård
2024-02-16 15:24         ` kobarity
2024-02-16 15:52           ` Eli Zaretskii
2024-02-16 20:10           ` Mattias Engdegård
2024-02-17 13:33             ` kobarity
2024-02-20 10:16               ` Mattias Engdegård
2024-02-21 13:13                 ` kobarity
2024-02-21 18:20                   ` Mattias Engdegård
2024-02-22 16:15                     ` kobarity
2024-02-23 11:00                       ` Mattias Engdegård
2024-02-23 14:39                         ` kobarity
2024-02-26 11:06                           ` Liu Hui
2024-02-26 12:16                             ` Mattias Engdegård
2024-02-26 15:08                               ` kobarity
2024-02-28 14:49                             ` Basil L. Contovounesios
2024-03-06 10:14                               ` Liu Hui
2024-03-08 15:44                                 ` Basil L. Contovounesios
2024-03-11 11:35                                   ` Liu Hui [this message]
2024-03-11 16:02                                     ` Basil L. Contovounesios
2024-03-13 10:21                                       ` Liu Hui
2024-03-14 14:24                                         ` Basil L. Contovounesios
2024-03-16  6:49                                           ` Liu Hui
2024-03-16  8:27                                             ` Eli Zaretskii
2024-02-17  4:36           ` Liu Hui
2024-02-17 13:20             ` Mattias Engdegård

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAOQTW-MrJUKmnOGQGBRdX_OQpuyFek4ZUSarSdvVMbwiE2k3TQ@mail.gmail.com \
    --to=liuhui1610@gmail.com \
    --cc=68559@debbugs.gnu.org \
    --cc=basil@contovou.net \
    --cc=eliz@gnu.org \
    --cc=kobarity@gmail.com \
    --cc=mattias.engdegard@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).