diff lisp/cedet/semantic/idle.el @ 110523:a5ad4f188e19

Synch Semantic to CEDET 1.0. Move CEDET ChangeLog entries to new file lisp/cedet/ChangeLog. * semantic.el (semantic-version): Update to 2.0. (semantic-mode-map): Add "," and "m" bindings. (navigate-menu): Update. * semantic/symref.el (semantic-symref-calculate-rootdir): New function. (semantic-symref-detect-symref-tool): Use it. * semantic/symref/grep.el (semantic-symref-grep-shell): New var. (semantic-symref-perform-search): Use it. Calculate root dir with semantic-symref-calculate-rootdir. (semantic-symref-derive-find-filepatterns): Improve error message. * semantic/symref/list.el (semantic-symref-results-mode-map): New bindings. (semantic-symref-auto-expand-results): New option. (semantic-symref-results-dump): Obey auto-expand. (semantic-symref-list-expand-all, semantic-symref-regexp) (semantic-symref-list-contract-all) (semantic-symref-list-map-open-hits) (semantic-symref-list-update-open-hits) (semantic-symref-list-create-macro-on-open-hit) (semantic-symref-list-call-macro-on-open-hits): New functions. (semantic-symref-list-menu-entries) (semantic-symref-list-menu): New vars. (semantic-symref-list-map-open-hits): Move cursor to beginning of match before calling the mapped function. * semantic/doc.el (semantic-documentation-comment-preceeding-tag): Do nothing if the mode doesn't provide comment-start-skip. * semantic/scope.el (semantic-analyze-scope-nested-tags-default): Strip duplicates. (semantic-analyze-scoped-inherited-tag-map): Take the tag we are looking for as part of the scoped tags list. * semantic/html.el (semantic-default-html-setup): Add senator-step-at-tag-classes. * semantic/decorate/include.el (semantic-decoration-on-unknown-includes): Change light bgcolor. (semantic-decoration-on-includes-highlight-default): Check that the include tag has a postion. * semantic/complete.el (semantic-collector-local-members): (semantic-complete-read-tag-local-members) (semantic-complete-jump-local-members): New class and functions. (semantic-complete-self-insert): Save excursion before completing. * semantic/analyze/complete.el (semantic-analyze-possible-completions-default): If no completions are found, return the raw by-name-only completion list. Add FLAGS arguments. Add support for 'no-tc (type constraint) and 'no-unique, or no stripping duplicates. (semantic-analyze-possible-completions-default): Add FLAGS arg. * semantic/util-modes.el (semantic-stickyfunc-show-only-functions-p): New option. (semantic-stickyfunc-fetch-stickyline): Don't show stickytext for the very first line in a buffer. * semantic/util.el (semantic-hack-search) (semantic-recursive-find-nonterminal-by-name) (semantic-current-tag-interactive): Deleted. (semantic-describe-buffer): Fix expand-nonterminal. Add lex-syntax-mods, type relation separator char, and command separation char. (semantic-sanity-check): Only message if called interactively. * semantic/tag.el (semantic-tag-deep-copy-one-tag): Copy the :filename property and the tag position. * semantic/lex-spp.el (semantic-lex-spp-lex-text-string): Add recursion limit. * semantic/imenu.el (semantic-imenu-bucketize-type-members): Make this buffer local, not the obsoleted variable. * semantic/idle.el: Add breadcrumbs support. (semantic-idle-summary-current-symbol-info-default) (semantic-idle-tag-highlight) (semantic-idle-completion-list-default): Use semanticdb-without-unloaded-file-searches for speed, and to conform to the controls that specify if the idle timer is supposed to be parsing unparsed includes. (semantic-idle-symbol-highlight-face) (semantic-idle-symbol-maybe-highlight): Rename from *-summary-*. Callers changed. (semantic-idle-work-parse-neighboring-files-flag): Default to nil. (semantic-idle-work-update-headers-flag): New var. (semantic-idle-work-for-one-buffer): Use it. (semantic-idle-local-symbol-highlight): Rename from semantic-idle-tag-highlight. (semantic-idle-truncate-long-summaries): New option. * semantic/ia.el (semantic-ia-cache) (semantic-ia-get-completions): Deleted. Callers changed. (semantic-ia-show-variants): New command. (semantic-ia-show-doc): If doc is empty, don't make a temp buffer. (semantic-ia-show-summary): If there isn't anything to show, say so. * semantic/grammar.el (semantic-grammar-create-package): Save the buffer even in batch mode. * semantic/fw.el (semanticdb-without-unloaded-file-searches): New macro. * semantic/dep.el (semantic-dependency-find-file-on-path): Fix case dereferencing ede-object when it is a list. * semantic/db-typecache.el (semanticdb-expand-nested-tag) (semanticdb-typecache-faux-namespace): New functions. (semanticdb-typecache-file-tags) (semanticdb-typecache-merge-streams): Use them. (semanticdb-typecache-file-tags): When deriving tags from a file, give the mode a chance to monkey with the tag copy. (semanticdb-typecache-find-default): Wrap find in save-excursion. (semanticdb-typecache-find-by-name-helper): Merge found names down. * semantic/db-global.el (semanticdb-enable-gnu-global-in-buffer): Don't show messages if GNU Global is not available and we don't want to throw an error. * semantic/db-find.el (semanticdb-find-result-nth-in-buffer): When trying to normalize the tag to a buffer, don't error if set-buffer method doesn't exist. * semantic/db-file.el (semanticdb-save-db): Simplify msg. * semantic/db.el (semanticdb-refresh-table): If forcing a refresh on a file not in a buffer, use semantic-find-file-noselect and delete the buffer after use. (semanticdb-current-database-list): When calculating root via hooks, force it through true-filename and skip the list of possible roots. * semantic/ctxt.el (semantic-ctxt-imported-packages): New. * semantic/analyze/debug.el (semantic-analyzer-debug-insert-tag): Reset standard output to current buffer. (semantic-analyzer-debug-global-symbol) (semantic-analyzer-debug-missing-innertype): Change "prefix" to "symbol" in messages. * semantic/analyze/refs.el: (semantic-analyze-refs-impl) (semantic-analyze-refs-proto): When calculating value, make sure the found tag is 'similar' to the originating tag. (semantic--analyze-refs-find-tags-with-parent): Attempt to identify matches via imported symbols of parents. (semantic--analyze-refs-full-lookup-with-parents): Do a deep search during the brute search. * semantic/analyze.el (semantic-analyze-find-tag-sequence-default): Be robust to calculated scopes being nil. * semantic/bovine/c.el (semantic-c-describe-environment): Add project macro symbol array. (semantic-c-parse-lexical-token): Add recursion limit. (semantic-ctxt-imported-packages, semanticdb-expand-nested-tag): New overrides. (semantic-expand-c-tag-namelist): Split a full type from a typedef out to its own tag. (semantic-expand-c-tag-namelist): Do not split out a typedef'd inline type if it is an anonymous type. (semantic-c-reconstitute-token): Use the optional initializers as a clue that some function is probably a constructor. When defining the type of these constructors, split the parent name, and use only the class part, if applicable. * semantic/bovine/c-by.el: * semantic/wisent/python-wy.el: Regenerate.
author Chong Yidong <cyd@stupidchicken.com>
date Sat, 18 Sep 2010 22:49:54 -0400
parents 181539c8b6a4
children b799d38f522a 376148b31b5e
line wrap: on
line diff
--- a/lisp/cedet/semantic/idle.el	Sat Sep 18 13:43:13 2010 -0700
+++ b/lisp/cedet/semantic/idle.el	Sat Sep 18 22:49:54 2010 -0400
@@ -49,6 +49,7 @@
 (defvar eldoc-last-message)
 (declare-function eldoc-message "eldoc")
 (declare-function semantic-analyze-interesting-tag "semantic/analyze")
