(defvar c-box-default-style 'single "*Preferred style for box comments.")
(defvar c-mode-taarna-style nil "*Non-nil for Taarna team C-style.")
(defun taarna-mode ()
(interactive)
(if c-mode-taarna-style
(progn
(setq c-mode-taarna-style nil)
(setq c-indent-level 2)
(setq c-continued-statement-offset 2)
(setq c-brace-offset 0)
(setq c-argdecl-indent 5)
(setq c-label-offset -2)
(setq c-tab-always-indent t)
(setq c-box-default-style 'single)
(message "C mode: GNU style"))
(setq c-mode-taarna-style t)
(setq c-indent-level 4)
(setq c-continued-statement-offset 4)
(setq c-brace-offset -4)
(setq c-argdecl-indent 4)
(setq c-label-offset -4)
(setq c-tab-always-indent t)
(setq c-box-default-style 'taarna)
(message "C mode: Taarna style")))
(defun buffer-left-margin ()
(let ((margin -1))
(goto-char (point-min))
(while (not (eobp))
(skip-chars-forward " \t")
(if (not (looking-at "\n"))
(setq margin
(if (< margin 0)
(current-column)
(min margin (current-column)))))
(forward-line 1))
margin))
(defun buffer-right-margin ()
(let ((margin 0) period)
(goto-char (point-min))
(while (not (eobp))
(end-of-line)
(if (bobp)
(setq period 0)
(backward-char 1)
(setq period (if (looking-at "[.?!]") 1 0))
(forward-char 1))
(setq margin (max margin (+ (current-column) period)))
(forward-char 1))
margin))
(defun rebox-c-comment-engine (flag refill)
(save-restriction
(let ((undo-list buffer-undo-list)
(marked-point (point-marker))
(saved-point (point))
box-style left-margin right-margin)
(skip-chars-forward " \t\n")
(if (looking-at "/\\*")
(forward-char 2))
(let ((here (point)) start end temp)
(search-backward "/*")
(setq temp (point))
(beginning-of-line)
(setq start (point))
(skip-chars-forward " \t")
(if (< (point) temp)
(progn
(goto-char saved-point)
(error "text before comment's start")))
(search-forward "*/")
(setq temp (point))
(end-of-line)
(if (looking-at "\n")
(forward-char 1))
(setq end (point))
(skip-chars-backward " \t\n")
(if (> (point) temp)
(progn
(goto-char saved-point)
(error "text after comment's end")))
(if (< end here)
(progn
(goto-char saved-point)
(error "outside any comment block")))
(goto-char start)
(while (and (not (bobp))
(progn (previous-line 1)
(beginning-of-line)
(looking-at "[ \t]*/\\*.*\\*/[ \t]*$")))
(setq start (point)))
(goto-char end)
(while (looking-at "[ \t]*/\\*.*\\*/[ \t]*$")
(forward-line 1)
(beginning-of-line)
(setq end (point)))
(narrow-to-region start end))
(let ((previous-margin (buffer-left-margin))
actual-margin)
(goto-char (point-min))
(replace-regexp "^\\([ \t]*\\)/\\*" "\\1 ")
(goto-char (point-min))
(replace-regexp "^\\([ \t]*\\)|" "\\1 ")
(goto-char (point-min))
(replace-regexp "\\(\\*/\\||\\)[ \t]*" "")
(goto-char (point-min))
(replace-regexp "\\*/[ \t]*/\\*" " ")
(setq box-style 'plain)
(goto-char (point-min))
(if (looking-at "^[ \t]*-*[.\+\\]?[ \t]*\n")
(progn
(setq box-style 'single)
(replace-match ""))
(if (looking-at "^[ \t]*=*[.\+\\]?[ \t]*\n")
(progn
(setq box-style 'double)
(replace-match ""))))
(goto-char (point-max))
(previous-line 1)
(beginning-of-line)
(if (looking-at "^[ \t]*[`\+\\]?*[-=]+[ \t]*\n")
(progn
(if (eq box-style 'plain)
(setq box-style 'taarna))
(replace-match "")))
(goto-char (point-min))
(replace-regexp "[ \t]+$" "")
(goto-char (point-min))
(if (looking-at "\n+")
(replace-match ""))
(goto-char (point-max))
(skip-chars-backward "\n")
(if (looking-at "\n\n+")
(replace-match "\n"))
(goto-char (point-min))
(replace-regexp "\n\n\n+" "\n\n")
(setq actual-margin (buffer-left-margin))
(if (not (= previous-margin actual-margin))
(indent-rigidly (point-min) (point-max)
(- previous-margin actual-margin))))
(if flag
(setq box-style
(cond ((eq flag 0) 'plain)
((eq flag 1) 'single)
((eq flag 2) 'double)
((eq flag 3) 'taarna)
((eq flag '-) (setq c-box-default-style 'plain) 'plain)
((eq flag -1) (setq c-box-default-style 'single) 'single)
((eq flag -2) (setq c-box-default-style 'double) 'double)
((eq flag -3) (setq c-box-default-style 'taarna) 'taarna)
(t c-box-default-style))))
(setq left-margin (buffer-left-margin))
(untabify (point-min) (point-max))
(if refill
(let ((fill-prefix (make-string left-margin ? ))
(fill-column (- fill-column
(if (memq box-style '(single double)) 4 6))))
(fill-region (point-min) (point-max))))
(setq right-margin (buffer-right-margin))
(setq right-margin (+ right-margin
(if (memq box-style '(single double))
2
3)))
(goto-char (point-min))
(cond ((eq box-style 'plain)
(skip-chars-forward " " (+ (point) left-margin))
(insert (make-string (- left-margin (current-column)) ? )
"/* ")
(end-of-line)
(forward-char 1)
(while (not (eobp))
(skip-chars-forward " " (+ (point) left-margin))
(insert (make-string (- left-margin (current-column)) ? )
" ")
(end-of-line)
(forward-char 1))
(backward-char 1)
(insert " */"))
((eq box-style 'single)
(indent-to left-margin)
(insert "/*")
(insert (make-string (- right-margin (current-column)) ?-)
"-.\n")
(while (not (eobp))
(skip-chars-forward " " (+ (point) left-margin))
(insert (make-string (- left-margin (current-column)) ? )
"| ")
(end-of-line)
(indent-to right-margin)
(insert " |")
(forward-char 1))
(indent-to left-margin)
(insert "`")
(insert (make-string (- right-margin (current-column)) ?-)
"*/\n"))
((eq box-style 'double)
(indent-to left-margin)
(insert "/*")
(insert (make-string (- right-margin (current-column)) ?=)
"=\\\n")
(while (not (eobp))
(skip-chars-forward " " (+ (point) left-margin))
(insert (make-string (- left-margin (current-column)) ? )
"| ")
(end-of-line)
(indent-to right-margin)
(insert " |")
(forward-char 1))
(indent-to left-margin)
(insert "\\")
(insert (make-string (- right-margin (current-column)) ?=)
"*/\n"))
((eq box-style 'taarna)
(while (not (eobp))
(skip-chars-forward " " (+ (point) left-margin))
(insert (make-string (- left-margin (current-column)) ? )
"/* ")
(end-of-line)
(indent-to right-margin)
(insert " */")
(forward-char 1))
(indent-to left-margin)
(insert "/* ")
(insert (make-string (- right-margin (current-column)) ?-)
" */\n"))
(t (error "unknown box style")))
(goto-char (point-min))
(while (re-search-forward "^[ \t][ \t][ \t]*" nil t)
(let ((column (current-column))
(indent-tabs-mode t))
(delete-region (match-beginning 0) (point))
(indent-to column)))
(goto-char (marker-position marked-point))
(if (not (eq buffer-undo-list undo-list))
(let ((cursor buffer-undo-list))
(while (not (eq (cdr cursor) undo-list))
(if (car (cdr cursor))
(setq cursor (cdr cursor))
(rplacd cursor (cdr (cdr cursor))))))))))
(defun rebox-c-comment (flag)
(interactive "P")
(rebox-c-comment-engine flag nil))
(defun reindent-c-comment (flag)
(interactive "P")
(rebox-c-comment-engine flag t))