dotfiles

Obligatory dotfiles repo
git clone git://git.danielmoch.com/dotfiles.git
Log | Files | Refs

commit 25cf064ed2ef0e94ea7cade7cafad541ee306b9c
parent 33894c9338b138940d60964aa85417c2f3862283
Author: Daniel Moch <daniel@danielmoch.com>
Date:   Wed,  1 Jan 2020 07:52:27 -0500

Re-organize $HOME

Treat $HOME as a root, which /bin, /lib, etc..

This will require that some XDG variables be added to my environment,
so add xdg.sh to profile.d.

Diffstat:
D.config/awesome/rc.lua | 557-------------------------------------------------------------------------------
D.config/awesome/theme.lua | 69---------------------------------------------------------------------
D.config/dunst/dunstrc | 68--------------------------------------------------------------------
D.config/khal/config | 23-----------------------
D.config/khard/khard.conf | 39---------------------------------------
D.config/todoman/todoman.conf | 7-------
M.gitconfig | 4++--
D.local/bin/fws | 16----------------
D.local/bin/my | 443-------------------------------------------------------------------------------
D.local/bin/my-init | 254-------------------------------------------------------------------------------
D.local/bin/my-netrc | 46----------------------------------------------
D.local/bin/my-open | 118-------------------------------------------------------------------------------
D.local/bin/my-perms | 36------------------------------------
D.local/lib/cron.avail/cloudsync.sh | 99-------------------------------------------------------------------------------
D.local/lib/cron.avail/weather.sh | 12------------
D.local/lib/forecastio/weather.py | 91-------------------------------------------------------------------------------
D.local/lib/tmux/battery_indicator.sh | 17-----------------
D.local/man/man1/my.1 | 201-------------------------------------------------------------------------------
D.muttrc | 203-------------------------------------------------------------------------------
M.profile | 2+-
D.profile.d/env.sh | 5-----
D.profile.d/go.sh | 6------
D.profile.d/my.sh | 1-
D.shrc | 13-------------
M.tmux.conf | 4++--
M.w3m/config | 60++++++++++++++++++++++++++++++------------------------------
R.local/bin/dviprint -> bin/dviprint | 0
Abin/fws | 16++++++++++++++++
R.local/bin/ix -> bin/ix | 0
Abin/my | 443+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abin/my-init | 254+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abin/my-netrc | 46++++++++++++++++++++++++++++++++++++++++++++++
Abin/my-open | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abin/my-perms | 36++++++++++++++++++++++++++++++++++++
R.local/bin/sncli-export -> bin/sncli-export | 0
R.local/bin/tmux-session -> bin/tmux-session | 0
R.config/autostart/xbindkeys.desktop -> etc/autostart/xbindkeys.desktop | 0
Aetc/awesome/rc.lua | 557+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aetc/awesome/theme.lua | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aetc/dunst/dunstrc | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
R.config/gtk-3.0/settings.ini -> etc/gtk-3.0/settings.ini | 0
R.config/homebrew/brew_leaves.txt -> etc/homebrew/brew_leaves.txt | 0
R.config/homebrew/brew_leaves_head.txt -> etc/homebrew/brew_leaves_head.txt | 0
R.config/homebrew/brew_setup.sh -> etc/homebrew/brew_setup.sh | 0
R.config/i3/config -> etc/i3/config | 0
Aetc/khal/config | 23+++++++++++++++++++++++
Aetc/khard/khard.conf | 39+++++++++++++++++++++++++++++++++++++++
Aetc/mutt/muttrc | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
R.config/nncli/config -> etc/nncli/config | 0
R.config/pacman/makepkg.conf -> etc/pacman/makepkg.conf | 0
R.profile.d/brew.sh -> etc/profile.d/brew.sh | 0
R.profile.d/browser.sh -> etc/profile.d/browser.sh | 0
R.profile.d/cargo.sh -> etc/profile.d/cargo.sh | 0
R.profile.d/editor.sh -> etc/profile.d/editor.sh | 0
Aetc/profile.d/env.sh | 5+++++
Aetc/profile.d/go.sh | 6++++++
R.profile.d/gpg.sh -> etc/profile.d/gpg.sh | 0
R.profile.d/hostname.sh -> etc/profile.d/hostname.sh | 0
R.profile.d/logname.sh -> etc/profile.d/logname.sh | 0
Aetc/profile.d/my.sh | 1+
R.profile.d/pager.sh -> etc/profile.d/pager.sh | 0
R.profile.d/sh.sh -> etc/profile.d/sh.sh | 0
R.profile.d/visual.sh -> etc/profile.d/visual.sh | 0
Aetc/profile.d/xdg.sh | 4++++
Aetc/shrc | 13+++++++++++++
R.shrc.d/dotfiles.sh -> etc/shrc.d/dotfiles.sh | 0
R.shrc.d/feh.sh -> etc/shrc.d/feh.sh | 0
R.shrc.d/gpg.sh -> etc/shrc.d/gpg.sh | 0
R.shrc.d/motd.sh -> etc/shrc.d/motd.sh | 0
R.shrc.d/num.sh -> etc/shrc.d/num.sh | 0
R.shrc.d/proj.sh -> etc/shrc.d/proj.sh | 0
R.shrc.d/ps1.sh -> etc/shrc.d/ps1.sh | 0
R.shrc.d/rsync.sh -> etc/shrc.d/rsync.sh | 0
R.shrc.d/ssh.sh -> etc/shrc.d/ssh.sh | 0
R.shrc.d/tmux.sh -> etc/shrc.d/tmux.sh | 0
Aetc/todoman/todoman.conf | 7+++++++
R.config/urlwatch/hooks.py -> etc/urlwatch/hooks.py | 0
R.config/urlwatch/urls.yaml -> etc/urlwatch/urls.yaml | 0
R.config/urlwatch/urlwatch.yaml -> etc/urlwatch/urlwatch.yaml | 0
R.config/vis/ctags.lua -> etc/vis/ctags.lua | 0
R.config/vis/themes/djmoch.lua -> etc/vis/themes/djmoch.lua | 0
R.config/vis/vis-commentary.lua -> etc/vis/vis-commentary.lua | 0
R.config/vis/visrc.lua -> etc/vis/visrc.lua | 0
Alib/cron.avail/cloudsync.sh | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
R.local/lib/cron.avail/dc_backup.sh -> lib/cron.avail/dc_backup.sh | 0
R.local/lib/cron.avail/vdirsyncer.sh -> lib/cron.avail/vdirsyncer.sh | 0
Alib/cron.avail/weather.sh | 12++++++++++++
R.local/lib/forecastio/org.djmoch.forecastio.plist -> lib/forecastio/org.djmoch.forecastio.plist | 0
Alib/forecastio/weather.py | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
R.local/lib/gitdir/hooks/ctags -> lib/gitdir/hooks/ctags | 0
R.local/lib/gitdir/hooks/post-checkout -> lib/gitdir/hooks/post-checkout | 0
R.local/lib/gitdir/hooks/post-commit -> lib/gitdir/hooks/post-commit | 0
R.local/lib/gitdir/hooks/post-merge -> lib/gitdir/hooks/post-merge | 0
R.local/lib/gitdir/hooks/post-rewrite -> lib/gitdir/hooks/post-rewrite | 0
R.local/lib/gitdir/hooks/pre-commit -> lib/gitdir/hooks/pre-commit | 0
R.local/lib/gitdir/hooks/prepare-commit-msg -> lib/gitdir/hooks/prepare-commit-msg | 0
R.local/lib/gitdir/info/attributes -> lib/gitdir/info/attributes | 0
R.local/lib/terminfo/tmux-from-screen.terminfo -> lib/terminfo/tmux-from-screen.terminfo | 0
R.local/lib/terminfo/tmux.terminfo -> lib/terminfo/tmux.terminfo | 0
Alib/tmux/battery_indicator.sh | 17+++++++++++++++++
Aman/man1/my.1 | 201+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
R.local/man/man5/my-open.config.5 -> man/man5/my-open.config.5 | 0
102 files changed, 2363 insertions(+), 2359 deletions(-)

diff --git a/.config/awesome/rc.lua b/.config/awesome/rc.lua @@ -1,557 +0,0 @@ --- --- ~/.config/awesome/rc.lua --- - --- Standard awesome library -local gears = require("gears") -local awful = require("awful") -require("awful.autofocus") --- Widget and layout library -local wibox = require("wibox") --- Theme handling library -local beautiful = require("beautiful") --- Notification library -local naughty = require("naughty") -local menubar = require("menubar") -local hotkeys_popup = require("awful.hotkeys_popup").widget --- Enable hotkeys help widget for VIM and other apps --- when client with a matching name is opened: -require("awful.hotkeys_popup.keys") - --- {{{ Error handling --- Check if awesome encountered an error during startup and fell back to --- another config (This code will only ever execute for the fallback config) -if awesome.startup_errors then - naughty.notify({ preset = naughty.config.presets.critical, - title = "Oops, there were errors during startup!", - text = awesome.startup_errors }) -end - --- Handle runtime errors after startup -do - local in_error = false - awesome.connect_signal("debug::error", function (err) - -- Make sure we don't go into an endless error loop - if in_error then return end - in_error = true - - naughty.notify({ preset = naughty.config.presets.critical, - title = "Oops, an error happened!", - text = tostring(err) }) - in_error = false - end) -end --- }}} - --- {{{ Variable definitions --- Themes define colours, icons, font and wallpapers. -beautiful.init(gears.filesystem.get_dir("config") .. "theme.lua") - --- This is used later as the default terminal and editor to run. -terminal = "my term" -editor = os.getenv("EDITOR") or "nano" -editor_cmd = terminal .. " -e " .. editor - --- Default modkey. --- Usually, Mod4 is the key with a logo between Control and Alt. --- If you do not like this or do not have such a key, --- I suggest you to remap Mod4 to another key using xmodmap or other tools. --- However, you can use another modifier like Mod1, but it may interact with others. -modkey = "Mod4" - --- Table of layouts to cover with awful.layout.inc, order matters. -awful.layout.layouts = { - -- awful.layout.suit.floating, - awful.layout.suit.tile, - awful.layout.suit.tile.left, - awful.layout.suit.tile.bottom, - awful.layout.suit.tile.top, - awful.layout.suit.fair, - awful.layout.suit.fair.horizontal, - awful.layout.suit.spiral, - awful.layout.suit.spiral.dwindle, - awful.layout.suit.max, - awful.layout.suit.max.fullscreen, - awful.layout.suit.magnifier, - awful.layout.suit.corner.nw, - -- awful.layout.suit.corner.ne, - -- awful.layout.suit.corner.sw, - -- awful.layout.suit.corner.se, -} --- }}} - --- {{{ Helper functions -local function client_menu_toggle_fn() - local instance = nil - - return function () - if instance and instance.wibox.visible then - instance:hide() - instance = nil - else - instance = awful.menu.clients({ theme = { width = 250 } }) - end - end -end --- }}} - --- {{{ Menu --- Create a launcher widget and a main menu -myawesomemenu = { - { "hotkeys", function() return false, hotkeys_popup.show_help end}, - { "manual", terminal .. " -e man awesome" }, - { "edit config", editor_cmd .. " " .. awesome.conffile }, - { "restart", awesome.restart }, - { "quit", function() awesome.quit() end} -} - -mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon }, - { "open terminal", terminal } - } - }) - -mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, - menu = mymainmenu }) - --- Menubar configuration -menubar.utils.terminal = terminal -- Set the terminal for applications that require it --- }}} - --- {{{ Wibar --- Create a status widget -mystatus = awful.widget.watch('my status', 15) - --- Create a wibox for each screen and add it -local taglist_buttons = gears.table.join( - awful.button({ }, 1, function(t) t:view_only() end), - awful.button({ modkey }, 1, function(t) - if client.focus then - client.focus:move_to_tag(t) - end - end), - awful.button({ }, 3, awful.tag.viewtoggle), - awful.button({ modkey }, 3, function(t) - if client.focus then - client.focus:toggle_tag(t) - end - end), - awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end), - awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end) - ) - -local tasklist_buttons = gears.table.join( - awful.button({ }, 1, function (c) - if c == client.focus then - c.minimized = true - else - -- Without this, the following - -- :isvisible() makes no sense - c.minimized = false - if not c:isvisible() and c.first_tag then - c.first_tag:view_only() - end - -- This will also un-minimize - -- the client, if needed - client.focus = c - c:raise() - end - end), - awful.button({ }, 3, client_menu_toggle_fn()), - awful.button({ }, 4, function () - awful.client.focus.byidx(1) - end), - awful.button({ }, 5, function () - awful.client.focus.byidx(-1) - end)) - -local function set_wallpaper(s) - -- Wallpaper - if beautiful.wallpaper then - local wallpaper = beautiful.wallpaper - -- If wallpaper is a function, call it with the screen - if type(wallpaper) == "function" then - wallpaper = wallpaper(s) - end - gears.wallpaper.maximized(wallpaper, s, true) - end -end - --- Re-set wallpaper when a screen's geometry changes (e.g. different resolution) -screen.connect_signal("property::geometry", set_wallpaper) - -awful.screen.connect_for_each_screen(function(s) - -- Each screen has its own tag table. - awful.tag( - {"1", "2", "3", "4", "5", "6", "7", "8", "9"}, - s, - awful.layout.suit.tile - ) - - awful.tag.find_by_name(s, "9").layout = awful.layout.suit.max.fullscreen - - -- Create a promptbox for each screen - s.mypromptbox = awful.widget.prompt() - -- Create an imagebox widget which will contain an icon indicating which layout we're using. - -- We need one layoutbox per screen. - s.mylayoutbox = awful.widget.layoutbox(s) - s.mylayoutbox:buttons(gears.table.join( - awful.button({ }, 1, function () awful.layout.inc( 1) end), - awful.button({ }, 3, function () awful.layout.inc(-1) end), - awful.button({ }, 4, function () awful.layout.inc( 1) end), - awful.button({ }, 5, function () awful.layout.inc(-1) end))) - -- Create a taglist widget - s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons) - - -- Create a tasklist widget - s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons) - - -- Create the wibox - s.mywibox = awful.wibar({ position = "top", screen = s }) - - -- Add widgets to the wibox - s.mywibox:setup { - layout = wibox.layout.align.horizontal, - { -- Left widgets - layout = wibox.layout.fixed.horizontal, - mylauncher, - s.mytaglist, - s.mypromptbox, - }, - s.mytasklist, -- Middle widget - { -- Right widgets - layout = wibox.layout.fixed.horizontal, - mystatus, - wibox.widget.systray(), - s.mylayoutbox, - }, - } -end) --- }}} - --- {{{ Mouse bindings -root.buttons(gears.table.join( - awful.button({ }, 3, function () mymainmenu:toggle() end) - -- awful.button({ }, 4, awful.tag.viewnext), - -- awful.button({ }, 5, awful.tag.viewprev) -)) --- }}} - --- {{{ Key bindings -globalkeys = gears.table.join( - awful.key({ modkey, }, "s", hotkeys_popup.show_help, - {description="show help", group="awesome"}), - awful.key({ modkey, }, "Left", awful.tag.viewprev, - {description = "view previous", group = "tag"}), - awful.key({ modkey, }, "Right", awful.tag.viewnext, - {description = "view next", group = "tag"}), - awful.key({ modkey, }, "Escape", awful.tag.history.restore, - {description = "go back", group = "tag"}), - awful.key({ modkey, }, "j", - function () - awful.client.focus.byidx( 1) - end, - {description = "focus next by index", group = "client"} - ), - awful.key({ modkey, }, "k", - function () - awful.client.focus.byidx(-1) - end, - {description = "focus previous by index", group = "client"} - ), - awful.key({ modkey, }, "w", function () mymainmenu:show() end, - {description = "show main menu", group = "awesome"}), - - -- Layout manipulation - awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end, - {description = "swap with next client by index", group = "client"}), - awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end, - {description = "swap with previous client by index", group = "client"}), - awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end, - {description = "focus the next screen", group = "screen"}), - awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end, - {description = "focus the previous screen", group = "screen"}), - awful.key({ modkey, }, "u", awful.client.urgent.jumpto, - {description = "jump to urgent client", group = "client"}), - awful.key({ modkey, }, "Tab", - function () - awful.client.focus.history.previous() - if client.focus then - client.focus:raise() - end - end, - {description = "go back", group = "client"}), - - -- Standard program - awful.key({ modkey, "Control" }, "r", awesome.restart, - {description = "reload awesome", group = "awesome"}), - awful.key({ "Mod1", "Control" }, "BackSpace", awesome.quit, - {description = "quit awesome", group = "awesome"}), - - awful.key({ modkey, "Mod1" }, "l", function () awful.tag.incmwfact( 0.05) end, - {description = "increase master width factor", group = "layout"}), - awful.key({ modkey, "Mod1" }, "h", function () awful.tag.incmwfact(-0.05) end, - {description = "decrease master width factor", group = "layout"}), - awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end, - {description = "increase the number of master clients", group = "layout"}), - awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end, - {description = "decrease the number of master clients", group = "layout"}), - awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end, - {description = "increase the number of columns", group = "layout"}), - awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end, - {description = "decrease the number of columns", group = "layout"}), - awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end, - {description = "select next", group = "layout"}), - awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end, - {description = "select previous", group = "layout"}), - - awful.key({ modkey, "Control" }, "n", - function () - local c = awful.client.restore() - -- Focus restored client - if c then - client.focus = c - c:raise() - end - end, - {description = "restore minimized", group = "client"}), - - -- Prompt - awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end, - {description = "run prompt", group = "launcher"}), - - awful.key({ modkey }, "x", - function () - awful.prompt.run { - prompt = "Run Lua code: ", - textbox = awful.screen.focused().mypromptbox.widget, - exe_callback = awful.util.eval, - history_path = awful.util.get_cache_dir() .. "/history_eval" - } - end, - {description = "lua execute prompt", group = "awesome"}), - -- Menubar - awful.key({ modkey }, "p", function() menubar.show() end, - {description = "show the menubar", group = "launcher"}) -) - -clientkeys = gears.table.join( - awful.key({ modkey, }, "f", - function (c) - c.fullscreen = not c.fullscreen - c:raise() - end, - {description = "toggle fullscreen", group = "client"}), - awful.key({ modkey, }, "q", function (c) c:kill() end, - {description = "close", group = "client"}), - awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle , - {description = "toggle floating", group = "client"}), - awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end, - {description = "move to master", group = "client"}), - awful.key({ modkey, }, "o", function (c) c:move_to_screen() end, - {description = "move to screen", group = "client"}), - awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end, - {description = "toggle keep on top", group = "client"}), - awful.key({ modkey, }, "n", - function (c) - -- The client currently has the input focus, so it cannot be - -- minimized, since minimized clients can't have the focus. - c.minimized = true - end , - {description = "minimize", group = "client"}), - awful.key({ modkey, }, "m", - function (c) - c.maximized = not c.maximized - c:raise() - end , - {description = "(un)maximize", group = "client"}), - awful.key({ modkey, "Control" }, "m", - function (c) - c.maximized_vertical = not c.maximized_vertical - c:raise() - end , - {description = "(un)maximize vertically", group = "client"}), - awful.key({ modkey, "Shift" }, "m", - function (c) - c.maximized_horizontal = not c.maximized_horizontal - c:raise() - end , - {description = "(un)maximize horizontally", group = "client"}) -) - --- Bind all key numbers to tags. --- Be careful: we use keycodes to make it work on any keyboard layout. --- This should map on the top row of your keyboard, usually 1 to 9. -for i = 1, 9 do - globalkeys = gears.table.join(globalkeys, - -- View tag only. - awful.key({ modkey }, "#" .. i + 9, - function () - local screen = awful.screen.focused() - local tag = screen.tags[i] - if tag then - tag:view_only() - end - end, - {description = "view tag #"..i, group = "tag"}), - -- Toggle tag display. - awful.key({ modkey, "Control" }, "#" .. i + 9, - function () - local screen = awful.screen.focused() - local tag = screen.tags[i] - if tag then - awful.tag.viewtoggle(tag) - end - end, - {description = "toggle tag #" .. i, group = "tag"}), - -- Move client to tag. - awful.key({ modkey, "Shift" }, "#" .. i + 9, - function () - if client.focus then - local tag = client.focus.screen.tags[i] - if tag then - client.focus:move_to_tag(tag) - end - end - end, - {description = "move focused client to tag #"..i, group = "tag"}), - -- Toggle tag on focused client. - awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, - function () - if client.focus then - local tag = client.focus.screen.tags[i] - if tag then - client.focus:toggle_tag(tag) - end - end - end, - {description = "toggle focused client on tag #" .. i, group = "tag"}) - ) -end - -clientbuttons = gears.table.join( - awful.button({ }, 1, function (c) client.focus = c; c:raise() end), - awful.button({ modkey }, 1, awful.mouse.client.move), - awful.button({ modkey }, 3, awful.mouse.client.resize)) - --- Set keys -root.keys(globalkeys) --- }}} - --- {{{ Rules --- Rules to apply to new clients (through the "manage" signal). -awful.rules.rules = { - -- All clients will match this rule. - { rule = { }, - properties = { border_width = beautiful.border_width, - border_color = beautiful.border_normal, - focus = awful.client.focus.filter, - raise = true, - keys = clientkeys, - buttons = clientbuttons, - screen = awful.screen.preferred, - placement = awful.placement.no_overlap+awful.placement.no_offscreen - } - }, - - -- Floating clients. - { rule_any = { - instance = { - "DTA", -- Firefox addon DownThemAll. - "copyq", -- Includes session name in class. - }, - class = { - "Arandr", - "Gpick", - "Kruler", - "MessageWin", -- kalarm. - "Sxiv", - "Wpa_gui", - "pinentry", - "veromix", - "xtightvncviewer"}, - - name = { - "Event Tester", -- xev. - "xbindkeys_show", - "xfontsel" - }, - role = { - "AlarmWindow", -- Thunderbird's calendar. - "pop-up", -- e.g. Google Chrome's (detached) Developer Tools. - } - }, properties = { floating = true }}, - - -- Set Firefox to always map on the tag named "2" on screen 1. - -- { rule = { class = "Firefox" }, - -- properties = { screen = 1, tag = "2" } }, -} --- }}} - --- {{{ Signals --- Signal function to execute when a new client appears. -client.connect_signal("manage", function (c) - -- Set the windows at the slave, - -- i.e. put it at the end of others instead of setting it master. - -- if not awesome.startup then awful.client.setslave(c) end - - if awesome.startup and - not c.size_hints.user_position - and not c.size_hints.program_position then - -- Prevent clients from being unreachable after screen count changes. - awful.placement.no_offscreen(c) - end -end) - --- Add a titlebar if titlebars_enabled is set to true in the rules. -client.connect_signal("request::titlebars", function(c) - -- buttons for the titlebar - local buttons = gears.table.join( - awful.button({ }, 1, function() - client.focus = c - c:raise() - awful.mouse.client.move(c) - end), - awful.button({ }, 3, function() - client.focus = c - c:raise() - awful.mouse.client.resize(c) - end) - ) - - awful.titlebar(c, { size = beautiful.titlebar_height }) : setup { - { -- Left - -- awful.titlebar.widget.iconwidget(c), - buttons = buttons, - layout = wibox.layout.fixed.horizontal - }, - { -- Middle - { -- Title - align = "center", - widget = awful.titlebar.widget.titlewidget(c) - }, - buttons = buttons, - layout = wibox.layout.flex.horizontal - }, - { -- Right - awful.titlebar.widget.floatingbutton (c), - awful.titlebar.widget.maximizedbutton(c), - awful.titlebar.widget.stickybutton (c), - awful.titlebar.widget.ontopbutton (c), - awful.titlebar.widget.closebutton (c), - layout = wibox.layout.fixed.horizontal() - }, - layout = wibox.layout.align.horizontal - } -end) - --- Enable sloppy focus, so that focus follows mouse. -client.connect_signal("mouse::enter", function(c) - if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier - and awful.client.focus.filter(c) then - client.focus = c - end -end) - -client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) -client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) --- }}} diff --git a/.config/awesome/theme.lua b/.config/awesome/theme.lua @@ -1,69 +0,0 @@ --- --- ~/.config/awesome/theme.lua --- -local theme_assets = require("beautiful.theme_assets") -local xresources = require("beautiful.xresources") -local xtheme = xresources.get_current_theme() -local dpi = xresources.apply_dpi - -local gfs = require("gears.filesystem") -local awful = require("awful") -local themes_path = gfs.get_themes_dir() - -local theme = dofile(themes_path.."default/theme.lua") - -theme.font = "sans 9" - -theme.bg_normal = xtheme.color8 -theme.bg_focus = xtheme.color7 -theme.bg_urgent = xtheme.color4 -theme.bg_minimize = xtheme.color0 -theme.bg_systray = xtheme.color8 - -theme.fg_normal = xtheme.background -theme.fg_focus = xtheme.foreground -theme.fg_urgent = xtheme.background -theme.fg_minimize = xtheme.background - -theme.useless_gap = dpi(0) -theme.border_width = dpi(1) -theme.border_normal = xtheme.color8 -theme.border_focus = xtheme.color4 -theme.border_marked = xtheme.color5 - -theme.hotkeys_bg = xtheme.color8 -theme.hotkeys_fg = xtheme.background -theme.hotkeys_modifiers_fg = xtheme.color6 - --- Generate taglist squares: -local taglist_square_size = dpi(4) -theme.taglist_squares_sel = theme_assets.taglist_squares_sel( - taglist_square_size, theme.fg_focus -) -theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel( - taglist_square_size, theme.fg_normal -) - -theme = theme_assets.recolor_layout(theme, theme.fg_normal) -theme = theme_assets.recolor_titlebar(theme, theme.fg_normal, "normal") -theme = theme_assets.recolor_titlebar(theme, theme.bg_normal, "focus") - --- Variables set for theming the menu: -theme.menu_height = dpi(15) -theme.menu_width = dpi(100) - -theme.wallpaper = function (s) awful.spawn('my wallpaper') end - --- Generate Awesome icon: -theme.awesome_icon = theme_assets.awesome_icon( - theme.menu_height, theme.bg_focus, theme.fg_focus -) - -theme.wibar_height = dpi(16) -theme.titlebar_height = dpi(16) - --- Define the icon theme for application icons. If not set then the icons --- from /usr/share/icons and /usr/share/icons/hicolor will be used. -theme.icon_theme = "Arc" - -return theme diff --git a/.config/dunst/dunstrc b/.config/dunst/dunstrc @@ -1,68 +0,0 @@ -# -# ~/.config/dunst/dunstrc -# -[global] -monitor = 0 -follow = mouse -geometry = "300x5-30+20" -indicate_hidden = yes -shrink = no -transparency = 0 -notification_height = 0 -separator_height = 2 -padding = 8 -horizontal_padding = 8 -frame_width = 1 -frame_color = "#bcbcbc" -separator_color = frame -sort = yes -idle_threshold = 120 -font = Sans 9 -line_height = 0 -markup = full -format = "<b>%s</b>\n%b" -alignment = left -show_age_threshold = 60 -word_wrap = yes -ellipsize = middle -ignore_newline = no -stack_duplicates = true -hide_duplicate_count = false -show_indicators = yes -icon_position = off -max_icon_size = 32 -icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ -sticky_history = yes -history_length = 20 -dmenu = /usr/bin/dmenu -p dunst: -browser = my-open -always_run_script = true -title = Dunst -class = Dunst -startup_notification = false -force_xinerama = false - -[experimental] -per_monitor_dpi = false - -[shortcuts] -close = ctrl+space -close_all = ctrl+shift+space -history = ctrl+grave -context = ctrl+shift+period - -[urgency_low] -background = "#262626" -foreground = "#bcbcbc" -timeout = 10 - -[urgency_normal] -background = "#262626" -foreground = "#bcbcbc" -timeout = 10 - -[urgency_critical] -background = "#af5f5f" -foreground = "#bcbcbc" -frame_color = "#ff0000" -timeout = 0 diff --git a/.config/khal/config b/.config/khal/config @@ -1,23 +0,0 @@ -[calendars] - -[[home]] -path = ~/.local/share/calendars/nextcloud/home -type = discover -color = 4 - -[[family]] -path = ~/.local/share/calendars/nextcloud/family -type = discover -color = 2 - -[[planning_center]] -path = ~/.local/share/calendars/planningcenter -type = discover -color = 3 - -[locale] -timeformat = %I:%M %p -dateformat = %m/%d/%Y -longdateformat = %m/%d/%Y -datetimeformat = %m/%d/%Y %I:%M %p -longdatetimeformat = %m/%d/%Y %I:%M %p diff --git a/.config/khard/khard.conf b/.config/khard/khard.conf @@ -1,39 +0,0 @@ -# example configuration file for khard version >= 0.11.0 -# place it under $HOME/.config/khard/khard.conf - -[addressbooks] -[[nextcloud]] -path = ~/.local/share/contacts/nextcloud/Contacts - -[general] -debug = no -default_action = list - -[contact table] -# display names by first or last name: first_name / last_name -display = first_name -# group by address book: yes / no -group_by_addressbook = no -# reverse table ordering: yes / no -reverse = no -# append nicknames to name column: yes / no -show_nicknames = no -# show uid table column: yes / no -show_uids = yes -# sort by first or last name: first_name / last_name -sort = last_name - -[vcard] -# extend contacts with your own private objects -# these objects are stored with a leading "X-" before the object name in the vcard files -# every object label may only contain letters, digits and the - character -# example: -# private_objects = Jabber, Skype, Twitter -private_objects = Jabber, Skype, Twitter -# preferred vcard version: 3.0 / 4.0 -preferred_version = 3.0 -# Look into source vcf files to speed up search queries: yes / no -search_in_source_files = no -# skip unparsable vcard files: yes / no -skip_unparsable = no - diff --git a/.config/todoman/todoman.conf b/.config/todoman/todoman.conf @@ -1,7 +0,0 @@ -[main] -# A glob expression which matches all directories relevant. -path = ~/.local/share/calendars/nextcloud/* -date_format = %Y-%m-%d -time_format = %H:%M -default_list = Tasks: Home -default_due = 48 diff --git a/.gitconfig b/.gitconfig @@ -19,11 +19,11 @@ ctags = !`git rev-parse --git-dir`/hooks/ctags po = push -u origin HEAD [init] - templatedir = ~/.local/lib/gitdir + templatedir = ~/lib/gitdir [credential] helper = /usr/share/git/credential/netrc/git-credential-netrc [include] - path = ~/.gitconfig.local + path = ~/etc/gitconfig.local [pull] rebase = true [sendemail] diff --git a/.local/bin/fws b/.local/bin/fws @@ -1,16 +0,0 @@ -#!/bin/sh -# -# ~/.local/bin/fws -# -# Remove trailing whitespace recursively. Pass in file extensions to -# search for. - -case `uname -s` in - CYGWIN*) ext='\r' ;; - *) ext="" ;; -esac - -for arg -do - find . -name *.$arg -exec sed -i -e "s/[[:space:]]*\$/$ext/g" '{}' \; -done diff --git a/.local/bin/my b/.local/bin/my @@ -1,443 +0,0 @@ -#!/bin/sh -# -# ~/.local/bin/my -# - -# Command and handlers for them are added as-needed. Some commands only -# have one handler, but exist to avoid re-writes across my dotfiles -# later on. - -[ $# -eq 0 ] && exit 1 - -log="$HOME/.local/var/log/my" -command=$1 -shift - -__mylog() -{ - echo "$1 (`date +'%m/%d/%Y %H:%M:%S'`): $2" >> $log -} - -__getlocker() -{ - if type slock > /dev/null 2>&1 - then - echo slock - exit 0 - fi - for locker in slock light-locker cinnamon-screensaver gnome-screensaver xscreensaver - do - if my processes | grep $locker > /dev/null 2>&1 - then - echo $locker - exit 0 - fi - done - - __mylog "__getlocker" "No screen locker running" - exit 1 -} - -case $command in - mailto) - for m in mutt mail - do - if type $m > /dev/null 2>&1 - then - mailer=$m - break - fi - done - if [ -n "$2" ] - then - $mailer -s "$2" $1 - else - $mailer $1 - fi - ;; - search) - query=`echo $1 | tr ' ' '+'` - exec my open -T https://duckduckgo.com/?q=$query - ;; - term) - SHLVL=0; export SHLVL - if type st > /dev/null 2>&1 - then - exec st "$@" - elif type urxvtd > /dev/null 2>&1 - then - urxvtc "$@" - if [ "$?" -eq 2 ] - then - urxvtd -q -o -f - urxvtc "$@" - fi - exit 0 - elif type urxvt > /dev/null 2>&1 - then - exec urxvt "$@" - elif type xterm > /dev/null 2>&1 - then - exec xterm "$@" - elif type x-terminal-emulator > /dev/null 2>&1 - then - exec x-terminal-emulator "$@" - fi - - [ "$1" = "-e" ] && shift && set -- "-x" $@ - if type xfce4-terminal > /dev/null 2>&1 - then - exec xfce4-terminal "$@" - elif type gnome-terminal > /dev/null 2>&1 - then - exec gnome-terminal "$@" - fi - - __mylog "my term" "No terminal emulator found" - exit 1 - ;; - lock) - sleep 1 - - locker=`__getlocker` - - if [ -z "$locker" ] - then - __mylog "my lock" "no locker running" - exit 1 - fi - [ "$locker" = "light-locker" -o "$locker"="slock" ] || $locker-command -l - exec xset dpms force off - ;; - wallpaper) - xsetroot -solid "#444444" - [ -x "$HOME/.fehbg" ] && "$HOME/.fehbg" >> $log 2>&1 - ;; - standby) - if type systemctl > /dev/null 2>&1 - then - locker=`__getlocker` - if [ -z "$locker" ] - then - __mylog "my standby" "no locker running" - exit 1 - fi - if [ ! "$locker" = "light-locker" ] - then - sleep 1 - $locker-command -l - xset dpms force off - fi - exec systemctl hybrid-sleep - else - __mylog "my standby" "No handler found" - fi - ;; - shutdown) - if type systemctl > /dev/null 2>&1 - then - exec systemctl poweroff - elif type poweroff > /dev/null 2>&1 - then - exec my term -e sudo poweroff - else - __mylog "my shutdown" "No handler found" - fi - ;; - perms) - exec my-perms "$@" - ;; - init) - exec my-init "$@" - ;; - open) - exec my-open "$@" - ;; - sound) - if type pactl > /dev/null 2>&1 && pactl stat > /dev/null 2>&1 - then - [ -z "$1" ] && exit 1 - if [ $1 = "status" ] - then - sink_status=`pactl list sinks | grep ^[[:space:]]*Volume | awk '{print $5}'` - source_status=`pactl list sources | grep ^[[:space:]]*Volume | awk '{print $5}'` - echo -n "Sinks: " - for sink in $sink_status - do - echo -n "$sink " - done - echo "" - echo -n "Sources: " - for source in $source_status - do - echo -n "$source " - done - echo "" - exit 0 - else - exec pactl "$@" - fi - else - __mylog "my sound" "No handler found" - fi - ;; - kbopts) - setxkbmap -option -option ctrl:nocaps - ;; - screen) - xrandr_options=`xrandr -q | grep ' disconnected' | awk '{print $1}'` - for option in $xrandr_options - do - xrandr --output $option --off - done - - xrandr_options=`xrandr -q | grep ' connected' | awk '{print $1}'` - numoptions=`echo $xrandr_options | wc -w` - if [ $numoptions -eq 1 ] - then - xrandr --output $xrandr_options --auto --primary - else - # Prefer external monitors - # If more than one display is connected, then enable the - # first non-primary display, and turn off all the others. - primary=`xrandr -q | grep primary | awk '{print $1}'` - - for option in $xrandr_options - do - [ $option = $primary ] && primary_found=1 && continue - [ -n "$primary_found" ] && selection=$option && break - done - - xrandr --output $selection --auto --primary - - for option in $xrandr_options - do - [ $option != $selection ] && xrandr --output $option --off - done - fi - exec my wallpaper - ;; - brightness) - if type xbacklight > /dev/null 2>&1 - then - if [ "$1" = "monitor" ] - then - # Future-proofing ... gmux is specific, imagine other - # systems will be different - for opt in gmux intel_backlight - do - selection=`xbacklight -list | grep $opt` - num=`echo $selection | wc -w` - [ $num -gt 0 ] && break - done - else - selection=`xbacklight -list | grep $1` - num=`echo $selection | wc -w` - fi - [ $num -gt 1 ] && __mylog "my brightness" "More than one $1" && exit 1 - [ $num -lt 1 ] && __mylog "my brightness" "No $1 to adjust" && exit 1 - shift - exec xbacklight -ctrl $selection "$@" - else - __mylog "my brightness" "No handler found" - fi - ;; - battery) - uname=`uname -s` - - case $1 in - remaining) - case $uname in - *Linux*) - if [ `acpi | wc -l` -eq 2 ] - then - acpi | awk 'getline' | awk '{print $4}' | sed 's~%~~' | sed 's~,~~' - else - acpi | awk '{print $4}' | sed 's~%~~' | sed 's~,~~' - fi - ;; - *Darwin*) - battery_info=`ioreg -rc AppleSmartBattery` - echo $battery_info | grep -o '"CurrentCapacity" = [0-9]\+' | awk '{print $3}' - ;; - *CYGWIN*) - wmic path Win32_Battery Get EstimatedChargeRemaining /format:list 2>/dev/null | grep '[^[:blank:]]' | cut -d= -f2 - ;; - *) - echo "no battery status" - exit 1 - esac - exit 0 - ;; - total) - case $uname in - *Linux*|*CYGWIN*) - echo 100 - ;; - *Darwin*) - battery_info=`ioreg -rc AppleSmartBattery` - echo $battery_info | grep -o '"MaxCapacity" = [0-9]\+' | awk '{print $3}' - ;; - *) - echo "no battery status" - exit 1 - esac - exit 0 - ;; - percent) - echo "$((`my battery remaining` * 100 / `my battery total`))" - exit 0 - ;; - esac - ;; - status) - echo -n "Batt: `my battery percent`% | " - cat $HOME/.local/var/forecastio/current_forecast.txt | tr -d '\n' - echo -n " | " - date +'%l:%M %p' - exit 0 - ;; - i3status) - while : - do - echo "`my status`" || exit 1 - sleep 15 - done - ;; - copy) - uname=`uname -s` - - case $uname in - *Darwin*) - reattach-to-user-namespace pbcopy - ;; - *CYGWIN*) - cat > /dev/clipboard - ;; - *Linux*) - xclip -selection clipboard - ;; - *) - return - esac - ;; - paste) - uname=`uname -s` - - case $uname in - *Darwin*) - reattach-to-user-namespace pbpaste - ;; - *CYGWIN*) - cat /dev/clipboard - ;; - *Linux*) - xclip -o - ;; - *) - return - esac - ;; - netrc) - exec my-netrc "$@" - ;; - dotfiles) - predicate="$1" && shift - case $predicate in - check) - cd "$HOME" - aweekago=$(($(date +%s) - 604800)) - lastupdate=$(stat --format=%Y ._.djmoch) - [ $lastupdate -lt $aweekago ] && "Dotfiles more than one week old" - ;; - update) - if [ -d "$HOME/.dotfiles_tgz" ] - then - - if type sha256sum > /dev/null 2>&1 - then - sha_exec=sha256sum - fieldnum=1 - else - sha_exec=sha256 - fieldnum=4 - fi - - curl -s https://git.danielmoch.com/dotfiles/snapshot/dotfiles-master.tar.gz > /tmp/dotfiles.tgz.$$ - oldsum=`$sha_exec "$HOME/.dotfiles_tgz/dotfiles.tar.gz" | cut -d ' ' -f $fieldnum` - newsum=`$sha_exec "/tmp/dotfiles.tgz.$$" | cut -d ' ' -f $fieldnum` - if [ ! "$oldsum" = "$newsum" ] - then - mv /tmp/dotfiles.tgz.$$ "$HOME/.dotfiles_tgz/dotfiles.tar.gz" - cd "$HOME" - tar xzf .dotfiles_tgz/dotfiles.tar.gz - for file in $(ls -A dotfiles-master) - do - cp -r dotfiles-master/$file . - done - rm -rf dotfiles-master - else - rm /tmp/dotfiles.tgz.$$ - fi - fi - my init -f > /dev/null 2>&1 - touch "$HOME/._.djmoch" - ;; - esac - ;; - cron) - [ "$1" = systemd ] && mycron_systemd=1 - case ":$PATH:" in - *:"$HOME/.local/bin":*) ;; - *) PATH="$HOME/.local/bin:$PATH" ;; - esac - cronpath="$HOME/.local/lib/cron.d" - logpath="$HOME/.local/var/log" - for job in $cronpath/* - do - if [ -x $job ] - then - if [ -n "$mycron_systemd" ] - then - $job - else - $job > $logpath/`basename $job` 2>&1 - fi - fi - done - ;; - login_async) - starttime=`date '+%s'` - runningtime=0 - while [ $runningtime -le 120 ] - do - if ping -c 1 danielmoch.com > /dev/null 2>&1 - then - connected=1 - break - fi - sleep 1 - runningtime=$((`date '+%s'` - $starttime)) - done - if [ -n "$connected" ] - then - cd "$HOME" - aweekago=$(($(date +%s) - 604800)) - lastupdate=$(stat --format=%Y ._.djmoch) - [ $lastupdate -lt $aweekago ] && my dotfiles update - fi - ;; - login) - my login_async & - ;; - processes) - if [ -L /bin/ps ] - then - # busybox - ps -o user,comm= | grep $LOGNAME | awk '{print $2;}' - else - ps -U $LOGNAME -o comm= - fi - ;; - *) echo "my: command $command not found" >&2 -esac diff --git a/.local/bin/my-init b/.local/bin/my-init @@ -1,254 +0,0 @@ -#!/bin/sh -# -# ~/.local/bin/my-init -# -# A place to dump run-once type initializations - -while [ -n "$1" ] -do - [ "$1" = "-f" ] && force_init=1 - [ "$1" = "-c" ] && crontab_init=1 - shift -done - -vim_bundle_path="$HOME/.vim/pack/bundle" -configdir=${XDG_CONFIG_HOME:-$HOME/.config} - -__has() -{ - for token in $@ - do - type $token > /dev/null 2>&1 - [ $? -ne 0 ] && echo " $token doesn't exist" && return 1 - done - return 0 -} - -__clone() -{ - dir=`echo "$1" | cut -d '/' -f2` - if [ -d $dir ] - then - echo -n " Updating $1 ..." - cd $dir - git pull > /dev/null 2>&1 - result=$? - cd .. - else - echo -n " Cloning $1 ... " - git clone https://github.com/$1.git > /dev/null 2>&1 - result=$? - fi - [ $result -ne 0 ] && echo "FAILED!" && return 1 - echo "Succeeded" -} - -__optclone_pathogen() -{ - vim --cmd "redir! > /tmp/vimpackages.$$ | silent echo has('packages') | q" - case `cat /tmp/vimpackages.$$` in - *0*) - if [ -d vim-pathogen ] - then - echo -n " Updating tpope/vim-pathogen ..." - cd vim-pathogen - git pull > /dev/null 2>&1 - result=$? - cd .. - else - echo -n " Cloning tpope/vim-pathogen ... " - git clone https://github.com/tpope/vim-pathogen.git > /dev/null 2>&1 - result=$? - fi - [ $result -ne 0 ] && echo "FAILED!" && return 1 - echo "Succeeded" - ;; - esac - rm /tmp/vimpackages.$$ -} - - -if [ -n "$force_init" ] -then - echo "Re-initialization requested" - rm -f "$HOME/._.djmoch" - rm -rf "$HOME/.terminfo" - rm "$HOME/.less" - rm "$HOME/.gnupg/gpg-agent.conf" -fi - -if [ -f "$HOME/._.djmoch" ] -then - echo "Already initialized. Exiting." - exit 0 -fi - -echo "Performing run-once initializations" - -if __has "infocmp" "tic" -then - echo " Initializing Termcaps" - if infocmp tmux-256color > /dev/null 2>&1 - then - tic "$HOME/.local/lib/terminfo/tmux.terminfo" - else - tic "$HOME/.local/lib/terminfo/tmux-from-screen.terminfo" - fi -fi - -if __has "lesskey" -then - echo " Initializing .less" - lesskey -fi - -if my processes | grep systemd > /dev/null 2>&1 \ - && [ -n "$crontab_init" ] -then - echo " Installing systemd timers" - cat >> $configdir/systemd/user/my-cron.service <<-EOF -[Unit] -Description=djmoch "my cron" service - -[Service] -Type=simple -ExecStart=$HOME/.local/bin/my cron systemd -EOF - cat >> $configdir/systemd/user/my-cron.timer <<-EOF -[Unit] -Description=djmoch "my cron" timer - -[Timer] -OnBootSec=1min -OnUnitActiveSec=15min - -[Install] -WantedBy=timers.target -EOF - systemctl --user enable my-cron.timer -elif __has "crontab" && [ -n "$crontab_init" ] -then - echo " Installing crontab" - crontab -l > /tmp/crontab.$$.orig - [ $? -ne 0 ] && echo "" > /tmp/crontab.$$.orig - grep .local/bin/my /tmp/crontab.$$.orig > /dev/null 2>&1 - if [ ! $? -eq 0 ] - then - cat >> /tmp/crontab.$$ <<-EOF -# crontab created by my-init on `date '+%m/%d/%Y'` -# m h dom mon dow command -*/15 * * * * "\$HOME/.local/bin/my" cron - -# Entries below this line created manually -EOF - cat /tmp/crontab.$$.orig >> /tmp/crontab.$$ - cat /tmp/crontab.$$ | crontab - rm /tmp/crontab.$$ - fi - rm /tmp/crontab.$$.orig -fi - -# Vim plugins -if __has "vim" "git" -then - echo " Downloading Vim plugins" - # Plugins that should always be enabled - mkdir -p $vim_bundle_path/start - cd $vim_bundle_path/start - __clone romainl/Apprentice - __clone tpope/vim-commentary - __clone tpope/vim-eunuch - __clone tpope/vim-fugitive - __clone tpope/vim-obsession - __clone tpope/vim-scriptease - __clone tpope/vim-surround - __clone tpope/vim-unimpaired - __clone tpope/vim-vinegar - __clone junegunn/goyo.vim - __clone junegunn/limelight.vim - __clone beloglazov/vim-online-thesaurus - __clone chr4/sslsecure.vim - __optclone_pathogen - cd - > /dev/null 2>&1 - - # Plugins used optionally - mkdir -p $vim_bundle_path/opt - cd $vim_bundle_path/opt - __clone jpalardy/vim-slime - __clone skammer/vim-css-color - cd - > /dev/null 2>&1 - - vim --cmd 'silent! execute "helptags ALL" | q' - unset vim_bundle_path -fi - -for shell in zsh bash dash sh -do - preferred_shell=`cat /etc/shells | grep /$shell$ | tr '\n' ' ' | cut -d ' ' -f 1` - [ "$preferred_shell" = "" ] || break -done -if getent passwd | grep ^$LOGNAME.*$preferred_shell$ > /dev/null 2>&1 -then - echo " Login shell already set to $preferred_shell" -else - echo " Setting login shell to $preferred_shell" - chsh -s $preferred_shell -fi - -for locker in xscreensaver light-locker cinnamon-screensaver -do - if type $locker > /dev/null 2>&1 - then - echo " Creating autostart entry for $locker" - cat > "$HOME/.config/autostart/$locker.desktop" <<-EOF -[Desktop Entry] -TryExec=$locker -Exec=$locker -Name=$locker -Comment=Screen locker -Type=Application -EOF - break - fi -done - -if [ ! -f "$HOME/.gnupg/gpg-agent.conf" ] -then - echo " Creating gpg-agent.conf and configuring pinentry" - pinentry="" - if type pinentry > /dev/null 2>&1 - then - pinentry=`which pinentry` - fi - case `uname -s` in - *Darwin*) - pinentry="/usr/local/bin/pinentry-mac $pinentry" - ;; - esac - - for testpath in $pinentry - do - if [ -x $testpath ] - then - cat > "$HOME/.gnupg/gpg-agent.conf" <<-EOF -default-cache-ttl 600 -max-cache-ttl 7200 -enable-ssh-support -pinentry-program $testpath -EOF - break - fi - done -fi - -[ ! -d "$HOME/.local/var/log" ] && mkdir -p "$HOME/.local/var/log" -[ ! -d "$HOME/.local/var/forecastio" ] && mkdir -p "$HOME/.local/var/forecastio" -[ ! -d "$HOME/.local/lib/cron.d" ] && mkdir -p "$HOME/.local/lib/cron.d" -[ ! -f "$HOME/.local/var/forecastio/current_forecast.txt" ] && echo \ - "Weather not available" > \ - "$HOME/.local/var/forecastio/current_forecast.txt" -[ ! -d "$HOME/.vim/undo/" ] && mkdir -p "$HOME/.vim/undo" -touch "$HOME/._.djmoch" -chmod 000 "$HOME/._.djmoch" - -unset __clone __has __optclone_pathogen diff --git a/.local/bin/my-netrc b/.local/bin/my-netrc @@ -1,46 +0,0 @@ -#!/usr/bin/env python -# -# ~/.local/bin/my-netrc -# -# Parse .netrc for usernames and passwords. For clients with a password -# eval feature, but no built-in netrc support. -import netrc -import sys - -def parse_netrc(host, token=None): - try: - authenticators = netrc.netrc().authenticators(host) - except Exception as error: - exit(str(error)) - if authenticators is None: - exit('my-netrc: ' + host + ' not found') - elif token == 'login': - if authenticators[0] is not None: - print(authenticators[0]) - else: - exit(host + ' contains no login token') - elif token == 'account': - if authenticators[1] is not None: - print(authenticators[1]) - else: - exit(host + ' contains no account token') - elif token == 'password': - if authenticators[2] is not None: - print(authenticators[2]) - else: - exit(host + ' contains no password token') - else: - if authenticators[0] is not None: - print('login: ' + authenticators[0]) - if authenticators[1] is not None: - print('account: ' + authenticators[1]) - if authenticators[2] is not None: - print('password: ' + authenticators[2]) - -if __name__ == "__main__": - if len(sys.argv) < 2: - exit('my-netrc: No request made. Exiting') - elif len(sys.argv) == 2: - parse_netrc(sys.argv[1]) - else: - parse_netrc(sys.argv[1], sys.argv[2]) diff --git a/.local/bin/my-open b/.local/bin/my-open @@ -1,118 +0,0 @@ -#!/bin/sh -# -# ~/.local/bin/my-open -# -# Every OS seems to use it's own uniquely-named binary to open -# files using the correct handler for the file's MIME type. This is my -# attempt to resolve the different handlers into a platform-independent -# one. -# -if [ "$1" = "-T" ] -then - shift - - configfile="${XDG_CONFIG_HOME:-$HOME/.config}/my-open/config" - - if [ ! -f "$configfile" ] - then - echo "my-open: No config file. Creating skeleton." - mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/my-open" - configname=${configfile/$HOME/'~'} - cat >> "$configfile" <<-EOF -# -# $configname -# -# format: [mimetype]:default fallback1 fallback2 ...:commandline -# second segment of mimetype can be a wildcard. my-open looks for exact -# matches first. -EOF - exit 2 - fi - - if type xdg-mime > /dev/null 2>&1 - then - mimecmd="xdg-mime query filetype %s" - elif type mimetype > /dev/null 2>&1 - then - mimecmd="mimetype %s" - else - echo "my-open: No way to determine MIME type" >&2 - exit 1 - fi - - if [ -f "$1" -o -d "$1" ] - then - mimecmd=`printf "$mimecmd" "$1"` - mimetype=`$mimecmd` - elif echo "$1" | grep -E '^http:\/\/' > /dev/null 2>&1 - then - mimetype='x-scheme-handler/http' - elif echo "$1" | grep -E '^https:\/\/' > /dev/null 2>&1 - then - mimetype='x-scheme-handler/https' - elif echo "$1" | grep -E '^ftp:\/\/' > /dev/null 2>&1 - then - mimetype='x-scheme-handler/ftp' - else - mimetype='application/octet-stream' - fi - - handlers=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ - cut -d ':' -f 2` - cmdline=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ - cut -d ':' -f 3` - if [ -z "$handlers" ] - then - mimetype="`echo $mimetype | cut -d '/' -f 1`/*" - handlers=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ - cut -d ':' -f 2` - cmdline=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ - cut -d ':' -f 3` - fi - if [ -z "$handlers" ] - then - echo "my-open: No handler specified" >&2 - exit 4 - fi - - for h in $handlers - do - if type $h > /dev/null 2>&1 - then - handler=$h - break - fi - done - - if [ -z "$handler" ] - then - echo "my-open: No handler found in \$PATH" >&2 - exit 8 - fi - set -- `printf -- "$cmdline" "$1"` - exec $handler "$@" -fi - -# Find handler, if one is available -if type cygstart > /dev/null 2>&1 -then - handler=cygstart -elif type xdg-open > /dev/null 2>&1 -then - handler=xdg-open -# Most of the following handlers are used within xdg-open, but we should -# check for them anyway since xdg-open doesn't exist -elif type exo-open > /dev/null 2>&1 -then - handler=exo-open -# Because of its ambiguity, open (the macOS handler) should always be -# tested last -elif type open > /dev/null 2>&1 -then - handler=open -else - echo "my-open: No suitable handler found" > /dev/stderr - exit -1 -fi - -$handler "$@" diff --git a/.local/bin/my-perms b/.local/bin/my-perms @@ -1,36 +0,0 @@ -#!/bin/sh - -# -# ~/.local/bin/my-perms -# -# This file operates on $HOME, seting permissions for all dotfiles and -# dot-directories. The $HOME folder itself also has its permissions set -# to a secure default. -# - -cd $HOME - -for rec in `ls -A` -do - case $rec in - .*) - if [ -f $rec ] - then - if [ -x $rec ] - then - chmod 700 $rec - else - chmod 600 $rec - fi - fi - - if [ -d $rec ] - then - chmod 700 $rec - fi - ;; - esac -done - -# Finally, set the permissions for $HOME itself -chmod 700 . diff --git a/.local/lib/cron.avail/cloudsync.sh b/.local/lib/cron.avail/cloudsync.sh @@ -1,99 +0,0 @@ -#!/bin/sh -# -# ~/.local/lib/cron.avail/cloudsync.sh -# - -echo "Beginning cloud sync at `date`" - -year=`date '+%Y'` -month=`date '+%m'` -lastrun_dir="$HOME/.local/var/`basename $0`" -lastrun_file="$lastrun_dir/lastrun" -mobile_docs="$HOME/Documents/Mobile" -notes="$HOME/Documents/Notes" -server_fqdn="nextcloud.djmoch.org" - -if [ -d "$lastrun_dir" ] -then - if [ -f "$lastrun_file" ] - then - lastrun_year=`cat $lastrun_file | cut -d ' ' -f 1` - lastrun_month=`cat $lastrun_file | cut -d ' ' -f 2` - else - firstrun=1 - fi -else - firstrun=1 - mkdir -p "$lastrun_dir" -fi -echo "$year $month" > $lastrun_file - -[ ! -d "$mobile_docs" ] && mkdir -p "$mobile_docs" - -# Only do the following if the server is reachable -if ping -c 1 $server_fqdn > /dev/null 2>&1 -then - echo "$server_fqdn reachable. Proceeding." -else - echo "$server_fqdn NOT reachable. Exiting." - exit -1 -fi - -if type xdg-user-dir > /dev/null 2>&1 -then - LOCAL_PHOTOS=`xdg-user-dir PICTURES` -else - LOCAL_PHOTOS="$HOME/Pictures" -fi - -# Mount the WebDAV folder and set so only we can read it -if mount /mnt/nextcloud -then - echo "NextCloud WebDAV successfully mounted. Setting permissions." - chmod 700 /mnt/nextcloud - - # Rsync from WebDAV to ~/Photos - echo "Syncing Photos from WebDAV to $LOCAL_PHOTOS" - [ ! -d $LOCAL_PHOTOS/$year/$month ] && mkdir -p $LOCAL_PHOTOS/$year/$month - rsync -aq /mnt/nextcloud/Photos/$year/$month/* $LOCAL_PHOTOS/$year/$month - if [ -z "$firstrun" -a $lastrun_month -ne $month ] - then - # TODO: What if we're more than a month behind? - if [ ! -d $LOCAL_PHOTOS/$lastrun_year/$lastrun_month ] - then - mkdir -p $LOCAL_PHOTOS/$lastrun_year/$lastrun_month - fi - rsync -aq /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month/* $LOCAL_PHOTOS/$lastrun_year/$lastrun_month - fi - - # Rsync from ~/Photos to WebDAV - echo "Syncing Photos from $LOCAL_PHOTOS to WebDAV" - [ ! -d /mnt/nextcloud/Photos/$year/$month ] && mkdir -p /mnt/nextcloud/Photos/$year/$month - rsync -aq $LOCAL_PHOTOS/$year/$month/* /mnt/nextcloud/Photos/$year/$month - if [ -z "$firstrun" -a $lastrun_month -ne $month ] - then - if [ ! -d /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month ] - then - mkdir -p /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month - fi - # TODO: What if we're more than a month behind? - rsync -aq $LOCAL_PHOTOS/$lastrun_year/$lastrun_month/* /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month - fi - - # Rsync from ~/Documents/Mobile to WebDAV - echo "Syncing mobile documents from $mobile_docs to WebDAV" - rsync -aq "$mobile_docs"/* /mnt/nextcloud/Documents - - # Rsync from WebDAV to ~/Documents/Mobile - echo "Syncing mobile documents from WebDAV to $mobile_docs" - rsync -aq /mnt/nextcloud/Documents/* "$mobile_docs" - - # Finish by unmounting the WebDAV folder - echo "Unmounting $server_fqdn" - umount /mnt/nextcloud -else - echo "NextCloud WebDAV mount FAILED. Exiting." - exit -2 -fi - -echo "Completed cloud sync at `date`" diff --git a/.local/lib/cron.avail/weather.sh b/.local/lib/cron.avail/weather.sh @@ -1,12 +0,0 @@ -#!/bin/sh -if ping -c 1 ipinfo.io > /dev/null 2>&1 -then - echo "ipinfo reachable. Proceeding." -else - echo "ipinfo NOT reachable. Aborting." - exit 1 -fi - -cd "$HOME/.local/lib/forecastio/" - -./weather.py diff --git a/.local/lib/forecastio/weather.py b/.local/lib/forecastio/weather.py @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -from datetime import datetime -import math -import os -import sys -import forecastio -import requests - -def generate_forecast(): - error = False - latitude = None - longitude = None - - try: - # I keep my api key for forecast.io in a separate text file so - # I don't accidentally publish it anywhere. - with open('forecastio_api.txt', 'r') as apifile: - api_key = apifile.read() - api_key = api_key.strip() - - try: - with open('zipcode.txt', 'r') as zipcodefile: - zipcode = zipcodefile.read() - zipcode = zipcode.strip() - except FileNotFoundError: - zipcode = None - - if zipcode is None: - # Resolving location from IP is always going to be a best - # guess, but it's better than hardcoding location data - latitude, longitude = requests.get('https://ipinfo.io'). \ - json()['loc'].split(',') - else: - try: - with open('zipcodeapi_api.txt', 'r') as zipcodeapifile: - zipcodeapi_key = zipcodeapifile.read() - zipcodeapi_key = zipcodeapi_key.strip() - except FileNotFoundError: - sys.stdout.writelines( - datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + - " Could not find zipcodeapi key\n") - exit() - - location = requests.get('https://www.zipcodeapi.com/rest/' \ - + zipcodeapi_key + '/info.json/' + zipcode + \ - '/degrees').json() - latitude = location['lat'] - longitude = location['lng'] - - # Now we're ready to actually get the weather - forecast = forecastio.load_forecast(api_key, latitude, longitude) - - current_temp = forecast.currently() - day = forecast.daily() - - if 'LANG' in os.environ and \ - os.environ['LANG'].find('UTF-8') != -1: - degree_symbol = "\u00b0" - else: - degree_symbol = "" - - temp = str(current_temp.temperature) + degree_symbol + " F" - high = str(int(math.ceil(day.data[0].temperatureMax))) - low = str(int(math.ceil(day.data[0].temperatureMin))) - - out_filename = os.path.join( - os.environ['HOME'], - '.local/var/forecastio/current_forecast.txt' - ) - - with open(out_filename, 'w') as outfile: - outfile.write(temp + ", " + str(current_temp.summary) + \ - ", " + high + degree_symbol + "/" +low + \ - degree_symbol + " F") - except requests.exceptions.ConnectionError: - error = True - sys.stdout.writelines( - datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + - " Could not connect. Will try again in 5 minutes.\n") - - if not error: - sys.stdout.writelines( - datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + - " Successfully updated weather\n") - -if __name__ == '__main__': - sys.stdout.writelines( - datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + - " Updating weather\n") - generate_forecast() diff --git a/.local/lib/tmux/battery_indicator.sh b/.local/lib/tmux/battery_indicator.sh @@ -1,17 +0,0 @@ -#!/bin/sh -# -# ~/.local/lib/tmux/battery_indicator.sh -# -SMILE='☻ ' - -charged_slots=$((`my battery percent` / 25)) -[ $charged_slots -gt 3 ] && charged_slots=3 - -echo -n '#[fg=green]' -for i in `seq 1 $charged_slots`; do echo -n "$SMILE"; done - -if [ $charged_slots -lt 3 ]; then - echo -n '#[fg=red]' - uncharged_slots=$((3-$charged_slots)) - for i in `seq 1 $uncharged_slots`; do echo -n "$SMILE"; done -fi diff --git a/.local/man/man1/my.1 b/.local/man/man1/my.1 @@ -1,201 +0,0 @@ -.TH MY 1 "September 2019" "djmoch 0.0" "DJMOCH Commands Manual" -.SH NAME -my \- utility functions for use across dotfiles and elsewhere -.SH SYNOPSIS -.SY my -\fISUBCOMMAND\fR [\fIARGS\fR] -.YS -.SH DESCRIPTION -\fBmy\fR runs the subcommand specified by \fISUBCOMMAND\/\fR, passing any provided -\fIARGS\/\fR along. Many of the available subcommands amount to a list of providers -which are searched in the $PATH, with the first one found being executed. This -design allows for dotfiles to port across machines with relative ease. -.SH SUBCOMMANDS -.PP -.TP -\fBmailto\fR -Send email. -.sp -Command synopsis: \fBmy\fR \fBmailto\fR [\fIaddress\fR]\fR [\fIsubject\fR] -.TP -\fBsearch\fR -Search DuckDuckGo in the terminal. -.sp -Command synopsis: \fBmy\fR \fBsearch\fR [\fIterm\fR] (shell quoting rules apply) -.TP -\fBterm\fR -Open an X terminal window. This subcommand follows an order of preference for which -terminal emulator is used. -.sp -The current order is: -.sp -1. st -.br -2. urxvtc (if urxvtd is available) -.br -3. urxvt -.br -4. xterm -.br -5. xfce4-terminal -.br -6. gnome-terminal -.TP -\fBlock\fR -Lock the X session. -.TP -\fBwallpaper\fR -Set the xroot color and, if available, set the wallpaper using the feh .fehbg command. -.TP -\fBstandby\fR -Put the machine into hybrid-sleep mode. -.TP -\fBshutdown\fR -Shut down the machine. -.TP -\fBperms\fR -Search for all of the files in \fIHOME\fR beginning with a dot (i.e., a dotfile) and -sets its permissions via chmod to be inaccessible to everyone except the file owner. -.TP -\fBinit\fR -Perform initializations necessary for "moving in." -.sp -Command synopsis: \fBmy\fR \fBinit\fR [\fI\-f\fR][\fI\-c\fR] -.sp -When run with \fI\-f\fR, the command is forced to run completely, even if it has -already been run. When run with \fI\-c\fR, the user crontab is also initialized. -.sp -In addition to optionally initializing the crontab, init initializes custom termcaps, .less, ensures -the login shell is set to /bin/sh, creates an autostart entry for an available screen locker based -on a preference list and availability in \fIPATH\fR, and initializes gpg-agent.conf to point to the -correct pinentry program. Finally, init creates several folders required for proper behavior of -dotfiles. -.sp -When complete, init touches the file $HOME/._.djmoch to act as a flag for the last time the dotfiles -where updated/initialized. See the \fBlogin\fR subcommand for more details of how this file is used. -.TP -\fBopen\fR -Open a file in the configured XDG handler specific to the file's MIME type, or, optionally, in a -configured terminal handler. -.sp -Command synopsis: \fBmy\fR \fBopen\fR [\fI\-T\fR] \fIFILE\fR -.sp -When the \fI\-T\fR flag is provided, the file is opened in a terminal handler configured in a -different file. See my-open.config(5) for more information an how to configure terminal handlers. -.TP -\fBsound\fR -Adjust the sound settings or display sound status. -.sp -Command synopsis: \fBmy\fR \fBsound\fR [\fIstatus\fR] ... -.sp -If the \fIstatus\fR action is provided, then the current status of the sound sinks and sources -is put out. If the status is not requested, then other command arguments should be provided -according to pactl(1). -.TP -\fBkbopts\fR -Set X keyboard options. -.TP -\fBscreen\fR -Set screen options. This is more or less deprecated in favor of autorandr(1). -.TP -\fBbrightness\fR -Sets the brightness of the provided monitor using the xbacklight(1) utility. -.sp -Command synopsis: \fBmy\fR \fBbrightness\fR \fICTRL\fR ... -.sp -The \fICTRL\fR argument should be the name of an attached display device, or the generic -argument "monitor," which simply looks determines the name of the (only) attached display -device. The remaider of the command arguments follow the description in xbacklight(1). -.TP -\fBbattery\fR -Show information about the battery. -.sp -Command synopsis: \fBmy\fR \fBbattery\fR [\fIremaining\fR][\fItotal\fR][\fIpercent\fR] -.sp -The \fIpercent\fR argument will probably be the only one of any interest. The others are -used internally to calculate the percent, and their representation is dependent on the -operating system. -.TP -\fBstatus\fR -Print an embeddable status message showing the remaining battery percentage, the current -weather, and the time. -.TP -\fBi3status\fR -Same as status, but automatically prints the status to stdout every 15 seconds, allowing -it to be used in the status bar of the i3 window manager. -.TP -\fBcopy\fR -An os-independent way to copy text from the terminal into the system clipboard. -.TP -\fBpaste\fR -An os-independent way to paste text from the system clipboard into the terminal. -.TP -\fBnetrc\fR -Parses netrc to return username/password information for use in configuration files or -anywhere a service credential might be required. Note that this subcommand calls out -to a handler written in Python. -.sp -Command synopsis: \fBmy\fR \fBnetrc\fR \fI<server>\fR [\fIlogin\fR][\fIaccount\fR] -[\fIpassword\fR] -.sp -The \fIserver\fR argument should be the fully-qualified domian name of the server whose -credential is being requested. One of the three optional arguments, \fIlogin\fR, -\fIaccount\fR, or \fIpassword\fR may also be provided, in which case only that portion -of the credential will be provided. If none of the optional arguments are provided, then -all three will be returned. All responses are provided on stdout. -.TP -\fBdotfiles\fR -Perform one of several maintanence actions on the dotfiles. -.sp -Command synopsis: \fBmy\fR \fBdotfiles\fR <\fIargument\fR> -.sp -\fIargument\fR may be one of \fIcheck\fR, in which case the ._.djmoch file in consulted -to see when the dotfiles were last updated, or \fIupdate\fR, in which case the dotfiles -are actually updated. Whether or not \fIupdate\fR actually does anything is conditioned -on whether the dotfiles are sourced from a tarfile. If the dotfiles are sourced from a -Git repository, then \fIupdate\fR does nothing. -.TP -\fBcron\fR -Run configured cron tasks. This subcommand should be called either from a user crontab -or a user systemd timer. -.sp -Command synopsis: \fBmy\fR \fBcron\fR [\fIsystemd\fR] -.sp -If the \fIsystemd\fR argument is provided, then the job output is sent to stdout, -otherwise no output is given. -.sp -Any script located in $HOME/.local/lib/cron.d (either physically or via link) will be -executed. Note that cron scripts that are included in the dotfiles are located in -$HOME/.local/lib/cron.avail and must be linked into cron.d before they will be -activated. -.sp -Recall that \fBinit\fR will either place an entry in the user crontab or create a user -systemd timer to call \fBmy cron\fR. -.TP -\fBlogin_async\fR -This should really be called login_sync, since it is the synchronous (i.e. blocking) -version of the login command (see \fBmy login\fR to run as a background job). -.sp -\fBlogin_async\fR will attempt to contact the dotfiles server for up to two minutes -from the point it is called. If it is able to make contact, it consults the ._.djmoch -file to see if the dotfiles have to updated in the past week. If not, it calls \fBmy -dotfiles update\fR. -.TP -\fBlogin\fR -Calls \fBmy login_async\fR as a background job. -.TP -\fBprocesses\fR -List's the current users running processes. -.PP -.SH EXIT STATUS -.PP -.TP -\fB0\fR -\fISUBCOMMAND\fR executed successfully. -.TP -\fB1\fR -Error executing \fISUBCOMMAND\fR. -.PP -.SH SEE ALSO -feh(1), chmod(1), my-open.config(5), pactl(1), autorandr(1), xbacklight(1), crontab(5), -systemd.timer(5) diff --git a/.muttrc b/.muttrc @@ -1,203 +0,0 @@ -# Headers -ignore * -unignore from: subject to cc date x-mailer x-url user-agent list-id - -hdr_order date from to cc subject list-id - -# Macros -macro index \eb "<search>~b " "search in message bodies" - -macro index,pager,attach,compose \cb "\ -<enter-command> set my_pipe_decode=\$pipe_decode pipe_decode<Enter>\ -<pipe-message> urlview<Enter>\ -<enter-command> set pipe_decode=\$my_pipe_decode; unset my_pipe_decode<Enter>" \ -"call urlview to extract URLs out of a message" - -macro generic,pager <F1> "<shell-escape> less /usr/share/doc/mutt/manual.txt<Enter>" "show Mutt documentation" - -macro index,pager y "<change-folder>?<toggle-mailboxes>" "show incoming mailboxes list" - -macro index <F9> "<sync-mailbox><enter-command>source ~/.config/mutt/account.dotcom<enter><change-folder>!<enter>" -macro index <F10> "<sync-mailbox><enter-command>source ~/.config/mutt/account.icloud<enter><change-folder>!<enter>" -macro index <F11> "<sync-mailbox><enter-command>source ~/.config/mutt/account.fullsail<enter><change-folder>!<enter>" -macro index <F8> \ -"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\ -<shell-escape>notmuch-mutt -r --prompt search<enter>\ -<change-folder-readonly>`echo ${XDG_CACHE_HOME:-$HOME/.cache}/notmuch/mutt/results`<enter>\ -<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \ -"notmuch: search mail" - -macro index <F4> \ -"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\ -<pipe-message>notmuch-mutt -r thread<enter>\ -<change-folder-readonly>`echo ${XDG_CACHE_HOME:-$HOME/.cache}/notmuch/mutt/results`<enter>\ -<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \ -"notmuch: reconstruct thread" - -macro generic,pager <F5> "<enter-command>toggle sidebar_visible<enter>" "Toggle the sidebar" - -# Hooks -message-hook '~s .*' 'uncolor body red default "^-.*"' -message-hook '~s .*' 'uncolor body green default "^\\+.*"' -message-hook '~s .*' 'uncolor body cyan default "^@@.*"' -message-hook '~s .*' 'uncolor body brightwhite default "^(diff|index|new|\\+\\+\\+|---).*"' -message-hook '~s \\[PATCH' 'color body red default "^-.*"' -message-hook '~s \\[PATCH' 'color body green default "^\\+.*"' -message-hook '~s \\[PATCH' 'color body cyan default "^@@.*"' -message-hook '~s \\[PATCH' 'color body brightwhite default "^(diff\\s|index\\s|new\\s|\\+\\+\\+|---).*"' - -# General Settings -set realname = "Daniel Moch" -set sendmail_wait = -1 -set sort = "threads" -set strict_threads = "yes" -set sort_browser = "alpha" -set sort_aux = "last-date-received" -set query_command = "khard email --parsable --search-in-source-files '%s'" -set sidebar_sort_method = "alpha" -set sidebar_visible -unset collapse_unread - -bind browser y exit -bind index - collapse-thread -bind index _ collapse-all -bind index J sidebar-next -bind index K sidebar-prev -bind index O sidebar-open -bind pager j next-line -bind pager <Down> next-line -bind pager k previous-line -bind pager <Up> previous-line -bind pager \Cu half-up -bind pager \Cd half-down - -mime_lookup application/octet-stream - -attachments +A */.* -attachments -A text/x-vcard application/pgp.* -attachments -A application/x-pkcs7-.* -attachments +I text/plain -attachments -A message/external-body -attachments -I message/external-body - -auto_view text/html -alternative_order text/plain text/enriched text/html - -# GPG -set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f" -set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f" -set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f" -set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f" -set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f" -set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f" -set pgp_encrypt_sign_command="pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f" -set pgp_import_command="gpg --no-verbose --import %f" -set pgp_export_command="gpg --no-verbose --export --armor %r" -set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r" -set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --with-fingerprint --list-keys %r" -set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --with-fingerprint --list-secret-keys %r" -set pgp_good_sign="^\\[GNUPG:\\] GOODSIG" -set pgp_decryption_okay="^\\[GNUPG:\\] DECRYPTION_OKAY" - -# S/MIME -set smime_timeout=300 -set crypt_autosign = yes -set crypt_replyencrypt = yes -set crypt_replysign = yes -set crypt_replysignencrypted = yes -set crypt_verify_sig = yes -set smime_default_key="12345678.0" -set smime_ca_location="/usr/local/etc/openssl/cert.pem" -set smime_certificates="~/.mutt/smime/certificates" -set smime_keys="~/.mutt/smime/keys" -set smime_pk7out_command="openssl smime -verify -in %f -noverify -pk7out" -set smime_get_cert_command="openssl pkcs7 -print_certs -in %f" -set smime_get_signer_cert_command="openssl smime -verify -in %f -noverify -signer %c -out /dev/null" -set smime_get_cert_email_command="openssl x509 -in %f -noout -email" -set smime_import_cert_command="smime_keys add_cert %f" -set smime_encrypt_with="aes256" -set smime_encrypt_command="openssl smime -encrypt -%a -outform DER -in %f %c" -set smime_sign_digest_alg="sha256" -set smime_sign_command="openssl smime -sign -md %d -signer %c -inkey %k -passin stdin -in %f -certfile %i -outform DER" -set smime_decrypt_command="openssl smime -decrypt -passin stdin -inform DER -in %f -inkey %k -recip %c" -set smime_verify_command="openssl smime -verify -inform DER -in %s %C -content %f" -set smime_verify_opaque_command="\ -openssl smime -verify -inform DER -in %s %C || \ -openssl smime -verify -inform DER -in %s -noverify 2>/dev/null" - -# Colors -color normal default default -color error brightred default -color tilde default default -color message default default -color markers default default -color attachment default default -color search default default -color status brightwhite blue -color indicator black white -color tree blue default - -mono bold bold -mono underline underline -mono indicator reverse -mono error bold - -color index default default "~A" # all messages -color index red default "~E" # expired messages -color index default default "~N" # new messages -color index default default "~O" # old messages -color index default default "~Q" # messages that have been replied to -color index default default "~R" # read messages -color index default default "~U" # unread messages -color index default default "~U~$" # unread, unreferenced messages -color index default default "~v" # messages part of a collapsed thread -color index white default "~P" # messages from me -color index blue default "~p!~F" # messages to me -color index blue default "~N~p!~F" # new messages to me -color index blue default "~U~p!~F" # unread messages to me -color index blue default "~R~p!~F" # messages to me -color index brightgreen default "~F" # flagged messages -color index brightgreen default "~F~p" # flagged messages to me -color index brightgreen default "~N~F" # new flagged messages -color index brightgreen default "~N~F~p" # new flagged messages to me -color index brightgreen default "~U~F~p" # new flagged messages to me -color index brightwhite red "~D" # deleted messages -color index white default "~v~(!~N)" # collapsed thread with no unread -color index default default "~v~(~N)" # collapsed thread with some unread -color index white default "~N~v~(~N)" # collapsed thread with unread parent -color index brightgreen default "~v~(~F)!~N" # collapsed thread with flagged, no unread -color index default default "~v~(~F~N)" # collapsed thread with some unread & flagged -color index brightgreen default "~N~v~(~F~N)" # collapsed thread with unread parent & flagged -color index brightgreen default "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged -color index white default "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly -color index black red "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial) -color hdrdefault default default -color header default default "^(From)" -color header default default "^(Subject)" -color quoted green default -color quoted1 magenta default -color quoted2 green default -color quoted3 red default -color quoted4 yellow default -color signature default default -color bold default default -color underline underline default default -color normal default default -color body bold default default "[;:][-o][)/(|]" # emoticons -color body bold default default "[;:][)(|]" # emoticons -color body bold default default "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\ - |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\ - |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?" -color body bold default default "[ ][*][^*]*[*][ ]?" # more emoticon? -color body bold default default "[ ]?[*][^*]*[*][ ]" # more emoticon? -color body brightwhite red "(BAD signature)" -color body default default "(Good signature)" -color body default default "^gpg:Good signature .*" -color body default default "^gpg: " -color body brightwhite red "^gpg:BAD signature from.*" -mono body bold "^gpg: Good signature" -mono body bold "^gpg: BAD signature from.*" -color body blue default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]" -color body blue default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])" - -source ~/.config/mutt/account.default diff --git a/.profile b/.profile @@ -19,7 +19,7 @@ __addpath () fi } -for file in "$HOME"/.profile.d/*.sh +for file in "$HOME"/etc/profile.d/*.sh do [ -r $file ] && . $file done diff --git a/.profile.d/env.sh b/.profile.d/env.sh @@ -1,5 +0,0 @@ -if [ -r "$HOME/.shrc" ] -then - ENV="$HOME/.shrc" - export ENV -fi diff --git a/.profile.d/go.sh b/.profile.d/go.sh @@ -1,6 +0,0 @@ -if type go > /dev/null 2>&1 -then - GOPATH="$HOME/.go" - export GOPATH - __addpath "$HOME/.go/bin" -fi diff --git a/.profile.d/my.sh b/.profile.d/my.sh @@ -1 +0,0 @@ -__addpath "$HOME/.local/bin" "before" diff --git a/.shrc b/.shrc @@ -1,13 +0,0 @@ -# -# ~/.shrc -# -case $TERM in -st*|rxvt*|xterm*) printf "\033]0;$LOGNAME@$HOSTNAME\007" ;; -esac - -for file in "$HOME"/.shrc.d/*.sh -do - [ -r $file ] && . $file -done - -unset -v file diff --git a/.tmux.conf b/.tmux.conf @@ -98,8 +98,8 @@ set-option -g display-panes-colour $tm_color_inactive set-window-option -g clock-mode-colour $tm_color_active -tm_weather="#[fg=$tm_color_feature]#(cat ~/.local/var/forecastio/current_forecast.txt)" -tm_battery="#(~/.local/lib/tmux/battery_indicator.sh)" +tm_weather="#[fg=$tm_color_feature]#(cat ~/var/forecastio/current_forecast.txt)" +tm_battery="#(~/lib/tmux/battery_indicator.sh)" tm_date="#[fg=$tm_color_inactive] %R %d %b" tm_host="#[fg=$tm_color_feature]#h" diff --git a/.w3m/config b/.w3m/config @@ -28,7 +28,7 @@ auto_image 0 max_load_image 4 ext_image_viewer 1 image_scale 100 -imgdisplay ~/.local/bin/my-open +imgdisplay ~/bin/my-open image_map_list 1 fold_line 0 show_lnum 0 @@ -68,34 +68,34 @@ decode_cte 0 auto_uncompress 0 preserve_timestamp 1 keymap_file keymap -document_root -personal_document_root -cgi_bin -index_file +document_root +personal_document_root +cgi_bin +index_file mime_types ~/.mime.types, /usr/share/cups/mime/mime.types mailcap ~/.mailcap urimethodmap ~/.w3m/urimethodmap, /usr/etc/w3m/urimethodmap editor $EDITOR mailto_options 1 -mailer ~/.local/bin/my mailto -extbrowser ~/.local/bin/my-open -extbrowser2 -extbrowser3 -extbrowser4 -extbrowser5 -extbrowser6 -extbrowser7 -extbrowser8 -extbrowser9 +mailer ~/bin/my mailto +extbrowser ~/bin/my-open +extbrowser2 +extbrowser3 +extbrowser4 +extbrowser5 +extbrowser6 +extbrowser7 +extbrowser8 +extbrowser9 bgextviewer 1 use_lessopen 1 passwd_file ~/.w3m/passwd disable_secret_security_check 0 -ftppasswd +ftppasswd ftppass_hostnamegen 1 pre_form_file ~/.w3m/pre_form siteconf_file ~/.w3m/siteconf -user_agent +user_agent no_referer 0 accept_language en;q=1.0 accept_encoding gzip, compress, bzip, bzip2, deflate @@ -106,29 +106,29 @@ default_url 0 follow_redirection 10 meta_refresh 0 dns_order 0 -nntpserver -nntpmode +nntpserver +nntpmode max_news 50 use_proxy 1 -http_proxy -https_proxy -ftp_proxy -no_proxy +http_proxy +https_proxy +ftp_proxy +no_proxy noproxy_netaddr 1 no_cache 0 ssl_forbid_method 2, 3 ssl_verify_server 1 -ssl_cert_file -ssl_key_file -ssl_ca_path -ssl_ca_file +ssl_cert_file +ssl_key_file +ssl_ca_path +ssl_ca_file use_cookie 1 show_cookie 0 accept_cookie 1 accept_bad_cookie 0 -cookie_reject_domains -cookie_accept_domains -cookie_avoid_wrong_number_of_dots +cookie_reject_domains +cookie_accept_domains +cookie_avoid_wrong_number_of_dots display_charset UTF-8 document_charset UTF-8 auto_detect 2 diff --git a/.local/bin/dviprint b/bin/dviprint diff --git a/bin/fws b/bin/fws @@ -0,0 +1,16 @@ +#!/bin/sh +# +# ~/bin/fws +# +# Remove trailing whitespace recursively. Pass in file extensions to +# search for. + +case `uname -s` in + CYGWIN*) ext='\r' ;; + *) ext="" ;; +esac + +for arg +do + find . -name *.$arg -exec sed -i -e "s/[[:space:]]*\$/$ext/g" '{}' \; +done diff --git a/.local/bin/ix b/bin/ix diff --git a/bin/my b/bin/my @@ -0,0 +1,443 @@ +#!/bin/sh +# +# ~/bin/my +# + +# Command and handlers for them are added as-needed. Some commands only +# have one handler, but exist to avoid re-writes across my dotfiles +# later on. + +[ $# -eq 0 ] && exit 1 + +log="$HOME/var/log/my" +command=$1 +shift + +__mylog() +{ + echo "$1 (`date +'%m/%d/%Y %H:%M:%S'`): $2" >> $log +} + +__getlocker() +{ + if type slock > /dev/null 2>&1 + then + echo slock + exit 0 + fi + for locker in slock light-locker cinnamon-screensaver gnome-screensaver xscreensaver + do + if my processes | grep $locker > /dev/null 2>&1 + then + echo $locker + exit 0 + fi + done + + __mylog "__getlocker" "No screen locker running" + exit 1 +} + +case $command in + mailto) + for m in mutt mail + do + if type $m > /dev/null 2>&1 + then + mailer=$m + break + fi + done + if [ -n "$2" ] + then + $mailer -s "$2" $1 + else + $mailer $1 + fi + ;; + search) + query=`echo $1 | tr ' ' '+'` + exec my open -T https://duckduckgo.com/?q=$query + ;; + term) + SHLVL=0; export SHLVL + if type st > /dev/null 2>&1 + then + exec st "$@" + elif type urxvtd > /dev/null 2>&1 + then + urxvtc "$@" + if [ "$?" -eq 2 ] + then + urxvtd -q -o -f + urxvtc "$@" + fi + exit 0 + elif type urxvt > /dev/null 2>&1 + then + exec urxvt "$@" + elif type xterm > /dev/null 2>&1 + then + exec xterm "$@" + elif type x-terminal-emulator > /dev/null 2>&1 + then + exec x-terminal-emulator "$@" + fi + + [ "$1" = "-e" ] && shift && set -- "-x" $@ + if type xfce4-terminal > /dev/null 2>&1 + then + exec xfce4-terminal "$@" + elif type gnome-terminal > /dev/null 2>&1 + then + exec gnome-terminal "$@" + fi + + __mylog "my term" "No terminal emulator found" + exit 1 + ;; + lock) + sleep 1 + + locker=`__getlocker` + + if [ -z "$locker" ] + then + __mylog "my lock" "no locker running" + exit 1 + fi + [ "$locker" = "light-locker" -o "$locker"="slock" ] || $locker-command -l + exec xset dpms force off + ;; + wallpaper) + xsetroot -solid "#444444" + [ -x "$HOME/.fehbg" ] && "$HOME/.fehbg" >> $log 2>&1 + ;; + standby) + if type systemctl > /dev/null 2>&1 + then + locker=`__getlocker` + if [ -z "$locker" ] + then + __mylog "my standby" "no locker running" + exit 1 + fi + if [ ! "$locker" = "light-locker" ] + then + sleep 1 + $locker-command -l + xset dpms force off + fi + exec systemctl hybrid-sleep + else + __mylog "my standby" "No handler found" + fi + ;; + shutdown) + if type systemctl > /dev/null 2>&1 + then + exec systemctl poweroff + elif type poweroff > /dev/null 2>&1 + then + exec my term -e sudo poweroff + else + __mylog "my shutdown" "No handler found" + fi + ;; + perms) + exec my-perms "$@" + ;; + init) + exec my-init "$@" + ;; + open) + exec my-open "$@" + ;; + sound) + if type pactl > /dev/null 2>&1 && pactl stat > /dev/null 2>&1 + then + [ -z "$1" ] && exit 1 + if [ $1 = "status" ] + then + sink_status=`pactl list sinks | grep ^[[:space:]]*Volume | awk '{print $5}'` + source_status=`pactl list sources | grep ^[[:space:]]*Volume | awk '{print $5}'` + echo -n "Sinks: " + for sink in $sink_status + do + echo -n "$sink " + done + echo "" + echo -n "Sources: " + for source in $source_status + do + echo -n "$source " + done + echo "" + exit 0 + else + exec pactl "$@" + fi + else + __mylog "my sound" "No handler found" + fi + ;; + kbopts) + setxkbmap -option -option ctrl:nocaps + ;; + screen) + xrandr_options=`xrandr -q | grep ' disconnected' | awk '{print $1}'` + for option in $xrandr_options + do + xrandr --output $option --off + done + + xrandr_options=`xrandr -q | grep ' connected' | awk '{print $1}'` + numoptions=`echo $xrandr_options | wc -w` + if [ $numoptions -eq 1 ] + then + xrandr --output $xrandr_options --auto --primary + else + # Prefer external monitors + # If more than one display is connected, then enable the + # first non-primary display, and turn off all the others. + primary=`xrandr -q | grep primary | awk '{print $1}'` + + for option in $xrandr_options + do + [ $option = $primary ] && primary_found=1 && continue + [ -n "$primary_found" ] && selection=$option && break + done + + xrandr --output $selection --auto --primary + + for option in $xrandr_options + do + [ $option != $selection ] && xrandr --output $option --off + done + fi + exec my wallpaper + ;; + brightness) + if type xbacklight > /dev/null 2>&1 + then + if [ "$1" = "monitor" ] + then + # Future-proofing ... gmux is specific, imagine other + # systems will be different + for opt in gmux intel_backlight + do + selection=`xbacklight -list | grep $opt` + num=`echo $selection | wc -w` + [ $num -gt 0 ] && break + done + else + selection=`xbacklight -list | grep $1` + num=`echo $selection | wc -w` + fi + [ $num -gt 1 ] && __mylog "my brightness" "More than one $1" && exit 1 + [ $num -lt 1 ] && __mylog "my brightness" "No $1 to adjust" && exit 1 + shift + exec xbacklight -ctrl $selection "$@" + else + __mylog "my brightness" "No handler found" + fi + ;; + battery) + uname=`uname -s` + + case $1 in + remaining) + case $uname in + *Linux*) + if [ `acpi | wc -l` -eq 2 ] + then + acpi | awk 'getline' | awk '{print $4}' | sed 's~%~~' | sed 's~,~~' + else + acpi | awk '{print $4}' | sed 's~%~~' | sed 's~,~~' + fi + ;; + *Darwin*) + battery_info=`ioreg -rc AppleSmartBattery` + echo $battery_info | grep -o '"CurrentCapacity" = [0-9]\+' | awk '{print $3}' + ;; + *CYGWIN*) + wmic path Win32_Battery Get EstimatedChargeRemaining /format:list 2>/dev/null | grep '[^[:blank:]]' | cut -d= -f2 + ;; + *) + echo "no battery status" + exit 1 + esac + exit 0 + ;; + total) + case $uname in + *Linux*|*CYGWIN*) + echo 100 + ;; + *Darwin*) + battery_info=`ioreg -rc AppleSmartBattery` + echo $battery_info | grep -o '"MaxCapacity" = [0-9]\+' | awk '{print $3}' + ;; + *) + echo "no battery status" + exit 1 + esac + exit 0 + ;; + percent) + echo "$((`my battery remaining` * 100 / `my battery total`))" + exit 0 + ;; + esac + ;; + status) + echo -n "Batt: `my battery percent`% | " + cat $HOME/var/forecastio/current_forecast.txt | tr -d '\n' + echo -n " | " + date +'%l:%M %p' + exit 0 + ;; + i3status) + while : + do + echo "`my status`" || exit 1 + sleep 15 + done + ;; + copy) + uname=`uname -s` + + case $uname in + *Darwin*) + reattach-to-user-namespace pbcopy + ;; + *CYGWIN*) + cat > /dev/clipboard + ;; + *Linux*) + xclip -selection clipboard + ;; + *) + return + esac + ;; + paste) + uname=`uname -s` + + case $uname in + *Darwin*) + reattach-to-user-namespace pbpaste + ;; + *CYGWIN*) + cat /dev/clipboard + ;; + *Linux*) + xclip -o + ;; + *) + return + esac + ;; + netrc) + exec my-netrc "$@" + ;; + dotfiles) + predicate="$1" && shift + case $predicate in + check) + cd "$HOME" + aweekago=$(($(date +%s) - 604800)) + lastupdate=$(stat --format=%Y ._.djmoch) + [ $lastupdate -lt $aweekago ] && "Dotfiles more than one week old" + ;; + update) + if [ -d "$HOME/.dotfiles_tgz" ] + then + + if type sha256sum > /dev/null 2>&1 + then + sha_exec=sha256sum + fieldnum=1 + else + sha_exec=sha256 + fieldnum=4 + fi + + curl -s https://git.danielmoch.com/dotfiles/snapshot/dotfiles-master.tar.gz > /tmp/dotfiles.tgz.$$ + oldsum=`$sha_exec "$HOME/.dotfiles_tgz/dotfiles.tar.gz" | cut -d ' ' -f $fieldnum` + newsum=`$sha_exec "/tmp/dotfiles.tgz.$$" | cut -d ' ' -f $fieldnum` + if [ ! "$oldsum" = "$newsum" ] + then + mv /tmp/dotfiles.tgz.$$ "$HOME/.dotfiles_tgz/dotfiles.tar.gz" + cd "$HOME" + tar xzf .dotfiles_tgz/dotfiles.tar.gz + for file in $(ls -A dotfiles-master) + do + cp -r dotfiles-master/$file . + done + rm -rf dotfiles-master + else + rm /tmp/dotfiles.tgz.$$ + fi + fi + my init -f > /dev/null 2>&1 + touch "$HOME/._.djmoch" + ;; + esac + ;; + cron) + [ "$1" = systemd ] && mycron_systemd=1 + case ":$PATH:" in + *:"$HOME/bin":*) ;; + *) PATH="$HOME/bin:$PATH" ;; + esac + cronpath="$HOME/lib/cron.d" + logpath="$HOME/var/log" + for job in $cronpath/* + do + if [ -x $job ] + then + if [ -n "$mycron_systemd" ] + then + $job + else + $job > $logpath/`basename $job` 2>&1 + fi + fi + done + ;; + login_async) + starttime=`date '+%s'` + runningtime=0 + while [ $runningtime -le 120 ] + do + if ping -c 1 danielmoch.com > /dev/null 2>&1 + then + connected=1 + break + fi + sleep 1 + runningtime=$((`date '+%s'` - $starttime)) + done + if [ -n "$connected" ] + then + cd "$HOME" + aweekago=$(($(date +%s) - 604800)) + lastupdate=$(stat --format=%Y ._.djmoch) + [ $lastupdate -lt $aweekago ] && my dotfiles update + fi + ;; + login) + my login_async & + ;; + processes) + if [ -L /bin/ps ] + then + # busybox + ps -o user,comm= | grep $LOGNAME | awk '{print $2;}' + else + ps -U $LOGNAME -o comm= + fi + ;; + *) echo "my: command $command not found" >&2 +esac diff --git a/bin/my-init b/bin/my-init @@ -0,0 +1,254 @@ +#!/bin/sh +# +# ~/bin/my-init +# +# A place to dump run-once type initializations + +while [ -n "$1" ] +do + [ "$1" = "-f" ] && force_init=1 + [ "$1" = "-c" ] && crontab_init=1 + shift +done + +vim_bundle_path="$HOME/.vim/pack/bundle" +configdir=${XDG_CONFIG_HOME:-$HOME/.config} + +__has() +{ + for token in $@ + do + type $token > /dev/null 2>&1 + [ $? -ne 0 ] && echo " $token doesn't exist" && return 1 + done + return 0 +} + +__clone() +{ + dir=`echo "$1" | cut -d '/' -f2` + if [ -d $dir ] + then + echo -n " Updating $1 ..." + cd $dir + git pull > /dev/null 2>&1 + result=$? + cd .. + else + echo -n " Cloning $1 ... " + git clone https://github.com/$1.git > /dev/null 2>&1 + result=$? + fi + [ $result -ne 0 ] && echo "FAILED!" && return 1 + echo "Succeeded" +} + +__optclone_pathogen() +{ + vim --cmd "redir! > /tmp/vimpackages.$$ | silent echo has('packages') | q" + case `cat /tmp/vimpackages.$$` in + *0*) + if [ -d vim-pathogen ] + then + echo -n " Updating tpope/vim-pathogen ..." + cd vim-pathogen + git pull > /dev/null 2>&1 + result=$? + cd .. + else + echo -n " Cloning tpope/vim-pathogen ... " + git clone https://github.com/tpope/vim-pathogen.git > /dev/null 2>&1 + result=$? + fi + [ $result -ne 0 ] && echo "FAILED!" && return 1 + echo "Succeeded" + ;; + esac + rm /tmp/vimpackages.$$ +} + + +if [ -n "$force_init" ] +then + echo "Re-initialization requested" + rm -f "$HOME/._.djmoch" + rm -rf "$HOME/.terminfo" + rm "$HOME/.less" + rm "$HOME/.gnupg/gpg-agent.conf" +fi + +if [ -f "$HOME/._.djmoch" ] +then + echo "Already initialized. Exiting." + exit 0 +fi + +echo "Performing run-once initializations" + +if __has "infocmp" "tic" +then + echo " Initializing Termcaps" + if infocmp tmux-256color > /dev/null 2>&1 + then + tic "$HOME/lib/terminfo/tmux.terminfo" + else + tic "$HOME/lib/terminfo/tmux-from-screen.terminfo" + fi +fi + +if __has "lesskey" +then + echo " Initializing .less" + lesskey +fi + +if my processes | grep systemd > /dev/null 2>&1 \ + && [ -n "$crontab_init" ] +then + echo " Installing systemd timers" + cat >> $configdir/systemd/user/my-cron.service <<-EOF +[Unit] +Description=djmoch "my cron" service + +[Service] +Type=simple +ExecStart=$HOME/bin/my cron systemd +EOF + cat >> $configdir/systemd/user/my-cron.timer <<-EOF +[Unit] +Description=djmoch "my cron" timer + +[Timer] +OnBootSec=1min +OnUnitActiveSec=15min + +[Install] +WantedBy=timers.target +EOF + systemctl --user enable my-cron.timer +elif __has "crontab" && [ -n "$crontab_init" ] +then + echo " Installing crontab" + crontab -l > /tmp/crontab.$$.orig + [ $? -ne 0 ] && echo "" > /tmp/crontab.$$.orig + grep bin/my /tmp/crontab.$$.orig > /dev/null 2>&1 + if [ ! $? -eq 0 ] + then + cat >> /tmp/crontab.$$ <<-EOF +# crontab created by my-init on `date '+%m/%d/%Y'` +# m h dom mon dow command +*/15 * * * * "\$HOME/bin/my" cron + +# Entries below this line created manually +EOF + cat /tmp/crontab.$$.orig >> /tmp/crontab.$$ + cat /tmp/crontab.$$ | crontab + rm /tmp/crontab.$$ + fi + rm /tmp/crontab.$$.orig +fi + +# Vim plugins +if __has "vim" "git" +then + echo " Downloading Vim plugins" + # Plugins that should always be enabled + mkdir -p $vim_bundle_path/start + cd $vim_bundle_path/start + __clone romainl/Apprentice + __clone tpope/vim-commentary + __clone tpope/vim-eunuch + __clone tpope/vim-fugitive + __clone tpope/vim-obsession + __clone tpope/vim-scriptease + __clone tpope/vim-surround + __clone tpope/vim-unimpaired + __clone tpope/vim-vinegar + __clone junegunn/goyo.vim + __clone junegunn/limelight.vim + __clone beloglazov/vim-online-thesaurus + __clone chr4/sslsecure.vim + __optclone_pathogen + cd - > /dev/null 2>&1 + + # Plugins used optionally + mkdir -p $vim_bundle_path/opt + cd $vim_bundle_path/opt + __clone jpalardy/vim-slime + __clone skammer/vim-css-color + cd - > /dev/null 2>&1 + + vim --cmd 'silent! execute "helptags ALL" | q' + unset vim_bundle_path +fi + +for shell in zsh bash dash sh +do + preferred_shell=`cat /etc/shells | grep /$shell$ | tr '\n' ' ' | cut -d ' ' -f 1` + [ "$preferred_shell" = "" ] || break +done +if getent passwd | grep ^$LOGNAME.*$preferred_shell$ > /dev/null 2>&1 +then + echo " Login shell already set to $preferred_shell" +else + echo " Setting login shell to $preferred_shell" + chsh -s $preferred_shell +fi + +for locker in xscreensaver light-locker cinnamon-screensaver +do + if type $locker > /dev/null 2>&1 + then + echo " Creating autostart entry for $locker" + cat > "${XDG_CONFIG_HOME:-$HOME}/.config/autostart/$locker.desktop" <<-EOF +[Desktop Entry] +TryExec=$locker +Exec=$locker +Name=$locker +Comment=Screen locker +Type=Application +EOF + break + fi +done + +if [ ! -f "$HOME/.gnupg/gpg-agent.conf" ] +then + echo " Creating gpg-agent.conf and configuring pinentry" + pinentry="" + if type pinentry > /dev/null 2>&1 + then + pinentry=`which pinentry` + fi + case `uname -s` in + *Darwin*) + pinentry="/usr/local/bin/pinentry-mac $pinentry" + ;; + esac + + for testpath in $pinentry + do + if [ -x $testpath ] + then + cat > "$HOME/.gnupg/gpg-agent.conf" <<-EOF +default-cache-ttl 600 +max-cache-ttl 7200 +enable-ssh-support +pinentry-program $testpath +EOF + break + fi + done +fi + +[ ! -d "$HOME/var/log" ] && mkdir -p "$HOME/var/log" +[ ! -d "$HOME/var/forecastio" ] && mkdir -p "$HOME/var/forecastio" +[ ! -d "$HOME/lib/cron.d" ] && mkdir -p "$HOME/lib/cron.d" +[ ! -f "$HOME/var/forecastio/current_forecast.txt" ] && echo \ + "Weather not available" > \ + "$HOME/var/forecastio/current_forecast.txt" +[ ! -d "$HOME/.vim/undo/" ] && mkdir -p "$HOME/.vim/undo" +touch "$HOME/._.djmoch" +chmod 000 "$HOME/._.djmoch" + +unset __clone __has __optclone_pathogen diff --git a/bin/my-netrc b/bin/my-netrc @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# ~/bin/my-netrc +# +# Parse .netrc for usernames and passwords. For clients with a password +# eval feature, but no built-in netrc support. +import netrc +import sys + +def parse_netrc(host, token=None): + try: + authenticators = netrc.netrc().authenticators(host) + except Exception as error: + exit(str(error)) + if authenticators is None: + exit('my-netrc: ' + host + ' not found') + elif token == 'login': + if authenticators[0] is not None: + print(authenticators[0]) + else: + exit(host + ' contains no login token') + elif token == 'account': + if authenticators[1] is not None: + print(authenticators[1]) + else: + exit(host + ' contains no account token') + elif token == 'password': + if authenticators[2] is not None: + print(authenticators[2]) + else: + exit(host + ' contains no password token') + else: + if authenticators[0] is not None: + print('login: ' + authenticators[0]) + if authenticators[1] is not None: + print('account: ' + authenticators[1]) + if authenticators[2] is not None: + print('password: ' + authenticators[2]) + +if __name__ == "__main__": + if len(sys.argv) < 2: + exit('my-netrc: No request made. Exiting') + elif len(sys.argv) == 2: + parse_netrc(sys.argv[1]) + else: + parse_netrc(sys.argv[1], sys.argv[2]) diff --git a/bin/my-open b/bin/my-open @@ -0,0 +1,118 @@ +#!/bin/sh +# +# ~/bin/my-open +# +# Every OS seems to use it's own uniquely-named binary to open +# files using the correct handler for the file's MIME type. This is my +# attempt to resolve the different handlers into a platform-independent +# one. +# +if [ "$1" = "-T" ] +then + shift + + configfile="${XDG_CONFIG_HOME:-$HOME/.config}/my-open/config" + + if [ ! -f "$configfile" ] + then + echo "my-open: No config file. Creating skeleton." + mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/my-open" + configname=${configfile/$HOME/'~'} + cat >> "$configfile" <<-EOF +# +# $configname +# +# format: [mimetype]:default fallback1 fallback2 ...:commandline +# second segment of mimetype can be a wildcard. my-open looks for exact +# matches first. +EOF + exit 2 + fi + + if type xdg-mime > /dev/null 2>&1 + then + mimecmd="xdg-mime query filetype %s" + elif type mimetype > /dev/null 2>&1 + then + mimecmd="mimetype %s" + else + echo "my-open: No way to determine MIME type" >&2 + exit 1 + fi + + if [ -f "$1" -o -d "$1" ] + then + mimecmd=`printf "$mimecmd" "$1"` + mimetype=`$mimecmd` + elif echo "$1" | grep -E '^http:\/\/' > /dev/null 2>&1 + then + mimetype='x-scheme-handler/http' + elif echo "$1" | grep -E '^https:\/\/' > /dev/null 2>&1 + then + mimetype='x-scheme-handler/https' + elif echo "$1" | grep -E '^ftp:\/\/' > /dev/null 2>&1 + then + mimetype='x-scheme-handler/ftp' + else + mimetype='application/octet-stream' + fi + + handlers=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ + cut -d ':' -f 2` + cmdline=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ + cut -d ':' -f 3` + if [ -z "$handlers" ] + then + mimetype="`echo $mimetype | cut -d '/' -f 1`/*" + handlers=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ + cut -d ':' -f 2` + cmdline=`cat $configfile | grep -Ev '^#' | grep $mimetype | \ + cut -d ':' -f 3` + fi + if [ -z "$handlers" ] + then + echo "my-open: No handler specified" >&2 + exit 4 + fi + + for h in $handlers + do + if type $h > /dev/null 2>&1 + then + handler=$h + break + fi + done + + if [ -z "$handler" ] + then + echo "my-open: No handler found in \$PATH" >&2 + exit 8 + fi + set -- `printf -- "$cmdline" "$1"` + exec $handler "$@" +fi + +# Find handler, if one is available +if type cygstart > /dev/null 2>&1 +then + handler=cygstart +elif type xdg-open > /dev/null 2>&1 +then + handler=xdg-open +# Most of the following handlers are used within xdg-open, but we should +# check for them anyway since xdg-open doesn't exist +elif type exo-open > /dev/null 2>&1 +then + handler=exo-open +# Because of its ambiguity, open (the macOS handler) should always be +# tested last +elif type open > /dev/null 2>&1 +then + handler=open +else + echo "my-open: No suitable handler found" > /dev/stderr + exit -1 +fi + +$handler "$@" diff --git a/bin/my-perms b/bin/my-perms @@ -0,0 +1,36 @@ +#!/bin/sh + +# +# ~/bin/my-perms +# +# This file operates on $HOME, seting permissions for all dotfiles and +# dot-directories. The $HOME folder itself also has its permissions set +# to a secure default. +# + +cd $HOME + +for rec in `ls -A` +do + case $rec in + .*) + if [ -f $rec ] + then + if [ -x $rec ] + then + chmod 700 $rec + else + chmod 600 $rec + fi + fi + + if [ -d $rec ] + then + chmod 700 $rec + fi + ;; + esac +done + +# Finally, set the permissions for $HOME itself +chmod 700 . diff --git a/.local/bin/sncli-export b/bin/sncli-export diff --git a/.local/bin/tmux-session b/bin/tmux-session diff --git a/.config/autostart/xbindkeys.desktop b/etc/autostart/xbindkeys.desktop diff --git a/etc/awesome/rc.lua b/etc/awesome/rc.lua @@ -0,0 +1,557 @@ +-- +-- ~/etc/awesome/rc.lua +-- + +-- Standard awesome library +local gears = require("gears") +local awful = require("awful") +require("awful.autofocus") +-- Widget and layout library +local wibox = require("wibox") +-- Theme handling library +local beautiful = require("beautiful") +-- Notification library +local naughty = require("naughty") +local menubar = require("menubar") +local hotkeys_popup = require("awful.hotkeys_popup").widget +-- Enable hotkeys help widget for VIM and other apps +-- when client with a matching name is opened: +require("awful.hotkeys_popup.keys") + +-- {{{ Error handling +-- Check if awesome encountered an error during startup and fell back to +-- another config (This code will only ever execute for the fallback config) +if awesome.startup_errors then + naughty.notify({ preset = naughty.config.presets.critical, + title = "Oops, there were errors during startup!", + text = awesome.startup_errors }) +end + +-- Handle runtime errors after startup +do + local in_error = false + awesome.connect_signal("debug::error", function (err) + -- Make sure we don't go into an endless error loop + if in_error then return end + in_error = true + + naughty.notify({ preset = naughty.config.presets.critical, + title = "Oops, an error happened!", + text = tostring(err) }) + in_error = false + end) +end +-- }}} + +-- {{{ Variable definitions +-- Themes define colours, icons, font and wallpapers. +beautiful.init(gears.filesystem.get_dir("config") .. "theme.lua") + +-- This is used later as the default terminal and editor to run. +terminal = "my term" +editor = os.getenv("EDITOR") or "nano" +editor_cmd = terminal .. " -e " .. editor + +-- Default modkey. +-- Usually, Mod4 is the key with a logo between Control and Alt. +-- If you do not like this or do not have such a key, +-- I suggest you to remap Mod4 to another key using xmodmap or other tools. +-- However, you can use another modifier like Mod1, but it may interact with others. +modkey = "Mod4" + +-- Table of layouts to cover with awful.layout.inc, order matters. +awful.layout.layouts = { + -- awful.layout.suit.floating, + awful.layout.suit.tile, + awful.layout.suit.tile.left, + awful.layout.suit.tile.bottom, + awful.layout.suit.tile.top, + awful.layout.suit.fair, + awful.layout.suit.fair.horizontal, + awful.layout.suit.spiral, + awful.layout.suit.spiral.dwindle, + awful.layout.suit.max, + awful.layout.suit.max.fullscreen, + awful.layout.suit.magnifier, + awful.layout.suit.corner.nw, + -- awful.layout.suit.corner.ne, + -- awful.layout.suit.corner.sw, + -- awful.layout.suit.corner.se, +} +-- }}} + +-- {{{ Helper functions +local function client_menu_toggle_fn() + local instance = nil + + return function () + if instance and instance.wibox.visible then + instance:hide() + instance = nil + else + instance = awful.menu.clients({ theme = { width = 250 } }) + end + end +end +-- }}} + +-- {{{ Menu +-- Create a launcher widget and a main menu +myawesomemenu = { + { "hotkeys", function() return false, hotkeys_popup.show_help end}, + { "manual", terminal .. " -e man awesome" }, + { "edit config", editor_cmd .. " " .. awesome.conffile }, + { "restart", awesome.restart }, + { "quit", function() awesome.quit() end} +} + +mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon }, + { "open terminal", terminal } + } + }) + +mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, + menu = mymainmenu }) + +-- Menubar configuration +menubar.utils.terminal = terminal -- Set the terminal for applications that require it +-- }}} + +-- {{{ Wibar +-- Create a status widget +mystatus = awful.widget.watch('my status', 15) + +-- Create a wibox for each screen and add it +local taglist_buttons = gears.table.join( + awful.button({ }, 1, function(t) t:view_only() end), + awful.button({ modkey }, 1, function(t) + if client.focus then + client.focus:move_to_tag(t) + end + end), + awful.button({ }, 3, awful.tag.viewtoggle), + awful.button({ modkey }, 3, function(t) + if client.focus then + client.focus:toggle_tag(t) + end + end), + awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end), + awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end) + ) + +local tasklist_buttons = gears.table.join( + awful.button({ }, 1, function (c) + if c == client.focus then + c.minimized = true + else + -- Without this, the following + -- :isvisible() makes no sense + c.minimized = false + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() + end + -- This will also un-minimize + -- the client, if needed + client.focus = c + c:raise() + end + end), + awful.button({ }, 3, client_menu_toggle_fn()), + awful.button({ }, 4, function () + awful.client.focus.byidx(1) + end), + awful.button({ }, 5, function () + awful.client.focus.byidx(-1) + end)) + +local function set_wallpaper(s) + -- Wallpaper + if beautiful.wallpaper then + local wallpaper = beautiful.wallpaper + -- If wallpaper is a function, call it with the screen + if type(wallpaper) == "function" then + wallpaper = wallpaper(s) + end + gears.wallpaper.maximized(wallpaper, s, true) + end +end + +-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution) +screen.connect_signal("property::geometry", set_wallpaper) + +awful.screen.connect_for_each_screen(function(s) + -- Each screen has its own tag table. + awful.tag( + {"1", "2", "3", "4", "5", "6", "7", "8", "9"}, + s, + awful.layout.suit.tile + ) + + awful.tag.find_by_name(s, "9").layout = awful.layout.suit.max.fullscreen + + -- Create a promptbox for each screen + s.mypromptbox = awful.widget.prompt() + -- Create an imagebox widget which will contain an icon indicating which layout we're using. + -- We need one layoutbox per screen. + s.mylayoutbox = awful.widget.layoutbox(s) + s.mylayoutbox:buttons(gears.table.join( + awful.button({ }, 1, function () awful.layout.inc( 1) end), + awful.button({ }, 3, function () awful.layout.inc(-1) end), + awful.button({ }, 4, function () awful.layout.inc( 1) end), + awful.button({ }, 5, function () awful.layout.inc(-1) end))) + -- Create a taglist widget + s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons) + + -- Create a tasklist widget + s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons) + + -- Create the wibox + s.mywibox = awful.wibar({ position = "top", screen = s }) + + -- Add widgets to the wibox + s.mywibox:setup { + layout = wibox.layout.align.horizontal, + { -- Left widgets + layout = wibox.layout.fixed.horizontal, + mylauncher, + s.mytaglist, + s.mypromptbox, + }, + s.mytasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + mystatus, + wibox.widget.systray(), + s.mylayoutbox, + }, + } +end) +-- }}} + +-- {{{ Mouse bindings +root.buttons(gears.table.join( + awful.button({ }, 3, function () mymainmenu:toggle() end) + -- awful.button({ }, 4, awful.tag.viewnext), + -- awful.button({ }, 5, awful.tag.viewprev) +)) +-- }}} + +-- {{{ Key bindings +globalkeys = gears.table.join( + awful.key({ modkey, }, "s", hotkeys_popup.show_help, + {description="show help", group="awesome"}), + awful.key({ modkey, }, "Left", awful.tag.viewprev, + {description = "view previous", group = "tag"}), + awful.key({ modkey, }, "Right", awful.tag.viewnext, + {description = "view next", group = "tag"}), + awful.key({ modkey, }, "Escape", awful.tag.history.restore, + {description = "go back", group = "tag"}), + awful.key({ modkey, }, "j", + function () + awful.client.focus.byidx( 1) + end, + {description = "focus next by index", group = "client"} + ), + awful.key({ modkey, }, "k", + function () + awful.client.focus.byidx(-1) + end, + {description = "focus previous by index", group = "client"} + ), + awful.key({ modkey, }, "w", function () mymainmenu:show() end, + {description = "show main menu", group = "awesome"}), + + -- Layout manipulation + awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end, + {description = "swap with next client by index", group = "client"}), + awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end, + {description = "swap with previous client by index", group = "client"}), + awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end, + {description = "focus the next screen", group = "screen"}), + awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end, + {description = "focus the previous screen", group = "screen"}), + awful.key({ modkey, }, "u", awful.client.urgent.jumpto, + {description = "jump to urgent client", group = "client"}), + awful.key({ modkey, }, "Tab", + function () + awful.client.focus.history.previous() + if client.focus then + client.focus:raise() + end + end, + {description = "go back", group = "client"}), + + -- Standard program + awful.key({ modkey, "Control" }, "r", awesome.restart, + {description = "reload awesome", group = "awesome"}), + awful.key({ "Mod1", "Control" }, "BackSpace", awesome.quit, + {description = "quit awesome", group = "awesome"}), + + awful.key({ modkey, "Mod1" }, "l", function () awful.tag.incmwfact( 0.05) end, + {description = "increase master width factor", group = "layout"}), + awful.key({ modkey, "Mod1" }, "h", function () awful.tag.incmwfact(-0.05) end, + {description = "decrease master width factor", group = "layout"}), + awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end, + {description = "increase the number of master clients", group = "layout"}), + awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end, + {description = "decrease the number of master clients", group = "layout"}), + awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end, + {description = "increase the number of columns", group = "layout"}), + awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end, + {description = "decrease the number of columns", group = "layout"}), + awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end, + {description = "select next", group = "layout"}), + awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end, + {description = "select previous", group = "layout"}), + + awful.key({ modkey, "Control" }, "n", + function () + local c = awful.client.restore() + -- Focus restored client + if c then + client.focus = c + c:raise() + end + end, + {description = "restore minimized", group = "client"}), + + -- Prompt + awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end, + {description = "run prompt", group = "launcher"}), + + awful.key({ modkey }, "x", + function () + awful.prompt.run { + prompt = "Run Lua code: ", + textbox = awful.screen.focused().mypromptbox.widget, + exe_callback = awful.util.eval, + history_path = awful.util.get_cache_dir() .. "/history_eval" + } + end, + {description = "lua execute prompt", group = "awesome"}), + -- Menubar + awful.key({ modkey }, "p", function() menubar.show() end, + {description = "show the menubar", group = "launcher"}) +) + +clientkeys = gears.table.join( + awful.key({ modkey, }, "f", + function (c) + c.fullscreen = not c.fullscreen + c:raise() + end, + {description = "toggle fullscreen", group = "client"}), + awful.key({ modkey, }, "q", function (c) c:kill() end, + {description = "close", group = "client"}), + awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle , + {description = "toggle floating", group = "client"}), + awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end, + {description = "move to master", group = "client"}), + awful.key({ modkey, }, "o", function (c) c:move_to_screen() end, + {description = "move to screen", group = "client"}), + awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end, + {description = "toggle keep on top", group = "client"}), + awful.key({ modkey, }, "n", + function (c) + -- The client currently has the input focus, so it cannot be + -- minimized, since minimized clients can't have the focus. + c.minimized = true + end , + {description = "minimize", group = "client"}), + awful.key({ modkey, }, "m", + function (c) + c.maximized = not c.maximized + c:raise() + end , + {description = "(un)maximize", group = "client"}), + awful.key({ modkey, "Control" }, "m", + function (c) + c.maximized_vertical = not c.maximized_vertical + c:raise() + end , + {description = "(un)maximize vertically", group = "client"}), + awful.key({ modkey, "Shift" }, "m", + function (c) + c.maximized_horizontal = not c.maximized_horizontal + c:raise() + end , + {description = "(un)maximize horizontally", group = "client"}) +) + +-- Bind all key numbers to tags. +-- Be careful: we use keycodes to make it work on any keyboard layout. +-- This should map on the top row of your keyboard, usually 1 to 9. +for i = 1, 9 do + globalkeys = gears.table.join(globalkeys, + -- View tag only. + awful.key({ modkey }, "#" .. i + 9, + function () + local screen = awful.screen.focused() + local tag = screen.tags[i] + if tag then + tag:view_only() + end + end, + {description = "view tag #"..i, group = "tag"}), + -- Toggle tag display. + awful.key({ modkey, "Control" }, "#" .. i + 9, + function () + local screen = awful.screen.focused() + local tag = screen.tags[i] + if tag then + awful.tag.viewtoggle(tag) + end + end, + {description = "toggle tag #" .. i, group = "tag"}), + -- Move client to tag. + awful.key({ modkey, "Shift" }, "#" .. i + 9, + function () + if client.focus then + local tag = client.focus.screen.tags[i] + if tag then + client.focus:move_to_tag(tag) + end + end + end, + {description = "move focused client to tag #"..i, group = "tag"}), + -- Toggle tag on focused client. + awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, + function () + if client.focus then + local tag = client.focus.screen.tags[i] + if tag then + client.focus:toggle_tag(tag) + end + end + end, + {description = "toggle focused client on tag #" .. i, group = "tag"}) + ) +end + +clientbuttons = gears.table.join( + awful.button({ }, 1, function (c) client.focus = c; c:raise() end), + awful.button({ modkey }, 1, awful.mouse.client.move), + awful.button({ modkey }, 3, awful.mouse.client.resize)) + +-- Set keys +root.keys(globalkeys) +-- }}} + +-- {{{ Rules +-- Rules to apply to new clients (through the "manage" signal). +awful.rules.rules = { + -- All clients will match this rule. + { rule = { }, + properties = { border_width = beautiful.border_width, + border_color = beautiful.border_normal, + focus = awful.client.focus.filter, + raise = true, + keys = clientkeys, + buttons = clientbuttons, + screen = awful.screen.preferred, + placement = awful.placement.no_overlap+awful.placement.no_offscreen + } + }, + + -- Floating clients. + { rule_any = { + instance = { + "DTA", -- Firefox addon DownThemAll. + "copyq", -- Includes session name in class. + }, + class = { + "Arandr", + "Gpick", + "Kruler", + "MessageWin", -- kalarm. + "Sxiv", + "Wpa_gui", + "pinentry", + "veromix", + "xtightvncviewer"}, + + name = { + "Event Tester", -- xev. + "xbindkeys_show", + "xfontsel" + }, + role = { + "AlarmWindow", -- Thunderbird's calendar. + "pop-up", -- e.g. Google Chrome's (detached) Developer Tools. + } + }, properties = { floating = true }}, + + -- Set Firefox to always map on the tag named "2" on screen 1. + -- { rule = { class = "Firefox" }, + -- properties = { screen = 1, tag = "2" } }, +} +-- }}} + +-- {{{ Signals +-- Signal function to execute when a new client appears. +client.connect_signal("manage", function (c) + -- Set the windows at the slave, + -- i.e. put it at the end of others instead of setting it master. + -- if not awesome.startup then awful.client.setslave(c) end + + if awesome.startup and + not c.size_hints.user_position + and not c.size_hints.program_position then + -- Prevent clients from being unreachable after screen count changes. + awful.placement.no_offscreen(c) + end +end) + +-- Add a titlebar if titlebars_enabled is set to true in the rules. +client.connect_signal("request::titlebars", function(c) + -- buttons for the titlebar + local buttons = gears.table.join( + awful.button({ }, 1, function() + client.focus = c + c:raise() + awful.mouse.client.move(c) + end), + awful.button({ }, 3, function() + client.focus = c + c:raise() + awful.mouse.client.resize(c) + end) + ) + + awful.titlebar(c, { size = beautiful.titlebar_height }) : setup { + { -- Left + -- awful.titlebar.widget.iconwidget(c), + buttons = buttons, + layout = wibox.layout.fixed.horizontal + }, + { -- Middle + { -- Title + align = "center", + widget = awful.titlebar.widget.titlewidget(c) + }, + buttons = buttons, + layout = wibox.layout.flex.horizontal + }, + { -- Right + awful.titlebar.widget.floatingbutton (c), + awful.titlebar.widget.maximizedbutton(c), + awful.titlebar.widget.stickybutton (c), + awful.titlebar.widget.ontopbutton (c), + awful.titlebar.widget.closebutton (c), + layout = wibox.layout.fixed.horizontal() + }, + layout = wibox.layout.align.horizontal + } +end) + +-- Enable sloppy focus, so that focus follows mouse. +client.connect_signal("mouse::enter", function(c) + if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier + and awful.client.focus.filter(c) then + client.focus = c + end +end) + +client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) +client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) +-- }}} diff --git a/etc/awesome/theme.lua b/etc/awesome/theme.lua @@ -0,0 +1,69 @@ +-- +-- ~/etc/awesome/theme.lua +-- +local theme_assets = require("beautiful.theme_assets") +local xresources = require("beautiful.xresources") +local xtheme = xresources.get_current_theme() +local dpi = xresources.apply_dpi + +local gfs = require("gears.filesystem") +local awful = require("awful") +local themes_path = gfs.get_themes_dir() + +local theme = dofile(themes_path.."default/theme.lua") + +theme.font = "sans 9" + +theme.bg_normal = xtheme.color8 +theme.bg_focus = xtheme.color7 +theme.bg_urgent = xtheme.color4 +theme.bg_minimize = xtheme.color0 +theme.bg_systray = xtheme.color8 + +theme.fg_normal = xtheme.background +theme.fg_focus = xtheme.foreground +theme.fg_urgent = xtheme.background +theme.fg_minimize = xtheme.background + +theme.useless_gap = dpi(0) +theme.border_width = dpi(1) +theme.border_normal = xtheme.color8 +theme.border_focus = xtheme.color4 +theme.border_marked = xtheme.color5 + +theme.hotkeys_bg = xtheme.color8 +theme.hotkeys_fg = xtheme.background +theme.hotkeys_modifiers_fg = xtheme.color6 + +-- Generate taglist squares: +local taglist_square_size = dpi(4) +theme.taglist_squares_sel = theme_assets.taglist_squares_sel( + taglist_square_size, theme.fg_focus +) +theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel( + taglist_square_size, theme.fg_normal +) + +theme = theme_assets.recolor_layout(theme, theme.fg_normal) +theme = theme_assets.recolor_titlebar(theme, theme.fg_normal, "normal") +theme = theme_assets.recolor_titlebar(theme, theme.bg_normal, "focus") + +-- Variables set for theming the menu: +theme.menu_height = dpi(15) +theme.menu_width = dpi(100) + +theme.wallpaper = function (s) awful.spawn('my wallpaper') end + +-- Generate Awesome icon: +theme.awesome_icon = theme_assets.awesome_icon( + theme.menu_height, theme.bg_focus, theme.fg_focus +) + +theme.wibar_height = dpi(16) +theme.titlebar_height = dpi(16) + +-- Define the icon theme for application icons. If not set then the icons +-- from /usr/share/icons and /usr/share/icons/hicolor will be used. +theme.icon_theme = "Arc" + +return theme diff --git a/etc/dunst/dunstrc b/etc/dunst/dunstrc @@ -0,0 +1,68 @@ +# +# ~/etc/dunst/dunstrc +# +[global] +monitor = 0 +follow = mouse +geometry = "300x5-30+20" +indicate_hidden = yes +shrink = no +transparency = 0 +notification_height = 0 +separator_height = 2 +padding = 8 +horizontal_padding = 8 +frame_width = 1 +frame_color = "#bcbcbc" +separator_color = frame +sort = yes +idle_threshold = 120 +font = Sans 9 +line_height = 0 +markup = full +format = "<b>%s</b>\n%b" +alignment = left +show_age_threshold = 60 +word_wrap = yes +ellipsize = middle +ignore_newline = no +stack_duplicates = true +hide_duplicate_count = false +show_indicators = yes +icon_position = off +max_icon_size = 32 +icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ +sticky_history = yes +history_length = 20 +dmenu = /usr/bin/dmenu -p dunst: +browser = my-open +always_run_script = true +title = Dunst +class = Dunst +startup_notification = false +force_xinerama = false + +[experimental] +per_monitor_dpi = false + +[shortcuts] +close = ctrl+space +close_all = ctrl+shift+space +history = ctrl+grave +context = ctrl+shift+period + +[urgency_low] +background = "#262626" +foreground = "#bcbcbc" +timeout = 10 + +[urgency_normal] +background = "#262626" +foreground = "#bcbcbc" +timeout = 10 + +[urgency_critical] +background = "#af5f5f" +foreground = "#bcbcbc" +frame_color = "#ff0000" +timeout = 0 diff --git a/.config/gtk-3.0/settings.ini b/etc/gtk-3.0/settings.ini diff --git a/.config/homebrew/brew_leaves.txt b/etc/homebrew/brew_leaves.txt diff --git a/.config/homebrew/brew_leaves_head.txt b/etc/homebrew/brew_leaves_head.txt diff --git a/.config/homebrew/brew_setup.sh b/etc/homebrew/brew_setup.sh diff --git a/.config/i3/config b/etc/i3/config diff --git a/etc/khal/config b/etc/khal/config @@ -0,0 +1,23 @@ +[calendars] + +[[home]] +path = ~/lib/share/calendars/nextcloud/home +type = discover +color = 4 + +[[family]] +path = ~/lib/share/calendars/nextcloud/family +type = discover +color = 2 + +[[planning_center]] +path = ~/lib/share/calendars/planningcenter +type = discover +color = 3 + +[locale] +timeformat = %I:%M %p +dateformat = %m/%d/%Y +longdateformat = %m/%d/%Y +datetimeformat = %m/%d/%Y %I:%M %p +longdatetimeformat = %m/%d/%Y %I:%M %p diff --git a/etc/khard/khard.conf b/etc/khard/khard.conf @@ -0,0 +1,38 @@ +# +# ~/etc/khard/khard.conf +# +[addressbooks] +[[nextcloud]] +path = ~/lib/share/contacts/nextcloud/Contacts + +[general] +debug = no +default_action = list + +[contact table] +# display names by first or last name: first_name / last_name +display = first_name +# group by address book: yes / no +group_by_addressbook = no +# reverse table ordering: yes / no +reverse = no +# append nicknames to name column: yes / no +show_nicknames = no +# show uid table column: yes / no +show_uids = yes +# sort by first or last name: first_name / last_name +sort = last_name + +[vcard] +# extend contacts with your own private objects +# these objects are stored with a leading "X-" before the object name in the vcard files +# every object label may only contain letters, digits and the - character +# example: +# private_objects = Jabber, Skype, Twitter +private_objects = Jabber, Skype, Twitter +# preferred vcard version: 3.0 / 4.0 +preferred_version = 3.0 +# Look into source vcf files to speed up search queries: yes / no +search_in_source_files = no +# skip unparsable vcard files: yes / no +skip_unparsable = no+ \ No newline at end of file diff --git a/etc/mutt/muttrc b/etc/mutt/muttrc @@ -0,0 +1,203 @@ +# Headers +ignore * +unignore from: subject to cc date x-mailer x-url user-agent list-id + +hdr_order date from to cc subject list-id + +# Macros +macro index \eb "<search>~b " "search in message bodies" + +macro index,pager,attach,compose \cb "\ +<enter-command> set my_pipe_decode=\$pipe_decode pipe_decode<Enter>\ +<pipe-message> urlview<Enter>\ +<enter-command> set pipe_decode=\$my_pipe_decode; unset my_pipe_decode<Enter>" \ +"call urlview to extract URLs out of a message" + +macro generic,pager <F1> "<shell-escape> less /usr/share/doc/mutt/manual.txt<Enter>" "show Mutt documentation" + +macro index,pager y "<change-folder>?<toggle-mailboxes>" "show incoming mailboxes list" + +macro index <F9> "<sync-mailbox><enter-command>source ~/etc/mutt/account.dotcom<enter><change-folder>!<enter>" +macro index <F10> "<sync-mailbox><enter-command>source ~/etc/mutt/account.icloud<enter><change-folder>!<enter>" +macro index <F11> "<sync-mailbox><enter-command>source ~/etc/mutt/account.fullsail<enter><change-folder>!<enter>" +macro index <F8> \ +"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\ +<shell-escape>notmuch-mutt -r --prompt search<enter>\ +<change-folder-readonly>`echo ${XDG_CACHE_HOME:-$HOME/.cache}/notmuch/mutt/results`<enter>\ +<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \ +"notmuch: search mail" + +macro index <F4> \ +"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\ +<pipe-message>notmuch-mutt -r thread<enter>\ +<change-folder-readonly>`echo ${XDG_CACHE_HOME:-$HOME/.cache}/notmuch/mutt/results`<enter>\ +<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \ +"notmuch: reconstruct thread" + +macro generic,pager <F5> "<enter-command>toggle sidebar_visible<enter>" "Toggle the sidebar" + +# Hooks +message-hook '~s .*' 'uncolor body red default "^-.*"' +message-hook '~s .*' 'uncolor body green default "^\\+.*"' +message-hook '~s .*' 'uncolor body cyan default "^@@.*"' +message-hook '~s .*' 'uncolor body brightwhite default "^(diff|index|new|\\+\\+\\+|---).*"' +message-hook '~s \\[PATCH' 'color body red default "^-.*"' +message-hook '~s \\[PATCH' 'color body green default "^\\+.*"' +message-hook '~s \\[PATCH' 'color body cyan default "^@@.*"' +message-hook '~s \\[PATCH' 'color body brightwhite default "^(diff\\s|index\\s|new\\s|\\+\\+\\+|---).*"' + +# General Settings +set realname = "Daniel Moch" +set sendmail_wait = -1 +set sort = "threads" +set strict_threads = "yes" +set sort_browser = "alpha" +set sort_aux = "last-date-received" +set query_command = "khard email --parsable --search-in-source-files '%s'" +set sidebar_sort_method = "alpha" +set sidebar_visible +unset collapse_unread + +bind browser y exit +bind index - collapse-thread +bind index _ collapse-all +bind index J sidebar-next +bind index K sidebar-prev +bind index O sidebar-open +bind pager j next-line +bind pager <Down> next-line +bind pager k previous-line +bind pager <Up> previous-line +bind pager \Cu half-up +bind pager \Cd half-down + +mime_lookup application/octet-stream + +attachments +A */.* +attachments -A text/x-vcard application/pgp.* +attachments -A application/x-pkcs7-.* +attachments +I text/plain +attachments -A message/external-body +attachments -I message/external-body + +auto_view text/html +alternative_order text/plain text/enriched text/html + +# GPG +set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f" +set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f" +set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f" +set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f" +set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f" +set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f" +set pgp_encrypt_sign_command="pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f" +set pgp_import_command="gpg --no-verbose --import %f" +set pgp_export_command="gpg --no-verbose --export --armor %r" +set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r" +set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --with-fingerprint --list-keys %r" +set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --with-fingerprint --list-secret-keys %r" +set pgp_good_sign="^\\[GNUPG:\\] GOODSIG" +set pgp_decryption_okay="^\\[GNUPG:\\] DECRYPTION_OKAY" + +# S/MIME +set smime_timeout=300 +set crypt_autosign = yes +set crypt_replyencrypt = yes +set crypt_replysign = yes +set crypt_replysignencrypted = yes +set crypt_verify_sig = yes +set smime_default_key="12345678.0" +set smime_ca_location="/etc/ca-certificates/extracted/email-ca-bundle.pem" +set smime_certificates="~/lib/mutt/smime/certificates" +set smime_keys="~/lib/mutt/smime/keys" +set smime_pk7out_command="openssl smime -verify -in %f -noverify -pk7out" +set smime_get_cert_command="openssl pkcs7 -print_certs -in %f" +set smime_get_signer_cert_command="openssl smime -verify -in %f -noverify -signer %c -out /dev/null" +set smime_get_cert_email_command="openssl x509 -in %f -noout -email" +set smime_import_cert_command="smime_keys add_cert %f" +set smime_encrypt_with="aes256" +set smime_encrypt_command="openssl smime -encrypt -%a -outform DER -in %f %c" +set smime_sign_digest_alg="sha256" +set smime_sign_command="openssl smime -sign -md %d -signer %c -inkey %k -passin stdin -in %f -certfile %i -outform DER" +set smime_decrypt_command="openssl smime -decrypt -passin stdin -inform DER -in %f -inkey %k -recip %c" +set smime_verify_command="openssl smime -verify -inform DER -in %s %C -content %f" +set smime_verify_opaque_command="\ +openssl smime -verify -inform DER -in %s %C || \ +openssl smime -verify -inform DER -in %s -noverify 2>/dev/null" + +# Colors +color normal default default +color error brightred default +color tilde default default +color message default default +color markers default default +color attachment default default +color search default default +color status brightwhite blue +color indicator black white +color tree blue default + +mono bold bold +mono underline underline +mono indicator reverse +mono error bold + +color index default default "~A" # all messages +color index red default "~E" # expired messages +color index default default "~N" # new messages +color index default default "~O" # old messages +color index default default "~Q" # messages that have been replied to +color index default default "~R" # read messages +color index default default "~U" # unread messages +color index default default "~U~$" # unread, unreferenced messages +color index default default "~v" # messages part of a collapsed thread +color index white default "~P" # messages from me +color index blue default "~p!~F" # messages to me +color index blue default "~N~p!~F" # new messages to me +color index blue default "~U~p!~F" # unread messages to me +color index blue default "~R~p!~F" # messages to me +color index brightgreen default "~F" # flagged messages +color index brightgreen default "~F~p" # flagged messages to me +color index brightgreen default "~N~F" # new flagged messages +color index brightgreen default "~N~F~p" # new flagged messages to me +color index brightgreen default "~U~F~p" # new flagged messages to me +color index brightwhite red "~D" # deleted messages +color index white default "~v~(!~N)" # collapsed thread with no unread +color index default default "~v~(~N)" # collapsed thread with some unread +color index white default "~N~v~(~N)" # collapsed thread with unread parent +color index brightgreen default "~v~(~F)!~N" # collapsed thread with flagged, no unread +color index default default "~v~(~F~N)" # collapsed thread with some unread & flagged +color index brightgreen default "~N~v~(~F~N)" # collapsed thread with unread parent & flagged +color index brightgreen default "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged +color index white default "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly +color index black red "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial) +color hdrdefault default default +color header default default "^(From)" +color header default default "^(Subject)" +color quoted green default +color quoted1 magenta default +color quoted2 green default +color quoted3 red default +color quoted4 yellow default +color signature default default +color bold default default +color underline underline default default +color normal default default +color body bold default default "[;:][-o][)/(|]" # emoticons +color body bold default default "[;:][)(|]" # emoticons +color body bold default default "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\ + |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\ + |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?" +color body bold default default "[ ][*][^*]*[*][ ]?" # more emoticon? +color body bold default default "[ ]?[*][^*]*[*][ ]" # more emoticon? +color body brightwhite red "(BAD signature)" +color body default default "(Good signature)" +color body default default "^gpg:Good signature .*" +color body default default "^gpg: " +color body brightwhite red "^gpg:BAD signature from.*" +mono body bold "^gpg: Good signature" +mono body bold "^gpg: BAD signature from.*" +color body blue default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]" +color body blue default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])" + +source ~/etc/mutt/account.default diff --git a/.config/nncli/config b/etc/nncli/config diff --git a/.config/pacman/makepkg.conf b/etc/pacman/makepkg.conf diff --git a/.profile.d/brew.sh b/etc/profile.d/brew.sh diff --git a/.profile.d/browser.sh b/etc/profile.d/browser.sh diff --git a/.profile.d/cargo.sh b/etc/profile.d/cargo.sh diff --git a/.profile.d/editor.sh b/etc/profile.d/editor.sh diff --git a/etc/profile.d/env.sh b/etc/profile.d/env.sh @@ -0,0 +1,5 @@ +if [ -r "$HOME/etc/shrc" ] +then + ENV="$HOME/etc/shrc" + export ENV +fi diff --git a/etc/profile.d/go.sh b/etc/profile.d/go.sh @@ -0,0 +1,6 @@ +if type go > /dev/null 2>&1 +then + GOPATH="$HOME/src/go" + export GOPATH + __addpath "$HOME/src/go/bin" +fi diff --git a/.profile.d/gpg.sh b/etc/profile.d/gpg.sh diff --git a/.profile.d/hostname.sh b/etc/profile.d/hostname.sh diff --git a/.profile.d/logname.sh b/etc/profile.d/logname.sh diff --git a/etc/profile.d/my.sh b/etc/profile.d/my.sh @@ -0,0 +1 @@ +__addpath "$HOME/bin" "before" diff --git a/.profile.d/pager.sh b/etc/profile.d/pager.sh diff --git a/.profile.d/sh.sh b/etc/profile.d/sh.sh diff --git a/.profile.d/visual.sh b/etc/profile.d/visual.sh diff --git a/etc/profile.d/xdg.sh b/etc/profile.d/xdg.sh @@ -0,0 +1,4 @@ +XDG_CONFIG_HOME=$HOME/etc +XDG_CACHE_HOME=$HOME/var/cache +XDG_DATA_HOME=$HOME/lib/share +export XDG_CONFIG_HOME XDG_CACHE_HOME XDG_DATA_HOME diff --git a/etc/shrc b/etc/shrc @@ -0,0 +1,13 @@ +# +# ~/etc/shrc +# +case $TERM in +st*|rxvt*|xterm*|tmux*) printf "\033]0;$LOGNAME@$HOSTNAME\007" ;; +esac + +for file in "$HOME"/etc/shrc.d/*.sh +do + [ -r $file ] && . $file +done + +unset -v file diff --git a/.shrc.d/dotfiles.sh b/etc/shrc.d/dotfiles.sh diff --git a/.shrc.d/feh.sh b/etc/shrc.d/feh.sh diff --git a/.shrc.d/gpg.sh b/etc/shrc.d/gpg.sh diff --git a/.shrc.d/motd.sh b/etc/shrc.d/motd.sh diff --git a/.shrc.d/num.sh b/etc/shrc.d/num.sh diff --git a/.shrc.d/proj.sh b/etc/shrc.d/proj.sh diff --git a/.shrc.d/ps1.sh b/etc/shrc.d/ps1.sh diff --git a/.shrc.d/rsync.sh b/etc/shrc.d/rsync.sh diff --git a/.shrc.d/ssh.sh b/etc/shrc.d/ssh.sh diff --git a/.shrc.d/tmux.sh b/etc/shrc.d/tmux.sh diff --git a/etc/todoman/todoman.conf b/etc/todoman/todoman.conf @@ -0,0 +1,7 @@ +[main] +# A glob expression which matches all directories relevant. +path = ~/lib/share/calendars/nextcloud/* +date_format = %Y-%m-%d +time_format = %H:%M +default_list = Tasks: Home +default_due = 48 diff --git a/.config/urlwatch/hooks.py b/etc/urlwatch/hooks.py diff --git a/.config/urlwatch/urls.yaml b/etc/urlwatch/urls.yaml diff --git a/.config/urlwatch/urlwatch.yaml b/etc/urlwatch/urlwatch.yaml diff --git a/.config/vis/ctags.lua b/etc/vis/ctags.lua diff --git a/.config/vis/themes/djmoch.lua b/etc/vis/themes/djmoch.lua diff --git a/.config/vis/vis-commentary.lua b/etc/vis/vis-commentary.lua diff --git a/.config/vis/visrc.lua b/etc/vis/visrc.lua diff --git a/lib/cron.avail/cloudsync.sh b/lib/cron.avail/cloudsync.sh @@ -0,0 +1,99 @@ +#!/bin/sh +# +# ~/lib/cron.avail/cloudsync.sh +# + +echo "Beginning cloud sync at `date`" + +year=`date '+%Y'` +month=`date '+%m'` +lastrun_dir="$HOME/var/`basename $0`" +lastrun_file="$lastrun_dir/lastrun" +mobile_docs="$HOME/doc/mobile" +notes="$HOME/doc/notes" +server_fqdn="nextcloud.djmoch.org" + +if [ -d "$lastrun_dir" ] +then + if [ -f "$lastrun_file" ] + then + lastrun_year=`cat $lastrun_file | cut -d ' ' -f 1` + lastrun_month=`cat $lastrun_file | cut -d ' ' -f 2` + else + firstrun=1 + fi +else + firstrun=1 + mkdir -p "$lastrun_dir" +fi +echo "$year $month" > $lastrun_file + +[ ! -d "$mobile_docs" ] && mkdir -p "$mobile_docs" + +# Only do the following if the server is reachable +if ping -c 1 $server_fqdn > /dev/null 2>&1 +then + echo "$server_fqdn reachable. Proceeding." +else + echo "$server_fqdn NOT reachable. Exiting." + exit -1 +fi + +if type xdg-user-dir > /dev/null 2>&1 +then + LOCAL_PHOTOS=`xdg-user-dir PICTURES` +else + LOCAL_PHOTOS="$HOME/Pictures" +fi + +# Mount the WebDAV folder and set so only we can read it +if mount /mnt/nextcloud +then + echo "NextCloud WebDAV successfully mounted. Setting permissions." + chmod 700 /mnt/nextcloud + + # Rsync from WebDAV to ~/Photos + echo "Syncing Photos from WebDAV to $LOCAL_PHOTOS" + [ ! -d $LOCAL_PHOTOS/$year/$month ] && mkdir -p $LOCAL_PHOTOS/$year/$month + rsync -aq /mnt/nextcloud/Photos/$year/$month/* $LOCAL_PHOTOS/$year/$month + if [ -z "$firstrun" -a $lastrun_month -ne $month ] + then + # TODO: What if we're more than a month behind? + if [ ! -d $LOCAL_PHOTOS/$lastrun_year/$lastrun_month ] + then + mkdir -p $LOCAL_PHOTOS/$lastrun_year/$lastrun_month + fi + rsync -aq /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month/* $LOCAL_PHOTOS/$lastrun_year/$lastrun_month + fi + + # Rsync from ~/Photos to WebDAV + echo "Syncing Photos from $LOCAL_PHOTOS to WebDAV" + [ ! -d /mnt/nextcloud/Photos/$year/$month ] && mkdir -p /mnt/nextcloud/Photos/$year/$month + rsync -aq $LOCAL_PHOTOS/$year/$month/* /mnt/nextcloud/Photos/$year/$month + if [ -z "$firstrun" -a $lastrun_month -ne $month ] + then + if [ ! -d /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month ] + then + mkdir -p /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month + fi + # TODO: What if we're more than a month behind? + rsync -aq $LOCAL_PHOTOS/$lastrun_year/$lastrun_month/* /mnt/nextcloud/Photos/$lastrun_year/$lastrun_month + fi + + # Rsync from ~/Documents/Mobile to WebDAV + echo "Syncing mobile documents from $mobile_docs to WebDAV" + rsync -aq "$mobile_docs"/* /mnt/nextcloud/Documents + + # Rsync from WebDAV to ~/Documents/Mobile + echo "Syncing mobile documents from WebDAV to $mobile_docs" + rsync -aq /mnt/nextcloud/Documents/* "$mobile_docs" + + # Finish by unmounting the WebDAV folder + echo "Unmounting $server_fqdn" + umount /mnt/nextcloud +else + echo "NextCloud WebDAV mount FAILED. Exiting." + exit -2 +fi + +echo "Completed cloud sync at `date`" diff --git a/.local/lib/cron.avail/dc_backup.sh b/lib/cron.avail/dc_backup.sh diff --git a/.local/lib/cron.avail/vdirsyncer.sh b/lib/cron.avail/vdirsyncer.sh diff --git a/lib/cron.avail/weather.sh b/lib/cron.avail/weather.sh @@ -0,0 +1,12 @@ +#!/bin/sh +if ping -c 1 ipinfo.io > /dev/null 2>&1 +then + echo "ipinfo reachable. Proceeding." +else + echo "ipinfo NOT reachable. Aborting." + exit 1 +fi + +cd "$HOME/lib/forecastio/" + +./weather.py diff --git a/.local/lib/forecastio/org.djmoch.forecastio.plist b/lib/forecastio/org.djmoch.forecastio.plist diff --git a/lib/forecastio/weather.py b/lib/forecastio/weather.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from datetime import datetime +import math +import os +import sys +import forecastio +import requests + +def generate_forecast(): + error = False + latitude = None + longitude = None + + try: + # I keep my api key for forecast.io in a separate text file so + # I don't accidentally publish it anywhere. + with open('forecastio_api.txt', 'r') as apifile: + api_key = apifile.read() + api_key = api_key.strip() + + try: + with open('zipcode.txt', 'r') as zipcodefile: + zipcode = zipcodefile.read() + zipcode = zipcode.strip() + except FileNotFoundError: + zipcode = None + + if zipcode is None: + # Resolving location from IP is always going to be a best + # guess, but it's better than hardcoding location data + latitude, longitude = requests.get('https://ipinfo.io'). \ + json()['loc'].split(',') + else: + try: + with open('zipcodeapi_api.txt', 'r') as zipcodeapifile: + zipcodeapi_key = zipcodeapifile.read() + zipcodeapi_key = zipcodeapi_key.strip() + except FileNotFoundError: + sys.stdout.writelines( + datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + + " Could not find zipcodeapi key\n") + exit() + + location = requests.get('https://www.zipcodeapi.com/rest/' \ + + zipcodeapi_key + '/info.json/' + zipcode + \ + '/degrees').json() + latitude = location['lat'] + longitude = location['lng'] + + # Now we're ready to actually get the weather + forecast = forecastio.load_forecast(api_key, latitude, longitude) + + current_temp = forecast.currently() + day = forecast.daily() + + if 'LANG' in os.environ and \ + os.environ['LANG'].find('UTF-8') != -1: + degree_symbol = "\u00b0" + else: + degree_symbol = "" + + temp = str(current_temp.temperature) + degree_symbol + " F" + high = str(int(math.ceil(day.data[0].temperatureMax))) + low = str(int(math.ceil(day.data[0].temperatureMin))) + + out_filename = os.path.join( + os.environ['HOME'], + 'var/forecastio/current_forecast.txt' + ) + + with open(out_filename, 'w') as outfile: + outfile.write(temp + ", " + str(current_temp.summary) + \ + ", " + high + degree_symbol + "/" +low + \ + degree_symbol + " F") + except requests.exceptions.ConnectionError: + error = True + sys.stdout.writelines( + datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + + " Could not connect. Will try again in 5 minutes.\n") + + if not error: + sys.stdout.writelines( + datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + + " Successfully updated weather\n") + +if __name__ == '__main__': + sys.stdout.writelines( + datetime.now().strftime("%m/%d/%Y %I:%M:%S:") + + " Updating weather\n") + generate_forecast() diff --git a/.local/lib/gitdir/hooks/ctags b/lib/gitdir/hooks/ctags diff --git a/.local/lib/gitdir/hooks/post-checkout b/lib/gitdir/hooks/post-checkout diff --git a/.local/lib/gitdir/hooks/post-commit b/lib/gitdir/hooks/post-commit diff --git a/.local/lib/gitdir/hooks/post-merge b/lib/gitdir/hooks/post-merge diff --git a/.local/lib/gitdir/hooks/post-rewrite b/lib/gitdir/hooks/post-rewrite diff --git a/.local/lib/gitdir/hooks/pre-commit b/lib/gitdir/hooks/pre-commit diff --git a/.local/lib/gitdir/hooks/prepare-commit-msg b/lib/gitdir/hooks/prepare-commit-msg diff --git a/.local/lib/gitdir/info/attributes b/lib/gitdir/info/attributes diff --git a/.local/lib/terminfo/tmux-from-screen.terminfo b/lib/terminfo/tmux-from-screen.terminfo diff --git a/.local/lib/terminfo/tmux.terminfo b/lib/terminfo/tmux.terminfo diff --git a/lib/tmux/battery_indicator.sh b/lib/tmux/battery_indicator.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# +# ~/lib/tmux/battery_indicator.sh +# +SMILE='☻ ' + +charged_slots=$((`my battery percent` / 25)) +[ $charged_slots -gt 3 ] && charged_slots=3 + +echo -n '#[fg=green]' +for i in `seq 1 $charged_slots`; do echo -n "$SMILE"; done + +if [ $charged_slots -lt 3 ]; then + echo -n '#[fg=red]' + uncharged_slots=$((3-$charged_slots)) + for i in `seq 1 $uncharged_slots`; do echo -n "$SMILE"; done +fi diff --git a/man/man1/my.1 b/man/man1/my.1 @@ -0,0 +1,201 @@ +.TH MY 1 "September 2019" "djmoch 0.0" "DJMOCH Commands Manual" +.SH NAME +my \- utility functions for use across dotfiles and elsewhere +.SH SYNOPSIS +.SY my +\fISUBCOMMAND\fR [\fIARGS\fR] +.YS +.SH DESCRIPTION +\fBmy\fR runs the subcommand specified by \fISUBCOMMAND\/\fR, passing any provided +\fIARGS\/\fR along. Many of the available subcommands amount to a list of providers +which are searched in the $PATH, with the first one found being executed. This +design allows for dotfiles to port across machines with relative ease. +.SH SUBCOMMANDS +.PP +.TP +\fBmailto\fR +Send email. +.sp +Command synopsis: \fBmy\fR \fBmailto\fR [\fIaddress\fR]\fR [\fIsubject\fR] +.TP +\fBsearch\fR +Search DuckDuckGo in the terminal. +.sp +Command synopsis: \fBmy\fR \fBsearch\fR [\fIterm\fR] (shell quoting rules apply) +.TP +\fBterm\fR +Open an X terminal window. This subcommand follows an order of preference for which +terminal emulator is used. +.sp +The current order is: +.sp +1. st +.br +2. urxvtc (if urxvtd is available) +.br +3. urxvt +.br +4. xterm +.br +5. xfce4-terminal +.br +6. gnome-terminal +.TP +\fBlock\fR +Lock the X session. +.TP +\fBwallpaper\fR +Set the xroot color and, if available, set the wallpaper using the feh .fehbg command. +.TP +\fBstandby\fR +Put the machine into hybrid-sleep mode. +.TP +\fBshutdown\fR +Shut down the machine. +.TP +\fBperms\fR +Search for all of the files in \fIHOME\fR beginning with a dot (i.e., a dotfile) and +sets its permissions via chmod to be inaccessible to everyone except the file owner. +.TP +\fBinit\fR +Perform initializations necessary for "moving in." +.sp +Command synopsis: \fBmy\fR \fBinit\fR [\fI\-f\fR][\fI\-c\fR] +.sp +When run with \fI\-f\fR, the command is forced to run completely, even if it has +already been run. When run with \fI\-c\fR, the user crontab is also initialized. +.sp +In addition to optionally initializing the crontab, init initializes custom termcaps, .less, ensures +the login shell is set to /bin/sh, creates an autostart entry for an available screen locker based +on a preference list and availability in \fIPATH\fR, and initializes gpg-agent.conf to point to the +correct pinentry program. Finally, init creates several folders required for proper behavior of +dotfiles. +.sp +When complete, init touches the file $HOME/._.djmoch to act as a flag for the last time the dotfiles +where updated/initialized. See the \fBlogin\fR subcommand for more details of how this file is used. +.TP +\fBopen\fR +Open a file in the configured XDG handler specific to the file's MIME type, or, optionally, in a +configured terminal handler. +.sp +Command synopsis: \fBmy\fR \fBopen\fR [\fI\-T\fR] \fIFILE\fR +.sp +When the \fI\-T\fR flag is provided, the file is opened in a terminal handler configured in a +different file. See my-open.config(5) for more information an how to configure terminal handlers. +.TP +\fBsound\fR +Adjust the sound settings or display sound status. +.sp +Command synopsis: \fBmy\fR \fBsound\fR [\fIstatus\fR] ... +.sp +If the \fIstatus\fR action is provided, then the current status of the sound sinks and sources +is put out. If the status is not requested, then other command arguments should be provided +according to pactl(1). +.TP +\fBkbopts\fR +Set X keyboard options. +.TP +\fBscreen\fR +Set screen options. This is more or less deprecated in favor of autorandr(1). +.TP +\fBbrightness\fR +Sets the brightness of the provided monitor using the xbacklight(1) utility. +.sp +Command synopsis: \fBmy\fR \fBbrightness\fR \fICTRL\fR ... +.sp +The \fICTRL\fR argument should be the name of an attached display device, or the generic +argument "monitor," which simply looks determines the name of the (only) attached display +device. The remaider of the command arguments follow the description in xbacklight(1). +.TP +\fBbattery\fR +Show information about the battery. +.sp +Command synopsis: \fBmy\fR \fBbattery\fR [\fIremaining\fR][\fItotal\fR][\fIpercent\fR] +.sp +The \fIpercent\fR argument will probably be the only one of any interest. The others are +used internally to calculate the percent, and their representation is dependent on the +operating system. +.TP +\fBstatus\fR +Print an embeddable status message showing the remaining battery percentage, the current +weather, and the time. +.TP +\fBi3status\fR +Same as status, but automatically prints the status to stdout every 15 seconds, allowing +it to be used in the status bar of the i3 window manager. +.TP +\fBcopy\fR +An os-independent way to copy text from the terminal into the system clipboard. +.TP +\fBpaste\fR +An os-independent way to paste text from the system clipboard into the terminal. +.TP +\fBnetrc\fR +Parses netrc to return username/password information for use in configuration files or +anywhere a service credential might be required. Note that this subcommand calls out +to a handler written in Python. +.sp +Command synopsis: \fBmy\fR \fBnetrc\fR \fI<server>\fR [\fIlogin\fR][\fIaccount\fR] +[\fIpassword\fR] +.sp +The \fIserver\fR argument should be the fully-qualified domian name of the server whose +credential is being requested. One of the three optional arguments, \fIlogin\fR, +\fIaccount\fR, or \fIpassword\fR may also be provided, in which case only that portion +of the credential will be provided. If none of the optional arguments are provided, then +all three will be returned. All responses are provided on stdout. +.TP +\fBdotfiles\fR +Perform one of several maintanence actions on the dotfiles. +.sp +Command synopsis: \fBmy\fR \fBdotfiles\fR <\fIargument\fR> +.sp +\fIargument\fR may be one of \fIcheck\fR, in which case the ._.djmoch file in consulted +to see when the dotfiles were last updated, or \fIupdate\fR, in which case the dotfiles +are actually updated. Whether or not \fIupdate\fR actually does anything is conditioned +on whether the dotfiles are sourced from a tarfile. If the dotfiles are sourced from a +Git repository, then \fIupdate\fR does nothing. +.TP +\fBcron\fR +Run configured cron tasks. This subcommand should be called either from a user crontab +or a user systemd timer. +.sp +Command synopsis: \fBmy\fR \fBcron\fR [\fIsystemd\fR] +.sp +If the \fIsystemd\fR argument is provided, then the job output is sent to stdout, +otherwise no output is given. +.sp +Any script located in $HOME/lib/cron.d (either physically or via link) will be +executed. Note that cron scripts that are included in the dotfiles are located in +$HOME/lib/cron.avail and must be linked into cron.d before they will be +activated. +.sp +Recall that \fBinit\fR will either place an entry in the user crontab or create a user +systemd timer to call \fBmy cron\fR. +.TP +\fBlogin_async\fR +This should really be called login_sync, since it is the synchronous (i.e. blocking) +version of the login command (see \fBmy login\fR to run as a background job). +.sp +\fBlogin_async\fR will attempt to contact the dotfiles server for up to two minutes +from the point it is called. If it is able to make contact, it consults the ._.djmoch +file to see if the dotfiles have to updated in the past week. If not, it calls \fBmy +dotfiles update\fR. +.TP +\fBlogin\fR +Calls \fBmy login_async\fR as a background job. +.TP +\fBprocesses\fR +List's the current users running processes. +.PP +.SH EXIT STATUS +.PP +.TP +\fB0\fR +\fISUBCOMMAND\fR executed successfully. +.TP +\fB1\fR +Error executing \fISUBCOMMAND\fR. +.PP +.SH SEE ALSO +feh(1), chmod(1), my-open.config(5), pactl(1), autorandr(1), xbacklight(1), crontab(5), +systemd.timer(5) diff --git a/.local/man/man5/my-open.config.5 b/man/man5/my-open.config.5