Instantly share code, notes, and snippets.

What would you like to do?
Use fennel to write the awesome-wm config

Fetch fennel.lua and what else into you need (e.g. fun) into your ~/.config/awesome/ directory

(local fun (require "fun"))
(local gears (require "gears"))
(local awful (require "awful"))
(require "awful.autofocus")
(local naughty (require "naughty"))
; Tools
(defn notify
(naughty.notify {:text text}))
(defn debug
(notify (gears.debug.dump_return x)))
(defn cset
[k v]
(fn [c]
(tset c k v)))
(defn cinv
(fn [c]
(let [v (. c k)]
(tset c k (not v)))))
(local modifiers {:mod "Mod4"
:shift "Shift"
:ctrl "Control"})
(defn map-mods
(->> mods
( (partial . modifiers))
(defn key
[mods key-code fun]
(awful.key (map-mods mods) key-code fun))
(defn btn
[mods btn-code fun]
(awful.button (map-mods mods) btn-code fun))
; Tag managment
(local layouts [
(local tags {})
(var current-tag-pos [0 0])
(defn set-tag-pos
[tag pos]
(let [[x y] pos]
(->> {"x-pos" x "y-pos" y}
(fun.each (partial awful.tag.setproperty tag)))))
(defn get-tag-pos
(->> ["x-pos" "y-pos"]
( (partial awful.tag.getproperty tag))
(defn tag-name
(let [[x y] pos ]
(.. "(" x " " y ")")))
(defn get-or-create-tag
(let [tn (tag-name pos)]
(when (not (. tags tn))
(let [[tag] (awful.tag [tn] mouse.screen (. layouts 1))]
(tset tags tn tag)
(set-tag-pos tag pos)))
(. tags tn)))
(defn view-current-tag
(awful.tag.viewonly (get-or-create-tag current-tag-pos)))
(defn view-all-tags
(let [ts (awful.tag.gettags mouse.screen)]
(each [_ t (pairs ts)]
(tset t :selected true))))
(defn select-tag-by-focused-client
(let [tags (: c :tags)]
(when (# tags)
(let [[tag] tags]
(set current-tag-pos (get-tag-pos tag))
(defn translate-pos
[pos off]
(let [[x y] pos
[off-x off-y] off]
[(+ x off-x) (+ y off-y)]))
(defn select-current-tag-by-offset
(let [tag (awful.tag.selected)]
(when tag
(set current-tag-pos (get-tag-pos tag))))
(set current-tag-pos (translate-pos current-tag-pos off))
(defn move-client-relative
[c off]
(awful.client.movetotag (get-or-create-tag (translate-pos current-tag-pos off)) c)
(select-current-tag-by-offset off))
(defn focus-client-by-offset
(awful.client.focus.byidx off)
(when client.focus
(defn arrange-tag
(when (not client.focus)
(let [c (awful.client.focus.history.get screen 0)]
(when c
(tset client :focus c))))
(let [cs (awful.client.visible screen)
bw (if (> (# cs) 1) 1 0)]
(fun.each (cset :border_width bw)
(defn unminimize-tag
(fun.each (fn [client]
(tset client :minimized false)
(: client :redraw))
(: tag :clients)))
; Main Config
(local global-keys
(key [:mod :shift :ctrl] "Escape" awesome.restart)
(key [:mod :shift] "a" view-all-tags)
(key [:mod] "h" (fn [] (select-current-tag-by-offset [-1 0])))
(key [:mod] "l" (fn [] (select-current-tag-by-offset [ 1 0])))
(key [:mod] "k" (fn [] (select-current-tag-by-offset [ 0 -1])))
(key [:mod] "j" (fn [] (select-current-tag-by-offset [ 0 1])))
(key [:mod] "space" (fn [] ( layouts 1)))
(key [:mod :shift] "space" (fn [] ( layouts -1)))
(key [:mod :ctrl] "space" awful.client.floating.toggle)
(key [:mod] "Tab" (fn [] (focus-client-by-offset 1)))
(key [:mod :shift] "Tab" (fn [] (focus-client-by-offset -1)))
(key [:mod :ctrl] "Tab" (fn [] (awful.client.swap.byidx 1)))
(key [:mod :shift :ctrl] "Tab" (fn [] (awful.client.swap.byidx -1)))
(key [:mod :shift] "BackSpace" (fn [] (unminimize-tag (awful.tag.selected))))
(local client-keys
(key [:mod] "Escape" (fn [c] (: c :kill)))
(key [:mod] "s" (cinv :sticky))
(key [:mod] "a" select-tag-by-focused-client)
(key [:mod] "x" (cinv :maximized_horizontal))
(key [:mod] "y" (cinv :maximized_vertical))
(key [:mod :shift] "h" (fn [c] (move-client-relative c [-1 0])))
(key [:mod :shift] "l" (fn [c] (move-client-relative c [ 1 0])))
(key [:mod :shift] "k" (fn [c] (move-client-relative c [ 0 -1])))
(key [:mod :shift] "j" (fn [c] (move-client-relative c [ 0 1])))
(local client-buttons
(btn [:mod] 1 awful.mouse.client.move)
(btn [:mod] 3 awful.mouse.client.resize)
(local rules [
{:rule {}
:properties {:focus true
:keys client-keys
:buttons client-buttons}}
; Wire everything up
(->> {"manage" (fn [c]
(awful.client.movetotag (get-or-create-tag current-tag-pos) c))
"mouse::enter" (fn [c]
; TODO if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier and awful.client.focus.filter(c) then
(if (awful.client.focus.filter c)
(tset client :focus c)))
"focus" (cset :border_color "#ff0000")
"unfocus" (cset :border_color "#000000")}
(fun.each (fn [event callback] (client.connect_signal event callback))))
(fn [s]
(: s :connect_signal "arrange" arrange-tag)))
(root.keys global-keys)
(tset awful.rules :rules rules)
(gears.wallpaper.set "#123")
local fennel = require("fennel")
fennel.path = fennel.path .. ";.config/awesome/?.fnl" -- assuming awesome was started from the users ~
table.insert(package.loaders or package.searchers, fennel.searcher)
require("cfg") -- load ~/.config/awesome/cfg.fnl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment