EmacsClient allows one to open a file for editing in an already running Emacs. Because it doesn’t start a new Emacs instance at each invocation, you can setup EmacsClient as the default editor, e.g. in the environment variable EDITOR or VISUAL. EmacsClient is part of and works only in conjunction with GNU Emacs. The program GnuClient provides the corresponding functionality for XEmacs, but also works with GnuEmacs.
Since the release of GnuEmacs 22.1 both EmacsClient and GnuClient also work on “Windows” and offer similar functionality, e.g. execute arbitrary EmacsLisp code from the command line.
RichardRiley : With emacs 23 simply do something like
#!/bin/bash exec emacsclient --alternate-editor="" -c "$@"
Then
export EDITOR=~/bin/edit
Where “edit” is the small script above. The key is the “” for alternate-editor. emacsclient starts the server for you if and only if it is not already running.
OweAndersson : Think this works fine, only I get a warning: “Emacsclient ERROR, No connection could be made because the target machine actively refused it”
RobDavenport : Owe - I believe that error means the file ~/.emacs.d/server/server is for an old emacs process. I delete that file and then it works. (On Windows at least.)
See EmacsMsWindowsIntegration for a fairly complete and workable solution for Emacs 23/24, using stock Emacs builds (not W32Emacs).
Create an emacs.bat file in your Emacs “bin” directory. (Perhaps something like “\Program Files\emacs-23.1\bin” if you’ve used an installer.) Add the following commands:
@echo off "%~dp0emacsclientw.exe" -na "%~dp0runemacs.exe" "%1"
The first line suppresses command line output, but if anyone knows a quick and easy trick to prevent the batch file from popping a command window in the process, that’d be nice. The “%~dp0” returns the directory in which the batch file resides, which is why it’s important to put it alongside “emacsclientw.exe” and “runemacs.exe”. Everything is set in quotes to handle for spaces in path names. A script seen elsewhere suggested use of “-n/--no-wait”. If you’d like Emacs to create a new window (an Emacs frame) consider adding the “-c/--create-frame” option to the beginning of the options argument.
The -a option specifies a fallback program to run if the emacs server is not found. In this case, it is runemacs.exe, which runs emacs without opening a console window.
To address: “The first line suppresses command line output, but if anyone knows a quick and easy trick to prevent the batch file from popping a command window in the process, that’d be nice.”
@echo off start "" "%~dp0emacsclientw.exe" --alternate-editor="" -n %*
Pro tip: Under Windows Vista/7 with your emacs directory in “Program Files”, do NOT use Emacs itself to create or edit the batch file. Windows creates a “Virtual Store” in the environment of the current user when it sees an executable messing with it’s own directory under “Program Files”. This could cause some confusing problems.
17 Dec 2010: @Pro tip: what do you mean “when it sees an executable messing with it’s own directory”? Can’t an executable run another executable under same directory? Could you please provide more details? Thanks.
9 Jul 2012: I believe he means that, to bypass permissions issues, any edits made in Program Files by programs stored there, are actually written to a virtual version of that folder somehwere in the user’s home folder in C:\Users\<Username> (I cannot exactly remember where)
Also, two things, with .cmd files, you can avoid the cmd window from opening if you use “start emacsclient <put your options here> %*”, and that using %* is far better than using %1 since that collects all command line arguments after the command, and not just the first one.
CaptainObvious : The problem is with the creation of files, not running. http://answers.microsoft.com/en-us/windows/forum/windows_7-security/how-to-disable-virtualstore-in-windows-7/55dce284-0dcd-46af-892e-d2b9cf5bcff6
Then it’s as easy as associating whatever files you like with with the new emacs.bat file.
Inspired by the original text:
Under Windows I used someting like this wedit.bat:
“\emacs-22.3\bin\emacsclientw.exe” --alternate-editor=”\emacs-22.3-bin-i386\emacs-22.3\bin\runemacs.exe” “%1”
Note: Make sure you have (server-start) in your .emacs file, so the first time emacs is run it will run as a server.
Note: I had to remove the quotes from around the %1, and then in the registry, have something like “c:\apps\emacs\bin\emacs.bat” “%1” for the shell/open/command entries. Otherwise file paths with spaces in them would get parsed incorrectly.
Since BAT files may not work for everything, I made a small launcher app that does the same as the aforementioned. https://github.com/mickbeaver/win32emacslauncher
The tips for doing this are platform specific.
To have emacsclient start a full Emacs process if it can’t connect to one, simply set ALTERNATE_EDITOR. In your .bash_profile (or similar):
export ALTERNATE_EDITOR=emacs EDITOR=emacsclient VISUAL=emacsclient
Alternatively, the following script can be used to open Emacs in the background if not already present, giving more consistent behaviour:
tempuid=$(id -u) temphost=$(hostname) if [ ! -e "/tmp/esrv$tempuid-$temphost" ] then emacs & while [ ! -e "/tmp/esrv$tempuid-$temphost" ] ; do sleep 1 ; done fi emacsclient "$@"
Note that the above script is not perfect. It assumes that emacs will sucessfully load, and that the InitFile will start the server. Also on my system using some cvs version of 22.0, the socket to look for is “/tmp/emacs$tempuid/server”.
Best Solution: The same basic functionality is available in etc/emacs.bash of Emacs, which defines a new command named edit, and should be sourced from .bashrc with a line like “source /usr/share/emacs/21.4/etc/emacs.bash”.
edit can then be used as the value of EDITOR. If no windowing system is found, no attempt to use emacsclient is made, however if a suspended emacs session is available, it will be re-used, otherwise a new emacs session is used. Future versions might try emacsclient even without a windowing system before testing for a suspended emacs.
The current cvs version of emacs.bash notes that this method is now obsolete, and the -a (alternate editor) option to emacsclient should be used instead if available.
For current cvs version, I have write a EmacsdInitScript to put in /etc/init.d/emacsd for autostart emacs daemon on startup and kill emacs on shutdown.
See EmacsMsWindowsIntegration for how to set up taskbar/Start-menu shortcuts and make Emacs open particular file types using emacsclient. This works well for Emacs 24 at least, and is simpler and perhaps better than the VBS solutions mentioned below.
With the patched version of EmacsW32 EmacsW32Client will start Emacs automatically by default. You can use the same solution also with the unpatched version, but this requires using the patched version of emacs client + the file auto-server.el.
With Emacs 23 (and possibly any version with EmacsClient), to avoid the following VB scripting, a simple batch file solution can be found in the “Easy Way” section above.
Note: On Windows, GnuClient works better than EmacsClient (for versions prior to 22.1). The instructions below apply to EmacsClient; head over to GnuClient for a less cumbersome solution.
(I haven’t found GnuClient less cumberson than EmacsClient, and in fact have always had trouble getting GnuClient set up on Windows. Not big trouble, but enough to be frustrating when I have to get it set up. Once running, both GnuClient and EmacsClient (for 22.1 and later) work fine. With EmacsClient, once Emacs is started, I only use emacsclient to send file edit requests. I only use the vbs script below to launch Emacs from quicklaunch or a PowerPro script.) --RobDavenport
(A trivial version of this, not using EmacsClient, is at MsWindowsGlobalContextMenu.)
Save the current VBscript (shiver) in emacs/bin folder, as launch-emacs-client.vbs:
Set objShell = WScript.CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 1 Then strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 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 Next If isRunning Then objShell.Run(fso.GetParentFolderName(WScript.ScriptFullName) & "/emacsclientw.exe -n """ & WScript.Arguments(0) & """") Else objShell.Run(fso.GetParentFolderName(WScript.ScriptFullName) & "/runemacs.exe """ & WScript.Arguments(0) & """") End If Else objShell.Run(fso.GetParentFolderName(WScript.ScriptFullName) & "/runemacs.exe") End If
Add the following keys to the registry:
[HKEY_CLASSES_ROOT\*\shell] [HKEY_CLASSES_ROOT\*\shell\openwemacs] @="Edit with Emacs" [HKEY_CLASSES_ROOT\*\shell\openwemacs\command] @="Wscript.exe C:\\Program Files\\emacs\\bin\\launch-emacs-client.vbs \"%1\""
You’ll have to adjust the path in the last key, to your installed directory.
Remember to put (server-start) in your InitFile.
If anybody knows, how to get an icon into the contextmenu, please append the information here – I gave up googling it.
--TroelsKn
I encountered “permission denied” problems when using the value for the ‘command’ registry key as described above. I have no idea what the underlying cause was, but I discovered that using %L instead of \”%1\” appeared to solve the problem; so my value was:
Wscript.exe C:\\[PATH TO EMACS]\\bin\\launch-emacs-client.vbs %L
--Dave Hancock
I found that I ran into problems when using the VBScript that TroelsKn posted. I encountered errors when trying to edit files found in folders with spaces (i.e. "c:\My Documents\mytest.txt"). This VBScript should work better:
Set objShell = WScript.CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 1 Then strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 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 Next If isRunning Then objShell.Run("""" & fso.GetParentFolderName(WScript.ScriptFullName) & "\emacsclientw.exe"" -n " & """" & WScript.Arguments(0) & """") Else objShell.Run("""" & fso.GetParentFolderName(WScript.ScriptFullName) & "\runemacs.exe"" " & """" & WScript.Arguments(0) & """") End If Else objShell.Run("""" & fso.GetParentFolderName(WScript.ScriptFullName) & "\runemacs.exe"" ") End If
– Shane
I only know how to get icons to show up in Windows Explorer, by defining file “meta types”, e.g., "EmacsFile", and then hanging the file associations (e.g., “.foo”) off of those:
REGEDIT4 #----- # Set up the handler and icon #----- [HKEY_CLASSES_ROOT\EmacsFile] @="Emacs File" "Content Type"="text/plain" [HKEY_CLASSES_ROOT\EmacsFile\shell] [HKEY_CLASSES_ROOT\EmacsFile\shell\open] # This gets displayed in context menu @="Open in Emacs" [HKEY_CLASSES_ROOT\EmacsFile\shell\open\command] @="C:\\Program Files\\Emacs\\bin\\runemacs.exe \"%1\"" [HKEY_CLASSES_ROOT\EmacsFile\DefaultIcon] @="C:\\Program Files\\Emacs\\etc\\icons\\emacs.ico,0" # Alternate # @="C:\\Program Files\\Emacs\\bin\\runemacs.exe,0" #----- # Associate file types w/ Emacs #----- [HKEY_CLASSES_ROOT\.foo] @="EmacsFile" "Content Type"="text/plain"</pre>
Note that this does not do the context menus; it sets the icons in Windows Explorer! (Only takes effect after you restart your desktop Explorer instance, e.g., after rebooting or manually killing off all ‘explorer.exe’ instances in Task Manager and rerunning it. This reloads the registry cache.)
Hopefully this brings us a step closer. --thundt
Had some trouble getting emacsclient to work under Windows 7 with the default settings. The server file was created in %userprofile%\appdata\roaming\.emacs.d\server\server and emacsclient didn’t look there by default. Quickest solution was to define EMACS_SERVER_FILE environment variable and restart Emacs.
The following opens the selected file in a running instance of Emacs, starting Emacs if necessary.
This is similar to TroelsKn method above but leverages the newly integrated EmacsClient (emacsclientw.exe) in Emacs 22 to obviate the use of the .vbs file:
1. Add the registry key as described above, i.e.
[HKEY_CLASSES_ROOT\*\shell\openwemacs\command]
2. Set the value of command to the following, adjusting the path as necessary:
C:\emacs-22\emacs\bin\emacsclientw.exe -n "%1"With this setup on my pc the shell window just blinks momentarily and disappears. Is there any way to keep it on screen to see what the problem is? (Emacs sever is running, and the path to emacsclientw.exe looks fine)
As far as I know the vbs-script from TroelsKn is still useful because EmacsClient does not start a new Emacs if it is not running. At least for me the changes above only worked if Emacs was already started. --MartinStemplinger
The -a option of emacsclient, or the environment variable ALTERNATE_EDITOR can be used to specify runemacs.exe as an alternate editor when emacsclient fails to find a server.
Using a utility like NirCmd (http://www.nirsoft.net/utils/nircmd.html) to supress the command window for emacsclient, it makes for a much smoother experience. As emacsclientw pops a dialog on initial run.
See: WThirtyTwoFileAssociations
Bind this script to the registry key as above to edit files from the context menu, starting emacs as required. Run the script with no argument and it will open a new emacs or make the already running emacs the top window. I put a shortcut to the script on my desktop and attach a hot key so emacs is just a keystroke away and I never have more than one running.
'******************************************************************************* ' Start emacs if it's not running & open file if script called with argument '******************************************************************************* For Each process In GetObject("winmgmts:\\.\root\cimv2"). _ ExecQuery("Select * From Win32_Process") If process.name = "emacs.exe" Then ' connect to emacs & open file or make emacs the top window ' replace -f arg with your server file location run path("emacsclientw.exe") & " -f c:\.emacs.d\server\server -n " & _ fileOr("-e (raise-frame)") WScript.Quit End If Next run path("runemacs.exe") & " " & fileOr(Null) ' start new emacs Sub run(cmd) ' run the cmd WScript.CreateObject("WScript.Shell").Run(cmd) End Sub Function path(exe) ' return full, quoted path to executable scriptDir = CreateObject("Scripting.FileSystemObject"). _ GetParentFolderName(WScript.ScriptFullName) path = """" & scriptDir & "\" & exe & """" End Function Function fileOr(default) ' return script arg (filename) or default If WScript.Arguments.Count = 1 Then fileOr = """" & WScript.Arguments(0) & """" Else fileOr = default End If End Function
– John Dell’Aquila
You can open a file in Emacs via Windows Send To by placing a shortcut to emacsclientw.exe in C:\Documents and Settings\yourName\SendTo. Then, when you right-click on a file and select Send To select emacsclientw. This will open the file in the running version of Emacs; if Emacs isn’t running it will fail, but you can use methods described elsewhere in this Wiki for starting the server automatically. The simplest way I found is to simply add (server-start) to your emacs init file, then configure Windows to automatically start Emacs when you log in and leave Emacs running until you log off.
- Glen Cordrey
I’ve used two ways to get EmacsClient into the SendTo on Windows 7. First was to use the VBScript mentioned above, but I had to copy the script to the SendTo folder (%APPDATA%\Roaming\Microsoft\Windows\SendTo) not just a link/shortcut to it, and that meant altering the script to use a fixed path since the script was no longer in the same directory as emacsclientw.exe or runemacs.exe.
Set objShell = WScript.CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 1 Then objShell.Run("c:/sys/emacs-23.3/bin/emacsclientw.exe -na ""c:/sys/emacs-23.3/bin/runemacs.exe"" """ & WScript.Arguments(0) & """") Else objShell.Run("c:/sys/emacs-23.3/bin/emacsclientw.exe -na ""c:/sys/emacs-23.3/bin/runemacs.exe"" ") end If
(I’m not VBScript programmer so that could obviously be improved, but it was short and quick, and you’ll need to modify paths as appropriate.) Benefit is that it sends the file to Emacs (starting Emacs if necessary) without a flashing command prompt. Downside is that it has to show up with the “.vbs” extension to work. Would rather it showed up in the SendTo menu as just “Emacs” and not “emacs.vbs”. Oh well. Ideas? Second way was to create a batch file like described above, put it into Emacs’ bin directory and create a shortcut to it in the SendTo folder. Change the shortcut name to just “Emacs” and it looks better in the menu, but there is a command prompt window that flashes up. – RobDavenport
The above tips have worked well for me on Windows-XP. When I recently was moved to Windows-7, it would no longer work. My emacs client .bat file would fire up from a cmd command just fine, but when invoked via a SendTo link, it could not find the server socket. Taking information found elsewhere on this page (does anyone else think this page could use some organizing?) as well as the source for emacsclient that was connected to another Google hit on the subject, I discovered a way to tell emacsclient where to look for the socket, er. the server file. SendTo seems to now be happy. Here is what I put in my emacsclient .bat file:
@c:\apps\emacs\bin\emacsclient.exe -a c:\apps\emacs\bin\runemacs.exe --server-file h:\.emacs.d\server\server %1 %2 %3 %4 %5 %6 %7 %8 %9
Where I am using my h-drive for my .emacs.d directory (HOME = h:\). Your path to the server file probably is different. Your path to emacsclient is probably different also. I pass all the command line arguments (upto 9) in case I use this file for another purpose. – KevinBuchs 2012-02-06
You might want to use %* which is short hand for all arguments. – shjk
Wanted to have Emacs icon on taskbar that calls runemacs to get Emacs started (without command prompt windows flashing or odd submenus and with proper icon (putting .vbs scripts on the taskbar created pinned shortcuts to wscript with the runemacs.vbs as a submenu). I found a tip here http://superuser.com/questions/259146/why-latest-emacs-version-dont-support-windows-7-taskbar and was able to do it by:
1. Start Emacs via runemacs shortcut, no other Emacs process running previously. Emacs icon shows up on taskbar when Emacs starts.
2. Right-click on icon, select pin to taskbar.
3. Shift-right-click on the icon and change the target from emacs.exe to runemacs.exe
Emacsclient can be used (with -n -a arguments as above) but needs “%1” in shortcut to work and that creates an empty buffer ‘%1’ which isn’t ideal so I just use runemacs.exe. I don’t drag-and-drop files to the taskbar icon (can’t) just use it to start/focus Emacs, and I use other tips here to use emacsclient via SendTo or context menu options to send files. --RobDavenport
Suggestion: use emacsclientw -e (raise-frame) to be able to click on the icon to raise an existing frame - at the cost of not being able to drag files onto the taskbar icon. Add --alternate-editor= to launch emacs in daemon mode (works on Emacs 25 and later for Windows) if it is not already running, or in older versions you can use --alternate-editor=runemacs.exe but this will start emacs with an error due to the -e option being unrecognized by emacs (it has --eval, but with different syntax)
And there’s another possible method here: http://robert-adesam.blogspot.com/2011/01/emacsclient-setup-on-windows-7-starter.html. He uses a bat-to-exe converter to create an executable to run a batch file that executes emacsclient as needed, but the exe can be put onto the taskbar (and the converter he mentions can have it run invisibly and with custom icon). Might also be worth a look. --RobDavenport
After upgrading to Windows 10 and installing a fresh installation of Emacs, pinning emacs.exe to the taskbar had same old problems (multiple icons), and the ‘fix’ above to change emacs.exe target to ‘runemacs.exe’ didn’t help. However, using MichaelHoffman’s tip over in [1] to use a nice tool to set the AppID for the shortcut. Running the app at http://code.google.com/p/win7appid/ on the emacs.lnk shortcut in \users\<name>\ApplicationData\Microsoft\Internet Explorer\QuickLaunch\User Pinned\Taskbar and setting it’s AppID to “Gnu.Emacs” did the trick. --RobDavenport
Another way to (manually) edit the app id of a shortcut… add the following string registry entry to HKCR\lnkfile:
[HKEY_CLASSES_ROOT\lnkfile] "FullDetails"="prop:System.PropGroup.Description;System.ItemTypeText;System.Comment;System.Link.TargetParsingPath;System.AppUserModel.ID;System.ItemFolderPathDisplay;prop:System.PropGroup.FileSystem;System.ItemNameDisplay;System.Size;System.DateCreated;System.DateModified;System.FileAttributes;*System.OfflineAvailability;*System.OfflineStatus;*System.SharedWith;*System.FileOwner;*System.ComputerName"
Then when viewing the Properties on a shortcut file, in the Details tab, the AppUserModelID is displayed - and is editable. I fixed my repinned emacs shortcut with this. (You could just set “FullDetails” to be just “prop:SystemAppUserModel.ID” but then the details tab will only show the app id.) --RobDavenport
To execute emacsclient From Firefox to call Windows Native Emacs to edit web pages, see Mozilla page and comments about add-on It's all text.
There is a tool in [NxhtmlMode[nXhtml]] that allows you to do this. You can find it in the nXhtml menus under “nXhtml / Tools / External Editor Setup”.
Edit with Emacs - a Google Chrome browser extension: Source: http://github.com/stsquad/emacs_chrome or https://chrome.google.com/extensions/detail/ljobjlafonikaiipfkggjbhkghgicgoh to install in Chrome. This extension by Alex Bennee allows users to edit web-page TEXTAREAs with Emacs. It’s nice to use Emacs when typing in posts or editing Wiki pages. It uses its own edit-server.el instead of gnuclient or emacsclient currently, and doesn’t let you edit page source yet. (This is not strictly about emacsclient, but seems related.)
MozEx is a Firefox extension which allows the user to use external programs for editing TEXTAREAs, viewing page source, handling mailto, news, telnet and FTP links. http://mozex.mozdev.org/
External.exe allows you to assign a keyboard shortcut to “EMACS editing”: Whenever you want to edit text in a text area in Windows, hit the shortcut. Then External.exe copies the text in the text area to a file, opens the file with an external editor, and - once editing has finished - copies back the text from the file into the text area. The source code of External.exe is included in the downloadable zip file, and it is under the GPL.
The patched version of Emacs + EmacsW32 may start Emacs automatically and opens the given file name. Note that in this case you do not have to add server-start to .emacs. The patched version of Emacs client does this for you. (Actually I believe the same code can be used on other platforms than w32, but so far I do not think anyone has tested this.)
The installation of Emacs + EmacsW32 also does some file associations etc, but see also WThirtyTwoFileAssociations.
WThirtyTwoServerMode describes how to set up Windows so that a desktop shortcut will open the same instance of Emacs every time you double-click on the shortcut, and hide Emacs when you exit.
GnuEmacs cannot currently handle different terminal devices at the same time, so emacsclient is not able to open a new Frame on the terminal that it is invoked from. Fortunately this is issue is being resolved, see MultiTTYSupport.
To open the files designated by emacsclient in their own frame, you can use the following hook as a Server Switch Hook which can be setup in customize-group <RET> Server <RET>, or in your InitFile, as such:
(add-hook 'server-switch-hook
(lambda nil
(let ((server-buf (current-buffer)))
(bury-buffer)
(switch-to-buffer-other-frame server-buf))))If you’re setting this up via M-x customize, you’ll of course want to drop the (add-hook) call.
You might also want to close the frame when you’re done with it. To do this, setup a Server Done Hook in the same section to call delete-frame.
(add-hook 'server-done-hook 'delete-frame)
I also like emacs to cleanup stuff when I finish the emacsclient, so I add another hook to kill the buffer when finished. This also takes care of weird buffer switching behaviors when closing client buffers.
(add-hook 'server-done-hook (lambda nil (kill-buffer nil)))The whole thing is actually in my .emacs-custom file:
(custom-set-variables '(server-done-hook (quote ((lambda nil (kill-buffer nil)) delete-frame))) '(server-switch-hook (quote ((lambda nil (let (server-buf) (setq server-buf (current-buffer)) (bury-buffer) (switch-to-buffer-other-frame server-buf)))))) )
You can also use ‘server-kill-new-buffers’ instead of calling ‘kill-buffer’ in your ‘server-done-hook’, e.g.
(custom-set-variables '(server-kill-new-buffers t))
(add-hook 'server-done-hook (lambda () (delete-frame)))I’ve found it very useful to set my $EDITOR to emacsclient, and let it judge wether or not to start emacs, based on the $DISPLAY variable, which is often an indication of running on a faster machine for me. So I’ve wrote the following script, and installed it as /usr/bin/emacsclient.vim.
#! /bin/sh files="$@" files=${files:-/dev/zero} if [ -z "$DISPLAY" ]; then exec emacsclient.emacs21 -a vim "$files" else exec emacsclient.emacs21 -a emacs "$files" fi
Note that I avoided calling directly emacsclient, which might be an alternative that points to emacsclient.vim, which would lead to an horrible recursion.
To complete the setup on Debian, I’ve installed this script as an alternative to the editor command:
update-alternatives --install /usr/bin/editor editor /usr/bin/emacsclient.vim 50
Now I can choose emacsclient.vim as my editor using:
update-alternatives --config editor
Add the following to your InitFile:
(defadvice server-visit-files (around save-buffers last activate) "Try to emulate gnuclient behavior with emacsclient. Works only for visiting one buffer at a time." (let* ((filen (car (car (ad-get-arg 0)))) (buf (get-file-buffer filen)) (this-buf-modified-p nil)) ;;; the following is copied from server-visit-files, with ;;; a modification for the `verify-visited-file-modtime' test (if (and buf (set-buffer buf)) (if (file-exists-p filen) ;;; if the file has changed on disk, reload it ;;; using `find-file-noselect' (if (not (verify-visited-file-modtime buf)) (progn (find-file-noselect filen) ;;; if user answered `no', reset modtime anyway ;;; so that server-visit-files doesn't realize the ;;; difference: (set-visited-file-modtime))) ;;; if file exists no longer, we let server-visit-files ;;; deal with that t) (setq buf (find-file-noselect filen))) (setq this-buf-modified-p (buffer-modified-p buf)) (set-buffer buf) (set-buffer-modified-p nil) ad-do-it (set-buffer-modified-p this-buf-modified-p)))
From http://docs.kde.org/en/HEAD/kdegraphics/kdvi/inverse-search-editor.html
I use screen all the time, and always wanted to get it to autoswitch back and forth between shell and emacs window. I now figured out how, and here is what I do:
In ~/.screenrc I have:
screen -t Emacs 1 /usr/bin/emacs
In ~/bin/emacs I have the following:
#!/bin/sh
echo $WINDOW >~/tmp/emacsclient-caller
screen -r -X select 1
emacsclient "$1"And in my InitFile I have:
(add-hook 'after-init-hook 'server-start)
(add-hook 'server-done-hook
(lambda ()
(shell-command
"screen -r -X select $(cat ~/tmp/emacsclient-caller)")))Now I only need to set my EDITOR environment variable to ~/bin/emacs.
With MultiTTYSupport emacs branch, simply calling emacsclient -t would be enough and would not require such a hack 😊 Plus it is really damn fast ;)
I’ve made a screenserver.el that takes this an extra step, allowing you to move to the correct screen window no matter where you run the emacs server.
I wanted a do-it-all script, that would:
All you need is to drop and chmod u+x the following shell script somewhere in your PATH:
add this snippet to your .emacs:
;; emacsclient/server hook (defvar server-seb-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-xk" '(lambda () (interactive) (shell-command (concat "touch " "/tmp/blah")) (server-edit))) map)) (define-minor-mode server-seb-mode "Server") (add-hook 'server-visit-hook 'server-seb-mode)
and then add the following into one of your shell startup files:
export EDITOR=emacs-screen.sh
if you’re used to typing ‘emacs’, maybe also alias it:
alias emacs=emacs-screen.sh
dtach (Emulate GNU screen’s detach feature.)
dtach is a tiny program that emulates the detach feature of GNU screen, allowing you to run a program in an environment that is protected from the controlling terminal and attach to it later.
Visit the dtach homepage project at http://dtach.sourceforge.net
The cool thing with dtach is that you do not have anything to setup, just run something like:
dtach -A /tmp/emacs emacs
that’s all !
When you want to detach from a running session, just press C-\. To reattach, run your dtach command again. Very simple and very handy.
A major addition has been done in the EmacsCVS trunk lately. This addition allows a user to start emacs as a daemon !
To start the daemon, just do:
emacs --daemon
This will launch an emacs daemon and detach itself.
When you want to attach to it, either issue:
emacsclient -t
or
emacsclient -c
Tadah !
To detach again, just use the usual key binding.
Enjoy.
ssh remote_host -f emacsclient --eval '"(make-frame-on-display \"$DISPLAY\")"'Open a new frame from you shell by adding to your .bashrc or .zshrc
new-frame() {
emacsclient -e "(new-frame)"
}Edit a file in a new frame by adding to your .bashrc or .zshrc
edit() {
local FILE=$1if [[ -z $FILE ]]; then echo "Missing filename" return fi
if [ $FILE[0] != "/" -o $FILE[0] = "~" ] then FILE="$PWD/$FILE" fi
if [[ -z $2 ]]; then emacsclient -n $FILE else emacsclient -e "(find-file-other-frame \"$FILE\")" fi }
edit_new_frame() {
edit $1 "yes"
}If you want your window manager to automatically focus the emacs frame when emacsclient is invoked, then once editing is done, refocus back to the original window from which emacsclient was invoked, here’s how:
First you need wmctrl installed, and a helper script called current-winid:
#!/bin/sh # Only ttys have $WINDOWID set correctly? Firefox doesn't, anyway. if ! which wmctrl >/dev/null 2>&1; then me=$(basename $0) echo "$me: wmctrl not found; aborting." >&2 exit 1 fi # Note that the exit in END is what determines the final exit status, # even t/pre~hough the previous exit initiates the exit. wmctrl -a :ACTIVE: -v 2>&1 \ | awk 'BEGIN { exit_status = 1 } /^Using window:/ { print $3; exit_status = 0; exit } END { exit exit_status }' \ || exit 1
Then all you need is an emacsclient wrapper script (e.g. call it switch-to-emacsclient):
#!/bin/sh
# Save the current winid so we know what to switch back to from emacs.
client_winid=$(current-winid)
# Switch to emacs and wait for editing to be completed.
wmctrl -xa emacs
emacsclient -a fe "$@"
# Switch back to window from which emacsclient was invoked.
wmctrl -ia $client_winid
The really nice thing about this is that it supports multiple emacsclients running at once, and it doesn’t matter which order you complete editing of the emacsclient buffers.
Alternative: Lisp:switching_emacsclient.bash
If you use the package saveplace.el (http://www.emacswiki.org/cgi-bin/wiki/SavePlace) to remember the last position a file was visited at, you may have noticed that opening files with emacsclient(w) the cursor always goes at the beginning of buffer, that is, it looks like emacsclient (or better, emacs server) does not care about save-place being active. I suppose this is a bug. A temporary workaround to this is to set
(setq server-visit-hook (quote (save-place-find-file-hook)))
in your .emacs file (or set this option through the customization buffer).
I suppose you must have
(require 'saveplace)
in your .emacs file as well in order not to receive error messages.
I also suppose a similar solution works for gnuclient(w), which has apparently similar problems.
-PGLPM
Saveplace with emacsclient doesn’t have the described problem in the latest version of GNU emacs. Atleast on 24.2 I don’t see this problem.
If your fingers are wired to using C-x k to kill off buffers (and you dont like having to type C-x #) then try this :
(add-hook 'server-switch-hook
(lambda ()
(when (current-local-map)
(use-local-map (copy-keymap (current-local-map))))
(local-set-key (kbd "C-x k") 'server-edit)))If there are no clients, the above code will error. I would suggest the folowing instead:
(add-hook 'server-switch-hook
(lambda ()
(when (current-local-map)
(use-local-map (copy-keymap (current-local-map))))
(when server-buffer-clients
(local-set-key (kbd "C-x k") 'server-edit))))This is similar to the C-x k binding above, but uses C-c C-c – which makes it similar to using gnus – and is, of course, for the other protocol.
(add-hook 'gnuserv-visit-hook '(lambda () (local-set-key [(control c) (control c)] (lambda () (interactive) (save-buffer) (gnuserv-edit)))))
‘kill-emacs-query-functions’ allows one to call functions that query the user about killing emacs, with the potential for aborting the quit. i have a simple check in my .emacs that works fine for a standalone emacs process but doesn’t get called when exiting an emacs client.
(setq kill-emacs-query-functions
(cons (lambda () (yes-or-no-p "Really kill Emacs? "))
kill-emacs-query-functions))is there some way of achieving similar when killing a client?
I wanted to use emacsclient as my editor to svn in Windows, but when I used emacsclientw.exe or emacsclient.exe, the return value when I was done editing was always 1, which made svn to reject my edit. How it is with emacsclient and return values? Is my copy just broken?
A: This is known to be broken currently (16-Oct-09); it always returns 1. There’s some discussion in the help-emacs-windows mailing list about fixing it.
Is emacs-server protocol compatible with gnuclient or are they totally different implementations? I would like to use an utility in Windows designed for gnuclient (visemacs), but it only supports gnuclient at the moment. I would like to know, how big effor it would be to patch it to support emacs client protocol. All pointers to relevant documentation is gladly accepted too!
Is this possible? I read how to do it in linux here: http://blog.lathi.net/articles/2007/10/09/remote-pair-programming
You may want to try Rudel for realtime collaborative editing.
If a first instance of emacs is started (and it starts its server), then a remote login is performed and a second instance started, the new instance will starts its own server and mask or kill the original one. An attempt to use emacsclient at the initial login will then start a client window at the remote login. In case that sounds an unlikely scenario, I achieved it by 1) starting an X11 session with emacs in one window, 2) working on a machine in another room, including an ssh to the first machine and another emacs session, 3) returning to the first machine where I attempted to respond to a Usenet post. The edit appeared in emacs on the second machine.
Is there some way to allow the servers started in different ttys to distinguish themselves from each other ?
I find that after starting emacs server (eg, /Applications/Emacs.app/Contents/MacOS/Emacs --daemon) I can start a client session locally, but emacsclient can’t find the socket if I try to create a terminal-only client via ssh (OS X 10.6.2, GNU Emacs 23.1.90.1 compiled with ./configure --with-ns). I’ve seen this reported as a bug (bug#3992: 23.1.50) on bug-gnu-emacs-gnu. Here’s a workaround.
First, you need to make sure that you’re using the right emacsclient binary. Apple distributes GNU Emacs 22 (installed in /usr/bin), but its emacsclient binary is not compatible with GNU Emacs 23.
alias emacsclient="/Applications/Emacs.app/Contents/MacOS/bin/emacsclient"
Then, you need to set the server-socket-dir variable in your .emacs so that the standard path assumed by emacsclient is used instead of the path that Emacs 23 defaults to on MacOS X.
(setq server-socket-dir (format "/tmp/emacs%d" (user-uid)))
Obviously, this needs to be executed before (server-start) is called.
Now you can attach to the server process using the above alias in terminal mode via an ssh session:
emacsclient -nw
And it also works locally to launch the cocoa GUI:
emacsclient -c &
I expect that this will fail if you are running multiple servers.
– Noah Hoffman edited by: – HansHuebner
I’d had a few problems connecting to the emacs server from emacsclient, until I realised I was using the default /usr/bin/emacsclient when I should’ve been using the /Applications/Emacs.app/Contents/MacOS/bin/emacsclient … so make a symlink,
sudo mv /usr/bin/emacsclient /usr/bin/emacsclient.old # backup the original emacsclient. sudo ln /Applications/Emacs.app/Contents/MacOS/bin/emacsclient /usr/bin/emacsclient # symlink emacsclient from Emacs.app
Rather than moving a file installed by the OS, I have symlinked /Applications/Emacs.app/Contents/MacOS/bin/emacsclient to /usr/local/bin/emacsclient. Of course you have to make sure that /usr/local/bin comes before /usr/bin in your $PATH. - citizen428
Setting emacs to work over tcp will create the ~/.emacs.d/server/server socket file, you can then use emacsclient this way…
emacsclient +4:14 FILE # opens FILE at line 4, col 14.
(I’ve found there’s no need to specify the server, unless you are running more than one Emacs server. )
Set -a and/or -c as you like.
– Jasonm23
See e-pipe
– LeWang
I defined the following function within .bashrc and start emacs under cygwin with the command e.
e() {
local TMP;
if [[ "$1" == "-" ]]; then
TMP="$(mktemp /tmp/emacsstdinXXX)";
cat >"$TMP";
if ! emacsclient --alternate-editor /usr/bin/false --eval "(let ((b (create-file-buffer \"*stdin*\"))) (switch-to-buffer b) (insert-file-contents \"${TMP}\") (delete-file \"${TMP}\"))" > /dev/null 2>&1; then
emacs --eval "(let ((b (create-file-buffer \"*stdin*\"))) (switch-to-buffer b) (insert-file-contents \"${TMP}\") (delete-file \"${TMP}\"))" &
fi;
else
emacsclient --alternate-editor "emacs" --no-wait "$@" > /dev/null 2>&1 &
fi;
}
Editing a file text.txt:
e text.txt
Piping something:
echo "something" | e -
Using --alternate-editor and --eval together did not work for me. I don’t know why. The bad thing about e is that it relies on an undocumented feature of emacsclient. It is assumed that emacsclient --alternate-editor /usr/bin/false … returns the exit code of false if the alternate editor is used and that it returns SUCCESS if the server can successfully be contacted.
– TN
I’ve simplified this down to the following shell script, which I keep in ~/bin/e:
if [ -z "$1" ] then TMP="$(mktemp /tmp/stdin-XXX)" cat >$TMP emacsclient -a emacs $TMP rm $TMP else emacsclient -a emacs "$@" fi
It’s not quite the same but I value the simplicity of it. With this you no longer need ‘e -’ to indicate STDIN, e will just look for STDIN whenever no files are specified.
If you happen to be using Eshell, you can get this via:
cat myfile > (switch-to-buffer "*my-buf*")
See: SettingFrameColorsForEmacsClient
This function will ask if you want to save any modified buffers, quit your session, and shutdown the associated emacs server instance.
Add the below code to your .emacs file. Call it w/ M-x server-shutdown
;; define function to shutdown emacs server instance (defun server-shutdown () "Save buffers, Quit, and Shutdown (kill) server" (interactive) (save-some-buffers) (kill-emacs) )
You can start different emacs server instances w/ different color schemes (so you instantly know which one your using).
This works to set the background color:
emacs --daemon=todo --background-color='#93DB80' emacs --daemon=edit --background-color=yellow
But if you try setting the cursor color – it fails miserably.
Another, more flexible option:
Example scripts for starting different instances of emacs server:
#!/bin/bash export ESRVNAME=todo emacs --daemon=$ESRVNAME
or
#!/bin/bash export ESRVNAME=edit emacs --daemon=$ESRVNAME ps -ef | grep -i 'emacs --daemon'
Also see http://www.gnu.org/s/libtool/manual/emacs/Emacs-Server.html#Emacs-Server
Set your color choices in your .emacs file:
;; set colors for my emacs server instances (defvar esrvname (getenv "ESRVNAME")) ;; is there a var that provides the server-name? (ignore-errors ;; this prevents error when environment variable is not set (when (string-match "todo" esrvname) (setq default-frame-alist (append default-frame-alist '((background-color . "#93DB80") (cursor-color . "yellow") ))) ;; or set a color-theme, e.g., (color-theme-classic) ) (when (string-match "edit" esrvname) (setq default-frame-alist (append default-frame-alist '((background-color . "yellow") ;; (foreground-color . "black") (cursor-color . "blue") ))) ) )
An example script for starting emacsclient (for different instances of emacs server):
#!/bin/bash
emacsclient -s edit -c "$@"
This allows you to pass any parameters to emacsclient, e.g., filenames, or even the ‘-t’ (or ‘-nw’) option (it will override the ‘-c’)
Another example:
#!/bin/bash umask 0007 # you can set a different umask than your default for emcas session cd ~/docs/todo/ emacsclient -s todo -c ~/docs/todo/work.org &
Also see: http://www.gnu.org/s/libtool/manual/emacs/emacsclient-Options.html#emacsclient-Options
In KDE, you can set File Associations to open in emacsclient instead of KWrite.