matlab.el:

matlab-scan.el:
(mlf-entity-start, mlf-paren-outer-char, mlf-paren-outer-point):
New const, renumber the others.
(mlf-paren-inner-char, mlf-paren-inner-col):
Renamed fro versions w/out -inner in the name.
(matlab-compute-line-context-lvl-1):
Fill in entity start, and outer char/point.
(matlab-line-block-comment-start): New
(matlab-line-close-paren-inner-col, -char):
Renamed to include -inner
(matlab-line-close-paren-outer-char, -point): New
(matlab-line-comment-help-p): Renamed to
(matlab-scan-comment-help-p): Option PT
now specifies if a point is returned instead of a column.
(matlab-scan-previous-line-ellipsis-p): New
(matlab-scan-beginning-of-command): New
(matlab-describe-line-indent-context): Fixup names, etc.
This commit is contained in:
Eric Ludlam 2021-03-12 08:00:34 -05:00
parent 06c26b19e7
commit 52775e4af3
2 changed files with 136 additions and 72 deletions

View file

@ -86,30 +86,22 @@ return the cache if it finds it."
(defconst mlf-ltype 0)
(defconst mlf-stype 1)
(defconst mlf-indent 2)
(defconst mlf-paren-depth 3)
(defconst mlf-paren-char 4)
(defconst mlf-paren-col 5)
(defconst mlf-paren-delta 6)
(defconst mlf-end-comment-type 7)
(defconst mlf-end-comment-col 8)
(defconst mlf-entity-start 3)
(defconst mlf-paren-depth 4)
(defconst mlf-paren-inner-char 5)
(defconst mlf-paren-inner-col 6)
(defconst mlf-paren-outer-char 7)
(defconst mlf-paren-outer-point 8)
(defconst mlf-paren-delta 9)
(defconst mlf-end-comment-type 10)
(defconst mlf-end-comment-col 11)
(defun matlab-compute-line-context-lvl-1 ()
"Compute and return the level1 context for the current line of MATLAB code.
Level 1 contexts are things quickly derived from `syntax-ppss'
and other simple states.
Computes multiple styles of line by checking for multiple types of context
in a single call using fastest methods.
Return list has these fields:
0 - Primary line type
1 - Secondary line type
2 - Indentation
3 - Parenthisis depth
4 - Char for innermost beginning paren
5 - Column of innermost beginning paren
6 - Parenthisis depth change on this line
7 - End Comment type (ellipsis, comment, or nil)
8 - End Comment start column
"
in a single call using fastest methods."
(save-excursion
(back-to-indentation)
(let* ((ppsend (save-excursion (syntax-ppss (point-at-eol))))
@ -117,13 +109,16 @@ Return list has these fields:
(ltype 'empty)
(stype nil)
(cc 0)
(start (point))
(paren-depth (nth 0 pps))
(paren-char nil)
(paren-col nil)
(paren-inner-char nil)
(paren-inner-col nil)
(paren-outer-char nil)
(paren-outer-point nil)
(paren-delta (- (car pps) (car ppsend)))
(ec-type nil)
(ec-col nil)
(cont-from-prev nil)
)
;; This means we are somewhere inside a cell, array, or arg list.
@ -133,8 +128,10 @@ Return list has these fields:
(when (> (nth 0 pps) 0)
(save-excursion
(goto-char (car (last (nth 9 pps))))
(setq paren-char (char-after (point))
paren-col (current-column))))
(setq paren-inner-char (char-after (point))
paren-inner-col (current-column)
paren-outer-point (car (nth 9 pps))
paren-outer-char (char-after paren-outer-point) )))
(cond
;; For comments - We can only ever be inside a block comment, so
@ -146,7 +143,8 @@ Return list has these fields:
'block-end)
((looking-at "%")
'block-body-prefix)
(t 'block-body))))
(t 'block-body))
start (nth 8 pps)))
;; If indentation lands on end of line, this is an empty line
;; so nothing left to do. Keep after block-comment-body check
@ -214,7 +212,9 @@ Return list has these fields:
ec-type (if (= (char-after csc) ?\%) 'comment 'ellipsis))) ;; type
)
(list ltype stype cc paren-depth paren-char paren-col paren-delta ec-type ec-col)
(list ltype stype cc start paren-depth
paren-inner-char paren-inner-col paren-outer-char paren-outer-point paren-delta
ec-type ec-col cont-from-prev)
)))
@ -267,6 +267,13 @@ All lines that start with a comment end with a comment."
All lines that start with a comment end with a comment."
(eq (nth mlf-end-comment-type lvl1) 'ellipsis))
(defsubst matlab-line-block-comment-start (lvl1)
"Return the start of the block comment we are in, or nil."
(when (and (matlab-line-comment-p lvl1)
(memq (nth mlf-stype lvl1)
'(block-start block-end block-body block-body-prefix)))
(nth mlf-entity-start lvl1)))
;; Code and Declarations
(defsubst matlab-line-block-start-keyword-p (lvl1)
"Return t if the current line starts with block keyword."
@ -296,32 +303,87 @@ These are keywords like `else' or `catch'."
"Non nil If the current line starts with closing paren (any type.)"
(eq (car lvl1) 'close-paren))
(defsubst matlab-line-close-paren-char (lvl1)
"Non nil If the current line starts with closing paren (any type.)"
(nth mlf-paren-char lvl1))
(defsubst matlab-line-close-paren-inner-char (lvl1)
"Return the paren character for the parenthetical expression LVL1 is in."
(nth mlf-paren-inner-char lvl1))
(defsubst matlab-line-close-paren-col (lvl1)
"Non nil If the current line starts with closing paren (any type.)"
(nth mlf-paren-col lvl1))
(defsubst matlab-line-close-paren-inner-col (lvl1)
"Return the paren column for the prenthetical expression LVL1 is in."
(nth mlf-paren-inner-col lvl1))
(defsubst matlab-line-close-paren-outer-char (lvl1)
"The paren character for the outermost prenthetical expression LVL1 is in."
(nth mlf-paren-outer-char lvl1))
(defsubst matlab-line-close-paren-outer-point (lvl1)
"The poit the outermost parenthetical expression start is at."
(nth mlf-paren-outer-point lvl1))
;;; Scanning Accessor utilities
;;
;; some utilities require some level of buffer scanning to get the answer.
;; Some utilities require some level of buffer scanning to get the answer.
;; Keep those separate so they can depend on the earlier decls.
(defun matlab-line-comment-help-p (lvl1)
(defun matlab-scan-comment-help-p (lvl1 &optional pt)
"Return declaration column if the current line is part of a help comment.
Declarations are things like functions and classdefs.
Indentation a help comment depends on the column of the declaration."
Indentation a help comment depends on the column of the declaration.
Optional PT, if non-nil, means return the point instead of column"
(and (matlab-line-comment-p lvl1)
(save-excursion
(beginning-of-line)
(forward-comment -100000)
(let ((c-lvl1 (matlab-compute-line-context 1)))
(when (matlab-line-declaration-p c-lvl1)
(current-indentation)))
(if pt (point) (current-indentation))))
)))
(defun matlab-scan-previous-line-ellipsis-p ()
"Return the point of the previous line's continuation if there is one.
This is true iff the previous line has an ellipsis, but not if this line
is in an array with an implied continuation."
(save-excursion
(beginning-of-line)
(when (not (bobp))
(forward-char -1)
(let* ((pps (syntax-ppss (point)))
(csc (nth 8 pps)))
;; If the comment active on eol does NOT start with %, then it must be
;; and ellipsis.
(and (/= (char-after csc) ?\%)
csc)))))
(defun matlab-scan-beginning-of-command (&optional lvl1)
"Return point in buffer at the beginning of this command.
This function walks up any enclosing parens, and skips
backward over lines that include ellipsis."
(unless lvl1 (setq lvl1 (matlab-compute-line-context 1)))
;; If we are in a block comment, just jump to the beginning, and
;; that's it.
(let ((bcs (matlab-line-block-comment-start lvl1)))
(when bcs
(goto-char bcs)
(setq lvl1 (matlab-compute-line-context 1)))
;; If we are in a help comment, jump over that first.
(setq bcs (matlab-scan-comment-help-p lvl1 'point))
(when bcs
(goto-char bcs)
(setq lvl1 (matlab-compute-line-context 1)))
;; Now scan backward till we find the beginning.
(let ((found nil))
(while (not found)
;; first - just jump to our outermost point.
(goto-char (or (matlab-line-close-paren-outer-point lvl1) (point)))
;; Second - is there an ellipsis on prev line?
(let ((prev (matlab-scan-previous-line-ellipsis-p)))
(if (not prev)
(setq found t)
;; Move to prev location if not found.
(goto-char prev))))
(back-to-indentation)
(point))))
;;; Caching
;;
@ -363,13 +425,13 @@ Used to speed up repeated queries on the same set of lines.")
"Describe the indentation context for the current line."
(interactive)
(let* ((lvl1 (matlab-compute-line-context 1))
(paren-char (nth mlf-paren-char lvl1))
(open (format "%c" (or paren-char ?\()))
(paren-inner-char (nth mlf-paren-inner-char lvl1))
(open (format "%c" (or paren-inner-char ?\()))
(close (format "%c"
(cond ((not paren-char) ?\))
((= paren-char ?\() ?\))
((= paren-char ?\[) ?\])
((= paren-char ?\{) ?\})
(cond ((not paren-inner-char) ?\))
((= paren-inner-char ?\() ?\))
((= paren-inner-char ?\[) ?\])
((= paren-inner-char ?\{) ?\})
(t ??))))
(extraopen "")
(extraclose "")

View file

@ -2088,37 +2088,39 @@ If `matlab-functions-have-end', skip over functions with end."
(goto-char (match-end 0))
(current-word)))))
(defun matlab-beginning-of-command ()
(defun matlab-beginning-of-command (&optional arg)
"Go to the beginning of an M command.
Travels across continuations."
(interactive)
(beginning-of-line)
(save-match-data
(let ((p nil)
(bc (matlab-block-comment-bounds)))
;; block comment - just go to the beginning.
(if bc
(goto-char (car bc))
(interactive "P")
(if arg
(matlab-scan-beginning-of-command)
(beginning-of-line)
(save-match-data
(let ((p nil)
(bc (matlab-block-comment-bounds)))
;; block comment - just go to the beginning.
(if bc
(goto-char (car bc))
;; ELSE : Scan across lines that are related.
;; Step one, skip all comments indented as continutions of a previous.
;; Using forward-comment is very fast, and just skipps all comments until
;; we hit a line of code.
;; NOTE: This may fail with poorly indented code.
(when (or (matlab-ltype-help-comm)
(matlab-ltype-continued-comm))
(forward-comment -100000))
;; ELSE : Scan across lines that are related.
;; Step one, skip all comments indented as continutions of a previous.
;; Using forward-comment is very fast, and just skipps all comments until
;; we hit a line of code.
;; NOTE: This may fail with poorly indented code.
(when (or (matlab-ltype-help-comm)
(matlab-ltype-continued-comm))
(forward-comment -100000))
;; Now walk backward across continued code lines.
(while (and (or (setq p (matlab-lattr-array-cont)) ;; do this first b/c fast
(matlab-prev-line-cont)
;; We used to do this, now handled w/ forward-comment above.
;;(matlab-ltype-continued-comm)
)
(save-excursion (beginning-of-line) (not (bobp))))
(if p (goto-char p) (matlab-prev-line))
(setq p nil)))
(back-to-indentation))))
;; Now walk backward across continued code lines.
(while (and (or (setq p (matlab-lattr-array-cont)) ;; do this first b/c fast
(matlab-prev-line-cont)
;; We used to do this, now handled w/ forward-comment above.
;;(matlab-ltype-continued-comm)
)
(save-excursion (beginning-of-line) (not (bobp))))
(if p (goto-char p) (matlab-prev-line))
(setq p nil)))
(back-to-indentation)))))
(defun matlab-end-of-command ()
"Go to the end of an M command.
@ -2527,7 +2529,7 @@ Argument CURRENT-INDENTATION is what the previous line recommends for indentatio
((eq comment-style 'block-body)
(list 'comment (+ 2 (matlab-line-end-comment-column lvl1))))
;; HELP COMMENT and COMMENT REGION
((setq tmp (matlab-line-comment-help-p lvl1))
((setq tmp (matlab-scan-comment-help-p lvl1))
(list 'comment-help tmp))
;; COMMENT REGION comments
((matlab-line-comment-ignore-p lvl1)
@ -2625,8 +2627,8 @@ Argument CURRENT-INDENTATION is what the previous line recommends for indentatio
;; End of a MATRIX
((matlab-line-close-paren-p lvl1)
;;(matlab-lattr-array-end)
(list 'array-end (let* ((fc (matlab-line-close-paren-char lvl1)) ;;following-char))
(pc (matlab-line-close-paren-col lvl1))
(list 'array-end (let* ((fc (matlab-line-close-paren-inner-char lvl1)) ;;following-char))
(pc (matlab-line-close-paren-inner-col lvl1))
(mi (assoc fc matlab-maximum-indents))
(max (if mi (if (listp (cdr mi))
(car (cdr mi)) (cdr mi))
@ -2782,7 +2784,7 @@ See `matlab-calculate-indentation'."
(mc (and (matlab-line-block-middle-p lvl1) 1)) ;(matlab-lattr-middle-block-cont))
(ec (and (matlab-line-block-case-p lvl1) 1)) ;(matlab-lattr-endless-block-cont))
(hc (and (matlab-indent-function-body-p)
(matlab-line-comment-help-p lvl1))) ;(matlab-ltype-help-comm)))
(matlab-scan-comment-help-p lvl1))) ;(matlab-ltype-help-comm)))
(rc (and (/= 0 matlab-comment-anti-indent)
(matlab-line-regular-comment-p lvl1) ;(matlab-ltype-comm-noblock)
;;(not (matlab-ltype-help-comm))