This repository lists my configuration for GNU Emacs, my primary editor. The installation instructions and customizations should work on a GNU/Linux platform and are not extensively tested on Windows. Suggestions and pull requests are welcome.
The Emacs version on Ubuntu is mostly outdated. There are a couple of PPAs [Emacs stable releases, Ubuntu Emacs Lisp] that we can use, but they may not include build flags I prefer. So, I suggest building Emacs from source [*Build GNU Emacs].
Add the following repository to install GCC v10 only if you are using Ubuntu 20.04. We do not need the following step if a more recent version version of GCC is already installed.
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
# Install gcc-10 packages with the required support for libgccjit
sudo apt install -y gcc-10 g++-10 libgccjit0 libgccjit-10-dev libjansson4 libjansson-dev
Use the following instructions to configure and build GNU Emacs from source.
wget https://ftp.gnu.org/gnu/emacs/emacs-29.4.tar.xz
tar -xf emacs-29.4.tar.xz
# Use GCC 10 or newer if you are on Ubuntu 20.04
# export CC=/usr/bin/gcc-11 CXX=/usr/bin/g++-11
make distclean
./autogen.sh
./configure --with-cairo --with-modules --without-compress-install --without-x-toolkit --with-gnutls=ifavailable --without-gconf --without-xwidgets --without-toolkit-scroll-bars --without-xaw3d --without-gsettings --without-mailutils --without-pop --without-kerberos --with-native-compilation=aot --with-json=ifavailable --with-harfbuzz --with-imagemagick --with-jpeg --with-png --with-rsvg --with-tiff=ifavailable --with-wide-int --with-xft --with-xml2 --with-xpm=ifavailable --with-gif=ifavailable --with-threads --with-included-regex --with-zlib --without-sound --with-dbus --with-tree-sitter=ifavailable CFLAGS="-O3 -mtune=native -march=native -fomit-frame-pointer -funroll-loops -floop-parallelize-all" prefix=$HOME/.local
# Use NATIVE_FULL_AOT=1 to native compile ahead-of-time all the elisp files
# included in the Emacs distribution instead of after startup
make -j"$(nproc)" NATIVE_FULL_AOT=1
make install
Try the following if the build fails: make bootstrap
or rm lisp/loaddefs.el; make;
.
Back up the contents of your .emacs.d
directory if it is not empty, and then check out the source.
git clone https://github.com/swarnendubiswas/dotemacs.git .emacs.d
We use straight.el as the package manager, and the setup should work on most Linux systems.
Try the following resolution in case there is an error trying to connect to “raw.githubusercontent.com:443”.
git clone -b develop https://github.com/raxod502/straight.el ~/.emacs.d/straight/repos/straight.el
Comment the bootstrap code in init.el
and add the following snippet.
(load "~/.emacs.d/straight/repos/straight.el/bootstrap.el" 'nomessage)
(load "~/.emacs.d/straight/repos/straight.el/straight.el" 'nomessage)
Comment the recipe for nongnu-elpa
in bootstrap.el
if there is an error while cloning.
Build and install texinfo
if there is an error about the unavailability of makeinfo
.
extras
- third-party packages (may not be available from the package archives)snippets
- custom snippetsreferences
- documentation and help files
The following are examples of a few customization options defined in init.el. Please check the file for more customization options.
sb/theme
– Set the desired theme from a bunch of themes (default ismodus-vivendi
)sb/modeline-theme
– Set the desired modeline theme (default ispowerline-nano
)sb/in-buffer-completion
- Choose eithercompany
orcorfu
for in-buffer completion at point (default iscompany
)
Support for LSP in GNU Emacs means you will usually not need to create tags separately. However, tags are still useful for languages that are not yet supported by lsp-mode
and to understand complicated project structures that a language server may not understand. I prefer Universal Ctags over GNU Global.
GNU Global has better database search support while Universal Ctags supports more languages. GNU Global can be built with support for Universal Ctags.
Use Universal Ctags (u-ctags
) with Citre
.
-R
– recursively scan for files-e
– use Emacs-compatible syntax--list-excludes
– check which patterns are excluded from processing--list-languages
– list supported languages--languages=Python
– include Python files
By default, Emacs expects a tag file by the name TAGS
in the current directory. Once the tag file is built, the following commands exercise the tag indexing feature.
M-x visit-tags-table <RET> FILE <RET>
– Select the tag fileFILE
to useM-. [TAG] <RET>
– Find the first definition ofTAG
. The default tag is the identifier under the cursor.M-*
– Pop back to where you invokedM-.
C-u M-.
– Find the next definition for the last tag
For more commands, see the Tags topic in the Emacs info document.
ctags -eR --exclude=*.py --exclude=*.json --exclude=*.js --exclude=build* --exclude=*.sh --exclude=*.xml --exclude=*.java --exclude=*.html --exclude=*.md --exclude=*.pbtxt --exclude=*.png --exclude=*.css --exclude=*.rst --exclude=bazel-* --exclude=doc --exclude=node_modules --exclude=.meteor --exclude='packages/*/.build/'
ctags -e -R --exclude=@.ctagsignore --languages=EmacsLisp .
ctags -eR -quiet=yes --exclude=@.ctagsignore .
ctags -eR --languages=Python
find . -name "*.tex" | ctags -e -quiet -L -
find src -name "*.py" | ctags -e -L -
find -L . -type f -iname "*.cpp" -o -iname "*.c" -o -iname "*.cc" -o -iname "*.h" -o -iname "*.hpp" -o -iname "*.cu" | ctags -e -L -
$ cat .ctagsignore
dir1
dir2
dir3
# Generate tags for LaTeX draft
find . -type f -iname "*.tex" -print >gtags.files
gtags -vc --gtagsconf=$HOME/.globalrc --gtagslabel=new-ctags
# Generate tags for .emacs.d directory find . \( -path "./servers" -o -path "./etc" -o -path "./var" -o -path "./tree-sitter" -o -path "./.cache" -o -path "./eglot-java-eclipse-jdt-cache" -o -path "./eln-cache" -o -path "./straight/build" -o -path "./snippets" -o -path "./company-dict" -o -path "./**/.git" -o -path "./.git" -o -path "./share" \) -prune -o \( -type f ! -name "*.elc" ! -name "*.js" ! -name "*.png" ! -name "*.svg" ! -name "*.gif" ! -name "*.txt" ! -name "*.rst" ! -name "*.html" ! -name "*.xml" \) -print | gtags -cv --gtagsconf=$HOME/.globalrc --gtagslabel=new-ctags -f -
Enable server support either through init.el
or as a systemd
service. I prefer the systemd
approach. Create a file $HOME/.config/systemd/user/emacs.service
with the following content.
[Unit]
Description=GNU Emacs Daemon
[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(progn (setq kill-emacs-hook 'nil) (kill-emacs))"
Restart=always
[Install]
WantedBy=default.target
- Enable the unit to start at login:
systemctl --user enable emacs.service
- Disable the unit to start at login:
systemctl --user disable emacs.service
- Start the service for the current session:
systemctl --user start emacs.service
- Stop the service for the current session:
systemctl --user stop emacs.service
- Restart the service for the current session:
systemctl --user restart emacs.service
Create emacs.desktop
and emacsclient.desktop
files in $HOME/.local/share/applications
with the following content.
[Desktop Entry]
Name=GNU Emacs
GenericName=Text Editor
Comment=Edit text
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
Exec=/usr/local/bin/emacs
Icon=emacs
Type=Application
Terminal=false
Categories=Development;TextEditor;Utility;
StartupWMClass=Emacs
Keywords=Text;Editor;
[Desktop Entry]
Name=GNU Emacsclient
GenericName=Text Editor
Comment=Edit text
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
Exec=emacsclient -c -a "" -n -F "'(fullscreen . maximized)" %f
Icon=emacs
Type=Application
Terminal=false
Categories=Development;TextEditor;Utility;
StartupWMClass=Emacs
Keywords=Text;Editor;
I use LSP over Tramp intensively, and LSP+Tramp is sluggish and fails often. It seems difficult to properly set up language servers with Tramp support. Therefore, I prefer to use Emacs in a terminal that has a much better performance. It is important to set up support for 24-bit colors and proper keybindings in the terminal for a good experience. I use Alacritty which is easy to customize.
Using Terminal Emacs over Tramp for editing remote files obviates the need for a remote language server.
Use the steps mentioned in the link Spacemacs Terminal to enable support for 24bit colors in the terminal.
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export TERM=xterm-24bit
Using export TERM=xterm-24bit
may lead to failures when accessing remote systems. In such cases, we can fall back to TERM=xterm-256color ssh -X <remote-path>
.
Start the Emacs daemon with emacs --daemon
. To run Emacsclient with a GUI, use emacsclient -c -a ""
, where -a ""
starts Emacs daemon and reattaches. To run Emacsclient in a terminal, use emacsclient -nw -q
or emacsclient -t -q -a ""
, where -t
starts the client in the terminal.
Add the following to your .bashrc
to use Emacsclient as your editor.
export ALTERNATE_EDITOR=""
export EDITOR="emacsclient -t" # $EDITOR opens in terminal
export VISUAL="emacsclient -c -a emacs" # $VISUAL opens in GUI mode
- Delete all
.elc
files:find $HOME/.emacs.d -name "*.elc" -delete
kill -s USR2 [pid]
killall -s USR2 emacs
pkill -USR2 emacs
Estimate the best possible startup time with emacs -q --eval
‘(message “%s” (emacs-init-time))’=.
There are a few choices to evaluate the performance of the configuration.
- Set
use-package-compute-statistics
and then invokeuse-package-report
- Use the package
benchmark-init
- Use the script
profile-dotemacs.el
as follows:emacs -Q -l $HOME/.emacs.d/extras/profile-dotemacs.el -f profile-dotemacs
- Disable prettifying symbols on auto-completion in
LaTeX-mode