|
|
1.1 ! root 1: ;;; C comment mode - An auto-filled comment mode for gnu c-mode. ! 2: ;;; ! 3: ;;; Author: Robert Mecklenburg ! 4: ;;; Computer Science Dept. ! 5: ;;; University of Utah ! 6: ;;; From: [email protected] (Robert Mecklenburg) ! 7: ;;; Also [email protected] ! 8: ;;; (c) 1986, University of Utah ! 9: ;;; ! 10: ;;; Everyone is granted permission to copy, modify and redistribute ! 11: ;;; this file, provided the people they give it to can. ! 12: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ! 13: ;;; ! 14: ;;; I have written a "global comment" minor-mode which performs auto-fill, ! 15: ;;; fill-paragraph, and auto-indentation functions. This function only ! 16: ;;; works for comments which occupy an entire line (not comments to the ! 17: ;;; right of code). The mode has several options set through variables. ! 18: ;;; If the variable c-comment-starting-blank is non-nil multi-line ! 19: ;;; comments come out like this: ! 20: ;;; ! 21: ;;; /* ! 22: ;;; * Your favorite ! 23: ;;; * multi-line comment. ! 24: ;;; */ ! 25: ;;; ! 26: ;;; otherwise they look like this: ! 27: ;;; ! 28: ;;; /* Your Favorite ! 29: ;;; * multi-line comment. ! 30: ;;; */ ! 31: ;;; ! 32: ;;; If the variable c-comment-hanging-indent is non-nil K&R style comments ! 33: ;;; are indented automatically like this: ! 34: ;;; ! 35: ;;; /* my_func - For multi-line comments with hanging indent ! 36: ;;; * the text is lined up after the dash. ! 37: ;;; */ ! 38: ;;; ! 39: ;;; otherwise the text "the text" (!) is lined up under my_func. If a ! 40: ;;; comment fits (as typed) on a single line it remains a single line ! 41: ;;; comment even if c-comment-starting-blank is set. If ! 42: ;;; c-comment-indenting is non-nil hitting carriage return resets the ! 43: ;;; indentation for the next line to the current line's indentation ! 44: ;;; (within the comment) like this: ! 45: ;;; ! 46: ;;; /* Typing along merrily.... ! 47: ;;; * Now I indent with spaces, when I hit return ! 48: ;;; * the indentation is automatically set to ! 49: ;;; * ^ here. ! 50: ;;; */ ! 51: ;;; ! 52: ;;; Due to my lack of understanding of keymaps this permanently resets M-q ! 53: ;;; to my own fill function. I would like to have the comment mode ! 54: ;;; bindings only in comment mode but I can't seem to get that to work. ! 55: ;;; If some gnu guru can clue me in, I'd appreciate it. ! 56: ;;; ! 57: (defvar c-comment-starting-blank t ! 58: "*Controls whether global comments have an initial blank line.") ! 59: (defvar c-comment-indenting t ! 60: "*If set global comments are indented to the level of the previous line.") ! 61: (defvar c-comment-hanging-indent t ! 62: "*If true, comments will be automatically indented to the dash.") ! 63: (defvar c-hang-already-done t ! 64: "If true we have performed the haning indent already for this comment.") ! 65: ! 66: ! 67: ;;; ! 68: ;;; c-comment-map - This is a sparse keymap for comment mode which ! 69: ;;; gets inserted when c-comment is called. ! 70: ;;; ! 71: (defvar c-comment-mode-map () ! 72: "Keymap used in C comment mode.") ! 73: (if c-comment-mode-map ! 74: () ! 75: (setq c-comment-mode-map (copy-keymap c-mode-map)) ! 76: (define-key c-comment-mode-map "\e\r" 'newline) ! 77: (define-key c-comment-mode-map "\eq" 'set-fill-and-fill) ! 78: (define-key c-comment-mode-map "\r" 'set-fill-and-return)) ! 79: ! 80: ;;; ! 81: ;;; c-comment - This is a filled comment mode which can format ! 82: ;;; indented text, do hanging indents, and symetric ! 83: ;;; placement of comment delimiters. ! 84: ;;; ! 85: (defun c-comment () ! 86: "Edit a C comment with filling and indentation. ! 87: This performs hanging indentation, symmetric placement of delimiters, ! 88: and Indented-Text mode style indentation. Type 'M-x apropos ! 89: c-comment' for information on options." ! 90: (interactive) ! 91: (let ! 92: ;; Save old state. ! 93: ((auto-fill-hook (if c-comment-indenting ! 94: 'do-indented-auto-fill 'do-auto-fill)) ! 95: ; (comment-start nil) ! 96: (comment-multi-line t) ! 97: (comment-start-skip "/*\\*+[ ]*") ! 98: (paragraph-start-ref paragraph-start) ! 99: fill-prefix paragraph-start paragraph-separate opoint) ! 100: ! 101: ;; Determine if we are inside a comment. ! 102: (setq in-comment ! 103: (save-excursion ! 104: (and (re-search-backward "/\\*\\|\\*/" 0 t) ! 105: (string= "/*" (buffer-substring (point) (+ (point) 2)))))) ! 106: ! 107: ;; Indent the comment and set the fill prefix to comment continuation ! 108: ;; string. If we are already in a comment get the indentation on ! 109: ;; the current line. ! 110: (setq c-hang-already-done nil) ! 111: ! 112: ;; Set the beginning of the comment and insert the blank line if needed. ! 113: (use-local-map c-comment-mode-map) ! 114: (if (not in-comment) ! 115: (progn (c-indent-line) ! 116: (insert "/* ") ! 117: (setq fill-prefix (get-current-fill (point))) ! 118: (recursive-edit) ! 119: ! 120: ;; If the comment fits on one line, place the close ! 121: ;; comment at the end of the line. Otherwise, newline. ! 122: (setq opoint (point)) ! 123: (if (and (save-excursion (beginning-of-line) ! 124: (search-forward "/*" opoint t)) ! 125: (<= (+ (current-column) 3) 79)) ! 126: (insert " */") ! 127: (insert "\n*/")) ! 128: ! 129: (c-indent-line)) ! 130: (progn (setq fill-prefix (get-current-fill (point))) ! 131: (recursive-edit) ! 132: (search-forward "*/" (buffer-size) t) ! 133: (forward-line 1))) ! 134: ! 135: ;; If starting blank enabled, insert a newline, etc., but only if ! 136: ;; this comment requires multiple lines. ! 137: (if c-comment-starting-blank ! 138: (save-excursion ! 139: (setq opoint (point)) ! 140: (forward-line -1) ! 141: (if (or (null (search-forward "/*" opoint t)) ! 142: (null (search-forward "*/" opoint t))) ! 143: (progn ! 144: (search-backward "/*") ! 145: (re-search-forward comment-start-skip opoint t) ! 146: (setq fill-prefix (get-current-fill (point))) ! 147: (if (not (looking-at "\n")) ! 148: (insert ?\n fill-prefix)))))) ! 149: ; (indent-new-comment-line)))))) ! 150: ! 151: ;; Move cursor to indentation. ! 152: (c-indent-line) ! 153: (use-local-map c-mode-map) ! 154: ) ! 155: ) ! 156: ! 157: ! 158: ;;; ! 159: ;;; set-fill-and-fill - Get the current fill for this line and fill ! 160: ;;; the paragraph. ! 161: ;;; ! 162: (defun set-fill-and-fill (arg) ! 163: "Get the fill-prefix and fill the current paragraph." ! 164: ! 165: (interactive "P") ! 166: (setq fill-prefix (get-current-fill (point))) ! 167: (fill-paragraph arg)) ! 168: ! 169: ;;; ! 170: ;;; set-fill-and-return - Set the current fill prefix and ! 171: ;;; indent-new-comment-line. ! 172: ;;; ! 173: (defun set-fill-and-return () ! 174: "Set the current fill prefix and move to the next line." ! 175: ! 176: (interactive) ! 177: (if c-comment-indenting ! 178: (setq fill-prefix (get-current-fill (point)))) ! 179: (insert ?\n fill-prefix)) ! 180: ! 181: ;;; ! 182: ;;; do-indented-auto-fill - Perform the auto-fill function, but get ! 183: ;;; the fill-prefix first. ! 184: ;;; ! 185: (defun do-indented-auto-fill () ! 186: "Perform auto-fill, but get fill-prefix first." ! 187: ! 188: (let ((opoint (point))) ! 189: (save-excursion ! 190: (move-to-column (1+ fill-column)) ! 191: (skip-chars-backward "^ \t\n") ! 192: (if (bolp) ! 193: (re-search-forward "[ \t]" opoint t)) ! 194: ;; If there is a space on the line before fill-point, ! 195: ;; and nonspaces precede it, break the line there. ! 196: (if (save-excursion ! 197: (skip-chars-backward " \t") ! 198: (not (bolp))) ! 199: ! 200: ;; If we are wrapping to a new line, figure out the indentation on ! 201: ;; the current line first. ! 202: (progn ! 203: (setq fill-prefix (get-current-fill opoint)) ! 204: (insert ?\n fill-prefix))))) ! 205: ; (indent-new-comment-line))))) ! 206: ) ! 207: ! 208: ! 209: ;;; ! 210: ;;; get-current-fill - Get the fill-prefix for the current line. This ! 211: ;;; assumes that the valid fill prefix is between ! 212: ;;; (beginning-of-line) and (point). ! 213: ;;; ! 214: (defun get-current-fill (pnt) ! 215: "Get the current fill prefix. ! 216: A valid fill prefix must be between the beginning of the line and point." ! 217: ! 218: (let ((opoint pnt) fill last-char) ! 219: (save-excursion ! 220: (beginning-of-line) ! 221: (setq fill ! 222: (buffer-substring (point) ! 223: (progn ! 224: (re-search-forward comment-start-skip opoint t) ! 225: (point)))) ! 226: ! 227: ;; Be sure there is trailing white space. ! 228: (setq last-char (substring fill (1- (length fill)) (length fill))) ! 229: (if (and (not (string= " " last-char)) ! 230: (not (string= " " last-char))) ! 231: (setq fill (concat fill " "))) ! 232: ! 233: (setq fill (replace-letter fill "/" " ")) ! 234: ! 235: ;; Get the hanging indentation if we haven't already. ! 236: (if (and c-comment-hanging-indent (not c-hang-already-done)) ! 237: (let ((curr (point)) ! 238: (opnt (progn (end-of-line) (point)))) ! 239: (beginning-of-line) ! 240: (if (search-forward " - " opnt t) ! 241: (progn ! 242: (setq fill (concat fill (make-string (- (point) curr) 32))) ! 243: (setq c-hang-already-done t))))) ! 244: ! 245: ;; Set the paragraph delimiters. ! 246: (setq paragraph-start (concat paragraph-start-ref ! 247: "\\|^" ! 248: (regexp-quote ! 249: (substring fill ! 250: 0 (1- (length fill)))) ! 251: "$")) ! 252: (setq paragraph-separate paragraph-start)) ! 253: fill) ! 254: ) ! 255: ! 256: ! 257: ;;; ! 258: ;;; replace-letter - Given a string, an old letter and a new letter, ! 259: ;;; perform the substitution. ! 260: ;;; ! 261: (defun replace-letter (str old-letter new-letter) ! 262: (let (new-str c ! 263: (sp 0) ! 264: (size (length str))) ! 265: (while (< sp size) ! 266: (setq c (substring str sp (1+ sp))) ! 267: (setq new-str (concat new-str (if (string= c old-letter) new-letter c))) ! 268: (setq sp (1+ sp))) ! 269: new-str))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.