debian-changelog-mode.el 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. ;; debian-changelog.el --- change log maintenance for Debian-style changelogs
  2. ;; Keywords: maint
  3. ;; Copyright (C) 1996 Ian Jackson
  4. ;; This file is part of dpkg.
  5. ;;
  6. ;; It is free software; you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation; either version 2, or (at your option)
  9. ;; any later version.
  10. ;;
  11. ;; dpkg is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;;
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with your Debian installation, in /usr/doc/copyright/GPL.
  18. ;; If not, write to the Free Software Foundation, 675 Mass Ave,
  19. ;; Cambridge, MA 02139, USA.
  20. (require 'add-log)
  21. (defvar debian-changelog-urgencies
  22. '((?l."low") (?m."medium") (?h."HIGH"))
  23. "alist of keystrokes vs. urgency values debian-changelog-urgency ^c^u.")
  24. (defvar debian-changelog-distributions
  25. '((?s."stable") (?u."unstable") (?c."contrib") (?n."non-free") (?e."experimental"))
  26. "alist of keystrokes vs. distribution values for debian-changelog-distribution ^c^d.")
  27. (defvar debian-changelog-mode-map nil
  28. "Keymap for Debian changelog major mode.")
  29. (if debian-changelog-mode-map
  30. nil
  31. (setq debian-changelog-mode-map (make-sparse-keymap))
  32. (define-key debian-changelog-mode-map "\C-c\C-a" 'debian-changelog-add-entry)
  33. (define-key debian-changelog-mode-map "\C-c\C-f"
  34. 'debian-changelog-finalise-last-version)
  35. (define-key debian-changelog-mode-map "\C-c\C-c" 'debian-changelog-finalise-and-save)
  36. (define-key debian-changelog-mode-map "\C-c\C-v" 'debian-changelog-add-version)
  37. (define-key debian-changelog-mode-map "\C-c\C-d" 'debian-changelog-distribution)
  38. (define-key debian-changelog-mode-map "\C-c\C-u" 'debian-changelog-urgency)
  39. (define-key debian-changelog-mode-map "\C-c\C-e"
  40. 'debian-changelog-unfinalise-last-version))
  41. (defun debian-changelog-add-entry ()
  42. "Add a new change entry to a debian-style changelog."
  43. (interactive)
  44. (if (eq (debian-changelog-finalised-p) t)
  45. (error "most recent version has been finalised - use ^c^e or ^c^v"))
  46. (goto-char (point-min))
  47. (re-search-forward "\n --")
  48. (backward-char 5)
  49. (if (prog1 (looking-at "\n") (forward-char 1))
  50. nil
  51. (insert "\n"))
  52. (insert " * ")
  53. (save-excursion (insert "\n")))
  54. (defun debian-changelog-headervalue (arg re alist)
  55. (let (a b v k
  56. (lineend (save-excursion (end-of-line) (point))))
  57. (save-excursion
  58. (goto-char (point-min))
  59. (re-search-forward re lineend)
  60. (setq a (match-beginning 1)
  61. b (match-end 1))
  62. (goto-char a)
  63. (if arg nil
  64. (message (mapconcat
  65. (function (lambda (x) (format "%c:%s" (car x) (cdr x))))
  66. alist " "))
  67. (while (not v)
  68. (setq k (read-char))
  69. (setq v (assoc k alist))))
  70. (delete-region a b)
  71. (if arg nil (insert (cdr v))))
  72. (if arg (goto-char a))))
  73. (defun debian-changelog-urgency (arg)
  74. "Without argument, prompt for a key for a new urgency value (using
  75. debian-changelog-urgencies). With argument, delete the current urgency
  76. and position the cursor to type a new one."
  77. (interactive "P")
  78. (debian-changelog-headervalue
  79. arg
  80. "\\;[^\n]* urgency=\\(\\sw+\\)"
  81. debian-changelog-urgencies))
  82. (defun debian-changelog-distribution (arg)
  83. "Without argument, prompt for a key for a new distribution value (using
  84. debian-changelog-distributions). With argument, delete the current distribution
  85. and position the cursor to type a new one."
  86. (interactive "P")
  87. (debian-changelog-headervalue
  88. arg
  89. ") \\(.*\\)\\;"
  90. debian-changelog-distributions))
  91. (defun debian-changelog-finalised-p ()
  92. "Check whether the most recent debian-style changelog entry is
  93. finalised yet (ie, has a maintainer name and email address and a
  94. release date."
  95. (save-excursion
  96. (goto-char (point-min))
  97. (if (re-search-forward "\n\\S-" (point-max) t)
  98. (progn
  99. (if (re-search-backward "\n --" (point-min) t)
  100. (forward-char 4)
  101. (beginning-of-line)
  102. (insert " --\n\n")
  103. (backward-char 2))
  104. (cond
  105. ((looking-at "[ \n]+\\S-[^\n\t]+\\S- <[^ \t\n<>]+> \\S-[^\t\n]+\\S-[ \t]*\n")
  106. t)
  107. ((looking-at "[ \t]*\n")
  108. nil)
  109. (t
  110. "finalisation line has bad format (not ` -- maintainer <email> date')")))
  111. t)))
  112. (defun debian-changelog-add-version ()
  113. "Add a new version section to a debian-style changelog file."
  114. (interactive)
  115. (let ((f (debian-changelog-finalised-p)))
  116. (and (stringp f) (error f))
  117. (or f (error "previous version not yet finalised")))
  118. (goto-char (point-min))
  119. (let ((headstring
  120. (if (looking-at "\\(\\S-+ ([^()\n\t ]*[^0-9\n\t()]\\)\\([0-9]+\\)\\()[^\n]*\\)")
  121. (concat (match-string 1)
  122. (number-to-string (+ 1 (string-to-number (match-string 2))))
  123. (match-string 3))
  124. (let ((pkg (read-string "Package name: "))
  125. (ver (read-string "New version (including any revision): ")))
  126. (concat pkg " (" ver ") unstable; urgency="
  127. (cdr (car debian-changelog-urgencies)))))))
  128. (insert headstring "\n\n * ")
  129. (save-excursion
  130. (if (re-search-backward "\;[^\n]* urgency=\\(\\sw+\\)" (point-min) t)
  131. (progn (goto-char (match-beginning 1))
  132. (delete-region (point) (match-end 1))
  133. (insert (cdr (car debian-changelog-urgencies))))))
  134. (save-excursion (insert "\n\n --\n\n"))))
  135. (defun debian-changelog-finalise-and-save ()
  136. "Finalise, if necessary, and then save a debian-style changelog file."
  137. (interactive)
  138. (let ((f (debian-changelog-finalised-p)))
  139. (and (stringp f) (error f))
  140. (or f (debian-changelog-finalise-last-version)))
  141. (save-buffer))
  142. (defun debian-changelog-finalise-last-version ()
  143. "Remove the `finalisation' information (maintainer's name and email
  144. address and release date) so that new entries can be made."
  145. (interactive)
  146. (or add-log-full-name (setq add-log-full-name (user-full-name)))
  147. (or add-log-mailing-address (setq add-log-mailing-address user-mail-address))
  148. (and (debian-changelog-finalised-p) (debian-changelog-unfinalise-last-version))
  149. (save-excursion
  150. (goto-char (point-min))
  151. (re-search-forward "\n --\\([ \t]*\\)")
  152. (delete-region (match-beginning 1) (match-end 1))
  153. (insert " " add-log-full-name " <" add-log-mailing-address "> ")
  154. (let* ((dp "822-date")
  155. (r (call-process dp nil t)))
  156. (or (= r 0) (error (concat dp " returned error status " (prin1-to-string r)))))
  157. (backward-char)
  158. (or (looking-at "\n")
  159. (error (concat "expected newline after date from " dp)))
  160. (delete-char 1)))
  161. (defun debian-changelog-unfinalise-last-version ()
  162. "Remove the `finalisation' information (maintainer's name and email
  163. address and release date) so that new entries can be made."
  164. (interactive)
  165. (if (debian-changelog-finalised-p) nil
  166. (error "most recent version is not finalised"))
  167. (save-excursion
  168. (goto-char (point-min))
  169. (re-search-forward "\n --")
  170. (let ((dels (point)))
  171. (end-of-line)
  172. (delete-region dels (point)))))
  173. (defun debian-changelog-mode ()
  174. "Major mode for editing Debian-style change logs.
  175. Runs `debian-changelog-mode-hook' if it exists.
  176. Key bindings:
  177. \\{debian-changelog-mode-map}"
  178. (interactive)
  179. (kill-all-local-variables)
  180. (text-mode)
  181. (setq major-mode 'debian-changelog-mode
  182. mode-name "Debian changelog"
  183. left-margin 2
  184. fill-prefix " "
  185. fill-column 74)
  186. (use-local-map debian-changelog-mode-map)
  187. ;; Let each entry behave as one paragraph:
  188. (set (make-local-variable 'paragraph-start) "\\*")
  189. (set (make-local-variable 'paragraph-separate) "\\*\\|\\s-*$|\\S-")
  190. ;; Let each version behave as one page.
  191. ;; Match null string on the heading line so that the heading line
  192. ;; is grouped with what follows.
  193. (set (make-local-variable 'page-delimiter) "^\\<")
  194. (set (make-local-variable 'version-control) 'never)
  195. (run-hooks 'debian-changelog-mode-hook))
  196. (provide 'debian-changelog)