├── README.md └── rdoc-mode.el /README.md: -------------------------------------------------------------------------------- 1 | # elisp-rdoc-mode 2 | -------------------------------------------------------------------------------- /rdoc-mode.el: -------------------------------------------------------------------------------- 1 | ;;; rdoc-mode.el --- Major mode for RDoc editing 2 | ;; 3 | ;; Authors: Nobuyoshi Nakada 4 | ;; Akinori MUSHA 5 | ;; Maintainer: Nobuyoshi Nakada 6 | ;; Akinori MUSHA 7 | ;; Created: Fri Sep 18 09:04:49 JST 2009 8 | ;; URL: https://github.com/ruby/elisp-rdoc-mode 9 | ;; Keywords: rdoc ruby languages 10 | ;; License: The same license terms as Ruby 11 | ;; Version: 1.0.0 12 | 13 | ;;; Commentary: 14 | ;; 15 | ;; `rdoc-mode' is a major mode for editing RDoc files. 16 | 17 | (require 'derived) 18 | 19 | ;;;###autoload 20 | (define-derived-mode rdoc-mode text-mode "RDoc" 21 | "Major mode for RD editing. 22 | \\{rdoc-mode-map}" 23 | (make-local-variable 'paragraph-separate) 24 | (setq paragraph-separate "^\\(=+\\|\\*+\\)[ \t\v\f]*\\|^\\s *$") 25 | (make-local-variable 'paragraph-start) 26 | (setq paragraph-start paragraph-separate) 27 | (make-local-variable 'require-final-newline) 28 | (setq require-final-newline t) 29 | (make-local-variable 'font-lock-defaults) 30 | (setq font-lock-defaults '((rdoc-font-lock-keywords) t nil)) 31 | (make-local-variable 'font-lock-keywords) 32 | (setq font-lock-keywords rdoc-font-lock-keywords) 33 | (make-local-variable 'outline-regexp) 34 | (setq outline-regexp "^\\(=+\\)[ \t\v\f]*") 35 | (outline-minor-mode t) 36 | (setq show-trailing-whitespace t) 37 | (rdoc-setup-keys) 38 | (setq indent-tabs-mode nil) 39 | (run-hooks 'rdoc-mode-hook) 40 | ) 41 | 42 | (defun rdoc-fill-paragraph (&optional justify region) 43 | "Fills paragraph, except for cited region" 44 | (interactive (progn 45 | (barf-if-buffer-read-only) 46 | (list (if current-prefix-arg 'full)))) 47 | (save-excursion 48 | (beginning-of-line) 49 | (save-restriction 50 | (let ((pos (point)) beg end indent hanging) 51 | (cond 52 | ((looking-at "^ +\\(\\*\\s *\\)") 53 | (setq indent (- (match-end 0) (match-beginning 0)) 54 | hanging (- (match-end 1) (match-beginning 1)))) 55 | ((looking-at "^ +") 56 | (setq indent (- (match-end 0) (match-beginning 0))) 57 | (when (and (re-search-backward "^[^ ]\\|^\\( *\\(\\* *\\)\\)" nil t) 58 | (match-beginning 1) 59 | (= indent (- (match-end 1) (match-beginning 1)))) 60 | (setq hanging (- (match-end 2) (match-beginning 2))) 61 | (setq beg (match-beginning 1)))) 62 | ((setq beg t))) 63 | (when beg 64 | (when indent 65 | (goto-char pos) 66 | (while (progn (beginning-of-line 2) 67 | (and (looking-at "^\\( +\\)\\S ") 68 | (= indent (- (match-end 1) (match-beginning 1)))))) 69 | (setq end (point)) 70 | (when (and beg (not region)) 71 | (setq region (list beg end)) 72 | (narrow-to-region beg end) 73 | )) 74 | (goto-char pos) 75 | (fill-paragraph justify region) 76 | (when (and indent 77 | (or (goto-char beg) t) 78 | (or (beginning-of-line 2) t) 79 | (looking-at "^\\( +\\)") 80 | (= (- indent hanging) (- (match-end 0) (match-beginning 0)))) 81 | (insert-char ?\s hanging) 82 | (beginning-of-line) 83 | (narrow-to-region (point) end) 84 | (fill-paragraph justify (list (point) end)))))))) 85 | 86 | (defun rdoc-setup-keys () 87 | (interactive) 88 | (define-key rdoc-mode-map "\M-q" 'rdoc-fill-paragraph) 89 | ) 90 | 91 | (defvar rdoc-heading1-face 'font-lock-keyword-face) 92 | (defvar rdoc-heading2-face 'font-lock-type-face) 93 | (defvar rdoc-heading3-face 'font-lock-variable-name-face) 94 | (defvar rdoc-heading4-face 'font-lock-comment-face) 95 | (defvar rdoc-bold-face 'font-lock-function-name-face) 96 | (defvar rdoc-emphasis-face 'font-lock-function-name-face) 97 | (defvar rdoc-code-face 'font-lock-keyword-face) 98 | (defvar rdoc-description-face 'font-lock-constant-face) 99 | 100 | (defvar rdoc-font-lock-keywords 101 | (let ((heading "\\([^=\r\n].*\\)?$") 102 | (before "\\(^\\|[ \t\v\f]\\)") 103 | (after "\\($\\|[ \t\v\f,.:]\\)") 104 | (phrase "\\(?:[^<>]*\\|<\\(?:<=?\\|=>?\\)?\\|>>?=?\\)") 105 | (word "\\(\\sw\\|[-_:]\\)+")) 106 | (list 107 | (list (concat "^=" heading) 108 | 0 rdoc-heading1-face) 109 | (list (concat "^==" heading) 110 | 0 rdoc-heading2-face) 111 | (list (concat "^===" heading) 112 | 0 rdoc-heading3-face) 113 | (list "^====+.*$" 114 | 0 rdoc-heading4-face) 115 | (list (concat before "\\(\\*" word "\\*\\)" after) 116 | 2 rdoc-bold-face) ; *bold* 117 | (list (concat before "\\(_" word "_\\)" after) 118 | 2 rdoc-emphasis-face) ; _emphasis_ 119 | (list (concat before "\\(\\+" word "\\+\\)" after) 120 | 2 rdoc-code-face) ; +code+ 121 | (list (concat "" phrase "") 0 rdoc-emphasis-face) 122 | (list (concat "" phrase "") 0 rdoc-emphasis-face) 123 | (list (concat "" phrase "") 0 rdoc-bold-face) 124 | (list (concat "" phrase "") 0 rdoc-code-face) 125 | (list (concat "" phrase "") 0 rdoc-code-face) 126 | (list "^\\([-*]\\|[0-9]+\\.\\|[A-Za-z]\\.\\)\\s " 127 | 1 rdoc-description-face) ; bullet | numbered | alphabetically numbered 128 | (list "^\\[[^\\]]*\\]\\|\\S .*::\\)\\([ \t\v\f]\\|$\\)" 129 | 1 rdoc-description-face) ; labeled | node 130 | ;(list "^[ \t\v\f]+\\(.*\\)" 1 rdoc-verbatim-face) 131 | ))) 132 | 133 | (defun rdoc-imenu-create-index () 134 | (let ((root '(nil . nil)) 135 | cur-alist 136 | (cur-level 0) 137 | (pattern (concat outline-regexp "\\(.*?\\)[ \t\v\f]*$")) 138 | (empty-heading "-") 139 | (self-heading ".") 140 | pos level heading alist) 141 | (save-excursion 142 | (goto-char (point-min)) 143 | (while (re-search-forward pattern (point-max) t) 144 | (setq heading (match-string-no-properties 2) 145 | level (min 6 (length (match-string-no-properties 1))) 146 | pos (match-beginning 1)) 147 | (if (= (length heading) 0) 148 | (setq heading empty-heading)) 149 | (setq alist (list (cons heading pos))) 150 | (cond 151 | ((= cur-level level) ; new sibling 152 | (setcdr cur-alist alist) 153 | (setq cur-alist alist)) 154 | ((< cur-level level) ; first child 155 | (dotimes (i (- level cur-level 1)) 156 | (setq alist (list (cons empty-heading alist)))) 157 | (if cur-alist 158 | (let* ((parent (car cur-alist)) 159 | (self-pos (cdr parent))) 160 | (setcdr parent (cons (cons self-heading self-pos) alist))) 161 | (setcdr root alist)) ; primogenitor 162 | (setq cur-alist alist 163 | cur-level level)) 164 | (t ; new sibling of an ancestor 165 | (let ((sibling-alist (last (cdr root)))) 166 | (dotimes (i (1- level)) 167 | (setq sibling-alist (last (cdar sibling-alist)))) 168 | (setcdr sibling-alist alist) 169 | (setq cur-alist alist 170 | cur-level level)))))) 171 | (cdr root))) 172 | 173 | (defun rdoc-set-imenu-create-index-function () 174 | (setq imenu-create-index-function 'rdoc-imenu-create-index)) 175 | 176 | (add-hook 'rdoc-mode-hook 'rdoc-set-imenu-create-index-function) 177 | 178 | ;;;###autoload 179 | (add-to-list 'auto-mode-alist '("\\.rdoc\\'" . rdoc-mode)) 180 | 181 | (provide 'rdoc-mode) 182 | 183 | ;;; rdoc-mode.el ends here 184 | --------------------------------------------------------------------------------