emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Custom themes


From: Luc Teirlinck
Subject: Re: Custom themes
Date: Tue, 28 Jun 2005 22:17:05 -0500 (CDT)

Unfortunately, after taking a closer look at it, things are way worse
than I originally thought.  It does not appear that there is _any_
support for undoing the requiring of an individual theme in the
current code.  You can apparently more or less undo all themes
together (although you have to ask to undo one single theme to get
that effect), but one can not undo just one particular theme.

The function `custom-do-theme-reset' does not do what I thought it
did.  I was mislead by its docstring.  That docstring is terrible.

    "Undo all settings defined by THEME.

  A variable remains unchanged if its property `theme-value' does not
  contain a value for THEME.  A face remains unchanged if its property
  `theme-face' does not contain a value for THEME.  In either case, all
  settings for THEME are removed from the property and the variable or
  face is set to the `user' theme.

The docstring contadicts itself.  A variable remains _un_changed if...
A face remains _un_changed if...  In either case, the variable or face
_is_ changed to the 'user' theme.  Which of the two?  What happens in
other cases?  Not only do both statements in the docstring say
opposite things, they are _both_ wrong.

What really happens is that _all_ variables and faces get reset to the
user theme whenever they _have_ a `theme-value' or `theme-face'
property, _regardless_ of whether the `theme-value' or `theme-face'
property contains a value for THEME or not.  What the function does is
setting _everything_ back to the `user' theme, that is, it undoes the
effects of all loaded themes, regardless of the value of THEME.

Fixing this function or most related stuff in the Custom Themes code
seems hopeless.  This function's code (and much of the related code)
appears to be as incoherent as its docstring.  The entire Custom
themes implementation appears to be completely unfinished at best.

However, the _enabling_ of Custom themes actually appears to work.
What I could do is install the following revised version of my
patches.  I believe this version is now sufficiently tested.

===File ~/cus-theme.el-diff=================================
*** cus-theme.el        17 Apr 2005 15:28:09 -0500      1.8
--- cus-theme.el        28 Jun 2005 20:33:02 -0500      
***************
*** 31,36 ****
--- 31,48 ----
  (eval-when-compile
    (require 'wid-edit))
  
+ (define-derived-mode custom-new-theme-mode nil "New-Theme"
+   "Major mode for the buffer created by `customize-create-theme'.
+ Do not call this mode function yourself.  It is only meant for internal
+ use by `customize-create-theme'."
+   (set-keymap-parent custom-new-theme-mode-map widget-keymap))
+ (put 'custom-new-theme-mode 'mode-class 'special)
+ 
+ (defvar custom-theme-name)
+ (defvar custom-theme-variables)
+ (defvar custom-theme-faces)
+ (defvar custom-theme-description)
+ 
  ;;;###autoload
  (defun customize-create-theme ()
    "Create a custom theme."
***************
*** 38,52 ****
    (if (get-buffer "*New Custom Theme*")
        (kill-buffer "*New Custom Theme*"))
    (switch-to-buffer "*New Custom Theme*")
!   (kill-all-local-variables)
    (make-local-variable 'custom-theme-name)
    (make-local-variable 'custom-theme-variables)
    (make-local-variable 'custom-theme-faces)
    (make-local-variable 'custom-theme-description)
-   (let ((inhibit-read-only t))
-     (erase-buffer))
    (widget-insert "This buffer helps you write a custom theme elisp file.
! This will help you share your customizations with other people.\n\n")
    (widget-insert "Theme name: ")
    (setq custom-theme-name
        (widget-create 'editable-field
--- 50,72 ----
    (if (get-buffer "*New Custom Theme*")
        (kill-buffer "*New Custom Theme*"))
    (switch-to-buffer "*New Custom Theme*")
!   (let ((inhibit-read-only t))
!     (erase-buffer))
!   (custom-new-theme-mode)
    (make-local-variable 'custom-theme-name)
    (make-local-variable 'custom-theme-variables)
    (make-local-variable 'custom-theme-faces)
    (make-local-variable 'custom-theme-description)
    (widget-insert "This buffer helps you write a custom theme elisp file.
! This will help you share your customizations with other people.
! 
! Just insert the names of all variables and faces you want the theme
! to include.  Then clicking mouse-2 or pressing RET on the [Done] button
! will write a theme file that sets all these variables and faces to their
! current global values.  It will write that file into the directory given
! by the variable `custom-theme-directory', usually \"~/.emacs.d/\".
! 
! To undo all your edits to the buffer, use the [Reset] button.\n\n")
    (widget-insert "Theme name: ")
    (setq custom-theme-name
        (widget-create 'editable-field
***************
*** 81,87 ****
                           (bury-buffer))
                 "Bury Buffer")
    (widget-insert "\n")
-   (use-local-map widget-keymap)
    (widget-setup))
  
  (defun custom-theme-write (&rest ignore)
--- 101,106 ----
***************
*** 90,98 ****
--- 109,143 ----
        (variables (widget-value custom-theme-variables))
        (faces (widget-value custom-theme-faces)))
      (switch-to-buffer (concat name "-theme.el"))
