initial commit of new dotfiles repo
This commit is contained in:
commit
fb4d968caf
66
.config/alacritty/alacritty.toml
Normal file
66
.config/alacritty/alacritty.toml
Normal file
@ -0,0 +1,66 @@
|
||||
working_directory = "/home/ezri"
|
||||
|
||||
[bell]
|
||||
animation = "EaseOutSine"
|
||||
color = "0x9a7c9d"
|
||||
duration = 200
|
||||
|
||||
[colors]
|
||||
draw_bold_text_with_bright_colors = false
|
||||
|
||||
[colors.bright]
|
||||
black = "0x3f3242"
|
||||
blue = "0x7587a6"
|
||||
cyan = "0xafc4db"
|
||||
green = "0x8f9d6a"
|
||||
magenta = "0x9b859d"
|
||||
red = "0xcf6a4c"
|
||||
white = "0xffffff"
|
||||
yellow = "0xf9ee98"
|
||||
|
||||
[colors.normal]
|
||||
black = "0x2d272f"
|
||||
blue = "0x7587a6"
|
||||
cyan = "0xafc4db"
|
||||
green = "0x8f9d6a"
|
||||
magenta = "0x9b859d"
|
||||
red = "0xcf6a4c"
|
||||
white = "0xa7a7a7"
|
||||
yellow = "0xf9ee98"
|
||||
|
||||
[colors.primary]
|
||||
background = "0x1e1e1e"
|
||||
foreground = "0x9a7c9d"
|
||||
|
||||
[cursor.style]
|
||||
blinking = "Always"
|
||||
shape = "underline"
|
||||
|
||||
[debug]
|
||||
highlight_damage = false
|
||||
render_timer = false
|
||||
|
||||
[font]
|
||||
size = 9
|
||||
|
||||
[font.bold]
|
||||
family = "JetBrainsMono Nerd Font"
|
||||
style = "Bold"
|
||||
|
||||
[font.bold_italic]
|
||||
family = "JetBrainsMono Nerd Font"
|
||||
style = "Semibold Italic"
|
||||
|
||||
[font.italic]
|
||||
family = "JetBrainsMono Nerd Font"
|
||||
style = "Italic"
|
||||
|
||||
[font.normal]
|
||||
family = "JetBrainsMono Nerd Font"
|
||||
style = "Regular"
|
||||
|
||||
[window]
|
||||
dynamic_padding = true
|
||||
dynamic_title = true
|
||||
opacity = 0.98
|
||||
title = "Terminal"
|
||||
92
.config/alacritty/alacritty.yml
Normal file
92
.config/alacritty/alacritty.yml
Normal file
@ -0,0 +1,92 @@
|
||||
colors:
|
||||
# Default colors
|
||||
primary:
|
||||
# background: '0x1b191b'
|
||||
# foreground: '0x9a7c9d'
|
||||
background: '0x1e1e1e'
|
||||
foreground: '0x9a7c9d'
|
||||
|
||||
# Normal colors
|
||||
normal:
|
||||
black: '0x2d272f'
|
||||
red: '0xcf6a4c'
|
||||
green: '0x8f9d6a'
|
||||
yellow: '0xf9ee98'
|
||||
blue: '0x7587a6'
|
||||
magenta: '0x9b859d'
|
||||
cyan: '0xafc4db'
|
||||
white: '0xa7a7a7'
|
||||
|
||||
# Bright colors
|
||||
bright:
|
||||
black: '0x3f3242'
|
||||
red: '0xcf6a4c'
|
||||
green: '0x8f9d6a'
|
||||
yellow: '0xf9ee98'
|
||||
blue: '0x7587a6'
|
||||
magenta: '0x9b859d'
|
||||
cyan: '0xafc4db'
|
||||
white: '0xffffff'
|
||||
|
||||
# normal:
|
||||
# black: '0x453f45'
|
||||
# red: '0xd27377'
|
||||
# green: '0x7e9d7c'
|
||||
# yellow: '0xd2c377'
|
||||
# blue: '0x7587a6'
|
||||
# magenta: '0xae96b0'
|
||||
# cyan: '0xb0c4c2'
|
||||
# white: '0xd6cad7'
|
||||
|
||||
# bright:
|
||||
# black: '0x453f45'
|
||||
# red: '0xd27377'
|
||||
# green: '0x7e9d7c'
|
||||
# yellow: '0xd2c377'
|
||||
# blue: '0x7587a6'
|
||||
# magenta: '0xae96b0'
|
||||
# cyan: '0xb0c4c2'
|
||||
# white: '0xd6cad7'
|
||||
|
||||
cursor:
|
||||
|
||||
style:
|
||||
blinking: Always
|
||||
shape: underline
|
||||
|
||||
|
||||
font:
|
||||
size: 9
|
||||
|
||||
normal:
|
||||
family: JetBrainsMono Nerd Font
|
||||
style: Regular
|
||||
bold:
|
||||
family: JetBrainsMono Nerd Font
|
||||
style: Bold
|
||||
italic:
|
||||
family: JetBrainsMono Nerd Font
|
||||
style: Italic
|
||||
bold_italic:
|
||||
family: JetBrainsMono Nerd Font
|
||||
style: Semibold Italic
|
||||
|
||||
window:
|
||||
title: Terminal
|
||||
dynamic_title: true
|
||||
opacity: 0.98
|
||||
dynamic_padding: true
|
||||
|
||||
bell:
|
||||
|
||||
animation: EaseOutSine
|
||||
duration: 200
|
||||
color: '0x9a7c9d'
|
||||
|
||||
working_directory: /home/ezri
|
||||
|
||||
draw_bold_text_with_bright_colors: false
|
||||
|
||||
debug:
|
||||
render_timer: false
|
||||
highlight_damage: false
|
||||
84
.config/dunst/dunstrc
Normal file
84
.config/dunst/dunstrc
Normal file
@ -0,0 +1,84 @@
|
||||
# -*-conf-unix-*-
|
||||
[global]
|
||||
|
||||
# Settings
|
||||
monitor = 0
|
||||
follow = none
|
||||
|
||||
# Window Geometry / Appearance
|
||||
width = 300
|
||||
origin = top-center
|
||||
offset = 0x-36
|
||||
height = 150
|
||||
|
||||
indicate_hidden = yes
|
||||
shrink = no
|
||||
transparency = 0
|
||||
notification_height = 0
|
||||
separator_height = 1
|
||||
padding = 5
|
||||
horizontal_padding = 5
|
||||
frame_width = 1
|
||||
background = "#1e1e1e"
|
||||
separator_color = frame
|
||||
corner_radius = 0
|
||||
title = Notification
|
||||
class = Dunst
|
||||
sort = yes
|
||||
|
||||
# Text Apperanace
|
||||
font = JetBrainsMono 9,Nebula 9
|
||||
line_height = 0
|
||||
markup = full
|
||||
#format = "<b>%a: %s</b>\n───────────────\n%b <i>%p</i>"
|
||||
format = "<span font-family='Nebula' font-size='11pt'>%a</span>\n<span font-family='JetBrainsMono' font-size='9pt'>%s</span>\n\n<span font-family='JetBrainsMono' font-size='8pt'>%b</span>"
|
||||
alignment = center
|
||||
vertical_alignment = top
|
||||
show_age_threshold = 120
|
||||
word_wrap = yes
|
||||
ellipsize = middle
|
||||
ignore_newline = no
|
||||
stack_duplicates = true
|
||||
hide_duplicate_count = false
|
||||
show_indicators = yes
|
||||
|
||||
# Icons
|
||||
icon_position = off
|
||||
|
||||
# History
|
||||
sticky_history = yes
|
||||
history_length = 20
|
||||
|
||||
# Misc
|
||||
dmenu = /usr/bin/rofi -dmenu -p dunst:
|
||||
browser = /usr/bin/firefox --new-tab
|
||||
always_run_script = true
|
||||
|
||||
startup_notification = true
|
||||
verbosity = mesg
|
||||
|
||||
ignore_dbusclose = false
|
||||
|
||||
# Mouse
|
||||
mouse_left_click = do_action, close_current
|
||||
mouse_middle_click = none
|
||||
mouse_right_click = none
|
||||
|
||||
[urgency_low]
|
||||
background = "#1e1e1e"
|
||||
#background = "#3B4252"
|
||||
foreground = "#9a7c9d"
|
||||
frame_color = "#3f3242"
|
||||
timeout = 10
|
||||
|
||||
[urgency_normal]
|
||||
background = "#1e1e1e"
|
||||
foreground = "#9b859d"
|
||||
frame_color = "#815986"
|
||||
timeout = 60
|
||||
|
||||
[urgency_critical]
|
||||
background = "#1e1e1e"
|
||||
foreground = "#cf6a4c"
|
||||
frame_color = "#cf6a4c"
|
||||
timeout = 0
|
||||
1
.config/eww/.python-version
Normal file
1
.config/eww/.python-version
Normal file
@ -0,0 +1 @@
|
||||
eww-modules
|
||||
13
.config/eww/colors.scss
Normal file
13
.config/eww/colors.scss
Normal file
@ -0,0 +1,13 @@
|
||||
$wallpaper: #1e1e1e;
|
||||
$foreground: #9a7c9d;
|
||||
|
||||
$bg0: #2d272f;
|
||||
$bg1: #3f3242;
|
||||
|
||||
$red: #cf6a4c;
|
||||
$green: #8f9d6a;
|
||||
$yellow: #f9ee98;
|
||||
$blue: #7587a6;
|
||||
$magenta: #9b859d;
|
||||
$cyan: #afc4db;
|
||||
$white: #a7a7a7;
|
||||
98
.config/eww/eww.scss
Normal file
98
.config/eww/eww.scss
Normal file
@ -0,0 +1,98 @@
|
||||
@import "colors";
|
||||
|
||||
* {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.root {
|
||||
color: $foreground;
|
||||
font-family: "JetBrains Mono";
|
||||
font-size: 8.5pt;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
// Probably needs to change
|
||||
&.bar {
|
||||
margin: 10px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
&.side {
|
||||
margin: 10px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
&.bg {
|
||||
background-color: $bg0;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.nebula {
|
||||
font-family: "Nebula";
|
||||
font-size: 1.2em;
|
||||
&.big,
|
||||
.big {
|
||||
font-size: 2em;
|
||||
}
|
||||
&.medium,
|
||||
.medium {
|
||||
font-size: 1.6em;
|
||||
|
||||
&.small {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-family: "Font Awesome 5 Free Solid";
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
.offline {
|
||||
color: $bg1;
|
||||
}
|
||||
|
||||
.special {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.big {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
// sway module
|
||||
|
||||
.sway--ws {
|
||||
color: $bg1;
|
||||
|
||||
&.sway--active {
|
||||
color: $foreground;
|
||||
}
|
||||
|
||||
&.sway--visible {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
&.sway--focused {
|
||||
.fill {
|
||||
background-color: $foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clock module
|
||||
|
||||
.clock--time {
|
||||
font-size: 20pt;
|
||||
}
|
||||
|
||||
.clock--date {
|
||||
font-size: 9pt;
|
||||
}
|
||||
170
.config/eww/eww.yuck
Normal file
170
.config/eww/eww.yuck
Normal file
@ -0,0 +1,170 @@
|
||||
;; Include modules
|
||||
(include "./modules/workspaces/workspaces.yuck")
|
||||
(include "./modules/clock/clock.yuck")
|
||||
(include "./modules/system/system.yuck")
|
||||
(include "./modules/network/network.yuck")
|
||||
(include "./modules/volume/volume.yuck")
|
||||
(include "./modules/aggietime/aggietime.yuck")
|
||||
(include "./modules/weather/weather.yuck")
|
||||
(include "./modules/timer/timer.yuck")
|
||||
(include "./modules/mpris/mpris.yuck")
|
||||
|
||||
;; Windows
|
||||
(defwidget leftbar--left
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(clock)
|
||||
(network)
|
||||
(vpn-network)
|
||||
(aggietime-shift)))
|
||||
|
||||
|
||||
(defwidget leftbar--center
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "centerbox"
|
||||
(system-name)))
|
||||
|
||||
(defwidget leftbar--right
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "end"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "rightbox"
|
||||
(sway-workspace :group "left")
|
||||
(sway-workspaces :group "left")))
|
||||
|
||||
(defwidget rightbar--left
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(sway-workspaces :group "right")
|
||||
(sway-workspace :group "right")))
|
||||
|
||||
(defwidget rightbar--hypr-left
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(hypr-workspaces :group "main")
|
||||
(hypr-workspace :group "main")))
|
||||
|
||||
(defwidget rightbar--center
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "centerbox"
|
||||
(system-name)))
|
||||
|
||||
(defwidget rightbar--right
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "end"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(mpris)
|
||||
(system-memory)
|
||||
(system-cpu-avg)
|
||||
(clock)))
|
||||
|
||||
(defwidget sidebar
|
||||
[]
|
||||
(box :orientation "v"
|
||||
:valign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "bar root"
|
||||
(clock)))
|
||||
|
||||
(defwindow leftbar
|
||||
:monitor 0
|
||||
:geometry (geometry :width "100%"
|
||||
:height "36px"
|
||||
:anchor "top center"):exclusive
|
||||
true
|
||||
:focusable false
|
||||
:stacking "fg"
|
||||
(centerbox :orientation "h"
|
||||
:class "bar root"
|
||||
(leftbar--left)
|
||||
(leftbar--center)
|
||||
(leftbar--right)))
|
||||
|
||||
(defwindow rightbar
|
||||
:monitor 1
|
||||
:geometry (geometry :width "100%"
|
||||
:height "26px"
|
||||
:anchor "top center"):exclusive
|
||||
true
|
||||
:focusable false
|
||||
:stacking "fg"
|
||||
(centerbox :orientation "h"
|
||||
:class "bar root"
|
||||
(rightbar--left)
|
||||
(rightbar--center)
|
||||
(rightbar--right)))
|
||||
|
||||
(defwindow network-status
|
||||
:monitor 0
|
||||
:geometry (geometry :width "200px"
|
||||
:height "0px"
|
||||
:x "80px"
|
||||
:y "0px"
|
||||
:anchor "top left")
|
||||
:exclusive false
|
||||
:focusable false
|
||||
:stacking "overlay"
|
||||
(box :orientation "v"
|
||||
:class "bar root bg"
|
||||
:visible {network--show-details}
|
||||
(network-detail)))
|
||||
|
||||
(defwindow lock-overlay-1
|
||||
:monitor 1
|
||||
:geometry (geometry :width "50%"
|
||||
:height "50%"
|
||||
:anchor "center"):exclusive
|
||||
false
|
||||
:focusable false
|
||||
:stacking "overlay"
|
||||
"testing")
|
||||
|
||||
(defwindow hypr-mainbar
|
||||
:monitor 0
|
||||
:geometry (geometry :width "100%"
|
||||
:height "36px"
|
||||
:anchor "top center"):exclusive
|
||||
true
|
||||
:focusable false
|
||||
:stacking "overlay"
|
||||
(centerbox :orientation "h"
|
||||
:class "bar root"
|
||||
(rightbar--hypr-left)
|
||||
(rightbar--center)
|
||||
(rightbar--right)))
|
||||
|
||||
(defwindow sidebar
|
||||
:monitor 0
|
||||
:geometry (geometry :width "210px"
|
||||
:height "1044px"
|
||||
:anchor "left bottom"):exclusive
|
||||
true
|
||||
:focusable false
|
||||
:stacking "fg"
|
||||
(sidebar))
|
||||
128
.config/eww/eww.yuck~
Normal file
128
.config/eww/eww.yuck~
Normal file
@ -0,0 +1,128 @@
|
||||
;; Include modules
|
||||
(include "./modules/workspaces/workspaces.yuck")
|
||||
(include "./modules/clock/clock.yuck")
|
||||
(include "./modules/system/system.yuck")
|
||||
(include "./modules/network/network.yuck")
|
||||
(include "./modules/volume/volume.yuck")
|
||||
|
||||
;; Windows
|
||||
(defwidget leftbar--left []
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(clock)
|
||||
(network)
|
||||
(vpn-network)))
|
||||
|
||||
|
||||
(defwidget leftbar--center []
|
||||
(box :orientation "h"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "centerbox"
|
||||
))
|
||||
|
||||
(defwidget leftbar--right []
|
||||
(box :orientation "h"
|
||||
:halign "end"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "rightbox"
|
||||
(sway-workspace :group "left")
|
||||
(sway-workspaces :group "left")))
|
||||
|
||||
(defwidget rightbar--left []
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(sway-workspaces :group "right")
|
||||
(sway-workspace :group "right")))
|
||||
|
||||
(defwidget rightbar--hypr-left []
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(hypr-workspaces :group "main")
|
||||
(hypr-workspace :group "main")))
|
||||
|
||||
(defwidget rightbar--center []
|
||||
(box :orientation "h"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "centerbox"
|
||||
))
|
||||
|
||||
(defwidget rightbar--right []
|
||||
(box :orientation "h"
|
||||
:halign "end"
|
||||
:space-evenly false
|
||||
:spacing 20
|
||||
:class "leftbox"
|
||||
(system-memory)
|
||||
(system-cpu-avg)
|
||||
(clock)))
|
||||
|
||||
(defwidget sidebar []
|
||||
(box :orientation "v"
|
||||
:valign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "bar root"
|
||||
(clock)))
|
||||
|
||||
(defwindow leftbar
|
||||
:monitor 1
|
||||
:geometry (geometry :width "100%"
|
||||
:height "36px"
|
||||
:anchor "top center")
|
||||
:exclusive true
|
||||
:focusable false
|
||||
:stacking "fg"
|
||||
(centerbox :orientation "h" :class "bar root"
|
||||
(leftbar--left)
|
||||
(leftbar--center)
|
||||
(leftbar--right)))
|
||||
|
||||
(defwindow rightbar
|
||||
:monitor 0
|
||||
:geometry (geometry :width "100%"
|
||||
:height "26px"
|
||||
:anchor "top center")
|
||||
:exclusive true
|
||||
:focusable false
|
||||
:stacking "fg"
|
||||
(centerbox :orientation "h" :class "bar root"
|
||||
(rightbar--left)
|
||||
(rightbar--center)
|
||||
(rightbar--right)))
|
||||
|
||||
(defwindow hypr-mainbar
|
||||
:monitor 0
|
||||
:geometry (geometry :width "100%"
|
||||
:height "36px"
|
||||
:anchor "top center")
|
||||
:exclusive true
|
||||
:focusable false
|
||||
:stacking "overlay"
|
||||
(centerbox :orientation "h" :class "bar root"
|
||||
(rightbar--hypr-left)
|
||||
(rightbar--center)
|
||||
(rightbar--right)))
|
||||
|
||||
(defwindow sidebar
|
||||
:monitor 1
|
||||
:geometry (geometry :width "210px"
|
||||
:height "1044px"
|
||||
:anchor "left bottom")
|
||||
:exclusive true
|
||||
:focusable false
|
||||
:stacking "fg"
|
||||
(sidebar))
|
||||
25
.config/eww/modules/aggietime/aggietime.sh
Executable file
25
.config/eww/modules/aggietime/aggietime.sh
Executable file
@ -0,0 +1,25 @@
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
shift_data=$(aggietimed -s /run/user/1000/aggietimed.sock --action current-shift 2>&1)
|
||||
|
||||
if [[ ${shift_data} == "null" ]]; then
|
||||
echo '{"active": false, "err": false}'
|
||||
exit
|
||||
fi
|
||||
|
||||
now=$(date +%s)
|
||||
start=$(date --date=$(echo $shift_data | jq '.start' -r) +%s)
|
||||
delta=$(( now - start ))
|
||||
fallback=$(date --date="" +%s)
|
||||
|
||||
if [[ $start == $fallback ]]; then
|
||||
echo '{"active": false, "err": true}'
|
||||
exit
|
||||
fi
|
||||
|
||||
hours=$(( delta / 3600 ))
|
||||
minutes=$( printf "%02d" $(( (delta - (hours * 3600)) / 60 )))
|
||||
seconds=$( printf "%02d" $(( delta - (hours * 3600) - (minutes * 60) )))
|
||||
|
||||
echo "{\"active\": true, \"hours\": \"$hours\", \"minutes\": \"$minutes\", \"seconds\": \"$seconds\", \"err\": false}"
|
||||
18
.config/eww/modules/aggietime/aggietime.yuck
Normal file
18
.config/eww/modules/aggietime/aggietime.yuck
Normal file
@ -0,0 +1,18 @@
|
||||
(defpoll aggietime--data :interval "10s"
|
||||
`~/.config/eww/modules/aggietime/aggietime.sh`)
|
||||
|
||||
(defwidget aggietime-shift []
|
||||
(box :class "module text"
|
||||
:spacing 0
|
||||
:orientation "v"
|
||||
:visible {aggietime--data != ''}
|
||||
(label :class "highlight"
|
||||
:text "AggieTimeD Not Running"
|
||||
:visible {aggietime--data.err})
|
||||
(label :class "special"
|
||||
:visible {aggietime--data.active && !aggietime--data.err}
|
||||
:text "${aggietime--data.hours}:${aggietime--data.minutes}")
|
||||
(label :class "highlight"
|
||||
:text "not clocked in"
|
||||
:visible {!aggietime--data.active && !aggietime--data.err})
|
||||
"current shift"))
|
||||
11
.config/eww/modules/angles/angles.yuck
Normal file
11
.config/eww/modules/angles/angles.yuck
Normal file
@ -0,0 +1,11 @@
|
||||
(defwidget left-angle []
|
||||
(image :path "/home/ezri/.config/eww.new/modules/angles/left.png"
|
||||
:width 150
|
||||
:height 36))
|
||||
|
||||
(defwidget right-angle []
|
||||
(image :path "/home/ezri/.config/eww.new/modules/angles/right.png"
|
||||
:width 150
|
||||
:height 36))
|
||||
|
||||
|
||||
BIN
.config/eww/modules/angles/left.png
Normal file
BIN
.config/eww/modules/angles/left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
.config/eww/modules/angles/right.png
Normal file
BIN
.config/eww/modules/angles/right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
10
.config/eww/modules/clock/clock.yuck
Normal file
10
.config/eww/modules/clock/clock.yuck
Normal file
@ -0,0 +1,10 @@
|
||||
(defpoll clock--data :interval "500ms"
|
||||
`date +'{"hour": "%H", "minute": "%M", "second": "%S", "year": "%Y", "day": "%d", "month": "%m", "dow": "%A", "month_name": "%B", "unix": %s}'`)
|
||||
|
||||
(defwidget clock []
|
||||
(box :class "module text"
|
||||
:spacing 0
|
||||
:orientation "v"
|
||||
(label :class "special"
|
||||
:text "${clock--data.hour}:${clock--data.minute}:${clock--data.second}")
|
||||
(label :text "${clock--data.year}-${clock--data.month}-${clock--data.day}")))
|
||||
148
.config/eww/modules/mpris/mpris.py
Executable file
148
.config/eww/modules/mpris/mpris.py
Executable file
@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import gi
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import requests
|
||||
|
||||
try:
|
||||
gi.require_version("Playerctl", "2.0")
|
||||
except:
|
||||
sys.exit(1)
|
||||
|
||||
from gi.repository import Playerctl, GLib
|
||||
|
||||
title_maxlen = 30
|
||||
title_end_at = ["(", "-"]
|
||||
artist_maxlen = 30
|
||||
album_maxlen = 30
|
||||
# Split on these characters, take the first part, and strip whitespace
|
||||
# from the result. This can be used to remove subtitles (like " - Remastered" or " (feat. Artist)").
|
||||
album_end_at = ["(", "-"]
|
||||
|
||||
|
||||
class Status:
|
||||
def __init__(self):
|
||||
self.running = False
|
||||
self.playing = False
|
||||
self.title = None
|
||||
self.artist = None
|
||||
self.album = None
|
||||
self.album_artist = None
|
||||
self.album_art = None
|
||||
|
||||
def _dict_dump(self):
|
||||
return {
|
||||
"running": self.running,
|
||||
"playing": self.playing,
|
||||
"title": self.title,
|
||||
"artist": self.artist,
|
||||
"album": self.album,
|
||||
"album_artist": self.album_artist,
|
||||
"album_art": self.album_art,
|
||||
}
|
||||
|
||||
def __str__(self):
|
||||
return json.dumps(self._dict_dump())
|
||||
|
||||
|
||||
class StatusDisplay:
|
||||
def __init__(self):
|
||||
self._player = None
|
||||
self.last_album_art = None
|
||||
|
||||
def show(self):
|
||||
self._init_player()
|
||||
|
||||
main = GLib.MainLoop()
|
||||
main.run()
|
||||
|
||||
def _get_status(self, playing=None):
|
||||
if self._player:
|
||||
status = Status()
|
||||
status.running = self._player.props.playback_status != 2
|
||||
if playing == None:
|
||||
status.playing = self._player.props.playback_status == 0
|
||||
else:
|
||||
status.playing = playing
|
||||
status.title = self._player.get_title() or ""
|
||||
status.artist = self._player.get_artist() or ""
|
||||
status.album = self._player.get_album() or ""
|
||||
album_art = (
|
||||
dict(self._player.get_property("metadata")).get("mpris:artUrl") or ""
|
||||
)
|
||||
if album_art != self.last_album_art:
|
||||
# Need to download the new album art
|
||||
self.last_album_art = album_art
|
||||
if album_art.startswith("file://"):
|
||||
album_art = album_art[7:]
|
||||
if os.path.exists(album_art):
|
||||
status.album_art = album_art
|
||||
else:
|
||||
try:
|
||||
r = requests.get(album_art, timeout=1)
|
||||
# Write album art to tmp file
|
||||
if r.status_code == 200:
|
||||
with open("/tmp/album_art", "wb") as f:
|
||||
f.write(r.content)
|
||||
status.album_art = "/tmp/album_art"
|
||||
except:
|
||||
pass
|
||||
|
||||
for end in title_end_at:
|
||||
if end in status.title:
|
||||
status.title = status.title.split(end)[0].strip()
|
||||
if len(status.title) > title_maxlen:
|
||||
status.title = status.title[: title_maxlen - 1] + "…"
|
||||
if len(status.artist) > artist_maxlen:
|
||||
status.artist = status.artist[: artist_maxlen - 1] + "…"
|
||||
for end in album_end_at:
|
||||
if end in status.album:
|
||||
status.album = status.album.split(end)[0].strip()
|
||||
if len(status.album) > album_maxlen:
|
||||
status.album = status.album[: album_maxlen - 1] + "…"
|
||||
|
||||
return status
|
||||
else:
|
||||
return Status()
|
||||
|
||||
def _print_status(self, status):
|
||||
print(status, flush=True)
|
||||
|
||||
def _init_player(self):
|
||||
success = False
|
||||
|
||||
while not success:
|
||||
try:
|
||||
self._player = Playerctl.Player()
|
||||
self._player.connect("metadata", self._on_update)
|
||||
self._player.connect("play", self._on_play)
|
||||
self._player.connect("pause", self._on_pause)
|
||||
self._player.connect("exit", self._on_exit)
|
||||
|
||||
self._print_status(self._get_status())
|
||||
|
||||
success = True
|
||||
except Exception as e:
|
||||
# print(e, flush=True, file=sys.stderr)
|
||||
self._print_status(Status())
|
||||
time.sleep(2)
|
||||
|
||||
def _on_update(self, *args):
|
||||
self._print_status(self._get_status())
|
||||
|
||||
def _on_play(self, *args):
|
||||
self._print_status(self._get_status(playing=True))
|
||||
|
||||
def _on_pause(self, *args):
|
||||
self._print_status(self._get_status(playing=False))
|
||||
|
||||
def _on_exit(self, player):
|
||||
del self._player
|
||||
self._player = None
|
||||
self._init_player()
|
||||
|
||||
|
||||
StatusDisplay().show()
|
||||
28
.config/eww/modules/mpris/mpris.yuck
Normal file
28
.config/eww/modules/mpris/mpris.yuck
Normal file
@ -0,0 +1,28 @@
|
||||
(deflisten mpris--data :initial "{}"
|
||||
`~/.config/eww/modules/mpris/mpris.py`)
|
||||
|
||||
(defwidget mpris
|
||||
[]
|
||||
(box :class "module text"
|
||||
:spacing 0
|
||||
:orientation "v"
|
||||
(label :class {mpris--data.playing ? "special" : "offline"}
|
||||
:visible {mpris--data.running}
|
||||
:text "${mpris--data.title} by ${mpris--data.artist}")
|
||||
(label :class "offline"
|
||||
:visible {!mpris--data.running}
|
||||
:text "player offline")
|
||||
(label :visible {mpris--data.running}
|
||||
:text "now playing from ${mpris--data.album}")
|
||||
(label :visible {!mpris--data.running}
|
||||
:text "player offline")))
|
||||
|
||||
|
||||
(defwidget mpris-miniplayer []
|
||||
(box :class "miniplayer"
|
||||
:orientation "v"
|
||||
:spacing 10
|
||||
(image :path {mpris--data.album_art}
|
||||
:image-width 100
|
||||
:image-height 100)
|
||||
(label)))
|
||||
86
.config/eww/modules/network/network.py
Executable file
86
.config/eww/modules/network/network.py
Executable file
@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
from time import sleep
|
||||
|
||||
TRUSTED_NETWORKS = ["honnouji", "honnouji_2.4"]
|
||||
|
||||
|
||||
def wifi():
|
||||
try:
|
||||
ssid_cmd = subprocess.run(["iwgetid", "-r"], capture_output=True)
|
||||
if ssid_cmd.returncode != 0:
|
||||
return {"connected": False, "ssid": None}
|
||||
return {"connected": True, "ssid": ssid_cmd.stdout.decode("utf-8").strip()}
|
||||
except:
|
||||
return {"connected": False, "ssid": None}
|
||||
|
||||
|
||||
def netdev(device: str):
|
||||
ip_cmd = subprocess.run(["ip", "-j", "addr", "show", device], capture_output=True)
|
||||
if ip_cmd.returncode != 0:
|
||||
sys.stderr.write(ip_cmd.stdout.decode("utf-8"))
|
||||
return {
|
||||
"exists": False,
|
||||
"online": False,
|
||||
"connecting": False,
|
||||
"offline": True,
|
||||
"ip4_addr": None,
|
||||
"ip4_prefix": None,
|
||||
}
|
||||
ip_data = json.loads(ip_cmd.stdout.decode("utf-8"))[0]
|
||||
online = ip_data["operstate"] == "UP"
|
||||
ip4_addr = ""
|
||||
ip4_prefix_length = 24
|
||||
addr4_info = list(
|
||||
filter(lambda addr: addr.get("family") == "inet", ip_data["addr_info"])
|
||||
)
|
||||
if len(addr4_info) >= 1:
|
||||
ip4_addr = addr4_info[0]["local"]
|
||||
ip4_prefix_length = addr4_info[0]["prefixlen"]
|
||||
connecting = ip_data["operstate"] != "DOWN" and (ip4_addr == "" or not online)
|
||||
return {
|
||||
"exists": True,
|
||||
"online": online,
|
||||
"connecting": connecting,
|
||||
"offline": not online and not connecting,
|
||||
"ip4_addr": ip4_addr,
|
||||
"ip4_prefix": ip4_prefix_length,
|
||||
}
|
||||
|
||||
|
||||
def trusted(ssid: str | None):
|
||||
# Don't throw up an "INSECURE" alert when offline
|
||||
if not ssid:
|
||||
return True
|
||||
return ssid in TRUSTED_NETWORKS
|
||||
|
||||
|
||||
while True:
|
||||
lan = netdev("lan")
|
||||
wlan = netdev("wlan0")
|
||||
vpn = netdev("ezrinet")
|
||||
mullvad = netdev("wg-mullvad")
|
||||
wifi_data = wifi()
|
||||
# VPNs are routed over physical interfaces, so don't check them for online status
|
||||
online = lan["online"] or wlan["online"]
|
||||
configuring = (lan["connecting"] and not wlan["online"]) or (
|
||||
wlan["connecting"] and not lan["online"]
|
||||
)
|
||||
result = {
|
||||
"online": online,
|
||||
"configuring": configuring,
|
||||
"offline": not online and not configuring,
|
||||
"network": {
|
||||
"lan": lan,
|
||||
"wlan": wlan,
|
||||
"vpn": vpn,
|
||||
"mullvad": mullvad,
|
||||
},
|
||||
"wifi": wifi_data,
|
||||
"trusted": True,
|
||||
}
|
||||
print(json.dumps(result), flush=True)
|
||||
sleep(1)
|
||||
249
.config/eww/modules/network/network.yuck
Normal file
249
.config/eww/modules/network/network.yuck
Normal file
@ -0,0 +1,249 @@
|
||||
(deflisten network--data
|
||||
`~/.config/eww/modules/network/new_network.py`)
|
||||
|
||||
(defvar network--show-details false)
|
||||
|
||||
(defwidget network-big
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:valign "center"
|
||||
:space-evenly false
|
||||
:spacing 10
|
||||
(label :class "big nebula"
|
||||
:text "comms:")
|
||||
(network--interface :device "lan")
|
||||
(network--interface :device "ezrinet")
|
||||
(network--secure)
|
||||
(network--vpn)))
|
||||
|
||||
(defwidget network--interface
|
||||
[device]
|
||||
(box :orientation "v"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :class "offline"
|
||||
:visible {!device.online}
|
||||
:text "offline")
|
||||
(label :visible {device.online}
|
||||
:class "special"
|
||||
:text "${device.addresses[0].address}/${device.addresses[0].prefixlen}")))
|
||||
|
||||
(defwidget network-big--online
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:valign "center"
|
||||
:space-evenly false
|
||||
:spacing 10
|
||||
(label :class "medium green nebula"
|
||||
:visible {network--data.online}
|
||||
:text "online")
|
||||
(label :class "medium offline nebula"
|
||||
:visible {network--data.offline}
|
||||
:text "offline")
|
||||
(label :class "medium highlight nebula"
|
||||
:visible {network--data.configuring}
|
||||
:text "configuring")))
|
||||
|
||||
(defwidget network-big--lan
|
||||
[device]
|
||||
(label :visible {network--data
|
||||
[device]
|
||||
.online}
|
||||
:class ""
|
||||
:text "${network--data.interfaces[device].addresses[0].address}/${network--data.interfaces[device].addresses[0].prefixlen}"))
|
||||
|
||||
(defwidget network--wlan
|
||||
[device]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :class "offline"
|
||||
:visible {network--data
|
||||
["network"]
|
||||
[device]
|
||||
["offline"]
|
||||
}
|
||||
:text "offline")
|
||||
(label :visible {network--data
|
||||
["network"]
|
||||
[device]
|
||||
["connecting"]
|
||||
}
|
||||
:class "highlight"
|
||||
:text "connecting...")
|
||||
(label :visible {network--data
|
||||
["network"]
|
||||
[device]
|
||||
["online"]
|
||||
}
|
||||
:class "special"
|
||||
:text "${network--data['wifi']['ssid']}")))
|
||||
|
||||
(defwidget network--lan
|
||||
[device]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :class "offline"
|
||||
:visible {!device.online}
|
||||
:text "offline")
|
||||
(label :visible {device.online}
|
||||
:class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"}
|
||||
:text "${device.addresses[0].address}/${device.addresses[0].prefixlen}")))
|
||||
|
||||
(defwidget network--secure
|
||||
[]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :class "highlight"
|
||||
:text "- insecure"
|
||||
:visible {!
|
||||
network--data.secure })
|
||||
(label :class "green"
|
||||
:text "- secured via ${network--data.secure_msg}"
|
||||
:visible {network--data.secure})))
|
||||
|
||||
(defwidget vpn-network
|
||||
[]
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:visible {network--data
|
||||
!=
|
||||
''}
|
||||
(label :class "highlight"
|
||||
:text "offline"
|
||||
:visible {!
|
||||
network--data.interfaces.ezrinet.online })
|
||||
(label :class "green"
|
||||
:text "connected"
|
||||
:visible {network--data.interfaces.ezrinet.online})
|
||||
"personal network"))
|
||||
|
||||
(defwidget network
|
||||
[]
|
||||
(button :onclick "eww update network--show-details=${!network--show-details}"
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:visible {network--data != ''}
|
||||
(box :orientation "h"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 10
|
||||
(network--lan :device {network--data.default_interface}))
|
||||
"communications")))
|
||||
|
||||
(defwidget network--public-ip
|
||||
[]
|
||||
(centerbox :orientation "h"
|
||||
:halign "start"
|
||||
:width 200
|
||||
(box :halign "start"
|
||||
"public ip:")
|
||||
""
|
||||
(box :halign "end"
|
||||
:spacing 0
|
||||
:space-evenly false
|
||||
(label :class "highlight"
|
||||
:text "offline"
|
||||
:visible {!network--data.online})
|
||||
(label :class "highlight"
|
||||
:text "no response"
|
||||
:visible {network--data.online && !network--data.have_public_ip})
|
||||
(label :class "special"
|
||||
:text {network--data.public_ip.ip}
|
||||
:visible {network--data.online && network--data.have_public_ip}))))
|
||||
|
||||
(defwidget network--default-route
|
||||
[]
|
||||
(centerbox :orientation "h"
|
||||
:halign "start"
|
||||
:width 200
|
||||
(box :halign "start"
|
||||
"route on:")
|
||||
""
|
||||
(box :halign "end"
|
||||
:spacing 0
|
||||
:space-evenly false
|
||||
(label :class "highlight"
|
||||
:text "offline"
|
||||
:visible {!network--data.online})
|
||||
(label :class "highlight"
|
||||
:text "no route"
|
||||
:visible {network--data.online && !network--data.have_default_route})
|
||||
(label :class "special"
|
||||
:text {network--data.default_route}
|
||||
:visible {network--data.online && network--data.have_default_route}))))
|
||||
|
||||
(defwidget network--gateway
|
||||
[]
|
||||
(centerbox :orientation "h"
|
||||
:halign "start"
|
||||
:width 200
|
||||
(box :halign "start"
|
||||
"gateway:")
|
||||
""
|
||||
(box :halign "end"
|
||||
:spacing 0
|
||||
:space-evenly false
|
||||
(label :class "highlight"
|
||||
:text "no response"
|
||||
:visible {!network--data.have_gateway})
|
||||
(label :class "special"
|
||||
:text {network--data.gateway}
|
||||
:visible {network--data.have_gateway}))))
|
||||
|
||||
(defwidget network--status-summary
|
||||
[]
|
||||
(centerbox :orientation "h"
|
||||
:halign "start"
|
||||
:width 200
|
||||
(box :halign "start"
|
||||
"status:")
|
||||
""
|
||||
(box :halign "end"
|
||||
:spacing 0
|
||||
:space-evenly false
|
||||
(label :class "highlight"
|
||||
:text "offline"
|
||||
:visible {!network--data.online})
|
||||
(label :class "special"
|
||||
:text "online"
|
||||
:visible {network--data.online && !network--data.secure})
|
||||
(label :class "green"
|
||||
:text {network--data.secure_msg == "usu" ? "vpn online" : "secure"}
|
||||
:visible {network--data.online && network--data.secure}))))
|
||||
|
||||
|
||||
(defwidget network-detail
|
||||
[]
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(network--status-summary)
|
||||
(network--public-ip)
|
||||
(network--default-route)
|
||||
(network--gateway)
|
||||
(centerbox :orientation "h"
|
||||
:halign "start"
|
||||
:width 200
|
||||
(box :halign "start"
|
||||
"last update:")
|
||||
""
|
||||
(box :halign "end"
|
||||
:spacing 0
|
||||
:space-evenly false
|
||||
(label :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"}
|
||||
:text "${network--data.last_update.month}-${network--data.last_update.day} ${network--data.last_update.hour}:${network--data.last_update.minute}:${network--data.last_update.second}")))
|
||||
))
|
||||
287
.config/eww/modules/network/new_network.py
Executable file
287
.config/eww/modules/network/new_network.py
Executable file
@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import trparse
|
||||
from subprocess import run, PIPE, DEVNULL
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from time import sleep, time as now
|
||||
from ipaddress import (
|
||||
IPv4Address as IPAddress,
|
||||
IPv4Network as IPNetwork,
|
||||
IPv4Interface as IPInterface,
|
||||
AddressValueError,
|
||||
)
|
||||
from netifaces import interfaces, ifaddresses, AF_INET, AF_LINK, gateways
|
||||
import dbus
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
# These are networks that are considered secure. All traffic being routed
|
||||
# through one of these networks is being encrypted and routed through an
|
||||
# anonymizing service.
|
||||
SECURE_FIRSTHOP_NETWORKS = {
|
||||
"home": IPNetwork("10.242.0.0/16"), # Personal network
|
||||
"mullvad": IPNetwork("10.64.0.1/32"), # Mullvad VPN
|
||||
"usu": IPNetwork("129.123.8.126/32"), # USU VPN
|
||||
}
|
||||
|
||||
# Interfaces that we should check
|
||||
DEFAULT_INTERFACES_TO_WATCH = ["lan", "ezrinet"]
|
||||
# Interfaces that we should use when determining if we are online
|
||||
DEFAULT_INTERFACES_TO_COUNT = ["lan"]
|
||||
# Overrides for IP addresses to ping to determine if an interface is
|
||||
# online This is useful for interfaces that don't have or report a
|
||||
# gateway, but we still want to check if they're online, such as the
|
||||
# ezrinet interface.
|
||||
INTERFACE_PING_OVERRIDES = {"ezrinet": IPAddress("10.242.3.1")}
|
||||
|
||||
INTERFACES_TO_WATCH = os.environ.get(
|
||||
"NETWORK_INTERFACES_TO_WATCH", ",".join(DEFAULT_INTERFACES_TO_WATCH)
|
||||
).split(",")
|
||||
INTERFACES_TO_COUNT = os.environ.get(
|
||||
"NETWORK_INTERFACES_TO_COUNT", ",".join(DEFAULT_INTERFACES_TO_COUNT)
|
||||
).split(",")
|
||||
|
||||
for key, value in os.environ.items():
|
||||
if key[: len("NETWORK_PING_OVERRIDE_")] == "NETWORK_PING_OVERRIDE_":
|
||||
INTERFACE_PING_OVERRIDES[key[len("NETWORK_PING_OVERRIDE_") :]] = IPAddress(
|
||||
value
|
||||
)
|
||||
|
||||
|
||||
class Interface:
|
||||
name: str
|
||||
mac: str
|
||||
addresses: list[IPInterface]
|
||||
gateway: IPAddress | None
|
||||
|
||||
@property
|
||||
def online(self):
|
||||
# If we have no addresses, we're not online
|
||||
if len(self.addresses) == 0:
|
||||
return False
|
||||
# If we have an override, ping that
|
||||
if self.name in INTERFACE_PING_OVERRIDES:
|
||||
return ping(INTERFACE_PING_OVERRIDES[self.name])
|
||||
# If we have no gateway, this interface is likely not intended
|
||||
# to route beyond the local network, so we'll assume it's
|
||||
# online, at least for whatever it's used for.
|
||||
if self.gateway is None:
|
||||
return True
|
||||
return ping(self.gateway)
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
"name": self.name,
|
||||
"mac": self.mac,
|
||||
"addresses": [
|
||||
{
|
||||
"address": str(addr.ip),
|
||||
"netmask": str(addr.netmask),
|
||||
"network": str(addr.network),
|
||||
"prefixlen": addr._prefixlen,
|
||||
}
|
||||
for addr in self.addresses
|
||||
],
|
||||
"online": self.online,
|
||||
}
|
||||
|
||||
|
||||
def get_first_hop() -> IPAddress | None:
|
||||
"""Get the first network hop."""
|
||||
# Use ping to get the first hop
|
||||
cmd = ["/usr/bin/ping", "-c1", "-W0.3", "-t1", "1.1.1.1"]
|
||||
result = run(cmd, stdout=PIPE, stderr=PIPE)
|
||||
try:
|
||||
ip = IPAddress(result.stdout.decode("utf-8").split("\n")[1].split()[1])
|
||||
except (IndexError, AddressValueError):
|
||||
# If we can't parse the output, return None
|
||||
return None
|
||||
return ip
|
||||
|
||||
|
||||
def validate_first_hop_is_secure(first_hop: IPAddress):
|
||||
"""Check if the first hop is in a secure network."""
|
||||
for name, network in SECURE_FIRSTHOP_NETWORKS.items():
|
||||
if first_hop in network:
|
||||
return name
|
||||
|
||||
|
||||
def get_gateways():
|
||||
"""Get gateways on each interface."""
|
||||
gw = gateways().get(AF_INET, [])
|
||||
result = {}
|
||||
for iface in INTERFACES_TO_WATCH:
|
||||
for gateway in gw:
|
||||
if gateway[1] == iface:
|
||||
result[iface] = gateway[0]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def interface_status(interface: str, gw):
|
||||
"""Get the status of an interface."""
|
||||
try:
|
||||
addrs = ifaddresses(interface)
|
||||
except:
|
||||
addrs = {}
|
||||
result = Interface()
|
||||
result.name = interface
|
||||
result.gateway = gw.get(interface, None)
|
||||
if AF_LINK in addrs:
|
||||
result.mac = addrs[AF_LINK][0]["addr"]
|
||||
else:
|
||||
result.mac = None
|
||||
if AF_INET in addrs:
|
||||
result.addresses = [
|
||||
IPInterface(f'{addr["addr"]}/{addr["netmask"]}')
|
||||
for addr in addrs.get(AF_INET, [])
|
||||
]
|
||||
else:
|
||||
result.addresses = []
|
||||
return result
|
||||
|
||||
|
||||
def ping(host: IPAddress) -> bool:
|
||||
cmd = ["/usr/bin/ping", "-c1", "-w1", str(host)]
|
||||
result = run(cmd, stdout=DEVNULL, stderr=DEVNULL)
|
||||
return result.returncode == 0
|
||||
|
||||
|
||||
def get_public_ip():
|
||||
"""Get the public IP address."""
|
||||
cmd = ["/usr/bin/curl", "-s", "https://ipinfo.io"]
|
||||
result = run(cmd, stdout=PIPE, stderr=PIPE)
|
||||
try:
|
||||
data = json.loads(result.stdout.decode("utf-8"))
|
||||
except (IndexError, ValueError):
|
||||
return None
|
||||
try:
|
||||
# If the IP address is invalid, don't return anything
|
||||
IPAddress(data["ip"])
|
||||
except (AddressValueError, KeyError):
|
||||
if data.get("status", None) == 429:
|
||||
# We're rate limited, so return something indicating that
|
||||
return {"rate_limited": True}
|
||||
return None
|
||||
return data
|
||||
|
||||
|
||||
def get_default_route():
|
||||
"""Get the default route."""
|
||||
cmd = ["/usr/bin/ip", "route", "show", "default"]
|
||||
result = run(cmd, stdout=PIPE, stderr=PIPE)
|
||||
try:
|
||||
# Get first line (might have multiple gateway routes)
|
||||
line = result.stdout.decode("utf-8").split("\n")[0]
|
||||
# Get the gateway link (following "dev")
|
||||
link = re.search(r"dev\s+(\S+)", line).group(1)
|
||||
# We already know the gateway IP based on our firsthop check earlier, and that's more reliable since it will respect any routing rules
|
||||
except (IndexError, AttributeError):
|
||||
return None
|
||||
return link
|
||||
|
||||
|
||||
def format_time(time: datetime) -> dict[str, str | int]:
|
||||
"""Format a datetime object for display."""
|
||||
return {
|
||||
"hour": f"{time.hour:02}",
|
||||
"minute": f"{time.minute:02}",
|
||||
"second": f"{time.second:02}",
|
||||
"year": f"{time.year:04}",
|
||||
"month": f"{time.month:02}",
|
||||
"day": f"{time.day:02}",
|
||||
"unix": int(time.timestamp()),
|
||||
}
|
||||
|
||||
|
||||
# system_bus = dbus.SystemBus()
|
||||
# networkd = system_bus.get_object(
|
||||
# "org.freedesktop.network1", "/org/freedesktop/network1"
|
||||
# )
|
||||
# manager = dbus.Interface(networkd, "org.freedesktop.network1.Manager")
|
||||
|
||||
|
||||
# def get_dbus_interfaces():
|
||||
# for iface in INTERFACES_TO_WATCH:
|
||||
# dbus_object = system_bus.get_object(
|
||||
# "org.freedesktop.network1", manager.GetLinkByName(iface)
|
||||
# )
|
||||
# dbus_interface = dbus.Interface(dbus_object, "org.freedesktop.network1.Link")
|
||||
# yield dbus_interface
|
||||
|
||||
last_default_route = None
|
||||
last_ip_data = None
|
||||
last_request = None
|
||||
last_first_hop = None
|
||||
|
||||
while True:
|
||||
start = now()
|
||||
try:
|
||||
online = ping("1.1.1.1")
|
||||
except:
|
||||
online = False
|
||||
hop = get_first_hop()
|
||||
gw = get_gateways()
|
||||
default_route = get_default_route()
|
||||
# public IP shouldn't change often, so only check every 30 minutes or
|
||||
# if the default route or first hop changes
|
||||
if (
|
||||
default_route != last_default_route
|
||||
or last_ip_data is None
|
||||
or last_request is None
|
||||
or now() - last_request > 1800
|
||||
or (hop != last_first_hop and hop is not None)
|
||||
):
|
||||
print("refreshing public IP", file=sys.stderr, flush=True)
|
||||
public_ip_data = get_public_ip()
|
||||
if public_ip_data is None:
|
||||
print("failed to get public IP", file=sys.stderr, flush=True)
|
||||
elif public_ip_data.get("rate_limited", False):
|
||||
last_ip_data = public_ip_data
|
||||
public_ip_data = None
|
||||
else:
|
||||
last_ip_data = public_ip_data
|
||||
last_default_route = default_route
|
||||
last_request = now()
|
||||
last_first_hop = hop
|
||||
else:
|
||||
public_ip_data = last_ip_data
|
||||
if hop is not None:
|
||||
secure_msg = validate_first_hop_is_secure(hop)
|
||||
secure = secure_msg is not None
|
||||
else:
|
||||
# If we can't reach the router, assume insecure
|
||||
secure = False
|
||||
iface_data = [interface_status(iface, gw) for iface in INTERFACES_TO_WATCH]
|
||||
iface_dict = {iface.name: iface.asdict() for iface in iface_data}
|
||||
|
||||
default_route_iface_data = interface_status(default_route, gw)
|
||||
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"online": online,
|
||||
"secure": secure,
|
||||
"interfaces": iface_dict,
|
||||
"public_ip": public_ip_data or {},
|
||||
"have_public_ip": public_ip_data is not None and "ip" in public_ip_data,
|
||||
"default_route": default_route,
|
||||
"default_interface": default_route_iface_data.asdict(),
|
||||
"have_default_route": default_route is not None,
|
||||
"gateway": str(hop),
|
||||
"have_gateway": hop is not None,
|
||||
"last_update": format_time(datetime.now()),
|
||||
}
|
||||
),
|
||||
flush=True,
|
||||
)
|
||||
|
||||
end = now()
|
||||
delta = end - start
|
||||
if delta > 5:
|
||||
print("Warning: took longer than 5 seconds to run", file=sys.stderr, flush=True)
|
||||
else:
|
||||
sleep(5 - delta)
|
||||
84
.config/eww/modules/system/system.py
Executable file
84
.config/eww/modules/system/system.py
Executable file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from time import sleep
|
||||
import json
|
||||
import psutil
|
||||
import subprocess
|
||||
import os
|
||||
from dotenv import dotenv_values
|
||||
|
||||
|
||||
def cpu():
|
||||
util = psutil.cpu_percent(percpu=False)
|
||||
per_core = psutil.cpu_percent(percpu=True)
|
||||
return {
|
||||
"avg_display": f"{int(util):2}",
|
||||
"avg": util,
|
||||
"cores": [{"value": core, "display": f"{int(core):2}"} for core in per_core],
|
||||
"cores_display": "".join([f"{int(core):3}" for core in per_core]),
|
||||
"core_count": len(per_core),
|
||||
}
|
||||
|
||||
|
||||
def sensor(chip: str):
|
||||
return {
|
||||
temp.label: temp.current for temp in psutil.sensors_temperatures().get(chip)
|
||||
}
|
||||
|
||||
|
||||
def memory():
|
||||
mem = psutil.virtual_memory()
|
||||
return {
|
||||
"total": mem.total,
|
||||
"available": mem.available,
|
||||
"percent": mem.percent,
|
||||
"used": mem.used,
|
||||
"free": mem.free,
|
||||
"active": mem.active,
|
||||
"inactive": mem.inactive,
|
||||
"buffers": mem.buffers,
|
||||
"cached": mem.cached,
|
||||
"shared": mem.shared,
|
||||
"slab": mem.slab,
|
||||
}
|
||||
|
||||
|
||||
def swap():
|
||||
swap = psutil.swap_memory()
|
||||
return {
|
||||
"total": swap.total,
|
||||
"used": swap.used,
|
||||
"free": swap.free,
|
||||
"percent": swap.percent,
|
||||
}
|
||||
|
||||
|
||||
def reboot():
|
||||
running = os.uname().release
|
||||
version_proc = subprocess.run(["pacman", "-Q", "linux"], capture_output=True)
|
||||
installed = version_proc.stdout.strip().decode("utf-8").split(" ")[1]
|
||||
return running != installed
|
||||
|
||||
|
||||
sensor_list = ["coretemp"]
|
||||
|
||||
counter = 60
|
||||
machine_info = dotenv_values("/etc/machine-info")
|
||||
|
||||
while True:
|
||||
# Refresh machine info every minute, in case it changes
|
||||
if counter == 0:
|
||||
machine_info = dotenv_values("/etc/machine-info")
|
||||
counter = 60
|
||||
|
||||
result = {
|
||||
"cpu": cpu(),
|
||||
"sensors": {chip: sensor(chip) for chip in sensor_list},
|
||||
"memory": memory(),
|
||||
"swap": swap(),
|
||||
"reboot": reboot(),
|
||||
"hostname": machine_info.get("PRETTY_HOSTNAME"),
|
||||
}
|
||||
print(json.dumps(result), flush=True)
|
||||
counter -= 1
|
||||
sleep(1)
|
||||
59
.config/eww/modules/system/system.yuck
Normal file
59
.config/eww/modules/system/system.yuck
Normal file
@ -0,0 +1,59 @@
|
||||
(deflisten system--data :initial "{}"
|
||||
`~/.config/eww/modules/system/system.py`)
|
||||
|
||||
(defwidget system-battery [battery]
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:class "module text"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :class {EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'green' : EWW_BATTERY[battery].capacity <= 25 ? 'highlight' : 'special'}
|
||||
:text "${EWW_BATTERY[battery].capacity}%")
|
||||
(label :text "${EWW_BATTERY[battery].status == 'Charging' || EWW_BATTERY[battery].status == 'Full' ? 'external' : 'internal'} power")))
|
||||
|
||||
(defwidget system-name []
|
||||
(label :halign "center"
|
||||
:valign "center"
|
||||
:class "module text big nebula"
|
||||
:text {system--data.hostname}))
|
||||
|
||||
(defwidget system-cpu-avg []
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:class "module text"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :class {system--data.cpu.avg > 90 ? 'highlight' : 'special'}
|
||||
:text "${system--data.cpu.avg_display}%")
|
||||
(label :text "cpu utilization")))
|
||||
|
||||
(defwidget system--cpu-core [core]
|
||||
(label :class {core.value > 90 ? "highlight" : "special"}
|
||||
:text "${core.display}%"))
|
||||
|
||||
(defwidget system-cpu-percore []
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:class "module text"
|
||||
:space-evenly false
|
||||
;; (box :orientation "h"
|
||||
;; :halign "center"
|
||||
;; :space-evenly false
|
||||
;; (for core in {system--data.cpu.cores}
|
||||
;; (system--cpu-core :core core)))
|
||||
(label :class "special"
|
||||
:text {system--data.cpu.cores_display})
|
||||
(label :text "per-core cpu utilization")
|
||||
))
|
||||
|
||||
(defwidget system-memory []
|
||||
(box :orientation "v"
|
||||
:halign "start"
|
||||
:class "module text"
|
||||
:space-evenly false
|
||||
(label :class {system--data.memory.percent > 85 ? "highlight" : "special"}
|
||||
:text "${round(system--data.memory.used / 1024 / 1024 / 1024, 2)} / ${round(system--data.memory.total / 1024 / 1024 / 1024, 2)} GiB")
|
||||
(label :text "system memory")))
|
||||
|
||||
|
||||
|
||||
56
.config/eww/modules/timer/timer.py
Executable file
56
.config/eww/modules/timer/timer.py
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script prints the time remaining for the current timer
|
||||
# as stored in the file ~/.timer as a binary unix timestamp.
|
||||
|
||||
import time
|
||||
import datetime
|
||||
|
||||
# Get the time stored in the file ~/.timer
|
||||
try:
|
||||
with open("/home/ezri/.timer", "br") as f:
|
||||
timer = f.read()
|
||||
except FileNotFoundError:
|
||||
print("It's Time!", flush=True)
|
||||
exit()
|
||||
|
||||
# Convert the binary unix timestamp to a datetime object
|
||||
timer = datetime.datetime.fromtimestamp(int.from_bytes(timer, "big"))
|
||||
|
||||
while True:
|
||||
# Get the current time
|
||||
now = datetime.datetime.now()
|
||||
|
||||
# Calculate the time remaining
|
||||
remaining = timer - now
|
||||
|
||||
# If the timer has already expired, delete the file and exit
|
||||
if remaining.total_seconds() <= 0:
|
||||
import os
|
||||
|
||||
os.remove("/home/ezri/.timer")
|
||||
print("Timer expired.")
|
||||
|
||||
# Print the time remaining in the format "D days, HH:MM:SS"
|
||||
if remaining.days == 0:
|
||||
print(
|
||||
"{} hours {:02d}:{:02d}".format(
|
||||
remaining.seconds // 3600,
|
||||
remaining.seconds % 3600 // 60,
|
||||
remaining.seconds % 60,
|
||||
),
|
||||
flush=True,
|
||||
)
|
||||
else:
|
||||
print(
|
||||
"{} days, {:02d}:{:02d}:{:02d}".format(
|
||||
remaining.days,
|
||||
remaining.seconds // 3600,
|
||||
remaining.seconds % 3600 // 60,
|
||||
remaining.seconds % 60,
|
||||
),
|
||||
flush=True,
|
||||
)
|
||||
|
||||
# Wait half a second before printing the time again
|
||||
time.sleep(1)
|
||||
11
.config/eww/modules/timer/timer.yuck
Normal file
11
.config/eww/modules/timer/timer.yuck
Normal file
@ -0,0 +1,11 @@
|
||||
(deflisten timer--text :initial 'loading...'
|
||||
`~/.config/eww/modules/timer/timer.py`)
|
||||
|
||||
(defwidget timer []
|
||||
(box :class "module text"
|
||||
:spacing 0
|
||||
:orientation "v"
|
||||
(label :class "special"
|
||||
:text {timer--text})
|
||||
(label :text "baldur's gate 3")))
|
||||
|
||||
50
.config/eww/modules/volume/volume.py
Executable file
50
.config/eww/modules/volume/volume.py
Executable file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import asyncio
|
||||
import signal
|
||||
from contextlib import suppress
|
||||
import pulsectl_asyncio
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
|
||||
async def get_values(pulse):
|
||||
sink = None
|
||||
try:
|
||||
sink = await pulse.get_sink_by_name("@DEFAULT_SINK@")
|
||||
source = await pulse.get_source_by_name("@DEFAULT_SOURCE@")
|
||||
except:
|
||||
# reload the script in the event of an exception
|
||||
os.execv(sys.argv[0], sys.argv)
|
||||
sink_result = {
|
||||
"mute": sink.mute == 1,
|
||||
"volume": f"{int(sink.volume.value_flat * 100):2}"
|
||||
}
|
||||
source_result = {
|
||||
"mute": source.mute == 1,
|
||||
"volume": f"{int(source.volume.value_flat * 100):2}"
|
||||
}
|
||||
result = {
|
||||
"output": sink_result,
|
||||
"input": source_result
|
||||
}
|
||||
print(json.dumps(result), flush=True)
|
||||
return result
|
||||
|
||||
async def listen():
|
||||
async with pulsectl_asyncio.PulseAsync("volume-monitor") as pulse:
|
||||
await get_values(pulse)
|
||||
async for _ in pulse.subscribe_events('all'):
|
||||
await get_values(pulse)
|
||||
|
||||
async def main():
|
||||
listen_task = asyncio.create_task(listen())
|
||||
|
||||
for sig in (signal.SIGTERM, signal.SIGHUP, signal.SIGINT):
|
||||
loop.add_signal_handler(sig, listen_task.cancel)
|
||||
|
||||
with suppress(asyncio.CancelledError):
|
||||
await listen_task
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(main())
|
||||
28
.config/eww/modules/volume/volume.yuck
Normal file
28
.config/eww/modules/volume/volume.yuck
Normal file
@ -0,0 +1,28 @@
|
||||
(deflisten volume--data
|
||||
`~/.config/eww/modules/volume/volume.py`)
|
||||
|
||||
(defwidget volume-h []
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:class "module ${volume--data['mute'] ? 'offline' : ''}"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(label :visible {!volume--data["mute"]} :text "")
|
||||
(label :visible { volume--data["mute"]} :text "")
|
||||
(label :text " ${volume--data['volume']}")))
|
||||
|
||||
(defwidget audio []
|
||||
(box :orientation "v"
|
||||
:halign "center"
|
||||
:class "module text"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
(box :orientation "h"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 15
|
||||
(label :class {volume--data.output.mute ? "offline" : "special"}
|
||||
:text "${volume--data.output.volume}%")
|
||||
(label :class {volume--data.input.mute ? "offline" : "special"}
|
||||
:text "${volume--data.input.volume}%"))
|
||||
"audio system"))
|
||||
17
.config/eww/modules/weather/weather.yuck
Normal file
17
.config/eww/modules/weather/weather.yuck
Normal file
@ -0,0 +1,17 @@
|
||||
;; -*- lisp -*-
|
||||
|
||||
;; This is NOT lisp. It is "yuck", a lisp-like language that is used
|
||||
;; to configure eww. It is a subset of lisp, with some extra features
|
||||
;; that make it more suitable for configuration.
|
||||
|
||||
(defpoll weather--data :interval "30m"
|
||||
`curl wttr.in/84321?format=j1 | jq -c `)
|
||||
|
||||
(defwidget weather
|
||||
[]
|
||||
(box :class "module text"
|
||||
:spacing 0
|
||||
:orientation "v"
|
||||
(label :class "special"
|
||||
:text "${weather--data.current_condition[0].weatherDesc[0].value} ${weather--data.current_condition[0].temp_F}°F")
|
||||
(label :text "current weather")))
|
||||
213
.config/eww/modules/workspaces/hyprland.py
Executable file
213
.config/eww/modules/workspaces/hyprland.py
Executable file
@ -0,0 +1,213 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
WorkspaceTree = dict[str, dict[str, list['Workspace']]]
|
||||
WorkspaceList = dict[str, 'Workspace']
|
||||
|
||||
socketdir = f"/tmp/hypr/{os.environ['HYPRLAND_INSTANCE_SIGNATURE']}"
|
||||
socket1 = f"{socketdir}/.socket.sock"
|
||||
socket2 = f"{socketdir}/.socket2.sock"
|
||||
|
||||
listened_events = ['workspace', 'movewindow', 'createworkspace', 'destroyworkspace']
|
||||
|
||||
class Workspace:
|
||||
|
||||
index: str = None
|
||||
name: str = None
|
||||
exec_cmd: str = None
|
||||
group: str = None
|
||||
|
||||
active: bool = False
|
||||
visible: bool = False
|
||||
focused: bool = False
|
||||
alerted: bool = False
|
||||
|
||||
def __init__(self, dictionary: dict[str, str | int], group: str):
|
||||
self.index = str(dictionary.get('index'))
|
||||
self.name = dictionary.get('name')
|
||||
self.exec_cmd = dictionary.get('exec')
|
||||
self.group = group
|
||||
|
||||
self.active = dictionary.get('active', False)
|
||||
self.visible = dictionary.get('visible', False)
|
||||
self.focused = dictionary.get('focused', False)
|
||||
self.alerted = dictionary.get('alerted', False)
|
||||
|
||||
def update_state(self, state_update, monitor_dict):
|
||||
self.active = True
|
||||
self.visible = monitor_dict[state_update['monitor']]['activeWorkspace']['name'] == state_update['name']
|
||||
self.focused = self.visible and monitor_dict[state_update['monitor']]['focused']
|
||||
self.alerted = False
|
||||
|
||||
def deactivate(self):
|
||||
self.active = False
|
||||
self.visible = False
|
||||
self.focused = False
|
||||
self.alerted = False
|
||||
|
||||
@classmethod
|
||||
def parse_file(cls: type, filename: str) -> tuple[WorkspaceTree, WorkspaceList]:
|
||||
|
||||
result = {}
|
||||
|
||||
initial: dict = None
|
||||
with open(filename, 'r') as file:
|
||||
initial = json.load(file)
|
||||
|
||||
workspaces: WorkspaceList = {}
|
||||
|
||||
def find_workspace(workspace: dict[str, str|int], group: str) -> 'Workspace':
|
||||
index = str(workspace.get('index'))
|
||||
if index in workspaces:
|
||||
return workspaces[index]
|
||||
else:
|
||||
workspaces[index] = cls(workspace, group)
|
||||
return workspaces[index]
|
||||
|
||||
result = {
|
||||
context: {
|
||||
group: [
|
||||
find_workspace(workspace, group) for workspace in workspaces
|
||||
] for group, workspaces in groups.items()
|
||||
} for context, groups in initial.items()
|
||||
}
|
||||
|
||||
return result, workspaces
|
||||
|
||||
@staticmethod
|
||||
def full_dictify(tree: WorkspaceTree):
|
||||
return {
|
||||
context: {
|
||||
group: [
|
||||
workspace.dictify() for workspace in workspaces
|
||||
] for group, workspaces in groups.items()
|
||||
} for context, groups in tree.items()
|
||||
}
|
||||
|
||||
def dictify(self):
|
||||
|
||||
return {
|
||||
'index': self.index,
|
||||
'name': self.name,
|
||||
'exec': self.exec_cmd,
|
||||
'active': self.active,
|
||||
'visible': self.visible,
|
||||
'focused': self.focused,
|
||||
'alerted': self.alerted
|
||||
}
|
||||
|
||||
workspace_tree, workspace_list = Workspace.parse_file(f"{os.environ['HOME']}/.config/hypr/workspaces.json")
|
||||
|
||||
data = {
|
||||
"ws": {},
|
||||
"current": {},
|
||||
"context": "personal",
|
||||
"visible": {},
|
||||
}
|
||||
|
||||
def write_data():
|
||||
global data
|
||||
print(json.dumps(data), flush=True)
|
||||
|
||||
async def get_workspace_data():
|
||||
request = b"[[BATCH]] j/workspaces; j/monitors"
|
||||
reader = None
|
||||
writer = None
|
||||
data = None
|
||||
try:
|
||||
reader, writer = await asyncio.open_unix_connection(socket1)
|
||||
writer.write(request)
|
||||
await writer.drain()
|
||||
data = await reader.read()
|
||||
finally:
|
||||
if writer is not None:
|
||||
writer.close()
|
||||
if data is None:
|
||||
return;
|
||||
|
||||
workspace_data = None
|
||||
monitor_data = None
|
||||
try:
|
||||
workspace_data, monitor_data = data.decode().split("}][{")
|
||||
workspace_data += "}]"
|
||||
monitor_data = "[{" + monitor_data
|
||||
except ValueError:
|
||||
print("Error unpacking response", file=sys.stderr)
|
||||
return
|
||||
|
||||
return [json.loads(workspace_data), json.loads(monitor_data)]
|
||||
|
||||
async def update_workspaces():
|
||||
global workspace_tree, workspace_list, data
|
||||
|
||||
workspaces, monitors = await get_workspace_data()
|
||||
|
||||
ws_hypr_dict = { ws["name"]: ws for ws in workspaces }
|
||||
monitor_dict = { monitor["name"]: monitor for monitor in monitors }
|
||||
|
||||
touched = []
|
||||
|
||||
for index, ws_data in ws_hypr_dict.items():
|
||||
|
||||
# Update data for all active workspaces
|
||||
ws_state = workspace_list.get(index)
|
||||
if ws_state is None:
|
||||
# If the workspace isn't configured, note it and handle gracefully
|
||||
print(f"Warning: found unconfigured workspace {index}", file=sys.stderr, flush=True)
|
||||
if monitor_dict[ws_data['monitor']]['activeWorkspace']['name'] == ws_data['name']:
|
||||
data['current'] = {
|
||||
'index': index,
|
||||
'name': 'undefined',
|
||||
'exec': 'alacritty',
|
||||
'active': True,
|
||||
'visible': True,
|
||||
'focused': True,
|
||||
'alerted': False
|
||||
}
|
||||
else:
|
||||
# Otherwise, 'touch' it and update status data
|
||||
touched.append(index)
|
||||
ws_state.update_state(ws_data, monitor_dict)
|
||||
if ws_state.focused:
|
||||
data['current'] = ws_state.dictify()
|
||||
if ws_state.visible:
|
||||
data['visible'][ws_state.group] = ws_state.dictify()
|
||||
|
||||
inactives = [
|
||||
v for k, v in workspace_list.items() if v.active and k not in touched
|
||||
]
|
||||
|
||||
for workspace in inactives:
|
||||
workspace.deactivate()
|
||||
|
||||
# Create an 'unknown' workspace object for each group that doesn't yet have a listed visible workspace
|
||||
for group in workspace_tree[data['context'] or 'personal'].keys():
|
||||
if group not in data['visible']:
|
||||
data['visible'][group] = {
|
||||
'index': 'U',
|
||||
'name': 'undefined',
|
||||
'exec': 'alacritty',
|
||||
'active': True,
|
||||
'visible': True,
|
||||
'focused': False,
|
||||
'alerted': False
|
||||
}
|
||||
data['ws'] = Workspace.full_dictify(workspace_tree)
|
||||
write_data()
|
||||
|
||||
async def main():
|
||||
reader, writer = await asyncio.open_unix_connection(socket2)
|
||||
|
||||
await update_workspaces()
|
||||
|
||||
while True:
|
||||
event = (await reader.readline()).decode()
|
||||
eventType, eventData = event.split(">>")
|
||||
if eventType in listened_events:
|
||||
await update_workspaces()
|
||||
|
||||
asyncio.run(main())
|
||||
184
.config/eww/modules/workspaces/sway.py
Executable file
184
.config/eww/modules/workspaces/sway.py
Executable file
@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from i3ipc.aio import Connection
|
||||
from i3ipc import Event
|
||||
from typing import List, Dict, Any, Union, Tuple
|
||||
|
||||
WorkspaceTree = Dict[str, Dict[str, List['Workspace']]]
|
||||
WorkspaceList = Dict[str, 'Workspace']
|
||||
|
||||
class Workspace:
|
||||
|
||||
index: str = None
|
||||
name: str = None
|
||||
exec_cmd: str = None
|
||||
group: str = None
|
||||
|
||||
active: bool = False
|
||||
visible: bool = False
|
||||
focused: bool = False
|
||||
alerted: bool = False
|
||||
|
||||
def __init__(self, dictionary: Dict[str, Union[str, int]], group: str):
|
||||
self.index = str(dictionary.get('index'))
|
||||
self.name = dictionary.get('name')
|
||||
self.exec_cmd = dictionary.get('exec')
|
||||
self.group = group
|
||||
|
||||
self.active = dictionary.get('active', False)
|
||||
self.visible = dictionary.get('visible', False)
|
||||
self.focused = dictionary.get('focused', False)
|
||||
self.alerted = dictionary.get('alerted', False)
|
||||
|
||||
def update_state(self, state_update: Any):
|
||||
self.active = True
|
||||
self.visible = state_update.visible
|
||||
self.focused = state_update.focused
|
||||
self.alerted = state_update.urgent
|
||||
|
||||
def deactivate(self):
|
||||
self.active = False
|
||||
self.visible = False
|
||||
self.focused = False
|
||||
self.alerted = False
|
||||
|
||||
@classmethod
|
||||
def parse_file(cls: type, filename: str) -> Tuple[WorkspaceTree, WorkspaceList]:
|
||||
|
||||
result = {}
|
||||
|
||||
initial: dict = None
|
||||
with open(filename, 'r') as file:
|
||||
initial = json.load(file)
|
||||
|
||||
workspaces: WorkspaceList = {}
|
||||
|
||||
def find_workspace(workspace: Dict[str, Union[str, int]], group: str) -> 'Workspace':
|
||||
index = str(workspace.get('index'))
|
||||
if index in workspaces:
|
||||
return workspaces[index]
|
||||
else:
|
||||
workspaces[index] = cls(workspace, group)
|
||||
return workspaces[index]
|
||||
|
||||
result = {
|
||||
context: {
|
||||
group: [
|
||||
find_workspace(workspace, group) for workspace in workspaces
|
||||
] for group, workspaces in groups.items()
|
||||
} for context, groups in initial.items()
|
||||
}
|
||||
|
||||
return result, workspaces
|
||||
|
||||
@staticmethod
|
||||
def full_dictify(tree: WorkspaceTree):
|
||||
return {
|
||||
context: {
|
||||
group: [
|
||||
workspace.dictify() for workspace in workspaces
|
||||
] for group, workspaces in groups.items()
|
||||
} for context, groups in tree.items()
|
||||
}
|
||||
|
||||
def dictify(self):
|
||||
|
||||
return {
|
||||
'index': self.index,
|
||||
'name': self.name,
|
||||
'exec': self.exec_cmd,
|
||||
'active': self.active,
|
||||
'visible': self.visible,
|
||||
'focused': self.focused,
|
||||
'alerted': self.alerted
|
||||
}
|
||||
|
||||
workspace_tree, workspace_list = Workspace.parse_file(f"{os.environ['HOME']}/.config/sway/workspaces.json")
|
||||
|
||||
data = {
|
||||
"ws": {},
|
||||
"mode": "default",
|
||||
"current": {},
|
||||
"context": "work",
|
||||
"visible": {},
|
||||
}
|
||||
|
||||
def write_data():
|
||||
global data
|
||||
print(json.dumps(data), flush=True)
|
||||
|
||||
async def workspace_event(self: Connection, _):
|
||||
global workspace_tree, workspace_list, data
|
||||
|
||||
ws_sway_dict = { ws.name: ws for ws in await self.get_workspaces()}
|
||||
|
||||
touched = []
|
||||
|
||||
for index, ws_data in ws_sway_dict.items():
|
||||
|
||||
# Update data for all active workspaces
|
||||
ws_state = workspace_list.get(index)
|
||||
if ws_state is None:
|
||||
# If the workspace isn't configured, note it and handle gracefully
|
||||
print(f"Warning: found unconfigured workspace {index}", file=sys.stderr, flush=True)
|
||||
if ws_data.focused:
|
||||
data['current'] = {
|
||||
'index': index,
|
||||
'name': 'undefined',
|
||||
'exec': 'alacritty',
|
||||
'active': True,
|
||||
'visible': True,
|
||||
'focused': True,
|
||||
'alerted': False
|
||||
}
|
||||
else:
|
||||
# Otherwise, 'touch' it and update the status data
|
||||
touched.append(index)
|
||||
ws_state.update_state(ws_data)
|
||||
if ws_state.focused:
|
||||
data['current'] = ws_state.dictify()
|
||||
if ws_state.visible:
|
||||
data['visible'][ws_state.group] = ws_state.dictify()
|
||||
|
||||
# 'Deactivate' any untouched workspaces
|
||||
inactives = [
|
||||
v for k, v in workspace_list.items() if v.active and k not in touched
|
||||
]
|
||||
|
||||
for workspace in inactives:
|
||||
workspace.deactivate()
|
||||
|
||||
# Create an 'unknown' workspace object for each group that doesn't yet have a listed visible workspace
|
||||
for group in workspace_tree[data['context'] or 'personal'].keys():
|
||||
if group not in data['visible']:
|
||||
data['visible'][group] = {
|
||||
'index': 'U',
|
||||
'name': 'undefined',
|
||||
'exec': 'alacritty',
|
||||
'active': True,
|
||||
'visible': True,
|
||||
'focused': False,
|
||||
'alerted': False
|
||||
}
|
||||
|
||||
data['ws'] = Workspace.full_dictify(workspace_tree)
|
||||
write_data()
|
||||
|
||||
async def mode_event(self: Connection, event):
|
||||
global data
|
||||
data['mode'] = event.change
|
||||
write_data()
|
||||
|
||||
async def main():
|
||||
sway = await Connection(auto_reconnect = True).connect()
|
||||
|
||||
sway.on(Event.WORKSPACE, workspace_event)
|
||||
sway.on(Event.MODE, mode_event)
|
||||
await workspace_event(sway, None)
|
||||
await sway.main()
|
||||
|
||||
asyncio.run(main())
|
||||
77
.config/eww/modules/workspaces/workspaces.yuck
Normal file
77
.config/eww/modules/workspaces/workspaces.yuck
Normal file
@ -0,0 +1,77 @@
|
||||
(deflisten sway--data :initial '{"mode": "default"}'
|
||||
`~/.config/eww/modules/workspaces/sway.py`)
|
||||
|
||||
(defvar hypr--data '{}')
|
||||
|
||||
(defwidget sway--workspace [ws]
|
||||
(button :onclick "swaymsg workspace ${ws['index']}"
|
||||
(circular-progress
|
||||
:class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused" : ""} ${ws.alerted ? "sway--alerted" : ""}'
|
||||
:value 100
|
||||
:start-at 0
|
||||
:clockwise true
|
||||
:width 16
|
||||
:thickness 1
|
||||
(box :class 'fill' ))))
|
||||
|
||||
(defwidget hypr--workspace [ws]
|
||||
(button :onclick "hyprmsg dispatch workspace ${ws['index']}"
|
||||
(circular-progress
|
||||
:class 'indicator-circle sway--ws ${ws.active ? "sway--active" : ""} ${ws.visible ? "sway--visible" : ""} ${ws.focused ? "sway--focused": ""}'
|
||||
:value 100
|
||||
:start-at 0
|
||||
:clockwise true
|
||||
:width 15
|
||||
:thickness 1
|
||||
(box :class 'fill' :visible {ws.focused}))))
|
||||
|
||||
(defwidget sway-mode []
|
||||
(box :orientation "v"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class "module text"
|
||||
:visible {sway--data != '' && sway--data.mode != "default"}
|
||||
(label :class "special"
|
||||
:text "${hypr--data.mode}")
|
||||
"sway mode"))
|
||||
|
||||
(defwidget sway-workspace [group]
|
||||
(box :orientation "v"
|
||||
:halign "center"
|
||||
:valign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class 'module text'
|
||||
(label :class '${sway--data.visible[group].focused ? "special" : "offline"} nebula medium small'
|
||||
:text '${sway--data.visible[group].name}')))
|
||||
; (label :text "current workspace")))
|
||||
|
||||
(defwidget hypr-workspace [group]
|
||||
(box :orientation "v"
|
||||
:halign "center"
|
||||
:space-evenly false
|
||||
:spacing 0
|
||||
:class 'module text'
|
||||
(label :class '${hypr--data.visible[group].focused ? "special" : "offline"}'
|
||||
:text '${hypr--data.visible[group].name}')
|
||||
(label :text "current workspace")))
|
||||
|
||||
(defwidget sway-workspaces [group]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:visible {sway--data != ''}
|
||||
:space-evenly false
|
||||
:spacing 5
|
||||
:class "sway--root"
|
||||
(for workspace in {sway--data.ws[sway--data.context ?: "personal"][group]}
|
||||
(sway--workspace :ws workspace))))
|
||||
|
||||
(defwidget hypr-workspaces [group]
|
||||
(box :orientation "h"
|
||||
:halign "start"
|
||||
:space-evenly false
|
||||
:spacing 5
|
||||
:class "sway--root"
|
||||
(for workspace in {hypr--data.ws[hypr--data.context ?: "personal"][group]}
|
||||
(hypr--workspace :ws workspace))))
|
||||
63
.config/htop/htoprc
Normal file
63
.config/htop/htoprc
Normal file
@ -0,0 +1,63 @@
|
||||
# Beware! This file is rewritten by htop when settings are changed in the interface.
|
||||
# The parser is also very primitive, and not human-friendly.
|
||||
htop_version=3.3.0
|
||||
config_reader_min_version=3
|
||||
fields=0 48 17 18 38 39 40 2 46 47 49 1
|
||||
hide_kernel_threads=1
|
||||
hide_userland_threads=1
|
||||
hide_running_in_container=0
|
||||
shadow_other_users=0
|
||||
show_thread_names=0
|
||||
show_program_path=1
|
||||
highlight_base_name=0
|
||||
highlight_deleted_exe=1
|
||||
shadow_distribution_path_prefix=0
|
||||
highlight_megabytes=1
|
||||
highlight_threads=1
|
||||
highlight_changes=0
|
||||
highlight_changes_delay_secs=5
|
||||
find_comm_in_cmdline=1
|
||||
strip_exe_from_cmdline=1
|
||||
show_merged_command=0
|
||||
header_margin=1
|
||||
screen_tabs=1
|
||||
detailed_cpu_time=0
|
||||
cpu_count_from_one=0
|
||||
show_cpu_usage=1
|
||||
show_cpu_frequency=0
|
||||
show_cpu_temperature=1
|
||||
degree_fahrenheit=0
|
||||
update_process_names=0
|
||||
account_guest_in_cpu_meter=0
|
||||
color_scheme=0
|
||||
enable_mouse=1
|
||||
delay=15
|
||||
hide_function_bar=0
|
||||
header_layout=two_33_67
|
||||
column_meters_0=Hostname Blank Tasks LoadAverage Uptime Clock
|
||||
column_meter_modes_0=2 2 2 2 2 2
|
||||
column_meters_1=AllCPUs2 Blank MemorySwap
|
||||
column_meter_modes_1=1 2 1
|
||||
tree_view=0
|
||||
sort_key=46
|
||||
tree_sort_key=46
|
||||
sort_direction=-1
|
||||
tree_sort_direction=-1
|
||||
tree_view_always_by_pid=0
|
||||
all_branches_collapsed=0
|
||||
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
|
||||
.sort_key=PERCENT_CPU
|
||||
.tree_sort_key=PERCENT_CPU
|
||||
.tree_view_always_by_pid=0
|
||||
.tree_view=0
|
||||
.sort_direction=-1
|
||||
.tree_sort_direction=-1
|
||||
.all_branches_collapsed=0
|
||||
screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command
|
||||
.sort_key=IO_RATE
|
||||
.tree_sort_key=PID
|
||||
.tree_view_always_by_pid=0
|
||||
.tree_view=0
|
||||
.sort_direction=-1
|
||||
.tree_sort_direction=1
|
||||
.all_branches_collapsed=0
|
||||
19
.config/sway/config
Normal file
19
.config/sway/config
Normal file
@ -0,0 +1,19 @@
|
||||
### ###
|
||||
# Tycho Station Sway Config #
|
||||
### ###
|
||||
|
||||
# This config file is modular. Set variables here, then use them in
|
||||
# drop-in config files located in ~/.config/sway/config.d/
|
||||
|
||||
set $mod Mod4
|
||||
set $alt Mod1
|
||||
|
||||
set $colors.primary '#815986'
|
||||
set $colors.background '#2d272f'
|
||||
|
||||
### ###
|
||||
# HERE BE DRAGONS #
|
||||
### ###
|
||||
|
||||
# Do not edit anything below these comments. You have been warned.
|
||||
include ~/.config/sway/config.d/*.conf
|
||||
9
.config/sway/config.d/00-meta.conf
Normal file
9
.config/sway/config.d/00-meta.conf
Normal file
@ -0,0 +1,9 @@
|
||||
### ###
|
||||
# Controls for Sway #
|
||||
### ###
|
||||
|
||||
# This file includes "meta" controls, that is, keybinds
|
||||
# for sway itself.
|
||||
|
||||
bindsym $mod+Shift+r reload
|
||||
bindsym $mod+Shift+e exit
|
||||
88
.config/sway/config.d/10-display-settings.conf
Normal file
88
.config/sway/config.d/10-display-settings.conf
Normal file
@ -0,0 +1,88 @@
|
||||
### ###
|
||||
# Display Settings #
|
||||
### ###
|
||||
|
||||
set $leftdisplay 'Hewlett Packard HP Z24n CN47090537'
|
||||
set $centerdisplay 'Hewlett Packard HP Z24n CN4709053L'
|
||||
|
||||
output {
|
||||
$leftdisplay pos 0 0 mode 1920x1200
|
||||
$centerdisplay pos 1920 0 mode 1920x1200
|
||||
# * bg '/home/ezri/2023-09-28T14:06:22,599070355-06:00.png' center '#1e1e1e'
|
||||
* bg '#1e1e1e' solid_color
|
||||
}
|
||||
|
||||
mode "output-switching" {
|
||||
bindsym 1 mode output-1
|
||||
bindsym 2 mode output-2
|
||||
# bindsym 3 mode output-3
|
||||
}
|
||||
|
||||
mode "output-1" {
|
||||
|
||||
## Focus output
|
||||
bindsym Return exec swaymsg focus output $leftdisplay && swaymsg mode default
|
||||
|
||||
## Focus workspace on another output
|
||||
bindsym 1 exec swaymsg workspace 1 && swaymsg mode default
|
||||
bindsym 2 exec swaymsg workspace 2 && swaymsg mode default
|
||||
bindsym 3 exec swaymsg workspace 3 && swaymsg mode default
|
||||
bindsym 4 exec swaymsg workspace 4 && swaymsg mode default
|
||||
bindsym 5 exec swaymsg workspace 5 && swaymsg mode default
|
||||
bindsym 6 exec swaymsg workspace 6 && swaymsg mode default
|
||||
bindsym 7 exec swaymsg workspace 7 && swaymsg mode default
|
||||
bindsym 8 exec swaymsg workspace 8 && swaymsg mode default
|
||||
bindsym 9 exec swaymsg workspace 9 && swaymsg mode default
|
||||
bindsym 0 exec swaymsg workspace 10 && swaymsg mode default
|
||||
|
||||
## Move container to focused workspace on other output
|
||||
bindsym Shift+Return exec swaymsg move container to output $leftdisplay && swaymsg mode default
|
||||
|
||||
## Move container to workspace on another output
|
||||
bindsym Shift+1 exec swaymsg move container to workspace 1 && swaymsg mode default
|
||||
bindsym Shift+2 exec swaymsg move container to workspace 2 && swaymsg mode default
|
||||
bindsym Shift+3 exec swaymsg move container to workspace 3 && swaymsg mode default
|
||||
bindsym Shift+4 exec swaymsg move container to workspace 4 && swaymsg mode default
|
||||
bindsym Shift+5 exec swaymsg move container to workspace 5 && swaymsg mode default
|
||||
bindsym Shift+6 exec swaymsg move container to workspace 6 && swaymsg mode default
|
||||
bindsym Shift+7 exec swaymsg move container to workspace 7 && swaymsg mode default
|
||||
bindsym Shift+8 exec swaymsg move container to workspace 8 && swaymsg mode default
|
||||
bindsym Shift+9 exec swaymsg move container to workspace 9 && swaymsg mode default
|
||||
bindsym Shift+0 exec swaymsg move container to workspace 10 && swaymsg mode default
|
||||
}
|
||||
|
||||
mode "output-2" {
|
||||
|
||||
## Focus output
|
||||
bindsym Return exec swaymsg focus output $centerdisplay && swaymsg mode default
|
||||
|
||||
## Focus workspace on another output
|
||||
bindsym 1 exec swaymsg workspace 11 && swaymsg mode default
|
||||
bindsym 2 exec swaymsg workspace 12 && swaymsg mode default
|
||||
bindsym 3 exec swaymsg workspace 13 && swaymsg mode default
|
||||
bindsym 4 exec swaymsg workspace 14 && swaymsg mode default
|
||||
bindsym 5 exec swaymsg workspace 15 && swaymsg mode default
|
||||
bindsym 6 exec swaymsg workspace 16 && swaymsg mode default
|
||||
bindsym 7 exec swaymsg workspace 17 && swaymsg mode default
|
||||
bindsym 8 exec swaymsg workspace 18 && swaymsg mode default
|
||||
bindsym 9 exec swaymsg workspace 19 && swaymsg mode default
|
||||
bindsym 0 exec swaymsg workspace 20 && swaymsg mode default
|
||||
|
||||
## Move container to focused workspace on other output
|
||||
bindsym Shift+Return exec swaymsg move container to output $centerdisplay && swaymsg mode default
|
||||
|
||||
## Move container to workspace on another output
|
||||
bindsym Shift+1 exec swaymsg move container to workspace 11 && swaymsg mode default
|
||||
bindsym Shift+2 exec swaymsg move container to workspace 12 && swaymsg mode default
|
||||
bindsym Shift+3 exec swaymsg move container to workspace 13 && swaymsg mode default
|
||||
bindsym Shift+4 exec swaymsg move container to workspace 14 && swaymsg mode default
|
||||
bindsym Shift+5 exec swaymsg move container to workspace 15 && swaymsg mode default
|
||||
bindsym Shift+6 exec swaymsg move container to workspace 16 && swaymsg mode default
|
||||
bindsym Shift+7 exec swaymsg move container to workspace 17 && swaymsg mode default
|
||||
bindsym Shift+8 exec swaymsg move container to workspace 18 && swaymsg mode default
|
||||
bindsym Shift+9 exec swaymsg move container to workspace 19 && swaymsg mode default
|
||||
bindsym Shift+0 exec swaymsg move container to workspace 10 && swaymsg mode default
|
||||
}
|
||||
|
||||
bindsym $mod+O mode output-switching
|
||||
|
||||
66
.config/sway/config.d/11-workspaces.conf
Normal file
66
.config/sway/config.d/11-workspaces.conf
Normal file
@ -0,0 +1,66 @@
|
||||
### ###
|
||||
# Workspaces #
|
||||
### ###
|
||||
|
||||
# This section defines the workspaces and creates keybinds to switch
|
||||
# between them. It relies on an `i3-sensible-workspaces' command
|
||||
# which prints the name of the workspace to target when given a
|
||||
# workspace index
|
||||
|
||||
## Define Workspaces
|
||||
|
||||
workspace {
|
||||
# Left monitor workspaces
|
||||
1 output $leftdisplay
|
||||
2 output $leftdisplay
|
||||
3 output $leftdisplay
|
||||
4 output $leftdisplay
|
||||
5 output $leftdisplay
|
||||
6 output $leftdisplay
|
||||
7 output $leftdisplay
|
||||
8 output $leftdisplay
|
||||
9 output $leftdisplay
|
||||
10 output $leftdisplay
|
||||
|
||||
# Right monitor workspaces
|
||||
11 output $centerdisplay
|
||||
12 output $centerdisplay
|
||||
13 output $centerdisplay
|
||||
14 output $centerdisplay
|
||||
15 output $centerdisplay
|
||||
16 output $centerdisplay
|
||||
17 output $centerdisplay
|
||||
18 output $centerdisplay
|
||||
19 output $centerdisplay
|
||||
20 output $centerdisplay
|
||||
}
|
||||
|
||||
## Workspace Switching Keybinds
|
||||
|
||||
bindsym {
|
||||
$mod+1 exec swaymsg workspace $(i3-sensible-workspaces 1 )
|
||||
$mod+2 exec swaymsg workspace $(i3-sensible-workspaces 2 )
|
||||
$mod+3 exec swaymsg workspace $(i3-sensible-workspaces 3 )
|
||||
$mod+4 exec swaymsg workspace $(i3-sensible-workspaces 4 )
|
||||
$mod+5 exec swaymsg workspace $(i3-sensible-workspaces 5 )
|
||||
$mod+6 exec swaymsg workspace $(i3-sensible-workspaces 6 )
|
||||
$mod+7 exec swaymsg workspace $(i3-sensible-workspaces 7 )
|
||||
$mod+8 exec swaymsg workspace $(i3-sensible-workspaces 8 )
|
||||
$mod+9 exec swaymsg workspace $(i3-sensible-workspaces 9 )
|
||||
$mod+0 exec swaymsg workspace $(i3-sensible-workspaces 10)
|
||||
}
|
||||
|
||||
## Window Reassignment Keybinds
|
||||
|
||||
bindsym {
|
||||
$mod+Shift+1 exec swaymsg move container to workspace $(i3-sensible-workspaces 1 )
|
||||
$mod+Shift+2 exec swaymsg move container to workspace $(i3-sensible-workspaces 2 )
|
||||
$mod+Shift+3 exec swaymsg move container to workspace $(i3-sensible-workspaces 3 )
|
||||
$mod+Shift+4 exec swaymsg move container to workspace $(i3-sensible-workspaces 4 )
|
||||
$mod+Shift+5 exec swaymsg move container to workspace $(i3-sensible-workspaces 5 )
|
||||
$mod+Shift+6 exec swaymsg move container to workspace $(i3-sensible-workspaces 6 )
|
||||
$mod+Shift+7 exec swaymsg move container to workspace $(i3-sensible-workspaces 7 )
|
||||
$mod+Shift+8 exec swaymsg move container to workspace $(i3-sensible-workspaces 8 )
|
||||
$mod+Shift+9 exec swaymsg move container to workspace $(i3-sensible-workspaces 9 )
|
||||
$mod+Shift+0 exec swaymsg move container to workspace $(i3-sensible-workspaces 10)
|
||||
}
|
||||
71
.config/sway/config.d/12-windows.conf
Normal file
71
.config/sway/config.d/12-windows.conf
Normal file
@ -0,0 +1,71 @@
|
||||
### ###
|
||||
# Window Management #
|
||||
### ###
|
||||
|
||||
# This file contains settings and keybinds related to window
|
||||
# management
|
||||
|
||||
## Allow dragging of floating windows whilst holding $mod
|
||||
floating_modifier $mod
|
||||
|
||||
## Define a window resizing mode
|
||||
mode "resize" {
|
||||
bindsym {
|
||||
Left resize shrink width 10 px or 1 ppt
|
||||
Right resize grow width 10 px or 1 ppt
|
||||
Up resize shrink height 10 px or 1 ppt
|
||||
Down resize grow height 10 px or 1 ppt
|
||||
|
||||
Return mode "default"
|
||||
Escape mode "default"
|
||||
$mod+r mode "default"
|
||||
}
|
||||
}
|
||||
bindsym $mod+r mode "resize"
|
||||
|
||||
## Moving windows
|
||||
bindsym {
|
||||
$mod+Shift+b move left
|
||||
$mod+Shift+f move right
|
||||
$mod+Shift+p move up
|
||||
$mod+Shift+n move down
|
||||
|
||||
$mod+Shift+Left move left
|
||||
$mod+Shift+Right move right
|
||||
$mod+Shift+Up move up
|
||||
$mod+Shift+Down move down
|
||||
}
|
||||
|
||||
## Shifting focus
|
||||
bindsym {
|
||||
$mod+b focus left
|
||||
$mod+f focus right
|
||||
$mod+p focus up
|
||||
$mod+n focus down
|
||||
|
||||
$mod+Left focus left
|
||||
$mod+Right focus right
|
||||
$mod+Up focus up
|
||||
$mod+Down focus down
|
||||
|
||||
$mod+a focus parent
|
||||
$mod+space focus mode_toggle
|
||||
}
|
||||
|
||||
## Creating and rearranging containers
|
||||
bindsym {
|
||||
# Create new split-view containers
|
||||
$mod+h split h
|
||||
$mod+v split v
|
||||
|
||||
# Rearrange focused container
|
||||
$mod+e layout toggle split
|
||||
$mod+t layout tabbed
|
||||
$mod+s layout stacking
|
||||
|
||||
# Toggle floating of focused container
|
||||
$mod+Shift+space floating toggle
|
||||
}
|
||||
|
||||
## Close focused window
|
||||
bindsym $mod+Shift+q kill
|
||||
36
.config/sway/config.d/20-style.conf
Normal file
36
.config/sway/config.d/20-style.conf
Normal file
@ -0,0 +1,36 @@
|
||||
### ###
|
||||
# Style configuration #
|
||||
### ###
|
||||
|
||||
## Window-manager Font
|
||||
font pango:JetBrainsMono Nerd Font 8
|
||||
|
||||
## One-pixel borders around windows
|
||||
default_border pixel 1
|
||||
|
||||
set $colorprimary '#815986'
|
||||
set $colorbackground '#2d272f'
|
||||
set $colorwallpaper '#1e1e1e'
|
||||
|
||||
## Colors (define these in the main config file
|
||||
client.focused $colorprimary $colorbackground $colorprimary $colorprimary $colorprimary
|
||||
client.focused_inactive $colorbackground $colorbackground $colorprimary $colorbackground $colorbackground
|
||||
client.unfocused $colorwallpaper $colorwallpaper $colorprimary $colorbackground $colorbackground
|
||||
|
||||
## Window gaps
|
||||
gaps inner 10
|
||||
|
||||
## GTK theme
|
||||
exec_always gsettings set org.gnome.desktop.interface {
|
||||
gtk-theme 'Nordic-darker'
|
||||
icon-theme 'ePapirus-dark'
|
||||
font-name 'Source Sans Pro:12'
|
||||
text-scaling-factor 1
|
||||
}
|
||||
|
||||
for_window [app_id="Alacritty"] {
|
||||
border normal 1
|
||||
client.focused $colorprimary $colorbackground $colorprimary $colorprimary $colorprimary
|
||||
client.focused_inactive $colorbackground $colorbackground $colorprimary $colorbackground $colorbackground
|
||||
client.unfocusd $colorbackground $colorwallpaper $colorprimary $colorbackground $colorbackground
|
||||
}
|
||||
51
.config/sway/config.d/30-qol.conf
Normal file
51
.config/sway/config.d/30-qol.conf
Normal file
@ -0,0 +1,51 @@
|
||||
### ###
|
||||
# Desktop QoL Features #
|
||||
### ###
|
||||
|
||||
# This file includes common desktop features such as application
|
||||
# launching keybinds, alongside quality-of-life things such as media
|
||||
# controls.
|
||||
|
||||
## Application 'sensible' launcher.
|
||||
# Relies on an `i3-sensible-launcher' script, intended to launch
|
||||
# specific programs based on environment data, such as the current
|
||||
# workspace.
|
||||
bindsym $mod+Return exec i3-sensible-launcher
|
||||
|
||||
## Terminal launch override
|
||||
# Quick keybind to launch a terminal on any workspace, ignoring the
|
||||
# normal default.
|
||||
bindsym $mod+Shift+Return exec alacritty msg create-window || alacritty
|
||||
|
||||
## Program menu
|
||||
bindsym $mod+d exec wofi --show drun
|
||||
|
||||
## Media controls
|
||||
# Relies on the `playerctl' command, will not function without it.
|
||||
# Security note: these keybinds will function while screen is locked
|
||||
bindsym --locked {
|
||||
XF86AudioPlay exec playerctl play-pause
|
||||
XF86AudioNext exec playerctl next
|
||||
XF86AudioPrev exec playerctl previous
|
||||
|
||||
Ctrl+F7 exec playerctl previous
|
||||
Ctrl+F8 exec playerctl play-pause
|
||||
Ctrl+F9 exec playerctl next
|
||||
}
|
||||
|
||||
## Screen locking
|
||||
# This depends on a running screen-locking agent (ideally `swayidle')
|
||||
bindsym $mod+l exec loginctl lock-session
|
||||
|
||||
## Notification management
|
||||
# This depends on the `dunst' notification daemon
|
||||
bindsym $mod+Ctrl+Space exec swaync-client --hide-latest
|
||||
bindsym Ctrl+Shift+Space exec swaync-client -t
|
||||
|
||||
## Screenshotting
|
||||
bindsym {
|
||||
Shift+Print exec grimshot copy window && notify-send -a 'Screenshot' -u low 'Screenshot taken' 'An image of the focused window has been copied to clipboard'
|
||||
Ctrl+Print exec grimshot copy area && notify-send -a 'Screenshot' -u low 'Screenshot taken' 'An image of the selected area has been copied to clipboard'
|
||||
Print exec grimshot copy screen && notify-send -a 'Screenshot' -u low 'Screenshot taken' 'An image of the entire screen has been copied to clipboard'
|
||||
Mod1+Print exec grimshot copy output && notify-send -a 'Screenshot' -u low 'Screenshot taken' 'An image of the focused display has been copied to clipboard'
|
||||
}
|
||||
21
.config/sway/config.d/40-input.conf
Normal file
21
.config/sway/config.d/40-input.conf
Normal file
@ -0,0 +1,21 @@
|
||||
### ###
|
||||
# Input Configuration #
|
||||
### ###
|
||||
|
||||
# Includes configuration for input devices (keyboards, mice,
|
||||
# trackpads, etc.)
|
||||
|
||||
## Keyboard settings
|
||||
# Enables numlock, makes capslock into a compose key, and loads custom
|
||||
# keymap
|
||||
input * {
|
||||
xkb_numlock enabled
|
||||
xkb_options compose:caps
|
||||
xkb_file ~/.config/sway/keymap.xkb
|
||||
}
|
||||
|
||||
## Touchpad settings
|
||||
# Enables tap-to-click
|
||||
input type:touchpad {
|
||||
tap enabled
|
||||
}
|
||||
14
.config/sway/config.d/90-services.conf
Normal file
14
.config/sway/config.d/90-services.conf
Normal file
@ -0,0 +1,14 @@
|
||||
### ###
|
||||
# Service Management #
|
||||
### ###
|
||||
|
||||
# This file interacts with SystemD to activate services
|
||||
|
||||
## Import activation environment
|
||||
exec_always XDG_CURRENT_DESKTOP=sway {
|
||||
systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP PATH ASDF_DATA_DIR
|
||||
dbus-update-activation-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP PATH ASDF_DATA_DIR
|
||||
}
|
||||
|
||||
## Start the session target
|
||||
exec_always systemctl --user start sway-session.target
|
||||
19
.config/sway/config.new
Normal file
19
.config/sway/config.new
Normal file
@ -0,0 +1,19 @@
|
||||
### ###
|
||||
# Tycho Station Sway Config #
|
||||
### ###
|
||||
|
||||
# This config file is modular. Set variables here, then use them in
|
||||
# drop-in config files located in ~/.config/sway/config.d/
|
||||
|
||||
set $mod Mod4
|
||||
set $alt Mod1
|
||||
|
||||
set $leftdisplay DP-1
|
||||
set $rightdisplay DP-2
|
||||
|
||||
### ###
|
||||
# HERE BE DRAGONS #
|
||||
### ###
|
||||
|
||||
# Do not edit anything below these comments. You have been warned.
|
||||
include ~/.config/sway/config.d/*.conf
|
||||
264
.config/sway/config.old
Normal file
264
.config/sway/config.old
Normal file
@ -0,0 +1,264 @@
|
||||
|
||||
#### ####
|
||||
## Tycho Station sway Config File ##
|
||||
#### ####
|
||||
|
||||
### ###
|
||||
# Display settings #
|
||||
### ###
|
||||
|
||||
# This section controls how connected displays are treated
|
||||
|
||||
# Set monitor vars
|
||||
set $leftdisplay DP-1
|
||||
set $rightdisplay DP-2
|
||||
|
||||
output {
|
||||
$leftdisplay pos 0 0 mode 1920x1200
|
||||
$rightdisplay pos 1920 0 mode 1920x1200
|
||||
* bg '#1e1e1e' solid_color
|
||||
}
|
||||
|
||||
### ###
|
||||
# Window Manager settings #
|
||||
### ###
|
||||
|
||||
# This section controls how the window manager functions. It does
|
||||
# not include keybinds that are not directly related to the window
|
||||
# manager's window management functions.
|
||||
|
||||
set $mod Mod4
|
||||
set $alt Mod1
|
||||
|
||||
# Set font
|
||||
font pango:Source Code Pro 8
|
||||
|
||||
# Reload configuration
|
||||
bindsym $mod+Shift+r reload
|
||||
|
||||
# Exit
|
||||
bindsym $mod+Shift+e exit
|
||||
|
||||
### ###
|
||||
# Window Management Settings #
|
||||
### ###
|
||||
|
||||
# This section controls window behavior and management keybinds.
|
||||
# It also includes the resize mode.
|
||||
|
||||
# Set keybinds to switch workspaces
|
||||
bindsym $mod+1 exec swaymsg workspace $(i3-sensible-workspaces 1 )
|
||||
bindsym $mod+2 exec swaymsg workspace $(i3-sensible-workspaces 2 )
|
||||
bindsym $mod+3 exec swaymsg workspace $(i3-sensible-workspaces 3 )
|
||||
bindsym $mod+4 exec swaymsg workspace $(i3-sensible-workspaces 4 )
|
||||
bindsym $mod+5 exec swaymsg workspace $(i3-sensible-workspaces 5 )
|
||||
bindsym $mod+6 exec swaymsg workspace $(i3-sensible-workspaces 6 )
|
||||
bindsym $mod+7 exec swaymsg workspace $(i3-sensible-workspaces 7 )
|
||||
bindsym $mod+8 exec swaymsg workspace $(i3-sensible-workspaces 8 )
|
||||
bindsym $mod+9 exec swaymsg workspace $(i3-sensible-workspaces 9 )
|
||||
bindsym $mod+0 exec swaymsg workspace $(i3-sensible-workspaces 10)
|
||||
|
||||
# Set keybinds to move windows between workspaces
|
||||
bindsym $mod+Shift+1 exec swaymsg move container to workspace $(i3-sensible-workspaces 1 )
|
||||
bindsym $mod+Shift+2 exec swaymsg move container to workspace $(i3-sensible-workspaces 2 )
|
||||
bindsym $mod+Shift+3 exec swaymsg move container to workspace $(i3-sensible-workspaces 3 )
|
||||
bindsym $mod+Shift+4 exec swaymsg move container to workspace $(i3-sensible-workspaces 4 )
|
||||
bindsym $mod+Shift+5 exec swaymsg move container to workspace $(i3-sensible-workspaces 5 )
|
||||
bindsym $mod+Shift+6 exec swaymsg move container to workspace $(i3-sensible-workspaces 6 )
|
||||
bindsym $mod+Shift+7 exec swaymsg move container to workspace $(i3-sensible-workspaces 7 )
|
||||
bindsym $mod+Shift+8 exec swaymsg move container to workspace $(i3-sensible-workspaces 8 )
|
||||
bindsym $mod+Shift+9 exec swaymsg move container to workspace $(i3-sensible-workspaces 9 )
|
||||
bindsym $mod+Shift+0 exec swaymsg move container to workspace $(i3-sensible-workspaces 10)
|
||||
|
||||
# Bind workspaces to monitors
|
||||
workspace 1 output $leftdisplay
|
||||
workspace 2 output $leftdisplay
|
||||
workspace 3 output $leftdisplay
|
||||
workspace 4 output $leftdisplay
|
||||
workspace 5 output $leftdisplay
|
||||
workspace 6 output $leftdisplay
|
||||
workspace 7 output $leftdisplay
|
||||
workspace 8 output $leftdisplay
|
||||
workspace 9 output $leftdisplay
|
||||
workspace 10 output $leftdisplay
|
||||
|
||||
workspace 11 output $rightdisplay
|
||||
workspace 12 output $rightdisplay
|
||||
workspace 13 output $rightdisplay
|
||||
workspace 14 output $rightdisplay
|
||||
workspace 15 output $rightdisplay
|
||||
workspace 16 output $rightdisplay
|
||||
workspace 17 output $rightdisplay
|
||||
workspace 18 output $rightdisplay
|
||||
workspace 19 output $rightdisplay
|
||||
workspace 20 output $rightdisplay
|
||||
|
||||
# Allow dragging of floating windows whilst holding $mod
|
||||
floating_modifier $mod
|
||||
|
||||
# Resize mode
|
||||
mode "resize" {
|
||||
bindsym Left resize shrink width 10 px or 1 ppt
|
||||
bindsym Down resize grow height 10 px or 1 ppt
|
||||
bindsym Up resize shrink height 10 px or 1 ppt
|
||||
bindsym f resize grow width 10 px or 1 ppt
|
||||
|
||||
# Exit resize mode
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
bindsym $mod+r mode "default"
|
||||
}
|
||||
|
||||
bindsym $mod+r mode "resize"
|
||||
|
||||
|
||||
bindsym {
|
||||
# Move windows
|
||||
$mod+Shift+b move left
|
||||
$mod+Shift+f move right
|
||||
$mod+Shift+p move up
|
||||
$mod+Shift+n move down
|
||||
|
||||
$mod+Shift+Left move left
|
||||
$mod+Shift+Right move right
|
||||
$mod+Shift+Up move up
|
||||
$mod+Shift+Down move down
|
||||
|
||||
# Shift focus
|
||||
$mod+b focus left
|
||||
$mod+f focus right
|
||||
$mod+p focus up
|
||||
$mod+n focus down
|
||||
$mod+a focus parent
|
||||
|
||||
# Splits
|
||||
$mod+h split h
|
||||
$mod+v split v
|
||||
|
||||
# Fullscreen
|
||||
$mod+$alt+f fullscreen toggle
|
||||
|
||||
# Floating
|
||||
$mod+Shift+space floating toggle
|
||||
$mod+space focus mode_toggle
|
||||
|
||||
# Close window
|
||||
$mod+Shift+q kill
|
||||
|
||||
# Change window arrangement
|
||||
$mod+e layout toggle split
|
||||
$mod+t layout tabbed
|
||||
$mod+s layout stacking
|
||||
}
|
||||
|
||||
### ###
|
||||
# Appearance #
|
||||
### ###
|
||||
|
||||
default_border pixel 1
|
||||
|
||||
# Colors
|
||||
set $blue #5E81AC
|
||||
set $orange #D08770
|
||||
set $grey #2E3440
|
||||
set $wallpaper #242933
|
||||
|
||||
set $primary '#815986'
|
||||
set $background '#2d272f'
|
||||
set $wallpaper '#242933'
|
||||
|
||||
client.focused $primary $background $primary $primary $primary
|
||||
client.focused_inactive $primary $background $primary $background $background
|
||||
client.unfocused $background $background $primary $background $background
|
||||
|
||||
# client.focused $blue $grey $blue $blue $blue
|
||||
# client.focused_inactive $grey $grey $blue $blue $grey
|
||||
# client.unfocused $grey $grey $blue $blue $grey
|
||||
# client.urgent $orange $wallpaper $orange $orange $orange
|
||||
|
||||
# Gaps
|
||||
gaps inner 10
|
||||
|
||||
# Themes
|
||||
|
||||
set $gnome-schema org.gnome.desktop.interface
|
||||
|
||||
exec_always {
|
||||
gsettings set $gnome-schema gtk-theme 'Nordic-darker'
|
||||
gsettings set $gnome-schema icon-theme 'ePapirus-Dark'
|
||||
gsettings set $gnome-schema font-name 'Source Sans Pro:12'
|
||||
gsettings set $gnome-schema text-scaling-factor 1
|
||||
}
|
||||
|
||||
### ###
|
||||
# Desktop Features #
|
||||
### ###
|
||||
|
||||
# This section includes basic desktop features, such as
|
||||
# the ability to launch programs and functional media keys
|
||||
|
||||
# Sensible launcher (launches program based on workspace)
|
||||
bindsym $mod+Return exec i3-sensible-launcher
|
||||
|
||||
# Terminal launch override
|
||||
bindsym $mod+Shift+Return exec alacritty
|
||||
|
||||
# Program menu
|
||||
bindsym $mod+d exec wofi --show drun
|
||||
|
||||
# Media keys
|
||||
bindsym --locked {
|
||||
XF86AudioPlay exec playerctl play-pause
|
||||
XF86AudioNext exec playerctl next
|
||||
XF86AudioPrev exec playerctl previous
|
||||
}
|
||||
|
||||
# Volume keys (disabled)
|
||||
# bindsym --locked {
|
||||
# XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@ +1%
|
||||
# XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@ -1%
|
||||
# XF86AudioMute exec pactl set-sink-mute @DEFAULT_SINK@ toggle
|
||||
# }
|
||||
# Backlight
|
||||
bindsym --locked {
|
||||
XF86MonBrightnessUp exec light -A 5
|
||||
XF86MonBrightnessDown exec light -U 5
|
||||
}
|
||||
|
||||
# Lock screen
|
||||
bindsym $mod+l exec loginctl lock-session
|
||||
bindsym $mod+Shift+l exec aggietimed -s /run/user/1000/aggietimed.sock --action clock-out && loginctl lock-session
|
||||
|
||||
# Notification management
|
||||
bindsym $mod+Ctrl+Space exec dunstctl close
|
||||
|
||||
# Screenshot bindings
|
||||
bindsym {
|
||||
Shift+Print exec grimshot copy area
|
||||
Ctrl+Print exec grimshot copy window
|
||||
Print exec grimshot copy screen
|
||||
Mod1+Print exec grimshot copy output
|
||||
}
|
||||
|
||||
# Start daemons
|
||||
#include /etc/sway/config.d/50-systemd-user.conf
|
||||
exec_always env ASDF_DATA_DIR=/home/ezri/.local/share/asdf-vm XDG_CURRENT_DESKTOP=sway {
|
||||
systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP PATH ASDF_DATA_DIR
|
||||
dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP PATH ASDF_DATA_DIR
|
||||
}
|
||||
|
||||
exec_always /usr/bin/systemctl --user start sway-session.target
|
||||
|
||||
# Start status bars
|
||||
exec systemd-cat -t eww -p info --stderr-priority=notice eww daemon; sleep 1; eww open-many leftbar rightbar
|
||||
|
||||
# Keyboard settings
|
||||
input * {
|
||||
xkb_numlock enabled
|
||||
xkb_options compose:caps
|
||||
xkb_file ~/.config/sway/keymap.xkb
|
||||
}
|
||||
|
||||
input type:touchpad {
|
||||
tap enabled
|
||||
}
|
||||
260
.config/sway/config~
Normal file
260
.config/sway/config~
Normal file
@ -0,0 +1,260 @@
|
||||
#### ####
|
||||
## Triskelion sway Config File ##
|
||||
#### ####
|
||||
|
||||
### ###
|
||||
# Display settings #
|
||||
### ###
|
||||
|
||||
# This section controls how connected displays are treated
|
||||
|
||||
# Set monitor vars
|
||||
set $leftdisplay DP-1
|
||||
set $rightdisplay DP-2
|
||||
|
||||
output {
|
||||
$leftdisplay pos 0 0 mode 1920x1080
|
||||
$rightdisplay pos 1920 0 mode 1920x1080
|
||||
* bg '#1e1e1e' solid_color
|
||||
}
|
||||
|
||||
### ###
|
||||
# Window Manager settings #
|
||||
### ###
|
||||
|
||||
# This section controls how the window manager functions. It does
|
||||
# not include keybinds that are not directly related to the window
|
||||
# manager's window management functions.
|
||||
|
||||
set $mod Mod4
|
||||
set $alt Mod1
|
||||
|
||||
# Set font
|
||||
font pango:Source Code Pro 8
|
||||
|
||||
# Reload configuration
|
||||
bindsym $mod+Shift+r reload
|
||||
|
||||
# Exit
|
||||
bindsym $mod+Shift+e exit
|
||||
|
||||
### ###
|
||||
# Window Management Settings #
|
||||
### ###
|
||||
|
||||
# This section controls window behavior and management keybinds.
|
||||
# It also includes the resize mode.
|
||||
|
||||
# Set keybinds to switch workspaces
|
||||
bindsym $mod+1 exec swaymsg workspace $(i3-sensible-workspaces 1 )
|
||||
bindsym $mod+2 exec swaymsg workspace $(i3-sensible-workspaces 2 )
|
||||
bindsym $mod+3 exec swaymsg workspace $(i3-sensible-workspaces 3 )
|
||||
bindsym $mod+4 exec swaymsg workspace $(i3-sensible-workspaces 4 )
|
||||
bindsym $mod+5 exec swaymsg workspace $(i3-sensible-workspaces 5 )
|
||||
bindsym $mod+6 exec swaymsg workspace $(i3-sensible-workspaces 6 )
|
||||
bindsym $mod+7 exec swaymsg workspace $(i3-sensible-workspaces 7 )
|
||||
bindsym $mod+8 exec swaymsg workspace $(i3-sensible-workspaces 8 )
|
||||
bindsym $mod+9 exec swaymsg workspace $(i3-sensible-workspaces 9 )
|
||||
bindsym $mod+0 exec swaymsg workspace $(i3-sensible-workspaces 10)
|
||||
|
||||
# Set keybinds to move windows between workspaces
|
||||
bindsym $mod+Shift+1 exec swaymsg move container to workspace $(i3-sensible-workspaces 1 )
|
||||
bindsym $mod+Shift+2 exec swaymsg move container to workspace $(i3-sensible-workspaces 2 )
|
||||
bindsym $mod+Shift+3 exec swaymsg move container to workspace $(i3-sensible-workspaces 3 )
|
||||
bindsym $mod+Shift+4 exec swaymsg move container to workspace $(i3-sensible-workspaces 4 )
|
||||
bindsym $mod+Shift+5 exec swaymsg move container to workspace $(i3-sensible-workspaces 5 )
|
||||
bindsym $mod+Shift+6 exec swaymsg move container to workspace $(i3-sensible-workspaces 6 )
|
||||
bindsym $mod+Shift+7 exec swaymsg move container to workspace $(i3-sensible-workspaces 7 )
|
||||
bindsym $mod+Shift+8 exec swaymsg move container to workspace $(i3-sensible-workspaces 8 )
|
||||
bindsym $mod+Shift+9 exec swaymsg move container to workspace $(i3-sensible-workspaces 9 )
|
||||
bindsym $mod+Shift+0 exec swaymsg move container to workspace $(i3-sensible-workspaces 10)
|
||||
|
||||
# Bind workspaces to monitors
|
||||
workspace 1 output $leftdisplay
|
||||
workspace 2 output $leftdisplay
|
||||
workspace 3 output $leftdisplay
|
||||
workspace 4 output $leftdisplay
|
||||
workspace 5 output $leftdisplay
|
||||
workspace 6 output $leftdisplay
|
||||
workspace 7 output $leftdisplay
|
||||
workspace 8 output $leftdisplay
|
||||
workspace 9 output $leftdisplay
|
||||
workspace 10 output $leftdisplay
|
||||
|
||||
workspace 11 output $rightdisplay
|
||||
workspace 12 output $rightdisplay
|
||||
workspace 13 output $rightdisplay
|
||||
workspace 14 output $rightdisplay
|
||||
workspace 15 output $rightdisplay
|
||||
workspace 16 output $rightdisplay
|
||||
workspace 17 output $rightdisplay
|
||||
workspace 18 output $rightdisplay
|
||||
workspace 19 output $rightdisplay
|
||||
workspace 20 output $rightdisplay
|
||||
|
||||
# Allow dragging of floating windows whilst holding $mod
|
||||
floating_modifier $mod
|
||||
|
||||
# Resize mode
|
||||
mode "resize" {
|
||||
bindsym Left resize shrink width 10 px or 1 ppt
|
||||
bindsym Down resize grow height 10 px or 1 ppt
|
||||
bindsym Up resize shrink height 10 px or 1 ppt
|
||||
bindsym f resize grow width 10 px or 1 ppt
|
||||
|
||||
# Exit resize mode
|
||||
bindsym Return mode "default"
|
||||
bindsym Escape mode "default"
|
||||
bindsym $mod+r mode "default"
|
||||
}
|
||||
|
||||
bindsym $mod+r mode "resize"
|
||||
|
||||
|
||||
bindsym {
|
||||
# Move windows
|
||||
$mod+Shift+b move left
|
||||
$mod+Shift+f move right
|
||||
$mod+Shift+p move up
|
||||
$mod+Shift+n move down
|
||||
|
||||
$mod+Shift+Left move left
|
||||
$mod+Shift+Right move right
|
||||
$mod+Shift+Up move up
|
||||
$mod+Shift+Down move down
|
||||
|
||||
# Shift focus
|
||||
$mod+b focus left
|
||||
$mod+f focus right
|
||||
$mod+p focus up
|
||||
$mod+n focus down
|
||||
$mod+a focus parent
|
||||
|
||||
# Splits
|
||||
$mod+h split h
|
||||
$mod+v split v
|
||||
|
||||
# Fullscreen
|
||||
$mod+$alt+f fullscreen toggle
|
||||
|
||||
# Floating
|
||||
$mod+Shift+space floating toggle
|
||||
$mod+space focus mode_toggle
|
||||
|
||||
# Close window
|
||||
$mod+Shift+q kill
|
||||
|
||||
# Change window arrangement
|
||||
$mod+e layout toggle split
|
||||
$mod+t layout tabbed
|
||||
$mod+s layout stacking
|
||||
}
|
||||
|
||||
### ###
|
||||
# Appearance #
|
||||
### ###
|
||||
|
||||
default_border pixel 1
|
||||
|
||||
# Colors
|
||||
set $blue #5E81AC
|
||||
set $orange #D08770
|
||||
set $grey #2E3440
|
||||
set $wallpaper #242933
|
||||
|
||||
set $primary '#815986'
|
||||
set $background '#2d272f'
|
||||
set $wallpaper '#242933'
|
||||
|
||||
client.focused $primary $background $primary $primary $primary
|
||||
client.focused_inactive $primary $background $primary $background $background
|
||||
client.unfocused $background $background $primary $background $background
|
||||
|
||||
# client.focused $blue $grey $blue $blue $blue
|
||||
# client.focused_inactive $grey $grey $blue $blue $grey
|
||||
# client.unfocused $grey $grey $blue $blue $grey
|
||||
# client.urgent $orange $wallpaper $orange $orange $orange
|
||||
|
||||
# Gaps
|
||||
gaps inner 10
|
||||
|
||||
# Themes
|
||||
|
||||
set $gnome-schema org.gnome.desktop.interface
|
||||
|
||||
exec_always {
|
||||
gsettings set $gnome-schema gtk-theme 'Nordic-darker'
|
||||
gsettings set $gnome-schema icon-theme 'ePapirus-Dark'
|
||||
gsettings set $gnome-schema font-name 'Source Sans Pro:12'
|
||||
gsettings set $gnome-schema text-scaling-factor 1
|
||||
}
|
||||
|
||||
### ###
|
||||
# Desktop Features #
|
||||
### ###
|
||||
|
||||
# This section includes basic desktop features, such as
|
||||
# the ability to launch programs and functional media keys
|
||||
|
||||
# Sensible launcher (launches program based on workspace)
|
||||
bindsym $mod+Return exec i3-sensible-launcher
|
||||
|
||||
# Terminal launch override
|
||||
bindsym $mod+Shift+Return exec alacritty
|
||||
|
||||
# Program menu
|
||||
bindsym $mod+d exec wofi --show drun
|
||||
|
||||
# Media keys
|
||||
bindsym --locked {
|
||||
XF86AudioPlay exec playerctl play-pause
|
||||
XF86AudioNext exec playerctl next
|
||||
XF86AudioPrev exec playerctl previous
|
||||
}
|
||||
|
||||
# Volume keys
|
||||
bindsym --locked {
|
||||
XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@ +1%
|
||||
XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@ -1%
|
||||
XF86AudioMute exec pactl set-sink-mute @DEFAULT_SINK@ toggle
|
||||
}
|
||||
# Backlight
|
||||
bindsym --locked {
|
||||
XF86MonBrightnessUp exec light -A 5
|
||||
XF86MonBrightnessDown exec light -U 5
|
||||
}
|
||||
|
||||
# Lock screen
|
||||
bindsym $mod+l exec loginctl lock-session
|
||||
|
||||
# Notification management
|
||||
bindsym $mod+Ctrl+Space exec dunstctl close
|
||||
|
||||
# Screenshot bindings
|
||||
bindsym {
|
||||
Shift+Print exec grimshot copy area
|
||||
Ctrl+Print exec grimshot copy window
|
||||
Print exec grimshot copy screen
|
||||
Mod1+Print exec grimshot copy output
|
||||
}
|
||||
|
||||
# Start daemons
|
||||
#include /etc/sway/config.d/50-systemd-user.conf
|
||||
exec env XDG_CURRENT_DESKTOP=sway systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP PATH
|
||||
exec env XDG_CURRENT_DESKTOP=sway hash dbus-update-activation-environment 2>/dev/null && \
|
||||
env XDG_CURRENT_DESKTOP=sway dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP PATH
|
||||
exec_always /usr/bin/systemctl --user start sway-session.target
|
||||
|
||||
# Start status bars
|
||||
exec eww open-many leftbar rightbar
|
||||
|
||||
# Keyboard settings
|
||||
input * {
|
||||
xkb_numlock enabled
|
||||
xkb_options compose:caps
|
||||
xkb_file ~/.config/sway/keymap.xkb
|
||||
}
|
||||
|
||||
input type:touchpad {
|
||||
tap enabled
|
||||
}
|
||||
1565
.config/sway/keymap.xkb
Normal file
1565
.config/sway/keymap.xkb
Normal file
File diff suppressed because it is too large
Load Diff
9
.config/sway/swayidle
Normal file
9
.config/sway/swayidle
Normal file
@ -0,0 +1,9 @@
|
||||
# -*-conf-*-
|
||||
|
||||
timeout 30 'if pgrep swaylock; then swaymsg "output * power off"; pkill -SIGSTOP electron; pkill -SIGSTOP slack; fi' resume 'if pgrep swaylock; then swaymsg "output * power on"; pkill -SIGCONT electron; pkill -SIGCONT slack; fi'
|
||||
timeout 300 'if pgrep swaylock; then lock-keyring; fi'
|
||||
lock ~/.local/bin/screenlock
|
||||
before-sleep 'loginctl lock-session'
|
||||
unlock 'pkill -USR1 swaylock'
|
||||
idlehint 300
|
||||
|
||||
137
.config/sway/workspaces.json
Normal file
137
.config/sway/workspaces.json
Normal file
@ -0,0 +1,137 @@
|
||||
{
|
||||
"work": {
|
||||
"left": [
|
||||
{
|
||||
"index": 10,
|
||||
"name": "config",
|
||||
"exec": "pavucontrol",
|
||||
"program_name": "pavucontrol"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"name": "messages",
|
||||
"exec": "alacritty",
|
||||
"program_name": "console"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"name": "slack",
|
||||
"exec": "slack -s",
|
||||
"program_name": "slack",
|
||||
"memory_profile": {
|
||||
"high": "800M",
|
||||
"max": "1.2G"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"name": "music",
|
||||
"exec": "spotify",
|
||||
"program_name": "spotify"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"name": "documents",
|
||||
"exec": "console",
|
||||
"program_name": "console"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"name": "images",
|
||||
"exec": "console",
|
||||
"program_name": "console"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"name": "project",
|
||||
"exec": "firefox --new-window",
|
||||
"void_output": true,
|
||||
"program_name": "firefox"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"name": "internet",
|
||||
"exec": "firefox --new-window",
|
||||
"void_output": true,
|
||||
"program_name": "firefox"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"name": "code",
|
||||
"exec": "emacsclient -nc",
|
||||
"program_name": "emacsclient"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"name": "console",
|
||||
"exec": "console",
|
||||
"program_name": "console"
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"index": 11,
|
||||
"name": "console",
|
||||
"exec": "console",
|
||||
"program_name": "console"
|
||||
},
|
||||
{
|
||||
"index": 12,
|
||||
"name": "code",
|
||||
"exec": "code",
|
||||
"program_name": "vscode"
|
||||
},
|
||||
{
|
||||
"index": 13,
|
||||
"name": "internet",
|
||||
"exec": "firefox --new-window",
|
||||
"void_output": true,
|
||||
"program_name": "firefox"
|
||||
},
|
||||
{
|
||||
"index": 14,
|
||||
"name": "project",
|
||||
"exec": "firefox --new-window",
|
||||
"void_output": true,
|
||||
"program_name": "firefox"
|
||||
},
|
||||
{
|
||||
"index": 15,
|
||||
"name": "server management",
|
||||
"exec": "virt-manager",
|
||||
"program_name": "virt-manager",
|
||||
"systemd": false
|
||||
},
|
||||
{
|
||||
"index": 16,
|
||||
"name": "password management",
|
||||
"exec": "bitwarden-desktop",
|
||||
"program_name": "bitwarden"
|
||||
},
|
||||
{
|
||||
"index": 17,
|
||||
"name": "video",
|
||||
"exec": "jellyfinmediaplayer",
|
||||
"program_name": "jellyfinmediaplayer"
|
||||
},
|
||||
{
|
||||
"index": 18,
|
||||
"name": "discord",
|
||||
"exec": "discord",
|
||||
"program_name": "discord"
|
||||
},
|
||||
{
|
||||
"index": 19,
|
||||
"name": "matrix",
|
||||
"exec": "element-desktop",
|
||||
"program_name": "element"
|
||||
},
|
||||
{
|
||||
"index": 20,
|
||||
"name": "vpn control",
|
||||
"exec": "gpclient",
|
||||
"program_name": "gpclient"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
85
.config/swaync/config.json
Normal file
85
.config/swaync/config.json
Normal file
@ -0,0 +1,85 @@
|
||||
{
|
||||
"$schema": "/etc/xdg/swaync/configSchema.json",
|
||||
"positionX": "center",
|
||||
"positionY": "top",
|
||||
"layer": "overlay",
|
||||
"control-center-layer": "top",
|
||||
"layer-shell": true,
|
||||
"cssPriority": "user",
|
||||
"control-center-margin-top": 0,
|
||||
"control-center-margin-bottom": 0,
|
||||
"control-center-margin-right": 0,
|
||||
"control-center-margin-left": 0,
|
||||
"notification-2fa-action": true,
|
||||
"notification-inline-replies": false,
|
||||
"notification-icon-size": 64,
|
||||
"notification-body-image-height": 100,
|
||||
"notification-body-image-width": 200,
|
||||
"timeout": 10,
|
||||
"timeout-low": 5,
|
||||
"timeout-critical": 0,
|
||||
"fit-to-screen": true,
|
||||
"relative-timestamps": true,
|
||||
"control-center-width": 500,
|
||||
"control-center-height": 600,
|
||||
"notification-window-width": 500,
|
||||
"keyboard-shortcuts": true,
|
||||
"image-visibility": "when-available",
|
||||
"transition-time": 200,
|
||||
"hide-on-clear": false,
|
||||
"hide-on-action": true,
|
||||
"script-fail-notify": true,
|
||||
"scripts": {
|
||||
"example-script": {
|
||||
"exec": "echo 'Do something...'",
|
||||
"urgency": "Normal"
|
||||
},
|
||||
"example-action-script": {
|
||||
"exec": "echo 'Do something actionable!'",
|
||||
"urgency": "Normal",
|
||||
"run-on": "action"
|
||||
}
|
||||
},
|
||||
"notification-visibility": {
|
||||
"example-name": {
|
||||
"state": "muted",
|
||||
"urgency": "Low",
|
||||
"app-name": "Spotify"
|
||||
}
|
||||
},
|
||||
"widgets": ["inhibitors", "title", "dnd", "notifications"],
|
||||
"widget-config": {
|
||||
"inhibitors": {
|
||||
"text": "Inhibitors",
|
||||
"button-text": "Clear All",
|
||||
"clear-all-button": true
|
||||
},
|
||||
"title": {
|
||||
"text": "Notifications",
|
||||
"clear-all-button": true,
|
||||
"button-text": "Clear All"
|
||||
},
|
||||
"dnd": {
|
||||
"text": "Do Not Disturb"
|
||||
},
|
||||
"label": {
|
||||
"max-lines": 5,
|
||||
"text": "Label Text"
|
||||
},
|
||||
"mpris": {
|
||||
"image-size": 96,
|
||||
"image-radius": 12
|
||||
},
|
||||
"buttons-grid": {
|
||||
"actions": [
|
||||
{
|
||||
"label": "直",
|
||||
"type": "toggle",
|
||||
"active": true,
|
||||
"command": "sh -c '[[ $SWAYNC_TOGGLE_STATE == true ]] && nmcli radio wifi on || nmcli radio wifi off'",
|
||||
"update_command": "sh -c '[[ $(nmcli radio wifi) == \"enabled\" ]] && echo true || echo false'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
659
.config/swaync/style.css
Normal file
659
.config/swaync/style.css
Normal file
@ -0,0 +1,659 @@
|
||||
@define-color cc-bg rgba(30, 30, 30, 0.8);
|
||||
@define-color noti-border-color #815986;
|
||||
@define-color noti-border-color-low #3f3242;
|
||||
@define-color noti-border-color-critical #cf6a4c;
|
||||
@define-color noti-bg rgba(30, 30, 30, 0.8);
|
||||
@define-color noti-bg-opaque #1e1e1e;
|
||||
@define-color noti-bg-darker #1a1a1a;
|
||||
@define-color noti-bg-hover rgba(32, 32, 32, 0.8);
|
||||
@define-color noti-bg-hover-opaque #202020;
|
||||
@define-color noti-bg-focus rgba(40, 40, 40, 0.8);
|
||||
@define-color noti-close-bg rgba(255, 255, 255, 0.1);
|
||||
@define-color noti-close-bg-hover rgba(255, 255, 255, 0.15);
|
||||
@define-color text-color #9b859d;
|
||||
@define-color text-color-low #9a7c9d;
|
||||
@define-color text-color-critical #cf6a4c;
|
||||
@define-color text-color-disabled rgb(150, 150, 150);
|
||||
@define-color bg-selected rgb(0, 128, 255);
|
||||
.notification-row {
|
||||
outline: none;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-row:focus,
|
||||
.notification-row:hover {
|
||||
background: @noti-bg-focus;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-row .notification-background {
|
||||
padding: 6px 12px;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .close-button {
|
||||
/* The notification Close Button */
|
||||
background: @noti-close-bg;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
padding: 0;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .close-button:hover {
|
||||
box-shadow: none;
|
||||
background: @noti-close-bg-hover;
|
||||
transition: background 0.15s ease-in-out;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification {
|
||||
/* The actual notification */
|
||||
border: 1px solid @noti-border-color;
|
||||
padding: 0;
|
||||
transition: background 0.15s ease-in-out;
|
||||
background: @noti-bg;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification.low {
|
||||
/* Low Priority Notification */
|
||||
border-color: @noti-border-color-low;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification.normal {
|
||||
/* Normal Priority Notification */
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification.critical {
|
||||
/* Critical Priority Notification */
|
||||
border-color: @noti-border-color-critical;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification .notification-action,
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action {
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: @text-color;
|
||||
transition: background 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-action:hover,
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action:hover {
|
||||
-gtk-icon-effect: none;
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action {
|
||||
/* The large action that also displays the notification summary and body */
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action:not(:only-child) {
|
||||
/* When alternative actions are visible */
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content {
|
||||
background: transparent;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.image {
|
||||
/* Notification Primary Image */
|
||||
-gtk-icon-effect: none;
|
||||
/* Size in px */
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.app-icon {
|
||||
/* Notification app icon (only visible when the primary image is set) */
|
||||
-gtk-icon-effect: none;
|
||||
-gtk-icon-shadow: 0 1px 4px black;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.summary {
|
||||
/* Notification summary/title */
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.low
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.summary {
|
||||
/* Low Priority Notification summary/title */
|
||||
color: @text-color-low;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.critical
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.summary {
|
||||
/* Critical Priority Notification summary/title */
|
||||
color: @text-color-critical;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.time {
|
||||
/* Notification time-ago */
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.body {
|
||||
/* Notification body */
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
background: transparent;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.low
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.body {
|
||||
/* Low Priority Notification body */
|
||||
color: @text-color-low;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.critical
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.body {
|
||||
/* Critical Priority Notification body */
|
||||
color: @text-color-critical;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
progressbar {
|
||||
/* The optional notification progress bar */
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.body-image {
|
||||
/* The "extra" optional bottom notification image */
|
||||
margin-top: 4px;
|
||||
background-color: white;
|
||||
-gtk-icon-effect: none;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply {
|
||||
/* The inline reply section */
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-entry {
|
||||
background: @noti-bg-darker;
|
||||
color: @text-color;
|
||||
caret-color: @text-color;
|
||||
border: 1px solid @noti-border-color;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-button {
|
||||
margin-left: 4px;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-button:disabled {
|
||||
background: initial;
|
||||
color: @text-color-disabled;
|
||||
border: 1px solid @noti-border-color;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification .notification-action {
|
||||
/* The alternative actions below the default action */
|
||||
border-top: 1px solid @noti-border-color;
|
||||
border-right: 1px solid @noti-border-color;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-action:first-child {
|
||||
/* add bottom border radius to eliminate clipping */
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-action:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.notification-group {
|
||||
/* Styling only for Grouped Notifications */
|
||||
}
|
||||
|
||||
.notification-group.low {
|
||||
/* Low Priority Group */
|
||||
}
|
||||
|
||||
.notification-group.normal {
|
||||
/* Low Priority Group */
|
||||
}
|
||||
|
||||
.notification-group.critical {
|
||||
/* Low Priority Group */
|
||||
}
|
||||
|
||||
.notification-group .notification-group-buttons,
|
||||
.notification-group .notification-group-headers {
|
||||
margin: 0 16px;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-group .notification-group-headers {
|
||||
/* Notification Group Headers */
|
||||
}
|
||||
|
||||
.notification-group .notification-group-headers .notification-group-icon {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-group.low .notification-group-headers .notification-group-icon {
|
||||
/* Low Priority Group Icon */
|
||||
color: @text-color-low;
|
||||
}
|
||||
|
||||
.notification-group.critical
|
||||
.notification-group-headers
|
||||
.notification-group-icon {
|
||||
/* Critical Priority Group Icon */
|
||||
color: @text-color-critical;
|
||||
}
|
||||
|
||||
.notification-group .notification-group-headers .notification-group-header {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-group.low .notification-group-headers .notification-group-header {
|
||||
/* Low Priority Group Header */
|
||||
color: @text-color-low;
|
||||
}
|
||||
|
||||
.notification-group.critical
|
||||
.notification-group-headers
|
||||
.notification-group-header {
|
||||
/* Critical Priority Group Header */
|
||||
color: @text-color-critical;
|
||||
}
|
||||
|
||||
.notification-group .notification-group-buttons {
|
||||
/* Notification Group Buttons */
|
||||
}
|
||||
|
||||
.notification-group.collapsed .notification-row .notification {
|
||||
background-color: @noti-bg-opaque;
|
||||
}
|
||||
|
||||
.notification-group.collapsed .notification-row:not(:last-child) {
|
||||
/* Top notification in stack */
|
||||
/* Set lower stacked notifications opacity to 0 */
|
||||
}
|
||||
|
||||
.notification-group.collapsed
|
||||
.notification-row:not(:last-child)
|
||||
.notification-action,
|
||||
.notification-group.collapsed
|
||||
.notification-row:not(:last-child)
|
||||
.notification-default-action {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.notification-group.collapsed:hover
|
||||
.notification-row:not(:only-child)
|
||||
.notification {
|
||||
background-color: @noti-bg-hover-opaque;
|
||||
}
|
||||
|
||||
.control-center {
|
||||
/* The Control Center which contains the old notifications + widgets */
|
||||
background: @cc-bg;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.control-center .control-center-list-placeholder {
|
||||
/* The placeholder when there are no notifications */
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.control-center .control-center-list {
|
||||
/* List of notifications */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.control-center .control-center-list .notification {
|
||||
}
|
||||
|
||||
.control-center .control-center-list .notification .notification-default-action,
|
||||
.control-center .control-center-list .notification .notification-action {
|
||||
transition: opacity 400ms ease-in-out, background 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.control-center
|
||||
.control-center-list
|
||||
.notification
|
||||
.notification-default-action:hover,
|
||||
.control-center .control-center-list .notification .notification-action:hover {
|
||||
background-color: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.blank-window {
|
||||
/* Window behind control center and on all other monitors */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.floating-notifications {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.floating-notifications .notification {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*** Widgets ***/
|
||||
/* Title widget */
|
||||
.widget-title {
|
||||
color: @text-color;
|
||||
margin: 8px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.widget-title > button {
|
||||
font-size: initial;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.widget-title > button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
/* DND widget */
|
||||
.widget-dnd {
|
||||
color: @text-color;
|
||||
margin: 8px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.widget-dnd > switch {
|
||||
font-size: initial;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.widget-dnd > switch:checked {
|
||||
background: @bg-selected;
|
||||
}
|
||||
|
||||
.widget-dnd > switch slider {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
/* Label widget */
|
||||
.widget-label {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.widget-label > label {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Mpris widget */
|
||||
@define-color mpris-album-art-overlay rgba(0, 0, 0, 0.55);
|
||||
@define-color mpris-button-hover rgba(0, 0, 0, 0.50);
|
||||
.widget-mpris {
|
||||
/* The parent to all players */
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player {
|
||||
padding: 8px;
|
||||
padding: 16px;
|
||||
margin: 16px 20px;
|
||||
background-color: @mpris-album-art-overlay;
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player button:hover {
|
||||
/* The media player buttons (play, pause, next, etc...) */
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player .widget-mpris-album-art {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player .widget-mpris-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player .widget-mpris-subtitle {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player > box > button {
|
||||
/* Change player control buttons */
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player > box > button:hover {
|
||||
background-color: @mpris-button-hover;
|
||||
}
|
||||
|
||||
.widget-mpris > box > button {
|
||||
/* Change player side buttons */
|
||||
}
|
||||
|
||||
.widget-mpris > box > button:disabled {
|
||||
/* Change player side buttons insensitive */
|
||||
}
|
||||
|
||||
/* Buttons widget */
|
||||
.widget-buttons-grid {
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
background-color: @noti-bg;
|
||||
}
|
||||
|
||||
.widget-buttons-grid > flowbox > flowboxchild > button {
|
||||
background: @noti-bg;
|
||||
}
|
||||
|
||||
.widget-buttons-grid > flowbox > flowboxchild > button.toggle:checked {
|
||||
/* style given to the active toggle button */
|
||||
}
|
||||
|
||||
/* Menubar widget */
|
||||
.widget-menubar > box > .menu-button-bar > button {
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* .AnyName { Name defined in config after #
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.AnyName>button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.AnyName>button:hover {
|
||||
background-color: @noti-bg-hover;
|
||||
} */
|
||||
.topbar-buttons > button {
|
||||
/* Name defined in config after # */
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Volume widget */
|
||||
.widget-volume {
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.widget-volume > box > button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.per-app-volume {
|
||||
background-color: @noti-bg-alt;
|
||||
padding: 4px 8px 8px 8px;
|
||||
margin: 0px 8px 8px 8px;
|
||||
}
|
||||
|
||||
/* Backlight widget */
|
||||
.widget-backlight {
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
/* Inhibitors widget */
|
||||
.widget-inhibitors {
|
||||
margin: 8px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.widget-inhibitors > button {
|
||||
font-size: initial;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.widget-inhibitors > button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
651
.config/swaync/style.css.old
Normal file
651
.config/swaync/style.css.old
Normal file
@ -0,0 +1,651 @@
|
||||
@define-color cc-bg rgba(30, 30, 30, 0.8);
|
||||
@define-color noti-border-color #815986;
|
||||
@define-color noti-border-color-low #3f3242;
|
||||
@define-color noti-border-color-critical #cf6a4c;
|
||||
@define-color noti-bg rgba(30, 30, 30, 0.8);
|
||||
@define-color noti-bg-opaque #1e1e1e;
|
||||
@define-color noti-bg-darker #1a1a1a;
|
||||
@define-color noti-bg-hover rgba(32, 32, 32, 0.8);
|
||||
@define-color noti-bg-hover-opaque #202020;
|
||||
@define-color noti-bg-focus rgba(40, 40, 40, 0.8);
|
||||
@define-color noti-close-bg rgba(255, 255, 255, 0.1);
|
||||
@define-color noti-close-bg-hover rgba(255, 255, 255, 0.15);
|
||||
@define-color text-color #9b859d;
|
||||
@define-color text-color-low #9a7c9d;
|
||||
@define-color text-color-critical #cf6a4c;
|
||||
@define-color text-color-disabled rgb(150, 150, 150);
|
||||
@define-color bg-selected rgb(0, 128, 255);
|
||||
.notification-row {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.notification-row:focus,
|
||||
.notification-row:hover {
|
||||
background: @noti-bg-focus;
|
||||
}
|
||||
|
||||
.notification-row .notification-background {
|
||||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .close-button {
|
||||
/* The notification Close Button */
|
||||
background: @noti-close-bg;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
padding: 0;
|
||||
border-radius: 100%;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .close-button:hover {
|
||||
box-shadow: none;
|
||||
background: @noti-close-bg-hover;
|
||||
transition: background 0.15s ease-in-out;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification {
|
||||
/* The actual notification */
|
||||
border: 1px solid @noti-border-color;
|
||||
padding: 0;
|
||||
transition: background 0.15s ease-in-out;
|
||||
background: @noti-bg;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification.low {
|
||||
/* Low Priority Notification */
|
||||
border-color: @noti-border-color-low;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification.normal {
|
||||
/* Normal Priority Notification */
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification.critical {
|
||||
/* Critical Priority Notification */
|
||||
border-color: @noti-border-color-critical;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification .notification-action,
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action {
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: @text-color;
|
||||
transition: background 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-action:hover,
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action:hover {
|
||||
-gtk-icon-effect: none;
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action {
|
||||
/* The large action that also displays the notification summary and body */
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action:not(:only-child) {
|
||||
/* When alternative actions are visible */
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content {
|
||||
background: transparent;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.image {
|
||||
/* Notification Primary Image */
|
||||
-gtk-icon-effect: none;
|
||||
border-radius: 100px;
|
||||
/* Size in px */
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.app-icon {
|
||||
/* Notification app icon (only visible when the primary image is set) */
|
||||
-gtk-icon-effect: none;
|
||||
-gtk-icon-shadow: 0 1px 4px black;
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.summary {
|
||||
/* Notification summary/title */
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.low
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.summary {
|
||||
/* Low Priority Notification summary/title */
|
||||
color: @text-color-low;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.critical
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.summary {
|
||||
/* Critical Priority Notification summary/title */
|
||||
color: @text-color-critical;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.time {
|
||||
/* Notification time-ago */
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.body {
|
||||
/* Notification body */
|
||||
font-size: 15px;
|
||||
font-weight: normal;
|
||||
background: transparent;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.low
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.body {
|
||||
/* Low Priority Notification body */
|
||||
color: @text-color-low;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification.critical
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.text-box
|
||||
.body {
|
||||
/* Critical Priority Notification body */
|
||||
color: @text-color-critical;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
progressbar {
|
||||
/* The optional notification progress bar */
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.body-image {
|
||||
/* The "extra" optional bottom notification image */
|
||||
margin-top: 4px;
|
||||
background-color: white;
|
||||
-gtk-icon-effect: none;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply {
|
||||
/* The inline reply section */
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-entry {
|
||||
background: @noti-bg-darker;
|
||||
color: @text-color;
|
||||
caret-color: @text-color;
|
||||
border: 1px solid @noti-border-color;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-button {
|
||||
margin-left: 4px;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-button:disabled {
|
||||
background: initial;
|
||||
color: @text-color-disabled;
|
||||
border: 1px solid @noti-border-color;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-default-action
|
||||
.notification-content
|
||||
.inline-reply
|
||||
.inline-reply-button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.notification-row .notification-background .notification .notification-action {
|
||||
/* The alternative actions below the default action */
|
||||
border-top: 1px solid @noti-border-color;
|
||||
border-radius: 0px;
|
||||
border-right: 1px solid @noti-border-color;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-action:first-child {
|
||||
/* add bottom border radius to eliminate clipping */
|
||||
border-bottom-left-radius: 12px;
|
||||
}
|
||||
|
||||
.notification-row
|
||||
.notification-background
|
||||
.notification
|
||||
.notification-action:last-child {
|
||||
border-bottom-right-radius: 12px;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.notification-group {
|
||||
/* Styling only for Grouped Notifications */
|
||||
}
|
||||
|
||||
.notification-group.low {
|
||||
/* Low Priority Group */
|
||||
}
|
||||
|
||||
.notification-group.normal {
|
||||
/* Low Priority Group */
|
||||
}
|
||||
|
||||
.notification-group.critical {
|
||||
/* Low Priority Group */
|
||||
}
|
||||
|
||||
.notification-group .notification-group-buttons,
|
||||
.notification-group .notification-group-headers {
|
||||
margin: 0 16px;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-group .notification-group-headers {
|
||||
/* Notification Group Headers */
|
||||
}
|
||||
|
||||
.notification-group .notification-group-headers .notification-group-icon {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-group .notification-group-headers .notification-group-header {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.notification-group .notification-group-buttons {
|
||||
/* Notification Group Buttons */
|
||||
}
|
||||
|
||||
.notification-group.collapsed .notification-row .notification {
|
||||
background-color: @noti-bg-opaque;
|
||||
}
|
||||
|
||||
.notification-group.collapsed .notification-row:not(:last-child) {
|
||||
/* Top notification in stack */
|
||||
/* Set lower stacked notifications opacity to 0 */
|
||||
}
|
||||
|
||||
.notification-group.collapsed
|
||||
.notification-row:not(:last-child)
|
||||
.notification-action,
|
||||
.notification-group.collapsed
|
||||
.notification-row:not(:last-child)
|
||||
.notification-default-action {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.notification-group.collapsed:hover
|
||||
.notification-row:not(:only-child)
|
||||
.notification {
|
||||
background-color: @noti-bg-hover-opaque;
|
||||
}
|
||||
|
||||
.control-center {
|
||||
/* The Control Center which contains the old notifications + widgets */
|
||||
background: @cc-bg;
|
||||
color: @text-color;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.control-center .control-center-list-placeholder {
|
||||
/* The placeholder when there are no notifications */
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.control-center .control-center-list {
|
||||
/* List of notifications */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.control-center .control-center-list .notification {
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7),
|
||||
0 2px 6px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.control-center .control-center-list .notification .notification-default-action,
|
||||
.control-center .control-center-list .notification .notification-action {
|
||||
transition: opacity 400ms ease-in-out, background 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.control-center
|
||||
.control-center-list
|
||||
.notification
|
||||
.notification-default-action:hover,
|
||||
.control-center .control-center-list .notification .notification-action:hover {
|
||||
background-color: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.blank-window {
|
||||
/* Window behind control center and on all other monitors */
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.floating-notifications {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.floating-notifications .notification {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*** Widgets ***/
|
||||
/* Title widget */
|
||||
.widget-title {
|
||||
color: @text-color;
|
||||
margin: 8px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.widget-title > button {
|
||||
font-size: initial;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.widget-title > button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
/* DND widget */
|
||||
.widget-dnd {
|
||||
color: @text-color;
|
||||
margin: 8px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.widget-dnd > switch {
|
||||
font-size: initial;
|
||||
border-radius: 12px;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.widget-dnd > switch:checked {
|
||||
background: @bg-selected;
|
||||
}
|
||||
|
||||
.widget-dnd > switch slider {
|
||||
background: @noti-bg-hover;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Label widget */
|
||||
.widget-label {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.widget-label > label {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Mpris widget */
|
||||
@define-color mpris-album-art-overlay rgba(0, 0, 0, 0.55);
|
||||
@define-color mpris-button-hover rgba(0, 0, 0, 0.50);
|
||||
.widget-mpris {
|
||||
/* The parent to all players */
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player {
|
||||
padding: 8px;
|
||||
padding: 16px;
|
||||
margin: 16px 20px;
|
||||
background-color: @mpris-album-art-overlay;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player button:hover {
|
||||
/* The media player buttons (play, pause, next, etc...) */
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player .widget-mpris-album-art {
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player .widget-mpris-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player .widget-mpris-subtitle {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player > box > button {
|
||||
/* Change player control buttons */
|
||||
}
|
||||
|
||||
.widget-mpris .widget-mpris-player > box > button:hover {
|
||||
background-color: @mpris-button-hover;
|
||||
}
|
||||
|
||||
.widget-mpris > box > button {
|
||||
/* Change player side buttons */
|
||||
}
|
||||
|
||||
.widget-mpris > box > button:disabled {
|
||||
/* Change player side buttons insensitive */
|
||||
}
|
||||
|
||||
/* Buttons widget */
|
||||
.widget-buttons-grid {
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
background-color: @noti-bg;
|
||||
}
|
||||
|
||||
.widget-buttons-grid > flowbox > flowboxchild > button {
|
||||
background: @noti-bg;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.widget-buttons-grid > flowbox > flowboxchild > button.toggle:checked {
|
||||
/* style given to the active toggle button */
|
||||
}
|
||||
|
||||
/* Menubar widget */
|
||||
.widget-menubar > box > .menu-button-bar > button {
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* .AnyName { Name defined in config after #
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.AnyName>button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.AnyName>button:hover {
|
||||
background-color: @noti-bg-hover;
|
||||
} */
|
||||
.topbar-buttons > button {
|
||||
/* Name defined in config after # */
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Volume widget */
|
||||
.widget-volume {
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.widget-volume > box > button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.per-app-volume {
|
||||
background-color: @noti-bg-alt;
|
||||
padding: 4px 8px 8px 8px;
|
||||
margin: 0px 8px 8px 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Backlight widget */
|
||||
.widget-backlight {
|
||||
background-color: @noti-bg;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Inhibitors widget */
|
||||
.widget-inhibitors {
|
||||
margin: 8px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.widget-inhibitors > button {
|
||||
font-size: initial;
|
||||
color: @text-color;
|
||||
text-shadow: none;
|
||||
background: @noti-bg;
|
||||
border: 1px solid @noti-border-color;
|
||||
box-shadow: none;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.widget-inhibitors > button:hover {
|
||||
background: @noti-bg-hover;
|
||||
}
|
||||
13
.config/systemd/user/aggietimed.service
Normal file
13
.config/systemd/user/aggietimed.service
Normal file
@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=AggieTimeD
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=-/usr/bin/rm /run/user/%U/aggietimed.sock
|
||||
ExecStartPre=/usr/bin/sleep 1
|
||||
ExecStart=/usr/bin/node /usr/bin/aggietimed -d -s /run/user/%U/aggietimed.sock -p echo
|
||||
RestartSec=30
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=sway-session.target
|
||||
9
.config/systemd/user/alacritty.service
Normal file
9
.config/systemd/user/alacritty.service
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Terminal emulator
|
||||
PartOf=sway-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=alacritty
|
||||
Slice=gui.slice
|
||||
|
||||
12
.config/systemd/user/autolock.service
Normal file
12
.config/systemd/user/autolock.service
Normal file
@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description = Lock the screen when the last smart card is removed
|
||||
PartOf = smartcard.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit = yes
|
||||
ExecStart = swaymsg output '*' dpms on
|
||||
ExecStop = sh -c "loginctl lock-session; sleep 1; swaymsg output '*' dpms off"
|
||||
|
||||
[Install]
|
||||
WantedBy = smartcard.target
|
||||
11
.config/systemd/user/dunst.service
Normal file
11
.config/systemd/user/dunst.service
Normal file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=dunst notification daemon
|
||||
PartOf=sway-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=dunst
|
||||
Slice=session.slice
|
||||
|
||||
[Install]
|
||||
WantedBy=sway-session.target
|
||||
20
.config/systemd/user/emacs.service
Normal file
20
.config/systemd/user/emacs.service
Normal file
@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=Emacs text editor
|
||||
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/bin/emacs --daemon
|
||||
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
|
||||
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
|
||||
Environment=ASDF_DATA_DIR=/home/ezri/.local/share/asdf-vm
|
||||
Restart=on-failure
|
||||
Slice=session.slice
|
||||
MemoryAccounting=yes
|
||||
# Tide eats memory like crazy, so lets put it on a diet.
|
||||
MemoryHigh=3G
|
||||
MemoryMax=5G
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
20
.config/systemd/user/eww.service
Normal file
20
.config/systemd/user/eww.service
Normal file
@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=eww status bars
|
||||
PartOf=sway-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=eww daemon --no-daemonize
|
||||
ExecStartPost=eww open-many leftbar rightbar network-status
|
||||
ExecReload=eww reload
|
||||
Slice=session.slice
|
||||
MemoryAccounting=yes
|
||||
# Eww is prone to memory leaks, esp. with (for ...), so
|
||||
# if it ever goes nuts, kill it and restart.
|
||||
MemoryHigh=150M
|
||||
MemoryMax=400M
|
||||
Restart=on-abnormal
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=sway-session.target
|
||||
9
.config/systemd/user/gnome-keyring.service
Normal file
9
.config/systemd/user/gnome-keyring.service
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description = GNOME Keyring
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=gnome-keyring-daemon --daemonize
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
7
.config/systemd/user/hypr-session.target
Normal file
7
.config/systemd/user/hypr-session.target
Normal file
@ -0,0 +1,7 @@
|
||||
[Unit]
|
||||
Description=Hyprland compositor session
|
||||
Documentation=man:systemd.special
|
||||
BindsTo=graphical-session.target
|
||||
Wants=graphical-session-pre.target
|
||||
After=graphical-session-pre.target
|
||||
Wants=sway-session.target
|
||||
9
.config/systemd/user/kdeconnect.service
Normal file
9
.config/systemd/user/kdeconnect.service
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=KDE Connect Daemon
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/lib/kdeconnectd
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
10
.config/systemd/user/lxpolkit.service
Normal file
10
.config/systemd/user/lxpolkit.service
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description = PolicyKit authentication agent
|
||||
BindTo=sway-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/lxpolkit
|
||||
|
||||
[Install]
|
||||
WantedBy=sway-session.target
|
||||
9
.config/systemd/user/mpris-proxy.service
Normal file
9
.config/systemd/user/mpris-proxy.service
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description = Forwarding bluetooth audio controls to MPRIS players
|
||||
|
||||
[Service]
|
||||
Type = simple
|
||||
ExecStart = /usr/bin/mpris-proxy
|
||||
|
||||
[Install]
|
||||
WantedBy = graphical@i3.target
|
||||
10
.config/systemd/user/playerctld.service
Normal file
10
.config/systemd/user/playerctld.service
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Keeping track of media player activity
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/playerctld daemon
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
6
.config/systemd/user/sway-session.target
Normal file
6
.config/systemd/user/sway-session.target
Normal file
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Sway compositor session
|
||||
Documentation=man:systemd.special
|
||||
BindsTo=graphical-session.target
|
||||
Wants=graphical-session-pre.target
|
||||
After=graphical-session-pre.target
|
||||
10
.config/systemd/user/swaybg.service
Normal file
10
.config/systemd/user/swaybg.service
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Background program for wlroots-based compositors
|
||||
BindsTo=hypr-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=swaybg -c "#1e1e1e"
|
||||
|
||||
[Install]
|
||||
WantedBy=hypr-session.target
|
||||
11
.config/systemd/user/swayidle.service
Normal file
11
.config/systemd/user/swayidle.service
Normal file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Sway idle management
|
||||
PartOf=sway-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=swayidle -C %h/.config/sway/swayidle
|
||||
Slice=session.slice
|
||||
|
||||
[Install]
|
||||
WantedBy=sway-session.target
|
||||
14
.config/systemd/user/swaync.service
Normal file
14
.config/systemd/user/swaync.service
Normal file
@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=swaync notification daemon
|
||||
PartOf=sway-session.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=org.freedesktop.Notifications
|
||||
ExecStart=swaync
|
||||
ExecReload=swaync-client -R
|
||||
ExecReload=swaync-client -rs
|
||||
Slice=session.slice
|
||||
|
||||
[Install]
|
||||
WantedBy=sway-session.target
|
||||
11
.config/systemd/user/test.service
Normal file
11
.config/systemd/user/test.service
Normal file
@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=testing a thing
|
||||
After=smartcard.target
|
||||
Conflicts=smartcard.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=echo it worked
|
||||
|
||||
[Install]
|
||||
WantedBy=smartcard.target
|
||||
2
.config/wofi/config
Normal file
2
.config/wofi/config
Normal file
@ -0,0 +1,2 @@
|
||||
dynamic_lines=true
|
||||
layer=overlay
|
||||
31
.config/wofi/style.css
Normal file
31
.config/wofi/style.css
Normal file
@ -0,0 +1,31 @@
|
||||
* {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
#outer-box {
|
||||
background-color: #1e1e1e;
|
||||
border: 1px solid #815986;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#scroll {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#entry {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#entry:selected {
|
||||
background-color: #2d272f;
|
||||
}
|
||||
|
||||
#text {
|
||||
color: #9a7c9d;
|
||||
}
|
||||
|
||||
#input {
|
||||
background-color: #2d272f;
|
||||
color: #9a7c9d;
|
||||
padding: 5px;
|
||||
}
|
||||
47
.config/yadm/bootstrap
Normal file
47
.config/yadm/bootstrap
Normal file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
cd $HOME
|
||||
# Initialize and update submodules
|
||||
yadm submodule update --init --recursive
|
||||
yadm submodule foreach git pull
|
||||
|
||||
# Load OS information from /etc/os-release
|
||||
eval $(awk '{print "OS_" $0}' /etc/os-release)
|
||||
|
||||
function pyenv_install() {
|
||||
if [[ ${OS_ID} == "arch" ]]; then
|
||||
sudo pacman -S --noconfirm pyenv pyenv-virtualenv
|
||||
elif [[ ${OS_ID} == "ubuntu" ]]; then
|
||||
sudo apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
|
||||
libreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev xz-utils \
|
||||
tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
|
||||
curl https://pyenv.run | bash
|
||||
fi
|
||||
|
||||
pyenv install 3.10.13
|
||||
pyenv virtualenv 3.10.13 personal
|
||||
pyenv virtualenv 3.10.13 eww-modules
|
||||
pyenv global personal
|
||||
pyenv rehash
|
||||
eval "$(pyenv init -)"
|
||||
|
||||
# Install packages for personal python environment
|
||||
pyenv shell personal
|
||||
pip install --upgrade pip
|
||||
if [[ -f $HOME/.config/pip/requirements.txt ]]; then
|
||||
pip install -r $HOME/.config/pip/requirements.txt
|
||||
fi
|
||||
|
||||
# Install packages for eww-modules
|
||||
pyenv shell eww-modules
|
||||
pip install --upgrade pip
|
||||
if [[ -f $HOME/.config/pip/eww-modules-requirements.txt ]]; then
|
||||
pip install -r $HOME/.config/pip/eww-modules-requirements.txt
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# Install pyenv and configure personal and eww-modules python environments
|
||||
if [[ ! -d $HOME/.pyenv ]]; then
|
||||
pyenv_install
|
||||
fi
|
||||
1
.config/zsh/.#auth-agent.zsh
Symbolic link
1
.config/zsh/.#auth-agent.zsh
Symbolic link
@ -0,0 +1 @@
|
||||
stephen@Triskelion.703:1598899691
|
||||
125
.config/zsh/alias.zsh
Normal file
125
.config/zsh/alias.zsh
Normal file
@ -0,0 +1,125 @@
|
||||
# Simple shell aliasing
|
||||
|
||||
alias emacs="TERM=screen-256color emacsclient -t"
|
||||
alias sumacs="sudo emacs -nw"
|
||||
|
||||
alias systemctl="sudo systemctl"
|
||||
alias userctl="\systemctl --user"
|
||||
|
||||
alias ujournalctl="\journalctl --user"
|
||||
|
||||
alias reconf="source $HOME/.zshrc"
|
||||
|
||||
alias cp="cp -i --reflink=auto"
|
||||
alias mv="mv -i"
|
||||
alias rm="rm -i"
|
||||
|
||||
alias screenclip="scrot -o >(xclip -sel clip -t image/png)"
|
||||
|
||||
alias virsh="\virsh -c qemu:///system"
|
||||
alias sandbox-virsh="\virsh -c qemu+ssh://sandbox/system"
|
||||
|
||||
alias ls='ls --color=tty'
|
||||
alias ll='ls -lh'
|
||||
alias la='ls -lAh'
|
||||
alias l='ls -lh'
|
||||
|
||||
alias nuke='echo "Are you sure?"; read -q && rm -rf'
|
||||
|
||||
alias sudo='sudo '
|
||||
|
||||
alias sign='gpg --sign-with ezri@ezri.dev --detach-sign'
|
||||
alias verify='gpg --verify'
|
||||
|
||||
function didifuckingstutter {
|
||||
echo $fg[blue]Apologies, Captain. Right away.$fg[default]
|
||||
# Run the last command as root
|
||||
last_cmd=$(fc -ln -1)
|
||||
# if last command was emacs, use TRAMP rather than running as root
|
||||
if [[ $last_cmd =~ "^emacs .*" ]]; then
|
||||
cmd="emacsclient -t /sudo::$(echo $last_cmd | cut -d' ' -f2-)"
|
||||
echo "> $fg[white]$cmd$fg[default]"
|
||||
$=cmd
|
||||
else
|
||||
cmd="sudo $(fc -ln -1)"
|
||||
echo "> $fg[white]$cmd$fg[default]"
|
||||
sudo -p "$fg[red]I'll need your authorization:$fg[default] " $last_cmd
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function pygrep {
|
||||
success=0
|
||||
for pid in $(pgrep python); do
|
||||
if cut -d '' -f2 < /proc/$pid/cmdline | rev | cut -d'/' -f1 | rev | grep "$1.py" &> /dev/null; then
|
||||
echo $pid
|
||||
success=1
|
||||
fi
|
||||
done
|
||||
if ! (( success )); then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function create-discord-timestamp {
|
||||
date --date="$(echo $@)" +'<t:%s:t>' | tee >(tr -d '\n' | cbcopy)
|
||||
}
|
||||
|
||||
function copy-text {
|
||||
echo -n $@ | cbcopy
|
||||
}
|
||||
|
||||
function cbcopy {
|
||||
x_args='-sel clip'
|
||||
if [[ $1 == '--primary' ]] || [[ $1 == '-p' ]]; then
|
||||
wl_args='--primary'
|
||||
x_args=''
|
||||
fi
|
||||
if [[ -x $(command -v wl-copy) ]]; then
|
||||
# Prioritize wayland
|
||||
wl-copy $wl_args
|
||||
return $?
|
||||
fi
|
||||
if [[ -x $(command -v xclip) ]]; then
|
||||
# Next do Xorg
|
||||
xclip $x_args
|
||||
return $?
|
||||
fi
|
||||
if [[ -x $(command -v pbcopy) ]]; then
|
||||
pbcopy
|
||||
return $?
|
||||
fi
|
||||
echo "No known clipboard commands available"
|
||||
return 1
|
||||
}
|
||||
|
||||
function cbpaste {
|
||||
x_args='-sel clip'
|
||||
if [[ $1 == '--primary' ]] || [[ $1 == '-p' ]]; then
|
||||
wl_args='--primary'
|
||||
x_args=''
|
||||
fi
|
||||
if [[ -x $(command -v wl-copy) ]]; then
|
||||
# Prioritize wayland
|
||||
wl-paste $wl_args
|
||||
return $?
|
||||
fi
|
||||
if [[ -x $(command -v xclip) ]]; then
|
||||
# Next do Xorg
|
||||
xclip -o $x_args
|
||||
return $?
|
||||
fi
|
||||
if [[ -x $(command -v pbcopy) ]]; then
|
||||
pbpaste
|
||||
return $?
|
||||
fi
|
||||
echo "No known clipboard commands available" > /dev/stderr
|
||||
return 1
|
||||
}
|
||||
|
||||
alias aggietimed='aggietimed -s /run/user/1000/aggietimed.sock -pos 190910 --action'
|
||||
|
||||
function mkcd {
|
||||
[[ -e $1 ]] || mkdir -p $1
|
||||
cd $1
|
||||
}
|
||||
30
.config/zsh/alias.zsh~
Normal file
30
.config/zsh/alias.zsh~
Normal file
@ -0,0 +1,30 @@
|
||||
# Simple shell aliasing
|
||||
|
||||
alias emacs="TERM=screen-256color emacsclient -t"
|
||||
alias sumacs="sudo emacs -nw"
|
||||
|
||||
alias systemctl="sudo systemctl"
|
||||
alias userctl="\systemctl --user"
|
||||
|
||||
alias reconf="source $HOME/.zshrc"
|
||||
|
||||
alias cp="cp --reflink=auto"
|
||||
|
||||
alias screenclip="scrot -o >(xclip -sel clip -t image/png)"
|
||||
|
||||
alias virsh="\virsh -c qemu:///system"
|
||||
alias sandbox-virsh="\virsh -c qemu+ssh://sandbox/system"
|
||||
|
||||
alias ssh="env TERM=xterm-256color \ssh"
|
||||
|
||||
alias ls='ls --color=tty'
|
||||
alias ll='ls -lh'
|
||||
alias la='ls -lAh'
|
||||
alias l='ls -lh'
|
||||
|
||||
alias sudo='sudo '
|
||||
|
||||
function take {
|
||||
[[ -e $1 ]] || mkdir -p $1
|
||||
cd $1
|
||||
}
|
||||
2
.config/zsh/dir-hash.zsh
Normal file
2
.config/zsh/dir-hash.zsh
Normal file
@ -0,0 +1,2 @@
|
||||
hash -d cpp=$HOME/Documents/School/FA22/CS3460
|
||||
hash -d hpc=$HOME/Documents/School/FA22/CS5030
|
||||
2
.config/zsh/directories.zsh
Normal file
2
.config/zsh/directories.zsh
Normal file
@ -0,0 +1,2 @@
|
||||
hash -d webdev=$HOME/Documents/School/SP22/CS4610
|
||||
hash -d gamedev=$HOME/Documents/School/SP22/CS5410
|
||||
43
.config/zsh/env.zsh
Normal file
43
.config/zsh/env.zsh
Normal file
@ -0,0 +1,43 @@
|
||||
export ASDF_DATA_DIR=$HOME/.local/share/asdf-vm
|
||||
|
||||
PATH_pyenv=$HOME/.pyenv/bin:$HOME/.pyenv/shims:/opt/pyenv/pyenv-virtualenv/shims
|
||||
PATH_asdf=$ASDF_DATA_DIR/shims:/opt/asdf-vm/bin
|
||||
PATH_node=$HOME/.opt/npm/bin
|
||||
PATH_java=/usr/lib/jvm/default/bin
|
||||
PATH_perl=/usr/bin/vendor_perl:/usr/bin/core_perl
|
||||
PATH_system=/usr/local/sbin:/usr/local/bin:/usr/bin
|
||||
PATH_system_nonarch=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
PATH_user=$HOME/.local/bin
|
||||
PATH_wincmake=/opt/msvcmake/bin:/opt/msvc/bin/x64
|
||||
|
||||
cdpath=(~ ~/src)
|
||||
|
||||
export PATH=.:$PATH_asdf:$PATH_node:$PATH_pyenv:$PATH_java:$PATH_user:$PATH_system
|
||||
|
||||
# Function to run a command with only the "safe" system PATH element
|
||||
function safeexec {
|
||||
env PATH=$PATH_system "$@"
|
||||
}
|
||||
|
||||
# Set an alias with a trailing space so that we can run other aliases
|
||||
# using this function
|
||||
alias safeexec="safeexec "
|
||||
|
||||
# Function to run a command with only the user PATH element, forcing
|
||||
# the use of user-installed binaries
|
||||
function userexec {
|
||||
env PATH=$PATH_user "$@"
|
||||
}
|
||||
|
||||
export LS_COLORS='di=34;40:ln=1;35;1:so=1;33;1:pi=32;1;40:ex=1;32;1:bd=33;1;40:cd=1;33;1;40:su=1;31;1:sg=1;31;1;40:tw=1;35;1;40:ow=1;31;1;40'
|
||||
|
||||
export GPG_TTY=$(tty)
|
||||
gpg-connect-agent updatestartuptty /bye &> /dev/null
|
||||
export EDITOR="emacsclient -t"
|
||||
|
||||
SAVEHIST=10000
|
||||
HISTSIZE=$SAVEHIST
|
||||
HISTFILE="${HOME}/.zsh_history"
|
||||
|
||||
export PAGER=less
|
||||
export SUDO_PROMPT="$fg[red]Authorization required: $fg[default]"
|
||||
14
.config/zsh/env.zsh~
Normal file
14
.config/zsh/env.zsh~
Normal file
@ -0,0 +1,14 @@
|
||||
export PATH=/usr/local/bin:/usr/bin
|
||||
|
||||
enabled_snaps=('discord' 'apple-music-for-linux')
|
||||
|
||||
for snap in $enabled_snaps; do
|
||||
export PATH=/snap/$snap/current/usr/bin:$PATH
|
||||
done
|
||||
|
||||
export PATH=.:$HOME/.local/bin:$PATH
|
||||
|
||||
export GPG_TTY=$(tty)
|
||||
gpg-connect-agent updatestartuptty /bye &> /dev/null
|
||||
|
||||
export EDITOR="emacsclient -t"
|
||||
24
.config/zsh/line-editing.zsh
Normal file
24
.config/zsh/line-editing.zsh
Normal file
@ -0,0 +1,24 @@
|
||||
WORDCHARS='*?$'
|
||||
|
||||
# The following lines were added by compinstall
|
||||
|
||||
zstyle ':completion:*' completer _expand _complete _ignored _correct
|
||||
zstyle ':completion:*' file-sort name
|
||||
zstyle ':completion:*' format '--- Completing %d ---'
|
||||
zstyle ':completion:*' group-name ''
|
||||
zstyle ':completion:*' ignore-parents parent pwd
|
||||
zstyle ':completion:*' insert-unambiguous false
|
||||
zstyle ':completion:*' list-colors ''
|
||||
zstyle ':completion:*' list-suffixes true
|
||||
zstyle ':completion:*' matcher-list '' 'm:{[:lower:]}={[:upper:]}' 'r:|[._-]=** r:|=**' 'l:|=* r:|=*'
|
||||
zstyle ':completion:*' menu select=1
|
||||
zstyle ':completion:*' original false
|
||||
zstyle ':completion:*' preserve-prefix '//[^/]##/'
|
||||
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
|
||||
zstyle ':completion:*' squeeze-slashes true
|
||||
zstyle ':completion:*' use-compctl true
|
||||
zstyle :compinstall filename "${HOME}/.config/zsh/compinstall.zsh"
|
||||
|
||||
autoload -Uz compaudit compinit
|
||||
compinit
|
||||
# End of lines added by compinstall
|
||||
11
.config/zsh/options.zsh
Normal file
11
.config/zsh/options.zsh
Normal file
@ -0,0 +1,11 @@
|
||||
# CD to directory when you type it, without having to type cd
|
||||
setopt auto_cd
|
||||
# Use directory stack
|
||||
setopt auto_pushd
|
||||
# Always resolve symlinks when changing directory
|
||||
setopt chase_links
|
||||
|
||||
# Ignore duplicate commands and commands starting with space
|
||||
setopt hist_ignore_dups
|
||||
setopt hist_ignore_space
|
||||
|
||||
152
.config/zsh/prompt.zsh##distro.Arch
Normal file
152
.config/zsh/prompt.zsh##distro.Arch
Normal file
@ -0,0 +1,152 @@
|
||||
autoload -Uz vcs_info
|
||||
|
||||
pwd="%B%F{blue}%3~%f%b"
|
||||
|
||||
# Show active python virtualenv in prompt
|
||||
precmd_pyenv_info() {
|
||||
# use nerd fonts for icons
|
||||
_pyenv_icon=""
|
||||
# Only update if we've changed directory, since pyenv can be slow
|
||||
if [[ "$PWD" == "$_pyenv_old_pwd" ]]; then
|
||||
return
|
||||
else
|
||||
_pyenv_old_pwd="$PWD"
|
||||
fi
|
||||
_pyenv_version=$(pyenv version-name 2>/dev/null)
|
||||
if [[ $? -eq 0 ]] && [[ ${_pyenv_version} != "system" ]] && [[ ${_pyenv_version} != "personal" ]]; then
|
||||
pyenv_info_msg_0_="%F{yellow} ${_pyenv_icon} ${_pyenv_version}%f"
|
||||
elif [[ ${_pyenv_version} == "system" ]]; then
|
||||
pyenv_info_msg_0_="%F{red} ${_pyenv_icon} ${_pyenv_version}%f"
|
||||
else
|
||||
pyenv_info_msg_0_=""
|
||||
fi
|
||||
}
|
||||
|
||||
_kernel_pkg=$(pacman -Qqo /usr/lib/modules/$(uname -r)/vmlinuz 2>/dev/null)
|
||||
|
||||
precmd_kernel_info() {
|
||||
# check to see if a kernel update has been installed
|
||||
# since we need to reboot to use it
|
||||
|
||||
# if message has been set, don't check again, since a reboot
|
||||
# is required to clear the message
|
||||
if [[ -n ${kernel_info_msg_0_} ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ -z ${_kernel_pkg} ]]; then
|
||||
# no kernel package found, so we can't check for updates
|
||||
return
|
||||
fi
|
||||
case ${_kernel_pkg} in
|
||||
"linux")
|
||||
# mainline kernel
|
||||
diff <(uname -r | sed 's/-/./;s/\.0\././') <(pacman -Q linux | cut -d' ' -f2) >/dev/null
|
||||
_ret=$?
|
||||
;;
|
||||
"linux-lts")
|
||||
# lts kernel
|
||||
diff <(uname -r | sed 's/-lts//') <(pacman -Q linux-lts | cut -d' ' -f2) >/dev/null
|
||||
_ret=$?
|
||||
;;
|
||||
esac
|
||||
diff <(uname -r | sed 's/-/./;s/\.0\././') <(pacman -Q linux | cut -d' ' -f2) >/dev/null
|
||||
if [[ $? -eq 1 ]]; then
|
||||
# kernel update available
|
||||
kernel_info_msg_0_="%F{red} reboot required %f"
|
||||
fi
|
||||
}
|
||||
|
||||
precmd_vcs_info() {
|
||||
vcs_info
|
||||
}
|
||||
# Reset precmd_functions, then add our functions. This way, regardless of
|
||||
# whether this file is sourced multiple times, we don't end up with duplicate
|
||||
# entries which will slow down the prompt.
|
||||
precmd_functions=()
|
||||
precmd_functions+=(precmd_vcs_info precmd_pyenv_info _reset_window_name)
|
||||
setopt prompt_subst
|
||||
|
||||
eval $(awk '{print "OS_" $0}' /etc/os-release)
|
||||
eval $(awk '{print "MACHINE_" $0}' /etc/machine-info)
|
||||
eval $(awk '{print "PERSONAL_" $0}' ${HOME}/.personal-info 2>/dev/null)
|
||||
|
||||
if [[ -z ${MACHINE_CHASSIS} ]]; then MACHINE_CHASSIS=$(hostnamectl chassis); fi
|
||||
|
||||
if [[ ${MACHINE_CHASSIS} != "container" ]]; then
|
||||
# Only check if a reboot is necessary if we're not in a container
|
||||
precmd_functions+=(precmd_kernel_info)
|
||||
fi
|
||||
|
||||
hostname=$PERSONAL_HOSTNAME
|
||||
if [[ -z ${hostname} ]]; then # No personal hostname set
|
||||
if [[ -n ${MACHINE_PRETTY_HOSTNAME} ]]; then
|
||||
# Use MACHINE_PRETTY_HOSTNAME if set
|
||||
hostname=${MACHINE_PRETTY_HOSTNAME}
|
||||
elif [[ -f /etc/hostname ]]; then
|
||||
# Fall back to system hostname
|
||||
hostname=$(</etc/hostname)
|
||||
else
|
||||
# Ask the kernel for the hostname
|
||||
hostname=$(uname -n)
|
||||
fi
|
||||
fi
|
||||
|
||||
show_os_icon=1
|
||||
# use nerd fonts for icons
|
||||
case $OS_ID in
|
||||
"arch")
|
||||
show_os_icon=0 # Arch is my default, no need to show icon
|
||||
;;
|
||||
"debian")
|
||||
os_icon=""
|
||||
;;
|
||||
"ubuntu")
|
||||
os_icon=""
|
||||
;;
|
||||
*)
|
||||
show_os_icon=0
|
||||
;;
|
||||
esac
|
||||
prompt="▶"
|
||||
host="%F{cyan}[ %F{green}${hostname}%(!.%F{red} as root.) %F{cyan}]%f"
|
||||
localhost="%F{cyan}[ %F{magenta}%B${hostname}%(!.%F{red} as root.)%b %F{cyan}]%f"
|
||||
serial_host="%F{cyan}[ %F{magenta}${hostname}%(!.%F{red} as root.) %F{cyan}] %F{red}%y%f"
|
||||
container_host="%F{cyan}[ %F{blue}%B${hostname}%(!.%F{red} as root.)%b %F{cyan}]%f"
|
||||
returncode="%(?..%F{red} %?%f)"
|
||||
|
||||
prompt_line1='$kernel_info_msg_0_'
|
||||
prompt_line3=$prompt
|
||||
|
||||
# Create conditional prompt line 2
|
||||
if [[ -v SSH_CLIENT ]]; then
|
||||
prompt_line2='${host}$pyenv_info_msg_0_ ${pwd}'
|
||||
elif [[ ${TTY} =~ "tty" ]]; then
|
||||
prompt_line2='${serial_host}$pyenv_info_msg_0_ ${pwd}'
|
||||
elif [[ ${MACHINE_CHASSIS} == "container" ]]; then
|
||||
prompt_line2='${container_host}$pyenv_info_msg_0_ ${pwd}'
|
||||
else
|
||||
prompt_line2='${localhost}$pyenv_info_msg_0_ ${pwd}'
|
||||
fi
|
||||
|
||||
# Inject icon if available, with ANSI color code stored in $OS_ANSI_COLOR
|
||||
if [[ ${show_os_icon} -eq 1 ]]; then
|
||||
prompt_line2=$'%{\x1b[${OS_ANSI_COLOR}m${os_icon}\x1b[0m%}'" ${prompt_line2}"
|
||||
fi
|
||||
|
||||
if [[ ${TERM} == "dumb" ]]; then
|
||||
# Dumb terminal needs a dumb prompt, otherwise things like
|
||||
# emacs TRAMP break
|
||||
PROMPT='$ '
|
||||
else
|
||||
PROMPT="${prompt_line1}
|
||||
${prompt_line2}
|
||||
${prompt_line3} "
|
||||
fi
|
||||
|
||||
RPROMPT='$vcs_info_msg_0_$returncode'
|
||||
|
||||
zstyle ':vcs_info:git:*' formats '%c %F{magenta} %B%r%%b %F{cyan} %b%f'
|
||||
zstyle ':vcs_info:git:*' actionformats '%c%F{magenta} %B%r%%b %F{cyan} %b %F{red} %a%f'
|
||||
zstyle ':vcs_info:git:*' stagedstr "%F{green}%f"
|
||||
zstyle ':vcs_info:git:*' check-for-staged-changes true
|
||||
zstyle ':vcs_info:*' enable git
|
||||
6
.config/zsh/pyenv.zsh
Normal file
6
.config/zsh/pyenv.zsh
Normal file
@ -0,0 +1,6 @@
|
||||
export PYENV_ROOT="$HOME/.pyenv"
|
||||
# Remove pyenv alias for shell reloads
|
||||
unalias pyenv > /dev/null 2>&1
|
||||
eval "$(pyenv init -)"
|
||||
alias pyenv="unset _pyenv_old_pwd; pyenv"
|
||||
|
||||
43
.config/zsh/ros.zsh
Normal file
43
.config/zsh/ros.zsh
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# ROS stuff for ZSH
|
||||
#
|
||||
|
||||
function ros-version {
|
||||
if [[ $1 == '' ]]; then
|
||||
if [[ $ROS_DISTRO == '' ]]; then
|
||||
echo 'Error: no ROS distribution active' >&2
|
||||
return 1
|
||||
else
|
||||
echo ROS Distribution: $ROS_DISTRO
|
||||
echo ROS Version: $ROS_VERSION
|
||||
fi
|
||||
|
||||
else
|
||||
source /opt/ros/$1/setup.zsh
|
||||
fi
|
||||
}
|
||||
|
||||
function ros-load-workspace {
|
||||
if [[ $1 == '' ]]; then
|
||||
echo 'Error: No workspace directory given' >&2
|
||||
return 1
|
||||
elif [[ ! -d $1 ]]; then
|
||||
echo 'Error: workspace directory does not exist' >&2
|
||||
return 2
|
||||
elif [[ $ROS_VERSION != '2' ]] && ([[ ! -d $1/devel ]] || [[ ! -f $1/devel/setup.zsh ]]); then
|
||||
echo 'Error: directory is not a ROS workspace' >&2
|
||||
return 3
|
||||
elif [[ $ROS_VERSION == '2' ]] && ([[ ! -d $1/install ]] || [[ ! -f $1/install/local_setup.zsh ]]); then
|
||||
echo 'Error: directory is not a ROS workspace' >&2
|
||||
return 3
|
||||
else
|
||||
if [[ $ROS_VERSION == '2' ]]; then
|
||||
source $1/install/local_setup.zsh
|
||||
else
|
||||
source $1/devel/setup.zsh
|
||||
fi
|
||||
ROS_WORKSPACES=$ROS_WORKSPACES:$(readlink -f $1)
|
||||
fi
|
||||
}
|
||||
|
||||
export ROS_DOMAIN_ID=37
|
||||
36
.config/zsh/utils.zsh
Normal file
36
.config/zsh/utils.zsh
Normal file
@ -0,0 +1,36 @@
|
||||
# Utility functions
|
||||
|
||||
function copylastcmd() {
|
||||
echo -n $(fc -ln -1) | wl-copy
|
||||
}
|
||||
|
||||
function getkernelpkg() {
|
||||
if [[ ${OS_ID} == "arch" ]]; then
|
||||
pacman -Qqo /usr/lib/modules/$(uname -r)/vmlinuz
|
||||
else
|
||||
echo "Unsupported OS" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $(hostnamectl chassis) == "container" ]]; then
|
||||
DEFAULT_WINDOW_NAME="Container Connection: [ $hostname Console ]"
|
||||
elif [[ -z "${SSH_CONNECTION+x}" ]]; then
|
||||
DEFAULT_WINDOW_NAME=" $hostname Console"
|
||||
else
|
||||
DEFAULT_WINDOW_NAME="Remote Connection: [ $hostname Console ]"
|
||||
fi
|
||||
|
||||
function _rename_window() {
|
||||
echo -ne "\033]0;$@\007"
|
||||
}
|
||||
|
||||
function _reset_window_name() {
|
||||
_rename_window "$DEFAULT_WINDOW_NAME"
|
||||
}
|
||||
|
||||
function rename_window() {
|
||||
_rename_window "$@"
|
||||
DEFAULT_WINDOW_NAME="$@"
|
||||
}
|
||||
|
||||
_rename_window "$DEFAULT_WINDOW_NAME"
|
||||
2
.config/zsh/zz-asdf.zsh
Normal file
2
.config/zsh/zz-asdf.zsh
Normal file
@ -0,0 +1,2 @@
|
||||
# source $HOME/.local/lib/asdf/asdf.sh
|
||||
# source $HOME/.local/lib/asdf/completions/asdf.bash
|
||||
8
.config/zsh/zz-plugins.zsh
Normal file
8
.config/zsh/zz-plugins.zsh
Normal file
@ -0,0 +1,8 @@
|
||||
# This file activates certain plugins which are not a part of oh-my-zsh
|
||||
|
||||
source $HOME/.local/lib/zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
|
||||
source $HOME/.local/lib/zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||||
source $HOME/.local/lib/zsh/zsh-history-substring-search/zsh-history-substring-search.zsh
|
||||
|
||||
bindkey '^P' history-substring-search-up
|
||||
bindkey '^N' history-substring-search-down
|
||||
23
.config/zsh/zz-ssh.zsh
Normal file
23
.config/zsh/zz-ssh.zsh
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
if [[ $SSH_CLIENT != "" ]]; then
|
||||
|
||||
mkfifo "/tmp/ssh_test.$$"
|
||||
exec 3<> "/tmp/ssh_test.$$"
|
||||
unlink "/tmp/ssh_test.$$"
|
||||
|
||||
ps -o ppid= -p $$ | sed 's/ //g' 1>&3
|
||||
|
||||
read -u3 ppid
|
||||
|
||||
if ls /tmp | grep ssh- 1> /dev/null 2>&1; then
|
||||
for dir in /tmp/ssh-*; do
|
||||
if [[ -e $dir/agent.$ppid ]]; then
|
||||
export SSH_AUTH_SOCK=$dir/agent.$ppid
|
||||
fi
|
||||
done
|
||||
fi
|
||||
else
|
||||
|
||||
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
|
||||
|
||||
fi
|
||||
198
.emacs.d/doom-personal-theme.el
Normal file
198
.emacs.d/doom-personal-theme.el
Normal file
@ -0,0 +1,198 @@
|
||||
;;; doom-nord-theme.el --- dark variant of Nord -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;
|
||||
;; Added: March 8, 2018 (c503ebdacac1)
|
||||
;; Author: fuxialexander <https://github.com/fuxialexander>
|
||||
;; Maintainer:
|
||||
;; Source: https://www.nordtheme.com
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'doom-themes)
|
||||
|
||||
|
||||
;;
|
||||
;;; Variables
|
||||
|
||||
(defgroup doom-personal-theme nil
|
||||
"Options for the `doom-personal' theme."
|
||||
:group 'doom-themes)
|
||||
|
||||
(defcustom doom-nord-brighter-modeline nil
|
||||
"If non-nil, more vivid colors will be used to style the mode-line."
|
||||
:group 'doom-nord-theme
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom doom-nord-brighter-comments nil
|
||||
"If non-nil, comments will be highlighted in more vivid colors."
|
||||
:group 'doom-nord-theme
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom doom-nord-comment-bg doom-nord-brighter-comments
|
||||
"If non-nil, comments will have a subtle, darker background. Enhancing their
|
||||
legibility."
|
||||
:group 'doom-nord-theme
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom doom-nord-padded-modeline doom-themes-padded-modeline
|
||||
"If non-nil, adds a 4px padding to the mode-line. Can be an integer to
|
||||
determine the exact padding."
|
||||
:group 'doom-nord-theme
|
||||
:type '(choice integer boolean))
|
||||
|
||||
(eval-and-compile
|
||||
(defcustom doom-nord-region-highlight t
|
||||
"Determines the selection highlight style. Can be 'frost, 'snowstorm or t
|
||||
(default)."
|
||||
:group 'doom-nord-theme
|
||||
:type 'symbol))
|
||||
|
||||
|
||||
;;
|
||||
;;; Theme definition
|
||||
|
||||
(def-doom-theme doom-personal
|
||||
"A dark theme I made myself."
|
||||
|
||||
;; name default 256 16
|
||||
((bg '("#1e1e1e" nil nil ))
|
||||
(bg-alt '("#2d272f" nil nil ))
|
||||
(base0 '("#2d272f" "black" "black" ))
|
||||
(base1 '("#2d272f" "#1e1e1e" "brightblack" ))
|
||||
(base2 '("#2d272f" "#2e2e2e" "brightblack" ))
|
||||
(base3 '("#2d272f" "#262626" "brightblack" ))
|
||||
(base4 '("#3f3242" "#3f3f3f" "brightblack" ))
|
||||
(base5 '("#3f3242" "#525252" "brightblack" ))
|
||||
(base6 '("#4C566A" "#6b6b6b" "brightblack" ))
|
||||
(base7 '("#a7a7a7" "#979797" "brightblack" ))
|
||||
(base8 '("#a7a7a7" "#dfdfdf" "white" ))
|
||||
(fg '("#a7a7a7" "#ECECEC" "white" ))
|
||||
(fg-alt '("#ffffff" "#bfbfbf" "brightwhite" ))
|
||||
|
||||
(grey base4)
|
||||
(red '("#cf6a4c" "#ff6655" "red" )) ;; Nord11
|
||||
(orange '("#cf6a4c" "#dd8844" "brightred" )) ;; Nord12
|
||||
(green '("#8f9d6a" "#99bb66" "green" )) ;; Nord14
|
||||
(teal '("#8f9d6a" "#44b9b1" "brightgreen" )) ;; Nord7
|
||||
(yellow '("#f9ee98" "#ECBE7B" "yellow" )) ;; Nord13
|
||||
(blue '("#7587a6" "#51afef" "brightblue" )) ;; Nord9
|
||||
(dark-blue '("#7587a6" "#2257A0" "blue" )) ;; Nord10
|
||||
(magenta '("#9b859d" "#c678dd" "magenta" )) ;; Nord15
|
||||
(violet '("#9b859d" "#a9a1e1" "brightmagenta")) ;; ??
|
||||
(cyan '("#afc4db" "#46D9FF" "brightcyan" )) ;; Nord8
|
||||
(dark-cyan '("#afc4db" "#5699AF" "cyan" )) ;; ??
|
||||
|
||||
;; face categories -- required for all themes
|
||||
(highlight blue)
|
||||
(vertical-bar (doom-darken base1 0.2))
|
||||
(selection dark-blue)
|
||||
(builtin blue)
|
||||
(comments (if doom-nord-brighter-comments dark-cyan (doom-lighten base5 0.2)))
|
||||
(doc-comments (doom-lighten (if doom-nord-brighter-comments dark-cyan base5) 0.25))
|
||||
(constants blue)
|
||||
(functions cyan)
|
||||
(keywords blue)
|
||||
(methods cyan)
|
||||
(operators blue)
|
||||
(type teal)
|
||||
(strings green)
|
||||
(variables base7)
|
||||
(numbers magenta)
|
||||
(region (pcase doom-nord-region-highlight
|
||||
(`frost teal)
|
||||
(`snowstorm base7)
|
||||
(_ base4)))
|
||||
(error red)
|
||||
(warning yellow)
|
||||
(success green)
|
||||
(vc-modified orange)
|
||||
(vc-added green)
|
||||
(vc-deleted red)
|
||||
|
||||
;; custom categories
|
||||
(hidden `(,(car bg) "black" "black"))
|
||||
(-modeline-bright doom-nord-brighter-modeline)
|
||||
(-modeline-pad
|
||||
(when doom-nord-padded-modeline
|
||||
(if (integerp doom-nord-padded-modeline) doom-nord-padded-modeline 4)))
|
||||
|
||||
(region-fg
|
||||
(when (memq doom-nord-region-highlight '(frost snowstorm))
|
||||
base0))
|
||||
|
||||
(modeline-fg nil)
|
||||
(modeline-fg-alt base6)
|
||||
|
||||
(modeline-bg
|
||||
(if -modeline-bright
|
||||
(doom-blend bg base5 0.2)
|
||||
`(,(doom-darken (car bg) 0.1) ,@(cdr base2))))
|
||||
(modeline-bg-l
|
||||
(if -modeline-bright
|
||||
(doom-blend bg base5 0.2)
|
||||
base1))
|
||||
(modeline-bg-inactive `(,(doom-darken (car bg) 0.1) ,@(cdr base2)))
|
||||
(modeline-bg-inactive-l `(,(doom-darken (car bg) 0.025) ,@(cdr base2))))
|
||||
|
||||
|
||||
;;;; Base theme face overrides
|
||||
((fringe :foreground teal)
|
||||
((line-number &override) :foreground (doom-lighten 'base5 0.2))
|
||||
((line-number-current-line &override) :foreground base7)
|
||||
((font-lock-comment-face &override)
|
||||
:background (if doom-nord-comment-bg (doom-lighten bg 0.05)))
|
||||
((tab-line &override) :background modeline-bg :foreground magenta)
|
||||
((tab-line-tab-inactive &override) :foreground magenta)
|
||||
(mode-line
|
||||
:background modeline-bg :foreground modeline-fg
|
||||
:box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
|
||||
(mode-line-inactive
|
||||
:background modeline-bg-inactive :foreground modeline-fg-alt
|
||||
:box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
|
||||
(mode-line-emphasis :foreground (if -modeline-bright base8 highlight))
|
||||
((region &override) :foreground region-fg)
|
||||
|
||||
;;;; css-mode <built-in> / scss-mode
|
||||
(css-proprietary-property :foreground orange)
|
||||
(css-property :foreground green)
|
||||
(css-selector :foreground magenta)
|
||||
;;;; doom-modeline
|
||||
(doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
|
||||
(doom-modeline-project-root-dir :foreground base6)
|
||||
;;;; ediff <built-in>
|
||||
(ediff-fine-diff-A :background (doom-darken violet 0.4) :weight 'bold)
|
||||
(ediff-current-diff-A :background (doom-darken base0 0.25))
|
||||
;;;; elscreen
|
||||
(elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
|
||||
;;;; highlight-symbol
|
||||
(highlight-symbol-face :background (doom-lighten base4 0.1) :distant-foreground fg-alt)
|
||||
;;;; highlight-thing
|
||||
(highlight-thing :background (doom-lighten base4 0.1) :distant-foreground fg-alt)
|
||||
;;;; ivy
|
||||
((ivy-current-match &override) :foreground region-fg :weight 'semi-bold)
|
||||
;;;; markdown-mode
|
||||
(markdown-markup-face :foreground base5)
|
||||
(markdown-header-face :inherit 'bold :foreground red)
|
||||
((markdown-code-face &override) :background (doom-lighten base3 0.05))
|
||||
;;;; mic-paren
|
||||
((paren-face-match &override) :foreground bg :background teal :weight 'ultra-bold)
|
||||
((paren-face-mismatch &override) :foreground base7 :background red :weight 'ultra-bold)
|
||||
;;;; org <built-in>
|
||||
(org-hide :foreground hidden)
|
||||
;;;; solaire-mode
|
||||
(solaire-mode-line-face
|
||||
:inherit 'mode-line
|
||||
:background modeline-bg-l
|
||||
:box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
|
||||
(solaire-mode-line-inactive-face
|
||||
:inherit 'mode-line-inactive
|
||||
:background modeline-bg-inactive-l
|
||||
:box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
|
||||
;;;; vimish-fold
|
||||
((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light)
|
||||
((vimish-fold-fringe &override) :foreground teal))
|
||||
|
||||
;;;; Base theme variable overrides-
|
||||
())
|
||||
|
||||
;;; doom-nord-theme.el ends here
|
||||
546
.emacs.d/settings.org
Normal file
546
.emacs.d/settings.org
Normal file
@ -0,0 +1,546 @@
|
||||
#+TITLE: Ezri's Settings
|
||||
#+AUTHOR: Ezri & Simponic
|
||||
#+STARTUP: fold
|
||||
|
||||
Shamelessly stole this from Simponic, made some limited modifications myself.
|
||||
Namely to indent style, theme, and line numbers. Also added Github Copilot.
|
||||
|
||||
* Packages
|
||||
** Melpa
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(require 'package)
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "https://melpa.org/packages/") t)
|
||||
#+END_SRC
|
||||
* General emacs
|
||||
** Tab bar mode
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun my-tabbar-buffer-groups () ;; customize to show all normal files in one group
|
||||
(list (cond ((string-equal "*" (substring (buffer-name) 0 1)) "emacs")
|
||||
((eq major-mode 'dired-mode) "emacs")
|
||||
(t "user"))))
|
||||
(setq tabbar-buffer-groups-function 'my-tabbar-buffer-groups)
|
||||
(tab-bar-mode)
|
||||
#+END_SRC
|
||||
** Indentation
|
||||
Indent using tabs, render with tab-width of 2.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq default-tab-width 2)
|
||||
(setq-default tab-width 2)
|
||||
(setq-default indent-tabs-mode t)
|
||||
(setq sh-indentation 2)
|
||||
(smart-tabs-insinuate 'c 'c++ 'java 'javascript 'python)
|
||||
|
||||
|
||||
#+END_SRC
|
||||
** Line numbers
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(global-display-line-numbers-mode)
|
||||
#+END_SRC
|
||||
** Filesystem stuff
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq auto-save-default nil)
|
||||
(setq make-backup-files nil)
|
||||
(setq create-lockfiles nil)
|
||||
(global-auto-revert-mode t) ;; Change files on disk as they are updated
|
||||
#+END_SRC
|
||||
** UI stuff
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; (when (window-system)
|
||||
;; (menu-bar-mode -1)
|
||||
;; (tool-bar-mode -1)
|
||||
;; (toggle-scroll-bar -1)
|
||||
;; (if (display-graphic-p)
|
||||
;; (funcall (lambda ()
|
||||
;; (set-fringe-mode '(1 . 1))
|
||||
;; )))
|
||||
;; (setq frame-resize-pixelwise t))
|
||||
|
||||
(setq inhibit-startup-screen t)
|
||||
|
||||
(defun my-frame-config (&optional frame)
|
||||
(setq frame-resize-pixelwise t)
|
||||
(if (display-graphic-p)
|
||||
(set-fringe-mode '(1 . 1)))
|
||||
(if (not frame) ;; The initial call, run when emacs starts
|
||||
(funcall (lambda ()
|
||||
(menu-bar-mode -1)
|
||||
(tool-bar-mode -1)
|
||||
(toggle-scroll-bar -1)
|
||||
)))
|
||||
;;-----------------------------------------;;
|
||||
;; reinitialize modes in case of new frame ;;
|
||||
;;-----------------------------------------;;
|
||||
(if menu-bar-mode
|
||||
(menu-bar-mode -1))
|
||||
(if tool-bar-mode
|
||||
(tool-bar-mode -1))
|
||||
(if scroll-bar-mode
|
||||
(scroll-bar-mode -1)))
|
||||
|
||||
(my-frame-config) ;; Run initially so that direct invocations work
|
||||
(add-hook 'after-make-frame-functions 'my-frame-config)
|
||||
#+END_SRC
|
||||
** TUI stuff
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun terminal-config (&optional frame)
|
||||
"Establish settings for teh current terminal."
|
||||
(if (not frame) ;; The initial call.
|
||||
(xterm-mouse-mode 1)
|
||||
(if xterm-mouse-mode
|
||||
;; Re-initialize the mode in case of a new terminal.
|
||||
(xterm-mouse-mode 1))))
|
||||
|
||||
(terminal-config)
|
||||
(add-hook 'after-make-frame-functions 'terminal-config)
|
||||
#+END_SRC
|
||||
** Custom keymap
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(global-set-key (kbd "C-;") 'comment-or-uncomment-region)
|
||||
#+END_SRC
|
||||
** System path (macos)
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; Use system path on macos - needed for node
|
||||
(use-package exec-path-from-shell
|
||||
:ensure t
|
||||
:init
|
||||
(when (memq window-system '(mac ns x))
|
||||
(exec-path-from-shell-initialize)))
|
||||
#+END_SRC
|
||||
|
||||
* Theming
|
||||
** Highlight current line
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(global-hl-line-mode)
|
||||
#+END_SRC
|
||||
** Font
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'default-frame-alist '(font . "JetBrains Mono-9"))
|
||||
#+END_SRC
|
||||
** Doom-themes
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun my-theme-config (&optional frame)
|
||||
(use-package doom-themes
|
||||
:ensure t
|
||||
:config
|
||||
;; Global settings (defaults)
|
||||
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
|
||||
doom-themes-enable-italic t) ; if nil, italics is universally disabled
|
||||
(load-theme 'doom-personal t)
|
||||
|
||||
;; Enable flashing mode-line on errors
|
||||
(doom-themes-visual-bell-config)
|
||||
;; Enable custom neotree theme (all-the-icons must be installed!)
|
||||
(doom-themes-neotree-config)
|
||||
;; or for treemacs users
|
||||
(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
|
||||
(doom-themes-treemacs-config)
|
||||
;; Corrects (and improves) org-mode's native fontification.
|
||||
(doom-themes-org-config)))
|
||||
(my-theme-config)
|
||||
(add-hook 'after-make-frame-functions 'my-theme-config)
|
||||
#+END_SRC
|
||||
** Doom-modeline
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun my-modeline-config (&optional frame)
|
||||
(use-package doom-modeline
|
||||
:ensure t
|
||||
:init (doom-modeline-mode 1)))
|
||||
(my-modeline-config)
|
||||
(add-hook 'after-make-frame-functions 'my-modeline-config)
|
||||
#+END_SRC
|
||||
** All the icons
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package all-the-icons
|
||||
:ensure t)
|
||||
#+END_SRC
|
||||
|
||||
* Projectile
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package projectile
|
||||
:bind ("C-c p" . 'projectile-command-map)
|
||||
:init (projectile-mode +1) (setq projectile-enable-caching t)
|
||||
:ensure t)
|
||||
#+END_SRC
|
||||
|
||||
* Swiper, Ivy
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package counsel
|
||||
:ensure t
|
||||
:bind
|
||||
("C-s" . 'swiper-isearch)
|
||||
("M-x" . 'counsel-M-x)
|
||||
:init
|
||||
(setq ivy-use-virtual-buffers t)
|
||||
(setq enable-recursive-minibuffers t)
|
||||
(ivy-mode 1))
|
||||
#+END_SRC
|
||||
|
||||
* Neotree
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package neotree
|
||||
:ensure t
|
||||
:bind ("C-c j" . 'neotree-toggle)
|
||||
:init
|
||||
;; slow rendering
|
||||
(setq inhibit-compacting-font-caches t)
|
||||
|
||||
;; set icons theme
|
||||
(setq neo-theme (if (display-graphic-p) 'icons 'arrow))
|
||||
|
||||
;; Every time when the neotree window is opened, let it find current file and jump to node
|
||||
(setq neo-smart-open t)
|
||||
|
||||
;; When running ‘projectile-switch-project’ (C-c p p), ‘neotree’ will change root automatically
|
||||
(setq projectile-switch-project-action 'neotree-projectile-action)
|
||||
|
||||
(setq neo-window-width 35)
|
||||
|
||||
;; show hidden files
|
||||
(setq-default neo-show-hidden-files t))
|
||||
#+END_SRC
|
||||
|
||||
* Custom Mode Bindings
|
||||
** SystemD unit files
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; Base systemd unit files
|
||||
(add-to-list 'auto-mode-alist '("\\.service\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.timer\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.mount\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.automount\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.target\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.path\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.slice\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.socket\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.device\\'" . conf-unix-mode))
|
||||
;; systemd-networkd
|
||||
(add-to-list 'auto-mode-alist '("\\.network\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.link\\'" . conf-unix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.netdev\\'" . conf-unix-mode))
|
||||
#+END_SRC
|
||||
|
||||
** elkowar's wacky widgets
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'auto-mode-alist '("\\.yuck\\'" . conf-unix-mode))
|
||||
#+END_SRC
|
||||
|
||||
* Markdown mode
|
||||
** Auto Text Wrap
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-hook 'markdown-mode-hook (lambda ()
|
||||
(setq fill-column 85)
|
||||
(visual-fill-column-mode)
|
||||
(visual-line-mode)
|
||||
(display-fill-column-indicator-mode)))
|
||||
#+END_SRC
|
||||
* Org mode
|
||||
** General
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq org-startup-indented t)
|
||||
#+END_SRC
|
||||
** Auto Text Wrap
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-hook 'org-mode-hook (lambda ()
|
||||
(setq fill-column 85)
|
||||
(visual-fill-column-mode)
|
||||
(visual-line-mode)))
|
||||
#+END_SRC
|
||||
** Babel
|
||||
*** Elixir
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package ob-elixir
|
||||
:ensure t)
|
||||
#+END_SRC
|
||||
|
||||
*** Load Languages
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((lisp . t)
|
||||
(elixir . t)
|
||||
(emacs-lisp . t)
|
||||
(python . t)))
|
||||
#+END_SRC
|
||||
** org-bullets
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package org-bullets
|
||||
:ensure t
|
||||
:init
|
||||
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
|
||||
#+END_SRC
|
||||
** org-appear
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package org-appear
|
||||
:ensure t
|
||||
:init
|
||||
(add-hook 'org-mode-hook 'org-appear-mode))
|
||||
#+END_SRC
|
||||
** Presentations
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package org-present
|
||||
:ensure t
|
||||
:straight '(org-present
|
||||
:type git
|
||||
:host github
|
||||
:repo "rlister/org-present"))
|
||||
#+END_SRC
|
||||
|
||||
* Development
|
||||
** Copilot
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; Load copilot
|
||||
(add-to-list 'load-path "/home/ezri/.emacs.d/copilot.el")
|
||||
(require 'copilot)
|
||||
|
||||
;; Enable completion
|
||||
(add-hook 'prog-mode-hook 'copilot-mode)
|
||||
#+END_SRC
|
||||
** Git
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package magit :ensure t)
|
||||
#+END_SRC
|
||||
** Autocomplete
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package auto-complete :ensure t)
|
||||
(ac-config-default)
|
||||
(defun my-tab ()
|
||||
(interactive)
|
||||
(or (copilot-accept-completion)
|
||||
(ac-expand nil)))
|
||||
|
||||
(with-eval-after-load 'auto-complete
|
||||
; diable inline preview
|
||||
(setq ac-disable-inline t)
|
||||
; show menu if have only one candidate
|
||||
(setq ac-candidate-menu-min 0))
|
||||
|
||||
(define-key copilot-completion-map (kbd "<tab>") 'copilot-accept-completion)
|
||||
(define-key copilot-completion-map (kbd "TAB") 'copilot-accept-completion)
|
||||
#+END_SRC
|
||||
** Company mode
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package company
|
||||
:ensure t
|
||||
:init
|
||||
(global-company-mode t)
|
||||
:bind (:map company-active-map
|
||||
("C-n" . company-select-next)
|
||||
("C-p" . company-select-previous))
|
||||
:config
|
||||
(setq company-idle-delay 0.3))
|
||||
#+END_SRC
|
||||
** LSP Mode
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package lsp-mode
|
||||
:ensure t
|
||||
:init
|
||||
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
|
||||
(setq lsp-keymap-prefix "C-c l")
|
||||
:hook ((python-mode . lsp) ;; pip install python-lsp-server pyls-black pyls-isort pyls-mypy
|
||||
(elixir-mode . lsp)
|
||||
(rust-mode . lsp)
|
||||
(java-mode . lsp)
|
||||
(php-mode . lsp)
|
||||
(typescript-mode . lsp) ;; npm install -g typescript typescript-language-server
|
||||
(lsp-mode . lsp-enable-which-key-integration))
|
||||
:config (lsp-register-custom-settings
|
||||
'(("pyls.plugins.pyls_mypy.enabled" t t)
|
||||
("pyls.plugins.pyls_mypy.live_mode" nil t)
|
||||
("pyls.plugins.pyls_black.enabled" t t)
|
||||
("pyls.plugins.pyls_isort.enabled" t t)))
|
||||
:commands lsp)
|
||||
|
||||
#+END_SRC
|
||||
** Languages
|
||||
*** Common Lisp
|
||||
**** Formatter! semantic-refactor
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package srefactor
|
||||
:ensure t
|
||||
:hook ((before-save .
|
||||
(lambda ()
|
||||
(when (eq major-mode 'lisp-mode)
|
||||
(srefactor-lisp-format-buffer))))))
|
||||
(require 'srefactor)
|
||||
(require 'srefactor-lisp)
|
||||
#+END_SRC
|
||||
|
||||
**** Rainbow Parentheses
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package rainbow-delimiters :ensure t)
|
||||
(add-hook 'lisp-mode-hook #'rainbow-delimiters-mode)
|
||||
#+END_SRC
|
||||
|
||||
**** Slime
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package slime
|
||||
:ensure t
|
||||
:init
|
||||
(setq inferior-lisp-program "sbcl"))
|
||||
#+END_SRC
|
||||
**** AC-Slime
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package ac-slime
|
||||
:ensure t
|
||||
:straight '(ac-slime
|
||||
:type git
|
||||
:host github
|
||||
:repo "purcell/ac-slime"))
|
||||
(add-hook 'slime-mode-hook 'set-up-slime-ac)
|
||||
(add-hook 'slime-repl-mode-hook 'set-up-slime-ac)
|
||||
(eval-after-load "auto-complete"
|
||||
'(add-to-list 'ac-modes 'slime-repl-mode))
|
||||
|
||||
#+END_SRC
|
||||
*** Elixir
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package elixir-mode
|
||||
:ensure t
|
||||
:hook ((before-save .
|
||||
(lambda ()
|
||||
(when (eq major-mode 'elixir-mode)
|
||||
(elixir-format))))))
|
||||
#+END_SRC
|
||||
*** Rust
|
||||
After installing the ~rust-analyzer~ program, the following can be used:
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package rust-mode
|
||||
:ensure t)
|
||||
(setq lsp-rust-server 'rust-analyzer)
|
||||
#+END_SRC
|
||||
*** Vue
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-hook 'mmm-mode-hook
|
||||
(lambda ()
|
||||
(set-face-background 'mmm-default-submode-face nil)))
|
||||
#+END_SRC
|
||||
*** Web Stuff
|
||||
**** typescript-mode
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; TODO: Update to tree-sitter in Emacs 29
|
||||
(use-package typescript-mode
|
||||
:ensure t)
|
||||
(setq typescript-indent-level 2)
|
||||
#+END_SRC
|
||||
**** TIDE
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun setup-tide-mode ()
|
||||
(interactive)
|
||||
(tide-setup)
|
||||
(flycheck-mode +1)
|
||||
(setq flycheck-check-syntax-automatically '(save mode-enabled))
|
||||
(eldoc-mode +1)
|
||||
(tide-hl-identifier-mode +1)
|
||||
;; company is an optional dependency. You have to
|
||||
;; install it separately via package-install
|
||||
;; `M-x package-install [ret] company`
|
||||
(company-mode +1))
|
||||
|
||||
(use-package tide
|
||||
:ensure t
|
||||
:after (typescript-mode company flycheck)
|
||||
:hook ((typescript-mode . setup-tide-mode) ;; TODO: Update to tree-sitter in Emacs 29
|
||||
(js2-mode . setup-tide-mode)))
|
||||
#+END_SRC
|
||||
|
||||
**** Web Mode
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; web-mode
|
||||
(setq web-mode-markup-indent-offset 2)
|
||||
(setq web-mode-code-indent-offset 2)
|
||||
(setq web-mode-css-indent-offset 2)
|
||||
(use-package web-mode
|
||||
:ensure t
|
||||
:mode (("\\.scss\\'" . web-mode)
|
||||
("\\.css\\'" . web-mode)
|
||||
("\\.jsx\\'" . web-mode)
|
||||
("\\.tsx\\'" . web-mode)
|
||||
("\\.html\\'" . web-mode))
|
||||
:commands web-mode)
|
||||
#+END_SRC
|
||||
**** Prettier
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package prettier-js
|
||||
:ensure t)
|
||||
(add-hook 'js2-mode-hook 'prettier-js-mode)
|
||||
(add-hook 'typescript-mode 'prettier-js-mode)
|
||||
(add-hook 'web-mode-hook 'prettier-js-mode)
|
||||
#+END_SRC
|
||||
**** Prisma
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package prisma-mode
|
||||
:ensure t
|
||||
:straight '(prisma-mode
|
||||
:type git
|
||||
:host github
|
||||
:repo "pimeys/emacs-prisma-mode"))
|
||||
#+END_SRC
|
||||
**** Svelte
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package svelte-mode
|
||||
:ensure t
|
||||
:straight '(svelte-mode
|
||||
:type git
|
||||
:host github
|
||||
:repo "leafOfTree/svelte-mode"))
|
||||
#+END_SRC
|
||||
*** Kotlin
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package kotlin-mode
|
||||
:ensure t)
|
||||
#+END_SRC
|
||||
*** Java
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package lsp-java
|
||||
:config (add-hook 'java-mode-hook 'lsp)
|
||||
:ensure t)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: t
|
||||
*** PHP
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package php-mode
|
||||
:ensure t)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
|
||||
** Format All The Buffers
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package format-all
|
||||
:ensure t)
|
||||
(add-hook 'prog-mode-hook 'format-all-mode)
|
||||
(add-hook 'format-all-mode-hook 'format-all-ensure-formatter)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
| format-all-ensure-formatter |
|
||||
|
||||
* Multiple Cursors
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package multiple-cursors
|
||||
:straight t
|
||||
:ensure t
|
||||
:bind (("H-SPC" . set-rectangular-region-anchor)
|
||||
("C-M-SPC" . set-rectangular-region-anchor)
|
||||
("C->" . mc/mark-next-like-this)
|
||||
("C-<" . mc/mark-previous-like-this)
|
||||
("C-c C->" . mc/mark-all-like-this)
|
||||
("C-c C-SPC" . mc/edit-lines)
|
||||
))
|
||||
#+END_SRC
|
||||
* Obsidian
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package obsidian
|
||||
:ensure t
|
||||
:demand t
|
||||
:config
|
||||
(obsidian-specify-path "~/PersonalDocuments/Personal/TTRPG Vault")
|
||||
(global-obsidian-mode t)
|
||||
:custom
|
||||
:bind (:map obsidian-mode-map
|
||||
("C-c C-o" . obsidian-follow-link-at-point)
|
||||
("C-c C-b" . obsidian-backlink-jump)
|
||||
("C-c C-l" . obsidian-insert-wikilink)))
|
||||
#+END_SRC
|
||||
9
.gitmodules
vendored
Normal file
9
.gitmodules
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
[submodule ".local/lib/zsh/zsh-syntax-highlighting"]
|
||||
path = .local/lib/zsh/zsh-syntax-highlighting
|
||||
url = github:zsh-users/zsh-syntax-highlighting
|
||||
[submodule ".local/lib/zsh/zsh-autosuggestions"]
|
||||
path = .local/lib/zsh/zsh-autosuggestions
|
||||
url = github:zsh-users/zsh-autosuggestions
|
||||
[submodule ".local/lib/zsh/zsh-history-substring-search"]
|
||||
path = .local/lib/zsh/zsh-history-substring-search
|
||||
url = github:zsh-users/zsh-history-substring-search
|
||||
1
.local/lib/zsh/zsh-autosuggestions
Submodule
1
.local/lib/zsh/zsh-autosuggestions
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c3d4e576c9c86eac62884bd47c01f6faed043fc5
|
||||
1
.local/lib/zsh/zsh-history-substring-search
Submodule
1
.local/lib/zsh/zsh-history-substring-search
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 8dd05bfcc12b0cd1ee9ea64be725b3d9f713cf64
|
||||
1
.local/lib/zsh/zsh-syntax-highlighting
Submodule
1
.local/lib/zsh/zsh-syntax-highlighting
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e0165eaa730dd0fa321a6a6de74f092fe87630b0
|
||||
2
.ssh/authorized_keys
Normal file
2
.ssh/authorized_keys
Normal file
@ -0,0 +1,2 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCxTuUx4k1E+354rh1nyC5totwtIcw4RuyXXixIj0dCmlfACfCijuIYoA+2nCcGrGGDnEPLCR7PwHgJebN1MxQ6T1Vf170k05Zfnlqnd7d0llBmGYEVY1BgBcKIJEfASsOYxSnIlqT0mYCVYGx/el928tLwrWBfp2f2RqTblg6hTFW//1krkrD3X/s+rTX51dP9dOE9U7dIpKaHaxE1IpKziLbL6RnjDdNDK4ZvIRDjQIOcSNJbw3z42pZO/u83SpIB3O3pWckE5WTYcqhyg764gMkcQeWbpGpB+9wvxkbpoDuVUcNkdBYKF3+AF3ELszAMD+TwgFaqbLpy2EivhuC52DC64j+ZcpQC1vozm7JK81+7tZVfZc6VQqwe15BSx1n0rPPaBn98l0t26BUfZEQFFdp6AHjnEAjaJTiKJ4pqdsCJSprolXtGfyY7WVIrLr7hM5JihGftGrb6d08kbs0tSE1VC15fRMZ/XMhucqEF91cLzCNgRhJG55FDlaSHryQHqGDlzeaKZECDm0EwhoMDi2Qfb2d2Jy/BDZvf9mYhiCvLgSNAh3qi5hHXyq5IY7RP3xrs7Cz3e6lSlpYpyfey9fU+tya+RfgwMCB9HWDrCI6wUiwHs2SRuHLtZIZYfFKzkpct/la7voSDWZHv+O0gUyik3CBFJKaL9Ra/fot2Yw== cardno:11 462 306
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDGIejfvH+wJXmUFW1xGlGtKRSRmEb0DwcWH7FvXIQXMFdomZI/imrDbr/Lj0i1o66TsIDc3IgxxLzO+aCDSyr768S0y1/w7ob50NtOcRTOLHqhK2kS2dQGouhDNVG5pnBI1muS0YxuQ1mLRoFteY7BL24wbYttfmRd/dQXbTAzk+WRZw8lCOLMCphLDA4axuWMi116Tbc/x4/i41DHsrXz+Q3qr/+p06DMRc2HcbHQ8WyZoF70iB24WAdWydw+9GU6HNdmHtmPLrmNM007dkKHvZ0r5Z5gbOpqSdEA6+N2EP6KrC/euzDcaCEuBjDj7ro5fzltmLh5TyyTcXlfgNYj7L8ft+2adHsBgVP4Mf9GljZANWFee10G+lubIYKCVDUtKz5smzNZAH6VAd1+q8BLwsWHkxkX9CZELEKprnEbjS9Bw81grhKYDFf+U2qqOGUNIX++rADBeVram8EVIFvz424FXC5IGbaOUoacqbonk9pb4cGiPOzORs4FdroVMplVsll9WC6HpzGpTFDSu9ExJInnjCXjYFGehlB8aNGOE0WMUMc8iuUUkcIpNMv7+kTZFEDRcXqrsX1VbGa0+8hgtlcwiG3VJTbOT/M3m/ioS2ZDctKvwfBfFQpR93+o79nUMvtZC+9fhdb8bfsi/Pp4i8MMpjhhG+lZYhAGotTkfw== cardno:12 241 532
|
||||
Loading…
x
Reference in New Issue
Block a user