Literate programming is the cool thing.

This commit is contained in:
Derek Taylor 2020-07-18 14:12:14 -05:00
parent 15f669f1ce
commit 12a7c416a5
6 changed files with 689 additions and 58 deletions

View File

@ -1,53 +0,0 @@
# My Qtile Configuration
![Screenshot of my desktop](https://www.gitlab.com/dwt1/dotfiles/raw/master/.screenshots/dotfiles07.png)
A full-featured, pure-Python tiling window manager
# Features
* Simple, small and extensible. It's easy to write your own layouts,
widgets and commands.
* Configured in Python.
* Command shell that allows all aspects of Qtile to be managed and
inspected.
* Complete remote scriptability - write scripts to set up workspaces,
manipulate windows, update status bar widgets and more.
* Qtile's remote scriptability makes it one of the most thoroughly
unit-tested window managers around.
# My Keybindings
The MODKEY is set to the Super key (aka the Windows key). I try to keep the
keybindings consistent with all of my window managers.
| Keybinding | Action |
| :--- | :--- |
| `MODKEY + RETURN` | opens terminal (alacritty is the terminal but can be easily changed) |
| `MODKEY + SHIFT + RETURN` | opens run launcher (dmenu is the run launcher but can be easily changed) |
| `MODKEY + TAB` | rotates through the available layouts |
| `MODKEY + SHIFT + c` | closes window with focus |
| `MODKEY + SHIFT + r` | restarts qtile |
| `MODKEY + SHIFT + q` | quits qtile |
| `MODKEY + 1-9` | switch focus to workspace (1-9) |
| `MODKEY + SHIFT + 1-9` | send focused window to workspace (1-9) |
| `MODKEY + j` | lazy layout up (switches focus between windows in the stack) |
| `MODKEY + k` | lazy layout down (switches focus between windows in the stack) |
| `MODKEY + SHIFT + j` | lazy layout shuffle_up (rotates the windows in the stack) |
| `MODKEY + SHIFT + k` | lazy layout shuffle_down (rotates the windows in the stack) |
| `MODKEY + h` | expand size of window (MondadTall layout) |
| `MODKEY + l` | shrink size of window (MondadTall layout) |
| `MODKEY + w` | switch focus to monitor 1 |
| `MODKEY + e` | switch focus to monitor 2 |
| `MODKEY + r` | switch focus to monitor 3 |
| `MODKEY + period` | switch focus to next monitor |
| `MODKEY + comma` | switch focus to prev monitor |
# Community
Qtile is supported by a dedicated group of users. If you need any help, please
don't hesitate to fire off an email to our mailing list or join us on IRC.
* Mailing List: http://groups.google.com/group/qtile-dev
* IRC: irc://irc.oftc.net:6667/qtile

686
.config/qtile/README.org Normal file
View File

@ -0,0 +1,686 @@
#+TITLE: Qtile Config
#+PROPERTY: header-args :tangle config.py
* Table of Contents :toc:
- [[#about-this-config][About This Config]]
- [[#features-of-qtile][Features of Qtile]]
- [[#imports][Imports]]
- [[#variables][Variables]]
- [[#keybindings][Keybindings]]
- [[#groups][Groups]]
- [[#settings-for-some-layouts][Settings For Some Layouts]]
- [[#layouts][Layouts]]
- [[#colors][Colors]]
- [[#prompt][Prompt]]
- [[#default-widget-settings][Default Widget Settings]]
- [[#widgets][Widgets]]
- [[#screens][Screens]]
- [[#drag-floating-windows][Drag floating windows]]
- [[#floating-windows][Floating windows]]
- [[#startup-applications][Startup applications]]
* About This Config
#+CAPTION: Qtile Scrot
#+ATTR_HTML: :alt Qtile Scrot :title Qtile Scrot :align left
[[https://gitlab.com/dwt1/dotfiles/-/raw/master/.screenshots/dotfiles07-thumb.png]]
The following comments are the copyright and licensing information from the default
qtile config. Copyright (c) 2010 Aldo Cortesi, 2010, 2014 dequis, 2012 Randall Ma,
2012-2014 Tycho Andersen, 2012 Craig Barnes, 2013 horsik, 2013 Tao Sauvage
Modified by Derek Taylor (http://www.gitlab.com/dwt1/ )
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
* Features of Qtile
- Simple, small and extensible. It's easy to write your own layouts, widgets and commands.
- Configured in Python.
- Command shell that allows all aspects of Qtile to be managed and inspected.
- Complete remote scriptability - write scripts to set up workspaces, manipulate windows, update status bar widgets and more.
- Qtile's remote scriptability makes it one of the most thoroughly unit-tested window managers around.
* Imports
These are python modules that must be imported for this config.
#+BEGIN_SRC python
# -*- coding: utf-8 -*-
import os
import re
import socket
import subprocess
from libqtile.config import Key, Screen, Group, Drag, Click
from libqtile.command import lazy
from libqtile import layout, bar, widget, hook
from typing import List # noqa: F401
#+END_SRC
* Variables
Just some variables I am setting to make my life easier.
#+BEGIN_SRC python
mod = "mod4" # Sets mod key to SUPER/WINDOWS
myTerm = "alacritty" # My terminal of choice
myConfig = "/home/dt/.config/qtile/config.py" # The Qtile config file location
#+END_SRC
* Keybindings
These are the keybindings for qtile.
#+BEGIN_SRC python
keys = [
### The essentials
Key([mod], "Return",
lazy.spawn(myTerm),
desc='Launches My Terminal'
),
Key([mod, "shift"], "Return",
lazy.spawn("dmenu_run -p 'Run: '"),
desc='Dmenu Run Launcher'
),
Key([mod], "Tab",
lazy.next_layout(),
desc='Toggle through layouts'
),
Key([mod, "shift"], "c",
lazy.window.kill(),
desc='Kill active window'
),
Key([mod, "shift"], "r",
lazy.restart(),
desc='Restart Qtile'
),
Key([mod, "shift"], "q",
lazy.shutdown(),
desc='Shutdown Qtile'
),
Key(["control", "shift"], "e",
lazy.spawn("emacsclient -c -a emacs"),
desc='Doom Emacs'
),
### Switch focus to specific monitor (out of three)
Key([mod], "w",
lazy.to_screen(0),
desc='Keyboard focus to monitor 1'
),
Key([mod], "e",
lazy.to_screen(1),
desc='Keyboard focus to monitor 2'
),
Key([mod], "r",
lazy.to_screen(2),
desc='Keyboard focus to monitor 3'
),
### Switch focus of monitors
Key([mod], "period",
lazy.next_screen(),
desc='Move focus to next monitor'
),
Key([mod], "comma",
lazy.prev_screen(),
desc='Move focus to prev monitor'
),
### Treetab controls
Key([mod, "control"], "k",
lazy.layout.section_up(),
desc='Move up a section in treetab'
),
Key([mod, "control"], "j",
lazy.layout.section_down(),
desc='Move down a section in treetab'
),
### Window controls
Key([mod], "k",
lazy.layout.down(),
desc='Move focus down in current stack pane'
),
Key([mod], "j",
lazy.layout.up(),
desc='Move focus up in current stack pane'
),
Key([mod, "shift"], "k",
lazy.layout.shuffle_down(),
desc='Move windows down in current stack'
),
Key([mod, "shift"], "j",
lazy.layout.shuffle_up(),
desc='Move windows up in current stack'
),
Key([mod], "h",
lazy.layout.grow(),
lazy.layout.increase_nmaster(),
desc='Expand window (MonadTall), increase number in master pane (Tile)'
),
Key([mod], "l",
lazy.layout.shrink(),
lazy.layout.decrease_nmaster(),
desc='Shrink window (MonadTall), decrease number in master pane (Tile)'
),
Key([mod], "n",
lazy.layout.normalize(),
desc='normalize window size ratios'
),
Key([mod], "m",
lazy.layout.maximize(),
desc='toggle window between minimum and maximum sizes'
),
Key([mod, "shift"], "f",
lazy.window.toggle_floating(),
desc='toggle floating'
),
Key([mod, "shift"], "m",
lazy.window.toggle_fullscreen(),
desc='toggle fullscreen'
),
### Stack controls
Key([mod, "shift"], "space",
lazy.layout.rotate(),
lazy.layout.flip(),
desc='Switch which side main pane occupies (XmonadTall)'
),
Key([mod], "space",
lazy.layout.next(),
desc='Switch window focus to other pane(s) of stack'
),
Key([mod, "control"], "Return",
lazy.layout.toggle_split(),
desc='Toggle between split and unsplit sides of stack'
),
### Dmenu scripts launched with ALT + CTRL + KEY
Key(["mod1", "control"], "e",
lazy.spawn("./.dmenu/dmenu-edit-configs.sh"),
desc='Dmenu script for editing config files'
),
Key(["mod1", "control"], "m",
lazy.spawn("./.dmenu/dmenu-sysmon.sh"),
desc='Dmenu system monitor script'
),
Key(["mod1", "control"], "p",
lazy.spawn("passmenu"),
desc='Passmenu'
),
Key(["mod1", "control"], "r",
lazy.spawn("./.dmenu/dmenu-reddio.sh"),
desc='Dmenu reddio script'
),
Key(["mod1", "control"], "s",
lazy.spawn("./.dmenu/dmenu-surfraw.sh"),
desc='Dmenu surfraw script'
),
Key(["mod1", "control"], "t",
lazy.spawn("./.dmenu/dmenu-trading.sh"),
desc='Dmenu trading programs script'
),
Key(["mod1", "control"], "i",
lazy.spawn("./.dmenu/dmenu-scrot.sh"),
desc='Dmenu scrot script'
),
### My applications launched with SUPER + ALT + KEY
Key([mod, "mod1"], "b",
lazy.spawn("tabbed -r 2 surf -pe x '.surf/html/homepage.html'"),
desc='lynx browser'
),
Key([mod, "mod1"], "l",
lazy.spawn(myTerm+" -e lynx gopher://distro.tube"),
desc='lynx browser'
),
Key([mod, "mod1"], "n",
lazy.spawn(myTerm+" -e newsboat"),
desc='newsboat'
),
Key([mod, "mod1"], "r",
lazy.spawn(myTerm+" -e rtv"),
desc='reddit terminal viewer'
),
Key([mod, "mod1"], "e",
lazy.spawn(myTerm+" -e neomutt"),
desc='neomutt'
),
Key([mod, "mod1"], "m",
lazy.spawn(myTerm+" -e sh ./scripts/toot.sh"),
desc='toot mastodon cli'
),
Key([mod, "mod1"], "t",
lazy.spawn(myTerm+" -e sh ./scripts/tig-script.sh"),
desc='tig'
),
Key([mod, "mod1"], "f",
lazy.spawn(myTerm+" -e sh ./.config/vifm/scripts/vifmrun"),
desc='vifm'
),
Key([mod, "mod1"], "j",
lazy.spawn(myTerm+" -e joplin"),
desc='joplin'
),
Key([mod, "mod1"], "c",
lazy.spawn(myTerm+" -e cmus"),
desc='cmus'
),
Key([mod, "mod1"], "i",
lazy.spawn(myTerm+" -e irssi"),
desc='irssi'
),
Key([mod, "mod1"], "y",
lazy.spawn(myTerm+" -e youtube-viewer"),
desc='youtube-viewer'
),
Key([mod, "mod1"], "a",
lazy.spawn(myTerm+" -e ncpamixer"),
desc='ncpamixer'
),
]
#+END_SRC
* Groups
Groups are really workspaces.
#+BEGIN_SRC python
group_names = [("WWW", {'layout': 'monadtall'}),
("DEV", {'layout': 'monadtall'}),
("SYS", {'layout': 'monadtall'}),
("DOC", {'layout': 'monadtall'}),
("VBOX", {'layout': 'monadtall'}),
("CHAT", {'layout': 'monadtall'}),
("MUS", {'layout': 'monadtall'}),
("VID", {'layout': 'monadtall'}),
("GFX", {'layout': 'floating'})]
groups = [Group(name, **kwargs) for name, kwargs in group_names]
for i, (name, kwargs) in enumerate(group_names, 1):
keys.append(Key([mod], str(i), lazy.group[name].toscreen())) # Switch to another group
keys.append(Key([mod, "shift"], str(i), lazy.window.togroup(name))) # Send current window to another group
#+END_SRC
* Settings For Some Layouts
Settings that I use in most layouts, so I'm defining them one time here.
#+BEGIN_SRC python
layout_theme = {"border_width": 2,
"margin": 6,
"border_focus": "e1acff",
"border_normal": "1D2330"
}
#+END_SRC
* Layouts
The layouts that I use, plus several that I don't use. Uncomment the layouts you want; comment out the ones that you don't want to use.
#+BEGIN_SRC python
layouts = [
#layout.MonadWide(**layout_theme),
#layout.Bsp(**layout_theme),
#layout.Stack(stacks=2, **layout_theme),
#layout.Columns(**layout_theme),
#layout.RatioTile(**layout_theme),
#layout.VerticalTile(**layout_theme),
#layout.Matrix(**layout_theme),
#layout.Zoomy(**layout_theme),
layout.MonadTall(**layout_theme),
layout.Max(**layout_theme),
layout.Tile(shift_windows=True, **layout_theme),
layout.Stack(num_stacks=2),
layout.TreeTab(
font = "Ubuntu",
fontsize = 10,
sections = ["FIRST", "SECOND"],
section_fontsize = 11,
bg_color = "141414",
active_bg = "90C435",
active_fg = "000000",
inactive_bg = "384323",
inactive_fg = "a0a0a0",
padding_y = 5,
section_top = 10,
panel_width = 320
),
layout.Floating(**layout_theme)
]
#+END_SRC
* Colors
Defining some colors for use in our panel.
#+BEGIN_SRC python
colors = [["#292d3e", "#292d3e"], # panel background
["#434758", "#434758"], # background for current screen tab
["#ffffff", "#ffffff"], # font color for group names
["#ff5555", "#ff5555"], # border line color for current tab
["#8d62a9", "#8d62a9"], # border line color for other tab and odd widgets
["#668bd7", "#668bd7"], # color for the even widgets
["#e1acff", "#e1acff"]] # window name
#+END_SRC
* Prompt
Settings for the qtile run prompt, even though I don't actually use this. I prefer to use dmenu instead.
#+BEGIN_SRC python
prompt = "{0}@{1}: ".format(os.environ["USER"], socket.gethostname())
#+END_SRC
* Default Widget Settings
Defining a few default widget key values.
#+BEGIN_SRC python
##### DEFAULT WIDGET SETTINGS #####
widget_defaults = dict(
font="Ubuntu Mono",
fontsize = 12,
padding = 2,
background=colors[2]
)
extension_defaults = widget_defaults.copy()
#+END_SRC
* Widgets
This is the bar, or the panel, and the widgets within the bar.
#+BEGIN_SRC python
def init_widgets_list():
widgets_list = [
widget.Sep(
linewidth = 0,
padding = 6,
foreground = colors[2],
background = colors[0]
),
widget.Image(
filename = "~/.config/qtile/icons/python.png",
mouse_callbacks = {'Button1': lambda qtile: qtile.cmd_spawn('dmenu_run')}
),
widget.GroupBox(
font = "Ubuntu Bold",
fontsize = 9,
margin_y = 3,
margin_x = 0,
padding_y = 5,
padding_x = 3,
borderwidth = 3,
active = colors[2],
inactive = colors[2],
rounded = False,
highlight_color = colors[1],
highlight_method = "line",
this_current_screen_border = colors[3],
this_screen_border = colors [4],
other_current_screen_border = colors[0],
other_screen_border = colors[0],
foreground = colors[2],
background = colors[0]
),
widget.Prompt(
prompt = prompt,
font = "Ubuntu Mono",
padding = 10,
foreground = colors[3],
background = colors[1]
),
widget.Sep(
linewidth = 0,
padding = 40,
foreground = colors[2],
background = colors[0]
),
widget.WindowName(
foreground = colors[6],
background = colors[0],
padding = 0
),
widget.TextBox(
text = '',
background = colors[0],
foreground = colors[4],
padding = 0,
fontsize = 37
),
widget.TextBox(
text = " ₿",
padding = 0,
foreground = colors[2],
background = colors[4],
fontsize = 12
),
widget.BitcoinTicker(
foreground = colors[2],
background = colors[4],
padding = 5
),
widget.TextBox(
text = '',
background = colors[4],
foreground = colors[5],
padding = 0,
fontsize = 37
),
widget.TextBox(
text = " 🌡",
padding = 2,
foreground = colors[2],
background = colors[5],
fontsize = 11
),
widget.ThermalSensor(
foreground = colors[2],
background = colors[5],
threshold = 90,
padding = 5
),
widget.TextBox(
text='',
background = colors[5],
foreground = colors[4],
padding = 0,
fontsize = 37
),
widget.TextBox(
text = " ⟳",
padding = 2,
foreground = colors[2],
background = colors[4],
fontsize = 14
),
widget.Pacman(
update_interval = 1800,
foreground = colors[2],
mouse_callbacks = {'Button1': lambda qtile: qtile.cmd_spawn(myTerm + ' -e sudo pacman -Syu')},
background = colors[4]
),
widget.TextBox(
text = "Updates",
padding = 5,
mouse_callbacks = {'Button1': lambda qtile: qtile.cmd_spawn(myTerm + ' -e sudo pacman -Syu')},
foreground = colors[2],
background = colors[4]
),
widget.TextBox(
text = '',
background = colors[4],
foreground = colors[5],
padding = 0,
fontsize = 37
),
widget.TextBox(
text = " 🖬",
foreground = colors[2],
background = colors[5],
padding = 0,
fontsize = 14
),
widget.Memory(
foreground = colors[2],
background = colors[5],
mouse_callbacks = {'Button1': lambda qtile: qtile.cmd_spawn(myTerm + ' -e htop')},
padding = 5
),
widget.TextBox(
text='',
background = colors[5],
foreground = colors[4],
padding = 0,
fontsize = 37
),
widget.Net(
interface = "enp6s0",
format = '{down} ↓↑ {up}',
foreground = colors[2],
background = colors[4],
padding = 5
),
widget.TextBox(
text = '',
background = colors[4],
foreground = colors[5],
padding = 0,
fontsize = 37
),
widget.TextBox(
text = " Vol:",
foreground = colors[2],
background = colors[5],
padding = 0
),
widget.Volume(
foreground = colors[2],
background = colors[5],
padding = 5
),
widget.TextBox(
text = '',
background = colors[5],
foreground = colors[4],
padding = 0,
fontsize = 37
),
widget.CurrentLayoutIcon(
custom_icon_paths = [os.path.expanduser("~/.config/qtile/icons")],
foreground = colors[0],
background = colors[4],
padding = 0,
scale = 0.7
),
widget.CurrentLayout(
foreground = colors[2],
background = colors[4],
padding = 5
),
widget.TextBox(
text = '',
background = colors[4],
foreground = colors[5],
padding = 0,
fontsize = 37
),
widget.Clock(
foreground = colors[2],
background = colors[5],
format = "%A, %B %d [ %H:%M ]"
),
widget.Sep(
linewidth = 0,
padding = 10,
foreground = colors[0],
background = colors[5]
),
widget.Systray(
background = colors[0],
padding = 5
),
]
return widgets_list
#+END_SRC
* Screens
Screen settings for my triple monitor setup.
#+BEGIN_SRC python
def init_widgets_screen1():
widgets_screen1 = init_widgets_list()
return widgets_screen1 # Slicing removes unwanted widgets on Monitors 1,3
def init_widgets_screen2():
widgets_screen2 = init_widgets_list()
return widgets_screen2 # Monitor 2 will display all widgets in widgets_list
def init_screens():
return [Screen(top=bar.Bar(widgets=init_widgets_screen1(), opacity=1.0, size=20)),
Screen(top=bar.Bar(widgets=init_widgets_screen2(), opacity=1.0, size=20)),
Screen(top=bar.Bar(widgets=init_widgets_screen1(), opacity=1.0, size=20))]
if __name__ in ["config", "__main__"]:
screens = init_screens()
widgets_list = init_widgets_list()
widgets_screen1 = init_widgets_screen1()
widgets_screen2 = init_widgets_screen2()
#+END_SRC
* Drag floating windows
Defining some mousebindings for use with floating windows.
#+BEGIN_SRC python
mouse = [
Drag([mod], "Button1", lazy.window.set_position_floating(),
start=lazy.window.get_position()),
Drag([mod], "Button3", lazy.window.set_size_floating(),
start=lazy.window.get_size()),
Click([mod], "Button2", lazy.window.bring_to_front())
]
dgroups_key_binder = None
dgroups_app_rules = [] # type: List
main = None
follow_mouse_focus = True
bring_front_click = False
cursor_warp = False
#+END_SRC
* Floating windows
Defining what class of windows should always be floating.
#+BEGIN_SRC python
floating_layout = layout.Floating(float_rules=[
{'wmclass': 'confirm'},
{'wmclass': 'dialog'},
{'wmclass': 'download'},
{'wmclass': 'error'},
{'wmclass': 'file_progress'},
{'wmclass': 'notification'},
{'wmclass': 'splash'},
{'wmclass': 'toolbar'},
{'wmclass': 'confirmreset'}, # gitk
{'wmclass': 'makebranch'}, # gitk
{'wmclass': 'maketag'}, # gitk
{'wname': 'branchdialog'}, # gitk
{'wname': 'pinentry'}, # GPG key password entry
{'wmclass': 'ssh-askpass'}, # ssh-askpass
])
auto_fullscreen = True
focus_on_window_activation = "smart"
#+END_SRC
* Startup applications
The applications that should autostart every time qtile is started.
#+BEGIN_SRC python
@hook.subscribe.startup_once
def start_once():
home = os.path.expanduser('~')
subprocess.call([home + '/.config/qtile/autostart.sh'])
# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
# string besides java UI toolkits; you can see several discussions on the
# mailing lists, GitHub issues, and other WM documentation that suggest setting
# this string if your java app doesn't work correctly. We may as well just lie
# and say that we're a working one by default.
#
# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
# java that happens to be on java's whitelist.
wmname = "LG3D"
#+END_SRC

View File

@ -94,4 +94,3 @@
(custom-set-faces
)
(put 'downcase-region 'disabled nil)

View File

@ -1,5 +1,6 @@
#+TITLE: DT's Doom Emacs Config
#+AUTHOR: Derek Taylor (DT)
#+STARTUP: showeverything
** FONTS
Doom exposes five (optional) variables for controlling fonts in Doom. Here

View File

@ -33,8 +33,8 @@ Xmonad is a dynamically tiling X11 window manager that is written and
configured in Haskell. Official documentation: https://xmonad.org
This is the xmonad configuration of Derek Taylor (DistroTube)
My YouTube: http://www.youtube.com/c/DistroTube
My GitLab: http://www.gitlab.com/dwt1/
- My YouTube: http://www.youtube.com/c/DistroTube
- My GitLab: http://www.gitlab.com/dwt1/
Keep in mind, that my configs are purposely bloated with examples of
what you can do with xmonad. It is written more as a study guide rather
@ -67,7 +67,6 @@ import Data.Char (isSpace)
import Data.Monoid
import Data.Maybe (isJust)
import Data.Tree
import qualified Data.Tuple.Extra as TE
import qualified Data.Map as M
-- Hooks

View File

@ -21,7 +21,6 @@ import Data.Char (isSpace)
import Data.Monoid
import Data.Maybe (isJust)
import Data.Tree
import qualified Data.Tuple.Extra as TE
import qualified Data.Map as M
-- Hooks