-
Notifications
You must be signed in to change notification settings - Fork 0
/
zasar-navigation.el
70 lines (62 loc) · 2.98 KB
/
zasar-navigation.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
;;; zAsar-navigation.el --- Navigation and Imenu Integration for zAsar Mode -*- lexical-binding: t; -*-
(require 'zAsar-parser)
(require 'zAsar-symbols)
(require 'zAsar-utils)
(defun zAsar-jump-to-reference-at-point ()
"Jump to the definition of the label or symbol under point."
(interactive)
(let* ((label (thing-at-point 'symbol t))
(clean-label (zAsar-clean-label label))
(label-entry (or (zAsar-find-label clean-label zAsar-labels)
(zAsar-find-label clean-label zAsar-project-labels)
(zAsar-find-symbol-by-address (zAsar-label-address-from-code)))))
(if label-entry
(progn
(find-file (plist-get label-entry :file))
(goto-char (plist-get label-entry :position)))
(message "Label or symbol '%s' not found." label))))
(defun zAsar-clean-label (label)
"Clean the LABEL by substituting dots with underscores if necessary."
(if (and label (string-prefix-p "." label))
(replace-regexp-in-string "^\\." "_" label)
label))
(defun zAsar-find-label (label-name label-list)
"Find a label by LABEL-NAME in LABEL-LIST."
(cl-find-if (lambda (lbl)
(string= (plist-get lbl :name) label-name))
label-list))
(defun zAsar-find-symbol-by-address (address)
"Find a symbol by ADDRESS in `zAsar-symbols`."
(cl-find-if (lambda (sym)
(= (plist-get sym :address) address))
zAsar-symbols))
(defun zAsar-label-address-from-code ()
"Extract address from code under point, e.g., #$7E000A."
(save-excursion
(when (re-search-backward "#\\$\$begin:math:text$[0-9A-Fa-f]+\\$end:math:text$" (line-beginning-position) t)
(string-to-number (match-string 1) 16))))
(defun zAsar-imenu-create-index ()
"Create an imenu index for zAsar-mode with hierarchical entries."
(let ((index '()))
;; Main Labels
(dolist (label (cl-remove-if-not (lambda (lbl)
(eq (plist-get lbl :type) 'main))
zAsar-labels))
(push (cons (plist-get label :name) (plist-get label :position)) index))
;; Pools with their associated functions
(dolist (pool (cl-remove-if-not (lambda (lbl)
(eq (plist-get lbl :type) 'pool))
zAsar-labels))
(let ((pool-name (zAsar-extract-pool-function-name (plist-get pool :name))))
(let ((functions (cl-remove-if-not (lambda (lbl)
(and (eq (plist-get lbl :type) 'main)
(string= (plist-get lbl :name) pool-name)))
zAsar-labels)))
(when functions
(push (cons (plist-get pool :name)
(mapcar (lambda (f) (cons (plist-get f :name) (plist-get f :position)))
functions))
index))))))
index)
(provide 'zAsar-navigation)
;;; zAsar-navigation.el ends here