+(declare-function semantic-analyze-unsplit-name "semantic/analyze/fcn")
 (declare-function semantic-complete-analyze-inline-idle "semantic/complete")
 (declare-function semanticdb-deep-find-tags-by-name "semantic/db-find")
 (declare-function semanticdb-save-all-db-idle "semantic/db")
@@ -328,12 +329,18 @@
 ;;
 ;; Unlike the shorter timer, the WORK timer will kick of tasks that
 ;; may take a long time to complete.
-(defcustom semantic-idle-work-parse-neighboring-files-flag t
+(defcustom semantic-idle-work-parse-neighboring-files-flag nil
   "*Non-nil means to parse files in the same dir as the current buffer.
 Disable to prevent lots of excessive parsing in idle time."
   :group 'semantic
   :type 'boolean)
 
+(defcustom semantic-idle-work-update-headers-flag nil
+  "*Non-nil means to parse through header files in idle time.
+Disable to prevent idle time parsing of many files.  If completion
+is called that work will be done then instead."
+  :group 'semantic
+  :type 'boolean)
 
 (defun semantic-idle-work-for-one-buffer (buffer)
   "Do long-processing work for BUFFER.
@@ -346,6 +353,9 @@
 	    (semantic-idle-scheduler-refresh-tags)
 	    t)
 
+	  ;; Option to disable this work.
+	  semantic-idle-work-update-headers-flag
+
 	  ;; Force all our include files to get read in so we
 	  ;; are ready to provide good smart completion and idle
 	  ;; summary information
@@ -674,6 +684,11 @@
 ;;; SUMMARY MODE
 ;;
 ;; A mode similar to eldoc using semantic
+(defcustom semantic-idle-truncate-long-summaries t
+  "Truncate summaries that are too long to fit in the minibuffer.
+This can prevent minibuffer resizing in idle time."
+  :group 'semantic
+  :type 'boolean)
 
 (defcustom semantic-idle-summary-function
   'semantic-format-tag-summarize-with-file
@@ -725,21 +740,16 @@
   "Return a string message describing the current context.
 This function will disable loading of previously unloaded files
 by semanticdb as a time-saving measure."
-  (let (
-	(semanticdb-find-default-throttle
-	 (if (featurep 'semantic/db-find)
-	     (remq 'unloaded semanticdb-find-default-throttle)
-	   nil))
-	)
-    (save-excursion
-      ;; use whicever has success first.
-      (or
-       (semantic-idle-summary-current-symbol-keyword)
+  (semanticdb-without-unloaded-file-searches
+      (save-excursion
+	;; use whichever has success first.
+	(or
+	 (semantic-idle-summary-current-symbol-keyword)
 
-       (semantic-idle-summary-current-symbol-info-context)
+	 (semantic-idle-summary-current-symbol-info-context)
 
-       (semantic-idle-summary-current-symbol-info-brutish)
-       ))))
+	 (semantic-idle-summary-current-symbol-info-brutish)
+	 ))))
 
 (defvar semantic-idle-summary-out-of-context-faces
   '(
@@ -803,6 +813,14 @@
           (let ((w (1- (window-width (minibuffer-window)))))
             (if (> (length str) w)
                 (setq str (substring str 0 w)))))
+	;; I borrowed some bits from eldoc to shorten the
+	;; message.
+	(when semantic-idle-truncate-long-summaries
+	  (let ((ea-width (1- (window-width (minibuffer-window))))
+		(strlen (length str)))
+	    (when (> strlen ea-width)
+	      (setq str (substring str 0 ea-width)))))
+	;; Display it
         (eldoc-message str))))
 
 (define-minor-mode semantic-idle-summary-mode
@@ -868,12 +886,12 @@
 ;; of all uses of the symbol that is under the cursor.
 ;;
 ;; This is to mimic the Eclipse tool of a similar nature.
-(defvar semantic-idle-summary-highlight-face 'region
-  "Face used for the summary highlight.")
+(defvar semantic-idle-symbol-highlight-face 'region
+  "Face used for highlighting local symbols.")
 
-(defun semantic-idle-summary-maybe-highlight (tag)
-  "Perhaps add highlighting onto TAG.
-TAG was found as the thing under point.  If it happens to be
+(defun semantic-idle-symbol-maybe-highlight (tag)
+  "Perhaps add highlighting to the symbol represented by TAG.
+TAG was found as the symbol under point.  If it happens to be
 visible, then highlight it."
   (require 'pulse)
   (let* ((region (when (and (semantic-tag-p tag)
@@ -894,12 +912,12 @@
 		    (point) (get-buffer-window (current-buffer) 'visible))
 	       (if (< (semantic-overlay-end region) (point-at-eol))
 		   (pulse-momentary-highlight-overlay
-		    region semantic-idle-summary-highlight-face)
+		    region semantic-idle-symbol-highlight-face)
 		 ;; Not the same
 		 (pulse-momentary-highlight-region
 		  (semantic-overlay-start region)
 		  (point-at-eol)
-		  semantic-idle-summary-highlight-face)))
+		  semantic-idle-symbol-highlight-face)))
 	     ))
 	  ((vectorp region)
 	   (let ((start (aref region 0))
@@ -919,17 +937,19 @@
 		   (pulse-momentary-highlight-region
 		    start (if (<= end (point-at-eol)) end
 			    (point-at-eol))
-		    semantic-idle-summary-highlight-face)))
+		    semantic-idle-symbol-highlight-face)))
 	       ))))
     nil))
 
