summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2009-12-07 20:06:26 +0000
committerStefan Monnier <monnier@iro.umontreal.ca>2009-12-07 20:06:26 +0000
commit51ef56c47fc0b02b20f44b673f8b60350c03b4e1 (patch)
treef3c898b5885cfc9cdca8681966bd223d3ee19ff7
parent5e7a90229a1c32ded160a6d27f4ad9f3c66f60c3 (diff)
downloademacs-51ef56c47fc0b02b20f44b673f8b60350c03b4e1.tar.gz
* 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.
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/ChangeLog20
-rw-r--r--lisp/emacs-lisp/lisp-mode.el21
-rw-r--r--lisp/emacs-lisp/lisp.el18
-rw-r--r--lisp/ielm.el4
-rw-r--r--lisp/indent.el41
-rw-r--r--lisp/minibuffer.el30
-rw-r--r--lisp/obsolete/sym-comp.el (renamed from lisp/progmodes/sym-comp.el)1
-rw-r--r--lisp/progmodes/python.el23
9 files changed, 115 insertions, 49 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 8181fbf21ae..d3fdf359c4f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -137,6 +137,10 @@ subsequent kills are not duplicated in the `kill-ring'.
** 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 @@ cycling order of C-l (`recenter-top-bottom').
** 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
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9a13c3d51d8..1eec4f80e5f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -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
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index a42ef5da930..7e5d89c66dc 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -280,7 +280,7 @@ font-lock keywords will not be case sensitive."
(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 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
: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 @@ Blank lines separate paragraphs. Semicolons start comments.
\\{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 @@ if that value is non-nil."
(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 @@ if that value is non-nil."
(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.
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index 0edd6556dbf..d364f2cb602 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -622,6 +622,15 @@ symbols with function definitions are considered. Otherwise, all
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 @@ considered."
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
diff --git a/lisp/ielm.el b/lisp/ielm.el
index 10451877e8a..dc845376ae2 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -172,7 +172,7 @@ This variable is buffer-local.")
(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 @@ Customized bindings may be defined in `ielm-map', which currently contains:
(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)
diff --git a/lisp/indent.el b/lisp/indent.el
index e91fe0b1a29..265b4ba4d30 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -49,6 +49,9 @@ Don't rebind TAB unless you really need to.")
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 @@ The function actually called to indent the line is determined by the value of
(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)))
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 62a0157c352..40c3f4193c0 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -1113,6 +1113,36 @@ Point needs to be somewhere between START and END."
(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)
diff --git a/lisp/progmodes/sym-comp.el b/lisp/obsolete/sym-comp.el
index a0f572266bd..722807b6273 100644
--- a/lisp/progmodes/sym-comp.el
+++ b/lisp/obsolete/sym-comp.el
@@ -5,6 +5,7 @@
;; 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.
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index eff599c77a5..c401cdfbf54 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -268,7 +268,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
(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 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
"-"
["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 @@ Uses `python-imports' to load modules against which to complete."
(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 @@ Uses `python-imports' to load modules against which to complete."
(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 @@ with skeleton expansions for compound statement templates.
(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 @@ with skeleton expansions for compound statement templates.
'((< '(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))