diff options
| author | Stefan Monnier | 2006-08-25 22:49:14 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2006-08-25 22:49:14 +0000 |
| commit | 1c1095bfeb058341c89db46606daa23a5cc95058 (patch) | |
| tree | c4ed28747bff26d8ad7da191021fcef9270b9952 /lisp/progmodes/python.el | |
| parent | 0304d18be9b1f2711c31fdb9f1b6a5e8c8af84e6 (diff) | |
| download | emacs-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.el | 234 |
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'. |
| 1371 | COMMAND 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. |
| 1564 | The result is what follows `_emacs_out' in the output (or nil)." | 1578 | The 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. |