Goodbye bacon!
This commit is contained in:
parent
d010c48306
commit
4f02db850b
3
Xresources.d/configure
vendored
3
Xresources.d/configure
vendored
|
@ -5,5 +5,4 @@ echo $(for i in "" "%20Bold" "%20Oblique" "%20Bold%20Oblique"; do
|
||||||
cd $HOME/.local/share/fonts
|
cd $HOME/.local/share/fonts
|
||||||
wget -c http://raw.githubusercontent.com/powerline/fonts/master/DejaVuSansMono/DejaVu%20Sans%20Mono$i%20for%20Powerline.ttf
|
wget -c http://raw.githubusercontent.com/powerline/fonts/master/DejaVuSansMono/DejaVu%20Sans%20Mono$i%20for%20Powerline.ttf
|
||||||
done)
|
done)
|
||||||
wget -c "https://aur.archlinux.org/cgit/aur.git/plain/icons.ttf?h=ttf-font-icons" -O $HOME/.local/share/fonts/icons.ttf
|
wget -c "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/a8386aae19e200ddb0f6845b5feeee5eb7013687/fonts/fontawesome-webfont.ttf" -O $HOME/.local/share/fonts/fontawesome-webfont.ttf
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ bindsym $mod+F11 exec urxvtc -e 'pacmixer'
|
||||||
bindsym $mod+F12 exec urxvtc -e 'pacmixer'
|
bindsym $mod+F12 exec urxvtc -e 'pacmixer'
|
||||||
|
|
||||||
#Brightness control
|
#Brightness control
|
||||||
bindsym XF86MonBrightnessDown exec xbacklight -dec 20
|
bindsym XF86MonBrightnessDown exec xbacklight -dec 20 -time 0
|
||||||
bindsym XF86MonBrightnessUp exec xbacklight -inc 20
|
bindsym XF86MonBrightnessUp exec xbacklight -inc 20 -time 0
|
||||||
|
|
||||||
# Screenshots
|
# Screenshots
|
||||||
bindsym Print exec scrot -ue 'mv $f ~/Screenshots/'
|
bindsym Print exec scrot -ue 'mv $f ~/Screenshots/'
|
||||||
|
@ -226,13 +226,6 @@ bindsym $mod+ctrl+shift+Left move workspace to output left
|
||||||
bindsym $mod+Ctrl+Shift+Up move workspace to output above
|
bindsym $mod+Ctrl+Shift+Up move workspace to output above
|
||||||
bindsym $mod+Ctrl+Shift+Down move workspace to output below
|
bindsym $mod+Ctrl+Shift+Down move workspace to output below
|
||||||
|
|
||||||
# Open applications on specific workspaces
|
|
||||||
assign [class="Thunderbird"] $WS7
|
|
||||||
assign [class="Skype"] $WS7
|
|
||||||
assign [class="Pidgin"] $WS7
|
|
||||||
assign [class="Clementine"] $WS10
|
|
||||||
assign [title="TweetDeck"] $WS8
|
|
||||||
|
|
||||||
# Open specific applications in floating mode
|
# Open specific applications in floating mode
|
||||||
for_window [title="pacmixer"] floating enable border pixel 2
|
for_window [title="pacmixer"] floating enable border pixel 2
|
||||||
for_window [class="Firefox"] layout tabbed
|
for_window [class="Firefox"] layout tabbed
|
||||||
|
@ -353,6 +346,7 @@ set_from_resource $color15 i3wm.color15 #cfd0c2
|
||||||
|
|
||||||
# Inactivity settings
|
# Inactivity settings
|
||||||
exec --no-startup-id xautolock -time 10 -locker 'xset dpms force standby' -killtime 1 -killer '$locker'
|
exec --no-startup-id xautolock -time 10 -locker 'xset dpms force standby' -killtime 1 -killer '$locker'
|
||||||
|
bindsym $mod+F1 exec --no-startup-id xset dpms force off
|
||||||
bindsym $mod+F4 exec --no-startup-id xautolock -disable
|
bindsym $mod+F4 exec --no-startup-id xautolock -disable
|
||||||
bindsym $mod+F5 exec --no-startup-id xautolock -enable
|
bindsym $mod+F5 exec --no-startup-id xautolock -enable
|
||||||
|
|
||||||
|
@ -366,7 +360,7 @@ exec --no-startup-id unclutter -root # Hide mouse cursor after some time
|
||||||
#exec --no-startup-id dunst # Notifications (handled by systemd)
|
#exec --no-startup-id dunst # Notifications (handled by systemd)
|
||||||
exec --no-startup-id keynav # Keyboard cursor controller
|
exec --no-startup-id keynav # Keyboard cursor controller
|
||||||
#exec --no-startup-id mpd # Music Player Daemon (handled by systemd)
|
#exec --no-startup-id mpd # Music Player Daemon (handled by systemd)
|
||||||
exec --no-startup-id ~/.config/i3/ashuffle # MPD Auto-refill
|
# exec --no-startup-id ~/.config/i3/ashuffle # MPD Auto-refill
|
||||||
exec --no-startup-id autorandr --change # Screen configuration and everything that depends on it
|
exec --no-startup-id autorandr --change # Screen configuration and everything that depends on it
|
||||||
exec --no-startup-id ~/.config/i3/batteryNotify -d # Battery state notification
|
exec --no-startup-id ~/.config/i3/batteryNotify -d # Battery state notification
|
||||||
|
|
||||||
|
@ -381,3 +375,7 @@ client.urgent $color01 $color01 $color07 $foreground $color09
|
||||||
client.placeholder $ignore $color06 $color07 $ignore $color14
|
client.placeholder $ignore $color06 $color07 $ignore $color14
|
||||||
|
|
||||||
client.background $color15
|
client.background $color15
|
||||||
|
|
||||||
|
# bar {
|
||||||
|
# i3bar_command ~/.config/lemonbar/bar.py
|
||||||
|
# }
|
||||||
|
|
|
@ -25,6 +25,7 @@ if __name__ == "__main__":
|
||||||
Bar.addSectionAll(MpdProvider(theme=7), BarGroupType.LEFT)
|
Bar.addSectionAll(MpdProvider(theme=7), BarGroupType.LEFT)
|
||||||
# Bar.addSectionAll(I3WindowTitleProvider(), BarGroupType.LEFT)
|
# Bar.addSectionAll(I3WindowTitleProvider(), BarGroupType.LEFT)
|
||||||
|
|
||||||
|
# TODO Computer modes
|
||||||
|
|
||||||
SYSTEM_THEME = 2
|
SYSTEM_THEME = 2
|
||||||
DANGER_THEME = FOCUS_THEME
|
DANGER_THEME = FOCUS_THEME
|
||||||
|
@ -40,6 +41,7 @@ if __name__ == "__main__":
|
||||||
# TODO Disk space provider
|
# TODO Disk space provider
|
||||||
# TODO Screen (connected, autorandr configuration, bbswitch) provider
|
# TODO Screen (connected, autorandr configuration, bbswitch) provider
|
||||||
Bar.addSectionAll(PulseaudioProvider(theme=PERIPHERAL_THEME), BarGroupType.RIGHT)
|
Bar.addSectionAll(PulseaudioProvider(theme=PERIPHERAL_THEME), BarGroupType.RIGHT)
|
||||||
|
Bar.addSectionAll(RfkillProvider(theme=PERIPHERAL_THEME), BarGroupType.RIGHT)
|
||||||
Bar.addSectionAll(NetworkProvider(theme=NETWORK_THEME), BarGroupType.RIGHT)
|
Bar.addSectionAll(NetworkProvider(theme=NETWORK_THEME), BarGroupType.RIGHT)
|
||||||
|
|
||||||
# Personal
|
# Personal
|
||||||
|
@ -50,3 +52,5 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
TIME_THEME = 6
|
TIME_THEME = 6
|
||||||
Bar.addSectionAll(TimeProvider(theme=TIME_THEME), BarGroupType.RIGHT)
|
Bar.addSectionAll(TimeProvider(theme=TIME_THEME), BarGroupType.RIGHT)
|
||||||
|
|
||||||
|
# Bar.run()
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
import enum
|
import enum
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import i3ipc
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import logging
|
import logging
|
||||||
import coloredlogs
|
import coloredlogs
|
||||||
|
@ -10,6 +13,7 @@ import coloredlogs
|
||||||
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
# TODO Allow deletion of Bar, BarGroup and Section for screen changes
|
# TODO Allow deletion of Bar, BarGroup and Section for screen changes
|
||||||
# IDEA Use i3 ipc events rather than relying on xrandr or Xlib (less portable
|
# IDEA Use i3 ipc events rather than relying on xrandr or Xlib (less portable
|
||||||
# but easier)
|
# but easier)
|
||||||
|
@ -18,6 +22,7 @@ log = logging.getLogger()
|
||||||
# TODO Use bytes rather than strings
|
# TODO Use bytes rather than strings
|
||||||
# TODO Use default colors of lemonbar sometimes
|
# TODO Use default colors of lemonbar sometimes
|
||||||
# TODO Adapt bar height with font height
|
# TODO Adapt bar height with font height
|
||||||
|
# TODO OPTI Static text objects that update its parents if modified
|
||||||
|
|
||||||
|
|
||||||
class BarGroupType(enum.Enum):
|
class BarGroupType(enum.Enum):
|
||||||
|
@ -30,7 +35,7 @@ class BarGroupType(enum.Enum):
|
||||||
|
|
||||||
class BarStdoutThread(threading.Thread):
|
class BarStdoutThread(threading.Thread):
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while Bar.running:
|
||||||
handle = Bar.process.stdout.readline().strip()
|
handle = Bar.process.stdout.readline().strip()
|
||||||
if not len(handle):
|
if not len(handle):
|
||||||
continue
|
continue
|
||||||
|
@ -52,6 +57,7 @@ class Bar:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def init():
|
def init():
|
||||||
|
Bar.running = True
|
||||||
Section.init()
|
Section.init()
|
||||||
|
|
||||||
cmd = ['lemonbar', '-b', '-a', '64']
|
cmd = ['lemonbar', '-b', '-a', '64']
|
||||||
|
@ -66,10 +72,35 @@ class Bar:
|
||||||
Bar(0)
|
Bar(0)
|
||||||
# Bar(1)
|
# Bar(1)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def stop():
|
||||||
|
Bar.running = False
|
||||||
|
Bar.process.kill()
|
||||||
|
|
||||||
|
# TODO This is not really the best way to do it I guess
|
||||||
|
os.killpg(os.getpid(), signal.SIGTERM)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def run():
|
||||||
|
Bar.forever()
|
||||||
|
i3 = i3ipc.Connection()
|
||||||
|
|
||||||
|
def doStop(*args):
|
||||||
|
Bar.stop()
|
||||||
|
print(88)
|
||||||
|
|
||||||
|
try:
|
||||||
|
i3.on('ipc_shutdown', doStop)
|
||||||
|
i3.main()
|
||||||
|
except BaseException:
|
||||||
|
print(93)
|
||||||
|
Bar.stop()
|
||||||
|
|
||||||
# Class globals
|
# Class globals
|
||||||
everyone = set()
|
everyone = set()
|
||||||
string = ""
|
string = ""
|
||||||
process = None
|
process = None
|
||||||
|
running = False
|
||||||
|
|
||||||
nextHandle = 0
|
nextHandle = 0
|
||||||
actionsF2H = dict()
|
actionsF2H = dict()
|
||||||
|
@ -92,8 +123,11 @@ class Bar:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def forever():
|
def forever():
|
||||||
while True:
|
try:
|
||||||
time.sleep(60)
|
while True:
|
||||||
|
time.sleep(60)
|
||||||
|
except BaseException:
|
||||||
|
Bar.stop()
|
||||||
|
|
||||||
def __init__(self, screen):
|
def __init__(self, screen):
|
||||||
assert isinstance(screen, int)
|
assert isinstance(screen, int)
|
||||||
|
@ -136,15 +170,16 @@ class Bar:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def updateAll():
|
def updateAll():
|
||||||
|
|
||||||
Bar.string = ""
|
if Bar.running:
|
||||||
for bar in Bar.everyone:
|
Bar.string = ""
|
||||||
bar.update()
|
for bar in Bar.everyone:
|
||||||
Bar.string += bar.string
|
bar.update()
|
||||||
# Color for empty sections
|
Bar.string += bar.string
|
||||||
Bar.string += BarGroup.color(*Section.EMPTY)
|
# Color for empty sections
|
||||||
|
Bar.string += BarGroup.color(*Section.EMPTY)
|
||||||
|
|
||||||
Bar.process.stdin.write(bytes(Bar.string + '\n', 'utf-8'))
|
Bar.process.stdin.write(bytes(Bar.string + '\n', 'utf-8'))
|
||||||
Bar.process.stdin.flush()
|
Bar.process.stdin.flush()
|
||||||
|
|
||||||
|
|
||||||
class BarGroup:
|
class BarGroup:
|
||||||
|
@ -276,11 +311,14 @@ class SectionThread(threading.Thread):
|
||||||
class Section:
|
class Section:
|
||||||
|
|
||||||
# TODO Update all of that to base16
|
# TODO Update all of that to base16
|
||||||
COLORS = ['#002b36', '#dc322f', '#859900', '#b58900', '#268bd2', '#6c71c4',
|
# COLORS = ['#272822', '#383830', '#49483e', '#75715e', '#a59f85', '#f8f8f2',
|
||||||
'#2aa198', '#93a1a1', '#657b83', '#dc322f', '#859900', '#b58900',
|
# '#f5f4f1', '#f9f8f5', '#f92672', '#fd971f', '#f4bf75', '#a6e22e',
|
||||||
'#268bd2', '#6c71c4', '#2aa198', '#fdf6e3']
|
# '#a1efe4', '#66d9ef', '#ae81ff', '#cc6633']
|
||||||
FGCOLOR = '#93a1a1'
|
COLORS = ['#181818', '#AB4642', '#A1B56C', '#F7CA88', '#7CAFC2', '#BA8BAF',
|
||||||
BGCOLOR = '#002b36'
|
'#86C1B9', '#D8D8D8', '#585858', '#AB4642', '#A1B56C', '#F7CA88',
|
||||||
|
'#7CAFC2', '#BA8BAF', '#86C1B9', '#F8F8F8']
|
||||||
|
FGCOLOR = '#F8F8F2'
|
||||||
|
BGCOLOR = '#272822'
|
||||||
|
|
||||||
THEMES = list()
|
THEMES = list()
|
||||||
EMPTY = (FGCOLOR, BGCOLOR)
|
EMPTY = (FGCOLOR, BGCOLOR)
|
||||||
|
@ -357,6 +395,8 @@ class Section:
|
||||||
def updateText(self, text):
|
def updateText(self, text):
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
text = Text(text)
|
text = Text(text)
|
||||||
|
elif isinstance(text, Text) and not len(text.elements):
|
||||||
|
text = None
|
||||||
|
|
||||||
self.dstText[0] = None if (text is None and not self.persistent) else ((' ' + self.icon + ' ') if self.icon else ' ')
|
self.dstText[0] = None if (text is None and not self.persistent) else ((' ' + self.icon + ' ') if self.icon else ' ')
|
||||||
self.dstText[1] = text
|
self.dstText[1] = text
|
||||||
|
@ -373,6 +413,12 @@ class Section:
|
||||||
Section.sizeChanging.add(self)
|
Section.sizeChanging.add(self)
|
||||||
Section.somethingChanged.set()
|
Section.somethingChanged.set()
|
||||||
|
|
||||||
|
def setDecorators(self, **kwargs):
|
||||||
|
self.dstText.setDecorators(**kwargs)
|
||||||
|
self.curText = str(self.dstText)
|
||||||
|
self.informParentsTextChanged()
|
||||||
|
Section.somethingChanged.set()
|
||||||
|
|
||||||
def updateTheme(self, theme):
|
def updateTheme(self, theme):
|
||||||
assert isinstance(theme, int)
|
assert isinstance(theme, int)
|
||||||
assert theme < len(Section.THEMES)
|
assert theme < len(Section.THEMES)
|
||||||
|
@ -440,13 +486,14 @@ class Section:
|
||||||
class StatefulSection(Section):
|
class StatefulSection(Section):
|
||||||
# TODO FEAT Allow to temporary expand the section (e.g. when important change)
|
# TODO FEAT Allow to temporary expand the section (e.g. when important change)
|
||||||
NUMBER_STATES = None
|
NUMBER_STATES = None
|
||||||
|
DEFAULT_STATE = 0
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
Section.__init__(self, *args, **kwargs)
|
Section.__init__(self, *args, **kwargs)
|
||||||
self.state = 0
|
self.state = self.DEFAULT_STATE
|
||||||
if hasattr(self, 'onChangeState'):
|
if hasattr(self, 'onChangeState'):
|
||||||
self.onChangeState(self.state)
|
self.onChangeState(self.state)
|
||||||
self.dstText.setDecorators(clickLeft=self.incrementState,
|
self.setDecorators(clickLeft=self.incrementState,
|
||||||
clickRight=self.decrementState)
|
clickRight=self.decrementState)
|
||||||
|
|
||||||
def incrementState(self):
|
def incrementState(self):
|
||||||
|
@ -466,6 +513,9 @@ class StatefulSection(Section):
|
||||||
self.refreshData()
|
self.refreshData()
|
||||||
|
|
||||||
class ColorCountsSection(StatefulSection):
|
class ColorCountsSection(StatefulSection):
|
||||||
|
# TODO FEAT Blend colors when not expanded
|
||||||
|
# TODO FEAT Blend colors with importance of count
|
||||||
|
# TODO FEAT Allow icons instead of counts
|
||||||
NUMBER_STATES = 3
|
NUMBER_STATES = 3
|
||||||
COLORABLE_ICON = '?'
|
COLORABLE_ICON = '?'
|
||||||
|
|
||||||
|
@ -552,6 +602,8 @@ class Text:
|
||||||
nest('A' + number + ':' + handle.decode() + ':', 'A' + number)
|
nest('A' + number + ':' + handle.decode() + ':', 'A' + number)
|
||||||
|
|
||||||
for key, val in self.decorators.items():
|
for key, val in self.decorators.items():
|
||||||
|
if val is None:
|
||||||
|
continue
|
||||||
if key == 'fg':
|
if key == 'fg':
|
||||||
reset = self.section.THEMES[self.section.theme][0]
|
reset = self.section.THEMES[self.section.theme][0]
|
||||||
nest('F' + getColor(val), 'F' + reset)
|
nest('F' + getColor(val), 'F' + reset)
|
||||||
|
|
15
config/lemonbar/launch.sh
Executable file
15
config/lemonbar/launch.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# TODO Make this better
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||||
|
|
||||||
|
ex="$DIR/bar.py"
|
||||||
|
|
||||||
|
# Terminate already running bar instances
|
||||||
|
ps -af | grep "python3 $ex" | grep -v grep | awk '{print $2}' | while read p; do kill $p; done
|
||||||
|
killall -q lemonbar
|
||||||
|
|
||||||
|
$ex
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ import random
|
||||||
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
|
|
||||||
|
# TODO Generator class (for I3WorkspacesProvider, NetworkProvider and later
|
||||||
|
# PulseaudioProvider and MpdProvider)
|
||||||
|
|
||||||
def humanSize(num):
|
def humanSize(num):
|
||||||
"""
|
"""
|
||||||
|
@ -43,6 +45,7 @@ class TimeProvider(StatefulSection, PeriodicUpdater):
|
||||||
"%d/%m %H:%M:%S",
|
"%d/%m %H:%M:%S",
|
||||||
"%a %d/%m/%y %H:%M:%S"]
|
"%a %d/%m/%y %H:%M:%S"]
|
||||||
NUMBER_STATES = len(FORMATS)
|
NUMBER_STATES = len(FORMATS)
|
||||||
|
DEFAULT_STATE = 1
|
||||||
|
|
||||||
def fetcher(self):
|
def fetcher(self):
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
@ -114,13 +117,13 @@ class RamProvider(AlertingSection, PeriodicUpdater):
|
||||||
|
|
||||||
def fetcher(self):
|
def fetcher(self):
|
||||||
mem = psutil.virtual_memory()
|
mem = psutil.virtual_memory()
|
||||||
freePerc = 1-mem.percent/100
|
freePerc = mem.percent/100
|
||||||
self.updateLevel(freePerc)
|
self.updateLevel(freePerc)
|
||||||
|
|
||||||
if self.state < 1:
|
if self.state < 1:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
text = Text(Section.ramp(freePerc))
|
text = Text(Section.ramp(1-freePerc))
|
||||||
if self.state >= 2:
|
if self.state >= 2:
|
||||||
freeStr = humanSize(mem.available)
|
freeStr = humanSize(mem.available)
|
||||||
text.append(freeStr)
|
text.append(freeStr)
|
||||||
|
@ -162,7 +165,8 @@ class TemperatureProvider(AlertingSection, PeriodicUpdater):
|
||||||
|
|
||||||
|
|
||||||
class BatteryProvider(AlertingSection, PeriodicUpdater):
|
class BatteryProvider(AlertingSection, PeriodicUpdater):
|
||||||
NUMBER_STATES = 2
|
# TODO Support ACPID for events
|
||||||
|
NUMBER_STATES = 3
|
||||||
RAMP = ""
|
RAMP = ""
|
||||||
|
|
||||||
def fetcher(self):
|
def fetcher(self):
|
||||||
|
@ -179,8 +183,15 @@ class BatteryProvider(AlertingSection, PeriodicUpdater):
|
||||||
if self.state < 1:
|
if self.state < 1:
|
||||||
return
|
return
|
||||||
|
|
||||||
return Text('{:.0f}%'.format(bat.percent))
|
t = Text('{:.0f}%'.format(bat.percent))
|
||||||
# TODO Time remaining (if the estimation is somewhat correct)
|
|
||||||
|
if self.state < 2:
|
||||||
|
return t
|
||||||
|
|
||||||
|
h = int(bat.secsleft / 3600)
|
||||||
|
m = int((bat.secsleft - h * 3600) / 60)
|
||||||
|
t.append(" ({:d}:{:02d})".format(h, m))
|
||||||
|
return t
|
||||||
|
|
||||||
def __init__(self, theme=None):
|
def __init__(self, theme=None):
|
||||||
AlertingSection.__init__(self, theme)
|
AlertingSection.__init__(self, theme)
|
||||||
|
@ -189,10 +200,13 @@ class BatteryProvider(AlertingSection, PeriodicUpdater):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PulseaudioProvider(Section, ThreadedUpdater):
|
class PulseaudioProvider(StatefulSection, ThreadedUpdater):
|
||||||
|
NUMBER_STATES = 3
|
||||||
|
DEFAULT_STATE = 1
|
||||||
|
|
||||||
def __init__(self, theme=None):
|
def __init__(self, theme=None):
|
||||||
ThreadedUpdater.__init__(self)
|
ThreadedUpdater.__init__(self)
|
||||||
Section.__init__(self, theme)
|
StatefulSection.__init__(self, theme)
|
||||||
self.pulseEvents = pulsectl.Pulse('event-handler')
|
self.pulseEvents = pulsectl.Pulse('event-handler')
|
||||||
|
|
||||||
self.pulseEvents.event_mask_set(pulsectl.PulseEventMaskEnum.sink)
|
self.pulseEvents.event_mask_set(pulsectl.PulseEventMaskEnum.sink)
|
||||||
|
@ -205,20 +219,32 @@ class PulseaudioProvider(Section, ThreadedUpdater):
|
||||||
sinks = []
|
sinks = []
|
||||||
with pulsectl.Pulse('list-sinks') as pulse:
|
with pulsectl.Pulse('list-sinks') as pulse:
|
||||||
for sink in pulse.sink_list():
|
for sink in pulse.sink_list():
|
||||||
vol = pulse.volume_get_all_chans(sink)
|
|
||||||
if vol > 1:
|
|
||||||
vol = 1
|
|
||||||
|
|
||||||
if sink.port_active.name == "analog-output-headphones":
|
if sink.port_active.name == "analog-output-headphones":
|
||||||
icon = ""
|
icon = ""
|
||||||
elif sink.port_active.name == "analog-output-speaker":
|
elif sink.port_active.name == "analog-output-speaker":
|
||||||
icon = ""
|
icon = "" if sink.mute else ""
|
||||||
else:
|
else:
|
||||||
icon = "?"
|
icon = "?"
|
||||||
|
vol = pulse.volume_get_all_chans(sink)
|
||||||
|
fg = (sink.mute and '#333333') or (vol > 1 and '#FF0000') or None
|
||||||
|
|
||||||
ramp = "" if sink.mute else (" " + self.ramp(vol))
|
t = Text(icon, fg=fg)
|
||||||
sinks.append(icon + ramp)
|
sinks.append(t)
|
||||||
return " ".join(sinks)
|
|
||||||
|
if self.state < 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if self.state < 2:
|
||||||
|
if not sink.mute:
|
||||||
|
ramp = " "
|
||||||
|
while vol >= 0:
|
||||||
|
ramp += self.ramp(vol if vol < 1 else 1)
|
||||||
|
vol -= 1
|
||||||
|
t.append(ramp)
|
||||||
|
else:
|
||||||
|
t.append(" {:2.0f}%".format(vol*100))
|
||||||
|
|
||||||
|
return Text(*sinks)
|
||||||
|
|
||||||
def loop(self):
|
def loop(self):
|
||||||
self.pulseEvents.event_listen()
|
self.pulseEvents.event_listen()
|
||||||
|
@ -230,6 +256,7 @@ class PulseaudioProvider(Section, ThreadedUpdater):
|
||||||
class NetworkProviderSection(StatefulSection, Updater):
|
class NetworkProviderSection(StatefulSection, Updater):
|
||||||
|
|
||||||
NUMBER_STATES = 5
|
NUMBER_STATES = 5
|
||||||
|
DEFAULT_STATE = 1
|
||||||
|
|
||||||
def actType(self):
|
def actType(self):
|
||||||
self.ssid = None
|
self.ssid = None
|
||||||
|
@ -260,6 +287,8 @@ class NetworkProviderSection(StatefulSection, Updater):
|
||||||
return ipv4, ipv6
|
return ipv4, ipv6
|
||||||
|
|
||||||
def fetcher(self):
|
def fetcher(self):
|
||||||
|
self.icon = None
|
||||||
|
self.persistent = False
|
||||||
if self.iface not in self.parent.stats or \
|
if self.iface not in self.parent.stats or \
|
||||||
not self.parent.stats[self.iface].isup or \
|
not self.parent.stats[self.iface].isup or \
|
||||||
self.iface.startswith('lo'):
|
self.iface.startswith('lo'):
|
||||||
|
@ -364,6 +393,41 @@ class NetworkProvider(Section, PeriodicUpdater):
|
||||||
self.fetchData()
|
self.fetchData()
|
||||||
self.changeInterval(5)
|
self.changeInterval(5)
|
||||||
|
|
||||||
|
class RfkillProvider(Section, PeriodicUpdater):
|
||||||
|
# TODO FEAT rfkill doesn't seem to indicate that the hardware switch is
|
||||||
|
# toggled
|
||||||
|
PATH = '/sys/class/rfkill'
|
||||||
|
|
||||||
|
def fetcher(self):
|
||||||
|
t = Text()
|
||||||
|
for device in os.listdir(self.PATH):
|
||||||
|
with open(os.path.join(self.PATH, device, 'soft'), 'rb') as f:
|
||||||
|
softBlocked = f.read().strip() != b'0'
|
||||||
|
with open(os.path.join(self.PATH, device, 'hard'), 'rb') as f:
|
||||||
|
hardBlocked = f.read().strip() != b'0'
|
||||||
|
|
||||||
|
if not hardBlocked and not softBlocked:
|
||||||
|
continue
|
||||||
|
|
||||||
|
with open(os.path.join(self.PATH, device, 'type'), 'rb') as f:
|
||||||
|
typ = f.read().strip()
|
||||||
|
|
||||||
|
fg = (hardBlocked and '#CCCCCC') or (softBlocked and '#FF0000')
|
||||||
|
if typ == b'wlan':
|
||||||
|
icon = ''
|
||||||
|
elif typ == b'bluetooth':
|
||||||
|
icon = ''
|
||||||
|
else:
|
||||||
|
icon = '?'
|
||||||
|
|
||||||
|
t.append(Text(icon, fg=fg))
|
||||||
|
return t
|
||||||
|
|
||||||
|
def __init__(self, theme=None):
|
||||||
|
PeriodicUpdater.__init__(self)
|
||||||
|
Section.__init__(self, theme)
|
||||||
|
self.changeInterval(5)
|
||||||
|
|
||||||
class SshAgentProvider(PeriodicUpdater):
|
class SshAgentProvider(PeriodicUpdater):
|
||||||
def fetcher(self):
|
def fetcher(self):
|
||||||
cmd = ["ssh-add", "-l"]
|
cmd = ["ssh-add", "-l"]
|
||||||
|
@ -405,6 +469,7 @@ class GpgAgentProvider(PeriodicUpdater):
|
||||||
self.changeInterval(5)
|
self.changeInterval(5)
|
||||||
|
|
||||||
class KeystoreProvider(Section, MergedUpdater):
|
class KeystoreProvider(Section, MergedUpdater):
|
||||||
|
# TODO OPTI+FEAT Use ColorCountsSection and not MergedUpdater, this is useless
|
||||||
ICON = ''
|
ICON = ''
|
||||||
|
|
||||||
def __init__(self, theme=None):
|
def __init__(self, theme=None):
|
||||||
|
@ -412,8 +477,6 @@ class KeystoreProvider(Section, MergedUpdater):
|
||||||
Section.__init__(self, theme)
|
Section.__init__(self, theme)
|
||||||
|
|
||||||
class NotmuchUnreadProvider(ColorCountsSection, InotifyUpdater):
|
class NotmuchUnreadProvider(ColorCountsSection, InotifyUpdater):
|
||||||
# TODO OPTI Transform InotifyUpdater (watching notmuch folder should be
|
|
||||||
# enough)
|
|
||||||
COLORABLE_ICON = ''
|
COLORABLE_ICON = ''
|
||||||
|
|
||||||
def subfetcher(self):
|
def subfetcher(self):
|
||||||
|
@ -456,7 +519,6 @@ class TodoProvider(ColorCountsSection, InotifyUpdater):
|
||||||
COLORABLE_ICON = ''
|
COLORABLE_ICON = ''
|
||||||
|
|
||||||
def updateCalendarList(self):
|
def updateCalendarList(self):
|
||||||
print(459)
|
|
||||||
calendars = sorted(os.listdir(self.dir))
|
calendars = sorted(os.listdir(self.dir))
|
||||||
for calendar in calendars:
|
for calendar in calendars:
|
||||||
# If the calendar wasn't in the list
|
# If the calendar wasn't in the list
|
||||||
|
@ -473,7 +535,6 @@ class TodoProvider(ColorCountsSection, InotifyUpdater):
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
self.colors[calendar] = f.read().strip()
|
self.colors[calendar] = f.read().strip()
|
||||||
self.calendars = calendars
|
self.calendars = calendars
|
||||||
print(475, self.calendars)
|
|
||||||
|
|
||||||
def __init__(self, dir, theme=None):
|
def __init__(self, dir, theme=None):
|
||||||
"""
|
"""
|
||||||
|
@ -539,6 +600,9 @@ class I3WorkspacesProviderSection(Section):
|
||||||
else:
|
else:
|
||||||
return self.parent.themeNormal
|
return self.parent.themeNormal
|
||||||
|
|
||||||
|
# TODO On mode change the state (shown / hidden) gets overriden so every
|
||||||
|
# tab is shown
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
self.updateTheme(self.selectTheme())
|
self.updateTheme(self.selectTheme())
|
||||||
self.updateText(self.fullName if self.focused else self.shortName)
|
self.updateText(self.fullName if self.focused else self.shortName)
|
||||||
|
@ -553,10 +617,15 @@ class I3WorkspacesProviderSection(Section):
|
||||||
self.fullName = self.parent.customNames[name] \
|
self.fullName = self.parent.customNames[name] \
|
||||||
if name in self.parent.customNames else name
|
if name in self.parent.customNames else name
|
||||||
|
|
||||||
|
def switchTo(self):
|
||||||
|
self.parent.i3.command('workspace {}'.format(self.shortName))
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, name, parent):
|
def __init__(self, name, parent):
|
||||||
Section.__init__(self)
|
Section.__init__(self)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.setName(name)
|
self.setName(name)
|
||||||
|
self.setDecorators(clickLeft=self.switchTo)
|
||||||
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
self.updateTheme(self.parent.themeNormal)
|
self.updateTheme(self.parent.themeNormal)
|
||||||
|
@ -564,7 +633,7 @@ class I3WorkspacesProviderSection(Section):
|
||||||
|
|
||||||
|
|
||||||
class I3WorkspacesProvider(Section, I3Updater):
|
class I3WorkspacesProvider(Section, I3Updater):
|
||||||
# TODO Multi-screen
|
# TODO FEAT Multi-screen
|
||||||
|
|
||||||
def initialPopulation(self, parent):
|
def initialPopulation(self, parent):
|
||||||
"""
|
"""
|
||||||
|
@ -674,10 +743,13 @@ class MpdProvider(Section, ThreadedUpdater):
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def fetcher(self):
|
def fetcher(self):
|
||||||
cur = self.mpd.currentsong()
|
stat = self.mpd.status()
|
||||||
|
if not len(stat) or stat["state"] == "stop":
|
||||||
|
return None
|
||||||
|
|
||||||
|
cur = self.mpd.currentsong()
|
||||||
if not len(cur):
|
if not len(cur):
|
||||||
return ''
|
return None
|
||||||
|
|
||||||
infos = []
|
infos = []
|
||||||
|
|
||||||
|
|
|
@ -190,10 +190,16 @@ class ThreadedUpdaterThread(threading.Thread):
|
||||||
def __init__(self, updater, *args, **kwargs):
|
def __init__(self, updater, *args, **kwargs):
|
||||||
self.updater = updater
|
self.updater = updater
|
||||||
threading.Thread.__init__(self, *args, **kwargs)
|
threading.Thread.__init__(self, *args, **kwargs)
|
||||||
|
self.looping = True
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
try:
|
||||||
self.updater.loop()
|
while self.looping:
|
||||||
|
self.updater.loop()
|
||||||
|
except BaseException as e:
|
||||||
|
log.error("Error with {}".format(self.updater))
|
||||||
|
log.error(e, exc_info=True)
|
||||||
|
self.updater.updateText("")
|
||||||
|
|
||||||
|
|
||||||
class ThreadedUpdater(Updater):
|
class ThreadedUpdater(Updater):
|
||||||
|
|
|
@ -76,7 +76,8 @@ enable-ipc = true
|
||||||
inherit = bar/base
|
inherit = bar/base
|
||||||
|
|
||||||
modules-center = mpd
|
modules-center = mpd
|
||||||
modules-right = cpu memory temperature mail todo vpncheck eth wlan bbswitch xbacklight volume battery shortdate
|
; modules-right = cpu memory temperature mail todo vpncheck eth wlan bbswitch xbacklight volume battery shortdate
|
||||||
|
modules-right = cpu memory temperature mail vpncheck eth wlan bbswitch xbacklight volume battery shortdate
|
||||||
|
|
||||||
tray-position = right
|
tray-position = right
|
||||||
tray-padding = 2
|
tray-padding = 2
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
/home/geoffrey/.local/share/systemd/user/mbsync.timer
|
|
|
@ -1 +0,0 @@
|
||||||
/usr/lib/systemd/user/syncthing.service
|
|
159
scripts/archive
159
scripts/archive
|
@ -1,31 +1,139 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import coloredlogs
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Place a folder in ~/Documents in ~/Documents/Archives and symlink it")
|
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
||||||
parser.add_argument('dir', metavar='DIRECTORY', type=str, help="The directory to archive")
|
log = logging.getLogger()
|
||||||
parser.add_argument('-d', '--dry', action='store_true')
|
|
||||||
args = parser.parse_args()
|
# Coding conventions:
|
||||||
|
# No leading or trailing slashes. Let os.path.join do its job
|
||||||
|
|
||||||
|
# TODO Config arparse and pass args to the functions. No globals
|
||||||
|
|
||||||
# Finding directories
|
# Finding directories
|
||||||
assert('HOME' in os.environ), "Home directory unknown"
|
assert 'HOME' in os.environ, "Home directory unknown"
|
||||||
docs = os.path.realpath(os.path.join(os.environ['HOME'], 'Documents'))
|
DOCS = os.path.realpath(os.path.join(os.environ['HOME'], 'Documents'))
|
||||||
assert(os.path.isdir(docs)), "Documents folder not found"
|
assert os.path.isdir(DOCS), "Documents folder not found"
|
||||||
arcs = os.path.join(docs, 'Archives')
|
ARCS = os.path.realpath(os.path.join(os.environ['HOME'], 'Archives'))
|
||||||
assert(os.path.isdir(arcs)), "Archives folder not found"
|
assert os.path.isdir(ARCS), "Archives folder not found"
|
||||||
|
|
||||||
|
|
||||||
|
def dirRange(relpath):
|
||||||
|
splits = relpath.split(os.path.sep)
|
||||||
|
res = list()
|
||||||
|
|
||||||
|
for p in range(len(splits)):
|
||||||
|
partPath = os.path.join(*splits[:p+1])
|
||||||
|
|
||||||
|
arcPath = os.path.join(os.path.join(ARCS, partPath))
|
||||||
|
docPath = os.path.join(os.path.join(DOCS, partPath))
|
||||||
|
|
||||||
|
res.append((docPath, arcPath))
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def travel(relpath):
|
||||||
|
"""
|
||||||
|
Dunno what this will do, let's write code and see.
|
||||||
|
"""
|
||||||
|
wholeRange = dirRange(relpath)
|
||||||
|
for tup in wholeRange:
|
||||||
|
isLast = wholeRange[-1] == tup
|
||||||
|
docPath, arcPath = tup
|
||||||
|
linkPath = os.path.relpath(arcPath, start=docPath)
|
||||||
|
|
||||||
|
log.debug(f"47 {tup}")
|
||||||
|
|
||||||
|
if not os.path.exists(docPath) and not os.path.exists(arcPath):
|
||||||
|
log.error("Not existing")
|
||||||
|
sys.exit(1)
|
||||||
|
elif os.path.isdir(docPath) and os.path.isdir(arcPath) and not isLast:
|
||||||
|
log.debug("Both folder")
|
||||||
|
continue
|
||||||
|
elif os.path.isdir(docPath) and os.path.isdir(arcPath) and isLast:
|
||||||
|
log.error("This should fail for some reason, maybe")
|
||||||
|
sys.exit(1)
|
||||||
|
elif os.path.islink(docPath) and os.path.exists(arcPath):
|
||||||
|
currentLink = os.readlink(docPath)
|
||||||
|
if currentLink != linkPath:
|
||||||
|
log.warning(f"'{docPath}' is pointing to '{currentLink}' " +
|
||||||
|
f"but should point to '{linkPath}'.")
|
||||||
|
# TODO Fixing if asked for
|
||||||
|
sys.exit(1)
|
||||||
|
log.debug("Early link already exists {docPath} → {arcPath}")
|
||||||
|
return
|
||||||
|
elif not os.path.exists(docPath) and os.path.exists(arcPath):
|
||||||
|
log.debug("Only existing on archive side, linking")
|
||||||
|
print(f"ln -s {linkPath} {docPath}")
|
||||||
|
elif os.path.exists(docPath) and not os.path.exists(arcPath) \
|
||||||
|
and isLast:
|
||||||
|
log.debug("Only existing on doc side, moving and linking")
|
||||||
|
print(f"mv {docPath} {arcPath}")
|
||||||
|
print(f"ln -s {linkPath} {docPath}")
|
||||||
|
elif os.path.exists(docPath) and not os.path.exists(arcPath) \
|
||||||
|
and not isLast:
|
||||||
|
raise NotImplementedError("Here comes the trouble")
|
||||||
|
else:
|
||||||
|
log.error("Unhandled case")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def ensureLink(relpath):
|
||||||
|
"""
|
||||||
|
Ensure that ~/Documents/$relpath points to ~/Archives/$relpath
|
||||||
|
"""
|
||||||
|
arcPath = os.path.join(os.path.join(ARCS, relpath))
|
||||||
|
docPath = os.path.join(os.path.join(DOCS, relpath))
|
||||||
|
assert os.path.exists(arcPath)
|
||||||
|
|
||||||
|
# For each tree element of the path
|
||||||
|
for docPath, arcPath in dirRange(relpath):
|
||||||
|
linkPath = os.path.relpath(arcPath, start=docPath)
|
||||||
|
|
||||||
|
def installLink():
|
||||||
|
if args.dry:
|
||||||
|
print(f"ln -s {linkPath} {docPath}")
|
||||||
|
else:
|
||||||
|
os.symlink(linkPath, docPath)
|
||||||
|
|
||||||
|
if os.path.islink(docPath):
|
||||||
|
currentLink = os.readlink(docPath)
|
||||||
|
if currentLink != linkPath:
|
||||||
|
log.warning(f"'{docPath}' is pointing to '{currentLink}' " +
|
||||||
|
f"but should point to '{linkPath}'. Fixing")
|
||||||
|
if args.dry:
|
||||||
|
print(f"rm {docPath}")
|
||||||
|
else:
|
||||||
|
os.unlink(docPath)
|
||||||
|
installLink()
|
||||||
|
return
|
||||||
|
elif not os.path.exists(docPath):
|
||||||
|
installLink()
|
||||||
|
return
|
||||||
|
elif os.path.isdir(docPath):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
raise RuntimeError(f"'{docPath}' exists and is not a directory " +
|
||||||
|
f"or a link. Unable to link it to '{linkPath}'")
|
||||||
|
raise RuntimeError(f"'{docPath}' is a directory. Unable to link it to " +
|
||||||
|
f"'{linkPath}'")
|
||||||
|
|
||||||
|
|
||||||
def archive(docdir):
|
def archive(docdir):
|
||||||
docdir = os.path.realpath(args.dir)
|
docdir = os.path.realpath(args.dir)
|
||||||
assert(os.path.isdir(docdir)), docdir + " must be a directory"
|
assert os.path.isdir(docdir), docdir + " must be a directory"
|
||||||
|
|
||||||
assert(docdir.startswith(docs)), "Directory is not in the document folder"
|
assert docdir.startswith(DOCS), "Directory is not in the document folder"
|
||||||
assert(not docdir.startswith(arcs)), "Directory is already in the archive folder"
|
assert not docdir.startswith(ARCS), "Directory is already in the archive folder"
|
||||||
|
|
||||||
reldir = os.path.relpath(docdir, docs)
|
reldir = os.path.relpath(docdir, DOCS)
|
||||||
print("ARC", reldir)
|
print("ARC", reldir)
|
||||||
|
|
||||||
arcdir = os.path.join(arcs, reldir)
|
arcdir = os.path.join(ARCS, reldir)
|
||||||
parentArcdir = os.path.realpath(os.path.join(arcdir, '..'))
|
parentArcdir = os.path.realpath(os.path.join(arcdir, '..'))
|
||||||
parentDocdir = os.path.realpath(os.path.join(docdir, '..'))
|
parentDocdir = os.path.realpath(os.path.join(docdir, '..'))
|
||||||
linkDest = os.path.relpath(arcdir, parentDocdir)
|
linkDest = os.path.relpath(arcdir, parentDocdir)
|
||||||
|
@ -35,9 +143,9 @@ def archive(docdir):
|
||||||
# If the directory exists
|
# If the directory exists
|
||||||
if os.path.isdir(arcdir):
|
if os.path.isdir(arcdir):
|
||||||
return
|
return
|
||||||
# for f in os.listdir(arcdir):
|
# for f in os.listdir(arcdir):
|
||||||
# assert(os.path.isdir(f)), "Something unknown in Archive dir")
|
# assert os.path.isdir(f), "Something unknown in Archive dir")
|
||||||
# archive(os.path.join(arcdir, f))
|
# archive(os.path.join(arcdir, f))
|
||||||
|
|
||||||
# If the directory doesn't exist, create the directories under it and move all the folder
|
# If the directory doesn't exist, create the directories under it and move all the folder
|
||||||
else:
|
else:
|
||||||
|
@ -58,8 +166,17 @@ def archive(docdir):
|
||||||
os.symlink(linkDest, docdir)
|
os.symlink(linkDest, docdir)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def unarchive(arcdir):
|
def unarchive(arcdir):
|
||||||
return
|
pass
|
||||||
|
|
||||||
archive(args.dir)
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Place a folder in ~/Documents in ~/Documents/Archives and symlink it")
|
||||||
|
parser.add_argument('dir', metavar='DIRECTORY', type=str, help="The directory to archive")
|
||||||
|
parser.add_argument('-d', '--dry', action='store_true')
|
||||||
|
args = parser.parse_args()
|
||||||
|
args.dry = True # DEBUG
|
||||||
|
|
||||||
|
# archive(args.dir)
|
||||||
|
ensureLink(args.dir)
|
||||||
|
|
|
@ -21,30 +21,18 @@ function prompt { # text
|
||||||
}
|
}
|
||||||
|
|
||||||
# Don't ask for things that are already there
|
# Don't ask for things that are already there
|
||||||
if which pacaur &> /dev/null; then
|
if which aurman &> /dev/null; then
|
||||||
PACAUR=1
|
AURMAN=1
|
||||||
fi
|
fi
|
||||||
if which bauerbill &> /dev/null; then
|
if [ -z $AURMAN ]; then
|
||||||
BAUERBILL=1
|
prompt "Do you want aurman on this machine?"
|
||||||
|
AURMAN=$?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z $PACAUR ]; then
|
|
||||||
prompt "Do you want pacaur on this machine?"
|
|
||||||
PACAUR=$?
|
|
||||||
fi
|
|
||||||
if [ $PACAUR == 1 ]; then
|
|
||||||
if [ -z $BAUERBILL ]; then
|
|
||||||
prompt "Do you want bauerbill on this machine?"
|
|
||||||
BAUERBILL=$?
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
BAUERBILL=0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# COMMON
|
# COMMON
|
||||||
|
|
||||||
# Install packages if they aren't installed
|
# Install packages if they aren't installed
|
||||||
function inst {
|
function inst {
|
||||||
|
# Could also use --needed but, meh
|
||||||
for pkg in $*; do
|
for pkg in $*; do
|
||||||
pacman -Q $pkg &> /dev/null
|
pacman -Q $pkg &> /dev/null
|
||||||
if [ $? == 1 ]; then
|
if [ $? == 1 ]; then
|
||||||
|
@ -69,14 +57,13 @@ inst wget
|
||||||
|
|
||||||
# Aur
|
# Aur
|
||||||
|
|
||||||
pacman -Q pacaur &> /dev/null
|
pacman -Q aurman &> /dev/null
|
||||||
if [[ $PACAUR == 1 && $? == 1 ]]; then
|
if [[ $AURMAN == 1 && $? == 1 ]]; then
|
||||||
installPKGBUILD "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=cower"
|
installPKGBUILD "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=aurman"
|
||||||
installPKGBUILD "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=pacaur"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Git for /etc
|
# Git for /etc
|
||||||
sudo pacman -S etckeeper --noconfirm --needed
|
inst etckeeper
|
||||||
sudo etckeeper init
|
sudo etckeeper init
|
||||||
sudo etckeeper commit "~/.dotfiles/scripts/install-arch commit"
|
sudo etckeeper commit "~/.dotfiles/scripts/install-arch commit"
|
||||||
|
|
||||||
|
@ -86,25 +73,11 @@ if pacman -Q pamac &> /dev/null ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ccache
|
# Ccache
|
||||||
sudo pacman -S ccache --noconfirm --needed
|
inst ccache
|
||||||
sudo sed 's|BUILDENV=\(.\+\)!ccache\(.\+\)|BUILDENV=\1ccache\2|' /etc/makepkg.conf -i
|
sudo sed 's|BUILDENV=\(.\+\)!ccache\(.\+\)|BUILDENV=\1ccache\2|' /etc/makepkg.conf -i
|
||||||
|
|
||||||
# Bauerbill
|
|
||||||
pacman -Q bauerbill &> /dev/null
|
|
||||||
if [[ $BAUERBILL == 1 && $? == 1 ]]; then
|
|
||||||
sudo pacman -Sy
|
|
||||||
|
|
||||||
gpg --recv-keys 1D1F0DC78F173680
|
|
||||||
installPKGBUILD http://xyne.archlinux.ca/projects/reflector/pkgbuild/PKGBUILD
|
|
||||||
pacaur -S bauerbill --noconfirm --noedit
|
|
||||||
|
|
||||||
bauerbill -Su --noconfirm
|
|
||||||
else
|
|
||||||
sudo pacman -Syu
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TLP
|
# TLP
|
||||||
sudo pacman -S tlp --noconfirm --needed
|
inst tlp
|
||||||
sudo sed 's|SATA_LINKPWR_ON_BAT=min_power|SATA_LINKPWR_ON_BAT=max_performance|' /etc/default/tlp -i
|
sudo sed 's|SATA_LINKPWR_ON_BAT=min_power|SATA_LINKPWR_ON_BAT=max_performance|' /etc/default/tlp -i
|
||||||
sudo systemctl enable tlp.service tlp-sleep.service
|
sudo systemctl enable tlp.service tlp-sleep.service
|
||||||
sudo systemctl disable systemd-rfkill.service systemd-rfkill.socket
|
sudo systemctl disable systemd-rfkill.service systemd-rfkill.socket
|
||||||
|
@ -117,7 +90,7 @@ echo -e "[Service]\nExecStartPre=/bin/sh -c 'setleds +num < /dev/%I'" | sudo sys
|
||||||
sudo sed "s|#MAKEFLAGS=\"-j2\"|MAKEFLAGS=\"-j$(nproc)\"|" /etc/makepkg.conf -i
|
sudo sed "s|#MAKEFLAGS=\"-j2\"|MAKEFLAGS=\"-j$(nproc)\"|" /etc/makepkg.conf -i
|
||||||
|
|
||||||
# Time synchronisation
|
# Time synchronisation
|
||||||
sudo pacman -S ntp --noconfirm --needed
|
inst ntp
|
||||||
sudo systemctl start ntpd
|
sudo systemctl start ntpd
|
||||||
sudo systemctl enable ntpd
|
sudo systemctl enable ntpd
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,14 @@ if which pacman &> /dev/null; then
|
||||||
function installFileOne { # file
|
function installFileOne { # file
|
||||||
sudo pacman -U "$1"
|
sudo pacman -U "$1"
|
||||||
}
|
}
|
||||||
if which pacaur &> /dev/null; then
|
if which aurman &> /dev/null; then
|
||||||
|
function altInstallOne { # package
|
||||||
|
pacman -Q $1 &> /dev/null
|
||||||
|
if [ $? == 1 ]; then
|
||||||
|
aurman -S "$1" --noconfirm --noedit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
elif which pacaur &> /dev/null; then
|
||||||
function altInstallOne { # package
|
function altInstallOne { # package
|
||||||
pacman -Q $1 &> /dev/null
|
pacman -Q $1 &> /dev/null
|
||||||
if [ $? == 1 ]; then
|
if [ $? == 1 ]; then
|
||||||
|
@ -174,10 +181,11 @@ function systemdUserUnit {
|
||||||
|
|
||||||
# Common CLI
|
# Common CLI
|
||||||
|
|
||||||
|
changeColors monokai
|
||||||
|
|
||||||
# Utils
|
# Utils
|
||||||
inst coreutils man openssl-tool grep sed sh tar
|
|
||||||
if [ $TERMUX == 1 ]; then
|
if [ $TERMUX == 1 ]; then
|
||||||
|
inst coreutils man openssl-tool grep sed sh tar
|
||||||
inst termux-api
|
inst termux-api
|
||||||
if [ $ADMIN == 1 ]; then
|
if [ $ADMIN == 1 ]; then
|
||||||
inst tsu
|
inst tsu
|
||||||
|
@ -186,17 +194,10 @@ fi
|
||||||
inst moreutils screen ncdu lsof htop proxytunnel pv curl wget netcat mosh bash-completion rsync pwgen fzf highlight
|
inst moreutils screen ncdu lsof htop proxytunnel pv curl wget netcat mosh bash-completion rsync pwgen fzf highlight
|
||||||
# TODO Test those who are on Debian machines and those who aren't
|
# TODO Test those who are on Debian machines and those who aren't
|
||||||
if [ $ARCH == 1 ]; then
|
if [ $ARCH == 1 ]; then
|
||||||
inst bash-completion tldr
|
inst bash-completion
|
||||||
altInst gopass
|
altInst gopass
|
||||||
else
|
else
|
||||||
inst pass
|
inst pass
|
||||||
wget -qO ~/.local/bin/ https://raw.githubusercontent.com/pepa65/tldr-bash-client/master/tldr
|
|
||||||
chmod +x ~/.local/bin/tldr
|
|
||||||
fi
|
|
||||||
tldr -u
|
|
||||||
if [[ $ARCH == 1 && $ADMIN == 1 ]]; then
|
|
||||||
inst pkgfile
|
|
||||||
sudo systemctl enable pkgfile-update.timer
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Dev
|
# Dev
|
||||||
|
@ -207,20 +208,17 @@ elif [ $ARCH == 1 ]; then
|
||||||
else
|
else
|
||||||
inst make
|
inst make
|
||||||
fi
|
fi
|
||||||
inst git
|
inst git
|
||||||
|
|
||||||
|
|
||||||
# Text editor
|
# Text editor
|
||||||
if [ $TERMUX == 1 ]; then
|
inst neovim
|
||||||
inst vim-python
|
if [ $DEBIAN == 1]; then
|
||||||
elif [ $DEBIAN == 1 ]; then
|
inst python-neovim pyhon3-neovim
|
||||||
inst vim-nox
|
elif [ $ARCH == 1]; then
|
||||||
if [ $ADMIN == 0 ]; then
|
inst python2-neovim python-neovim
|
||||||
debloc altern vim nox
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
inst vim
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $DEBIAN == 1 ]; then
|
if [ $DEBIAN == 1 ]; then
|
||||||
inst exuberant-ctags
|
inst exuberant-ctags
|
||||||
else
|
else
|
||||||
|
@ -233,54 +231,13 @@ if [ $GUI == 1 ]; then
|
||||||
.Xresources.d/configure
|
.Xresources.d/configure
|
||||||
|
|
||||||
# Desktop manager
|
# Desktop manager
|
||||||
inst i3 i3lock dunst unclutter xautolock feh numlockx scrot rxvt-unicode xclip
|
inst dunst feh i3-wm i3lock numlockx qutebrowser rofi rxvt-unicode scrot trayer unclutter xautolock xclip
|
||||||
curl "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/a8386aae19e200ddb0f6845b5feeee5eb7013687/fonts/fontawesome-webfont.ttf" > ~/.local/share/fonts/fontawesome-webfont.ttf
|
|
||||||
if [ $ARCH == 1 ]; then
|
if [ $ARCH == 1 ]; then
|
||||||
inst xorg-xinit
|
inst xorg-xinit xorg-backlight
|
||||||
altInst polybar-git autorandr-git keynav-enhanced pacmixer
|
altInst lemonbar-xft-git autorandr-git keynav-enhanced pacmixer rofi-pass
|
||||||
else
|
elif [ $DEBIAN == 1 ]; then
|
||||||
# Compiling polybar
|
# TODO autorandr pacmixer rofi-pass
|
||||||
if ! which polybar > /dev/null; then
|
inst lemonbar keynav xbacklight
|
||||||
inst debhelper cmake libxcb-icccm4-dev libxcb-image0-dev libxcb-randr0-dev libx11-dev libxcb1-dev libxcb-util-dev libx11-xcb-dev linux-libc-dev libboost-dev x11proto-core-dev libxcb-ewmh-dev libxft-dev libasound2-dev libiw-dev libmpdclient-dev xcb-proto python-xcbgen libxcb-xkb-dev i3-wm libcairo2-dev libxcb-xrm-dev
|
|
||||||
# TODO Figure which one are really needed
|
|
||||||
#inst libasound2 libc6 libgcc1 libiw30 libmpdclient2 libstdc++6 libx11-6 libx11-xcb1 libxcb-ewmh2 libxcb-icccm4 libxcb-randr0 libxcb-xkb1 libxcb1 libxft2
|
|
||||||
# ↓ really needed
|
|
||||||
inst libcairo2-dev libxcb-xkb-dev libxcb-randr0-dev xcb-proto libxcb-image0-dev libxcb-icccm4-dev libxcb-ewmh-dev libxcb-util0-dev python-xcbgen
|
|
||||||
|
|
||||||
TMP=$(mktemp -d)
|
|
||||||
git clone --branch 3.0.5 --recursive https://github.com/jaagr/polybar $TMP
|
|
||||||
mkdir $TMP/build
|
|
||||||
cd $TMP/build
|
|
||||||
cmake ..
|
|
||||||
make -j`nproc`
|
|
||||||
strip bin/polybar
|
|
||||||
mv bin/polybar ~/.local/bin/
|
|
||||||
rm -rf $TMP
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ $DEBIAN == 1 ]; then
|
|
||||||
inst suckless-tools keynav
|
|
||||||
if [ $ADMIN == 0 ]; then
|
|
||||||
debloc altern dmenu xft
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
inst dmenu
|
|
||||||
fi
|
|
||||||
if [ "$(source /etc/os-release; echo $NAME)" == "Manjaro Linux" ]; then
|
|
||||||
inst menda-themes menda-circle-icon-theme xcursor-menda
|
|
||||||
fi
|
|
||||||
|
|
||||||
# qutebrowser
|
|
||||||
if [ $DEBIAN == 1 ]; then
|
|
||||||
inst python3-lxml python-tox python3-pyqt5 python3-pyqt5.qtwebkit python3-pyqt5.qtquick python3-sip python3-jinja2 python3-pygments python3-yaml python3-pyqt5.qtsql libqt5sql5-sqlite python3-pyqt5.qtwebengine python3-pyqt5.qtopengl python3-opengl
|
|
||||||
TMP_DIR=$(mktemp -d)
|
|
||||||
$(cd $TMP_DIR; wget https://qutebrowser.org/python3-pypeg2_2.15.2-1_all.deb)
|
|
||||||
$(cd $TMP_DIR; wget https://github.com/qutebrowser/qutebrowser/releases/download/v0.11.0/qutebrowser_0.11.0-1_all.deb)
|
|
||||||
instFile $TMP_DIR/*.deb
|
|
||||||
rm -rf $TMP_DIR
|
|
||||||
|
|
||||||
elif [ $ARCH == 1 ]; then
|
|
||||||
inst qutebrowser qt5-webengine python-opengl
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Screen filter
|
# Screen filter
|
||||||
|
@ -294,48 +251,47 @@ if [ $GUI == 1 ]; then
|
||||||
rm $TMP
|
rm $TMP
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Graphical vim
|
|
||||||
if [ $DEBIAN == 1 ]; then
|
|
||||||
inst vim-gtk
|
|
||||||
else
|
|
||||||
inst gvim
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ $EXTRA == 1 ]; then
|
if [ $EXTRA == 1 ]; then
|
||||||
# Extra dev
|
# Extra dev (not on mobile though ^^)
|
||||||
inst cmake clang llvm npm
|
if [ $TERMUX == 0 ]; then
|
||||||
inst python-rope
|
inst cmake clang llvm ccache python-pip
|
||||||
|
fi
|
||||||
|
|
||||||
# Extra CLI
|
# Extra CLI
|
||||||
inst ffmpeg youtube-dl optipng syncthing ccache mutt
|
inst ffmpeg optipng syncthing mutt jq
|
||||||
systemdUserUnit syncthing.service
|
systemdUserUnit syncthing
|
||||||
if [ $ARCH == 1 ]; then
|
if [ $ARCH == 1 ]; then
|
||||||
inst jq
|
insta pandoc youtube-dl translate-shell
|
||||||
altInst pdftk translate-shell git-lfs js-beautify insect visidata-git
|
altInst insect pdftk visidata
|
||||||
|
|
||||||
# Orga
|
# Orga
|
||||||
# TODO For others
|
# TODO For others
|
||||||
inst vdirsyncer khard
|
inst vdirsyncer khard todoman offlineimap khal
|
||||||
altInst khal todoman offlineimap
|
|
||||||
systemdUserUnit vdirsyncer.timer
|
systemdUserUnit vdirsyncer.timer
|
||||||
|
elif [ $DEBIAN == 1]; then
|
||||||
|
inst pandoc pdftk visidata translate-shell youtube-dl
|
||||||
else
|
else
|
||||||
# translate-shell
|
# translate-shell
|
||||||
curl -L git.io/trans > ~/.local/bin/trans
|
curl -L git.io/trans > ~/.local/bin/trans
|
||||||
chmod +x ~/.local/bin/trans
|
chmod +x ~/.local/bin/trans
|
||||||
|
|
||||||
|
# TODO Others
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Extra GUI
|
# Extra GUI
|
||||||
if [ $GUI == 1 ]; then
|
if [ $GUI == 1 ]; then
|
||||||
inst vlc gimp mpd thunar noto-fonts-emoji musescore
|
inst vlc gimp mpd thunar musescore evince pdfpc texlive-{most,lang}
|
||||||
|
|
||||||
if [ $ARCH == 1 ]; then
|
if [ $ARCH == 1 ]; then
|
||||||
inst simplescreenrecorder
|
inst simplescreenrecorder mpc
|
||||||
altInst pacmixer xcursor-menda-git menda-themes-git menda-maia-icon-theme vimpc-git mpc ashuffle-git
|
altInst vimpc-git ashuffle-git ttf-emojione-color
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# TODO Others
|
||||||
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
22
scripts/unziptree
Executable file
22
scripts/unziptree
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk("."):
|
||||||
|
for name in files:
|
||||||
|
base, ext = os.path.splitext(name)
|
||||||
|
if ext.lower() != ".zip":
|
||||||
|
continue
|
||||||
|
|
||||||
|
filepath = os.path.join(root, name)
|
||||||
|
dirpath = os.path.join(root, base)
|
||||||
|
print(filepath)
|
||||||
|
|
||||||
|
os.mkdir(dirpath)
|
||||||
|
|
||||||
|
cmd = ["unzip", os.path.realpath(filepath)]
|
||||||
|
r = subprocess.run(cmd, cwd=dirpath)
|
||||||
|
r.check_returncode()
|
||||||
|
|
||||||
|
os.unlink(filepath)
|
6
vimrc
6
vimrc
|
@ -58,6 +58,8 @@ Plug 'junegunn/fzf.vim'
|
||||||
Plug 'ervandew/supertab'
|
Plug 'ervandew/supertab'
|
||||||
Plug 'dpelle/vim-LanguageTool'
|
Plug 'dpelle/vim-LanguageTool'
|
||||||
Plug 'terryma/vim-smooth-scroll'
|
Plug 'terryma/vim-smooth-scroll'
|
||||||
|
Plug 'vim-pandoc/vim-pandoc'
|
||||||
|
Plug 'vim-pandoc/vim-pandoc-syntax'
|
||||||
|
|
||||||
call plug#end()
|
call plug#end()
|
||||||
|
|
||||||
|
@ -143,6 +145,10 @@ let g:SuperTabContextDefaultCompletionType = "<c-n>"
|
||||||
|
|
||||||
let g:languagetool_jar = "/usr/share/java/languagetool/languagetool-commandline.jar"
|
let g:languagetool_jar = "/usr/share/java/languagetool/languagetool-commandline.jar"
|
||||||
|
|
||||||
|
""" vim-pandoc """
|
||||||
|
let g:pandoc#modules#disabled = ["folding"]
|
||||||
|
let g:pandoc#syntax#conceal#use = 0
|
||||||
|
|
||||||
|
|
||||||
""" VIM SETTINGS """
|
""" VIM SETTINGS """
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue