summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.Xresources.un~bin0 -> 6376 bytes
-rw-r--r--.gitignore57
-rw-r--r--.gitmodules12
-rw-r--r--Ultisnips/django.snippets3
-rw-r--r--Ultisnips/python.snippets4
-rw-r--r--User/keybindings.json21
-rw-r--r--User/settings.json57
-rw-r--r--Xresources177
-rw-r--r--Xresources-alt101
-rw-r--r--Xresources-bak98
-rw-r--r--abookrc40
-rw-r--r--bashrc134
-rw-r--r--bpython/config96
-rw-r--r--bugwarriorrc41
-rw-r--r--coc-settings.json23
-rw-r--r--compton.conf52
-rw-r--r--config/i3-laptop/config280
-rw-r--r--config/i3-laptop/config-bak241
-rw-r--r--config/i3/config-laptop279
-rw-r--r--config/i3blocks/config191
-rw-r--r--ctags3
-rw-r--r--fish/.config.fish.un~bin0 -> 595 bytes
-rw-r--r--fish/completions/bcompiler.fish7
-rw-r--r--fish/completions/catnote.fish1
-rw-r--r--fish/completions/fisher.fish1
-rw-r--r--fish/completions/hl-monthly-for-account.fish1
-rw-r--r--fish/completions/hl-weekly-for-account.fish1
-rw-r--r--fish/completions/pass.fish117
-rw-r--r--fish/completions/pipenv.fish1
-rw-r--r--fish/completions/poetry.fish145
-rw-r--r--fish/completions/twdft.fish6
-rw-r--r--fish/config.fish38
-rw-r--r--fish/fish_variables43
-rw-r--r--fish/fishd.debian936
-rw-r--r--fish/fishfile2
-rw-r--r--fish/functions/.vi.fish.un~bin0 -> 1910 bytes
l---------fish/functions/__bass.py1
-rw-r--r--fish/functions/a.fish4
-rw-r--r--fish/functions/add-inspection-prep-to-todo.fish9
-rw-r--r--fish/functions/backup-home.fish5
l---------fish/functions/bass.fish1
-rw-r--r--fish/functions/bobbins-mosh.fish3
-rw-r--r--fish/functions/catnote.fish3
-rw-r--r--fish/functions/copy-to-markdown.fish3
-rw-r--r--fish/functions/dmenu-notes.fish4
-rw-r--r--fish/functions/du.fish4
-rw-r--r--fish/functions/fish_prompt.fish13
-rw-r--r--fish/functions/fish_user_key_bindings.fish2
-rw-r--r--fish/functions/fisher.fish2536
-rw-r--r--fish/functions/fr.fish4
-rw-r--r--fish/functions/fs.fish3
-rw-r--r--fish/functions/ftnotes.fish4
-rw-r--r--fish/functions/fz_lastpass.fish3
-rw-r--r--fish/functions/fzf-cdhist-widget.fish14
l---------fish/functions/fzf_key_bindings.fish1
-rw-r--r--fish/functions/get-all-installed-packages-debian.fish4
-rw-r--r--fish/functions/get-location-from-ip.fish3
-rw-r--r--fish/functions/get-random-package-info.fish4
-rw-r--r--fish/functions/gitcommands.fish7
-rw-r--r--fish/functions/gloga.fish3
-rw-r--r--fish/functions/grep_lastpass.fish3
-rw-r--r--fish/functions/greptnotes.fish3
-rw-r--r--fish/functions/grup.fish3
-rw-r--r--fish/functions/hl-monthly-for-account.fish4
-rw-r--r--fish/functions/hl-weekly-for-account.fish4
-rw-r--r--fish/functions/in.fish4
-rw-r--r--fish/functions/laptopscreenoff.fish3
-rw-r--r--fish/functions/latest-textnote.fish4
-rw-r--r--fish/functions/livehosts.fish4
-rw-r--r--fish/functions/ls-links.fish3
l---------fish/functions/man.fish1
-rw-r--r--fish/functions/ml_jps_to_SharePics.fish7
-rw-r--r--fish/functions/mount-nc-webdav.fish4
-rw-r--r--fish/functions/mplayer-yt.fish5
-rw-r--r--fish/functions/pomo.fish4
-rw-r--r--fish/functions/pull-textnotes.fish3
-rw-r--r--fish/functions/push-textnotes.fish3
-rw-r--r--fish/functions/pyfind.fish4
-rw-r--r--fish/functions/pythontree.fish4
-rw-r--r--fish/functions/quteconfig.fish4
-rw-r--r--fish/functions/samba-share.fish3
-rw-r--r--fish/functions/screenshot.fish4
-rw-r--r--fish/functions/sus.fish4
-rw-r--r--fish/functions/syn.fish4
-rw-r--r--fish/functions/techno-pulse.fish3
-rw-r--r--fish/functions/techno.fish3
-rw-r--r--fish/functions/termux-ssh.fish3
-rw-r--r--fish/functions/test-task.fish4
-rw-r--r--fish/functions/todo-pull.fish4
-rw-r--r--fish/functions/todo-push.fish3
-rw-r--r--fish/functions/trance.fish4
-rw-r--r--fish/functions/unmount-nc-webdav.fish4
-rw-r--r--fish/functions/vcb.fish4
-rw-r--r--fish/functions/weather.fish4
-rw-r--r--fish/functions/wgdown.fish4
-rw-r--r--fish/functions/wgup.fish4
-rw-r--r--flake84
-rw-r--r--gcalclirc4
-rw-r--r--gitconfig27
-rw-r--r--gitignore_global52
-rw-r--r--gtkrc40
-rw-r--r--ideavimrc3
-rw-r--r--init.vim-legacy1109
-rw-r--r--init_to_disable_nvim_plugs.vim1
-rw-r--r--mailcap76
-rw-r--r--mplayer/config4
-rw-r--r--mps-youtube/configbin0 -> 716 bytes
-rw-r--r--mps-youtube/playlist_v2bin0 -> 6 bytes
-rw-r--r--mps-youtube/playlists/good_techno.m3u68
-rw-r--r--mps-youtube/playlists/studymix.m3u4
-rw-r--r--mpv/mpv.conf6
-rw-r--r--msmtprc28
-rw-r--r--mutt/aliases8
-rw-r--r--mutt/colours94
-rw-r--r--mutt/colours-bak69
-rw-r--r--mutt/mailcap23
-rw-r--r--mutt/mutt-colors-solarized-dark-256.muttrc151
-rw-r--r--mutt/mutt-colors-solarized-light-16.muttrc151
-rw-r--r--mutt/mutt-colors-solarized-light-256.muttrc151
-rw-r--r--mutt/offlineimap.py5
-rw-r--r--mutt/offlineimap.py-bak17
-rw-r--r--mutt/signature3
-rw-r--r--mutt/subscriptions3
-rwxr-xr-xmutt/view_attachment.sh129
-rw-r--r--muttrc235
-rw-r--r--muttrc-gmail155
-rw-r--r--mypy.ini2
-rw-r--r--nethackrc109
-rw-r--r--newsboat/config42
-rw-r--r--newsboat/history.cmdline2
-rw-r--r--newsboat/history.search1
-rw-r--r--newsboat/queue0
l---------newsboat/urls1
-rw-r--r--newsboat/urls-bak24
-rw-r--r--noserc2
-rw-r--r--notmuch-config102
-rw-r--r--nvim/after/syntax/markdown.vim8
-rw-r--r--nvim/init.vim739
-rw-r--r--obnam.conf3
-rw-r--r--offlineimap.py7
-rw-r--r--offlineimaprc61
-rw-r--r--pdbrc30
-rw-r--r--pdbrc.py63
-rw-r--r--profile28
-rw-r--r--ptpython/config.py177
-rw-r--r--pypirc9
-rw-r--r--qutebrowser/bookmarks/urls26
-rw-r--r--qutebrowser/config.py1807
-rw-r--r--qutebrowser/quickmarks5
-rw-r--r--ranger/rc.conf1
-rw-r--r--redshift.conf56
-rw-r--r--rsync_excludes.txt8
-rwxr-xr-xscreenlayout/desktop_layout_debian.sh2
-rwxr-xr-xscreenlayout/desktop_layout_debian_all_landscape.sh2
-rwxr-xr-xscreenlayout/left_portrait_right_land.sh2
-rw-r--r--scripts/cllogger15
-rw-r--r--scripts/export-html.pl90
-rw-r--r--scripts/export-ical.pl102
-rw-r--r--scripts/ical2org.awk391
-rw-r--r--scripts/keepassx2pass_csv.py186
-rw-r--r--scripts/nextcloud-data-persmissions.sh7
-rw-r--r--scripts/org-gcal-sync32
-rw-r--r--scripts/top_ten_directories.sh2
-rwxr-xr-xscripts/wireless_fix.sh7
-rw-r--r--sqliterc5
-rw-r--r--st-master/.gitignore3
-rw-r--r--st-master/.travis.yml11
-rw-r--r--st-master/LICENSE34
-rw-r--r--st-master/Makefile57
-rw-r--r--st-master/README.md77
-rw-r--r--st-master/arg.h50
-rw-r--r--st-master/config.h526
-rw-r--r--st-master/config.mk28
-rw-r--r--st-master/st-xresources-20190105-9f80f67.diff185
-rw-r--r--st-master/st.1188
-rw-r--r--st-master/st.c2741
-rw-r--r--st-master/st.h141
-rw-r--r--st-master/st.info222
-rw-r--r--st-master/win.h42
-rw-r--r--st-master/x.c2094
-rw-r--r--st-master/x.c.rej122
-rw-r--r--surfraw.conf2
-rw-r--r--taskopenrc71
-rw-r--r--taskrc250
-rw-r--r--taskrc-termux142
-rw-r--r--tmux.conf154
-rw-r--r--tmux.conf-alt29
-rw-r--r--tmuxinator.zsh29
-rw-r--r--tmuxinator/aphids.yml49
-rw-r--r--tmuxinator/bcompiler_tmux.yml55
-rw-r--r--tmuxinator/epm.yml47
-rw-r--r--tmuxinator/general.yml36
-rw-r--r--tmuxinator/xldigest.yml47
-rw-r--r--urlview1
-rw-r--r--urxvt/ext/clipboard117
-rw-r--r--urxvt/ext/font-size471
-rw-r--r--urxvt/ext/fullscreen33
-rw-r--r--urxvt/ext/keyboard-select598
-rw-r--r--urxvt/ext/url-select410
-rw-r--r--urxvt/ext/vtwheel49
-rw-r--r--wyrdrc3
-rw-r--r--xfce-terminalrc31
-rw-r--r--xfce4/terminal/accels.scm56
-rw-r--r--xfce4/terminal/terminalrc29
-rw-r--r--xinitrc1
-rw-r--r--xmonad/xmonad-x86_64-linuxbin0 -> 5316488 bytes
-rw-r--r--xmonad/xmonad.errors0
-rw-r--r--xmonad/xmonad.hibin0 -> 2250 bytes
-rw-r--r--xmonad/xmonad.hs22
-rw-r--r--xmonad/xmonad.hs.bak7
-rw-r--r--xmonad/xmonad.obin0 -> 28080 bytes
-rw-r--r--xsession4
-rw-r--r--xsessionrc9
-rw-r--r--youtube-dl-config1
-rw-r--r--zathurarc12
215 files changed, 21142 insertions, 0 deletions
diff --git a/.Xresources.un~ b/.Xresources.un~
new file mode 100644
index 0000000..fd1a0dd
--- /dev/null
+++ b/.Xresources.un~
Binary files differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3d3dba7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,57 @@
+mutt/temp/
+task/pending.data
+newsbeuter/cache.db
+task/backlog.data
+task/completed.data
+task/undo.data
+newsbeuter/cache.db.lock
+newsbeuter/cache.db
+newsbeuter/cache.db
+fish/fishd.debian-desktop
+ptpython/history
+fish/fishd.debtosh
+task/ca.cert.pem
+task/matthew_lemon*
+Matthew_Lemon.cert.pem
+Matthew_Lemon.key.pem
+matthew_lemon.cert.pem
+matthew_lemon.key.pem
+ca.cert.pem
+task/*
+newsbeuter/history.cmdline
+scripts/chromedriver
+scripts/geckodriver
+task-data.tgz
+newsboat/cache.db.lock
+newsboat/cache.db
+task-data_3_Dec_2018.tgz
+qutebrowser/autoconfig.yml
+fish/fishd.desktop
+qutebrowser/qsettings/QtProject.conf
+config/mpv/watch_later/
+config/transmission/resume/
+config/transmission/torrents/
+config/cmus/autosave
+config/GIMP/
+config/Code/
+config/chromium/
+config/QtProject/
+config/gmic/
+config/blender/
+config/nvim/*
+!config/nvim/init.vim
+config/spotify/
+config/cmus/autosave
+config/cmus/cache
+config/cmus/playlist.pl
+config/cmus/search-history
+config/cmus/lib.pl
+config/libreoffice/*
+config/pulse/*
+mpv/watch_later/*
+User/workspaceStorage/
+User/globalStorage/
+vim/swap/*
+vim/undo/*
+vim/.netrwhist
+nvim/plugged/*
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..6fcfb3b
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "vim/pack/tpope/start/sensible"]
+ path = vim/pack/tpope/start/sensible
+ url = https://github.com/tpope/vim-sensible.git
+[submodule "vim/pack/plugins/start/vim-go"]
+ path = vim/pack/plugins/start/vim-go
+ url = https://github.com/fatih/vim-go
+[submodule "vim/pack/plugins/start/vim-test"]
+ path = vim/pack/plugins/start/vim-test
+ url = https://github.com/janko/vim-test
+[submodule "vim/pack/tpope/start/dispatch"]
+ path = vim/pack/tpope/start/dispatch
+ url = https://github.com/tpope/vim-dispatch
diff --git a/Ultisnips/django.snippets b/Ultisnips/django.snippets
new file mode 100644
index 0000000..472166b
--- /dev/null
+++ b/Ultisnips/django.snippets
@@ -0,0 +1,3 @@
+snippet dj_tag
+{% $1 %}
+endsnippet
diff --git a/Ultisnips/python.snippets b/Ultisnips/python.snippets
new file mode 100644
index 0000000..c34bc74
--- /dev/null
+++ b/Ultisnips/python.snippets
@@ -0,0 +1,4 @@
+snippet fn_main
+if __name__ == '__main__':
+ main()
+endsnippet
diff --git a/User/keybindings.json b/User/keybindings.json
new file mode 100644
index 0000000..8c3edad
--- /dev/null
+++ b/User/keybindings.json
@@ -0,0 +1,21 @@
+// Place your key bindings in this file to override the defaults
+[
+ {
+ "key": "ctrl+f",
+ "command": "-workbench.action.terminal.focusFindWidget",
+ "when": "terminalFocus"
+ },
+ {
+ "key": "ctrl+9",
+ "command": "editor.action.showHover",
+ "when": "editorTextFocus"
+ },
+ {
+ "key": "ctrl+tab",
+ "command": "workbench.action.openPreviousEditorFromHistory" },
+ {
+ "key": "ctrl+tab",
+ "command": "workbench.action.quickOpenNavigateNext",
+ "when": "inQuickOpen"
+ },
+] \ No newline at end of file
diff --git a/User/settings.json b/User/settings.json
new file mode 100644
index 0000000..d95c863
--- /dev/null
+++ b/User/settings.json
@@ -0,0 +1,57 @@
+{
+ "editor.suggestSelection": "first",
+ "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
+ "python.jediEnabled": false,
+ "editor.fontFamily": "'Hack', 'Monaco', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'",
+ "editor.fontSize": 18,
+ "terminal.integrated.fontFamily": "Hack",
+ "terminal.integrated.fontSize": 18,
+ "editor.lineNumbers": "relative",
+ "files.exclude": {
+ "**/.git": true,
+ "**/.svn": true,
+ "**/.hg": true,
+ "**/CVS": true,
+ "**/.DS_Store": true,
+ "**/.idea": true,
+ "**/.mypy_cache": true,
+ "**/.pytest_cache": true,
+ "**/.ropeproject": true,
+ "**/.vscode": true,
+ "**/__pycache__": true,
+ "**/*.egg-info": true,
+ "**/.tox": true,
+ "**/.coverage": true,
+ "**/skip-covered": true,
+ "**/pip-wheel-metadata": true,
+ "**/prof": true,
+ "**/tags": true,
+ },
+ "vim.enableNeovim": true,
+ "vim.neovimPath": "/usr/bin/nvim",
+ "vim.hlsearch": true,
+ "vim.leader": "\\",
+ "vim.visualstar": true,
+ "vim.handleKeys": {
+ "<C-d>": true,
+ "<C-b>": false,
+ "<C-r>": false,
+ "<C-k>": false,
+ },
+ "vim.searchHighlightColor": "#f93005",
+ "vim.visualModeKeyBindingsNonRecursive": [
+ {
+ "before": [">"],
+ "commands": ["editor.action.indentLines"]
+ },
+ {
+ "before": ["<"],
+ "commands": ["editor.action.outdentLines"]
+ },
+ ],
+ "editor.renderWhitespace": "none",
+ "editor.dragAndDrop": false,
+ "telemetry.enableCrashReporter": false,
+ "telemetry.enableTelemetry": false,
+ "go.formatTool": "goimports"
+} \ No newline at end of file
diff --git a/Xresources b/Xresources
new file mode 100644
index 0000000..ba974ce
--- /dev/null
+++ b/Xresources
@@ -0,0 +1,177 @@
+! urxvt - see bottom of file for explanation of these settings
+
+!! from https://wiki.manjaro.org/index.php?title=Improve_Font_Rendering
+Xft.dpi: 96
+Xft.antialias: true
+Xft.hinting: true
+Xft.rgba: rgb
+Xft.autohint: false
+Xft.hintstyle: hintslight
+Xft.lcdfilter: lcddefault
+
+xterm*VT100*colorMode: on
+xterm*VT100*boldColors: on
+xterm*VT100*dynamicColors: on
+
+xterm*borderWidth :0
+xterm*internalBorder :2
+XTerm*allowBoldFonts :false
+
+XTerm*VT100*Translations : #override Shift : exec-formatted("chrome --enable-unveil '%t'", PRIMARY)
+
+!XTerm*allowBoldFonts: false
+
+!!rofi
+!!check https://github.com/davatorium/rofi/wiki/Using-Rofi-with-Fish-Shell
+rofi.run-command: fish -c '{cmd}'
+rofi.run-list-command: 'fish -c functions'
+
+!! stops xterm using C-h as backspace!
+!! https://unix.stackexchange.com/questions/180087/why-pressing-ctrl-h-in-xterm-tmux-sends/180106
+XTerm*ptyInitialErase:xtrue
+
+XTerm*backarrowKey: false
+XTerm.vt100.backarrowKey: false
+XTerm.ttyModes: erase ^?
+XTerm.vt100.locale:true
+
+
+#define GruvBoxBackground #1d2021
+URxvt*buffered: true
+URxvt*cursorBlink: true
+!URxvt*cursorColor: #a8a19f
+URxvt*cursorColor: #d65d0e
+URxvt*xftAntialias: true
+URxvt*underlineColor: #d65d0e
+
+!!URxvt*font: -misc-fixed-medium-*-normal-*-20-200-75-75-*-100-iso10646-1
+!!URxvt*boldFont: -misc-fixed-bold-r-normal--15-140-75-75-c-90-iso8859-1
+!!URxvt*font: xft:Liberation Mono:size=12:antialias=true
+!!URxvt*boldFont: xft:Liberation Mono:bold:size=12:antialias=true
+!!URxvt*font: xft:Noto Mono:size=12:antialias=true
+!!URxvt*boldFont: xft:Noto Mono:bold:size=12:antialias=true
+!!URxvt*font: xft:monofur:size=17:antialias=true
+!!URxvt*boldFont: xft:monofur:size=17:antialias=true
+
+!!URxvt*font: xft:monospace:size=15
+!!URxvt*boldFont: xft:monospace:bold:size=15
+
+!!URxvt*font: xft:Fira Mono:size=15
+!!URxvt*boldFont: xft:Fira Mono:bold:size=15
+!!URxvt*font: xft:Monaco:size=14
+!!URxvt*boldFont: xft:Monaco:bold:size=14
+!!URxvt*font: xft:Hack:size=12
+!!URxvt*boldFont: xft:Hack:bold:size=12
+
+URxvt*letterSpace: -1
+URxvt*allow_bold: true
+URxvt*depth: 32
+URxvt*borderless: 1
+URxvt*scrollBar: false
+URxvt*loginShell: true
+Urxvt*secondaryScroll: true # Enable Shift-PageUp/Down in screen
+URxvt*saveLines: 30000
+URxvt*termName: screen-256color
+URxvt.perl-ext-common: default,matcher,resize-font,font-size,url-select
+URxvt.perl-lib:/home/lemon/dotfiles/urxvt/ext
+URxvt.url-launcher: qutebrowser
+URxvt.matcher.button: 1
+URxvt.intensityStyles: false
+URxvt.background: GruvBoxBackground
+URxvt.foreground: white
+
+URxvt.keysym.M-u: perl:url-select:select_next
+
+URxvt.keysym.C-minus: font-size:decrease
+URxvt.keysym.C-plus: font-size:increase
+URxvt.keysym.C-equal: font-size:reset
+URxvt.keysym.C-question: font-size:show
+
+!! resize-font bindings
+!! And re-bind some keymappings (if you want, below are the defaults):
+!!URxvt.keysym.C-minus: resize-font:smaller
+!!URxvt.keysym.C-plus: resize-font:bigger
+!!URxvt.keysym.C-equal: resize-font:reset
+!!URxvt.keysym.C-question: resize-font:show
+
+
+! xterm
+!! THESE TWO ARE BEST
+!!xterm*font:-misc-fixed-medium-*-normal-*-15-*-100-100-*-*-iso8859-1
+!!xterm*boldFont:-misc-fixed-bold-*-normal-*-15-*-100-100-*-*-iso8859-1
+!
+xterm*utf8: 1
+!!xterm*font: -xos4-terminus-medium-r-normal--20-200-72-72-c-100-iso10646-1
+!!xterm*font: -xos4-terminus-medium-r-normal--24-240-72-72-c-120-iso8859-1
+!!xterm*boldFont: -xos4-terminus-bold-r-normal--24-240-72-72-c-120-iso8859-1
+
+!!xterm*font: -xos4-terminus-medium-r-normal-*-17-120-100-100-c-0-iso10646-1
+!!xterm*Boldfont: -xos4-terminus-bold-r-normal-*-17-120-100-100-c-0-iso10646-1
+
+!!xterm*Boldfont: -xos4-terminus-bold-r-normal--16-160-72-72-c-80-iso10646-1
+!!xterm*font: -xos4-terminus-medium-r-normal--16-160-72-72-c-80-iso10646-1
+
+!!xterm*font: xft:Monospace:size=14:antialias=true
+!!xterm*Boldfont: xft:Monospace:bold::size=14:antialias=true
+
+!!xterm*font: xft:Source Code Pro:size=12:antialias=true
+!!xterm*Boldfont: xft:Source Code Pro:bold:size=12:antialias=true
+
+!!xterm*font: xft:Fira Code:size=12:antialias=true
+!!xterm*boldFont: xft:Fira Code:bold:size=12:antialias=true
+
+!!*.font: Hack:size=13
+!!*.boldFont: Hack:bold:size=13
+
+!! nice in ST
+!*.font: -xos4-terminus-medium-r-normal-*-17-120-100-100-c-0-iso10646-1
+
+!!xterm*font:-misc-proggycleantt-*-*-*-*-*-*-*-*-*-*-*-*
+xterm*font: xft:ProggyCleanTT:size=12:antialias=false
+
+!!xterm*font: xft:IBMPlexMono-Regular:size=13:antialias=true
+!!xterm*boldFont: xft:IBMPlexMono-BoldItalic:size=13:antialias=true
+!!xterm*font: xft:Droid Sans Mono:size=13:antialias=true
+!!xterm*fontFont: xft:Droid Sans Mono:bold:size=13:antialias=true
+!xterm*font: xft:Noto Mono:size=12:antialias=true
+!!xterm*boldFont: xft:Noto Mono:bold:size=14:antialias=true
+!!xterm*font: xft:Monaco:size=10:antialias=true
+!!xterm*boldFont: xft:Monaco:bold:size=10:antialias=true
+!!xterm*font: xft:Ubuntu Mono:size=13:antialias=true
+!!xterm*fontFont: xft:Ubuntu Mono:bold:size=13:antialias=true
+!!xterm*faceName: Ubuntu Mono
+!!xterm*faceSize: 13
+xterm*background: black
+xterm*foreground: white
+!!xterm*font: 9x15
+xterm*metaSendsEscape: true
+xterm.perl-ext-common: default,matcher,resize-font,font-size,url-select
+xterm.perl-lib:/home/lemon/dotfiles/urxvt/ext
+
+! PaperColor theme
+! https://www.reddit.com/r/vim/comments/36xzbs/vim_paper_color_theme_inspired_by_googles/crqbfpa/
+! black
+!xterm*background: black
+!xterm*foreground: white
+!xterm*color0: #1c1c1c
+!xterm*color1: #af005f
+!xterm*color2: #5faf00
+!xterm*color3: #d7af5f
+!xterm*color4: #5fafd7
+!xterm*color5: #808080
+!xterm*color6: #000000
+!xterm*color6: #d7875f
+!xterm*color7: #d0d0d0
+!xterm*color8: #585858
+!xterm*color9: #5faf5f
+!xterm*color10: #afd700
+!xterm*color11: #af87d7
+!xterm*color12: #ffaf00
+!xterm*color13:x#ff5faf
+!xterm*color14: #000000
+!xterm*color14: #00afaf
+!xterm*color15: #5f8787
+!xterm*color16: #5fafd7
+!xterm*color17: #d7af00
+
+
diff --git a/Xresources-alt b/Xresources-alt
new file mode 100644
index 0000000..7cef4e3
--- /dev/null
+++ b/Xresources-alt
@@ -0,0 +1,101 @@
+!===== fonts
+Xft.autohint : 0
+Xft.lcdfilter : lcddefault
+Xft.hintstyle : hintslight
+Xft.hinting : 1
+Xft.antialias : 1
+Xft.rgba : rgb
+! fixed is the one true font - use iso10646 for unicode characters
+*font : -misc-fixed-medium-r-semicondensed-*-13-*-*-*-*-*-iso10646-1
+
+! ===== xidle
+! drag pointer to lower left corner to lock screen
+XIdle*position : sw
+! and leave it there for one second.
+XIdle*delay : 1
+! also lock screen after 5 minutes idle
+XIdle*timeout : 300
+
+! ===== xlock
+! actually turn the backlight off
+XLock.dpmsoff : 1
+! plain white-on-black lock screen
+XLock.description : off
+XLock.echokeys : off
+XLock.info :
+XLock.background : black
+XLock.foreground : white
+XLock.mode : blank
+XLock.username : username:
+XLock.password : password:
+XLock.font : -misc-fixed-medium-r-normal-*-15-*-*-*-*-*-iso10646-1
+XLock.planfont : -misc-fixed-medium-r-normal-*-13-*-*-*-*-*-iso10646-1
+
+! ===== xclock
+! digital clock in lower right-hand corner
+XClock*analog : false
+XClock*twentyfour : true
+XClock*padding : 0
+XClock*geometry : -2-2
+XClock*render : false
+XClock*font : -misc-fixed-bold-r-normal-*-13-*-*-*-*-*-iso10646-1
+XClock*height : 12
+XClock*background : dimgray
+XClock*foreground : white
+XClock*borderWidth : 0
+
+! ===== xterm
+! zenburn theme - http://kippura.org/zenburnpage
+XTerm*background : #3f3f3f
+XTerm*foreground : #dcdccc
+XTerm*cursorColor : #aaaaaa
+XTerm*colorUL : #366060
+XTerm*underlineColor : #dfaf8f
+XTerm*color0 : #3f3f3f
+XTerm*color1 : #cc9393
+XTerm*color2 : #7f9f7f
+XTerm*color3 : #d0bf8f
+XTerm*color4 : #6ca0a3
+XTerm*color5 : #dc8cc3
+XTerm*color6 : #93e0e3
+XTerm*color7 : #dcdccc
+XTerm*color8 : #000000
+XTerm*color9 : #dca3a3
+XTerm*color10 : #bfebbf
+XTerm*color11 : #f0dfaf
+XTerm*color12 : #8cd0d3
+XTerm*color13 : #dc8cc3
+XTerm*color14 : #93e0e3
+XTerm*color15 : #ffffff
+
+! remove the additional black border
+XTerm*borderWidth : 0
+XTerm*internalBorder : 2
+! set TERM env variable to use 256 colors
+XTerm*termName : xterm-256color
+! make alt key work normally
+XTerm*vt100.metaSendsEscape : true
+! save ~10,000 lines of scrollback
+XTerm*v100.saveLines : 10240
+! hide scrollbar
+XTerm*vt100.scrollBar : false
+! terminal bell tells the window manager to raise urgent flag
+XTerm*vt100.bellIsUrgent : true
+! no bold fonts - just use brighter colors
+XTerm*allowBoldFonts : false
+! pressing a key automatically scrolls to the bottom
+XTerm*scrollKey : true
+! don't allow terminal to go fullscreen
+XTerm*fullscreen : never
+! clicking a line selects only from the current word forward
+XTerm*cutToBeginningOfLine : false
+! and don't include a trailing newline in the selection!
+XTerm*cutNewline : false
+! some black magic to change what characters XTerm considers "word delimeters"
+XTerm*charClass : 33:48,36-47:48,58-59:48,61:48,63-64:48,95:48,126:48
+! select word on two clicks
+XTerm*on2Clicks : word
+! select whole line on three clicks
+XTerm*on3Clicks : line
+! shift + left click to open selection in web browser
+XTerm*VT100*Translations : #override Shift : exec-formatted("chrome --enable-unveil '%t'", PRIMARY)
diff --git a/Xresources-bak b/Xresources-bak
new file mode 100644
index 0000000..b3cbc9b
--- /dev/null
+++ b/Xresources-bak
@@ -0,0 +1,98 @@
+! urxvt
+URxvt*buffered: true
+URxvt*cursorBlink: true
+!URxvt*cursorColor: orange
+URxvt*underlineColor: yellow
+URxvt*font: -misc-fixed-medium-r-normal--15-140-75-75-c-90-iso8859-1
+URxvt*boldFont: -misc-fixed-bold-r-normal--15-140-75-75-c-90-iso8859-1
+!!URxvt*font: xft:Liberation Mono:size=10:antialias=true
+!!URxvt*boldFont: xft:Liberation Mono:bold:size=10:antialias=true
+URxvt*allow_bold: true
+URxvt*depth: 32
+URxvt*borderless: 1
+URxvt*scrollBar: false
+URxvt*loginShell: true
+Urxvt*secondaryScroll: true # Enable Shift-PageUp/Down in screen
+URxvt*saveLines: 30000
+URxvt*termName: screen-256color
+URxvt.perl-ext-common: default,matcher
+URxvt.url-launcher: firefox
+URxvt.matcher.button: 1
+
+
+!! drop in Solarized colorscheme for Xresources/Xdefaults
+
+!!SOLARIZED HEX 16/8 TERMCOL XTERM/HEX L*A*B RGB HSB
+!!--------- ------- ---- ------- ----------- ---------- ----------- -----------
+!!base03 #002b36 8/4 brblack 234 #1c1c1c 15 -12 -12 0 43 54 193 100 21
+!!base02 #073642 0/4 black 235 #262626 20 -12 -12 7 54 66 192 90 26
+!!base01 #586e75 10/7 brgreen 240 #585858 45 -07 -07 88 110 117 194 25 46
+!!base00 #657b83 11/7 bryellow 241 #626262 50 -07 -07 101 123 131 195 23 51
+!!base0 #839496 12/6 brblue 244 #808080 60 -06 -03 131 148 150 186 13 59
+!!base1 #93a1a1 14/4 brcyan 245 #8a8a8a 65 -05 -02 147 161 161 180 9 63
+!!base2 #eee8d5 7/7 white 254 #e4e4e4 92 -00 10 238 232 213 44 11 93
+!!base3 #fdf6e3 15/7 brwhite 230 #ffffd7 97 00 10 253 246 227 44 10 99
+!!yellow #b58900 3/3 yellow 136 #af8700 60 10 65 181 137 0 45 100 71
+!!orange #cb4b16 9/3 brred 166 #d75f00 50 50 55 203 75 22 18 89 80
+!!red #dc322f 1/1 red 160 #d70000 50 65 45 220 50 47 1 79 86
+!!magenta #d33682 5/5 magenta 125 #af005f 50 65 -05 211 54 130 331 74 83
+!!violet #6c71c4 13/5 brmagenta 61 #5f5faf 50 15 -45 108 113 196 237 45 77
+!!blue #268bd2 4/4 blue 33 #0087ff 55 -10 -45 38 139 210 205 82 82
+!!cyan #2aa198 6/6 cyan 37 #00afaf 60 -35 -05 42 161 152 175 74 63
+!!green #859900 2/2 green 64 #5f8700 60 -20 65 133 153 0 68 100 60
+
+!!#define S_base03 #002b36
+!!#define S_base02 #073642
+!!#define S_base01 #586e75
+!!#define S_base00 #657b83
+!!#define S_base0 #839496
+!!#define S_base1 #93a1a1
+!!#define S_base2 #eee8d5
+!!#define S_base3 #fdf6e3
+!!#define S_yellow #b58900
+!!#define S_orange #cb4b16
+!!#define S_red #dc322f
+!!#define S_magenta #d33682
+!!#define S_violet #6c71c4
+!!#define S_blue #268bd2
+!!#define S_cyan #2aa198
+!!#define S_green #859900
+!!
+URxvt*background: #000000
+!!URxvt*background: #fcffd6
+URxvt*foreground: #cccccc
+!!*cursorColor: S_base1
+!!*pointerColorBackground:S_base01
+!!*pointerColorForeground:S_base1
+!!
+!!!! black dark/light
+!!*color0: S_base02
+!!*color8: S_base03
+!!
+!!!! red dark/light
+!!*color1: S_red
+!!*color9: S_orange
+!!
+!!!! green dark/light
+!!*color2: S_green
+!!*color10: S_base01
+!!
+!!!! yellow dark/light
+!!*color3: S_yellow
+!!*color11: S_base00
+!!
+!!!! blue dark/light
+!!*color4: S_blue
+!!*color12: S_base0
+!!
+!!!! magenta dark/light
+!!*color5: S_magenta
+!!*color13: S_violet
+!!
+!!!! cyan dark/light
+!!*color6: S_cyan
+!!*color14: S_base1
+!!
+!!!! white dark/light
+!!*color7: S_base2
+!!*color15: S_base
diff --git a/abookrc b/abookrc
new file mode 100644
index 0000000..3a595da
--- /dev/null
+++ b/abookrc
@@ -0,0 +1,40 @@
+# Automatically save database on exit
+set autosave=true
+
+# Show all email addresses in list
+set show_all_emails=true
+
+# frequently used values:
+# -1 disabled
+# phone Home Phone
+# workphone Work Phone
+# fax Fax
+# mobile Mobile Phone
+# nick Nickname/Alias
+# url URL
+
+# Command used to start mutt
+set mutt_command=mutt
+
+# Command used to print
+set print_command=lpr
+
+# Command used to start the web browser
+set www_command=w3m
+
+# address style [eu|us|uk]
+set address_style=eu
+
+# use ASCII characters only
+set use_ascii_only=false
+
+# Prevent double entry
+set add_email_prevent_duplicates=false
+
+# field to be used with "sort by field" command
+set sort_field=nick
+
+# show cursor in main display
+set show_cursor=false
+
+set index_format=" {name:30} {mobile:20} {workphone:20} {email:35}"
diff --git a/bashrc b/bashrc
new file mode 100644
index 0000000..552a1b2
--- /dev/null
+++ b/bashrc
@@ -0,0 +1,134 @@
+# ~/.bashrc: executed by bash(1) for non-login shells.
+# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
+# for examples
+
+# If not running interactively, don't do anything
+case $- in
+ *i*) ;;
+ *) return;;
+esac
+
+# don't put duplicate lines or lines starting with space in the history.
+# See bash(1) for more options
+HISTCONTROL=ignoreboth
+
+# append to the history file, don't overwrite it
+shopt -s histappend
+
+# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
+HISTSIZE=1000
+HISTFILESIZE=2000
+
+# check the window size after each command and, if necessary,
+# update the values of LINES and COLUMNS.
+shopt -s checkwinsize
+
+# If set, the pattern "**" used in a pathname expansion context will
+# match all files and zero or more directories and subdirectories.
+#shopt -s globstar
+
+# make less more friendly for non-text input files, see lesspipe(1)
+#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
+
+# set variable identifying the chroot you work in (used in the prompt below)
+if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
+ debian_chroot=$(cat /etc/debian_chroot)
+fi
+
+# set a fancy prompt (non-color, unless we know we "want" color)
+case "$TERM" in
+ xterm-color|*-256color) color_prompt=yes;;
+esac
+
+# uncomment for a colored prompt, if the terminal has the capability; turned
+# off by default to not distract the user: the focus in a terminal window
+# should be on the output of commands, not on the prompt
+#force_color_prompt=yes
+
+if [ -n "$force_color_prompt" ]; then
+ if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
+ # We have color support; assume it's compliant with Ecma-48
+ # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
+ # a case would tend to support setf rather than setaf.)
+ color_prompt=yes
+ else
+ color_prompt=
+ fi
+fi
+
+if [ "$color_prompt" = yes ]; then
+ PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
+else
+ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
+fi
+unset color_prompt force_color_prompt
+
+# If this is an xterm set the title to user@host:dir
+case "$TERM" in
+xterm*|rxvt*)
+ PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
+ ;;
+*)
+ ;;
+esac
+
+# enable color support of ls and also add handy aliases
+if [ -x /usr/bin/dircolors ]; then
+ test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
+ alias ls='ls --color=auto'
+ #alias dir='dir --color=auto'
+ #alias vdir='vdir --color=auto'
+
+ #alias grep='grep --color=auto'
+ #alias fgrep='fgrep --color=auto'
+ #alias egrep='egrep --color=auto'
+fi
+
+# colored GCC warnings and errors
+#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
+
+# some more ls aliases
+alias ll='ls -l'
+alias la='ls -A'
+alias l='ls -CF'
+
+# Alias definitions.
+# You may want to put all your additions into a separate file like
+# ~/.bash_aliases, instead of adding them here directly.
+# See /usr/share/doc/bash-doc/examples in the bash-doc package.
+
+if [ -f ~/.bash_aliases ]; then
+ . ~/.bash_aliases
+fi
+
+# enable programmable completion features (you don't need to enable
+# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
+# sources /etc/bash.bashrc).
+if ! shopt -oq posix; then
+ if [ -f /usr/share/bash-completion/bash_completion ]; then
+ . /usr/share/bash-completion/bash_completion
+ elif [ -f /etc/bash_completion ]; then
+ . /etc/bash_completion
+ fi
+fi
+
+# kill bell
+xset b off
+
+## FUNCTIONS
+
+function get-location-from-ip() {
+ curl -s https://ipvigilante.com/`curl -s https://ipinfo.io/ip` | jq '.data.latitude, .data.longitude, .data.city_name, .data.country_name'
+}
+
+
+function gloga() {
+ git log --oneline --decorate --graph --all
+}
+
+
+# set TERM
+export TERM="xterm-256color"
+
+
+[ -f ~/.fzf.bash ] && source ~/.fzf.bash
diff --git a/bpython/config b/bpython/config
new file mode 100644
index 0000000..835e34f
--- /dev/null
+++ b/bpython/config
@@ -0,0 +1,96 @@
+# This is a standard python config file
+# Valid values can be True, False, integer numbers, strings
+# By default bpython will look for $XDG_CONFIG_HOME/bpython/config
+# ($XDG_CONFIG_HOME defaults to ~/.config) or you can specify a file with the
+# --config option on the command line
+#
+# see http://docs.bpython-interpreter.org/configuration.html
+# for all configurable options
+
+# General section tag
+[general]
+
+# Display the autocomplete list as you type (default: True).
+# When this is off, you can hit tab to see the suggestions.
+# auto_display_list = True
+
+# Syntax highlighting as you type (default: True).
+# syntax = True
+
+# Display the arg spec (list of arguments) for callables,
+# when possible (default: True).
+# arg_spec = True
+
+# History file (default: ~/.pythonhist):
+hist_file = ~/.bpythonhist
+
+# Number of lines to store in history (set to 0 to disable) (default: 100):
+# hist_length = 100
+
+# Soft tab size (default: 4, see pep-8):
+# tab_length = 4
+
+# Color schemes should be put in $XDG_CONFIG_HOME/bpython/ e.g. to use the theme
+# $XDG_CONFIG_HOME/bpython/foo.theme set color_scheme = foo. Leave blank or set
+# to "default" to use the default theme
+# color_scheme = default
+
+# External editor to use for editing the current line, block, or full history
+# Default is to try $EDITOR and $VISUAL, then vi - but if you uncomment
+# the line below that will take precedence
+# editor = vi
+
+# Whether to append .py to the filename while saving session to a file.
+# (default: False)
+# save_append_py = False
+
+# The name of a helper executable that should perform pastebin upload on
+# bpython's behalf. If unset, bpython uploads pastes to bpaste.net. (default: )
+#pastebin_helper = gist.py
+
+# How long an undo must be expected to take before prompting for how
+# many lines should be undone. Set to -1 to never prompt, or 0 to
+# always prompt.
+# single_undo_time = 1.0
+
+# Enable autoreload feature by default (default: False).
+# default_autoreload = False
+
+[keyboard]
+
+# All key bindings are shown commented out with their default binding
+
+# pastebin = F8
+# last_output = F9
+# reimport = F6
+# help = F1
+# toggle_file_watch = F5
+# save = C-s
+# undo = C-r
+# up_one_line = C-p
+# down_one_line = C-n
+# cut_to_buffer = C-k
+# search = C-o
+# yank_from_buffer = C-y
+# backspace = C-h
+# clear_word = C-w
+# clear_line = C-u
+# clear_screen = C-l
+# show_source = F2
+# exit = C-d
+# external_editor = F7
+# edit_config = F3
+# reverse_incremental_search = M-r
+# incremental_search = M-s
+
+[curtsies]
+
+# Allow the the completion and docstring box above the current line
+# (default: False)
+# list_above = False
+
+# Enables two fish (the shell) style features:
+# Previous line key will search for the current line (like reverse incremental
+# search) and right arrow will complete the current line with the first match
+# from history. (default: True)
+# right_arrow_completion = True
diff --git a/bugwarriorrc b/bugwarriorrc
new file mode 100644
index 0000000..a85cafa
--- /dev/null
+++ b/bugwarriorrc
@@ -0,0 +1,41 @@
+[general]
+targets = my_github
+inline_links = False
+annotation_comments = True
+shorten = True
+
+[my_gmail]
+service = gmail
+gmail.query = label:STARRED OR label:readme
+gmail.login_name = matthew.lemon@gmail.com
+gmail.project_template = Gmail
+gmail.description_template = (email){{gmaillastsender}}: {{gmailsubject}}
+
+[my_github]
+service = github
+github.login = yulqen
+github.token = 435e145c4daa2c43cdaa2c608417b4be7a56b7c0
+github.username = yulqen
+github.include_user_repos = bcompiler-engine,ctrack,datamaps
+github.exclude_repos = bcompiler,dbasik
+github.default_priority = L
+github.add_tags = code
+github.project_template = code.{{githubrepo}}
+
+[my_gitlab]
+service = gitlab
+gitlab.default_priority = L
+gitlab.login = mrlemon
+gitlab.token = J4uD5RjYJSDWNJT7J3qZ
+gitlab.host = gitlab.com
+gitlab.add_tags = aphids
+
+[my_bitbucket]
+service = bitbucket
+bitbucket.username = mrlemon
+bitbucket.default_priority = L
+bitbucket.login = mrlemon
+#bitbucket.key = 79aSuwZ7xJZ83jTCtR
+#bitbucket.secret = zH8bVmpADYmxvYPCEHhLfCFP7EzcyuDh
+bitbucket.include_repos = bcompiler
+bitbucket.password = chunkyday687
diff --git a/coc-settings.json b/coc-settings.json
new file mode 100644
index 0000000..cb42cfd
--- /dev/null
+++ b/coc-settings.json
@@ -0,0 +1,23 @@
+{
+ "python.linting.enabled": true,
+ "python.jediEnabled": false,
+ "python.linting.pylintArgs": ["--disable=C0111,R0903,R0913"],
+ "python.linting.pydocstyleEnabled": true,
+ "python.linting.pydocstyleArgs": ["--ignore D100"],
+ "python.linting.flake8Enabled": false,
+ "python.linting.mypyEnabled": true,
+ "python.linting.mypyArgs": ["--ignore-missing-imports"],
+ "python.formatting.blackPath": "black",
+ "python.formatting.provider": "black",
+ "python.venvFolders": ["~/.virtualenv"],
+ "python.venvPath": "${workspaceFolder}",
+ "python.autoComplete.typeshedPaths": [],
+ "codeLens.enable": true,
+ "suggest.maxCompleteItemCount": 20,
+ "suggest.enablePreview": true,
+ "diagnostic.checkCurrentLine": true,
+ "diagnostic.displayByAle": false,
+ "diagnostic.hintSign": ">>",
+ "diagnostic.virtualText": true,
+ "diagnostic.virtualTextPrefix": "->> "
+}
diff --git a/compton.conf b/compton.conf
new file mode 100644
index 0000000..7b21074
--- /dev/null
+++ b/compton.conf
@@ -0,0 +1,52 @@
+shadow = true;
+no-dnd-shadow = true;
+no-dock-shadow = false;
+clear-shadow = true;
+shadow-radius = 7;
+shadow-offset-x = -7;
+shadow-offset-y = -7;
+shadow-opacity = 0.7;
+shadow-red = 0.0;
+shadow-green = 0.0;
+shadow-blue = 0.0;
+shadow-exclude = [ "name = 'Notification'", "class_g = 'Conky'", "class_g ?= 'Notify-osd'", "class_g = 'Cairo-clock'" ];
+shadow-ignore-shaped = false;
+xinerama-shadow-crop = false;
+menu-opacity = 0.8;
+inactive-opacity = 0.8;
+active-opacity = 1.0;
+frame-opacity = 0.7;
+inactive-opacity-override = false;
+alpha-step = 0.06;
+inactive-dim = 0.0;
+blur-kern = "3x3box";
+blur-background-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ];
+fading = true;
+fade-in-step = 0.03;
+fade-out-step = 0.03;
+fade-exclude = [ ];
+backend = "xrender";
+mark-wmwin-focused = true;
+mark-ovredir-focused = true;
+detect-rounded-corners = true;
+detect-client-opacity = true;
+refresh-rate = 0;
+vsync = "none";
+dbe = false;
+paint-on-overlay = true;
+focus-exclude = [ "class_g = 'Cairo-clock'" ];
+detect-transient = true;
+detect-client-leader = true;
+invert-color-include = [ ];
+glx-copy-from-front = false;
+glx-swap-method = "undefined";
+wintypes :
+{
+ tooltip :
+ {
+ fade = true;
+ shadow = false;
+ opacity = 0.75;
+ focus = true;
+ };
+};
diff --git a/config/i3-laptop/config b/config/i3-laptop/config
new file mode 100644
index 0000000..d49b0ae
--- /dev/null
+++ b/config/i3-laptop/config
@@ -0,0 +1,280 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see http://i3wm.org/docs/userguide.html for a complete reference!
+
+# start compton compiz
+#exec compton
+
+for_window [class="^.*"] border pixel 2
+
+#gaps inner 15
+#gaps outer 15
+#gaps horizontal 5
+#gaps vertical 5
+#gaps top 5
+#gaps right 5
+#gaps bottom 5
+#gaps left 5
+#
+#smart_gaps on
+
+set $mod Mod4
+
+# no border
+#new_window none
+#border none
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+#font pango:monospace 8
+font pango:mono 10
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# Before i3 v4.8, we used to recommend this one as the default:
+# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+# The font above is very space-efficient, that is, it looks good, sharp and
+# clear in small sizes. However, its unicode glyph coverage is limited, the old
+# X core fonts rendering does not support right-to-left and this being a bitmap
+# font, it doesn’t scale on retina/hidpi displays.
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# get network app and others
+#exec --no-startup-id nm-applet
+#exec --no-startup-id /usr/bin/qjackctl
+#exec --no-startup-id /usr/bin/nextcloud
+exec --no-startup-id /usr/bin/redshift-gtk
+#exec --no-startup-id /usr/bin/feh --bg-max /home/lemon/Pictures/wallpaper/wallhaven-733911.jpg
+#exec --no-startup-id /home/lemon/.screenlayout/desktop_layout_debian_all_landscape.sh
+#exec --no-startup-id /usr/bin/xfce4-clipman
+#exec --no-startup-id /usr/bin/copyq
+#exec --no-startup-id /usr/bin/xfce4-mixer
+#exec --no-startup-id /usr/bin/xfce4-power-manager-settings # setting this
+#means laptop lid closure will kill suspend the laptop so switched off for now
+
+# scratchpad
+# Make the currently focused window a scratchpad
+bindsym $mod+Shift+minus exec /home/lemon/bin/i3scripts/scratch_todo
+bindsym $mod+Shift+BackSpace move scratchpad
+bindsym $mod+minus scratchpad show
+
+# Show the sup-mail scratchpad window, if any.
+#bindsym mod4+z [title="^Sup ::"] scratchpad show
+
+# start a terminal
+bindsym $mod+Return exec xterm -en en_GB.UTF-8
+#bindsym $mod+Return exec i3-sensible-terminal
+#bindsym $mod+Return exec st
+#bindsym $mod+Return exec urxvt
+
+# change gap size
+
+#bindsym $mod+z gaps outer current plus 5
+#bindsym $mod+Shift+z gaps outer current minus 5
+#bindsym $mod+g gaps inner current plus 5
+#bindsym $mod+Shift+g gaps inner current minus 5
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+# start dmenu (a program launcher)
+bindsym $mod+d exec dmenu_run
+# There also is the (new) i3-dmenu-desktop which only displays applications
+# shipping a .desktop file. It is a wrapper around dmenu, so you need that
+# installed.
+#bindsym $mod+t exec --no-startup-id i3-dmenu-desktop
+
+# pass for dmenu
+bindsym $mod+p exec /home/lemon/bin/passmenu.sh
+
+## change focus
+#bindsym $mod+j focus left
+#bindsym $mod+k focus down
+#bindsym $mod+l focus up
+#bindsym $mod+semicolon focus right
+
+# change focus - vim -style
+bindsym $mod+u split h
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+h move left
+bindsym $mod+Shift+j move down
+bindsym $mod+Shift+k move up
+bindsym $mod+Shift+l move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+b split horizontal
+
+# split in vertical orientation
+bindsym $mod+v split vertical
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+#bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+#
+#set $workspace1 "1: Terminals"
+#set $workspace2 "2: Browser"
+
+# switch to workspace
+#bindsym $mod+1 workspace $workspace1
+#bindsym $mod+2 workspace $workspace2
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
+bindsym $mod+6 workspace 6
+bindsym $mod+7 workspace 7
+bindsym $mod+8 workspace 8
+bindsym $mod+9 workspace 9
+bindsym $mod+0 workspace 10
+
+
+# switch to workspace
+#bindsym $mod+1 workspace $workspace1
+#bindsym $mod+2 workspace $workspace2
+bindsym $mod+Control+1 workspace 11
+bindsym $mod+Control+2 workspace 12
+bindsym $mod+Control+3 workspace 3
+bindsym $mod+Control+4 workspace 14
+bindsym $mod+Control+5 workspace 15
+bindsym $mod+Control+6 workspace 16
+bindsym $mod+Control+7 workspace 17
+bindsym $mod+Control+8 workspace 18
+bindsym $mod+Control+9 workspace 19
+bindsym $mod+Control+0 workspace 20
+
+# dealing with multiple monitors
+bindsym $mod+Shift+greater move container to output right
+bindsym $mod+Shift+less move container to output left
+
+bindsym $mod+Shift+bracketright move workspace to output right
+bindsym $mod+Shift+bracketleft move workspace to output left
+
+# move focused container to workspace
+#bindsym $mod+Shift+1 move container to workspace $workspace1
+#bindsym $mod+Shift+2 move container to workspace $workspace2
+bindsym $mod+Shift+1 move container to workspace 1
+bindsym $mod+Shift+2 move container to workspace 2
+bindsym $mod+Shift+3 move container to workspace 3
+bindsym $mod+Shift+4 move container to workspace 4
+bindsym $mod+Shift+5 move container to workspace 5
+bindsym $mod+Shift+6 move container to workspace 6
+bindsym $mod+Shift+7 move container to workspace 7
+bindsym $mod+Shift+8 move container to workspace 8
+bindsym $mod+Shift+9 move container to workspace 9
+bindsym $mod+Shift+0 move container to workspace 10
+#
+# move focused container to workspace > 10
+#bindsym $mod+Shift+1 move container to workspace $workspace1
+#bindsym $mod+Shift+2 move container to workspace $workspace2
+bindsym $mod+Control+Shift+1 move container to workspace 11
+bindsym $mod+Control+Shift+2 move container to workspace 12
+bindsym $mod+Control+Shift+3 move container to workspace 13
+bindsym $mod+Control+Shift+4 move container to workspace 14
+bindsym $mod+Control+Shift+5 move container to workspace 15
+bindsym $mod+Control+Shift+6 move container to workspace 16
+bindsym $mod+Control+Shift+7 move container to workspace 17
+bindsym $mod+Control+Shift+8 move container to workspace 18
+bindsym $mod+Control+Shift+9 move container to workspace 19
+bindsym $mod+Control+Shift+0 move container to workspace 20
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ # These bindings trigger as soon as you enter the resize mode
+
+ # Pressing left will shrink the window’s width.
+ # Pressing right will grow the window’s width.
+ # Pressing up will shrink the window’s height.
+ # Pressing down will grow the window’s height.
+ bindsym j resize shrink width 10 px or 10 ppt
+ bindsym k resize grow height 10 px or 10 ppt
+ bindsym l resize shrink height 10 px or 10 ppt
+ bindsym semicolon resize grow width 10 px or 10 ppt
+
+ # same bindings, but for the arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # back to normal: Enter or Escape
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+
+new_window 1pixel
+
+bindsym $mod+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+#
+#bar {
+# status_command /home/lemon/bin/conky-i3bar
+# position top
+#}
+#
+ bar {
+ status_command i3blocks
+# status_command 2>/tmp/i3blocks.err /usr/bin/i3blocks -vvv -c /home/lemon/.config/i3blocks/config | tee /tmp/i3blocks.out
+# status_command 2>/tmp/i3blocks.err SCRIPT_DIR=~/.config/i3blocks /usr/bin/i3blocks -vvv -c /home/lemon/.config/i3blocks/config | tee /tmp/i3blocks.out
+ position top
+ mode dock
+ modifier None
+ colors {
+ background #1d2021
+ # focused_workspace #4c7899 #f2a2dc #000000
+ # active_workspace #333333 #5f676a #ffffff
+ }
+ }
diff --git a/config/i3-laptop/config-bak b/config/i3-laptop/config-bak
new file mode 100644
index 0000000..dd76647
--- /dev/null
+++ b/config/i3-laptop/config-bak
@@ -0,0 +1,241 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see http://i3wm.org/docs/userguide.html for a complete reference!
+
+set $mod Mod4
+
+# no border
+#new_window none
+#border none
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+#font pango:monospace 8
+font pango:Droid Sans Mono 10
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# Before i3 v4.8, we used to recommend this one as the default:
+# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+# The font above is very space-efficient, that is, it looks good, sharp and
+# clear in small sizes. However, its unicode glyph coverage is limited, the old
+# X core fonts rendering does not support right-to-left and this being a bitmap
+# font, it doesn’t scale on retina/hidpi displays.
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# get network app and others
+#exec --no-startup-id nm-applet
+#exec --no-startup-id /usr/bin/qjackctl
+exec --no-startup-id /usr/bin/nextcloud
+#exec --no-startup-id /usr/bin/feh --bg-max /home/lemon/Pictures/wallpaper/first_render9.png
+exec --no-startup-id /home/lemon/.screenlayout/desktop_layout_debian_all_landscape.sh
+exec --no-startup-id /usr/bin/xfce4-clipman
+#exec --no-startup-id /usr/bin/xfce4-mixer
+#exec --no-startup-id /usr/bin/xfce4-power-manager-settings # setting this
+#means laptop lid closure will kill suspend the laptop so switched off for now
+
+# scratchpad
+# Make the currently focused window a scratchpad
+bindsym $mod+Shift+minus move scratchpad
+
+# Show the first scratchpad window
+bindsym $mod+minus scratchpad show
+
+# Show the sup-mail scratchpad window, if any.
+bindsym mod4+z [title="^Sup ::"] scratchpad show
+
+# start a terminal
+#bindsym $mod+Return exec xterm -en en_GB.UTF-8
+#bindsym $mod+Return exec i3-sensible-terminal
+bindsym $mod+Return exec urxvt
+#bindsym $mod+Return exec st
+#bindsym $mod+Return exec xfce4-terminal
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+# start dmenu (a program launcher)
+bindsym $mod+d exec dmenu_run
+# There also is the (new) i3-dmenu-desktop which only displays applications
+# shipping a .desktop file. It is a wrapper around dmenu, so you need that
+# installed.
+bindsym $mod+t exec --no-startup-id i3-dmenu-desktop
+
+# pass for dmenu
+bindsym $mod+p exec /home/lemon/bin/passmenu.sh
+
+## change focus
+#bindsym $mod+j focus left
+#bindsym $mod+k focus down
+#bindsym $mod+l focus up
+#bindsym $mod+semicolon focus right
+
+# change focus - vim -style
+bindsym $mod+u split h
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+h move left
+bindsym $mod+Shift+j move down
+bindsym $mod+Shift+k move up
+bindsym $mod+Shift+l move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+g split g
+
+# split in vertical orientation
+bindsym $mod+v split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+#
+#set $workspace1 "1: Terminals"
+#set $workspace2 "2: Browser"
+
+# switch to workspace
+#bindsym $mod+1 workspace $workspace1
+#bindsym $mod+2 workspace $workspace2
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
+bindsym $mod+6 workspace 6
+bindsym $mod+7 workspace 7
+bindsym $mod+8 workspace 8
+bindsym $mod+9 workspace 9
+bindsym $mod+0 workspace 10
+
+
+# switch to workspace
+#bindsym $mod+1 workspace $workspace1
+#bindsym $mod+2 workspace $workspace2
+bindsym $mod+Control+1 workspace 11
+bindsym $mod+Control+2 workspace 12
+bindsym $mod+Control+3 workspace 3
+bindsym $mod+Control+4 workspace 14
+bindsym $mod+Control+5 workspace 15
+bindsym $mod+Control+6 workspace 16
+bindsym $mod+Control+7 workspace 17
+bindsym $mod+Control+8 workspace 18
+bindsym $mod+Control+9 workspace 19
+bindsym $mod+Control+0 workspace 20
+
+# dealing with multiple monitors
+bindsym $mod+Shift+greater move container to output right
+bindsym $mod+Shift+less move container to output left
+
+bindsym $mod+Shift+bracketright move workspace to output right
+bindsym $mod+Shift+bracketleft move workspace to output left
+
+# move focused container to workspace
+#bindsym $mod+Shift+1 move container to workspace $workspace1
+#bindsym $mod+Shift+2 move container to workspace $workspace2
+bindsym $mod+Shift+1 move container to workspace 1
+bindsym $mod+Shift+2 move container to workspace 2
+bindsym $mod+Shift+3 move container to workspace 3
+bindsym $mod+Shift+4 move container to workspace 4
+bindsym $mod+Shift+5 move container to workspace 5
+bindsym $mod+Shift+6 move container to workspace 6
+bindsym $mod+Shift+7 move container to workspace 7
+bindsym $mod+Shift+8 move container to workspace 8
+bindsym $mod+Shift+9 move container to workspace 9
+bindsym $mod+Shift+0 move container to workspace 10
+#
+# move focused container to workspace > 10
+#bindsym $mod+Shift+1 move container to workspace $workspace1
+#bindsym $mod+Shift+2 move container to workspace $workspace2
+bindsym $mod+Control+Shift+1 move container to workspace 11
+bindsym $mod+Control+Shift+2 move container to workspace 12
+bindsym $mod+Control+Shift+3 move container to workspace 13
+bindsym $mod+Control+Shift+4 move container to workspace 14
+bindsym $mod+Control+Shift+5 move container to workspace 15
+bindsym $mod+Control+Shift+6 move container to workspace 16
+bindsym $mod+Control+Shift+7 move container to workspace 17
+bindsym $mod+Control+Shift+8 move container to workspace 18
+bindsym $mod+Control+Shift+9 move container to workspace 19
+bindsym $mod+Control+Shift+0 move container to workspace 20
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ # These bindings trigger as soon as you enter the resize mode
+
+ # Pressing left will shrink the window’s width.
+ # Pressing right will grow the window’s width.
+ # Pressing up will shrink the window’s height.
+ # Pressing down will grow the window’s height.
+ bindsym j resize shrink width 10 px or 10 ppt
+ bindsym k resize grow height 10 px or 10 ppt
+ bindsym l resize shrink height 10 px or 10 ppt
+ bindsym semicolon resize grow width 10 px or 10 ppt
+
+ # same bindings, but for the arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # back to normal: Enter or Escape
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+
+new_window 1pixel
+
+bindsym $mod+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+bar {
+ status_command i3status
+}
diff --git a/config/i3/config-laptop b/config/i3/config-laptop
new file mode 100644
index 0000000..a8d82bb
--- /dev/null
+++ b/config/i3/config-laptop
@@ -0,0 +1,279 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see http://i3wm.org/docs/userguide.html for a complete reference!
+
+# start compton compiz
+#exec compton
+
+for_window [class="^.*"] border pixel 2
+
+#gaps inner 15
+#gaps outer 15
+#gaps horizontal 5
+#gaps vertical 5
+#gaps top 5
+#gaps right 5
+#gaps bottom 5
+#gaps left 5
+#
+#smart_gaps on
+
+set $mod Mod4
+
+# no border
+#new_window none
+#border none
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+#font pango:monospace 8
+font pango:mono 10
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# Before i3 v4.8, we used to recommend this one as the default:
+# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+# The font above is very space-efficient, that is, it looks good, sharp and
+# clear in small sizes. However, its unicode glyph coverage is limited, the old
+# X core fonts rendering does not support right-to-left and this being a bitmap
+# font, it doesn’t scale on retina/hidpi displays.
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# get network app and others
+#exec --no-startup-id nm-applet
+#exec --no-startup-id /usr/bin/qjackctl
+#exec --no-startup-id /usr/bin/nextcloud
+#exec --no-startup-id /usr/bin/feh --bg-max /home/lemon/Pictures/wallpaper/wallhaven-733911.jpg
+#exec --no-startup-id /home/lemon/.screenlayout/desktop_layout_debian_all_landscape.sh
+#exec --no-startup-id /usr/bin/xfce4-clipman
+#exec --no-startup-id /usr/bin/copyq
+#exec --no-startup-id /usr/bin/xfce4-mixer
+#exec --no-startup-id /usr/bin/xfce4-power-manager-settings # setting this
+#means laptop lid closure will kill suspend the laptop so switched off for now
+
+# scratchpad
+# Make the currently focused window a scratchpad
+bindsym $mod+Shift+minus exec /home/lemon/bin/i3scripts/scratch_todo
+bindsym $mod+Shift+BackSpace move scratchpad
+bindsym $mod+minus scratchpad show
+
+# Show the sup-mail scratchpad window, if any.
+#bindsym mod4+z [title="^Sup ::"] scratchpad show
+
+# start a terminal
+bindsym $mod+Return exec xterm -en en_GB.UTF-8
+#bindsym $mod+Return exec i3-sensible-terminal
+#bindsym $mod+Return exec urxvt
+#bindsym $mod+Return exec st
+
+# change gap size
+
+#bindsym $mod+z gaps outer current plus 5
+#bindsym $mod+Shift+z gaps outer current minus 5
+#bindsym $mod+g gaps inner current plus 5
+#bindsym $mod+Shift+g gaps inner current minus 5
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+# start dmenu (a program launcher)
+bindsym $mod+d exec dmenu_run
+# There also is the (new) i3-dmenu-desktop which only displays applications
+# shipping a .desktop file. It is a wrapper around dmenu, so you need that
+# installed.
+#bindsym $mod+t exec --no-startup-id i3-dmenu-desktop
+
+# pass for dmenu
+bindsym $mod+p exec /home/lemon/bin/passmenu.sh
+
+## change focus
+#bindsym $mod+j focus left
+#bindsym $mod+k focus down
+#bindsym $mod+l focus up
+#bindsym $mod+semicolon focus right
+
+# change focus - vim -style
+bindsym $mod+u split h
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+h move left
+bindsym $mod+Shift+j move down
+bindsym $mod+Shift+k move up
+bindsym $mod+Shift+l move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+b split horizontal
+
+# split in vertical orientation
+bindsym $mod+v split vertical
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+#bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+#
+#set $workspace1 "1: Terminals"
+#set $workspace2 "2: Browser"
+
+# switch to workspace
+#bindsym $mod+1 workspace $workspace1
+#bindsym $mod+2 workspace $workspace2
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
+bindsym $mod+6 workspace 6
+bindsym $mod+7 workspace 7
+bindsym $mod+8 workspace 8
+bindsym $mod+9 workspace 9
+bindsym $mod+0 workspace 10
+
+
+# switch to workspace
+#bindsym $mod+1 workspace $workspace1
+#bindsym $mod+2 workspace $workspace2
+bindsym $mod+Control+1 workspace 11
+bindsym $mod+Control+2 workspace 12
+bindsym $mod+Control+3 workspace 3
+bindsym $mod+Control+4 workspace 14
+bindsym $mod+Control+5 workspace 15
+bindsym $mod+Control+6 workspace 16
+bindsym $mod+Control+7 workspace 17
+bindsym $mod+Control+8 workspace 18
+bindsym $mod+Control+9 workspace 19
+bindsym $mod+Control+0 workspace 20
+
+# dealing with multiple monitors
+bindsym $mod+Shift+greater move container to output right
+bindsym $mod+Shift+less move container to output left
+
+bindsym $mod+Shift+bracketright move workspace to output right
+bindsym $mod+Shift+bracketleft move workspace to output left
+
+# move focused container to workspace
+#bindsym $mod+Shift+1 move container to workspace $workspace1
+#bindsym $mod+Shift+2 move container to workspace $workspace2
+bindsym $mod+Shift+1 move container to workspace 1
+bindsym $mod+Shift+2 move container to workspace 2
+bindsym $mod+Shift+3 move container to workspace 3
+bindsym $mod+Shift+4 move container to workspace 4
+bindsym $mod+Shift+5 move container to workspace 5
+bindsym $mod+Shift+6 move container to workspace 6
+bindsym $mod+Shift+7 move container to workspace 7
+bindsym $mod+Shift+8 move container to workspace 8
+bindsym $mod+Shift+9 move container to workspace 9
+bindsym $mod+Shift+0 move container to workspace 10
+#
+# move focused container to workspace > 10
+#bindsym $mod+Shift+1 move container to workspace $workspace1
+#bindsym $mod+Shift+2 move container to workspace $workspace2
+bindsym $mod+Control+Shift+1 move container to workspace 11
+bindsym $mod+Control+Shift+2 move container to workspace 12
+bindsym $mod+Control+Shift+3 move container to workspace 13
+bindsym $mod+Control+Shift+4 move container to workspace 14
+bindsym $mod+Control+Shift+5 move container to workspace 15
+bindsym $mod+Control+Shift+6 move container to workspace 16
+bindsym $mod+Control+Shift+7 move container to workspace 17
+bindsym $mod+Control+Shift+8 move container to workspace 18
+bindsym $mod+Control+Shift+9 move container to workspace 19
+bindsym $mod+Control+Shift+0 move container to workspace 20
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ # These bindings trigger as soon as you enter the resize mode
+
+ # Pressing left will shrink the window’s width.
+ # Pressing right will grow the window’s width.
+ # Pressing up will shrink the window’s height.
+ # Pressing down will grow the window’s height.
+ bindsym j resize shrink width 10 px or 10 ppt
+ bindsym k resize grow height 10 px or 10 ppt
+ bindsym l resize shrink height 10 px or 10 ppt
+ bindsym semicolon resize grow width 10 px or 10 ppt
+
+ # same bindings, but for the arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # back to normal: Enter or Escape
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+
+new_window 1pixel
+
+bindsym $mod+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+#
+#bar {
+# status_command /home/lemon/bin/conky-i3bar
+# position top
+#}
+#
+ bar {
+# status_command /usr/local/bin/i3status
+# status_command 2>/tmp/i3blocks.err /usr/bin/i3blocks -vvv -c /home/lemon/.config/i3blocks/config | tee /tmp/i3blocks.out
+# status_command 2>/tmp/i3blocks.err SCRIPT_DIR=~/.config/i3blocks /usr/bin/i3blocks -vvv -c /home/lemon/.config/i3blocks/config | tee /tmp/i3blocks.out
+ position top
+ mode dock
+ modifier None
+ colors {
+ background #1d2021
+ # focused_workspace #4c7899 #f2a2dc #000000
+ # active_workspace #333333 #5f676a #ffffff
+ }
+ }
diff --git a/config/i3blocks/config b/config/i3blocks/config
new file mode 100644
index 0000000..05b0bb8
--- /dev/null
+++ b/config/i3blocks/config
@@ -0,0 +1,191 @@
+# LEMON NOTE:
+
+# The fucking environment variables don't work in i3 for me so I've had to put
+# the paths to scripts in this file manually.
+
+#********************
+
+# i3blocks config file
+#
+# Please see man i3blocks for a complete reference!
+# The man page is also hosted at http://vivien.github.io/i3blocks
+#
+# List of valid properties:
+#
+# align
+# color
+# command
+# full_text
+# instance
+# interval
+# label
+# min_width
+# name
+# separator
+# separator_block_width
+# short_text
+# signal
+# urgent
+
+# Global properties
+#
+# The top properties below are applied to every block, but can be overridden.
+# Each block command defaults to the script name to avoid boilerplate.
+# Change $SCRIPT_DIR to the location of your scripts!
+#command=$SCRIPT_DIR/$BLOCK_NAME
+command=$SCRIPT_DIR/$BLOCK_NAME
+separator_block_width=15
+markup=none
+#
+# Generic media player support
+#
+# This displays "ARTIST - SONG" if a music is playing.
+# Supported players are: spotify, vlc, audacious, xmms2, mplayer, and others.
+#[mediaplayer]
+#command=/~.config/i3blocks/mediaplayer/mediaplayer
+#instance=spotify
+#interval=5
+#signal=10
+
+
+# Volume indicator
+#
+# The first parameter sets the step (and units to display)
+# The second parameter overrides the mixer selection
+# See the script for details.
+
+[volume]
+label=♪
+#label=VOL
+interval=1
+signal=10
+command=~/.config/i3blocks/volume/volume
+#STEP=5%
+
+# Memory usage
+#
+# The type defaults to "mem" if the instance is not specified.
+[memory]
+label=MEM
+separator=false
+command=~/.config/i3blocks/memory/memory
+interval=30
+
+[memory]
+label=SWAP
+instance=swap
+separator=false
+command=~/.config/i3blocks/memory/memory
+interval=30
+
+# Disk usage
+#
+# The directory defaults to $HOME if the instance is not specified.
+# The script may be called with a optional argument to set the alert
+# (defaults to 10 for 10%).
+[disk]
+label=HOME
+command=~/.config/i3blocks/disk/disk
+#DIR=/mnt/data
+interval=30
+
+# Network interface monitoring
+#
+# If the instance is not specified, use the interface used for default route.
+# The address can be forced to IPv4 or IPv6 with -4 or -6 switches.
+[iface]
+#IFACE=enp6s0
+color=#00FF00
+interval=10
+command=~/.config/i3blocks/iface/iface
+separator=false
+
+[wifi]
+#INTERFACE=wlp3s0
+label=wifi:
+interval=10
+command=~/.config/i3blocks/wifi/wifi
+separator=false
+
+[bandwidth]
+#INTERFACE=enp6s0
+command=~/.config/i3blocks/bandwidth/bandwidth
+interval=5
+
+# CPU usage
+#
+# The script may be called with -w and -c switches to specify thresholds,
+# see the script for details.
+[cpu_usage]
+label=CPU
+interval=10
+min_width=CPU 100.00%
+command=~/.config/i3blocks/cpu_usage/cpu_usage
+#separator=false
+
+[load_average]
+label=LOAD
+command=~/.config/i3blocks/load_average/load_average
+interval=10
+
+# Battery indicator
+#
+# The battery instance defaults to 0.
+[battery]
+#label=BAT
+label=âš¡
+interval=30
+command=~/.config/i3blocks/battery/battery
+
+
+[location]
+command=~/.config/i3blocks/ip-location-for-i3blocks.sh
+interval=60
+color=#cafc16
+
+[upgrades]
+label=UPGRADES
+command=~/.config/i3blocks/apt-upgrades/apt-upgrades
+interval=60
+
+#
+# Date Time
+#
+[time]
+command=date '+%Y-%m-%d %H:%M:%S'
+interval=5
+
+
+
+# OpenVPN support
+#
+# Support multiple VPN, with colors.
+#[openvpn]
+#interval=20
+
+# Temperature
+#
+# Support multiple chips, though lm-sensors.
+# The script may be called with -w and -c switches to specify thresholds,
+# see the script for details.
+#[temperature]
+#label=TEMP
+#interval=10
+
+# Key indicators
+#
+# Add the following bindings to i3 config file:
+#
+# bindsym --release Caps_Lock exec pkill -SIGRTMIN+11 i3blocks
+# bindsym --release Num_Lock exec pkill -SIGRTMIN+11 i3blocks
+#[keyindicator]
+#KEY=CAPS
+#markup=pango
+#interval=once
+#signal=11
+
+#[keyindicator]
+#KEY=NUM
+#markup=pango
+#interval=once
+#signal=11
diff --git a/ctags b/ctags
new file mode 100644
index 0000000..2f7638b
--- /dev/null
+++ b/ctags
@@ -0,0 +1,3 @@
+--python-kinds=-iv
+--exclude=build
+--exclude=dist
diff --git a/fish/.config.fish.un~ b/fish/.config.fish.un~
new file mode 100644
index 0000000..c6ba657
--- /dev/null
+++ b/fish/.config.fish.un~
Binary files differ
diff --git a/fish/completions/bcompiler.fish b/fish/completions/bcompiler.fish
new file mode 100644
index 0000000..57d6433
--- /dev/null
+++ b/fish/completions/bcompiler.fish
@@ -0,0 +1,7 @@
+complete -c "bcompiler" -s h -l help -d "Get help for bcompiler"
+complete -c "bcompiler" -s c -l clean-datamap -d "Clean the datamap"
+complete -c "bcompiler" -s v -l version -d "Ask for version"
+complete -c "bcompiler" -s p -l parse -d "Parse master.csv and transpose" -a "(find ~/Documents/bcompiler/source -maxdepth 1 | grep master)"
+complete -c "bcompiler" -s a -l all -d "Create new populated templates from master.csv"
+complete -c "bcompiler" -l compare -d "Compare old master with current one" -a "old_master"
+complete -c "bcompiler" -s ll -d "Debugging options" -a "DEBUG INFO WARNING ERROR CRITICAL"
diff --git a/fish/completions/catnote.fish b/fish/completions/catnote.fish
new file mode 100644
index 0000000..d4d7165
--- /dev/null
+++ b/fish/completions/catnote.fish
@@ -0,0 +1 @@
+complete -c "catnote" -a "(find /home/lemon/Nextcloud/Textnotes -type f)"
diff --git a/fish/completions/fisher.fish b/fish/completions/fisher.fish
new file mode 100644
index 0000000..61a3810
--- /dev/null
+++ b/fish/completions/fisher.fish
@@ -0,0 +1 @@
+fisher --complete
diff --git a/fish/completions/hl-monthly-for-account.fish b/fish/completions/hl-monthly-for-account.fish
new file mode 100644
index 0000000..1c38c98
--- /dev/null
+++ b/fish/completions/hl-monthly-for-account.fish
@@ -0,0 +1 @@
+complete -c "hl-monthly-for-account" -d "hledger register by month for account" -a "(hledger account)"
diff --git a/fish/completions/hl-weekly-for-account.fish b/fish/completions/hl-weekly-for-account.fish
new file mode 100644
index 0000000..bd0e801
--- /dev/null
+++ b/fish/completions/hl-weekly-for-account.fish
@@ -0,0 +1 @@
+complete -c "hl-weekly-for-account" -d "hledger register by month for account" -a "(hledger account)"
diff --git a/fish/completions/pass.fish b/fish/completions/pass.fish
new file mode 100644
index 0000000..3e70af1
--- /dev/null
+++ b/fish/completions/pass.fish
@@ -0,0 +1,117 @@
+#!/usr/bin/env fish
+
+# Copyright (C) 2012-2014 Dmitry Medvinsky <me@dmedvinsky.name>. All Rights Reserved.
+# This file is licensed under the GPLv2+. Please see COPYING for more information.
+
+set -l PROG 'pass'
+
+function __fish_pass_get_prefix
+ set -l prefix "$PASSWORD_STORE_DIR"
+ if [ -z "$prefix" ]
+ set prefix "$HOME/.password-store"
+ end
+ echo "$prefix"
+end
+
+function __fish_pass_needs_command
+ [ (count (commandline -opc)) -eq 1 ]
+end
+
+function __fish_pass_uses_command
+ set -l cmd (commandline -opc)
+ if [ (count $cmd) -gt 1 ]
+ if [ $argv[1] = $cmd[2] ]
+ return 0
+ end
+ end
+ return 1
+end
+
+function __fish_pass_print_gpg_keys
+ gpg2 --list-keys | grep uid | sed 's/.*<\(.*\)>/\1/'
+end
+
+function __fish_pass_print
+ set -l ext $argv[1]
+ set -l strip $argv[2]
+ set -l prefix (__fish_pass_get_prefix)
+ set -l matches $prefix/**$ext
+ printf '%s\n' $matches | sed "s#$prefix/\(.*\)$strip#\1#"
+end
+
+function __fish_pass_print_entry_dirs
+ __fish_pass_print "/"
+end
+
+function __fish_pass_print_entries
+ __fish_pass_print ".gpg" ".gpg"
+end
+
+function __fish_pass_print_entries_and_dirs
+ __fish_pass_print_entry_dirs
+ __fish_pass_print_entries
+end
+
+function __fish_pass_git_complete
+ set -l prefix (__fish_pass_get_prefix)
+ set -l git_cmd (commandline -opc) (commandline -ct)
+ set -e git_cmd[1 2] # Drop "pass git".
+ complete -C"git -C $prefix $git_cmd"
+end
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a help -d 'Command: show usage help'
+complete -c $PROG -f -n '__fish_pass_needs_command' -a version -d 'Command: show program version'
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a init -d 'Command: initialize new password storage'
+complete -c $PROG -f -n '__fish_pass_uses_command init' -s p -l path -d 'Assign gpg-id for specified sub folder of password store'
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a ls -d 'Command: list passwords'
+complete -c $PROG -f -n '__fish_pass_uses_command ls' -a "(__fish_pass_print_entry_dirs)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a insert -d 'Command: insert new password'
+complete -c $PROG -f -n '__fish_pass_uses_command insert' -s e -l echo -d 'Echo the password on console'
+complete -c $PROG -f -n '__fish_pass_uses_command insert' -s m -l multiline -d 'Provide multiline password entry'
+complete -c $PROG -f -n '__fish_pass_uses_command insert' -s f -l force -d 'Do not prompt before overwritting'
+complete -c $PROG -f -n '__fish_pass_uses_command insert' -a "(__fish_pass_print_entry_dirs)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a generate -d 'Command: generate new password'
+complete -c $PROG -f -n '__fish_pass_uses_command generate' -s n -l no-symbols -d 'Do not use special symbols'
+complete -c $PROG -f -n '__fish_pass_uses_command generate' -s c -l clip -d 'Put the password in clipboard'
+complete -c $PROG -f -n '__fish_pass_uses_command generate' -s f -l force -d 'Do not prompt before overwritting'
+complete -c $PROG -f -n '__fish_pass_uses_command generate' -s i -l in-place -d 'Replace only the first line with the generated password'
+complete -c $PROG -f -n '__fish_pass_uses_command generate' -a "(__fish_pass_print_entry_dirs)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a mv -d 'Command: rename existing password'
+complete -c $PROG -f -n '__fish_pass_uses_command mv' -s f -l force -d 'Force rename'
+complete -c $PROG -f -n '__fish_pass_uses_command mv' -a "(__fish_pass_print_entries_and_dirs)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a cp -d 'Command: copy existing password'
+complete -c $PROG -f -n '__fish_pass_uses_command cp' -s f -l force -d 'Force copy'
+complete -c $PROG -f -n '__fish_pass_uses_command cp' -a "(__fish_pass_print_entries_and_dirs)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a rm -d 'Command: remove existing password'
+complete -c $PROG -f -n '__fish_pass_uses_command rm' -s r -l recursive -d 'Remove password groups recursively'
+complete -c $PROG -f -n '__fish_pass_uses_command rm' -s f -l force -d 'Force removal'
+complete -c $PROG -f -n '__fish_pass_uses_command rm' -a "(__fish_pass_print_entries_and_dirs)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a edit -d 'Command: edit password using text editor'
+complete -c $PROG -f -n '__fish_pass_uses_command edit' -a "(__fish_pass_print_entries)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a show -d 'Command: show existing password'
+complete -c $PROG -f -n '__fish_pass_uses_command show' -s c -l clip -d 'Put password in clipboard'
+complete -c $PROG -f -n '__fish_pass_uses_command show' -a "(__fish_pass_print_entries)"
+# When no command is given, `show` is defaulted.
+complete -c $PROG -f -n '__fish_pass_needs_command' -s c -l clip -d 'Put password in clipboard'
+complete -c $PROG -f -n '__fish_pass_needs_command' -a "(__fish_pass_print_entries)"
+complete -c $PROG -f -n '__fish_pass_uses_command -c' -a "(__fish_pass_print_entries)"
+complete -c $PROG -f -n '__fish_pass_uses_command --clip' -a "(__fish_pass_print_entries)"
+
+complete -c $PROG -f -n '__fish_pass_needs_command' -a git -d 'Command: execute a git command'
+complete -c $PROG -f -n '__fish_pass_uses_command git' -a '(__fish_pass_git_complete)'
+complete -c $PROG -f -n '__fish_pass_needs_command' -a find -d 'Command: find a password file or directory matching pattern'
+complete -c $PROG -f -n '__fish_pass_needs_command' -a grep -d 'Command: search inside of decrypted password files for matching pattern'
+complete -c $PROG -f -n '__fish_pass_uses_command grep' -a '(begin
+ set -l cmd (commandline -opc) (commandline -ct)
+ set -e cmd[1 2] # Drop "pass grep".
+ complete -C"grep $cmd"
+end)'
diff --git a/fish/completions/pipenv.fish b/fish/completions/pipenv.fish
new file mode 100644
index 0000000..01ca3be
--- /dev/null
+++ b/fish/completions/pipenv.fish
@@ -0,0 +1 @@
+eval (pipenv --completion)
diff --git a/fish/completions/poetry.fish b/fish/completions/poetry.fish
new file mode 100644
index 0000000..2d3f76c
--- /dev/null
+++ b/fish/completions/poetry.fish
@@ -0,0 +1,145 @@
+function __fish_poetry_3a61cd031c563512_complete_no_subcommand
+ for i in (commandline -opc)
+ if contains -- $i about add build cache:clear check config debug:info debug:resolve develop help init install list lock new publish remove run script search self:update shell show update version
+ return 1
+ end
+ end
+ return 0
+end
+
+# global options
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l ansi -d 'Force ANSI output'
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l help -d 'Display this help message'
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l no-ansi -d 'Disable ANSI output'
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l no-interaction -d 'Do not ask any interactive question'
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l quiet -d 'Do not output any message'
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l verbose -d 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'
+complete -c poetry -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -l version -d 'Display this application version'
+
+# commands
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a about -d 'Short information about Poetry.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a add -d 'Add a new dependency to pyproject.toml.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a build -d 'Builds a package, as a tarball and a wheel by default.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a cache:clear -d 'Clears poetry\'s cache.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a check -d 'Checks the validity of the pyproject.toml file.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a config -d 'Sets/Gets config options.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a debug:info -d 'Shows debug information.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a debug:resolve -d 'Debugs dependency resolution.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a develop -d 'Installs the current project in development mode. (Deprecated)'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a help -d 'Displays help for a command'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a init -d 'Creates a basic pyproject.toml file in the current directory.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a install -d 'Installs the project dependencies.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a list -d 'Lists commands'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a lock -d 'Locks the project dependencies.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a new -d 'Creates a new Python project at <path>'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a publish -d 'Publishes a package to a remote repository.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a remove -d 'Removes a package from the project dependencies.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a run -d 'Runs a command in the appropriate environment.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a script -d 'Executes a script defined in pyproject.toml. (Deprecated)'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a search -d 'Searches for packages on remote repositories.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a self:update -d 'Updates poetry to the latest version.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a shell -d 'Spawns a shell within the virtual environment.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a show -d 'Shows information about packages.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a update -d 'Update dependencies as according to the pyproject.toml file.'
+complete -c poetry -f -n '__fish_poetry_3a61cd031c563512_complete_no_subcommand' -a version -d 'Bumps the version of the project.'
+
+# command options
+
+# about
+
+# add
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l allow-prereleases -d 'Accept prereleases.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l dev -d 'Add package as development dependency.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l dry-run -d 'Outputs the operations but will not execute anything (implicitly enables --verbose).'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l extras -d 'Extras to activate for the dependency.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l git -d 'The url of the Git repository.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l optional -d 'Add as an optional dependency.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l path -d 'The path to a dependency.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l platform -d 'Platforms for which the dependencies must be installed.'
+complete -c poetry -A -n '__fish_seen_subcommand_from add' -l python -d 'Python version( for which the dependencies must be installed.'
+
+# build
+complete -c poetry -A -n '__fish_seen_subcommand_from build' -l format -d 'Limit the format to either wheel or sdist.'
+
+# cache:clear
+complete -c poetry -A -n '__fish_seen_subcommand_from cache:clear' -l all -d 'Clear all entries in cache.'
+
+# check
+
+# config
+complete -c poetry -A -n '__fish_seen_subcommand_from config' -l list -d 'List configuration settings'
+complete -c poetry -A -n '__fish_seen_subcommand_from config' -l unset -d 'Unset configuration setting'
+
+# debug:info
+
+# debug:resolve
+complete -c poetry -A -n '__fish_seen_subcommand_from debug:resolve' -l extras -d 'Extras to activate for the dependency.'
+complete -c poetry -A -n '__fish_seen_subcommand_from debug:resolve' -l install -d 'Show what would be installed for the current system.'
+complete -c poetry -A -n '__fish_seen_subcommand_from debug:resolve' -l python -d 'Python version(s) to use for resolution.'
+complete -c poetry -A -n '__fish_seen_subcommand_from debug:resolve' -l tree -d 'Displays the dependency tree.'
+
+# develop
+
+# help
+complete -c poetry -A -n '__fish_seen_subcommand_from help' -l format -d 'The output format (txt, json, or md)'
+complete -c poetry -A -n '__fish_seen_subcommand_from help' -l raw -d 'To output raw command help'
+
+# init
+complete -c poetry -A -n '__fish_seen_subcommand_from init' -l author -d 'Author name of the package'
+complete -c poetry -A -n '__fish_seen_subcommand_from init' -l dependency -d 'Package to require with an optional version constraint, e.g. requests:^2.10.0 or requests=2.11.1'
+complete -c poetry -A -n '__fish_seen_subcommand_from init' -l description -d 'Description of the package'
+complete -c poetry -A -n '__fish_seen_subcommand_from init' -l dev-dependency -d 'Package to require for development with an optional version constraint, e.g. requests:^2.10.0 or requests=2.11.1'
+complete -c poetry -A -n '__fish_seen_subcommand_from init' -l license -d 'License of the package'
+complete -c poetry -A -n '__fish_seen_subcommand_from init' -l name -d 'Name of the package'
+
+# install
+complete -c poetry -A -n '__fish_seen_subcommand_from install' -l develop -d 'Install given packages in development mode.'
+complete -c poetry -A -n '__fish_seen_subcommand_from install' -l dry-run -d 'Outputs the operations but will not execute anything (implicitly enables --verbose).'
+complete -c poetry -A -n '__fish_seen_subcommand_from install' -l extras -d 'Extra sets of dependencies to install.'
+complete -c poetry -A -n '__fish_seen_subcommand_from install' -l no-dev -d 'Do not install dev dependencies.'
+
+# list
+complete -c poetry -A -n '__fish_seen_subcommand_from list' -l format -d 'The output format (txt, json, or md)'
+complete -c poetry -A -n '__fish_seen_subcommand_from list' -l raw -d 'To output raw command list'
+
+# lock
+
+# new
+complete -c poetry -A -n '__fish_seen_subcommand_from new' -l name -d 'Set the resulting package name.'
+complete -c poetry -A -n '__fish_seen_subcommand_from new' -l src -d 'Use the src layout for the project.'
+
+# publish
+complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l build -d 'Build the package before publishing.'
+complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l password -d 'The password to access the repository.'
+complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l repository -d 'The repository to publish the package to.'
+complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l username -d 'The username to access the repository.'
+
+# remove
+complete -c poetry -A -n '__fish_seen_subcommand_from remove' -l dev -d 'Removes a package from the development dependencies.'
+complete -c poetry -A -n '__fish_seen_subcommand_from remove' -l dry-run -d 'Outputs the operations but will not execute anything (implicitly enables --verbose).'
+
+# run
+
+# script
+
+# search
+complete -c poetry -A -n '__fish_seen_subcommand_from search' -l only-name -d 'Search only in name.'
+
+# self:update
+complete -c poetry -A -n '__fish_seen_subcommand_from self:update' -l preview -d 'Install prereleases.'
+
+# shell
+
+# show
+complete -c poetry -A -n '__fish_seen_subcommand_from show' -l all -d 'Show all packages (even those not compatible with current system).'
+complete -c poetry -A -n '__fish_seen_subcommand_from show' -l latest -d 'Show the latest version.'
+complete -c poetry -A -n '__fish_seen_subcommand_from show' -l no-dev -d 'Do not list the dev dependencies.'
+complete -c poetry -A -n '__fish_seen_subcommand_from show' -l outdated -d 'Show the latest version but only for packages that are outdated.'
+complete -c poetry -A -n '__fish_seen_subcommand_from show' -l tree -d 'List the dependencies as a tree.'
+
+# update
+complete -c poetry -A -n '__fish_seen_subcommand_from update' -l dry-run -d 'Outputs the operations but will not execute anything (implicitly enables --verbose).'
+complete -c poetry -A -n '__fish_seen_subcommand_from update' -l lock -d 'Do not perform install (only update the lockfile).'
+complete -c poetry -A -n '__fish_seen_subcommand_from update' -l no-dev -d 'Do not install dev dependencies.'
+
+# version
diff --git a/fish/completions/twdft.fish b/fish/completions/twdft.fish
new file mode 100644
index 0000000..7474227
--- /dev/null
+++ b/fish/completions/twdft.fish
@@ -0,0 +1,6 @@
+#complete -c twdft -l create_inspection -d "Port Facility Name" -a "(twdft complete_site (commandline -cp))"
+#complete -f -c twdft -d "Create inspection" -a "(twdft complete_site)"
+complete -f -c twdft -d "Port Facility" -a "(twdft_complete_site)"
+complete -f -c twdft -l inspectiondate -d "Inspection date"
+complete -f -c twdft -l inspectiontime -d "Inspection time"
+complete -f -c twdft -l opencard -d "Open inspection card in vim"
diff --git a/fish/config.fish b/fish/config.fish
new file mode 100644
index 0000000..41b3457
--- /dev/null
+++ b/fish/config.fish
@@ -0,0 +1,38 @@
+## fish git prompt
+#set __fish_git_prompt_showdirtystate 'yes'
+#set __fish_git_prompt_showstashstate 'yes'
+#set __fish_git_prompt_showupstream 'yes'
+#set __fish_git_prompt_color_branch yellow
+#
+## Status Chars
+#set __fish_git_prompt_char_dirtystate 'âš¡'
+#set __fish_git_prompt_char_stagedstate '→'
+#set __fish_git_prompt_char_stashstate '↩'
+#set __fish_git_prompt_char_upstream_ahead '↑'
+#set __fish_git_prompt_char_upstream_behind '↓'
+#
+
+alias xclip='xclip -selection c'
+set fish_greeting ""
+set -gx TERM screen-256color
+#set -gx TERM xterm-256color
+set -gx SHELL /usr/bin/fish
+set -gx PATH ~/.local/bin $PATH
+set -gx PATH ~/scripts $PATH
+set -gx PATH ~/bin $PATH
+set -gx FZF_DEFAULT_COMMAND 'ag --nocolor -g ""'
+set -gx FZF_CTRL_T_COMMAND $FZF_DEFAULT_COMMAND
+set -gx FZF_ALT_C_COMMAND $FZF_DEFAULT_COMMAND
+set -gx FZF_DEFAULT_OPTS '--color info:108,prompt:109,spinner:108,pointer:168,marker:168'
+#set -gx FZF_DEFAULT_OPTS '--color=bw'
+
+# OPAM configuration
+source /home/lemon/.opam/opam-init/init.fish > /dev/null 2> /dev/null or true
+#
+# THIS REMOVES COLOURS FROM ls COMMAND, ETC
+# from https://opensource.com/article/19/9/linux-terminal-colors
+#set -gx LS_COLORS 'rs=0:di=01;00:ln=01;00:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;66:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:';
+set -gx GPG_TTY (tty)
+set -gx SSH_AUTH_SOCK (gpgconf --list-dirs agent-ssh-socket)
+gpgconf --launch gpg-agent
+#. ~/perl5/perlbrew/etc/perlbrew.fish
diff --git a/fish/fish_variables b/fish/fish_variables
new file mode 100644
index 0000000..2d81313
--- /dev/null
+++ b/fish/fish_variables
@@ -0,0 +1,43 @@
+# This file contains fish universal variable definitions.
+# VERSION: 3.0
+SETUVAR --export EDITOR:/usr/bin/nvim
+SETUVAR --export LEDGER_FILE:/home/lemon/ledger/hledger\x2eledger
+SETUVAR PATH:/home/lemon/bin/adb\x2dfastboot/platform\x2dtools/\x1e/home/lemon/bin\x1e/home/lemon/scripts\x1e/home/lemon/\x2elocal/bin\x1e/home/lemon/\x2efzf/bin\x1e/home/lemon/bin\x1e/home/lemon/scripts\x1e/home/lemon/\x2elocal/bin\x1e/home/lemon/bin\x1e/usr/local/bin\x1e/usr/bin\x1e/bin\x1e/usr/local/games\x1e/usr/games
+SETUVAR --export TERMINAL:/usr/bin/xfce4\x2dterminal
+SETUVAR --export _JAVA_OPTIONS:\x2dDswing\x2eaatext\x3dTRUE\x1e\x2dDawt\x2euseSystemAAFontSettings\x3don
+SETUVAR __fish_classic_git_prompt_initialized:\x1d
+SETUVAR __fish_init_2_39_8:\x1d
+SETUVAR __fish_init_2_3_0:\x1d
+SETUVAR __fish_init_3_x:\x1d
+SETUVAR __fish_initialized:3100
+SETUVAR fish_color_autosuggestion:555\x1ebrblack
+SETUVAR fish_color_cancel:\x2dr
+SETUVAR fish_color_command:005fd7
+SETUVAR fish_color_comment:990000
+SETUVAR fish_color_cwd:green
+SETUVAR fish_color_cwd_root:red
+SETUVAR fish_color_end:009900
+SETUVAR fish_color_error:ff0000
+SETUVAR fish_color_escape:00a6b2
+SETUVAR fish_color_history_current:\x2d\x2dbold
+SETUVAR fish_color_host:normal
+SETUVAR fish_color_host_remote:yellow
+SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue
+SETUVAR fish_color_normal:normal
+SETUVAR fish_color_operator:00a6b2
+SETUVAR fish_color_param:00afff
+SETUVAR fish_color_quote:999900
+SETUVAR fish_color_redirection:00afff
+SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack
+SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack
+SETUVAR fish_color_status:red
+SETUVAR fish_color_user:brgreen
+SETUVAR fish_color_valid_path:\x2d\x2dunderline
+SETUVAR fish_greeting:
+SETUVAR fish_key_bindings:fish_default_key_bindings
+SETUVAR fish_pager_color_completion:normal
+SETUVAR fish_pager_color_description:B3A06D\x1eyellow
+SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
+SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan
+SETUVAR fish_user_paths:/home/lemon/perl5/perlbrew/bin/\x1e/usr/lib/cargo/bin/\x1e/home/lemon/go/bin\x1e/usr/local/go/bin\x1e/snap/bin\x1e/home/lemon/\x2epoetry/bin\x1e/home/lemon/\x2ecargo/bin\x1e/snap/bin\x1e/home/lemon/bin\x1e/home/lemon/bin/adb\x2dfastboot/platform\x2dtools/\x1e/home/lemon/\x2efzf/bin\x1e/home/lemon/bin
+SETUVAR fisher_dependency_count:Colored\x2dMan\x2dPages\x1ebass
diff --git a/fish/fishd.debian9 b/fish/fishd.debian9
new file mode 100644
index 0000000..56d0eb7
--- /dev/null
+++ b/fish/fishd.debian9
@@ -0,0 +1,36 @@
+# This file is automatically generated by the fish.
+# Do NOT edit it directly, your changes will be overwritten.
+SET_EXPORT EDITOR:/usr/bin/nvim
+SET_EXPORT PAGER:/usr/bin/less
+SET __fish_classic_git_prompt_initialized:\x1d
+SET __fish_init_2_39_8:\x1d
+SET __fish_init_2_3_0:\x1d
+SET fish_color_autosuggestion:555\x1ebrblack
+SET fish_color_command:\x2d\x2dbold
+SET fish_color_comment:red
+SET fish_color_cwd:green
+SET fish_color_cwd_root:red
+SET fish_color_end:brmagenta
+SET fish_color_error:brred
+SET fish_color_escape:bryellow\x1e\x2d\x2dbold
+SET fish_color_history_current:\x2d\x2dbold
+SET fish_color_host:normal
+SET fish_color_match:\x2d\x2dbackground\x3dbrblue
+SET fish_color_normal:normal
+SET fish_color_operator:bryellow
+SET fish_color_param:cyan
+SET fish_color_quote:yellow
+SET fish_color_redirection:brblue
+SET fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack
+SET fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack
+SET fish_color_status:red
+SET fish_color_user:brgreen
+SET fish_color_valid_path:\x2d\x2dunderline
+SET fish_greeting:\x1d
+SET fish_key_bindings:fish_default_key_bindings
+SET fish_pager_color_completion:\x1d
+SET fish_pager_color_description:B3A06D\x1eyellow
+SET fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
+SET fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan
+SET fish_user_abbreviations:mux\x20tmuxinator\x1etfiles\x20/home/lemon/Nextcloud/Textnotes\x1eml_rmsharepics\x20rm\x20\x7e/Nextcloud/SharePics/\x2a\x3b\x20and\x20echo\x20\x27SharePics\x20folder\x20cleared\x21\x27
+SET fish_user_paths:/home/lemon/\x2efzf/bin
diff --git a/fish/fishfile b/fish/fishfile
new file mode 100644
index 0000000..3b753a3
--- /dev/null
+++ b/fish/fishfile
@@ -0,0 +1,2 @@
+edc/bass
+patrickf3139/Colored-Man-Pages
diff --git a/fish/functions/.vi.fish.un~ b/fish/functions/.vi.fish.un~
new file mode 100644
index 0000000..2fa5fb1
--- /dev/null
+++ b/fish/functions/.vi.fish.un~
Binary files differ
diff --git a/fish/functions/__bass.py b/fish/functions/__bass.py
new file mode 120000
index 0000000..32d6148
--- /dev/null
+++ b/fish/functions/__bass.py
@@ -0,0 +1 @@
+/home/lemon/.config/fisherman/bass/functions/__bass.py \ No newline at end of file
diff --git a/fish/functions/a.fish b/fish/functions/a.fish
new file mode 100644
index 0000000..43b36db
--- /dev/null
+++ b/fish/functions/a.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function a --description 'alias a task add'
+ task add $argv;
+end
diff --git a/fish/functions/add-inspection-prep-to-todo.fish b/fish/functions/add-inspection-prep-to-todo.fish
new file mode 100644
index 0000000..eb4d5b7
--- /dev/null
+++ b/fish/functions/add-inspection-prep-to-todo.fish
@@ -0,0 +1,9 @@
+# Defined in /tmp/fish.KYnv1Y/add-inspection-prep-to-todo.fish @ line 2
+function add-inspection-prep-to-todo --description 'Adds a bunch of stuff from a text file to end of todo.txt file'
+ if [ -z "$argv" ]; # no arguments
+ echo "No arguments supplied. Provide a project name."
+ return
+ else
+ sed "s/#projectname/\#\"$argv[1]\"/g" ~/todo/templates/Inspection_Plan_Template_For_todo.txt >> /home/lemon/todo/todo.todo
+ end
+end
diff --git a/fish/functions/backup-home.fish b/fish/functions/backup-home.fish
new file mode 100644
index 0000000..651d7f4
--- /dev/null
+++ b/fish/functions/backup-home.fish
@@ -0,0 +1,5 @@
+# Defined in /tmp/fish.38PNLg/backup-home.fish @ line 2
+function backup-home --description 'Backup /home/lemon and /etc to /home-backup/rsync/'
+ sudo rsync -avzhe --delete --progress /home/ /home-backup/rsync_home/ --exclude-from /home/lemon/.rsync_excludes.txt --delete-excluded
+ sudo rsync -avzhe --delete --progress /etc/ /home-backup/rsync_etc/
+end
diff --git a/fish/functions/bass.fish b/fish/functions/bass.fish
new file mode 120000
index 0000000..b639a8f
--- /dev/null
+++ b/fish/functions/bass.fish
@@ -0,0 +1 @@
+/home/lemon/.config/fisherman/bass/functions/bass.fish \ No newline at end of file
diff --git a/fish/functions/bobbins-mosh.fish b/fish/functions/bobbins-mosh.fish
new file mode 100644
index 0000000..c674f05
--- /dev/null
+++ b/fish/functions/bobbins-mosh.fish
@@ -0,0 +1,3 @@
+function bobbins-mosh
+ mosh --ssh="ssh -p 2222" lemon@46.101.17.241
+end
diff --git a/fish/functions/catnote.fish b/fish/functions/catnote.fish
new file mode 100644
index 0000000..0e35412
--- /dev/null
+++ b/fish/functions/catnote.fish
@@ -0,0 +1,3 @@
+function catnote --description 'cat a single file in Textnotes - must use completion!'
+ cat $argv[1]
+end
diff --git a/fish/functions/copy-to-markdown.fish b/fish/functions/copy-to-markdown.fish
new file mode 100644
index 0000000..aaa91e1
--- /dev/null
+++ b/fish/functions/copy-to-markdown.fish
@@ -0,0 +1,3 @@
+function copy-to-markdown --description 'Text copied from browser will be converted to Markdown and put back on clipboard'
+ xclip -o -selection clipboard -t text/html | pandoc -r html -w markdown | xclip -i -selection clipboard
+end
diff --git a/fish/functions/dmenu-notes.fish b/fish/functions/dmenu-notes.fish
new file mode 100644
index 0000000..d5a98ac
--- /dev/null
+++ b/fish/functions/dmenu-notes.fish
@@ -0,0 +1,4 @@
+function dmenu-notes -d 'Use dmenu to list ~/Nextcloud/Notes and show select in less'
+ set selection (find ~/Nextcloud/Notes -type f| sort| dmenu -i -l 20 -fn FiraMono:size=18)
+less $selection
+end
diff --git a/fish/functions/du.fish b/fish/functions/du.fish
new file mode 100644
index 0000000..1aec7cc
--- /dev/null
+++ b/fish/functions/du.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function du --description 'alias du=ncdu --color dark -rr -x --exclude .git'
+ ncdu --color dark -rr -x --exclude .git $argv;
+end
diff --git a/fish/functions/fish_prompt.fish b/fish/functions/fish_prompt.fish
new file mode 100644
index 0000000..57a3c21
--- /dev/null
+++ b/fish/functions/fish_prompt.fish
@@ -0,0 +1,13 @@
+# Defined in /tmp/fish.OarydH/fish_prompt.fish @ line 2
+function fish_prompt --description 'Write out the prompt'
+ if not set -q __fish_prompt_normal
+ set -g __fish_prompt_normal (set_color normal)
+ end
+
+ if not set -q __fish_prompt_cwd
+ set -g __fish_prompt_cwd (set_color $fish_color_cwd)
+ end
+
+ # echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal" ' ' (task +in +PENDING count) '> '
+ echo -n -s "$USER" @ (prompt_hostname) ' ' "$__fish_prompt_cwd" (prompt_pwd) (__fish_vcs_prompt) "$__fish_prompt_normal"'> '
+end
diff --git a/fish/functions/fish_user_key_bindings.fish b/fish/functions/fish_user_key_bindings.fish
new file mode 100644
index 0000000..ff61c90
--- /dev/null
+++ b/fish/functions/fish_user_key_bindings.fish
@@ -0,0 +1,2 @@
+
+fzf_key_bindings
diff --git a/fish/functions/fisher.fish b/fish/functions/fisher.fish
new file mode 100644
index 0000000..5dae6cc
--- /dev/null
+++ b/fish/functions/fisher.fish
@@ -0,0 +1,2536 @@
+if not set -q fisher_cmd_name
+ status --current-filename | command awk '
+ {
+ if (n = split($0, parts, "/")) {
+ gsub(/\.fish$/, "", parts[n])
+ print(parts[n])
+ }
+ }
+ ' | read -gx fisher_cmd_name
+end
+
+if test -z "$fisher_cmd_name"
+ set -gx fisher_cmd_name "fisher"
+end
+
+function $fisher_cmd_name -d "fish plugin manager"
+ switch "$FISH_VERSION"
+ case 2.1.2 2.1.1 2.1.0 2.0.0
+ echo "You need fish 2.2.0 or higher to use fisherman."
+
+ if type brew >/dev/null 2>&1
+ echo "Run: brew upgrade fish"
+ else
+ echo "
+ Refer to your package manager documentation for
+ instructions on how to upgrade your fish build.
+ "
+ end
+
+ return 1
+
+ case 2.2.0
+ __fisher_log info "
+ You need fish 2.3.0 or higher to take advantage of snippets.
+ Without it some plugins might not work.
+ "
+
+ if type -q brew
+ __fisher_log info "Please run &brew upgrade fish&"
+ else
+ __fisher_log info "
+
+ Refer to your package manager documentation
+ for instructions on how to upgrade your fish build.
+
+ If you can not upgrade, append the following code
+ to your ~/.config/fish/config.fish:
+
+ &for file in ~/.config/fish/conf.d/*.fish&
+ &source \$file&
+ &end&
+
+ "
+ end
+ end
+
+ set -g fisher_version "2.13.3"
+ set -g fisher_spinners â ‹ â ™ â ¹ â ¸ â ¼ â ´ â ¦ â § â ‡ â 
+
+ if [ -e /dev/stdout ]
+ set -g __fisher_stdout /dev/stdout
+ else if [ -e /proc/self/fd/1 ]
+ set -g __fisher_stdout /proc/self/fd/1
+ else
+ echo "No suitable stdout"
+ return 1
+ end
+
+ if [ -e /dev/stderr ]
+ set -g __fisher_stderr /dev/stderr
+ else if [ -e /proc/self/fd/2 ]
+ set -g __fisher_stderr /proc/self/fd/2
+ else
+ echo "No suitable stderr"
+ return 1
+ end
+
+ function __fisher_show_spinner
+ if not set -q __fisher_fg_spinner[1]
+ set -g __fisher_fg_spinner $fisher_spinners
+ end
+
+ printf " $__fisher_fg_spinner[1]\r" >&2
+
+ set -e __fisher_fg_spinner[1]
+ end
+
+ set -l config_home $XDG_CONFIG_HOME
+ set -l cache_home $XDG_CACHE_HOME
+
+ if test -z "$config_home"
+ set config_home ~/.config
+ end
+
+ if test -z "$cache_home"
+ set cache_home ~/.cache
+ end
+
+ if test -z "$fish_config"
+ set -g fish_config "$config_home/fish"
+ end
+
+ if test -z "$fisher_config"
+ set -g fisher_config "$config_home/fisherman"
+ end
+
+ if test -z "$fisher_cache"
+ set -g fisher_cache "$cache_home/fisherman"
+ end
+
+ if test -z "$fish_path"
+ set -g fish_path "$fish_config"
+ end
+
+ if test -z "$fisher_file"
+ set -g fisher_file "$fish_path/fishfile"
+ end
+
+ if test -z "$fisher_copy"
+ set -g fisher_copy false
+ end
+
+ switch "$argv[1]"
+ case --complete
+ __fisher_complete
+ return
+
+ case -v --version
+ __fisher_version
+ return
+
+ case -h
+ __fisher_usage >&2
+ return
+ end
+
+ command mkdir -p {"$fish_path","$fish_config"}/{conf.d,functions,completions} "$fisher_config" "$fisher_cache"
+ or return 1
+
+ set -l completions "$fish_path/completions/$fisher_cmd_name.fish"
+
+ if test ! -e "$completions"
+ echo "$fisher_cmd_name --complete" > "$completions"
+ __fisher_complete
+ end
+
+ for i in -q --quiet
+ if set -l index (builtin contains --index -- $i $argv)
+ set -e argv[$index]
+ set __fisher_stdout /dev/null
+ set __fisher_stderr /dev/null
+ break
+ end
+ end
+
+ set -l cmd
+
+ switch "$argv[1]"
+ case i install
+ set -e argv[1]
+
+ if test -z "$argv"
+ set cmd "default"
+ else
+ set cmd "install"
+ end
+
+ case u up update
+ set -e argv[1]
+ set cmd "update"
+
+ case r rm remove uninstall
+ set -e argv[1]
+ set cmd "rm"
+
+ case l ls list
+ set -e argv[1]
+ set cmd "ls"
+
+ case info ls-remote
+ set -e argv[1]
+ set cmd "ls-remote"
+
+ case h help
+ set -e argv[1]
+ __fisher_help $argv
+ return
+
+ case --help
+ set -e argv[1]
+ __fisher_help
+ return
+
+ case -- ""
+ set -e argv[1]
+
+ if test -z "$argv"
+ set cmd "default"
+ else
+ set cmd "install"
+ end
+
+ case self-{uninstall,destroy}
+ set -e argv[1]
+ __fisher_self_uninstall $argv
+ return
+
+ case -\*\?
+ printf "$fisher_cmd_name: '%s' is not a valid option\n" "$argv[1]" >&2
+ __fisher_usage >&2
+ return 1
+
+ case \*
+ set cmd "install"
+ end
+
+ set -l elapsed (__fisher_get_epoch_in_ms)
+ set -l items (
+ if test ! -z "$argv"
+ printf "%s\n" $argv | __fisher_read_bundle_file
+ end
+ )
+
+ if test -z "$items" -a "$cmd" = "default"
+ if isatty
+ command touch "$fisher_file"
+
+ set cmd "install"
+ set items (__fisher_read_bundle_file < "$fisher_file")
+
+ if test -z "$items"
+ __fisher_log info "
+ No plugins to install or dependencies missing.
+ " >&2
+
+ __fisher_log info "
+ See &$fisher_cmd_name help& for usage instructions.
+ " >&2
+ return
+ end
+ else
+ set cmd "install"
+ end
+ end
+
+ switch "$cmd"
+ case install update
+ if not command -s git > /dev/null
+ __fisher_log error "
+ git is required to download plugin repositories.
+ " >&2
+
+ __fisher_log info "
+ Please install git and try again.
+ Visit <&https://git-scm.com&> for more information.
+ " >&2
+
+ return 1
+ end
+
+ case ls ls-remote
+ if not command -s curl > /dev/null
+ __fisher_log error "
+ curl is required to query the GitHub API.
+ " >&2
+
+ __fisher_log info "
+ Please install curl and try again.
+ Refer to your package manager documentation for instructions.
+ " >&2
+
+ return 1
+ end
+ end
+
+ switch "$cmd"
+ case install
+ if __fisher_install $items
+ __fisher_log info "Done in &"(__fisher_get_epoch_in_ms $elapsed | __fisher_humanize_duration)"&" "$__fisher_stderr"
+ end
+
+ case update
+ if isatty
+ if test -z "$items"
+ set items (__fisher_list | command sed 's/^[@* ]*//')
+
+ if not __fisher_self_update
+ if test -z "$items"
+ __fisher_log info "Use your package manager to update fisherman."
+ return 1
+ end
+ end
+ end
+ else
+ __fisher_parse_column_output | __fisher_read_bundle_file | read -laz _items
+ set items $items $_items
+ end
+
+ __fisher_update $items
+
+ __fisher_log info "Done in &"(__fisher_get_epoch_in_ms $elapsed | __fisher_humanize_duration)"&" "$__fisher_stderr"
+
+ case ls
+ if test (count "$argv") -ge 0 -o "$argv" = -
+ if isatty stdout
+ __fisher_list | column -c$argv
+ else
+ __fisher_list | sed 's|^[@* ]*||'
+ end
+
+ else
+ __fisher_list_plugin_directory $argv
+ end
+
+ case ls-remote
+ set -l format
+
+ if test ! -z "$argv"
+ switch "$argv[1]"
+ case --format\*
+ set format (printf "%s\n" "$argv[1]" | command sed 's|^--[^= ]*[= ]\(.*\)|\1|')
+ set -e argv[1]
+ end
+
+ if test -z "$format"
+ set format "%info\n%url\n"
+ end
+ end
+
+ if test -z "$format"
+ set format "%name\n"
+
+ if isatty stdout
+ __fisher_list_remote "$format" $argv | column
+ else
+ __fisher_list_remote "$format" $argv
+ end
+ else
+ __fisher_list_remote "$format" $argv
+ end
+
+ case rm
+ if test -z "$items"
+ __fisher_parse_column_output | __fisher_read_bundle_file | read -az items
+ end
+
+ for i in $items
+ set -l name (__fisher_plugin_get_names $i)[1]
+
+ if test ! -d "$fisher_config/$name"
+ set -e items
+
+ if test -L "$fisher_config/$name"
+ set -l real_path (command readlink "$fisher_config/$name")
+
+ __fisher_log error "
+ I can't remove &$name& without its real path.
+ " "$__fisher_stderr"
+
+ __fisher_log info "
+ Restore &$real_path& and try again.
+ " "$__fisher_stderr"
+ else
+ __fisher_log error "Plugin &$name& is not installed." "$__fisher_stderr"
+ end
+
+ break
+ end
+ end
+
+ if test ! -z "$items"
+ __fisher_remove $items
+ __fisher_log info "Done in &"(
+ __fisher_get_epoch_in_ms $elapsed | __fisher_humanize_duration)"&" "$__fisher_stderr"
+ end
+ end
+
+ set -l config_glob $fisher_config/*
+ set -l config (
+ if test ! -z "$config_glob"
+ command find $config_glob -maxdepth 0 -type d | command sed "s|.*/||"
+ end
+ )
+
+ switch "$cmd"
+ case ls ls-remote
+ case \*
+ if test -z "$config"
+ echo > "$fisher_file"
+ set -e fisher_dependency_count
+ else
+ __fisher_plugin_get_url_info -- "$fisher_config"/$config > $fisher_file
+ end
+ end
+
+ complete -c $fisher_cmd_name --erase
+
+ __fisher_complete
+end
+
+
+function __fisher_install
+ if test -z "$argv"
+ __fisher_read_bundle_file | read -az argv
+ end
+
+ set -e __fisher_fetch_plugins_state
+
+ if set -l fetched (__fisher_plugin_fetch_items (__fisher_plugin_get_missing $argv))
+ if test -z "$fetched"
+ __fisher_log info "
+ No plugins to install or dependencies missing.
+ " "$__fisher_stderr"
+
+ return 1
+ end
+
+ for i in $fetched
+ __fisher_show_spinner
+
+ if test -f "$fisher_config/$i/fishfile"
+ while read -l i
+ set -l name (__fisher_plugin_get_names "$i")[1]
+
+ if contains -- "$name" $fetched
+ if contains -- "$name" $argv
+ __fisher_plugin_increment_ref_count "$name"
+ end
+ else
+ __fisher_plugin_increment_ref_count "$name"
+ end
+
+ end < "$fisher_config/$i/fishfile"
+ end
+
+ __fisher_show_spinner
+ __fisher_plugin_increment_ref_count "$i"
+
+ set -l path "$fisher_config/$i"
+
+ if __fisher_plugin_is_prompt "$path"
+ if test ! -z "$fisher_active_prompt"
+ __fisher_remove "$fisher_active_prompt"
+ end
+
+ set -U fisher_active_prompt "$i"
+ end
+
+ __fisher_plugin_enable "$path"
+ end
+ else
+ __fisher_log error "
+ There was an error installing &$fetched& or more plugin/s.
+ " "$__fisher_stderr"
+
+ __fisher_log info "
+ Try using a namespace before the plugin name: &owner&/$fetched
+ " "$__fisher_stderr"
+
+ return 1
+ end
+end
+
+
+function __fisher_plugin_fetch_items
+ __fisher_show_spinner
+
+ set -l jobs
+ set -l links
+ set -l white
+ set -l count (count $argv)
+
+ if test "$count" -eq 0
+ return
+ end
+
+ switch "$__fisher_fetch_plugins_state"
+ case ""
+ if test "$count" = 1 -a -d "$argv[1]"
+ if test "$argv[1]" = "$PWD"
+ set -l home ~
+ set -l name (printf "%s\n" "$argv[1]" | command sed "s|$home|~|")
+
+ __fisher_log info "Installing &$name& " "$__fisher_stderr"
+ else
+ set -l name (printf "%s\n" "$argv[1]" | command sed "s|$PWD/||")
+
+ __fisher_log info "Installing &$name& " "$__fisher_stderr"
+ end
+ else
+ __fisher_log info "Installing &$count& plugin/s" "$__fisher_stderr"
+ end
+
+ set -g __fisher_fetch_plugins_state "fetching"
+
+ case "fetching"
+ if test "$count" -eq 1
+ __fisher_log info "Installing &1& dependency" "$__fisher_stderr"
+ else
+ __fisher_log info "Installing &$count& dependencies" "$__fisher_stderr"
+ end
+
+ set -g __fisher_fetch_plugins_state "done"
+
+ case "done"
+ end
+
+ for i in $argv
+ set -l names
+ set -l branch
+
+ switch "$i"
+ case \*gist.github.com\*
+ __fisher_log okay "Resolving gist name."
+ if not set names (__fisher_get_plugin_name_from_gist "$i") ""
+ __fisher_log error "
+ I couldn't clone this gist:
+ &$i&
+ "
+ continue
+ end
+
+ case \*
+ printf "%s\n" "$i" | sed 's/[@:]\(.*\)/ \1/' | read i branch
+ set names (__fisher_plugin_get_names "$i")
+ end
+
+ if test -d "$i"
+ command ln -sf "$i" "$fisher_config/$names[1]"
+ set links $links "$names[1]"
+ continue
+ end
+
+ set -l src "$fisher_cache/$names[1]"
+
+ if test -z "$names[2]"
+ if test -d "$src" -a -z "$branch"
+ if test ! -d "$fisher_config/$names[1]"
+ __fisher_log okay "Copy &$names[1]&" "$__fisher_stderr"
+ end
+
+ if test -L "$src"
+ command ln -sf "$src" "$fisher_config"
+ else
+ command cp -Rf "$src" "$fisher_config"
+ end
+ else
+ set jobs $jobs (__fisher_plugin_url_clone_async "$i" "$names[1]" "$branch")
+ end
+ else
+ if test -d "$src" -a -z "$branch"
+ set -l real_namespace (__fisher_plugin_get_url_info --dirname "$src")
+
+ if test "$real_namespace" = "$names[2]"
+ if test ! -d "$fisher_config/$names[1]"
+ __fisher_log okay "Copy &$names[1]&" "$__fisher_stderr"
+ end
+
+ command cp -Rf "$src" "$fisher_config"
+ else
+ set jobs $jobs (__fisher_plugin_url_clone_async "$i" "$names[1]" "$branch")
+ end
+ else
+ set jobs $jobs (__fisher_plugin_url_clone_async "$i" "$names[1]" "$branch")
+ end
+ end
+
+ set fetched $fetched "$names[1]"
+ end
+
+ __fisher_jobs_await $jobs
+
+ for i in $fetched
+ if test ! -d "$fisher_cache/$i"
+ printf "%s\n" "$i"
+
+ for i in $fetched
+ if test -d "$fisher_config/$i"
+ command rm -rf "$fisher_config/$i"
+ end
+ end
+
+ return 1
+ end
+ end
+
+ if test ! -z "$fetched"
+ __fisher_plugin_fetch_items (__fisher_plugin_get_missing $fetched)
+ printf "%s\n" $fetched
+ end
+
+ if test ! -z "$links"
+ __fisher_plugin_fetch_items (__fisher_plugin_get_missing $links)
+ printf "%s\n" $links
+ end
+end
+
+
+function __fisher_plugin_url_clone_async -a url name branch
+ switch "$url"
+ case http://\* https://\*
+ case {gitlab.com,github.com,bitbucket.org}\*
+ set url "https://$url"
+
+ case \?\*/\?\*
+ set url "https://github.com/$url"
+
+ case \*
+ set url "https://github.com/fisherman/$url"
+ end
+
+ set -l nc (set_color normal)
+ set -l error (set_color $fish_color_error)
+ set -l okay (set_color $fish_color_match)
+ set -l hm_url (printf "%s\n" "$url" | command sed 's|^https://||')
+
+ if test ! -z "$branch"
+ set hm_url "$hm_url ($branch)"
+ set branch -b "$branch"
+ end
+
+ fish -c "
+ set -lx GIT_ASKPASS /bin/echo
+
+ if test -d '$fisher_cache/$name'
+ command rm -rf '$fisher_cache/$name'
+ end
+
+ if command git clone $branch -q --depth 1 '$url' '$fisher_cache/$name' 2> /dev/null
+ printf '$okay""OK""$nc Fetch $okay%s$nc %s\n' '$name' '$hm_url' > $__fisher_stderr
+ command cp -Rf '$fisher_cache/$name' '$fisher_config'
+ else
+ printf '$error""!""$nc Fetch $error%s$nc %s\n' '$name' '$hm_url' > $__fisher_stderr
+ end
+ " >&2
+
+ __fisher_jobs_get -l
+end
+
+
+function __fisher_update
+ set -l jobs
+ set -l count (count $argv)
+ set -l updated
+ set -l links 0
+
+ if test "$count" = 0
+ return
+ end
+
+ if test "$count" -eq 1
+ __fisher_log info "Updating &$count& plugin" "$__fisher_stderr"
+ else
+ __fisher_log info "Updating &$count& plugins" "$__fisher_stderr"
+ end
+
+ for i in $argv
+ set -l name (__fisher_plugin_get_names "$i")[1]
+ set -l path "$fisher_config/$name"
+
+ if test -d "$path"
+ set updated $updated "$name"
+
+ if test -L "$fisher_config/$name"
+ set links (math "$links + 1")
+ continue
+ end
+
+ set jobs $jobs (__fisher_update_path_async "$name" "$path")
+ else
+ __fisher_log error "Skipped &$name&"
+ end
+ end
+
+ __fisher_jobs_await $jobs
+
+ set -g __fisher_fetch_plugins_state "fetching"
+ set -l fetched (__fisher_plugin_fetch_items (__fisher_plugin_get_missing $updated))
+
+ for i in $updated $fetched
+ __fisher_plugin_enable "$fisher_config/$i"
+ end
+
+ if test "$links" -gt 0
+ __fisher_log info "Synced &$links& symlink/s" "$__fisher_stderr"
+ end
+end
+
+
+function __fisher_self_update
+ set -l file (status --current-filename)
+
+ if test "$file" != "$fish_path/functions/$fisher_cmd_name.fish"
+ return 1
+ end
+
+ set -l completions "$fish_path/completions/$fisher_cmd_name.fish"
+ set -l raw_url "https://raw.githubusercontent.com/fisherman/fisherman/master/fisher.fish"
+ set -l fake_qs (date "+%s")
+
+ set -l previous_version "$fisher_version"
+
+ fish -c "curl --max-time 5 -sS '$raw_url?$fake_qs' > $file.$fake_qs" &
+
+ __fisher_jobs_await (__fisher_jobs_get -l)
+
+ if test -s "$file.$fake_qs"
+ command mv "$file.$fake_qs" "$file"
+ end
+
+ builtin source "$file" 2> /dev/null
+
+ echo "$fisher_cmd_name -v" | source > /dev/null
+
+ set -l new_version "$fisher_version"
+
+ echo "$fisher_cmd_name --complete" > "$completions"
+ builtin source "$completions" 2> /dev/null
+
+ if test "$previous_version" = "$fisher_version"
+ __fisher_log okay "fisherman is up to date" "$__fisher_stderr"
+ else
+ __fisher_log okay "You are running fisherman &$fisher_version&" "$__fisher_stderr"
+ __fisher_log info "See github.com/fisherman/fisherman/releases" "$__fisher_stderr"
+ end
+end
+
+
+function __fisher_update_path_async -a name path
+ set -l nc (set_color normal)
+ set -l error (set_color $fish_color_match)
+ set -l okay (set_color $fish_color_match)
+
+ fish -c "
+
+ pushd $path
+
+ set -l branch (basename (command git symbolic-ref HEAD 2> /dev/null))
+ set -l hm_branch
+
+ if test -z \"\$branch\"
+ set branch master
+ end
+
+ if test \"\$branch\" != master
+ set hm_branch \" (\$branch)\"
+ end
+
+ if not command git fetch -q origin \$branch 2> /dev/null
+ printf '$error""!""$nc Fetch $error%s$nc\n' '$name' > $__fisher_stderr
+ exit
+ end
+
+ set -l commits (command git rev-list --left-right --count \$branch..FETCH_HEAD 2> /dev/null | cut -d\t -f2)
+
+ command git reset -q --hard FETCH_HEAD 2> /dev/null
+ command git clean -qdfx
+ command cp -Rf '$path/.' '$fisher_cache/$name'
+
+ if test -z \"\$commits\" -o \"\$commits\" -eq 0
+ printf '$okay""OK""$nc Latest $okay%s$nc%s\n' '$name' \$hm_branch > $__fisher_stderr
+ else
+ printf '$okay""OK""$nc Pulled $okay%s$nc new commit/s $okay%s$nc%s\n' \$commits '$name' \$hm_branch > $__fisher_stderr
+ end
+
+ " >&2 &
+
+ __fisher_jobs_get -l
+end
+
+
+function __fisher_plugin_enable -a path
+ set -l plugin_name (basename $path)
+
+ for file in $path/{functions/*,}*.fish
+ set -l base (basename "$file")
+
+ if test "$base" = "uninstall.fish"
+ continue
+ end
+
+ switch "$base"
+ case {,fish_{,user_}}key_bindings.fish
+ __fisher_key_bindings_remove "$plugin_name"
+ __fisher_key_bindings_append "$plugin_name" "$file"
+ continue
+ end
+
+ set -l dir "functions"
+
+ if test "$base" = "init.fish"
+ set dir "conf.d"
+
+ set base "$plugin_name.$base"
+ end
+
+ set -l target "$fish_path/$dir/$base"
+
+ if test -e "$target" -a ! -L "$target"
+ set -l backup_target "$fish_path/$dir/copy-$base"
+
+ __fisher_log info "Backup &$base&" "$__fisher_stderr"
+
+ command mv -f "$target" "$backup_target" 2> /dev/null
+ end
+
+ if test $fisher_copy = true
+ command cp -Rf "$file" "$target"
+ else
+ command ln -sf "$file" "$target"
+ end
+
+ builtin source "$target" 2> /dev/null
+
+ if test "$base" = "set_color_custom.fish"
+ if test ! -s "$fish_path/fish_colors"
+ __fisher_print_fish_colors > "$fish_path/fish_colors"
+ end
+
+ set_color_custom
+ end
+ end
+
+ for file in $path/{functions/,}*.{py,awk}
+ set -l base (basename "$file")
+ if test $fisher_copy = true
+ command cp -Rf "$file" "$fish_path/functions/$base"
+ else
+ command ln -sf "$file" "$fish_path/functions/$base"
+ end
+ end
+
+ for file in $path/conf.d/*.{py,awk}
+ set -l base (basename "$file")
+ if test $fisher_copy = true
+ command cp -Rf "$file" "$fish_path/conf.d/$base"
+ else
+ command ln -sf "$file" "$fish_path/conf.d/$base"
+ end
+ end
+
+ for file in $path/conf.d/*.fish
+ set -l base (basename "$file")
+ set -l target "$fish_path/conf.d/$base"
+
+ if test $fisher_copy = true
+ command cp -Rf "$file" "$target"
+ else
+ command ln -sf "$file" "$target"
+ end
+ builtin source "$target" 2> /dev/null
+ end
+
+ for file in $path/completions/*.fish
+ set -l base (basename "$file")
+ set -l target "$fish_path/completions/$base"
+
+ if test $fisher_copy = true
+ command cp -Rf "$file" "$target"
+ else
+ command ln -sf "$file" "$target"
+ end
+ builtin source "$target" 2> /dev/null
+ end
+
+ return 0
+end
+
+
+function __fisher_plugin_disable -a path
+ set -l plugin_name (basename $path)
+
+ for i in "$path/functions/uninstall.fish" "$path/uninstall.fish"
+ if test -s "$i"
+ builtin source "$i" 2> /dev/null
+ break
+ end
+ end
+
+ for file in $path/{functions/*,}*.fish
+ set -l name (basename "$file" .fish)
+ set -l base "$name.fish"
+
+ if test "$base" = "uninstall.fish"
+ continue
+ end
+
+ switch "$base"
+ case {,fish_}key_bindings.fish
+ __fisher_key_bindings_remove "$plugin_name"
+ continue
+ end
+
+ set -l dir "functions"
+
+ if test "$base" = "init.fish"
+ set dir "conf.d"
+ set base "$plugin_name.$base"
+ end
+
+ set -l target "$fish_path/$dir/$base"
+
+ command rm -f "$target"
+
+ functions -e "$name"
+
+ set -l backup_source "$fish_path/$dir/copy-$base"
+
+ if test -e "$backup_source"
+ command mv "$backup_source" "$target"
+ builtin source "$target" 2> /dev/null
+ end
+
+ if test "$base" = "set_color_custom.fish"
+ set -l fish_colors_config "$fish_path/fish_colors"
+
+ if test ! -f "$fish_colors_config"
+ __fisher_reset_default_fish_colors
+ continue
+ end
+
+ __fisher_restore_fish_colors < $fish_colors_config | builtin source 2> /dev/null
+
+ command rm -f $fish_colors_config
+ end
+ end
+
+ for file in $path/conf.d/*.{py,awk}
+ set -l base (basename "$file")
+ command rm -f "$fish_path/conf.d/$base"
+ end
+
+ for file in $path/{functions/,}*.{py,awk}
+ set -l base (basename "$file")
+ command rm -f "$fish_path/functions/$base"
+ end
+
+ for file in $path/conf.d/*.fish
+ set -l base (basename "$file")
+ command rm -f "$fish_path/conf.d/$base"
+ end
+
+ for file in $path/completions/*.fish
+ set -l name (basename "$file" .fish)
+ set -l base "$name.fish"
+
+ command rm -f "$fish_path/completions/$base"
+ complete -c "$name" --erase
+ end
+
+ if __fisher_plugin_is_prompt "$path"
+ set -U fisher_active_prompt
+ builtin source $__fish_datadir/functions/fish_prompt.fish 2> /dev/null
+ end
+
+ command rm -rf "$path" >&2
+end
+
+
+function __fisher_remove
+ if test -z "$argv"
+ return 1
+ end
+
+ set -l orphans
+ set -l removed
+
+ for i in $argv
+ set -l name (__fisher_plugin_get_names "$i")[1]
+
+ if test ! -d "$fisher_config/$name"
+ continue
+ end
+
+ set removed $removed $name
+
+ __fisher_show_spinner
+ __fisher_plugin_decrement_ref_count "$name"
+
+ if test -s "$fisher_config/$name/fishfile"
+ while read -l i
+ set -l name (__fisher_plugin_get_names "$i")[1]
+
+ if test (__fisher_plugin_get_ref_count "$name") -le 1
+ set orphans $orphans "$name"
+ else
+ __fisher_plugin_decrement_ref_count "$name"
+ end
+
+ __fisher_show_spinner
+ end < "$fisher_config/$name/fishfile"
+ end
+
+ __fisher_plugin_disable "$fisher_config/$name"
+
+ __fisher_show_spinner
+ end
+
+ for i in $orphans
+ __fisher_remove "$i" >&2
+ end
+end
+
+
+function __fisher_get_plugin_name_from_gist -a url
+ set -l gist_id (printf "%s\n" "$url" | command sed 's|.*/||')
+ set -l name (fish -c "
+
+ $fisher_cmd_name -v > /dev/null
+ curl -Ss https://api.github.com/gists/$gist_id &
+
+ __fisher_jobs_await (__fisher_jobs_get -l)
+
+ " | command awk '
+
+ /"files": / {
+ files++
+ }
+
+ /"[^ ]+.fish": / && files {
+ gsub("^ *\"|\.fish.*", "")
+ print
+ }
+
+ ')
+
+ if test -z "$name"
+ return 1
+ end
+
+ printf "%s\n" $name
+end
+
+
+function __fisher_remote_parse_header
+ command awk '
+
+ function get_page_count(s, rstart, rlength, pages) {
+ if (split(substr(s, rstart, rlength), pages, "=")) {
+ return pages[2]
+ }
+ }
+
+ BEGIN {
+ FS = " <|>; |, <"
+ }
+
+ /^Link: / {
+ if (match($2, "&page=[0-9]*")) {
+ url = substr($2, 1, RSTART - 1)
+ page_next = get_page_count($2, RSTART, RLENGTH)
+
+ if (page_next) {
+ page_last = get_page_count($4, RSTART, RLENGTH)
+
+ printf("%s\n%s\n%s", url, page_next, page_last)
+ }
+ }
+ }
+
+ '
+end
+
+
+function __fisher_remote_index_update
+ set -l index "$fisher_cache/.index"
+ set -l interval 3240
+ set -l players "fisherman" "oh-my-fish"
+
+ if test ! -z "$fisher_index_update_interval"
+ set interval "$fisher_index_update_interval"
+ end
+
+ if test -s "$index"
+ if set -l file_age (__fisher_get_file_age "$index")
+ if test "$file_age" -lt "$interval"
+ return
+ end
+ end
+ end
+
+ for i in $players
+ curl -u$GITHUB_USER:$GITHUB_TOKEN -Is "https://api.github.com/orgs/$i/repos?per_page=100" > "$index-header-$i" &
+ end
+
+ __fisher_jobs_await (__fisher_jobs_get -l)
+
+ for i in $players
+ set -l url "https://api.github.com/orgs/$i/repos?per_page=100"
+ set -l next 0
+ set -l last 0
+ set -l data
+
+ if test -s "$index-header-$i"
+ __fisher_remote_parse_header < "$index-header-$i" | read -az data
+ command rm -f "$index-header-$i"
+ end
+
+ if set -q data[3]
+ set -l url "$data[1]"
+ set -l next "$data[2]"
+ set -l last "$data[3]"
+ end
+
+ for page in "" (seq "$next" "$last")
+ if test "$page" = 0
+ continue
+ end
+
+ set -l next_url "$url"
+
+ if test ! -z "$page"
+ set next_url "$url&page=$page"
+ end
+
+ curl -u$GITHUB_USER:$GITHUB_TOKEN --max-time 10 -s "$next_url" | command awk -v ORS='' '
+
+ {
+ gsub(/[{}[]]/, "")
+
+ } //
+
+ ' | command awk '
+
+ {
+ n = split($0, a, /,[\t ]*"/)
+
+ for (i = 1; i <= n; i++) {
+ gsub(/"/, "", a[i])
+ print(a[i])
+ }
+ }
+
+ ' > "$index-$i-$page" &
+ end
+ end
+
+ __fisher_jobs_await (__fisher_jobs_get -l)
+
+ for i in $players
+ command cat "$index-$i-"*
+ end > "$index"
+
+ command rm "$index"-*
+
+ if test ! -s "$index"
+ return 1
+ end
+
+ command awk '
+
+ function quicksort(list, lo, hi, pivot, j, i, t) {
+ pivot = j = i = t
+
+ if (lo >= hi) {
+ return
+ }
+
+ pivot = lo
+ i = lo
+ j = hi
+
+ while (i < j) {
+ while (list[i] <= list[pivot] && i < hi) {
+ i++
+ }
+
+ while (list[j] > list[pivot]) {
+ j--
+ }
+
+ if (i < j) {
+ t = list[i]
+ list[i] = list[j]
+ list[j] = t
+ }
+ }
+
+ t = list[pivot]
+
+ list[pivot] = list[j]
+ list[j] = t
+
+ quicksort(list, lo, j - 1)
+ quicksort(list, j + 1, hi)
+ }
+
+ function reset_vars() {
+ name = info = stars = url = ""
+ }
+
+ {
+ if (match($0, /^name:[[:blank:]]*/)) {
+ name = substr($0, RLENGTH+1)
+ }
+
+ if (match($0, /^description:[[:blank:]]*/)) {
+ info = substr($0, RLENGTH+1)
+ }
+
+ if (match($0, /^stargazers_count:[[:blank:]]*/)) {
+ stars = substr($0, RLENGTH+1)
+ }
+
+ if (name != "" && stars != "") {
+ if (name ~ /oh-my-fish/) {
+ reset_vars()
+ next
+ }
+
+ url = "github.com/fisherman/" name
+
+ if (name ~ /^(plugin|theme)-/) {
+ gsub(/^plugin-/, "", name)
+
+ if (seen_names[name]) {
+ reset_vars()
+ next
+ }
+
+ url = "github.com/oh-my-fish/" name
+ name = "omf/" name
+
+ } else {
+ seen_names[name]++
+ }
+
+ if (info == "" || info == "null") {
+ info = url
+ }
+
+ if (info ~ /\.$/) {
+ info = substr(info, 1, length(info) - 1)
+ }
+
+ records[++record_count] = name "\t" info "\t" url "\t" stars
+ reset_vars()
+ }
+ }
+
+ END {
+ quicksort(records, 1, record_count)
+
+ for (i = 1; i <= record_count; i++) {
+ print(records[i])
+ }
+ }
+
+ ' < "$index" > "$index-tab"
+
+ if test ! -s "$index-tab"
+ command rm "$index"
+ return 1
+ end
+
+ command mv -f "$index-tab" "$index"
+end
+
+
+function __fisher_list_remote -a format
+ set -l index "$fisher_cache/.index"
+
+ if not __fisher_remote_index_update
+ __fisher_log error "I could not update the remote index."
+ __fisher_log info "
+
+ This is most likely a problem with http://api.github.com/
+ or a connection timeout. If the problem persists, open an
+ issue in: <github.com/fisherman/fisherman/issues>
+ "
+
+ return 1
+ end
+
+ set -e argv[1]
+ set -l keys $argv
+
+ command awk -v FS=\t -v format_s="$format" -v keys="$keys" '
+
+ function basename(s, n, a) {
+ n = split(s, a, "/")
+ return a[n]
+ }
+
+ function record_printf(fmt, name, info, url, stars) {
+ gsub(/%name/, name, fmt)
+ gsub(/%stars/, stars, fmt)
+ gsub(/%url/, url, fmt)
+ gsub(/%info/, info, fmt)
+
+ printf("%s", fmt)
+ }
+
+ BEGIN {
+ keys_n = split(keys, keys_a, " ")
+ }
+
+ {
+ if (keys_n > 0) {
+ for (i = 1; i <= keys_n; i++) {
+ if (keys_a[i] == $1) {
+ record_printf(format_s, $1, $2, $3, $4)
+ next
+ }
+ }
+ } else if ($1 !~ /^fisherman/) {
+ record_printf(format_s, $1, $2, $3, $4)
+ }
+ }
+
+ ' < "$index"
+end
+
+
+function __fisher_list
+ set -l config "$fisher_config"/*
+
+ if test -z "$config"
+ return 1
+ end
+
+ set -l white
+ set -l links (command find $config -maxdepth 0 -type l ! -name "$fisher_active_prompt" 2> /dev/null)
+ set -l names (command find $config -maxdepth 0 -type d ! -name "$fisher_active_prompt" 2> /dev/null)
+
+ if test ! -z "$links"
+ set white " "
+ printf "%s\n" $links | command sed "s|.*/|@ |"
+ end
+
+ if test ! -z "$fisher_active_prompt"
+ set white " "
+ printf "* %s\n" "$fisher_active_prompt"
+ end
+
+ if test ! -z "$names"
+ printf "%s\n" $names | command sed "s|.*/|$white|"
+ end
+end
+
+
+function __fisher_list_plugin_directory
+ if test -z "$argv"
+ return 1
+ end
+
+ for i in $argv
+ if test ! -d "$fisher_config/$i"
+ __fisher_log error "You can only list plugins you've installed." "$__fisher_stderr"
+
+ return 1
+ end
+ end
+
+ set -l fd "$__fisher_stderr"
+ set -l uniq_items
+
+ for i in $argv
+ if contains -- "$i" $uniq_items
+ continue
+ end
+
+ set uniq_items $uniq_items "$i"
+ set -l path "$fisher_config/$i"
+
+ pushd "$path"
+
+ set -l color (set_color $fish_color_command)
+ set -l nc (set_color normal)
+ set -l previous_tree
+
+ if contains -- --no-color $argv
+ set color
+ set nc
+ set fd "$__fisher_stdout"
+ end
+
+ printf "$color%s$nc\n" "$PWD" > $fd
+
+ for file in .* **
+ if test -f "$file"
+ switch "$file"
+ case \*/\*
+ set -l current_tree (dirname $file)
+
+ if test "$previous_tree" != "$current_tree"
+ printf " $color%s/$nc\n" $current_tree
+ end
+
+ printf " %s\n" (basename $file)
+
+ set previous_tree $current_tree
+
+ case \*
+ printf " %s\n" $file
+ end
+ end
+ end > $fd
+
+ popd
+ end
+end
+
+
+function __fisher_log -a log message fd
+ if test -z "$argv"
+ return
+ end
+
+ switch "$fd"
+ case "/dev/null"
+ return
+
+ case "" "/dev/stderr"
+ set fd $__fisher_stderr
+
+ case \*
+ set nc ""
+ set okay ""
+ set info ""
+ set error ""
+ end
+
+ set -l nc (set_color normal)
+ set -l okay (set_color $fish_color_match)
+ set -l info (set_color $fish_color_match)
+ set -l error (set_color $fish_color_error)
+
+ printf "%s\n" "$message" | command awk '
+ function okay(s) {
+ printf("'"$okay"'%s'"$nc"' %s\n", "OK", s)
+ }
+
+ function info(s) {
+ printf("%s\n", s)
+ }
+
+ function error(s) {
+ printf("'"$error"'%s'"$nc"' %s\n", "!", s)
+ }
+
+ {
+ sub(/^[ ]+/, "")
+ gsub("``", " ")
+
+ if (/&[^&]+&/) {
+ n = match($0, /&[^&]+&/)
+ if (n) {
+ sub(/&[^&]+&/, "'"$$log"'" substr($0, RSTART + 1, RLENGTH - 2) "'"$nc"'", $0)
+ }
+ }
+
+ s[++len] = $0
+ }
+
+ END {
+ for (i = 1; i <= len; i++) {
+ if ((i == 1 || i == len) && (s[i] == "")) {
+ continue
+ }
+
+ if (s[i] == "") {
+ print
+ } else {
+ '"$log"'(s[i])
+ }
+ }
+ }
+
+ ' > "$fd"
+end
+
+
+function __fisher_jobs_get
+ jobs $argv | command awk -v FS=\t '
+ /[0-9]+\t/{
+ jobs[++job_count] = $1
+ }
+
+ END {
+ for (i = 1; i <= job_count; i++) {
+ print(jobs[i])
+ }
+
+ exit job_count == 0
+ }
+ '
+end
+
+
+function __fisher_jobs_await
+ if test -z "$argv"
+ return
+ end
+
+ while true
+ for spinner in $fisher_spinners
+ printf " $spinner \r" >&2
+ sleep 0.05
+ end
+
+ set -l currently_active_jobs (__fisher_jobs_get)
+
+ if test -z "$currently_active_jobs"
+ break
+ end
+
+ set -l has_jobs
+
+ for i in $argv
+ if builtin contains -- $i $currently_active_jobs
+ set has_jobs "*"
+ break
+ end
+ end
+
+ if test -z "$has_jobs"
+ break
+ end
+ end
+end
+
+
+function __fisher_key_bindings_remove -a plugin_name
+ set -l user_key_bindings "$fish_path/functions/fish_user_key_bindings.fish"
+
+ if test ! -f "$user_key_bindings"
+ return
+ end
+
+ set -l tmp (date "+%s")
+
+ fish_indent < "$user_key_bindings" | command sed -n "/### $plugin_name ###/,/### $plugin_name ###/{s/^ *bind /bind -e /p;};" | builtin source 2> /dev/null
+
+ command sed "/### $plugin_name ###/,/### $plugin_name ###/d" < "$user_key_bindings" > "$user_key_bindings.$tmp"
+ command mv -f "$user_key_bindings.$tmp" "$user_key_bindings"
+
+ if command awk '
+ /^$/ { next }
+
+ /^function fish_user_key_bindings/ {
+ i++
+ next
+ }
+
+ /^end$/ && 1 == i {
+ exit 0
+ }
+
+ // {
+ exit 1
+ }
+
+ ' < "$user_key_bindings"
+
+ command rm -f "$user_key_bindings"
+ end
+end
+
+
+function __fisher_key_bindings_append -a plugin_name file
+ set -l user_key_bindings "$fish_path/functions/fish_user_key_bindings.fish"
+
+ command mkdir -p (dirname "$user_key_bindings")
+ command touch "$user_key_bindings"
+
+ set -l key_bindings_source (
+ fish_indent < "$user_key_bindings" | command awk '
+
+ /^function fish_user_key_bindings/ {
+ reading_function_source = 1
+ next
+ }
+
+ /^end$/ && reading_function_source {
+ exit
+ }
+
+ reading_function_source {
+ print($0)
+ next
+ }
+
+ '
+ )
+
+ set -l plugin_key_bindings_source (
+ fish_indent < "$file" | command awk -v name="$plugin_name" '
+
+ BEGIN {
+ printf("### %s ###\n", name)
+ }
+
+ END {
+ printf("### %s ###\n", name)
+ }
+
+ /^function (fish_(user_)?)?key_bindings$/ {
+ is_end = 1
+ next
+ }
+
+ /^end$/ && is_end {
+ end = 0
+ next
+ }
+
+ !/^ *(#.*)*$/ {
+ gsub("#.*", "")
+ printf("%s\n", $0)
+ }
+
+ '
+ )
+
+ printf "%s\n" $plugin_key_bindings_source | source 2> /dev/null
+
+ fish_indent < "$user_key_bindings" | command awk '
+ {
+
+ if ($0 ~ /^function fish_user_key_bindings/) {
+ reading_function_source = 1
+ next
+ } else if ($0 ~ /^end$/ && reading_function_source) {
+ reading_function_source = 0
+ next
+ }
+
+ if (!reading_function_source) {
+ print($0)
+ }
+ }
+
+ ' > "$user_key_bindings-copy"
+
+ command mv -f "$user_key_bindings-copy" "$user_key_bindings"
+
+ printf "%s\n" $key_bindings_source $plugin_key_bindings_source | command awk '
+
+ BEGIN {
+ print "function fish_user_key_bindings"
+ }
+
+ //
+
+ END {
+ print "end"
+ }
+
+ ' | fish_indent >> "$user_key_bindings"
+end
+
+
+function __fisher_plugin_is_prompt -a path
+ for file in "$path"/{,functions/}{fish_prompt,fish_right_prompt}.fish
+ if test -e "$file"
+ return
+ end
+ end
+
+ return 1
+end
+
+
+function __fisher_plugin_get_names
+ printf "%s\n" $argv | command awk '
+
+ {
+ sub(/\/$/, "")
+ n = split($0, s, "/")
+ sub(/^(omf|omf-theme|omf-plugin|plugin|theme|fish|fisher|fish-plugin|fish-theme)-/, "", s[n])
+
+ printf("%s\n%s\n", s[n], s[n - 1])
+ }
+
+ '
+end
+
+
+function __fisher_plugin_get_url_info -a option
+ set -e argv[1]
+
+ if test -z "$argv"
+ return
+ end
+
+ for dir in $argv
+ git -C $dir config remote.origin.url 2> /dev/null | command awk -v option="$option" '
+ {
+ n = split($0, s, "/")
+
+ if ($0 ~ /https:\/\/gist/) {
+ printf("# %s\n", $0)
+ next
+ }
+
+ if (option == "--dirname") {
+ printf("%s\n", s[n - 1])
+
+ } else if (option == "--basename") {
+ printf("%s\n", s[n])
+
+ } else {
+ printf("%s/%s\n", s[n - 1], s[n])
+ }
+ }
+ '
+ end
+end
+
+
+function __fisher_plugin_normalize_path
+ printf "%s\n" $argv | command awk -v pwd="$PWD" '
+
+ /^\.$/ {
+ print(pwd)
+ next
+ }
+
+ /^\// {
+ sub(/\/$/, "")
+ print($0)
+ next
+ }
+
+ {
+ print(pwd "/" $0)
+ next
+ }
+
+ '
+end
+
+
+function __fisher_plugin_get_missing
+ for i in $argv
+ if test -d "$i"
+ set i (__fisher_plugin_normalize_path "$i")
+ end
+
+ set -l name (__fisher_plugin_get_names "$i")[1]
+
+ if test "$name" = fisherman
+
+ __fisher_log info "
+ Run &$fisher_cmd_name update& to update fisherman.
+ " >&2
+ continue
+ end
+
+ if set -l path (__fisher_plugin_is_installed "$name")
+ for file in fishfile bundle
+ if test -s "$path/$file"
+ __fisher_plugin_get_missing (__fisher_read_bundle_file < "$path/$file")
+ end
+ end
+ else
+ printf "%s\n" "$i"
+ end
+ end
+
+ __fisher_show_spinner
+end
+
+
+function __fisher_plugin_is_installed -a name
+ if test -z "$name" -o ! -d "$fisher_config/$name"
+ return 1
+ end
+
+ printf "%s\n" "$fisher_config/$name"
+end
+
+
+function __fisher_print_fish_colors
+ printf "%s\n" "$fish_color_normal" "$fish_color_command" "$fish_color_param" "$fish_color_redirection" "$fish_color_comment" "$fish_color_error" "$fish_color_escape" "$fish_color_operator" "$fish_color_end" "$fish_color_quote" "$fish_color_autosuggestion" "$fish_color_user" "$fish_color_valid_path" "$fish_color_cwd" "$fish_color_cwd_root" "$fish_color_match" "$fish_color_search_match" "$fish_color_selection" "$fish_pager_color_prefix" "$fish_pager_color_completion" "$fish_pager_color_description" "$fish_pager_color_progress" "$fish_color_history_current" "$fish_color_host"
+end
+
+
+function __fisher_restore_fish_colors
+ command awk '
+ {
+ if ($0 == "") {
+ set_option "-e"
+ } else {
+ set_option "-U"
+ }
+ }
+
+ NR == 1 {
+ print("set " set_option " fish_color_normal " $0)
+ }
+ NR == 2 {
+ print("set " set_option " fish_color_command " $0)
+ }
+ NR == 3 {
+ print("set " set_option " fish_color_param " $0)
+ }
+ NR == 4 {
+ print("set " set_option " fish_color_redirection " $0)
+ }
+ NR == 5 {
+ print("set " set_option " fish_color_comment " $0)
+ }
+ NR == 6 {
+ print("set " set_option " fish_color_error " $0)
+ }
+ NR == 7 {
+ print("set " set_option " fish_color_escape " $0)
+ }
+ NR == 8 {
+ print("set " set_option " fish_color_operator " $0)
+ }
+ NR == 9 {
+ print("set " set_option " fish_color_end " $0)
+ }
+ NR == 10 {
+ print("set " set_option " fish_color_quote " $0)
+ }
+ NR == 11 {
+ print("set " set_option " fish_color_autosuggestion " $0)
+ }
+ NR == 12 {
+ print("set " set_option " fish_color_user " $0)
+ }
+ NR == 13 {
+ print("set " set_option " fish_color_valid_path " $0)
+ }
+ NR == 14 {
+ print("set " set_option " fish_color_cwd " $0)
+ }
+ NR == 15 {
+ print("set " set_option " fish_color_cwd_root " $0)
+ }
+ NR == 16 {
+ print("set " set_option " fish_color_match " $0)
+ }
+ NR == 17 {
+ print("set " set_option " fish_color_search_match " $0)
+ }
+ NR == 18 {
+ print("set " set_option " fish_color_selection " $0)
+ }
+ NR == 19 {
+ print("set " set_option " fish_pager_color_prefix " $0)
+ }
+ NR == 20 {
+ print("set " set_option " fish_pager_color_completion " $0)
+ }
+ NR == 21 {
+ print("set " set_option " fish_pager_color_description " $0)
+ }
+ NR == 22 {
+ print("set " set_option " fish_pager_color_progress " $0)
+ }
+ NR == 23 {
+ print("set " set_option " fish_color_history_current " $0)
+ }
+ NR == 24 {
+ print("set " set_option " fish_color_host " $0)
+ }
+
+ '
+end
+
+
+function __fisher_reset_default_fish_colors
+ set -U fish_color_normal normal
+ set -U fish_color_command 005fd7 purple
+ set -U fish_color_param 00afff cyan
+ set -U fish_color_redirection 005fd7
+ set -U fish_color_comment 600
+ set -U fish_color_error red --bold
+ set -U fish_color_escape cyan
+ set -U fish_color_operator cyan
+ set -U fish_color_end green
+ set -U fish_color_quote brown
+ set -U fish_color_autosuggestion 555 yellow
+ set -U fish_color_user green
+ set -U fish_color_valid_path --underline
+ set -U fish_color_cwd green
+ set -U fish_color_cwd_root red
+ set -U fish_color_match cyan
+ set -U fish_color_search_match --background=purple
+ set -U fish_color_selection --background=purple
+ set -U fish_pager_color_prefix cyan
+ set -U fish_pager_color_completion normal
+ set -U fish_pager_color_description 555 yellow
+ set -U fish_pager_color_progress cyan
+ set -U fish_color_history_current cyan
+ set -U fish_color_host normal
+end
+
+
+function __fisher_read_bundle_file
+ command awk -v FS=\t '
+ /^$/ || /^[ \t]*#/ || /^(--|-).*/ {
+ next
+ }
+
+ /^omf\// {
+ sub(/^omf\//, "oh-my-fish/")
+
+ if ($0 !~ /(theme|plugin)-/) {
+ sub(/^oh-my-fish\//, "oh-my-fish/plugin-")
+ }
+ }
+
+ /^[ \t]*package / {
+ sub("^[ \t]*package ", "oh-my-fish/plugin-")
+ }
+
+ {
+ sub(/\.git$/, "")
+ sub("^[@* \t]*", "")
+
+ if (!dedupe[$0]++) {
+ printf("%s\n", $0)
+ }
+ }
+ '
+end
+
+
+function __fisher_plugin_increment_ref_count -a name
+ set -U fisher_dependency_count $fisher_dependency_count $name
+end
+
+
+function __fisher_plugin_decrement_ref_count -a name
+ if set -l i (contains --index -- "$name" $fisher_dependency_count)
+ set -e fisher_dependency_count[$i]
+ end
+end
+
+
+function __fisher_plugin_get_ref_count -a name
+ printf "%s\n" $fisher_dependency_count | command awk -v plugin="$name" '
+
+ BEGIN {
+ i = 0
+ }
+
+ $0 == plugin {
+ i++
+ }
+
+ END {
+ print(i)
+ }
+
+ '
+end
+
+
+function __fisher_complete
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -a install -d "Install plugins"
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -a update -d "Update plugins and self"
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -a rm -d "Remove plugins"
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -a ls -d "List what you've installed"
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -a ls-remote -d "List everything that's available"
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -a help -d "Show help"
+
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -s h -l help -d "Show usage help"
+ complete -xc $fisher_cmd_name -n "__fish_use_subcommand" -s v -l version -d "Show version information"
+ complete -xc $fisher_cmd_name -s q -l quiet -d "Enable quiet mode"
+
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from ls-remote" -l "format" -d "Format with verbs: %name, %url, %info and %stars"
+
+ set -l config_glob "$fisher_config"/*
+ set -l config (printf "%s\n" $config_glob | command sed "s|.*/||")
+
+ if test ! -s "$fisher_cache/.index"
+ if test ! -z "$config"
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from l ls list u up update r rm remove h help" -a "$config"
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from l ls list u up update r rm remove h help" -a "$fisher_active_prompt" -d "Prompt"
+ end
+ return
+ end
+
+ set -l real_home ~
+
+ for name in (command find $config_glob -maxdepth 0 -type l 2> /dev/null)
+ set -l path (command readlink "$name")
+ set -l name (command basename "$name" | sed "s|$real_home|~|")
+
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from l ls list u up update r rm remove h help" -a "$name" -d "$path"
+ end
+
+ set -l IFS \t
+
+ command awk -v FS=\t -v OFS=\t '
+
+ {
+ print($1, $2)
+ }
+
+ ' "$fisher_cache/.index" 2> /dev/null | while read -l name info
+
+ switch "$name"
+ case fisherman\*
+ continue
+ end
+
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from info ls-remote" -a "$name" -d "$info"
+
+ if contains -- "$name" $config
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from l ls list u up update r rm remove h help" -a "$name" -d "$info"
+ else
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from i in install" -a "$name" -d "$info"
+ end
+ end
+
+ if functions -q __fisher_plugin_get_url_info
+ for i in (__fisher_plugin_get_url_info -- $config_glob)
+ switch "$i"
+ case fisherman\*
+ case \*
+ set -l name (__fisher_plugin_get_names "$i")[1]
+ complete -xc $fisher_cmd_name -n "__fish_seen_subcommand_from l ls list u up update r rm remove h help" -a "$name" -d "$i"
+ end
+ end
+ end
+end
+
+
+function __fisher_humanize_duration
+ command awk '
+ function hmTime(time, stamp) {
+ split("h:m:s:ms", units, ":")
+
+ for (i = 2; i >= -1; i--) {
+ if (t = int( i < 0 ? time % 1000 : time / (60 ^ i * 1000) % 60 )) {
+ stamp = stamp t units[sqrt((i - 2) ^ 2) + 1] " "
+ }
+ }
+
+ if (stamp ~ /^ *$/) {
+ return "0ms"
+ }
+
+ return substr(stamp, 1, length(stamp) - 1)
+ }
+
+ {
+ print hmTime($0)
+ }
+ '
+end
+
+function __fisher_get_key
+ stty -icanon -echo 2> /dev/null
+ printf "$argv" >&2
+ while true
+ dd bs=1 count=1 2> /dev/null | read -p "" -l yn
+ switch "$yn"
+ case y Y n N
+ printf "\n" >&2
+ printf "%s\n" $yn > /dev/stdout
+ break
+ end
+ end
+ stty icanon echo > /dev/stderr 2> /dev/null
+end
+
+
+switch (command uname)
+ case Darwin FreeBSD
+ function __fisher_get_epoch_in_ms -a elapsed
+ if test -z "$elapsed"
+ set elapsed 0
+ end
+
+ if command -s perl > /dev/null
+ perl -MTime::HiRes -e 'printf("%.0f\n", (Time::HiRes::time() * 1000) - '$elapsed')'
+ else
+ math (command date "+%s") - $elapsed
+ end
+ end
+
+ case \*
+ function __fisher_get_epoch_in_ms -a elapsed
+ if test -z "$elapsed"
+ set elapsed 0
+ end
+ math (command date "+%s%3N") - $elapsed
+ end
+end
+
+
+function __fisher_parse_column_output
+ command awk -v FS=\t '
+ {
+ for (i = 1; i <= NF; i++) {
+ if ($i != "") {
+ print $i
+ }
+ }
+ }
+ '
+end
+
+
+function __fisher_get_file_age -a file
+ if type -q perl
+ perl -e "printf(\"%s\n\", time - (stat ('$file'))[9])" 2> /dev/null
+
+ else if type -q python
+ python -c "from __future__ import print_function; import os, time; print(int(time.time() - os.path.getmtime('$file')))" 2> /dev/null
+ end
+end
+
+
+function __fisher_usage
+ set -l u (set_color -u)
+ set -l nc (set_color normal)
+
+ echo "Usage: $fisher_cmd_name [COMMAND] [PLUGINS]"
+ echo
+ echo "where COMMAND is one of:"
+ echo " "$u"i"$nc"nstall (default)"
+ echo " "$u"u"$nc"pdate"
+ echo " "$u"r"$nc"m"
+ echo " "$u"l"$nc"s (or ls-remote [--format=FORMAT])"
+ echo " "$u"h"$nc"elp"
+end
+
+
+function __fisher_version
+ set -l real_home ~
+ printf "fisherman version $fisher_version %s\n" (
+ __fisher_plugin_normalize_path (status -f) | command sed "s|$real_home|~|;s|$__fish_datadir|\$__fish_datadir|")
+end
+
+function __fisher_help -a cmd number
+ if test -z "$argv"
+ set -l page "$fisher_cache/$fisher_cmd_name.1"
+
+ if test ! -s "$page"
+ __fisher_man_page_write > "$page"
+ end
+
+ if [ "$PREFIX" = "/data/data/com.termux/files/usr" ]
+
+ mandoc -a "$page"
+
+ else
+
+ set -l pager "/usr/bin/less -s"
+
+ if test ! -z "$PAGER"
+ set pager "$PAGER"
+ end
+
+ man -P "$pager" -- "$page"
+
+ end
+
+ command rm -f "$page"
+
+ else
+ if test -z "$number"
+ set number 1
+ end
+
+ set -l page "$fisher_config/$cmd/man/man$number/$cmd.$number"
+
+ if not man "$page" 2> /dev/null
+ if test -d "$fisher_config/$cmd"
+ __fisher_log info "There's no manual for this plugin." "$__fisher_stderr"
+
+ set -l url (__fisher_plugin_get_url_info -- "$fisher_config/$cmd")
+
+ __fisher_log info "Try online: <&github.com/$url&>" "$__fisher_stderr"
+ else
+ __fisher_log error "This plugin is not installed." "$__fisher_stderr"
+ end
+
+ return 1
+ end
+ end
+end
+
+
+function __fisher_self_uninstall -a yn
+ set -l file (status --current-filename)
+ set -l u (set_color -u)
+ set -l nc (set_color normal)
+
+ switch "$yn"
+ case -y --yes
+ case \*
+ __fisher_log info "
+ This will permanently remove fisherman from your system.
+ The following directories and files will be erased:
+
+ $fisher_cache
+ $fisher_config
+ $fish_config/functions/$fisher_cmd_name.fish
+ $fish_config/completions/$fisher_cmd_name.fish
+
+ " >&2
+
+ echo -sn "Continue? [Y/n] " >&2
+
+ __fisher_get_key | read -l yn
+
+ switch "$yn"
+ case n N
+ set -l username
+
+ if test ! -z "$USER"
+ set username " $USER"
+ end
+
+ __fisher_log okay "As you wish cap!"
+ return 1
+ end
+ end
+
+ complete -c $fisher_cmd_name --erase
+
+ __fisher_show_spinner
+
+ echo "$fisher_cmd_name ls | $fisher_cmd_name rm -q" | source 2> /dev/null
+
+ __fisher_show_spinner
+
+ command rm -rf "$fisher_cache" "$fisher_config"
+ command rm -f "$fish_config"/{functions,completions}/$fisher_cmd_name.fish "$fisher_file"
+
+ set -e fish_config
+ set -e fish_path
+ set -e fisher_active_prompt
+ set -e fisher_cache
+ set -e fisher_config
+ set -e fisher_file
+ set -e fisher_version
+ set -e fisher_spinners
+
+ __fisher_log info "Done." "$__fisher_stderr"
+
+ set -l funcs (functions -a | command grep __fisher)
+
+ functions -e $funcs $fisher_cmd_name
+end
+
+
+function __fisher_man_page_write
+ echo '.
+.TH "FISHERMAN" "1" "May 2016" "" "fisherman"
+.
+.SH "NAME"
+\fBfisherman\fR \- fish plugin manager
+.
+.SH "SYNOPSIS"
+'"$fisher_cmd_name"' [(\fBi\fRnstall | \fBu\fRpdate | \fBl\fRs[\-remote] | \fBr\fRm | \fBh\fRelp) PLUGINS]
+.
+.br
+.
+.SH "DESCRIPTION"
+A plugin manager for fish\.
+.
+.SH "OPTIONS"
+.
+.IP "\(bu" 4
+\-v, \-\-version: Show version information\.
+.
+.IP "\(bu" 4
+\-h, \-\-help: Show usage help\. Use the long form to display this page\.
+.
+.IP "\(bu" 4
+\-q, \-\-quiet: Enable quiet mode\. Use to suppress output\.
+.
+.IP "" 0
+.
+.SH "USAGE"
+Install a plugin\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' mono
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Install some plugins\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' z fzf edc/bass omf/tab
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Install a specific branch\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' edc/bass:master
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Install a specific tag\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' done@1.2.0
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Install a gist\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' https://gist\.github\.com/username/1f40e1c6e0551b2666b2
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Install a local directory\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' ~/my/plugin
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Edit your \fIfishfile\fR and run \fB'"$fisher_cmd_name"'\fR to commit changes\.
+.
+.IP "" 4
+.
+.nf
+
+$EDITOR ~/\.config/fish/fishfile
+'"$fisher_cmd_name"'
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Show everything you\'ve installed\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' ls
+@ plugin # a local directory
+* mono # the current prompt
+ bass
+ fzf
+ thefuck
+ z
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Show everything that\'s available\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' ls\-remote
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Update everything\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' up
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Update some plugins\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' up bass z fzf
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Remove plugins\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' rm thefuck
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Remove all the plugins\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' ls | '"$fisher_cmd_name"' rm
+.
+.fi
+.
+.IP "" 0
+.
+.P
+Get help\.
+.
+.IP "" 4
+.
+.nf
+
+'"$fisher_cmd_name"' help z
+.
+.fi
+.
+.IP "" 0
+.
+.SH "FAQ"
+.
+.SS "What is the required fish version?"
+>=2\.2\.0\.
+.
+.P
+For \fIsnippet\fR support, upgrade to >=2\.3\.0 or append the following code to your \fI~/\.config/fish/config\.fish\fR\.
+.
+.IP "" 4
+.
+.nf
+
+for file in ~/\.config/fish/conf\.d/*\.fish
+ source $file
+end
+.
+.fi
+.
+.IP "" 0
+.
+.SS "Is fisherman compatible with oh\-my\-fish themes and plugins?"
+Yes\.
+.
+.SS "Where does fisherman put stuff?"
+The cache and configuration go in \fI~/\.cache/fisherman\fR and \fI~/\.config/fisherman\fR respectively\.
+.
+.P
+The fishfile is saved to \fI~/\.config/fish/fishfile\fR\.
+.
+.SS "How do I have fisherman copy plugin files instead of linking?"
+By default, fisherman will create symlinks to plugin files.
+.
+.P
+To have fisherman copy files:
+.
+.IP "" 4
+.
+.nf=
+
+set -U fisher_copy true
+.
+.fi
+.
+.IP "" 0
+.
+.SS "What is a fishfile and how do I use it?"
+The fishfile \fI~/\.config/fish/fishfile\fR lists what plugins you\'ve installed\.
+.
+.P
+This file is updated automatically as you install / remove plugins. You can also edit this file and run \fBfisher\fR to commit changes\.
+.
+.P
+This mechanism only installs plugins and missing dependencies\. To remove plugins, use \fBfisher rm\fR\.
+.
+.SS "What is a plugin?"
+A plugin is:
+.
+.IP "1." 4
+a directory or git repo with one or more \fI\.fish\fR functions either at the root level of the project or inside a \fIfunctions\fR directory
+.
+.IP "2." 4
+a theme or prompt, i\.e, a \fIfish_prompt\.fish\fR, \fIfish_right_prompt\.fish\fR or both files
+.
+.IP "3." 4
+a snippet, i\.e, one or more \fI\.fish\fR files inside a directory named \fIconf\.d\fR, evaluated by fish at the start of the session
+.
+.IP "" 0
+.
+.SS "How can I list plugins as dependencies to my plugin?"
+Create a new \fIfishfile\fR file at the root level of your project and write in the plugins\.'
+end
diff --git a/fish/functions/fr.fish b/fish/functions/fr.fish
new file mode 100644
index 0000000..a73dd8d
--- /dev/null
+++ b/fish/functions/fr.fish
@@ -0,0 +1,4 @@
+function fr
+ find ./ -iname "*"$argv"*" -printf "%T@ %Td-%Tb-%TY %Tk:%TM %p\n" | sort -n | cut -d " " -f 2- | grep -i "$argv"
+end
+
diff --git a/fish/functions/fs.fish b/fish/functions/fs.fish
new file mode 100644
index 0000000..79cb275
--- /dev/null
+++ b/fish/functions/fs.fish
@@ -0,0 +1,3 @@
+function fs --description 'Switch tmux session'
+ tmux list-sessions -F "#{session_name}" | fzf | xargs tmux switch-client -t
+end
diff --git a/fish/functions/ftnotes.fish b/fish/functions/ftnotes.fish
new file mode 100644
index 0000000..22dd24c
--- /dev/null
+++ b/fish/functions/ftnotes.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.x1oNhc/ftnotes.fish @ line 2
+function ftnotes --description 'Use find to identify file names in Textnotes directory' --argument pattern
+ find ~/Nextcloud/Notes/ -type f -iname "*$pattern*" | cut -f6 -d/
+end
diff --git a/fish/functions/fz_lastpass.fish b/fish/functions/fz_lastpass.fish
new file mode 100644
index 0000000..4d3fe5f
--- /dev/null
+++ b/fish/functions/fz_lastpass.fish
@@ -0,0 +1,3 @@
+function fz_lastpass --description 'Fuzzy search in lastpass archive gpg file'
+ gpg -d -r matt@matthewlemon.com ~/Nextcloud/Documents/lastpass-export.gpg | fzf
+end
diff --git a/fish/functions/fzf-cdhist-widget.fish b/fish/functions/fzf-cdhist-widget.fish
new file mode 100644
index 0000000..1477699
--- /dev/null
+++ b/fish/functions/fzf-cdhist-widget.fish
@@ -0,0 +1,14 @@
+function fzf-cdhist-widget --description 'cd to one of the previously visited locations'
+ # Clear non-existent folders from cdhist.
+ set -l buf
+ for i in (seq 1 (count $dirprev))
+ set -l dir $dirprev[$i]
+ if test -d $dir
+ set buf $buf $dir
+ end
+ end
+ set dirprev $buf
+ string join \n $dirprev | tac | sed 1d | eval (__fzfcmd) +m $FZF_CDHIST_OPTS | read -l result
+ [ "$result" ]; and cd $result
+ commandline -f repaint
+end
diff --git a/fish/functions/fzf_key_bindings.fish b/fish/functions/fzf_key_bindings.fish
new file mode 120000
index 0000000..c9ab910
--- /dev/null
+++ b/fish/functions/fzf_key_bindings.fish
@@ -0,0 +1 @@
+/home/lemon/.fzf/shell/key-bindings.fish \ No newline at end of file
diff --git a/fish/functions/get-all-installed-packages-debian.fish b/fish/functions/get-all-installed-packages-debian.fish
new file mode 100644
index 0000000..1d2a838
--- /dev/null
+++ b/fish/functions/get-all-installed-packages-debian.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.5hRdP2/get-all-installed-packages-debian.fish @ line 1
+function get-all-installed-packages-debian --description Get\ all\ the\ packages\ I\'ve\ installed\ on\ Debian
+ dpkg --get-selections | grep -w 'install$'
+end
diff --git a/fish/functions/get-location-from-ip.fish b/fish/functions/get-location-from-ip.fish
new file mode 100644
index 0000000..1aea2f7
--- /dev/null
+++ b/fish/functions/get-location-from-ip.fish
@@ -0,0 +1,3 @@
+function get-location-from-ip --description 'Get location from IP addres'
+ curl -s https://ipvigilante.com/(curl -s https://ipinfo.io/ip) | jq '.data.latitude, .data.longitude, .data.city_name, .data.country_name'
+end
diff --git a/fish/functions/get-random-package-info.fish b/fish/functions/get-random-package-info.fish
new file mode 100644
index 0000000..9d68d78
--- /dev/null
+++ b/fish/functions/get-random-package-info.fish
@@ -0,0 +1,4 @@
+function get-random-package-info --description 'Get random information on installed Debian packages'
+ dpkg-query --status (dpkg --get-selections | awk '{print NR,}' | grep -oP "^( echo [ (
+ % (dpkg --get-selections| wc -l) + 1 ) ] ) \K.*")
+end
diff --git a/fish/functions/gitcommands.fish b/fish/functions/gitcommands.fish
new file mode 100644
index 0000000..97f78f8
--- /dev/null
+++ b/fish/functions/gitcommands.fish
@@ -0,0 +1,7 @@
+function gitcommands --description 'Grep (or not) git-aliases.txt'
+ if count $argv > 0
+cat ~/Nextcloud/Notes/git-aliases.txt | grep $argv[1]
+else
+cat ~/Nextcloud/Notes/git-aliases.txt
+end
+end
diff --git a/fish/functions/gloga.fish b/fish/functions/gloga.fish
new file mode 100644
index 0000000..4c4e588
--- /dev/null
+++ b/fish/functions/gloga.fish
@@ -0,0 +1,3 @@
+function gloga
+ git log --oneline --decorate --graph --all
+end
diff --git a/fish/functions/grep_lastpass.fish b/fish/functions/grep_lastpass.fish
new file mode 100644
index 0000000..6b572ca
--- /dev/null
+++ b/fish/functions/grep_lastpass.fish
@@ -0,0 +1,3 @@
+function grep_lastpass --description 'Fuzzy search in lastpass archive gpg file'
+ gpg -d -r matt@matthewlemon.com ~/Nextcloud/Documents/lastpass-export.gpg | grep $argv
+end
diff --git a/fish/functions/greptnotes.fish b/fish/functions/greptnotes.fish
new file mode 100644
index 0000000..f04002d
--- /dev/null
+++ b/fish/functions/greptnotes.fish
@@ -0,0 +1,3 @@
+function greptnotes
+ ls ~/Nextcloud/Textnotes/ | grep $argv[1]
+end
diff --git a/fish/functions/grup.fish b/fish/functions/grup.fish
new file mode 100644
index 0000000..517bc3d
--- /dev/null
+++ b/fish/functions/grup.fish
@@ -0,0 +1,3 @@
+function grup --description 'git remote update'
+ command git remote update
+end
diff --git a/fish/functions/hl-monthly-for-account.fish b/fish/functions/hl-monthly-for-account.fish
new file mode 100644
index 0000000..8c8dc89
--- /dev/null
+++ b/fish/functions/hl-monthly-for-account.fish
@@ -0,0 +1,4 @@
+function hl-monthly-for-account --description 'hledger register for account (given in food:home format)'
+ cd ~/ledger
+hledger reg --monthly $argv[1]
+end
diff --git a/fish/functions/hl-weekly-for-account.fish b/fish/functions/hl-weekly-for-account.fish
new file mode 100644
index 0000000..0aceac7
--- /dev/null
+++ b/fish/functions/hl-weekly-for-account.fish
@@ -0,0 +1,4 @@
+function hl-weekly-for-account --description 'hledger show weekly for account (given in food:home format)'
+ cd ~/ledger
+ hledger reg --weekly $argv[1]
+end
diff --git a/fish/functions/in.fish b/fish/functions/in.fish
new file mode 100644
index 0000000..a9e5873
--- /dev/null
+++ b/fish/functions/in.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function in --description 'alias in=task add +in'
+ task add +in $argv;
+end
diff --git a/fish/functions/laptopscreenoff.fish b/fish/functions/laptopscreenoff.fish
new file mode 100644
index 0000000..433f5a4
--- /dev/null
+++ b/fish/functions/laptopscreenoff.fish
@@ -0,0 +1,3 @@
+function laptopscreenoff
+ xrandr --output LVDS-1 --off
+end
diff --git a/fish/functions/latest-textnote.fish b/fish/functions/latest-textnote.fish
new file mode 100644
index 0000000..537449d
--- /dev/null
+++ b/fish/functions/latest-textnote.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.BHTweX/latest-textnote.fish @ line 2
+function latest-textnote
+ ls -alt ~/Nextcloud/Notes/ | head -n$argv
+end
diff --git a/fish/functions/livehosts.fish b/fish/functions/livehosts.fish
new file mode 100644
index 0000000..7e53bc6
--- /dev/null
+++ b/fish/functions/livehosts.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function livehosts --description alias\ livehosts=nmap\ -sP\ \(ip\ -4\ -o\ route\ get\ 1\ \|\ cut\ -d\ \'\ \'\ -f\ 7\)/24\ \|\ grep\ report\ \|\ cut\ -d\ \'\ \'\ -f\ 5
+ nmap -sP (ip -4 -o route get 1 | cut -d ' ' -f 7)/24 | grep report | cut -d ' ' -f 5 $argv;
+end
diff --git a/fish/functions/ls-links.fish b/fish/functions/ls-links.fish
new file mode 100644
index 0000000..6c88ca0
--- /dev/null
+++ b/fish/functions/ls-links.fish
@@ -0,0 +1,3 @@
+function ls-links
+ find ~ -type l ! -path "*virtualenvs*" | cut -f4- -d/
+end
diff --git a/fish/functions/man.fish b/fish/functions/man.fish
new file mode 120000
index 0000000..053f86b
--- /dev/null
+++ b/fish/functions/man.fish
@@ -0,0 +1 @@
+/home/lemon/.config/fisherman/Colored-Man-Pages/functions/man.fish \ No newline at end of file
diff --git a/fish/functions/ml_jps_to_SharePics.fish b/fish/functions/ml_jps_to_SharePics.fish
new file mode 100644
index 0000000..f77fe2d
--- /dev/null
+++ b/fish/functions/ml_jps_to_SharePics.fish
@@ -0,0 +1,7 @@
+function ml_jps_to_SharePics -d "Copy all .jpg files in this directory to ~/Nextcloud/SharePics"
+ for file in *.jpg
+ cp $file ~/Nextcloud/SharePics
+ printf "copied %s to ~/Nextcloud/SharePics\n" $file
+ end
+end
+
diff --git a/fish/functions/mount-nc-webdav.fish b/fish/functions/mount-nc-webdav.fish
new file mode 100644
index 0000000..51eda9d
--- /dev/null
+++ b/fish/functions/mount-nc-webdav.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function mount-nc-webdav --description 'alias mount-nc-webdav=sudo mount -t davfs -o uid=1000,gid=1000 https://ronver.xyz/remote.php/dav/files/mrlemon Nextcloud-webDAV/'
+ sudo mount -t davfs -o uid=1000,gid=1000 https://ronver.xyz/remote.php/dav/files/mrlemon Nextcloud-webDAV/ $argv;
+end
diff --git a/fish/functions/mplayer-yt.fish b/fish/functions/mplayer-yt.fish
new file mode 100644
index 0000000..eae137d
--- /dev/null
+++ b/fish/functions/mplayer-yt.fish
@@ -0,0 +1,5 @@
+# Defined in /tmp/fish.ai34DV/mplayer-yt.fish @ line 2
+function mplayer-yt --description 'Play a YouTube video in mplayer'
+ set url (youtube-dl -g -f 43 --cookies /tmp/cookie-youtube.txt $argv)
+ mplayer -fs -cookies -cookies-file /tmp/cookie-youtube.txt $url
+end
diff --git a/fish/functions/pomo.fish b/fish/functions/pomo.fish
new file mode 100644
index 0000000..37e7840
--- /dev/null
+++ b/fish/functions/pomo.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.ZKaTF7/pomo.fish @ line 1
+function pomo --description 'Pomodoro for 25 minutes with zenity warning at end'
+ sleep 1500; and zenity --warning --text="Stop working! Break for 5 mins."
+end
diff --git a/fish/functions/pull-textnotes.fish b/fish/functions/pull-textnotes.fish
new file mode 100644
index 0000000..6f91b6d
--- /dev/null
+++ b/fish/functions/pull-textnotes.fish
@@ -0,0 +1,3 @@
+function pull-textnotes --description 'Pull ~/Nextcloud/Textnotes from server'
+ rsync -av --delete -e "ssh -p 2222" lemon@46.101.17.241:/home/lemon/Nextcloud/Textnotes/ /home/lemon/Nextcloud/Textnotes/
+end
diff --git a/fish/functions/push-textnotes.fish b/fish/functions/push-textnotes.fish
new file mode 100644
index 0000000..15084e7
--- /dev/null
+++ b/fish/functions/push-textnotes.fish
@@ -0,0 +1,3 @@
+function push-textnotes --description 'Push ~/Nextcloud/Textnotes to server'
+ rsync -av --delete -e "ssh -p 2222" /home/lemon/Nextcloud/Textnotes/ lemon@46.101.17.241:/home/lemon/Nextcloud/Textnotes/
+end
diff --git a/fish/functions/pyfind.fish b/fish/functions/pyfind.fish
new file mode 100644
index 0000000..e82d716
--- /dev/null
+++ b/fish/functions/pyfind.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.e6R9oj/pyfind.fish @ line 2
+function pyfind --description 'Find string in Python files from this root'
+ find -name "*.py"|xargs grep $argv
+end
diff --git a/fish/functions/pythontree.fish b/fish/functions/pythontree.fish
new file mode 100644
index 0000000..359829a
--- /dev/null
+++ b/fish/functions/pythontree.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function pythontree --description 'alias pythontree tree -I "*.pyc" -I "__pycache__" |less'
+ tree -I "*.pyc" -I "__pycache__" |less $argv;
+end
diff --git a/fish/functions/quteconfig.fish b/fish/functions/quteconfig.fish
new file mode 100644
index 0000000..2b74ebd
--- /dev/null
+++ b/fish/functions/quteconfig.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function quteconfig --description 'alias quteconfig vim -u init_to_disable_nvim_plugs.vim ~/.config/qutebrowser/config.py'
+ vim -u init_to_disable_nvim_plugs.vim ~/.config/qutebrowser/config.py $argv;
+end
diff --git a/fish/functions/samba-share.fish b/fish/functions/samba-share.fish
new file mode 100644
index 0000000..f424f46
--- /dev/null
+++ b/fish/functions/samba-share.fish
@@ -0,0 +1,3 @@
+function samba-share --description 'scp a file to /media/usbdrivesilver2/shares'
+ scp $argv[1] rasp:/media/usbdrivesilver2/shares
+end
diff --git a/fish/functions/screenshot.fish b/fish/functions/screenshot.fish
new file mode 100644
index 0000000..8b1f736
--- /dev/null
+++ b/fish/functions/screenshot.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function screenshot --description 'alias screenshot=xwd | xwdtopnm | pnmtopng > ~/Downloads/capture.png'
+ xwd | xwdtopnm | pnmtopng > ~/Downloads/capture.png $argv;
+end
diff --git a/fish/functions/sus.fish b/fish/functions/sus.fish
new file mode 100644
index 0000000..5bc12fd
--- /dev/null
+++ b/fish/functions/sus.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function sus --description 'alias sus=sudo systemctl suspend'
+ sudo systemctl suspend $argv;
+end
diff --git a/fish/functions/syn.fish b/fish/functions/syn.fish
new file mode 100644
index 0000000..2202314
--- /dev/null
+++ b/fish/functions/syn.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function syn --description 'alias syn task sync'
+ task sync $argv;
+end
diff --git a/fish/functions/techno-pulse.fish b/fish/functions/techno-pulse.fish
new file mode 100644
index 0000000..65aa19b
--- /dev/null
+++ b/fish/functions/techno-pulse.fish
@@ -0,0 +1,3 @@
+function techno-pulse --description 'Play di techno with pulseaudio'
+ mplayer --ao=pulse http://pub1.diforfree.org:8000/di_techno_hi
+end
diff --git a/fish/functions/techno.fish b/fish/functions/techno.fish
new file mode 100644
index 0000000..3d808ae
--- /dev/null
+++ b/fish/functions/techno.fish
@@ -0,0 +1,3 @@
+function techno
+ mplayer http://pub1.diforfree.org:8000/di_techno_hi
+end
diff --git a/fish/functions/termux-ssh.fish b/fish/functions/termux-ssh.fish
new file mode 100644
index 0000000..f4b1be3
--- /dev/null
+++ b/fish/functions/termux-ssh.fish
@@ -0,0 +1,3 @@
+function termux-ssh
+ ssh -p 8022 192.168.1.105
+end
diff --git a/fish/functions/test-task.fish b/fish/functions/test-task.fish
new file mode 100644
index 0000000..75d7784
--- /dev/null
+++ b/fish/functions/test-task.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function test-task --description 'alias test-task env TASKDATA=/home/lemon/.test_tw_data env TASKRC=/home/lemon/.test_twrc task'
+ env TASKDATA=/home/lemon/.test_tw_data env TASKRC=/home/lemon/.test_twrc task $argv;
+end
diff --git a/fish/functions/todo-pull.fish b/fish/functions/todo-pull.fish
new file mode 100644
index 0000000..388895f
--- /dev/null
+++ b/fish/functions/todo-pull.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.tCvOIe/todo-push.fish @ line 2
+function todo-pull --description 'Push /home/lemon/todo directory to crocusnedloyd.online'
+ rsync -avzh --delete -e "ssh -p 2222" lemon@46.101.17.241:todo/ /home/lemon/todo/
+end
diff --git a/fish/functions/todo-push.fish b/fish/functions/todo-push.fish
new file mode 100644
index 0000000..bcbc448
--- /dev/null
+++ b/fish/functions/todo-push.fish
@@ -0,0 +1,3 @@
+function todo-push --description 'Push todo directory to crocusnedloyd.online'
+ rsync -avzh --delete -e "ssh -p 2222" /home/lemon/todo/ lemon@46.101.17.241:todo/
+end
diff --git a/fish/functions/trance.fish b/fish/functions/trance.fish
new file mode 100644
index 0000000..f817059
--- /dev/null
+++ b/fish/functions/trance.fish
@@ -0,0 +1,4 @@
+# Defined in /tmp/fish.8DcyQh/trance.fish @ line 2
+function trance
+ mpv http://pub1.diforfree.org:8000/di_trance_hi --no-video
+end
diff --git a/fish/functions/unmount-nc-webdav.fish b/fish/functions/unmount-nc-webdav.fish
new file mode 100644
index 0000000..5257f00
--- /dev/null
+++ b/fish/functions/unmount-nc-webdav.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function unmount-nc-webdav --description 'alias unmount-nc-webdav=sudo umount ~/Nextcloud-webDAV'
+ sudo umount ~/Nextcloud-webDAV $argv;
+end
diff --git a/fish/functions/vcb.fish b/fish/functions/vcb.fish
new file mode 100644
index 0000000..d0a0052
--- /dev/null
+++ b/fish/functions/vcb.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function vcb --description 'alias vcb xclip -i -selection clipboard -o | vim -'
+ xclip -i -selection clipboard -o | vim - $argv;
+end
diff --git a/fish/functions/weather.fish b/fish/functions/weather.fish
new file mode 100644
index 0000000..96a8776
--- /dev/null
+++ b/fish/functions/weather.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 0
+function weather --description 'alias weather=curl wttr.in/~Berwick-upon-Tweed'
+ curl wttr.in/~Berwick-upon-Tweed $argv;
+end
diff --git a/fish/functions/wgdown.fish b/fish/functions/wgdown.fish
new file mode 100644
index 0000000..6b17218
--- /dev/null
+++ b/fish/functions/wgdown.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function wgdown --description 'alias wgdown sudo wg-quick down laptop-x201'
+ sudo wg-quick down laptop-x201 $argv;
+end
diff --git a/fish/functions/wgup.fish b/fish/functions/wgup.fish
new file mode 100644
index 0000000..455b468
--- /dev/null
+++ b/fish/functions/wgup.fish
@@ -0,0 +1,4 @@
+# Defined in - @ line 1
+function wgup --description 'alias wgup sudo wg-quick up laptop-x201'
+ sudo wg-quick up laptop-x201 $argv;
+end
diff --git a/flake8 b/flake8
new file mode 100644
index 0000000..4b656a8
--- /dev/null
+++ b/flake8
@@ -0,0 +1,4 @@
+[flake8]
+ignore = E203,E501,E303,E261,E26,E731,E702,F403,F405,W503,W504,E203,D100,D101,D102,D103,D104,D105,D107,D300,D400,C0111
+exclude = .git,__pycache__,docs/source/conf.py,old,build,dist
+max-line-length = 88
diff --git a/gcalclirc b/gcalclirc
new file mode 100644
index 0000000..26e54db
--- /dev/null
+++ b/gcalclirc
@@ -0,0 +1,4 @@
+--client_id=419034302572-fgpls69eip2oq26ae5a4lofob2u33f09.apps.googleusercontent.com
+--client_secret=vTxUanyrdWwZTjUN_XtK13Bu
+--monday
+--width=20
diff --git a/gitconfig b/gitconfig
new file mode 100644
index 0000000..be0b9e0
--- /dev/null
+++ b/gitconfig
@@ -0,0 +1,27 @@
+[user]
+ email = matt@matthewlemon.com
+ name = Matthew Lemon
+[core]
+ excludesfile = /home/lemon/.gitignore_global
+ quotepath = false
+ editor = /usr/bin/nvim
+[alias]
+ co = checkout
+ ci = commit
+ br = branch
+ # friendly statuses
+ st = status -sb --ignore-submodules=all
+ # Add all unstaged changes/removals and commit. All you gotta do here is pass the commit message.
+ # Example: git ac 'My commit message'
+ ac = !git add -A && git commit -m
+ # Pretty looking log
+ lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit
+ d = difftool
+[push]
+ default = simple
+[diff]
+ tool = vimdiff
+[difftool]
+ prompt = false
+[pull]
+ rebase = false
diff --git a/gitignore_global b/gitignore_global
new file mode 100644
index 0000000..65ea724
--- /dev/null
+++ b/gitignore_global
@@ -0,0 +1,52 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+#bin/
+build/
+develop-eggs/
+eggs/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
+
+# Rope
+.ropeproject
+
+# Django stuff:
+*.log
+*.pot
+
+# Sphinx documentation
+docs/_build/
+.pdb-pyhist
+.mypy_cache/
diff --git a/gtkrc b/gtkrc
new file mode 100644
index 0000000..8c097be
--- /dev/null
+++ b/gtkrc
@@ -0,0 +1,40 @@
+style "compact"
+{
+GtkButton::default_border={0,0,0,0}
+GtkButton::default_outside_border={0,0,0,0}
+GtkButtonBox::child_min_width=0
+GtkButtonBox::child_min_heigth=0
+GtkButtonBox::child_internal_pad_x=0
+GtkButtonBox::child_internal_pad_y=0
+GtkMenu::vertical-padding=1
+GtkMenuBar::internal_padding=1
+GtkMenuItem::horizontal_padding=4
+GtkToolbar::internal-padding=1
+GtkToolbar::space-size=1
+GtkOptionMenu::indicator_size=0
+GtkOptionMenu::indicator_spacing=0
+GtkPaned::handle_size=4
+GtkRange::trough_border=0
+GtkRange::stepper_spacing=0
+GtkScale::value_spacing=0
+GtkScrolledWindow::scrollbar_spacing=0
+GtkExpander::expander_size=10
+GtkExpander::expander_spacing=0
+GtkTreeView::vertical-separator=0
+GtkTreeView::horizontal-separator=0
+GtkTreeView::expander-size=12
+GtkTreeView::fixed-height-mode=TRUE
+GtkWidget::focus_padding=0
+
+font_name="Liberation Sans,Sans Regular 8"
+text[SELECTED] = @selected_text_color
+}
+class "GtkWidget" style "compact"
+style "compact2"
+{
+xthickness=1
+ythickness=1
+}
+class "GtkButton" style "compact2"
+class "GtkToolbar" style "compact2"
+class "GtkPaned" style "compact2"
diff --git a/ideavimrc b/ideavimrc
new file mode 100644
index 0000000..5b65632
--- /dev/null
+++ b/ideavimrc
@@ -0,0 +1,3 @@
+source ~/.vimrc
+set visualbell
+set noerrorbells
diff --git a/init.vim-legacy b/init.vim-legacy
new file mode 100644
index 0000000..fc242f4
--- /dev/null
+++ b/init.vim-legacy
@@ -0,0 +1,1109 @@
+"LEMON'S VIMRC - 16 NOVEMBER 2014
+" Preamble {{{...
+set t_Co=256
+set background=dark
+set path+=**
+"}}}
+"
+" set syntax on
+syntax on
+
+" vertical diff please
+set diffopt=vertical
+
+" twdft colouring and syntaxing
+autocmd BufNewFile,BufRead *.twdft set syntax=markdown
+" macro to create and delete a 'check a box'
+"nmap 1 0f[lrx
+nmap 1 0f rx
+nmap 2 0fxr 
+"
+" Remap the leader key {{{...
+let mapleader = ","
+"...}}}
+"
+" map ESCAPE to exit to Normal mode in neovim terminal {{{...
+tnoremap <Esc> <C-\><C-N>
+" ...}}}
+"
+" Signify mapping & config
+nnoremap <leader>R :SignifyRefresh<CR>
+let g:signify_realtime = 1
+
+"
+" Basic options {{{...
+
+set cmdheight=1
+set termguicolors
+set inccommand=split
+set foldmethod=manual
+set encoding=utf-8
+set modelines=0
+set relativenumber
+set autoindent
+set showmode
+set cursorline
+set ttyfast
+set ttimeout
+set notimeout
+set nottimeout
+set backspace=indent,eol,start
+set ruler
+set laststatus=2
+set history=1000 " remember more commands and search history
+set undolevels=1000 " use many muchos levels of undo
+set wildignore=*.swp,*.bak,*.pyc,*.class
+set title " change the terminal's title
+set visualbell " don't beep
+set noerrorbells " don't beep
+set number
+set fillchars=diff:⣿,vert:\|
+set noswapfile
+set ruler " show the cursor position all the time
+set showcmd " display incomplete commands
+set vb
+"set list
+set listchars=tab:â–¸\ ,eol:¬,extends:â¯,precedes:â®
+set lazyredraw
+set matchtime=3
+set showbreak=↪
+set shell=/usr/local/bin/fish
+set splitbelow
+set splitright
+set autowrite
+set autoread
+set linebreak
+set hidden
+"set colorcolumn=80
+"...}}}
+" Wildmenu completion {{{
+set wildmenu
+" set wildmode=list:longest " don't like this
+set wildignore+=.hg,.git,.svn " Version control
+set wildignore+=*.aux,*.out,*.toc " LaTeX intermediate files
+set wildignore+=*.jpg,*.bmp,*.gif,*.png,*.jpeg " binary images
+set wildignore+=*.o,*.obj,*.exe,*.dll,*.manifest " compiled object files
+set wildignore+=*.spl " compiled spelling word lists
+set wildignore+=*.sw? " Vim swap files
+set wildignore+=*.DS_Store " OSX bullshit
+set wildignore+=*.luac " Lua byte code
+set wildignore+=migrations " Django migrations
+set wildignore+=*.pyc " Python byte code
+set wildignore+=*.orig " Merge resolution files
+" Clojure/Leiningen
+set wildignore+=classes
+set wildignore+=lib
+
+" }}}
+" Make Vim able to edit crontab files ... {{{
+set backupskip=/tmp/*,/private/tmp/*"
+"...}}}
+" Remaps ...{{{
+"NERDTree!
+nmap \e :NERDTreeToggle<CR>
+let NERDTreeIgnore=['\.pyc$', '\~$'] "ignore files in NERDTree
+
+" targbar handler
+nmap <F8> :TagbarToggle<CR>
+
+" Don't use Ex mode, use Q for formatting
+"map Q gq
+
+" easier formatting of paragraphs
+" from https://github.com/thesheff17/youtube/blob/master/vim/vimrc
+vmap Q gq
+nmap Q gqap
+
+" set trailing whitespace to be visible with using special chars with ,s
+"set listchars=tab:>-,trail:*,eol:$
+"nmap <silent> <leader>s :set nolist!<CR>
+" some misc settings
+:nmap \l :setlocal number!<CR>
+:nmap \o :set paste!<CR>
+
+" map sort function to a key
+" from https://github.com/thesheff17/youtube/blob/master/vim/vimrc
+vnoremap <Leader>s :sort<CR>
+
+" Plug Plugs...{{{
+call plug#begin('~/.config/nvim/plugged')
+
+Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
+"Plug 'lervag/vimtex' " does not work with Latex Box in vim-polyglot
+Plug 'google/yapf', { 'rtp': 'plugins/vim', 'for': 'python' }
+Plug 'hdima/python-syntax'
+Plug 'deoplete-plugins/deoplete-go', {'do': 'make'}
+Plug 'junegunn/rainbow_parentheses.vim'
+Plug 'rust-lang/rust.vim'
+Plug 'reewr/vim-monokai-phoenix'
+Plug 'junegunn/fzf'
+Plug 'junegunn/fzf.vim'
+Plug 'zchee/deoplete-jedi'
+Plug 'mhinz/vim-signify' " marking changes in repo
+Plug 'anekos/hledger-vim'
+Plug 'fatih/vim-go', {'do': ':GoUpdateBinaries'}
+Plug 'buoto/gotests-vim'
+Plug 'bitc/vim-hdevtools'
+Plug 'NLKNguyen/papercolor-theme'
+Plug 'neovimhaskell/haskell-vim'
+Plug 'ledger/vim-ledger'
+Plug 'sophacles/vim-bundle-mako'
+"Plug 'zchee/deoplete-clang'
+Plug 'chriskempson/vim-tomorrow-theme'
+Plug 'sbdchd/neoformat'
+Plug 'w0rp/ale'
+Plug 'tpope/vim-fugitive'
+Plug 'tpope/vim-unimpaired'
+"Plug 'rking/ag.vim'
+Plug 'tmhedberg/SimpylFold'
+Plug 'tpope/vim-surround'
+Plug 'plasticboy/vim-markdown'
+Plug 'scrooloose/nerdtree'
+Plug 'scrooloose/nerdcommenter'
+Plug 'dag/vim-fish'
+Plug 'majutsushi/tagbar'
+Plug 'SirVer/ultisnips'
+Plug 'honza/vim-snippets'
+Plug 'jlanzarotta/bufexplorer'
+Plug 'jmcantrell/vim-virtualenv'
+Plug 'sukima/xmledit'
+Plug 'mileszs/ack.vim'
+Plug 'klen/python-mode'
+Plug 'Shougo/neosnippet'
+Plug 'Shougo/neosnippet-snippets'
+Plug 'itchyny/lightline.vim'
+Plug 'mhinz/vim-grepper'
+Plug 'sickill/vim-pasta'
+Plug 'sheerun/vim-polyglot'
+Plug 'tommcdo/vim-fubitive'
+Plug 'janko-m/vim-test'
+Plug 'tpope/vim-dispatch'
+Plug 'radenling/vim-dispatch-neovim'
+Plug 'sunaku/vim-dasht'
+Plug 'Shougo/neoinclude.vim'
+Plug 'sebdah/vim-delve'
+Plug 'ambv/black'
+Plug 'drewtempelmeyer/palenight.vim'
+Plug 'bitc/vim-hdevtools'
+Plug 'tweekmonster/django-plus.vim'
+Plug 'morhetz/gruvbox'
+Plug 'junegunn/limelight.vim'
+Plug 'nathangrigg/vim-beancount'
+Plug 'junegunn/vim-peekaboo'
+Plug 'cormacrelf/vim-colors-github'
+"Plug 'neoclide/coc.nvim', {'branch': 'release'}
+"Plug 'autozimu/LanguageClient-neovim', {
+" \ 'branch': 'next',
+" \ 'do': 'bash install.sh',
+" \ }
+call plug#end()
+" point neovim to virtualenv specific to neovim (using 3.7)
+let g:python3_host_prog = "/home/lemon/.virtualenvs/neovim3.7/bin/python3"
+
+"..{{{ rainbow_parentheses
+"activation based on file type
+augroup rainbow_lisp
+ autocmd!
+ autocmd FileType lisp,clojure,scheme,python RainbowParentheses
+augroup END
+"..}}}
+
+""..{{{ lightline and coc
+"
+"function! StatusDiagnostic() abort
+" let info = get(b:, 'coc_diagnostic_info', {})
+" if empty(info) | return '' | endif
+" let msgs = []
+" if get(info, 'error', 0)
+" call add(msgs, 'E' . info['error'])
+" endif
+" if get(info, 'warning', 0)
+" call add(msgs, 'W' . info['warning'])
+" endif
+" return join(msgs, ' ') . ' ' . get(g:, 'coc_status', '')
+"endfunction
+"
+"let g:lightline = {
+" \ 'colorscheme': 'monokai-phoenix',
+" \ 'active': {
+" \ 'left': [ [ 'mode', 'paste' ],
+" \ [ 'cocstatus', 'readonly', 'filename', 'modified' ] ]
+" \},
+" \ 'component_function': {
+" \ 'cocstatus': 'StatusDiagnostic'
+" \ },
+" \}
+"autocmd User CocStatusChange,CocDiagnosticsChange call lightline#update()
+""..}}}
+"
+"" ..{{{ coc.vim
+"let g:coc_node_path = "/usr/bin/nodejs"
+"" ..}}}
+"
+"" Some servers have issues with backup files, see #649
+"set nobackup
+"set nowritebackup
+"
+"" Better display for messages
+"set cmdheight=2
+"
+"" You will have bad experience for diagnostic messages when it's default 4000.
+"set updatetime=300
+"
+"" don't give |ins-completion-menu| messages.
+"set shortmess+=c
+"
+"" always show signcolumns
+"set signcolumn=yes
+"
+"" Use tab for trigger completion with characters ahead and navigate.
+"" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
+"inoremap <silent><expr> <TAB>
+" \ pumvisible() ? "\<C-n>" :
+" \ <SID>check_back_space() ? "\<TAB>" :
+" \ coc#refresh()
+"inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
+"
+"function! s:check_back_space() abort
+" let col = col('.') - 1
+" return !col || getline('.')[col - 1] =~# '\s'
+"endfunction
+"
+"" Use <c-space> to trigger completion.
+"inoremap <silent><expr> <c-space> coc#refresh()
+"
+"" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position.
+"" Coc only does snippet and additional edit on confirm.
+"inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
+"
+"" Use `[c` and `]c` to navigate diagnostics
+"nmap <silent> [c <Plug>(coc-diagnostic-prev)
+"nmap <silent> ]c <Plug>(coc-diagnostic-next)
+"
+"" Remap keys for gotos
+"nmap <silent> gd <Plug>(coc-definition)
+"nmap <silent> gy <Plug>(coc-type-definition)
+"nmap <silent> gi <Plug>(coc-implementation)
+"nmap <silent> gr <Plug>(coc-references)
+"
+"" Use K to show documentation in preview window
+"nnoremap <silent> K :call <SID>show_documentation()<CR>
+"
+"function! s:show_documentation()
+" if (index(['vim','help'], &filetype) >= 0)
+" execute 'h '.expand('<cword>')
+" else
+" call CocAction('doHover')
+" endif
+"endfunction
+"
+"" Highlight symbol under cursor on CursorHold
+"autocmd CursorHold * silent call CocActionAsync('highlight')
+"
+"" Remap for rename current word
+"nmap <leader>rn <Plug>(coc-rename)
+"
+"" Remap for format selected region
+"xmap <leader>f <Plug>(coc-format-selected)
+"nmap <leader>f <Plug>(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
+"
+"" Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph
+"xmap <leader>a <Plug>(coc-codeaction-selected)
+"nmap <leader>a <Plug>(coc-codeaction-selected)
+"
+"" Remap for do codeAction of current line
+"nmap <leader>ac <Plug>(coc-codeaction)
+"" Fix autofix problem of current line
+"nmap <leader>qf <Plug>(coc-fix-current)
+"
+"" Use <tab> for select selections ranges, needs server support, like: coc-tsserver, coc-python
+"nmap <silent> <TAB> <Plug>(coc-range-select)
+"xmap <silent> <TAB> <Plug>(coc-range-select)
+"xmap <silent> <S-TAB> <Plug>(coc-range-select-backword)
+"
+"" Use `:Format` to format current buffer
+"command! -nargs=0 Format :call CocAction('format')
+"
+"" Use `:Fold` to fold current buffer
+"command! -nargs=? Fold :call CocAction('fold', <f-args>)
+"
+"" use `:OR` for organize import of current buffer
+"command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
+"
+"
+"" Add status line support, for integration with other plugin, checkout `:h coc-status`
+""set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
+"
+"" Using CocList
+"" Show all diagnostics
+"nnoremap <silent> <space>a :<C-u>CocList diagnostics<cr>
+"" Manage extensions
+"nnoremap <silent> <space>e :<C-u>CocList extensions<cr>
+"" Show commands
+"nnoremap <silent> <space>c :<C-u>CocList commands<cr>
+"" Find symbol of current document
+"nnoremap <silent> <space>o :<C-u>CocList outline<cr>
+"" Search workspace symbols
+"nnoremap <silent> <space>s :<C-u>CocList -I symbols<cr>
+"" Do default action for next item.
+"nnoremap <silent> <space>j :<C-u>CocNext<CR>
+"" Do default action for previous item.
+"nnoremap <silent> <space>k :<C-u>CocPrev<CR>
+"" Resume latest coc list
+"nnoremap <silent> <space>p :<C-u>CocListResume<CR>
+"
+"
+
+
+
+"
+" ..{{{ LanguageClient config (base from github
+"
+" Required for operations modifying multiple buffers like rename.
+"set hidden
+
+"let g:LanguageClient_serverCommands = {
+" \ 'rust': ['~/.cargo/bin/rustup', 'run', 'stable', 'rls'],
+" \ 'javascript': ['/usr/local/bin/javascript-typescript-stdio'],
+" \ 'javascript.jsx': ['tcp://127.0.0.1:2089'],
+" \ 'python': ['/usr/local/bin/pyls' '-vv', '--log-file', '~/pyls.log'],
+" \ 'ruby': ['~/.rbenv/shims/solargraph', 'stdio'],
+" \ }
+
+" Instuctions for clangd here: https://clang.llvm.org/extra/clangd/Installation.html
+"let g:LanguageClient_serverCommands = {
+" \ 'rust': ['~/.cargo/bin/rustup', 'run', 'stable', 'rls'],
+" \ 'python': ['/usr/local/bin/pyls'],
+" \ 'cpp': ['clangd'],
+" \ 'c': ['clangd'],
+" \ }
+"let g:LanguageClient_settingsPath = 'ls-settings.json'
+" NOT REQUIRED WITH COC
+"let g:LanguageClient_useVirtualText = 1
+"let g:LanguageClient_diagnosticsEnable = 0
+"let g:LanguageClient_settingsPath=expand('~/.local/share/nvim/settings.json')
+"
+"nnoremap <F5> :call LanguageClient_contextMenu()<CR>
+"" Or map each action separately
+"nnoremap <silent> K :call LanguageClient#textDocument_hover()<CR>
+"nnoremap <silent> gd :call LanguageClient#textDocument_definition()<CR>
+"nnoremap <silent> <F2> :call LanguageClient#textDocument_rename()<CR>
+"nnoremap <silent> <F3> :call LanguageClient#textDocument_typeDefinition()<CR>
+"nnoremap <silent> <F4> :call LanguageClient#textDocument_documentSymbol()<CR>
+"nnoremap <silent> <F6> :call LanguageClient#textDocument_references()<CR>
+"nnoremap <silent> <F7> :call LanguageClient#workspace_symbol()<CR>
+"autocmd FileType * call LC_maps()
+" ..}}}
+" ..{{{ Rust
+let g:autofmt_autosave = 1
+" ...}}}
+" ..{{{ gruvbox config
+let g:gruvbox_contrast_dark = "hard"
+let g:gruvbox_invert_signs = 1
+let g:gruvbox_italic = 1
+let g:gruvbox_invert_indent_guides = 1
+"let g:gruvbox_italicize_strings = 1
+" ...}}}
+" vim-hdevtools for Haskell ..{{
+ au FileType haskell nnoremap <buffer> <F1> :HdevtoolsType<CR>
+ au FileType haskell nnoremap <buffer> <silent> <F2> :HdevtoolsClear<CR>
+" }}
+" vim-test config ..{{{
+" use vim-dispatch to run tests in the quickfix window
+" from Modern Vim Ch.4
+" the mappings below are from vim-test
+" https://github.com/janko/vim-test
+" dispatch opens send test output to quickfix window
+"let test#strategy = "dispatch"
+" neovim strategy runs the test in the neovim terminal
+let test#strategy = "neovim"
+let test#neovim#term_position = "topleft"
+let test#python#pytest#options = '-vvv --tb=short'
+
+" To run mypy using vim-dispath -with Dispatch
+autocmd FileType python let b:dispatch = 'mypy --ignore-missing-imports'
+
+nmap <silent> t<C-n> :TestNearest<CR>
+nmap <silent> t<C-f> :TestFile<CR>
+nmap <silent> t<C-s> :TestSuite<CR>
+"nmap <silent> t<C-l> :TestLast<CR>
+nmap <silent> <S-F10> :TestLast<CR>
+nmap <silent> t<C-g> :TestVisit<CR>
+" }}}
+"
+"
+"
+" clang support ... for Debian Stretch only!{{{
+"let g:deoplete#sources#clang#libclang_path = '/usr/lib/llvm-3.8/lib/libclang.so.1'
+"let g:deoplete#sources#clang#clang_header = '/usr/lib/llvm-3.8/lib/clang/3.8.1/include'
+" works on Debian Buster anyway
+let g:deoplete#sources#clang#clang_header = '/usr/lib/llvm-6.0/lib/clang/6.0.1/include/'
+let g:deoplete#sources#clang#libclang_path = '/usr/lib/llvm-6.0/lib/libclang.so.1'
+"}}}
+"
+" deoplete omnifuc {{{
+let g:deoplete#enable_at_startup = 1
+let g:deoplete#disable_auto_complete = 0
+"call deoplete#custom#option('auto_complete', 0)
+"call deoplete#custom#source('jedi', 'debug_enabled', 1)
+"call deoplete#enable_logging('DEBUG', '/tmp/deoplete.log')
+"inoremap <silent><expr><C-Space> deoplete#mappings#manual_complete()
+"}}}
+"
+" golang stuff {{{
+let g:go_term_mode = "split"
+let g:go_term_height = 10
+"autocmd FileType go nmap <leader>r :w<CR>:split <bar> terminal go run %<CR>
+autocmd FileType go nmap <leader>r :GoRun<CR>
+" highlights the variable in the file for you..
+"let g:go_auto_sameids = 1
+" auto import...
+let g:go_fmt_command = "goimports"
+" automatic type info on cursor
+let g:go_auto_type_info = 1
+let g:go_snippet_engine = "neosnippet"
+au Filetype go nmap <leader>ga <Plug>(go-alternate-edit)
+au Filetype go nmap <leader>gah <Plug>(go-alternate-split)
+au Filetype go nmap <leader>gav <Plug>(go-alternate-vertical)
+au FileType go nmap <F10> :GoTest -short<cr>
+" }}}
+"
+" NEOSNIPPET
+" Plugin key-mappings.
+" Note: It must be "imap" and "smap". It uses <Plug> mappings.
+imap <C-k> <Plug>(neosnippet_expand_or_jump)
+smap <C-k> <Plug>(neosnippet_expand_or_jump)
+xmap <C-k> <Plug>(neosnippet_expand_target)
+" SuperTab like snippets behavior.
+" Note: It must be "imap" and "smap". It uses <Plug> mappings.
+"imap <expr><TAB>
+" \ pumvisible() ? "\<C-n>" :
+" \ neosnippet#expandable_or_jumpable() ?
+" \ "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
+smap <expr><TAB> neosnippet#expandable_or_jumpable() ?
+\ "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
+
+" For conceal markers.
+if has('conceal')
+ set conceallevel=2 concealcursor=niv
+endif
+"END OF NEOSNIPPET
+"
+" ultisnips... {{{
+"inoremap <silent><expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
+"let g:UltiSnipsExpandTrigger="<tab>"
+"let g:UltiSnipsSnippetsDir = "/home/lemon/dotfiles/Ultisnips"
+"let g:UltiSnipsSnippetDirectories=["/home/lemon/dotfiles/Ultisnips"]
+"" let g:UltiSnipsJumpForwardTrigger="<c-n>"
+"" let g:UltiSnipsJumpBackwardTrigger="<c-p>"
+"let g:UltiSnipsJumpForwardTrigger="<c-j>"
+"let g:UltiSnipsJumpBackwardTrigger="<c-k>"
+" }}}
+"
+" yapf - format python code (https://github.com/google/yapf)...{{{
+map <leader>y :call yapf#YAPF()<cr>
+imap <leader>y :call yapf#YAPF()<cr>
+"autocmd FileType python nnoremap <leader>yy :0,$!yapf<Cr><C-o>
+" ...}}}
+"
+" isort - sort python imports (https://github.com/timothycrosley/isort) ...{{{
+let maplocalleader = "\\"
+autocmd FileType python nnoremap <LocalLeader>j :!isort %<CR><CR>
+" ...}}}
+"
+" Tabs, spaces, wrapping ...{{{
+set tabstop=4
+set shiftwidth=4
+set shiftround
+set softtabstop=4
+set expandtab
+set tw=79 " width of document(used by gd)
+set nowrap "don't automatically wrap on load
+set formatoptions=qrn1j
+set fo-=t " don't automatically wrap text when typing
+"set colorcolumn=+1
+" ...}}}
+"
+" Enable folding ...{{{
+set foldmethod=manual
+set foldlevel=99
+"...}}}
+"
+" Pymode stuff ...{{{
+let g:pymode = 1
+let g:pymode_options_colorcolumn = 0
+
+" Python 3 syntax
+let g:pymode_python = 'python3'
+
+let g:pymode_rope = 1
+let g:pymode_rope_completion = 0
+let g:pymode_rope_complete_on_dot = 0
+let g:pymode_rope_organize_imports_bind = '<C-c>ro'
+let g:pymode_rope_enable_autoimport = 0
+
+" Set quickfix window
+let g:pymode_quickfix_minheight = 3
+let g:pymode_quickfix_maxheight = 3
+
+" Sort indentation
+let g:pymode_indent = 1
+
+" Documentation
+let g:pymode_doc = 0
+"let g:pymode_doc_key = 'K'
+
+"Linting
+let g:pymode_lint = 0
+let g:pymode_lint_checker = "flake8"
+" Auto check on save
+let g:pymode_lint_write = 0
+
+" Support virtualenv
+let g:pymode_virtualenv = 1
+let g:pymode_virtualenv_path = $VIRTUAL_ENV
+
+"Enable breakpoints plugin
+let g:pymode_breakpoint = 1
+let g:pymode_breakpoint_bind = '<leader>b'
+let g:pymode_breakpoint_cmd = 'breakpoint()'
+"let g:pymode_breakpoint_cmd = 'from pdb import set_trace; set_trace()'
+
+" more debug - this probably does pudb if you have that instead of ipdb
+" map <Leader>b Oimport ipdb; ipdb.set_trace() # BREAKPOINT<C-c>
+
+" syntax highlighting
+let g:pymode_syntax = 0
+let g:pymode_syntax_all = 1
+let g:pymode_syntax_indent_errors = g:pymode_syntax_all
+let g:pymode_syntax_space_errors = g:pymode_syntax_all
+
+" Don't autofold code
+let g:pymode_folding = 0
+
+" Rope rename
+let g:pymode_rope_rename_bind = '<C-c>rr'
+
+" Rope extract variable/method
+let g:pymode_rope_extract_method_bind = '<C-c>rm'
+let g:pymode_rope_extract_variable_bind = '<C-c>rl'
+
+
+" SimplyFold config
+let g:SimpylFold_docstring_preview=1 " docstrings for folded code
+
+let python_highlight_all=1
+" ...}}}
+"
+" Line return (make sure Vim goes where you left it ...{{{
+" Make sure Vim returns to the same line when you reopen a file.
+augroup line_return
+ au!
+ au BufReadPost *
+ \ if line("'\"") > 0 && line("'\"") <= line("$") |
+ \ execute 'normal! g`"zvzz' |
+ \ endif
+augroup END
+"}}}
+"
+"
+" Backups ...{{{
+set undodir=~/.nvim-tmp/tmp/undo// "undo files
+set backupdir=~/.nvim-tmp/tmp/backup// " backups
+set directory=~/.nvim-tmp/tmp/swap// " swap files
+set backup " enable backups
+"}}}
+"
+" Highlight VCS conflict markers ...{{{
+match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$'
+"}}}
+"
+" Searching and movement ...{{{
+nnoremap / /\v
+vnoremap / /\v
+set ignorecase
+set smartcase
+set incsearch
+set showmatch
+set hlsearch
+set gdefault
+set scrolloff=3
+set sidescroll=1
+set sidescrolloff=10
+set virtualedit+=block
+nnoremap <leader><space> :noh<cr>:call clearmatches()<cr>
+
+" search for the word you're looking at
+nmap <M-k> :Ack! "\b<cword>\b" <CR>
+"nmap <Esc>k :Ack! "\b<cword>\b" <CR>
+nmap <M-S-k> :Ggrep! "\b<cword>\b" <CR>
+"nmap <Esc>K :Ggrep! "\b<cword>\b" <CR>
+
+nmap \x :cclose<CR>
+
+" Don't move on *
+nnoremap * *<c-o>
+
+" Easier to type move extreme left and right
+noremap H ^
+noremap L g_
+
+" Use ctrl-e and ctrl-a
+inoremap <c-a> <esc>I
+inoremap <c-e> <esc>A
+
+" open a Quickfix window for the last search
+nnoremap <silent> <leader>/ :execute 'vimgrep /'.@/.'/g %'<CR>:copen<CR>
+"}}}
+"
+" Ag! ... {{{
+nnoremap <leader>a :Ack!<space>
+let g:ackprg = 'ag --smart-case --nogroup --nocolor --column'
+" }}}
+"
+" Folding ... {{{
+" Enable folding with the spacebar
+nnoremap <space> za
+nnoremap <leader>fm :set foldmethod=manual<CR>
+" Make zO recursively open whatever fold we're in, even if it's partially open.
+nnoremap zO zczO
+" Use ,z to "focus" the current fold
+nnoremap <leader>z zMzvzz
+" }}}
+"
+"" Quick Editing ...{{{
+nnoremap <leader>ev <C-w>s<C-w>j<C-w>L:e $MYVIMRC<cr>
+" }}}
+"
+" Convenience mappings ... {{{
+" No more help key.
+noremap <F1> :checktime<cr>
+inoremap <F1> <esc>:checktime<cr>
+
+" Kill window
+"nnoremap <leader>K :q<cr>
+
+" Wrap
+nnoremap <leader>W :set wrap!<cr>
+
+" Change case
+noremap <C-u> gUiw
+inoremap <C-u> <esc> gUiwea
+
+" Substitute
+nnoremap <leader>su :%s//<left>
+nnoremap <Leader>s :%s/<C-r><C-w>//g<Left><Left>
+"
+" Emacs bindings in command line mode
+cnoremap <c-a> <home>
+cnoremap <c-e> <end>
+
+" Turn off vimdiff
+nnoremap <leader>D :diffoff!<cr>
+
+" Formatting, like Textmate
+nnoremap Q gqip
+
+" Easier linewise reselection
+nnoremap <leader>V V`]
+
+" Split line (colleague of Join lines)
+nnoremap S i<cr><esc><right>
+
+" Source the current line
+vnoremap <leader>S y:execute @@<cr>:echo 'Sourced selection.'<cr>
+nnoremap <leader>S ^vg_y:execute @@<cr>:echo 'Sourced line.'<cr>
+
+" Select (charwise) the contents of the current line, excluding indentation.
+" Great for pasting Python lines into REPLs.
+nnoremap vv ^vg_
+" }}}
+"
+" Ack motions ... {{{
+
+" Motions to Ack for things. Works with pretty much everything, including:
+"
+" w, W, e, E, b, B, t*, f*, i*, a*, and custom text objects
+"
+" Awesome.
+"
+" Note: If the text covered by a motion contains a newline it won't work. Ack
+" searches line-by-line.
+
+nnoremap <silent> <leader>B :set opfunc=<SID>AckMotion<CR>g@
+xnoremap <silent> <leader>B :<C-U>call <SID>AckMotion(visualmode())<CR>
+
+"nnoremap <bs> :Ack! '\b<c-r><c-w>\b'<cr>
+xnoremap <silent> <bs> :<C-U>call <SID>AckMotion(visualmode())<CR>
+
+function! s:CopyMotionForType(type)
+ if a:type ==# 'v'
+ silent execute "normal! `<" . a:type . "`>y"
+ elseif a:type ==# 'char'
+ silent execute "normal! `[v`]y"
+ endif
+endfunction
+
+function! s:AckMotion(type) abort
+ let reg_save = @@
+
+ call s:CopyMotionForType(a:type)
+
+ execute "normal! :Ack! --literal " . shellescape(@@) . "\<cr>"
+
+ let @@ = reg_save
+endfunction
+" }}}
+"
+" Mutt ... {{{
+
+augroup ft_muttrc
+ au!
+
+ au BufRead,BufNewFile *.muttrc set ft=muttrc
+
+ au FileType muttrc setlocal foldmethod=marker foldmarker={{{,}}}
+augroup END
+
+" }}}
+"
+" perldoc ... {{{
+let g:perldoc_split_modifier = '10v'
+"}}}
+"
+" vim-fugitive ... {{{
+" prevent buffer build-up
+autocmd BufReadPost fugitive://* set bufhidden=delete
+"}}}
+"
+" ALE statusline ...{{{
+"set statusline+=%{ALEGetStatusLine()}
+"let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '• ok']
+"let g:ale_linters = {'python': ['flake8'],}
+"...}}}
+"
+" ale setting..{{{
+"let g:ale_lint_on_text_changed = 'never'
+
+" black config ...{{{
+"let g:black_virtualenv = "/home/lemon/.virtualenvs/black-for-vim/"
+"nmap <leader>l :Black<CR>
+" LET'S RUN VIRTUALENV BLACK ON SAVE!
+"autocmd BufWritePre *.py execute ':Black'
+"let g:black_virtualenv = $VIRTUAL_ENV
+" }}}
+
+
+let g:ale_enabled = 1
+let g:ale_sign_column_always = 1
+let g:ale_open_list = 0
+let g:ale_set_highlights = 1
+let g:ale_set_signs = 1
+let g:ale_set_loclist = 0
+let g:ale_set_quickfix = 1
+let g:ale_echo_cursor = 1
+let g:ale_echo_msg_error_str = 'Error'
+let g:ale_echo_msg_format = '%linter% - %code: %%s'
+let g:ale_loclist_msg_format = '%linter% - %code: %%s'
+let g:ale_echo_msg_warning_str = 'Warning'
+"let g:ale_linters = {'python': ['flake8', 'mypy', 'pyls', 'pylint'],
+"\ 'ocaml': ['merlin'],
+" \}
+let g:ale_linters = {'python': ['flake8', 'mypy'],
+\ 'ocaml': ['merlin'],
+\ 'cpp': ['clang'],
+\ 'go': ['gometalinter', 'gofmt'],
+ \}
+"let g:ale_linters_ignore = {'python': ['pyls']}
+let g:ale_fixers = {'python': ['isort']} " we want to run black manually
+let g:ale_python_mypy_ignore_invalid_syntax = 1
+let g:ale_python_mypy_executable = 'mypy'
+let g:ale_python_mypy_options = '--config-file mypy.ini'
+" let g:ale_sign_error = '>>'
+let g:ale_sign_warning = '--'
+let g:ale_fix_on_save = 1
+let g:ale_linters_explicit = 0
+
+
+" Mappings in the style of unimpaired-next
+nmap [W <Plug>(ale_first)
+nmap [w <Plug>(ale_previous)
+nmap ]w <Plug>(ale_next)
+nmap ]W <Plug>(ale_last)
+" }}}
+
+"
+" More Haskell stuff - May 2017 ...{{{
+let g:haskell_enable_quantification = 1 " to enable highlighting of `forall`
+let g:haskell_enable_recursivedo = 1 " to enable highlighting of `mdo` and `rec`
+let g:haskell_enable_arrowsyntax = 1 " to enable highlighting of `proc`
+let g:haskell_enable_pattern_synonyms = 1 " to enable highlighting of `pattern`
+let g:haskell_enable_typeroles = 1 " to enable highlighting of type roles
+let g:haskell_enable_static_pointers = 1 " to enable highlighting of `static`
+let g:haskell_backpack = 1 " to enable highlighting of backpack keywords}
+let g:haskell_indent_if = 3
+let g:haskell_indent_case = 2
+let g:haskell_indent_let = 4
+let g:haskell_indent_where = 6
+let g:haskell_indent_before_where = 2
+let g:haskell_indent_after_bare_where = 2
+let g:haskell_indent_do = 3
+let g:haskell_indent_in = 1
+let g:haskell_indent_guard = 2
+"}}}
+"
+" Bufexplorer config ... {{{
+let g:bufExplorerDefaultHelp=1 " Show default help.
+let g:bufExplorerShowNoName=1 " Show "No Name" buffers.
+let g:bufExplorerShowUnlisted=1 " Show unlisted buffers.
+"}}}
+"
+" Django ... {{{
+augroup ft_django
+ au!
+
+ au BufNewFile,BufRead urls.py setlocal nowrap
+ au BufNewFile,BufRead urls.py normal! zR
+ au BufNewFile,BufRead dashboard.py normal! zR
+ au BufNewFile,BufRead local_settings.py normal! zR
+
+ au BufNewFile,BufRead admin.py setlocal filetype=python.django
+ au BufNewFile,BufRead urls.py setlocal filetype=python.django
+ au BufNewFile,BufRead models.py setlocal filetype=python.django
+ au BufNewFile,BufRead views.py setlocal filetype=python.django
+ au BufNewFile,BufRead settings.py setlocal filetype=python.django
+ au BufNewFile,BufRead settings.py setlocal foldmethod=marker
+ au BufNewFile,BufRead forms.py setlocal filetype=python.django
+ au BufNewFile,BufRead common_settings.py setlocal filetype=python.django
+ au BufNewFile,BufRead common_settings.py setlocal foldmethod=marker
+augroup END
+
+" vim-markdown ...{{{
+let g:vim_markdown_folding_disabled=1
+set foldenable
+let g:vim_markdown_initial_foldlevel=1
+let g:vim_markdown_no_default_key_mappings=1
+let g:vim_markdown_math=1
+let g:vim_markdown_frontmatter=1
+"}}}
+"
+" get rid of annoying Press ENTER prompts etc ...{{{
+"set shortmess=atI
+"}}}
+"
+" Remap movement in windows ...{{{
+map <c-j> <c-w>j
+map <c-k> <c-w>k
+map <c-l> <c-w>l
+map <c-h> <c-w>h
+"}}}
+"
+nnoremap <Leader>c :set cursorline!<CR>
+":nnoremap <Leader>c :set cursorline! cursorcolumn!<CR>
+"}}}
+"
+" General python properness ...{{{
+autocmd FileType python set sw=4
+autocmd FileType python set ts=4
+autocmd FileType python set sts=4
+"}}}
+"
+" Escape sudo heck ...{{{
+cmap w!! %!sudo tee > /dev/null %
+"}}}
+"
+" Colorscheme ...{{{
+"let g:github_colors_soft = "1
+" from https://github.com/thesheff17/youtube/blob/master/vim/vimrc
+"color wombat256mod
+"color Tomorrow-Night-Bright
+"color monokai-phoenix
+"colorscheme github
+"colorscheme gruvbox
+"color afterglow
+colorscheme PaperColor
+"
+" if we are using default colorscheme, you want to switch off horrid
+" grey gutter colour
+highlight clear SignColumn
+"
+
+" Cursor and column highlighting ...{{{
+" hi CursorLine cterm=NONE ctermbg=darkred ctermfg=white guibg=#4b5260 guifg=white
+
+" use guibg and guifg because I have set termguicolors switched on in this file
+" The pythonSelf is a pymode thing...
+"hi pythonSelf ctermfg=68 guifg=#5f87d7 cterm=bold gui=bold
+"hi pythonSelf ctermfg=16 guifg=#5f87d7 cterm=bold gui=bold
+"hi pythonNumber ctermfg=16 guifg=#aa4aef cterm=bold gui=bold
+"hi pythonFloat ctermfg=16 guifg=#aa4aef cterm=bold gui=bold
+"hi pythonHexNumber ctermfg=16 guifg=#aa4aef cterm=bold gui=bold
+"
+" my todo.todo... {{
+autocmd BufNewFile,BufRead *.todo set syntax=markdown
+"autocmd BufWritePost *.todo !todo-push
+nmap <F2> a<C-R>=strftime("%c")<CR><Esc>
+"let @d=':r! date _€kb-I i€kb ($a)0"+dd:!xlcip€kb€kb€kb€kbclip -o >> /home/lemon/todo/done.todo '
+let @d='0$a(€k2a)0"+dd:!xlcip€kb€kb€kb€kbclip -o >> /home/lemon/todo/done.todo '
+" ...}}
+
+
+" Grepper ...{{{
+nmap gs <plug>(GrepperOperator)
+xmap gs <plug>(GrepperOperator)
+" ...}}}
+"
+" FZF ...{{{
+" This is the default extra key bindings
+let g:fzf_action = {
+ \ 'ctrl-t': 'tab split',
+ \ 'ctrl-x': 'split',
+ \ 'ctrl-v': 'vsplit' }
+
+" Default fzf layout
+" - down / up / left / right
+let g:fzf_layout = { 'down': '~40%' }
+
+" Customize fzf colors to match your color scheme
+let g:fzf_colors =
+\ { 'fg': ['fg', 'Normal'],
+ \ 'bg': ['bg', 'Normal'],
+ \ 'hl': ['fg', 'Comment'],
+ \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
+ \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
+ \ 'hl+': ['fg', 'Statement'],
+ \ 'info': ['fg', 'PreProc'],
+ \ 'prompt': ['fg', 'Conditional'],
+ \ 'pointer': ['fg', 'Exception'],
+ \ 'marker': ['fg', 'Keyword'],
+ \ 'spinner': ['fg', 'Label'],
+ \ 'header': ['fg', 'Comment'] }
+" {{{ More fzf settings
+" (https://github.com/zenbro/dotfiles/blob/master/.nvimrc#L151-L187)
+ let g:fzf_nvim_statusline = 0 " disable statusline overwriting
+
+ nnoremap <C-p> :<C-u>FZF<CR>
+ nnoremap <leader><C-p> :<C-u>FZF!<CR>
+ nnoremap ; :Buffers<CR>
+ nnoremap <leader>t :Files<CR>
+ nnoremap <leader>o :Tags<CR>
+ nnoremap <leader>h :History<CR>
+ nnoremap <silent> <leader>0 :Files<CR>
+ nnoremap <silent> <leader>A :Windows<CR>
+ nnoremap <silent> <leader>; :BLines<CR>
+ nnoremap <silent> <leader>l :Lines<CR>
+" nnoremap <silent> <leader># :Lines<CR>
+ nnoremap <silent> <leader>o :BTags<CR>
+" command history is :History:
+ nnoremap <silent> <leader>? :History:<CR>
+ nnoremap <silent> <leader>/ :execute 'Ag ' . input('Ag/')<CR>
+" nnoremap <silent> <leader>. :AgIn #
+" nnoremap <silent> <leader>a :Buffers<CR>
+" nnoremap <silent> <leader>O :Tags<CR>
+ nnoremap <silent> <leader>P :call SearchWordWithAg()<CR>
+ vnoremap <silent> <leader>P :call SearchVisualSelectionWithAg()<CR>
+" nnoremap <silent> <leader>gl :Commits<CR>
+" nnoremap <silent> <leader>ga :BCommits<CR>
+ nnoremap <silent> <leader>ft :Filetypes<CR>
+
+ imap <C-x><C-f> <plug>(fzf-complete-file-ag)
+ imap <C-x><C-l> <plug>(fzf-complete-line)
+
+ function! SearchWordWithAg()
+ execute 'Ag' expand('<cword>')
+ endfunction
+
+ function! SearchVisualSelectionWithAg() range
+ let old_reg = getreg('"')
+ let old_regtype = getregtype('"')
+ let old_clipboard = &clipboard
+ set clipboard&
+ normal! ""gvy
+ let selection = getreg('"')
+ call setreg('"', old_reg, old_regtype)
+ let &clipboard = old_clipboard
+ execute 'Ag' selection
+ endfunction
+
+" function! SearchWithAgInDirectory(...)
+" call fzf#vim#ag(join(a:000[1:], ' '), extend({'dir': a:1}, g:fzf#vim#default_layout))
+" endfunction
+" command! -nargs=+ -complete=dir AgIn call SearchWithAgInDirectory(<f-args>)
+ " }}}
+
+" Enable per-command history.
+" CTRL-N and CTRL-P will be automatically bound to next-history and
+" previous-history instead of down and up. If you don't like the change,
+" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.
+let g:fzf_history_dir = '~/.local/share/fzf-history'
+"
+" Mapping selecting mappings
+nmap <leader><tab> <plug>(fzf-maps-n)
+xmap <leader><tab> <plug>(fzf-maps-x)
+omap <leader><tab> <plug>(fzf-maps-o)
+
+" Insert mode completion
+imap <c-x><c-k> <plug>(fzf-complete-word)
+imap <c-x><c-f> <plug>(fzf-complete-path)
+imap <c-x><c-j> <plug>(fzf-complete-file-ag)
+imap <c-x><c-l> <plug>(fzf-complete-line)
+
+" Advanced customization using autoload functions
+inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'left': '15%'}
+" ...}}}
+"
+" Ocaml/merlin
+"let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
+"execute "set rtp+=" . g:opamshare . "/merlin/vim"
+"set rtp^="/home/lemon/.opam/4.06.1/share/ocp-indent/vim"
+"
+
+" Search from git root via :Rag (Root Ag)
+" Thanks! https://github.com/fortes/dotfiles/blob/7ba6ea651edde8fbc24fdf9df52ba06f7e956efc/stowed-files/nvim/.vimrc
+" :Rag - hidden preview enabled with "?" key
+" :Rag! - fullscreen and preview window above
+
+" Change to git root of current file (if in a repo)
+function! FindGitRootCD()
+ let root = systemlist('git -C ' . expand('%:p:h') . ' rev-parse --show-toplevel')[0]
+ if v:shell_error
+ return ''
+ else
+ return {'dir': root}
+ endif
+endfunction
+
+
+function! GitRootCD()
+ let result = FindGitRootCD()
+ if type(result) == type({})
+ execute 'lcd' fnameescape(result['dir'])
+ echo 'Now in '.result['dir']
+ else
+ echo 'Not in git repo!'
+ endif
+endfunction
+
+command! GitRootCD :call GitRootCD()
+
+command! -bang -nargs=* Rag
+ \ call GitRootCD() | call fzf#vim#ag(<q-args>,
+ \ <bang>0 ? fzf#vim#with_preview('up:60%', '?')
+ \ : fzf#vim#with_preview('right:50%:hidden', '?'),
+ \ <bang>0)
+
+" Use fuzzy searching for K & Q, select items to go into quickfix
+nnoremap L :Rag! <C-R><C-W><cr>
+vnoremap L :<C-u>norm! gv"sy<cr>:silent! Rag! <C-R>s<cr>
+nnoremap Q :Rag!<SPACE>
+
+"highlight ColorColumn ctermbg=0
+highlight NonText cterm=NONE
diff --git a/init_to_disable_nvim_plugs.vim b/init_to_disable_nvim_plugs.vim
new file mode 100644
index 0000000..e9abef5
--- /dev/null
+++ b/init_to_disable_nvim_plugs.vim
@@ -0,0 +1 @@
+syntax on
diff --git a/mailcap b/mailcap
new file mode 100644
index 0000000..032b0a9
--- /dev/null
+++ b/mailcap
@@ -0,0 +1,76 @@
+# Example mailcap file for Reddit Terminal Viewer
+# https://github.com/michael-lazar/rtv/
+#
+# Copy the contents of this file to {HOME}/.mailcap, or point to using $MAILCAPS
+# Then launch RTV using the --enable-media flag. All shell commands defined in
+# this file depend on external programs that must be installed on your system.
+#
+# HELP REQUESTED! If you come up with your own commands (especially for OS X)
+# and would like to share, please post an issue on the GitHub tracker and we
+# can get them added to this file as references.
+#
+#
+# Mailcap 101
+# - The first entry with a matching MIME type will be executed, * is a wildcard
+# - %s will be replaced with the image or video url
+# - Add ``test=test -n "$DISPLAY"`` if your command opens a new window
+# - Add ``needsterminal`` for commands that use the terminal
+# - Add ``copiousoutput`` for commands that dump text to stdout
+
+###############################################################################
+# Commands below this point will open media in a separate window without
+# pausing execution of RTV.
+###############################################################################
+
+# Feh is a simple and effective image viewer
+# Note that rtv returns a list of urls for imgur albums, so we don't put quotes
+# around the `%s`
+image/x-imgur-album; feh -g 640x480 %s; test=test -n "$DISPLAY"
+image/gif; mpv '%s' --autofit 640x480 --loop=inf; test=test -n "$DISPLAY"
+image/*; feh -g 640x480 '%s'; test=test -n "$DISPLAY"
+
+# Youtube videos are assigned a custom mime-type, which can be streamed with
+# vlc or youtube-dl.
+video/x-youtube; vlc '%s' --width 640 --height 480; test=test -n "$DISPLAY"
+video/x-youtube; mpv --ytdl-format=best '%s' --autofit 640x480; test=test -n "$DISPLAY"
+
+# Mpv is a simple and effective video streamer
+video/*; mpv '%s' --autofit 640x480 --loop=inf; test=test -n "$DISPLAY"
+
+###############################################################################
+# Commands below this point will attempt to display media directly in the
+# terminal when X is not available.
+###############################################################################
+
+# View images directly in your terminal with iTerm2
+# curl -L https://iterm2.com/misc/install_shell_integration_and_utilities.sh | bash
+# image/*; curl -s %s | ~/.iterm2/imgcat && read -n 1; needsterminal
+
+# View true images in the terminal, supported by rxvt-unicode, xterm and st
+# Requires the w3m-img package
+# image/*; w3m -o 'ext_image_viewer=off' '%s'; needsterminal
+
+# Don't have a solution for albums yet
+image/x-imgur-album; echo
+
+# 256 color images using half-width unicode characters
+# Much higher quality that img2txt, but must be built from source
+# https://github.com/rossy/img2xterm
+image/*; curl -s '%s' | convert -resize 80x80 - jpg:/tmp/rtv.jpg && img2xterm /tmp/rtv.jpg; needsterminal; copiousoutput
+
+# Display images in classic ascii using img2txt and lib-caca
+image/*; curl -s '%s' | convert - jpg:/tmp/rtv.jpg && img2txt -f utf8 /tmp/rtv.jpg; needsterminal; copiousoutput
+
+# Libreoffice documents
+application/vnd.openxmlformats-officedocument.wordprocessingml.document; libreoffice %s;
+
+# Full motion videos - requires a framebuffer to view
+video/x-youtube; mpv -vo drm -quiet '%s'; needsterminal
+video/*; mpv -vo drm -quiet '%s'; needsterminal
+
+# Ascii videos
+# video/x-youtube; youtube-dl -q -o - '%s' | mplayer -cache 8192 -vo caca -quiet -; needsterminal
+# video/*; wget '%s' -O - | mplayer -cache 8192 -vo caca -quiet -; needsterminal
+
+text/html; w3m %s; nametemplate=%s.html
+text/html; w3m -dump %s; nametemplate=%s.html; copiousoutput
diff --git a/mplayer/config b/mplayer/config
new file mode 100644
index 0000000..c6853e5
--- /dev/null
+++ b/mplayer/config
@@ -0,0 +1,4 @@
+# Write your default config options here!
+# use Jack
+#ao=jack
+
diff --git a/mps-youtube/config b/mps-youtube/config
new file mode 100644
index 0000000..e776c79
--- /dev/null
+++ b/mps-youtube/config
Binary files differ
diff --git a/mps-youtube/playlist_v2 b/mps-youtube/playlist_v2
new file mode 100644
index 0000000..0a47446
--- /dev/null
+++ b/mps-youtube/playlist_v2
Binary files differ
diff --git a/mps-youtube/playlists/good_techno.m3u b/mps-youtube/playlists/good_techno.m3u
new file mode 100644
index 0000000..1e2f543
--- /dev/null
+++ b/mps-youtube/playlists/good_techno.m3u
@@ -0,0 +1,68 @@
+#EXTM3U
+
+#EXTINF:488,Matador - Stanleys (Anna Remix)
+https://www.youtube.com/watch?v=rtSIUjqQbA4
+#EXTINF:491,Kollektiv Turmstrasse - Sorry I'm Late (Original Mix)
+https://www.youtube.com/watch?v=dOYjCxGf-K0
+#EXTINF:468,Kollektiv Turmstrasse - Sorry I Am Late (Pig&Dan Remix)
+https://www.youtube.com/watch?v=zEedxPCXPQE
+#EXTINF:392,Pierre Pienaar - Aroha [Extended] OUT NOW
+https://www.youtube.com/watch?v=H5kNrY_tDso
+#EXTINF:569,Victor Ruiz - Nevermind (Original Mix)
+https://www.youtube.com/watch?v=wmouuas1Eos
+#EXTINF:415,Vince Watson - Speaker Freaker (Original Mix)
+https://www.youtube.com/watch?v=Dfr07_CCCjw
+#EXTINF:433,Victor Ruiz - Jaws
+https://www.youtube.com/watch?v=f4Beqx5oC-s
+#EXTINF:443,Lunatique Sublime - Slamming [RBL049]
+https://www.youtube.com/watch?v=ccytCbCV-Vo
+#EXTINF:536,Christian Smith - Blast Off (Victor Ruiz Remix)
+https://www.youtube.com/watch?v=nfSdLrMU-u8
+#EXTINF:486,UMEK - Fonon (Original Mix) [1605-229]
+https://www.youtube.com/watch?v=j5hGwIh48Fw
+#EXTINF:384,Maceo Plex - The Replicant V1 (Original Mix) [Ellum]
+https://www.youtube.com/watch?v=xTbEpkiGWUU
+#EXTINF:437,LAKAC - Tunnel (Vontech Remix) [I AM DIFFERENT]
+https://www.youtube.com/watch?v=9_WBro_VD20
+#EXTINF:154,Metodi Hristov - Kind Of Blue (Original Mix) [Terminal M]
+https://www.youtube.com/watch?v=z7iIAJlg0Uo
+#EXTINF:3690,Mark Rey - Tainted Souls Vol.25
+https://www.youtube.com/watch?v=tWsC59HjEbM
+#EXTINF:454,Enrico Sangiuliano – Moon Rocks (Original Mix) [Drumcode]
+https://www.youtube.com/watch?v=BQFca9ceSho
+#EXTINF:450,Silvia Trix - Pirates (Origina Mix) [Eclipse Recordings]
+https://www.youtube.com/watch?v=MwW3LZGRHek
+#EXTINF:448,Reinier Zonneveld - EHT [Stil Vor Talent]
+https://www.youtube.com/watch?v=O8dv9IoXatI
+#EXTINF:304,Lunatique Sublime - Behind The Side (Original Mix) [Black Square Recordings]
+https://www.youtube.com/watch?v=0tAv0tQURD4
+#EXTINF:422,Slam - Ecclesiastic
+https://www.youtube.com/watch?v=iD1qO3SkNhM
+#EXTINF:486,BPC328 Ellen Allien - Landing XX
+https://www.youtube.com/watch?v=rN6r6qiQsEI
+#EXTINF:526,Secret Cinema & Egbert – Maximaal (Original Mix) [Drumcode]
+https://www.youtube.com/watch?v=vFz1XneVV2k
+#EXTINF:454,Enrico Sangiuliano - Moon Rocks [Drumcode]
+https://www.youtube.com/watch?v=2hsoXTZbhBo
+#EXTINF:401,Mike Shiver vs Matias Lehtola - Slacker (Original Mix)
+https://www.youtube.com/watch?v=2yOTLirEUEk
+#EXTINF:387,Pierre Pienaar - Aroha (Original Mix)
+https://www.youtube.com/watch?v=8nrMrVyWSpw
+#EXTINF:360,Bak - Nebula
+https://www.youtube.com/watch?v=ZiqpocJvIhE
+#EXTINF:428,Tom Hutt - Just In Time (Original Mix)
+https://www.youtube.com/watch?v=QHL1NyDNaKM
+#EXTINF:402,Adrian Oblanca - Evoke ( Original Mix )
+https://www.youtube.com/watch?v=tm6Xvo1CckM
+#EXTINF:399,MasterManiac, StoKed - Pressure (Original Mix) [Lethal Bass]
+https://www.youtube.com/watch?v=7Q_xq-TI8Ac
+#EXTINF:432,Oxia - Domino
+https://www.youtube.com/watch?v=FO566BKY2Jc
+#EXTINF:430,Noir & Olivier Giacomotto ft Hendrik Burkhard - Blackrays (Original Mix) - Suara
+https://www.youtube.com/watch?v=MjvoTxOGv4s
+#EXTINF:198,RIOT059 - Infaam Konijn - Rings Of Saturn (Aitor Ronda Remix) [Riot Recordings]
+https://www.youtube.com/watch?v=Xp3TH6WRVFo
+#EXTINF:398,Joe Red - Couldn't Find A Better Name (Original Mix) (Beatfreak Recordings)
+https://www.youtube.com/watch?v=3nlL2mlMArg
+#EXTINF:460,Gabriel Padrevita - Hass (Original Mix)
+https://www.youtube.com/watch?v=QAaUQMgs6ak
diff --git a/mps-youtube/playlists/studymix.m3u b/mps-youtube/playlists/studymix.m3u
new file mode 100644
index 0000000..85184dc
--- /dev/null
+++ b/mps-youtube/playlists/studymix.m3u
@@ -0,0 +1,4 @@
+#EXTM3U
+
+#EXTINF:29233,8 Hour Study Mix: "Trance to Study By: All-Nighter"
+https://www.youtube.com/watch?v=Zk26FUe38y0
diff --git a/mpv/mpv.conf b/mpv/mpv.conf
new file mode 100644
index 0000000..74c8569
--- /dev/null
+++ b/mpv/mpv.conf
@@ -0,0 +1,6 @@
+# should be symlinked from ~/.config/mpv/mpv.conf
+# use Jack
+#ao=jack
+ao=pulse
+save-position-on-quit=yes
+ytdl-format=bestvideo[height <= 1080]+bestaudio/best
diff --git a/msmtprc b/msmtprc
new file mode 100644
index 0000000..cd42308
--- /dev/null
+++ b/msmtprc
@@ -0,0 +1,28 @@
+account matthewlemon
+host mail.messagingengine.com
+from matt@matthewlemon.com
+tls on
+tls_certcheck off
+tls_starttls off
+#tls_trust_file /etc/ssl/certs/ca-certificates.crt
+port 465
+auth on
+user matthewlemon@fastmail.fm
+#passwordeval python2 -c "import keyring; print keyring.get_password('fastmail', 'matthewlemon')"
+#passwordeval pass Email/fastmail
+#passwordeval gpg --no-tty -q -d /home/lemon/.password-store/Email/fastmail.gpg
+passwordeval gpg -d /home/lemon/.password-store/Email/fastmail.gpg
+logfile ~/.msmtp.log
+
+account gmail
+from matthew.lemon@gmail.com
+user matthew.lemon@gmail.com
+host smtp.gmail.com
+port 587
+protocol smtp
+auth on
+tls on
+tls_trust_file /etc/ssl/certs/ca-certificates.crt
+passwordeval pass Email/gmail-application
+
+account default : matthewlemon
diff --git a/mutt/aliases b/mutt/aliases
new file mode 100644
index 0000000..fab124a
--- /dev/null
+++ b/mutt/aliases
@@ -0,0 +1,8 @@
+alias work Matthew Lemon (DfT) <matthew.lemon@dft.gov.uk>
+alias joanna Joanna Lemon <joannalemon1@gmail.com>
+alias maw Clare Lemon <clarelemon51@gmail.com>
+alias tam Tim Lemon <tjlemon43@gmail.com>
+alias henry Gavin Macfarlane <gavmacfarlane@gmail.com>
+alias dan Daniel Barwick <danbarwick@gmail.com>
+alias neil Neil Byrne <nbyrne@wandsworth.gov.uk>
+alias Keiron Keiron Hart <keironh@googlemail.com>
diff --git a/mutt/colours b/mutt/colours
new file mode 100644
index 0000000..2f57890
--- /dev/null
+++ b/mutt/colours
@@ -0,0 +1,94 @@
+## Theme kindly inspired from
+## http://nongeekshandbook.blogspot.ie/2009/03/mutt-color-configuration.html
+
+
+## Colours for items in the index
+#color index blue default ~N
+color index brightblue default ~N
+color index brightred black ~O
+color index brightyellow black ~F
+color index black green ~T
+color index brightred black ~D
+color index magenta default ~Q # replied-to
+#color index black yellow ~U
+color index red default ~T
+mono index bold ~N
+mono index bold ~F
+mono index bold ~T
+mono index bold ~D
+
+## Highlights inside the body of a message.
+
+## URLs
+color body green black "(http|ftp|news|telnet|finger)://[^ \"\t\r\n]*"
+color body green black "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+"
+color body green black "(http|ftp|news|telnet|finger)://[^ \"\t\r\n]*"
+color body green black "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+"
+mono body bold "(http|ftp|news|telnet|finger)://[^ \"\t\r\n]*"
+mono body bold "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+"
+
+## Email addresses.
+color body black green "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+"
+
+## Header
+color header green black "^from:"
+color header green black "^to:"
+color header green black "^cc:"
+color header green black "^date:"
+color header yellow black "^newsgroups:"
+color header yellow black "^reply-to:"
+color header brightcyan black "^subject:"
+color header red black "^x-spam-rule:"
+color header green black "^x-mailer:"
+color header yellow black "^message-id:"
+color header yellow black "^Organization:"
+color header yellow black "^Organisation:"
+color header yellow black "^User-Agent:"
+color header yellow black "^message-id: .*pine"
+color header yellow black "^X-Fnord:"
+color header yellow black "^X-WebTV-Stationery:"
+
+color header red black "^x-spam-rule:"
+color header green black "^x-mailer:"
+color header yellow black "^message-id:"
+color header yellow black "^Organization:"
+color header yellow black "^Organisation:"
+color header yellow black "^User-Agent:"
+color header yellow black "^message-id: .*pine"
+color header yellow black "^X-Fnord:"
+color header yellow black "^X-WebTV-Stationery:"
+color header yellow black "^X-Message-Flag:"
+color header yellow black "^X-Spam-Status:"
+color header yellow black "^X-SpamProbe:"
+color header red black "^X-SpamProbe: SPAM"
+
+## Coloring quoted text - coloring the first 7 levels:
+color quoted cyan black
+color quoted1 yellow black
+color quoted2 red black
+color quoted3 green black
+color quoted4 cyan black
+color quoted5 yellow black
+color quoted6 red black
+color quoted7 green black
+
+## Default color definitions
+#color hdrdefault white green
+color normal white default
+color signature brightmagenta black
+color indicator black cyan
+color attachment green black
+color error red black
+color message white black
+color search brightwhite magenta
+color status brightyellow blue
+color tree brightblue black
+#color tilde green black
+color bold brightyellow black
+#color underline magenta black
+color markers brightcyan black
+
+## Colour definitions when on a mono screen
+mono bold bold
+mono underline underline
+mono indicator reverse
diff --git a/mutt/colours-bak b/mutt/colours-bak
new file mode 100644
index 0000000..8c80ebf
--- /dev/null
+++ b/mutt/colours-bak
@@ -0,0 +1,69 @@
+# -*- muttrc -*-
+#
+# Colour settings for mutt.
+#
+# $Id: colours 6 2007-03-02 17:36:39Z vdanen $
+
+# Default colour definitions
+color normal white default
+color quoted yellow default
+color quoted1 green default
+color quoted2 white default
+color quoted3 yellow default
+color quoted4 green default
+color quoted5 white default
+
+color indicator black cyan
+color message yellow black
+color status yellow blue
+color error yellow red
+color attachment magenta default
+color signature red default
+color markers red yellow
+color tilde yellow black
+color search white red
+color tree green default
+color bold brightyellow default
+
+color hdrdefault cyan default
+color header green default '^From:'
+color header red default '^Subject:'
+color header yellow default '^(To|CC):.*vdanen'
+
+# Colours for items in the index
+color index cyan default ~N
+color index green default "~N (~x annvix\.org | ~h \"^In-[Rr]eply-[Tt]o: .*annvix\.org\")"
+color index green default "~N (~x linsec\.ca | ~h \"^In-[Rr]eply-[Tt]o: .*linsec\.ca\")"
+color index green default "~N (~x mandriva\.com | ~h \"^In-[Rr]eply-[Tt]o: .*mandriva\.com\")"
+color index red default ~F
+color index green default ~T
+color index brightwhite default ~D
+mono index bold ~N
+mono index bold ~F
+mono index bold ~T
+mono index bold ~D
+
+# Highlights inside the body of a message.
+
+# URLs
+color body brightgreen default "(http|https|ftp|news|telnet|finger)://[^ \">\t\r\n]*"
+color body brightgreen default "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+"
+color body brightgreen default "news:[^ \">\t\r\n]*"
+mono body bold "(http|https|ftp|news|telnet|finger)://[^ \">\t\r\n]*"
+mono body bold "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+"
+mono body bold "news:[^ \">\t\r\n]*"
+
+# email addresses
+color body brightcyan default "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+"
+mono body bold "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+"
+
+# Various smilies and the like
+color body yellow default "(^|[[:space:]])\\*[^[:space:]]+\\*([[:space:]]|$)" # *Bold* text.
+color body yellow default "(^|[[:space:]])_[^[:space:]]+_([[:space:]]|$)" # _Underlined_ text.
+color body yellow default "(^|[[:space:]])/[^[:space:]]+/([[:space:]]|$)" # /Italic/ text.
+
+# Colour definitions when on a mono screen
+mono bold bold
+mono underline underline
+mono indicator reverse
+mono header bold "^(From|Subject|X-Junked-Because|X-Virus-hagbard):"
diff --git a/mutt/mailcap b/mutt/mailcap
new file mode 100644
index 0000000..9a568c0
--- /dev/null
+++ b/mutt/mailcap
@@ -0,0 +1,23 @@
+# MS Word documents
+# DONT HAVE A SOLUTION YET: application/msword; ~/.mutt/view_attachment.sh %s "-" '/Applications/TextEdit.app'
+
+# Images
+image/jpg; ~/.mutt/view_attachment.sh %s jpg ristretto
+image/jpeg; ~/.mutt/view_attachment.sh %s jpg ristretto
+image/pjpeg; ~/.mutt/view_attachment.sh %s jpg gpicview
+image/png; ~/.mutt/view_attachment.sh %s png gpicview
+image/gif; ~/.mutt/view_attachment.sh %s gif gpicview
+
+# PDFs
+application/pdf; ~/.mutt/view_attachment.sh %s pdf evince
+
+# HTML
+#text/html; ~/.mutt/view_attachment.sh %s html w3m # try different
+text/html; w3m %s; nametemplate=%s.html
+text/html; w3m -dump %s; nametemplate=%s.html; copiousoutput
+
+# Plain Text
+text/plain; cat; copiousoutput; edit=$VISUAL %s
+
+# Unidentified files
+application/octet-stream; ~/.mutt/view_attachment.sh %s "-"
diff --git a/mutt/mutt-colors-solarized-dark-256.muttrc b/mutt/mutt-colors-solarized-dark-256.muttrc
new file mode 100644
index 0000000..b318651
--- /dev/null
+++ b/mutt/mutt-colors-solarized-dark-256.muttrc
@@ -0,0 +1,151 @@
+# vim: filetype=muttrc
+
+#
+#
+# make sure that you are using mutt linked against slang, not ncurses, or
+# suffer the consequences of weird color issues. use "mutt -v" to check this.
+
+# custom body highlights -----------------------------------------------
+# highlight my name and other personally relevant strings
+#color body color136 color234 "(ethan|schoonover)"
+# custom index highlights ----------------------------------------------
+# messages which mention my name in the body
+#color index color136 color234 "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
+#color index J_cream color230 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
+#color index color136 color37 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
+#color index color136 J_magent "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
+## messages which are in reference to my mails
+#color index J_magent color234 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
+#color index J_magent color230 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
+#color index J_magent color37 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
+#color index J_magent color160 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
+
+# for background in 16 color terminal, valid background colors include:
+# base03, bg, black, any of the non brights
+
+# basic colors ---------------------------------------------------------
+color normal color241 color234
+color error color160 color234
+color tilde color235 color234
+color message color37 color234
+color markers color160 color254
+color attachment color254 color234
+color search color61 color234
+#color status J_black J_status
+color status color241 color235
+color indicator color234 color136
+color tree color136 color234 # arrow in threads
+
+# basic monocolor screen
+mono bold bold
+mono underline underline
+mono indicator reverse
+mono error bold
+
+# index ----------------------------------------------------------------
+
+#color index color160 color234 "~D(!~p|~p)" # deleted
+#color index color235 color234 ~F # flagged
+#color index color166 color234 ~= # duplicate messages
+#color index color240 color234 "~A!~N!~T!~p!~Q!~F!~D!~P" # the rest
+#color index J_base color234 "~A~N!~T!~p!~Q!~F!~D" # the rest, new
+color index color160 color234 "~A" # all messages
+color index color166 color234 "~E" # expired messages
+color index color33 color234 "~N" # new messages
+color index color33 color234 "~O" # old messages
+color index color61 color234 "~Q" # messages that have been replied to
+color index color240 color234 "~R" # read messages
+color index color33 color234 "~U" # unread messages
+color index color33 color234 "~U~$" # unread, unreferenced messages
+color index color241 color234 "~v" # messages part of a collapsed thread
+color index color241 color234 "~P" # messages from me
+color index color37 color234 "~p!~F" # messages to me
+color index color37 color234 "~N~p!~F" # new messages to me
+color index color37 color234 "~U~p!~F" # unread messages to me
+color index color240 color234 "~R~p!~F" # messages to me
+color index color160 color234 "~F" # flagged messages
+color index color160 color234 "~F~p" # flagged messages to me
+color index color160 color234 "~N~F" # new flagged messages
+color index color160 color234 "~N~F~p" # new flagged messages to me
+color index color160 color234 "~U~F~p" # new flagged messages to me
+color index color235 color160 "~D" # deleted messages
+color index color245 color234 "~v~(!~N)" # collapsed thread with no unread
+color index color136 color234 "~v~(~N)" # collapsed thread with some unread
+color index color64 color234 "~N~v~(~N)" # collapsed thread with unread parent
+# statusbg used to indicated flagged when foreground color shows other status
+# for collapsed thread
+color index color160 color235 "~v~(~F)!~N" # collapsed thread with flagged, no unread
+color index color136 color235 "~v~(~F~N)" # collapsed thread with some unread & flagged
+color index color64 color235 "~N~v~(~F~N)" # collapsed thread with unread parent & flagged
+color index color64 color235 "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged
+color index color37 color235 "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly
+color index color136 color160 "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial)
+#color index color136 color234 "~(~N)" # messages in threads with some unread
+#color index color64 color234 "~S" # superseded messages
+#color index color160 color234 "~T" # tagged messages
+#color index color166 color160 "~=" # duplicated messages
+
+# message headers ------------------------------------------------------
+
+#color header color240 color234 "^"
+color hdrdefault color240 color234
+color header color241 color234 "^(From)"
+color header color33 color234 "^(Subject)"
+
+# body -----------------------------------------------------------------
+
+color quoted color33 color234
+color quoted1 color37 color234
+color quoted2 color136 color234
+color quoted3 color160 color234
+color quoted4 color166 color234
+
+color signature color240 color234
+color bold color235 color234
+color underline color235 color234
+color normal color244 color234
+#
+color body color245 color234 "[;:][-o][)/(|]" # emoticons
+color body color245 color234 "[;:][)(|]" # emoticons
+color body color245 color234 "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
+ |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
+ |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
+color body color245 color234 "[ ][*][^*]*[*][ ]?" # more emoticon?
+color body color245 color234 "[ ]?[*][^*]*[*][ ]" # more emoticon?
+
+## pgp
+
+color body color160 color234 "(BAD signature)"
+color body color37 color234 "(Good signature)"
+color body color234 color234 "^gpg: Good signature .*"
+color body color241 color234 "^gpg: "
+color body color241 color160 "^gpg: BAD signature from.*"
+mono body bold "^gpg: Good signature"
+mono body bold "^gpg: BAD signature from.*"
+
+# yes, an insance URL regex
+color body color160 color234 "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
+# and a heavy handed email regex
+#color body J_magent color234 "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
+
+# Various smilies and the like
+#color body color230 color234 "<[Gg]>" # <g>
+#color body color230 color234 "<[Bb][Gg]>" # <bg>
+#color body color136 color234 " [;:]-*[})>{(<|]" # :-) etc...
+# *bold*
+#color body color33 color234 "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+#mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+# _underline_
+#color body color33 color234 "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+#mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+# /italic/ (Sometimes gets directory names)
+#color body color33 color234 "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+#mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+
+# Border lines.
+#color body color33 color234 "( *[-+=#*~_]){6,}"
+
+#folder-hook . "color status J_black J_status "
+#folder-hook gmail/inbox "color status J_black color136 "
+#folder-hook gmail/important "color status J_black color136 "
+
diff --git a/mutt/mutt-colors-solarized-light-16.muttrc b/mutt/mutt-colors-solarized-light-16.muttrc
new file mode 100644
index 0000000..3c119fb
--- /dev/null
+++ b/mutt/mutt-colors-solarized-light-16.muttrc
@@ -0,0 +1,151 @@
+# vim: filetype=muttrc
+
+#
+#
+# make sure that you are using mutt linked against slang, not ncurses, or
+# suffer the consequences of weird color issues. use "mutt -v" to check this.
+
+# custom body highlights -----------------------------------------------
+# highlight my name and other personally relevant strings
+#color body yellow default "(ethan|schoonover)"
+# custom index highlights ----------------------------------------------
+# messages which mention my name in the body
+#color index yellow default "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
+#color index J_cream brightblack "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
+#color index yellow cyan "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
+#color index yellow J_magent "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
+## messages which are in reference to my mails
+#color index J_magent default "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
+#color index J_magent brightblack "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
+#color index J_magent cyan "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
+#color index J_magent red "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
+
+# for background in 16 color terminal, valid background colors include:
+# base03, bg, black, any of the non brights
+
+# basic colors ---------------------------------------------------------
+color normal brightblue default
+color error red default
+color tilde white default
+color message cyan default
+color markers red black
+color attachment black default
+color search brightmagenta default
+#color status J_black J_status
+color status brightblue white
+color indicator brightwhite yellow
+color tree yellow default # arrow in threads
+
+# basic monocolor screen
+mono bold bold
+mono underline underline
+mono indicator reverse
+mono error bold
+
+# index ----------------------------------------------------------------
+
+#color index red default "~D(!~p|~p)" # deleted
+#color index white default ~F # flagged
+#color index brightred default ~= # duplicate messages
+#color index brightcyan default "~A!~N!~T!~p!~Q!~F!~D!~P" # the rest
+#color index J_base default "~A~N!~T!~p!~Q!~F!~D" # the rest, new
+color index red default "~A" # all messages
+color index brightred default "~E" # expired messages
+color index blue default "~N" # new messages
+color index blue default "~O" # old messages
+color index brightmagenta default "~Q" # messages that have been replied to
+color index brightcyan default "~R" # read messages
+color index blue default "~U" # unread messages
+color index blue default "~U~$" # unread, unreferenced messages
+color index brightblue default "~v" # messages part of a collapsed thread
+color index brightblue default "~P" # messages from me
+color index cyan default "~p!~F" # messages to me
+color index cyan default "~N~p!~F" # new messages to me
+color index cyan default "~U~p!~F" # unread messages to me
+color index brightcyan default "~R~p!~F" # messages to me
+color index red default "~F" # flagged messages
+color index red default "~F~p" # flagged messages to me
+color index red default "~N~F" # new flagged messages
+color index red default "~N~F~p" # new flagged messages to me
+color index red default "~U~F~p" # new flagged messages to me
+color index white red "~D" # deleted messages
+color index brightgreen default "~v~(!~N)" # collapsed thread with no unread
+color index yellow default "~v~(~N)" # collapsed thread with some unread
+color index green default "~N~v~(~N)" # collapsed thread with unread parent
+# statusbg used to indicated flagged when foreground color shows other status
+# for collapsed thread
+color index red white "~v~(~F)!~N" # collapsed thread with flagged, no unread
+color index yellow white "~v~(~F~N)" # collapsed thread with some unread & flagged
+color index green white "~N~v~(~F~N)" # collapsed thread with unread parent & flagged
+color index green white "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged
+color index cyan white "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly
+color index yellow red "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial)
+#color index yellow default "~(~N)" # messages in threads with some unread
+#color index green default "~S" # superseded messages
+#color index red default "~T" # tagged messages
+#color index brightred red "~=" # duplicated messages
+
+# message headers ------------------------------------------------------
+
+#color header brightcyan default "^"
+color hdrdefault brightcyan default
+color header brightblue default "^(From)"
+color header blue default "^(Subject)"
+
+# body -----------------------------------------------------------------
+
+color quoted blue default
+color quoted1 cyan default
+color quoted2 yellow default
+color quoted3 red default
+color quoted4 brightred default
+
+color signature brightcyan default
+color bold white default
+color underline white default
+color normal default default
+#
+color body brightgreen default "[;:][-o][)/(|]" # emoticons
+color body brightgreen default "[;:][)(|]" # emoticons
+color body brightgreen default "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
+ |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
+ |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
+color body brightgreen default "[ ][*][^*]*[*][ ]?" # more emoticon?
+color body brightgreen default "[ ]?[*][^*]*[*][ ]" # more emoticon?
+
+## pgp
+
+color body red default "(BAD signature)"
+color body cyan default "(Good signature)"
+color body brightwhite default "^gpg: Good signature .*"
+color body brightblue default "^gpg: "
+color body brightblue red "^gpg: BAD signature from.*"
+mono body bold "^gpg: Good signature"
+mono body bold "^gpg: BAD signature from.*"
+
+# yes, an insance URL regex
+color body red default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
+# and a heavy handed email regex
+#color body J_magent default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
+
+# Various smilies and the like
+#color body brightblack default "<[Gg]>" # <g>
+#color body brightblack default "<[Bb][Gg]>" # <bg>
+#color body yellow default " [;:]-*[})>{(<|]" # :-) etc...
+# *bold*
+#color body blue default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+#mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+# _underline_
+#color body blue default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+#mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+# /italic/ (Sometimes gets directory names)
+#color body blue default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+#mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+
+# Border lines.
+#color body blue default "( *[-+=#*~_]){6,}"
+
+#folder-hook . "color status J_black J_status "
+#folder-hook gmail/inbox "color status J_black yellow "
+#folder-hook gmail/important "color status J_black yellow "
+
diff --git a/mutt/mutt-colors-solarized-light-256.muttrc b/mutt/mutt-colors-solarized-light-256.muttrc
new file mode 100644
index 0000000..4b3861d
--- /dev/null
+++ b/mutt/mutt-colors-solarized-light-256.muttrc
@@ -0,0 +1,151 @@
+# vim: filetype=muttrc
+
+#
+#
+# make sure that you are using mutt linked against slang, not ncurses, or
+# suffer the consequences of weird color issues. use "mutt -v" to check this.
+
+# custom body highlights -----------------------------------------------
+# highlight my name and other personally relevant strings
+#color body color136 color233 "(ethan|schoonover)"
+# custom index highlights ----------------------------------------------
+# messages which mention my name in the body
+#color index color136 color233 "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
+#color index J_cream color233 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
+#color index color136 color37 "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
+#color index color136 J_magent "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
+## messages which are in reference to my mails
+#color index J_magent color233 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
+#color index J_magent color233 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
+#color index J_magent color37 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
+#color index J_magent color160 "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
+
+# for background in 16 color terminal, valid background colors include:
+# base03, bg, black, any of the non brights
+
+# basic colors ---------------------------------------------------------
+color normal color244 color233
+color error color160 color233
+color tilde color254 color233
+color message color37 color233
+color markers color160 color234
+color attachment color234 color233
+color search color61 color233
+#color status J_black J_status
+color status color244 color254
+color indicator color230 color136
+color tree color136 color233 # arrow in threads
+
+# basic monocolor screen
+mono bold bold
+mono underline underline
+mono indicator reverse
+mono error bold
+
+# index ----------------------------------------------------------------
+
+#color index color160 color233 "~D(!~p|~p)" # deleted
+#color index color254 color233 ~F # flagged
+#color index color166 color233 ~= # duplicate messages
+#color index color245 color233 "~A!~N!~T!~p!~Q!~F!~D!~P" # the rest
+#color index J_base color233 "~A~N!~T!~p!~Q!~F!~D" # the rest, new
+color index color160 color233 "~A" # all messages
+color index color166 color233 "~E" # expired messages
+color index color33 color233 "~N" # new messages
+color index color33 color233 "~O" # old messages
+color index color61 color233 "~Q" # messages that have been replied to
+color index color245 color233 "~R" # read messages
+color index color33 color233 "~U" # unread messages
+color index color33 color233 "~U~$" # unread, unreferenced messages
+color index color244 color233 "~v" # messages part of a collapsed thread
+color index color244 color233 "~P" # messages from me
+color index color37 color233 "~p!~F" # messages to me
+color index color37 color233 "~N~p!~F" # new messages to me
+color index color37 color233 "~U~p!~F" # unread messages to me
+color index color245 color233 "~R~p!~F" # messages to me
+color index color160 color233 "~F" # flagged messages
+color index color160 color233 "~F~p" # flagged messages to me
+color index color160 color233 "~N~F" # new flagged messages
+color index color160 color233 "~N~F~p" # new flagged messages to me
+color index color160 color233 "~U~F~p" # new flagged messages to me
+color index color254 color160 "~D" # deleted messages
+color index color239 color233 "~v~(!~N)" # collapsed thread with no unread
+color index color136 color233 "~v~(~N)" # collapsed thread with some unread
+color index color64 color233 "~N~v~(~N)" # collapsed thread with unread parent
+# statusbg used to indicated flagged when foreground color shows other status
+# for collapsed thread
+color index color160 color254 "~v~(~F)!~N" # collapsed thread with flagged, no unread
+color index color136 color254 "~v~(~F~N)" # collapsed thread with some unread & flagged
+color index color64 color254 "~N~v~(~F~N)" # collapsed thread with unread parent & flagged
+color index color64 color254 "~N~v~(~F)" # collapsed thread with unread parent, no unread inside, but some flagged
+color index color37 color254 "~v~(~p)" # collapsed thread with unread parent, no unread inside, some to me directly
+color index color136 color160 "~v~(~D)" # thread with deleted (doesn't differentiate between all or partial)
+#color index color136 color233 "~(~N)" # messages in threads with some unread
+#color index color64 color233 "~S" # superseded messages
+#color index color160 color233 "~T" # tagged messages
+#color index color166 color160 "~=" # duplicated messages
+
+# message headers ------------------------------------------------------
+
+#color header color245 color233 "^"
+color hdrdefault color245 color233
+color header color244 color233 "^(From)"
+color header color33 color233 "^(Subject)"
+
+# body -----------------------------------------------------------------
+
+color quoted color33 color233
+color quoted1 color37 color233
+color quoted2 color136 color233
+color quoted3 color160 color233
+color quoted4 color166 color233
+
+color signature color245 color233
+color bold color254 color233
+color underline color254 color233
+color normal color240 color233
+#
+color body color239 color233 "[;:][-o][)/(|]" # emoticons
+color body color239 color233 "[;:][)(|]" # emoticons
+color body color239 color233 "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
+ |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
+ |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
+color body color239 color233 "[ ][*][^*]*[*][ ]?" # more emoticon?
+color body color239 color233 "[ ]?[*][^*]*[*][ ]" # more emoticon?
+
+## pgp
+
+color body color160 color233 "(BAD signature)"
+color body color37 color233 "(Good signature)"
+color body color230 color233 "^gpg: Good signature .*"
+color body color244 color233 "^gpg: "
+color body color244 color160 "^gpg: BAD signature from.*"
+mono body bold "^gpg: Good signature"
+mono body bold "^gpg: BAD signature from.*"
+
+# yes, an insance URL regex
+color body color160 color233 "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
+# and a heavy handed email regex
+#color body J_magent color233 "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
+
+# Various smilies and the like
+#color body color233 color233 "<[Gg]>" # <g>
+#color body color233 color233 "<[Bb][Gg]>" # <bg>
+#color body color136 color233 " [;:]-*[})>{(<|]" # :-) etc...
+# *bold*
+#color body color33 color233 "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+#mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+# _underline_
+#color body color33 color233 "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+#mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+# /italic/ (Sometimes gets directory names)
+#color body color33 color233 "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+#mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+
+# Border lines.
+#color body color33 color233 "( *[-+=#*~_]){6,}"
+
+#folder-hook . "color status J_black J_status "
+#folder-hook gmail/inbox "color status J_black color136 "
+#folder-hook gmail/important "color status J_black color136 "
+
diff --git a/mutt/offlineimap.py b/mutt/offlineimap.py
new file mode 100644
index 0000000..3bdc780
--- /dev/null
+++ b/mutt/offlineimap.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python2
+from subprocess import check_output
+
+def get_pass(account):
+ return check_output("pass Email/" + account, shell=True).rstrip()
diff --git a/mutt/offlineimap.py-bak b/mutt/offlineimap.py-bak
new file mode 100644
index 0000000..41fe18b
--- /dev/null
+++ b/mutt/offlineimap.py-bak
@@ -0,0 +1,17 @@
+#/usr/bin/python
+
+import re, subprocess
+def get_keychain_pass(account=None, server=None):
+ params = {
+ 'security': '/usr/bin/security',
+ 'command': 'find-internet-password',
+ 'account': account,
+ 'server': server,
+ 'keychain': '/Users/lemon/Library/Keychains/login.keychain',
+ }
+ command = "sudo -u lemon %(security)s -v %(command)s -g -a %(account)s -s %(server)s %(keychain)s" % params
+ output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
+ outtext = [l for l in output.splitlines()
+ if l.startswith('password: ')][0]
+
+ return re.match(r'password: "(.*)"', outtext).group(1)
diff --git a/mutt/signature b/mutt/signature
new file mode 100644
index 0000000..c375431
--- /dev/null
+++ b/mutt/signature
@@ -0,0 +1,3 @@
+
+Matthew Lemon
+Email: matt@matthewlemon.com
diff --git a/mutt/subscriptions b/mutt/subscriptions
new file mode 100644
index 0000000..3b7eac4
--- /dev/null
+++ b/mutt/subscriptions
@@ -0,0 +1,3 @@
+subscribe debian-user@lists.debian.org
+subscribe python-list
+subscribe ubuntu-news@lists.ubuntu.com
diff --git a/mutt/view_attachment.sh b/mutt/view_attachment.sh
new file mode 100755
index 0000000..f391399
--- /dev/null
+++ b/mutt/view_attachment.sh
@@ -0,0 +1,129 @@
+#!/bin/bash
+#
+# Author: Eric Gebhart
+#
+# Purpose: To be called by mutt as indicated by .mailcap to handle mail attachments.
+#
+# Function: Copy the given file to a temporary directory so mutt
+# Won't delete it before it is read by the application.
+#
+# Along the way, discern the file type or use the type
+# That is given.
+#
+# Finally use 'open' or 'open -a' if the third argument is
+# given.
+#
+#
+# Arguments:
+#
+# $2 is the file
+# $2 is the type - for those times when file magic isn't enough.
+# I frequently get html mail that has no extension
+# and file can't figure out what it is.
+#
+# Set to '-' if you don't want the type to be discerned.
+# Many applications can sniff out the type on their own.
+# And they do a better job of it too.
+#
+# Open Office and MS Office for example.
+#
+# $3 is open with. as in open -a 'open with this .app' foo.xls
+#
+# Examples: These are typical .mailcap entries which use this program.
+#
+# Image/JPEG; /Users/vdanen/.mutt/view_attachment %s
+# Image/PNG; /Users/vdanen/.mutt/view_attachment %s
+# Image/GIF; /Users/vdanen/.mutt/view_attachment %s
+#
+# Application/PDF; /Users/vdanen/.mutt/view_attachment %s
+#
+# #This HTML example passes the type because file doesn't always work and
+# #there aren't always extensions.
+#
+# text/html; /Users/vdanen/.mutt/view_attachment %s html
+#
+# # If your Start OpenOffice.org.app is spelled with a space like this one, <--
+# # then you'll need to precede the space with a \ . I found that too painful
+# # and renamed it with an _.
+#
+# Application/vnd.ms-excel; /Users/vdanen/.mutt/view_attachment %s "-" '/Applications/OpenOffice.org1.1.2/Start_OpenOffice.org.app'
+# Application/msword; /Users/vdanen/.mutt/view_attachment %s "-" '/Applications/OpenOffice.org1.1.2/Start_OpenOffice.org.app'
+#
+#
+# Debugging: If you have problems set debug to 'yes'. That will cause a debug file
+# be written to /tmp/mutt_attach/debug so you can see what is going on.
+#
+# See Also: The man pages for open, file, basename
+#
+
+# the tmp directory to use.
+tmpdir="$HOME/.mutt/temp/mutt_attach"
+
+# the name of the debug file if debugging is turned on.
+debug_file=$tmpdir/debug
+
+# debug. yes or no.
+debug="no"
+#debug="yes"
+
+type=$2
+open_with=$3
+
+# make sure the tmpdir exists.
+mkdir -p $tmpdir
+
+# clean it out. Remove this if you want the directory
+# to accumulate attachment files.
+rm -f $tmpdir/*
+
+# Mutt puts everything in /tmp by default.
+# This gets the basic filename from the full pathname.
+filename=`basename $1`
+
+# get rid of the extenson and save the name for later.
+file=`echo $filename | cut -d"." -f1`
+
+if [ $debug = "yes" ]; then
+ echo "1:" $1 " 2:" $2 " 3:" $3 > $debug_file
+ echo "Filename:"$filename >> $debug_file
+ echo "File:"$file >> $debug_file
+ echo "===========================" >> $debug_file
+fi
+
+# if the type is empty then try to figure it out.
+if [ -z $type ]; then
+ type=`file -bi $1 | cut -d"/" -f2`
+fi
+
+# if the type is '-' then we don't want to mess with type.
+# Otherwise we are rebuilding the name. Either from the
+# type that was passed in or from the type we discerned.
+if [ $type = "-" ]; then
+ newfile=$filename
+else
+ newfile=$file.$type
+fi
+
+newfile=$tmpdir/$newfile
+
+# Copy the file to our new spot so mutt can't delete it
+# before the app has a chance to view it.
+cp $1 $newfile
+
+if [ $debug = "yes" ]; then
+ echo "File:" $file "TYPE:" $type >> $debug_file
+ echo "Newfile:" $newfile >> $debug_file
+ echo "Open With:" $open_with >> $debug_file
+fi
+
+# If there's no 'open with' then we can let preview do it's thing.
+# Otherwise we've been told what to use. So do an open -a.
+
+#vim $newfile
+
+#ML REMOVED THIS ON 18 September 2014
+if [ -z $open_with ]; then
+ echo "Dae ken how to open that razzer."
+else
+ $open_with $newfile
+fi
diff --git a/muttrc b/muttrc
new file mode 100644
index 0000000..1d63046
--- /dev/null
+++ b/muttrc
@@ -0,0 +1,235 @@
+# Paths ----------------------------------------------
+# Getting all this from article by Steve Losh
+# at http://stevelosh.com/blog/2012/10/the-homely-mutt/#contacts
+
+# source the mutt-solarized colorscheme
+#source ~/dotfiles/.mutt/mutt-colors-solarized-dark-256.muttrc - no because it doesn't really work ya radge
+
+set folder = ~/.mail/ # mailbox location
+set alias_file = ~/.mutt/aliases # where to store aliases
+set header_cache = ~/.mutt/cache/headers # where to store headers
+set message_cachedir = ~/.mutt/cache/bodies # where to store bodies
+set certificate_file = ~/.mutt/certificates # where to store certs
+set mailcap_path = ~/.mutt/mailcap # entries for filetypes
+set tmpdir = ~/.mutt/temp # where to keep temp files
+set signature = ~/.mutt/signature # my signature file
+
+# Allow forwarding of attachments with emails
+set mime_forward
+set mime_forward_rest
+
+# Basic Options --------------------------------------
+set wait_key = no # shut up, mutt
+set mbox_type = Maildir # mailbox type
+set timeout = 3 # idle time before scanning
+set mail_check = 0 # minimum time between scans
+#unset move # gmail does that
+set delete # don't ask, just do
+unset confirmappend # don't ask, just do!
+set quit # don't ask, just do!!
+unset mark_old # read/new is good enough for me
+#set beep_new # bell on new mails
+set pipe_decode # strip headers and eval mimes when piping
+set thorough_search # strip headers and eval mimes before searching
+
+# nicer text
+set text_flowed=yes
+
+# Sidebar Patch --------------------------------------
+#set sidebar_delim = '│'
+#set sidebar_visible = yes
+#set sidebar_width = 24
+## not working in xubuntu set sidebar_shortpath = yes
+#set sidebar_sort = yes
+## Paths ----------------------------------------------
+#color sidebar_new color221 color233
+
+# Status Bar -----------------------------------------
+set status_chars = " *%A"
+set status_format = "───[ Folder: %f ]───[%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]───%>─%?p?( %p postponed )?───"
+
+# Header Options -------------------------------------
+ignore * # ignore all headers
+unignore from: to: cc: date: bcc: subject: # show only these
+unhdr_order * # some distros order things by default
+hdr_order from: to: cc: bcc: date: subject: # and in this order
+
+# Account Settings -----------------------------------
+
+# Default inbox.
+set spoolfile = "+matt-matthewlemon.com/INBOX"
+
+# Alternate email addresses.
+#alternates <shit goes in here>
+
+# Mailboxes to show in the sidebar.
+
+ mailboxes +matt-matthewlemon.com/INBOX \
+ +matt-matthewlemon.com/INBOX.Archive \
+ +matt-matthewlemon.com/INBOX.Sent\ Items \
+ +matt-matthewlemon.com/INBOX.Drafts \
+# +matt-matthewlemon.com/INBOX.Gmail.Archive \
+ +matt-matthewlemon.com/INBOX.Trash \
+# +temporary/search \
+
+# Other special folders.
+set mbox = "+matt-matthewlemon.com/INBOX.Archive"
+set postponed = "+matt-matthewlemon.com/INBOX.Drafts"
+
+# Index View Options ---------------------------------
+set date_format = "%d-%m-%Y"
+set index_format = "[%Z] %B %D %-20.20F %s"
+set sort = threads # like gmail
+set sort_aux = reverse-last-date-received # like gmail
+set uncollapse_jump # don't collapse on an unread message
+set sort_re # thread based on regex
+set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"
+
+# Index Key Bindings ---------------------------------
+#bind index gg first-entry
+bind index G last-entry
+
+bind index R group-reply
+bind index <tab> sync-mailbox
+bind index <space> collapse-thread
+
+# Ctrl-R to mark all as read
+macro index \Cr "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "mark all messages as read"
+
+# Sync email
+macro index O "<shell-escape>offlineimap<enter>" "run offlineimap to sync all mail"
+macro index o "<shell-escape>offlineimap -qf INBOX<enter>" "run offlineimap to sync inbox"
+
+# Saner copy/move dialogs
+macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox"
+macro index M "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"
+
+# Sidebar Navigation ---------------------------------
+bind index,pager <down> sidebar-next
+bind index,pager <up> sidebar-prev
+bind index,pager <right> sidebar-open
+
+# Pager View Options ---------------------------------
+set pager_index_lines = 10 # number of index lines to show
+set pager_context = 3 # number of context lines to show
+set pager_stop # don't go to next message automatically
+set menu_scroll # scroll in menus
+set tilde # show tildes like in vim
+unset markers # no ugly plus signs
+
+set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
+alternative_order text/plain text/enriched text/html
+
+# fix background colour
+#color normal white black
+
+# identifies URLs
+
+# Pager Key Bindings ---------------------------------
+bind pager k previous-line
+bind pager j next-line
+bind pager gg top
+bind pager G bottom
+
+bind pager R group-reply
+
+# View attachments properly.
+bind attach <return> view-mailcap
+
+# open links
+macro pager \Cu "|urlview<enter>" "call urlview to open links"
+
+# Compose View Options -------------------------------
+set realname = "Matthew Lemon" # who am i?
+set envelope_from # which from?
+set sig_dashes # dashes before sig
+set edit_headers # show headers when composing
+set fast_reply # skip to compose when replying
+set askcc # ask for CC:
+set fcc_attach # save attachments with the body
+unset mime_forward # forward attachments as part of body
+set forward_format = "Fwd: %s" # format of subject when forwarding
+set forward_decode # decode when forwarding
+set attribution = "On %d, %n wrote:" # format of quoting header
+set reply_to # reply to Reply to: field
+set reverse_name # reply as whomever it was to
+set include # include message in replies
+set forward_quote # include message in forwards
+
+#set editor = "vim" # Use terminal Vim to compose email.
+set editor = "nvim %s"
+
+set from = "matt@matthewlemon.com"
+set sendmail = "/usr/bin/msmtp -a matthewlemon"
+set sendmail_wait = 0
+set record = "+matt-matthewlemon.com/INBOX.Sent\ Items"
+
+bind compose p postpone-message
+bind index p recall-message
+
+# Get mutt to understand the contacts command line prog which reads Contacts
+#set query_command = "contacts -Sf '%eTOKEN%n' '%s' | sed -e 's/TOKEN/\t/g'"
+
+## Abook
+set query_command= "abook --mutt-query '%s'"
+macro generic,index,pager \ca "<shell-escape>abook<return>" "launch abook"
+macro index,pager A "<pipe-message>abook --add-email<return>" "Add this sender to Abook"
+bind editor <Tab> complete-query
+bind editor ^T complete
+
+# Better searching in mutt
+bind index N search-opposite
+bind pager N search-opposite
+macro index a "<limit>all\n" "show all messages (undo limit)"
+
+# get an email from mutt to taskwarrior
+macro index T "<pipe-message>mutt2task<enter> <move-message>+matt-matthewlemon.com/INBOX.Archive<enter>"
+
+# Handle searching using notmuch (see Steve Losh article)
+# this doesn't work on linux so using another macro index S "<enter-command>unset wait_key<enter><shell-escape>mutt-notmuch-py.py ~/.mail/temporary/search<enter><change-folder-readonly>+temporary/search<enter>" "search mail (using notmuch)"
+
+
+#new notmuch-mutt for linux
+
+macro index <F8> \
+"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\
+<shell-escape>notmuch-mutt -r --prompt search<enter>\
+<change-folder-readonly>`echo ${XDG_CACHE_HOME:-$HOME/.cache}/notmuch/mutt/results`<enter>\
+<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \
+ "notmuch: search mail"
+
+macro index <F9> \
+"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\
+<pipe-message>notmuch-mutt -r thread<enter>\
+<change-folder-readonly>`echo ${XDG_CACHE_HOME:-$HOME/.cache}/notmuch/mutt/results`<enter>\
+<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \
+ "notmuch: reconstruct thread"
+
+macro index <F6> \
+"<enter-command>set my_old_pipe_decode=\$pipe_decode my_old_wait_key=\$wait_key nopipe_decode nowait_key<enter>\
+<pipe-message>notmuch-mutt tag -- -inbox<enter>\
+<enter-command>set pipe_decode=\$my_old_pipe_decode wait_key=\$my_old_wait_key<enter>" \
+ "notmuch: remove message from inbox"
+
+
+# old Losh OSX-based orientation
+#macro index <F8> "<enter-command>unset wait_key<enter><shell-escape>/usr/bin/notmuch-mutt --prompt search<enter><change-folder-readonly>~/.cache/mutt_results<enter>" "search mail (using notmuch)"
+#macro index <F9> "<enter-command>unset wait_key<enter><pipe-message>/usr/bin/notmuch-mutt thread<enter><change-folder-readonly>~/.cache/mutt_results<enter><enter-command>set wait_key<enter>" "search and reconstruct owning thread (using notmuch)"
+#
+#source ~/.mutt/gpg.rc # Use GPG
+#source ~/.mutt/auto_views # Define auto_views.
+source ~/.mutt/aliases # Load in my aliases.
+source ~/.mutt/subscriptions # Define the list of subscribed mailing lists.
+#source ~/.mutt/mailboxes # Define the list of folders that receive mail.
+#source ~/.mutt/headers # Configure header display.
+#source ~/.mutt/folder-hooks # Define folder-hooks.
+#source ~/.mutt/save-hooks # Define save-hooks.
+#source ~/.mutt/fcc-hooks # Define fcc-hooks.
+#source ~/.mutt/message-hooks # Define message hooks.
+#source ~/.mutt/bindings # Define key bindings.
+#source ~/.mutt/macros # Define macros.
+source ~/.mutt/colours # Define colours.
+#source ~/.mutt/sidebar # Define sidebar support (requires sidebar patch)
+#
+# MAILCAP
+auto_view text/html
diff --git a/muttrc-gmail b/muttrc-gmail
new file mode 100644
index 0000000..f5b01da
--- /dev/null
+++ b/muttrc-gmail
@@ -0,0 +1,155 @@
+set folder = ~/.mail/ # mailbox location
+set alias_file = ~/.mutt/aliases # where to store aliases
+set header_cache = ~/.mutt/cache/headers # where to store headers
+set message_cachedir = ~/.mutt/cache/bodies # where to store bodies
+set certificate_file = ~/.mutt/certificates # where to store certs
+set mailcap_path = ~/.mutt/mailcap # entries for filetypes
+set tmpdir = ~/.mutt/temp # where to keep temp files
+set signature = ~/.mutt/signature # my signature file
+#
+# Allow forwarding of attachments with emails
+set mime_forward
+set mime_forward_rest
+
+# Basic Options --------------------------------------
+set wait_key = no # shut up, mutt
+set mbox_type = Maildir # mailbox type
+set timeout = 3 # idle time before scanning
+set mail_check = 0 # minimum time between scans
+unset move # gmail does that
+set delete # don't ask, just do
+unset confirmappend # don't ask, just do!
+set quit # don't ask, just do!!
+unset mark_old # read/new is good enough for me
+#set beep_new # bell on new mails
+set pipe_decode # strip headers and eval mimes when piping
+set thorough_search # strip headers and eval mimes before searching
+
+# Account Settings -----------------------------------
+set mbox_type = Maildir
+set folder = "~/.mail/"
+set from = "matthew.lemon@gmail.com"
+set spoolfile = "+matthew.lemon-gmail.com/INBOX"
+set sendmail = "/usr/bin/msmtp -a gmail"
+set mbox = "+matthew.lemon-gmail.com/INBOX"
+set postponed = "+matthew.lemon-gmail.com/[Gmail].Drafts"
+mailboxes +matthew.lemon-gmail.com/INBOX \
+ +matthew.lemon-gmail.com/'[Gmail].All Mail' \
+ +matthew.lemon-gmail.com/'[Gmail].Archive' \
+ +matthew.lemon-gmail.com/'[Gmail].Bin' \
+ +matthew.lemon-gmail.com/'[Gmail].Important' \
+ +matthew.lemon-gmail.com/'[Gmail].Starred' \
+
+# Other special folders.
+#set mbox = "+matt-matthewlemon.com/INBOX.Archive"
+#set postponed = "+matt-matthewlemon.com/INBOX.Drafts"
+
+# Index View Options ---------------------------------
+set date_format = "%d-%m-%Y"
+set index_format = "[%Z] %B %D %-20.20F %s"
+set sort = threads # like gmail
+set sort_aux = reverse-last-date-received # like gmail
+set uncollapse_jump # don't collapse on an unread message
+set sort_re # thread based on regex
+set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"
+
+# Index Key Bindings ---------------------------------
+#bind index gg first-entry
+bind index G last-entry
+
+bind index R group-reply
+bind index <tab> sync-mailbox
+bind index <space> collapse-thread
+#
+## Abook
+set query_command= "abook --mutt-query '%s'"
+macro generic,index,pager \ca "<shell-escape>abook<return>" "launch abook"
+macro index,pager A "<pipe-message>abook --add-email<return>" "Add this sender to Abook"
+bind editor <Tab> complete-query
+bind editor ^T complete
+
+# Ctrl-R to mark all as read
+macro index \Cr "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "mark all messages as read"
+
+# Sync email
+macro index O "<shell-escape>offlineimap<enter>" "run offlineimap to sync all mail"
+macro index o "<shell-escape>offlineimap -qf INBOX<enter>" "run offlineimap to sync inbox"
+
+# Saner copy/move dialogs
+macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox"
+macro index M "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"
+
+# Sidebar Navigation ---------------------------------
+bind index,pager <down> sidebar-next
+bind index,pager <up> sidebar-prev
+bind index,pager <right> sidebar-open
+
+# Pager View Options ---------------------------------
+set pager_index_lines = 10 # number of index lines to show
+set pager_context = 3 # number of context lines to show
+set pager_stop # don't go to next message automatically
+set menu_scroll # scroll in menus
+set tilde # show tildes like in vim
+unset markers # no ugly plus signs
+
+set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
+alternative_order text/plain text/enriched text/html
+
+# fix background colour
+#color normal white black
+
+# identifies URLs
+
+# Pager Key Bindings ---------------------------------
+bind pager k previous-line
+bind pager j next-line
+bind pager gg top
+bind pager G bottom
+
+bind pager R group-reply
+
+# View attachments properly.
+bind attach <return> view-mailcap
+
+# open links
+macro pager \Cu "|urlview<enter>" "call urlview to open links"
+
+# Compose View Options -------------------------------
+set realname = "Matthew Lemon" # who am i?
+set envelope_from # which from?
+set sig_dashes # dashes before sig
+set edit_headers # show headers when composing
+set fast_reply # skip to compose when replying
+set askcc # ask for CC:
+set fcc_attach # save attachments with the body
+unset mime_forward # forward attachments as part of body
+set forward_format = "Fwd: %s" # format of subject when forwarding
+set forward_decode # decode when forwarding
+set attribution = "On %d, %n wrote:" # format of quoting header
+set reply_to # reply to Reply to: field
+set reverse_name # reply as whomever it was to
+set include # include message in replies
+set forward_quote # include message in forwards
+
+#set editor = "vim" # Use terminal Vim to compose email.
+set editor = "nvim %s"
+# nicer text
+set text_flowed=yes
+
+#source ~/.mutt/gpg.rc # Use GPG
+#source ~/.mutt/auto_views # Define auto_views.
+source ~/.mutt/aliases # Load in my aliases.
+source ~/.mutt/subscriptions # Define the list of subscribed mailing lists.
+#source ~/.mutt/mailboxes # Define the list of folders that receive mail.
+#source ~/.mutt/headers # Configure header display.
+#source ~/.mutt/folder-hooks # Define folder-hooks.
+#source ~/.mutt/save-hooks # Define save-hooks.
+#source ~/.mutt/fcc-hooks # Define fcc-hooks.
+#source ~/.mutt/message-hooks # Define message hooks.
+#source ~/.mutt/bindings # Define key bindings.
+#source ~/.mutt/macros # Define macros.
+source ~/.mutt/colours # Define colours.
+#source ~/.mutt/sidebar # Define sidebar support (requires sidebar patch)
+#
+# MAILCAP
+auto_view text/html
diff --git a/mypy.ini b/mypy.ini
new file mode 100644
index 0000000..dfac43a
--- /dev/null
+++ b/mypy.ini
@@ -0,0 +1,2 @@
+[mypy]
+ignore-missing-imports = True
diff --git a/nethackrc b/nethackrc
new file mode 100644
index 0000000..c00dec2
--- /dev/null
+++ b/nethackrc
@@ -0,0 +1,109 @@
+OPTIONS=DECgraphics
+OPTIONS=name:Mister Lemon
+OPTIONS=dogname:Cleethorpes
+OPTIONS=catname:Cinnamon
+OPTIONS=horsename:Joanna
+OPTIONS=color
+OPTIONS=!autopickup
+OPTIONS=pickup_thrown
+OPTIONS=pickup_burden:u
+OPTIONS=checkpoint
+OPTIONS=cmdassist
+OPTIONS=dark_room
+OPTIONS=fixinv
+OPTIONS=fullscreen
+OPTIONS=hilite_pile
+OPTIONS=hilite_pet
+OPTIONS=menustyle:full
+OPTIONS=lit_corridor
+OPTIONS=msg_window:r
+OPTIONS=standout
+OPTIONS=time
+OPTIONS=use_inverse
+OPTIONS=menucolors
+OPTIONS=large_font
+OPTIONS=showexp
+OPTIONS=autoquiver
+OPTIONS=paranoid_confirmation:attack pray Remove
+OPTIONS=statushilites
+
+#OPTIONS=hilite_status: hitpoints/30%/red/green
+#OPTIONS=hilite_status: power/33%/orange/cyan
+#OPTIONS=hilite_status: hitpoints-max/updown/orange/green
+#OPTIONS=hilite_status: power-max/updown/yellow/cyan
+#OPTIONS=hilite_status: alignment/updown/white/gray
+
+# gold is always yellow
+#OPTIONS=hilite_status: gold/1%/yellow/yellow
+
+# all food conditions become magenta, satiated to fainted
+#OPTIONS=hilite_status: hunger/50%/bright-magenta/green
+
+
+# Enhance
+MENUCOLOR=" \[Basic\]$"=green
+MENUCOLOR=" \[(Skilled|Master)\]$"=lightgreen
+MENUCOLOR=" \[(Expert|Grand Master)\]$"=white
+MENUCOLOR=" martial arts +\[Expert\]$"=green
+MENUCOLOR="^ *[a-z -]+ +\[Unskilled\]$"=black
+#MENUCOLOR="^ *[a-z] - +[a-z -]+ +\[(Unskilled|Basic|Skilled|Expert|Master)\]$"
+
+MENUCOLOR=" blessed"=green
+MENUCOLOR=" uncursed"=cyan
+MENUCOLOR=" named nc"=cyan
+MENUCOLOR=" cursed"=red
+MENUCOLOR=" named pc"=red
+
+MENUCOLOR=" water"=lightblue
+MENUCOLOR=" called plain"=lightblue
+MENUCOLOR=" clear"=lightblue
+MENUCOLOR=" holy water"=lightcyan
+MENUCOLOR=" unholy water"=blue
+
+MENUCOLOR=" blessed .* water"=lightcyan
+MENUCOLOR=" blessed clear"=lightcyan
+MENUCOLOR=" cursed .* water"=blue
+MENUCOLOR=" cursed clear"=blue
+
+MENUCOLOR=" worn"=cyan&inverse
+MENUCOLOR=" blessed .* worn"=green&inverse
+MENUCOLOR=" cursed .* worn"=red&inverse
+
+MENUCOLOR=" cursed .* wielded"=red&inverse
+MENUCOLOR=" cursed .* hand"=red&inverse
+
+MENUCOLOR=" blessed .* bag of holding"=green&underline
+MENUCOLOR=" uncursed .* bag of holding"=cyan&underline
+MENUCOLOR=" cursed .* bag of holding"=red&underline
+
+
+MENUCOLOR=" (gauntlets|gloves|boots) .* fumbl"=orange
+MENUCOLOR=" fumble boots"=orange
+MENUCOLOR=" dunce cap"=orange
+MENUCOLOR="align"=orange
+MENUCOLOR=" c(hi|o)ckatrice corpse"=yellow
+MENUCOLOR=" cockatrice egg"=yellow
+MENUCOLOR=":0"=yellow
+MENUCOLOR="named op"=yellow
+MENUCOLOR="empty"=yellow
+MENUCOLOR="wishing"=lightcyan
+MENUCOLOR="unpaid"=white&underline
+
+# my original stuff
+#
+#MENUCOLOR="blessed " = lightcyan
+#MENUCOLOR="holy " = green
+#MENUCOLOR="cursed " = red
+#MENUCOLOR="uncursed " = white
+#MENUCOLOR="unholy " = red
+#MENUCOLOR="cursed .* (being worn) " = orange&underline
+
+
+
+SYMBOLS=S_boulder:0
+MSGTYPE=hide "You swap places with .*"
+MSGTYPE=hide "You stop. Your kitten is in the way!"
+## items on floor. don't repeat the message.
+MSGTYPE=norep "You see here a .*"
+MSGTYPE=norep "You see here an .*"
+MSGTYPE=norep "You stop. .* is in the way!
diff --git a/newsboat/config b/newsboat/config
new file mode 100644
index 0000000..df4334f
--- /dev/null
+++ b/newsboat/config
@@ -0,0 +1,42 @@
+#browser "w3m %u"
+auto-reload yes
+
+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
+
+refresh-on-startup yes
+define-filter "Linux articles" "title =~ \"Linux\""
+color info color15 color6
+#macro y set browser "mpv %u"; open-in-browser ; set browser "elinks %u"
+#color listfocus color15 color0
+#color listfocus color14 color0
+#color listfocus_unread color15 color0 bold
+#highlight-article "title =~ \"Productivity\"" white red bold
+#highlight-article "title =~ \"Setup\"" yellow red bold
+#highlight all "Linux" yellow red bold
+notify-program "notify-send"
+notify-screen yes
+notify-xterm yes
+
+max-items 20
+download-path "~/Downloads"
+
+player mpv
+browser w3m
+macro m set browser "mpv %u" ; open-in-browser ; set browser "w3m %u"
diff --git a/newsboat/history.cmdline b/newsboat/history.cmdline
new file mode 100644
index 0000000..2935811
--- /dev/null
+++ b/newsboat/history.cmdline
@@ -0,0 +1,2 @@
+q
+q
diff --git a/newsboat/history.search b/newsboat/history.search
new file mode 100644
index 0000000..146f275
--- /dev/null
+++ b/newsboat/history.search
@@ -0,0 +1 @@
+setup
diff --git a/newsboat/queue b/newsboat/queue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/newsboat/queue
diff --git a/newsboat/urls b/newsboat/urls
new file mode 120000
index 0000000..bc5f076
--- /dev/null
+++ b/newsboat/urls
@@ -0,0 +1 @@
+/home/lemon/linux-storage/Notes/newsboat-urls \ No newline at end of file
diff --git a/newsboat/urls-bak b/newsboat/urls-bak
new file mode 100644
index 0000000..7f8c4d4
--- /dev/null
+++ b/newsboat/urls-bak
@@ -0,0 +1,24 @@
+https://www.youtube.com/channel/UC2eYFnH61tmytImy1mTYvhA
+https://taskwarrior.org/feed.rss
+http://feeds2.feedburner.com/Command-line-fu
+http://feeds.feedburner.com/mylinuxrig
+http://feeds.doughellmann.com/PyMOTW
+https://plaintextproject.online/feed.xml
+https://www.reddit.com/r/linuxmasterrace/.rss
+http://feedproxy.google.com/linuxtoday/linux
+https://www.reddit.com/r/rugbyunion/.rss
+http://planetpython.org/rss20.xml
+http://www.linuxjournal.com/node/feed
+http://www.linuxinsider.com/perl/syndication/rssfull.pl
+http://usesthis.com/feed/
+http://joeyh.name/blog/index.rss
+https://www.debian.org/News/news
+http://planet.debian.org/rss20.xml
+https://opensource.org/news.xml
+http://blog.canonical.com/feed
+http://feeds2.feedburner.com/Command-line-fu
+https://www.fsf.org/static/fsforg/rss/news.xml
+http://feeds.doughellmann.com/PyMOTW
+http://feeds.feedburner.com/mylinuxrig
+https://blog.nightly.mozilla.org/feed/
+https://www.gamingonlinux.com/article_rss.php
diff --git a/noserc b/noserc
new file mode 100644
index 0000000..f8747ca
--- /dev/null
+++ b/noserc
@@ -0,0 +1,2 @@
+[nosetests]
+verbosity=3
diff --git a/notmuch-config b/notmuch-config
new file mode 100644
index 0000000..7a506e8
--- /dev/null
+++ b/notmuch-config
@@ -0,0 +1,102 @@
+# .notmuch-config - Configuration file for the notmuch mail system
+#
+# For more information about notmuch, see http://notmuchmail.org
+
+# Database configuration
+#
+# The only value supported here is 'path' which should be the top-level
+# directory where your mail currently exists and to where mail will be
+# delivered in the future. Files should be individual email messages.
+# Notmuch will store its database within a sub-directory of the path
+# configured here named ".notmuch".
+#
+
+[database]
+path=/home/lemon/.mail
+
+# User configuration
+#
+# Here is where you can let notmuch know how you would like to be
+# addressed. Valid settings are
+#
+# name Your full name.
+# primary_email Your primary email address.
+# other_email A list (separated by ';') of other email addresses
+# at which you receive email.
+#
+# Notmuch will use the various email addresses configured here when
+# formatting replies. It will avoid including your own addresses in the
+# recipient list of replies, and will set the From address based on the
+# address to which the original email was addressed.
+#
+
+[user]
+name=Matthew Lemon
+primary_email=matt@matthewlemon.com
+
+# Configuration for "notmuch new"
+#
+# The following options are supported here:
+#
+# tags A list (separated by ';') of the tags that will be
+# added to all messages incorporated by "notmuch new".
+#
+# ignore A list (separated by ';') of file and directory names
+# that will not be searched for messages by "notmuch new".
+#
+# NOTE: *Every* file/directory that goes by one of those
+# names will be ignored, independent of its depth/location
+# in the mail store.
+#
+
+[new]
+tags=unread;inbox;
+ignore=
+
+# Search configuration
+#
+# The following option is supported here:
+#
+# exclude_tags
+# A ;-separated list of tags that will be excluded from
+# search results by default. Using an excluded tag in a
+# query will override that exclusion.
+#
+
+[search]
+exclude_tags=deleted;spam;
+
+# Maildir compatibility configuration
+#
+# The following option is supported here:
+#
+# synchronize_flags Valid values are true and false.
+#
+# If true, then the following maildir flags (in message filenames)
+# will be synchronized with the corresponding notmuch tags:
+#
+# Flag Tag
+# ---- -------
+# D draft
+# F flagged
+# P passed
+# R replied
+# S unread (added when 'S' flag is not present)
+#
+# The "notmuch new" command will notice flag changes in filenames
+# and update tags, while the "notmuch tag" and "notmuch restore"
+# commands will notice tag changes and update flags in filenames
+#
+
+[maildir]
+synchronize_flags=true
+
+# Cryptography related configuration
+#
+# The following option is supported here:
+#
+# gpg_path
+# binary name or full path to invoke gpg.
+#
+[crypto]
+gpg_path=gpg
diff --git a/nvim/after/syntax/markdown.vim b/nvim/after/syntax/markdown.vim
new file mode 100644
index 0000000..4ce0215
--- /dev/null
+++ b/nvim/after/syntax/markdown.vim
@@ -0,0 +1,8 @@
+syntax keyword singleTextTask task todo thisweek nextweek thisweekend
+syntax keyword singleTextProjects ctrack datamaps bcompiler-engine
+
+syntax keyword singleUrgent urgent important
+
+highlight link singleTextTask markdownH1
+highlight link singleTextProjects markdownListMarker
+highlight link singleUrgent markdownError
diff --git a/nvim/init.vim b/nvim/init.vim
new file mode 100644
index 0000000..6de99ff
--- /dev/null
+++ b/nvim/init.vim
@@ -0,0 +1,739 @@
+"LEMON'S VIMRC - 16 NOVEMBER 2014
+" Preamble
+set t_Co=256
+set background=dark
+set path+=**
+"
+
+"
+nnoremap <C-J> <C-W><C-J>
+nnoremap <C-K> <C-W><C-K>
+nnoremap <C-L> <C-W><C-L>
+nnoremap <C-H> <C-W><C-H>
+
+
+" vertical diff please
+set diffopt=vertical
+
+
+" Remap the leader key
+let mapleader = ","
+
+" map ESCAPE to exit to Normal mode in neovim terminal
+tnoremap <Esc> <C-\><C-N>
+
+
+" Signify mapping & config
+nnoremap <leader>R :SignifyRefresh<CR>
+let g:signify_realtime = 1
+
+
+" Basic options
+
+set cmdheight=1
+set termguicolors
+set inccommand=split
+set foldmethod=manual
+set encoding=utf-8
+set modelines=0
+set relativenumber
+set autoindent
+set showmode
+set cursorline
+set ttyfast
+set ttimeout
+set notimeout
+set nottimeout
+set backspace=indent,eol,start
+set ruler
+set laststatus=2
+set history=1000 " remember more commands and search history
+set undolevels=1000 " use many muchos levels of undo
+set wildignore=*.swp,*.bak,*.pyc,*.class
+set title " change the terminal's title
+set visualbell " don't beep
+set noerrorbells " don't beep
+set number
+set fillchars=diff:⣿,vert:\|
+set noswapfile
+set ruler " show the cursor position all the time
+set showcmd " display incomplete commands
+set vb
+"set list
+set listchars=tab:â–¸\ ,eol:¬,extends:â¯,precedes:â®
+set lazyredraw
+set matchtime=3
+set showbreak=↪
+set shell=/usr/bin/fish
+set splitbelow
+set splitright
+set autowrite
+set autoread
+set linebreak
+set hidden
+"set colorcolumn=80
+"
+" Wildmenu completion
+set wildmenu
+" set wildmode=list:longest " don't like this
+set wildignore+=.hg,.git,.svn " Version control
+set wildignore+=*.aux,*.out,*.toc " LaTeX intermediate files
+set wildignore+=*.jpg,*.bmp,*.gif,*.png,*.jpeg " binary images
+set wildignore+=*.o,*.obj,*.exe,*.dll,*.manifest " compiled object files
+set wildignore+=*.spl " compiled spelling word lists
+set wildignore+=*.sw? " Vim swap files
+set wildignore+=*.DS_Store " OSX bullshit
+set wildignore+=*.luac " Lua byte code
+set wildignore+=migrations " Django migrations
+set wildignore+=*.pyc " Python byte code
+set wildignore+=*.orig " Merge resolution files
+" Clojure/Leiningen
+set wildignore+=classes
+set wildignore+=lib
+
+" Make Vim able to edit crontab files ...
+set backupskip=/tmp/*,/private/tmp/*"
+"
+" Remaps ...
+"NERDTree!
+nmap \e :NERDTreeToggle<CR>
+let NERDTreeIgnore=['\.pyc$', '\~$'] "ignore files in NERDTree
+
+" targbar handler
+nmap <F8> :TagbarToggle<CR>
+
+" Don't use Ex mode, use Q for formatting
+"map Q gq
+
+" easier formatting of paragraphs
+" from https://github.com/thesheff17/youtube/blob/master/vim/vimrc
+vmap Q gq
+nmap Q gqap
+
+" set trailing whitespace to be visible with using special chars with ,s
+"set listchars=tab:>-,trail:*,eol:$
+"nmap <silent> <leader>s :set nolist!<CR>
+" some misc settings
+:nmap \l :setlocal number!<CR>
+:nmap \o :set paste!<CR>
+
+" map sort function to a key
+" from https://github.com/thesheff17/youtube/blob/master/vim/vimrc
+vnoremap <Leader>s :sort<CR>
+
+" Plug Plugs...
+call plug#begin('~/.config/nvim/plugged')
+if has('nvim')
+ Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
+else
+ Plug 'Shougo/deoplete.nvim'
+ Plug 'roxma/nvim-yarp'
+ Plug 'roxma/vim-hug-neovim-rpc'
+endif
+Plug 'google/yapf', { 'rtp': 'plugins/vim', 'for': 'python' }
+Plug 'deoplete-plugins/deoplete-go', {'do': 'make'}
+Plug 'rust-lang/rust.vim'
+Plug 'tpope/vim-commentary'
+Plug 'junegunn/fzf'
+Plug 'junegunn/fzf.vim'
+Plug 'zchee/deoplete-jedi'
+Plug 'davidhalter/jedi'
+Plug 'mhinz/vim-signify' " marking changes in repo
+Plug 'anekos/hledger-vim'
+Plug 'fatih/vim-go', {'do': ':GoUpdateBinaries'}
+Plug 'buoto/gotests-vim'
+Plug 'zchee/deoplete-clang'
+Plug 'w0rp/ale'
+Plug 'tpope/vim-fugitive'
+Plug 'tpope/vim-unimpaired'
+Plug 'tpope/vim-surround'
+Plug 'scrooloose/nerdtree'
+Plug 'majutsushi/tagbar'
+Plug 'SirVer/ultisnips'
+Plug 'honza/vim-snippets'
+Plug 'jlanzarotta/bufexplorer'
+Plug 'itchyny/lightline.vim'
+Plug 'janko-m/vim-test'
+Plug 'tpope/vim-dispatch'
+Plug 'radenling/vim-dispatch-neovim'
+Plug 'Shougo/neoinclude.vim'
+Plug 'psf/black', { 'branch': 'stable' }
+Plug 'sebdah/vim-delve'
+Plug 'tweekmonster/django-plus.vim'
+Plug 'junegunn/limelight.vim'
+Plug 'junegunn/vim-peekaboo'
+call plug#end()
+
+" Lightline config
+let g:lightline = {
+ \ 'colorscheme': 'default',
+ \ 'active': {
+ \ 'left': [ [ 'mode', 'paste' ],
+ \ [ 'gitbranch', 'readonly', 'filename', 'modified' ] ]
+ \ },
+ \ 'component_function': {
+ \ 'gitbranch': 'FugitiveHead'
+ \ },
+ \ }
+
+" point neovim to virtualenv specific to neovim (using 3.7)
+let g:python3_host_prog = "/home/lemon/.virtualenvs/pynvim/bin/python3"
+let g:deoplete#enable_at_startup = 1
+
+"" Some servers have issues with backup files, see #649
+set nobackup
+set nowritebackup
+"
+"" Better display for messages
+"set cmdheight=2
+"
+"" You will have bad experience for diagnostic messages when it's default 4000.
+"set updatetime=300
+"
+"" don't give |ins-completion-menu| messages.
+"set shortmess+=c
+"
+"" always show signcolumns
+"set signcolumn=yes
+"
+
+" .. Rust
+let g:autofmt_autosave = 1
+"
+
+" vim-test config ..
+" use vim-dispatch to run tests in the quickfix window
+" from Modern Vim Ch.4
+" the mappings below are from vim-test
+" https://github.com/janko/vim-test
+" dispatch opens send test output to quickfix window
+"let test#strategy = "dispatch"
+" neovim strategy runs the test in the neovim terminal
+let test#strategy = "neovim"
+let test#python#runner = "pytest"
+let test#neovim#term_position = "topleft"
+let test#python#pytest#options = '--tb=short --color=no'
+let test#go#runner = 'gotest'
+"let test#go#gotest#options = '-v'
+
+" To run mypy using vim-dispath -with Dispatch
+autocmd FileType python let b:dispatch = 'mypy --ignore-missing-imports'
+
+nmap <silent> t<C-n> :TestNearest<CR>
+nmap <silent> t<C-f> :TestFile<CR>
+nmap <silent> t<C-s> :TestSuite<CR>
+"nmap <silent> t<C-l> :TestLast<CR>
+nmap <silent> <S-F10> :TestLast<CR>
+nmap <silent> t<C-g> :TestVisit<CR>
+"
+"
+"
+" clang support ... for Debian Stretch only!
+"let g:deoplete#sources#clang#libclang_path = '/usr/lib/llvm-3.8/lib/libclang.so.1'
+"let g:deoplete#sources#clang#clang_header = '/usr/lib/llvm-3.8/lib/clang/3.8.1/include'
+" works on Debian Buster anyway
+"let g:deoplete#sources#clang#clang_header = '/usr/lib/llvm-6.0/lib/clang/6.0.1/include/'
+let g:deoplete#sources#clang#clang_header = '/usr/include/clang/10/include'
+let g:deoplete#sources#clang#libclang_path = '/usr/lib/llvm-10/lib/libclang-10.so.1'
+"
+" deoplete omnifuc
+let g:deoplete#enable_at_startup = 1
+let g:deoplete#disable_auto_complete = 0
+"call deoplete#custom#option('auto_complete', 0)
+"call deoplete#custom#source('jedi', 'debug_enabled', 1)
+"call deoplete#enable_logging('DEBUG', '/tmp/deoplete.log')
+"inoremap <silent><expr><C-Space> deoplete#mappings#manual_complete()
+"
+" jedi-specific stuff
+" WHICH DOES NOT APPEAR TO WORK
+" USE CTAGS TO GENERATE FILE FOR NAVIGATION
+" e.g ctags ~/.virtualenvs/ctrack/lib64/python3.8/site-packages/**/*.py
+" To pull in a virtualenv - file kept in root of project will automatically
+" be picked up
+" disable autocompletion, cause we use deoplete for completion
+let g:jedi#completions_enabled = 0
+
+" open the go-to function in split, not another buffer
+let g:jedi#use_splits_not_buffers = "right"
+
+let g:jedi#goto_command = "<leader>d"
+let g:jedi#goto_assignments_command = "<leader>g"
+let g:jedi#goto_stubs_command = "<leader>s"
+let g:jedi#goto_definitions_command = ""
+let g:jedi#documentation_command = "K"
+let g:jedi#usages_command = "<leader>n"
+let g:jedi#completions_command = "<C-Space>"
+let g:jedi#rename_command = "<leader>r"
+"
+" golang stuff
+let g:go_term_mode = "split"
+let g:go_term_height = 10
+"autocmd FileType go nmap <leader>r :w<CR>:split <bar> terminal go run %<CR>
+autocmd FileType go nmap <leader>r :GoRun<CR>
+" highlights the variable in the file for you..
+"let g:go_auto_sameids = 1
+" auto import...
+let g:go_fmt_command = "goimports"
+" automatic type info on cursor
+let g:go_auto_type_info = 1
+au Filetype go nmap <leader>ga <Plug>(go-alternate-edit)
+au Filetype go nmap <leader>gah <Plug>(go-alternate-split)
+au Filetype go nmap <leader>gav <Plug>(go-alternate-vertical)
+au FileType go nmap <F10> :GoTest -short<cr>
+au FileType go nmap <F9> :DlvToggleBreakpoint<CR>
+au FileType go nmap <S-F9> :DlvTest<CR>
+au FileType go nmap <F11> :DlvDebug<CR>
+au FileType go nmap <S-F5> :GoRename<CR>
+
+
+" ultisnips...
+"inoremap <silent><expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
+"let g:UltiSnipsExpandTrigger="<tab>"
+"let g:UltiSnipsSnippetsDir = "/home/lemon/dotfiles/Ultisnips"
+"let g:UltiSnipsSnippetDirectories=["/home/lemon/dotfiles/Ultisnips"]
+"" let g:UltiSnipsJumpForwardTrigger="<c-n>"
+"" let g:UltiSnipsJumpBackwardTrigger="<c-p>"
+"let g:UltiSnipsJumpForwardTrigger="<c-j>"
+"let g:UltiSnipsJumpBackwardTrigger="<c-k>"
+
+" yapf - format python code (https://github.com/google/yapf)...
+map <leader>y :call yapf#YAPF()<cr>
+imap <leader>y :call yapf#YAPF()<cr>
+"autocmd FileType python nnoremap <leader>yy :0,$!yapf<Cr><C-o>
+
+
+" isort - sort python imports (https://github.com/timothycrosley/isort) ...
+let maplocalleader = "\\"
+autocmd FileType python nnoremap <LocalLeader>j :!isort %<CR><CR>
+
+
+" Tabs, spaces, wrapping ...
+set tabstop=4
+set shiftwidth=4
+set shiftround
+set softtabstop=4
+set expandtab
+set tw=79 " width of document(used by gd)
+set nowrap "don't automatically wrap on load
+set formatoptions=qrn1j
+set fo-=t " don't automatically wrap text when typing
+"
+"
+" Enable folding ...
+set foldmethod=manual
+set foldlevel=99
+"
+
+
+" Backups ...
+set undodir=~/.nvim-tmp/tmp/undo// "undo files
+set backupdir=~/.nvim-tmp/tmp/backup// " backups
+set directory=~/.nvim-tmp/tmp/swap// " swap files
+set backup " enable backups
+"
+" Highlight VCS conflict markers ...
+match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$'
+
+" Searching and movement ...
+nnoremap / /\v
+vnoremap / /\v
+set ignorecase
+set smartcase
+set incsearch
+set showmatch
+set hlsearch
+set gdefault
+set scrolloff=3
+set sidescroll=1
+set sidescrolloff=10
+set virtualedit+=block
+nnoremap <leader><space> :noh<cr>:call clearmatches()<cr>
+
+nmap \x :cclose<CR>
+
+" Don't move on *
+nnoremap * *<c-o>
+
+" Easier to type move extreme left and right
+noremap H ^
+noremap L g_
+
+" Use ctrl-e and ctrl-a
+inoremap <c-a> <esc>I
+inoremap <c-e> <esc>A
+
+" open a Quickfix window for the last search
+nnoremap <silent> <leader>/ :execute 'vimgrep /'.@/.'/g %'<CR>:copen<CR>
+
+" ##################################
+" Ag!
+"
+" How to do search (May 2020)
+"
+" lgrep -R "search term" .venv
+"
+" (ALE currently hijacks the quicklist which is why we need l there)
+" - to search current directory including
+" virtualenv. Results will open in :lopen (loclist)
+
+" :Ag
+"
+" Will do nice FZF search, but not into gitignored or hidden files.
+"
+" !ag -Q "breakpoint()" .venv
+"
+" will do an exact match search but not populate the loclist.
+" ##################################
+"
+"
+let g:ackprg = 'ag --smart-case --nogroup --nocolor --column'
+" WARNING - IF REPLACE GREP WITH AG, IT DOESN'T POPULATE THE QUICKFIX
+" WHICH IS SOMETHING I WANT FOR BIG SEARCHES
+"if executable('ag')
+" set grepprg=ag\ --nogroup\ --smart-case\ --nocolor\ --column
+" set grepformat=%f:%l:%c:%m
+"endif
+" bind \ (backward slash) to grep shortcut
+" THIS ALLOWS AN ag SEARCH AND PUTS OUTPUT IN Quick Fix window
+" this is great for passing ag flags, such as .venv or Q or whatever
+"command -nargs=+ -complete=file -bar Agg silent! grep! <args>|cwindow|redraw!
+
+
+" (example use :14 to select from menu)
+nnoremap <leader>S :g//#<left><left>
+
+
+" Folding ...
+" Enable folding with the spacebar
+nnoremap <space> za
+nnoremap <leader>fm :set foldmethod=manual<CR>
+" Make zO recursively open whatever fold we're in, even if it's partially open.
+nnoremap zO zczO
+" Use ,z to "focus" the current fold
+nnoremap <leader>z zMzvzz
+
+"" Quick Editing ...
+nnoremap <leader>ev <C-w>s<C-w>j<C-w>L:e $MYVIMRC<cr>
+
+" Convenience mappings ...
+" No more help key.
+noremap <F1> :checktime<cr>
+inoremap <F1> <esc>:checktime<cr>
+
+" Kill window
+"nnoremap <leader>K :q<cr>
+
+" Wrap
+nnoremap <leader>W :set wrap!<cr>
+
+" Change case
+"noremap <C-S-u> gUiw
+"inoremap <C-S-u> <esc> gUiwea
+
+" Substitute
+nnoremap <leader>su :%s//<left>
+nnoremap <Leader>s :%s/<C-r><C-w>//g<Left><Left>
+"
+" Emacs bindings in command line mode
+cnoremap <c-a> <home>
+cnoremap <c-e> <end>
+
+" Turn off vimdiff
+nnoremap <leader>D :diffoff!<cr>
+
+" Formatting, like Textmate
+nnoremap Q gqip
+
+" Easier linewise reselection
+nnoremap <leader>V V`]
+
+" Split line (colleague of Join lines)
+nnoremap S i<cr><esc><right>
+
+" Source the current line
+vnoremap <leader>S y:execute @@<cr>:echo 'Sourced selection.'<cr>
+nnoremap <leader>S ^vg_y:execute @@<cr>:echo 'Sourced line.'<cr>
+
+" Select (charwise) the contents of the current line, excluding indentation.
+" Great for pasting Python lines into REPLs.
+nnoremap vv ^vg_
+
+" Mutt ...
+augroup ft_muttrc
+ au!
+
+ au BufRead,BufNewFile *.muttrc set ft=muttrc
+
+ au FileType muttrc setlocal foldmethod=marker foldmarker=,}}}
+augroup END
+"
+
+" vim-fugitive ...
+" prevent buffer build-up
+autocmd BufReadPost fugitive://* set bufhidden=delete
+"
+" ALE statusline ...
+"set statusline+=%{ALEGetStatusLine()}
+"let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '• ok']
+"let g:ale_linters = {'python': ['flake8'],}
+
+
+" ale setting..
+"let g:ale_lint_on_text_changed = 'never'
+
+" black config ...
+"let g:black_virtualenv = "/home/lemon/.virtualenvs/black-for-vim/"
+"nmap <leader>l :Black<CR>
+" LET'S RUN VIRTUALENV BLACK ON SAVE!
+"autocmd BufWritePre *.py execute ':Black'
+"let g:black_virtualenv = $VIRTUAL_ENV
+
+
+let g:ale_enabled = 1
+let g:ale_sign_column_always = 1
+let g:ale_open_list = 0
+let g:ale_set_highlights = 1
+let g:ale_set_signs = 1
+let g:ale_set_loclist = 0
+let g:ale_set_quickfix = 1
+let g:ale_echo_cursor = 1
+let g:ale_echo_msg_error_str = 'Error'
+let g:ale_echo_msg_format = '%linter% - %code: %%s'
+let g:ale_loclist_msg_format = '%linter% - %code: %%s'
+let g:ale_echo_msg_warning_str = 'Warning'
+"let g:ale_linters = {'python': ['flake8', 'mypy', 'pyls', 'pylint'],
+"\ 'ocaml': ['merlin'],
+" \}
+let g:ale_linters = {'python': ['flake8', 'mypy'],
+\ 'ocaml': ['merlin'],
+\ 'cpp': ['clang'],
+\ 'c': ['clang'],
+\ 'go': ['gometalinter', 'gofmt'],
+ \}
+"let g:ale_linters_ignore = {'python': ['pyls']}
+let g:ale_fixers = {'python': ['isort', 'black']}
+let g:ale_python_mypy_ignore_invalid_syntax = 1
+let g:ale_python_mypy_executable = 'mypy'
+let g:ale_python_mypy_options = '--config-file mypy.ini'
+" let g:ale_sign_error = '>>'
+let g:ale_sign_warning = '--'
+let g:ale_fix_on_save = 1
+let g:ale_linters_explicit = 0
+
+
+" Mappings in the style of unimpaired-next
+nmap [W <Plug>(ale_first)
+nmap [w <Plug>(ale_previous)
+nmap ]w <Plug>(ale_next)
+nmap ]W <Plug>(ale_last)
+
+
+" Bufexplorer config ...
+let g:bufExplorerDefaultHelp=1 " Show default help.
+let g:bufExplorerShowNoName=1 " Show "No Name" buffers.
+let g:bufExplorerShowUnlisted=1 " Show unlisted buffers.
+"
+" Django ...
+augroup ft_django
+ au!
+
+ au BufNewFile,BufRead urls.py setlocal nowrap
+ au BufNewFile,BufRead urls.py normal! zR
+ au BufNewFile,BufRead dashboard.py normal! zR
+ au BufNewFile,BufRead local_settings.py normal! zR
+
+ au BufNewFile,BufRead admin.py setlocal filetype=python.django
+ au BufNewFile,BufRead urls.py setlocal filetype=python.django
+ au BufNewFile,BufRead models.py setlocal filetype=python.django
+ au BufNewFile,BufRead views.py setlocal filetype=python.django
+ au BufNewFile,BufRead settings.py setlocal filetype=python.django
+ au BufNewFile,BufRead settings.py setlocal foldmethod=marker
+ au BufNewFile,BufRead forms.py setlocal filetype=python.django
+ au BufNewFile,BufRead common_settings.py setlocal filetype=python.django
+ au BufNewFile,BufRead common_settings.py setlocal foldmethod=marker
+augroup END
+
+" vim-markdown ...
+let g:vim_markdown_folding_disabled=1
+set foldenable
+let g:vim_markdown_initial_foldlevel=1
+let g:vim_markdown_no_default_key_mappings=1
+let g:vim_markdown_math=1
+let g:vim_markdown_frontmatter=1
+"
+" get rid of annoying Press ENTER prompts etc ...
+"set shortmess=atI
+"
+" Remap movement in windows ...
+map <c-j> <c-w>j
+map <c-k> <c-w>k
+map <c-l> <c-w>l
+map <c-h> <c-w>h
+
+" General python properness ...
+autocmd FileType python set sw=4
+autocmd FileType python set ts=4
+autocmd FileType python set sts=4
+
+" Escape sudo heck ...
+cmap w!! %!sudo tee > /dev/null %
+
+
+" my todo.todo... {{
+autocmd BufNewFile,BufRead *.todo set syntax=markdown
+"autocmd BufWritePost *.todo !todo-push
+nmap <F2> a<C-R>=strftime("%c")<CR><Esc>
+"let @d=':r! date _€kb-I i€kb ($a)0"+dd:!xlcip€kb€kb€kb€kbclip -o >> /home/lemon/todo/done.todo '
+let @d='0$a(€k2a)0"+dd:!xlcip€kb€kb€kb€kbclip -o >> /home/lemon/todo/done.todo '
+" ...}}
+
+"
+" FZF ...
+" This is the default extra key bindings
+let g:fzf_action = {
+ \ 'ctrl-t': 'tab split',
+ \ 'ctrl-x': 'split',
+ \ 'ctrl-v': 'vsplit' }
+
+" Default fzf layout
+" - down / up / left / right
+let g:fzf_layout = { 'down': '~40%' }
+
+" Customize fzf colors to match your color scheme
+let g:fzf_colors =
+\ { 'fg': ['fg', 'Normal'],
+ \ 'bg': ['bg', 'Normal'],
+ \ 'hl': ['fg', 'Comment'],
+ \ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
+ \ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
+ \ 'hl+': ['fg', 'Statement'],
+ \ 'info': ['fg', 'PreProc'],
+ \ 'prompt': ['fg', 'Conditional'],
+ \ 'pointer': ['fg', 'Exception'],
+ \ 'marker': ['fg', 'Keyword'],
+ \ 'spinner': ['fg', 'Label'],
+ \ 'header': ['fg', 'Comment'] }
+" More fzf settings
+" (https://github.com/zenbro/dotfiles/blob/master/.nvimrc#L151-L187)
+ let g:fzf_nvim_statusline = 0 " disable statusline overwriting
+
+ nnoremap <C-p> :<C-u>FZF<CR>
+ nnoremap <leader><C-p> :<C-u>FZF!<CR>
+ nnoremap ; :Buffers<CR>
+ nnoremap <leader>t :Files<CR>
+ nnoremap <leader>o :Tags<CR>
+ nnoremap <leader>h :History<CR>
+ nnoremap <silent> <leader>0 :Files<CR>
+ nnoremap <silent> <leader>A :Windows<CR>
+ nnoremap <silent> <leader>; :BLines<CR>
+ nnoremap <silent> <leader>l :Lines<CR>
+" nnoremap <silent> <leader># :Lines<CR>
+ nnoremap <silent> <leader>o :BTags<CR>
+" command history is :History:
+ nnoremap <silent> <leader>? :History:<CR>
+ nnoremap <silent> <leader>/ :execute 'Ag ' . input('Ag/')<CR>
+" nnoremap <silent> <leader>. :AgIn #
+" nnoremap <silent> <leader>a :Buffers<CR>
+" nnoremap <silent> <leader>O :Tags<CR>
+ nnoremap <silent> <leader>P :call SearchWordWithAg()<CR>
+ vnoremap <silent> <leader>P :call SearchVisualSelectionWithAg()<CR>
+" nnoremap <silent> <leader>gl :Commits<CR>
+" nnoremap <silent> <leader>ga :BCommits<CR>
+ nnoremap <silent> <leader>ft :Filetypes<CR>
+ nnoremap <silent> <leader>CC :Commands<CR>
+
+ imap <C-x><C-f> <plug>(fzf-complete-file-ag)
+ imap <C-x><C-l> <plug>(fzf-complete-line)
+
+ function! SearchWordWithAg()
+ execute 'Ag' expand('<cword>')
+ endfunction
+
+ function! SearchVisualSelectionWithAg() range
+ let old_reg = getreg('"')
+ let old_regtype = getregtype('"')
+ let old_clipboard = &clipboard
+ set clipboard&
+ normal! ""gvy
+ let selection = getreg('"')
+ call setreg('"', old_reg, old_regtype)
+ let &clipboard = old_clipboard
+ execute 'Ag' selection
+ endfunction
+
+" function! SearchWithAgInDirectory(...)
+" call fzf#vim#ag(join(a:000[1:], ' '), extend({'dir': a:1}, g:fzf#vim#default_layout))
+" endfunction
+" command! -nargs=+ -complete=dir AgIn call SearchWithAgInDirectory(<f-args>)
+
+" Enable per-command history.
+" CTRL-N and CTRL-P will be automatically bound to next-history and
+" previous-history instead of down and up. If you don't like the change,
+" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.
+let g:fzf_history_dir = '~/.local/share/fzf-history'
+"
+" Mapping selecting mappings
+nmap <leader><tab> <plug>(fzf-maps-n)
+xmap <leader><tab> <plug>(fzf-maps-x)
+omap <leader><tab> <plug>(fzf-maps-o)
+
+" Insert mode completion
+imap <c-x><c-k> <plug>(fzf-complete-word)
+imap <c-x><c-f> <plug>(fzf-complete-path)
+imap <c-x><c-j> <plug>(fzf-complete-file-ag)
+imap <c-x><c-l> <plug>(fzf-complete-line)
+
+" Advanced customization using autoload functions
+inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'left': '15%'}
+"
+"
+" Ocaml/merlin
+"let g:opamshare = substitute(system('opam config var share'),'\n$','','''')
+"execute "set rtp+=" . g:opamshare . "/merlin/vim"
+"set rtp^="/home/lemon/.opam/4.06.1/share/ocp-indent/vim"
+"
+
+" Search from git root via :Rag (Root Ag)
+" Thanks! https://github.com/fortes/dotfiles/blob/7ba6ea651edde8fbc24fdf9df52ba06f7e956efc/stowed-files/nvim/.vimrc
+" :Rag - hidden preview enabled with "?" key
+" :Rag! - fullscreen and preview window above
+
+" Change to git root of current file (if in a repo)
+function! FindGitRootCD()
+ let root = systemlist('git -C ' . expand('%:p:h') . ' rev-parse --show-toplevel')[0]
+ if v:shell_error
+ return ''
+ else
+ return {'dir': root}
+ endif
+endfunction
+
+
+function! GitRootCD()
+ let result = FindGitRootCD()
+ if type(result) == type({})
+ execute 'lcd' fnameescape(result['dir'])
+ echo 'Now in '.result['dir']
+ else
+ echo 'Not in git repo!'
+ endif
+endfunction
+
+command! GitRootCD :call GitRootCD()
+
+command! -bang -nargs=* Rag
+ \ call GitRootCD() | call fzf#vim#ag(<q-args>,
+ \ <bang>0 ? fzf#vim#with_preview('up:60%', '?')
+ \ : fzf#vim#with_preview('right:50%:hidden', '?'),
+ \ <bang>0)
+
+" Use fuzzy searching for K & Q, select items to go into quickfix
+nnoremap L :Rag! <C-R><C-W><cr>
+vnoremap L :<C-u>norm! gv"sy<cr>:silent! Rag! <C-R>s<cr>
+nnoremap Q :Rag!<SPACE>
+"
+
+"highlight ColorColumn ctermbg=0
+highlight NonText cterm=NONE
+"
+syntax enable
diff --git a/obnam.conf b/obnam.conf
new file mode 100644
index 0000000..31db9e4
--- /dev/null
+++ b/obnam.conf
@@ -0,0 +1,3 @@
+[config]
+repository = sftp://192.168.1.101/media/usbdrivesilver2/backups/
+log = /home/lemon/Documents/obnam.log
diff --git a/offlineimap.py b/offlineimap.py
new file mode 100644
index 0000000..9a64c0c
--- /dev/null
+++ b/offlineimap.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
+from subprocess import check_output
+
+def get_pass(account):
+ return check_output("pass Email/" + account, shell=True).splitlines()[0]
diff --git a/offlineimaprc b/offlineimaprc
new file mode 100644
index 0000000..dd4181c
--- /dev/null
+++ b/offlineimaprc
@@ -0,0 +1,61 @@
+[general]
+ui = TTY.TTYUI
+accounts = MatthewLemon, Gmail
+pythonfile=~/.offlineimap.py
+fsync = False
+
+[Account MatthewLemon]
+localrepository = MatthewLemon-Local
+remoterepository = MatthewLemon-Remote
+#status_backend = sqlite
+postsynchook = notmuch new
+
+[Repository MatthewLemon-Local]
+type = Maildir
+localfolders = ~/.mail/matt-matthewlemon.com
+# nametrans = lambda folder: {'drafts': '/Drafts',
+# 'sent': '/Sent',
+# 'archive': '/Archive',
+# 'inbox': '/Inbox',
+# }.get(folder, folder)
+
+[Repository MatthewLemon-Remote]
+#cert_fingerprint = 54137524fe721f0cbb8a6a0e1e280ade50482e29
+maxconnections = 3
+type = IMAP
+remotehost = mail.messagingengine.com
+ssl = yes
+sslcacertfile = /etc/ssl/certs/ca-certificates.crt
+remoteuser = matthewlemon@fastmail.fm
+remotepasseval = get_pass("fastmail")
+#remotepasseval = keyring.get_password('offlineimap', 'matthewlemon')
+# nametrans = lamda folder: {'/Drafts': 'drafts',
+# '/Sent': 'sent',
+# '/Archive': 'archive',
+# '/Inbox': 'inbox',
+# }.get(folder, folder)
+#folderfilter = lambda folder: folder in ['INBOX', 'INBOX.Sent', 'INBOX.Archive', 'INBOX.Drafts']
+folderfilter = lambda folder: folder in ['INBOX', 'INBOX.Sent Items', 'INBOX.Archive', 'INBOX.Drafts']
+
+[Account Gmail]
+localrepository = Gmail-Local
+remoterepository = Gmail-Remote
+synclabels = yes
+
+[Repository Gmail-Local]
+type = GmailMaildir
+localfolders = ~/.mail/matthew.lemon-gmail.com
+
+[Repository Gmail-Remote]
+type = Gmail
+remoteuser = matthew.lemon@gmail.com
+remotepass = hvhmfbdlgggebxgc
+nametrans = lambda folder: {'drafts': '/Drafts',
+ 'sent': '/Sent',
+ 'archive': '/Archive',
+ 'inbox': '/Inbox',
+ }.get(folder, folder)
+folderfilter = lambda foldername: foldername not in ['Gmail]/All Mail']
+sslcacertfile = /etc/ssl/certs/ca-certificates.crt
+ssl_version = tls1_2
+
diff --git a/pdbrc b/pdbrc
new file mode 100644
index 0000000..f332aa7
--- /dev/null
+++ b/pdbrc
@@ -0,0 +1,30 @@
+Ned's .pdbrc
+
+# Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names.
+alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k]))
+
+# Print the instance variables of a thing.
+alias pi p_ %1.__dict__ %1.
+
+# Print the instance variables of self.
+alias ps pi self
+
+# Print the locals.
+alias pl p_ locals() local:
+
+# Next and list, and step and list.
+alias nl n;;l
+alias sl s;;l
+
+# Short cuts for walking up and down the stack
+alias uu u;;u
+alias uuu u;;u;;u
+alias uuuu u;;u;;u;;u
+alias uuuuu u;;u;;u;;u;;u
+alias dd d;;d
+alias ddd d;;d;;d
+alias dddd d;;d;;d;;d
+alias ddddd d;;d;;d;;d;;d
+
+
+# Taken from https://stackoverflow.com/questions/1623039/python-debugging-tips
diff --git a/pdbrc.py b/pdbrc.py
new file mode 100644
index 0000000..b3a8675
--- /dev/null
+++ b/pdbrc.py
@@ -0,0 +1,63 @@
+# import pdb
+#
+#
+# class Config(pdb.DefaultConfig):
+# sticky_by_default = True
+# current_line_color = 93
+# use_pygments = True
+# colorscheme =
+#
+#
+# def _pdbrc_init():
+# # Save history across sessions
+# import readline
+# histfile = ".pdb-pyhist"
+# try:
+# readline.read_history_file(histfile)
+# except IOError:
+# pass
+# import atexit
+# atexit.register(readline.write_history_file, histfile)
+# readline.set_history_length(500)
+#
+#
+# _pdbrc_init()
+# del _pdbrc_init
+
+
+import readline
+import pdb
+
+
+class Config(pdb.DefaultConfig):
+
+ editor = 'e'
+ stdin_paste = 'epaste'
+ filename_color = pdb.Color.lightgray
+ use_terminal256formatter = False
+ sticky_by_default = True
+ #exec_if_unfocused = "play ~/sounds/dialtone.wav 2> /dev/null &"
+
+ def __init__(self):
+ # readline.parse_and_bind('set convert-meta on')
+ # readline.parse_and_bind('Meta-/: complete')
+
+ try:
+ from pygments.formatters import terminal
+ except ImportError:
+ pass
+ else:
+ self.colorscheme = terminal.TERMINAL_COLORS.copy()
+ self.colorscheme.update({
+ terminal.Keyword: ('darkred', 'red'),
+ terminal.Number: ('darkyellow', 'yellow'),
+ terminal.String: ('brown', 'green'),
+ terminal.Name.Function: ('darkgreen', 'blue'),
+ terminal.Name.Namespace: ('teal', 'turquoise'),
+ })
+
+ def setup(self, pdb):
+ # make 'l' an alias to 'longlist'
+ Pdb = pdb.__class__
+ Pdb.do_l = Pdb.do_longlist
+ Pdb.do_st = Pdb.do_sticky
diff --git a/profile b/profile
new file mode 100644
index 0000000..078bdc9
--- /dev/null
+++ b/profile
@@ -0,0 +1,28 @@
+# ~/.profile: executed by the command interpreter for login shells.
+# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
+# exists.
+# see /usr/share/doc/bash/examples/startup-files for examples.
+# the files are located in the bash-doc package.
+
+# the default umask is set in /etc/profile; for setting the umask
+# for ssh logins, install and configure the libpam-umask package.
+#umask 022
+
+# if running bash
+if [ -n "$BASH_VERSION" ]; then
+ # include .bashrc if it exists
+ if [ -f "$HOME/.bashrc" ]; then
+ . "$HOME/.bashrc"
+ fi
+fi
+
+# set PATH so it includes user's private bin if it exists
+if [ -d "$HOME/bin" ] ; then
+ PATH="$HOME/bin:$PATH"
+fi
+
+export PATH="$HOME/.poetry/bin:$PATH"
+export PATH="$HOME/.cargo/bin:$PATH"
+export PATH=/usr/local/go/bin:$PATH
+export PATH=~/.local/bin:$PATH
+export PATH=~/scripts:$PATH
diff --git a/ptpython/config.py b/ptpython/config.py
new file mode 100644
index 0000000..92292af
--- /dev/null
+++ b/ptpython/config.py
@@ -0,0 +1,177 @@
+"""
+Configuration example for ``ptpython``.
+
+Copy this file to ~/.ptpython/config.py
+"""
+from __future__ import unicode_literals
+from prompt_toolkit.filters import ViInsertMode
+from prompt_toolkit.key_binding.key_processor import KeyPress
+#from prompt_toolkit.key_binding.input_processor import KeyPress
+from prompt_toolkit.keys import Keys
+from pygments.token import Token
+
+from ptpython.layout import CompletionVisualisation
+
+__all__ = (
+ 'configure',
+)
+
+
+def configure(repl):
+ """
+ Configuration method. This is called during the start-up of ptpython.
+
+ :param repl: `PythonRepl` instance.
+ """
+ # Show function signature (bool).
+ repl.show_signature = True
+
+ # Show docstring (bool).
+ repl.show_docstring = False
+
+ # Show the "[Meta+Enter] Execute" message when pressing [Enter] only
+ # inserts a newline instead of executing the code.
+ repl.show_meta_enter_message = True
+
+ # Show completions. (NONE, POP_UP, MULTI_COLUMN or TOOLBAR)
+ repl.completion_visualisation = CompletionVisualisation.POP_UP
+
+ # When CompletionVisualisation.POP_UP has been chosen, use this
+ # scroll_offset in the completion menu.
+ repl.completion_menu_scroll_offset = 0
+
+ # Show line numbers (when the input contains multiple lines.)
+ repl.show_line_numbers = True
+
+ # Show status bar.
+ repl.show_status_bar = True
+
+ # When the sidebar is visible, also show the help text.
+ repl.show_sidebar_help = True
+
+ # Highlight matching parethesis.
+ repl.highlight_matching_parenthesis = True
+
+ # Line wrapping. (Instead of horizontal scrolling.)
+ repl.wrap_lines = True
+
+ # Mouse support.
+ repl.enable_mouse_support = True
+
+# # Complete while typing. (Don't require tab before the
+# # completion menu is shown.)
+# repl.complete_while_typing = True
+#
+# # Vi mode.
+# repl.vi_mode = True
+#
+# # Paste mode. (When True, don't insert whitespace after new line.)
+# repl.paste_mode = False
+#
+# # Use the classic prompt. (Display '>>>' instead of 'In [1]'.)
+# repl.prompt_style = 'classic' # 'classic' or 'ipython'
+#
+# # Don't insert a blank line after the output.
+# repl.insert_blank_line_after_output = False
+#
+# # History Search.
+# # When True, going back in history will filter the history on the records
+# # starting with the current input. (Like readline.)
+# # Note: When enable, please disable the `complete_while_typing` option.
+# # otherwise, when there is a completion available, the arrows will
+# # browse through the available completions instead of the history.
+# repl.enable_history_search = False
+#
+# # Enable auto suggestions. (Pressing right arrow will complete the input,
+# # based on the history.)
+# repl.enable_auto_suggest = False
+#
+# # Enable open-in-editor. Pressing C-X C-E in emacs mode or 'v' in
+# # Vi navigation mode will open the input in the current editor.
+# repl.enable_open_in_editor = True
+#
+# # Enable system prompt. Pressing meta-! will display the system prompt.
+# # Also enables Control-Z suspend.
+# repl.enable_system_bindings = True
+#
+# # Ask for confirmation on exit.
+# repl.confirm_exit = True
+#
+# # Enable input validation. (Don't try to execute when the input contains
+# # syntax errors.)
+# repl.enable_input_validation = True
+#
+# # Use this colorscheme for the code.
+# repl.use_code_colorscheme('vim')
+#
+# # Enable 24bit True color. (Not all terminals support this. -- maybe check
+# # $TERM before changing.)
+# repl.true_color = False
+#
+# # Install custom colorscheme named 'my-colorscheme' and use it.
+# repl.install_ui_colorscheme('my-colorscheme', _custom_ui_colorscheme)
+# repl.use_ui_colorscheme('my-colorscheme')
+#
+# # Add custom key binding for PDB.
+# @repl.add_key_binding(Keys.ControlB)
+# def _(event):
+# ' Pressing Control-B will insert "pdb.set_trace()" '
+# event.cli.current_buffer.insert_text('\nimport pdb; pdb.set_trace()\n')
+#
+# # Typing ControlE twice should also execute the current command.
+# # (Alternative for Meta-Enter.)
+# @repl.add_key_binding(Keys.ControlE, Keys.ControlE)
+# def _(event):
+# b = event.current_buffer
+# if b.accept_action.is_returnable:
+# b.accept_action.validate_and_handle(event.cli, b)
+#
+#
+# # Typing 'jj' in Vi Insert mode, should send escape. (Go back to navigation
+# # mode.)
+# @repl.add_key_binding('j', 'j', filter=ViInsertMode())
+# def _(event):
+# " Map 'jj' to Escape. "
+# event.cli.input_processor.feed(KeyPress(Keys.Escape))
+#
+# """
+# # Custom key binding for some simple autocorrection while typing.
+# corrections = {
+# 'impotr': 'import',
+# 'pritn': 'print',
+# }
+#
+# @repl.add_key_binding(' ')
+# def _(event):
+# ' When a space is pressed. Check & correct word before cursor. '
+# b = event.cli.current_buffer
+# w = b.document.get_word_before_cursor()
+#
+# if w is not None:
+# if w in corrections:
+# b.delete_before_cursor(count=len(w))
+# b.insert_text(corrections[w])
+#
+# b.insert_text(' ')
+# """
+#
+#
+# Custom colorscheme for the UI. See `ptpython/layout.py` and
+# `ptpython/style.py` for all possible tokens.
+_custom_ui_colorscheme = {
+ # Blue prompt.
+ Token.Layout.Prompt: 'bg:#eeeeff #000000 bold',
+
+ # Make the status toolbar red.
+ Token.Toolbar.Status: 'bg:#ff0000 #000000',
+
+ # test from ptpython/style.py
+ # Completer menu.
+ Token.Menu.Completions.Completion: 'bg:#44bbbb #000000',
+ Token.Menu.Completions.Completion.Current: 'bg:#008888 #ffffff',
+ Token.Menu.Completions.Meta: 'bg:#449999 #000000',
+ Token.Menu.Completions.Meta.Current: 'bg:#00aaaa #000000',
+ Token.Menu.Completions.ProgressBar: 'bg:#aaaaaa',
+ Token.Menu.Completions.ProgressButton: 'bg:#000000',
+ #
+}
diff --git a/pypirc b/pypirc
new file mode 100644
index 0000000..9938cf0
--- /dev/null
+++ b/pypirc
@@ -0,0 +1,9 @@
+[testpypi]
+repository = https://test.pypi.org/legacy/
+username = mrlemon
+password = deg4em7quib7kib
+
+[pypi]
+repository = https://pypi.org
+username = mrlemon
+password = MxA3yaO9vAjqznu9
diff --git a/qutebrowser/bookmarks/urls b/qutebrowser/bookmarks/urls
new file mode 100644
index 0000000..e197543
--- /dev/null
+++ b/qutebrowser/bookmarks/urls
@@ -0,0 +1,26 @@
+https://b2b.enterprise.co.uk/Pages/CreateReservation.aspx Create Reservation
+https://regex101.com/ Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript
+https://github.com/insanum/gcalcli/pull/402#discussion_r249528101 Better user interaction during prompts when adding an event by hammerheadlemon · Pull Request #402 · insanum/gcalcli
+https://ronver.xyz/apps/files/?dir=/&fileid=10344 Files - Nextcloud
+https://getoutline.org/en/home Outline VPN - Making it safer to break the news
+https://wiki.lineageos.org/adb_fastboot_guide.html Using ADB and fastboot | LineageOS Wiki
+https://wiki.lineageos.org/devices/bacon/install Install LineageOS on bacon | LineageOS Wiki
+https://learning.oreilly.com/home/ Home
+https://app.programmingfonts.org/#ubuntu Programming Fonts - Test Drive
+https://duckduckgo.com/?q=javascript%3A%28function%28%29%257Bvar%2520a%3Dwindow%2Cb%3Ddocument%2Cc%3DencodeURIComponent%2Ce%3Dc%28document.title%29%2Cd%3Da.open%28%27https%3A//ronver.xyz/index.php/apps/bookmarks/bookmarklet%3Foutput%3Dpopup%26url%3D%27%2Bc%28b.location%29%2B%27%26title%3D%27%2Be%2C%27bkmk_popup%27%2C%27left%3D%27%2B%28%28a.screenX%257C%257Ca.screenLeft%29%2B10%29%2B%27%2Ctop%3D%27%2B%28%28a.screenY%257C%257Ca.screenTop%29%2B10%29%2B%27%2Cheight%3D500px%2Cwidth%3D550px%2Cresizable%3D1%2CalwaysRaised%3D1%27%29%3Ba.setTimeout%28function%28%29%257Bd.focus%28%29%257D%2C300%29%3B%257D%29%28%29%3B duckduckgo.com
+https://gist.github.com/Zearin/2f40b7b9cfc51132851a The best explanation of Python decorators I’ve ever seen. (An archived answer from StackOverflow.)
+https://pymotw.com/3/subprocess/ subprocess — Spawning Additional Processes — PyMOTW 3
+https://www.edenred.uk.com/Scripts/Secure/Login/Login.aspx?so_SID= Welcome to Edenred (UK Group) Limited
+https://cardsonline-commercial.com/RBSG_Commercial/Login.do?promoCode=NatWest Cards OnLine
+https://www.openstreetmap.org/#map=19/51.52061/-0.08970 OpenStreetMap
+https://twitter.com/ Twitter
+https://ronver.xyz/apps/bookmarks/#all Bookmarks - Nextcloud
+https://pymotw.com/3/ Python 3 Module of the Week — PyMOTW 3
+https://www.civilservicejobs.service.gov.uk/csr/index.cgi?SID= Civil Service job search - Civil Service Jobs - GOV.UK
+https://www.youtube.com/ YouTube
+https://docs.google.com/spreadsheets/d/1KsW4Hm2NM4JaT8HzdYW_mv4dR7gdAyW2XWdI6ths5Eo/edit#gid=0 DfT Maritime - Timesheet - Google Sheets
+https://www.britishgas.co.uk/my-account/premises/001A4BF58A241ED1A0B0FB818A255E00/accounts/payments/energy-accounts/851009058057/make-a-payment/payment-setup/card-details My account
+https://wiki.lineageos.org/upgrading.html Upgrading LineageOS | LineageOS Wiki
+http://www.qutebrowser.org/doc/help/commands.html | qutebrowser
+http://wellclosemedicalgroup.co.uk/ Well Close Medical Group
+https://trello.com/c/ov4CrxWa/1066-bean-and-halloumi-stew Bean and Halloumi Stew on ðŸ´Food and Meal Planning | Trello
diff --git a/qutebrowser/config.py b/qutebrowser/config.py
new file mode 100644
index 0000000..b77efb8
--- /dev/null
+++ b/qutebrowser/config.py
@@ -0,0 +1,1807 @@
+## Autogenerated config.py
+## Documentation:
+## qute://help/configuring.html
+## qute://help/settings.html
+
+## This is here so configs done via the GUI are still loaded.
+## Remove it to not load settings done via the GUI.
+# config.load_autoconfig()
+
+## Aliases for commands. The keys of the given dictionary are the
+## aliases, while the values are the commands they map to.
+## Type: Dict
+c.aliases = {"ncbookmark": "open -t https://ronver.xyz/index.php/apps/bookmarks/bookmarklet?output=popup&url="}
+# c.aliases = {'w': 'session-save', 'q': 'quit', 'wq': 'quit --save'}
+#c.aliases.update({"ncbookmark": "jseval javascript:(function(){var a=window,b=document,c=encodeURIComponent,e=c(document.title),d=a.open('https://ronver.xyz/index.php/apps/bookmarks/bookmarklet?output=popup&url=');});" })
+#c.aliases.update({"ncbookmark": "jseval javascript:(function(){var a=window,b=document,c=encodeURIComponent,e=c(document.title),d=a.open('https://ronver.xyz/index.php/apps/bookmarks/bookmarklet?output=popup&url='+c(b.location)+'&title='+e,'bkmk_popup','left='+((a.screenX||a.screenLeft)+10)+',top='+((a.screenY||a.screenTop)+10)+',height=500px,width=550px,resizable=1,alwaysRaised=1');a.setTimeout(function(){d.focus()},300);});" })
+## Time interval (in milliseconds) between auto-saves of
+## config/cookies/etc.
+## Type: Int
+# c.auto_save.interval = 15000
+
+## Always restore open sites when qutebrowser is reopened.
+## Type: Bool
+c.auto_save.session = True
+
+# Remove images and javascript from sites
+#c.content.images = False
+#config.set('content.images', False, '*://www.bbc.co.uk/*')
+#config.set('content.javascript.enabled', False, '*://www.bbc.co.uk/*')
+#
+#config.set('content.images', False, '*://www.telegraph.co.uk/*')
+#config.set('content.javascript.enabled', False, '*://www.telegraph.co.uk/*')
+
+c.content.javascript.enabled = False
+
+
+## Backend to use to display websites. qutebrowser supports two different
+## web rendering engines / backends, QtWebKit and QtWebEngine. QtWebKit
+## was discontinued by the Qt project with Qt 5.6, but picked up as a
+## well maintained fork: https://github.com/annulen/webkit/wiki -
+## qutebrowser only supports the fork. QtWebEngine is Qt's official
+## successor to QtWebKit. It's slightly more resource hungry than
+## QtWebKit and has a couple of missing features in qutebrowser, but is
+## generally the preferred choice.
+## Type: String
+## Valid values:
+## - webengine: Use QtWebEngine (based on Chromium).
+## - webkit: Use QtWebKit (based on WebKit, similar to Safari).
+# c.backend = 'webengine'
+
+## This setting can be used to map keys to other keys. When the key used
+## as dictionary-key is pressed, the binding for the key used as
+## dictionary-value is invoked instead. This is useful for global
+## remappings of keys, for example to map Ctrl-[ to Escape. Note that
+## when a key is bound (via `bindings.default` or `bindings.commands`),
+## the mapping is ignored.
+## Type: Dict
+# c.bindings.key_mappings = {'<Ctrl-[>': '<Escape>', '<Ctrl-6>': '<Ctrl-^>', '<Ctrl-M>': '<Return>', '<Ctrl-J>': '<Return>', '<Shift-Return>': '<Return>', '<Enter>': '<Return>', '<Shift-Enter>': '<Return>', '<Ctrl-Enter>': '<Ctrl-Return>'}
+
+## Background color of the completion widget category headers.
+## Type: QssColor
+# c.colors.completion.category.bg = 'qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #888888, stop:1 #505050)'
+
+## Bottom border color of the completion widget category headers.
+## Type: QssColor
+# c.colors.completion.category.border.bottom = 'black'
+
+## Top border color of the completion widget category headers.
+## Type: QssColor
+# c.colors.completion.category.border.top = 'black'
+
+## Foreground color of completion widget category headers.
+## Type: QtColor
+# c.colors.completion.category.fg = 'white'
+
+## Background color of the completion widget for even rows.
+## Type: QssColor
+# c.colors.completion.even.bg = '#333333'
+
+## Text color of the completion widget. May be a single color to use for
+## all columns or a list of three colors, one for each column.
+## Type: List of QtColor, or QtColor
+# c.colors.completion.fg = ['white', 'white', 'white']
+
+## Background color of the selected completion item.
+## Type: QssColor
+# c.colors.completion.item.selected.bg = '#e8c000'
+
+## Bottom border color of the selected completion item.
+## Type: QssColor
+# c.colors.completion.item.selected.border.bottom = '#bbbb00'
+
+## Top border color of the completion widget category headers.
+## Type: QssColor
+# c.colors.completion.item.selected.border.top = '#bbbb00'
+
+## Foreground color of the selected completion item.
+## Type: QtColor
+# c.colors.completion.item.selected.fg = 'black'
+
+## Foreground color of the matched text in the completion.
+## Type: QssColor
+# c.colors.completion.match.fg = '#ff4444'
+
+## Background color of the completion widget for odd rows.
+## Type: QssColor
+# c.colors.completion.odd.bg = '#444444'
+
+## Color of the scrollbar in the completion view.
+## Type: QssColor
+# c.colors.completion.scrollbar.bg = '#333333'
+
+## Color of the scrollbar handle in the completion view.
+## Type: QssColor
+# c.colors.completion.scrollbar.fg = 'white'
+
+## Background color for the download bar.
+## Type: QssColor
+# c.colors.downloads.bar.bg = 'black'
+
+## Background color for downloads with errors.
+## Type: QtColor
+# c.colors.downloads.error.bg = 'red'
+
+## Foreground color for downloads with errors.
+## Type: QtColor
+# c.colors.downloads.error.fg = 'white'
+
+## Color gradient start for download backgrounds.
+## Type: QtColor
+# c.colors.downloads.start.bg = '#0000aa'
+
+## Color gradient start for download text.
+## Type: QtColor
+# c.colors.downloads.start.fg = 'white'
+
+## Color gradient stop for download backgrounds.
+## Type: QtColor
+# c.colors.downloads.stop.bg = '#00aa00'
+
+## Color gradient end for download text.
+## Type: QtColor
+# c.colors.downloads.stop.fg = 'white'
+
+## 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 = 'rgb'
+
+## Color gradient interpolation system for download text.
+## 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.fg = 'rgb'
+
+## Background color for hints. Note that you can use a `rgba(...)` value
+## for transparency.
+## Type: QssColor
+# c.colors.hints.bg = 'qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 247, 133, 0.8), stop:1 rgba(255, 197, 66, 0.8))'
+
+## Font color for hints.
+## Type: QssColor
+# c.colors.hints.fg = 'black'
+
+## Font color for the matched part of hints.
+## Type: QssColor
+# c.colors.hints.match.fg = 'green'
+
+## Background color of the keyhint widget.
+## Type: QssColor
+# c.colors.keyhint.bg = 'rgba(0, 0, 0, 80%)'
+
+## Text color for the keyhint widget.
+## Type: QssColor
+# c.colors.keyhint.fg = '#FFFFFF'
+
+## Highlight color for keys to complete the current keychain.
+## Type: QssColor
+# c.colors.keyhint.suffix.fg = '#FFFF00'
+
+## Background color of an error message.
+## Type: QssColor
+# c.colors.messages.error.bg = 'red'
+
+## Border color of an error message.
+## Type: QssColor
+# c.colors.messages.error.border = '#bb0000'
+
+## Foreground color of an error message.
+## Type: QssColor
+# c.colors.messages.error.fg = 'white'
+
+## Background color of an info message.
+## Type: QssColor
+# c.colors.messages.info.bg = 'black'
+
+## Border color of an info message.
+## Type: QssColor
+# c.colors.messages.info.border = '#333333'
+
+## Foreground color of an info message.
+## Type: QssColor
+# c.colors.messages.info.fg = 'white'
+
+## Background color of a warning message.
+## Type: QssColor
+# c.colors.messages.warning.bg = 'darkorange'
+
+## Border color of a warning message.
+## Type: QssColor
+# c.colors.messages.warning.border = '#d47300'
+
+## Foreground color of a warning message.
+## Type: QssColor
+# c.colors.messages.warning.fg = 'white'
+
+## Background color for prompts.
+## Type: QssColor
+# c.colors.prompts.bg = '#444444'
+
+## Border used around UI elements in prompts.
+## Type: String
+# c.colors.prompts.border = '1px solid gray'
+
+## Foreground color for prompts.
+## Type: QssColor
+# c.colors.prompts.fg = 'white'
+
+## Background color for the selected item in filename prompts.
+## Type: QssColor
+# c.colors.prompts.selected.bg = 'grey'
+
+## Background color of the statusbar in caret mode.
+## Type: QssColor
+# c.colors.statusbar.caret.bg = 'purple'
+
+## Foreground color of the statusbar in caret mode.
+## Type: QssColor
+# c.colors.statusbar.caret.fg = 'white'
+
+## Background color of the statusbar in caret mode with a selection.
+## Type: QssColor
+# c.colors.statusbar.caret.selection.bg = '#a12dff'
+
+## Foreground color of the statusbar in caret mode with a selection.
+## Type: QssColor
+# c.colors.statusbar.caret.selection.fg = 'white'
+
+## Background color of the statusbar in command mode.
+## Type: QssColor
+# c.colors.statusbar.command.bg = 'black'
+
+## Foreground color of the statusbar in command mode.
+## Type: QssColor
+# c.colors.statusbar.command.fg = 'white'
+
+## Background color of the statusbar in private browsing + command mode.
+## Type: QssColor
+# c.colors.statusbar.command.private.bg = 'grey'
+
+## Foreground color of the statusbar in private browsing + command mode.
+## Type: QssColor
+# c.colors.statusbar.command.private.fg = 'white'
+
+## Background color of the statusbar in insert mode.
+## Type: QssColor
+# c.colors.statusbar.insert.bg = 'darkgreen'
+
+## Foreground color of the statusbar in insert mode.
+## Type: QssColor
+# c.colors.statusbar.insert.fg = 'white'
+
+## Background color of the statusbar.
+## Type: QssColor
+# c.colors.statusbar.normal.bg = 'black'
+
+## Foreground color of the statusbar.
+## Type: QssColor
+# c.colors.statusbar.normal.fg = 'white'
+
+## Background color of the statusbar in passthrough mode.
+## Type: QssColor
+# c.colors.statusbar.passthrough.bg = 'darkblue'
+
+## Foreground color of the statusbar in passthrough mode.
+## Type: QssColor
+# c.colors.statusbar.passthrough.fg = 'white'
+
+## Background color of the statusbar in private browsing mode.
+## Type: QssColor
+# c.colors.statusbar.private.bg = '#666666'
+
+## Foreground color of the statusbar in private browsing mode.
+## Type: QssColor
+# c.colors.statusbar.private.fg = 'white'
+
+## Background color of the progress bar.
+## Type: QssColor
+# c.colors.statusbar.progress.bg = 'white'
+
+## Foreground color of the URL in the statusbar on error.
+## Type: QssColor
+# c.colors.statusbar.url.error.fg = 'orange'
+
+## Default foreground color of the URL in the statusbar.
+## Type: QssColor
+# c.colors.statusbar.url.fg = 'white'
+
+## Foreground color of the URL in the statusbar for hovered links.
+## Type: QssColor
+# c.colors.statusbar.url.hover.fg = 'aqua'
+
+## Foreground color of the URL in the statusbar on successful load
+## (http).
+## Type: QssColor
+# c.colors.statusbar.url.success.http.fg = 'white'
+
+## Foreground color of the URL in the statusbar on successful load
+## (https).
+## Type: QssColor
+# c.colors.statusbar.url.success.https.fg = 'lime'
+
+## Foreground color of the URL in the statusbar when there's a warning.
+## Type: QssColor
+# c.colors.statusbar.url.warn.fg = 'yellow'
+
+## Background color of the tab bar.
+## Type: QtColor
+# c.colors.tabs.bar.bg = '#555555'
+
+## Background color of unselected even tabs.
+## Type: QtColor
+# c.colors.tabs.even.bg = 'darkgrey'
+
+## Foreground color of unselected even tabs.
+## Type: QtColor
+# c.colors.tabs.even.fg = 'white'
+
+## Color for the tab indicator on errors.
+## Type: QtColor
+# c.colors.tabs.indicator.error = '#ff0000'
+
+## Color gradient start for the tab indicator.
+## Type: QtColor
+# c.colors.tabs.indicator.start = '#0000aa'
+
+## Color gradient end for the tab indicator.
+## Type: QtColor
+# c.colors.tabs.indicator.stop = '#00aa00'
+
+## 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 = 'rgb'
+
+## Background color of unselected odd tabs.
+## Type: QtColor
+# c.colors.tabs.odd.bg = 'grey'
+
+## Foreground color of unselected odd tabs.
+## Type: QtColor
+# c.colors.tabs.odd.fg = 'white'
+
+## Background color of selected even tabs.
+## Type: QtColor
+# c.colors.tabs.selected.even.bg = 'black'
+
+## Foreground color of selected even tabs.
+## Type: QtColor
+# c.colors.tabs.selected.even.fg = 'white'
+
+## Background color of selected odd tabs.
+## Type: QtColor
+# c.colors.tabs.selected.odd.bg = 'black'
+
+## Foreground color of selected odd tabs.
+## Type: QtColor
+# c.colors.tabs.selected.odd.fg = 'white'
+
+## Background color for webpages if unset (or empty to use the theme's
+## color).
+## Type: QtColor
+# c.colors.webpage.bg = 'white'
+
+## Number of commands to save in the command history. 0: no history / -1:
+## unlimited
+## Type: Int
+# c.completion.cmd_history_max_items = 100
+
+## Delay (in milliseconds) before updating completions after typing a
+## character.
+## Type: Int
+# c.completion.delay = 0
+
+## Height (in pixels or as percentage of the window) of the completion.
+## Type: PercOrInt
+# c.completion.height = '50%'
+
+## Minimum amount of characters needed to update completions.
+## Type: Int
+# c.completion.min_chars = 1
+
+## Move on to the next part when there's only one possible completion
+## left.
+## Type: Bool
+# c.completion.quick = True
+
+## Padding (in pixels) of the scrollbar handle in the completion window.
+## Type: Int
+# c.completion.scrollbar.padding = 2
+
+## Width (in pixels) of the scrollbar in the completion window.
+## Type: Int
+# c.completion.scrollbar.width = 12
+
+## When to show the autocompletion window.
+## Type: String
+## Valid values:
+## - always: Whenever a completion is available.
+## - auto: Whenever a completion is requested.
+## - never: Never.
+# c.completion.show = 'always'
+
+## Shrink the completion to be smaller than the configured size if there
+## are no scrollbars.
+## Type: Bool
+# c.completion.shrink = False
+
+## Format of timestamps (e.g. for the history completion).
+## Type: TimestampTemplate
+# c.completion.timestamp_format = '%Y-%m-%d'
+
+## Execute the best-matching command on a partial match.
+## Type: Bool
+# c.completion.use_best_match = False
+
+## A list of patterns which should not be shown in the history. This only
+## affects the completion. Matching URLs are still saved in the history
+## (and visible on the qute://history page), but hidden in the
+## completion. Changing this setting will cause the completion history to
+## be regenerated on the next start, which will take a short while.
+## Type: List of UrlPattern
+# c.completion.web_history.exclude = []
+
+## Number of URLs to show in the web history. 0: no history / -1:
+## unlimited
+## Type: Int
+# c.completion.web_history.max_items = -1
+
+## Require a confirmation before quitting the application.
+## Type: ConfirmQuit
+## Valid values:
+## - always: Always show a confirmation.
+## - multiple-tabs: Show a confirmation if multiple tabs are opened.
+## - downloads: Show a confirmation if downloads are running
+## - never: Never show a confirmation.
+# c.confirm_quit = ['never']
+
+## Automatically start playing `<video>` elements. Note: On Qt < 5.11,
+## this option needs a restart and does not support URL patterns.
+## Type: Bool
+# c.content.autoplay = True
+
+## Enable support for the HTML 5 web application cache feature. An
+## application cache acts like an HTTP cache in some sense. For documents
+## that use the application cache via JavaScript, the loader engine will
+## first ask the application cache for the contents, before hitting the
+## network.
+## Type: Bool
+# c.content.cache.appcache = True
+
+## Maximum number of pages to hold in the global memory page cache. The
+## page cache allows for a nicer user experience when navigating forth or
+## back to pages in the forward/back history, by pausing and resuming up
+## to _n_ pages. For more information about the feature, please refer to:
+## http://webkit.org/blog/427/webkit-page-cache-i-the-basics/
+## Type: Int
+# c.content.cache.maximum_pages = 0
+
+## Size (in bytes) of the HTTP network cache. Null to use the default
+## value. With QtWebEngine, the maximum supported value is 2147483647 (~2
+## GB).
+## Type: Int
+# c.content.cache.size = None
+
+## Allow websites to read canvas elements. Note this is needed for some
+## websites to work properly.
+## Type: Bool
+# c.content.canvas_reading = True
+
+## Which cookies to accept.
+## Type: String
+## Valid values:
+## - all: Accept all cookies.
+## - no-3rdparty: Accept cookies from the same origin only. This is known to break some sites, such as GMail.
+## - no-unknown-3rdparty: Accept cookies from the same origin only, unless a cookie is already set for the domain. On QtWebEngine, this is the same as no-3rdparty.
+## - never: Don't accept cookies at all.
+c.content.cookies.accept = 'no-unknown-3rdparty'
+
+## Store cookies. Note this option needs a restart with QtWebEngine on Qt
+## < 5.9.
+## Type: Bool
+# c.content.cookies.store = True
+
+## Default encoding to use for websites. The encoding must be a string
+## describing an encoding such as _utf-8_, _iso-8859-1_, etc.
+## Type: String
+# c.content.default_encoding = 'iso-8859-1'
+
+## Allow websites to share screen content. On Qt < 5.10, a dialog box is
+## always displayed, even if this is set to "true".
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.desktop_capture = 'ask'
+
+## Try to pre-fetch DNS entries to speed up browsing.
+## Type: Bool
+# c.content.dns_prefetch = True
+
+## Expand each subframe to its contents. This will flatten all the frames
+## to become one scrollable page.
+## Type: Bool
+# c.content.frame_flattening = False
+
+## Allow websites to request geolocations.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.geolocation = 'ask'
+
+## Value to send in the `Accept-Language` header. Note that the value
+## read from JavaScript is always the global value.
+## Type: String
+# c.content.headers.accept_language = 'en-US,en'
+
+## Custom headers for qutebrowser HTTP requests.
+## Type: Dict
+# c.content.headers.custom = {}
+
+## Value to send in the `DNT` header. When this is set to true,
+## qutebrowser asks websites to not track your identity. If set to null,
+## the DNT header is not sent at all.
+## Type: Bool
+# c.content.headers.do_not_track = True
+
+## When to send the Referer header. The Referer header tells websites
+## from which website you were coming from when visiting them. No restart
+## is needed with QtWebKit.
+## Type: String
+## Valid values:
+## - always: Always send the Referer.
+## - never: Never send the Referer. This is not recommended, as some sites may break.
+## - same-domain: Only send the Referer for the same domain. This will still protect your privacy, but shouldn't break any sites. With QtWebEngine, the referer will still be sent for other domains, but with stripped path information.
+# c.content.headers.referer = 'same-domain'
+
+## User agent to send. Unset to send the default. Note that the value
+## read from JavaScript is always the global value.
+## Type: String
+# c.content.headers.user_agent = None
+
+## Enable host blocking.
+## Type: Bool
+# c.content.host_blocking.enabled = True
+
+## List of URLs of lists which contain hosts to block. The file can be
+## in one of the following formats: - An `/etc/hosts`-like file - One
+## host per line - A zip-file of any of the above, with either only one
+## file, or a file named `hosts` (with any extension). It's also
+## possible to add a local file or directory via a `file://` URL. In case
+## of a directory, all files in the directory are read as adblock lists.
+## The file `~/.config/qutebrowser/blocked-hosts` is always read if it
+## exists.
+## Type: List of Url
+# c.content.host_blocking.lists = ['https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts']
+
+## A list of patterns that should always be loaded, despite being ad-
+## blocked. Local domains are always exempt from hostblocking.
+## Type: List of UrlPattern
+# c.content.host_blocking.whitelist = ['piwik.org']
+
+## Enable hyperlink auditing (`<a ping>`).
+## Type: Bool
+# c.content.hyperlink_auditing = False
+
+## Load images automatically in web pages.
+## Type: Bool
+# c.content.images = True
+
+## Show javascript alerts.
+## Type: Bool
+# c.content.javascript.alert = True
+
+## Allow JavaScript to read from or write to the clipboard. With
+## QtWebEngine, writing the clipboard as response to a user interaction
+## is always allowed.
+## Type: Bool
+# c.content.javascript.can_access_clipboard = False
+
+## Allow JavaScript to close tabs.
+## Type: Bool
+# c.content.javascript.can_close_tabs = False
+
+## Allow JavaScript to open new tabs without user interaction.
+## Type: Bool
+# c.content.javascript.can_open_tabs_automatically = False
+
+## Enable JavaScript.
+## Type: Bool
+# c.content.javascript.enabled = True
+
+## Log levels to use for JavaScript console logging messages. When a
+## JavaScript message with the level given in the dictionary key is
+## logged, the corresponding dictionary value selects the qutebrowser
+## logger to use. On QtWebKit, the "unknown" setting is always used.
+## Type: Dict
+# c.content.javascript.log = {'unknown': 'debug', 'info': 'debug', 'warning': 'debug', 'error': 'debug'}
+
+## Use the standard JavaScript modal dialog for `alert()` and
+## `confirm()`.
+## Type: Bool
+# c.content.javascript.modal_dialog = False
+
+## Show javascript prompts.
+## Type: Bool
+# c.content.javascript.prompt = True
+
+## Allow locally loaded documents to access other local URLs.
+## Type: Bool
+# c.content.local_content_can_access_file_urls = True
+
+## Allow locally loaded documents to access remote URLs.
+## Type: Bool
+# c.content.local_content_can_access_remote_urls = False
+
+## Enable support for HTML 5 local storage and Web SQL.
+## Type: Bool
+# c.content.local_storage = True
+
+## Allow websites to record audio/video.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.media_capture = 'ask'
+
+## Allow websites to lock your mouse pointer.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.mouse_lock = 'ask'
+
+## Automatically mute tabs. Note that if the `:tab-mute` command is used,
+## the mute status for the affected tab is now controlled manually, and
+## this setting doesn't have any effect.
+## Type: Bool
+# c.content.mute = False
+
+## Netrc-file for HTTP authentication. If unset, `~/.netrc` is used.
+## Type: File
+# c.content.netrc_file = None
+
+## Allow websites to show notifications.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.notifications = 'ask'
+
+## Allow pdf.js to view PDF files in the browser. Note that the files can
+## still be downloaded by clicking the download button in the pdf.js
+## viewer.
+## Type: Bool
+# c.content.pdfjs = False
+
+## Allow websites to request persistent storage quota via
+## `navigator.webkitPersistentStorage.requestQuota`.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.persistent_storage = 'ask'
+
+## Enable plugins in Web pages.
+## Type: Bool
+# c.content.plugins = False
+
+## Draw the background color and images also when the page is printed.
+## Type: Bool
+# c.content.print_element_backgrounds = True
+
+## Open new windows in private browsing mode which does not record
+## visited pages.
+## Type: Bool
+# c.content.private_browsing = False
+
+## Proxy to use. In addition to the listed values, you can use a
+## `socks://...` or `http://...` URL.
+## Type: Proxy
+## Valid values:
+## - system: Use the system wide proxy.
+## - none: Don't use any proxy
+# c.content.proxy = 'system'
+
+## Send DNS requests over the configured proxy.
+## Type: Bool
+# c.content.proxy_dns_requests = True
+
+## Allow websites to register protocol handlers via
+## `navigator.registerProtocolHandler`.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.register_protocol_handler = 'ask'
+
+## Validate SSL handshakes.
+## Type: BoolAsk
+## Valid values:
+## - true
+## - false
+## - ask
+# c.content.ssl_strict = 'ask'
+
+## List of user stylesheet filenames to use.
+## Type: List of File, or File
+# c.content.user_stylesheets = []
+
+## Enable WebGL.
+## Type: Bool
+# c.content.webgl = True
+
+## Which interfaces to expose via WebRTC. On Qt 5.10, this option doesn't
+## work because of a Qt bug.
+## Type: String
+## Valid values:
+## - all-interfaces: WebRTC has the right to enumerate all interfaces and bind them to discover public interfaces.
+## - default-public-and-private-interfaces: WebRTC should only use the default route used by http. This also exposes the associated default private address. Default route is the route chosen by the OS on a multi-homed endpoint.
+## - default-public-interface-only: WebRTC should only use the default route used by http. This doesn't expose any local addresses.
+## - disable-non-proxied-udp: WebRTC should only use TCP to contact peers or servers unless the proxy server supports UDP. This doesn't expose any local addresses either.
+# c.content.webrtc_ip_handling_policy = 'all-interfaces'
+
+## Limit fullscreen to the browser window (does not expand to fill the
+## screen).
+## Type: Bool
+# c.content.windowed_fullscreen = False
+
+## Monitor load requests for cross-site scripting attempts. Suspicious
+## scripts will be blocked and reported in the inspector's JavaScript
+## console.
+## Type: Bool
+# c.content.xss_auditing = True
+
+## Directory to save downloads to. If unset, a sensible OS-specific
+## default is used.
+## Type: Directory
+# c.downloads.location.directory = None
+
+## Prompt the user for the download location. If set to false,
+## `downloads.location.directory` will be used.
+## Type: Bool
+# c.downloads.location.prompt = True
+
+## Remember the last used download directory.
+## Type: Bool
+# c.downloads.location.remember = True
+
+## What to display in the download filename input.
+## Type: String
+## Valid values:
+## - path: Show only the download path.
+## - filename: Show only download filename.
+## - both: Show download path and filename.
+# c.downloads.location.suggestion = 'path'
+
+## Default program used to open downloads. If null, the default internal
+## handler is used. Any `{}` in the string will be expanded to the
+## filename, else the filename will be appended.
+## Type: String
+# c.downloads.open_dispatcher = None
+
+## Where to show the downloaded files.
+## Type: VerticalPosition
+## Valid values:
+## - top
+## - bottom
+# c.downloads.position = 'top'
+
+## Duration (in milliseconds) to wait before removing finished downloads.
+## If set to -1, downloads are never removed.
+## Type: Int
+# c.downloads.remove_finished = -1
+
+## Editor (and arguments) to use for the `open-editor` command. The
+## following placeholders are defined: * `{file}`: Filename of the file
+## to be edited. * `{line}`: Line in which the caret is found in the
+## text. * `{column}`: Column in which the caret is found in the text. *
+## `{line0}`: Same as `{line}`, but starting from index 0. * `{column0}`:
+## Same as `{column}`, but starting from index 0.
+## Type: ShellCommand
+# c.editor.command = ['gvim', '-f', '{file}', '-c', 'normal {line}G{column0}l']
+
+## Encoding to use for the editor.
+## Type: Encoding
+# c.editor.encoding = 'utf-8'
+
+## Font used in the completion categories.
+## Type: Font
+# c.fonts.completion.category = 'bold 10pt monospace'
+
+## Font used in the completion widget.
+## Type: Font
+# c.fonts.completion.entry = '10pt monospace'
+
+## Font used for the debugging console.
+## Type: QtFont
+# c.fonts.debug_console = '10pt monospace'
+
+## Font used for the downloadbar.
+## Type: Font
+# c.fonts.downloads = '10pt monospace'
+
+## Font used for the hints.
+## Type: Font
+# c.fonts.hints = 'bold 10pt monospace'
+
+## Font used in the keyhint widget.
+## Type: Font
+# c.fonts.keyhint = '10pt monospace'
+
+## Font used for error messages.
+## Type: Font
+# c.fonts.messages.error = '10pt monospace'
+
+## Font used for info messages.
+## Type: Font
+# c.fonts.messages.info = '10pt monospace'
+
+## Font used for warning messages.
+## Type: Font
+# c.fonts.messages.warning = '10pt monospace'
+
+## Default monospace fonts. Whenever "monospace" is used in a font
+## setting, it's replaced with the fonts listed here.
+## Type: Font
+# c.fonts.monospace = '"xos4 Terminus", Terminus, Monospace, "DejaVu Sans Mono", Monaco, "Bitstream Vera Sans Mono", "Andale Mono", "Courier New", Courier, "Liberation Mono", monospace, Fixed, Consolas, Terminal'
+
+## Font used for prompts.
+## Type: Font
+# c.fonts.prompts = '10pt sans-serif'
+
+## Font used in the statusbar.
+## Type: Font
+# c.fonts.statusbar = '10pt monospace'
+
+## Font used in the tab bar.
+## Type: QtFont
+# c.fonts.tabs = '10pt monospace'
+
+## Font family for cursive fonts.
+## Type: FontFamily
+# c.fonts.web.family.cursive = ''
+
+## Font family for fantasy fonts.
+## Type: FontFamily
+# c.fonts.web.family.fantasy = ''
+
+## Font family for fixed fonts.
+## Type: FontFamily
+# c.fonts.web.family.fixed = ''
+
+## Font family for sans-serif fonts.
+## Type: FontFamily
+# c.fonts.web.family.sans_serif = ''
+
+## Font family for serif fonts.
+## Type: FontFamily
+# c.fonts.web.family.serif = ''
+
+## Font family for standard fonts.
+## Type: FontFamily
+# c.fonts.web.family.standard = ''
+
+## Default font size (in pixels) for regular text.
+## Type: Int
+# c.fonts.web.size.default = 16
+
+## Default font size (in pixels) for fixed-pitch text.
+## Type: Int
+# c.fonts.web.size.default_fixed = 13
+
+## Hard minimum font size (in pixels).
+## Type: Int
+# c.fonts.web.size.minimum = 0
+
+## Minimum logical font size (in pixels) that is applied when zooming
+## out.
+## Type: Int
+# c.fonts.web.size.minimum_logical = 6
+
+## When a hint can be automatically followed without pressing Enter.
+## Type: String
+## Valid values:
+## - always: Auto-follow whenever there is only a single hint on a page.
+## - unique-match: Auto-follow whenever there is a unique non-empty match in either the hint string (word mode) or filter (number mode).
+## - full-match: Follow the hint when the user typed the whole hint (letter, word or number mode) or the element's text (only in number mode).
+## - never: The user will always need to press Enter to follow a hint.
+# c.hints.auto_follow = 'unique-match'
+
+## Duration (in milliseconds) to ignore normal-mode key bindings after a
+## successful auto-follow.
+## Type: Int
+# c.hints.auto_follow_timeout = 0
+
+## CSS border value for hints.
+## Type: String
+# c.hints.border = '1px solid #E3BE23'
+
+## Characters used for hint strings.
+## Type: UniqueCharString
+# c.hints.chars = 'asdfghjkl'
+
+## Dictionary file to be used by the word hints.
+## Type: File
+# c.hints.dictionary = '/usr/share/dict/words'
+
+## Which implementation to use to find elements to hint.
+## Type: String
+## Valid values:
+## - javascript: Better but slower
+## - python: Slightly worse but faster
+# c.hints.find_implementation = 'python'
+
+## Hide unmatched hints in rapid mode.
+## Type: Bool
+# c.hints.hide_unmatched_rapid_hints = True
+
+## Minimum number of characters used for hint strings.
+## Type: Int
+# c.hints.min_chars = 1
+
+## Mode to use for hints.
+## Type: String
+## Valid values:
+## - number: Use numeric hints. (In this mode you can also type letters from the hinted element to filter and reduce the number of elements that are hinted.)
+## - letter: Use the characters in the `hints.chars` setting.
+## - word: Use hints words based on the html elements and the extra words.
+# c.hints.mode = 'letter'
+
+## Comma-separated list of regular expressions to use for 'next' links.
+## Type: List of Regex
+# c.hints.next_regexes = ['\\bnext\\b', '\\bmore\\b', '\\bnewer\\b', '\\b[>→≫]\\b', '\\b(>>|»)\\b', '\\bcontinue\\b']
+
+## Comma-separated list of regular expressions to use for 'prev' links.
+## Type: List of Regex
+# c.hints.prev_regexes = ['\\bprev(ious)?\\b', '\\bback\\b', '\\bolder\\b', '\\b[<â†â‰ª]\\b', '\\b(<<|«)\\b']
+
+## Scatter hint key chains (like Vimium) or not (like dwb). Ignored for
+## number hints.
+## Type: Bool
+# c.hints.scatter = True
+
+## Make characters in hint strings uppercase.
+## Type: Bool
+# c.hints.uppercase = False
+
+## Maximum time (in minutes) between two history items for them to be
+## considered being from the same browsing session. Items with less time
+## between them are grouped when being displayed in `:history`. Use -1 to
+## disable separation.
+## Type: Int
+# c.history_gap_interval = 30
+
+## Allow Escape to quit the crash reporter.
+## Type: Bool
+# c.input.escape_quits_reporter = True
+
+## Which unbound keys to forward to the webview in normal mode.
+## Type: String
+## Valid values:
+## - all: Forward all unbound keys.
+## - auto: Forward unbound non-alphanumeric keys.
+## - none: Don't forward any keys.
+# c.input.forward_unbound_keys = 'auto'
+
+## Enter insert mode if an editable element is clicked.
+## Type: Bool
+# c.input.insert_mode.auto_enter = True
+
+## Leave insert mode if a non-editable element is clicked.
+## Type: Bool
+# c.input.insert_mode.auto_leave = True
+
+## Automatically enter insert mode if an editable element is focused
+## after loading the page.
+## Type: Bool
+# c.input.insert_mode.auto_load = False
+
+## Switch to insert mode when clicking flash and other plugins.
+## Type: Bool
+# c.input.insert_mode.plugins = False
+
+## Include hyperlinks in the keyboard focus chain when tabbing.
+## Type: Bool
+# c.input.links_included_in_focus_chain = True
+
+## Timeout (in milliseconds) for partially typed key bindings. If the
+## current input forms only partial matches, the keystring will be
+## cleared after this time.
+## Type: Int
+# c.input.partial_timeout = 5000
+
+## Enable Opera-like mouse rocker gestures. This disables the context
+## menu.
+## Type: Bool
+# c.input.rocker_gestures = False
+
+## Enable spatial navigation. Spatial navigation consists in the ability
+## to navigate between focusable elements in a Web page, such as
+## hyperlinks and form controls, by using Left, Right, Up and Down arrow
+## keys. For example, if the user presses the Right key, heuristics
+## determine whether there is an element he might be trying to reach
+## towards the right and which element he probably wants.
+## Type: Bool
+# c.input.spatial_navigation = False
+
+## Keychains that shouldn't be shown in the keyhint dialog. Globs are
+## supported, so `;*` will blacklist all keychains starting with `;`. Use
+## `*` to disable keyhints.
+## Type: List of String
+# c.keyhint.blacklist = []
+
+## Time (in milliseconds) from pressing a key to seeing the keyhint
+## dialog.
+## Type: Int
+# c.keyhint.delay = 500
+
+## Rounding radius (in pixels) for the edges of the keyhint dialog.
+## Type: Int
+# c.keyhint.radius = 6
+
+## Duration (in milliseconds) to show messages in the statusbar for. Set
+## to 0 to never clear messages.
+## Type: Int
+# c.messages.timeout = 2000
+
+## How to open links in an existing instance if a new one is launched.
+## This happens when e.g. opening a link from a terminal. See
+## `new_instance_open_target_window` to customize in which window the
+## link is opened in.
+## Type: String
+## Valid values:
+## - tab: Open a new tab in the existing window and activate the window.
+## - tab-bg: Open a new background tab in the existing window and activate the window.
+## - tab-silent: Open a new tab in the existing window without activating the window.
+## - tab-bg-silent: Open a new background tab in the existing window without activating the window.
+## - window: Open in a new window.
+# c.new_instance_open_target = 'tab'
+
+## Which window to choose when opening links as new tabs. When
+## `new_instance_open_target` is not set to `window`, this is ignored.
+## Type: String
+## Valid values:
+## - first-opened: Open new tabs in the first (oldest) opened window.
+## - last-opened: Open new tabs in the last (newest) opened window.
+## - last-focused: Open new tabs in the most recently focused window.
+## - last-visible: Open new tabs in the most recently visible window.
+# c.new_instance_open_target_window = 'last-focused'
+
+## Show a filebrowser in upload/download prompts.
+## Type: Bool
+# c.prompt.filebrowser = True
+
+## Rounding radius (in pixels) for the edges of prompts.
+## Type: Int
+# c.prompt.radius = 8
+
+## Additional arguments to pass to Qt, without leading `--`. With
+## QtWebEngine, some Chromium arguments (see
+## https://peter.sh/experiments/chromium-command-line-switches/ for a
+## list) will work.
+## Type: List of String
+# c.qt.args = []
+
+## Force a Qt platform to use. This sets the `QT_QPA_PLATFORM`
+## environment variable and is useful to force using the XCB plugin when
+## running QtWebEngine on Wayland.
+## Type: String
+# c.qt.force_platform = None
+
+## Force software rendering for QtWebEngine. This is needed for
+## QtWebEngine to work with Nouveau drivers and can be useful in other
+## scenarios related to graphic issues.
+## Type: String
+## Valid values:
+## - software-opengl: Tell LibGL to use a software implementation of GL (`LIBGL_ALWAYS_SOFTWARE` / `QT_XCB_FORCE_SOFTWARE_OPENGL`)
+## - qt-quick: Tell Qt Quick to use a software renderer instead of OpenGL. (`QT_QUICK_BACKEND=software`)
+## - chromium: Tell Chromium to disable GPU support and use Skia software rendering instead. (`--disable-gpu`)
+## - none: Don't force software rendering.
+# c.qt.force_software_rendering = 'none'
+
+## Turn on Qt HighDPI scaling. This is equivalent to setting
+## QT_AUTO_SCREEN_SCALE_FACTOR=1 in the environment. It's off by default
+## as it can cause issues with some bitmap fonts. As an alternative to
+## this, it's possible to set font sizes and the `zoom.default` setting.
+## Type: Bool
+# c.qt.highdpi = False
+
+## When to use Chromium's low-end device mode. This improves the RAM
+## usage of renderer processes, at the expense of performance.
+## Type: String
+## Valid values:
+## - always: Always use low-end device mode.
+## - auto: Decide automatically (uses low-end mode with < 1 GB available RAM).
+## - never: Never use low-end device mode.
+# c.qt.low_end_device_mode = 'auto'
+
+## Which Chromium process model to use. Alternative process models use
+## less resources, but decrease security and robustness. See the
+## following pages for more details: -
+## https://www.chromium.org/developers/design-documents/process-models
+## - https://doc.qt.io/qt-5/qtwebengine-features.html#process-models
+## Type: String
+## Valid values:
+## - process-per-site-instance: Pages from separate sites are put into separate processes and separate visits to the same site are also isolated.
+## - process-per-site: Pages from separate sites are put into separate processes. Unlike Process per Site Instance, all visits to the same site will share an OS process. The benefit of this model is reduced memory consumption, because more web pages will share processes. The drawbacks include reduced security, robustness, and responsiveness.
+## - single-process: Run all tabs in a single process. This should be used for debugging purposes only, and it disables `:open --private`.
+# c.qt.process_model = 'process-per-site-instance'
+
+## When to show the scrollbar.
+## Type: String
+## Valid values:
+## - always: Always show the scrollbar.
+## - never: Never show the scrollbar.
+## - when-searching: Show the scrollbar when searching for text in the webpage. With the QtWebKit backend, this is equal to `never`.
+# c.scrolling.bar = 'when-searching'
+
+## Enable smooth scrolling for web pages. Note smooth scrolling does not
+## work with the `:scroll-px` command.
+## Type: Bool
+# c.scrolling.smooth = False
+
+## When to find text on a page case-insensitively.
+## Type: String
+## Valid values:
+## - always: Search case-insensitively.
+## - never: Search case-sensitively.
+## - smart: Search case-sensitively if there are capital characters.
+# c.search.ignore_case = 'smart'
+
+## Find text on a page incrementally, renewing the search for each typed
+## character.
+## Type: Bool
+# c.search.incremental = True
+
+## Name of the session to save by default. If this is set to null, the
+## session which was last loaded is saved.
+## Type: SessionName
+# c.session.default_name = None
+
+## Load a restored tab as soon as it takes focus.
+## Type: Bool
+# c.session.lazy_restore = False
+
+## Languages to use for spell checking. You can check for available
+## languages and install dictionaries using scripts/dictcli.py. Run the
+## script with -h/--help for instructions.
+## Type: List of String
+## Valid values:
+## - af-ZA: Afrikaans (South Africa)
+## - bg-BG: Bulgarian (Bulgaria)
+## - ca-ES: Catalan (Spain)
+## - cs-CZ: Czech (Czech Republic)
+## - da-DK: Danish (Denmark)
+## - de-DE: German (Germany)
+## - el-GR: Greek (Greece)
+## - en-AU: English (Australia)
+## - en-CA: English (Canada)
+## - en-GB: English (United Kingdom)
+## - en-US: English (United States)
+## - es-ES: Spanish (Spain)
+## - et-EE: Estonian (Estonia)
+## - fa-IR: Farsi (Iran)
+## - fo-FO: Faroese (Faroe Islands)
+## - fr-FR: French (France)
+## - he-IL: Hebrew (Israel)
+## - hi-IN: Hindi (India)
+## - hr-HR: Croatian (Croatia)
+## - hu-HU: Hungarian (Hungary)
+## - id-ID: Indonesian (Indonesia)
+## - it-IT: Italian (Italy)
+## - ko: Korean
+## - lt-LT: Lithuanian (Lithuania)
+## - lv-LV: Latvian (Latvia)
+## - nb-NO: Norwegian (Norway)
+## - nl-NL: Dutch (Netherlands)
+## - pl-PL: Polish (Poland)
+## - pt-BR: Portuguese (Brazil)
+## - pt-PT: Portuguese (Portugal)
+## - ro-RO: Romanian (Romania)
+## - ru-RU: Russian (Russia)
+## - sh: Serbo-Croatian
+## - sk-SK: Slovak (Slovakia)
+## - sl-SI: Slovenian (Slovenia)
+## - sq: Albanian
+## - sr: Serbian
+## - sv-SE: Swedish (Sweden)
+## - ta-IN: Tamil (India)
+## - tg-TG: Tajik (Tajikistan)
+## - tr-TR: Turkish (Turkey)
+## - uk-UA: Ukrainian (Ukraine)
+## - vi-VN: Vietnamese (Viet Nam)
+# c.spellcheck.languages = []
+
+## Hide the statusbar unless a message is shown.
+## Type: Bool
+# c.statusbar.hide = False
+
+## Padding (in pixels) for the statusbar.
+## Type: Padding
+# c.statusbar.padding = {'top': 1, 'bottom': 1, 'left': 0, 'right': 0}
+
+## Position of the status bar.
+## Type: VerticalPosition
+## Valid values:
+## - top
+## - bottom
+# c.statusbar.position = 'bottom'
+
+## List of widgets displayed in the statusbar.
+## Type: List of String
+## Valid values:
+## - url: Current page URL.
+## - scroll: Percentage of the current page position like `10%`.
+## - scroll_raw: Raw percentage of the current page position like `10`.
+## - history: Display an arrow when possible to go back/forward in history.
+## - tabs: Current active tab, e.g. `2`.
+## - keypress: Display pressed keys when composing a vi command.
+## - progress: Progress bar for the current page loading.
+# c.statusbar.widgets = ['keypress', 'url', 'scroll', 'history', 'tabs', 'progress']
+
+## Open new tabs (middleclick/ctrl+click) in the background.
+## Type: Bool
+c.tabs.background = True
+
+## Mouse button with which to close tabs.
+## Type: String
+## Valid values:
+## - right: Close tabs on right-click.
+## - middle: Close tabs on middle-click.
+## - none: Don't close tabs using the mouse.
+c.tabs.close_mouse_button = 'middle'
+
+## How to behave when the close mouse button is pressed on the tab bar.
+## Type: String
+## Valid values:
+## - new-tab: Open a new tab.
+## - close-current: Close the current tab.
+## - close-last: Close the last tab.
+## - ignore: Don't do anything.
+# c.tabs.close_mouse_button_on_bar = 'new-tab'
+
+## Scaling factor for favicons in the tab bar. The tab size is unchanged,
+## so big favicons also require extra `tabs.padding`.
+## Type: Float
+# c.tabs.favicons.scale = 1.0
+
+## When to show favicons in the tab bar.
+## Type: String
+## Valid values:
+## - always: Always show favicons.
+## - never: Always hide favicons.
+## - pinned: Show favicons only on pinned tabs.
+# c.tabs.favicons.show = 'always'
+
+## Padding (in pixels) for tab indicators.
+## Type: Padding
+# c.tabs.indicator.padding = {'top': 2, 'bottom': 2, 'left': 0, 'right': 4}
+
+## Width (in pixels) of the progress indicator (0 to disable).
+## Type: Int
+# c.tabs.indicator.width = 3
+
+## How to behave when the last tab is closed.
+## Type: String
+## Valid values:
+## - ignore: Don't do anything.
+## - blank: Load a blank page.
+## - startpage: Load the start page.
+## - default-page: Load the default page.
+## - close: Close the window.
+# c.tabs.last_close = 'ignore'
+
+## Maximum width (in pixels) of tabs (-1 for no maximum). This setting
+## only applies when tabs are horizontal. This setting does not apply to
+## pinned tabs, unless `tabs.pinned.shrink` is False. This setting may
+## not apply properly if max_width is smaller than the minimum size of
+## tab contents, or smaller than tabs.min_width.
+## Type: Int
+# c.tabs.max_width = -1
+
+## Minimum width (in pixels) of tabs (-1 for the default minimum size
+## behavior). This setting only applies when tabs are horizontal. This
+## setting does not apply to pinned tabs, unless `tabs.pinned.shrink` is
+## False.
+## Type: Int
+# c.tabs.min_width = -1
+
+## When switching tabs, what input mode is applied.
+## Type: String
+## Valid values:
+## - persist: Retain the current mode.
+## - restore: Restore previously saved mode.
+## - normal: Always revert to normal mode.
+# c.tabs.mode_on_change = 'normal'
+
+## Switch between tabs using the mouse wheel.
+## Type: Bool
+# c.tabs.mousewheel_switching = True
+
+## Position of new tabs opened from another tab.
+## Type: NewTabPosition
+## Valid values:
+## - prev: Before the current tab.
+## - next: After the current tab.
+## - first: At the beginning.
+## - last: At the end.
+# c.tabs.new_position.related = 'next'
+
+## Position of new tabs which aren't opened from another tab.
+## Type: NewTabPosition
+## Valid values:
+## - prev: Before the current tab.
+## - next: After the current tab.
+## - first: At the beginning.
+## - last: At the end.
+# c.tabs.new_position.unrelated = 'last'
+
+## Padding (in pixels) around text for tabs.
+## Type: Padding
+# c.tabs.padding = {'top': 0, 'bottom': 0, 'left': 5, 'right': 5}
+
+## Shrink pinned tabs down to their contents.
+## Type: Bool
+# c.tabs.pinned.shrink = True
+
+## Position of the tab bar.
+## Type: Position
+## Valid values:
+## - top
+## - bottom
+## - left
+## - right
+# c.tabs.position = 'top'
+
+## Which tab to select when the focused tab is removed.
+## Type: SelectOnRemove
+## Valid values:
+## - prev: Select the tab which came before the closed one (left in horizontal, above in vertical).
+## - next: Select the tab which came after the closed one (right in horizontal, below in vertical).
+## - last-used: Select the previously selected tab.
+# c.tabs.select_on_remove = 'next'
+
+## When to show the tab bar.
+## Type: String
+## Valid values:
+## - always: Always show the tab bar.
+## - never: Always hide the tab bar.
+## - multiple: Hide the tab bar if only one tab is open.
+## - switching: Show the tab bar when switching tabs.
+# c.tabs.show = 'always'
+
+## Duration (in milliseconds) to show the tab bar before hiding it when
+## tabs.show is set to 'switching'.
+## Type: Int
+# c.tabs.show_switching_delay = 800
+
+## Open a new window for every tab.
+## Type: Bool
+# c.tabs.tabs_are_windows = False
+
+## Alignment of the text inside of tabs.
+## Type: TextAlignment
+## Valid values:
+## - left
+## - right
+## - center
+# c.tabs.title.alignment = 'left'
+
+## Format to use for the tab title. The following placeholders are
+## defined: * `{perc}`: Percentage as a string like `[10%]`. *
+## `{perc_raw}`: Raw percentage, e.g. `10`. * `{title}`: Title of the
+## current web page. * `{title_sep}`: The string ` - ` if a title is set,
+## empty otherwise. * `{index}`: Index of this tab. * `{id}`: Internal
+## tab ID of this tab. * `{scroll_pos}`: Page scroll position. *
+## `{host}`: Host of the current web page. * `{backend}`: Either
+## ''webkit'' or ''webengine'' * `{private}`: Indicates when private mode
+## is enabled. * `{current_url}`: URL of the current web page. *
+## `{protocol}`: Protocol (http/https/...) of the current web page. *
+## `{audio}`: Indicator for audio/mute status.
+## Type: FormatString
+# c.tabs.title.format = '{audio}{index}: {title}'
+
+## Format to use for the tab title for pinned tabs. The same placeholders
+## like for `tabs.title.format` are defined.
+## Type: FormatString
+# c.tabs.title.format_pinned = '{index}'
+
+## Width (in pixels or as percentage of the window) of the tab bar if
+## it's vertical.
+## Type: PercOrInt
+# c.tabs.width = '20%'
+
+## Wrap when changing tabs.
+## Type: Bool
+# c.tabs.wrap = True
+
+## What search to start when something else than a URL is entered.
+## Type: String
+## Valid values:
+## - naive: Use simple/naive check.
+## - dns: Use DNS requests (might be slow!).
+## - never: Never search automatically.
+# c.url.auto_search = 'naive'
+
+## Page to open if :open -t/-b/-w is used without URL. Use `about:blank`
+## for a blank page.
+## Type: FuzzyUrl
+# c.url.default_page = 'https://start.duckduckgo.com/'
+
+## URL segments where `:navigate increment/decrement` will search for a
+## number.
+## Type: FlagList
+## Valid values:
+## - host
+## - port
+## - path
+## - query
+## - anchor
+# c.url.incdec_segments = ['path', 'query']
+
+## Open base URL of the searchengine if a searchengine shortcut is
+## invoked without parameters.
+## Type: Bool
+# c.url.open_base_url = False
+
+## Search engines which can be used via the address bar. Maps a search
+## engine name (such as `DEFAULT`, or `ddg`) to a URL with a `{}`
+## placeholder. The placeholder will be replaced by the search term, use
+## `{{` and `}}` for literal `{`/`}` signs. The search engine named
+## `DEFAULT` is used when `url.auto_search` is turned on and something
+## else than a URL was entered to be opened. Other search engines can be
+## used by prepending the search engine name to the search term, e.g.
+## `:open google qutebrowser`.
+## Type: Dict
+c.url.searchengines = {'DEFAULT': 'https://www.google.co.uk/#q={}'}
+c.url.searchengines.update({'ddg': 'https://duckduckgo.com/?q={}'})
+c.url.searchengines.update({'g': 'https://www.google.co.uk/#q={}'})
+c.url.searchengines.update({'deb': 'https://packages.debian.org/search?keywords={}'})
+c.url.searchengines.update({'t': 'https://twitter.com/search?q={}'})
+c.url.searchengines.update({'yt': 'https://www.youtube.com/results?search_query={}'})
+c.url.searchengines.update({'r': 'https://www.reddit.com/search?q={}'})
+
+
+## Page(s) to open at the start.
+## Type: List of FuzzyUrl, or FuzzyUrl
+# c.url.start_pages = ['https://start.duckduckgo.com']
+
+## URL parameters to strip with `:yank url`.
+## Type: List of String
+# c.url.yank_ignored_parameters = ['ref', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']
+
+## Hide the window decoration. This setting requires a restart on
+## Wayland.
+## Type: Bool
+# c.window.hide_decoration = False
+
+## Format to use for the window title. The same placeholders like for
+## `tabs.title.format` are defined.
+## Type: FormatString
+# c.window.title_format = '{perc}{title}{title_sep}qutebrowser'
+
+## Default zoom level.
+## Type: Perc
+c.zoom.default = '115%'
+
+## Available zoom levels.
+## Type: List of Perc
+# c.zoom.levels = ['25%', '33%', '50%', '67%', '75%', '90%', '100%', '110%', '125%', '150%', '175%', '200%', '250%', '300%', '400%', '500%']
+
+## Number of zoom increments to divide the mouse wheel movements to.
+## Type: Int
+# c.zoom.mouse_divider = 512
+
+## Apply the zoom factor on a frame only to the text or to all content.
+## Type: Bool
+# c.zoom.text_only = False
+
+## Bindings for normal mode
+config.bind(';M', 'hint links spawn mpv {hint-url}')
+# config.bind("'", 'enter-mode jump_mark')
+# config.bind('+', 'zoom-in')
+# config.bind('-', 'zoom-out')
+# config.bind('.', 'repeat-command')
+# config.bind('/', 'set-cmd-text /')
+# config.bind(':', 'set-cmd-text :')
+# config.bind(';I', 'hint images tab')
+# config.bind(';O', 'hint links fill :open -t -r {hint-url}')
+# config.bind(';R', 'hint --rapid links window')
+# config.bind(';Y', 'hint links yank-primary')
+# config.bind(';b', 'hint all tab-bg')
+# config.bind(';d', 'hint links download')
+# config.bind(';f', 'hint all tab-fg')
+# config.bind(';h', 'hint all hover')
+# config.bind(';i', 'hint images')
+# config.bind(';o', 'hint links fill :open {hint-url}')
+# config.bind(';r', 'hint --rapid links tab-bg')
+# config.bind(';t', 'hint inputs')
+# config.bind(';y', 'hint links yank')
+# config.bind('<Alt-1>', 'tab-focus 1')
+# config.bind('<Alt-2>', 'tab-focus 2')
+# config.bind('<Alt-3>', 'tab-focus 3')
+# config.bind('<Alt-4>', 'tab-focus 4')
+# config.bind('<Alt-5>', 'tab-focus 5')
+# config.bind('<Alt-6>', 'tab-focus 6')
+# config.bind('<Alt-7>', 'tab-focus 7')
+# config.bind('<Alt-8>', 'tab-focus 8')
+# config.bind('<Alt-9>', 'tab-focus -1')
+# config.bind('<Alt-m>', 'tab-mute')
+# config.bind('<Ctrl-A>', 'navigate increment')
+# config.bind('<Ctrl-Alt-p>', 'print')
+# config.bind('<Ctrl-B>', 'scroll-page 0 -1')
+# config.bind('<Ctrl-D>', 'scroll-page 0 0.5')
+# config.bind('<Ctrl-F5>', 'reload -f')
+# config.bind('<Ctrl-F>', 'scroll-page 0 1')
+# config.bind('<Ctrl-N>', 'open -w')
+# config.bind('<Ctrl-PgDown>', 'tab-next')
+# config.bind('<Ctrl-PgUp>', 'tab-prev')
+# config.bind('<Ctrl-Q>', 'quit')
+# config.bind('<Ctrl-Return>', 'follow-selected -t')
+# config.bind('<Ctrl-Shift-N>', 'open -p')
+# config.bind('<Ctrl-Shift-T>', 'undo')
+# config.bind('<Ctrl-Shift-Tab>', 'nop')
+# config.bind('<Ctrl-Shift-W>', 'close')
+# config.bind('<Ctrl-T>', 'open -t')
+# config.bind('<Ctrl-Tab>', 'tab-focus last')
+# config.bind('<Ctrl-U>', 'scroll-page 0 -0.5')
+# config.bind('<Ctrl-V>', 'enter-mode passthrough')
+# config.bind('<Ctrl-W>', 'tab-close')
+# config.bind('<Ctrl-X>', 'navigate decrement')
+# config.bind('<Ctrl-^>', 'tab-focus last')
+# config.bind('<Ctrl-h>', 'home')
+# config.bind('<Ctrl-p>', 'tab-pin')
+# config.bind('<Ctrl-s>', 'stop')
+# config.bind('<Escape>', 'clear-keychain ;; search ;; fullscreen --leave')
+# config.bind('<F11>', 'fullscreen')
+# config.bind('<F5>', 'reload')
+# config.bind('<Return>', 'follow-selected')
+# config.bind('<back>', 'back')
+# config.bind('<forward>', 'forward')
+# config.bind('=', 'zoom')
+# config.bind('?', 'set-cmd-text ?')
+# config.bind('@', 'run-macro')
+# config.bind('B', 'set-cmd-text -s :quickmark-load -t')
+config.bind('D', 'nop')
+# config.bind('F', 'hint all tab')
+# config.bind('G', 'scroll-to-perc')
+# config.bind('H', 'back')
+# config.bind('J', 'tab-next')
+# config.bind('K', 'tab-prev')
+# config.bind('L', 'forward')
+# config.bind('M', 'bookmark-add')
+# config.bind('N', 'search-prev')
+# config.bind('O', 'set-cmd-text -s :open -t')
+# config.bind('PP', 'open -t -- {primary}')
+# config.bind('Pp', 'open -t -- {clipboard}')
+# config.bind('R', 'reload -f')
+# config.bind('Sb', 'open qute://bookmarks#bookmarks')
+# config.bind('Sh', 'open qute://history')
+# config.bind('Sq', 'open qute://bookmarks')
+# config.bind('Ss', 'open qute://settings')
+# config.bind('T', 'tab-focus')
+# config.bind('ZQ', 'quit')
+# config.bind('ZZ', 'quit --save')
+# config.bind('[[', 'navigate prev')
+# config.bind(']]', 'navigate next')
+# config.bind('`', 'enter-mode set_mark')
+# config.bind('ad', 'download-cancel')
+# config.bind('b', 'set-cmd-text -s :quickmark-load')
+# config.bind('cd', 'download-clear')
+# config.bind('co', 'tab-only')
+#config.bind('d', 'tab-close')
+config.bind('d', 'nop')
+# config.bind('f', 'hint')
+# config.bind('g$', 'tab-focus -1')
+# config.bind('g0', 'tab-focus 1')
+# config.bind('gB', 'set-cmd-text -s :bookmark-load -t')
+# config.bind('gC', 'tab-clone')
+# config.bind('gD', 'tab-give')
+# config.bind('gO', 'set-cmd-text :open -t -r {url:pretty}')
+# config.bind('gU', 'navigate up -t')
+# config.bind('g^', 'tab-focus 1')
+# config.bind('ga', 'open -t')
+# config.bind('gb', 'set-cmd-text -s :bookmark-load')
+# config.bind('gd', 'download')
+# config.bind('gf', 'view-source')
+# config.bind('gg', 'scroll-to-perc 0')
+# config.bind('gi', 'hint inputs --first')
+# config.bind('gl', 'tab-move -')
+# config.bind('gm', 'tab-move')
+# config.bind('go', 'set-cmd-text :open {url:pretty}')
+# config.bind('gr', 'tab-move +')
+# config.bind('gt', 'set-cmd-text -s :buffer')
+# config.bind('gu', 'navigate up')
+# config.bind('h', 'scroll left')
+# config.bind('i', 'enter-mode insert')
+# config.bind('j', 'scroll down')
+# config.bind('k', 'scroll up')
+# config.bind('l', 'scroll right')
+config.bind('m', 'quickmark-save')
+# config.bind('n', 'search-next')
+# config.bind('o', 'set-cmd-text -s :open')
+# config.bind('pP', 'open -- {primary}')
+# config.bind('pp', 'open -- {clipboard}')
+# config.bind('q', 'record-macro')
+# config.bind('r', 'reload')
+# config.bind('sf', 'save')
+# config.bind('sk', 'set-cmd-text -s :bind')
+# config.bind('sl', 'set-cmd-text -s :set -t')
+# config.bind('ss', 'set-cmd-text -s :set')
+# config.bind('tIH', 'config-cycle -p -u *://*.{url:host}/* content.images ;; reload')
+# config.bind('tIh', 'config-cycle -p -u *://{url:host}/* content.images ;; reload')
+# config.bind('tIu', 'config-cycle -p -u {url} content.images ;; reload')
+# config.bind('tPH', 'config-cycle -p -u *://*.{url:host}/* content.plugins ;; reload')
+# config.bind('tPh', 'config-cycle -p -u *://{url:host}/* content.plugins ;; reload')
+# config.bind('tPu', 'config-cycle -p -u {url} content.plugins ;; reload')
+# config.bind('tSH', 'config-cycle -p -u *://*.{url:host}/* content.javascript.enabled ;; reload')
+# config.bind('tSh', 'config-cycle -p -u *://{url:host}/* content.javascript.enabled ;; reload')
+# config.bind('tSu', 'config-cycle -p -u {url} content.javascript.enabled ;; reload')
+# config.bind('th', 'back -t')
+# config.bind('tiH', 'config-cycle -p -t -u *://*.{url:host}/* content.images ;; reload')
+# config.bind('tih', 'config-cycle -p -t -u *://{url:host}/* content.images ;; reload')
+# config.bind('tiu', 'config-cycle -p -t -u {url} content.images ;; reload')
+# config.bind('tl', 'forward -t')
+# config.bind('tpH', 'config-cycle -p -t -u *://*.{url:host}/* content.plugins ;; reload')
+# config.bind('tph', 'config-cycle -p -t -u *://{url:host}/* content.plugins ;; reload')
+# config.bind('tpu', 'config-cycle -p -t -u {url} content.plugins ;; reload')
+# config.bind('tsH', 'config-cycle -p -t -u *://*.{url:host}/* content.javascript.enabled ;; reload')
+# config.bind('tsh', 'config-cycle -p -t -u *://{url:host}/* content.javascript.enabled ;; reload')
+# config.bind('tsu', 'config-cycle -p -t -u {url} content.javascript.enabled ;; reload')
+# config.bind('u', 'undo')
+# config.bind('v', 'enter-mode caret')
+# config.bind('wB', 'set-cmd-text -s :bookmark-load -w')
+# config.bind('wO', 'set-cmd-text :open -w {url:pretty}')
+# config.bind('wP', 'open -w -- {primary}')
+# config.bind('wb', 'set-cmd-text -s :quickmark-load -w')
+# config.bind('wf', 'hint all window')
+# config.bind('wh', 'back -w')
+# config.bind('wi', 'inspector')
+# config.bind('wl', 'forward -w')
+# config.bind('wo', 'set-cmd-text -s :open -w')
+# config.bind('wp', 'open -w -- {clipboard}')
+# config.bind('xO', 'set-cmd-text :open -b -r {url:pretty}')
+# config.bind('xo', 'set-cmd-text -s :open -b')
+# config.bind('yD', 'yank domain -s')
+# config.bind('yP', 'yank pretty-url -s')
+# config.bind('yT', 'yank title -s')
+# config.bind('yY', 'yank -s')
+# config.bind('yd', 'yank domain')
+# config.bind('yp', 'yank pretty-url')
+# config.bind('yt', 'yank title')
+# config.bind('yy', 'yank')
+# config.bind('{{', 'navigate prev -t')
+# config.bind('}}', 'navigate next -t')
+
+## Bindings for caret mode
+# config.bind('$', 'move-to-end-of-line', mode='caret')
+# config.bind('0', 'move-to-start-of-line', mode='caret')
+# config.bind('<Ctrl-Space>', 'drop-selection', mode='caret')
+# config.bind('<Escape>', 'leave-mode', mode='caret')
+# config.bind('<Return>', 'yank selection', mode='caret')
+# config.bind('<Space>', 'toggle-selection', mode='caret')
+# config.bind('G', 'move-to-end-of-document', mode='caret')
+# config.bind('H', 'scroll left', mode='caret')
+# config.bind('J', 'scroll down', mode='caret')
+# config.bind('K', 'scroll up', mode='caret')
+# config.bind('L', 'scroll right', mode='caret')
+# config.bind('Y', 'yank selection -s', mode='caret')
+# config.bind('[', 'move-to-start-of-prev-block', mode='caret')
+# config.bind(']', 'move-to-start-of-next-block', mode='caret')
+# config.bind('b', 'move-to-prev-word', mode='caret')
+# config.bind('c', 'enter-mode normal', mode='caret')
+# config.bind('e', 'move-to-end-of-word', mode='caret')
+# config.bind('gg', 'move-to-start-of-document', mode='caret')
+# config.bind('h', 'move-to-prev-char', mode='caret')
+# config.bind('j', 'move-to-next-line', mode='caret')
+# config.bind('k', 'move-to-prev-line', mode='caret')
+# config.bind('l', 'move-to-next-char', mode='caret')
+# config.bind('v', 'toggle-selection', mode='caret')
+# config.bind('w', 'move-to-next-word', mode='caret')
+# config.bind('y', 'yank selection', mode='caret')
+# config.bind('{', 'move-to-end-of-prev-block', mode='caret')
+# config.bind('}', 'move-to-end-of-next-block', mode='caret')
+
+## Bindings for command mode
+# config.bind('<Alt-B>', 'rl-backward-word', mode='command')
+# config.bind('<Alt-Backspace>', 'rl-backward-kill-word', mode='command')
+# config.bind('<Alt-D>', 'rl-kill-word', mode='command')
+# config.bind('<Alt-F>', 'rl-forward-word', mode='command')
+# config.bind('<Ctrl-?>', 'rl-delete-char', mode='command')
+# config.bind('<Ctrl-A>', 'rl-beginning-of-line', mode='command')
+# config.bind('<Ctrl-B>', 'rl-backward-char', mode='command')
+# config.bind('<Ctrl-C>', 'completion-item-yank', mode='command')
+# config.bind('<Ctrl-D>', 'completion-item-del', mode='command')
+# config.bind('<Ctrl-E>', 'rl-end-of-line', mode='command')
+# config.bind('<Ctrl-F>', 'rl-forward-char', mode='command')
+# config.bind('<Ctrl-H>', 'rl-backward-delete-char', mode='command')
+# config.bind('<Ctrl-K>', 'rl-kill-line', mode='command')
+# config.bind('<Ctrl-N>', 'command-history-next', mode='command')
+# config.bind('<Ctrl-P>', 'command-history-prev', mode='command')
+# config.bind('<Ctrl-Return>', 'command-accept --rapid', mode='command')
+# config.bind('<Ctrl-Shift-C>', 'completion-item-yank --sel', mode='command')
+# config.bind('<Ctrl-Shift-Tab>', 'completion-item-focus prev-category', mode='command')
+# config.bind('<Ctrl-Tab>', 'completion-item-focus next-category', mode='command')
+# config.bind('<Ctrl-U>', 'rl-unix-line-discard', mode='command')
+# config.bind('<Ctrl-W>', 'rl-unix-word-rubout', mode='command')
+# config.bind('<Ctrl-Y>', 'rl-yank', mode='command')
+# config.bind('<Down>', 'completion-item-focus --history next', mode='command')
+# config.bind('<Escape>', 'leave-mode', mode='command')
+# config.bind('<Return>', 'command-accept', mode='command')
+# config.bind('<Shift-Delete>', 'completion-item-del', mode='command')
+# config.bind('<Shift-Tab>', 'completion-item-focus prev', mode='command')
+# config.bind('<Tab>', 'completion-item-focus next', mode='command')
+# config.bind('<Up>', 'completion-item-focus --history prev', mode='command')
+
+## Bindings for hint mode
+# config.bind('<Ctrl-B>', 'hint all tab-bg', mode='hint')
+# config.bind('<Ctrl-F>', 'hint links', mode='hint')
+# config.bind('<Ctrl-R>', 'hint --rapid links tab-bg', mode='hint')
+# config.bind('<Escape>', 'leave-mode', mode='hint')
+# config.bind('<Return>', 'follow-hint', mode='hint')
+
+## Bindings for insert mode
+# config.bind('<Ctrl-E>', 'open-editor', mode='insert')
+# config.bind('<Escape>', 'leave-mode', mode='insert')
+# config.bind('<Shift-Ins>', 'insert-text {primary}', mode='insert')
+
+## Bindings for passthrough mode
+# config.bind('<Shift-Escape>', 'leave-mode', mode='passthrough')
+
+## Bindings for prompt mode
+# config.bind('<Alt-B>', 'rl-backward-word', mode='prompt')
+# config.bind('<Alt-Backspace>', 'rl-backward-kill-word', mode='prompt')
+# config.bind('<Alt-D>', 'rl-kill-word', mode='prompt')
+# config.bind('<Alt-F>', 'rl-forward-word', mode='prompt')
+# config.bind('<Alt-Shift-Y>', 'prompt-yank --sel', mode='prompt')
+# config.bind('<Alt-Y>', 'prompt-yank', mode='prompt')
+# config.bind('<Ctrl-?>', 'rl-delete-char', mode='prompt')
+# config.bind('<Ctrl-A>', 'rl-beginning-of-line', mode='prompt')
+# config.bind('<Ctrl-B>', 'rl-backward-char', mode='prompt')
+# config.bind('<Ctrl-E>', 'rl-end-of-line', mode='prompt')
+# config.bind('<Ctrl-F>', 'rl-forward-char', mode='prompt')
+# config.bind('<Ctrl-H>', 'rl-backward-delete-char', mode='prompt')
+# config.bind('<Ctrl-K>', 'rl-kill-line', mode='prompt')
+# config.bind('<Ctrl-P>', 'prompt-open-download --pdfjs', mode='prompt')
+# config.bind('<Ctrl-U>', 'rl-unix-line-discard', mode='prompt')
+# config.bind('<Ctrl-W>', 'rl-unix-word-rubout', mode='prompt')
+# config.bind('<Ctrl-X>', 'prompt-open-download', mode='prompt')
+# config.bind('<Ctrl-Y>', 'rl-yank', mode='prompt')
+# config.bind('<Down>', 'prompt-item-focus next', mode='prompt')
+# config.bind('<Escape>', 'leave-mode', mode='prompt')
+# config.bind('<Return>', 'prompt-accept', mode='prompt')
+# config.bind('<Shift-Tab>', 'prompt-item-focus prev', mode='prompt')
+# config.bind('<Tab>', 'prompt-item-focus next', mode='prompt')
+# config.bind('<Up>', 'prompt-item-focus prev', mode='prompt')
+
+## Bindings for register mode
+# config.bind('<Escape>', 'leave-mode', mode='register')
+
+## Bindings for yesno mode
+# config.bind('<Alt-Shift-Y>', 'prompt-yank --sel', mode='yesno')
+# config.bind('<Alt-Y>', 'prompt-yank', mode='yesno')
+# config.bind('<Escape>', 'leave-mode', mode='yesno')
+# config.bind('<Return>', 'prompt-accept', mode='yesno')
+# config.bind('n', 'prompt-accept no', mode='yesno')
+# config.bind('y', 'prompt-accept yes', mode='yesno')
diff --git a/qutebrowser/quickmarks b/qutebrowser/quickmarks
new file mode 100644
index 0000000..1037ac8
--- /dev/null
+++ b/qutebrowser/quickmarks
@@ -0,0 +1,5 @@
+Amazon https://www.amazon.co.uk/
+NatWest Cards Online https://cardsonline-commercial.com/RBSG_Commercial/Login.do?promoCode=NatWest
+QT Forum https://forum.qt.io/
+Fastmail https://www.fastmail.com/login/?
+Live Sport https://www.vipbox.live/
diff --git a/ranger/rc.conf b/ranger/rc.conf
new file mode 100644
index 0000000..3a64263
--- /dev/null
+++ b/ranger/rc.conf
@@ -0,0 +1 @@
+set preview_images true
diff --git a/redshift.conf b/redshift.conf
new file mode 100644
index 0000000..b32e213
--- /dev/null
+++ b/redshift.conf
@@ -0,0 +1,56 @@
+; Global settings for redshift
+[redshift]
+; Set the day and night screen temperatures
+temp-day=5700
+temp-night=3500
+
+; Enable/Disable a smooth transition between day and night
+; 0 will cause a direct change from day to night screen temperature.
+; 1 will gradually increase or decrease the screen temperature.
+transition=1
+
+; Set the screen brightness. Default is 1.0.
+;brightness=0.9
+; It is also possible to use different settings for day and night
+; since version 1.8.
+;brightness-day=0.7
+;brightness-night=0.4
+; Set the screen gamma (for all colors, or each color channel
+; individually)
+gamma=0.8
+;gamma=0.8:0.7:0.8
+; This can also be set individually for day and night since
+; version 1.10.
+;gamma-day=0.8:0.7:0.8
+;gamma-night=0.6
+
+; Set the location-provider: 'geoclue', 'geoclue2', 'manual'
+; type 'redshift -l list' to see possible values.
+; The location provider settings are in a different section.
+location-provider=manual
+
+; Set the adjustment-method: 'randr', 'vidmode'
+; type 'redshift -m list' to see all possible values.
+; 'randr' is the preferred method, 'vidmode' is an older API.
+; but works in some cases when 'randr' does not.
+; The adjustment method settings are in a different section.
+adjustment-method=randr
+
+; Configuration of the location-provider:
+; type 'redshift -l PROVIDER:help' to see the settings.
+; ex: 'redshift -l manual:help'
+; Keep in mind that longitudes west of Greenwich (e.g. the Americas)
+; are negative numbers.
+[manual]
+lat=55
+lon=-2
+
+; Configuration of the adjustment-method
+; type 'redshift -m METHOD:help' to see the settings.
+; ex: 'redshift -m randr:help'
+; In this example, randr is configured to adjust screen 1.
+; Note that the numbering starts from 0, so this is actually the
+; second screen. If this option is not specified, Redshift will try
+; to adjust _all_ screens.
+[randr]
+; screen=1
diff --git a/rsync_excludes.txt b/rsync_excludes.txt
new file mode 100644
index 0000000..965b622
--- /dev/null
+++ b/rsync_excludes.txt
@@ -0,0 +1,8 @@
+/lemon/.cache
+/lemon/.mozilla/firefox
+/lemon/.mypy_cache
+/lemon/.nvim-tmp/tmp
+/lemon/.mail/.notmuch
+/lemon/.local/share/Steam
+/lemon/Downloads
+/lemon/.fgfs/Scenery/Terrain
diff --git a/screenlayout/desktop_layout_debian.sh b/screenlayout/desktop_layout_debian.sh
new file mode 100755
index 0000000..51d22f6
--- /dev/null
+++ b/screenlayout/desktop_layout_debian.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+xrandr --output DP-0 --off --output DVI-D-0 --mode 1920x1080 --pos 3000x0 --rotate normal --output DP-1 --primary --mode 1920x1080 --pos 0x0 --rotate right --output HDMI-0 --mode 1920x1080 --pos 1080x0 --rotate normal
diff --git a/screenlayout/desktop_layout_debian_all_landscape.sh b/screenlayout/desktop_layout_debian_all_landscape.sh
new file mode 100755
index 0000000..cd42bdd
--- /dev/null
+++ b/screenlayout/desktop_layout_debian_all_landscape.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+xrandr --output DP-0 --off --output DVI-D-0 --mode 1920x1080 --pos 3840x0 --rotate normal --output DP-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output HDMI-0 --mode 1920x1080 --pos 1920x0 --rotate normal
diff --git a/screenlayout/left_portrait_right_land.sh b/screenlayout/left_portrait_right_land.sh
new file mode 100755
index 0000000..95cfedb
--- /dev/null
+++ b/screenlayout/left_portrait_right_land.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+xrandr --output DP-1 --primary --mode 1920x1080 --pos 0x0 --rotate right --output LVDS-1 --off --output HDMI-3 --off --output HDMI-2 --off --output HDMI-1 --mode 1920x1080 --pos 1800x0 --rotate normal --output DP-3 --off --output DP-2 --off --output DP-1 --off
diff --git a/scripts/cllogger b/scripts/cllogger
new file mode 100644
index 0000000..e13941f
--- /dev/null
+++ b/scripts/cllogger
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# We want to log stuff on a text file when there are interesting commands or snippets on the command line
+
+LOGFILE=/home/lemon/ownCloud/Textnotes/commandline_stuff.txt
+
+if [ $# -ne 1 ]; then
+ echo "You need to include a fucking string. Your message?"
+ exit 1
+fi
+
+echo $1
+echo $1 >> $LOGFILE
+
+echo "Ok, I've written that to the end of $LOGFILE."
diff --git a/scripts/export-html.pl b/scripts/export-html.pl
new file mode 100644
index 0000000..48aa96c
--- /dev/null
+++ b/scripts/export-html.pl
@@ -0,0 +1,90 @@
+#! /usr/bin/perl
+################################################################################
+##
+## Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.
+##
+## Permission is hereby granted, free of charge, to any person obtaining a copy
+## of this software and associated documentation files (the "Software"), to deal
+## in the Software without restriction, including without limitation the rights
+## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+## copies of the Software, and to permit persons to whom the Software is
+## furnished to do so, subject to the following conditions:
+##
+## The above copyright notice and this permission notice shall be included
+## in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+## SOFTWARE.
+##
+## http://www.opensource.org/licenses/mit-license.php
+##
+################################################################################
+
+use strict;
+use warnings;
+
+# Give a nice error if the (non-standard) JSON module is not installed.
+eval "use JSON";
+if ($@)
+{
+ print "Error: You need to install the JSON Perl module.\n";
+ exit 1;
+}
+
+# Use the taskwarrior 2.0+ export command to filter and return JSON
+my $command = join (' ', ("env PATH='$ENV{PATH}' task rc.verbose=nothing rc.json.array=no export", @ARGV));
+if ($command =~ /No matches/)
+{
+ printf STDERR $command;
+ exit 1;
+}
+
+# Generate output.
+print "<html>\n",
+ " <body>\n",
+ " <table>\n",
+ " <thead>\n",
+ " <tr>\n",
+ " <td>ID</td>\n",
+ " <td>Pri</td>\n",
+ " <td>Description</td>\n",
+ " <td>Project</td>\n",
+ " <td>Due</td>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n";
+
+my $count = 0;
+for my $task (split "\n", qx{$command})
+{
+ ++$count;
+ my $data = from_json ($task);
+
+ print " <tr>\n",
+ " <td>", ($data->{'id'} || ''), "</td>\n",
+ " <td>", ($data->{'priority'} || ''), "</td>\n",
+ " <td>", ($data->{'description'} || ''), "</td>\n",
+ " <td>", ($data->{'project'} || ''), "</td>\n",
+ " <td>", ($data->{'due'} || ''), "</td>\n",
+ " </tr>\n";
+}
+
+print " </tbody>\n",
+ " <tfooter>\n",
+ " <tr>\n",
+ " <td>", $count, " matching tasks</td>\n",
+ " </tr>\n",
+ " </tfooter>\n",
+ " </table>\n",
+ " </body>\n",
+ "</html>\n";
+
+exit 0;
+
+################################################################################
+
diff --git a/scripts/export-ical.pl b/scripts/export-ical.pl
new file mode 100644
index 0000000..594feea
--- /dev/null
+++ b/scripts/export-ical.pl
@@ -0,0 +1,102 @@
+#! /usr/bin/perl
+################################################################################
+##
+## Copyright 2006 - 2016, Paul Beckingham, Federico Hernandez.
+##
+## Permission is hereby granted, free of charge, to any person obtaining a copy
+## of this software and associated documentation files (the "Software"), to deal
+## in the Software without restriction, including without limitation the rights
+## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+## copies of the Software, and to permit persons to whom the Software is
+## furnished to do so, subject to the following conditions:
+##
+## The above copyright notice and this permission notice shall be included
+## in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+## SOFTWARE.
+##
+## http://www.opensource.org/licenses/mit-license.php
+##
+################################################################################
+
+use strict;
+use warnings;
+
+# Give a nice error if the (non-standard) JSON module is not installed.
+eval "use JSON";
+if ($@)
+{
+ print "Error: You need to install the JSON Perl module.\n";
+ exit 1;
+}
+
+# Use the taskwarrior 2.0+ export command to filter and return JSON
+my $command = join (' ', ("env PATH=$ENV{PATH} task rc.verbose=nothing rc.json.array=no export", @ARGV));
+if ($command =~ /No matches/)
+{
+ printf STDERR $command;
+ exit 1;
+}
+
+# Generate output.
+print "BEGIN:VCALENDAR\n",
+ "VERSION:2.0\n",
+ "PRODID:=//GBF/taskwarrior 1.9.4//EN\n";
+
+for my $task (split "\n", qx{$command})
+{
+ my $data = from_json ($task);
+
+ print "BEGIN:VTODO\n";
+ print "UID:$data->{'uuid'}\n";
+ print "DTSTAMP:$data->{'entry'}\n";
+ print "DTSTART:$data->{'start'}\n" if exists $data->{'start'};
+ print "DUE:$data->{'due'}\n" if exists $data->{'due'};
+ print "COMPLETED:$data->{'end'}\n" if exists $data->{'end'};
+ print "SUMMARY:$data->{'description'}\n";
+ print "CLASS:PRIVATE\n";
+ print "CATEGORIES:", join (',', @{$data->{'tags'}}), "\n" if exists $data->{'tags'};
+
+ # Priorities map to a 1-9 scale.
+ if (exists $data->{'priority'})
+ {
+ print "PRIORITY:", ($data->{'priority'} eq 'H' ? '1' :
+ $data->{'priority'} eq 'M' ? '5' :
+ '9'), "\n";
+ }
+
+ # Status maps differently.
+ my $status = $data->{'status'};
+ if ($status eq 'pending' || $status eq 'waiting')
+ {
+ print "STATUS:", (exists $data->{'start'} ? 'IN-PROCESS' : 'NEEDS-ACTION'), "\n";
+ }
+ elsif ($status eq 'completed')
+ {
+ print "STATUS:COMPLETED\n";
+ }
+ elsif ($status eq 'deleted')
+ {
+ print "STATUS:CANCELLED\n";
+ }
+
+ # Annotations become comments.
+ if (exists $data->{'annotations'})
+ {
+ print "COMMENT:$_->{'description'}\n" for @{$data->{'annotations'}};
+ }
+
+ print "END:VTODO\n";
+}
+
+print "END:VCALENDAR\n";
+exit 0;
+
+################################################################################
+
diff --git a/scripts/ical2org.awk b/scripts/ical2org.awk
new file mode 100644
index 0000000..6b1996f
--- /dev/null
+++ b/scripts/ical2org.awk
@@ -0,0 +1,391 @@
+#!/usr/bin/awk -f
+# awk script for converting an iCal formatted file to a sequence of org-mode headings.
+# this may not work in general but seems to work for day and timed events from Google's
+# calendar, which is really all I need right now...
+#
+# usage:
+# awk -f THISFILE < icalinputfile.ics > orgmodeentries.org
+#
+# Note: change org meta information generated below for author and
+# email entries!
+#
+# Caveats:
+#
+# - date entries with no time specified are assumed to be local time zone;
+# same remark for date entries that do have a time but do not end with Z
+# e.g.: 20130101T123456 is local and will be kept as 2013-01-01 12:34
+# where 20130223T123422Z is UTC and will be corrected appropriately
+#
+# - UTC times are changed into local times, using the time zone of the
+# computer that runs the script; it would be very hard in an awk script
+# to respect the time zone of a file belonging to another time zone:
+# the offsets will be different as well as the switchover time(s);
+# (consider a remote shell to a computer with the file's time zone)
+#
+# - the UTC conversion entirely relies on the built-in strftime method;
+# the author is not responsible for any erroneous conversions nor the
+# consequence of such conversions
+#
+# - does process RRULE recurring events, but ignores COUNT specifiers
+#
+# - does not process EXDATE to exclude date(s) from recurring events
+#
+# Eric S Fraga
+# 20100629 - initial version
+# 20100708 - added end times to timed events
+# - adjust times according to time zone information
+# - fixed incorrect transfer for entries with ":" embedded within the text
+# - added support for multi-line summary entries (which become headlines)
+# 20100709 - incorporated time zone identification
+# - fixed processing of continuation lines as Google seems to
+# have changed, in the last day, the number of spaces at
+# the start of the line for each continuation...
+# - remove backslashes used to protect commas in iCal text entries
+# no further revision log after this as the file was moved into a git
+# repository...
+#
+# Updated by: Guido Van Hoecke <guivhoATgmailDOTcom>
+# Last change: 2013.05.26 14:28:33
+#----------------------------------------------------------------------------------
+
+BEGIN {
+ ### config section
+
+ # maximum age in days for entries to be output: set this to -1 to
+ # get all entries or to N>0 to only get enties that start or end
+ # less than N days ago
+ max_age = 7;
+
+ # set to 1 or 0 to yes or not output a header block with TITLE,
+ # AUTHOR, EMAIL etc...
+ header = 1;
+
+ # set to 1 or 0 to yes or not output the original ical preamble as
+ # comment
+ preamble = 1;
+
+ # set to 1 to output time and summary as one line starting with
+ # the time (value 1) or to 0 to output the summary as first line
+ # and the date and time info as a second line
+ condense = 0;
+
+ # set to 1 or 0 to yes or not output the original ical entry as a
+ # comment (mostly useful for debugging purposes)
+ original = 1;
+
+ # google truncates long subjects with ... which is misleading in
+ # an org file: it gives the unfortunate impression that an
+ # expanded entry is still collapsed; value 1 will trim those
+ # ... and value 0 doesn't touch them
+ trimdots = 1;
+
+ # change this to your name
+ author = "Matthew Lemon"
+
+ # and to your email address
+ emailaddress = "matthew.lemon@gmail.com"
+
+ ### end config section
+
+ # use a colon to separate the type of data line from the actual contents
+ FS = ":";
+
+ # we only need to preserve the original entry lines if either the
+ # preamble or original options are true
+ preserve = preamble || original
+ first = 1; # true until an event has been found
+ max_age_seconds = max_age*24*60*60
+
+ if (header) {
+ print "#+TITLE: Main Google calendar entries"
+ print "#+AUTHOR: ", author
+ print "#+EMAIL: ", emailaddress
+ print "#+DESCRIPTION: converted using the ical2org awk script"
+ print "#+CATEGORY: google"
+ print "#+STARTUP: hidestars"
+ print "#+STARTUP: overview"
+ print ""
+ }
+}
+
+# continuation lines (at least from Google) start with a space
+# if the continuation is after a description or a summary, append the entry
+# to the respective variable
+
+/^[ ]/ {
+ if (indescription) {
+ entry = entry gensub("\r", "", "g", gensub("^[ ]", "", "", $0));
+ } else if (insummary) {
+ summary = summary gensub("\r", "", "g", gensub("^[ ]", "", "", $0))
+ }
+ if (preserve)
+ icalentry = icalentry "\n" $0
+}
+
+/^BEGIN:VEVENT/ {
+ # start of an event: initialize global velues used for each event
+ date = "";
+ entry = ""
+ headline = ""
+ icalentry = "" # the full entry for inspection
+ id = ""
+ indescription = 0;
+ insummary = 0
+ intfreq = "" # the interval and frequency for repeating org timestamps
+ lasttimestamp = -1;
+ location = ""
+ rrend = ""
+ status = ""
+ summary = ""
+
+ # if this is the first event, output the preamble from the iCal file
+ if (first) {
+ if(preamble) {
+ print "* COMMENT original iCal preamble"
+ print gensub("\r", "", "g", icalentry)
+ }
+ if (preserve)
+ icalentry = ""
+ first = false;
+ }
+}
+
+# any line that starts at the left with a non-space character is a new data field
+
+/^[A-Z]/ {
+ # we do not copy DTSTAMP lines as they change every time you download
+ # the iCal format file which leads to a change in the converted
+ # org file as I output the original input. This change, which is
+ # really content free, makes a revision control system update the
+ # repository and confuses.
+ if (preserve)
+ if (! index("DTSTAMP", $1))
+ icalentry = icalentry "\n" $0
+ # this line terminates the collection of description and summary entries
+ indescription = 0;
+ insummary = 0;
+}
+
+# this type of entry represents a day entry, not timed, with date stamp YYYYMMDD
+
+/^DTSTART;VALUE=DATE/ {
+ date = datestring($2);
+}
+
+/^DTEND;VALUE=DATE/ {
+ time2 = datestring($2, 1);
+ if ( issameday )
+ time2 = ""
+}
+
+# this represents a timed entry with date and time stamp YYYYMMDDTHHMMSS
+# we ignore the seconds
+
+/^DTSTART[:;][^V]/ {
+ date = datetimestring($2);
+ # print date;
+}
+
+# and the same for the end date;
+
+/^DTEND[:;][^V]/ {
+ time2 = datetimestring($2);
+ if (substr(date,1,10) == substr(time2,1,10)) {
+ # timespan within same date, use one date with a time range
+ date = date "-" substr(time2, length(time2)-4)
+ time2 = ""
+ }
+}
+
+# repetition rule
+
+/^RRULE:FREQ=(DAILY|WEEKLY|MONTHLY|YEARLY)/ {
+ # get the d, w, m or y value
+ freq = tolower(gensub(/.*FREQ=(.).*/, "\\1", $0))
+ # get the interval, and use 1 if none specified
+ interval = $2 ~ /INTERVAL=/ ? gensub(/.*INTERVAL=([0-9]+);.*/, "\\1", $2) : 1
+ # get the enddate of the rule and use "" if none specified
+ rrend = $2 ~ /UNTIL=/ ? datestring(gensub(/.*UNTIL=([0-9]{8}).*/, "\\1", $2)) : ""
+ # build the repetitor vale as understood by org
+ intfreq = " +" interval freq
+ # if the repetition is daily, and there is an end date, drop the repetitor
+ # as that is the default
+ if (intfreq == " +1d" && time2 =="" && rrend != "")
+ intfreq = ""
+}
+
+# The description will the contents of the entry in org-mode.
+# this line may be continued.
+
+/^DESCRIPTION/ {
+ $1 = "";
+ entry = entry gensub("\r", "", "g", $0);
+ indescription = 1;
+}
+
+# the summary will be the org heading
+
+/^SUMMARY/ {
+ $1 = "";
+ summary = gensub("\r", "", "g", $0);
+
+ # trim trailing dots if requested by config option
+ if(trimdots && summary ~ /\.\.\.$/)
+ sub(/\.\.\.$/, "", summary)
+ insummary = 1;
+}
+
+# the unique ID will be stored as a property of the entry
+
+/^UID/ {
+ id = gensub("\r", "", "g", $2);
+}
+
+/^LOCATION/ {
+ location = gensub("\r", "", "g", $2);
+}
+
+/^STATUS/ {
+ status = gensub("\r", "", "g", $2);
+}
+
+# when we reach the end of the event line, we output everything we
+# have collected so far, creating a top level org headline with the
+# date/time stamp, unique ID property and the contents, if any
+
+/^END:VEVENT/ {
+ #output event
+ if(max_age<0 || ( lasttimestamp>0 && systime()<lasttimestamp+max_age_seconds ) )
+ {
+ # build org timestamp
+ if (intfreq != "")
+ date = date intfreq
+ if (time2 != "")
+ date = date ">--<" time2
+ else if (rrend != "")
+ date = date ">--<" rrend
+
+ # translate \n sequences to actual newlines and unprotect commas (,)
+ if (condense)
+ print "* <" date "> " gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)))
+ else
+ print "* " gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary))) "\n<" date ">"
+ print ":PROPERTIES:"
+ print ":ID: " id
+ if(length(location))
+ print ":LOCATION: " location
+ if(length(status))
+ print ":STATUS: " status
+ print ":END:"
+
+ print ""
+ # translate \n sequences to actual newlines and unprotect commas (,)
+ if(length(entry)>1)
+ print gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry)));
+
+ # output original entry if requested by 'original' config option
+ if (original)
+ print "** COMMENT original iCal entry\n", gensub("\r", "", "g", icalentry)
+ }
+}
+
+
+
+# funtion to convert an iCal time string 'yyyymmddThhmmss[Z]' into a
+# date time string as used by org, preferably including the short day
+# of week: 'yyyy-mm-dd day hh:mm' or 'yyyy-mm-dd hh:mm' if we cannot
+# define the day of the week
+
+function datetimestring(input)
+{
+ # print "________"
+ # print "input : " input
+ # convert the iCal Date+Time entry to a format that mktime can understand
+ spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 \\4 \\5 \\6", "g", input);
+ # print "spec :" spec
+
+ stamp = mktime(spec);
+ lasttimestamp = stamp;
+
+ if (stamp <= 0) {
+ # this is a date before the start of the epoch, so we cannot
+ # use strftime and will deliver a 'yyyy-mm-dd hh:mm' string
+ # without day of week; this assumes local time, and does not
+ # attempt UTC offset correction
+ spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3 \\4:\\5", "g", input);
+ # print "==> spec:" spec;
+ return spec;
+ }
+
+ if (input ~ /[0-9]{8}T[0-9]{6}Z/ ) {
+ # this is an utc time;
+ # we need to correct the timestamp by the utc offset for this time
+ offset = strftime("%z", stamp)
+ pm = substr(offset,1,1) 1 # define multiplier +1 or -1
+ hh = substr(offset,2,2) * 3600 * pm
+ mm = substr(offset,4,2) * 60 * pm
+
+ # adjust the timestamp
+ stamp = stamp + hh + mm
+ }
+
+ return strftime("%Y-%m-%d %a %H:%M", stamp);
+}
+
+# function to convert an iCal date into an org date;
+# the optional parameter indicates whether this is an end date;
+# for single or multiple whole day events, the end date given by
+# iCal is the date of the first day after the event;
+# if the optional 'isenddate' parameter is non zero, this function
+# tries to reduce the given date by one day
+
+function datestring(input, isenddate)
+{
+ #convert the iCal string to a an mktime input string
+ spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 00 00 00", "g", input);
+
+ # compute the nr of seconds after or before the epoch
+ # dates before the epoch will have a negative timestamp
+ # days after the epoch will have a positive timestamp
+ stamp = mktime(spec);
+
+ if (isenddate) {
+ # subtract 1 day from the timestamp
+ # note that this also works for dates before the epoch
+ stamp = stamp - 86400;
+
+ # register whether the end date is same as the start date
+ issameday = lasttimestamp == stamp
+ }
+ # save timestamp to allow for check of max_age
+ lasttimestamp = stamp
+
+ if (stamp < 0) {
+ # this date is before the epoch;
+ # the returned datestring will not have the short day of week string
+ # as strftime does not handle negative times;
+ # we have to construct the datestring directly from the input
+ if (isenddate) {
+ # we really should return the date before the input date, but strftime
+ # does not work with negative timestamp values; so we can not use it
+ # to obtain the string representation of the corrected timestamp;
+ # we have to return the date specified in the iCal input and we
+ # add time 00:00 to clarify this
+ return spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3 00:00", "g", input);
+ } else {
+ # just generate the desired representation of the input date, without time;
+ return gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", input);
+ }
+ }
+
+ # return the date and day of week
+ return strftime("%Y-%m-%d %a", stamp);
+}
+
+# Local Variables:
+# time-stamp-line-limit: 1000
+# time-stamp-format: "%04y.%02m.%02d %02H:%02M:%02S"
+# time-stamp-active: t
+# time-stamp-start: "Last change:[ \t]+"
+# time-stamp-end: "$"
+# End:
diff --git a/scripts/keepassx2pass_csv.py b/scripts/keepassx2pass_csv.py
new file mode 100644
index 0000000..c3bd288
--- /dev/null
+++ b/scripts/keepassx2pass_csv.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python3
+
+# Copyright 2015 David Francoeur <dfrancoeur04@gmail.com>
+# Copyright 2017 Nathan Sommer <nsommer@wooster.edu>
+#
+# This file is licensed under the GPLv2+. Please see COPYING for more
+# information.
+#
+# KeePassX 2+ on Mac allows export to CSV. The CSV contains the following
+# headers:
+# "Group","Title","Username","Password","URL","Notes"
+#
+# By default the pass entry will have the path Group/Title/Username and will
+# have the following structure:
+#
+# <Password>
+# user: <Username>
+# url: <URL>
+# notes: <Notes>
+#
+# Any missing fields will be omitted from the entry. If Username is not present
+# the path will be Group/Title.
+#
+# The username can be left out of the path by using the --name_is_original
+# switch. Group and Title can be converted to lowercase using the --to_lower
+# switch. Groups can be excluded using the --exclude_groups option.
+#
+# Default usage: ./keepass2csv2pass.py input.csv
+#
+# To see the full usage: ./keepass2csv2pass.py -h
+
+import sys
+import csv
+import argparse
+from subprocess import Popen, PIPE
+
+
+class KeepassCSVArgParser(argparse.ArgumentParser):
+ """
+ Custom ArgumentParser class which prints the full usage message if the
+ input file is not provided.
+ """
+ def error(self, message):
+ print(message, file=sys.stderr)
+ self.print_help()
+ sys.exit(2)
+
+
+def pass_import_entry(path, data):
+ """Import new password entry to password-store using pass insert command"""
+ proc = Popen(['pass', 'insert', '--multiline', path], stdin=PIPE,
+ stdout=PIPE)
+ proc.communicate(data.encode('utf8'))
+ proc.wait()
+
+
+def confirmation(prompt):
+ """
+ Ask the user for 'y' or 'n' confirmation and return a boolean indicating
+ the user's choice. Returns True if the user simply presses enter.
+ """
+
+ prompt = '{0} {1} '.format(prompt, '(Y/n)')
+
+ while True:
+ user_input = input(prompt)
+
+ if len(user_input) > 0:
+ first_char = user_input.lower()[0]
+ else:
+ first_char = 'y'
+
+ if first_char == 'y':
+ return True
+ elif first_char == 'n':
+ return False
+
+ print('Please enter y or n')
+
+
+def insert_file_contents(filename, preparation_args):
+ """ Read the file and insert each entry """
+
+ entries = []
+
+ with open(filename, 'rU') as csv_in:
+ next(csv_in)
+ csv_out = (line for line in csv.reader(csv_in, dialect='excel'))
+ for row in csv_out:
+ path, data = prepare_for_insertion(row, **preparation_args)
+ if path and data:
+ entries.append((path, data))
+
+ if len(entries) == 0:
+ return
+
+ print('Entries to import:')
+
+ for (path, data) in entries:
+ print(path)
+
+ if confirmation('Proceed?'):
+ for (path, data) in entries:
+ pass_import_entry(path, data)
+ print(path, 'imported!')
+
+
+def prepare_for_insertion(row, name_is_username=True, convert_to_lower=False,
+ exclude_groups=None):
+ """Prepare a CSV row as an insertable string"""
+
+ group = escape(row[0])
+ name = escape(row[1])
+
+ # Bail if we are to exclude this group
+ if exclude_groups is not None:
+ for exclude_group in exclude_groups:
+ if exclude_group.lower() in group.lower():
+ return None, None
+
+ # The first component of the group is 'Root', which we do not need
+ group_components = group.split('/')[1:]
+
+ path = '/'.join(group_components + [name])
+
+ if convert_to_lower:
+ path = path.lower()
+
+ username = row[2]
+ password = row[3]
+ url = row[4]
+ notes = row[5]
+
+ if username and name_is_username:
+ path += '/' + username
+
+ data = '{}\n'.format(password)
+
+ if username:
+ data += 'user: {}\n'.format(username)
+
+ if url:
+ data += 'url: {}\n'.format(url)
+
+ if notes:
+ data += 'notes: {}\n'.format(notes)
+
+ return path, data
+
+
+def escape(str_to_escape):
+ """ escape the list """
+ return str_to_escape.replace(" ", "-")\
+ .replace("&", "and")\
+ .replace("[", "")\
+ .replace("]", "")
+
+
+def main():
+ description = 'Import pass entries from an exported KeePassX CSV file.'
+ parser = KeepassCSVArgParser(description=description)
+
+ parser.add_argument('--exclude_groups', nargs='+',
+ help='Groups to exclude when importing')
+ parser.add_argument('--to_lower', action='store_true',
+ help='Convert group and name to lowercase')
+ parser.add_argument('--name_is_original', action='store_true',
+ help='Use the original entry name instead of the '
+ 'username for the pass entry')
+ parser.add_argument('input_file', help='The CSV file to read from')
+
+ args = parser.parse_args()
+
+ preparation_args = {
+ 'convert_to_lower': args.to_lower,
+ 'name_is_username': not args.name_is_original,
+ 'exclude_groups': args.exclude_groups
+ }
+
+ input_file = args.input_file
+ print("File to read:", input_file)
+ insert_file_contents(input_file, preparation_args)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/nextcloud-data-persmissions.sh b/scripts/nextcloud-data-persmissions.sh
new file mode 100644
index 0000000..4156fa5
--- /dev/null
+++ b/scripts/nextcloud-data-persmissions.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+voldata='/home/lemon/Nextcloud/'
+
+printf "chmod Files and Directories\n"
+find ${voldata}/ -type f -print0 | xargs -0 chmod 0640
+find ${voldata}/ -type d -print0 | xargs -0 chmod 0750
+
diff --git a/scripts/org-gcal-sync b/scripts/org-gcal-sync
new file mode 100644
index 0000000..cd0880e
--- /dev/null
+++ b/scripts/org-gcal-sync
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# customize these
+WGET=/usr/bin/wget
+ICS2ORG=/home/lemon/bin/ical2org.awk
+WORK_ICSFILE=/home/lemon/ownCloud/org/work.ics
+WORK_ORGFILE=/home/lemon/ownCloud/org/work_cal.org
+WORK_URL=https://calendar.google.com/calendar/ical/matthew.lemon%40gmail.com/private-5b9d1efdec3e07b601e48e01e6b2d5c9/basic.ics
+
+HOME_ICSFILE=/home/lemon/ownCloud/org/home.ics
+HOME_ORGFILE=/home/lemon/ownCloud/org/home_cal.org
+HOME_URL=https://calendar.google.com/calendar/ical/12panp3nqdbmm9df4if9jigigo%40group.calendar.google.com/private-4b7e890b479d67c3cf66c4119c80ec63/basic.ics
+
+ONCALL_ICSFILE=/home/lemon/ownCloud/org/oncall.ics
+ONCALL_ORGFILE=/home/lemon/ownCloud/org/oncall_cal.org
+ONCALL_URL=https://calendar.google.com/calendar/ical/od5ch3rahhapi4e3sgkij8jkhg%40group.calendar.google.com/private-ee0dcd7197d05da273de5c32db73ac5d/basic.ics
+
+MYTASKSCALL_ICSFILE=/home/lemon/ownCloud/org/mytasks.ics
+MYTASKSCALL_ORGFILE=/home/lemon/ownCloud/org/mytasks_cal.org
+MYTASKSCALL_URL=https://calendar.google.com/calendar/ical/1egrujsm7tkp6unaenu2354mq4%40group.calendar.google.com/private-5d95863285306565a20aeb791d591f55/basic.ics
+# no customization needed below
+$WGET -O $WORK_ICSFILE $WORK_URL
+gawk -f $ICS2ORG $WORK_ICSFILE > $WORK_ORGFILE
+
+$WGET -O $HOME_ICSFILE $HOME_URL
+gawk -f $ICS2ORG $HOME_ICSFILE > $HOME_ORGFILE
+
+$WGET -O $ONCALL_ICSFILE $ONCALL_URL
+gawk -f $ICS2ORG $ONCALL_ICSFILE > $ONCALL_ORGFILE
+
+$WGET -O $MYTASKSCALL_ICSFILE $MYTASKSCALL_URL
+gawk -f $ICS2ORG $MYTASKSCALL_ICSFILE > $MYTASKSCALL_ORGFILE
diff --git a/scripts/top_ten_directories.sh b/scripts/top_ten_directories.sh
new file mode 100644
index 0000000..5da89cb
--- /dev/null
+++ b/scripts/top_ten_directories.sh
@@ -0,0 +1,2 @@
+#!/usr/bin
+sudo find . -type d -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {}
diff --git a/scripts/wireless_fix.sh b/scripts/wireless_fix.sh
new file mode 100755
index 0000000..7c6e32a
--- /dev/null
+++ b/scripts/wireless_fix.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+echo "Removing rtl8xxxu. Please wait.\n"
+modprobe -r rtl8xxxu
+sleep 20
+echo "Enabling rtl8xxxu. Please wait.\n"
+modprobe rtl8xxxu
diff --git a/sqliterc b/sqliterc
new file mode 100644
index 0000000..d54e55d
--- /dev/null
+++ b/sqliterc
@@ -0,0 +1,5 @@
+.headers on
+.mode column
+.nullvalue ¤
+.prompt "> "
+.timer on
diff --git a/st-master/.gitignore b/st-master/.gitignore
new file mode 100644
index 0000000..aa41e95
--- /dev/null
+++ b/st-master/.gitignore
@@ -0,0 +1,3 @@
+st
+st.o
+x.o
diff --git a/st-master/.travis.yml b/st-master/.travis.yml
new file mode 100644
index 0000000..dfc38d4
--- /dev/null
+++ b/st-master/.travis.yml
@@ -0,0 +1,11 @@
+language: c
+compiler:
+ - gcc
+script: make
+notifications:
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/ec51097009f538278ab8
+ on_success: change
+ on_failure: always
+
diff --git a/st-master/LICENSE b/st-master/LICENSE
new file mode 100644
index 0000000..c356c39
--- /dev/null
+++ b/st-master/LICENSE
@@ -0,0 +1,34 @@
+MIT/X Consortium License
+
+© 2014-2018 Hiltjo Posthuma <hiltjo at codemadness dot org>
+© 2018 Devin J. Pohly <djpohly at gmail dot com>
+© 2014-2017 Quentin Rameau <quinq at fifth dot space>
+© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com>
+© 2008-2017 Anselm R Garbe <garbeam at gmail dot com>
+© 2012-2017 Roberto E. Vargas Caballero <k0ga at shike2 dot com>
+© 2012-2016 Christoph Lohmann <20h at r-36 dot net>
+© 2013 Eon S. Jeon <esjeon at hyunmu dot am>
+© 2013 Alexander Sedov <alex0player at gmail dot com>
+© 2013 Mark Edgar <medgar123 at gmail dot com>
+© 2013-2014 Eric Pruitt <eric.pruitt at gmail dot com>
+© 2013 Michael Forney <mforney at mforney dot org>
+© 2013-2014 Markus Teich <markus dot teich at stusta dot mhn dot de>
+© 2014-2015 Laslo Hunhold <dev at frign dot de>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/st-master/Makefile b/st-master/Makefile
new file mode 100644
index 0000000..0b3cecd
--- /dev/null
+++ b/st-master/Makefile
@@ -0,0 +1,57 @@
+# st - simple terminal
+# See LICENSE file for copyright and license details.
+.POSIX:
+
+include config.mk
+
+SRC = st.c x.c
+OBJ = $(SRC:.c=.o)
+
+all: options st
+
+options:
+ @echo st build options:
+ @echo "CFLAGS = $(STCFLAGS)"
+ @echo "LDFLAGS = $(STLDFLAGS)"
+ @echo "CC = $(CC)"
+
+config.h:
+ cp config.def.h config.h
+
+.c.o:
+ $(CC) $(STCFLAGS) -c $<
+
+st.o: config.h st.h win.h
+x.o: arg.h st.h win.h
+
+$(OBJ): config.h config.mk
+
+st: $(OBJ)
+ $(CC) -o $@ $(OBJ) $(STLDFLAGS)
+
+clean:
+ rm -f st $(OBJ) st-$(VERSION).tar.gz
+
+dist: clean
+ mkdir -p st-$(VERSION)
+ cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\
+ config.def.h st.info st.1 arg.h st.h win.h $(SRC)\
+ st-$(VERSION)
+ tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz
+ rm -rf st-$(VERSION)
+
+install: st
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
+ cp -f st $(DESTDIR)$(PREFIX)/bin
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/st
+ mkdir -p $(DESTDIR)$(MANPREFIX)/man1
+ sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1
+ chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1
+ tic -sx st.info
+ @echo Please see the README file regarding the terminfo entry of st.
+
+uninstall:
+ rm -f $(DESTDIR)$(PREFIX)/bin/st
+ rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1
+
+.PHONY: all options clean dist install uninstall
diff --git a/st-master/README.md b/st-master/README.md
new file mode 100644
index 0000000..2da44c2
--- /dev/null
+++ b/st-master/README.md
@@ -0,0 +1,77 @@
+# Luke's build of st - the simple (suckless) terminal
+
+The [suckless terminal (st)](https://st.suckless.org/) with some additional features:
+
++ Compatibility with `Xresources` and `pywal` for dynamic colors.
++ Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise.
++ Transparency/alpha, which is also adjustable from `~/.Xresources`.
++ Default font is system "mono" at 16pt, meaning the font will match your system font.
++ Very useful keybinds including:
+ + Copy is alt-c, paste is alt-v or alt-p pastes from primary selection
+ + Alt-l feeds all urls on screen to dmenu, so they user can choose and
+ follow one (requires xurls and dmenu installed).
+ + Zoom in/out or increase font size with Alt+Shift+k/j or u/d for larger intervals.
+ + Hold alt and press either ↑/↓ or the vim keys k/j to move up/down in the terminal.
+ + Shift+Mouse wheel do the same.
+ + Alt-u and Alt-d scroll back/forward in history a page at a time.
+ + Alt-PageUp and Alt-PageDown will do the same.
++ Vertcenter
++ Scrollback
++ updated to latest version 0.8.1
+
+The following additional bindings were added before I forked this:
+
++ Scroll through history -- Shift+PageUp/PageDown or Shift+Mouse wheel
++ Increase/decrease font size -- Shift+Alt+PageUp/PageDown
++ Return to default font size -- Alt+Home
++ Paste -- Shift+Insert
+
+## Installation for newbs
+
+```
+make
+sudo make install
+```
+
+Obviously, `make` is required to build. `fontconfig` is required for the
+default build, since it asks `fontconfig` for your system monospace font. It
+might be obvious, but `libX11` and `libXft` are required as well. Chances are,
+you have all of this installed already.
+
+On OpenBSD, be sure to edit `config.mk` first and remove `-lrt` from the
+`$LIBS` before compiling.
+
+## How to configure dynamically with Xresources
+
+For many key variables, this build of `st` will look for X settings set in
+either `~/.Xdefaults` or `~/.Xresources`. You must run `xrdb` on one of these
+files to load the settings.
+
+For example, you can define your desired fonts, transparency or colors:
+
+```
+*.font: Liberation Mono:pixelsize=12:antialias=true:autohint=true;
+*.alpha: 150
+*.color0: #111
+...
+```
+
+The `alpha` value (for transparency) goes from `0` (transparent) to `255`
+(opaque).
+
+### Colors
+
+To be clear about the color settings:
+
+- This build will use gruvbox colors by default and as a fallback.
+- If there are Xresources colors defined, those will take priority.
+- But if `wal` has run in your session, its colors will take priority.
+
+Note that when you run `wal`, it will negate the transparency of existing
+windows, but new windows will continue with the previously defined
+transparency.
+
+## Contact
+
+- Luke Smith <luke@lukesmith.xyz>
+- [https://lukesmith.xyz](https://lukesmith.xyz)
diff --git a/st-master/arg.h b/st-master/arg.h
new file mode 100644
index 0000000..a22e019
--- /dev/null
+++ b/st-master/arg.h
@@ -0,0 +1,50 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][0] == '-'\
+ && argv[0][1];\
+ argc--, argv++) {\
+ char argc_;\
+ char **argv_;\
+ int brk_;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ int i_;\
+ for (i_ = 1, brk_ = 0, argv_ = argv;\
+ argv[0][i_] && !brk_;\
+ i_++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][i_];\
+ switch (argc_)
+
+#define ARGEND }\
+ }
+
+#define ARGC() argc_
+
+#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk_ = 1, (argv[0][i_+1] != '\0')?\
+ (&argv[0][i_+1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk_ = 1, (argv[0][i_+1] != '\0')?\
+ (&argv[0][i_+1]) :\
+ (argc--, argv++, argv[0])))
+
+#endif
diff --git a/st-master/config.h b/st-master/config.h
new file mode 100644
index 0000000..2ec16f5
--- /dev/null
+++ b/st-master/config.h
@@ -0,0 +1,526 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+ * appearance
+ *
+ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
+ */
+static char *font = "FiraMono:pixelsize=18:antialias=true:autohint=true";
+static int borderpx = 2;
+
+/*
+ * What program is execed by st depends of these precedence rules:
+ * 1: program passed with -e
+ * 2: utmp option
+ * 3: SHELL environment variable
+ * 4: value of shell in /etc/passwd
+ * 5: value of shell in config.h
+ */
+static char *shell = "/bin/sh";
+char *utmp = NULL;
+char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
+
+/* identification sequence returned in DA and DECID */
+char *vtiden = "\033[?6c";
+
+/* Kerning / character bounding-box multipliers */
+static float cwscale = 1.0;
+static float chscale = 1.0;
+
+/*
+ * word delimiter string
+ *
+ * More advanced example: " `'\"()[]{}"
+ */
+char *worddelimiters = " ";
+
+/* selection timeouts (in milliseconds) */
+static unsigned int doubleclicktimeout = 300;
+static unsigned int tripleclicktimeout = 600;
+
+/* alt screens */
+int allowaltscreen = 1;
+
+/* frames per second st should at maximum draw to the screen */
+static unsigned int xfps = 120;
+static unsigned int actionfps = 30;
+
+/*
+ * blinking timeout (set to 0 to disable blinking) for the terminal blinking
+ * attribute.
+ */
+static unsigned int blinktimeout = 800;
+
+/*
+ * thickness of underline and bar cursors
+ */
+static unsigned int cursorthickness = 2;
+
+/*
+ * bell volume. It must be a value between -100 and 100. Use 0 for disabling
+ * it
+ */
+static int bellvolume = 0;
+
+/* default TERM value */
+char *termname = "st-256color";
+
+/*
+ * spaces per tab
+ *
+ * When you are changing this value, don't forget to adapt the »it« value in
+ * the st.info and appropriately install the st.info in the environment where
+ * you use this st version.
+ *
+ * it#$tabspaces,
+ *
+ * Secondly make sure your kernel is not expanding tabs. When running `stty
+ * -a` »tab0« should appear. You can tell the terminal to not expand tabs by
+ * running following command:
+ *
+ * stty tabs
+ */
+unsigned int tabspaces = 8;
+
+/* bg opacity */
+//unsigned int alpha = 0xed;
+unsigned int alpha = 0xFF;
+
+static const char *colorname[] = {
+ "#1d2021", /* hard contrast: #1d2021 / soft contrast: #32302f */
+ "#cc241d",
+ "#98971a",
+ "#d79921",
+ "#458588",
+ "#b16286",
+ "#689d6a",
+ "#a89984",
+ "#928374",
+ "#fb4934",
+ "#b8bb26",
+ "#fabd2f",
+ "#83a598",
+ "#d3869b",
+ "#8ec07c",
+ "#ebdbb2",
+ [255] = 0,
+ /* more colors can be added after 255 to use with DefaultXX */
+ "black", /* 256 -> bg */
+ "white", /* 257 -> fg */
+};
+
+
+/*
+ * Default colors (colorname index)
+ * foreground, background, cursor, reverse cursor
+ */
+unsigned int defaultfg = 15;
+unsigned int defaultbg = 0;
+static unsigned int defaultcs = 15;
+static unsigned int defaultrcs = 0;
+
+/*
+ * Default shape of cursor
+ * 2: Block ("â–ˆ")
+ * 4: Underline ("_")
+ * 6: Bar ("|")
+ * 7: Snowman ("☃")
+ */
+static unsigned int cursorshape = 2;
+
+/*
+ * Default columns and rows numbers
+ */
+
+static unsigned int cols = 80;
+static unsigned int rows = 24;
+
+/*
+ * Default colour and shape of the mouse cursor
+ */
+static unsigned int mouseshape = XC_xterm;
+static unsigned int mousefg = 7;
+static unsigned int mousebg = 0;
+
+/*
+ * Color used to display font attributes when fontconfig selected a font which
+ * doesn't match the ones requested.
+ */
+static unsigned int defaultattr = 11;
+
+/*
+ * Xresources preferences to load at startup
+ */
+ResourcePref resources[] = {
+ { "font", STRING, &font },
+ { "color0", STRING, &colorname[0] },
+ { "color1", STRING, &colorname[1] },
+ { "color2", STRING, &colorname[2] },
+ { "color3", STRING, &colorname[3] },
+ { "color4", STRING, &colorname[4] },
+ { "color5", STRING, &colorname[5] },
+ { "color6", STRING, &colorname[6] },
+ { "color7", STRING, &colorname[7] },
+ { "color8", STRING, &colorname[8] },
+ { "color9", STRING, &colorname[9] },
+ { "color10", STRING, &colorname[10] },
+ { "color11", STRING, &colorname[11] },
+ { "color12", STRING, &colorname[12] },
+ { "color13", STRING, &colorname[13] },
+ { "color14", STRING, &colorname[14] },
+ { "color15", STRING, &colorname[15] },
+ { "background", STRING, &colorname[256] },
+ { "foreground", STRING, &colorname[257] },
+ { "termname", STRING, &termname },
+ { "shell", STRING, &shell },
+ { "xfps", INTEGER, &xfps },
+ { "actionfps", INTEGER, &actionfps },
+ { "blinktimeout", INTEGER, &blinktimeout },
+ { "bellvolume", INTEGER, &bellvolume },
+ { "tabspaces", INTEGER, &tabspaces },
+ { "cwscale", FLOAT, &cwscale },
+ { "chscale", FLOAT, &chscale },
+ { "alpha", INTEGER, &alpha },
+};
+
+/*
+ * Internal mouse shortcuts.
+ * Beware that overloading Button1 will disable the selection.
+ */
+static MouseShortcut mshortcuts[] = {
+ /* button mask string */
+ { Button4, XK_NO_MOD, "\031" },
+ { Button5, XK_NO_MOD, "\005" },
+};
+
+/* Internal keyboard shortcuts. */
+#define MODKEY Mod1Mask
+
+MouseKey mkeys[] = {
+ /* button mask function argument */
+ { Button4, ShiftMask, kscrollup, {.i = 1} },
+ { Button5, ShiftMask, kscrolldown, {.i = 1} },
+ { Button4, MODKEY, kscrollup, {.i = 1} },
+ { Button5, MODKEY, kscrolldown, {.i = 1} },
+ { Button4, MODKEY|ShiftMask, zoom, {.f = +1} },
+ { Button5, MODKEY|ShiftMask, zoom, {.f = -1} },
+};
+
+static char *openurlcmd[] = { "/bin/sh", "-c",
+ "xurls | uniq | dmenu -l 10 | xargs -r xdg-open",
+ "externalpipe", NULL };
+
+static Shortcut shortcuts[] = {
+ /* mask keysym function argument */
+ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
+ { ControlMask, XK_Print, toggleprinter, {.i = 0} },
+ { ShiftMask, XK_Print, printscreen, {.i = 0} },
+ { XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
+ { MODKEY|ShiftMask, XK_Prior, zoom, {.f = +1} },
+ { MODKEY|ShiftMask, XK_Next, zoom, {.f = -1} },
+ { MODKEY, XK_Home, zoomreset, {.f = 0} },
+ { ShiftMask, XK_Insert, clippaste, {.i = 0} },
+ { MODKEY, XK_c, clipcopy, {.i = 0} },
+ { MODKEY, XK_v, clippaste, {.i = 0} },
+ { MODKEY, XK_p, selpaste, {.i = 0} },
+ { MODKEY, XK_Num_Lock, numlock, {.i = 0} },
+ { MODKEY, XK_Control_L, iso14755, {.i = 0} },
+ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
+ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
+ { MODKEY, XK_Page_Up, kscrollup, {.i = -1} },
+ { MODKEY, XK_Page_Down, kscrolldown, {.i = -1} },
+ { MODKEY, XK_k, kscrollup, {.i = 1} },
+ { MODKEY, XK_j, kscrolldown, {.i = 1} },
+ { MODKEY, XK_Up, kscrollup, {.i = 1} },
+ { MODKEY, XK_Down, kscrolldown, {.i = 1} },
+ { MODKEY, XK_u, kscrollup, {.i = -1} },
+ { MODKEY, XK_d, kscrolldown, {.i = -1} },
+ { MODKEY|ShiftMask, XK_Up, zoom, {.f = +1} },
+ { MODKEY|ShiftMask, XK_Down, zoom, {.f = -1} },
+ { MODKEY|ShiftMask, XK_K, zoom, {.f = +1} },
+ { MODKEY|ShiftMask, XK_J, zoom, {.f = -1} },
+ { MODKEY|ShiftMask, XK_U, zoom, {.f = +2} },
+ { MODKEY|ShiftMask, XK_D, zoom, {.f = -2} },
+ { MODKEY, XK_l, externalpipe, { .v = openurlcmd } },
+};
+
+/*
+ * Special keys (change & recompile st.info accordingly)
+ *
+ * Mask value:
+ * * Use XK_ANY_MOD to match the key no matter modifiers state
+ * * Use XK_NO_MOD to match the key alone (no modifiers)
+ * appkey value:
+ * * 0: no value
+ * * > 0: keypad application mode enabled
+ * * = 2: term.numlock = 1
+ * * < 0: keypad application mode disabled
+ * appcursor value:
+ * * 0: no value
+ * * > 0: cursor application mode enabled
+ * * < 0: cursor application mode disabled
+ * crlf value
+ * * 0: no value
+ * * > 0: crlf mode is enabled
+ * * < 0: crlf mode is disabled
+ *
+ * Be careful with the order of the definitions because st searches in
+ * this table sequentially, so any XK_ANY_MOD must be in the last
+ * position for a key.
+ */
+
+/*
+ * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
+ * to be mapped below, add them to this array.
+ */
+static KeySym mappedkeys[] = { -1 };
+
+/*
+ * State bits to ignore when matching key or button events. By default,
+ * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
+ */
+static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
+
+/*
+ * Override mouse-select while mask is active (when MODE_MOUSE is set).
+ * Note that if you want to use ShiftMask with selmasks, set this to an other
+ * modifier, set to 0 to not use it.
+ */
+static uint forceselmod = ShiftMask;
+
+/*
+ * This is the huge key array which defines all compatibility to the Linux
+ * world. Please decide about changes wisely.
+ */
+static Key key[] = {
+ /* keysym mask string appkey appcursor */
+ { XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
+ { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
+ { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
+ { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
+ { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
+ { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
+ { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
+ { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
+ { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
+ { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
+ { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
+ { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
+ { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
+ { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
+ { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
+ { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
+ { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
+ { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
+ { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
+ { XK_KP_End, ControlMask, "\033[J", -1, 0},
+ { XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
+ { XK_KP_End, ShiftMask, "\033[K", -1, 0},
+ { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
+ { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
+ { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
+ { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
+ { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
+ { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
+ { XK_KP_Insert, ControlMask, "\033[L", -1, 0},
+ { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
+ { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
+ { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
+ { XK_KP_Delete, ControlMask, "\033[M", -1, 0},
+ { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
+ { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
+ { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
+ { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
+ { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
+ { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
+ { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
+ { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
+ { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
+ { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
+ { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
+ { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
+ { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
+ { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
+ { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
+ { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
+ { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
+ { XK_Up, ShiftMask, "\033[1;2A", 0, 0},
+ { XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
+ { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
+ { XK_Up, ControlMask, "\033[1;5A", 0, 0},
+ { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
+ { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
+ { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
+ { XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
+ { XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
+ { XK_Down, ShiftMask, "\033[1;2B", 0, 0},
+ { XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
+ { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
+ { XK_Down, ControlMask, "\033[1;5B", 0, 0},
+ { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
+ { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
+ { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
+ { XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
+ { XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
+ { XK_Left, ShiftMask, "\033[1;2D", 0, 0},
+ { XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
+ { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
+ { XK_Left, ControlMask, "\033[1;5D", 0, 0},
+ { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
+ { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
+ { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
+ { XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
+ { XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
+ { XK_Right, ShiftMask, "\033[1;2C", 0, 0},
+ { XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
+ { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
+ { XK_Right, ControlMask, "\033[1;5C", 0, 0},
+ { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
+ { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
+ { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
+ { XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
+ { XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
+ { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
+ { XK_Return, Mod1Mask, "\033\r", 0, 0},
+ { XK_Return, XK_ANY_MOD, "\r", 0, 0},
+ { XK_Insert, ShiftMask, "\033[4l", -1, 0},
+ { XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
+ { XK_Insert, ControlMask, "\033[L", -1, 0},
+ { XK_Insert, ControlMask, "\033[2;5~", +1, 0},
+ { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
+ { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
+ { XK_Delete, ControlMask, "\033[M", -1, 0},
+ { XK_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
+ { XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
+ { XK_Home, ShiftMask, "\033[2J", 0, -1},
+ { XK_Home, ShiftMask, "\033[1;2H", 0, +1},
+ { XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
+ { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
+ { XK_End, ControlMask, "\033[J", -1, 0},
+ { XK_End, ControlMask, "\033[1;5F", +1, 0},
+ { XK_End, ShiftMask, "\033[K", -1, 0},
+ { XK_End, ShiftMask, "\033[1;2F", +1, 0},
+ { XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
+ { XK_Prior, ControlMask, "\033[5;5~", 0, 0},
+ { XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
+ { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
+ { XK_Next, ControlMask, "\033[6;5~", 0, 0},
+ { XK_Next, ShiftMask, "\033[6;2~", 0, 0},
+ { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
+ { XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
+ { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
+ { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
+ { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
+ { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
+ { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
+ { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
+ { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
+ { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
+ { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
+ { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
+ { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
+ { XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
+ { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
+ { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
+ { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
+ { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
+ { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
+ { XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
+ { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
+ { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
+ { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
+ { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
+ { XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
+ { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
+ { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
+ { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
+ { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
+ { XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
+ { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
+ { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
+ { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
+ { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
+ { XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
+ { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
+ { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
+ { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
+ { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
+ { XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
+ { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
+ { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
+ { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
+ { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
+ { XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
+ { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
+ { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
+ { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
+ { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
+ { XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
+ { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
+ { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
+ { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
+ { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
+ { XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
+ { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
+ { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
+ { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
+ { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
+ { XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
+ { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
+ { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
+ { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
+ { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
+ { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
+ { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
+ { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
+ { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
+ { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
+ { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
+ { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
+ { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
+ { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
+ { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
+ { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
+ { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
+ { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
+ { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
+ { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
+ { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
+ { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
+ { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
+ { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
+ { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
+ { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
+ { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
+ { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
+};
+
+/*
+ * Selection types' masks.
+ * Use the same masks as usual.
+ * Button1Mask is always unset, to make masks match between ButtonPress.
+ * ButtonRelease and MotionNotify.
+ * If no match is found, regular selection is used.
+ */
+static uint selmasks[] = {
+ [SEL_RECTANGULAR] = Mod1Mask,
+};
+
+/*
+ * Printable characters in ASCII, used to estimate the advance width
+ * of single wide characters.
+ */
+static char ascii_printable[] =
+ " !\"#$%&'()*+,-./0123456789:;<=>?"
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+ "`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/st-master/config.mk b/st-master/config.mk
new file mode 100644
index 0000000..3b00d7e
--- /dev/null
+++ b/st-master/config.mk
@@ -0,0 +1,28 @@
+# st version
+VERSION = 0.8.1
+
+# Customize below to fit your system
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+X11INC = /usr/X11R6/include
+X11LIB = /usr/X11R6/lib
+
+# includes and libs
+INCS = -I$(X11INC) \
+ `pkg-config --cflags fontconfig` \
+ `pkg-config --cflags freetype2`
+LIBS = -L${X11LIB} -lm -lrt -lX11 -lutil -lXft -lXrender \
+ `pkg-config --libs fontconfig` \
+ `pkg-config --libs freetype2`
+
+# flags
+CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
+STCFLAGS = $(INCS) $(CPPFLAGS) $(CFLAGS)
+STLDFLAGS = $(LIBS) $(LDFLAGS)
+
+# compiler and linker
+# CC = c99
+
diff --git a/st-master/st-xresources-20190105-9f80f67.diff b/st-master/st-xresources-20190105-9f80f67.diff
new file mode 100644
index 0000000..7dab9e6
--- /dev/null
+++ b/st-master/st-xresources-20190105-9f80f67.diff
@@ -0,0 +1,185 @@
+From 9f80f67b6238c58d2e3e209ed1c4f872d9ea7ccd Mon Sep 17 00:00:00 2001
+From: Sai Praneeth Reddy <spr.mora04@gmail.com>
+Date: Sat, 5 Jan 2019 18:13:04 +0530
+Subject: [PATCH] Update base patch to 0.8.1
+
+Read borderpx from Xresources too
+---
+ config.def.h | 36 ++++++++++++++++++++++++
+ x.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 110 insertions(+), 4 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 823e79f..f960cac 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -150,6 +150,42 @@ static unsigned int mousebg = 0;
+ */
+ static unsigned int defaultattr = 11;
+
++/*
++ * Xresources preferences to load at startup
++ */
++ResourcePref resources[] = {
++ { "font", STRING, &font },
++ { "color0", STRING, &colorname[0] },
++ { "color1", STRING, &colorname[1] },
++ { "color2", STRING, &colorname[2] },
++ { "color3", STRING, &colorname[3] },
++ { "color4", STRING, &colorname[4] },
++ { "color5", STRING, &colorname[5] },
++ { "color6", STRING, &colorname[6] },
++ { "color7", STRING, &colorname[7] },
++ { "color8", STRING, &colorname[8] },
++ { "color9", STRING, &colorname[9] },
++ { "color10", STRING, &colorname[10] },
++ { "color11", STRING, &colorname[11] },
++ { "color12", STRING, &colorname[12] },
++ { "color13", STRING, &colorname[13] },
++ { "color14", STRING, &colorname[14] },
++ { "color15", STRING, &colorname[15] },
++ { "background", STRING, &colorname[256] },
++ { "foreground", STRING, &colorname[257] },
++ { "cursorColor", STRING, &colorname[258] },
++ { "termname", STRING, &termname },
++ { "shell", STRING, &shell },
++ { "xfps", INTEGER, &xfps },
++ { "actionfps", INTEGER, &actionfps },
++ { "blinktimeout", INTEGER, &blinktimeout },
++ { "bellvolume", INTEGER, &bellvolume },
++ { "tabspaces", INTEGER, &tabspaces },
++ { "borderpx", INTEGER, &borderpx },
++ { "cwscale", FLOAT, &cwscale },
++ { "chscale", FLOAT, &chscale },
++};
++
+ /*
+ * Internal mouse shortcuts.
+ * Beware that overloading Button1 will disable the selection.
+diff --git a/x.c b/x.c
+index 0422421..6e9b061 100644
+--- a/x.c
++++ b/x.c
+@@ -14,6 +14,7 @@
+ #include <X11/keysym.h>
+ #include <X11/Xft/Xft.h>
+ #include <X11/XKBlib.h>
++#include <X11/Xresource.h>
+
+ static char *argv0;
+ #include "arg.h"
+@@ -43,6 +44,19 @@ typedef struct {
+ signed char appcursor; /* application cursor */
+ } Key;
+
++/* Xresources preferences */
++enum resource_type {
++ STRING = 0,
++ INTEGER = 1,
++ FLOAT = 2
++};
++
++typedef struct {
++ char *name;
++ enum resource_type type;
++ void *dst;
++} ResourcePref;
++
+ /* X modifiers */
+ #define XK_ANY_MOD UINT_MAX
+ #define XK_NO_MOD 0
+@@ -783,8 +797,8 @@ xclear(int x1, int y1, int x2, int y2)
+ void
+ xhints(void)
+ {
+- XClassHint class = {opt_name ? opt_name : termname,
+- opt_class ? opt_class : termname};
++ XClassHint class = {opt_name ? opt_name : "st",
++ opt_class ? opt_class : "St"};
+ XWMHints wm = {.flags = InputHint, .input = 1};
+ XSizeHints *sizeh;
+
+@@ -1005,8 +1019,6 @@ xinit(int cols, int rows)
+ pid_t thispid = getpid();
+ XColor xmousefg, xmousebg;
+
+- if (!(xw.dpy = XOpenDisplay(NULL)))
+- die("can't open display\n");
+ xw.scr = XDefaultScreen(xw.dpy);
+ xw.vis = XDefaultVisual(xw.dpy, xw.scr);
+
+@@ -1870,6 +1882,59 @@ run(void)
+ }
+ }
+
++int
++resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
++{
++ char **sdst = dst;
++ int *idst = dst;
++ float *fdst = dst;
++
++ char fullname[256];
++ char fullclass[256];
++ char *type;
++ XrmValue ret;
++
++ snprintf(fullname, sizeof(fullname), "%s.%s",
++ opt_name ? opt_name : "st", name);
++ snprintf(fullclass, sizeof(fullclass), "%s.%s",
++ opt_class ? opt_class : "St", name);
++ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
++
++ XrmGetResource(db, fullname, fullclass, &type, &ret);
++ if (ret.addr == NULL || strncmp("String", type, 64))
++ return 1;
++
++ switch (rtype) {
++ case STRING:
++ *sdst = ret.addr;
++ break;
++ case INTEGER:
++ *idst = strtoul(ret.addr, NULL, 10);
++ break;
++ case FLOAT:
++ *fdst = strtof(ret.addr, NULL);
++ break;
++ }
++ return 0;
++}
++
++void
++config_init(void)
++{
++ char *resm;
++ XrmDatabase db;
++ ResourcePref *p;
++
++ XrmInitialize();
++ resm = XResourceManagerString(xw.dpy);
++ if (!resm)
++ return;
++
++ db = XrmGetStringDatabase(resm);
++ for (p = resources; p < resources + LEN(resources); p++)
++ resource_load(db, p->name, p->type, p->dst);
++}
++
+ void
+ usage(void)
+ {
+@@ -1943,6 +2008,11 @@ run:
+
+ setlocale(LC_CTYPE, "");
+ XSetLocaleModifiers("");
++
++ if(!(xw.dpy = XOpenDisplay(NULL)))
++ die("Can't open display\n");
++
++ config_init();
+ cols = MAX(cols, 1);
+ rows = MAX(rows, 1);
+ tnew(cols, rows);
+--
+2.20.1
+
diff --git a/st-master/st.1 b/st-master/st.1
new file mode 100644
index 0000000..efa32ee
--- /dev/null
+++ b/st-master/st.1
@@ -0,0 +1,188 @@
+.TH ST 1 st\-VERSION
+.SH NAME
+st \- simple terminal (Luke Smith (https://lukesmith.xyz)'s build)
+.SH SYNOPSIS
+.B st
+.RB [ \-aiv ]
+.RB [ \-c
+.IR class ]
+.RB [ \-f
+.IR font ]
+.RB [ \-g
+.IR geometry ]
+.RB [ \-n
+.IR name ]
+.RB [ \-o
+.IR iofile ]
+.RB [ \-T
+.IR title ]
+.RB [ \-t
+.IR title ]
+.RB [ \-l
+.IR line ]
+.RB [ \-w
+.IR windowid ]
+.RB [[ \-e ]
+.IR command
+.RI [ arguments ...]]
+.PP
+.B st
+.RB [ \-aiv ]
+.RB [ \-c
+.IR class ]
+.RB [ \-f
+.IR font ]
+.RB [ \-g
+.IR geometry ]
+.RB [ \-n
+.IR name ]
+.RB [ \-o
+.IR iofile ]
+.RB [ \-T
+.IR title ]
+.RB [ \-t
+.IR title ]
+.RB [ \-w
+.IR windowid ]
+.RB \-l
+.IR line
+.RI [ stty_args ...]
+.SH DESCRIPTION
+.B st
+is a simple terminal emulator.
+.SH OPTIONS
+.TP
+.B \-a
+disable alternate screens in terminal
+.TP
+.BI \-c " class"
+defines the window class (default $TERM).
+.TP
+.BI \-f " font"
+defines the
+.I font
+to use when st is run.
+.TP
+.BI \-g " geometry"
+defines the X11 geometry string.
+The form is [=][<cols>{xX}<rows>][{+-}<xoffset>{+-}<yoffset>]. See
+.BR XParseGeometry (3)
+for further details.
+.TP
+.B \-i
+will fixate the position given with the -g option.
+.TP
+.BI \-n " name"
+defines the window instance name (default $TERM).
+.TP
+.BI \-o " iofile"
+writes all the I/O to
+.I iofile.
+This feature is useful when recording st sessions. A value of "-" means
+standard output.
+.TP
+.BI \-T " title"
+defines the window title (default 'st').
+.TP
+.BI \-t " title"
+defines the window title (default 'st').
+.TP
+.BI \-w " windowid"
+embeds st within the window identified by
+.I windowid
+.TP
+.BI \-l " line"
+use a tty
+.I line
+instead of a pseudo terminal.
+.I line
+should be a (pseudo-)serial device (e.g. /dev/ttyS0 on Linux for serial port
+0).
+When this flag is given
+remaining arguments are used as flags for
+.BR stty(1).
+By default st initializes the serial line to 8 bits, no parity, 1 stop bit
+and a 38400 baud rate. The speed is set by appending it as last argument
+(e.g. 'st -l /dev/ttyS0 115200'). Arguments before the last one are
+.BR stty(1)
+flags. If you want to set odd parity on 115200 baud use for example 'st -l
+/dev/ttyS0 parenb parodd 115200'. Set the number of bits by using for
+example 'st -l /dev/ttyS0 cs7 115200'. See
+.BR stty(1)
+for more arguments and cases.
+.TP
+.B \-v
+prints version information to stderr, then exits.
+.TP
+.BI \-e " command " [ " arguments " "... ]"
+st executes
+.I command
+instead of the shell. If this is used it
+.B must be the last option
+on the command line, as in xterm / rxvt.
+This option is only intended for compatibility,
+and all the remaining arguments are used as a command
+even without it.
+.SH SHORTCUTS
+.TP
+.B Alt-j/k or Alt-Up/Down or Alt-Mouse Wheel
+Scroll up/down one line at a time.
+.TP
+.B Alt-u/d or Alt-Page Up/Page Down
+Scroll up/down one screen at a time.
+.TP
+.B Alt-Shift-k/j or Alt-Shift-Page Up/Page Down or Alt-Shift-Mouse Wheel
+Increase or decrease font size.
+.TP
+.B Alt-Home
+Reset to default font size.
+.TP
+.B Shift-Insert or Alt-v
+Paste from clipboard.
+.TP
+.B Alt-c
+Copy to clipboard.
+.TP
+.B Alt-p
+Paste/input primary selection.
+.TP
+.B Alt-l
+Show dmenu menu of all URLs on screen and choose one to open.
+.I Note:
+Requires xurls installed.
+.TP
+.B Break
+Send a break in the serial line.
+Break key is obtained in PC keyboards
+pressing at the same time control and pause.
+.TP
+.B Ctrl-Print Screen
+Toggle if st should print to the
+.I iofile.
+.TP
+.B Shift-Print Screen
+Print the full screen to the
+.I iofile.
+.TP
+.B Print Screen
+Print the selection to the
+.I iofile.
+.TP
+.B Ctrl-Shift-i
+Launch dmenu to enter a unicode codepoint and send the corresponding glyph
+to st.
+.SH CUSTOMIZATION
+.B st
+can be customized by creating a custom config.h and (re)compiling the source
+code. This keeps it fast, secure and simple.
+.SH AUTHORS
+See the LICENSE file for the authors.
+.SH LICENSE
+See the LICENSE file for the terms of redistribution.
+.SH SEE ALSO
+.BR tabbed (1),
+.BR utmp (1),
+.BR stty (1)
+.SH BUGS
+See the TODO file in the distribution.
+
diff --git a/st-master/st.c b/st-master/st.c
new file mode 100644
index 0000000..9fd04bd
--- /dev/null
+++ b/st-master/st.c
@@ -0,0 +1,2741 @@
+/* See LICENSE for license details. */
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+#include <wchar.h>
+
+#include "st.h"
+#include "win.h"
+
+#if defined(__linux)
+ #include <pty.h>
+#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+ #include <util.h>
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
+ #include <libutil.h>
+#endif
+
+/* Arbitrary sizes */
+#define UTF_INVALID 0xFFFD
+#define UTF_SIZ 4
+#define ESC_BUF_SIZ (128*UTF_SIZ)
+#define ESC_ARG_SIZ 16
+#define STR_BUF_SIZ ESC_BUF_SIZ
+#define STR_ARG_SIZ ESC_ARG_SIZ
+
+/* macros */
+#define IS_SET(flag) ((term.mode & (flag)) != 0)
+#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
+#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177')
+#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
+#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
+#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL)
+
+/* constants */
+#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: </dev/null"
+
+enum term_mode {
+ MODE_WRAP = 1 << 0,
+ MODE_INSERT = 1 << 1,
+ MODE_ALTSCREEN = 1 << 2,
+ MODE_CRLF = 1 << 3,
+ MODE_ECHO = 1 << 4,
+ MODE_PRINT = 1 << 5,
+ MODE_UTF8 = 1 << 6,
+ MODE_SIXEL = 1 << 7,
+};
+
+enum cursor_movement {
+ CURSOR_SAVE,
+ CURSOR_LOAD
+};
+
+enum cursor_state {
+ CURSOR_DEFAULT = 0,
+ CURSOR_WRAPNEXT = 1,
+ CURSOR_ORIGIN = 2
+};
+
+enum charset {
+ CS_GRAPHIC0,
+ CS_GRAPHIC1,
+ CS_UK,
+ CS_USA,
+ CS_MULTI,
+ CS_GER,
+ CS_FIN
+};
+
+enum escape_state {
+ ESC_START = 1,
+ ESC_CSI = 2,
+ ESC_STR = 4, /* OSC, PM, APC */
+ ESC_ALTCHARSET = 8,
+ ESC_STR_END = 16, /* a final string was encountered */
+ ESC_TEST = 32, /* Enter in test mode */
+ ESC_UTF8 = 64,
+ ESC_DCS =128,
+};
+
+typedef struct {
+ Glyph attr; /* current char attributes */
+ int x;
+ int y;
+ char state;
+} TCursor;
+
+typedef struct {
+ int mode;
+ int type;
+ int snap;
+ /*
+ * Selection variables:
+ * nb – normalized coordinates of the beginning of the selection
+ * ne – normalized coordinates of the end of the selection
+ * ob – original coordinates of the beginning of the selection
+ * oe – original coordinates of the end of the selection
+ */
+ struct {
+ int x, y;
+ } nb, ne, ob, oe;
+
+ int alt;
+} Selection;
+
+/* Internal representation of the screen */
+typedef struct {
+ int row; /* nb row */
+ int col; /* nb col */
+ Line *line; /* screen */
+ Line *alt; /* alternate screen */
+ Line hist[HISTSIZE]; /* history buffer */
+ int histi; /* history index */
+ int scr; /* scroll back */
+ int *dirty; /* dirtyness of lines */
+ TCursor c; /* cursor */
+ int ocx; /* old cursor col */
+ int ocy; /* old cursor row */
+ int top; /* top scroll limit */
+ int bot; /* bottom scroll limit */
+ int mode; /* terminal mode flags */
+ int esc; /* escape state flags */
+ char trantbl[4]; /* charset table translation */
+ int charset; /* current charset */
+ int icharset; /* selected charset for sequence */
+ int *tabs;
+} Term;
+
+/* CSI Escape sequence structs */
+/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
+typedef struct {
+ char buf[ESC_BUF_SIZ]; /* raw string */
+ int len; /* raw string length */
+ char priv;
+ int arg[ESC_ARG_SIZ];
+ int narg; /* nb of args */
+ char mode[2];
+} CSIEscape;
+
+/* STR Escape sequence structs */
+/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
+typedef struct {
+ char type; /* ESC type ... */
+ char buf[STR_BUF_SIZ]; /* raw string */
+ int len; /* raw string length */
+ char *args[STR_ARG_SIZ];
+ int narg; /* nb of args */
+} STREscape;
+
+static void execsh(char *, char **);
+static void stty(char **);
+static void sigchld(int);
+static void ttywriteraw(const char *, size_t);
+
+static void csidump(void);
+static void csihandle(void);
+static void csiparse(void);
+static void csireset(void);
+static int eschandle(uchar);
+static void strdump(void);
+static void strhandle(void);
+static void strparse(void);
+static void strreset(void);
+
+static void tprinter(char *, size_t);
+static void tdumpsel(void);
+static void tdumpline(int);
+static void tdump(void);
+static void tclearregion(int, int, int, int);
+static void tcursor(int);
+static void tdeletechar(int);
+static void tdeleteline(int);
+static void tinsertblank(int);
+static void tinsertblankline(int);
+static int tlinelen(int);
+static void tmoveto(int, int);
+static void tmoveato(int, int);
+static void tnewline(int);
+static void tputtab(int);
+static void tputc(Rune);
+static void treset(void);
+static void tscrollup(int, int, int);
+static void tscrolldown(int, int, int);
+static void tsetattr(int *, int);
+static void tsetchar(Rune, Glyph *, int, int);
+static void tsetdirt(int, int);
+static void tsetscroll(int, int);
+static void tswapscreen(void);
+static void tsetmode(int, int, int *, int);
+static int twrite(const char *, int, int);
+static void tfulldirt(void);
+static void tcontrolcode(uchar );
+static void tdectest(char );
+static void tdefutf8(char);
+static int32_t tdefcolor(int *, int *, int);
+static void tdeftran(char);
+static void tstrsequence(uchar);
+
+static void drawregion(int, int, int, int);
+
+static void selnormalize(void);
+static void selscroll(int, int);
+static void selsnap(int *, int *, int);
+
+static size_t utf8decode(const char *, Rune *, size_t);
+static Rune utf8decodebyte(char, size_t *);
+static char utf8encodebyte(Rune, size_t);
+static char *utf8strchr(char *, Rune);
+static size_t utf8validate(Rune *, size_t);
+
+static char *base64dec(const char *);
+static char base64dec_getc(const char **);
+
+static ssize_t xwrite(int, const char *, size_t);
+
+/* Globals */
+static Term term;
+static Selection sel;
+static CSIEscape csiescseq;
+static STREscape strescseq;
+static int iofd = 1;
+static int cmdfd;
+static pid_t pid;
+
+static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
+static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
+static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+
+ssize_t
+xwrite(int fd, const char *s, size_t len)
+{
+ size_t aux = len;
+ ssize_t r;
+
+ while (len > 0) {
+ r = write(fd, s, len);
+ if (r < 0)
+ return r;
+ len -= r;
+ s += r;
+ }
+
+ return aux;
+}
+
+void *
+xmalloc(size_t len)
+{
+ void *p = malloc(len);
+
+ if (!p)
+ die("Out of memory\n");
+
+ return p;
+}
+
+void *
+xrealloc(void *p, size_t len)
+{
+ if ((p = realloc(p, len)) == NULL)
+ die("Out of memory\n");
+
+ return p;
+}
+
+char *
+xstrdup(char *s)
+{
+ if ((s = strdup(s)) == NULL)
+ die("Out of memory\n");
+
+ return s;
+}
+
+size_t
+utf8decode(const char *c, Rune *u, size_t clen)
+{
+ size_t i, j, len, type;
+ Rune udecoded;
+
+ *u = UTF_INVALID;
+ if (!clen)
+ return 0;
+ udecoded = utf8decodebyte(c[0], &len);
+ if (!BETWEEN(len, 1, UTF_SIZ))
+ return 1;
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+ udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
+ if (type != 0)
+ return j;
+ }
+ if (j < len)
+ return 0;
+ *u = udecoded;
+ utf8validate(u, len);
+
+ return len;
+}
+
+Rune
+utf8decodebyte(char c, size_t *i)
+{
+ for (*i = 0; *i < LEN(utfmask); ++(*i))
+ if (((uchar)c & utfmask[*i]) == utfbyte[*i])
+ return (uchar)c & ~utfmask[*i];
+
+ return 0;
+}
+
+size_t
+utf8encode(Rune u, char *c)
+{
+ size_t len, i;
+
+ len = utf8validate(&u, 0);
+ if (len > UTF_SIZ)
+ return 0;
+
+ for (i = len - 1; i != 0; --i) {
+ c[i] = utf8encodebyte(u, 0);
+ u >>= 6;
+ }
+ c[0] = utf8encodebyte(u, len);
+
+ return len;
+}
+
+char
+utf8encodebyte(Rune u, size_t i)
+{
+ return utfbyte[i] | (u & ~utfmask[i]);
+}
+
+char *
+utf8strchr(char *s, Rune u)
+{
+ Rune r;
+ size_t i, j, len;
+
+ len = strlen(s);
+ for (i = 0, j = 0; i < len; i += j) {
+ if (!(j = utf8decode(&s[i], &r, len - i)))
+ break;
+ if (r == u)
+ return &(s[i]);
+ }
+
+ return NULL;
+}
+
+size_t
+utf8validate(Rune *u, size_t i)
+{
+ if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
+ *u = UTF_INVALID;
+ for (i = 1; *u > utfmax[i]; ++i)
+ ;
+
+ return i;
+}
+
+static const char base64_digits[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
+ 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+char
+base64dec_getc(const char **src)
+{
+ while (**src && !isprint(**src)) (*src)++;
+ return *((*src)++);
+}
+
+char *
+base64dec(const char *src)
+{
+ size_t in_len = strlen(src);
+ char *result, *dst;
+
+ if (in_len % 4)
+ in_len += 4 - (in_len % 4);
+ result = dst = xmalloc(in_len / 4 * 3 + 1);
+ while (*src) {
+ int a = base64_digits[(unsigned char) base64dec_getc(&src)];
+ int b = base64_digits[(unsigned char) base64dec_getc(&src)];
+ int c = base64_digits[(unsigned char) base64dec_getc(&src)];
+ int d = base64_digits[(unsigned char) base64dec_getc(&src)];
+
+ *dst++ = (a << 2) | ((b & 0x30) >> 4);
+ if (c == -1)
+ break;
+ *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2);
+ if (d == -1)
+ break;
+ *dst++ = ((c & 0x03) << 6) | d;
+ }
+ *dst = '\0';
+ return result;
+}
+
+void
+selinit(void)
+{
+ sel.mode = SEL_IDLE;
+ sel.snap = 0;
+ sel.ob.x = -1;
+}
+
+int
+tlinelen(int y)
+{
+ int i = term.col;
+
+ if (TLINE(y)[i - 1].mode & ATTR_WRAP)
+ return i;
+
+ while (i > 0 && TLINE(y)[i - 1].u == ' ')
+ --i;
+
+ return i;
+}
+
+void
+selstart(int col, int row, int snap)
+{
+ selclear();
+ sel.mode = SEL_EMPTY;
+ sel.type = SEL_REGULAR;
+ sel.snap = snap;
+ sel.oe.x = sel.ob.x = col;
+ sel.oe.y = sel.ob.y = row;
+ selnormalize();
+
+ if (sel.snap != 0)
+ sel.mode = SEL_READY;
+ tsetdirt(sel.nb.y, sel.ne.y);
+}
+
+void
+selextend(int col, int row, int type, int done)
+{
+ int oldey, oldex, oldsby, oldsey, oldtype;
+
+ if (sel.mode == SEL_IDLE)
+ return;
+ if (done && sel.mode == SEL_EMPTY) {
+ selclear();
+ return;
+ }
+
+ oldey = sel.oe.y;
+ oldex = sel.oe.x;
+ oldsby = sel.nb.y;
+ oldsey = sel.ne.y;
+ oldtype = sel.type;
+
+ sel.alt = IS_SET(MODE_ALTSCREEN);
+ sel.oe.x = col;
+ sel.oe.y = row;
+ selnormalize();
+ sel.type = type;
+
+ if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type)
+ tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
+
+ sel.mode = done ? SEL_IDLE : SEL_READY;
+}
+
+void
+selnormalize(void)
+{
+ int i;
+
+ if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) {
+ sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x;
+ sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x;
+ } else {
+ sel.nb.x = MIN(sel.ob.x, sel.oe.x);
+ sel.ne.x = MAX(sel.ob.x, sel.oe.x);
+ }
+ sel.nb.y = MIN(sel.ob.y, sel.oe.y);
+ sel.ne.y = MAX(sel.ob.y, sel.oe.y);
+
+ selsnap(&sel.nb.x, &sel.nb.y, -1);
+ selsnap(&sel.ne.x, &sel.ne.y, +1);
+
+ /* expand selection over line breaks */
+ if (sel.type == SEL_RECTANGULAR)
+ return;
+ i = tlinelen(sel.nb.y);
+ if (i < sel.nb.x)
+ sel.nb.x = i;
+ if (tlinelen(sel.ne.y) <= sel.ne.x)
+ sel.ne.x = term.col - 1;
+}
+
+int
+selected(int x, int y)
+{
+ if (sel.mode == SEL_EMPTY || sel.ob.x == -1 ||
+ sel.alt != IS_SET(MODE_ALTSCREEN))
+ return 0;
+
+ if (sel.type == SEL_RECTANGULAR)
+ return BETWEEN(y, sel.nb.y, sel.ne.y)
+ && BETWEEN(x, sel.nb.x, sel.ne.x);
+
+ return BETWEEN(y, sel.nb.y, sel.ne.y)
+ && (y != sel.nb.y || x >= sel.nb.x)
+ && (y != sel.ne.y || x <= sel.ne.x);
+}
+
+void
+selsnap(int *x, int *y, int direction)
+{
+ int newx, newy, xt, yt;
+ int delim, prevdelim;
+ Glyph *gp, *prevgp;
+
+ switch (sel.snap) {
+ case SNAP_WORD:
+ /*
+ * Snap around if the word wraps around at the end or
+ * beginning of a line.
+ */
+ prevgp = &TLINE(*y)[*x];
+ prevdelim = ISDELIM(prevgp->u);
+ for (;;) {
+ newx = *x + direction;
+ newy = *y;
+ if (!BETWEEN(newx, 0, term.col - 1)) {
+ newy += direction;
+ newx = (newx + term.col) % term.col;
+ if (!BETWEEN(newy, 0, term.row - 1))
+ break;
+
+ if (direction > 0)
+ yt = *y, xt = *x;
+ else
+ yt = newy, xt = newx;
+ if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
+ break;
+ }
+
+ if (newx >= tlinelen(newy))
+ break;
+
+ gp = &TLINE(newy)[newx];
+ delim = ISDELIM(gp->u);
+ if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
+ || (delim && gp->u != prevgp->u)))
+ break;
+
+ *x = newx;
+ *y = newy;
+ prevgp = gp;
+ prevdelim = delim;
+ }
+ break;
+ case SNAP_LINE:
+ /*
+ * Snap around if the the previous line or the current one
+ * has set ATTR_WRAP at its end. Then the whole next or
+ * previous line will be selected.
+ */
+ *x = (direction < 0) ? 0 : term.col - 1;
+ if (direction < 0) {
+ for (; *y > 0; *y += direction) {
+ if (!(TLINE(*y-1)[term.col-1].mode
+ & ATTR_WRAP)) {
+ break;
+ }
+ }
+ } else if (direction > 0) {
+ for (; *y < term.row-1; *y += direction) {
+ if (!(TLINE(*y)[term.col-1].mode
+ & ATTR_WRAP)) {
+ break;
+ }
+ }
+ }
+ break;
+ }
+}
+
+char *
+getsel(void)
+{
+ char *str, *ptr;
+ int y, bufsize, lastx, linelen;
+ Glyph *gp, *last;
+
+ if (sel.ob.x == -1)
+ return NULL;
+
+ bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ;
+ ptr = str = xmalloc(bufsize);
+
+ /* append every set & selected glyph to the selection */
+ for (y = sel.nb.y; y <= sel.ne.y; y++) {
+ if ((linelen = tlinelen(y)) == 0) {
+ *ptr++ = '\n';
+ continue;
+ }
+
+ if (sel.type == SEL_RECTANGULAR) {
+ gp = &TLINE(y)[sel.nb.x];
+ lastx = sel.ne.x;
+ } else {
+ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
+ lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
+ }
+ last = &TLINE(y)[MIN(lastx, linelen-1)];
+ while (last >= gp && last->u == ' ')
+ --last;
+
+ for ( ; gp <= last; ++gp) {
+ if (gp->mode & ATTR_WDUMMY)
+ continue;
+
+ ptr += utf8encode(gp->u, ptr);
+ }
+
+ /*
+ * Copy and pasting of line endings is inconsistent
+ * in the inconsistent terminal and GUI world.
+ * The best solution seems like to produce '\n' when
+ * something is copied from st and convert '\n' to
+ * '\r', when something to be pasted is received by
+ * st.
+ * FIXME: Fix the computer world.
+ */
+ if ((y < sel.ne.y || lastx >= linelen) && !(last->mode & ATTR_WRAP))
+ *ptr++ = '\n';
+ }
+ *ptr = 0;
+ return str;
+}
+
+void
+selclear(void)
+{
+ if (sel.ob.x == -1)
+ return;
+ sel.mode = SEL_IDLE;
+ sel.ob.x = -1;
+ tsetdirt(sel.nb.y, sel.ne.y);
+}
+
+void
+die(const char *errstr, ...)
+{
+ va_list ap;
+
+ va_start(ap, errstr);
+ vfprintf(stderr, errstr, ap);
+ va_end(ap);
+ exit(1);
+}
+
+void
+execsh(char *cmd, char **args)
+{
+ char *sh, *prog;
+ const struct passwd *pw;
+
+ errno = 0;
+ if ((pw = getpwuid(getuid())) == NULL) {
+ if (errno)
+ die("getpwuid:%s\n", strerror(errno));
+ else
+ die("who are you?\n");
+ }
+
+ if ((sh = getenv("SHELL")) == NULL)
+ sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd;
+
+ if (args)
+ prog = args[0];
+ else if (utmp)
+ prog = utmp;
+ else
+ prog = sh;
+ DEFAULT(args, ((char *[]) {prog, NULL}));
+
+ unsetenv("COLUMNS");
+ unsetenv("LINES");
+ unsetenv("TERMCAP");
+ setenv("LOGNAME", pw->pw_name, 1);
+ setenv("USER", pw->pw_name, 1);
+ setenv("SHELL", sh, 1);
+ setenv("HOME", pw->pw_dir, 1);
+ setenv("TERM", termname, 1);
+
+ signal(SIGCHLD, SIG_DFL);
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGALRM, SIG_DFL);
+
+ execvp(prog, args);
+ _exit(1);
+}
+
+void
+sigchld(int a)
+{
+ int stat;
+ pid_t p;
+
+ if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
+ die("Waiting for pid %hd failed: %s\n", pid, strerror(errno));
+
+ if (pid != p)
+ return;
+
+ if (WIFEXITED(stat) && WEXITSTATUS(stat))
+ die("child exited with status %d\n", WEXITSTATUS(stat));
+ else if (WIFSIGNALED(stat))
+ die("child terminated due to signal %d\n", WTERMSIG(stat));
+ exit(0);
+}
+
+void
+stty(char **args)
+{
+ char cmd[_POSIX_ARG_MAX], **p, *q, *s;
+ size_t n, siz;
+
+ if ((n = strlen(stty_args)) > sizeof(cmd)-1)
+ die("incorrect stty parameters\n");
+ memcpy(cmd, stty_args, n);
+ q = cmd + n;
+ siz = sizeof(cmd) - n;
+ for (p = args; p && (s = *p); ++p) {
+ if ((n = strlen(s)) > siz-1)
+ die("stty parameter length too long\n");
+ *q++ = ' ';
+ memcpy(q, s, n);
+ q += n;
+ siz -= n + 1;
+ }
+ *q = '\0';
+ if (system(cmd) != 0)
+ perror("Couldn't call stty");
+}
+
+int
+ttynew(char *line, char *cmd, char *out, char **args)
+{
+ int m, s;
+
+ if (out) {
+ term.mode |= MODE_PRINT;
+ iofd = (!strcmp(out, "-")) ?
+ 1 : open(out, O_WRONLY | O_CREAT, 0666);
+ if (iofd < 0) {
+ fprintf(stderr, "Error opening %s:%s\n",
+ out, strerror(errno));
+ }
+ }
+
+ if (line) {
+ if ((cmdfd = open(line, O_RDWR)) < 0)
+ die("open line failed: %s\n", strerror(errno));
+ dup2(cmdfd, 0);
+ stty(args);
+ return cmdfd;
+ }
+
+ /* seems to work fine on linux, openbsd and freebsd */
+ if (openpty(&m, &s, NULL, NULL, NULL) < 0)
+ die("openpty failed: %s\n", strerror(errno));
+
+ switch (pid = fork()) {
+ case -1:
+ die("fork failed\n");
+ break;
+ case 0:
+ close(iofd);
+ setsid(); /* create a new process group */
+ dup2(s, 0);
+ dup2(s, 1);
+ dup2(s, 2);
+ if (ioctl(s, TIOCSCTTY, NULL) < 0)
+ die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
+ close(s);
+ close(m);
+ execsh(cmd, args);
+ break;
+ default:
+ close(s);
+ cmdfd = m;
+ signal(SIGCHLD, sigchld);
+ break;
+ }
+ return cmdfd;
+}
+
+size_t
+ttyread(void)
+{
+ static char buf[BUFSIZ];
+ static int buflen = 0;
+ int written;
+ int ret;
+
+ /* append read bytes to unprocessed bytes */
+ if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
+ die("Couldn't read from shell: %s\n", strerror(errno));
+ buflen += ret;
+
+ written = twrite(buf, buflen, 0);
+ buflen -= written;
+ /* keep any uncomplete utf8 char for the next call */
+ if (buflen > 0)
+ memmove(buf, buf + written, buflen);
+
+ if (term.scr > 0 && term.scr < HISTSIZE-1)
+ term.scr++;
+
+ return ret;
+}
+
+void
+ttywrite(const char *s, size_t n, int may_echo)
+{
+ const char *next;
+ Arg arg = (Arg) { .i = term.scr };
+
+ kscrolldown(&arg);
+
+ if (may_echo && IS_SET(MODE_ECHO))
+ twrite(s, n, 1);
+
+ if (!IS_SET(MODE_CRLF)) {
+ ttywriteraw(s, n);
+ return;
+ }
+
+ /* This is similar to how the kernel handles ONLCR for ttys */
+ while (n > 0) {
+ if (*s == '\r') {
+ next = s + 1;
+ ttywriteraw("\r\n", 2);
+ } else {
+ next = memchr(s, '\r', n);
+ DEFAULT(next, s + n);
+ ttywriteraw(s, next - s);
+ }
+ n -= next - s;
+ s = next;
+ }
+}
+
+void
+ttywriteraw(const char *s, size_t n)
+{
+ fd_set wfd, rfd;
+ ssize_t r;
+ size_t lim = 256;
+
+ /*
+ * Remember that we are using a pty, which might be a modem line.
+ * Writing too much will clog the line. That's why we are doing this
+ * dance.
+ * FIXME: Migrate the world to Plan 9.
+ */
+ while (n > 0) {
+ FD_ZERO(&wfd);
+ FD_ZERO(&rfd);
+ FD_SET(cmdfd, &wfd);
+ FD_SET(cmdfd, &rfd);
+
+ /* Check if we can write. */
+ if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
+ if (errno == EINTR)
+ continue;
+ die("select failed: %s\n", strerror(errno));
+ }
+ if (FD_ISSET(cmdfd, &wfd)) {
+ /*
+ * Only write the bytes written by ttywrite() or the
+ * default of 256. This seems to be a reasonable value
+ * for a serial line. Bigger values might clog the I/O.
+ */
+ if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0)
+ goto write_error;
+ if (r < n) {
+ /*
+ * We weren't able to write out everything.
+ * This means the buffer is getting full
+ * again. Empty it.
+ */
+ if (n < lim)
+ lim = ttyread();
+ n -= r;
+ s += r;
+ } else {
+ /* All bytes have been written. */
+ break;
+ }
+ }
+ if (FD_ISSET(cmdfd, &rfd))
+ lim = ttyread();
+ }
+ return;
+
+write_error:
+ die("write error on tty: %s\n", strerror(errno));
+}
+
+void
+ttyresize(int tw, int th)
+{
+ struct winsize w;
+
+ w.ws_row = term.row;
+ w.ws_col = term.col;
+ w.ws_xpixel = tw;
+ w.ws_ypixel = th;
+ if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0)
+ fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno));
+}
+
+void
+ttyhangup()
+{
+ /* Send SIGHUP to shell */
+ kill(pid, SIGHUP);
+}
+
+int
+tattrset(int attr)
+{
+ int i, j;
+
+ for (i = 0; i < term.row-1; i++) {
+ for (j = 0; j < term.col-1; j++) {
+ if (term.line[i][j].mode & attr)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void
+tsetdirt(int top, int bot)
+{
+ int i;
+
+ LIMIT(top, 0, term.row-1);
+ LIMIT(bot, 0, term.row-1);
+
+ for (i = top; i <= bot; i++)
+ term.dirty[i] = 1;
+}
+
+void
+tsetdirtattr(int attr)
+{
+ int i, j;
+
+ for (i = 0; i < term.row-1; i++) {
+ for (j = 0; j < term.col-1; j++) {
+ if (term.line[i][j].mode & attr) {
+ tsetdirt(i, i);
+ break;
+ }
+ }
+ }
+}
+
+void
+tfulldirt(void)
+{
+ tsetdirt(0, term.row-1);
+}
+
+void
+tcursor(int mode)
+{
+ static TCursor c[2];
+ int alt = IS_SET(MODE_ALTSCREEN);
+
+ if (mode == CURSOR_SAVE) {
+ c[alt] = term.c;
+ } else if (mode == CURSOR_LOAD) {
+ term.c = c[alt];
+ tmoveto(c[alt].x, c[alt].y);
+ }
+}
+
+void
+treset(void)
+{
+ uint i;
+
+ term.c = (TCursor){{
+ .mode = ATTR_NULL,
+ .fg = defaultfg,
+ .bg = defaultbg
+ }, .x = 0, .y = 0, .state = CURSOR_DEFAULT};
+
+ memset(term.tabs, 0, term.col * sizeof(*term.tabs));
+ for (i = tabspaces; i < term.col; i += tabspaces)
+ term.tabs[i] = 1;
+ term.top = 0;
+ term.bot = term.row - 1;
+ term.mode = MODE_WRAP|MODE_UTF8;
+ memset(term.trantbl, CS_USA, sizeof(term.trantbl));
+ term.charset = 0;
+
+ for (i = 0; i < 2; i++) {
+ tmoveto(0, 0);
+ tcursor(CURSOR_SAVE);
+ tclearregion(0, 0, term.col-1, term.row-1);
+ tswapscreen();
+ }
+}
+
+void
+tnew(int col, int row)
+{
+ term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } };
+ tresize(col, row);
+ treset();
+}
+
+void
+tswapscreen(void)
+{
+ Line *tmp = term.line;
+
+ term.line = term.alt;
+ term.alt = tmp;
+ term.mode ^= MODE_ALTSCREEN;
+ tfulldirt();
+}
+
+void
+kscrolldown(const Arg* a)
+{
+ int n = a->i;
+
+ if (n < 0)
+ n = term.row + n;
+
+ if (n > term.scr)
+ n = term.scr;
+
+ if (term.scr > 0) {
+ term.scr -= n;
+ selscroll(0, -n);
+ tfulldirt();
+ }
+}
+
+void
+kscrollup(const Arg* a)
+{
+ int n = a->i;
+
+ if (n < 0)
+ n = term.row + n;
+
+ if (term.scr <= HISTSIZE-n) {
+ term.scr += n;
+ selscroll(0, n);
+ tfulldirt();
+ }
+}
+
+
+void
+tscrolldown(int orig, int n, int copyhist)
+{
+ int i;
+ Line temp;
+
+ LIMIT(n, 0, term.bot-orig+1);
+
+ if (copyhist) {
+ term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
+ temp = term.hist[term.histi];
+ term.hist[term.histi] = term.line[term.bot];
+ term.line[term.bot] = temp;
+ }
+
+ tsetdirt(orig, term.bot-n);
+ tclearregion(0, term.bot-n+1, term.col-1, term.bot);
+
+ for (i = term.bot; i >= orig+n; i--) {
+ temp = term.line[i];
+ term.line[i] = term.line[i-n];
+ term.line[i-n] = temp;
+ }
+
+ selscroll(orig, n);
+}
+
+void
+tscrollup(int orig, int n, int copyhist)
+{
+ int i;
+ Line temp;
+
+ LIMIT(n, 0, term.bot-orig+1);
+
+ if (copyhist) {
+ term.histi = (term.histi + 1) % HISTSIZE;
+ temp = term.hist[term.histi];
+ term.hist[term.histi] = term.line[orig];
+ term.line[orig] = temp;
+ }
+
+ tclearregion(0, orig, term.col-1, orig+n-1);
+ tsetdirt(orig+n, term.bot);
+
+ for (i = orig; i <= term.bot-n; i++) {
+ temp = term.line[i];
+ term.line[i] = term.line[i+n];
+ term.line[i+n] = temp;
+ }
+
+ selscroll(orig, -n);
+}
+
+void
+selscroll(int orig, int n)
+{
+ if (sel.ob.x == -1)
+ return;
+
+ if (BETWEEN(sel.ob.y, orig, term.bot) || BETWEEN(sel.oe.y, orig, term.bot)) {
+ if ((sel.ob.y += n) > term.bot || (sel.oe.y += n) < term.top) {
+ selclear();
+ return;
+ }
+ if (sel.type == SEL_RECTANGULAR) {
+ if (sel.ob.y < term.top)
+ sel.ob.y = term.top;
+ if (sel.oe.y > term.bot)
+ sel.oe.y = term.bot;
+ } else {
+ if (sel.ob.y < term.top) {
+ sel.ob.y = term.top;
+ sel.ob.x = 0;
+ }
+ if (sel.oe.y > term.bot) {
+ sel.oe.y = term.bot;
+ sel.oe.x = term.col;
+ }
+ }
+ selnormalize();
+ }
+}
+
+void
+tnewline(int first_col)
+{
+ int y = term.c.y;
+
+ if (y == term.bot) {
+ tscrollup(term.top, 1, 1);
+ } else {
+ y++;
+ }
+ tmoveto(first_col ? 0 : term.c.x, y);
+}
+
+void
+csiparse(void)
+{
+ char *p = csiescseq.buf, *np;
+ long int v;
+
+ csiescseq.narg = 0;
+ if (*p == '?') {
+ csiescseq.priv = 1;
+ p++;
+ }
+
+ csiescseq.buf[csiescseq.len] = '\0';
+ while (p < csiescseq.buf+csiescseq.len) {
+ np = NULL;
+ v = strtol(p, &np, 10);
+ if (np == p)
+ v = 0;
+ if (v == LONG_MAX || v == LONG_MIN)
+ v = -1;
+ csiescseq.arg[csiescseq.narg++] = v;
+ p = np;
+ if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
+ break;
+ p++;
+ }
+ csiescseq.mode[0] = *p++;
+ csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0';
+}
+
+/* for absolute user moves, when decom is set */
+void
+tmoveato(int x, int y)
+{
+ tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0));
+}
+
+void
+tmoveto(int x, int y)
+{
+ int miny, maxy;
+
+ if (term.c.state & CURSOR_ORIGIN) {
+ miny = term.top;
+ maxy = term.bot;
+ } else {
+ miny = 0;
+ maxy = term.row - 1;
+ }
+ term.c.state &= ~CURSOR_WRAPNEXT;
+ term.c.x = LIMIT(x, 0, term.col-1);
+ term.c.y = LIMIT(y, miny, maxy);
+}
+
+void
+tsetchar(Rune u, Glyph *attr, int x, int y)
+{
+ static char *vt100_0[62] = { /* 0x41 - 0x7e */
+ "↑", "↓", "→", "â†", "â–ˆ", "â–š", "☃", /* A - G */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
+ 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */
+ "â—†", "â–’", "â‰", "âŒ", "â", "âŠ", "°", "±", /* ` - g */
+ "â¤", "â‹", "┘", "â”", "┌", "â””", "┼", "⎺", /* h - o */
+ "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */
+ "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */
+ };
+
+ /*
+ * The table is proudly stolen from rxvt.
+ */
+ if (term.trantbl[term.charset] == CS_GRAPHIC0 &&
+ BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41])
+ utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ);
+
+ if (term.line[y][x].mode & ATTR_WIDE) {
+ if (x+1 < term.col) {
+ term.line[y][x+1].u = ' ';
+ term.line[y][x+1].mode &= ~ATTR_WDUMMY;
+ }
+ } else if (term.line[y][x].mode & ATTR_WDUMMY) {
+ term.line[y][x-1].u = ' ';
+ term.line[y][x-1].mode &= ~ATTR_WIDE;
+ }
+
+ term.dirty[y] = 1;
+ term.line[y][x] = *attr;
+ term.line[y][x].u = u;
+}
+
+void
+tclearregion(int x1, int y1, int x2, int y2)
+{
+ int x, y, temp;
+ Glyph *gp;
+
+ if (x1 > x2)
+ temp = x1, x1 = x2, x2 = temp;
+ if (y1 > y2)
+ temp = y1, y1 = y2, y2 = temp;
+
+ LIMIT(x1, 0, term.col-1);
+ LIMIT(x2, 0, term.col-1);
+ LIMIT(y1, 0, term.row-1);
+ LIMIT(y2, 0, term.row-1);
+
+ for (y = y1; y <= y2; y++) {
+ term.dirty[y] = 1;
+ for (x = x1; x <= x2; x++) {
+ gp = &term.line[y][x];
+ if (selected(x, y))
+ selclear();
+ gp->fg = term.c.attr.fg;
+ gp->bg = term.c.attr.bg;
+ gp->mode = 0;
+ gp->u = ' ';
+ }
+ }
+}
+
+void
+tdeletechar(int n)
+{
+ int dst, src, size;
+ Glyph *line;
+
+ LIMIT(n, 0, term.col - term.c.x);
+
+ dst = term.c.x;
+ src = term.c.x + n;
+ size = term.col - src;
+ line = term.line[term.c.y];
+
+ memmove(&line[dst], &line[src], size * sizeof(Glyph));
+ tclearregion(term.col-n, term.c.y, term.col-1, term.c.y);
+}
+
+void
+tinsertblank(int n)
+{
+ int dst, src, size;
+ Glyph *line;
+
+ LIMIT(n, 0, term.col - term.c.x);
+
+ dst = term.c.x + n;
+ src = term.c.x;
+ size = term.col - dst;
+ line = term.line[term.c.y];
+
+ memmove(&line[dst], &line[src], size * sizeof(Glyph));
+ tclearregion(src, term.c.y, dst - 1, term.c.y);
+}
+
+void
+tinsertblankline(int n)
+{
+ if (BETWEEN(term.c.y, term.top, term.bot))
+ tscrolldown(term.c.y, n, 0);
+}
+
+void
+tdeleteline(int n)
+{
+ if (BETWEEN(term.c.y, term.top, term.bot))
+ tscrollup(term.c.y, n, 0);
+}
+
+int32_t
+tdefcolor(int *attr, int *npar, int l)
+{
+ int32_t idx = -1;
+ uint r, g, b;
+
+ switch (attr[*npar + 1]) {
+ case 2: /* direct color in RGB space */
+ if (*npar + 4 >= l) {
+ fprintf(stderr,
+ "erresc(38): Incorrect number of parameters (%d)\n",
+ *npar);
+ break;
+ }
+ r = attr[*npar + 2];
+ g = attr[*npar + 3];
+ b = attr[*npar + 4];
+ *npar += 4;
+ if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255))
+ fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n",
+ r, g, b);
+ else
+ idx = TRUECOLOR(r, g, b);
+ break;
+ case 5: /* indexed color */
+ if (*npar + 2 >= l) {
+ fprintf(stderr,
+ "erresc(38): Incorrect number of parameters (%d)\n",
+ *npar);
+ break;
+ }
+ *npar += 2;
+ if (!BETWEEN(attr[*npar], 0, 255))
+ fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]);
+ else
+ idx = attr[*npar];
+ break;
+ case 0: /* implemented defined (only foreground) */
+ case 1: /* transparent */
+ case 3: /* direct color in CMY space */
+ case 4: /* direct color in CMYK space */
+ default:
+ fprintf(stderr,
+ "erresc(38): gfx attr %d unknown\n", attr[*npar]);
+ break;
+ }
+
+ return idx;
+}
+
+void
+tsetattr(int *attr, int l)
+{
+ int i;
+ int32_t idx;
+
+ for (i = 0; i < l; i++) {
+ switch (attr[i]) {
+ case 0:
+ term.c.attr.mode &= ~(
+ ATTR_BOLD |
+ ATTR_FAINT |
+ ATTR_ITALIC |
+ ATTR_UNDERLINE |
+ ATTR_BLINK |
+ ATTR_REVERSE |
+ ATTR_INVISIBLE |
+ ATTR_STRUCK );
+ term.c.attr.fg = defaultfg;
+ term.c.attr.bg = defaultbg;
+ break;
+ case 1:
+ term.c.attr.mode |= ATTR_BOLD;
+ break;
+ case 2:
+ term.c.attr.mode |= ATTR_FAINT;
+ break;
+ case 3:
+ term.c.attr.mode |= ATTR_ITALIC;
+ break;
+ case 4:
+ term.c.attr.mode |= ATTR_UNDERLINE;
+ break;
+ case 5: /* slow blink */
+ /* FALLTHROUGH */
+ case 6: /* rapid blink */
+ term.c.attr.mode |= ATTR_BLINK;
+ break;
+ case 7:
+ term.c.attr.mode |= ATTR_REVERSE;
+ break;
+ case 8:
+ term.c.attr.mode |= ATTR_INVISIBLE;
+ break;
+ case 9:
+ term.c.attr.mode |= ATTR_STRUCK;
+ break;
+ case 22:
+ term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT);
+ break;
+ case 23:
+ term.c.attr.mode &= ~ATTR_ITALIC;
+ break;
+ case 24:
+ term.c.attr.mode &= ~ATTR_UNDERLINE;
+ break;
+ case 25:
+ term.c.attr.mode &= ~ATTR_BLINK;
+ break;
+ case 27:
+ term.c.attr.mode &= ~ATTR_REVERSE;
+ break;
+ case 28:
+ term.c.attr.mode &= ~ATTR_INVISIBLE;
+ break;
+ case 29:
+ term.c.attr.mode &= ~ATTR_STRUCK;
+ break;
+ case 38:
+ if ((idx = tdefcolor(attr, &i, l)) >= 0)
+ term.c.attr.fg = idx;
+ break;
+ case 39:
+ term.c.attr.fg = defaultfg;
+ break;
+ case 48:
+ if ((idx = tdefcolor(attr, &i, l)) >= 0)
+ term.c.attr.bg = idx;
+ break;
+ case 49:
+ term.c.attr.bg = defaultbg;
+ break;
+ default:
+ if (BETWEEN(attr[i], 30, 37)) {
+ term.c.attr.fg = attr[i] - 30;
+ } else if (BETWEEN(attr[i], 40, 47)) {
+ term.c.attr.bg = attr[i] - 40;
+ } else if (BETWEEN(attr[i], 90, 97)) {
+ term.c.attr.fg = attr[i] - 90 + 8;
+ } else if (BETWEEN(attr[i], 100, 107)) {
+ term.c.attr.bg = attr[i] - 100 + 8;
+ } else {
+ fprintf(stderr,
+ "erresc(default): gfx attr %d unknown\n",
+ attr[i]);
+ csidump();
+ }
+ break;
+ }
+ }
+}
+
+void
+tsetscroll(int t, int b)
+{
+ int temp;
+
+ LIMIT(t, 0, term.row-1);
+ LIMIT(b, 0, term.row-1);
+ if (t > b) {
+ temp = t;
+ t = b;
+ b = temp;
+ }
+ term.top = t;
+ term.bot = b;
+}
+
+void
+tsetmode(int priv, int set, int *args, int narg)
+{
+ int alt, *lim;
+
+ for (lim = args + narg; args < lim; ++args) {
+ if (priv) {
+ switch (*args) {
+ case 1: /* DECCKM -- Cursor key */
+ xsetmode(set, MODE_APPCURSOR);
+ break;
+ case 5: /* DECSCNM -- Reverse video */
+ xsetmode(set, MODE_REVERSE);
+ break;
+ case 6: /* DECOM -- Origin */
+ MODBIT(term.c.state, set, CURSOR_ORIGIN);
+ tmoveato(0, 0);
+ break;
+ case 7: /* DECAWM -- Auto wrap */
+ MODBIT(term.mode, set, MODE_WRAP);
+ break;
+ case 0: /* Error (IGNORED) */
+ case 2: /* DECANM -- ANSI/VT52 (IGNORED) */
+ case 3: /* DECCOLM -- Column (IGNORED) */
+ case 4: /* DECSCLM -- Scroll (IGNORED) */
+ case 8: /* DECARM -- Auto repeat (IGNORED) */
+ case 18: /* DECPFF -- Printer feed (IGNORED) */
+ case 19: /* DECPEX -- Printer extent (IGNORED) */
+ case 42: /* DECNRCM -- National characters (IGNORED) */
+ case 12: /* att610 -- Start blinking cursor (IGNORED) */
+ break;
+ case 25: /* DECTCEM -- Text Cursor Enable Mode */
+ xsetmode(!set, MODE_HIDE);
+ break;
+ case 9: /* X10 mouse compatibility mode */
+ xsetpointermotion(0);
+ xsetmode(0, MODE_MOUSE);
+ xsetmode(set, MODE_MOUSEX10);
+ break;
+ case 1000: /* 1000: report button press */
+ xsetpointermotion(0);
+ xsetmode(0, MODE_MOUSE);
+ xsetmode(set, MODE_MOUSEBTN);
+ break;
+ case 1002: /* 1002: report motion on button press */
+ xsetpointermotion(0);
+ xsetmode(0, MODE_MOUSE);
+ xsetmode(set, MODE_MOUSEMOTION);
+ break;
+ case 1003: /* 1003: enable all mouse motions */
+ xsetpointermotion(set);
+ xsetmode(0, MODE_MOUSE);
+ xsetmode(set, MODE_MOUSEMANY);
+ break;
+ case 1004: /* 1004: send focus events to tty */
+ xsetmode(set, MODE_FOCUS);
+ break;
+ case 1006: /* 1006: extended reporting mode */
+ xsetmode(set, MODE_MOUSESGR);
+ break;
+ case 1034:
+ xsetmode(set, MODE_8BIT);
+ break;
+ case 1049: /* swap screen & set/restore cursor as xterm */
+ if (!allowaltscreen)
+ break;
+ tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
+ /* FALLTHROUGH */
+ case 47: /* swap screen */
+ case 1047:
+ if (!allowaltscreen)
+ break;
+ alt = IS_SET(MODE_ALTSCREEN);
+ if (alt) {
+ tclearregion(0, 0, term.col-1,
+ term.row-1);
+ }
+ if (set ^ alt) /* set is always 1 or 0 */
+ tswapscreen();
+ if (*args != 1049)
+ break;
+ /* FALLTHROUGH */
+ case 1048:
+ tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
+ break;
+ case 2004: /* 2004: bracketed paste mode */
+ xsetmode(set, MODE_BRCKTPASTE);
+ break;
+ /* Not implemented mouse modes. See comments there. */
+ case 1001: /* mouse highlight mode; can hang the
+ terminal by design when implemented. */
+ case 1005: /* UTF-8 mouse mode; will confuse
+ applications not supporting UTF-8
+ and luit. */
+ case 1015: /* urxvt mangled mouse mode; incompatible
+ and can be mistaken for other control
+ codes. */
+ default:
+ fprintf(stderr,
+ "erresc: unknown private set/reset mode %d\n",
+ *args);
+ break;
+ }
+ } else {
+ switch (*args) {
+ case 0: /* Error (IGNORED) */
+ break;
+ case 2:
+ xsetmode(set, MODE_KBDLOCK);
+ break;
+ case 4: /* IRM -- Insertion-replacement */
+ MODBIT(term.mode, set, MODE_INSERT);
+ break;
+ case 12: /* SRM -- Send/Receive */
+ MODBIT(term.mode, !set, MODE_ECHO);
+ break;
+ case 20: /* LNM -- Linefeed/new line */
+ MODBIT(term.mode, set, MODE_CRLF);
+ break;
+ default:
+ fprintf(stderr,
+ "erresc: unknown set/reset mode %d\n",
+ *args);
+ break;
+ }
+ }
+ }
+}
+
+void
+csihandle(void)
+{
+ char buf[40];
+ int len;
+
+ switch (csiescseq.mode[0]) {
+ default:
+ unknown:
+ fprintf(stderr, "erresc: unknown csi ");
+ csidump();
+ /* die(""); */
+ break;
+ case '@': /* ICH -- Insert <n> blank char */
+ DEFAULT(csiescseq.arg[0], 1);
+ tinsertblank(csiescseq.arg[0]);
+ break;
+ case 'A': /* CUU -- Cursor <n> Up */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(term.c.x, term.c.y-csiescseq.arg[0]);
+ break;
+ case 'B': /* CUD -- Cursor <n> Down */
+ case 'e': /* VPR --Cursor <n> Down */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(term.c.x, term.c.y+csiescseq.arg[0]);
+ break;
+ case 'i': /* MC -- Media Copy */
+ switch (csiescseq.arg[0]) {
+ case 0:
+ tdump();
+ break;
+ case 1:
+ tdumpline(term.c.y);
+ break;
+ case 2:
+ tdumpsel();
+ break;
+ case 4:
+ term.mode &= ~MODE_PRINT;
+ break;
+ case 5:
+ term.mode |= MODE_PRINT;
+ break;
+ }
+ break;
+ case 'c': /* DA -- Device Attributes */
+ if (csiescseq.arg[0] == 0)
+ ttywrite(vtiden, strlen(vtiden), 0);
+ break;
+ case 'C': /* CUF -- Cursor <n> Forward */
+ case 'a': /* HPR -- Cursor <n> Forward */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(term.c.x+csiescseq.arg[0], term.c.y);
+ break;
+ case 'D': /* CUB -- Cursor <n> Backward */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(term.c.x-csiescseq.arg[0], term.c.y);
+ break;
+ case 'E': /* CNL -- Cursor <n> Down and first col */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(0, term.c.y+csiescseq.arg[0]);
+ break;
+ case 'F': /* CPL -- Cursor <n> Up and first col */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(0, term.c.y-csiescseq.arg[0]);
+ break;
+ case 'g': /* TBC -- Tabulation clear */
+ switch (csiescseq.arg[0]) {
+ case 0: /* clear current tab stop */
+ term.tabs[term.c.x] = 0;
+ break;
+ case 3: /* clear all the tabs */
+ memset(term.tabs, 0, term.col * sizeof(*term.tabs));
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ case 'G': /* CHA -- Move to <col> */
+ case '`': /* HPA */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveto(csiescseq.arg[0]-1, term.c.y);
+ break;
+ case 'H': /* CUP -- Move to <row> <col> */
+ case 'f': /* HVP */
+ DEFAULT(csiescseq.arg[0], 1);
+ DEFAULT(csiescseq.arg[1], 1);
+ tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1);
+ break;
+ case 'I': /* CHT -- Cursor Forward Tabulation <n> tab stops */
+ DEFAULT(csiescseq.arg[0], 1);
+ tputtab(csiescseq.arg[0]);
+ break;
+ case 'J': /* ED -- Clear screen */
+ switch (csiescseq.arg[0]) {
+ case 0: /* below */
+ tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
+ if (term.c.y < term.row-1) {
+ tclearregion(0, term.c.y+1, term.col-1,
+ term.row-1);
+ }
+ break;
+ case 1: /* above */
+ if (term.c.y > 1)
+ tclearregion(0, 0, term.col-1, term.c.y-1);
+ tclearregion(0, term.c.y, term.c.x, term.c.y);
+ break;
+ case 2: /* all */
+ tclearregion(0, 0, term.col-1, term.row-1);
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ case 'K': /* EL -- Clear line */
+ switch (csiescseq.arg[0]) {
+ case 0: /* right */
+ tclearregion(term.c.x, term.c.y, term.col-1,
+ term.c.y);
+ break;
+ case 1: /* left */
+ tclearregion(0, term.c.y, term.c.x, term.c.y);
+ break;
+ case 2: /* all */
+ tclearregion(0, term.c.y, term.col-1, term.c.y);
+ break;
+ }
+ break;
+ case 'S': /* SU -- Scroll <n> line up */
+ DEFAULT(csiescseq.arg[0], 1);
+ tscrollup(term.top, csiescseq.arg[0], 0);
+ break;
+ case 'T': /* SD -- Scroll <n> line down */
+ DEFAULT(csiescseq.arg[0], 1);
+ tscrolldown(term.top, csiescseq.arg[0], 0);
+ break;
+ case 'L': /* IL -- Insert <n> blank lines */
+ DEFAULT(csiescseq.arg[0], 1);
+ tinsertblankline(csiescseq.arg[0]);
+ break;
+ case 'l': /* RM -- Reset Mode */
+ tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg);
+ break;
+ case 'M': /* DL -- Delete <n> lines */
+ DEFAULT(csiescseq.arg[0], 1);
+ tdeleteline(csiescseq.arg[0]);
+ break;
+ case 'X': /* ECH -- Erase <n> char */
+ DEFAULT(csiescseq.arg[0], 1);
+ tclearregion(term.c.x, term.c.y,
+ term.c.x + csiescseq.arg[0] - 1, term.c.y);
+ break;
+ case 'P': /* DCH -- Delete <n> char */
+ DEFAULT(csiescseq.arg[0], 1);
+ tdeletechar(csiescseq.arg[0]);
+ break;
+ case 'Z': /* CBT -- Cursor Backward Tabulation <n> tab stops */
+ DEFAULT(csiescseq.arg[0], 1);
+ tputtab(-csiescseq.arg[0]);
+ break;
+ case 'd': /* VPA -- Move to <row> */
+ DEFAULT(csiescseq.arg[0], 1);
+ tmoveato(term.c.x, csiescseq.arg[0]-1);
+ break;
+ case 'h': /* SM -- Set terminal mode */
+ tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg);
+ break;
+ case 'm': /* SGR -- Terminal attribute (color) */
+ tsetattr(csiescseq.arg, csiescseq.narg);
+ break;
+ case 'n': /* DSR – Device Status Report (cursor position) */
+ if (csiescseq.arg[0] == 6) {
+ len = snprintf(buf, sizeof(buf),"\033[%i;%iR",
+ term.c.y+1, term.c.x+1);
+ ttywrite(buf, len, 0);
+ }
+ break;
+ case 'r': /* DECSTBM -- Set Scrolling Region */
+ if (csiescseq.priv) {
+ goto unknown;
+ } else {
+ DEFAULT(csiescseq.arg[0], 1);
+ DEFAULT(csiescseq.arg[1], term.row);
+ tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1);
+ tmoveato(0, 0);
+ }
+ break;
+ case 's': /* DECSC -- Save cursor position (ANSI.SYS) */
+ tcursor(CURSOR_SAVE);
+ break;
+ case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */
+ tcursor(CURSOR_LOAD);
+ break;
+ case ' ':
+ switch (csiescseq.mode[1]) {
+ case 'q': /* DECSCUSR -- Set Cursor Style */
+ if (xsetcursor(csiescseq.arg[0]))
+ goto unknown;
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ }
+}
+
+void
+csidump(void)
+{
+ int i;
+ uint c;
+
+ fprintf(stderr, "ESC[");
+ for (i = 0; i < csiescseq.len; i++) {
+ c = csiescseq.buf[i] & 0xff;
+ if (isprint(c)) {
+ putc(c, stderr);
+ } else if (c == '\n') {
+ fprintf(stderr, "(\\n)");
+ } else if (c == '\r') {
+ fprintf(stderr, "(\\r)");
+ } else if (c == 0x1b) {
+ fprintf(stderr, "(\\e)");
+ } else {
+ fprintf(stderr, "(%02x)", c);
+ }
+ }
+ putc('\n', stderr);
+}
+
+void
+csireset(void)
+{
+ memset(&csiescseq, 0, sizeof(csiescseq));
+}
+
+void
+strhandle(void)
+{
+ char *p = NULL;
+ int j, narg, par;
+
+ term.esc &= ~(ESC_STR_END|ESC_STR);
+ strparse();
+ par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0;
+
+ switch (strescseq.type) {
+ case ']': /* OSC -- Operating System Command */
+ switch (par) {
+ case 0:
+ case 1:
+ case 2:
+ if (narg > 1)
+ xsettitle(strescseq.args[1]);
+ return;
+ case 52:
+ if (narg > 2) {
+ char *dec;
+
+ dec = base64dec(strescseq.args[2]);
+ if (dec) {
+ xsetsel(dec);
+ xclipcopy();
+ } else {
+ fprintf(stderr, "erresc: invalid base64\n");
+ }
+ }
+ return;
+ case 4: /* color set */
+ if (narg < 3)
+ break;
+ p = strescseq.args[2];
+ /* FALLTHROUGH */
+ case 104: /* color reset, here p = NULL */
+ j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
+ if (xsetcolorname(j, p)) {
+ fprintf(stderr, "erresc: invalid color %s\n", p);
+ } else {
+ /*
+ * TODO if defaultbg color is changed, borders
+ * are dirty
+ */
+ redraw();
+ }
+ return;
+ }
+ break;
+ case 'k': /* old title set compatibility */
+ xsettitle(strescseq.args[0]);
+ return;
+ case 'P': /* DCS -- Device Control String */
+ term.mode |= ESC_DCS;
+ case '_': /* APC -- Application Program Command */
+ case '^': /* PM -- Privacy Message */
+ return;
+ }
+
+ fprintf(stderr, "erresc: unknown str ");
+ strdump();
+}
+
+void
+strparse(void)
+{
+ int c;
+ char *p = strescseq.buf;
+
+ strescseq.narg = 0;
+ strescseq.buf[strescseq.len] = '\0';
+
+ if (*p == '\0')
+ return;
+
+ while (strescseq.narg < STR_ARG_SIZ) {
+ strescseq.args[strescseq.narg++] = p;
+ while ((c = *p) != ';' && c != '\0')
+ ++p;
+ if (c == '\0')
+ return;
+ *p++ = '\0';
+ }
+}
+
+void
+strdump(void)
+{
+ int i;
+ uint c;
+
+ fprintf(stderr, "ESC%c", strescseq.type);
+ for (i = 0; i < strescseq.len; i++) {
+ c = strescseq.buf[i] & 0xff;
+ if (c == '\0') {
+ putc('\n', stderr);
+ return;
+ } else if (isprint(c)) {
+ putc(c, stderr);
+ } else if (c == '\n') {
+ fprintf(stderr, "(\\n)");
+ } else if (c == '\r') {
+ fprintf(stderr, "(\\r)");
+ } else if (c == 0x1b) {
+ fprintf(stderr, "(\\e)");
+ } else {
+ fprintf(stderr, "(%02x)", c);
+ }
+ }
+ fprintf(stderr, "ESC\\\n");
+}
+
+void
+strreset(void)
+{
+ memset(&strescseq, 0, sizeof(strescseq));
+}
+
+void
+sendbreak(const Arg *arg)
+{
+ if (tcsendbreak(cmdfd, 0))
+ perror("Error sending break");
+}
+
+void
+tprinter(char *s, size_t len)
+{
+ if (iofd != -1 && xwrite(iofd, s, len) < 0) {
+ perror("Error writing to output file");
+ close(iofd);
+ iofd = -1;
+ }
+}
+
+void
+externalpipe(const Arg *arg)
+{
+ int to[2];
+ char buf[UTF_SIZ];
+ void (*oldsigpipe)(int);
+ Glyph *bp, *end;
+ int lastpos, n, newline;
+
+ if (pipe(to) == -1)
+ return;
+
+ switch (fork()) {
+ case -1:
+ close(to[0]);
+ close(to[1]);
+ return;
+ case 0:
+ dup2(to[0], STDIN_FILENO);
+ close(to[0]);
+ close(to[1]);
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
+ perror("failed");
+ exit(0);
+ }
+
+ close(to[0]);
+ /* ignore sigpipe for now, in case child exists early */
+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
+ newline = 0;
+ for (n = 0; n < term.row; n++) {
+ bp = term.line[n];
+ lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
+ if (lastpos < 0)
+ break;
+ end = &bp[lastpos + 1];
+ for (; bp < end; ++bp)
+ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
+ break;
+ if ((newline = term.line[n][lastpos].mode & ATTR_WRAP))
+ continue;
+ if (xwrite(to[1], "\n", 1) < 0)
+ break;
+ newline = 0;
+ }
+ if (newline)
+ (void)xwrite(to[1], "\n", 1);
+ close(to[1]);
+ /* restore */
+ signal(SIGPIPE, oldsigpipe);
+}
+
+void
+iso14755(const Arg *arg)
+{
+ FILE *p;
+ char *us, *e, codepoint[9], uc[UTF_SIZ];
+ unsigned long utf32;
+
+ if (!(p = popen(ISO14755CMD, "r")))
+ return;
+
+ us = fgets(codepoint, sizeof(codepoint), p);
+ pclose(p);
+
+ if (!us || *us == '\0' || *us == '-' || strlen(us) > 7)
+ return;
+ if ((utf32 = strtoul(us, &e, 16)) == ULONG_MAX ||
+ (*e != '\n' && *e != '\0'))
+ return;
+
+ ttywrite(uc, utf8encode(utf32, uc), 1);
+}
+
+void
+toggleprinter(const Arg *arg)
+{
+ term.mode ^= MODE_PRINT;
+}
+
+void
+printscreen(const Arg *arg)
+{
+ tdump();
+}
+
+void
+printsel(const Arg *arg)
+{
+ tdumpsel();
+}
+
+void
+tdumpsel(void)
+{
+ char *ptr;
+
+ if ((ptr = getsel())) {
+ tprinter(ptr, strlen(ptr));
+ free(ptr);
+ }
+}
+
+void
+tdumpline(int n)
+{
+ char buf[UTF_SIZ];
+ Glyph *bp, *end;
+
+ bp = &term.line[n][0];
+ end = &bp[MIN(tlinelen(n), term.col) - 1];
+ if (bp != end || bp->u != ' ') {
+ for ( ;bp <= end; ++bp)
+ tprinter(buf, utf8encode(bp->u, buf));
+ }
+ tprinter("\n", 1);
+}
+
+void
+tdump(void)
+{
+ int i;
+
+ for (i = 0; i < term.row; ++i)
+ tdumpline(i);
+}
+
+void
+tputtab(int n)
+{
+ uint x = term.c.x;
+
+ if (n > 0) {
+ while (x < term.col && n--)
+ for (++x; x < term.col && !term.tabs[x]; ++x)
+ /* nothing */ ;
+ } else if (n < 0) {
+ while (x > 0 && n++)
+ for (--x; x > 0 && !term.tabs[x]; --x)
+ /* nothing */ ;
+ }
+ term.c.x = LIMIT(x, 0, term.col-1);
+}
+
+void
+tdefutf8(char ascii)
+{
+ if (ascii == 'G')
+ term.mode |= MODE_UTF8;
+ else if (ascii == '@')
+ term.mode &= ~MODE_UTF8;
+}
+
+void
+tdeftran(char ascii)
+{
+ static char cs[] = "0B";
+ static int vcs[] = {CS_GRAPHIC0, CS_USA};
+ char *p;
+
+ if ((p = strchr(cs, ascii)) == NULL) {
+ fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
+ } else {
+ term.trantbl[term.icharset] = vcs[p - cs];
+ }
+}
+
+void
+tdectest(char c)
+{
+ int x, y;
+
+ if (c == '8') { /* DEC screen alignment test. */
+ for (x = 0; x < term.col; ++x) {
+ for (y = 0; y < term.row; ++y)
+ tsetchar('E', &term.c.attr, x, y);
+ }
+ }
+}
+
+void
+tstrsequence(uchar c)
+{
+ strreset();
+
+ switch (c) {
+ case 0x90: /* DCS -- Device Control String */
+ c = 'P';
+ term.esc |= ESC_DCS;
+ break;
+ case 0x9f: /* APC -- Application Program Command */
+ c = '_';
+ break;
+ case 0x9e: /* PM -- Privacy Message */
+ c = '^';
+ break;
+ case 0x9d: /* OSC -- Operating System Command */
+ c = ']';
+ break;
+ }
+ strescseq.type = c;
+ term.esc |= ESC_STR;
+}
+
+void
+tcontrolcode(uchar ascii)
+{
+ switch (ascii) {
+ case '\t': /* HT */
+ tputtab(1);
+ return;
+ case '\b': /* BS */
+ tmoveto(term.c.x-1, term.c.y);
+ return;
+ case '\r': /* CR */
+ tmoveto(0, term.c.y);
+ return;
+ case '\f': /* LF */
+ case '\v': /* VT */
+ case '\n': /* LF */
+ /* go to first col if the mode is set */
+ tnewline(IS_SET(MODE_CRLF));
+ return;
+ case '\a': /* BEL */
+ if (term.esc & ESC_STR_END) {
+ /* backwards compatibility to xterm */
+ strhandle();
+ } else {
+ xbell();
+ }
+ break;
+ case '\033': /* ESC */
+ csireset();
+ term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST);
+ term.esc |= ESC_START;
+ return;
+ case '\016': /* SO (LS1 -- Locking shift 1) */
+ case '\017': /* SI (LS0 -- Locking shift 0) */
+ term.charset = 1 - (ascii - '\016');
+ return;
+ case '\032': /* SUB */
+ tsetchar('?', &term.c.attr, term.c.x, term.c.y);
+ case '\030': /* CAN */
+ csireset();
+ break;
+ case '\005': /* ENQ (IGNORED) */
+ case '\000': /* NUL (IGNORED) */
+ case '\021': /* XON (IGNORED) */
+ case '\023': /* XOFF (IGNORED) */
+ case 0177: /* DEL (IGNORED) */
+ return;
+ case 0x80: /* TODO: PAD */
+ case 0x81: /* TODO: HOP */
+ case 0x82: /* TODO: BPH */
+ case 0x83: /* TODO: NBH */
+ case 0x84: /* TODO: IND */
+ break;
+ case 0x85: /* NEL -- Next line */
+ tnewline(1); /* always go to first col */
+ break;
+ case 0x86: /* TODO: SSA */
+ case 0x87: /* TODO: ESA */
+ break;
+ case 0x88: /* HTS -- Horizontal tab stop */
+ term.tabs[term.c.x] = 1;
+ break;
+ case 0x89: /* TODO: HTJ */
+ case 0x8a: /* TODO: VTS */
+ case 0x8b: /* TODO: PLD */
+ case 0x8c: /* TODO: PLU */
+ case 0x8d: /* TODO: RI */
+ case 0x8e: /* TODO: SS2 */
+ case 0x8f: /* TODO: SS3 */
+ case 0x91: /* TODO: PU1 */
+ case 0x92: /* TODO: PU2 */
+ case 0x93: /* TODO: STS */
+ case 0x94: /* TODO: CCH */
+ case 0x95: /* TODO: MW */
+ case 0x96: /* TODO: SPA */
+ case 0x97: /* TODO: EPA */
+ case 0x98: /* TODO: SOS */
+ case 0x99: /* TODO: SGCI */
+ break;
+ case 0x9a: /* DECID -- Identify Terminal */
+ ttywrite(vtiden, strlen(vtiden), 0);
+ break;
+ case 0x9b: /* TODO: CSI */
+ case 0x9c: /* TODO: ST */
+ break;
+ case 0x90: /* DCS -- Device Control String */
+ case 0x9d: /* OSC -- Operating System Command */
+ case 0x9e: /* PM -- Privacy Message */
+ case 0x9f: /* APC -- Application Program Command */
+ tstrsequence(ascii);
+ return;
+ }
+ /* only CAN, SUB, \a and C1 chars interrupt a sequence */
+ term.esc &= ~(ESC_STR_END|ESC_STR);
+}
+
+/*
+ * returns 1 when the sequence is finished and it hasn't to read
+ * more characters for this sequence, otherwise 0
+ */
+int
+eschandle(uchar ascii)
+{
+ switch (ascii) {
+ case '[':
+ term.esc |= ESC_CSI;
+ return 0;
+ case '#':
+ term.esc |= ESC_TEST;
+ return 0;
+ case '%':
+ term.esc |= ESC_UTF8;
+ return 0;
+ case 'P': /* DCS -- Device Control String */
+ case '_': /* APC -- Application Program Command */
+ case '^': /* PM -- Privacy Message */
+ case ']': /* OSC -- Operating System Command */
+ case 'k': /* old title set compatibility */
+ tstrsequence(ascii);
+ return 0;
+ case 'n': /* LS2 -- Locking shift 2 */
+ case 'o': /* LS3 -- Locking shift 3 */
+ term.charset = 2 + (ascii - 'n');
+ break;
+ case '(': /* GZD4 -- set primary charset G0 */
+ case ')': /* G1D4 -- set secondary charset G1 */
+ case '*': /* G2D4 -- set tertiary charset G2 */
+ case '+': /* G3D4 -- set quaternary charset G3 */
+ term.icharset = ascii - '(';
+ term.esc |= ESC_ALTCHARSET;
+ return 0;
+ case 'D': /* IND -- Linefeed */
+ if (term.c.y == term.bot) {
+ tscrollup(term.top, 1, 1);
+ } else {
+ tmoveto(term.c.x, term.c.y+1);
+ }
+ break;
+ case 'E': /* NEL -- Next line */
+ tnewline(1); /* always go to first col */
+ break;
+ case 'H': /* HTS -- Horizontal tab stop */
+ term.tabs[term.c.x] = 1;
+ break;
+ case 'M': /* RI -- Reverse index */
+ if (term.c.y == term.top) {
+ tscrolldown(term.top, 1, 1);
+ } else {
+ tmoveto(term.c.x, term.c.y-1);
+ }
+ break;
+ case 'Z': /* DECID -- Identify Terminal */
+ ttywrite(vtiden, strlen(vtiden), 0);
+ break;
+ case 'c': /* RIS -- Reset to initial state */
+ treset();
+ resettitle();
+ xloadcols();
+ break;
+ case '=': /* DECPAM -- Application keypad */
+ xsetmode(1, MODE_APPKEYPAD);
+ break;
+ case '>': /* DECPNM -- Normal keypad */
+ xsetmode(0, MODE_APPKEYPAD);
+ break;
+ case '7': /* DECSC -- Save Cursor */
+ tcursor(CURSOR_SAVE);
+ break;
+ case '8': /* DECRC -- Restore Cursor */
+ tcursor(CURSOR_LOAD);
+ break;
+ case '\\': /* ST -- String Terminator */
+ if (term.esc & ESC_STR_END)
+ strhandle();
+ break;
+ default:
+ fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
+ (uchar) ascii, isprint(ascii)? ascii:'.');
+ break;
+ }
+ return 1;
+}
+
+void
+tputc(Rune u)
+{
+ char c[UTF_SIZ];
+ int control;
+ int width, len;
+ Glyph *gp;
+
+ control = ISCONTROL(u);
+ if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
+ c[0] = u;
+ width = len = 1;
+ } else {
+ len = utf8encode(u, c);
+ if (!control && (width = wcwidth(u)) == -1) {
+ memcpy(c, "\357\277\275", 4); /* UTF_INVALID */
+ width = 1;
+ }
+ }
+
+ if (IS_SET(MODE_PRINT))
+ tprinter(c, len);
+
+ /*
+ * STR sequence must be checked before anything else
+ * because it uses all following characters until it
+ * receives a ESC, a SUB, a ST or any other C1 control
+ * character.
+ */
+ if (term.esc & ESC_STR) {
+ if (u == '\a' || u == 030 || u == 032 || u == 033 ||
+ ISCONTROLC1(u)) {
+ term.esc &= ~(ESC_START|ESC_STR|ESC_DCS);
+ if (IS_SET(MODE_SIXEL)) {
+ /* TODO: render sixel */;
+ term.mode &= ~MODE_SIXEL;
+ return;
+ }
+ term.esc |= ESC_STR_END;
+ goto check_control_code;
+ }
+
+
+ if (IS_SET(MODE_SIXEL)) {
+ /* TODO: implement sixel mode */
+ return;
+ }
+ if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
+ term.mode |= MODE_SIXEL;
+
+ if (strescseq.len+len >= sizeof(strescseq.buf)-1) {
+ /*
+ * Here is a bug in terminals. If the user never sends
+ * some code to stop the str or esc command, then st
+ * will stop responding. But this is better than
+ * silently failing with unknown characters. At least
+ * then users will report back.
+ *
+ * In the case users ever get fixed, here is the code:
+ */
+ /*
+ * term.esc = 0;
+ * strhandle();
+ */
+ return;
+ }
+
+ memmove(&strescseq.buf[strescseq.len], c, len);
+ strescseq.len += len;
+ return;
+ }
+
+check_control_code:
+ /*
+ * Actions of control codes must be performed as soon they arrive
+ * because they can be embedded inside a control sequence, and
+ * they must not cause conflicts with sequences.
+ */
+ if (control) {
+ tcontrolcode(u);
+ /*
+ * control codes are not shown ever
+ */
+ return;
+ } else if (term.esc & ESC_START) {
+ if (term.esc & ESC_CSI) {
+ csiescseq.buf[csiescseq.len++] = u;
+ if (BETWEEN(u, 0x40, 0x7E)
+ || csiescseq.len >= \
+ sizeof(csiescseq.buf)-1) {
+ term.esc = 0;
+ csiparse();
+ csihandle();
+ }
+ return;
+ } else if (term.esc & ESC_UTF8) {
+ tdefutf8(u);
+ } else if (term.esc & ESC_ALTCHARSET) {
+ tdeftran(u);
+ } else if (term.esc & ESC_TEST) {
+ tdectest(u);
+ } else {
+ if (!eschandle(u))
+ return;
+ /* sequence already finished */
+ }
+ term.esc = 0;
+ /*
+ * All characters which form part of a sequence are not
+ * printed
+ */
+ return;
+ }
+ if (sel.ob.x != -1 && BETWEEN(term.c.y, sel.ob.y, sel.oe.y))
+ selclear();
+
+ gp = &term.line[term.c.y][term.c.x];
+ if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) {
+ gp->mode |= ATTR_WRAP;
+ tnewline(1);
+ gp = &term.line[term.c.y][term.c.x];
+ }
+
+ if (IS_SET(MODE_INSERT) && term.c.x+width < term.col)
+ memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph));
+
+ if (term.c.x+width > term.col) {
+ tnewline(1);
+ gp = &term.line[term.c.y][term.c.x];
+ }
+
+ tsetchar(u, &term.c.attr, term.c.x, term.c.y);
+
+ if (width == 2) {
+ gp->mode |= ATTR_WIDE;
+ if (term.c.x+1 < term.col) {
+ gp[1].u = '\0';
+ gp[1].mode = ATTR_WDUMMY;
+ }
+ }
+ if (term.c.x+width < term.col) {
+ tmoveto(term.c.x+width, term.c.y);
+ } else {
+ term.c.state |= CURSOR_WRAPNEXT;
+ }
+}
+
+int
+twrite(const char *buf, int buflen, int show_ctrl)
+{
+ int charsize;
+ Rune u;
+ int n;
+
+ for (n = 0; n < buflen; n += charsize) {
+ if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
+ /* process a complete utf8 char */
+ charsize = utf8decode(buf + n, &u, buflen - n);
+ if (charsize == 0)
+ break;
+ } else {
+ u = buf[n] & 0xFF;
+ charsize = 1;
+ }
+ if (show_ctrl && ISCONTROL(u)) {
+ if (u & 0x80) {
+ u &= 0x7f;
+ tputc('^');
+ tputc('[');
+ } else if (u != '\n' && u != '\r' && u != '\t') {
+ u ^= 0x40;
+ tputc('^');
+ }
+ }
+ tputc(u);
+ }
+ return n;
+}
+
+void
+tresize(int col, int row)
+{
+ int i, j;
+ int minrow = MIN(row, term.row);
+ int mincol = MIN(col, term.col);
+ int *bp;
+ TCursor c;
+
+ if (col < 1 || row < 1) {
+ fprintf(stderr,
+ "tresize: error resizing to %dx%d\n", col, row);
+ return;
+ }
+
+ /*
+ * slide screen to keep cursor where we expect it -
+ * tscrollup would work here, but we can optimize to
+ * memmove because we're freeing the earlier lines
+ */
+ for (i = 0; i <= term.c.y - row; i++) {
+ free(term.line[i]);
+ free(term.alt[i]);
+ }
+ /* ensure that both src and dst are not NULL */
+ if (i > 0) {
+ memmove(term.line, term.line + i, row * sizeof(Line));
+ memmove(term.alt, term.alt + i, row * sizeof(Line));
+ }
+ for (i += row; i < term.row; i++) {
+ free(term.line[i]);
+ free(term.alt[i]);
+ }
+
+ /* resize to new height */
+ term.line = xrealloc(term.line, row * sizeof(Line));
+ term.alt = xrealloc(term.alt, row * sizeof(Line));
+ term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
+ term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
+
+ for (i = 0; i < HISTSIZE; i++) {
+ term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph));
+ for (j = mincol; j < col; j++) {
+ term.hist[i][j] = term.c.attr;
+ term.hist[i][j].u = ' ';
+ }
+ }
+
+ /* resize each r w to new width, zero-pad if needed */
+ for (i = 0; i < minrow; i++) {
+ term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
+ term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph));
+ }
+
+ /* allocate any new rows */
+ for (/* i = minrow */; i < row; i++) {
+ term.line[i] = xmalloc(col * sizeof(Glyph));
+ term.alt[i] = xmalloc(col * sizeof(Glyph));
+ }
+ if (col > term.col) {
+ bp = term.tabs + term.col;
+
+ memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
+ while (--bp > term.tabs && !*bp)
+ /* nothing */ ;
+ for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces)
+ *bp = 1;
+ }
+ /* update terminal size */
+ term.col = col;
+ term.row = row;
+ /* reset scrolling region */
+ tsetscroll(0, row-1);
+ /* make use of the LIMIT in tmoveto */
+ tmoveto(term.c.x, term.c.y);
+ /* Clearing both screens (it makes dirty all lines) */
+ c = term.c;
+ for (i = 0; i < 2; i++) {
+ if (mincol < col && 0 < minrow) {
+ tclearregion(mincol, 0, col - 1, minrow - 1);
+ }
+ if (0 < col && minrow < row) {
+ tclearregion(0, minrow, col - 1, row - 1);
+ }
+ tswapscreen();
+ tcursor(CURSOR_LOAD);
+ }
+ term.c = c;
+}
+
+void
+resettitle(void)
+{
+ xsettitle(NULL);
+}
+
+void
+drawregion(int x1, int y1, int x2, int y2)
+{
+ int y;
+ for (y = y1; y < y2; y++) {
+ if (!term.dirty[y])
+ continue;
+
+ term.dirty[y] = 0;
+ xdrawline(TLINE(y), x1, y, x2);
+ }
+}
+
+void
+draw(void)
+{
+ int cx = term.c.x;
+
+ if (!xstartdraw())
+ return;
+
+ /* adjust cursor position */
+ LIMIT(term.ocx, 0, term.col-1);
+ LIMIT(term.ocy, 0, term.row-1);
+ if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY)
+ term.ocx--;
+ if (term.line[term.c.y][cx].mode & ATTR_WDUMMY)
+ cx--;
+
+ drawregion(0, 0, term.col, term.row);
+ if (term.scr == 0) {
+ xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
+ term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
+ }
+ term.ocx = cx, term.ocy = term.c.y;
+ xfinishdraw();
+}
+
+void
+redraw(void)
+{
+ tfulldirt();
+ draw();
+}
diff --git a/st-master/st.h b/st-master/st.h
new file mode 100644
index 0000000..01cad23
--- /dev/null
+++ b/st-master/st.h
@@ -0,0 +1,141 @@
+/* See LICENSE for license details. */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+/* Arbitrary size */
+#define HISTSIZE 2000
+
+/* macros */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#define LEN(a) (sizeof(a) / sizeof(a)[0])
+#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
+#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d))
+#define DEFAULT(a, b) (a) = (a) ? (a) : (b)
+#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
+#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \
+ (a).bg != (b).bg)
+#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
+ (t1.tv_nsec-t2.tv_nsec)/1E6)
+#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
+
+#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
+#define IS_TRUECOL(x) (1 << 24 & (x))
+#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - term.scr \
+ + HISTSIZE + 1) % HISTSIZE] : term.line[(y) - term.scr])
+
+enum glyph_attribute {
+ ATTR_NULL = 0,
+ ATTR_BOLD = 1 << 0,
+ ATTR_FAINT = 1 << 1,
+ ATTR_ITALIC = 1 << 2,
+ ATTR_UNDERLINE = 1 << 3,
+ ATTR_BLINK = 1 << 4,
+ ATTR_REVERSE = 1 << 5,
+ ATTR_INVISIBLE = 1 << 6,
+ ATTR_STRUCK = 1 << 7,
+ ATTR_WRAP = 1 << 8,
+ ATTR_WIDE = 1 << 9,
+ ATTR_WDUMMY = 1 << 10,
+ ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
+};
+
+enum selection_mode {
+ SEL_IDLE = 0,
+ SEL_EMPTY = 1,
+ SEL_READY = 2
+};
+
+enum selection_type {
+ SEL_REGULAR = 1,
+ SEL_RECTANGULAR = 2
+};
+
+enum selection_snap {
+ SNAP_WORD = 1,
+ SNAP_LINE = 2
+};
+
+typedef unsigned char uchar;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+typedef unsigned short ushort;
+
+typedef uint_least32_t Rune;
+
+#define Glyph Glyph_
+typedef struct {
+ Rune u; /* character code */
+ ushort mode; /* attribute flags */
+ uint32_t fg; /* foreground */
+ uint32_t bg; /* background */
+} Glyph;
+
+typedef Glyph *Line;
+
+typedef union {
+ int i;
+ uint ui;
+ float f;
+ const void *v;
+} Arg;
+
+typedef struct {
+ uint b;
+ uint mask;
+ void (*func)(const Arg *);
+ const Arg arg;
+} MouseKey;
+
+void die(const char *, ...);
+void redraw(void);
+void draw(void);
+
+void externalpipe(const Arg *);
+void iso14755(const Arg *);
+void printscreen(const Arg *);
+void printsel(const Arg *);
+void sendbreak(const Arg *);
+void toggleprinter(const Arg *);
+
+int tattrset(int);
+void tnew(int, int);
+void tresize(int, int);
+void tsetdirtattr(int);
+void ttyhangup(void);
+int ttynew(char *, char *, char *, char **);
+size_t ttyread(void);
+void ttyresize(int, int);
+void ttywrite(const char *, size_t, int);
+
+void resettitle(void);
+
+void selclear(void);
+void selinit(void);
+void selstart(int, int, int);
+void selextend(int, int, int, int);
+int selected(int, int);
+char *getsel(void);
+
+size_t utf8encode(Rune, char *);
+
+void *xmalloc(size_t);
+void *xrealloc(void *, size_t);
+char *xstrdup(char *);
+
+void kscrolldown(const Arg *);
+void kscrollup(const Arg *);
+
+/* config.h globals */
+extern char *utmp;
+extern char *stty_args;
+extern char *vtiden;
+extern char *worddelimiters;
+extern int allowaltscreen;
+extern char *termname;
+extern unsigned int tabspaces;
+extern unsigned int alpha;
+extern unsigned int defaultfg;
+extern unsigned int defaultbg;
+extern MouseKey mkeys[];
diff --git a/st-master/st.info b/st-master/st.info
new file mode 100644
index 0000000..52fc617
--- /dev/null
+++ b/st-master/st.info
@@ -0,0 +1,222 @@
+st| simpleterm,
+ acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+ am,
+ bce,
+ bel=^G,
+ blink=\E[5m,
+ bold=\E[1m,
+ cbt=\E[Z,
+ cvvis=\E[?25h,
+ civis=\E[?25l,
+ clear=\E[H\E[2J,
+ cnorm=\E[?12l\E[?25h,
+ colors#8,
+ cols#80,
+ cr=^M,
+ csr=\E[%i%p1%d;%p2%dr,
+ cub=\E[%p1%dD,
+ cub1=^H,
+ cud1=^J,
+ cud=\E[%p1%dB,
+ cuf1=\E[C,
+ cuf=\E[%p1%dC,
+ cup=\E[%i%p1%d;%p2%dH,
+ cuu1=\E[A,
+ cuu=\E[%p1%dA,
+ dch=\E[%p1%dP,
+ dch1=\E[P,
+ dim=\E[2m,
+ dl=\E[%p1%dM,
+ dl1=\E[M,
+ ech=\E[%p1%dX,
+ ed=\E[J,
+ el=\E[K,
+ el1=\E[1K,
+ enacs=\E)0,
+ flash=\E[?5h$<80/>\E[?5l,
+ fsl=^G,
+ home=\E[H,
+ hpa=\E[%i%p1%dG,
+ hs,
+ ht=^I,
+ hts=\EH,
+ ich=\E[%p1%d@,
+ il1=\E[L,
+ il=\E[%p1%dL,
+ ind=^J,
+ indn=\E[%p1%dS,
+ invis=\E[8m,
+ is2=\E[4l\E>\E[?1034l,
+ it#8,
+ kel=\E[1;2F,
+ ked=\E[1;5F,
+ ka1=\E[1~,
+ ka3=\E[5~,
+ kc1=\E[4~,
+ kc3=\E[6~,
+ kbs=\177,
+ kcbt=\E[Z,
+ kb2=\EOu,
+ kcub1=\EOD,
+ kcud1=\EOB,
+ kcuf1=\EOC,
+ kcuu1=\EOA,
+ kDC=\E[3;2~,
+ kent=\EOM,
+ kEND=\E[1;2F,
+ kIC=\E[2;2~,
+ kNXT=\E[6;2~,
+ kPRV=\E[5;2~,
+ kHOM=\E[1;2H,
+ kLFT=\E[1;2D,
+ kRIT=\E[1;2C,
+ kind=\E[1;2B,
+ kri=\E[1;2A,
+ kclr=\E[3;5~,
+ kdl1=\E[3;2~,
+ kdch1=\E[3~,
+ kich1=\E[2~,
+ kend=\E[4~,
+ kf1=\EOP,
+ kf2=\EOQ,
+ kf3=\EOR,
+ kf4=\EOS,
+ kf5=\E[15~,
+ kf6=\E[17~,
+ kf7=\E[18~,
+ kf8=\E[19~,
+ kf9=\E[20~,
+ kf10=\E[21~,
+ kf11=\E[23~,
+ kf12=\E[24~,
+ kf13=\E[1;2P,
+ kf14=\E[1;2Q,
+ kf15=\E[1;2R,
+ kf16=\E[1;2S,
+ kf17=\E[15;2~,
+ kf18=\E[17;2~,
+ kf19=\E[18;2~,
+ kf20=\E[19;2~,
+ kf21=\E[20;2~,
+ kf22=\E[21;2~,
+ kf23=\E[23;2~,
+ kf24=\E[24;2~,
+ kf25=\E[1;5P,
+ kf26=\E[1;5Q,
+ kf27=\E[1;5R,
+ kf28=\E[1;5S,
+ kf29=\E[15;5~,
+ kf30=\E[17;5~,
+ kf31=\E[18;5~,
+ kf32=\E[19;5~,
+ kf33=\E[20;5~,
+ kf34=\E[21;5~,
+ kf35=\E[23;5~,
+ kf36=\E[24;5~,
+ kf37=\E[1;6P,
+ kf38=\E[1;6Q,
+ kf39=\E[1;6R,
+ kf40=\E[1;6S,
+ kf41=\E[15;6~,
+ kf42=\E[17;6~,
+ kf43=\E[18;6~,
+ kf44=\E[19;6~,
+ kf45=\E[20;6~,
+ kf46=\E[21;6~,
+ kf47=\E[23;6~,
+ kf48=\E[24;6~,
+ kf49=\E[1;3P,
+ kf50=\E[1;3Q,
+ kf51=\E[1;3R,
+ kf52=\E[1;3S,
+ kf53=\E[15;3~,
+ kf54=\E[17;3~,
+ kf55=\E[18;3~,
+ kf56=\E[19;3~,
+ kf57=\E[20;3~,
+ kf58=\E[21;3~,
+ kf59=\E[23;3~,
+ kf60=\E[24;3~,
+ kf61=\E[1;4P,
+ kf62=\E[1;4Q,
+ kf63=\E[1;4R,
+ khome=\E[1~,
+ kil1=\E[2;5~,
+ krmir=\E[2;2~,
+ knp=\E[6~,
+ kmous=\E[M,
+ kpp=\E[5~,
+ lines#24,
+ mir,
+ msgr,
+ npc,
+ op=\E[39;49m,
+ pairs#64,
+ mc0=\E[i,
+ mc4=\E[4i,
+ mc5=\E[5i,
+ rc=\E8,
+ rev=\E[7m,
+ ri=\EM,
+ ritm=\E[23m,
+ rmacs=\E(B,
+ rmcup=\E[?1049l,
+ rmir=\E[4l,
+ rmkx=\E[?1l\E>,
+ rmso=\E[27m,
+ rmul=\E[24m,
+ rs1=\Ec,
+ rs2=\E[4l\E>\E[?1034l,
+ sc=\E7,
+ setab=\E[4%p1%dm,
+ setaf=\E[3%p1%dm,
+ setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
+ setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
+ sgr0=\E[0m,
+ sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
+ sitm=\E[3m,
+ smacs=\E(0,
+ smcup=\E[?1049h,
+ smir=\E[4h,
+ smkx=\E[?1h\E=,
+ smso=\E[7m,
+ smul=\E[4m,
+ tbc=\E[3g,
+ tsl=\E]0;,
+ xenl,
+ vpa=\E[%i%p1%dd,
+# XTerm extensions
+ rmxx=\E[29m,
+ smxx=\E[9m,
+# tmux extensions, see TERMINFO EXTENSIONS in tmux(1)
+ Se,
+ Ss,
+ Tc,
+ Ms=\E]52;%p1%s;%p2%s\007,
+
+st-256color| simpleterm with 256 colors,
+ use=st,
+ ccc,
+ colors#256,
+ oc=\E]104\007,
+ pairs#32767,
+# Nicked from xterm-256color
+ initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
+ setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+ setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+
+st-meta| simpleterm with meta key,
+ use=st,
+ km,
+ rmm=\E[?1034l,
+ smm=\E[?1034h,
+ rs2=\E[4l\E>\E[?1034h,
+ is2=\E[4l\E>\E[?1034h,
+
+st-meta-256color| simpleterm with meta key and 256 colors,
+ use=st-256color,
+ km,
+ rmm=\E[?1034l,
+ smm=\E[?1034h,
+ rs2=\E[4l\E>\E[?1034h,
+ is2=\E[4l\E>\E[?1034h,
diff --git a/st-master/win.h b/st-master/win.h
new file mode 100644
index 0000000..d277477
--- /dev/null
+++ b/st-master/win.h
@@ -0,0 +1,42 @@
+/* See LICENSE for license details. */
+
+enum win_mode {
+ MODE_VISIBLE = 1 << 0,
+ MODE_FOCUSED = 1 << 1,
+ MODE_APPKEYPAD = 1 << 2,
+ MODE_MOUSEBTN = 1 << 3,
+ MODE_MOUSEMOTION = 1 << 4,
+ MODE_REVERSE = 1 << 5,
+ MODE_KBDLOCK = 1 << 6,
+ MODE_HIDE = 1 << 7,
+ MODE_APPCURSOR = 1 << 8,
+ MODE_MOUSESGR = 1 << 9,
+ MODE_8BIT = 1 << 10,
+ MODE_BLINK = 1 << 11,
+ MODE_FBLINK = 1 << 12,
+ MODE_FOCUS = 1 << 13,
+ MODE_MOUSEX10 = 1 << 14,
+ MODE_MOUSEMANY = 1 << 15,
+ MODE_BRCKTPASTE = 1 << 16,
+ MODE_NUMLOCK = 1 << 17,
+ MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
+ |MODE_MOUSEMANY,
+};
+
+/* alpha */
+#define OPAQUE 0Xff
+#define USE_ARGB (alpha != OPAQUE && opt_embed == NULL)
+
+void xbell(void);
+void xclipcopy(void);
+void xdrawcursor(int, int, Glyph, int, int, Glyph);
+void xdrawline(Line, int, int, int);
+void xfinishdraw(void);
+void xloadcols(void);
+int xsetcolorname(int, const char *);
+void xsettitle(char *);
+int xsetcursor(int);
+void xsetmode(int, unsigned int);
+void xsetpointermotion(int);
+void xsetsel(char *);
+int xstartdraw(void);
diff --git a/st-master/x.c b/st-master/x.c
new file mode 100644
index 0000000..da5084b
--- /dev/null
+++ b/st-master/x.c
@@ -0,0 +1,2094 @@
+/* See LICENSE for license details. */
+#include <errno.h>
+#include <math.h>
+#include <limits.h>
+#include <locale.h>
+#include <signal.h>
+#include <sys/select.h>
+#include <time.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <X11/Xft/Xft.h>
+#include <X11/XKBlib.h>
+#include <X11/Xresource.h>
+
+static char *argv0;
+#include "arg.h"
+#include "st.h"
+#include "win.h"
+
+/* types used in config.h */
+typedef struct {
+ uint mod;
+ KeySym keysym;
+ void (*func)(const Arg *);
+ const Arg arg;
+} Shortcut;
+
+typedef struct {
+ uint b;
+ uint mask;
+ char *s;
+} MouseShortcut;
+
+typedef struct {
+ KeySym k;
+ uint mask;
+ char *s;
+ /* three-valued logic variables: 0 indifferent, 1 on, -1 off */
+ signed char appkey; /* application keypad */
+ signed char appcursor; /* application cursor */
+} Key;
+
+/* Xresources preferences */
+enum resource_type {
+ STRING = 0,
+ INTEGER = 1,
+ FLOAT = 2
+};
+
+typedef struct {
+ char *name;
+ enum resource_type type;
+ void *dst;
+} ResourcePref;
+
+/* X modifiers */
+#define XK_ANY_MOD UINT_MAX
+#define XK_NO_MOD 0
+#define XK_SWITCH_MOD (1<<13)
+
+/* function definitions used in config.h */
+static void clipcopy(const Arg *);
+static void clippaste(const Arg *);
+static void numlock(const Arg *);
+static void selpaste(const Arg *);
+static void zoom(const Arg *);
+static void zoomabs(const Arg *);
+static void zoomreset(const Arg *);
+
+/* config.h for applying patches and the configuration. */
+#include "config.h"
+
+/* XEMBED messages */
+#define XEMBED_FOCUS_IN 4
+#define XEMBED_FOCUS_OUT 5
+
+/* macros */
+#define IS_SET(flag) ((win.mode & (flag)) != 0)
+#define TRUERED(x) (((x) & 0xff0000) >> 8)
+#define TRUEGREEN(x) (((x) & 0xff00))
+#define TRUEBLUE(x) (((x) & 0xff) << 8)
+
+typedef XftDraw *Draw;
+typedef XftColor Color;
+typedef XftGlyphFontSpec GlyphFontSpec;
+
+/* Purely graphic info */
+typedef struct {
+ int tw, th; /* tty width and height */
+ int w, h; /* window width and height */
+ int ch; /* char height */
+ int cw; /* char width */
+ int cyo; /* char y offset */
+ int mode; /* window state/mode flags */
+ int cursor; /* cursor style */
+} TermWindow;
+
+typedef struct {
+ Display *dpy;
+ Colormap cmap;
+ Window win;
+ Drawable buf;
+ GlyphFontSpec *specbuf; /* font spec buffer used for rendering */
+ Atom xembed, wmdeletewin, netwmname, netwmpid;
+ XIM xim;
+ XIC xic;
+ Draw draw;
+ Visual *vis;
+ XSetWindowAttributes attrs;
+ int scr;
+ int isfixed; /* is fixed geometry? */
+ int depth; /* bit depth */
+ int l, t; /* left and top offset */
+ int gm; /* geometry mask */
+} XWindow;
+
+typedef struct {
+ Atom xtarget;
+ char *primary, *clipboard;
+ struct timespec tclick1;
+ struct timespec tclick2;
+} XSelection;
+
+/* Font structure */
+#define Font Font_
+typedef struct {
+ int height;
+ int width;
+ int ascent;
+ int descent;
+ int badslant;
+ int badweight;
+ short lbearing;
+ short rbearing;
+ XftFont *match;
+ FcFontSet *set;
+ FcPattern *pattern;
+} Font;
+
+/* Drawing Context */
+typedef struct {
+ Color *col;
+ size_t collen;
+ Font font, bfont, ifont, ibfont;
+ GC gc;
+} DC;
+
+static inline ushort sixd_to_16bit(int);
+static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
+static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
+static void xdrawglyph(Glyph, int, int);
+static void xclear(int, int, int, int);
+static int xgeommasktogravity(int);
+static void xinit(int, int);
+static void cresize(int, int);
+static void xresize(int, int);
+static void xhints(void);
+static int xloadcolor(int, const char *, Color *);
+static int xloadfont(Font *, FcPattern *);
+static void xloadfonts(char *, double);
+static void xunloadfont(Font *);
+static void xunloadfonts(void);
+static void xsetenv(void);
+static void xseturgency(int);
+static int evcol(XEvent *);
+static int evrow(XEvent *);
+
+static void expose(XEvent *);
+static void visibility(XEvent *);
+static void unmap(XEvent *);
+static void kpress(XEvent *);
+static void cmessage(XEvent *);
+static void resize(XEvent *);
+static void focus(XEvent *);
+static void brelease(XEvent *);
+static void bpress(XEvent *);
+static void bmotion(XEvent *);
+static void propnotify(XEvent *);
+static void selnotify(XEvent *);
+static void selclear_(XEvent *);
+static void selrequest(XEvent *);
+static void setsel(char *, Time);
+static void mousesel(XEvent *, int);
+static void mousereport(XEvent *);
+static char *kmap(KeySym, uint);
+static int match(uint, uint);
+
+static void run(void);
+static void usage(void);
+
+static void (*handler[LASTEvent])(XEvent *) = {
+ [KeyPress] = kpress,
+ [ClientMessage] = cmessage,
+ [ConfigureNotify] = resize,
+ [VisibilityNotify] = visibility,
+ [UnmapNotify] = unmap,
+ [Expose] = expose,
+ [FocusIn] = focus,
+ [FocusOut] = focus,
+ [MotionNotify] = bmotion,
+ [ButtonPress] = bpress,
+ [ButtonRelease] = brelease,
+/*
+ * Uncomment if you want the selection to disappear when you select something
+ * different in another window.
+ */
+/* [SelectionClear] = selclear_, */
+ [SelectionNotify] = selnotify,
+/*
+ * PropertyNotify is only turned on when there is some INCR transfer happening
+ * for the selection retrieval.
+ */
+ [PropertyNotify] = propnotify,
+ [SelectionRequest] = selrequest,
+};
+
+/* Globals */
+static DC dc;
+static XWindow xw;
+static XSelection xsel;
+static TermWindow win;
+
+/* Font Ring Cache */
+enum {
+ FRC_NORMAL,
+ FRC_ITALIC,
+ FRC_BOLD,
+ FRC_ITALICBOLD
+};
+
+typedef struct {
+ XftFont *font;
+ int flags;
+ Rune unicodep;
+} Fontcache;
+
+/* Fontcache is an array now. A new font will be appended to the array. */
+static Fontcache frc[16];
+static int frclen = 0;
+static char *usedfont = NULL;
+static double usedfontsize = 0;
+static double defaultfontsize = 0;
+
+static char *opt_class = NULL;
+static char **opt_cmd = NULL;
+static char *opt_embed = NULL;
+static char *opt_font = NULL;
+static char *opt_io = NULL;
+static char *opt_line = NULL;
+static char *opt_name = NULL;
+static char *opt_title = NULL;
+
+static int oldbutton = 3; /* button event on startup: 3 = release */
+
+void
+clipcopy(const Arg *dummy)
+{
+ Atom clipboard;
+
+ free(xsel.clipboard);
+ xsel.clipboard = NULL;
+
+ if (xsel.primary != NULL) {
+ xsel.clipboard = xstrdup(xsel.primary);
+ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime);
+ }
+}
+
+void
+clippaste(const Arg *dummy)
+{
+ Atom clipboard;
+
+ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard,
+ xw.win, CurrentTime);
+}
+
+void
+selpaste(const Arg *dummy)
+{
+ XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY,
+ xw.win, CurrentTime);
+}
+
+void
+numlock(const Arg *dummy)
+{
+ win.mode ^= MODE_NUMLOCK;
+}
+
+void
+zoom(const Arg *arg)
+{
+ Arg larg;
+
+ larg.f = usedfontsize + arg->f;
+ zoomabs(&larg);
+}
+
+void
+zoomabs(const Arg *arg)
+{
+ xunloadfonts();
+ xloadfonts(usedfont, arg->f);
+ cresize(0, 0);
+ redraw();
+ xhints();
+}
+
+void
+zoomreset(const Arg *arg)
+{
+ Arg larg;
+
+ if (defaultfontsize > 0) {
+ larg.f = defaultfontsize;
+ zoomabs(&larg);
+ }
+}
+
+int
+evcol(XEvent *e)
+{
+ int x = e->xbutton.x - borderpx;
+ LIMIT(x, 0, win.tw - 1);
+ return x / win.cw;
+}
+
+int
+evrow(XEvent *e)
+{
+ int y = e->xbutton.y - borderpx;
+ LIMIT(y, 0, win.th - 1);
+ return y / win.ch;
+}
+
+void
+mousesel(XEvent *e, int done)
+{
+ int type, seltype = SEL_REGULAR;
+ uint state = e->xbutton.state & ~(Button1Mask | forceselmod);
+
+ for (type = 1; type < LEN(selmasks); ++type) {
+ if (match(selmasks[type], state)) {
+ seltype = type;
+ break;
+ }
+ }
+ selextend(evcol(e), evrow(e), seltype, done);
+ if (done)
+ setsel(getsel(), e->xbutton.time);
+}
+
+void
+mousereport(XEvent *e)
+{
+ int len, x = evcol(e), y = evrow(e),
+ button = e->xbutton.button, state = e->xbutton.state;
+ char buf[40];
+ static int ox, oy;
+
+ /* from urxvt */
+ if (e->xbutton.type == MotionNotify) {
+ if (x == ox && y == oy)
+ return;
+ if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY))
+ return;
+ /* MOUSE_MOTION: no reporting if no button is pressed */
+ if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3)
+ return;
+
+ button = oldbutton + 32;
+ ox = x;
+ oy = y;
+ } else {
+ if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) {
+ button = 3;
+ } else {
+ button -= Button1;
+ if (button >= 3)
+ button += 64 - 3;
+ }
+ if (e->xbutton.type == ButtonPress) {
+ oldbutton = button;
+ ox = x;
+ oy = y;
+ } else if (e->xbutton.type == ButtonRelease) {
+ oldbutton = 3;
+ /* MODE_MOUSEX10: no button release reporting */
+ if (IS_SET(MODE_MOUSEX10))
+ return;
+ if (button == 64 || button == 65)
+ return;
+ }
+ }
+
+ if (!IS_SET(MODE_MOUSEX10)) {
+ button += ((state & ShiftMask ) ? 4 : 0)
+ + ((state & Mod4Mask ) ? 8 : 0)
+ + ((state & ControlMask) ? 16 : 0);
+ }
+
+ if (IS_SET(MODE_MOUSESGR)) {
+ len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c",
+ button, x+1, y+1,
+ e->xbutton.type == ButtonRelease ? 'm' : 'M');
+ } else if (x < 223 && y < 223) {
+ len = snprintf(buf, sizeof(buf), "\033[M%c%c%c",
+ 32+button, 32+x+1, 32+y+1);
+ } else {
+ return;
+ }
+
+ ttywrite(buf, len, 0);
+}
+
+void
+bpress(XEvent *e)
+{
+ struct timespec now;
+ MouseShortcut *ms;
+ MouseKey *mk;
+ int snap;
+
+ if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
+ mousereport(e);
+ return;
+ }
+
+ for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
+ if (e->xbutton.button == ms->b
+ && match(ms->mask, e->xbutton.state)) {
+ ttywrite(ms->s, strlen(ms->s), 1);
+ return;
+ }
+ }
+
+ for (mk = mkeys; mk < mkeys + LEN(mkeys); mk++) {
+ if (e->xbutton.button == mk->b
+ && match(mk->mask, e->xbutton.state)) {
+ mk->func(&mk->arg);
+ return;
+ }
+ }
+
+ if (e->xbutton.button == Button1) {
+ /*
+ * If the user clicks below predefined timeouts specific
+ * snapping behaviour is exposed.
+ */
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) {
+ snap = SNAP_LINE;
+ } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) {
+ snap = SNAP_WORD;
+ } else {
+ snap = 0;
+ }
+ xsel.tclick2 = xsel.tclick1;
+ xsel.tclick1 = now;
+
+ selstart(evcol(e), evrow(e), snap);
+ }
+}
+
+void
+propnotify(XEvent *e)
+{
+ XPropertyEvent *xpev;
+ Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+
+ xpev = &e->xproperty;
+ if (xpev->state == PropertyNewValue &&
+ (xpev->atom == XA_PRIMARY ||
+ xpev->atom == clipboard)) {
+ selnotify(e);
+ }
+}
+
+void
+selnotify(XEvent *e)
+{
+ ulong nitems, ofs, rem;
+ int format;
+ uchar *data, *last, *repl;
+ Atom type, incratom, property = None;
+
+ incratom = XInternAtom(xw.dpy, "INCR", 0);
+
+ ofs = 0;
+ if (e->type == SelectionNotify)
+ property = e->xselection.property;
+ else if (e->type == PropertyNotify)
+ property = e->xproperty.atom;
+
+ if (property == None)
+ return;
+
+ do {
+ if (XGetWindowProperty(xw.dpy, xw.win, property, ofs,
+ BUFSIZ/4, False, AnyPropertyType,
+ &type, &format, &nitems, &rem,
+ &data)) {
+ fprintf(stderr, "Clipboard allocation failed\n");
+ return;
+ }
+
+ if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
+ /*
+ * If there is some PropertyNotify with no data, then
+ * this is the signal of the selection owner that all
+ * data has been transferred. We won't need to receive
+ * PropertyNotify events anymore.
+ */
+ MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
+ &xw.attrs);
+ }
+
+ if (type == incratom) {
+ /*
+ * Activate the PropertyNotify events so we receive
+ * when the selection owner does send us the next
+ * chunk of data.
+ */
+ MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
+ &xw.attrs);
+
+ /*
+ * Deleting the property is the transfer start signal.
+ */
+ XDeleteProperty(xw.dpy, xw.win, (int)property);
+ continue;
+ }
+
+ /*
+ * As seen in getsel:
+ * Line endings are inconsistent in the terminal and GUI world
+ * copy and pasting. When receiving some selection data,
+ * replace all '\n' with '\r'.
+ * FIXME: Fix the computer world.
+ */
+ repl = data;
+ last = data + nitems * format / 8;
+ while ((repl = memchr(repl, '\n', last - repl))) {
+ *repl++ = '\r';
+ }
+
+ if (IS_SET(MODE_BRCKTPASTE) && ofs == 0)
+ ttywrite("\033[200~", 6, 0);
+ ttywrite((char *)data, nitems * format / 8, 1);
+ if (IS_SET(MODE_BRCKTPASTE) && rem == 0)
+ ttywrite("\033[201~", 6, 0);
+ XFree(data);
+ /* number of 32-bit chunks returned */
+ ofs += nitems * format / 32;
+ } while (rem > 0);
+
+ /*
+ * Deleting the property again tells the selection owner to send the
+ * next data chunk in the property.
+ */
+ XDeleteProperty(xw.dpy, xw.win, (int)property);
+}
+
+void
+xclipcopy(void)
+{
+ clipcopy(NULL);
+}
+
+void
+selclear_(XEvent *e)
+{
+ selclear();
+}
+
+void
+selrequest(XEvent *e)
+{
+ XSelectionRequestEvent *xsre;
+ XSelectionEvent xev;
+ Atom xa_targets, string, clipboard;
+ char *seltext;
+
+ xsre = (XSelectionRequestEvent *) e;
+ xev.type = SelectionNotify;
+ xev.requestor = xsre->requestor;
+ xev.selection = xsre->selection;
+ xev.target = xsre->target;
+ xev.time = xsre->time;
+ if (xsre->property == None)
+ xsre->property = xsre->target;
+
+ /* reject */
+ xev.property = None;
+
+ xa_targets = XInternAtom(xw.dpy, "TARGETS", 0);
+ if (xsre->target == xa_targets) {
+ /* respond with the supported type */
+ string = xsel.xtarget;
+ XChangeProperty(xsre->display, xsre->requestor, xsre->property,
+ XA_ATOM, 32, PropModeReplace,
+ (uchar *) &string, 1);
+ xev.property = xsre->property;
+ } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) {
+ /*
+ * xith XA_STRING non ascii characters may be incorrect in the
+ * requestor. It is not our problem, use utf8.
+ */
+ clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ if (xsre->selection == XA_PRIMARY) {
+ seltext = xsel.primary;
+ } else if (xsre->selection == clipboard) {
+ seltext = xsel.clipboard;
+ } else {
+ fprintf(stderr,
+ "Unhandled clipboard selection 0x%lx\n",
+ xsre->selection);
+ return;
+ }
+ if (seltext != NULL) {
+ XChangeProperty(xsre->display, xsre->requestor,
+ xsre->property, xsre->target,
+ 8, PropModeReplace,
+ (uchar *)seltext, strlen(seltext));
+ xev.property = xsre->property;
+ }
+ }
+
+ /* all done, send a notification to the listener */
+ if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev))
+ fprintf(stderr, "Error sending SelectionNotify event\n");
+}
+
+void
+setsel(char *str, Time t)
+{
+ if (!str)
+ return;
+
+ free(xsel.primary);
+ xsel.primary = str;
+
+ XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
+ if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
+ selclear();
+
+ xclipcopy();
+}
+
+void
+xsetsel(char *str)
+{
+ setsel(str, CurrentTime);
+}
+
+void
+brelease(XEvent *e)
+{
+ if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
+ mousereport(e);
+ return;
+ }
+
+ if (e->xbutton.button == Button2)
+ selpaste(NULL);
+ else if (e->xbutton.button == Button1)
+ mousesel(e, 1);
+}
+
+void
+bmotion(XEvent *e)
+{
+ if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
+ mousereport(e);
+ return;
+ }
+
+ mousesel(e, 0);
+}
+
+void
+cresize(int width, int height)
+{
+ int col, row;
+
+ if (width != 0)
+ win.w = width;
+ if (height != 0)
+ win.h = height;
+
+ col = (win.w - 2 * borderpx) / win.cw;
+ row = (win.h - 2 * borderpx) / win.ch;
+ col = MAX(1, col);
+ row = MAX(1, row);
+
+ tresize(col, row);
+ xresize(col, row);
+ ttyresize(win.tw, win.th);
+}
+
+void
+xresize(int col, int row)
+{
+ win.tw = col * win.cw;
+ win.th = row * win.ch;
+
+ XFreePixmap(xw.dpy, xw.buf);
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h,
+ xw.depth);
+ XftDrawChange(xw.draw, xw.buf);
+ xclear(0, 0, win.w, win.h);
+
+ /* resize to new width */
+ xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
+}
+
+ushort
+sixd_to_16bit(int x)
+{
+ return x == 0 ? 0 : 0x3737 + 0x2828 * x;
+}
+
+int
+xloadcolor(int i, const char *name, Color *ncolor)
+{
+ XRenderColor color = { .alpha = 0xffff };
+
+ if (!name) {
+ if (BETWEEN(i, 16, 255)) { /* 256 color */
+ if (i < 6*6*6+16) { /* same colors as xterm */
+ color.red = sixd_to_16bit( ((i-16)/36)%6 );
+ color.green = sixd_to_16bit( ((i-16)/6) %6 );
+ color.blue = sixd_to_16bit( ((i-16)/1) %6 );
+ } else { /* greyscale */
+ color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16));
+ color.green = color.blue = color.red;
+ }
+ return XftColorAllocValue(xw.dpy, xw.vis,
+ xw.cmap, &color, ncolor);
+ } else
+ name = colorname[i];
+ }
+
+ return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
+}
+
+void
+xloadcols(void)
+{
+ int i;
+ static int loaded;
+ Color *cp;
+
+ if (loaded) {
+ for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
+ } else {
+ dc.collen = MAX(LEN(colorname), 256);
+ dc.col = xmalloc(dc.collen * sizeof(Color));
+ }
+
+ for (i = 0; i < dc.collen; i++)
+ if (!xloadcolor(i, NULL, &dc.col[i])) {
+ if (colorname[i])
+ die("Could not allocate color '%s'\n", colorname[i]);
+ else
+ die("Could not allocate color %d\n", i);
+ }
+
+ /* set alpha value of bg color */
+ if (USE_ARGB) {
+ dc.col[defaultbg].color.alpha = (0xffff * alpha) / OPAQUE;
+ dc.col[defaultbg].pixel &= 0x00111111;
+ dc.col[defaultbg].pixel |= alpha << 24;
+ }
+ loaded = 1;
+}
+
+int
+xsetcolorname(int x, const char *name)
+{
+ Color ncolor;
+
+ if (!BETWEEN(x, 0, dc.collen))
+ return 1;
+
+
+ if (!xloadcolor(x, name, &ncolor))
+ return 1;
+
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]);
+ dc.col[x] = ncolor;
+
+ return 0;
+}
+
+void
+xtermclear(int col1, int row1, int col2, int row2)
+{
+ XftDrawRect(xw.draw,
+ &dc.col[IS_SET(MODE_REVERSE) ? defaultfg : defaultbg],
+ borderpx + col1 * win.cw,
+ borderpx + row1 * win.ch,
+ (col2-col1+1) * win.cw,
+ (row2-row1+1) * win.ch);
+}
+
+/*
+ * Absolute coordinates.
+ */
+void
+xclear(int x1, int y1, int x2, int y2)
+{
+ XftDrawRect(xw.draw,
+ &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg],
+ x1, y1, x2-x1, y2-y1);
+}
+
+void
+xhints(void)
+{
+ XClassHint class = {opt_name ? opt_name : "st",
+ opt_class ? opt_class : "St"};
+ XWMHints wm = {.flags = InputHint, .input = 1};
+ XSizeHints *sizeh;
+
+ sizeh = XAllocSizeHints();
+
+ sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize;
+ sizeh->height = win.h;
+ sizeh->width = win.w;
+ sizeh->height_inc = win.ch;
+ sizeh->width_inc = win.cw;
+ sizeh->base_height = 2 * borderpx;
+ sizeh->base_width = 2 * borderpx;
+ sizeh->min_height = win.ch + 2 * borderpx;
+ sizeh->min_width = win.cw + 2 * borderpx;
+ if (xw.isfixed) {
+ sizeh->flags |= PMaxSize;
+ sizeh->min_width = sizeh->max_width = win.w;
+ sizeh->min_height = sizeh->max_height = win.h;
+ }
+ if (xw.gm & (XValue|YValue)) {
+ sizeh->flags |= USPosition | PWinGravity;
+ sizeh->x = xw.l;
+ sizeh->y = xw.t;
+ sizeh->win_gravity = xgeommasktogravity(xw.gm);
+ }
+
+ XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm,
+ &class);
+ XFree(sizeh);
+}
+
+int
+xgeommasktogravity(int mask)
+{
+ switch (mask & (XNegative|YNegative)) {
+ case 0:
+ return NorthWestGravity;
+ case XNegative:
+ return NorthEastGravity;
+ case YNegative:
+ return SouthWestGravity;
+ }
+
+ return SouthEastGravity;
+}
+
+int
+xloadfont(Font *f, FcPattern *pattern)
+{
+ FcPattern *configured;
+ FcPattern *match;
+ FcResult result;
+ XGlyphInfo extents;
+ int wantattr, haveattr;
+
+ /*
+ * Manually configure instead of calling XftMatchFont
+ * so that we can use the configured pattern for
+ * "missing glyph" lookups.
+ */
+ configured = FcPatternDuplicate(pattern);
+ if (!configured)
+ return 1;
+
+ FcConfigSubstitute(NULL, configured, FcMatchPattern);
+ XftDefaultSubstitute(xw.dpy, xw.scr, configured);
+
+ match = FcFontMatch(NULL, configured, &result);
+ if (!match) {
+ FcPatternDestroy(configured);
+ return 1;
+ }
+
+ if (!(f->match = XftFontOpenPattern(xw.dpy, match))) {
+ FcPatternDestroy(configured);
+ FcPatternDestroy(match);
+ return 1;
+ }
+
+ if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) ==
+ XftResultMatch)) {
+ /*
+ * Check if xft was unable to find a font with the appropriate
+ * slant but gave us one anyway. Try to mitigate.
+ */
+ if ((XftPatternGetInteger(f->match->pattern, "slant", 0,
+ &haveattr) != XftResultMatch) || haveattr < wantattr) {
+ f->badslant = 1;
+ fputs("st: font slant does not match\n", stderr);
+ }
+ }
+
+ if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) ==
+ XftResultMatch)) {
+ if ((XftPatternGetInteger(f->match->pattern, "weight", 0,
+ &haveattr) != XftResultMatch) || haveattr != wantattr) {
+ f->badweight = 1;
+ fputs("st: font weight does not match\n", stderr);
+ }
+ }
+
+ XftTextExtentsUtf8(xw.dpy, f->match,
+ (const FcChar8 *) ascii_printable,
+ strlen(ascii_printable), &extents);
+
+ f->set = NULL;
+ f->pattern = configured;
+
+ f->ascent = f->match->ascent;
+ f->descent = f->match->descent;
+ f->lbearing = 0;
+ f->rbearing = f->match->max_advance_width;
+
+ f->height = f->ascent + f->descent;
+ f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));
+
+ return 0;
+}
+
+void
+xloadfonts(char *fontstr, double fontsize)
+{
+ FcPattern *pattern;
+ double fontval;
+
+ if (fontstr[0] == '-') {
+ pattern = XftXlfdParse(fontstr, False, False);
+ } else {
+ pattern = FcNameParse((FcChar8 *)fontstr);
+ }
+
+ if (!pattern)
+ die("st: can't open font %s\n", fontstr);
+
+ if (fontsize > 1) {
+ FcPatternDel(pattern, FC_PIXEL_SIZE);
+ FcPatternDel(pattern, FC_SIZE);
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize);
+ usedfontsize = fontsize;
+ } else {
+ if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
+ FcResultMatch) {
+ usedfontsize = fontval;
+ } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) ==
+ FcResultMatch) {
+ usedfontsize = -1;
+ } else {
+ /*
+ * Default font size is 12, if none given. This is to
+ * have a known usedfontsize value.
+ */
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12);
+ usedfontsize = 12;
+ }
+ defaultfontsize = usedfontsize;
+ }
+
+ if (xloadfont(&dc.font, pattern))
+ die("st: can't open font %s\n", fontstr);
+
+ if (usedfontsize < 0) {
+ FcPatternGetDouble(dc.font.match->pattern,
+ FC_PIXEL_SIZE, 0, &fontval);
+ usedfontsize = fontval;
+ if (fontsize == 0)
+ defaultfontsize = fontval;
+ }
+
+ /* Setting character width and height. */
+ win.cw = ceilf(dc.font.width * cwscale);
+ win.ch = ceilf(dc.font.height * chscale);
+ win.cyo = ceilf(dc.font.height * (chscale - 1) / 2);
+
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ if (xloadfont(&dc.ifont, pattern))
+ die("st: can't open font %s\n", fontstr);
+
+ FcPatternDel(pattern, FC_WEIGHT);
+ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+ if (xloadfont(&dc.ibfont, pattern))
+ die("st: can't open font %s\n", fontstr);
+
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
+ if (xloadfont(&dc.bfont, pattern))
+ die("st: can't open font %s\n", fontstr);
+
+ FcPatternDestroy(pattern);
+}
+
+void
+xunloadfont(Font *f)
+{
+ XftFontClose(xw.dpy, f->match);
+ FcPatternDestroy(f->pattern);
+ if (f->set)
+ FcFontSetDestroy(f->set);
+}
+
+void
+xunloadfonts(void)
+{
+ /* Free the loaded fonts in the font cache. */
+ while (frclen > 0)
+ XftFontClose(xw.dpy, frc[--frclen].font);
+
+ xunloadfont(&dc.font);
+ xunloadfont(&dc.bfont);
+ xunloadfont(&dc.ifont);
+ xunloadfont(&dc.ibfont);
+}
+
+void
+xinit(int cols, int rows)
+{
+ XGCValues gcvalues;
+ Cursor cursor;
+ Window parent;
+ pid_t thispid = getpid();
+ XColor xmousefg, xmousebg;
+
+ xw.scr = XDefaultScreen(xw.dpy);
+ xw.depth = (USE_ARGB) ? 32: XDefaultDepth(xw.dpy, xw.scr);
+ if (!USE_ARGB)
+ xw.vis = XDefaultVisual(xw.dpy, xw.scr);
+ else {
+ XVisualInfo *vis;
+ XRenderPictFormat *fmt;
+ int nvi;
+ int i;
+
+ XVisualInfo tpl = {
+ .screen = xw.scr,
+ .depth = 32,
+ .class = TrueColor
+ };
+
+ vis = XGetVisualInfo(xw.dpy,
+ VisualScreenMask | VisualDepthMask | VisualClassMask,
+ &tpl, &nvi);
+ xw.vis = NULL;
+ for (i = 0; i < nvi; i++) {
+ fmt = XRenderFindVisualFormat(xw.dpy, vis[i].visual);
+ if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
+ xw.vis = vis[i].visual;
+ break;
+ }
+ }
+
+ XFree(vis);
+
+ if (!xw.vis) {
+ fprintf(stderr, "Couldn't find ARGB visual.\n");
+ exit(1);
+ }
+ }
+
+ /* font */
+ if (!FcInit())
+ die("Could not init fontconfig.\n");
+
+ usedfont = (opt_font == NULL)? font : opt_font;
+ xloadfonts(usedfont, 0);
+
+ /* colors */
+ if (!USE_ARGB)
+ xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
+ else
+ xw.cmap = XCreateColormap(xw.dpy, XRootWindow(xw.dpy, xw.scr),
+ xw.vis, None);
+ xloadcols();
+
+ /* adjust fixed window geometry */
+ win.w = 2 * borderpx + cols * win.cw;
+ win.h = 2 * borderpx + rows * win.ch;
+ if (xw.gm & XNegative)
+ xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2;
+ if (xw.gm & YNegative)
+ xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2;
+
+ /* Events */
+ xw.attrs.background_pixel = dc.col[defaultbg].pixel;
+ xw.attrs.border_pixel = dc.col[defaultbg].pixel;
+ xw.attrs.bit_gravity = NorthWestGravity;
+ xw.attrs.event_mask = FocusChangeMask | KeyPressMask
+ | ExposureMask | VisibilityChangeMask | StructureNotifyMask
+ | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
+ xw.attrs.colormap = xw.cmap;
+
+ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0))))
+ parent = XRootWindow(xw.dpy, xw.scr);
+ xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t,
+ win.w, win.h, 0, xw.depth, InputOutput,
+ xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
+ | CWEventMask | CWColormap, &xw.attrs);
+
+ memset(&gcvalues, 0, sizeof(gcvalues));
+ gcvalues.graphics_exposures = False;
+ xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth);
+ dc.gc = XCreateGC(xw.dpy, (USE_ARGB) ? xw.buf: parent,
+ GCGraphicsExposures, &gcvalues);
+ XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel);
+ XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
+
+ /* font spec buffer */
+ xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
+
+ /* Xft rendering context */
+ xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
+
+ /* input methods */
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
+ XSetLocaleModifiers("@im=local");
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
+ XSetLocaleModifiers("@im=");
+ if ((xw.xim = XOpenIM(xw.dpy,
+ NULL, NULL, NULL)) == NULL) {
+ die("XOpenIM failed. Could not open input"
+ " device.\n");
+ }
+ }
+ }
+ xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing
+ | XIMStatusNothing, XNClientWindow, xw.win,
+ XNFocusWindow, xw.win, NULL);
+ if (xw.xic == NULL)
+ die("XCreateIC failed. Could not obtain input method.\n");
+
+ /* white cursor, black outline */
+ cursor = XCreateFontCursor(xw.dpy, mouseshape);
+ XDefineCursor(xw.dpy, xw.win, cursor);
+
+ if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) {
+ xmousefg.red = 0xffff;
+ xmousefg.green = 0xffff;
+ xmousefg.blue = 0xffff;
+ }
+
+ if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) {
+ xmousebg.red = 0x0000;
+ xmousebg.green = 0x0000;
+ xmousebg.blue = 0x0000;
+ }
+
+ XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
+
+ xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
+ xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
+ xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False);
+ XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1);
+
+ xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False);
+ XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32,
+ PropModeReplace, (uchar *)&thispid, 1);
+
+ win.mode = MODE_NUMLOCK;
+ resettitle();
+ XMapWindow(xw.dpy, xw.win);
+ xhints();
+ XSync(xw.dpy, False);
+
+ clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1);
+ clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2);
+ xsel.primary = NULL;
+ xsel.clipboard = NULL;
+ xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
+ if (xsel.xtarget == None)
+ xsel.xtarget = XA_STRING;
+}
+
+int
+xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
+{
+ float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
+ ushort mode, prevmode = USHRT_MAX;
+ Font *font = &dc.font;
+ int frcflags = FRC_NORMAL;
+ float runewidth = win.cw;
+ Rune rune;
+ FT_UInt glyphidx;
+ FcResult fcres;
+ FcPattern *fcpattern, *fontpattern;
+ FcFontSet *fcsets[] = { NULL };
+ FcCharSet *fccharset;
+ int i, f, numspecs = 0;
+
+ for (i = 0, xp = winx, yp = winy + font->ascent + win.cyo; i < len; ++i) {
+ /* Fetch rune and mode for current glyph. */
+ rune = glyphs[i].u;
+ mode = glyphs[i].mode;
+
+ /* Skip dummy wide-character spacing. */
+ if (mode == ATTR_WDUMMY)
+ continue;
+
+ /* Determine font for glyph if different from previous glyph. */
+ if (prevmode != mode) {
+ prevmode = mode;
+ font = &dc.font;
+ frcflags = FRC_NORMAL;
+ runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
+ if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
+ font = &dc.ibfont;
+ frcflags = FRC_ITALICBOLD;
+ } else if (mode & ATTR_ITALIC) {
+ font = &dc.ifont;
+ frcflags = FRC_ITALIC;
+ } else if (mode & ATTR_BOLD) {
+ font = &dc.bfont;
+ frcflags = FRC_BOLD;
+ }
+ yp = winy + font->ascent + win.cyo;
+ }
+
+ /* Lookup character index with default font. */
+ glyphidx = XftCharIndex(xw.dpy, font->match, rune);
+ if (glyphidx) {
+ specs[numspecs].font = font->match;
+ specs[numspecs].glyph = glyphidx;
+ specs[numspecs].x = (short)xp;
+ specs[numspecs].y = (short)yp;
+ xp += runewidth;
+ numspecs++;
+ continue;
+ }
+
+ /* Fallback on font cache, search the font cache for match. */
+ for (f = 0; f < frclen; f++) {
+ glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
+ /* Everything correct. */
+ if (glyphidx && frc[f].flags == frcflags)
+ break;
+ /* We got a default font for a not found glyph. */
+ if (!glyphidx && frc[f].flags == frcflags
+ && frc[f].unicodep == rune) {
+ break;
+ }
+ }
+
+ /* Nothing was found. Use fontconfig to find matching font. */
+ if (f >= frclen) {
+ if (!font->set)
+ font->set = FcFontSort(0, font->pattern,
+ 1, 0, &fcres);
+ fcsets[0] = font->set;
+
+ /*
+ * Nothing was found in the cache. Now use
+ * some dozen of Fontconfig calls to get the
+ * font for one single character.
+ *
+ * Xft and fontconfig are design failures.
+ */
+ fcpattern = FcPatternDuplicate(font->pattern);
+ fccharset = FcCharSetCreate();
+
+ FcCharSetAddChar(fccharset, rune);
+ FcPatternAddCharSet(fcpattern, FC_CHARSET,
+ fccharset);
+ FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
+
+ FcConfigSubstitute(0, fcpattern,
+ FcMatchPattern);
+ FcDefaultSubstitute(fcpattern);
+
+ fontpattern = FcFontSetMatch(0, fcsets, 1,
+ fcpattern, &fcres);
+
+ /*
+ * Overwrite or create the new cache entry.
+ */
+ if (frclen >= LEN(frc)) {
+ frclen = LEN(frc) - 1;
+ XftFontClose(xw.dpy, frc[frclen].font);
+ frc[frclen].unicodep = 0;
+ }
+
+ frc[frclen].font = XftFontOpenPattern(xw.dpy,
+ fontpattern);
+ if (!frc[frclen].font)
+ die("XftFontOpenPattern failed seeking fallback font: %s\n",
+ strerror(errno));
+ frc[frclen].flags = frcflags;
+ frc[frclen].unicodep = rune;
+
+ glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune);
+
+ f = frclen;
+ frclen++;
+
+ FcPatternDestroy(fcpattern);
+ FcCharSetDestroy(fccharset);
+ }
+
+ specs[numspecs].font = frc[f].font;
+ specs[numspecs].glyph = glyphidx;
+ specs[numspecs].x = (short)xp;
+ specs[numspecs].y = (short)yp;
+ xp += runewidth;
+ numspecs++;
+ }
+
+ return numspecs;
+}
+
+void
+xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
+{
+ int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
+ int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
+ width = charlen * win.cw;
+ Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
+ XRenderColor colfg, colbg;
+ XRectangle r;
+
+ /* Fallback on color display for attributes not supported by the font */
+ if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) {
+ if (dc.ibfont.badslant || dc.ibfont.badweight)
+ base.fg = defaultattr;
+ } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) ||
+ (base.mode & ATTR_BOLD && dc.bfont.badweight)) {
+ base.fg = defaultattr;
+ }
+
+ if (IS_TRUECOL(base.fg)) {
+ colfg.alpha = 0xffff;
+ colfg.red = TRUERED(base.fg);
+ colfg.green = TRUEGREEN(base.fg);
+ colfg.blue = TRUEBLUE(base.fg);
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg);
+ fg = &truefg;
+ } else {
+ fg = &dc.col[base.fg];
+ }
+
+ if (IS_TRUECOL(base.bg)) {
+ colbg.alpha = 0xffff;
+ colbg.green = TRUEGREEN(base.bg);
+ colbg.red = TRUERED(base.bg);
+ colbg.blue = TRUEBLUE(base.bg);
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg);
+ bg = &truebg;
+ } else {
+ bg = &dc.col[base.bg];
+ }
+
+ /* Change basic system colors [0-7] to bright system colors [8-15] */
+ if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7))
+ fg = &dc.col[base.fg];
+
+ if (IS_SET(MODE_REVERSE)) {
+ if (fg == &dc.col[defaultfg]) {
+ fg = &dc.col[defaultbg];
+ } else {
+ colfg.red = ~fg->color.red;
+ colfg.green = ~fg->color.green;
+ colfg.blue = ~fg->color.blue;
+ colfg.alpha = fg->color.alpha;
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg,
+ &revfg);
+ fg = &revfg;
+ }
+
+ if (bg == &dc.col[defaultbg]) {
+ bg = &dc.col[defaultfg];
+ } else {
+ colbg.red = ~bg->color.red;
+ colbg.green = ~bg->color.green;
+ colbg.blue = ~bg->color.blue;
+ colbg.alpha = bg->color.alpha;
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg,
+ &revbg);
+ bg = &revbg;
+ }
+ }
+
+ if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) {
+ colfg.red = fg->color.red / 2;
+ colfg.green = fg->color.green / 2;
+ colfg.blue = fg->color.blue / 2;
+ colfg.alpha = fg->color.alpha;
+ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg);
+ fg = &revfg;
+ }
+
+ if (base.mode & ATTR_REVERSE) {
+ temp = fg;
+ fg = bg;
+ bg = temp;
+ }
+
+ if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK)
+ fg = bg;
+
+ if (base.mode & ATTR_INVISIBLE)
+ fg = bg;
+
+ /* Intelligent cleaning up of the borders. */
+ if (x == 0) {
+ xclear(0, (y == 0)? 0 : winy, borderpx,
+ winy + win.ch +
+ ((winy + win.ch >= borderpx + win.th)? win.h : 0));
+ }
+ if (winx + width >= borderpx + win.tw) {
+ xclear(winx + width, (y == 0)? 0 : winy, win.w,
+ ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
+ }
+ if (y == 0)
+ xclear(winx, 0, winx + width, borderpx);
+ if (winy + win.ch >= borderpx + win.th)
+ xclear(winx, winy + win.ch, winx + width, win.h);
+
+ /* Clean up the region we want to draw to. */
+ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
+
+ /* Set the clip region because Xft is sometimes dirty. */
+ r.x = 0;
+ r.y = 0;
+ r.height = win.ch;
+ r.width = width;
+ XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
+
+ /* Render the glyphs. */
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+
+ /* Render underline and strikethrough. */
+ if (base.mode & ATTR_UNDERLINE) {
+ XftDrawRect(xw.draw, fg, winx, winy + win.cyo + dc.font.ascent + 1,
+ width, 1);
+ }
+
+ if (base.mode & ATTR_STRUCK) {
+ XftDrawRect(xw.draw, fg, winx, winy + win.cyo + 2 * dc.font.ascent / 3,
+ width, 1);
+ }
+
+ /* Reset clip to none. */
+ XftDrawSetClip(xw.draw, 0);
+}
+
+void
+xdrawglyph(Glyph g, int x, int y)
+{
+ int numspecs;
+ XftGlyphFontSpec spec;
+
+ numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
+ xdrawglyphfontspecs(&spec, g, numspecs, x, y);
+}
+
+void
+xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
+{
+ Color drawcol;
+
+ /* remove the old cursor */
+ if (selected(ox, oy))
+ og.mode ^= ATTR_REVERSE;
+ xdrawglyph(og, ox, oy);
+
+ if (IS_SET(MODE_HIDE))
+ return;
+
+ /*
+ * Select the right color for the right mode.
+ */
+ g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE;
+
+ if (IS_SET(MODE_REVERSE)) {
+ g.mode |= ATTR_REVERSE;
+ g.bg = defaultfg;
+ if (selected(cx, cy)) {
+ drawcol = dc.col[defaultcs];
+ g.fg = defaultrcs;
+ } else {
+ drawcol = dc.col[defaultrcs];
+ g.fg = defaultcs;
+ }
+ } else {
+ if (selected(cx, cy)) {
+ g.fg = defaultfg;
+ g.bg = defaultrcs;
+ } else {
+ g.fg = defaultbg;
+ g.bg = defaultcs;
+ }
+ drawcol = dc.col[g.bg];
+ }
+
+ /* draw the new one */
+ if (IS_SET(MODE_FOCUSED)) {
+ switch (win.cursor) {
+ case 7: /* st extension: snowman (U+2603) */
+ g.u = 0x2603;
+ case 0: /* Blinking Block */
+ case 1: /* Blinking Block (Default) */
+ case 2: /* Steady Block */
+ xdrawglyph(g, cx, cy);
+ break;
+ case 3: /* Blinking Underline */
+ case 4: /* Steady Underline */
+ XftDrawRect(xw.draw, &drawcol,
+ borderpx + cx * win.cw,
+ borderpx + (cy + 1) * win.ch - \
+ cursorthickness,
+ win.cw, cursorthickness);
+ break;
+ case 5: /* Blinking bar */
+ case 6: /* Steady bar */
+ XftDrawRect(xw.draw, &drawcol,
+ borderpx + cx * win.cw,
+ borderpx + cy * win.ch,
+ cursorthickness, win.ch);
+ break;
+ }
+ } else {
+ XftDrawRect(xw.draw, &drawcol,
+ borderpx + cx * win.cw,
+ borderpx + cy * win.ch,
+ win.cw - 1, 1);
+ XftDrawRect(xw.draw, &drawcol,
+ borderpx + cx * win.cw,
+ borderpx + cy * win.ch,
+ 1, win.ch - 1);
+ XftDrawRect(xw.draw, &drawcol,
+ borderpx + (cx + 1) * win.cw - 1,
+ borderpx + cy * win.ch,
+ 1, win.ch - 1);
+ XftDrawRect(xw.draw, &drawcol,
+ borderpx + cx * win.cw,
+ borderpx + (cy + 1) * win.ch - 1,
+ win.cw, 1);
+ }
+}
+
+void
+xsetenv(void)
+{
+ char buf[sizeof(long) * 8 + 1];
+
+ snprintf(buf, sizeof(buf), "%lu", xw.win);
+ setenv("WINDOWID", buf, 1);
+}
+
+void
+xsettitle(char *p)
+{
+ XTextProperty prop;
+ DEFAULT(p, opt_title);
+
+ Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
+ &prop);
+ XSetWMName(xw.dpy, xw.win, &prop);
+ XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname);
+ XFree(prop.value);
+}
+
+int
+xstartdraw(void)
+{
+ return IS_SET(MODE_VISIBLE);
+}
+
+void
+xdrawline(Line line, int x1, int y1, int x2)
+{
+ int i, x, ox, numspecs;
+ Glyph base, new;
+ XftGlyphFontSpec *specs = xw.specbuf;
+
+ numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
+ i = ox = 0;
+ for (x = x1; x < x2 && i < numspecs; x++) {
+ new = line[x];
+ if (new.mode == ATTR_WDUMMY)
+ continue;
+ if (selected(x, y1))
+ new.mode ^= ATTR_REVERSE;
+ if (i > 0 && ATTRCMP(base, new)) {
+ xdrawglyphfontspecs(specs, base, i, ox, y1);
+ specs += i;
+ numspecs -= i;
+ i = 0;
+ }
+ if (i == 0) {
+ ox = x;
+ base = new;
+ }
+ i++;
+ }
+ if (i > 0)
+ xdrawglyphfontspecs(specs, base, i, ox, y1);
+}
+
+void
+xfinishdraw(void)
+{
+ XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w,
+ win.h, 0, 0);
+ XSetForeground(xw.dpy, dc.gc,
+ dc.col[IS_SET(MODE_REVERSE)?
+ defaultfg : defaultbg].pixel);
+}
+
+void
+expose(XEvent *ev)
+{
+ redraw();
+}
+
+void
+visibility(XEvent *ev)
+{
+ XVisibilityEvent *e = &ev->xvisibility;
+
+ MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE);
+}
+
+void
+unmap(XEvent *ev)
+{
+ win.mode &= ~MODE_VISIBLE;
+}
+
+void
+xsetpointermotion(int set)
+{
+ MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
+ XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
+}
+
+void
+xsetmode(int set, unsigned int flags)
+{
+ int mode = win.mode;
+ MODBIT(win.mode, set, flags);
+ if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE))
+ redraw();
+}
+
+int
+xsetcursor(int cursor)
+{
+ DEFAULT(cursor, 1);
+ if (!BETWEEN(cursor, 0, 6))
+ return 1;
+ win.cursor = cursor;
+ return 0;
+}
+
+void
+xseturgency(int add)
+{
+ XWMHints *h = XGetWMHints(xw.dpy, xw.win);
+
+ MODBIT(h->flags, add, XUrgencyHint);
+ XSetWMHints(xw.dpy, xw.win, h);
+ XFree(h);
+}
+
+void
+xbell(void)
+{
+ if (!(IS_SET(MODE_FOCUSED)))
+ xseturgency(1);
+ if (bellvolume)
+ XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL);
+}
+
+void
+focus(XEvent *ev)
+{
+ XFocusChangeEvent *e = &ev->xfocus;
+
+ if (e->mode == NotifyGrab)
+ return;
+
+ if (ev->type == FocusIn) {
+ XSetICFocus(xw.xic);
+ win.mode |= MODE_FOCUSED;
+ xseturgency(0);
+ if (IS_SET(MODE_FOCUS))
+ ttywrite("\033[I", 3, 0);
+ } else {
+ XUnsetICFocus(xw.xic);
+ win.mode &= ~MODE_FOCUSED;
+ if (IS_SET(MODE_FOCUS))
+ ttywrite("\033[O", 3, 0);
+ }
+}
+
+int
+match(uint mask, uint state)
+{
+ return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
+}
+
+char*
+kmap(KeySym k, uint state)
+{
+ Key *kp;
+ int i;
+
+ /* Check for mapped keys out of X11 function keys. */
+ for (i = 0; i < LEN(mappedkeys); i++) {
+ if (mappedkeys[i] == k)
+ break;
+ }
+ if (i == LEN(mappedkeys)) {
+ if ((k & 0xFFFF) < 0xFD00)
+ return NULL;
+ }
+
+ for (kp = key; kp < key + LEN(key); kp++) {
+ if (kp->k != k)
+ continue;
+
+ if (!match(kp->mask, state))
+ continue;
+
+ if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0)
+ continue;
+ if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2)
+ continue;
+
+ if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0)
+ continue;
+
+ return kp->s;
+ }
+
+ return NULL;
+}
+
+void
+kpress(XEvent *ev)
+{
+ XKeyEvent *e = &ev->xkey;
+ KeySym ksym;
+ char buf[32], *customkey;
+ int len;
+ Rune c;
+ Status status;
+ Shortcut *bp;
+
+ if (IS_SET(MODE_KBDLOCK))
+ return;
+
+ len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status);
+ /* 1. shortcuts */
+ for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
+ if (ksym == bp->keysym && match(bp->mod, e->state)) {
+ bp->func(&(bp->arg));
+ return;
+ }
+ }
+
+ /* 2. custom keys from config.h */
+ if ((customkey = kmap(ksym, e->state))) {
+ ttywrite(customkey, strlen(customkey), 1);
+ return;
+ }
+
+ /* 3. composed string from input method */
+ if (len == 0)
+ return;
+ if (len == 1 && e->state & Mod1Mask) {
+ if (IS_SET(MODE_8BIT)) {
+ if (*buf < 0177) {
+ c = *buf | 0x80;
+ len = utf8encode(c, buf);
+ }
+ } else {
+ buf[1] = buf[0];
+ buf[0] = '\033';
+ len = 2;
+ }
+ }
+ ttywrite(buf, len, 1);
+}
+
+
+void
+cmessage(XEvent *e)
+{
+ /*
+ * See xembed specs
+ * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
+ */
+ if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) {
+ if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) {
+ win.mode |= MODE_FOCUSED;
+ xseturgency(0);
+ } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) {
+ win.mode &= ~MODE_FOCUSED;
+ }
+ } else if (e->xclient.data.l[0] == xw.wmdeletewin) {
+ ttyhangup();
+ exit(0);
+ }
+}
+
+void
+resize(XEvent *e)
+{
+ if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
+ return;
+
+ cresize(e->xconfigure.width, e->xconfigure.height);
+}
+
+void
+run(void)
+{
+ XEvent ev;
+ int w = win.w, h = win.h;
+ fd_set rfd;
+ int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0;
+ int ttyfd;
+ struct timespec drawtimeout, *tv = NULL, now, last, lastblink;
+ long deltatime;
+
+ /* Waiting for window mapping */
+ do {
+ XNextEvent(xw.dpy, &ev);
+ /*
+ * This XFilterEvent call is required because of XOpenIM. It
+ * does filter out the key event and some client message for
+ * the input method too.
+ */
+ if (XFilterEvent(&ev, None))
+ continue;
+ if (ev.type == ConfigureNotify) {
+ w = ev.xconfigure.width;
+ h = ev.xconfigure.height;
+ }
+ } while (ev.type != MapNotify);
+
+ ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd);
+ cresize(w, h);
+
+ clock_gettime(CLOCK_MONOTONIC, &last);
+ lastblink = last;
+
+ for (xev = actionfps;;) {
+ FD_ZERO(&rfd);
+ FD_SET(ttyfd, &rfd);
+ FD_SET(xfd, &rfd);
+
+ if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
+ if (errno == EINTR)
+ continue;
+ die("select failed: %s\n", strerror(errno));
+ }
+ if (FD_ISSET(ttyfd, &rfd)) {
+ ttyread();
+ if (blinktimeout) {
+ blinkset = tattrset(ATTR_BLINK);
+ if (!blinkset)
+ MODBIT(win.mode, 0, MODE_BLINK);
+ }
+ }
+
+ if (FD_ISSET(xfd, &rfd))
+ xev = actionfps;
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ drawtimeout.tv_sec = 0;
+ drawtimeout.tv_nsec = (1000 * 1E6)/ xfps;
+ tv = &drawtimeout;
+
+ dodraw = 0;
+ if (blinktimeout && TIMEDIFF(now, lastblink) > blinktimeout) {
+ tsetdirtattr(ATTR_BLINK);
+ win.mode ^= MODE_BLINK;
+ lastblink = now;
+ dodraw = 1;
+ }
+ deltatime = TIMEDIFF(now, last);
+ if (deltatime > 1000 / (xev ? xfps : actionfps)) {
+ dodraw = 1;
+ last = now;
+ }
+
+ if (dodraw) {
+ while (XPending(xw.dpy)) {
+ XNextEvent(xw.dpy, &ev);
+ if (XFilterEvent(&ev, None))
+ continue;
+ if (handler[ev.type])
+ (handler[ev.type])(&ev);
+ }
+
+ draw();
+ XFlush(xw.dpy);
+
+ if (xev && !FD_ISSET(xfd, &rfd))
+ xev--;
+ if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
+ if (blinkset) {
+ if (TIMEDIFF(now, lastblink) \
+ > blinktimeout) {
+ drawtimeout.tv_nsec = 1000;
+ } else {
+ drawtimeout.tv_nsec = (1E6 * \
+ (blinktimeout - \
+ TIMEDIFF(now,
+ lastblink)));
+ }
+ drawtimeout.tv_sec = \
+ drawtimeout.tv_nsec / 1E9;
+ drawtimeout.tv_nsec %= (long)1E9;
+ } else {
+ tv = NULL;
+ }
+ }
+ }
+ }
+}
+
+int
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
+{
+ char **sdst = dst;
+ int *idst = dst;
+ float *fdst = dst;
+
+ char fullname[256];
+ char fullclass[256];
+ char *type;
+ XrmValue ret;
+
+ snprintf(fullname, sizeof(fullname), "%s.%s",
+ opt_name ? opt_name : "st", name);
+ snprintf(fullclass, sizeof(fullclass), "%s.%s",
+ opt_class ? opt_class : "St", name);
+ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
+
+ XrmGetResource(db, fullname, fullclass, &type, &ret);
+ if (ret.addr == NULL || strncmp("String", type, 64))
+ return 1;
+
+ switch (rtype) {
+ case STRING:
+ *sdst = ret.addr;
+ break;
+ case INTEGER:
+ *idst = strtoul(ret.addr, NULL, 10);
+ break;
+ case FLOAT:
+ *fdst = strtof(ret.addr, NULL);
+ break;
+ }
+ return 0;
+}
+
+void
+config_init(void)
+{
+ char *resm;
+ XrmDatabase db;
+ ResourcePref *p;
+
+ XrmInitialize();
+ resm = XResourceManagerString(xw.dpy);
+ if (!resm)
+ return;
+
+ db = XrmGetStringDatabase(resm);
+ for (p = resources; p < resources + LEN(resources); p++)
+ resource_load(db, p->name, p->type, p->dst);
+}
+
+void
+usage(void)
+{
+ die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]"
+ " [-n name] [-o file]\n"
+ " [-T title] [-t title] [-w windowid]"
+ " [[-e] command [args ...]]\n"
+ " %s [-aiv] [-c class] [-f font] [-g geometry]"
+ " [-n name] [-o file]\n"
+ " [-T title] [-t title] [-w windowid] -l line"
+ " [stty_args ...]\n", argv0, argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ xw.l = xw.t = 0;
+ xw.isfixed = False;
+ win.cursor = cursorshape;
+
+ ARGBEGIN {
+ case 'a':
+ allowaltscreen = 0;
+ break;
+ case 'c':
+ opt_class = EARGF(usage());
+ break;
+ case 'e':
+ if (argc > 0)
+ --argc, ++argv;
+ goto run;
+ case 'f':
+ opt_font = EARGF(usage());
+ break;
+ case 'g':
+ xw.gm = XParseGeometry(EARGF(usage()),
+ &xw.l, &xw.t, &cols, &rows);
+ break;
+ case 'i':
+ xw.isfixed = 1;
+ break;
+ case 'o':
+ opt_io = EARGF(usage());
+ break;
+ case 'l':
+ opt_line = EARGF(usage());
+ break;
+ case 'n':
+ opt_name = EARGF(usage());
+ break;
+ case 't':
+ case 'T':
+ opt_title = EARGF(usage());
+ break;
+ case 'w':
+ opt_embed = EARGF(usage());
+ break;
+ case 'v':
+ die("%s " VERSION " (c) 2010-2016 st engineers\n", argv0);
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+run:
+ if (argc > 0) /* eat all remaining arguments */
+ opt_cmd = argv;
+
+ if (!opt_title)
+ opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0];
+
+ setlocale(LC_CTYPE, "");
+ XSetLocaleModifiers("");
+
+ if(!(xw.dpy = XOpenDisplay(NULL)))
+ die("Can't open display\n");
+
+ config_init();
+ cols = MAX(cols, 1);
+ rows = MAX(rows, 1);
+ tnew(cols, rows);
+ xinit(cols, rows);
+ xsetenv();
+ selinit();
+ run();
+
+ return 0;
+}
diff --git a/st-master/x.c.rej b/st-master/x.c.rej
new file mode 100644
index 0000000..5e0bebe
--- /dev/null
+++ b/st-master/x.c.rej
@@ -0,0 +1,122 @@
+--- x.c
++++ x.c
+@@ -14,6 +14,7 @@
+ #include <X11/keysym.h>
+ #include <X11/Xft/Xft.h>
+ #include <X11/XKBlib.h>
++#include <X11/Xresource.h>
+
+ static char *argv0;
+ #include "arg.h"
+@@ -43,6 +44,19 @@ typedef struct {
+ signed char appcursor; /* application cursor */
+ } Key;
+
++/* Xresources preferences */
++enum resource_type {
++ STRING = 0,
++ INTEGER = 1,
++ FLOAT = 2
++};
++
++typedef struct {
++ char *name;
++ enum resource_type type;
++ void *dst;
++} ResourcePref;
++
+ /* X modifiers */
+ #define XK_ANY_MOD UINT_MAX
+ #define XK_NO_MOD 0
+@@ -783,8 +797,8 @@ xclear(int x1, int y1, int x2, int y2)
+ void
+ xhints(void)
+ {
+- XClassHint class = {opt_name ? opt_name : termname,
+- opt_class ? opt_class : termname};
++ XClassHint class = {opt_name ? opt_name : "st",
++ opt_class ? opt_class : "St"};
+ XWMHints wm = {.flags = InputHint, .input = 1};
+ XSizeHints *sizeh;
+
+@@ -1005,8 +1019,6 @@ xinit(int cols, int rows)
+ pid_t thispid = getpid();
+ XColor xmousefg, xmousebg;
+
+- if (!(xw.dpy = XOpenDisplay(NULL)))
+- die("can't open display\n");
+ xw.scr = XDefaultScreen(xw.dpy);
+ xw.vis = XDefaultVisual(xw.dpy, xw.scr);
+
+@@ -1870,6 +1882,59 @@ run(void)
+ }
+ }
+
++int
++resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
++{
++ char **sdst = dst;
++ int *idst = dst;
++ float *fdst = dst;
++
++ char fullname[256];
++ char fullclass[256];
++ char *type;
++ XrmValue ret;
++
++ snprintf(fullname, sizeof(fullname), "%s.%s",
++ opt_name ? opt_name : "st", name);
++ snprintf(fullclass, sizeof(fullclass), "%s.%s",
++ opt_class ? opt_class : "St", name);
++ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
++
++ XrmGetResource(db, fullname, fullclass, &type, &ret);
++ if (ret.addr == NULL || strncmp("String", type, 64))
++ return 1;
++
++ switch (rtype) {
++ case STRING:
++ *sdst = ret.addr;
++ break;
++ case INTEGER:
++ *idst = strtoul(ret.addr, NULL, 10);
++ break;
++ case FLOAT:
++ *fdst = strtof(ret.addr, NULL);
++ break;
++ }
++ return 0;
++}
++
++void
++config_init(void)
++{
++ char *resm;
++ XrmDatabase db;
++ ResourcePref *p;
++
++ XrmInitialize();
++ resm = XResourceManagerString(xw.dpy);
++ if (!resm)
++ return;
++
++ db = XrmGetStringDatabase(resm);
++ for (p = resources; p < resources + LEN(resources); p++)
++ resource_load(db, p->name, p->type, p->dst);
++}
++
+ void
+ usage(void)
+ {
+@@ -1943,6 +2008,11 @@ run:
+
+ setlocale(LC_CTYPE, "");
+ XSetLocaleModifiers("");
++
++ if(!(xw.dpy = XOpenDisplay(NULL)))
++ die("Can't open display\n");
++
++ config_init();
+ cols = MAX(cols, 1);
+ rows = MAX(rows, 1);
+ tnew(cols, rows);
diff --git a/surfraw.conf b/surfraw.conf
new file mode 100644
index 0000000..119fee8
--- /dev/null
+++ b/surfraw.conf
@@ -0,0 +1,2 @@
+SURFRAW_text_browser=/usr/bin/w3m
+SURFRAW_graphical=no
diff --git a/taskopenrc b/taskopenrc
new file mode 100644
index 0000000..17add9c
--- /dev/null
+++ b/taskopenrc
@@ -0,0 +1,71 @@
+
+#BROWSER='xdg-open $FILE &>/dev/null'
+EDITOR='vim'
+#FILE_CMD='xdg-open'
+TASKBIN='task'
+
+# If you sync tasks NOTES_FOLDER should be a location that syncs and is available to
+# other computers, i.e. /users/dropbox/tasknotes
+# NOTES_FOLDER to store notes in, must already exist!
+NOTES_FOLDER="$HOME/tasknotes/"
+
+# Preferred extension for tasknotes
+NOTES_EXT=".md"
+
+# Path to notes file. UUID will be replaced with the actual uuid of
+# the task. If NOTES_CMD
+# Default is: ${NOTES_FOLDER}UUID${NOTES_EXT}
+#NOTES_FILE="$HOME/tasknotes/UUID.txt"
+
+# Command that opens notes. UUID will be replaced with the actual uuid of
+# the task.
+# Default is: $EDITOR $NOTES_FILE
+#NOTES_CMD="vim "$HOME/tasknotes/$UUID.txt""
+
+# Specify the default sorting.
+# Default is taskwarrior's default sorting, i.e. sorting by task IDs.
+#DEFAULT_SORT="urgency-,label,annot"
+
+# Apply a default taskwarrior filter in order to exclude certain tasks.
+# Default is: status.is:pending
+#DEFAULT_FILTER=
+
+# Default command for '-i'
+# Default is: ls -la
+#DEFAULT-i="ls -la"
+
+# Add some paths to the taskopen's PATH variable
+#PATH_EXT=/path/to/taskopen/scripts
+PATH_EXT=/usr/local/share/taskopen/scripts
+
+# Regular expression that referes to the NOTES_FILE.
+# Default is: Notes
+#NOTES_REGEX="Notes"
+
+# Regular expression that identifies annotations openable by BROWSER.
+# Default is: www|http
+#BROWSER_REGEX="www|http"
+
+# Regular expression that identifies file paths in annotations. Will be opened by xdg-open.
+# Default is: \.|\/|~
+#FILE_REGEX="\.|\/|~"
+
+# Regular expression that identifies a text annotation. Automatically triggers raw edit mode like '-r'.
+#TEXT_REGEX=".*"
+
+# Custom regular expression that specifies annotations passed to CUSTOM1_CMD, e.g:
+#CUSTOM1_REGEX="Message-[Ii][Dd]:|message:"
+#CUSTOM1_CMD="muttjumpwrapper"
+
+# Custom regular expression that specifies annotations passed to CUSTOM2_CMD.
+#CUSTOM2_REGEX=""
+#CUSTOM2_CMD=""
+
+# Execute an arbitrary command if there is no annotation available. The corresponding taskwarrior IDs will
+# be passed as arguments, e.g. "addnote 21 42"
+#NO_ANNOTATION_HOOK=addnote
+
+# Make additional taskwarrior attributes available as sort keys and environment variables.
+# E.g. TASK_ATTRIBUTES="project,tags" allows to sort by "task_project" or "task_tags" and to use
+# "$TASK_PROJECT" or "$TASK_TAGS" within your (custom) commands.
+#TASK_ATTRIBUTES=""
diff --git a/taskrc b/taskrc
new file mode 100644
index 0000000..b4db914
--- /dev/null
+++ b/taskrc
@@ -0,0 +1,250 @@
+# [Created by task 2.5.1 5/22/2016 09:24:00]
+# Taskwarrior program configuration file.
+# For more documentation, see http://taskwarrior.org or try 'man task', 'man task-color',
+# 'man task-sync' or 'man taskrc'
+#
+# CALENDAR
+calendar.details=full
+calendar.holidays=sparse
+
+#
+#
+# Here is an example of entries that use the default, override and blank values
+# variable=foo -- By specifying a value, this overrides the default
+# variable= -- By specifying no value, this means no default
+# #variable=foo -- By commenting out the line, or deleting it, this uses the default
+
+# Use the command 'task show' to see all defaults and overrides
+#
+# HOLIDAYS
+#include /usr/share/doc/task/rc/holidays.en-GB.rc
+#include /usr/share/taskwarrior/holidays.en-GB.rc
+
+# Files
+data.location=~/.task
+
+
+# calendar
+weekstart=Monday
+
+# Color theme (uncomment one to use)
+#include /usr/share/doc/task/rc/light-16.theme
+#include /usr/share/taskwarrior/light-256.theme
+#include /usr/share/taskwarrior/dark-16.theme
+#include /usr/share/doc/task/rc/dark-256.theme
+#include /usr/share/doc/task/rc/dark-red-256.theme
+#include /usr/share/taskwarrior/dark-red-256.theme
+#include /usr/share/taskwarrior/dark-green-256.theme
+#include /usr/share/taskwarrior/dark-blue-256.theme
+#include /usr/share/taskwarrior/dark-violets-256.theme
+#include /usr/share/taskwarrior/dark-yellow-green.theme
+#include /usr/share/taskwarrior/dark-gray-256.theme
+#include /usr/share/taskwarrior/dark-gray-blue-256.theme
+#include /usr/share/taskwarrior/solarized-dark-256.theme
+#include /usr/share/taskwarrior/solarized-light-256.theme
+#include /usr/share/taskwarrior/no-color.theme
+#include /home/lemon/.task/solarized-16.theme
+#include /home/lemon/.task/solarized-dark-256.theme
+#
+# colour
+color.burndown.done=black on green
+color.burndown.pending=black on rgb510
+color.burndown.started=black on yellow
+color.calendar.due.today=on red
+color.calendar.overdue=bold red
+color.calendar.today=blue
+color.calendar.due=cyan
+color.blocked=underline grey10 on grey3
+color.blocking=color5
+color.due=
+color.tagged=
+#color=off
+
+# Task server - essential config!
+taskd.certificate=\/home\/lemon\/.task\/matt_lemon.cert.pem
+taskd.key=\/home\/lemon\/.task\/matt_lemon.key.pem
+taskd.ca=\/home\/lemon\/.task\/ca.cert.pem
+taskd.server=16693433.xyz:53589
+#taskd.trust=ignore hostname
+taskd.credentials=Public\/matt lemon\/65ed83f1-a2ec-48d2-ad74-9625cc58b030
+
+# Tasksh report stuff
+uda.reviewed.type=date
+uda.reviewed.label=Reviewed
+report._reviewed.description=Tasksh review report. Adjust the filter to your needs.
+report._reviewed.columns=uuid
+report._reviewed.sort=reviewed+,modified+
+report._reviewed.filter=( reviewed.none: or reviewed.before:now-1week ) and ( +PENDING or +WAITING )
+
+# Inbox report
+report.in.columns = id,description
+report.in.description = Inbox
+report.in.filter = status:pending limit:page (+in)
+report.in.labels = ID,Description
+
+# changing urgency of priorities
+urgency.uda.priority.L.coefficient=-1.8
+
+# some UDAs for me
+urgency.user.tag.trivial.coefficient=-3.0
+urgency.user.tag.bug.coefficient=+1.5
+urgency.user.tag.reference.coefficient=-3.2
+urgency.user.tag.idea.coefficient=-3.0
+urgency.user.project.Gmail.coefficient=-1
+urgency.user.tag.link.coefficient=-5.0
+urgency.user.tag.home.coefficient=+1.8
+urgency.user.tag.waiting.coefficient=-2.0
+# UDA for bash script (inspection_planning.sh)
+uda.wb.type=date
+uda.wb.label=Week Beginning
+
+# F*ck annotations having any effect on urgency!
+urgency.annotations.coefficient=0
+
+# Changing coefficients
+#urgency.annotations.coefficient=0.5
+urgency.tags.coefficient=0
+
+#urgency.project.coefficient=1
+#urgency.age.coefficient=1
+#urgency.due.coefficient=6.0
+
+# Colours
+#color.project.code.dbasik=green
+#color.tag.next=black on bright yellow
+#color.due.today=red on yellow
+#color.overdue=bold red
+##color.active=bold yellow
+#color.calendar.weekend=bold
+#color.scheduled=bold magenta
+#color.tag.dft=white on rgb100
+#color.tag.prep=rgb150 on rgb020
+#color.alternate=on grey2
+#color.tag.bug=red on cyan
+#rule.color.merge=no
+
+# 2019 HOLIDAYS
+holiday.en-GB1.name=New Year's Day
+holiday.en-GB1.date=20190101
+holiday.en-GB2.name=Good Friday
+holiday.en-GB2.date=20190419
+holiday.en-GB2.name=Easter Sunday
+holiday.en-GB2.date=20190421
+holiday.en-GB3.name=Easter Monday
+holiday.en-GB3.date=20190422
+holiday.en-GB4.name=Early May Bank Holiday
+holiday.en-GB4.date=20190506
+holiday.en-GB5.name=Spring Bank Holiday
+holiday.en-GB5.date=20190527
+holiday.en-GB6.name=August Bank Holiday
+holiday.en-GB6.date=20190826
+holiday.en-GB7.name=Christmas Day
+holiday.en-GB7.date=20191225
+holiday.en-GB8.name=Boxing Day
+holiday.en-GB8.date=20191226
+holiday.en-GB9.name=New Year's Day
+holiday.en-GB9.date=20200101
+
+# next report ("task")
+
+# Don't ask for confirmation
+confirmation=no
+
+# RECURRANCE MUST BE ONE FOR ONE MACHINE
+recurrence=yes
+recurrence.limit=1
+
+# Context
+context.code=project:code
+context.work=-code +dft
+context.nocode=(project.not:code and project.not:audible)
+context.home=(project.not:code and project.not:audible) -dft
+context.bcompiler=(project:code.bcompiler-engine or code.bcompiler or project:'code.hammerheadlemon/bcompiler-engine' or project:'code.hammerheadelemon/bcompiler')
+context.listen=+listen
+
+
+# REPORTS
+report.waiting.columns=id,start.active,entry.age,depends.indicator,priority,project,tags,recur.indicator,wait,wait.remaining,scheduled,due,until,description.count
+
+
+report.all.column=id,status.short,uuid.short,start.active,entry.age,end.age,depends.indicator,priority,project.parent,tags.count,recur.indicator,wait.remaining,scheduled.remaining,due,until,remaining,description
+report.all.labels=ID,St,UUID,A,Age,Done,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description
+report.all.description="All Tasks (amended)"
+reprot.all.sort=entry-
+
+# how to filter out a project from next - but this also means you can't filter
+# it at all
+#report.next.columns=id,start.age,entry.age,depends,priority,project,tags.count,recur,scheduled.countdown,due.relative,until.remaining,description.count,urgency
+#report.next.filter=status:pending and (+next or scheduled.before:today or due.before:today or scheduled.today or due.today)
+#report.next.filter=project.not:code.bcompiler status:pending limit:page
+
+# mlscheduled
+report.ml_scheduled.description='Modified list of scheduled tasks'
+report.ml_scheduled.columns=id,project.indented,tags.count,scheduled.formatted,due,description.count,priority,urgency
+report.ml_scheduled.labels=ID,Project,Tags,Scheduled,Due,Description,Priority,Urgency
+report.ml_scheduled.sort=scheduled+/,priority-
+report.ml_scheduled.filter=status:pending and +SCHEDULED and -BLOCKED
+
+
+# inspection_prep
+report.ml_inspection_prep.description="List of all tasks related to inspection planning"
+report.ml_inspection_prep.columns=id,project.indented,description.count,scheduled,due
+report.ml_inspection_prep.labels=ID,Project,Task,Scheduled,Due
+report.ml_inspection_prep.filter=+inspection -inspection_followup status:pending
+report.ml_inspection_prep.sort=project+/,due+,scheduled+
+
+# inspection_followup
+report.ml_inspection_followup.description="List of all tasks related to inspection follow-up"
+report.ml_inspection_followup.columns=id,project.indented,description.count,scheduled,due
+report.ml_inspection_followup.labels=ID,Project,Task,Scheduled,Due
+report.ml_inspection_followup.filter=+inspection_followup status:pending
+
+# upcoming
+report.ml_upcoming.description=Pending and Waiting coming up
+report.ml_upcoming.columns=id,status,wait.remaining,entry,tags,scheduled,due,description.count
+report.ml_upcoming.labels=ID,Status,Wait,Age,Tags,Sched,Due,Description
+report.ml_upcoming.sort=status+,wait+,scheduled+,due+
+report.ml_upcoming.filter=status:pending or status:waiting
+
+# nextmonth
+report.ml_nextmonth.description=Next month
+report.ml_nextmonth.columns=id,status,wait.remaining,entry,tags,scheduled,due,description.count
+report.ml_nextmonth.labels=ID,Status,Wait,Age,Tags,Sched,Due,Description
+report.ml_nextmonth.sort=status+,wait+,scheduled+,due+
+report.ml_nextmonth.filter=scheduled.after:yesterday and scheduled.before:4weeks
+#context=work
+
+# completed in last week
+report.ml_comp_lastweek.description=Tasks completed in the last week
+report.ml_comp_lastweek.columns=uuid.short,project.full,description.combined,end.relative
+report.ml_comp_lastweek.labels=UUID,Project,Task,Completed
+report.ml_comp_lastweek.sort=end-
+report.ml_comp_lastweek.filter=end.after:today-7day
+
+# completed in last month
+report.ml_comp_lastmonth.description=Tasks completed in the last month
+report.ml_comp_lastmonth.columns=uuid.short,project.full,description.combined,end.relative
+report.ml_comp_lastmonth.labels=UUID,Project,Task,Completed
+report.ml_comp_lastmonth.sort=end-
+report.ml_comp_lastmonth.filter=end.after:today-31day
+
+# deleted in the last month
+report.ml_deleted_last_month.description=Tasks deleted in last month
+report.ml_deleted_last_month.columns=status.short,uuid.short,project.full,tags.list,description.count,end.formatted
+report.ml_deleted_last_month.labels=Status,UUID,Project,Tags,Description,Deleted
+report.ml_deleted_last_month.sort=end-
+report.ml_deleted_last_month.filter=end.after:today-30day status:deleted
+
+
+# all projects used
+# THIS IS THE COMMAND THAT WORKS: task rc.list.all.projects=1 projects
+# BUT DOESN'T WORK HERE - NOT TRIED TOO HARD
+#report.ml_all_projects_used.description=All projects
+#report.ml_all_projects_used.columns=project.full
+#report.ml_all_projects_used.labels=Project
+#report.ml_all_projects_used.sort=project+
+#report.ml_all_projects_used.filter=rc.list.all.projects=1 projects
+
+# regex on
+regex=on
+context=home
diff --git a/taskrc-termux b/taskrc-termux
new file mode 100644
index 0000000..ca89527
--- /dev/null
+++ b/taskrc-termux
@@ -0,0 +1,142 @@
+# [Created by task 2.5.1 5/22/2016 09:24:00]
+# Taskwarrior program configuration file.
+# For more documentation, see http://taskwarrior.org or try 'man task', 'man task-color',
+# 'man task-sync' or 'man taskrc'
+#
+# CALENDAR
+calendar.details=full
+calendar.holidays=sparse
+
+# Here is an example of entries that use the default, override and blank values
+# variable=foo -- By specifying a value, this overrides the default
+# variable= -- By specifying no value, this means no default
+# #variable=foo -- By commenting out the line, or deleting it, this uses the default
+
+# Use the command 'task show' to see all defaults and overrides
+#
+# HOLIDAYS
+#include /usr/local/share/doc/task/rc/holidays.en-GB.rc
+
+# Files
+data.location=~/.task
+
+
+# calendar
+weekstart=Monday
+
+# Bugwarrior UDAs
+uda.bitbuckettitle.type=string
+uda.bitbuckettitle.label=Bitbucket Title
+uda.bitbucketurl.type=string
+uda.bitbucketurl.label=Bitbucket URL
+uda.bitbucketid.type=string
+uda.bitbucketid.label=Bitbucket Issue ID
+# END Bugwarrior UDAs
+#
+
+
+# Color theme (uncomment one to use)
+#include /usr/share/taskwarrior/light-16.theme
+#include /usr/share/taskwarrior/light-256.theme
+#include /usr/share/taskwarrior/dark-16.theme
+#include /usr/share/taskwarrior/dark-256.theme
+#include /usr/share/taskwarrior/dark-red-256.theme
+#include /usr/share/taskwarrior/dark-green-256.theme
+#include /usr/share/taskwarrior/dark-blue-256.theme
+#include /usr/share/taskwarrior/dark-violets-256.theme
+#include /usr/share/taskwarrior/dark-yellow-green.theme
+#include /usr/share/taskwarrior/dark-gray-256.theme
+#include /usr/share/taskwarrior/dark-gray-blue-256.theme
+#include /usr/share/taskwarrior/solarized-dark-256.theme
+#include /usr/share/taskwarrior/solarized-light-256.theme
+#include /usr/share/taskwarrior/no-color.theme
+#include /home/lemon/.task/solarized-16.theme
+include /data/data/com.termux/files/home/.task/no-color.theme
+
+taskd.certificate=\/data/data/com.termux/files/home/.task/Matthew_Lemon.cert.pem
+taskd.key=\/data/data/com.termux/files/home/.task/Matthew_Lemon.key.pem
+taskd.ca=\/data/data/com.termux/files/home/.task/ca.cert.pem
+taskd.server=crocusnedloyd.online:53589
+#taskd.trust=ignore hostname
+taskd.credentials=Public\/Matthew Lemon\/ead2f3ff-f538-4865-8829-62a4a119ade9
+urgency.user.tag.later.coefficient=-6.0
+color=on
+#color.project.Work=bold yellow
+uda.reviewed.type=date
+uda.reviewed.label=Reviewed
+report._reviewed.description=Tasksh review report. Adjust the filter to your needs.
+report._reviewed.columns=uuid
+report._reviewed.sort=reviewed+,modified+
+report._reviewed.filter=( reviewed.none: or reviewed.before:now-1week ) and ( +PENDING or +WAITING )
+
+#colours
+color.due.today=black on cyan
+color.scheduled=green
+color.overdue=bold red
+color.active=bold yellow
+color.tag.next=black on bright yellow
+rule.color.merge=no
+
+# Contexts
+context.code=project:code
+context.work=-code +dft
+context.home=+home or +tech or +link or +joanna or +sophie or +harvey
+context.nocode=project.not:code
+context=nocode
+
+# changing urgency of priorities
+urgency.uda.priority.L.coefficient=-1.8
+#
+# Bugwarrior UDAs
+uda.gitlabduedate.type=date
+uda.gitlabduedate.label=Gitlab Due Date
+uda.gitlaburl.type=string
+uda.gitlaburl.label=Gitlab URL
+uda.gitlabwip.type=numeric
+uda.gitlabwip.label=Gitlab MR Work-In-Progress Flag
+uda.gitlabstate.type=string
+uda.gitlabstate.label=Gitlab Issue/MR State
+uda.gitlabauthor.type=string
+uda.gitlabauthor.label=Gitlab Author
+uda.bitbucketid.type=numeric
+uda.bitbucketid.label=Bitbucket Issue ID
+uda.gitlabassignee.type=string
+uda.gitlabassignee.label=Gitlab Assignee
+uda.gitlabupdatedat.type=date
+uda.gitlabupdatedat.label=Gitlab Updated
+uda.gitlabtype.type=string
+uda.gitlabtype.label=Gitlab Type
+uda.bitbuckettitle.type=string
+uda.bitbuckettitle.label=Bitbucket Title
+uda.gitlabdownvotes.type=numeric
+uda.gitlabdownvotes.label=Gitlab Downvotes
+uda.gitlabupvotes.type=numeric
+uda.gitlabupvotes.label=Gitlab Upvotes
+uda.bitbucketurl.type=string
+uda.bitbucketurl.label=Bitbucket URL
+uda.gitlabcreatedon.type=date
+uda.gitlabcreatedon.label=Gitlab Created
+uda.gitlabmilestone.type=string
+uda.gitlabmilestone.label=Gitlab Milestone
+uda.gitlabtitle.type=string
+uda.gitlabtitle.label=Gitlab Title
+uda.gitlabdescription.type=string
+uda.gitlabdescription.label=Gitlab Description
+uda.gitlabnumber.type=numeric
+uda.gitlabnumber.label=Gitlab Issue/MR #
+uda.gitlabrepo.type=string
+uda.gitlabrepo.label=Gitlab Repo Slug
+# END Bugwarrior UDAs
+urgency.tags.coefficient=0
+urgency.annotations.coefficient=0
+urgency.project.coefficient=0
+recurrence=0
+
+# tiny report
+report.short.description=Report suitable for termux
+report.short.labels=Id,Description
+report.short.columns=id,description.truncated_count
+report.short.sort=urgency-
+report.short.filter=status:pending
+
+default.command=short
diff --git a/tmux.conf b/tmux.conf
new file mode 100644
index 0000000..a6c0317
--- /dev/null
+++ b/tmux.conf
@@ -0,0 +1,154 @@
+# unbind some default keybindings
+unbind C-b
+
+# command sequence for nested tmux sessions
+bind-key a send-prefix
+
+# set prefix key to ctrl-a
+set -g prefix C-a
+
+# lower command delay
+set -sg escape-time 1
+
+# force tmux to use xterm
+#set -g default-terminal "xterm-256color"
+#set -g default-terminal "tmux-256color"
+set -g default-terminal "screen-256color"
+
+# set from advice in neovim :checkhealth
+set-option -sa terminal-overrides ',screen-256color:RGB'
+
+# start first window and pane at 1, not zero
+set -g base-index 1
+set -g pane-base-index 1
+
+# bind r to reloading the config file
+bind r source-file ~/.tmux.conf \; display "Reloaded tmux config file."
+
+# pass through a ctrl-a if you press it twice
+bind C-a send-prefix
+
+# better mnemonics for splitting panes!
+bind | split-window -h
+bind - split-window -v
+
+# vim / xmonad style bindings for pane movement
+bind -r h select-pane -L
+bind -r j select-pane -D
+bind -r k select-pane -U
+bind -r l select-pane -R
+
+# vim / xmonad style bindings for window movement
+bind -r C-h select-window -t :-
+bind -r C-l select-window -t :+
+
+
+# shift-movement keys will resize panes
+bind -r H resize-pane -L 5
+bind -r J resize-pane -D 5
+bind -r K resize-pane -U 5
+bind -r L resize-pane -R 5
+
+# disable mouse support (at least while we're learning)
+# setw -g mode-mouse off
+# set -g mouse-select-pane off
+# set -g mouse-resize-pane off
+# set -g mouse-select-window off
+#
+# copy and paste
+unbind p
+bind p paste-buffer
+#bind -t vi-copy 'v' begin-selection
+#bind -t vi-copy 'y' copy-selection
+
+# fiddle with colors of status bar
+#set -g status-position bottom
+#set -g status-style "bg=colour1"
+#set -g status-style "fg=colour137"
+##set -g status-fg colour137
+##set -g status-attr dim
+##set -g status-left ''
+#set -g status-left-length 30
+#set -g status-right '#[fg=colour233,bg=colour241,bold] %d/%m #[fg=colour233,bg=colour245,bold] %H:%M:%S '
+##set -g status-right-length 5
+##set -g status-left-length 20
+##
+##setw -g window-status-current-style "fg=colour81"
+##setw -g window-status-current-bg colour238
+##setw -g window-status-current-style bold
+#setw -g window-status-current-format ' #[bg=colour237]#I#[fg=colour250]:#[fg=colour255]#[bg=colour237]#W#[fg=colour50]#F '
+##
+#setw -g window-status-style "fg=colour61"
+#setw -g window-status-style "bg=colour235"
+#setw -g window-status-attr none
+#setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F '
+#
+#setw -g window-status-bell-attr bold
+#setw -g window-status-bell-fg colour255
+#setw -g window-status-bell-bg colour1
+##
+## fuck with border colours
+#set -g pane-border-fg yellow
+#set -g pane-active-border-fg red
+#
+#
+## fiddle with colors of inactive windows
+#setw -g window-status-fg cyan
+
+# vim mode keys
+setw -g mode-keys vi
+
+#
+## Smart pane switching with awareness of Vim splits.
+## See: https://github.com/christoomey/vim-tmux-navigator
+#is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
+# | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
+#bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
+#bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
+#bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
+#bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
+#tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
+#if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
+# "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'"
+#if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
+# "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'"
+#
+#bind-key -T copy-mode-vi 'C-h' select-pane -L
+#bind-key -T copy-mode-vi 'C-j' select-pane -D
+#bind-key -T copy-mode-vi 'C-k' select-pane -U
+#bind-key -T copy-mode-vi 'C-l' select-pane -R
+#bind-key -T copy-mode-vi 'C-\' select-pane -l
+#
+#
+# try different, vimlike copy-mode
+unbind [
+bind Escape copy-mode
+unbind p
+bind p paste-buffer
+#bind-key -t vi-copy 'v' begin-selection
+#bind-key -t vi-copy 'y' copy-selection
+
+# this is supposed to grab powerline for tmux but it disnae work
+#run-shell "powerline-daemon -q"
+#source "/usr/local/lib/python2.7/dist-packages/powerline/bindings/tmux/powerline.conf"
+
+#List of plugins
+set -g @plugin 'tmux-plugins/tpm'
+set -g @plugin 'tmux-plugins/tmux-sensible'
+set -g @plugin 'tmux-plugins/tmux-resurrect'
+set -g @plugin 'tmux-plugins/tmux-yank'
+
+# Other examples:
+# set -g @plugin 'github_username/plugin_name'
+# set -g @plugin 'git@github.com/user/plugin'
+# set -g @plugin 'git@bitbucket.com/user/plugin'
+
+set -g @resurrect-save 'Q'
+set -g @resurrect-restore 'R'
+# gcalcli config
+#
+set-option -g status-interval 60
+run-shell ~/.tmux-resurrect/resurrect.tmux
+#set-option -g status-left "#[fg=blue,bright]#(gcalcli agenda | head -2 | tail -1)#[default]"
+# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
+run '~/.tmux/plugins/tpm/tpm'
diff --git a/tmux.conf-alt b/tmux.conf-alt
new file mode 100644
index 0000000..e9faf85
--- /dev/null
+++ b/tmux.conf-alt
@@ -0,0 +1,29 @@
+set -g default-terminal "screen-256color"
+
+# vi-like keybindings
+setw -g mode-keys vi
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+bind-key -T copy-mode-vi 'v' send -X begin-selection
+bind-key -T copy-mode-vi 'y' send -X copy-selection
+
+# zenburn theme
+setw -g clock-mode-colour colour117
+setw -g mode-attr bold
+setw -g mode-fg colour117
+setw -g mode-bg colour238
+set -g status-bg colour235
+set -g status-fg colour248
+setw -g window-status-current-fg colour223
+setw -g window-status-current-bg colour237
+setw -g window-status-current-attr bold
+set -g message-attr bold
+set -g message-fg colour117
+set -g message-bg colour235
+
+# fancy status line: user@host, date, time
+set-option -g status-right "#(whoami)@#(hostname -s) #[fg=colour187,bold]%a %Y-%m-%d %H:%M"
+set -g status-right-length 50
+set -g status-left-length 20
diff --git a/tmuxinator.zsh b/tmuxinator.zsh
new file mode 100644
index 0000000..40a6964
--- /dev/null
+++ b/tmuxinator.zsh
@@ -0,0 +1,29 @@
+_tmuxinator() {
+ local commands projects
+ commands=(${(f)"$(tmuxinator commands zsh)"})
+ projects=(${(f)"$(tmuxinator completions start)"})
+
+ if (( CURRENT == 2 )); then
+ _describe -t commands "tmuxinator subcommands" commands
+ _describe -t projects "tmuxinator projects" projects
+ elif (( CURRENT == 3)); then
+ case $words[2] in
+ copy|debug|delete|open|start)
+ _arguments '*:projects:($projects)'
+ ;;
+ esac
+ fi
+
+ return
+}
+
+compdef _tmuxinator tmuxinator mux
+alias mux="tmuxinator"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/tmuxinator/aphids.yml b/tmuxinator/aphids.yml
new file mode 100644
index 0000000..89320fb
--- /dev/null
+++ b/tmuxinator/aphids.yml
@@ -0,0 +1,49 @@
+# ~/.tmuxinator/xldigest_pyqt_tmux.yml
+
+name: aphids
+root: ~/code/python/aphids-api
+
+# Optional tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
+# startup_window: editor
+
+# Specitifes (by index) which pane of the specified window will be selected on project startup. If not set, the first pane is used.
+# startup_pane: 1
+
+# Controls whether the tmux session should be attached to automatically. Defaults to true.
+# attach: false
+
+# Runs after everything. Use it to attach to tmux with custom options etc.
+# post: tmux -CC attach -t xldigest_pyqt_tmux
+
+windows:
+ - code:
+ - vf activate aphids-api; cd ~/code/python/aphids-api
+ - cd ~/code/python/aphids-api
+ - clear
+ - runner:
+ - vf activate aphids-api; cd ~/code/python/aphids-api
+ - cd ~/code/python/aphids-api
+ - clear
+ - db:
+ - vf activate aphids-api; cd ~/code/python/aphids-api
+ - cd ~/code/python/aphids-api
+ - psql aphids_api
+ - http:
+ - vf activate aphids-api; cd ~/code/python/aphids-api
+ - cd ~/code/python/aphids-api
+
diff --git a/tmuxinator/bcompiler_tmux.yml b/tmuxinator/bcompiler_tmux.yml
new file mode 100644
index 0000000..0e6044c
--- /dev/null
+++ b/tmuxinator/bcompiler_tmux.yml
@@ -0,0 +1,55 @@
+# ~/.tmuxinator/bcompiler_tmux.yml
+
+name: bcompiler_tmux
+root: ~/code/python/bcompiler
+
+# Optional tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
+# startup_window: editor
+
+# Specitifes (by index) which pane of the specified window will be selected on project startup. If not set, the first pane is used.
+# startup_pane: 1
+
+# Controls whether the tmux session should be attached to automatically. Defaults to true.
+# attach: false
+
+# Runs after everything. Use it to attach to tmux with custom options etc.
+# post: tmux -CC attach -t bcompiler_tmux
+
+windows:
+ - code:
+ - vf activate bcompiler-python36; cd ~/code/python/bcompiler/bcompiler
+ - test:
+ - vf activate bcompiler-python36; cd ~/code/python/bcompiler/bcompiler
+ - clear
+ - runner:
+ - vf activate bcompiler-python36; cd ~/code/python/bcompiler/bcompiler
+ - clear
+ - git st
+ - repl:
+ - vf activate bcompiler-python36; cd ~/code/python/bcompiler/bcompiler
+ - clear
+ - ptpython
+ - source:
+ - cd ~/Documents/bcompiler/source
+ - clear
+ - logs:
+ layout: even-horizontal
+ panes:
+ - logs:
+ - tail -f ~/Documents/bcompiler/output/bcompiler.log
+
diff --git a/tmuxinator/epm.yml b/tmuxinator/epm.yml
new file mode 100644
index 0000000..9f6f5bb
--- /dev/null
+++ b/tmuxinator/epm.yml
@@ -0,0 +1,47 @@
+# ~/.tmuxinator/bcompiler_tmux.yml
+
+name: epm
+root: ~/code/python/epm
+
+# Optional tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
+# startup_window: editor
+
+# Specitifes (by index) which pane of the specified window will be selected on project startup. If not set, the first pane is used.
+# startup_pane: 1
+
+# Controls whether the tmux session should be attached to automatically. Defaults to true.
+# attach: false
+
+# Runs after everything. Use it to attach to tmux with custom options etc.
+# post: tmux -CC attach -t bcompiler_tmux
+
+windows:
+ - code:
+ - source ~/.virtualenvs/epm/bin/activate && cd ~/code/python/epm/
+ - clear
+ - test:
+ - source ~/.virtualenvs/epm/bin/activate && cd ~/code/python/epm/
+ - clear
+ - runner:
+ - source ~/.virtualenvs/epm/bin/activate && cd ~/code/python/epm/
+ - clear
+ - git st
+ - repl:
+ - source ~/.virtualenvs/epm/bin/activate && cd ~/code/python/epm/
+ - clear
+ - ptpython
diff --git a/tmuxinator/general.yml b/tmuxinator/general.yml
new file mode 100644
index 0000000..f6da6a5
--- /dev/null
+++ b/tmuxinator/general.yml
@@ -0,0 +1,36 @@
+# ~/.tmuxinator/general.yml
+
+name: general
+root: ~/
+
+# Optional tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
+# startup_window: editor
+
+# Specitifes (by index) which pane of the specified window will be selected on project startup. If not set, the first pane is used.
+# startup_pane: 1
+
+# Controls whether the tmux session should be attached to automatically. Defaults to true.
+# attach: false
+
+# Runs after everything. Use it to attach to tmux with custom options etc.
+# post: tmux -CC attach -t bcompiler_tmux
+
+windows:
+ - music:
+ - mpsyt
+ - shell:
diff --git a/tmuxinator/xldigest.yml b/tmuxinator/xldigest.yml
new file mode 100644
index 0000000..392f2b4
--- /dev/null
+++ b/tmuxinator/xldigest.yml
@@ -0,0 +1,47 @@
+# ~/.tmuxinator/xldigest_pyqt_tmux.yml
+
+name: xldigest
+root: ~/code/python/xldigest
+
+# Optional tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
+# startup_window: editor
+
+# Specitifes (by index) which pane of the specified window will be selected on project startup. If not set, the first pane is used.
+# startup_pane: 1
+
+# Controls whether the tmux session should be attached to automatically. Defaults to true.
+# attach: false
+
+# Runs after everything. Use it to attach to tmux with custom options etc.
+# post: tmux -CC attach -t xldigest_pyqt_tmux
+
+windows:
+ - code:
+ - vf activate xldigest_pyqt; cd ~/code/python/xldigest
+ - cd ~/code/python/xldigest
+ - clear
+ - runner:
+ - vf activate xldigest_pyqt; cd ~/code/python/xldigest
+ - cd ~/code/python/xldigest
+ - clear
+ - repl:
+ - vf activate xldigest_pyqt; cd ~/code/python/xldigest
+ - cd ~/code/python/xldigest
+ - clear
+ - ptpython
+
diff --git a/urlview b/urlview
new file mode 100644
index 0000000..823fa9f
--- /dev/null
+++ b/urlview
@@ -0,0 +1 @@
+COMMAND quotebrowser %s &
diff --git a/urxvt/ext/clipboard b/urxvt/ext/clipboard
new file mode 100644
index 0000000..e5d2322
--- /dev/null
+++ b/urxvt/ext/clipboard
@@ -0,0 +1,117 @@
+#!/usr/bin/perl
+# Author: Bert Muennich
+# Website: http://www.github.com/muennich/urxvt-perls
+# License: GPLv2
+
+# Use keyboard shortcuts to copy the selection to the clipboard and to paste
+# the clipboard contents (optionally escaping all special characters).
+# Requires xsel to be installed!
+
+# Usage: put the following lines in your .Xdefaults/.Xresources:
+# URxvt.perl-ext-common: ...,clipboard
+# URxvt.keysym.M-c: perl:clipboard:copy
+# URxvt.keysym.M-v: perl:clipboard:paste
+# URxvt.keysym.M-C-v: perl:clipboard:paste_escaped
+
+# Options:
+# URxvt.clipboard.autocopy: If true, PRIMARY overwrites clipboard
+
+# You can also overwrite the system commands to use for copying/pasting.
+# The default ones are:
+# URxvt.clipboard.copycmd: xsel -ib
+# URxvt.clipboard.pastecmd: xsel -ob
+# If you prefer xclip, then put these lines in your .Xdefaults/.Xresources:
+# URxvt.clipboard.copycmd: xclip -i -selection clipboard
+# URxvt.clipboard.pastecmd: xclip -o -selection clipboard
+# On Mac OS X, put these lines in your .Xdefaults/.Xresources:
+# URxvt.clipboard.copycmd: pbcopy
+# URxvt.clipboard.pastecmd: pbpaste
+
+# The use of the functions should be self-explanatory!
+
+
+use strict;
+use warnings;
+
+sub on_start {
+ my ($self) = @_;
+
+ $self->{copy_cmd} = $self->x_resource('clipboard.copycmd') || 'xsel -ib';
+ $self->{paste_cmd} = $self->x_resource('clipboard.pastecmd') || 'xsel -ob';
+
+ if ($self->x_resource('clipboard.autocopy') eq 'true') {
+ $self->enable(sel_grab => \&sel_grab);
+ }
+
+ ()
+}
+
+sub copy {
+ my ($self) = @_;
+
+ if (open(CLIPBOARD, "| $self->{copy_cmd}")) {
+ my $sel = $self->selection();
+ utf8::encode($sel);
+ print CLIPBOARD $sel;
+ close(CLIPBOARD);
+ } else {
+ print STDERR "error running '$self->{copy_cmd}': $!\n";
+ }
+
+ ()
+}
+
+sub paste {
+ my ($self) = @_;
+
+ my $str = `$self->{paste_cmd}`;
+ if ($? == 0) {
+ $self->tt_paste($str);
+ } else {
+ print STDERR "error running '$self->{paste_cmd}': $!\n";
+ }
+
+ ()
+}
+
+sub paste_escaped {
+ my ($self) = @_;
+
+ my $str = `$self->{paste_cmd}`;
+ if ($? == 0) {
+ $str =~ s/([!#\$%&\*\(\) ='"\\\|\[\]`~,<>\?])/\\$1/g;
+ $self->tt_paste($str);
+ } else {
+ print STDERR "error running '$self->{paste_cmd}': $!\n";
+ }
+
+ ()
+}
+
+sub on_action {
+ my ($self, $action) = @_;
+
+ on_user_command($self, "clipboard:" . $action);
+}
+
+sub on_user_command {
+ my ($self, $cmd) = @_;
+
+ if ($cmd eq "clipboard:copy") {
+ $self->copy;
+ } elsif ($cmd eq "clipboard:paste") {
+ $self->paste;
+ } elsif ($cmd eq "clipboard:paste_escaped") {
+ $self->paste_escaped;
+ }
+
+ ()
+}
+
+sub sel_grab {
+ my ($self) = @_;
+
+ $self->copy;
+
+ ()
+}
diff --git a/urxvt/ext/font-size b/urxvt/ext/font-size
new file mode 100644
index 0000000..f6a33bb
--- /dev/null
+++ b/urxvt/ext/font-size
@@ -0,0 +1,471 @@
+#!/usr/bin/perl
+#
+# On-the-fly adjusting of the font size in urxvt
+#
+# Copyright (c) 2008 David O'Neill
+# 2012 Noah K. Tilton <noahktilton@gmail.com>
+# 2009-2012 Simon Lundström <simmel@soy.se>
+# 2012-2016 Jan Larres <jan@majutsushi.net>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# URL: https://github.com/majutsushi/urxvt-font-size
+#
+# Based on:
+# https://github.com/dave0/urxvt-font-size
+# https://github.com/noah/urxvt-font
+# https://github.com/simmel/urxvt-resize-font
+#
+
+#:META:X_RESOURCE:%.step:interger:font size increase/decrease step
+
+=head1 NAME
+
+font-size - interactive font size setter
+
+=head1 USAGE
+
+Put the font-size script into $HOME/.urxvt/ext/ and add it to the list
+of enabled perl-extensions in ~/.Xresources:
+
+ URxvt.perl-ext-common: ...,font-size
+
+Add some keybindings:
+
+ URxvt.keysym.C-Up: font-size:increase
+ URxvt.keysym.C-Down: font-size:decrease
+ URxvt.keysym.C-S-Up: font-size:incglobal
+ URxvt.keysym.C-S-Down: font-size:decglobal
+ URxvt.keysym.C-equal: font-size:reset
+ URxvt.keysym.C-slash: font-size:show
+
+Note that for urxvt versions older than 9.21 the resources have to look like this:
+
+ URxvt.keysym.C-Up: perl:font-size:increase
+ URxvt.keysym.C-Down: perl:font-size:decrease
+ URxvt.keysym.C-S-Up: perl:font-size:incglobal
+ URxvt.keysym.C-S-Down: perl:font-size:decglobal
+ URxvt.keysym.C-equal: perl:font-size:reset
+ URxvt.keysym.C-slash: perl:font-size:show
+
+Supported functions:
+
+=over 2
+
+=item * increase/decrease:
+
+ increase or decrease the font size of the current terminal.
+
+=item * incglobal/decglobal:
+
+ same as above and also adjust the X server values so all newly
+ started terminals will use the same fontsize.
+
+=item * incsave/decsave:
+
+ same as incglobal/decglobal and also modify the ~/.Xresources
+ file so the changed font sizes will persist over a restart of
+ the X server or a reboot.
+
+=item * reset:
+
+ reset the font size to the value of the resource when starting
+ the terminal.
+
+=item * show
+
+ show the current value of the 'font' resource in a popup.
+
+=back
+
+You can also change the step size that the script will use to increase
+the font size:
+
+ URxvt.font-size.step: 4
+
+The default step size is 1. This means that with this setting a
+size change sequence would be for example 8->12->16->20 instead of
+8->9->10->11->12 etc. Please note that many X11 fonts are only
+available in specific sizes, though, and odd sizes are often not
+available, resulting in an effective step size of 2 instead of 1
+in that case.
+=cut
+
+use strict;
+use warnings;
+
+my %escapecodes = (
+ "font" => 710,
+ "boldFont" => 711,
+ "italicFont" => 712,
+ "boldItalicFont" => 713
+);
+
+sub on_start
+{
+ my ($self) = @_;
+
+ $self->{step} = $self->x_resource("%.step") || 1;
+
+ foreach my $type (qw(font boldFont italicFont boldItalicFont)) {
+ $self->{$type} = $self->x_resource($type) || "undef";
+ }
+}
+
+# Needed for backwards compatibility with < 9.21
+sub on_user_command
+{
+ my ($self, $cmd) = @_;
+
+ my $step = $self->{step};
+
+ if ($cmd eq "font-size:increase") {
+ fonts_change_size($self, $step, 0);
+ } elsif ($cmd eq "font-size:decrease") {
+ fonts_change_size($self, -$step, 0);
+ } elsif ($cmd eq "font-size:incglobal") {
+ fonts_change_size($self, $step, 1);
+ } elsif ($cmd eq "font-size:decglobal") {
+ fonts_change_size($self, -$step, 1);
+ } elsif ($cmd eq "font-size:incsave") {
+ fonts_change_size($self, $step, 2);
+ } elsif ($cmd eq "font-size:decsave") {
+ fonts_change_size($self, -$step, 2);
+ } elsif ($cmd eq "font-size:reset") {
+ fonts_reset($self);
+ } elsif ($cmd eq "font-size:show") {
+ fonts_show($self);
+ }
+}
+
+sub on_action
+{
+ my ($self, $action) = @_;
+
+ my $step = $self->{step};
+
+ if ($action eq "increase") {
+ fonts_change_size($self, $step, 0);
+ } elsif ($action eq "decrease") {
+ fonts_change_size($self, -$step, 0);
+ } elsif ($action eq "incglobal") {
+ fonts_change_size($self, $step, 1);
+ } elsif ($action eq "decglobal") {
+ fonts_change_size($self, -$step, 1);
+ } elsif ($action eq "incsave") {
+ fonts_change_size($self, $step, 2);
+ } elsif ($action eq "decsave") {
+ fonts_change_size($self, -$step, 2);
+ } elsif ($action eq "reset") {
+ fonts_reset($self);
+ } elsif ($action eq "show") {
+ fonts_show($self);
+ }
+}
+
+sub fonts_change_size
+{
+ my ($term, $delta, $save) = @_;
+
+ my @newfonts = ();
+
+ my $curres = $term->resource('font');
+ if (!$curres) {
+ $term->scr_add_lines("\r\nWarning: No font configured, trying a default.\r\nPlease set a font with the 'URxvt.font' resource.");
+ $curres = "fixed";
+ }
+ my @curfonts = split(/\s*,\s*/, $curres);
+
+ my $basefont = shift(@curfonts);
+ my ($newbasefont, $newbasedelta, $newbasesize) = handle_font($term, $basefont, $delta, 0, 0);
+ push @newfonts, $newbasefont;
+
+ # Only adjust other fonts if base font changed
+ if ($newbasefont ne $basefont) {
+ foreach my $font (@curfonts) {
+ my ($newfont, $newdelta, $newsize) = handle_font($term, $font, $delta, $newbasedelta, $newbasesize);
+ push @newfonts, $newfont;
+ }
+ my $newres = join(",", @newfonts);
+ font_apply_new($term, $newres, "font", $save);
+
+ handle_type($term, "boldFont", $delta, $newbasedelta, $newbasesize, $save);
+ handle_type($term, "italicFont", $delta, $newbasedelta, $newbasesize, $save);
+ handle_type($term, "boldItalicFont", $delta, $newbasedelta, $newbasesize, $save);
+ }
+
+ if ($save > 1) {
+ # write the new values back to the file
+ my $xresources = readlink $ENV{"HOME"} . "/.Xresources";
+ system("xrdb -edit " . $xresources);
+ }
+}
+
+sub fonts_reset
+{
+ my ($term) = @_;
+
+ foreach my $type (qw(font boldFont italicFont boldItalicFont)) {
+ my $initial = $term->{$type};
+ if ($initial ne "undef") {
+ font_apply_new($term, $initial, $type, 0);
+ }
+ }
+}
+
+sub fonts_show
+{
+ my ($term) = @_;
+
+ my $out = $term->resource('font');
+ $out =~ s/\s*,\s*/\n/g;
+
+ $term->{'font-size'}{'overlay'} = {
+ overlay => $term->overlay_simple(0, -1, $out),
+ timer => urxvt::timer->new->start(urxvt::NOW + 5)->cb(
+ sub {
+ delete $term->{'font-size'}{'overlay'};
+ }
+ ),
+ };
+}
+
+sub handle_type
+{
+ my ($term, $type, $delta, $basedelta, $basesize, $save) = @_;
+
+ my $curres = $term->resource($type);
+ if (!$curres) {
+ return;
+ }
+ my @curfonts = split(/\s*,\s*/, $curres);
+ my @newfonts = ();
+
+ foreach my $font (@curfonts) {
+ my ($newfont, $newdelta, $newsize) = handle_font($term, $font, $delta, $basedelta, $basesize);
+ push @newfonts, $newfont;
+ }
+
+ my $newres = join(",", @newfonts);
+ font_apply_new($term, $newres, $type, $save);
+}
+
+sub handle_font
+{
+ my ($term, $font, $delta, $basedelta, $basesize) = @_;
+
+ my $newfont;
+ my $newdelta;
+ my $newsize;
+ my $prefix = 0;
+
+ if ($font =~ /^\s*x:/) {
+ $font =~ s/^\s*x://;
+ $prefix = 1;
+ }
+ if ($font =~ /^\s*(\[.*\])?xft:/) {
+ ($newfont, $newdelta, $newsize) = font_change_size_xft($term, $font, $delta, $basedelta, $basesize);
+ } elsif ($font =~ /^\s*-/) {
+ ($newfont, $newdelta, $newsize) = font_change_size_xlfd($term, $font, $delta, $basedelta, $basesize);
+ } else {
+ # check whether the font is a valid alias and if yes resolve it to the
+ # actual font
+ my $lsfinfo = `xlsfonts -l $font 2>/dev/null`;
+
+ if ($lsfinfo eq "") {
+ # not a valid alias, ring the bell if it is the base font and just
+ # return the current font
+ if ($basesize == 0) {
+ $term->scr_bell;
+ }
+ return ($font, $basedelta, $basesize);
+ }
+
+ my $fontinfo = (split(/\n/, $lsfinfo))[-1];
+ my ($fontfull) = ($fontinfo =~ /\s+([-a-z0-9]+$)/);
+ ($newfont, $newdelta, $newsize) = font_change_size_xlfd($term, $fontfull, $delta, $basedelta, $basesize);
+ }
+
+ # $term->scr_add_lines("\r\nNew font is $newfont\n");
+ if ($prefix) {
+ $newfont = "x:$newfont";
+ }
+ return ($newfont, $newdelta, $newsize);
+}
+
+sub font_change_size_xft
+{
+ my ($term, $fontstring, $delta, $basedelta, $basesize) = @_;
+
+ my @pieces = split(/:/, $fontstring);
+ my @resized = ();
+ my $size = 0;
+ my $new_size = 0;
+
+ foreach my $piece (@pieces) {
+ if ($piece =~ /^(?:(?:pixel)?size=|[^=-]+-)(\d+(\.\d*)?)$/) {
+ $size = $1;
+
+ if ($basedelta != 0) {
+ $new_size = $size + $basedelta;
+ } else {
+ $new_size = $size + $delta;
+ }
+
+ $piece =~ s/(=|-)$size/$1$new_size/;
+ }
+ push @resized, $piece;
+ }
+
+ my $resized_str = join(":", @resized);
+
+ # don't make fonts too small
+ if ($new_size >= 6) {
+ return ($resized_str, $new_size - $size, $new_size);
+ } else {
+ if ($basesize == 0) {
+ $term->scr_bell;
+ }
+ return ($fontstring, 0, $size);
+ }
+}
+
+sub font_change_size_xlfd
+{
+ my ($term, $fontstring, $delta, $basedelta, $basesize) = @_;
+
+ #-xos4-terminus-medium-r-normal-*-12-*-*-*-*-*-*-1
+
+ my @fields = qw(foundry family weight slant setwidth style pixelSize pointSize Xresolution Yresolution spacing averageWidth registry encoding);
+
+ my %font;
+ $fontstring =~ s/^-//; # Strip leading - before split
+ @font{@fields} = split(/-/, $fontstring);
+
+ if ($font{pixelSize} eq '*') {
+ $term->scr_add_lines("\r\nWarning: Font size undefined, assuming 12.\r\nPlease set the 'URxvt.font' resource to a font with a concrete size.");
+ $font{pixelSize} = '12'
+ }
+ if ($font{registry} eq '*') {
+ $font{registry} ='iso8859';
+ }
+
+ # Blank out the size for the pattern
+ my %pattern = %font;
+ $pattern{foundry} = '*';
+ $pattern{setwidth} = '*';
+ $pattern{pixelSize} = '*';
+ $pattern{pointSize} = '*';
+ # if ($basesize != 0) {
+ # $pattern{Xresolution} = '*';
+ # $pattern{Yresolution} = '*';
+ # }
+ $pattern{averageWidth} = '*';
+ # make sure there are no empty fields
+ foreach my $field (@fields) {
+ $pattern{$field} = '*' unless defined($pattern{$field});
+ }
+ my $new_fontstring = '-' . join('-', @pattern{@fields});
+
+ my @candidates;
+ # $term->scr_add_lines("\r\nPattern is $new_fontstring\n");
+ open(FOO, "xlsfonts -fn '$new_fontstring' | sort -u |") or die $!;
+ while (<FOO>) {
+ chomp;
+ s/^-//; # Strip leading '-' before split
+ my @fontdata = split(/-/, $_);
+
+ push @candidates, [$fontdata[6], "-$_"];
+ # $term->scr_add_lines("\r\npossibly $fontdata[6] $_\n");
+ }
+ close(FOO);
+
+ if (!@candidates) {
+ die "No possible fonts!";
+ }
+
+ if ($basesize != 0) {
+ # sort by font size, descending
+ @candidates = sort {$b->[0] <=> $a->[0]} @candidates;
+
+ # font is not the base font, so find the largest font that is at most
+ # as large as the base font. If the largest possible font is smaller
+ # than the base font bail and hope that a 0-size font can be found at
+ # the end of the function
+ if ($candidates[0]->[0] > $basesize) {
+ foreach my $candidate (@candidates) {
+ if ($candidate->[0] <= $basesize) {
+ return ($candidate->[1], $candidate->[0] - $font{pixelSize}, $candidate->[0]);
+ }
+ }
+ }
+ } elsif ($delta > 0) {
+ # sort by font size, ascending
+ @candidates = sort {$a->[0] <=> $b->[0]} @candidates;
+
+ foreach my $candidate (@candidates) {
+ if ($candidate->[0] >= $font{pixelSize} + $delta) {
+ return ($candidate->[1], $candidate->[0] - $font{pixelSize}, $candidate->[0]);
+ }
+ }
+ } elsif ($delta < 0) {
+ # sort by font size, descending
+ @candidates = sort {$b->[0] <=> $a->[0]} @candidates;
+
+ foreach my $candidate (@candidates) {
+ if ($candidate->[0] <= $font{pixelSize} + $delta && $candidate->[0] != 0) {
+ return ($candidate->[1], $candidate->[0] - $font{pixelSize}, $candidate->[0]);
+ }
+ }
+ }
+
+ # no fitting font available, check whether a 0-size font can be used to
+ # fit the size of the base font
+ @candidates = sort {$a->[0] <=> $b->[0]} @candidates;
+ if ($basesize != 0 && $candidates[0]->[0] == 0) {
+ return ($candidates[0]->[1], $basedelta, $basesize);
+ } else {
+ # if there is absolutely no smaller/larger font that can be used
+ # return the current one, and beep if this is the base font
+ if ($basesize == 0) {
+ $term->scr_bell;
+ }
+ return ("-$fontstring", 0, $font{pixelSize});
+ }
+}
+
+sub font_apply_new
+{
+ my ($term, $newfont, $type, $save) = @_;
+
+ # $term->scr_add_lines("\r\nnew font is $newfont\n");
+
+ $term->cmd_parse("\033]" . $escapecodes{$type} . ";" . $newfont . "\033\\");
+
+ # load the xrdb db
+ # system("xrdb -load " . X_RESOURCES);
+
+ if ($save > 0) {
+ # merge the new values
+ open(XRDB_MERGE, "| xrdb -merge") || die "can't fork: $!";
+ local $SIG{PIPE} = sub { die "xrdb pipe broken" };
+ print XRDB_MERGE "URxvt." . $type . ": " . $newfont;
+ close(XRDB_MERGE) || die "bad xrdb: $! $?";
+ }
+}
diff --git a/urxvt/ext/fullscreen b/urxvt/ext/fullscreen
new file mode 100644
index 0000000..086c2ea
--- /dev/null
+++ b/urxvt/ext/fullscreen
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+#
+# Toggle fullscreen
+#
+# URL: https://aur.archlinux.org/packages/urxvt-fullscreen
+#
+# Copyright (C) 2010-2011 Christopher Luna
+#
+# 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 3 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/>.
+
+
+use strict;
+use warnings;
+
+sub on_user_command
+{
+ my ($self, $cmd) = @_;
+
+ if ($cmd eq "fullscreen:switch") {
+ my $dummy = `wmctrl -r :ACTIVE: -b toggle,fullscreen,above`;
+ }
+}
diff --git a/urxvt/ext/keyboard-select b/urxvt/ext/keyboard-select
new file mode 100644
index 0000000..a6f89af
--- /dev/null
+++ b/urxvt/ext/keyboard-select
@@ -0,0 +1,598 @@
+#!/usr/bin/perl
+# Author: Bert Muennich
+# Website: http://www.github.com/muennich/urxvt-perls
+# License: GPLv2
+
+# Use keyboard shortcuts to select and copy text.
+
+# Usage: put the following lines in your .Xdefaults/.Xresources:
+# URxvt.perl-ext-common: ...,keyboard-select
+# URxvt.keysym.M-Escape: perl:keyboard-select:activate
+# The following line overwrites the default Meta-s binding and allows to
+# activate keyboard-select directly in backward search mode:
+# URxvt.keysym.M-s: perl:keyboard-select:search
+
+# Use Meta-Escape to activate selection mode, then use the following keys:
+# h/j/k/l: Move cursor left/down/up/right (also with arrow keys)
+# g/G/0/^/$/H/M/L/f/F/;/,/w/W/b/B/e/E: More vi-like cursor movement keys
+# '/'/?: Start forward/backward search
+# n/N: Repeat last search, N: in reverse direction
+# Ctrl-f/b: Scroll down/up one screen
+# Ctrl-d/u: Scroll down/up half a screen
+# v/V/Ctrl-v: Toggle normal/linewise/blockwise selection
+# y/Return: Copy selection to primary buffer, Return: quit afterwards
+# Y: Copy selected lines to primary buffer or cursor line and quit
+# q/Escape: Quit keyboard selection mode
+
+
+use strict;
+use warnings;
+
+sub on_start{
+ my ($self) = @_;
+
+ $self->{patterns}{'w'} = qr/\w[^\w\s]|\W\w|\s\S/;
+ $self->{patterns}{'W'} = qr/\s\S/;
+ $self->{patterns}{'b'} = qr/.*(?:\w[^\w\s]|\W\w|\s\S)/;
+ $self->{patterns}{'B'} = qr/.*\s\S/;
+ $self->{patterns}{'e'} = qr/[^\w\s](?=\w)|\w(?=\W)|\S(?=\s|$)/;
+ $self->{patterns}{'E'} = qr/\S(?=\s|$)/;
+
+ ()
+}
+
+
+sub on_action {
+ my ($self, $action) = @_;
+
+ on_user_command($self, "keyboard-select:" . $action);
+}
+
+
+sub on_user_command {
+ my ($self, $cmd) = @_;
+
+ if (not $self->{active}) {
+ if ($cmd eq 'keyboard-select:activate') {
+ activate($self);
+ } elsif ($cmd eq 'keyboard-select:search') {
+ activate($self, 1);
+ }
+ }
+
+ ()
+}
+
+
+sub key_press {
+ my ($self, $event, $keysym, $char) = @_;
+ my $key = chr($keysym);
+
+ if (lc($key) eq 'c' && $event->{state} & urxvt::ControlMask) {
+ deactivate($self);
+ } elsif ($self->{search}) {
+ if ($keysym == 0xff1b) {
+ if ($self->{search_mode}) {
+ deactivate($self);
+ } else {
+ $self->{search} = '';
+ status_area($self);
+ }
+ } elsif ($keysym == 0xff08) {
+ $self->{search} = substr($self->{search}, 0, -1);
+ if (not $self->{search} and $self->{search_mode}) {
+ deactivate($self);
+ } else {
+ status_area($self);
+ }
+ } elsif ($keysym == 0xff0d ||
+ (lc($key) eq 'm' && $event->{state} & urxvt::ControlMask)) {
+ my $txt = substr($self->{search}, 1);
+ if ($txt) {
+ $self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ :
+ qr/\Q$txt\E/i;
+ } elsif ($self->{pattern}) {
+ delete $self->{pattern};
+ }
+ $self->{search} = '';
+ $self->screen_cur($self->{srhcr}, $self->{srhcc});
+ if (not find_next($self)) {
+ if ($self->{search_mode}) {
+ deactivate($self);
+ } else {
+ status_area($self);
+ }
+ }
+ } elsif (length($char) > 0) {
+ $self->{search} .= $self->locale_decode($char);
+ my $txt = substr($self->{search}, 1);
+ if ($txt) {
+ $self->{pattern} = ($txt =~ m/[[:upper:]]/) ? qr/\Q$txt\E/ :
+ qr/\Q$txt\E/i;
+ } elsif ($self->{pattern}) {
+ delete $self->{pattern};
+ }
+ $self->screen_cur($self->{srhcr}, $self->{srhcc});
+ find_next($self);
+ status_area($self);
+ }
+ } elsif ($self->{move_to}) {
+ if ($keysym == 0xff1b) {
+ $self->{move_to} = 0;
+ status_area($self);
+ } elsif (length($char) > 0) {
+ $self->{move_to} = 0;
+ $self->{patterns}{'f-1'} = qr/^.*\Q$key\E/;
+ $self->{patterns}{'f+1'} = qr/^.+?\Q$key\E/;
+ move_to($self, ';');
+ status_area($self);
+ }
+ } elsif ($keysym == 0xff1b || lc($key) eq 'q') {
+ deactivate($self);
+ } elsif (lc($key) eq 'y' || $keysym == 0xff0d ||
+ (lc($key) eq 'm' && $event->{state} & urxvt::ControlMask)) {
+ my $quit = 0;
+ if ($key eq 'Y' && $self->{select} ne 'l') {
+ $quit = !$self->{select};
+ toggle_select($self, 'l');
+ }
+ if ($self->{select}) {
+ my ($br, $bc, $er, $ec) = calc_span($self);
+ $ec = $self->line($er)->l if $self->{select} eq 'l';
+ $self->selection_beg($br, $bc);
+ $self->selection_end($er, $ec);
+ $self->selection_make($event->{time}, $self->{select} eq 'b');
+ if (lc($key) eq 'y') {
+ $self->selection_beg(1, 0);
+ $self->selection_end(1, 0);
+ $self->{select} = '';
+ status_area($self);
+ $self->want_refresh();
+ } else {
+ $quit = 1;
+ }
+ }
+ if ($quit) {
+ deactivate($self);
+ }
+ } elsif ($key eq 'V') {
+ toggle_select($self, 'l');
+ } elsif ($key eq 'v') {
+ if ($event->{state} & urxvt::ControlMask) {
+ toggle_select($self, 'b');
+ } else {
+ toggle_select($self, 'n');
+ }
+ } elsif ($key eq 'k' || $keysym == 0xff52) {
+ move_cursor($self, 'k');
+ } elsif ($key eq 'j' || $keysym == 0xff54) {
+ move_cursor($self, 'j');
+ } elsif ($key eq 'h' || $keysym == 0xff51) {
+ move_cursor($self, 'h');
+ } elsif ($key eq 'l' || $keysym == 0xff53) {
+ move_cursor($self, 'l');
+ } elsif ($keysym == 0xff57) {
+ move_cursor($self, '$');
+ } elsif ($keysym == 0xff50) {
+ move_cursor($self, '^');
+ } elsif ('gG0^$HML' =~ m/\Q$key\E/ ||
+ ('fbdu' =~ m/\Q$key\E/ && $event->{state} & urxvt::ControlMask)) {
+ move_cursor($self, $key);
+ } elsif (lc($key) eq 'f') {
+ $self->{move_to} = 1;
+ $self->{move_dir} = $key eq 'F' ? -1 : 1;
+ status_area($self, $key);
+ } elsif (';,wWbBeE' =~ m/\Q$key\E/) {
+ move_to($self, $key);
+ } elsif ($key eq '/' || $key eq '?') {
+ $self->{search} = $key;
+ $self->{search_dir} = $key eq '?' ? -1 : 1;
+ ($self->{srhcr}, $self->{srhcc}) = $self->screen_cur();
+ status_area($self);
+ } elsif (lc($key) eq 'n') {
+ find_next($self, $self->{search_dir} * ($key eq 'N' ? -1 : 1));
+ }
+
+ return 1;
+}
+
+
+sub move_cursor {
+ my ($self, $key) = @_;
+ my ($cr, $cc) = $self->screen_cur();
+ my $line = $self->line($cr);
+
+ if ($key eq 'k' && $line->beg > $self->top_row) {
+ $cr = $line->beg - 1;
+ } elsif ($key eq 'j' && $line->end < $self->nrow - 1) {
+ $cr = $line->end + 1;
+ } elsif ($key eq 'h' && $self->{offset} > 0) {
+ $self->{offset} = $line->offset_of($cr, $cc) - 1;
+ $self->{dollar} = 0;
+ } elsif ($key eq 'l' && $self->{offset} < $line->l - 1) {
+ ++$self->{offset};
+ } elsif ($key eq 'f' || $key eq 'd') {
+ my $vs = $self->view_start() +
+ ($key eq 'd' ? $self->nrow / 2 : $self->nrow - 1);
+ $vs = 0 if $vs > 0;
+ $cr += $vs - $self->view_start($vs);
+ } elsif ($key eq 'b' || $key eq 'u') {
+ my $vs = $self->view_start() -
+ ($key eq 'u' ? $self->nrow / 2 : $self->nrow - 1);
+ $vs = $self->top_row if $vs < $self->top_row;
+ $cr += $vs - $self->view_start($vs);
+ } elsif ($key eq 'g') {
+ ($cr, $self->{offset}) = ($self->top_row, 0);
+ $self->{dollar} = 0;
+ } elsif ($key eq 'G') {
+ ($cr, $self->{offset}) = ($self->nrow - 1, 0);
+ $self->{dollar} = 0;
+ } elsif ($key eq '0') {
+ $self->{offset} = 0;
+ $self->{dollar} = 0;
+ } elsif ($key eq '^') {
+ my $ltxt = $self->special_decode($line->t);
+ while ($ltxt =~ s/^( *)\t/$1 . " " x (8 - length($1) % 8)/e) {}
+ $self->{offset} = $ltxt =~ m/^ +/ ? $+[0] : 0;
+ $self->{dollar} = 0;
+ } elsif ($key eq '$') {
+ my $co = $line->offset_of($cr, $cc);
+ $self->{dollar} = $co + 1;
+ $self->{offset} = $line->l - 1;
+ } elsif ($key eq 'H') {
+ $cr = $self->view_start();
+ } elsif ($key eq 'M') {
+ $cr = $self->view_start() + $self->nrow / 2;
+ } elsif ($key eq 'L') {
+ $cr = $self->view_start() + $self->nrow - 1;
+ }
+
+ $line = $self->line($cr);
+ $cc = $self->{dollar} || $self->{offset} >= $line->l ? $line->l - 1 :
+ $self->{offset};
+ $self->screen_cur($line->coord_of($cc));
+
+ status_area($self);
+ $self->want_refresh();
+
+ ()
+}
+
+
+sub move_to {
+ my ($self, $key) = @_;
+ my ($cr, $cc) = $self->screen_cur();
+ my $line = $self->line($cr);
+ my $offset = $self->{offset};
+ my ($dir, $pattern);
+ my ($wrap, $found) = (0, 0);
+
+ if ($key eq ';' || $key eq ',') {
+ $dir = $self->{move_dir} * ($key eq ',' ? -1 : 1);
+ $pattern = $self->{patterns}{sprintf('f%+d', $dir)};
+ return if not $pattern;
+ } else {
+ if (lc($key) eq 'b') {
+ $dir = -1;
+ } else {
+ $dir = 1;
+ ++$offset if lc($key) eq 'e';
+ }
+ $pattern = $self->{patterns}{$key};
+ $wrap = 1;
+ }
+
+ if ($dir > 0) {
+ NEXTDOWN: my $text = substr($line->t, $offset);
+ if ($text =~ m/$pattern/) {
+ $offset += $+[0] - 1;
+ $found = 1;
+ } elsif ($wrap && $line->end + 1 < $self->nrow) {
+ $cr = $line->end + 1;
+ $line = $self->line($cr);
+ $offset = 0;
+ if (lc($key) eq 'e') {
+ goto NEXTDOWN;
+ } else {
+ $found = 1;
+ }
+ }
+ } elsif ($dir < 0) {
+ NEXTUP: my $text = substr($line->t, 0, $offset);
+ if ($text =~ m/$pattern/) {
+ $offset += $+[0] - length($text) - 1;
+ $found = 1;
+ } elsif ($wrap) {
+ if ($offset > 0) {
+ $offset = 0;
+ $found = 1;
+ } elsif ($line->beg > $self->top_row) {
+ $cr = $line->beg - 1;
+ $line = $self->line($cr);
+ $offset = $line->l;
+ goto NEXTUP;
+ }
+ }
+ }
+
+ if ($found) {
+ $self->{dollar} = 0;
+ $self->{offset} = $offset;
+ $self->screen_cur($line->coord_of($offset));
+ $self->want_refresh();
+ }
+
+ ()
+}
+
+
+sub find_next {
+ my ($self, $dir) = @_;
+
+ return if not $self->{pattern};
+ $dir = $self->{search_dir} if not $dir;
+
+ my ($cr, $cc) = $self->screen_cur();
+ my $line = $self->line($cr);
+ my $offset = $line->offset_of($cr, $cc);
+ my $text;
+ my $found = 0;
+
+ ++$offset if $dir > 0;
+
+ while (not $found) {
+ if ($dir > 0) {
+ $text = substr($line->t, $offset);
+ if ($text =~ m/$self->{pattern}/) {
+ $found = 1;
+ $offset += $-[0];
+ } else {
+ last if $line->end >= $self->nrow;
+ $line = $self->line($line->end + 1);
+ $offset = 0;
+ }
+ } else {
+ $text = substr($line->t, 0, $offset);
+ if ($text =~ m/$self->{pattern}/) {
+ $found = 1;
+ $offset = $-[0] while $text =~ m/$self->{pattern}/g;
+ } else {
+ last if $line->beg <= $self->top_row;
+ $line = $self->line($line->beg - 1);
+ $offset = $line->l;
+ }
+ }
+ }
+
+ if ($found) {
+ $self->{dollar} = 0;
+ $self->{offset} = $offset;
+ $self->screen_cur($line->coord_of($offset));
+ status_area($self);
+ $self->want_refresh();
+ }
+
+ return $found;
+}
+
+
+sub tt_write {
+ return 1;
+}
+
+
+sub refresh {
+ my ($self) = @_;
+ my ($cr, $cc) = $self->screen_cur();
+
+ # scroll the current cursor position into visible area
+ if ($cr < $self->view_start()) {
+ $self->view_start($cr);
+ } elsif ($cr >= $self->view_start() + $self->nrow) {
+ $self->view_start($cr - $self->nrow + 1);
+ }
+
+ if ($self->{select}) {
+ my ($hl, $reverse_cursor);
+ my ($br, $bc, $er, $ec) = calc_span($self);
+
+ if ($self->x_resource('highlightColor')) {
+ $hl = urxvt::RS_Sel;
+ $reverse_cursor = 0;
+ } else {
+ $hl = urxvt::RS_RVid;
+ $reverse_cursor = $self->{select} ne 'l';
+ }
+ if ($self->{select} eq 'b') {
+ my $co = $self->line($cr)->offset_of($cr, $cc);
+ my $dollar = $self->{dollar} && $co >= $self->{dollar} - 1;
+
+ my $r = $br;
+ while ($r <= $er) {
+ my $line = $self->line($r);
+ if ($bc < $line->l) {
+ $ec = $line->l if $dollar;
+ my ($br, $bc) = $line->coord_of($bc);
+ my ($er, $ec) = $line->coord_of($ec <= $line->l ? $ec : $line->l);
+ $self->scr_xor_span($br, $bc, $er, $ec, $hl);
+ } elsif ($r == $cr) {
+ $reverse_cursor = 0;
+ }
+ $r = $line->end + 1;
+ }
+ } else {
+ $self->scr_xor_span($br, $bc, $er, $ec, $hl);
+ }
+
+ if ($reverse_cursor) {
+ # make the cursor visible again
+ $self->scr_xor_span($cr, $cc, $cr, $cc + 1, $hl);
+ }
+ }
+
+ ()
+}
+
+
+sub activate {
+ my ($self, $search) = @_;
+
+ $self->{active} = 1;
+
+ $self->{select} = '';
+ $self->{dollar} = 0;
+ $self->{move_to} = 0;
+
+ if ($search) {
+ $self->{search} = '?';
+ $self->{search_dir} = -1;
+ $self->{search_mode} = 1;
+ } else {
+ $self->{search} = '';
+ $self->{search_mode} = 0;
+ }
+
+ ($self->{oldcr}, $self->{oldcc}) = $self->screen_cur();
+ ($self->{srhcr}, $self->{srhcc}) = $self->screen_cur();
+ $self->{old_view_start} = $self->view_start();
+ $self->{old_pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE);
+
+ my $line = $self->line($self->{oldcr});
+ $self->{offset} = $line->offset_of($self->{oldcr}, $self->{oldcc});
+
+ $self->selection_beg(1, 0);
+ $self->selection_end(1, 0);
+
+ $self->enable(
+ key_press => \&key_press,
+ refresh_begin => \&refresh,
+ refresh_end => \&refresh,
+ tt_write => \&tt_write,
+ );
+
+ if ($self->{offset} >= $line->l) {
+ $self->{offset} = $line->l > 0 ? $line->l - 1 : 0;
+ $self->screen_cur($line->coord_of($self->{offset}));
+ $self->want_refresh();
+ }
+
+ $self->{overlay_len} = 0;
+ status_area($self);
+
+ ()
+}
+
+
+sub deactivate {
+ my ($self) = @_;
+
+ $self->selection_beg(1, 0);
+ $self->selection_end(1, 0);
+
+ delete $self->{overlay} if $self->{overlay};
+
+ $self->disable("key_press", "refresh_begin", "refresh_end", "tt_write");
+ $self->screen_cur($self->{oldcr}, $self->{oldcc});
+ $self->view_start($self->{old_view_start});
+ $self->pty_ev_events($self->{old_pty_ev_events});
+
+ $self->want_refresh();
+
+ $self->{active} = 0;
+
+ ()
+}
+
+
+sub status_area {
+ my ($self, $extra) = @_;
+ my ($stat, $stat_len);
+
+ if ($self->{search}) {
+ $stat_len = $self->ncol;
+ $stat = $self->{search} . ' ' x ($stat_len - length($self->{search}));
+ } else {
+ if ($self->{select}) {
+ $stat = "-V" . ($self->{select} ne 'n' ? uc($self->{select}) : "") . "- ";
+ }
+
+ if ($self->top_row == 0) {
+ $stat .= "All";
+ } elsif ($self->view_start() == $self->top_row) {
+ $stat .= "Top";
+ } elsif ($self->view_start() == 0) {
+ $stat .= "Bot";
+ } else {
+ $stat .= sprintf("%2d%%",
+ ($self->top_row - $self->view_start) * 100 / $self->top_row);
+ }
+
+ $stat = "$extra $stat" if $extra;
+ $stat_len = length($stat);
+ }
+
+ if (!$self->{overlay} || $self->{overlay_len} != $stat_len) {
+ delete $self->{overlay} if $self->{overlay};
+ $self->{overlay} = $self->overlay(-1, -1, $stat_len, 1,
+ urxvt::OVERLAY_RSTYLE, 0);
+ $self->{overlay_len} = $stat_len;
+ }
+
+ $self->{overlay}->set(0, 0, $self->special_encode($stat));
+ $self->{overlay}->show();
+
+ ()
+}
+
+
+sub toggle_select {
+ my ($self, $mode) = @_;
+
+ if ($self->{select} eq $mode) {
+ $self->{select} = '';
+ } else {
+ if (not $self->{select}) {
+ ($self->{ar}, $self->{ac}) = $self->screen_cur();
+ }
+ $self->{select} = $mode;
+ }
+
+ status_area($self);
+ $self->want_refresh();
+
+ ()
+}
+
+
+sub calc_span {
+ my ($self) = @_;
+ my ($cr, $cc) = $self->screen_cur();
+ my ($br, $bc, $er, $ec);
+
+ if ($self->{select} eq 'b') {
+ $br = $self->line($cr)->beg;
+ $bc = $self->line($cr)->offset_of($cr, $cc);
+ $er = $self->line($self->{ar})->beg;
+ $ec = $self->line($self->{ar})->offset_of($self->{ar}, $self->{ac});
+ ($br, $er) = ($er, $br) if $br > $er;
+ ($bc, $ec) = ($ec, $bc) if $bc > $ec;
+ } else {
+ if ($cr < $self->{ar}) {
+ ($br, $bc, $er, $ec) = ($cr, $cc, $self->{ar}, $self->{ac});
+ } elsif ($cr > $self->{ar}) {
+ ($br, $bc, $er, $ec) = ($self->{ar}, $self->{ac}, $cr, $cc);
+ } else {
+ ($br, $er) = ($cr, $cr);
+ ($bc, $ec) = $cc < $self->{ac} ? ($cc, $self->{ac}) : ($self->{ac}, $cc);
+ }
+ }
+
+ if ($self->{select} eq 'l') {
+ ($br, $er) = ($self->line($br)->beg, $self->line($er)->end);
+ ($bc, $ec) = (0, $self->ncol);
+ } else {
+ ++$ec;
+ }
+
+ return ($br, $bc, $er, $ec);
+}
diff --git a/urxvt/ext/url-select b/urxvt/ext/url-select
new file mode 100644
index 0000000..1afbd70
--- /dev/null
+++ b/urxvt/ext/url-select
@@ -0,0 +1,410 @@
+#!/usr/bin/perl
+# Author: Bert Muennich
+# Website: http://www.github.com/muennich/urxvt-perls
+# Based on: http://www.jukie.net/~bart/blog/urxvt-url-yank
+# License: GPLv2
+
+# Use keyboard shortcuts to select URLs.
+# This should be used as a replacement for the default matcher extension,
+# it also makes URLs clickable with the middle mouse button.
+
+# Usage: put the following lines in your .Xdefaults/.Xresources:
+# URxvt.perl-ext-common: ...,url-select
+# URxvt.keysym.M-u: perl:url-select:select_next
+
+# Use Meta-u to activate URL selection mode, then use the following keys:
+# j/k: Select next downward/upward URL (also with arrow keys)
+# g/G: Select first/last URL (also with home/end key)
+# o/Return: Open selected URL in browser, Return: deactivate afterwards
+# y: Copy (yank) selected URL and deactivate selection mode
+# q/Escape: Deactivate URL selection mode
+
+# Options:
+# URxvt.url-select.autocopy: If true, selected URLs are copied to PRIMARY
+# URvxt.url-select.button: Mouse button to click-open URLs (default: 2)
+# URxvt.url-select.launcher: Browser/command to open selected URL with
+# URxvt.url-select.underline: If set to true, all URLs get underlined
+
+
+use strict;
+use warnings;
+
+# The custom rendition bit to use for marking the cell as being underlined
+# by us so we can unset it again after a line has changed.
+use constant UNDERLINED => 1<<3; # arbitrarily chosen in hope of no collision
+
+sub on_start {
+ my ($self) = @_;
+
+ # read resource settings
+ if ($self->x_resource('url-select.launcher')) {
+ @{$self->{browser}} = split /\s+/, $self->x_resource('url-select.launcher');
+ } else {
+ @{$self->{browser}} = ('x-www-browser');
+ }
+ if ($self->x_resource('url-select.underline') eq 'true') {
+ $self->enable(line_update => \&line_update);
+ }
+ if ($self->x_resource('url-select.autocopy') eq 'true') {
+ $self->{autocopy} = 1;
+ }
+
+ $self->{state} = 0;
+
+ for my $mod (split '', $self->x_resource("url-select.button") ||
+ $self->x_resource("matcher.button") || 2) {
+ if ($mod =~ /^\d+$/) {
+ $self->{button} = $mod;
+ } elsif ($mod eq "C") {
+ $self->{state} |= urxvt::ControlMask;
+ } elsif ($mod eq "S") {
+ $self->{state} |= urxvt::ShiftMask;
+ } elsif ($mod eq "M") {
+ $self->{state} |= $self->ModMetaMask;
+ } elsif ($mod ne "-" && $mod ne " ") {
+ warn("invalid button/modifier in $self->{_name}<$self->{argv}[0]>: $mod\n");
+ }
+ }
+
+ if ($self->x_resource('matcher.pattern')) {
+ @{$self->{pattern}} = ($self->x_resource('matcher.pattern'));
+ } elsif ($self->x_resource('matcher.pattern.0')) {
+ my $current = 0;
+
+ while (defined (my $res = $self->x_resource("matcher.pattern.$current"))) {
+ $res = $self->locale_decode($res);
+ utf8::encode $res;
+ push @{$self->{pattern}}, qr($res)x;
+ $current++;
+ }
+ } else {
+ @{$self->{pattern}} = qr{
+ (?:https?://|ftp://|news://|mailto:|file://|\bwww\.)
+ [\w\-\@;\/?:&=%\$.+!*\x27,~#]*
+ (
+ \([\w\-\@;\/?:&=%\$.+!*\x27,~#]*\) # Allow a pair of matched parentheses
+ | #
+ [\w\-\@;\/?:&=%\$+*~] # exclude some trailing characters (heuristic)
+ )+
+ }x;
+ }
+
+ ()
+}
+
+
+sub line_update {
+ my ($self, $row) = @_;
+
+ my $line = $self->line($row);
+ my $text = $line->t;
+ my $rend = $line->r;
+
+ # clear all underlines that were set by us
+ for (@$rend) {
+ if (urxvt::GET_CUSTOM($_) & UNDERLINED) {
+ $_ = urxvt::SET_CUSTOM($_, urxvt::GET_CUSTOM($_) & ~UNDERLINED) &
+ ~urxvt::RS_Uline;
+ }
+ }
+
+ for my $pattern (@{$self->{pattern}}) {
+ while ($text =~ /$pattern/g) {
+ my $url = $&;
+ my ($beg, $end) = ($-[0], $+[0] - 1);
+
+ for (@{$rend}[$beg .. $end]) {
+ unless ($_ & urxvt::RS_Uline) {
+ $_ = urxvt::SET_CUSTOM($_, urxvt::GET_CUSTOM($_) | UNDERLINED);
+ $_ |= urxvt::RS_Uline;
+ }
+ }
+ }
+ }
+
+ $line->r($rend);
+
+ ()
+}
+
+sub on_action {
+ my ($self, $action) = @_;
+
+ on_user_command($self, "url-select:" . $action);
+}
+
+
+sub on_user_command {
+ my ($self, $cmd) = @_;
+
+ if ($cmd eq 'url-select:select_next') {
+ if (not $self->{active}) {
+ activate($self);
+ }
+ select_next($self, -1);
+ }
+
+ ()
+}
+
+
+sub key_press {
+ my ($self, $event, $keysym) = @_;
+ my $char = chr($keysym);
+
+ if ($keysym == 0xff1b || lc($char) eq 'q' ||
+ (lc($char) eq 'c' && $event->{state} & urxvt::ControlMask)) {
+ deactivate($self);
+ } elsif ($keysym == 0xff0d || $char eq 'o' ||
+ (lc($char) eq 'm' && $event->{state} & urxvt::ControlMask)) {
+ $self->exec_async(@{$self->{browser}}, ${$self->{found}[$self->{n}]}[4]);
+ deactivate($self) unless $char eq 'o';
+ } elsif ($char eq 'y') {
+ my $found = $self->{found}[$self->{n}];
+ $self->selection_beg(${$found}[0], ${$found}[1]);
+ $self->selection_end(${$found}[2], ${$found}[3]);
+ $self->selection_make($event->{time});
+ $self->selection_beg(1, 0);
+ $self->selection_end(1, 0);
+ deactivate($self);
+ } elsif ($char eq 'k' || $keysym == 0xff52 || $keysym == 0xff51) {
+ select_next($self, -1, $event);
+ } elsif ($char eq 'j' || $keysym == 0xff54 || $keysym == 0xff53) {
+ select_next($self, 1, $event);
+ } elsif ($char eq 'g' || $keysym == 0xff50) {
+ $self->{row} = $self->top_row - 1;
+ delete $self->{found};
+ select_next($self, 1, $event);
+ } elsif ($char eq 'G' || $keysym == 0xff57) {
+ $self->{row} = $self->nrow;
+ delete $self->{found};
+ select_next($self, -1, $event);
+ }
+
+ return 1;
+}
+
+
+sub on_button_press {
+ my ($self, $event) = @_;
+
+ my $mask = $self->ModLevel3Mask | $self->ModMetaMask |
+ urxvt::ShiftMask | urxvt::ControlMask;
+
+ if ($event->{button} == $self->{button} && ($event->{state} & $mask) == $self->{state}) {
+ my $col = $event->{col};
+ my $row = $event->{row};
+ my $line = $self->line($row);
+ my $text = $line->t;
+
+ for my $pattern (@{$self->{pattern}}) {
+ while ($text =~ /$pattern/g) {
+ my ($url, $beg, $end) = ($&, $-[0], $+[0]);
+ --$end if $url =~ s/["')]$//;
+
+ if ($col >= $beg && $col <= $end) {
+ $self->{button_pressed} = 1;
+ $self->{button_col} = $col;
+ $self->{button_row} = $row;
+ $self->{button_url} = $url;
+ return 1;
+ }
+ }
+ }
+ }
+
+ ()
+}
+
+sub on_button_release {
+ my ($self, $event) = @_;
+
+ if ($self->{button_pressed} && $event->{button} == $self->{button}) {
+ my $col = $event->{col};
+ my $row = $event->{row};
+
+ $self->{button_pressed} = 0;
+
+ if ($col == $self->{button_col} && $row == $self->{button_row}) {
+ $self->exec_async(@{$self->{browser}}, $self->{button_url});
+ return 1;
+ }
+ }
+
+ ()
+}
+
+
+sub select_next {
+ # $dir < 0: up, > 0: down
+ my ($self, $dir, $event) = @_;
+ my $row = $self->{row};
+
+ if (($dir < 0 && $self->{n} > 0) ||
+ ($dir > 0 && $self->{n} < $#{ $self->{found} })) {
+ # another url on current line
+ $self->{n} += $dir;
+ hilight($self);
+ if ($self->{autocopy}) {
+ my $found = $self->{found}[$self->{n}];
+ $self->selection_beg(${$found}[0], ${$found}[1]);
+ $self->selection_end(${$found}[2], ${$found}[3]);
+ $self->selection_make($event->{time});
+ $self->selection_beg(1, 0);
+ $self->selection_end(1, 0);
+ }
+ return;
+ }
+
+ while (($dir < 0 && $row > $self->top_row) ||
+ ($dir > 0 && $row < $self->nrow - 1)) {
+ my $line = $self->line($row);
+ $row = ($dir < 0 ? $line->beg : $line->end) + $dir;
+ $line = $self->line($row);
+ my $text = $line->t;
+
+ for my $pattern (@{$self->{pattern}}) {
+ if ($text =~ /$pattern/g) {
+ delete $self->{found};
+
+ do {
+ my ($beg, $end) = ($-[0], $+[0]);
+ push @{$self->{found}}, [$line->coord_of($beg),
+ $line->coord_of($end), substr($text, $beg, $end - $beg)];
+ } while ($text =~ /$pattern/g);
+
+ $self->{row} = $row;
+ $self->{n} = $dir < 0 ? $#{$self->{found}} : 0;
+ hilight($self);
+ if ($self->{autocopy}) {
+ my $found = $self->{found}[$self->{n}];
+ $self->selection_beg(${$found}[0], ${$found}[1]);
+ $self->selection_end(${$found}[2], ${$found}[3]);
+ $self->selection_make($event->{time});
+ $self->selection_beg(1, 0);
+ $self->selection_end(1, 0);
+ }
+ return;
+ }
+ }
+ }
+
+ deactivate($self) unless $self->{found};
+
+ ()
+}
+
+
+sub hilight {
+ my ($self) = @_;
+
+ if ($self->{found}) {
+ if ($self->{row} < $self->view_start() ||
+ $self->{row} >= $self->view_start() + $self->nrow) {
+ # scroll selected url into visible area
+ my $top = $self->{row} - ($self->nrow >> 1);
+ $self->view_start($top < 0 ? $top : 0);
+ }
+
+ status_area($self);
+ $self->want_refresh();
+ }
+
+ ()
+}
+
+
+sub refresh {
+ my ($self) = @_;
+
+ if ($self->{found}) {
+ if ($self->x_resource('highlightColor')) {
+ $self->scr_xor_span(@{$self->{found}[$self->{n}]}[0 .. 3], urxvt::RS_Sel);
+ } else {
+ $self->scr_xor_span(@{$self->{found}[$self->{n}]}[0 .. 3], urxvt::RS_RVid);
+ }
+ }
+
+ ()
+}
+
+
+sub status_area {
+ my ($self) = @_;
+
+ my $row = $self->{row} < 0 ?
+ $self->{row} - $self->top_row : abs($self->top_row) + $self->{row};
+ my $text = sprintf("%d,%d ", $row + 1, $self->{n} + 1);
+
+ if ($self->top_row == 0) {
+ $text .= "All";
+ } elsif ($self->view_start() == $self->top_row) {
+ $text .= "Top";
+ } elsif ($self->view_start() == 0) {
+ $text .= "Bot";
+ } else {
+ $text .= sprintf("%2d%",
+ ($self->top_row - $self->view_start) * 100 / $self->top_row);
+ }
+
+ my $text_len = length($text);
+
+ if ($self->{overlay_len} != $text_len) {
+ delete $self->{overlay} if $self->{overlay};
+ $self->{overlay} = $self->overlay(-1, -1, $text_len, 1,
+ urxvt::OVERLAY_RSTYLE, 0);
+ $self->{overlay_len} = $text_len;
+ }
+
+ $self->{overlay}->set(0, 0, $self->special_encode($text));
+ $self->{overlay}->show();
+
+ ()
+}
+
+
+sub tt_write {
+ return 1;
+}
+
+
+sub activate {
+ my ($self) = @_;
+
+ $self->{active} = 1;
+
+ $self->{row} = $self->view_start() + $self->nrow;
+ $self->{n} = 0;
+ $self->{overlay_len} = 0;
+ $self->{button_pressed} = 0;
+
+ $self->{view_start} = $self->view_start();
+ $self->{pty_ev_events} = $self->pty_ev_events(urxvt::EV_NONE);
+
+ $self->enable(
+ key_press => \&key_press,
+ refresh_begin => \&refresh,
+ refresh_end => \&refresh,
+ tt_write => \&tt_write,
+ );
+
+ ()
+}
+
+
+sub deactivate {
+ my ($self) = @_;
+
+ $self->disable("key_press", "refresh_begin", "refresh_end", "tt_write");
+ $self->view_start($self->{view_start});
+ $self->pty_ev_events($self->{pty_ev_events});
+
+ delete $self->{overlay} if $self->{overlay};
+ delete $self->{found} if $self->{found};
+
+ $self->want_refresh();
+
+ $self->{active} = 0;
+
+ ()
+}
diff --git a/urxvt/ext/vtwheel b/urxvt/ext/vtwheel
new file mode 100644
index 0000000..7f51226
--- /dev/null
+++ b/urxvt/ext/vtwheel
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+# Implements a scrollwheel just like in good old vt100's mices
+
+sub simulate_keypress {
+ my ($self, $type) = @_; #type: 0:up, 1:down
+
+ my $keycode_up = 111;
+ my $keycode_down = 116;
+
+ my $numlines = 3;
+
+ my $keycode = 0;
+ if ($type eq 0) {
+ $keycode = $keycode_up;
+ } elsif ($type eq 1) {
+ $keycode = $keycode_down;
+ } else {
+ return;
+ }
+
+ for (my $i = 0 ; $i ne $numlines ; $i++) {
+ $self->key_press(0,$keycode);
+ $self->key_release(0,$keycode);
+ }
+}
+
+sub on_button_release {
+ my ($self, $event) = @_;
+
+ #my $res_ss = $self->resource("secondaryScroll");
+ #warn("ressource ss is <$res_ss>");
+
+ !$self->current_screen and return ();
+
+ #warn("foo, event: <$event->{button}>\n");
+ if ($event->{button} eq "4") { # scroll up
+ $self->simulate_keypress(0);
+ return 1;
+ } elsif ($event->{button} eq "5") { # scroll down
+ $self->simulate_keypress(1);
+ return 1;
+ }
+
+ return ();
+}
diff --git a/wyrdrc b/wyrdrc
new file mode 100644
index 0000000..b161421
--- /dev/null
+++ b/wyrdrc
@@ -0,0 +1,3 @@
+include "/etc/wyrdrc"
+
+set week_starts_monday="true"
diff --git a/xfce-terminalrc b/xfce-terminalrc
new file mode 100644
index 0000000..38e8aae
--- /dev/null
+++ b/xfce-terminalrc
@@ -0,0 +1,31 @@
+[Configuration]
+FontName=Fira Mono 14
+MiscAlwaysShowTabs=FALSE
+MiscBell=FALSE
+MiscBellUrgent=FALSE
+MiscBordersDefault=TRUE
+MiscCursorBlinks=FALSE
+MiscCursorShape=TERMINAL_CURSOR_SHAPE_BLOCK
+MiscDefaultGeometry=80x24
+MiscInheritGeometry=FALSE
+MiscMenubarDefault=FALSE
+MiscMouseAutohide=FALSE
+MiscMouseWheelZoom=TRUE
+MiscToolbarDefault=FALSE
+MiscConfirmClose=TRUE
+MiscCycleTabs=TRUE
+MiscTabCloseButtons=TRUE
+MiscTabCloseMiddleClick=TRUE
+MiscTabPosition=GTK_POS_TOP
+MiscHighlightUrls=TRUE
+MiscMiddleClickOpensUri=FALSE
+MiscCopyOnSelect=FALSE
+MiscShowRelaunchDialog=TRUE
+MiscRewrapOnResize=TRUE
+MiscUseShiftArrowsToScroll=FALSE
+MiscSlimTabs=FALSE
+MiscNewTabAdjacent=FALSE
+ColorCursor=#a2a2a2a2a2a2
+ColorForeground=#a2a2a2a2a2a2
+ColorBackground=#1d2021
+ColorPalette=#555555555555;#9c9c35352828;#6161bcbc3b3b;#f3f3b4b43a3a;#0d0d6868a8a8;#747445456060;#28288e8e9c9c;#a2a2a2a2a2a2;#888888888888;#d6d649493737;#8686dfdf5d5d;#fdfdd7d75a5a;#0f0f7575bdbd;#9e9e5e5e8383;#3737c3c3d6d6;#f9f9f9f9f9f9
diff --git a/xfce4/terminal/accels.scm b/xfce4/terminal/accels.scm
new file mode 100644
index 0000000..43521c9
--- /dev/null
+++ b/xfce4/terminal/accels.scm
@@ -0,0 +1,56 @@
+; xfce4-terminal GtkAccelMap rc-file -*- scheme -*-
+; this file is an automated accelerator map dump
+;
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-1" "<Alt>1")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-3" "<Alt>3")
+; (gtk_accel_path "<Actions>/terminal-window/file-menu" "")
+; (gtk_accel_path "<Actions>/terminal-window/close-other-tabs" "")
+; (gtk_accel_path "<Actions>/terminal-window/search" "<Primary><Shift>f")
+; (gtk_accel_path "<Actions>/terminal-window/next-tab" "<Primary>Page_Down")
+; (gtk_accel_path "<Actions>/terminal-window/copy-html" "")
+; (gtk_accel_path "<Actions>/terminal-window/show-menubar" "")
+; (gtk_accel_path "<Actions>/terminal-window/zoom-reset" "<Primary>0")
+; (gtk_accel_path "<Actions>/terminal-window/close-window" "<Primary><Shift>q")
+; (gtk_accel_path "<Actions>/terminal-window/save-contents" "")
+; (gtk_accel_path "<Actions>/terminal-window/close-tab" "<Primary><Shift>w")
+; (gtk_accel_path "<Actions>/terminal-window/view-menu" "")
+; (gtk_accel_path "<Actions>/terminal-window/new-tab" "<Primary><Shift>t")
+; (gtk_accel_path "<Actions>/terminal-window/show-toolbar" "")
+; (gtk_accel_path "<Actions>/terminal-window/copy-input" "")
+; (gtk_accel_path "<Actions>/terminal-window/paste" "<Primary><Shift>v")
+; (gtk_accel_path "<Actions>/terminal-window/copy" "<Primary><Shift>c")
+; (gtk_accel_path "<Actions>/terminal-window/edit-menu" "")
+; (gtk_accel_path "<Actions>/terminal-window/fullscreen" "F11")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-6" "<Alt>6")
+; (gtk_accel_path "<Actions>/terminal-window/read-only" "")
+; (gtk_accel_path "<Actions>/terminal-window/detach-tab" "<Primary><Shift>d")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-8" "<Alt>8")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-2" "<Alt>2")
+; (gtk_accel_path "<Actions>/terminal-window/scroll-on-output" "")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-5" "<Alt>5")
+; (gtk_accel_path "<Actions>/terminal-window/prev-tab" "<Primary>Page_Up")
+; (gtk_accel_path "<Actions>/terminal-window/move-tab-left" "<Primary><Shift>Page_Up")
+; (gtk_accel_path "<Actions>/terminal-window/zoom-in" "<Primary>plus")
+; (gtk_accel_path "<Actions>/terminal-window/search-prev" "")
+; (gtk_accel_path "<Actions>/terminal-window/reset-and-clear" "")
+; (gtk_accel_path "<Actions>/terminal-window/about" "")
+; (gtk_accel_path "<Actions>/terminal-window/search-next" "")
+(gtk_accel_path "<Actions>/terminal-window/toggle-menubar" "F10")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-7" "<Alt>7")
+; (gtk_accel_path "<Actions>/terminal-window/select-all" "<Primary><Shift>a")
+; (gtk_accel_path "<Actions>/terminal-window/help-menu" "")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-9" "<Alt>9")
+; (gtk_accel_path "<Actions>/terminal-window/show-borders" "")
+; (gtk_accel_path "<Actions>/terminal-window/new-window" "<Primary><Shift>n")
+(gtk_accel_path "<Actions>/terminal-window/goto-tab-4" "<Alt>4")
+; (gtk_accel_path "<Actions>/terminal-window/contents" "F1")
+; (gtk_accel_path "<Actions>/terminal-window/preferences" "")
+; (gtk_accel_path "<Actions>/terminal-window/move-tab-right" "<Primary><Shift>Page_Down")
+; (gtk_accel_path "<Actions>/terminal-window/zoom-out" "<Primary>minus")
+; (gtk_accel_path "<Actions>/terminal-window/set-title" "<Primary><Shift>s")
+; (gtk_accel_path "<Actions>/terminal-window/paste-selection" "")
+; (gtk_accel_path "<Actions>/terminal-window/undo-close-tab" "")
+; (gtk_accel_path "<Actions>/terminal-window/tabs-menu" "")
+; (gtk_accel_path "<Actions>/terminal-window/zoom-menu" "")
+; (gtk_accel_path "<Actions>/terminal-window/reset" "")
+; (gtk_accel_path "<Actions>/terminal-window/terminal-menu" "")
diff --git a/xfce4/terminal/terminalrc b/xfce4/terminal/terminalrc
new file mode 100644
index 0000000..fe7af8c
--- /dev/null
+++ b/xfce4/terminal/terminalrc
@@ -0,0 +1,29 @@
+[Configuration]
+FontName=NotoMono Nerd Font Mono 14
+MiscAlwaysShowTabs=FALSE
+MiscBell=FALSE
+MiscBellUrgent=FALSE
+MiscBordersDefault=FALSE
+MiscCursorBlinks=FALSE
+MiscCursorShape=TERMINAL_CURSOR_SHAPE_UNDERLINE
+MiscDefaultGeometry=80x24
+MiscInheritGeometry=FALSE
+MiscMenubarDefault=FALSE
+MiscMouseAutohide=FALSE
+MiscMouseWheelZoom=TRUE
+MiscToolbarDefault=FALSE
+MiscConfirmClose=FALSE
+MiscCycleTabs=TRUE
+MiscTabCloseButtons=TRUE
+MiscTabCloseMiddleClick=TRUE
+MiscTabPosition=GTK_POS_TOP
+MiscHighlightUrls=TRUE
+MiscMiddleClickOpensUri=FALSE
+MiscCopyOnSelect=FALSE
+MiscShowRelaunchDialog=TRUE
+MiscRewrapOnResize=TRUE
+MiscUseShiftArrowsToScroll=FALSE
+MiscSlimTabs=FALSE
+MiscNewTabAdjacent=FALSE
+ScrollingBar=TERMINAL_SCROLLBAR_NONE
+
diff --git a/xinitrc b/xinitrc
new file mode 100644
index 0000000..a57fd88
--- /dev/null
+++ b/xinitrc
@@ -0,0 +1 @@
+autocutsel
diff --git a/xmonad/xmonad-x86_64-linux b/xmonad/xmonad-x86_64-linux
new file mode 100644
index 0000000..5612d37
--- /dev/null
+++ b/xmonad/xmonad-x86_64-linux
Binary files differ
diff --git a/xmonad/xmonad.errors b/xmonad/xmonad.errors
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/xmonad/xmonad.errors
diff --git a/xmonad/xmonad.hi b/xmonad/xmonad.hi
new file mode 100644
index 0000000..5128aff
--- /dev/null
+++ b/xmonad/xmonad.hi
Binary files differ
diff --git a/xmonad/xmonad.hs b/xmonad/xmonad.hs
new file mode 100644
index 0000000..4b0d3eb
--- /dev/null
+++ b/xmonad/xmonad.hs
@@ -0,0 +1,22 @@
+import XMonad
+import XMonad.Hooks.ManageDocks
+import XMonad.Hooks.SetWMName
+import XMonad.Config.Xfce
+import XMonad.Layout.NoBorders
+import XMonad.Hooks.EwmhDesktops
+
+myLayout = tiled ||| Mirror tiled ||| Full
+ where
+ tiled = Tall 1 (3/100) (3/5)
+
+main = xmonad xfceConfig
+ { terminal = "xfce4-terminal"
+ , layoutHook = avoidStruts $ smartBorders $ myLayout
+ , handleEventHook = ewmhDesktopsEventHook
+ , borderWidth = 1
+ , normalBorderColor = "#000000'"
+ , focusedBorderColor = "#ff3f3f"
+ , modMask = mod4Mask
+-- , startupHook = ewmhDesktopsStartup
+ , startupHook = setWMName "LG3D" -- this is purely to get Minecraft working in xmonad
+ }
diff --git a/xmonad/xmonad.hs.bak b/xmonad/xmonad.hs.bak
new file mode 100644
index 0000000..b1172ed
--- /dev/null
+++ b/xmonad/xmonad.hs.bak
@@ -0,0 +1,7 @@
+import XMonad
+import XMonad.Config.Xfce
+
+main = xmonad xfceConfig
+ { terminal = "xterm"
+ , modMask = mod4Mask
+ }
diff --git a/xmonad/xmonad.o b/xmonad/xmonad.o
new file mode 100644
index 0000000..51c7a54
--- /dev/null
+++ b/xmonad/xmonad.o
Binary files differ
diff --git a/xsession b/xsession
new file mode 100644
index 0000000..701eb9b
--- /dev/null
+++ b/xsession
@@ -0,0 +1,4 @@
+xset s off # don't activate screensaver
+xset -dpms # disable DPMS (Energy Star) features.
+xsetroot -solid "#333333"
+xset b off # stop the fucking beep
diff --git a/xsessionrc b/xsessionrc
new file mode 100644
index 0000000..6dd2b61
--- /dev/null
+++ b/xsessionrc
@@ -0,0 +1,9 @@
+sh ~/.screenlayout/desktop_layout_debian_all_landscape.sh &
+# nextcloud & # doesnt work!
+xfce4-clipman &
+#
+# Statusbar loop
+while true; do
+ xsetroot -name "$( date +"%F %R" )"
+ sleep 1m # Update time every minute
+done &
diff --git a/youtube-dl-config b/youtube-dl-config
new file mode 100644
index 0000000..c3851a3
--- /dev/null
+++ b/youtube-dl-config
@@ -0,0 +1 @@
+-o %(title)s.%(ext)s
diff --git a/zathurarc b/zathurarc
new file mode 100644
index 0000000..9fa50ca
--- /dev/null
+++ b/zathurarc
@@ -0,0 +1,12 @@
+set statusbar-h-padding 0
+set statusbar-v-padding 0
+set page-padding 1
+map u scroll half-up
+map d scroll half-down
+map D toggle_page_mode
+map r reload
+map R rotate
+map K zoom in
+map J zoom out
+map i recolor
+map p print