commit 46d9d9eb4ce4e9875f4288b4171bd839af9ad0ef Author: Alexander Bocken Date: Sat Jul 4 14:23:27 2020 +0200 inital commit diff --git a/.config/X11/Xresources b/.config/X11/Xresources new file mode 100644 index 0000000..040144a --- /dev/null +++ b/.config/X11/Xresources @@ -0,0 +1,12 @@ +*.dpi: 160 +Xft.autohint: 0 +Xft.lcdfilter: lcddefault +Xft.hintstyle: hintfull +Xft.hinting: 1 +Xft.antialias: 1 +Xft.rgba: rgb + +Sxiv.background: black +Sxiv.foreground: white +Sxiv.font: Monospace-10 +Sxiv.text_color: blue diff --git a/.config/X11/xinitrc b/.config/X11/xinitrc new file mode 100644 index 0000000..4a7c6e8 --- /dev/null +++ b/.config/X11/xinitrc @@ -0,0 +1,14 @@ +#!/bin/sh + +xrdb -merge ~/.Xresources +[ -f "$HOME/.xprofile" ] && . ~/.xprofile +#xrdb -merge ~/.Xresources +wal -n -i ~/.config/wall.png -b '#000000' +while true; do + # Log stderror to a file + #dwm 2> ~/.dwm.log + # No error logging + dwm >/dev/null 2>&1 +done +#exec i3 +#exec bspwm diff --git a/.config/aliasrc b/.config/aliasrc new file mode 100644 index 0000000..c7d85ff --- /dev/null +++ b/.config/aliasrc @@ -0,0 +1,65 @@ +#!/bin/sh + +# Use neovim for vim if present. +command -v nvim >/dev/null && alias vim="nvim" vimdiff="nvim -d" + +# Verbosity and settings that you pretty much just always are going to want. +alias \ + bat="cat /sys/class/power_supply/BAT?/capacity" \ + cp="cp -iv" \ + mv="mv -iv" \ + rm="rm -v" \ + mkd="mkdir -pv" \ + yt="youtube-dl --add-metadata -i" \ + yta="yt -x -f bestaudio/best" \ + ffmpeg="ffmpeg -hide_banner" + +# Colorize commands when possible. +alias \ + ls="ls -hN --color=auto --group-directories-first" \ + grep="grep --color=auto" \ + diff="diff --color=auto" \ + ccat="highlight --out-format=ansi" + +# These common commands are just too long! Abbreviate them. +alias \ + ka="killall" \ + g="git" \ + trem="transmission-remote" \ + YT="youtube-viewer" \ + sdn="sudo shutdown -h now" \ + f="$FILE" \ + e="$EDITOR" \ + v="$EDITOR" \ + p="sudo pacman" \ + xi="sudo xbps-install" \ + xr="sudo xbps-remove -R" \ + xq="xbps-query" \ + z="zathura"\ + q="exit"\ + dunstpause="notify-send 'dunst' 'Pausing dunst...'; sleep 2; notify-send 'DUNST_COMMAND_PAUSE'"\ + dunstresume="notify-send 'dunst' 'Resuming dunst...' && notify-send 'DUNST_COMMAND_RESUME'"\ + glog="git log --all --graph --decorate"\ + clog="config log --all --graph --decorate"\ + cam="mpv --demuxer-lavf-format=video4linux2 --demuxer-lavf-o-set=input_format=mjpeg av://v4l2:/dev/video0"\ + createvocabhtml="awk -F '\t' '{print \"
\"$2\"
\"$4\"
\t
\"$3\"
\"$5\"
\"$6\"
no. \"$1\", \"$7\", \"$8\"
\"}'" + + +# Some other stuff +alias \ + magit="nvim -c MagitOnly" \ + ref="shortcuts >/dev/null; source ${XDG_CONFIG_HOME:-$HOME/.config}/shortcutrc ; source ${XDG_CONFIG_HOME:-$HOME/.config}/zshnameddirrc" \ + weath="less -S ${XDG_DATA_HOME:-$HOME/.local/share}/weatherreport" \ + tmux="tmux -f ${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf"\ + cast="mkchromecast --video --control -i"\ + castaudio="mkchromecast --control --screencast" + #gpg="gpg --homedir=$GNUPGHOME" + +# Some useful functions +vf() { fzf | xargs -r -I % $EDITOR % ;} +# [ -z $video ] || ( mpv "$video" & disown ) ;} +vpdf() { pdf="$( ls -t $HOME/.cache/luakit/viewpdf/ | fzf -e )" + [ -z $pdf ] || ( $READER "$HOME/.cache/luakit/viewpdf/$pdf" & disown ) ;} +epdf() { pdf="$(du -a --time ETH/ | awk '!($1="")' | sort -r | grep '\.pdf' | awk '!($1="")' | awk '!($1="")' | sed 's/^ //' | fzf -e )" + [ -z $pdf ] || ( $READER "$pdf" & ) ;} +alias config='/usr/bin/git --git-dir=/home/alex/.local/share/git_dotfiles --work-tree=/home/alex' diff --git a/.config/alsa/asoundrc b/.config/alsa/asoundrc new file mode 100644 index 0000000..38722f0 --- /dev/null +++ b/.config/alsa/asoundrc @@ -0,0 +1,21 @@ +# Find and use input "Microphone" for input +pcm.usb +{ + type hw + card Microphone +} +pcm.!default +{ + type asym + playback.pcm + { + # Use the dmix plug to allow multiple outputs. + type plug + slave.pcm "dmix" + } + capture.pcm + { + type plug + slave.pcm "usb" + } +} diff --git a/.config/calcurse/.calcurse.pid b/.config/calcurse/.calcurse.pid new file mode 100644 index 0000000..382d2d7 --- /dev/null +++ b/.config/calcurse/.calcurse.pid @@ -0,0 +1 @@ +6827 diff --git a/.config/calcurse/conf b/.config/calcurse/conf new file mode 100644 index 0000000..3e59195 --- /dev/null +++ b/.config/calcurse/conf @@ -0,0 +1,32 @@ +appearance.calendarview=monthly +appearance.compactpanels=no +appearance.defaultpanel=calendar +appearance.layout=1 +appearance.headerline=yes +appearance.eventseparator=yes +appearance.dayseparator=yes +appearance.emptyline=yes +appearance.notifybar=yes +appearance.sidebarwidth=0 +appearance.theme=default on default +appearance.todoview=hide-completed +appearance.headingpos=right-justified +daemon.enable=yes +daemon.log=no +format.inputdate=1 +format.notifydate=%a %F +format.notifytime=%T +format.outputdate=%D +format.dayheading=%B %e, %Y +general.autogc=no +general.autosave=yes +general.confirmdelete=yes +general.confirmquit=yes +general.firstdayofweek=monday +general.multipledays=yes +general.periodicsave=1 +general.systemevents=yes +general.systemdialogs=yes +notification.command=printf '\a' +notification.notifyall=all +notification.warning=300 diff --git a/.config/calcurse/keys b/.config/calcurse/keys new file mode 100644 index 0000000..0f5ee8d --- /dev/null +++ b/.config/calcurse/keys @@ -0,0 +1,55 @@ +# +# Calcurse keys configuration file +# +# In this file the keybindings used by Calcurse are defined. +# It is generated automatically by Calcurse and is maintained +# via the key configuration menu of the interactive user +# interface. It should not be edited directly. + +generic-cancel ESC +generic-select SPC +generic-credits @ +generic-help ? +generic-quit q Q +generic-save s S ^S +generic-reload R +generic-copy c +generic-paste p ^V +generic-change-view TAB +generic-import i I +generic-export x X +generic-goto g G +generic-other-cmd o O +generic-config-menu C +generic-redraw ^R +generic-add-appt ^A +generic-add-todo ^T +generic-prev-day T ^H +generic-next-day t ^L +generic-prev-week W ^K +generic-next-week w +generic-prev-month M +generic-next-month m +generic-prev-year Y +generic-next-year y +generic-scroll-down ^N +generic-scroll-up ^P +generic-goto-today ^G +generic-command : +move-right l L RGT +move-left h H LFT +move-down j J DWN +move-up k K UP +start-of-week 0 +end-of-week $ +add-item a A +del-item d D +edit-item e E +view-item v V RET +pipe-item | +flag-item ! +repeat r +edit-note n N +view-note > +raise-priority + +lower-priority - diff --git a/.config/coc/extensions/db.json b/.config/coc/extensions/db.json new file mode 100644 index 0000000..dc30f12 --- /dev/null +++ b/.config/coc/extensions/db.json @@ -0,0 +1,3 @@ +{ + "lastUpdate": 1593852197191 +} \ No newline at end of file diff --git a/.config/coc/extensions/node_modules/coc-vimtex/Readme.md b/.config/coc/extensions/node_modules/coc-vimtex/Readme.md new file mode 100644 index 0000000..63ec16e --- /dev/null +++ b/.config/coc/extensions/node_modules/coc-vimtex/Readme.md @@ -0,0 +1,22 @@ +# coc-vimtex + +Tex completion source use [vimtex](https://github.com/lervag/vimtex). + +## Install + +In your vim/neovim, run command: + +``` +:CocInstall coc-vimtex +``` + +## Options + +- `coc.source.vimtex.disableSyntaxes` disabled syntax names. +- `coc.source.vimtex.enable` set to false to disable this source. +- `coc.source.vimtex.priority` priority of source, default `99`. +- `coc.source.vimtex.shortcut` shortcut used in `menu` of completion item. + +## License + +MIT diff --git a/.config/coc/extensions/node_modules/coc-vimtex/package.json b/.config/coc/extensions/node_modules/coc-vimtex/package.json new file mode 100644 index 0000000..2259aab --- /dev/null +++ b/.config/coc/extensions/node_modules/coc-vimtex/package.json @@ -0,0 +1,46 @@ +{ + "name": "coc-vimtex", + "version": "1.0.3", + "description": "vimtex integration for coc.nvim", + "main": "src/index.js", + "publisher": "chemzqm", + "keywords": [ + "coc.nvim", + "vimtex" + ], + "engines": { + "coc": "^0.0.56" + }, + "activationEvents": [ + "onLanguage:tex", + "onLanguage:plaintex", + "onLanguage:latex" + ], + "contributes": { + "configuration": { + "type": "object", + "properties": { + "coc.source.vimtex.enable": { + "type": "boolean", + "default": true + }, + "coc.source.vimtex.priority": { + "type": "integer", + "default": 99 + } + } + } + }, + "author": "chemzqm@gmail.com", + "repository": { + "type": "git", + "url": "git+https://github.com/neoclide/coc-vimtex.git" + }, + "license": "MIT", + "devDependencies": { + "@types/node": "^10.12.24", + "coc.nvim": "^0.0.74", + "rimraf": "^2.6.3" + }, + "dependencies": {} +} diff --git a/.config/coc/extensions/node_modules/coc-vimtex/src/index.js b/.config/coc/extensions/node_modules/coc-vimtex/src/index.js new file mode 100644 index 0000000..68d3850 --- /dev/null +++ b/.config/coc/extensions/node_modules/coc-vimtex/src/index.js @@ -0,0 +1,67 @@ +const {sources, workspace, SourceType} = require('coc.nvim') +const {convertRegex, byteSlice} = require('./util') + +exports.activate = async context => { + let config = workspace.getConfiguration('coc.source.vimtex') + let {nvim} = workspace + + let regex = await nvim.getVar('vimtex#re#deoplete') + if (!regex) { + workspace.showMessage('vimtex not loaded', 'error') + return + } + regex = regex.slice(2, regex.length) + let pattern = new RegExp(convertRegex(regex) + '$') + + function convertItems(list) { + let res = [] + for (let item of list) { + if (typeof item == 'string') { + res.push(Object.assign({word: item})) + } + if (item.hasOwnProperty('word')) { + res.push(item) + } + } + return res + } + + let source = { + name: 'vimtex', + enable: config.get('enable', true), + priority: config.get('priority', 99), + filetypes: ['tex', 'plaintex', 'latex'], + sourceType: SourceType.Remote, + triggerPatterns: [pattern], + doComplete: async opt => { + let {nvim} = workspace + let func = 'vimtex#complete#omnifunc' + let {line, colnr, col} = opt + let startcol = col + try { + startcol = await nvim.call(func, [1, '']) + startcol = Number(startcol) + } catch (e) { + workspace.showMessage(`vim error from ${func} :${e.message}`, 'error') + return null + } + // invalid startcol + if (isNaN(startcol) || startcol < 0 || startcol > colnr) return null + let text = byteSlice(line, startcol, colnr - 1) + let words = await nvim.call(func, [0, text]) + if (words.hasOwnProperty('words')) { + words = words.words + } + let res = {items: convertItems(words)} + res.startcol = startcol + return res + } + } + + sources.addSource(source) + context.subscriptions.push({ + dispose: () => { + sources.removeSource(source) + } + }) +} diff --git a/.config/coc/extensions/node_modules/coc-vimtex/src/util.js b/.config/coc/extensions/node_modules/coc-vimtex/src/util.js new file mode 100644 index 0000000..d5518ec --- /dev/null +++ b/.config/coc/extensions/node_modules/coc-vimtex/src/util.js @@ -0,0 +1,56 @@ +/****************************************************************** +MIT License http://www.opensource.org/licenses/mit-license.php +Author Qiming Zhao (https://github.com/chemzqm) +*******************************************************************/ + +const conditionRe = /\(\?\(\?:\w+\).+\|/ +const bellRe = /\\a/ +const commentRe = /\(\?#.*?\)/ +const stringStartRe = /\\A/ +const lookBehindRe = /\(\?<[!=].*?\)/ +const namedCaptureRe = /\(\?P<\w+>.*?\)/ +const namedReferenceRe = /\(\?P=(\w+)\)/ +const braceRe = /\^\]/ +const regex = new RegExp(`${bellRe.source}|${commentRe.source}|${stringStartRe.source}|${lookBehindRe.source}|${namedCaptureRe.source}|${namedReferenceRe.source}|${braceRe}`, 'g') + +/** + * Convert python regex to javascript regex, + * throw error when unsupported pattern found + * + * @public + * @param {string} str + * @returns {string} + */ +exports.convertRegex = function(str) { + if (str.indexOf('\\z') !== -1) { + throw new Error('pattern \\z not supported') + } + if (str.indexOf('(?s)') !== -1) { + throw new Error('pattern (?s) not supported') + } + if (str.indexOf('(?x)') !== -1) { + throw new Error('pattern (?x) not supported') + } + if (str.indexOf('\n') !== -1) { + throw new Error('multiple line pattern not supported') + } + if (conditionRe.test(str)) { + throw new Error('condition pattern not supported') + } + return str.replace(regex, (match, p1) => { + if (match == '^]') return '^\\]' + if (match == '\\a') return '' + if (match.startsWith('(?#')) return '' + if (match == '\\A') return '^' + if (match.startsWith('(?<')) return '(?' + match.slice(3) + if (match.startsWith('(?P<')) return '(?' + match.slice(3) + if (match.startsWith('(?P=')) return `\\k<${p1}>` + return '' + }) +} + + +exports.byteSlice = function (content, start, end) { + let buf = Buffer.from(content, 'utf8') + return buf.slice(start, end).toString('utf8') +} diff --git a/.config/coc/extensions/package.json b/.config/coc/extensions/package.json new file mode 100644 index 0000000..3c752eb --- /dev/null +++ b/.config/coc/extensions/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "coc-json": ">=1.2.6", + "coc-vimtex": ">=1.0.3" + } +} \ No newline at end of file diff --git a/.config/coc/history.json b/.config/coc/history.json new file mode 100644 index 0000000..ccf6cbc --- /dev/null +++ b/.config/coc/history.json @@ -0,0 +1,16 @@ +{ + "diagnostics": { + "%2Fhome%2Falex%2F": { + "local%2Fbin%2Ftools": [ + " " + ], + "local%2Fsrc%2Fbthandler": [ + " " + ] + }, + "%2Fhome%2Falex": [ + "kk", + " " + ] + } +} \ No newline at end of file diff --git a/.config/coc/lists b/.config/coc/lists new file mode 100644 index 0000000..20a174f --- /dev/null +++ b/.config/coc/lists @@ -0,0 +1 @@ +diagnostics \ No newline at end of file diff --git a/.config/coc/memos.json b/.config/coc/memos.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.config/coc/memos.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.config/coc/mru b/.config/coc/mru new file mode 100644 index 0000000..e69de29 diff --git a/.config/directories b/.config/directories new file mode 100644 index 0000000..879219c --- /dev/null +++ b/.config/directories @@ -0,0 +1,11 @@ +# You can add comments to these files with # +h ~/ +d ~/Documents +D ~/Downloads +m ~/Music +pp ~/Pictures +vv ~/Videos +cf ${XDG_CONFIG_HOME:-$HOME/.config} +cac ${XDG_CACHE_HOME:-$HOME/.cache} +sc ~/.local/bin +mn /mnt diff --git a/.config/dunst/dunstrc b/.config/dunst/dunstrc new file mode 100644 index 0000000..b1ed8ca --- /dev/null +++ b/.config/dunst/dunstrc @@ -0,0 +1,257 @@ +[global] +#font = Iosevka Term 11 +font = Monospace 14 +# Allow a small subset of html markup: +# bold +# italic +# strikethrough +# underline +# +# For a complete reference see +# . +# If markup is not allowed, those tags will be stripped out of the +# message. +markup = yes +plain_text = no + +# The format of the message. Possible variables are: +# %a appname +# %s summary +# %b body +# %i iconname (including its path) +# %I iconname (without its path) +# %p progress value if set ([ 0%] to [100%]) or nothing +# Markup is allowed +format = "%s\n%b" + +# Sort messages by urgency. +sort = no + +# Show how many messages are currently hidden (because of geometry). +indicate_hidden = yes + +# Alignment of message text. +# Possible values are "left", "center" and "right". +alignment = center + +# The frequency with wich text that is longer than the notification +# window allows bounces back and forth. +# This option conflicts with "word_wrap". +# Set to 0 to disable. +bounce_freq = 0 + +# Show age of message if message is older than show_age_threshold +# seconds. +# Set to -1 to disable. +show_age_threshold = 60 + +# Split notifications into multiple lines if they don't fit into +# geometry. +word_wrap = yes + +# Ignore newlines '\n' in notifications. +ignore_newline = no + +# Hide duplicate's count and stack them +stack_duplicates = yes +hide_duplicates_count = yes + + +# The geometry of the window: +# [{width}]x{height}[+/-{x}+/-{y}] +# The geometry of the message window. +# The height is measured in number of notifications everything else +# in pixels. If the width is omitted but the height is given +# ("-geometry x2"), the message window expands over the whole screen +# (dmenu-like). If width is 0, the window expands to the longest +# message displayed. A positive x is measured from the left, a +# negative from the right side of the screen. Y is measured from +# the top and down respectevly. +# The width can be negative. In this case the actual width is the +# screen width minus the width defined in within the geometry option. +#geometry = "250x50-40+40" +geometry = "500x50-10+50" + +# Shrink window if it's smaller than the width. Will be ignored if +# width is 0. +shrink = no + +# The transparency of the window. Range: [0; 100]. +# This option will only work if a compositing windowmanager is +# present (e.g. xcompmgr, compiz, etc.). +transparency = 20 + +# Don't remove messages, if the user is idle (no mouse or keyboard input) +# for longer than idle_threshold seconds. +# Set to 0 to disable. +idle_threshold = 120 + +# Which monitor should the notifications be displayed on. +monitor = 0 + +# Display notification on focused monitor. Possible modes are: +# mouse: follow mouse pointer +# keyboard: follow window with keyboard focus +# none: don't follow anything +# +# "keyboard" needs a windowmanager that exports the +# _NET_ACTIVE_WINDOW property. +# This should be the case for almost all modern windowmanagers. +# +# If this option is set to mouse or keyboard, the monitor option +# will be ignored. +follow = none + +# Should a notification popped up from history be sticky or timeout +# as if it would normally do. +sticky_history = yes + +# Maximum amount of notifications kept in history +history_length = 20 + +# Display indicators for URLs (U) and actions (A). +show_indicators = no + +# The height of a single line. If the height is smaller than the +# font height, it will get raised to the font height. +# This adds empty space above and under the text. +line_height = 3 + +# Draw a line of "separatpr_height" pixel height between two +# notifications. +# Set to 0 to disable. +separator_height = 2 + +# Padding between text and separator. +padding = 0 + +# Horizontal padding. +horizontal_padding = 6 + +# Define a color for the separator. +# possible values are: +# * auto: dunst tries to find a color fitting to the background; +# * foreground: use the same color as the foreground; +# * frame: use the same color as the frame; +# * anything else will be interpreted as a X color. +separator_color = frame + +# Print a notification on startup. +# This is mainly for error detection, since dbus (re-)starts dunst +# automatically after a crash. +startup_notification = false + +# dmenu path. +dmenu = /usr/bin/dmenu -p dunst: + +# Browser for opening urls in context menu. +browser = /usr/bin/firefox -new-tab + +# Align icons left/right/off +icon_position = off +max_icon_size = 80 + +# Paths to default icons. +icon_path = /usr/share/icons/Paper/16x16/mimetypes/:/usr/share/icons/Paper/48x48/status/:/usr/share/icons/Paper/16x16/devices/:/usr/share/icons/Paper/48x48/notifications/:/usr/share/icons/Paper/48x48/emblems/ + +frame_width = 1 +frame_color = "#8EC07C" + +[shortcuts] + +# Shortcuts are specified as [modifier+][modifier+]...key +# Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", +# "mod3" and "mod4" (windows-key). +# Xev might be helpful to find names for keys. + +# Close notification. +close = ctrl+space + +# Close all notifications. +close_all = ctrl+shift+space + +# Redisplay last message(s). +# On the US keyboard layout "grave" is normally above TAB and left +# of "1". +history = ctrl+grave + +# Context menu. +context = ctrl+shift+period + +[urgency_low] +# IMPORTANT: colors have to be defined in quotation marks. +# Otherwise the "#" and following would be interpreted as a comment. +frame_color = "#3B7C87" +foreground = "#d7d5d1" +background = "#191311" +#background = "#2B313C" +timeout = 15 + +[urgency_normal] +frame_color = "#5B8234" +foreground = "#d7d5d1" +background = "#191311" +#background = "#2B313C" +timeout = 20 + +[urgency_critical] +frame_color = "#B7472A" +foreground = "#d7d5d1" +background = "#191311" +#background = "#2B313C" +timeout = 30 + + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# Messages can be matched by "appname", "summary", "body", "icon", "category", +# "msg_urgency" and you can override the "timeout", "urgency", "foreground", +# "background", "new_icon" and "format". +# Shell-like globbing will get expanded. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: if you don't want a notification to be displayed, set the format +# to "". +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# format = "" + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +# vim: ft=cfg diff --git a/.config/dunst/dunstrc_old b/.config/dunst/dunstrc_old new file mode 100644 index 0000000..abf5586 --- /dev/null +++ b/.config/dunst/dunstrc_old @@ -0,0 +1,152 @@ +[global] + monitor = 0 + follow = keyboard + geometry = "350x5-0+24" + indicate_hidden = yes + shrink = yes + transparency = 20 + notification_height = 0 + separator_height = 2 + padding = 0 + horizontal_padding = 8 + frame_width = 3 + frame_color = "#282828" + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + separator_color = frame + + # Sort messages by urgency. + sort = yes + + idle_threshold = 120 + font = Monospace 14 + line_height = 0 + markup = full + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # %n progress value if set without any extra characters + # %% Literal % + # Markup is allowed + format = "%s\n%b" + + alignment = left + show_age_threshold = 60 + word_wrap = yes + ellipsize = middle + ignore_newline = no + stack_duplicates = true + hide_duplicate_count = true + show_indicators = yes + icon_position = left + max_icon_size = 40 + #icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/:/usr/share/icons/Adwaita/256x256/status/ + sticky_history = yes + history_length = 20 + dmenu = /usr/bin/dmenu -p dunst: + browser = /usr/bin/firefox -new-tab + + # Always run rule-defined scripts, even if the notification is suppressed + always_run_script = true + + title = Dunst + class = Dunst + startup_notification = false + force_xinerama = false +[experimental] + per_monitor_dpi = false + +[shortcuts] + close = ctrl+space + close_all = ctrl+shift+space + history = ctrl+grave + context = ctrl+shift+period + +[urgency_low] + # IMPORTANT: colors have to be defined in quotation marks. + # Otherwise the "#" and following would be interpreted as a comment. + background = "#282828" + foreground = "#928374" + timeout = 5 + # Icon for notifications with low urgency, uncomment to enable + #icon = /path/to/icon + +[urgency_normal] + background = "#458588" + foreground = "#ebdbb2" + timeout = 5 + +[urgency_critical] + background = "#cc2421" + foreground = "#ebdbb2" + frame_color = "#fabd2f" + timeout = 0 + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# Messages can be matched by "appname", "summary", "body", "icon", "category", +# "msg_urgency" and you can override the "timeout", "urgency", "foreground", +# "background", "new_icon" and "format". +# Shell-like globbing will get expanded. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: if you don't want a notification to be displayed, set the format +# to "". +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# format = "" + +#[history-ignore] +# # This notification will not be saved in history +# summary = "foobar" +# history_ignore = yes + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +# vim: ft=cfg diff --git a/.config/emoji b/.config/emoji new file mode 100644 index 0000000..35c1e1b --- /dev/null +++ b/.config/emoji @@ -0,0 +1,1644 @@ +๐Ÿ˜€ grinning face; U+1F600 +๐Ÿ˜ƒ grinning face with big eyes; U+1F603 +๐Ÿ˜„ grinning face with smiling eyes; U+1F604 +๐Ÿ˜ beaming face with smiling eyes; U+1F601 +๐Ÿ˜† grinning squinting face; U+1F606 +๐Ÿ˜… grinning face with sweat; U+1F605 +๐Ÿคฃ rolling on the floor laughing; U+1F923 +๐Ÿ˜‚ face with tears of joy; U+1F602 +๐Ÿ™‚ slightly smiling face; U+1F642 +๐Ÿ™ƒ upside-down face; U+1F643 +๐Ÿ˜‰ winking face; U+1F609 +๐Ÿ˜Š smiling face with smiling eyes; U+1F60A +๐Ÿ˜‡ smiling face with halo; U+1F607 +๐Ÿฅฐ smiling face with 3 hearts; U+1F970 +๐Ÿ˜ smiling face with heart-eyes; U+1F60D +๐Ÿคฉ star-struck; U+1F929 +๐Ÿ˜˜ face blowing a kiss; U+1F618 +๐Ÿ˜— kissing face; U+1F617 +โ˜บ smiling face; U+263A +๐Ÿ˜š kissing face with closed eyes; U+1F61A +๐Ÿ˜™ kissing face with smiling eyes; U+1F619 +๐Ÿ˜‹ face savoring food; U+1F60B +๐Ÿ˜› face with tongue; U+1F61B +๐Ÿ˜œ winking face with tongue; U+1F61C +๐Ÿคช zany face; U+1F92A +๐Ÿ˜ squinting face with tongue; U+1F61D +๐Ÿค‘ money-mouth face; U+1F911 +๐Ÿค— hugging face; U+1F917 +๐Ÿคญ face with hand over mouth; U+1F92D +๐Ÿคซ shushing face; U+1F92B +๐Ÿค” thinking face; U+1F914 +๐Ÿค zipper-mouth face; U+1F910 +๐Ÿคจ face with raised eyebrow; U+1F928 +๐Ÿ˜ neutral face; U+1F610 +๐Ÿ˜‘ expressionless face; U+1F611 +๐Ÿ˜ถ face without mouth; U+1F636 +๐Ÿ˜ smirking face; U+1F60F +๐Ÿ˜’ unamused face; U+1F612 +๐Ÿ™„ face with rolling eyes; U+1F644 +๐Ÿ˜ฌ grimacing face; U+1F62C +๐Ÿคฅ lying face; U+1F925 +๐Ÿ˜Œ relieved face; U+1F60C +๐Ÿ˜” pensive face; U+1F614 +๐Ÿ˜ช sleepy face; U+1F62A +๐Ÿคค drooling face; U+1F924 +๐Ÿ˜ด sleeping face; U+1F634 +๐Ÿ˜ท face with medical mask; U+1F637 +๐Ÿค’ face with thermometer; U+1F912 +๐Ÿค• face with head-bandage; U+1F915 +๐Ÿคข nauseated face; U+1F922 +๐Ÿคฎ face vomiting; U+1F92E +๐Ÿคง sneezing face; U+1F927 +๐Ÿฅต hot face; U+1F975 +๐Ÿฅถ cold face; U+1F976 +๐Ÿฅด woozy face; U+1F974 +๐Ÿ˜ต dizzy face; U+1F635 +๐Ÿคฏ exploding head; U+1F92F +๐Ÿค  cowboy hat face; U+1F920 +๐Ÿฅณ partying face; U+1F973 +๐Ÿ˜Ž smiling face with sunglasses; U+1F60E +๐Ÿค“ nerd face; U+1F913 +๐Ÿง face with monocle; U+1F9D0 +๐Ÿ˜• confused face; U+1F615 +๐Ÿ˜Ÿ worried face; U+1F61F +๐Ÿ™ slightly frowning face; U+1F641 +โ˜น frowning face; U+2639 +๐Ÿ˜ฎ face with open mouth; U+1F62E +๐Ÿ˜ฏ hushed face; U+1F62F +๐Ÿ˜ฒ astonished face; U+1F632 +๐Ÿ˜ณ flushed face; U+1F633 +๐Ÿฅบ pleading face; U+1F97A +๐Ÿ˜ฆ frowning face with open mouth; U+1F626 +๐Ÿ˜ง anguished face; U+1F627 +๐Ÿ˜จ fearful face; U+1F628 +๐Ÿ˜ฐ anxious face with sweat; U+1F630 +๐Ÿ˜ฅ sad but relieved face; U+1F625 +๐Ÿ˜ข crying face; U+1F622 +๐Ÿ˜ญ loudly crying face; U+1F62D +๐Ÿ˜ฑ face screaming in fear; U+1F631 +๐Ÿ˜– confounded face; U+1F616 +๐Ÿ˜ฃ persevering face; U+1F623 +๐Ÿ˜ž disappointed face; U+1F61E +๐Ÿ˜“ downcast face with sweat; U+1F613 +๐Ÿ˜ฉ weary face; U+1F629 +๐Ÿ˜ซ tired face; U+1F62B +๐Ÿ˜ค face with steam from nose; U+1F624 +๐Ÿ˜ก pouting face; U+1F621 +๐Ÿ˜  angry face; U+1F620 +๐Ÿคฌ face with symbols on mouth; U+1F92C +๐Ÿ˜ˆ smiling face with horns; U+1F608 +๐Ÿ‘ฟ angry face with horns; U+1F47F +๐Ÿ’€ skull; U+1F480 +โ˜  skull and crossbones; U+2620 +๐Ÿ’ฉ pile of poo; U+1F4A9 +๐Ÿคก clown face; U+1F921 +๐Ÿ‘น ogre; U+1F479 +๐Ÿ‘บ goblin; U+1F47A +๐Ÿ‘ป ghost; U+1F47B +๐Ÿ‘ฝ alien; U+1F47D +๐Ÿ‘พ alien monster; U+1F47E +๐Ÿค– robot face; U+1F916 +๐Ÿ˜บ grinning cat face; U+1F63A +๐Ÿ˜ธ grinning cat face with smiling eyes; U+1F638 +๐Ÿ˜น cat face with tears of joy; U+1F639 +๐Ÿ˜ป smiling cat face with heart-eyes; U+1F63B +๐Ÿ˜ผ cat face with wry smile; U+1F63C +๐Ÿ˜ฝ kissing cat face; U+1F63D +๐Ÿ™€ weary cat face; U+1F640 +๐Ÿ˜ฟ crying cat face; U+1F63F +๐Ÿ˜พ pouting cat face; U+1F63E +๐Ÿ™ˆ see-no-evil monkey; U+1F648 +๐Ÿ™‰ hear-no-evil monkey; U+1F649 +๐Ÿ™Š speak-no-evil monkey; U+1F64A +๐Ÿ’‹ kiss mark; U+1F48B +๐Ÿ’Œ love letter; U+1F48C +๐Ÿ’˜ heart with arrow; U+1F498 +๐Ÿ’ heart with ribbon; U+1F49D +๐Ÿ’– sparkling heart; U+1F496 +๐Ÿ’— growing heart; U+1F497 +๐Ÿ’“ beating heart; U+1F493 +๐Ÿ’ž revolving hearts; U+1F49E +๐Ÿ’• two hearts; U+1F495 +๐Ÿ’Ÿ heart decoration; U+1F49F +โฃ heavy heart exclamation; U+2763 +๐Ÿ’” broken heart; U+1F494 +โค red heart; U+2764 +๐Ÿงก orange heart; U+1F9E1 +๐Ÿ’› yellow heart; U+1F49B +๐Ÿ’š green heart; U+1F49A +๐Ÿ’™ blue heart; U+1F499 +๐Ÿ’œ purple heart; U+1F49C +๐Ÿ–ค black heart; U+1F5A4 +๐Ÿ’ฏ hundred points; U+1F4AF +๐Ÿ’ข anger symbol; U+1F4A2 +๐Ÿ’ฅ collision; U+1F4A5 +๐Ÿ’ซ dizzy; U+1F4AB +๐Ÿ’ฆ sweat droplets; U+1F4A6 +๐Ÿ’จ dashing away; U+1F4A8 +๐Ÿ•ณ hole; U+1F573 +๐Ÿ’ฃ bomb; U+1F4A3 +๐Ÿ’ฌ speech balloon; U+1F4AC +๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ eye in speech bubble; U+1F441 U+FE0F U+200D U+1F5E8 U+FE0F +๐Ÿ—จ left speech bubble; U+1F5E8 +๐Ÿ—ฏ right anger bubble; U+1F5EF +๐Ÿ’ญ thought balloon; U+1F4AD +๐Ÿ’ค zzz; U+1F4A4 +๐Ÿ‘‹ waving hand; U+1F44B +๐Ÿคš raised back of hand; U+1F91A +๐Ÿ– hand with fingers splayed; U+1F590 +โœ‹ raised hand; U+270B +๐Ÿ–– vulcan salute; U+1F596 +๐Ÿ‘Œ OK hand; U+1F44C +โœŒ victory hand; U+270C +๐Ÿคž crossed fingers; U+1F91E +๐ŸคŸ love-you gesture; U+1F91F +๐Ÿค˜ sign of the horns; U+1F918 +๐Ÿค™ call me hand; U+1F919 +๐Ÿ‘ˆ backhand index pointing left; U+1F448 +๐Ÿ‘‰ backhand index pointing right; U+1F449 +๐Ÿ‘† backhand index pointing up; U+1F446 +๐Ÿ–• middle finger; U+1F595 +๐Ÿ‘‡ backhand index pointing down; U+1F447 +โ˜ index pointing up; U+261D +๐Ÿ‘ thumbs up; U+1F44D +๐Ÿ‘Ž thumbs down; U+1F44E +โœŠ raised fist; U+270A +๐Ÿ‘Š oncoming fist; U+1F44A +๐Ÿค› left-facing fist; U+1F91B +๐Ÿคœ right-facing fist; U+1F91C +๐Ÿ‘ clapping hands; U+1F44F +๐Ÿ™Œ raising hands; U+1F64C +๐Ÿ‘ open hands; U+1F450 +๐Ÿคฒ palms up together; U+1F932 +๐Ÿค handshake; U+1F91D +๐Ÿ™ folded hands; U+1F64F +โœ writing hand; U+270D +๐Ÿ’… nail polish; U+1F485 +๐Ÿคณ selfie; U+1F933 +๐Ÿ’ช flexed biceps; U+1F4AA +๐Ÿฆต leg; U+1F9B5 +๐Ÿฆถ foot; U+1F9B6 +๐Ÿ‘‚ ear; U+1F442 +๐Ÿ‘ƒ nose; U+1F443 +๐Ÿง  brain; U+1F9E0 +๐Ÿฆท tooth; U+1F9B7 +๐Ÿฆด bone; U+1F9B4 +๐Ÿ‘€ eyes; U+1F440 +๐Ÿ‘ eye; U+1F441 +๐Ÿ‘… tongue; U+1F445 +๐Ÿ‘„ mouth; U+1F444 +๐Ÿ‘ถ baby; U+1F476 +๐Ÿง’ child; U+1F9D2 +๐Ÿ‘ฆ boy; U+1F466 +๐Ÿ‘ง girl; U+1F467 +๐Ÿง‘ person; U+1F9D1 +๐Ÿ‘ฑ person: blond hair; U+1F471 +๐Ÿ‘จ man; U+1F468 +๐Ÿ‘ฑโ€โ™‚๏ธ man: blond hair; U+1F471 U+200D U+2642 U+FE0F +๐Ÿ‘จโ€๐Ÿฆฐ man: red hair; U+1F468 U+200D U+1F9B0 +๐Ÿ‘จโ€๐Ÿฆฑ man: curly hair; U+1F468 U+200D U+1F9B1 +๐Ÿ‘จโ€๐Ÿฆณ man: white hair; U+1F468 U+200D U+1F9B3 +๐Ÿ‘จโ€๐Ÿฆฒ man: bald; U+1F468 U+200D U+1F9B2 +๐Ÿง” man: beard; U+1F9D4 +๐Ÿ‘ฉ woman; U+1F469 +๐Ÿ‘ฑโ€โ™€๏ธ woman: blond hair; U+1F471 U+200D U+2640 U+FE0F +๐Ÿ‘ฉโ€๐Ÿฆฐ woman: red hair; U+1F469 U+200D U+1F9B0 +๐Ÿ‘ฉโ€๐Ÿฆฑ woman: curly hair; U+1F469 U+200D U+1F9B1 +๐Ÿ‘ฉโ€๐Ÿฆณ woman: white hair; U+1F469 U+200D U+1F9B3 +๐Ÿ‘ฉโ€๐Ÿฆฒ woman: bald; U+1F469 U+200D U+1F9B2 +๐Ÿง“ older person; U+1F9D3 +๐Ÿ‘ด old man; U+1F474 +๐Ÿ‘ต old woman; U+1F475 +๐Ÿ™ person frowning; U+1F64D +๐Ÿ™โ€โ™‚๏ธ man frowning; U+1F64D U+200D U+2642 U+FE0F +๐Ÿ™โ€โ™€๏ธ woman frowning; U+1F64D U+200D U+2640 U+FE0F +๐Ÿ™Ž person pouting; U+1F64E +๐Ÿ™Žโ€โ™‚๏ธ man pouting; U+1F64E U+200D U+2642 U+FE0F +๐Ÿ™Žโ€โ™€๏ธ woman pouting; U+1F64E U+200D U+2640 U+FE0F +๐Ÿ™… person gesturing NO; U+1F645 +๐Ÿ™…โ€โ™‚๏ธ man gesturing NO; U+1F645 U+200D U+2642 U+FE0F +๐Ÿ™…โ€โ™€๏ธ woman gesturing NO; U+1F645 U+200D U+2640 U+FE0F +๐Ÿ™† person gesturing OK; U+1F646 +๐Ÿ™†โ€โ™‚๏ธ man gesturing OK; U+1F646 U+200D U+2642 U+FE0F +๐Ÿ™†โ€โ™€๏ธ woman gesturing OK; U+1F646 U+200D U+2640 U+FE0F +๐Ÿ’ person tipping hand; U+1F481 +๐Ÿ’โ€โ™‚๏ธ man tipping hand; U+1F481 U+200D U+2642 U+FE0F +๐Ÿ’โ€โ™€๏ธ woman tipping hand; U+1F481 U+200D U+2640 U+FE0F +๐Ÿ™‹ person raising hand; U+1F64B +๐Ÿ™‹โ€โ™‚๏ธ man raising hand; U+1F64B U+200D U+2642 U+FE0F +๐Ÿ™‹โ€โ™€๏ธ woman raising hand; U+1F64B U+200D U+2640 U+FE0F +๐Ÿ™‡ person bowing; U+1F647 +๐Ÿ™‡โ€โ™‚๏ธ man bowing; U+1F647 U+200D U+2642 U+FE0F +๐Ÿ™‡โ€โ™€๏ธ woman bowing; U+1F647 U+200D U+2640 U+FE0F +๐Ÿคฆ person facepalming; U+1F926 +๐Ÿคฆโ€โ™‚๏ธ man facepalming; U+1F926 U+200D U+2642 U+FE0F +๐Ÿคฆโ€โ™€๏ธ woman facepalming; U+1F926 U+200D U+2640 U+FE0F +๐Ÿคท person shrugging; U+1F937 +๐Ÿคทโ€โ™‚๏ธ man shrugging; U+1F937 U+200D U+2642 U+FE0F +๐Ÿคทโ€โ™€๏ธ woman shrugging; U+1F937 U+200D U+2640 U+FE0F +๐Ÿ‘จโ€โš•๏ธ man health worker; U+1F468 U+200D U+2695 U+FE0F +๐Ÿ‘ฉโ€โš•๏ธ woman health worker; U+1F469 U+200D U+2695 U+FE0F +๐Ÿ‘จโ€๐ŸŽ“ man student; U+1F468 U+200D U+1F393 +๐Ÿ‘ฉโ€๐ŸŽ“ woman student; U+1F469 U+200D U+1F393 +๐Ÿ‘จโ€๐Ÿซ man teacher; U+1F468 U+200D U+1F3EB +๐Ÿ‘ฉโ€๐Ÿซ woman teacher; U+1F469 U+200D U+1F3EB +๐Ÿ‘จโ€โš–๏ธ man judge; U+1F468 U+200D U+2696 U+FE0F +๐Ÿ‘ฉโ€โš–๏ธ woman judge; U+1F469 U+200D U+2696 U+FE0F +๐Ÿ‘จโ€๐ŸŒพ man farmer; U+1F468 U+200D U+1F33E +๐Ÿ‘ฉโ€๐ŸŒพ woman farmer; U+1F469 U+200D U+1F33E +๐Ÿ‘จโ€๐Ÿณ man cook; U+1F468 U+200D U+1F373 +๐Ÿ‘ฉโ€๐Ÿณ woman cook; U+1F469 U+200D U+1F373 +๐Ÿ‘จโ€๐Ÿ”ง man mechanic; U+1F468 U+200D U+1F527 +๐Ÿ‘ฉโ€๐Ÿ”ง woman mechanic; U+1F469 U+200D U+1F527 +๐Ÿ‘จโ€๐Ÿญ man factory worker; U+1F468 U+200D U+1F3ED +๐Ÿ‘ฉโ€๐Ÿญ woman factory worker; U+1F469 U+200D U+1F3ED +๐Ÿ‘จโ€๐Ÿ’ผ man office worker; U+1F468 U+200D U+1F4BC +๐Ÿ‘ฉโ€๐Ÿ’ผ woman office worker; U+1F469 U+200D U+1F4BC +๐Ÿ‘จโ€๐Ÿ”ฌ man scientist; U+1F468 U+200D U+1F52C +๐Ÿ‘ฉโ€๐Ÿ”ฌ woman scientist; U+1F469 U+200D U+1F52C +๐Ÿ‘จโ€๐Ÿ’ป man technologist; U+1F468 U+200D U+1F4BB +๐Ÿ‘ฉโ€๐Ÿ’ป woman technologist; U+1F469 U+200D U+1F4BB +๐Ÿ‘จโ€๐ŸŽค man singer; U+1F468 U+200D U+1F3A4 +๐Ÿ‘ฉโ€๐ŸŽค woman singer; U+1F469 U+200D U+1F3A4 +๐Ÿ‘จโ€๐ŸŽจ man artist; U+1F468 U+200D U+1F3A8 +๐Ÿ‘ฉโ€๐ŸŽจ woman artist; U+1F469 U+200D U+1F3A8 +๐Ÿ‘จโ€โœˆ๏ธ man pilot; U+1F468 U+200D U+2708 U+FE0F +๐Ÿ‘ฉโ€โœˆ๏ธ woman pilot; U+1F469 U+200D U+2708 U+FE0F +๐Ÿ‘จโ€๐Ÿš€ man astronaut; U+1F468 U+200D U+1F680 +๐Ÿ‘ฉโ€๐Ÿš€ woman astronaut; U+1F469 U+200D U+1F680 +๐Ÿ‘จโ€๐Ÿš’ man firefighter; U+1F468 U+200D U+1F692 +๐Ÿ‘ฉโ€๐Ÿš’ woman firefighter; U+1F469 U+200D U+1F692 +๐Ÿ‘ฎ police officer; U+1F46E +๐Ÿ‘ฎโ€โ™‚๏ธ man police officer; U+1F46E U+200D U+2642 U+FE0F +๐Ÿ‘ฎโ€โ™€๏ธ woman police officer; U+1F46E U+200D U+2640 U+FE0F +๐Ÿ•ต detective; U+1F575 +๐Ÿ•ต๏ธโ€โ™‚๏ธ man detective; U+1F575 U+FE0F U+200D U+2642 U+FE0F +๐Ÿ•ต๏ธโ€โ™€๏ธ woman detective; U+1F575 U+FE0F U+200D U+2640 U+FE0F +๐Ÿ’‚ guard; U+1F482 +๐Ÿ’‚โ€โ™‚๏ธ man guard; U+1F482 U+200D U+2642 U+FE0F +๐Ÿ’‚โ€โ™€๏ธ woman guard; U+1F482 U+200D U+2640 U+FE0F +๐Ÿ‘ท construction worker; U+1F477 +๐Ÿ‘ทโ€โ™‚๏ธ man construction worker; U+1F477 U+200D U+2642 U+FE0F +๐Ÿ‘ทโ€โ™€๏ธ woman construction worker; U+1F477 U+200D U+2640 U+FE0F +๐Ÿคด prince; U+1F934 +๐Ÿ‘ธ princess; U+1F478 +๐Ÿ‘ณ person wearing turban; U+1F473 +๐Ÿ‘ณโ€โ™‚๏ธ man wearing turban; U+1F473 U+200D U+2642 U+FE0F +๐Ÿ‘ณโ€โ™€๏ธ woman wearing turban; U+1F473 U+200D U+2640 U+FE0F +๐Ÿ‘ฒ man with Chinese cap; U+1F472 +๐Ÿง• woman with headscarf; U+1F9D5 +๐Ÿคต man in tuxedo; U+1F935 +๐Ÿ‘ฐ bride with veil; U+1F470 +๐Ÿคฐ pregnant woman; U+1F930 +๐Ÿคฑ breast-feeding; U+1F931 +๐Ÿ‘ผ baby angel; U+1F47C +๐ŸŽ… Santa Claus; U+1F385 +๐Ÿคถ Mrs. Claus; U+1F936 +๐Ÿฆธ superhero; U+1F9B8 +๐Ÿฆธโ€โ™‚๏ธ man superhero; U+1F9B8 U+200D U+2642 U+FE0F +๐Ÿฆธโ€โ™€๏ธ woman superhero; U+1F9B8 U+200D U+2640 U+FE0F +๐Ÿฆน supervillain; U+1F9B9 +๐Ÿฆนโ€โ™‚๏ธ man supervillain; U+1F9B9 U+200D U+2642 U+FE0F +๐Ÿฆนโ€โ™€๏ธ woman supervillain; U+1F9B9 U+200D U+2640 U+FE0F +๐Ÿง™ mage; U+1F9D9 +๐Ÿง™โ€โ™‚๏ธ man mage; U+1F9D9 U+200D U+2642 U+FE0F +๐Ÿง™โ€โ™€๏ธ woman mage; U+1F9D9 U+200D U+2640 U+FE0F +๐Ÿงš fairy; U+1F9DA +๐Ÿงšโ€โ™‚๏ธ man fairy; U+1F9DA U+200D U+2642 U+FE0F +๐Ÿงšโ€โ™€๏ธ woman fairy; U+1F9DA U+200D U+2640 U+FE0F +๐Ÿง› vampire; U+1F9DB +๐Ÿง›โ€โ™‚๏ธ man vampire; U+1F9DB U+200D U+2642 U+FE0F +๐Ÿง›โ€โ™€๏ธ woman vampire; U+1F9DB U+200D U+2640 U+FE0F +๐Ÿงœ merperson; U+1F9DC +๐Ÿงœโ€โ™‚๏ธ merman; U+1F9DC U+200D U+2642 U+FE0F +๐Ÿงœโ€โ™€๏ธ mermaid; U+1F9DC U+200D U+2640 U+FE0F +๐Ÿง elf; U+1F9DD +๐Ÿงโ€โ™‚๏ธ man elf; U+1F9DD U+200D U+2642 U+FE0F +๐Ÿงโ€โ™€๏ธ woman elf; U+1F9DD U+200D U+2640 U+FE0F +๐Ÿงž genie; U+1F9DE +๐Ÿงžโ€โ™‚๏ธ man genie; U+1F9DE U+200D U+2642 U+FE0F +๐Ÿงžโ€โ™€๏ธ woman genie; U+1F9DE U+200D U+2640 U+FE0F +๐ŸงŸ zombie; U+1F9DF +๐ŸงŸโ€โ™‚๏ธ man zombie; U+1F9DF U+200D U+2642 U+FE0F +๐ŸงŸโ€โ™€๏ธ woman zombie; U+1F9DF U+200D U+2640 U+FE0F +๐Ÿ’† person getting massage; U+1F486 +๐Ÿ’†โ€โ™‚๏ธ man getting massage; U+1F486 U+200D U+2642 U+FE0F +๐Ÿ’†โ€โ™€๏ธ woman getting massage; U+1F486 U+200D U+2640 U+FE0F +๐Ÿ’‡ person getting haircut; U+1F487 +๐Ÿ’‡โ€โ™‚๏ธ man getting haircut; U+1F487 U+200D U+2642 U+FE0F +๐Ÿ’‡โ€โ™€๏ธ woman getting haircut; U+1F487 U+200D U+2640 U+FE0F +๐Ÿšถ person walking; U+1F6B6 +๐Ÿšถโ€โ™‚๏ธ man walking; U+1F6B6 U+200D U+2642 U+FE0F +๐Ÿšถโ€โ™€๏ธ woman walking; U+1F6B6 U+200D U+2640 U+FE0F +๐Ÿƒ person running; U+1F3C3 +๐Ÿƒโ€โ™‚๏ธ man running; U+1F3C3 U+200D U+2642 U+FE0F +๐Ÿƒโ€โ™€๏ธ woman running; U+1F3C3 U+200D U+2640 U+FE0F +๐Ÿ’ƒ woman dancing; U+1F483 +๐Ÿ•บ man dancing; U+1F57A +๐Ÿ•ด man in suit levitating; U+1F574 +๐Ÿ‘ฏ people with bunny ears; U+1F46F +๐Ÿ‘ฏโ€โ™‚๏ธ men with bunny ears; U+1F46F U+200D U+2642 U+FE0F +๐Ÿ‘ฏโ€โ™€๏ธ women with bunny ears; U+1F46F U+200D U+2640 U+FE0F +๐Ÿง– person in steamy room; U+1F9D6 +๐Ÿง–โ€โ™‚๏ธ man in steamy room; U+1F9D6 U+200D U+2642 U+FE0F +๐Ÿง–โ€โ™€๏ธ woman in steamy room; U+1F9D6 U+200D U+2640 U+FE0F +๐Ÿง— person climbing; U+1F9D7 +๐Ÿง—โ€โ™‚๏ธ man climbing; U+1F9D7 U+200D U+2642 U+FE0F +๐Ÿง—โ€โ™€๏ธ woman climbing; U+1F9D7 U+200D U+2640 U+FE0F +๐Ÿคบ person fencing; U+1F93A +๐Ÿ‡ horse racing; U+1F3C7 +โ›ท skier; U+26F7 +๐Ÿ‚ snowboarder; U+1F3C2 +๐ŸŒ person golfing; U+1F3CC +๐ŸŒ๏ธโ€โ™‚๏ธ man golfing; U+1F3CC U+FE0F U+200D U+2642 U+FE0F +๐ŸŒ๏ธโ€โ™€๏ธ woman golfing; U+1F3CC U+FE0F U+200D U+2640 U+FE0F +๐Ÿ„ person surfing; U+1F3C4 +๐Ÿ„โ€โ™‚๏ธ man surfing; U+1F3C4 U+200D U+2642 U+FE0F +๐Ÿ„โ€โ™€๏ธ woman surfing; U+1F3C4 U+200D U+2640 U+FE0F +๐Ÿšฃ person rowing boat; U+1F6A3 +๐Ÿšฃโ€โ™‚๏ธ man rowing boat; U+1F6A3 U+200D U+2642 U+FE0F +๐Ÿšฃโ€โ™€๏ธ woman rowing boat; U+1F6A3 U+200D U+2640 U+FE0F +๐ŸŠ person swimming; U+1F3CA +๐ŸŠโ€โ™‚๏ธ man swimming; U+1F3CA U+200D U+2642 U+FE0F +๐ŸŠโ€โ™€๏ธ woman swimming; U+1F3CA U+200D U+2640 U+FE0F +โ›น person bouncing ball; U+26F9 +โ›น๏ธโ€โ™‚๏ธ man bouncing ball; U+26F9 U+FE0F U+200D U+2642 U+FE0F +โ›น๏ธโ€โ™€๏ธ woman bouncing ball; U+26F9 U+FE0F U+200D U+2640 U+FE0F +๐Ÿ‹ person lifting weights; U+1F3CB +๐Ÿ‹๏ธโ€โ™‚๏ธ man lifting weights; U+1F3CB U+FE0F U+200D U+2642 U+FE0F +๐Ÿ‹๏ธโ€โ™€๏ธ woman lifting weights; U+1F3CB U+FE0F U+200D U+2640 U+FE0F +๐Ÿšด person biking; U+1F6B4 +๐Ÿšดโ€โ™‚๏ธ man biking; U+1F6B4 U+200D U+2642 U+FE0F +๐Ÿšดโ€โ™€๏ธ woman biking; U+1F6B4 U+200D U+2640 U+FE0F +๐Ÿšต person mountain biking; U+1F6B5 +๐Ÿšตโ€โ™‚๏ธ man mountain biking; U+1F6B5 U+200D U+2642 U+FE0F +๐Ÿšตโ€โ™€๏ธ woman mountain biking; U+1F6B5 U+200D U+2640 U+FE0F +๐Ÿคธ person cartwheeling; U+1F938 +๐Ÿคธโ€โ™‚๏ธ man cartwheeling; U+1F938 U+200D U+2642 U+FE0F +๐Ÿคธโ€โ™€๏ธ woman cartwheeling; U+1F938 U+200D U+2640 U+FE0F +๐Ÿคผ people wrestling; U+1F93C +๐Ÿคผโ€โ™‚๏ธ men wrestling; U+1F93C U+200D U+2642 U+FE0F +๐Ÿคผโ€โ™€๏ธ women wrestling; U+1F93C U+200D U+2640 U+FE0F +๐Ÿคฝ person playing water polo; U+1F93D +๐Ÿคฝโ€โ™‚๏ธ man playing water polo; U+1F93D U+200D U+2642 U+FE0F +๐Ÿคฝโ€โ™€๏ธ woman playing water polo; U+1F93D U+200D U+2640 U+FE0F +๐Ÿคพ person playing handball; U+1F93E +๐Ÿคพโ€โ™‚๏ธ man playing handball; U+1F93E U+200D U+2642 U+FE0F +๐Ÿคพโ€โ™€๏ธ woman playing handball; U+1F93E U+200D U+2640 U+FE0F +๐Ÿคน person juggling; U+1F939 +๐Ÿคนโ€โ™‚๏ธ man juggling; U+1F939 U+200D U+2642 U+FE0F +๐Ÿคนโ€โ™€๏ธ woman juggling; U+1F939 U+200D U+2640 U+FE0F +๐Ÿง˜ person in lotus position; U+1F9D8 +๐Ÿง˜โ€โ™‚๏ธ man in lotus position; U+1F9D8 U+200D U+2642 U+FE0F +๐Ÿง˜โ€โ™€๏ธ woman in lotus position; U+1F9D8 U+200D U+2640 U+FE0F +๐Ÿ›€ person taking bath; U+1F6C0 +๐Ÿ›Œ person in bed; U+1F6CC +๐Ÿ‘ญ women holding hands; U+1F46D +๐Ÿ‘ซ woman and man holding hands; U+1F46B +๐Ÿ‘ฌ men holding hands; U+1F46C +๐Ÿ’ kiss; U+1F48F +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ kiss: woman, man; U+1F469 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 +๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ kiss: man, man; U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ kiss: woman, woman; U+1F469 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F469 +๐Ÿ’‘ couple with heart; U+1F491 +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ couple with heart: woman, man; U+1F469 U+200D U+2764 U+FE0F U+200D U+1F468 +๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ couple with heart: man, man; U+1F468 U+200D U+2764 U+FE0F U+200D U+1F468 +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ couple with heart: woman, woman; U+1F469 U+200D U+2764 U+FE0F U+200D U+1F469 +๐Ÿ‘ช family; U+1F46A +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ family: man, woman, boy; U+1F468 U+200D U+1F469 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง family: man, woman, girl; U+1F468 U+200D U+1F469 U+200D U+1F467 +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family: man, woman, girl, boy; U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ family: man, woman, boy, boy; U+1F468 U+200D U+1F469 U+200D U+1F466 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง family: man, woman, girl, girl; U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F467 +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ family: man, man, boy; U+1F468 U+200D U+1F468 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ง family: man, man, girl; U+1F468 U+200D U+1F468 U+200D U+1F467 +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family: man, man, girl, boy; U+1F468 U+200D U+1F468 U+200D U+1F467 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ family: man, man, boy, boy; U+1F468 U+200D U+1F468 U+200D U+1F466 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง family: man, man, girl, girl; U+1F468 U+200D U+1F468 U+200D U+1F467 U+200D U+1F467 +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ family: woman, woman, boy; U+1F469 U+200D U+1F469 U+200D U+1F466 +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ง family: woman, woman, girl; U+1F469 U+200D U+1F469 U+200D U+1F467 +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family: woman, woman, girl, boy; U+1F469 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ family: woman, woman, boy, boy; U+1F469 U+200D U+1F469 U+200D U+1F466 U+200D U+1F466 +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง family: woman, woman, girl, girl; U+1F469 U+200D U+1F469 U+200D U+1F467 U+200D U+1F467 +๐Ÿ‘จโ€๐Ÿ‘ฆ family: man, boy; U+1F468 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ family: man, boy, boy; U+1F468 U+200D U+1F466 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘ง family: man, girl; U+1F468 U+200D U+1F467 +๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family: man, girl, boy; U+1F468 U+200D U+1F467 U+200D U+1F466 +๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง family: man, girl, girl; U+1F468 U+200D U+1F467 U+200D U+1F467 +๐Ÿ‘ฉโ€๐Ÿ‘ฆ family: woman, boy; U+1F469 U+200D U+1F466 +๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ family: woman, boy, boy; U+1F469 U+200D U+1F466 U+200D U+1F466 +๐Ÿ‘ฉโ€๐Ÿ‘ง family: woman, girl; U+1F469 U+200D U+1F467 +๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family: woman, girl, boy; U+1F469 U+200D U+1F467 U+200D U+1F466 +๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง family: woman, girl, girl; U+1F469 U+200D U+1F467 U+200D U+1F467 +๐Ÿ—ฃ speaking head; U+1F5E3 +๐Ÿ‘ค bust in silhouette; U+1F464 +๐Ÿ‘ฅ busts in silhouette; U+1F465 +๐Ÿ‘ฃ footprints; U+1F463 +๐Ÿฆฐ red hair; U+1F9B0 +๐Ÿฆฑ curly hair; U+1F9B1 +๐Ÿฆณ white hair; U+1F9B3 +๐Ÿฆฒ bald; U+1F9B2 +๐Ÿต monkey face; U+1F435 +๐Ÿ’ monkey; U+1F412 +๐Ÿฆ gorilla; U+1F98D +๐Ÿถ dog face; U+1F436 +๐Ÿ• dog; U+1F415 +๐Ÿฉ poodle; U+1F429 +๐Ÿบ wolf face; U+1F43A +๐ŸฆŠ fox face; U+1F98A +๐Ÿฆ raccoon; U+1F99D +๐Ÿฑ cat face; U+1F431 +๐Ÿˆ cat; U+1F408 +๐Ÿฆ lion face; U+1F981 +๐Ÿฏ tiger face; U+1F42F +๐Ÿ… tiger; U+1F405 +๐Ÿ† leopard; U+1F406 +๐Ÿด horse face; U+1F434 +๐ŸŽ horse; U+1F40E +๐Ÿฆ„ unicorn face; U+1F984 +๐Ÿฆ“ zebra; U+1F993 +๐ŸฆŒ deer; U+1F98C +๐Ÿฎ cow face; U+1F42E +๐Ÿ‚ ox; U+1F402 +๐Ÿƒ water buffalo; U+1F403 +๐Ÿ„ cow; U+1F404 +๐Ÿท pig face; U+1F437 +๐Ÿ– pig; U+1F416 +๐Ÿ— boar; U+1F417 +๐Ÿฝ pig nose; U+1F43D +๐Ÿ ram; U+1F40F +๐Ÿ‘ ewe; U+1F411 +๐Ÿ goat; U+1F410 +๐Ÿช camel; U+1F42A +๐Ÿซ two-hump camel; U+1F42B +๐Ÿฆ™ llama; U+1F999 +๐Ÿฆ’ giraffe; U+1F992 +๐Ÿ˜ elephant; U+1F418 +๐Ÿฆ rhinoceros; U+1F98F +๐Ÿฆ› hippopotamus; U+1F99B +๐Ÿญ mouse face; U+1F42D +๐Ÿ mouse; U+1F401 +๐Ÿ€ rat; U+1F400 +๐Ÿน hamster face; U+1F439 +๐Ÿฐ rabbit face; U+1F430 +๐Ÿ‡ rabbit; U+1F407 +๐Ÿฟ chipmunk; U+1F43F +๐Ÿฆ” hedgehog; U+1F994 +๐Ÿฆ‡ bat; U+1F987 +๐Ÿป bear face; U+1F43B +๐Ÿจ koala; U+1F428 +๐Ÿผ panda face; U+1F43C +๐Ÿฆ˜ kangaroo; U+1F998 +๐Ÿฆก badger; U+1F9A1 +๐Ÿพ paw prints; U+1F43E +๐Ÿฆƒ turkey; U+1F983 +๐Ÿ” chicken; U+1F414 +๐Ÿ“ rooster; U+1F413 +๐Ÿฃ hatching chick; U+1F423 +๐Ÿค baby chick; U+1F424 +๐Ÿฅ front-facing baby chick; U+1F425 +๐Ÿฆ bird; U+1F426 +๐Ÿง penguin; U+1F427 +๐Ÿ•Š dove; U+1F54A +๐Ÿฆ… eagle; U+1F985 +๐Ÿฆ† duck; U+1F986 +๐Ÿฆข swan; U+1F9A2 +๐Ÿฆ‰ owl; U+1F989 +๐Ÿฆš peacock; U+1F99A +๐Ÿฆœ parrot; U+1F99C +๐Ÿธ frog face; U+1F438 +๐ŸŠ crocodile; U+1F40A +๐Ÿข turtle; U+1F422 +๐ŸฆŽ lizard; U+1F98E +๐Ÿ snake; U+1F40D +๐Ÿฒ dragon face; U+1F432 +๐Ÿ‰ dragon; U+1F409 +๐Ÿฆ• sauropod; U+1F995 +๐Ÿฆ– T-Rex; U+1F996 +๐Ÿณ spouting whale; U+1F433 +๐Ÿ‹ whale; U+1F40B +๐Ÿฌ dolphin; U+1F42C +๐ŸŸ fish; U+1F41F +๐Ÿ  tropical fish; U+1F420 +๐Ÿก blowfish; U+1F421 +๐Ÿฆˆ shark; U+1F988 +๐Ÿ™ octopus; U+1F419 +๐Ÿš spiral shell; U+1F41A +๐ŸŒ snail; U+1F40C +๐Ÿฆ‹ butterfly; U+1F98B +๐Ÿ› bug; U+1F41B +๐Ÿœ ant; U+1F41C +๐Ÿ honeybee; U+1F41D +๐Ÿž lady beetle; U+1F41E +๐Ÿฆ— cricket; U+1F997 +๐Ÿ•ท spider; U+1F577 +๐Ÿ•ธ spider web; U+1F578 +๐Ÿฆ‚ scorpion; U+1F982 +๐ŸฆŸ mosquito; U+1F99F +๐Ÿฆ  microbe; U+1F9A0 +๐Ÿ’ bouquet; U+1F490 +๐ŸŒธ cherry blossom; U+1F338 +๐Ÿ’ฎ white flower; U+1F4AE +๐Ÿต rosette; U+1F3F5 +๐ŸŒน rose; U+1F339 +๐Ÿฅ€ wilted flower; U+1F940 +๐ŸŒบ hibiscus; U+1F33A +๐ŸŒป sunflower; U+1F33B +๐ŸŒผ blossom; U+1F33C +๐ŸŒท tulip; U+1F337 +๐ŸŒฑ seedling; U+1F331 +๐ŸŒฒ evergreen tree; U+1F332 +๐ŸŒณ deciduous tree; U+1F333 +๐ŸŒด palm tree; U+1F334 +๐ŸŒต cactus; U+1F335 +๐ŸŒพ sheaf of rice; U+1F33E +๐ŸŒฟ herb; U+1F33F +โ˜˜ shamrock; U+2618 +๐Ÿ€ four leaf clover; U+1F340 +๐Ÿ maple leaf; U+1F341 +๐Ÿ‚ fallen leaf; U+1F342 +๐Ÿƒ leaf fluttering in wind; U+1F343 +๐Ÿ‡ grapes; U+1F347 +๐Ÿˆ melon; U+1F348 +๐Ÿ‰ watermelon; U+1F349 +๐ŸŠ tangerine; U+1F34A +๐Ÿ‹ lemon; U+1F34B +๐ŸŒ banana; U+1F34C +๐Ÿ pineapple; U+1F34D +๐Ÿฅญ mango; U+1F96D +๐ŸŽ red apple; U+1F34E +๐Ÿ green apple; U+1F34F +๐Ÿ pear; U+1F350 +๐Ÿ‘ peach; U+1F351 +๐Ÿ’ cherries; U+1F352 +๐Ÿ“ strawberry; U+1F353 +๐Ÿฅ kiwi fruit; U+1F95D +๐Ÿ… tomato; U+1F345 +๐Ÿฅฅ coconut; U+1F965 +๐Ÿฅ‘ avocado; U+1F951 +๐Ÿ† eggplant; U+1F346 +๐Ÿฅ” potato; U+1F954 +๐Ÿฅ• carrot; U+1F955 +๐ŸŒฝ ear of corn; U+1F33D +๐ŸŒถ hot pepper; U+1F336 +๐Ÿฅ’ cucumber; U+1F952 +๐Ÿฅฌ leafy green; U+1F96C +๐Ÿฅฆ broccoli; U+1F966 +๐Ÿ„ mushroom; U+1F344 +๐Ÿฅœ peanuts; U+1F95C +๐ŸŒฐ chestnut; U+1F330 +๐Ÿž bread; U+1F35E +๐Ÿฅ croissant; U+1F950 +๐Ÿฅ– baguette bread; U+1F956 +๐Ÿฅจ pretzel; U+1F968 +๐Ÿฅฏ bagel; U+1F96F +๐Ÿฅž pancakes; U+1F95E +๐Ÿง€ cheese wedge; U+1F9C0 +๐Ÿ– meat on bone; U+1F356 +๐Ÿ— poultry leg; U+1F357 +๐Ÿฅฉ cut of meat; U+1F969 +๐Ÿฅ“ bacon; U+1F953 +๐Ÿ” hamburger; U+1F354 +๐ŸŸ french fries; U+1F35F +๐Ÿ• pizza; U+1F355 +๐ŸŒญ hot dog; U+1F32D +๐Ÿฅช sandwich; U+1F96A +๐ŸŒฎ taco; U+1F32E +๐ŸŒฏ burrito; U+1F32F +๐Ÿฅ™ stuffed flatbread; U+1F959 +๐Ÿฅš egg; U+1F95A +๐Ÿณ cooking; U+1F373 +๐Ÿฅ˜ shallow pan of food; U+1F958 +๐Ÿฒ pot of food; U+1F372 +๐Ÿฅฃ bowl with spoon; U+1F963 +๐Ÿฅ— green salad; U+1F957 +๐Ÿฟ popcorn; U+1F37F +๐Ÿง‚ salt; U+1F9C2 +๐Ÿฅซ canned food; U+1F96B +๐Ÿฑ bento box; U+1F371 +๐Ÿ˜ rice cracker; U+1F358 +๐Ÿ™ rice ball; U+1F359 +๐Ÿš cooked rice; U+1F35A +๐Ÿ› curry rice; U+1F35B +๐Ÿœ steaming bowl; U+1F35C +๐Ÿ spaghetti; U+1F35D +๐Ÿ  roasted sweet potato; U+1F360 +๐Ÿข oden; U+1F362 +๐Ÿฃ sushi; U+1F363 +๐Ÿค fried shrimp; U+1F364 +๐Ÿฅ fish cake with swirl; U+1F365 +๐Ÿฅฎ moon cake; U+1F96E +๐Ÿก dango; U+1F361 +๐ŸฅŸ dumpling; U+1F95F +๐Ÿฅ  fortune cookie; U+1F960 +๐Ÿฅก takeout box; U+1F961 +๐Ÿฆ€ crab; U+1F980 +๐Ÿฆž lobster; U+1F99E +๐Ÿฆ shrimp; U+1F990 +๐Ÿฆ‘ squid; U+1F991 +๐Ÿฆ soft ice cream; U+1F366 +๐Ÿง shaved ice; U+1F367 +๐Ÿจ ice cream; U+1F368 +๐Ÿฉ doughnut; U+1F369 +๐Ÿช cookie; U+1F36A +๐ŸŽ‚ birthday cake; U+1F382 +๐Ÿฐ shortcake; U+1F370 +๐Ÿง cupcake; U+1F9C1 +๐Ÿฅง pie; U+1F967 +๐Ÿซ chocolate bar; U+1F36B +๐Ÿฌ candy; U+1F36C +๐Ÿญ lollipop; U+1F36D +๐Ÿฎ custard; U+1F36E +๐Ÿฏ honey pot; U+1F36F +๐Ÿผ baby bottle; U+1F37C +๐Ÿฅ› glass of milk; U+1F95B +โ˜• hot beverage; U+2615 +๐Ÿต teacup without handle; U+1F375 +๐Ÿถ sake; U+1F376 +๐Ÿพ bottle with popping cork; U+1F37E +๐Ÿท wine glass; U+1F377 +๐Ÿธ cocktail glass; U+1F378 +๐Ÿน tropical drink; U+1F379 +๐Ÿบ beer mug; U+1F37A +๐Ÿป clinking beer mugs; U+1F37B +๐Ÿฅ‚ clinking glasses; U+1F942 +๐Ÿฅƒ tumbler glass; U+1F943 +๐Ÿฅค cup with straw; U+1F964 +๐Ÿฅข chopsticks; U+1F962 +๐Ÿฝ fork and knife with plate; U+1F37D +๐Ÿด fork and knife; U+1F374 +๐Ÿฅ„ spoon; U+1F944 +๐Ÿ”ช kitchen knife; U+1F52A +๐Ÿบ amphora; U+1F3FA +๐ŸŒ globe showing Europe-Africa; U+1F30D +๐ŸŒŽ globe showing Americas; U+1F30E +๐ŸŒ globe showing Asia-Australia; U+1F30F +๐ŸŒ globe with meridians; U+1F310 +๐Ÿ—บ world map; U+1F5FA +๐Ÿ—พ map of Japan; U+1F5FE +๐Ÿงญ compass; U+1F9ED +๐Ÿ” snow-capped mountain; U+1F3D4 +โ›ฐ mountain; U+26F0 +๐ŸŒ‹ volcano; U+1F30B +๐Ÿ—ป mount fuji; U+1F5FB +๐Ÿ• camping; U+1F3D5 +๐Ÿ– beach with umbrella; U+1F3D6 +๐Ÿœ desert; U+1F3DC +๐Ÿ desert island; U+1F3DD +๐Ÿž national park; U+1F3DE +๐ŸŸ stadium; U+1F3DF +๐Ÿ› classical building; U+1F3DB +๐Ÿ— building construction; U+1F3D7 +๐Ÿงฑ brick; U+1F9F1 +๐Ÿ˜ houses; U+1F3D8 +๐Ÿš derelict house; U+1F3DA +๐Ÿ  house; U+1F3E0 +๐Ÿก house with garden; U+1F3E1 +๐Ÿข office building; U+1F3E2 +๐Ÿฃ Japanese post office; U+1F3E3 +๐Ÿค post office; U+1F3E4 +๐Ÿฅ hospital; U+1F3E5 +๐Ÿฆ bank; U+1F3E6 +๐Ÿจ hotel; U+1F3E8 +๐Ÿฉ love hotel; U+1F3E9 +๐Ÿช convenience store; U+1F3EA +๐Ÿซ school; U+1F3EB +๐Ÿฌ department store; U+1F3EC +๐Ÿญ factory; U+1F3ED +๐Ÿฏ Japanese castle; U+1F3EF +๐Ÿฐ castle; U+1F3F0 +๐Ÿ’’ wedding; U+1F492 +๐Ÿ—ผ Tokyo tower; U+1F5FC +๐Ÿ—ฝ Statue of Liberty; U+1F5FD +โ›ช church; U+26EA +๐Ÿ•Œ mosque; U+1F54C +๐Ÿ• synagogue; U+1F54D +โ›ฉ shinto shrine; U+26E9 +๐Ÿ•‹ kaaba; U+1F54B +โ›ฒ fountain; U+26F2 +โ›บ tent; U+26FA +๐ŸŒ foggy; U+1F301 +๐ŸŒƒ night with stars; U+1F303 +๐Ÿ™ cityscape; U+1F3D9 +๐ŸŒ„ sunrise over mountains; U+1F304 +๐ŸŒ… sunrise; U+1F305 +๐ŸŒ† cityscape at dusk; U+1F306 +๐ŸŒ‡ sunset; U+1F307 +๐ŸŒ‰ bridge at night; U+1F309 +โ™จ hot springs; U+2668 +๐ŸŒŒ milky way; U+1F30C +๐ŸŽ  carousel horse; U+1F3A0 +๐ŸŽก ferris wheel; U+1F3A1 +๐ŸŽข roller coaster; U+1F3A2 +๐Ÿ’ˆ barber pole; U+1F488 +๐ŸŽช circus tent; U+1F3AA +๐Ÿš‚ locomotive; U+1F682 +๐Ÿšƒ railway car; U+1F683 +๐Ÿš„ high-speed train; U+1F684 +๐Ÿš… bullet train; U+1F685 +๐Ÿš† train; U+1F686 +๐Ÿš‡ metro; U+1F687 +๐Ÿšˆ light rail; U+1F688 +๐Ÿš‰ station; U+1F689 +๐ŸšŠ tram; U+1F68A +๐Ÿš monorail; U+1F69D +๐Ÿšž mountain railway; U+1F69E +๐Ÿš‹ tram car; U+1F68B +๐ŸšŒ bus; U+1F68C +๐Ÿš oncoming bus; U+1F68D +๐ŸšŽ trolleybus; U+1F68E +๐Ÿš minibus; U+1F690 +๐Ÿš‘ ambulance; U+1F691 +๐Ÿš’ fire engine; U+1F692 +๐Ÿš“ police car; U+1F693 +๐Ÿš” oncoming police car; U+1F694 +๐Ÿš• taxi; U+1F695 +๐Ÿš– oncoming taxi; U+1F696 +๐Ÿš— automobile; U+1F697 +๐Ÿš˜ oncoming automobile; U+1F698 +๐Ÿš™ sport utility vehicle; U+1F699 +๐Ÿšš delivery truck; U+1F69A +๐Ÿš› articulated lorry; U+1F69B +๐Ÿšœ tractor; U+1F69C +๐ŸŽ racing car; U+1F3CE +๐Ÿ motorcycle; U+1F3CD +๐Ÿ›ต motor scooter; U+1F6F5 +๐Ÿšฒ bicycle; U+1F6B2 +๐Ÿ›ด kick scooter; U+1F6F4 +๐Ÿ›น skateboard; U+1F6F9 +๐Ÿš bus stop; U+1F68F +๐Ÿ›ฃ motorway; U+1F6E3 +๐Ÿ›ค railway track; U+1F6E4 +๐Ÿ›ข oil drum; U+1F6E2 +โ›ฝ fuel pump; U+26FD +๐Ÿšจ police car light; U+1F6A8 +๐Ÿšฅ horizontal traffic light; U+1F6A5 +๐Ÿšฆ vertical traffic light; U+1F6A6 +๐Ÿ›‘ stop sign; U+1F6D1 +๐Ÿšง construction; U+1F6A7 +โš“ anchor; U+2693 +โ›ต sailboat; U+26F5 +๐Ÿ›ถ canoe; U+1F6F6 +๐Ÿšค speedboat; U+1F6A4 +๐Ÿ›ณ passenger ship; U+1F6F3 +โ›ด ferry; U+26F4 +๐Ÿ›ฅ motor boat; U+1F6E5 +๐Ÿšข ship; U+1F6A2 +โœˆ airplane; U+2708 +๐Ÿ›ฉ small airplane; U+1F6E9 +๐Ÿ›ซ airplane departure; U+1F6EB +๐Ÿ›ฌ airplane arrival; U+1F6EC +๐Ÿ’บ seat; U+1F4BA +๐Ÿš helicopter; U+1F681 +๐ŸšŸ suspension railway; U+1F69F +๐Ÿš  mountain cableway; U+1F6A0 +๐Ÿšก aerial tramway; U+1F6A1 +๐Ÿ›ฐ satellite; U+1F6F0 +๐Ÿš€ rocket; U+1F680 +๐Ÿ›ธ flying saucer; U+1F6F8 +๐Ÿ›Ž bellhop bell; U+1F6CE +๐Ÿงณ luggage; U+1F9F3 +โŒ› hourglass done; U+231B +โณ hourglass not done; U+23F3 +โŒš watch; U+231A +โฐ alarm clock; U+23F0 +โฑ stopwatch; U+23F1 +โฒ timer clock; U+23F2 +๐Ÿ•ฐ mantelpiece clock; U+1F570 +๐Ÿ•› twelve oโ€™clock; U+1F55B +๐Ÿ•ง twelve-thirty; U+1F567 +๐Ÿ• one oโ€™clock; U+1F550 +๐Ÿ•œ one-thirty; U+1F55C +๐Ÿ•‘ two oโ€™clock; U+1F551 +๐Ÿ• two-thirty; U+1F55D +๐Ÿ•’ three oโ€™clock; U+1F552 +๐Ÿ•ž three-thirty; U+1F55E +๐Ÿ•“ four oโ€™clock; U+1F553 +๐Ÿ•Ÿ four-thirty; U+1F55F +๐Ÿ•” five oโ€™clock; U+1F554 +๐Ÿ•  five-thirty; U+1F560 +๐Ÿ•• six oโ€™clock; U+1F555 +๐Ÿ•ก six-thirty; U+1F561 +๐Ÿ•– seven oโ€™clock; U+1F556 +๐Ÿ•ข seven-thirty; U+1F562 +๐Ÿ•— eight oโ€™clock; U+1F557 +๐Ÿ•ฃ eight-thirty; U+1F563 +๐Ÿ•˜ nine oโ€™clock; U+1F558 +๐Ÿ•ค nine-thirty; U+1F564 +๐Ÿ•™ ten oโ€™clock; U+1F559 +๐Ÿ•ฅ ten-thirty; U+1F565 +๐Ÿ•š eleven oโ€™clock; U+1F55A +๐Ÿ•ฆ eleven-thirty; U+1F566 +๐ŸŒ‘ new moon; U+1F311 +๐ŸŒ’ waxing crescent moon; U+1F312 +๐ŸŒ“ first quarter moon; U+1F313 +๐ŸŒ” waxing gibbous moon; U+1F314 +๐ŸŒ• full moon; U+1F315 +๐ŸŒ– waning gibbous moon; U+1F316 +๐ŸŒ— last quarter moon; U+1F317 +๐ŸŒ˜ waning crescent moon; U+1F318 +๐ŸŒ™ crescent moon; U+1F319 +๐ŸŒš new moon face; U+1F31A +๐ŸŒ› first quarter moon face; U+1F31B +๐ŸŒœ last quarter moon face; U+1F31C +๐ŸŒก thermometer; U+1F321 +โ˜€ sun; U+2600 +๐ŸŒ full moon face; U+1F31D +๐ŸŒž sun with face; U+1F31E +โญ star; U+2B50 +๐ŸŒŸ glowing star; U+1F31F +๐ŸŒ  shooting star; U+1F320 +โ˜ cloud; U+2601 +โ›… sun behind cloud; U+26C5 +โ›ˆ cloud with lightning and rain; U+26C8 +๐ŸŒค sun behind small cloud; U+1F324 +๐ŸŒฅ sun behind large cloud; U+1F325 +๐ŸŒฆ sun behind rain cloud; U+1F326 +๐ŸŒง cloud with rain; U+1F327 +๐ŸŒจ cloud with snow; U+1F328 +๐ŸŒฉ cloud with lightning; U+1F329 +๐ŸŒช tornado; U+1F32A +๐ŸŒซ fog; U+1F32B +๐ŸŒฌ wind face; U+1F32C +๐ŸŒ€ cyclone; U+1F300 +๐ŸŒˆ rainbow; U+1F308 +๐ŸŒ‚ closed umbrella; U+1F302 +โ˜‚ umbrella; U+2602 +โ˜” umbrella with rain drops; U+2614 +โ›ฑ umbrella on ground; U+26F1 +โšก high voltage; U+26A1 +โ„ snowflake; U+2744 +โ˜ƒ snowman; U+2603 +โ›„ snowman without snow; U+26C4 +โ˜„ comet; U+2604 +๐Ÿ”ฅ fire; U+1F525 +๐Ÿ’ง droplet; U+1F4A7 +๐ŸŒŠ water wave; U+1F30A +๐ŸŽƒ jack-o-lantern; U+1F383 +๐ŸŽ„ Christmas tree; U+1F384 +๐ŸŽ† fireworks; U+1F386 +๐ŸŽ‡ sparkler; U+1F387 +๐Ÿงจ firecracker; U+1F9E8 +โœจ sparkles; U+2728 +๐ŸŽˆ balloon; U+1F388 +๐ŸŽ‰ party popper; U+1F389 +๐ŸŽŠ confetti ball; U+1F38A +๐ŸŽ‹ tanabata tree; U+1F38B +๐ŸŽ pine decoration; U+1F38D +๐ŸŽŽ Japanese dolls; U+1F38E +๐ŸŽ carp streamer; U+1F38F +๐ŸŽ wind chime; U+1F390 +๐ŸŽ‘ moon viewing ceremony; U+1F391 +๐Ÿงง red envelope; U+1F9E7 +๐ŸŽ€ ribbon; U+1F380 +๐ŸŽ wrapped gift; U+1F381 +๐ŸŽ— reminder ribbon; U+1F397 +๐ŸŽŸ admission tickets; U+1F39F +๐ŸŽซ ticket; U+1F3AB +๐ŸŽ– military medal; U+1F396 +๐Ÿ† trophy; U+1F3C6 +๐Ÿ… sports medal; U+1F3C5 +1st place medal; U+1F947 ๐Ÿฅ‡ +2nd place medal; U+1F948 ๐Ÿฅˆ +3rd place medal; U+1F949 ๐Ÿฅ‰ +โšฝ soccer ball; U+26BD +โšพ baseball; U+26BE +๐ŸฅŽ softball; U+1F94E +๐Ÿ€ basketball; U+1F3C0 +๐Ÿ volleyball; U+1F3D0 +๐Ÿˆ american football; U+1F3C8 +๐Ÿ‰ rugby football; U+1F3C9 +๐ŸŽพ tennis; U+1F3BE +๐Ÿฅ flying disc; U+1F94F +๐ŸŽณ bowling; U+1F3B3 +๐Ÿ cricket game; U+1F3CF +๐Ÿ‘ field hockey; U+1F3D1 +๐Ÿ’ ice hockey; U+1F3D2 +๐Ÿฅ lacrosse; U+1F94D +๐Ÿ“ ping pong; U+1F3D3 +๐Ÿธ badminton; U+1F3F8 +๐ŸฅŠ boxing glove; U+1F94A +๐Ÿฅ‹ martial arts uniform; U+1F94B +๐Ÿฅ… goal net; U+1F945 +โ›ณ flag in hole; U+26F3 +โ›ธ ice skate; U+26F8 +๐ŸŽฃ fishing pole; U+1F3A3 +๐ŸŽฝ running shirt; U+1F3BD +๐ŸŽฟ skis; U+1F3BF +๐Ÿ›ท sled; U+1F6F7 +๐ŸฅŒ curling stone; U+1F94C +๐ŸŽฏ direct hit; U+1F3AF +๐ŸŽฑ pool 8 ball; U+1F3B1 +๐Ÿ”ฎ crystal ball; U+1F52E +๐Ÿงฟ nazar amulet; U+1F9FF +๐ŸŽฎ video game; U+1F3AE +๐Ÿ•น joystick; U+1F579 +๐ŸŽฐ slot machine; U+1F3B0 +๐ŸŽฒ game die; U+1F3B2 +๐Ÿงฉ jigsaw; U+1F9E9 +๐Ÿงธ teddy bear; U+1F9F8 +โ™  spade suit; U+2660 +โ™ฅ heart suit; U+2665 +โ™ฆ diamond suit; U+2666 +โ™ฃ club suit; U+2663 +โ™Ÿ chess pawn; U+265F +๐Ÿƒ joker; U+1F0CF +๐Ÿ€„ mahjong red dragon; U+1F004 +๐ŸŽด flower playing cards; U+1F3B4 +๐ŸŽญ performing arts; U+1F3AD +๐Ÿ–ผ framed picture; U+1F5BC +๐ŸŽจ artist palette; U+1F3A8 +๐Ÿงต thread; U+1F9F5 +๐Ÿงถ yarn; U+1F9F6 +๐Ÿ‘“ glasses; U+1F453 +๐Ÿ•ถ sunglasses; U+1F576 +๐Ÿฅฝ goggles; U+1F97D +๐Ÿฅผ lab coat; U+1F97C +๐Ÿ‘” necktie; U+1F454 +๐Ÿ‘• t-shirt; U+1F455 +๐Ÿ‘– jeans; U+1F456 +๐Ÿงฃ scarf; U+1F9E3 +๐Ÿงค gloves; U+1F9E4 +๐Ÿงฅ coat; U+1F9E5 +๐Ÿงฆ socks; U+1F9E6 +๐Ÿ‘— dress; U+1F457 +๐Ÿ‘˜ kimono; U+1F458 +๐Ÿ‘™ bikini; U+1F459 +๐Ÿ‘š womanโ€™s clothes; U+1F45A +๐Ÿ‘› purse; U+1F45B +๐Ÿ‘œ handbag; U+1F45C +๐Ÿ‘ clutch bag; U+1F45D +๐Ÿ› shopping bags; U+1F6CD +๐ŸŽ’ backpack; U+1F392 +๐Ÿ‘ž manโ€™s shoe; U+1F45E +๐Ÿ‘Ÿ running shoe; U+1F45F +๐Ÿฅพ hiking boot; U+1F97E +๐Ÿฅฟ flat shoe; U+1F97F +๐Ÿ‘  high-heeled shoe; U+1F460 +๐Ÿ‘ก womanโ€™s sandal; U+1F461 +๐Ÿ‘ข womanโ€™s boot; U+1F462 +๐Ÿ‘‘ crown; U+1F451 +๐Ÿ‘’ womanโ€™s hat; U+1F452 +๐ŸŽฉ top hat; U+1F3A9 +๐ŸŽ“ graduation cap; U+1F393 +๐Ÿงข billed cap; U+1F9E2 +โ›‘ rescue workerโ€™s helmet; U+26D1 +๐Ÿ“ฟ prayer beads; U+1F4FF +๐Ÿ’„ lipstick; U+1F484 +๐Ÿ’ ring; U+1F48D +๐Ÿ’Ž gem stone; U+1F48E +๐Ÿ”‡ muted speaker; U+1F507 +๐Ÿ”ˆ speaker low volume; U+1F508 +๐Ÿ”‰ speaker medium volume; U+1F509 +๐Ÿ”Š speaker high volume; U+1F50A +๐Ÿ“ข loudspeaker; U+1F4E2 +๐Ÿ“ฃ megaphone; U+1F4E3 +๐Ÿ“ฏ postal horn; U+1F4EF +๐Ÿ”” bell; U+1F514 +๐Ÿ”• bell with slash; U+1F515 +๐ŸŽผ musical score; U+1F3BC +๐ŸŽต musical note; U+1F3B5 +๐ŸŽถ musical notes; U+1F3B6 +๐ŸŽ™ studio microphone; U+1F399 +๐ŸŽš level slider; U+1F39A +๐ŸŽ› control knobs; U+1F39B +๐ŸŽค microphone; U+1F3A4 +๐ŸŽง headphone; U+1F3A7 +๐Ÿ“ป radio; U+1F4FB +๐ŸŽท saxophone; U+1F3B7 +๐ŸŽธ guitar; U+1F3B8 +๐ŸŽน musical keyboard; U+1F3B9 +๐ŸŽบ trumpet; U+1F3BA +๐ŸŽป violin; U+1F3BB +๐Ÿฅ drum; U+1F941 +๐Ÿ“ฑ mobile phone; U+1F4F1 +๐Ÿ“ฒ mobile phone with arrow; U+1F4F2 +โ˜Ž telephone; U+260E +๐Ÿ“ž telephone receiver; U+1F4DE +๐Ÿ“Ÿ pager; U+1F4DF +๐Ÿ“  fax machine; U+1F4E0 +๐Ÿ”‹ battery; U+1F50B +๐Ÿ”Œ electric plug; U+1F50C +๐Ÿ’ป laptop computer; U+1F4BB +๐Ÿ–ฅ desktop computer; U+1F5A5 +๐Ÿ–จ printer; U+1F5A8 +โŒจ keyboard; U+2328 +๐Ÿ–ฑ computer mouse; U+1F5B1 +๐Ÿ–ฒ trackball; U+1F5B2 +๐Ÿ’ฝ computer disk; U+1F4BD +๐Ÿ’พ floppy disk; U+1F4BE +๐Ÿ’ฟ optical disk; U+1F4BF +๐Ÿ“€ dvd; U+1F4C0 +๐Ÿงฎ abacus; U+1F9EE +๐ŸŽฅ movie camera; U+1F3A5 +๐ŸŽž film frames; U+1F39E +๐Ÿ“ฝ film projector; U+1F4FD +๐ŸŽฌ clapper board; U+1F3AC +๐Ÿ“บ television; U+1F4FA +๐Ÿ“ท camera; U+1F4F7 +๐Ÿ“ธ camera with flash; U+1F4F8 +๐Ÿ“น video camera; U+1F4F9 +๐Ÿ“ผ videocassette; U+1F4FC +๐Ÿ” magnifying glass tilted left; U+1F50D +๐Ÿ”Ž magnifying glass tilted right; U+1F50E +๐Ÿ•ฏ candle; U+1F56F +๐Ÿ’ก light bulb; U+1F4A1 +๐Ÿ”ฆ flashlight; U+1F526 +๐Ÿฎ red paper lantern; U+1F3EE +๐Ÿ“” notebook with decorative cover; U+1F4D4 +๐Ÿ“• closed book; U+1F4D5 +๐Ÿ“– open book; U+1F4D6 +๐Ÿ“— green book; U+1F4D7 +๐Ÿ“˜ blue book; U+1F4D8 +๐Ÿ“™ orange book; U+1F4D9 +๐Ÿ“š books; U+1F4DA +๐Ÿ““ notebook; U+1F4D3 +๐Ÿ“’ ledger; U+1F4D2 +๐Ÿ“ƒ page with curl; U+1F4C3 +๐Ÿ“œ scroll; U+1F4DC +๐Ÿ“„ page facing up; U+1F4C4 +๐Ÿ“ฐ newspaper; U+1F4F0 +๐Ÿ—ž rolled-up newspaper; U+1F5DE +๐Ÿ“‘ bookmark tabs; U+1F4D1 +๐Ÿ”– bookmark; U+1F516 +๐Ÿท label; U+1F3F7 +๐Ÿ’ฐ money bag; U+1F4B0 +๐Ÿ’ด yen banknote; U+1F4B4 +๐Ÿ’ต dollar banknote; U+1F4B5 +๐Ÿ’ถ euro banknote; U+1F4B6 +๐Ÿ’ท pound banknote; U+1F4B7 +๐Ÿ’ธ money with wings; U+1F4B8 +๐Ÿ’ณ credit card; U+1F4B3 +๐Ÿงพ receipt; U+1F9FE +๐Ÿ’น chart increasing with yen; U+1F4B9 +๐Ÿ’ฑ currency exchange; U+1F4B1 +๐Ÿ’ฒ heavy dollar sign; U+1F4B2 +โœ‰ envelope; U+2709 +๐Ÿ“ง e-mail; U+1F4E7 +๐Ÿ“จ incoming envelope; U+1F4E8 +๐Ÿ“ฉ envelope with arrow; U+1F4E9 +๐Ÿ“ค outbox tray; U+1F4E4 +๐Ÿ“ฅ inbox tray; U+1F4E5 +๐Ÿ“ฆ package; U+1F4E6 +๐Ÿ“ซ closed mailbox with raised flag; U+1F4EB +๐Ÿ“ช closed mailbox with lowered flag; U+1F4EA +๐Ÿ“ฌ open mailbox with raised flag; U+1F4EC +๐Ÿ“ญ open mailbox with lowered flag; U+1F4ED +๐Ÿ“ฎ postbox; U+1F4EE +๐Ÿ—ณ ballot box with ballot; U+1F5F3 +โœ pencil; U+270F +โœ’ black nib; U+2712 +๐Ÿ–‹ fountain pen; U+1F58B +๐Ÿ–Š pen; U+1F58A +๐Ÿ–Œ paintbrush; U+1F58C +๐Ÿ– crayon; U+1F58D +๐Ÿ“ memo; U+1F4DD +๐Ÿ’ผ briefcase; U+1F4BC +๐Ÿ“ file folder; U+1F4C1 +๐Ÿ“‚ open file folder; U+1F4C2 +๐Ÿ—‚ card index dividers; U+1F5C2 +๐Ÿ“… calendar; U+1F4C5 +๐Ÿ“† tear-off calendar; U+1F4C6 +๐Ÿ—’ spiral notepad; U+1F5D2 +๐Ÿ—“ spiral calendar; U+1F5D3 +๐Ÿ“‡ card index; U+1F4C7 +๐Ÿ“ˆ chart increasing; U+1F4C8 +๐Ÿ“‰ chart decreasing; U+1F4C9 +๐Ÿ“Š bar chart; U+1F4CA +๐Ÿ“‹ clipboard; U+1F4CB +๐Ÿ“Œ pushpin; U+1F4CC +๐Ÿ“ round pushpin; U+1F4CD +๐Ÿ“Ž paperclip; U+1F4CE +๐Ÿ–‡ linked paperclips; U+1F587 +๐Ÿ“ straight ruler; U+1F4CF +๐Ÿ“ triangular ruler; U+1F4D0 +โœ‚ scissors; U+2702 +๐Ÿ—ƒ card file box; U+1F5C3 +๐Ÿ—„ file cabinet; U+1F5C4 +๐Ÿ—‘ wastebasket; U+1F5D1 +๐Ÿ”’ locked; U+1F512 +๐Ÿ”“ unlocked; U+1F513 +๐Ÿ” locked with pen; U+1F50F +๐Ÿ” locked with key; U+1F510 +๐Ÿ”‘ key; U+1F511 +๐Ÿ— old key; U+1F5DD +๐Ÿ”จ hammer; U+1F528 +โ› pick; U+26CF +โš’ hammer and pick; U+2692 +๐Ÿ›  hammer and wrench; U+1F6E0 +๐Ÿ—ก dagger; U+1F5E1 +โš” crossed swords; U+2694 +๐Ÿ”ซ pistol; U+1F52B +๐Ÿน bow and arrow; U+1F3F9 +๐Ÿ›ก shield; U+1F6E1 +๐Ÿ”ง wrench; U+1F527 +๐Ÿ”ฉ nut and bolt; U+1F529 +โš™ gear; U+2699 +๐Ÿ—œ clamp; U+1F5DC +โš– balance scale; U+2696 +๐Ÿ”— link; U+1F517 +โ›“ chains; U+26D3 +๐Ÿงฐ toolbox; U+1F9F0 +๐Ÿงฒ magnet; U+1F9F2 +โš— alembic; U+2697 +๐Ÿงช test tube; U+1F9EA +๐Ÿงซ petri dish; U+1F9EB +๐Ÿงฌ dna; U+1F9EC +๐Ÿ”ฌ microscope; U+1F52C +๐Ÿ”ญ telescope; U+1F52D +๐Ÿ“ก satellite antenna; U+1F4E1 +๐Ÿ’‰ syringe; U+1F489 +๐Ÿ’Š pill; U+1F48A +๐Ÿšช door; U+1F6AA +๐Ÿ› bed; U+1F6CF +๐Ÿ›‹ couch and lamp; U+1F6CB +๐Ÿšฝ toilet; U+1F6BD +๐Ÿšฟ shower; U+1F6BF +๐Ÿ› bathtub; U+1F6C1 +๐Ÿงด lotion bottle; U+1F9F4 +๐Ÿงท safety pin; U+1F9F7 +๐Ÿงน broom; U+1F9F9 +๐Ÿงบ basket; U+1F9FA +๐Ÿงป roll of paper; U+1F9FB +๐Ÿงผ soap; U+1F9FC +๐Ÿงฝ sponge; U+1F9FD +๐Ÿงฏ fire extinguisher; U+1F9EF +๐Ÿ›’ shopping cart; U+1F6D2 +๐Ÿšฌ cigarette; U+1F6AC +โšฐ coffin; U+26B0 +โšฑ funeral urn; U+26B1 +๐Ÿ—ฟ moai; U+1F5FF +๐Ÿง ATM sign; U+1F3E7 +๐Ÿšฎ litter in bin sign; U+1F6AE +๐Ÿšฐ potable water; U+1F6B0 +โ™ฟ wheelchair symbol; U+267F +๐Ÿšน menโ€™s room; U+1F6B9 +๐Ÿšบ womenโ€™s room; U+1F6BA +๐Ÿšป restroom; U+1F6BB +๐Ÿšผ baby symbol; U+1F6BC +๐Ÿšพ water closet; U+1F6BE +๐Ÿ›‚ passport control; U+1F6C2 +๐Ÿ›ƒ customs; U+1F6C3 +๐Ÿ›„ baggage claim; U+1F6C4 +๐Ÿ›… left luggage; U+1F6C5 +โš  warning; U+26A0 +๐Ÿšธ children crossing; U+1F6B8 +โ›” no entry; U+26D4 +๐Ÿšซ prohibited; U+1F6AB +๐Ÿšณ no bicycles; U+1F6B3 +๐Ÿšญ no smoking; U+1F6AD +๐Ÿšฏ no littering; U+1F6AF +๐Ÿšฑ non-potable water; U+1F6B1 +๐Ÿšท no pedestrians; U+1F6B7 +๐Ÿ“ต no mobile phones; U+1F4F5 +๐Ÿ”ž no one under eighteen; U+1F51E +โ˜ข radioactive; U+2622 +โ˜ฃ biohazard; U+2623 +โฌ† up arrow; U+2B06 +โ†— up-right arrow; U+2197 +โžก right arrow; U+27A1 +โ†˜ down-right arrow; U+2198 +โฌ‡ down arrow; U+2B07 +โ†™ down-left arrow; U+2199 +โฌ… left arrow; U+2B05 +โ†– up-left arrow; U+2196 +โ†• up-down arrow; U+2195 +โ†” left-right arrow; U+2194 +โ†ฉ right arrow curving left; U+21A9 +โ†ช left arrow curving right; U+21AA +โคด right arrow curving up; U+2934 +โคต right arrow curving down; U+2935 +๐Ÿ”ƒ clockwise vertical arrows; U+1F503 +๐Ÿ”„ counterclockwise arrows button; U+1F504 +๐Ÿ”™ BACK arrow; U+1F519 +๐Ÿ”š END arrow; U+1F51A +๐Ÿ”› ON! arrow; U+1F51B +๐Ÿ”œ SOON arrow; U+1F51C +๐Ÿ” TOP arrow; U+1F51D +๐Ÿ› place of worship; U+1F6D0 +โš› atom symbol; U+269B +๐Ÿ•‰ om; U+1F549 +โœก star of David; U+2721 +โ˜ธ wheel of dharma; U+2638 +โ˜ฏ yin yang; U+262F +โœ latin cross; U+271D +โ˜ฆ orthodox cross; U+2626 +โ˜ช star and crescent; U+262A +โ˜ฎ peace symbol; U+262E +๐Ÿ•Ž menorah; U+1F54E +๐Ÿ”ฏ dotted six-pointed star; U+1F52F +โ™ˆ Aries; U+2648 +โ™‰ Taurus; U+2649 +โ™Š Gemini; U+264A +โ™‹ Cancer; U+264B +โ™Œ Leo; U+264C +โ™ Virgo; U+264D +โ™Ž Libra; U+264E +โ™ Scorpio; U+264F +โ™ Sagittarius; U+2650 +โ™‘ Capricorn; U+2651 +โ™’ Aquarius; U+2652 +โ™“ Pisces; U+2653 +โ›Ž Ophiuchus; U+26CE +๐Ÿ”€ shuffle tracks button; U+1F500 +๐Ÿ” repeat button; U+1F501 +๐Ÿ”‚ repeat single button; U+1F502 +โ–ถ play button; U+25B6 +โฉ fast-forward button; U+23E9 +โญ next track button; U+23ED +โฏ play or pause button; U+23EF +โ—€ reverse button; U+25C0 +โช fast reverse button; U+23EA +โฎ last track button; U+23EE +๐Ÿ”ผ upwards button; U+1F53C +โซ fast up button; U+23EB +๐Ÿ”ฝ downwards button; U+1F53D +โฌ fast down button; U+23EC +โธ pause button; U+23F8 +โน stop button; U+23F9 +โบ record button; U+23FA +โ eject button; U+23CF +๐ŸŽฆ cinema; U+1F3A6 +๐Ÿ”… dim button; U+1F505 +๐Ÿ”† bright button; U+1F506 +๐Ÿ“ถ antenna bars; U+1F4F6 +๐Ÿ“ณ vibration mode; U+1F4F3 +๐Ÿ“ด mobile phone off; U+1F4F4 +โ™€ female sign; U+2640 +โ™‚ male sign; U+2642 +โš• medical symbol; U+2695 +โ™พ infinity; U+267E +โ™ป recycling symbol; U+267B +โšœ fleur-de-lis; U+269C +๐Ÿ”ฑ trident emblem; U+1F531 +๐Ÿ“› name badge; U+1F4DB +๐Ÿ”ฐ Japanese symbol for beginner; U+1F530 +โญ• heavy large circle; U+2B55 +โœ… white heavy check mark; U+2705 +โ˜‘ ballot box with check; U+2611 +โœ” heavy check mark; U+2714 +โœ– heavy multiplication x; U+2716 +โŒ cross mark; U+274C +โŽ cross mark button; U+274E +โž• heavy plus sign; U+2795 +โž– heavy minus sign; U+2796 +โž— heavy division sign; U+2797 +โžฐ curly loop; U+27B0 +โžฟ double curly loop; U+27BF +ใ€ฝ part alternation mark; U+303D +โœณ eight-spoked asterisk; U+2733 +โœด eight-pointed star; U+2734 +โ‡ sparkle; U+2747 +โ€ผ double exclamation mark; U+203C +โ‰ exclamation question mark; U+2049 +โ“ question mark; U+2753 +โ” white question mark; U+2754 +โ• white exclamation mark; U+2755 +โ— exclamation mark; U+2757 +ใ€ฐ wavy dash; U+3030 +ยฉ copyright; U+00A9 +ยฎ registered; U+00AE +โ„ข trade mark; U+2122 +#๏ธโƒฃ keycap: #; U+0023 U+FE0F U+20E3 +*๏ธโƒฃ keycap: *; U+002A U+FE0F U+20E3 +0๏ธโƒฃ keycap: 0; U+0030 U+FE0F U+20E3 +1๏ธโƒฃ keycap: 1; U+0031 U+FE0F U+20E3 +2๏ธโƒฃ keycap: 2; U+0032 U+FE0F U+20E3 +3๏ธโƒฃ keycap: 3; U+0033 U+FE0F U+20E3 +4๏ธโƒฃ keycap: 4; U+0034 U+FE0F U+20E3 +5๏ธโƒฃ keycap: 5; U+0035 U+FE0F U+20E3 +6๏ธโƒฃ keycap: 6; U+0036 U+FE0F U+20E3 +7๏ธโƒฃ keycap: 7; U+0037 U+FE0F U+20E3 +8๏ธโƒฃ keycap: 8; U+0038 U+FE0F U+20E3 +9๏ธโƒฃ keycap: 9; U+0039 U+FE0F U+20E3 +๐Ÿ”Ÿ keycap: 10; U+1F51F +๐Ÿ”  input latin uppercase; U+1F520 +๐Ÿ”ก input latin lowercase; U+1F521 +๐Ÿ”ข input numbers; U+1F522 +๐Ÿ”ฃ input symbols; U+1F523 +๐Ÿ”ค input latin letters; U+1F524 +๐Ÿ…ฐ A button (blood type); U+1F170 +๐Ÿ†Ž AB button (blood type); U+1F18E +๐Ÿ…ฑ B button (blood type); U+1F171 +๐Ÿ†‘ CL button; U+1F191 +๐Ÿ†’ COOL button; U+1F192 +๐Ÿ†“ FREE button; U+1F193 +โ„น information; U+2139 +๐Ÿ†” ID button; U+1F194 +โ“‚ circled M; U+24C2 +๐Ÿ†• NEW button; U+1F195 +๐Ÿ†– NG button; U+1F196 +๐Ÿ…พ O button (blood type); U+1F17E +๐Ÿ†— OK button; U+1F197 +๐Ÿ…ฟ P button; U+1F17F +๐Ÿ†˜ SOS button; U+1F198 +๐Ÿ†™ UP! button; U+1F199 +๐Ÿ†š VS button; U+1F19A +๐Ÿˆ Japanese โ€œhereโ€ button; U+1F201 +๐Ÿˆ‚ Japanese โ€œservice chargeโ€ button; U+1F202 +๐Ÿˆท Japanese โ€œmonthly amountโ€ button; U+1F237 +๐Ÿˆถ Japanese โ€œnot free of chargeโ€ button; U+1F236 +๐Ÿˆฏ Japanese โ€œreservedโ€ button; U+1F22F +๐Ÿ‰ Japanese โ€œbargainโ€ button; U+1F250 +๐Ÿˆน Japanese โ€œdiscountโ€ button; U+1F239 +๐Ÿˆš Japanese โ€œfree of chargeโ€ button; U+1F21A +๐Ÿˆฒ Japanese โ€œprohibitedโ€ button; U+1F232 +๐Ÿ‰‘ Japanese โ€œacceptableโ€ button; U+1F251 +๐Ÿˆธ Japanese โ€œapplicationโ€ button; U+1F238 +๐Ÿˆด Japanese โ€œpassing gradeโ€ button; U+1F234 +๐Ÿˆณ Japanese โ€œvacancyโ€ button; U+1F233 +ใŠ— Japanese โ€œcongratulationsโ€ button; U+3297 +ใŠ™ Japanese โ€œsecretโ€ button; U+3299 +๐Ÿˆบ Japanese โ€œopen for businessโ€ button; U+1F23A +๐Ÿˆต Japanese โ€œno vacancyโ€ button; U+1F235 +๐Ÿ”ด red circle; U+1F534 +๐Ÿ”ต blue circle; U+1F535 +โšช white circle; U+26AA +โšซ black circle; U+26AB +โฌœ white large square; U+2B1C +โฌ› black large square; U+2B1B +โ—ผ black medium square; U+25FC +โ—ป white medium square; U+25FB +โ—ฝ white medium-small square; U+25FD +โ—พ black medium-small square; U+25FE +โ–ซ white small square; U+25AB +โ–ช black small square; U+25AA +๐Ÿ”ถ large orange diamond; U+1F536 +๐Ÿ”ท large blue diamond; U+1F537 +๐Ÿ”ธ small orange diamond; U+1F538 +๐Ÿ”น small blue diamond; U+1F539 +๐Ÿ”บ red triangle pointed up; U+1F53A +๐Ÿ”ป red triangle pointed down; U+1F53B +๐Ÿ’  diamond with a dot; U+1F4A0 +๐Ÿ”˜ radio button; U+1F518 +๐Ÿ”ฒ black square button; U+1F532 +๐Ÿ”ณ white square button; U+1F533 +๐Ÿ chequered flag; U+1F3C1 +๐Ÿšฉ triangular flag; U+1F6A9 +๐ŸŽŒ crossed flags; U+1F38C +๐Ÿด black flag; U+1F3F4 +๐Ÿณ white flag; U+1F3F3 +๐Ÿณ๏ธโ€๐ŸŒˆ rainbow flag; U+1F3F3 U+FE0F U+200D U+1F308 +๐Ÿดโ€โ˜ ๏ธ pirate flag; U+1F3F4 U+200D U+2620 U+FE0F +๐Ÿ‡ฆ๐Ÿ‡จ flag: Ascension Island; U+1F1E6 U+1F1E8 +๐Ÿ‡ฆ๐Ÿ‡ฉ flag: Andorra; U+1F1E6 U+1F1E9 +๐Ÿ‡ฆ๐Ÿ‡ช flag: United Arab Emirates; U+1F1E6 U+1F1EA +๐Ÿ‡ฆ๐Ÿ‡ซ flag: Afghanistan; U+1F1E6 U+1F1EB +๐Ÿ‡ฆ๐Ÿ‡ฌ flag: Antigua & Barbuda; U+1F1E6 U+1F1EC +๐Ÿ‡ฆ๐Ÿ‡ฎ flag: Anguilla; U+1F1E6 U+1F1EE +๐Ÿ‡ฆ๐Ÿ‡ฑ flag: Albania; U+1F1E6 U+1F1F1 +๐Ÿ‡ฆ๐Ÿ‡ฒ flag: Armenia; U+1F1E6 U+1F1F2 +๐Ÿ‡ฆ๐Ÿ‡ด flag: Angola; U+1F1E6 U+1F1F4 +๐Ÿ‡ฆ๐Ÿ‡ถ flag: Antarctica; U+1F1E6 U+1F1F6 +๐Ÿ‡ฆ๐Ÿ‡ท flag: Argentina; U+1F1E6 U+1F1F7 +๐Ÿ‡ฆ๐Ÿ‡ธ flag: American Samoa; U+1F1E6 U+1F1F8 +๐Ÿ‡ฆ๐Ÿ‡น flag: Austria; U+1F1E6 U+1F1F9 +๐Ÿ‡ฆ๐Ÿ‡บ flag: Australia; U+1F1E6 U+1F1FA +๐Ÿ‡ฆ๐Ÿ‡ผ flag: Aruba; U+1F1E6 U+1F1FC +๐Ÿ‡ฆ๐Ÿ‡ฝ flag: ร…land Islands; U+1F1E6 U+1F1FD +๐Ÿ‡ฆ๐Ÿ‡ฟ flag: Azerbaijan; U+1F1E6 U+1F1FF +๐Ÿ‡ง๐Ÿ‡ฆ flag: Bosnia & Herzegovina; U+1F1E7 U+1F1E6 +๐Ÿ‡ง๐Ÿ‡ง flag: Barbados; U+1F1E7 U+1F1E7 +๐Ÿ‡ง๐Ÿ‡ฉ flag: Bangladesh; U+1F1E7 U+1F1E9 +๐Ÿ‡ง๐Ÿ‡ช flag: Belgium; U+1F1E7 U+1F1EA +๐Ÿ‡ง๐Ÿ‡ซ flag: Burkina Faso; U+1F1E7 U+1F1EB +๐Ÿ‡ง๐Ÿ‡ฌ flag: Bulgaria; U+1F1E7 U+1F1EC +๐Ÿ‡ง๐Ÿ‡ญ flag: Bahrain; U+1F1E7 U+1F1ED +๐Ÿ‡ง๐Ÿ‡ฎ flag: Burundi; U+1F1E7 U+1F1EE +๐Ÿ‡ง๐Ÿ‡ฏ flag: Benin; U+1F1E7 U+1F1EF +๐Ÿ‡ง๐Ÿ‡ฑ flag: St. Barthรฉlemy; U+1F1E7 U+1F1F1 +๐Ÿ‡ง๐Ÿ‡ฒ flag: Bermuda; U+1F1E7 U+1F1F2 +๐Ÿ‡ง๐Ÿ‡ณ flag: Brunei; U+1F1E7 U+1F1F3 +๐Ÿ‡ง๐Ÿ‡ด flag: Bolivia; U+1F1E7 U+1F1F4 +๐Ÿ‡ง๐Ÿ‡ถ flag: Caribbean Netherlands; U+1F1E7 U+1F1F6 +๐Ÿ‡ง๐Ÿ‡ท flag: Brazil; U+1F1E7 U+1F1F7 +๐Ÿ‡ง๐Ÿ‡ธ flag: Bahamas; U+1F1E7 U+1F1F8 +๐Ÿ‡ง๐Ÿ‡น flag: Bhutan; U+1F1E7 U+1F1F9 +๐Ÿ‡ง๐Ÿ‡ป flag: Bouvet Island; U+1F1E7 U+1F1FB +๐Ÿ‡ง๐Ÿ‡ผ flag: Botswana; U+1F1E7 U+1F1FC +๐Ÿ‡ง๐Ÿ‡พ flag: Belarus; U+1F1E7 U+1F1FE +๐Ÿ‡ง๐Ÿ‡ฟ flag: Belize; U+1F1E7 U+1F1FF +๐Ÿ‡จ๐Ÿ‡ฆ flag: Canada; U+1F1E8 U+1F1E6 +๐Ÿ‡จ๐Ÿ‡จ flag: Cocos (Keeling) Islands; U+1F1E8 U+1F1E8 +๐Ÿ‡จ๐Ÿ‡ฉ flag: Congo - Kinshasa; U+1F1E8 U+1F1E9 +๐Ÿ‡จ๐Ÿ‡ซ flag: Central African Republic; U+1F1E8 U+1F1EB +๐Ÿ‡จ๐Ÿ‡ฌ flag: Congo - Brazzaville; U+1F1E8 U+1F1EC +๐Ÿ‡จ๐Ÿ‡ญ flag: Switzerland; U+1F1E8 U+1F1ED +๐Ÿ‡จ๐Ÿ‡ฎ flag: Cรดte dโ€™Ivoire; U+1F1E8 U+1F1EE +๐Ÿ‡จ๐Ÿ‡ฐ flag: Cook Islands; U+1F1E8 U+1F1F0 +๐Ÿ‡จ๐Ÿ‡ฑ flag: Chile; U+1F1E8 U+1F1F1 +๐Ÿ‡จ๐Ÿ‡ฒ flag: Cameroon; U+1F1E8 U+1F1F2 +๐Ÿ‡จ๐Ÿ‡ณ flag: China; U+1F1E8 U+1F1F3 +๐Ÿ‡จ๐Ÿ‡ด flag: Colombia; U+1F1E8 U+1F1F4 +๐Ÿ‡จ๐Ÿ‡ต flag: Clipperton Island; U+1F1E8 U+1F1F5 +๐Ÿ‡จ๐Ÿ‡ท flag: Costa Rica; U+1F1E8 U+1F1F7 +๐Ÿ‡จ๐Ÿ‡บ flag: Cuba; U+1F1E8 U+1F1FA +๐Ÿ‡จ๐Ÿ‡ป flag: Cape Verde; U+1F1E8 U+1F1FB +๐Ÿ‡จ๐Ÿ‡ผ flag: Curaรงao; U+1F1E8 U+1F1FC +๐Ÿ‡จ๐Ÿ‡ฝ flag: Christmas Island; U+1F1E8 U+1F1FD +๐Ÿ‡จ๐Ÿ‡พ flag: Cyprus; U+1F1E8 U+1F1FE +๐Ÿ‡จ๐Ÿ‡ฟ flag: Czechia; U+1F1E8 U+1F1FF +๐Ÿ‡ฉ๐Ÿ‡ช flag: Germany; U+1F1E9 U+1F1EA +๐Ÿ‡ฉ๐Ÿ‡ฌ flag: Diego Garcia; U+1F1E9 U+1F1EC +๐Ÿ‡ฉ๐Ÿ‡ฏ flag: Djibouti; U+1F1E9 U+1F1EF +๐Ÿ‡ฉ๐Ÿ‡ฐ flag: Denmark; U+1F1E9 U+1F1F0 +๐Ÿ‡ฉ๐Ÿ‡ฒ flag: Dominica; U+1F1E9 U+1F1F2 +๐Ÿ‡ฉ๐Ÿ‡ด flag: Dominican Republic; U+1F1E9 U+1F1F4 +๐Ÿ‡ฉ๐Ÿ‡ฟ flag: Algeria; U+1F1E9 U+1F1FF +๐Ÿ‡ช๐Ÿ‡ฆ flag: Ceuta & Melilla; U+1F1EA U+1F1E6 +๐Ÿ‡ช๐Ÿ‡จ flag: Ecuador; U+1F1EA U+1F1E8 +๐Ÿ‡ช๐Ÿ‡ช flag: Estonia; U+1F1EA U+1F1EA +๐Ÿ‡ช๐Ÿ‡ฌ flag: Egypt; U+1F1EA U+1F1EC +๐Ÿ‡ช๐Ÿ‡ญ flag: Western Sahara; U+1F1EA U+1F1ED +๐Ÿ‡ช๐Ÿ‡ท flag: Eritrea; U+1F1EA U+1F1F7 +๐Ÿ‡ช๐Ÿ‡ธ flag: Spain; U+1F1EA U+1F1F8 +๐Ÿ‡ช๐Ÿ‡น flag: Ethiopia; U+1F1EA U+1F1F9 +๐Ÿ‡ช๐Ÿ‡บ flag: European Union; U+1F1EA U+1F1FA +๐Ÿ‡ซ๐Ÿ‡ฎ flag: Finland; U+1F1EB U+1F1EE +๐Ÿ‡ซ๐Ÿ‡ฏ flag: Fiji; U+1F1EB U+1F1EF +๐Ÿ‡ซ๐Ÿ‡ฐ flag: Falkland Islands; U+1F1EB U+1F1F0 +๐Ÿ‡ซ๐Ÿ‡ฒ flag: Micronesia; U+1F1EB U+1F1F2 +๐Ÿ‡ซ๐Ÿ‡ด flag: Faroe Islands; U+1F1EB U+1F1F4 +๐Ÿ‡ซ๐Ÿ‡ท flag: France; U+1F1EB U+1F1F7 +๐Ÿ‡ฌ๐Ÿ‡ฆ flag: Gabon; U+1F1EC U+1F1E6 +๐Ÿ‡ฌ๐Ÿ‡ง flag: United Kingdom; U+1F1EC U+1F1E7 +๐Ÿ‡ฌ๐Ÿ‡ฉ flag: Grenada; U+1F1EC U+1F1E9 +๐Ÿ‡ฌ๐Ÿ‡ช flag: Georgia; U+1F1EC U+1F1EA +๐Ÿ‡ฌ๐Ÿ‡ซ flag: French Guiana; U+1F1EC U+1F1EB +๐Ÿ‡ฌ๐Ÿ‡ฌ flag: Guernsey; U+1F1EC U+1F1EC +๐Ÿ‡ฌ๐Ÿ‡ญ flag: Ghana; U+1F1EC U+1F1ED +๐Ÿ‡ฌ๐Ÿ‡ฎ flag: Gibraltar; U+1F1EC U+1F1EE +๐Ÿ‡ฌ๐Ÿ‡ฑ flag: Greenland; U+1F1EC U+1F1F1 +๐Ÿ‡ฌ๐Ÿ‡ฒ flag: Gambia; U+1F1EC U+1F1F2 +๐Ÿ‡ฌ๐Ÿ‡ณ flag: Guinea; U+1F1EC U+1F1F3 +๐Ÿ‡ฌ๐Ÿ‡ต flag: Guadeloupe; U+1F1EC U+1F1F5 +๐Ÿ‡ฌ๐Ÿ‡ถ flag: Equatorial Guinea; U+1F1EC U+1F1F6 +๐Ÿ‡ฌ๐Ÿ‡ท flag: Greece; U+1F1EC U+1F1F7 +๐Ÿ‡ฌ๐Ÿ‡ธ flag: South Georgia & South Sandwich Islands; U+1F1EC U+1F1F8 +๐Ÿ‡ฌ๐Ÿ‡น flag: Guatemala; U+1F1EC U+1F1F9 +๐Ÿ‡ฌ๐Ÿ‡บ flag: Guam; U+1F1EC U+1F1FA +๐Ÿ‡ฌ๐Ÿ‡ผ flag: Guinea-Bissau; U+1F1EC U+1F1FC +๐Ÿ‡ฌ๐Ÿ‡พ flag: Guyana; U+1F1EC U+1F1FE +๐Ÿ‡ญ๐Ÿ‡ฐ flag: Hong Kong SAR China; U+1F1ED U+1F1F0 +๐Ÿ‡ญ๐Ÿ‡ฒ flag: Heard & McDonald Islands; U+1F1ED U+1F1F2 +๐Ÿ‡ญ๐Ÿ‡ณ flag: Honduras; U+1F1ED U+1F1F3 +๐Ÿ‡ญ๐Ÿ‡ท flag: Croatia; U+1F1ED U+1F1F7 +๐Ÿ‡ญ๐Ÿ‡น flag: Haiti; U+1F1ED U+1F1F9 +๐Ÿ‡ญ๐Ÿ‡บ flag: Hungary; U+1F1ED U+1F1FA +๐Ÿ‡ฎ๐Ÿ‡จ flag: Canary Islands; U+1F1EE U+1F1E8 +๐Ÿ‡ฎ๐Ÿ‡ฉ flag: Indonesia; U+1F1EE U+1F1E9 +๐Ÿ‡ฎ๐Ÿ‡ช flag: Ireland; U+1F1EE U+1F1EA +๐Ÿ‡ฎ๐Ÿ‡ฑ flag: Israel; U+1F1EE U+1F1F1 +๐Ÿ‡ฎ๐Ÿ‡ฒ flag: Isle of Man; U+1F1EE U+1F1F2 +๐Ÿ‡ฎ๐Ÿ‡ณ flag: India; U+1F1EE U+1F1F3 +๐Ÿ‡ฎ๐Ÿ‡ด flag: British Indian Ocean Territory; U+1F1EE U+1F1F4 +๐Ÿ‡ฎ๐Ÿ‡ถ flag: Iraq; U+1F1EE U+1F1F6 +๐Ÿ‡ฎ๐Ÿ‡ท flag: Iran; U+1F1EE U+1F1F7 +๐Ÿ‡ฎ๐Ÿ‡ธ flag: Iceland; U+1F1EE U+1F1F8 +๐Ÿ‡ฎ๐Ÿ‡น flag: Italy; U+1F1EE U+1F1F9 +๐Ÿ‡ฏ๐Ÿ‡ช flag: Jersey; U+1F1EF U+1F1EA +๐Ÿ‡ฏ๐Ÿ‡ฒ flag: Jamaica; U+1F1EF U+1F1F2 +๐Ÿ‡ฏ๐Ÿ‡ด flag: Jordan; U+1F1EF U+1F1F4 +๐Ÿ‡ฏ๐Ÿ‡ต flag: Japan; U+1F1EF U+1F1F5 +๐Ÿ‡ฐ๐Ÿ‡ช flag: Kenya; U+1F1F0 U+1F1EA +๐Ÿ‡ฐ๐Ÿ‡ฌ flag: Kyrgyzstan; U+1F1F0 U+1F1EC +๐Ÿ‡ฐ๐Ÿ‡ญ flag: Cambodia; U+1F1F0 U+1F1ED +๐Ÿ‡ฐ๐Ÿ‡ฎ flag: Kiribati; U+1F1F0 U+1F1EE +๐Ÿ‡ฐ๐Ÿ‡ฒ flag: Comoros; U+1F1F0 U+1F1F2 +๐Ÿ‡ฐ๐Ÿ‡ณ flag: St. Kitts & Nevis; U+1F1F0 U+1F1F3 +๐Ÿ‡ฐ๐Ÿ‡ต flag: North Korea; U+1F1F0 U+1F1F5 +๐Ÿ‡ฐ๐Ÿ‡ท flag: South Korea; U+1F1F0 U+1F1F7 +๐Ÿ‡ฐ๐Ÿ‡ผ flag: Kuwait; U+1F1F0 U+1F1FC +๐Ÿ‡ฐ๐Ÿ‡พ flag: Cayman Islands; U+1F1F0 U+1F1FE +๐Ÿ‡ฐ๐Ÿ‡ฟ flag: Kazakhstan; U+1F1F0 U+1F1FF +๐Ÿ‡ฑ๐Ÿ‡ฆ flag: Laos; U+1F1F1 U+1F1E6 +๐Ÿ‡ฑ๐Ÿ‡ง flag: Lebanon; U+1F1F1 U+1F1E7 +๐Ÿ‡ฑ๐Ÿ‡จ flag: St. Lucia; U+1F1F1 U+1F1E8 +๐Ÿ‡ฑ๐Ÿ‡ฎ flag: Liechtenstein; U+1F1F1 U+1F1EE +๐Ÿ‡ฑ๐Ÿ‡ฐ flag: Sri Lanka; U+1F1F1 U+1F1F0 +๐Ÿ‡ฑ๐Ÿ‡ท flag: Liberia; U+1F1F1 U+1F1F7 +๐Ÿ‡ฑ๐Ÿ‡ธ flag: Lesotho; U+1F1F1 U+1F1F8 +๐Ÿ‡ฑ๐Ÿ‡น flag: Lithuania; U+1F1F1 U+1F1F9 +๐Ÿ‡ฑ๐Ÿ‡บ flag: Luxembourg; U+1F1F1 U+1F1FA +๐Ÿ‡ฑ๐Ÿ‡ป flag: Latvia; U+1F1F1 U+1F1FB +๐Ÿ‡ฑ๐Ÿ‡พ flag: Libya; U+1F1F1 U+1F1FE +๐Ÿ‡ฒ๐Ÿ‡ฆ flag: Morocco; U+1F1F2 U+1F1E6 +๐Ÿ‡ฒ๐Ÿ‡จ flag: Monaco; U+1F1F2 U+1F1E8 +๐Ÿ‡ฒ๐Ÿ‡ฉ flag: Moldova; U+1F1F2 U+1F1E9 +๐Ÿ‡ฒ๐Ÿ‡ช flag: Montenegro; U+1F1F2 U+1F1EA +๐Ÿ‡ฒ๐Ÿ‡ซ flag: St. Martin; U+1F1F2 U+1F1EB +๐Ÿ‡ฒ๐Ÿ‡ฌ flag: Madagascar; U+1F1F2 U+1F1EC +๐Ÿ‡ฒ๐Ÿ‡ญ flag: Marshall Islands; U+1F1F2 U+1F1ED +๐Ÿ‡ฒ๐Ÿ‡ฐ flag: Macedonia; U+1F1F2 U+1F1F0 +๐Ÿ‡ฒ๐Ÿ‡ฑ flag: Mali; U+1F1F2 U+1F1F1 +๐Ÿ‡ฒ๐Ÿ‡ฒ flag: Myanmar (Burma); U+1F1F2 U+1F1F2 +๐Ÿ‡ฒ๐Ÿ‡ณ flag: Mongolia; U+1F1F2 U+1F1F3 +๐Ÿ‡ฒ๐Ÿ‡ด flag: Macau SAR China; U+1F1F2 U+1F1F4 +๐Ÿ‡ฒ๐Ÿ‡ต flag: Northern Mariana Islands; U+1F1F2 U+1F1F5 +๐Ÿ‡ฒ๐Ÿ‡ถ flag: Martinique; U+1F1F2 U+1F1F6 +๐Ÿ‡ฒ๐Ÿ‡ท flag: Mauritania; U+1F1F2 U+1F1F7 +๐Ÿ‡ฒ๐Ÿ‡ธ flag: Montserrat; U+1F1F2 U+1F1F8 +๐Ÿ‡ฒ๐Ÿ‡น flag: Malta; U+1F1F2 U+1F1F9 +๐Ÿ‡ฒ๐Ÿ‡บ flag: Mauritius; U+1F1F2 U+1F1FA +๐Ÿ‡ฒ๐Ÿ‡ป flag: Maldives; U+1F1F2 U+1F1FB +๐Ÿ‡ฒ๐Ÿ‡ผ flag: Malawi; U+1F1F2 U+1F1FC +๐Ÿ‡ฒ๐Ÿ‡ฝ flag: Mexico; U+1F1F2 U+1F1FD +๐Ÿ‡ฒ๐Ÿ‡พ flag: Malaysia; U+1F1F2 U+1F1FE +๐Ÿ‡ฒ๐Ÿ‡ฟ flag: Mozambique; U+1F1F2 U+1F1FF +๐Ÿ‡ณ๐Ÿ‡ฆ flag: Namibia; U+1F1F3 U+1F1E6 +๐Ÿ‡ณ๐Ÿ‡จ flag: New Caledonia; U+1F1F3 U+1F1E8 +๐Ÿ‡ณ๐Ÿ‡ช flag: Niger; U+1F1F3 U+1F1EA +๐Ÿ‡ณ๐Ÿ‡ซ flag: Norfolk Island; U+1F1F3 U+1F1EB +๐Ÿ‡ณ๐Ÿ‡ฌ flag: Nigeria; U+1F1F3 U+1F1EC +๐Ÿ‡ณ๐Ÿ‡ฎ flag: Nicaragua; U+1F1F3 U+1F1EE +๐Ÿ‡ณ๐Ÿ‡ฑ flag: Netherlands; U+1F1F3 U+1F1F1 +๐Ÿ‡ณ๐Ÿ‡ด flag: Norway; U+1F1F3 U+1F1F4 +๐Ÿ‡ณ๐Ÿ‡ต flag: Nepal; U+1F1F3 U+1F1F5 +๐Ÿ‡ณ๐Ÿ‡ท flag: Nauru; U+1F1F3 U+1F1F7 +๐Ÿ‡ณ๐Ÿ‡บ flag: Niue; U+1F1F3 U+1F1FA +๐Ÿ‡ณ๐Ÿ‡ฟ flag: New Zealand; U+1F1F3 U+1F1FF +๐Ÿ‡ด๐Ÿ‡ฒ flag: Oman; U+1F1F4 U+1F1F2 +๐Ÿ‡ต๐Ÿ‡ฆ flag: Panama; U+1F1F5 U+1F1E6 +๐Ÿ‡ต๐Ÿ‡ช flag: Peru; U+1F1F5 U+1F1EA +๐Ÿ‡ต๐Ÿ‡ซ flag: French Polynesia; U+1F1F5 U+1F1EB +๐Ÿ‡ต๐Ÿ‡ฌ flag: Papua New Guinea; U+1F1F5 U+1F1EC +๐Ÿ‡ต๐Ÿ‡ญ flag: Philippines; U+1F1F5 U+1F1ED +๐Ÿ‡ต๐Ÿ‡ฐ flag: Pakistan; U+1F1F5 U+1F1F0 +๐Ÿ‡ต๐Ÿ‡ฑ flag: Poland; U+1F1F5 U+1F1F1 +๐Ÿ‡ต๐Ÿ‡ฒ flag: St. Pierre & Miquelon; U+1F1F5 U+1F1F2 +๐Ÿ‡ต๐Ÿ‡ณ flag: Pitcairn Islands; U+1F1F5 U+1F1F3 +๐Ÿ‡ต๐Ÿ‡ท flag: Puerto Rico; U+1F1F5 U+1F1F7 +๐Ÿ‡ต๐Ÿ‡ธ flag: Palestinian Territories; U+1F1F5 U+1F1F8 +๐Ÿ‡ต๐Ÿ‡น flag: Portugal; U+1F1F5 U+1F1F9 +๐Ÿ‡ต๐Ÿ‡ผ flag: Palau; U+1F1F5 U+1F1FC +๐Ÿ‡ต๐Ÿ‡พ flag: Paraguay; U+1F1F5 U+1F1FE +๐Ÿ‡ถ๐Ÿ‡ฆ flag: Qatar; U+1F1F6 U+1F1E6 +๐Ÿ‡ท๐Ÿ‡ช flag: Rรฉunion; U+1F1F7 U+1F1EA +๐Ÿ‡ท๐Ÿ‡ด flag: Romania; U+1F1F7 U+1F1F4 +๐Ÿ‡ท๐Ÿ‡ธ flag: Serbia; U+1F1F7 U+1F1F8 +๐Ÿ‡ท๐Ÿ‡บ flag: Russia; U+1F1F7 U+1F1FA +๐Ÿ‡ท๐Ÿ‡ผ flag: Rwanda; U+1F1F7 U+1F1FC +๐Ÿ‡ธ๐Ÿ‡ฆ flag: Saudi Arabia; U+1F1F8 U+1F1E6 +๐Ÿ‡ธ๐Ÿ‡ง flag: Solomon Islands; U+1F1F8 U+1F1E7 +๐Ÿ‡ธ๐Ÿ‡จ flag: Seychelles; U+1F1F8 U+1F1E8 +๐Ÿ‡ธ๐Ÿ‡ฉ flag: Sudan; U+1F1F8 U+1F1E9 +๐Ÿ‡ธ๐Ÿ‡ช flag: Sweden; U+1F1F8 U+1F1EA +๐Ÿ‡ธ๐Ÿ‡ฌ flag: Singapore; U+1F1F8 U+1F1EC +๐Ÿ‡ธ๐Ÿ‡ญ flag: St. Helena; U+1F1F8 U+1F1ED +๐Ÿ‡ธ๐Ÿ‡ฎ flag: Slovenia; U+1F1F8 U+1F1EE +๐Ÿ‡ธ๐Ÿ‡ฏ flag: Svalbard & Jan Mayen; U+1F1F8 U+1F1EF +๐Ÿ‡ธ๐Ÿ‡ฐ flag: Slovakia; U+1F1F8 U+1F1F0 +๐Ÿ‡ธ๐Ÿ‡ฑ flag: Sierra Leone; U+1F1F8 U+1F1F1 +๐Ÿ‡ธ๐Ÿ‡ฒ flag: San Marino; U+1F1F8 U+1F1F2 +๐Ÿ‡ธ๐Ÿ‡ณ flag: Senegal; U+1F1F8 U+1F1F3 +๐Ÿ‡ธ๐Ÿ‡ด flag: Somalia; U+1F1F8 U+1F1F4 +๐Ÿ‡ธ๐Ÿ‡ท flag: Suriname; U+1F1F8 U+1F1F7 +๐Ÿ‡ธ๐Ÿ‡ธ flag: South Sudan; U+1F1F8 U+1F1F8 +๐Ÿ‡ธ๐Ÿ‡น flag: Sรฃo Tomรฉ & Prรญncipe; U+1F1F8 U+1F1F9 +๐Ÿ‡ธ๐Ÿ‡ป flag: El Salvador; U+1F1F8 U+1F1FB +๐Ÿ‡ธ๐Ÿ‡ฝ flag: Sint Maarten; U+1F1F8 U+1F1FD +๐Ÿ‡ธ๐Ÿ‡พ flag: Syria; U+1F1F8 U+1F1FE +๐Ÿ‡ธ๐Ÿ‡ฟ flag: Swaziland; U+1F1F8 U+1F1FF +๐Ÿ‡น๐Ÿ‡ฆ flag: Tristan da Cunha; U+1F1F9 U+1F1E6 +๐Ÿ‡น๐Ÿ‡จ flag: Turks & Caicos Islands; U+1F1F9 U+1F1E8 +๐Ÿ‡น๐Ÿ‡ฉ flag: Chad; U+1F1F9 U+1F1E9 +๐Ÿ‡น๐Ÿ‡ซ flag: French Southern Territories; U+1F1F9 U+1F1EB +๐Ÿ‡น๐Ÿ‡ฌ flag: Togo; U+1F1F9 U+1F1EC +๐Ÿ‡น๐Ÿ‡ญ flag: Thailand; U+1F1F9 U+1F1ED +๐Ÿ‡น๐Ÿ‡ฏ flag: Tajikistan; U+1F1F9 U+1F1EF +๐Ÿ‡น๐Ÿ‡ฐ flag: Tokelau; U+1F1F9 U+1F1F0 +๐Ÿ‡น๐Ÿ‡ฑ flag: Timor-Leste; U+1F1F9 U+1F1F1 +๐Ÿ‡น๐Ÿ‡ฒ flag: Turkmenistan; U+1F1F9 U+1F1F2 +๐Ÿ‡น๐Ÿ‡ณ flag: Tunisia; U+1F1F9 U+1F1F3 +๐Ÿ‡น๐Ÿ‡ด flag: Tonga; U+1F1F9 U+1F1F4 +๐Ÿ‡น๐Ÿ‡ท flag: Turkey; U+1F1F9 U+1F1F7 +๐Ÿ‡น๐Ÿ‡น flag: Trinidad & Tobago; U+1F1F9 U+1F1F9 +๐Ÿ‡น๐Ÿ‡ป flag: Tuvalu; U+1F1F9 U+1F1FB +๐Ÿ‡น๐Ÿ‡ผ flag: Taiwan; U+1F1F9 U+1F1FC +๐Ÿ‡น๐Ÿ‡ฟ flag: Tanzania; U+1F1F9 U+1F1FF +๐Ÿ‡บ๐Ÿ‡ฆ flag: Ukraine; U+1F1FA U+1F1E6 +๐Ÿ‡บ๐Ÿ‡ฌ flag: Uganda; U+1F1FA U+1F1EC +๐Ÿ‡บ๐Ÿ‡ฒ flag: U.S. Outlying Islands; U+1F1FA U+1F1F2 +๐Ÿ‡บ๐Ÿ‡ณ flag: United Nations; U+1F1FA U+1F1F3 +๐Ÿ‡บ๐Ÿ‡ธ flag: United States; U+1F1FA U+1F1F8 +๐Ÿ‡บ๐Ÿ‡พ flag: Uruguay; U+1F1FA U+1F1FE +๐Ÿ‡บ๐Ÿ‡ฟ flag: Uzbekistan; U+1F1FA U+1F1FF +๐Ÿ‡ป๐Ÿ‡ฆ flag: Vatican City; U+1F1FB U+1F1E6 +๐Ÿ‡ป๐Ÿ‡จ flag: St. Vincent & Grenadines; U+1F1FB U+1F1E8 +๐Ÿ‡ป๐Ÿ‡ช flag: Venezuela; U+1F1FB U+1F1EA +๐Ÿ‡ป๐Ÿ‡ฌ flag: British Virgin Islands; U+1F1FB U+1F1EC +๐Ÿ‡ป๐Ÿ‡ฎ flag: U.S. Virgin Islands; U+1F1FB U+1F1EE +๐Ÿ‡ป๐Ÿ‡ณ flag: Vietnam; U+1F1FB U+1F1F3 +๐Ÿ‡ป๐Ÿ‡บ flag: Vanuatu; U+1F1FB U+1F1FA +๐Ÿ‡ผ๐Ÿ‡ซ flag: Wallis & Futuna; U+1F1FC U+1F1EB +๐Ÿ‡ผ๐Ÿ‡ธ flag: Samoa; U+1F1FC U+1F1F8 +๐Ÿ‡ฝ๐Ÿ‡ฐ flag: Kosovo; U+1F1FD U+1F1F0 +๐Ÿ‡พ๐Ÿ‡ช flag: Yemen; U+1F1FE U+1F1EA +๐Ÿ‡พ๐Ÿ‡น flag: Mayotte; U+1F1FE U+1F1F9 +๐Ÿ‡ฟ๐Ÿ‡ฆ flag: South Africa; U+1F1FF U+1F1E6 +๐Ÿ‡ฟ๐Ÿ‡ฒ flag: Zambia; U+1F1FF U+1F1F2 +๐Ÿ‡ฟ๐Ÿ‡ผ flag: Zimbabwe; U+1F1FF U+1F1FC +๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ flag: England; U+1F3F4 U+E0067 U+E0062 U+E0065 U+E006E U+E0067 U+E007F +๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ flag: Scotland; U+1F3F4 U+E0067 U+E0062 U+E0073 U+E0063 U+E0074 U+E007F +๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ flag: Wales; U+1F3F4 U+E0067 U+E0062 U+E0077 U+E006C U+E0073 U+E007F diff --git a/.config/files b/.config/files new file mode 100644 index 0000000..6e07499 --- /dev/null +++ b/.config/files @@ -0,0 +1,15 @@ +bf ${XDG_CONFIG_HOME:-$HOME/.config}/files +bd ${XDG_CONFIG_HOME:-$HOME/.config}/directories +bw ${XDG_CONFIG_HOME:-$HOME/.config}/bookmarks +cfa ${XDG_CONFIG_HOME:-$HOME/.config}/aliasrc +cfz $ZDOTDIR/.zshrc +cfv ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim +cfm ${XDG_CONFIG_HOME:-$HOME/.config}/mutt/muttrc +cfx ${XDG_CONFIG_HOME:-$HOME/.config}/Xresources +cfu ${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls +cfn ${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/config +cfmb ${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/bindings +cfmc ${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/config +cfk ${XDG_CONFIG_HOME:-$HOME/.config}/sxhkd/sxhkdrc +cfi ${XDG_CONFIG_HOME:-$HOME/.config}/i3/config +cfb ${XDG_CONFIG_HOME:-$HOME/.config}/i3blocks/config diff --git a/.config/fontconfig/fonts.conf b/.config/fontconfig/fonts.conf new file mode 100755 index 0000000..3427ece --- /dev/null +++ b/.config/fontconfig/fonts.conf @@ -0,0 +1,28 @@ + + + + + + serif + Linux Libertine + + + sans-serif + Cantarell + + + sans + Cantarell + + + monospace + Inconsolata + + + + + monospace + Symbola + + + diff --git a/.config/gtk-2.0/gtkfilechooser.ini b/.config/gtk-2.0/gtkfilechooser.ini new file mode 100644 index 0000000..3fb28c7 --- /dev/null +++ b/.config/gtk-2.0/gtkfilechooser.ini @@ -0,0 +1,11 @@ +[Filechooser Settings] +LocationMode=path-bar +ShowHidden=false +ShowSizeColumn=true +GeometryX=1105 +GeometryY=500 +GeometryWidth=990 +GeometryHeight=800 +SortColumn=modified +SortOrder=ascending +StartupMode=recent diff --git a/.config/gtk-2.0/gtkrc-2.0 b/.config/gtk-2.0/gtkrc-2.0 new file mode 100644 index 0000000..9aa6a6e --- /dev/null +++ b/.config/gtk-2.0/gtkrc-2.0 @@ -0,0 +1,19 @@ +# DO NOT EDIT! This file will be overwritten by LXAppearance. +# Any customization should be done in ~/.gtkrc-2.0.mine instead. + +include "/home/luke/.gtkrc-2.0.mine" +gtk-theme-name="Arc-Gruvbox" +gtk-icon-theme-name="Adwaita" +gtk-font-name="Sans 10" +gtk-cursor-theme-name="Adwaita" +gtk-cursor-theme-size=0 +gtk-toolbar-style=GTK_TOOLBAR_TEXT +gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR +gtk-button-images=0 +gtk-menu-images=1 +gtk-enable-event-sounds=1 +gtk-enable-input-feedback-sounds=1 +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle="hintfull" +gtk-xft-rgba="rgb" diff --git a/.config/gtk-3.0/bookmarks b/.config/gtk-3.0/bookmarks new file mode 100644 index 0000000..f47e778 --- /dev/null +++ b/.config/gtk-3.0/bookmarks @@ -0,0 +1 @@ +file:///home/alex/Drive diff --git a/.config/gtk-3.0/settings.ini b/.config/gtk-3.0/settings.ini new file mode 100644 index 0000000..371c307 --- /dev/null +++ b/.config/gtk-3.0/settings.ini @@ -0,0 +1,16 @@ +[Settings] +gtk-theme-name=Arc-Gruvbox +gtk-icon-theme-name=Adwaita +gtk-font-name=Sans 10 +gtk-cursor-theme-size=0 +gtk-toolbar-style=GTK_TOOLBAR_TEXT +gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR +gtk-button-images=0 +gtk-menu-images=1 +gtk-enable-event-sounds=1 +gtk-enable-input-feedback-sounds=1 +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle=hintfull +gtk-xft-rgba=rgb +gtk-cursor-theme-name=Adwaita diff --git a/.config/homepage/bookmarks b/.config/homepage/bookmarks new file mode 100644 index 0000000..81cbd56 --- /dev/null +++ b/.config/homepage/bookmarks @@ -0,0 +1,15 @@ +aur.archlinux.org/ +file:///home/dt/.surf/html/homepage.html +distrowatch.com/ +https://gitlab.com/dwt1 +https://www.youtube.com/c/DistroTube/ +https://www.patreon.com/distrotube +https://socialblade.com/youtube/c/distrotube +https://mastodon.technology/web/accounts/85897 +https://diasp.org/stream +https://www.reddit.com/r/linux/ +https://forum.members.fsf.org/ +google.com/?gws_rd=ssl +suckless.org/ +https://distrowatch.com/ +https://www.omgubuntu.co.uk/ diff --git a/.config/homepage/html/empty.html b/.config/homepage/html/empty.html new file mode 100644 index 0000000..020dbe3 --- /dev/null +++ b/.config/homepage/html/empty.html @@ -0,0 +1,10 @@ + + + + vimb + + + + + + diff --git a/.config/homepage/html/homepage.html b/.config/homepage/html/homepage.html new file mode 100644 index 0000000..977d27a --- /dev/null +++ b/.config/homepage/html/homepage.html @@ -0,0 +1,151 @@ + + + + + + + + Home + + + + + +
+
+
+
+
+
-
+
+
+
+ +
+ + + + diff --git a/.config/homepage/script.js b/.config/homepage/script.js new file mode 100644 index 0000000..e69de29 diff --git a/.config/homepage/styles/archlinux.css b/.config/homepage/styles/archlinux.css new file mode 100644 index 0000000..85b71a2 --- /dev/null +++ b/.config/homepage/styles/archlinux.css @@ -0,0 +1,186 @@ +body { + font-size: 13px !important; + background: #282a36 !important; + color: #d0d0d0 !important; +} +a { + color: #9cc4ff !important; +} +#archnavbar { + min-height: 40px !important; + padding: 10px 15px !important; + background: #282a36 !important; + border-bottom: 0px !important; +} +.article-content p, h4 a { + font-size: 1.3em !important; +} +h4, h4 a, li a { + font-size: 1.3em !important; +} +h4 a, li a, #content h1, #content h2, #content h3 { + color: #82aaff !important; +} +#news h3 a { + font-size: 1.3em !important; + background: #82aaff !important; + color: #282a36 !important; +} +h3 span.arrow { + display: none !important; +} +#pkgsearch { + background: #9cc4ff !important; +} +label { + color: #282a36 !important; +} +.box { + font-size: 1.3em; + background: #000000 !important; + color: #d0d0d0 !important; + border: 1px solid #555 !important; +} +pre { + background: #9cc4ff !important; + margin: 1em 0px !important; + border: 1px solid #666666 !important; +} +code { + color: #282a36 !important; + background: #9cc4ff !important; +} +p code { + color: #000 !important; + font-size: 12px !important; + background: #ff8b92 !important; +} + + +dl dt{ + color: #ff8b92 !important; + font-size: 1.2em; +} +dd a{ + color: #82aaff !important; + font-size: 1.2em; +} + + +/* ARCH WIKI */ + +#mw-panel .portal .body li { + font-size: 0.9em !important; +} +#mw-panel .portal h3 { + color: #ff8b92 !important; + font-size: 0.9em !important; +} +#content { + background: #282a36 !important; + border: none !important; +} +#toc, .toc, .mw-warning, .toccolours { + background-color: #000000 !important; + border: 1px solid #666666 !important; + color: #d0d0d0 !important; +} +.tocnumber, .toctogglelabel { + color: #d0d0d0 !important; +} +.mw-body-content p { + color: #d0d0d0 !important; +} +div#mw-head { + top: 38px !important; +} +div.vectorTabs li.selected { + border: 1px solid #666666 !important; + border-bottom-color: #666666 !important; + background-color: #000000 !important; + padding-bottom: 20px !important; +} +.vectorTabs span { + background: none !important; +} +.catlinks { + border: 1px solid #666666 !important; + background-color: #000000 !important; +} +.mw-body, .parsoid-body { + color: #d0d0d0 !important; + font-size: 1.2em !important; +} + + +/* AUR */ +.results th { + background-color: #282a36 !important; +} +.results tr:nth-child(2n+1), #article-list tr:nth-child(2n+1) { + background: #282a36 !important; +} +.results tr:nth-child(2n), #article-list tr:nth-child(2n) { + background: #1f212a !important; +} + + + +/* ARCH FORUMS */ +#brdmenu, #brdmenu a { + background: #000000 !important; + border-color: #444444 !important; +} +#brdmenu.inbox { + margin-left: 30px !important; +} +.pun, .punwrap { + background: #282a36 !important; + border: none !important; +} +.pun .blocktable th { + background: #000000 !important; + border-color: #000 !important; + color: #ff8b92 !important; +} +#punindex .blocktable h2 { + font-size: 1.2em !important; + color: #ff8b92 !important; +} +tr.rowodd { + background: #282a36 !important; +} +tr.roweven { + background: #282a36 !important; +} +.pun .blocktable td { + border-color: #444444 !important; +} +.pun .blockpost { + background: #282a36 !important; + border-color: #444444 !important; +} +.pun .blockpost h2 { + background: #000000 !important; + border: none !important; + color: #82aaff !important; +} +.pun .blockpost .postbody, .pun .blockpost .postfoot { + background: #282a36 !important; + border-color: #444444 !important; +} +#punviewtopic .blockpost dt, #punmoderate .blockpost dt { + top: -1.8em !important; + color: #ff8b92 !important; +} +.pun .postmsg, #punhelp code, #punhelp samp { + color: #d0d0d0 !important; +} +.pun .codebox { + border-color: #444444 !important; + background: #9cc4ff !important; + color: #000000 !important; +} +.pun .codebox pre { + border: none !important; +} diff --git a/.config/homepage/styles/arcolinux-info.css b/.config/homepage/styles/arcolinux-info.css new file mode 100644 index 0000000..9b0b8d4 --- /dev/null +++ b/.config/homepage/styles/arcolinux-info.css @@ -0,0 +1,27 @@ +body { + font-size: 13px; + background-color: #282a36 !important; + color: #d0d0d0 !important; +} +#main-header { + background-color: #282a36 !important; + margin: 0; +} + +#et-navigation > ul > li > a { + color: #c3e88d !important; +} + +.widget_text .textwidget { + background-color: #434758 !important; + +} + +h4.widgettitle { + color: #d0d0d0 !important; + background-color: #434758 !important; +} + +.textwidget p { + color: #d0d0d0 !important; +} \ No newline at end of file diff --git a/.config/homepage/styles/arcolinuxforum.css b/.config/homepage/styles/arcolinuxforum.css new file mode 100644 index 0000000..58174a5 --- /dev/null +++ b/.config/homepage/styles/arcolinuxforum.css @@ -0,0 +1,48 @@ +body { + font-size: 13px; + background-color: #282a36 !important; + background-image: none !important; + color: #d0d0d0 !important; +} +h1 { + color: #e1acff !important; +} +.above { + border: 0px !important; + background: #282a36 !important; +} +.backhead { + background: #282a36 !important; + border: 0px !important; + box-shadow: inset 0px -1px 0 #282a36 !important; +} +.headerbar { + background: #282a36 !important; +} +.site-description p { + color: #c3e88d !important; +} +div#content { + background: #282a36 !important; +} +div.forabg { + background: #22232e !important; +} +dl.row-item { + color: #d0d0d0; + text-shadow: none; +} +ul.topiclist { + background: # !important; +} +li.row { + + background-color: #282a36 !important; + padding: 4px; + text-shadow: none; + +} +a.forumtitle { + color: #e1acff !important; + text-shadow: none; +} \ No newline at end of file diff --git a/.config/homepage/styles/empty.css b/.config/homepage/styles/empty.css new file mode 100644 index 0000000..c7324a2 --- /dev/null +++ b/.config/homepage/styles/empty.css @@ -0,0 +1,186 @@ +body { + font-size: 13px !important; + background: #000000!important; + color: #d0d0d0 !important; +} +a { + color: #9cc4ff !important; +} +#archnavbar { + min-height: 40px !important; + padding: 10px 15px !important; + background: #282a36 !important; + border-bottom: 0px !important; +} +.article-content p, h4 a { + font-size: 1.3em !important; +} +h4, h4 a, li a { + font-size: 1.3em !important; +} +h4 a, li a, #content h1, #content h2, #content h3 { + color: #82aaff !important; +} +#news h3 a { + font-size: 1.3em !important; + background: #82aaff !important; + color: #282a36 !important; +} +h3 span.arrow { + display: none !important; +} +#pkgsearch { + background: #9cc4ff !important; +} +label { + color: #282a36 !important; +} +.box { + font-size: 1.3em; + background: #000000 !important; + color: #d0d0d0 !important; + border: 1px solid #555 !important; +} +pre { + background: #9cc4ff !important; + margin: 1em 0px !important; + border: 1px solid #666666 !important; +} +code { + color: #282a36 !important; + background: #9cc4ff !important; +} +p code { + color: #000 !important; + font-size: 12px !important; + background: #ff8b92 !important; +} + + +dl dt{ + color: #ff8b92 !important; + font-size: 1.2em; +} +dd a{ + color: #82aaff !important; + font-size: 1.2em; +} + + +/* ARCH WIKI */ + +#mw-panel .portal .body li { + font-size: 0.9em !important; +} +#mw-panel .portal h3 { + color: #ff8b92 !important; + font-size: 0.9em !important; +} +#content { + background: #282a36 !important; + border: none !important; +} +#toc, .toc, .mw-warning, .toccolours { + background-color: #000000 !important; + border: 1px solid #666666 !important; + color: #d0d0d0 !important; +} +.tocnumber, .toctogglelabel { + color: #d0d0d0 !important; +} +.mw-body-content p { + color: #d0d0d0 !important; +} +div#mw-head { + top: 38px !important; +} +div.vectorTabs li.selected { + border: 1px solid #666666 !important; + border-bottom-color: #666666 !important; + background-color: #000000 !important; + padding-bottom: 20px !important; +} +.vectorTabs span { + background: none !important; +} +.catlinks { + border: 1px solid #666666 !important; + background-color: #000000 !important; +} +.mw-body, .parsoid-body { + color: #d0d0d0 !important; + font-size: 1.2em !important; +} + + +/* AUR */ +.results th { + background-color: #282a36 !important; +} +.results tr:nth-child(2n+1), #article-list tr:nth-child(2n+1) { + background: #282a36 !important; +} +.results tr:nth-child(2n), #article-list tr:nth-child(2n) { + background: #1f212a !important; +} + + + +/* ARCH FORUMS */ +#brdmenu, #brdmenu a { + background: #000000 !important; + border-color: #444444 !important; +} +#brdmenu.inbox { + margin-left: 30px !important; +} +.pun, .punwrap { + background: #282a36 !important; + border: none !important; +} +.pun .blocktable th { + background: #000000 !important; + border-color: #000 !important; + color: #ff8b92 !important; +} +#punindex .blocktable h2 { + font-size: 1.2em !important; + color: #ff8b92 !important; +} +tr.rowodd { + background: #282a36 !important; +} +tr.roweven { + background: #282a36 !important; +} +.pun .blocktable td { + border-color: #444444 !important; +} +.pun .blockpost { + background: #282a36 !important; + border-color: #444444 !important; +} +.pun .blockpost h2 { + background: #000000 !important; + border: none !important; + color: #82aaff !important; +} +.pun .blockpost .postbody, .pun .blockpost .postfoot { + background: #282a36 !important; + border-color: #444444 !important; +} +#punviewtopic .blockpost dt, #punmoderate .blockpost dt { + top: -1.8em !important; + color: #ff8b92 !important; +} +.pun .postmsg, #punhelp code, #punhelp samp { + color: #d0d0d0 !important; +} +.pun .codebox { + border-color: #444444 !important; + background: #9cc4ff !important; + color: #000000 !important; +} +.pun .codebox pre { + border: none !important; +} diff --git a/.config/homepage/styles/homepage.css b/.config/homepage/styles/homepage.css new file mode 100644 index 0000000..6f94d49 --- /dev/null +++ b/.config/homepage/styles/homepage.css @@ -0,0 +1,125 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto+Mono'); +@import url('https://fonts.googleapis.com/css?family=Roboto'); +@import url('https://fonts.googleapis.com/css?family=Anton'); + +body { + background-color: #282a36; + margin: 0px; +} + +.container { + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} + +#clock { + font-family: sans-serif; + font-size: 4.0rem; + font-weight: 600; + font-family: "Anton"; + color: #fff; + margin-bottom: .25em; +} + +#search { + width: 100%; + height: 100vh; + background-color: #000000; + display: none; + position: absolute; + box-sizing: border-box; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#search-field { + width: 90%; + padding: .75em 1em; + box-sizing: border-box; + background-color: #000000; + border: solid 0px #000000; + font-family: "Roboto Mono"; + font-size: 4rem; + color: #f2f2f2; + outline: none; + border-radius: 3px; + margin-bottom: 1em; + text-align: center; +} + +.weather-container { + width: 30%; + background-color: #000000; + padding: 1em; + border-radius: 3px; + font-family: "Roboto Mono"; + font-size: 1.2rem; + color: #fff; + text-align: center; +} +.inline { + display: inline-block; +} + +.bookmark-container { + display: flex; + flex-direction: row; + justify-content: center; + width: 60%; + margin: 1em 0em; +} + +@media only screen and (max-width: 960px) { + .container { + height: auto; + } + #clock { + margin-top: 1em; + } + .container > .bookmark-container { + flex-direction: column; + width: 60%; + } + .bookmark-container > .bookmark-set { + width: auto; + margin: 1em 0em; + } +} + +.bookmark-set{ + padding: 1em; + background-color: #000000; + border-radius: 3px; + font-family: "Roboto Mono"; + font-size: .85rem; + width: 25%; + height: 16em; + margin: 0em .5em; +} +.bookmark-inner-container { + overflow-y: scroll; + height: 80%; + vertical-align: top; +} +.bookmark-title { + font-family: "Roboto"; + font-size: 1.2rem; + font-weight: 600; + color: #ededed; + margin: 0em 0em .35em 0em; +} +.bookmark { + text-decoration: none; + color: #8c8c8b; + display:block; + margin: .4em 0em; +} +.bookmark:hover { + color: #fff; +} + diff --git a/.config/homepage/styles/suckless.css b/.config/homepage/styles/suckless.css new file mode 100644 index 0000000..4b41535 --- /dev/null +++ b/.config/homepage/styles/suckless.css @@ -0,0 +1,41 @@ +body { + font-size: 13px; + background-color: #282a36 !important; + color: #d0d0d0 !important; +} + +#header { + background-color: #282a36 !important; + clear: both; + color: #c3e88d !important; +} + +a { + color: #82aaff !important; +} + +#header a { + color: #e1acff !important; +} + +#menu { + clear: both; + color: #c792ea; + font-weight: bold; + overflow: hidden; + padding: 0.7ex; + border: 0px !important; +} + +#menu a { + color: #d0d0d0 !important; +} + +#nav li a:hover { + background-color: #282a36 !important; +} + +h1, h2 { + color: #f07178 !important; +} + diff --git a/.config/homepage/styles/wikipedia.css b/.config/homepage/styles/wikipedia.css new file mode 100644 index 0000000..b2127c8 --- /dev/null +++ b/.config/homepage/styles/wikipedia.css @@ -0,0 +1,4 @@ +* { + background-color: #282A36; + color: #eee; +} diff --git a/.config/inputrc b/.config/inputrc new file mode 100644 index 0000000..f9b94dd --- /dev/null +++ b/.config/inputrc @@ -0,0 +1,19 @@ +$include /etc/inputrc +set editing-mode vi +$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/lf/lfrc b/.config/lf/lfrc new file mode 100644 index 0000000..741f1a9 --- /dev/null +++ b/.config/lf/lfrc @@ -0,0 +1,69 @@ +# Luke's lf settings + +# Basic vars +set shell sh +set previewer ~/.config/lf/scope +set shellopts '-eu' +set ifs "\n" +set scrolloff 10 +set color256 +set icons # Enable icons. Requires nerd fonts and LF_ICONS variable. + +# cmds/functions +cmd open ${{ + case $(file --mime-type $f -b) in + text/troff) man ./ $f;; + text/*) $EDITOR $fx;; + image/x-xcf|image/svg+xml) setsid gimp $f >/dev/null 2>&1 & ;; + image/*) rotdir $f | setsid sxiv -aio 2>&1 | lf-select & ;; + audio/*) mpv --input-ipc-server=/tmp/mpvsoc$(date +%%s) $f ;; + video/*) setsid mpv --input-ipc-server=/tmp/mpvsoc$(date +%%s) $f -quiet >/dev/null 2>&1 & ;; + application/pdf) setsid zathura $fx >/dev/null 2>&1 & ;; + *) for f in $fx; do setsid $OPENER $f >/dev/null 2>&1 & done;; + esac +}} + +cmd rename %[ -e $1 ] && printf "file exists" || mv $f $1 + +cmd delete ${{ + set -f + printf "%s\n\t" "$fx" + printf "delete?[y/N]" + read ans + [ $ans = "y" ] && rm -rf $fx +}} + +cmd moveto ${{ + set -f + clear; echo "Move to where?" + dest="$(cut -d' ' -f2- ~/.config/directories | fzf)" && + eval mv -iv $fx $dest && + notify-send "๐Ÿšš File(s) moved." "File(s) moved to $dest." +}} + +cmd copyto ${{ + set -f + clear; echo "Copy to where?" + dest="$(cut -d' ' -f2- ~/.config/directories | fzf)" && + eval cp -ivr $fx $dest && + notify-send "๐Ÿ“‹ File(s) copied." "File(s) copies to $dest." +}} + +# Bindings +map c $lf -remote "send $id cd $(cut -d' ' -f2 ~/.config/directories | fzf)" +map $lf -remote "send $id select '$(fzf)'" +map J $lf -remote "send $id cd $(cut -d' ' -f2 ~/.config/directories | fzf)" +map gh +map g top +map D delete +map C copyto +map M moveto +map a push %mkdir +map r push :rename +map R $lf -remote "send $id push :rename$f" +map reload +map shell +map x $$f +map X !$f +map o &mimeopen $f +map O $mimeopen --ask $f diff --git a/.config/lf/scope b/.config/lf/scope new file mode 100755 index 0000000..94822ef --- /dev/null +++ b/.config/lf/scope @@ -0,0 +1,59 @@ +#!/bin/bash + +set -C -f -u +#IFS=$'\n' +IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" + +# ANSI color codes are supported. +# STDIN is disabled, so interactive scripts won't work properly + +# This script is considered a configuration file and must be updated manually. + +# Meanings of exit codes: +# code | meaning | action of ranger +# -----+------------+------------------------------------------- +# 0 | success | Display stdout as preview +# 1 | no preview | Display no preview at all +# 2 | plain text | Display the plain content of the file + +# Script arguments +FILE_PATH="${1}" # Full path of the highlighted file +HEIGHT="${2}" + +#FILE_EXTENSION="${FILE_PATH##*.}" +#FILE_EXTENSION_LOWER=$(echo ${FILE_EXTENSION} | tr '[:upper:]' '[:lower:]') + +# Settings +HIGHLIGHT_SIZE_MAX=262143 # 256KiB +HIGHLIGHT_TABWIDTH=8 +HIGHLIGHT_STYLE='pablo' + + +handle_mime() { + local mimetype="${1}" + case "${mimetype}" in + text/html) w3m -dump "${FILE_PATH}" ;; + text/troff) man ./ "${FILE_PATH}" | col -b ;; + text/* | */xml) + if [ "$( stat --printf='%s' -- "${FILE_PATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]; then + exit 2 + fi + if [ "$( tput colors )" -ge 256 ]; then + local highlight_format='xterm256' + else + local highlight_format='ansi' + fi + highlight --replace-tabs="${HIGHLIGHT_TABWIDTH}" --out-format="${highlight_format}" \ + --style="${HIGHLIGHT_STYLE}" --force -- "${FILE_PATH}" ;; + application/zip) atool --list -- "${FILE_PATH}" ;; + image/*) chafa --fill=block --symbols=block -c 256 -s 80x"${HEIGHT}" "${FILE_PATH}" || exit 1;; + audio/*|application/octet-stream) mediainfo "${FILE_PATH}" || exit 1;; + video/*) ffmpegthumbnailer -s 0 -i "${FILE_PATH}" -m -o "$HOME/.cache/thumb.jpg" && chafa --fill=all --symbols=all -c 256 -s 80x80 "$HOME/.cache/thumb.jpg" || exit 1;; + */pdf) pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - ;; + *opendocument*) odt2txt "${FILE_PATH}" ;; + esac +} + +MIMETYPE="$( file --dereference --brief --mime-type -- "${FILE_PATH}" )" +handle_mime "${MIMETYPE}" +exit 1 diff --git a/.config/mpd/mpd.conf b/.config/mpd/mpd.conf new file mode 100644 index 0000000..0edc4f8 --- /dev/null +++ b/.config/mpd/mpd.conf @@ -0,0 +1,26 @@ +db_file "~/.config/mpd/database" +log_file "~/.config/mpd/log" +music_directory "~/msc" +playlist_directory "~/.config/mpd/playlists" +pid_file "~/.config/mpd/pid" +state_file "~/.config/mpd/state" +sticker_file "~/.config/mpd/sticker.sql" + +auto_update "yes" + +bind_to_address "127.0.0.1" +restore_paused "yes" +max_output_buffer_size "16384" + +audio_output { + type "pulse" + name "pulse audio" + mixer_type "software" +} + +audio_output { +type "fifo" +name "toggle_visualizer" +path "/tmp/mpd.fifo" +format "44100:16:2" +} diff --git a/.config/mpd/playlists/lofi.m3u b/.config/mpd/playlists/lofi.m3u new file mode 100644 index 0000000..635d1a2 --- /dev/null +++ b/.config/mpd/playlists/lofi.m3u @@ -0,0 +1,721 @@ +lofi/20190915-i found my home in your arms - lofi hip hop mix.opus +lofi/20191208-1 A.M Study Session ๐Ÿ“š - [lofi hip hop_chill beats].opus +lofi/20200316-Just take care of yourself โ— lofi hip hop mix โ— Nostalgia.opus +lofi/20170505-close your eyes (lo-fi_chill mix).mkv +lofi/20190127-ใ€๏ผก๏ผณ๏ผซใ€€๏ผญ๏ผฅใ€€๏ผฏ๏ผต๏ผดใ€€๏ผฏ๏ผฎใ€€๏ผกใ€€๏ผค๏ผก๏ผด๏ผฅใ€‘_ Japanese Lofi _ Japanese_Anime Lofi Hip Hop Mix.m4a +lofi/ikigai/20170327-Hazy Year - quit asking me for sandwiches.opus +lofi/ikigai/20170328-engelwood - passing.by.opus +lofi/ikigai/20170329-tomcbumpz - again.opus +lofi/ikigai/20170330-potsu x Chance Thrash - selfish.opus +lofi/ikigai/20170401-tristan. - Shadฮฃ..opus +lofi/ikigai/20170402-awake - love of mine (prod. loprofile).opus +lofi/ikigai/20170403-ร†kaSora - one day in Japan.opus +lofi/ikigai/20170404-ใ‘๏ฝ SURF - sid's lesson.m4a +lofi/ikigai/20170405-HuggerMugger - Anywhere But Here.opus +lofi/ikigai/20170406-krylic. - 3am.opus +lofi/ikigai/20170410-Hazy Year - smoking on starstuff.opus +lofi/ikigai/20170411-dreya - blue.opus +lofi/ikigai/20170412-NarcolepZzz - bittersweet.opus +lofi/ikigai/20170413-cyberchase - OH MANNN!!!!.opus +lofi/ikigai/20170414-aclmte better days.opus +lofi/ikigai/20170414-ikigai Merch!!!.opus +lofi/ikigai/20170415-elijah who - hol up.opus +lofi/ikigai/20170416-ldst - drm_sqnc (w_ 990x).opus +lofi/ikigai/20170417-toph - purr-fect.opus +lofi/ikigai/20170418-prima - autumn leaves..opus +lofi/ikigai/20170419-mlshoto - the flower we saw that day.opus +lofi/ikigai/20170422-potsu - Chinatown.opus +lofi/ikigai/20170423-cฮฑde sweฯ„ - sincerely..opus +lofi/ikigai/20170424-loprofile . - โ˜๏ธ entre.nubes. โ˜๏ธ.opus +lofi/ikigai/20170425-shogonodo - snowfield.opus +lofi/ikigai/20170427-geerad - jets.m4a +lofi/ikigai/20170428-tusken. - tusken soul.opus +lofi/ikigai/20170429-NIKK BLVKK - Zephyr's Flutter.opus +lofi/ikigai/20170430-sugi.wa - urtha1.opus +lofi/ikigai/20170503-B I N A - children.opus +lofi/ikigai/20170504-Aso - Loungin.opus +lofi/ikigai/20170505-lildeath - banana split.opus +lofi/ikigai/20170506-driver - take care.opus +lofi/ikigai/20170507-Jayv - Sweater Weather [Jayv Mix].opus +lofi/ikigai/20170510-Tentacle - Space.opus +lofi/ikigai/20170512-ninjoi.- Misty.opus +lofi/ikigai/20170513-Taiko - Leaves.opus +lofi/ikigai/20170516-Chidi Himself - All Mine (demo).opus +lofi/ikigai/20170517-elijah who - i've got her love.opus +lofi/ikigai/20170519-rose image. dreaming on yoshi island. (w_ rose image.).opus +lofi/ikigai/20170520-K a l i m a n - Rivers Of Thought.opus +lofi/ikigai/20170521-chuckee. - gingerale..opus +lofi/ikigai/20170522-Objektiv - broadwaze -.opus +lofi/ikigai/20170523-KXLD. - I Really Wrote This For You..opus +lofi/ikigai/20170525-elli - flower crown.opus +lofi/ikigai/20170529-Veople - Miko.opus +lofi/ikigai/20170530-sugi.wa - je t'aime.opus +lofi/ikigai/20170531-lylo - onceagain.opus +lofi/ikigai/20170602-ACS ONE - Amor.opus +lofi/ikigai/20170606-Korporal K - Genki..m4a +lofi/ikigai/20170608-potsu - moonglow.opus +lofi/ikigai/20170609-Apollo - Why'd I Wait.opus +lofi/ikigai/20170612-l o k a ! jinsang & loka! - espresso (ft. lucy weld).opus +lofi/ikigai/20170613-potsu - holding your hand.opus +lofi/ikigai/20170615-lando! - ~dream~.opus +lofi/ikigai/20170618-The Albion - Home.opus +lofi/ikigai/20170620-MVLI - Cat Dreams.opus +lofi/ikigai/20170624-soho - sunsets.opus +lofi/ikigai/20170626-Sugar Cane Davis - driving.opus +lofi/ikigai/20170627-ldst biu ~ (w_ i eat plants for a living).opus +lofi/ikigai/20170702-d3tails - alien days.opus +lofi/ikigai/20170704-Idealism - Controlla.opus +lofi/ikigai/20170705-cucu [ๅ›ž้กง] - i don't trust nobody (feat. shiloh).opus +lofi/ikigai/20170707-Zach Farache - The Loser (bimyo remix).opus +lofi/ikigai/20170708-KUPLA - still breathing.opus +lofi/ikigai/20170709-kasper - all of you.opus +lofi/ikigai/20170710-driver - OWTC bootleg.opus +lofi/ikigai/20170711-oschea - homemade soup.opus +lofi/ikigai/20170712-SHIKARI ๐Ÿ’” - INFINITY.opus +lofi/ikigai/20170714-zugzwang - eating skittles on the moon.opus +lofi/ikigai/20170717-furino - about claudia (w_ importmedia).opus +lofi/ikigai/20170718-potsu - holding your hand.opus +lofi/ikigai/20170719-leavv - one day we will.opus +lofi/ikigai/20170720-ใƒ–ใƒญใƒƒใ‚ฏใƒซ miss u _ hate u.m4a +lofi/ikigai/20170722-Orca Vibes - Journey.opus +lofi/ikigai/20170723-afternoon - so mean ft. mxmtoon, samsa, love-sadKiD.opus +lofi/ikigai/20170724-navienta - i'll keep going....opus +lofi/ikigai/20170725-UPRIZE - Good Day.opus +lofi/ikigai/20170729-best of boxboys.opus +lofi/ikigai/20170731-mura;kami - snoozi'ng.opus +lofi/ikigai/20170801-I Won't Lie - Timeless.opus +lofi/ikigai/20170803-luv.ly - the girl from..opus +lofi/ikigai/20170805-redflushed - showers.opus +lofi/ikigai/20170807-mura;kami - rose in blue.opus +lofi/ikigai/20170810-potsu x lando! - breakfast.opus +lofi/ikigai/20170814-keshi - if youre not the one for me who is.opus +lofi/ikigai/20170815-Richard orofino - not old enough (hateful remix).opus +lofi/ikigai/20170816-Atwood - Most of my friends.m4a +lofi/ikigai/20170817-chuckee. - my girl likes to skate in the afternoon.opus +lofi/ikigai/20170819-sugiwa - the end.opus +lofi/ikigai/20170820-Rook1e - loving u (w_ planttvibes).opus +lofi/ikigai/20170821-Kogane - Sapporo.opus +lofi/ikigai/20170824-Play Konoki - Forgive me.opus +lofi/ikigai/20170825-NEW SUBMISSION SITE!.opus +lofi/ikigai/20170826-mt.tkovr. ๐Ÿ—ป- new kicks.m4a +lofi/ikigai/20170829-biosphere - halfmoon.opus +lofi/ikigai/20170830-yung quiet - flexxx.opus +lofi/ikigai/20170831-hazy nights - this is the last song i'll ever write for you (no idea why mix).opus +lofi/ikigai/20170903-NVTHVN - someday (ft. lanie & reacquainted).opus +lofi/ikigai/20170904-olivia herdt โ‚ - a little lost [ olivia herdt x niquo ].opus +lofi/ikigai/20170905-biosphere - dreaming of blueberry pancakes.opus +lofi/ikigai/20170906-Liu BAE - Mocambo.opus +lofi/ikigai/20170908-hakaisu - far away, yet somewhere.opus +lofi/ikigai/20170912-afternoon - be the same (w_ boxboys).m4a +lofi/ikigai/20170914-love-sadKiD - M.I.L.F. (prod. Frith).opus +lofi/ikigai/20170916-Kogane - Sapporo.opus +lofi/ikigai/20170917-yung quiet - blendn [prod laptopboy].opus +lofi/ikigai/20170918-hakaisu - wishing it would rain.opus +lofi/ikigai/20170920-through & through - stranger than fiction (w_ silk.y.).opus +lofi/ikigai/20170923-nakun. - suematsu.opus +lofi/ikigai/20170924-skirts - Don't Let Me Go (Demo).opus +lofi/ikigai/20170926-redpest โ˜ฏ - Late night drives with her.opus +lofi/ikigai/20171002-cucu [ๅ›ž้กง] - i guess u forgot about me.opus +lofi/ikigai/20171004-keshi - over u.m4a +lofi/ikigai/20171007-legalvariety - my last hope.opus +lofi/ikigai/20171008-Matt Quentin - Waves.opus +lofi/ikigai/20171012-ฮฒeta max - tap water _ prod. mario.opus +lofi/ikigai/20171013-afternoon - month & a half (ft. khai dreams, THIAGO & Atwood) prod. Afternoon & luv.ly.opus +lofi/ikigai/20171015-that guitar sound we all like pt. 2.opus +lofi/ikigai/20171018-biosphere - strangers (ft. love-sadKiD, Chris Wright, CIKI).opus +lofi/ikigai/20171023-Rook1e - the cute girl from the froyo shop (w_ Sky.High).opus +lofi/ikigai/20171025-knapsack - Hey Thursday.opus +lofi/ikigai/20171027-ok2222 - im feeling sad so i made a sad song.opus +lofi/ikigai/20171029-furino - i hope you love me back.opus +lofi/ikigai/20171030-StriveAU - keep me warm (ft hazy nights).opus +lofi/ikigai/20171031-Chopef - Deep Wood.opus +lofi/ikigai/20171101-New Merch!!! Thank you for 40k!.opus +lofi/ikigai/20171107-biosphere - it's a great big world.opus +lofi/ikigai/20171111-KRAPF - this is how it feels to be by your side.opus +lofi/ikigai/20171112-Fastoche - You're Finally Here.opus +lofi/ikigai/20171114-Chopef - Sunset Talk.opus +lofi/ikigai/20171115-ฮฒeta max - cherry red _ prod. Rook1e & j'san.opus +lofi/ikigai/20171117-mochi - puzzles.opus +lofi/ikigai/20171119-dybredly - i just feel like it.opus +lofi/ikigai/20171122-hazy nights - because.opus +lofi/ikigai/20171128-ok2222 - memories of us..opus +lofi/ikigai/20171203-Fris - wonderful life.opus +lofi/ikigai/20171205-groundfold - all we had is gone.opus +lofi/ikigai/20171209-Oui Lele - ๏ฝ˜.opus +lofi/ikigai/20171213-w00ds - d1st4nt.opus +lofi/ikigai/20171215-Purple Hex - Spirals.opus +lofi/ikigai/20171216-love-sadKiD - Breathe w_ Atwood (prod. bluknight).opus +lofi/ikigai/20171217-Godzimo - Ma(n)ta.opus +lofi/ikigai/20171218-ok2222 - i dont love you.opus +lofi/ikigai/20171222-hazy nights - Stay..opus +lofi/ikigai/20171225-biosphere - my merry christmas (ft. limbo, RYCE, Chris Wright).opus +lofi/ikigai/20171227-flavors - umbrella.opus +lofi/ikigai/20171229-korou. - journey..opus +lofi/ikigai/20180102-redpest โ˜ฏ - Falling In Love Pt. 3.opus +lofi/ikigai/20180103-June - It Seems Like.opus +lofi/ikigai/20180104-barnes blvd. - now, i see.opus +lofi/ikigai/20180107-sad boy with a laptop - you make my heart go doki doki.opus +lofi/ikigai/20180108-The Walk - IDGAF.opus +lofi/ikigai/20180109-Yotzu - Rainy Day.opus +lofi/ikigai/20180114-June - Before Anyone Else.opus +lofi/ikigai/20180115-saikenbeats - Templo de la belleza.opus +lofi/ikigai/20180119-sad boy with a laptop - lets eat pocky and look at stars together.opus +lofi/ikigai/20180122-keshi - say something (prod. Rook1e).opus +lofi/ikigai/20180124-Odtsu - petit.opus +lofi/ikigai/20180125-Peacock Affect - Who Cares If You Exist (Eisu remix).opus +lofi/ikigai/20180128-khai dreams - Through and Through (Atwood Remix).opus +lofi/ikigai/20180130-neeks - when you smile.opus +lofi/ikigai/20180205-lil mochi - I Hate The Way I Dont Hate You_Put The Pen Down.opus +lofi/ikigai/20180212-MEECHY -๏ผณ๏ฝ๏ฝ•๏ฝŒ ๏ผณ๏ฝ…๏ฝ๏ฝ’๏ฝƒ๏ฝˆ๏ฝ‰๏ฝŽ.opus +lofi/ikigai/20180214-Tyfon - Void (Prod. Lil Slump).opus +lofi/ikigai/20180219-sad boy with a laptop - thanks for making my life a little more bearable.opus +lofi/ikigai/20180220-Oui Lele -๏ฝ‚๏ฝ…๏ฝ”๏ฝ”๏ฝ…๏ฝ’ ๏ฝ„๏ฝ๏ฝ™๏ฝ“.opus +lofi/ikigai/20180222-Julie Cool - really nothing.opus +lofi/ikigai/20180226-Peter Kuli - Cozy w_ still haze.opus +lofi/ikigai/20180227-kavv - Violet.opus +lofi/ikigai/20180228-YNGBLOOD - Butterflies.opus +lofi/ikigai/20180303-love-sadKiD - Students (Prod. Ka$tro).opus +lofi/ikigai/20180306-fortnight - Aimlessly driftin.opus +lofi/ikigai/20180307-jeiku - i just can't stay.opus +lofi/ikigai/20180309-J E N - ๏ผฎ๏ผฏ ๏ผฌ๏ผต๏ผฃ๏ผฉ๏ผค๏ผฉ๏ผด๏ผน.opus +lofi/ikigai/20180312-through & through - your name.opus +lofi/ikigai/20180314-w00ds - bl00m.opus +lofi/ikigai/20180320-fortnight - 2000.opus +lofi/ikigai/20180322-ok2222 - ocean of blue..opus +lofi/ikigai/20180324-ใ€˜ E I S U ใ€™- Alone.opus +lofi/ikigai/20180327-nekoi - starry.opus +lofi/ikigai/20180328-itsnoday - it was just a fire drill.opus +lofi/ikigai/20180330-aura - sunset breeze.opus +lofi/ikigai/20180402-City Girl - runaway.opus +lofi/ikigai/20180403-ok2222 x j'san - on and on feat. khai dreams & barnes blvd..opus +lofi/ikigai/20180405-June - I'll Be Back.opus +lofi/ikigai/20180406-neeks - your laugh is my favorite song.opus +lofi/ikigai/20180408-Odtsu - always late.opus +lofi/ikigai/20180410-MERCH AVAILABLE NOW.opus +lofi/ikigai/20180411-Claine - Follow Your Dreams.opus +lofi/ikigai/20180415-the sleep tape vol. 2 (lofi chill study mix 2019).opus +lofi/ikigai/20180416-korou. - this place..opus +lofi/ikigai/20180417-tired - yeaaa..m4a +lofi/ikigai/20180418-burbank - i got sad when i realized it was a dream.opus +lofi/ikigai/20180422-cvstuls - midwest depression.opus +lofi/ikigai/20180425-๐ŸŒบ๏ผต๏ผง๏ผฌ๏ผน ๏ผง๏ผฉ๏ผฒ๏ผฌ๐ŸŒบ- arthur has a bad day...opus +lofi/ikigai/20180426-yung quiet - it's a lonely city [prod yung quiet].opus +lofi/ikigai/20180430-potsu take me there w_ Chance Thrash.opus +lofi/ikigai/20180502-through & through - alive.opus +lofi/ikigai/20180505-MEECHY -๏ผฉ ๏ฝŠ๏ฝ•๏ฝ“๏ฝ” ๏ฝ—๏ฝ๏ฝŽ๏ฝ” ๏ฝ”๏ฝ ๏ฝŒ๏ฝ‰๏ฝ–๏ฝ….opus +lofi/ikigai/20180506-sad boy with a laptop - you're the dream i never wanna wake up from.opus +lofi/ikigai/20180509-ใ€˜ E I S U ใ€™& masked man & lofty - Fall Apart.opus +lofi/ikigai/20180510-fortnight - Benzie [87bpm].opus +lofi/ikigai/20180511-nat - even the sky reminds me of you.opus +lofi/ikigai/20180512-blkulv - Let Me Drown.opus +lofi/ikigai/20180513-STEFAN - Got What U Need (prod. Derrick Pannther).opus +lofi/ikigai/20180515-potsu - food court.opus +lofi/ikigai/20180516-Smitty Mamba - R O O F T O P.opus +lofi/ikigai/20180519-Slipfunc - moonwalkin.opus +lofi/ikigai/20180521-Prod. Seany OWE - Could I Ever Be Loved Feat. Little Kuma.opus +lofi/ikigai/20180524-kavv - Sweetheart.opus +lofi/ikigai/20180525-theor - smoke gets in your eyes.opus +lofi/ikigai/20180527-ok2222 x keshi - beside you.opus +lofi/ikigai/20180528-slipfunc - summer luv.opus +lofi/ikigai/20180529-sad boy with a laptop - you're the dream i never wanna wake up from (new beat tape in description).opus +lofi/ikigai/20180601-Mon-Day - u r cute.opus +lofi/ikigai/20180603-w00ds - kula world (dive).opus +lofi/ikigai/20180606-Powfu - feel it all (Prod. aquinaswc).m4a +lofi/ikigai/20180610-theor - august.opus +lofi/ikigai/20180611-June - Go.opus +lofi/ikigai/20180612-Sonorous - Outside.opus +lofi/ikigai/20180613-nion - bright.opus +lofi/ikigai/20180621-nat. - petrichor (w_ leftonseen).opus +lofi/ikigai/20180623-Powfu - i could never be loved (Prod. Seany OWE).opus +lofi/ikigai/20180624-nemo - lakes sunset drive (prod. osed.trunks).opus +lofi/ikigai/20180625-biosphere - pastel sunset [w_ barnes blvd.].opus +lofi/ikigai/20180626-Donny - Block Motion (prod. knapsack).opus +lofi/ikigai/20180628-love-sadKiD - Control (prod. tomcbumpz).opus +lofi/ikigai/20180630-glass pattern - twintails.opus +lofi/ikigai/20180701-sad boy with a laptop - you deserve more.m4a +lofi/ikigai/20180702-Powfu - days we had _ Feat. king theta (Prod. Jayhmez).opus +lofi/ikigai/20180704-Oui Lele - ๏ฝ“๏ฝˆ๏ฝ‰๏ฝŽ๏ฝ™ ๏ฝ…๏ฝ™๏ฝ…๏ฝ“.opus +lofi/ikigai/20180710-w00ds - Cloud Driftin.opus +lofi/ikigai/20180712-lil mochi - good morning.opus +lofi/ikigai/20180713-ok2222 - space travels (music video).opus +lofi/ikigai/20180716-DeadPlanets - Perfect Circle.opus +lofi/ikigai/20180717-Kalaido - Hanging Lanterns.opus +lofi/ikigai/20180718-luv.ly - hadda letcha know.m4a +lofi/ikigai/20180719-the girl next door - roses in france.opus +lofi/ikigai/20180720-Kudasai album anouncement - white noise.opus +lofi/ikigai/20180722-ใ€˜ E I S U ใ€™- As Long As I Got You [feat. Madson Project.].opus +lofi/ikigai/20180724-slipfunc - cherry smile.opus +lofi/ikigai/20180725-lost-fi - Opportunity.opus +lofi/ikigai/20180728-NVTHVN x park bird - Dance in the Living Room (ft. Forrest. & ok2222).opus +lofi/ikigai/20180730-marc - Oceans w_ demxntia & Indii G..opus +lofi/ikigai/20180731-renรฉ - january.opus +lofi/ikigai/20180802-north takoda - when the night falls.opus +lofi/ikigai/20180805-karson - it'll be ok.opus +lofi/ikigai/20180808-druid - doom.opus +lofi/ikigai/20180809-House Pet - UP ALL NIGHT.opus +lofi/ikigai/20180810-slipfunc - amid the flowers..opus +lofi/ikigai/20180813-zenben55 - BLOOD PART 2.opus +lofi/ikigai/20180814-w00ds - part of you.opus +lofi/ikigai/20180815-Mon-Day - ive been tired.opus +lofi/ikigai/20180817-lofi.samurai - honey.opus +lofi/ikigai/20180818-Kudasai - Overcast.opus +lofi/ikigai/20180822-kavv - beach night.opus +lofi/ikigai/20180824-Claine - So into YOU.m4a +lofi/ikigai/20180825-kelpie - confession.opus +lofi/ikigai/20180826-sad boy with a laptop - you were so far away.opus +lofi/ikigai/20180827-olielle x catcat - i just wanna love u.opus +lofi/ikigai/20180829-@sadisasxx - โ˜†love letterโ˜†.opus +lofi/ikigai/20180830-Monty Datta - Childhood Memories.opus +lofi/ikigai/20180902-The Walk - Cherry Smile (prod. slipfunc).opus +lofi/ikigai/20180903-yuutsu - desire.opus +lofi/ikigai/20180904-Jordan Maxwell - I Couldn't.opus +lofi/ikigai/20180905-slipfunc - sweet nothing.opus +lofi/ikigai/20180906-Sร˜Reclusive - Street Light.opus +lofi/ikigai/20180907-PinkPools. - Feel it..opus +lofi/ikigai/20180908-bluedoom - I was thinking about us.opus +lofi/ikigai/20180909-tired - i never want to lose her.opus +lofi/ikigai/20180910-MOSHi - Without you..opus +lofi/ikigai/20180911-slipfunc - glance.opus +lofi/ikigai/20180912-Danny Bonsai - far away.opus +lofi/ikigai/20180914-K The Infinite - ..insta girl & her mask ft. emawk.opus +lofi/ikigai/20180915-nilรถwh. - the night hides our tears.opus +lofi/ikigai/20180916-@sadidasxx - โœฐgoodbyeโœฐ.opus +lofi/ikigai/20180917-S M I T T Y M A M B A - T O O L A T E.m4a +lofi/ikigai/20180918-slipfunc - drowning in her eyes.opus +lofi/ikigai/20180920-marc - Parachute.opus +lofi/ikigai/20180923-Powfu - i know you're not happy.opus +lofi/ikigai/20180924-laevi - Everyone was pretending to be someone else.opus +lofi/ikigai/20180926-w00ds - Auburn Eyes (ft. Thomas Reid).opus +lofi/ikigai/20180927-ohsobrkn - why am i so different.opus +lofi/ikigai/20180928-StrangeMood - Memories.opus +lofi/ikigai/20180930-slipfunc - lust in translation.opus +lofi/ikigai/20181002-House On The Hill - Be Alright w_ Madson..opus +lofi/ikigai/20181003-mewsyc ใƒ„- i'm never good enough..opus +lofi/ikigai/20181004-hฬทxฬทpฬทeฬท - feels like were dying.opus +lofi/ikigai/20181005-Powfu - breakfast with the moon (Prod. Slipfunc).opus +lofi/ikigai/20181007-sad boy with a laptop - i was lost until i met you.opus +lofi/ikigai/20181008-nekoi โœจ- i can't describe this feeling..opus +lofi/ikigai/20181009-โœฐsadidasโœฐ - for the last time, forever.opus +lofi/ikigai/20181010-TheLazzyProject - Emotions.opus +lofi/ikigai/20181011-MOSHi - dead feelings.opus +lofi/ikigai/20181012-slipfunc - lovesick hug.opus +lofi/ikigai/20181016-Huey Daze - Take You There.opus +lofi/ikigai/20181017-Skinny Atlas - Stitches To Your Scars (feat. Mishaal).opus +lofi/ikigai/20181019-the notglorious mike. - power..opus +lofi/ikigai/20181021-omar - serene.opus +lofi/ikigai/20181023-Teqkoi - You Broke My Heart Again (ft. Aiko).opus +lofi/ikigai/20181024-slipfunc - cherish.opus +lofi/ikigai/20181025-Prod. Seany OWE - Stay Ft. Ariel McCleary.opus +lofi/ikigai/20181026-hamzah - im never coming down.opus +lofi/ikigai/20181028-DominusBeats x BVG - i'm so tired of disappointing you.opus +lofi/ikigai/20181029-Mon-Day - the snooze button is my bff.m4a +lofi/ikigai/20181030-lofi.samurai - dearest.opus +lofi/ikigai/20181101-House Pet - 103.opus +lofi/ikigai/20181104-Powfu - nothing matters _ Feat. QAWI KAMRI.opus +lofi/ikigai/20181105-Chedum - Seikatsu.opus +lofi/ikigai/20181106-jack cates - tap dance.opus +lofi/ikigai/20181107-blkulv - So Close.opus +lofi/ikigai/20181110-Charlie Myles - this is crack {open a book}.opus +lofi/ikigai/20181111-faceless boy. & Kalon - promised not to break my heart (ft. dhan).opus +lofi/ikigai/20181113-slipfunc - warm thoughts w_ omar.opus +lofi/ikigai/20181114-w00ds - fallen leaves.opus +lofi/ikigai/20181115-e.c.l.i.p.s.3 - Alicia's Song.opus +lofi/ikigai/20181116-Kyaru - Graveyards and Gardens (feat. pluto).opus +lofi/ikigai/20181117-the girl next door - amor..opus +lofi/ikigai/20181118-david shouji - deliriant.opus +lofi/ikigai/20181119-arnd & arnd - moonlight..opus +lofi/ikigai/20181120-slipfunc - under your spell.opus +lofi/ikigai/20181121-Alicks - Passed [eisu edit].opus +lofi/ikigai/20181122-Skinny Atlas X Teqkoi - Don't Let Me Go.opus +lofi/ikigai/20181123-K ร˜ M E R - as i wait....opus +lofi/ikigai/20181124-SpoonBeats - Hello There 2 ft Call Me B.opus +lofi/ikigai/20181125-Claine - Life's Anecdote.opus +lofi/ikigai/20181126-Powfu - scars on my heart _ Feat. SadBoyProlific (Prod. Slipfunc).opus +lofi/ikigai/20181127-Sal Dulu - Duluoz Dream.opus +lofi/ikigai/20181128-New ikigai merch, Thank you for 200k!.opus +lofi/ikigai/20181130-sad boy with a laptop - quiet walks on a snowy street.opus +lofi/ikigai/20181201-omar - i've got my eye on you.opus +lofi/ikigai/20181202-u.lรธmi - s]i[mile.opus +lofi/ikigai/20181203-the girl next door - lovesick..opus +lofi/ikigai/20181204-What I Wish - 2am.opus +lofi/ikigai/20181205-SpoonBeats - GunShot.opus +lofi/ikigai/20181207-nekoi โœจ - exist.opus +lofi/ikigai/20181208-Teqkoi x Powfu - You Melt Away The Snow.opus +lofi/ikigai/20181209-hateful - a girl i've barely spoken to.opus +lofi/ikigai/20181210-omar - light w_ H E R B.opus +lofi/ikigai/20181211-K ร˜ M E R - rainy season 001..opus +lofi/ikigai/20181212-nekoi โœจ - fragile.opus +lofi/ikigai/20181213-slipfunc - upon my skin.opus +lofi/ikigai/20181214-w00ds - sleepless.opus +lofi/ikigai/20181216-Slushii - 09. Stargazing.opus +lofi/ikigai/20181218-To Uyen - GLANCE (pro. Slipfunc).opus +lofi/ikigai/20181219-What I Wish - Reflections.opus +lofi/ikigai/20181220-StrangeMood - Heโ€™s Okey.opus +lofi/ikigai/20181221-Eddy Rock x bill.suave x June - Affection.opus +lofi/ikigai/20181222-omar - was i not good enough.opus +lofi/ikigai/20181223-Powfu - running through the rain.opus +lofi/ikigai/20181224-House On The Hill HOTHMAS.opus +lofi/ikigai/20181225-DominusBeats - i just don't understand.opus +lofi/ikigai/20181226-nekoi - weight of the world.opus +lofi/ikigai/20181227-zamir - flowers in my soul w_ Alys (prod. by weirddough).opus +lofi/ikigai/20181228-memoryse. - ๏ฝข Alone ๏ฝฃ.opus +lofi/ikigai/20181230-hateful - take me away.opus +lofi/ikigai/20190101-Madson. - Go To Sleep (ft. Forrest.).opus +lofi/ikigai/20190102-singular balance - we forgot each other's words.opus +lofi/ikigai/20190103-Slushii - 04. Stay.opus +lofi/ikigai/20190104-slipfunc - until dawn.opus +lofi/ikigai/20190105-SLIPPERY SALAZAR - JALAPENO.opus +lofi/ikigai/20190106-diebonsai - i'm awake, thank u.opus +lofi/ikigai/20190107-kochetkovv - I Love You, That's The Problem.opus +lofi/ikigai/20190108-StrangeMood - Sur la route.opus +lofi/ikigai/20190109-Ice Cream Cult - Snow day! (ft. Joey Boone).opus +lofi/ikigai/20190110-Madson. - Kill The Voice Inside Your Head.opus +lofi/ikigai/20190111-R.E.G! - Made in aBliss.opus +lofi/ikigai/20190112-nilรถwh. - a sweet beginning.opus +lofi/ikigai/20190113-MEECHY - Voyage.opus +lofi/ikigai/20190114-porou. - clear ft. silh.opus +lofi/ikigai/20190115-cxld blxxd - my last episode.opus +lofi/ikigai/20190116-sorrow bringer - joy.opus +lofi/ikigai/20190117-tired - Disjointed.opus +lofi/ikigai/20190118-Charlie Myles - what a waste of time {is money}.opus +lofi/ikigai/20190121-Medda - Watch her go (w_ Omar).opus +lofi/ikigai/20190122-singular balance - goodbyes.opus +lofi/ikigai/20190123-Kudasai - Acid Rain.opus +lofi/ikigai/20190124-Teqkoi - understand that i'm in love with you.opus +lofi/ikigai/20190125-Claine - Saotome.opus +lofi/ikigai/20190127-Madson. - Never Die.opus +lofi/ikigai/20190128-Dream Easy Collective - Ikigai Tape (1 Hour Mix).opus +lofi/ikigai/20190129-cxld blxxd - lost.opus +lofi/ikigai/20190130-the girl next door - you said we would last..opus +lofi/ikigai/20190201-kavv - now that you're gone.opus +lofi/ikigai/20190202-slipfunc - days with you.opus +lofi/ikigai/20190203-โ˜†๐”ค๐”ฅ๐”ฌ๐”ฐ๐”ฑ ๐”ฐ๐”ฑ๐”ฌ๐”ฏ๐”ฆ๐”ข๐”ฐโ˜† - i brought you here, but you don't remember it.opus +lofi/ikigai/20190204-omar - another daydream.opus +lofi/ikigai/20190205-matt jordan - bored.opus +lofi/ikigai/20190206-GrayView - Lonely Summer Day.m4a +lofi/ikigai/20190208-l e a f sๆ„› - When you're gone.opus +lofi/ikigai/20190209-Lo'Fi Boy - I Know What You Need (Feat. Shiloh Dynasty).opus +lofi/ikigai/20190210-a l e x - (sad song title).opus +lofi/ikigai/20190211-mewsyc ใƒ„ - i think i'm done with you..opus +lofi/ikigai/20190212-MOSHi - daydream.opus +lofi/ikigai/20190214-cxld blxxd - think of you.opus +lofi/ikigai/20190215-nat - leaving.opus +lofi/ikigai/20190216-theor - away.opus +lofi/ikigai/20190218-Snรธw & Teqkoi - I never wanna lose you.opus +lofi/ikigai/20190220-lofish - where are you.opus +lofi/ikigai/20190222-Charlie Myles - everything means nothing.opus +lofi/ikigai/20190223-mell-รธ - Musing( w_Haru Pandi).opus +lofi/ikigai/20190225-omar - away from here.opus +lofi/ikigai/20190226-Lo'Fi Boy - Top Ten Anime Plot Twists.opus +lofi/ikigai/20190227-slipfunc - another chance.opus +lofi/ikigai/20190228-Sauce K -----km away [INTERLUDE] (prod. by sauce k).opus +lofi/ikigai/20190301-Kupla - Broken Wings.opus +lofi/ikigai/20190302-u.lรธmi - blossom.opus +lofi/ikigai/20190303-Sad Boy With A Laptop - Ice Cream Dates.opus +lofi/ikigai/20190304-Maxwell - Just... Stop....opus +lofi/ikigai/20190306-slipfunc - hazel eyes.opus +lofi/ikigai/20190309-Ellis H. - Show Me.opus +lofi/ikigai/20190310-tired - Late Night Walk.opus +lofi/ikigai/20190311-TOMii - iโ€™ll find her someday.opus +lofi/ikigai/20190312-cafe.wav - missing.you.opus +lofi/ikigai/20190313-omar - without you w_ slipfunc.opus +lofi/ikigai/20190314-Uzu - losing you is my worst nightmare.opus +lofi/ikigai/20190316-kavv - misty [demo].opus +lofi/ikigai/20190317-Make Major - Regret.opus +lofi/ikigai/20190318-kochetkovv - Only U.opus +lofi/ikigai/20190319-Teqkoi - don't you play your games.opus +lofi/ikigai/20190320-J E N - ๏ฝ’๏ฝ…๏ฝƒ๏ฝ๏ฝŒ๏ฝŒ๏ฝ‰๏ฝŽ๏ฝ‡ ๏ฝ”๏ฝˆ๏ฝ… ๏ฝ๏ฝ…๏ฝ๏ฝ๏ฝ’๏ฝ‰๏ฝ…๏ฝ“.opus +lofi/ikigai/20190321-cxld blxxd - stay.opus +lofi/ikigai/20190323-Shinkล - Sins.opus +lofi/ikigai/20190324-Dominus x Slipfunc - i was born to be free.opus +lofi/ikigai/20190326-Sxul๐Ÿ‘๏ธ้ญ‚๐Ÿ‘๏ธ - Save Yourself.opus +lofi/ikigai/20190327-tired - Night Out.opus +lofi/ikigai/20190328-StrangeMood - Im Not Feeling Blue Im Feeling Black ( Feat . Larissa ).opus +lofi/ikigai/20190329-fenoaltea - i still remember the day you left this house.opus +lofi/ikigai/20190331-ENRA - saudade.opus +lofi/ikigai/20190401-Powfu - met at a party _ Feat. Kuzu Mellow.opus +lofi/ikigai/20190402-Tander - be me, sad. (ft. Francis Bhein).opus +lofi/ikigai/20190403-Teqkoi - Stay With Me (feat. Mouse).opus +lofi/ikigai/20190404-Kayou. - It's Not Worth It.opus +lofi/ikigai/20190405-Zaini - you're the only one (ft. Vict Molina).opus +lofi/ikigai/20190407-imfinenow - But I Still Get Social Anxiety Attacks.opus +lofi/ikigai/20190408-slipfunc - always luv.opus +lofi/ikigai/20190409-Resident - Lemonade.opus +lofi/ikigai/20190410-cxld blxxd - last fall.opus +lofi/ikigai/20190411-Kayou. - i don't deserve her.opus +lofi/ikigai/20190413-sad boy with a laptop - portals to mystical worlds.opus +lofi/ikigai/20190415-ใƒ–ใƒญใƒƒใ‚ฏใƒซ - a catharsis in her eyes (w_ ibrahim).opus +lofi/ikigai/20190416-Jacob Seth - heart racing.opus +lofi/ikigai/20190417-neeks summer awaits - (feat. sad boy with a laptop).opus +lofi/ikigai/20190418-w00ds - all my friends (w_ powfu).opus +lofi/ikigai/20190421-๏ผด๏ฝ๏ฝโ˜€๏ธ - i wish i could see you again.opus +lofi/ikigai/20190422-Oui Lele -๏ฝŒ๏ฝ๏ฝƒ๏ฝ‹๏ฝ…๏ฝ”.opus +lofi/ikigai/20190423-fenoaltea - i have to go now.opus +lofi/ikigai/20190424-marc - Give Me A Chance.opus +lofi/ikigai/20190425-NEW IKIGAI MERCH AVAILABLE NOW.opus +lofi/ikigai/20190426-Thomas Reid & insomnia - I Like it.opus +lofi/ikigai/20190427-Sxul๐Ÿ‘๏ธ้ญ‚๐Ÿ‘๏ธ - more than ever.opus +lofi/ikigai/20190428-nilรถwh. - sing me a sad song.opus +lofi/ikigai/20190429-Resident - if youre still around then please feel this moment with me.opus +lofi/ikigai/20190430-ENRA seeking warmth w_ sleepermane.opus +lofi/ikigai/20190501-the girl next door - roses on coffins w_ porou.opus +lofi/ikigai/20190502-Wolfskind & Bayuk - Overdose.opus +lofi/ikigai/20190503-Abbey Glover - all the things she said (slipfunc edit).opus +lofi/ikigai/20190504-Gill Chang - LIMBO.opus +lofi/ikigai/20190506-sad boy with a laptop - anywhere next to you.opus +lofi/ikigai/20190507-toveii - isolated.opus +lofi/ikigai/20190509-Kerusu - Remembrance.opus +lofi/ikigai/20190510-arnd & arnd - directions..opus +lofi/ikigai/20190513-frrb - I'm so nervous.opus +lofi/ikigai/20190514-theor - waiting.opus +lofi/ikigai/20190515-diebonsai - jail court.opus +lofi/ikigai/20190516-cxld blxxd - heaven beside her.opus +lofi/ikigai/20190518-Woven In Hiatus - ill walk you home.opus +lofi/ikigai/20190519-frrb - Growing.opus +lofi/ikigai/20190520-Resident - Halo.opus +lofi/ikigai/20190525-theor - days.opus +lofi/ikigai/20190526-Imfinenow - Bright Night.opus +lofi/ikigai/20190527-dontaskalex - 'h e a v e n'.opus +lofi/ikigai/20190528-NXCRE - Room 28 [Prod. fantompower].opus +lofi/ikigai/20190531-Oui Lele -๏ฝˆ๏ฝ•๏ฝ’๏ฝ”.opus +lofi/ikigai/20190601-dontaskalex - 'e l u s i v e'.opus +lofi/ikigai/20190602-diebonsai - wvs.opus +lofi/ikigai/20190604-theor - remember.opus +lofi/ikigai/20190605-lost-fi - wishes.opus +lofi/ikigai/20190606-osedtrunks - can't hide, won't hide. (ft. nevi & matt fletcher).opus +lofi/ikigai/20190607-slipfunc - stay the night.opus +lofi/ikigai/20190608-INTRN - Headspace.opus +lofi/ikigai/20190609-Charlie Myles - thank you {mean the world}.opus +lofi/ikigai/20190610-Iam6teen - heartaches.opus +lofi/ikigai/20190611-cxld blxxd - dead silence.opus +lofi/ikigai/20190613-SEA all - night long.opus +lofi/ikigai/20190614-Iam6teen - mind.opus +lofi/ikigai/20190615-insomnia - we said goodbye for the last time [w_ Artemis Orion & Resident].opus +lofi/ikigai/20190617-slipfunc - honeycomb.opus +lofi/ikigai/20190618-Grimmwav - LOST.opus +lofi/ikigai/20190619-J E N -๏ฝŒ๏ฝ๏ฝ–๏ฝ… ๏ฝ๏ฝ….opus +lofi/ikigai/20190621-hateful - thought i had it all figured out.opus +lofi/ikigai/20190622-Mon-Day - flyhigh.opus +lofi/ikigai/20190623-toveii - i ruined me.opus +lofi/ikigai/20190624-diebonsai - uncomfortable.opus +lofi/ikigai/20190626-tired - Waking Up Next To You.opus +lofi/ikigai/20190627-Lil Nas X - panini ( im.fine lofi remix).opus +lofi/ikigai/20190629-nilรถwh. - i hope u can forgive me.opus +lofi/ikigai/20190630-Iam6teen - hey let's get some coffee.opus +lofi/ikigai/20190701-Tenno - Memories.opus +lofi/ikigai/20190704-lesspoint - dusk.opus +lofi/ikigai/20190705-nilรถwh. - there you go in my dreams again.opus +lofi/ikigai/20190707-Jay Musey - Self.opus +lofi/ikigai/20190708-slipfunc - warm but not in love.opus +lofi/ikigai/20190709-dontaskalex - t o u c h.opus +lofi/ikigai/20190710-ENRA - i have to leave now.opus +lofi/ikigai/20190711-jades - November Snow prod. 8ROKEBOY.opus +lofi/ikigai/20190713-Resident - Polaroid.opus +lofi/ikigai/20190715-tysu - missing her.opus +lofi/ikigai/20190718-๐ŸŒธ JameirKGolden ๐ŸŒธ - Losing My Mind (Ft.Shiloh Dynasty).opus +lofi/ikigai/20190719-w00ds - Out Of Love.opus +lofi/ikigai/20190720-Sxul๐Ÿ‘๏ธ - remember to remember.opus +lofi/ikigai/20190721-Thomas Reid - A Day Dream Date With You (prod. 8ROKEBOY).opus +lofi/ikigai/20190722-frrb - I try really hard....opus +lofi/ikigai/20190723-cxld blxxd - alive.opus +lofi/ikigai/20190727-spencer hunt - i just want it to stop..opus +lofi/ikigai/20190728-nilรถwh. - resonance.opus +lofi/ikigai/20190729-ohji - assuming w_ jasmine kelly [prod. theor].opus +lofi/ikigai/20190730-w00ds - In My Head.opus +lofi/ikigai/20190801-Madson. I Hate The One That I Was Before.opus +lofi/ikigai/20190802-Zaini - Not Enough (ft. Vict Molina).opus +lofi/ikigai/20190803-Ondi Vil & Skinny Atlas - No More Tears (ft. Thomas Reid).opus +lofi/ikigai/20190804-the girl next door.- for the best.opus +lofi/ikigai/20190805-CHELJI - drip.opus +lofi/ikigai/20190806-you probably don't even like me....opus +lofi/ikigai/20190807-Powfu - would look perfect feat. Rxseboy (Prod. Prettiboi).m4a +lofi/ikigai/20190808-nekoi - for you.opus +lofi/ikigai/20190809-hateful - too afraid.opus +lofi/ikigai/20190810-frrb - loser.opus +lofi/ikigai/20190811-Resident - Paralyzed.opus +lofi/ikigai/20190812-CHELJI - Hypocrite.opus +lofi/ikigai/20190813-marc indigo - accountable (prod. sensu).opus +lofi/ikigai/20190814-slipfunc - you're not real.opus +lofi/ikigai/20190815-nilรถwh. - that's what she loved about me.opus +lofi/ikigai/20190816-Powfu - koolaid summers _ feat. rxseboy.opus +lofi/ikigai/20190817-nekoi - end of a summer.opus +lofi/ikigai/20190819-dontaskalex - i n s a n e.opus +lofi/ikigai/20190820-@rxseboy - anime song (prod. deadman ๆญปไบบ).opus +lofi/ikigai/20190821-spencer hunt - it gets easier..opus +lofi/ikigai/20190822-ENRA & Sleepermane - getaway.opus +lofi/ikigai/20190823-tired - Moving Forward.opus +lofi/ikigai/20190824-@rxseboy - heartbeat conversations (prod. slipfunc).opus +lofi/ikigai/20190825-belis โœฉ - HYSTERICAL GLAMOUR (prod iankon).opus +lofi/ikigai/20190826-spencer hunt - you'll be okay, i promise..opus +lofi/ikigai/20190827-burbank - the more i see you w_ tysu.opus +lofi/ikigai/20190829-sweet medicine & mindeliq - lake rosa.opus +lofi/ikigai/20190830-nekoi - glass.opus +lofi/ikigai/20190901-nat - summer '19.opus +lofi/ikigai/20190902-frrb - Soulmates.opus +lofi/ikigai/20190903-NEW IKIGAI MERCH OUT NOW, LINK IN THE DESCRIPTION !.opus +lofi/ikigai/20190904-wavegxd - sunny day.opus +lofi/ikigai/20190906-ENRA & Sleepermane - after some time.opus +lofi/ikigai/20190907-Deyaz - My Worries.opus +lofi/ikigai/20190908-w00ds - part of you (Official Music Video).opus +lofi/ikigai/20190909-Packedsoda - No One Cares.opus +lofi/ikigai/20190912-sad boy with a laptop - solace.opus +lofi/ikigai/20190913-jades - coffee and cherry blossoms (prod. sille).opus +lofi/ikigai/20190914-Mon-Day - slowdown.opus +lofi/ikigai/20190915-Iam6teen - Tranquil.opus +lofi/ikigai/20190916-spencer hunt - melatonin w_ musiciansplace.opus +lofi/ikigai/20190917-marc indigo - suffering (prod. sensu).opus +lofi/ikigai/20190918-MICO - Online.opus +lofi/ikigai/20190919-slipfunc - lust or love.opus +lofi/ikigai/20190920-SpoonBeats - Getting Dark ft. Loafy Building.opus +lofi/ikigai/20190922-Chelji - Forgive and Forget.opus +lofi/ikigai/20190923-Packedsoda - Snow and Camel Crush w_ Laramie.opus +lofi/ikigai/20190924-fudasca - i'm scared to fall in love with you (feat. Resident and Aidan).opus +lofi/ikigai/20190927-mvdb - lost.opus +lofi/ikigai/20190928-spencer hunt - sweet dreams..opus +lofi/ikigai/20190929-imfinenow - Beautiful Day.opus +lofi/ikigai/20190930-Cadmio - all you can eat.opus +lofi/ikigai/20191001-tired - A crush.opus +lofi/ikigai/20191003-slipfunc - i was a fool for you.opus +lofi/ikigai/20191006-Iam6teen - Butterflies.opus +lofi/ikigai/20191007-neeks - cruisin'.opus +lofi/ikigai/20191008-ENRA - a closer distance.opus +lofi/ikigai/20191009-Packedsoda - A Regret From the Past w_ Cxld Blxxd.opus +lofi/ikigai/20191010-Yellow Station - Coffee in town.opus +lofi/ikigai/20191013-demxntia ๅˆ - it kills me w_ keshi.opus +lofi/ikigai/20191014-Resident - Dreamers.opus +lofi/ikigai/20191015-Powfu - Letters in December _ Feat. Rxseboy.opus +lofi/ikigai/20191016-Iam6teen - glitter.opus +lofi/ikigai/20191017-trxxshed - i'll never find her.opus +lofi/ikigai/20191018-Madson. - Voices Getting Me Nowhere.opus +lofi/ikigai/20191019-ENRA - ephemeral.opus +lofi/ikigai/20191020-tired - ๅฅฝๆขฆ.opus +lofi/ikigai/20191021-CHELJI - Loose.opus +lofi/ikigai/20191023-dontaskalex - s l e e p.opus +lofi/ikigai/20191025-toveii - confession.opus +lofi/ikigai/20191026-Shin - Kiba.opus +lofi/ikigai/20191027-Prvnci - Suicide.opus +lofi/ikigai/20191029-Monty Datta x Kehard - trust u.opus +lofi/ikigai/20191030-frrb - ERASE.opus +lofi/ikigai/20191031-neeks - chanel remix.opus +lofi/ikigai/20191101-kanye west - use this gospel (lofi remix by im.fine).opus +lofi/ikigai/20191102-sad boy with a laptop - silent love.opus +lofi/ikigai/20191103-Hevi - Always Need You.opus +lofi/ikigai/20191104-RONINCLOUD - Grey.opus +lofi/ikigai/20191106-Charlie Myles - been alone my friend {again}.opus +lofi/ikigai/20191107-๐™Š ๐™ค ๐™ž ๐ŸŒœ - old time.opus +lofi/ikigai/20191109-w00ds - tears fall (feat. roiael).opus +lofi/ikigai/20191110-Kyoshin - Heathens (Lofi Remix).opus +lofi/ikigai/20191112-the girl next door - keepsake..opus +lofi/ikigai/20191113-Sauce K - Frostbite.opus +lofi/ikigai/20191114-Lo'Fi Boy - Elle Est Amour.opus +lofi/ikigai/20191116-Teqkoi x Aiko - All These Lies That I've Been Told.opus +lofi/ikigai/20191117-spencer hunt - twilight.opus +lofi/ikigai/20191118-Powfu x Nuxe - All Again (Feat. Snรธw).opus +lofi/ikigai/20191121-iestn - i'm nothing at all.opus +lofi/ikigai/20191122-the girl next door - starburst..opus +lofi/ikigai/20191123-Charlie Myles - one day maybe {i'll get over it}.opus +lofi/ikigai/20191124-tired - Reminisence with @bvg.opus +lofi/ikigai/20191125-slipfunc - like i don't exist.opus +lofi/ikigai/20191126-young citrus - familiar feelings.opus +lofi/ikigai/20191127-sapientdream - reason to fly.opus +lofi/ikigai/20191128-Iam6teen - tranquil.opus +lofi/ikigai/20191130-imfinenow - but through my ups and downs.opus +lofi/ikigai/20191201-slipfunc - the summer in your heart.opus +lofi/ikigai/20191202-jishle - winter's warmth.opus +lofi/ikigai/20191203-pedrolina. - Awamori.opus +lofi/ikigai/20191204-Charlie Myles - i see ghosts at night {mare}.m4a +lofi/ikigai/20191205-CHELJI X Deyaz - Hate Me.opus +lofi/ikigai/20191207-SEBii๐Ÿ’ซ - realize [prod. maknae].opus +lofi/ikigai/20191208-JUICE WRLD - RUN! (lofi remix by Zeuz).opus +lofi/ikigai/20191210-slipfunc - a spring without you.opus +lofi/ikigai/20191212-SEBii๐Ÿ’ซ - lovestory [prod. winter].opus +lofi/ikigai/20191213-Sarcastic Sounds & Mishaal - Rain on Me.opus +lofi/ikigai/20191214-Lo'Fi Boy Sex For Breakfast II.opus +lofi/ikigai/20191215-Burbank - Pier.opus +lofi/ikigai/20191216-PikoM - I've already told you.opus +lofi/ikigai/20191217-kochetkovv - Alone Together.opus +lofi/ikigai/20191218-Powfu - i'm not your friend.opus +lofi/ikigai/20191219-GARZI - Higher.opus +lofi/ikigai/20191222-marc indigo - home (prod. sensu).opus +lofi/ikigai/20191224-the girl next door - without you i feel like im nothing, but that's okay.โ€.opus +lofi/ikigai/20191225-kavv - christmas eve.opus +lofi/ikigai/20191226-wrongnumber - we'll meet again.opus +lofi/ikigai/20191227-ENRA - amber.opus +lofi/ikigai/20191229-Powfu - a kiss goodbye (Prod. Kiyoto).opus +lofi/ikigai/20191230-Chopef - Last Caress.opus +lofi/ikigai/20200101-VIENCฮ› - last day..opus +lofi/ikigai/20200103-im.fine - all you need is time.opus +lofi/ikigai/20200104-Iam6teen - White Lines.opus +lofi/ikigai/20200105-chevieew - pain won't go.opus +lofi/ikigai/20200107-wrongnumber - i wish you love.opus +lofi/ikigai/20200108-tired - Feels Like An Eternity.opus +lofi/ikigai/20200110-Powfu - Laying on my porch while we watch the world end..opus +lofi/ikigai/20200111-wrongnumber - do you remember .opus +lofi/ikigai/20200112-Kiraiyzu - imperfections..opus +lofi/ikigai/20200113-lofi songs guaranteed to help you sleep.opus +lofi/ikigai/20200115-kochetkovv - over u (feat. Zaini).opus +lofi/ikigai/20200117-suwoh - Lonicera.opus +lofi/ikigai/20200118-Joe Asahi - maybe it was for the best.opus +lofi/ikigai/20200119-that guitar sound we all like pt. 3.opus +lofi/ikigai/20200121-Addict. - I stop breathing when you smile.opus +lofi/ikigai/20200123-svmp - All I Wanted (feat. Madson.).opus +lofi/ikigai/20200125-wrongnumber - let Go.opus +lofi/ikigai/20200126-kuri ken - sirens (prod. by S I M).opus +lofi/ikigai/20200127-slipfunc - left alone.opus +lofi/ikigai/20200129-LIVE SOLUM - drowning in my tears, feat. cxldface (prod. fantom).opus +lofi/ikigai/20200131-it's 3am and they turned on lofi music at the club....opus +lofi/ikigai/20200201-frrb - Highschool memories.opus +lofi/ikigai/20200204-marc indigo - soul searching w_ love-sadkid & garrett..opus +lofi/ikigai/20200205-that piano sound we all like.opus +lofi/ikigai/20191119-cat paw ๐Ÿ‚ - cafunรฉ _ viraha.opus +lofi/ikigai/20170909-mochi - bittersweet.opus +lofi/ikigai/20191221-@rxseboy - i really miss you (prod. con).opus +lofi/ikigai/20190725-omarr - it happened again.opus +lofi/ikigai/20181015-flowars - chai tea [prod. aidan].opus +lofi/ikigai/20190529-jiabeats - Chasin'.opus +lofi/ikigai/20190505-Casein - Cloud Control.opus +lofi/ikigai/20191211-IndExisive - Stars.opus +lofi/ikigai/20191206-sapientdream - stumble.opus +lofi/ikigai/20190910-lil mochi - walk.opus +lofi/ikigai/20170502-elijah who - first kiss.opus +lofi/ikigai/20191108-Teqkoi x Rxseboy - We all going.opus +lofi/ikigai/20170604-krygan - Days Of Wine N' Weed.opus +lofi/ikigai/20190616-wavegxd - you don't love me anymore.opus +lofi/ikigai/20190120-slushii -16. WALLS.opus +lofi/ikigai/20170925-khai dreams - New Place to Begin.opus +lofi/ikigai/20180604-tymรบ - lofi rhetoric.opus +lofi/ikigai/20190712-๐ŸŒธ JameirKGolden ๐ŸŒธ - โœจ Mix Match Socks โœจ.opus +lofi/ikigai/20170514-sui.luj - post malates.opus +lofi/ikigai/20180801-R.E.G! - Sunset Vibes.opus +lofi/ikigai/20180116-mochi - taste of your love.opus +lofi/ikigai/20200122-David Sanya - Tension (Ft. Mas. Charade).opus +lofi/ikigai/20190512-Linda - Toro.opus +lofi/ikigai/20190221-ใ€˜ E I S U ใ€™- Trauerfall w_ tzelun.opus +lofi/ikigai/20190508-jerichoavl - Tressa's.opus +lofi/ikigai/20191002-Essence - until her whispers fade..opus +lofi/ikigai/20170605-squid ethics - x jhfly.opus +lofi/ikigai/20190517-Snรธw & Teqkoi - you don't want me anymore.opus +lofi/ikigai/20181231-cxld blxxd - lost together.opus +lofi/kudasai/20171021-kudasai - the girl i haven't met.opus +lofi/kudasai/20171105-kudasai - a night together.opus +lofi/kudasai/20171208-kudasai - memories with her.opus +lofi/kudasai/20171223-kudasai - attached.opus +lofi/kudasai/20180207-kudasai - oh darling.opus +lofi/kudasai/20180304-kudasai - a light of mine.opus +lofi/kudasai/20180325-kudasai - when i see you.opus +lofi/kudasai/20180420-kudasai - flowers next to me.opus +lofi/kudasai/20180501-kudasai - vibrancy.opus +lofi/kudasai/20180520-luv.ly & kudasai - beingwithu.opus +lofi/kudasai/20180618-kudasai - technicolor.opus +lofi/kudasai/20180727-kudasai - dream of her.opus +lofi/kudasai/20180804-luv.ly & kudasai - solicitude.opus +lofi/kudasai/20180922-kudasai - she said, i wonder.opus +lofi/kudasai/20181001-kudasai - midnight.opus +lofi/kudasai/20181014-marc - kid in the sky w_ kudasai.opus +lofi/kudasai/20181022-kudasai - you make colors out of grey.opus +lofi/kudasai/20181108-kudasai - serenade.opus +lofi/kudasai/20181206-kudasai - sapphire.opus +lofi/kudasai/20181229-kudasai - separate ways.opus +lofi/kudasai/20190217-kudasai - love lasts.opus +lofi/kudasai/20190224-kudasai & slippery salazar - metrolink.opus +lofi/kudasai/20190828-kudasai - Platinum.opus diff --git a/.config/mpd/playlists/lofi2.m3u b/.config/mpd/playlists/lofi2.m3u new file mode 100644 index 0000000..9c96d37 --- /dev/null +++ b/.config/mpd/playlists/lofi2.m3u @@ -0,0 +1,5 @@ +lofi/20190127-ใ€๏ผก๏ผณ๏ผซใ€€๏ผญ๏ผฅใ€€๏ผฏ๏ผต๏ผดใ€€๏ผฏ๏ผฎใ€€๏ผกใ€€๏ผค๏ผก๏ผด๏ผฅใ€‘_ Japanese Lofi _ Japanese_Anime Lofi Hip Hop Mix.m4a +lofi/20170505-close your eyes (lo-fi_chill mix).mkv +lofi/20191208-1 A.M Study Session ๐Ÿ“š - [lofi hip hop_chill beats].opus +lofi/20190915-i found my home in your arms - lofi hip hop mix.opus +lofi/20200316-Just take care of yourself โ— lofi hip hop mix โ— Nostalgia.opus diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf new file mode 100644 index 0000000..02c7478 --- /dev/null +++ b/.config/mpv/input.conf @@ -0,0 +1,199 @@ +# mpv keybindings +# +# Location of user-defined bindings: ~/.config/mpv/input.conf +# +# Lines starting with # are comments. Use SHARP to assign the # key. +# Copy this file and uncomment and edit the bindings you want to change. +# +# List of commands and further details: DOCS/man/input.rst +# List of special keys: --input-keylist +# Keybindings testing mode: mpv --input-test --force-window --idle +# +# Use 'ignore' to unbind a key fully (e.g. 'ctrl+a ignore'). +# +# Strings need to be quoted and escaped: +# KEY show-text "This is a single backslash: \\ and a quote: \" !" +# +# You can use modifier-key combinations like Shift+Left or Ctrl+Alt+x with +# the modifiers Shift, Ctrl, Alt and Meta (may not work on the terminal). +# +# The default keybindings are hardcoded into the mpv binary. +# You can disable them completely with: --no-input-default-bindings + +# Developer note: +# On compilation, this file is baked into the mpv binary, and all lines are +# uncommented (unless '#' is followed by a space) - thus this file defines the +# default key bindings. + +# If this is enabled, treat all the following bindings as default. +#default-bindings start + +#MOUSE_BTN0 ignore # don't do anything +#MOUSE_BTN0_DBL cycle fullscreen # toggle fullscreen on/off +#MOUSE_BTN2 cycle pause # toggle pause on/off +#MOUSE_BTN3 seek 10 +#MOUSE_BTN4 seek -10 +#MOUSE_BTN5 add volume -2 +#MOUSE_BTN6 add volume 2 + +# Mouse wheels, touchpad or other input devices that have axes +# if the input devices supports precise scrolling it will also scale the +# numeric value accordingly +#AXIS_UP seek 10 +#AXIS_DOWN seek -10 +#AXIS_LEFT seek 5 +#AXIS_RIGHT seek -5 + +## Seek units are in seconds, but note that these are limited by keyframes +#RIGHT seek 5 +#LEFT seek -5 +#UP seek 60 +#DOWN seek -60 +# Do smaller, always exact (non-keyframe-limited), seeks with shift. +# Don't show them on the OSD (no-osd). +#Shift+RIGHT no-osd seek 1 exact +#Shift+LEFT no-osd seek -1 exact +#Shift+UP no-osd seek 5 exact +#Shift+DOWN no-osd seek -5 exact +# Skip to previous/next subtitle (subject to some restrictions; see manpage) +#Ctrl+LEFT no-osd sub-seek -1 +#Ctrl+RIGHT no-osd sub-seek 1 +#PGUP add chapter 1 # skip to next chapter +#PGDWN add chapter -1 # skip to previous chapter +#Shift+PGUP seek 600 +#Shift+PGDWN seek -600 +[ add speed -0.1 # scale playback speed +] add speed 0.1 +{ add speed -0.5 +} add speed 0.5 +#BS set speed 1.0 # reset speed to normal +#q quit +#Q quit-watch-later +#q {encode} quit 4 +#ESC set fullscreen no +#ESC {encode} quit 4 +#p cycle pause # toggle pause/playback mode +#. frame-step # advance one frame and pause +#, frame-back-step # go back by one frame and pause +#SPACE cycle pause +#> playlist-next # skip to next file +#ENTER playlist-next # skip to next file +#< playlist-prev # skip to previous file +#O no-osd cycle-values osd-level 3 1 # cycle through OSD mode +#o show-progress +#P show-progress +#I show-text "${filename}" # display filename in osd +#z add sub-delay -0.1 # subtract 100 ms delay from subs +#x add sub-delay +0.1 # add +#ctrl++ add audio-delay 0.100 # this changes audio/video sync +#ctrl+- add audio-delay -0.100 +#9 add volume -2 +#/ add volume -2 +#0 add volume 2 +#* add volume 2 +#m cycle mute +#1 add contrast -1 +#2 add contrast 1 +#3 add brightness -1 +#4 add brightness 1 +#5 add gamma -1 +#6 add gamma 1 +#7 add saturation -1 +#8 add saturation 1 +#Alt+0 set window-scale 0.5 +#Alt+1 set window-scale 1.0 +#Alt+2 set window-scale 2.0 +# toggle deinterlacer (automatically inserts or removes required filter) +#d cycle deinterlace +#r add sub-pos -1 # move subtitles up +#t add sub-pos +1 # down +#v cycle sub-visibility +# stretch SSA/ASS subtitles with anamorphic videos to match historical +#V cycle sub-ass-vsfilter-aspect-compat +# switch between applying no style overrides to SSA/ASS subtitles, and +# overriding them almost completely with the normal subtitle style +#u cycle-values sub-ass-style-override "force" "no" +#j cycle sub # cycle through subtitles +#J cycle sub down # ...backwards +#SHARP cycle audio # switch audio streams +#_ cycle video +#T cycle ontop # toggle video window ontop of other windows +#f cycle fullscreen # toggle fullscreen +#s screenshot # take a screenshot +#S screenshot video # ...without subtitles +#Ctrl+s screenshot window # ...with subtitles and OSD, and scaled +#Alt+s screenshot each-frame # automatically screenshot every frame +#w add panscan -0.1 # zoom out with -panscan 0 -fs +#e add panscan +0.1 # in +# cycle video aspect ratios; "-1" is the container aspect +#A cycle-values video-aspect "16:9" "4:3" "2.35:1" "-1" +#POWER quit +#PLAY cycle pause +#PAUSE cycle pause +#PLAYPAUSE cycle pause +#STOP quit +#FORWARD seek 60 +#REWIND seek -60 +#NEXT playlist-next +#PREV playlist-prev +#VOLUME_UP add volume 2 +#VOLUME_DOWN add volume -2 +#MUTE cycle mute +#CLOSE_WIN quit +#CLOSE_WIN {encode} quit 4 +#E cycle edition # next edition +#l ab-loop # Set/clear A-B loop points +#L cycle-values loop "inf" "no" # toggle infinite looping +#ctrl+c quit 4 + +# Apple Remote section +#AR_PLAY cycle pause +#AR_PLAY_HOLD quit +#AR_CENTER cycle pause +#AR_CENTER_HOLD quit +#AR_NEXT seek 10 +#AR_NEXT_HOLD seek 120 +#AR_PREV seek -10 +#AR_PREV_HOLD seek -120 +#AR_MENU show-progress +#AR_MENU_HOLD cycle mute +#AR_VUP add volume 2 +#AR_VUP_HOLD add chapter 1 +#AR_VDOWN add volume -2 +#AR_VDOWN_HOLD add chapter -1 + +# For tv:// +#h cycle tv-channel -1 # previous channel +#k cycle tv-channel +1 # next channel + +# For dvb:// +#H cycle dvb-channel-name -1 # previous channel +#K cycle dvb-channel-name +1 # next channel + +# +# Legacy bindings (may or may not be removed in the future) +# +! add chapter -1 # skip to previous chapter +@ add chapter 1 # next + +# +# Not assigned by default +# (not an exhaustive list of unbound commands) +# + +# ? add sub-scale +0.1 # increase subtitle font size +# ? add sub-scale -0.1 # decrease subtitle font size +# ? sub-step -1 # immediately display next subtitle +# ? sub-step +1 # previous +# ? cycle angle # switch DVD/Bluray angle +# ? add balance -0.1 # adjust audio balance in favor of left +# ? add balance 0.1 # right +# ? cycle sub-forced-only # toggle DVD forced subs +# ? cycle program # cycle transport stream programs +# ? stop # stop playback (quit or enter idle mode) + +l seek 5 +h seek -5 +j seek -60 +k seek 60 +S cycle sub diff --git a/.config/mutt/mailcap b/.config/mutt/mailcap new file mode 100644 index 0000000..0b2d1ef --- /dev/null +++ b/.config/mutt/mailcap @@ -0,0 +1,16 @@ +# PDF +application;zathura %s +image/pdf;zathura %s + +# Images +image/bmp;sxiv %s +image/gif;sxiv %s +image/libm;sxiv %s +image/jpg;sxiv %s +image/jpeg;sxiv %s +image/png;sxiv %s +image/tiff;sxiv %s +image/x-png;sxiv %s + +#Text +#text/html;firefox %s diff --git a/.config/ncmpcpp/bindings b/.config/ncmpcpp/bindings new file mode 100644 index 0000000..6f10623 --- /dev/null +++ b/.config/ncmpcpp/bindings @@ -0,0 +1,624 @@ +############################################################## +## This is the example bindings file. Copy it to ## +## ~/.ncmpcpp/bindings or $XDG_CONFIG_HOME/ncmpcpp/bindings ## +## and set up your preferences ## +############################################################## +## +##### General rules ##### +## +## 1) Because each action has runtime checks whether it's +## ok to run it, a few actions can be bound to one key. +## Actions will be bound in order given in configuration +## file. When a key is pressed, first action in order +## will test itself whether it's possible to run it. If +## test succeeds, action is executed and other actions +## bound to this key are ignored. If it doesn't, next +## action in order tests itself etc. +## +## 2) It's possible to bind more that one action at once +## to a key. It can be done using the following syntax: +## +## def_key "key" +## action1 +## action2 +## ... +## +## This creates a chain of actions. When such chain is +## executed, each action in chain is run until the end of +## chain is reached or one of its actions fails to execute +## due to its requirements not being met. If multiple actions +## and/or chains are bound to the same key, they will be +## consecutively run until one of them gets fully executed. +## +## 3) When ncmpcpp starts, bindings configuration file is +## parsed and then ncmpcpp provides "missing pieces" +## of default keybindings. If you want to disable some +## bindings, there is a special action called 'dummy' +## for that purpose. Eg. if you want to disable ability +## to crop playlists, you need to put the following +## into configuration file: +## +## def_key "C" +## dummy +## +## After that ncmpcpp will not bind any default action +## to this key. +## +## 4) To let you write simple macros, the following special +## actions are provided: +## +## - push_character "character" - pushes given special +## character into input queue, so it will be immediately +## picked by ncmpcpp upon next call to readKey function. +## Accepted values: mouse, up, down, page_up, page_down, +## home, end, space, enter, insert, delete, left, right, +## tab, ctrl-a, ctrl-b, ..., ctrl-z, ctrl-[, ctrl-\\, +## ctrl-], ctrl-^, ctrl-_, f1, f2, ..., f12, backspace. +## In addition, most of these names can be prefixed with +## alt-/ctrl-/shift- to be recognized with the appropriate +## modifier key(s). +## +## - push_characters "string" - pushes given string into +## input queue. +## +## - require_runnable "action" - checks whether given action +## is runnable and fails if it isn't. This is especially +## useful when mixed with previous two functions. Consider +## the following macro definition: +## +## def_key "key" +## push_characters "custom_filter" +## apply_filter +## +## If apply_filter can't be currently run, we end up with +## sequence of characters in input queue which will be +## treated just as we typed them. This may lead to unexpected +## results (in this case 'c' will most likely clear current +## playlist, 'u' will trigger database update, 's' will stop +## playback etc.). To prevent such thing from happening, we +## need to change above definition to this one: +## +## def_key "key" +## require_runnable "apply_filter" +## push_characters "custom_filter" +## apply_filter +## +## Here, first we test whether apply_filter can be actually run +## before we stuff characters into input queue, so if condition +## is not met, whole chain is aborted and we're fine. +## +## - require_screen "screen" - checks whether given screen is +## currently active. accepted values: browser, clock, help, +## media_library, outputs, playlist, playlist_editor, +## search_engine, tag_editor, visualizer, last_fm, lyrics, +## selected_items_adder, server_info, song_info, +## sort_playlist_dialog, tiny_tag_editor. +## +## - run_external_command "command" - runs given command using +## system() function. +## +## 5) In addition to binding to a key, you can also bind actions +## or chains of actions to a command. If it comes to commands, +## syntax is very similar to defining keys. Here goes example +## definition of a command: +## +## def_command "quit" [deferred] +## stop +## quit +## +## If you execute the above command (which can be done by +## invoking action execute_command, typing 'quit' and pressing +## enter), ncmpcpp will stop the player and then quit. Note the +## presence of word 'deferred' enclosed in square brackets. It +## tells ncmpcpp to wait for confirmation (ie. pressing enter) +## after you typed quit. Instead of 'deferred', 'immediate' +## could be used. Then ncmpcpp will not wait for confirmation +## (enter) and will execute the command the moment it sees it. +## +## Note: while command chains are executed, internal environment +## update (which includes current window refresh and mpd status +## update) is not performed for performance reasons. However, it +## may be desirable to do so in some situration. Therefore it's +## possible to invoke by hand by performing 'update enviroment' +## action. +## +## Note: There is a difference between: +## +## def_key "key" +## action1 +## +## def_key "key" +## action2 +## +## and +## +## def_key "key" +## action1 +## action2 +## +## First one binds two single actions to the same key whilst +## second one defines a chain of actions. The behavior of +## these two is different and is described in (1) and (2). +## +## Note: Function def_key accepts non-ascii characters. +## +##### List of unbound actions ##### +## +## The following actions are not bound to any key/command: +## +## - set_volume +## +# +#def_key "mouse" +# mouse_event +# +#def_key "up" +# scroll_up +# +#def_key "shift-up" +# select_item +# scroll_up +# +#def_key "down" +# scroll_down +# +#def_key "shift-down" +# select_item +# scroll_down +# +#def_key "[" +# scroll_up_album +# +#def_key "]" +# scroll_down_album +# +#def_key "{" +# scroll_up_artist +# +#def_key "}" +# scroll_down_artist +# +#def_key "page_up" +# page_up +# +#def_key "page_down" +# page_down +# +#def_key "home" +# move_home +# +#def_key "end" +# move_end +# +#def_key "insert" +# select_item +# +#def_key "enter" +# enter_directory +# +#def_key "enter" +# toggle_output +# +#def_key "enter" +# run_action +# +#def_key "enter" +# play_item +# +#def_key "space" +# add_item_to_playlist +# +#def_key "space" +# toggle_lyrics_update_on_song_change +# +#def_key "space" +# toggle_visualization_type +# +def_key "d" + delete_playlist_items +# +#def_key "delete" +# delete_browser_items +# +#def_key "delete" +# delete_stored_playlist +# +#def_key "right" +# next_column +# +#def_key "right" +# slave_screen +# +#def_key "right" +# volume_up +# +def_key "+" + volume_up +# +#def_key "left" +# previous_column +# +#def_key "left" +# master_screen +# +#def_key "left" +# volume_down +# +def_key "-" + volume_down +# +#def_key ":" +# execute_command +# +#def_key "tab" +# next_screen +# +#def_key "shift-tab" +# previous_screen +# +#def_key "f1" +# show_help +# +def_key "1" + show_playlist +# +def_key "2" + show_browser +# +#def_key "2" +# change_browse_mode +# +def_key "3" + show_search_engine +# +#def_key "3" +# reset_search_engine +# +#def_key "4" +# show_media_library +# +#def_key "4" +# toggle_media_library_columns_mode +# +def_key "5" + show_playlist_editor +# +def_key "6" + show_tag_editor +# +#def_key "7" +# show_outputs +# +#def_key "8" +# show_visualizer +# +#def_key "=" +# show_clock +# +#def_key "@" +# show_server_info +# +def_key "s" + stop + +def_key "p" + pause + +def_key ">" + next +# +#def_key "<" +# previous +# +#def_key "ctrl-h" +# jump_to_parent_directory +# +#def_key "ctrl-h" +# replay_song +# +#def_key "backspace" +# jump_to_parent_directory +# +#def_key "backspace" +# replay_song +# +#def_key "f" +# seek_forward +# +#def_key "b" +# seek_backward +# +def_key "r" + toggle_repeat +# +def_key "z" + toggle_random +# +def_key "y" + save_tag_changes +# +#def_key "y" +# start_searching +# +#def_key "y" +# toggle_single +# +#def_key "R" +# toggle_consume +# +#def_key "Y" +# toggle_replay_gain_mode +# +#def_key "T" +# toggle_add_mode +# +#def_key "|" +# toggle_mouse +# +#def_key "#" +# toggle_bitrate_visibility +# +def_key "Z" + shuffle +# +#def_key "x" +# toggle_crossfade +# +#def_key "X" +# set_crossfade +# +#def_key "u" +# update_database +# +#def_key "ctrl-s" +# sort_playlist +# +#def_key "ctrl-s" +# toggle_browser_sort_mode +# +#def_key "ctrl-s" +# toggle_media_library_sort_mode +# +#def_key "ctrl-r" +# reverse_playlist +# +#def_key "ctrl-f" +# apply_filter +# +#def_key "ctrl-_" +# select_found_items +# +#def_key "/" +# find +# +#def_key "/" +# find_item_forward +# +#def_key "?" +# find +# +#def_key "?" +# find_item_backward +# +#def_key "." +# next_found_item +# +#def_key "," +# previous_found_item +# +#def_key "w" +# toggle_find_mode +# +#def_key "e" +# edit_song +# +#def_key "e" +# edit_library_tag +# +#def_key "e" +# edit_library_album +# +#def_key "e" +# edit_directory_name +# +#def_key "e" +# edit_playlist_name +# +#def_key "e" +# edit_lyrics +# +#def_key "i" +# show_song_info +# +#def_key "I" +# show_artist_info +# +#def_key "g" +# jump_to_position_in_song +# +#def_key "l" +# show_lyrics +# +#def_key "ctrl-v" +# select_range +# +#def_key "v" +# reverse_selection +# +#def_key "V" +# remove_selection +# +#def_key "B" +# select_album +# +#def_key "a" +# add_selected_items +# +#def_key "c" +# clear_playlist +# +#def_key "c" +# clear_main_playlist +# +#def_key "C" +# crop_playlist +# +#def_key "C" +# crop_main_playlist +# +#def_key "m" +# move_sort_order_up +# +#def_key "m" +# move_selected_items_up +# +#def_key "n" +# move_sort_order_down +# +#def_key "n" +# move_selected_items_down +# +#def_key "M" +# move_selected_items_to +# +#def_key "A" +# add +# +#def_key "S" +# save_playlist +# +#def_key "o" +# jump_to_playing_song +# +#def_key "G" +# jump_to_browser +# +#def_key "G" +# jump_to_playlist_editor +# +def_key "~" + jump_to_media_library + +def_key "E" + jump_to_tag_editor +# +#def_key "U" +# toggle_playing_song_centering +# +#def_key "P" +# toggle_display_mode +# +#def_key "\\" +# toggle_interface +# +#def_key "!" +# toggle_separators_between_albums +# +#def_key "L" +# toggle_lyrics_fetcher +# +#def_key "F" +# fetch_lyrics_in_background +# +#def_key "alt-l" +# toggle_fetching_lyrics_in_background +# +#def_key "ctrl-l" +# toggle_screen_lock +# +#def_key "`" +# toggle_library_tag_type +# +#def_key "`" +# refetch_lyrics +# +#def_key "`" +# add_random_items +# +#def_key "ctrl-p" +# set_selected_items_priority +# +#def_key "q" +# quit +# +# +#def_key "f" +# find +#def_key "f" +# find_item_forward + +def_key "+" + show_clock +def_key "=" + volume_up + +def_key "j" + scroll_down +def_key "k" + scroll_up + +def_key "ctrl-u" + page_up +#push_characters "kkkkkkkkkkkkkkk" +def_key "ctrl-d" + page_down +#push_characters "jjjjjjjjjjjjjjj" +def_key "u" + page_up +#push_characters "kkkkkkkkkkkkkkk" +def_key "d" + page_down +#push_characters "jjjjjjjjjjjjjjj" +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 + +# not used but bound +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 +#jump_to_position_in_song +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..6874c14 --- /dev/null +++ b/.config/ncmpcpp/config @@ -0,0 +1,545 @@ +############################################################################## +## This is the example configuration file. Copy it to $HOME/.ncmpcpp/config ## +## or $XDG_CONFIG_HOME/ncmpcpp/config and set up your preferences. ## +############################################################################## +# +##### directories ###### +## +## Directory for storing ncmpcpp related files. Changing it is useful if you +## want to store everything somewhere else and provide command line setting for +## alternative location to config file which defines that while launching +## ncmpcpp. +## +# +ncmpcpp_directory = ~/.config/ncmpcpp +# +## +## Directory for storing downloaded lyrics. It defaults to ~/.lyrics since other +## MPD clients (eg. ncmpc) also use that location. +## +# +lyrics_directory = ~/.config/lyrics +# +##### connection settings ##### +# +#mpd_host = localhost +# +#mpd_port = 6600 +# +#mpd_connection_timeout = 5 +# +## Needed for tag editor and file operations to work. +## +mpd_music_dir = "~/msc" +# +#mpd_crossfade_time = 5 +# +##### music visualizer ##### +## +## Note: In order to make music visualizer work you'll need to use mpd fifo +## output, whose format parameter has to be set to 44100:16:1 for mono +## visualization or 44100:16:2 for stereo visualization. Example configuration +## (it has to be put into mpd.conf): +## +## audio_output { +## type "fifo" +## name "Visualizer feed" +## path "/tmp/mpd.fifo" +## format "44100:16:2" +## } +## +# +#visualizer_fifo_path = /tmp/mpd.fifo +# +## +## Note: Below parameter is needed for ncmpcpp to determine which output +## provides data for visualizer and thus allow syncing between visualization and +## sound as currently there are some problems with it. +## +# +#visualizer_output_name = Visualizer feed +# +## +## If you set format to 44100:16:2, make it 'yes'. +## +#visualizer_in_stereo = yes +# +## +## Note: Below parameter defines how often ncmpcpp has to "synchronize" +## visualizer and audio outputs. 30 seconds is optimal value, but if you +## experience synchronization problems, set it to lower value. Keep in mind +## that sane values start with >=10. +## +# +#visualizer_sync_interval = 30 +# +## +## Note: To enable spectrum frequency visualization you need to compile ncmpcpp +## with fftw3 support. +## +# +## Available values: spectrum, wave, wave_filled, ellipse. +## +visualizer_type = spectrum +# +#visualizer_look = โ—ๅ +#visualizer_look = ๅ +# +#visualizer_color = blue, cyan, green, yellow, magenta, red +# +## Alternative subset of 256 colors for terminals that support it. +## +#visualizer_color = 41, 83, 119, 155, 185, 215, 209, 203, 197, 161 +# +##### system encoding ##### +## +## ncmpcpp should detect your charset encoding but if it failed to do so, you +## can specify charset encoding you are using here. +## +## Note: You can see whether your ncmpcpp build supports charset detection by +## checking output of `ncmpcpp --version`. +## +## Note: Since MPD uses UTF-8 by default, setting this option makes sense only +## if your encoding is different. +## +# +#system_encoding = "" +# +##### delays ##### +# +## Time of inactivity (in seconds) after playlist highlighting will be disabled +## (0 = always on). +## +#playlist_disable_highlight_delay = 5 +# +## Defines how long messages are supposed to be visible. +## +message_delay_time = 1 +# +##### song format ##### +## +## For a song format you can use: +## +## %l - length +## %f - filename +## %D - directory +## %a - artist +## %A - album artist +## %t - title +## %b - album +## %y - date +## %n - track number (01/12 -> 01) +## %N - full track info (01/12 -> 01/12) +## %g - genre +## %c - composer +## %p - performer +## %d - disc +## %C - comment +## %P - priority +## $R - begin right alignment +## +## If you want to make sure that a part of the format is displayed only when +## certain tags are present, you can archieve it by grouping them with brackets, +## e.g. '{%a - %t}' will be evaluated to 'ARTIST - TITLE' if both tags are +## present or '' otherwise. It is also possible to define a list of +## alternatives by providing several groups and separating them with '|', +## e.g. '{%t}|{%f}' will be evaluated to 'TITLE' or 'FILENAME' if the former is +## not present. +## +## Note: If you want to set limit on maximal length of a tag, just put the +## appropriate number between % and character that defines tag type, e.g. to +## make album take max. 20 terminal cells, use '%20b'. +## +## In addition, formats support markers used for text attributes. They are +## followed by character '$'. After that you can put: +## +## - 0 - default window color (discards all other colors) +## - 1 - black +## - 2 - red +## - 3 - green +## - 4 - yellow +## - 5 - blue +## - 6 - magenta +## - 7 - cyan +## - 8 - white +## - 9 - end of current color +## - b - bold text +## - u - underline text +## - r - reverse colors +## - a - use alternative character set +## +## If you don't want to use a non-color attribute anymore, just put it again, +## but this time insert character '/' between '$' and attribute character, +## e.g. {$b%t$/b}|{$r%f$/r} will display bolded title tag or filename with +## reversed colors. +## +## If you want to use 256 colors and/or background colors in formats (the naming +## scheme is described below in section about color definitions), it can be done +## with the syntax $(COLOR), e.g. to set the artist tag to one of the +## non-standard colors and make it have yellow background, you need to write +## $(197_yellow)%a$(end). Note that for standard colors this is interchangable +## with attributes listed above. +## +## Note: colors can be nested. +## +# +song_list_format = {$4%a - }{%t}|{$8%f$9}$R{$3(%l)$9} +# +song_status_format = $b{{$8"%t"}} $3by {$4%a{ $3in $7%b{ (%y)}} $3}|{$8%f} +# +song_library_format = {%n - }{%t}|{%f} +# +alternative_header_first_line_format = $b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b +# +alternative_header_second_line_format = {{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D} +# +current_item_prefix = $(cyan)$r$b +# +current_item_suffix = $/r$(end)$/b +# +current_item_inactive_column_prefix = $(magenta)$r +# +current_item_inactive_column_suffix = $/r$(end) +# +#now_playing_prefix = $b +# +#now_playing_suffix = $/b +# +#browser_playlist_prefix = "$2playlist$9 " +# +#selected_item_prefix = $6 +# +#selected_item_suffix = $9 +# +#modified_item_prefix = $3> $9 +# +## +## Note: attributes are not supported for the following variables. +## +#song_window_title_format = {%a - }{%t}|{%f} +## +## Note: Below variables are used for sorting songs in browser. The sort mode +## determines how songs are sorted, and can be used in combination with a sort +## format to specify a custom sorting format. Available values for +## browser_sort_mode are "name", "mtime", "format" and "noop". +## +# +#browser_sort_mode = name +# +#browser_sort_format = {%a - }{%t}|{%f} {(%l)} +# +##### columns settings ##### +## +## syntax of song columns list format is "column column etc." +## +## - syntax for each column is: +## +## (width of the column)[color of the column]{displayed tag} +## +## Note: Width is by default in %, if you want a column to have fixed size, add +## 'f' after the value, e.g. (10)[white]{a} will be the column that take 10% of +## screen (so the real width will depend on actual screen size), whereas +## (10f)[white]{a} will take 10 terminal cells, no matter how wide the screen +## is. +## +## - color is optional (if you want the default one, leave the field empty). +## +## Note: You can give a column additional attributes by putting appropriate +## character after displayed tag character. Available attributes are: +## +## - r - column will be right aligned +## - E - if tag is empty, empty tag marker won't be displayed +## +## You can also: +## +## - give a column custom name by putting it after attributes, separated with +## character ':', e.g. {lr:Length} gives you right aligned column of lengths +## named "Length". +## +## - define sequence of tags, that have to be displayed in case predecessor is +## empty in a way similar to the one in classic song format, i.e. using '|' +## character, e.g. {a|c|p:Owner} creates column named "Owner" that tries to +## display artist tag and then composer and performer if previous ones are not +## available. +## +# +#song_columns_list_format = (20)[]{a} (6f)[green]{NE} (50)[white]{t|f:Title} (20)[cyan]{b} (7f)[magenta]{l} +# +##### various settings ##### +# +## +## Note: Custom command that will be executed each time song changes. Useful for +## notifications etc. +## +#execute_on_song_change = "" +# +## +## Note: Custom command that will be executed each time player state +## changes. The environment variable MPD_PLAYER_STATE is set to the current +## state (either unknown, play, pause, or stop) for its duration. +## +# +#execute_on_player_state_change = "" +# +#playlist_show_mpd_host = no +# +#playlist_show_remaining_time = no +# +#playlist_shorten_total_times = no +# +#playlist_separate_albums = no +# +## +## Note: Possible display modes: classic, columns. +## +playlist_display_mode = columns +# +browser_display_mode = columns +# +#search_engine_display_mode = classic +# +#playlist_editor_display_mode = classic +# +#discard_colors_if_item_is_selected = yes +# +#show_duplicate_tags = true +# +#incremental_seeking = yes +# +#seek_time = 1 +# +#volume_change_step = 2 +# +#autocenter_mode = no +# +#centered_cursor = no +# +## +## Note: You can specify third character which will be used to build 'empty' +## part of progressbar. +## +progressbar_look = -> +# +## Available values: database, playlist. +## +#default_place_to_search_in = database +# +## Available values: classic, alternative. +## +user_interface = alternative +# +#data_fetching_delay = yes +# +## Available values: artist, album_artist, date, genre, composer, performer. +## +media_library_primary_tag = artist +# +media_library_albums_split_by_date = no +# +## Available values: wrapped, normal. +## +#default_find_mode = wrapped +# +#default_tag_editor_pattern = %n - %t +# +#header_visibility = yes +# +#statusbar_visibility = yes +# +#titles_visibility = yes +# +#header_text_scrolling = yes +# +#cyclic_scrolling = no +# +#lines_scrolled = 2 +# +#lyrics_fetchers = lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, jahlyrics, plyrics, tekstowo, internet +# +#follow_now_playing_lyrics = no +# +#fetch_lyrics_for_current_song_in_background = no +# +#store_lyrics_in_song_dir = no +# +#generate_win32_compatible_filenames = yes +# +#allow_for_physical_item_deletion = no +# +## +## Note: If you set this variable, ncmpcpp will try to get info from last.fm in +## language you set and if it fails, it will fall back to english. Otherwise it +## will use english the first time. +## +## Note: Language has to be expressed as an ISO 639 alpha-2 code. +## +#lastfm_preferred_language = en +# +#space_add_mode = add_remove +# +#show_hidden_files_in_local_browser = no +# +## +## How shall screen switcher work? +## +## - "previous" - switch between the current and previous screen. +## - "screen1,...,screenN" - switch between given sequence of screens. +## +## Screens available for use: help, playlist, browser, search_engine, +## media_library, playlist_editor, tag_editor, outputs, visualizer, clock, +## lyrics, last_fm. +## +#screen_switcher_mode = playlist, browser +# +## +## Note: You can define startup screen by choosing screen from the list above. +## +startup_screen = browser +# +## +## Note: You can define startup slave screen by choosing screen from the list +## above or an empty value for no slave screen. +## +#startup_slave_screen = "" +# +#startup_slave_screen_focus = no +# +## +## Default width of locked screen (in %). Acceptable values are from 20 to 80. +## +# +#locked_screen_width_part = 50 +# +#ask_for_locked_screen_width_part = yes +# +#jump_to_now_playing_song_at_start = yes +# +#ask_before_clearing_playlists = yes +# +#clock_display_seconds = no +# +display_volume_level = yes +# +#display_bitrate = no +# +#display_remaining_time = no +# +## Available values: none, basic, extended, perl. +## +#regular_expressions = perl +# +## +## Note: if below is enabled, ncmpcpp will ignore leading "The" word while +## sorting items in browser, tags in media library, etc. +## +ignore_leading_the = yes +# +## +## Note: if below is enabled, ncmpcpp will ignore diacritics while searching and +## filtering lists. This takes an effect only if boost was compiled with ICU +## support. +## +#ignore_diacritics = no +# +#block_search_constraints_change_if_items_found = yes +# +#mouse_support = yes +# +#mouse_list_scroll_whole_page = yes +# +#empty_tag_marker = +# +#tags_separator = " | " +# +#tag_editor_extended_numeration = no +# +#media_library_sort_by_mtime = no +# +enable_window_title = yes +# +## +## Note: You can choose default search mode for search engine. Available modes +## are: +## +## - 1 - use mpd built-in searching (no regexes, pattern matching) +## +## - 2 - use ncmpcpp searching (pattern matching with support for regexes, but +## if your mpd is on a remote machine, downloading big database to process +## it can take a while +## +## - 3 - match only exact values (this mode uses mpd function for searching in +## database and local one for searching in current playlist) +## +# +#search_engine_default_search_mode = 1 +# +external_editor = vim +# +## Note: set to yes if external editor is a console application. +## +use_console_editor = yes +# +##### colors definitions ##### +## +## It is possible to set a background color by setting a color value +## "_", e.g. red_black will set foregound color to red +## and background color to black. +## +## In addition, for terminals that support 256 colors it is possible to set one +## of them by using a number in range [1, 256] instead of color name, +## e.g. numerical value corresponding to red_black is 2_1. To find out if the +## terminal supports 256 colors, run ncmpcpp and check out the bottom of the +## help screen for list of available colors and their numerical values. +## +## What is more, there are two special values for the background color: +## "transparent" and "current". The first one explicitly sets the background to +## be transparent, while the second one allows you to preserve current +## background color and change only the foreground one. It's used implicitly +## when background color is not specified. +## +## Moreover, it is possible to attach format information to selected color +## variables by appending to their end a colon followed by one or more format +## flags, e.g. black:b or red:ur. The following variables support this syntax: +## visualizer_color, color1, color2, empty_tag_color, volume_color, +## state_line_color, state_flags_color, progressbar_color, +## progressbar_elapsed_color, player_state_color, statusbar_time_color, +## alternative_ui_separator_color. +## +## Note: due to technical limitations of older ncurses version, if 256 colors +## are used there is a possibility that you'll be able to use only colors with +## transparent background. +# +#colors_enabled = yes +# +empty_tag_color = magenta +# +#header_window_color = magenta +# +#volume_color = default +# +#state_line_color = default +# +#state_flags_color = default:b +# +main_window_color = white +# +#color1 = white +# +#color2 = green +# +progressbar_color = black:b +# +progressbar_elapsed_color = blue:b +# +statusbar_color = red +# +statusbar_time_color = cyan:b +# +#player_state_color = default:b +# +#alternative_ui_separator_color = black:b +# +#window_border_color = green +# +#active_window_border = red +# diff --git a/.config/newsboat/config b/.config/newsboat/config new file mode 100644 index 0000000..88431ee --- /dev/null +++ b/.config/newsboat/config @@ -0,0 +1,40 @@ +#show-read-feeds no +auto-reload yes + +external-url-viewer "urlscan -dc -r 'linkhandler {}'" + +bind-key j down +bind-key k up +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 end +bind-key g home +bind-key d pagedown +bind-key u pageup +bind-key l open +bind-key h quit +bind-key a toggle-article-read +bind-key n next-unread +bind-key N prev-unread +bind-key D pb-download +bind-key U show-urls +bind-key x pb-delete +bind-key ^t next-unread + +color listnormal cyan default +color listfocus black yellow standout bold +color listnormal_unread blue default +color listfocus_unread yellow default bold +color info red black bold +color article cyan default + +browser linkhandler +macro , open-in-browser +macro t set browser "tsp youtube-dl --add-metadata -ic"; open-in-browser ; set browser linkhandler +macro a set browser "tsp youtube-dl --add-metadata -xic -f bestaudio/best"; open-in-browser ; set browser linkhandler +macro v set browser "setsid nohup mpv"; open-in-browser ; set browser linkhandler +macro w set browser "w3m"; open-in-browser ; set browser linkhandler +macro p set browser "setsid dmenuhandler"; open-in-browser ; set browser linkhandler +macro c set browser "xsel -b <<<" ; open-in-browser ; set browser linkandler diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim new file mode 100644 index 0000000..56f6ecd --- /dev/null +++ b/.config/nvim/init.vim @@ -0,0 +1,427 @@ +let mapleader ="," + +if ! filereadable(system('echo -n "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/plug.vim"')) + echo "Downloading junegunn/vim-plug to manage plugins..." + silent !mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/ + silent !curl "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" > ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/autoload/plug.vim + autocmd VimEnter * PlugInstall +endif + + +call plug#begin(system('echo -n "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/plugged"')) +Plug 'tpope/vim-surround' +Plug 'preservim/nerdtree' +Plug 'junegunn/goyo.vim' +Plug 'PotatoesMaster/i3-vim-syntax' +Plug 'jreybert/vimagit' +Plug 'lukesmithxyz/vimling' +Plug 'vimwiki/vimwiki' +Plug 'bling/vim-airline' +Plug 'tpope/vim-commentary' +Plug 'kovetskiy/sxhkd-vim' +Plug 'ap/vim-css-color' +Plug 'lervag/vimtex' +Plug 'terryma/vim-multiple-cursors' +Plug 'neoclide/coc.nvim', {'branch': 'release'} +Plug 'dense-analysis/ale' +Plug 'arcticicestudio/nord-vim' +Plug 'tpope/vim-fugitive' +call plug#end() + +set bg=light +set go=a +set mouse=a +set nohlsearch +set clipboard+=unnamedplus + +colorscheme nord + +" Some basics: + nnoremap c "_c + set nocompatible + filetype plugin on + syntax on + set encoding=utf-8 + set number relativenumber +" Enable autocompletion: + set wildmode=longest,list,full +" Disables automatic commenting on newline: + autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o + +" Goyo plugin makes text more readable when writing prose: + map f :Goyo \| set bg=light \| set linebreak + +" Spell-check set to o, 'o' for 'orthography': + map o :setlocal spell! spelllang=en_us + +" Splits open at the bottom and right, which is non-retarded, unlike vim defaults. + set splitbelow splitright + +" Nerd tree + map n :NERDTreeToggle + autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif + +" vimling: + nm d :call ToggleDeadKeys() + imap d :call ToggleDeadKeys()a + nm i :call ToggleIPA() + imap i :call ToggleIPA()a + nm q :call ToggleProse() + +" Shortcutting split navigation, saving a keypress: + map h + map j + map k + map l + +" Replace ex mode with gq + map Q gq + +" Check file in shellcheck: + map s :!clear && shellcheck % + +" Open my bibliography file in split + map b :vsp$BIB + map r :vsp$REFER + +" Replace all is aliased to S. + nnoremap S :%s//g + +" Compile document, be it groff/LaTeX/markdown/etc. + map c :w! \| !compiler % + +" Open corresponding .pdf/.html or preview + map p :!opout % + +" Runs a script that cleans out tex build files whenever I close out of a .tex file. + autocmd VimLeave *.tex !texclear % + +" Copy selected text to system clipboard (requires gvim/nvim/vim-x11 installed): + vnoremap "+y + map "+P + +" Ensure files are read as what I want: + let g:vimwiki_ext2syntax = {'.Rmd': 'markdown', '.rmd': 'markdown','.md': 'markdown', '.markdown': 'markdown', '.mdown': 'markdown'} + map v :VimwikiIndex + let g:vimwiki_list = [{'path': '~/vimwiki', 'syntax': 'markdown', 'ext': '.md'}] + autocmd BufRead,BufNewFile /tmp/calcurse*,~/.calcurse/notes/* set filetype=markdown + autocmd BufRead,BufNewFile *.ms,*.me,*.mom,*.man set filetype=groff + autocmd BufRead,BufNewFile *.tex set filetype=tex + +" Save file as sudo on files that require root permission + cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' edit! + +" Enable Goyo by default for mutt writting + autocmd BufRead,BufNewFile /tmp/neomutt* let g:goyo_width=80 + autocmd BufRead,BufNewFile /tmp/neomutt* :Goyo | set bg=light + autocmd BufRead,BufNewFile /tmp/neomutt* map ZZ :Goyo\|x! + autocmd BufRead,BufNewFile /tmp/neomutt* map ZQ :Goyo\|q! + +" Automatically deletes all trailing whitespace and newlines at end of file on save. + autocmd BufWritePre * %s/\s\+$//e + autocmd BufWritepre * %s/\n\+\%$//e + +" When shortcut files are updated, renew bash and ranger configs with new material: + autocmd BufWritePost files,directories !shortcuts +" Run xrdb whenever Xdefaults or Xresources are updated. + autocmd BufWritePost *Xresources,*Xdefaults !xrdb -merge % +" Update binds when sxhkdrc is updated. + autocmd BufWritePost *sxhkdrc !pkill -USR1 sxhkd + +" Turns off highlighting on the bits of code that are changed, so the line that is changed is highlighted but the actual text that has changed stands out on the line and is readable. +if &diff + highlight! link DiffText MatchParen +endif + +" Navigating with guides + inoremap /<++>"_c4l + vnoremap /<++>"_c4l + map /<++>"_c4l + + +" Enable completion where available. +" This setting must be set before ALE is loaded. +" +" You should not turn this setting on if you wish to use ALE as a completion +" source for other completion plugins, like Deoplete. +let g:ale_completion_enabled = 1 + + +""""COC config + +" TextEdit might fail if hidden is not set. +set hidden + +" Some servers have issues with backup files, see #649. +set nobackup +set nowritebackup + +" Give more space for displaying messages. +set cmdheight=2 + +" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable +" delays and poor user experience. +set updatetime=300 + +" Don't pass messages to |ins-completion-menu|. +set shortmess+=c + +" Always show the signcolumn, otherwise it would shift the text each time +" diagnostics appear/become resolved. +set signcolumn=no + +" Use tab for trigger completion with characters ahead and navigate. +" NOTE: Use command ':verbose imap ' to make sure tab is not mapped by +" other plugin before putting this into your config. +inoremap + \ pumvisible() ? "\" : + \ check_back_space() ? "\" : + \ coc#refresh() +inoremap pumvisible() ? "\" : "\" + +function! s:check_back_space() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~# '\s' +endfunction + +" Use to trigger completion. +inoremap coc#refresh() + +" Use to confirm completion, `u` means break undo chain at current +" position. Coc only does snippet and additional edit on confirm. +" could be remapped by other vim plugin, try `:verbose imap `. +if exists('*complete_info') + inoremap complete_info()["selected"] != "-1" ? "\" : "\u\" +else + inoremap pumvisible() ? "\" : "\u\" +endif + +" Use `[g` and `]g` to navigate diagnostics +nmap [g (coc-diagnostic-prev) +nmap ]g (coc-diagnostic-next) + +" GoTo code navigation. +nmap gd (coc-definition) +nmap gy (coc-type-definition) +nmap gi (coc-implementation) +nmap gr (coc-references) + +" Use K to show documentation in preview window. +nnoremap K :call show_documentation() + +function! s:show_documentation() + if (index(['vim','help'], &filetype) >= 0) + execute 'h '.expand('') + else + call CocAction('doHover') + endif +endfunction + +" Highlight the symbol and its references when holding the cursor. +autocmd CursorHold * silent call CocActionAsync('highlight') + +" Symbol renaming. +nmap rn (coc-rename) + +" Formatting selected code. +xmap f (coc-format-selected) +nmap f (coc-format-selected) + +augroup mygroup + autocmd! + " Setup formatexpr specified filetype(s). + autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') + " Update signature help on jump placeholder. + autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') +augroup end + +" Applying codeAction to the selected region. +" Example: `aap` for current paragraph +xmap a (coc-codeaction-selected) +nmap a (coc-codeaction-selected) + +" Remap keys for applying codeAction to the current line. +nmap ac (coc-codeaction) +" Apply AutoFix to problem on the current line. +nmap qf (coc-fix-current) + +" Introduce function text object +" NOTE: Requires 'textDocument.documentSymbol' support from the language server. +xmap if (coc-funcobj-i) +xmap af (coc-funcobj-a) +omap if (coc-funcobj-i) +omap af (coc-funcobj-a) + +" Use for selections ranges. +" NOTE: Requires 'textDocument/selectionRange' support from the language server. +" coc-tsserver, coc-python are the examples of servers that support it. +nmap (coc-range-select) +xmap (coc-range-select) + +" Add `:Format` command to format current buffer. +command! -nargs=0 Format :call CocAction('format') + +" Add `:Fold` command to fold current buffer. +command! -nargs=? Fold :call CocAction('fold', ) + +" Add `:OR` command for organize imports of the current buffer. +command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport') + +" Add (Neo)Vim's native statusline support. +" NOTE: Please see `:h coc-status` for integrations with external plugins that +" provide custom statusline: lightline.vim, vim-airline. +set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')} + +" Mappings using CoCList: +" Show all diagnostics. +nnoremap a :CocList diagnostics +" Manage extensions. +nnoremap e :CocList extensions +" Show commands. +nnoremap c :CocList commands +" Find symbol of current document. +nnoremap o :CocList outline +" Search workspace symbols. +nnoremap s :CocList -I symbols +" Do default action for next item. +nnoremap j :CocNext +" Do default action for previous item. +nnoremap k :CocPrev +" Resume latest coc list. +nnoremap p :CocListResume + +"""VimTex +let g:vimtex_view_method = 'zathura' +let g:latex_view_general_viewer = 'zathura' +let g:vimtex_log_verbose = 0 +let g:vimtex_quickfix_open_on_warning = 0 + +"""Fix E10 error for some tex stuff: +set nocompatible + + +"""LATEX + " Word count: + autocmd FileType tex map w :w !detex \| wc -w + " Code snippets + """autocmd FileType tex inoremap ,fr \begin{frame}\frametitle{}<++>\end{frame}<++>6kf}i + autocmd FileType tex inoremap ,fi \begin{fitch}\end{fitch}<++>3kA + autocmd FileType tex inoremap ,exe \begin{exe}\ex\end{exe}<++>3kA + autocmd FileType tex inoremap ,bf \textbf{}<++>T{i + autocmd FileType tex vnoremap , ``>2la}?\\{a + autocmd FileType tex inoremap ,it \textit{}<++>T{i + autocmd FileType tex inoremap ,ct \textcite{}<++>T{i + autocmd FileType tex inoremap ,cp \parencite{}<++>T{i + autocmd FileType tex inoremap ,glos {\gll<++>\\<++>\\\trans{``<++>''}}2k2bcw + autocmd FileType tex inoremap ,x \begin{xlist}\ex\end{xlist}kA + autocmd FileType tex inoremap ,ol \begin{enumerate}\end{enumerate}<++>3kA\item + autocmd FileType tex inoremap ,ul \begin{itemize}\end{itemize}<++>3kA\item + autocmd FileType tex inoremap ,li \item[] + autocmd FileType tex inoremap ,ref \ref{}<++>T{i + autocmd FileType tex inoremap ,tab \begin{tabular}<++>\end{tabular}<++>4kA{}i + autocmd FileType tex inoremap ,ot \begin{tableau}\inp{<++>}\const{<++>}<++><++>\end{tableau}<++>5kA{}i + autocmd FileType tex inoremap ,can \cand{}<++>T{i + autocmd FileType tex inoremap ,con \const{}<++>T{i + autocmd FileType tex inoremap ,v \vio{}<++>T{i + autocmd FileType tex inoremap ,a \href{}{<++>}<++>2T{i + autocmd FileType tex inoremap ,sc \textsc{}<++>T{i + autocmd FileType tex inoremap ,chap \chapter{}<++>2kf}i + autocmd FileType tex inoremap ,sec \section{}<++>2kf}i + autocmd FileType tex inoremap ,ssec \subsection{}<++>2kf}i + autocmd FileType tex inoremap ,sssec \subsubsection{}<++>2kf}i + autocmd FileType tex inoremap ,st F{i*f}i + autocmd FileType tex inoremap ,beg \begin{DELRN}<++>\end{DELRN}<++>4k0fR:MultipleCursorsFindDELRNc + autocmd FileType tex inoremap ,up /usepackageo\usepackage{}i + autocmd FileType tex nnoremap ,up /usepackageo\usepackage{}i + autocmd FileType tex inoremap ,tt \texttt{}<++>T{i + autocmd FileType tex inoremap ,bt {\blindtext} + autocmd FileType tex inoremap ,nu $\varnothing$ + autocmd FileType tex inoremap ,col \begin{columns}[T]\begin{column}{.5\textwidth}\end{column}\begin{column}{.5\textwidth}<++>\end{column}\end{columns}5kA + autocmd FileType tex inoremap ,rn (\ref{})<++>F}i + autocmd FileType tex inoremap ,fr \dfrac{}{<++>} <++> T{2hi + autocmd FileType tex inoremap ,sqrt \sqrt{}<++> T{i + autocmd FileType tex inoremap ,b( \left(\right)<++>T(i + autocmd FileType tex inoremap ,bb \mathbb{}<++>T{i + autocmd FileType tex inoremap ,b{ \left\{\right\}<++>T{i + autocmd FileType tex inoremap ,b[ \left[\right]<++>T[i + autocmd FileType tex inoremap ,rm \mathrm{}<++>T{i + autocmd FileType tex inoremap ,abs \left\|\right\|<++>3ba + autocmd FileType tex inoremap ,em \emph{}<++>T{i + autocmd FileType tex inoremap ,tabb \begin{tabbing}\hspace*{3cm}\=\hspace*{3cm}\= \kill\end{tabbing}<++>3kA + autocmd FileType tex inoremap ,txt \text{}<++>T{i + autocmd FileType tex inoremap ,sfr \sfrac{}{<++>}<++>2T{i + + + + +"""HTML + autocmd FileType html inoremap ,b <++>FbT>i + autocmd FileType html inoremap ,it <++>FeT>i + autocmd FileType html inoremap ,1

<++>2kf<++>2kf<++>2kf

<++>02kf>a + autocmd FileType html inoremap ,a href=""><++><++>14hi + autocmd FileType html inoremap ,e target="_blank"href=""><++><++>14hi + autocmd FileType html inoremap ,ul
<++>03kfo
  • F>a + autocmd FileType html inoremap ,ol
    <++>03kf<++>Fcf"a + autocmd FileType html inoremap ,td <++>Fdcit + autocmd FileType html inoremap ,tr <++>kf<++>Fhcit + autocmd FileType html inoremap ,tab
    O + autocmd FileType html inoremap ,gr F>a + autocmd FileType html inoremap ,rd F>a + autocmd FileType html inoremap ,yl F>a + autocmd FileType html inoremap ,dt
    <++>
    <++>2kcit + autocmd FileType html inoremap ,dl
    <++>3kcc + autocmd FileType html inoremap & & + autocmd FileType html inoremap รก á + autocmd FileType html inoremap รฉ é + autocmd FileType html inoremap รญ í + autocmd FileType html inoremap รณ ó + autocmd FileType html inoremap รบ ú + autocmd FileType html inoremap รค ä + autocmd FileType html inoremap รซ ë + autocmd FileType html inoremap รฏ ï + autocmd FileType html inoremap รถ ö + autocmd FileType html inoremap รผ ü + autocmd FileType html inoremap รฃ ã + autocmd FileType html inoremap แบฝ &etilde; + autocmd FileType html inoremap ฤฉ ĩ + autocmd FileType html inoremap รต õ + autocmd FileType html inoremap ลฉ ũ + autocmd FileType html inoremap รฑ ñ + autocmd FileType html inoremap ร  à + autocmd FileType html inoremap รจ è + autocmd FileType html inoremap รฌ ì + autocmd FileType html inoremap รฒ ò + autocmd FileType html inoremap รน ù + + +""".bib + autocmd FileType bib inoremap ,a @article{author={<++>},year={<++>},title={<++>},journal={<++>},volume={<++>},pages={<++>},}<++>8kA,i + autocmd FileType bib inoremap ,b @book{author={<++>},year={<++>},title={<++>},publisher={<++>},}<++>6kA,i + autocmd FileType bib inoremap ,c @incollection{author={<++>},title={<++>},booktitle={<++>},editor={<++>},year={<++>},publisher={<++>},}<++>8kA,i + +"MARKDOWN + autocmd Filetype markdown,rmd map w yiWi[Ea](pa) + autocmd Filetype markdown,rmd inoremap ,n --- + autocmd Filetype markdown,rmd inoremap ,b ****<++>F*hi + autocmd Filetype markdown,rmd inoremap ,s ~~~~<++>F~hi + autocmd Filetype markdown,rmd inoremap ,e **<++>F*i + autocmd Filetype markdown,rmd inoremap ,h ====<++>F=hi + autocmd Filetype markdown,rmd inoremap ,i ![](<++>)<++>F[a + autocmd Filetype markdown,rmd inoremap ,a [](<++>)<++>F[a + autocmd Filetype markdown,rmd inoremap ,1 #<++>kA + autocmd Filetype markdown,rmd inoremap ,2 ##<++>kA + autocmd Filetype markdown,rmd inoremap ,3 ###<++>kA + autocmd Filetype markdown,rmd inoremap ,l -------- + autocmd Filetype markdown,rmd inoremap ,r ```{r}```2kO + autocmd Filetype markdown,rmd inoremap ,p ```{python}```2kO + autocmd Filetype mardown,rmd inoremap ,c ``````2kO + +""".xml + autocmd FileType xml inoremap ,e <++>isPermaLink="false"><++>:put=strftime('%a, %d %b %Y %H:%M:%S %z')kJA<++>]]>?<enter>cit + autocmd FileType xml inoremap ,a <a href="<++>"><++></a><++><Esc>F"ci" diff --git a/.config/pass-git-helper/git-pass-mapping.ini b/.config/pass-git-helper/git-pass-mapping.ini new file mode 100644 index 0000000..97f7520 --- /dev/null +++ b/.config/pass-git-helper/git-pass-mapping.ini @@ -0,0 +1,2 @@ +[github.com] +target=Misc/github diff --git a/.config/qutebrowser/autoconfig.yml b/.config/qutebrowser/autoconfig.yml new file mode 100644 index 0000000..e0ab2bd --- /dev/null +++ b/.config/qutebrowser/autoconfig.yml @@ -0,0 +1,69 @@ +# If a config.py file exists, this file is ignored unless it's explicitly loaded +# via config.load_autoconfig(). For more information, see: +# https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc#loading-autoconfigyml +# DO NOT edit this file by hand, qutebrowser will overwrite it. +# Instead, create a config.py - see :help for details. + +config_version: 2 +settings: + bindings.commands: + global: + normal: + ',V': spawn setsid mpv {url} + ',X': spawn dmenuhandler {url} + ',c': hint links spawn setsid st castyt {hint-url} + ',v': hint links spawn setsid mpv {hint-url} + ',x': hint links spawn setsid dmenuhandler {hint-url} + content.desktop_capture: + global: ask + content.notifications: + https://boards.4chan.org: true + https://boards.4channel.org: true + https://riot.im: true + https://support.cloud.google.com: true + https://www.reddit.com: false + https://www.youtube.com: false + content.register_protocol_handler: + https://mail.google.com?extsrc=mailto&url=%25s: false + downloads.location.directory: + global: /home/alex/ + downloads.location.prompt: + global: false + downloads.location.suggestion: + global: path + downloads.position: + global: top + downloads.remove_finished: + global: 0 + editor.command: + global: + - nvim + - -f + - '{file}' + - -c + - normal {line}G{column0}l + fonts.default_size: + global: 20pt + fonts.web.size.default_fixed: + global: 13 + hints.border: + global: '2px solid #E3BE23' + prompt.filebrowser: + global: false + qt.highdpi: + global: true + tabs.show: + global: never + tabs.tabs_are_windows: + global: true + url.searchengines: + global: + DEFAULT: https://searx.tuxcloud.net/?q={}&categories=general&language=en-US + ddg: https://duckduckgo.com/?q={} + ling: https://www.linguee.com/english-german/search?source=auto&query={} + sx: https://searx.tuxcloud.net/?q={}&categories=general&language=en-US + yt: https://www.youtube.com/results?search_query={} + url.start_pages: + global: https://searx.privatenet.cf/ + zoom.default: + global: 160% diff --git a/.config/qutebrowser/bookmarks/urls b/.config/qutebrowser/bookmarks/urls new file mode 100644 index 0000000..3ed044f --- /dev/null +++ b/.config/qutebrowser/bookmarks/urls @@ -0,0 +1 @@ +https://security.stackexchange.com/questions/220068/using-local-port-forwarding-from-raspberrypi-to-vps-in-order-to-be-able-to-acces ssh - Using local port forwarding from RaspberryPI to VPS in order to be able to access the PI from anywhere on the Internet, security considerations? - Information Security Stack Exchange diff --git a/.config/qutebrowser/config.py b/.config/qutebrowser/config.py new file mode 100644 index 0000000..c99f21a --- /dev/null +++ b/.config/qutebrowser/config.py @@ -0,0 +1,11 @@ +import dracula.draw + +# Load existing settings made via :set +config.load_autoconfig() + +dracula.draw.blood(c, { + 'spacing': { + 'vertical': 0, + 'horizontal': 0 + } +}) diff --git a/.config/qutebrowser/dracula/.gitignore b/.config/qutebrowser/dracula/.gitignore new file mode 100644 index 0000000..4949fe8 --- /dev/null +++ b/.config/qutebrowser/dracula/.gitignore @@ -0,0 +1,2 @@ +/bookmarks/ +quickmarks diff --git a/.config/qutebrowser/dracula/INSTALL.md b/.config/qutebrowser/dracula/INSTALL.md new file mode 100644 index 0000000..7c61e78 --- /dev/null +++ b/.config/qutebrowser/dracula/INSTALL.md @@ -0,0 +1,31 @@ +### [qutebrowser](https://www.qutebrowser.org/) + +#### Install using Git + +If you are a git user, you can install the theme and keep up to date by cloning the repo: + + $ git clone https://github.com/dracula/qutebrowser-dracula-theme.git dracula + +#### Install manually + +Download using the [GitHub .zip download](https://github.com/dracula/qutebrowser.git) option and unzip. + +#### Activating theme + +- Find your *[qutebrowser configuration directory](https://www.qutebrowser.org/doc/help/configuring.html#configpy)* (see e.g. `:version` in qutebrowser). This folder should be located at the "config" location listed on qute://version, which is typically ~/.config/qutebrowser/ on Linux, ~/.qutebrowser/ on macOS, and %APPDATA%/qutebrowser/config/ on Windows. +- Move the repository folder to `dracula` inside the configuration directory. +- In your [qutebrowser config.py file](https://www.qutebrowser.org/doc/help/configuring.html#configpy), include the following: + +```python +import dracula.draw + +# Load existing settings made via :set +config.load_autoconfig() + +dracula.draw.blood(c, { + 'spacing': { + 'vertical': 6, + 'horizontal': 8 + } +}) +``` diff --git a/.config/qutebrowser/dracula/__init__.py b/.config/qutebrowser/dracula/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.config/qutebrowser/dracula/__pycache__/__init__.cpython-38.pyc b/.config/qutebrowser/dracula/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..35d495a Binary files /dev/null and b/.config/qutebrowser/dracula/__pycache__/__init__.cpython-38.pyc differ diff --git a/.config/qutebrowser/dracula/__pycache__/draw.cpython-38.pyc b/.config/qutebrowser/dracula/__pycache__/draw.cpython-38.pyc new file mode 100644 index 0000000..9c26f68 Binary files /dev/null and b/.config/qutebrowser/dracula/__pycache__/draw.cpython-38.pyc differ diff --git a/.config/qutebrowser/dracula/draw.py b/.config/qutebrowser/dracula/draw.py new file mode 100644 index 0000000..b73e3e1 --- /dev/null +++ b/.config/qutebrowser/dracula/draw.py @@ -0,0 +1,303 @@ +def blood(c, options = {}): + palette = { + 'background': '#000000', + 'background-alt': '#111111', + 'background-attention': '#181920', + 'border': '#282a36', + #'current-line': '#44475a', + #'selection': '#44475a', + #'foreground': '#f8f8f2', + #'foreground-alt': '#e0e0e0', + #'foreground-attention': '#ffffff', + #'comment': '#6272a4', + #'cyan': '#8be9fd', + #'green': '#50fa7b', + #'orange': '#ffb86c', + #'pink': '#ff79c6', + #'purple': '#bd93f9', + #'red': '#ff5555', + #'yellow': '#f1fa8c' + 'current-line': '#44475a', + 'selection': '#44475a', + 'foreground': '#f8f8f2', + 'foreground-alt': '#e0e0e0', + 'foreground-attention': '#ffffff', + 'comment': '#6272a4', + 'cyan': '#8be9fd', + 'green': '#A3C48C', + 'orange': '#ffb86c', + 'pink': '#ff79c6', + 'purple': '#bd93f9', + 'red': '#BF616A', + 'yellow': '#f1fa8c' + } + + spacing = options.get('spacing', { + 'vertical': 0, + 'horizontal': 0 + }) + + padding = options.get('padding', { + 'top': spacing['vertical'], + 'right': spacing['horizontal'], + 'bottom': spacing['vertical'], + 'left': spacing['horizontal'] + }) + + ## Background color of the completion widget category headers. + c.colors.completion.category.bg = palette['background'] + + ## Bottom border color of the completion widget category headers. + c.colors.completion.category.border.bottom = palette['border'] + + ## Top border color of the completion widget category headers. + c.colors.completion.category.border.top = palette['border'] + + ## Foreground color of completion widget category headers. + c.colors.completion.category.fg = palette['foreground'] + + ## Background color of the completion widget for even rows. + c.colors.completion.even.bg = palette['background'] + + ## Background color of the completion widget for odd rows. + c.colors.completion.odd.bg = palette['background-alt'] + + ## Text color of the completion widget. + c.colors.completion.fg = palette['foreground'] + + ## Background color of the selected completion item. + c.colors.completion.item.selected.bg = palette['selection'] + + ## Bottom border color of the selected completion item. + c.colors.completion.item.selected.border.bottom = palette['selection'] + + ## Top border color of the completion widget category headers. + c.colors.completion.item.selected.border.top = palette['selection'] + + ## Foreground color of the selected completion item. + c.colors.completion.item.selected.fg = palette['foreground'] + + ## Foreground color of the matched text in the completion. + c.colors.completion.match.fg = palette['orange'] + + ## Color of the scrollbar in completion view + c.colors.completion.scrollbar.bg = palette['background'] + + ## Color of the scrollbar handle in completion view. + c.colors.completion.scrollbar.fg = palette['foreground'] + + ## Background color for the download bar. + c.colors.downloads.bar.bg = palette['background'] + + ## Background color for downloads with errors. + c.colors.downloads.error.bg = palette['background'] + + ## Foreground color for downloads with errors. + c.colors.downloads.error.fg = palette['red'] + + ## Color gradient stop for download backgrounds. + c.colors.downloads.stop.bg = palette['background'] + + ## Color gradient interpolation system for download backgrounds. + ## Type: ColorSystem + ## Valid values: + ## - rgb: Interpolate in the RGB color system. + ## - hsv: Interpolate in the HSV color system. + ## - hsl: Interpolate in the HSL color system. + ## - none: Don't show a gradient. + c.colors.downloads.system.bg = 'none' + + ## Background color for hints. Note that you can use a `rgba(...)` value + ## for transparency. + c.colors.hints.bg = palette['background'] + + ## Font color for hints. + c.colors.hints.fg = palette['purple'] + + ## Hints + c.hints.border = '1px solid ' + palette['background-alt'] + + ## Font color for the matched part of hints. + c.colors.hints.match.fg = palette['foreground-alt'] + + ## Background color of the keyhint widget. + c.colors.keyhint.bg = palette['background'] + + ## Text color for the keyhint widget. + c.colors.keyhint.fg = palette['purple'] + + ## Highlight color for keys to complete the current keychain. + c.colors.keyhint.suffix.fg = palette['selection'] + + ## Background color of an error message. + c.colors.messages.error.bg = palette['background'] + + ## Border color of an error message. + c.colors.messages.error.border = palette['background-alt'] + + ## Foreground color of an error message. + c.colors.messages.error.fg = palette['red'] + + ## Background color of an info message. + c.colors.messages.info.bg = palette['background'] + + ## Border color of an info message. + c.colors.messages.info.border = palette['background-alt'] + + ## Foreground color an info message. + c.colors.messages.info.fg = palette['comment'] + + ## Background color of a warning message. + c.colors.messages.warning.bg = palette['background'] + + ## Border color of a warning message. + c.colors.messages.warning.border = palette['background-alt'] + + ## Foreground color a warning message. + c.colors.messages.warning.fg = palette['red'] + + ## Background color for prompts. + c.colors.prompts.bg = palette['background'] + + # ## Border used around UI elements in prompts. + c.colors.prompts.border = '1px solid ' + palette['background-alt'] + + ## Foreground color for prompts. + c.colors.prompts.fg = palette['cyan'] + + ## Background color for the selected item in filename prompts. + c.colors.prompts.selected.bg = palette['selection'] + + ## Background color of the statusbar in caret mode. + c.colors.statusbar.caret.bg = palette['background'] + + ## Foreground color of the statusbar in caret mode. + c.colors.statusbar.caret.fg = palette['orange'] + + ## Background color of the statusbar in caret mode with a selection. + c.colors.statusbar.caret.selection.bg = palette['background'] + + ## Foreground color of the statusbar in caret mode with a selection. + c.colors.statusbar.caret.selection.fg = palette['orange'] + + ## Background color of the statusbar in command mode. + c.colors.statusbar.command.bg = palette['background'] + + ## Foreground color of the statusbar in command mode. + c.colors.statusbar.command.fg = palette['foreground'] + + ## Background color of the statusbar in private browsing + command mode. + c.colors.statusbar.command.private.bg = palette['background'] + + ## Foreground color of the statusbar in private browsing + command mode. + c.colors.statusbar.command.private.fg = palette['foreground-alt'] + + ## Background color of the statusbar in insert mode. + c.colors.statusbar.insert.bg = palette['background-attention'] + + ## Foreground color of the statusbar in insert mode. + c.colors.statusbar.insert.fg = palette['foreground-attention'] + + ## Background color of the statusbar. + c.colors.statusbar.normal.bg = palette['background'] + + ## Foreground color of the statusbar. + c.colors.statusbar.normal.fg = palette['foreground'] + + ## Background color of the statusbar in passthrough mode. + c.colors.statusbar.passthrough.bg = palette['background'] + + ## Foreground color of the statusbar in passthrough mode. + c.colors.statusbar.passthrough.fg = palette['orange'] + + ## Background color of the statusbar in private browsing mode. + c.colors.statusbar.private.bg = palette['background-alt'] + + ## Foreground color of the statusbar in private browsing mode. + c.colors.statusbar.private.fg = palette['foreground-alt'] + + ## Background color of the progress bar. + c.colors.statusbar.progress.bg = palette['background'] + + ## Foreground color of the URL in the statusbar on error. + c.colors.statusbar.url.error.fg = palette['red'] + + ## Default foreground color of the URL in the statusbar. + c.colors.statusbar.url.fg = palette['foreground'] + + ## Foreground color of the URL in the statusbar for hovered links. + c.colors.statusbar.url.hover.fg = palette['cyan'] + + ## Foreground color of the URL in the statusbar on successful load + c.colors.statusbar.url.success.http.fg = palette['green'] + + ## Foreground color of the URL in the statusbar on successful load + c.colors.statusbar.url.success.https.fg = palette['green'] + + ## Foreground color of the URL in the statusbar when there's a warning. + c.colors.statusbar.url.warn.fg = palette['yellow'] + + ## Status bar padding + c.statusbar.padding = padding + + ## Background color of the tab bar. + ## Type: QtColor + c.colors.tabs.bar.bg = palette['selection'] + + ## Background color of unselected even tabs. + ## Type: QtColor + c.colors.tabs.even.bg = palette['selection'] + + ## Foreground color of unselected even tabs. + ## Type: QtColor + c.colors.tabs.even.fg = palette['foreground'] + + ## Color for the tab indicator on errors. + ## Type: QtColor + c.colors.tabs.indicator.error = palette['red'] + + ## Color gradient start for the tab indicator. + ## Type: QtColor + c.colors.tabs.indicator.start = palette['orange'] + + ## Color gradient end for the tab indicator. + ## Type: QtColor + c.colors.tabs.indicator.stop = palette['green'] + + ## Color gradient interpolation system for the tab indicator. + ## Type: ColorSystem + ## Valid values: + ## - rgb: Interpolate in the RGB color system. + ## - hsv: Interpolate in the HSV color system. + ## - hsl: Interpolate in the HSL color system. + ## - none: Don't show a gradient. + c.colors.tabs.indicator.system = 'none' + + ## Background color of unselected odd tabs. + ## Type: QtColor + c.colors.tabs.odd.bg = palette['selection'] + + ## Foreground color of unselected odd tabs. + ## Type: QtColor + c.colors.tabs.odd.fg = palette['foreground'] + + # ## Background color of selected even tabs. + # ## Type: QtColor + c.colors.tabs.selected.even.bg = palette['background'] + + # ## Foreground color of selected even tabs. + # ## Type: QtColor + c.colors.tabs.selected.even.fg = palette['foreground'] + + # ## Background color of selected odd tabs. + # ## Type: QtColor + c.colors.tabs.selected.odd.bg = palette['background'] + + # ## Foreground color of selected odd tabs. + # ## Type: QtColor + c.colors.tabs.selected.odd.fg = palette['foreground'] + + ## Tab padding + c.tabs.padding = padding + c.tabs.indicator.width = 1 + c.tabs.favicons.scale = 1 diff --git a/.config/qutebrowser/dracula/readme.md b/.config/qutebrowser/dracula/readme.md new file mode 100644 index 0000000..1e914ea --- /dev/null +++ b/.config/qutebrowser/dracula/readme.md @@ -0,0 +1,21 @@ +# Dracula for [qutebrowser](https://www.qutebrowser.org/) + +> A dark theme for [qutebrowser](https://www.qutebrowser.org/). + +![Screenshot](./screenshot.png) + +## Install + +All instructions can be found at [draculatheme.com/qutebrowser](https://draculatheme.com/qutebrowser). + +## Team + +This theme is maintained by the following person(s) and a bunch of [awesome contributors](https://github.com/dracula/qutebrowser/graphs/contributors). + +[![Evan Nagle](https://avatars2.githubusercontent.com/u/556537?s=88&v=4&s=70)](https://github.com/evannagle) | +--- | +[Evan Nagle](https://github.com/evannagle) | + +## License + +[MIT License](./LICENSE) diff --git a/.config/qutebrowser/dracula/screenshot.png b/.config/qutebrowser/dracula/screenshot.png new file mode 100644 index 0000000..5dbcba4 Binary files /dev/null and b/.config/qutebrowser/dracula/screenshot.png differ diff --git a/.config/qutebrowser/qsettings/QtProject.conf b/.config/qutebrowser/qsettings/QtProject.conf new file mode 100644 index 0000000..c7540e6 --- /dev/null +++ b/.config/qutebrowser/qsettings/QtProject.conf @@ -0,0 +1,8 @@ +[FileDialog] +history=file:///home/alex +lastVisited=file:///home/alex +qtVersion=5.15.0 +shortcuts=file:, file:///home/alex +sidebarWidth=82 +treeViewHeader=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1\xd9\0\0\0\x4\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\0\xe5\0\0\0\x1\0\0\0\0\0\0\0O\0\0\0\x1\0\0\0\0\0\0\0O\0\0\0\x1\0\0\0\0\0\0\0V\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\xff\xff\xff\xff) +viewMode=Detail diff --git a/.config/qutebrowser/quickmarks b/.config/qutebrowser/quickmarks new file mode 100644 index 0000000..776cdef --- /dev/null +++ b/.config/qutebrowser/quickmarks @@ -0,0 +1,6 @@ +gre https://www.prepscholar.com/gre/a/dashboard +ys https://www.youtube.com/feed/subscriptions +moo https://moodle-app2.let.ethz.ch/ +riot https://riot.im/app/#/room/!TVGuLdRkkENrCZonlF:matrix.org +fit https://boards.4channel.org/fit/ +wsg https://boards.4channel.org/wsg/ diff --git a/.config/ranger/colorschemes/__init__.py b/.config/ranger/colorschemes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.config/ranger/colorschemes/__pycache__/__init__.cpython-38.opt-1.pyc b/.config/ranger/colorschemes/__pycache__/__init__.cpython-38.opt-1.pyc new file mode 100644 index 0000000..3da4e5a Binary files /dev/null and b/.config/ranger/colorschemes/__pycache__/__init__.cpython-38.opt-1.pyc differ diff --git a/.config/ranger/colorschemes/__pycache__/default.cpython-38.opt-1.pyc b/.config/ranger/colorschemes/__pycache__/default.cpython-38.opt-1.pyc new file mode 100644 index 0000000..52d8ace Binary files /dev/null and b/.config/ranger/colorschemes/__pycache__/default.cpython-38.opt-1.pyc differ diff --git a/.config/ranger/colorschemes/default.py b/.config/ranger/colorschemes/default.py new file mode 100644 index 0000000..3d50e2e --- /dev/null +++ b/.config/ranger/colorschemes/default.py @@ -0,0 +1,183 @@ +# This file is part of ranger, the console file manager. +# License: GNU GPL version 3, see the file "AUTHORS" for details. + +from __future__ import (absolute_import, division, print_function) + +from ranger.gui.colorscheme import ColorScheme +from ranger.gui.color import ( + black, blue, cyan, green, magenta, red, white, yellow, default, + normal, bold, reverse, dim, BRIGHT, + default_colors, +) + + +class Default(ColorScheme): + progress_bar_color = blue + + def use(self, context): # pylint: disable=too-many-branches,too-many-statements + fg, bg, attr = default_colors + + if context.reset: + return default_colors + + elif context.in_browser: + if context.selected: + attr = reverse + else: + attr = normal + if context.empty or context.error: + bg = red + if context.border: + fg = default + if context.media: + if context.image: + fg = yellow + else: + fg = magenta + if context.container: + fg = red + if context.directory: + attr |= bold + fg = blue + fg += BRIGHT + elif context.executable and not \ + any((context.media, context.container, + context.fifo, context.socket)): + attr |= bold + fg = green + fg += BRIGHT + if context.socket: + attr |= bold + fg = magenta + fg += BRIGHT + if context.fifo or context.device: + fg = yellow + if context.device: + attr |= bold + fg += BRIGHT + if context.link: + fg = cyan if context.good else magenta + if context.tag_marker and not context.selected: + attr |= bold + if fg in (red, magenta): + fg = white + else: + fg = red + fg += BRIGHT + if not context.selected and (context.cut or context.copied): + attr |= bold + fg = black + fg += BRIGHT + # If the terminal doesn't support bright colors, use dim white + # instead of black. + if BRIGHT == 0: + attr |= dim + fg = white + if context.main_column: + # Doubling up with BRIGHT here causes issues because it's + # additive not idempotent. + if context.selected: + attr |= bold + if context.marked: + attr |= bold + fg = yellow + if context.badinfo: + if attr & reverse: + bg = magenta + else: + fg = magenta + + if context.inactive_pane: + fg = cyan + + elif context.in_titlebar: + if context.hostname: + fg = red if context.bad else green + elif context.directory: + fg = blue + elif context.tab: + if context.good: + bg = green + elif context.link: + fg = cyan + attr |= bold + + elif context.in_statusbar: + if context.permissions: + if context.good: + fg = cyan + elif context.bad: + fg = magenta + if context.marked: + attr |= bold | reverse + fg = yellow + fg += BRIGHT + if context.frozen: + attr |= bold | reverse + fg = cyan + fg += BRIGHT + if context.message: + if context.bad: + attr |= bold + fg = red + fg += BRIGHT + if context.loaded: + bg = self.progress_bar_color + if context.vcsinfo: + fg = blue + attr &= ~bold + if context.vcscommit: + fg = yellow + attr &= ~bold + if context.vcsdate: + fg = cyan + attr &= ~bold + + if context.text: + if context.highlight: + attr |= reverse + + if context.in_taskview: + if context.title: + fg = blue + + if context.selected: + attr |= reverse + + if context.loaded: + if context.selected: + fg = self.progress_bar_color + else: + bg = self.progress_bar_color + + if context.vcsfile and not context.selected: + attr &= ~bold + if context.vcsconflict: + fg = magenta + elif context.vcsuntracked: + fg = cyan + elif context.vcschanged: + fg = red + elif context.vcsunknown: + fg = red + elif context.vcsstaged: + fg = green + elif context.vcssync: + fg = green + elif context.vcsignored: + fg = default + + elif context.vcsremote and not context.selected: + attr &= ~bold + if context.vcssync or context.vcsnone: + fg = green + elif context.vcsbehind: + fg = red + elif context.vcsahead: + fg = blue + elif context.vcsdiverged: + fg = magenta + elif context.vcsunknown: + fg = red + + return fg, bg, attr diff --git a/.config/ranger/colorschemes/jungle.py b/.config/ranger/colorschemes/jungle.py new file mode 100644 index 0000000..a1fd768 --- /dev/null +++ b/.config/ranger/colorschemes/jungle.py @@ -0,0 +1,23 @@ +# This file is part of ranger, the console file manager. +# License: GNU GPL version 3, see the file "AUTHORS" for details. + +from __future__ import (absolute_import, division, print_function) + +from ranger.colorschemes.default import Default +from ranger.gui.color import green, red, blue + + +class Scheme(Default): + progress_bar_color = green + + def use(self, context): + fg, bg, attr = Default.use(self, context) + + if context.directory and not context.marked and not context.link \ + and not context.inactive_pane: + fg = self.progress_bar_color + + if context.in_titlebar and context.hostname: + fg = red if context.bad else blue + + return fg, bg, attr diff --git a/.config/ranger/colorschemes/snow.py b/.config/ranger/colorschemes/snow.py new file mode 100644 index 0000000..c5f23c1 --- /dev/null +++ b/.config/ranger/colorschemes/snow.py @@ -0,0 +1,44 @@ +# This file is part of ranger, the console file manager. +# License: GNU GPL version 3, see the file "AUTHORS" for details. + +from __future__ import (absolute_import, division, print_function) + +from ranger.gui.colorscheme import ColorScheme +from ranger.gui.color import default_colors, reverse, bold, BRIGHT + + +class Snow(ColorScheme): + + def use(self, context): + fg, bg, attr = default_colors + + if context.reset: + pass + + elif context.in_browser: + if context.selected: + attr = reverse + if context.directory: + attr |= bold + fg += BRIGHT + + elif context.highlight: + attr |= reverse + + elif context.in_titlebar and context.tab and context.good: + attr |= reverse + + elif context.in_statusbar: + if context.loaded: + attr |= reverse + if context.marked: + attr |= reverse + + elif context.in_taskview: + if context.selected: + attr |= bold + fg += BRIGHT + if context.loaded: + attr |= reverse + + return fg, bg, attr diff --git a/.config/ranger/commands.py b/.config/ranger/commands.py new file mode 100644 index 0000000..97b7909 --- /dev/null +++ b/.config/ranger/commands.py @@ -0,0 +1,62 @@ +# This is a sample commands.py. You can add your own commands here. +# +# Please refer to commands_full.py for all the default commands and a complete +# documentation. Do NOT add them all here, or you may end up with defunct +# commands when upgrading ranger. + +# A simple command for demonstration purposes follows. +# ----------------------------------------------------------------------------- + +from __future__ import (absolute_import, division, print_function) + +# You can import any python module as needed. +import os + +# You always need to import ranger.api.commands here to get the Command class: +from ranger.api.commands import Command + + +# Any class that is a subclass of "Command" will be integrated into ranger as a +# command. Try typing ":my_edit<ENTER>" in ranger! +class my_edit(Command): + # The so-called doc-string of the class will be visible in the built-in + # help that is accessible by typing "?c" inside ranger. + """:my_edit <filename> + + A sample command for demonstration purposes that opens a file in an editor. + """ + + # The execute method is called when you run this command in ranger. + def execute(self): + # self.arg(1) is the first (space-separated) argument to the function. + # This way you can write ":my_edit somefilename<ENTER>". + if self.arg(1): + # self.rest(1) contains self.arg(1) and everything that follows + target_filename = self.rest(1) + else: + # self.fm is a ranger.core.filemanager.FileManager object and gives + # you access to internals of ranger. + # self.fm.thisfile is a ranger.container.file.File object and is a + # reference to the currently selected file. + target_filename = self.fm.thisfile.path + + # This is a generic function to print text in ranger. + self.fm.notify("Let's edit the file " + target_filename + "!") + + # Using bad=True in fm.notify allows you to print error messages: + if not os.path.exists(target_filename): + self.fm.notify("The given file does not exist!", bad=True) + return + + # This executes a function from ranger.core.acitons, a module with a + # variety of subroutines that can help you construct commands. + # Check out the source, or run "pydoc ranger.core.actions" for a list. + self.fm.edit_file(target_filename) + + # The tab method is called when you press tab, and should return a list of + # suggestions that the user will tab through. + # tabnum is 1 for <TAB> and -1 for <S-TAB> by default + def tab(self, tabnum): + # This is a generic tab-completion function that iterates through the + # content of the current directory. + return self._tab_directory_content() diff --git a/.config/ranger/commands_full.py b/.config/ranger/commands_full.py new file mode 100644 index 0000000..d177203 --- /dev/null +++ b/.config/ranger/commands_full.py @@ -0,0 +1,1836 @@ +# -*- coding: utf-8 -*- +# This file is part of ranger, the console file manager. +# This configuration file is licensed under the same terms as ranger. +# =================================================================== +# +# NOTE: If you copied this file to /etc/ranger/commands_full.py or +# ~/.config/ranger/commands_full.py, then it will NOT be loaded by ranger, +# and only serve as a reference. +# +# =================================================================== +# This file contains ranger's commands. +# It's all in python; lines beginning with # are comments. +# +# Note that additional commands are automatically generated from the methods +# of the class ranger.core.actions.Actions. +# +# You can customize commands in the files /etc/ranger/commands.py (system-wide) +# and ~/.config/ranger/commands.py (per user). +# They have the same syntax as this file. In fact, you can just copy this +# file to ~/.config/ranger/commands_full.py with +# `ranger --copy-config=commands_full' and make your modifications, don't +# forget to rename it to commands.py. You can also use +# `ranger --copy-config=commands' to copy a short sample commands.py that +# has everything you need to get started. +# But make sure you update your configs when you update ranger. +# +# =================================================================== +# Every class defined here which is a subclass of `Command' will be used as a +# command in ranger. Several methods are defined to interface with ranger: +# execute(): called when the command is executed. +# cancel(): called when closing the console. +# tab(tabnum): called when <TAB> is pressed. +# quick(): called after each keypress. +# +# tab() argument tabnum is 1 for <TAB> and -1 for <S-TAB> by default +# +# The return values for tab() can be either: +# None: There is no tab completion +# A string: Change the console to this string +# A list/tuple/generator: cycle through every item in it +# +# The return value for quick() can be: +# False: Nothing happens +# True: Execute the command afterwards +# +# The return value for execute() and cancel() doesn't matter. +# +# =================================================================== +# Commands have certain attributes and methods that facilitate parsing of +# the arguments: +# +# self.line: The whole line that was written in the console. +# self.args: A list of all (space-separated) arguments to the command. +# self.quantifier: If this command was mapped to the key "X" and +# the user pressed 6X, self.quantifier will be 6. +# self.arg(n): The n-th argument, or an empty string if it doesn't exist. +# self.rest(n): The n-th argument plus everything that followed. For example, +# if the command was "search foo bar a b c", rest(2) will be "bar a b c" +# self.start(n): Anything before the n-th argument. For example, if the +# command was "search foo bar a b c", start(2) will be "search foo" +# +# =================================================================== +# And this is a little reference for common ranger functions and objects: +# +# self.fm: A reference to the "fm" object which contains most information +# about ranger. +# self.fm.notify(string): Print the given string on the screen. +# self.fm.notify(string, bad=True): Print the given string in RED. +# self.fm.reload_cwd(): Reload the current working directory. +# self.fm.thisdir: The current working directory. (A File object.) +# self.fm.thisfile: The current file. (A File object too.) +# self.fm.thistab.get_selection(): A list of all selected files. +# self.fm.execute_console(string): Execute the string as a ranger command. +# self.fm.open_console(string): Open the console with the given string +# already typed in for you. +# self.fm.move(direction): Moves the cursor in the given direction, which +# can be something like down=3, up=5, right=1, left=1, to=6, ... +# +# File objects (for example self.fm.thisfile) have these useful attributes and +# methods: +# +# tfile.path: The path to the file. +# tfile.basename: The base name only. +# tfile.load_content(): Force a loading of the directories content (which +# obviously works with directories only) +# tfile.is_directory: True/False depending on whether it's a directory. +# +# For advanced commands it is unavoidable to dive a bit into the source code +# of ranger. +# =================================================================== + +from __future__ import (absolute_import, division, print_function) + +from collections import deque +import os +import re + +from ranger.api.commands import Command + + +class alias(Command): + """:alias <newcommand> <oldcommand> + + Copies the oldcommand as newcommand. + """ + + context = 'browser' + resolve_macros = False + + def execute(self): + if not self.arg(1) or not self.arg(2): + self.fm.notify('Syntax: alias <newcommand> <oldcommand>', bad=True) + return + + self.fm.commands.alias(self.arg(1), self.rest(2)) + + +class echo(Command): + """:echo <text> + + Display the text in the statusbar. + """ + + def execute(self): + self.fm.notify(self.rest(1)) + + +class cd(Command): + """:cd [-r] <path> + + The cd command changes the directory. + If the path is a file, selects that file. + The command 'cd -' is equivalent to typing ``. + Using the option "-r" will get you to the real path. + """ + + def execute(self): + if self.arg(1) == '-r': + self.shift() + destination = os.path.realpath(self.rest(1)) + if os.path.isfile(destination): + self.fm.select_file(destination) + return + else: + destination = self.rest(1) + + if not destination: + destination = '~' + + if destination == '-': + self.fm.enter_bookmark('`') + else: + self.fm.cd(destination) + + def _tab_args(self): + # dest must be rest because path could contain spaces + if self.arg(1) == '-r': + start = self.start(2) + dest = self.rest(2) + else: + start = self.start(1) + dest = self.rest(1) + + if dest: + head, tail = os.path.split(os.path.expanduser(dest)) + if head: + dest_exp = os.path.join(os.path.normpath(head), tail) + else: + dest_exp = tail + else: + dest_exp = '' + return (start, dest_exp, os.path.join(self.fm.thisdir.path, dest_exp), + dest.endswith(os.path.sep)) + + @staticmethod + def _tab_paths(dest, dest_abs, ends_with_sep): + if not dest: + try: + return next(os.walk(dest_abs))[1], dest_abs + except (OSError, StopIteration): + return [], '' + + if ends_with_sep: + try: + return [os.path.join(dest, path) for path in next(os.walk(dest_abs))[1]], '' + except (OSError, StopIteration): + return [], '' + + return None, None + + def _tab_match(self, path_user, path_file): + if self.fm.settings.cd_tab_case == 'insensitive': + path_user = path_user.lower() + path_file = path_file.lower() + elif self.fm.settings.cd_tab_case == 'smart' and path_user.islower(): + path_file = path_file.lower() + return path_file.startswith(path_user) + + def _tab_normal(self, dest, dest_abs): + dest_dir = os.path.dirname(dest) + dest_base = os.path.basename(dest) + + try: + dirnames = next(os.walk(os.path.dirname(dest_abs)))[1] + except (OSError, StopIteration): + return [], '' + + return [os.path.join(dest_dir, d) for d in dirnames if self._tab_match(dest_base, d)], '' + + def _tab_fuzzy_match(self, basepath, tokens): + """ Find directories matching tokens recursively """ + if not tokens: + tokens = [''] + paths = [basepath] + while True: + token = tokens.pop() + matches = [] + for path in paths: + try: + directories = next(os.walk(path))[1] + except (OSError, StopIteration): + continue + matches += [os.path.join(path, d) for d in directories + if self._tab_match(token, d)] + if not tokens or not matches: + return matches + paths = matches + + return None + + def _tab_fuzzy(self, dest, dest_abs): + tokens = [] + basepath = dest_abs + while True: + basepath_old = basepath + basepath, token = os.path.split(basepath) + if basepath == basepath_old: + break + if os.path.isdir(basepath_old) and not token.startswith('.'): + basepath = basepath_old + break + tokens.append(token) + + paths = self._tab_fuzzy_match(basepath, tokens) + if not os.path.isabs(dest): + paths_rel = basepath + paths = [os.path.relpath(path, paths_rel) for path in paths] + else: + paths_rel = '' + return paths, paths_rel + + def tab(self, tabnum): + from os.path import sep + + start, dest, dest_abs, ends_with_sep = self._tab_args() + + paths, paths_rel = self._tab_paths(dest, dest_abs, ends_with_sep) + if paths is None: + if self.fm.settings.cd_tab_fuzzy: + paths, paths_rel = self._tab_fuzzy(dest, dest_abs) + else: + paths, paths_rel = self._tab_normal(dest, dest_abs) + + paths.sort() + + if self.fm.settings.cd_bookmarks: + paths[0:0] = [ + os.path.relpath(v.path, paths_rel) if paths_rel else v.path + for v in self.fm.bookmarks.dct.values() for path in paths + if v.path.startswith(os.path.join(paths_rel, path) + sep) + ] + + if not paths: + return None + if len(paths) == 1: + return start + paths[0] + sep + return [start + dirname for dirname in paths] + + +class chain(Command): + """:chain <command1>; <command2>; ... + + Calls multiple commands at once, separated by semicolons. + """ + + def execute(self): + if not self.rest(1).strip(): + self.fm.notify('Syntax: chain <command1>; <command2>; ...', bad=True) + return + for command in [s.strip() for s in self.rest(1).split(";")]: + self.fm.execute_console(command) + + +class shell(Command): + escape_macros_for_shell = True + + def execute(self): + if self.arg(1) and self.arg(1)[0] == '-': + flags = self.arg(1)[1:] + command = self.rest(2) + else: + flags = '' + command = self.rest(1) + + if command: + self.fm.execute_command(command, flags=flags) + + def tab(self, tabnum): + from ranger.ext.get_executables import get_executables + if self.arg(1) and self.arg(1)[0] == '-': + command = self.rest(2) + else: + command = self.rest(1) + start = self.line[0:len(self.line) - len(command)] + + try: + position_of_last_space = command.rindex(" ") + except ValueError: + return (start + program + ' ' for program + in get_executables() if program.startswith(command)) + if position_of_last_space == len(command) - 1: + selection = self.fm.thistab.get_selection() + if len(selection) == 1: + return self.line + selection[0].shell_escaped_basename + ' ' + return self.line + '%s ' + + before_word, start_of_word = self.line.rsplit(' ', 1) + return (before_word + ' ' + file.shell_escaped_basename + for file in self.fm.thisdir.files or [] + if file.shell_escaped_basename.startswith(start_of_word)) + + +class open_with(Command): + + def execute(self): + app, flags, mode = self._get_app_flags_mode(self.rest(1)) + self.fm.execute_file( + files=[f for f in self.fm.thistab.get_selection()], + app=app, + flags=flags, + mode=mode) + + def tab(self, tabnum): + return self._tab_through_executables() + + def _get_app_flags_mode(self, string): # pylint: disable=too-many-branches,too-many-statements + """Extracts the application, flags and mode from a string. + + examples: + "mplayer f 1" => ("mplayer", "f", 1) + "atool 4" => ("atool", "", 4) + "p" => ("", "p", 0) + "" => None + """ + + app = '' + flags = '' + mode = 0 + split = string.split() + + if len(split) == 1: + part = split[0] + if self._is_app(part): + app = part + elif self._is_flags(part): + flags = part + elif self._is_mode(part): + mode = part + + elif len(split) == 2: + part0 = split[0] + part1 = split[1] + + if self._is_app(part0): + app = part0 + if self._is_flags(part1): + flags = part1 + elif self._is_mode(part1): + mode = part1 + elif self._is_flags(part0): + flags = part0 + if self._is_mode(part1): + mode = part1 + elif self._is_mode(part0): + mode = part0 + if self._is_flags(part1): + flags = part1 + + elif len(split) >= 3: + part0 = split[0] + part1 = split[1] + part2 = split[2] + + if self._is_app(part0): + app = part0 + if self._is_flags(part1): + flags = part1 + if self._is_mode(part2): + mode = part2 + elif self._is_mode(part1): + mode = part1 + if self._is_flags(part2): + flags = part2 + elif self._is_flags(part0): + flags = part0 + if self._is_mode(part1): + mode = part1 + elif self._is_mode(part0): + mode = part0 + if self._is_flags(part1): + flags = part1 + + return app, flags, int(mode) + + def _is_app(self, arg): + return not self._is_flags(arg) and not arg.isdigit() + + @staticmethod + def _is_flags(arg): + from ranger.core.runner import ALLOWED_FLAGS + return all(x in ALLOWED_FLAGS for x in arg) + + @staticmethod + def _is_mode(arg): + return all(x in '0123456789' for x in arg) + + +class set_(Command): + """:set <option name>=<python expression> + + Gives an option a new value. + + Use `:set <option>!` to toggle or cycle it, e.g. `:set flush_input!` + """ + name = 'set' # don't override the builtin set class + + def execute(self): + name = self.arg(1) + name, value, _, toggle = self.parse_setting_line_v2() + if toggle: + self.fm.toggle_option(name) + else: + self.fm.set_option_from_string(name, value) + + def tab(self, tabnum): # pylint: disable=too-many-return-statements + from ranger.gui.colorscheme import get_all_colorschemes + name, value, name_done = self.parse_setting_line() + settings = self.fm.settings + if not name: + return sorted(self.firstpart + setting for setting in settings) + if not value and not name_done: + return sorted(self.firstpart + setting for setting in settings + if setting.startswith(name)) + if not value: + value_completers = { + "colorscheme": + # Cycle through colorschemes when name, but no value is specified + lambda: sorted(self.firstpart + colorscheme for colorscheme + in get_all_colorschemes(self.fm)), + + "column_ratios": + lambda: self.firstpart + ",".join(map(str, settings[name])), + } + + def default_value_completer(): + return self.firstpart + str(settings[name]) + + return value_completers.get(name, default_value_completer)() + if bool in settings.types_of(name): + if 'true'.startswith(value.lower()): + return self.firstpart + 'True' + if 'false'.startswith(value.lower()): + return self.firstpart + 'False' + # Tab complete colorscheme values if incomplete value is present + if name == "colorscheme": + return sorted(self.firstpart + colorscheme for colorscheme + in get_all_colorschemes(self.fm) if colorscheme.startswith(value)) + return None + + +class setlocal(set_): + """:setlocal path=<regular expression> <option name>=<python expression> + + Gives an option a new value. + """ + PATH_RE_DQUOTED = re.compile(r'^setlocal\s+path="(.*?)"') + PATH_RE_SQUOTED = re.compile(r"^setlocal\s+path='(.*?)'") + PATH_RE_UNQUOTED = re.compile(r'^path=(.*?)$') + + def _re_shift(self, match): + if not match: + return None + path = os.path.expanduser(match.group(1)) + for _ in range(len(path.split())): + self.shift() + return path + + def execute(self): + path = self._re_shift(self.PATH_RE_DQUOTED.match(self.line)) + if path is None: + path = self._re_shift(self.PATH_RE_SQUOTED.match(self.line)) + if path is None: + path = self._re_shift(self.PATH_RE_UNQUOTED.match(self.arg(1))) + if path is None and self.fm.thisdir: + path = self.fm.thisdir.path + if not path: + return + + name, value, _ = self.parse_setting_line() + self.fm.set_option_from_string(name, value, localpath=path) + + +class setintag(set_): + """:setintag <tag or tags> <option name>=<option value> + + Sets an option for directories that are tagged with a specific tag. + """ + + def execute(self): + tags = self.arg(1) + self.shift() + name, value, _ = self.parse_setting_line() + self.fm.set_option_from_string(name, value, tags=tags) + + +class default_linemode(Command): + + def execute(self): + from ranger.container.fsobject import FileSystemObject + + if len(self.args) < 2: + self.fm.notify( + "Usage: default_linemode [path=<regexp> | tag=<tag(s)>] <linemode>", bad=True) + + # Extract options like "path=..." or "tag=..." from the command line + arg1 = self.arg(1) + method = "always" + argument = None + if arg1.startswith("path="): + method = "path" + argument = re.compile(arg1[5:]) + self.shift() + elif arg1.startswith("tag="): + method = "tag" + argument = arg1[4:] + self.shift() + + # Extract and validate the line mode from the command line + lmode = self.rest(1) + if lmode not in FileSystemObject.linemode_dict: + self.fm.notify( + "Invalid linemode: %s; should be %s" % ( + lmode, "/".join(FileSystemObject.linemode_dict)), + bad=True, + ) + + # Add the prepared entry to the fm.default_linemodes + entry = [method, argument, lmode] + self.fm.default_linemodes.appendleft(entry) + + # Redraw the columns + if self.fm.ui.browser: + for col in self.fm.ui.browser.columns: + col.need_redraw = True + + def tab(self, tabnum): + return (self.arg(0) + " " + lmode + for lmode in self.fm.thisfile.linemode_dict.keys() + if lmode.startswith(self.arg(1))) + + +class quit(Command): # pylint: disable=redefined-builtin + """:quit + + Closes the current tab, if there's only one tab. + Otherwise quits if there are no tasks in progress. + """ + def _exit_no_work(self): + if self.fm.loader.has_work(): + self.fm.notify('Not quitting: Tasks in progress: Use `quit!` to force quit') + else: + self.fm.exit() + + def execute(self): + if len(self.fm.tabs) >= 2: + self.fm.tab_close() + else: + self._exit_no_work() + + +class quit_bang(Command): + """:quit! + + Closes the current tab, if there's only one tab. + Otherwise force quits immediately. + """ + name = 'quit!' + allow_abbrev = False + + def execute(self): + if len(self.fm.tabs) >= 2: + self.fm.tab_close() + else: + self.fm.exit() + + +class quitall(Command): + """:quitall + + Quits if there are no tasks in progress. + """ + def _exit_no_work(self): + if self.fm.loader.has_work(): + self.fm.notify('Not quitting: Tasks in progress: Use `quitall!` to force quit') + else: + self.fm.exit() + + def execute(self): + self._exit_no_work() + + +class quitall_bang(Command): + """:quitall! + + Force quits immediately. + """ + name = 'quitall!' + allow_abbrev = False + + def execute(self): + self.fm.exit() + + +class terminal(Command): + """:terminal + + Spawns an "x-terminal-emulator" starting in the current directory. + """ + + def execute(self): + from ranger.ext.get_executables import get_term + self.fm.run(get_term(), flags='f') + + +class delete(Command): + """:delete + + Tries to delete the selection or the files passed in arguments (if any). + The arguments use a shell-like escaping. + + "Selection" is defined as all the "marked files" (by default, you + can mark files with space or v). If there are no marked files, + use the "current file" (where the cursor is) + + When attempting to delete non-empty directories or multiple + marked files, it will require a confirmation. + """ + + allow_abbrev = False + escape_macros_for_shell = True + + def execute(self): + import shlex + from functools import partial + + def is_directory_with_files(path): + return os.path.isdir(path) and not os.path.islink(path) and len(os.listdir(path)) > 0 + + if self.rest(1): + files = shlex.split(self.rest(1)) + many_files = (len(files) > 1 or is_directory_with_files(files[0])) + else: + cwd = self.fm.thisdir + tfile = self.fm.thisfile + if not cwd or not tfile: + self.fm.notify("Error: no file selected for deletion!", bad=True) + return + + # relative_path used for a user-friendly output in the confirmation. + files = [f.relative_path for f in self.fm.thistab.get_selection()] + many_files = (cwd.marked_items or is_directory_with_files(tfile.path)) + + confirm = self.fm.settings.confirm_on_delete + if confirm != 'never' and (confirm != 'multiple' or many_files): + self.fm.ui.console.ask( + "Confirm deletion of: %s (y/N)" % ', '.join(files), + partial(self._question_callback, files), + ('n', 'N', 'y', 'Y'), + ) + else: + # no need for a confirmation, just delete + self.fm.delete(files) + + def tab(self, tabnum): + return self._tab_directory_content() + + def _question_callback(self, files, answer): + if answer == 'y' or answer == 'Y': + self.fm.delete(files) + + +class jump_non(Command): + """:jump_non [-FLAGS...] + + Jumps to first non-directory if highlighted file is a directory and vice versa. + + Flags: + -r Jump in reverse order + -w Wrap around if reaching end of filelist + """ + def __init__(self, *args, **kwargs): + super(jump_non, self).__init__(*args, **kwargs) + + flags, _ = self.parse_flags() + self._flag_reverse = 'r' in flags + self._flag_wrap = 'w' in flags + + @staticmethod + def _non(fobj, is_directory): + return fobj.is_directory if not is_directory else not fobj.is_directory + + def execute(self): + tfile = self.fm.thisfile + passed = False + found_before = None + found_after = None + for fobj in self.fm.thisdir.files[::-1] if self._flag_reverse else self.fm.thisdir.files: + if fobj.path == tfile.path: + passed = True + continue + + if passed: + if self._non(fobj, tfile.is_directory): + found_after = fobj.path + break + elif not found_before and self._non(fobj, tfile.is_directory): + found_before = fobj.path + + if found_after: + self.fm.select_file(found_after) + elif self._flag_wrap and found_before: + self.fm.select_file(found_before) + + +class mark_tag(Command): + """:mark_tag [<tags>] + + Mark all tags that are tagged with either of the given tags. + When leaving out the tag argument, all tagged files are marked. + """ + do_mark = True + + def execute(self): + cwd = self.fm.thisdir + tags = self.rest(1).replace(" ", "") + if not self.fm.tags or not cwd.files: + return + for fileobj in cwd.files: + try: + tag = self.fm.tags.tags[fileobj.realpath] + except KeyError: + continue + if not tags or tag in tags: + cwd.mark_item(fileobj, val=self.do_mark) + self.fm.ui.status.need_redraw = True + self.fm.ui.need_redraw = True + + +class console(Command): + """:console <command> + + Open the console with the given command. + """ + + def execute(self): + position = None + if self.arg(1)[0:2] == '-p': + try: + position = int(self.arg(1)[2:]) + except ValueError: + pass + else: + self.shift() + self.fm.open_console(self.rest(1), position=position) + + +class load_copy_buffer(Command): + """:load_copy_buffer + + Load the copy buffer from datadir/copy_buffer + """ + copy_buffer_filename = 'copy_buffer' + + def execute(self): + import sys + from ranger.container.file import File + from os.path import exists + fname = self.fm.datapath(self.copy_buffer_filename) + unreadable = IOError if sys.version_info[0] < 3 else OSError + try: + fobj = open(fname, 'r') + except unreadable: + return self.fm.notify( + "Cannot open %s" % (fname or self.copy_buffer_filename), bad=True) + + self.fm.copy_buffer = set(File(g) + for g in fobj.read().split("\n") if exists(g)) + fobj.close() + self.fm.ui.redraw_main_column() + return None + + +class save_copy_buffer(Command): + """:save_copy_buffer + + Save the copy buffer to datadir/copy_buffer + """ + copy_buffer_filename = 'copy_buffer' + + def execute(self): + import sys + fname = None + fname = self.fm.datapath(self.copy_buffer_filename) + unwritable = IOError if sys.version_info[0] < 3 else OSError + try: + fobj = open(fname, 'w') + except unwritable: + return self.fm.notify("Cannot open %s" % + (fname or self.copy_buffer_filename), bad=True) + fobj.write("\n".join(fobj.path for fobj in self.fm.copy_buffer)) + fobj.close() + return None + + +class unmark_tag(mark_tag): + """:unmark_tag [<tags>] + + Unmark all tags that are tagged with either of the given tags. + When leaving out the tag argument, all tagged files are unmarked. + """ + do_mark = False + + +class mkdir(Command): + """:mkdir <dirname> + + Creates a directory with the name <dirname>. + """ + + def execute(self): + from os.path import join, expanduser, lexists + from os import makedirs + + dirname = join(self.fm.thisdir.path, expanduser(self.rest(1))) + if not lexists(dirname): + makedirs(dirname) + else: + self.fm.notify("file/directory exists!", bad=True) + + def tab(self, tabnum): + return self._tab_directory_content() + + +class touch(Command): + """:touch <fname> + + Creates a file with the name <fname>. + """ + + def execute(self): + from os.path import join, expanduser, lexists + + fname = join(self.fm.thisdir.path, expanduser(self.rest(1))) + if not lexists(fname): + open(fname, 'a').close() + else: + self.fm.notify("file/directory exists!", bad=True) + + def tab(self, tabnum): + return self._tab_directory_content() + + +class edit(Command): + """:edit <filename> + + Opens the specified file in vim + """ + + def execute(self): + if not self.arg(1): + self.fm.edit_file(self.fm.thisfile.path) + else: + self.fm.edit_file(self.rest(1)) + + def tab(self, tabnum): + return self._tab_directory_content() + + +class eval_(Command): + """:eval [-q] <python code> + + Evaluates the python code. + `fm' is a reference to the FM instance. + To display text, use the function `p'. + + Examples: + :eval fm + :eval len(fm.directories) + :eval p("Hello World!") + """ + name = 'eval' + resolve_macros = False + + def execute(self): + # The import is needed so eval() can access the ranger module + import ranger # NOQA pylint: disable=unused-import,unused-variable + if self.arg(1) == '-q': + code = self.rest(2) + quiet = True + else: + code = self.rest(1) + quiet = False + global cmd, fm, p, quantifier # pylint: disable=invalid-name,global-variable-undefined + fm = self.fm + cmd = self.fm.execute_console + p = fm.notify + quantifier = self.quantifier + try: + try: + result = eval(code) # pylint: disable=eval-used + except SyntaxError: + exec(code) # pylint: disable=exec-used + else: + if result and not quiet: + p(result) + except Exception as err: # pylint: disable=broad-except + fm.notify("The error `%s` was caused by evaluating the " + "following code: `%s`" % (err, code), bad=True) + + +class rename(Command): + """:rename <newname> + + Changes the name of the currently highlighted file to <newname> + """ + + def execute(self): + from ranger.container.file import File + from os import access + + new_name = self.rest(1) + + if not new_name: + return self.fm.notify('Syntax: rename <newname>', bad=True) + + if new_name == self.fm.thisfile.relative_path: + return None + + if access(new_name, os.F_OK): + return self.fm.notify("Can't rename: file already exists!", bad=True) + + if self.fm.rename(self.fm.thisfile, new_name): + file_new = File(new_name) + self.fm.bookmarks.update_path(self.fm.thisfile.path, file_new) + self.fm.tags.update_path(self.fm.thisfile.path, file_new.path) + self.fm.thisdir.pointed_obj = file_new + self.fm.thisfile = file_new + + return None + + def tab(self, tabnum): + return self._tab_directory_content() + + +class rename_append(Command): + """:rename_append [-FLAGS...] + + Opens the console with ":rename <current file>" with the cursor positioned + before the file extension. + + Flags: + -a Position before all extensions + -r Remove everything before extensions + """ + def __init__(self, *args, **kwargs): + super(rename_append, self).__init__(*args, **kwargs) + + flags, _ = self.parse_flags() + self._flag_ext_all = 'a' in flags + self._flag_remove = 'r' in flags + + def execute(self): + from ranger import MACRO_DELIMITER, MACRO_DELIMITER_ESC + + tfile = self.fm.thisfile + relpath = tfile.relative_path.replace(MACRO_DELIMITER, MACRO_DELIMITER_ESC) + basename = tfile.basename.replace(MACRO_DELIMITER, MACRO_DELIMITER_ESC) + + if basename.find('.') <= 0: + self.fm.open_console('rename ' + relpath) + return + + if self._flag_ext_all: + pos_ext = re.search(r'[^.]+', basename).end(0) + else: + pos_ext = basename.rindex('.') + pos = len(relpath) - len(basename) + pos_ext + + if self._flag_remove: + relpath = relpath[:-len(basename)] + basename[pos_ext:] + pos -= pos_ext + + self.fm.open_console('rename ' + relpath, position=(7 + pos)) + + +class chmod(Command): + """:chmod <octal number> + + Sets the permissions of the selection to the octal number. + + The octal number is between 0 and 777. The digits specify the + permissions for the user, the group and others. + + A 1 permits execution, a 2 permits writing, a 4 permits reading. + Add those numbers to combine them. So a 7 permits everything. + """ + + def execute(self): + mode_str = self.rest(1) + if not mode_str: + if not self.quantifier: + self.fm.notify("Syntax: chmod <octal number>", bad=True) + return + mode_str = str(self.quantifier) + + try: + mode = int(mode_str, 8) + if mode < 0 or mode > 0o777: + raise ValueError + except ValueError: + self.fm.notify("Need an octal number between 0 and 777!", bad=True) + return + + for fobj in self.fm.thistab.get_selection(): + try: + os.chmod(fobj.path, mode) + except OSError as ex: + self.fm.notify(ex) + + # reloading directory. maybe its better to reload the selected + # files only. + self.fm.thisdir.content_outdated = True + + +class bulkrename(Command): + """:bulkrename + + This command opens a list of selected files in an external editor. + After you edit and save the file, it will generate a shell script + which does bulk renaming according to the changes you did in the file. + + This shell script is opened in an editor for you to review. + After you close it, it will be executed. + """ + + def execute(self): # pylint: disable=too-many-locals,too-many-statements + import sys + import tempfile + from ranger.container.file import File + from ranger.ext.shell_escape import shell_escape as esc + py3 = sys.version_info[0] >= 3 + + # Create and edit the file list + filenames = [f.relative_path for f in self.fm.thistab.get_selection()] + listfile = tempfile.NamedTemporaryFile(delete=False) + listpath = listfile.name + + if py3: + listfile.write("\n".join(filenames).encode("utf-8")) + else: + listfile.write("\n".join(filenames)) + listfile.close() + self.fm.execute_file([File(listpath)], app='editor') + listfile = open(listpath, 'r') + new_filenames = listfile.read().split("\n") + listfile.close() + os.unlink(listpath) + if all(a == b for a, b in zip(filenames, new_filenames)): + self.fm.notify("No renaming to be done!") + return + + # Generate script + cmdfile = tempfile.NamedTemporaryFile() + script_lines = [] + script_lines.append("# This file will be executed when you close the editor.\n") + script_lines.append("# Please double-check everything, clear the file to abort.\n") + script_lines.extend("mv -vi -- %s %s\n" % (esc(old), esc(new)) + for old, new in zip(filenames, new_filenames) if old != new) + script_content = "".join(script_lines) + if py3: + cmdfile.write(script_content.encode("utf-8")) + else: + cmdfile.write(script_content) + cmdfile.flush() + + # Open the script and let the user review it, then check if the script + # was modified by the user + self.fm.execute_file([File(cmdfile.name)], app='editor') + cmdfile.seek(0) + script_was_edited = (script_content != cmdfile.read()) + + # Do the renaming + self.fm.run(['/bin/sh', cmdfile.name], flags='w') + cmdfile.close() + + # Retag the files, but only if the script wasn't changed during review, + # because only then we know which are the source and destination files. + if not script_was_edited: + tags_changed = False + for old, new in zip(filenames, new_filenames): + if old != new: + oldpath = self.fm.thisdir.path + '/' + old + newpath = self.fm.thisdir.path + '/' + new + if oldpath in self.fm.tags: + old_tag = self.fm.tags.tags[oldpath] + self.fm.tags.remove(oldpath) + self.fm.tags.tags[newpath] = old_tag + tags_changed = True + if tags_changed: + self.fm.tags.dump() + else: + fm.notify("files have not been retagged") + + +class relink(Command): + """:relink <newpath> + + Changes the linked path of the currently highlighted symlink to <newpath> + """ + + def execute(self): + new_path = self.rest(1) + tfile = self.fm.thisfile + + if not new_path: + return self.fm.notify('Syntax: relink <newpath>', bad=True) + + if not tfile.is_link: + return self.fm.notify('%s is not a symlink!' % tfile.relative_path, bad=True) + + if new_path == os.readlink(tfile.path): + return None + + try: + os.remove(tfile.path) + os.symlink(new_path, tfile.path) + except OSError as err: + self.fm.notify(err) + + self.fm.reset() + self.fm.thisdir.pointed_obj = tfile + self.fm.thisfile = tfile + + return None + + def tab(self, tabnum): + if not self.rest(1): + return self.line + os.readlink(self.fm.thisfile.path) + return self._tab_directory_content() + + +class help_(Command): + """:help + + Display ranger's manual page. + """ + name = 'help' + + def execute(self): + def callback(answer): + if answer == "q": + return + elif answer == "m": + self.fm.display_help() + elif answer == "c": + self.fm.dump_commands() + elif answer == "k": + self.fm.dump_keybindings() + elif answer == "s": + self.fm.dump_settings() + + self.fm.ui.console.ask( + "View [m]an page, [k]ey bindings, [c]ommands or [s]ettings? (press q to abort)", + callback, + list("mqkcs") + ) + + +class copymap(Command): + """:copymap <keys> <newkeys1> [<newkeys2>...] + + Copies a "browser" keybinding from <keys> to <newkeys> + """ + context = 'browser' + + def execute(self): + if not self.arg(1) or not self.arg(2): + return self.fm.notify("Not enough arguments", bad=True) + + for arg in self.args[2:]: + self.fm.ui.keymaps.copy(self.context, self.arg(1), arg) + + return None + + +class copypmap(copymap): + """:copypmap <keys> <newkeys1> [<newkeys2>...] + + Copies a "pager" keybinding from <keys> to <newkeys> + """ + context = 'pager' + + +class copycmap(copymap): + """:copycmap <keys> <newkeys1> [<newkeys2>...] + + Copies a "console" keybinding from <keys> to <newkeys> + """ + context = 'console' + + +class copytmap(copymap): + """:copycmap <keys> <newkeys1> [<newkeys2>...] + + Copies a "taskview" keybinding from <keys> to <newkeys> + """ + context = 'taskview' + + +class unmap(Command): + """:unmap <keys> [<keys2>, ...] + + Remove the given "browser" mappings + """ + context = 'browser' + + def execute(self): + for arg in self.args[1:]: + self.fm.ui.keymaps.unbind(self.context, arg) + + +class cunmap(unmap): + """:cunmap <keys> [<keys2>, ...] + + Remove the given "console" mappings + """ + context = 'browser' + + +class punmap(unmap): + """:punmap <keys> [<keys2>, ...] + + Remove the given "pager" mappings + """ + context = 'pager' + + +class tunmap(unmap): + """:tunmap <keys> [<keys2>, ...] + + Remove the given "taskview" mappings + """ + context = 'taskview' + + +class map_(Command): + """:map <keysequence> <command> + + Maps a command to a keysequence in the "browser" context. + + Example: + map j move down + map J move down 10 + """ + name = 'map' + context = 'browser' + resolve_macros = False + + def execute(self): + if not self.arg(1) or not self.arg(2): + self.fm.notify("Syntax: {0} <keysequence> <command>".format(self.get_name()), bad=True) + return + + self.fm.ui.keymaps.bind(self.context, self.arg(1), self.rest(2)) + + +class cmap(map_): + """:cmap <keysequence> <command> + + Maps a command to a keysequence in the "console" context. + + Example: + cmap <ESC> console_close + cmap <C-x> console_type test + """ + context = 'console' + + +class tmap(map_): + """:tmap <keysequence> <command> + + Maps a command to a keysequence in the "taskview" context. + """ + context = 'taskview' + + +class pmap(map_): + """:pmap <keysequence> <command> + + Maps a command to a keysequence in the "pager" context. + """ + context = 'pager' + + +class scout(Command): + """:scout [-FLAGS...] <pattern> + + Swiss army knife command for searching, traveling and filtering files. + + Flags: + -a Automatically open a file on unambiguous match + -e Open the selected file when pressing enter + -f Filter files that match the current search pattern + -g Interpret pattern as a glob pattern + -i Ignore the letter case of the files + -k Keep the console open when changing a directory with the command + -l Letter skipping; e.g. allow "rdme" to match the file "readme" + -m Mark the matching files after pressing enter + -M Unmark the matching files after pressing enter + -p Permanent filter: hide non-matching files after pressing enter + -r Interpret pattern as a regular expression pattern + -s Smart case; like -i unless pattern contains upper case letters + -t Apply filter and search pattern as you type + -v Inverts the match + + Multiple flags can be combined. For example, ":scout -gpt" would create + a :filter-like command using globbing. + """ + # pylint: disable=bad-whitespace + AUTO_OPEN = 'a' + OPEN_ON_ENTER = 'e' + FILTER = 'f' + SM_GLOB = 'g' + IGNORE_CASE = 'i' + KEEP_OPEN = 'k' + SM_LETTERSKIP = 'l' + MARK = 'm' + UNMARK = 'M' + PERM_FILTER = 'p' + SM_REGEX = 'r' + SMART_CASE = 's' + AS_YOU_TYPE = 't' + INVERT = 'v' + # pylint: enable=bad-whitespace + + def __init__(self, *args, **kwargs): + super(scout, self).__init__(*args, **kwargs) + self._regex = None + self.flags, self.pattern = self.parse_flags() + + def execute(self): # pylint: disable=too-many-branches + thisdir = self.fm.thisdir + flags = self.flags + pattern = self.pattern + regex = self._build_regex() + count = self._count(move=True) + + self.fm.thistab.last_search = regex + self.fm.set_search_method(order="search") + + if (self.MARK in flags or self.UNMARK in flags) and thisdir.files: + value = flags.find(self.MARK) > flags.find(self.UNMARK) + if self.FILTER in flags: + for fobj in thisdir.files: + thisdir.mark_item(fobj, value) + else: + for fobj in thisdir.files: + if regex.search(fobj.relative_path): + thisdir.mark_item(fobj, value) + + if self.PERM_FILTER in flags: + thisdir.filter = regex if pattern else None + + # clean up: + self.cancel() + + if self.OPEN_ON_ENTER in flags or \ + (self.AUTO_OPEN in flags and count == 1): + if pattern == '..': + self.fm.cd(pattern) + else: + self.fm.move(right=1) + if self.quickly_executed: + self.fm.block_input(0.5) + + if self.KEEP_OPEN in flags and thisdir != self.fm.thisdir: + # reopen the console: + if not pattern: + self.fm.open_console(self.line) + else: + self.fm.open_console(self.line[0:-len(pattern)]) + + if self.quickly_executed and thisdir != self.fm.thisdir and pattern != "..": + self.fm.block_input(0.5) + + def cancel(self): + self.fm.thisdir.temporary_filter = None + self.fm.thisdir.refilter() + + def quick(self): + asyoutype = self.AS_YOU_TYPE in self.flags + if self.FILTER in self.flags: + self.fm.thisdir.temporary_filter = self._build_regex() + if self.PERM_FILTER in self.flags and asyoutype: + self.fm.thisdir.filter = self._build_regex() + if self.FILTER in self.flags or self.PERM_FILTER in self.flags: + self.fm.thisdir.refilter() + if self._count(move=asyoutype) == 1 and self.AUTO_OPEN in self.flags: + return True + return False + + def tab(self, tabnum): + self._count(move=True, offset=tabnum) + + def _build_regex(self): + if self._regex is not None: + return self._regex + + frmat = "%s" + flags = self.flags + pattern = self.pattern + + if pattern == ".": + return re.compile("") + + # Handle carets at start and dollar signs at end separately + if pattern.startswith('^'): + pattern = pattern[1:] + frmat = "^" + frmat + if pattern.endswith('$'): + pattern = pattern[:-1] + frmat += "$" + + # Apply one of the search methods + if self.SM_REGEX in flags: + regex = pattern + elif self.SM_GLOB in flags: + regex = re.escape(pattern).replace("\\*", ".*").replace("\\?", ".") + elif self.SM_LETTERSKIP in flags: + regex = ".*".join(re.escape(c) for c in pattern) + else: + regex = re.escape(pattern) + + regex = frmat % regex + + # Invert regular expression if necessary + if self.INVERT in flags: + regex = "^(?:(?!%s).)*$" % regex + + # Compile Regular Expression + # pylint: disable=no-member + options = re.UNICODE + if self.IGNORE_CASE in flags or self.SMART_CASE in flags and \ + pattern.islower(): + options |= re.IGNORECASE + # pylint: enable=no-member + try: + self._regex = re.compile(regex, options) + except re.error: + self._regex = re.compile("") + return self._regex + + def _count(self, move=False, offset=0): + count = 0 + cwd = self.fm.thisdir + pattern = self.pattern + + if not pattern or not cwd.files: + return 0 + if pattern == '.': + return 0 + if pattern == '..': + return 1 + + deq = deque(cwd.files) + deq.rotate(-cwd.pointer - offset) + i = offset + regex = self._build_regex() + for fsobj in deq: + if regex.search(fsobj.relative_path): + count += 1 + if move and count == 1: + cwd.move(to=(cwd.pointer + i) % len(cwd.files)) + self.fm.thisfile = cwd.pointed_obj + if count > 1: + return count + i += 1 + + return count == 1 + + +class narrow(Command): + """ + :narrow + + Show only the files selected right now. If no files are selected, + disable narrowing. + """ + def execute(self): + if self.fm.thisdir.marked_items: + selection = [f.basename for f in self.fm.thistab.get_selection()] + self.fm.thisdir.narrow_filter = selection + else: + self.fm.thisdir.narrow_filter = None + self.fm.thisdir.refilter() + + +class filter_inode_type(Command): + """ + :filter_inode_type [dfl] + + Displays only the files of specified inode type. Parameters + can be combined. + + d display directories + f display files + l display links + """ + + def execute(self): + if not self.arg(1): + self.fm.thisdir.inode_type_filter = "" + else: + self.fm.thisdir.inode_type_filter = self.arg(1) + self.fm.thisdir.refilter() + + +class filter_stack(Command): + """ + :filter_stack ... + + Manages the filter stack. + + filter_stack add FILTER_TYPE ARGS... + filter_stack pop + filter_stack decompose + filter_stack rotate [N=1] + filter_stack clear + filter_stack show + """ + def execute(self): + from ranger.core.filter_stack import SIMPLE_FILTERS, FILTER_COMBINATORS + + subcommand = self.arg(1) + + if subcommand == "add": + try: + self.fm.thisdir.filter_stack.append( + SIMPLE_FILTERS[self.arg(2)](self.rest(3)) + ) + except KeyError: + FILTER_COMBINATORS[self.arg(2)](self.fm.thisdir.filter_stack) + elif subcommand == "pop": + self.fm.thisdir.filter_stack.pop() + elif subcommand == "decompose": + inner_filters = self.fm.thisdir.filter_stack.pop().decompose() + if inner_filters: + self.fm.thisdir.filter_stack.extend(inner_filters) + elif subcommand == "clear": + self.fm.thisdir.filter_stack = [] + elif subcommand == "rotate": + rotate_by = int(self.arg(2) or 1) + self.fm.thisdir.filter_stack = ( + self.fm.thisdir.filter_stack[-rotate_by:] + + self.fm.thisdir.filter_stack[:-rotate_by] + ) + elif subcommand == "show": + stack = list(map(str, self.fm.thisdir.filter_stack)) + pager = self.fm.ui.open_pager() + pager.set_source(["Filter stack: "] + stack) + pager.move(to=100, percentage=True) + return + else: + self.fm.notify( + "Unknown subcommand: {}".format(subcommand), + bad=True + ) + return + + self.fm.thisdir.refilter() + + +class grep(Command): + """:grep <string> + + Looks for a string in all marked files or directories + """ + + def execute(self): + if self.rest(1): + action = ['grep', '--line-number'] + action.extend(['-e', self.rest(1), '-r']) + action.extend(f.path for f in self.fm.thistab.get_selection()) + self.fm.execute_command(action, flags='p') + + +class flat(Command): + """ + :flat <level> + + Flattens the directory view up to the specified level. + + -1 fully flattened + 0 remove flattened view + """ + + def execute(self): + try: + level_str = self.rest(1) + level = int(level_str) + except ValueError: + level = self.quantifier + if level is None: + self.fm.notify("Syntax: flat <level>", bad=True) + return + if level < -1: + self.fm.notify("Need an integer number (-1, 0, 1, ...)", bad=True) + self.fm.thisdir.unload() + self.fm.thisdir.flat = level + self.fm.thisdir.load_content() + +# Version control commands +# -------------------------------- + + +class stage(Command): + """ + :stage + + Stage selected files for the corresponding version control system + """ + + def execute(self): + from ranger.ext.vcs import VcsError + + if self.fm.thisdir.vcs and self.fm.thisdir.vcs.track: + filelist = [f.path for f in self.fm.thistab.get_selection()] + try: + self.fm.thisdir.vcs.action_add(filelist) + except VcsError as ex: + self.fm.notify('Unable to stage files: {0}'.format(ex)) + self.fm.ui.vcsthread.process(self.fm.thisdir) + else: + self.fm.notify('Unable to stage files: Not in repository') + + +class unstage(Command): + """ + :unstage + + Unstage selected files for the corresponding version control system + """ + + def execute(self): + from ranger.ext.vcs import VcsError + + if self.fm.thisdir.vcs and self.fm.thisdir.vcs.track: + filelist = [f.path for f in self.fm.thistab.get_selection()] + try: + self.fm.thisdir.vcs.action_reset(filelist) + except VcsError as ex: + self.fm.notify('Unable to unstage files: {0}'.format(ex)) + self.fm.ui.vcsthread.process(self.fm.thisdir) + else: + self.fm.notify('Unable to unstage files: Not in repository') + +# Metadata commands +# -------------------------------- + + +class prompt_metadata(Command): + """ + :prompt_metadata <key1> [<key2> [<key3> ...]] + + Prompt the user to input metadata for multiple keys in a row. + """ + + _command_name = "meta" + _console_chain = None + + def execute(self): + prompt_metadata._console_chain = self.args[1:] + self._process_command_stack() + + def _process_command_stack(self): + if prompt_metadata._console_chain: + key = prompt_metadata._console_chain.pop() + self._fill_console(key) + else: + for col in self.fm.ui.browser.columns: + col.need_redraw = True + + def _fill_console(self, key): + metadata = self.fm.metadata.get_metadata(self.fm.thisfile.path) + if key in metadata and metadata[key]: + existing_value = metadata[key] + else: + existing_value = "" + text = "%s %s %s" % (self._command_name, key, existing_value) + self.fm.open_console(text, position=len(text)) + + +class meta(prompt_metadata): + """ + :meta <key> [<value>] + + Change metadata of a file. Deletes the key if value is empty. + """ + + def execute(self): + key = self.arg(1) + update_dict = dict() + update_dict[key] = self.rest(2) + selection = self.fm.thistab.get_selection() + for fobj in selection: + self.fm.metadata.set_metadata(fobj.path, update_dict) + self._process_command_stack() + + def tab(self, tabnum): + key = self.arg(1) + metadata = self.fm.metadata.get_metadata(self.fm.thisfile.path) + if key in metadata and metadata[key]: + return [" ".join([self.arg(0), self.arg(1), metadata[key]])] + return [self.arg(0) + " " + k for k in sorted(metadata) + if k.startswith(self.arg(1))] + + +class linemode(default_linemode): + """ + :linemode <mode> + + Change what is displayed as a filename. + + - "mode" may be any of the defined linemodes (see: ranger.core.linemode). + "normal" is mapped to "filename". + """ + + def execute(self): + mode = self.arg(1) + + if mode == "normal": + from ranger.core.linemode import DEFAULT_LINEMODE + mode = DEFAULT_LINEMODE + + if mode not in self.fm.thisfile.linemode_dict: + self.fm.notify("Unhandled linemode: `%s'" % mode, bad=True) + return + + self.fm.thisdir.set_linemode_of_children(mode) + + # Ask the browsercolumns to redraw + for col in self.fm.ui.browser.columns: + col.need_redraw = True + + +class yank(Command): + """:yank [name|dir|path] + + Copies the file's name (default), directory or path into both the primary X + selection and the clipboard. + """ + + modes = { + '': 'basename', + 'name_without_extension': 'basename_without_extension', + 'name': 'basename', + 'dir': 'dirname', + 'path': 'path', + } + + def execute(self): + import subprocess + + def clipboards(): + from ranger.ext.get_executables import get_executables + clipboard_managers = { + 'xclip': [ + ['xclip'], + ['xclip', '-selection', 'clipboard'], + ], + 'xsel': [ + ['xsel'], + ['xsel', '-b'], + ], + 'pbcopy': [ + ['pbcopy'], + ], + } + ordered_managers = ['pbcopy', 'xclip', 'xsel'] + executables = get_executables() + for manager in ordered_managers: + if manager in executables: + return clipboard_managers[manager] + return [] + + clipboard_commands = clipboards() + + mode = self.modes[self.arg(1)] + selection = self.get_selection_attr(mode) + + new_clipboard_contents = "\n".join(selection) + for command in clipboard_commands: + process = subprocess.Popen(command, universal_newlines=True, + stdin=subprocess.PIPE) + process.communicate(input=new_clipboard_contents) + + def get_selection_attr(self, attr): + return [getattr(item, attr) for item in + self.fm.thistab.get_selection()] + + def tab(self, tabnum): + return ( + self.start(1) + mode for mode + in sorted(self.modes.keys()) + if mode + ) diff --git a/.config/ranger/rc.conf b/.config/ranger/rc.conf new file mode 100644 index 0000000..97869b2 --- /dev/null +++ b/.config/ranger/rc.conf @@ -0,0 +1,747 @@ +# =================================================================== +# This file contains the default startup commands for ranger. +# To change them, it is recommended to create either /etc/ranger/rc.conf +# (system-wide) or ~/.config/ranger/rc.conf (per user) and add your custom +# commands there. +# +# If you copy this whole file there, you may want to set the environment +# variable RANGER_LOAD_DEFAULT_RC to FALSE to avoid loading it twice. +# +# The purpose of this file is mainly to define keybindings and settings. +# For running more complex python code, please create a plugin in "plugins/" or +# a command in "commands.py". +# +# Each line is a command that will be run before the user interface +# is initialized. As a result, you can not use commands which rely +# on the UI such as :delete or :mark. +# =================================================================== + +# =================================================================== +# == Options +# =================================================================== + +# Which viewmode should be used? Possible values are: +# miller: Use miller columns which show multiple levels of the hierarchy +# multipane: Midnight-commander like multipane view showing all tabs next +# to each other +set viewmode miller +#set viewmode multipane + +# How many columns are there, and what are their relative widths? +set column_ratios 1,3,4 + +# Which files should be hidden? (regular expression) +set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$ + +# Show hidden files? You can toggle this by typing 'zh' +set show_hidden false + +# Ask for a confirmation when running the "delete" command? +# Valid values are "always", "never", "multiple" (default) +# With "multiple", ranger will ask only if you delete multiple files at once. +set confirm_on_delete multiple + +# Use non-default path for file preview script? +# ranger ships with scope.sh, a script that calls external programs (see +# README.md for dependencies) to preview images, archives, etc. +#set preview_script ~/.config/ranger/scope.sh + +# Use the external preview script or display simple plain text or image previews? +set use_preview_script true + +# Automatically count files in the directory, even before entering them? +set automatically_count_files true + +# Open all images in this directory when running certain image viewers +# like feh or sxiv? You can still open selected files by marking them. +set open_all_images true + +# Be aware of version control systems and display information. +set vcs_aware false + +# State of the four backends git, hg, bzr, svn. The possible states are +# disabled, local (only show local info), enabled (show local and remote +# information). +set vcs_backend_git enabled +set vcs_backend_hg disabled +set vcs_backend_bzr disabled +set vcs_backend_svn disabled + +# Use one of the supported image preview protocols +set preview_images true + +# Set the preview image method. Supported methods: +# +# * w3m (default): +# Preview images in full color with the external command "w3mimgpreview"? +# This requires the console web browser "w3m" and a supported terminal. +# It has been successfully tested with "xterm" and "urxvt" without tmux. +# +# * iterm2: +# Preview images in full color using iTerm2 image previews +# (http://iterm2.com/images.html). This requires using iTerm2 compiled +# with image preview support. +# +# This feature relies on the dimensions of the terminal's font. By default, a +# width of 8 and height of 11 are used. To use other values, set the options +# iterm2_font_width and iterm2_font_height to the desired values. +# +# * terminology: +# Previews images in full color in the terminology terminal emulator. +# Supports a wide variety of formats, even vector graphics like svg. +# +# * urxvt: +# Preview images in full color using urxvt image backgrounds. This +# requires using urxvt compiled with pixbuf support. +# +# * urxvt-full: +# The same as urxvt but utilizing not only the preview pane but the +# whole terminal window. +# +# * kitty: +# Preview images in full color using kitty image protocol. +# Requires python PIL or pillow library. +# If ranger does not share the local filesystem with kitty +# the transfer method is changed to encode the whole image; +# while slower, this allows remote previews, +# for example during an ssh session. +# Tmux is unsupported. +set preview_images_method ueberzug + +# Delay in seconds before displaying an image with the w3m method. +# Increase it in case of experiencing display corruption. +set w3m_delay 0.03 + +# Default iTerm2 font size (see: preview_images_method: iterm2) +set iterm2_font_width 8 +set iterm2_font_height 11 + +# Use a unicode "..." character to mark cut-off filenames? +set unicode_ellipsis false + +# BIDI support - try to properly display file names in RTL languages (Hebrew, Arabic). +# Requires the python-bidi pip package +set bidi_support false + +# Show dotfiles in the bookmark preview box? +set show_hidden_bookmarks true + +# Which colorscheme to use? These colorschemes are available by default: +# default, jungle, snow, solarized +set colorscheme default + +# Preview files on the rightmost column? +# And collapse (shrink) the last column if there is nothing to preview? +set preview_files true +set preview_directories true +set collapse_preview true + +# Save the console history on exit? +set save_console_history true + +# Draw the status bar on top of the browser window (default: bottom) +set status_bar_on_top false + +# Draw a progress bar in the status bar which displays the average state of all +# currently running tasks which support progress bars? +set draw_progress_bar_in_status_bar true + +# Draw borders around columns? (separators, outline, both, or none) +# Separators are vertical lines between columns. +# Outline draws a box around all the columns. +# Both combines the two. +set draw_borders none + +# Display the directory name in tabs? +set dirname_in_tabs false + +# Enable the mouse support? +set mouse_enabled false + +# Display the file size in the main column or status bar? +set display_size_in_main_column true +set display_size_in_status_bar true + +# Display the free disk space in the status bar? +set display_free_space_in_status_bar true + +# Display files tags in all columns or only in main column? +set display_tags_in_all_columns true + +# Set a title for the window? +set update_title true + +# Set the title to "ranger" in the tmux program? +set update_tmux_title true + +# Shorten the title if it gets long? The number defines how many +# directories are displayed at once, 0 turns off this feature. +set shorten_title 3 + +# Show hostname in titlebar? +set hostname_in_titlebar true + +# Abbreviate $HOME with ~ in the titlebar (first line) of ranger? +set tilde_in_titlebar false + +# How many directory-changes or console-commands should be kept in history? +set max_history_size 20 +set max_console_history_size 50 + +# Try to keep so much space between the top/bottom border when scrolling: +set scroll_offset 8 + +# Flush the input after each key hit? (Noticeable when ranger lags) +set flushinput true + +# Padding on the right when there's no preview? +# This allows you to click into the space to run the file. +set padding_right false + +# Save bookmarks (used with mX and `X) instantly? +# This helps to synchronize bookmarks between multiple ranger +# instances but leads to *slight* performance loss. +# When false, bookmarks are saved when ranger is exited. +set autosave_bookmarks true + +# Save the "`" bookmark to disk. This can be used to switch to the last +# directory by typing "``". +set save_backtick_bookmark true + +# You can display the "real" cumulative size of directories by using the +# command :get_cumulative_size or typing "dc". The size is expensive to +# calculate and will not be updated automatically. You can choose +# to update it automatically though by turning on this option: +set autoupdate_cumulative_size false + +# Turning this on makes sense for screen readers: +set show_cursor false + +# One of: size, natural, basename, atime, ctime, mtime, type, random +set sort natural + +# Additional sorting options +set sort_reverse false +set sort_case_insensitive true +set sort_directories_first true +set sort_unicode false + +# Enable this if key combinations with the Alt Key don't work for you. +# (Especially on xterm) +set xterm_alt_key false + +# Whether to include bookmarks in cd command +set cd_bookmarks true + +# Changes case sensitivity for the cd command tab completion +set cd_tab_case sensitive + +# Use fuzzy tab completion with the "cd" command. For example, +# ":cd /u/lo/b<tab>" expands to ":cd /usr/local/bin". +set cd_tab_fuzzy true + +# Avoid previewing files larger than this size, in bytes. Use a value of 0 to +# disable this feature. +set preview_max_size 0 + +# The key hint lists up to this size have their sublists expanded. +# Otherwise the submaps are replaced with "...". +set hint_collapse_threshold 10 + +# Add the highlighted file to the path in the titlebar +set show_selection_in_titlebar true + +# The delay that ranger idly waits for user input, in milliseconds, with a +# resolution of 100ms. Lower delay reduces lag between directory updates but +# increases CPU load. +set idle_delay 2000 + +# When the metadata manager module looks for metadata, should it only look for +# a ".metadata.json" file in the current directory, or do a deep search and +# check all directories above the current one as well? +set metadata_deep_search false + +# Clear all existing filters when leaving a directory +set clear_filters_on_dir_change false + +# Disable displaying line numbers in main column. +# Possible values: false, absolute, relative. +set line_numbers relative + +# When line_numbers=relative show the absolute line number in the +# current line. +set relative_current_zero false + +# Start line numbers from 1 instead of 0 +set one_indexed false + +# Save tabs on exit +set save_tabs_on_exit false + +# Enable scroll wrapping - moving down while on the last item will wrap around to +# the top and vice versa. +set wrap_scroll false + +map gmd cd ~/eth/mad +map gm2 cd ~/eth/mech2 +map gw2 cd ~/eth/wuf2 +map gev cd ~/eth/videos +map gq cd ~/eth/quant +map gf1 cd ~/eth/fluid1 +map gij cd ~/eth/innoproj +map giz cd ~/eth/innproz +map get cd ~/eth/thermo2 +map gew cd ~/eth/werkstatt +map gvl cd vl +map gus cd รผs +map gco cd coll +map gz cd zsf + + +map glb cd ~/.local/bin +map gcf cd ~/.config +# Set the global_inode_type_filter to nothing. Possible options: d, f and l for +# directories, files and symlinks respectively. +set global_inode_type_filter + +# This setting allows to freeze the list of files to save I/O bandwidth. It +# should be 'false' during start-up, but you can toggle it by pressing F. +set freeze_files false + +# =================================================================== +# == Local Options +# =================================================================== +# You can set local options that only affect a single directory. + +# Examples: +# setlocal path=~/downloads sort mtime + +# =================================================================== +# == Command Aliases in the Console +# =================================================================== + +alias e edit +alias q quit +alias q! quit! +alias qa quitall +alias qa! quitall! +alias qall quitall +alias qall! quitall! +alias setl setlocal + +alias filter scout -prts +alias find scout -aets +alias mark scout -mr +alias unmark scout -Mr +alias search scout -rs +alias search_inc scout -rts +alias travel scout -aefklst + +# =================================================================== +# == Define keys for the browser +# =================================================================== + +# Basic +map Q quitall +map q quit +copymap q ZZ ZQ + +map R reload_cwd +map F set freeze_files! +map <C-r> reset +map <C-l> redraw_window +map <C-c> abort +map <esc> change_mode normal +map ~ set viewmode! + +map i display_file +map ? help +map W display_log +map w taskview_open +map S shell $SHELL + +map : console +map ; console +map ! console shell%space +map @ console -p6 shell %%s +map # console shell -p%space +map s console shell%space +map r chain draw_possible_programs; console open_with%%space +map f console find%space +map cd console cd%space + +map <C-p> chain console; eval fm.ui.console.history_move(-1) + +# Change the line mode +map Mf linemode filename +map Mi linemode fileinfo +map Mm linemode mtime +map Mp linemode permissions +map Ms linemode sizemtime +map Mt linemode metatitle + +# Tagging / Marking +map t tag_toggle +map ut tag_remove +map "<any> tag_toggle tag=%any +map <Space> mark_files toggle=True +map v mark_files all=True toggle=True +map uv mark_files all=True val=False +map V toggle_visual_mode +map uV toggle_visual_mode reverse=True + +# For the nostalgics: Midnight Commander bindings +map <F1> help +map <F2> rename_append +map <F3> display_file +map <F4> edit +map <F5> copy +map <F6> cut +map <F7> console mkdir%space +map <F8> console delete +map <F10> exit + +# In case you work on a keyboard with dvorak layout +map <UP> move up=1 +map <DOWN> move down=1 +map <LEFT> move left=1 +map <RIGHT> move right=1 +map <HOME> move to=0 +map <END> move to=-1 +map <PAGEDOWN> move down=1 pages=True +map <PAGEUP> move up=1 pages=True +map <CR> move right=1 +#map <DELETE> console delete +map <INSERT> console touch%space + +# VIM-like +copymap <UP> k +copymap <DOWN> j +copymap <LEFT> h +copymap <RIGHT> l +copymap <HOME> gg +copymap <END> G +copymap <PAGEDOWN> <C-F> +copymap <PAGEUP> <C-B> + +map J move down=0.5 pages=True +map K move up=0.5 pages=True +copymap J <C-D> +copymap K <C-U> + +# Jumping around +map H history_go -1 +map L history_go 1 +map ] move_parent 1 +map [ move_parent -1 +map } traverse +map { traverse_backwards +map ) jump_non + +map gh cd ~ +map gE cd ~/eth +map gee cd ~/eth/el_eng +map gmd cd ~/eth/mad +map gm2 cd ~/eth/mech2 +map gw2 cd ~/eth/wuf2 +map gev cd ~/eth/videos +map gq cd ~/eth/quant +map gf1 cd ~/eth/fluid1 +map gij cd ~/eth/innoproj +map giz cd ~/eth/innoproz +map gl cd -r . +map gL cd -r %f +#map gi eval fm.cd('/run/media/' + os.getenv('USER')) +map gM cd /mnt +map gs cd /srv +map gr cd / +map gR eval fm.cd(ranger.RANGERDIR) +map g/ cd / +map g? cd /usr/share/doc/ranger + +# External Programs +map E edit +map du shell -p du --max-depth=1 -h --apparent-size +map dU shell -p du --max-depth=1 -h --apparent-size | sort -rh +map yp yank path +map yd yank dir +map yn yank name +map y. yank name_without_extension + +# Filesystem Operations +map = chmod + +map cw console rename%space +map a rename_append +map A eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%")) +map I eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%"), position=7) + +map pp paste +map po paste overwrite=True +map pP paste append=True +map pO paste overwrite=True append=True +map pl paste_symlink relative=False +map pL paste_symlink relative=True +map phl paste_hardlink +map pht paste_hardlinked_subtree + +map dD console delete +map DD shell gio trash %s + +map dd cut +map ud uncut +map da cut mode=add +map dr cut mode=remove +map dt cut mode=toggle + +map yy copy +map uy uncut +map ya copy mode=add +map yr copy mode=remove +map yt copy mode=toggle + +# Temporary workarounds +map dgg eval fm.cut(dirarg=dict(to=0), narg=quantifier) +map dG eval fm.cut(dirarg=dict(to=-1), narg=quantifier) +map dj eval fm.cut(dirarg=dict(down=1), narg=quantifier) +map dk eval fm.cut(dirarg=dict(up=1), narg=quantifier) +map ygg eval fm.copy(dirarg=dict(to=0), narg=quantifier) +map yG eval fm.copy(dirarg=dict(to=-1), narg=quantifier) +map yj eval fm.copy(dirarg=dict(down=1), narg=quantifier) +map yk eval fm.copy(dirarg=dict(up=1), narg=quantifier) + +# Searching +map / console search%space +map n search_next +map N search_next forward=False +map ct search_next order=tag +map cs search_next order=size +map ci search_next order=mimetype +map cc search_next order=ctime +map cm search_next order=mtime +map ca search_next order=atime + +# Tabs +map <C-n> tab_new +map <C-w> tab_close +map <TAB> tab_move 1 +map <S-TAB> tab_move -1 +map <A-Right> tab_move 1 +map <A-Left> tab_move -1 +map gt tab_move 1 +map gT tab_move -1 +map gn tab_new +#map gc tab_close +map uq tab_restore +map <a-1> tab_open 1 +map <a-2> tab_open 2 +map <a-3> tab_open 3 +map <a-4> tab_open 4 +map <a-5> tab_open 5 +map <a-6> tab_open 6 +map <a-7> tab_open 7 +map <a-8> tab_open 8 +map <a-9> tab_open 9 +map <a-r> tab_shift 1 +map <a-l> tab_shift -1 + +# Sorting +map or set sort_reverse! +map oz set sort=random +map os chain set sort=size; set sort_reverse=False +map ob chain set sort=basename; set sort_reverse=False +map on chain set sort=natural; set sort_reverse=False +map om chain set sort=mtime; set sort_reverse=False +map oc chain set sort=ctime; set sort_reverse=False +map oa chain set sort=atime; set sort_reverse=False +map ot chain set sort=type; set sort_reverse=False +map oe chain set sort=extension; set sort_reverse=False + +map oS chain set sort=size; set sort_reverse=True +map oB chain set sort=basename; set sort_reverse=True +map oN chain set sort=natural; set sort_reverse=True +map oM chain set sort=mtime; set sort_reverse=True +map oC chain set sort=ctime; set sort_reverse=True +map oA chain set sort=atime; set sort_reverse=True +map oT chain set sort=type; set sort_reverse=True +map oE chain set sort=extension; set sort_reverse=True + +map dc get_cumulative_size + +# Settings +map zc set collapse_preview! +map zd set sort_directories_first! +map zh set show_hidden! +map <C-h> set show_hidden! +copymap <C-h> <backspace> +copymap <backspace> <backspace2> +map zI set flushinput! +map zi set preview_images! +map zm set mouse_enabled! +map zp set preview_files! +map zP set preview_directories! +map zs set sort_case_insensitive! +map zu set autoupdate_cumulative_size! +map zv set use_preview_script! +map zf console filter%space +copymap zf zz + +# Filter stack +map .n console filter_stack add name%space +map .m console filter_stack add mime%space +map .d filter_stack add type d +map .f filter_stack add type f +map .l filter_stack add type l +map .| filter_stack add or +map .& filter_stack add and +map .! filter_stack add not +map .r console filter_stack rotate +map .c filter_stack clear +map .* filter_stack decompose +map .p filter_stack pop +map .. filter_stack show + +# Bookmarks +map `<any> enter_bookmark %any +map '<any> enter_bookmark %any +map m<any> set_bookmark %any +map um<any> unset_bookmark %any + +map m<bg> draw_bookmarks +copymap m<bg> um<bg> `<bg> '<bg> + +# Generate all the chmod bindings with some python help: +eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +g{0} shell -f chmod g+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +o{0} shell -f chmod o+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +a{0} shell -f chmod a+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +{0} shell -f chmod u+{0} %s".format(arg)) + +eval for arg in "rwxXst": cmd("map -u{0} shell -f chmod u-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -g{0} shell -f chmod g-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -o{0} shell -f chmod o-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -a{0} shell -f chmod a-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -{0} shell -f chmod u-{0} %s".format(arg)) + +# =================================================================== +# == Define keys for the console +# =================================================================== +# Note: Unmapped keys are passed directly to the console. + +# Basic +cmap <tab> eval fm.ui.console.tab() +cmap <s-tab> eval fm.ui.console.tab(-1) +cmap <ESC> eval fm.ui.console.close() +cmap <CR> eval fm.ui.console.execute() +cmap <C-l> redraw_window + +copycmap <ESC> <C-c> +copycmap <CR> <C-j> + +# Move around +cmap <up> eval fm.ui.console.history_move(-1) +cmap <down> eval fm.ui.console.history_move(1) +cmap <left> eval fm.ui.console.move(left=1) +cmap <right> eval fm.ui.console.move(right=1) +cmap <home> eval fm.ui.console.move(right=0, absolute=True) +cmap <end> eval fm.ui.console.move(right=-1, absolute=True) +cmap <a-b> eval fm.ui.console.move_word(left=1) +cmap <a-f> eval fm.ui.console.move_word(right=1) + +copycmap <a-b> <a-left> +copycmap <a-f> <a-right> + +# Line Editing +cmap <backspace> eval fm.ui.console.delete(-1) +cmap <delete> eval fm.ui.console.delete(0) +cmap <C-w> eval fm.ui.console.delete_word() +cmap <A-d> eval fm.ui.console.delete_word(backward=False) +cmap <C-k> eval fm.ui.console.delete_rest(1) +cmap <C-u> eval fm.ui.console.delete_rest(-1) +cmap <C-y> eval fm.ui.console.paste() + +# And of course the emacs way +copycmap <ESC> <C-g> +copycmap <up> <C-p> +copycmap <down> <C-n> +copycmap <left> <C-b> +copycmap <right> <C-f> +copycmap <home> <C-a> +copycmap <end> <C-e> +copycmap <delete> <C-d> +copycmap <backspace> <C-h> + +# Note: There are multiple ways to express backspaces. <backspace> (code 263) +# and <backspace2> (code 127). To be sure, use both. +copycmap <backspace> <backspace2> + +# This special expression allows typing in numerals: +cmap <allow_quantifiers> false + +# =================================================================== +# == Pager Keybindings +# =================================================================== + +# Movement +pmap <down> pager_move down=1 +pmap <up> pager_move up=1 +pmap <left> pager_move left=4 +pmap <right> pager_move right=4 +pmap <home> pager_move to=0 +pmap <end> pager_move to=-1 +pmap <pagedown> pager_move down=1.0 pages=True +pmap <pageup> pager_move up=1.0 pages=True +pmap <C-d> pager_move down=0.5 pages=True +pmap <C-u> pager_move up=0.5 pages=True + +copypmap <UP> k <C-p> +copypmap <DOWN> j <C-n> <CR> +copypmap <LEFT> h +copypmap <RIGHT> l +copypmap <HOME> g +copypmap <END> G +copypmap <C-d> d +copypmap <C-u> u +copypmap <PAGEDOWN> n f <C-F> <Space> +copypmap <PAGEUP> p b <C-B> + +# Basic +pmap <C-l> redraw_window +pmap <ESC> pager_close +copypmap <ESC> q Q i <F3> +pmap E edit_file + +# =================================================================== +# == Taskview Keybindings +# =================================================================== + +# Movement +tmap <up> taskview_move up=1 +tmap <down> taskview_move down=1 +tmap <home> taskview_move to=0 +tmap <end> taskview_move to=-1 +tmap <pagedown> taskview_move down=1.0 pages=True +tmap <pageup> taskview_move up=1.0 pages=True +tmap <C-d> taskview_move down=0.5 pages=True +tmap <C-u> taskview_move up=0.5 pages=True + +copytmap <UP> k <C-p> +copytmap <DOWN> j <C-n> <CR> +copytmap <HOME> g +copytmap <END> G +copytmap <C-u> u +copytmap <PAGEDOWN> n f <C-F> <Space> +copytmap <PAGEUP> p b <C-B> + +# Changing priority and deleting tasks +tmap J eval -q fm.ui.taskview.task_move(-1) +tmap K eval -q fm.ui.taskview.task_move(0) +tmap dd eval -q fm.ui.taskview.task_remove() +tmap <pagedown> eval -q fm.ui.taskview.task_move(-1) +tmap <pageup> eval -q fm.ui.taskview.task_move(0) +tmap <delete> eval -q fm.ui.taskview.task_remove() + +# Basic +tmap <C-l> redraw_window +tmap <ESC> taskview_close +copytmap <ESC> q Q w <C-c> diff --git a/.config/ranger/rifle.conf b/.config/ranger/rifle.conf new file mode 100644 index 0000000..bdf5db2 --- /dev/null +++ b/.config/ranger/rifle.conf @@ -0,0 +1,256 @@ +# vim: ft=cfg +# +# This is the configuration file of "rifle", ranger's file executor/opener. +# Each line consists of conditions and a command. For each line the conditions +# are checked and if they are met, the respective command is run. +# +# Syntax: +# <condition1> , <condition2> , ... = command +# +# The command can contain these environment variables: +# $1-$9 | The n-th selected file +# $@ | All selected files +# +# If you use the special command "ask", rifle will ask you what program to run. +# +# Prefixing a condition with "!" will negate its result. +# These conditions are currently supported: +# match <regexp> | The regexp matches $1 +# ext <regexp> | The regexp matches the extension of $1 +# mime <regexp> | The regexp matches the mime type of $1 +# name <regexp> | The regexp matches the basename of $1 +# path <regexp> | The regexp matches the absolute path of $1 +# has <program> | The program is installed (i.e. located in $PATH) +# env <variable> | The environment variable "variable" is non-empty +# file | $1 is a file +# directory | $1 is a directory +# number <n> | change the number of this command to n +# terminal | stdin, stderr and stdout are connected to a terminal +# X | $DISPLAY is not empty (i.e. Xorg runs) +# +# There are also pseudo-conditions which have a "side effect": +# flag <flags> | Change how the program is run. See below. +# label <label> | Assign a label or name to the command so it can +# | be started with :open_with <label> in ranger +# | or `rifle -p <label>` in the standalone executable. +# else | Always true. +# +# Flags are single characters which slightly transform the command: +# f | Fork the program, make it run in the background. +# | New command = setsid $command >& /dev/null & +# r | Execute the command with root permissions +# | New command = sudo $command +# t | Run the program in a new terminal. If $TERMCMD is not defined, +# | rifle will attempt to extract it from $TERM. +# | New command = $TERMCMD -e $command +# Note: The "New command" serves only as an illustration, the exact +# implementation may differ. +# Note: When using rifle in ranger, there is an additional flag "c" for +# only running the current file even if you have marked multiple files. + +#------------------------------------------- +# Websites +#------------------------------------------- +# Rarely installed browsers get higher priority; It is assumed that if you +# install a rare browser, you probably use it. Firefox/konqueror/w3m on the +# other hand are often only installed as fallback browsers. +ext x?html?, has surf, X, flag f = surf -- file://"$1" +ext x?html?, has vimprobable, X, flag f = vimprobable -- "$@" +ext x?html?, has vimprobable2, X, flag f = vimprobable2 -- "$@" +ext x?html?, has qutebrowser, X, flag f = qutebrowser -- "$@" +ext x?html?, has dwb, X, flag f = dwb -- "$@" +ext x?html?, has jumanji, X, flag f = jumanji -- "$@" +ext x?html?, has luakit, X, flag f = luakit -- "$@" +ext x?html?, has uzbl, X, flag f = uzbl -- "$@" +ext x?html?, has uzbl-tabbed, X, flag f = uzbl-tabbed -- "$@" +ext x?html?, has uzbl-browser, X, flag f = uzbl-browser -- "$@" +ext x?html?, has uzbl-core, X, flag f = uzbl-core -- "$@" +ext x?html?, has midori, X, flag f = midori -- "$@" +ext x?html?, has chromium-browser, X, flag f = chromium-browser -- "$@" +ext x?html?, has chromium, X, flag f = chromium -- "$@" +ext x?html?, has google-chrome, X, flag f = google-chrome -- "$@" +ext x?html?, has opera, X, flag f = opera -- "$@" +ext x?html?, has firefox, X, flag f = firefox -- "$@" +ext x?html?, has seamonkey, X, flag f = seamonkey -- "$@" +ext x?html?, has iceweasel, X, flag f = iceweasel -- "$@" +ext x?html?, has epiphany, X, flag f = epiphany -- "$@" +ext x?html?, has konqueror, X, flag f = konqueror -- "$@" +ext x?html?, has elinks, terminal = elinks "$@" +ext x?html?, has links2, terminal = links2 "$@" +ext x?html?, has links, terminal = links "$@" +ext x?html?, has lynx, terminal = lynx -- "$@" +ext x?html?, has w3m, terminal = w3m "$@" + +#------------------------------------------- +# Misc +#------------------------------------------- +# Define the "editor" for text files as first action +mime ^text, label editor = ${VISUAL:-$EDITOR} -- "$@" +mime ^text, label pager = "$PAGER" -- "$@" +!mime ^text, label editor, ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" +!mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@" + +ext 1 = man "$1" +ext s[wmf]c, has zsnes, X = zsnes "$1" +ext s[wmf]c, has snes9x-gtk,X = snes9x-gtk "$1" +ext nes, has fceux, X = fceux "$1" +ext exe = wine "$1" +name ^[mM]akefile$ = make + +#-------------------------------------------- +# Code +#------------------------------------------- +ext py = python -- "$1" +ext pl = perl -- "$1" +ext rb = ruby -- "$1" +ext js = node -- "$1" +ext sh = sh -- "$1" +ext php = php -- "$1" + +#-------------------------------------------- +# Audio without X +#------------------------------------------- +mime ^audio|ogg$, terminal, has mpv = mpv -- "$@" +mime ^audio|ogg$, terminal, has mplayer2 = mplayer2 -- "$@" +mime ^audio|ogg$, terminal, has mplayer = mplayer -- "$@" +ext midi?, terminal, has wildmidi = wildmidi -- "$@" + +#-------------------------------------------- +# Video/Audio with a GUI +#------------------------------------------- +mime ^video|audio, has gmplayer, X, flag f = gmplayer -- "$@" +mime ^video|audio, has smplayer, X, flag f = smplayer "$@" +mime ^video, has mpv, X, flag f = mpv -- "$@" +mime ^video, has mpv, X, flag f = mpv --fs -- "$@" +mime ^video, has mplayer2, X, flag f = mplayer2 -- "$@" +mime ^video, has mplayer2, X, flag f = mplayer2 -fs -- "$@" +mime ^video, has mplayer, X, flag f = mplayer -- "$@" +mime ^video, has mplayer, X, flag f = mplayer -fs -- "$@" +mime ^video|audio, has vlc, X, flag f = vlc -- "$@" +mime ^video|audio, has totem, X, flag f = totem -- "$@" +mime ^video|audio, has totem, X, flag f = totem --fullscreen -- "$@" + +#-------------------------------------------- +# Video without X: +#------------------------------------------- +mime ^video, terminal, !X, has mpv = mpv -- "$@" +mime ^video, terminal, !X, has mplayer2 = mplayer2 -- "$@" +mime ^video, terminal, !X, has mplayer = mplayer -- "$@" + +#------------------------------------------- +# Documents +#------------------------------------------- +ext pdf, has llpp, X, flag f = llpp "$@" +ext pdf, has zathura, X, flag f = zathura -- "$@" +ext pdf, has mupdf, X, flag f = mupdf "$@" +ext pdf, has mupdf-x11,X, flag f = mupdf-x11 "$@" +ext pdf, has apvlv, X, flag f = apvlv -- "$@" +ext pdf, has xpdf, X, flag f = xpdf -- "$@" +ext pdf, has evince, X, flag f = evince -- "$@" +ext pdf, has atril, X, flag f = atril -- "$@" +ext pdf, has okular, X, flag f = okular -- "$@" +ext pdf, has epdfview, X, flag f = epdfview -- "$@" +ext pdf, has qpdfview, X, flag f = qpdfview "$@" +ext pdf, has open, X, flag f = open "$@" + +ext docx?, has catdoc, terminal = catdoc -- "$@" | "$PAGER" + +ext sxc|xlsx?|xlt|xlw|gnm|gnumeric, has gnumeric, X, flag f = gnumeric -- "$@" +ext sxc|xlsx?|xlt|xlw|gnm|gnumeric, has kspread, X, flag f = kspread -- "$@" +ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has libreoffice, X, flag f = libreoffice "$@" +ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has soffice, X, flag f = soffice "$@" +ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has ooffice, X, flag f = ooffice "$@" + +ext djvu, has zathura,X, flag f = zathura -- "$@" +ext djvu, has evince, X, flag f = evince -- "$@" +ext djvu, has atril, X, flag f = atril -- "$@" +ext djvu, has djview, X, flag f = djview -- "$@" + +ext epub, has zathura, X, flag f = zathura -- "$@" +ext mobi, has ebook-viewer, X, flag f = ebook-viewer -- "$@" + +#------------------------------------------- +# Image Viewing: +#------------------------------------------- +mime ^image/svg, has inkscape, X, flag f = inkscape -- "$@" +mime ^image/svg, has display, X, flag f = display -- "$@" + +mime ^image, has pqiv, X, flag f = pqiv -- "$@" +mime ^image, has sxiv, X, flag f = sxiv -- "$@" +mime ^image, has feh, X, flag f = feh -- "$@" +mime ^image, has mirage, X, flag f = mirage -- "$@" +mime ^image, has ristretto, X, flag f = ristretto "$@" +mime ^image, has eog, X, flag f = eog -- "$@" +mime ^image, has eom, X, flag f = eom -- "$@" +mime ^image, has nomacs, X, flag f = nomacs -- "$@" +mime ^image, has geeqie, X, flag f = geeqie -- "$@" +mime ^image, has gwenview, X, flag f = gwenview -- "$@" +mime ^image, has gimp, X, flag f = gimp -- "$@" +ext xcf, X, flag f = gimp -- "$@" + +#------------------------------------------- +# Archives +#------------------------------------------- + +# avoid password prompt by providing empty password +ext 7z, has 7z = 7z -p l "$@" | "$PAGER" +# This requires atool +ext ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --list --each -- "$@" | "$PAGER" +ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --list --each -- "$@" | "$PAGER" +ext 7z|ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --extract --each -- "$@" +ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --extract --each -- "$@" + +# Listing and extracting archives without atool: +ext tar|gz|bz2|xz, has tar = tar vvtf "$1" | "$PAGER" +ext tar|gz|bz2|xz, has tar = for file in "$@"; do tar vvxf "$file"; done +ext bz2, has bzip2 = for file in "$@"; do bzip2 -dk "$file"; done +ext zip, has unzip = unzip -l "$1" | less +ext zip, has unzip = for file in "$@"; do unzip -d "${file%.*}" "$file"; done +ext ace, has unace = unace l "$1" | less +ext ace, has unace = for file in "$@"; do unace e "$file"; done +ext rar, has unrar = unrar l "$1" | less +ext rar, has unrar = for file in "$@"; do unrar x "$file"; done + +#------------------------------------------- +# Flag t fallback terminals +#------------------------------------------- +# Rarely installed terminal emulators get higher priority; It is assumed that +# if you install a rare terminal emulator, you probably use it. +# gnome-terminal/konsole/xterm on the other hand are often installed as part of +# a desktop environment or as fallback terminal emulators. +mime ^ranger/x-terminal-emulator, has terminology = terminology -e "$@" +mime ^ranger/x-terminal-emulator, has kitty = kitty -- "$@" +mime ^ranger/x-terminal-emulator, has alacritty = alacritty -e "$@" +mime ^ranger/x-terminal-emulator, has sakura = sakura -e "$@" +mime ^ranger/x-terminal-emulator, has lilyterm = lilyterm -e "$@" +#mime ^ranger/x-terminal-emulator, has cool-retro-term = cool-retro-term -e "$@" +mime ^ranger/x-terminal-emulator, has termite = termite -x '"$@"' +#mime ^ranger/x-terminal-emulator, has yakuake = yakuake -e "$@" +mime ^ranger/x-terminal-emulator, has guake = guake -ne "$@" +mime ^ranger/x-terminal-emulator, has tilda = tilda -c "$@" +mime ^ranger/x-terminal-emulator, has st = st -e "$@" +mime ^ranger/x-terminal-emulator, has terminator = terminator -x "$@" +mime ^ranger/x-terminal-emulator, has urxvt = urxvt -e "$@" +mime ^ranger/x-terminal-emulator, has pantheon-terminal = pantheon-terminal -e "$@" +mime ^ranger/x-terminal-emulator, has lxterminal = lxterminal -e "$@" +mime ^ranger/x-terminal-emulator, has mate-terminal = mate-terminal -x "$@" +mime ^ranger/x-terminal-emulator, has xfce4-terminal = xfce4-terminal -x "$@" +mime ^ranger/x-terminal-emulator, has konsole = konsole -e "$@" +mime ^ranger/x-terminal-emulator, has gnome-terminal = gnome-terminal -- "$@" +mime ^ranger/x-terminal-emulator, has xterm = xterm -e "$@" + +#------------------------------------------- +# Misc +#------------------------------------------- +label wallpaper, number 11, mime ^image, has feh, X = feh --bg-scale "$1" +label wallpaper, number 12, mime ^image, has feh, X = feh --bg-tile "$1" +label wallpaper, number 13, mime ^image, has feh, X = feh --bg-center "$1" +label wallpaper, number 14, mime ^image, has feh, X = feh --bg-fill "$1" + +# Define the editor for non-text files + pager as last action + !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ask +label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" +label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@" + +# The very last action, so that it's never triggered accidentally, is to execute a program: +mime application/x-executable = "$1" diff --git a/.config/ranger/scope.sh b/.config/ranger/scope.sh new file mode 100755 index 0000000..aaed966 --- /dev/null +++ b/.config/ranger/scope.sh @@ -0,0 +1,354 @@ +#!/usr/bin/env bash + +set -o noclobber -o noglob -o nounset -o pipefail +IFS=$'\n' + +## If the option `use_preview_script` is set to `true`, +## then this script will be called and its output will be displayed in ranger. +## ANSI color codes are supported. +## STDIN is disabled, so interactive scripts won't work properly + +## This script is considered a configuration file and must be updated manually. +## It will be left untouched if you upgrade ranger. + +## Because of some automated testing we do on the script #'s for comments need +## to be doubled up. Code that is commented out, because it's an alternative for +## example, gets only one #. + +## Meanings of exit codes: +## code | meaning | action of ranger +## -----+------------+------------------------------------------- +## 0 | success | Display stdout as preview +## 1 | no preview | Display no preview at all +## 2 | plain text | Display the plain content of the file +## 3 | fix width | Don't reload when width changes +## 4 | fix height | Don't reload when height changes +## 5 | fix both | Don't ever reload +## 6 | image | Display the image `$IMAGE_CACHE_PATH` points to as an image preview +## 7 | image | Display the file directly as an image + +## Script arguments +FILE_PATH="${1}" # Full path of the highlighted file +PV_WIDTH="${2}" # Width of the preview pane (number of fitting characters) +## shellcheck disable=SC2034 # PV_HEIGHT is provided for convenience and unused +PV_HEIGHT="${3}" # Height of the preview pane (number of fitting characters) +IMAGE_CACHE_PATH="${4}" # Full path that should be used to cache image preview +PV_IMAGE_ENABLED="${5}" # 'True' if image previews are enabled, 'False' otherwise. + +FILE_EXTENSION="${FILE_PATH##*.}" +FILE_EXTENSION_LOWER="$(printf "%s" "${FILE_EXTENSION}" | tr '[:upper:]' '[:lower:]')" + +## Settings +HIGHLIGHT_SIZE_MAX=262143 # 256KiB +HIGHLIGHT_TABWIDTH=${HIGHLIGHT_TABWIDTH:-8} +HIGHLIGHT_STYLE=${HIGHLIGHT_STYLE:-pablo} +HIGHLIGHT_OPTIONS="--replace-tabs=${HIGHLIGHT_TABWIDTH} --style=${HIGHLIGHT_STYLE} ${HIGHLIGHT_OPTIONS:-}" +PYGMENTIZE_STYLE=${PYGMENTIZE_STYLE:-autumn} +OPENSCAD_IMGSIZE=${RNGR_OPENSCAD_IMGSIZE:-1000,1000} +OPENSCAD_COLORSCHEME=${RNGR_OPENSCAD_COLORSCHEME:-Tomorrow Night} + +handle_extension() { + case "${FILE_EXTENSION_LOWER}" in + ## Archive + a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\ + rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip) + atool --list -- "${FILE_PATH}" && exit 5 + bsdtar --list --file "${FILE_PATH}" && exit 5 + exit 1;; + rar) + ## Avoid password prompt by providing empty password + unrar lt -p- -- "${FILE_PATH}" && exit 5 + exit 1;; + 7z) + ## Avoid password prompt by providing empty password + 7z l -p -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## PDF + pdf) + ## Preview as text conversion + pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - | \ + fmt -w "${PV_WIDTH}" && exit 5 + mutool draw -F txt -i -- "${FILE_PATH}" 1-10 | \ + fmt -w "${PV_WIDTH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + ## BitTorrent + torrent) + transmission-show -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## OpenDocument + odt|ods|odp|sxw) + ## Preview as text conversion + odt2txt "${FILE_PATH}" && exit 5 + ## Preview as markdown conversion + pandoc -s -t markdown -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## XLSX + xlsx) + ## Preview as csv conversion + ## Uses: https://github.com/dilshod/xlsx2csv + xlsx2csv -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## HTML + htm|html|xhtml) + ## Preview as text conversion + w3m -dump "${FILE_PATH}" && exit 5 + lynx -dump -- "${FILE_PATH}" && exit 5 + elinks -dump "${FILE_PATH}" && exit 5 + pandoc -s -t markdown -- "${FILE_PATH}" && exit 5 + ;; + + ## JSON + json) + jq --color-output . "${FILE_PATH}" && exit 5 + python -m json.tool -- "${FILE_PATH}" && exit 5 + ;; + + ## Direct Stream Digital/Transfer (DSDIFF) and wavpack aren't detected + ## by file(1). + dff|dsf|wv|wvc) + mediainfo "${FILE_PATH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + ;; # Continue with next handler on failure + esac +} + +handle_image() { + ## Skze of the preview if there are multiple options or it has to be + ## rendered from vector graphics. If the conversion program allows + ## specifying only one dimension while keeping the aspect ratio, the width + ## will be used. + local DEFAULT_SIZE="1920x1080" + + local mimetype="${1}" + case "${mimetype}" in + ## SVG + # image/svg+xml|image/svg) + # convert -- "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6 + # exit 1;; + + ## DjVu + image/vnd.djvu) + ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \ + - "${IMAGE_CACHE_PATH}" < "${FILE_PATH}" \ + && exit 6 || exit 1;; + + ## Image + image/*) + local orientation + orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FILE_PATH}" )" + ## If orientation data is present and the image actually + ## needs rotating ("1" means no rotation)... + if [[ -n "$orientation" && "$orientation" != 1 ]]; then + ## ...auto-rotate the image according to the EXIF data. + convert -- "${FILE_PATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6 + fi + + ## `w3mimgdisplay` will be called for all images (unless overriden + ## as above), but might fail for unsupported types. + exit 7;; + + ## Video + video/*) + ## Thumbnail + ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6 + exit 1;; + + ##Audio + audio/*) + ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6 + exit 1;; + ## PDF + application/pdf) + pdftoppm -f 1 -l 1 \ + -scale-to-x "${DEFAULT_SIZE%x*}" \ + -scale-to-y -1 \ + -singlefile \ + -jpeg -tiffcompression jpeg \ + -- "${FILE_PATH}" "${IMAGE_CACHE_PATH%.*}" \ + && exit 6 || exit 1;; + + + ## ePub, MOBI, FB2 (using Calibre) + application/epub+zip|application/x-mobipocket-ebook|\ + application/x-fictionbook+xml|application/octet-stream) + # ePub (using https://github.com/marianosimone/epub-thumbnailer) + epub-thumbnailer "${FILE_PATH}" "${IMAGE_CACHE_PATH}" \ + "${DEFAULT_SIZE%x*}" && exit 6 + ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FILE_PATH}" \ + >/dev/null && exit 6 + exit 1;; + + ## Font + application/font*|application/*opentype) + preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png" + if fontimage -o "${preview_png}" \ + --pixelsize "120" \ + --fontname \ + --pixelsize "80" \ + --text " ABCDEFGHIJKLMNOPQRSTUVWXYZ " \ + --text " abcdefghijklmnopqrstuvwxyz " \ + --text " 0123456789.:,;(*!?') ff fl fi ffi ffl " \ + --text " The quick brown fox jumps over the lazy dog. " \ + "${FILE_PATH}"; + then + convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \ + && rm "${preview_png}" \ + && exit 6 + else + exit 1 + fi + ;; + + ## Preview archives using the first image inside. + ## (Very useful for comic book collections for example.) + # application/zip|application/x-rar|application/x-7z-compressed|\ + # application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar) + # local fn=""; local fe="" + # local zip=""; local rar=""; local tar=""; local bsd="" + # case "${mimetype}" in + # application/zip) zip=1 ;; + # application/x-rar) rar=1 ;; + # application/x-7z-compressed) ;; + # *) tar=1 ;; + # esac + # { [ "$tar" ] && fn=$(tar --list --file "${FILE_PATH}"); } || \ + # { fn=$(bsdtar --list --file "${FILE_PATH}") && bsd=1 && tar=""; } || \ + # { [ "$rar" ] && fn=$(unrar lb -p- -- "${FILE_PATH}"); } || \ + # { [ "$zip" ] && fn=$(zipinfo -1 -- "${FILE_PATH}"); } || return + # + # fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \ + # [ print(l, end='') for l in sys.stdin if \ + # (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\ + # sort -V | head -n 1) + # [ "$fn" = "" ] && return + # [ "$bsd" ] && fn=$(printf '%b' "$fn") + # + # [ "$tar" ] && tar --extract --to-stdout \ + # --file "${FILE_PATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6 + # fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g') + # [ "$bsd" ] && bsdtar --extract --to-stdout \ + # --file "${FILE_PATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}" + # [ "$rar" ] && unrar p -p- -inul -- "${FILE_PATH}" "$fn" > \ + # "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$zip" ] && unzip -pP "" -- "${FILE_PATH}" "$fe" > \ + # "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}" + # ;; + esac + + # openscad_image() { + # TMPPNG="$(mktemp -t XXXXXX.png)" + # openscad --colorscheme="${OPENSCAD_COLORSCHEME}" \ + # --imgsize="${OPENSCAD_IMGSIZE/x/,}" \ + # -o "${TMPPNG}" "${1}" + # mv "${TMPPNG}" "${IMAGE_CACHE_PATH}" + # } + + # case "${FILE_EXTENSION_LOWER}" in + # ## 3D models + # ## OpenSCAD only supports png image output, and ${IMAGE_CACHE_PATH} + # ## is hardcoded as jpeg. So we make a tempfile.png and just + # ## move/rename it to jpg. This works because image libraries are + # ## smart enough to handle it. + # csg|scad) + # openscad_image "${FILE_PATH}" && exit 6 + # ;; + # 3mf|amf|dxf|off|stl) + # openscad_image <(echo "import(\"${FILE_PATH}\");") && exit 6 + # ;; + # esac +} + +handle_mime() { + local mimetype="${1}" + case "${mimetype}" in + ## RTF and DOC + text/rtf|*msword) + ## Preview as text conversion + ## note: catdoc does not always work for .doc files + ## catdoc: http://www.wagner.pp.ru/~vitus/software/catdoc/ + catdoc -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## DOCX, ePub, FB2 (using markdown) + ## You might want to remove "|epub" and/or "|fb2" below if you have + ## uncommented other methods to preview those formats + *wordprocessingml.document|*/epub+zip|*/x-fictionbook+xml) + ## Preview as markdown conversion + pandoc -s -t markdown -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## XLS + *ms-excel) + ## Preview as csv conversion + ## xls2csv comes with catdoc: + ## http://www.wagner.pp.ru/~vitus/software/catdoc/ + xls2csv -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## Text + text/* | */xml) + ## Syntax highlight + if [[ "$( stat --printf='%s' -- "${FILE_PATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then + exit 2 + fi + if [[ "$( tput colors )" -ge 256 ]]; then + local pygmentize_format='terminal256' + local highlight_format='xterm256' + else + local pygmentize_format='terminal' + local highlight_format='ansi' + fi + env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \ + --out-format="${highlight_format}" \ + --force -- "${FILE_PATH}" && exit 5 + env COLORTERM=8bit bat --color=always --style="plain" \ + -- "${FILE_PATH}" && exit 5 + pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\ + -- "${FILE_PATH}" && exit 5 + exit 2;; + + ## DjVu + image/vnd.djvu) + ## Preview as text conversion (requires djvulibre) + djvutxt "${FILE_PATH}" | fmt -w "${PV_WIDTH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + ## Image + image/*) + ## Preview as text conversion + # img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + ## Video and audio + video/* | audio/*) + mediainfo "${FILE_PATH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + esac +} + +handle_fallback() { + echo '----- File Type Classification -----' && file --dereference --brief -- "${FILE_PATH}" && exit 5 + exit 1 +} + + +MIMETYPE="$( file --dereference --brief --mime-type -- "${FILE_PATH}" )" +if [[ "${PV_IMAGE_ENABLED}" == 'True' ]]; then + handle_image "${MIMETYPE}" +fi +handle_extension +handle_mime "${MIMETYPE}" +handle_fallback + +exit 1 diff --git a/.config/shortcutrc b/.config/shortcutrc new file mode 100644 index 0000000..bb21b10 --- /dev/null +++ b/.config/shortcutrc @@ -0,0 +1,26 @@ +# vim: filetype=sh +alias h="cd ~/ && ls -a" \ +d="cd ~/Documents && ls -a" \ +D="cd ~/Downloads && ls -a" \ +m="cd ~/Music && ls -a" \ +pp="cd ~/Pictures && ls -a" \ +vv="cd ~/Videos && ls -a" \ +cf="cd ${XDG_CONFIG_HOME:-$HOME/.config} && ls -a" \ +cac="cd ${XDG_CACHE_HOME:-$HOME/.cache} && ls -a" \ +sc="cd ~/.local/bin && ls -a" \ +mn="cd /mnt && ls -a" \ +bf="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/files" \ +bd="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/directories" \ +bw="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/bookmarks" \ +cfa="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/aliasrc" \ +cfz="$EDITOR $ZDOTDIR/.zshrc" \ +cfv="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim" \ +cfm="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/mutt/muttrc" \ +cfx="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/Xresources" \ +cfu="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls" \ +cfn="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/config" \ +cfmb="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/bindings" \ +cfmc="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/config" \ +cfk="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/sxhkd/sxhkdrc" \ +cfi="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/i3/config" \ +cfb="$EDITOR ${XDG_CONFIG_HOME:-$HOME/.config}/i3blocks/config" \ diff --git a/.config/sxiv/exec/key-handler b/.config/sxiv/exec/key-handler new file mode 100755 index 0000000..dc68313 --- /dev/null +++ b/.config/sxiv/exec/key-handler @@ -0,0 +1,34 @@ +#!/usr/bin/env sh +while read file +do + case "$1" in + "w") setbg "$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 -n "$file" | xclip -selection clipboard && + notify-send "$file copied to clipboard" & ;; + "Y") + readlink -f "$file" | 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 && gimp "$file" & ;; + esac +done diff --git a/.config/wall.png b/.config/wall.png new file mode 100644 index 0000000..fd66c81 Binary files /dev/null and b/.config/wall.png differ diff --git a/.config/zathura/zathurarc b/.config/zathura/zathurarc new file mode 120000 index 0000000..1ca6572 --- /dev/null +++ b/.config/zathura/zathurarc @@ -0,0 +1 @@ +/home/alex/.cache/wal/zathurarc \ No newline at end of file diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc new file mode 100644 index 0000000..4057c07 --- /dev/null +++ b/.config/zsh/.zshrc @@ -0,0 +1,113 @@ +# Luke's config for the Zoomer Shell + +# Enable colors and change prompt: +autoload -U colors && colors # Load colors +export LC_ALL="en_US.UTF-8" + +PROMPT="%{%B%}%(?.%{$fg[grey]%}โ—†.%{$fg[red]%}โœ– %?)%{$fg[blue]%} %1~ %(?.%{$fg[grey]%}โฏ%{$fg[blue]%}โฏ%{$fg[white]%}โฏ.%{$fg[red]%}โฏโฏโฏ) %{%f%b%}" +#PS1="%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[magenta]%}%~%{$fg[red]%}]%{$reset_color%}$%b " +setopt autocd # Automatically cd into typed directory. +stty stop undef # Disable ctrl-s to freeze terminal. + +# History in cache directory: +HISTSIZE=10000 +SAVEHIST=10000 +HISTFILE=~/.cache/zsh/history + +# Load aliases and shortcuts if existent. +[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shortcutrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/shortcutrc" +[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/aliasrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/aliasrc" +[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/zshnameddirrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/zshnameddirrc" + +# Basic auto/tab complete: +autoload -U compinit +zstyle ':completion:*' menu select +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 -M menuselect 'h' vi-backward-char +bindkey -M menuselect 'k' vi-up-line-or-history +bindkey -M menuselect 'l' vi-forward-char +bindkey -M menuselect 'j' vi-down-line-or-history +bindkey -v '^?' backward-delete-char + +#bash-like reverse i-search +#bindkey '^R' history-incremental-pattern-search-backward + +# Change cursor shape for different vi modes. +function zle-keymap-select { + if [[ ${KEYMAP} == vicmd ]] || + [[ $1 = 'block' ]]; then + echo -ne '\e[1 q' + elif [[ ${KEYMAP} == main ]] || + [[ ${KEYMAP} == viins ]] || + [[ ${KEYMAP} = '' ]] || + [[ $1 = 'beam' ]]; then + echo -ne '\e[5 q' + fi +} +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. + +# Use lf to switch directories and bind it to ctrl-o +lfcd () { + tmp="$(mktemp)" + lf -last-dir-path="$tmp" "$@" + if [ -f "$tmp" ]; then + dir="$(cat "$tmp")" + rm -f "$tmp" >/dev/null + [ -d "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir" + fi +} + +#Same as Luke does with lf but with ranger +rangercd (){ + tmp="$(mktemp)" + ranger --choosedir="$tmp" "$@" + if [ -f "$tmp" ]; then + dir="$(cat "$tmp")" + rm -f "$tmp" >/dev/null + [ -d "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir" + fi +} +bindkey -s '^o' 'rangercd\n' + +bindkey -s '^a' 'bc -l\n' + +bindkey -s '^f' 'cd "$(dirname "$(fzf)")"\n' + +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 + + +#Fuzzy finder integration +source $HOME/.local/src/fzf/shell/key-bindings.zsh + +#AUTOSUGGEST CONFIG +bindkey '^ ' autosuggest-accept +bindkey '^<Tab>' autosuggest-accept +bindkey '^x' autosuggest-execute +zmodload zsh/zpty #needed for tab completion autosuggest +ZSH_AUTOSUGGEST_USE_ASYNC=1 #can be set to anything, as long as it's set it will work asynchronously +#ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20 #Might be useful for large buffers, but async might be enough +ZSH_AUTOSUGGEST_STRATEGY=(match_prev_cmd completion) # completion strategy, possible values: history, completion, match_prev_cmd or a combination of those + +ZLE_PROMPT_INDENT=0 +source $HOME/.local/src/zsh-autosuggestions/zsh-autosuggestions.zsh +# Load syntax highlighting; should be last. +source $HOME/.local/src/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh 2>/dev/null diff --git a/.local/bin/SCRIPTS.md b/.local/bin/SCRIPTS.md new file mode 100644 index 0000000..08bca91 --- /dev/null +++ b/.local/bin/SCRIPTS.md @@ -0,0 +1,87 @@ +# Directory of Scripts + +I keep all my user-created scripts here in `~/.local/bin/`. Scripts are sorted +into sub-directories for easy management, and all are seamlessly added to +`$PATH` with the command below in `~/.profile`: + +``` +export PATH="$(du $HOME/.local/bin/ | cut -f2 | tr '\n' ':')$PATH" +``` + +## `statusbar/` + +For modules used in i3blocks. + +- `battery` -- i3blocks module. Shows available power remaining with icon indicating battery status. Colors indicate different levels of charge. +- `clock` -- Shows time and date. If clicked, brings up calender or coming calcuse events. +- `cpu` -- Shows CPU temperature. If clicked, shows most processor-intensive processes. +- `help` -- Module which appears as a question mark. Brings up readme if clicked. +- `internet` -- Shows whether machine is connected to wifi and ethernet. If clicked, brings up `nmtui`. +- `mailbox` -- i3blocks module for use with mutt-wizard. Shows unread mail and if `mailsync.sh` is running. +- `mem` -- Shows memory usage. If clicked, shows most memory-intensive processes. +- `music` -- i3blocks module. Shows current song; if paused, name will be grayed and italic. +- `mpdupdate` -- A daemon running by default that will update the i3mpd block on mpd change. +- `news` -- Shows unread newsboat articles. Brings up newsboat or refreshes RSS feeds. +- `pacpackages` -- i3blocks module. Detects new installable upgrades. Only works if you use cronjobs to automatically sync repositories. +- `popupgrade` -- Called by clicking on the update icon if there are new packages. Spawns a `yay` upgrade of the main Arch repos and AUR packages, updates the i3blocks module once complete. +- `torrent` -- i3blocks module. Shows torrents idle (โŒ›๏ธ), downloading (โฌ‡๏ธ) or finished (๐ŸŒฑ). +- `volume` -- i3blocks module. Shows volume percentage or mute notification. +- `weather` -- i3blocks module. Gets weather forcast from wttr.in and returns today's precipitation chance (โ˜”), daily low (โ„๏ธ) and daily high (โ˜€๏ธ). + +## `cron/` + +For scripts meant to be cronjobs. None are active by default on LARBS. + +- `checkup` -- If connected to internet, syncs package repositories and downloads (but does not install) any potential updates. Gives `notify-send` notifications of when it is active since other `pacman` install commands cannot be run simultaneously. You may need to grant your user the ability to run `pacman -Syyuw --noconfirm` without a password (done in `/etc/sudoers`). +- `cronbat` -- Gives a dunst notification if the battery is less than 25%. +- `crontog` -- Not actually a cronjob, but just turns off/on all user cronjobs. +- `getforecast` -- Updates the weather forecast. This is automatically run by `weather` if there hasn't been a new forecast today. +- `newsup` -- Updates newsboat RSS feeds if connected to internet. Will also display a newspaper update icon on i3blocks if it has not be user disabled. + +## `tools/` + +Scripts intended to be run either manually by the user or linked to a shortcut +in vim or another program. + +- `compiler` -- Compiles a markdown, R markdown or LaTeX document with the approriate command. Will also run `make && sudo make install` if in a `config.h` file. Otherwise it will create a sent presentation. This can be thought of a general output handler. I have it bound to `<leader>c` in vim. +- `dmenuhandler` -- Give this script a url and it will offer dmenu options for opening it. Used by `newsboat` and some other programs as a link handler. +- `extract` -- Will detect file type of archive and run appropriate extraction command. +- `getbib` -- Use crossref.org to automatically detect bibtex entry of a .pdf. Attempts to search for the .pdf's DOI. Returns nothing if none detected. +- `getkeys` -- Get the LARBS documentation on what bindings exist for main programs. +- `linkhandler` -- The automatic link handler used by `newsboat` and other programs. Urls of video sites or of video files are opened in `mpv`, images are downloaded/opened in `feh`, music files are downloaded with `wget` and all other urls are opened in the default browser. +- `lmc` -- A music controller that simplifies music/audio management and improves the interface with i3blocks. Check inside to see what it does. This is what i3 audio/music commands run by default. If you use a difference music system or ALSA, you can change this script rather than changing all the shortcuts in different places. +- `note` -- Give this script some text/a message as an argument. It will print it to the terminal, and if `dunst` is running, display a notification. +- `opout` -- "Open output", opens the corresponding `.pdf` file if run on a `.md`, `.tex` or `.rmd` file, or if given an `.html` file, will open it in the browser. Bound to `<leader>p` in my vim config to reveal typical output. +- `pauseallmpv` -- Pauses all mpv instances by sending the `,` key to each. Used by several scripts, but can be used alone as well. It will not pause an audio only mpv instance. If you know how to add a hack to do this, feel free to PR it or email me an addition. +- `remaps` -- Remaps capslock to escape when pressed and super/mod when held. Maps the menu key to super as well. Runs the US international keyboard setup. If you want another keyboard setup, edit this fine. +- `shortcuts` -- For updating bash and ranger shortcuts. Reads `~/.config/bmdirs` and `~/.config/bmfiles` for pairs of keypresses and directories and files, then autoproduces bash aliases and ranger shortcuts for them which output to `~/.config/shortcutrc` and `~/.config/ranger/shortcuts.conf` respectively. These are read automatically by my bash and ranger configs. You don't have to run this script manually though, as it's run by vim whenever you edit one of the `~/.bm*` files. +- `speedvid` -- Speed up a given video file (`$1`) by a given ammount (`$2`). +- `tpb` -- Search Pirate Bay for the certain search terms given as arguments. +- `texclear` -- Remove all `.tex` related build files. This is run by my vim when I stop editing any `.tex` file. +- `transadd` -- The mimeapp default script for handling torrent magnet links. Starts `transmission-daemon` if not running and adds the link. + +## `i3cmds` + +These are scripts linked to bindings in i3. They typically perform +user-interface actions or involve dmenu. + +- `bottomleft` and `bottomright` -- Makes the currently selected window float in one of the bottom corners of the screen. `bottomleft` is bound to `mod+B` by default. +- `camtoggle` -- Starts/kills /dev/video0 webcam. Placed in bottom right by default. +- `ddspawn` -- This is the script called to create, show and hide the dropdown tmux terminal mapped to `mod+u`, but also the dropdown calculator mapped to `mod+a`. Give the script an argument that is a script the window will run. If a window does not already exist, `ddspawn` creates it, if it does, `ddspawn` will toggle its visibility. The the script itself for usage. +- `displayselect` -- Select which displays to use. Bound to `mod+F3`. +- `dmenumount` -- Gives a dmenu prompt for mounting USB drives or Android devices. Bound to `mod+F9`. Will do nothing if none are available. +- `dmenurecord` -- Gives a list of recording commands: `audio`, `video` and `screencast` (both) in dmenu for selection. Bound to `mod+PrintScreen` by default. Should be killed by `killrecording`. +- `dmenuumount` -- Unmount a mounted non-essential partition. Bound to `mod+F10`. Will do nothing if none are mounted. It will not try to unmount essential system partitions. +- `dmenuunicode` -- Shows a searchable dmenu prompt of emoji characters. The selected emoji is copied to the system clipboard, while its character code is copied to primary selection (middle mouse button). +- `dropdowncalc` -- The dropdown calculator script called by `ddspawn` and bound to `mod+a` by default. Will run an R calculator if installed, otherwise python. +- `ducksearch` -- Show a dmenu prompt and search for the inputed text in DuckDuckGo. Can take bangtags as expected, i.e. typing in `!aw Arch Linux` will search the Arch Wiki for "Arch Linux" or `!yt Luke Smith` will search YouTube for "Luke Smith", etc. +- `i3resize` -- A script that allows intuitive resizing of windows. Mapped to `mod+Y/U/I/O`. +- `killrecording` -- End a recording started by `dmenurecord` the proper way without file trucation or lingering background processes, mapped to `mod+Delete` by default. +- `lockscreen` -- The screen locker. Gives a confirm prompt and if user says yes, all audio will be paused and the screen will be distorted and locked and screen will soon time out. User must insert password to unlock. Mapped to `mod+x` by default. +- `newspod` -- A silly line that has a script all to itself due to i3's idiosyncracies. Starts `newsboat`, if `newsboat` cannot open because of another instance being open, opens `podboat`. +- `prompt` -- Gives a Yes/No prompt to a question given as an argument. Used by numerous bindings like `mod+shift+x`, `mod+shift+backspace` and `mod+shift+escape`. +- `samedir` -- Opens a terminal window in the same directory as the window currently selection. Bound to `mod+shift+enter`. +- `td-toggle` -- Gives a dmenu prompt to start `transmission-daemon` if not running, or the kill it if it is. Obviously you need `transmission-cli` installed for this to work. Mapped to `mod+F7` by default. +- `tmuxdd` -- The startup script for the dropdown terminal (toggleable with `mod+u`). Either attaches to an existing tmux session or begins a new one. +- `toggletouchpad` -- As the name suggests, turns off TouchPad if on, and turns it on if off. Requires `xf86-input-synaptics`. If your laptop has a special button for this, it will be mapped by default. +- `tutorialvids` -- A dmenu prompt that gives some options of tutorial videos to watch. Bound to `mod+shift+e`. diff --git a/.local/bin/bt b/.local/bin/bt new file mode 100755 index 0000000..19b9e2a --- /dev/null +++ b/.local/bin/bt @@ -0,0 +1,154 @@ +#!/bin/bash +#wait time to discover new devices in seconds +SCAN_PERIOD=5 +AUTOTRUST=false +#locations of blacklist and hard coded list of paired devices (watch out, need to modify Makefile as well if you want to change these values and still use make install) +BLACKLIST=${XDG_DATA_HOME:-$HOME/.local/share}/bt/blacklist +PAIRLIST=${XDG_DATA_HOME:-$HOME/.local/share}/bt/paired + +actions="pair +disconnect +unpair" + +[ "$AUTOTRUST" = false ] && actions+=" +trust" + +#Checks for necessary programs to be present. Very unlikely not to be present but let's just err on the safer side. +for prog in dmenu bluetoothctl awk cat date nl; do + if ! hash "$prog" 2>/dev/null; then + printf 'bthandler: %s: command not found\n' "$prog" >&2 + exit 127 + fi +done + +power(){ + powerstatus="$( bluetoothctl show | grep Powered | awk '{print $2}' )" + [ "$powerstatus" = "no" ] && [ "$1" = on ] && bluetoothctl power on + [ "$powerstatus" = "yes" ] && [ "$1" = off ] && bluetoothctl power off +} +scan(){ + scanstatus="$( bluetoothctl show | grep Discovering | awk '{print $2}' )" + if [ "$1" = on ]; then + #sets variable in case scanning was already on before the start of bt + [ "$start_scan" = "" ] && start_scan="$( date +'%s' )" + if [ "$scanstatus" = "no" ]; then + bluetoothctl scan on & + start_scan="$( date +'%s' )" + fi + elif [ "$1" = off ]; then + if [ "$scanstatus" = "yes" ]; then + bluetoothctl scan off + fi + fi +} + +#start scanning as early as possible to speed up pairing process +#=> maybe use an option to do this? Otherwise ever invocation of bt powers on the controller. +power on +scan on + +#Compile list of all Bluetooth IDS of paired devices (from bluetoothctl and from hardcoded list) +bt_IDS="$( ( bluetoothctl paired-devices && cat "$PAIRLIST" ) | sort -u | awk '{print $2}' )" + +#Compile list of all device Names of paired devices (from bluetoothctl and from hardcoded list) +paired_devices="$( ( bluetoothctl paired-devices && cat "$PAIRLIST" ) | sort -u | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' )" + +disp_devices="$( echo "$paired_devices" | grep -vf "$BLACKLIST" )" + +#detects current power mode of controller and adjusts options accordingly +poweroption="$( echo "$powerstatus" | sed 's/yes/power off/; s/no/power on/' )" +#Don't print empty device list, removes unnecessary empty choice in dmenu +[ "$disp_devices" = "" ] && choice=$( printf "%s\n%s" "$poweroption" "$actions" | dmenu -i -p 'What BT action would you like to perform:' ) +[ "$disp_devices" != "" ] && choice=$( ( echo "$disp_devices" && printf "%s\n%s" "$poweroption" "$actions" ) | dmenu -i -p 'What BT action would you like to perform:' ) + +cleanup(){ + scan off + exit 0 +} + +pair(){ + #since this function can get called indefinitely, make sure to always be scanning and controller has power in the case that it got deactived by some other process. + power on + scan on + #check whether $SCAN_PERIOD seconds has already passed since starting scanning, if not, wait for the rest of that time. + if [ $((( "$(date +'%s')" - "$start_scan" ))) -lt $SCAN_PERIOD ]; then + sleep_period="$((( "$SCAN_PERIOD" - "$( date +'%s')" + "$start_scan" )))" + if [ "$sleep_period" -eq 1 ]; then + notify-send "Bluetooth" "Searching for devices, please wait 1 second" + else + notify-send "Bluetooth" "Searching for devices, please wait $sleep_period seconds" + fi + + sleep "$sleep_period" + fi + echo paired_devices:"$paired_devices". + echo paired_devices:$paired_devices. + if [ $paired_devices = "" ]; then + new_devices="$( bluetoothctl devices | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' | grep -vf "<(echo $paired_devices)" )" + else + new_devices="$( bluetoothctl devices | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' )" + fi + echo new_devices:"$new_devices". + echo new_devices:$new_devices. + [ $new_devices = "" ] && options="rescan" || options=$(echo "$new_devices" && echo 'rescan') + choice=$( echo "$options" | dmenu -l 10 -i -p 'pair with which device?' ) + if [ -n "$choice" ]; then + if [ "$choice" = "rescan" ]; then + start_scan="$( date +'%s')" + pair + fi + bt_IDS="$( bluetoothctl devices | awk '{print $2}' )" + dev_no=$( echo "$new_devices" | nl | grep "$choice" | awk '{print $1}') + dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' ) + + bluetoothctl pair "$dev_id" && sleep 2 + bluetoothctl connect "$dev_id" + if $AUTOTRUST; then + bluetoothctl trust "$dev_id" + fi + #if device is not already hard coded as paired, add to paired devices list + if [ $( grep "$dev_id" "$PAIRLIST") = "" ] + then + echo to be added to "$PAIRLIST": + echo Device "$dev_id" "$choice" + echo Device "$dev_id" "$choice" >> "$PAIRLIST" + fi + fi +} + +case $choice in + "turn on") bluetoothctl power on;; + "turn off") bluetoothctl power off;; + "scan on") bluetoothctl power on && echo power on && sleep 2 + ([ -n "$TERMINAL" ] && $TERMINAL -e bluetoothctl scan on ) || st bluetoothctl scan on;; + "pair") pair;; + "unpair") choice=$( echo "$paired_devices" | dmenu -l 10 -i -p 'remove which paired device?') + if [ -n "$choice" ]; then + dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}') + dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' ) + bluetoothctl remove "$dev_id" + #remove device to unpair from hard coded paired devices list + new_paired_list="$( grep -v "$dev_id" "$PAIRLIST" )" + echo "$new_paired_list" > "$PAIRLIST" #needs to be done with temp var, can't read from file and pipe into it at the same time + fi;; + "trust") choice=$( echo "$paired_devices" | dmenu -l 10 -i -p 'remove which paired device?') + if [ -n "$choice" ]; then + dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}') + dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' ) + bluetoothctl trust "$dev_id" + fi;; + "disconnect") choice=$( echo "$paired_devices" | dmenu -l 10 -i -p 'remove which paired device?') + if [ -n "$choice" ]; then + dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}') + dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' ) + bluetoothctl disconnect "$dev_id" + fi;; + *) + echo "$choice" + dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}') + dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}') + bluetoothctl power on + bluetoothctl pair "$dev_id" + bluetoothctl connect "$dev_id";; +esac +cleanup diff --git a/.local/bin/cabl b/.local/bin/cabl new file mode 100755 index 0000000..8bc59c5 --- /dev/null +++ b/.local/bin/cabl @@ -0,0 +1,26 @@ +#!/bin/bash +# Dependencies are xclip and xorg-xprop. +# qrencode required for qrcode generation. +# groff/zathura required for man pages. +prim="$(xclip -o -selection 'clipboard')"; [ -z "$prim" ] && exit + +PID=$(xprop -id "$(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}')" | grep -m 1 PID | cut -d " " -f 3) +PID=$(echo "$(pstree -lpA "$PID" | tail -n 1)" | awk -F'---' '{print $NF}' | sed -re 's/[^0-9]//g') +cd "$(readlink /proc/"$PID"/cwd)" +[ -f "$prim" ] && xdg-open "$prim" && exit +[ -d "$prim" ] && "$TERMINAL" "$prim" && exit + +websearch() { "$BROWSER" "https://duckduckgo.com/?q=$@" ;} +wikipedia() { "$BROWSER" "https://en.wikipedia.org/wiki/$@" ;} +wiktionary() { "$BROWSER" "https://en.wiktionary.org/wiki/$@" ;} +maps() { "$BROWSER" "https://www.openstreetmap.org/search?query=$@" ;} +ebay() { "$BROWSER" "https://www.ebay.com/sch/$@" ;} + +echo "$prim" | grep "^.*\.[A-Za-z]\+.*" >/dev/null && gotourl() { "$BROWSER" "$@" ;} +echo "$prim" | grep "^.*@.*\.[A-Za-z]\+$" >/dev/null && email() { xdg-email "$@" ;} +command -v qrencode >/dev/null && qrcode() { qrencode "$@" -s 10 -o /tmp/qr.png && xdg-open /tmp/qr.png ;} +man -k "^$prim$" >/dev/null && manual() { man -Tpdf "$prim" | zathura - ;} + +func="$(declare -F | awk '{print $3}' | dmenu -p "Plumb \"$(echo "$prim" | cut -c -30)\" to?" -i -l 15)" + +[ -z "$func" ] || "$func" "$prim" diff --git a/.local/bin/castscreen b/.local/bin/castscreen new file mode 100755 index 0000000..939e0e4 --- /dev/null +++ b/.local/bin/castscreen @@ -0,0 +1,10 @@ +#!/bin/bash +xrandr --output eDP-1 --mode 1920x1080 --auto +xrdb -merge ~/.config/X11/Xres_casting +wal -q -i ~/.config/wall.png -b '#000000' +xdotool key super+F2 +st mkchromecast --video --control --screencast +xrandr --output eDP-1 --mode 3200x1800 --auto +xrdb -merge ~/.config/X11/Xresources +wal -q -i ~/.config/wall.png -b '#000000' +xdotool key super+F2 diff --git a/.local/bin/compiler b/.local/bin/compiler new file mode 100755 index 0000000..d191407 --- /dev/null +++ b/.local/bin/compiler @@ -0,0 +1,40 @@ +#!/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. Opens .sent files as sent +# presentations. Runs scripts based on extention or shebang + +file=$(readlink -f "$1") +dir=$(dirname "$file") +base="${file%.*}" + +cd "$dir" || exit + +textype() { \ + command="pdflatex" + ( sed 5q "$file" | grep -i -q 'xelatex' ) && command="xelatex" + $command --output-directory="$dir" "$base" && + grep -i addbibresource "$file" >/dev/null && + biber --input-directory "$dir" "$base" && + $command --output-directory="$dir" "$base" && + $command --output-directory="$dir" "$base" + } + +case "$file" in + *\.ms) refer -PS -e "$file" | groff -me -ms -kept -T pdf > "$base".pdf ;; + *\.mom) refer -PS -e "$file" | groff -mom -kept -T pdf > "$base".pdf ;; + *\.[0-9]) refer -PS -e "$file" | groff -mandoc -T pdf > "$base".pdf ;; + *\.[rR]md) Rscript -e "rmarkdown::render('$file', quiet=TRUE)" ;; + *\.tex) textype "$file" ;; + *\.md) pandoc "$file" -V geometry:margin=1in --pdf-engine=xelatex -o "$base".pdf ;; + *config.h) sudo make install ;; + *\.c) cc "$file" -o "$base" && "$base" ;; + *\.py) python "$file" ;; + *\.m) octave "$file" ;; + *\.scad) openscad -o "$base".stl "$file" ;; + *\.go) go run "$file" ;; + *\.sent) setsid sent "$file" 2>/dev/null & ;; + *) sed 1q "$file" | grep "^#!/" | sed "s/^#!//" | xargs -r -I % "$file" ;; +esac diff --git a/.local/bin/cron/IMPORTANT_NOTE.md b/.local/bin/cron/IMPORTANT_NOTE.md new file mode 100644 index 0000000..f5a130b --- /dev/null +++ b/.local/bin/cron/IMPORTANT_NOTE.md @@ -0,0 +1,11 @@ +# Important Note + +These cronjobs have components that require information about your current display to display notifications correctly. + +When you add them as cronjobs, I recommend you precede the command with commands as those below: + +``` +export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus; export DISPLAY=:0; . $HOME/.zprofile; then_command_goes_here +``` + +This ensures that notifications will display, xdotool commands will function and environmental variables will work as well. diff --git a/.local/bin/cron/checkup b/.local/bin/cron/checkup new file mode 100755 index 0000000..34ed61e --- /dev/null +++ b/.local/bin/cron/checkup @@ -0,0 +1,19 @@ +#!/bin/sh + +# Syncs repositories and downloads updates, meant to be run as a cronjob. + +ping -q -c 1 1.1.1.1 > /dev/null || exit + +notify-send "๐Ÿ“ฆ Repository Sync" "Checking for package updates..." + +sudo pacman -Syyuw --noconfirm || notify-send "Error downloading updates. + +Check your internet connection, if pacman is already running, or run update manually to see errors." +pkill -RTMIN+8 "${STATUSBAR:-dwmblocks}" + +if pacman -Qu | grep -v "\[ignored\]" +then + notify-send "๐ŸŽ Repository Sync" "Updates available. Click statusbar icon (๐Ÿ“ฆ) for update." +else + notify-send "๐Ÿ“ฆ Repository Sync" "Sync complete. No new packages for update." +fi diff --git a/.local/bin/cron/cronbat b/.local/bin/cron/cronbat new file mode 100755 index 0000000..2dc0950 --- /dev/null +++ b/.local/bin/cron/cronbat @@ -0,0 +1,9 @@ +#!/bin/sh + +# Notify me with notify-send if my battery is below 25%. +# You can set this to run via cron. + +[ "$(cat /sys/class/power_supply/BAT0/status)" = "Charging" ] && exit +[ "$(cat /sys/class/power_supply/BAT0/capacity)" -lt 25 ] && +export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus && +notify-send -u critical "Battery critically low." diff --git a/.local/bin/cron/crontog b/.local/bin/cron/crontog new file mode 100755 index 0000000..8168012 --- /dev/null +++ b/.local/bin/cron/crontog @@ -0,0 +1,6 @@ +#!/bin/sh + +# Toggles all cronjobs off/on. +# Stores disabled crontabs in ~/.consaved until restored. + +([ -f ${XDG_CONFIG_HOME:-$HOME/.config}/cronsaved ] && crontab - < ${XDG_CONFIG_HOME:-$HOME/.config}/cronsaved && rm ${XDG_CONFIG_HOME:-$HOME/.config}/cronsaved && notify-send "๐Ÿ•“ Cronjobs re-enabled.") || ( crontab -l > ${XDG_CONFIG_HOME:-$HOME/.config}/cronsaved && crontab -r && notify-send "๐Ÿ•“ Cronjobs saved and disabled.") diff --git a/.local/bin/cron/newsup b/.local/bin/cron/newsup new file mode 100755 index 0000000..bf8898e --- /dev/null +++ b/.local/bin/cron/newsup @@ -0,0 +1,17 @@ +#!/bin/sh + +# Set as a cron job to check for new RSS entries for newsboat. +# If newsboat is open, sends it an "R" key to refresh. + +ping -q -c 1 1.1.1.1 > /dev/null || exit + +/usr/bin/notify-send "๐Ÿ“ฐ Updating RSS feeds..." + +ps ax | grep -q newsboat$ && /usr/bin/xdotool key --window "$(/usr/bin/xdotool search --name newsboat)" R && exit + +echo ๐Ÿ”ƒ > /tmp/newsupdate +pkill -RTMIN+6 "${STATUSBAR:-dwmblocks}" +/usr/bin/newsboat -x reload +rm -f /tmp/newsupdate +pkill -RTMIN+6 "${STATUSBAR:-dwmblocks}" +/usr/bin/notify-send "๐Ÿ“ฐ RSS feed update complete." diff --git a/.local/bin/cv b/.local/bin/cv new file mode 100755 index 0000000..e41c6bc --- /dev/null +++ b/.local/bin/cv @@ -0,0 +1,13 @@ +#!/bin/sh +source $HOME/.config/aliasrc +alldata="/tmp/allfiles" +videos="/tmp/videos" +du -a ~/vids/* --time | sort -u | awk '!($1="")' | sort -bg | awk '!($1="")' | awk '!($1="")' | sed 's/^ //' | tac > $alldata +touch $videos +while read line; do + [ -f "$line" ] && echo $line >> $videos +done <$alldata +choice=$( cat $videos | dmenu -i -l 50 -p "Choose a video to watch:" ) +[ -n "$choice" ] && st mkchromecast --video --control -i "$choice" +rm -f "$alldata" +rm -f "$videos" diff --git a/.local/bin/ddspawn b/.local/bin/ddspawn new file mode 100755 index 0000000..d4a4034 --- /dev/null +++ b/.local/bin/ddspawn @@ -0,0 +1,19 @@ +#!/bin/sh + +# Toggle floating dropdown terminal in i3, or start if non-existing. +# $1 is the script run in the terminal. +# All other args are terminal settings. +# Terminal names are in dropdown_* to allow easily setting i3 settings. + +[ -z "$1" ] && exit + +script=$1 +shift +if xwininfo -tree -root | grep "(\"dropdown_$script\" "; +then + echo "Window detected." + i3 "[instance=\"dropdown_$script\"] scratchpad show; [instance=\"dropdown_$script\"] move position center" +else + echo "Window not detected... spawning." + i3 "exec --no-startup-id $TERMINAL -n dropdown_$script $@ -e $script" +fi diff --git a/.local/bin/displayselect b/.local/bin/displayselect new file mode 100755 index 0000000..02b35c2 --- /dev/null +++ b/.local/bin/displayselect @@ -0,0 +1,83 @@ +#!/bin/sh + +# A UI for detecting and selecting all displays. Probes xrandr for connected +# displays and lets user select one to use. User may also select "manual +# selection" which opens arandr. + +twoscreen() { # If multi-monitor is selected and there are two screens. + + mirror=$(printf "no\\nyes" | dmenu -i -p "Mirror displays?") + # Mirror displays using native resolution of external display and a scaled + # version for the internal display + if [ "$mirror" = "yes" ]; then + external=$(echo "$screens" | dmenu -i -p "Optimize resolution for:") + internal=$(echo "$screens" | grep -v "$external") + + res_external=$(xrandr --query | sed -n "/^$external/,/\+/p" | \ + tail -n 1 | awk '{print $1}') + res_internal=$(xrandr --query | sed -n "/^$internal/,/\+/p" | \ + tail -n 1 | awk '{print $1}') + + res_ext_x=$(echo $res_external | sed 's/x.*//') + res_ext_y=$(echo $res_external | sed 's/.*x//') + res_int_x=$(echo $res_internal | sed 's/x.*//') + res_int_y=$(echo $res_internal | sed 's/.*x//') + + scale_x=$(echo "$res_ext_x / $res_int_x" | bc -l) + scale_y=$(echo "$res_ext_y / $res_int_y" | bc -l) + + xrandr --output "$external" --auto --scale 1.0x1.0 \ + --output "$internal" --auto --same-as "$external" \ + --scale "$scale_x"x"$scale_y" + else + + primary=$(echo "$screens" | dmenu -i -p "Select primary display:") + secondary=$(echo "$screens" | grep -v "$primary") + direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?") + xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction"-of "$primary" --auto --scale 1.0x1.0 + fi + } + +morescreen() { # If multi-monitor is selected and there are more than two screens. + primary=$(echo "$screens" | dmenu -i -p "Select primary display:") + secondary=$(echo "$screens" | grep -v "$primary" | dmenu -i -p "Select secondary display:") + direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?") + tertiary=$(echo "$screens" | grep -v "$primary" | grep -v "$secondary" | dmenu -i -p "Select third display:") + xrandr --output "$primary" --auto --output "$secondary" --"$direction"-of "$primary" --auto --output "$tertiary" --"$(printf "left\\nright" | grep -v "$direction")"-of "$primary" --auto + } + +multimon() { # Multi-monitor handler. + case "$(echo "$screens" | wc -l)" in + 2) twoscreen ;; + *) morescreen ;; + esac ;} + +onescreen() { # If only one output available or chosen. + xrandr --output "$1" --auto --scale 1.0x1.0 $(echo "$allposs" | grep -v "$1" | awk '{print "--output", $1, "--off"}' | tr '\n' ' ') + } + +postrun() { # Stuff to run to clean up. + setbg # Fix background if screen size/arangement has changed. + remaps # Re-remap keys if keyboard added (for laptop bases) + { killall dunst ; setsid dunst & } >/dev/null 2>&1 # Restart dunst to ensure proper location on screen + } + +# Get all possible displays +allposs=$(xrandr -q | grep "connected") + +# Get all connected screens. +screens=$(echo "$allposs" | awk '/ connected/ {print $1}') + +# If there's only one screen +[ "$(echo "$screens" | wc -l)" -lt 2 ] && + { onescreen "$screens"; postrun; notify-send "๐Ÿ’ป Only one screen detected." "Using it in its optimal settings..."; exit ;} + +# Get user choice including multi-monitor and manual selection: +chosen=$(printf "%s\\nmulti-monitor\\nmanual selection" "$screens" | dmenu -i -p "Select display arangement:") && +case "$chosen" in + "manual selection") arandr ; exit ;; + "multi-monitor") multimon ;; + *) onescreen "$chosen" ;; +esac + +postrun diff --git a/.local/bin/dmenu-recent-aliases b/.local/bin/dmenu-recent-aliases new file mode 100755 index 0000000..7b3ab49 --- /dev/null +++ b/.local/bin/dmenu-recent-aliases @@ -0,0 +1,78 @@ +#!/bin/zsh +#cache=~/.cache/dmenu_run +freq="$HOME/.cache/dmenu_history_test" +alias_file="$HOME/.config/aliasrc" +dmenucmd='dmenu -i ' + +source $alias_file + +#pull our previously run commands in +history=$(<$freq) +#for ones that have arguments, condense them down to an asterisk +history=$(sed "s/[[:space:]].*/*/" <<< "$history") + +#generate list of commands including functions and alias' +#tail command gets rid of a few of the weird bash builtins +#at the beginning of the list +cache=$(compgen -a; compgen -c | grep -vxF "$(compgen -a)" | sort | tail -n +10) + +# sort history by frequency of use +sorted=$(sort <<< "$history" | uniq -c | sort -hr | colrm 1 8) +filter=$(sed 's/[*;]*$//' <<< "$sorted") + +echo "$filter" +# grep removes the duplicates from the unsorted list +cache_deduped=$(grep -vxF "$filter" <<< "$cache") + +# run the actual dmenu and let the user choose a command +cmd="$(echo "$sorted"$'\n'"$cache_deduped" | $dmenucmd)" + +# To remove a file from history: +# Trail the selected item with ;remove +if [[ $cmd == *";remove" ]]; then + cmd=${cmd/;remove/} + grep -vx "$cmd" $freq > temp + mv temp $freq + exit 0 +fi + +# expand an asterisked command to include argument history +regex='.+[*]$' +if [[ "$cmd" =~ $regex ]]; then + history=$(grep "${cmd/[*]/}" $freq) + sorted=$(sort <<< "$history" | uniq -c | sort -hr | colrm 1 8) + # remove trailing whitespace and asterisks from arguments + cmd=$(sed 's/[[:space:]*]*$//' <<< "$@") + dmenucmd+=' -l 17' + (sleep .1; xdotool key Tab) & + cmd="$(echo "$sorted"$'\n'"$cache" | $dmenucmd)" + if [[ $cmd == *";remove" ]]; then + cmd=${cmd/;remove/} + egrep -vx "$cmd" $freq > temp + mv temp $freq + exit 0 + fi +fi + +if ! [ "$cmd" == "" ]; then + # remember which commands have been run + echo "$cmd" >> $freq + cmdexec=$(alias | grep "${cmd/;/}=" | cut -f2 -d "'" | tr -d "'") + if [ -z "$cmdexec" ]; then + cmdexec=${cmd/;/} + fi + + # open a command up in a terminal + # a second semicolon holds the xterm open + if [[ $cmd == *";;" ]]; then + cmdexec="xterm -hold -e $cmdexec" + elif [[ $cmd == *";" ]]; then + cmdexec="xterm -e $cmdexec" + fi + + # Workaround to run functions... + echo "$cmdexec" | compgen -F "$cmdexec" | zsh -i + # ...and aliases + echo "$cmdexec" | zsh -i +fi + diff --git a/.local/bin/dmenumount b/.local/bin/dmenumount new file mode 100755 index 0000000..75e11b5 --- /dev/null +++ b/.local/bin/dmenumount @@ -0,0 +1,66 @@ +#!/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 + [ "$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;; + *) 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" | 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/dmenupass b/.local/bin/dmenupass new file mode 100755 index 0000000..2c14e6f --- /dev/null +++ b/.local/bin/dmenupass @@ -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 -fn Monospace-18 -P -p "$1" <&- && echo diff --git a/.local/bin/dmenurecord b/.local/bin/dmenurecord new file mode 100755 index 0000000..bb8233a --- /dev/null +++ b/.local/bin/dmenurecord @@ -0,0 +1,120 @@ +#!/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" \ + -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 "โบ๏ธ๐ŸŽ™๏ธ" + } + +screencast_old() { \ + 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\\naudio\\nwebcam\\nwebcam (hi-def)" | dmenu -i -p "Select recording style:") + case "$choice" in + screencast) screencast;; + audio) audio;; + video) video;; + webcam) webcam;; + "webcam (hi-def)") webcamhidef;; + esac + } + +asktoend() { \ + response=$(printf "No\\nYes" | dmenu -i -p "Recording still active. End recording?") && + [ "$response" = "Yes" ] && killrecording + } + + +case "$1" in + screencast) screencast;; + audio) audio;; + video) video;; + kill) killrecording;; + *) ([ -f /tmp/recordingpid ] && asktoend && exit) || askrecording;; +esac diff --git a/.local/bin/dmenuumount b/.local/bin/dmenuumount new file mode 100755 index 0000000..26612ef --- /dev/null +++ b/.local/bin/dmenuumount @@ -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" | awk '$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "%s (%s)\n",$4,$3}') + +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/dmenuunicode b/.local/bin/dmenuunicode new file mode 100755 index 0000000..15799a3 --- /dev/null +++ b/.local/bin/dmenuunicode @@ -0,0 +1,18 @@ +#!/bin/sh + +# The famous "get a menu of emojis to copy" script. + +# Must have xclip installed to even show menu. +xclip -h 2>/dev/null || exit 1 + +chosen=$(cut -d ';' -f1 ${XDG_DATA_HOME:-$HOME/.local/share}/larbs/emoji | dmenu -i -l 20 | sed "s/ .*//") + +[ "$chosen" != "" ] || exit + +# If you run this command with an argument, it will automatically insert the character. +if [ -n "$1" ]; then + xdotool key Shift+Insert +else + echo "$chosen" | tr -d '\n' | xclip -selection clipboard + notify-send "'$chosen' copied to clipboard." & +fi diff --git a/.local/bin/dropdowncalc b/.local/bin/dropdowncalc new file mode 100755 index 0000000..f0615fd --- /dev/null +++ b/.local/bin/dropdowncalc @@ -0,0 +1,3 @@ +#!/bin/sh + +ifinstalled bc && echo "Welcome to the Calculator." && bc -lq diff --git a/.local/bin/ducksearch b/.local/bin/ducksearch new file mode 100755 index 0000000..287dd86 --- /dev/null +++ b/.local/bin/ducksearch @@ -0,0 +1,21 @@ +#!/bin/sh +# Gives a dmenu prompt to search DuckDuckGo. +# Without input, will open DuckDuckGo.com. +# URLs will be directly handed to the browser. +# Anything else, it search it. +browser=${BROWSER:-firefox} + +pgrep -x dmenu && exit + +choice=$(echo "๐Ÿฆ†" | dmenu -i -p "Search DuckDuckGo:") || exit 1 + +if [ "$choice" = "๐Ÿฆ†" ]; then + $browser "https://duckduckgo.com" +else + if echo "$choice" | grep "^(http:\/\/|https:\/\/)?[a-zA-Z0-9]+\.[a-zA-Z]+(/)?.*$"; then + $browser "$choice" + else + string="$(echo $choice | sed 's/\ /+/g')" + $browser "https://duckduckgo.com/?q=$string&t=ffab&atb=v1-1" + fi +fi diff --git a/.local/bin/ext b/.local/bin/ext new file mode 100755 index 0000000..c5f89c5 --- /dev/null +++ b/.local/bin/ext @@ -0,0 +1,44 @@ +#!/bin/sh + +# A general, all-purpose extraction script. Not all extraction programs here +# are installed by LARBS automatically. +# +# Default behavior: Extract archive into new directory +# Behavior with `-c` option: Extract contents into current directory + +while getopts "hc" o; do case "${o}" in + c) extracthere="True" ;; + *) printf "Options:\\n -c: Extract archive into current directory rather than a new one.\\n" && exit ;; +esac done + +if [ -z "$extracthere" ]; then + archive="$(readlink -f "$*")" && + directory="$(echo "$archive" | sed 's/\.[^\/.]*$//')" && + mkdir -p "$directory" && + cd "$directory" || exit +else + archive="$(readlink -f "$(echo "$*" | cut -d' ' -f2)")" +fi + +[ "$archive" = "" ] && printf "Give archive to extract as argument.\\n" && exit + +if [ -f "$archive" ] ; then + case "$archive" in + *.tar.bz2|*.tbz2) tar xvjf "$archive" ;; + *.tar.xz) tar -xf "$archive" ;; + *.tar.gz|*.tgz) tar xvzf "$archive" ;; + *.lzma) unlzma "$archive" ;; + *.bz2) bunzip2 "$archive" ;; + *.rar) unrar x -ad "$archive" ;; + *.gz) gunzip "$archive" ;; + *.tar) tar xvf "$archive" ;; + *.zip) unzip "$archive" ;; + *.Z) uncompress "$archive" ;; + *.7z) 7z x "$archive" ;; + *.xz) unxz "$archive" ;; + *.exe) cabextract "$archive" ;; + *) printf "extract: '%s' - unknown archive method\\n" "$archive" ;; + esac +else + printf "File \"%s\" not found.\\n" "$archive" +fi diff --git a/.local/bin/f2py b/.local/bin/f2py new file mode 100755 index 0000000..40ce6f8 --- /dev/null +++ b/.local/bin/f2py @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.local/bin/f2py3 b/.local/bin/f2py3 new file mode 100755 index 0000000..40ce6f8 --- /dev/null +++ b/.local/bin/f2py3 @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.local/bin/f2py3.8 b/.local/bin/f2py3.8 new file mode 100755 index 0000000..40ce6f8 --- /dev/null +++ b/.local/bin/f2py3.8 @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from numpy.f2py.f2py2e import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.local/bin/getkeys b/.local/bin/getkeys new file mode 100755 index 0000000..0a0e86e --- /dev/null +++ b/.local/bin/getkeys @@ -0,0 +1,5 @@ +#!/bin/sh + +cat ${XDG_DATA_HOME:-$HOME/.local/share}/larbs/getkeys/"$1" 2>/dev/null && exit +echo "Run command with one of the following arguments for info about that program:" +ls ${XDG_DATA_HOME:-$HOME/.local/share}/larbs/getkeys diff --git a/.local/bin/i3cmds/hover b/.local/bin/i3cmds/hover new file mode 100755 index 0000000..f4bb86b --- /dev/null +++ b/.local/bin/i3cmds/hover @@ -0,0 +1,22 @@ +#!/bin/sh + +[ -z "$1" ] && exit # If $1 is left, hovers in the bottom left, if right, the bottom right +current=$(xdotool getwindowfocus) +newwidth=$(($(xdotool getdisplaygeometry | awk '{print $2}') / 3)) +newheight=$(($(xdotool getdisplaygeometry | awk '{print $1}') / 3)) +centerwidth=$(( $(xdotool getdisplaygeometry | awk '{print $1}') / 2)) +newsize=$(xdotool getwindowgeometry "$current" | grep Geometry | sed -e 's/x/ /g' | awk '{print $3}') +newwidth=$(xdotool getwindowgeometry "$current" | grep Geometry | grep -o " [0-9]*") +baroffset=47 + +case "$1" in + left) horizontal=0; vertical=$(($(xdotool getdisplaygeometry | awk '{print $2}') - newsize)) ;; + right) horizontal=$(($(xdotool getdisplaygeometry | awk '{print $1}') - newwidth)) ; vertical=$(($(xdotool getdisplaygeometry | awk '{print $2}') - newsize)) ;; + center) echo "$centerwidth" + horizontal=$(( ( $(xdotool getdisplaygeometry | awk '{print $1}') - centerwidth ) / 2 )); + vertical=$baroffset + newheight=$(( $(xdotool getdisplaygeometry | awk '{print $2}' ) - baroffset -5)) + newwidth=$centerwidth;; +esac +xdotool windowsize "$current" $newwidth $newheight +xdotool windowmove "$current" $horizontal $vertical diff --git a/.local/bin/i3cmds/i3resize b/.local/bin/i3cmds/i3resize new file mode 100755 index 0000000..0bfb5ea --- /dev/null +++ b/.local/bin/i3cmds/i3resize @@ -0,0 +1,28 @@ +#!/bin/sh + +# This script was made by `goferito` on Github. +# Some cleanup by Luke. + +[ -z "$1" ] && echo "No direction provided" && exit 1 +distanceStr="2 px or 2 ppt" + +moveChoice() { + i3-msg resize "$1" "$2" "$distanceStr" | grep '"success":true' || \ + i3-msg resize "$3" "$4" "$distanceStr" +} + +case $1 in + up) + moveChoice grow up shrink down + ;; + down) + moveChoice shrink up grow down + ;; + left) + moveChoice shrink right grow left + ;; + right) + moveChoice grow right shrink left + ;; +esac + diff --git a/.local/bin/i3cmds/killrecording b/.local/bin/i3cmds/killrecording new file mode 100755 index 0000000..ec9a698 --- /dev/null +++ b/.local/bin/i3cmds/killrecording @@ -0,0 +1,7 @@ +#!/bin/sh + +kill -9 "$(cat ~/.recordingpid)" + +# Update i3bar. +echo "" > ~/.recordingicon +pkill -RTMIN+9 i3blocks diff --git a/.local/bin/i3cmds/maimpick b/.local/bin/i3cmds/maimpick new file mode 100755 index 0000000..07d032f --- /dev/null +++ b/.local/bin/i3cmds/maimpick @@ -0,0 +1,9 @@ +#!/bin/sh +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-"$(date '+%y%m%d-%H%M-%S').png" ;; + "current window") maim -i "$(xdotool getactivewindow)" pic-window-"$(date '+%y%m%d-%H%M-%S').png" ;; + "full screen") maim pic-full-"$(date '+%y%m%d-%H%M-%S').png" ;; + "a selected area (copy)") maim -s | xclip -selection clipboard -t image/png ;; + "current window (copy)") maim -i "$(xdotool getactivewindow)" | xclip -selection clipboard -t image/png ;; + "full screen (copy)") maim | xclip -selection clipboard -t image/png ;; +esac diff --git a/.local/bin/i3cmds/prompt b/.local/bin/i3cmds/prompt new file mode 100755 index 0000000..13b21e4 --- /dev/null +++ b/.local/bin/i3cmds/prompt @@ -0,0 +1,7 @@ +#!/bin/sh +# A dmenu binary prompt script. +# Gives a dmenu prompt labeled with $1 to perform command $2. +# For example: +# `./prompt "Do you want to shutdown?" "shutdown -h now"` + +[ "$(printf "No\\nYes" | dmenu -i -n -p "$1" -nb darkred -sb red -sf white -nf gray )" = "Yes" ] && $2 diff --git a/.local/bin/i3cmds/samedir b/.local/bin/i3cmds/samedir new file mode 100755 index 0000000..88845fc --- /dev/null +++ b/.local/bin/i3cmds/samedir @@ -0,0 +1,5 @@ +#!/bin/sh +PID=$(xprop -id "$(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}')" | grep -m 1 PID | cut -d " " -f 3) +PID=$(echo "$(pstree -lpA "$PID" | tail -n 1)" | awk -F'---' '{print $NF}' | sed -re 's/[^0-9]//g') +cd "$(readlink /proc/"$PID"/cwd)" +"$TERMINAL" diff --git a/.local/bin/i3cmds/td-toggle b/.local/bin/i3cmds/td-toggle new file mode 100755 index 0000000..dc727b9 --- /dev/null +++ b/.local/bin/i3cmds/td-toggle @@ -0,0 +1,10 @@ +#!/bin/sh +# If transmission-daemon is running, will ask to kill, else will ask to start. +if pgrep -x transmission-da >/dev/null ; +then + [ "$(printf "No\\nYes" | dmenu -i -p "Kill transmission-daemon?")" = "Yes" ] && killall transmission-da && notify-send "transmission-daemon killed." +else + ifinstalled transmission-cli || exit + [ "$(printf "No\\nYes" | dmenu -i -p "Start transmission daemon?")" = "Yes" ] && transmission-daemon && notify-send "tranmission-daemon started." +fi +sleep 3 && pkill -RTMIN+7 i3blocks diff --git a/.local/bin/i3cmds/tmuxdd b/.local/bin/i3cmds/tmuxdd new file mode 100755 index 0000000..3997240 --- /dev/null +++ b/.local/bin/i3cmds/tmuxdd @@ -0,0 +1,5 @@ +#!/bin/sh + +# This is the script that i3 runs to either start tmux in +# the dropdown terminal or log into a previous session. +tmux a || tmux diff --git a/.local/bin/i3cmds/toggle-welcome b/.local/bin/i3cmds/toggle-welcome new file mode 100755 index 0000000..517c301 --- /dev/null +++ b/.local/bin/i3cmds/toggle-welcome @@ -0,0 +1,10 @@ +#!/bin/sh + +# Toggles the LARBS welcome message. + +PIC="${XDG_DATA_HOME:-$HOME/.local/share}/larbs/larbs.png" + +grep LARBSWELCOME "$HOME/.xprofile" && + ( sed -i "/LARBSWELCOME/d" ~/.xprofile && notify-send -i "$PIC" "LARBS welcome message" "Welcome message disabled. Press Super+Shift+F1 again to reverse." ) || + ( echo "notify-send -i \"$PIC\" \"Welcome to LARBS\" \"Press super+F1 for the help menu.\" # LARBSWELCOME" >> ~/.xprofile && + notify-send -i "$PIC" "LARBS welcome message" "Welcome message re-enabled." ) diff --git a/.local/bin/i3cmds/toggletouchpad b/.local/bin/i3cmds/toggletouchpad new file mode 100755 index 0000000..6d8c9c8 --- /dev/null +++ b/.local/bin/i3cmds/toggletouchpad @@ -0,0 +1,4 @@ +#!/bin/sh +# Toggle touchpad. Requires xf86-input-synaptics. +(synclient | grep "TouchpadOff.*1" && synclient TouchpadOff=0)>/dev/null && echo "TouchPad reactivated." && exit +synclient TouchpadOff=1 && echo "TouchPad deactivated." diff --git a/.local/bin/i3cmds/torwrap b/.local/bin/i3cmds/torwrap new file mode 100755 index 0000000..04e7a51 --- /dev/null +++ b/.local/bin/i3cmds/torwrap @@ -0,0 +1,6 @@ +#!/bin/sh +ifinstalled transmission-remote-cli transmission-cli || exit + +! pgrep -x transmission-da >/dev/null && transmission-daemon && notify-send "Starting torrent daemon..." && sleep 3 && pkill -RTMIN+7 i3blocks + +$TERMINAL -e transmission-remote-cli diff --git a/.local/bin/i3cmds/winresize b/.local/bin/i3cmds/winresize new file mode 100755 index 0000000..090bbf3 --- /dev/null +++ b/.local/bin/i3cmds/winresize @@ -0,0 +1,2 @@ +#!/bin/sh +echo "๐Ÿ“" | dmenu -p "Give width and height:" | xargs xdotool windowsize "$(xdotool getwindowfocus)" diff --git a/.local/bin/ifinstalled b/.local/bin/ifinstalled new file mode 100755 index 0000000..04c0eef --- /dev/null +++ b/.local/bin/ifinstalled @@ -0,0 +1,8 @@ +#!/bin/sh + +# Some optional functions in LARBS require programs not installed by default. I +# use this little script to check to see if a command exists and if it doesn't +# it informs the user that they need that command to continue. This is used in +# various other scripts for clarity's sake. + +pacman -Qq "$1" >/dev/null || { notify-send "๐Ÿ“ฆ $1" "must be installed for this function." && exit 1 ;} diff --git a/.local/bin/launch_polybar b/.local/bin/launch_polybar new file mode 100755 index 0000000..8786be6 --- /dev/null +++ b/.local/bin/launch_polybar @@ -0,0 +1,9 @@ +#!/bin/sh + +# Terminate already running bar instances +killall -q polybar + +# Wait until the processes have been shut down +while pidof polybar >/dev/null; do sleep 1; done + +for i in $(polybar -m | awk -F: '{print $1}'); do MONITOR=$i polybar default & done diff --git a/.local/bin/lf-select b/.local/bin/lf-select new file mode 100755 index 0000000..3b2a17a --- /dev/null +++ b/.local/bin/lf-select @@ -0,0 +1,9 @@ +#!/bin/sh + +# Reads file names from stdin and selects them in lf. + +while read -r file; do + [ -z "$file" ] && continue + lf -remote "send select \"$file\"" + lf -remote "send toggle" +done diff --git a/.local/bin/lmc b/.local/bin/lmc new file mode 100755 index 0000000..d431495 --- /dev/null +++ b/.local/bin/lmc @@ -0,0 +1,28 @@ +#!/bin/sh + +NUM="${2:-5}" + +# Uncomment the following line to use Pulseaudio. +# PULSE=true + +if [ "$PULSE" ]; then + toggle() { pulsemixer --toggle-mute ;} + mute() { pulsemixer --mute ;} + up() { pulsemixer --change-volume +"$NUM" ;} + down() { pulsemixer --change-volume -"$NUM" ;} + control() { pulsemixer ;} +else + toggle() { amixer sset Master toggle ;} + mute() { amixer sset Master mute ;} + up() { amixer sset Master "$NUM"%+ ;} + down() { amixer sset Master "$NUM"%- ;} + control() { alsamixer ;} +fi + +case "$1" in + toggle) toggle ;; + mute) mute ;; + up) up ;; + down) down ;; + control) control ;; +esac diff --git a/.local/bin/maimpick b/.local/bin/maimpick new file mode 100755 index 0000000..7125e61 --- /dev/null +++ b/.local/bin/maimpick @@ -0,0 +1,14 @@ +#!/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. + +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-"$(date '+%y%m%d-%H%M-%S').png" ;; + "current window") maim -i "$(xdotool getactivewindow)" pic-window-"$(date '+%y%m%d-%H%M-%S').png" ;; + "full screen") maim pic-full-"$(date '+%y%m%d-%H%M-%S').png" ;; + "a selected area (copy)") maim -s | xclip -selection clipboard -t image/png ;; + "current window (copy)") maim -i "$(xdotool getactivewindow)" | xclip -selection clipboard -t image/png ;; + "full screen (copy)") maim | xclip -selection clipboard -t image/png ;; +esac diff --git a/.local/bin/manga-py b/.local/bin/manga-py new file mode 100755 index 0000000..64af40b --- /dev/null +++ b/.local/bin/manga-py @@ -0,0 +1,12 @@ +#!/usr/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'manga-py==1.19.7','console_scripts','manga-py' +__requires__ = 'manga-py==1.19.7' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('manga-py==1.19.7', 'console_scripts', 'manga-py')() + ) diff --git a/.local/bin/markdown_py b/.local/bin/markdown_py new file mode 100755 index 0000000..ca0b785 --- /dev/null +++ b/.local/bin/markdown_py @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from markdown.__main__ import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/.local/bin/mpd-module-update b/.local/bin/mpd-module-update new file mode 100755 index 0000000..ced910f --- /dev/null +++ b/.local/bin/mpd-module-update @@ -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 && pkill -RTMIN+11 "${STATUSBAR:-dwmblocks}" || break +done diff --git a/.local/bin/muccadoro b/.local/bin/muccadoro new file mode 100755 index 0000000..63cbd90 --- /dev/null +++ b/.local/bin/muccadoro @@ -0,0 +1,304 @@ +#!/usr/bin/env bash +set -o nounset -o pipefail +# Before doing anything, check if the required programs are installed. See +# <https://stackoverflow.com/q/592620>. Some of these can probably be reasonably assumed +# to be present, but err on the side of caution. +for prog in awk cowsay figlet notify-send stty tput; do + if ! hash "$prog" 2>/dev/null; then + printf 'muccadoro: %s: command not found\n' "$prog" >&2 + exit 127 + fi +done + + +temp_loc=/tmp/pomptemptimes +temp_timeloc=/tmp/mucc_time +statusbar="dwmblocks" +update_signal="3" + +freetime=${2:-w} +if [ "$freetime" = "f" ]; then + temp_loc=/tmp/pomptemptimesft +fi + +declare -i silly=1 + +# http://mywiki.wooledge.org/BashFAQ/035#getopts +# http://wiki.bash-hackers.org/howto/getopts_tutorial +while getopts ':s' opt; do + case $opt in + s) (( ++silly ));; + esac +done +shift "$((OPTIND-1))" # Shift off the options and optional --. + +# One pomodoro lasts "$1" minutes. The default duration is 25 minutes. +declare -i duration=$((${1:-25}*60)) num_pomodoros=4 + +(( silly %= 5 )) +if (( silly )); then + declare -i silliness=$((2**(4-silly))) + # `apps` stands for appearances, of course. + declare -a apps=('' '-b' '-d' '-g' '-p' '-s' '-t' '-w' '-e oO' '-e Oo' '-e ><' '-e -o' + '-e o-' '-e >o' '-e o<') + num_apps=${#apps[@]} + cowtell() { + app_num=$((RANDOM % (silliness * num_apps))) + (( app_num >= num_apps )) && app_num=0 + cowsay -n ${apps[app_num]} + } +else + cowtell() { + cowsay -n + } +fi + +summary= + +# Standard output must be a terminal. See <https://unix.stackexchange.com/q/91638>. Save +# the original stdout to file descriptor 3 (see <https://unix.stackexchange.com/q/80988>). +exec 3>&1 &>/dev/tty + +# Save the current terminal settings. +initial_tty_settings=$(stty -g) + +# Revert all changed terminal settings (FIXME: restore everything from saved settings) and +# print a summary. +cleanup() { + tput rmcup + tput cnorm + stty "$initial_tty_settings" + [[ $summary ]] && echo -ne "$summary" >&3 + rm -f $temp_loc + rm -f $temp_timeloc + pkill -RTMIN+$update_signal $statusbar +} + +trap cleanup EXIT + +# Switch to the alternate screen. See <https://unix.stackexchange.com/q/27941>, xterm(1), +# terminfo(5), and <https://stackoverflow.com/q/11023929>. +tput smcup + +# TODO: explain. See +# <http://www.unix.com/shell-programming-and-scripting/176837-bash-hide-terminal-cursor.html>. +tput civis + +# Don't echo characters typed on the tty. See <https://unix.stackexchange.com/a/28620>. +stty -echo + +# Output empty lines before the message so the message is displayed at the bottom of the +# terminal. See <https://stackoverflow.com/a/29314659>. Also, instead of `clear`ing +# (which causes flickering), pad all lines of the message with spaces all the way to the +# right edge of the terminal, thereby overwriting any currently displayed characters. See +# <https://stackoverflow.com/questions/9394408>. TODO: probably just use Bash and not +# awk. +pad() { + awk -v lines="$(tput lines)" -v cols="$(tput cols)" ' + NR!=1 && FNR==1 { n=lines-NR; for(; n>0; n--) printf "%-"cols"s\n", "" } + NR==FNR { next } + { printf "%-"cols"s\n", $0 }' <(echo "$1"){,} +} + +pp() { + tput cup 0 0 # TODO: explain. + pad "$1" +} + +ppp() { + tput cup 0 0 + # FIXME: probably just check once if we have lolcat. + pad "$1" | { lolcat 2>/dev/null || cat; } +} + +declare -a lyrics +declare -i line_index=0 +lyrics=( + "Can't stop, addicted to the shindig;" + "Chop Top, he says I'm gonna win big;" + "Choose not a life of imitation;" + "Distant cousin to the reservation;" + "Defunct the pistol that you pay for;" + "This punk, the feeling that you stay for;" + "In time I want to be your best friend;" + "East side lovers living on the west end;" + "Knocked out but boy you better come to;" + "Don't die, you know the truth as some do;" + "Go write your message on the pavement;" + "Burn so bright I wonder what the wave meant;" +) + +declare -i state=0 + +cant-stop() { + (( state == 2 )) && return + state=2 + tty_settings=$(stty -g) + trap '' INT + stty susp undef + pp "$(cowsay -e '><' -W $(($(tput cols)-3)) ${lyrics[line_index]})" + + ((++line_index)); ((line_index%=${#lyrics[@]})) + sleep 2 & wait $! + stty "$tty_settings" + count-state +} + +# SIGTSTP handler. +on-tstp() { + # Signal all processes in the process group $$ (the group leader) to continue. See + # kill(1), and <https://unix.stackexchange.com/q/139222>. Pomodoros are not + # interruptible. + kill -CONT -- -$$ + if (( state == 1 )); then + cant-stop + fi +} +trap on-tstp TSTP + +count-state() { + # 130 is the exit status for termination by Ctrl-C. See + # <http://www.tldp.org/LDP/abs/html/exitcodes.html>. + trap 'trap on-int INT; on-int; return 130' INT + state=1 +} + +dead-state() { + trap on-int INT + state=0 +} + +pause-state() { + trap on-int INT + state=0 +} + +on-int() { + if (( state==0 )); then + # We are supposed to kill ourselves with SIGINT instead of using `exit`. See + # <http://mywiki.wooledge.org/SignalTrap#Special_Note_On_SIGINT>. + trap - INT + kill -INT $$ + elif (( state==1 )); then + dead-state + elif (( state==2 )); then + count-state + fi +} + +# XXX: beware of bugs due to SIGINT (Ctrl-C) being received during the short timeframe in +# which another function invoked by this one is executing. The `return 1` statement of +# the SIGINT trap will be ran in the context of the inner function. +pomodoro() { + count-state + while :; do + # Handle signals immediately, not after `sleep` exits. See + # <http://mywiki.wooledge.org/SignalTrap#When_is_the_signal_handled.3F>. + sleep 1 & + # See <http://mywiki.wooledge.org/BashFAQ/002>. + planned_end_time=$(( $start_time_secs + $duration )) + seconds=$(( $planned_end_time - $( date +'%s') )) + the_time=$((seconds/60)):$(printf '%02d' $((seconds%60))) + # Keep in mind that almost everything causes new values to be assigned to `$?`: + # $ false + # $ (( $? )) && echo $? + # 0 + # $ false || { (( $? != 148 )) && echo $?; } + # 0 + # In both cases, when `echo $?` is executed, `$?` is no longer 1. + fail=$? + if (( fail && fail != 148 )); then + return $fail + fi + text=$(figlet -f small "$the_time" ) #remove | cowtell + fail=$? + if (( ! fail )); then + pp "$text" + fail=$? + echo "$the_time" > $temp_timeloc + pkill -RTMIN+$update_signal $statusbar + (( fail && fail != 148 )) && return $fail + elif (( fail != 148 )); then + return $fail + fi + wait + ((--seconds <= 0)) && return 0 + done + return 1 +} + +flush-stdin() { + # See <https://superuser.com/q/276531>. + read -r -d '' -t 0.1 -n 1000 +} + +# FIXME: why `dummy` (http://wiki.bash-hackers.org/commands/builtin/read#press_any_key). +pause() { + # See <http://wiki.bash-hackers.org/syntax/pe#use_an_alternate_value>. + read -r -n 1${1:+ -t $1} +} + +for (( n=1; n<=num_pomodoros; ++n )); do + declare -i seconds=$duration + declare -i start_time_secs=$(date +'%s') + start_time=$(date --date "@$start_time_secs" +'%H:%M') + pomodoro + fail=$? + if (( fail == 130 )); then + end_time=$(date +'%H:%M') + end_time_secs=$(date -d $end_time +'%s') + day=$(date '+%Y%b%d') + summary+="Abandoned: $start_time to $end_time ($((($end_time_secs - $start_time_secs)/ 60))) $day\n" + #summary+="Abandoned: $start_time to $(date +'%H:%M')\n" + # Pomodoros are atomic. + pp "$(cowsay -d -W $(($(tput cols)-3)) 'You abandoned pomodoro '$n'. Press any' \ + 'key to restart it.')" + rm -f $temp_timeloc + pkill -RTMIN+$update_signal $statusbar + pause + (( --n )) + continue + elif (( fail )); then + exit $fail + fi + pause-state + tty_settings=$(stty -g) + stty susp undef + end_time_secs=$(date +'%s') + end_time=$(date --date "@$end_time_secs" +'%H:%M') + #end_time_secs=$(date -d $end_time +'%s') + #start_time_secs=$(date -d $start_time +'%s') + day=$(date '+%Y%b%d') + summary+="Pomodoro $n: $start_time to $end_time ($(( ($end_time_secs - $start_time_secs )/60))) $day\n" + #summary+="Pomodoro $n: $start_time to $(date +'%H:%M') \n" + if (( n!=num_pomodoros )); then + start_time=$(date +'%s') + notify-send "You completed pomodoro $n. Take a short break (3-5 minutes)." + # + # + echo "($n*$duration)/60" | bc > $temp_loc + pkill -RTMIN+$update_signal $statusbar + # TODO: it may be nice to create this message asynchronously with `lolcat -f` since + # lolcat is a bit slow. That's not a priority, though. + ppp "$(cowsay -e '^^' -W $(($(tput cols)-3)) 'You completed pomodoro '$n'. Take' \ + 'a short break (3-5 minutes), then press any key to continue.')" + rm -f $temp_timeloc + pkill -RTMIN+$update_signal $statusbar + flush-stdin + if ! pause 180; then + pp "$(cowsay -w -W $(($(tput cols)-3)) 'Press any key to continue.')" + pause 120 || { + notify-send -u critical 'Time to start the next pomodoro.'; pause; + } + fi + break_duration=$((($(date +'%s')-start_time+30)/60)) + summary+="Break: about $break_duration minute" + (( break_duration != 1 )) && summary+=s # plural + summary+='\n' + fi + stty "$tty_settings" +done + +notify-send "You completed all $num_pomodoros pomodoros!" + +# vim: tw=90 sts=-1 sw=3 et diff --git a/.local/bin/opout b/.local/bin/opout new file mode 100755 index 0000000..28af763 --- /dev/null +++ b/.local/bin/opout @@ -0,0 +1,13 @@ +#!/bin/sh + +# opout: "open output": A general handler for opening a file's intended output, +# usually the pdf of a compiled document. I find this useful especially +# running from vim. + +basename="$(echo "$1" | sed 's/\.[^\/.]*$//')" + +case "$1" in + *.tex|*.m[dse]|*.[rR]md|*.mom|*.[0-9]) setsid xdg-open "$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/pauseallmpv b/.local/bin/pauseallmpv new file mode 100755 index 0000000..15b9f59 --- /dev/null +++ b/.local/bin/pauseallmpv @@ -0,0 +1,10 @@ +#!/bin/sh + +# You might notice all mpv commands are aliased to have this input-ipc-server +# thing. That's just for this particular command, which allows us to pause +# every single one of them with one command! This is bound to super + shift + p +# (with other things) by default and is used in some other places. + +for i in $(ls /tmp/mpvSockets/*); do + echo '{ "command": ["set_property", "pause", true] }' | socat - $i; +done diff --git a/.local/bin/podentr b/.local/bin/podentr new file mode 100755 index 0000000..9a8313a --- /dev/null +++ b/.local/bin/podentr @@ -0,0 +1,7 @@ +#!/bin/sh + +# entr command to run `queueandnotify` when newsboat queue is changed + +[ "$(pgrep -x $(basename $0) | wc -l)" -gt 2 ] && exit + +echo ${XDG_DATA_HOME:-$HOME/.local/share}/newsboat/queue | entr -p queueandnotify 2>/dev/null diff --git a/.local/bin/pom b/.local/bin/pom new file mode 100755 index 0000000..2852042 --- /dev/null +++ b/.local/bin/pom @@ -0,0 +1,13 @@ +#!/bin/sh +SAVE_DIR=~/eth/pomodoros +case $1 in + add) start=$2 + start_secs=$(date -d $start +'%s') + end=$3 + end_secs=$(date -d $end +'%s') + duration="$(( ($end_secs - $start_secs)/60 ))" + echo "Pomodoro 1: $start to $end ($duration) $(date '+%Y%b%d')" | tee -ai $SAVE_DIR;; + *) xdotool key super+shift+9 + muccadoro $1 | tee -ai "$SAVE_DIR";; +esac +pkill -RTMIN+3 dwmblocks diff --git a/.local/bin/pomft b/.local/bin/pomft new file mode 100755 index 0000000..aeef88d --- /dev/null +++ b/.local/bin/pomft @@ -0,0 +1,12 @@ +#!/bin/sh +SAVE_DIR=~/bks/pomodoros_freetime +case $1 in + add) start=$2 + start_secs=$(date -d $start +'%s') + end=$3 + end_secs=$(date -d $end +'%s') + duration="$(( ($end_secs - $start_secs)/60 ))" + echo "Pomodoro 1: $start to $end ($duration) $(date '+%Y%b%d')" | tee -ai $SAVE_DIR;; + *) muccadoro ${1:-25} 'f' | tee -ai "$SAVE_DIR";; +esac +pkill -RTMIN+3 dwmblocks diff --git a/.local/bin/prompt b/.local/bin/prompt new file mode 100755 index 0000000..cda9a4a --- /dev/null +++ b/.local/bin/prompt @@ -0,0 +1,8 @@ +#!/bin/sh + +# A dmenu binary prompt script. +# Gives a dmenu prompt labeled with $1 to perform command $2. +# For example: +# `./prompt "Do you want to shutdown?" "shutdown -h now"` + +[ "$(printf "No\\nYes" | dmenu -i -n -p "$1" -nb darkred -sb red -sf white -nf gray )" = "Yes" ] && $2 diff --git a/.local/bin/pyls b/.local/bin/pyls new file mode 100755 index 0000000..681e269 --- /dev/null +++ b/.local/bin/pyls @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pyls.__main__ import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.local/bin/qndl b/.local/bin/qndl new file mode 100755 index 0000000..f5bd14f --- /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="youtube-dl --add-metadata" +idnum="$(tsp $cmd "$1")" +realname="$(echo "$base" | sed "s/?\(source\|dest\).*//;s/%20/ /g")" +tsp -D "$idnum" mv "$base" "$realname" +tsp -D "$idnum" notify-send "๐Ÿ‘ $realname done." diff --git a/.local/bin/queueandnotify b/.local/bin/queueandnotify new file mode 100755 index 0000000..a54b13e --- /dev/null +++ b/.local/bin/queueandnotify @@ -0,0 +1,14 @@ +#!/bin/sh + +# Podboat sucks. This script replaces it. +# It reads the newsboat queue, queuing downloads with taskspooler. +# It also removes the junk from extentions. +queuefile="${XDG_DATA_HOME:-$HOME/.local/share}/newsboat/queue" + +while read -r line; do + [ -z "$line" ] && continue + url="$(echo "$line" | awk '{print $1}')" + qndl "$url" "curl -LO" +done < "$queuefile" + +echo > "$queuefile" diff --git a/.local/bin/refbar b/.local/bin/refbar new file mode 100755 index 0000000..78b5018 --- /dev/null +++ b/.local/bin/refbar @@ -0,0 +1,5 @@ +#!/bin/sh + +# Refresh the dwmbar. +# Send SIGTRAP signal to dwmbar script, which will handle it with a trap. +pkill -SIGTRAP dwmbar diff --git a/.local/bin/remaps b/.local/bin/remaps new file mode 100755 index 0000000..13f3776 --- /dev/null +++ b/.local/bin/remaps @@ -0,0 +1,11 @@ +#!/bin/sh + +# This script is called on startup to remap keys. +# Increase key speed via a rate change +xset r rate 300 50 +# Map the caps lock key to super... +setxkbmap -option caps:super -variant intl +# But when it is pressed only once, treat it as escape. +killall xcape 2>/dev/null ; xcape -e 'Super_L=Escape' +# Map the menu button to right super as well. +xmodmap -e 'keycode 135 = Super_R' diff --git a/.local/bin/samedir b/.local/bin/samedir new file mode 100755 index 0000000..73facfd --- /dev/null +++ b/.local/bin/samedir @@ -0,0 +1,8 @@ +#!/bin/sh + +# Open a terminal window in the same directory as the currently active window. + +PID=$(xprop -id "$(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}')" | grep -m 1 PID | cut -d " " -f 3) +PID="$(pstree -lpA "$PID" | tail -n 1 | awk -F'---' '{print $NF}' | sed -re 's/[^0-9]//g')" +cd "$(readlink /proc/"$PID"/cwd)" || return 1 +"$TERMINAL" diff --git a/.local/bin/setbg b/.local/bin/setbg new file mode 100755 index 0000000..ea35e16 --- /dev/null +++ b/.local/bin/setbg @@ -0,0 +1,20 @@ +#!/bin/sh + +# This script does the following: +# Run by itself, set the wallpaper (at X start). +# If given a file, set that as the new wallpaper. +# If given a directory, choose random file in it. +# If wal is installed, also generates a colorscheme. + +# Location of link to wallpaper link. +bgloc="${XDG_DATA_HOME:-$HOME/.local/share/}/bg" + +[ -f "$1" ] && ln -sf "$(readlink -f "$1")" "$bgloc" && notify-send -i "$bgloc" "Changing wallpaper..." + +[ -d "$1" ] && ln -sf "$(find "$(readlink -f "$1")" -iregex '.*.\(jpg\|jpeg\|png\|gif\)' -type f | shuf -n 1)" "$bgloc" && notify-send -i "$bgloc" "Random Wallpaper chosen." + +# If pywal is installed, use it. +wal -s -i "$(readlink -f "$bgloc")" -o "${XDG_CONFIG_HOME:-$HOME/.config}/wal/postrun" >/dev/null 2>&1 + +pidof dwm >/dev/null && xdotool key super+F12 +xwallpaper --zoom "$bgloc" diff --git a/.local/bin/shortcuts b/.local/bin/shortcuts new file mode 100755 index 0000000..19d3ffd --- /dev/null +++ b/.local/bin/shortcuts @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# Output locations. Unactivated progs should go to /dev/null. +shell_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/shortcutrc" +zsh_named_dirs="${XDG_CONFIG_HOME:-$HOME/.config}/zshnameddirrc" +ranger_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/ranger/shortcuts.conf" +qute_shortcuts="/dev/null" +fish_shortcuts="/dev/null" +vifm_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/vifm/vifmshortcuts" + +# Remove, prepare files +rm -f "$ranger_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" 2>/dev/null +printf "# vim: filetype=sh\\n" > "$fish_shortcuts" +printf "# vim: filetype=sh\\nalias " > "$shell_shortcuts" +printf "\" vim: filetype=vim\\n" > "$vifm_shortcuts" + +# Format the `directories` file in the correct syntax and sent it to all three configs. +sed "s/\s*#.*$//;/^\s*$/d" "${XDG_CONFIG_HOME:-$HOME/.config}/directories" | tee >(awk '{print $1"=\"cd "$2" && ls -a\" \\"}' >> "$shell_shortcuts") \ + >(awk '{print "hash -d "$1"="$2}' >> "$zsh_named_dirs") \ + >(awk '{print "abbr", $1, "\"cd " $2 "; and ls -a\""}' >> "$fish_shortcuts") \ + >(awk '{print "map g" $1, ":cd", $2 "<CR>\nmap t" $1, "<tab>:cd", $2 "<CR><tab>\nmap M" $1, "<tab>:cd", $2 "<CR><tab>:mo<CR>\nmap Y" $1, "<tab>:cd", $2 "<CR><tab>:co<CR>" }' >> "$vifm_shortcuts") \ + >(awk '{print "config.bind(\";"$1"\", \"set downloads.location.directory "$2" ;; hint links download\")"}' >> "$qute_shortcuts") \ + | awk '{print "map g"$1" cd "$2"\nmap t"$1" tab_new "$2"\nmap m"$1" shell mv -v %s "$2"\nmap Y"$1" shell cp -rv %s "$2}' >> "$ranger_shortcuts" + +# Format the `files` file in the correct syntax and sent it to both configs. +sed "s/\s*#.*$//;/^\s*$/d" "${XDG_CONFIG_HOME:-$HOME/.config}/files" | tee >(awk '{print $1"=\"$EDITOR "$2"\" \\"}' >> "$shell_shortcuts") \ + >(awk '{print "abbr", $1, "\"$EDITOR "$2"\""}' >> "$fish_shortcuts") \ + >(awk '{print "map", $1, ":e", $2 "<CR>" }' >> "$vifm_shortcuts") \ + | awk '{print "map "$1" shell $EDITOR "$2}' >> "$ranger_shortcuts" diff --git a/.local/bin/showclip b/.local/bin/showclip new file mode 100755 index 0000000..d2faff8 --- /dev/null +++ b/.local/bin/showclip @@ -0,0 +1,10 @@ +#!/bin/sh + +# Display contents of selection via dunst if running. +# Separate script for i3. + +clip=$(xclip -o -selection clipboard) +prim=$(xclip -o -selection primary) + +[ -n "$clip" ] && notify-send "Clipboard:" "$clip" +[ -n "$prim" ] && notify-send "Primary:" "$prim" diff --git a/.local/bin/statusbar/battery b/.local/bin/statusbar/battery new file mode 100755 index 0000000..97868bb --- /dev/null +++ b/.local/bin/statusbar/battery @@ -0,0 +1,27 @@ +#!/bin/sh + +# Prints all batteries, their percentage remaining and an emoji corresponding +# to charge status (๐Ÿ”Œ for plugged up, ๐Ÿ”‹ for discharging on battery, etc.). + +case $BLOCK_BUTTON in + 3) notify-send "๐Ÿ”‹ Battery module" "๐Ÿ”‹: discharging +๐Ÿ›‘: not charging +โ™ป: stagnant charge +๐Ÿ”Œ: charging +โšก: charged +โ—: battery very low!" ;; +esac + +# Loop through all attached batteries. +for battery in /sys/class/power_supply/BAT? +do + # Get its remaining capacity and charge status. + capacity=$(cat "$battery"/capacity) || break + status=$(sed "s/Discharging/๐Ÿ”‹/;s/Not charging/๐Ÿ›‘/;s/Charging/๐Ÿ”Œ/;s/Unknown/โ™ป๏ธ/;s/Full/โšก/" "$battery"/status) + + # If it is discharging and 25% or less, we will add a โ— as a warning. + [ "$capacity" -le 25 ] && [ "$status" = "๐Ÿ”‹" ] && warn="โ—" + + printf "%s%s%s%% " "$status" "$warn" "$capacity" + unset warn +done | sed 's/ *$//' diff --git a/.local/bin/statusbar/battery_dwm b/.local/bin/statusbar/battery_dwm new file mode 100755 index 0000000..a779289 --- /dev/null +++ b/.local/bin/statusbar/battery_dwm @@ -0,0 +1,32 @@ +#!/bin/sh +# Give a battery name (e.g. BAT0) as an argument. + +case $BLOCK_BUTTON in + 3) pgrep -x dunst >/dev/null && notify-send "๐Ÿ”‹ Battery module" "๐Ÿ”‹: discharging +๐Ÿ›‘: not charging +โ™ป: stagnant charge +๐Ÿ”Œ: charging +โšก: charged +โ—: battery very low! +- Text color reflects charge left" ;; +esac + +capacity=$(cat /sys/class/power_supply/"$1"/capacity 2>/dev/null) || exit +status=$(cat /sys/class/power_supply/"$1"/status) + +if [ "$capacity" -ge 75 ]; then + color="#00ff00" +elif [ "$capacity" -ge 50 ]; then + color="#ffffff" +elif [ "$capacity" -ge 25 ]; then + color="#ffff00" +else + color="#ff0000" + warn="โ—" +fi + +[ -z $warn ] && warn=" " + +[ "$status" = "Charging" ] && color="#ffffff" + +printf "%s%s%s" "$(echo "$status" | sed -e "s/,//;s/Discharging/๐Ÿ”‹/;s/Not Charging/๐Ÿ›‘/;s/Charging/๐Ÿ”Œ/;s/Unknown/โ™ป/Full/โšก/;s/ 0*/ /g;s/ :/ /g")" "$warn" "$(echo "$capacity" | sed -e 's/$/%/')" diff --git a/.local/bin/statusbar/battery_personal b/.local/bin/statusbar/battery_personal new file mode 100755 index 0000000..de783c2 --- /dev/null +++ b/.local/bin/statusbar/battery_personal @@ -0,0 +1,32 @@ +#!/bin/sh +# Give a battery name (e.g. BAT0) as an argument. + +case $BLOCK_BUTTON in + 3) pgrep -x dunst >/dev/null && notify-send "๐Ÿ”‹ Battery module" "๐Ÿ”‹: discharging +๐Ÿ›‘: not charging +โ™ป: stagnant charge +๐Ÿ”Œ: charging +โšก: charged +โ—: battery very low! +- Text color reflects charge left" ;; +esac + +capacity=$(cat /sys/class/power_supply/"$1"/capacity) || exit +status=$(cat /sys/class/power_supply/"$1"/status) + +if [ "$capacity" -ge 75 ]; then + color="#00ff00" +elif [ "$capacity" -ge 50 ]; then + color="#ffffff" +elif [ "$capacity" -ge 25 ]; then + color="#ffff00" +else + color="#ff0000" + warn="โ•" +fi + +[ -z $warn ] && warn=" " + +[ "$status" = "Charging" ] && color="#ffffff" + +printf "<span color='%s'>%s%s%s</span>" "$color" "$(echo "$status" | sed -e "s/,//;s/Discharging/๐Ÿ”‹/;s/Not charging/๐Ÿ›‘/;s/Charging/๐Ÿ”Œ/;s/Unknown//;s/Full/โšก/;s/ 0*/ /g;s/ :/ /g")" "$warn" "$(echo "$capacity" | sed -e 's/$/%/')" diff --git a/.local/bin/statusbar/btstatus b/.local/bin/statusbar/btstatus new file mode 100755 index 0000000..be8dec5 --- /dev/null +++ b/.local/bin/statusbar/btstatus @@ -0,0 +1,2 @@ +#!/bin/bash +bluetoothctl show | grep Powered | awk '{print $2}' | sed "s/no//; s/yes/๐ŸŽง/" diff --git a/.local/bin/statusbar/clock b/.local/bin/statusbar/clock new file mode 100755 index 0000000..fd1efb2 --- /dev/null +++ b/.local/bin/statusbar/clock @@ -0,0 +1,3 @@ +#!/bin/sh + +date '+%H:%M' diff --git a/.local/bin/statusbar/corona b/.local/bin/statusbar/corona new file mode 100755 index 0000000..8858bfe --- /dev/null +++ b/.local/bin/statusbar/corona @@ -0,0 +1,11 @@ +#!/bin/bash +( [ "$(stat -c %y ~/.cache/corona | cut -d' ' -f1)" != "$(date '+%Y-%m-%d')" ] || [ "$1" = "up" ] )&& + curl -s https://corona-stats.online/Switzerland | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g" > ~/.cache/corona && notify-send "Corona" "Stats updated"; sleep 5; pkill -RTMIN+15 dwmblocks + +increase=$( grep "Switzerland" ~/.cache/corona | + sed "s/\s*//g; s/โ•‘//g; s/โ”‚/;/g" | awk -F';' '{print $4}' ) +[ "$increase" != "" ] && ( grep "Switzerland" ~/.cache/corona | + sed "s/\s*//g; s/โ•‘//g; s/โ”‚/;/g" | + awk -F';' '{print "๐Ÿ˜ท"$3 " ("$4") ๐Ÿ’€"$5 }' ) || ( grep "Switzerland" ~/.cache/corona | + sed "s/\s*//g; s/โ•‘//g; s/โ”‚/;/g" | + awk -F';' '{print "๐Ÿ˜ท"$3 " ๐Ÿ’€"$5 }' ) diff --git a/.local/bin/statusbar/cpu b/.local/bin/statusbar/cpu new file mode 100755 index 0000000..bfcf15d --- /dev/null +++ b/.local/bin/statusbar/cpu @@ -0,0 +1,12 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) notify-send "๐Ÿ–ฅ CPU hogs" "$(ps axch -o cmd:15,%cpu --sort=-%cpu | head)" ;; + 3) notify-send "๐Ÿ–ฅ CPU module " "\- Shows CPU temperature. +- Click to show intensive processes. +- % is of single core." ;; +esac + +temp=$(sensors | awk '/Package id 0/ {print "๐ŸŒก "$4}' | sed 's/\.[0-9]//; s/+//') +[ -n "$temp" ] && echo $temp > /tmp/cpu_temp +cat /tmp/cpu_temp diff --git a/.local/bin/statusbar/crypto b/.local/bin/statusbar/crypto new file mode 100755 index 0000000..31e88b3 --- /dev/null +++ b/.local/bin/statusbar/crypto @@ -0,0 +1,53 @@ +#!/bin/sh + +# Shows the price for desired cryptocurrencies. Module updates automatically +# every calendar day, but can also be updated with a middle click. + +# Currencies should be ;-separated: +# human-readable name;urlname;icon +coins="Bitcoin;btc;๐Ÿ’ฐ +Etherium;eth;๐Ÿธ +Basic Attention Token;bat;๐Ÿฆ +LBC;lbc;๐Ÿ“š" + +# Directory where currency info is stored. +dir="${XDG_DATA_HOME:-$HOME/.local/share}/crypto-prices" + +getprices() { # The command to get the desired prices + printf "๐Ÿ”ƒ "; printprices + { rm -rf "${dir:?}/*" + echo "$coins" | while IFS=';' read -r human web icon; do + val="$(curl -s "rate.sx/1$web")" && + echo "$icon;$val;$human" > "$dir/$web" + done; [ -d "$dir" ] && touch "$dir" + pkill -RTMIN+13 "${STATUSBAR:-dwmblocks}" ;} & + exit + } + +printprices() { # Print/format all prices + for x in "$dir"/*; do + [ -f "$x" ] || break + info="$(cut -d';' -f-2 --output-delimiter=' ' "$x")" + printf "%s $%0.2f " $info + done | sed 's/ $//' + } + +[ ! -d "$dir" ] && mkdir -p "$dir" && { getprices; exit ;} + +# If currencies haven't been updated today, try to update them. +[ "$(stat -c %x "$HOME/.local/share/crypto-prices" | cut -d' ' -f1)" != "$(date '+%Y-%m-%d')" ] && + { ping -q -c 1 1.1.1.1 >/dev/null 2>&1 && getprices || exit ;} + +case $BLOCK_BUTTON in + 1) uptime="$(date -d "$(stat -c %x "$dir")" '+%D at %T' | sed "s|$(date '+%D')|Today|")" + notify-send "Exact prices in USD" "$(awk -F';' '{print $1, $3 ":\n\t$" $2}' "$dir"/*) +<b>Last updated:</b> + $uptime" ;; + 2) getprices ;; + 3) notify-send "๐Ÿ’ธ Crypto-currency module" "\- Left click for exact prices. +- Middle click to update. +- Shows ๐Ÿ”ƒ if updating prices. +- Manually add/remove currencies to list in the script." ;; +esac + +printprices diff --git a/.local/bin/statusbar/current_day b/.local/bin/statusbar/current_day new file mode 100755 index 0000000..9321986 --- /dev/null +++ b/.local/bin/statusbar/current_day @@ -0,0 +1,2 @@ +#!/bin/sh +date '+%a %b %d' diff --git a/.local/bin/statusbar/disk b/.local/bin/statusbar/disk new file mode 100755 index 0000000..d3dd07d --- /dev/null +++ b/.local/bin/statusbar/disk @@ -0,0 +1,18 @@ +#!/bin/sh + +# Status bar module for disk space +# $1 should be drive mountpoint +# $2 is optional icon, otherwise mountpoint will displayed + +[ -z "$1" ] && exit + +icon="$2" +[ -z "$2" ] && icon="$1" + +case $BLOCK_BUTTON in + 1) pgrep -x dunst >/dev/null && notify-send "๐Ÿ’ฝ Disk space" "$(df -h --output=target,used,size)" ;; + 3) pgrep -x dunst >/dev/null && notify-send "๐Ÿ’ฝ Disk module" "\- Shows used hard drive space. +- Click to show all disk info." ;; +esac + +printf "%s: %s" "$icon" "$(df -h "$1" | awk ' /[0-9]/ {print $3 "/" $2}')" diff --git a/.local/bin/statusbar/getbright b/.local/bin/statusbar/getbright new file mode 100755 index 0000000..06617ab --- /dev/null +++ b/.local/bin/statusbar/getbright @@ -0,0 +1,2 @@ +#!/bin/bash +echo โ˜€ $(bc <<< "scale=0; $(cat /sys/class/backlight/intel_backlight/brightness) /9.37")% diff --git a/.local/bin/statusbar/getmail b/.local/bin/statusbar/getmail new file mode 100755 index 0000000..7288e63 --- /dev/null +++ b/.local/bin/statusbar/getmail @@ -0,0 +1,3 @@ +#!/bin/bash +num=$(find ~/.local/share/mail/*/INBOX/new -type f | wc -l) +[ $num != 0 ] && echo "๐Ÿ“ฌ "$num diff --git a/.local/bin/statusbar/getpomminutes b/.local/bin/statusbar/getpomminutes new file mode 100755 index 0000000..d9cac76 --- /dev/null +++ b/.local/bin/statusbar/getpomminutes @@ -0,0 +1,6 @@ +#!/bin/bash +day=$(date '+%Y%b%d') +logged=$(grep -v Break ~/eth/pomodoros | grep $(date '+%Y%b%d') | grep -Eo "\(.*\)" | paste -sd+ | bc) +temp=$(cat /tmp/pomptemptimes 2>/dev/null) +min=$([ "$logged" != "" ] && ([ "$temp" != "" ] && echo "$logged + $temp" | bc || echo $logged ) || ([ "$temp" != "" ] && echo $temp)) +[ -n "$min" ] && echo '๐Ÿ…'$min diff --git a/.local/bin/statusbar/getpomminutesft b/.local/bin/statusbar/getpomminutesft new file mode 100755 index 0000000..0678715 --- /dev/null +++ b/.local/bin/statusbar/getpomminutesft @@ -0,0 +1,6 @@ +#!/bin/bash +day=$(date '+%Y%b%d') +logged=$(grep -v Break ~/bks/pomodoros_freetime | grep $(date '+%Y%b%d') | grep -Eo "\(.*\)" | paste -sd+ | bc) +temp=$(cat /tmp/pomptemptimesft 2>/dev/null) +min=$([ "$logged" != "" ] && ([ "$temp" != "" ] && echo "$logged + $temp" | bc || echo $logged ) || ([ "$temp" != "" ] && echo $temp)) +[ -n "$min" ] && echo '๐Ÿ“š'$min diff --git a/.local/bin/statusbar/headset_connected b/.local/bin/statusbar/headset_connected new file mode 100755 index 0000000..c4a647b --- /dev/null +++ b/.local/bin/statusbar/headset_connected @@ -0,0 +1,2 @@ +#!/bin/bash +pactl list sinks | grep -qE 'device.icon_name = \"audio-(headset|headphones)-bluetooth\"' && echo ๐ŸŽง diff --git a/.local/bin/statusbar/help b/.local/bin/statusbar/help new file mode 100755 index 0000000..4916d5c --- /dev/null +++ b/.local/bin/statusbar/help @@ -0,0 +1,7 @@ +#!/bin/sh +case $BLOCK_BUTTON in + 1) groff -mom ~/.local/share/larbs/readme.mom -Tpdf | zathura - ;; + 2) i3 restart ;; + 3) pgrep -x dunst >/dev/null && notify-send "โ“ Help module" "\- Left click to open LARBS guide. +- Middle click to refresh i3.";; +esac; echo "โ“" diff --git a/.local/bin/statusbar/help-icon b/.local/bin/statusbar/help-icon new file mode 100755 index 0000000..4d8e3c2 --- /dev/null +++ b/.local/bin/statusbar/help-icon @@ -0,0 +1,16 @@ +#!/bin/sh + +# The clickable help menu. Middle click to restart wm. + +# If dwm is running, use dwm's readme and restart. +ps ax | grep -q "\sdwm$" && + READMEFILE=/usr/local/share/dwm/larbs.mom + restartwm() { pkill -HUP dwm ;} || + restartwm() { i3 restart ;} + +case $BLOCK_BUTTON in + 1) groff -mom "${READMEFILE:-${XDG_DATA_HOME:-$HOME/.local/share}/larbs/readme.mom}" -Tpdf | zathura - ;; + 2) restartwm ;; + 3) notify-send "โ“ Help module" "\- Left click to open LARBS guide. +- Middle click to refresh window manager.";; +esac; echo "โ“" diff --git a/.local/bin/statusbar/internet b/.local/bin/statusbar/internet new file mode 100755 index 0000000..ad9bee5 --- /dev/null +++ b/.local/bin/statusbar/internet @@ -0,0 +1,19 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) $TERMINAL -e nmtui ;; + 3) pgrep -x dunst >/dev/null && notify-send "๐ŸŒ Internet module" "\- Click to connect +๐Ÿ“ก: no wifi connection +๐Ÿ“ถ: wifi connection with quality +โŽ: no ethernet +๐ŸŒ: ethernet working +" ;; +esac + +[ "$(cat /sys/class/net/w*/operstate)" = 'down' ] && wifiicon="๐Ÿ“ก" + +[ ! -n "${wifiicon+var}" ] && wifiicon="๐Ÿ“ถ" +#[ ! -n "${wifiicon+var}" ] && wifiicon=$(grep "^\s*w" /proc/net/wireless | awk '{ print "๐Ÿ“ถ", int($3 * 100 / 70) "%" }') + + +printf "%s%s" "$wifiicon" "$(cat /sys/class/net/w*/operstate | sed "s/down/โŽ/;s/up/๐ŸŒ/")" diff --git a/.local/bin/statusbar/iplocate b/.local/bin/statusbar/iplocate new file mode 100755 index 0000000..4ca4f10 --- /dev/null +++ b/.local/bin/statusbar/iplocate @@ -0,0 +1,9 @@ +#!/bin/sh + +# Gets your public ip address checks which country you are in and +# displays that information in the statusbar +# +# https://www.maketecheasier.com/ip-address-geolocation-lookups-linux/ +ifinstalled "geoiplookup" || exit +addr="$(curl ifconfig.me 2>/dev/null)" || exit +grep "flag: " ~/.config/emoji | grep "$(geoiplookup $addr | sed 's/.*, //')" | sed "s/flag: //;s/;.*//" diff --git a/.local/bin/statusbar/mailbox b/.local/bin/statusbar/mailbox new file mode 100755 index 0000000..21c85ab --- /dev/null +++ b/.local/bin/statusbar/mailbox @@ -0,0 +1,16 @@ +#!/bin/sh + +# i3blocks mail module. +# Displays number of unread mail and an loading icon if updating. +# When clicked, brings up `neomutt`. + +case $BLOCK_BUTTON in + 1) "$TERMINAL" -e neomutt ;; + 2) setsid mailsync >/dev/null & ;; + 3) pgrep -x dunst >/dev/null && notify-send "๐Ÿ“ฌ Mail module" "\- Shows unread mail +- Shows ๐Ÿ”ƒ if syncing mail +- Left click opens neomutt +- Middle click syncs mail" ;; +esac + +echo "$(du -a ~/.local/share/mail/*/INBOX/new/* 2>/dev/null | sed -n '$=')$(cat /tmp/imapsyncicon_$USER 2>/dev/null)" diff --git a/.local/bin/statusbar/memory b/.local/bin/statusbar/memory new file mode 100755 index 0000000..dfd3d7b --- /dev/null +++ b/.local/bin/statusbar/memory @@ -0,0 +1,9 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) notify-send "๐Ÿง  Memory hogs" "$(ps axch -o cmd:15,%mem --sort=-%mem | head)" ;; + 3) notify-send "๐Ÿง  Memory module" "\- Shows Memory Used/Total. +- Click to show memory hogs." ;; +esac + +free -h | awk '/^Mem:/ {print $3 "/" $2}' diff --git a/.local/bin/statusbar/moonphase b/.local/bin/statusbar/moonphase new file mode 100755 index 0000000..12ed90b --- /dev/null +++ b/.local/bin/statusbar/moonphase @@ -0,0 +1,25 @@ +#!/bin/sh + +# Shows the current moon phase. Requires `pom-perl`. + +mnphs=$(pom $1 | grep -o 'New\|Waxing Crescent\|First Quarter\|Waxing Gibbous\|Full\|Waning Gibbous\|Last Quarter\|Waning Crescent' | grep -m1 '.') +prcnt=$(pom $1 | grep -o '[[:digit:]]*%' | grep -o '[[:digit:]]*' ) +case "$mnphs" in + "New") icon="๐ŸŒ‘" prcnt="0" ;; + "Waxing Crescent") icon="๐ŸŒ’" ;; + "First Quarter") icon="๐ŸŒ“" prcnt="50" ;; + "Waxing Gibbous") icon="๐ŸŒ”" ;; + "Full") icon="๐ŸŒ•" prcnt="100" ;; + "Waning Gibbous") icon="๐ŸŒ–" ;; + "Last Quarter") icon="๐ŸŒ—" prcnt="50" ;; + "Waning Crescent") icon="๐ŸŒ˜" ;; + *) echo errorrrr ;; +esac + +case $BLOCK_BUTTON in + 1) $mnphs ;; + 2) $mnphs ;; + 3) notify-send " ๐ŸŒœ$(pom)" ;; +esac + +echo "$icon" "$prcnt"% diff --git a/.local/bin/statusbar/mpdupdate b/.local/bin/statusbar/mpdupdate new file mode 100755 index 0000000..cd45481 --- /dev/null +++ b/.local/bin/statusbar/mpdupdate @@ -0,0 +1,9 @@ +#!/bin/sh +# Whenever the mpd state changes, update the mpd i3 module. +#kill -0 "$(cat /tmp/mpdupdate)" 2>/dev/null && exit || echo $$ > /tmp/mpdupdate + +#sleep 5 && while : ; do + #pkill -RTMIN+11 dwmblocks + #mpc idle >/dev/null || exit +#done +pkill -RTMIN+11 dwmblocks diff --git a/.local/bin/statusbar/music b/.local/bin/statusbar/music new file mode 100755 index 0000000..0bff061 --- /dev/null +++ b/.local/bin/statusbar/music @@ -0,0 +1,10 @@ +#!/bin/sh +if [ $( mpc status | grep '\[paused\]' | wc -l ) -eq 1 ]; then + echo "" + exit +fi + +if [ $( mpc status | grep '\[playing\]' | wc -l ) -eq 1 ]; then + echo $(mpc status | sed "/^volume:/d" | tac | sed -e "s/\\[paused\\].*//g;s/\\[playing\\].*//g" | tr -d '\n' | sed -e "s/$/ /g") + exit +fi diff --git a/.local/bin/statusbar/music_old b/.local/bin/statusbar/music_old new file mode 100755 index 0000000..93c2c9c --- /dev/null +++ b/.local/bin/statusbar/music_old @@ -0,0 +1,18 @@ +#!/bin/sh + +filter() { + sed "/^volume:/d" | tac | sed -e "s/\\&/&/g;s/\\[paused\\].*/<span color=\"gray\" font_style=\"italic\">/g;s/\\[playing\\].*/<span>/g" | tr -d '\n' | sed -e "s/$/<\\/span>/g" + } + +case $BLOCK_BUTTON in + 1) mpc status | filter && setsid "$TERMINAL" -e ncmpcpp & ;; # right click, pause/unpause + 2) mpc toggle | filter ;; # right click, pause/unpause + 3) mpc status | filter && pgrep -x dunst >/dev/null && notify-send "๐ŸŽต Music module" "\- Shows mpd song playing. +- Italic when paused. +- Left click opens ncmpcpp. +- Middle click pauses. +- Scroll changes track.";; # right click, pause/unpause + 4) mpc prev | filter ;; # scroll up, previous + 5) mpc next | filter ;; # scroll down, next + *) mpc status | filter ;; +esac; exit diff --git a/.local/bin/statusbar/news b/.local/bin/statusbar/news new file mode 100755 index 0000000..d836533 --- /dev/null +++ b/.local/bin/statusbar/news @@ -0,0 +1,3 @@ +#!/bin/bash +num=$( cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ print $1}' | sed s/^0$//g)$(cat ~/.config/newsboat/.update 2>/dev/null)") +[ "$num" = "" ] || echo ๐Ÿ“ฐ$num diff --git a/.local/bin/statusbar/pacpackages b/.local/bin/statusbar/pacpackages new file mode 100755 index 0000000..418bc2d --- /dev/null +++ b/.local/bin/statusbar/pacpackages @@ -0,0 +1,18 @@ +#!/bin/sh + +# i3blocks module for pacman upgrades. +# Displays number of upgradeable packages. +# For this to work, have a `pacman -Sy` command run in the background as a +# cronjob every so often as root. This script will then read those packages. +# When clicked, it will run an upgrade via pacman. + +case $BLOCK_BUTTON in + 1) $TERMINAL -e popupgrade ;; + 2) notify-send "$(/usr/bin/pacman -Qu)" ;; + 3) pgrep -x dunst >/dev/null && notify-send "Upgrade module" "๐Ÿ“ฆ: number of upgradable packages +- Left click to upgrade packages +- Middle click to show upgradable packages" ;; +esac + + +pacman -Qu | grep -v "\[ignored\]" | wc -l | sed -e "s/^0$//g" diff --git a/.local/bin/statusbar/popupgrade b/.local/bin/statusbar/popupgrade new file mode 100755 index 0000000..83035c3 --- /dev/null +++ b/.local/bin/statusbar/popupgrade @@ -0,0 +1,9 @@ +#!/bin/sh + +printf "Beginning upgrade.\\n" + +yay -Syu +pkill -RTMIN+8 i3blocks + +printf "\\nUpgrade complete.\\nPress <Enter> to exit window.\\n\\n" +read -r diff --git a/.local/bin/statusbar/statusbarinfo b/.local/bin/statusbar/statusbarinfo new file mode 100755 index 0000000..2b3e58c --- /dev/null +++ b/.local/bin/statusbar/statusbarinfo @@ -0,0 +1,32 @@ +#!/bin/sh + +echo " + ____ _ _ _ +/ ___|| |_ __ _| |_ _ _ ___| |__ __ _ _ __ +\___ \| __/ _\` | __| | | / __| '_ \ / _\` | '__| + ___) | || (_| | |_| |_| \__ \ |_) | (_| | | +|____/ \__\__,_|\__|\__,_|___/_.__/ \__,_|_| + +This is a list of the statusbar modules. + +๐Ÿ“ฆ5 \033[31mpacpackages\033[0m: updatable packages (must have pacman -Sy run in root cronjob to check). +๐Ÿ“ฐ 41 \033[32mnews\033[0m: unread RSS entries in newsboat. +โ˜” 83% โ„๏ธ 69ยฐ ๐ŸŒž 80ยฐ \033[33mweather\033[0m: โ˜” for precipitation, ๐ŸŒž and โ„ for daily high and low. +๐Ÿ“ฌ 20 \033[34mmailbox\033[0m: number of unread mail if mutt-wizard is active. +๐Ÿ”‰ 62% \033[35mvolume\033[0m: master sink volume. +๐Ÿ”Œ83% \033[36mbattery\033[0m: ๐Ÿ”Œ for charging, ๐Ÿ”‹ for discharging, โšก for full. +๐Ÿ“ถ 80% โŽ \033[37minternet\033[0m: ๐Ÿ“ถ for wifi with % (๐Ÿ“ก if none), ๐ŸŒ for ethernet. (โŽ if none). + +Obviously the time and date are displayed as well. + +Optional script modules: + +Edit \033[32m~/.local/src/dwmblocks/config.h\033[0m to add these or your own if you'd like (and recompile and restart dwmblocks). + +'memory' ๐Ÿง  559Mi/3.7Gi Current used memory/total memory. +'cpu' ๐ŸŒก +46.0ยฐC CPU temperature. +'disk' ๐Ÿ–ฅ : 28G/30G Remaining disk space... +'disk ~' ๐Ÿ : 641G/850G ...can be given directory argument. +'moonphase' ๐ŸŒ• 39% Phase of the moon (requires \033[32m\`pom-perl\`\033[0m). +'iplocate' ๐Ÿ‡บ๐Ÿ‡ธ United States Your own or VPN location (requires \033[32m\`geoiplookup\`\033[0m). +" | less diff --git a/.local/bin/statusbar/sync_status b/.local/bin/statusbar/sync_status new file mode 100755 index 0000000..fc4d7f3 --- /dev/null +++ b/.local/bin/statusbar/sync_status @@ -0,0 +1,8 @@ +#!/bin/sh +string="$(insync get_status)" + +case "$string" in + SYNCED) echo '๐Ÿ”—' ;; + OFFLINE) echo '๐Ÿ”—' ;; + SYNCING) echo '๐Ÿ”„' ;; +esac diff --git a/.local/bin/statusbar/torrent b/.local/bin/statusbar/torrent new file mode 100755 index 0000000..0ab811c --- /dev/null +++ b/.local/bin/statusbar/torrent @@ -0,0 +1,28 @@ +#!/bin/sh + +transmission-remote -l | grep % | + sed " # This first sed command is to ensure a desirable order with sort + s/.*Stopped.*/A/g; + s/.*Seeding.*/Z/g; + s/.*100%.*/N/g; + s/.*Idle.*/B/g; + s/.*Uploading.*/L/g; + s/.*%.*/M/g" | + sort -h | uniq -c | sed " # Now we replace the standin letters with icons. + s/A/๐Ÿ›‘/g; + s/B/โŒ›๏ธ/g; + s/L/๐Ÿ”ผ/g; + s/M/๐Ÿ”ฝ/g; + s/N/โœ…/g; + s/Z/๐ŸŒฑ/g" | awk '{print $2, $1}' | tr '\n' ' ' | sed -e "s/ $//g" + +case $BLOCK_BUTTON in + 1) $TERMINAL -e transmission-remote-cli ;; + 3) pgrep -x dunst >/dev/null && notify-send "Torrent module" "๐Ÿ›‘: paused +โณ: idle (seeds needed) +๐Ÿ”ผ: uploading (unfinished) +๐Ÿ”ฝ: downloading +โœ…: done +๐ŸŒฑ: done and seeding" ;; +esac + diff --git a/.local/bin/statusbar/volume b/.local/bin/statusbar/volume new file mode 100755 index 0000000..acb8586 --- /dev/null +++ b/.local/bin/statusbar/volume @@ -0,0 +1,48 @@ +#!/bin/sh + +# Prints the current volume or ๐Ÿ”‡ if muted. Uses PulseAudio by default, +# uncomment the ALSA lines if you remove PulseAudio. + +case $BLOCK_BUTTON in + # 1) setsid "$TERMINAL" -e alsamixer & ;; + # 2) amixer sset Master toggle ;; + # 4) amixer sset Master 5%+ >/dev/null 2>/dev/null ;; + # 5) amixer sset Master 5%- >/dev/null 2>/dev/null ;; + 1) setsid "$TERMINAL" -e pulsemixer & ;; + 2) pamixer -t ;; + 4) pamixer --allow-boost -i 1 ;; + 5) pamixer --allow-boost -d 1 ;; + 3) notify-send "๐Ÿ“ข Volume module" "\- Shows volume ๐Ÿ”Š, ๐Ÿ”‡ if muted. +- Middle click to mute. +- Scroll to change." +esac + +volstat="$(pactl list sinks)" +# volstat="$(amixer get Master)" # ALSA only equivalent. + +# Uses active sink if one is running, otherwise just go for the default one (First one listed in pactl list sinks) +if [ -z "$(echo "$volstat" | grep -A10 'State: RUNNING' )" ]; then + echo "$volstat" | grep -q "Mute: yes" && printf "๐Ÿ”‡\\n" && exit +else + echo "$volstat" | grep -A10 "State: RUNNING" | grep -q "Mute: yes" && printf "๐Ÿ”‡\\n" && exit +fi +# echo "$volstat" | grep "\[off\]" >/dev/null && printf "๐Ÿ”‡\\n" && exit # ALSA + +# Uses active sink if one is running, otherwise just go for the default one (First one listed in pactl list sinks) +if [ -z "$(echo "$volstat" | grep -A10 'State: RUNNING' )" ]; then + vol="$(echo "$volstat" | grep '[0-9]\+%' | sed "s,.* \([0-9]\+\)%.*,\1,;1q")" +else + vol="$(echo "$volstat" | grep -A10 "State: RUNNING" | grep '[0-9]\+%' | sed "s,.* \([0-9]\+\)%.*,\1,;1q")" +fi + +# vol=$(echo "$volstat" | grep -o "\[[0-9]\+%\]" | sed "s/[^0-9]*//g;1q") # ALSA + +if [ "$vol" -gt "70" ]; then + icon="๐Ÿ”Š" +elif [ "$vol" -lt "30" ]; then + icon="๐Ÿ”ˆ" +else + icon="๐Ÿ”‰" +fi + +printf "%s %s%%\\n" "$icon" "$vol" diff --git a/.local/bin/statusbar/volume_ b/.local/bin/statusbar/volume_ new file mode 100755 index 0000000..3bbb32b --- /dev/null +++ b/.local/bin/statusbar/volume_ @@ -0,0 +1,25 @@ +#!/bin/sh + +case $BLOCK_BUTTON in + 1) setsid "$TERMINAL" -e pulsemixer & ;; + 2) pulsemixer --toggle-mute ;; + 4) pulsemixer --change-volume +5 ;; + 5) pulsemixer --change-volume -5 ;; + 3) pgrep -x dunst >/dev/null && notify-send "๐Ÿ“ข Volume module" "\- Shows volume ๐Ÿ”Š, ๐Ÿ”‡ if muted. +- Middle click to mute. +- Scroll to change." +esac + +[ "$(pulsemixer --get-mute)" = "1" ] && printf "๐Ÿ”‡\\n" && exit + +vol=$(pulsemixer --get-volume | awk '{print $1}') + +if [ "$vol" -gt "70" ]; then + icon="๐Ÿ”Š" +elif [ "$vol" -lt "30" ]; then + icon="๐Ÿ”ˆ" +else + icon="๐Ÿ”‰" +fi + +printf "%s %s%%\\n" "$icon" "$vol" diff --git a/.local/bin/statusbar/weather b/.local/bin/statusbar/weather new file mode 100755 index 0000000..e4de680 --- /dev/null +++ b/.local/bin/statusbar/weather @@ -0,0 +1,23 @@ +#!/bin/sh +location="$1"; [ -z "$location" ] || { location="$location+" && rm -f "$HOME/.local/share/weatherreport" ;} + +getforecast() { ping -q -c 1 1.1.1.1 >/dev/null || exit 1 +curl -s "wttr.in/$location" > "$HOME/.local/share/weatherreport" || exit 1 ;} + +showweather() { printf "%s" "$(sed '16q;d' "$HOME/.local/share/weatherreport" | grep -wo "[0-9]*%" | sort -n | sed -e '$!d' | sed -e "s/^/โ˜” /g" | tr -d '\n')" +sed '13q;d' "$HOME/.local/share/weatherreport" | grep -o "m\\(-\\)*[0-9]\\+" | sort -n -t 'm' -k 2n | sed -e 1b -e '$!d' | tr '\n|m' ' ' | awk '{print " โ„๏ธ",$1 "ยฐ","๐ŸŒž",$2 "ยฐ"}' ;} + +case $BLOCK_BUTTON in + 1) $TERMINAL -e less -S "$HOME/.local/share/weatherreport" ;; + 2) getforecast && showweather ;; + 3) pgrep -x dunst >/dev/null && notify-send "๐ŸŒˆ Weather module" "\- Left click for full forecast. +- Middle click to update forecast. +โ˜”: Chance of rain/snow +โ„: Daily low +๐ŸŒž: Daily high" ;; +esac + +if [ "$(stat -c %y "$HOME/.local/share/weatherreport" >/dev/null 2>&1 | awk '{print $1}')" != "$(date '+%Y-%m-%d')" ] + then getforecast && showweather + else showweather +fi diff --git a/.local/bin/sysact b/.local/bin/sysact new file mode 100755 index 0000000..aaef469 --- /dev/null +++ b/.local/bin/sysact @@ -0,0 +1,14 @@ +#!/bin/sh + +# A dmenu wrapper script for system functions. + +cmds="\ +lock screen slock +leave dwm kill -TERM $(pidof -s dwm) +refresh dwm kill -HUP $(pidof -s dwm) +reboot sudo -A reboot +shutdown sudo -A shutdown -h now" + +choice="$(echo "$cmds" | cut -d' ' -f 1 | dmenu)" || exit 1 + +`echo "$cmds" | grep "^$choice " | cut -d ' ' -f2-` diff --git a/.local/bin/td-toggle b/.local/bin/td-toggle new file mode 100755 index 0000000..d2ba76a --- /dev/null +++ b/.local/bin/td-toggle @@ -0,0 +1,12 @@ +#!/bin/sh + +# If transmission-daemon is running, will ask to kill, else will ask to start. + +if pidof transmission-daemon >/dev/null ; +then + [ "$(printf "No\\nYes" | dmenu -i -p "Turn off transmission-daemon?")" = "Yes" ] && killall transmission-da && notify-send "transmission-daemon disabled." +else + ifinstalled transmission-cli || exit + [ "$(printf "No\\nYes" | dmenu -i -p "Turn on transmission daemon?")" = "Yes" ] && transmission-daemon && notify-send "tranmission-daemon enabled." +fi +sleep 3 && pkill -RTMIN+7 "${STATUSBAR:-dwmblocks}" diff --git a/.local/bin/test2 b/.local/bin/test2 new file mode 100755 index 0000000..14b2eb6 --- /dev/null +++ b/.local/bin/test2 @@ -0,0 +1,3 @@ +#!/bin/bash +echo $1 +echo $2 diff --git a/.local/bin/testscript b/.local/bin/testscript new file mode 100755 index 0000000..b0be37b --- /dev/null +++ b/.local/bin/testscript @@ -0,0 +1,2 @@ +#!/bin/bash +[ -n "$1" ] && echo "$1" > "/home/alex/test" diff --git a/.local/bin/tldextract b/.local/bin/tldextract new file mode 100755 index 0000000..613634a --- /dev/null +++ b/.local/bin/tldextract @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from tldextract.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.local/bin/tools/bright b/.local/bin/tools/bright new file mode 100755 index 0000000..4dd4826 --- /dev/null +++ b/.local/bin/tools/bright @@ -0,0 +1,8 @@ +#!/bin/bash +case $1 in + "set") printf %0.f $( echo "scale=0; $2 * 9.37" | bc -l ) > /sys/class/backlight/intel_backlight/brightness;; + "add") current=$( </sys/class/backlight/intel_backlight/brightness ) + new=$( printf %.0f $(echo "$current + $2 * 9.37" | bc -l ) ) + [ $new -gt 936 ] && bright set 937 || ( [ $new -lt 0 ] && bright set 0 || bright set "$(( new + 1 ))" ) ;; + "del") bright add "-$2";; +esac diff --git a/.local/bin/tools/bt_blacklist b/.local/bin/tools/bt_blacklist new file mode 100644 index 0000000..96e7896 --- /dev/null +++ b/.local/bin/tools/bt_blacklist @@ -0,0 +1 @@ +MX Master diff --git a/.local/bin/tools/bthandler_ b/.local/bin/tools/bthandler_ new file mode 100755 index 0000000..cdc7e52 --- /dev/null +++ b/.local/bin/tools/bthandler_ @@ -0,0 +1,77 @@ +#!/bin/bash +#wait time to discover new devices in seconds +SCAN_PERIOD=5 +BLACKLIST=$HOME/.local/bin/tools/bt_blacklist +actions="turn off\nturn on\npair\nunpair" + +#Checks for necessary programs to be present. Very unlikely not to be present but let's just err on the safer side. +for prog in dmenu bluetoothctl awk cat; do + if ! hash "$prog" 2>/dev/null; then + printf 'bthandler: %s: command not found\n' "$prog" >&2 + exit 127 + fi +done + + +bluetoothctl paired-devices | awk '{print $2}' > /tmp/bt_IDS +bluetoothctl paired-devices | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' > /tmp/paired_devices +grep -vf "$BLACKLIST" /tmp/paired_devices > /tmp/disp_devices + +#Don't print empty device list, removes unnecessary empty choice in dmenu +len=$(cat /tmp/disp_devices | wc -l) +[ $len -gt 0 ] && choice=$( printf "$(< /tmp/disp_devices)\n$actions" | dmenu -i -p 'What BT action would you like to perform:' ) +[ $len -eq 0 ] && choice=$( printf "$actions" | dmenu -i -p 'What BT action would you like to perform:' ) + +cleanup(){ + rm -f /tmp/bt_devices + rm -f /tmp/bt_IDS + rm -f /tmp/paired_devices + rm -f /tmp/new_devices + rm -f /tmp/disp_devices + bluetoothctl scan off > /dev/null + exit +} + + +case $choice in + "turn on") bluetoothctl power on + cleanup;; + "turn off") bluetoothctl power off + cleanup;; + "scan on") bluetoothctl power on && echo power on && sleep 2 + [ -n $TERMINAL ] && ($TERMINAL -e bluetoothctl scan on ) || st bluetoothctl scan on + cleanup;; + "pair") bluetoothctl power on + bluetoothctl scan on & disown + notify-send "Bluetooth" "Searching for devices, please wait a bit" + sleep $SCAN_PERIOD + bluetoothctl devices | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' > /tmp/bt_devices + grep -vf /tmp/paired_devices /tmp/bt_devices > /tmp/new_devices + choice=$( cat /tmp/new_devices | dmenu -l 10 -i -p 'pair with which device?' ) + if [ -n "$choice" ]; then + bluetoothctl devices | awk '{print $2}' > /tmp/bt_IDS + dev_no=$(cat -n /tmp/bt_devices | grep "$choice" | awk '{print $1}') + dev_id=$(cat -n /tmp/bt_IDS | grep -E $dev_no"[[:space:]]" | awk '{print $2}' ) + + bluetoothctl pair $dev_id && sleep 2 + bluetoothctl connect $dev_id + fi + cleanup;; + "unpair") choice=$( cat /tmp/paired_devices | dmenu -l 10 -i -p 'remove which paired device?') + if [ -n "choice" ]; then + dev_no=$(cat -n /tmp/paired_devices | grep "$choice" | awk '{print $1}') + dev_id=$(cat -n /tmp/bt_IDS | grep -E $dev_no"[[:space:]]" | awk '{print $2}' ) + bluetoo + bluetoothctl remove $dev_id + fi + cleanup;; +esac + +if [ -n "$choice" ]; then + dev_no=$(cat -n /tmp/paired_devices | grep "$choice" | awk '{print $1}') + dev_id=$(cat -n /tmp/bt_IDS | grep $dev_no | awk '{print $2}') + bluetoothctl power on + bluetoothctl connect $dev_id +fi + +cleanup diff --git a/.local/bin/tools/casttest b/.local/bin/tools/casttest new file mode 100755 index 0000000..807a57c --- /dev/null +++ b/.local/bin/tools/casttest @@ -0,0 +1,12 @@ +#!/bin/bash +video=$1 +speed=${2:-1} +echo "speed: $speed" +slowness="$( echo $speed | bc -l )" +echo "slowness: $slowness" +rate=$( ffmpeg -i $video | sed -n "s/.*, \(.*\) tbr.*/\1/p" ) +echo "oldrate: $rate" +newrate=$( echo "scale=0; $speed * $rate" | bc -l ) +echo "newrate: $newrate" +command=ffmpeg -re -i "$video" -r $newrate filter:v "setpts=$slowness*PTS" pipe:1 +mkchromecast --video --control --command "$command" diff --git a/.local/bin/tools/castyt b/.local/bin/tools/castyt new file mode 100755 index 0000000..c15c550 --- /dev/null +++ b/.local/bin/tools/castyt @@ -0,0 +1,2 @@ +#!/bin/sh +mkchromecast --notifications --video --control -y $1 2>/dev/null || true diff --git a/.local/bin/tools/ce b/.local/bin/tools/ce new file mode 100755 index 0000000..b6296b3 --- /dev/null +++ b/.local/bin/tools/ce @@ -0,0 +1,4 @@ +#!/bin/bash +currentdir="$(pwd)" +file="$( du -a ~/.config/* ~/.local/src/* ~/.local/bin/* | awk '{print $2}' | fzf -e --query="$*")" +[ "$file" = "" ] || ( cd "$( dirname "$file" )" && $EDITOR "$file" && cd "$currentdir" ) diff --git a/.local/bin/tools/clip b/.local/bin/tools/clip new file mode 100755 index 0000000..770cd5f --- /dev/null +++ b/.local/bin/tools/clip @@ -0,0 +1,2 @@ +#!/bin/sh +xclip -o -selection "clipboard" diff --git a/.local/bin/tools/dmenu_run_history b/.local/bin/tools/dmenu_run_history new file mode 100755 index 0000000..dcaa8dd --- /dev/null +++ b/.local/bin/tools/dmenu_run_history @@ -0,0 +1,58 @@ +#!/bin/sh +aliases=$HOME/.config/aliasrc + +source $aliases +termcmd="st -e" +cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"} +if [ -d "$cachedir" ]; then + cache=$cachedir/dmenu_run + historyfile=$cachedir/dmenu_history +else # if no xdg dir, fall back to dotfiles in ~ + cache=$HOME/.dmenu_cache + historyfile=$HOME/.dmenu_history +fi + +IFS=: +if stest -dqr -n "$cache" $PATH; then + stest -flx $PATH | sort -u > "$cache" +fi +unset IFS + +cmd=$(awk -v histfile=$historyfile ' + BEGIN { + while( (getline < histfile) > 0 ) { + sub("^[0-9]+\t","") + print + x[$0]=1 + } + } !x[$0]++ ' "$cache" \ + | dmenu "$@" \ + | awk -v histfile=$historyfile ' + BEGIN { + FS=OFS="\t" + while ( (getline < histfile) > 0 ) { + count=$1 + sub("^[0-9]+\t","") + fname=$0 + history[fname]=count + } + close(histfile) + } + + { + history[$0]++ + print + } + + END { + if(!NR) exit + for (f in history) + print history[f],f | "sort -t '\t' -k1rn >" histfile + } + ' ) + +case $cmd in + *\! ) ${termcmd} "$(printf "%s" "${cmd}" | cut -d'!' -f1)";; + * ) ${cmd} ;; +esac +exit diff --git a/.local/bin/tools/dmenuhandler b/.local/bin/tools/dmenuhandler new file mode 100755 index 0000000..485f991 --- /dev/null +++ b/.local/bin/tools/dmenuhandler @@ -0,0 +1,20 @@ +#!/bin/sh +# Feed this script a link and it will give dmenu +# some choice programs to use to open it. + +case "$(printf "mpv\\ncopy url\\nqueue download\\n\\nqueue youtube-dl\\nbrowser\\nrip media\\ncast" | dmenu -i -p "Open link with what program?")" in + "copy url") echo "$1" | xclip -selection clipboard ;; + mpv) setsid mpv --quiet --ytdl-format='bestvideo[height<=1080]+bestaudio/best[height<=1080]' "$1" & ;; + "mpv (loop)") setsid mpv --input-ipc-server=/tmp/mpvsoc$(date +%s) -quiet --loop "$1" >/dev/null 2>&1 & ;; + "queue download") name="$( dmenuinput 'Name for file:' )" + tsp curl -L -o $name "$1" >/dev/null 2>&1 ;; + "queue youtube-dl") youtube-dl --write-metadata -i -o '/home/alex/%(upload_date)s-%(title)s.%(ext)s' "$1" >/dev/null 2>&1 ;; + cast) setsid $TERMINAL -e mkchromecast -y $1 --video --control + ;; + browser) setsid "$BROWSER" "$1" >/dev/null 2>&1 & ;; + #feh) setsid feh "$1" >/dev/null 2>&1 & ;; + #w3m) w3m "$1" >/dev/null 2>&1 ;; + #"mpv (float)") setsid mpv --input-ipc-server=/tmp/mpvsoc$(date +%s) --geometry=+0-0 --autofit=30% --title="mpvfloat" "$1" >/dev/null 2>&1 & ;; + "rip media") dest="$(dmenuinput 'name of folder:')" + [ "$dest" != "" ] && ( lynx --dump --nonumbers --listonly $1 | grep -E "(*\.webm|*\.mp4|\.gif|\.jpg|\.jpeg|\.png)" | sort -u | xargs wget -P /home/alex/$dest ) || ( lynx --dump --nonumbers --listonly $1 | grep -E "(*\.webm|*\.mp4|\.gif|\.jpg|\.jpeg|\.png)" | sort -u | xargs wget -P /home/alex/ );; +esac diff --git a/.local/bin/tools/dmenuinput b/.local/bin/tools/dmenuinput new file mode 100755 index 0000000..aaf20c2 --- /dev/null +++ b/.local/bin/tools/dmenuinput @@ -0,0 +1,3 @@ +#!/bin/sh +dmenu -fn Monospace-13 -p "$1" <&- && echo + diff --git a/.local/bin/tools/dmenupass b/.local/bin/tools/dmenupass new file mode 100755 index 0000000..131a02e --- /dev/null +++ b/.local/bin/tools/dmenupass @@ -0,0 +1,2 @@ +!/bin/sh +dmenu -fn Monospace-13 -sb "#d79921" -sf "#1d2021" -nf "#000000" -nb "#000000" -p "$1" <&- && echo diff --git a/.local/bin/tools/email_handler b/.local/bin/tools/email_handler new file mode 100755 index 0000000..850a07a --- /dev/null +++ b/.local/bin/tools/email_handler @@ -0,0 +1,6 @@ +#!/bin/sh +input=$1 +while read -r str +do + [[ $(grep -c "$str" "$input") == 1 ]] && echo $str +done < "$input" diff --git a/.local/bin/tools/epdf b/.local/bin/tools/epdf new file mode 100755 index 0000000..7add619 --- /dev/null +++ b/.local/bin/tools/epdf @@ -0,0 +1,3 @@ +#!/bin/sh +pdf="$(du -a --time ETH/ | awk '!($1="")' | sort -r | grep '\.pdf' | awk '!($1="")' | awk '!($1="")' | sed 's/^ //' | dmenu -l 20 )" +[ -z $pdf ] || $READER "$pdf" diff --git a/.local/bin/tools/ethvpn b/.local/bin/tools/ethvpn new file mode 100755 index 0000000..e2dcec4 --- /dev/null +++ b/.local/bin/tools/ethvpn @@ -0,0 +1,2 @@ +#!/bin/bash +[ $( pgrep -c openconnect ) -eq 0 ] &&( dmenupass "Password for ETH-VPN:" | sudo openconnect -g student-net -u abocken@student-net.ethz.ch --passwd-on-stdin sslvpn.ethz.ch ) || ( sudo pkill openconnect; notify-send "ETH VPN" "ETH VPN disconnected") diff --git a/.local/bin/tools/ewv b/.local/bin/tools/ewv new file mode 100755 index 0000000..e1c6631 --- /dev/null +++ b/.local/bin/tools/ewv @@ -0,0 +1,3 @@ +#!/bin/sh +video=$(du -a ~/eth/videos/* --time | awk '!($1="")' | sort -bg | awk '!($1="")' | awk '!($1="")' | sed 's/^ \/home\/alex\/eth\/videos\///' | grep -E "\....$"| tac | dmenu -l 10 -p "What lecture would you like to watch?"); +[ -z $video ] || ( mpv "/home/alex/eth/videos/$video" & disown ) diff --git a/.local/bin/tools/ext b/.local/bin/tools/ext new file mode 120000 index 0000000..562d2b3 --- /dev/null +++ b/.local/bin/tools/ext @@ -0,0 +1 @@ +extract \ No newline at end of file diff --git a/.local/bin/tools/extract b/.local/bin/tools/extract new file mode 100755 index 0000000..a63ab10 --- /dev/null +++ b/.local/bin/tools/extract @@ -0,0 +1,41 @@ +#!/bin/sh +# A general, all-purpose extraction script. +# +# Default behavior: Extract archive into new directory +# Behavior with `-c` option: Extract contents into current directory + +while getopts "hc" o; do case "${o}" in + c) extracthere="True" ;; + *) printf "Options:\\n -c: Extract archive into current directory rather than a new one.\\n" && exit ;; +esac done + +if [ -z "$extracthere" ]; then + archive="$(readlink -f "$*")" && + directory="$(echo "$archive" | sed 's/\.[^\/.]*$//')" && + mkdir -p "$directory" && + cd "$directory" || exit +else + archive="$(readlink -f "$(echo "$*" | cut -d' ' -f2)")" +fi + +[ "$archive" = "" ] && printf "Give archive to extract as argument.\\n" && exit + +if [ -f "$archive" ] ; then + case "$archive" in + *.tar.bz2|*.tar.xz|*.tbz2) tar xvjf "$archive" ;; + *.tar.gz|*.tgz) tar xvzf "$archive" ;; + *.lzma) unlzma "$archive" ;; + *.bz2) bunzip2 "$archive" ;; + *.rar) unrar x -ad "$archive" ;; + *.gz) gunzip "$archive" ;; + *.tar) tar xvf "$archive" ;; + *.zip) unzip "$archive" ;; + *.Z) uncompress "$archive" ;; + *.7z) 7z x "$archive" ;; + *.xz) unxz "$archive" ;; + *.exe) cabextract "$archive" ;; + *) printf "extract: '%s' - unknown archive method\\n" "$archive" ;; + esac +else + printf "File \"%s\" not found.\\n" "$archive" +fi diff --git a/.local/bin/tools/fix_devices b/.local/bin/tools/fix_devices new file mode 100644 index 0000000..8f76e31 --- /dev/null +++ b/.local/bin/tools/fix_devices @@ -0,0 +1,3 @@ + +Device 00:00:00:00:3F:F3 TOZO-T10-R +Device 00:00:00:00:3F:F3 TOZO-T10-R diff --git a/.local/bin/tools/getbib b/.local/bin/tools/getbib new file mode 100755 index 0000000..ed441c5 --- /dev/null +++ b/.local/bin/tools/getbib @@ -0,0 +1,14 @@ +#!/bin/sh +[ -z "$1" ] && echo "Give either a pdf file or a DOI as an argument." && exit + +if [ -f "$1" ]; then + # Try to get DOI from pdfinfo or pdftotext output. + doi=$(pdfinfo "$1" | grep -io "doi:.*") || + doi=$(pdftotext "$1" 2>/dev/null - | grep -io "doi:.*" -m 1) || + exit 1 +else + doi="$1" +fi + +# Check crossref.org for the bib citation. +curl -s "http://api.crossref.org/works/$doi/transform/application/x-bibtex" -w "\\n" diff --git a/.local/bin/tools/getkeys b/.local/bin/tools/getkeys new file mode 100755 index 0000000..444f4c0 --- /dev/null +++ b/.local/bin/tools/getkeys @@ -0,0 +1,4 @@ +#!/bin/sh +cat ~/.config/getkeys/"$1" 2>/dev/null && exit +echo "Run command with one of the following arguments for info about that program:" +ls ~/.config/getkeys diff --git a/.local/bin/tools/ifinstalled b/.local/bin/tools/ifinstalled new file mode 100755 index 0000000..b0d23e5 --- /dev/null +++ b/.local/bin/tools/ifinstalled @@ -0,0 +1,3 @@ +#!/bin/sh +# If $1 command is not available, error code and notify. +command -v "$1" >/dev/null || { notify-send "๐Ÿ“ฆ $1" "must be installed for this function." && exit 1 ;} diff --git a/.local/bin/tools/importvocabs b/.local/bin/tools/importvocabs new file mode 100755 index 0000000..fe5e69a --- /dev/null +++ b/.local/bin/tools/importvocabs @@ -0,0 +1,13 @@ +#!/bin/bash +#arg 1: xlsx file +current_dir="$pwd" +cd $HOME/src/GRE/ +find *.xlsx | xargs git rm +find *.csv | xargs git rm +cd "$current_dir" +xlsx2csv -d 'tab' $1 | tail -n +3 > "$HOME/src/GRE/${1%xlsx}csv" +mv $1 $HOME/src/GRE +cd $HOME/src/GRE/ +git add "$1" +git add "${1%xlsx}csv" +cd "$current_dir" diff --git a/.local/bin/tools/linkhandler b/.local/bin/tools/linkhandler new file mode 100755 index 0000000..b839da2 --- /dev/null +++ b/.local/bin/tools/linkhandler @@ -0,0 +1,22 @@ +#!/bin/sh + +# Feed script a url or file location. +# If an image, it will view in sxiv, +# if a video or gif, it will view in mpv +# if a music file or pdf, it will download, +# otherwise it opens link in browser. + +# If no url given. Opens browser. For using script as $BROWSER. +[ -z "$1" ] && { "$BROWSER"; exit; } + +case "$1" in + *mkv|*webm|*mp4|*youtube.com/watch*|*youtube.com/playlist*|*youtu.be*|*hooktube.com*|*bitchute.com*) + setsid mpv --input-ipc-server=/tmp/mpvsoc$(date +%s) -quiet "$1" >/dev/null 2>&1 & ;; + *png|*jpg|*jpe|*jpeg|*gif) + curl -sL "$1" > "/tmp/$(echo "$1" | sed "s/.*\///")" && sxiv -a "/tmp/$(echo "$1" | sed "s/.*\///")" >/dev/null 2>&1 & ;; + *mp3|*flac|*opus|*mp3?source*) + setsid tsp curl -LO "$1" >/dev/null 2>&1 & ;; + *) + if [ -f "$1" ]; then "$TERMINAL" -e "$EDITOR $1" + else setsid "$BROWSER" "$1" >/dev/null 2>&1 & fi ;; +esac diff --git a/.local/bin/tools/lmc b/.local/bin/tools/lmc new file mode 100755 index 0000000..18cf2c2 --- /dev/null +++ b/.local/bin/tools/lmc @@ -0,0 +1,42 @@ +#!/bin/sh +# A general audio interface for LARBS. + +[ -z "$2" ] && num="2" || num="$2" + +case "$1" in + u*) pulsemixer --change-volume +"$num" ;; + d*) pulsemixer --change-volume -"$num" ;; + m*) pulsemixer --toggle-mute ;; + truemute) pulsemixer --mute ;; + play) mpc play ;; + n*) mpc next ;; + prev) mpc prev ;; + t*) mpc toggle ;; + p*) mpc pause ; pauseallmpv ;; + f*) mpc seek +"$num" ;; + b*) mpc seek -"$num" ;; + r*) mpc seek 0% ;; + *) cat << EOF +lmc: cli music interface for mpd and pulse for those with divine intellect too +grand to remember the mpc/pamixer commands. + +Allowed options: + up NUM Increase volume (2 secs default) + down NUM Decrease volume (2 secs default) + mute Toggle mute + truemute Mute + next Next track + prev Previous track + toggle Toggle pause + truepause Pause + foward NUM Seek foward in song (2 secs default) + back NUM Seek back in song (2 secs default) + restart Restart current song + all else Print this message + +All of these commands, except for \`truemute\`, \`prev\` and \`play\` can be truncated, +i.e. \`lmc r\` for \`lmc restart\`. +EOF +esac + +pkill -RTMIN+10 i3blocks diff --git a/.local/bin/tools/opout b/.local/bin/tools/opout new file mode 100755 index 0000000..c742aa9 --- /dev/null +++ b/.local/bin/tools/opout @@ -0,0 +1,11 @@ +#!/bin/sh +# opout: "open output": A general handler for opening a file's intended output. +# I find this useful especially running from vim. + +basename="$(echo "$1" | sed 's/\.[^\/.]*$//')" + +case "$1" in + *.tex|*.md|*.rmd|*.ms|*.me|*.mom) setsid "$READER" "$basename".pdf >/dev/null 2>&1 & ;; + *.html) setsid "$BROWSER" --new-window "$basename".html >/dev/null 2>&1 & ;; + *.sent) setsid sent "$1" >/dev/null 2>&1 & ;; +esac diff --git a/.local/bin/tools/passmenu2 b/.local/bin/tools/passmenu2 new file mode 100755 index 0000000..854e945 --- /dev/null +++ b/.local/bin/tools/passmenu2 @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +shopt -s nullglob globstar + +typeit=0 +if [[ $1 == "--type" ]]; then + typeit=1 + shift +fi + + +STARTDIR=${PASSWORD_STORE_DIR-~/.password-store} +BASEDIR=$STARTDIR +DONE=0 +LEVEL=0 +PREVSELECTION="" +SELECTION="" + +while [ "$DONE" -eq 0 ] ; do + password_files=( "$STARTDIR"/* ) + password_files=( "${password_files[@]#"$STARTDIR"/}" ) + password_files=( "${password_files[@]%.gpg}" ) + + if [ "$LEVEL" -ne 0 ] ; then + password_files=(".." "${password_files[@]}") + fi + entry=$(printf '%s\n' "${password_files[@]}" | grep -v 'mutt'| dmenu -i -p "Select a password:" "$@" -l 15) + + echo "entry: $entry" + if [ -z "$entry" ] ; then + DONE=1 + exit + fi + + if [ "$entry" != ".." ] ; then + PREVSELECTION=$SELECTION + SELECTION="$SELECTION/$entry" + + # check if another dir + if [ -d "$STARTDIR/$entry" ] ; then + STARTDIR="$STARTDIR/$entry" + LEVEL=$((LEVEL+1)) + else + # not a directory so it must be a real password entry + + if [[ $typeit -eq 0 ]]; then + pass show -c "$SELECTION" > $HOME/.cache/passstring + sed -e "s/^/\"/" -e "s/$/\"/" $HOME/.cache/passstring | xargs -r notify-send "Password" -t 4000 + sleep 45 + [ -f $HOME/.cache/passstring ] && notify-send "Password" "password cleared from clipboard" -t 4000 + rm $HOME/.cache/passstring + + else + xdotool - <<<"type --clearmodifiers -- $(pass show "$SELECTION" | head -n 1)" + fi + DONE=1 + fi + + else + LEVEL=$((LEVEL-1)) + SELECTION=$PREVSELECTION + STARTDIR="$BASEDIR/$SELECTION" + fi +done diff --git a/.local/bin/tools/pauseallmpv b/.local/bin/tools/pauseallmpv new file mode 100755 index 0000000..c5da220 --- /dev/null +++ b/.local/bin/tools/pauseallmpv @@ -0,0 +1,4 @@ +#!/bin/sh +for i in $(ls /tmp/mpvsoc*); do + echo '{ "command": ["set_property", "pause", true] }' | socat - $i; +done diff --git a/.local/bin/tools/plot b/.local/bin/tools/plot new file mode 100755 index 0000000..7113bdf --- /dev/null +++ b/.local/bin/tools/plot @@ -0,0 +1,34 @@ +#!/bin/bash +echo $1 +sed "9s/.*/func = lambda x: $1/" "/home/alex/.local/bin/tools/plotter.py" > /tmp/plotter_temp.py +if [ ! -z $(echo $2 | grep "a=") ]; then + echo $2 + echo "Has found attribute a=" + sed "13s/.*/$2/" "/tmp/plotter_temp.py" > /tmp/plotter_temp2.py + cat "/tmp/plotter_temp2.py" > /tmp/plotter_temp.py + a=0 +fi + +if [ ! -z $(echo $3 | grep "b=") ]; then + echo $3 + echo "has found attribute b=" + sed "14s/.*/$3/" "/tmp/plotter_temp.py" > /tmp/plotter_temp2.py + cat "/tmp/plotter_temp2.py" > /tmp/plotter_temp.py + b=0 +fi + +if [ -z $(echo $2 | grep "a=") ]; then + echo $2 + a=$2 +fi + +if [ -z $(echo $3 | grep "b=") ]; then + echo $3 + b=$3 +fi + +rm -f /tmp/plotter_temp2.py +python /tmp/plotter_temp.py "$1" $2 $3 +sxiv -b /tmp/plot.png +rm -f /tmp/plot.png +#rm /tmp/plotter_temp.py diff --git a/.local/bin/tools/plotter.py b/.local/bin/tools/plotter.py new file mode 100644 index 0000000..81cefaa --- /dev/null +++ b/.local/bin/tools/plotter.py @@ -0,0 +1,197 @@ +import matplotlib.pyplot as plt +from numpy import * +import sys +import re + +#limits of function: +#put function here +func=lambda x: 1 + + +if(len(sys.argv) == 4): + a_s = sys.argv[2] + b_s = sys.argv[3] +func_string = sys.argv[1] + +print("a_s: {}".format(a_s)) +print("b_s: {}".format(b_s)) +a = float(re.sub("a=", "", a_s)) +b = float(re.sub("b=", "", b_s)) +N= 1000 + +def plotter(): + x = linspace(a,b, N) + plt.figure(figsize=(10,10)) + plt.plot(x,func(x), label=func_string) + #plt.plot(x,g(x), label='g(x)') + plt.legend(loc='best') + plt.grid() + plt.show() + plt.savefig("/tmp/plot.png", dpi=150) + +# License: Creative Commons Zero (almost public domain) http://scpyce.org/cc0 + +import numpy as np + +def sample_function(func, points, tol=0.05, min_points=16, max_level=16, + sample_transform=None): + """ + Sample a 1D function to given tolerance by adaptive subdivision. + + The result of sampling is a set of points that, if plotted, + produces a smooth curve with also sharp features of the function + resolved. + + Parameters + ---------- + func : callable + Function func(x) of a single argument. It is assumed to be vectorized. + points : array-like, 1D + Initial points to sample, sorted in ascending order. + These will determine also the bounds of sampling. + tol : float, optional + Tolerance to sample to. The condition is roughly that the total + length of the curve on the (x, y) plane is computed up to this + tolerance. + min_point : int, optional + Minimum number of points to sample. + max_level : int, optional + Maximum subdivision depth. + sample_transform : callable, optional + Function w = g(x, y). The x-samples are generated so that w + is sampled. + + Returns + ------- + x : ndarray + X-coordinates + y : ndarray + Corresponding values of func(x) + + Notes + ----- + This routine is useful in computing functions that are expensive + to compute, and have sharp features --- it makes more sense to + adaptively dedicate more sampling points for the sharp features + than the smooth parts. + + Examples + -------- + >>> def func(x): + ... '''Function with a sharp peak on a smooth background''' + ... a = 0.001 + ... return x + a**2/(a**2 + x**2) + ... + >>> x, y = sample_function(func, [-1, 1], tol=1e-3) + + >>> import matplotlib.pyplot as plt + >>> xx = np.linspace(-1, 1, 12000) + >>> plt.plot(xx, func(xx), '-', x, y[0], '.') + >>> plt.show() + + """ + return _sample_function(func, points, values=None, mask=None, depth=0, + tol=tol, min_points=min_points, max_level=max_level, + sample_transform=sample_transform) + +def _sample_function(func, points, values=None, mask=None, tol=0.05, + depth=0, min_points=16, max_level=16, + sample_transform=None): + points = np.asarray(points) + + if values is None: + values = np.atleast_2d(func(points)) + + if mask is None: + mask = Ellipsis + + if depth > max_level: + # recursion limit + return points, values + + x_a = points[...,:-1][mask] + x_b = points[...,1:][mask] + + x_c = .5*(x_a + x_b) + y_c = np.atleast_2d(func(x_c)) + + x_2 = np.r_[points, x_c] + y_2 = np.r_['-1', values, y_c] + j = np.argsort(x_2) + + x_2 = x_2[...,j] + y_2 = y_2[...,j] + + # -- Determine the intervals at which refinement is necessary + + if len(x_2) < min_points: + mask = np.ones([len(x_2)-1], dtype=bool) + else: + # represent the data as a path in N dimensions (scaled to unit box) + if sample_transform is not None: + y_2_val = sample_transform(x_2, y_2) + else: + y_2_val = y_2 + + p = np.r_['0', + x_2[None,:], + y_2_val.real.reshape(-1, y_2_val.shape[-1]), + y_2_val.imag.reshape(-1, y_2_val.shape[-1]) + ] + + sz = (p.shape[0]-1)//2 + + xscale = x_2.ptp(axis=-1) + yscale = abs(y_2_val.ptp(axis=-1)).ravel() + + p[0] /= xscale + p[1:sz+1] /= yscale[:,None] + p[sz+1:] /= yscale[:,None] + + # compute the length of each line segment in the path + dp = np.diff(p, axis=-1) + s = np.sqrt((dp**2).sum(axis=0)) + s_tot = s.sum() + + # compute the angle between consecutive line segments + dp /= s + dcos = np.arccos(np.clip((dp[:,1:] * dp[:,:-1]).sum(axis=0), -1, 1)) + + # determine where to subdivide: the condition is roughly that + # the total length of the path (in the scaled data) is computed + # to accuracy `tol` + dp_piece = dcos * .5*(s[1:] + s[:-1]) + mask = (dp_piece > tol * s_tot) + + mask = np.r_[mask, False] + mask[1:] |= mask[:-1].copy() + + + # -- Refine, if necessary + + if mask.any(): + return _sample_function(func, x_2, y_2, mask, tol=tol, depth=depth+1, + min_points=min_points, max_level=max_level, + sample_transform=sample_transform) + else: + return x_2, y_2 + + +if __name__ == '__main__': + #plotter() + x, y = sample_function(func, [a, b], tol=1e-6) + xx = np.linspace(a, b, 300) + plt.figure(figsize=((10,10))) + plt.plot(x, y[0], '-',linewidth=1.5) + plt.grid() + plt.savefig("/tmp/plot.png", dpi=400) + #weightss = np.empty_like(xx) + #for i in range(len(xx)): + # if i == 0: + # weightss[i] = xx[i+1]-x[i] + # if i == len(xx)-1: + # weightss[i] = xx[-1]-xx[-2] + # else: + # weightss[i] = 0.5*(xx[i+1]-xx[i-1]) + #avg = average(abs(func(xx))) + #plt.ylim(top=avg, bottom=-1.0*avg) diff --git a/.local/bin/tools/plotter_.py b/.local/bin/tools/plotter_.py new file mode 100644 index 0000000..c625a11 --- /dev/null +++ b/.local/bin/tools/plotter_.py @@ -0,0 +1,195 @@ +import matplotlib.pyplot as plt +from numpy import * +import sys +import re + +#limits of function: +print(sys.argv) +#put function here +func=lambda x: 1/10*x-x**2/400 +a_s = sys.argv[2] +b_s = sys.argv[3] +if len(sys.argv) > 3: + print("LONGER") +#print('save_state: {}'.format(save_state)) +func_string = sys.argv[1] + +a = float(re.sub("a=", "", a_s)) +b = float(re.sub("b=", "", b_s)) +N= 1000 + +def plotter(): + x = linspace(a,b, N) + plt.figure(figsize=(10,10)) + plt.plot(x,func(x), label=func_string) + #plt.plot(x,g(x), label='g(x)') + plt.legend(loc='best') + plt.grid() + plt.savefig("/tmp/plot.png", dpi=150) + +# License: Creative Commons Zero (almost public domain) http://scpyce.org/cc0 + +import numpy as np + +def sample_function(func, points, tol=0.05, min_points=16, max_level=16, + sample_transform=None): + """ + Sample a 1D function to given tolerance by adaptive subdivision. + + The result of sampling is a set of points that, if plotted, + produces a smooth curve with also sharp features of the function + resolved. + + Parameters + ---------- + func : callable + Function func(x) of a single argument. It is assumed to be vectorized. + points : array-like, 1D + Initial points to sample, sorted in ascending order. + These will determine also the bounds of sampling. + tol : float, optional + Tolerance to sample to. The condition is roughly that the total + length of the curve on the (x, y) plane is computed up to this + tolerance. + min_point : int, optional + Minimum number of points to sample. + max_level : int, optional + Maximum subdivision depth. + sample_transform : callable, optional + Function w = g(x, y). The x-samples are generated so that w + is sampled. + + Returns + ------- + x : ndarray + X-coordinates + y : ndarray + Corresponding values of func(x) + + Notes + ----- + This routine is useful in computing functions that are expensive + to compute, and have sharp features --- it makes more sense to + adaptively dedicate more sampling points for the sharp features + than the smooth parts. + + Examples + -------- + >>> def func(x): + ... '''Function with a sharp peak on a smooth background''' + ... a = 0.001 + ... return x + a**2/(a**2 + x**2) + ... + >>> x, y = sample_function(func, [-1, 1], tol=1e-3) + + >>> import matplotlib.pyplot as plt + >>> xx = np.linspace(-1, 1, 12000) + >>> plt.plot(xx, func(xx), '-', x, y[0], '.') + >>> plt.show() + + """ + return _sample_function(func, points, values=None, mask=None, depth=0, + tol=tol, min_points=min_points, max_level=max_level, + sample_transform=sample_transform) + +def _sample_function(func, points, values=None, mask=None, tol=0.05, + depth=0, min_points=16, max_level=16, + sample_transform=None): + points = np.asarray(points) + + if values is None: + values = np.atleast_2d(func(points)) + + if mask is None: + mask = Ellipsis + + if depth > max_level: + # recursion limit + return points, values + + x_a = points[...,:-1][mask] + x_b = points[...,1:][mask] + + x_c = .5*(x_a + x_b) + y_c = np.atleast_2d(func(x_c)) + + x_2 = np.r_[points, x_c] + y_2 = np.r_['-1', values, y_c] + j = np.argsort(x_2) + + x_2 = x_2[...,j] + y_2 = y_2[...,j] + + # -- Determine the intervals at which refinement is necessary + + if len(x_2) < min_points: + mask = np.ones([len(x_2)-1], dtype=bool) + else: + # represent the data as a path in N dimensions (scaled to unit box) + if sample_transform is not None: + y_2_val = sample_transform(x_2, y_2) + else: + y_2_val = y_2 + + p = np.r_['0', + x_2[None,:], + y_2_val.real.reshape(-1, y_2_val.shape[-1]), + y_2_val.imag.reshape(-1, y_2_val.shape[-1]) + ] + + sz = (p.shape[0]-1)//2 + + xscale = x_2.ptp(axis=-1) + yscale = abs(y_2_val.ptp(axis=-1)).ravel() + + p[0] /= xscale + p[1:sz+1] /= yscale[:,None] + p[sz+1:] /= yscale[:,None] + + # compute the length of each line segment in the path + dp = np.diff(p, axis=-1) + s = np.sqrt((dp**2).sum(axis=0)) + s_tot = s.sum() + + # compute the angle between consecutive line segments + dp /= s + dcos = np.arccos(np.clip((dp[:,1:] * dp[:,:-1]).sum(axis=0), -1, 1)) + + # determine where to subdivide: the condition is roughly that + # the total length of the path (in the scaled data) is computed + # to accuracy `tol` + dp_piece = dcos * .5*(s[1:] + s[:-1]) + mask = (dp_piece > tol * s_tot) + + mask = np.r_[mask, False] + mask[1:] |= mask[:-1].copy() + + + # -- Refine, if necessary + + if mask.any(): + return _sample_function(func, x_2, y_2, mask, tol=tol, depth=depth+1, + min_points=min_points, max_level=max_level, + sample_transform=sample_transform) + else: + return x_2, y_2 + + +if __name__ == '__main__': + #plotter() + x, y = sample_function(func, [a, b], tol=1e-6) + xx = np.linspace(a, b, 300) + plt.figure(figsize=((10,10))) + plt.plot(x, y[0], '-',linewidth=1.5) + plt.grid() + plt.savefig("/tmp/plot.png", dpi=400) + #weightss = np.empty_like(xx) + #for i in range(len(xx)): + # if i == 0: + # weightss[i] = xx[i+1]-x[i] + # if i == len(xx)-1: + # weightss[i] = xx[-1]-xx[-2] + # else: + # weightss[i] = 0.5*(xx[i+1]-xx[i-1]) + #avg = average(abs(func(xx))) + #plt.ylim(top=avg, bottom=-1.0*avg) diff --git a/.local/bin/tools/podentr b/.local/bin/tools/podentr new file mode 100755 index 0000000..13ab4a8 --- /dev/null +++ b/.local/bin/tools/podentr @@ -0,0 +1,6 @@ +#!/bin/sh +# entr command to run `queueandnotify` when newsboat queue is changed + +[ "$(pgrep -x $(basename $0) | wc -l)" -gt 2 ] && exit + +echo ~/.local/share/newsboat/queue | entr -p queueandnotify 2>/dev/null diff --git a/.local/bin/tools/pw b/.local/bin/tools/pw new file mode 100755 index 0000000..b6597dc --- /dev/null +++ b/.local/bin/tools/pw @@ -0,0 +1,19 @@ +#!/bin/bash +passmenu2 +#group=$(pass list | sed 's/\x1B\[[0-9;]\+[A-Za-z]//g' | grep -Ev "Password|mutt-wizard" | grep -v ' .โ”€โ”€' | sed -E 's/โ”œโ”€โ”€|โ””โ”€โ”€| //' | sed 's/ //' | dmenu -l 20 -p 'choose group:') +# +#if [ -n "$group" ] +#then +# account=$(pass list "$group" | sed 1d | sed -E 's/โ”œโ”€โ”€|โ””โ”€โ”€| //'| sed 's/ //' | dmenu -l 20 -p "choose account from $group:") +# +# if [ -n "$account" ] +# then +# temp="$group/$account" +# echo "$temp" +# pass -c "$temp" > $HOME/.cache/passstring +# sed -e "s/^/\"/" -e "s/$/\"/" $HOME/.cache/passstring | xargs notify-send "Password" +# rm $HOME/.cache/passstring +# sleep 45 +# notify-send "Password" "password cleared from clipboard" +# fi +#fi diff --git a/.local/bin/tools/qndl b/.local/bin/tools/qndl new file mode 100755 index 0000000..a99d37e --- /dev/null +++ b/.local/bin/tools/qndl @@ -0,0 +1,11 @@ +#!/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="youtube-dl --add-metadata" +idnum="$(tsp $cmd "$1")" +realname="$(echo "$base" | sed "s/?\(source\|dest\).*//;s/%20/ /g")" +tsp -D "$idnum" mv "$base" "$realname" +tsp -D "$idnum" notify-send "๐Ÿ‘ $realname done." diff --git a/.local/bin/tools/queueandnotify b/.local/bin/tools/queueandnotify new file mode 100755 index 0000000..a1417ec --- /dev/null +++ b/.local/bin/tools/queueandnotify @@ -0,0 +1,13 @@ +#!/bin/sh +# Podboat sucks. This script replaces it. +# It reads the newsboat queue, queuing downloads with taskspooler. +# It also removes the junk from extentions. +queuefile="$HOME/.local/share/newsboat/queue" + +while read -r line; do + [ -z "$line" ] && continue + url="$(echo "$line" | awk '{print $1}')" + qndl "$url" "curl -LO" +done < "$queuefile" + +echo > "$queuefile" diff --git a/.local/bin/tools/refbar b/.local/bin/tools/refbar new file mode 100755 index 0000000..b346cf0 --- /dev/null +++ b/.local/bin/tools/refbar @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# Refresh the dwmbar. +# Send SIGTRAP signal to dwmbar script, which will handle it with a trap. +pkill -SIGTRAP dwmbar diff --git a/.local/bin/tools/restart b/.local/bin/tools/restart new file mode 100755 index 0000000..bdcad40 --- /dev/null +++ b/.local/bin/tools/restart @@ -0,0 +1,3 @@ +#!/bin/sh +pkill $1 +setsid $1 diff --git a/.local/bin/tools/ripper b/.local/bin/tools/ripper new file mode 100755 index 0000000..08dad9d --- /dev/null +++ b/.local/bin/tools/ripper @@ -0,0 +1,43 @@ +#!/bin/zsh + +#needed if run as cronjob +export XDG_VIDEOS_DIR=$HOME/vids + +DLARCHIVE=$XDG_VIDEOS_DIR/.downloaded +DLLOC=$XDG_VIDEOS_DIR +CHANNELSFILE=$XDG_VIDEOS_DIR/.channels + + +#STILL NOT WORKING +# Required to display notifications if run as a cronjob: +export XAUTHORITY="/home/alex/.cache/xdg_run/Xauthority" # This line will break some DMs. +export DISPLAY=:0.0 +DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus + +range="now-40years" +notify-send "Channel Ripper" "Scanning for new Videos to download" +echo "Scanning for new Videos to download" +grep 'youtube' "$CHANNELSFILE" | sed "s/$/\/videos/" |xargs -L1 lynx --dump --nonumbers -listonly $1 | grep "youtube.com/watch?v=" | grep -v "&list" > /tmp/todownload +grep 'youtube' "$DLARCHIVE" | sed 's/youtube /https:\/\/www\.youtube\.com\/watch?v=/' > /tmp/alreadydownloaded + +grep 'bitchute' "$CHANNELSFILE" | xargs -L1 lynx --dump --nonumbers -listonly $1 | grep 'bitchute\.com\/video' | sort -u >> /tmp/todownload +grep 'bitchute' "$DLARCHIVE" | sed 's/bitchute /https:\/\/www\.bitchute\.com\/video\//' >> /tmp/alreadydownloaded + +number=$(grep -vf /tmp/alreadydownloaded /tmp/todownload | sort -u | wc -l) + +if [ $number -gt 0 ]; then + [ $number -eq 1 ] && ( notify-send "Channel Ripper" "1 new video available for download, downloading now." ) || ( notify-send "Channel Ripper" "$number new videos available for download, downloading now." ) + echo "$number new videos for download available, downloading now." + grep -vf /tmp/alreadydownloaded /tmp/todownload | sort -u | xargs -L1 youtube-dl --get-filename -o "'%(uploader)s' '%(title)s'" $1 | xargs -L1 notify-send + grep -vf /tmp/alreadydownloaded /tmp/todownload | sort -u | grep 'youtube' | xargs -r -L1 youtube-dl --hls-prefer-native -i --download-archive $DLARCHIVE --dateafter $range -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' --add-metadata -o "$DLLOC/%(uploader)s/%(upload_date)s-%(title)s.%(ext)s" + grep -vf /tmp/alreadydownloaded /tmp/todownload | sort -u | grep 'bitchute' | xargs -r -L1 youtube-dl --hls-prefer-native -i --download-archive $DLARCHIVE -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' --add-metadata -o "$DLLOC/%(uploader)s/%(title)s.%(ext)s" + notify-send "Channel Ripper" "Finished downloading" +fi + +if [ $number -eq 0 ]; then + echo "No new Videos" + notify-send "Channel Ripper" "No new Videos" +fi + +rm -f /tmp/alreadydownloaded +rm -f /tmp/todownload diff --git a/.local/bin/tools/rotdir b/.local/bin/tools/rotdir new file mode 100755 index 0000000..e7103db --- /dev/null +++ b/.local/bin/tools/rotdir @@ -0,0 +1,4 @@ +#!/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/tools/rssadd b/.local/bin/tools/rssadd new file mode 100755 index 0000000..8822fc5 --- /dev/null +++ b/.local/bin/tools/rssadd @@ -0,0 +1,9 @@ +#!/bin/sh +! echo "$1" | grep "https*://\S\+\.[A-Za-z]\+\S*" >/dev/null && + notify-send "That doesn't look like a full URL." && exit +RSSFILE="$HOME/.config/newsboat/urls" +if awk '{print $1}' "$RSSFILE" | grep "^$1$" >/dev/null; then + notify-send "You already have this RSS feed." +else + echo "$1" >> "$RSSFILE" && notify-send "RSS feed added." +fi diff --git a/.local/bin/tools/score b/.local/bin/tools/score new file mode 100755 index 0000000..94c13d5 --- /dev/null +++ b/.local/bin/tools/score @@ -0,0 +1,3 @@ +#!/bin/sh +categories=$(( $(cat $1 | grep -oE '[0-9]*$' | wc -l ) - 1 )) +grep -oE '[0-9]*$' $1 | head -n $categories | paste -sd+ | bc diff --git a/.local/bin/tools/search b/.local/bin/tools/search new file mode 100755 index 0000000..f0def24 --- /dev/null +++ b/.local/bin/tools/search @@ -0,0 +1 @@ +find -iname "*$1*" diff --git a/.local/bin/tools/setbg b/.local/bin/tools/setbg new file mode 100755 index 0000000..950ae7c --- /dev/null +++ b/.local/bin/tools/setbg @@ -0,0 +1,4 @@ +#!/bin/sh +# Sets the background. If given an argument, will set file as background. +[ ! -z "$1" ] && cp "$1" ~/.config/wall.png && notify-send -i "$HOME/.config/wall.png" "Wallpaper changed." +xwallpaper --zoom ~/.config/wall.png diff --git a/.local/bin/tools/shortcuts b/.local/bin/tools/shortcuts new file mode 100755 index 0000000..1c4f278 --- /dev/null +++ b/.local/bin/tools/shortcuts @@ -0,0 +1,26 @@ +#!/bin/bash +# Output locations. Unactivated progs should go to /dev/null. +shell_shortcuts="$HOME/.config/shortcutrc" +ranger_shortcuts="/dev/null" +qute_shortcuts="/dev/null" +fish_shortcuts="/dev/null" +vifm_shortcuts="$HOME/.config/vifm/vifmshortcuts" + +# Remove, prepare files +rm -f "$ranger_shortcuts" "$qute_shortcuts" 2>/dev/null +printf "# vim: filetype=sh\\n" > "$fish_shortcuts" +printf "# vim: filetype=sh\\nalias " > "$shell_shortcuts" +printf "\" vim: filetype=vim\\n" > "$vifm_shortcuts" + +# Format the `bmdirs` file in the correct syntax and sent it to all three configs. +sed "s/\s*#.*$//;/^\s*$/d" "$HOME/.config/bmdirs" | tee >(awk '{print $1"=\"cd "$2" && ls -a\" \\"}' >> "$shell_shortcuts") \ + >(awk '{print "abbr", $1, "\"cd " $2 "; and ls -a\""}' >> "$fish_shortcuts") \ + >(awk '{print "map g" $1, ":cd", $2 "<CR>\nmap t" $1, "<tab>:cd", $2 "<CR><tab>\nmap M" $1, "<tab>:cd", $2 "<CR><tab>:mo<CR>\nmap Y" $1, "<tab>:cd", $2 "<CR><tab>:co<CR>" }' >> "$vifm_shortcuts") \ + >(awk '{print "config.bind(\";"$1"\", \"set downloads.location.directory "$2" ;; hint links download\")"}' >> "$qute_shortcuts") \ + | awk '{print "map g"$1" cd "$2"\nmap t"$1" tab_new "$2"\nmap m"$1" shell mv -v %s "$2"\nmap Y"$1" shell cp -rv %s "$2}' >> "$ranger_shortcuts" + +# Format the `configs` file in the correct syntax and sent it to both configs. +sed "s/\s*#.*$//;/^\s*$/d" "$HOME/.config/bmfiles" | tee >(awk '{print $1"=\"$EDITOR "$2"\" \\"}' >> "$shell_shortcuts") \ + >(awk '{print "abbr", $1, "\"$EDITOR "$2"\""}' >> "$fish_shortcuts") \ + >(awk '{print "map", $1, ":e", $2 "<CR>" }' >> "$vifm_shortcuts") \ + | awk '{print "map "$1" shell $EDITOR "$2}' >> "$ranger_shortcuts" diff --git a/.local/bin/tools/startanki b/.local/bin/tools/startanki new file mode 100755 index 0000000..f19058d --- /dev/null +++ b/.local/bin/tools/startanki @@ -0,0 +1,4 @@ +#!/bin/bash +anki & +sleep 2 +hover center diff --git a/.local/bin/tools/startzoom b/.local/bin/tools/startzoom new file mode 100755 index 0000000..513ee8c --- /dev/null +++ b/.local/bin/tools/startzoom @@ -0,0 +1,2 @@ +#!/bin/sh +sh /opt/zoom/zoom.sh diff --git a/.local/bin/tools/temp_bt b/.local/bin/tools/temp_bt new file mode 100755 index 0000000..a8e7e20 --- /dev/null +++ b/.local/bin/tools/temp_bt @@ -0,0 +1,3 @@ +#!/bin/bash +bluetoothctl power on +bluetoothctl scan on diff --git a/.local/bin/tools/texclear b/.local/bin/tools/texclear new file mode 100755 index 0000000..f6a5062 --- /dev/null +++ b/.local/bin/tools/texclear @@ -0,0 +1,14 @@ +#!/bin/sh + +# Clears the build files of a LaTeX/XeLaTeX build. +# I have vim run this file whenever I exit a .tex file. + +case "$1" in + *.tex) + file=$(readlink -f "$1") + dir=$(dirname "$file") + base="${file%.*}" + find "$dir" -maxdepth 1 -type f -regextype gnu-awk -regex "^$base\\.(4tc|xref|tmp|pyc|pyo|fls|vrb|fdb_latexmk|bak|swp|aux|log|synctex\\(busy\\)|lof|lot|maf|idx|mtc|mtc0|nav|out|snm|toc|bcf|run\\.xml|synctex\\.gz|blg|bbl)" -delete ;; + *) printf "Give .tex file as argument.\\n" ;; +esac + diff --git a/.local/bin/tools/timer b/.local/bin/tools/timer new file mode 100755 index 0000000..c2e4fab --- /dev/null +++ b/.local/bin/tools/timer @@ -0,0 +1,23 @@ +#!/bin/bash +turns=15 +if [[ -n $1 ]];then + turns=$1 +fi +echo "Starting!" +let "i=1" +notify-send "Timer" "Starting, $turns minutes to go" +for ((turn=1; turn<=$turns; turn++)); +do + clear + echo "turn $turn" + echo "###########" + sleep 2 + for seconds in {1..60} + do + echo "$seconds secs. passed" + sleep 1 + done + notify-send "Timer" "Switch\n($i/$turns done)" + let "i=i+1" +done +clear diff --git a/.local/bin/tools/toprim b/.local/bin/tools/toprim new file mode 100755 index 0000000..4bfad47 --- /dev/null +++ b/.local/bin/tools/toprim @@ -0,0 +1,2 @@ +#!/bin/sh +xclip -o -selection "primary" | xclip -i -selection 'clipboard' diff --git a/.local/bin/tools/transadd b/.local/bin/tools/transadd new file mode 100755 index 0000000..ad2ee7f --- /dev/null +++ b/.local/bin/tools/transadd @@ -0,0 +1,9 @@ +#!/bin/sh + +# Mimeapp script for adding torrent to transmission-daemon, but will also start the daemon first if not running. + +# transmission-daemon sometimes fails to take remote requests in its first moments. + +pgrep -x transmission-da || (transmission-daemon && notify-send "Starting transmission daemon..." && sleep 3 && pkill -RTMIN+7 i3blocks) + +transmission-remote -a "$@" && notify-send "๐Ÿ”ฝ Torrent added." diff --git a/.local/bin/tools/vifmimg b/.local/bin/tools/vifmimg new file mode 100755 index 0000000..1569962 --- /dev/null +++ b/.local/bin/tools/vifmimg @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +[ -z "$FIFO_UEBERZUG" ] && exit + +readonly ID_PREVIEW="preview" + +if [ "$1" = "draw" ]; then + declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" [x]="$2" [y]="$3" [max_width]="$4" [max_height]="$5" [path]="${PWD}/$6") > "$FIFO_UEBERZUG" +elif [ "$1" = "videopreview" ]; then + [ ! -f "/tmp/$6.png" ] && ffmpegthumbnailer -i "${PWD}/$6" -o "/tmp/$6.png" -s 0 -q 10 && + declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" [x]="$2" [y]="$3" [max_width]="$4" [max_height]="$5" [path]="/tmp/$6.png") > "$FIFO_UEBERZUG" +else + declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") > "$FIFO_UEBERZUG" +fi diff --git a/.local/bin/tools/vu b/.local/bin/tools/vu new file mode 100755 index 0000000..778835a --- /dev/null +++ b/.local/bin/tools/vu @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +export FIFO_UEBERZUG="/tmp/vifm-ueberzug-${PPID}" + +cleanup() { + rm "$FIFO_UEBERZUG" 2>/dev/null + pkill -P $$ 2>/dev/null +} + +rm "$FIFO_UEBERZUG" 2>/dev/null +mkfifo "$FIFO_UEBERZUG" +trap cleanup EXIT +tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser bash & + +vifm +cleanup diff --git a/.local/bin/tools/wv b/.local/bin/tools/wv new file mode 100755 index 0000000..5bd742f --- /dev/null +++ b/.local/bin/tools/wv @@ -0,0 +1,11 @@ +#!/bin/sh +alldata="/tmp/allfiles" +videos="/tmp/videos" +du -a ~/vids/* --time | sort -u | awk '!($1="")' | sort -bg | awk '!($1="")' | awk '!($1="")' | sed 's/^ //' | tac > $alldata +touch $videos +while read line; do + [ -f "$line" ] && echo $line >> $videos +done <$alldata +cat $videos | dmenu -i -l 30 -p "Choose a video to watch:" | sed 's/^/\"/' | sed 's/$/\"/' | xargs -r xdg-open +rm "$alldata" +rm "$videos" diff --git a/.local/bin/torwrap b/.local/bin/torwrap new file mode 100755 index 0000000..4f94053 --- /dev/null +++ b/.local/bin/torwrap @@ -0,0 +1,7 @@ +#!/bin/sh + +ifinstalled tremc-git transmission-cli || exit + +! pidof transmission-daemon >/dev/null && transmission-daemon && notify-send "Starting torrent daemon..." + +$TERMINAL -e tremc; pkill -RTMIN+7 "${STATUSBAR:-dwmblocks}" diff --git a/.local/bin/transadd b/.local/bin/transadd new file mode 100755 index 0000000..1b9599e --- /dev/null +++ b/.local/bin/transadd @@ -0,0 +1,9 @@ +#!/bin/sh + +# Mimeapp script for adding torrent to transmission-daemon, but will also start the daemon first if not running. + +# transmission-daemon sometimes fails to take remote requests in its first moments, hence the sleep. + +pidof transmission-daemon >/dev/null || (transmission-daemon && notify-send "Starting transmission daemon..." && sleep 3 && pkill -RTMIN+7 "${STATUSBAR:-dwmblocks}") & + +transmission-remote -a "$@" && notify-send "๐Ÿ”ฝ Torrent added." diff --git a/.local/bin/ttymaps.kmap b/.local/bin/ttymaps.kmap new file mode 100644 index 0000000..51a7042 --- /dev/null +++ b/.local/bin/ttymaps.kmap @@ -0,0 +1,2 @@ +keycode 1 = Caps_Lock +keycode 58 = Escape diff --git a/.local/bin/tutorialvids b/.local/bin/tutorialvids new file mode 100755 index 0000000..5ca5c50 --- /dev/null +++ b/.local/bin/tutorialvids @@ -0,0 +1,20 @@ +#!/bin/sh + +vidlist=" +status bar https://www.youtube.com/watch?v=gKumet6b-WY +sxiv (image viewer) https://www.youtube.com/watch?v=GYW9i_u5PYs +st (terminal) https://www.youtube.com/watch?v=9H75enWM22k +i3 (window manager) https://www.youtube.com/watch?v=GKviflL9XeI +pacman (installing/managing programs) https://www.youtube.com/watch?v=-dEuXTMzRKs +mutt (email) https://www.youtube.com/watch?v=2U3vRbF7v5A +ncmpcpp (music player) https://www.youtube.com/watch?v=sZIEdI9TS2U +newsboat (RSS reader) https://www.youtube.com/watch?v=dUFCRqs822w +ranger (file manager) https://www.youtube.com/watch?v=L6Vu7WPkoJo +zathura (pdf viewer) https://www.youtube.com/watch?v=V_Iz4zdyRM4 +gpg keys https://www.youtube.com/watch?v=DMGIlj7u7Eo +calcurse (calendar) https://www.youtube.com/watch?v=hvc-pHjbhdE +urlview https://www.youtube.com/watch?v=IgzpAjFgbCw +colorschemes with pywal https://www.youtube.com/watch?v=Es79N_9BblE +vi mode in shell https://www.youtube.com/watch?v=GqoJQft5R2E +" +echo "$vidlist" | grep -P "^$(echo "$vidlist" | grep "https:" | sed 's/\t.*//g' | dmenu -i -p "Learn about what? (ESC to cancel)" -l 20 | awk '{print $1}')\s" | sed 's/.*\t//' | xargs -r mpv diff --git a/.local/bin/ueberzug b/.local/bin/ueberzug new file mode 100755 index 0000000..35c201c --- /dev/null +++ b/.local/bin/ueberzug @@ -0,0 +1,12 @@ +#!/usr/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'ueberzug==18.1.5','console_scripts','ueberzug' +__requires__ = 'ueberzug==18.1.5' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('ueberzug==18.1.5', 'console_scripts', 'ueberzug')() + ) diff --git a/.local/bin/ueberzug_ b/.local/bin/ueberzug_ new file mode 100755 index 0000000..35c201c --- /dev/null +++ b/.local/bin/ueberzug_ @@ -0,0 +1,12 @@ +#!/usr/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'ueberzug==18.1.5','console_scripts','ueberzug' +__requires__ = 'ueberzug==18.1.5' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('ueberzug==18.1.5', 'console_scripts', 'ueberzug')() + ) diff --git a/.local/bin/unix b/.local/bin/unix new file mode 100755 index 0000000..a9fb96e --- /dev/null +++ b/.local/bin/unix @@ -0,0 +1,26 @@ +#!/bin/sh + +#original artwork by http://www.sanderfocus.nl/#/portfolio/tech-heroes +#converted to shell by #nixers @ irc.unix.chat + +cat << 'eof' + ,_ ,_==โ–„โ–‚ + , โ–‚โ–ƒโ–„โ–„โ–…โ–…โ–…โ–‚โ–…ยพ. / / + โ–„โ–†<ยด "ยปโ–“โ–“โ–“%\ / / / / + ,โ–…7" ยด>โ–“โ–“โ–“% / / > / >/% + โ–ยถโ–“ ,ยปโ–“โ–“ยพยด /> %/%// / / + โ–“โ–ƒโ–…โ–…โ–…โ–ƒ,,โ–„โ–…โ–…โ–…ร†\// ///>// />/ / + Vโ•‘ยซยผ.;โ†’ โ•‘<ยซ.,`=// />//%/% / / + //โ• <ยด -ยฒ,)(โ–“~"-โ•/ยพ/ %/>/ /> + / / / โ–% -./โ–„โ–ƒโ–„โ–…โ–, /7//;//% / / + / ////`โ–Œโ– %zWv xXโ–“โ–‡โ–Œ//&;% / / + / / / %//%/ยพยฝยดโ–Œโ–ƒโ–„โ–„โ–„โ–„โ–ƒโ–ƒโ–ยถ\/& / + </ /</%//`โ–“!%โ–“%โ•ฃ[38;5;255;โ•ฃWY<Y)y&/`\ + / / %/%//</%//\i7; โ• N>)VY>7; \_ UNIX IS VERY SIMPLE IT JUST NEEDS A + / /</ //<///<_/%\โ–“ V%W%ยฃ)XY _/%โ€พ\_, GENIUS TO UNDERSTAND ITS SIMPLICITY + / / //%/_,=--^/%/%%\ยพ%ยถ%%} /%%%%%%;\, + %/< /_/ %%%%%;X%%\%%;, _/%%%;, \ + / / %%%%%%;, \%%l%%;// _/%;, dmr + / %%%;, <;\-=-/ / + ;, l +eof diff --git a/.local/bin/unix_ b/.local/bin/unix_ new file mode 100755 index 0000000..14d7ef0 --- /dev/null +++ b/.local/bin/unix_ @@ -0,0 +1,25 @@ +#!/bin/sh +#original artwork by http://www.sanderfocus.nl/#/portfolio/tech-heroes +#converted to shell by #nixers @ irc.unix.chat + +cat << 'eof' + ,_ ,_==โ–„โ–‚ + , โ–‚โ–ƒโ–„โ–„โ–…โ–…โ–…โ–‚โ–…ยพ. / / + โ–„โ–†<ยด "ยปโ–“โ–“โ–“%\ / / / / + ,โ–…7" ยด>โ–“โ–“โ–“% / / > / >/% + โ–ยถโ–“ ,ยปโ–“โ–“ยพยด /> %/%// / / + โ–“โ–ƒโ–…โ–…โ–…โ–ƒ,,โ–„โ–…โ–…โ–…ร†\// ///>// />/ / + Vโ•‘ยซยผ.;โ†’ โ•‘<ยซ.,`=// />//%/% / / + //โ• <ยด -ยฒ,)(โ–“~"-โ•/ยพ/ %/>/ /> + / / / โ–% -./โ–„โ–ƒโ–„โ–…โ–, /7//;//% / / + / ////`โ–Œโ– %zWv xXโ–“โ–‡โ–Œ//&;% / / + / / / %//%/ยพยฝยดโ–Œโ–ƒโ–„โ–„โ–„โ–„โ–ƒโ–ƒโ–ยถ\/& / + </ /</%//`โ–“!%โ–“%โ•ฃ[38;5;255;โ•ฃWY<Y)y&/`\ + / / %/%//</%//\i7; โ• N>)VY>7; \_ UNIX IS VERY SIMPLE IT JUST NEEDS A + / /</ //<///<_/%\โ–“ V%W%ยฃ)XY _/%โ€พ\_, GENIUS TO UNDERSTAND ITS SIMPLICITY + / / //%/_,=--^/%/%%\ยพ%ยถ%%} /%%%%%%;\, + %/< /_/ %%%%%;X%%\%%;, _/%%%;, \ + / / %%%%%%;, \%%l%%;// _/%;, dmr + / %%%;, <;\-=-/ / + ;, l +eof \ No newline at end of file diff --git a/.local/bin/update_musicbar b/.local/bin/update_musicbar new file mode 100755 index 0000000..3d6f80d --- /dev/null +++ b/.local/bin/update_musicbar @@ -0,0 +1,3 @@ +#!/bin/sh +pkill -RTMIN+11 dwmblocks +#echo 'sent signal to dwmblocks' diff --git a/.local/bin/vifmimg b/.local/bin/vifmimg new file mode 100755 index 0000000..8fb8eed --- /dev/null +++ b/.local/bin/vifmimg @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +[ -z "$FIFO_UEBERZUG" ] && exit + +readonly ID_PREVIEW="preview" + +if [ "$1" = "draw" ]; then + declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" [x]="$2" [y]="$3" [max_width]="$4" [max_height]="$5" [path]="${PWD}/$6") > "$FIFO_UEBERZUG" +elif [ "$1" = "videopreview" ]; then + [ ! -f "/tmp/$6.png" ] && ffmpegthumbnailer -i "${PWD}/$6" -o "/tmp/$6.png" -s 0 -q 10 && + declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" [x]="$2" [y]="$3" [max_width]="$4" [max_height]="$5" [path]="/tmp/$6.png") > "$FIFO_UEBERZUG" +else + declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") > "$FIFO_UEBERZUG" +fi diff --git a/.local/bin/vnc b/.local/bin/vnc new file mode 100755 index 0000000..84e0af9 --- /dev/null +++ b/.local/bin/vnc @@ -0,0 +1,69 @@ +#!/bin/bash +# ---------------------------------------------------------------------------- +# "THE BEER-WARE LICENSE" (Revision 42): +# <k.bumsik@gmail.com> wrote this file. As long as you retain this notice you +# can do whatever you want with this stuff. If we meet some day, and you think +# this stuff is worth it, you can buy me a beer in return. - Bumsik Kim +# ---------------------------------------------------------------------------- + +# Configuration +WIDTH=1920 # 1368 for iPad Pro +HEIGHT=1080 # 1024 for iPad Pro +MODE_NAME="mode_ipad" # Set whatever name you like, you may need to change + # this when you change resolution, or just reboot. +DIS_NAME="VIRTUAL1" # Don't change it unless you know what it is +RANDR_POS="--right-of" # Default position setting for xrandr command + +# Parse arguments +while [ "$#" -gt 0 ]; do + case $1 in + -l|--left) RANDR_POS="--left-of" ;; + -r|--right) RANDR_POS="--right-of" ;; + -a|--above) RANDR_POS="--above" ;; + -b|--below) RANDR_POS="--below" ;; + -p|--portrait) TMP=$WIDTH; WIDTH=$HEIGHT; HEIGHT=$TMP + MODE_NAME="$MODE_NAME""_port" ;; + -h|--hidpi) WIDTH=$(($WIDTH * 2)); HEIGHT=$(($HEIGHT * 2)) + MODE_NAME="$MODE_NAME""_hidpi" ;; + *) echo "'$1' cannot be a monitor position"; exit 1 ;; + esac + shift +done + +# Detect primary display +PRIMARY_DISPLAY=$(xrandr | perl -ne 'print "$1" if /(\w*)\s*connected\s*primary/') + +# Add display mode +RANDR_MODE=$(cvt "$WIDTH" "$HEIGHT" 60 | sed '2s/^.*Modeline\s*\".*\"//;2q;d') +xrandr --addmode $DIS_NAME $MODE_NAME 2>/dev/null +# If the mode doesn't exist then make mode and retry +if ! [ $? -eq 0 ]; then + xrandr --newmode $MODE_NAME $RANDR_MODE + xrandr --addmode $DIS_NAME $MODE_NAME +fi + +# Show display first +xrandr --output $DIS_NAME --mode $MODE_NAME +# Then move display +sleep 5 # A short delay is needed. Otherwise sometimes the below command is ignored. +xrandr --output $DIS_NAME $RANDR_POS $PRIMARY_DISPLAY + +# Cleanup before exit +function finish { + xrandr --output $DIS_NAME --off + xrandr --delmode $DIS_NAME $MODE_NAME + echo "Second monitor disabled." +} + +trap finish EXIT + +# Get the display's position +CLIP_POS=$(xrandr | perl -ne 'print "$1" if /'$DIS_NAME'\s*connected\s*(\d*x\d*\+\d*\+\d*)/') +echo $CLIP_POS +# Share screen +x11vnc -multiptr -repeat -clip $CLIP_POS +# Possible alternative is x0vncserver but it does not show the mouse cursor. +# x0vncserver -display :0 -geometry $DIS_NAME -overlaymode -passwordfile ~/.vnc/passwd +if ! [ $? -eq 0 ]; then + echo x11vnc failed, did you \'apt-get install x11vnc\'? +fi diff --git a/.local/bin/wal b/.local/bin/wal new file mode 100755 index 0000000..7cd22a8 --- /dev/null +++ b/.local/bin/wal @@ -0,0 +1,12 @@ +#!/usr/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pywal==3.3.0','console_scripts','wal' +__requires__ = 'pywal==3.3.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pywal==3.3.0', 'console_scripts', 'wal')() + ) diff --git a/.local/bin/wheel b/.local/bin/wheel new file mode 100755 index 0000000..8149efb --- /dev/null +++ b/.local/bin/wheel @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from wheel.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.local/bin/xlsx2csv b/.local/bin/xlsx2csv new file mode 100755 index 0000000..4ab987f --- /dev/null +++ b/.local/bin/xlsx2csv @@ -0,0 +1,1137 @@ +#!/usr/bin/python +# +# Copyright information +# +# Copyright (C) 2010-2018 Dilshod Temirkhodjaev <tdilshod@gmail.com> +# +# License +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +from __future__ import print_function + +__author__ = "Dilshod Temirkhodjaev <tdilshod@gmail.com>" +__license__ = "GPL-2+" +__version__ = "0.7.6" + +import csv, datetime, zipfile, string, sys, os, re, signal +import xml.parsers.expat +from xml.dom import minidom + +try: + # python2.4 + from cStringIO import StringIO +except: + pass +try: + from argparse import ArgumentParser +except: + # python2.4 + from optparse import OptionParser + +# see also ruby-roo lib at: http://github.com/hmcgowan/roo +FORMATS = { + 'general': 'float', + '0': 'float', + '0.00': 'float', + '#,##0': 'float', + '#,##0.00': 'float', + '0%': 'percentage', + '0.00%': 'percentage', + '0.00e+00': 'float', + 'mm-dd-yy': 'date', + 'd-mmm-yy': 'date', + 'd-mmm': 'date', + 'mmm-yy': 'date', + 'h:mm am/pm': 'date', + 'h:mm:ss am/pm': 'date', + 'h:mm': 'time', + 'h:mm:ss': 'time', + 'm/d/yy h:mm': 'date', + '#,##0 ;(#,##0)': 'float', + '#,##0 ;[red](#,##0)': 'float', + '#,##0.00;(#,##0.00)': 'float', + '#,##0.00;[red](#,##0.00)': 'float', + 'mm:ss': 'time', + '[h]:mm:ss': 'time', + 'mmss.0': 'time', + '##0.0e+0': 'float', + '@': 'float', + 'yyyy\\-mm\\-dd': 'date', + 'dd/mm/yy': 'date', + 'hh:mm:ss': 'time', + "dd/mm/yy\\ hh:mm": 'date', + 'dd/mm/yyyy hh:mm:ss': 'date', + 'yy-mm-dd': 'date', + 'd-mmm-yyyy': 'date', + 'm/d/yy': 'date', + 'm/d/yyyy': 'date', + 'dd-mmm-yyyy': 'date', + 'dd/mm/yyyy': 'date', + 'mm/dd/yy h:mm am/pm': 'date', + 'mm/dd/yy hh:mm': 'date', + 'mm/dd/yyyy h:mm am/pm': 'date', + 'mm/dd/yyyy hh:mm:ss': 'date', + 'yyyy-mm-dd hh:mm:ss': 'date', + '#,##0;(#,##0)': 'float', + '_(* #,##0_);_(* (#,##0);_(* "-"??_);_(@_)': 'float', + '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)': 'float' +} +STANDARD_FORMATS = { + 0: 'general', + 1: '0', + 2: '0.00', + 3: '#,##0', + 4: '#,##0.00', + 9: '0%', + 10: '0.00%', + 11: '0.00e+00', + 12: '# ?/?', + 13: '# ??/??', + 14: 'mm-dd-yy', + 15: 'd-mmm-yy', + 16: 'd-mmm', + 17: 'mmm-yy', + 18: 'h:mm am/pm', + 19: 'h:mm:ss am/pm', + 20: 'h:mm', + 21: 'h:mm:ss', + 22: 'm/d/yy h:mm', + 37: '#,##0 ;(#,##0)', + 38: '#,##0 ;[red](#,##0)', + 39: '#,##0.00;(#,##0.00)', + 40: '#,##0.00;[red](#,##0.00)', + 45: 'mm:ss', + 46: '[h]:mm:ss', + 47: 'mmss.0', + 48: '##0.0e+0', + 49: '@', +} +CONTENT_TYPES = { + 'shared_strings', + 'styles', + 'workbook', + 'worksheet', + 'relationships', +} + +DEFAULT_APP_PATH = "/xl" +DEFAULT_WORKBOOK_PATH = DEFAULT_APP_PATH + "/workbook.xml" + + +class XlsxException(Exception): + pass + + +class InvalidXlsxFileException(XlsxException): + pass + + +class SheetNotFoundException(XlsxException): + pass + + +class OutFileAlreadyExistsException(XlsxException): + pass + + +class Xlsx2csv: + """ + Usage: Xlsx2csv("test.xslx", **params).convert("test.csv", sheetid=1) + Input: + xlsxfile - path to file or filehandle + options: + sheetid - sheet no to convert (0 for all sheets) + dateformat - override date/time format + timeformat - override time format + floatformat - override float format + quoting - if and how to quote + delimiter - csv columns delimiter symbol + sheetdelimiter - sheets delimiter used when processing all sheets + skip_empty_lines - skip empty lines + skip_trailing_columns - skip trailing columns + hyperlinks - include hyperlinks + include_sheet_pattern - only include sheets named matching given pattern + exclude_sheet_pattern - exclude sheets named matching given pattern + """ + + def __init__(self, xlsxfile, **options): + options.setdefault("delimiter", ",") + options.setdefault("quoting", csv.QUOTE_MINIMAL) + options.setdefault("sheetdelimiter", "--------") + options.setdefault("dateformat", None) + options.setdefault("timeformat", None) + options.setdefault("floatformat", None) + options.setdefault("scifloat", False) + options.setdefault("skip_empty_lines", False) + options.setdefault("skip_trailing_columns", False) + options.setdefault("escape_strings", False) + options.setdefault("hyperlinks", False) + options.setdefault("include_sheet_pattern", ["^.*$"]) + options.setdefault("exclude_sheet_pattern", []) + options.setdefault("merge_cells", False) + options.setdefault("ignore_formats", ['']) + options.setdefault("lineterminator", "\n") + + self.options = options + try: + self.ziphandle = zipfile.ZipFile(xlsxfile) + except (zipfile.BadZipfile, IOError): + raise InvalidXlsxFileException("Invalid xlsx file: " + str(xlsxfile)) + + self.py3 = sys.version_info[0] == 3 + + self.content_types = self._parse(ContentTypes, "/[Content_Types].xml") + self.shared_strings = self._parse(SharedStrings, self.content_types.types["shared_strings"]) + self.styles = self._parse(Styles, self.content_types.types["styles"]) + self.workbook = self._parse(Workbook, self.content_types.types["workbook"]) + workbook_relationships = list(filter(lambda r: "book" in r, self.content_types.types["relationships"]))[0] + self.workbook.relationships = self._parse(Relationships, workbook_relationships) + if self.options['escape_strings']: + self.shared_strings.escape_strings() + + def __del__(self): + # make sure to close zip file, ziphandler does have a close() method + self.ziphandle.close() + + def getSheetIdByName(self, name): + for s in self.workbook.sheets: + if s['name'] == name: + return s['index'] + return None + + def convert(self, outfile, sheetid=1): + """outfile - path to file or filehandle""" + if sheetid > 0: + self._convert(sheetid, outfile) + else: + if isinstance(outfile, str): + if not os.path.exists(outfile): + os.makedirs(outfile) + elif os.path.isfile(outfile): + raise OutFileAlreadyExistsException("File " + str(outfile) + " already exists!") + for s in self.workbook.sheets: + sheetname = s['name'] + + # filter sheets by include pattern + include_sheet_pattern = self.options['include_sheet_pattern'] + if type(include_sheet_pattern) == type(""): # optparser lib fix + include_sheet_pattern = [include_sheet_pattern] + if len(include_sheet_pattern) > 0: + include = False + for pattern in include_sheet_pattern: + include = pattern and len(pattern) > 0 and re.match(pattern, sheetname) + if include: + break + if not include: + continue + + # filter sheets by exclude pattern + exclude_sheet_pattern = self.options['exclude_sheet_pattern'] + if type(exclude_sheet_pattern) == type(""): # optparser lib fix + exclude_sheet_pattern = [exclude_sheet_pattern] + exclude = False + for pattern in exclude_sheet_pattern: + exclude = pattern and len(pattern) > 0 and re.match(pattern, sheetname) + if exclude: + break + if exclude: + continue + + if not self.py3: + sheetname = sheetname.encode('utf-8') + of = outfile + if isinstance(outfile, str): + of = os.path.join(outfile, sheetname + '.csv') + elif self.options['sheetdelimiter'] and len(self.options['sheetdelimiter']): + of.write(self.options['sheetdelimiter'] + " " + str(s['index']) + " - " + sheetname + self.options['lineterminator']) + self._convert(s['index'], of) + + def _convert(self, sheet_index, outfile): + closefile = False + if isinstance(outfile, str): + if sys.version_info[0] == 2: + outfile = open(outfile, 'wb+') + elif sys.version_info[0] == 3: + outfile = open(outfile, 'w+', encoding=self.options['outputencoding'], newline="") + else: + sys.stderr.write("error: version of your python is not supported: " + str(sys.version_info) + "\n") + sys.exit(1) + closefile = True + try: + writer = csv.writer(outfile, quoting=self.options['quoting'], delimiter=self.options['delimiter'], + lineterminator=self.options['lineterminator']) + + sheets_filtered = list(filter(lambda s: s['index'] == sheet_index, self.workbook.sheets)) + if len(sheets_filtered) == 0: + eprint("Sheet with index %i not found or can't be handled" % sheet_index) + return 1 + + sheet_path = None + # using sheet relation information + if 'relation_id' in sheets_filtered[0] and sheets_filtered[0]['relation_id'] is not None: + + relation_id = sheets_filtered[0]['relation_id'] + if relation_id in self.workbook.relationships.relationships and \ + 'target' in self.workbook.relationships.relationships[relation_id]: + relationship = self.workbook.relationships.relationships[relation_id] + sheet_path = "/xl/" + relationship['target'] + + if sheet_path is None: + sheet_path = "/xl/worksheets/sheet%i.xml" % sheet_index + if sheet_path is None: + sheet_path = "/xl/worksheets/worksheet%i.xml" % sheet_index + if sheet_path is None and sheet_index == 1: + sheet_path = self.content_types.types["worksheet"] + if sheet_path is None: + raise SheetNotFoundException("Sheet %i not found" % sheet_index) + sheet_file = self._filehandle(sheet_path) + sheet = Sheet(self.workbook, self.shared_strings, self.styles, sheet_file) + try: + relationships_path = os.path.join(os.path.dirname(sheet_path), + "_rels", + os.path.basename(sheet_path) + ".rels") + sheet.relationships = self._parse(Relationships, relationships_path) + sheet.set_dateformat(self.options['dateformat']) + sheet.set_timeformat(self.options['timeformat']) + sheet.set_floatformat(self.options['floatformat']) + sheet.set_skip_empty_lines(self.options['skip_empty_lines']) + sheet.set_skip_trailing_columns(self.options['skip_trailing_columns']) + sheet.set_include_hyperlinks(self.options['hyperlinks']) + sheet.set_merge_cells(self.options['merge_cells']) + sheet.set_scifloat(self.options['scifloat']) + sheet.set_ignore_formats(self.options['ignore_formats']) + if self.options['escape_strings'] and sheet.filedata: + sheet.filedata = re.sub(r"(<v>[^<>]+) ([^<>]+</v>)", r"\1\\n\2", + re.sub(r"(<v>[^<>]+) ([^<>]+</v>)", r"\1\\t\2", + re.sub(r"(<v>[^<>]+) ([^<>]+</v>)", r"\1\\r\2", sheet.filedata))) + sheet.to_csv(writer) + finally: + sheet_file.close() + sheet.close() + finally: + if closefile: + outfile.close() + + def _filehandle(self, filename): + for name in filter(lambda f: filename and f.lower() == filename.lower()[1:], self.ziphandle.namelist()): + # python2.4 fix + if not hasattr(self.ziphandle, "open"): + return StringIO(self.ziphandle.read(name)) + return self.ziphandle.open(name, "r") + return None + + def _parse(self, klass, filename): + instance = klass() + filehandle = self._filehandle(filename) + if filehandle: + instance.parse(filehandle) + filehandle.close() + return instance + + +class Workbook: + def __init__(self): + self.sheets = list() + self.date1904 = False + + def parse(self, filehandle): + workbookDoc = minidom.parseString(filehandle.read()) + if workbookDoc.firstChild.namespaceURI: + fileVersion = workbookDoc.firstChild.getElementsByTagNameNS(workbookDoc.firstChild.namespaceURI, + "fileVersion") + else: + fileVersion = workbookDoc.firstChild.getElementsByTagName("fileVersion") + if len(fileVersion) == 0: + self.appName = DEFAULT_APP_PATH + else: + try: + if workbookDoc.firstChild.namespaceURI: + self.appName = \ + workbookDoc.firstChild.getElementsByTagNameNS( + workbookDoc.firstChild.namespaceURI, "fileVersion")[0]._attrs['appName'].value + else: + self.appName = workbookDoc.firstChild.getElementsByTagName("fileVersion")[0]._attrs['appName'].value + except KeyError: + # no app name + self.appName = DEFAULT_APP_PATH + try: + if workbookDoc.firstChild.namespaceURI: + self.date1904 = \ + workbookDoc.firstChild.getElementsByTagNameNS( + workbookDoc.firstChild.namespaceURI, "workbookPr")[0]._attrs['date1904'].value.lower().strip() \ + != "false" + else: + self.date1904 = \ + workbookDoc.firstChild.getElementsByTagName("workbookPr")[0] \ + ._attrs['date1904'].value.lower().strip() \ + != "false" + except: + pass + + if workbookDoc.firstChild.namespaceURI: + sheets = workbookDoc.firstChild.getElementsByTagNameNS(workbookDoc.firstChild.namespaceURI, "sheets")[0] + else: + sheets = workbookDoc.firstChild.getElementsByTagName("sheets")[0] + if workbookDoc.firstChild.namespaceURI: + sheetNodes = sheets.getElementsByTagNameNS(workbookDoc.firstChild.namespaceURI, "sheet") + else: + sheetNodes = sheets.getElementsByTagName("sheet") + for i, sheetNode in enumerate(sheetNodes): + attrs = sheetNode._attrs + name = attrs["name"].value + relation_id = None + if 'r:id' in attrs: + relation_id = attrs['r:id'].value + self.sheets.append({'name': name, 'relation_id': relation_id, 'index': i + 1, 'id': i + 1}) # remove id starting 0.8.0 version + + +class ContentTypes: + def __init__(self): + self.types = {} + for type in CONTENT_TYPES: + self.types[type] = None + + def parse(self, filehandle): + types = minidom.parseString(filehandle.read()).firstChild + if not types: + return + if types.namespaceURI: + overrideNodes = types.getElementsByTagNameNS(types.namespaceURI, "Override") + else: + overrideNodes = types.getElementsByTagName("Override") + for override in overrideNodes: + attrs = override._attrs + type = attrs.get('ContentType').value + name = attrs.get('PartName').value + if type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": + self.types["workbook"] = name + elif type == "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": + self.types["styles"] = name + elif type == "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": + # BUG preserved only last sheet + self.types["worksheet"] = name + elif type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml": + self.types["shared_strings"] = name + elif type == "application/vnd.openxmlformats-package.relationships+xml": + if self.types["relationships"] is None: + self.types["relationships"] = list() + self.types["relationships"].append(name) + + if self.types["workbook"] is None: + self.types["workbook"] = DEFAULT_WORKBOOK_PATH + if self.types["relationships"] is None: + self.types["relationships"] = [os.path.dirname(self.types["workbook"]) + "/_rels/" + \ + os.path.basename(self.types["workbook"]) + ".rels"] + + +class Relationships: + def __init__(self): + self.relationships = {} + + def parse(self, filehandle): + doc = minidom.parseString(filehandle.read()) + if doc.namespaceURI: + relationships = doc.getElementsByTagNameNS(doc.namespaceURI, "Relationships") + else: + relationships = doc.getElementsByTagName("Relationships") + if not relationships: + return + if doc.namespaceURI: + relationshipNodes = relationships[0].getElementsByTagNameNS(doc.namespaceURI, "Relationship") + else: + relationshipNodes = relationships[0].getElementsByTagName("Relationship") + for rel in relationshipNodes: + attrs = rel._attrs + rId = attrs.get('Id') + if rId: + vtype = attrs.get('Type') + target = attrs.get('Target') + self.relationships[str(rId.value)] = { + "type": vtype and str(vtype.value) or None, + "target": target and str(target.value) or None + } + + +class Styles: + def __init__(self): + self.numFmts = {} + self.cellXfs = [] + + def parse(self, filehandle): + styles = minidom.parseString(filehandle.read()).firstChild + # numFmts + if styles.namespaceURI: + numFmtsElement = styles.getElementsByTagNameNS(styles.namespaceURI, "numFmts") + else: + numFmtsElement = styles.getElementsByTagName("numFmts") + if len(numFmtsElement) == 1: + for numFmt in numFmtsElement[0].childNodes: + if numFmt.nodeType == minidom.Node.ELEMENT_NODE: + numFmtId = int(numFmt._attrs['numFmtId'].value) + formatCode = numFmt._attrs['formatCode'].value.lower().replace('\\', '') + self.numFmts[numFmtId] = formatCode + + if styles.namespaceURI: + cellXfsElement = styles.getElementsByTagNameNS(styles.namespaceURI, "cellXfs") + else: + cellXfsElement = styles.getElementsByTagName("cellXfs") + if len(cellXfsElement) == 1: + for cellXfs in cellXfsElement[0].childNodes: + if cellXfs.nodeType != minidom.Node.ELEMENT_NODE or not ( + cellXfs.nodeName == "xf" or cellXfs.nodeName.endswith(":xf")): + continue + if cellXfs._attrs and 'numFmtId' in cellXfs._attrs: + numFmtId = int(cellXfs._attrs['numFmtId'].value) + if self.chk_exists(numFmtId) == None: + numFmtId = int(cellXfs._attrs['applyNumberFormat'].value) + self.cellXfs.append(numFmtId) + else: + self.cellXfs.append(None) + + # When Unknown Numformat ID assign applyNumberFormat + def chk_exists(self, numFmtId): + xfs_numfmt = numFmtId + format_str = None + if xfs_numfmt in self.numFmts: + format_str = self.numFmts[xfs_numfmt] + elif xfs_numfmt in STANDARD_FORMATS: + format_str = STANDARD_FORMATS[xfs_numfmt] + return format_str + + +class SharedStrings: + def __init__(self): + self.parser = None + self.strings = [] + self.si = False + self.t = False + self.rPh = False + self.value = "" + + def parse(self, filehandle): + self.parser = xml.parsers.expat.ParserCreate() + self.parser.CharacterDataHandler = self.handleCharData + self.parser.StartElementHandler = self.handleStartElement + self.parser.EndElementHandler = self.handleEndElement + self.parser.ParseFile(filehandle) + + def escape_strings(self): + for i in range(0, len(self.strings)): + self.strings[i] = self.strings[i].replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t") + + def handleCharData(self, data): + if self.t: + self.value += data + + def handleStartElement(self, name, attrs): + # ignore namespace + i = name.find(":") + if i >= 0: + name = name[i + 1:] + + if name == 'si': + self.si = True + self.value = "" + elif name == 't' and self.rPh: + self.t = False + elif name == 't' and self.si: + self.t = True + elif name == 'rPh': + self.rPh = True + + def handleEndElement(self, name): + # ignore namespace + i = name.find(":") + if i >= 0: + name = name[i + 1:] + + if name == 'si': + self.si = False + self.strings.append(self.value) + elif name == 't': + self.t = False + elif name == 'rPh': + self.rPh = False + + +class Sheet: + def __init__(self, workbook, sharedString, styles, filehandle): + self.py3 = sys.version_info[0] == 3 + self.parser = None + self.writer = None + self.sharedString = None + self.styles = None + self.relationships = None + self.columns_count = -1 + + self.in_sheet = False + self.in_row = False + self.in_cell = False + self.in_cell_value = False + + self.columns = {} + self.lastRowNum = 0 + self.rowNum = None + self.colType = None + self.cellId = None + self.s_attr = None + self.data = None + self.max_columns = -1 + + self.dateformat = None + self.timeformat = "%H:%M" # default time format + self.floatformat = None + self.skip_empty_lines = False + self.skip_trailing_columns = False + + self.filedata = None + self.filehandle = filehandle + self.workbook = workbook + self.sharedStrings = sharedString.strings + self.styles = styles + + self.hyperlinks = {} + self.mergeCells = {} + self.ignore_formats = [] + + self.colIndex = 0 + self.colNum = "" + + def close(self): + # Make sure Worksheet is closed, parsers lib does not have a close() function, so simply delete it + self.parser = None + + def set_dateformat(self, dateformat): + self.dateformat = dateformat + + def set_timeformat(self, timeformat): + if timeformat: + self.timeformat = timeformat + + def set_floatformat(self, floatformat): + self.floatformat = floatformat + + def set_skip_empty_lines(self, skip): + self.skip_empty_lines = skip + + def set_skip_trailing_columns(self, skip): + self.skip_trailing_columns = skip + + def set_ignore_formats(self, ignore_formats): + self.ignore_formats = ignore_formats + + def set_merge_cells(self, mergecells): + if not mergecells: + return + if not self.filedata: + self.filedata = self.filehandle.read() + data = str(self.filedata) # python3: convert byte buffer to string + + # find worksheet tag, we need namespaces from it + start = data.find("<worksheet") + if start < 0: + return + end = data.find(">", start) + worksheet = data[start: end + 1] + + # find hyperlinks part + start = data.find("<mergeCells") + if start < 0: + # hyperlinks not found + return + end = data.find("</mergeCells>") + data = data[start: end + 13] + + # parse hyperlinks + doc = minidom.parseString(worksheet + data + "</worksheet>").firstChild + + if doc.namespaceURI: + mergeCells = doc.getElementsByTagNameNS(doc.namespaceURI, "mergeCell") + else: + mergeCells = doc.getElementsByTagName("mergeCell") + for mergeCell in mergeCells: + attrs = mergeCell._attrs + if 'ref' in attrs.keys(): + rangeStr = attrs['ref'].value + rng = rangeStr.split(":") + if len(rng) > 1: + for cell in self._range(rangeStr): + self.mergeCells[cell] = {} + self.mergeCells[cell]['copyFrom'] = rng[0] + + def set_scifloat(self, scifloat): + self.scifloat = scifloat + + def set_include_hyperlinks(self, hyperlinks): + if not hyperlinks or not self.relationships or not self.relationships.relationships: + return + # we must read file first to get hyperlinks, but we don't wont to parse whole file + if not self.filedata: + self.filedata = self.filehandle.read() + data = str(self.filedata) # python3: convert byte buffer to string + + # find worksheet tag, we need namespaces from it + start = data.find("<worksheet") + if start < 0: + return + end = data.find(">", start) + worksheet = data[start: end + 1] + + # find hyperlinks part + start = data.find("<hyperlinks>") + if start < 0: + # hyperlinks not found + return + end = data.find("</hyperlinks>") + data = data[start: end + 13] + + # parse hyperlinks + doc = minidom.parseString(worksheet + data + "</worksheet>").firstChild + if doc.namespaceURI: + hiperlinkNodes = doc.getElementsByTagNameNS(doc.namespaceURI, "hyperlink") + else: + hiperlinkNodes = doc.getElementsByTagName("hyperlink") + for hlink in hiperlinkNodes: + attrs = hlink._attrs + ref = rId = None + for k in attrs.keys(): + if k == "ref": + ref = str(attrs[k].value) + if k.endswith(":id"): + rId = str(attrs[k].value) + if not ref or not rId: + continue + rel = self.relationships.relationships.get(rId) + if not rel: + continue + target = rel.get('target') + for cell in self._range(ref): + self.hyperlinks[cell] = target + + def to_csv(self, writer): + self.writer = writer + self.parser = xml.parsers.expat.ParserCreate() + self.parser.buffer_text = True + self.parser.CharacterDataHandler = self.handleCharData + self.parser.StartElementHandler = self.handleStartElement + self.parser.EndElementHandler = self.handleEndElement + if self.filedata: + self.parser.Parse(self.filedata) + else: + self.parser.ParseFile(self.filehandle) + + def handleCharData(self, data): + if self.in_cell_value: + self.collected_string += data + self.data = self.collected_string + if self.colType == "s": # shared string + self.data = self.sharedStrings[int(self.data)] + elif self.colType == "b": # boolean + self.data = (int(data) == 1 and "TRUE") or (int(data) == 0 and "FALSE") or data + elif self.colType == "str" or self.colType == "inlineStr": + self.data = data + elif self.s_attr: + s = int(self.s_attr) + + # get cell format + format_str = "general" + xfs_numfmt = self.styles.cellXfs[s] + if xfs_numfmt in self.styles.numFmts: + format_str = self.styles.numFmts[xfs_numfmt] + elif xfs_numfmt in STANDARD_FORMATS: + format_str = STANDARD_FORMATS[xfs_numfmt] + + # get format type + if not format_str: + eprint("unknown format %s at %d" % (format_str, xfs_numfmt)) + return + + format_type = None + if format_str in FORMATS: + format_type = FORMATS[format_str] + elif re.match("^\d+(\.\d+)?$", self.data) and re.match(".*[hsmdyY]", format_str) and not re.match( + '.*\[.*[dmhys].*\]', format_str): + # it must be date format + if float(self.data) < 1: + format_type = "time" + else: + format_type = "date" + elif re.match("^-?\d+(.\d+)?$", self.data) or ( + self.scifloat and re.match("^-?\d+(.\d+)?([eE]-?\d+)?$", self.data)): + format_type = "float" + if format_type == 'date' and self.dateformat == 'float': + format_type = "float" + if format_type and not format_type in self.ignore_formats: + try: + if format_type == 'date': # date/time + if self.workbook.date1904: + date = datetime.datetime(1904, 1, 1) + datetime.timedelta(float(self.data)) + else: + date = datetime.datetime(1899, 12, 30) + datetime.timedelta(float(self.data)) + if self.dateformat: + # str(dateformat) - python2.5 bug, see: http://bugs.python.org/issue2782 + self.data = date.strftime(str(self.dateformat)) + else: + # ignore ";@", don't know what does it mean right now + # ignore "[$-409], [$-f409], [$-16001]" and similar format codes + dateformat = re.sub(r"\[\$\-[A-z0-9]*\]", "", format_str, 1) \ + .replace(";@", "").replace("yyyy", "%Y").replace("yy", "%y") \ + .replace("hh:mm", "%H:%M").replace("h", "%I").replace("%H%H", "%H") \ + .replace("ss", "%S").replace("dddd", "d").replace("dd", "d").replace("d", "%d") \ + .replace("am/pm", "%p").replace("mmmm", "%B").replace("mmm", "%b") \ + .replace(":mm", ":%M").replace("m", "%m").replace("%m%m", "%m") + self.data = date.strftime(str(dateformat)).strip() + elif format_type == 'time': # time + t = int(round((float(self.data) % 1) * 24 * 60 * 60, 6)) # it should be in seconds + d = datetime.time(int((t // 3600) % 24), int((t // 60) % 60), int(t % 60)) + self.data = d.strftime(self.timeformat) + elif format_type == 'float' and ('E' in self.data or 'e' in self.data): + self.data = str(self.floatformat or '%f') % float(self.data) + # if cell is general, be aggressive about stripping any trailing 0s, decimal points, etc. + elif format_type == 'float' and format_str == 'general': + self.data = ("%f" % (float(self.data))).rstrip('0').rstrip('.') + elif format_type == 'float' and format_str[0:3] == '0.0': + if self.floatformat: + self.data = str(self.floatformat) % float(self.data) + else: + L = len(format_str.split(".")[1]) + if '%' in format_str: + L += 1 + self.data = ("%." + str(L) + "f") % float(self.data) + elif format_type == 'float': + # unsupported float formatting + self.data = ("%f" % (float(self.data))).rstrip('0').rstrip('.') + + except (ValueError, OverflowError): # this catch must be removed, it's hiding potential problems + eprint("Error: potential invalid date format.") + # invalid date format + pass + + def handleStartElement(self, name, attrs): + has_namespace = name.find(":") > 0 + if self.in_row and (name == 'c' or (has_namespace and name.endswith(':c'))): + self.colType = attrs.get("t") + self.s_attr = attrs.get("s") + self.cellId = attrs.get("r") + if self.cellId: + self.colNum = self.cellId[:len(self.cellId) - len(self.rowNum)] + self.colIndex = 0 + else: + self.colIndex += 1 + self.data = "" + self.in_cell = True + elif self.in_cell and ( + (name == 'v' or name == 'is') or (has_namespace and (name.endswith(':v') or name.endswith(':is')))): + self.in_cell_value = True + self.collected_string = "" + elif self.in_sheet and (name == 'row' or (has_namespace and name.endswith(':row'))) and ('r' in attrs): + self.rowNum = attrs['r'] + self.in_row = True + self.colIndex = 0 + self.colNum = "" + self.columns = {} + self.spans = None + if 'spans' in attrs: + self.spans = [int(i) for i in attrs['spans'].split(" ")[-1].split(":")] + elif name == 't': + # reset collected string + self.collected_string = "" + + elif name == 'sheetData' or (has_namespace and name.endswith(':sheetData')): + self.in_sheet = True + elif name == 'dimension': + rng = attrs.get("ref").split(":") + if len(rng) > 1: + start = re.match("^([A-Z]+)(\d+)$", rng[0]) + if (start): + end = re.match("^([A-Z]+)(\d+)$", rng[1]) + startCol = start.group(1) + endCol = end.group(1) + self.columns_count = 0 + for cell in self._range(startCol + "1:" + endCol + "1"): + self.columns_count += 1 + + def handleEndElement(self, name): + has_namespace = name.find(":") > 0 + if self.in_cell and ((name == 'v' or name == 'is' or name == 't') or ( + has_namespace and (name.endswith(':v') or name.endswith(':is')))): + self.in_cell_value = False + elif self.in_cell and (name == 'c' or (has_namespace and name.endswith(':c'))): + t = 0 + for i in self.colNum: t = t * 26 + ord(i) - 64 + d = self.data + if self.hyperlinks: + hyperlink = self.hyperlinks.get(self.cellId) + if hyperlink: + d = "<a href='" + hyperlink + "'>" + d + "</a>" + if self.colNum + self.rowNum in self.mergeCells.keys(): + if 'copyFrom' in self.mergeCells[self.colNum + self.rowNum].keys() and \ + self.mergeCells[self.colNum + self.rowNum]['copyFrom'] == self.colNum + self.rowNum: + self.mergeCells[self.colNum + self.rowNum]['value'] = d + else: + d = self.mergeCells[self.mergeCells[self.colNum + self.rowNum]['copyFrom']]['value'] + + self.columns[t - 1 + self.colIndex] = d + + if self.in_row and (name == 'row' or (has_namespace and name.endswith(':row'))): + if len(self.columns.keys()) > 0: + d = [""] * (max(self.columns.keys()) + 1) + for k in self.columns.keys(): + val = self.columns[k] + if not self.py3: + val = val.encode("utf-8") + d[k] = val + if self.spans: + l = self.spans[1] + if len(d) < l: + d += (l - len(d)) * [''] + + # write empty lines + if not self.skip_empty_lines: + for i in range(self.lastRowNum, int(self.rowNum) - 1): + self.writer.writerow([]) + self.lastRowNum = int(self.rowNum) + + # write line to csv + if not self.skip_empty_lines or d.count('') != len(d): + while len(d) < self.columns_count: + d.append("") + + if self.skip_trailing_columns: + if self.max_columns < 0: + self.max_columns = len(d) + while len(d) > 0 and d[-1] == "": + d = d[0:-1] + self.max_columns = self.max_columns - 1 + elif self.max_columns > 0: + d = d[0:self.max_columns] + self.writer.writerow(d) + + self.in_row = False + elif self.in_sheet and (name == 'sheetData' or (has_namespace and name.endswith(':sheetData'))): + self.in_sheet = False + + # rangeStr: "A3:C12" or "D5" + # example: for cell in _range("A1:Z12"): print cell + def _range(self, rangeStr): + rng = rangeStr.split(":") + if len(rng) == 1: + yield rangeStr + else: + start = re.match("^([A-Z]+)(\d+)$", rng[0]) + end = re.match("^([A-Z]+)(\d+)$", rng[1]) + if not start or not end: + return + startCol = start.group(1) + startRow = int(start.group(2)) + endCol = end.group(1) + endRow = int(end.group(2)) + col = startCol + while True: + for row in range(startRow, endRow + 1): + yield col + str(row) + if col == endCol: + break + t = 0 + for i in col: t = t * 26 + ord(i) - 64 + col = "" + while t >= 0: + col = chr(t % 26 + 65) + col + t = t // 26 - 1 + + +def convert_recursive(path, sheetid, outfile, kwargs): + for name in os.listdir(path): + fullpath = os.path.join(path, name) + if os.path.isdir(fullpath): + convert_recursive(fullpath, sheetid, outfile, kwargs) + else: + outfilepath = outfile + if len(outfilepath) == 0 and fullpath.lower().endswith(".xlsx"): + outfilepath = fullpath[:-4] + 'csv' + + print("Converting %s to %s" % (fullpath, outfilepath)) + try: + Xlsx2csv(fullpath, **kwargs).convert(outfilepath, sheetid) + except zipfile.BadZipfile: + print("File %s is not a zip file" % fullpath) + + +if __name__ == "__main__": + try: + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + signal.signal(signal.SIGINT, signal.SIG_DFL) + except AttributeError: + pass + + if "ArgumentParser" in globals(): + parser = ArgumentParser(description="xlsx to csv converter") + parser.add_argument('infile', metavar='xlsxfile', help="xlsx file path") + parser.add_argument('outfile', metavar='outfile', nargs='?', help="output csv file path") + parser.add_argument('-v', '--version', action='version', version=__version__) + nargs_plus = "+" + argparser = True + else: + parser = OptionParser(usage="%prog [options] infile [outfile]", version=__version__) + parser.add_argument = parser.add_option + nargs_plus = 1 + argparser = False + + if sys.version_info[0] == 2 and sys.version_info[1] < 5: + inttype = "int" + else: + inttype = int + parser.add_argument("-a", "--all", dest="all", default=False, action="store_true", + help="export all sheets") + parser.add_argument("-c", "--outputencoding", dest="outputencoding", default="utf-8", action="store", + help="encoding of output csv ** Python 3 only ** (default: utf-8)") + parser.add_argument("-d", "--delimiter", dest="delimiter", default=",", + help="delimiter - columns delimiter in csv, 'tab' or 'x09' for a tab (default: comma ',')") + parser.add_argument("--hyperlinks", "--hyperlinks", dest="hyperlinks", action="store_true", default=False, + help="include hyperlinks") + parser.add_argument("-e", "--escape", dest='escape_strings', default=False, action="store_true", + help="Escape \\r\\n\\t characters") + parser.add_argument("-E", "--exclude_sheet_pattern", nargs=nargs_plus, dest="exclude_sheet_pattern", default="", + help="exclude sheets named matching given pattern, only effects when -a option is enabled.") + parser.add_argument("-f", "--dateformat", dest="dateformat", + help="override date/time format (ex. %%Y/%%m/%%d)") + parser.add_argument("-t", "--timeformat", dest="timeformat", + help="override time format (ex. %%H/%%M/%%S)") + parser.add_argument("--floatformat", dest="floatformat", + help="override float format (ex. %%.15f)") + parser.add_argument("--sci-float", dest="scifloat", default=False, action="store_true", + help="force scientific notation to float") + parser.add_argument("-I", "--include_sheet_pattern", nargs=nargs_plus, dest="include_sheet_pattern", default="^.*$", + help="only include sheets named matching given pattern, only effects when -a option is enabled.") + parser.add_argument("--ignore-formats", nargs=nargs_plus, type=str, dest="ignore_formats", default=[''], + help="Ignores format for specific data types.") + parser.add_argument("-l", "--lineterminator", dest="lineterminator", default="\n", + help="line terminator - lines terminator in csv, '\\n' '\\r\\n' or '\\r' (default: \\n)") + parser.add_argument("-m", "--merge-cells", dest="merge_cells", default=False, action="store_true", + help="merge cells") + parser.add_argument("-n", "--sheetname", dest="sheetname", default=None, + help="sheet name to convert") + parser.add_argument("-i", "--ignoreempty", dest="skip_empty_lines", default=False, action="store_true", + help="skip empty lines") + parser.add_argument("--skipemptycolumns", dest="skip_trailing_columns", default=False, action="store_true", + help="skip trailing empty columns") + parser.add_argument("-p", "--sheetdelimiter", dest="sheetdelimiter", default="--------", + help="sheet delimiter used to separate sheets, pass '' if you do not need delimiter, or 'x07' " + "or '\\f' for form feed (default: '--------')") + parser.add_argument("-q", "--quoting", dest="quoting", default="minimal", + help="quoting - fields quoting in csv, 'none' 'minimal' 'nonnumeric' or 'all' (default: minimal)") + parser.add_argument("-s", "--sheet", dest="sheetid", default=1, type=inttype, + help="sheet number to convert") + + if argparser: + options = parser.parse_args() + else: + (options, args) = parser.parse_args() + if len(args) < 1: + parser.print_usage() + sys.stderr.write("error: too few arguments" + os.linesep) + sys.exit(1) + options.infile = args[0] + options.outfile = len(args) > 1 and args[1] or None + + if len(options.delimiter) == 1: + pass + elif options.delimiter == 'tab' or options.delimiter == '\\t': + options.delimiter = '\t' + elif options.delimiter == 'comma': + options.delimiter = ',' + elif options.delimiter[0] == 'x': + options.delimiter = chr(int(options.delimiter[1:])) + else: + sys.stderr.write("error: invalid delimiter\n") + sys.exit(1) + + if options.quoting == 'none': + options.quoting = csv.QUOTE_NONE + elif options.quoting == 'minimal': + options.quoting = csv.QUOTE_MINIMAL + elif options.quoting == 'nonnumeric': + options.quoting = csv.QUOTE_NONNUMERIC + elif options.quoting == 'all': + options.quoting = csv.QUOTE_ALL + else: + sys.stderr.write("error: invalid quoting\n") + sys.exit(1) + + if options.lineterminator == '\n': + pass + elif options.lineterminator == '\\n': + options.lineterminator = '\n' + elif options.lineterminator == '\\r': + options.lineterminator = '\r' + elif options.lineterminator == '\\r\\n': + options.lineterminator = '\r\n' + else: + sys.stderr.write("error: invalid line terminator\n") + sys.exit(1) + + if options.sheetdelimiter == '--------': + pass + elif options.sheetdelimiter == '': + pass + elif options.sheetdelimiter == '\\f': + options.sheetdelimiter = '\f' + elif options.sheetdelimiter[0] == 'x': + options.sheetdelimiter = chr(int(options.sheetdelimiter[1:])) + else: + sys.stderr.write("error: invalid sheet delimiter\n") + sys.exit(1) + + kwargs = { + 'delimiter': options.delimiter, + 'quoting': options.quoting, + 'sheetdelimiter': options.sheetdelimiter, + 'dateformat': options.dateformat, + 'timeformat': options.timeformat, + 'floatformat': options.floatformat, + 'scifloat': options.scifloat, + 'skip_empty_lines': options.skip_empty_lines, + 'skip_trailing_columns': options.skip_trailing_columns, + 'escape_strings': options.escape_strings, + 'hyperlinks': options.hyperlinks, + 'include_sheet_pattern': options.include_sheet_pattern, + 'exclude_sheet_pattern': options.exclude_sheet_pattern, + 'merge_cells': options.merge_cells, + 'outputencoding': options.outputencoding, + 'lineterminator': options.lineterminator, + 'ignore_formats': options.ignore_formats + } + sheetid = options.sheetid + if options.all: + sheetid = 0 + + outfile = options.outfile or sys.stdout + try: + if os.path.isdir(options.infile): + convert_recursive(options.infile, sheetid, outfile, kwargs) + else: + xlsx2csv = Xlsx2csv(options.infile, **kwargs) + if options.sheetname: + sheetid = xlsx2csv.getSheetIdByName(options.sheetname) + if not sheetid: + raise XlsxException("Sheet '%s' not found" % options.sheetname) + xlsx2csv.convert(outfile, sheetid) + except XlsxException: + _, e, _ = sys.exc_info() + sys.stderr.write(str(e) + "\n") + sys.exit(1) + + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) diff --git a/.profile b/.profile new file mode 120000 index 0000000..c1abe3f --- /dev/null +++ b/.profile @@ -0,0 +1 @@ +.zprofile \ No newline at end of file diff --git a/.xprofile b/.xprofile new file mode 120000 index 0000000..c000896 --- /dev/null +++ b/.xprofile @@ -0,0 +1 @@ +.config/xprofile \ No newline at end of file diff --git a/.zprofile b/.zprofile new file mode 100644 index 0000000..2b87552 --- /dev/null +++ b/.zprofile @@ -0,0 +1,144 @@ +#!/bin/zsh + +# zsh profile file. Runs on login. Environmental variables are set here. + +# If you don't plan on reverting to bash, you can remove the link in ~/.profile +# to clean up. + +# Adds `~/.local/bin` to $PATH +export PATH="$PATH:$(du "$HOME/.local/bin/" | cut -f2 | tr '\n' ':' | sed 's/:*$//')" +# Adds cargo bin path to $PATH +export PATH="$PATH:$(du "$HOME/.local/share/cargo/bin/" | cut -f2 | tr '\n' ':' | sed 's/:*$//')" + +# Default programs: +export EDITOR="nvim" +export TERMINAL="st" +export BROWSER="qutebrowser" +export READER="zathura" +export FILE="ranger" +export PIC="sxiv" +export SHELL="zsh" + +# ~/ Clean-up: +export XDG_CONFIG_HOME="$HOME/.config" +export XDG_DATA_HOME="$HOME/.local/share" +export XDG_CACHE_HOME="$HOME/.cache" +#export XDG_RUNTIME_DIR="$HOME/.cache/xdg_run" # Messes up Audio for some reason, might be useful to figure out in the future how to fix +#export XAUTHORITY="$HOME/.cache/xdg_run/Xauthority" # This line will break some DMs. +export NOTMUCH_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/notmuch-config" +export GTK2_RC_FILES="${XDG_CONFIG_HOME:-$HOME/.config}/gtk-2.0/gtkrc-2.0" +export LESSHISTFILE="-" +export WGETRC="${XDG_CONFIG_HOME:-$HOME/.config}/wget/wgetrc" +export INPUTRC="${XDG_CONFIG_HOME:-$HOME/.config}/inputrc" +export ZDOTDIR="${XDG_CONFIG_HOME:-$HOME/.config}/zsh" +export ALSA_CONFIG_PATH="$XDG_CONFIG_HOME/alsa/asoundrc" +export GNUPGHOME="$XDG_DATA_HOME/gnupg" +#export GNUPGHOME="$HOME/.gnupg" +export WINEPREFIX="${XDG_DATA_HOME:-$HOME/.local/share}/wineprefixes/default" +export KODI_DATA="${XDG_DATA_HOME:-$HOME/.local/share}/kodi" +export PASSWORD_STORE_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/password-store" +export TMUX_TMPDIR="$XDG_RUNTIME_DIR" +export ANDROID_SDK_HOME="${XDG_CONFIG_HOME:-$HOME/.config}/android" +export CARGO_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/cargo" +export GOPATH="${XDG_DATA_HOME:-$HOME/.local/share}/go" +export ANSIBLE_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/ansible/ansible.cfg" +export SSB_HOME="$XDG_DATA_HOME/zoom" +export PASSWORD_STORE_GPG_OPTS='--homedir=/home/alex/.local/share/gnupg' + + +# XDG USER DIRECOTRIES +export XDG_DESKTOP_DIR="$HOME" +export XDG_DOCUMENTS_DIR="$HOME/dox" +export XDG_DOWNLOAD_DIR="$HOME/dl" +export XDG_MUSIC_DIR="$HOME/msc" +export XDG_PICTURES_DIR="$HOME/pics" +export XDG_VIDEOS_DIR="$HOME/vids" + +# Other program settings: +export DICS="/usr/share/stardict/dic/" +export SUDO_ASKPASS="$HOME/.local/bin/dmenupass" +export FZF_DEFAULT_OPTS="--layout=reverse --height 40%" +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 LESSOPEN="| /usr/bin/highlight -O ansi %s 2>/dev/null" +export QT_QPA_PLATFORMTHEME="gtk2" # Have QT use gtk2 theme. +export MOZ_USE_XINPUT2="1" # Mozilla smooth scrolling/touchpads. +export _JAVA_AWT_WM_NONREPARENTING=1 # Java doesn't understand tiling windows +export AWT_TOOLKIT="MToolkit wmname LG3D" #May have to install wmname + +# This is the list for lf icons: +export LF_ICONS="di=๐Ÿ“:\ +fi=๐Ÿ“ƒ:\ +tw=๐Ÿค:\ +ow=๐Ÿ“‚:\ +ln=โ›“:\ +or=โŒ:\ +ex=๐ŸŽฏ:\ +*.txt=โœ:\ +*.mom=โœ:\ +*.me=โœ:\ +*.ms=โœ:\ +*.png=๐Ÿ–ผ:\ +*.ico=๐Ÿ–ผ:\ +*.jpg=๐Ÿ“ธ:\ +*.jpeg=๐Ÿ“ธ:\ +*.gif=๐Ÿ–ผ:\ +*.svg=๐Ÿ—บ:\ +*.xcf=๐Ÿ–Œ:\ +*.html=๐ŸŒŽ:\ +*.xml=๐Ÿ“ฐ:\ +*.gpg=๐Ÿ”’:\ +*.css=๐ŸŽจ:\ +*.pdf=๐Ÿ“š:\ +*.djvu=๐Ÿ“š:\ +*.epub=๐Ÿ“š:\ +*.csv=๐Ÿ““:\ +*.xlsx=๐Ÿ““:\ +*.tex=๐Ÿ“œ:\ +*.md=๐Ÿ“˜:\ +*.r=๐Ÿ“Š:\ +*.R=๐Ÿ“Š:\ +*.rmd=๐Ÿ“Š:\ +*.Rmd=๐Ÿ“Š:\ +*.mp3=๐ŸŽต:\ +*.opus=๐ŸŽต:\ +*.ogg=๐ŸŽต:\ +*.m4a=๐ŸŽต:\ +*.flac=๐ŸŽผ:\ +*.mkv=๐ŸŽฅ:\ +*.mp4=๐ŸŽฅ:\ +*.webm=๐ŸŽฅ:\ +*.mpeg=๐ŸŽฅ:\ +*.avi=๐ŸŽฅ:\ +*.zip=๐Ÿ“ฆ:\ +*.rar=๐Ÿ“ฆ:\ +*.7z=๐Ÿ“ฆ:\ +*.tar.gz=๐Ÿ“ฆ:\ +*.z64=๐ŸŽฎ:\ +*.v64=๐ŸŽฎ:\ +*.n64=๐ŸŽฎ:\ +*.1=โ„น:\ +*.nfo=โ„น:\ +*.info=โ„น:\ +*.log=๐Ÿ“™:\ +*.iso=๐Ÿ“€:\ +*.img=๐Ÿ“€:\ +*.bib=๐ŸŽ“:\ +*.ged=๐Ÿ‘ช:\ +*.part=๐Ÿ’”:\ +*.torrent=๐Ÿ”ฝ:\ +" + +[ ! -f ${XDG_CONFIG_HOME:-$HOME/.config}/shortcutrc ] && shortcuts >/dev/null 2>&1 & + +# Start graphical server on tty1 if not already running. +[ "$(tty)" = "/dev/tty1" ] && ! ps -e | grep -qw Xorg && exec startx + +# Switch escape and caps if tty and no passwd required: +sudo -n loadkeys ${XDG_DATA_HOME:-$HOME/.local/share}/larbs/ttymaps.kmap 2>/dev/null