diff options
author | Eli Zaretskii <eliz@gnu.org> | 2013-04-19 11:39:24 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2013-04-19 11:39:24 +0300 |
commit | 4cf86a2fa737296d26e8a02338e2bf6f26e1133a (patch) | |
tree | 094502cb2926db798570e62d32c680b2ce72b6c2 /lisp | |
parent | f60f289656d815827a492150f2e564dd081967f8 (diff) | |
parent | 7d6883367a54b4eee342aa861ef73e4191151ef0 (diff) | |
download | emacs-4cf86a2fa737296d26e8a02338e2bf6f26e1133a.tar.gz emacs-4cf86a2fa737296d26e8a02338e2bf6f26e1133a.tar.bz2 emacs-4cf86a2fa737296d26e8a02338e2bf6f26e1133a.zip |
Merge from trunk.
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/ChangeLog | 27 | ||||
-rw-r--r-- | lisp/bookmark.el | 27 | ||||
-rw-r--r-- | lisp/progmodes/python.el | 234 | ||||
-rw-r--r-- | lisp/vc/vc-dispatcher.el | 4 |
4 files changed, 254 insertions, 38 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 98ba110ab33..a09d37352f7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,30 @@ +2013-04-19 Thierry Volpiatto <thierry.volpiatto@gmail.com> + + * bookmark.el (bookmark-completing-read): Improve handling of empty + string (bug#14176). + +2013-04-19 Stefan Monnier <monnier@iro.umontreal.ca> + + * vc/vc-dispatcher.el (vc-do-command): Get rid of default sentinel msg. + +2013-04-19 Fabián Ezequiel Gallina <fgallina@gnu.org> + + New faster Imenu implementation (bug#14058). + * progmodes/python.el: + (python-imenu-prev-index-position): + (python-imenu-format-item-label-function) + (python-imenu-format-parent-item-label-function) + (python-imenu-format-parent-item-jump-label-function): + New vars. + (python-imenu-format-item-label) + (python-imenu-format-parent-item-label) + (python-imenu-format-parent-item-jump-label) + (python-imenu--put-parent, python-imenu--build-tree) + (python-imenu-create-index, python-imenu-create-flat-index) + (python-util-popn): New functions. + (python-mode): Set imenu-create-index-function to + python-imenu-create-index. + 2013-04-18 Stefan Monnier <monnier@iro.umontreal.ca> * winner.el (winner-active-region): Use region-active-p, activate-mark diff --git a/lisp/bookmark.el b/lisp/bookmark.el index c1d8a4a0a5e..482cdf92752 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -427,8 +427,8 @@ just return it." "Prompting with PROMPT, read a bookmark name in completion. PROMPT will get a \": \" stuck on the end no matter what, so you probably don't want to include one yourself. -Optional second arg DEFAULT is a string to return if the user enters -the empty string." +Optional arg DEFAULT is a string to return if the user input is empty. +If DEFAULT is nil then return empty string for empty input." (bookmark-maybe-load-default-file) ; paranoia (if (listp last-nonmenu-event) (bookmark-menu-popup-paned-menu t prompt @@ -437,22 +437,17 @@ the empty string." 'string-lessp) (bookmark-all-names))) (let* ((completion-ignore-case bookmark-completion-ignore-case) - (default default) + (default (unless (equal "" default) default)) (prompt (concat prompt (if default (format " (%s): " default) - ": "))) - (str - (completing-read prompt - (lambda (string pred action) - (if (eq action 'metadata) - '(metadata (category . bookmark)) - (complete-with-action - action bookmark-alist string pred))) - nil - 0 - nil - 'bookmark-history))) - (if (string-equal "" str) default str)))) + ": ")))) + (completing-read prompt + (lambda (string pred action) + (if (eq action 'metadata) + '(metadata (category . bookmark)) + (complete-with-action + action bookmark-alist string pred))) + nil 0 nil 'bookmark-history default)))) (defmacro bookmark-maybe-historicize-string (string) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 53aff94ae0e..06d07d6ee3c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -177,12 +177,14 @@ ;; might guessed you should run `python-shell-send-buffer' from time ;; to time to get better results too. -;; Imenu: This mode supports Imenu in its most basic form, letting it -;; build the necessary alist via `imenu-default-create-index-function' -;; by having set `imenu-extract-index-name-function' to -;; `python-info-current-defun' and -;; `imenu-prev-index-position-function' to -;; `python-imenu-prev-index-position'. +;; Imenu: There are two index building functions to be used as +;; `imenu-create-index-function': `python-imenu-create-index' (the +;; default one, builds the alist in form of a tree) and +;; `python-imenu-create-flat-index'. See also +;; `python-imenu-format-item-label-function', +;; `python-imenu-format-parent-item-label-function', +;; `python-imenu-format-parent-item-jump-label-function' variables for +;; changing the way labels are formatted in the tree version. ;; If you used python-mode.el you probably will miss auto-indentation ;; when inserting newlines. To achieve the same behavior you have @@ -1194,7 +1196,7 @@ Returns nil if point is not in a def or class." (defun python-nav--syntactically (fn poscompfn &optional contextfn) "Move point using FN avoiding places with specific context. -FN must take no arguments. POSCOMPFN is a two arguments function +FN must take no arguments. POSCOMPFN is a two arguments function used to compare current and previous point after it is moved using FN, this is normally a less-than or greater-than comparison. Optional argument CONTEXTFN defaults to @@ -3008,15 +3010,192 @@ Interactively, prompt for symbol." ;;; Imenu -(defun python-imenu-prev-index-position () - "Python mode's `imenu-prev-index-position-function'." - (let ((found)) - (while (and (setq found - (re-search-backward python-nav-beginning-of-defun-regexp nil t)) - (not (python-info-looking-at-beginning-of-defun)))) - (and found - (python-info-looking-at-beginning-of-defun) - (python-info-current-defun)))) +(defvar python-imenu-format-item-label-function + 'python-imenu-format-item-label + "Imenu function used to format an item label. +It must be a function with two arguments: TYPE and NAME.") + +(defvar python-imenu-format-parent-item-label-function + 'python-imenu-format-parent-item-label + "Imenu function used to format a parent item label. +It must be a function with two arguments: TYPE and NAME.") + +(defvar python-imenu-format-parent-item-jump-label-function + 'python-imenu-format-parent-item-jump-label + "Imenu function used to format a parent jump item label. +It must be a function with two arguments: TYPE and NAME.") + +(defun python-imenu-format-item-label (type name) + "Return imenu label for single node using TYPE and NAME." + (format "%s (%s)" name type)) + +(defun python-imenu-format-parent-item-label (type name) + "Return imenu label for parent node using TYPE and NAME." + (format "%s..." (python-imenu-format-item-label type name))) + +(defun python-imenu-format-parent-item-jump-label (type name) + "Return imenu label for parent node jump using TYPE and NAME." + (if (string= type "class") + "*class definition*" + "*function definition*")) + +(defun python-imenu--put-parent (type name pos num-children tree &optional root) + "Add the parent with TYPE, NAME, POS and NUM-CHILDREN to TREE. +Optional Argument ROOT must be non-nil when the node being +processed is the root of the TREE." + (let ((label + (funcall python-imenu-format-item-label-function type name)) + (jump-label + (funcall python-imenu-format-parent-item-jump-label-function type name))) + (if root + ;; This is the root, everything is a children. + (cons label (cons (cons jump-label pos) tree)) + ;; This is node a which may contain some children. + (cons + (cons label (cons (cons jump-label pos) + ;; Append all the children + (python-util-popn tree num-children))) + ;; All previous non-children nodes. + (nthcdr num-children tree))))) + +(defun python-imenu--build-tree (&optional min-indent prev-indent num-children tree) + "Recursively build the tree of nested definitions of a node. +Arguments MIN-INDENT PREV-INDENT NUM-CHILDREN and TREE are +internal and should not be passed explicitly unless you know what +you are doing." + (setq num-children (or num-children 0) + min-indent (or min-indent 0)) + (let* ((pos (python-nav-backward-defun)) + (type) + (name (when (and pos (looking-at python-nav-beginning-of-defun-regexp)) + (let ((split (split-string (match-string-no-properties 0)))) + (setq type (car split)) + (cadr split)))) + (label (when name + (funcall python-imenu-format-item-label-function type name))) + (indent (current-indentation))) + (cond ((not pos) + ;; No defun found, nothing to add. + tree) + ((equal indent 0) + (if (> num-children 0) + ;; Append it as the parent of everything collected to + ;; this point. + (python-imenu--put-parent type name pos num-children tree t) + ;; There are no children, this is a lonely defun. + (cons label pos))) + ((equal min-indent indent) + ;; Stop collecting nodes after moving to a position with + ;; indentation equaling min-indent. This is specially + ;; useful for navigating nested definitions recursively. + tree) + (t + (python-imenu--build-tree + min-indent + indent + ;; Add another children, either when this is the + ;; first call or when indentation is + ;; less-or-equal than previous. And do not + ;; discard the number of children, because the + ;; way code is scanned, all children are + ;; collected until a root node yet to be found + ;; appears. + (if (or (not prev-indent) + (and + (> indent min-indent) + (<= indent prev-indent))) + (1+ num-children) + num-children) + (cond ((not prev-indent) + ;; First call to the function: append this + ;; defun to the index. + (list (cons label pos))) + ((= indent prev-indent) + ;; Add another defun with the same depth + ;; as the previous. + (cons (cons label pos) tree)) + ((and (< indent prev-indent) + (< 0 num-children)) + ;; There are children to be appended and + ;; the previous defun had more + ;; indentation, the current one must be a + ;; parent. + (python-imenu--put-parent type name pos num-children tree)) + ((> indent prev-indent) + ;; There are children defuns deeper than + ;; current depth. Fear not, we already + ;; know how to treat them. + (cons + (prog1 + (python-imenu--build-tree + prev-indent indent 1 (list (cons label pos))) + ;; Adjustment: after scanning backwards + ;; for all deeper children, we need to + ;; continue our scan for a parent from + ;; the current defun we are looking at. + (python-nav-forward-defun)) + tree)))))))) + +(defun python-imenu-create-index () + "Return tree Imenu alist for the current python buffer. +Change `python-imenu-format-item-label-function', +`python-imenu-format-parent-item-label-function', +`python-imenu-format-parent-item-jump-label-function' to +customize how labels are formatted." + (goto-char (point-max)) + (let ((index) + (tree)) + (while (setq tree (python-imenu--build-tree)) + (setq index (cons tree index))) + index)) + +(defun python-imenu-create-flat-index (&optional alist prefix) + "Return flat outline of the current python buffer for Imenu. +Optional Argument ALIST is the tree to be flattened, when nil +`python-imenu-build-index' is used with +`python-imenu-format-parent-item-jump-label-function' +`python-imenu-format-parent-item-label-function' +`python-imenu-format-item-label-function' set to (lambda (type +name) name). Optional Argument PREFIX is used in recursive calls +and should not be passed explicitly. + +Converts this: + + \((\"Foo\" . 103) + (\"Bar\" . 138) + (\"decorator\" + (\"decorator\" . 173) + (\"wrap\" + (\"wrap\" . 353) + (\"wrapped_f\" . 393)))) + +To this: + + \((\"Foo\" . 103) + (\"Bar\" . 138) + (\"decorator\" . 173) + (\"decorator.wrap\" . 353) + (\"decorator.wrapped_f\" . 393))" + (apply + 'nconc + (mapcar + (lambda (item) + (let ((name (if prefix + (concat prefix "." (car item)) + (car item))) + (pos (cdr item))) + (cond ((or (numberp pos) (markerp pos)) + (list (cons name pos))) + ((listp pos) + (message "%S" item) + (cons + (cons name (cdar pos)) + (python-imenu-create-flat-index (cddr item) name)))))) + (or alist + (let ((python-imenu-format-item-label-function (lambda (type name) name)) + (python-imenu-format-parent-item-label-function (lambda (type name) name)) + (python-imenu-format-parent-item-jump-label-function (lambda (type name) name))) + (python-imenu-create-index)))))) ;;; Misc helpers @@ -3337,6 +3516,22 @@ Optional argument DIRECTION defines the direction to move to." (goto-char comment-start)) (forward-comment factor))) +(defun python-util-popn (lst n) + "Return LST first N elements. +N should be an integer, when it's a natural negative number its +opposite is used. When N is bigger than the length of LST, the +list is returned as is." + (let* ((n (min (abs n))) + (len (length lst)) + (acc)) + (if (> n len) + lst + (while (< 0 n) + (setq acc (cons (car lst) acc) + lst (cdr lst) + n (1- n))) + (reverse acc)))) + ;;;###autoload (define-derived-mode python-mode prog-mode "Python" @@ -3382,11 +3577,8 @@ if that value is non-nil." (add-hook 'post-self-insert-hook 'python-indent-post-self-insert-function nil 'local) - (set (make-local-variable 'imenu-extract-index-name-function) - #'python-info-current-defun) - - (set (make-local-variable 'imenu-prev-index-position-function) - #'python-imenu-prev-index-position) + (set (make-local-variable 'imenu-create-index-function) + #'python-imenu-create-index) (set (make-local-variable 'add-log-current-defun-function) #'python-info-current-defun) diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index b03619e03d9..ed61adec1fe 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -329,7 +329,9 @@ case, and the process object in the asynchronous case." command squeezed)))) (when vc-command-messages (message "Running %s in background..." full-command)) - ;;(set-process-sentinel proc (lambda (p msg) (delete-process p))) + ;; Get rid of the default message insertion, in case we don't + ;; set a sentinel explicitly. + (set-process-sentinel proc #'ignore) (set-process-filter proc 'vc-process-filter) (setq status proc) (when vc-command-messages |