From 1454457a85c9fb10145f45f80e1d3baa065017e5 Mon Sep 17 00:00:00 2001 From: Gonzalo Larumbe Date: Sun, 7 Apr 2024 15:52:54 +0200 Subject: [PATCH] Add point-inside-block tree-sitter implementation --- test-hdl | 2 +- verilog-ext-hierarchy.el | 1 - verilog-ext-nav.el | 3 +- verilog-ext-tags.el | 1 - verilog-ext-utils.el | 171 ++++++++++++++++++++++----------------- 5 files changed, 99 insertions(+), 79 deletions(-) diff --git a/test-hdl b/test-hdl index 95c5695..6862088 160000 --- a/test-hdl +++ b/test-hdl @@ -1 +1 @@ -Subproject commit 95c569540c81e42c308cede5385749fcdeb7500e +Subproject commit 6862088f52611116d2809869c96d94fe78bd3120 diff --git a/verilog-ext-hierarchy.el b/verilog-ext-hierarchy.el index 119d480..c96d4a2 100644 --- a/verilog-ext-hierarchy.el +++ b/verilog-ext-hierarchy.el @@ -29,7 +29,6 @@ (require 'tree-widget) (require 'async) (require 'verilog-ext-nav) -(require 'verilog-ts-mode) (defgroup verilog-ext-hierarchy nil "Verilog-ext hierarchy." diff --git a/verilog-ext-nav.el b/verilog-ext-nav.el index b821fd2..ebfdde1 100644 --- a/verilog-ext-nav.el +++ b/verilog-ext-nav.el @@ -28,7 +28,6 @@ (require 'ripgrep) (require 'xref) (require 'verilog-ext-utils) -(require 'verilog-ts-mode) ;;;; Custom @@ -646,9 +645,11 @@ moves the cursor to current instance if pointing at one." (defun verilog-ext-instance-at-point () "Return list with module and instance names if point is at an instance." (if (eq major-mode 'verilog-ts-mode) + ;; `verilog-ts-mode' based search (let ((node (verilog-ts-instance-at-point))) (when node `(,(verilog-ts--node-identifier-name node) ,(verilog-ts--node-instance-name node)))) + ;; `verilog-mode' based search (let ((point-cur (point)) point-instance-begin point-instance-end instance-type instance-name) (save-excursion diff --git a/verilog-ext-tags.el b/verilog-ext-tags.el index cb89c5f..09e5536 100644 --- a/verilog-ext-tags.el +++ b/verilog-ext-tags.el @@ -43,7 +43,6 @@ (require 'async) (require 'map) (require 'verilog-ext-nav) -(require 'verilog-ts-mode) (defgroup verilog-ext-tags nil diff --git a/verilog-ext-utils.el b/verilog-ext-utils.el index 0b915d8..1e82afb 100644 --- a/verilog-ext-utils.el +++ b/verilog-ext-utils.el @@ -25,6 +25,7 @@ ;;; Code: (require 'verilog-mode) +(require 'verilog-ts-mode) ;;;; Custom (defcustom verilog-ext-file-extension-re "\\.s?vh?\\'" @@ -540,81 +541,101 @@ Assumes that point is looking at a BLOCK type." (defun verilog-ext-point-inside-block (block) "Return non-nil if cursor is inside specified BLOCK type. Return alist with block type, name and boundaries." - (let ((pos (point)) - (re (cond ((eq block 'function) "\\<\\(function\\)\\>") - ((eq block 'task) "\\<\\(task\\)\\>") - ((eq block 'class) "\\<\\(class\\)\\>") - ((eq block 'module) "\\<\\(module\\)\\>") - ((eq block 'interface) "\\<\\(interface\\)\\>") - ((eq block 'package) "\\<\\(package\\)\\>") - ((eq block 'program) "\\<\\(program\\)\\>") - ((eq block 'always) "\\<\\(always\\(_ff\\|_comb\\|_latch\\)?\\)\\>") - ((eq block 'initial) "\\<\\(initial\\)\\>") - ((eq block 'final) "\\<\\(final\\)\\>") - ((eq block 'generate) "\\<\\(generate\\)\\>") - ((eq block 'begin-end) "\\<\\(begin\\|end\\)\\>") - (t (error "Incorrect block argument")))) - block-boundaries block-beg-point block-end-point block-type block-name) - (save-match-data - (save-excursion - (when (and (verilog-re-search-backward re nil t) - (cond (;; Classes - (equal block 'class) - (if (verilog-ext-class-declaration-is-typedef-p) - ;; Try again if looking at a typedef class declaration - (verilog-ext-point-inside-block 'class) - ;; Else do the same as for function/tasks and top blocks - (setq block-type (match-string-no-properties 1)) - (looking-at verilog-ext-class-re) - (setq block-name (match-string-no-properties 3)))) - ;; Function/tasks and top blocks - ((member block '(function task module interface package program)) - (and (save-excursion ; Exclude external func/tasks declarations - (save-match-data - (verilog-beg-of-statement) - (not (looking-at "\\")))) - (setq block-type (match-string-no-properties 1)) - (or (looking-at verilog-ext-function-re) - (looking-at verilog-ext-task-re) - (looking-at verilog-ext-top-re)) - (setq block-name (match-string-no-properties 3)))) - ;; Procedural: always, initial and final - ((member block '(always initial final)) - (if (equal block 'always) - (setq block-type "always") - (setq block-type (match-string-no-properties 1))) - (save-excursion ; Get block name - (verilog-ext-skip-identifier-forward) - (verilog-ext-forward-syntactic-ws) - (setq block-name (buffer-substring-no-properties (point) (line-end-position))))) - ;; Generate - ((equal block 'generate) - (and (setq block-type (match-string-no-properties 1)) - (save-excursion ; Get block name - (verilog-ext-skip-identifier-forward) - (verilog-ext-forward-syntactic-ws) - (setq block-name (buffer-substring-no-properties (point) (line-end-position)))))) - ;; Procedural block (begin-end) - ((equal block 'begin-end) - (verilog-ext-while-t (string= (match-string-no-properties 0) "end") - (verilog-ext-backward-sexp) - (verilog-re-search-backward re nil t)) - (setq block-type "begin-end") - (setq block-name "")) ; Return non-nil for and condition - ;; Default invalid condition - (t - (error "Invalid condition")))) - ;; Set boundaries and return value - (setq block-boundaries (verilog-ext-get-block-boundaries block)) - (setq block-beg-point (car block-boundaries)) - (setq block-end-point (cdr block-boundaries))) - (when (and block-beg-point block-end-point - (>= pos block-beg-point) - (< pos block-end-point)) - `((type . ,block-type) - (name . ,block-name) - (beg-point . ,block-beg-point) - (end-point . ,block-end-point))))))) + (if (eq major-mode 'verilog-ts-mode) + ;; `verilog-ts-mode' based search + (let* ((re (cond ((eq block 'function) "\\<\\(function_declaration\\)\\>") + ((eq block 'task) "\\<\\(task_declaration\\)\\>") + ((eq block 'class) "\\<\\(class_declaration\\)\\>") + ((eq block 'module) "\\<\\(module_declaration\\)\\>") + ((eq block 'interface) "\\<\\(interface_declaration\\)\\>") + ((eq block 'package) "\\<\\(package_declaration\\)\\>") + ((eq block 'program) "\\<\\(program_declaration\\)\\>") + ((eq block 'always) "\\<\\(always_construct\\)\\>") + ((eq block 'initial) "\\<\\(initial_construct\\)\\>") + ((eq block 'final) "\\<\\(final_construct\\)\\>") + ((eq block 'generate) "\\<\\(generate_region\\)\\>"))) + (node (verilog-ts--node-has-parent-recursive (verilog-ts--node-at-point) re))) + (when node + `((type . ,(verilog-ts--node-identifier-type node)) + (name . ,(verilog-ts--node-identifier-name node)) + (beg-point . ,(treesit-node-start node)) + (end-point . ,(treesit-node-end node))))) + ;; `verilog-mode' based search + (let ((pos (point)) + (re (cond ((eq block 'function) "\\<\\(function\\)\\>") + ((eq block 'task) "\\<\\(task\\)\\>") + ((eq block 'class) "\\<\\(class\\)\\>") + ((eq block 'module) "\\<\\(module\\)\\>") + ((eq block 'interface) "\\<\\(interface\\)\\>") + ((eq block 'package) "\\<\\(package\\)\\>") + ((eq block 'program) "\\<\\(program\\)\\>") + ((eq block 'always) "\\<\\(always\\(_ff\\|_comb\\|_latch\\)?\\)\\>") + ((eq block 'initial) "\\<\\(initial\\)\\>") + ((eq block 'final) "\\<\\(final\\)\\>") + ((eq block 'generate) "\\<\\(generate\\)\\>") + ((eq block 'begin-end) "\\<\\(begin\\|end\\)\\>") + (t (error "Incorrect block argument")))) + block-boundaries block-beg-point block-end-point block-type block-name) + (save-match-data + (save-excursion + (when (and (verilog-re-search-backward re nil t) + (cond (;; Classes + (equal block 'class) + (if (verilog-ext-class-declaration-is-typedef-p) + ;; Try again if looking at a typedef class declaration + (verilog-ext-point-inside-block 'class) + ;; Else do the same as for function/tasks and top blocks + (setq block-type (match-string-no-properties 1)) + (looking-at verilog-ext-class-re) + (setq block-name (match-string-no-properties 3)))) + ;; Function/tasks and top blocks + ((member block '(function task module interface package program)) + (and (save-excursion ; Exclude external func/tasks declarations + (save-match-data + (verilog-beg-of-statement) + (not (looking-at "\\")))) + (setq block-type (match-string-no-properties 1)) + (or (looking-at verilog-ext-function-re) + (looking-at verilog-ext-task-re) + (looking-at verilog-ext-top-re)) + (setq block-name (match-string-no-properties 3)))) + ;; Procedural: always, initial and final + ((member block '(always initial final)) + (if (equal block 'always) + (setq block-type "always") + (setq block-type (match-string-no-properties 1))) + (save-excursion ; Get block name + (verilog-ext-skip-identifier-forward) + (verilog-ext-forward-syntactic-ws) + (setq block-name (buffer-substring-no-properties (point) (line-end-position))))) + ;; Generate + ((equal block 'generate) + (and (setq block-type (match-string-no-properties 1)) + (save-excursion ; Get block name + (verilog-ext-skip-identifier-forward) + (verilog-ext-forward-syntactic-ws) + (setq block-name (buffer-substring-no-properties (point) (line-end-position)))))) + ;; Procedural block (begin-end) + ((equal block 'begin-end) + (verilog-ext-while-t (string= (match-string-no-properties 0) "end") + (verilog-ext-backward-sexp) + (verilog-re-search-backward re nil t)) + (setq block-type "begin-end") + (setq block-name "")) ; Return non-nil for and condition + ;; Default invalid condition + (t + (error "Invalid condition")))) + ;; Set boundaries and return value + (setq block-boundaries (verilog-ext-get-block-boundaries block)) + (setq block-beg-point (car block-boundaries)) + (setq block-end-point (cdr block-boundaries))) + (when (and block-beg-point block-end-point + (>= pos block-beg-point) + (< pos block-end-point)) + `((type . ,block-type) + (name . ,block-name) + (beg-point . ,block-beg-point) + (end-point . ,block-end-point)))))))) (defconst verilog-ext-block-at-point-all-re (eval-when-compile