diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2021-04-04 16:05:55 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2021-04-04 16:05:55 +0300 |
commit | fd0937138c16f77215d93285a3f79b07d2d3250f (patch) | |
tree | 0b11273fd2709eae78960152b079adaabc23d226 | |
parent | 52b63882560c34afaf0575233cbb815b0de5d87d (diff) | |
download | cflow-fd0937138c16f77215d93285a3f79b07d2d3250f.tar.gz cflow-fd0937138c16f77215d93285a3f79b07d2d3250f.tar.bz2 |
cflow-mode: functions for moving to the next and previous calls at the same level
* elisp/cflow-mode.el (cflow-next-function)
(cflow-prev-function): New functions.
-rw-r--r-- | elisp/cflow-mode.el | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/elisp/cflow-mode.el b/elisp/cflow-mode.el index 7456a9a..b53f4b0 100644 --- a/elisp/cflow-mode.el +++ b/elisp/cflow-mode.el @@ -55,6 +55,8 @@ (define-key cflow-mode-map "x" 'cflow-goto-expand) (define-key cflow-mode-map "E" 'cflow-edit-out-full) (define-key cflow-mode-map "c" 'cflow-find-caller) +(define-key cflow-mode-map "n" 'cflow-next-function) +(define-key cflow-mode-map "p" 'cflow-prev-function) (define-key cflow-mode-map [menu-bar] (make-sparse-keymap)) @@ -171,23 +173,22 @@ (defun cflow-find-caller () "Go to the caller of the current function" (interactive) - (let ((num (cond - ((save-excursion - (beginning-of-line) - (cond - ((looking-at "^\\( +\\)\\w") - (let ((indent (- (match-end 1) (match-beginning 1)))) - (re-search-backward (format "^ \\{,%d\\}\\w" (- indent 1)) nil t) - (- (match-end 0) 1))) - ((looking-at "^\\(\\s-+\\)\\w") - (let ((indent (- (match-end 1) (match-beginning 1)))) - (catch 'found - (while (re-search-backward "^\\(\\s-*\\)\\w" nil t) - (if (< (- (match-end 1) (match-beginning 1)) indent) - (throw 'found (match-end 1)))) - 0))) - (t - 0))))))) + (let ((num (save-excursion + (beginning-of-line) + (cond + ((looking-at "^\\( +\\)\\w") + (let ((indent (- (match-end 1) (match-beginning 1)))) + (re-search-backward (format "^ \\{,%d\\}\\w" (- indent 1)) nil t) + (- (match-end 0) 1))) + ((looking-at "^\\(\\s-+\\)\\w") + (let ((indent (- (match-end 1) (match-beginning 1)))) + (catch 'found + (while (re-search-backward "^\\(\\s-*\\)\\w" nil t) + (if (< (- (match-end 1) (match-beginning 1)) indent) + (throw 'found (match-end 1)))) + 0))) + (t + 0))))) (cond ((> num 0) (push-mark) @@ -195,6 +196,46 @@ (t (error "At top-level function"))))) +(defun cflow-goto-sibling (count advance) + (let ((pos (save-excursion + (beginning-of-line) + (cond + ((looking-at "^\\( +\\)\\w") + (let ((indent (- (match-end 1) (match-beginning 1))) + (rx (format "^%s\\w" (match-string 0)))) + (let ((pos nil) + (stop (if (> advance 0) 'eobp 'bobp))) + (while (not pos) + (if (funcall stop) + (error "No more calls")) + (forward-line advance) + (cond + ((looking-at "^\\( +\\)\\w") + (let ((l (- (match-end 1) (match-beginning 1)))) + (cond + ((= l indent) + (setq count (1- count)) + (if (= count 0) + (setq pos (- (match-end 0) 1)))) + ((< l indent) + (error "No more calls"))))))) + pos))) + ((looking-at "^\\w") + (error "At top-level function")) + (t + (error "Not at function")))))) + (goto-char pos))) + +(defun cflow-next-function (&optional arg) + "Go to the next function at this nesting level" + (interactive "P") + (cflow-goto-sibling (or arg 1) 1)) + +(defun cflow-prev-function (&optional arg) + "Go to the previous function at this nesting level" + (interactive "P") + (cflow-goto-sibling (or arg 1) -1)) + (defvar cflow-read-only) (defun cflow-edit-out-full () |