-(define-semantic-idle-service semantic-idle-tag-highlight
-  "Highlight the tag, and references of the symbol under point.
+(define-semantic-idle-service semantic-idle-local-symbol-highlight
+  "Highlight the tag and symbol references of the symbol under point.
 Call `semantic-analyze-current-context' to find the reference tag.
 Call `semantic-symref-hits-in-region' to identify local references."
   (require 'pulse)
   (when (semantic-idle-summary-useful-context-p)
-    (let* ((ctxt (semantic-analyze-current-context))
+    (let* ((ctxt
+	    (semanticdb-without-unloaded-file-searches
+		(semantic-analyze-current-context)))
 	   (Hbounds (when ctxt (oref ctxt bounds)))
 	   (target (when ctxt (car (reverse (oref ctxt prefix)))))
 	   (tag (semantic-current-tag))
@@ -939,7 +959,7 @@
       (when ctxt
 	;; Highlight the original tag?  Protect against problems.
 	(condition-case nil
-	    (semantic-idle-summary-maybe-highlight target)
+	    (semantic-idle-symbol-maybe-highlight target)
 	  (error nil))
 	;; Identify all hits in this current tag.
 	(when (semantic-tag-p target)
@@ -948,7 +968,7 @@
 	   target (lambda (start end prefix)
 		    (when (/= start (car Hbounds))
 		      (pulse-momentary-highlight-region
-		       start end semantic-idle-summary-highlight-face))
+		       start end semantic-idle-symbol-highlight-face))
 		    (semantic-throw-on-input 'symref-highlight)
 		    )
 	   (semantic-tag-start tag)
@@ -968,7 +988,7 @@
   (when (or (and (numberp arg) (< arg 0))
 	    (and (null arg) global-semantic-idle-scheduler-mode))
     (global-semantic-idle-summary-mode -1)
-    (global-semantic-idle-tag-highlight-mode -1)
+    (global-semantic-idle-local-symbol-highlight-mode -1)
     (global-semantic-idle-completions-mode -1))
   (setq global-semantic-idle-scheduler-mode
         (semantic-toggle-minor-mode-globally
@@ -980,25 +1000,23 @@
 ;; This mode uses tooltips to display a (hopefully) short list of possible
 ;; completions available for the text under point.  It provides
 ;; NO provision for actually filling in the values from those completions.
+(defun semantic-idle-completions-end-of-symbol-p ()
+  "Return non-nil if the cursor is at the END of a symbol.
+If the cursor is in the middle of a symbol, then we shouldn't be
+doing fancy completions."
+  (not (looking-at "\\w\\|\\s_")))
 
 (defun semantic-idle-completion-list-default ()
   "Calculate and display a list of completions."
-  (when (semantic-idle-summary-useful-context-p)
+  (when (and (semantic-idle-summary-useful-context-p)
+	     (semantic-idle-completions-end-of-symbol-p))
     ;; This mode can be fragile.  Ignore problems.
     ;; If something doesn't do what you expect, run
     ;; the below command by hand instead.
     (condition-case nil
-	(let (
-	      ;; Don't go loading in oodles of header libraries in
-	      ;; IDLE time.
-	      (semanticdb-find-default-throttle
-	       (if (featurep 'semantic/db-find)
-		   (remq 'unloaded semanticdb-find-default-throttle)
-		 nil))
-	      )
-	  ;; Use idle version.
-	  (require 'semantic/complete)
-	  (semantic-complete-analyze-inline-idle)
+	(semanticdb-without-unloaded-file-searches
+	    ;; Use idle version.
+	    (semantic-complete-analyze-inline-idle)
 	  )
       (error nil))
     ))
@@ -1026,6 +1044,347 @@
   ;; Add the ability to override sometime.
   (semantic-idle-completion-list-default))
 
+
+;;; Breadcrumbs for tag under point
+;;
+;; Service that displays a breadcrumbs indication of the tag under
+;; point and its parents in the header or mode line.
+;;
+
+(defcustom semantic-idle-breadcrumbs-display-function
+  #'semantic-idle-breadcrumbs--display-in-header-line
+  "Function to display the tag under point in idle time.
+This function should take a list of Semantic tags as its only
+argument. The tags are sorted according to their nesting order,
+starting with the outermost tag. The function should call
+`semantic-idle-breadcrumbs-format-tag-list-function' to convert
+the tag list into a string."
+  :group 'semantic
+  :type  '(choice
+	   (const    :tag "Display in header line"
+		     semantic-idle-breadcrumbs--display-in-header-line)
+	   (const    :tag "Display in mode line"
+		     semantic-idle-breadcrumbs--display-in-mode-line)
+	   (function :tag "Other function")))
+
+(defcustom semantic-idle-breadcrumbs-format-tag-list-function
+  #'semantic-idle-breadcrumbs--format-linear
+  "Function to format the list of tags containing point.
+This function should take a list of Semantic tags and an optional
+maximum length of the produced string as its arguments. The
+maximum length is a hint and can be ignored. When the maximum
+length is omitted, an unconstrained string should be
+produced. The tags are sorted according to their nesting order,
+starting with the outermost tag. Single tags should be formatted
+using `semantic-idle-breadcrumbs-format-tag-function' unless
+special formatting is required."
+  :group 'semantic
+  :type  '(choice
+	   (const    :tag "Format tags as list, innermost last"
+		     semantic-idle-breadcrumbs--format-linear)
+	   (const    :tag "Innermost tag with details, followed by remaining tags"
+		     semantic-idle-breadcrumbs--format-innermost-first)
+	   (function :tag "Other function")))
+
+(defcustom semantic-idle-breadcrumbs-format-tag-function
+  #'semantic-format-tag-abbreviate
+  "Function to call to format information about tags.
+This function should take a single argument, a Semantic tag, and
+return a string to display.
+Some useful functions are found in `semantic-format-tag-functions'."
+   :group 'semantic
+   :type  semantic-format-tag-custom-list)
+
+(defcustom semantic-idle-breadcrumbs-separator 'mode-specific
+  "Specify how to separate tags in the breadcrumbs string.
+An arbitrary string or a mode-specific scope nesting
+string (like, for example, \"::\" in C++, or \".\" in Java) can
+be used."
+  :group 'semantic
+  :type  '(choice
+	   (const  :tag "Use mode specific separator"
+		   mode-specific)
+	   (string :tag "Specify separator string")))
+
+(defcustom semantic-idle-breadcrumbs-header-line-prefix
+  semantic-stickyfunc-indent-string ;; TODO not optimal
+  "String used to indent the breadcrumbs string.
+Customize this string to match the space used by scrollbars and
+fringe."
+  :group 'semantic
+  :type  'string)
+
+(defvar semantic-idle-breadcrumbs-popup-menu nil
+  "Menu used when a tag displayed by `semantic-idle-breadcrumbs-mode' is clicked.")
+
+(defun semantic-idle-breadcrumbs--popup-menu (event)
+  "Popup a menu that displays things to do to the clicked tag.
+Argument EVENT describes the event that caused this function to
+be called."
+  (interactive "e")
+  (let ((old-window (selected-window))
+	(window     (semantic-event-window event)))
+    (select-window window t)
+    (semantic-popup-menu semantic-idle-breadcrumbs-popup-menu)
+    (select-window old-window)))
+
+(defmacro semantic-idle-breadcrumbs--tag-function (function)
+  "Return lambda expression calling FUNCTION when called from a popup."
+  `(lambda (event)
+     (interactive "e")
+     (let* ((old-window (selected-window))
+	    (window     (semantic-event-window event))
+	    (column     (car (nth 6 (nth 1 event)))) ;; TODO semantic-event-column?
+	    (tag        (progn
+			  (select-window window t)
+			  (plist-get
+			   (text-properties-at column header-line-format)
+			   'tag))))
+       (,function tag)
+       (select-window old-window)))
+  )
+
+;; TODO does this work for mode-line case?
+(defvar semantic-idle-breadcrumbs-popup-map
+  (let ((map (make-sparse-keymap)))
+    ;; mouse-1 goes to clicked tag
+    (define-key map
+      [ header-line mouse-1 ]
+      (semantic-idle-breadcrumbs--tag-function
+       semantic-go-to-tag))
+    ;; mouse-3 pops up a context menu
+    (define-key map
+      [ header-line mouse-3 ]
+      'semantic-idle-breadcrumbs--popup-menu)
+    map)
+  "Keymap for semantic idle breadcrumbs minor mode.")
+
+(easy-menu-define
+  semantic-idle-breadcrumbs-popup-menu
+  semantic-idle-breadcrumbs-popup-map
+  "Semantic Breadcrumbs Mode Menu"
+  (list
+   "Breadcrumb Tag"
+   (semantic-menu-item
+    (vector
+     "Go to Tag"
+     (semantic-idle-breadcrumbs--tag-function
+      semantic-go-to-tag)
+     :active t
+     :help  "Jump to this tag"))
+   ;; TODO these entries need minor changes (optional tag argument) in
+   ;; senator-copy-tag etc
+  ;;  (semantic-menu-item
+  ;;   (vector
+  ;;    "Copy Tag"
+  ;;    (semantic-idle-breadcrumbs--tag-function
+  ;;     senator-copy-tag)
+  ;;    :active t
+  ;;    :help   "Copy this tag"))
+  ;;   (semantic-menu-item
+  ;;    (vector
+  ;;     "Kill Tag"
+  ;;     (semantic-idle-breadcrumbs--tag-function
+  ;;      senator-kill-tag)
+  ;;     :active t
+  ;;     :help   "Kill tag text to the kill ring, and copy the tag to
+  ;; the tag ring"))
+  ;;   (semantic-menu-item
+  ;;    (vector
+  ;;     "Copy Tag to Register"
+  ;;     (semantic-idle-breadcrumbs--tag-function
+  ;;      senator-copy-tag-to-register)
+  ;;     :active t
+  ;;     :help   "Copy this tag"))
+  ;;   (semantic-menu-item
+  ;;    (vector
+  ;;     "Narrow to Tag"
+  ;;     (semantic-idle-breadcrumbs--tag-function
+  ;;      senator-narrow-to-defun)
+  ;;     :active t
+  ;;     :help   "Narrow to the bounds of the current tag"))
+  ;;   (semantic-menu-item
+  ;;    (vector
+  ;;     "Fold Tag"
+  ;;     (semantic-idle-breadcrumbs--tag-function
+  ;;      senator-fold-tag-toggle)
+  ;;     :active   t
+  ;;     :style    'toggle
+  ;;     :selected '(let ((tag (semantic-current-tag)))
+  ;; 		   (and tag (semantic-tag-folded-p tag)))
+  ;;     :help     "Fold the current tag to one line"))
+    "---"
+    (semantic-menu-item
+     (vector
+      "About this Header Line"
+      (lambda ()
+	(interactive)
+	(describe-function 'semantic-idle-breadcrumbs-mode))
+      :active t
+      :help   "Display help about this header line."))
+    )
+  )
+
+(define-semantic-idle-service semantic-idle-breadcrumbs
+  "Display breadcrumbs for the tag under point and its parents."
+  (let* ((scope    (semantic-calculate-scope))
+	 (tag-list (if scope
+		       ;; If there is a scope, extract the tag and its
+		       ;; parents.
+		       (append (oref scope parents)
+			       (when (oref scope tag)
+				 (list (oref scope tag))))
+		     ;; Fall back to tags by overlay
+		     (semantic-find-tag-by-overlay))))
+    ;; Display the tags.
+    (funcall semantic-idle-breadcrumbs-display-function tag-list)))
+
+(defun semantic-idle-breadcrumbs--display-in-header-line (tag-list)
+  "Display the tags in TAG-LIST in the header line of their buffer."
+  (let ((width (- (nth 2 (window-edges))
+		  (nth 0 (window-edges)))))
+    ;; Format TAG-LIST and put the formatted string into the header
+    ;; line.
+    (setq header-line-format
+	  (concat
+	   semantic-idle-breadcrumbs-header-line-prefix
+	   (if tag-list
+	       (semantic-idle-breadcrumbs--format-tag-list
+		tag-list
+		(- width
+		   (length semantic-idle-breadcrumbs-header-line-prefix)))
+	     (propertize
+	      "<not on tags>"
+	      'face
+	      'font-lock-comment-face)))))
+
+  ;; Update the header line.
+  (force-mode-line-update))
+
+(defun semantic-idle-breadcrumbs--display-in-mode-line (tag-list)
+  "Display the tags in TAG-LIST in the mode line of their buffer.
+TODO THIS FUNCTION DOES NOT WORK YET."
+
+  (error "This function does not work yet")
+
+  (let ((width (- (nth 2 (window-edges))
+		  (nth 0 (window-edges)))))
+    (setq mode-line-format
+	  (semantic-idle-breadcrumbs--format-tag-list tag-list width)))
+
+  (force-mode-line-update))
+
+(defun semantic-idle-breadcrumbs--format-tag-list (tag-list max-length)
+  "Format TAG-LIST using configured functions respecting MAX-LENGTH.
+If the initial formatting result is longer than MAX-LENGTH, it is
+shortened at the beginning."
+  ;; Format TAG-LIST using the configured formatting function.
+  (let* ((complete-format (funcall
+			   semantic-idle-breadcrumbs-format-tag-list-function
+			   tag-list max-length))
+	 ;; Determine length of complete format.
+	 (complete-length (length complete-format)))
+    ;; Shorten string if necessary.
+    (if (<= complete-length max-length)
+	complete-format
+      (concat "... "
+	      (substring
+	       complete-format
+	       (- complete-length (- max-length 4))))))
+  )
+
+(defun semantic-idle-breadcrumbs--format-linear
+  (tag-list &optional max-length)
+  "Format TAG-LIST as a linear list, starting with the outermost tag.
+MAX-LENGTH is not used."
+  (require 'semantic/analyze/fcn)
+  (let* ((format-pieces   (mapcar
+			   #'semantic-idle-breadcrumbs--format-tag
+			   tag-list))
+	 ;; Format tag list, putting configured separators between the
+	 ;; tags.
+	 (complete-format (cond
+			   ;; Mode specific separator.
+			   ((eq semantic-idle-breadcrumbs-separator
+				'mode-specific)
+			    (semantic-analyze-unsplit-name format-pieces))
+
+			   ;; Custom separator.
+			   ((stringp semantic-idle-breadcrumbs-separator)
+			    (mapconcat
+			     #'identity
+			     format-pieces
+			     semantic-idle-breadcrumbs-separator)))))
+    complete-format)
+  )
+
+(defun semantic-idle-breadcrumbs--format-innermost-first
+  (tag-list &optional max-length)
+  "Format TAG-LIST placing the innermost tag first, separated from its parents.
+If MAX-LENGTH is non-nil, the innermost tag is shortened."
+  (let* (;; Separate and format remaining tags. Calculate length of
+	 ;; resulting string.
+	 (rest-tags       (butlast tag-list))
+	 (rest-format     (if rest-tags
+			      (concat
+			       " | "
+			       (semantic-idle-breadcrumbs--format-linear
+				rest-tags))
+			    ""))
+	 (rest-length     (length rest-format))
+	 ;; Format innermost tag and calculate length of resulting
+	 ;; string.
+	 (inner-format    (semantic-idle-breadcrumbs--format-tag
+			   (car (last tag-list))
+			   #'semantic-format-tag-prototype))
+	 (inner-length    (length inner-format))
+	 ;; Calculate complete length and shorten string for innermost
+	 ;; tag if MAX-LENGTH is non-nil and the complete string is
+	 ;; too long.
+	 (complete-length (+ inner-length rest-length))
+	 (inner-short     (if (and max-length
+				   (<= complete-length max-length))
+			      inner-format
+			    (concat (substring
+				     inner-format
+				     0
+				     (- inner-length
+					(- complete-length max-length)
+					4))
+				    " ..."))))
+    ;; Concat both parts.
+    (concat inner-short rest-format))
+  )
+
+(defun semantic-idle-breadcrumbs--format-tag (tag &optional format-function)
+  "Format TAG using the configured function or FORMAT-FUNCTION.
+This function also adds text properties for help-echo, mouse
+highlighting and a keymap."
+  (let ((formatted (funcall
+		    (or format-function
+			semantic-idle-breadcrumbs-format-tag-function)
+		    tag nil t)))
+    (add-text-properties
+     0 (length formatted)
+     (list
+      'tag
+      tag
+      'help-echo
+      (format
+       "Tag %s
+Type: %s
+mouse-1: jump to tag
+mouse-3: popup context menu"
+       (semantic-tag-name tag)
+       (semantic-tag-class tag))
+      'mouse-face
+      'highlight
+      'keymap
+      semantic-idle-breadcrumbs-popup-map)
+     formatted)
+    formatted))
+
+
 (provide 'semantic/idle)
 
 ;; Local variables: