X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/fa7886a46ff8d611cd75eaf651944f0fbc260324..001d88b62ecb8163a148656acb103b354ce7613a:/lisp/progmodes/python.el diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 9c23655b91..ba3cdfe17c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -4,7 +4,7 @@ ;; Author: Fabián E. Gallina ;; URL: https://github.com/fgallina/python.el -;; Version: 0.25.1 +;; Version: 0.25.2 ;; Package-Requires: ((emacs "24.1") (cl-lib "1.0")) ;; Maintainer: emacs-devel@gnu.org ;; Created: Jul 2010 @@ -283,6 +283,18 @@ :version "24.3" :link '(emacs-commentary-link "python")) + +;;; 24.x Compat + + +(unless (fboundp 'prog-widen) + (defun prog-widen () + (widen))) + +(unless (fboundp 'prog-first-column) + (defun prog-first-column () + 0)) + ;;; Bindings @@ -318,6 +330,7 @@ ;; Some util commands (define-key map "\C-c\C-v" 'python-check) (define-key map "\C-c\C-f" 'python-eldoc-at-point) + (define-key map "\C-c\C-d" 'python-describe-at-point) ;; Utilities (substitute-key-definition 'complete-symbol 'completion-at-point map global-map) @@ -524,6 +537,7 @@ The type returned can be `comment', `string' or `paren'." "nonlocal" ;; Python 3.5+ PEP492 (and "async" (+ space) (or "def" "for" "with")) + "await" ;; Extra: "self") symbol-end) @@ -548,23 +562,32 @@ The type returned can be `comment', `string' or `paren'." ;; Builtin Exceptions (,(rx symbol-start (or + ;; Python 2 and 3: "ArithmeticError" "AssertionError" "AttributeError" "BaseException" - "DeprecationWarning" "EOFError" "EnvironmentError" "Exception" - "FloatingPointError" "FutureWarning" "GeneratorExit" "IOError" - "ImportError" "ImportWarning" "IndexError" "KeyError" - "KeyboardInterrupt" "LookupError" "MemoryError" "NameError" - "NotImplementedError" "OSError" "OverflowError" - "PendingDeprecationWarning" "ReferenceError" "RuntimeError" - "RuntimeWarning" "StopIteration" "SyntaxError" "SyntaxWarning" - "SystemError" "SystemExit" "TypeError" "UnboundLocalError" - "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError" - "UnicodeTranslateError" "UnicodeWarning" "UserWarning" "VMSError" - "ValueError" "Warning" "WindowsError" "ZeroDivisionError" + "BufferError" "BytesWarning" "DeprecationWarning" "EOFError" + "EnvironmentError" "Exception" "FloatingPointError" "FutureWarning" + "GeneratorExit" "IOError" "ImportError" "ImportWarning" + "IndentationError" "IndexError" "KeyError" "KeyboardInterrupt" + "LookupError" "MemoryError" "NameError" "NotImplementedError" + "OSError" "OverflowError" "PendingDeprecationWarning" + "ReferenceError" "RuntimeError" "RuntimeWarning" "StopIteration" + "SyntaxError" "SyntaxWarning" "SystemError" "SystemExit" "TabError" + "TypeError" "UnboundLocalError" "UnicodeDecodeError" + "UnicodeEncodeError" "UnicodeError" "UnicodeTranslateError" + "UnicodeWarning" "UserWarning" "ValueError" "Warning" + "ZeroDivisionError" ;; Python 2: "StandardError" ;; Python 3: - "BufferError" "BytesWarning" "IndentationError" "ResourceWarning" - "TabError") + "BlockingIOError" "BrokenPipeError" "ChildProcessError" + "ConnectionAbortedError" "ConnectionError" "ConnectionRefusedError" + "ConnectionResetError" "FileExistsError" "FileNotFoundError" + "InterruptedError" "IsADirectoryError" "NotADirectoryError" + "PermissionError" "ProcessLookupError" "RecursionError" + "ResourceWarning" "StopAsyncIteration" "TimeoutError" + ;; OS specific + "VMSError" "WindowsError" + ) symbol-end) . font-lock-type-face) ;; Builtins (,(rx symbol-start @@ -758,7 +781,7 @@ work on `python-indent-calculate-indentation' instead." (interactive) (save-excursion (save-restriction - (widen) + (prog-widen) (goto-char (point-min)) (let ((block-end)) (while (and (not block-end) @@ -857,7 +880,7 @@ keyword - Point is on a line starting a dedenter block. - START is the position where the dedenter block starts." (save-restriction - (widen) + (prog-widen) (let ((ppss (save-excursion (beginning-of-line) (syntax-ppss)))) @@ -1004,10 +1027,10 @@ current context or a list of integers. The latter case is only happening for :at-dedenter-block-start context since the possibilities can be narrowed to specific indentation points." (save-restriction - (widen) + (prog-widen) (save-excursion (pcase (python-indent-context) - (`(:no-indent . ,_) 0) + (`(:no-indent . ,_) (prog-first-column)) ; usually 0 (`(,(or :after-line :after-comment :inside-string @@ -1045,7 +1068,7 @@ possibilities can be narrowed to specific indentation points." (let ((opening-block-start-points (python-info-dedenter-opening-block-positions))) (if (not opening-block-start-points) - 0 ; if not found default to first column + (prog-first-column) ; if not found default to first column (mapcar (lambda (pos) (save-excursion (goto-char pos) @@ -1063,7 +1086,7 @@ integers. Levels are returned in ascending order, and in the case INDENTATION is a list, this order is enforced." (if (listp indentation) (sort (copy-sequence indentation) #'<) - (nconc (number-sequence 0 (1- indentation) + (nconc (number-sequence (prog-first-column) (1- indentation) python-indent-offset) (list indentation)))) @@ -1088,7 +1111,7 @@ minimum." (python-indent--previous-level levels (current-indentation)) (if levels (apply #'max levels) - 0)))) + (prog-first-column))))) (defun python-indent-line (&optional previous) "Internal implementation of `python-indent-line-function'. @@ -2041,8 +2064,8 @@ virtualenv." (defun python-shell-calculate-pythonpath () "Calculate the PYTHONPATH using `python-shell-extra-pythonpaths'." (let ((pythonpath - (tramp-compat-split-string - (or (getenv "PYTHONPATH") "") path-separator))) + (split-string + (or (getenv "PYTHONPATH") "") path-separator 'omit))) (python-shell--add-to-path-with-priority pythonpath python-shell-extra-pythonpaths) (mapconcat 'identity pythonpath path-separator))) @@ -2113,7 +2136,7 @@ appends `python-shell-remote-exec-path' instead of `exec-path'." (md5 tramp-end-of-output))) unset vars item) (while env - (setq item (tramp-compat-split-string (car env) "=")) + (setq item (split-string (car env) "=" 'omit)) (setcdr item (mapconcat 'identity (cdr item) "=")) (if (and (stringp (cdr item)) (not (string-equal (cdr item) ""))) (push (format "%s %s" (car item) (cdr item)) vars) @@ -2677,6 +2700,7 @@ variable. \(Type \\[describe-mode] in the process buffer for a list of commands.)" (when python-shell--parent-buffer (python-util-clone-local-variables python-shell--parent-buffer)) + (set (make-local-variable 'indent-tabs-mode) nil) ;; Users can interactively override default values for ;; `python-shell-interpreter' and `python-shell-interpreter-args' ;; when calling `run-python'. This ensures values let-bound in @@ -4022,8 +4046,8 @@ The skeleton will be bound to python-skeleton-NAME." (declare (indent 2)) (let* ((name (symbol-name name)) (function-name (intern (concat "python-skeleton--" name))) - (msg (format-message - "Add `%s' clause? " name))) + (msg (funcall (if (fboundp 'format-message) #'format-message #'format) + "Add `%s' clause? " name))) (when (not skel) (setq skel `(< ,(format "%s:" name) \n \n @@ -4290,12 +4314,47 @@ returns will be used. If not FORCE-PROCESS is passed what (unless (zerop (length docstring)) docstring))))) +(defvar-local python-eldoc-get-doc t + "Non-nil means eldoc should fetch the documentation + automatically. Set to nil by `python-eldoc-function' if + `python-eldoc-function-timeout-permanent' is non-nil and + `python-eldoc-function' times out.") + +(defcustom python-eldoc-function-timeout 1 + "Timeout for `python-eldoc-function' in seconds." + :group 'python + :type 'integer + :version "25.1") + +(defcustom python-eldoc-function-timeout-permanent t + "Non-nil means that when `python-eldoc-function' times out +`python-eldoc-get-doc' will be set to nil" + :group 'python + :type 'boolean + :version "25.1") + (defun python-eldoc-function () "`eldoc-documentation-function' for Python. For this to work as best as possible you should call `python-shell-send-buffer' from time to time so context in -inferior Python process is updated properly." - (python-eldoc--get-doc-at-point)) +inferior Python process is updated properly. + +If `python-eldoc-function-timeout' seconds elapse before this +function returns then if +`python-eldoc-function-timeout-permanent' is non-nil +`python-eldoc-get-doc' will be set to nil and eldoc will no +longer return the documentation at the point automatically. + +Set `python-eldoc-get-doc' to t to reenable eldoc documentation +fetching" + (when python-eldoc-get-doc + (with-timeout (python-eldoc-function-timeout + (if python-eldoc-function-timeout-permanent + (progn + (message "Eldoc echo-area display muted in this buffer, see `python-eldoc-function'") + (setq python-eldoc-get-doc nil)) + (message "`python-eldoc-function' timed out, see `python-eldoc-function-timeout'"))) + (python-eldoc--get-doc-at-point)))) (defun python-eldoc-at-point (symbol) "Get help on SYMBOL using `help'. @@ -4309,6 +4368,11 @@ Interactively, prompt for symbol." nil nil symbol)))) (message (python-eldoc--get-doc-at-point symbol))) +(defun python-describe-at-point (symbol process) + (interactive (list (python-info-current-symbol) + (python-shell-get-process))) + (comint-send-string process (concat "help('" symbol "')\n"))) + ;;; Hideshow @@ -4476,7 +4540,7 @@ Optional argument INCLUDE-TYPE indicates to include the type of the defun. This function can be used as the value of `add-log-current-defun-function' since it returns nil if point is not inside a defun." (save-restriction - (widen) + (prog-widen) (save-excursion (end-of-line 1) (let ((names) @@ -4659,7 +4723,7 @@ likely an invalid python file." (let ((point (python-info-dedenter-opening-block-position))) (when point (save-restriction - (widen) + (prog-widen) (message "Closes %s" (save-excursion (goto-char point) (buffer-substring @@ -4680,7 +4744,7 @@ statement." With optional argument LINE-NUMBER, check that line instead." (save-excursion (save-restriction - (widen) + (prog-widen) (when line-number (python-util-goto-line line-number)) (while (and (not (eobp)) @@ -4696,7 +4760,7 @@ With optional argument LINE-NUMBER, check that line instead." Optional argument LINE-NUMBER forces the line number to check against." (save-excursion (save-restriction - (widen) + (prog-widen) (when line-number (python-util-goto-line line-number)) (when (python-info-line-ends-backslash-p) @@ -4713,7 +4777,7 @@ When current line is continuation of another return the point where the continued line ends." (save-excursion (save-restriction - (widen) + (prog-widen) (let* ((context-type (progn (back-to-indentation) (python-syntax-context-type))) @@ -5089,12 +5153,14 @@ returned as is." (current-column)))) (^ '(- (1+ (current-indentation)))))) - (if (null eldoc-documentation-function) - ;; Emacs<25 - (set (make-local-variable 'eldoc-documentation-function) - #'python-eldoc-function) - (add-function :before-until (local 'eldoc-documentation-function) - #'python-eldoc-function)) + (if (boundp 'eldoc-documentation-functions) + (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t) + (if (null eldoc-documentation-function) + ;; Emacs<25 + (set (make-local-variable 'eldoc-documentation-function) + #'python-eldoc-function) + (add-function :before-until (local 'eldoc-documentation-function) + #'python-eldoc-function))) (add-to-list 'hs-special-modes-alist