fanf: (Default)
[personal profile] fanf

One of the features I like about Firefox is when I run firefox (from the command line or from my window manager) it will start it if it isn't running, and it'll open a new window if it is. I have a lot of virtual desktops, and it is much more convenient to just run firefox than to find a desktop with an existing firefox window, create a new window, then move it to the target desktop. Sadly emacs is not so accommodating.

Emacs has a feature which allows you to tell a running emacs to start editing a file. However it does not open a new frame to display the file, so you have to go searching through your virtual desktops to find where it ended up.

I run emacs version 21, but version 22's emacsclient has a new -e (eval) option which allows you to tell emacs to run arbitrary lisp. This can solve the niggles I have described: e.g. to open a new emacs frame on the current desktop I could just run emacsclient -e '(make-frame)'. It would be nice to have this feature in version 21, so I have come up with an evil hack to do the job.

My original idea was that I could set up a file with a local variables section, including an "eval" specifier that tells emacs to open a new frame. Then opening the file would create a new frame. However emacs is sensibly paranoid and won't run lisp in arbitrary files without manual confirmation.

Plan B was to add a function to the find file hook, so that when I opened a specific file (that need not exist) the necessary magic would occur. Then running emacsclient --no-wait ~/.emacs-newframe would create a new frame. After some fiddling I made this work. The code in my .emacs is as follows. As well as creating a new frame, it kills the buffer containing the dummy file and switches the new frame to the canonical dummy buffer, to keep things tidy. It uses the server-visit-hook which is a bit more specific for my purpose than the file-find-hook.

(defun fanf-newframe ()
  (cond ((string-equal buffer-file-name "/home/fanf2/.emacs-newframe")
	 (kill-buffer nil)
	 (select-frame (make-frame))
	 (switch-to-buffer "*scratch*"))))

(add-hook 'server-visit-hook 'fanf-newframe)

A little wrapper script can start emacs or run emacsclient as necessary, to get behaviour like firefox. Instead of running bare emacsclient, it can now also create a new frame before asking emacs to visit a file, which is a bit nicer. However doing so may be racy because I can't make emacsclient ~/.emacs-newframe (without --no-wait) work sensibly: the hook runs before the buffer is registered as being visited by emacsclient, so the hook can't tell the server that the buffer is finished with after it is sure the frame exists. However emacs is not internally multi-threaded and the server handles requests in-order, so it's probably OK.

Date: 2007-06-05 09:27 (UTC)
From: [identity profile] hoiho.livejournal.com
There is nothing new under the sun: I solved this same problem, in more or less the same way, at least 10 years ago! Although clearly something has changed in my working style since, as I haven't used the solution for a few years now.

Date: 2007-06-05 09:29 (UTC)
From: [identity profile] zkzkz.livejournal.com
I do seem to recall gnudoit had an option to do precisely this in the past. I'm surprised it got lost when emacsserver levelled up to replace it.

Date: 2007-06-05 10:21 (UTC)
From: [identity profile] hoiho.livejournal.com
Yes, but there was some weird difference between Gnu Emacs and Lucid at that time, in this area. But I forget what it was...

Really, the amount of effort I put into scripts & elisp to keep it all running just right on Solaris, IRIX, HP/UX, and whatever other weird-ass Unix box I was working on that week was just silly.

Date: 2007-06-05 09:27 (UTC)
From: [identity profile] zkzkz.livejournal.com
I don't understand why you're mucking about with .emacs-newframe

For your purposes can't you just make server-visit-hook call make-frame all the time?

Date: 2007-06-05 10:09 (UTC)
From: [identity profile] stephdairy.livejournal.com
In XEmacs gnuclient and gnuserv give you the feature you want (and I use them all the time), but they might not be available in GNU Emacs.

(S)

Date: 2007-06-05 10:27 (UTC)
From: [identity profile] filecoreinuse.livejournal.com
Or you could just use vim and not care about spawning as many copies as you want because it *still* takes up less memory than one emacs session.

Date: 2007-06-05 10:27 (UTC)
From: [identity profile] filecoreinuse.livejournal.com
*sigh* - LJ ate the <troll> tags around that...

Date: 2007-06-05 10:58 (UTC)
vatine: Generated with some CL code and a hand-designed blackletter font (Default)
From: [personal profile] vatine
I could comment on this with (some) real-world stats, but... :)

Date: 2007-06-05 11:20 (UTC)
vatine: Generated with some CL code and a hand-designed blackletter font (Default)
From: [personal profile] vatine
That'd be why I I install nvi as soon as possible (and ideally uninstall vim, if I have a choice). I still tend towards vi for "small edits", but if I'm actively using emacs when the need for an unassociated small edit is needed, it tends to be done there. Thus the inclusion of (setq wq "Emacs, not vi!") in my .emacs file.

Date: 2007-06-05 12:18 (UTC)
From: [identity profile] filecoreinuse.livejournal.com
Funnily enough I dislike vi because is not compatible with proper vim and breaks *my* finger macros. :)

Date: 2007-06-05 20:26 (UTC)
From: [identity profile] gareth-rees.livejournal.com
In Emacs 22 I reckon you can use (setq server-window #'switch-to-buffer-other-frame) (untested, but it looks plausible based on the server-window docstring).

December 2025

S M T W T F S
 123456
78910111213
14151617181920
21222324 252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated 2026-01-09 20:05
Powered by Dreamwidth Studios