The Problem
I want to install Emacs on a USB Flash Drive in a portable fashion, that is, Emacs should be able to be run from the UFD, once plugged on a device, without predefined paths to its binaries and save all its persistent data on the UFD.
To obtain this, the Emacs startup script (possibly in the form of an icon for the user to click on) should be able to find the relevant binaries and set the needed directory paths.
Hereafter I take Windows as an example, but my concepts are not platform-specific.
In Windows 90% of the work for a portable Emacs is already done by GNU Emacs, because Emacs for Windows comes as a zipped package, without an installer. According to the docs you have to:
Unzip the zip file preserving the directory structure, and run
bin\runemacs.exe
. Alternatively, create a desktop shortcut tobin\runemacs.exe
, and start Emacs by double-clicking on that shortcut's icon.
Anyway, when extracting on a UFD, persistent data will not be stored on the UFD, but on the home directory of the host system.
This is what I tried
Let us assume that Emacs has been extracted as emacs
on the root of the UFD, where there is also a docs
folder. In the root I therefore create the following batch script to bootstrap Emacs:
Emacs.cmd
---------
set "HOME=%~dp0docs"
emacs\bin\runemacs.exe -q --load emacs\init.el %*
Script Explanation
-q
solves side effects due to unwanted reading/writing of init files on the host system.
At the same time, this requires that some init file equivalent is manually loaded with the --load
part. An alternative would be using site-start.el
, not bypassed by -q
.
Note that paths are relative to the position of the script so there is no need to guess the UFD drive letter.
The same is not true for the home dir. In this case I use the %~dp0
trick, which is converted by the shell to the script parent dir (somewhat like $(dirname "$0")
in Bash).
%*
lets add add extra arguments to runemacs
, when running Emacs.cmd
from the console.
Given -q
is intended to make a slimmer Emacs, some default settings might be missing and if you need them you have to manually set them in emacs\init.el
. By reading superficially Emacs startup.el
code, one such missing item is:
(package-initialize)
which should be added to emacs\init.el
or alternatively to site-start.el
This setup works pretty well. So now I come to the actual
Question
In the setup above, where the HOME
dir is used to store documents, therefore it would be nice and make sense to have the Emacs settings directory, .emacs.d
, outside the document folder.
According to the documentation it should be possible to obtain this result by properly setting the variable user-emacs-directory
. Therefore, the following lines should be added to the head of the init file called by the bootstrap script:
init.el
-------
(setq user-emacs-directory
(expand-file-name (concat invocation-directory "../.emacs.d")))
(setq abbrev-file-name
(locate-user-emacs-file "abbrev_defs"))
(setq auto-save-list-file-prefix
(locate-user-emacs-file "auto-save-list/.saves-"))
(cd "~"))
Despite the -q
switch, before running init.el
other code is run (this is why the abbreviations and the auto-save directory require a separate setup).
These settings work only partially. In fact, an empty ~/.emacs.d
keeps appearing in the home dir.
What library creates the folder?
Is it possible to avoid to make the HOME
folder dirty?
Debugging startup.el
would help, but it is not possible, as it is a fake file. Its actual content is dumped into the Emacs binary.
.emacs.d
, and the real HOME in my pseudo-init like:(setenv "HOME" (expand-file-name (concat invocation-directory "../../doc")))
?user-emacs-directory
, not necessarily outsideHOME
. @phil suggested this idea of a dynamicHOME
, but it does not work. Emacs can't find system/config files any more and, when it absolutely needs to write config files, it consequently stalls. Anyway, since I don't see other possiblities, I am determined to investigate this path. ... will let u know`