diff options
Diffstat (limited to 'scripts/kde-emacs/dirvars.el')
-rw-r--r-- | scripts/kde-emacs/dirvars.el | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/scripts/kde-emacs/dirvars.el b/scripts/kde-emacs/dirvars.el new file mode 100644 index 00000000..5fba18e7 --- /dev/null +++ b/scripts/kde-emacs/dirvars.el @@ -0,0 +1,200 @@ +;;; -*- local-enable-local-variables: nil -*- +;;; dirvars.el --- Local variables that apply to an entire directory + +;; Copyright (C) 2002 Matt Armstrong + +;; Author: Matt Armstrong <matt@lickey.com> +;; Location: http://www.lickey.com/env/elisp/dirvars.el +;; Keywords: files +;; Version: 1.2 +;; Obscure: matt@squeaker.lickey.com|elisp/dirvars.el|20021213043855|48166 + +;; 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 Steet, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; Emacs allows you to specify local variable values for use when +;; editing a file either in the first line or in a local variables +;; list. +;; +;; This file provides similar functionality, but for an entire +;; directory tree. +;; +;; You simply place an .emacs-dirvars file in the root of your +;; project's tree, and you can then set emacs variables like you would +;; in a Local Variables: section at the end of a file. E.g. the +;; contents of a typical dirvars file might look like this: +;; +;; ;; -*- emacs-lisp -*- +;; ;; +;; ;; This file is processed by the dirvars emacs package. Each variable +;; ;; setting below is performed when this dirvars file is loaded. +;; ;; +;; indent-tabs-mode: nil +;; tab-width: 8 +;; show-trailing-whitespace: t +;; indicate-empty-lines: t +;; +;; Much of this code is stolen and modified from the standard Emacs +;; files.el +;; +;; This code refuses to set any symbol that meets any of these +;; criteria (this criteria is stolen from files.el): +;; +;; - the symbol is in the ignored-local-variables list +;; - the symbol has the risky-local-variable property. +;; - the symbol name ends in -hook(s), -function(s), -form(s), +;; -program, -command, or -predicate. + +;;; Todo: + +;; Implement the following changes to keep in line with elisp coding +;; conventions: When a package provides a modification of ordinary +;; Emacs behavior, it is good to include a command to enable and +;; disable the feature, Provide a command named `WHATEVER-mode' which +;; turns the feature on or off, and make it autoload (*note +;; Autoload::). Design the package so that simply loading it has no +;; visible effect--that should not enable the feature.(2) Users will +;; request the feature by invoking the command. +;; +;; Support customize? + +;;; Code: + +(defvar dirvars-enable-flag t + "*Control use of directory variables in files you visit. +The meaningful values are nil and non-nil.") + +(defun dirvars-find-upwards (file-name) + "Find a file in the current directory or one of its parents. + +Returns the fully qualified file name, or nil if it isn't found. + +The FILE-NAME specifies the file name to search for." + ;; Chase links in the source file and search in the dir where it + ;; points. + (setq dir-name (or (and buffer-file-name + (file-name-directory (file-chase-links + buffer-file-name))) + default-directory)) + ;; Chase links before visiting the file. This makes it easier to + ;; use a single file for several related directories. + (setq dir-name (file-chase-links dir-name)) + (setq dir-name (expand-file-name dir-name)) + ;; Move up in the dir hierarchy till we find a change log file. + (let ((file1 (concat dir-name file-name)) + parent-dir) + (while (and (not (file-exists-p file1)) + (progn (setq parent-dir + (file-name-directory + (directory-file-name + (file-name-directory file1)))) + ;; Give up if we are already at the root dir. + (not (string= (file-name-directory file1) + parent-dir)))) + ;; Move up to the parent dir and try again. + (setq file1 (expand-file-name file-name parent-dir))) + ;; If we found the file in a parent dir, use that. Otherwise, + ;; return nil + (if (or (get-file-buffer file1) (file-exists-p file1)) + file1 + nil))) + +(defun dirvars-eat-comment () + (while (looking-at "[ \t\n]*;") + (let ((begin (point))) + (skip-chars-forward " \t\n") + (if (looking-at ";") + (progn + (end-of-line) + (delete-region begin (point))))))) + +(defun dirvars-hack-local-variables (dirvars-file) + (save-excursion + (let ((original-buffer (current-buffer)) + (temp-buffer (get-buffer-create "*dirvars-temp*")) + (enable-local-variables (and ;local-enable-local-variables -- doesn't exist! + enable-local-variables + dirvars-enable-flag)) + (continue t) + (parse-sexp-ignore-comments t) + (lisp-mode-hook nil) + beg) + (set-buffer temp-buffer) + (erase-buffer) + (lisp-mode) + (insert-file dirvars-file) + (goto-char (point-min)) + (catch 'done + (while continue + (if (null (scan-sexps (point) 1)) + (throw 'done nil)) + (goto-char (scan-sexps (point) 1)) + (goto-char (scan-sexps (point) -1)) + (if (eobp) + (throw 'done nil)) + (setq beg (point)) + (skip-chars-forward "^:\n") + (if (not (looking-at ":")) + (error (format "Missing colon in directory variables entry at %d" + (point)))) + (skip-chars-backward " \t") + (let* ((str (buffer-substring beg (point))) + (var (read str)) + val) + ;; Read the variable value. + (skip-chars-forward "^:") + (forward-char 1) + (setq val (read (current-buffer))) + (save-excursion + (set-buffer original-buffer) + (dirvars-hack-one-local-variable dirvars-file + var val)))))))) + +(defun dirvars-hack-one-local-variable (dirvars-file var val) + "\"Set\" one variable in a local variables spec. +A few variable names are treated specially." + (cond ((memq var ignored-local-variables) + nil) + ;; Trap risky variables and such. This is the same logic + ;; that files.el uses. + ((or (get var 'risky-local-variable) + (and + (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$\\|-predicate$" + (symbol-name var)) + (not (get var 'safe-local-variable)))) + (message (format "Ignoring %s in %s" + (symbol-name var) dirvars-file))) + ;;check whether the var should be evaluated + ((eq var 'evaluate) + (eval val)) + ;; Ordinary variable, really set it. + (t (make-local-variable var) + (set var val)))) + +(defun dirvars-hack-local-variables-before () + (let ((dirvars-file (dirvars-find-upwards ".emacs-dirvars"))) + (if dirvars-file + (dirvars-hack-local-variables dirvars-file)))) + +(defadvice hack-local-variables + (before dirvars-hack-local-variables-before) + "Process dirvars before a file's local variables are processed." + (dirvars-hack-local-variables-before)) +(ad-activate 'hack-local-variables) + +(provide 'dirvars) +;;; dirvars.el ends here |