blob: 2427362c6adb928c2f5c5930a2178c3a43c01cfc (
plain) (
tree)
|
|
;;; delphi-mode-ench.el
(require 'compile)
(require 'cl)
(pushnew '("^\\([-a-zA-Z0-9\\.\\/_~]+\\)(\\([0-9]+\\),\\([0-9]+\\))\s\\([Ff]atal:\\|[Nn]ote:\\|[Ww]arning:\\|[Ee]rror:\\)\s\\(.*$\\)" 1 2 3)
compilation-error-regexp-alist)
(setq auto-mode-alist (cons '("\\.pas" . delphi-mode) auto-mode-alist))
(setq delphi-unit-sections
'(implementation program library package))
(defconst delphi-method-types-regexp
"\\(procedure\\|function\\|constructor\\|destructor\\)"
"Regular expression for delphi method types")
(defconst delphi-method-signature-regexp
;; like mymethod(myvar1:varType; myvar2:varType=defaultvalue):TReturnType
(concat
"\\("
(concat
;; mymethod
"[_a-zA-Z][_a-zA-Z0-9]*"
;; (myvar1:varType; myvar2:varType=defaultvalue)
"\\((.*)\\)?"
;; : TReturnType
"\\( *: *[_a-zA-Z][_a-zA-Z0-9]*\\)?")
"\\)")
"Signature of a delphi method")
(defconst delphi-class-declaration-regexp
;;like TMyClass = class(TParentClass)
"\\(?:^\\|[ \t]\\)[ \t]*\\([_a-zA-Z][_a-zA-Z0-9]*\\) *= *class"
"Class declaration regexp")
(defvar imenu--function-name-regexp-delphi
(concat
"^[ \t]*\\(function\\|procedure\\|constructor\\|destructor\\)[ \t]+"
"\\([_a-zA-Z][_a-zA-Z0-9]*\\.\\)?"
"\\([_a-zA-Z][_a-zA-Z0-9]*\\)")
"Re to get function/procedure names in Delphi.")
(defun delphi-get-classes ()
(save-excursion
(goto-char (point-min))
(let ((classes '()))
(while (re-search-forward delphi-class-declaration-regexp nil t)
(push (match-string-no-properties 1) classes))
classes)))
(defun delphi-in-string (&optional pos)
(delphi-is (delphi-token-kind (delphi-token-at (point))) delphi-strings))
(defun delphi-in-comment (&optional pos)
(delphi-is (delphi-token-kind (delphi-token-at (point))) delphi-comments))
(defun delphi-is-definition (&optional pos)
(let ((class (save-excursion (delphi-in-class-definition))))
(if class class
(if pos (goto-char pos))
(re-search-forward "\\(begin\\|implementation\\)" nil t)
(let ((match (match-string-no-properties 1)))
(if (equal match "implementation") 't 'nil)))))
(defun delphi-in-class-definition (&optional pos)
(if pos (goto-char pos))
(let ((break 't) (class nil) (open-blocks 0) (max-negative 0))
(while (and break
(re-search-backward (concat "\\(?:\\(?:^\\|[^_a-zA-Z0-9]\\)"
"\\(end\\|record\\|case\\|begin\\)"
"\\(?:$\\|[^_a-zA-Z0-9]\\)"
"\\|\\(?:^\\|[ \t]\\)"
"\\([_a-zA-Z][_a-zA-Z0-9]*\\)"
"[ \t]*=[ \t]*class\\)") nil t))
(let ((result (match-string-no-properties 1)))
(if (not (or (delphi-in-string) (delphi-in-comment)))
(cond ((equal result "end")
(setq open-blocks (+ open-blocks 1)))
((or
(or
(equal result "record")
(equal result "case")) (equal result "begin"))
(setq open-blocks (- open-blocks 1))
(setq max-negative (min open-blocks max-negative)))
('t (setq break nil)
(if (= open-blocks max-negative)
(setq class (match-string-no-properties 2))))))))
class)
)
(defun imenu--create-delphi-index (&optional regexp)
(let ((index-alist '())
(progress-prev-pos 0)
(case-fold-search t))
(goto-char (point-min))
(imenu-progress-message progress-prev-pos 0)
(save-match-data
(while (re-search-forward
(or regexp imenu--function-name-regexp-delphi)
'nil 't)
(imenu-progress-message progress-prev-pos)
(let ((pos (save-excursion
(beginning-of-line)
(if imenu-use-markers (point-marker) (point))))
(function-name (match-string-no-properties 3))
(class-name (match-string-no-properties 2)))
(let ((class-def (save-excursion (delphi-is-definition pos))))
(let ((class-name (if class-name (substring class-name 0 -1) class-def))
(content (let ((sub-alist (if (not (equal class-def 't))
(assoc class-def index-alist)
index-alist)))
(if (not (equal class-def 'nil))
(cond ((assoc "Definition" sub-alist)
(let ((alist (reverse (assoc "Definition" sub-alist))))
(setcdr (assoc "Definition" sub-alist)
(cdr (reverse (push (cons function-name pos) alist)))))
nil)
(t
(list "Definition" (cons function-name pos))))
(cons function-name pos)))))
(if content (cond
((not (or (equal class-name 'nil) (equal class-name 't)))
(cond ((assoc class-name index-alist)
(let ((alist (reverse (assoc class-name index-alist))))
(setcdr (assoc class-name index-alist)
(cdr (reverse (push content alist))))))
(t
(push (list class-name content) index-alist))
))
(t
(push content index-alist))))
)))))
(imenu-progress-message progress-prev-pos 100)
(setq index-alist (nreverse index-alist))
; remove class-name if only one class exists
(if (equal (length index-alist) 1) (setq index-alist (cdr (car index-alist))))
index-alist))
(defun delphi-method-jump ()
(cond ((save-excursion (delphi-is-definition)) (delphi-go-to-method-implementation))
('t (delphi-go-to-method-definition))))
(defun delphi-go-to-method-definition ()
"Move cursor to method definition of current edited method"
(interactive)
(re-search-backward (concat
delphi-method-types-regexp
" *"
"\\([_a-zA-Z][_a-zA-Z0-9]*\\)\\."
delphi-method-signature-regexp))
(let
((class (match-string 2))
(method (match-string 3)))
(message "%s %s" class method)
(re-search-backward (concat class " *= *class"))
(re-search-forward method)))
(defun delphi-go-to-method-implementation ()
"Move cursor to method implementation of method on current line"
(interactive)
(beginning-of-line)
(let (methodtype methodname class)
(re-search-forward (concat
delphi-method-types-regexp
" *"
delphi-method-signature-regexp))
(setq methodtype (match-string 1)
methodname (match-string 2))
(re-search-backward delphi-class-declaration-regexp)
(setq class (match-string 1))
(re-search-forward (concat methodtype " +" class "\\." methodname))))
(defun delphi-complete-method ()
"Create the method skeleton for method definition under cursor"
(interactive)
(beginning-of-line)
(let (methodtype methodname class)
(re-search-forward (concat
delphi-method-types-regexp
" *"
delphi-method-signature-regexp))
(setq methodtype (match-string 1)
methoddef (match-string 2))
(re-search-backward delphi-class-declaration-regexp)
(setq class (match-string 1))
(end-of-buffer)
(re-search-backward (concat
"\\("
delphi-method-types-regexp
" *"
class
"\\)\\|implementation"))
(next-line)
(re-search-forward (concat
delphi-method-types-regexp
"\\|\\(initialization\\|finalization\\|end\\.\\)"))
(previous-line)
(newline 2)
(previous-line 2)
(insert (concat methodtype " " class "." methoddef ";"))
(newline)
(insert "begin")
(newline 2)
(insert "end;")
(previous-line)))
;;key binding
(add-hook 'delphi-mode-hook
'(lambda ()
(define-key delphi-mode-map "\C-c\C-mi" 'delphi-go-to-method-implementation)
(define-key delphi-mode-map "\C-c\C-md" 'delphi-go-to-method-definition)
(define-key delphi-mode-map "\C-c\C-mc" 'delphi-complete-method)))
; hook if starting delphi-mode
(add-hook 'delphi-mode-hook
'(lambda ()
(setq comment-start "// ")
(require 'imenu)
(setq imenu-create-index-function
'imenu--create-delphi-index)
(imenu-add-menubar-index)))
|