]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/python.el
python.el removed.
[gnu-emacs] / lisp / progmodes / python.el
index 66d8cd4714f9f9425df57944569761f37fb19a84..e57c7e639c9fa50de3fc844e5873c302552bf5d5 100644 (file)
@@ -1,6 +1,6 @@
 ;;; python.el --- silly walks for Python
 
-;; Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+;; Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
 
 ;; Author: Dave Love <fx@gnu.org>
 ;; Maintainer: FSF
@@ -67,7 +67,8 @@
 (eval-when-compile
   (require 'cl)
   (require 'compile)
-  (require 'comint))
+  (require 'comint)
+  (require 'hippie-exp))
 
 (autoload 'comint-mode "comint")
 
@@ -95,7 +96,9 @@
             "import" "in" "is" "lambda" "not" "or" "pass" "print"
             "raise" "return" "try" "while" "yield"
             ;; Future keywords
-            "as" "None")
+            "as" "None"
+             ;; Not real keywords, but close enough to be fontified as such
+             "self" "True" "False")
         symbol-end)
     ;; Definitions
     (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_))))
@@ -160,7 +163,7 @@ Used for syntactic keywords.  N is the match number (1, 2 or 3)."
               (= (match-beginning 1) (match-end 1))) ; prefix is null
          (and (= n 1)                  ; prefix
               (/= (match-beginning 1) (match-end 1)))) ; non-empty
