changeset 106482:806e9f7990d8

* minibuffer.el (completion-at-point-functions): New var. (completion-at-point): New command. * indent.el (indent-for-tab-command): Handle the new `complete' behavior. * progmodes/python.el (python-mode-map): Use completion-at-point. (python-completion-at-point): Rename from python-partial-symbol and adjust for use in completion-at-point-functions. (python-mode): Setup completion-at-point for Python completion. * emacs-lisp/lisp.el (lisp-completion-at-point): New function extracted from lisp-complete-symbol. (lisp-complete-symbol): Use it. * emacs-lisp/lisp-mode.el (emacs-lisp-mode): Use define-derived-mode, setup completion-at-point for Elisp completion. (emacs-lisp-mode-map, lisp-interaction-mode-map): Use completion-at-point. * ielm.el (ielm-map): Use completion-at-point. (inferior-emacs-lisp-mode): Setup completion-at-point for Elisp completion. * progmodes/sym-comp.el: Move to... * obsolete/sym-comp.el: Move from progmodes.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 07 Dec 2009 20:06:26 +0000
parents 665bd5e777e1
children d34942d911b5
files etc/NEWS lisp/ChangeLog lisp/emacs-lisp/lisp-mode.el lisp/emacs-lisp/lisp.el lisp/ielm.el lisp/indent.el lisp/minibuffer.el lisp/obsolete/sym-comp.el lisp/progmodes/python.el lisp/progmodes/sym-comp.el
diffstat 10 files changed, 345 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Mon Dec 07 19:21:57 2009 +0000
+++ b/etc/NEWS	Mon Dec 07 20:06:26 2009 +0000
@@ -137,6 +137,10 @@
 
 ** Completion changes
 
+*** The new command `completion-at-point' provides mode-sensitive completion.
+
+*** tab-always-indent set to `complete' lets TAB do completion as well.
+
 *** The new completion-style `initials' is available.
 For instance, this can complete M-x lch to list-command-history.
 
@@ -170,6 +174,8 @@
 ** LaTeX mode now provides completion via latex-complete and
 latex-indent-or-complete.
 
+** sym-comp.el is now declared obsolete, superceded by completion-at-point.
+
 ** lucid.el and levents.el are now declared obsolete.
 
 ** pcomplete provides a new command `pcomplete-std-completion' which
--- a/lisp/ChangeLog	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/ChangeLog	Mon Dec 07 20:06:26 2009 +0000
@@ -1,3 +1,23 @@
+2009-12-07  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* minibuffer.el (completion-at-point-functions): New var.
+	(completion-at-point): New command.
+	* indent.el (indent-for-tab-command): Handle the new `complete' behavior.
+	* progmodes/python.el (python-mode-map): Use completion-at-point.
+	(python-completion-at-point): Rename from python-partial-symbol and
+	adjust for use in completion-at-point-functions.
+	(python-mode): Setup completion-at-point for Python completion.
+	* emacs-lisp/lisp.el (lisp-completion-at-point): New function
+	extracted from lisp-complete-symbol.
+	(lisp-complete-symbol): Use it.
+	* emacs-lisp/lisp-mode.el (emacs-lisp-mode): Use define-derived-mode,
+	setup completion-at-point for Elisp completion.
+	(emacs-lisp-mode-map, lisp-interaction-mode-map): Use completion-at-point.
+	* ielm.el (ielm-map): Use completion-at-point.
+	(inferior-emacs-lisp-mode): Setup completion-at-point for Elisp completion.
+	* progmodes/sym-comp.el: Move to...
+	* obsolete/sym-comp.el: Move from progmodes.
+
 2009-12-07  Eli Zaretskii  <eliz@gnu.org>
 
 	Prevent save-buffer in Rmail buffers from using the coding-system
--- a/lisp/emacs-lisp/lisp-mode.el	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/emacs-lisp/lisp-mode.el	Mon Dec 07 20:06:26 2009 +0000
@@ -280,7 +280,7 @@
 	(prof-map (make-sparse-keymap))
 	(tracing-map (make-sparse-keymap)))
     (set-keymap-parent map lisp-mode-shared-map)
