Skip to content

Commit

Permalink
WIP: Add first sketch of navigation features to ts-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
gmlarumbe committed Aug 14, 2023
1 parent 4a908e8 commit 3fe7e26
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 66 deletions.
16 changes: 3 additions & 13 deletions misc/notes.org
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,6 @@ DANGER: Still very inefficient, removed funcall in

* Tree-sitter dev
** Pending
*** navigation
- Probably it is better to do it inside verilog-ts-mode, as code won't probably be reused
- [ ] verilog-ext-nav-beg-of-defun-dwim
- [ ] verilog-ext-nav-end-of-defun-dwim
- [ ] verilog-ext-nav-down-dwim
- [ ] verilog-ext-nav-up-dwim
- [ ] verilog-ext-nav-prev-dwim
- [ ] verilog-ext-nav-next-dwim
- [ ] verilog-ext-jump-to-module-at-point-def
- [ ] verilog-ext-jump-to-module-at-point-ref
- [ ] verilog-ext-workspace-jump-to-parent-module

*** xref
- [ ] Implement tags/refs gathering in workspace
- `verilog-ext-workspace-get-tags points' to `verilog-ext-workspace-get-tags'
Expand All @@ -390,11 +378,13 @@ DANGER: Still very inefficient, removed funcall in
- [ ] Include verilog-keywords?
- (no need to include in company-keywords)


*** Tests
- [ ] Refactor/reorganize and prepare to split into separate repo for verilog-ts-mode

** Implemented
*** navigation
- [ ] Finish implementing, test, check ideas, refactor code

*** beautify
- [ ] What about the equivalents of verilog-pretty-declarations and verilog-pretty-expressions?
- [ ] Finish implementation so that all tests are passing
Expand Down
153 changes: 100 additions & 53 deletions ts-mode/verilog-ts-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -1251,126 +1251,166 @@ Return nil if there is no name or if NODE is not a defun node."

