Commit 51ef56c4 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

* 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.
parent 5e7a9022
...@@ -137,6 +137,10 @@ subsequent kills are not duplicated in the `kill-ring'. ...@@ -137,6 +137,10 @@ subsequent kills are not duplicated in the `kill-ring'.
** Completion changes ** 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. *** The new completion-style `initials' is available.
For instance, this can complete M-x lch to list-command-history. For instance, this can complete M-x lch to list-command-history.
...@@ -170,6 +174,8 @@ cycling order of C-l (`recenter-top-bottom'). ...@@ -170,6 +174,8 @@ cycling order of C-l (`recenter-top-bottom').
** LaTeX mode now provides completion via latex-complete and ** LaTeX mode now provides completion via latex-complete and
latex-indent-or-complete. 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. ** lucid.el and levents.el are now declared obsolete.
** pcomplete provides a new command `pcomplete-std-completion' which ** pcomplete provides a new command `pcomplete-std-completion' which
......
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> 2009-12-07 Eli Zaretskii <eliz@gnu.org>
Prevent save-buffer in Rmail buffers from using the coding-system Prevent save-buffer in Rmail buffers from using the coding-system
......
...@@ -280,7 +280,7 @@ font-lock keywords will not be case sensitive." ...@@ -280,7 +280,7 @@ font-lock keywords will not be case sensitive."
(prof-map (make-sparse-keymap)) (prof-map (make-sparse-keymap))
(tracing-map (make-sparse-keymap))) (tracing-map (make-sparse-keymap)))
(set-keymap-parent map lisp-mode-shared-map) (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-x" 'eval-defun)
(define-key map "\e\C-q" 'indent-pp-sexp) (define-key map "\e\C-q" 'indent-pp-sexp)
(define-key map [menu-bar emacs-lisp] (cons (purecopy "Emacs-Lisp") menu-map)) (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.") ...@@ -431,7 +431,7 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
:type 'hook :type 'hook
:group 'lisp) :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. "Major mode for editing Lisp code to run in Emacs.
Commands: Commands:
Delete converts tabs to spaces as it moves back. Delete converts tabs to spaces as it moves back.
...@@ -440,16 +440,11 @@ Blank lines separate paragraphs. Semicolons start comments. ...@@ -440,16 +440,11 @@ Blank lines separate paragraphs. Semicolons start comments.
\\{emacs-lisp-mode-map} \\{emacs-lisp-mode-map}
Entry to this mode calls the value of `emacs-lisp-mode-hook' Entry to this mode calls the value of `emacs-lisp-mode-hook'
if that value is non-nil." if that value is non-nil."
(interactive) :group 'lisp
(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")
(lisp-mode-variables) (lisp-mode-variables)
(setq imenu-case-fold-search nil) (setq imenu-case-fold-search nil)
(run-mode-hooks 'emacs-lisp-mode-hook)) (add-hook 'completion-at-point-functions
(put 'emacs-lisp-mode 'custom-mode-group 'lisp) 'lisp-completion-at-point nil 'local))
(defvar lisp-mode-map (defvar lisp-mode-map
(let ((map (make-sparse-keymap)) (let ((map (make-sparse-keymap))
...@@ -519,7 +514,7 @@ if that value is non-nil." ...@@ -519,7 +514,7 @@ if that value is non-nil."
(set-keymap-parent map lisp-mode-shared-map) (set-keymap-parent map lisp-mode-shared-map)
(define-key map "\e\C-x" 'eval-defun) (define-key map "\e\C-x" 'eval-defun)
(define-key map "\e\C-q" 'indent-pp-sexp) (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 "\n" 'eval-print-last-sexp)
(define-key map [menu-bar lisp-interaction] (cons (purecopy "Lisp-Interaction") menu-map)) (define-key map [menu-bar lisp-interaction] (cons (purecopy "Lisp-Interaction") menu-map))
(define-key menu-map [eval-defun] (define-key menu-map [eval-defun]
...@@ -535,8 +530,8 @@ if that value is non-nil." ...@@ -535,8 +530,8 @@ if that value is non-nil."
(define-key menu-map [indent-pp-sexp] (define-key menu-map [indent-pp-sexp]
`(menu-item ,(purecopy "Indent or Pretty-Print") 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"))) :help ,(purecopy "Indent each line of the list starting just after point, or prettyprint it")))
(define-key menu-map [lisp-complete-symbol] (define-key menu-map [complete-symbol]
`(menu-item ,(purecopy "Complete Lisp Symbol") lisp-complete-symbol `(menu-item ,(purecopy "Complete Lisp Symbol") completion-at-point
:help ,(purecopy "Perform completion on Lisp symbol preceding point"))) :help ,(purecopy "Perform completion on Lisp symbol preceding point")))
map) map)
"Keymap for Lisp Interaction mode. "Keymap for Lisp Interaction mode.
......
...@@ -622,6 +622,15 @@ symbols with function definitions are considered. Otherwise, all ...@@ -622,6 +622,15 @@ symbols with function definitions are considered. Otherwise, all
symbols with function definitions, values or properties are symbols with function definitions, values or properties are
considered." considered."
(interactive) (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)) (let* ((end (point))
(beg (with-syntax-table emacs-lisp-mode-syntax-table (beg (with-syntax-table emacs-lisp-mode-syntax-table
(save-excursion (save-excursion
...@@ -648,10 +657,11 @@ considered." ...@@ -648,10 +657,11 @@ considered."
nil nil
;; Else, we assume that a function name is expected. ;; Else, we assume that a function name is expected.
'fboundp)))))) 'fboundp))))))
(let ((completion-annotate-function (list beg end obarray
(unless (eq predicate 'fboundp) :predicate predicate
(lambda (str) (if (fboundp (intern-soft str)) " <f>"))))) :annotate-function
(completion-in-region beg end obarray predicate)))) (unless (eq predicate 'fboundp)
(lambda (str) (if (fboundp (intern-soft str)) " <f>"))))))
;; arch-tag: aa7fa8a4-2e6f-4e9b-9cd9-fef06340e67e ;; arch-tag: aa7fa8a4-2e6f-4e9b-9cd9-fef06340e67e
;;; lisp.el ends here ;;; lisp.el ends here
...@@ -172,7 +172,7 @@ This variable is buffer-local.") ...@@ -172,7 +172,7 @@ This variable is buffer-local.")
(define-key map "\C-m" 'ielm-return) (define-key map "\C-m" 'ielm-return)
(define-key map "\C-j" 'ielm-send-input) (define-key map "\C-j" 'ielm-send-input)
(define-key map "\e\C-x" 'eval-defun) ; for consistency with (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 ;; These bindings are from `lisp-mode-shared-map' -- can you inherit
;; from more than one keymap?? ;; from more than one keymap??
(define-key map "\e\C-q" 'indent-sexp) (define-key map "\e\C-q" 'indent-sexp)
...@@ -493,6 +493,8 @@ Customized bindings may be defined in `ielm-map', which currently contains: ...@@ -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 'indent-line-function) 'ielm-indent-line)
(set (make-local-variable 'ielm-working-buffer) (current-buffer)) (set (make-local-variable 'ielm-working-buffer) (current-buffer))
(set (make-local-variable 'fill-paragraph-function) 'lisp-fill-paragraph) (set (make-local-variable 'fill-paragraph-function) 'lisp-fill-paragraph)
(add-hook 'completion-at-point-functions
'lisp-completion-at-point nil 'local)
;; Value holders ;; Value holders
(set (make-local-variable '*) nil) (set (make-local-variable '*) nil)
......
...@@ -49,6 +49,9 @@ Don't rebind TAB unless you really need to.") ...@@ -49,6 +49,9 @@ Don't rebind TAB unless you really need to.")
If t, hitting TAB always just indents the current line. 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 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. 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, Some programming language modes have their own variable to control this,
e.g., `c-tab-always-indent', and do not respect this variable." e.g., `c-tab-always-indent', and do not respect this variable."
:group 'indent :group 'indent
...@@ -103,26 +106,32 @@ The function actually called to indent the line is determined by the value of ...@@ -103,26 +106,32 @@ The function actually called to indent the line is determined by the value of
(eq this-command last-command)))) (eq this-command last-command))))
(insert-tab arg)) (insert-tab arg))
(t (t
(let ((end-marker (let ((old-tick (buffer-chars-modified-tick))
(and arg (old-point (point))
(save-excursion (old-indent (current-indentation)))
(forward-line 0) (forward-sexp) (point-marker))))
(old-indent
(current-indentation)))
;; Indent the line. ;; Indent the line.
(funcall indent-line-function) (funcall indent-line-function)
;; If a prefix argument was given, rigidly indent the following (cond
;; sexp to match the change in the current line's indentation. ;; If the text was already indented right, try completion.
;; ((and (eq tab-always-indent 'complete)
(when arg (eq old-point (point))
(let ((indentation-change (- (current-indentation) old-indent))) (eq old-tick (buffer-chars-modified-tick)))
(unless (zerop indentation-change) (completion-at-point))
(save-excursion
(forward-line 1) ;; If a prefix argument was given, rigidly indent the following
(when (< (point) end-marker) ;; sexp to match the change in the current line's indentation.
(indent-rigidly (point) end-marker indentation-change)))))))))) (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) (defun insert-tab (&optional arg)
(let ((count (prefix-numeric-value arg))) (let ((count (prefix-numeric-value arg)))
......
...@@ -1113,6 +1113,36 @@ Point needs to be somewhere between START and END." ...@@ -1113,6 +1113,36 @@ Point needs to be somewhere between START and END."
(call-interactively 'minibuffer-complete) (call-interactively 'minibuffer-complete)
(delete-overlay ol))))) (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)) (let ((map minibuffer-local-map))
(define-key map "\C-g" 'abort-recursive-edit) (define-key map "\C-g" 'abort-recursive-edit)
(define-key map "\r" 'exit-minibuffer) (define-key map "\r" 'exit-minibuffer)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
;; Author: Dave Love <fx@gnu.org> ;; Author: Dave Love <fx@gnu.org>
;; Keywords: extensions ;; Keywords: extensions
;; URL: http://www.loveshack.ukfsn.org/emacs ;; URL: http://www.loveshack.ukfsn.org/emacs
;; Obsolete-since: 23.2
;; This file is part of GNU Emacs. ;; This file is part of GNU Emacs.
......
...@@ -268,7 +268,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." ...@@ -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-z" 'python-switch-to-python)
(define-key map "\C-c\C-m" 'python-load-file) (define-key map "\C-c\C-m" 'python-load-file)
(define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme (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) map global-map)
(define-key map "\C-c\C-i" 'python-find-imports) (define-key map "\C-c\C-i" 'python-find-imports)
(define-key map "\C-c\C-t" 'python-expand-template) (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)." ...@@ -319,7 +319,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)."
"-" "-"
["Help on symbol" python-describe-symbol ["Help on symbol" python-describe-symbol
:help "Use pydoc on symbol at point"] :help "Use pydoc on symbol at point"]
["Complete symbol" symbol-complete ["Complete symbol" completion-at-point
:help "Complete (qualified) symbol before point"] :help "Complete (qualified) symbol before point"]
["Find function" python-find-function ["Find function" python-find-function
:help "Try to find source definition of function at point"] :help "Try to find source definition of function at point"]
...@@ -2159,8 +2159,7 @@ Uses `python-imports' to load modules against which to complete." ...@@ -2159,8 +2159,7 @@ Uses `python-imports' to load modules against which to complete."
(delete-dups completions) (delete-dups completions)
#'string<)))) #'string<))))
(defun python-partial-symbol () (defun python-completion-at-point ()
"Return the partial symbol before point (for completion)."
(let ((end (point)) (let ((end (point))
(start (save-excursion (start (save-excursion
(and (re-search-backward (and (re-search-backward
...@@ -2168,7 +2167,9 @@ Uses `python-imports' to load modules against which to complete." ...@@ -2168,7 +2167,9 @@ Uses `python-imports' to load modules against which to complete."
(group (1+ (regexp "[[:alnum:]._]"))) point) (group (1+ (regexp "[[:alnum:]._]"))) point)
nil t) nil t)
(match-beginning 1))))) (match-beginning 1)))))
(if start (buffer-substring-no-properties start end)))) (when start
(list start end
(completion-table-dynamic 'python-symbol-completions)))))
;;;; FFAP support ;;;; FFAP support
...@@ -2471,10 +2472,8 @@ with skeleton expansions for compound statement templates. ...@@ -2471,10 +2472,8 @@ with skeleton expansions for compound statement templates.
(add-hook 'eldoc-mode-hook (add-hook 'eldoc-mode-hook
(lambda () (run-python nil t)) ; need it running (lambda () (run-python nil t)) ; need it running
nil t) nil t)
(set (make-local-variable 'symbol-completion-symbol-function) (add-hook 'completion-at-point-functions
'python-partial-symbol) 'python-completion-at-point nil 'local)
(set (make-local-variable 'symbol-completion-completions-function)
'python-symbol-completions)
;; Fixme: should be in hideshow. This seems to be of limited use ;; Fixme: should be in hideshow. This seems to be of limited use
;; since it isn't (can't be) indentation-based. Also hide-level ;; since it isn't (can't be) indentation-based. Also hide-level
;; doesn't seem to work properly. ;; doesn't seem to work properly.
...@@ -2488,12 +2487,6 @@ with skeleton expansions for compound statement templates. ...@@ -2488,12 +2487,6 @@ with skeleton expansions for compound statement templates.
'((< '(backward-delete-char-untabify (min python-indent '((< '(backward-delete-char-untabify (min python-indent
(current-column)))) (current-column))))
(^ '(- (1+ (current-indentation)))))) (^ '(- (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. ;; Python defines TABs as being 8-char wide.
(set (make-local-variable 'tab-width) 8) (set (make-local-variable 'tab-width) 8)
(unless font-lock-mode (font-lock-mode 1)) (unless font-lock-mode (font-lock-mode 1))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment