Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 21 additions & 26 deletions haskell-decl-scan.el
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,18 @@ current line that starts with REGEXP and is not in `font-lock-comment-face'."
'font-lock-comment-face)))))

(defun haskell-ds-move-to-start-regexp-skipping-comments (inc regexp)
"Like haskell-ds-move-to-start-regexp, but uses syntax-ppss to
skip comments"
"Like haskell-ds-move-to-start-regexp, but skips comments."
(let (p)
(cl-loop
do (setq p (point))
(haskell-ds-move-to-start-regexp inc regexp)
while (and (nth 4 (syntax-ppss))
while (and (not (haskell-ds-whitespace-p))
(haskell-ds-comment-p)
(/= p (point))))))

(defvar literate-haskell-ds-line-prefix "> ?"
"Regexp matching start of a line of Bird-style literate code.

Current value is \"> \" as we assume top-level declarations start
at column 3. Must not contain the special \"^\" regexp as we may
not use the regexp at the start of a regexp string. Note this is
Expand All @@ -217,10 +218,10 @@ only for `imenu' support.")
(concat literate-haskell-ds-line-prefix haskell-ds-start-decl-re)
"The regexp that starts a Bird-style literate Haskell declaration.")

(defun haskell-ds-whitespace-p (char)
"Test if CHAR is a whitespace character."
;; the nil is a bob/eob test
(member char '(nil ?\t ?\n ?\ )))
(defun haskell-ds-whitespace-p ()
"Test if PT is at a whitespace character."
(or (eolp)
(equal (string-to-syntax " ") (syntax-after (point)))))

(defun haskell-ds-move-to-decl (direction bird-literate fix)
"General function for moving to the start of a declaration,
Expand Down Expand Up @@ -356,20 +357,15 @@ there."
(interactive)
(haskell-ds-move-to-decl nil (haskell-ds-bird-p) nil))

(defun haskell-ds-comment-p
(&optional
pt)
"Test if the cursor is on whitespace or a comment.

`PT' defaults to `(point)'"
(defun haskell-ds-comment-p ()
"Test if the cursor is on whitespace or a comment."
;; ensure result is `t' or `nil' instead of just truthy
(if (or
;; is cursor on whitespace
(haskell-ds-whitespace-p (following-char))
(haskell-ds-whitespace-p)
;; http://emacs.stackexchange.com/questions/14269/how-to-detect-if-the-point-is-within-a-comment-area
;; is cursor at begging, inside, or end of comment
(let ((fontfaces (get-text-property (or pt
(point)) 'face)))
(let ((fontfaces (get-text-property (point) 'face)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't add comment on a line that follows, so I'm putting it here: comments in haskell have structure and we use more faces than just font-lock-comment-face: haskell-pragma-face, haskell-liquid-haskell-annotation-face, haskell-literate-comment-face. Sometimes we also add (:weight bold) and (:slant italic).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The weight and slant already work. I can add these other faces to the member test if you want.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they have to be there. Otherwise declscan will not work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the help.

(when (not (listp fontfaces))
(setf fontfaces (list fontfaces)))
(delq nil (mapcar
Expand All @@ -382,18 +378,17 @@ there."
nil))

(defun haskell-ds-line-commented-p ()
"Tests if all characters from `point' to `end-of-line' pass
`haskell-ds-comment-p'"
(let ((r t))
(while (and r (not (eolp)))
(if (not (haskell-ds-comment-p))
(setq r nil))
(forward-char))
r))
"Test if all characters from `point' to `end-of-line' pass `haskell-ds-comment-p'."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is horrible. The way to find end of current comment is to use (parse-partial-sexp (point) (point-max) nil nil (syntax-ppss) 'syntax-table). Examples are in haskell-font-lock.el.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only usage of this function is to go back to the end of a definition. That requires going through all lines that are composed only of white space and comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use (parse-partial-sexp (point) (point-max) nil nil (syntax-ppss) 'syntax-table) for this purpose.

(save-excursion
(let ((r t))
(while (and r (not (eolp)))
(if (not (haskell-ds-comment-p))
(setq r nil))
(forward-char))
r)))

(defun haskell-ds-forward-decl ()
"Move forward to the first character that starts a top-level
declaration. As `haskell-ds-backward-decl' but forward."
"Move forward to the end of the top-level declaration."
(interactive)
(let ((p (point)) b e empty was-at-bob)
;; Go back to beginning of defun, then go to beginning of next
Expand Down