@@ -2532,22 +2532,78 @@ See also `verilog-font-lock-extra-types'.")
2532
2532
(0 'verilog-font-lock-translate-off-face prepend))
2533
2533
)))))
2534
2534
2535
+ ;;
2536
+ ;; Comment detection and caching
2535
2537
2536
- (defun verilog-inside-comment-p ()
2537
- "Check if point inside a nested comment."
2538
+ (defvar verilog-scan-cache-preserving nil
2539
+ "If set, the specified buffer's comment properties are static.
2540
+ Buffer changes will be ignored. See `verilog-inside-comment-p'
2541
+ and `verilog-scan'.")
2542
+
2543
+ (defvar verilog-scan-cache-tick nil
2544
+ "Modification tick at which `verilog-scan' was last completed.")
2545
+ (make-variable-buffer-local 'verilog-scan-cache-tick)
2546
+
2547
+ (defun verilog-scan-region (beg end)
2548
+ "Parse comments between BEG and END for `verilog-inside-comment-p'."
2538
2549
(save-excursion
2539
- (let ((st-point (point)) hitbeg)
2540
- (or (search-backward "//" (verilog-get-beg-of-line) t)
2541
- (if (progn
2542
- ;; This is for tricky case //*, we keep searching if /*
2543
- ;; is proceeded by // on same line.
2544
- (while
2545
- (and (setq hitbeg (search-backward "/*" nil t))
2546
- (progn
2547
- (forward-char 1)
2548
- (search-backward "//" (verilog-get-beg-of-line) t))))
2549
- hitbeg)
2550
- (not (search-forward "*/" st-point t)))))))
2550
+ (let (pt)
2551
+ (goto-char beg)
2552
+ (while (< (point) end)
2553
+ (cond ((looking-at "//")
2554
+ (setq pt (point))
2555
+ (or (search-forward "\n" end t)
2556
+ (goto-char end))
2557
+ ;; "1+": The leading // or /* itself isn't considered as
2558
+ ;; being "inside" the comment, so that a (search-backward)
2559
+ ;; that lands at the start of the // won't mis-indicate
2560
+ ;; it's inside a comment
2561
+ (put-text-property (1+ pt) (point) 'v-cmt t))
2562
+ ((looking-at "/\\*")
2563
+ (setq pt (point))
2564
+ (or (search-forward "*/" end t)
2565
+ ;; No error - let later code indicate it so we can
2566
+ ;; use inside functions on-the-fly
2567
+ ;;(error "%s: Unmatched /* */, at char %d"
2568
+ ;; (verilog-point-text) (point))
2569
+ (goto-char end))
2570
+ (put-text-property (1+ pt) (point) 'v-cmt t))
2571
+ (t
2572
+ (forward-char 1)
2573
+ (if (search-forward "/" end t)
2574
+ (backward-char 1)
2575
+ (goto-char end))))))))
2576
+
2577
+ (defun verilog-scan ()
2578
+ "Parse the buffer, marking all comments with properties.
2579
+ Also assumes any text inserted since `verilog-scan-cache-tick'
2580
+ either is ok to parse as a non-comment, or `verilog-insert' was used."
2581
+ (unless (or (and verilog-scan-cache-preserving
2582
+ (eq verilog-scan-cache-preserving (current-buffer)))
2583
+ (equal verilog-scan-cache-tick (buffer-modified-tick)))
2584
+ (setq verilog-scan-cache-tick (buffer-modified-tick))
2585
+ (save-excursion
2586
+ (let ((was-mod (buffer-modified-p)))
2587
+ (remove-text-properties (point-min) (point-max) '(v-cmt nil))
2588
+ (verilog-scan-region (point-min) (point-max))
2589
+ (unless was-mod (set-buffer-modified-p nil))))))
2590
+
2591
+ (defun verilog-inside-comment-p ()
2592
+ "Check if point inside a comment.
2593
+ This may require a slow pre-parse of the buffer with `verilog-scan'
2594
+ to establish comment properties on all text."
2595
+ (verilog-scan)
2596
+ (get-text-property (point) 'v-cmt))
2597
+
2598
+ (defun verilog-insert (&rest stuff)
2599
+ "Insert arguments, tracking comments for `verilog-inside-comment-p'."
2600
+ (let ((pt (point)))
2601
+ (while stuff
2602
+ (insert (car stuff))
2603
+ (setq stuff (cdr stuff)))
2604
+ (verilog-scan-region pt (point))))
2605
+
2606
+ ;; More searching
2551
2607
2552
2608
(defun verilog-declaration-end ()
2553
2609
(search-forward ";"))
@@ -7908,7 +7964,7 @@ See `verilog-dir-exists-p' and `verilog-dir-files'.")
7908
7964
"Execute the BODY forms, allowing directory cache preservation within BODY.
7909
7965
This means that changes inside BODY made to the file system will not be
7910
7966
seen by the `verilog-dir-files' and related functions."
7911
- `(let ((verilog-dir-cache-preserving t )
7967
+ `(let ((verilog-dir-cache-preserving (current-buffer) )
7912
7968
verilog-dir-cache-list
7913
7969
verilog-dir-cache-lib-filenames)
7914
7970
(progn ,@body)))
@@ -8470,7 +8526,7 @@ format. Sort unless DONT-SORT. DIRECTION is normally wire/reg/output."
8470
8526
(equal "" (verilog-sig-comment sig)))
8471
8527
(insert "\n")
8472
8528
(indent-to (max 48 (+ indent-pt 40)))
8473
- (insert (concat "// " (verilog-sig-comment sig) "\n") ))
8529
+ (verilog- insert "// " (verilog-sig-comment sig) "\n"))
8474
8530
(setq sigs (cdr sigs)))))
8475
8531
8476
8532
(eval-when-compile
@@ -8484,7 +8540,7 @@ Presumes that any newlines end a list element."
8484
8540
(while stuff
8485
8541
(if need-indent (indent-to indent-pt))
8486
8542
(setq need-indent nil)
8487
- (insert (car stuff))
8543
+ (verilog- insert (car stuff))
8488
8544
(setq need-indent (string-match "\n$" (car stuff))
8489
8545
stuff (cdr stuff)))))
8490
8546
;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n"))
@@ -8816,7 +8872,7 @@ Typing \\[verilog-inject-auto] will make this into:
8816
8872
(verilog-backward-syntactic-ws)
8817
8873
(backward-char 1) ; Moves to paren that closes argdecl's
8818
8874
(when (looking-at ")")
8819
- (insert "/*AUTOARG*/")))))))
8875
+ (verilog- insert "/*AUTOARG*/")))))))
8820
8876
8821
8877
(defun verilog-inject-sense ()
8822
8878
"Inject AUTOSENSE into new code. See `verilog-inject-auto'."
@@ -8838,7 +8894,7 @@ Typing \\[verilog-inject-auto] will make this into:
8838
8894
(when (not (or (verilog-signals-not-in pre-sigs got-sigs) ; Both are equal?
8839
8895
(verilog-signals-not-in got-sigs pre-sigs)))
8840
8896
(delete-region start-pt (point))
8841
- (insert "/*AS*/")))))))
8897
+ (verilog- insert "/*AS*/")))))))
8842
8898
8843
8899
(defun verilog-inject-inst ()
8844
8900
"Inject AUTOINST into new code. See `verilog-inject-auto'."
@@ -8872,9 +8928,8 @@ Typing \\[verilog-inject-auto] will make this into:
8872
8928
;; Not verilog-re-search, as we don't want to strip comments
8873
8929
(while (re-search-backward "[ \t\n\f]+" (- (point) 1) t)
8874
8930
(delete-region (match-beginning 0) (match-end 0)))
8875
- (insert "\n")
8876
- (indent-to indent-pt)
8877
- (insert "/*AUTOINST*/")))))))))
8931
+ (verilog-insert "\n")
8932
+ (verilog-insert-indent "/*AUTOINST*/")))))))))
8878
8933
8879
8934
;;
8880
8935
;; Auto save
@@ -9113,14 +9168,15 @@ If PAR-VALUES replace final strings with these parameter values."
9113
9168
(cond (tpl-ass
9114
9169
(indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
9115
9170
verilog-auto-inst-column))
9116
- (insert " // Templated")
9117
- (when verilog-auto-inst-template-numbers
9118
- (insert " T" (int-to-string (nth 2 tpl-ass))
9119
- " L" (int-to-string (nth 3 tpl-ass)))))
9171
+ (if verilog-auto-inst-template-numbers
9172
+ (verilog-insert " // Templated"
9173
+ " T" (int-to-string (nth 2 tpl-ass))
9174
+ " L" (int-to-string (nth 3 tpl-ass)))
9175
+ (verilog-insert " // Templated")))
9120
9176
(for-star
9121
9177
(indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
9122
9178
verilog-auto-inst-column))
9123
- (insert " // Implicit .\*"))) ;For some reason the . or * must be escaped...
9179
+ (verilog- insert " // Implicit .\*"))) ;For some reason the . or * must be escaped...
9124
9180
(insert "\n")))
9125
9181
;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
9126
9182
;;(x "incom[@\"(+ (* 8 @) 7)\":@\"(* 8 @)\"]")
@@ -9471,9 +9527,8 @@ For more information see the \\[verilog-faq] and forums at URL
9471
9527
(vl-dir "interface"))
9472
9528
(when sig-list
9473
9529
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9474
- (indent-to indent-pt)
9475
9530
;; Note these are searched for in verilog-read-sub-decls.
9476
- (insert "// Interfaces\n")
9531
+ (verilog- insert-indent "// Interfaces\n")
9477
9532
(mapc (lambda (port)
9478
9533
(verilog-auto-inst-port port indent-pt
9479
9534
tpl-list tpl-num for-star par-values))
@@ -9484,8 +9539,7 @@ For more information see the \\[verilog-faq] and forums at URL
9484
9539
(vl-dir "output"))
9485
9540
(when sig-list
9486
9541
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9487
- (indent-to indent-pt)
9488
- (insert "// Outputs\n")
9542
+ (verilog-insert-indent "// Outputs\n")
9489
9543
(mapc (lambda (port)
9490
9544
(verilog-auto-inst-port port indent-pt
9491
9545
tpl-list tpl-num for-star par-values))
@@ -9496,8 +9550,7 @@ For more information see the \\[verilog-faq] and forums at URL
9496
9550
(vl-dir "inout"))
9497
9551
(when sig-list
9498
9552
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9499
- (indent-to indent-pt)
9500
- (insert "// Inouts\n")
9553
+ (verilog-insert-indent "// Inouts\n")
9501
9554
(mapc (lambda (port)
9502
9555
(verilog-auto-inst-port port indent-pt
9503
9556
tpl-list tpl-num for-star par-values))
@@ -9508,8 +9561,7 @@ For more information see the \\[verilog-faq] and forums at URL
9508
9561
(vl-dir "input"))
9509
9562
(when sig-list
9510
9563
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9511
- (indent-to indent-pt)
9512
- (insert "// Inputs\n")
9564
+ (verilog-insert-indent "// Inputs\n")
9513
9565
(mapc (lambda (port)
9514
9566
(verilog-auto-inst-port port indent-pt
9515
9567
tpl-list tpl-num for-star par-values))
@@ -9614,9 +9666,8 @@ Templates:
9614
9666
(vl-dir "parameter"))
9615
9667
(when sig-list
9616
9668
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9617
- (indent-to indent-pt)
9618
9669
;; Note these are searched for in verilog-read-sub-decls.
9619
- (insert "// Parameters\n")
9670
+ (verilog- insert-indent "// Parameters\n")
9620
9671
(mapc (lambda (port)
9621
9672
(verilog-auto-inst-port port indent-pt
9622
9673
tpl-list tpl-num nil nil))
@@ -10322,6 +10373,7 @@ text:
10322
10373
(forward-line -1)
10323
10374
(eval (read cmd))
10324
10375
(forward-line -1)
10376
+ (setq verilog-scan-cache-tick nil) ;; Clear cache; inserted unknown text
10325
10377
(verilog-delete-empty-auto-pair))))
10326
10378
10327
10379
(defun verilog-auto-sense-sigs (moddecls presense-sigs)
@@ -10413,7 +10465,7 @@ operator. (This was added to the language in part due to AUTOSENSE!)
10413
10465
(when sig-memories
10414
10466
(let ((tlen (length sig-list)))
10415
10467
(setq sig-list (verilog-signals-not-in sig-list sig-memories))
10416
- (if (not (eq tlen (length sig-list))) (insert " /*memory or*/ "))))
10468
+ (if (not (eq tlen (length sig-list))) (verilog- insert " /*memory or*/ "))))
10417
10469
(if (and presense-sigs ;; Add a "or" if not "(.... or /*AUTOSENSE*/"
10418
10470
(save-excursion (goto-char (point))
10419
10471
(verilog-re-search-backward "[a-zA-Z0-9$_.%`]+" start-pt t)
@@ -10517,8 +10569,7 @@ Typing \\[verilog-auto] will make this into:
10517
10569
(setq sig-list (sort sig-list `verilog-signals-sort-compare))
10518
10570
(when sig-list
10519
10571
(insert "\n");
10520
- (indent-to indent-pt)
10521
- (insert "// Beginning of autoreset for uninitialized flops\n");
10572
+ (verilog-insert-indent "// Beginning of autoreset for uninitialized flops\n");
10522
10573
(indent-to indent-pt)
10523
10574
(while sig-list
10524
10575
(let ((sig (or (assoc (verilog-sig-name (car sig-list)) all-list) ;; As sig-list has no widths
@@ -10529,7 +10580,7 @@ Typing \\[verilog-auto] will make this into:
10529
10580
";\n")
10530
10581
(indent-to indent-pt)
10531
10582
(setq sig-list (cdr sig-list))))
10532
- (insert "// End of automatics")))))
10583
+ (verilog- insert "// End of automatics")))))
10533
10584
10534
10585
(defun verilog-auto-tieoff ()
10535
10586
"Expand AUTOTIEOFF statements, as part of \\[verilog-auto].
10939
10990
(after-change-functions nil)
10940
10991
;; Cache directories; we don't write new files, so can't change
10941
10992
(verilog-dir-cache-preserving t)
10993
+ (verilog-scan-cache-preserving (current-buffer))
10994
+ (verilog-scan-cache-tick nil)
10942
10995
;; Cache current module
10943
10996
(verilog-modi-cache-current-enable t)
10944
10997
(verilog-modi-cache-current-max (point-min)) ; IE it's invalid
0 commit comments