Skip to content

thblt/sway.el

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 

Repository files navigation

Sway ❤ Emacs

https://melpa.org/packages/sway-badge.svg http://stable.melpa.org/packages/sway-badge.svg

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 )

Extension to Shackle

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.

The socket problem

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`.

What about i3?

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).

Exemple Shackle configuration

(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)