Table of Contents
- 1. How to associate a file type with GNU Emacs
- 2. Second chapter (completely optional)
(This article is initially about how to integrate GNU Emacs with Windows 8, but part of this article also applies to older Windows. This article will be updated to include how to for later versions of Windows as well, if necessary.)
Normally, one is supposed to use something under “Change PC settings” or “Default Programs” to associate file types with apps (or programs), but associating things with GNU Emacs is going to be more than just using that for two reasons:
- you want to associate some new file types (or new file extensions) such as elisp files or org-mode files
- you don’t want to simply associate with runemacs or emacsclient: you want to pass some command line options to emacsclient.
This post is divided into two chapters. The first chapter is for beginners and everything I want beginners to learn from this post is contained in that chapter. The second chapter is a completely optional reading material, part of which not intended for beginners.
Ubuntu users should read instead: How to make Emacs the default text editor in Ubuntu.
You might want to read a section on EDITOR and VISUAL in the above link because that section is applicable to Windows as well.
1. How to associate a file type with GNU Emacs
For example, how to associate elisp files (with file extension
.el) with Emacs so that whenever you open an elisp file (through searching for that file in Search, or from tapping on it from File Explorer), they open in Emacs?
Step 1. Create a batch script named
Current Emacs or Notepad.bat with the following content:
"%~dp0emacsclientw.exe" --no-wait --alternate-editor=notepad %*
and place that batch script file in the Emacs bin folder which is the folder that contains
Step 2. Test the batch script by dragging a text file to the batch file (in File Explorer). When you do that, either that text file will open in Notepad or will open in Emacs.
Step 3. Find an elisp file, any elisp file, or just create one. Make the context menu of the elisp file appear (either by press and hold, or by right clicking on the file from File Explorer). Tap or click on “Open with…” or “Properties”. From there, figure out how to get the “How do you want to open this type of file?” box appear.
Step 4. See that the “how do you want to open this type of file” or “how do you want to open this file” box contains a checkbox with label “Use this app for all .el files” (which sometimes doesn’t appear), a list of apps, and a button with label “More options”. This box is pretty much self-explanatory. If you tap or click on “More options”, you’ll see a bigger list of apps and then if you scroll down to the bottom of the list, you will see “Look for an app in the Store” and “Look for another app on this PC”. You need to do two things here: first, make sure that the “Use this app for all .el files” checkbox is checked on, and if you don’t see that checkbox, don’t worry, in that case, just repeating these steps twice does the job. Second, tap on “Look for another app on this PC” and choose the batch script that we created in step 1. (By the way, when you repeat these steps for another file type, for example, org-mode files, you will see “Current Emacs or Notepad” as an item in the list of apps so you don’t have to “Look for another app on this PC” again.)
Step 5. Now we are going to make Emacs server start automatically whenever you start Emacs. That can be done by simply adding
(server-start) to your Emacs init file. Restart Emacs.
Finally, do not forget the troubleshooting tip which I will get to soon.
Now whenever you open an elisp file, it will open in the current Emacs session, if any, otherwise it will open in Notepad (hence the name of the batch script). If Emacs is not already running, you should launch Emacs first before opening an elisp file. This little inconvenience can be eliminated but that requires using Emacs daemon which I cannot recommend to most beginners.1
If you want the file to always open in a new frame, create another batch script named
Current Emacs (new frame) or Notepad.bat with the following content:
"%~dp0emacsclientw.exe" -c --no-wait --alternate-editor=notepad %*
and place that batch script file in the Emacs bin folder and use that instead.
Optionally, if you want to change icons associated with elisp files, you can use Default Programs Editor which is an extremely self-explanatory program.
You might notice that a window pops up and disappears within a second every time you open an elisp file. That temporary window shouldn’t be too distracting, but if you want to eliminate it, there are some ideas in the second chapter.
1.1. troubleshooting tip
If you find later that files that used to open in Emacs suddenly start opening in Notepad even when you already have Emacs running, that means that Emacs server is failing to start for some reason. In that case, executing
M-x server-force-delete and restarting Emacs might fix the problem.
2. Second chapter (completely optional)
2.1. what is
%~dp0 and why?
It is what enables us to make a batch script that is portable. See this Microsoft article.
Making things portable has some benefits. In my case, I have Emacs installed to a folder in OneDrive and the portable batch script is located in the same folder. When I get another Windows machine, Emacs and the batch script is available as soon as OneDrive sync is finished on that machine. My username happens to be different between machines, so the path to the Emacs binary is different between machines.
2.2. what is
%* and why is it not in quotes?
Opening files with paths that contain spaces seems to work fine with that and I am not quite sure how. See this thread.
2.3. why not –alternate-editor=”%~dp0runemacs.exe” ?
That does not pass the –debug-init option to runemacs.exe, therefore not something I would suggest to beginners. Running something like
runemacs some-file.txt without
--debug-init results in hiding of the error message (and the message about what to do about that error) by the newly visited file’s buffer.
2.4. why not –alternate-editor=”%~dp0runemacs.exe –debug-init” ?
That fails to do the expected thing for some reason and I would love to know how to make that work as expected.
2.5. how to eliminate that temporary window and why does it show up?
That’s a command prompt window. I suspect this window showing up is supposed to be a feature and not a bug. Maybe there is a way for bad guys to trick you into launching some scripts of evil without you noticing, if that command prompt window can be hidden.
Two candidates for workarounds may come to mind: (1) using a VBScript instead and (2) using a Powershell script instead. Problem with (1) is that file types cannot be associated with a VBScript, at least on my system. As for (2), same problem.
A workaround that works is to edit Windows Registry (rather than relying on writing a batch script), which is made easier with FileTypesMan. This workaround consists of these steps:
Step 1. associate the elisp files with
emacsclientw.exe from the “How do you want to open this type of file?” box.
Step 2. Open FileTypesMan and find the entry (in the upper pane) that has
emacsclientw.exe in its Type Name field, and select that entry.
Step 3. From the lower pane, double tap or double click on the only item (in the lower pane) and a window will show up. From that window, you add the necessary command line options to the line in the Command-Line field. For example, in my case, I change the line from
"C:\Users\Yoo\SkyDrive\run\Emacs\bin\emacsclientw.exe" --no-wait --alternate-editor=notepad "%1"
Now when you try to associate other file types from the “How do you want to open this type of file?” box, you will see “GNU EmacsClient (blah blah)” as an item in the list of apps. That is there not because of what you did with FileTypesMan, but because you did Step 1 at least once. But what that item “GNU EmacsClient (blah blah)” does is changed by what you did with FileTypesMan.
A con of this workaround: the file association created by this method might be system-wide rather than user-wide.
Another and the best workaround that works is to create an executable file that does the same job as the batch script. If you create one, you might want to share that with the Emacs community.
Emacs daemon is intended to be a ghost (a soul without a body) and beginners would find it difficult to troubleshoot the invisible Emacs daemon. It is for advanced users.