lord+@andrew.cmu.edu (Tom Lord) (07/26/88)
Some time ago Robert Mecklenburg posted a c-comment minor mode that nicely supported comments like: /* * multi line comments can * be your friend. */ Recently, we updated to version 18.51 and the comment code stopped working. Has anyone got a fix? I was unable to repair c-comment myself because I could not make sense of the code in simple.el (particularly the functions used to indent comment lines). Simple.el should be cleaned up and adequately commented. -Thomas Lord lord+@andrew.cmu.edu
hartzell@beagle (George Hartzell) (07/26/88)
In article <gWv3ery00jaI8A=UVv@andrew.cmu.edu>, lord+@andrew (Tom Lord) writes: > >Some time ago Robert Mecklenburg posted a c-comment minor mode that >nicely supported comments like: > > /* > * multi line comments can > * be your friend. > */ > >Recently, we updated to version 18.51 and the comment code stopped >working. Has anyone got a fix? > Try this. ;;;;;;;;;;;;;;;;cut here;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Fix by george hartzell. 4-3-88 ;;; When we upgraded from 18.47 to 18.50 c-comment broke. ;;; I haven't been able to figure out why it is broken, but worked ;;; out the following fix. In the function set-fill-and-return I ;;; commented out the call to indent-new-comment-line and added ;;; (insert ?\n fill-prefix), which does what seems to be needed. ;;; Also need to make the same change in the function c-comment. ;;; And, in do-indented-autofill. ;;; ;;; C comment mode - An auto-filled comment mode for gnu c-mode. ;;; ;;; Author: Robert Mecklenburg ;;; Computer Science Dept. ;;; University of Utah ;;; From: mecklen@utah-gr.UUCP (Robert Mecklenburg) ;;; ;;; (c) 1986, University of Utah ;;; ;;; Everyone is granted permission to copy, modify and redistribute ;;; this file, provided the people they give it to can. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; I have written a "global comment" minor-mode which performs auto-fill, ;;; fill-paragraph, and auto-indentation functions. This function only ;;; works for comments which occupy an entire line (not comments to the ;;; right of code). The mode has several options set through variables. ;;; If the variable c-comment-starting-blank is non-nil multi-line ;;; comments come out like this: ;;; ;;; /* ;;; * Your favorite ;;; * multi-line comment. ;;; */ ;;; ;;; otherwise they look like this: ;;; ;;; /* Your Favorite ;;; * multi-line comment. ;;; */ ;;; ;;; If the variable c-comment-hanging-indent is non-nil K&R style comments ;;; are indented automatically like this: ;;; ;;; /* my_func - For multi-line comments with hanging indent ;;; * the text is lined up after the dash. ;;; */ ;;; ;;; otherwise the text "the text" (!) is lined up under my_func. If a ;;; comment fits (as typed) on a single line it remains a single line ;;; comment even if c-comment-starting-blank is set. If ;;; c-comment-indenting is non-nil hitting carriage return resets the ;;; indentation for the next line to the current line's indentation ;;; (within the comment) like this: ;;; ;;; /* Typing along merrily.... ;;; * Now I indent with spaces, when I hit return ;;; * the indentation is automatically set to ;;; * ^ here. ;;; */ ;;; ;;; Due to my lack of understanding of keymaps this permanently resets M-q ;;; to my own fill function. I would like to have the comment mode ;;; bindings only in comment mode but I can't seem to get that to work. ;;; If some gnu guru can clue me in, I'd appreciate it. ;;; (defvar c-comment-starting-blank t "*Controls whether global comments have an initial blank line.") (defvar c-comment-indenting t "*If set global comments are indented to the level of the previous line.") (defvar c-comment-hanging-indent t "*If true, comments will be automatically indented to the dash.") (defvar c-hang-already-done t "If true we have performed the haning indent already for this comment.") ;;; ;;; c-comment-map - This is a sparse keymap for comment mode which ;;; gets inserted when c-comment is called. ;;; (defvar c-comment-mode-map () "Keymap used in C comment mode.") (if c-comment-mode-map () ; (setq c-comment-mode-map (copy-sequence c-mode-map)) (setq c-comment-mode-map (make-sparse-keymap)) (define-key c-comment-mode-map "{" 'electric-c-brace) (define-key c-comment-mode-map "}" 'electric-c-brace) (define-key c-comment-mode-map ";" 'electric-c-semi) (define-key c-comment-mode-map ":" 'electric-c-terminator) (define-key c-comment-mode-map "\e\r" 'newline) (define-key c-comment-mode-map "\e\C-h" 'mark-c-function) (define-key c-comment-mode-map "\e\C-q" 'indent-c-exp) (define-key c-comment-mode-map "\eq" 'set-fill-and-fill) (define-key c-comment-mode-map "\177" 'backward-delete-char-untabify) (define-key c-comment-mode-map "\t" 'c-indent-command) (define-key c-comment-mode-map "\r" 'set-fill-and-return) ) ;;; ;;; c-comment - This is a filled comment mode which can format ;;; indented text, do hanging indents, and symetric ;;; placement of comment delimiters. ;;; (defun c-comment () "Edit a C comment with filling and indentation. This performs hanging indentation, symetric placement of delimiters, and Indented-Text mode style indentation. Type 'M-x apropos c-comment' for information on options." (interactive) (let ;; Save old state. ((auto-fill-hook (if c-comment-indenting 'do-indented-auto-fill 'do-auto-fill)) ; (comment-start nil) (comment-multi-line t) (comment-start-skip "/*\\*+[ ]*") (paragraph-start-ref paragraph-start) fill-prefix paragraph-start paragraph-separate opoint) ;; Determine if we are inside a comment. (setq in-comment (save-excursion (and (re-search-backward "/\\*\\|\\*/" 0 t) (string= "/*" (buffer-substring (point) (+ (point) 2)))))) ;; Indent the comment and set the fill prefix to comment continuation ;; string. If we are already in a comment get the indentation on ;; the current line. (setq c-hang-already-done nil) ;; Set the beginning of the comment and insert the blank line if needed. (use-local-map c-comment-mode-map) (if (not in-comment) (progn (c-indent-line) (insert "/* ") (setq fill-prefix (get-current-fill (point))) (recursive-edit) ;; If the comment fits on one line, place the close ;; comment at the end of the line. Otherwise, newline. (setq opoint (point)) (if (and (save-excursion (beginning-of-line) (search-forward "/*" opoint t)) (<= (+ (current-column) 3) 79)) (insert " */") (insert "\n*/")) (c-indent-line)) (progn (setq fill-prefix (get-current-fill (point))) (recursive-edit) (search-forward "*/" (buffer-size) t) (forward-line 1))) ;; If starting blank enabled, insert a newline, etc., but only if ;; this comment requires multiple lines. (if c-comment-starting-blank (save-excursion (setq opoint (point)) (forward-line -1) (if (or (null (search-forward "/*" opoint t)) (null (search-forward "*/" opoint t))) (progn (search-backward "/*") (re-search-forward comment-start-skip opoint t) (setq fill-prefix (get-current-fill (point))) (if (not (looking-at "\n")) (insert ?\n fill-prefix)))))) ; (indent-new-comment-line)))))) ;; Move cursor to indentation. (c-indent-line) (use-local-map c-mode-map) ) ) ;;; ;;; set-fill-and-fill - Get the current fill for this line and fill ;;; the paragraph. ;;; (defun set-fill-and-fill (arg) "Get the fill-prefix and fill the current paragraph." (interactive "P") (setq fill-prefix (get-current-fill (point))) (fill-paragraph arg) ) ;;; ;;; set-fill-and-return - Set the current fill prefix and ;;; indent-new-comment-line. ;;; (defun set-fill-and-return () "Set the current fill prefix and move to the next line." (interactive) (if c-comment-indenting (setq fill-prefix (get-current-fill (point)))) (insert ?\n fill-prefix) ; (indent-new-comment-line) ) ;;; ;;; do-indented-auto-fill - Perform the auto-fill function, but get ;;; the fill-prefix first. ;;; (defun do-indented-auto-fill () "Perform auto-fill, but get fill-prefix first." (let ((opoint (point))) (save-excursion (move-to-column (1+ fill-column)) (skip-chars-backward "^ \t\n") (if (bolp) (re-search-forward "[ \t]" opoint t)) ;; If there is a space on the line before fill-point, ;; and nonspaces precede it, break the line there. (if (save-excursion (skip-chars-backward " \t") (not (bolp))) ;; If we are wrapping to a new line, figure out the indentation on ;; the current line first. (progn (setq fill-prefix (get-current-fill opoint)) (insert ?\n fill-prefix))))) ; (indent-new-comment-line))))) ) ;;; ;;; get-current-fill - Get the fill-prefix for the current line. This ;;; assumes that the valid fill prefix is between ;;; (beginning-of-line) and (point). ;;; (defun get-current-fill (pnt) "Get the current fill prefix. A valid fill prefix must be between the beginning of the line and point." (let ((opoint pnt) fill last-char) (save-excursion (beginning-of-line) (setq fill (buffer-substring (point) (progn (re-search-forward comment-start-skip opoint t) (point)))) ;; Be sure there is trailing white space. (setq last-char (substring fill (1- (length fill)) (length fill))) (if (and (not (string= " " last-char)) (not (string= " " last-char))) (setq fill (concat fill " "))) (setq fill (replace-letter fill "/" " ")) ;; Get the hanging indentation if we haven't already. (if (and c-comment-hanging-indent (not c-hang-already-done)) (let ((curr (point)) (opnt (progn (end-of-line) (point)))) (beginning-of-line) (if (search-forward " - " opnt t) (progn (setq fill (concat fill (make-string (- (point) curr) 32))) (setq c-hang-already-done t))))) ;; Set the paragraph delimiters. (setq paragraph-start (concat paragraph-start-ref "\\|^" (regexp-quote (substring fill 0 (1- (length fill)))) "$")) (setq paragraph-separate paragraph-start)) fill) ) ;;; ;;; replace-letter - Given a string, an old letter and a new letter, ;;; perform the substitution. ;;; (defun replace-letter (str old-letter new-letter) (let (new-str c (sp 0) (size (length str))) (while (< sp size) (setq c (substring str sp (1+ sp))) (setq new-str (concat new-str (if (string= c old-letter) new-letter c))) (setq sp (1+ sp))) new-str) ) ;(define-key c-mode-map "\C-j" 'c-reindent-then-newline-and-indent) ;(define-key c-mode-map "\015" 'c-newline) ;(define-key c-mode-map "\e:" 'c-comment) -- George Hartzell (303) 492-4535 MCD Biology, University of Colorado-Boulder, Boulder, CO 80309 hartzell@Boulder.Colorado.EDU ..!{ncar,nbires}!boulder!hartzell