-      (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
+      (unless (nth 3 (syntax-ppss))
         (eval-when-compile (string-to-syntax "|"))))
      ;; Otherwise (we're in a non-matching string) the property is
      ;; nil, which is OK.
@@ -405,6 +408,7 @@ The criteria are that the line isn't a comment or in string and
 See also `\\[python-guess-indent]'"
   :group 'python
   :type 'integer)
+(put 'python-indent 'safe-local-variable 'integerp)
 
 (defcustom python-guess-indent t
   "Non-nil means Python mode guesses `python-indent' for the buffer."
@@ -977,11 +981,15 @@ 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)))
+                      (open (python-open-block-statement-p))
+                      opoint)
                  (if (and (zerop ci) (not open))
                      (not (goto-char point))
                    (catch 'done
-                     (while (zerop (python-next-statement))
+                     (setq opoint (point))
+                     (while (and (zerop (python-next-statement))
+                                 (not (= opoint (point))))
+                       (setq opoint (point))
                        (when (or (and open (<= (current-indentation) ci))
                                  (< (current-indentation) ci))
                          (python-skip-comments/blanks t)
@@ -1146,7 +1154,7 @@ modified by the user.  Additional arguments are added when the command
 is used by `run-python' et al.")
 
 (defvar python-buffer nil
-  "*The current python process buffer.
+  "*The current Python process buffer.
 
 Commands that send text from source buffers to Python processes have
 to choose a process to send to.  This is determined by buffer-local
@@ -1191,6 +1199,15 @@ local value.")
     ;; (define-key map "\C-c\C-f" 'python-describe-symbol)
     map))
 
+(defvar inferior-python-mode-syntax-table
+  (let ((st (make-syntax-table python-mode-syntax-table)))
+    ;; Don't get confused by apostrophes in the process's output (e.g. if
+    ;; you execute "help(os)").
+    (modify-syntax-entry ?\' "." st)
+    ;; Maybe we should do the same for double quotes?
+    ;; (modify-syntax-entry ?\" "." st)
+    st))
+
 ;; 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?
@@ -1213,7 +1230,6 @@ For running multiple processes in multiple buffers, see `run-python' and
 
 \\{inferior-python-mode-map}"
   :group 'python
-  (set-syntax-table python-mode-syntax-table)
   (setq mode-line-process '(":%s"))
   (set (make-local-variable 'comint-input-filter) 'python-input-filter)
   (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
@@ -1286,7 +1302,7 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
                     ;; Maybe we could be more selective here.
                     (if (zerop (length res))
                         (not (bolp))
-                      (string-match res ".\\'"))))
+                      (string-match ".\\'" res))))
            ;; The need for this seems to be system-dependent:
            ;; What is this all about, exactly?  --Stef
            ;; (if (and (eq ?. (aref s 0)))
@@ -1371,11 +1387,11 @@ buffer for a list of commands.)"
 COMMAND should be a single statement."
   ;; (assert (not (string-match "\n" command)))
   ;; (let ((end (marker-position (process-mark (python-proc)))))
-    (with-current-buffer python-buffer (goto-char (point-max)))
+  (with-current-buffer (process-buffer (python-proc))
+    (goto-char (point-max))
     (compilation-forget-errors)
     (python-send-string command)
-    (with-current-buffer python-buffer
-      (setq compilation-last-buffer (current-buffer)))
+    (setq compilation-last-buffer (current-buffer)))
     ;; No idea what this is for but it breaks the call to
     ;; compilation-fake-loc in python-send-region.  -- Stef
     ;; Must wait until this has completed before re-setting variables below.
@@ -1424,11 +1440,13 @@ COMMAND should be a single statement."
   "Evaluate STRING in inferior Python process."
   (interactive "sPython command: ")
   (comint-send-string (python-proc) string)
-  (comint-send-string (python-proc)
-                      ;; If the string is single-line or if it ends with \n,
-                      ;; only add a single \n, otherwise add 2, so as to
-                      ;; make sure we terminate the multiline instruction.
-                      (if (string-match "\n.+\\'" string) "\n\n" "\n")))
+  (unless (string-match "\n\\'" string)
+    ;; Make sure the text is properly LF-terminated.
+    (comint-send-string (python-proc) "\n"))
+  (when (string-match "\n[ \t].*\n?\\'" string)
+    ;; If the string contains a final indented line, add a second newline so
+    ;; as to make sure we terminate the multiline instruction.
+    (comint-send-string (python-proc) "\n")))
 
 (defun python-send-buffer ()
   "Send the current buffer to the inferior Python process."
@@ -1503,9 +1521,9 @@ See variable `python-buffer'.  Starts a new process if necessary."
   ;; isn't one for `python-buffer'.
   (unless (comint-check-proc python-buffer)
     (run-python nil t))
-  (get-buffer-process (or (if (derived-mode-p 'inferior-python-mode)
-                              (current-buffer)
-                            python-buffer))))
+  (get-buffer-process (if (derived-mode-p 'inferior-python-mode)
+                          (current-buffer)
+                        python-buffer)))
 
 (defun python-set-proc ()
   "Set the default value of `python-buffer' to correspond to this buffer.
@@ -1729,12 +1747,11 @@ Otherwise, do nothing."
               (orig (point))
               (start (nth 8 syntax))
               end)
-         (cond ((eq t (nth 3 syntax))      ; in fenced string
-                (goto-char (nth 8 syntax)) ; string start
-                (condition-case ()         ; for unbalanced quotes
-                    (progn (forward-sexp)
-                           (setq end (point)))
-                  (error (setq end (point-max)))))
+         (cond ((eq t (nth 3 syntax))        ; in fenced string
+                (goto-char (nth 8 syntax))   ; string start
+                (setq end (condition-case () ; for unbalanced quotes
+                               (progn (forward-sexp) (point))
+                             (error (point-max)))))
                ((re-search-backward "\\s|\\s-*\\=" nil t) ; end of fenced
                                                           ; string
                 (forward-char)
@@ -1742,13 +1759,17 @@ Otherwise, do nothing."
                 (condition-case ()
                     (progn (backward-sexp)
                            (setq start (point)))
-                  (error nil))))
+                  (error (setq end nil)))))
          (when end
            (save-restriction
              (narrow-to-region start end)
              (goto-char orig)
-             (fill-paragraph justify))))))
-      t)
+              (let ((paragraph-separate
+                     ;; Make sure that fenced-string delimiters that stand
+                     ;; on their own line stay there.
+                     (concat "[ \t]*['\"]+[ \t]*$\\|" paragraph-separate)))
+                (fill-paragraph justify))))))
+      t))
 
 (defun python-shift-left (start end &optional count)
   "Shift lines in region COUNT (the prefix arg) columns to the left.
@@ -1964,6 +1985,13 @@ Repeating the command scrolls the completion window."
 \f
 ;;;; Skeletons
 
+(defcustom python-use-skeletons nil
+  "Non-nil means template skeletons will be automagically inserted.
+This happens when pressing \"if<SPACE>\", for example, to prompt for
+the if condition."
+  :type 'boolean
+  :group 'python)
+
 (defvar python-skeletons nil
   "Alist of named skeletons for Python mode.
 Elements are of the form (NAME . EXPANDER-FUNCTION).")
@@ -1981,7 +2009,8 @@ 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))
-       (define-abbrev python-mode-abbrev-table ,name "" ',function nil t)
+       (if python-use-skeletons
+          (define-abbrev python-mode-abbrev-table ,name "" ',function nil t))
        (define-skeleton ,function
         ,(format "Insert Python \"%s\" template." name)
         ,@elements)))))
@@ -2063,7 +2092,7 @@ The default contents correspond to the elements of `python-skeletons'.")
   > _ \n)
 
 (defvar python-default-template "if"
-  "Default template to expand by `python-insert-template'.
+  "Default template to expand by `python-expand-template'.
 Updated on each expansion.")
 
 (defun python-expand-template (name)
@@ -2200,6 +2229,7 @@ with skeleton expansions for compound statement templates.
                                   ;;  . python-font-lock-syntactic-face-function)
                                   ))
   (set (make-local-variable 'parse-sexp-lookup-properties) t)
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
   (set (make-local-variable 'comment-start) "# ")
   (set (make-local-variable 'indent-line-function) #'python-indent-line)
   (set (make-local-variable 'indent-region-function) #'python-indent-region)