Compare commits

...

5 Commits

16 changed files with 1060 additions and 71 deletions

View File

@ -63,6 +63,3 @@ dynamic_padding = true
dynamic_title = true
opacity = 0.8
title = "Terminal"
[general]
working_directory = "/home/ezri"

View File

@ -0,0 +1,96 @@
;; -*-lisp-*- Include modules
(include "./modules/workspaces.yuck")
(include "./modules/clock.yuck")
(include "./modules/system.yuck")
(include "./modules/network.yuck")
(include "./modules/volume.yuck")
(include "./modules/aggietime.yuck")
(include "./modules/timer.yuck")
(include "./modules/mpris.yuck")
(defvar power--state "normal")
(include "./windows.yuck")
(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"
(tycho-leftbar--left)
(tycho-leftbar--center)
(tycho-leftbar--right)))
(defwindow centerbar
:monitor 0
:geometry (geometry :width "100%"
:height "26px"
:anchor "top center")
:exclusive true
:focusable false
:stacking "fg"
(centerbox :orientation "h"
:class "bar root"
(tycho-centerbar--left)
(tycho-centerbar--center)
(tycho-centerbar--right)))
(defwindow rightbar
:monitor 2
:geometry (geometry :width "100%"
:height "36px"
:anchor "top center")
:exclusive true
:focusable false
:stacking "fg"
(centerbox :orientation "h"
:class "bar root"
(tycho-rightbar--left)
(tycho-rightbar--center)
(tycho-rightbar--right)))
(defwindow sidebar
:monitor 1
:geometry (geometry :width "200px"
:height "100%"
:anchor "left center")
:exclusive true
:focusable false
:stacking "fg"
(tycho-sidebar))
(defwindow network-status
:monitor 0
:geometry (geometry :width "200px"
:height "0px"
:x "300px"
:y "0px"
:anchor "top right")
:exclusive false
:focusable false
:stacking "overlay"
(box :orientation "v"
:class "bar root bg outline"
:visible {network--show-details}
(network-detail)))
(defwindow builtinbar
:monitor 0
:geometry (geometry :width "100%"
:height "36px"
:anchor "top center")
:exclusive true
:focusable false
:stacking "fg"
(centerbox :orientation "h" :class "bar root ${power--state == 'critical' ? 'reservepower' : ''}"
(rocinante-builtinbar--left)
(rocinante-builtinbar--center)
(rocinante-builtinbar--right)))

View File

@ -0,0 +1,347 @@
;; -*-lisp-*-
(deflisten network--data
`~/.config/eww/scripts/network.py`)
(defvar network--show-details false)
(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}")))
))
(defwidget network-sidebar-details []
(box :orientation "v"
:halign "start"
:class "module"
:space-evenly false
:spacing 5
:width 200
(box :orientation "h"
:halign "center"
:class "nebula"
:spacing 10
:space-evenly false
(label :class "medium special"
:text "Comms"))
(box :orientation "h"
:halign "center"
:class "nebula"
:spacing 10
:space-evenly false
(label :class "nebula green"
:text "Online"
:visible {network--data.online})
(label :class "nebula highlight"
:text "Offline"
:visible {!network--data.online}))
(centerbox :orientation "h"
:halign "start"
:spacing 10
:width 200
:space-evenly false
(box :halign "start"
:class "nebula"
"Route On:")
""
(box :halign "end"
(label :text "No Route"
:class "highlight"
:visible {network--data.online && !network--data.have_default_route})
(label :text "${network--data.default_route}"
:class "special"
:visible {network--data.online && network--data.have_default_route})))
(centerbox :orientation "h"
:halign "start"
:spacing 10
:width 200
:space-evenly false
(box :halign "start"
:valign "start"
:class "nebula"
"Address:")
""
(box :halign "end"
:orientation "v"
(label :text "${network--data.default_interface.addresses[0].address}"
:class "special")
(label :text "/${network--data.default_interface.addresses[0].prefixlen}"
:halign "end"
:class "special")))
(centerbox :orientation "h"
:halign "start"
:spacing 10
:width 200
:space-evenly false
(box :halign "start"
:class "nebula"
"Public IP:")
""
(box :halign "end"
(label :text "Offline"
:class "highlight"
:visible {!network--data.have_public_ip})
(label :text {network--data.public_ip.ip}
:class "special"
:visible {network--data.have_public_ip})))
(centerbox :orientation "h"
:halign "start"
:spacing 10
:width 200
:space-evenly false
(box :halign "start"
:class "nebula"
"Gateway:")
""
(box :halign "end"
(label :text "Error"
:class "highlight nebula"
:visible {!network--data.have_gateway})
(label :text {network--data.gateway}
:class "special"
:visible {network--data.have_gateway})))
(centerbox :orientation "h"
:halign "start"
:class "nebula"
:spacing 10
:width 200
:space-evenly false
(box :halign "start"
"VPN:")
""
(box :halign "end"
(label :text "Offline"
:class "highlight"
:visible {!network--data.interfaces.ezrinet.online})
(label :text "Online"
:class "green"
:visible {network--data.interfaces.ezrinet.online})))
))

