;;; cvs-admin-mode.el --- a mode for viewing/editing CVS modules files ;; ;; $Id: cvs-admin-mode.el,v 1.6 2007-11-11 05:13:28 gno Exp $ ;; Copyright (c) 2007 Greg Olszewski ;; ;; Author: Greg Olszewski ;; Keywords: ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; CVS Admin is a major mode for editing CVS repository config files ;; (stored under CVSROOT/). Files have 1 of three syntaxes in CVSROOT, ;; so expose 3 major modes, 1 for each syntax: ;; ;; cvs-admin-mode ;; cvs-admin-loginfo-mode ;; cvs-admin-modules-mode ;;; Usage: ;; Rename this file to cvs-admin-mode.el if it isn't already then place it in ;; your Emacs lisp path (eg. site-lisp) and add to your .emacs file: ;; (require 'cvs-admin-mode) ;; If you want colorization, turn on global-font-lock or ;; add this to your .emacs: ;; (add-hook 'cvs-admin-mode-hook 'turn-on-font-lock) ;;; Code: (require 'custom) (require 'font-lock) (defgroup cvs-admin nil "CVS admin file mode" :prefix "cvs-admin-" :group 'tools) (defcustom cvs-admin-loginfo-files '("commitinfo""editinfo" "loginfo" "notify" "preproxy" "postadmin" "posttag" "postwatch" "postproxy" "rcsinfo" "taginfo" "verifymsg") "*Files which use the loginfo syntax" :type '(repeat (string :tag "filename")) :group 'cvs-admin ) (defcustom cvs-admin-modules-files '("modules") "*Files which use the modules syntax" :type '(repeat (string :tag "filename")) :group 'cvs-admin ) (defcustom cvs-admin-generic-files '("checkoutlist" "config" "cvsignore" "cvswrappers" "options") "*Files which use the default syntax" :type '(repeat (string :tag "filename")) :group 'cvs-admin ) (defvar cvs-admin-font-lock-keywords '( ("^\\w+" 0 font-lock-function-name-face) ("\\(\"\\([^\"]\\|\\\"|\\\\\\)+\"\\)" 1 font-lock-string-face) ("\\('\\([^']\\|\'|\\\\\\)+'\\)" 1 font-lock-string-face) ("^\\(ALL\\|DEFAULT\\)" 1 font-lock-constant-face t) ("%{?\\(sVv\\|c\\|R\\|p\\|r\\|s\\)}?" 0 font-lock-keyword-face t) ("^\\s-*#.*$" 0 font-lock-comment-face t) ) "Font lock keywords used to highlight text CVS admin files." ) (defvar cvs-admin-font-lock-keywords-modules (append '(("\\s--[aioetudl]" 0 font-lock-keyword-face)) cvs-admin-font-lock-keywords ) "Font lock keywords used to highlight text in CVS modules file." ) (defvar cvs-admin-font-lock-keywords-loginfo (append '(("^\\(\\w+\\)\\(\\s-+.*\\)$" 1 font-lock-function-name-face)) cvs-admin-font-lock-keywords) "Font lock keywords used to highlight text in CVS loginfo style files." ) (defun cvs-admin-calc-indent-offset () (let* ((end (progn (save-excursion (beginning-of-line) (point)))) (start (progn (save-excursion (beginning-of-line) (backward-char) (backward-char) (point)))) (continuation (buffer-substring start end))) (cond ((string-match "\\\\" continuation) tab-width) (t 0)))) (defun cvs-admin-indent-line () "Indent a line according to CVSROOT rules" (interactive) (let ((depth (cvs-admin-calc-indent-offset)) (pos (- (point-max) (point))) (beg )) (message (format "depth %i" depth)) (beginning-of-line) (setq beg (point)) (skip-chars-forward " \t") (delete-region beg (point)) (indent-to depth) (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos))))) (defun cvs-admin-setup-auto-mode (derived-mode-list) (when derived-mode-list (let ((mode (car (car derived-mode-list))) (filelist (cdr (car derived-mode-list)))) (let ((fileregex (concat "\\(" (mapconcat 'identity filelist "\\|") "\\)\\'"))) (setq auto-mode-alist (cons (cons (concat "CVSROOT/" fileregex) mode) auto-mode-alist)))) (cvs-admin-setup-auto-mode (cdr derived-mode-list)))) (let ((derived-mode-list `( (cvs-admin-mode . ,cvs-admin-generic-files) (cvs-admin-loginfo-mode . ,cvs-admin-loginfo-files) (cvs-admin-modules-mode . ,cvs-admin-modules-files)))) (cvs-admin-setup-auto-mode derived-mode-list)) ;; Mode. (defun cvs-admin-font-lock-from-keywords (font-lock-keywords) (list font-lock-keywords nil nil '((?_ . "w") (?- . "w") (?. . "w") (?/ . "w") (?* . "w") (?^ . "w") (?$ . "w")))) (define-derived-mode cvs-admin-mode text-mode "CVSROOT admin files" "CVS Administrative Files mode" (set (make-local-variable 'font-lock-defaults) (cvs-admin-font-lock-from-keywords 'cvs-admin-font-lock-keywords)) (set (make-local-variable 'comment-start) "#") (set (make-local-variable 'comment-end) "") (set (make-local-variable 'comment-start-skip) ";+ *") ) (define-derived-mode cvs-admin-modules-mode cvs-admin-mode "CVSROOT modules" "Adapted `cvs-admin-mode' for the modules file" (define-key cvs-admin-modules-mode-map "\t" 'cvs-admin-indent-line) (setq font-lock-defaults (cvs-admin-font-lock-from-keywords 'cvs-admin-font-lock-keywords-modules)) ) (define-derived-mode cvs-admin-loginfo-mode cvs-admin-mode "CVSROOT info files" "Adapted `cvs-admin-mode' for the files sharing syntax with loginfo" (setq font-lock-defaults (cvs-admin-font-lock-from-keywords 'cvs-admin-font-lock-keywords-loginfo)) ) ;; done (provide 'cvs-admin-mode)