(defun verilog-ts-find-function-task (&optional bwd)
"Search for a Verilog function/task declaration or definition."
;; TODO: Maybe use `treesit-search-forward-goto'?
(let ((node (treesit-search-forward (verilog-ts--node-at-point) "\\(task\\|function\\)_declaration" bwd)))
(if bwd
(goto-char (treesit-node-start node))
(goto-char (treesit-node-end node)))))
;; TODO: Still does not work with static/extern methods (check uvm_component.svh)
(treesit-search-forward-goto (verilog-ts--node-at-point) "\\(task\\|function\\)_declaration" t bwd))

(defun verilog-ts-find-function-task-fwd ()
"Search forward for a Verilog function/task declaration or definition."
(verilog-ts-find-function-task))

(defun verilog-ts-find-function-task-bwd (&optional)
(defun verilog-ts-find-function-task-bwd ()
"Search backward for a Verilog function/task declaration or definition."
(verilog-ts-find-function-task :bwd))

(defun verilog-ts-find-class (&optional limit bwd interactive-p)
(defun verilog-ts-find-class (&optional bwd)
"Search for a class declaration."
)
(treesit-search-forward-goto (verilog-ts--node-at-point) "class_declaration" t bwd))

(defun verilog-ts-find-class-fwd (&optional limit)
"Search forward for a Verilog class declaration.
Bound search to LIMIT in case optional argument is non-nil."
)
(defun verilog-ts-find-class-fwd ()
"Search forward for a Verilog class declaration."
(verilog-ts-find-class))

(defun verilog-ts-find-class-bwd (&optional limit)
"Search backward for a Verilog class declaration.
Bound search to LIMIT in case optional argument is non-nil."
)
(defun verilog-ts-find-class-bwd ()
"Search backward for a Verilog class declaration."
(verilog-ts-find-class :bwd))

(defun verilog-ts-find-function-task-class (&optional limit bwd interactive-p)
(defun verilog-ts-find-function-task-class (&optional bwd)
"Find closest declaration of a function/task/class."
)
(treesit-search-forward-goto (verilog-ts--node-at-point) "\\(task\\|function\\|class\\)_declaration" t bwd))

(defun verilog-ts-find-function-task-class-fwd (&optional limit)
"Search forward for a Verilog function/task/class declaration.
Bound search to LIMIT in case optional argument is non-nil."
)
(defun verilog-ts-find-function-task-class-fwd ()
"Search forward for a Verilog function/task/class declaration."
(verilog-ts-find-function-task-class))

(defun verilog-ts-find-function-task-class-bwd (&optional limit)
"Search backward for a Verilog function/task/class declaration.
Bound search to LIMIT in case optional argument is non-nil."
)
(defun verilog-ts-find-function-task-class-bwd ()
"Search backward for a Verilog function/task/class declaration."
(verilog-ts-find-function-task-class :bwd))

(defun verilog-ts-find-block (&optional bwd interactive-p)
(defun verilog-ts-find-block (&optional bwd)
"Search for a Verilog block regexp."
)
(treesit-search-forward-goto (verilog-ts--node-at-point) verilog-ts-block-at-point-re t bwd))

(defun verilog-ts-find-block-fwd ()
"Search forward for a Verilog block regexp."
)
(verilog-ts-find-block))

(defun verilog-ts-find-block-bwd ()
"Search backwards for a Verilog block regexp."
)
(verilog-ts-find-block :bwd))

(defun verilog-ts-find-module-instance (&optional bwd)
"Search for a Verilog module/instance."
(treesit-search-forward-goto (verilog-ts--node-at-point) "\\(module\\|interface\\)_instantiation" t bwd))

(defun verilog-ts-find-module-instance-fwd (&optional limit)
(defun verilog-ts-find-module-instance-fwd ()
"Search forwards for a Verilog module/instance."
)
(verilog-ts-find-module-instance))

(defun verilog-ts-find-module-instance-bwd (&optional limit)
(defun verilog-ts-find-module-instance-bwd ()
"Search backwards for a Verilog module/instance."
)

;; TODO: Already implemented as `verilog-ts-module-at-point'
(defun verilog-ts-instance-at-point ()
"Return list with module and instance names if point is at an instance."
)
(verilog-ts-find-module-instance :bwd))

;; TODO: Do something for when point is in "begin", like (string=
;; (verilog-ts--node-at-point) "begin"), then move back point if its not
;; beginning of buffer to search for new node!
(defun verilog-ts-goto-begin-up ()
"Move point to start position of current begin."
)

(let* ((begin-node (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) "seq_block"))
(begin-pos (treesit-node-start begin-node)))
(when begin-pos
(goto-char begin-pos))))

