[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
emacs as a service
emacs as a service
Sun, 8 Mar 2009 06:52:01 -0700 (PDT)
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 http://www.emacswiki.org/cgi-bin/wiki/RupertSwarbrick#toc1
(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
I changed the line
(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")
isRunning = False
For Each objItem in colItems
If InStr(objItem.CommandLine, "emacs.exe") Then
isRunning = True
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) &
If isRunning Then
callString = parent & "/emacsclientw.exe -n -e ""(raise-frame)"""
callString = parent & "/runemacs.exe"
Q: Whats the diff between emacs and runemacs?
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.
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 ...) ?
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.
Thanks (if you read so far!)
- emacs as a service,