Hello All,
> Is there any existing way of sorting the Classes imenu,
> (I thought that setting the imenu-sort-function may do this but
> apparently not)
> or would this require a modification to the jde-create-imenu-index
> function?
Attached file jde-parse-imenu.el contains enhanced versions of the
jde-parse.el imenu functions to add customizable sort facilities to the
JDE Classes index menu.
Your feedback will be welcome.
Sincerely,
David <[EMAIL PROTECTED]>
;;;
;;; Load this file after the JDE or replace `jde-create-imenu-index',
;;; `jde-imenu-index-class' and `jde-imenu-index-class-parts'
;;; functions by the above code in jde-parse.el to add customizable
;;; sort facilities to the JDE Classes imenu.
;;;
;;; David Ponce <[EMAIL PROTECTED]>
;;;
(defcustom jde-imenu-index-sort nil
"If non-nil sorts items in the classes index menu.
You can choose:
- - 'asc to sort by token name ascending (ignoring case).
- - 'desc to sort by token name descending (ignoring case).
Use *Rescan* to rebuild the imenu when you have changed this option."
:group 'jde-project
:type '(choice (const :tag "No sort" nil )
(const :tag "Ascending" asc )
(const :tag "Descending" desc)))
(defun jde-sort-tokens (tokens)
"Sorts the token list TOKENS depending on `jde-imenu-index-sort' value."
(cond ((eq jde-imenu-index-sort 'asc)
(sort tokens
(function
(lambda (token1 token2)
(string-lessp (upcase (semantic-token-name token1))
(upcase (semantic-token-name token2)))))))
((eq jde-imenu-index-sort 'desc)
(sort tokens
(function
(lambda (token1 token2)
(string-lessp (upcase (semantic-token-name token2))
(upcase (semantic-token-name token1)))))))
(t
tokens)))
(defun jde-imenu-index-class (class-token)
"Creates an imenu index for a class in CLASS-TOKEN."
(let* ((class-name (semantic-token-name class-token))
(class-type (semantic-token-type class-token))
(class-start (semantic-token-start class-token))
(class-parts (semantic-token-type-parts class-token))
(class-index (jde-imenu-index-class-parts class-parts)))
(if jde-imenu-include-classdef
;; If requested adds a *class def* item to go to the class def.
(setq class-index (cons (cons "*class def*" class-start)
class-index))
;; Else adds an *empty* item to go to the class def. only
;; when there is not parts
(or class-index
(setq class-index
(list (cons "*empty*"
class-start)))))
(list (cons (format "%s %s" class-type class-name)
class-index))))
(defun jde-imenu-index-class-parts (tokens)
"Creates an imenu index for class parts in TOKENS.
When`jde-imenu-include-signature' is non-nil the
index menu displays full method signatures and field types."
(let ((methods (semantic-find-nonterminal-by-token 'function tokens))
(fields (semantic-find-nonterminal-by-token 'variable tokens))
(classes (semantic-find-nonterminal-by-token 'type tokens))
index)
(setq methods (jde-sort-tokens methods))
(while methods
(let* ((method-token (car methods))
(method-name (semantic-token-name method-token))
(method-pos (semantic-token-start method-token))
method-sig)
(if jde-imenu-include-signature
(let ((method-type (semantic-token-type method-token))
(method-args (semantic-token-function-args method-token)))
(setq method-sig (if method-type
(format "%s %s(" method-type method-name)
(format "%s(" method-name)))
(while method-args
(let ((method-arg-token (car method-args))
method-arg-type)
(when method-arg-token
(setq method-arg-type (semantic-token-type method-arg-token))
(setq method-sig (concat method-sig method-arg-type))))
(setq method-args (cdr method-args))
(if method-args (setq method-sig (concat method-sig ","))))
(setq method-sig (concat method-sig ")")))
(setq method-sig (format "%s()" method-name)))
(setq index
(append
index (list (cons method-sig method-pos)))))
(setq methods (cdr methods)))
;; Add a separator between method and field index
(if fields
(setq index (append index '(("-")))))
(setq fields (jde-sort-tokens fields))
(while fields
(let* ((field-token (car fields))
(field-name (semantic-token-name field-token))
(field-pos (semantic-token-start field-token)))
(if jde-imenu-include-signature
(setq field-name (concat (semantic-token-type field-token)
" " field-name)))
(setq index
(append
index (list (cons field-name field-pos)))))
(setq fields (cdr fields)))
(setq classes (jde-sort-tokens classes))
(while classes
(let* ((class-token (car classes))
(class-index (jde-imenu-index-class class-token)))
(setq index (append index class-index)))
(setq classes (cdr classes)))
index))
(defun jde-create-imenu-index ()
"Creates an imenu index for a Java source buffer.
This function uses the semantic bovinator to index the buffer."
;; The following clears the toplevel bovine cache for the current
;; buffer and forces *rescan* to work even if the current buffer has
;; not been modifified. This is needed to rebuild the "Classes"
;; imenu when customization has been changed.
(semantic-clear-toplevel-cache)
(let* ((tokens (semantic-bovinate-toplevel))
(packages (semantic-find-nonterminal-by-token 'package tokens))
(depends (semantic-find-nonterminal-by-token 'include tokens))
(classes (semantic-find-nonterminal-by-token 'type tokens))
depend-index
index)
(setq classes (jde-sort-tokens classes))
(while classes
(let* ((class-token (car classes))
(class-index (jde-imenu-index-class class-token)))
(setq index (append index class-index)))
(setq classes (cdr classes)))
(setq depends (jde-sort-tokens depends))
(while depends
(let* ((depend-token (car depends))
(depend-name (semantic-token-name depend-token))
(depend-pos (semantic-token-start depend-token)))
(setq depend-index (append depend-index (list (cons depend-name depend-pos)))))
(setq depends (cdr depends)))
(if depend-index
(setq index (append index (list (cons "imports" depend-index)))))
(setq packages (jde-sort-tokens packages))
(while packages
(let* ((package-token (car packages))
(package-name (semantic-token-name package-token))
(package-pos (semantic-token-start package-token)))
(setq index
(append
index
(list (cons (concat "package " package-name) package-pos)))))
(setq packages (cdr packages)))
index))
;;; jde-parse-imenu.el ends here