imenu parser for emacs delphi-mode

improve the one found on


1. support 'record', 'class' and 'interface' as level 1 menu

2. methods show as submenu of class

3. correctly jump to the impl. part (ignore interface part)


FIXME: currently not work if no 'interface/implementation'


keyword: emacs, delphi, freepascal, imenu


;; based on code from

(defvar imenu--function-name-regexp-delphi
    "^[ \t]*\\(function\\|procedure\\|constructor\\|destructor\\)[ \t]+"
    "\\([_a-zA-Z][_a-zA-Z0-9]*\\.\\)?"   ; class?
  "Re to get function/procedure names in Delphi.")

(defvar imenu--type-name-regexp-delphi
   (concat "^[ \t]*\\([a-zA-Z0-9]*\\)[ \t]*=[ \t]*\\(class\\|record\\|interface\\)"
   "regexp to get class/record namesin Delphi.")

(defun imenu--create-delphi-index-enh (&optional regexp)
  (let ((index-alist '())
        (progress-prev-pos 0)
        (case-fold-search t))
    (goto-char (point-min))
    (imenu-progress-message progress-prev-pos 0)
    ;;first, scan interface part for types
    (if (eq nil (re-search-forward "interface" nil t)) 
        (goto-char (point-min))
      (progn    ;; if we have interface..implementaion
         (while (re-search-forward
                 (or regexp imenu--type-name-regexp-delphi)
                 nil t)
           (imenu-progress-message progress-prev-pos)
           (let ((pos (save-excursion
                        (if imenu-use-markers (point-marker) (point))))
                  (sub-alist '())
                 (type-name (match-string-no-properties 1)))
                (push (cons "(declaration)" pos) sub-alist)
                (push (cons (format "%s." type-name) sub-alist) index-alist))))
    ;;now, scan implementation part for methods (and other functions)
    (goto-char (point-min))
    (if (eq nil (re-search-forward "implementation" nil t)) ;;advance to the interface part
        (goto-char (point-min))    
        (while (re-search-forward
                (or regexp imenu--function-name-regexp-delphi)
                nil t)
          (imenu-progress-message progress-prev-pos)
          (let* ((pos (save-excursion
                        (if imenu-use-markers (point-marker) (point))))
                 (class-name (match-string-no-properties 2))
                 (function-name (match-string-no-properties 3))
                 (   tn>lass="menu" href="ho-prop (cons "(declaward "interface" nil t)) 
ass="menu" href=" htn>id="blog_nav_contacnterfainterface..imppd	
                 ( )int         ( )"blog_nav_contacnterfainterface..imppds 2))
      )"blog_nav_contacnterfainterfacss-message progreeeeeeeeeeee tn>lass="mestring-no-propertsetcdr s 3))
   "menu""menus 2))
       sh (c(cdr s 3)>

2rs (point-marker) ( (point-marker)rs (point-m (poo-char (point-min)) (imenu-progress-m10essag(nogr tn>lass="menu /recoadd-hook '">imenu par-hook(point#'(lambda ( (point-tchquie t'iard "interfatsetq s

(t'iard - s

by )"blog_ntsetq lphi.") tn>la ("blog_n#'esin Delphi.") (defun imenu)"blog_ntesin Dadd-sin barefun irs (p y"> info_bript!--done--> <"bloP"> Ci."gory/h1> y"> info">  phi-mode next_rogr/h1>

"potyp@ )) /hlogs-04-07 21:49ve the on'class="postTitle2" href="http:/'www.cnblogwiki 阅读( _t="u_couin">...)  ( _cripre-_couin">...) ve the o menu" rel="nofollow" hreppliP"> s.aspx?y"> St2278524og_nav_admin" cl>编辑wiki e the one#"priclick="AddToWz(2278524);hliurn hjax=f">收藏wiki.o