views:

243

answers:

2

I run an email client in a separate emacs window (usually connecting to gnuserv), for example,

emacs -f wl

(the email client being Wanderlust, which probably doesn't matter much).

Is it possible to make emacs remember my preferred

  • window layout,
  • main window dimensions,
  • fonts, colours, etc.,

to set these up only when wl is called? Roughly speaking, if I want to have black background in the email client but white otherwise?

I'm especially interested in keeping the window layout because the default one has to be manually adjusted every time wl is loaded.

+4  A: 

There is default-frame-alist variable that allows you to specify the default appearance and behavior for a new frame (frame is what you call a seperate Emacs window). Though it overrides the settings for all frame, you can advise your function to mask its global value and set it yours. Something like this:

(defadvice wl (around wl-frame-settings activate)
  (let ((default-frame-alist (append
                              '((width . 82) (height . 36)
                                (cursor-color . "#ffa200")
                                (tool-bar-lines . 0)
                                ;; ...
                                )
                              default-frame-alist)))
    ad-do-it))

As TJ pointed out, this solution might have a drawback that it gets invoked too late. TJ's wlwrapper may be a better way.

Török Gábor
Thanks! This brings me to the info node "17 Advising Emacs Lisp Function" in elisp manual, which seems detailed enough to figure out the exact meaning of your code. I can't make it work yet, but since it's documented, this shouldn't be difficult.
volodyako
Depending on what happens inside of 'wl, it may be too late for the modified 'default-frame-alist to have an effect (i.e. gnuclient has already created the frame).
Trey Jackson
For some reason gnuclient happens to open wl first in the focused window of an emacs server application, and then in a new frame. This is why it seems it may be too late.
volodyako
+4  A: 

Building on Török Gábor's answer, you can use any of a number of packages to store and restore window/frame configurations, many are listed here. The various window layout packages all have their quirks, so you'll have to find which one you like (there are so many packages b/c everyone finds something they don't like about the existing packages and roll their own).

With respect to fonts and colors, some can be customized on a frame-by-frame basis, see the info page for frame parameters.

With respect to how to hook it to the function 'wl, you can use advice if you want (I love using it), but it might be much more straight-forward to just either customize 'wl itself, or write a wrapper which does the frame/window configuration loading and then calls 'wl. Then your invocation might have to change to:

emacs -f wlwrapper

The way your emacsclient is configured (or, for older Emacsen, gnuclient) may be what's causing TG's solution not work. I'd probably use the 'wlwrapper solution, customizing emacsclient to re-use an existing frame, then inside 'wlwrapper modify the 'default-frame-parameters and then call 'wl. That way you ensure you create the frame after the parameters are set.

Something like this untested:

(defun wlwrapper ()
  "wrapper for 'wl which sets up window/frame configurations"
   (let ((default-frame-alist (append
                               '((width . 82) (height . 36)
                                 (cursor-color . "#ffa200")
                                 (tool-bar-lines . 0)
                                 ;; ...
                                 )
                               default-frame-alist)))
     ;; if 'wl doesn't create a frame
     (select-frame (make-frame))
     (wl)
     ;; now use which ever window saving package you want
     ))
Trey Jackson
I was having a problem with this, otherwise excellent, answer because the link [emacsclient is configured] points to a wiki page about a different server. It should have pointed to http://www.emacswiki.org/emacs/GnuClient . As simple as that :)
volodyako
@volodyako gnuclient is for older versions of Emacs, as of Emacs 22, you should probably be using emacsclient. But I'll add a link to gnuclient as well.
Trey Jackson