[Top][All Lists]

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

Re: emacs as a service

From: B. T. Raven
Subject: Re: emacs as a service
Date: Sun, 08 Mar 2009 14:39:17 -0600
User-agent: Thunderbird (Windows/20081209)

rustom wrote:
This is about tweaking emacs to run (somewhat like) a service.
Environment is emacs22 on win-XP.

I describing my current configuration with questions here and there in
the hope that some (better) solutions will come out.

Normally emacs runs with 1 or more windows (frames in emacsspeak)
multiple emacs processes have no relation wilth each other.

So in sort the typical setup is:
0 or more emacses each having 1 or more frame.

By a server setup I mean the following (which may not be proper usage
from the os service point of view)
0 or 1 emacs having 0 or more frames.

So first thing I did
; from
 (defun buffer-used-elsewhere-p (&optional buf)
   "Returns true if more than one window is attached to BUF in all
 frames. If buf is nil or not supplied, search
   (unless buf (setq buf (current-buffer)))
   (< 1 (length (get-buffer-window-list buf nil t))))

 (defun delete-frame-ex ()
   "Delete frame as normal, unless we're on the last frame, in
   which case, exit emacs as we would normally do"
   (if (eq (selected-frame) (next-frame (selected-frame) 0))
       ;; This is the last frame
    ;; There's more!
     (unless (buffer-used-elsewhere-p) (kill-buffer nil))

(global-set-key "\C-x\C-c" 'delete-frame-ex)

This basically makes C-x C-c kill frames rather than kill emacs except
for the last one in which case it kills emacs.

Then recently got some solutions from Scott Turner that prompted me to
try again:

I changed the line
above to
       (make-frame-invisible (car (frame-list)) t)
which makes the last frame behavior consistent with the others (and
emacs unkillable unless one uses explicit M-x kill-emacs).  Basically
emacs disappears rather than dying.

Q: Obviously the (car (frame-list)) thingy is clumsy. Any better way?
Also I want to bind the X on the window top right to function delete-
rather than the default save-buffer-kill-emacs. How to do that?

To move to a more client-server oriented model.
The default emacs program that runs is to be replaced by this vbs
Set objShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root

Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
Dim isRunning
isRunning = False

For Each objItem in colItems
  If InStr(objItem.CommandLine, "emacs.exe") Then
    isRunning = True
  End If

parent = fso.GetParentFolderName(WScript.ScriptFullName)
If WScript.Arguments.Count = 1 Then
  If isRunning Then
    callString = parent & "/emacsclientw.exe -n """ & WScript.Arguments
(0) & """"
    callString = parent & "/runemacs.exe """ & WScript.Arguments(0) &
  End If
  If isRunning Then
    callString = parent & "/emacsclientw.exe -n -e ""(raise-frame)"""
    callString = parent & "/runemacs.exe"
  End If
End if
Q: Whats the diff between emacs and runemacs?

I think that runemacs is just a wrapper used to suppress the appearance of the command window. It is after all only 217kB in size.

Q: The for loop is ugly but my windows/vbs is out of depth here

This script basically does a 4=2x2 way check:
Is emacs server running or not?
Is the script called with an argument or not?
And the default bindings for emacs-ish files (in my case .txt, .org)
is bound to this script in the registry.

If someone can offer HKEY magic to automate this that'd be nice.

I'm not sure I understand your problem or how it differs from just putting emacsclientw in the Windows Registry. You don't need VB to do that:

goes in .emacs (Emacs version 22.1)

goes in environment

in HKCR hive
default c:\emacs\bin\emacsclientw.exe -n "%1"

default c:\emacs\bin\emacsclientw.exe -n "%1"

I think that these will propagate to the HKLM hive on startup but beware of manual registry surgery. At one point, when I clicked on files associated with Emacs in Windows Explorer, all that would happen was that the runemacs.exe binary would load into an emacs buffer, a consummation not devoutly to be wished for. Also, it's safest to make associations from WE with Tools>Folder Options>File Types rather than in the registry but you may need ./ (also in HKCR) set to something like ft000003, ft000002, or ft000001 for click-opening extensionless files (e.g. readme). I think these are automatically generated user file types but I can't find any documentation on them. Again beware; some system files don't have extensions , even parts of the registry itself.

Now one fragile aspect of this is that if 2 emacsservers run well the
system is borked!  How is the (server-start) to be enclosed in a
(if server-not-started-p ...) ?

Is that... run well or run, well.... ;-)

And one (entirely windowsy) related question:
How to catch the system login, logout, shutdown etc events?
Once I can get some script to give me some control for this I can use
emacsclient to do appropriate actions.

I am totally out of my depth here. Don't MSwin processes with pending open files warn about needed actions in case of logout or shutdown?

Thanks (if you read so far!)

reply via email to

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