Function: hif-backward-comment

hif-backward-comment is a byte-compiled function defined in hideif.el.gz.

Signature

(hif-backward-comment &optional START END)

Documentation

If we're currently within a C(++) comment, skip them backwards.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/hideif.el.gz
(defun hif-backward-comment (&optional start end)
  "If we're currently within a C(++) comment, skip them backwards."
  ;; Ignore trailing white spaces after comment
  (setq end (or end (point)))
  (while (and (> (1- end) 1)
              (hif-is-white (char-after (1- end))))
     (decf end))
  (let ((p0 end)
        p cmt ce ws we ;; ce:comment start, ws:white start, we whilte end
        cmtlist) ;; pair of (start.end) of comments
    (setq start (or start (progn (beginning-of-line) (point)))
          p start)
    (while (< (1+ p) end)
      (if (char-equal ?/ (char-after p)) ; /
          (if (char-equal ?/ (char-after (1+ p))) ; //
              (progn
                ;; merge whites immediately ahead
                (setq ce (if (and we (= (1- p) we)) ws p))
                ;; scan for end of line
                (while (and (< (incf p) end)
                            (not (char-equal ?\n (char-after p)))
                            (not (char-equal ?\r (char-after p)))))
                ;; Merge with previous comment if immediately followed
                (push (cons (if (and cmtlist
                                     (= (cdr (car cmtlist)) ce))
                                (car (pop cmtlist)) ;; extend previous comment
                              ce)
                            p)
                      cmtlist))
            (when (char-equal ?* (char-after (1+ p))) ; /*
              ;; merge whites immediately ahead
              (setq ce (if (and we (= (1- p) we)) ws p))
              ;; Check if it immediately follows previous /*...*/ comment;
              ;; if yes, extend and merge into previous comment
              (setq cmt (if (and cmtlist
                                 (= (cdr (car cmtlist)) ce))
                            (car (pop cmtlist)) ;; extend previous comment
                          ce))
              (setq p (+ 2 p))
              ;; Scanning for `*/'
              (catch 'break
                (while (< (1+ p) end)
                  (if (not (and (char-equal ?* (char-after p))
                                (char-equal ?/ (char-after (1+ p)))))
                      (incf p)
                    ;; found `*/', mark end pos
                    (push (cons cmt (1+ (setq p (1+ p)))) cmtlist)
                    (throw 'break nil)))
                ;; (1+ p) >= end
                (push (cons cmt end) cmtlist))))
        ;; Trace most recent continuous white spaces before a comment
        (if (char-equal ?  (char-after p))
            (if (and ws (= we (1- p))) ;; continued
                (setq we p)
              (setq ws p
                    we p))
          (setq ws nil
                we nil)))
      (incf p))
    ;; Goto beginning of the last comment, if we're within
    (setq cmt (car cmtlist)) ;; last cmt
    (setq cmt (if (and cmt
                       (>= p0 (car cmt))
                       (<= p0 (cdr cmt)))
                  (car cmt) ;; beginning of the last comment
                p0))
    ;; Ignore leading whites ahead of comment
    (while (and (> (1- cmt) 1)
                (hif-is-white (char-after (1- cmt))))
       (decf cmt))
    (goto-char cmt)))