View File

@ -0,0 +1,306 @@
#!/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
runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp")
def load_last_data(var_name: str):
try:
if os.path.exists(f"{runtime_dir}/{var_name}.json"):
with open(f"{runtime_dir}/{var_name}.json", "r") as f:
return json.load(f), os.path.getmtime(f"{runtime_dir}/{var_name}.json")
except:
pass
return None, None
def store_last_data(var_name: str, data):
with open(f"{runtime_dir}/{var_name}.json", "w") as f:
json.dump(data, f)
last_default_route = load_last_data("default_route")[0]
last_ip_data, last_request = load_last_data("ip_data")
try:
last_first_hop = IPAddress(load_last_data("first_hop")[0])
except:
last_first_hop = None
while True:
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 2 hours 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 > (2 * 60 * 60)
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
# Write the public IP data to a file
store_last_data("ip_data", public_ip_data)
last_default_route = default_route
store_last_data("default_route", default_route)
last_request = now()
last_first_hop = hop
store_last_data("first_hop", str(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,
)
sleep(5)

View File

@ -38,20 +38,20 @@ 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=1
sort_key=0
tree_sort_key=0
sort_direction=1
tree_sort_direction=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=PID
.tree_sort_key=PID
.sort_key=PERCENT_CPU
.tree_sort_key=PERCENT_CPU
.tree_view_always_by_pid=0
.tree_view=1
.sort_direction=1
.tree_sort_direction=1
.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

View File

@ -199,6 +199,9 @@ for_window [floating] border normal 1
## Thunderbird New.* windows should float
for_window [app_id="thunderbird" title="(New|Write)"] floating enable
## Bitwarden extension windows should float by default
for_window [app_id="firefox" title="Extension: \(Bitwarden Password Manager\)"] floating enable
### ###
# Application Keybinds #
### ###
@ -220,6 +223,10 @@ bindsym --locked {
XF86AudioPlay exec playerctl play-pause
XF86AudioNext exec playerctl next
XF86AudioPrev exec playerctl previous
XF86AudioRaiseVolume exec pactl set-sink-volume @DEFUALT_SINK@ +5%
XF86AudioLowerVolume exec pactl set-sink-volume @DEFUALT_SINK@ -5%
XF86AudioMute exec pactl set-sink-mute @DEFUALT_SINK@ toggle
}
## Screen Locking

View File

@ -0,0 +1,9 @@
### -*-conf-space-*- ###
# Gathering Storm Display Config #
### ###
set $display eDP-1
output $display scale 1 pos 0 1080
output $display color_profile icc /usr/share/color/icc/colord/BOE_CQ_______NE160QDM_NZ6.icm

View File

@ -20,30 +20,3 @@ workspace {
10 output $display
}
## Workspace Switching Keybinds
bindsym {
$mod+1 exec swaymsg workspace 1
$mod+2 exec swaymsg workspace 2
$mod+3 exec swaymsg workspace 3
$mod+4 exec swaymsg workspace 4
$mod+5 exec swaymsg workspace 5
$mod+6 exec swaymsg workspace 6
$mod+7 exec swaymsg workspace 7
$mod+8 exec swaymsg workspace 8
$mod+9 exec swaymsg workspace 9
$mod+0 exec swaymsg workspace 10
}
## Window Reassignment Keybinds
bindsym {
$mod+Shift+1 exec swaymsg move container to workspace 1
$mod+Shift+2 exec swaymsg move container to workspace 2
$mod+Shift+3 exec swaymsg move container to workspace 3
$mod+Shift+4 exec swaymsg move container to workspace 4
$mod+Shift+5 exec swaymsg move container to workspace 5
$mod+Shift+6 exec swaymsg move container to workspace 6
$mod+Shift+7 exec swaymsg move container to workspace 7
$mod+Shift+8 exec swaymsg move container to workspace 8
$mod+Shift+9 exec swaymsg move container to workspace 9
$mod+Shift+0 exec swaymsg move container to workspace 10
}

View File

@ -0,0 +1,249 @@
{
"default_context": "personal-portable",
"workspaces": [
{
"index": 1,
"name": "console",
"exec": "console",
"program_name": "console"
},
{
"index": 2,
"name": "code",
"exec": "emacsclient",
"args": ["-nc"],
"program_name": "emacsclient"
},
{
"index": 3,
"name": "documentation",
"exec": "firefox",
"args": ["--new-window"],
"environ": {},
"program_name": "firefox"
},
{
"index": 4,
"name": "project",
"exec": "firefox",
"args": ["--new-window"],
"program_name": "firefox"
},
{
"index": 5,
"name": "discord",
"exec": "discord",
"program_name": "discord"
},
{
"index": 6,
"name": "console",
"exec": "console",
"program_name": "console"
},
{
"index": 7,
"name": "code",
"exec": "emacsclient",
"args": ["-nc"],
"program_name": "emacsclient"
},
{
"index": 8,
"name": "internet",
"exec": "firefox",
"args": ["--new-window"],
"program_name": "firefox"
},
{
"index": 9,
"name": "project",
"exec": "firefox-developer-edition",
"args": ["-start-debugger-server", "--new-window"],
"program_name": "firefox-developer-edition"
},
{
"index": 10,
"name": "server management",
"exec": "virt-manager",
"program_name": "virt-manager",
"systemd": false
},
{
"index": 11,
"name": "password management",
"exec": "bitwarden-desktop",
"program_name": "bitwarden"
},
{
"index": 12,
"name": "video",
"exec": "jellyfinmediaplayer",
"program_name": "jellyfinmediaplayer"
},
{
"index": 13,
"name": "edex-ui",
"exec": "edex-ui",
"program_name": "edex-ui"
},
{
"index": 14,
"name": "mail",
"exec": "thunderbird",
"program_name": "thunderbird",
"environ": {
"MOZ_ENABLE_WAYLAND": "1"
}
},
{
"index": 15,
"name": "config",
"exec": "console",
"program_name": "console"
},
{
"index": 16,
"name": "console",
"exec": "console",
"program_name": "console"
},
{
"index": 17,
"name": "code",
"exec": "emacsclient",
"args": ["-nc"],
"program_name": "emacsclient"
},
{
"index": 18,
"name": "music",
"exec": "feishin",
"program_name": "feishin"
},
{
"index": 19,
"name": "project",
"exec": "firefox",
"args": ["--new-window"],
"program_name": "firefox"
},
{
"index": 20,
"name": "slack",
"exec": "slack",
"program_name": "slack",
"args": [
"--enable-features=UseOzonePlatform",
"--ozone-platform=wayland",
"--enable-gpu-rasterization"
],
"memory_profile": {
"high": "800M",
"max": "1.2G"
}
},
{
"index": 21,
"name": "ferrets",
"exec": "firefox",
"args": ["--new-window", "https://www.twitch.tv/ferretsoftware"],
"program_name": "firefox"
}
],
"contexts": {
"docked": {
"primary": "center",
"outputs": [
{
"names": ["eDP-1"],
"group": "builtin",
"position": [0, 600],
"eww_windows": ["builtinbar"],
"mode": "2560x1600@165Hz scale 1.5 color_profile icc /usr/share/color/icc/colord/BOE_CQ_______NE160QDM_NZ6.icm"
},
{
"make": "Acer Technologies",
"model": "XV271U M3",
"serial": "1322131231233",
"group": "left",
"position": [1707, 0],
"mode": "2560x1440@120Hz",
"eww_windows": ["leftbar", "sidebar"]
},
{
"make": "Dell Inc.",
"model": "DELL U3818DW",
"serial": "97F8P9350W0L",
"group": "center",
"position": [4267, 0],
"mode": "3840x1600",
"eww_windows": ["centerbar"]
},
{
"make": "Acer Technologies",
"model": "XV271U M3",
"serial": "1431038964205",
"group": "right",
"position": [8107, 0],
"mode": "2560x1440@120Hz",
"eww_windows": ["rightbar"]
}
],
"groups": {
"builtin": {
"workspaces": [21],
"reverse": false
},
"left": {
"workspaces": [1, 2, 3, 4, 5],
"reverse": true
},
"center": {
"workspaces": [6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
"reverse": false
},
"right": {
"workspaces": [16, 17, 18, 19, 20],
"reverse": false
}
}
},
"work-portable": {
"primary": "builtin",
"outputs": [
{
"names": ["eDP-1"],
"group": "builtin",
"position": [0, 0],
"eww_windows": ["builtinbar"],
"mode": "2560x1600@165Hz scale 1.25 color_profile icc /usr/share/color/icc/colord/BOE_CQ_______NE160QDM_NZ6.icm"
}
],
"groups": {
"builtin": {
"workspaces": [6, 7, 8, 9, 10, 11, 18, 20, 14, 15],
"reverse": false
}
}
},
"personal-portable": {
"primary": "builtin",
"outputs": [
{
"names": ["eDP-1"],
"group": "builtin",
"position": [0, 0],
"eww_windows": ["builtinbar"],
"mode": "2560x1600@165Hz scale 1.25 color_profile icc /usr/share/color/icc/colord/BOE_CQ_______NE160QDM_NZ6.icm"
}
],
"groups": {
"builtin": {
"workspaces": [6, 7, 8, 9, 10, 11, 18, 5, 14, 15],
"reverse": false
}
}
}
}
}

View File

@ -13,8 +13,8 @@ Restart=on-failure
Slice=session.slice
MemoryAccounting=yes
# Tide eats memory like crazy, so lets put it on a diet.
MemoryHigh=3G
MemoryMax=5G
MemoryHigh=8G
MemoryMax=10G
[Install]
WantedBy=graphical-session.target

View File

@ -3,8 +3,8 @@ Description=eww status bars
PartOf=sway-session.target
[Service]
Type=forking
ExecStart=eww daemon
Type=simple
ExecStart=eww daemon --no-daemonize
ExecReload=eww reload
ExecStop=eww kill
ExecStopPost=sleep 1

View File

@ -0,0 +1,4 @@
# -*-conf-unix-*-
[Service]
ExecStartPost=eww open-many builtinbar

View File

@ -7,7 +7,7 @@ alias userctl="\systemctl --user"
alias ujournalctl="\journalctl --user"
alias reconf="source $HOME/.zshrc"
alias reconf="exec $SHELL"
alias cp="cp -i --reflink=auto"
alias mv="mv -i"

View File

@ -11,7 +11,7 @@ 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
export PATH=.:$PATH_node:$PATH_pyenv:$PATH_java:$PATH_user:$PATH_system
# Function to run a command with only the "safe" system PATH element
function safeexec {

View File

@ -1,2 +0,0 @@
# source $HOME/.local/lib/asdf/asdf.sh
# source $HOME/.local/lib/asdf/completions/asdf.bash

View File

@ -513,26 +513,29 @@ Indent using tabs, render with tab-width of 2.
:config
(setq company-idle-delay 0.3))
#+END_SRC
** LSP Mode
** LSP
#+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)
;; (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
;; )
;; :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)
(use-package eglot
:ensure t)
#+END_SRC
** Languages
@ -570,11 +573,11 @@ After installing the ~rust-analyzer~ program, the following can be used:
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode))
(add-hook 'tsx-ts-mode-hook #'lsp)
(add-hook 'tsx-ts-mode-hook #'setup-tide-mode)
;; (add-hook 'tsx-ts-mode-hook #'eglot)
;; (add-hook 'tsx-ts-mode-hook #'setup-tide-mode)
(add-hook 'typescript-ts-mode-hook #'lsp)
(add-hook 'typescript-ts-mode-hook #'setup-tide-mode)
;; (add-hook 'typescript-ts-mode-hook #'eglot)
;; (add-hook 'typescript-ts-mode-hook #'setup-tide-mode)
#+END_SRC
**** TIDE
#+BEGIN_SRC emacs-lisp