1 ;;; crontab-mode.el --- Mode for editing crontab files
3 ;; ~/share/emacs/pkg/crontab/crontab-mode.el ---
5 ;; $Id: crontab-mode.el,v 1.18 2004/03/10 06:51:59 harley Exp $
8 ;; Author: Harley Gorrell <harley@mahalito.net>
9 ;; URL: http://www.mahalito.net/~harley/elisp/crontab-mode.el
11 ;; Keywords: cron, crontab, emacs
14 ;; * I want to keep my crontabs under rcs to keep a history of
15 ;; the file. Editing them with 'crontab -e' is rather
16 ;; cumbersome. My method is to keep the crontab as a file,
17 ;; under rcs, and check in the changes with 'C-c C-c' after
20 ;; * The remote systems are expected to share a filesystem.
21 ;; If they dont, modify crontab-shell or crontab-apply to
24 ;; * You may want to add one of these to your startup:
25 ;; (add-to-list 'auto-mode-alist '("\\.cron\\(tab\\)?\\'" . crontab-mode))
26 ;; (add-to-list 'auto-mode-alist '("cron\\(tab\\)?\\." . crontab-mode))
29 ;; 2003-03-16: Updated URL and contact info
30 ;; 2004-02-26: Use ssh to apply crontabs to remote hosts.
34 (defvar crontab-suffix ".crontab"
35 "*Suffix for crontab buffers.")
37 (defvar crontab-apply-after-save nil
38 "*Non-nil to apply the crontab after a save.")
39 (make-variable-buffer-local 'crontab-apply-after-save)
41 (defvar crontab-host nil
42 "*Hostname to use when saving the crontab to a remote host.")
43 (make-variable-buffer-local 'crontab-host)
45 (defvar crontab-user nil
46 "*Username to use when saving the crontab to a remote host.")
47 (make-variable-buffer-local 'crontab-user)
49 ;; Would be better to have "\\([0-9]\\([-,][0-9]+\\)+\\|...
50 (defvar crontab-unit-regexp "\\([-,0-9]+\\|\\*\\)"
51 "A regexp which matches a cron time unit.")
53 (defvar crontab-sep-regexp "[ \t]+"
54 "A regexp to match whitespace seperating cron time units.")
56 (defvar crontab-ruler "
57 # min hour day month day-of-week command
58 #(0-59) (0-23) (1-31) (1-12) (0-6)
60 #------------------------------------------------------------
62 "*The ruler `crontab-insert-ruler' inserts.")
65 (defvar crontab-mode-hook nil
66 "*Hook for customising `crontab-mode'.")
68 (defvar crontab-load-hook nil
69 "*Hook run when the `crontab-mode' is loaded.")
72 (defvar crontab-font-lock-keywords
75 '("^#.*$" . font-lock-comment-face)
76 ;; Blank lines are bad!
77 '("^[ \t]+$" . highlight)
79 '("^\\([A-Z_]+\\)=\\(.*\\)$" .
80 ((1 font-lock-keyword-face)
81 (2 font-lock-string-face)) )
83 ;; 50 * * * * /usr/gnu/bin/bash
86 crontab-unit-regexp crontab-sep-regexp
87 crontab-unit-regexp crontab-sep-regexp
88 crontab-unit-regexp crontab-sep-regexp
89 crontab-unit-regexp crontab-sep-regexp
90 crontab-unit-regexp crontab-sep-regexp
92 '((1 font-lock-keyword-face)
93 (2 font-lock-keyword-face)
94 (3 font-lock-keyword-face)
95 (4 font-lock-keyword-face)
96 (5 font-lock-keyword-face)
97 (6 font-lock-string-face))) )
98 "Info for function `font-lock-mode'.")
100 (defvar crontab-mode-map nil
101 "Keymap used in `crontab-mode'.")
105 (setq crontab-mode-map (make-sparse-keymap))
106 (define-key crontab-mode-map "\C-c\C-c" 'crontab-save-and-apply)
107 (define-key crontab-mode-map "\C-cc" 'crontab-save-and-apply)
108 (define-key crontab-mode-map "\C-ca" 'crontab-save-and-apply-to)
109 (define-key crontab-mode-map "\C-ci" 'crontab-insert-local-var)
110 (define-key crontab-mode-map "\C-cr" 'crontab-insert-ruler))
112 ;; This will barf without the correct agent or key setup.
113 (defvar crontab-rsh-cmd "ssh" ;; "rsh"
114 "Program to use for remote shells.")
116 (defun crontab-rsh-cmd ()
117 "Generate the rsh command. Redefine as needed."
119 (concat crontab-rsh-cmd " -l " (format "%s" crontab-user)) ;; str-ify
122 (defun crontab-localhost-p (&optional host)
123 "True if this is the same HOST Emacs is on."
126 (string= host "localhost")
127 (string= host (system-name))) )
129 (defun crontab-shell (host cmd out-buffer)
130 "On a possibly remote HOST, run CMD Output to OUT-BUFFER."
131 (when (not (crontab-localhost-p host))
132 (setq cmd (concat (crontab-rsh-cmd) " " host " " cmd)))
133 (shell-command cmd out-buffer) )
136 (defun crontab-mode ()
137 "Major mode for editing crontabs.
138 Defines commands for getting and applying crontabs for hosts.
139 Sets up command `font-lock-mode'.
141 \\{crontab-mode-map}"
144 (kill-all-local-variables)
145 (setq mode-name "crontab")
146 (setq major-mode 'crontab-mode)
147 (use-local-map crontab-mode-map)
149 (setq comment-start "#")
150 (setq comment-start-skip "#+ *")
152 (make-local-variable 'font-lock-defaults)
153 (setq font-lock-defaults '(crontab-font-lock-keywords))
154 ;; Add to the end of the buffers save hooks.
155 (add-hook 'after-save-hook 'crontab-after-save t t)
157 (run-hooks 'crontab-mode-hook) )
161 (defun crontab-get (host)
162 "Get the crontab for the HOST into a buffer."
163 (interactive "sCrontab for host:")
164 (let ((cbn (generate-new-buffer-name (concat host crontab-suffix))))
165 (switch-to-buffer-other-window cbn)
168 (crontab-insert host)
170 (setq crontab-host host)) )
172 (defun crontab-insert (&optional host)
173 "Insert the crontab for the HOST into the current buffer."
174 (crontab-shell host "crontab -l" t) )
176 (defun crontab-apply (&optional host)
177 "Apply the crontab to a HOST. The filesystem must be common."
178 (if (buffer-file-name)
179 (crontab-shell host (concat "crontab " (buffer-file-name)) nil)
180 (error "No filename for this buffer")))
182 (defun crontab-save-and-apply ()
183 "Save and apply the buffer to the HOST."
186 (if (not crontab-apply-after-save) ;; Dont apply it twice.
187 (crontab-apply (crontab-host))) )
189 (defun crontab-save-and-apply-to (host)
190 "Prompt for the HOST and apply the file."
191 (interactive "sApply to host:")
192 (setq crontab-host host) ;; remember the change
193 (crontab-save-and-apply) )
195 (defun crontab-insert-ruler ()
196 "Insert a ruler with comments into the crontab."
199 (insert crontab-ruler) )
201 (defun crontab-insert-local-var ()
202 "Insert the current values of buffer local variables."
206 " comment-start " Local " "Variables:
207 " comment-start " mode: " (format "%s" (or mode-name "crontab")) "
208 " comment-start " crontab-host: " (crontab-host) "
209 " comment-start " crontab-apply-after-save: "
210 (format "%s" crontab-apply-after-save) "
211 " comment-start " End:
214 (defun crontab-host ()
215 "Return the hostname as a string, defaulting to the local host.
216 The variable `crontab-host' could be a symbol or a string."
217 (format "%s" (or crontab-host system-name)) )
220 (defun crontab-after-save ()
221 "If `crontab-apply-after-save' is set, apply the crontab after a save."
222 (if crontab-apply-after-save (crontab-apply (crontab-host))) )
224 (provide 'crontab-mode)
225 (run-hooks 'crontab-load-hook)
227 ;;; crontab-mode.el ends here