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
|
||||
wget -c http://raw.githubusercontent.com/powerline/fonts/master/DejaVuSansMono/DejaVu%20Sans%20Mono$i%20for%20Powerline.ttf
|
||||
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'
|
||||
|
||||
#Brightness control
|
||||
bindsym XF86MonBrightnessDown exec xbacklight -dec 20
|
||||
bindsym XF86MonBrightnessUp exec xbacklight -inc 20
|
||||
bindsym XF86MonBrightnessDown exec xbacklight -dec 20 -time 0
|
||||
bindsym XF86MonBrightnessUp exec xbacklight -inc 20 -time 0
|
||||
|
||||
# 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+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
|
||||
for_window [title="pacmixer"] floating enable border pixel 2
|
||||
for_window [class="Firefox"] layout tabbed
|
||||
|
@ -353,6 +346,7 @@ set_from_resource $color15 i3wm.color15 #cfd0c2
|
|||
|
||||
# Inactivity settings
|
||||
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+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 keynav # Keyboard cursor controller
|
||||
#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 ~/.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.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(I3WindowTitleProvider(), BarGroupType.LEFT)
|
||||
|
||||
# TODO Computer modes
|
||||
|
||||
SYSTEM_THEME = 2
|
||||
DANGER_THEME = FOCUS_THEME
|
||||
|
@ -40,6 +41,7 @@ if __name__ == "__main__":
|
|||
# TODO Disk space provider
|
||||
# TODO Screen (connected, autorandr configuration, bbswitch) provider
|
||||
Bar.addSectionAll(PulseaudioProvider(theme=PERIPHERAL_THEME), BarGroupType.RIGHT)
|
||||
Bar.addSectionAll(RfkillProvider(theme=PERIPHERAL_THEME), BarGroupType.RIGHT)
|
||||
Bar.addSectionAll(NetworkProvider(theme=NETWORK_THEME), BarGroupType.RIGHT)
|
||||
|
||||
# Personal
|
||||
|
@ -50,3 +52,5 @@ if __name__ == "__main__":
|
|||
|
||||
TIME_THEME = 6
|
||||
Bar.addSectionAll(TimeProvider(theme=TIME_THEME), BarGroupType.RIGHT)
|
||||
|
||||
# Bar.run()
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
import enum
|
||||
import threading
|
||||
import time
|
||||
import i3ipc
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import logging
|
||||
import coloredlogs
|
||||
|
@ -10,6 +13,7 @@ import coloredlogs
|
|||
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
||||
log = logging.getLogger()
|
||||
|
||||
|
||||
# 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
|
||||
# but easier)
|
||||
|
@ -18,6 +22,7 @@ log = logging.getLogger()
|
|||
# TODO Use bytes rather than strings
|
||||
# TODO Use default colors of lemonbar sometimes
|
||||
# TODO Adapt bar height with font height
|
||||
# TODO OPTI Static text objects that update its parents if modified
|
||||
|
||||
|
||||
class BarGroupType(enum.Enum):
|
||||
|
@ -30,7 +35,7 @@ class BarGroupType(enum.Enum):
|
|||
|
||||
class BarStdoutThread(threading.Thread):
|
||||
def run(self):
|
||||
while True:
|
||||
while Bar.running:
|
||||
handle = Bar.process.stdout.readline().strip()
|
||||
if not len(handle):
|
||||
continue
|
||||
|
@ -52,6 +57,7 @@ class Bar:
|
|||
|
||||
@staticmethod
|
||||
def init():
|
||||
Bar.running = True
|
||||
Section.init()
|
||||
|
||||
cmd = ['lemonbar', '-b', '-a', '64']
|
||||
|
@ -66,10 +72,35 @@ class Bar:
|
|||
Bar(0)
|
||||
# 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
|
||||
everyone = set()
|
||||
string = ""
|
||||
process = None
|
||||
running = False
|
||||
|
||||
nextHandle = 0
|
||||
actionsF2H = dict()
|
||||
|
@ -92,8 +123,11 @@ class Bar:
|
|||
|
||||
@staticmethod
|
||||
def forever():
|
||||
while True:
|
||||
time.sleep(60)
|
||||
try:
|
||||
while True:
|
||||
time.sleep(60)
|
||||
except BaseException:
|
||||
Bar.stop()
|
||||
|
||||
def __init__(self, screen):
|
||||
assert isinstance(screen, int)
|
||||
|
@ -136,15 +170,16 @@ class Bar:
|
|||
@staticmethod
|
||||
def updateAll():
|
||||
|
||||
Bar.string = ""
|
||||
for bar in Bar.everyone:
|
||||
bar.update()
|
||||
Bar.string += bar.string
|
||||
# Color for empty sections
|
||||
Bar.string += BarGroup.color(*Section.EMPTY)
|
||||
if Bar.running:
|
||||
Bar.string = ""
|
||||
for bar in Bar.everyone:
|
||||
bar.update()
|
||||
Bar.string += bar.string
|
||||
# Color for empty sections
|
||||
Bar.string += BarGroup.color(*Section.EMPTY)
|
||||
|
||||
Bar.process.stdin.write(bytes(Bar.string + '\n', 'utf-8'))
|
||||
Bar.process.stdin.flush()
|
||||
Bar.process.stdin.write(bytes(Bar.string + '\n', 'utf-8'))
|
||||
Bar.process.stdin.flush()
|
||||
|
||||
|
||||
class BarGroup:
|
||||
|
@ -276,11 +311,14 @@ class SectionThread(threading.Thread):
|
|||
class Section:
|
||||
|
||||
# TODO Update all of that to base16
|
||||
COLORS = ['#002b36', '#dc322f', '#859900', '#b58900', '#268bd2', '#6c71c4',
|
||||
'#2aa198', '#93a1a1', '#657b83', '#dc322f', '#859900', '#b58900',
|
||||
'#268bd2', '#6c71c4', '#2aa198', '#fdf6e3']
|
||||
FGCOLOR = '#93a1a1'
|
||||
BGCOLOR = '#002b36'
|
||||
# COLORS = ['#272822', '#383830', '#49483e', '#75715e', '#a59f85', '#f8f8f2',
|
||||
# '#f5f4f1', '#f9f8f5', '#f92672', '#fd971f', '#f4bf75', '#a6e22e',
|
||||
# '#a1efe4', '#66d9ef', '#ae81ff', '#cc6633']
|
||||
COLORS = ['#181818', '#AB4642', '#A1B56C', '#F7CA88', '#7CAFC2', '#BA8BAF',
|
||||
'#86C1B9', '#D8D8D8', '#585858', '#AB4642', '#A1B56C', '#F7CA88',
|
||||
'#7CAFC2', '#BA8BAF', '#86C1B9', '#F8F8F8']
|
||||
FGCOLOR = '#F8F8F2'
|
||||
BGCOLOR = '#272822'
|
||||
|
||||
THEMES = list()
|
||||
EMPTY = (FGCOLOR, BGCOLOR)
|
||||
|
@ -357,6 +395,8 @@ class Section:
|
|||
def updateText(self, text):
|
||||
if isinstance(text, str):
|
||||
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[1] = text
|
||||
|
@ -373,6 +413,12 @@ class Section:
|
|||
Section.sizeChanging.add(self)
|
||||
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):
|
||||
assert isinstance(theme, int)
|
||||
assert theme < len(Section.THEMES)
|
||||
|
@ -440,13 +486,14 @@ class Section:
|
|||
class StatefulSection(Section):
|
||||
# TODO FEAT Allow to temporary expand the section (e.g. when important change)
|
||||
NUMBER_STATES = None
|
||||
DEFAULT_STATE = 0
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
Section.__init__(self, *args, **kwargs)
|
||||
self.state = 0
|
||||
self.state = self.DEFAULT_STATE
|
||||
if hasattr(self, 'onChangeState'):
|
||||
self.onChangeState(self.state)
|
||||
self.dstText.setDecorators(clickLeft=self.incrementState,
|
||||
self.setDecorators(clickLeft=self.incrementState,
|
||||
clickRight=self.decrementState)
|
||||
|
||||
def incrementState(self):
|
||||
|
@ -466,6 +513,9 @@ class StatefulSection(Section):
|
|||
self.refreshData()
|
||||
|
||||
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
|
||||
COLORABLE_ICON = '?'
|
||||
|
||||
|
@ -552,6 +602,8 @@ class Text:
|
|||
nest('A' + number + ':' + handle.decode() + ':', 'A' + number)
|
||||
|
||||
for key, val in self.decorators.items():
|
||||
if val is None:
|
||||
continue
|
||||
if key == 'fg':
|
||||
reset = self.section.THEMES[self.section.theme][0]
|
||||
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')
|
||||
log = logging.getLogger()
|
||||
|
||||
# TODO Generator class (for I3WorkspacesProvider, NetworkProvider and later
|
||||
# PulseaudioProvider and MpdProvider)
|
||||
|
||||
def humanSize(num):
|
||||
"""
|
||||
|
@ -43,6 +45,7 @@ class TimeProvider(StatefulSection, PeriodicUpdater):
|
|||
"%d/%m %H:%M:%S",
|
||||
"%a %d/%m/%y %H:%M:%S"]
|
||||
NUMBER_STATES = len(FORMATS)
|
||||
DEFAULT_STATE = 1
|
||||
|
||||
def fetcher(self):
|
||||
now = datetime.datetime.now()
|
||||
|
@ -114,13 +117,13 @@ class RamProvider(AlertingSection, PeriodicUpdater):
|
|||
|
||||
def fetcher(self):
|
||||
mem = psutil.virtual_memory()
|
||||
freePerc = 1-mem.percent/100
|
||||
freePerc = mem.percent/100
|
||||
self.updateLevel(freePerc)
|
||||
|
||||
if self.state < 1:
|
||||
return None
|
||||
|
||||
text = Text(Section.ramp(freePerc))
|
||||
text = Text(Section.ramp(1-freePerc))
|
||||
if self.state >= 2:
|
||||
freeStr = humanSize(mem.available)
|
||||
text.append(freeStr)
|
||||
|
@ -162,7 +165,8 @@ class TemperatureProvider(AlertingSection, PeriodicUpdater):
|
|||
|
||||
|
||||
class BatteryProvider(AlertingSection, PeriodicUpdater):
|
||||
NUMBER_STATES = 2
|
||||
# TODO Support ACPID for events
|
||||
NUMBER_STATES = 3
|
||||
RAMP = ""
|
||||
|
||||
def fetcher(self):
|
||||
|
@ -179,8 +183,15 @@ class BatteryProvider(AlertingSection, PeriodicUpdater):
|
|||
if self.state < 1:
|
||||
return
|
||||
|
||||
return Text('{:.0f}%'.format(bat.percent))
|
||||
# TODO Time remaining (if the estimation is somewhat correct)
|
||||
t = Text('{:.0f}%'.format(bat.percent))
|
||||
|
||||
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):
|
||||
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):
|
||||
ThreadedUpdater.__init__(self)
|
||||
Section.__init__(self, theme)
|
||||
StatefulSection.__init__(self, theme)
|
||||
self.pulseEvents = pulsectl.Pulse('event-handler')
|
||||
|
||||
self.pulseEvents.event_mask_set(pulsectl.PulseEventMaskEnum.sink)
|
||||
|
@ -205,20 +219,32 @@ class PulseaudioProvider(Section, ThreadedUpdater):
|
|||
sinks = []
|
||||
with pulsectl.Pulse('list-sinks') as pulse:
|
||||
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":
|
||||
icon = ""
|
||||
elif sink.port_active.name == "analog-output-speaker":
|
||||
icon = ""
|
||||
icon = "" if sink.mute else ""
|
||||
else:
|
||||
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))
|
||||
sinks.append(icon + ramp)
|
||||
return " ".join(sinks)
|
||||
t = Text(icon, fg=fg)
|
||||
sinks.append(t)
|
||||
|
||||
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):
|
||||
self.pulseEvents.event_listen()
|
||||
|
@ -230,6 +256,7 @@ class PulseaudioProvider(Section, ThreadedUpdater):
|
|||
class NetworkProviderSection(StatefulSection, Updater):
|
||||
|
||||
NUMBER_STATES = 5
|
||||
DEFAULT_STATE = 1
|
||||
|
||||
def actType(self):
|
||||
self.ssid = None
|
||||
|
@ -260,6 +287,8 @@ class NetworkProviderSection(StatefulSection, Updater):
|
|||
return ipv4, ipv6
|
||||
|
||||
def fetcher(self):
|
||||
self.icon = None
|
||||
self.persistent = False
|
||||
if self.iface not in self.parent.stats or \
|
||||
not self.parent.stats[self.iface].isup or \
|
||||
self.iface.startswith('lo'):
|
||||
|
@ -364,6 +393,41 @@ class NetworkProvider(Section, PeriodicUpdater):
|
|||
self.fetchData()
|
||||
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):
|
||||
def fetcher(self):
|
||||
cmd = ["ssh-add", "-l"]
|
||||
|
@ -405,6 +469,7 @@ class GpgAgentProvider(PeriodicUpdater):
|
|||
self.changeInterval(5)
|
||||
|
||||
class KeystoreProvider(Section, MergedUpdater):
|
||||
# TODO OPTI+FEAT Use ColorCountsSection and not MergedUpdater, this is useless
|
||||
ICON = ''
|
||||
|
||||
def __init__(self, theme=None):
|
||||
|
@ -412,8 +477,6 @@ class KeystoreProvider(Section, MergedUpdater):
|
|||
Section.__init__(self, theme)
|
||||
|
||||
class NotmuchUnreadProvider(ColorCountsSection, InotifyUpdater):
|
||||
# TODO OPTI Transform InotifyUpdater (watching notmuch folder should be
|
||||
# enough)
|
||||
COLORABLE_ICON = ''
|
||||
|
||||
def subfetcher(self):
|
||||
|
@ -456,7 +519,6 @@ class TodoProvider(ColorCountsSection, InotifyUpdater):
|
|||
COLORABLE_ICON = ''
|
||||
|
||||
def updateCalendarList(self):
|
||||
print(459)
|
||||
calendars = sorted(os.listdir(self.dir))
|
||||
for calendar in calendars:
|
||||
# If the calendar wasn't in the list
|
||||
|
@ -473,7 +535,6 @@ class TodoProvider(ColorCountsSection, InotifyUpdater):
|
|||
with open(path, 'r') as f:
|
||||
self.colors[calendar] = f.read().strip()
|
||||
self.calendars = calendars
|
||||
print(475, self.calendars)
|
||||
|
||||
def __init__(self, dir, theme=None):
|
||||
"""
|
||||
|
@ -539,6 +600,9 @@ class I3WorkspacesProviderSection(Section):
|
|||
else:
|
||||
return self.parent.themeNormal
|
||||
|
||||
# TODO On mode change the state (shown / hidden) gets overriden so every
|
||||
# tab is shown
|
||||
|
||||
def show(self):
|
||||
self.updateTheme(self.selectTheme())
|
||||
self.updateText(self.fullName if self.focused else self.shortName)
|
||||
|
@ -553,10 +617,15 @@ class I3WorkspacesProviderSection(Section):
|
|||
self.fullName = self.parent.customNames[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):
|
||||
Section.__init__(self)
|
||||
self.parent = parent
|
||||
self.setName(name)
|
||||
self.setDecorators(clickLeft=self.switchTo)
|
||||
|
||||
def empty(self):
|
||||
self.updateTheme(self.parent.themeNormal)
|
||||
|
@ -564,7 +633,7 @@ class I3WorkspacesProviderSection(Section):
|
|||
|
||||
|
||||
class I3WorkspacesProvider(Section, I3Updater):
|
||||
# TODO Multi-screen
|
||||
# TODO FEAT Multi-screen
|
||||
|
||||
def initialPopulation(self, parent):
|
||||
"""
|
||||
|
@ -674,10 +743,13 @@ class MpdProvider(Section, ThreadedUpdater):
|
|||
self.start()
|
||||
|
||||
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):
|
||||
return ''
|
||||
return None
|
||||
|
||||
infos = []
|
||||
|
||||
|
|
|
@ -190,10 +190,16 @@ class ThreadedUpdaterThread(threading.Thread):
|
|||
def __init__(self, updater, *args, **kwargs):
|
||||
self.updater = updater
|
||||
threading.Thread.__init__(self, *args, **kwargs)
|
||||
self.looping = True
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
self.updater.loop()
|
||||
try:
|
||||
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):
|
||||
|
|
|
@ -76,7 +76,8 @@ enable-ipc = true
|
|||
inherit = bar/base
|
||||
|
||||
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-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
|
||||
|
||||
import os
|
||||
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")
|
||||
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()
|
||||
coloredlogs.install(level='DEBUG', fmt='%(levelname)s %(message)s')
|
||||
log = logging.getLogger()
|
||||
|
||||
# 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
|
||||
assert('HOME' in os.environ), "Home directory unknown"
|
||||
docs = os.path.realpath(os.path.join(os.environ['HOME'], 'Documents'))
|
||||
assert(os.path.isdir(docs)), "Documents folder not found"
|
||||
arcs = os.path.join(docs, 'Archives')
|
||||
assert(os.path.isdir(arcs)), "Archives folder not found"
|
||||
assert 'HOME' in os.environ, "Home directory unknown"
|
||||
DOCS = os.path.realpath(os.path.join(os.environ['HOME'], 'Documents'))
|
||||
assert os.path.isdir(DOCS), "Documents folder not found"
|
||||
ARCS = os.path.realpath(os.path.join(os.environ['HOME'], 'Archives'))
|
||||
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):
|
||||
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(not docdir.startswith(arcs)), "Directory is already in the archive folder"
|
||||
assert docdir.startswith(DOCS), "Directory is not in the document 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)
|
||||
|
||||
arcdir = os.path.join(arcs, reldir)
|
||||
arcdir = os.path.join(ARCS, reldir)
|
||||
parentArcdir = os.path.realpath(os.path.join(arcdir, '..'))
|
||||
parentDocdir = os.path.realpath(os.path.join(docdir, '..'))
|
||||
linkDest = os.path.relpath(arcdir, parentDocdir)
|
||||
|
@ -35,9 +143,9 @@ def archive(docdir):
|
|||
# If the directory exists
|
||||
if os.path.isdir(arcdir):
|
||||
return
|
||||
# for f in os.listdir(arcdir):
|
||||
# assert(os.path.isdir(f)), "Something unknown in Archive dir")
|
||||
# archive(os.path.join(arcdir, f))
|
||||
# for f in os.listdir(arcdir):
|
||||
# assert os.path.isdir(f), "Something unknown in Archive dir")
|
||||
# archive(os.path.join(arcdir, f))
|
||||
|
||||
# If the directory doesn't exist, create the directories under it and move all the folder
|
||||
else:
|
||||
|
@ -58,8 +166,17 @@ def archive(docdir):
|
|||
os.symlink(linkDest, docdir)
|
||||
|
||||
|
||||
|
||||
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
|
||||
if which pacaur &> /dev/null; then
|
||||
PACAUR=1
|
||||
if which aurman &> /dev/null; then
|
||||
AURMAN=1
|
||||
fi
|
||||
if which bauerbill &> /dev/null; then
|
||||
BAUERBILL=1
|
||||
if [ -z $AURMAN ]; then
|
||||
prompt "Do you want aurman on this machine?"
|
||||
AURMAN=$?
|
||||
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
|
||||
|
||||
# Install packages if they aren't installed
|
||||
function inst {
|
||||
# Could also use --needed but, meh
|
||||
for pkg in $*; do
|
||||
pacman -Q $pkg &> /dev/null
|
||||
if [ $? == 1 ]; then
|
||||
|
@ -69,14 +57,13 @@ inst wget
|
|||
|
||||
# Aur
|
||||
|
||||
pacman -Q pacaur &> /dev/null
|
||||
if [[ $PACAUR == 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=pacaur"
|
||||
pacman -Q aurman &> /dev/null
|
||||
if [[ $AURMAN == 1 && $? == 1 ]]; then
|
||||
installPKGBUILD "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=aurman"
|
||||
fi
|
||||
|
||||
# Git for /etc
|
||||
sudo pacman -S etckeeper --noconfirm --needed
|
||||
inst etckeeper
|
||||
sudo etckeeper init
|
||||
sudo etckeeper commit "~/.dotfiles/scripts/install-arch commit"
|
||||
|
||||
|
@ -86,25 +73,11 @@ if pacman -Q pamac &> /dev/null ; then
|
|||
fi
|
||||
|
||||
# Ccache
|
||||
sudo pacman -S ccache --noconfirm --needed
|
||||
inst ccache
|
||||
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
|
||||
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 systemctl enable tlp.service tlp-sleep.service
|
||||
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
|
||||
|
||||
# Time synchronisation
|
||||
sudo pacman -S ntp --noconfirm --needed
|
||||
inst ntp
|
||||
sudo systemctl start ntpd
|
||||
sudo systemctl enable ntpd
|
||||
|
||||
|
|
|
@ -54,7 +54,14 @@ if which pacman &> /dev/null; then
|
|||
function installFileOne { # file
|
||||
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
|
||||
pacman -Q $1 &> /dev/null
|
||||
if [ $? == 1 ]; then
|
||||
|
@ -174,10 +181,11 @@ function systemdUserUnit {
|
|||
|
||||
# Common CLI
|
||||
|
||||
changeColors monokai
|
||||
|
||||
# Utils
|
||||
inst coreutils man openssl-tool grep sed sh tar
|
||||
if [ $TERMUX == 1 ]; then
|
||||
inst coreutils man openssl-tool grep sed sh tar
|
||||
inst termux-api
|
||||
if [ $ADMIN == 1 ]; then
|
||||
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
|
||||
# TODO Test those who are on Debian machines and those who aren't
|
||||
if [ $ARCH == 1 ]; then
|
||||
inst bash-completion tldr
|
||||
inst bash-completion
|
||||
altInst gopass
|
||||
else
|
||||
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
|
||||
|
||||
# Dev
|
||||
|
@ -211,16 +212,13 @@ inst git
|
|||
|
||||
|
||||
# Text editor
|
||||
if [ $TERMUX == 1 ]; then
|
||||
inst vim-python
|
||||
elif [ $DEBIAN == 1 ]; then
|
||||
inst vim-nox
|
||||
if [ $ADMIN == 0 ]; then
|
||||
debloc altern vim nox
|
||||
fi
|
||||
else
|
||||
inst vim
|
||||
inst neovim
|
||||
if [ $DEBIAN == 1]; then
|
||||
inst python-neovim pyhon3-neovim
|
||||
elif [ $ARCH == 1]; then
|
||||
inst python2-neovim python-neovim
|
||||
fi
|
||||
|
||||
if [ $DEBIAN == 1 ]; then
|
||||
inst exuberant-ctags
|
||||
else
|
||||
|
@ -233,54 +231,13 @@ if [ $GUI == 1 ]; then
|
|||
.Xresources.d/configure
|
||||
|
||||
# Desktop manager
|
||||
inst i3 i3lock dunst unclutter xautolock feh numlockx scrot rxvt-unicode xclip
|
||||
curl "https://raw.githubusercontent.com/FortAwesome/Font-Awesome/a8386aae19e200ddb0f6845b5feeee5eb7013687/fonts/fontawesome-webfont.ttf" > ~/.local/share/fonts/fontawesome-webfont.ttf
|
||||
inst dunst feh i3-wm i3lock numlockx qutebrowser rofi rxvt-unicode scrot trayer unclutter xautolock xclip
|
||||
if [ $ARCH == 1 ]; then
|
||||
inst xorg-xinit
|
||||
altInst polybar-git autorandr-git keynav-enhanced pacmixer
|
||||
else
|
||||
# Compiling polybar
|
||||
if ! which polybar > /dev/null; then
|
||||
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
|
||||
inst xorg-xinit xorg-backlight
|
||||
altInst lemonbar-xft-git autorandr-git keynav-enhanced pacmixer rofi-pass
|
||||
elif [ $DEBIAN == 1 ]; then
|
||||
# TODO autorandr pacmixer rofi-pass
|
||||
inst lemonbar keynav xbacklight
|
||||
fi
|
||||
|
||||
# Screen filter
|
||||
|
@ -294,48 +251,47 @@ if [ $GUI == 1 ]; then
|
|||
rm $TMP
|
||||
fi
|
||||
fi
|
||||
|
||||
# Graphical vim
|
||||
if [ $DEBIAN == 1 ]; then
|
||||
inst vim-gtk
|
||||
else
|
||||
inst gvim
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ $EXTRA == 1 ]; then
|
||||
# Extra dev
|
||||
inst cmake clang llvm npm
|
||||
inst python-rope
|
||||
# Extra dev (not on mobile though ^^)
|
||||
if [ $TERMUX == 0 ]; then
|
||||
inst cmake clang llvm ccache python-pip
|
||||
fi
|
||||
|
||||
# Extra CLI
|
||||
inst ffmpeg youtube-dl optipng syncthing ccache mutt
|
||||
systemdUserUnit syncthing.service
|
||||
inst ffmpeg optipng syncthing mutt jq
|
||||
systemdUserUnit syncthing
|
||||
if [ $ARCH == 1 ]; then
|
||||
inst jq
|
||||
altInst pdftk translate-shell git-lfs js-beautify insect visidata-git
|
||||
insta pandoc youtube-dl translate-shell
|
||||
altInst insect pdftk visidata
|
||||
|
||||
# Orga
|
||||
# TODO For others
|
||||
inst vdirsyncer khard
|
||||
altInst khal todoman offlineimap
|
||||
inst vdirsyncer khard todoman offlineimap khal
|
||||
systemdUserUnit vdirsyncer.timer
|
||||
elif [ $DEBIAN == 1]; then
|
||||
inst pandoc pdftk visidata translate-shell youtube-dl
|
||||
else
|
||||
# translate-shell
|
||||
curl -L git.io/trans > ~/.local/bin/trans
|
||||
chmod +x ~/.local/bin/trans
|
||||
|
||||
# TODO Others
|
||||
fi
|
||||
|
||||
# Extra GUI
|
||||
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
|
||||
inst simplescreenrecorder
|
||||
altInst pacmixer xcursor-menda-git menda-themes-git menda-maia-icon-theme vimpc-git mpc ashuffle-git
|
||||
inst simplescreenrecorder mpc
|
||||
altInst vimpc-git ashuffle-git ttf-emojione-color
|
||||
fi
|
||||
|
||||
# TODO Others
|
||||
|
||||
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 'dpelle/vim-LanguageTool'
|
||||
Plug 'terryma/vim-smooth-scroll'
|
||||
Plug 'vim-pandoc/vim-pandoc'
|
||||
Plug 'vim-pandoc/vim-pandoc-syntax'
|
||||
|
||||
call plug#end()
|
||||
|
||||
|
@ -143,6 +145,10 @@ let g:SuperTabContextDefaultCompletionType = "<c-n>"
|
|||
|
||||
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 """
|
||||
|
||||
|
|
Loading…
Reference in a new issue