Skip to content

Instantly share code, notes, and snippets.

@agent-kilo
Created February 28, 2025 03:24
Show Gist options
  • Select an option

  • Save agent-kilo/4e17f8ad547a8021488e1886b501dfc4 to your computer and use it in GitHub Desktop.

Select an option

Save agent-kilo/4e17f8ad547a8021488e1886b501dfc4 to your computer and use it in GitHub Desktop.
A script that provides a new command :rotate-sibling-frames for Jwno v0.9.11.
#
# rotate-sibling-frames-cmd.janet
#
# This script provides a new command :rotate-sibling-frames for Jwno v0.9.11.
# The command "rotates" the siblings of the current frame (including the current
# frame itself). Say we have a frame laid out like this, and sub-frame 1 is active:
#
# +---+---+---+
# | 1 | 2 | 3 |
# +-^-+---+---+
#
# The layout would look like this after calling the command:
#
# +---+---+---+
# | 2 | 3 | 1 |
# +---+---+-^-+
#
# And if we call it again:
#
# +---+---+---+
# | 3 | 1 | 2 |
# +---+-^-+---+
#
# It also works with vertical layouts.
#
# To try it out, put this file alongside your config file, and
#
# (import rotate-sibling-frames-cmd)
# (rotate-sibling-frames-cmd/enable jwno/context)
# # Bind the command to a key, for example
# (:define-key your-keymap "Win + Ctrl + R" :rotate-sibling-frames)
# (:set-keymap (in jwno/context :key-manager) your-keymap)
#
(import jwno/log)
(use jwno/util)
(defn call-frame-resized-hooks [hook-man frame-list]
(each fr frame-list
(def children (in fr :children))
# Only call hooks on leaf frames
(cond
(empty? children)
(:call-hook hook-man :frame-resized fr)
(= :window (get-in fr [:children 0 :type]))
(:call-hook hook-man :frame-resized fr)
(= :frame (get-in fr [:children 0 :type]))
(call-frame-resized-hooks hook-man (in fr :children)))))
(defn move-children [from to]
(def children (in from :children))
(def active (in from :current-child))
(each c children
(:add-child to c))
(table/setproto to (table/getproto from))
(put to :current-child active))
(defn calc-new-ratio [old-fr parent-fr dir]
# w1 - w1/w * wn = wn
(def old-rect (in old-fr :rect))
(def padded-parent-rect (:get-padded-rect parent-fr))
(case dir
:horizontal
(let [old-w (- (in old-rect :right)
(in old-rect :left))
parent-w (- (in padded-parent-rect :right)
(in padded-parent-rect :left))
new-w (/ (* old-w parent-w) (+ old-w parent-w))]
(/ new-w parent-w))
:vertical
(let [old-h (- (in old-rect :bottom)
(in old-rect :top))
parent-h (- (in padded-parent-rect :bottom)
(in padded-parent-rect :top))
new-h (/ (* old-h parent-h) (+ old-h parent-h))]
(/ new-h parent-h))
(errorf "unknown direction: %n" dir)))
(defn rotate-sub-frames [context fr]
(unless fr
(break))
(def wm (in context :window-manager))
(def dir (:get-direction fr))
(unless dir
# It's a leaf frame
(break))
(def children (in fr :children))
(def child-count (length children))
(when (>= 1 child-count)
# Top frame contains only one child frame
(break))
(def first-child (first children))
(def resized (array/slice children 1))
(with-activation-hooks wm
(def activate-new-frame
(= first-child (in fr :current-child)))
(def new-ratio (calc-new-ratio first-child fr dir))
(def new-frame
(do
(:insert-sub-frame fr child-count new-ratio)
(get-in fr [:children child-count])))
(move-children first-child new-frame)
(:close first-child)
(:transform new-frame (in new-frame :rect)) # re-calculate children rects
(array/push resized new-frame)
(call-frame-resized-hooks (in context :hook-manager) resized)
(:retile wm fr)
(when activate-new-frame
(:activate new-frame))
(:set-focus wm fr)))
(defn enable [context]
(def wm (in context :window-manager))
(:add-command (in context :command-manager) :rotate-sibling-frames
(fn []
(def cur-fr (:get-current-frame (in wm :root)))
(when (in cur-fr :monitor)
# Don't deal with top-level frames
(break))
(rotate-sub-frames context (in cur-fr :parent)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment