commit 3f098b5d105ab5a4c6ec4286ecd154102b15df46 Author: Dmitry Zakharchenko Date: Tue Aug 2 16:20:41 2022 +0300 dots: initial commit diff --git a/.config/dunst/dunstrc b/.config/dunst/dunstrc new file mode 100644 index 0000000..fb1a414 --- /dev/null +++ b/.config/dunst/dunstrc @@ -0,0 +1,28 @@ +[global] + notification_limit = 0 + follow = mouse + shrink= yes + frame_width = 1 + frame_color = "#005577" + separator_color = frame + font = Monospace 9 + format = "%s\n%b" + alignment = center + ellipsize = middle + +[urgency_low] + background = "#222222" + foreground = "#d3d0c8" + timeout = 3 + +[urgency_normal] + background = "#222222" + foreground = "#d3d0c8" + timeout = 5 + +[urgency_critical] + background = "#181a1b" + foreground = "#d3d0c8" + timeout = 10 + +# vim: ft=cfg diff --git a/.config/fontconfig/fonts.conf b/.config/fontconfig/fonts.conf new file mode 100755 index 0000000..8f13d82 --- /dev/null +++ b/.config/fontconfig/fonts.conf @@ -0,0 +1,28 @@ + + + + + + serif + + Fira Sans + + + + sans-serif + + Fira Sans + + + + sans + + Fira Sans + + + + monospace + Fira Mono + + + diff --git a/.config/git/config b/.config/git/config new file mode 100644 index 0000000..d8f9823 --- /dev/null +++ b/.config/git/config @@ -0,0 +1,12 @@ +[user] + name = Dmitry Zakharchenko + email = dmitz@disroot.org + username = dmitz +[init] + defaultBranch = master +[sendemail] + smtpserver = disroot.org + smtpuser = dmitz@disroot.org + smtpencryption = tls + smtpserverport = 587 + annotate = yes diff --git a/.config/mimeapps.list b/.config/mimeapps.list new file mode 100644 index 0000000..c808ace --- /dev/null +++ b/.config/mimeapps.list @@ -0,0 +1,13 @@ +[Default Applications] + +text/x-shellscript=text.desktop; +x-scheme-handler/magnet=torrent.desktop; +application/x-bittorrent=torrent.desktop; +x-scheme-handler/mailto=mail.desktop; +text/plain=text.desktop; +application/postscript=pdf.desktop; +application/pdf=pdf.desktop; +image/png=img.desktop; +image/jpeg=img.desktop; +image/gif=img.desktop; +inode/directory=file.desktop diff --git a/.config/mpd/mpd.conf b/.config/mpd/mpd.conf new file mode 100644 index 0000000..398bee9 --- /dev/null +++ b/.config/mpd/mpd.conf @@ -0,0 +1,21 @@ +db_file "~/.config/mpd/database" +state_file "~/.config/mpd/state" +music_directory "~/music" + +auto_update "yes" +bind_to_address "localhost" +port "6600" +restore_paused "yes" +max_output_buffer_size "16384" + +audio_output { + type "pulse" + name "pulse" +} + +audio_output { + type "fifo" + name "Visualizer feed" + path "/tmp/mpd.fifo" + format "44100:16:2" +} diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf new file mode 100644 index 0000000..4786ce8 --- /dev/null +++ b/.config/mpv/input.conf @@ -0,0 +1,13 @@ +l seek 5 +h seek -5 +j seek -60 +k seek 60 +L add chapter 1 +H add chapter -1 +S cycle sub +A cycle audio += add volume 5 +- add volume -5 +z add sub-delay -1 +x add sub-delay +1 +tab script-message osc-chapterlist 2 ; show-text "${osd-ass-cc/0}{\\an9}${osd-ass-cc/1}${chapter}" diff --git a/.config/mpv/mpv.conf b/.config/mpv/mpv.conf new file mode 100644 index 0000000..5fa4b4b --- /dev/null +++ b/.config/mpv/mpv.conf @@ -0,0 +1,6 @@ +ytdl-format="bestvideo[height<=?720]+bestaudio/best" +vo=gpu +alang=eng,rus +slang=rus,eng +audio-file-auto=fuzzy +sub-auto=fuzzy diff --git a/.config/mpv/scripts/autosub.lua b/.config/mpv/scripts/autosub.lua new file mode 100644 index 0000000..5225193 --- /dev/null +++ b/.config/mpv/scripts/autosub.lua @@ -0,0 +1,246 @@ +--============================================================================= +-->> SUBLIMINAL PATH: +--============================================================================= +-- This script uses Subliminal to download subtitles, +-- so make sure to specify your system's Subliminal location below: +local subliminal = '/usr/bin/subliminal' +--============================================================================= +-->> SUBTITLE LANGUAGE: +--============================================================================= +-- Specify languages in this order: +-- { 'language name', 'ISO-639-1', 'ISO-639-2' } ! +-- (See: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) +local languages = { +-- If subtitles are found for the first language, +-- other languages will NOT be downloaded, +-- so put your preferred language first: + { 'English', 'en', 'eng' } +} +--============================================================================= +-->> PROVIDER LOGINS: +--============================================================================= +-- These are completely optional and not required +-- for the functioning of the script! +-- If you use any of these services, simply uncomment it +-- and replace 'USERNAME' and 'PASSWORD' with your own: +local logins = { + { '--opensubtitles', 'giveaway1', 'qwe123A@' }, +} +--============================================================================= +-->> ADDITIONAL OPTIONS: +--============================================================================= +local bools = { + auto = false, -- Automatically download subtitles, no hotkeys required + debug = false, -- Use `--debug` in subliminal command for debug output + force = true, -- Force download; will overwrite existing subtitle files + utf8 = true, -- Save all subtitle files as UTF-8 +} +local excludes = { + -- Movies with a path containing any of these strings/paths + -- will be excluded from auto-downloading subtitles. + -- Full paths are also allowed, e.g.: + -- '/home/david/Videos', + 'no-subs-dl', +} +local includes = { + -- If anything is defined here, only the movies with a path + -- containing any of these strings/paths will auto-download subtitles. + -- Full paths are also allowed, e.g.: + -- '/home/david/Videos', +} +--============================================================================= +local utils = require 'mp.utils' + + +-- Download function: download the best subtitles in most preferred language +function download_subs(language) + language = language or languages[1] + if #language == 0 then + log('No Language found\n') + return false + end + + log('Searching ' .. language[1] .. ' subtitles ...', 30) + + -- Build the `subliminal` command, starting with the executable: + local table = { args = { subliminal } } + local a = table.args + + for _, login in ipairs(logins) do + a[#a + 1] = login[1] + a[#a + 1] = login[2] + a[#a + 1] = login[3] + end + if bools.debug then + -- To see `--debug` output start MPV from the terminal! + a[#a + 1] = '--debug' + end + + a[#a + 1] = 'download' + if bools.force then + a[#a + 1] = '-f' + end + if bools.utf8 then + a[#a + 1] = '-e' + a[#a + 1] = 'utf-8' + end + + a[#a + 1] = '-l' + a[#a + 1] = language[2] + a[#a + 1] = '-d' + a[#a + 1] = directory + a[#a + 1] = filename --> Subliminal command ends with the movie filename. + + local result = utils.subprocess(table) + + if string.find(result.stdout, 'Downloaded 1 subtitle') then + -- When multiple external files are present, + -- always activate the most recently downloaded: + mp.set_property('slang', language[2]) + -- Subtitles are downloaded successfully, so rescan to activate them: + mp.commandv('rescan_external_files') + log(language[1] .. ' subtitles ready!') + return true + else + log('No ' .. language[1] .. ' subtitles found\n') + return false + end +end + +-- Manually download second language subs by pressing 'n': +function download_subs2() + download_subs(languages[2]) +end + +-- Control function: only download if necessary +function control_downloads() + -- Make MPV accept external subtitle files with language specifier: + mp.set_property('sub-auto', 'fuzzy') + -- Set subtitle language preference: + mp.set_property('slang', languages[1][2]) + mp.msg.warn('Reactivate external subtitle files:') + mp.commandv('rescan_external_files') + directory, filename = utils.split_path(mp.get_property('path')) + + if not autosub_allowed() then + return + end + + sub_tracks = {} + for _, track in ipairs(mp.get_property_native('track-list')) do + if track['type'] == 'sub' then + sub_tracks[#sub_tracks + 1] = track + end + end + if bools.debug then -- Log subtitle properties to terminal: + for _, track in ipairs(sub_tracks) do + mp.msg.warn('Subtitle track', track['id'], ':\n{') + for k, v in pairs(track) do + if type(v) == 'string' then v = '"' .. v .. '"' end + mp.msg.warn(' "' .. k .. '":', v) + end + mp.msg.warn('}\n') + end + end + + for _, language in ipairs(languages) do + if should_download_subs_in(language) then + if download_subs(language) then return end -- Download successful! + else return end -- No need to download! + end + log('No subtitles were found') +end + +-- Check if subtitles should be auto-downloaded: +function autosub_allowed() + local duration = tonumber(mp.get_property('duration')) + local active_format = mp.get_property('file-format') + + if not bools.auto then + mp.msg.warn('Automatic downloading disabled!') + return false + elseif duration < 900 then + mp.msg.warn('Video is less than 15 minutes\n' .. + '=> NOT auto-downloading subtitles') + return false + elseif directory:find('^http') then + mp.msg.warn('Automatic subtitle downloading is disabled for web streaming') + return false + elseif active_format:find('^cue') then + mp.msg.warn('Automatic subtitle downloading is disabled for cue files') + return false + else + local not_allowed = {'aiff', 'ape', 'flac', 'mp3', 'ogg', 'wav', 'wv', 'tta'} + + for _, file_format in pairs(not_allowed) do + if file_format == active_format then + mp.msg.warn('Automatic subtitle downloading is disabled for audio files') + return false + end + end + + for _, exclude in pairs(excludes) do + local escaped_exclude = exclude:gsub('%W','%%%0') + local excluded = directory:find(escaped_exclude) + + if excluded then + mp.msg.warn('This path is excluded from auto-downloading subs') + return false + end + end + + for i, include in ipairs(includes) do + local escaped_include = include:gsub('%W','%%%0') + local included = directory:find(escaped_include) + + if included then break + elseif i == #includes then + mp.msg.warn('This path is not included for auto-downloading subs') + return false + end + end + end + + return true +end + +-- Check if subtitles should be downloaded in this language: +function should_download_subs_in(language) + for i, track in ipairs(sub_tracks) do + local subtitles = track['external'] and + 'subtitle file' or 'embedded subtitles' + + if not track['lang'] and (track['external'] or not track['title']) + and i == #sub_tracks then + local status = track['selected'] and ' active' or ' present' + log('Unknown ' .. subtitles .. status) + mp.msg.warn('=> NOT downloading new subtitles') + return false -- Don't download if 'lang' key is absent + elseif track['lang'] == language[3] or track['lang'] == language[2] or + (track['title'] and track['title']:lower():find(language[3])) then + if not track['selected'] then + mp.set_property('sid', track['id']) + log('Enabled ' .. language[1] .. ' ' .. subtitles .. '!') + else + log(language[1] .. ' ' .. subtitles .. ' active') + end + mp.msg.warn('=> NOT downloading new subtitles') + return false -- The right subtitles are already present + end + end + mp.msg.warn('No ' .. language[1] .. ' subtitles were detected\n' .. + '=> Proceeding to download:') + return true +end + +-- Log function: log to both terminal and MPV OSD (On-Screen Display) +function log(string, secs) + secs = secs or 2.5 -- secs defaults to 2.5 when secs parameter is absent + mp.msg.warn(string) -- This logs to the terminal + mp.osd_message(string, secs) -- This logs to MPV screen +end + + +mp.add_key_binding('b', 'download_subs', download_subs) +mp.add_key_binding('B', 'download_subs2', download_subs2) +mp.register_event('file-loaded', control_downloads) diff --git a/.config/mpv/scripts/youtube-quality.lua b/.config/mpv/scripts/youtube-quality.lua new file mode 100644 index 0000000..98f04e9 --- /dev/null +++ b/.config/mpv/scripts/youtube-quality.lua @@ -0,0 +1,272 @@ +-- youtube-quality.lua +-- +-- Change youtube video quality on the fly. +-- +-- Diplays a menu that lets you switch to different ytdl-format settings while +-- you're in the middle of a video (just like you were using the web player). +-- +-- Bound to ctrl-f by default. + +local mp = require 'mp' +local utils = require 'mp.utils' +local msg = require 'mp.msg' +local assdraw = require 'mp.assdraw' + +local opts = { + --key bindings + toggle_menu_binding = "ctrl+f", + up_binding = "UP", + down_binding = "DOWN", + select_binding = "ENTER", + + --formatting / cursors + selected_and_active = "▶ - ", + selected_and_inactive = "● - ", + unselected_and_active = "▷ - ", + unselected_and_inactive = "○ - ", + + --font size scales by window, if false requires larger font and padding sizes + scale_playlist_by_window=false, + + --playlist ass style overrides inside curly brackets, \keyvalue is one field, extra \ for escape in lua + --example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1 + --read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags + --undeclared tags will use default osd settings + --these styles will be used for the whole playlist. More specific styling will need to be hacked in + -- + --(a monospaced font is recommended but not required) + style_ass_tags = "{\\fnmonospace}", + + --paddings for top left corner + text_padding_x = 5, + text_padding_y = 5, + + --other + menu_timeout = 10, + + --use youtube-dl to fetch a list of available formats (overrides quality_strings) + fetch_formats = false, + + --default menu entries + quality_strings=[[ + [ + {"1080p" : "bestvideo[height<=?1080]+bestaudio/best"}, + {"720p" : "bestvideo[height<=?720]+bestaudio/best"}, + {"480p" : "bestvideo[height<=?480]+bestaudio/best"}, + {"360p" : "bestvideo[height<=?360]+bestaudio/best"}, + {"240p" : "bestvideo[height<=?240]+bestaudio/best"}, + {"144p" : "bestvideo[height<=?144]+bestaudio/best"} + ] + ]], +} +(require 'mp.options').read_options(opts, "youtube-quality") +opts.quality_strings = utils.parse_json(opts.quality_strings) + +local destroyer = nil + + +function show_menu() + local selected = 1 + local active = 0 + local current_ytdl_format = mp.get_property("ytdl-format") + msg.verbose("current ytdl-format: "..current_ytdl_format) + local num_options = 0 + local options = {} + + + if opts.fetch_formats then + options, num_options = download_formats() + end + + if next(options) == nil then + for i,v in ipairs(opts.quality_strings) do + num_options = num_options + 1 + for k,v2 in pairs(v) do + options[i] = {label = k, format=v2} + if v2 == current_ytdl_format then + active = i + selected = active + end + end + end + end + + --set the cursor to the currently format + for i,v in ipairs(options) do + if v.format == current_ytdl_format then + active = i + selected = active + break + end + end + + function selected_move(amt) + selected = selected + amt + if selected < 1 then selected = num_options + elseif selected > num_options then selected = 1 end + timeout:kill() + timeout:resume() + draw_menu() + end + function choose_prefix(i) + if i == selected and i == active then return opts.selected_and_active + elseif i == selected then return opts.selected_and_inactive end + + if i ~= selected and i == active then return opts.unselected_and_active + elseif i ~= selected then return opts.unselected_and_inactive end + return "> " --shouldn't get here. + end + + function draw_menu() + local ass = assdraw.ass_new() + + ass:pos(opts.text_padding_x, opts.text_padding_y) + ass:append(opts.style_ass_tags) + + for i,v in ipairs(options) do + ass:append(choose_prefix(i)..v.label.."\\N") + end + + local w, h = mp.get_osd_size() + if opts.scale_playlist_by_window then w,h = 0, 0 end + mp.set_osd_ass(w, h, ass.text) + end + + function destroy() + timeout:kill() + mp.set_osd_ass(0,0,"") + mp.remove_key_binding("move_up") + mp.remove_key_binding("move_down") + mp.remove_key_binding("select") + mp.remove_key_binding("escape") + destroyer = nil + end + timeout = mp.add_periodic_timer(opts.menu_timeout, destroy) + destroyer = destroy + + mp.add_forced_key_binding(opts.up_binding, "move_up", function() selected_move(-1) end, {repeatable=true}) + mp.add_forced_key_binding(opts.down_binding, "move_down", function() selected_move(1) end, {repeatable=true}) + mp.add_forced_key_binding(opts.select_binding, "select", function() + destroy() + mp.set_property("ytdl-format", options[selected].format) + reload_resume() + end) + mp.add_forced_key_binding(opts.toggle_menu_binding, "escape", destroy) + + draw_menu() + return +end + +local ytdl = { + path = "youtube-dl", + searched = false, + blacklisted = {} +} + +format_cache={} +function download_formats() + local function exec(args) + local ret = utils.subprocess({args = args}) + return ret.status, ret.stdout, ret + end + + local function table_size(t) + s = 0 + for i,v in ipairs(t) do + s = s+1 + end + return s + end + + local url = mp.get_property("path") + + url = string.gsub(url, "ytdl://", "") -- Strip possible ytdl:// prefix. + + -- don't fetch the format list if we already have it + if format_cache[url] ~= nil then + local res = format_cache[url] + return res, table_size(res) + end + mp.osd_message("fetching available formats with youtube-dl...", 60) + + if not (ytdl.searched) then + local ytdl_mcd = mp.find_config_file("youtube-dl") + if not (ytdl_mcd == nil) then + msg.verbose("found youtube-dl at: " .. ytdl_mcd) + ytdl.path = ytdl_mcd + end + ytdl.searched = true + end + + local command = {ytdl.path, "--no-warnings", "--no-playlist", "-J"} + table.insert(command, url) + local es, json, result = exec(command) + + if (es < 0) or (json == nil) or (json == "") then + mp.osd_message("fetching formats failed...", 1) + msg.error("failed to get format list: " .. err) + return {}, 0 + end + + local json, err = utils.parse_json(json) + + if (json == nil) then + mp.osd_message("fetching formats failed...", 1) + msg.error("failed to parse JSON data: " .. err) + return {}, 0 + end + + res = {} + msg.verbose("youtube-dl succeeded!") + for i,v in ipairs(json.formats) do + if v.vcodec ~= "none" then + local fps = v.fps and v.fps.."fps" or "" + local resolution = string.format("%sx%s", v.width, v.height) + local l = string.format("%-9s %-5s (%-4s / %s)", resolution, fps, v.ext, v.vcodec) + local f = string.format("%s+bestaudio/best", v.format_id) + table.insert(res, {label=l, format=f, width=v.width }) + end + end + + table.sort(res, function(a, b) return a.width > b.width end) + + mp.osd_message("", 0) + format_cache[url] = res + return res, table_size(res) +end + + +-- register script message to show menu +mp.register_script_message("toggle-quality-menu", +function() + if destroyer ~= nil then + destroyer() + else + show_menu() + end +end) + +-- keybind to launch menu +mp.add_key_binding(opts.toggle_menu_binding, "quality-menu", show_menu) + +-- special thanks to reload.lua (https://github.com/4e6/mpv-reload/) +function reload_resume() + local playlist_pos = mp.get_property_number("playlist-pos") + local reload_duration = mp.get_property_native("duration") + local time_pos = mp.get_property("time-pos") + + mp.set_property_number("playlist-pos", playlist_pos) + + -- Tries to determine live stream vs. pre-recordered VOD. VOD has non-zero + -- duration property. When reloading VOD, to keep the current time position + -- we should provide offset from the start. Stream doesn't have fixed start. + -- Decent choice would be to reload stream from it's current 'live' positon. + -- That's the reason we don't pass the offset when reloading streams. + if reload_duration and reload_duration > 0 then + local function seeker() + mp.commandv("seek", time_pos, "absolute") + mp.unregister_event(seeker) + end + mp.register_event("file-loaded", seeker) + end +end diff --git a/.config/msmtp/config b/.config/msmtp/config new file mode 100644 index 0000000..58628c3 --- /dev/null +++ b/.config/msmtp/config @@ -0,0 +1,11 @@ +account dmitz@disroot.org +host disroot.org +port 465 +from dmitz@disroot.org +user dmitz@disroot.org +passwordeval "pass mail/disroot.org" +auth on +tls on +tls_trust_file /etc/ssl/certs/ca-certificates.crt +logfile /home/dmitz/.config/msmtp/msmtp.log +tls_starttls off diff --git a/.config/mutt/binds b/.config/mutt/binds new file mode 100644 index 0000000..e30fd93 --- /dev/null +++ b/.config/mutt/binds @@ -0,0 +1,67 @@ +# vim: filetype=neomuttrc + +# General rebindings +bind index v tag-entry +bind index,pager i noop +bind index,pager g noop +bind index \Cf noop +bind index,pager M noop +bind index,pager C noop +bind index a toggle-new +bind index gg first-entry +bind index j next-entry +bind index k previous-entry +bind attach l view-mailcap +bind index G last-entry +bind pager,attach h exit +bind pager j next-line +bind pager k previous-line +bind pager l view-attachments +bind index D delete-message +bind index U undelete-message +bind index L limit +bind index h noop +bind index l display-message +bind index,query tag-entry +macro browser h '..' "Go to parent folder" +bind index,pager H view-raw-message +bind browser l select-entry +bind pager,browser gg top-page +bind pager,browser G bottom-page +bind index,pager,browser d half-down +bind index,pager,browser u half-up +bind index,pager S sync-mailbox +bind index,pager R group-reply +bind index \031 previous-undeleted +bind index \005 next-undeleted +bind pager \031 previous-line +bind pager \005 next-line +bind editor complete-query + +# Sidebar +bind index,pager \Ck sidebar-prev +bind index,pager \Cj sidebar-next +bind index,pager \Co sidebar-open +bind index,pager \Cp sidebar-prev-new +bind index,pager \Cn sidebar-next-new +bind index,pager B sidebar-toggle-visible + +macro index,pager gi "=INBOX" "go to inbox" +macro index,pager Mi ";=INBOX" "move mail to inbox" +macro index,pager Ci ";=INBOX" "copy mail to inbox" +macro index,pager gd "=Drafts" "go to drafts" +macro index,pager Md ";=Drafts" "move mail to drafts" +macro index,pager Cd ";=Drafts" "copy mail to drafts" +macro index,pager gt "=Trash" "go to trash" +macro index,pager Mt ";=Trash" "move mail to trash" +macro index,pager Ct ";=Trash" "copy mail to trash" +macro index,pager gs "=Sent" "go to sent" +macro index,pager Ms ";=Sent" "move mail to sent" +macro index,pager Cs ";=Sent" "copy mail to sent" +macro index,pager ga "=Archive" "go to archive" +macro index,pager Ma ";=Archive" "move mail to archive" +macro index,pager Ca ";=Archive" "copy mail to archive" +macro index,pager c "set my_pipe_decode=\$pipe_decode pipe_decodeabook --add-emailset pipe_decode=\$my_pipe_decode; unset my_pipe_decode" "add the sender address to abook" +macro index R "mbsync -c $XDG_CONFIG_HOME/isync/mbsyncrc dmitz@disroot.org" "run mbsync to sync dmitz@disroot.org" +macro index A "T~UN." "mark all messages as read" +macro index \Cf "unset wait_keyprintf 'Enter a search term to find with notmuch: '; read x; echo \$x >~/.cache/mutt_terms~i \"\`notmuch search --output=messages \$(cat ~/.cache/mutt_terms) | head -n 600 | perl -le '@a=<>;s/\^id:// for@a;$,=\"|\";print@a' | perl -le '@a=<>; chomp@a; s/\\+/\\\\+/ for@a;print@a' \`\"" "show only messages matching a notmuch pattern" diff --git a/.config/mutt/colors b/.config/mutt/colors new file mode 100644 index 0000000..ff320fe --- /dev/null +++ b/.config/mutt/colors @@ -0,0 +1,48 @@ +# vim: filetype=neomuttrc + +color index blue default '.*' +color index white default "~R" +color index brightyellow default "~T" +color indicator yellow black +color sidebar_highlight yellow default +color sidebar_divider brightblack black +color sidebar_flagged red black +color sidebar_new blue black +color normal blue default +color error red default +color tilde black default +color message blue default +color markers red white +color attachment white default +color search magenta default +color status white black +color hdrdefault green default +color quoted green default +color quoted1 blue default +color quoted2 cyan default +color quoted3 yellow default +color quoted4 red default +color quoted5 brightred default +color signature green default +color bold black default +color underline black default +color normal default default + +# Regex highlighting: +color header default default ".*" +color header magenta default "(^Date:)" +color header yellow default "(^From:)" +color header cyan default "(^Subject:)" +color header white default "(^CC|BCC:)" +color body red default "[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+" # Email addresses +color body blue default "(https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+" # URL +color body brightwhite black "\`[^\`]*\`" # Green text between ` and ` +color body blue default "^# \.*" # Headings as bold blue +color body cyan default "^## \.*" # Subheadings as bold cyan +color body green default "^### \.*" # Subsubheadings as bold green +color body yellow default "^(\t| )*(-|\\*) \.*" # List items as yellow +color body red default "(BAD signature)" +color body cyan default "(Good signature)" +color body brightblack default "^gpg: Good signature .*" +color body brightyellow default "^gpg: " +color body brightyellow red "^gpg: BAD signature from.*" diff --git a/.config/mutt/mailcap b/.config/mutt/mailcap new file mode 100644 index 0000000..b355f32 --- /dev/null +++ b/.config/mutt/mailcap @@ -0,0 +1,9 @@ +text/plain; $EDITOR %s ; +text/html; openfile %s ; nametemplate=%s.html +text/html; lynx -assume_charset=%{charset} -display_charset=utf-8 -dump %s; nametemplate=%s.html; copiousoutput; +image/*; openfile %s ; +video/*; setsid mpv --quiet %s &; copiousoutput +audio/*; mpv %s ; +application/pdf; openfile %s ; +application/pgp-encrypted; gpg -d '%s'; copiousoutput; +application/pgp-keys; gpg --import '%s'; copiousoutput; diff --git a/.config/mutt/muttrc b/.config/mutt/muttrc new file mode 100644 index 0000000..c0ca59c --- /dev/null +++ b/.config/mutt/muttrc @@ -0,0 +1,53 @@ +# vim: filetype=neomuttrc + +set realname = "Dmitry Zakharchenko" +set from = "dmitz@disroot.org" +set sendmail = "msmtp -a dmitz@disroot.org" +alias me dmitz +set folder = "/home/dmitz/.local/share/mail/dmitz@disroot.org" +set header_cache = /home/dmitz/.cache/mutt/dmitz@disroot.org/headers +set message_cachedir = /home/dmitz/.cache/mutt/dmitz@disroot.org/bodies +set mbox_type = Maildir +set hostname = "disroot.org" +set spoolfile = +INBOX +set postponed = +Drafts +set trash = +Trash +set record = +Sent + +mailboxes "=INBOX" "=Sent" "=Drafts" "=Archive" "=Trash" + +set mailcap_path = /home/dmitz/.config/mutt/mailcap +set mime_type_query_command = "file --mime-type -b %s" +set date_format="%b %d" +set index_format="%3zs %-8D %s" +set status_format = "[ Folder: %f ] [%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]%> %?p?( %p postponed )?" +set sort = 'reverse-date' +set smtp_authenticators = 'gssapi:login' +set query_command = "abook --mutt-query '%s'" +set rfc2047_parameters = yes +set sleep_time = 0 +set markers = no +set mark_old = no +set mime_forward = yes +set wait_key = no +set fast_reply +set fcc_attach +set forward_format = "Fwd: %s" +set forward_quote +set reverse_name +set include +set mail_check=60 +auto_view text/html +auto_view application/pgp-encrypted +alternative_order text/plain text/enriched text/html + +# Sidebar +set sidebar_visible = yes +set sidebar_width = 15 +set sidebar_short_path = yes +set sidebar_next_new_wrap = yes +set mail_check_stats +set sidebar_format = '%D%?F? [%F]?%* %?N?%N/? %?S?%S?' + +source /home/dmitz/.config/mutt/binds +source /home/dmitz/.config/mutt/colors diff --git a/.config/ncmpcpp/bindings b/.config/ncmpcpp/bindings new file mode 100644 index 0000000..87d67db --- /dev/null +++ b/.config/ncmpcpp/bindings @@ -0,0 +1,64 @@ +def_key "+" + show_clock +def_key "=" + volume_up +def_key "j" + scroll_down +def_key "k" + scroll_up +def_key "ctrl-u" + page_up +def_key "ctrl-d" + page_down +def_key "u" + page_up +def_key "d" + page_down +def_key "h" + previous_column +def_key "l" + next_column +def_key "." + show_lyrics +def_key "n" + next_found_item +def_key "N" + previous_found_item +def_key "J" + move_sort_order_down +def_key "K" + move_sort_order_up +def_key "h" + jump_to_parent_directory +def_key "l" + enter_directory +def_key "l" + run_action +def_key "l" + play_item +def_key "m" + show_media_library +def_key "m" + toggle_media_library_columns_mode +def_key "t" + show_tag_editor +def_key "v" + show_visualizer +def_key "G" + move_end +def_key "g" + move_home +def_key "U" + update_database +def_key "s" + reset_search_engine +def_key "s" + show_search_engine +def_key "f" + show_browser +def_key "f" + change_browse_mode +def_key "x" + delete_playlist_items +def_key "P" + show_playlist diff --git a/.config/ncmpcpp/config b/.config/ncmpcpp/config new file mode 100644 index 0000000..181b421 --- /dev/null +++ b/.config/ncmpcpp/config @@ -0,0 +1,45 @@ +# mpd +mpd_host = "localhost" +mpd_port = "6600" + +# Directories for storing ncmpcpp files +ncmpcpp_directory = ~/.config/ncmpcpp +lyrics_directory = ~/.local/share/lyrics + +# Playlist +playlist_display_mode = "classic" (classic/columns) +autocenter_mode = "yes" +centered_cursor = "yes" +cyclic_scrolling = "yes" +mouse_list_scroll_whole_page = "no" +now_playing_prefix = "> $b" + +# Bars +titles_visibility = "yes" +header_visibility = "no" +statusbar_visibility = "yes" + +# Browser +browser_playlist_prefix = "$2plist »$0 " +browser_display_mode = "classic" (classic/columns) + +# Colors +discard_colors_if_item_is_selected = "yes" +header_window_color = "default" +volume_color = "yellow" +state_line_color = "black" +state_flags_color = "black" +main_window_color = "default" +color1 = "black" +color2 = "magenta" +progressbar_color = "white" +statusbar_color = "white" +visualizer_color = "cyan" + +# Others +progressbar_look = "=>" +song_window_title_format = "Now playing: {%a > }{%t}|{%f}" +search_engine_display_mode = "columns" (classic/columns) +follow_now_playing_lyrics = "yes" +user_interface = "alternative" (classic/alternative) +vim:ft=config diff --git a/.config/newsboat/config b/.config/newsboat/config new file mode 100644 index 0000000..2fbbe4d --- /dev/null +++ b/.config/newsboat/config @@ -0,0 +1,79 @@ +external-url-viewer "urlscan -dc -r 'linkhandler {}'" +browser linkhandler +auto-reload no +goto-next-feed no +show-read-feeds no +show-read-articles no +confirm-mark-feed-read no +max-items 30 +reload-threads 40 +text-width 120 +history-limit 0 +notify-always no +notify-program "notify-send" + +# Formatting +notify-format "%d new articles loaded." +datetime-format "%b %d" +feedlist-title-format " Feed (%u feeds unreaded)" +articlelist-title-format " %T (%u articles unreaded)" +feedlist-format " %-6T %-50t (%U New)" +articlelist-format "%3f %-8D %t" +itemview-title-format " %T" + +# Bindings +bind-key h quit +bind-key j down +bind-key k up +bind-key l open +bind-key j next articlelist +bind-key k prev articlelist +bind-key J next-feed articlelist +bind-key K prev-feed articlelist +bind-key g home +bind-key G end +bind-key d pagedown +bind-key u pageup +bind-key U show-urls +bind-key a toggle-article-read +bind-key T set-tag +bind-key t toggle-show-read-feeds +bind-key x delete-article +bind-key b bookmark +bind-key SPACE macro-prefix + +# Bookmarks +bookmark-cmd "echo >> $XDG_CONFIG_HOME/newsboat/bookmarks" +bookmark-interactive no +bookmark-autopilot yes + +# Macroses +macro y set browser "echo %u | xclip -r -sel c"; open-in-browser; set browser linkhandler +macro d set browser "dm-handler %u"; open-in-browser-and-mark-read; set browser linkhandler +macro c set browser "pipe-viewer --no-interactive --comments=%u | less"; open-in-browser; set browser linkhandler +macro i set browser "pipe-viewer --no-interactive --info=%u | less"; open-in-browser; set browser linkhandler + +# Colors +color info black white reverse +color listnormal default default +color listnormal_unread blue default +color listfocus yellow default +color listfocus_unread yellow default + +# Highlights +highlight all "---.*---" yellow +highlight feedlist ".*(0/0))" black +highlight article "(^Feed:*)" cyan default +highlight article "(^Title:*)" green default +highlight article "(^Author:*)" yellow default +highlight article "(^Date:*)" magenta default +highlight article "(^Link:)" blue default +highlight article "https?://[^ ]+" blue default +highlight article "\\[[0-9]+\\]" magenta default + +# Filters +ignore-mode "display" +ignore-article "https://www.youtube.com/feeds/videos.xml?channel_id=UCWnNKC1wrH_NXAXc5bhbFnA" "title !# \"Опергеймер\"" +ignore-article "https://www.youtube.com/feeds/videos.xml?channel_id=UCjulQNQQJmpYzI-BD1-s03w" "title !# \"Маргинал\"" +ignore-article "http://feed.rutracker.cc/atom/f/1950.atom" "title !# \"Sub\"" +ignore-article "https://www.youtube.com/feeds/videos.xml?channel_id=UC4rpWi42yPqTA0wnfx7MqOA" "title =~ \"на Паучительных\"" diff --git a/.config/newsboat/urls b/.config/newsboat/urls new file mode 100644 index 0000000..ea4e422 --- /dev/null +++ b/.config/newsboat/urls @@ -0,0 +1,79 @@ +"TECH" "(---)" +https://go.dev/blog/feed.atom "(www)" +https://landchad.net/rss.xml "(www)" "~LandChad" +https://drewdevault.com/blog/index.xml "(www)" "~Drew DeVault" +http://suckless.org/atom.xml "(www)" "~skls" +https://www.phoronix.com/rss.php "(www)" +https://www.gamingonlinux.com/article_rss.php "(www)" "~GamingOnLinux" +https://lobste.rs/top/rss "(www)" "~Lobsters" +https://www.youtube.com/feeds/videos.xml?channel_id=UC3kAbMcYr-JEMSb2xX4OdpA "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCsnGwSIHyoYN0kiINAGUKxg "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC9-y-6csu5WGm29I7JiwpnA "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCkf4VIqu3Acnfzuk3kRIFwA "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC8ENHE5xdFSwx71u3fDH5Xw "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCUmLRMERmJrmUtgnbFfknAg "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC3cntnJoRiiLaZ7dZwTTQ8A "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCW-HBBzxn7URXPHzWiZTq_A "(ytb)" + +"HL" "(---)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCjulQNQQJmpYzI-BD1-s03w "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC4rpWi42yPqTA0wnfx7MqOA "(ytb)" +https://www.youtube.com./feeds/videos.xml?channel_id=UC2WNW0NZVyMeEPvtLmScgvQ "(ytb)" + +"PPL" "(---)" +https://lukesmith.xyz/rss.xml "(www)" +https://notrelated.xyz/rss "(www)" "~Not Related" +https://lukesmith.xyz/peertube "(prt)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCfUaZ8Ra7m7BqUEACv2jySw "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC7YOGHUfC1Tb6E4pudI9STA "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCRxPHKOOwFxW2Ej2svBh3lw "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCla6APLHX6W3FeNLc8PYuvg "(ytb)" + +"SOC" "(---)" +https://lb.ua/rss/ukr/rss.xml "(www)" "~LB.ua" +https://svtv.org/feed/rss/ "(www)" "~SVTV" +https://www.youtube.com/feeds/videos.xml?channel_id=UCWjEiMNZv4g3P9BWbrtMjyA "(ytb)" "~SVTV" +https://kamilkazani.substack.com/feed "(www)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCjjElKokwu5KCN2PeHzE9Eg "(ytb)" "~Furydrops" +https://www.youtube.com/feeds/videos.xml?channel_id=UCbWcXB0PoqOsAvAdfzWMf0w "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCo4au6lRX4-_gIczBneEZWA "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCdHT7KB1gDAXZYpPW71fn0Q "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCsK84qDhiw7SwtZonplxavg "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCvKPc71Dd8qnuKZd2nRyH4g "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC8GoduxspzU7MpKYdbMyI0A "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCJLorkdDK41pOQyoVQbFqJQ "(ytb)" + +"MOV" "(---)" +https://thepiratebay10.org/rss/top100/207 "(prb)" "~Movies (top 100)" +http://feed.rutracker.cc/atom/f/1950.atom "(rtk)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCbaKd4mhqd1QvfDp5EaUlHw "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCoxVyr6d4OBKEY1dHhtEkRg "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCOaqC7XshSJO7PWwvjDJ1nQ "(ytb)" + +"HIS" "(---)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCOuWeOkMrq84u5LY6apWQ8Q "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC2CmP3hssH0MAqV18UZs0Xw "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCGzfpg1YiBIlgcODQI4lDvQ "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCZAENaOaceQUMd84GDc26EA "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCsK1oV0PGkcZ1UhFtajx0dg "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCxRSpkGOH_09pxKvgD8S5jQ "(ytb)" "~Study of Antiquity" +https://www.youtube.com/feeds/videos.xml?channel_id=UCprXm6I8qIRkllnCX_MnDyQ "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC0I4VnqZNLttX3BC0P7c1wQ "(ytb)" + +"LANG" "(---)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCJSqXOkySQgm0dYjccicA1Q "(ytb)" +https://www.youtube.com/feeds/videos.xml?channel_id=UCKMGLK-Inu1lReNdbeYBgOA "(ytb)" "~Virginia Bēowulf" + +"MUS" "(---)" +https://www.youtube.com/feeds/videos.xml?channel_id=UC-MUFcjuU49I-vVL7H1Antw "(ytb)" +https://rss.nixnet.services/?action=display&bridge=Bandcamp&context=By+band&band=soundfortress&type=changes&format=Atom "(bnd)" "~Soundfortess" +https://rss.nixnet.services/?action=display&bridge=Bandcamp&context=By+band&band=yezdin&type=changes&format=Atom "(bnd)" "~Yezdin" + +"DEV" "(---)" +https://repology.org/maintainer/dmitz%40disroot.org/feed-for-repo/alpine_edge/atom "(www)" +https://github.com/lukesmithxyz/voidrice/commits/master.atom "(ghb)" +https://github.com/LukeSmithxyz/dwmblocks/commits/master.atom "(ghb)" +https://github.com/LukeSmithxyz/dwm/commits/master.atom "(ghb)" +https://github.com/LukeSmithxyz/st/commits/master.atom "(ghb)" +https://github.com/qutebrowser/qutebrowser/releases.atom "(ghb)" +https://github.com/newsboat/newsboat/releases.atom "(ghb)" diff --git a/.config/notmuch/notmuchrc b/.config/notmuch/notmuchrc new file mode 100644 index 0000000..97d1a83 --- /dev/null +++ b/.config/notmuch/notmuchrc @@ -0,0 +1,14 @@ +[database] +path=/home/dmitz/.local/share/mail +[user] +name=dmitz +primary_email=dmitz@disroot.org +[new] +tags=unread;inbox; +ignore=.mbsyncstate;.uidvalidity +[search] +exclude_tags=deleted;spam; +[maildir] +synchronize_flags=true +[crypto] +gpg_path=gpg diff --git a/.config/nvim/colors/eighties.vim b/.config/nvim/colors/eighties.vim new file mode 100644 index 0000000..d88f042 --- /dev/null +++ b/.config/nvim/colors/eighties.vim @@ -0,0 +1,413 @@ +" vi:syntax=vim + +" base16-vim (https://github.com/chriskempson/base16-vim) +" by Chris Kempson (http://chriskempson.com) +" Eighties scheme by Chris Kempson (http://chriskempson.com) + +" This enables the coresponding base16-shell script to run so that +" :colorscheme works in terminals supported by base16-shell scripts +" User must set this variable in .vimrc +" let g:base16_shell_path=base16-builder/output/shell/ +if !has("gui_running") + if exists("g:base16_shell_path") + execute "silent !/bin/sh ".g:base16_shell_path."/base16-eighties.sh" + endif +endif + +" GUI color definitions +let s:gui00 = "2d2d2d" +let g:base16_gui00 = "2d2d2d" +let s:gui01 = "393939" +let g:base16_gui01 = "393939" +let s:gui02 = "515151" +let g:base16_gui02 = "515151" +let s:gui03 = "747369" +let g:base16_gui03 = "747369" +let s:gui04 = "a09f93" +let g:base16_gui04 = "a09f93" +let s:gui05 = "d3d0c8" +let g:base16_gui05 = "d3d0c8" +let s:gui06 = "e8e6df" +let g:base16_gui06 = "e8e6df" +let s:gui07 = "f2f0ec" +let g:base16_gui07 = "f2f0ec" +let s:gui08 = "f2777a" +let g:base16_gui08 = "f2777a" +let s:gui09 = "f99157" +let g:base16_gui09 = "f99157" +let s:gui0A = "ffcc66" +let g:base16_gui0A = "ffcc66" +let s:gui0B = "99cc99" +let g:base16_gui0B = "99cc99" +let s:gui0C = "66cccc" +let g:base16_gui0C = "66cccc" +let s:gui0D = "6699cc" +let g:base16_gui0D = "6699cc" +let s:gui0E = "cc99cc" +let g:base16_gui0E = "cc99cc" +let s:gui0F = "d27b53" +let g:base16_gui0F = "d27b53" + +" Terminal color definitions +let s:cterm00 = "00" +let g:base16_cterm00 = "00" +let s:cterm03 = "08" +let g:base16_cterm03 = "08" +let s:cterm05 = "07" +let g:base16_cterm05 = "07" +let s:cterm07 = "15" +let g:base16_cterm07 = "15" +let s:cterm08 = "01" +let g:base16_cterm08 = "01" +let s:cterm0A = "03" +let g:base16_cterm0A = "03" +let s:cterm0B = "02" +let g:base16_cterm0B = "02" +let s:cterm0C = "06" +let g:base16_cterm0C = "06" +let s:cterm0D = "04" +let g:base16_cterm0D = "04" +let s:cterm0E = "05" +let g:base16_cterm0E = "05" +if exists("base16colorspace") && base16colorspace == "256" + let s:cterm01 = "18" + let g:base16_cterm01 = "18" + let s:cterm02 = "19" + let g:base16_cterm02 = "19" + let s:cterm04 = "20" + let g:base16_cterm04 = "20" + let s:cterm06 = "21" + let g:base16_cterm06 = "21" + let s:cterm09 = "16" + let g:base16_cterm09 = "16" + let s:cterm0F = "17" + let g:base16_cterm0F = "17" +else + let s:cterm01 = "10" + let g:base16_cterm01 = "10" + let s:cterm02 = "11" + let g:base16_cterm02 = "11" + let s:cterm04 = "12" + let g:base16_cterm04 = "12" + let s:cterm06 = "13" + let g:base16_cterm06 = "13" + let s:cterm09 = "09" + let g:base16_cterm09 = "09" + let s:cterm0F = "14" + let g:base16_cterm0F = "14" +endif + +" Neovim terminal colours +if has("nvim") + let g:terminal_color_0 = "#2d2d2d" + let g:terminal_color_1 = "#f2777a" + let g:terminal_color_2 = "#99cc99" + let g:terminal_color_3 = "#ffcc66" + let g:terminal_color_4 = "#6699cc" + let g:terminal_color_5 = "#cc99cc" + let g:terminal_color_6 = "#66cccc" + let g:terminal_color_7 = "#d3d0c8" + let g:terminal_color_8 = "#747369" + let g:terminal_color_9 = "#f2777a" + let g:terminal_color_10 = "#99cc99" + let g:terminal_color_11 = "#ffcc66" + let g:terminal_color_12 = "#6699cc" + let g:terminal_color_13 = "#cc99cc" + let g:terminal_color_14 = "#66cccc" + let g:terminal_color_15 = "#f2f0ec" + let g:terminal_color_background = g:terminal_color_0 + let g:terminal_color_foreground = g:terminal_color_5 + if &background == "light" + let g:terminal_color_background = g:terminal_color_7 + let g:terminal_color_foreground = g:terminal_color_2 + endif +elseif has("terminal") + let g:terminal_ansi_colors = [ + \ "#2d2d2d", + \ "#f2777a", + \ "#99cc99", + \ "#ffcc66", + \ "#6699cc", + \ "#cc99cc", + \ "#66cccc", + \ "#d3d0c8", + \ "#747369", + \ "#f2777a", + \ "#99cc99", + \ "#ffcc66", + \ "#6699cc", + \ "#cc99cc", + \ "#66cccc", + \ "#f2f0ec", + \ ] +endif + +" Theme setup +hi clear +syntax reset +let g:colors_name = "base16-eighties" + +" Highlighting function +" Optional variables are attributes and guisp +function! g:Base16hi(group, guifg, guibg, ctermfg, ctermbg, ...) + let l:attr = get(a:, 1, "") + let l:guisp = get(a:, 2, "") + + if a:guifg != "" + exec "hi " . a:group . " guifg=#" . a:guifg + endif + if a:guibg != "" + exec "hi " . a:group . " guibg=#" . a:guibg + endif + if a:ctermfg != "" + exec "hi " . a:group . " ctermfg=" . a:ctermfg + endif + if a:ctermbg != "" + exec "hi " . a:group . " ctermbg=" . a:ctermbg + endif + if l:attr != "" + exec "hi " . a:group . " gui=" . l:attr . " cterm=" . l:attr + endif + if l:guisp != "" + exec "hi " . a:group . " guisp=#" . l:guisp + endif +endfunction + + +fun hi(group, guifg, guibg, ctermfg, ctermbg, attr, guisp) + call g:Base16hi(a:group, a:guifg, a:guibg, a:ctermfg, a:ctermbg, a:attr, a:guisp) +endfun + +" Vim editor colors +call hi("Normal", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call hi("Bold", "", "", "", "", "bold", "") +call hi("Debug", s:gui08, "", s:cterm08, "", "", "") +call hi("Directory", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Error", s:gui00, s:gui08, s:cterm00, s:cterm08, "", "") +call hi("ErrorMsg", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call hi("Exception", s:gui08, "", s:cterm08, "", "", "") +call hi("FoldColumn", s:gui0C, s:gui01, s:cterm0C, s:cterm01, "", "") +call hi("Folded", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("IncSearch", s:gui01, s:gui09, s:cterm01, s:cterm09, "none", "") +call hi("Italic", "", "", "", "", "none", "") +call hi("Macro", s:gui08, "", s:cterm08, "", "", "") +call hi("MatchParen", "", s:gui03, "", s:cterm03, "", "") +call hi("ModeMsg", s:gui0B, "", s:cterm0B, "", "", "") +call hi("MoreMsg", s:gui0B, "", s:cterm0B, "", "", "") +call hi("Question", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Search", s:gui01, s:gui0A, s:cterm01, s:cterm0A, "", "") +call hi("Substitute", s:gui01, s:gui0A, s:cterm01, s:cterm0A, "none", "") +call hi("SpecialKey", s:gui03, "", s:cterm03, "", "", "") +call hi("TooLong", s:gui08, "", s:cterm08, "", "", "") +call hi("Underlined", s:gui08, "", s:cterm08, "", "", "") +call hi("Visual", "", "", "", "", "", "reverse") +call hi("VisualNOS", s:gui08, "", s:cterm08, "", "", "") +call hi("WarningMsg", s:gui08, "", s:cterm08, "", "", "") +call hi("WildMenu", s:gui08, s:gui0A, s:cterm08, "", "", "") +call hi("Title", s:gui0D, "", s:cterm0D, "", "none", "") +call hi("Conceal", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call hi("Cursor", s:gui00, s:gui05, s:cterm00, s:cterm05, "", "") +call hi("NonText", s:gui03, "", s:cterm03, "", "", "") +call hi("LineNr", "", "", s:cterm03, "", "", "") +call hi("SignColumn", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("StatusLine", s:gui04, s:gui02, s:cterm04, s:cterm02, "none", "") +call hi("StatusLineNC", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("VertSplit", s:gui02, s:gui02, s:cterm02, s:cterm02, "none", "") +call hi("ColorColumn", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorColumn", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorLine", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorLineNr", s:gui04, s:gui01, s:cterm04, s:cterm01, "", "") +call hi("QuickFixLine", "", s:gui01, "", s:cterm01, "none", "") +call hi("PMenu", s:gui05, s:gui01, s:cterm05, s:cterm01, "none", "") +call hi("PMenuSel", s:gui01, s:gui05, s:cterm01, s:cterm05, "", "") +call hi("TabLine", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("TabLineFill", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("TabLineSel", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "none", "") + +" Standard syntax highlighting +call hi("Boolean", s:gui09, "", s:cterm09, "", "", "") +call hi("Character", s:gui08, "", s:cterm08, "", "", "") +call hi("Comment", s:gui03, "", s:cterm03, "", "", "") +call hi("Conditional", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Constant", s:gui09, "", s:cterm09, "", "", "") +call hi("Define", s:gui0E, "", s:cterm0E, "", "none", "") +call hi("Delimiter", s:gui0F, "", s:cterm0F, "", "", "") +call hi("Float", s:gui09, "", s:cterm09, "", "", "") +call hi("Function", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Identifier", s:gui08, "", s:cterm08, "", "none", "") +call hi("Include", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Keyword", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Label", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Number", s:gui09, "", s:cterm09, "", "", "") +call hi("Operator", s:gui05, "", s:cterm05, "", "none", "") +call hi("PreProc", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Repeat", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Special", s:gui0C, "", s:cterm0C, "", "", "") +call hi("SpecialChar", s:gui0F, "", s:cterm0F, "", "", "") +call hi("Statement", s:gui08, "", s:cterm08, "", "", "") +call hi("StorageClass", s:gui0A, "", s:cterm0A, "", "", "") +call hi("String", s:gui0B, "", s:cterm0B, "", "", "") +call hi("Structure", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Tag", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Todo", s:gui0A, s:gui01, s:cterm0A, s:cterm01, "", "") +call hi("Type", s:gui0A, "", s:cterm0A, "", "none", "") +call hi("Typedef", s:gui0A, "", s:cterm0A, "", "", "") + +" C highlighting +call hi("cOperator", s:gui0C, "", s:cterm0C, "", "", "") +call hi("cPreCondit", s:gui0E, "", s:cterm0E, "", "", "") + +" C# highlighting +call hi("csClass", s:gui0A, "", s:cterm0A, "", "", "") +call hi("csAttribute", s:gui0A, "", s:cterm0A, "", "", "") +call hi("csModifier", s:gui0E, "", s:cterm0E, "", "", "") +call hi("csType", s:gui08, "", s:cterm08, "", "", "") +call hi("csUnspecifiedStatement", s:gui0D, "", s:cterm0D, "", "", "") +call hi("csContextualStatement", s:gui0E, "", s:cterm0E, "", "", "") +call hi("csNewDecleration", s:gui08, "", s:cterm08, "", "", "") + +" CSS highlighting +call hi("cssBraces", s:gui05, "", s:cterm05, "", "", "") +call hi("cssClassName", s:gui0E, "", s:cterm0E, "", "", "") +call hi("cssColor", s:gui0C, "", s:cterm0C, "", "", "") + +" Diff highlighting +call hi("DiffAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("DiffChange", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("DiffDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call hi("DiffText", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("DiffAdded", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call hi("DiffFile", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call hi("DiffNewFile", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call hi("DiffLine", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call hi("DiffRemoved", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") + +" Git highlighting +call hi("gitcommitOverflow", s:gui08, "", s:cterm08, "", "", "") +call hi("gitcommitSummary", s:gui0B, "", s:cterm0B, "", "", "") +call hi("gitcommitComment", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitUntracked", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitDiscarded", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitSelected", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitHeader", s:gui0E, "", s:cterm0E, "", "", "") +call hi("gitcommitSelectedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitUnmergedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitDiscardedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitBranch", s:gui09, "", s:cterm09, "", "bold", "") +call hi("gitcommitUntrackedFile", s:gui0A, "", s:cterm0A, "", "", "") +call hi("gitcommitUnmergedFile", s:gui08, "", s:cterm08, "", "bold", "") +call hi("gitcommitDiscardedFile", s:gui08, "", s:cterm08, "", "bold", "") +call hi("gitcommitSelectedFile", s:gui0B, "", s:cterm0B, "", "bold", "") + +" GitGutter highlighting +call hi("GitGutterAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("GitGutterChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("GitGutterDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call hi("GitGutterChangeDelete", s:gui0E, s:gui01, s:cterm0E, s:cterm01, "", "") + +" HTML highlighting +call hi("htmlBold", s:gui0A, "", s:cterm0A, "", "", "") +call hi("htmlItalic", s:gui0E, "", s:cterm0E, "", "", "") +call hi("htmlEndTag", s:gui05, "", s:cterm05, "", "", "") +call hi("htmlTag", s:gui05, "", s:cterm05, "", "", "") + +" JavaScript highlighting +call hi("javaScript", s:gui05, "", s:cterm05, "", "", "") +call hi("javaScriptBraces", s:gui05, "", s:cterm05, "", "", "") +call hi("javaScriptNumber", s:gui09, "", s:cterm09, "", "", "") +" pangloss/vim-javascript highlighting +call hi("jsOperator", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsStatement", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsReturn", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsThis", s:gui08, "", s:cterm08, "", "", "") +call hi("jsClassDefinition", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsFunction", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsFuncCall", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsClassFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsClassMethodType", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsRegexpString", s:gui0C, "", s:cterm0C, "", "", "") +call hi("jsGlobalObjects", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsGlobalNodeObjects", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsExceptions", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsBuiltins", s:gui0A, "", s:cterm0A, "", "", "") + +" Mail highlighting +call hi("mailQuoted1", s:gui0A, "", s:cterm0A, "", "", "") +call hi("mailQuoted2", s:gui0B, "", s:cterm0B, "", "", "") +call hi("mailQuoted3", s:gui0E, "", s:cterm0E, "", "", "") +call hi("mailQuoted4", s:gui0C, "", s:cterm0C, "", "", "") +call hi("mailQuoted5", s:gui0D, "", s:cterm0D, "", "", "") +call hi("mailQuoted6", s:gui0A, "", s:cterm0A, "", "", "") +call hi("mailURL", s:gui0D, "", s:cterm0D, "", "", "") +call hi("mailEmail", s:gui0D, "", s:cterm0D, "", "", "") + +" Markdown highlighting +call hi("markdownCode", s:gui0B, "", s:cterm0B, "", "", "") +call hi("markdownError", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call hi("markdownCodeBlock", s:gui0B, "", s:cterm0B, "", "", "") +call hi("markdownHeadingDelimiter", s:gui0D, "", s:cterm0D, "", "", "") + +" NERDTree highlighting +call hi("NERDTreeDirSlash", s:gui0D, "", s:cterm0D, "", "", "") +call hi("NERDTreeExecFile", s:gui05, "", s:cterm05, "", "", "") + +" PHP highlighting +call hi("phpMemberSelector", s:gui05, "", s:cterm05, "", "", "") +call hi("phpComparison", s:gui05, "", s:cterm05, "", "", "") +call hi("phpParent", s:gui05, "", s:cterm05, "", "", "") +call hi("phpMethodsVar", s:gui0C, "", s:cterm0C, "", "", "") + +" Python highlighting +call hi("pythonOperator", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonRepeat", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonInclude", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonStatement", s:gui0E, "", s:cterm0E, "", "", "") + +" Ruby highlighting +call hi("rubyAttribute", s:gui0D, "", s:cterm0D, "", "", "") +call hi("rubyConstant", s:gui0A, "", s:cterm0A, "", "", "") +call hi("rubyInterpolationDelimiter", s:gui0F, "", s:cterm0F, "", "", "") +call hi("rubyRegexp", s:gui0C, "", s:cterm0C, "", "", "") +call hi("rubySymbol", s:gui0B, "", s:cterm0B, "", "", "") +call hi("rubyStringDelimiter", s:gui0B, "", s:cterm0B, "", "", "") + +" SASS highlighting +call hi("sassidChar", s:gui08, "", s:cterm08, "", "", "") +call hi("sassClassChar", s:gui09, "", s:cterm09, "", "", "") +call hi("sassInclude", s:gui0E, "", s:cterm0E, "", "", "") +call hi("sassMixing", s:gui0E, "", s:cterm0E, "", "", "") +call hi("sassMixinName", s:gui0D, "", s:cterm0D, "", "", "") + +" Signify highlighting +call hi("SignifySignAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("SignifySignChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("SignifySignDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") + +" Spelling highlighting +call hi("SpellBad", "", "", "", "", "undercurl", s:gui08) +call hi("SpellLocal", "", "", "", "", "undercurl", s:gui0C) +call hi("SpellCap", "", "", "", "", "undercurl", s:gui0D) +call hi("SpellRare", "", "", "", "", "undercurl", s:gui0E) + +" Startify highlighting +call hi("StartifyBracket", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifyFile", s:gui07, "", s:cterm07, "", "", "") +call hi("StartifyFooter", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifyHeader", s:gui0B, "", s:cterm0B, "", "", "") +call hi("StartifyNumber", s:gui09, "", s:cterm09, "", "", "") +call hi("StartifyPath", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifySection", s:gui0E, "", s:cterm0E, "", "", "") +call hi("StartifySelect", s:gui0C, "", s:cterm0C, "", "", "") +call hi("StartifySlash", s:gui03, "", s:cterm03, "", "", "") +call hi("StartifySpecial", s:gui03, "", s:cterm03, "", "", "") + +" Java highlighting +call hi("javaOperator", s:gui0D, "", s:cterm0D, "", "", "") + +" Remove functions +delf hi + +" Remove color variables +unlet s:gui00 s:gui01 s:gui02 s:gui03 s:gui04 s:gui05 s:gui06 s:gui07 s:gui08 s:gui09 s:gui0A s:gui0B s:gui0C s:gui0D s:gui0E s:gui0F +unlet s:cterm00 s:cterm01 s:cterm02 s:cterm03 s:cterm04 s:cterm05 s:cterm06 s:cterm07 s:cterm08 s:cterm09 s:cterm0A s:cterm0B s:cterm0C s:cterm0D s:cterm0E s:cterm0F diff --git a/.config/pipe-viewer/pipe-viewer.conf b/.config/pipe-viewer/pipe-viewer.conf new file mode 100644 index 0000000..9cce18c --- /dev/null +++ b/.config/pipe-viewer/pipe-viewer.conf @@ -0,0 +1,118 @@ +#!/usr/bin/perl + +# CLI Pipe Viewer 0.2.2 - configuration file + +our $CONFIG = { + api_host => "auto", + auto_captions => 0, + autoplay_mode => 0, + bypass_age_gate_with_proxy => 0, + cache_dir => "$ENV{HOME}/.cache/pipe-viewer", + colors => 1, + comments_order => "top", + confirm => 0, + convert_cmd => "ffmpeg -i *IN* *OUT*", + convert_to => undef, + cookie_file => undef, + copy_caption => 0, + custom_channel_layout_format => [ + { align => "right", color => "white", text => "*NO*.", width => 3 }, + { align => "left", color => "blue", text => "*AUTHOR*", width => "45%" }, + { align => "right", color => "magenta", text => "*VIDEOS* vids", width => 14 }, + { + align => "right", + color => "green", + text => "*SUBS_SHORT* subs", + width => 10, + }, + ], + custom_layout_format => [ + { align => "right", color => "white", text => "*NO*.", width => 3 }, + { align => "left", color => "blue", text => "*TITLE*", width => "45%" }, + { align => "right", color => "magenta", text => "*AUTHOR*", width => 15 }, + { align => "right", color => "yellow", text => "*VIEWS_SHORT*", width => 5 }, + { align => "right", color => "green", text => "*TIME*", width => 8 }, + ], + custom_playlist_layout_format => [ + { align => "right", color => "white", text => "*NO*.", width => 3 }, + { align => "left", color => "blue", text => "*TITLE*", width => "45%" }, + { align => "right", color => "green", text => "*ITEMS* videos", width => 14 }, + { align => "left", color => "magenta", text => "*AUTHOR*", width => 15 }, + ], + dash => 1, + date => undef, + debug => 0, + download_and_play => 0, + download_with_wget => 0, + download_with_ytdl => 1, + downloads_dir => "$ENV{HOME}/downloads", + env_proxy => 1, + fat32safe => 0, + ffmpeg_cmd => "ffmpeg", + force_fallback => 0, + fullscreen => 0, + get_captions => 0, + get_term_width => 1, + hfr => 1, + highlight_color => "white", + highlight_watched => 1, + history => 1, + history_file => "$ENV{HOME}/.cache/pipe-viewer/cli-history", + history_limit => 100000, + http_proxy => undef, + ignore_av1 => 0, + ignored_projections => [], + interactive => 1, + keep_original_video => 0, + local_playlist_limit => -1, + maxResults => 25, + merge_into_mkv => 1, + merge_into_mkv_args => "-loglevel warning -c:s srt -c:v copy -c:a copy -disposition:s forced", + merge_with_captions => 1, + order => "relevance", + page => 1, + prefer_av1 => 0, + prefer_invidious => 0, + prefer_m4a => 0, + prefer_mp4 => 0, + region => undef, + remove_played_file => 0, + resolution => "720p", + saved_channels_file => "$ENV{HOME}/.cache/pipe-viewer/users", + show_video_info => 0, + skip_if_exists => 1, + skip_watched => 0, + split_videos => 1, + srt_languages => ["en", "ru"], + subscribed_channels_file => "$ENV{HOME}/.cache/pipe-viewer/subscribed_channels.txt", + subscriptions_lifetime => 600, + subscriptions_limit => 10000, + thousand_separator => ",", + timeout => undef, + user_agent => undef, + video_filename_format => "*FTITLE* - *ID*.*FORMAT*", + video_player_selected => "mpv", + video_players => { + mpv => { + arg => "--really-quiet --force-media-title=*TITLE* *URL*", + cmd => "mpv", + fs => "--fullscreen", + novideo => "--no-video", + srt => "--sub-file=*SUB*", + }, + }, + videoCaption => undef, + videoDefinition => undef, + videoDimension => undef, + videoDuration => undef, + videoLicense => undef, + watch_history => 1, + watch_history_file => "$ENV{HOME}/.cache/pipe-viewer/watched", + wget_cmd => "wget", + youtube_video_url => "https://www.youtube.com/watch?v=%s", + ytdl => 1, + ytdl_cmd => "yt-dlp", + ytdlp_comments => 1, + ytdlp_max_comments => 20, + ytdlp_max_replies => 3, +} diff --git a/.config/qutebrowser/config.py b/.config/qutebrowser/config.py new file mode 100644 index 0000000..7a50bf7 --- /dev/null +++ b/.config/qutebrowser/config.py @@ -0,0 +1,60 @@ +# Binds +config.bind('po', 'spawn linkhandler {url}') +config.bind('pd', 'spawn dm-handler {url}') +config.bind('yo', 'hint links spawn linkhandler {hint-url}') +config.bind('yd', 'hint links spawn dm-handler {hint-url}') + +# Search engines +c.url.searchengines = {'DEFAULT': 'https://paulgo.io/search?q={}', + 'w': 'https://en.wikipedia.org/w/index.php?search={}', + 'y': 'https://yewtu.be/search?q={}', + 'gh': 'https://github.com/search?q={}', + 'md': 'https://reelgood.com/search?q={}', + 'rtk': 'https://rutracker.org/forum/tracker.php?nm={}', + 'rep': 'https://repology.org/projects/?search={}', + 'trans': 'https://lingva.pussthecat.org/en/uk/{}' + } + +c.confirm_quit = ['downloads'] +c.content.geolocation = False +c.content.mouse_lock = False +c.content.notifications.enabled = False +c.content.blocking.enabled = True +c.downloads.location.directory = "$XDG_DOWNLOAD_DIR" +c.downloads.location.prompt = False +c.downloads.remove_finished = 500 +c.tabs.background = True +c.url.start_pages = ['about:blank'] +c.url.default_page = 'about:blank' + +# Colors +c.colors.completion.odd.bg = "#222222" +c.colors.completion.even.bg = "#222222" +c.colors.completion.category.bg = "#222222" +c.colors.completion.category.fg = "#ffcc66" +c.colors.completion.category.border.top = "#222222" +c.colors.completion.category.border.bottom = "#222222" +c.colors.statusbar.normal.bg = "#222222" +c.colors.statusbar.command.bg = "#222222" +c.colors.statusbar.url.success.https.fg = "white" +c.colors.tabs.even.fg = "#888" +c.colors.tabs.even.bg = "#002A3B" +c.colors.tabs.odd.fg = "#888" +c.colors.tabs.odd.bg = "#002A3B" +c.colors.tabs.selected.odd.bg = "#005577" +c.colors.tabs.selected.even.bg = "#005577" +c.colors.messages.error.fg = c.colors.statusbar.normal.fg +c.colors.messages.warning.fg = c.colors.statusbar.normal.fg +c.colors.prompts.fg = c.colors.statusbar.normal.fg +c.colors.webpage.preferred_color_scheme = 'dark' + +# UI +c.fonts.default_family = "monospace" +c.fonts.default_size = "8pt" +c.tabs.padding = {"bottom": 1, "left": 5, "right": 5, "top": 1} +c.tabs.favicons.scale = 0.9 +c.completion.cmd_history_max_items = 10 +c.completion.height = "30%" +c.completion.scrollbar.width = 12 + +config.load_autoconfig(False) diff --git a/.config/qutebrowser/quickmarks b/.config/qutebrowser/quickmarks new file mode 100644 index 0000000..d58f6fc --- /dev/null +++ b/.config/qutebrowser/quickmarks @@ -0,0 +1,15 @@ +t web.telegram.org/k/ +s steamcommunity.com +w ru.wikipedia.org +m miped.ru/f +y yewtu.be +gh github.com +ap gitlab.alpinelinux.org/alpine/aports +cs teachyourselfcs.com +ms missing.csail.mit.edu +md reelgood.com/movies +ep englishpage.com +dm market.dota2.net/sell +gbe gobyexample.com +lrn learnxinyminutes.com +rtk rutracker.org/forum/index.php diff --git a/.config/shell/aliases b/.config/shell/aliases new file mode 100644 index 0000000..b5f4828 --- /dev/null +++ b/.config/shell/aliases @@ -0,0 +1,33 @@ +#!/bin/sh + +alias f="$FILE" \ +v="$EDITOR" \ +z="zathura" \ +cp="cp -i" \ +mv="mv -i" \ +rm="rm -i" \ +yt="pipe-viewer" \ +mkd="mkdir -p" \ +trans="trans -j -v :en" \ +ls="ls -h --group-directories-first" \ +dots="git --git-dir=$XDG_DOCUMENTS_DIR/dots --work-tree=$HOME" \ +h="cd $HOME && ls" \ +d="cd $XDG_DOWNLOAD_DIR && ls" \ +m="cd $XDG_MUSIC_DIR && ls" \ +dc="cd $XDG_DOCUMENTS_DIR && ls" \ +cf="cd $XDG_CONFIG_HOME && ls" \ +gs="cd $GOPATH/src && ls" \ +shr="cd $XDG_DATA_HOME && ls" \ +sc="cd ~/.local/bin && ls" \ +ap="cd $XDG_DOCUMENTS_DIR/code/aports && ls" \ +ab="cd $XDG_DOCUMENTS_DIR/code/abuilds && ls" \ +cfn="$EDITOR $XDG_CONFIG_HOME/newsboat/config" \ +cfz="$EDITOR $XDG_CONFIG_HOME/zsh/.zshrc" \ +cfp="$EDITOR $XDG_CONFIG_HOME/zsh/.zprofile" \ +cfq="$EDITOR $XDG_CONFIG_HOME/qutebrowser/config.py" \ +cfu="$EDITOR $XDG_CONFIG_HOME/newsboat/urls" \ +cfv="$EDITOR $XDG_CONFIG_HOME/nvim/init.lua" + +for command in apk rc rc-service rc-update mount umount poweroff reboot ; do + alias $command="doas $command" +done; unset command diff --git a/.config/shell/inputrc b/.config/shell/inputrc new file mode 100644 index 0000000..5cfcbaa --- /dev/null +++ b/.config/shell/inputrc @@ -0,0 +1,22 @@ +$include /etc/inputrc +set editing-mode vi +set show-all-if-ambiguous on +set echo-control-characters off + +$if mode=vi + +set show-mode-in-prompt on +set vi-ins-mode-string \1\e[6 q\2 +set vi-cmd-mode-string \1\e[2 q\2 + +set keymap vi-command +# these are for vi-command mode +Control-l: clear-screen +Control-a: beginning-of-line + +set keymap vi-insert +# these are for vi-insert mode +Control-l: clear-screen +Control-a: beginning-of-line + +$endif diff --git a/.config/sxiv/exec/key-handler b/.config/sxiv/exec/key-handler new file mode 100755 index 0000000..253eabb --- /dev/null +++ b/.config/sxiv/exec/key-handler @@ -0,0 +1,35 @@ +#!/bin/sh +while read file +do + case "$1" in + "w") xwallpaper --zoom "$file" & ;; + "c") + [ -z "$destdir" ] && destdir="$(sed "s/\s.*#.*$//;/^\s*$/d" ${XDG_CONFIG_HOME:-$HOME/.config}/directories | awk '{print $2}' | dmenu -l 20 -i -p "Copy file(s) to where?" | sed "s|~|$HOME|g")" + [ -z "$destdir" ] && exit + [ ! -d "$destdir" ] && notify-send "$destdir is not a directory, cancelled." && exit + cp "$file" "$destdir" && notify-send -i "$(readlink -f "$file")" "$file copied to $destdir." & + ;; + "m") + [ -z "$destdir" ] && destdir="$(sed "s/\s.*#.*$//;/^\s*$/d" ${XDG_CONFIG_HOME:-$HOME/.config}/directories | awk '{print $2}' | dmenu -l 20 -i -p "Move file(s) to where?" | sed "s|~|$HOME|g")" + [ -z "$destdir" ] && exit + [ ! -d "$destdir" ] && notify-send "$destdir is not a directory, cancelled." && exit + mv "$file" "$destdir" && notify-send -i "$(readlink -f "$file")" "$file moved to $destdir." & + ;; + "r") + convert -rotate 90 "$file" "$file" ;; + "R") + convert -rotate -90 "$file" "$file" ;; + "f") + convert -flop "$file" "$file" ;; + "y") + echo "$file" | tr -d '\n' | xclip -selection clipboard && + notify-send "$file copied to clipboard" & ;; + "Y") + readlink -f "$file" | tr -d '\n' | xclip -selection clipboard && + notify-send "$(readlink -f "$file") copied to clipboard" & ;; + "d") + [ "$(printf "No\\nYes" | dmenu -i -p "Really delete $file?")" = "Yes" ] && rm "$file" && notify-send "$file deleted." ;; + "g") ifinstalled gimp && setsid -f gimp "$file" ;; + "i") notify-send "File information" "$(mediainfo --Output=HTML "$file")" ;; + esac +done diff --git a/.config/transmission-daemon/settings.json b/.config/transmission-daemon/settings.json new file mode 100644 index 0000000..017acb0 --- /dev/null +++ b/.config/transmission-daemon/settings.json @@ -0,0 +1,68 @@ +{ + "alt-speed-down": 0, + "alt-speed-enabled": false, + "alt-speed-time-begin": 540, + "alt-speed-time-day": 127, + "alt-speed-time-enabled": false, + "alt-speed-time-end": 1020, + "alt-speed-up": 50, + "bind-address-ipv4": "0.0.0.0", + "bind-address-ipv6": "::", + "blocklist-enabled": false, + "blocklist-url": "http://www.example.com/blocklist", + "cache-size-mb": 4, + "dht-enabled": true, + "download-dir": "/home/dmitz/downloads", + "download-queue-enabled": true, + "download-queue-size": 5, + "encryption": 1, + "idle-seeding-limit": 30, + "idle-seeding-limit-enabled": false, + "incomplete-dir": "", + "incomplete-dir-enabled": false, + "lpd-enabled": false, + "message-level": 2, + "peer-congestion-algorithm": "", + "peer-id-ttl-hours": 6, + "peer-limit-global": 200, + "peer-limit-per-torrent": 50, + "peer-port": 51413, + "peer-port-random-high": 65535, + "peer-port-random-low": 49152, + "peer-port-random-on-start": false, + "peer-socket-tos": "default", + "pex-enabled": true, + "port-forwarding-enabled": true, + "preallocation": 1, + "prefetch-enabled": true, + "queue-stalled-enabled": true, + "queue-stalled-minutes": 30, + "ratio-limit": 2, + "ratio-limit-enabled": false, + "rename-partial-files": true, + "rpc-authentication-required": false, + "rpc-bind-address": "0.0.0.0", + "rpc-enabled": true, + "rpc-host-whitelist": "", + "rpc-host-whitelist-enabled": true, + "rpc-password": "{0f6ad2424677cac9104f38499f79819bca2ab45ftzDtZncJ", + "rpc-port": 9091, + "rpc-url": "/transmission/", + "rpc-username": "", + "rpc-whitelist": "127.0.0.1", + "rpc-whitelist-enabled": true, + "scrape-paused-torrents-enabled": true, + "script-torrent-done-enabled": true, + "script-torrent-done-filename": "/home/dmitz/.local/bin/torwrap", + "seed-queue-enabled": false, + "seed-queue-size": 10, + "speed-limit-down": 100, + "speed-limit-down-enabled": false, + "speed-limit-up": 100, + "speed-limit-up-enabled": false, + "start-added-torrents": true, + "trash-original-torrent-files": false, + "umask": 18, + "upload-slots-per-torrent": 14, + "utp-enabled": true +} diff --git a/.config/tremc/settings.cfg b/.config/tremc/settings.cfg new file mode 100644 index 0000000..c3af446 --- /dev/null +++ b/.config/tremc/settings.cfg @@ -0,0 +1,106 @@ +[Connection] +password = +username = +port = 9091 +host = localhost +path = /transmission/rpc +ssl = False + +[Sorting] +# Set startup torrent list sort order. Possible sort keys are: +# name, addedDate, percentDone, seeders, leechers, sizeWhenDone, status, +# uploadedEver, rateUpload, rateDownload, uploadRatio, peersConnected, +# downloadDir, mainTrackerDomain. +# Prepend ':' for reversed sort. +# Examples: +# +# order = :name +# Sorts by torrent name in reversed alphabetical order. +# +# order = sizeWhenDone +# Sorts by torrent size, small to large. +order = name + +[Filtering] +# Set startup torrent list filter. Possible filter keys are: +# uploading, downloading, active, paused, seeding, incomplete, verifying, +# private, isolated, selected, honors. +# Use 'invert=True' to shoe only torrents not matching filter. +filter = +invert = False + +[Misc] +lines_per_torrent = 3 +torrentname_is_progressbar = True +file_viewer = xdg-open %%s +file_open_in_terminal = True +view_selected = False +rdns = True +geoip_database = /xyz +torrent_numbers = False + +[Colors] +# Set colors of various interface elements. +# Each element has background and foreground color. +# Each color is default or one of the eight curses colors: +# Black, White, Red, Green, Blue, Cyan, Yellow, Magenta. +# Default is the default background or foreground color. +header = bg:white,fg:black +footer = bg:white,fg:black +title_seed = bg:green,fg:black +title_incomplete = bg:white,fg:black +title_download = bg:blue,fg:black +title_idle = bg:black,fg:cyan +title_verify = bg:black,fg:magenta +title_paused = bg:default,fg:black +title_error = bg:red,fg:default +download_rate = bg:black,fg:blue +upload_rate = bg:black,fg:red +eta+ratio = bg:black,fg:white +filter_status = bg:white,fg:black +multi_filter_status = bg:default,fg:blue +dialog = bg:black,fg:white +dialog_important = bg:black,fg:red +file_prio_high = bg:black,fg:red +file_prio_normal = bg:black,fg:default +file_prio_low = bg:black,fg:yellow +file_prio_off = bg:black,fg:blue + +[Profiles] +# Define filter/sort profiles. See README.md for details. +# Examples: +# +# profile1 = regex#=ubuntu#=:uploadRatio +# A profile named '1' shows only torrents whose name contains ubuntu (case +# insensitive match), sorted by upload ratio from large to small. +# This profile can be selected from the profile menu or by pressing '1'. +# +# profile2 = incomplete#=#=percentDone +# A profile named '2' shows incomplete torrents sorted by progress. +# +# profileABC = regex#=ubuntu#=:incomplete#= #& # location#=/torrents#=peersConnected +# A profile named 'ABC' shows only torrents that satisfy one of the +# conditions: +# 1. Name contains ubuntu and complete; +# 2. Download location is /torrents. +# The torrent list is sorted by number of peers connected. +# This profile can be selected from the profile menu. + +# Show all torrents, sort by name: +profile0 = + + +[ListKeys] +# Configure keys in torrent list only. +backslash = select_search_torrent_fulltext +gt = select_search_torrent_regex_fulltext +y = toggle_torrent_numbers + +[DetailsKeys] +# Configure keys in torrent details only. +y = view_file + +[CommonKeys] +# Configure keys globally. +Y = verify_torrent +v = move_torrent diff --git a/.config/urlscan/config.json b/.config/urlscan/config.json new file mode 100644 index 0000000..e975656 --- /dev/null +++ b/.config/urlscan/config.json @@ -0,0 +1,71 @@ +{ + "palettes": { + "default": [ + [ + "footer", + "white", + "black" + ], + [ + "search", + "white", + "" + ], + [ + "msgtext:ellipses", + "light gray", + "black" + ], + [ + "urlref:number:braces", + "dark magenta", + "" + ], + [ + "urlref:number", + "dark magenta", + "" + ], + [ + "urlref:url", + "dark blue", + "default" + ], + [ + "url:sel", + "yellow", + "default" + ] + ] + }, + "keys": { + "/": "search_key", + "0": "digits", + "1": "digits", + "2": "digits", + "3": "digits", + "4": "digits", + "5": "digits", + "6": "digits", + "7": "digits", + "8": "digits", + "9": "digits", + "y": "clipboard", + "c": "context", + "ctrl l": "clear_screen", + "?": "help_menu", + "G": "bottom", + "g": "top", + "j": "down", + "k": "up", + "P": "clipboard_pri", + "l": "link_handler", + "p": "palette", + "Q": "quit", + "q": "quit", + "R": "reverse", + "S": "all_shorten", + "s": "shorten", + "u": "all_escape" + } +} diff --git a/.config/vifm/colors/eighties.vifm b/.config/vifm/colors/eighties.vifm new file mode 100644 index 0000000..57f5718 --- /dev/null +++ b/.config/vifm/colors/eighties.vifm @@ -0,0 +1,24 @@ +highlight clear +highlight Win cterm=none ctermfg=white ctermbg=default +highlight Directory cterm=none ctermfg=blue ctermbg=default +highlight Link cterm=bold ctermfg=default ctermbg=default +highlight BrokenLink cterm=bold ctermfg=red ctermbg=default +highlight Socket cterm=bold ctermfg=blue ctermbg=default +highlight Device cterm=bold ctermfg=red ctermbg=default +highlight Fifo cterm=bold ctermfg=cyan ctermbg=default +highlight Executable cterm=bold ctermfg=green ctermbg=default +highlight Selected cterm=bold ctermfg=yellow ctermbg=default +highlight CurrLine cterm=reverse ctermfg=black ctermbg=yellow +highlight TopLine cterm=bold ctermfg=white ctermbg=black +highlight TopLineSel cterm=bold ctermfg=white ctermbg=default +highlight StatusLine cterm=bold ctermfg=white ctermbg=black +highlight WildMenu cterm=underline,reverse ctermfg=white ctermbg=black +highlight CmdLine cterm=none ctermfg=white ctermbg=default +highlight ErrorMsg cterm=none ctermfg=red ctermbg=black +highlight Border cterm=none ctermfg=white ctermbg=black +highlight JobLine cterm=bold,reverse ctermfg=black ctermbg=white +highlight SuggestBox cterm=bold ctermfg=default ctermbg=default +highlight CmpMismatch cterm=bold ctermfg=white ctermbg=red +highlight AuxWin cterm=bold,underline,reverse,standout,italic ctermfg=default ctermbg=default +highlight TabLine cterm=none ctermfg=white ctermbg=black +highlight TabLineSel cterm=bold,reverse ctermfg=default ctermbg=default diff --git a/.config/vifm/vifmrc b/.config/vifm/vifmrc new file mode 100644 index 0000000..7992f76 --- /dev/null +++ b/.config/vifm/vifmrc @@ -0,0 +1,69 @@ +" vim: filetype=vifm +source ~/.config/vifm/shortcuts + +set vicmd=$EDITOR +set syscalls +set nofollowlinks +set sortnumbers +set undolevels=100 +set wildmenu +set wildstyle=popup +set scrolloff=4 +set ignorecase +set smartcase +set nohlsearch +set incsearch +set suggestoptions=normal,visual,view,otherpane,keys,marks,registers +colorscheme eighties + +map h +map j +map k +map l +map o +map s +map v + +map R :restart +map x :!sxiv -ft * 2>/dev/null & +nnoremap o :file & +map E :!$EDITOR %f +map mkd :mkdir +map X :!aunpack %f & +nnoremap s :shell +nnoremap w :view +vnoremap w :viewgv +nnoremap yd :!echo %d | xclip %i +nnoremap yf :!echo %c:p | xclip %i +nnoremap I cw +nnoremap cc cw +nnoremap A cw +nnoremap ,w :set wrap! +nmap tj +nmap q ZQ + +fileviewer *.html elinks -dump %c +filextype *.html,*.htm $BROWSER %f 2>/dev/null & + +fileviewer *.docx docx2txt %c - +fileviewer *.odt odt2txt %c - + +filetype *.csv,*.xlsx sc-im %c +fileviewer *.csv sed "s/,,,,/,,-,,/g;s/,,/ /g" %c | column -t | sed "s/ - / /g" | cut -c -%pw + +filetype *.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus mpv --no-audio-display --input-ipc-server=/tmp/mpvsoc$(date +%%s) %c +filextype *.pdf,*.ps,*.eps,*.ps.gz,*.djvu,*.epub zathura %f 2>/dev/null &, +fileviewer *.pdf pdftotext -l 1 -nopgbrk %c - +fileviewer *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.qt,*.divx,*.as[fx],*mp3,*.flac mediainfo +filextype *.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,*.as[fx] mpv --input-ipc-server=/tmp/mpvsoc$(date +%%s) %f 2>/dev/null &, + +fileview *.zip,*.rar,*.tar.gz atool -l %f +filetype *.zip,*.rar,*.tar.gz,*.iso,*.xz,*.tar,*.tgz aunpack %f + +fileviewer *.[1-8] man ./%c | col -b +filetype *.[1-8] man ./%c + +fileviewer *.jpg,*.jpeg,*.png,*.ico vifmimg draw %px %py %pw %ph %c %pc vifmimg clear +filextype *.bmp,*.jpg,*.jpeg,*.png,*.ico,*.gif,*.xpm rotdir %f 2>/dev/null | sxiv -ia 2>/dev/null & + +set vifminfo=dhistory,chistory,tui,shistory,phistory,fhistory,dirstack,registers,bookmarks,bmarks diff --git a/.config/wall.jpg b/.config/wall.jpg new file mode 100644 index 0000000..01c881d Binary files /dev/null and b/.config/wall.jpg differ diff --git a/.config/x11/xinitrc b/.config/x11/xinitrc new file mode 100644 index 0000000..09474dd --- /dev/null +++ b/.config/x11/xinitrc @@ -0,0 +1,5 @@ +#!/bin/sh + +. "$XDG_CONFIG_HOME/x11/xprofile" + +ssh-agent dwm diff --git a/.config/x11/xprofile b/.config/x11/xprofile new file mode 100644 index 0000000..9346159 --- /dev/null +++ b/.config/x11/xprofile @@ -0,0 +1,17 @@ +#!/bin/sh + +# Keyboard layout +setxkbmap -layout us,ru,ua -option grp:ctrl_shift_toggle -variant altgr-intl + +# Start on launch +remaps & +xrandr --dpi 96 +gpg-agent --daemon +xwallpaper --zoom $XDG_CONFIG_HOME/wall.jpg + +autostart="mpd dunst unclutter-xfixes pipewire" + +for program in $autostart; do + pidof -s "$program" || setsid -f "$program" + +done >/dev/null 2>&1 diff --git a/.config/yt-dlp/config b/.config/yt-dlp/config new file mode 100644 index 0000000..b59b9a4 --- /dev/null +++ b/.config/yt-dlp/config @@ -0,0 +1,5 @@ +-o $XDG_DOWNLOAD_DIR/%(title)s.%(ext)s +-f bestvideo[height<=?720]+bestaudio/best +--write-subs +--sub-format "srt" +--sub-langs "en" diff --git a/.config/zathura/zathurarc b/.config/zathura/zathurarc new file mode 100644 index 0000000..452e116 --- /dev/null +++ b/.config/zathura/zathurarc @@ -0,0 +1,15 @@ +set sandbox none +set statusbar-h-padding 0 +set statusbar-v-padding 0 +set page-padding 1 +set selection-clipboard clipboard +map u scroll half-up +map d scroll half-down +map D toggle_page_mode +map r reload +map R rotate +map K zoom in +map J zoom out +map i recolor +map p print +map g goto top diff --git a/.config/zsh/.zprofile b/.config/zsh/.zprofile new file mode 100644 index 0000000..127a71c --- /dev/null +++ b/.config/zsh/.zprofile @@ -0,0 +1,43 @@ +#!/bin/zsh + +# Adds `~/.local/bin` to $PATH +export PATH="$PATH:$(du "$HOME/.local/bin" | cut -f2 | tr '\n' ':' | sed 's/:*$//')" + +unsetopt PROMPT_SP + +export EDITOR="nvim" +export TERMINAL="st" +export FILE="vifm" +export BROWSER="qutebrowser" +export READER="zathura" +export XDG_DOWNLOAD_DIR="$HOME/downloads" +export XDG_DOCUMENTS_DIR="$HOME/documents" +export XDG_MUSIC_DIR="$HOME/music" +export XDG_CONFIG_HOME="$HOME/.config" +export XDG_CACHE_HOME="$HOME/.cache" +export XDG_DATA_HOME="$HOME/.local/share" +export ZDOTDIR="$XDG_CONFIG_HOME/zsh" +export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc-2.0" +export GOPATH="$XDG_DOCUMENTS_DIR/code/go" +export GOBIN="$HOME/.local/bin" +export INPUTRC="$XDG_CONFIG_HOME/shell/inputrc" +export ELINKS_CONFDIR="$XDG_CONFIG_HOME/elinks" +export PASSWORD_STORE_DIR="$XDG_DATA_HOME/password-store" +export XAUTHORITY="$XDG_CONFIG_HOME/x11/xauthority" +export XINITRC="$XDG_CONFIG_HOME/x11/xinitrc" +export FZF_DEFAULT_OPTS="--layout=reverse --height 40%" +export GNUPGHOME="$XDG_DATA_HOME/gnupg" +export PASSWORD_STORE_DIR="$XDG_DATA_HOME/password-store" +export WINEPREFIX="$XDG_DATA_HOME/wineprefixes/default" +export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch/notmuchrc" +export LESS=-R +export LESS_TERMCAP_mb="$(printf '%b' '')" +export LESS_TERMCAP_md="$(printf '%b' '')" +export LESS_TERMCAP_me="$(printf '%b' '')" +export LESS_TERMCAP_so="$(printf '%b' '')" +export LESS_TERMCAP_se="$(printf '%b' '')" +export LESS_TERMCAP_us="$(printf '%b' '')" +export LESS_TERMCAP_ue="$(printf '%b' '')" +export LESSHISTFILE="-" + +[ "$(tty)" = "/dev/tty1" ] && ! pidof -s Xorg >/dev/null 2>&1 && exec startx "$XINITRC" diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc new file mode 100644 index 0000000..ae9f68c --- /dev/null +++ b/.config/zsh/.zshrc @@ -0,0 +1,64 @@ +# Enable colors and change prompt: +autoload -U colors && colors # Load colors +PROMPT='%1~%f%b $ ' + +# gpg key for ssh authentication +export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" +export GPG_TTY=$(tty) + +stty stop undef +setopt autocd +setopt interactive_comments +setopt noglob + +# Load aliases +source $XDG_CONFIG_HOME/shell/aliases + +HISTSIZE=10000 +SAVEHIST=10000 +HISTFILE=~/.cache/history +setopt INC_APPEND_HISTORY +setopt HIST_IGNORE_ALL_DUPS + +# Basic auto/tab complete: +autoload -U compinit +zmodload zsh/complist +compinit +_comp_options+=(globdots) # Include hidden files. + +# vi mode +bindkey -v +export KEYTIMEOUT=1 + +# Use vim keys in tab complete menu: +bindkey -v '^?' backward-delete-char + +# Change cursor shape for different vi modes. +function zle-keymap-select () { + case $KEYMAP in + vicmd) echo -ne '\e[1 q';; # block + viins|main) echo -ne '\e[5 q';; # beam + esac +} +zle -N zle-keymap-select +zle-line-init() { + zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere) + echo -ne "\e[5 q" +} +zle -N zle-line-init +echo -ne '\e[5 q' # Use beam shape cursor on startup. +preexec() { echo -ne '\e[5 q' ;} # Use beam shape cursor for each new prompt. + +bindkey -s '^o' 'vifm\n' + +bindkey -s '^a' 'bc -lq\n' + +bindkey -s '^f' 'cd "$(dirname "$(fzf)")"\n' + +bindkey -v '^r' 'history-incremental-search-backward' + +bindkey '^[[P' delete-char + +# Edit line in vim with ctrl-e: +autoload edit-command-line; zle -N edit-command-line +bindkey '^e' edit-command-line diff --git a/.local/bin/compiler b/.local/bin/compiler new file mode 100755 index 0000000..1ff42a9 --- /dev/null +++ b/.local/bin/compiler @@ -0,0 +1,57 @@ +#!/bin/sh + +# This script will compile or run another finishing operation on a document. I +# have this script run via vim. +# +# Compiles .tex. groff (.mom, .ms), .rmd, .md, .org. Opens .sent files as sent +# presentations. Runs scripts based on extention or shebang. +# +# Note that .tex files which you wish to compile with XeLaTeX should have the +# string "xelatex" somewhere in a comment/command in the first 5 lines. + +file=$(readlink -f "$1") +dir=${file%/*} +base="${file%.*}" +ext="${file##*.}" + +cd "$dir" || exit 1 + +textype() { \ + command="pdflatex" + ( head -n5 "$file" | grep -qi 'xelatex' ) && command="xelatex" + $command --output-directory="$dir" "$base" && + grep -qi addbibresource "$file" && + biber --input-directory "$dir" "$base" && + $command --output-directory="$dir" "$base" && + $command --output-directory="$dir" "$base" +} + +case "$ext" in + # Try to keep these cases in alphabetical order. + [0-9]) preconv "$file" | refer -PS -e | groff -mandoc -T pdf > "$base".pdf ;; + c) cc "$file" -o "$base" && "$base" ;; + cpp) g++ "$file" -o "$base" && "$base" ;; + cs) mcs "$file" && mono "$base".exe ;; + go) go run "$file" ;; + h) doas make install ;; + java) javac -d classes "$file" && java -cp classes "${1%.*}" ;; + m) octave "$file" ;; + md) if [ -x "$(command -v lowdown)" ]; then + lowdown --parse-no-intraemph "$file" -Tms | groff -mpdfmark -ms -kept > "$base".pdf + elif [ -x "$(command -v groffdown)" ]; then + groffdown -i "$file" | groff > "$base.pdf" + else + pandoc -t ms --highlight-style=kate -s -o "$base".pdf "$file" + fi ; ;; + mom) preconv "$file" | refer -PS -e | groff -mom -kept -T pdf > "$base".pdf ;; + ms) preconv "$file" | refer -PS -e | groff -me -ms -kept -T pdf > "$base".pdf ;; + org) emacs "$file" --batch -u "$USER" -f org-latex-export-to-pdf ;; + py) python "$file" ;; + [rR]md) Rscript -e "rmarkdown::render('$file', quiet=TRUE)" ;; + rs) cargo build ;; + sass) sassc -a "$file" "$base.css" ;; + scad) openscad -o "$base".stl "$file" ;; + sent) setsid -f sent "$file" 2>/dev/null ;; + tex) textype "$file" ;; + *) sed -n '/^#!/s/^#!//p; q' "$file" | xargs -r -I % "$file" ;; +esac diff --git a/.local/bin/dmenu/dm-handler b/.local/bin/dmenu/dm-handler new file mode 100755 index 0000000..5d2da20 --- /dev/null +++ b/.local/bin/dmenu/dm-handler @@ -0,0 +1,19 @@ +#!/bin/sh + +# Feed this script a link and it will give dmenu +# some choice programs to use to open it. +feed="${1:-$(printf "%s" | dmenu -p 'Paste URL or file path')}" + +case "$(printf "yt-dlp\\nyt-dlp (audio)\\nyt-dlp (music)\\ncurl\\nmpv (audio)\\nmpv (float)\\nmpv (loop)\\nzathura\\nsxiv\\nnvim\\nbrowser" | dmenu -i -p "Handle it with?")" in + "yt-dlp") qndl "$feed" >/dev/null 2>&1 ;; + "yt-dlp (audio)") qndl "$feed" 'yt-dlp -f bestaudio/best -icx --embed-metadata' >/dev/null 2>&1 ;; + "yt-dlp (music)") qndl "$feed" 'yt-dlp -f bestaudio/best -icx --embed-metadata --no-playlist --audio-format mp3 -o $XDG_MUSIC_DIR/%(title)s.%(ext)s' >/dev/null 2>&1 ;; + "curl") qndl "$feed" 'curl -LO' >/dev/null 2>&1 ;; + "mpv (audio)") setsid -f "$TERMINAL" -e mpv --quiet --no-video "$feed" >/dev/null 2>&1 ;; + "mpv (float)") setsid -f mpv --geometry=+0-0 --autofit=30% --title="mpvfloat" "$feed" >/dev/null 2>&1 ;; + "mpv (loop)") setsid -f mpv -quiet --loop "$feed" >/dev/null 2>&1 ;; + zathura) curl -sL "$feed" > "/tmp/$(echo "$feed" | sed "s/.*\///;s/%20/ /g")" && zathura "/tmp/$(echo "$feed" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 ;; + sxiv) curl -sL "$feed" > "/tmp/$(echo "$feed" | sed "s/.*\///;s/%20/ /g")" && sxiv -a "/tmp/$(echo "$feed" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 ;; + vim) curl -sL "$feed" > "/tmp/$(echo "$feed" | sed "s/.*\///;s/%20/ /g")" && setsid -f "$TERMINAL" -e "$EDITOR" "/tmp/$(echo "$feed" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 ;; + browser) setsid -f "$BROWSER" "$feed" >/dev/null 2>&1 +esac diff --git a/.local/bin/dmenu/dm-mount b/.local/bin/dmenu/dm-mount new file mode 100755 index 0000000..ca93237 --- /dev/null +++ b/.local/bin/dmenu/dm-mount @@ -0,0 +1,67 @@ +#!/bin/sh + +# Gives a dmenu prompt to mount unmounted drives and Android phones. If +# they're in /etc/fstab, they'll be mounted automatically. Otherwise, you'll +# be prompted to give a mountpoint from already existsing directories. If you +# input a novel directory, it will prompt you to create that directory. + +getmount() { \ + [ -z "$chosen" ] && exit 1 + # shellcheck disable=SC2086 + mp="$(find $1 2>/dev/null | dmenu -i -p "Type in mount point.")" || exit 1 + test -z "$mp" && exit 1 + if [ ! -d "$mp" ]; then + mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") || exit 1 + [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp") + fi + } + +mountusb() { \ + chosen="$(echo "$usbdrives" | dmenu -i -p "Mount which drive?")" || exit 1 + chosen="$(echo "$chosen" | awk '{print $1}')" + sudo -A mount "$chosen" 2>/dev/null && notify-send "USB mounting" "$chosen mounted." && exit 0 + alreadymounted=$(lsblk -nrpo "name,type,mountpoint" | awk '$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not ( -path *%s -prune ) ",$3}') + getmount "/mnt /media /mount /home -maxdepth 5 -type d $alreadymounted" + partitiontype="$(lsblk -no "fstype" "$chosen")" + case "$partitiontype" in + "vfat") sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000;; + "exfat") sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)";; + *) sudo -A mount "$chosen" "$mp"; user="$(whoami)"; ug="$(groups | awk '{print $1}')"; sudo -A chown "$user":"$ug" "$mp";; + esac + notify-send "USB mounting" "$chosen mounted to $mp." + } + +mountandroid() { \ + chosen="$(echo "$anddrives" | dmenu -i -p "Which Android device?")" || exit 1 + chosen="$(echo "$chosen" | cut -d : -f 1)" + getmount "$HOME -maxdepth 3 -type d" + simple-mtpfs --device "$chosen" "$mp" + echo "OK" | dmenu -i -p "Tap Allow on your phone if it asks for permission and then press enter" || exit 1 + simple-mtpfs --device "$chosen" "$mp" + notify-send "Android Mounting" "Android device mounted to $mp." + } + +asktype() { \ + choice="$(printf "USB\\nAndroid" | dmenu -i -p "Mount a USB drive or Android device?")" || exit 1 + case $choice in + USB) mountusb ;; + Android) mountandroid ;; + esac + } + +anddrives=$(simple-mtpfs -l 2>/dev/null) +usbdrives="$(lsblk -rpo "name,type,size,mountpoint" | grep 'part\|rom' | awk '$4==""{printf "%s (%s)\n",$1,$3}')" + +if [ -z "$usbdrives" ]; then + [ -z "$anddrives" ] && echo "No USB drive or Android device detected" && exit + echo "Android device(s) detected." + mountandroid +else + if [ -z "$anddrives" ]; then + echo "USB drive(s) detected." + mountusb + else + echo "Mountable USB drive(s) and Android device(s) detected." + asktype + fi +fi diff --git a/.local/bin/dmenu/dm-pass b/.local/bin/dmenu/dm-pass new file mode 100755 index 0000000..b8e2f1b --- /dev/null +++ b/.local/bin/dmenu/dm-pass @@ -0,0 +1,6 @@ +#!/bin/sh + +# This script is the SUDO_ASKPASS variable, meaning that it will be used as a +# password prompt if needed. + +dmenu -P -p "$1" <&- && echo diff --git a/.local/bin/dmenu/dm-record b/.local/bin/dmenu/dm-record new file mode 100755 index 0000000..b1a034a --- /dev/null +++ b/.local/bin/dmenu/dm-record @@ -0,0 +1,123 @@ +#!/bin/sh + +# Usage: +# `$0`: Ask for recording type via dmenu +# `$0 screencast`: Record both audio and screen +# `$0 video`: Record only screen +# `$0 audio`: Record only audio +# `$0 kill`: Kill existing recording +# +# If there is already a running instance, user will be prompted to end it. + +updateicon() { \ + echo "$1" > /tmp/recordingicon + pkill -RTMIN+9 "${STATUSBAR:-dwmblocks}" + } + +killrecording() { + recpid="$(cat /tmp/recordingpid)" + # kill with SIGTERM, allowing finishing touches. + kill -15 "$recpid" + rm -f /tmp/recordingpid + updateicon "" + pkill -RTMIN+9 "${STATUSBAR:-dwmblocks}" + # even after SIGTERM, ffmpeg may still run, so SIGKILL it. + sleep 3 + kill -9 "$recpid" + exit + } + +screencast() { \ + ffmpeg -y \ + -f x11grab \ + -framerate 60 \ + -s "$(xdpyinfo | grep dimensions | awk '{print $2;}')" \ + -i "$DISPLAY" \ + -f alsa -i default \ + -r 30 \ + -c:v h264 -crf 0 -preset ultrafast -c:a aac \ + "$HOME/screencast-$(date '+%y%m%d-%H%M-%S').mp4" & + echo $! > /tmp/recordingpid + updateicon "⏺️🎙️" + } + +video() { ffmpeg \ + -f x11grab \ + -s "$(xdpyinfo | grep dimensions | awk '{print $2;}')" \ + -i "$DISPLAY" \ + -c:v libx264 -qp 0 -r 30 \ + "$HOME/video-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "⏺️" + } + +webcamhidef() { ffmpeg \ + -f v4l2 \ + -i /dev/video0 \ + -video_size 1920x1080 \ + "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "🎥" + } + +webcam() { ffmpeg \ + -f v4l2 \ + -i /dev/video0 \ + -video_size 640x480 \ + "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "🎥" + } + + +audio() { \ + ffmpeg \ + -f alsa -i default \ + -c:a flac \ + "$HOME/audio-$(date '+%y%m%d-%H%M-%S').flac" & + echo $! > /tmp/recordingpid + updateicon "🎙️" + } + +askrecording() { \ + choice=$(printf "screencast\\nvideo\\nvideo selected\\naudio\\nwebcam\\nwebcam (hi-def)" | dmenu -i -p "Select recording style:") + case "$choice" in + screencast) screencast;; + audio) audio;; + video) video;; + *selected) videoselected;; + webcam) webcam;; + "webcam (hi-def)") webcamhidef;; + esac + } + +asktoend() { \ + response=$(printf "No\\nYes" | dmenu -i -p "Recording still active. End recording?") && + [ "$response" = "Yes" ] && killrecording + } + +videoselected() +{ + slop -f "%x %y %w %h" > /tmp/slop + read -r X Y W H < /tmp/slop + rm /tmp/slop + + ffmpeg \ + -f x11grab \ + -framerate 60 \ + -video_size "$W"x"$H" \ + -i :0.0+"$X,$Y" \ + -c:v libx264 -qp 0 -r 30 \ + "$HOME/box-$(date '+%y%m%d-%H%M-%S').mkv" & + echo $! > /tmp/recordingpid + updateicon "⏺️" +} + +case "$1" in + screencast) screencast;; + audio) audio;; + video) video;; + *selected) videoselected;; + kill) killrecording;; + *) ([ -f /tmp/recordingpid ] && asktoend && exit) || askrecording;; +esac diff --git a/.local/bin/dmenu/dm-umount b/.local/bin/dmenu/dm-umount new file mode 100755 index 0000000..a73b9ab --- /dev/null +++ b/.local/bin/dmenu/dm-umount @@ -0,0 +1,44 @@ +#!/bin/sh + +# A dmenu prompt to unmount drives. +# Provides you with mounted partitions, select one to unmount. +# Drives mounted at /, /boot and /home will not be options to unmount. + +unmountusb() { + [ -z "$drives" ] && exit + chosen="$(echo "$drives" | dmenu -i -p "Unmount which drive?")" || exit 1 + chosen="$(echo "$chosen" | awk '{print $1}')" + [ -z "$chosen" ] && exit + sudo -A umount "$chosen" && notify-send "USB unmounting" "$chosen unmounted." + } + +unmountandroid() { \ + chosen="$(awk '/simple-mtpfs/ {print $2}' /etc/mtab | dmenu -i -p "Unmount which device?")" || exit 1 + [ -z "$chosen" ] && exit + sudo -A umount -l "$chosen" && notify-send "Android unmounting" "$chosen unmounted." + } + +asktype() { \ + choice="$(printf "USB\\nAndroid" | dmenu -i -p "Unmount a USB drive or Android device?")" || exit 1 + case "$choice" in + USB) unmountusb ;; + Android) unmountandroid ;; + esac + } + +drives=$(lsblk -nrpo "name,type,size,mountpoint,label" | awk -F':' '{gsub(/ /,":")}$4!~/\/boot|\/efi|\/home$|SWAP/&&length($4)>1{printf "%s (%s) %s\n",$4,$3,$5}') + +if ! grep simple-mtpfs /etc/mtab; then + [ -z "$drives" ] && echo "No drives to unmount." && exit + echo "Unmountable USB drive detected." + unmountusb +else + if [ -z "$drives" ] + then + echo "Unmountable Android device detected." + unmountandroid + else + echo "Unmountable USB drive(s) and Android device(s) detected." + asktype + fi +fi diff --git a/.local/bin/dmenu/prompt b/.local/bin/dmenu/prompt new file mode 100755 index 0000000..050159c --- /dev/null +++ b/.local/bin/dmenu/prompt @@ -0,0 +1,5 @@ +#!/bin/sh + +# A dmenu binary prompt script. + +[ "$(printf "No\\nYes" | dmenu -i -p "$1" )" = "Yes" ] && $2 diff --git a/.local/bin/dmenu/sysact b/.local/bin/dmenu/sysact new file mode 100755 index 0000000..8a145eb --- /dev/null +++ b/.local/bin/dmenu/sysact @@ -0,0 +1,13 @@ +#!/bin/sh + +# A dmenu wrapper script for system functions. +case $1 in + shut) + prompt "Shutdown computer?" "doas poweroff" ;; + reb) + prompt "Reboot computer?" "doas reboot" ;; + rest) + prompt "Leave dwm?" "kill -TERM $(pgrep -u $USER "\bdwm$")" ;; + lock) + slock & xset dpms force off; mpc pause +esac diff --git a/.local/bin/linkhandler b/.local/bin/linkhandler new file mode 100755 index 0000000..c26e2b9 --- /dev/null +++ b/.local/bin/linkhandler @@ -0,0 +1,16 @@ +#!/bin/sh + +[ -z "$1" ] && { "$BROWSER"; exit; } + +case "$1" in + *mkv|*webm|*mp4|*youtube.com/watch*|*youtube.com/playlist*|*youtu.be*|*yewtu.be*|*hooktube.com*|*twitch.tv*|*bitchute.com/embed*|*videos.lukesmith.xyz*) + setsid -f mpv --quiet "$1" >/dev/null 2>&1 ;; + *png|*jpg|*jpe|*jpeg|*gif|*svg) + curl -sL "$1" > "/tmp/$(echo "$1" | sed "s/.*\///;s/%20/ /g")" && sxiv -a "/tmp/$(echo "$1" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 & ;; + *pdf|*cbz|*cbr) + curl -sL "$1" > "/tmp/$(echo "$1" | sed "s/.*\///;s/%20/ /g")" && zathura "/tmp/$(echo "$1" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 & ;; + *mp3|*flac|*opus|*mp3?source*) + qndl "$1" 'curl -LO' >/dev/null 2>&1 ;; + *) + elinks "$1" +esac diff --git a/.local/bin/maimpick b/.local/bin/maimpick new file mode 100755 index 0000000..8ea9f5e --- /dev/null +++ b/.local/bin/maimpick @@ -0,0 +1,18 @@ +#!/bin/sh + +# This is bound to Shift+PrintScreen by default, requires maim. It lets you +# choose the kind of screenshot to take, including copying the image or even +# highlighting an area to copy. scrotcucks on suicidewatch right now. + +# variables +output="$(date '+%y%m%d-%H%M-%S').png" +xclip_cmd="xclip -sel clip -t image/png" + +case "$(printf "a selected area\\ncurrent window\\nfull screen\\na selected area (copy)\\ncurrent window (copy)\\nfull screen (copy)" | dmenu -l 6 -i -p "Screenshot which area?")" in + "a selected area") maim -s pic-selected-"${output}" ;; + "current window") maim -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;; + "full screen") maim -q -d 0.2 pic-full-"${output}" ;; + "a selected area (copy)") maim -s | ${xclip_cmd} ;; + "current window (copy)") maim -q -d 0.2 -i "$(xdotool getactivewindow)" | ${xclip_cmd} ;; + "full screen (copy)") maim -q -d 0.2 | ${xclip_cmd} ;; +esac diff --git a/.local/bin/opout b/.local/bin/opout new file mode 100755 index 0000000..2097af4 --- /dev/null +++ b/.local/bin/opout @@ -0,0 +1,12 @@ +#!/bin/sh + +# A general handler for opening a file's intended output + +basename="$(echo "$1" | sed 's/\.[^\/.]*$//')" + +case "$1" in + *.tex|*.md|*.[rR]md|*.ms|*.me|*.mom) setsid "$READER" "$basename".pdf >/dev/null 2>&1 & ;; + *.[0-9]) setsid "$READER" "$basename".pdf >/dev/null 2>&1 & ;; + *.html) setsid $BROWSER "$basename".html >/dev/null 2>&1 & ;; + *.sent) setsid sent "$1" >/dev/null 2>&1 & ;; +esac diff --git a/.local/bin/qndl b/.local/bin/qndl new file mode 100755 index 0000000..1e82181 --- /dev/null +++ b/.local/bin/qndl @@ -0,0 +1,12 @@ +#!/bin/sh + +# $1 is a url; $2 is a command +[ -z "$1" ] && exit +base="$(basename "$1")" +notify-send "Queuing $base..." +cmd="$2" +[ -z "$cmd" ] && cmd="yt-dlp --embed-metadata -ic" +idnum="$(ts $cmd "$1")" +realname="$(echo "$base" | sed "s/?\(source\|dest\).*//;s/%20/ /g")" +ts -D "$idnum" mv "$base" "$realname" +ts -D "$idnum" notify-send "$realname done." diff --git a/.local/bin/remaps b/.local/bin/remaps new file mode 100755 index 0000000..8768b46 --- /dev/null +++ b/.local/bin/remaps @@ -0,0 +1,14 @@ +#!/bin/sh + +# This script is called on startup to remap keys. +# Decrease key repeat delay to 300ms and increase key repeat rate to 50 per second. +xset r rate 300 50 + +# Map the caps lock key to super, and map the menu key to right super. +setxkbmap -option caps:super,altwin:menu_win + +# When caps lock is pressed only once, treat it as escape. +killall xcape 2>/dev/null ; xcape -e 'Super_L=Escape' + +# Turn off caps lock if on since there is no longer a key for it. +xset -q | grep "Caps Lock:\s*on" && xdotool key Caps_Lock diff --git a/.local/bin/rotdir b/.local/bin/rotdir new file mode 100755 index 0000000..8fbdef5 --- /dev/null +++ b/.local/bin/rotdir @@ -0,0 +1,5 @@ +#!/bin/sh + +[ -z "$1" ] && echo "usage: rotdir regex 2>&1" && exit 1 +base="$(basename $1)" + ls "$PWD" | awk "BEGIN { lines = \"\"; m = 0; } /^$base$/ { m = 1; } { if (!m) { if (lines) { lines = lines\"\n\"; } lines = lines\"\"\$0; } else { print \$0; } } END { print lines; }" diff --git a/.local/bin/rssadd b/.local/bin/rssadd new file mode 100755 index 0000000..fb60be8 --- /dev/null +++ b/.local/bin/rssadd @@ -0,0 +1,18 @@ +#!/bin/sh + +if echo "$1" | grep "https*://\S\+\.[A-Za-z]\+\S*" >/dev/null; then + url="$1" +else + url="$(grep -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" | + sed -E 's_^.*href="(https?://[^"]+)".*$_\1_')" + + ! grep "https*://\S\+\.[A-Za-z]\+\S*" <<<"$url" && + notify-send "That doesn't look like a full URL." && exit 1 +fi + +RSSFILE="${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls" +if awk '{print $1}' "$RSSFILE" | grep "^$url$" >/dev/null; then + notify-send "You already have this RSS feed." +else + echo "$url" >> "$RSSFILE" && notify-send "RSS feed added." +fi diff --git a/.local/bin/statusbar/battery b/.local/bin/statusbar/battery new file mode 100755 index 0000000..d8b0b6d --- /dev/null +++ b/.local/bin/statusbar/battery @@ -0,0 +1,15 @@ +#!/bin/sh + +# Prints all batteries and their percentage remaining + +case $BLOCK_BUTTON in + 1) notify-send "Battery status: $(cat "/sys/class/power_supply/BAT0/status")" ;; + 6) "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +# Loop through all attached batteries. +for battery in /sys/class/power_supply/BAT? +do + capacity=$(cat "$battery"/capacity 2>/dev/null) || break + printf "%s%%" "$capacity" +done diff --git a/.local/bin/statusbar/clock b/.local/bin/statusbar/clock new file mode 100755 index 0000000..0649107 --- /dev/null +++ b/.local/bin/statusbar/clock @@ -0,0 +1,11 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) notify-send "This Month" "$(cal --color=always | sed "s/..7m//;s/..27m/<\/span><\/b>/")" ;; + 3) setsid -f "$TERMINAL" -e calcurse ;; + 6) "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +clk=$(date '+%A %B %d, %I:%M %p') + +printf "%s" "$clk" diff --git a/.local/bin/statusbar/mpdup b/.local/bin/statusbar/mpdup new file mode 100755 index 0000000..2d8d027 --- /dev/null +++ b/.local/bin/statusbar/mpdup @@ -0,0 +1,8 @@ +#!/bin/sh + +# This loop will update the mpd statusbar module whenever a command changes the +# music player's status. mpd must be running on X's start for this to work. + +while : ; do + mpc idle >/dev/null && kill -46 "$(pidof dwmblocks)" || break +done diff --git a/.local/bin/statusbar/music b/.local/bin/statusbar/music new file mode 100755 index 0000000..3852e4d --- /dev/null +++ b/.local/bin/statusbar/music @@ -0,0 +1,14 @@ +#!/bin/sh + +filter() { mpc -f %title% | sed "/^volume:/d;s/\\&/&/g;s/\\[paused\\].*/[P]/g;/\\[playing\\].*/d;/^ERROR/Q" | paste -sd ' ';} + +pidof -x mpdup >/dev/null 2>&1 || mpdup >/dev/null 2>&1 & + +case $BLOCK_BUTTON in + 1) mpc toggle | filter ;; + 3) mpc status | filter ; setsid -f "$TERMINAL" -e ncmpcpp ;; + 4) mpc prev | filter ;; + 5) mpc next | filter ;; + 6) mpc status | filter ; "$TERMINAL" -e "$EDITOR" "$0" ;; + *) mpc status | filter ;; +esac diff --git a/.local/bin/statusbar/volume b/.local/bin/statusbar/volume new file mode 100755 index 0000000..43bad91 --- /dev/null +++ b/.local/bin/statusbar/volume @@ -0,0 +1,15 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) pamixer -t ;; + 3) setsid -f "$TERMINAL" -e pulsemixer ;; + 4) pamixer --allow-boost -i 1 ;; + 5) pamixer --allow-boost -d 1 ;; + 6) "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +[ $(pamixer --get-mute) = true ] && echo Muted && exit + +vol="$(pamixer --get-volume)" + +printf "%s%%" "$vol" diff --git a/.local/bin/tag b/.local/bin/tag new file mode 100755 index 0000000..8462b99 --- /dev/null +++ b/.local/bin/tag @@ -0,0 +1,67 @@ +#!/bin/sh + +err() { echo "Usage: + tag [OPTIONS] file +Options: + -a: artist/author + -t: song/chapter title + -A: album/book title + -n: track/chapter number + -N: total number of tracks/chapters + -d: year of publication + -g: genre + -c: comment +You will be prompted for title, artist, album and track if not given." && exit 1 ;} + +while getopts "a:t:A:n:N:d:g:c:f:" o; do case "${o}" in + a) artist="${OPTARG}" ;; + t) title="${OPTARG}" ;; + A) album="${OPTARG}" ;; + n) track="${OPTARG}" ;; + N) total="${OPTARG}" ;; + d) date="${OPTARG}" ;; + g) genre="${OPTARG}" ;; + c) comment="${OPTARG}" ;; + f) file="${OPTARG}" ;; + *) printf "Invalid option: -%s\\n" "$OPTARG" && err ;; +esac done + +shift $((OPTIND - 1)) + +file="$1" + +[ ! -f "$file" ] && echo "Provide file to tag." && err + +[ -z "$title" ] && echo "Enter a title." && read -r title +[ -z "$artist" ] && echo "Enter an artist." && read -r artist +[ -z "$album" ] && echo "Enter an album." && read -r album +[ -z "$track" ] && echo "Enter a track number." && read -r track + +case "$file" in + *.ogg) echo "Title=$title +Artist=$artist +Album=$album +Track=$track +Total=$total +Date=$date +Genre=$genre +Comment=$comment" | vorbiscomment -w "$file" ;; + *.opus) echo "Title=$title +Artist=$artist +Album=$album +Track=$track +Total=$total +Date=$date +Genre=$genre +Comment=$comment" | opustags -i -S "$file" ;; + *.mp3) eyeD3 -Q --remove-all -a "$artist" -A "$album" -t "$title" -n "$track" -N "$total" -Y "$date" "$file" ;; + *.flac) echo "TITLE=$title +ARTIST=$artist +ALBUM=$album +TRACKNUMBER=$track +TOTALTRACKS=$total +DATE=$date +GENRE=$genre +DESCRIPTION=$comment" | metaflac --remove-all-tags --import-tags-from=- "$file" ;; + *) echo "File type not implemented yet." ;; +esac diff --git a/.local/bin/torwrap b/.local/bin/torwrap new file mode 100755 index 0000000..ffa0553 --- /dev/null +++ b/.local/bin/torwrap @@ -0,0 +1,21 @@ +#!/bin/sh + +check () { \ + ! pidof transmission-daemon >/dev/null && transmission-daemon && notify-send "transmission daemon enabled." + } + +case "$1" in + toggle) + if pidof transmission-daemon >/dev/null ; + then + prompt "Turn off transmission-daemon?" "pkill transmission-da" && notify-send "transmission-daemon disabled." + else + prompt "Turn on transmission-daemon?" "transmission-daemon" && notify-send "transmission-daemon enabled." + fi ;; + open) + check ; $TERMINAL -e tremc ;; + add) + check ; sleep 1 && transmission-remote -a "$2" && notify-send "Torrent added." ;; + *) + notify-send "$TR_TORRENT_NAME downloaded." && sleep 180 && transmission-remote -t ${TR_TORRENT_ID} -r +esac diff --git a/.local/share/applications/file.desktop b/.local/share/applications/file.desktop new file mode 100644 index 0000000..04631cd --- /dev/null +++ b/.local/share/applications/file.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=File Manager +Exec=/usr/local/bin/st -e vifm %u diff --git a/.local/share/applications/img.desktop b/.local/share/applications/img.desktop new file mode 100644 index 0000000..42aa81e --- /dev/null +++ b/.local/share/applications/img.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=Image viewer +Exec=/usr/bin/sxiv -a %f diff --git a/.local/share/applications/pdf.desktop b/.local/share/applications/pdf.desktop new file mode 100644 index 0000000..8c38677 --- /dev/null +++ b/.local/share/applications/pdf.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=PDF reader +Exec=/usr/bin/zathura %u diff --git a/.local/share/applications/rss.desktop b/.local/share/applications/rss.desktop new file mode 100644 index 0000000..6fafc4f --- /dev/null +++ b/.local/share/applications/rss.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=RSS feed addition +Exec=/usr/bin/env rssadd %U diff --git a/.local/share/applications/text.desktop b/.local/share/applications/text.desktop new file mode 100644 index 0000000..41ee05f --- /dev/null +++ b/.local/share/applications/text.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=Text editor +Exec=/usr/local/bin/st -e nvim %u diff --git a/.local/share/applications/torrent.desktop b/.local/share/applications/torrent.desktop new file mode 100644 index 0000000..a0dfa73 --- /dev/null +++ b/.local/share/applications/torrent.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=Torrent +Exec=/usr/bin/env torwrap add %U diff --git a/.local/share/gnupg/gpg-agent.conf b/.local/share/gnupg/gpg-agent.conf new file mode 100644 index 0000000..f58b85d --- /dev/null +++ b/.local/share/gnupg/gpg-agent.conf @@ -0,0 +1,4 @@ +pinentry-program /usr/bin/pinentry-gtk-2 +default-cache-ttl 5000 +max-cache-ttl 7200 +enable-ssh-support diff --git a/.ssh/config b/.ssh/config new file mode 100644 index 0000000..4be131d --- /dev/null +++ b/.ssh/config @@ -0,0 +1 @@ +Match host * exec "gpg-connect-agent UPDATESTARTUPTTY /bye"