This package provides a partial interface for integrating Sway with Emacs. It is meant for those Emacs users who prefer to let their window manager deal with window management, and is designed to play well with Shackle, but it should work with other popup managers just as well.
Usage with pgtk Emacs require an extra bit of configuration, see the config example below.
The only directly usable feature as of now is the
sway-shackle-display-buffer-frame
function, which either creates a
new frame with a given buffer or focuses that buffer in the frame it’s
already displayed on. A reasonable default config with Shackle could
look like:
(setq shackle-default-rule '(:frame t)
shackle-display-buffer-frame-function 'sway-shackle-display-buffer-frame)
(sway-socket-tracker-mode)
(sway-undertaker-mode) ;; If you want to use :dedicate, read below.
(sway-x-focus-through-sway-mode) ;; Temporary workaround for Sway bug 6216
;; To use with pgtk Emacs, you *must* ensure that frame names are
;; unique. This is a way to achieve this:
(setq frame-title-format '("%b — GNU Emacs [" (:eval (frame-parameter (selected-frame) 'window-id)) "]"))
;; You may want to make this nicer, feel free to improve. The only
;; requirement is that each frame must have a strictly unique name on
;; that Emacs instance (name collisions with other programs, including
;; other Emacs processes, are not an issue )
sway.el
introduces a new Shackle rule, :dedicate t
, managed by
sway-undertaker-mode
. With :dedicate
, when a new frame is created
for a buffer, it is sway-dedicated to this buffer. If this buffer gets
buried, the frame gets closed immediately. For convenience, using this
frame in any other way than acting on that buffer (switching buffers,
splitting windows) will permanently deactivate the undertaker and make
it behave like a normal frame.
This package requires an Emacs with (preferably native) JSON support.
Your Emacs is built with native JSON iff C-h f
reports that the
function json-parse-buffer
is implemented in C.
Emacs has an issue keeping track of environment variables of client frames. To maintain access to the Sway socket, we need some tricks, that are automagically managed by `sway-socket-tracker-mode`.
I don’t use i3, but it would be trivial to implement i3-msg
along
sway-msg
, and the rest should work immediately. Feel free :)
(Notice that with i3 you won’t need sway-socket-tracker-mode
, frames
have a display
parameter).
(setq shackle-rules
`(("*Help*" :align t :select t)
;; ** Magit **
(magit-status-mode :same t)
((:custom
,(lambda (buffer)
(with-current-buffer buffer
(and
(eq major-mode 'magit-diff-mode)
magit-display-buffer-noselect))))
:select nil :frame t :dedicate t)
((:custom
,(lambda (buffer)
(with-current-buffer buffer
(bound-and-true-p magit-display-buffer-noselect))))
:select nil :frame nil :dedicate t)
(magit-log-mode :same t)
(magit-submodule-list-mode :same t)
(magit-revision-mode :same t)
(magit-process-mode :frame nil)
("COMMIT_EDITMSG" :popup t :select t)
("^magit.*$'" :regexp t :frame nil)
(" *transient*" :frame nil :popup t :select nil) ; Magit helper popups
;; ** Sunrise commander **
(sunrise-mode :custom (lambda (&rest _)))
;; ** Proced **
("*Proced*" :same t)
(" *Marked Processes*" :frame nil :popup t :select t)
;; ** Byte-compiler
("*Compile-Log*" :frame nil :popup t :select t)
;; ** Local variables warning **
("*Local Variables*" :same t :frame nil :popup t :select t)
;; ** Misc **
("*Org PDF LaTeX Output*" :select nil)
("*Org Preview LaTeX Output*" :select nil)
(" *undo-tree*" :frame nil)
("*Register Preview*" :frame nil :noselect t)
(flycheck-error-list-mode :select t)
((compilation-mode) :noselect t)
((inferior-scheme-mode "*shell*" "*eshell*") :popup t))
shackle-default-rule '(:frame t)
shackle-default-size 0.4
shackle-inhibit-window-quit-on-same-windows t
shackle-display-buffer-frame-function 'sway-shackle-display-buffer-frame)