branch: elpa/swift-mode commit 19e6974b007e9f13808cdabf22a669af8208787e Author: taku0 <mxxouy6x3m_git...@tatapa.org> Commit: taku0 <mxxouy6x3m_git...@tatapa.org>
Abstract syntax-ppss --- swift-mode-indent.el | 33 +++++++------- swift-mode-lexer.el | 126 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 114 insertions(+), 45 deletions(-) diff --git a/swift-mode-indent.el b/swift-mode-indent.el index 05d6849..9a8194e 100644 --- a/swift-mode-indent.el +++ b/swift-mode-indent.el @@ -1510,10 +1510,11 @@ Return nil otherwise." "Return t if the point is inside an incomplete comment. Return nil otherwise." - (and (nth 4 (syntax-ppss)) - (save-excursion - (goto-char (nth 8 (syntax-ppss))) - (not (forward-comment 1))))) + (let ((chunk (swift-mode:chunk-after))) + (and (swift-mode:chunk:comment-p chunk) + (save-excursion + (goto-char (swift-mode:chunk:start chunk)) + (not (forward-comment 1)))))) (defun swift-mode:indent-new-comment-line (&optional soft) "Break the line at the point and indent the new line. @@ -1523,10 +1524,8 @@ multiline comment, close the previous comment and start new one if `comment-multi-line' is nil. See `indent-new-comment-line' for SOFT." (interactive) - (let* ((parser-state (syntax-ppss)) - (is-inside-comment (nth 4 parser-state)) - (is-single-line-comment (eq (nth 7 parser-state) 1)) - (comment-beginning-position (nth 8 parser-state)) + (let* ((chunk (swift-mode:chunk-after)) + (comment-beginning-position (swift-mode:chunk:start chunk)) (space-after-asterisk (if swift-mode:insert-space-after-asterisk-in-comment " " "")) (default-line-prefix @@ -1537,20 +1536,20 @@ See `indent-new-comment-line' for SOFT." (if soft (insert-and-inherit ?\n) (newline 1)) (delete-horizontal-space) - (when is-inside-comment + (when (swift-mode:chunk:comment-p chunk) (insert-before-markers-and-inherit (cond - (is-single-line-comment + ((swift-mode:chunk:single-line-comment-p chunk) (save-excursion (goto-char comment-beginning-position) - (looking-at "/+\\s *") + (looking-at "/+\\(\\s *\\)") (match-string-no-properties 0))) (comment-multi-line (save-excursion - (beginning-of-line) + (forward-line 0) (forward-char -1) - (beginning-of-line) + (forward-line 0) (if (<= (point) comment-beginning-position) ;; The cursor was on the 2nd line of the comment. ;; Uses default prefix. @@ -1576,7 +1575,7 @@ See `indent-new-comment-line' for SOFT." ;; Closes incomplete multiline comment. (when (and swift-mode:auto-close-multiline-comment - (not is-single-line-comment) + (swift-mode:chunk:multiline-comment-p chunk) (swift-mode:incomplete-comment-p)) (save-excursion (end-of-line) @@ -1592,7 +1591,7 @@ See `indent-new-comment-line' for SOFT." ((and swift-mode:prepend-asterisk-to-comment-line (= last-command-event ?*) - (nth 4 (syntax-ppss)) + (swift-mode:chunk:comment-p (swift-mode:chunk-after)) (save-excursion (backward-char) (skip-syntax-backward " ") (bolp))) (when swift-mode:insert-space-after-asterisk-in-comment (insert-before-markers-and-inherit " ")) @@ -1602,10 +1601,10 @@ See `indent-new-comment-line' for SOFT." ((and (= last-command-event ?/) swift-mode:fix-comment-close - (nth 4 (syntax-ppss)) + (swift-mode:chunk:comment-p (swift-mode:chunk-after)) (save-excursion (let ((pos (point))) - (beginning-of-line) + (forward-line 0) (and (looking-at "^\\s *\\*\\s +/") (eq (match-end 0) pos) diff --git a/swift-mode-lexer.el b/swift-mode-lexer.el index c2bb0b8..25339a8 100644 --- a/swift-mode-lexer.el +++ b/swift-mode-lexer.el @@ -221,19 +221,16 @@ Intended for `syntax-propertize-function'." nil swift-mode:matching-parenthesis nil)) - (let* ((parser-state (syntax-ppss start)) - (inside-string (nth 3 parser-state)) - (comment-nesting (nth 4 parser-state)) - (comment-beginning-position (nth 8 parser-state))) + (let* ((chunk (swift-mode:chunk-after (syntax-ppss start)))) (cond - ((eq inside-string t) + ((swift-mode:chunk:multiline-string-p chunk) (swift-mode:syntax-propertize:end-of-multiline-string end)) - (inside-string + ((swift-mode:chunk:single-line-string-p chunk) (swift-mode:syntax-propertize:end-of-single-line-string end)) - (comment-nesting - (goto-char comment-beginning-position) + ((swift-mode:chunk:comment-p chunk) + (goto-char (swift-mode:chunk:start chunk)) (forward-comment (point-max))))) (swift-mode:syntax-propertize:scan end 0)) @@ -748,8 +745,9 @@ Return the token object. If no more tokens available, return a token with type `out-of-buffer'" (let ((pos (point))) - (when (nth 4 (syntax-ppss)) - (goto-char (nth 8 (syntax-ppss)))) + (let ((chunk (swift-mode:chunk-after))) + (when (swift-mode:chunk:comment-p chunk) + (goto-char (swift-mode:chunk:start chunk)))) (forward-comment (point-max)) (cond ;; Outside of buffer @@ -959,8 +957,9 @@ Return the token object. If no more tokens available, return a token with type `out-of-buffer'." (let ((pos (point))) - (when (nth 4 (syntax-ppss)) - (goto-char (nth 8 (syntax-ppss)))) + (let ((chunk (swift-mode:chunk-after))) + (when (swift-mode:chunk:comment-p chunk) + (goto-char (swift-mode:chunk:start chunk)))) (forward-comment (- (point))) (cond ;; Outside of buffer @@ -1226,28 +1225,99 @@ Assuming the cursor is on a string." (defun swift-mode:goto-non-comment-bol () "Back to the beginning of line that is not inside a comment." - (beginning-of-line) - (while (nth 4 (syntax-ppss)) - ;; The cursor is in a comment. Backs to the beginning of the comment. - (goto-char (nth 8 (syntax-ppss))) - (beginning-of-line))) + (forward-line 0) + (let (chunk) + (while (progn + (setq chunk (swift-mode:chunk-after)) + (swift-mode:chunk:comment-p chunk)) + ;; The cursor is in a comment. Backs to the beginning of the comment. + (goto-char (swift-mode:chunk:start chunk)) + (forward-line 0)))) (defun swift-mode:goto-non-comment-eol () "Proceed to the end of line that is not inside a comment. If this line ends with a single-line comment, goto just before the comment." (end-of-line) - (while (nth 4 (syntax-ppss)) - ;; The cursor is in a comment. - (if (eq (nth 4 (syntax-ppss)) t) - ;; This ia a single-line comment - ;; Back to the beginning of the comment. - (goto-char (nth 8 (syntax-ppss))) - ;; This is a multiline comment - ;; Proceed to the end of the comment. - (goto-char (nth 8 (syntax-ppss))) - (forward-comment 1) - (end-of-line)))) + (let (chunk) + (while (progn + (setq chunk (swift-mode:chunk-after)) + (swift-mode:chunk:comment-p chunk)) + ;; The cursor is in a comment. + (if (swift-mode:chunk:single-line-comment-p chunk) + ;; This ia a single-line comment + ;; Back to the beginning of the comment. + (goto-char (swift-mode:chunk:start chunk)) + ;; This is a multiline comment + ;; Proceed to the end of the comment. + (goto-char (swift-mode:chunk:start chunk)) + (forward-comment 1) + (end-of-line))))) + +;;; Comment or string chunks + +;; A chunk is either a string-chunk or a comment. +;; It have the type and the start position. + +(defun swift-mode:chunk (type start) + "Return a new chunk with TYPE and START position." + (list type start)) + +(defun swift-mode:chunk:type (chunk) + "Return the type of the CHUNK." + (nth 0 chunk)) + +(defun swift-mode:chunk:start (chunk) + "Return the start position of the CHUNK." + (nth 1 chunk)) + +(defun swift-mode:chunk:comment-p (chunk) + "Return non-nil if the CHUNK is a comment." + (memq (swift-mode:chunk:type chunk) '(single-line-comment multiline-comment))) + +(defun swift-mode:chunk:string-p (chunk) + "Return non-nil if the CHUNK is a string." + (memq (swift-mode:chunk:type chunk) '(single-line-string multiline-string))) + +(defun swift-mode:chunk:single-line-comment-p (chunk) + "Return non-nil if the CHUNK is a single-line comment." + (eq (swift-mode:chunk:type chunk) 'single-line-comment)) + +(defun swift-mode:chunk:multiline-comment-p (chunk) + "Return non-nil if the CHUNK is a multiline comment." + (eq (swift-mode:chunk:type chunk) 'multiline-comment)) + +(defun swift-mode:chunk:single-line-string-p (chunk) + "Return non-nil if the CHUNK is a single-line string." + (eq (swift-mode:chunk:type chunk) 'single-line-string)) + +(defun swift-mode:chunk:multiline-string-p (chunk) + "Return non-nil if the CHUNK is a multiline string." + (eq (swift-mode:chunk:type chunk) 'multiline-string)) + +(defun swift-mode:chunk-after (&optional parser-state) + "Return the chunk at the cursor. + +If the cursor is outside of strings and comments, return nil. + +If PARSER-STATE is given, it is used instead of (syntax-ppss)." + (unless parser-state + (setq parser-state (syntax-ppss))) + (cond + ((eq (nth 3 parser-state) t) + (swift-mode:chunk 'multiline-string (nth 8 parser-state))) + ((nth 3 parser-state) + (swift-mode:chunk 'single-line-string (nth 8 parser-state))) + ((eq (nth 4 parser-state) t) + (swift-mode:chunk 'single-line-comment (nth 8 parser-state))) + ((nth 4 parser-state) + (swift-mode:chunk 'multiline-comment (nth 8 parser-state))) + ((and (eq (char-before) ?/) (eq (char-after) ?/)) + (swift-mode:chunk 'single-line-comment (1- (point)))) + ((and (eq (char-before) ?/) (eq (char-after) ?*)) + (swift-mode:chunk 'multiline-comment (1- (point)))) + (t + nil))) (provide 'swift-mode-lexer)