5.2 KiB
Desktop
I use Emacs as a Desktop Environment with the EXWM1 package. It allows Emacs to function as a complete tiling window manager for X112.
Profile
Setup the default shell profile to run Emacs as a desktop environment.
Append to the $PATH
Ensure that ~/.local/bin
added to the $PATH
variable.
PATH=$PATH:~/.local/bin export PATH
Launch on TTY1
When launching into a new session on TTY1
, if the display server is not running, run StartX3. This will launch the window manager.
if [ -z "${DISPLAY}" ] && [ "${XDG_VTNR}" -eq 1 ]; then exec startx fi
Create symbolic link
The system will look for the default shell profile at ~/.profile
. Create a symbolic link from this location to the configuration file defined.
(dotfiles/symlink "~/.emacs.d/config/profile" "~/.profile")
Window manager
My workflow includes launching the window manager with Xinit3, without the use of a display manager, controlling everything within Emacs.
exec dbus-launch --exit-with-session emacs -mm --debug-init
Create a symbolic link
Xinit3 reads its configuration from ~/.xinitrc
. Override this location with a link to the custom configuration.
(dotfiles/symlink "~/.emacs.d/config/xinitrc" "~/.xinitrc")
Browser integration
Write out the $BROWSER
variable so other applications can pick up the custom browser.
(setenv "BROWSER" dotfiles/browser)
Displays detection
When the window manager first launches the init-hook
executes, allowing us to define some custom logic.
-
Display time and date
-
Display battery info (if available)
In my personal configuration, I do not want the battery or time displayed within Emacs when it's not running as desktop environment because that information is typically already available.
(defun dotfiles/init-hook () (exwm-workspace-switch-create 1) (setq display-time-and-date t) (display-battery-mode 1) (display-time-mode 1))
Using autorandr
with pre configured profiles, switching screens (AKA hot plugging) is also handled through a hook.
(defun dotfiles/update-display () "Update the displays by forcing a change through autorandr." (dotfiles/run-in-background "autorandr --change --force"))
Shell interaction
Define a method to run an external process, allowing us to launch any application on a new process without interferring with Emacs.
(defun dotfiles/run (cmd) "Run an external process." (interactive (list (read-shell-command "λ "))) (start-process-shell-command cmd nil cmd))
Apply methods to the current call process to avoid issues with hooks.
(defun dotfiles/run-in-background (cmd) (let ((command-parts (split-string cmd "[ ]+"))) (apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
Place keybindings for executing shell commands behind SPC x
.
-
Run shell commands with
x
-
Run async shell commands with
z
(dotfiles/leader "x" '(:ignore t :which-key "Run") "xx" '(dotfiles/run :which-key "Run") "xz" '(async-shell-command :which-key "Async"))
Configuration
Connect our custom hooks and configure the input keys, a custom layer for key capture layers.
-
Enable
randr
support -
Pass through to Emacs
-
M-x
to Emacs -
C-g
to Emacs -
C-SPC
to Emacs
-
-
Bindings with
S
(Super / Win)-
Reset
S-r
-
Launch
S-&
-
Workspace
S-[1..9]
-
(use-package exwm :custom (exwm-workspace-show-all-buffers t) (exwm-input-prefix-keys '(?\M-x ?\C-g ?\C-\ )) (exwm-input-global-keys `(([?\s-r] . exwm-reset) ,@(mapcar (lambda (i) `(,(kbd (format "s-%d" i)) . (lambda () (interactive) (exwm-workspace-switch-create ,i)))) (number-sequence 1 9)))) :config (require 'exwm-randr) (exwm-randr-enable) (add-hook 'exwm-init-hook #'dotfiles/init-hook) (add-hook 'exwm-randr-screen-change-hook #'dotfiles/update-display) (add-hook 'exwm-update-class-hook (lambda () (exwm-workspace-rename-buffer exwm-class-name))) (dotfiles/update-display) (exwm-enable))