diff options
author | Pierre Courtieu <courtieu@lri.fr> | 2006-08-17 17:15:23 +0000 |
---|---|---|
committer | Pierre Courtieu <courtieu@lri.fr> | 2006-08-17 17:15:23 +0000 |
commit | 0cd45520c84be3822a248bd4acf1f9505416d64f (patch) | |
tree | 2eaffbad32bb067e251025157c45d658af8af348 /lib/local-vars-list.el | |
parent | ac2e639f94f49c3b76720d53575c25022d4d58cc (diff) |
continue on the support for local variables list semi-automatic
insertion. I put a new file in lib with basic tools for file variables
lists.
Diffstat (limited to 'lib/local-vars-list.el')
-rw-r--r-- | lib/local-vars-list.el | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/lib/local-vars-list.el b/lib/local-vars-list.el new file mode 100644 index 00000000..7038ebf9 --- /dev/null +++ b/lib/local-vars-list.el @@ -0,0 +1,226 @@ +;;; local-vars.el --- local variables list utilities +;; Copyright (C) 2006 Pierre Courtieu +;; Authors: Pierre Courtieu +;; Maintainer: Pierre Courtieu <Pierre.Courtieu@cnam.fr> + +;; This software is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public +;; License version 2, as published by the Free Software Foundation. +;; +;; This software 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 version 2 for more details +;; (enclosed in the file GPL). +;; +;; See documentation in variable holes-short-doc. +;; + +;;; Commentary: +;; See documentation in variable holes-doc. + +;;; History: +;; + +;;; Help: + +(defconst local-vars-list-doc nil + "Quoting emacs info: + +A file can contain a \"local variables list\", which specifies the values to use for +certain Emacs variables when that file is edited. See info node \"(xemacs)File +Variables\". + +local-vars-list provides two useful functions: + +\\[local-vars-list-get] that reads a local variable value at the end of the file. + +\\[local-vars-list-set] that writes a local variable value at the end of the file.") + +(defun local-vars-list-help (describe-variable 'local-vars-list-doc)) + +;;TOTO: use the code in xemacs-sources/lisp/files.el +;; in particular the function hack-local-variables-last-page + +(defun local-vars-list-insert-empty-zone () + "Insert an empty local variables zone at the end of the buffer. +Indents the zone according to mode after insertion." + (save-excursion + (goto-char (point-max)) + (let ((pt (point))) + (cond + ((not comment-start) + (insert + " +*** Local Variables: *** +*** End: *** +" + )) + + ((string-equal comment-end "") + (insert + (format + " +%s** Local Variables: *** +%s** End: *** +" + comment-start comment-start))) + + (t + (insert + (format + " +%s +*** Local Variables: *** +*** End: *** +%s" + comment-start comment-end)) + )) + (indent-region pt (point) nil) + (message "%s" "Local variables zone added at the end of the buffer.")))) + + +(defun local-vars-list-find () + "Find the local variable definition paragraph. +Return a list containing the prefix and the suffix of its first line, +or throw 'notfound if not found. Sets the point at the beginning of +the second line of the paragraph." + (goto-char (point-max)) + (catch 'notfound + (if (not (re-search-backward "Local Variables:" nil t)) (throw 'notfound nil)) + (let ((bol (save-excursion (beginning-of-line) (point))) + (eol (save-excursion (end-of-line) (point))) + (lpattern) + (rpattern)) + (setq lpattern (buffer-substring bol (point))) + (re-search-forward "Local Variables:" eol t) + (setq rpattern (buffer-substring (point) eol)) + (forward-line 1) + (beginning-of-line) + (cons lpattern (cons rpattern nil))))) + +(defun local-vars-list-goto-var (symb lpat rpat) + "Search a line defining local variable symb at current line and below. +If successful set point to the beginning of the *value* and return t. +Otherwise set point to the beginning of the last line of the local +variables list (the one containing \"End:\"), and return nil. + +lpat and rpat are the suffix and prefix of the local variable list. + +Note: this function must be called when at the beginning of a local +variable definition (or at the \"End:\" line)." + (let* ((symbname (symbol-name symb)) + (found nil) (endreached nil) + (eol)) + (while (and (not found) (not endreached)) + (setq eol (save-excursion (end-of-line) (point))) + (search-forward lpat eol) + (re-search-forward "\\([^ :]+\\):" eol) + (let ((varname (match-string 1))) + (message "varname = %s" varname) + (cond + ((string-equal varname "End") (setq endreached t) (beginning-of-line)) + ((string-equal varname symbname) (setq found t)) + (t (forward-line 1) (beginning-of-line)) + )) + (message "found %s" found) + (message "endreached %s" endreached) + ) + (if found t nil))) + + +; precond: really be on a var def line +(defun local-vars-list-get-current (lpat rpat) + "Return the value written in the local variable list at current line. + +lpat and rpat are the suffix and prefix of the local variable list. + +Note: this function must be called when at the beginning of a local +variable definition (or at the \"End:\" line)." + (let ((bol (save-excursion (beginning-of-line) (point))) + (eol (save-excursion (end-of-line) (point))) + (varname "")) + (catch 'notfound + (if (not (search-forward lpat eol t)) (throw 'notfound nil)) + (if (not (re-search-forward "\\([^ :]+\\):" eol t)) (throw 'notfound nil)) + (setq varname (match-string 1)) + (let ((boexp (point))) + (if (not (search-forward rpat eol t)) (throw 'notfound nil)) + (search-backward rpat bol) ; should always succeed + (read (buffer-substring boexp (point))))))) ; TODO: catch errors here? + + + +(defun local-vars-list-set-current (val lpat rpat) + "Write the value val in the local variable list at current line. + +lpat and rpat are the suffix and prefix of the local variable list. + +Note: this function must be called when at the beginning of a local +variable definition (or at the \"End:\" line)." + (let ((bol (save-excursion (beginning-of-line) (point))) + (eol (save-excursion (end-of-line) (point))) + (varname "")) + (search-forward lpat eol) + (re-search-forward "\\([^ :]+\\):" eol) + (setq varname (match-string 1)) + (let ((boexp (point))) + (search-forward rpat eol) + (search-backward rpat bol) + (kill-region boexp (point)) + (insert (format " %S " val)) + ) + ) + ) + + +(defun local-vars-list-get (symb) + "Return the value written in the local variable list for variable symb. +Raises an error if symb is not in the list." + (save-excursion + (let* + ((lrpat (local-vars-list-find)) + (dummy (if lrpat t (error "local variables zone not found. "))) + (lpat (car lrpat)) + (rpat (car (cdr lrpat))) + ) + (beginning-of-line) + (if (local-vars-list-goto-var symb lpat rpat) + t + (error "variable %s not found" symb)) + (beginning-of-line) + (local-vars-list-get-current lpat rpat)))) + +(defun local-vars-list-set (symb val) + "Write the value val in the local variable list for variable symb. +If the variable is already specified in the list, replace the value. If no local +variable list is found, create one at the end of the buffer first." + (save-excursion + (let ((lrpat (local-vars-list-find))) + (if (not lrpat) + (progn + (local-vars-list-insert-empty-zone) + (setq lrpat (local-vars-list-find)))) + (beginning-of-line) + (let ((lpat (car lrpat)) + (rpat (car (cdr lrpat)))) + (if (local-vars-list-goto-var symb lpat rpat) + (progn (beginning-of-line) + (local-vars-list-set-current val lpat rpat)) + (insert (format "%s%s: %S%s\n" lpat (symbol-name symb) val rpat)) + (forward-line -1) + (indent-according-to-mode)))))) + + +(provide 'local-vars-list) + + + +;;; Local Variables: *** +;;; fill-column: 85 *** +;;; indent-tabs-mode: nil *** +;;; End: *** + + + |