Skip to content

Commit df3a386

Browse files
authored
Update call-graph.el
1 parent 2d8d2c0 commit df3a386

1 file changed

Lines changed: 62 additions & 63 deletions

File tree

call-graph.el

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
;;; call-graph.el --- Generate call graph for c/c++ functions -*- lexical-binding: t; -*-
22

3-
;; Copyright (C) 2018-2025 by Huming Chen
3+
;; Copyright (C) 2018-2026 by Huming Chen
44

55
;; Author: Huming Chen <chenhuming@gmail.com>
66
;; URL: https://github.com/beacoder/call-graph
7-
;; Version: 1.0.5
7+
;; Version: 1.0.6
88
;; Created: 2018-01-07
99
;; Keywords: programming, convenience
1010
;; Package-Requires: ((emacs "28.1") (tree-mode "1.0.0") (ivy "0.10.0") (beacon "1.3.4"))
@@ -58,16 +58,16 @@
5858
;; 1.0.3 Flash visited file location with beacon.
5959
;; 1.0.4 Disable arg number check for now.
6060
;; 1.0.5 Use Git as default search backend.
61+
;; 1.0.6 Fix all kinds of stability issue.
6162

6263
;;; Code:
6364

64-
(require 'beacon)
6565
(require 'cc-mode)
6666
(require 'cl-lib)
6767
(require 'desktop)
6868
(require 'hierarchy)
69-
(require 'ivy)
7069
(require 'map)
70+
(require 'pulse)
7171
(require 'seq)
7272
(require 'subr-x)
7373
(require 'tree-mode)
@@ -79,7 +79,7 @@
7979

8080
(defgroup call-graph nil
8181
"Customization support for the `call-graph'."
82-
:version "0.1.0"
82+
:version "1.0.5"
8383
:group 'applications)
8484

8585
(defcustom call-graph-initial-max-depth 2
@@ -210,8 +210,6 @@ When FUNC with args, match number of args as well."
210210
(short-func (call-graph--extract-method-name func)))
211211
(let ((location (concat file-name ":" line-nb-str))
212212
(caller nil)
213-
(nb-of-func-args (call-graph--number-of-args (symbol-name func)))
214-
(nb-of-reference-args nil)
215213
(short-fun-str (symbol-name short-func))
216214
(is-valid-reference t))
217215
(with-temp-buffer
@@ -225,7 +223,7 @@ When FUNC with args, match number of args as well."
225223
(forward-line (1- line-nb))
226224
(call-graph--setq-local-mode-hook-nil data-mode)
227225
(setq imenu--index-alist nil)
228-
(funcall data-mode)
226+
(delay-mode-hooks (funcall data-mode))
229227
(setq-local which-func-cleanup-function nil)
230228
(which-function-mode t)
231229
;; make sure reference contains a function call
@@ -240,14 +238,6 @@ When FUNC with args, match number of args as well."
240238
(setq is-valid-reference nil))))))
241239
(when is-valid-reference
242240
(setq caller (call-graph--which-function))
243-
;; disable arg number check for now
244-
;; (setq nb-of-reference-args (call-graph--scan-func-args short-fun-str))
245-
;; (if (and nb-of-func-args nb-of-reference-args)
246-
;; ;; TODO: check if func has args with default value
247-
;; ;; if not, we should use exact match here.
248-
;; (when (= nb-of-reference-args nb-of-func-args) ; check func-args matches references-args
249-
;; (setq caller (call-graph--which-function)))
250-
;; (setq caller (call-graph--which-function)))
251241
(unless call-graph-display-func-args
252242
(setq caller (call-graph--extract-namespace-and-method caller)))))
253243
(when caller
@@ -375,10 +365,7 @@ If there's a string at point, use it instead of prompt."
375365
(defun call-graph--trim-string (string)
376366
"Remove white spaces in beginning and ending of STRING.
377367
White space here is any of: space, tab, Emacs newline (line feed, ASCII 10)."
378-
(replace-regexp-in-string
379-
"\\`[ \t\n]*" ""
380-
(replace-regexp-in-string
381-
"[ \t\n]*\\'" "" string)))
368+
(string-trim string))
382369

383370
(defun call-graph--extract-namespace-and-method (full-func)
384371
"Given FULL-FUNC, return a namespace and method.
@@ -433,19 +420,17 @@ e.g: class::method(arg1, arg2) => class::method."
433420
(delete-region (point-min) (point))
434421
(goto-char (point-max))
435422
(delete-region (search-backward ")" nil t) (point-max))
436-
;; (message (buffer-string))
437423
(save-match-data ;; save previous match-data and restore later
438424
;; Map over the elements of call-graph--pattern-replace-alist
439-
;; (pattern, replace)
425+
;; Replace nested constructs iteratively until no more matches
440426
(dolist (pair call-graph--pattern-replace-alist)
441427
(let ((pattern (car pair))
442-
(replace (cadr pair)))
443-
(goto-char (point-min))
444-
(while (re-search-forward pattern nil t) ;; patttern exists
445-
(goto-char (point-min)) ;; start from begining
446-
(while (re-search-forward pattern nil t) ;; start replacing
447-
(replace-match replace t nil))
448-
(goto-char (point-min))))) ;; go over and do match-replace again
428+
(replace (cadr pair))
429+
(found t))
430+
(while found
431+
(goto-char (point-min))
432+
(setq found (re-search-forward pattern nil t))
433+
(when found (replace-match replace t nil)))))
449434
;; all noise cleared, count number of args
450435
(let ((args-string (call-graph--trim-string (buffer-string))))
451436
(cond ((string= "" args-string) 0)
@@ -511,7 +496,9 @@ e.g: class::method(arg1, arg2) => class::method."
511496
(find-file-read-only-other-window file-name)
512497
(with-no-warnings (goto-char (point-min))
513498
(forward-line (1- line-nb))
514-
(beacon-blink))
499+
(if (fboundp 'beacon-blink)
500+
(beacon-blink)
501+
(pulse-momentary-highlight-one-line (point))))
515502
(unless (member
516503
(buffer-name (window-buffer))
517504
(cl-loop for buffer in call-graph--previous-buffers
@@ -543,15 +530,16 @@ e.g: class::method(arg1, arg2) => class::method."
543530

544531
(defun call-graph--widget-depth-imp (tree &optional depth)
545532
"Return `DEPTH' of `TREE'."
546-
(if-let ((depth (or depth 0))
547-
(is-valid-tree (tree-widget-p tree))
548-
(is-tree-open (widget-get tree :open)))
549-
(progn
550-
;; (message "Depth of %s is %d" (widget-get (tree-widget-node tree) :tag) depth)
551-
(seq-max
552-
(seq-map (lambda (child) (call-graph--widget-depth-imp child (1+ depth)))
553-
(widget-get tree :children))))
554-
(if is-valid-tree depth (1- depth))))
533+
(let ((depth (or depth 0))
534+
(is-valid-tree (tree-widget-p tree)))
535+
(if (and is-valid-tree (widget-get tree :open))
536+
(let ((children (widget-get tree :children)))
537+
(if children
538+
(seq-max
539+
(seq-map (lambda (child) (call-graph--widget-depth-imp child (1+ depth)))
540+
children))
541+
depth))
542+
(if is-valid-tree depth (1- depth)))))
555543

556544
(defun call-graph--save-caller-cache ()
557545
"Save caller cache by saving `call-graph--caller-cache-alist' in .emacs.desktop file."
@@ -638,7 +626,7 @@ CALCULATE-DEPTH is used to calculate actual depth."
638626
(lambda (tree-item _)
639627
(let ((caller (symbol-name tree-item))
640628
(parent (or (hierarchy-parent call-graph--default-hierarchy tree-item) 'root-function)))
641-
(insert (propertize caller 'caller-name tree-item 'callee-name parent 'intangible t))))
629+
(insert (propertize caller 'caller-name tree-item 'callee-name parent))))
642630
(call-graph--get-buffer)))
643631
(when switch-buffer
644632
(switch-to-buffer-other-window hierarchy-buffer))
@@ -733,15 +721,20 @@ This works as a supplement, as `Global' sometimes fail to find caller."
733721
(defun call-graph--forward-to-text ()
734722
"Forward to text with callee-name."
735723
(let ((is-end-of-line (= (point) (line-end-position))))
736-
(while (not (get-text-property (point) 'callee-name))
724+
(while (and (not (get-text-property (point) 'callee-name))
725+
(if is-end-of-line
726+
(> (point) (point-min))
727+
(< (point) (point-max))))
737728
(if is-end-of-line (backward-char 1)
738729
(forward-char)))))
739730

740731
(defun call-graph--forward-to-button ()
741732
"Forward to button."
742733
(beginning-of-line)
743-
(while (not (get-char-property (point) 'button))
744-
(forward-char)))
734+
(let ((eol (line-end-position)))
735+
(while (and (not (get-char-property (point) 'button))
736+
(< (point) eol))
737+
(forward-char))))
745738

746739
(defun call-graph-goto-file-at-point ()
747740
"Go to the occurrence on the current line."
@@ -775,13 +768,16 @@ This works as a supplement, as `Global' sometimes fail to find caller."
775768
(concat (symbol-name (call-graph--extract-method-name callee)) " <- " (symbol-name caller))))
776769
(locations (call-graph--get-func-caller-location call-graph callee caller))
777770
(has-many (> (seq-length locations) 1)))
778-
(ivy-read "Caller Locations:" locations
779-
:action (lambda (func-location)
780-
(while (not (equal func-location (car locations)))
781-
(setq locations ; put selected location upfront
782-
(nconc (cdr locations) (cons (car locations) ()))))
783-
(setf (map-elt (call-graph--locations call-graph) func-caller-key) locations)
784-
(call-graph--visit-function func-location))))))
771+
(let ((visit-action (lambda (func-location)
772+
(while (not (equal func-location (car locations)))
773+
(setq locations ; put selected location upfront
774+
(nconc (cdr locations) (cons (car locations) ()))))
775+
(setf (map-elt (call-graph--locations call-graph) func-caller-key) locations)
776+
(call-graph--visit-function func-location))))
777+
(if (fboundp 'ivy-read)
778+
(ivy-read "Caller Locations:" locations :action visit-action)
779+
(let ((loc (completing-read "Caller Locations: " locations nil t)))
780+
(funcall visit-action loc)))))))
785781

786782
(defun call-graph-remove-single-caller ()
787783
"Within buffer <*call-graph*>, remove single caller at point."
@@ -877,13 +873,15 @@ With prefix argument, discard whole caller cache."
877873
(get-text-property (point) 'caller-name)))
878874
(unless origin-caller-name
879875
(beginning-of-line)
880-
(while (null (setq origin-caller-name
881-
(get-text-property (point) 'caller-name)))
876+
(while (and (null (setq origin-caller-name
877+
(get-text-property (point) 'caller-name)))
878+
(< (point) (line-end-position)))
882879
(forward-char)))
883880
(call-graph--create call-graph func depth)
884881
(goto-char origin-pos)
885-
(while (null (equal (get-text-property (point) 'caller-name)
886-
origin-caller-name))
882+
(while (and (null (equal (get-text-property (point) 'caller-name)
883+
origin-caller-name))
884+
(< (point) (point-max)))
887885
(forward-char))
888886
(call-graph--forward-to-button)
889887
(call-graph-display-file-at-point))))
@@ -898,14 +896,16 @@ With prefix argument, discard whole caller cache."
898896
list-of-parents parent-caller-name)
899897
(unless origin-caller-name
900898
(beginning-of-line)
901-
(while (null (setq origin-caller-name
902-
(get-text-property (point) 'caller-name)))
899+
(while (and (null (setq origin-caller-name
900+
(get-text-property (point) 'caller-name)))
901+
(< (point) (line-end-position)))
903902
(forward-char)))
904903
(cl-pushnew origin-caller-name list-of-parents)
905904
(while (null (tree-mode-root-linep))
906905
(tree-mode-goto-parent 1)
907-
(while (null (setq parent-caller-name
908-
(get-text-property (point) 'caller-name)))
906+
(while (and (null (setq parent-caller-name
907+
(get-text-property (point) 'caller-name)))
908+
(< (point) (line-end-position)))
909909
(forward-char))
910910
(cl-pushnew parent-caller-name list-of-parents))
911911
(goto-char (point-min))
@@ -916,8 +916,9 @@ With prefix argument, discard whole caller cache."
916916
(tree-mode-expand-level 1)))
917917
(goto-char origin-pos)
918918
(end-of-line)
919-
(while (null (member (get-text-property (point) 'caller-name)
920-
list-of-parents))
919+
(while (and (null (member (get-text-property (point) 'caller-name)
920+
list-of-parents))
921+
(> (point) (point-min)))
921922
(forward-char -1))
922923
(call-graph--forward-to-button)
923924
(call-graph-display-file-at-point)
@@ -955,15 +956,13 @@ With prefix argument, discard whole caller cache."
955956
buffer-read-only t
956957
show-trailing-whitespace nil)
957958
(setq-local line-move-visual t)
958-
(set (make-local-variable 'inhibit-point-motion-hooks) nil)
959959
(hack-dir-local-variables-non-file-buffer)
960960
(make-local-variable 'text-property-default-nonsticky)
961961
(push (cons 'keymap t) text-property-default-nonsticky)
962962
(when call-graph-display-file-other-window
963963
(add-hook 'widget-move-hook 'call-graph-display-file-at-point))
964964
(setq desktop-globals-to-save
965-
(add-to-list 'desktop-globals-to-save 'call-graph--caller-cache-alist))
966-
(run-mode-hooks))
965+
(add-to-list 'desktop-globals-to-save 'call-graph--caller-cache-alist)))
967966

968967
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
969968
;; Tests

0 commit comments

Comments
 (0)