diff options
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r-- | lisp/progmodes/python.el | 106 |
1 files changed, 57 insertions, 49 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ea4f620faad..0708bf7037d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -65,7 +65,6 @@ ;;; Code: (eval-when-compile - (require 'cl) (require 'compile) (require 'comint) (require 'hippie-exp)) @@ -885,10 +884,13 @@ On a comment line, go to end of line." nil) ((eq 'string (syntax-ppss-context s)) ;; Go to start of string and skip it. - (goto-char (nth 8 s)) - (condition-case () ; beware invalid syntax - (progn (forward-sexp) t) - (error (end-of-line)))) + (let ((pos (point))) + (goto-char (nth 8 s)) + (condition-case () ; beware invalid syntax + (progn (forward-sexp) t) + ;; If there's a mismatched string, make sure + ;; we still overall move *forward*. + (error (goto-char pos) (end-of-line))))) ((python-skip-out t s)))) (end-of-line)) (unless comment @@ -983,15 +985,11 @@ don't move and return nil. Otherwise return t." (_ (if (python-comment-line-p) (python-skip-comments/blanks t))) (ci (current-indentation)) - (open (python-open-block-statement-p)) - opoint) + (open (python-open-block-statement-p))) (if (and (zerop ci) (not open)) (not (goto-char point)) (catch 'done - (setq opoint (point)) - (while (and (zerop (python-next-statement)) - (not (= opoint (point)))) - (setq opoint (point)) + (while (zerop (python-next-statement)) (when (or (and open (<= (current-indentation) ci)) (< (current-indentation) ci)) (python-skip-comments/blanks t) @@ -999,7 +997,16 @@ don't move and return nil. Otherwise return t." (throw 'done t))))))) (setq arg (1- arg))) (zerop arg))) - + +(defvar python-which-func-length-limit 40 + "Non-strict length limit for `python-which-func' output.") + +(defun python-which-func () + (let ((function-name (python-current-defun python-which-func-length-limit))) + (set-text-properties 0 (length function-name) nil function-name) + function-name)) + + ;;;; Imenu. (defvar python-recursing) @@ -1216,6 +1223,9 @@ local value.") ;; (modify-syntax-entry ?\" "." st) st)) +;; Autoloaded. +(declare-function compilation-shell-minor-mode "compile" (&optional arg)) + ;; Fixme: This should inherit some stuff from `python-mode', but I'm ;; not sure how much: at least some keybindings, like C-c C-f; ;; syntax?; font-locking, e.g. for triple-quoted strings? @@ -1375,7 +1385,7 @@ buffer for a list of commands.)" ;; seems worth putting in a separate file, and it's probably cleaner ;; to put it in a module. ;; Ensure we're at a prompt before doing anything else. - (python-send-receive "import emacs; print '_emacs_out ()'"))) + (python-send-string "import emacs"))) (if (derived-mode-p 'python-mode) (setq python-buffer (default-value 'python-buffer))) ; buffer-local ;; Without this, help output goes into the inferior python buffer if @@ -1648,6 +1658,8 @@ instance. Assumes an inferior Python is running." ;;;; Info-look functionality. +(declare-function info-lookup-maybe-add-help "../info-look" (&rest arg)) + (defun python-after-info-look () "Set up info-look for Python. Used with `eval-after-load'." @@ -1833,22 +1845,33 @@ of current line." (1+ (/ (current-indentation) python-indent))) ;; Fixme: Consider top-level assignments, imports, &c. -(defun python-current-defun () +(defun python-current-defun (&optional length-limit) "`add-log-current-defun-function' for Python." (save-excursion ;; Move up the tree of nested `class' and `def' blocks until we ;; get to zero indentation, accumulating the defined names. - (let ((start t) - accum) - (while (or start (> (current-indentation) 0)) - (setq start nil) - (python-beginning-of-block) - (end-of-line) - (beginning-of-defun) - (if (looking-at (rx (0+ space) (or "def" "class") (1+ space) - (group (1+ (or word (syntax symbol)))))) - (push (match-string 1) accum))) - (if accum (mapconcat 'identity accum "."))))) + (let ((accum) + (length -1)) + (catch 'done + (while (or (null length-limit) + (null (cdr accum)) + (< length length-limit)) + (let ((started-from (point))) + (python-beginning-of-block) + (end-of-line) + (beginning-of-defun) + (when (= (point) started-from) + (throw 'done nil))) + (when (looking-at (rx (0+ space) (or "def" "class") (1+ space) + (group (1+ (or word (syntax symbol)))))) + (push (match-string 1) accum) + (setq length (+ length 1 (length (car accum))))) + (when (= (current-indentation) 0) + (throw 'done nil)))) + (when accum + (when (and length-limit (> length length-limit)) + (setcar accum "..")) + (mapconcat 'identity accum "."))))) (defun python-mark-block () "Mark the block around point. @@ -1947,7 +1970,7 @@ Repeating the command scrolls the completion window." (interactive) (let ((window (get-buffer-window "*Completions*"))) (if (and (eq last-command this-command) - window (window-live-p window) (window-buffer window) + (window-live-p window) (window-buffer window) (buffer-name (window-buffer window))) (with-current-buffer (window-buffer window) (if (pos-visible-in-window-p (point-max) window) @@ -2017,10 +2040,11 @@ the if condition." "Alist of named skeletons for Python mode. Elements are of the form (NAME . EXPANDER-FUNCTION).") -(defvar python-mode-abbrev-table nil +(define-abbrev-table 'python-mode-abbrev-table () "Abbrev table for Python mode. -The default contents correspond to the elements of `python-skeletons'.") -(define-abbrev-table 'python-mode-abbrev-table ()) +The default contents correspond to the elements of `python-skeletons'." + ;; Allow / in abbrevs. + :regexp "\\<\\([[:word:]/]+\\)\\W*") (eval-when-compile ;; Define a user-level skeleton and add it to `python-skeletons' and @@ -2030,8 +2054,9 @@ The default contents correspond to the elements of `python-skeletons'.") (function (intern (concat "python-insert-" name)))) `(progn (add-to-list 'python-skeletons ',(cons name function)) - (if python-use-skeletons - (define-abbrev python-mode-abbrev-table ,name "" ',function nil t)) + (define-abbrev python-mode-abbrev-table ,name "" ',function + :system t :case-fixed t + :enable-function (lambda () python-use-skeletons)) (define-skeleton ,function ,(format "Insert Python \"%s\" template." name) ,@elements))))) @@ -2186,23 +2211,6 @@ without confirmation." (defvar outline-heading-end-regexp) (defvar eldoc-documentation-function) - -;; Stuff to allow expanding abbrevs with non-word constituents. -(defun python-abbrev-pc-hook () - "Set the syntax table before possibly expanding abbrevs." - (remove-hook 'post-command-hook 'python-abbrev-pc-hook t) - (set-syntax-table python-mode-syntax-table)) - -(defvar python-abbrev-syntax-table - (copy-syntax-table python-mode-syntax-table) - "Syntax table used when expanding abbrevs.") - -(defun python-pea-hook () - "Reset the syntax table after possibly expanding abbrevs." - (set-syntax-table python-abbrev-syntax-table) - (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t)) -(modify-syntax-entry ?/ "w" python-abbrev-syntax-table) - (defvar python-mode-running) ;Dynamically scoped var. ;;;###autoload @@ -2270,6 +2278,7 @@ with skeleton expansions for compound statement templates. (set (make-local-variable 'beginning-of-defun-function) 'python-beginning-of-defun) (set (make-local-variable 'end-of-defun-function) 'python-end-of-defun) + (add-hook 'which-func-functions 'python-which-func nil t) (setq imenu-create-index-function #'python-imenu-create-index) (set (make-local-variable 'eldoc-documentation-function) #'python-eldoc-function) @@ -2289,7 +2298,6 @@ with skeleton expansions for compound statement templates. '((< '(backward-delete-char-untabify (min python-indent (current-column)))) (^ '(- (1+ (current-indentation)))))) - (add-hook 'pre-abbrev-expand-hook 'python-pea-hook nil t) (if (featurep 'hippie-exp) (set (make-local-variable 'hippie-expand-try-functions-list) (cons 'python-try-complete hippie-expand-try-functions-list))) |