comparison 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
comparison
equal deleted inserted replaced
110522:4bca1a43c0d3 110523:a5ad4f188e19
47 (eval-when-compile (require 'semantic/find)) 47 (eval-when-compile (require 'semantic/find))
48 48
49 (defvar eldoc-last-message) 49 (defvar eldoc-last-message)
50 (declare-function eldoc-message "eldoc") 50 (declare-function eldoc-message "eldoc")
51 (declare-function semantic-analyze-interesting-tag "semantic/analyze") 51 (declare-function semantic-analyze-interesting-tag "semantic/analyze")
52 (declare-function semantic-analyze-unsplit-name "semantic/analyze/fcn")
52 (declare-function semantic-complete-analyze-inline-idle "semantic/complete") 53 (declare-function semantic-complete-analyze-inline-idle "semantic/complete")
53 (declare-function semanticdb-deep-find-tags-by-name "semantic/db-find") 54 (declare-function semanticdb-deep-find-tags-by-name "semantic/db-find")
54 (declare-function semanticdb-save-all-db-idle "semantic/db") 55 (declare-function semanticdb-save-all-db-idle "semantic/db")
55 (declare-function semanticdb-typecache-refresh-for-buffer "semantic/db-typecache") 56 (declare-function semanticdb-typecache-refresh-for-buffer "semantic/db-typecache")
56 (declare-function semantic-decorate-flush-pending-decorations 57 (declare-function semantic-decorate-flush-pending-decorations
326 327
327 ;;; WORK FUNCTION 328 ;;; WORK FUNCTION
328 ;; 329 ;;
329 ;; Unlike the shorter timer, the WORK timer will kick of tasks that 330 ;; Unlike the shorter timer, the WORK timer will kick of tasks that
330 ;; may take a long time to complete. 331 ;; may take a long time to complete.
331 (defcustom semantic-idle-work-parse-neighboring-files-flag t 332 (defcustom semantic-idle-work-parse-neighboring-files-flag nil
332 "*Non-nil means to parse files in the same dir as the current buffer. 333 "*Non-nil means to parse files in the same dir as the current buffer.
333 Disable to prevent lots of excessive parsing in idle time." 334 Disable to prevent lots of excessive parsing in idle time."
334 :group 'semantic 335 :group 'semantic
335 :type 'boolean) 336 :type 'boolean)
336 337
338 (defcustom semantic-idle-work-update-headers-flag nil
339 "*Non-nil means to parse through header files in idle time.
340 Disable to prevent idle time parsing of many files. If completion
341 is called that work will be done then instead."
342 :group 'semantic
343 :type 'boolean)
337 344
338 (defun semantic-idle-work-for-one-buffer (buffer) 345 (defun semantic-idle-work-for-one-buffer (buffer)
339 "Do long-processing work for BUFFER. 346 "Do long-processing work for BUFFER.
340 Uses `semantic-safe' and returns the output. 347 Uses `semantic-safe' and returns the output.
341 Returns t if all processing succeeded." 348 Returns t if all processing succeeded."
343 (not (and 350 (not (and
344 ;; Just in case 351 ;; Just in case
345 (semantic-safe "Idle Work Parse Error: %S" 352 (semantic-safe "Idle Work Parse Error: %S"
346 (semantic-idle-scheduler-refresh-tags) 353 (semantic-idle-scheduler-refresh-tags)
347 t) 354 t)
355
356 ;; Option to disable this work.
357 semantic-idle-work-update-headers-flag
348 358
349 ;; Force all our include files to get read in so we 359 ;; Force all our include files to get read in so we
350 ;; are ready to provide good smart completion and idle 360 ;; are ready to provide good smart completion and idle
351 ;; summary information 361 ;; summary information
352 (semantic-safe "Idle Work Including Error: %S" 362 (semantic-safe "Idle Work Including Error: %S"
672 682
673 683
674 ;;; SUMMARY MODE 684 ;;; SUMMARY MODE
675 ;; 685 ;;
676 ;; A mode similar to eldoc using semantic 686 ;; A mode similar to eldoc using semantic
687 (defcustom semantic-idle-truncate-long-summaries t
688 "Truncate summaries that are too long to fit in the minibuffer.
689 This can prevent minibuffer resizing in idle time."
690 :group 'semantic
691 :type 'boolean)
677 692
678 (defcustom semantic-idle-summary-function 693 (defcustom semantic-idle-summary-function
679 'semantic-format-tag-summarize-with-file 694 'semantic-format-tag-summarize-with-file
680 "Function to call when displaying tag information during idle time. 695 "Function to call when displaying tag information during idle time.
681 This function should take a single argument, a Semantic tag, and 696 This function should take a single argument, a Semantic tag, and
723 738
724 (defun semantic-idle-summary-current-symbol-info-default () 739 (defun semantic-idle-summary-current-symbol-info-default ()
725 "Return a string message describing the current context. 740 "Return a string message describing the current context.
726 This function will disable loading of previously unloaded files 741 This function will disable loading of previously unloaded files
727 by semanticdb as a time-saving measure." 742 by semanticdb as a time-saving measure."
728 (let ( 743 (semanticdb-without-unloaded-file-searches
729 (semanticdb-find-default-throttle 744 (save-excursion
730 (if (featurep 'semantic/db-find) 745 ;; use whichever has success first.
731 (remq 'unloaded semanticdb-find-default-throttle) 746 (or
732 nil)) 747 (semantic-idle-summary-current-symbol-keyword)
733 ) 748
734 (save-excursion 749 (semantic-idle-summary-current-symbol-info-context)
735 ;; use whicever has success first. 750
736 (or 751 (semantic-idle-summary-current-symbol-info-brutish)
737 (semantic-idle-summary-current-symbol-keyword) 752 ))))
738
739 (semantic-idle-summary-current-symbol-info-context)
740
741 (semantic-idle-summary-current-symbol-info-brutish)
742 ))))
743 753
744 (defvar semantic-idle-summary-out-of-context-faces 754 (defvar semantic-idle-summary-out-of-context-faces
745 '( 755 '(
746 font-lock-comment-face 756 font-lock-comment-face
747 font-lock-string-face 757 font-lock-string-face
801 (unless (and str (boundp 'eldoc-echo-area-use-multiline-p) 811 (unless (and str (boundp 'eldoc-echo-area-use-multiline-p)
802 eldoc-echo-area-use-multiline-p) 812 eldoc-echo-area-use-multiline-p)
803 (let ((w (1- (window-width (minibuffer-window))))) 813 (let ((w (1- (window-width (minibuffer-window)))))
804 (if (> (length str) w) 814 (if (> (length str) w)
805 (setq str (substring str 0 w))))) 815 (setq str (substring str 0 w)))))
816 ;; I borrowed some bits from eldoc to shorten the
817 ;; message.
818 (when semantic-idle-truncate-long-summaries
819 (let ((ea-width (1- (window-width (minibuffer-window))))
820 (strlen (length str)))
821 (when (> strlen ea-width)
822 (setq str (substring str 0 ea-width)))))
823 ;; Display it
806 (eldoc-message str)))) 824 (eldoc-message str))))
807 825
808 (define-minor-mode semantic-idle-summary-mode 826 (define-minor-mode semantic-idle-summary-mode
809 "Toggle Semantic Idle Summary mode. 827 "Toggle Semantic Idle Summary mode.
810 With ARG, turn Semantic Idle Summary mode on if ARG is positive, 828 With ARG, turn Semantic Idle Summary mode on if ARG is positive,
866 ;; 884 ;;
867 ;; This mode will use context analysis to perform highlighting 885 ;; This mode will use context analysis to perform highlighting
868 ;; of all uses of the symbol that is under the cursor. 886 ;; of all uses of the symbol that is under the cursor.
869 ;; 887 ;;
870 ;; This is to mimic the Eclipse tool of a similar nature. 888 ;; This is to mimic the Eclipse tool of a similar nature.
871 (defvar semantic-idle-summary-highlight-face 'region 889 (defvar semantic-idle-symbol-highlight-face 'region
872 "Face used for the summary highlight.") 890 "Face used for highlighting local symbols.")
873 891
874 (defun semantic-idle-summary-maybe-highlight (tag) 892 (defun semantic-idle-symbol-maybe-highlight (tag)
875 "Perhaps add highlighting onto TAG. 893 "Perhaps add highlighting to the symbol represented by TAG.
876 TAG was found as the thing under point. If it happens to be 894 TAG was found as the symbol under point. If it happens to be
877 visible, then highlight it." 895 visible, then highlight it."
878 (require 'pulse) 896 (require 'pulse)
879 (let* ((region (when (and (semantic-tag-p tag) 897 (let* ((region (when (and (semantic-tag-p tag)
880 (semantic-tag-with-position-p tag)) 898 (semantic-tag-with-position-p tag))
881 (semantic-tag-overlay tag))) 899 (semantic-tag-overlay tag)))
892 (goto-char (semantic-overlay-start region)) 910 (goto-char (semantic-overlay-start region))
893 (when (pos-visible-in-window-p 911 (when (pos-visible-in-window-p
894 (point) (get-buffer-window (current-buffer) 'visible)) 912 (point) (get-buffer-window (current-buffer) 'visible))
895 (if (< (semantic-overlay-end region) (point-at-eol)) 913 (if (< (semantic-overlay-end region) (point-at-eol))
896 (pulse-momentary-highlight-overlay 914 (pulse-momentary-highlight-overlay
897 region semantic-idle-summary-highlight-face) 915 region semantic-idle-symbol-highlight-face)
898 ;; Not the same 916 ;; Not the same
899 (pulse-momentary-highlight-region 917 (pulse-momentary-highlight-region
900 (semantic-overlay-start region) 918 (semantic-overlay-start region)
901 (point-at-eol) 919 (point-at-eol)
902 semantic-idle-summary-highlight-face))) 920 semantic-idle-symbol-highlight-face)))
903 )) 921 ))
904 ((vectorp region) 922 ((vectorp region)
905 (let ((start (aref region 0)) 923 (let ((start (aref region 0))
906 (end (aref region 1))) 924 (end (aref region 1)))
907 (save-excursion 925 (save-excursion
917 end t) 935 end t)
918 ;; This is likely it, give it a try. 936 ;; This is likely it, give it a try.
919 (pulse-momentary-highlight-region 937 (pulse-momentary-highlight-region
920 start (if (<= end (point-at-eol)) end 938 start (if (<= end (point-at-eol)) end
921 (point-at-eol)) 939 (point-at-eol))
922 semantic-idle-summary-highlight-face))) 940 semantic-idle-symbol-highlight-face)))
923 )))) 941 ))))
924 nil)) 942 nil))
925 943
926 (define-semantic-idle-service semantic-idle-tag-highlight 944 (define-semantic-idle-service semantic-idle-local-symbol-highlight
927 "Highlight the tag, and references of the symbol under point. 945 "Highlight the tag and symbol references of the symbol under point.
928 Call `semantic-analyze-current-context' to find the reference tag. 946 Call `semantic-analyze-current-context' to find the reference tag.
929 Call `semantic-symref-hits-in-region' to identify local references." 947 Call `semantic-symref-hits-in-region' to identify local references."
930 (require 'pulse) 948 (require 'pulse)
931 (when (semantic-idle-summary-useful-context-p) 949 (when (semantic-idle-summary-useful-context-p)
932 (let* ((ctxt (semantic-analyze-current-context)) 950 (let* ((ctxt
951 (semanticdb-without-unloaded-file-searches
952 (semantic-analyze-current-context)))
933 (Hbounds (when ctxt (oref ctxt bounds))) 953 (Hbounds (when ctxt (oref ctxt bounds)))
934 (target (when ctxt (car (reverse (oref ctxt prefix))))) 954 (target (when ctxt (car (reverse (oref ctxt prefix)))))
935 (tag (semantic-current-tag)) 955 (tag (semantic-current-tag))
936 ;; We use pulse, but we don't want the flashy version, 956 ;; We use pulse, but we don't want the flashy version,
937 ;; just the stable version. 957 ;; just the stable version.
938 (pulse-flag nil)) 958 (pulse-flag nil))
939 (when ctxt 959 (when ctxt
940 ;; Highlight the original tag? Protect against problems. 960 ;; Highlight the original tag? Protect against problems.
941 (condition-case nil 961 (condition-case nil
942 (semantic-idle-summary-maybe-highlight target) 962 (semantic-idle-symbol-maybe-highlight target)
943 (error nil)) 963 (error nil))
944 ;; Identify all hits in this current tag. 964 ;; Identify all hits in this current tag.
945 (when (semantic-tag-p target) 965 (when (semantic-tag-p target)
946 (require 'semantic/symref/filter) 966 (require 'semantic/symref/filter)
947 (semantic-symref-hits-in-region 967 (semantic-symref-hits-in-region
948 target (lambda (start end prefix) 968 target (lambda (start end prefix)
949 (when (/= start (car Hbounds)) 969 (when (/= start (car Hbounds))
950 (pulse-momentary-highlight-region 970 (pulse-momentary-highlight-region
951 start end semantic-idle-summary-highlight-face)) 971 start end semantic-idle-symbol-highlight-face))
952 (semantic-throw-on-input 'symref-highlight) 972 (semantic-throw-on-input 'symref-highlight)
953 ) 973 )
954 (semantic-tag-start tag) 974 (semantic-tag-start tag)
955 (semantic-tag-end tag))) 975 (semantic-tag-end tag)))
956 )))) 976 ))))
966 (interactive "P") 986 (interactive "P")
967 ;; When turning off, disable other idle modes. 987 ;; When turning off, disable other idle modes.
968 (when (or (and (numberp arg) (< arg 0)) 988 (when (or (and (numberp arg) (< arg 0))
969 (and (null arg) global-semantic-idle-scheduler-mode)) 989 (and (null arg) global-semantic-idle-scheduler-mode))
970 (global-semantic-idle-summary-mode -1) 990 (global-semantic-idle-summary-mode -1)
971 (global-semantic-idle-tag-highlight-mode -1) 991 (global-semantic-idle-local-symbol-highlight-mode -1)
972 (global-semantic-idle-completions-mode -1)) 992 (global-semantic-idle-completions-mode -1))
973 (setq global-semantic-idle-scheduler-mode 993 (setq global-semantic-idle-scheduler-mode
974 (semantic-toggle-minor-mode-globally 994 (semantic-toggle-minor-mode-globally
975 'semantic-idle-scheduler-mode arg))) 995 'semantic-idle-scheduler-mode arg)))
976 996
978 ;;; Completion Popup Mode 998 ;;; Completion Popup Mode
979 ;; 999 ;;
980 ;; This mode uses tooltips to display a (hopefully) short list of possible 1000 ;; This mode uses tooltips to display a (hopefully) short list of possible
981 ;; completions available for the text under point. It provides 1001 ;; completions available for the text under point. It provides
982 ;; NO provision for actually filling in the values from those completions. 1002 ;; NO provision for actually filling in the values from those completions.
1003 (defun semantic-idle-completions-end-of-symbol-p ()
1004 "Return non-nil if the cursor is at the END of a symbol.
1005 If the cursor is in the middle of a symbol, then we shouldn't be
1006 doing fancy completions."
1007 (not (looking-at "\\w\\|\\s_")))
983 1008
984 (defun semantic-idle-completion-list-default () 1009 (defun semantic-idle-completion-list-default ()
985 "Calculate and display a list of completions." 1010 "Calculate and display a list of completions."
986 (when (semantic-idle-summary-useful-context-p) 1011 (when (and (semantic-idle-summary-useful-context-p)
1012 (semantic-idle-completions-end-of-symbol-p))
987 ;; This mode can be fragile. Ignore problems. 1013 ;; This mode can be fragile. Ignore problems.
988 ;; If something doesn't do what you expect, run 1014 ;; If something doesn't do what you expect, run
989 ;; the below command by hand instead. 1015 ;; the below command by hand instead.
990 (condition-case nil 1016 (condition-case nil
991 (let ( 1017 (semanticdb-without-unloaded-file-searches
992 ;; Don't go loading in oodles of header libraries in 1018 ;; Use idle version.
993 ;; IDLE time. 1019 (semantic-complete-analyze-inline-idle)
994 (semanticdb-find-default-throttle
995 (if (featurep 'semantic/db-find)
996 (remq 'unloaded semanticdb-find-default-throttle)
997 nil))
998 )
999 ;; Use idle version.
1000 (require 'semantic/complete)
1001 (semantic-complete-analyze-inline-idle)
1002 ) 1020 )
1003 (error nil)) 1021 (error nil))
1004 )) 1022 ))
1005 1023
1006 (define-semantic-idle-service semantic-idle-completions 1024 (define-semantic-idle-service semantic-idle-completions
1024 1042
1025 \\{semantic-complete-inline-map}" 1043 \\{semantic-complete-inline-map}"
1026 ;; Add the ability to override sometime. 1044 ;; Add the ability to override sometime.
1027 (semantic-idle-completion-list-default)) 1045 (semantic-idle-completion-list-default))
1028 1046
1047
1048 ;;; Breadcrumbs for tag under point
1049 ;;
1050 ;; Service that displays a breadcrumbs indication of the tag under
1051 ;; point and its parents in the header or mode line.
1052 ;;
1053
1054 (defcustom semantic-idle-breadcrumbs-display-function
1055 #'semantic-idle-breadcrumbs--display-in-header-line
1056 "Function to display the tag under point in idle time.
1057 This function should take a list of Semantic tags as its only
1058 argument. The tags are sorted according to their nesting order,
1059 starting with the outermost tag. The function should call
1060 `semantic-idle-breadcrumbs-format-tag-list-function' to convert
1061 the tag list into a string."
1062 :group 'semantic
1063 :type '(choice
1064 (const :tag "Display in header line"
1065 semantic-idle-breadcrumbs--display-in-header-line)
1066 (const :tag "Display in mode line"
1067 semantic-idle-breadcrumbs--display-in-mode-line)
1068 (function :tag "Other function")))
1069
1070 (defcustom semantic-idle-breadcrumbs-format-tag-list-function
1071 #'semantic-idle-breadcrumbs--format-linear
1072 "Function to format the list of tags containing point.
1073 This function should take a list of Semantic tags and an optional
1074 maximum length of the produced string as its arguments. The
1075 maximum length is a hint and can be ignored. When the maximum
1076 length is omitted, an unconstrained string should be
1077 produced. The tags are sorted according to their nesting order,
1078 starting with the outermost tag. Single tags should be formatted
1079 using `semantic-idle-breadcrumbs-format-tag-function' unless
1080 special formatting is required."
1081 :group 'semantic
1082 :type '(choice
1083 (const :tag "Format tags as list, innermost last"
1084 semantic-idle-breadcrumbs--format-linear)
1085 (const :tag "Innermost tag with details, followed by remaining tags"
1086 semantic-idle-breadcrumbs--format-innermost-first)
1087 (function :tag "Other function")))
1088
1089 (defcustom semantic-idle-breadcrumbs-format-tag-function
1090 #'semantic-format-tag-abbreviate
1091 "Function to call to format information about tags.
1092 This function should take a single argument, a Semantic tag, and
1093 return a string to display.
1094 Some useful functions are found in `semantic-format-tag-functions'."
1095 :group 'semantic
1096 :type semantic-format-tag-custom-list)
1097
1098 (defcustom semantic-idle-breadcrumbs-separator 'mode-specific
1099 "Specify how to separate tags in the breadcrumbs string.
1100 An arbitrary string or a mode-specific scope nesting
1101 string (like, for example, \"::\" in C++, or \".\" in Java) can
1102 be used."
1103 :group 'semantic
1104 :type '(choice
1105 (const :tag "Use mode specific separator"
1106 mode-specific)
1107 (string :tag "Specify separator string")))
1108
1109 (defcustom semantic-idle-breadcrumbs-header-line-prefix
1110 semantic-stickyfunc-indent-string ;; TODO not optimal
1111 "String used to indent the breadcrumbs string.
1112 Customize this string to match the space used by scrollbars and
1113 fringe."
1114 :group 'semantic
1115 :type 'string)
1116
1117 (defvar semantic-idle-breadcrumbs-popup-menu nil
1118 "Menu used when a tag displayed by `semantic-idle-breadcrumbs-mode' is clicked.")
1119
1120 (defun semantic-idle-breadcrumbs--popup-menu (event)
1121 "Popup a menu that displays things to do to the clicked tag.
1122 Argument EVENT describes the event that caused this function to
1123 be called."
1124 (interactive "e")
1125 (let ((old-window (selected-window))
1126 (window (semantic-event-window event)))
1127 (select-window window t)
1128 (semantic-popup-menu semantic-idle-breadcrumbs-popup-menu)
1129 (select-window old-window)))
1130
1131 (defmacro semantic-idle-breadcrumbs--tag-function (function)
1132 "Return lambda expression calling FUNCTION when called from a popup."
1133 `(lambda (event)
1134 (interactive "e")
1135 (let* ((old-window (selected-window))
1136 (window (semantic-event-window event))
1137 (column (car (nth 6 (nth 1 event)))) ;; TODO semantic-event-column?
1138 (tag (progn
1139 (select-window window t)
1140 (plist-get
1141 (text-properties-at column header-line-format)
1142 'tag))))
1143 (,function tag)
1144 (select-window old-window)))
1145 )
1146
1147 ;; TODO does this work for mode-line case?
1148 (defvar semantic-idle-breadcrumbs-popup-map
1149 (let ((map (make-sparse-keymap)))
1150 ;; mouse-1 goes to clicked tag
1151 (define-key map
1152 [ header-line mouse-1 ]
1153 (semantic-idle-breadcrumbs--tag-function
1154 semantic-go-to-tag))
1155 ;; mouse-3 pops up a context menu
1156 (define-key map
1157 [ header-line mouse-3 ]
1158 'semantic-idle-breadcrumbs--popup-menu)
1159 map)
1160 "Keymap for semantic idle breadcrumbs minor mode.")
1161
1162 (easy-menu-define
1163 semantic-idle-breadcrumbs-popup-menu
1164 semantic-idle-breadcrumbs-popup-map
1165 "Semantic Breadcrumbs Mode Menu"
1166 (list
1167 "Breadcrumb Tag"
1168 (semantic-menu-item
1169 (vector
1170 "Go to Tag"
1171 (semantic-idle-breadcrumbs--tag-function
1172 semantic-go-to-tag)
1173 :active t
1174 :help "Jump to this tag"))
1175 ;; TODO these entries need minor changes (optional tag argument) in
1176 ;; senator-copy-tag etc
1177 ;; (semantic-menu-item
1178 ;; (vector
1179 ;; "Copy Tag"
1180 ;; (semantic-idle-breadcrumbs--tag-function
1181 ;; senator-copy-tag)
1182 ;; :active t
1183 ;; :help "Copy this tag"))
1184 ;; (semantic-menu-item
1185 ;; (vector
1186 ;; "Kill Tag"
1187 ;; (semantic-idle-breadcrumbs--tag-function
1188 ;; senator-kill-tag)
1189 ;; :active t
1190 ;; :help "Kill tag text to the kill ring, and copy the tag to
1191 ;; the tag ring"))
1192 ;; (semantic-menu-item
1193 ;; (vector
1194 ;; "Copy Tag to Register"
1195 ;; (semantic-idle-breadcrumbs--tag-function
1196 ;; senator-copy-tag-to-register)
1197 ;; :active t
1198 ;; :help "Copy this tag"))
1199 ;; (semantic-menu-item
1200 ;; (vector
1201 ;; "Narrow to Tag"
1202 ;; (semantic-idle-breadcrumbs--tag-function
1203 ;; senator-narrow-to-defun)
1204 ;; :active t
1205 ;; :help "Narrow to the bounds of the current tag"))
1206 ;; (semantic-menu-item
1207 ;; (vector
1208 ;; "Fold Tag"
1209 ;; (semantic-idle-breadcrumbs--tag-function
1210 ;; senator-fold-tag-toggle)
1211 ;; :active t
1212 ;; :style 'toggle
1213 ;; :selected '(let ((tag (semantic-current-tag)))
1214 ;; (and tag (semantic-tag-folded-p tag)))
1215 ;; :help "Fold the current tag to one line"))
1216 "---"
1217 (semantic-menu-item
1218 (vector
1219 "About this Header Line"
1220 (lambda ()
1221 (interactive)
1222 (describe-function 'semantic-idle-breadcrumbs-mode))
1223 :active t
1224 :help "Display help about this header line."))
1225 )
1226 )
1227
1228 (define-semantic-idle-service semantic-idle-breadcrumbs
1229 "Display breadcrumbs for the tag under point and its parents."
1230 (let* ((scope (semantic-calculate-scope))
1231 (tag-list (if scope
1232 ;; If there is a scope, extract the tag and its
1233 ;; parents.
1234 (append (oref scope parents)
1235 (when (oref scope tag)
1236 (list (oref scope tag))))
1237 ;; Fall back to tags by overlay
1238 (semantic-find-tag-by-overlay))))
1239 ;; Display the tags.
1240 (funcall semantic-idle-breadcrumbs-display-function tag-list)))
1241
1242 (defun semantic-idle-breadcrumbs--display-in-header-line (tag-list)
1243 "Display the tags in TAG-LIST in the header line of their buffer."
1244 (let ((width (- (nth 2 (window-edges))
1245 (nth 0 (window-edges)))))
1246 ;; Format TAG-LIST and put the formatted string into the header
1247 ;; line.
1248 (setq header-line-format
1249 (concat
1250 semantic-idle-breadcrumbs-header-line-prefix
1251 (if tag-list
1252 (semantic-idle-breadcrumbs--format-tag-list
1253 tag-list
1254 (- width
1255 (length semantic-idle-breadcrumbs-header-line-prefix)))
1256 (propertize
1257 "<not on tags>"
1258 'face
1259 'font-lock-comment-face)))))
1260
1261 ;; Update the header line.
1262 (force-mode-line-update))
1263
1264 (defun semantic-idle-breadcrumbs--display-in-mode-line (tag-list)
1265 "Display the tags in TAG-LIST in the mode line of their buffer.
1266 TODO THIS FUNCTION DOES NOT WORK YET."
1267
1268 (error "This function does not work yet")
1269
1270 (let ((width (- (nth 2 (window-edges))
1271 (nth 0 (window-edges)))))
1272 (setq mode-line-format
1273 (semantic-idle-breadcrumbs--format-tag-list tag-list width)))
1274
1275 (force-mode-line-update))
1276
1277 (defun semantic-idle-breadcrumbs--format-tag-list (tag-list max-length)
1278 "Format TAG-LIST using configured functions respecting MAX-LENGTH.
1279 If the initial formatting result is longer than MAX-LENGTH, it is
1280 shortened at the beginning."
1281 ;; Format TAG-LIST using the configured formatting function.
1282 (let* ((complete-format (funcall
1283 semantic-idle-breadcrumbs-format-tag-list-function
1284 tag-list max-length))
1285 ;; Determine length of complete format.
1286 (complete-length (length complete-format)))
1287 ;; Shorten string if necessary.
1288 (if (<= complete-length max-length)
1289 complete-format
1290 (concat "... "
1291 (substring
1292 complete-format
1293 (- complete-length (- max-length 4))))))
1294 )
1295
1296 (defun semantic-idle-breadcrumbs--format-linear
1297 (tag-list &optional max-length)
1298 "Format TAG-LIST as a linear list, starting with the outermost tag.
1299 MAX-LENGTH is not used."
1300 (require 'semantic/analyze/fcn)
1301 (let* ((format-pieces (mapcar
1302 #'semantic-idle-breadcrumbs--format-tag
1303 tag-list))
1304 ;; Format tag list, putting configured separators between the
1305 ;; tags.
1306 (complete-format (cond
1307 ;; Mode specific separator.
1308 ((eq semantic-idle-breadcrumbs-separator
1309 'mode-specific)
1310 (semantic-analyze-unsplit-name format-pieces))
1311
1312 ;; Custom separator.
1313 ((stringp semantic-idle-breadcrumbs-separator)
1314 (mapconcat
1315 #'identity
1316 format-pieces
1317 semantic-idle-breadcrumbs-separator)))))
1318 complete-format)
1319 )
1320
1321 (defun semantic-idle-breadcrumbs--format-innermost-first
1322 (tag-list &optional max-length)
1323 "Format TAG-LIST placing the innermost tag first, separated from its parents.
1324 If MAX-LENGTH is non-nil, the innermost tag is shortened."
1325 (let* (;; Separate and format remaining tags. Calculate length of
1326 ;; resulting string.
1327 (rest-tags (butlast tag-list))
1328 (rest-format (if rest-tags
1329 (concat
1330 " | "
1331 (semantic-idle-breadcrumbs--format-linear
1332 rest-tags))
1333 ""))
1334 (rest-length (length rest-format))
1335 ;; Format innermost tag and calculate length of resulting
1336 ;; string.
1337 (inner-format (semantic-idle-breadcrumbs--format-tag
1338 (car (last tag-list))
1339 #'semantic-format-tag-prototype))
1340 (inner-length (length inner-format))
1341 ;; Calculate complete length and shorten string for innermost
1342 ;; tag if MAX-LENGTH is non-nil and the complete string is
1343 ;; too long.
1344 (complete-length (+ inner-length rest-length))
1345 (inner-short (if (and max-length
1346 (<= complete-length max-length))
1347 inner-format
1348 (concat (substring
1349 inner-format
1350 0
1351 (- inner-length
1352 (- complete-length max-length)
1353 4))
1354 " ..."))))
1355 ;; Concat both parts.
1356 (concat inner-short rest-format))
1357 )
1358
1359 (defun semantic-idle-breadcrumbs--format-tag (tag &optional format-function)
1360 "Format TAG using the configured function or FORMAT-FUNCTION.
1361 This function also adds text properties for help-echo, mouse
1362 highlighting and a keymap."
1363 (let ((formatted (funcall
1364 (or format-function
1365 semantic-idle-breadcrumbs-format-tag-function)
1366 tag nil t)))
1367 (add-text-properties
1368 0 (length formatted)
1369 (list
1370 'tag
1371 tag
1372 'help-echo
1373 (format
1374 "Tag %s
1375 Type: %s
1376 mouse-1: jump to tag
1377 mouse-3: popup context menu"
1378 (semantic-tag-name tag)
1379 (semantic-tag-class tag))
1380 'mouse-face
1381 'highlight
1382 'keymap
1383 semantic-idle-breadcrumbs-popup-map)
1384 formatted)
1385 formatted))
1386
1387
1029 (provide 'semantic/idle) 1388 (provide 'semantic/idle)
1030 1389
1031 ;; Local variables: 1390 ;; Local variables:
1032 ;; generated-autoload-file: "loaddefs.el" 1391 ;; generated-autoload-file: "loaddefs.el"
1033 ;; generated-autoload-load-name: "semantic/idle" 1392 ;; generated-autoload-load-name: "semantic/idle"