Well, the following works exactly as I want it in emacsclient/daemon mode (which is what I use pretty much all the time):

(defun set-project-in-frame-title (frame)
  (interactive)
  (select-frame frame) ;; Doen't seem to make a difference if you uncomment this or not.
  (setq project-name (getenv "project"))
  (message "Project: %s" project-name)
  (if project-name
      (setq frame-title-format (concat "%b (%*) [" project-name "] "))
    (setq frame-title-format (concat "%b (%*)"))))
(add-hook 'after-make-frame-functions 'set-project-in-frame-title)

In normal mode (just starting 'emacs filename' from the command line, rather than emacsclient) it doesn't show the project name until I open a new frame, then both frames get the right frame title.

Thank you for your help,

Ian.

PS. The reason I wanted this, is that I often work on multiple projects at the same time. (or multiple mercurial repositories of the same source code) and I like to see in the frame title which one I'm having in front of me. Each also has its own daemon: emacs --daemon=project Some shell scripting makes sure that the proper daemon is automatically started if it's not running already.


On Sat, Mar 16, 2013 at 12:04 PM, Ian van der Neut <ivdneut@gmail.com> wrote:



On Sat, Mar 16, 2013 at 11:24 AM, Mark Skilbeck <m@iammark.us> wrote:
On Sat, Mar 16, 2013 at 10:47:54AM +0100, Ian van der Neut wrote:
> On Fri, Mar 15, 2013 at 8:51 PM, Mark Skilbeck <m@iammark.us> wrote:
>
> > Use modify-frame-parameters:
> >
> >     (modify-frame-parameters nil '((title . "test")))
> >
> >
> Hi, thank you for your reply.
>
> After some searching and reading docs I changed the code to
>
> (defun set-project-in-frame-title ()
>   (interactive)
>   ;;(select-frame frame)
>   (setq projectname (getenv "project"))
>   (message "Project: %s" projectname)
>   (if projectname
>       (modify-frame-parameters nil (list (cons 'title (concat
> (buffer-name) " [" projectname "]"))))
>     (modify-frame-parameters frame (list (cons 'title (buffer-name))))
>     ) ;; if projectname
> )
>
> But it doesn't really make any difference. I figured out however, that I
> probably need a hook to be executed when a frame is opened:
>
> (add-hook 'after-make-frame-functions 'set-project-in-frame-title)
>
>
> But, this doesn't work exactly right either. I get the buffer-name of the
> previous buffer. E.g. when I start emacs:
>
> export projectname="myproject"
> emacs myfile
>
> The frame title has:
>
> *scratch* [myproject]

Hum. I suppose this is because when a frame is created, the hook
is run before the new buffer (i.e., myfile) is created, and therefore
(current-buffer) points to the default buffer (in your case, *scratch*).
I'm not sure how to remedy this as my Emacs hacking isn't much good.

One thought would be to hook into the buffer change event, and update the
title that way; but, of course, that will change the title whenever you
change buffers, which may or may not be desirable.


That would be desirable, the buffer name in the title should reflect the buffer in the frame.
 

>
> I get an error:
> Wrong number of arguments: (lambda (frame) (interactive) (select-frame
> frame) (setq projectname (getenv project)) (message Project: %s
> projectname) (if projectname (modify-frame-parameters frame (list (cons
> (quote title) (concat (buffer-name)  [ projectname ]))))
> (modify-frame-parameters frame (list (cons (quote title)
> (buffer-name)))))), 0


Argh... my bad. Somewhere in my ~/.emacs there was still a call to set-project-in-frame-title without any argument.


Also note that you have "project" rather than "projectname" in your
GETENV call; but that may just be a typo.

Yes, it was a typo in the email :)
 
Thank you so far. Not quite there yet though... :)

Ian.



--
One man's "magic" is another man's engineering. "Supernatural" is a null word.
-- Excerpt from the notebooks of Lazarus Long, from Robert Heinlein's "Time Enough for Love"