;; TODO: Doesn't work. Don't know how to make it work.
;; `verilog-ts--node-has-child-recursive' doesn't find anything on current node
;; Also tried with: (treesit-search-subtree (verilog-ts--node-at-point) "seq_block") but no results
;; @ /home/gonz/.emacs.d/straight/repos/verilog-ext/test/files/common/uvm_component.svh:1503
(defun verilog-ts-goto-begin-down ()
"Move point to start position of next nested begin."
)
(let* ((begin-node (verilog-ts--node-has-child-recursive (verilog-ts--node-at-point) "seq_block"))
(begin-pos (treesit-node-start begin-node)))
(when begin-pos
(goto-char begin-pos))))

(defun verilog-ts-defun-level-up ()
"Move up one defun-level.
Return alist with defun data if point moved to a higher block."
)
"Move up one defun-level."
(let* ((node (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) "\\(function\\|task\\|class\\(_constructor\\)?\\|package\\|module\\)_declaration"))
(pos (treesit-node-start node)))
(when pos
(goto-char pos))))

;; TODO: Not sure how to implement it
(defun verilog-ts-defun-level-down ()
"Move down one defun-level.
Return alist with defun data if point moved to a lower block."
"Move down one defun-level."

)

;;;; Dwim
(defun verilog-ts-nav-down-dwim ()
"Context based search downwards.
If in a module/interface look for instantiations.
Otherwise look for functions/tasks."
)
(interactive)
(if (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) "\\(module\\|interface\\)_declaration")
(verilog-ts-find-module-instance-fwd)
(verilog-ts-find-function-task-class-fwd)))

(defun verilog-ts-nav-up-dwim ()
"Context based search upwards.
If in a module/interface look for instantiations.
Otherwise look for functions/tasks."
)
(interactive)
(if (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) "\\(module\\|interface\\)_declaration")
(verilog-ts-find-module-instance-bwd)
(verilog-ts-find-function-task-class-bwd)))

;; TODO: Are these necessary if ussing `beginning-of-defun' or `end-of-defun' with `verilog-ts--defun-type-regexp'?
;; These can be tweaked for something more specific.
;; TODO: Update documentation
(defconst verilog-ts-nav-beg-of-defun-dwim-inside-module-re
(regexp-opt '("module_declaration"
"interface_declaration"
"always_construct"
"initial_construct"
"final_construct"
"generate_region")))
(defconst verilog-ts-nav-beg-of-defun-dwim-outside-module-re
(regexp-opt '("function_declaration"
"task_declaration"
"class_declaration"
"package_declaration"
"program_declaration")))

(defun verilog-ts-nav-beg-of-defun-dwim ()
"Context based search upwards.
If in a module/interface look for instantiations.
Otherwise look for functions/tasks."
)
pOtherwise look for functions/tasks."
(interactive)
(if (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) "\\(module\\|interface\\)_declaration")
(treesit-search-forward-goto (verilog-ts--node-at-point) verilog-ts-nav-beg-of-defun-dwim-inside-module-re t :bwd)
(treesit-search-forward-goto (verilog-ts--node-at-point) verilog-ts-nav-beg-of-defun-dwim-outside-module-re t :bwd)))

(defun verilog-ts-nav-end-of-defun-dwim ()
"Context based search upwards.
If in a module/interface look for instantiations.
Otherwise look for functions/tasks."
)
(interactive)
(if (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) "\\(module\\|interface\\)_declaration")
(treesit-search-forward-goto (verilog-ts--node-at-point) verilog-ts-nav-beg-of-defun-dwim-inside-module-re t)
(treesit-search-forward-goto (verilog-ts--node-at-point) verilog-ts-nav-beg-of-defun-dwim-outside-module-re t)))

;; TODO: Reformulate these. See if something better can be done, something more useful
(defun verilog-ts-nav-next-dwim ()
"Context based search next.
If in a parenthesis, go to closing parenthesis (Elisp like).
Otherwise move to next paragraph."
(interactive)
)

(defun verilog-ts-nav-prev-dwim ()
"Context based search previous.
If in a parenthesis, go to opening parenthesis (Elisp like).
Otherwise move to previous paragraph."
(interactive)
)


Expand Down Expand Up @@ -1524,10 +1564,17 @@ Complete with keywords and current buffer identifiers."
:doc "Keymap for SystemVerilog language with tree-sitter"
:parent verilog-mode-map
"TAB" #'indent-for-tab-command
"C-M-a" #'verilog-ts-nav-beg-of-defun-dwim
"C-M-e" #'verilog-ts-nav-end-of-defun-dwim
"C-M-f" #'verilog-ts-forward-sexp
"C-M-b" #'verilog-ts-backward-sexp
"C-M-d" #'verilog-ts-nav-down-dwim
"C-M-u" #'verilog-ts-nav-up-dwim
"C-M-p" #'verilog-ts-nav-prev-dwim
"C-M-n" #'verilog-ts-nav-next-dwim
"C-c TAB" #'verilog-ts-pretty-declarations
"C-c C-o" #'verilog-ts-pretty-expr)
"C-c C-o" #'verilog-ts-pretty-expr
)

(defvar verilog-ts-mode-syntax-table
(let ((table (make-syntax-table)))
Expand Down

0 comments on commit 3fe7e26

Please sign in to comment.