aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorStefan Monnier2006-08-25 22:49:14 +0000
committerStefan Monnier2006-08-25 22:49:14 +0000
commit1c1095bfeb058341c89db46606daa23a5cc95058 (patch)
treec4ed28747bff26d8ad7da191021fcef9270b9952 /lisp/progmodes/python.el
parent0304d18be9b1f2711c31fdb9f1b6a5e8c8af84e6 (diff)
downloademacs-1c1095bfeb058341c89db46606daa23a5cc95058.tar.gz
emacs-1c1095bfeb058341c89db46606daa23a5cc95058.zip
(python-preoutput-skip-next-prompt): New var.
(python-preoutput-continuation): Remove. (python-preoutput-filter): Simplify correspondingly. Remove handling of _emacs_ok. Make sure we skip _emacs_out's prompts. Loop around to catch embedded _emacs_out output. (run-python): Send the import&print command on a single line. (python-send-command): Send command&print on a single line. (python-send-string): Only add double \n if needed. (python-send-receive): Loop until the result comes. (python-mode-running): Defvar it. (python-setup-brm): Remove unused var `menu'. Only bind py-mode-map and `features' around brm-init. (python-calculate-indentation): Remove unused var `point'. (python-beginning-of-defun): Remove unused var `def-line'.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el234
1 files changed, 125 insertions, 109 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 8a7b0537516..a7942c603f3 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -65,6 +65,7 @@
65;;; Code: 65;;; Code:
66 66
67(eval-when-compile 67(eval-when-compile
68 (require 'cl)
68 (require 'compile) 69 (require 'compile)
69 (require 'comint)) 70 (require 'comint))
70 71
@@ -547,40 +548,39 @@ Set `python-indent' locally to the value guessed."
547 ((looking-at (rx (0+ space) (syntax comment-start) 548 ((looking-at (rx (0+ space) (syntax comment-start)
548 (not (any " \t\n")))) ; non-indentable comment 549 (not (any " \t\n")))) ; non-indentable comment
549 (current-indentation)) 550 (current-indentation))
550 (t (let ((point (point))) 551 (t (if python-honour-comment-indentation
551 (if python-honour-comment-indentation 552 ;; Back over whitespace, newlines, non-indentable comments.
552 ;; Back over whitespace, newlines, non-indentable comments. 553 (catch 'done
553 (catch 'done 554 (while t
554 (while t 555 (if (cond ((bobp))
555 (if (cond ((bobp)) 556 ;; not at comment start
556 ;; not at comment start 557 ((not (forward-comment -1))
557 ((not (forward-comment -1)) 558 (python-beginning-of-statement)
558 (python-beginning-of-statement) 559 t)
559 t) 560 ;; trailing comment
560 ;; trailing comment 561 ((/= (current-column) (current-indentation))
561 ((/= (current-column) (current-indentation)) 562 (python-beginning-of-statement)
562 (python-beginning-of-statement) 563 t)
563 t) 564 ;; indentable comment like python-mode.el
564 ;; indentable comment like python-mode.el 565 ((and (looking-at (rx (syntax comment-start)
565 ((and (looking-at (rx (syntax comment-start) 566 (or space line-end)))
566 (or space line-end))) 567 (/= 0 (current-column)))))
567 (/= 0 (current-column))))) 568 (throw 'done t)))))
568 (throw 'done t))))) 569 (python-indentation-levels)
569 (python-indentation-levels) 570 ;; Prefer to indent comments with an immediately-following
570 ;; Prefer to indent comments with an immediately-following 571 ;; statement, e.g.
571 ;; statement, e.g. 572 ;; ...
572 ;; ... 573 ;; # ...
573 ;; # ... 574 ;; def ...
574 ;; def ... 575 (when (and (> python-indent-list-length 1)
575 (when (and (> python-indent-list-length 1) 576 (python-comment-line-p))
576 (python-comment-line-p)) 577 (forward-line)
577 (forward-line) 578 (unless (python-comment-line-p)
578 (unless (python-comment-line-p) 579 (let ((elt (assq (current-indentation) python-indent-list)))
579 (let ((elt (assq (current-indentation) python-indent-list))) 580 (setq python-indent-list
580 (setq python-indent-list 581 (nconc (delete elt python-indent-list)
581 (nconc (delete elt python-indent-list) 582 (list elt))))))
582 (list elt)))))) 583 (caar (last python-indent-list)))))))
583 (caar (last python-indent-list))))))))
584 584
585;;;; Cycling through the possible indentations with successive TABs. 585;;;; Cycling through the possible indentations with successive TABs.
586 586
@@ -755,13 +755,13 @@ reached start of buffer."
755 (let ((ci (current-indentation)) 755 (let ((ci (current-indentation))
756 (def-re (rx line-start (0+ space) (or "def" "class") (1+ space) 756 (def-re (rx line-start (0+ space) (or "def" "class") (1+ space)
757 (group (1+ (or word (syntax symbol)))))) 757 (group (1+ (or word (syntax symbol))))))
758 found lep def-line) 758 found lep) ;; def-line
759 (if (python-comment-line-p) 759 (if (python-comment-line-p)
760 (setq ci most-positive-fixnum)) 760 (setq ci most-positive-fixnum))
761 (while (and (not (bobp)) (not found)) 761 (while (and (not (bobp)) (not found))
762 ;; Treat bol at beginning of function as outside function so 762 ;; Treat bol at beginning of function as outside function so
763 ;; that successive C-M-a makes progress backwards. 763 ;; that successive C-M-a makes progress backwards.
764 (setq def-line (looking-at def-re)) 764 ;;(setq def-line (looking-at def-re))
765 (unless (bolp) (end-of-line)) 765 (unless (bolp) (end-of-line))
766 (setq lep (line-end-position)) 766 (setq lep (line-end-position))
767 (if (and (re-search-backward def-re nil 'move) 767 (if (and (re-search-backward def-re nil 'move)
@@ -773,7 +773,7 @@ reached start of buffer."
773 ;; Not sure why it was like this -- fails in case of 773 ;; Not sure why it was like this -- fails in case of
774 ;; last internal function followed by first 774 ;; last internal function followed by first
775 ;; non-def statement of the main body. 775 ;; non-def statement of the main body.
776;; (and def-line (= in ci)) 776 ;;(and def-line (= in ci))
777 (= in ci) 777 (= in ci)
778 (< in ci))) 778 (< in ci)))
779 (not (python-in-string/comment))) 779 (not (python-in-string/comment)))
@@ -1250,47 +1250,57 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
1250(defvar python-preoutput-result nil 1250(defvar python-preoutput-result nil
1251 "Data from last `_emacs_out' line seen by the preoutput filter.") 1251 "Data from last `_emacs_out' line seen by the preoutput filter.")
1252 1252
1253(defvar python-preoutput-continuation nil
1254 "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.")
1255
1256(defvar python-preoutput-leftover nil) 1253(defvar python-preoutput-leftover nil)
1254(defvar python-preoutput-skip-next-prompt nil)
1257 1255
1258;; Using this stops us getting lines in the buffer like 1256;; Using this stops us getting lines in the buffer like
1259;; >>> ... ... >>> 1257;; >>> ... ... >>>
1260;; Also look for (and delete) an `_emacs_ok' string and call
1261;; `python-preoutput-continuation' if we get it.
1262(defun python-preoutput-filter (s) 1258(defun python-preoutput-filter (s)
1263 "`comint-preoutput-filter-functions' function: ignore prompts not at bol." 1259 "`comint-preoutput-filter-functions' function: ignore prompts not at bol."
1264 (when python-preoutput-leftover 1260 (when python-preoutput-leftover
1265 (setq s (concat python-preoutput-leftover s)) 1261 (setq s (concat python-preoutput-leftover s))
1266 (setq python-preoutput-leftover nil)) 1262 (setq python-preoutput-leftover nil))
1267 (cond ((and (string-match (rx string-start (repeat 3 (any ".>")) 1263 (let ((start 0)
1268 " " string-end) 1264 (res ""))
1269 s) 1265 ;; First process whole lines.
1270 (/= (let ((inhibit-field-text-motion t)) 1266 (while (string-match "\n" s start)
1271 (line-beginning-position)) 1267 (let ((line (substring s start (setq start (match-end 0)))))
1272 (point))) 1268 ;; Skip prompt if needed.
1273 ;; The need for this seems to be system-dependent: 1269 (when (and python-preoutput-skip-next-prompt
1274 ;; What is this all about, exactly? --Stef 1270 (string-match comint-prompt-regexp line))
1275 ;; (if (and (eq ?. (aref s 0))) 1271 (setq python-preoutput-skip-next-prompt nil)
1276 ;; (accept-process-output (get-buffer-process (current-buffer)) 1)) 1272 (setq line (substring line (match-end 0))))
1277 "") 1273 ;; Recognize special _emacs_out lines.
1278 ((string= s "_emacs_ok\n") 1274 (if (and (string-match "\\`_emacs_out \\(.*\\)\n\\'" line)
1279 (when python-preoutput-continuation 1275 (local-variable-p 'python-preoutput-result))
1280 (funcall python-preoutput-continuation) 1276 (progn
1281 (setq python-preoutput-continuation nil)) 1277 (setq python-preoutput-result (match-string 1 line))
1282 "") 1278 (set (make-local-variable 'python-preoutput-skip-next-prompt) t))
1283 ((string-match "_emacs_out \\(.*\\)\n" s) 1279 (setq res (concat res line)))))
1284 (setq python-preoutput-result (match-string 1 s)) 1280 ;; Then process the remaining partial line.
1285 "") 1281 (unless (zerop start) (setq s (substring s start)))
1286 ((string-match ".*\n" s) 1282 (cond ((and (string-match comint-prompt-regexp s)
1287 s) 1283 ;; Drop this prompt if it follows an _emacs_out...
1288 ((or (eq t (compare-strings s nil nil "_emacs_ok\n" nil (length s))) 1284 (or python-preoutput-skip-next-prompt
1289 (let ((end (min (length "_emacs_out ") (length s)))) 1285 ;; ... or if it's not gonna be inserted at BOL.
1290 (eq t (compare-strings s nil end "_emacs_out " nil end)))) 1286 ;; Maybe we could be more selective here.
1291 (setq python-preoutput-leftover s) 1287 (if (zerop (length res))
1292 "") 1288 (not (bolp))
1293 (t s))) 1289 (string-match res ".\\'"))))
1290 ;; The need for this seems to be system-dependent:
1291 ;; What is this all about, exactly? --Stef
1292 ;; (if (and (eq ?. (aref s 0)))
1293 ;; (accept-process-output (get-buffer-process (current-buffer)) 1))
1294 (setq python-preoutput-skip-next-prompt nil)
1295 res)
1296 ((let ((end (min (length "_emacs_out ") (length s))))
1297 (eq t (compare-strings s nil end "_emacs_out " nil end)))
1298 ;; The leftover string is a prefix of _emacs_out so we don't know
1299 ;; yet whether it's an _emacs_out or something else: wait until we
1300 ;; get more output so we can resolve this ambiguity.
1301 (set (make-local-variable 'python-preoutput-leftover) s)
1302 res)
1303 (t (concat res s)))))
1294 1304
1295(autoload 'comint-check-proc "comint") 1305(autoload 'comint-check-proc "comint")
1296 1306
@@ -1342,9 +1352,8 @@ buffer for a list of commands.)"
1342 ;; file. The code might be inline here, but there's enough that it 1352 ;; file. The code might be inline here, but there's enough that it
1343 ;; seems worth putting in a separate file, and it's probably cleaner 1353 ;; seems worth putting in a separate file, and it's probably cleaner
1344 ;; to put it in a module. 1354 ;; to put it in a module.
1345 (python-send-string "import emacs")
1346 ;; Ensure we're at a prompt before doing anything else. 1355 ;; Ensure we're at a prompt before doing anything else.
1347 (python-send-receive "print '_emacs_out ()'") 1356 (python-send-receive "import emacs; print '_emacs_out ()'")
1348 ;; Without this, help output goes into the inferior python buffer if 1357 ;; Without this, help output goes into the inferior python buffer if
1349 ;; the process isn't already running. 1358 ;; the process isn't already running.
1350 (sit-for 1 t) ;Should we use accept-process-output instead? --Stef 1359 (sit-for 1 t) ;Should we use accept-process-output instead? --Stef
@@ -1358,13 +1367,14 @@ buffer for a list of commands.)"
1358;; commands having set up such a state. 1367;; commands having set up such a state.
1359 1368
1360(defun python-send-command (command) 1369(defun python-send-command (command)
1361 "Like `python-send-string' but resets `compilation-shell-minor-mode'." 1370 "Like `python-send-string' but resets `compilation-shell-minor-mode'.
1371COMMAND should be a single statement."
1372 (assert (not (string-match "\n" command)))
1362 (let ((end (marker-position (process-mark (python-proc))))) 1373 (let ((end (marker-position (process-mark (python-proc)))))
1363 (with-current-buffer python-buffer (goto-char (point-max))) 1374 (with-current-buffer python-buffer (goto-char (point-max)))
1364 (compilation-forget-errors) 1375 (compilation-forget-errors)
1365 (python-send-string command)
1366 ;; Must wait until this has completed before re-setting variables below. 1376 ;; Must wait until this has completed before re-setting variables below.
1367 (python-send-receive "print '_emacs_out ()'") 1377 (python-send-receive (concat command "; print '_emacs_out ()'"))
1368 (with-current-buffer python-buffer 1378 (with-current-buffer python-buffer
1369 (set-marker compilation-parsing-end end) 1379 (set-marker compilation-parsing-end end)
1370 (setq compilation-last-buffer (current-buffer))))) 1380 (setq compilation-last-buffer (current-buffer)))))
@@ -1409,7 +1419,11 @@ buffer for a list of commands.)"
1409 "Evaluate STRING in inferior Python process." 1419 "Evaluate STRING in inferior Python process."
1410 (interactive "sPython command: ") 1420 (interactive "sPython command: ")
1411 (comint-send-string (python-proc) string) 1421 (comint-send-string (python-proc) string)
1412 (comint-send-string (python-proc) "\n\n")) 1422 (comint-send-string (python-proc)
1423 ;; If the string is single-line or if it ends with \n,
1424 ;; only add a single \n, otherwise add 2, so as to
1425 ;; make sure we terminate the multiline instruction.
1426 (if (string-match "\n.+\\'" string) "\n\n" "\n")))
1413 1427
1414(defun python-send-buffer () 1428(defun python-send-buffer ()
1415 "Send the current buffer to the inferior Python process." 1429 "Send the current buffer to the inferior Python process."
@@ -1561,14 +1575,15 @@ will."
1561 1575
1562(defun python-send-receive (string) 1576(defun python-send-receive (string)
1563 "Send STRING to inferior Python (if any) and return result. 1577 "Send STRING to inferior Python (if any) and return result.
1564The result is what follows `_emacs_out' in the output (or nil)." 1578The result is what follows `_emacs_out' in the output."
1565 (let ((proc (python-proc))) 1579 (let ((proc (python-proc)))
1566 (python-send-string string) 1580 (python-send-string string)
1567 (setq python-preoutput-result nil) 1581 (set (make-local-variable 'python-preoutput-result) nil)
1568 (while (progn 1582 (while (progn
1569 (accept-process-output proc 5) 1583 (accept-process-output proc 5)
1570 python-preoutput-leftover)) 1584 (null python-preoutput-result)))
1571 python-preoutput-result)) 1585 (prog1 python-preoutput-result
1586 (kill-local-variable 'python-preoutput-result))))
1572 1587
1573;; Fixme: Is there anything reasonable we can do with random methods? 1588;; Fixme: Is there anything reasonable we can do with random methods?
1574;; (Currently only works with functions.) 1589;; (Currently only works with functions.)
@@ -2078,36 +2093,35 @@ without confirmation."
2078 (unless (fboundp 'brm-rename) 2093 (unless (fboundp 'brm-rename)
2079 (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe 2094 (pymacs-load "bikeemacs" "brm-") ; first line of normal recipe
2080 (let ((py-mode-map (make-sparse-keymap)) ; it assumes this 2095 (let ((py-mode-map (make-sparse-keymap)) ; it assumes this
2081 (features (cons 'python-mode features)) ; and requires this 2096 (features (cons 'python-mode features))) ; and requires this
2082 menu) 2097 (brm-init)) ; second line of normal recipe
2083 (brm-init) ; second line of normal recipe 2098 (remove-hook 'python-mode-hook ; undo this from `brm-init'
2084 (remove-hook 'python-mode-hook ; undo this from `brm-init' 2099 '(lambda () (easy-menu-add brm-menu)))
2085 '(lambda () (easy-menu-add brm-menu))) 2100 (easy-menu-define
2086 (easy-menu-define 2101 python-brm-menu python-mode-map
2087 python-brm-menu python-mode-map 2102 "Bicycle Repair Man"
2088 "Bicycle Repair Man" 2103 '("BicycleRepairMan"
2089 '("BicycleRepairMan" 2104 :help "Interface to navigation and refactoring tool"
2090 :help "Interface to navigation and refactoring tool" 2105 "Queries"
2091 "Queries" 2106 ["Find References" brm-find-references
2092 ["Find References" brm-find-references 2107 :help "Find references to name at point in compilation buffer"]
2093 :help "Find references to name at point in compilation buffer"] 2108 ["Find Definition" brm-find-definition
2094 ["Find Definition" brm-find-definition 2109 :help "Find definition of name at point"]
2095 :help "Find definition of name at point"] 2110 "-"
2096 "-" 2111 "Refactoring"
2097 "Refactoring" 2112 ["Rename" brm-rename
2098 ["Rename" brm-rename 2113 :help "Replace name at point with a new name everywhere"]
2099 :help "Replace name at point with a new name everywhere"] 2114 ["Extract Method" brm-extract-method
2100 ["Extract Method" brm-extract-method 2115 :active (and mark-active (not buffer-read-only))
2101 :active (and mark-active (not buffer-read-only)) 2116 :help "Replace statements in region with a method"]
2102 :help "Replace statements in region with a method"] 2117 ["Extract Local Variable" brm-extract-local-variable
2103 ["Extract Local Variable" brm-extract-local-variable 2118 :active (and mark-active (not buffer-read-only))
2104 :active (and mark-active (not buffer-read-only)) 2119 :help "Replace expression in region with an assignment"]
2105 :help "Replace expression in region with an assignment"] 2120 ["Inline Local Variable" brm-inline-local-variable
2106 ["Inline Local Variable" brm-inline-local-variable 2121 :help
2107 :help 2122 "Substitute uses of variable at point with its definition"]
2108 "Substitute uses of variable at point with its definition"] 2123 ;; Fixme: Should check for anything to revert.
2109 ;; Fixme: Should check for anything to revert. 2124 ["Undo Last Refactoring" brm-undo :help ""])))
2110 ["Undo Last Refactoring" brm-undo :help ""]))))
2111 (error (error "Bicyclerepairman setup failed: %s" data)))) 2125 (error (error "Bicyclerepairman setup failed: %s" data))))
2112 2126
2113;;;; Modes. 2127;;;; Modes.
@@ -2131,6 +2145,8 @@ without confirmation."
2131 (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t)) 2145 (add-hook 'post-command-hook 'python-abbrev-pc-hook nil t))
2132(modify-syntax-entry ?/ "w" python-abbrev-syntax-table) 2146(modify-syntax-entry ?/ "w" python-abbrev-syntax-table)
2133 2147
2148(defvar python-mode-running) ;Dynamically scoped var.
2149
2134;;;###autoload 2150;;;###autoload
2135(define-derived-mode python-mode fundamental-mode "Python" 2151(define-derived-mode python-mode fundamental-mode "Python"
2136 "Major mode for editing Python files. 2152 "Major mode for editing Python files.