Function: verilog-calculate-indent

verilog-calculate-indent is a byte-compiled function defined in verilog-mode.el.gz.

Signature

(verilog-calculate-indent)

Documentation

Calculate the indent of the current Verilog line.

Examine previous lines. Once a line is found that is definitive as to the type of the current line, return that lines' indent level and its type. Return a list of two elements: (INDENT-TYPE INDENT-LEVEL).

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/verilog-mode.el.gz
(defun verilog-calculate-indent ()
  "Calculate the indent of the current Verilog line.
Examine previous lines.  Once a line is found that is definitive as to the
type of the current line, return that lines' indent level and its type.
Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
  (save-excursion
    (let* ((starting_position (point))
	   (case-fold-search nil)
	   (par 0)
	   (begin (looking-at "[ \t]*begin\\>"))
          (lim (save-excursion (verilog-re-search-backward "\\(\\<begin\\>\\)\\|\\(\\<\\(connect\\)?module\\>\\)" nil t)))
           (structres nil)
	   (type (catch 'nesting
		   ;; Keep working backwards until we can figure out
		   ;; what type of statement this is.
		   ;; Basically we need to figure out
		   ;; 1) if this is a continuation of the previous line;
		   ;; 2) are we in a block scope (begin..end)

		   ;; if we are in a comment, done.
		   (if (verilog-in-star-comment-p)
		       (throw 'nesting 'comment))

		   ;; if we have a directive, done.
		   (if (save-excursion (beginning-of-line)
				       (and (looking-at verilog-directive-re-1)
					    (not (or (looking-at "[ \t]*`[ou]vm_")
						     (looking-at "[ \t]*`vmm_")))))
		       (throw 'nesting 'directive))
                   ;; indent structs as if there were module level
                   (setq structres (verilog-in-struct-nested-p))
                   (cond ((not structres) nil)
                         ;;((and structres (equal (char-after) ?\})) (throw 'nesting 'struct-close))
                         ((> structres 0) (throw 'nesting 'nested-struct))
                         ((= structres 0) (throw 'nesting 'block))
                         (t nil))

                   ;; if we are in a parenthesized list, and the user likes to indent these, return.
                   ;; unless we are in the newfangled coverpoint or constraint blocks
                   (if (and
                        verilog-indent-lists
                        (verilog-in-paren)
                        (not (verilog-in-coverage-p))
                        )
                       (progn (setq par 1)
                              (throw 'nesting 'block)))

                   ;; See if we are continuing a previous line
                   (while t
                     ;; trap out if we crawl off the top of the buffer
                     (if (bobp) (throw 'nesting 'cpp))

                     (if (and (verilog-continued-line-1 lim)
                              (or (not (verilog-in-coverage-p))
                                  (looking-at verilog-in-constraint-re) ))  ; may still get hosed if concat in constraint
                         (let ((sp (point)))
                           (if (and
                                (not (looking-at verilog-complete-reg))
                                (verilog-continued-line-1 lim))
                               (progn (goto-char sp)
                                      (throw 'nesting 'cexp))

                             (goto-char sp))
                           (if (and (verilog-in-coverage-p)
                                    (looking-at verilog-in-constraint-re))
                               (progn
                                 (beginning-of-line)
                                 (skip-chars-forward " \t")
                                 (throw 'nesting 'constraint)))
                           (if (and begin
                                    (not verilog-indent-begin-after-if)
                                    (looking-at verilog-no-indent-begin-re))
                               (progn
                                 (beginning-of-line)
                                 (skip-chars-forward " \t")
                                 (throw 'nesting 'statement))
                             (progn
                               (throw 'nesting 'cexp))))
                       ;; not a continued line
                       (goto-char starting_position))

                     (if (looking-at "\\<else\\>")
                         ;; search back for governing if, striding across begin..end pairs
                         ;; appropriately
                         (let ((elsec 1))
                           (while (verilog-re-search-backward verilog-ends-re nil 'move)
                             (cond
                              ((match-end 1) ; else, we're in deep
                               (setq elsec (1+ elsec)))
                              ((match-end 2) ; if
                               (setq elsec (1- elsec))
                               (if (= 0 elsec)
                                   (if verilog-align-ifelse
                                       (throw 'nesting 'statement)
                                     (progn  ; back up to first word on this line
                                       (beginning-of-line)
                                       (verilog-forward-syntactic-ws)
                                       (throw 'nesting 'statement)))))
                              ((match-end 3) ; assert block
                               (setq elsec (1- elsec))
                               (verilog-beg-of-statement)  ; doesn't get to beginning
                               (if (looking-at verilog-property-re)
                                   (throw 'nesting 'statement)  ; We don't need an endproperty for these
                                 (throw 'nesting 'block)	; We still need an endproperty
                                 ))
                              (t ; endblock
                               ;; try to leap back to matching outward block by striding across
                               ;; indent level changing tokens then immediately
                               ;; previous line governs indentation.
                               (let (( reg) (nest 1))
                                 ;;	 verilog-ends =>  else|if|end|join(_any|_none|)|endcase|endclass|endtable|endspecify|endfunction|endtask|endgenerate|endgroup
                                 (cond
                                  ((match-end 4) ; end
                                   ;; Search back for matching begin
                                   (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ))
                                  ((match-end 5) ; endcase
                                   ;; Search back for matching case
                                   (setq reg "\\(\\<randcase\\>\\|\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ))
                                  ((match-end 6) ; endfunction
                                   ;; Search back for matching function
                                   (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ))
                                  ((match-end 7) ; endtask
                                   ;; Search back for matching task
                                   (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ))
                                  ((match-end 8) ; endspecify
                                   ;; Search back for matching specify
                                   (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ))
                                  ((match-end 9) ; endtable
                                   ;; Search back for matching table
                                   (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ))
                                  ((match-end 10) ; endgenerate
                                   ;; Search back for matching generate
                                   (setq reg "\\(\\<generate\\>\\)\\|\\(\\<endgenerate\\>\\)" ))
                                  ((match-end 11) ; joins
                                   ;; Search back for matching fork
                                   (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\(_any\\|none\\)?\\>\\)" ))
                                  ((match-end 12) ; class
                                   ;; Search back for matching class
                                   (setq reg "\\(\\<class\\>\\)\\|\\(\\<endclass\\>\\)" ))
                                  ((match-end 13) ; covergroup
                                   ;; Search back for matching covergroup
                                   (setq reg "\\(\\<covergroup\\>\\)\\|\\(\\<endgroup\\>\\)" )))
                                 (catch 'skip
                                   (while (verilog-re-search-backward reg nil 'move)
                                     (cond
                                      ((match-end 1) ; begin
                                       (setq nest (1- nest))
                                       (if (= 0 nest)
                                           (throw 'skip 1)))
                                      ((match-end 2) ; end
                                       (setq nest (1+ nest)))))
                                   )))))))
                     (throw 'nesting (verilog-calc-1)))
                   )  ; catch nesting
		 ) ; type
	   )
      ;; Return type of block and indent level.
      (if (not type)
	  (setq type 'cpp))
      (if (> par 0)			; Unclosed Parenthesis
	  (list 'cparenexp par)
	(cond
         ((eq type 'case)
          (list type (verilog-case-indent-level)))
         ((eq type 'statement)
          (list type (current-column)))
         ((eq type 'defun)
          (list type 0))
         ((eq type 'constraint)
          (list 'block (current-column)))
         ((eq type 'nested-struct)
          (list 'block structres))
         (t
          (list type (verilog-current-indent-level))))))))