+     (emacs-lisp-mode)
+     (unless (file-exists-p custom-theme-directory)
+       (make-directory (file-name-as-directory custom-theme-directory) t))
+     (setq default-directory custom-theme-directory)
      (setq buffer-file-name (expand-file-name (concat name "-theme.el")))
      (let ((inhibit-read-only t))
        (erase-buffer))
+     (insert (format ";; This file is the Custom theme file for the theme %s.
+ 
+ ;; If enabled, it sets the variables and faces listed below to the given
+ ;; values.  To enable it, type `M-x require-theme RET %s',
+ ;; or just load this file.
+ 
+ ;; You can also write `(require-theme '%s)' (or load
+ ;; this file) in your .emacs file.  If you do that before the
+ ;; `custom-set-variables' and `custom-set-faces' forms, any values
+ ;; explicitly given in these forms take precedence.  If you write it
+ ;; after these forms, the theme takes precedence.
+ 
+ ;; For the command `require-theme' to work, this file should be in a
+ ;; directory in `load-path', or in the directory given by
+ ;; `custom-theme-directory' (usually \"~/.emacs.d/\"), which is the
+ ;; directory in which `custom-theme-create' writes the theme files it
+ ;; produces.
+ 
+ ;; Requiring a theme that is already loaded has no effect.  You have to
+ ;; load this file directly if you want to reinstall settings that got
+ ;; overridden.\n\n"
+                   name name name))
      (insert "(deftheme " name)
      (when doc
        (newline)
***************
*** 100,106 ****
      (insert  ")\n")
      (custom-theme-write-variables name variables)
      (custom-theme-write-faces name faces)
!     (insert "\n(provide-theme '" name ")\n")))
  
  (defun custom-theme-write-variables (theme vars)
    "Write a `custom-theme-set-variables' command for THEME.
--- 145,152 ----
      (insert  ")\n")
      (custom-theme-write-variables name variables)
      (custom-theme-write-faces name faces)
!     (insert "\n(provide-theme '" name ")\n")
!     (save-buffer)))
  
  (defun custom-theme-write-variables (theme vars)
    "Write a `custom-theme-set-variables' command for THEME.
============================================================

===File ~/custom.el-diff====================================
*** custom.el   13 Apr 2005 13:49:27 -0500      1.83
--- custom.el   28 Jun 2005 19:36:19 -0500      
***************
*** 560,566 ****
              (t (condition-case nil (load load) (error nil))))))))
  
  (defvar custom-known-themes '(user standard)
!    "Themes that have been define with `deftheme'.
  The default value is the list (user standard).  The theme `standard'
  contains the Emacs standard settings from the original Lisp files.  The
  theme `user' contains all the the settings the user customized and saved.
--- 560,566 ----
              (t (condition-case nil (load load) (error nil))))))))
  
  (defvar custom-known-themes '(user standard)
!    "Themes that have been defined with `deftheme'.
  The default value is the list (user standard).  The theme `standard'
  contains the Emacs standard settings from the original Lisp files.  The
  theme `user' contains all the the settings the user customized and saved.
***************
*** 926,931 ****
--- 926,944 ----
  (defvar custom-loaded-themes nil
    "Themes in the order they are loaded.")
  
+ (defcustom custom-theme-directory
+   (if (eq system-type 'ms-dos)
+        ;; MS-DOS cannot have initial dot.
+        "~/_emacs.d/"
+       "~/.emacs.d/")
+   "Directory in which Custom theme files should be written.
+ `require-theme' searches this directory in addition to load-path.
+ The command `customize-create-theme' writes the files it produces
+ into this directory."
+   :type 'string
+   :group 'customize
+   :version "22.1")
+ 
  (defun custom-theme-loaded-p (theme)
    "Return non-nil when THEME has been loaded."
    (memq theme custom-loaded-themes))
***************
*** 949,956 ****
  by `custom-make-theme-feature'."
    ;; Note we do no check for validity of the theme here.
    ;; This allows to pull in themes by a file-name convention
!   (require (or (get theme 'theme-feature)
!              (custom-make-theme-feature theme))))
  
  (defun custom-remove-theme (spec-alist theme)
    "Delete all elements from SPEC-ALIST whose car is THEME."
--- 962,973 ----
  by `custom-make-theme-feature'."
    ;; Note we do no check for validity of the theme here.
    ;; This allows to pull in themes by a file-name convention
!   (interactive "SAdd theme: ")
!   (let ((load-path (if (file-directory-p custom-theme-directory)
!                      (cons custom-theme-directory load-path)
!                    load-path)))
!     (require (or (get theme 'theme-feature)
!                (custom-make-theme-feature theme)))))
  
  (defun custom-remove-theme (spec-alist theme)
    "Delete all elements from SPEC-ALIST whose car is THEME."
============================================================




reply via email to

[Prev in Thread] Current Thread [Next in Thread]