Function: modify-file-local-variable-prop-line

modify-file-local-variable-prop-line is a byte-compiled function defined in files-x.el.gz.

Signature

(modify-file-local-variable-prop-line VARIABLE VALUE OP &optional INTERACTIVE)

Documentation

Modify file-local VARIABLE in the -*- line depending on operation OP.

If OP is add-or-replace then delete all existing settings of VARIABLE (except mode and eval) and add a new file-local VARIABLE with VALUE to the -*- line.

If there is no -*- line at the beginning of the current file buffer and OP is not delete then this function adds the -*- line.

If OP is delete then delete all existing settings of VARIABLE from the -*- line ignoring the input argument VALUE.

If optional variable INTERACTIVE is non-nil, display a message telling the user how to make the new value take effect.

Source Code

;; Defined in /usr/src/emacs/lisp/files-x.el.gz
(defun modify-file-local-variable-prop-line (variable value op &optional interactive)
  "Modify file-local VARIABLE in the -*- line depending on operation OP.

If OP is `add-or-replace' then delete all existing settings of
VARIABLE (except `mode' and `eval') and add a new file-local VARIABLE
with VALUE to the -*- line.

If there is no -*- line at the beginning of the current file buffer
and OP is not `delete' then this function adds the -*- line.

If OP is `delete' then delete all existing settings of VARIABLE
from the -*- line ignoring the input argument VALUE.

If optional variable INTERACTIVE is non-nil, display a message telling
the user how to make the new value take effect."
  (catch 'exit
    (let ((beg (point)) end replaced-pos)
      (unless enable-local-variables
	(throw 'exit (message "File-local variables are disabled")))

      ;; Find the -*- line at the beginning of the current buffer.
      (widen)
      (goto-char (point-min))
      (setq end (set-auto-mode-1))

      (if end
	  (setq beg (point-marker) end (copy-marker end))

	;; Add the -*- line if not found.
	;; Don't add the -*- line for the deletion operation.
	(when (eq op 'delete)
	  (throw 'exit (progn (goto-char beg)
			      (message "The -*- line not found"))))

	(goto-char (point-min))

	;; Skip interpreter magic line "#!" or XML declaration.
	(when (or (looking-at file-auto-mode-skip)
		  (looking-at "<\\?xml[^>\n]*>$"))
	  (forward-line 1))

	(let ((comment-style 'plain)
	      (comment-start (or comment-start ";;; "))
	      (line-beg (line-beginning-position))
	      (ce nil))
	  (comment-normalize-vars)
	  ;; If the first line contains a comment.
	  (if (save-excursion
		(and (looking-at comment-start-skip)
		     (goto-char (match-end 0))
		     (re-search-forward comment-end-skip)
		     (goto-char (match-beginning 0))
		     ;; Still on the same line?
		     (equal line-beg (line-beginning-position))
		     (setq ce (point))))
	      ;; Add local variables to the end of the existing comment.
	      (progn
		(goto-char ce)
		(insert "  -*-")
		(setq beg (point-marker))
		(setq end (point-marker))
		(insert "-*-"))
	    ;; Otherwise, add a new comment before the first line.
	    (comment-region
	     (prog1 (point)
	       (insert "-*-")
	       (setq beg (point-marker))
	       (setq end (point-marker))
	       (insert "-*-\n"))
	     (point)))))

      (cond
       ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)")
	;; Simple form: "-*- MODENAME -*-".
	(if (eq variable 'mode)
	    ;; Replace or delete MODENAME
	    (progn
	      (when (member op '(add-or-replace delete))
		(delete-region (match-beginning 1) (match-end 1)))
	      (when (eq op 'add-or-replace)
		(goto-char (match-beginning 1))
		(insert (format "%S" value))))
	  ;; Else, turn `MODENAME' into `mode:MODENAME'
	  ;; and add `VARIABLE: VALUE;'
	  (goto-char (match-beginning 2))
	  (insert (format "; %S: %S; " variable value))
	  (goto-char (match-beginning 1))
	  (insert " mode: ")))

       (t
	;; Hairy form: '-*-' [ <variable> ':' <value> ';' ]* '-*-'
	;; Find and delete all existing variable/value pairs.
	(when (member op '(add-or-replace delete))
	  (if (and (eq op 'add-or-replace) (memq variable '(mode eval)))
	      (goto-char end)
	    (goto-char beg)
	    (while (< (point) end)
	      (or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*")
		  (throw 'exit (message "Malformed -*- line")))
	      (goto-char (match-end 0))
	      (let ((key (intern (match-string 1))))
                (save-restriction
                  (narrow-to-region (point) end)
                  (let ((read-circle nil))
                    (read (current-buffer))))
		(skip-chars-forward " \t;")
		(when (eq key variable)
		  (delete-region (match-beginning 0) (point))
		  (setq replaced-pos (point)))))))
	;; Add a new variable/value pair.  Add `mode' to the start, add new
	;; variable to the end, and add a replaced variable to its last location.
	(when (eq op 'add-or-replace)
	  (cond
	   ((eq variable 'mode) (goto-char beg))
	   ((null replaced-pos) (goto-char end))
	   (replaced-pos (goto-char replaced-pos)))
          (if (and (save-excursion
                     (skip-chars-backward " \t")
                     (not (eq (char-before) ?\;)))
		   (not (equal (point) (marker-position beg)))
		   ;; When existing `-*- -*-' is empty, beg > end.
		   (not (> (marker-position beg) (marker-position end))))
	      (insert ";"))
	  (unless (eq (char-before) ?\s) (insert " "))
	  (insert (format "%S: %S;" variable value))
	  (unless (eq (char-after) ?\s) (insert " ")))))

      (when interactive
	(modify-file-local-variable-message variable value op)))))