diff options
| author | Juri Linkov | 2009-08-04 23:52:06 +0000 |
|---|---|---|
| committer | Juri Linkov | 2009-08-04 23:52:06 +0000 |
| commit | b4d84ecfec33d4a2df59cb7d56052659c5cfe44f (patch) | |
| tree | d512ef7f3787843dc6cd4cc680600c95f024d599 | |
| parent | 82941b5e55d656bb56efa4d60cd62644d34f52e7 (diff) | |
| download | emacs-b4d84ecfec33d4a2df59cb7d56052659c5cfe44f.tar.gz emacs-b4d84ecfec33d4a2df59cb7d56052659c5cfe44f.zip | |
Commands to add/delete file/directory-local variables.
(read-file-local-variable, read-file-local-variable-value)
(read-file-local-variable-mode, modify-file-local-variable)
(modify-file-local-variable-prop-line)
(modify-dir-local-variable): New functions.
(add-file-local-variable, delete-file-local-variable)
(add-file-local-variable-prop-line, delete-file-local-variable-prop-line)
(add-dir-local-variable, delete-dir-local-variable)
(copy-file-locals-to-dir-locals, copy-dir-locals-to-file-locals)
(copy-dir-locals-to-file-locals-prop-line): New commands.
| -rw-r--r-- | lisp/ChangeLog | 13 | ||||
| -rw-r--r-- | lisp/files.el | 413 |
2 files changed, 426 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 42b40e1442f..dea01f1eea3 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2009-08-04 Juri Linkov <juri@jurta.org> | ||
| 2 | |||
| 3 | * files.el: Commands to add/delete file/directory-local variables. | ||
| 4 | (read-file-local-variable, read-file-local-variable-value) | ||
| 5 | (read-file-local-variable-mode, modify-file-local-variable) | ||
| 6 | (modify-file-local-variable-prop-line) | ||
| 7 | (modify-dir-local-variable): New functions. | ||
| 8 | (add-file-local-variable, delete-file-local-variable) | ||
| 9 | (add-file-local-variable-prop-line, delete-file-local-variable-prop-line) | ||
| 10 | (add-dir-local-variable, delete-dir-local-variable) | ||
| 11 | (copy-file-locals-to-dir-locals, copy-dir-locals-to-file-locals) | ||
| 12 | (copy-dir-locals-to-file-locals-prop-line): New commands. | ||
| 13 | |||
| 1 | 2009-08-04 Chong Yidong <cyd@stupidchicken.com> | 14 | 2009-08-04 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 15 | ||
| 3 | * abbrev.el (insert-abbrev-table-description): Prettify output. | 16 | * abbrev.el (insert-abbrev-table-description): Prettify output. |
diff --git a/lisp/files.el b/lisp/files.el index 5f256a016ca..ae28ee2610f 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -3407,6 +3407,419 @@ and `file-local-variables-alist', without applying them." | |||
| 3407 | (hack-local-variables-filter variables dir-name))))))) | 3407 | (hack-local-variables-filter variables dir-name))))))) |
| 3408 | 3408 | ||
| 3409 | 3409 | ||
| 3410 | ;;; Commands to add/delete file-local/directory-local variables. | ||
| 3411 | |||
| 3412 | (defun read-file-local-variable (prompt) | ||
| 3413 | "Read file-local variable using PROMPT and completion. | ||
| 3414 | Intended to be used in the `interactive' spec of | ||
| 3415 | `add-file-local-variable', `delete-file-local-variable', | ||
| 3416 | `add-dir-local-variable', `delete-dir-local-variable'." | ||
| 3417 | (let (default variable) | ||
| 3418 | (setq default (variable-at-point)) | ||
| 3419 | (setq default (and (symbolp default) (boundp default) | ||
| 3420 | (symbol-name default))) | ||
| 3421 | (setq variable | ||
| 3422 | (completing-read | ||
| 3423 | (if default | ||
| 3424 | (format "%s (default %s): " prompt default) | ||
| 3425 | (format "%s: " prompt)) | ||
| 3426 | obarray | ||
| 3427 | (lambda (sym) | ||
| 3428 | (or (user-variable-p sym) | ||
| 3429 | (memq sym '(mode eval coding unibyte)))) | ||
| 3430 | nil nil nil default nil)) | ||
| 3431 | (and (stringp variable) (intern variable)))) | ||
| 3432 | |||
| 3433 | (defun read-file-local-variable-value (variable) | ||
| 3434 | "Read value of file-local VARIABLE using completion. | ||
| 3435 | Intended to be used in the `interactive' spec of | ||
| 3436 | `add-file-local-variable' and `add-dir-local-variable'." | ||
| 3437 | (let (default value) | ||
| 3438 | (cond | ||
| 3439 | ((eq variable 'mode) | ||
| 3440 | (setq default (and (symbolp major-mode) (symbol-name major-mode))) | ||
| 3441 | (setq value | ||
| 3442 | (completing-read | ||
| 3443 | (if default | ||
| 3444 | (format "Add %s with value (default %s): " variable default) | ||
| 3445 | (format "Add %s with value: " variable)) | ||
| 3446 | obarray | ||
| 3447 | (lambda (sym) | ||
| 3448 | (and (string-match-p "-mode\\'" (symbol-name sym)) | ||
| 3449 | (not (string-match-p "-minor-mode\\'" (symbol-name sym))))) | ||
| 3450 | nil nil nil default nil)) | ||
| 3451 | (and (stringp value) | ||
| 3452 | (intern (replace-regexp-in-string "-mode\\'" "" value)))) | ||
| 3453 | ((eq variable 'eval) | ||
| 3454 | (let ((minibuffer-completing-symbol t)) | ||
| 3455 | (read-from-minibuffer (format "Add %s with expression: " variable) | ||
| 3456 | nil read-expression-map t | ||
| 3457 | 'read-expression-history))) | ||
| 3458 | ((eq variable 'coding) | ||
| 3459 | (setq default (and (symbolp buffer-file-coding-system) | ||
| 3460 | (symbol-name buffer-file-coding-system))) | ||
| 3461 | (read-coding-system | ||
| 3462 | (if default | ||
| 3463 | (format "Add %s with value (default %s): " variable default) | ||
| 3464 | (format "Add %s with value: " variable)) | ||
| 3465 | default)) | ||
| 3466 | (t | ||
| 3467 | (read (read-string (format "Add %s with value: " variable) | ||
| 3468 | nil 'set-variable-value-history | ||
| 3469 | (format "%S" (symbol-value variable)))))))) | ||
| 3470 | |||
| 3471 | (defun read-file-local-variable-mode () | ||
| 3472 | "Read per-directory file-local variable's mode using completion. | ||
| 3473 | Intended to be used in the `interactive' spec of | ||
| 3474 | `add-dir-local-variable', `delete-dir-local-variable'." | ||
| 3475 | (let* ((default (and (symbolp major-mode) (symbol-name major-mode))) | ||
| 3476 | (mode | ||
| 3477 | (completing-read | ||
| 3478 | (if default | ||
| 3479 | (format "Mode or subdirectory (default %s): " default) | ||
| 3480 | (format "Mode or subdirectory: ")) | ||
| 3481 | obarray | ||
| 3482 | (lambda (sym) | ||
| 3483 | (and (string-match-p "-mode\\'" (symbol-name sym)) | ||
| 3484 | (not (string-match-p "-minor-mode\\'" (symbol-name sym))))) | ||
| 3485 | nil nil nil default nil))) | ||
| 3486 | (cond | ||
| 3487 | ((equal mode "nil") nil) | ||
| 3488 | ((and (stringp mode) (fboundp (intern mode))) (intern mode)) | ||
| 3489 | (t mode)))) | ||
| 3490 | |||
| 3491 | (defun modify-file-local-variable (variable value op) | ||
| 3492 | "Modify file-local VARIABLE in Local Variables depending on operation OP. | ||
| 3493 | |||
| 3494 | If OP is `add-or-replace' then delete all existing settings of | ||
| 3495 | VARIABLE (except `mode' and `eval') and add a new file-local VARIABLE | ||
| 3496 | with VALUE to the Local Variables list. | ||
| 3497 | |||
| 3498 | If there is no Local Variables list in the current file buffer and OP | ||
| 3499 | is not `delete' then this function adds the first line containing the | ||
| 3500 | string `Local Variables:' and the last line containing the string `End:'. | ||
| 3501 | |||
| 3502 | If OP is `delete' then delete all existing settings of VARIABLE | ||
| 3503 | from the Local Variables list ignoring the input argument VALUE." | ||
| 3504 | (catch 'exit | ||
| 3505 | (let ((beg (point)) end replaced-pos) | ||
| 3506 | (unless enable-local-variables | ||
| 3507 | (throw 'exit (message "File-local variables are disabled"))) | ||
| 3508 | |||
| 3509 | ;; Look for "Local variables:" line in last page. | ||
| 3510 | (widen) | ||
| 3511 | (goto-char (point-max)) | ||
| 3512 | (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move) | ||
| 3513 | |||
| 3514 | ;; Add "Local variables:" list if not found. | ||
| 3515 | (unless (let ((case-fold-search t)) | ||
| 3516 | (search-forward "Local Variables:" nil t)) | ||
| 3517 | |||
| 3518 | ;; Don't add "Local variables:" list for the deletion operation. | ||
| 3519 | (when (eq op 'delete) | ||
| 3520 | (throw 'exit (progn (goto-char beg) | ||
| 3521 | (message "Local Variables not found")))) | ||
| 3522 | |||
| 3523 | (goto-char (point-max)) | ||
| 3524 | (let ((comment-style 'plain) | ||
| 3525 | (comment-start (or comment-start ";;; "))) | ||
| 3526 | (comment-region | ||
| 3527 | (prog1 (setq beg (point)) | ||
| 3528 | (insert "\nLocal Variables:\nEnd:\n")) | ||
| 3529 | (point))) | ||
| 3530 | |||
| 3531 | (unless (let ((case-fold-search t)) | ||
| 3532 | (goto-char beg) | ||
| 3533 | (search-forward "Local Variables:" nil t)) | ||
| 3534 | (throw 'exit (message "Can't add file-local variables")))) | ||
| 3535 | |||
| 3536 | ;; prefix is what comes before "local variables:" in its line. | ||
| 3537 | ;; suffix is what comes after "local variables:" in its line. | ||
| 3538 | (let* ((prefix (buffer-substring (line-beginning-position) | ||
| 3539 | (match-beginning 0))) | ||
| 3540 | (suffix (buffer-substring (point) (line-end-position))) | ||
| 3541 | (prefix-re (concat "^" (regexp-quote prefix))) | ||
| 3542 | (suffix-re (concat (regexp-quote suffix) "$"))) | ||
| 3543 | |||
| 3544 | ;; Find or add missing "End:". | ||
| 3545 | (forward-line 1) | ||
| 3546 | (setq beg (point)) | ||
| 3547 | (save-excursion | ||
| 3548 | (unless (let ((case-fold-search t)) | ||
| 3549 | (re-search-forward | ||
| 3550 | (concat prefix-re "[ \t]*End:[ \t]*" suffix-re) | ||
| 3551 | nil t)) | ||
| 3552 | (save-excursion | ||
| 3553 | (insert (format "%sEnd:%s\n" prefix suffix)))) | ||
| 3554 | (beginning-of-line) | ||
| 3555 | (setq end (point-marker))) | ||
| 3556 | |||
| 3557 | ;; Find and delete all existing variable/value pairs. | ||
| 3558 | (when (member op '(add-or-replace delete)) | ||
| 3559 | (if (and (eq op 'add-or-replace) (memq variable '(mode eval))) | ||
| 3560 | (goto-char end) | ||
| 3561 | (goto-char beg) | ||
| 3562 | (while (re-search-forward | ||
| 3563 | (format "%s%S:.*%s" prefix-re variable suffix-re) end t) | ||
| 3564 | (delete-region (match-beginning 0) (1+ (match-end 0))) | ||
| 3565 | (setq replaced-pos (point))))) | ||
| 3566 | |||
| 3567 | ;; Add a new variable/value pair. Add `mode' to the start, add new | ||
| 3568 | ;; variable to the end, and add a replaced variable to its last location. | ||
| 3569 | (when (eq op 'add-or-replace) | ||
| 3570 | (cond | ||
| 3571 | ((eq variable 'mode) (goto-char beg)) | ||
| 3572 | ((null replaced-pos) (goto-char end)) | ||
| 3573 | (replaced-pos (goto-char replaced-pos))) | ||
| 3574 | (insert (format "%s%S: %S%s\n" prefix variable value suffix))))))) | ||
| 3575 | |||
| 3576 | (defun add-file-local-variable (variable value) | ||
| 3577 | "Add file-local VARIABLE with its VALUE to the Local Variables list. | ||
| 3578 | |||
| 3579 | This command deletes all existing settings of VARIABLE (except `mode' | ||
| 3580 | and `eval') and adds a new file-local VARIABLE with VALUE to the | ||
| 3581 | Local Variables list. | ||
| 3582 | |||
| 3583 | If there is no Local Variables list in the current file buffer | ||
| 3584 | then this function adds the first line containing the string | ||
| 3585 | `Local Variables:' and the last line containing the string `End:'." | ||
| 3586 | (interactive | ||
| 3587 | (let ((variable (read-file-local-variable "Add file-local variable"))) | ||
| 3588 | (list variable (read-file-local-variable-value variable)))) | ||
| 3589 | (modify-file-local-variable variable value 'add-or-replace)) | ||
| 3590 | |||
| 3591 | (defun delete-file-local-variable (variable) | ||
| 3592 | "Delete all settings of file-local VARIABLE from the Local Variables list." | ||
| 3593 | (interactive | ||
| 3594 | (list (read-file-local-variable "Delete file-local variable"))) | ||
| 3595 | (modify-file-local-variable variable nil 'delete)) | ||
| 3596 | |||
| 3597 | (defun modify-file-local-variable-prop-line (variable value op) | ||
| 3598 | "Modify file-local VARIABLE in the -*- line depending on operation OP. | ||
| 3599 | |||
| 3600 | If OP is `add-or-replace' then delete all existing settings of | ||
| 3601 | VARIABLE (except `mode' and `eval') and add a new file-local VARIABLE | ||
| 3602 | with VALUE to the -*- line. | ||
| 3603 | |||
| 3604 | If there is no -*- line at the beginning of the current file buffer | ||
| 3605 | and OP is not `delete' then this function adds the -*- line. | ||
| 3606 | |||
| 3607 | If OP is `delete' then delete all existing settings of VARIABLE | ||
| 3608 | from the -*- line ignoring the input argument VALUE." | ||
| 3609 | (catch 'exit | ||
| 3610 | (let ((beg (point)) end replaced-pos) | ||
| 3611 | (unless enable-local-variables | ||
| 3612 | (throw 'exit (message "File-local variables are disabled"))) | ||
| 3613 | |||
| 3614 | ;; Find the -*- line at the beginning of the current buffer. | ||
| 3615 | (widen) | ||
| 3616 | (goto-char (point-min)) | ||
| 3617 | (setq end (set-auto-mode-1)) | ||
| 3618 | |||
| 3619 | (if end | ||
| 3620 | (setq beg (point) end (copy-marker end)) | ||
| 3621 | |||
| 3622 | ;; Add the -*- line if not found. | ||
| 3623 | ;; Don't add the -*- line for the deletion operation. | ||
| 3624 | (when (eq op 'delete) | ||
| 3625 | (throw 'exit (progn (goto-char beg) | ||
| 3626 | (message "The -*- line not found")))) | ||
| 3627 | |||
| 3628 | (goto-char (point-min)) | ||
| 3629 | |||
| 3630 | ;; Skip interpreter magic line "#!" | ||
| 3631 | (when (looking-at "^\\(#!\\|'\\\\\"\\)") | ||
| 3632 | (forward-line 1)) | ||
| 3633 | |||
| 3634 | (let ((comment-style 'plain) | ||
| 3635 | (comment-start (or comment-start ";;; "))) | ||
| 3636 | (comment-region | ||
| 3637 | (prog1 (point) | ||
| 3638 | (insert "-*-") | ||
| 3639 | (setq beg (point-marker)) | ||
| 3640 | (setq end (point-marker)) | ||
| 3641 | (insert "-*-\n")) | ||
| 3642 | (point)))) | ||
| 3643 | |||
| 3644 | (cond | ||
| 3645 | ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)") | ||
| 3646 | ;; Simple form: "-*- MODENAME -*-". | ||
| 3647 | (if (eq variable 'mode) | ||
| 3648 | ;; Replace or delete MODENAME | ||
| 3649 | (progn | ||
| 3650 | (when (member op '(add-or-replace delete)) | ||
| 3651 | (delete-region (match-beginning 1) (match-end 1))) | ||
| 3652 | (when (eq op 'add-or-replace) | ||
| 3653 | (goto-char (match-beginning 1)) | ||
| 3654 | (insert (format "%S" value)))) | ||
| 3655 | ;; Else, turn `MODENAME' into `mode:MODENAME' | ||
| 3656 | ;; and add `;VARIABLE:VALUE' | ||
| 3657 | (goto-char (match-beginning 2)) | ||
| 3658 | (insert (format "; %S: %S " variable value)) | ||
| 3659 | (goto-char (match-beginning 1)) | ||
| 3660 | (insert " mode: "))) | ||
| 3661 | |||
| 3662 | (t | ||
| 3663 | ;; Hairy form: '-*-' [ <variable> ':' <value> ';' ]* '-*-' | ||
| 3664 | ;; Find and delete all existing variable/value pairs. | ||
| 3665 | (when (member op '(add-or-replace delete)) | ||
| 3666 | (if (and (eq op 'add-or-replace) (memq variable '(mode eval))) | ||
| 3667 | (goto-char end) | ||
| 3668 | (goto-char beg) | ||
| 3669 | (while (< (point) end) | ||
| 3670 | (or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*") | ||
| 3671 | (throw 'exit (message "Malformed -*- line"))) | ||
| 3672 | (goto-char (match-end 0)) | ||
| 3673 | (let ((key (intern (match-string 1))) | ||
| 3674 | (val (save-restriction | ||
| 3675 | (narrow-to-region (point) end) | ||
| 3676 | (let ((read-circle nil)) | ||
| 3677 | (read (current-buffer)))))) | ||
| 3678 | (skip-chars-forward " \t;") | ||
| 3679 | (when (eq key variable) | ||
| 3680 | (delete-region (match-beginning 0) (point)) | ||
| 3681 | (setq replaced-pos (point))))))) | ||
| 3682 | ;; Add a new variable/value pair. Add `mode' to the start, add new | ||
| 3683 | ;; variable to the end, and add a replaced variable to its last location. | ||
| 3684 | (when (eq op 'add-or-replace) | ||
| 3685 | (cond | ||
| 3686 | ((eq variable 'mode) (goto-char beg)) | ||
| 3687 | ((null replaced-pos) (goto-char end) (insert "; ")) | ||
| 3688 | (replaced-pos (goto-char replaced-pos))) | ||
| 3689 | (insert (format "%S: %S" variable value)) | ||
| 3690 | (cond | ||
| 3691 | ((eq variable 'mode) (insert "; ")) | ||
| 3692 | (replaced-pos (insert "; ") )))))))) | ||
| 3693 | |||
| 3694 | (defun add-file-local-variable-prop-line (variable value) | ||
| 3695 | "Add file-local VARIABLE with its VALUE to the -*- line. | ||
| 3696 | |||
| 3697 | This command deletes all existing settings of VARIABLE (except `mode' | ||
| 3698 | and `eval') and adds a new file-local VARIABLE with VALUE to | ||
| 3699 | the -*- line. | ||
| 3700 | |||
| 3701 | If there is no -*- line at the beginning of the current file buffer | ||
| 3702 | then this function adds it." | ||
| 3703 | (interactive | ||
| 3704 | (let ((variable (read-file-local-variable "Add -*- file-local variable"))) | ||
| 3705 | (list variable (read-file-local-variable-value variable)))) | ||
| 3706 | (modify-file-local-variable-prop-line variable value 'add-or-replace)) | ||
| 3707 | |||
| 3708 | (defun delete-file-local-variable-prop-line (variable) | ||
| 3709 | "Delete all settings of file-local VARIABLE from the -*- line." | ||
| 3710 | (interactive | ||
| 3711 | (list (read-file-local-variable "Delete -*- file-local variable"))) | ||
| 3712 | (modify-file-local-variable-prop-line variable nil 'delete)) | ||
| 3713 | |||
| 3714 | (defun modify-dir-local-variable (mode variable value op) | ||
| 3715 | "Modify directory-local VARIABLE in .dir-locals.el depending on operation OP. | ||
| 3716 | |||
| 3717 | If OP is `add-or-replace' then delete all existing settings of | ||
| 3718 | VARIABLE (except `mode' and `eval') and add a new directory-local VARIABLE | ||
| 3719 | with VALUE to the MODE alist where MODE can be a mode name symbol or | ||
| 3720 | a subdirectory name. | ||
| 3721 | |||
| 3722 | If .dir-locals.el was not found and OP is not `delete' then create | ||
| 3723 | this file in the current directory. | ||
| 3724 | |||
| 3725 | If OP is `delete' then delete all existing settings of VARIABLE | ||
| 3726 | from the the MODE alist ignoring the input argument VALUE." | ||
| 3727 | (catch 'exit | ||
| 3728 | (unless enable-local-variables | ||
| 3729 | (throw 'exit (message "Directory-local variables are disabled"))) | ||
| 3730 | |||
| 3731 | (let ((variables-file (or (and (buffer-file-name) | ||
| 3732 | (not (file-remote-p (buffer-file-name))) | ||
| 3733 | (dir-locals-find-file (buffer-file-name))) | ||
| 3734 | dir-locals-file)) | ||
| 3735 | variables) | ||
| 3736 | |||
| 3737 | ;; Don't create ".dir-locals.el" for the deletion operation. | ||
| 3738 | (when (and (eq op 'delete) | ||
| 3739 | (not (file-exists-p variables-file))) | ||
| 3740 | (throw 'exit (message "File .dir-locals.el not found"))) | ||
| 3741 | |||
| 3742 | (let ((auto-insert nil)) | ||
| 3743 | (find-file variables-file)) | ||
| 3744 | (widen) | ||
| 3745 | (goto-char (point-min)) | ||
| 3746 | |||
| 3747 | ;; Read alist of directory-local variables. | ||
| 3748 | (ignore-errors | ||
| 3749 | (delete-region | ||
| 3750 | (prog1 (point) | ||
| 3751 | (setq variables (let ((read-circle nil)) | ||
| 3752 | (read (current-buffer))))) | ||
| 3753 | (point))) | ||
| 3754 | |||
| 3755 | ;; Add or replace variable in alist of directory-local variables. | ||
| 3756 | (let ((mode-assoc (assoc mode variables))) | ||
| 3757 | (if mode-assoc | ||
| 3758 | (setq variables | ||
| 3759 | (cons (cons mode | ||
| 3760 | (if (eq op 'delete) | ||
| 3761 | (assq-delete-all variable (cdr mode-assoc)) | ||
| 3762 | (cons | ||
| 3763 | (cons variable value) | ||
| 3764 | (if (memq variable '(mode eval)) | ||
| 3765 | (cdr mode-assoc) | ||
| 3766 | (assq-delete-all variable (cdr mode-assoc)))))) | ||
| 3767 | (assq-delete-all mode variables))) | ||
| 3768 | (setq variables | ||
| 3769 | (cons `(,mode . ((,variable . ,value))) | ||
| 3770 | variables)))) | ||
| 3771 | |||
| 3772 | ;; Insert modified alist of directory-local variables. | ||
| 3773 | (insert ";;; Directory Local Variables\n") | ||
| 3774 | (insert ";;; See Info node `(emacs) Directory Variables' for more information.\n\n") | ||
| 3775 | (pp (sort variables | ||
| 3776 | (lambda (a b) | ||
| 3777 | (cond | ||
| 3778 | ((null (car a)) t) | ||
| 3779 | ((null (car b)) nil) | ||
| 3780 | ((and (symbolp (car a)) (stringp (car b))) t) | ||
| 3781 | ((and (symbolp (car b)) (stringp (car a))) nil) | ||
| 3782 | (t (string< (car a) (car b)))))) | ||
| 3783 | (current-buffer))))) | ||
| 3784 | |||
| 3785 | (defun add-dir-local-variable (mode variable value) | ||
| 3786 | "Add directory-local VARIABLE with its VALUE and MODE to .dir-locals.el." | ||
| 3787 | (interactive | ||
| 3788 | (let (variable) | ||
| 3789 | (list | ||
| 3790 | (read-file-local-variable-mode) | ||
| 3791 | (setq variable (read-file-local-variable "Add directory-local variable")) | ||
| 3792 | (read-file-local-variable-value variable)))) | ||
| 3793 | (modify-dir-local-variable mode variable value 'add-or-replace)) | ||
| 3794 | |||
| 3795 | (defun delete-dir-local-variable (mode variable) | ||
| 3796 | "Delete all MODE settings of file-local VARIABLE from .dir-locals.el." | ||
| 3797 | (interactive | ||
| 3798 | (list | ||
| 3799 | (read-file-local-variable-mode) | ||
| 3800 | (read-file-local-variable "Delete directory-local variable"))) | ||
| 3801 | (modify-dir-local-variable mode variable nil 'delete)) | ||
| 3802 | |||
| 3803 | (defun copy-file-locals-to-dir-locals () | ||
| 3804 | "Copy file-local variables to .dir-locals.el." | ||
| 3805 | (interactive) | ||
| 3806 | (dolist (elt file-local-variables-alist) | ||
| 3807 | (unless (assq (car elt) dir-local-variables-alist) | ||
| 3808 | (add-dir-local-variable major-mode (car elt) (cdr elt))))) | ||
| 3809 | |||
| 3810 | (defun copy-dir-locals-to-file-locals () | ||
| 3811 | "Copy directory-local variables to the Local Variables list." | ||
| 3812 | (interactive) | ||
| 3813 | (dolist (elt dir-local-variables-alist) | ||
| 3814 | (add-file-local-variable (car elt) (cdr elt)))) | ||
| 3815 | |||
| 3816 | (defun copy-dir-locals-to-file-locals-prop-line () | ||
| 3817 | "Copy directory-local variables to the the -*- line." | ||
| 3818 | (interactive) | ||
| 3819 | (dolist (elt dir-local-variables-alist) | ||
| 3820 | (add-file-local-variable-prop-line (car elt) (cdr elt)))) | ||
| 3821 | |||
| 3822 | |||
| 3410 | (defcustom change-major-mode-with-file-name t | 3823 | (defcustom change-major-mode-with-file-name t |
| 3411 | "Non-nil means \\[write-file] should set the major mode from the file name. | 3824 | "Non-nil means \\[write-file] should set the major mode from the file name. |
| 3412 | However, the mode will not be changed if | 3825 | However, the mode will not be changed if |