-    (define-key map "\e\t" 'lisp-complete-symbol)
+    (define-key map "\e\t" 'completion-at-point)
     (define-key map "\e\C-x" 'eval-defun)
     (define-key map "\e\C-q" 'indent-pp-sexp)
     (define-key map [menu-bar emacs-lisp] (cons (purecopy "Emacs-Lisp") menu-map))
@@ -431,7 +431,7 @@
   :type 'hook
   :group 'lisp)
 
-(defun emacs-lisp-mode ()
+(define-derived-mode emacs-lisp-mode nil "Emacs-Lisp"
   "Major mode for editing Lisp code to run in Emacs.
 Commands:
 Delete converts tabs to spaces as it moves back.
@@ -440,16 +440,11 @@
 \\{emacs-lisp-mode-map}
 Entry to this mode calls the value of `emacs-lisp-mode-hook'
 if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map emacs-lisp-mode-map)
-  (set-syntax-table emacs-lisp-mode-syntax-table)
-  (setq major-mode 'emacs-lisp-mode)
-  (setq mode-name "Emacs-Lisp")
+  :group 'lisp
   (lisp-mode-variables)
   (setq imenu-case-fold-search nil)
-  (run-mode-hooks 'emacs-lisp-mode-hook))
-(put 'emacs-lisp-mode 'custom-mode-group 'lisp)
+  (add-hook 'completion-at-point-functions
+            'lisp-completion-at-point nil 'local))
 
 (defvar lisp-mode-map
   (let ((map (make-sparse-keymap))
@@ -519,7 +514,7 @@
     (set-keymap-parent map lisp-mode-shared-map)
     (define-key map "\e\C-x" 'eval-defun)
     (define-key map "\e\C-q" 'indent-pp-sexp)
-    (define-key map "\e\t" 'lisp-complete-symbol)
+    (define-key map "\e\t" 'completion-at-point)
     (define-key map "\n" 'eval-print-last-sexp)
     (define-key map [menu-bar lisp-interaction] (cons (purecopy "Lisp-Interaction") menu-map))
     (define-key menu-map [eval-defun]
@@ -535,8 +530,8 @@
     (define-key menu-map [indent-pp-sexp]
       `(menu-item ,(purecopy "Indent or Pretty-Print") indent-pp-sexp
 		  :help ,(purecopy "Indent each line of the list starting just after point, or prettyprint it")))
-    (define-key menu-map [lisp-complete-symbol]
-      `(menu-item ,(purecopy "Complete Lisp Symbol") lisp-complete-symbol
+    (define-key menu-map [complete-symbol]
+      `(menu-item ,(purecopy "Complete Lisp Symbol") completion-at-point
 		  :help ,(purecopy "Perform completion on Lisp symbol preceding point")))
     map)
   "Keymap for Lisp Interaction mode.
--- a/lisp/emacs-lisp/lisp.el	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/emacs-lisp/lisp.el	Mon Dec 07 20:06:26 2009 +0000
@@ -622,6 +622,15 @@
 symbols with function definitions, values or properties are
 considered."
   (interactive)
+  (let* ((data (lisp-completion-at-point predicate))
+         (plist (nthcdr 3 data)))
+    (let ((completion-annotate-function (plist-get plist :annotate-function)))
+      (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data)
+                            (plist-get plist :predicate)))))
+    
+
+(defun lisp-completion-at-point (&optional predicate)
+  ;; FIXME: the `end' could be after point?
   (let* ((end (point))
          (beg (with-syntax-table emacs-lisp-mode-syntax-table
                 (save-excursion
@@ -648,10 +657,11 @@
                       nil
                     ;; Else, we assume that a function name is expected.
                     'fboundp))))))
-    (let ((completion-annotate-function
-           (unless (eq predicate 'fboundp)
-             (lambda (str) (if (fboundp (intern-soft str)) " <f>")))))
-      (completion-in-region beg end obarray predicate))))
+    (list beg end obarray
+          :predicate predicate
+          :annotate-function
+            (unless (eq predicate 'fboundp)
+              (lambda (str) (if (fboundp (intern-soft str)) " <f>"))))))
 
 ;; arch-tag: aa7fa8a4-2e6f-4e9b-9cd9-fef06340e67e
 ;;; lisp.el ends here
--- a/lisp/ielm.el	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/ielm.el	Mon Dec 07 20:06:26 2009 +0000
@@ -172,7 +172,7 @@
     (define-key map "\C-m" 'ielm-return)
     (define-key map "\C-j" 'ielm-send-input)
     (define-key map "\e\C-x" 'eval-defun)         ; for consistency with
-    (define-key map "\e\t" 'lisp-complete-symbol) ; lisp-interaction-mode
+    (define-key map "\e\t" 'completion-at-point)  ; lisp-interaction-mode
     ;; These bindings are from `lisp-mode-shared-map' -- can you inherit
     ;; from more than one keymap??
     (define-key map "\e\C-q" 'indent-sexp)
@@ -493,6 +493,8 @@
   (set (make-local-variable 'indent-line-function) 'ielm-indent-line)
   (set (make-local-variable 'ielm-working-buffer) (current-buffer))
   (set (make-local-variable 'fill-paragraph-function) 'lisp-fill-paragraph)
+  (add-hook 'completion-at-point-functions
+            'lisp-completion-at-point nil 'local)
 
   ;; Value holders
   (set (make-local-variable '*) nil)
--- a/lisp/indent.el	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/indent.el	Mon Dec 07 20:06:26 2009 +0000
@@ -49,6 +49,9 @@
 If t, hitting TAB always just indents the current line.
 If nil, hitting TAB indents the current line if point is at the left margin
 or in the line's indentation, otherwise it inserts a \"real\" TAB character.
+If `complete', TAB first tries to indent the current line, and if the line
+was already indented, then try to complete the thing at point.
+
 Some programming language modes have their own variable to control this,
 e.g., `c-tab-always-indent', and do not respect this variable."
   :group 'indent
@@ -103,26 +106,32 @@
 		 (eq this-command last-command))))
     (insert-tab arg))
    (t
-    (let ((end-marker
-	   (and arg
-		(save-excursion
-		  (forward-line 0) (forward-sexp) (point-marker))))
-	  (old-indent
-	   (current-indentation)))
+    (let ((old-tick (buffer-chars-modified-tick))
+          (old-point (point))
+	  (old-indent (current-indentation)))
 
       ;; Indent the line.
       (funcall indent-line-function)
 
-      ;; If a prefix argument was given, rigidly indent the following
-      ;; sexp to match the change in the current line's indentation.
-      ;;
-      (when arg
-	(let ((indentation-change (- (current-indentation) old-indent)))
-	  (unless (zerop indentation-change)
-	    (save-excursion
-	      (forward-line 1)
-	      (when (< (point) end-marker)
-		(indent-rigidly (point) end-marker indentation-change))))))))))
+      (cond
+       ;; If the text was already indented right, try completion.
+       ((and (eq tab-always-indent 'complete)
+             (eq old-point (point))
+             (eq old-tick (buffer-chars-modified-tick)))
+        (completion-at-point))
+
+       ;; If a prefix argument was given, rigidly indent the following
+       ;; sexp to match the change in the current line's indentation.
+       (arg
+        (let ((end-marker
+               (save-excursion
+                 (forward-line 0) (forward-sexp) (point-marker)))
+              (indentation-change (- (current-indentation) old-indent)))
+          (save-excursion
+            (forward-line 1)
+            (when (and (not (zerop indentation-change))
+                       (< (point) end-marker))
+              (indent-rigidly (point) end-marker indentation-change))))))))))
 
 (defun insert-tab (&optional arg)
   (let ((count (prefix-numeric-value arg)))
--- a/lisp/minibuffer.el	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/minibuffer.el	Mon Dec 07 20:06:26 2009 +0000
@@ -1113,6 +1113,36 @@
           (call-interactively 'minibuffer-complete)
         (delete-overlay ol)))))
 
+(defvar completion-at-point-functions nil
+  "Special hook to find the completion table for the thing at point.
+It is called without any argument and should return either nil,
+or a function of no argument to perform completion (discouraged),
+or a list of the form (START END COLLECTION &rest PROPS) where
+ START and END delimit the entity to complete and should include point,
+ COLLECTION is the completion table to use to complete it, and
+ PROPS is a property list for additional information.
+Currently supported properties are:
+ `:predicate'           a predicate that completion candidates need to satisfy.
+ `:annotation-function' the value to use for `completion-annotate-function'.")
+
+(defun completion-at-point ()
+  "Complete the thing at point according to local mode."
+  (interactive)
+  (let ((res (run-hook-with-args-until-success
+              'completion-at-point-functions)))
+    (cond
+     ((functionp res) (funcall res))
+     (res
+      (let* ((plist (nthcdr 3 res))
+             (start (nth 0 res))
+             (end (nth 1 res))
+             (completion-annotate-function
+              (or (plist-get plist :annotation-function)
+                  completion-annotate-function)))
+        (completion-in-region start end (nth 2 res)
+                              (plist-get plist :predicate)))))))
+
+
 (let ((map minibuffer-local-map))
   (define-key map "\C-g" 'abort-recursive-edit)
   (define-key map "\r" 'exit-minibuffer)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/obsolete/sym-comp.el	Mon Dec 07 20:06:26 2009 +0000
@@ -0,0 +1,231 @@
+;;; sym-comp.el --- mode-dependent symbol completion
+
+;; Copyright (C) 2004, 2008, 2009  Free Software Foundation, Inc.
+
+;; Author: Dave Love <fx@gnu.org>
+;; Keywords: extensions
+;; URL: http://www.loveshack.ukfsn.org/emacs
+;; Obsolete-since: 23.2
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This defines `symbol-complete', which is a generalization of the
+;; old `lisp-complete-symbol'.  It provides the following hooks to
+;; allow major modes to set up completion appropriate for the mode:
+;; `symbol-completion-symbol-function',
+;; `symbol-completion-completions-function',
+;; `symbol-completion-predicate-function',
+;; `symbol-completion-transform-function'.  Typically it is only
+;; necessary for a mode to set
+;; `symbol-completion-completions-function' locally and to bind
+;; `symbol-complete' appropriately.
+
+;; It's unfortunate that there doesn't seem to be a good way of
+;; combining this with `complete-symbol'.
+
+;; There is also `symbol-completion-try-complete', for use with
+;; Hippie-exp.
+
+;;; Code:
+
+;;;; Mode-dependent symbol completion.
+
+(defun symbol-completion-symbol ()
+  "Default `symbol-completion-symbol-function'.
+Uses `current-word' with the buffer narrowed to the part before
+point."
+  (save-restriction
+    ;; Narrow in case point is in the middle of a symbol -- we want
+    ;; just the preceeding part.
+    (narrow-to-region (point-min) (point))
+    (current-word)))
+
+(defvar symbol-completion-symbol-function 'symbol-completion-symbol
+  "Function to return a partial symbol before point for completion.
+The value it returns should be a string (or nil).
+Major modes may set this locally if the default isn't appropriate.
+
+Beware: the length of the string STR returned need to be equal to the length
+of text before point that's subject to completion.  Typically, this amounts
+to saying that STR is equal to
+\(buffer-substring (- (point) (length STR)) (point)).")
+
+(defvar symbol-completion-completions-function nil
+  "Function to return possible symbol completions.
+It takes an argument which is the string to be completed and
+returns a value suitable for the second argument of
+`try-completion'.  This value need not use the argument, i.e. it
+may be all possible completions, such as `obarray' in the case of
+Emacs Lisp.
+
+Major modes may set this locally to allow them to support
+`symbol-complete'.  See also `symbol-completion-symbol-function',
+`symbol-completion-predicate-function' and
+`symbol-completion-transform-function'.")
+
+(defvar symbol-completion-predicate-function nil
+  "If non-nil, function to return a predicate for selecting symbol completions.
+The function gets two args, the positions of the beginning and
+end of the symbol to be completed.
+
+Major modes may set this locally if the default isn't
+appropriate.  This is a function returning a predicate so that
+the predicate can be context-dependent, e.g. to select only
+function names if point is at a function call position.  The
+function's args may be useful for determining the context.")
+
+(defvar symbol-completion-transform-function nil
+  "If non-nil, function to transform symbols in the symbol-completion buffer.
+E.g., for Lisp, it may annotate the symbol as being a function,
+not a variable.
+
+The function takes the symbol name as argument.  If it needs to
+annotate this, it should return a value suitable as an element of
+the list passed to `display-completion-list'.
+
+The predicate being used for selecting completions (from
+`symbol-completion-predicate-function') is available
+dynamically-bound as `symbol-completion-predicate' in case the
+transform needs it.")
+
+(defvar symbol-completion-predicate)
+
+;;;###autoload
+(defun symbol-complete (&optional predicate)
+  "Perform completion of the symbol preceding point.
+This is done in a way appropriate to the current major mode,
+perhaps by interrogating an inferior interpreter.  Compare
+`complete-symbol'.
+If no characters can be completed, display a list of possible completions.
+Repeating the command at that point scrolls the list.
+
+When called from a program, optional arg PREDICATE is a predicate
+determining which symbols are considered.
+
+This function requires `symbol-completion-completions-function'
+to be set buffer-locally.  Variables `symbol-completion-symbol-function',
+`symbol-completion-predicate-function' and
+`symbol-completion-transform-function' are also consulted."
+  (interactive)
+  ;; Fixme: Punt to `complete-symbol' in this case?
+  (unless (functionp symbol-completion-completions-function)
+    (error "symbol-completion-completions-function not defined"))
+  (let* ((pattern (or (funcall symbol-completion-symbol-function)
+                      (error "No preceding symbol to complete")))
+         ;; FIXME: We assume below that `pattern' holds the text just
+         ;; before point.  This is a problem in the way
+         ;; symbol-completion-symbol-function was defined.
+         (predicate (or predicate
+                        (if symbol-completion-predicate-function
+                            (funcall symbol-completion-predicate-function
+                                     (- (point) (length pattern))
+                                     (point)))))
+         (completions (funcall symbol-completion-completions-function
+                               pattern))
+         ;; In case the transform needs to access it.
+         (symbol-completion-predicate predicate)
+         (completion-annotate-function
+          (if (functionp symbol-completion-transform-function)
+              (lambda (str)
+                (car-safe (cdr-safe
+                           (funcall symbol-completion-transform-function
+                                    str)))))))
+    (completion-in-region (- (point) (length pattern)) (point)
+                          completions predicate)))
+
+(eval-when-compile (require 'hippie-exp))
+
+;;;###autoload
+(defun symbol-completion-try-complete (old)
+  "Completion function for use with `hippie-expand'.
+Uses `symbol-completion-symbol-function' and
+`symbol-completion-completions-function'.  It is intended to be
+used something like this in a major mode which provides symbol
+completion:
+
+  (if (featurep 'hippie-exp)
+      (set (make-local-variable 'hippie-expand-try-functions-list)
+	   (cons 'symbol-completion-try-complete
+                 hippie-expand-try-functions-list)))"
+  (when (and symbol-completion-symbol-function
+	     symbol-completion-completions-function)
+    (unless old
+      (let ((symbol (funcall symbol-completion-symbol-function)))
+	(he-init-string (- (point) (length symbol)) (point))
+	(if (not (he-string-member he-search-string he-tried-table))
+	    (push he-search-string he-tried-table))
+	(setq he-expand-list
+	      (and symbol
+		   (funcall symbol-completion-completions-function symbol)))))
+    (while (and he-expand-list
+		(he-string-member (car he-expand-list) he-tried-table))
+      (pop he-expand-list))
+    (if he-expand-list
+	(progn
+	  (he-substitute-string (pop he-expand-list))
+	  t)
+      (if old (he-reset-string))
+      nil)))
+
+;;; Emacs Lisp symbol completion.
+
+(defun lisp-completion-symbol ()
+  "`symbol-completion-symbol-function' for Lisp."
+  (let ((end (point))
+	(beg (with-syntax-table emacs-lisp-mode-syntax-table
+	       (save-excursion
+		 (backward-sexp 1)
+		 (while (= (char-syntax (following-char)) ?\')
+		   (forward-char 1))
+		 (point)))))
+    (buffer-substring-no-properties beg end)))
+
+(defun lisp-completion-predicate (beg end)
+  "`symbol-completion-predicate-function' for Lisp."
+  (save-excursion
+    (goto-char beg)
+    (if (not (eq (char-before) ?\())
+	(lambda (sym)			;why not just nil ?   -sm
+					;To avoid interned symbols with
+					;no slots.  -- fx
+	  (or (boundp sym) (fboundp sym)
+	      (symbol-plist sym)))
+      ;; Looks like a funcall position.  Let's double check.
+      (if (condition-case nil
+	      (progn (up-list -2) (forward-char 1)
+		     (eq (char-after) ?\())
+	    (error nil))
+	  ;; If the first element of the parent list is an open
+	  ;; parenthesis we are probably not in a funcall position.
+	  ;; Maybe a `let' varlist or something.
+	  nil
+	;; Else, we assume that a function name is expected.
+	'fboundp))))
+
+(defun lisp-symbol-completion-transform ()
+  "`symbol-completion-transform-function' for Lisp."
+  (lambda (elt)
+    (if (and (not (eq 'fboundp symbol-completion-predicate))
+	     (fboundp (intern elt)))
+	(list elt " <f>")
+      elt)))
+
+(provide 'sym-comp)
+
+;; arch-tag: 6fcce616-f3c4-4751-94b4-710e83144124
+;;; sym-comp.el ends here
--- a/lisp/progmodes/python.el	Mon Dec 07 19:21:57 2009 +0000
+++ b/lisp/progmodes/python.el	Mon Dec 07 20:06:26 2009 +0000
@@ -268,7 +268,7 @@
     (define-key map "\C-c\C-z" 'python-switch-to-python)
     (define-key map "\C-c\C-m" 'python-load-file)
     (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme
-    (substitute-key-definition 'complete-symbol 'symbol-complete
+    (substitute-key-definition 'complete-symbol 'completion-at-point
 			       map global-map)
     (define-key map "\C-c\C-i" 'python-find-imports)
     (define-key map "\C-c\C-t" 'python-expand-template)
@@ -319,7 +319,7 @@
 	"-"
 	["Help on symbol" python-describe-symbol
 	 :help "Use pydoc on symbol at point"]
-	["Complete symbol" symbol-complete
+	["Complete symbol" completion-at-point
 	 :help "Complete (qualified) symbol before point"]
 	["Find function" python-find-function
 	 :help "Try to find source definition of function at point"]
@@ -2159,8 +2159,7 @@
        (delete-dups completions)
        #'string<))))
 
-(defun python-partial-symbol ()
-  "Return the partial symbol before point (for completion)."
+(defun python-completion-at-point ()
   (let ((end (point))
 	(start (save-excursion
 		 (and (re-search-backward
@@ -2168,7 +2167,9 @@
 			   (group (1+ (regexp "[[:alnum:]._]"))) point)
 		       nil t)
 		      (match-beginning 1)))))
-    (if start (buffer-substring-no-properties start end))))
+    (when start
+      (list start end
+            (completion-table-dynamic 'python-symbol-completions)))))
 
 ;;;; FFAP support
 
@@ -2471,10 +2472,8 @@
   (add-hook 'eldoc-mode-hook
 	    (lambda () (run-python nil t)) ; need it running
 	    nil t)
-  (set (make-local-variable 'symbol-completion-symbol-function)
-       'python-partial-symbol)
-  (set (make-local-variable 'symbol-completion-completions-function)
-       'python-symbol-completions)
+  (add-hook 'completion-at-point-functions
+            'python-completion-at-point nil 'local)
   ;; Fixme: should be in hideshow.  This seems to be of limited use
   ;; since it isn't (can't be) indentation-based.  Also hide-level
   ;; doesn't seem to work properly.
@@ -2488,12 +2487,6 @@
        '((< '(backward-delete-char-untabify (min python-indent
 						 (current-column))))
 	 (^ '(- (1+ (current-indentation))))))
-  ;; Let's not mess with hippie-expand.  Symbol-completion should rather be
-  ;; bound to another key, since it has different performance requirements.
-  ;; (if (featurep 'hippie-exp)
-  ;;     (set (make-local-variable 'hippie-expand-try-functions-list)
-  ;;          (cons 'symbol-completion-try-complete
-  ;;       	 hippie-expand-try-functions-list)))
   ;; Python defines TABs as being 8-char wide.
   (set (make-local-variable 'tab-width) 8)
   (unless font-lock-mode (font-lock-mode 1))
--- a/lisp/progmodes/sym-comp.el	Mon Dec 07 19:21:57 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-;;; sym-comp.el --- mode-dependent symbol completion
-
-;; Copyright (C) 2004, 2008, 2009  Free Software Foundation, Inc.
-
-;; Author: Dave Love <fx@gnu.org>
-;; Keywords: extensions
-;; URL: http://www.loveshack.ukfsn.org/emacs
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This defines `symbol-complete', which is a generalization of the
-;; old `lisp-complete-symbol'.  It provides the following hooks to
-;; allow major modes to set up completion appropriate for the mode:
-;; `symbol-completion-symbol-function',
-;; `symbol-completion-completions-function',
-;; `symbol-completion-predicate-function',
-;; `symbol-completion-transform-function'.  Typically it is only
-;; necessary for a mode to set
-;; `symbol-completion-completions-function' locally and to bind
-;; `symbol-complete' appropriately.
-
-;; It's unfortunate that there doesn't seem to be a good way of
-;; combining this with `complete-symbol'.
-
-;; There is also `symbol-completion-try-complete', for use with
-;; Hippie-exp.
-
-;;; Code:
-
-;;;; Mode-dependent symbol completion.
-
-(defun symbol-completion-symbol ()
-  "Default `symbol-completion-symbol-function'.
-Uses `current-word' with the buffer narrowed to the part before
-point."
-  (save-restriction
-    ;; Narrow in case point is in the middle of a symbol -- we want
-    ;; just the preceeding part.
-    (narrow-to-region (point-min) (point))
-    (current-word)))
-
-(defvar symbol-completion-symbol-function 'symbol-completion-symbol
-  "Function to return a partial symbol before point for completion.
-The value it returns should be a string (or nil).
-Major modes may set this locally if the default isn't appropriate.
-
-Beware: the length of the string STR returned need to be equal to the length
-of text before point that's subject to completion.  Typically, this amounts
-to saying that STR is equal to
-\(buffer-substring (- (point) (length STR)) (point)).")
-
-(defvar symbol-completion-completions-function nil
-  "Function to return possible symbol completions.
-It takes an argument which is the string to be completed and
-returns a value suitable for the second argument of
-`try-completion'.  This value need not use the argument, i.e. it
-may be all possible completions, such as `obarray' in the case of
-Emacs Lisp.
-
-Major modes may set this locally to allow them to support
-`symbol-complete'.  See also `symbol-completion-symbol-function',
-`symbol-completion-predicate-function' and
-`symbol-completion-transform-function'.")
-
-(defvar symbol-completion-predicate-function nil
-  "If non-nil, function to return a predicate for selecting symbol completions.
-The function gets two args, the positions of the beginning and
-end of the symbol to be completed.
-
-Major modes may set this locally if the default isn't
-appropriate.  This is a function returning a predicate so that
-the predicate can be context-dependent, e.g. to select only
-function names if point is at a function call position.  The
-function's args may be useful for determining the context.")
-
-(defvar symbol-completion-transform-function nil
-  "If non-nil, function to transform symbols in the symbol-completion buffer.
-E.g., for Lisp, it may annotate the symbol as being a function,
-not a variable.
-
-The function takes the symbol name as argument.  If it needs to
-annotate this, it should return a value suitable as an element of
-the list passed to `display-completion-list'.
-
-The predicate being used for selecting completions (from
-`symbol-completion-predicate-function') is available
-dynamically-bound as `symbol-completion-predicate' in case the
-transform needs it.")
-
-(defvar symbol-completion-predicate)
-
-;;;###autoload
-(defun symbol-complete (&optional predicate)
-  "Perform completion of the symbol preceding point.
-This is done in a way appropriate to the current major mode,
-perhaps by interrogating an inferior interpreter.  Compare
-`complete-symbol'.
-If no characters can be completed, display a list of possible completions.
-Repeating the command at that point scrolls the list.
-
-When called from a program, optional arg PREDICATE is a predicate
-determining which symbols are considered.
-
-This function requires `symbol-completion-completions-function'
-to be set buffer-locally.  Variables `symbol-completion-symbol-function',
-`symbol-completion-predicate-function' and
-`symbol-completion-transform-function' are also consulted."
-  (interactive)
-  ;; Fixme: Punt to `complete-symbol' in this case?
-  (unless (functionp symbol-completion-completions-function)
-    (error "symbol-completion-completions-function not defined"))
-  (let* ((pattern (or (funcall symbol-completion-symbol-function)
-                      (error "No preceding symbol to complete")))
-         ;; FIXME: We assume below that `pattern' holds the text just
-         ;; before point.  This is a problem in the way
-         ;; symbol-completion-symbol-function was defined.
-         (predicate (or predicate
-                        (if symbol-completion-predicate-function
-                            (funcall symbol-completion-predicate-function
-                                     (- (point) (length pattern))
-                                     (point)))))
-         (completions (funcall symbol-completion-completions-function
-                               pattern))
-         ;; In case the transform needs to access it.
-         (symbol-completion-predicate predicate)
-         (completion-annotate-function
-          (if (functionp symbol-completion-transform-function)
-              (lambda (str)
-                (car-safe (cdr-safe
-                           (funcall symbol-completion-transform-function
-                                    str)))))))
-    (completion-in-region (- (point) (length pattern)) (point)
-                          completions predicate)))
-
-(eval-when-compile (require 'hippie-exp))
-
-;;;###autoload
-(defun symbol-completion-try-complete (old)
-  "Completion function for use with `hippie-expand'.
-Uses `symbol-completion-symbol-function' and
-`symbol-completion-completions-function'.  It is intended to be
-used something like this in a major mode which provides symbol
-completion:
-
-  (if (featurep 'hippie-exp)
-      (set (make-local-variable 'hippie-expand-try-functions-list)
-	   (cons 'symbol-completion-try-complete
-                 hippie-expand-try-functions-list)))"
-  (when (and symbol-completion-symbol-function
-	     symbol-completion-completions-function)
-    (unless old
-      (let ((symbol (funcall symbol-completion-symbol-function)))
-	(he-init-string (- (point) (length symbol)) (point))
-	(if (not (he-string-member he-search-string he-tried-table))
-	    (push he-search-string he-tried-table))
-	(setq he-expand-list
-	      (and symbol
-		   (funcall symbol-completion-completions-function symbol)))))
-    (while (and he-expand-list
-		(he-string-member (car he-expand-list) he-tried-table))
-      (pop he-expand-list))
-    (if he-expand-list
-	(progn
-	  (he-substitute-string (pop he-expand-list))
-	  t)
-      (if old (he-reset-string))
-      nil)))
-
-;;; Emacs Lisp symbol completion.
-
-(defun lisp-completion-symbol ()
-  "`symbol-completion-symbol-function' for Lisp."
-  (let ((end (point))
-	(beg (with-syntax-table emacs-lisp-mode-syntax-table
-	       (save-excursion
-		 (backward-sexp 1)
-		 (while (= (char-syntax (following-char)) ?\')
-		   (forward-char 1))
-		 (point)))))
-    (buffer-substring-no-properties beg end)))
-
-(defun lisp-completion-predicate (beg end)
-  "`symbol-completion-predicate-function' for Lisp."
-  (save-excursion
-    (goto-char beg)
-    (if (not (eq (char-before) ?\())
-	(lambda (sym)			;why not just nil ?   -sm
-					;To avoid interned symbols with
-					;no slots.  -- fx
-	  (or (boundp sym) (fboundp sym)
-	      (symbol-plist sym)))
-      ;; Looks like a funcall position.  Let's double check.
-      (if (condition-case nil
-	      (progn (up-list -2) (forward-char 1)
-		     (eq (char-after) ?\())
-	    (error nil))
-	  ;; If the first element of the parent list is an open
-	  ;; parenthesis we are probably not in a funcall position.
-	  ;; Maybe a `let' varlist or something.
-	  nil
-	;; Else, we assume that a function name is expected.
-	'fboundp))))
-
-(defun lisp-symbol-completion-transform ()
-  "`symbol-completion-transform-function' for Lisp."
-  (lambda (elt)
-    (if (and (not (eq 'fboundp symbol-completion-predicate))
-	     (fboundp (intern elt)))
-	(list elt " <f>")
-      elt)))
-
-(provide 'sym-comp)
-
-;; arch-tag: 6fcce616-f3c4-4751-94b4-710e83144124
-;;; sym-comp.el ends here