Warning, /sdk/kde-dev-scripts/kde-emacs/dirvars.el is written in an unsupported language. File is not indexed.

0001 ;;; -*- local-enable-local-variables: nil -*-
0002 ;;; dirvars.el --- Local variables that apply to an entire directory
0003 
0004 ;; Copyright (C) 2002  Matt Armstrong
0005 
0006 ;; Author: Matt Armstrong <matt@lickey.com>
0007 ;; Location: http://www.lickey.com/env/elisp/dirvars.el
0008 ;; Keywords: files
0009 ;; Version: 1.2
0010 ;; Obscure: matt@squeaker.lickey.com|elisp/dirvars.el|20021213043855|48166
0011 
0012 ;; This file is free software; you can redistribute it and/or modify
0013 ;; it under the terms of the GNU General Public License as published by
0014 ;; the Free Software Foundation; either version 2, or (at your option)
0015 ;; any later version.
0016 
0017 ;; This file is distributed in the hope that it will be useful,
0018 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
0019 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0020 ;; GNU General Public License for more details.
0021 
0022 ;; You should have received a copy of the GNU General Public License
0023 ;; along with GNU Emacs; see the file COPYING.  If not, write to
0024 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0025 ;; Boston, MA 02110-1301, USA.
0026 
0027 ;;; Commentary:
0028 
0029 ;; Emacs allows you to specify local variable values for use when
0030 ;; editing a file either in the first line or in a local variables
0031 ;; list.
0032 ;;
0033 ;; This file provides similar functionality, but for an entire
0034 ;; directory tree.
0035 ;;
0036 ;; You simply place an .emacs-dirvars file in the root of your
0037 ;; project's tree, and you can then set emacs variables like you would
0038 ;; in a Local Variables: section at the end of a file.  E.g. the
0039 ;; contents of a typical dirvars file might look like this:
0040 ;;
0041 ;;    ;; -*- emacs-lisp -*-
0042 ;;    ;;
0043 ;;    ;; This file is processed by the dirvars emacs package.  Each variable
0044 ;;    ;; setting below is performed when this dirvars file is loaded.
0045 ;;    ;;
0046 ;;    indent-tabs-mode: nil
0047 ;;    tab-width: 8
0048 ;;    show-trailing-whitespace: t
0049 ;;    indicate-empty-lines: t
0050 ;;
0051 ;; Much of this code is stolen and modified from the standard Emacs
0052 ;; files.el
0053 ;;
0054 ;; This code refuses to set any symbol that meets any of these
0055 ;; criteria (this criteria is stolen from files.el):
0056 ;;
0057 ;;   - the symbol is in the ignored-local-variables list
0058 ;;   - the symbol has the risky-local-variable property.
0059 ;;   - the symbol name ends in -hook(s), -function(s), -form(s),
0060 ;;     -program, -command, or -predicate.
0061 
0062 ;;; Todo:
0063 
0064 ;; Implement the following changes to keep in line with elisp coding
0065 ;; conventions: When a package provides a modification of ordinary
0066 ;; Emacs behavior, it is good to include a command to enable and
0067 ;; disable the feature, Provide a command named `WHATEVER-mode' which
0068 ;; turns the feature on or off, and make it autoload (*note
0069 ;; Autoload::).  Design the package so that simply loading it has no
0070 ;; visible effect--that should not enable the feature.(2) Users will
0071 ;; request the feature by invoking the command.
0072 ;;
0073 ;; Support customize?
0074 
0075 ;;; Code:
0076 
0077 (defvar dirvars-enable-flag t
0078   "*Control use of directory variables in files you visit.
0079 The meaningful values are nil and non-nil.")
0080 
0081 (defun dirvars-find-upwards (file-name)
0082   "Find a file in the current directory or one of its parents.
0083 
0084 Returns the fully qualified file name, or nil if it isn't found.
0085 
0086 The FILE-NAME specifies the file name to search for."
0087   ;; Chase links in the source file and search in the dir where it
0088   ;; points.
0089   (setq dir-name (or (and buffer-file-name
0090                           (file-name-directory (file-chase-links
0091                                                 buffer-file-name)))
0092                      default-directory))
0093   ;; Chase links before visiting the file.  This makes it easier to
0094   ;; use a single file for several related directories.
0095   (setq dir-name (file-chase-links dir-name))
0096   (setq dir-name (expand-file-name dir-name))
0097   ;; Move up in the dir hierarchy till we find a change log file.
0098   (let ((file1 (concat dir-name file-name))
0099         parent-dir)
0100     (while (and (not (file-exists-p file1))
0101                 (progn (setq parent-dir
0102                              (file-name-directory
0103                               (directory-file-name
0104                                (file-name-directory file1))))
0105                        ;; Give up if we are already at the root dir.
0106                        (not (string= (file-name-directory file1)
0107                                      parent-dir))))
0108       ;; Move up to the parent dir and try again.
0109       (setq file1 (expand-file-name file-name parent-dir)))
0110     ;; If we found the file in a parent dir, use that.  Otherwise,
0111     ;; return nil
0112     (if (or (get-file-buffer file1) (file-exists-p file1))
0113         file1
0114       nil)))
0115 
0116 (defun dirvars-eat-comment ()
0117   (while (looking-at "[ \t\n]*;")
0118     (let ((begin (point)))
0119       (skip-chars-forward " \t\n")
0120       (if (looking-at ";")
0121           (progn
0122             (end-of-line)
0123             (delete-region begin (point)))))))
0124 
0125 (defun dirvars-hack-local-variables (dirvars-file)
0126   (save-excursion
0127     (let ((original-buffer (current-buffer))
0128           (temp-buffer (get-buffer-create "*dirvars-temp*"))
0129           (enable-local-variables (and ;local-enable-local-variables  -- doesn't exist!
0130                                        enable-local-variables
0131                                        dirvars-enable-flag))
0132           (continue t)
0133           (parse-sexp-ignore-comments t)
0134           (lisp-mode-hook nil)
0135           beg)
0136       (set-buffer temp-buffer)
0137       (erase-buffer)
0138       (lisp-mode)
0139       (insert-file dirvars-file)
0140       (goto-char (point-min))
0141       (catch 'done
0142         (while continue
0143           (if (null (scan-sexps (point) 1))
0144               (throw 'done nil))
0145           (goto-char (scan-sexps (point) 1))
0146           (goto-char (scan-sexps (point) -1))
0147           (if (eobp)
0148               (throw 'done nil))
0149           (setq beg (point))
0150           (skip-chars-forward "^:\n")
0151           (if (not (looking-at ":"))
0152               (error (format "Missing colon in directory variables entry at %d"
0153                              (point))))
0154           (skip-chars-backward " \t")
0155           (let* ((str (buffer-substring beg (point)))
0156                  (var (read str))
0157                  val)
0158             ;; Read the variable value.
0159             (skip-chars-forward "^:")
0160             (forward-char 1)
0161             (setq val (read (current-buffer)))
0162             (save-excursion
0163               (set-buffer original-buffer)
0164               (dirvars-hack-one-local-variable dirvars-file
0165                                                var val))))))))
0166 
0167 (defun dirvars-hack-one-local-variable (dirvars-file var val)
0168   "\"Set\" one variable in a local variables spec.
0169 A few variable names are treated specially."
0170   (cond ((memq var ignored-local-variables)
0171          nil)
0172         ;; Trap risky variables and such.  This is the same logic
0173         ;; that files.el uses.
0174         ((or (get var 'risky-local-variable)
0175              (and
0176               (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$\\|-predicate$"
0177                             (symbol-name var))
0178               (not (get var 'safe-local-variable))))
0179          (message (format "Ignoring %s in %s"
0180                           (symbol-name var) dirvars-file)))
0181         ;;check whether the var should be evaluated
0182         ((eq var 'evaluate)
0183          (eval val))
0184         ;; Ordinary variable, really set it.
0185         (t (make-local-variable var)
0186            (set var val))))
0187 
0188 (defun dirvars-hack-local-variables-before ()
0189   (let ((dirvars-file (dirvars-find-upwards ".emacs-dirvars")))
0190     (if dirvars-file
0191         (dirvars-hack-local-variables dirvars-file))))
0192 
0193 (defadvice hack-local-variables
0194   (before dirvars-hack-local-variables-before)
0195   "Process dirvars before a file's local variables are processed."
0196   (dirvars-hack-local-variables-before))
0197 (ad-activate 'hack-local-variables)
0198 
0199 (provide 'dirvars)
0200 ;;; dirvars.el ends here