diff options
| author | Augusto Stoffel | 2021-09-11 14:50:28 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-09-11 14:58:12 +0200 |
| commit | e4300777e8cc7559ea29faaeab6cafd3f7ebf3b7 (patch) | |
| tree | 31cac363dab51ce2aba8316433c529c1112dc30f /lisp/progmodes/python.el | |
| parent | e40f5a91eed69b5d6131671ba1699ce3ccb92f16 (diff) | |
| download | emacs-e4300777e8cc7559ea29faaeab6cafd3f7ebf3b7.tar.gz emacs-e4300777e8cc7559ea29faaeab6cafd3f7ebf3b7.zip | |
Implement caching for 'python-shell-completion-at-point'
* lisp/progmodes/python.el (python-shell-completion-at-point): cache
results, since computing them involves talking with the inferior
process and, potentially, network communications
(python-shell--capf-cache): new variable, for cache
(python-shell-completion-get-completions)
(python-shell-completion-native-get-completions): 'import' argument is
not needed anymore.
(python-shell-completion-native-setup)
(python-shell-completion-native-try): pass the setup code
synchronously, to avoid printing a message in the shell (bug#50459).
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 2eef52de0cc..e71a8102dfe 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -3577,13 +3577,12 @@ When a match is found, native completion is disabled." | |||
| 3577 | python-shell-completion-native-try-output-timeout)) | 3577 | python-shell-completion-native-try-output-timeout)) |
| 3578 | (python-shell-completion-native-get-completions | 3578 | (python-shell-completion-native-get-completions |
| 3579 | (get-buffer-process (current-buffer)) | 3579 | (get-buffer-process (current-buffer)) |
| 3580 | nil "_"))) | 3580 | "_"))) |
| 3581 | 3581 | ||
| 3582 | (defun python-shell-completion-native-setup () | 3582 | (defun python-shell-completion-native-setup () |
| 3583 | "Try to setup native completion, return non-nil on success." | 3583 | "Try to setup native completion, return non-nil on success." |
| 3584 | (let ((process (python-shell-get-process))) | 3584 | (let* ((process (python-shell-get-process)) |
| 3585 | (with-current-buffer (process-buffer process) | 3585 | (output (python-shell-send-string-no-output " |
| 3586 | (python-shell-send-string " | ||
| 3587 | def __PYTHON_EL_native_completion_setup(): | 3586 | def __PYTHON_EL_native_completion_setup(): |
| 3588 | try: | 3587 | try: |
| 3589 | import readline | 3588 | import readline |
| @@ -3693,14 +3692,10 @@ def __PYTHON_EL_native_completion_setup(): | |||
| 3693 | print ('python.el: native completion setup failed, %s: %s' | 3692 | print ('python.el: native completion setup failed, %s: %s' |
| 3694 | % sys.exc_info()[:2]) | 3693 | % sys.exc_info()[:2]) |
| 3695 | 3694 | ||
| 3696 | __PYTHON_EL_native_completion_setup()" process) | 3695 | __PYTHON_EL_native_completion_setup()" process))) |
| 3697 | (when (and | 3696 | (when (string-match-p "python\\.el: native completion setup loaded" |
| 3698 | (python-shell-accept-process-output | 3697 | output) |
| 3699 | process python-shell-completion-native-try-output-timeout) | 3698 | (python-shell-completion-native-try)))) |
| 3700 | (save-excursion | ||
| 3701 | (re-search-backward | ||
| 3702 | (regexp-quote "python.el: native completion setup loaded") nil t 1))) | ||
| 3703 | (python-shell-completion-native-try))))) | ||
| 3704 | 3699 | ||
| 3705 | (defun python-shell-completion-native-turn-off (&optional msg) | 3700 | (defun python-shell-completion-native-turn-off (&optional msg) |
| 3706 | "Turn off shell native completions. | 3701 | "Turn off shell native completions. |
| @@ -3760,13 +3755,10 @@ With argument MSG show activation/deactivation message." | |||
| 3760 | (python-shell-completion-native-turn-on msg)) | 3755 | (python-shell-completion-native-turn-on msg)) |
| 3761 | python-shell-completion-native-enable)) | 3756 | python-shell-completion-native-enable)) |
| 3762 | 3757 | ||
| 3763 | (defun python-shell-completion-native-get-completions (process import input) | 3758 | (defun python-shell-completion-native-get-completions (process input) |
| 3764 | "Get completions using native readline for PROCESS. | 3759 | "Get completions of INPUT using native readline for PROCESS." |
| 3765 | When IMPORT is non-nil takes precedence over INPUT for | ||
| 3766 | completion." | ||
| 3767 | (with-current-buffer (process-buffer process) | 3760 | (with-current-buffer (process-buffer process) |
| 3768 | (let* ((input (or import input)) | 3761 | (let* ((original-filter-fn (process-filter process)) |
| 3769 | (original-filter-fn (process-filter process)) | ||
| 3770 | (redirect-buffer (get-buffer-create | 3762 | (redirect-buffer (get-buffer-create |
| 3771 | python-shell-completion-native-redirect-buffer)) | 3763 | python-shell-completion-native-redirect-buffer)) |
| 3772 | (trigger "\t") | 3764 | (trigger "\t") |
| @@ -3818,11 +3810,8 @@ completion." | |||
| 3818 | :test #'string=)))) | 3810 | :test #'string=)))) |
| 3819 | (set-process-filter process original-filter-fn))))) | 3811 | (set-process-filter process original-filter-fn))))) |
| 3820 | 3812 | ||
| 3821 | (defun python-shell-completion-get-completions (process import input) | 3813 | (defun python-shell-completion-get-completions (process input) |
| 3822 | "Do completion at point using PROCESS for IMPORT or INPUT. | 3814 | "Get completions of INPUT using PROCESS." |
| 3823 | When IMPORT is non-nil takes precedence over INPUT for | ||
| 3824 | completion." | ||
| 3825 | (setq input (or import input)) | ||
| 3826 | (with-current-buffer (process-buffer process) | 3815 | (with-current-buffer (process-buffer process) |
| 3827 | (let ((completions | 3816 | (let ((completions |
| 3828 | (python-util-strip-string | 3817 | (python-util-strip-string |
| @@ -3836,6 +3825,9 @@ completion." | |||
| 3836 | (split-string completions | 3825 | (split-string completions |
| 3837 | "^'\\|^\"\\|;\\|'$\\|\"$" t))))) | 3826 | "^'\\|^\"\\|;\\|'$\\|\"$" t))))) |
| 3838 | 3827 | ||
| 3828 | (defvar-local python-shell--capf-cache nil | ||
| 3829 | "Variable to store cached completions and invalidation keys.") | ||
| 3830 | |||
| 3839 | (defun python-shell-completion-at-point (&optional process) | 3831 | (defun python-shell-completion-at-point (&optional process) |
| 3840 | "Function for `completion-at-point-functions' in `inferior-python-mode'. | 3832 | "Function for `completion-at-point-functions' in `inferior-python-mode'. |
| 3841 | Optional argument PROCESS forces completions to be retrieved | 3833 | Optional argument PROCESS forces completions to be retrieved |
| @@ -3889,12 +3881,21 @@ using that one instead of current buffer's process." | |||
| 3889 | ;; it during a multiline statement (Bug#28051). | 3881 | ;; it during a multiline statement (Bug#28051). |
| 3890 | #'ignore | 3882 | #'ignore |
| 3891 | #'python-shell-completion-get-completions)) | 3883 | #'python-shell-completion-get-completions)) |
| 3892 | (t #'python-shell-completion-native-get-completions))))) | 3884 | (t #'python-shell-completion-native-get-completions)))) |
| 3893 | (list start end | 3885 | (prev-prompt (car python-shell--capf-cache)) |
| 3894 | (completion-table-dynamic | 3886 | (re (or (cadr python-shell--capf-cache) regexp-unmatchable)) |
| 3895 | (apply-partially | 3887 | (prefix (buffer-substring-no-properties start end))) |
| 3896 | completion-fn | 3888 | ;; To invalidate the cache, we check if the prompt position or the |
| 3897 | process import-statement))))) | 3889 | ;; completion prefix changed. |
| 3890 | (unless (and (equal prev-prompt (car prompt-boundaries)) | ||
| 3891 | (string-match re prefix)) | ||
| 3892 | (setq python-shell--capf-cache | ||
| 3893 | `(,(car prompt-boundaries) | ||
| 3894 | ,(if (string-empty-p prefix) | ||
| 3895 | regexp-unmatchable | ||
| 3896 | (concat "\\`" (regexp-quote prefix) "\\(?:\\sw\\|\\s_\\)*\\'")) | ||
| 3897 | ,@(funcall completion-fn process (or import-statement prefix))))) | ||
| 3898 | (list start end (cddr python-shell--capf-cache)))) | ||
| 3898 | 3899 | ||
| 3899 | (define-obsolete-function-alias | 3900 | (define-obsolete-function-alias |
| 3900 | 'python-shell-completion-complete-at-point | 3901 | 'python-shell-completion-complete-at-point |