(define-key map "\C-c\C-f" 'python-eldoc-at-point)
;; Utilities
(substitute-key-definition 'complete-symbol 'completion-at-point
- map global-map)
+ map global-map)
(easy-menu-define python-menu map "Python Mode menu"
`("Python"
- :help "Python-specific Features"
- ["Shift region left" python-indent-shift-left :active mark-active
- :help "Shift region left by a single indentation step"]
- ["Shift region right" python-indent-shift-right :active mark-active
- :help "Shift region right by a single indentation step"]
- "-"
- ["Start of def/class" beginning-of-defun
- :help "Go to start of outermost definition around point"]
- ["End of def/class" end-of-defun
- :help "Go to end of definition around point"]
- ["Mark def/class" mark-defun
- :help "Mark outermost definition around point"]
- ["Jump to def/class" python-nav-jump-to-defun
- :help "Jump to a class or function definition"]
+ :help "Python-specific Features"
+ ["Shift region left" python-indent-shift-left :active mark-active
+ :help "Shift region left by a single indentation step"]
+ ["Shift region right" python-indent-shift-right :active mark-active
+ :help "Shift region right by a single indentation step"]
+ "-"
+ ["Start of def/class" beginning-of-defun
+ :help "Go to start of outermost definition around point"]
+ ["End of def/class" end-of-defun
+ :help "Go to end of definition around point"]
+ ["Mark def/class" mark-defun
+ :help "Mark outermost definition around point"]
+ ["Jump to def/class" python-nav-jump-to-defun
+ :help "Jump to a class or function definition"]
"--"
- ("Skeletons")
+ ("Skeletons")
"---"
- ["Start interpreter" run-python
- :help "Run inferior Python process in a separate buffer"]
- ["Switch to shell" python-shell-switch-to-shell
- :help "Switch to running inferior Python process"]
- ["Eval string" python-shell-send-string
- :help "Eval string in inferior Python session"]
- ["Eval buffer" python-shell-send-buffer
- :help "Eval buffer in inferior Python session"]
- ["Eval region" python-shell-send-region
- :help "Eval region in inferior Python session"]
- ["Eval defun" python-shell-send-defun
- :help "Eval defun in inferior Python session"]
- ["Eval file" python-shell-send-file
- :help "Eval file in inferior Python session"]
- ["Debugger" pdb :help "Run pdb under GUD"]
+ ["Start interpreter" run-python
+ :help "Run inferior Python process in a separate buffer"]
+ ["Switch to shell" python-shell-switch-to-shell
+ :help "Switch to running inferior Python process"]
+ ["Eval string" python-shell-send-string
+ :help "Eval string in inferior Python session"]
+ ["Eval buffer" python-shell-send-buffer
+ :help "Eval buffer in inferior Python session"]
+ ["Eval region" python-shell-send-region
+ :help "Eval region in inferior Python session"]
+ ["Eval defun" python-shell-send-defun
+ :help "Eval defun in inferior Python session"]
+ ["Eval file" python-shell-send-file
+ :help "Eval file in inferior Python session"]
+ ["Debugger" pdb :help "Run pdb under GUD"]
"----"
- ["Check file" python-check
- :help "Check file for errors"]
- ["Help on symbol" python-eldoc-at-point
- :help "Get help on symbol at point"]
- ["Complete symbol" completion-at-point
- :help "Complete symbol before point"]))
+ ["Check file" python-check
+ :help "Check file for errors"]
+ ["Help on symbol" python-eldoc-at-point
+ :help "Get help on symbol at point"]
+ ["Complete symbol" completion-at-point
+ :help "Complete symbol before point"]))
map)
"Keymap for `python-mode'.")
"except" "finally" "for" "while" "with")
symbol-end))
`(decorator . ,(rx line-start (* space) ?@ (any letter ?_)
- (* (any word ?_))))
+ (* (any word ?_))))
`(defun . ,(rx symbol-start (or "def" "class") symbol-end))
`(symbol-name . ,(rx (any letter ?_) (* (any word ?_))))
`(open-paren . ,(rx (or "{" "[" "(")))
`(close-paren . ,(rx (or "}" "]" ")")))
`(simple-operator . ,(rx (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)))
- `(not-simple-operator . ,(rx (not (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))))
+ `(not-simple-operator . ,(rx
+ (not
+ (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%))))
`(operator . ,(rx (or "+" "-" "/" "&" "^" "~" "|" "*" "<" ">"
"=" "%" "**" "//" "<<" ">>" "<=" "!="
"==" ">=" "is" "not")))
"Additional Python specific sexps for `python-rx'"))
(defmacro python-rx (&rest regexps)
- "Python mode specialized rx macro which supports common python named REGEXPS."
- (let ((rx-constituents (append python-rx-constituents rx-constituents)))
- (cond ((null regexps)
- (error "No regexp"))
- ((cdr regexps)
- (rx-to-string `(and ,@regexps) t))
- (t
- (rx-to-string (car regexps) t)))))
+ "Python mode specialized rx macro.
+This variant of `rx' supports common python named REGEXPS."
+ (let ((rx-constituents (append python-rx-constituents rx-constituents)))
+ (cond ((null regexps)
+ (error "No regexp"))
+ ((cdr regexps)
+ (rx-to-string `(and ,@regexps) t))
+ (t
+ (rx-to-string (car regexps) t)))))
\f
;;; Font-lock and syntax
;; string delimiters. Fixme: Is there a better way?
;; First avoid a sequence preceded by an odd number of backslashes.
`((,(concat "\\(?:\\([RUru]\\)[Rr]?\\|^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix.
- "\\(?:\\('\\)'\\('\\)\\|\\(?2:\"\\)\"\\(?3:\"\\)\\)")
+ "\\(?:\\('\\)'\\('\\)\\|\\(?2:\"\\)\"\\(?3:\"\\)\\)")
(3 (python-quote-syntax)))))
(defun python-quote-syntax ()
(cond
((eq t (nth 3 syntax)) ; after unclosed fence
;; Consider property for the last char if in a fenced string.
- (goto-char (nth 8 syntax)) ; fence position
- (skip-chars-forward "uUrR") ; skip any prefix
+ (goto-char (nth 8 syntax)) ; fence position
+ (skip-chars-forward "uUrR") ; skip any prefix
;; Is it a matching sequence?
(if (eq (char-after) (char-after (match-beginning 2)))
(put-text-property (match-beginning 3) (match-end 3)
;; Give punctuation syntax to ASCII that normally has symbol
;; syntax or has word syntax and isn't a letter.
(let ((symbol (string-to-syntax "_"))
- (sst (standard-syntax-table)))
+ (sst (standard-syntax-table)))
(dotimes (i 128)
- (unless (= i ?_)
- (if (equal symbol (aref sst i))
- (modify-syntax-entry i "." table)))))
+ (unless (= i ?_)
+ (if (equal symbol (aref sst i))
+ (modify-syntax-entry i "." table)))))
(modify-syntax-entry ?$ "." table)
(modify-syntax-entry ?% "." table)
;; exceptions
(defun python-indent-guess-indent-offset ()
"Guess and set `python-indent-offset' for the current buffer."
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (let ((block-end))
- (while (and (not block-end)
- (re-search-forward
- (python-rx line-start block-start) nil t))
- (when (and
- (not (python-info-ppss-context-type))
- (progn
- (goto-char (line-end-position))
- (python-util-forward-comment -1)
- (if (equal (char-before) ?:)
- t
- (forward-line 1)
- (when (python-info-block-continuation-line-p)
- (while (and (python-info-continuation-line-p)
- (not (eobp)))
- (forward-line 1))
- (python-util-forward-comment -1)
- (when (equal (char-before) ?:)
- t)))))
- (setq block-end (point-marker))))
- (let ((indentation
- (when block-end
- (goto-char block-end)
- (python-util-forward-comment)
- (current-indentation))))
- (if indentation
- (setq python-indent-offset indentation)
- (message "Can't guess python-indent-offset, using defaults: %s"
- python-indent-offset)))))))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (let ((block-end))
+ (while (and (not block-end)
+ (re-search-forward
+ (python-rx line-start block-start) nil t))
+ (when (and
+ (not (python-info-ppss-context-type))
+ (progn
+ (goto-char (line-end-position))
+ (python-util-forward-comment -1)
+ (if (equal (char-before) ?:)
+ t
+ (forward-line 1)
+ (when (python-info-block-continuation-line-p)
+ (while (and (python-info-continuation-line-p)
+ (not (eobp)))
+ (forward-line 1))
+ (python-util-forward-comment -1)
+ (when (equal (char-before) ?:)
+ t)))))
+ (setq block-end (point-marker))))
+ (let ((indentation
+ (when block-end
+ (goto-char block-end)
+ (python-util-forward-comment)
+ (current-indentation))))
+ (if indentation
+ (setq python-indent-offset indentation)
+ (message "Can't guess python-indent-offset, using defaults: %s"
+ python-indent-offset)))))))
(defun python-indent-context ()
"Get information on indentation context.
((setq start (when (not (or (python-info-ppss-context 'string ppss)
(python-info-ppss-context 'comment ppss)))
(let ((line-beg-pos (line-beginning-position)))
- (when (python-info-line-ends-backslash-p (1- line-beg-pos))
+ (when (python-info-line-ends-backslash-p
+ (1- line-beg-pos))
(- line-beg-pos 2)))))
'after-backslash)
;; After beginning of block
(when (looking-at "\\.")
(forward-line -1)
(goto-char (line-end-position))
- (while (and (re-search-backward "\\." (line-beginning-position) t)
+ (while (and (re-search-backward
+ "\\." (line-beginning-position) t)
(or (python-info-ppss-context 'comment)
(python-info-ppss-context 'string)
(python-info-ppss-context 'paren))))
(python-info-line-ends-backslash-p))
(python-info-ppss-context 'string)
(python-info-ppss-context 'paren))
- (forward-line -1)))))
+ (forward-line -1)))))
(defun python-nav-sentence-end ()
"Move to end of current sentence."
(python-info-line-ends-backslash-p)
(python-info-ppss-context 'string)
(python-info-ppss-context 'paren))
- (forward-line 1)))))
+ (forward-line 1)))))
(defun python-nav-backward-sentence (&optional arg)
"Move backward to start of sentence. With ARG, do it arg times.
(defcustom python-shell-compilation-regexp-alist
`((,(rx line-start (1+ (any " \t")) "File \""
- (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
- "\", line " (group (1+ digit)))
+ (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c
+ "\", line " (group (1+ digit)))
1 2)
(,(rx " in file " (group (1+ not-newline)) " on line "
- (group (1+ digit)))
+ (group (1+ digit)))
1 2)
(,(rx line-start "> " (group (1+ (not (any "(\"<"))))
- "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
+ "(" (group (1+ digit)) ")" (1+ (not (any "("))) "()")
1 2))
"`compilation-error-regexp-alist' for inferior Python."
:type '(alist string)
"Do completion at point for PROCESS."
(with-syntax-table python-dotty-syntax-table
(let* ((line (substring-no-properties
- (buffer-substring (point-at-bol) (point)) nil nil))
- (input (substring-no-properties
- (or (comint-word (current-word)) "") nil nil))
+ (buffer-substring (point-at-bol) (point)) nil nil))
+ (input (substring-no-properties
+ (or (comint-word (current-word)) "") nil nil))
(prompt (buffer-substring-no-properties
(overlay-start comint-last-prompt-overlay)
(overlay-end comint-last-prompt-overlay)))
- (completion-code
+ (completion-code
(cond ((and (> (length python-shell-completion-pdb-string-code) 0)
(string-match
(concat "^" python-shell-prompt-pdb-regexp) prompt))
python-shell-completion-pdb-string-code)
- ((and (> (length python-shell-completion-module-string-code) 0)
+ ((and (>
+ (length python-shell-completion-module-string-code) 0)
(string-match
(concat "^" python-shell-prompt-regexp) prompt)
(string-match "^\\(from\\|import\\)[ \t]" line))
(and completion-code (> (length input) 0)
(python-shell-completion--get-completions
line process completion-code)))
- (completion (when completions
- (try-completion input completions))))
+ (completion (when completions
+ (try-completion input completions))))
(cond ((eq completion t)
- (if (eq this-command last-command)
- (when python-shell-completion-original-window-configuration
- (set-window-configuration
- python-shell-completion-original-window-configuration)))
- (setq python-shell-completion-original-window-configuration nil)
- t)
- ((null completion)
- (message "Can't find completion for \"%s\"" input)
- (ding)
+ (if (eq this-command last-command)
+ (when python-shell-completion-original-window-configuration
+ (set-window-configuration
+ python-shell-completion-original-window-configuration)))
+ (setq python-shell-completion-original-window-configuration nil)
+ t)
+ ((null completion)
+ (message "Can't find completion for \"%s\"" input)
+ (ding)
nil)
((not (string= input completion))
(progn (delete-char (- (length input)))
(and comint-last-prompt-overlay
(> (point-marker) (overlay-end comint-last-prompt-overlay))
(python-shell-completion--do-completion-at-point
- (get-buffer-process (current-buffer)))))
+ (get-buffer-process (current-buffer)))))
(defun python-shell-completion-complete-or-indent ()
"Complete or indent depending on the context.
;; but in some cases (like when doing a step-in) it is
;; on the second.
(when (or (looking-at python-pdbtrack-stacktrace-info-regexp)
- (and (forward-line)
- (looking-at python-pdbtrack-stacktrace-info-regexp)))
+ (and
+ (forward-line)
+ (looking-at python-pdbtrack-stacktrace-info-regexp)))
(setq line-number (string-to-number
(match-string-no-properties 2)))
(match-string-no-properties 1)))))
(if (and file-name line-number)
- (let* ((tracked-buffer (python-pdbtrack-set-tracked-buffer file-name))
+ (let* ((tracked-buffer
+ (python-pdbtrack-set-tracked-buffer file-name))
(shell-buffer (current-buffer))
(tracked-buffer-window (get-buffer-window tracked-buffer))
(tracked-buffer-line-pos))
(error "Completion needs an inferior Python process running")
(python-shell-completion--do-completion-at-point process))))
-(add-to-list 'debug-ignored-errors "^Completion needs an inferior Python process running.")
+(add-to-list 'debug-ignored-errors
+ "^Completion needs an inferior Python process running.")
\f
;;; Fill paragraph
The skeleton will be bound to python-skeleton-NAME and will
be added to `python-mode-abbrev-table'."
(let* ((name (symbol-name name))
- (function-name (intern (concat "python-skeleton-" name))))
+ (function-name (intern (concat "python-skeleton-" name))))
`(progn
(define-abbrev python-mode-abbrev-table ,name "" ',function-name)
(setq python-skeleton-available
"Define a `python-mode' auxiliary skeleton using NAME DOC and SKEL.
The skeleton will be bound to python-skeleton-NAME."
(let* ((name (symbol-name name))
- (function-name (intern (concat "python-skeleton--" name)))
+ (function-name (intern (concat "python-skeleton--" name)))
(msg (format
"Add '%s' clause? " name)))
(when (not skel)
"Function name: "
"def " str " (" ("Parameter, %s: "
(unless (equal ?\( (char-before)) ", ")
- str) "):" \n
- "\"\"\"" - "\"\"\"" \n
- > _ \n)
+ str) "):" \n
+ "\"\"\"" - "\"\"\"" \n
+ > _ \n)
(python-skeleton-define class nil
"Class name: "
"class " str " (" ("Inheritance, %s: "
- (unless (equal ?\( (char-before)) ", ")
- str)
+ (unless (equal ?\( (char-before)) ", ")
+ str)
& ")" | -2
":" \n
"\"\"\"" - "\"\"\"" \n
(python-shell-send-string-no-output
(format python-ffap-string-code module) process)))
(when module-file
- (substring-no-properties module-file 1 -1))))))
+ (substring-no-properties module-file 1 -1))))))
(eval-after-load "ffap"
'(progn
`python-check-command' for the default."
(interactive
(list (read-string "Check command: "
- (or python-check-custom-command
- (concat python-check-command " "
+ (or python-check-custom-command
+ (concat python-check-command " "
(shell-quote-argument
(or
(let ((name (buffer-file-name)))
(current-word)
(concat current-defun "." (current-word))))))
(ppss (syntax-ppss))
- (help (when (and input
- (not (string= input (concat current-defun ".")))
- (not (or (python-info-ppss-context 'string ppss)
- (python-info-ppss-context 'comment ppss))))
- (when (string-match (concat
- (regexp-quote (concat current-defun "."))
- "self\\.") input)
+ (help (when (and
+ input
+ (not (string= input (concat current-defun ".")))
+ (not (or (python-info-ppss-context 'string ppss)
+ (python-info-ppss-context 'comment ppss))))
+ (when (string-match
+ (concat
+ (regexp-quote (concat current-defun "."))
+ "self\\.") input)
(with-temp-buffer
(insert input)
(goto-char (point-min))
(forward-word)
(forward-char)
- (delete-region (point-marker) (search-forward "self."))
- (setq input (buffer-substring (point-min) (point-max)))))
+ (delete-region
+ (point-marker) (search-forward "self."))
+ (setq input (buffer-substring
+ (point-min) (point-max)))))
(python-shell-send-string-no-output
(format python-eldoc-string-code input) process))))
(with-current-buffer (process-buffer process)
(defun python-eldoc-at-point (symbol)
"Get help on SYMBOL using `help'.
Interactively, prompt for symbol."
- (interactive
- (let ((symbol (with-syntax-table python-dotty-syntax-table
- (current-word)))
- (enable-recursive-minibuffers t))
- (list (read-string (if symbol
- (format "Describe symbol (default %s): " symbol)
- "Describe symbol: ")
- nil nil symbol))))
- (let ((process (python-shell-get-process)))
- (if (not process)
- (message "Eldoc needs an inferior Python process running.")
- (message (python-eldoc--get-doc-at-point symbol process)))))
+ (interactive
+ (let ((symbol (with-syntax-table python-dotty-syntax-table
+ (current-word)))
+ (enable-recursive-minibuffers t))
+ (list (read-string (if symbol
+ (format "Describe symbol (default %s): " symbol)
+ "Describe symbol: ")
+ nil nil symbol))))
+ (let ((process (python-shell-get-process)))
+ (if (not process)
+ (message "Eldoc needs an inferior Python process running.")
+ (message (python-eldoc--get-doc-at-point symbol process)))))
\f
;;; Imenu
(point-marker))))))))
(defun python-info-line-ends-backslash-p (&optional line-number)
- "Return non-nil if current line ends with backslash.
+ "Return non-nil if current line ends with backslash.
With optional argument LINE-NUMBER, check that line instead."
- (save-excursion
- (save-restriction
- (when line-number
- (goto-char line-number))
- (widen)
- (goto-char (line-end-position))
- (equal (char-after (1- (point))) ?\\))))
+ (save-excursion
+ (save-restriction
+ (when line-number
+ (goto-char line-number))
+ (widen)
+ (goto-char (line-end-position))
+ (equal (char-after (1- (point))) ?\\))))
(defun python-info-continuation-line-p ()
"Check if current line is continuation of another.
(and (symbolp (car pair))
(string-match (or regexp "^python-")
(symbol-name (car pair)))
- (set (make-local-variable (car pair))
- (cdr pair))))
+ (set (make-local-variable (car pair))
+ (cdr pair))))
(buffer-local-variables from-buffer)))
(defun python-util-forward-comment (&optional direction)
nil nil nil nil
(font-lock-syntactic-keywords . python-font-lock-syntactic-keywords)))
- (set (make-local-variable 'indent-line-function) #'python-indent-line-function)
+ (set (make-local-variable 'indent-line-function)
+ #'python-indent-line-function)
(set (make-local-variable 'indent-region-function) #'python-indent-region)
(set (make-local-variable 'paragraph-start) "\\s-*$")
- (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph-function)
+ (set (make-local-variable 'fill-paragraph-function)
+ 'python-fill-paragraph-function)
(set (make-local-variable 'beginning-of-defun-function)
#'python-beginning-of-defun-function)
(set (make-local-variable 'skeleton-further-elements)
'((abbrev-mode nil)
(< '(backward-delete-char-untabify (min python-indent-offset
- (current-column))))
- (^ '(- (1+ (current-indentation))))))
+ (current-column))))
+ (^ '(- (1+ (current-indentation))))))
(set (make-local-variable 'eldoc-documentation-function)
#'python-eldoc-function)
(add-to-list 'hs-special-modes-alist
- `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
+ `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#"
,(lambda (arg)
(python-end-of-defun-function)) nil))