diff --git a/.emacs b/.emacs deleted file mode 100644 index 88f3ce0..0000000 --- a/.emacs +++ /dev/null @@ -1,6792 +0,0 @@ -;; Toms Emacs Config - portable - version ("20210501.01") -*-emacs-lisp-*- -;; * Introduction - -;; This is my emacs config, it is more than twenty years old. It -;; mostly contains stuff implemented by myself, but there are also -;; snippets I found here and there. The config will probably not be -;; usefull for anyone else but myself. - -;; If you're reading the html exported version: be advised, that I do -;; NOT maintain my emacs config with "literate programming". Instead I -;; maintain a plain old .emacs file, which I use at home and work, on -;; windows, linux and freebsd, console or X11. I use outshine minor -;; mode to organize my config and I use outorg to export it to org -;; mode and from there to html. - -;; Also I don't use any packaging mechanism, instead I download all -;; the required elisp files manually and update them only if -;; required. There's a melpa config toggle though, which I only use to -;; try out new modes. I distribute my .emacs config along with the -;; lisp directory to all systems where I need it using a Makefile and -;; scp. The reason is that I work on a couple of systems without -;; direct internet access, where packaging or git don't work. So, I -;; don't use these things nowhere. It's ok for me, I'm used to it. - -;; Another thing you might wonder about are my key bindings or -;; (sometimes) the lack thereof. My problem with key bindings is that -;; I don't have any useful prefixes left. I am using ONLY commandline -;; tools, my window manager is Xmonad, I use screen, bash and -;; mutt. The only applications where I use the mouse is firefox and -;; gimp. So, it is very hard to avoid conflicts AND memoize new key -;; bindings. Some key bindings are so deeply wired into muscle memory -;; that I could use them while drunk or dying. - -;; Therefore I use lots of aliases in emacs for not-so-regular used -;; functions, which turned out to be sometimes easier to type than an -;; actual key binding. - -;; The html export has been created with the function -;; outshine-to-html, written by myself, see below. - - -;; * Config Log, Trivia, Notes, Changes -;; ** Changelog - -;; 20160420.03: -;; - started with Changelog and outshine mode -;; - fixed tabs -;; - reorganized keys -;; - added new goto line func - -;; 20160421.01: -;; - added smex -;; - added show-keys() -;; - added redo -;; - ssh et. al. interactive in eshell -;; - added recompile() - -;; 20160421.02: -;; - added dividers -;; - using org headers -;; - better show-keys() - -;; 20160421.03: -;; - added windows support - -;; 20160421.04: -;; - added elisp repl support - -;; 20160424.01: -;; - added custom modeline -;; - added which-func-mode -;; - shortened some major mode names -;; - added diminish for shorter minor mode names -;; - added better printing menu - -;; 20160425.01: -;; - fixed ielm integration -;; - C-x e = eval (buffer|region) -;; - C-x C-e = send (buffer|region) to ielm and eval there - -;; 20160425.02: -;; - fix word wrapping - -;; 20160426.01: -;; - fixed mode-line config 4 win emacs -;; - added M- move-region - -;; 20160426.01: -;; - added markdown - -;; 20160427.01+02: -;; - cosmetics - -;; 20160428.01: -;; - fringe cursor - -;; 20160429.01: -;; - file name completion -;; - C-# finally, search for symbol at point -;; - C-c C-c now comments or uncomments regios or line, whatever is current - -;; 20160501.01: -;; - no outshine minor in python -;; - added recent files support - -;; 20160501.02: -;; - added margin() function, no key binding though - -;; 20160503.01: -;; - added C-q fill+justify paragraph macro -;; - added alias 'i' for info manuals - -;; 20160503.02: -;; - added 'cp to create read-only buffer copy - -;; 20160504.01: -;; - better fringe, now also inversed with C-c i - -;; 20160505.01: -;; - added electric-align mode -;; - better outline header colors -;; - no more line numbers in sk occur buffer - -;; 20160507.01: -;; - disable electric-align-momde (broken), using M-x align instead -;; - hightlighting TABs with extra font - -;; 20160509.01: -;; - fixed margin() -;; - discovered that C-x 0 deletes current window, god did I miss this one! - -;; 20160510.01: -;; - added kill-all-buffers() -;; 20160510.02: -;; - no more load-file -;; - added C-c [wlpa]: easy copy things at point -;; without marking them - -;; 20160511.01: -;; - better buffer names with uniquify - -;; 20160511.02: -;; - copy-* functions now blink region -;; - added del-* functions, bound to C-d: -;; press multiple times to delete word, line, paragraph, buffer - -;; 20160513.01: -;; - fixed END key func - -;; 20160516.01: -;; - removed C-d stuff, replaced with vikiing-mode - -;; 20160517.01: -;; - changed highlight face -;; - enabled debug-on-error in lispmode -;; - enabled IDO mode globally, I just tend to love love love it - -;; 20160517.02: -;; - added workgroup.el, started experimenting -;; - enabled Super_L (for workgroups) - -;; 20160519.01: -;; - fixed write-file, now ido mode is disabled for this one. - -;; 20160520.01: -;; - no x-sel on windows (C-v+C-c => emacs doesn't work anymore otherwise) -;; - added eldoc mode to elisp hook - -;; 20160520.02: -;; - added novel-mode, for better reading - -;; 20160522.01: -;; - added vi's % jump paren emulation -;; - enhanced novel-mode -;; - enabled save-place mode which is VERY useful in combination with -;; novel-mode - -;; 20160523.01: -;; - detached novel-mode into its own module, maintain on github -;; enabled with C-n - -;; 20160526.01: -;; - added toggle-melpa - -;; 20160527.01: -;; - added htmlize - -;; 20160529.01: -;; - added html-listify - -;; 20160530.01: -;; - added key chords -;; - added open-line-above+below - -;; 20160602.01: -;; - C-q now fills and pressing it again un-fills - -;; 20160606.01: -;; - deactivated key-chords, I didn't use them and they were annoying. - -;; 20160609.01: -;; - added puppet mode - -;; 20160614.01: -;; - added rotate-text (C-t) -;; - added macro math (C-x-0) (0 used as =) - -;; 20160713.01: -;; - fixed indent for Makefiles - -;; 20160729.01: -;; - rm duplicate abbr defs - -;; 20160916.01: -;; - enable mouse mark to copy - -;; 20160926.01: -;; - Dont kill-buffer, kill-this-buffer instead - -;; 20160928.01: -;; - change macro math C-x 0 to C-x C-0 so that C-0 is -;; usable again for close window -;; - elisp mode: debug-on-error only on non-cygwin - -;; 20161011.01: -;; - added dos2unix and unix2dos - -;; 20161014.01: -;; - fix auto-indent in conf-mode -;; - force C-c C-c comment-uncomment in conf-mode - -;; 20161018.01: -;; - more effective conf-mode disarming (own defun) - -;; 20161022.01: -;; - better paren mode - -;; 20161024.01: -;; - fixed org mode hook - -;; 20161027.01: -;; - turn off tramp stuff in kill-all-buffers as well, -;; so that after executing it, no more ssh prompt -;; appears on C-x f. - -;; 20161106.01: -;; - added iedit mode with C-c e -;; - added file-open support to eshell (aliases: vi + emacs) -;; - much better C-l behavior in eshell (eshell/clear) - -;; 20161205.01: -;; - added SLIME, sbcl and paredit support, only loaded when exists - -;; 20161206.01: -;; - elisp mode: debug-on-error finally completeley disabled -;; - added alias 'table, which enables org-mode table support everywhere - -;; 20170205.01: -;; - started with ETAGS support - -;; 20170212.01: -;; - added copy-defun (C-c f) to copy whole functions as is - -;; 20170212.02: -;; - now using € (alt-r + e) as jump to etag - -;; 20170215.02: -;; - added goto-last-change (C-b) -;; - +test section -;; - paredit - -;; 20170215.02: -;; - disabled workgoups mode, don't use it, doesn't load correctly -;; - fixed windows switch, no more printing popup on startup - -;; 20170220.01: -;; - finally disabled aggressive-indent, it annoys more than it helps -;; - added some bookmark aliases (bm, to, bl, like apparix) -;; - added C-c y [..] copy+yank functions so that I can copy and paste -;; stuff very fast with one key commbo, like yy in vi. -;; - added copy-parens, copy-quote, copy-help (help message) - -;; 20170220.02: -;; - fixed C-c y y: indent correctly - -;; 20170220.03: -;; - fixed C-y+mouse-2: both use primary selection - -;; 20170221.01: -;; - added which-key - -;; 20170223.01: -;; - org-mode enhancements, C-n capture from everywhere -;; - fixed org-mode todo keywords -;; - fixed duplicate yank on win32 on mouse2 - -;; 20170223.01: -;; - forgot to mv novel-mode to C-c C-n -;; - better org heading faces - -;; 20170224.01: -;; - finally fixed C-t, now works everywhere -;; - added more org short commands - -;; 20170224.02: -;; - fixed org-mode M-return -;; - added support for windmove (WINDOWS-Key+Arrow: switch window) - -;; 20170224.03: -;; - better org colours - -;; 20170224.03: -;; - better org capture tpl (DRAFT) -;; - capturing works now globally, even if no org file is open -;; - using org-indent 4 - -;; 20170224.05: -;; - fixed org tpls - -;; 20170227.01: -;; - fix cut/paste org subtress -;; - M-o now switch buffer if 1 window, else switch window - -;; 20170227.02: -;; - added alias 'dp which displays everything -;; there is to know about point (like current face, mode, etc) - -;; 20170228.01: -;; - org-refile now works recursivly with completion -;; - org-refile also now uses ido-mode and completes in minibuffer -;; - added alias '2table which converts CSV region to table -;; - added shortcut formatting defuns 'bold, 'italic, 'underline and 'code -;; which call 'org-emphasize respectively on current region, -;; including key bindings with org mode keymap (C-c b,/,c,_) -;; - hide emphasized markers in org mode -;; - renamed 'recompile to 'recompile-el and fixed it -;; - added 'info-find-file - -;; 20170301.01: -;; - added 'tvd-org-left-or-level-up bound to in org mode -;; - in org mode now jump up on current level and -;; fold current one and unfolds the target heading -;; - enabled org-bullets -;; - customized height of org-level faces - -;; 20170301.02: -;; - org mode emphasize shortcuts (C-c b...) expand region if -;; theres no region active. - -;; 20170301.03: -;; - dis line num in org (faster) - -;; 20170303.01: -;; - elmacro support added, incl fix for org and outshine, -;; F6 starts (or stops) a macro and displays the generated -;; defun. CTRL-F6 executes the last macro interactively, -;; repeats, a repeats til EOF, q aborts, e enter macro -;; (with completion) -;; - C-x C-s on * elmacro ... * buffer stores it to tvd-macro-file - -;; 20170305.01: -;; - added elmacro defadvice, run after done with macro, it will -;; be evaluated and saved along with a repeater defun. -;; - display red [REC] hint on the mode-line while recording -;; - added ~ shortcut for use inside IDO so I can reach $HOME -;; very fast from everywhere, no more editing pre-filled -;; current path and entering /home/$user/. Yeah! -;; - added flip-window (bound to M-O (ALT-shift-o) -;; - added cleanup-buffer (alias cb) -;; - fixed C- and C-S- - -;; 20170306.01: -;; - re-enabled linenum mode -;; - fixed custom modeline - -;; 20170306.01: -;; - which-func not in elisp anymore -;; - added alias 'ee for 'eval-expression -;; - added 'sa (show-aliases) -;; - some occur enhancements for 'sk and 'sa. -;; - note: inside *Occur*: q:quit, g:reload, e:edit (buffer must be open) - -;; 20170307.01: -;; - fixed 'sk and 'sa -;; - added key bindings to mark things. M-a is the prefix, followed by: -;; a - all, p - paragraph, f - function, l - line, w - word. -;; - disabled M-O (flip-windows) on console emacs - -;; 20170309.01: -;; - added C-c s,u,e and M-a s,u,e - -;; 20170309.02: -;; - re-enabled paredit, its better in ielm and slime -;; - added alias 'pe to quickly enable/disable par-edit -;; - added virtual eShell dev /dev/log which stores stuff in *LOG* - -;; 20170313.01: -;; - iedit to C-c C-e, so C-c e works again (copy email) -;; - put eshell aliases into .emacs(here) no need for aliases file anymore -;; - added copy-comment (C-c c), copy-and-yank-comment (C-c y c) and -;; m-mark-comment (M-a c) - -;; 20170314.01: -;; - enhanced copy-comment (that is, rewrote it), it now supports -;; indented multiline comments - -;; 20170315.01: -;; - fixed C-c y [cpwf] -;; - fixed copy[+yank+mark] word, it now includes - _ . -;; - added copy-ip (C-c i), yank-ip (C-c y i) and mark-ip (M-a i) -;; - copy-url alternatively copies file-path if it's no url at point -;; - added numerical arg support to yy - -;; 20170321.01: -;; - rewrote copy-comment stuff, now supports blocks of comment -;; after code etc. - -;; 20170323.01: -;; - moved the mark,copy,yank stuff into its own mode - -;; 20170327.01: -;; - added defadvice for mcyt mode, so that I can use C-v to -;; always yank the last thing copied. - -;; 20170502.01: -;; - added config for ibuffer - -;; 20170503.01: -;; - added ibuffer-vc support - -;; 20170503.02: -;; - added ibuffer-tramp support -;; - disabled ibuffer tab-collaps stuff - -;; 20170505.01: -;; - generalized init-dir+file variables, now more portable, i hope - -;; 20170508.01: -;; - backup tramp files remote -;; - do not backup emacs state files - -;; 20170509.01: -;; - version fix - -;; 20170523.01: -;; - commented ssh backup stuff, not working yet, destroys tramp -;; - added inferior shells for perl, ruby and python (iperl, iruby, ipython) -;; with ansi-term - -;; 20170610.01: -;; - org mode: added C-c C-# to edit src blocks in an extra window -;; - org mode: opens link in eww -;; - ido-find-file advice: if not writable, try sudo/tramp -;; - +eshell-there remote eshell (Alias: et) -;; - disabled pager in eshell -;; - fixed eshell/x, now uses C-d -;; - org mode: DONE makes heading greyish -;; - re-organized emacs config, now with subsections -;; - removed lisp electric return, destroyed almost all modes -;; - added POD mode with specific abbrevs and including specific outlining -;; - added heading cycle code for outline mode as well -;; - added outline 'n (narrow) + 'w (widen) -;; - added orange fringe for narrowing (org, outline and everywhere else -;; - added alias 'colors -;; - added 'dl (aka describe-library to display the doc string in -; COMMENTARY section of .el files -;; - added "C-c t" to copy an org mode cell -;; - ena org pretty entities, list: org-entities-help -;; - 2table => tablify, which is now a function and uses region or whole buffer -;; - added indirect narrowing buffers -;; - renamed all occurences of my- to tvd- so I better know which stuff is mine -;; - added table-to-* org table exporters with aliases -;; - inside org mode: C-c o copy table c[o]lumn, C-c t copy [t]able cell -;; - experimental: added beacon mode (blinking pointer) -;; (moved 'seq from exp. elpa to lisp/) -;; - added render-html to render current html buffer with eww -;; - added align-regexp-repeat[-left|right] wrappers -;; - fixed org mode C- jump paragraphs if not on heading -;; - added 'tvd-outshine-jump (alias 'j) to directly jump to headers -;; with IDO completion and as sparse-tree, very cool! -;; mapped to C-c C-j -;; - added *text* scratch buffer with text mode -;; - added jump-paren-match-or-insert-percent, bound to %, which jumps parens -;; or inserts a % if not on a paren. Better than C-5, haha. -;; - added 'ffxs -;; - added emacs-change-log -;; - removed GNUS config, not used anymore -;; - restored C-d binding to viking in paredit -;; - added outshine HTML exporter via org: outshine-to-html -;; - fixed outshine config -;; - added (my) config-general-mode -;; - fixed pod format inserters - -;; 20170629.01: -;; - added tablist-minor-mode (+config) -;; - added config for tabulated-list-mode -;; - added config for help-mode -;; - added default filename for outshine-to-html -;; - Info mode: C-left+C-right history keys -;; - added loader for el2markdown -;; - removed smart-forward, it annoys me -;; - made tvd-outshine-jump more portable, do not use hardcoded -;; regexps anymore, use outshine functions -;; - added 'change-inner and ci simulators' -;; - added suggest.el with my own reload function -;; - modified recentf: do not provide files already visited - -;; 20170703.01: -;; - fixed recentf-exclude list, now REALLY ignores unreadables -;; - added export for easier export and commit of dot-emacs -;; - added tvd-suggest-jump to jump between input and output - -;; 20170707.01: -;; - added C-x 4 to split fram into 4 windows -;; - fixed config-general-mode config -;; - fixed 'emacs-change-log (didn't expand trees before work) -;; - fix python loading - -;; 20170711.01: -;; - fixed outshine: only loaded with elisp -;; - fixed tvd-outshine-jump: use imenu if outside outshine -;; - fixed kill-all-buffers: restore scratch after killing all buffers -;; - do not ask to save abbrevs on exit anymore -;; - reformat changelog -;; - rm open-line-below - -;; 20170711.02: -;; - fixed POD abbrevs, added way to move point after expansion - -;; 20170712.01: -;; - disabled org mode superscripts -;; - + winner mode -;; - org mode 'code new binding: C-c 0 -;; - fixed emacs-change-log -;; - added tvd-outshine-end-of-section incl speed command - -;; 20170712.02: -;; - fixed tvd-outshine-end-of-section, it's way faster now and -;; works without narrowing. - -;; 20170714.01: -;; - fixed pod-mode abbrev cursor jumping if no jump pos exists -;; - fix initial-buffer-choice -;; - added mmm-mode -;; - added here-doc support to config-general using mmm-mode -;; - made outline faces a little bigger, added face for level 4 -;; - rm initial buffer, doesnt open commandline files anymore with this -;; - finally initial buffer works, opens command line file or text scratch - -;; 20170715.01: -;; - no more MMM for C::G, destroys indent -;; - incorporated my C::G customizations, Steve Purcell removed from -;; it because inappropriate, -;; [[https://github.com/TLINDEN/config-general-mode/commit/d7e8323][see d7e8323]] -;; - fixed autoscratch hook -;; - add scratch alias - -;; 20170718.01: -;; - better autoscratch config -;; - added persistent-scratch mode - -;; 20170719.01: -;; - fixed electric-indent in autoscratch config -;; - use my own autoscratch triggers -;; - kill-all-buffers now uses 'autoscratch-buffer -;; - renamce autoscratch -;; - tuned recenter-positions - -;; 20170722.01: -;; - added followcursor-mode - -;; 20170724.01: -;; - added ido completion for tramp hostnames - -;; 20170725.01: -;; - autoscratch lambda=>progn -;; - added sort-table-ip[desc] and fixed auto-alignment so -;; that ip's are left aligned -;; - +req org-table - -;; 20170727.01: -;; - +magit -;; - configured magit dirs -;; - +magit ido -;; - fix magit info dir - -;; 20170730.01 -;; - +some magit navigation keys - -;; 20170731.01 -;; - do not load magit on w32 -;; - Always call `magit-status' with prefix arg -;; - do bigger jumps in magit with just C- -;; - add "ls" to magit-status leading to dired - -;; 20170801.01 -;; - added C command to magit to switch repo -;; - add : trigger for ido-find-file to begin with tramp - -;; 20170802.01 -;; - +table-to-excel -;; - added some git wrappers to dired to add or rm files - -;; 20170805.01 -;; - +C-c C-c for rename files in dired - -;; 20170807.01 -;; - added dired config and functions -;; - added dired-hacks: ranger and filters, enhanced navigation commands - -;; 20170808.01 -;; - (i) is now a function, not an alias anymore and more comfortable -;; - added org info path -;; - added info+ - -;; 20170821.01 -;; - highlight line color light green with default bg - -;; 20170901.01 -;; - added :jump-to-captured to org capture templates, -;; didn't know about it before - -;; 20170913.01 -;; - disabled outline in config-general-mode - -;; 20170924.01 -;; - experimenting swiper - -;; 20171201.01 -;; - highlight TABs with ruby as well - -;; 20171205.01 -;; - fixed ORG template headings - -;; 20180210.01 -;; - added ediff config -;; - fixed ob-sh to ob-shell - -;; 20180730.01 -;; - added autoscratch-reset-default-directory t - -;; 20181004.01 -;; - added projectile and config -;; - added hydra and config (for org tables and projectile) -;; - finished org table hydra -;; - added info hydra, fixed 't bug - -;; 20181016.01 -;; - fixed dired under cygwin w/o git - -;; 20181019.01 -;; - using C-x for all hydras now: -;; C-x w: windows -;; C-x t: org table -;; C-y p: projectile -;; - added copy org table row -;; - enhanced window hyrda by resizing chords -;; - changed table copy key chords (C-c t [ctr] - - -;; - better windows hydra -;; - on help close restore windows setup -;; - fixed hydra hints - -;; 20181021.01 -;; - fixed window resizing - -;; 20181022.01 -;; - enhanced M-o for window switching a lot, using a hydra and the arrow keys - -;; 20181029.01 -;; - fixed recentf max files - -;; 20181030.01 -;; - fixed windows hydra flip window call - -;; 20181105.01 -;; - added eyebrowse with config and hydra, prefix: C-x C-x - -;; 20181106.01 -;; - close help windows regularly again - -;; 20181107.01 -;; - removed debug toggle -;; - added magit status window new "q" feature which kills -;; all magit buffers and restores window setup -;; - added magit status margin timestamps - -;; 20181107.01 -;; - fixed function, inserts at () -;; - added / to dired hydra - -;; 20181110.01 -;; - fixed % function, really -;; - fixed elisp autoscratch config - -;; 20181111.01 -;; - fixed autoscratch elisp trigger -;; - started with smartparens, first config just replaces paredit - -;; 20181113.01 -;; - disabled paredit, enabled smartparens - -;; 20181115.01 -;; - disabled smartparens strict mode, much annoying -;; - map C-k to 'sp-kill-hybrid-sexp - -;; 20181117.01 -;; - disabled outline C- it overwrote sp slurp left -;; - enhanced emacs-changelog -;; - fixed parens bug, added sp ti monibuffer -;; - added tvd-lisp-comment -;; - (re-)added electric pair mode to eval-expression -;; - diret -lt - -;; 20181121.01 -;; - added org agenda - -;; 20181122.01 -;; - + new agenda o function - -;; 20181126.01 -;; - unlimited recentf - -;; 20181127.01 -;; - fixed tvd-replace-all -;; - fixed agenda capture template - -;; 20181127.02 -;; - fixed C-up|down in agenda - -;; 20181206.01 -;; - added support for scheduled agenda entries and fixed tvd-replace-all -;; (I already had this in 20181123 but overwrote it somehow!) - -;; 20181210.01 -;; - fixed agenda g command - -;; 20181212.01 -;; - configured agenda sorting - -;; 20181212.02 -;; - fixed agenda sorting, must be global - -;; 20181220.01 -;; - added org table move cells functions - -;; 20181222.01 -;; - removed duplicate key bindings, added via comment - -;; 20181227.01 -;; - ena variable pitch w/ org, turned face config into theme - -;; 20190108.01 -;; - added server - -;; 20190112.01 -;; - added wdired cleanup function - -;; 20190112.02 -;; - enhanced cleaner - -;; 20190114.01 -;; - disabled variable pitch, annoys me - -;; 20190214.01 -;; - fixed C-c C-c in shell-script-mode - -;; 20190226.01 -;; - unbound F6 and F5 from cperl mode - -;; 20190412.01 -;; - added yaml mode and highlight indent mode - -;; 20190513.01 -;; - added scheduled task org capture template along with wrappers etc - -;; 20190520.01 -;; - fixed 'n' in agenda, added 'k', fixed scheduled task template - -;; 20190521.01 -;; - split agenda window left - -;; 20190705.01 -;; - added smerge hydra plus alias 'merge -;; - fixed window resize hydra help - -;; 20200902.01 -;; - added rust mode - -;; 20200904.01 -;; - rust+smartparens - -;; 20190923.01 -;; - added RCS - -;; 20201126.01 -;; - -gh - -;; 20210501.01 -;; - added golang support - -;; ** TODO - -;; - check helpful https://github.com/wilfred/helpful -;; - check no-littering https://github.com/tarsius/no-littering -;; - put tvd-ci-* stuff into mcyt -;; - check https://github.com/Wilfred/refine -;; https://github.com/Wilfred/emacs-refactor -;; - check https://github.com/Malabarba/speed-of-thought-lisp -;; - https://github.com/tkf/emacs-jedi - -;; ** Parking Lot / Snippets - -;; Snippets which maybe of use in the future - -;; *** buffer-local hook - -;; (with-current-buffer (get-buffer "*scratch*") -;; (add-hook 'kill-buffer-hook -;; (lambda () (error "DENIED! don't kill my precious *scratch*!!")) -;; nil t)) - -;; -------------------------------------------------------------------------------- -;; ** .emacs config version - -;; My emacs config has a version (consisting of a timestamp with a -;; serial), which I display in the mode line. So I can clearly see, if -;; I'm using an outdated config somewhere. -(defvar tvd-emacs-version "20210501.01") - -;; -------------------------------------------------------------------------------- - -;; * System Specifics -;; ** Global init file+dir vars, portable -;; - added dev function which opens a new development frame - -;; since I always use ~/.emacs as my init file, this results in the -;; correct emacs dir: -(setq user-init-dir (expand-file-name (concat user-init-file ".d"))) - -;; FIXME: use (pwd) to determine .emacs.d, make it more portable -;; use different init dir on cygwin systems -(setq tvd-win-home "C:/Cygwin/home/iz00468") -(if (file-exists-p tvd-win-home) - (setq user-init-dir (expand-file-name ".emacs.d" tvd-win-home)) - (setq tvd-win-home nil)) - -;; all modes and extensions are located here -(setq tvd-lisp-dir (expand-file-name "lisp" user-init-dir)) - -;; -------------------------------------------------------------------------------- -;; ** Shortcut Mode - mode specific help about my own customizations - -;; FIXME: complete - -(defun add-shortcut (mode help) - (add-to-list 'shortcut-alist '(mode . help))) - -(defun shortcut () - (interactive) - (message (cdr (assoc major-mode 'shortcut-alist)))) - -;; -------------------------------------------------------------------------------- -;; ** Fontlock-mode - use syntax highlighting on graphical displays - -;; look: [[https://www.emacswiki.org/emacs/CustomizingBoth][emacswiki]] -(if window-system - (progn - (global-font-lock-mode 1) - (set-background-color "white") - (set-foreground-color "DarkBlue"))) - -;; -------------------------------------------------------------------------------- -;; ** line-cursor in console - -;; better visibility of cursor in console sessions -(unless (display-graphic-p) - (global-hl-line-mode) - (set-face-background hl-line-face "DarkGray") - (set-face-foreground hl-line-face "Black")) - -;; -------------------------------------------------------------------------------- -;; ** Backup Config - -;; I save backup files in a central location below the init dir, that -;; way they don't clutter productive file systems or repos. - -(setq tvd-backup-directory (expand-file-name "backups" user-init-dir)) -(if (not (file-exists-p tvd-backup-directory)) - (make-directory tvd-backup-directory t)) - -;; there's even a trash -(setq tvd-trash-directory (expand-file-name "trash" tvd-backup-directory)) - - -;; actual configuration of all things backup related: -(setq make-backup-files t ; backup of a file the first time it is saved. - backup-by-copying t ; don't clobber symlinks - version-control t ; version numbers for backup files - delete-old-versions t ; delete excess backup files silently - delete-by-moving-to-trash t - kept-old-versions 6 ; oldest versions to keep when a new numbered backup is made (default: 2) - kept-new-versions 9 ; newest versions to keep when a new numbered backup is made (default: 2) - auto-save-default t ; auto-save every buffer that visits a file - auto-save-timeout 20 ; number of seconds idle time before auto-save (default: 30) - auto-save-interval 200 ; number of keystrokes between auto-saves (default: 300) - delete-by-moving-to-trash t - trash-directory tvd-trash-directory - backup-directory-alist `(("emacs.d/\\(recentf\\|ido.last\\|places\\)" . nil) ; do not backup state files - ("." . ,tvd-backup-directory))) ; backup everything else - -;; However, if the file to be backed up is remote, backup -;; per remote directory. that way, no root owned files end -;; up in my home directory, ready to be read by everyone. -;; This is system specific and only matches special host names. -;; FIXME: find out programatically hostname und remote user to make this generic -(advice-add 'make-backup-file-name-1 :before - '(lambda (&rest file) - (let ((filename (car file))) - (if (string-match "\\(/ssh:.devel[0-9]+\\):/" filename) - (setq backup-directory-alist `(("." . ,(concat (match-string 1 filename) ":/root/.emacs.d/backups")))) - (setq backup-directory-alist `(("." . ,tvd-backup-directory))))))) - -;; FIXME: and/or check [[https://www.gnu.org/software/tramp/#Auto_002dsave-and-Backup][gnu.org]] -;; + tramp-default-proxies-alist - -;; -------------------------------------------------------------------------------- -;; ** console backspace fix - -;; make backspace work in console sessions -(define-key key-translation-map [?\C-h] [?\C-?]) - -;; -------------------------------------------------------------------------------- -;; ** hide menu- and tool-bar - -;; I prefer a bare bones emacs window without any distractions, so turn them off. -(menu-bar-mode -1) -(tool-bar-mode -1) -(setq use-dialog-box nil) -(scroll-bar-mode 0) - -;; -------------------------------------------------------------------------------- -;; ** stay silent on startup - -(setq initial-scratch-message "") -(setq inhibit-startup-message t) -(setq inhibit-startup-screen t) -(setq inhibit-startup-echo-area-message "scip") - -;; -------------------------------------------------------------------------------- -;; ** y means yes - -;; y is shorter than yes and less error prone. -(defalias 'yes-or-no-p 'y-or-n-p) - -;; -------------------------------------------------------------------------------- -;; ** show col in modeline - -;; very useful to know current column -(column-number-mode t) - -;; -------------------------------------------------------------------------------- -;; ** file or buffer in title - -;; this can be seen in xmobar -(setq frame-title-format '(buffer-file-name "emacs %f" ("emacs %b"))) - - -;; -------------------------------------------------------------------------------- -;; ** avoid invalid files -(setq require-final-newline t) - -;; -------------------------------------------------------------------------------- -;; ** prepare load-path - -;; where to look for extensions: -(add-to-list 'load-path tvd-lisp-dir) - -(if (null tvd-win-home) - (add-to-list 'load-path (expand-file-name "compat" tvd-lisp-dir))) - -;; modules -(add-to-list 'load-path (concat tvd-lisp-dir "/er")) -(add-to-list 'load-path (concat tvd-lisp-dir "/org/lisp")) -(add-to-list 'load-path (concat tvd-lisp-dir "/ivy")) -(add-to-list 'load-path (concat tvd-lisp-dir "/doremi")) -(add-to-list 'load-path (concat tvd-lisp-dir "/org/contrib/lisp")) - -;; -------------------------------------------------------------------------------- -;; ** Hydra -;; Used here and there below, loaded as early as possible -(require 'hydra) - -;; ** byte-compile all of them, if needed - -;; handy function to recompile all lisp files -(defun recompile-el() - (interactive) - (byte-recompile-directory tvd-lisp-dir 0)) - -;; -------------------------------------------------------------------------------- -;; ** increase fontsize with ctrl-+ and ctrl-- - -;; I use those bindings everywhere (firefox, terminal, etc), and in -;; emacs as well. - -(defun tvd-global-font-size-bigger () - "Make font size larger." - (interactive) - (text-scale-increase 0.5)) - -(defun tvd-global-font-size-smaller () - "Change font size back to original." - (interactive) - (text-scale-increase -0.5)) - -(global-set-key (kbd "C-+") 'tvd-global-font-size-bigger) ; Schrift groesser -(global-set-key (kbd "C--") 'tvd-global-font-size-smaller) ; kleiner - -;; -------------------------------------------------------------------------------- -;; ** WINDOW management stuff -;; *** resize windows by keyboard - -;; Very practical: resize windows easily. - -;; hit C-c C-r then use cursor keys to resize, to finish -(require 'windresize) -(global-set-key (kbd "C-c C-r") 'windresize) ; Split Buffer Groesse Aendern - -;; *** switch windows with MS-WINDOWS key -(require 'windmove) -(windmove-default-keybindings 'super) -(setq windmove-wrap-around t) - -;; *** M-o switch window or buffer - -;; The key M-o has different functions depending on context: -;; -;; If there's only 1 window open, switch to the last active. -;; -;; If there are 2 windows open, switch back and forth between the -;; two. In order to flip them, Use M-O (that is: ALT+shift+o). -;; -;; And if there are more than 2 windows open, call the hydra, which -;; allows to switch to another window using the arrow keys. The hydra -;; stays for 1 second unles an arrow key has been pressed. So, I can -;; press multiple arrow keys in a row as long as I'm fast enough -;; between key presses. If I stop,the hydra disappears and I end up -;; whereever I was last. -;; -;; Also, within the hydra 'o' jumps to the last active window and -;; 'f' flips all windows. - -;; from https://github.com/lukhas/buffer-move -(require 'buffer-move) - -(defun tvd-previous-window (&optional ignore) - "Toggle between the last two selected windows." - (interactive) - (let ((win (get-mru-window t t t))) - (unless win (error "Last window not found.")) - (select-window win))) - -;; via -;; [[http://whattheemacsd.com/buffer-defuns.el-02.html][whattheemacs.d]]: -;; exchange left with right buffer (or up and down), love it. -(defun tvd-flip-windows () - "Rotate your windows" - (interactive) - (cond ((not (> (count-windows)1)) - (message "You can't rotate a single window!")) - (t - (setq i 1) - (setq numWindows (count-windows)) - (while (< i numWindows) - (let* ( - (w1 (elt (window-list) i)) - (w2 (elt (window-list) (+ (% i numWindows) 1))) - (b1 (window-buffer w1)) - (b2 (window-buffer w2)) - (s1 (window-start w1)) - (s2 (window-start w2)) - ) - (set-window-buffer w1 b2) - (set-window-buffer w2 b1) - (set-window-start w1 s2) - (set-window-start w2 s1) - (setq i (1+ i))))))) - -(defhydra hydra-switch-windows (:color pink: :timeout 2.5) - " -Switch to buffer: ← ↑ → ↓ | _o_: previous | _f_: flip | MOVE: _u_: up _d_: down _l_: left _r_: right" - ("" windmove-up nil) - ("" windmove-down nil) - ("" windmove-left nil) - ("" windmove-right nil) - ("o" tvd-previous-window nil :color blue) - ("f" tvd-flip-windows nil :color blue) - ("u" buf-move-up nil :color blue) - ("d" buf-move-down nil :color blue) - ("l" buf-move-left nil :color blue) - ("r" buf-move-right nil :color blue) - ("q" nil nil :color red)) - -;; via [[http://mbork.pl/2017-02-26_other-window-or-switch-buffer][mbork]] -;; modified to call the above hydra if there are more than 2 windows -(defun other-window-or-switch-buffer () - "Call `other-window' if more than one window is visible, switch -to next buffer otherwise." - (interactive) - (if (one-window-p) - (switch-to-buffer nil) - (progn - (if (= (length (window-list)) 2) - (other-window 1) - (hydra-switch-windows/body))))) - -(global-set-key (kbd "M-o") 'other-window-or-switch-buffer) - -;; M-o doesn't work when using emacs via Win->RDP->VNC->X11->Xmonad, -;; so fall back to C-o. -(global-set-key (kbd "C-o") 'other-window-or-switch-buffer) - -;; Use only in X11 emacs - setting M-O inside console causes and -;; to stop working properly, for whatever reasons. -(if (display-graphic-p) - (global-set-key (kbd "M-O") 'tvd-flip-windows)) - -;; -------------------------------------------------------------------------------- -;; *** Split window to 4 parts - -(defun tvd-quarter-windows () - (interactive) - (split-window-vertically) - (split-window-horizontally) - (windmove-down) - (split-window-horizontally)) - -(global-set-key (kbd "C-x 4") 'tvd-quarter-windows) - -;; -------------------------------------------------------------------------------- - -;; *** Remember and Restore Window Configurations - winner mode - -(winner-mode 1) - -;; keybindings: C-c left - winner-undo -;; keybindings: C-c right - winner-redo - -;; ** re-read a modified buffer - -;; F5 == reload file if it has been modified by another process, shift -;; because Xmonad -(global-set-key (kbd "S-") ; re-read a buffer from disk (revert) - (lambda (&optional force-reverting) - "Interactive call to revert-buffer. Ignoring the auto-save - file and not requesting for confirmation. When the current buffer - is modified, the command refuses to revert it, unless you specify - the optional argument: force-reverting to true." - (interactive "P") - ;;(message "force-reverting value is %s" force-reverting) - (if (or force-reverting (not (buffer-modified-p))) - (revert-buffer :ignore-auto :noconfirm) - (error "The buffer has been modified")))) - - -;; -------------------------------------------------------------------------------- -;; ** global TAB/Indent config - -;; I use spaces everywhere but Makefiles. If I encounter TABs I -;; replace them with spaces, if I encounter users entering TABs into -;; files, I block them. - -;; FIXME: also check [[https://github.com/glasserc/ethan-wspace][ethan-wspace]] ! - -(setq-default indent-tabs-mode nil) -(setq-default tab-width 4) -(setq indent-line-function 'insert-tab) -(setq tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120))) -(setq tab-always-indent 'complete) ; FIXME: doesnt work in cperl-mode -(setq show-trailing-whitespace t) - -(defun indent-buffer () - ;; Author: Mathias Creutz - "Re-Indent every line in the current buffer." - (interactive) - (indent-region (point-min) (point-max) nil)) - -;; Use normal tabs in makefiles -(add-hook 'makefile-mode-hook '(lambda() (setq indent-tabs-mode t))) - - -;; -------------------------------------------------------------------------------- -;; ** handy aliases - -;; M-x q r is short enough for me, no need for key bindings for -;; those - -(defalias 'qrr 'query-replace-regexp) -(defalias 'qr 'query-replace) -(defalias 'cr 'comment-region) -(defalias 'ur 'uncomment-region) -(defalias 'ir 'indent-region) -(defalias 'dv 'describe-variable) -(defalias 'dk 'describe-key) -(defalias 'df 'describe-function) -(defalias 'dp 'describe-char) -(defalias 'dm 'describe-mode) -(defalias 'db 'describe-bindings) -(defalias 'dl 'finder-commentary) ; aka "describe library" -(defalias 'repl 'ielm) -(defalias 'ws 'window-configuration-to-register) ; save window config -(defalias 'wr 'jump-to-register) ; restore window config -(defalias 'rec 'rectangle-mark-mode) -(defalias '| 'shell-command-on-region) ; apply shell command on region - -;; -------------------------------------------------------------------------------- -;; ** various settings - -;; point stays while scrolling -(setq scroll-preserve-screen-position t) - -;; no comment margins -(setq-default comment-column 0) - -;; do not save until I hit C-x-s -(setq auto-save-default nil) - -;; show all buffers in buffer menu -(setq buffers-menu-max-size nil) - -;; start to wrap at 30 entries -(setq mouse-buffer-menu-mode-mult 30) - -;; I'm grown up! -(setq disabled-command-function nil) - -;; -------------------------------------------------------------------------------- -;; ** load imenu -(define-key global-map [C-down-mouse-2] 'imenu) - -;; -------------------------------------------------------------------------------- -;; ** copy/paste Config - -;; Related: -;; - see also mark-copy-yank-things-mode below! -;; - see also: move-region below (for M-) -;; - see also: expand-region below (for C-0) - -;; middle mouse button paste at click not where cursor is -(setq mouse-yank-at-point t) - -;; highlight selected stuff (also allows DEL of active region) -(setq transient-mark-mode t) - -;; pasting onto selection deletes it -(delete-selection-mode t) - -;; delete whole lines -(setq kill-whole-line t) - -;; middle-mouse and C-y use both X-selection and Emacs-clipboard -(if (null tvd-win-home) - (progn ; unix - (setq x-select-enable-primary t) - (setq x-select-enable-clipboard nil)) - (progn ; win - (global-set-key (kbd "") 'yank))) - -;; marked region automatically copied, also on win -(setq mouse-drag-copy-region t) - -;; -------------------------------------------------------------------------------- -;; ** use more mem -;; are you from the past? -(setq gc-cons-threshold 20000000) - -;; -------------------------------------------------------------------------------- -;; ** better file name completion - -;; Complete filenames case insensitive and ignore certain files during completion. -(setq read-file-name-completion-ignore-case t) -(setq read-buffer-completion-ignore-case t) - -;; via [[http://endlessparentheses.com/improving-emacs-file-name-completion.html][endlessparantheses]] -(mapc (lambda (x) - (add-to-list 'completion-ignored-extensions x)) - '(".aux" ".bbl" ".blg" ".exe" - ".log" ".meta" ".out" ".pdf" - ".synctex.gz" ".tdo" ".toc" - "-pkg.el" "-autoloads.el" ".elc" - ".dump" ".ps" ".png" ".jpg" - ".gz" ".tgz" ".zip" - "Notes.bib" "auto/")) - -;; -------------------------------------------------------------------------------- -;; ** abbreviations - -;; Do I really need those anymore? Added ca 1999... - -(define-abbrev-table 'global-abbrev-table '( - ("oe" "ö" nil 0) - ("ue" "ü" nil 0) - ("ae" "ä" nil 0) - ("Oe" "Ö" nil 0) - ("Ue" "Ü" nil 0) - ("Ae" "Ä" nil 0) - ("
  • " "
  • " nil 0) - ("
      " "
      " nil 0) - )) - -;; do NOT ask to save abbrevs on exit -(setq save-abbrevs nil) - -;; ** meaningful names for buffers with the same name - -;; from ([[https://github.com/bbatsov/prelude][prelude]]) - -(require 'uniquify) -(setq uniquify-buffer-name-style 'forward) -(setq uniquify-separator "/") -(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified -(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers - -;; -------------------------------------------------------------------------------- -;; ** packages - -;; I dont need it all the time and only for experimentation, so lets -;; only use melpa on demand -(defun toggle-melpa() - (interactive) - (require 'package) - (add-to-list 'package-archives - '("melpa" . "http://melpa.org/packages/")) - (when (< emacs-major-version 24) - ;; For important compatibility libraries like cl-lib - (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))) - (package-initialize) - (list-packages)) - -;; -------------------------------------------------------------------------------- -;; ** My own global variables - -;; narrowed fringe background -(defvar tvd-fringe-narrow-bg "OrangeRed") - -;; -------------------------------------------------------------------------------- -;; ** More scratch space -;; *** Text scratch -;; Sometimes I need a text mode scratch buffer while scratch is -;; already in use. So let's prepare one. I also add a buffer hook so that -;; this never gets deleted, but cleaned instead. - -(with-current-buffer (get-buffer-create "*text*") - (text-mode)) - -;; *** Autoscratch -;; use autoscratch otherwise -;; [[https://github.com/TLINDEN/autoscratch][autoscratch github]] -(require 'autoscratch-mode) -(setq initial-major-mode 'autoscratch-mode) -(add-hook 'autoscratch-mode-hook '(lambda () - (setq autoscratch-triggers-alist - '(("[(;]" . (progn - (call-interactively 'emacs-lisp-mode) - (call-interactively 'enable-paredit-mode) - (call-interactively 'electric-pair-mode))) - ("#" . (progn - (call-interactively 'config-general-mode) - (electric-indent-local-mode t))) - ("[-a-zA-Z0-9]" . (text-mode)) - ("/" . (c-mode)) - ("*" . (progn (insert " ") (org-mode))) - ("." . (fundamental-mode))) - autoscratch-trigger-on-first-char t - autoscratch-reset-default-directory t) - (electric-indent-local-mode nil) - )) -(defalias 'scratch 'autoscratch-buffer) - -;; *** Persistent Scratch -;; I also like to be scratch buffers persistent with -;; [[https://github.com/Fanael/persistent-scratch][persistent-scratch]] -(require 'persistent-scratch) -(setq persistent-scratch-save-file (expand-file-name "scratches.el" user-init-dir)) -(persistent-scratch-setup-default) - -(defun tvd-autoscratch-p () - "Return non-nil if the current buffer is a scratch buffer" - (string-match "scratch*" (buffer-name))) - -(setq persistent-scratch-scratch-buffer-p-function 'tvd-autoscratch-p) - -;; ** Recenter config - -;; [[http://oremacs.com/2015/03/28/recenter/][via abo abo]] - -;; However, I set the first position to 1, which causes the window to -;; be recentered on the second line, that is, I can see one line above -;; the current one. It works the same with bottom, which I intend, but -;; I think this is a recenter calculation bug. - -(setq recenter-positions '(1 middle bottom)) - -;; * Global Key Bindings -;; -------------------------------------------------------------------------------- -;; ** c-h != delete -(keyboard-translate ?\C-h ?\C-?) -(keyboard-translate ?\C-? ?\C-h) - -;; -------------------------------------------------------------------------------- -;; ** general keys (re-)mappings -;(global-set-key (kbd "C-s") 'isearch-forward-regexp) -;(global-set-key (kbd "C-r") 'isearch-backward-regexp) -(global-set-key (kbd "M-C-s") 'isearch-forward) -(global-set-key (kbd "M-C-r") 'isearch-backward) -(global-set-key (kbd "M-%") 'query-replace-regexp) -(global-set-key (kbd "") 'dabbrev-completion) ; shift-tab, inline completion - -(global-set-key (kbd "") 'html-mode) -(global-set-key (kbd "") 'delete-char) ; Entf Char loeschen -(global-set-key (kbd "") 'backward-delete-char) ; Shift+Backspace dito -(global-set-key (kbd "S-") 'kill-word) ; Shift+Entf Wort loeschen -(global-set-key (kbd "S-") 'backward-kill-word) ; Shift+Backspace dito -(global-set-key (kbd "C-") 'kill-word) ; Shift+Entf dito -(global-set-key (kbd "C-") 'backward-kill-word) ; Shift+Backspace dito -(global-unset-key (kbd "C-z")) -(global-set-key (kbd "C-x k") 'kill-this-buffer) ; C-x k really kill current buffer w/o asking -(global-set-key (kbd "C-x C-b") 'buffer-menu) - - - -;; -------------------------------------------------------------------------------- -;; ** display a list of my own global key bindings and aliases -;; via [[https://www.emacswiki.org/emacs/OccurMode#toc9][emacswiki]] - -;; Inside *Occur*: q - quit, e - edit, g - reload -;; more help with: describe-function occur-mode - -(defun occur-mode-clean-buffer () - "Removes all commentary from the *Occur* buffer, leaving the - unadorned lines." - (interactive) - (if (get-buffer "*Occur*") - (save-excursion - (set-buffer (get-buffer "*Occur*")) - (goto-char (point-min)) - (toggle-read-only 0) - (if (looking-at "^[0-9]+ lines matching \"") - (kill-line 1)) - (while (re-search-forward "^[ \t]*[0-9]+:" - (point-max) - t) - (replace-match "") - (forward-line 1))) - (message "There is no buffer named \"*Occur*\"."))) - -(defun show-definition(REGEX) - (interactive) - (let ((dotemacs-loaded nil) - (occur-b "*Occur*") - (occur-c "")) - (if (get-buffer ".emacs") - (progn - (switch-to-buffer ".emacs") - (setq dotemacs-loaded t)) - (find-file "~/.emacs")) - (occur REGEX) - (with-current-buffer occur-b - (occur-mode-clean-buffer) - (setq occur-c (current-buffer)) - (let ((inhibit-read-only t)) (set-text-properties (point-min) (point-max) ())) - (while (re-search-forward "[0-9]*:" nil t) - (replace-match "")) - (beginning-of-buffer) - (kill-line) - (sort-lines nil (point-min) (point-max)) - (emacs-lisp-mode) - (beginning-of-buffer) - (insert (format ";; *SHOW*: %s\n" REGEX)) - (highlight-regexp REGEX) - (beginning-of-buffer)) - (switch-to-buffer occur-b) - (delete-other-windows) - (if (eq dotemacs-loaded nil) - (kill-buffer ".emacs")))) - -(defun show-keys() - (interactive) - (show-definition "^(global-set-key")) - -(defun show-aliases() - (interactive) - (show-definition "^(defalias")) - -(defalias 'sk 'show-keys) -(defalias 'sa 'show-aliases) - -;; -------------------------------------------------------------------------------- -;; * Productivity Functions -;; -------------------------------------------------------------------------------- -;; ** goto line with tmp line numbers - -;; I stole this somewhere, as far as I remember, emacswiki, however, I -;; always had F7 for goto-line - -(defun goto-line-with-feedback () - "Show line numbers temporarily, while prompting for the line number input" - (interactive) - (unwind-protect - (progn - (linum-mode 1) - (call-interactively 'goto-line)) - (linum-mode -1))) - -(global-set-key (kbd "") 'goto-line-with-feedback) - -;; -------------------------------------------------------------------------------- -;; ** invert fore- and background - -;; Sometimes when sitting in a very dark enviroment, my usual light -;; emacs frame is a too stark contrast to the environment. With this -;; function I can just invert my current color settings to dark -;; background and light foreground. - -;; remember last inverse -(defvar tvd-invert-state t) - -;; invert everything, reverse it when called again -(defun tvd-invert() - "invert fg-bg" - (interactive) - (invert-face 'default) - (invert-face 'mode-line) - (set-face-attribute 'fringe nil :inverse-video tvd-invert-state) - (setq tvd-invert-state (not tvd-invert-state)) ;; cycle variable tvd-invert-state - ) - -;; fast -(global-set-key (kbd "C-c C-i") 'tvd-invert) - -;; -------------------------------------------------------------------------------- -;; ** Some useful bindings for Home and End keys Hit the key once to - -;; Go to the beginning/end of a line, hit it twice in a row to go to -;; the beginning/end of the window, three times in a row goes to the -;; beginning/end of the buffer. NB that there is no timeout involved. - -;; Uses a function of viking-mode to establish key repeats, see below. - -(defun pc-keys-home () - "Go to beginning of line/window/buffer. First hitting key goes -to beginning of line, second in a row goes to beginning of -window, third in a row goes to beginning of buffer." - (interactive) - (let* ((key-times (viking-last-key-repeats))) - (cond - ((eq key-times 3) - (if mark-active - (goto-char (point-min)) - (beginning-of-buffer))) - ((eq key-times 2) - (if mark-active () (push-mark)) - (move-to-window-line 0)) - ((eq key-times 1) - (beginning-of-line))))) - -(defun pc-keys-end () - "Go to end of line/window/buffer. First hitting key goes -to end of line, second in a row goes to end of -window, third in a row goes to end of buffer." - (interactive) - (let* ((key-times (viking-last-key-repeats))) - (cond - ((eq key-times 3) - (if mark-active - (goto-char (point-max)) - (end-of-buffer))) - ((eq key-times 2) - (if mark-active () (push-mark)) - (move-to-window-line -1) - (end-of-line)) - ((eq key-times 1) - (end-of-line))))) - -;; This is the most natural use for those keys -(global-set-key (kbd "") 'pc-keys-home) -(global-set-key (kbd "") 'pc-keys-end) - - - -;; -------------------------------------------------------------------------------- -;; ** percent function -;; by Jens Heunemann: jump to percent position into current buffer - -(defun goto-percent (p) ;goto Prozentwert (0-100): F8 - (interactive "nProzent: ") - (if (> (point-max) 80000) - (goto-char (* (/ (point-max) 100) p)) ;Ueberlauf vermeiden: (max/100)*p - (goto-char (/ (* p (point-max)) 100))) ;Rundungsfehler verm.: (max*p)/100 - (beginning-of-line)) - -(global-set-key (kbd "") 'goto-percent) ;F8 goto percent - -;; -------------------------------------------------------------------------------- -;; ** Simulate vi's % (percent) function - -;; There's not a lot about vi[m] I like, but jumping with % to a -;; matching paren is one of THOSE features, I also need in emacs. - -;; with ideas from [[https://www.emacswiki.org/emacs/NavigatingParentheses#toc2][emacswiki]] - -;; If (point) is on a paren, jump to the matching paren, otherwise, -;; just insert a literal ?%. Only make sense if bound to %. -;; Does not jump in inside () though -(defun jump-paren-match-or-insert-percent (arg) -"Go to the matching parenthesis if on parenthesis. Otherwise -insert %. Mimics vi stle of % jumping to matching brace." -(interactive "p") -(cond ((looking-at "\\s\(\\|\{\\|\\[") (forward-list 1) (backward-char 1)) - ((and (looking-at "\\s\)\\|\}\\|\\]") - (not (looking-back "\\s\(\\|\{\\|\\["))) - (forward-char 1) (backward-list 1)) - (t (insert "%")))) - -;; only useful in programming modes -(define-key prog-mode-map (kbd "%") 'jump-paren-match-or-insert-percent) - -;; -------------------------------------------------------------------------------- -;; ** Move region - -;; Mark a region, then use M-up|down to move it around -;; via [[https://www.emacswiki.org/emacs/MoveRegion][emacswiki]] -;; code from [[https://github.com/targzeta/move-lines/blob/master/move-lines.el][move-lines]] - -(defun move-lines--internal (n) - (let* ((start (point)) ;; The position of beginning of line of the first line - (end start) ;; The position of eol+\n of the end line - col-init ;; The current column for the first line - (col-end (current-column)) ;; The current column for the end line - exchange_pm ;; If I had exchanged point and mark - delete-latest-newline) ;; If I had inserted a newline at the end - - ;; STEP 1: Identifying the line(s) to cut. - ;; --- - ;; If region is actives, I ensure that point always is at the end of the - ;; region and mark at the beginning. - (when (region-active-p) - (when (< (point) (mark)) - (setq exchange_pm t) - (exchange-point-and-mark)) - (setq start (mark) - end (point) - col-end (current-column))) - - (goto-char start) (setq col-init (current-column)) - (beginning-of-line) (setq start (point)) - - (goto-char end) (end-of-line) - ;; If point == point-max, this buffers doesn't have the trailing newline. - ;; In this case I have to insert a newline otherwise the following - ;; `forward-char' (to keep the "\n") will fail. - (when (= (point) (point-max)) - (setq delete-latest-newline t) - (insert-char ?\n) (forward-char -1)) - (forward-char 1) (setq end (point)) - - ;; STEP 2: Moving the lines. - ;; --- - ;; The region I'm cutting span from the beginning of line of the current - ;; line (or current region) to the end of line + 1 (newline) of the current - ;; line (or current region). - (let ((line-text (delete-and-extract-region start end))) - (forward-line n) - ;; If the current-column != 0, I have moved the region at the bottom of a - ;; buffer doesn't have the trailing newline. - (when (not (= (current-column) 0)) - (insert-char ?\n) - (setq delete-latest-newline t)) - (setq start (+ (point) col-init)) ;; Now, start is the start of new region - (insert line-text)) - - ;; STEP 3: Restoring - ;; --- - ;; I'm at the end of new region (or line) and start has setted at the - ;; beginning of new region (if a region is active). - ;; Restoring the end column. - (forward-line -1) - (forward-char col-end) - - (when delete-latest-newline - (save-excursion - (goto-char (point-max)) - (delete-char -1))) - - (when (region-active-p) - (setq deactivate-mark nil) - (set-mark start) - (if exchange_pm - (exchange-point-and-mark))))) - -(defun move-lines-up (n) - "Moves the current line or, if region is actives, the lines surrounding -region, up by N lines, or 1 line if N is nil." - (interactive "p") - (if (eq n nil) - (setq n 1)) - (move-lines--internal (- n))) - -(defun move-lines-down (n) - "Moves the current line or, if region is actives, the lines surrounding -region, down by N lines, or 1 line if N is nil." - (interactive "p") - (if (eq n nil) - (setq n 1)) - (move-lines--internal n)) - -(global-set-key (kbd "M-") 'move-lines-up) -(global-set-key (kbd "M-") 'move-lines-down) - -;; -------------------------------------------------------------------------------- -;; ** comment-uncomment region with one key binding -;; via [[http://stackoverflow.com/a/9697222/3350881][stackoverflow]] -(defun comment-or-uncomment-region-or-line () - "Comments or uncomments the region or the current line if there's no active region." - (interactive) - (let (beg end) - (if (region-active-p) - (setq beg (region-beginning) end (region-end)) - (setq beg (line-beginning-position) end (line-end-position))) - (comment-or-uncomment-region beg end))) - -(global-set-key (kbd "C-c C-c") 'comment-or-uncomment-region-or-line) - -;; -------------------------------------------------------------------------------- -;; ** search for symbol at point - -;; Simulate the # function of vi, marks the symbol at point, C-s then -;; searches for it. I use this a lot. - -;; via [[http://ergoemacs.org/emacs/modernization_isearch.html][ergomacs]] - -(defun xah-search-current-word () - "Call `isearch' on current word or text selection. - 'word' here is A to Z, a to z, and hyphen and underline, independent of syntax table. -URL `[[http://ergoemacs.org/emacs/modernization_isearch.html'][ergomacs]] -Version 2015-04-09" - (interactive) - (let ( xahp1 xahp2 ) - (if (use-region-p) - (progn - (setq xahp1 (region-beginning)) - (setq xahp2 (region-end))) - (save-excursion - (skip-chars-backward "-_A-Za-z0-9") - (setq xahp1 (point)) - (right-char) - (skip-chars-forward "-_A-Za-z0-9") - (setq xahp2 (point)))) - (setq mark-active nil) - (when (< xahp1 (point)) - (goto-char xahp1)) - (isearch-mode t) - (isearch-yank-string (buffer-substring-no-properties xahp1 xahp2)) - (message "Now use C-s to search for it ...") - )) - -(global-set-key (kbd "C-#") 'xah-search-current-word) - -;; -------------------------------------------------------------------------------- -;; ** Window Margin - -;; Kinda screen reader for the poor. I use this sometimes with info -;; or woman mode. I also use a full featured screen reader: nove-mode, -;; see below. - -;; left+right margin on demand (but nothing else) -(defun margin(m) - "set left and right margins for better readability" - (interactive "nEnter Margin (0 to disable) [0-9]+: ") - (set-window-margins (car (get-buffer-window-list (current-buffer) nil t)) m m) ;; set immediately - (setq left-margin-width m) ;; persist until reset - (setq right-margin-width m) - (message "To reset, change Buffer or call again with arg 0.") - ) - -;; -------------------------------------------------------------------------------- -;; ** Fill and justify a paragraph - -;; this is just a shortcut for: -;; C-u 70 M-x fill-paragraph -;; but C-q is just easier to remember - -;; however, if pressed again it un-fills the paragraph, -;; idea via: [[http://endlessparentheses.com/fill-and-unfill-paragraphs-with-a-single-key.html][endlessparentheses]] -(defun tvd-fill-and-justify-or-unfill() - (interactive) - (let ((fill-column - (if (eq last-command 'tvd-fill-and-justify-or-unfill) - (progn (setq this-command nil) - (point-max)) - fill-column))) - (fill-paragraph 70))) - -(global-set-key (kbd "C-q") 'tvd-fill-and-justify-or-unfill) ; like M-q, which is bound to x-window-quit in xmonad: fill+justify - -;; -------------------------------------------------------------------------------- -;; ** Make a read-only copy of the current buffer - -;; I just create a new read-only buffer and copy the contents of the -;; current one into it, which can be used as backup. I use this in -;; cases where I need to re-factor a file and do lots of changes. With -;; the buffer copy I have a reference to compare without the need to -;; leave emacs and look at revision control diffs or the like, and if -;; a file is not maintained via VC anyway. - -(defvar copy-counter 0) - -(defun get-copy-buffer-name() - "return unique copy buffer name" - (let ((name (concat "*COPY " (buffer-name (current-buffer)) " (RO)"))) - (if (not (get-buffer name)) - (progn - (setq copy-counter (1+ copy-counter)) - (concat name "<" (number-to-string copy-counter) ">")) - (concat name)))) - -(defun copy-buffer-read-only() - "Create a read-only copy of the current buffer" - (interactive) - (let ((old-buffer (current-buffer)) - (new-buffer-name (get-copy-buffer-name))) - (progn - (delete-other-windows) - (split-window-horizontally) - (other-window 1) - (if (not (eq (get-buffer new-buffer-name) nil)) - (kill-buffer (get-buffer new-buffer-name))) - (set-buffer (get-buffer-create new-buffer-name)) - (insert-buffer-substring old-buffer) - (read-only-mode) - (switch-to-buffer new-buffer-name) - (other-window 1)))) - -(defalias 'cp 'copy-buffer-read-only) - -(global-set-key (kbd "C-c C-p") 'copy-buffer-read-only) ; make read-only buffer copy - -;; -------------------------------------------------------------------------------- -;; ** Cleanup, close all windows and kill all buffers - -;; From time to time I get annoyed by the many dozen buffers -;; opened. In such cases I like to close them all at once. - -;; No key binding though, just in case I stumble upon it and kill my -;; setup accidentally. - -(defun kill-all-buffers () - "Kill all buffers, clean up, close all windows" - (interactive) - (when (y-or-n-p "Close all windows and kill all buffers?") - (delete-other-windows) - (clean-buffer-list) - (dolist (buffer (buffer-list)) - (kill-buffer buffer)) - (delete-minibuffer-contents) - (if (fboundp 'tramp-cleanup-all-connections) - (tramp-cleanup-all-connections)) - (with-current-buffer (get-buffer-create "*text*") - (text-mode)) - (autoscratch-buffer))) - -;; -------------------------------------------------------------------------------- -;; ** Cleanup current buffer - -;; Remove TABs, leading and trailing spaces, re-indent a buffer. - -;; via [[http://whattheemacsd.com/buffer-defuns.el-01.html][whattheemacs.d]] - -(defun cleanup-buffer () - "Perform a bunch of safe operations on the whitespace content of a buffer. -Does not indent buffer, because it is used for a before-save-hook, and that -might be bad." - (interactive) - (untabify (point-min) (point-max)) - (delete-trailing-whitespace) - (save-excursion - (replace-regexp "^\n\\{3,\\}" "\n\n" nil (point-min) (point-max))) - (set-buffer-file-coding-system 'utf-8) - (indent-region (point-min) (point-max))) - -(defalias 'cb 'cleanup-buffer) - -;; related, I use this to cleanup directories and rename files and -;; directories to my liking. Sometimes I get a disk or stick from -;; Windows users and they use every character available on their -;; keyboards to name files and dirs. I can't have this shit. -;; -(defun cleanup-dired-buffer () - "If inside a wdired (edit) buffer, rename everything" - (interactive) - (delete-trailing-whitespace) - (save-excursion - (replace-regexp "[\(\)'`#,_&\!]" "" nil (point-min) (point-max)) - (replace-string " " "-" nil (point-min) (point-max)) - (replace-regexp "--*" "-" nil (point-min) (point-max)) - (replace-string "ä" "ae" nil (point-min) (point-max)) - (replace-string "ö" "oe" nil (point-min) (point-max)) - (replace-string "ü" "ue" nil (point-min) (point-max)) - (replace-string "Ä" "Ae" nil (point-min) (point-max)) - (replace-string "Ö" "Oe" nil (point-min) (point-max)) - (replace-string "Ü" "Ue" nil (point-min) (point-max)) - (replace-string "ß" "ss" nil (point-min) (point-max)) - (replace-string ".." "." nil (point-min) (point-max)))) - -(defun cleanup-dir() - "Cleanup wdired buffer in one whole step, used for emacsclient buffers" - (interactive) - (wdired-change-to-wdired-mode) - (cleanup-dired-buffer) - (wdired-finish-edit) - (kill-this-buffer)) - - -;; -------------------------------------------------------------------------------- -;; ** Remove Umlauts and other crab in current buffer - -;; converts: -;; Stan Lem - ein schönes Leben & sonst nix(ungekuerzte Ausgabe) -;; to: -;; Stan_Lem-ein_schoenes_Leben_sonst_nix_ungekuerzte_Ausgabe -;; -;; used in dired buffers to cleanup filenames by german windows users. -(defun umlaute-weg() - (interactive) - (let ((umlaute '((Ü . Ue) - (Ä . Ae) - (Ö . Oe) - (ü . ue) - (ä . ae) - (ö . oe) - (ß . ss))) - (regs (list - '(" " . "_") - '("_-_" . "-") - '("[\(\)&]" . "_") - '("__*" . "_") - '("_$" . "") - ))) - (save-excursion - (dolist (pair umlaute) - (replace-regexp (symbol-name (car pair)) - (symbol-name (cdr pair)) - nil - (point-min) (point-max))) - (dolist (reg regs) - (replace-regexp (car reg) (cdr reg) nil - (point-min) (point-max)))))) - -;; -------------------------------------------------------------------------------- -;; ** Better newline(s) - -;; Add newline and jump to indent from wherever I am in the current -;; line, that is it is not required to be on the end of line. - -;; via [[http://whattheemacsd.com/editing-defuns.el-01.html][whattheemacs.d]] - -(defun open-line-below () - (interactive) - (end-of-line) - (newline) - (indent-for-tab-command)) - -(defun open-line-above () - (interactive) - (end-of-line) - (beginning-of-line) - (newline) - (forward-line -1) - (indent-for-tab-command)) - -;; disabled, interferes with modes. - -;; (global-set-key (kbd "") 'open-line-below) - -;; (global-set-key (kbd "") 'open-line-above) - -;; -------------------------------------------------------------------------------- -;; ** Mouse Rectangle - -;; There's not much use for the mouse in emacs, but this gimick is -;; funny and works like a charm. - -;; via [[http://emacs.stackexchange.com/a/7261][stackoverflow]] -(defun mouse-start-rectangle (start-event) - (interactive "e") - (deactivate-mark) - (mouse-set-point start-event) - (rectangle-mark-mode +1) - (let ((drag-event)) - (track-mouse - (while (progn - (setq drag-event (read-event)) - (mouse-movement-p drag-event)) - (mouse-set-point drag-event))))) - -(global-set-key (kbd "S-") 'mouse-start-rectangle) - -;; -------------------------------------------------------------------------------- -;; ** DOS <=> UNIX conversion helpers - -(defun dos2unix () - (interactive) - (set-buffer-file-coding-system 'utf-8-unix) - (message (format "converted current buffer to %s" buffer-file-coding-system))) - -(defun unix2dos () - (interactive) - (set-buffer-file-coding-system 'utf-8-dos) - (message (format "converted current buffer to %s" buffer-file-coding-system))) -;; -------------------------------------------------------------------------------- -;; ** helper do add the same thing to multiple mode hooks -;; via [[http://stackoverflow.com/posts/3900056/revisions][stackoverflow]] -;; usage samples below. -(defun add-something-to-mode-hooks (mode-list something) - "helper function to add a callback to multiple hooks" - (dolist (mode mode-list) - (add-hook (intern (concat (symbol-name mode) "-mode-hook")) something))) - -;; -------------------------------------------------------------------------------- - -;; ** helper to catch load errors - -;; Try to eval 'fn, catch errors, if any but make it possible for -;; emacs to continue undisturbed, used with SMEX, see below. -(defmacro safe-wrap (fn &rest clean-up) - `(unwind-protect - (let (retval) - (condition-case ex - (setq retval (progn ,fn)) - ('error - (message (format "Caught exception: [%s]" ex)) - (setq retval (cons 'exception (list ex))))) - retval) - ,@clean-up)) -;; -------------------------------------------------------------------------------- -;; ** Alignment Wrappers - -;; align-regexp is already a very usefull tool, however, sometimes I -;; want to repeat the alignment and I hate C-u, so here are some -;; wrappers to make this easier. - -(defun align-repeat (regex &optional alignment) - "Aply REGEX to all columns not just the first. Align by -ALIGNMENT which must be 'left or 'right. The default is 'left. - -Right alignment: - -col1 ,col2 -col1 ,col2 - -Left alignment: - -col1, col2 -col1, col2" - (interactive "MRepeat Align Regex [ ]: ") - (let ((spc " ") - (beg (point-min)) - (end (point-max)) - (areg "%s\\(\\s-*\\)" ; default left aligned - )) - (when (string= regex "") - (setq regex spc)) - (when (region-active-p) - (setq beg (region-beginning)) - (setq end (region-end))) - (when (eq alignment 'right) - (setq areg "\\(\\s-*\\)%s")) - (align-regexp beg end (format areg regex) 1 1 t))) - -(defun align-repeat-left (regex) - (interactive "MRepeat Left Align Regex [ ]: ") - (align-regexp-repeat regex 'left)) - -(defun align-repeat-right (regex) - (interactive "MRepeat Left Align Regex [ ]: ") - (align-regexp-repeat regex 'right)) - - -;; ** String Helpers - -;; Some helper functions I use here and there. - -(defun tvd-alist-keys (A) - "return a list of keys of alist A" - (let ((K ())) - (dolist (e A) - (push (car e) K) - ) - K)) - -(defun tvd-get-line () - "return current line in current buffer" - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position))) - -(defun tvd-starts-with (s begins) - "Return non-nil if string S starts with BEGINS." - (cond ((>= (length s) (length begins)) - (string-equal (substring s 0 (length begins)) begins)) - (t nil))) - -(defun tvd-replace-all (regex replace) - "Replace all matches of REGEX with REPLACE in current buffer." - (interactive) - (goto-char (point-min)) - (while (re-search-forward regex nil t) - (replace-match replace))) - -;; * Modes -;; ** Programming Languages -;; *** VALA - -(autoload 'vala-mode "vala-mode" "Major mode for editing Vala code." t) -(add-to-list 'auto-mode-alist '("\\.vala$" . vala-mode)) -(add-to-list 'auto-mode-alist '("\\.vapi$" . vala-mode)) -(add-to-list 'file-coding-system-alist '("\\.vala$" . utf-8)) -(add-to-list 'file-coding-system-alist '("\\.vapi$" . utf-8)) - -;; -------------------------------------------------------------------------------- -;; *** rust mode -(autoload 'rust-mode "rust-mode" nil t) - -(defun rustlings-done () - "I use this with rustlings" - (interactive) - (search-backward "DONE") - (move-beginning-of-line 1) - (kill-line) - (save-buffer)) - -(setq auto-mode-alist - (append '(("\\.\\(rs\\)$" . rust-mode)) - auto-mode-alist)) - -;; -------------------------------------------------------------------------------- - -;; *** python mode - -;; Not much configured for python, I'm happy with the defaults as it seems :) -(require 'python) -(autoload 'python-mode "python-mode" "Major mode for python scripts" t) - -(add-hook - 'python-mode-hook - (function - (lambda() - (local-set-key [delete] 'py-electric-delete) - (setq-default indent-tabs-mode nil) - (setq mode-name "PY") - (outline-minor-mode 0) ;; turn off outline here. FIXME: find out where it's turned on! - ))) - -(setq auto-mode-alist - (append '(("\\.\\(py\\)$" . python-mode)) - auto-mode-alist)) -;; -------------------------------------------------------------------------------- -;; *** Shell-Script Mode - -;; C-c C-c [un-]comments everywhere, force in shell-script-mode as well -(add-hook - 'sh-mode-hook - (function - (lambda() - (local-set-key (kbd "C-c C-c") 'comment-or-uncomment-region-or-line)))) - -;; -------------------------------------------------------------------------------- - -;; *** cperl mode - -;; I am a perl addict. I love it, therefore, emacs must be prepared -;; for my addiction. Most importantly, I prefer cperl instead of the -;; default perl mode. I do not use the cperl version delivered with -;; emacs though, but the latest git version. - -(autoload 'cperl-mode "cperl-mode" "alternate perl mode" t) -(defalias 'perl-mode 'cperl-mode) - -;; enable the most important cperl features -(setq cperl-indent-left-aligned-comments nil) -(setq cperl-comment-column 32) -(setq cperl-hairy t) -(setq cperl-electric-linefeed t) -(setq cperl-electric-keywords t) -(setq cperl-electric-parens t) -(setq cperl-electric-parens-string nil) - -;; perl special: run, compile, debug -(setq perl-run-out-buffer "*Async Shell Command*") - -(defun perl-kill () - "get rid of hanging perl compile or run buffers" - (interactive) - (delete-windows-on perl-run-out-buffer) - (kill-buffer perl-run-out-buffer)) - -(defun perl-run (switches parameters prefix) - "execute current perl buffer" - (interactive "sPerl-switches:\nsParameter:\nP") - (let ((file buffer-file-name)) - (if (eq prefix nil) - (shell-command (concat "perl " switches " " file " " parameters "&")) - (shell-command (concat "perl -wc " switches " " file " " parameters "&"))) - (save-excursion - (set-buffer perl-run-out-buffer) - (setq perl-error-fontified nil - perl-error-start nil - perl-error-end nil) - (goto-char (point-min))) - )) - -(defun perl-next-error () - "jump to next perl run error, if any" - (interactive) - (let (line - errorfile - (window (get-buffer-window (buffer-name))) - (file buffer-file-name) - (buffer (buffer-name)) - ) - (select-window (display-buffer perl-run-out-buffer)) - (set-buffer perl-run-out-buffer) - (if (eq perl-error-fontified t) - (progn - (set-text-properties perl-error-start perl-error-end ()) - (setq perl-error-fontified nil) - ) - ) - (if (re-search-forward (concat "at \\([-a-zA-Z:0-9._~#/\\]*\\) line \\([0-9]*\\)[.,]") (point-max) t) - () - (goto-char (point-min)) - (message "LAST ERROR, jumping to first") - (re-search-forward (concat "at \\([-a-zA-Z:0-9._~#/\\]*\\) line \\([0-9]*\\)[.,]") (point-max) t) - ) - (recenter) - (set-text-properties (match-beginning 1) - (match-end 2) - (list 'face font-lock-keyword-face)) - (setq perl-error-fontified t - perl-error-start (match-beginning 1) - perl-error-end (match-end 2) - errorfile (buffer-substring - (match-beginning 1) - (match-end 1)) - line (string-to-int (buffer-substring - (match-beginning 2) - (match-end 2)))) - (select-window window) - (find-file errorfile) - (goto-line line))) - -;; cperl indent region -(defun own-cperl-indent-region-or-paragraph (start end) - (interactive "r") - (if mark-active - (cperl-indent-region start end) - (save-excursion - (mark-paragraph) - (cperl-indent-region (point) (mark t)) - ))) - -;; and hook them into cperl -(add-hook - 'cperl-mode-hook - (function - (lambda() - (make-variable-buffer-local 'perl-error-fontified) - (make-variable-buffer-local 'perl-error-start) - (make-variable-buffer-local 'perl-error-end) - (make-variable-buffer-local 'perl-old-switches) - (make-variable-buffer-local 'perl-old-parameters) - (local-set-key "\C-hF" 'cperl-info-on-current-command) - (local-set-key "\C-hf" 'describe-function) - (local-set-key "\C-hV" 'cperl-get-help) - (local-set-key "\C-hv" 'describe-variable) - (local-set-key "\C-cr" 'perl-run) - (local-set-key "\C-ck" 'perl-kill) - (local-set-key "\C-c#" 'perl-next-error) - (local-set-key "\M-\C-q" 'own-cperl-indent-region-or-paragraph) - (setq mode-name "PL") - ))) - - - -;; -------------------------------------------------------------------------------- - -;; *** Paredit for lisp only - -;; 13.11.2018: disabled in exchange for smartparens, which see - -;; I use paredit in lisp a lot, and I'm mostly happy with the defaults. - -;; (autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t) - -;; ;; However, I use it with lisp dialects only -;; (add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode) -;; (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode) -;; (add-hook 'ielm-mode-hook #'enable-paredit-mode) -;; (add-hook 'lisp-mode-hook #'enable-paredit-mode) -;; (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode) -;; (add-hook 'scheme-mode-hook #'enable-paredit-mode) -;; (add-hook 'slime-repl-mode-hook (lambda () (paredit-mode +1))) - -;; ;; sometimes I need to be able to turn it off fast: -;; (defalias 'pe 'paredit-mode) - -;; (eval-after-load 'paredit -;; '(progn -;; ;; force my own bindings for those -;; (define-key paredit-mode-map (kbd "C-d") nil) -;; (define-key paredit-mode-map (kbd "") nil) -;; (define-key paredit-mode-map (kbd "") nil))) -;; -------------------------------------------------------------------------------- -;; *** Smart Parens -;; I'm trying to migrate to smart-parens, since it supports all of -;; paredit but can do more - -;; Also look at: -;; https://github.com/Fuco1/.emacs.d/blob/master/files/smartparens.el -;; https://github.com/Fuco1/smartparens/wiki -;; https://ebzzry.io/en/emacs-pairs/ -(require 'smartparens-config) -(require 'cl) - -(defun tvd-disable-par-and-pair() - "Disables Paredit and Electric-Pair-Mode if currently active. -Used when enabling smartparens-mode." - (interactive) - (when electric-pair-mode - (electric-pair-mode)) - (when (fboundp 'pparedit-mode) - (when paredit-mode - (disable-paredit-mode)))) - -;; enable sp in minibuffer as well -;; maybe, see: https://github.com/Fuco1/smartparens/issues/33: -;; (sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil) -(setq sp-ignore-modes-list - (delete 'minibuffer-inactive-mode sp-ignore-modes-list)) - -;; automatically enable where needed -(add-something-to-mode-hooks - '(rust emacs-lisp ielm lisp lisp-interaction scheme slime-repl ) 'smartparens-mode) - -;; also in some select prog modes -(add-something-to-mode-hooks - '(perl ruby c c++ shell-script makefile config-general) 'smartparens-mode) - -;; I use my own lisp comment tool until sp#942 is fixed -(defun tvd-lisp-comment () - (interactive) - (if (not (looking-at "\s*\(")) - (self-insert-command 1) - (let ((beg (point))) - (forward-list 1) - (when (looking-at "\s*\)") - (insert "\n")) - (comment-region beg (point)) - (indent-for-tab-command) - (goto-char beg)))) - -(eval-after-load 'smartparens - '(progn - ;; hydra via https://github.com/lunaryorn/old-emacs-configuration/blob/master/init.el - (defhydra hydra-smartparens (:hint nil) - " -Sexps [quit with _q_, reach this hydra with 'C-x ('] - -^Nav^ ^Barf/Slurp^ ^Depth^ -^---^-----------------------^----------^---------------------------^-----^----------------- -_f_: forward (C-M-right) _→_: slurp forward (C-right) _R_: splice -_b_: backward (C-M-left) _←_: barf forward (C-left) _r_: raise -_u_: backward ↑ _C-_: slurp backward _↑_: raise backward -_d_: forward ↓ (C-M-down) _C-_: barf backward _↓_: raise forward -_p_: backward ↓ -_n_: forward ↑ (C-M-up) - -^Kill^ ^Misc^ ^Wrap^ -^----^-----------^----^-----------------------^----^------------------ -_w_: copy _j_: join _(_: wrap with ( ) -_k_: kill (C-k) _s_: split _{_: wrap with { } -^^ _t_: transpose _'_: wrap with ' ' -^^ _c_: convolute _\"_: wrap with \" \" -^^ _i_: indent defun - -" - ("q" nil) - ;; Wrapping - ("(" (lambda (_) (interactive "P") (sp-wrap-with-pair "("))) - ("{" (lambda (_) (interactive "P") (sp-wrap-with-pair "{"))) - ("'" (lambda (_) (interactive "P") (sp-wrap-with-pair "'"))) - ("\"" (lambda (_) (interactive "P") (sp-wrap-with-pair "\""))) - ;; Navigation - ("f" sp-forward-sexp ) - ("b" sp-backward-sexp) - ("u" sp-backward-up-sexp) - ("d" sp-down-sexp) - ("p" sp-backward-down-sexp) - ("n" sp-up-sexp) - ;; Kill/copy - ("w" sp-copy-sexp) - ("k" sp-kill-sexp) - ;; Misc - ("t" sp-transpose-sexp) - ("j" sp-join-sexp) - ("s" sp-split-sexp) - ("c" sp-convolute-sexp) - ("i" sp-indent-defun) - ;; Depth changing - ("R" sp-splice-sexp) - ("r" sp-splice-sexp-killing-around) - ("" sp-splice-sexp-killing-backward) - ("" sp-splice-sexp-killing-forward) - ;; Barfing/slurping - ("" sp-forward-slurp-sexp) - ("" sp-forward-barf-sexp) - ("C-" sp-backward-barf-sexp) - ("C-" sp-backward-slurp-sexp)) - - ;; via https://ebzzry.io/en/emacs-pairs/: - (defmacro def-pairs (pairs) - "Define functions for pairing. PAIRS is an alist of (NAME . STRING) -conses, where NAME is the function name that will be created and -STRING is a single-character string that marks the opening character. - - (def-pairs ((paren . \"(\") - (bracket . \"[\")) - -defines the functions WRAP-WITH-PAREN and WRAP-WITH-BRACKET, -respectively." - `(progn - ,@(loop for (key . val) in pairs - collect - `(defun ,(read (concat - "wrap-with-" - (prin1-to-string key) - "s")) - (&optional arg) - (interactive "p") - (sp-wrap-with-pair ,val))))) - (def-pairs ((paren . "(") - (bracket . "[") - (brace . "{") - (single-quote . "'") - (double-quote . "\"") - (back-quote . "`"))) - - ;;(add-hook 'smartparens-enabled-hook #'tvd-disable-par-and-pair) - ;;(add-hook 'smartparens-enabled-hook #'turn-on-smartparens-strict-mode) - - ;; auto wrapping w/o region - (define-key smartparens-mode-map (kbd "C-c (") 'wrap-with-parens) - (define-key smartparens-mode-map (kbd "C-c [") 'wrap-with-brackets) - (define-key smartparens-mode-map (kbd "C-c {") 'wrap-with-braces) - (define-key smartparens-mode-map (kbd "C-c '") 'wrap-with-single-quotes) - (define-key smartparens-mode-map (kbd "C-c \"") 'wrap-with-double-quotes) - (define-key smartparens-mode-map (kbd "C-c `") 'wrap-with-back-quotes) - - ;; modification - (define-key smartparens-mode-map (kbd "C-x (") 'hydra-smartparens/body) - (define-key smartparens-mode-map (kbd "C-k") 'sp-kill-hybrid-sexp) - (define-key smartparens-mode-map (kbd "C-") 'sp-forward-slurp-sexp) - (define-key smartparens-mode-map (kbd "C-") 'sp-forward-barf-sexp) - - ;; movement - ;; Also Check: https://github.com/Fuco1/smartparens/wiki/Working-with-expressions - ;; (look for "quick summary for each navigation function") - ;; - ;; Jump after the next balanced expression. If inside one and - ;; there is no forward exp., jump after its closing pair. - (define-key smartparens-mode-map (kbd "C-M-") 'sp-forward-sexp) - ;; Jump before the previous balanced expression. If inside one - ;; and there is no previous exp., jump before its opening pair. - (define-key smartparens-mode-map (kbd "C-M-") 'sp-backward-sexp) - ;; Jump up one level from the current balanced expression. This - ;; means skipping all the enclosed expressions within this and - ;; then jumping after the closing pair. - (define-key smartparens-mode-map (kbd "C-M-") 'sp-up-sexp) - ;; Jump after the opening pair of next balanced expression. This - ;; effectively descends one level down in the "expression - ;; hierarchy". If there is no expression to descend to, jump - ;; after current expression's opening pair. This can be used to - ;; quickly navigate to the beginning of current balanced - ;; expression. - (define-key smartparens-mode-map (kbd "C-M-") 'sp-down-sexp) - ;; Jump to the beginning of following balanced expression. If - ;; there is no following expression on the current level, jump - ;; one level up backward, effectively doing sp-backward-up-sexp. - (define-key smartparens-mode-map (kbd "C-S-") 'sp-next-sexp) - ;; Jump to the end of the previous balanced expression. If there - ;; is no previous expression on the current level, jupm one level - ;; up forward, effectively doing sp-up-sexp. - (define-key smartparens-mode-map (kbd "C-S-") 'sp-previous-sexp) - - ;; comment the whole sexp - (define-key smartparens-mode-map (kbd ";") 'tvd-lisp-comment) - - ;; replace my global setting - ;; FIXME: fhceck/fix M! - (define-key smartparens-mode-map (kbd "M-") 'sp-forward-symbol) - (define-key smartparens-mode-map (kbd "M-") 'sp-backward-symbol))) - -;; -------------------------------------------------------------------------------- -;; *** ETAGS - -;; I use ETAGS for some projects. With etags I can easily jump to the -;; definition of a function, struct or whatever across files and -;; directories. - -;; manually generate the tags file: -;; /usr/bin/ctags-exuberant -e *.c ... -;; visit-tags-file ("TAGS" whereever ctags run) - -;; then load TAGS with visit-tags-table -(require 'etags-select) - -;; generate TAGS and load it -(defun etags-create (dir-name) - "Create tags file." - (interactive "DDirectory: ") - (let* ((ctags "/usr/bin/ctags-exuberant") - (odir (directory-file-name dir-name)) - (ofile (concat odir "/TAGS")) - (langs "lisp,python,perl,c,c++,shell") - (shell-command - (format "%s -f %s -e -R --languages=%s %s" ctags ofile langs odir)) - (visit-tags-table ofile)))) - -;; ALT_R + e (equals on de keyboard € sign): jump to tag source -(global-set-key (kbd "€") 'etags-select-find-tag-at-point) ; alt-right + e: jump to tag definition - -;; Use ido to list tags, but then select via etags-select (best of both worlds!) -(defun etags-find () - "Find a tag using ido" - (interactive) - (tags-completion-table) - (let (tag-names) - (mapatoms (lambda (x) - (push (prin1-to-string x t) tag-names)) - tags-completion-table) - (etags-select-find (ido-completing-read "Tag: " tag-names)))) - -;; some handy aliases -(defalias 'ec 'etags-create) -(defalias 'ef 'etags-find) - -;; -------------------------------------------------------------------------------- - -;; *** Go Lang -(autoload 'go-mode "go-mode" nil t) -(add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode)) - -;; -------------------------------------------------------------------------------- -;; ** Text Modes -;; *** sgml - -;; Used for XML and the likes. - -(setq sgml-set-face t) -(setq sgml-balanced-tag-edit t) -(setq sgml-omittag-transparent nil) -(setq sgml-auto-insert-required-elements t) - -(setq sgml-markup-faces - '((start-tag . font-lock-function-name-face) - (end-tag . font-lock-function-name-face) - (comment . font-lock-comment-face) - (pi . font-lock-other-type-face) - (sgml . font-lock-variable-name-face) - (doctype . font-lock-type-face) - (entity . font-lock-string-face) - (shortref . font-lock-keyword-face))) -;; -------------------------------------------------------------------------------- - -;; *** web-mode (JS, HTML, CSS combined) - -;; Web development is shit. Tech involved is a mess, and in most cases -;; intermixed. web-mode provides a great fix for this: it handles -;; HTML, CSS and Javascript in the same buffer very well. - -;; See: [[http://web-mode.org/][web-mode.org]] - -(require 'web-mode) - -;; associate with the usual suspects -(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode)) -(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)) - -;; configure web mode -(defun tvd-web-mode-hook () - "Hooks for Web mode." - (setq web-mode-markup-indent-offset 2) - (setq web-mode-css-indent-offset 2) - (setq web-mode-code-indent-offset 2) - (setq web-mode-style-padding 1) - (setq web-mode-script-padding 1) - (setq web-mode-block-padding 0) - (setq web-mode-enable-auto-pairing t) - (setq web-mode-enable-auto-expanding t)) -(add-hook 'web-mode-hook 'tvd-web-mode-hook) - -;; some handy html code inserters -(defun html-insert-p() - (interactive) - (web-mode-element-wrap "p")) - -(defun html-insert-li() - (interactive) - (web-mode-element-wrap "li")) - -(defun html-insert-ul() - (interactive) - (web-mode-element-wrap "ul")) - -(defun html-insert-b() - (interactive) - (web-mode-element-wrap "b")) - -;; convert a text list into a html list. -(defun html-listify (beg end) - (interactive "r") - (save-excursion - (let* ((lines (split-string (buffer-substring beg end) "\n" t))) - (delete-region beg end) - (insert "
        \n") - (while lines - (insert "
      • ") - (insert (pop lines)) - (insert "
      • \n")) - (insert "
      \n") - ))) -;; -------------------------------------------------------------------------------- - -;; *** Cisco Mode - -;; Written by myself many years ago, but I'm still using it daily to -;; view and prepare cisco configs. - -(autoload 'cisco-mode "cisco-mode" "Major mode for CISCO configs" t) -(setq auto-mode-alist - (append '(("\\.\\(cfg\\)$" . cisco-mode)) - auto-mode-alist)) -;; -------------------------------------------------------------------------------- - -;; *** Markdown - -;; I rarely use markdown, but sometimes I stumble upon such a file and -;; like to view it with emacs without rendering. -;; Source: [[http://jblevins.org/projects/markdown-mode/][jblevins.org]] - -(autoload 'markdown-mode "markdown-mode" - "Major mode for editing Markdown files" t) - -(add-to-list 'auto-mode-alist '("\\.text\\'" . markdown-mode)) -(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode)) -(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode)) - -;; parens and quotes constraints check on save -(add-hook 'markdown-mode-hook - (lambda () - (when buffer-file-name - (add-hook 'after-save-hook - 'check-parens - nil t)) - (modify-syntax-entry ?\" "\"" markdown-mode-syntax-table) - )) -;; -------------------------------------------------------------------------------- - -;; *** POD mode - -;; I LOVE POD! POD is the documentation format of perl and there's a -;; solid toolset available for it. I use it to write documentation and -;; manual pages. It's much more powerfull than lame markdown and you -;; can even program great tools yourself around POD (like I did with -;; PodWiki years ago!) - -;; Although cperl mode already has some POD support, pod mode is way -;; better. - -;; Source: [[https://github.com/renormalist/emacs-pod-mode][emacs-pod-mode]] - -(require 'pod-mode) -(add-to-list 'auto-mode-alist '("\\.pod$" . pod-mode)) -(add-hook 'pod-mode-hook 'font-lock-mode) - -;; using expand-region: apply pod entity formatting to word at point. -(defun tvd-outline-emphasize(CHAR) - "expand once if no region and apply emphasize CHAR" - (interactive) - (unless (use-region-p) - (er/expand-region 1)) - (save-excursion - (goto-char (region-beginning)) - (insert (format "%c<" CHAR)) - (goto-char (region-end)) - (insert ">"))) - -(defun pod-bold() - "bold text in outline mode" - (interactive) - (tvd-outline-emphasize ?B)) - -(defun pod-italic() - "italic text in outline mode" - (interactive) - (tvd-outline-emphasize ?I)) - -(defun pod-code() - "verbatim text in outline mode" - (interactive) - (tvd-outline-emphasize ?C)) - -;; enhance abbrevs and jump into expanded area to the -;; $ character (if it exists), which it also removes -(setq tvd-abbrev-pos 0) -(advice-add 'expand-abbrev :before - '(lambda () (setq tvd-abbrev-pos (point)))) -(advice-add 'expand-abbrev :after - '(lambda () - (ignore-errors - (when (re-search-backward "\\$" (- tvd-abbrev-pos 0)) - (delete-char 1))))) - -;; pod mode config -(add-hook 'pod-mode-hook - (lambda () - ;; tune syntax table - (modify-syntax-entry ?= "w" pod-mode-syntax-table) - - ;; POD contains headers and I'm used to outlining if there are headers - ;; so, enable outlining - (setq outline-heading-alist '(("=head1" . 1) - ("=head2" . 2) - ("=head3" . 3) - ("=head4" . 4) - ("=over" . 5) - ("=item" . 6) - ("=begin" . 5) - ("=pod" . 5) - )) - - ;; outline alone, however, works well - (outline-minor-mode) - - ;; my own abbrevs for POD using mode-specific abbrev table - (define-abbrev-table 'pod-mode-abbrev-table '( - ("=o" "=over\n\n=item *$\n\n=back\n\n") - ("=i" "=item ") - ("=h1" "=head1 ") - ("=h2" "=head2 ") - ("=h3" "=head3 ") - ("=h4" "=head4 ") - ("=c" "=cut") - ("=b" "=begin") - ("=e" "=end") - ("b" "B<$>") - ("c" "C<$>") - ("l" "L<$>") - ("i" "I<$>") - ("e" "E<$>") - ("f" "F<$>")) - "POD mode abbreviations, see .emacs") - - (abbrev-table-put pod-mode-abbrev-table :case-fixed t) - (abbrev-table-put pod-mode-abbrev-table :system t) - - ;; enable abbreviations - (setq local-abbrev-table pod-mode-abbrev-table) - (abbrev-mode 1) - - ;; POD easy formatting - (local-set-key (kbd "C-c b") 'pod-bold) - (local-set-key (kbd "C-c /") 'pod-italic) - (local-set-key (kbd "C-c c") 'pod-code))) - -;; -------------------------------------------------------------------------------- -;; *** conf-mode - -;; conf-mode annoyingly overwrites the global keybinding C-c C-c with -;; some of its internal crab. So, force it to use my own defun. Also, -;; while we're at it, disable electric indent, it's annoying in -;; configs. Applies for derivates as well. - -(defun tvd-disarm-conf-mode() - (local-set-key (kbd "C-c C-c") 'comment-or-uncomment-region-or-line) - (electric-indent-local-mode 0)) - -(add-something-to-mode-hooks '(conf cisco fundamental conf-space pod) 'tvd-disarm-conf-mode) -;; -------------------------------------------------------------------------------- - -;; *** Config::General mode -;; **** Config and doc -;; [[https://github.com/TLINDEN/config-general-mode][config-general-mode]] (also on Melpa). - -;; My own mode for [[http://search.cpan.org/dist/Config-General/][Config::General]] -;; config files. Whenever I write some perl stuff, which needs a config file, I use -;; this module (and I do this a lot). Previously I used conf-mode or html-mode, but -;; both did not satisfy me. Now (as of 20170625) I solved this mess once and for all. - -(require 'config-general-mode) -(require 'sh-script) - -;; **** Convenicence Wrappers -(defun config-general-completion-at-point () - "Complete word at point using hippie-expand, if not on a comment." - (interactive) - (when (looking-back "[-%$_a-zA-Z0-9]") - (unless (eq (get-text-property (point) 'face) 'font-lock-comment-face) - (hippie-expand nil)))) - -(defun config-general-do-electric-tab () - "Enter a or goto current indentation." - (interactive) - (if (eq (point) (line-end-position)) - (indent-for-tab-command) - (back-to-indentation))) - -(defun config-general-tab-or-expand () - "Do electric TAB or completion depending where point is. - -This is just a convenience function, which can be mapped -to `tab' by the user. .Not in use by default." - (interactive) - (unless (config-general-completion-at-point) - (config-general-do-electric-tab))) - -;; FIXME: Use this patched version for older emacsen and the default -;; for version which contain the patch (if any, ever). -;; -;; The original function try-expand-dabbrev-all-buffers doesn't work -;; correctly, it ignores a buffer-local configuration of the variables -;; hippie-expand-only-buffers and hippie-expand-ignore-buffers. This -;; is the patched version of the function. -;; -;; Bugreport: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=27501 -(defun config-general--try-expand-dabbrev-all-buffers (old) - "Try to expand word \"dynamically\", searching all other buffers. -The argument OLD has to be nil the first call of this function, and t -for subsequent calls (for further possible expansions of the same -string). It returns t if a new expansion is found, nil otherwise." - (let ((expansion ()) - (buf (current-buffer)) - (orig-case-fold-search case-fold-search) - (heib hippie-expand-ignore-buffers) - (heob hippie-expand-only-buffers) - ) - (if (not old) - (progn - (he-init-string (he-dabbrev-beg) (point)) - (setq he-search-bufs (buffer-list)) - (setq he-searched-n-bufs 0) - (set-marker he-search-loc 1 (car he-search-bufs)))) - - (if (not (equal he-search-string "")) - (while (and he-search-bufs - (not expansion) - (or (not hippie-expand-max-buffers) - (< he-searched-n-bufs hippie-expand-max-buffers))) - (set-buffer (car he-search-bufs)) - (if (and (not (eq (current-buffer) buf)) - (if heob - (he-buffer-member heob) - (not (he-buffer-member heib)))) - (save-excursion - (save-restriction - (if hippie-expand-no-restriction - (widen)) - (goto-char he-search-loc) - (setq expansion - (let ((case-fold-search orig-case-fold-search)) - (he-dabbrev-search he-search-string nil))) - (set-marker he-search-loc (point)) - (if (not expansion) - (progn - (setq he-search-bufs (cdr he-search-bufs)) - (setq he-searched-n-bufs (1+ he-searched-n-bufs)) - (set-marker he-search-loc 1 (car he-search-bufs)))))) - (setq he-search-bufs (cdr he-search-bufs)) - (set-marker he-search-loc 1 (car he-search-bufs))))) - - (set-buffer buf) - (if (not expansion) - (progn - (if old (he-reset-string)) - ()) - (progn - (he-substitute-string expansion t) - t)))) - -;; **** Mode Hook - -;; I use TAB for completion AND tab and outshine. Also, the mode -;; enables electric indent automatically, but I disabled it for -;; conf-mode (see tvd-disarm-conf-mode), therefore I re-enable it here -;; for config-general-mode (which inherits from conf-mode). -(add-hook 'config-general-mode-hook - (lambda () - (electric-indent-mode) - ;; de-activate some senseless bindings - (local-unset-key (kbd "C-c C-c")) - (local-unset-key (kbd "C-c C-p")) - (local-unset-key (kbd "C-c C-u")) - (local-unset-key (kbd "C-c C-w")) - (local-unset-key (kbd "C-c C-x")) - (local-unset-key (kbd "C-c :")) - (local-set-key (kbd "") 'config-general-tab-or-expand) - - ;; from shell-script-mode, turn << into here-doc - (sh-electric-here-document-mode 1) - - ;; Inserting a brace or quote automatically inserts the matching pair - ;; use smartparens now - ;; (electric-pair-mode t) - (setq-local hippie-expand-only-buffers '(config-general-mode)) - - ;; configure order of expansion functions - (if (version< emacs-version "25.1") - (set (make-local-variable 'hippie-expand-try-functions-list) - '(try-expand-dabbrev ;; use patched version - config-general--try-expand-dabbrev-all-buffers - try-complete-file-name-partially - try-complete-file-name)) - (set (make-local-variable 'hippie-expand-try-functions-list) - '(try-expand-dabbrev - try-expand-dabbrev-all-buffers - try-complete-file-name-partially - try-complete-file-name))) - ;; enable - (add-hook 'completion-at-point-functions 'config-general-completion-at-point) - ) - ) - -;; -------------------------------------------------------------------------------- -;; *** Xmodmap Mode - -;; the shortest mode ever, [[https://www.emacswiki.org/emacs/XModMapMode][via emacswiki]]. - -(define-generic-mode 'xmodmap-mode - '(?!) - '("add" "clear" "keycode" "keysym" "pointer" "remove") - '(("[0-9]+" . 'font-lock-variable-name-face)) - '("[xX]modmap\\(rc\\)?\\'") - nil - "Simple mode for xmodmap files.") - -;; [[https://www.emacswiki.org/emacs/GenericMode][see GenericMode for more examples]]. - -;; *** MMM Mode -;; **** MMM configure: -(add-to-list 'load-path (concat tvd-lisp-dir "/mmm-mode")) - -(require 'cl) -(require 'mmm-auto) -(require 'mmm-vars) - -(setq mmm-submode-decoration-level 2) - - -;; [[https://github.com/purcell/mmm-mode][mmm-mode github]] -;; see doc for class definition in var 'mmm-classes-alist - -;; **** MMM config for POD mode -(mmm-add-classes - '((html-pod - :submode html-mode ;; web-mode doesnt work this way! - :delimiter-mode nil - :front "=begin html" - :back "=end html"))) - -(mmm-add-mode-ext-class 'pod-mode nil 'html-pod) - -(add-hook 'pod-mode-hook 'mmm-mode-on) - -;; *** Yaml Mode -(require 'yaml-mode) -(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)) -(add-to-list 'auto-mode-alist '("\\.j2\\'" . yaml-mode)) - -(add-hook 'yaml-mode-hook - '(lambda () - (define-key yaml-mode-map "\C-m" 'newline-and-indent))) -;; ** Text Manupilation -;; *** expand-region - -;; One of the best modes I ever discovered. Press C-= multiple times -;; to create a larger and larger region. I use C-0 (zero) because on a -;; german keyboard this is the same as C-= without pressing shift. - -(require 'expand-region) -(global-set-key (kbd "C-0") 'er/expand-region) ; C-= without pressing shift on DE keyboard - -;; related to ER: -;; *** Mark, Copy, Yank Things - -;; For a long time this stuff was located here in my emacs config. As -;; it grew larger and larger I decided to put it into its own mode: -;; mark-copy-yank-things-mode, which can be found on github these -;; days. - -;; With this, you can quickly mark or copy or copy+yank things like -;; words, ip's, url's, lines or defun's with one key binding. I use -;; this permanently and couldn't live without it anymore. - -;; A special feature is the copy+yanking, this is something vi offers: -;; go to a line, press yy, then p and the current line will be yanked -;; below. Prefix with a number and copy+yank more lines. This is -;; really cool and (in vi) often used. So, with this mode, I can use -;; it with emacs as well. For example, say you edit a configuration -;; file and added a complicated statement. Next you need to add -;; another very similar statement. Instead of entering it again, you -;; just hit and the current line appears as a copy -;; below. Change the differences and you're done! - -(require 'mark-copy-yank-things-mode) -(mark-copy-yank-things-global-mode) - -;; The mode has a rather impractical prefix since it's published on -;; github and therefore must be written in a way not to disturb other -;; modes. However, I myself need those simple prefixes: -(define-key mark-copy-yank-things-mode-map (kbd "C-c") 'mcyt-copy-map) -(define-key mark-copy-yank-things-mode-map (kbd "M-a") 'mcyt-mark-map) -;; I use the default yank map - -;; With this I put the last thing copied into a register 'c. I can -;; then later yank this using C-v anytime without browsing the -;; kill-ring if I kill things between yanking. So, C-v always inserts -;; the last copied thing, while C-y yanks the last thing killed, which -;; might be something else. -(advice-add 'mcyt--copy-thing - :after - '(lambda (&rest args) - (with-temp-buffer - (yank) - (copy-to-register 'c (point-min) (point-max))))) - -(defun tvd-insert-c-register () - (interactive) - (insert-register 'c)) - -(global-set-key (kbd "C-v") 'tvd-insert-c-register) - -;; copy a real number and convert it to german punctuation upon -;; yanking, so I can do some calculations in 'calculator, copy the -;; result NNN.NN and paste it into my online banking formular, where -;; it appears as NNN,NN. -(defun tvd-mcyt-copy-euro (&optional arg) - "Copy euro at point into kill-ring and convert to german -punctuation" - (interactive "P") - (mcyt--blink-and-copy-thing 'mcyt-beginning-of-ip 'mcyt-end-of-ip arg) - (with-temp-buffer - (yank) - (beginning-of-buffer) - (while (re-search-forward "\\." nil t) - (replace-match ",")) - (kill-region (point-min) (point-max)))) - -(eval-after-load "mark-copy-yank-things-mode" - '(progn - (add-hook 'mark-copy-yank-things-mode-hook - (lambda () ;; g like [G]eld - (define-key mcyt-copy-map (kbd "g") 'tvd-mcyt-copy-euro))))) - - - -;; -------------------------------------------------------------------------------- - -;; *** change-inner - -;; I use change-inner with a prefix key and some wrappers around -;; mark-copy-yank-things-mode, which is related to change-inner -;; and expand-region. - -;; [[https://github.com/magnars/change-inner.el][github source]]: -(require 'change-inner) - -;; first some functions: - -(defun tvd-ci (beg end &optional ins) - "change-inner simulator which works with symbols instead of strings. - -BEG and END must be executable elisp symbols moving (point). Everything -in between will be killed. If INS is non-nil, it will be inserted then." - (interactive) - (let ((B nil)) - (funcall beg) - (setq B (point)) - (funcall end) - (kill-region B (point)) - (when ins - (insert ins)))) - -(defun tvd-ci-comment () - "\"change inner\" a whole comment [block]." - (interactive) - (tvd-ci 'mcyt-beginning-of-comment-block - 'mcyt-end-of-comment-block - (format "%s;# " comment-start))) - -(defun tvd-ci-quote () - "\"change inner\" quoted text." - (interactive) - (tvd-ci 'mcyt-beginning-of-quote - 'mcyt-end-of-quote)) - -(defun tvd-ci-word () - "\"change inner\" a word (like cw in vi)." - (interactive) - (tvd-ci 'mcyt-beginning-of-symbol - 'mcyt-end-of-symbol)) - -(defun tvd-ci-line () - "\"change inner\" a whole line." - (interactive) - (tvd-ci 'beginning-of-line - 'end-of-line)) - -(defun tvd-ci-paragraph () - "\"change inner\" a whole paragraph." - (interactive) - (tvd-ci 'backward-paragraph - 'forward-paragraph)) - -(defun tvd-ci-buffer () - "\"change inner\" a whole buffer." - (interactive) - (tvd-ci 'point-min - 'point-max)) - -(defun tvd-ci-sexp () - "\"change inner\" a whole sexp." - (interactive) - (er/mark-inside-pairs) - (call-interactively 'kill-region)) - -;; Define ALT_R (AltGR) + i as my prefix command for change-inner stuff. -;; Since I use a german keyboard, this translates to →. -;; I'll refrence it here now as -(define-prefix-command 'ci-map) -(global-set-key (kbd "→") 'ci-map) - -;; typing the prefix key twice calls the real change-inner -(define-key ci-map (kbd "→") 'change-inner) ;; - -(define-key ci-map (kbd "c") 'tvd-ci-comment) ;; -(define-key ci-map (kbd "¢") 'tvd-ci-comment) ;; - -(define-key ci-map (kbd "q") 'tvd-ci-quote) ;; -(define-key ci-map (kbd "@") 'tvd-ci-quote) ;; - -(define-key ci-map (kbd "w") 'tvd-ci-word) ;; -(define-key ci-map (kbd "ł") 'tvd-ci-word) ;; - -(define-key ci-map (kbd "l") 'tvd-ci-line) ;; - -(define-key ci-map (kbd "s") 'tvd-ci-sexp) ;; -(define-key ci-map (kbd "ſ") 'tvd-ci-sexp) ;; - -(define-key ci-map (kbd "p") 'tvd-ci-paragraph) ;; -(define-key ci-map (kbd "þ") 'tvd-ci-paragraph) ;; - -(define-key ci-map (kbd "a") 'tvd-ci-buffer) ;; -(define-key ci-map (kbd "æ") 'tvd-ci-buffer) ;; - -;; -------------------------------------------------------------------------------- -;; *** Rotate text - -;; This one is great as well, I use it to toggle flags and such stuff -;; in configs or code with just one key binding. - -;; Source: [[http://nschum.de/src/emacs/rotate-text/][nschum.de]] - -(autoload 'rotate-text "rotate-text" nil t) -(autoload 'rotate-text-backward "rotate-text" nil t) - -;; my toggle list -(setq rotate-text-words '(("width" "height") - ("left" "right" "top" "bottom") - ("ja" "nein") - ("off" "on") - ("true" "false") - ("nil" "t") - ("yes" "no"))) - -;; C-t normally used by transpose-chars, so, unbind it first -(global-unset-key (kbd "C-t")) - -;; however, we cannot re-bind it globally since then it could not be -;; used in org-mode for org-todo (see below) FIXME: I only use the "t" -;; short command anymore, so C-t would be free now, wouldn't it? -(add-something-to-mode-hooks - '(c c++ cperl vala web emacs-lisp python ruby) - '(lambda () - (local-set-key (kbd "C-t") 'rotate-text))) - -;; -------------------------------------------------------------------------------- - -;; *** Word wrapping -;; same as word-wrap but without the fringe which I hate the most! -(add-something-to-mode-hooks '(tex text eww) 'visual-line-mode) - -;; however, it's required when coding, so enable it globally -;; overwritten by visual-line-mode above for specifics -(setq word-wrap t) -;; -------------------------------------------------------------------------------- - -;; *** Viking Mode - -;; Delete stuff fast. Press the key multiple times - delete more -;; things. Inspired by expand-region. Written by myself. - -(require 'viking-mode) -(viking-global-mode) -(setq viking-greedy-kill nil) -(define-key viking-mode-map (kbd "M-d") 'viking-repeat-last-kill) -;; -------------------------------------------------------------------------------- - -;; *** HTMLize - -;; extracted from debian package emacs-goodies-el-35.2+nmu1, since -;; there's no other source left. Generates a fontified html version of -;; the current buffer, however it looks. - -(require 'htmlize) -(setq htmlize-output-type "inline-css") - - -;; *** iEdit (inline edit multiple searches) - -;; Edit all occurences of something at once. Great for re-factoring. - -(require 'iedit) - -(global-set-key (kbd "C-c C-e") 'iedit-mode) - -;; Keep buffer-undo-list as is while iedit is active, that is, as long -;; as I am inside iedit I can undo/redo current occurences. However, -;; if I leave iedit and issue the undo command, ALL changes made with -;; iedit are undone, whereas the default behaviour would be to go -;; through every change made iside iedit, which I hate. - -;; iedit doesn't provide a customizable flag to configure it's undo -;; behavior, so, I modify it myself using defadvice. - -(setq tvd-buffer-undo-list nil) -(advice-add 'iedit-mode :before '(lambda (&rest args) ;; save current - (setq tvd-buffer-undo-list buffer-undo-list))) - -(advice-add 'iedit-mode :after '(lambda (&rest args) ;; restore previously saved - (setq buffer-undo-list tvd-buffer-undo-list))) - -;; -------------------------------------------------------------------------------- - -;; ** Interactives -;; *** eShell stuff, or if interactive stuff is needed, use ansi-term - -;; I am a hardcore bash user, but from time to time eshell is good -;; enough. It's great when used remote when only sftp is supported. - -(require 'eshell) - -;; fac'ifier -(defmacro with-face (str &rest properties) - `(propertize ,str 'face (list ,@properties))) - -;; custom prompt, which resembles my bash prompt -(defun shk-eshell-prompt () - (let ((header-bg "Azure")) - (concat - (with-face "\n") - (with-face (format-time-string - "[%Y-%m-%d %H:%M] --- [" - (current-time)) :background header-bg :foreground "Black") - (with-face (concat (eshell/pwd) "") :background header-bg :foreground "Blue") - (with-face "] --- " :background header-bg :foreground "Black") - (with-face (or - (ignore-errors (format "(%s)" (vc-responsible-backend default-directory))) - "") :background header-bg) - (with-face "\n" :background header-bg) - (with-face user-login-name :foreground "blue") - "@" - (with-face "localhost" :foreground "blue") - (if (= (user-uid) 0) - (with-face " #" :foreground "red") - " $") - " "))) - -(setq eshell-prompt-function 'shk-eshell-prompt) -(setq eshell-highlight-prompt nil) - -;; I use my own virtual loggin target /dev/log, just redirect -;; command output to /dev/log and it will be saved to -;; the *LOG* buffer. > inserts, >> appends -;; N.B: /dev/kill puts the stuff into the kill-ring. -(defun log-comment () - (with-current-buffer (get-buffer-create "*LOG*") - (insert (format "# %s\n" (time-stamp-string))))) - -(defun log-insert (string) - (with-current-buffer (get-buffer-create "*LOG*") - (delete-region (point-min) (point-max)) - (log-comment) - (insert string) - (message "wrote output to *LOG* buffer"))) - -(defun log-append (string) - (with-current-buffer (get-buffer-create "*LOG*") - (end-of-buffer) - (newline) - (log-comment) - (insert string) - (message "wrote output to *LOG* buffer"))) - -;; must return a defun which gets the stuff as ARG1 -;; 'mode is 'overwrite or 'append -(add-to-list 'eshell-virtual-targets '("/dev/log" (lambda (mode) - (if (eq mode 'overwrite) - 'log-insert - 'log-append)) - t - )) - -;; eshell config -(eval-after-load "eshell" - '(progn - (add-hook 'eshell-mode-hook - (lambda () - (local-unset-key (kbd "C-c C-r")) ; we're already using this for windresize - (add-to-list 'eshell-visual-commands "tail") - (add-to-list 'eshell-visual-commands "top") - (add-to-list 'eshell-visual-commands "vi") - (add-to-list 'eshell-visual-commands "ssh") - (add-to-list 'eshell-visual-commands "tail") - (add-to-list 'eshell-visual-commands "mutt") - (add-to-list 'eshell-visual-commands "note") - (setenv "TERM" "xterm") - (local-set-key (kbd "C-l") 'eshell/clear) - (define-key viking-mode-map (kbd "C-d") nil) ;; need to undef C-d first - (local-set-key (kbd "C-d") 'eshell/x) - (setq mode-name "ESH" - eshell-hist-ignoredups t - eshell-history-size 5000 - eshell-where-to-jump 'begin - eshell-review-quick-commands nil - eshell-smart-space-goes-to-end t - eshell-scroll-to-bottom-on-input 'all - eshell-error-if-no-glob t - eshell-save-history-on-exit t - eshell-prefer-lisp-functions t))))) - -;; exit and restore viking key binding afterwards -(defun eshell/x (&rest args) - (interactive) - (eshell-life-is-too-much) - (define-key viking-mode-map (kbd "C-d") 'viking-kill-thing-at-point)) - -;; open files in emacs, split the shell if not already splitted -;; open empty window if no file argument given. -(defun eshell/emacs (&rest args) - "Editor commands fired from eshell will be handled by emacs, which already runs anyway." - (interactive) - (let* ((framesize (frame-width)) - (winsize (window-body-width))) - (progn - (if (eq winsize framesize) - (split-window-horizontally)) - (other-window 1) - (if (null args) - (bury-buffer) - (mapc #'find-file (mapcar #'expand-file-name (eshell-flatten-list (reverse args)))))))) - -(defun eshell/clear () - "Better clear command than (recenter 0) which doesn't work as I -want. This version really removes the output of previous commands -and puts the shell to the beginning of a really (then) empty eshell -buffer. However, just to be sure that I do no accidentally clear -some shell output that might be useful in the future, it also -copies the cleared stuff into a backup buffer named -*eshell-log-buffer*, just in case." - (interactive) - (let ((beg (point-min)) - (end (point-max)) - (savebuffer "*eshell-log-buffer*") - (log (buffer-substring-no-properties (point-min) (point-max)))) - (progn - (if (not (get-buffer savebuffer)) - (get-buffer-create savebuffer)) - (with-current-buffer savebuffer - (goto-char (point-max)) - (insert log)) - (delete-region beg end) - (eshell-emit-prompt)))) - -(defun eshell/perldoc (&rest args) - "Like `eshell/man', but invoke `perldoc'." - (funcall 'eshell/perldoc (apply 'eshell-flatten-and-stringify args))) - -(defun eshell/perldoc (man-args) - (interactive "sPerldoc: ") - (require 'man) - (let ((manual-program "perldoc")) - (man man-args))) - -(defun eshell-here () - "Opens up a new shell in the directory associated with the -current buffer's file. The eshell is renamed to match that -directory to make multiple eshell windows easier." - (interactive) - (let* ((parent (if (buffer-file-name) - (file-name-directory (buffer-file-name)) - default-directory)) - (height (/ (window-total-height) 3)) - (name (car (last (split-string parent "/" t))))) - (split-window-vertically (- height)) - (other-window 1) - (eshell "new") - (rename-buffer (concat "*eshell: " name "*")) - (insert (concat "ls")) - (eshell-send-input))) - -;; via howardism -(defun eshell-there (host) - "Opens a shell on a remote host using tramp." - (interactive "sHost: ") - (let ((default-directory (format "/%s:" host))) - (eshell host))) - -(defalias 'es 'eshell-here) -(defalias 'et 'eshell-there) -(defalias 'eshell/vi 'eshell/emacs) - -;; plan9 smart command, edit while exec if not silent or successful -(require 'em-smart) - -;; eshell shell aliases. I set the global -;; defvar here so there's no need to transport -;; ~/.emacs.d/eshell/aliases across networks -(setq eshell-command-aliases-list ()) - -(defun +alias (al cmd) - "handy wrapper function to convert alias symbols -to alias strings to avoid writing 4 quotes per alias. -AL is a single-word symbol naming the alias, CMD is -a list symbol describing the command." - (add-to-list 'eshell-command-aliases-list - (list (symbol-name al) - (mapconcat 'symbol-name cmd " ")))) - -;; actual aliases -(+alias 'l '(ls -laF $*)) -(+alias 'll '(ls -l $*)) -(+alias 'la '(ls -a $*)) -(+alias 'lt '(ls -ltr $*)) -(+alias '.. '(cd ..)) -(+alias '... '(cd ../..)) -(+alias '.... '(cd ../../..)) -(+alias '..... '(cd ../../../..)) -(+alias 'md '(mkdir -p $*)) -(+alias 'emacs '(find-file $1)) -(+alias 'less '(find-file-read-only $1)) -(+alias 'x '(eshell/exit)) - -;; no need for less or more, this is emacs, isn't it? -(setenv "PAGER" "cat") - -;; -------------------------------------------------------------------------------- - -;; *** Emacs LISP interactive - -;; General configuration for all things elisp. - -;; By using C-x-e I can push region or buffer -;; of lisp code (i.e. inside *scratch*) into -;; REPL where it will be evaluated - -(defun tvd-get-code() - "helper: returns marked region or the whole buffer contents" - ;; FIXME: mv to string helpers? - (if mark-active - (let ( ;; save region and buffer - (partb (buffer-substring-no-properties (region-beginning) (region-end))) - (whole (buffer-substring-no-properties (point-min) (point-max))) - ) - (if (> (length partb) 0) - partb - whole - ) - ) - ;; no mark, also return everything - (buffer-substring-no-properties (point-min) (point-max)))) - -(defun tvd-send-region-to-repl () - "put region or buffer into elisp repl and eval" - (interactive) - (let ( ;; fetch region or buffer contents - (code (tvd-get-code))) - (progn - (if (not (get-buffer "*ielm*")) - ;; ielm not yet running, start it in split window but stay here - (progn - (split-window-horizontally) - (other-window 1) - (ielm) - (other-window 1))) - ;; finially, paste content into ielm and evaluate it - ;; still we stay where we are - (with-current-buffer "*ielm*" - (goto-char (point-max)) - (insert code) - (ielm-return))))) - -(defun tvd-elisp-eval() - "just eval region or buffer whatever feasible" - (interactive) - (progn - (if mark-active - (eval-region) - (eval-buffer)))) - -(defun ff () - "Jump to function definition at point." - (interactive) - (find-function-other-window (symbol-at-point))) - -(defun tvd-make-defun-links () - "experimental: make function calls clickable, on click, jump to definition of it" - (interactive) - (let ((beg 0) - (end 0) - (fun nil)) - (goto-char (point-min)) - (while (re-search-forward "(tvd[-a-z0-9]*" nil t) - (setq end (point)) - (re-search-backward "(" nil t) - (forward-char 1) - (setq beg (point)) - (setq fun (buffer-substring-no-properties beg end)) - (make-button beg end 'action - (lambda (x) - (find-function-other-window (symbol-at-point)))) - (goto-char end)))) - -(defun emacs-change-version (v) - "Change version of .emacs (must be the current buffer). -Returns t if version changed, nil otherwise." - (interactive - (list - (completing-read "New config version (press TAB for old): " - (list tvd-emacs-version)))) - (if (equal v tvd-emacs-version) - nil - (save-excursion - (show-all) - (beginning-of-buffer) - (tvd-replace-all (format "\"%s\"" tvd-emacs-version) - (format "\"%s\"" v)) - (setq tvd-emacs-version v) - (message (format "New config version set: %s" v)) - t))) - -(defun emacs-change-log (entry) - "Add a changelog entry to .emacs Changelog" - (interactive "Menter change log entry: ") - (let ((newversion (call-interactively 'emacs-change-version))) - (save-excursion - (show-all) - (beginning-of-buffer) - (re-search-forward ";; .. Changelog") - (next-line) - (tvd-outshine-end-of-section) - (when newversion - (insert (format "\n;; %s\n" tvd-emacs-version))) - (insert (format ";; - %s\n" entry))))) - -;; elisp config -(add-hook 'emacs-lisp-mode-hook - (lambda() - ;; non-separated x-e == eval hidden, aka current buffer - (local-set-key (kbd "C-x C-e") 'tvd-elisp-eval) - ;; separate 'e' == separate buffer - (local-set-key (kbd "C-x e") 'tvd-send-region-to-repl) - (setq mode-name "EL" - show-trailing-whitespace t) - (eldoc-mode t) - - ;; enable outline (with outshine) - (outline-minor-mode) - - ;; enable outshine mode - (outshine-hook-function) - - (electric-indent-mode t))) - -;; use UP arrow for history in *ielm* as well, just as C-up -(add-hook 'comint-mode-hook - (lambda() - (define-key comint-mode-map [up] 'comint-previous-input))) - -;; sometimes I use lisp in minibuffer -(defun ee() - (interactive) - (electric-pair-mode) - (call-interactively 'eval-expression) - (electric-pair-mode)) - -;; sometimes I eval regions -(defalias 'er 'eval-region) - -;; ... or defuns -(defalias 'ef 'eval-defun) - -;; I like to have some functions fontified differently -(font-lock-add-keywords - 'emacs-lisp-mode - '(("(\\s-*\\(eq\\|if\\|cond\\|and\\|set\\|or\\|not\\|when\\|setq\\|let**\\|lambda\\|kbd\\|defun\\|car\\|cdr\\)\\s-+" - 1 'font-lock-keyword-face))) - -;; same applies for quoted symbols -(font-lock-add-keywords - 'emacs-lisp-mode - '(("'[-a-zA-Z_][-a-zA-Z0-9_]*\\>" 0 'font-lock-constant-face))) - -;; I hate it when help, debug, ielm and other peripheral buffers -;; litter my emacs window setup. So, this function fixes this: it -;; opens a new frame with all those buffers already opened and pinned. - -(defun dev () - "Open a new emacs frame with some development peripheral buffers." - (interactive) - (let ((F (new-frame))) - (with-selected-frame F - (with-current-buffer (get-buffer-create "*Help*") - (help-mode)) - (with-current-buffer (get-buffer-create "*ielm*") - (ielm)) - (with-current-buffer (get-buffer-create "*suggest*") - (suggest)) - (switch-to-buffer "*ielm*") - (split-window-horizontally) - (split-window-vertically) - (windmove-down) - (switch-to-buffer "*suggest*") - (tvd-suggest-reload) - (tvd-suggest-reload) - (windmove-right) - (switch-to-buffer "*Help*") - (split-window-vertically) - (windmove-down) - (switch-to-buffer "*scratch*") - (set-window-dedicated-p (selected-window) t) - (set-background-color "azure")))) - - -;; -------------------------------------------------------------------------------- -;; *** el2markdown - -;; [[https://github.com/Lindydancer/el2markdown][el2markdown]] is a module which -;; can be used to convert Commentary sections into markdown files. I use this to -;; avoid maintaining the README.md and the Commentary section in parallel. - -(require 'el2markdown) - -;; To use, call el2markdown-view-buffer and put it into the -;; README.md. Take care though: it doesn't convert the META section. - -;; FIXME: write a wrapper to circumvent these restrictions. - -;; *** tramp mode - -;; Edit remote files, one of the best things in emacs. I use it every day heavily. - -;; Sample: C-x-f /$host:/$file ($host as of .ssh/config or direct, $file including completion) - -;; doku: [[http://www.gnu.org/software/tramp/][gnu.org]] -(setq tramp-default-method "ssh" - tramp-default-user nil - tramp-verbose 1 - ido-enable-tramp-completion t) - -;; see also backup section - -;; -------------------------------------------------------------------------------- - -;; *** org mode - -;; I use org mode to take notes mostly at work. I also track projects -;; and TODO lists etc. I do not, however, use agenda or any -;; scheduling whatsoever. - -(require 'org) - -;; I like custom bullets -(require 'org-bullets) - -;; enable syntax highlighting for embedded source blocks -(require 'ob-python) -(require 'ob-perl) -(require 'ob-shell) - -(setq org-bullets-bullet-list '("►" "✜" "✸" "✿" "♦")) - -;; capture target, os-dependend -(if (null tvd-win-home) - (setq tvd-org-file (concat tvd-lisp-dir "/notizen.org") - org-attach-directory (concat tvd-lisp-dir "/attachments")) - (setq tvd-org-file (concat tvd-win-home "/notizen.org") - org-attach-directory (concat tvd-win-home "/attachments"))) - -;; text formatting made easy, bound to C-c keys locally -(defun tvd-org-emphasize(CHAR) - "expand once if no region and apply emphasize CHAR" - (interactive) - (unless (region-active-p) - (er/expand-region 1)) - (org-emphasize CHAR)) - -(defun bold() - "bold text in org mode" - (interactive) - (tvd-org-emphasize '42)) - -(defun italic() - "italic text in org mode" - (interactive) - (tvd-org-emphasize '47)) - -(defun code() - "verbatim text in org mode" - (interactive) - (tvd-org-emphasize '126)) - -(defun underline() - "underline text in org mode" - (interactive) - (tvd-org-emphasize '95)) - -;; my org-mode specific and -(defun tvd-org-left-or-level-up() - "jump one word to the left if not on a org heading, -otherwise fold current level and jump one level up." - (interactive) - (if (and (org-at-heading-p) (looking-at "*")) - (progn - (hide-subtree) - (outline-up-heading 1)) - (left-word))) - -(defun tvd-org-heading-up() - "If on a heading, fold current heading, jump one level -up and unfold it, otherwise jump paragraph as usual." - (interactive) - (if (and (org-at-heading-p) (looking-at "*")) - (progn - (hide-subtree) - (org-backward-heading-same-level 1) - (org-cycle)) - (backward-paragraph))) - -(defun tvd-org-heading-down() - "If on a heading, fold current heading, jump one level -down and unfold it, otherwise jump paragraph as usual." - (interactive) - (if (and (org-at-heading-p) (looking-at "*")) - (progn - (hide-subtree) - (org-forward-heading-same-level 1) - (org-cycle)) - (forward-paragraph))) - -;; org-mode specific config, after load -(eval-after-load "org" - '(progn - (add-hook 'org-mode-hook - (lambda () - (setq - org-M-RET-may-split-line nil - org-agenda-files (list tvd-org-file) - org-agenda-restore-windows-after-quit t - org-blank-before-new-entry (quote ((heading . auto) (plain-list-item . auto))) - org-catch-invisible-edits (quote error) - org-columns-default-format "%80ITEM %22Timestamp %TODO %TAGS %0PRIORITY" - org-insert-heading-always-after-current (quote t) - org-mouse-1-follows-link nil - org-remember-store-without-prompt t - org-reverse-note-order t - org-startup-indented t - org-startup-truncated nil - org-return-follows-link t - org-use-speed-commands t - org-yank-adjusted-subtrees t - org-refile-targets '((nil . (:maxlevel . 5))) - org-refile-use-outline-path t - org-outline-path-complete-in-steps nil - org-completion-use-ido t - org-support-shift-select t - org-hide-emphasis-markers t - org-fontify-done-headline t - org-pretty-entities t - org-use-sub-superscripts nil - org-confirm-babel-evaluate nil) - ; shortcuts - (setq org-speed-commands-user - (quote ( - ("0" . ignore) - ("1" . delete-other-windows) - ("2" . ignore) - ("3" . ignore) - ("d" . org-archive-subtree-default-with-confirmation) ; delete, keep track - ("v" . org-narrow-to-subtree) ; only show current heading ("view") - ("q" . widen) ; close current heading and show all ("quit") - (":" . org-set-tags-command) ; add/edit tags - ("t" . org-todo) ; toggle todo type, same as C-t - ("z" . org-refile) ; archive the (sub-)tree - ("a" . org-attach) ; manage attachments - ))) - ; same as toggle - (local-set-key (kbd "C-t") 'org-todo) - - ; alt-enter = insert new subheading below current - (local-set-key (kbd "") 'org-insert-subheading) - - ; search for tags (ends up in agenda view) - (local-set-key (kbd "C-f") 'org-tags-view) - - ; run presenter, org-present must be installed and loadedwhite - (local-set-key (kbd "C-p") 'org-present) - - ; todo colors - (setq org-todo-keyword-faces '( - ("TODO" . (:foreground "#b70101" :weight bold)) - ("START" . (:foreground "blue" :weight bold)) - ("WAIT" . (:foreground "darkorange" :weight bold)) - ("DONE" . (:foreground "forestgreen" :weight bold)) - ("CANCEL" . (:foreground "red" :weight bold)) - )) - - (local-set-key (kbd "C-c b") 'bold) - (local-set-key (kbd "C-c /") 'italic) - (local-set-key (kbd "C-c 0") 'code) ; aka = without shift - (local-set-key (kbd "C-c _") 'underline) - - ; edit babel src block in extra buffer: - ; default is C-c ' which is hard to type - ; brings me to src code editor buffer - ; Also note: enter ") 'tvd-org-heading-up) - (local-set-key (kbd "") 'tvd-org-heading-down) - - ; move word left or heading up, depending where point is - (local-set-key (kbd "") 'tvd-org-left-or-level-up) - - ; use nicer bullets - (org-bullets-mode 1) - - (org-babel-do-load-languages 'org-babel-load-languages - '((python . t) - (emacs-lisp . t) - (shell . t) - (perl . t))))))) - -;; no more ... at the end of a heading -(setq org-ellipsis " ⤵") - -;; my own keywords, must be set globally, not catched correctly inside hook -(setq org-todo-keywords - '((sequence "TODO" "START" "WAIT" "|" "DONE" "CANCEL"))) - -;; I always want to be able to capture, even if no ORG is running -(global-set-key (kbd "C-n") (lambda () (interactive) (org-capture))) - -;; must be global since code edit sub buffers run their own major mode, not org -(global-set-key (kbd "C-c C-#") 'org-edit-src-exit) - -;; some org mode vars must be set globally -(setq org-default-notes-file tvd-org-file - org-startup-indented t - org-indent-indentation-per-level 4) - -;; my own capture templates -(setq org-capture-templates - '(("n" "Project" entry (file+headline tvd-org-file "Unsorted Tasks") - "* TODO %^{title}\n%u\n** Kostenstelle\n** Contact Peer\n** Contact Customer\n** Aufträge\n** Daten\n** Notizen\n %i%?\n" - :prepend t :jump-to-captured t) - - ("t" "Todo Item" entry (file+headline tvd-org-file "Manual-Agenda-Tasks") - "* TODO %^{title}\n:LOGBOOK:\n%u:END:\n" :prepend t :immediate-finish t) - - ("s" "Scheduled Item" entry (file+headline tvd-org-file "Scheduled-Agenda-Tasks") - "* TODO %^t %^{title}\n:LOGBOOK:\n%u:END:\n" :prepend t :immediate-finish t) - - ("j" "Journal" entry (file+headline tvd-org-file "Kurznotizen") - "* TODO %^{title}\n%u\n %i%?\n" :prepend t :jump-to-captured t) - - ("c" "Copy/Paste" entry (file+headline tvd-org-file "Kurznotizen") - "* TODO %^{title}\n%u\n %x\n" :immediate-finish t :prepend t :jump-to-captured t))) - -;; follow links using eww, if present -(if (fboundp 'eww-browse-url) - (setq browse-url-browser-function 'eww-browse-url)) - -;; mark narrowing with an orange fringe, the advice for 'widen -;; is in the outline section. -(advice-add 'org-narrow-to-subtree :after - '(lambda (&rest args) - (set-face-attribute 'fringe nil :background tvd-fringe-narrow-bg))) - -;; always use the latest docs -(with-eval-after-load 'info - (info-initialize) - (add-to-list 'Info-directory-list - (expand-file-name "~/.emacs.d/lisp/org/doc"))) -;; -------------------------------------------------------------------------------- -;; *** org agenda mode - -;; I use org mode for along time now, primarily at work, but did not -;; use agenda. Instead I developed the habit of maintaining one org -;; entry which contains just a list with all things to do today. I -;; just edited this list manually and it worked. However, recently I -;; found out that agenda provides lots of features and commands -;; precisely for what I already did manually. So, now, finally (as of -;; november 2018) I switch to using the agenda. - -;; My agenda use is very simple though: I don't use any scheduling, no -;; priorities, no recurring events, no daily or other time based -;; views. I just keep a list of TODO entries and another of entries in -;; WAIT state, that's it. All those entries are located under a -;; special org entry with the title "Heute" and the category (as -;; property) WORK, which I use for filtering out agenda items. - -;; The general workflow is as follows: I execute (agenda) which starts -;; directly my custom agenda view. It lists open TODO items and -;; waiting WAIT items below. If I press `n', I will be asked for a -;; title and a new TODO item appears in my agenda. I can press `d' to -;; mark it as DONE, it will also be archived into a subsibling below -;; "HEUTE". I can press `w' to move an item into WAIT state and I can -;; press `a' to add text to the org entry under point (like "waiting -;; for customer email"). - -;; So, I don't use my regular org entries, which are in most cases -;; very large containing lots of information, as agenda items, but -;; only very short ones which act as reminders about what work I have -;; to do. However, since I have the org buffer always opened and -;; visible in a split buffer next to the agenda, it is no problem to -;; go to such a deep entry for editing or viewing. - -(require 'org-agenda) - -;; This is my one and only agenda custom view, it displays TODO items -;; below entries categorized as WORK and WAIT items under the same -;; category. The cool thing here is, that the `tags' agenda view can -;; be used to filter for properties as well. In order to have this -;; working the following property drawer must exist in an entry with -;; TODO siblings: -;; -;; * START Arbeit -;; :PROPERTIES: -;; :CATEGORY: WORK -;; :END: -;; ** TODO a thing to do -;; ** WAIT a thing waiting for something -;; -(setq org-agenda-custom-commands - '(("o" "Daily TODO Tasks" - ( - ;; a block containing only items scheduled for today, if any - (agenda "" - ((org-agenda-span 1) - (org-agenda-overriding-header "Tasks scheduled:"))) - ;; manually created todo items due (state TODO) - (tags "CATEGORY=\"WORK\"" - ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo '("CANCEL" "START" "DONE" "WAIT"))) - (org-agenda-overriding-header "\nTasks to do today:") - (org-agenda-follow-mode t) - (org-agenda-entry-text-mode t))) - ;; manually created todo items in wait state - (tags "CATEGORY=\"WORK\"" - ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo '("CANCEL" "START" "DONE" "TODO"))) - (org-agenda-overriding-header "\nTasks Waiting:")))) - ((org-agenda-compact-blocks t))))) - -;; A shortcut to reach my custom view directly -(defun agenda () - "Visit my org agenda directly, splits left" - (interactive) - (org-agenda nil "o") - (tvd-flip-windows) - (other-window-or-switch-buffer)) - -;; Add a line of text to the top of an existing TODO entry and refresh -;; the agenda -(defun tvd-org-agenda-edit-entry (note) - "Insert a note as plain text into an entry" - (interactive "sEnter note: ") - (save-excursion - (org-agenda-switch-to) - (end-of-line) - (newline) - (insert note)) - (switch-to-buffer "*Org Agenda*") - (org-agenda-redo t)) - -;; Mark an entry as DONE, archive it to an archive sibling and refresh -;; the agenda -(defun tvd-org-agenda-done() - (interactive) - (org-agenda-todo 'done) - (org-agenda-archive-to-archive-sibling) - (org-agenda-redo t)) - -;; Mark an entry as WAIT, archive it to an archive sibling and refresh -;; the agenda -(defun tvd-org-agenda-wait() - (interactive) - (org-agenda-todo "WAIT") - (org-agenda-redo t)) - -;; A wrapper which executes an org capture directly. `t' is the -;; shortcut for the capture, defined above in org mode. -(defun tvd-org-agenda-capture (task) - "Capture a task in agenda mode, using the date at point" - (interactive) - (let ((org-overriding-default-time (org-get-cursor-date))) - (org-capture nil task) - (org-agenda-redo t))) - -(defun tvd-org-agenda-capture-todo () - "Capture a todo task in agenda mode" - (interactive) - (tvd-org-agenda-capture "t")) - -(defun tvd-org-agenda-capture-scheduled () - "Capture a scheduled task in agenda mode" - (interactive) - (tvd-org-agenda-capture "s")) - - - - - -;; Sometimes it is nice to see the agenda alone, so I press -;; `o'. However, since follow mode is enabled, once I move point, the -;; org buffer re-appears. -(defun tvd-org-agenda-solitair () - (interactive) - (delete-other-windows) - (setq org-agenda-follow-mode nil) - (message "Org Agenda Follow Mode Disabled")) - -;; The original function scrolls the buffer every time when it runs a -;; little bit up, which is annoying, to say the least -(defun tvd-org-agenda-redo() - (interactive) - (org-agenda-redo t) - (beginning-of-buffer)) - -;; Since I learned to love hydra, I have one for my agenda as well, of course: -(defhydra hydra-org-agenda (:color blue - :pre (setq which-key-inhibit t) - :post (setq which-key-inhibit nil) - :hint none) - " -Org Agenda (_q_uit) - -^Tasks^ ^Options^ ^Movement^ --^^^^^^------------------------------------------------------------------------------------- -_n_: create new todo task _f_: follow =?f? ENTER: switch to entry -_N_: create new scheduled task _e_: entry =?e? C-: go one entry up -_d_: mark task done and archive _o_: one window C-: go one entry down -_w_: mark task waiting ^^ M-: move entry up -_t_: toggle todo state ^^ M-: move entry down -_z_: archive task ^ ^ -_+_: increase prio -_-_: decrease prio ^Marking^ -_g_: refresh _m_: mark entry -_s_: save org buffer(s) _u_: un-mark entry -_a_: add a note to the entry _U_: un-mark all -_k_: delete a task w/o archiving _B_: bulk action - -" - ("a" tvd-org-agenda-edit-entry nil) - ("n" tvd-org-agenda-capture-todo nil) - ("N" tvd-org-agenda-capture-scheduled nil) - ("o" tvd-org-agenda-solitair nil) - ("g" tvd-org-agenda-redo) - ("t" org-agenda-todo) - ("d" tvd-org-agenda-done nil) - ("w" tvd-org-agenda-wait nil) - ("z" org-agenda-archive-to-archive-sibling nil) - ("+" org-agenda-priority-up nil) - ("-" org-agenda-priority-down nil) - ("s" org-save-all-org-buffers nil) - ("f" org-agenda-follow-mode - (format "% -3S" org-agenda-follow-mode)) - ("e" org-agenda-entry-text-mode - (format "% -3S" org-agenda-entry-text-mode)) - ("m" org-agenda-bulk-mark nil) - ("u" org-agenda-bulk-unmark nil) - ("U" org-agenda-bulk-remove-all-marks nil) - ("B" org-agenda-bulk-action nil) - ("k" org-agenda-kill nil) - ("q" nil nil :color red)) - -;; Configuration and key bindings for org agenda (same as in the hydra) -(add-hook 'org-agenda-mode-hook '(lambda () (progn - (setq org-agenda-follow-mode t - org-log-into-drawer t - org-agenda-entry-text-mode t - org-agenda-sorting-strategy '(priority-down timestamp-down)) - (local-set-key (kbd "n") 'tvd-org-agenda-capture-todo) - (local-set-key (kbd "N") 'tvd-org-agenda-capture-scheduled) - (local-set-key (kbd "o") 'tvd-org-agenda-solitair) - (local-set-key (kbd "a") 'tvd-org-agenda-edit-entry) - (local-set-key (kbd "d") 'tvd-org-agenda-done) - (local-set-key (kbd "w") 'tvd-org-agenda-wait) - (local-set-key (kbd "g") 'tvd-org-agenda-redo) - (local-set-key (kbd "f") 'org-agenda-follow-mode) - (local-set-key (kbd "e") 'org-agenda-entry-text-mode) - (local-set-key (kbd "k") 'org-agenda-kill) - (local-set-key (kbd "z") 'org-agenda-archive-to-archive-sibling) - (local-set-key (kbd "C-") 'org-agenda-previous-item) - (local-set-key (kbd "C-") 'org-agenda-next-item) - (local-set-key (kbd "?") 'hydra-org-agenda/body)))) -;; -------------------------------------------------------------------------------- -;; *** org table mode - -;; I'm so used to lovely org mode tables, I need them everywhere! -(require 'org-table) - - - -;; convert CSV region to table -(defun tablify (regex) - "Convert a whitespace separated column list into -an org mode table and enable orgtbl-mode. You can -specify another regex for cell splitting." - (interactive "MConvert [region] to table with regex ([\t\s]+): ") - (let ((spc "[\t\s]+")) - (when (string= regex "") - (setq regex spc)) - (delete-trailing-whitespace) - (if (org-region-active-p) - (org-table-convert-region (region-beginning) (region-end) regex) - (org-table-convert-region (point-min) (point-max) regex)) - (when (not (eq major-mode 'org-mode)) - (orgtbl-mode)))) - -;; table sorting shortcuts -(defun sort-table-numeric () - "sort org table numerically by current column" - (interactive) - (org-table-sort-lines nil ?n)) - -(defun sort-table-numeric-desc () - "reverse sort org table numerically by current column" - (interactive) - (org-table-sort-lines nil ?N)) - -(defun sort-table-alphanumeric () - "sort org table charwise by current column" - (interactive) - (org-table-sort-lines nil ?a)) - -(defun sort-table-alphanumeric-desc () - "reverse sort org table charwise by current column" - (interactive) - (org-table-sort-lines nil ?A)) - -(defun sort-table-time () - "sort org table by times by current column" - (interactive) - (org-table-sort-lines nil ?t)) - -(defun sort-table-time-desc () - "reverse sort org table by times by current column" - (interactive) - (org-table-sort-lines nil ?T)) - -;; [[http://irreal.org/blog/?p=3542][via jcs/irreal.org]] -;; however, I renamed the actual sort wrappers to match my -;; naming scheme -(defun jcs-ip-lessp (ip1 ip2 &optional op) - "Compare two IP addresses. -Unless the optional argument OP is provided, this function will return T -if IP1 is less than IP2 or NIL otherwise. The optional argument OP is -intended to be #'> to support reverse sorting." - (setq cmp (or op #'<)) - (cl-labels ((compare (l1 l2) - (if (or (null l1) (null l2)) - nil - (let ((n1 (string-to-number (car l1))) - (n2 (string-to-number (car l2)))) - (cond - ((funcall cmp n1 n2) t) - ((= n1 n2) (compare (cdr l1) (cdr l2))) - (t nil)))))) - (compare (split-string ip1 "\\.") (split-string ip2 "\\.")))) - -(defun sort-table-ip () - (interactive) - (org-table-sort-lines nil ?f #'org-sort-remove-invisible #'jcs-ip-lessp)) - -(defun sort-table-ip-desc () - (interactive) - (org-table-sort-lines nil ?F #'org-sort-remove-invisible - (lambda (ip1 ip2) (jcs-ip-lessp ip1 ip2 #'>)))) - - -;; easy access for the shortcuts -(defalias 'stn 'sort-table-numeric) -(defalias 'stnd 'sort-table-numeric-desc) -(defalias 'sta 'sort-table-alphanumeric) -(defalias 'stad 'sort-table-alphanumeric-desc) -(defalias 'stt 'sort-table-time) -(defalias 'sttd 'sort-table-time-desc) -(defalias 'sti 'sort-table-ip) -(defalias 'stid 'sort-table-ip-desc) - -;; generic table exporter -(defun tvd-export-org-table (fmt) - "export an org table using format FMT" - (interactive) - (let ((efile "/tmp/org-table-export.tmp") - (ebuf (format "*table-%s*" fmt))) - (when (file-exists-p efile) - (delete-file efile)) - (org-table-export efile (format "orgtbl-to-%s" fmt)) - (other-window 1) - (if (not (eq (get-buffer ebuf) nil)) - (kill-buffer (get-buffer ebuf))) - (set-buffer (get-buffer-create ebuf)) - (insert-file-contents efile) - (switch-to-buffer ebuf) - (delete-file efile))) - -;; FIXME: once there's an org solution to this, remove this code -;; format specific exporters -(defun tvd-org-quote-csv-field (s) - "Quote every field." - (if (string-match "." s) - (concat "=\"" (mapconcat 'identity - (split-string s "\"") "\"\"") "\"") - s)) - -(defun table-to-excel () - "export current org table to CSV format suitable for MS Excel." - (interactive) - ;; quote everything, map temporarily 'org-quote-csv-field - ;; to my version - (cl-letf (((symbol-function 'org-quote-csv-field) - #'tvd-org-quote-csv-field)) - (tvd-export-org-table "csv"))) - -(defun table-to-csv () - "export current org table to CSV format" - (interactive) - (tvd-export-org-table "csv")) - -(defun table-to-latex () - "export current org table to LaTeX format" - (interactive) - (tvd-export-org-table "latex")) - -(defun table-to-html () - "export current org table to HTML format" - (interactive) - (tvd-export-org-table "html")) - -(defun table-to-csv-tab () - "export current org table to CSV format, separated by " - (interactive) - (tvd-export-org-table "tsv")) - -(defun table-to-aligned () - "export current org table to space-aligned columns format" - (interactive) - (tvd-export-org-table "csv") - (with-current-buffer "*table-csv*" - (align-regexp (point-min) (point-max) "\\(\\s-*\\)," 1 1 t) - (while (re-search-forward " ," nil t) - (replace-match " ")))) - -;; exporter shortcuts -(defalias 'ttc 'table-to-csv) -(defalias 'tte 'table-to-excel) -(defalias 'ttl 'table-to-latex) -(defalias 'tth 'table-to-html) -(defalias 'ttt 'table-to-csv-tab) -(defalias 'tta 'table-to-aligned) - -;; In org mode I sometimes want to copy the content of a table cell -(defun tvd-beginning-of-cell (&optional arg) - "move (point) to the beginning of a org mode table cell" - (interactive) - (if (re-search-backward "|" (line-beginning-position) 3 1) - (forward-char))) - -(defun tvd-end-of-cell (&optional arg) - "move (point) to the end of a org mode table cell" - (interactive) - (if (re-search-forward "|" (line-end-position) 3 1) - (backward-char))) - -(defun tvd-copy-org-table-cell(&optional arg) - "Copy an org mode table cell to the kill ring using MCYT" - (interactive "P") - (mcyt--blink-and-copy-thing 'tvd-beginning-of-cell 'tvd-end-of-cell arg)) - -(defun tvd-del-org-table-cell (&optional arg) - "Delete a cell" - (interactive "P") - (let - ((beg (progn (tvd-beginning-of-cell) (point))) - (end (progn (tvd-end-of-cell) (point)))) - (delete-region beg end) - (org-table-align))) - -(defun tvd-del-org-table-row () - "Delete a table row's contents" - (interactive) - (org-beginning-of-line 1) - (kill-line) - (org-table-insert-row nil)) - -(defun tvd-del-org-table-col () - "Delete a table column's contents, keep heading as is" - (interactive) - (let ((head (org-table-get 1 nil))) - (org-table-delete-column) - (re-search-forward "|") - (org-table-insert-column) - (tvd-org-table-goto-col-beginning) - (insert head) - (org-table-align)) - ) - -;; Sometimes I need to copy whole columns too: -;; via [[https://emacs.stackexchange.com/questions/28270/how-to-select-and-copy-a-column-of-an-org-table-without-rectangle-selection][stackoverflow]] - -(defun tvd-org-table-goto-col-beginning () - "Go to beginning of current column and return `point'." - (interactive) - (assert (org-table-p) "Not in org-table.") - (org-table-align) - (let ((col (org-table-current-column))) - (goto-char (org-table-begin)) - (org-table-goto-column col)) - (point)) - -(defun tvd-org-table-col-beginning () - "Return beginning position of current column." - (save-excursion - (tvd-org-table-goto-col-beginning))) - -(defun tvd-org-table-goto-col-end () - "Goto end of current column and return `point'." - (interactive) - (assert (org-table-p) "Not in org-table.") - (org-table-align) - (let ((col (org-table-current-column))) - (goto-char (1- (org-table-end))) - (org-table-goto-column col) - (skip-chars-forward "^|")) - (point)) - -(defun tvd-org-table-col-end () - "Return end position of current column." - (save-excursion - (tvd-org-table-goto-col-end))) - -(defun tvd-org-table-select-col () - "Select current column." - (interactive) - (set-mark (tvd-org-table-col-beginning)) - (tvd-org-table-goto-col-end) - (rectangle-mark-mode)) - -(defun tvd-copy-org-table-col () - "Copy current column." - (interactive) - (tvd-org-table-select-col) - (sit-for 0.2 t) - (copy-region-as-kill nil nil t) - (with-temp-buffer - (yank) - (delete-trailing-whitespace) - (delete-whitespace-rectangle (point-min) (point-max)) - (font-lock-unfontify-buffer) - (copy-region-as-kill (point-min) (point-max)))) - -(defun tvd-copy-org-table-row () - "Copy current row, space aligned" - (interactive) - (mcyt-copy-line) - (with-temp-buffer - (yank) - (goto-char (point-min)) - (let ((spc "")) - (while (re-search-forward "|[ ]*" nil t) - (replace-match spc) - (setq spc " "))) - (delete-trailing-whitespace) - (copy-region-as-kill (point-min) (point-max)))) - -;; Move single cells using C-M-up C-M-down C-M-left C-M-right -;; [[https://cs.gmu.edu/~kauffman/software/org-table-move-single-cell.el][via Kauffmann]] -(defun org-table-swap-cells (i1 j1 i2 j2) - "Swap two cells" - (let ((c1 (org-table-get i1 j1)) - (c2 (org-table-get i2 j2))) - (org-table-put i1 j1 c2) - (org-table-put i2 j2 c1) - (org-table-align))) - -(defun org-table-move-single-cell (direction) - "Move the current cell in a cardinal direction according to the - parameter symbol: 'up 'down 'left 'right. Swaps contents of - adjacent cell with current one." - (unless (org-at-table-p) - (error "No table at point")) - (let ((di 0) (dj 0)) - (cond ((equal direction 'up) (setq di -1)) - ((equal direction 'down) (setq di +1)) - ((equal direction 'left) (setq dj -1)) - ((equal direction 'right) (setq dj +1)) - (t (error "Not a valid direction, must be up down left right"))) - (let* ((i1 (org-table-current-line)) - (j1 (org-table-current-column)) - (i2 (+ i1 di)) - (j2 (+ j1 dj))) - (org-table-swap-cells i1 j1 i2 j2) - (org-table-goto-line i2) - (org-table-goto-column j2)))) - -(defun org-table-move-single-cell-up () - "Move a single cell up in a table; swap with anything in target cell" - (interactive) - (org-table-move-single-cell 'up)) - -(defun org-table-move-single-cell-down () - "Move a single cell down in a table; swap with anything in target cell" - (interactive) - (org-table-move-single-cell 'down)) - -(defun org-table-move-single-cell-left () - "Move a single cell left in a table; swap with anything in target cell" - (interactive) - (org-table-move-single-cell 'left)) - -(defun org-table-move-single-cell-right () - "Move a single cell right in a table; swap with anything in target cell" - (interactive) - (org-table-move-single-cell 'right)) - -;; actual org table config -(with-eval-after-load "org" - (add-hook 'org-mode-hook - (lambda () - (local-set-key (kbd "C-c t l") 'tvd-copy-org-table-col) - (local-set-key (kbd "C-c t r") 'tvd-copy-org-table-row) - (local-set-key (kbd "C-c t c") 'tvd-copy-org-table-cell) - (local-set-key (kbd "C-M-") 'org-table-move-single-cell-left) - (local-set-key (kbd "C-M-") 'org-table-move-single-cell-right) - (local-set-key (kbd "C-M-") 'org-table-move-single-cell-up) - (local-set-key (kbd "C-M-") 'org-table-move-single-cell-down)))) - -;; eval-after-load 'orgtbl doesn't work -(add-hook 'orgtbl-mode-hook '(lambda () - (define-key orgtbl-mode-map (kbd "C-c t l") 'tvd-copy-org-table-col) - (define-key orgtbl-mode-map (kbd "C-c t r") 'tvd-copy-org-table-row) - (define-key orgtbl-mode-map (kbd "C-c t c") 'tvd-copy-org-table-cell))) - -;; integers, reals, positives, set via custom -(setq org-table-number-regexp "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.?[0-9]*\\)$") - -;; table hydras, maybe better than aliases?! -(defhydra hydra-org-tables (:color blue) - " -^Sort by^ ^Transform to^ ^Copy/Del what^ ^Modify^ ^Outside Org^ -^^^^^^^^----------------------------------------------------------------------------------------------------------------------- -_sa_: alphanumeric _tc_: CSV _cl_: Copy Column (C-c t l) _ic_: Insert Column _ot_: Table to Org Mode -_sA_: -alphanumeric _te_: Excel _cr_: Copy Row (C-c t r) _ir_: Insert Row _oe_: Enable Org-Tbl Mode -_si_: ip _tl_: Latex _cc_: Copy Cell (C-c t c) _il_: Insert Line _oc_: Turn region to columns -_sI_: -ip _th_: HTML _dd_: Delete Cell _tr_: Transpose Table -_sn_: numeric _tt_: Tab _dc_: Delete Column _mr_: Move Cell right -_sN_: -numeric _ta_: Aligned _dr_: Delete Row _ml_: Move Cell left -_st_: time ^^ _kr_: Kill Row _mu_: Move Cell up -_sT_: -time ^^ _kc_: Kill Column _md_: Move Cell down _q_: Cancel - - -^^^^^^^^----------------------------------------------------------------------------------------------------------------------- -Reach this hydra with -^^^^^^^^----------------------------------------------------------------------------------------------------------------------- - - -" - ("mr" org-table-move-single-cell-right) - ("ml" org-table-move-single-cell-left) - ("mu" org-table-move-single-cell-up) - ("md" org-table-move-single-cell-down) - ("sa" sort-table-alphanumeric nil) - ("sA" sort-table-alphanumeric-desc nil) - ("si" sort-table-ip nil) - ("sI" sort-table-ip-desc nil) - ("sn" sort-table-numeric nil) - ("sN" sort-table-numeric-desc nil) - ("st" sort-table-time nil) - ("sT" sort-table-time-desc nil) - - ("tc" table-to-csv nil) - ("te" table-to-excel nil) - ("tl" table-to-latex nil) - ("th" table-to-html nil) - ("tt" table-to-csv-tab nil) - ("ta" table-to-aligned nil) - - ("cl" tvd-copy-org-table-col nil) - ("cr" tvd-copy-org-table-row nil) - ("cc" tvd-copy-org-table-cell nil) - ("dd" org-table-blank-field nil) - ("dr" tvd-del-org-table-row nil) - ("dc" tvd-del-org-table-col nil) - ("kc" org-table-delete-column nil) - ("kr" org-table-kill-row nil) - - ("ic" org-table-insert-column nil) - ("ir" org-table-insert-row nil) - ("il" org-table-hline-and-move nil) - ("tr" org-table-transpose-table-at-point nil) - - ("ot" tablify nil) - ("oe" orgtbl-mode nil) - ("oc" align-repeat nil) - - ("q" nil nil :color red)) - -;; allow me to insert org tables everywhere on request -(defalias 'table 'hydra-org-tables/body) -(global-set-key (kbd "C-x t") 'hydra-org-tables/body) - -;; *** org mode slideshows - -;; Making presentations within emacs with org mode is cool as well. - -(require 'org-present) -(require 'darkroom) ;; hides distractions - -;; showtime helpers -(defun slide-return-to-present () - "wherever we are, go back to slideshow" - (interactive) - (switch-to-buffer-other-window "*slide*") - (delete-other-windows)) - -(defun slide-split-to-past () - "split slide show and show previous buffer next to it" - (interactive) - (split-window-horizontally) - (other-window 1) - (if (get-buffer "*eshell*") - ;; if there's no eshell running, start it, otherwise switch to it - (switch-to-buffer "*eshell*") - (eshell))) - -;; org present config -(eval-after-load "org-present" - '(progn - (add-hook 'org-present-mode-hook - (lambda () - (org-present-big) - (org-display-inline-images) - (org-present-hide-cursor) - (org-present-read-only) - - ;; some opticals - (setq org-hide-emphasis-markers t) - (font-lock-add-keywords 'org-mode - '(("^ +\\([-*]\\) " - (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•")))))) - ;; keys - (define-key org-present-mode-keymap [down] 'org-present-next) - (define-key org-present-mode-keymap [up] 'org-present-prev) - (define-key org-present-mode-keymap (kbd "q") 'org-present-quit) - (global-set-key (kbd "C-c p") 'slide-return-to-present) ; used inside eshell to return to slide - (define-key org-present-mode-keymap (kbd "s") 'slide-split-to-past) - (setq current-buffer (buffer-name)) ; remember slide buffer name - (rename-buffer "*slide*") - ;;(darkroom-tentative-mode) - )) - - (add-hook 'org-present-mode-quit-hook - (lambda () - (org-present-small) - (org-remove-inline-images) - (org-present-show-cursor) - (org-present-read-write) - (setq org-hide-emphasis-markers nil) - (rename-buffer current-buffer) - (global-unset-key (kbd "C-c p")) - ;;(darkroom-tentative-mode) - )))) - -;; Will be inserted as first help slide in a slide show -;; (edit table in org-mode!) -(defun slide-header (prefix) - (interactive "P") - (save-excursion - (if (eq prefix nil) - () - (goto-char (point-min))) - (insert "\n* ORG-MODE slide show commands - - | Key | Command | - +-------+------------------------------------------------------------+ - | C-p | start slide show | - | q | stop slide show | - | s | slit window and switchto or start eshell | - | C-c p | while in split mode, return to full screen slide show | - | C-c r | enter window resize mode, use cursor keys, to finish | - | C-- | (CTRL and minus) shrink font size | - | C-+ | (CTRL and plus) increase font size | - -"))) - - -;; -------------------------------------------------------------------------------- -;; *** outshine mode - -;; I maintain my emacs config with outshine mode. It works a lot like -;; org mode, but I still have a normal emacs lisp buffer, which I can -;; use directly without any conversion beforehand and which works if -;; outshine is not installed. Also I thing "literal programming" is -;; bullshit. - -(require 'outshine) - -;; Generate an alist of all headings with each position in buffer and -;; use this later to jump to those positions with IDO. -(make-variable-buffer-local 'tvd-headings) - -(defun tvd-outshine-get-level (heading) - "Return level of HEADING as number, or nil" - (if (string-match " \\(*+\\) " heading) ; normal outline heading - (length (match-string 1 heading)) - (when (string-match "^;;\\(;+\\) " heading) ; else look for elisp heading - (length (match-string 1 heading))))) - -(defun tvd-outshine-cl-heading (heading) - (let ((regex (cadar outshine-imenu-preliminary-generic-expression))) - (when (string-match regex heading) - (match-string-no-properties 1 heading)))) - -(defun tvd-outshine-parse-headings () - "extract outshine headings of current buffer" - (interactive) - (let ((line nil)) - (save-excursion - (setq tvd-headings ()) - (beginning-of-buffer) - (while (not (eobp)) - (setq line (tvd-get-line)) - (when (outline-on-heading-p t) - (add-to-list 'tvd-headings (cons (tvd-outshine-cl-heading line) (point)))) - (forward-line))))) - -(defun tvd-outshine-sparse-tree () - "expand outline tree from current position as sparse tree" - (interactive) - (let ((done nil) - (pos (point)) - (tree (list (list (point) 5))) - (l 0)) - (while (not done) - (outline-up-heading 1) - (setq l (tvd-outshine-get-level (tvd-get-line))) - (add-to-list 'tree (list (point) l)) - (when (eq l 1) - (setq done t))) - (outline-hide-other) - (dolist (pos tree) - (goto-char (car pos)) - (outline-cycle)))) - -(defun tvd-outshine-jump () - "jump to an outshine heading with IDO prompt, -update heading list if neccessary." - (interactive) - (let ((heading nil)) - (if (string= "" outshine-normalized-outline-regexp-base) - (call-interactively 'imenu) ;; use imenu outside outshine - (when (or (not tvd-headings) - (buffer-modified-p)) - (tvd-outshine-parse-headings)) - (if (not tvd-headings) - (message "Could not parse headings") - (setq heading (ido-completing-read - "Jump to heading: " - (tvd-alist-keys tvd-headings))) - (when heading - (show-all) - (goto-char (cdr (assoc heading tvd-headings))) - (tvd-outshine-sparse-tree)))))) - - -(defun tvd-outshine-end-of-section () - "Jump to the end of an outshine section." - (interactive) - (let ((end)) - (outline-show-subtree) - (save-excursion - (outline-next-heading) - (when (outline-on-heading-p) - (backward-paragraph)) - (setq end (point))) - (goto-char end))) - -;; outshine mode config (inside outline mode) -(eval-after-load "outline" - '(progn - (add-hook 'outline-minor-mode-hook - (lambda () - (defalias 'j 'tvd-outshine-jump) - (defalias 'jump 'tvd-outshine-jump) - (define-key outline-minor-mode-map (kbd "C-c C-j") 'tvd-outshine-jump) - (setq outshine-org-style-global-cycling-at-bob-p t - outshine-use-speed-commands t - outshine-speed-commands-user - (quote ( - ("v" . outshine-narrow-to-subtree) - ("q" . widen) - ("e" . tvd-outshine-end-of-section)))))))) - -;; Narrowing now works within the headline rather than requiring to be on it -(advice-add 'outshine-narrow-to-subtree :before - (lambda (&rest args) (unless (outline-on-heading-p t) - (outline-previous-visible-heading 1)))) - -;; convert outshine buffer to org buffer using outorg, which is part -;; of outshine. -(defun outshine-to-org () - (interactive) - (outorg-convert-to-org) - (org-mode)) - -;; I use this to generate a HTML version of my emacs config for -;; posting online, which makes it way easier to read. -(defun outshine-to-html (file) - (interactive - (list - (read-file-name "HTML output file: " - (expand-file-name "~/D/github/dot-emacs") - "emacs.html"))) - (let ((B (current-buffer))) - (with-temp-buffer - (insert-buffer-substring B) - ;; remove 'sk spacings for smaller
      's
      -      (tvd-replace-all ")\s*;" ") ;")
      -      ;; highlight at least a little
      -      (tvd-replace-all "FIXME" "/FIXME/")
      -      (emacs-lisp-mode)
      -      (outshine-to-org)
      -      (org-export-to-file 'html file))))
      -
      -(defun export (cmessage)
      -  "Export .emacs to git, do not use."
      -  ;; FIXME: generate version number, add last changelog to git
      -  (interactive "sEnter Commit Message: ")
      -  (outshine-to-html "~/D/github/dot-emacs/emacs.html")
      -  (shell-command "cp ~/.emacs ~/D/github/dot-emacs/")
      -  (shell-command (format "cd ~/D/github/dot-emacs && git ci '%s' .emacs emacs.html" cmessage))
      -  (shell-command "cd ~/D/github/dot-emacs && git push"))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** outline mode
      -
      -;; I use the very same cycle style  as in org mode: when on a heading,
      -;; hide it, jump to next heading on the same level and expand that (or
      -;; vice versa).  however, when NOT on  a heading behave as loved: jump
      -;; paragraphs.
      -
      -;; Note, that  this also  affects outshine  mode, since  that inherits
      -;; from outline.
      -
      -(defun tvd-outline-left-or-level-up()
      -  "jump one word to the left if not on a heading,
      -otherwise fold current level and jump one level up."
      -  (interactive)
      -  (if (outline-on-heading-p)
      -      (progn
      -        (hide-subtree)
      -        (outline-up-heading 1))
      -    (left-word)))
      -
      -(defun tvd-outline-heading-up()
      -  "fold current heading, jump one level up and unfold it"
      -  (interactive)
      -  (if (not (outline-on-heading-p))
      -      (backward-paragraph)
      -    (hide-subtree)
      -    (outline-backward-same-level 1)
      -    (outline-cycle)))
      -
      -(defun tvd-outline-heading-down()
      -  "fold current heading, jump one level down and unfold it"
      -  (interactive)
      -  (if (not (outline-on-heading-p))
      -      (forward-paragraph)
      -    (hide-subtree)
      -    (outline-forward-same-level 1)
      -    (outline-cycle)))
      -
      -;; unused, see tvd-outshine-jump
      -(defun tvd-outline-jump (part)
      -  "Jump interactively to next header containing PART using search."
      -  (interactive "Mjump to: ")
      -  (let ((done nil)
      -        (pwd (point)))
      -    (beginning-of-buffer)
      -    (outline-show-all)
      -    (when (re-search-forward (format "^;; \\*+.*%s" part) (point-max) t)
      -      (when (outline-on-heading-p)
      -        (beginning-of-line)
      -        (setq done t)))
      -    (when (not done)
      -      (message (format "no heading with '%s' found" part))
      -      (goto-char pwd))))
      -
      -;; outline mode config
      -(eval-after-load "outline"
      -  '(progn
      -     (add-hook 'outline-minor-mode-hook
      -               (lambda ()
      -                 ;; narrowing, we use outshine functions, it's loaded anyway
      -                 (defalias 'n 'outshine-narrow-to-subtree)
      -                 (defalias 'w 'widen)
      -                 (define-key outline-minor-mode-map (kbd "")   'tvd-outline-heading-up)
      -                 (define-key outline-minor-mode-map (kbd "") 'tvd-outline-heading-down)
      -                 ;;(define-key outline-minor-mode-map (kbd "") 'tvd-outline-left-or-level-up)
      -                 ))))
      -
      -;; orange fringe when narrowed
      -(advice-add 'outshine-narrow-to-subtree :after
      -            '(lambda (&rest args)
      -               (set-face-attribute 'fringe nil :background tvd-fringe-narrow-bg)))
      -
      -
      -;; --------------------------------------------------------------------------------
      -;; *** narrowing (no mode but fits here)
      -
      -;; I use narrowing quite frequently, so here are some enhancements.
      -
      -;; easier narrowing with Indirect Buffers
      -;; Source: [[https://www.emacswiki.org/emacs/NarrowIndirect3][emacswiki]]
      -(require 'narrow-indirect)
      -(defalias 'nf 'ni-narrow-to-defun-indirect-other-window)
      -(defalias 'nr 'ni-narrow-to-region-indirect-other-window)
      -
      -;; I  like to  have  an  orange fringe  background  when narrowing  is
      -;; active, since I forget that it is in effect otherwise sometimes.
      -
      -;; via [[https://emacs.stackexchange.com/questions/33288/how-to-find-out-if-narrow-to-region-has-been-called-within-save-restriction][stackoverflow]]
      -(defun tvd-narrowed-fringe-status ()
      -  "Make the fringe background reflect the buffer's narrowing status."
      -  (set-face-attribute
      -   'fringe nil :background (if (buffer-narrowed-p)
      -                               tvd-fringe-narrow-bg
      -                             nil)))
      -
      -(add-hook 'post-command-hook 'tvd-narrowed-fringe-status)
      -
      -;; --------------------------------------------------------------------------------
      -;; *** ANSI-TERM (inferior shells/interpreters and REPLs)
      -
      -;; I use ansi term for inferior shells only.
      -
      -;; via [[http://echosa.github.io/blog/2012/06/06/improving-ansi-term/][echosa]]
      -
      -;; kill buffer when done
      -(defadvice term-sentinel (around tvd-advice-term-sentinel (proc msg))
      -  (if (memq (process-status proc) '(signal exit))
      -      (let ((buffer (process-buffer proc)))
      -        ad-do-it
      -        (kill-buffer buffer))
      -    ad-do-it))
      -(ad-activate 'term-sentinel)
      -
      -;; force utf8
      -(defun tvd-term-use-utf8 ()
      -  (set-buffer-process-coding-system 'utf-8-unix 'utf-8-unix))
      -(add-hook 'term-exec-hook 'tvd-term-use-utf8)
      -
      -;; make C-y work
      -(defun tvd-term-paste (&optional string)
      -                      (interactive)
      -                      (process-send-string
      -                       (get-buffer-process (current-buffer))
      -                       (if string string (current-kill 0))))
      -
      -;; put all term hooks in here
      -(defun tvd-term-hook ()
      -  (goto-address-mode)
      -  (define-key term-raw-map (kbd "C-y") 'tvd-term-paste)
      -  (define-key term-raw-map (kbd "C-c C-d") 'kill-this-buffer)
      -  (define-key term-raw-map (kbd "C-d") 'kill-this-buffer)
      -  (define-key term-raw-map (kbd "C-c C-l") 'term-line-mode)
      -  (define-key term-raw-map (kbd "C-k")
      -    (lambda ()
      -      (interactive)
      -      (term-send-raw-string "\C-k")
      -      (kill-line))))
      -(add-hook 'term-mode-hook 'tvd-term-hook)
      -
      -;; via [[https://www.emacswiki.org/emacs/AnsiTermHints#toc4][emacswiki]]:
      -;; Use to supply commandline arguments to ansi-term
      -(defun term-with-args (new-buffer-name cmd &rest switches)
      -  (setq term-ansi-buffer-name (concat "*" new-buffer-name "*"))
      -  (setq term-ansi-buffer-name (generate-new-buffer-name term-ansi-buffer-name))
      -  (setq term-ansi-buffer-name (apply 'make-term term-ansi-buffer-name cmd nil switches))
      -  (set-buffer term-ansi-buffer-name)
      -  (term-mode)
      -  (term-char-mode)
      -  (message "Line mode: C-c C-l, Char mode: C-c C-k, Exit: C-c C-d")
      -  (switch-to-buffer term-ansi-buffer-name))
      -
      -;; finally the inferior REPLs:
      -(defun iperl ()
      -  "interactive perl (via perlbrew if exist or global)"
      -  (interactive)
      -  (let ((perlbrew (expand-file-name "~/perl5/perlbrew/bin/perlbrew")))
      -    (if (file-exists-p perlbrew)
      -        (term-with-args "*perlbrew-de0*" perlbrew "exec" "--" "perl" "-de0")
      -      (term-with-args "*perl-de0*" "perl" "-de0"))))
      -
      -(defun iruby ()
      -  "interactive ruby"
      -  (interactive)
      -  (term-with-args "*ruby-irb*" "irb"))
      -
      -(defun ipython ()
      -  "interactive python"
      -  (interactive)
      -  (setenv "PYTHONSTARTUP" (expand-file-name "~/.pythonrc"))
      -  (term-with-args "*python-i*" "python" "-i"))
      -
      -(defun icalc ()
      -  "interactive calc"
      -  (interactive)
      -  (term-with-args "*calc*" (expand-file-name "~/bin/calc")))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Puppet
      -
      -;; adds hook for .pp files
      -(require 'puppet-mode)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Novel Mode - Screen Reader
      -
      -;; my own emacs screen reader, very handy to read docs on the road.
      -
      -(require 'novel-mode)
      -(global-set-key (kbd "C-c C-n")         'novel-mode)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Macro Math
      -
      -;; see [[https://github.com/nschum/macro-math.el][macro-math]]
      -
      -;; perform elisp evaluation/caluclaton directly in the buffer.
      -;; mark something and hit C-x C-0  (which is a reminder to C-x C-= w/o the shift)
      -
      -(autoload 'macro-math-eval-and-round-region "macro-math" t nil)
      -(autoload 'macro-math-eval-region "macro-math" t nil)
      -
      -(global-set-key (kbd "C-x C-0")         'macro-math-eval-region)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Common-Lisp (SLIME)
      -
      -;; I'm learing CL with slime, start with M-x slime.
      -
      -;; INSTALL: (see: [[http://www.jonathanfischer.net/modern-common-lisp-on-linux/)][jonathanfischer.net]]
      -
      -(setq slimehelper (expand-file-name "~/quicklisp/slime-helper.el"))
      -
      -(if (file-exists-p slimehelper)
      -    (progn
      -      (load slimehelper)
      -
      -      ;; Replace "sbcl" with the path to your implementation
      -      (setq inferior-lisp-program "sbcl")
      -
      -      ;; Stop SLIME's REPL from grabbing DEL,
      -      ;; which is annoying when backspacing over a '('
      -      (defun override-slime-repl-bindings-with-paredit ()
      -        (define-key slime-repl-mode-map
      -          (read-kbd-macro paredit-backward-delete-key) nil))
      -      (add-hook 'slime-repl-mode-hook 'override-slime-repl-bindings-with-paredit)))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** INFO Mode
      -
      -(require 'info)
      -
      -;; open an info file somewhere outside %infodir% with info-mode
      -(defun info-find-file (file)
      -  (interactive "f")
      -  (info-setup file
      -              (pop-to-buffer-same-window
      -               (format "*info*<%s>"
      -                       (file-name-sans-extension
      -                        (file-name-nondirectory file))))))
      -
      -;; easier navigation in Info mode, intuitive history back and forth.
      -(eval-after-load "Info"
      -  '(progn
      -     (define-key Info-mode-map (kbd "")  'Info-history-back)
      -     (define-key Info-mode-map (kbd "") 'Info-history-forward)
      -     (require 'info+)))
      -
      -;; make Info great again!
      -;; [[http://mbork.pl/2014-12-27_Info_dispatch][based on Marcins]] info dispatch,
      -;; contains (interactive) code from 'info-display-manual for manual selection.
      -(defun i (manual)
      -    "Read documentation for MANUAL in the info system.  Name the
      -buffer '*Info MANUAL*'.  If that buffer is already present, just
      -switch to it.
      -
      -If MANUAL not given as argument, ask interactively with completion
      -to select from a list of installed manuals."
      -  (interactive
      -   (list
      -    (progn
      -      (info-initialize)
      -      (ido-completing-read "Manual name: "
      -                       (info--manual-names current-prefix-arg)
      -                       nil t))))
      -  (let ((buffer (format "*Info %s*" manual)))
      -    (if (get-buffer buffer)
      -      (switch-to-buffer bufer)
      -      (info manual buffer))))
      -
      -;; from examples, I love this one!, replaces the ? buffer
      -(define-key Info-mode-map (kbd "?") #'hydra-info/body)
      -(defhydra hydra-info (:color blue
      -                      :hint nil)
      -      "
      -Info-mode:
      -  ^^_]_ forward  (next logical node)       ^^_l_ast (←)        _u_p (↑)                             _f_ollow reference       _T_OC
      -  ^^_[_ backward (prev logical node)       ^^_r_eturn (→)      _m_enu (↓) (C-u for new window)      _i_ndex                  _d_irectory
      -  ^^_n_ext (same level only)               ^^_H_istory         _g_oto (C-u for new window)          _,_ next index item      _c_opy node name
      -  ^^_p_rev (same level only)               _<_/_t_op           _b_eginning of buffer                virtual _I_ndex          _C_lone buffer
      -  regex _s_earch (_S_ case sensitive)      ^^_>_ final         _e_nd of buffer                      ^^                       _a_propos
      -
      -  _1_ .. _9_ Pick first .. ninth item in the node's menu.
      -
      -"
      -      ("]"   Info-forward-node nil)
      -      ("["   Info-backward-node nil)
      -      ("n"   Info-next nil)
      -      ("p"   Info-prev nil)
      -      ("s"   Info-search nil)
      -      ("S"   Info-search-case-sensitively nil)
      -
      -      ("l"   Info-history-back nil)
      -      ("r"   Info-history-forward nil)
      -      ("H"   Info-history nil)
      -      ("t"   Info-top-node nil)
      -      ("<"   Info-top-node nil)
      -      (">"   Info-final-node nil)
      -
      -      ("u"   Info-up nil)
      -      ("^"   Info-up nil)
      -      ("m"   Info-menu nil)
      -      ("g"   Info-goto-node nil)
      -      ("b"   beginning-of-buffer nil)
      -      ("e"   end-of-buffer nil)
      -
      -      ("f"   Info-follow-reference nil)
      -      ("i"   Info-index nil)
      -      (","   Info-index-next nil)
      -      ("I"   Info-virtual-index nil)
      -
      -      ("T"   Info-toc nil)
      -      ("d"   Info-directory nil)
      -      ("c"   Info-copy-current-node-name nil)
      -      ("C"   clone-buffer nil)
      -      ("a"   info-apropos nil)
      -
      -      ("1"   Info-nth-menu-item nil)
      -      ("2"   Info-nth-menu-item nil)
      -      ("3"   Info-nth-menu-item nil)
      -      ("4"   Info-nth-menu-item nil)
      -      ("5"   Info-nth-menu-item nil)
      -      ("6"   Info-nth-menu-item nil)
      -      ("7"   Info-nth-menu-item nil)
      -      ("8"   Info-nth-menu-item nil)
      -      ("9"   Info-nth-menu-item nil)
      -
      -      ("?"   Info-summary "Info summary")
      -      ("h"   Info-help "Info help")
      -      ("q"   Info-exit "Info exit")
      -      ("C-g" nil "cancel" :color blue))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** calc et al.
      -
      -;; emacs provides 4 ways to calculate:
      -
      -;; M-x calc:
      -;; RPN calc with stack. Enter numbers, when done, operator, enter, etc
      -;; heavy duty.
      -
      -;; provided by calc:
      -
      -;; #+BEGIN_SRC
      -;; (defun c (expr)
      -;;   (interactive "Mcalc:")
      -;;   (message (format "result: %s" (calc-eval expr))))
      -;; #+END_SRC
      -
      -;; by calc as well, but with algebraic input, access last result with $
      -;; algebraic == 1 +1 / 3. result will stored in kill-ring, use C-y to paste
      -(defalias 'c         'quick-calc)
      -
      -;; M-x calculator
      -;; interactive, simpler than calc, but comprehensive nevertheless, input
      -;; is algebraic as well, but last result can be used just as ~/bin/calc
      -
      -;; lisp can be used to calc as well:
      -;; M-x evaluate-expression  (+ 1 2) 
      -
      -;; or, inferior perl calc: M-x icalc, see above
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** MACROs
      -
      -;; help: [[https://www.emacswiki.org/emacs/KeyboardMacrosTricks][emacswiki macro tricks]].
      -
      -;; Default keybindings:
      -;; start-kbd-macro default binding: ‘C-x (’     — Starts recording a keyboard macro.
      -;; end-kbd-macro default binding: ‘C-x )’       — Ends recording of a keyboard macro.
      -;; call-last-kbd-macro default binding: ‘C-x e’ — Executes the last keyboard macro defined.
      -
      -;; however, I use [[https://github.com/Silex/elmacro][elmacro]].
      -
      -(require 'elmacro)
      -(elmacro-mode)
      -
      -(setq tvd-macro-name "last-macro")
      -
      -;; ignore stuff
      -(add-to-list 'elmacro-unwanted-commands-regexps "^(mouse.*)$")
      -(add-to-list 'elmacro-unwanted-commands-regexps "^(tvd-start-or-stop-macro)$")
      -
      -(defun tvd-get-macro-name()
      -  "Ask for a macro name, check for duplicates.
      -If the given name is already defined, ask again (and again until unique).
      -If a buffer with the given name exists, kill it (that is, the buffer is
      -there but has not been saved or evaluated yet). Return the name as string."
      -  (interactive)
      -  (let ((done nil)
      -        (name nil)
      -        (mbuf nil)
      -        (err ""))
      -    (while (not done)
      -      (setq name (read-string (format "%s - enter macro name (last-macro): " err) nil nil "last-macro"))
      -      (if (fboundp (intern name))
      -          (setq err (format "macro '%s is already defined" name))
      -        (setq mbuf (format "* elmacro - %s *" name))
      -        (if (get-buffer mbuf)
      -            (with-current-buffer mbuf
      -              (kill-buffer mbuf)))
      -        (setq done t)))
      -    name))
      -
      -(defun tvd-get-exec-macro-name()
      -  "Ask for a macro name to be executed"
      -  (interactive)
      -  (let ((macros ())
      -        (N 1)
      -        (S nil)
      -        (T ""))
      -    (dolist (entry (cdr (assoc tvd-macro-file load-history )))
      -      (setq S (cdr entry))
      -      (setq T (symbol-name S))
      -      (push (list T N) macros)
      -      (setq N (1+ N)))
      -    (completing-read "enter macro name: " macros nil t nil)))
      -
      -;; the heart of my elmacro stuff
      -(defun tvd-start-or-stop-macro()
      -  "start macro or stop if started"
      -  (interactive)
      -  (if (eq defining-kbd-macro nil)
      -      (progn
      -        (elmacro-clear-command-history)
      -        (start-kbd-macro nil)
      -        (message "Recording macro. Finish with  ..."))
      -    (progn
      -      (call-interactively 'end-kbd-macro)
      -      (setq tvd-macro-name (tvd-get-macro-name))
      -      (elmacro-show-last-macro tvd-macro-name)
      -      (message "Recording done. Execute with , save or  buffer..."))))
      -
      -;; better than the default function
      -(defun tvd-exec-last-macro(&optional ARG)
      -  "execute last macro (or ARG, if given) repeatedly after every
      -, abort with C-g or q, and repeat until EOF after pressing a.
      -
      -If macro defun is known (i.e. because you evaluated the elmacro buffer
      -containing the generated defun), it will be executed. Otherwise the
      -last kbd-macro will be executed."
      -  (interactive)
      -  (let ((melm-count 0)
      -        (melm-all nil)
      -        (melm-abort nil)
      -        (melm-beg (eobp))
      -        (melm-code (or ARG tvd-macro-name)))
      -    (if (eobp)
      -        (if (yes-or-no-p "(point) is at end of buffer. Jump to top?")
      -            (goto-char (point-min))))
      -    (while (and (not melm-abort)
      -                (not (eobp)))
      -       (when (not melm-all)
      -         (message (concat
      -                   (format
      -                    "Executing last macro '%s (%d). Keys:\n"  melm-code melm-count)
      -                   "      repeat once\n"
      -                   "a            repeat until EOF\n"
      -                   "e            enter macro name to execute\n"
      -                   " or q   abort ..\n "))
      -         (setq K (read-event))
      -         (cond ((or (eq K 'return) (eq K 'C-f6)) t)
      -               ((equal (char-to-string K) "q") (setq melm-abort t))
      -               ((equal (char-to-string K) "a") (message "Repeating until EOF")(setq melm-all t))
      -               ((equal (char-to-string K) "e") (setq tvd-macro-name (tvd-get-exec-macro-name)))
      -               (t (setq melm-abort t))))
      -       (if (not melm-abort)
      -           (progn
      -             (if (fboundp (intern melm-code))
      -                 (call-interactively (intern melm-code))
      -               (call-interactively 'call-last-kbd-macro))
      -             (setq melm-count (1+ melm-count)))))
      -    (if (and (eq melm-count 0) (eq (point) (point-max)))
      -        (message "(point) is at end of buffer, aborted")
      -      (message (format "executed '%s %d times" melm-code melm-count)))))
      -
      -;; My macro recording workflow:
      -;; - shift-F6
      -;; - ... do things  ...
      -;; - shift-F6 again
      -;; - enter a  name
      -;; - a new buffer with macro defun appears
      -;; - C-x C-e evals it
      -;; - C-F6 (repeatedly) executes it.
      -(global-set-key (kbd "")            'tvd-start-or-stop-macro)
      -(global-set-key (kbd "")          'tvd-exec-last-macro)
      -
      -;; I use my own macro file
      -(setq tvd-macro-file (concat tvd-lisp-dir "/macros.el"))
      -
      -;; but only load if in use
      -(if (file-exists-p tvd-macro-file)
      -    (load-file tvd-macro-file))
      -
      -(defun tvd-macro-store()
      -  "store current macro to emacs config"
      -  (interactive)
      -  (copy-region-as-kill (point-min) (point-max))
      -  (if (not (get-buffer "macros.el"))
      -      (find-file tvd-macro-file))
      -  (with-current-buffer "macros.el"
      -    (goto-char (point-max))
      -    (newline)
      -    (insert ";;")
      -    (newline)
      -    (insert (format ";; elmacro added on %s" (current-time-string)))
      -    (newline)
      -    (yank)
      -    (newline)
      -    (save-buffer))
      -  (switch-to-buffer nil)
      -  (delete-window))
      -
      -(defalias 'ms        'tvd-macro-store)
      -
      -(defun tvd-macro-gen-repeater-and-save()
      -  "generate repeater and save the defun's
      -Runs when (point) is at 0,0 of generated
      -defun."
      -  (next-line)
      -  (goto-char (point-max))
      -  (newline)
      -  (insert (format "(defun %s-repeat()\n" tvd-macro-name))
      -  (insert "  (interactive)\n")
      -  (insert (format "  (tvd-exec-last-macro \"%s\"))\n" tvd-macro-name))
      -  (newline)
      -  (eval-buffer)
      -  (tvd-macro-store))
      -
      -(advice-add 'elmacro-show-defun :after '(lambda (&rest args)
      -                                          (tvd-macro-gen-repeater-and-save)))
      -
      -;; --------------------------------------------------------------------------------
      -;; *** EWW browser stuff
      -
      -;; Emacs has a builtin browser, which is not too bad.
      -
      -(require 'eww)
      -
      -;; see also: shr-render-[buffer|region] !
      -(defun eww-render-current-buffer ()
      -  "Render HTML in the current buffer with EWW"
      -  (interactive)
      -  (beginning-of-buffer)
      -  (eww-display-html 'utf8 (buffer-name)))
      -
      -(defalias 'render-html 'eww-render-current-buffer)
      -
      -;; eww config
      -(add-hook 'eww-mode-hook #'toggle-word-wrap)
      -(add-hook 'eww-mode-hook #'visual-line-mode)
      -
      -;; custom short commands, see ? for the defaults
      -(define-key eww-mode-map "o" 'eww) ; aka other page
      -(define-key eww-mode-map "f" 'eww-browse-with-external-browser) ; aka firefox
      -(define-key eww-mode-map "j" 'next-line)
      -(define-key eww-mode-map "r" 'eww-reload)
      -(define-key eww-mode-map "s" 'shr-save-contents)
      -(define-key eww-mode-map "v" 'eww-view-source)
      -(define-key eww-mode-map "b" 'eww-add-bookmark)
      -(define-key eww-mode-map "p" 'eww-back-url)
      -(define-key eww-mode-map "n" 'eww-forward-url)
      -
      -;; link short commands
      -(define-key eww-link-keymap "c" 'shr-copy-url)
      -(define-key eww-link-keymap "s" 'shr-save-contents)
      -
      -;; FIXME:  latest GIT  version  of eww  contains 'eww-readable,  which
      -;; hides menus and distractions! Update emacs.
      -
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Firestarter
      -
      -;; experimental: do things on save buffer etc.
      -;; Source: [[https://github.com/wasamasa/firestarter][firestarter]]
      -
      -;; *** Tabulated List Mode
      -;; built-in, used by many interactive major modes
      -
      -;; +tablist, which provides many cool features
      -;; [[https://github.com/politza/tablist][github source]]
      -;; important commands:
      -;; - <  shrink column
      -;; - >  enlarge column
      -;; - s  sort column
      -;; - /  prefix for filter commands
      -;;   / e   edit filter, e.g. do not list auto-complete sub-packages in melpa:
      -;;   / a  ! Package =~ ac- 
      -(require 'tablist)
      -
      -;; we need to kill tablist's binding in order to have ours run (see below)
      -(define-key tablist-minor-mode-map (kbd "q") nil)
      -(define-key tablist-minor-mode-map (kbd "q") 'tvd-close-window)
      -
      -(defun tvd-close-window ()
      -  (interactive)
      -  (kill-this-buffer)
      -  (delete-window))
      -
      -(eval-after-load "tabulated-list"
      -  '(progn
      -     (add-hook 'tabulated-list-mode-hook
      -               (lambda ()
      -                 (tablist-minor-mode)
      -                 (local-set-key (kbd "Q") 'delete-other-windows)
      -                 (hl-line-mode)))))
      -
      -;; *** Help Mode
      -
      -;; I even customize help windows! ... at least a little :)
      -
      -(defun tvd-close-help ()
      -  (interactive)
      -  (kill-this-buffer)
      -  (winner-undo))
      -
      -(eval-after-load "Help"
      -  '(progn
      -     (add-hook 'help-mode-hook
      -               (lambda ()
      -                 ; doesn' work the way I like
      -                 ;(local-set-key (kbd "q") 'tvd-close-help)
      -                 (local-set-key (kbd "q") 'quit-window)
      -                 (local-set-key (kbd "p") 'help-go-back)
      -                 (local-set-key (kbd "b") 'help-go-back)
      -                 (local-set-key (kbd "n") 'help-go-forward)
      -                 (local-set-key (kbd "f") 'help-go-forward)
      -                 (setq help-window-select t)
      -                 ))))
      -
      -;; *** Suggest Mode
      -
      -;; [[https://github.com/Wilfred/suggest.el][suggest mode]] is a great
      -;; elisp development tool. Execute `M-x suggest' and try it.
      -
      -(require 'suggest) ;; depends on dash, s, f, loop
      -
      -;; I use my own clearing function, since suggest doesn't provide this
      -(defun tvd-suggest-reload ()
      -  "Clear suggest buffer and re-paint it."
      -  (interactive)
      -  (let ((inhibit-read-only t))
      -    (erase-buffer)
      -    (suggest--insert-heading suggest--inputs-heading)
      -    (insert "\n\n\n")
      -    (suggest--insert-heading suggest--outputs-heading)
      -    (insert "\n\n\n")
      -    (suggest--insert-heading suggest--results-heading)
      -    (insert "\n")
      -    (suggest--nth-heading 1)
      -    (forward-line 1)))
      -
      -(defun tvd-suggest-jump ()
      -  "Jump between input and output suggest buffer."
      -  (interactive)
      -  (forward-line -1)
      -  (if (eq (line-number-at-pos) 1)
      -      (suggest--nth-heading 2)
      -    (suggest--nth-heading 1))
      -  (forward-line 1))
      -
      -(eval-after-load "suggest"
      -  '(progn
      -     (add-hook 'suggest-mode-hook
      -               (lambda ()
      -                 (local-set-key (kbd "C-l") 'tvd-suggest-reload)
      -                 (local-set-key (kbd "") 'tvd-suggest-jump)))))
      -
      -;; *** Followcursor Mode
      -
      -;; [[https://github.com/TLINDEN/followcursor-mode][source on github]]
      -
      -;; From time to time I need to  refactor configs and the like based on
      -;; lists. For example  in the left window  I have a list  of bgp peers
      -;; and in the right window a config file for all peers which I have to
      -;; modify based on current settings.  With followcursor-mode I can put
      -;; point on an  ip address and the line in  the config containing this
      -;; ip address  will be highlighted. If  I move on to  the next address
      -;; the next line on the right will be highlighted.
      -
      -;; The mode is a work-in-progress...
      -
      -(require 'followcursor-mode)
      -
      -
      -
      -;; *** RCS Mode
      -(defun rcs-ci-co nil
      -  "check in check out the file if it is under vc with rcs
      -        with a prefix other than 1 only check-in"
      -  (when (eq (vc-backend (buffer-file-name)) 'RCS)
      -    (if (= args 1)
      -        (save-window-excursion
      -          (vc-toggle-read-only)
      -          (call-interactively 'log-edit-done)
      -          (vc-toggle-read-only))
      -      (vc-toggle-read-only))))
      -
      -(defun rcs-is-under-revision ()
      -    "Return t in case current buffer is RCS revisioned"
      -    (if (eq (vc-backend (buffer-file-name)) 'RCS)
      -        "[X]"  "[ ]"))
      -
      -;; always lock after checkout
      -(setq vc-rcs-checkin-switches "-l")
      -
      -(defhydra hydra-rcs (:color blue)
      -  "
      -RCS revision control. Current buffer %(file-name-nondirectory (buffer-file-name)) is under RCS: %(rcs-is-under-revision).
      -
      - _co_: Checkout            (C-x v v)
      - _ci_: Checkin             (C-x v v)
      -  _d_: Diff                (C-x v =)
      -  _u_: Undo Changes        (C-x v u)
      -  _l_: View revision log   (C-x v l)
      -  _s_: Status              (C-x v d)
      -  _m_: Merge               (C-x v m)
      -  _q_: Cancel
      -
      -^^^^^^^^---------------------
      -Reach this hydra with 
      -^^^^^^^^---------------------
      -
      -"
      -  ("co" rcs-ci-co)
      -  ("ci" rcs-ci-co)
      -  ("d"  vc-version-diff)
      -  ("u"  vc-revert-buffer)
      -  ("l"  vc-print-log)
      -  ("s"  vc-dir)
      -  ("m"  vc-merge)
      -  ("q"  nil nil :color red))
      -
      -(global-set-key (kbd "C-x R") 'hydra-rcs/body)
      -
      -;; *** Magit
      -
      -;; Not much to  say about Magit
      -(unless tvd-win-home
      -  (setq tvd-magit-revision "20170725.1153")
      -  (add-to-list 'load-path (concat tvd-lisp-dir (concat "/magit-" tvd-magit-revision)))
      -
      -  (require 'magit)
      -
      -  (defun tvd-magit-status ()
      -    "Always call `magit-status' with prefix arg."
      -    (interactive)
      -    (let ((current-prefix-arg t))
      -      (call-interactively 'magit-status)))
      -
      -  (with-eval-after-load 'info
      -    (info-initialize)
      -    (add-to-list 'Info-directory-list
      -                 (expand-file-name (concat "~/.emacs.d/lisp/magit-"
      -                                           tvd-magit-revision
      -                                           "/Documentation/")))
      -    (setq magit-view-git-manual-method 'woman))
      -
      -  (defalias 'git       'magit-status)
      -  (defalias 'gitlog    'magit-log-buffer-file)
      -
      -  ;; configure magit
      -  (with-eval-after-load 'magit
      -    (dolist (dir (list (expand-file-name "~/D/github")
      -                       (expand-file-name "~/dev/git")))
      -      (when (file-exists-p dir)
      -        (add-to-list 'magit-repository-directories (cons dir 1))))
      -    (setq magit-completing-read-function 'magit-ido-completing-read)
      -
      -    ;; use timestamps in log buffers
      -    (setq magit-log-margin '(t "%Y-%m-%d " magit-log-margin-width t 18))
      -
      -    ;; navigate magit buffers as I do everywhere else, I do not automatically
      -    ;; cycle/decycle though, the magit defaults are absolutely sufficient.
      -    (define-key magit-mode-map (kbd "") 'magit-section-forward-sibling)
      -    (define-key magit-mode-map (kbd "")   'magit-section-backward-sibling)
      -    (define-key magit-mode-map (kbd "") 'magit-delete-thing))
      -
      -  ;; one thing though:  on startup it bitches about git  version, but it
      -  ;; works nevertheless. So I disable this specific warning.
      -
      -  (defun tvd-ignore-magit-warnings-if-any ()
      -    (interactive)
      -    (when (get-buffer "*Warnings*")
      -      (with-current-buffer "*Warnings*"
      -        (goto-char (point-min))
      -        (when (re-search-forward "Magit requires Git >=")
      -          (kill-buffer-and-window)))))
      -
      -  (add-hook 'after-init-hook 'tvd-ignore-magit-warnings-if-any t)
      -
      -  ;; now, THIS is the pure genius me: hit "ls in magit-status buffer
      -  ;; and end up in a dired buffer of current repository. The default
      -  ;; binding for this is C-M-i, which is not memorizable, while "ls"
      -  ;; is. That is, 'l' is a prefix command leading to magit-log-popup
      -  ;; and 's' is undefined, which I define here, which then jumps to
      -  ;; dired.
      -  (magit-define-popup-action 'magit-log-popup
      -    ?s "Dired" 'magit-dired-jump)
      -
      -  ;; after an exhausting discussion on magit#3139 I use this function
      -  ;; to (kind of) switch to another repository from inside magit-status.
      -  (defun tvd-switch-magit-repo ()
      -    (interactive)
      -    (let ((dir (magit-read-repository)))
      -      (magit-mode-bury-buffer)
      -      (magit-status dir)))
      -  (define-key magit-mode-map (kbd "C") 'tvd-switch-magit-repo)
      -
      -  ;; scheisse
      -  ;; (require 'magit-gh-pulls)
      -  ;; (add-hook 'magit-mode-hook 'turn-on-magit-gh-pulls)
      -
      -  ;; via
      -  ;; http://manuel-uberti.github.io/emacs/2018/02/17/magit-bury-buffer/:
      -  ;; a great  enhancement, when closing  the magit status  buffer, ALL
      -  ;; other possibly  still remaining magit  buffers will be  killed as
      -  ;; well AND the window setup will be restored.
      -  (defun tvd-kill-magit-buffers()
      -    "Restore window setup from before magit and kill all magit buffers."
      -    (interactive)
      -    (let ((buffers (magit-mode-get-buffers)))
      -      (magit-restore-window-configuration)
      -      (mapc #'kill-buffer buffers)))
      -  (define-key magit-status-mode-map (kbd "q") #'tvd-kill-magit-buffers))
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Dired
      -
      -;; I use dired  for two things: from inside magit  as a convenient way
      -;; to add or remove files from a  repository. Or if I want to rename a
      -;; bunch of files using search/replace and other editing commands.
      -
      -;; But as with everything else I use,  it must fit and so I managed to
      -;; tune this as well.
      -
      -;; [[http://ergoemacs.org/emacs/emacs_dired_tips.html][More Hints]]
      -
      -;; **** dired-k
      -
      -;; dired-k is k  for dired/emacs: it colorizes files  and directory by
      -;; age, that is, the older the  greyer they get. And it displays flags
      -;; about the git status of each file, which is really handy.
      -
      -;; However,  it only  works with  git installed  and if  enabled stops
      -;; dired to work  completely. So I define an exception  here and don't
      -;; load k if there's no git (e.g. on my notebook at work)
      -(when (string-match "version" (shell-command-to-string "git version"))
      -  (require 'dired-k)
      -  (add-hook 'dired-initial-position-hook 'dired-k)
      -  (add-hook 'dired-after-readin-hook #'dired-k-no-revert)
      -  (setq dired-k-padding 2))
      -
      -;; **** dired-hacks
      -
      -;; [[https://github.com/Fuco1/dired-hacks][Fuco1s dired-hacks]] is a
      -;; place to find the really cool stuff, I mostly use the filters.
      -(require 'dired-filter)
      -
      -(defun tvd-dired-quit-or-filter-pop (&optional arg)
      -  "Remove a filter from the filter stack. If none left, quit the dired buffer."
      -  (interactive "p")
      -  (if dired-filter-stack
      -      (dired-filter-pop arg)
      -    (quit-window)))
      -
      -(require 'dired-ranger)
      -
      -;; **** dired sort helpers
      -
      -;; This sort function by [[http://ergoemacs.org/emacs/dired_sort.html][Xah Lee]]
      -;; is easy to use and does what it should, great!, However, I added some -desc
      -;; sister sorts for reverse sorting.
      -(defun xah-dired-sort ()
      -  "Sort dired dir listing in different ways.
      -Prompt for a choice.
      -URL `http://ergoemacs.org/emacs/dired_sort.html'
      -Version 2015-07-30"
      -  (interactive)
      -  (let (sort-by arg)
      -    (setq sort-by (ido-completing-read "Sort by:" '( "date" "size" "name" "dir" "date-desc" "size-desc" "name-desc" "dir-desc" )))
      -    (cond
      -     ((equal sort-by "name") (setq arg "-Al --si --time-style long-iso "))
      -     ((equal sort-by "date") (setq arg "-Al --si --time-style long-iso -t"))
      -     ((equal sort-by "size") (setq arg "-Al --si --time-style long-iso -S"))
      -     ((equal sort-by "dir") (setq arg "-Al --si --time-style long-iso --group-directories-first"))
      -     ((equal sort-by "name-desc") (setq arg "-Al --si --time-style long-iso -r"))
      -     ((equal sort-by "date-desc") (setq arg "-Al --si --time-style long-iso -t -r"))
      -     ((equal sort-by "size-desc") (setq arg "-Al --si --time-style long-iso -S -r"))
      -     ((equal sort-by "dir-desc") (setq arg "-Al --si --time-style long-iso --group-directories-first -r"))
      -     (t (error "logic error 09535" )))
      -    (dired-sort-other arg )))
      -
      -;; **** dired git helpers
      -
      -;; [[http://blog.binchen.org/posts/the-most-efficient-way-to-git-add-file-in-dired-mode-emacsendiredgit.html][via bin chen]]:
      -;; make git commands available from dired  buffer, which can be used in
      -;; those rare cases, where my wrappers below don't fit.
      -(defun diredext-exec-git-command-in-shell (command &optional arg file-list)
      -  "Run a shell command git COMMAND  ' on the marked files.  if no
      -files marked, always operate on current line in dired-mode"
      -  (interactive
      -   (let ((files (dired-get-marked-files t current-prefix-arg)))
      -     (list
      -      ;; Want to give feedback whether this file or marked files are used:
      -      (dired-read-shell-command "git command on %s: " current-prefix-arg files)
      -      current-prefix-arg
      -      files)))
      -  (unless (string-match "[?][ \t]\'" command)
      -    (setq command (concat command " *")))
      -  (setq command (concat "git " command))
      -  (dired-do-shell-command command arg file-list)
      -  (message command))
      -
      -;; some git  commandline wrappers  which directly  work on  git files,
      -;; called with "hydras".
      -(defun tvd-dired-git-add(&optional arg file-list)
      -  "Add marked or current file to current repository (stash)."
      -  (interactive
      -    (let ((files (dired-get-marked-files t current-prefix-arg)))
      -      (list current-prefix-arg files)))
      -  (dired-do-shell-command "git add -v * " arg file-list)
      -  (revert-buffer))
      -
      -(defun tvd-dired-git-rm(&optional arg file-list)
      -  "Remove marked or current file from current repository and filesystem."
      -  (interactive
      -   (let ((files (dired-get-marked-files t current-prefix-arg)))
      -     (list current-prefix-arg files)))
      -  (dired-do-shell-command "git rm -rf * " arg file-list)
      -  (revert-buffer))
      -
      -(defun tvd-dired-git-ungit(&optional arg file-list)
      -  "Like `tvd-dired-git-rm' but keep the files in the filesystem (unstage)."
      -  (interactive
      -   (let ((files (dired-get-marked-files t current-prefix-arg)))
      -     (list current-prefix-arg files)))
      -  (dired-do-shell-command "git rm -rf --cached * " arg file-list)
      -  (revert-buffer))
      -
      -;; **** dired navigation
      -
      -;; I'm used to jump around with pos1+end
      -(defun tvd-dired-begin ()
      -  "Move point to the first directory in the listing .."
      -  (interactive)
      -  (goto-char (point-min))
      -  (dired-next-dirline 2))
      -
      -(defun tvd-dired-end ()
      -  "Move point to the last file or directory in the listing."
      -  (interactive)
      -  (goto-char (point-max))
      -  (dired-previous-line 1))
      -
      -;; **** dired buffer names
      -
      -;; This took  me a long time  to figure out,  but I finally got  it: I
      -;; really  hate it  how  dired names  its buffers,  it  just uses  the
      -;; basename part of  the current working directory as  buffer name. So
      -;; when there are  a couple of dozen  buffers open and one  of them is
      -;; named "tmp"  I just can't see  it. So what  I do here is  to rename
      -;; each   dired  buffer   right   after  its   creation  by   advising
      -;; `dired-internal-noselect'. My  dired buffers  have such  names now:
      -;; *dired: ~/tmp*. I  can find them easily, and I  can reach all dired
      -;; buffers very  fast thanks to  the *dired  prefix. And they  are now
      -;; clearly  marked  as  non-file  buffers. In  fact  I  consider  this
      -;; behavior as a bug, but I doubt many people would agree :)
      -
      -(advice-add 'dired-internal-noselect
      -            :filter-return
      -            '(lambda (buffer)
      -               "Modify dired buffer names to this pattern: *dired: full-path*"
      -               (interactive)
      -               (with-current-buffer buffer
      -                 (rename-buffer (format "*dired: %s*" default-directory)))
      -               buffer))
      -
      -;; **** dired config and key bindings
      -
      -;; and finally put everything together.
      -
      -(eval-after-load 'dired
      -  '(progn
      -     ;; dired vars
      -     (setq dired-listing-switches "-lt")
      -
      -     ;; stay  with 1  dired buffer  per instance
      -     ;; when changing directories
      -     (define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
      -     (define-key dired-mode-map (kbd "") 'dired-find-alternate-file)
      -     (define-key dired-mode-map (kbd "^") (lambda () (interactive) (find-alternate-file "..")))
      -     (define-key dired-mode-map (kbd "") (lambda () (interactive) (find-alternate-file "..")))
      -
      -     ;; Xah Lee'S custom sort's
      -     (define-key dired-mode-map (kbd "s") 'xah-dired-sort)
      -
      -     ;; my git "hydras"
      -     (define-prefix-command 'tvd-dired-git-map)
      -     (define-key dired-mode-map (kbd "g") 'tvd-dired-git-map)
      -     (define-key tvd-dired-git-map (kbd "a") 'tvd-dired-git-add)
      -     (define-key tvd-dired-git-map (kbd "d") 'tvd-dired-git-rm)
      -     (define-key tvd-dired-git-map (kbd "u") 'tvd-dired-git-ungit)
      -
      -     ;; edit filenames
      -     (defalias 'edit-dired 'wdired-change-to-wdired-mode)
      -     (define-key dired-mode-map (kbd "C-c C-c") 'wdired-change-to-wdired-mode)
      -
      -     ;; dired-hacks filters
      -     (define-key dired-mode-map (kbd "f") dired-filter-map)
      -     (define-key dired-mode-map (kbd "q") 'tvd-dired-quit-or-filter-pop)
      -     (define-key dired-mode-map (kbd "Q") 'dired-filter-pop-all)
      -
      -     ;; ranger, multi file copy/move
      -     (define-prefix-command 'tvd-dired-ranger-map)
      -     (define-key dired-mode-map (kbd "r") 'tvd-dired-ranger-map)
      -     (define-key tvd-dired-ranger-map (kbd "c") 'dired-ranger-copy)
      -     (define-key tvd-dired-ranger-map (kbd "p") 'dired-ranger-paste)
      -     (define-key tvd-dired-ranger-map (kbd "m") 'dired-ranger-move)
      -
      -     ;; navigation,  use TAB  and C-TAB  to move
      -     ;; point to  next or prev dir  like in info
      -     ;; mode, and  HOME+END to reach the  end or
      -     ;; beginning of the listing.
      -     (define-key dired-mode-map (kbd "") 'dired-next-dirline)
      -     (define-key dired-mode-map (kbd "") 'dired-prev-dirline)
      -     (define-key dired-mode-map (kbd "") 'tvd-dired-begin)
      -     (define-key dired-mode-map (kbd "") 'tvd-dired-end)
      -
      -     ;; overwrite some defaults I do not use anyway
      -     (define-key dired-mode-map (kbd "n") 'dired-create-directory)))
      -;; **** Dired Hydra
      -
      -;; FIXME: not yet customized to fit my own config
      -(defhydra hydra-dired (:hint nil :color pink)
      -  "
      -_+_ mkdir          _v_iew           _m_ark             _(_ details        _i_nsert-subdir    _W_dired (EDIT FILENAMES)
      -_C_opy             _O_ view other   _U_nmark all       _)_ omit-mode      _$_ hide-subdir    C-c C-c : edit
      -_D_elete           _o_pen other     _u_nmark           _l_ redisplay      _w_ kill-subdir
      -_R_ename           _M_ chmod        _t_oggle           _g_ revert buf     _e_ ediff          _q_uit
      -_Y_ rel symlink    _G_ chgrp        _E_xtension mark   _s_ort             _=_ pdiff
      -_S_ymlink          ^ ^              _F_ind marked      _._ toggle hydra   \\ flyspell
      -_r_sync            ^ ^              ^ ^                ^ ^                _?_ summary
      -_z_ compress-file  _A_ find regexp   / Filter
      -_Z_ compress       _Q_ repl regexp
      -
      -T - tag prefix
      -
      -"
      -  ("\\" dired-do-ispell nil)
      -  ("(" dired-hide-details-mode nil)
      -  (")" dired-omit-mode nil)
      -  ("+" dired-create-directory nil)
      -  ("=" diredp-ediff nil)         ;; smart diff
      -  ("?" dired-summary nil)
      -  ("$" diredp-hide-subdir-nomove nil)
      -  ("A" dired-do-find-regexp nil)
      -  ("C" dired-do-copy nil)        ;; Copy all marked files
      -  ("D" dired-do-delete nil)
      -  ("E" dired-mark-extension nil)
      -  ("e" dired-ediff-files nil)
      -  ("F" dired-do-find-marked-files nil)
      -  ("G" dired-do-chgrp nil)
      -  ("g" revert-buffer nil)        ;; read all directories again (refresh nil)
      -  ("i" dired-maybe-insert-subdir nil)
      -  ("l" dired-do-redisplay nil)   ;; relist the marked or singel directory
      -  ("M" dired-do-chmod nil)
      -  ("m" dired-mark nil)
      -  ("O" dired-display-file nil)
      -  ("o" dired-find-file-other-window nil)
      -  ("Q" dired-do-find-regexp-and-replace nil)
      -  ("R" dired-do-rename nil)
      -  ("r" dired-do-rsynch nil)
      -  ("S" dired-do-symlink nil)
      -  ("s" dired-sort-toggle-or-edit nil)
      -  ("t" dired-toggle-marks nil)
      -  ("U" dired-unmark-all-marks nil)
      -  ("u" dired-unmark nil)
      -  ("v" dired-view-file nil)      ;; q to exit, s to search, = gets line #
      -  ("w" dired-kill-subdir nil)
      -  ("W" wdired-change-to-wdired-mode nil)
      -  ("Y" dired-do-relsymlink nil)
      -  ("z" diredp-compress-this-file nil)
      -  ("Z" dired-do-compress nil)
      -  ("q" nil nil)
      -  ("." nil nil :color blue))
      -
      -(define-key dired-mode-map "?" 'hydra-dired/body)
      -
      -;; *** Ediff Config
      -
      -;; Force ediff to use  1 frame (the current) and not  open a new frame
      -;; for control  and help. Also  changing the split  orientation doesnt
      -;; open a new frame.
      -
      -(eval-after-load "ediff"
      -  '(progn
      -     (setq ediff-diff-options   "-w"
      -           ediff-split-window-function 'split-window-horizontally
      -           ediff-window-setup-function 'ediff-setup-windows-plain)
      -
      -     (add-hook 'ediff-startup-hook 'ediff-toggle-wide-display)
      -     (add-hook 'ediff-cleanup-hook 'ediff-toggle-wide-display)
      -     (add-hook 'ediff-suspend-hook 'ediff-toggle-wide-display)
      -
      -     (add-hook 'ediff-mode-hook
      -               (lambda ()
      -                 (ediff-setup-keymap)
      -                 ;; merge left to right
      -                 (define-key ediff-mode-map ">" 'ediff-copy-A-to-B)
      -                 ;; merge right to left
      -                 (define-key ediff-mode-map "<" 'ediff-copy-B-to-A)))
      -
      -     ;; restore window config on quit
      -     (add-hook 'ediff-after-quit-hook-internal 'winner-undo)
      -     ))
      -
      -;; from emacswiki:
      -;; Usage: emacs -diff file1 file2
      -(defun command-line-diff (switch)
      -  (let ((file1 (pop command-line-args-left))
      -        (file2 (pop command-line-args-left)))
      -    (ediff file1 file2)))
      -(add-to-list 'command-switch-alist '("diff" . command-line-diff))
      -;; --------------------------------------------------------------------------------
      -;; *** Smerge Config
      -
      -;; smerge-mode is being issued during editing of conflicts from magit,
      -;; however, I  hate its default  prefix, but don't have  any practical
      -;; prefixes  left AND  am using  it far  too rare  to deserve  its own
      -;; prefix. So just a hydra will do.
      -
      -(defhydra hydra-smerge (:color blue :timeout 30.0)
      -  "
      -^Smerge Mode^
      -^^-------------------------------------------------------
      -_n_ext conflict         keep _u_pper    m_e_rge conflicts in Ediff
      -_p_revious conflict     keep _l_ower    _q_uit"
      -
      -  ("n"  smerge-next       nil :exit nil)
      -  ("p"  smerge-prev       nil :exit nil)
      -  ("u"  smerge-keep-upper nil :exit nil)
      -  ("l"  smerge-keep-lower nil :exit nil)
      -  ("e"  smerge-ediff      nil :color red)
      -  ("q"  nil               nil :color red))
      -
      -(defalias 'merge      'hydra-smerge/body)
      -;; --------------------------------------------------------------------------------
      -;; *** Projectile
      -(require 'projectile)
      -(projectile-mode +1)
      -
      -(defun tvd-dir-to-projectile ()
      -    "drop a .projectile wherever we are"
      -  (interactive)
      -  (with-temp-file ".projectile"
      -    (insert "-.snapshot\n-.git\n-.RCS\n"))
      -  (message (format "Turned %s into projectile project" default-directory)))
      -
      -;; FIXME: add custom docstring
      -(defhydra hydra-projectile
      -  ( :color teal
      -    :columns 4)
      -  "Projectile (use C-p for this menu)"
      -  ("s"   projectile-switch-project           "Switch Project")
      -  ("f"   projectile-find-file                "Find File")
      -  ("r"   projectile-recentf                  "Recent Files")
      -  ("b"   projectile-ibuffer                  "Show Project Buffers")
      -
      -  ("g"   projectile-grep                     "Grep")
      -  ("o"   projectile-multi-occur              "Multi Occur")
      -  ("d"   projectile-dired                    "Project Dired")
      -  ("R"   projectile-replace                  "Replace in Project")
      -
      -  ("C"   projectile-invalidate-cache         "Clear Cache")
      -  ("t"   projectile-regenerate-tags          "Regenerate Tags")
      -  ("X"   projectile-cleanup-known-projects   "Cleanup Known Projects")
      -  ("n"   tvd-dir-to-projectile               "Turn current directory into Projectile")
      -
      -  ("c"   projectile-commander                "Commander")
      -  ("k"   projectile-kill-buffers             "Kill Buffers")
      -  ("q"   nil                                 "Cancel" :color blue))
      -
      -(global-set-key (kbd "C-x p") 'hydra-projectile/body)
      -
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Occur
      -;; https://oremacs.com/2015/01/26/occur-dwim/
      -;; https://github.com/abo-abo/hydra/wiki/Emacs
      -(defun occur-dwim ()
      -  "Call `occur' with a sane default, chosen as the thing under point or selected region"
      -  (interactive)
      -  (push (if (region-active-p)
      -            (buffer-substring-no-properties
      -             (region-beginning)
      -             (region-end))
      -          (let ((sym (thing-at-point 'symbol)))
      -            (when (stringp sym)
      -              (regexp-quote sym))))
      -        regexp-history)
      -  (call-interactively 'occur))
      -
      -;; *** Window Hydra
      -
      -;; brightness wrappers
      -(defun tvd-bg-brighter ()
      -  (interactive)
      -  (doremi-increment-background-color-1 ?v -1))
      -
      -(defun tvd-bg-darker ()
      -  (interactive)
      -  (doremi-increment-background-color-1 ?v 1))
      -
      -(defun tvd-pre-resize ()
      -  "Called as  pre execute  hook py  hydra-windows-resize/body and
      -executes the called key once, so that no key press gets lost from
      -hydra-windows (a,s,d,w)"
      -  (interactive)
      -  (let
      -      ((key (car (reverse (append (recent-keys) nil)))))
      -    (cond
      -     ((eq key ?a)
      -      (shrink-window-horizontally 1))
      -     ((eq key ?d)
      -      (enlarge-window-horizontally 1))
      -     ((eq key ?w)
      -      (shrink-window 1))
      -     ((eq key ?s)
      -      (enlarge-window 1)))))
      -
      -(defhydra hydra-windows-resize (:color pink :pre (tvd-pre-resize))
      -  ;; small sub hydra  for window resizing, it leaves as  much room for
      -  ;; windows as possible
      -  "
      -_a_ ||    _d_ |---|     _w_ ---   _s_ ="
      -  ("a" shrink-window-horizontally nil)
      -  ("d" enlarge-window-horizontally nil)
      -  ("w" shrink-window nil)
      -  ("s" enlarge-window nil)
      -  ("q" nil nil :color red))
      -
      -(defhydra hydra-windows (:color blue)
      -"
      -
      -^Window Management^
      -^^------------------------------------------------------------------------
      -_+_ Increase Font | _-_ Decrease Font      Resize     ^ ^  _w_  ^ ^
      -_f_: Flip Windows                ^^   Current    _a_  ^ ^  _d_
      -_4_: Quarter Windows           ^^   Window:    ^ ^  _s_  ^ ^
      -_u_: Windows Undo    
      -_r_: Windows Redo          ^^   _l_: Adjust Background brighter
      -_i_: Invert Colors           ^^   _b_: Adjust Background darker
      -
      -_h_: Toggle Highlight Line Mode       ^^   _e_: Eyebrowse Workspaces (C-x C-x)
      -_n_: Toogle Line Number Mode
      -
      -^^------------------------------------------------------------------------
      -Reach this hydra with 
      -^^------------------------------------------------------------------------
      -
      -"
      -  ("+" tvd-global-font-size-bigger nil :color pink)
      -  ("-" tvd-global-font-size-smaller nil :color pink)
      -  ("f" tvd-flip-windows nil)
      -  ("4" tvd-quarter-windows nil)
      -  ("u" winner-undo nil)
      -  ("r" winner-redo nil)
      -  ("i" tvd-invert nil)
      -  ("b" tvd-bg-darker nil :color pink)
      -  ("l" tvd-bg-brighter nil :color pink)
      -  ("a" hydra-windows-resize/body nil)
      -  ("d" hydra-windows-resize/body nil)
      -  ("w" hydra-windows-resize/body nil)
      -  ("s" hydra-windows-resize/body nil)
      -  ("e" hydra-eyebrowse/body nil)
      -  ("h" hl-line-mode nil)
      -  ("n" linum-mode nil)
      -  ("q" nil nil :color red))
      -
      -(global-set-key (kbd "C-x w") 'hydra-windows/body)
      -
      -
      -;; *** Eyebrowse Workspaces
      -;; workspace configuration, like desktops. Seems to be a good implementation, w/o save though
      -
      -;; "prefix key" has to be set before loading, keep in mind, that
      -;; if you change it here, you need to change it below as well!
      -(setq eyebrowse-keymap-prefix (kbd "C-x C-x"))
      -(global-unset-key (kbd "C-x C-x"))
      -
      -(require 'eyebrowse)
      -
      -(defun tvd-new-eyebrowse-workspace ()
      -  "Create new scratch buffer and ask for a name"
      -  (interactive)
      -  (eyebrowse-rename-window-config (eyebrowse--get 'current-slot) (read-string "Workspace: "))
      -  (autoscratch-buffer))
      -
      -;; always enable
      -(eyebrowse-mode t)
      -(setq eyebrowse-new-workspace 'tvd-new-eyebrowse-workspace
      -      eyebrowse-switch-back-and-forth t
      -      eyebrowse-wrap-around t
      -      eyebrowse-mode-line-style t
      -      eyebrowse-slot-format "%s:init")
      -
      -;; add a hydra, just in case, it contains hydra commands and hints
      -;; about the actual key bindings, it's also being refered from
      -;; hydra-window/body with "e"
      -(defhydra hydra-eyebrowse (:color blue)
      -  "
      -^Eyebrowse Workspace Management^
      -^^--------------------------------------
      -_l_: last window      (C-x C-x C-x)
      -_n_: next window      (C-x C-x )
      -_p_: prev window      (C-x C-x )
      -_x_: close workspace  (C-x C-x q)
      -_t_: rename workspace (C-x C-x t)
      -_c_: create workspace (C-x C-x n)
      -
      -Use C-x C-x to access eyebrowse directly.
      -"
      -  ("l" eyebrowse-last-window-config nil)
      -  ("n" eyebrowse-next-window-config nil)
      -  ("p" eyebrowse-prev-window-config nil)
      -  ("x" eyebrowse-close-window-config nil)
      -  ("t" eyebrowse-rename-window-config nil)
      -  ("c" eyebrowse-create-window-config nil)
      -  ("q" nil nil :color red))
      -
      -;;Modifying the eyebrowse keymap directly doesn't work because it's
      -;; not setup correctly. I sent a pull request to fix this:
      -;; https://github.com/wasamasa/eyebrowse/pull/94, however, vaslilly choosed
      -;; not to accept it. So, I need to configure the whole chords for every
      -;; function I use AND set the "prefix key" using the weird way above
      -;; (before loading).
      -(global-set-key (kbd "C-x C-x C-x")     'eyebrowse-last-window-config)
      -(global-set-key (kbd "C-x C-x ") 'eyebrowse-next-window-config)
      -(global-set-key (kbd "C-x C-x ")  'eyebrowse-prev-window-config)
      -(global-set-key (kbd "C-x C-x q")       'eyebrowse-close-window-config)
      -(global-set-key (kbd "C-x C-x t")       'eyebrowse-rename-window-config)
      -(global-set-key (kbd "C-x C-x n")       'eyebrowse-create-window-config)
      -(global-set-key (kbd "C-x C-x ?")       'hydra-eyebrowse/body)
      -
      -;; There's also some face config, see defcustom at end of file!
      -
      -;; *** Highlighting Indentation
      -;; provides: highlight-indentation-mode and highlight-indentation-current-column-mode
      -(require 'highlight-indentation)
      -
      -(add-something-to-mode-hooks
      - '(yaml python ruby) 'highlight-indentation-current-column-mode)
      -
      -(set-face-background 'highlight-indentation-face "#e3e3d3")
      -(set-face-background 'highlight-indentation-current-column-face "#c3b3b3")
      -
      -;; ** Emacs Interface
      -;; *** Parens
      -
      -;; display matching braces
      -(show-paren-mode 1)
      -
      -;; 'mixed: highlight all if the other paren is invisible
      -;; 'expression: highlight the whole sexp
      -(setq show-paren-style 'mixed)
      -
      -;; *** highlight todo keywords (such as FIXME)
      -
      -;; Absolutely needed!
      -
      -(require 'fic-mode)
      -(add-something-to-mode-hooks '(c c++ cperl vala web emacs-lisp ruby python) 'turn-on-fic-mode)
      -
      -;; --------------------------------------------------------------------------------
      -;; *** UNDO Tree Mode
      -
      -;; Better undo, with redo support.
      -
      -;; C-_   (`undo-tree-undo')
      -;;   Undo changes.
      -;;
      -;; C-:   (`undo-tree-redo')
      -;;   Redo changes.
      -;;
      -;; more: see undo-tree.el
      -(require 'undo-tree)
      -
      -;; use always
      -(global-undo-tree-mode)
      -
      -;; M-_ catched by Xmonad
      -(global-set-key (kbd "C-:")             'undo-tree-redo)                                  ; C-: == REDO   C-_ == UNDO
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Smarter M-x Mode (smex)
      -
      -;; This is really cool and I don't know how I could ever live without it.
      -
      -;; fails @win, so wrap it
      -(safe-wrap
      - (progn
      -   (require 'smex)
      -   (smex-initialize)
      -   (global-set-key (kbd "M-x") 'smex)
      -   (global-set-key (kbd "M-X") 'smex-major-mode-commands))
      - (message "ignoring unsupported smex"))
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Smarter Search
      -
      -;; test, replace isearch-forward-regexp first only.
      -;; dir: ivy/
      -(require 'swiper)
      -(with-eval-after-load 'swiper
      -  (setq ivy-wrap t)
      -  (global-set-key "\C-s" 'swiper))
      -
      -;; *** Which Func
      -;; display current function - if any - in mode line
      -(add-something-to-mode-hooks
      -    '(c c++ cperl vala makefile ruby shell-script python)
      -    'which-func-mode)
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Show current-line in the Fringe
      -(require 'fringe-current-line)
      -(global-fringe-current-line-mode 1)
      -
      -;; also change the color (matching the mode line
      -(set-face-attribute 'fringe nil :foreground "NavyBlue")
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Recent Files
      -
      -;; You know the  file you edited yesterday had "kri"  in its name, but
      -;; where was it? You don't remember.  But don't worry, recent files is
      -;; your friend.  It shows the last  N files you edited  recently.
      -;; I use it permanently.
      -
      -;; see also: ido-mode and smex
      -
      -;; setup
      -(require 'recentf)
      -(require 'cl-lib)
      -(setq recentf-auto-cleanup 'never) ;; avoid stat() on tramp buffers
      -(recentf-mode 1)
      -
      -;; I like to have a longer list reaching deeper into the past
      -(setq recentf-max-menu-items 200
      -      recentf-max-saved-items nil)
      -
      -;; enable IDO completion
      -;; via [[http://emacsredux.com/blog/2013/04/05/recently-visited-files/][emacsredux]]
      -;; modified to exclude already visited files
      -(defun tvd-buffer-exists-p (bufname)
      -  (not (eq nil (get-file-buffer bufname))))
      -
      -(defun recentf-ido-find-file ()
      -  "Find a recent file using ido."
      -  (interactive)
      -  (let ((file (ido-completing-read
      -               "Choose recent file: "
      -               (cl-remove-if 'tvd-buffer-exists-p recentf-list) nil t)))
      -    (when file
      -      (find-file file))))
      -
      -(global-set-key (kbd "C-x C-r")         'recentf-ido-find-file)                           ; open recent files, same as M-x rf
      -
      -;; now if I incidentally closed a  buffer, I can re-open it, thanks to
      -;; recent-files
      -(defun undo-kill-buffer (arg)
      -  "Re-open the last buffer killed.  With ARG, re-open the nth buffer."
      -  (interactive "p")
      -  (let ((recently-killed-list (copy-sequence recentf-list))
      -        (buffer-files-list
      -         (delq nil (mapcar (lambda (buf)
      -                             (when (buffer-file-name buf)
      -                               (expand-file-name (buffer-file-name buf)))) (buffer-list)))))
      -    (mapc
      -     (lambda (buf-file)
      -       (setq recently-killed-list
      -             (delq buf-file recently-killed-list)))
      -     buffer-files-list)
      -    (find-file
      -     (if arg (nth arg recently-killed-list)
      -       (car recently-killed-list)))))
      -
      -;; exclude some auto generated files
      -(setq recentf-exclude (list "ido.last"
      -                            "/elpa/"
      -                            ".el.gz$"
      -                            '(not (file-readable-p))))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** IDO mode
      -
      -;; There are other completion  enhancement packages available like ivy
      -;; for example,  but I love IDO  and I am so  used to it, it  would be
      -;; impossible to  change. So, I'll  stick with  IDO until end  of (my)
      -;; times.
      -
      -;; Hint: Use C-f during file selection to switch to regular find-file
      -
      -;; Basic config
      -(ido-mode t)
      -(ido-everywhere nil)
      -(setq ido-enable-flex-matching t)
      -(setq ido-use-filename-at-point nil)
      -(setq ido-use-virtual-buffers t)
      -(setq ido-auto-merge-work-directories-length -1)
      -
      -;; One thing annoys  me with IDO though: when writing  a new file, IDO
      -;; wants me  to select  from a  list of existing  files.  Since  it is
      -;; nearly impossible to disable ido mode for write-file, which I HATE,
      -;; I came up with this:
      -
      -;; I added a  new global variable, 'tvd-ido-disabled, which  is nil by
      -;; default. Whenever I  hit C-x C-w (in order  to execute write-file),
      -;; it will be  set to t, ido mode will  be disabled and ido-write-file
      -;; will be called.  Since ido mode is now disabled,  it just calls the
      -;; original write-file, which is what I really want.
      -
      -;; When I'm finished  selecting a filename and writing,  ido mode will
      -;; be turned  on again and the  variable will be set  to nil. However,
      -;; sometimes I may abort the process  using C-g. In that case ido mode
      -;; may end  up being disabled  because the  :after advice will  not be
      -;; called on C-g.
      -
      -;; So,  I   also  advice  the   minibuffer  C-g  function,   which  is
      -;; 'abort-recursive-edit, and  re-enable ido mode  from here if  it is
      -;; still disabled. So far I haven't seen any bad side effects of this.
      -
      -(defvar tvd-ido-disabled nil)
      -(advice-add 'ido-write-file :before '(lambda (&rest args) (ido-mode 0) (setq tvd-ido-disabled t)))
      -(advice-add 'ido-write-file :after  '(lambda (&rest args) (ido-mode 1) (setq tvd-ido-disabled nil)))
      -
      -(defun tvd-keyboard-quit-advice (fn &rest args)
      -  (when tvd-ido-disabled
      -    (ido-mode 1)
      -    (setq tvd-ido-disabled nil))
      -  (apply fn args))
      -
      -(advice-add 'abort-recursive-edit :around #'tvd-keyboard-quit-advice)
      -
      -;; from emacs wiki
      -;; Display ido results vertically, rather than horizontally
      -(setq ido-decorations (quote ("\n-> " "" "\n   " "\n   ..." "[" "]"
      -                              " [No match]" " [Matched]" " [Not readable]"
      -                              " [Too big]" " [Confirm]")))
      -
      -(defun ido-disable-line-truncation () (set (make-local-variable 'truncate-lines) nil))
      -(add-hook 'ido-minibuffer-setup-hook 'ido-disable-line-truncation)
      -(defun ido-define-keys ()
      -  (define-key ido-completion-map (kbd "") 'ido-next-match)
      -  (define-key ido-completion-map (kbd "") 'ido-prev-match))
      -(add-hook 'ido-setup-hook 'ido-define-keys)
      -
      -;; quickly go to home via ~ wherever I am
      -;; via [[http://whattheemacsd.com/setup-ido.el-02.html][whattheemacs.d]]
      -(add-hook 'ido-setup-hook
      - (lambda ()
      -   ;; Go straight home
      -   (define-key ido-file-completion-map
      -     (kbd "~")
      -     (lambda ()
      -       (interactive)
      -       (if (looking-back "/")
      -           (insert "~/")
      -         (call-interactively 'self-insert-command))))
      -   ;; same thing, but for ssh/tramp triggered by :
      -   (define-key ido-file-completion-map
      -     (kbd ":")
      -     (lambda ()
      -       (interactive)
      -       (if (looking-back "/")
      -           (progn
      -             (ido-set-current-directory "/ssh:")
      -             (ido-reread-directory))
      -         (call-interactively 'self-insert-command))))))
      -
      -;; by howardism: [re]open non-writable file with sudo
      -(defadvice ido-find-file (after find-file-sudo activate)
      -  "Find file as root if necessary."
      -  (unless (and buffer-file-name
      -               (file-writable-p buffer-file-name))
      -    (let* ((file-name (buffer-file-name))
      -           (file-root (if (string-match "/ssh:\\([^:]+\\):\\(.*\\)" file-name)
      -                          (concat "/ssh:"  (match-string 1 file-name)
      -                                  "|sudo:" (match-string 1 file-name)
      -                                  ":"      (match-string 2 file-name))
      -                        (concat "/sudo:localhost:" file-name))))
      -      (find-alternate-file file-root))))
      -
      -;; FIXME: add ido-ignore-files defun.
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Save cursor position
      -
      -;; So the  next time  I start  emacs and  open a  file I  were editing
      -;; previously,  (point) will  be  in  the exact  places  where it  was
      -;; before.
      -
      -(if (version< emacs-version "25.0")
      -    (progn
      -      (require 'saveplace)
      -      (setq-default save-place t))
      -  (save-place-mode 1))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** DoReMi experimentation
      -
      -;; I'm not using it a lot, sometimes I tune the background color though.
      -
      -;; via [[https://www.emacswiki.org/emacs/DoReMi][emacswiki/DoReMi]]
      -;; cool ones: doremi-buffers, doremi-all-faces-fg+ [s, h]
      -
      -(require 'doremi)
      -(require 'doremi-frm)
      -(require 'doremi-cmd)
      -
      -;; FIXME: find a good key
      -(defalias 'cb 'doremi-buffers+)
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Hightligt TABs
      -
      -;; not a mode, but however: higlight TABs in certain modes
      -
      -(defface extra-whitespace-face
      -  '((t (:background "pale green")))
      -  "Used for tabs and such.")
      -
      -(defvar tvd-extra-keywords
      -  '(("\t" . 'extra-whitespace-face)))
      -
      -(add-something-to-mode-hooks '(c c++ vala cperl emacs-lisp python shell-script ruby)
      -                             (lambda () (font-lock-add-keywords nil tvd-extra-keywords)))
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Browse kill-ring
      -
      -;; when active use n  and p to browse,  to  select, it's the same
      -;; as  and I never really use it...
      -
      -(require 'browse-kill-ring)
      -(setq browse-kill-ring-highlight-current-entry t
      -      browse-kill-ring-highlight-inserted-item t)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** goto-last-change
      -
      -;; Very handy, jump to last change[s].
      -
      -(require 'goto-last-change)
      -
      -(global-set-key (kbd "C-b")             'goto-last-change)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Bookmarks
      -
      -;; I use  the builtin bookmark feature  quite a lot and  am happy with
      -;; it.  Especially at  work, where  many  files are  located in  large
      -;; path's on remote storage systems, it  great to jump quickly to such
      -;; places.
      -
      -;; everytime bookmark is changed, automatically save it
      -(setq bookmark-save-flag 1
      -      bookmark-version-control t)
      -
      -;; I use the same aliases as in apparix for bash (since I'm used to them)
      -(defalias 'to        'bookmark-jump)
      -(defalias 'bm        'bookmark-set)
      -(defalias 'bl        'bookmark-bmenu-list)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** which-key
      -
      -;; One of the  best unobstrusive modes for key help  ever.  Just start
      -;; entering  a key  chord, prefix  or whatever,  and it  pops a  small
      -;; buffer (on the right side in my case) showing the avialable keys to
      -;; press from there along with the associated functions.
      -
      -(require 'which-key)
      -(which-key-mode)
      -(which-key-setup-side-window-right)
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** iBuffer mode
      -
      -;; iBuffer is a great interactive buffer management tool included with
      -;; emacs.   I  use  it  with  a   couple  of  custom  groups,  my  own
      -;; collapse-code () and formats.
      -
      -(require 'ibuffer)
      -
      -;; from github:
      -(require 'ibuffer-vc)
      -(require 'ibuffer-tramp)
      -
      -;; replace default list-buffers with ibuffer
      -(global-set-key (kbd "C-x C-b")         'ibuffer)
      -
      -;; group name
      -(setq tvd-ibuffer-filter-group-name "tvd-filters")
      -
      -;; filter group config
      -;; with hints from [[https://ogbe.net/emacsconfig.html][Ogbe]] et.al.
      -(setq ibuffer-saved-filter-groups
      -      (list (nreverse
      -             `(
      -               ("Org" (mode . org-mode))
      -               ("Shell" (or (mode . term-mode)
      -                            (mode . eshell-mode)
      -                            (mode . shell-mode)))
      -               ("Emacs-Config"  (filename . "emacs"))
      -               ("Cisco-Config" (mode . cisco-mode))
      -               ("Code" (or (mode . cperl-mode)
      -                           (mode . c-mode)
      -                           (mode . python-mode)
      -                           (mode . shell-script-mode)
      -                           (mode . makefile-mode)
      -                           (mode . cc-mode)))
      -               ("Text" (or (mode . text-mode)
      -                           (filename . "\\.pod$")))
      -               ("LaTeX" (mode . latex-mode))
      -               ("Interactive" (or
      -                               (mode . inferior-python-mode)
      -                               (mode . slime-repl-mode)
      -                               (mode . inferior-lisp-mode)
      -                               (mode . inferior-scheme-mode)
      -                               (name . "*ielm*")))
      -               ("Crab" (or
      -                        (name . "^\\*\\(Help\\|scratch\\|Messages\\)\\*")
      -                          ))
      -               ,tvd-ibuffer-filter-group-name))))
      -
      -;; Reverse the  order of the  filter groups. Kind of  confusing: Since
      -;; I'm reversing the  order of the groups above,  this snippet ensures
      -;; that the groups are ordered in the way they are written above, with
      -;; the "Default" group on top. This  advice might need to be ported to
      -;; the new advice system soon.
      -
      -(defadvice ibuffer-generate-filter-groups
      -    (after reverse-ibuffer-groups () activate)
      -  (setq ad-return-value (nreverse ad-return-value)))
      -
      -(defun ibuffer-add-dynamic-filter-groups ()
      -  (interactive)
      -  (dolist (group (ibuffer-vc-generate-filter-groups-by-vc-root))
      -    (add-to-list 'ibuffer-filter-groups group))
      -  (dolist (group (ibuffer-tramp-generate-filter-groups-by-tramp-connection))
      -    (add-to-list 'ibuffer-filter-groups group)))
      -
      -(defun tvd-ibuffer-hooks ()
      -  (ibuffer-auto-mode 1)
      -  (ibuffer-switch-to-saved-filter-groups tvd-ibuffer-filter-group-name)
      -  (ibuffer-add-dynamic-filter-groups))
      -(add-hook 'ibuffer-mode-hook 'tvd-ibuffer-hooks)
      -
      -;; Only show groups that have active buffers
      -(setq ibuffer-show-empty-filter-groups nil)
      -
      -;; Don't show the summary or headline
      -(setq ibuffer-display-summary nil)
      -
      -;; do not prompt for every action
      -(setq ibuffer-expert t)
      -
      -;; buffers to always ignore
      -(add-to-list 'ibuffer-never-show-predicates "^\\*\\(Completions\\|tramp/\\)")
      -
      -;; Use human readable Size column instead of original one
      -(define-ibuffer-column size-h
      -  (:name "Size" :inline t)
      -  (cond
      -   ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
      -   ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0)))
      -   ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
      -   (t (format "%8d" (buffer-size)))))
      -
      -;; Modify the default ibuffer-formats
      -(setq ibuffer-formats
      -      '((mark modified read-only " "
      -              (name 20 40 :left :elide)
      -              " "
      -              (size-h 9 -1 :right)
      -              " "
      -              (mode 16 16 :left :elide)
      -              " "
      -              filename-and-process)))
      -
      -;; hide annoying groups, but keep its buffers available
      -(defvar ibuffer-collapsed-groups (list "Crab"))
      -
      -(advice-add 'ibuffer :after '(lambda (&rest args)
      -  (ignore args)
      -  (save-excursion
      -    (dolist (group ibuffer-collapsed-groups)
      -      (ignore-errors
      -        (ibuffer-jump-to-filter-group group)
      -        (ibuffer-toggle-filter-group))))))
      -
      -;; move point to most recent buffer when entering ibuffer
      -(defadvice ibuffer (around ibuffer-point-to-most-recent) ()
      -           "Open ibuffer with cursor pointed to most recent (non-minibuffer) buffer name"
      -           (let ((recent-buffer-name
      -                  (if (minibufferp (buffer-name))
      -                      (buffer-name
      -                       (window-buffer (minibuffer-selected-window)))
      -                    (buffer-name (other-buffer)))))
      -             ad-do-it
      -             (ibuffer-jump-to-buffer recent-buffer-name)))
      -(ad-activate 'ibuffer)
      -
      -;; override ibuffer M-o binding
      -(define-key ibuffer-mode-map (kbd "M-o")    'other-window-or-switch-buffer)
      -
      -
      -;; --------------------------------------------------------------------------------
      -
      -;; *** Printing
      -;; overwrites printing default menu, access via menu File => Print
      -;; or:
      -;; - M-x ps-spool-buffer-with-faces
      -;; - go to *spool* buffer
      -;; - save to .ps file
      -;; - print
      -(require 'printing)
      -(pr-menu-bind)
      -
      -;; via [[https://emacs.stackexchange.com/questions/9364/convert-a-text-buffer-to-a-pdf-file][stackoverflow]]
      -(when (executable-find "ps2pdf")
      -  (defun print-to-pdf (&optional filename)
      -    "Print file in the current buffer as pdf, including font, color, and
      -underline information.  This command works only if you are using a window system,
      -so it has a way to determine color values.
      -
      -C-u COMMAND prompts user where to save the Postscript file (which is then
      -converted to PDF at the same location."
      -    (interactive (list (if current-prefix-arg
      -                           (ps-print-preprint 4)
      -                         (concat (file-name-sans-extension (buffer-file-name))
      -                                 ".ps"))))
      -    (ps-print-with-faces (point-min) (point-max) filename)
      -    (shell-command (concat "ps2pdf " filename))
      -    (delete-file filename)
      -    (message "Deleted %s" filename)
      -    (message "Wrote %s" (concat (file-name-sans-extension filename) ".pdf"))))
      -
      -;; --------------------------------------------------------------------------------
      -;; *** Beacon mode (pointer blink)
      -;; Source: [[https://github.com/Malabarba/beacon][beacon mode]]
      -
      -;; Blink the cursor shortly when  moving across large text sections or
      -;; when changing  windows. That way it  is easier to find  the current
      -;; editing position.
      -
      -(require 'beacon)
      -
      -(setq beacon-blink-duration 0.1
      -      beacon-blink-when-point-moves-vertically 10
      -      beacon-color 0.3)
      -
      -(add-hook 'beacon-dont-blink-predicates
      -          (lambda () (bound-and-true-p novel-mode)))
      -
      -(beacon-mode)
      -
      -;; --------------------------------------------------------------------------------
      -;; ** mode-line setup (must be the last mode)
      -
      -;; I just append the current version  of my emacs config and leave out
      -;; some stuff  to keep the modeline  short, so that everything  can be
      -;; seen even if I have multiple windows open.
      -
      -;; smaller pos
      -(setq-default mode-line-position
      -              '((-3 "%p") (size-indication-mode ("/" (-4 "%I")))
      -                " "
      -                (line-number-mode
      -                 ("%l" (column-number-mode ":%c")))))
      -
      -;; when macro recording is active,  signal it with coloring instead of
      -;; just a character
      -(defface rec-face
      -  '((t (:background "red" :foreground "white" :weight bold)))
      -  "Flag macro recording in mode-line"
      -  :group 'tvd-mode-line-faces)
      -
      -;; custom modeline
      -(setq-default mode-line-format
      -              (list
      -               "%e"
      -               mode-line-front-space
      -               mode-line-mule-info
      -               mode-line-modified
      -               mode-line-remote
      -               "  "
      -               mode-line-buffer-identification
      -               "  "
      -               mode-line-position
      -               " (%m) "
      -
      -               " [" tvd-emacs-version "] "
      -
      -               ; added because of eyebrowse
      -               mode-line-misc-info
      -
      -               '(:eval (propertize
      -                        (if (eq defining-kbd-macro t)
      -                            "[REC]"
      -                          "")
      -                        'face 'rec-face))
      -
      -               mode-line-end-spaces))
      -
      -;; --------------------------------------------------------------------------------
      -;; * Emacs Autoconfig / Customize group / final stuff
      -;; --------------------------------------------------------------------------------
      -;; ** font faces
      -;; Font color config, must always be the last thing so all hook faces are loaded.
      -
      -;; show available colors:
      -(defalias 'colors 'list-colors-display)
      -
      -;; from 20181227 I outsourced my font  config into a theme, located in
      -;; .emacs.d/tom-past-century.el,  so that  I  can  load another  theme
      -;; anytime I  like AND  switch back  to my  own config  w/o restarting
      -;; emacs
      -(add-hook 'after-init-hook (lambda () (load-theme 'tom-past-century t)))
      -
      -;; unless we're on windoze
      -(if (not (null tvd-win-home))
      -    (set-face-font 'default "Courier New"))
      -
      -;; --------------------------------------------------------------------------------
      -;; ** emacs server
      -
      -;; [[http://lists.gnu.org/archive/html/bug-gnu-emacs/2018-06/msg00723.html][Based on this]]
      -;; I check both predicates, just to be sure, only one of them doesn't work.
      -
      -;; FIXME: check if 'server-socket-dir/server exists as well
      -(require 'server)
      -(unless (or (server-running-p)
      -            (and (boundp 'server-process) server-process))
      -  (progn
      -    (advice-add 'save-buffers-kill-terminal :before
      -                (lambda (&rest args) (server-edit)))
      -    (server-start)))
      -
      -;; --------------------------------------------------------------------------------
      -;; ** variables
      -
      -;; If I  ever use custom-group  to customize a  mode, then I  create a
      -;; manual config  section for  it using the  values, custom  has added
      -;; here. So, in normal times this should be empty, but needs to exist.
      -
      -(custom-set-variables
      - ;; custom-set-variables was added by Custom.
      - ;; If you edit it by hand, you could mess it up, so be careful.
      - ;; Your init file should contain only one such instance.
      - ;; If there is more than one, they won't work right.
      - '(custom-safe-themes
      -   (quote
      -    ("d88c43fe03ac912e35963695caf0ae54bc6ce6365c3a42da434ef639f7a37399" default)))
      - '(package-selected-packages (quote (magit)))
      - '(safe-local-variable-values (quote ((ruby-indent-level 4)))))
      -
      -;; ** done
      -
      -;; Finally, this message is being displayed.  If this isn't the case I
      -;; know easily that something went wrong.
      -
      -(message "loading done")
      -(custom-set-faces
      - ;; custom-set-faces was added by Custom.
      - ;; If you edit it by hand, you could mess it up, so be careful.
      - ;; Your init file should contain only one such instance.
      - ;; If there is more than one, they won't work right.
      - )
      diff --git a/CHANGELOG.org b/CHANGELOG.org
      new file mode 100644
      index 0000000..0551edf
      --- /dev/null
      +++ b/CHANGELOG.org
      @@ -0,0 +1,793 @@
      +* Changelog
      +
      +** 20160420.03:
      +   - started with Changelog and outshine mode
      +   - fixed tabs
      +   - reorganized keys
      +   - added new goto line func
      +
      +** 20160421.01:
      +   - added smex
      +   - added show-keys()
      +   - added redo
      +   - ssh et. al. interactive in eshell
      +   - added recompile()
      +
      +** 20160421.02:
      +   - added dividers
      +   - using org headers
      +   - better show-keys()
      +
      +** 20160421.03:
      +   - added windows support
      +
      +** 20160421.04:
      +   - added elisp repl support
      +
      +** 20160424.01:
      +   - added custom modeline
      +   - added which-func-mode
      +   - shortened some major mode names
      +   - added diminish for shorter minor mode names
      +   - added better printing menu
      +
      +** 20160425.01:
      +   - fixed ielm integration
      +   - C-x e    = eval (buffer|region)
      +   - C-x C-e  = send (buffer|region) to ielm and eval there
      +
      +** 20160425.02:
      +   - fix word wrapping
      +
      +** 20160426.01:
      +   - fixed mode-line config 4 win emacs
      +   - added M- move-region
      +
      +** 20160426.01:
      +   - added markdown
      +
      +** 20160427.01+02:
      +   - cosmetics
      +
      +** 20160428.01:
      +   - fringe cursor
      +
      +** 20160429.01:
      +   - file name completion
      +   - C-#  finally, search for symbol at point
      +   - C-c C-c now comments or uncomments regios or line, whatever is current
      +
      +** 20160501.01:
      +   - no outshine minor in python
      +   - added recent files support
      +
      +** 20160501.02:
      +   - added margin() function, no key binding though
      +
      +** 20160503.01:
      +   - added C-q fill+justify paragraph macro
      +   - added alias 'i' for info manuals
      +
      +** 20160503.02:
      +   - added 'cp to create read-only buffer copy
      +
      +** 20160504.01:
      +   - better fringe, now also inversed with C-c i
      +
      +** 20160505.01:
      +   - added electric-align mode
      +   - better outline header colors
      +   - no more line numbers in sk occur buffer
      +
      +** 20160507.01:
      +   - disable electric-align-momde (broken), using M-x align instead
      +   - hightlighting TABs with extra font
      +
      +** 20160509.01:
      +   - fixed margin()
      +   - discovered that C-x 0 deletes current window, god did I miss this one!
      +
      +** 20160510.01:
      +   - added kill-all-buffers()
      + 
      +** 20160510.02:
      +   - no more load-file
      +   - added C-c [wlpa]: easy copy things at point
      +     without marking them
      +
      +** 20160511.01:
      +   - better buffer names with uniquify
      +
      +** 20160511.02:
      +   - copy-* functions now blink region
      +   - added del-* functions, bound to C-d:
      +     press multiple times to delete word, line, paragraph, buffer
      +
      +** 20160513.01:
      +   - fixed END key func
      +
      +** 20160516.01:
      +   - removed C-d stuff, replaced with vikiing-mode
      +
      +** 20160517.01:
      +   - changed highlight face
      +   - enabled debug-on-error in lispmode
      +   - enabled IDO mode globally, I just tend to love love love it
      +
      +** 20160517.02:
      +   - added workgroup.el, started experimenting
      +   - enabled Super_L (for workgroups)
      +
      +** 20160519.01:
      +   - fixed write-file, now ido mode is disabled for this one.
      +
      +** 20160520.01:
      +   - no x-sel on windows (C-v+C-c => emacs doesn't work anymore otherwise)
      +   - added eldoc mode to elisp hook
      +
      +** 20160520.02:
      +   - added novel-mode, for better reading
      +
      +** 20160522.01:
      +   - added vi's % jump paren emulation
      +   - enhanced novel-mode
      +   - enabled save-place mode which is VERY useful in combination with
      +     novel-mode
      +
      +** 20160523.01:
      +   - detached novel-mode into its own module, maintain on github
      +     enabled with C-n
      +
      +** 20160526.01:
      +   - added toggle-melpa
      +
      +** 20160527.01:
      +   - added htmlize
      +
      +** 20160529.01:
      +   - added html-listify
      +
      +** 20160530.01:
      +   - added key chords
      +   - added open-line-above+below
      +
      +** 20160602.01:
      +   - C-q now fills and pressing it again un-fills
      +
      +** 20160606.01:
      +   - deactivated key-chords, I didn't use them and they were annoying.
      +
      +** 20160609.01:
      +   - added puppet mode
      +
      +** 20160614.01:
      +   - added rotate-text (C-t)
      +   - added macro math  (C-x-0) (0 used as =)
      +
      +** 20160713.01:
      +   - fixed indent for Makefiles
      +
      +** 20160729.01:
      +   - rm duplicate abbr defs
      +
      +** 20160916.01:
      +   - enable mouse mark to copy
      +
      +** 20160926.01:
      +   - Dont kill-buffer, kill-this-buffer instead
      +
      +** 20160928.01:
      +   - change macro math C-x 0 to C-x C-0 so that C-0 is
      +     usable again for close window
      +   - elisp mode: debug-on-error only on non-cygwin
      +
      +** 20161011.01:
      +   - added dos2unix and unix2dos
      +
      +** 20161014.01:
      +   - fix auto-indent in conf-mode
      +   - force C-c C-c comment-uncomment in conf-mode
      +
      +** 20161018.01:
      +   - more effective conf-mode disarming (own defun)
      +
      +** 20161022.01:
      +   - better paren mode
      +
      +** 20161024.01:
      +   - fixed org mode hook
      +
      +** 20161027.01:
      +   - turn off tramp stuff in kill-all-buffers as well,
      +     so that after executing it, no more ssh prompt
      +     appears on C-x f.
      +
      +** 20161106.01:
      +   - added iedit mode with C-c e
      +   - added file-open support to eshell (aliases: vi + emacs)
      +   - much better C-l behavior in eshell (eshell/clear)
      +
      +** 20161205.01:
      +   - added SLIME, sbcl and paredit support, only loaded when exists
      +
      +** 20161206.01:
      +   - elisp mode: debug-on-error finally completeley disabled
      +   - added alias 'table, which enables org-mode table support everywhere
      +
      +** 20170205.01:
      +   - started with ETAGS support
      +
      +** 20170212.01:
      +   - added copy-defun (C-c f) to copy whole functions as is
      +
      +** 20170212.02:
      +   - now using € (alt-r + e) as jump to etag
      +
      +** 20170215.02:
      +   - added goto-last-change (C-b)
      +   - +test section
      +   - paredit
      +
      +** 20170215.02:
      +   - disabled workgoups mode, don't use it, doesn't load correctly
      +   - fixed windows switch, no more printing popup on startup
      +
      +** 20170220.01:
      +   - finally disabled aggressive-indent, it annoys more than it helps
      +   - added some bookmark aliases (bm, to, bl, like apparix)
      +   - added C-c y [..] copy+yank functions so that I can copy and paste
      +     stuff very fast with one key commbo, like yy in vi.
      +   - added copy-parens, copy-quote, copy-help (help message)
      +
      +** 20170220.02:
      +   - fixed C-c y y: indent correctly
      +
      +** 20170220.03:
      +   - fixed C-y+mouse-2: both use primary selection
      +
      +** 20170221.01:
      +   - added which-key
      +
      +** 20170223.01:
      +   - org-mode enhancements, C-n capture from everywhere
      +   - fixed org-mode todo keywords
      +   - fixed duplicate yank on win32 on mouse2
      +
      +** 20170223.01:
      +   - forgot to mv novel-mode to C-c C-n
      +   - better org heading faces
      +
      +** 20170224.01:
      +   - finally fixed C-t, now works everywhere
      +   - added more org short commands
      +
      +** 20170224.02:
      +   - fixed org-mode M-return
      +   - added support for windmove (WINDOWS-Key+Arrow: switch window)
      +
      +** 20170224.03:
      +   - better org colours
      +
      +** 20170224.03:
      +   - better org capture tpl (DRAFT)
      +   - capturing works now globally, even if no org file is open
      +   - using org-indent 4
      +
      +** 20170224.05:
      +   - fixed org tpls
      +
      +** 20170227.01:
      +   - fix cut/paste org subtress
      +   - M-o now switch buffer if 1 window, else switch window
      +
      +** 20170227.02:
      +   - added alias 'dp which displays everything
      +     there is to know about point (like current face, mode, etc)
      +
      +** 20170228.01:
      +   - org-refile now works recursivly with completion
      +   - org-refile also now uses ido-mode and completes in minibuffer
      +   - added alias '2table which converts CSV region to table
      +   - added shortcut formatting defuns 'bold, 'italic, 'underline and 'code
      +     which call 'org-emphasize respectively on current region,
      +     including key bindings with org mode keymap (C-c b,/,c,_)
      +   - hide emphasized markers in org mode
      +   - renamed 'recompile to 'recompile-el and fixed it
      +   - added 'info-find-file
      +
      +** 20170301.01:
      +   - added 'tvd-org-left-or-level-up bound to  in org mode
      +   -  in org mode now jump up on current level and
      +     fold current one and unfolds the target heading
      +   - enabled org-bullets
      +   - customized height of org-level faces
      +
      +** 20170301.02:
      +   - org mode emphasize shortcuts (C-c b...) expand region if
      +     theres no region active.
      +
      +** 20170301.03:
      +   - dis line num in org (faster)
      +
      +** 20170303.01:
      +   - elmacro support added, incl fix for org and outshine,
      +     F6 starts (or stops) a macro and displays the generated
      +     defun. CTRL-F6 executes the last macro interactively,
      +      repeats, a repeats til EOF, q aborts, e  enter macro
      +     (with completion)
      +   - C-x C-s on * elmacro ... * buffer stores it to tvd-macro-file
      +
      +** 20170305.01:
      +   - added elmacro defadvice, run after done with macro, it will
      +     be evaluated and saved along with a repeater defun.
      +   - display red [REC] hint on the mode-line while recording
      +   - added ~ shortcut for use inside IDO so I can reach $HOME
      +     very fast from everywhere, no more editing pre-filled
      +     current path and entering /home/$user/. Yeah!
      +   - added flip-window (bound to M-O (ALT-shift-o)
      +   - added cleanup-buffer (alias cb)
      +   - fixed C- and C-S-
      +
      +** 20170306.01:
      +   - re-enabled linenum mode
      +   - fixed custom modeline
      +
      +** 20170306.01:
      +   - which-func not in elisp anymore
      +   - added alias 'ee for 'eval-expression
      +   - added 'sa (show-aliases)
      +   - some occur enhancements for 'sk and 'sa.
      +   - note: inside *Occur*: q:quit, g:reload, e:edit (buffer must be open)
      +
      +** 20170307.01:
      +   - fixed 'sk and 'sa
      +   - added key bindings to mark things. M-a is the prefix, followed by:
      +     a - all, p - paragraph, f - function, l - line, w - word.
      +   - disabled M-O (flip-windows) on console emacs
      +
      +** 20170309.01:
      +   - added C-c s,u,e and M-a s,u,e
      +
      +** 20170309.02:
      +   - re-enabled paredit, its better in ielm and slime
      +   - added alias 'pe to quickly enable/disable par-edit
      +   - added virtual eShell dev /dev/log which stores stuff in *LOG*
      +
      +** 20170313.01:
      +   - iedit to C-c C-e, so C-c e works again (copy email)
      +   - put eshell aliases into .emacs(here) no need for aliases file anymore
      +   - added copy-comment (C-c c), copy-and-yank-comment (C-c y c) and
      +     m-mark-comment (M-a c)
      +
      +** 20170314.01:
      +   - enhanced copy-comment (that is, rewrote it), it now supports
      +     indented multiline comments
      +
      +** 20170315.01:
      +   - fixed C-c y [cpwf]
      +   - fixed copy[+yank+mark] word, it now includes - _ .
      +   - added copy-ip (C-c i), yank-ip (C-c y i) and mark-ip (M-a i)
      +   - copy-url alternatively copies file-path if it's no url at point
      +   - added numerical arg support to yy
      +
      +** 20170321.01:
      +   - rewrote copy-comment stuff, now supports blocks of comment
      +     after code etc.
      +
      +** 20170323.01:
      +   - moved the mark,copy,yank stuff into its own mode
      +
      +** 20170327.01:
      +   - added defadvice for mcyt mode, so that I can use C-v to
      +     always yank the last thing copied.
      +
      +** 20170502.01:
      +   - added config for ibuffer
      +
      +** 20170503.01:
      +   - added ibuffer-vc support
      +
      +** 20170503.02:
      +   - added ibuffer-tramp support
      +   - disabled ibuffer tab-collaps stuff
      +
      +** 20170505.01:
      +   - generalized init-dir+file variables, now more portable, i hope
      +
      +** 20170508.01:
      +   - backup tramp files remote
      +   - do not backup emacs state files
      +
      +** 20170509.01:
      +   - version fix
      +
      +** 20170523.01:
      +   - commented ssh backup stuff, not working yet, destroys tramp
      +   - added inferior shells for perl, ruby and python (iperl, iruby, ipython)
      +     with ansi-term
      +
      +** 20170610.01:
      +   - org mode: added C-c C-# to edit src blocks in an extra window
      +   - org mode:  opens link in eww
      +   - ido-find-file advice: if not writable, try sudo/tramp
      +   - +eshell-there remote eshell (Alias: et)
      +   - disabled pager in eshell
      +   - fixed eshell/x, now uses C-d
      +   - org mode: DONE makes heading greyish
      +   - re-organized emacs config, now with subsections
      +   - removed lisp electric return, destroyed almost all modes
      +   - added POD mode with specific abbrevs and including specific outlining
      +   - added heading cycle code for outline mode as well
      +   - added outline 'n (narrow) + 'w (widen)
      +   - added orange fringe for narrowing (org, outline and everywhere else
      +   - added alias 'colors
      +   - added 'dl (aka describe-library to display the doc string in
      +;       COMMENTARY section of .el files
      +   - added "C-c t" to copy an org mode cell
      +   - ena org pretty entities, list: org-entities-help
      +   - 2table => tablify, which is now a function and uses region or whole buffer
      +   - added indirect narrowing buffers
      +   - renamed all occurences of my- to tvd- so I better know which stuff is mine
      +   - added table-to-* org table exporters with aliases
      +   - inside org mode: C-c o copy table c[o]lumn, C-c t copy [t]able cell
      +   - experimental: added beacon mode (blinking pointer)
      +     (moved 'seq from exp. elpa to lisp/)
      +   - added render-html to render current html buffer with eww
      +   - added align-regexp-repeat[-left|right] wrappers
      +   - fixed org mode C- jump paragraphs if not on heading
      +   - added 'tvd-outshine-jump (alias 'j) to directly jump to headers
      +     with IDO completion and as sparse-tree, very cool!
      +     mapped to C-c C-j
      +   - added *text* scratch buffer with text mode
      +   - added jump-paren-match-or-insert-percent, bound to %, which jumps parens
      +     or inserts a % if not on a paren. Better than C-5, haha.
      +   - added 'ffxs
      +   - added emacs-change-log
      +   - removed GNUS config, not used anymore
      +   - restored C-d binding to viking in paredit
      +   - added outshine HTML exporter via org: outshine-to-html
      +   - fixed outshine config
      +   - added (my) config-general-mode
      +   - fixed pod format inserters
      +
      +** 20170629.01:
      +   - added tablist-minor-mode (+config)
      +   - added config for tabulated-list-mode
      +   - added config for help-mode
      +   - added default filename for outshine-to-html
      +   - Info mode: C-left+C-right history keys
      +   - added loader for el2markdown
      +   - removed smart-forward, it annoys me
      +   - made tvd-outshine-jump more portable, do not use hardcoded
      +     regexps anymore, use outshine functions
      +   - added 'change-inner and ci simulators'
      +   - added suggest.el with my own reload function
      +   - modified recentf: do not provide files already visited
      +
      +** 20170703.01:
      +   - fixed recentf-exclude list, now REALLY ignores unreadables
      +   - added export for easier export and commit of dot-emacs
      +   - added tvd-suggest-jump to jump between input and output
      +
      +** 20170707.01:
      +   - added C-x 4 to split fram into 4 windows
      +   - fixed config-general-mode config
      +   - fixed 'emacs-change-log (didn't expand trees before work)
      +   - fix python loading
      +
      +** 20170711.01:
      +   - fixed outshine: only loaded with elisp
      +   - fixed tvd-outshine-jump: use imenu if outside outshine
      +   - fixed kill-all-buffers: restore scratch after killing all buffers
      +   - do not ask to save abbrevs on exit anymore
      +   - reformat changelog
      +   - rm open-line-below
      +
      +** 20170711.02:
      +   - fixed POD abbrevs, added way to move point after expansion
      +
      +** 20170712.01:
      +   - disabled org mode superscripts
      +   - + winner mode
      +   - org mode 'code new binding: C-c 0
      +   - fixed emacs-change-log
      +   - added tvd-outshine-end-of-section incl speed command
      +
      +** 20170712.02:
      +   - fixed tvd-outshine-end-of-section, it's way faster now and
      +     works without narrowing.
      +
      +** 20170714.01:
      +   - fixed pod-mode abbrev cursor jumping if no jump pos exists
      +   - fix initial-buffer-choice
      +   - added mmm-mode
      +   - added here-doc support to config-general using mmm-mode
      +   - made outline faces a little bigger, added face for level 4
      +   - rm initial buffer, doesnt open commandline files anymore with this
      +   - finally initial buffer works, opens command line file or text scratch
      +
      +** 20170715.01:
      +   - no more MMM for C::G, destroys indent
      +   - incorporated my C::G customizations, Steve Purcell removed from
      +     it because inappropriate,
      +     [[https://github.com/TLINDEN/config-general-mode/commit/d7e8323][see d7e8323]]
      +   - fixed autoscratch hook
      +   - add scratch alias
      +
      +** 20170718.01:
      +   - better autoscratch config
      +   - added persistent-scratch mode
      +
      +** 20170719.01:
      +   - fixed electric-indent in autoscratch config
      +   - use my own autoscratch triggers
      +   - kill-all-buffers now uses 'autoscratch-buffer
      +   - renamce autoscratch
      +   - tuned recenter-positions
      +
      +** 20170722.01:
      +   - added followcursor-mode
      +
      +** 20170724.01:
      +   - added ido completion for tramp hostnames
      +
      +** 20170725.01:
      +   - autoscratch lambda=>progn
      +   - added sort-table-ip[desc] and fixed auto-alignment so
      +     that ip's are left aligned
      +   - +req org-table
      +
      +** 20170727.01:
      +   - +magit
      +   - configured magit dirs
      +   - +magit ido
      +   - fix magit info dir
      +
      +** 20170730.01
      +   - +some magit navigation keys
      +
      +** 20170731.01
      +   - do not load magit on w32
      +   - Always call `magit-status' with prefix arg
      +   - do bigger jumps in magit with just C-
      +   - add "ls" to magit-status leading to dired
      +
      +** 20170801.01
      +   - added C command to magit to switch repo
      +   - add : trigger for ido-find-file to begin with tramp
      +
      +** 20170802.01
      +   - +table-to-excel
      +   - added some git wrappers to dired to add or rm files
      +
      +** 20170805.01
      +   - +C-c C-c for rename files in dired
      +
      +** 20170807.01
      +   - added dired config and functions
      +   - added dired-hacks: ranger and filters, enhanced navigation commands
      +
      +** 20170808.01
      +   - (i) is now a function, not an alias anymore and more comfortable
      +   - added org info path
      +   - added info+
      +
      +** 20170821.01
      +   - highlight line color light green with default bg
      +
      +** 20170901.01
      +   - added :jump-to-captured to org capture templates,
      +     didn't know about it before
      +
      +** 20170913.01
      +   - disabled outline in config-general-mode
      +
      +** 20170924.01
      +   - experimenting swiper
      +
      +** 20171201.01
      +   - highlight TABs with ruby as well
      +
      +** 20171205.01
      +   - fixed ORG template headings
      +
      +** 20180210.01
      +   - added ediff config
      +   - fixed ob-sh to ob-shell
      +
      +** 20180730.01
      +   - added autoscratch-reset-default-directory t
      +
      +** 20181004.01
      +   - added projectile and config
      +   - added hydra and config (for org tables and projectile)
      +   - finished org table hydra
      +   - added info hydra, fixed 't bug
      +
      +** 20181016.01
      +   - fixed dired under cygwin w/o git
      +
      +** 20181019.01
      +   - using C-x for all hydras now:
      +     C-x w: windows
      +     C-x t: org table
      +     C-y p: projectile
      +   - added copy org table row
      +   - enhanced window hyrda by resizing chords
      +   - changed table copy key chords (C-c t [ctr]
      +
      +
      +   - better windows hydra
      +   - on help close restore windows setup
      +   - fixed hydra hints
      +
      +** 20181021.01
      +   - fixed window resizing
      +
      +** 20181022.01
      +   - enhanced M-o for window switching a lot, using a hydra and the arrow keys
      +
      +** 20181029.01
      +   - fixed recentf max files
      +
      +** 20181030.01
      +   - fixed windows hydra flip window call
      +
      +** 20181105.01
      +   - added eyebrowse with config and hydra, prefix: C-x C-x
      +
      +** 20181106.01
      +   - close help windows regularly again
      +
      +** 20181107.01
      +   - removed debug toggle
      +   - added magit status window new "q" feature which kills
      +     all magit buffers and restores window setup
      +   - added magit status margin timestamps
      +
      +** 20181107.01
      +   - fixed  function, inserts  at ()
      +   - added / to dired hydra
      +
      +** 20181110.01
      +   - fixed % function, really
      +   - fixed elisp autoscratch config
      +
      +** 20181111.01
      +   - fixed autoscratch elisp trigger
      +   - started with smartparens, first config just replaces paredit
      +
      +** 20181113.01
      +   - disabled paredit, enabled smartparens
      +
      +** 20181115.01
      +   - disabled smartparens strict mode, much annoying
      +   - map C-k to 'sp-kill-hybrid-sexp
      +
      +** 20181117.01
      +   - disabled outline C- it overwrote sp slurp left
      +   - enhanced emacs-changelog
      +   - fixed parens bug, added sp ti monibuffer
      +   - added tvd-lisp-comment
      +   - (re-)added electric pair mode to eval-expression
      +   - diret -lt
      +
      +** 20181121.01
      +   - added org agenda
      +
      +** 20181122.01
      +   - + new agenda o function
      +
      +** 20181126.01
      +   - unlimited recentf
      +
      +** 20181127.01
      +   - fixed tvd-replace-all
      +   - fixed agenda capture template
      +
      +** 20181127.02
      +   - fixed C-up|down in agenda
      +
      +** 20181206.01
      +   - added support for scheduled agenda entries and fixed tvd-replace-all
      +     (I already had this in 20181123 but overwrote it somehow!)
      +
      +** 20181210.01
      +   - fixed agenda g command
      +
      +** 20181212.01
      +   - configured agenda sorting
      +
      +** 20181212.02
      +   - fixed agenda sorting, must be global
      +
      +** 201812** 20.01
      +   - added org table move cells functions
      +
      +** 20181222.01
      +   - removed duplicate key bindings, added via comment
      +
      +** 20181227.01
      +   - ena variable pitch w/ org, turned face config into theme
      +
      +** 20190108.01
      +   - added server
      +
      +** 20190112.01
      +   - added wdired cleanup function
      +
      +** 20190112.02
      +   - enhanced cleaner
      +
      +** 20190114.01
      +   - disabled variable pitch, annoys me
      +
      +** 20190214.01
      +   - fixed C-c C-c in shell-script-mode
      +
      +** 20190226.01
      +   - unbound F6 and F5 from cperl mode
      +
      +** 20190412.01
      +   - added yaml mode and highlight indent mode
      +
      +** 20190513.01
      +   - added scheduled task org capture template along with wrappers etc
      +
      +** 20190520.01
      +   - fixed 'n' in agenda, added 'k', fixed scheduled task template
      +
      +** 20190521.01
      +   - split agenda window left
      +
      +** 20190705.01
      +   - added smerge hydra plus alias 'merge
      +   - fixed window resize hydra help
      +
      +** 20200902.01
      +   - added rust mode
      +
      +** 20200904.01
      +   - rust+smartparens
      +
      +** 20190923.01
      +   - added RCS
      +
      +** 20201126.01
      +   - -gh
      +
      +** 20210501.01
      +   - added golang support
      +
      +** 20220706.01
      +   - added smartparens to sh mode
      +
      +** 20220707.01
      +   - smartparens => go
      +
      +** 20220722.01
      +   - added yaml movement defuns and keys
      +
      +** 20230131.01
      +   - add ido-imenu
      +
      +** 20230207.01
      +   - set default font size
      +
      +** 20230329.01
      +   - fix magit
      +
      +** 20230405.01
      +   - fixed ibuffer-vc display, added solarized theme, added defaut-text-scale
      +
      +** 20230406.01
      +   - add fits git dir, incr default font size to suit solarized theme
      +
      +** 20230412.01
      +- adapted use-package, got rid of all locally installed packages
      +- use el-get for non-packages
      +- re-organized emacs config: ~/.emacs.d/init.el is now the starting point.
      +  ~/.emacs.d/conf-lisp/ contains init files (one per mode or topic) and
      +  ~/.emacs.d/init/ contains symlinks to them. That way it is very easy to
      +disable a module without needing to comment code or loosing something.
      +- put this repo directly into ~/.emacs.d/.
      diff --git a/README.md b/README.md
      index 7c3235a..ac08ea7 100644
      --- a/README.md
      +++ b/README.md
      @@ -1 +1,29 @@
      -You can read the [HTML export of my .emacs file](https://rawgit.com/TLINDEN/dot-emacs/master/emacs.html) or download the [original elisp file](https://raw.githubusercontent.com/TLINDEN/dot-emacs/master/.emacs).
      +# My Personal Emacs Configuration
      +
      +This is my personal emacs configuration.  It is more than 20 years old
      +and may contain obskure or outright nonsense code and customization.
      +
      +I use this live whereever I use emacs. You may try it at your own risk
      +or take a look as you wish.
      +
      +Please be advised,  that I'll not answer any issues  or other requests
      +for this repo.
      +
      +You can read the [HTML export of my OLD .emacs file here](https://rawgit.com/TLINDEN/dot-emacs/master/emacs.html).
      +
      +# How it works
      +
      +Check this repo out into `~/.emacs.d/`.
      +
      +The starting point is `init.el`,  it configures some global things and
      +initializes  the  package  manager.   It  then  loads  every  file  in
      +`~/.emacs.d/init/*.el`, which are symlinks to  the real load files.
      +
      +In order  to be able to  force a particular load  order, every symlink
      +contains a number in its name.
      +
      +To disable some module, just remove the symlink.
      +
      +# License
      +
      +GPLv3
      diff --git a/conf-lisp/ansiterm.el b/conf-lisp/ansiterm.el
      new file mode 100644
      index 0000000..d72bea2
      --- /dev/null
      +++ b/conf-lisp/ansiterm.el
      @@ -0,0 +1,77 @@
      +;; *** ANSI-TERM (inferior shells/interpreters and REPLs)
      +
      +;; I use ansi term for inferior shells only.
      +
      +;; via [[http://echosa.github.io/blog/2012/06/06/improving-ansi-term/][echosa]]
      +
      +;; kill buffer when done
      +(defadvice term-sentinel (around tvd-advice-term-sentinel (proc msg))
      +  (if (memq (process-status proc) '(signal exit))
      +      (let ((buffer (process-buffer proc)))
      +        ad-do-it
      +        (kill-buffer buffer))
      +    ad-do-it))
      +(ad-activate 'term-sentinel)
      +
      +;; force utf8
      +(defun tvd-term-use-utf8 ()
      +  (set-buffer-process-coding-system 'utf-8-unix 'utf-8-unix))
      +(add-hook 'term-exec-hook 'tvd-term-use-utf8)
      +
      +;; make C-y work
      +(defun tvd-term-paste (&optional string)
      +                      (interactive)
      +                      (process-send-string
      +                       (get-buffer-process (current-buffer))
      +                       (if string string (current-kill 0))))
      +
      +;; put all term hooks in here
      +(defun tvd-term-hook ()
      +  (goto-address-mode)
      +  (define-key term-raw-map (kbd "C-y") 'tvd-term-paste)
      +  (define-key term-raw-map (kbd "C-c C-d") 'kill-this-buffer)
      +  (define-key term-raw-map (kbd "C-d") 'kill-this-buffer)
      +  (define-key term-raw-map (kbd "C-c C-l") 'term-line-mode)
      +  (define-key term-raw-map (kbd "C-k")
      +    (lambda ()
      +      (interactive)
      +      (term-send-raw-string "\C-k")
      +      (kill-line))))
      +(add-hook 'term-mode-hook 'tvd-term-hook)
      +
      +;; via [[https://www.emacswiki.org/emacs/AnsiTermHints#toc4][emacswiki]]:
      +;; Use to supply commandline arguments to ansi-term
      +(defun term-with-args (new-buffer-name cmd &rest switches)
      +  (setq term-ansi-buffer-name (concat "*" new-buffer-name "*"))
      +  (setq term-ansi-buffer-name (generate-new-buffer-name term-ansi-buffer-name))
      +  (setq term-ansi-buffer-name (apply 'make-term term-ansi-buffer-name cmd nil switches))
      +  (set-buffer term-ansi-buffer-name)
      +  (term-mode)
      +  (term-char-mode)
      +  (message "Line mode: C-c C-l, Char mode: C-c C-k, Exit: C-c C-d")
      +  (switch-to-buffer term-ansi-buffer-name))
      +
      +;; finally the inferior REPLs:
      +(defun iperl ()
      +  "interactive perl (via perlbrew if exist or global)"
      +  (interactive)
      +  (let ((perlbrew (expand-file-name "~/perl5/perlbrew/bin/perlbrew")))
      +    (if (file-exists-p perlbrew)
      +        (term-with-args "*perlbrew-de0*" perlbrew "exec" "--" "perl" "-de0")
      +      (term-with-args "*perl-de0*" "perl" "-de0"))))
      +
      +(defun iruby ()
      +  "interactive ruby"
      +  (interactive)
      +  (term-with-args "*ruby-irb*" "irb"))
      +
      +(defun ipython ()
      +  "interactive python"
      +  (interactive)
      +  (setenv "PYTHONSTARTUP" (expand-file-name "~/.pythonrc"))
      +  (term-with-args "*python-i*" "python" "-i"))
      +
      +(defun icalc ()
      +  "interactive calc"
      +  (interactive)
      +  (term-with-args "*calc*" (expand-file-name "~/bin/calc")))
      diff --git a/conf-lisp/autoscratch.el b/conf-lisp/autoscratch.el
      new file mode 100644
      index 0000000..d2f97ed
      --- /dev/null
      +++ b/conf-lisp/autoscratch.el
      @@ -0,0 +1,49 @@
      +;; ** More scratch space
      +;; *** Text scratch
      +;; Sometimes  I need  a  text  mode scratch  buffer  while scratch  is
      +;; already in use. So let's prepare one. I also add a buffer hook so that
      +;; this never gets deleted, but cleaned instead.
      +
      +(with-current-buffer (get-buffer-create "*text*")
      +  (text-mode))
      +
      +;; *** Autoscratch
      +;; use autoscratch otherwise
      +;; [[https://github.com/TLINDEN/autoscratch][autoscratch github]]
      +(use-package autoscratch-mode
      +             :ensure nil
      +             :config
      +             (setq initial-major-mode 'autoscratch-mode)
      +             (add-hook 'autoscratch-mode-hook '(lambda ()
      +                                                 (setq autoscratch-triggers-alist
      +                                                       '(("[(;]"         . (progn
      +                                                                             (call-interactively 'emacs-lisp-mode)
      +                                                                             (call-interactively 'enable-paredit-mode)
      +                                                                             (call-interactively 'electric-pair-mode)))
      +                                                         ("#"            . (progn
      +                                                                             (call-interactively 'config-general-mode)
      +                                                                             (electric-indent-local-mode t)))
      +                                                         ("[-a-zA-Z0-9]" . (text-mode))
      +                                                         ("/"            . (c-mode))
      +                                                         ("*"            . (progn (insert " ") (org-mode)))
      +                                                         ("."            . (fundamental-mode)))
      +                                                       autoscratch-trigger-on-first-char t
      +                                                       autoscratch-reset-default-directory t)
      +                                                 (electric-indent-local-mode nil)
      +                                                 ))
      +             (defalias 'scratch 'autoscratch-buffer))
      +
      +;;; *** Persistent Scratch
      +;; I also like to be scratch buffers persistent with
      +;; [[https://github.com/Fanael/persistent-scratch][persistent-scratch]]
      +
      +(defun tvd-autoscratch-p ()
      +  "Return non-nil if the current buffer is a scratch buffer"
      +  (string-match "scratch*" (buffer-name)))
      +
      +(use-package persistent-scratch
      +             :config
      +             (setq persistent-scratch-save-file (expand-file-name "scratches.el" user-emacs-directory))
      +             (persistent-scratch-setup-default)
      +
      +             (setq persistent-scratch-scratch-buffer-p-function 'tvd-autoscratch-p))
      diff --git a/conf-lisp/cisco.el b/conf-lisp/cisco.el
      new file mode 100644
      index 0000000..7f70df7
      --- /dev/null
      +++ b/conf-lisp/cisco.el
      @@ -0,0 +1,8 @@
      +;; *** Cisco Mode
      +
      +;; Written by myself  many years ago, but I'm still  using it daily to
      +;; view and prepare cisco configs.
      +
      +(use-package cisco-mode
      +             :ensure nil ;; static install
      +             :mode "\\.cfg\\'")
      diff --git a/conf-lisp/completion.el b/conf-lisp/completion.el
      new file mode 100644
      index 0000000..82d3759
      --- /dev/null
      +++ b/conf-lisp/completion.el
      @@ -0,0 +1,100 @@
      +;; *** IDO mode
      +
      +;; There are other completion  enhancement packages available like ivy
      +;; for example,  but I love IDO  and I am so  used to it, it  would be
      +;; impossible to  change. So, I'll  stick with  IDO until end  of (my)
      +;; times.
      +
      +;; Hint: Use C-f during file selection to switch to regular find-file
      +
      +;; Basic config
      +(ido-mode t)
      +(ido-everywhere nil)
      +(setq ido-enable-flex-matching t)
      +(setq ido-use-filename-at-point nil)
      +(setq ido-use-virtual-buffers t)
      +(setq ido-auto-merge-work-directories-length -1)
      +
      +;; One thing annoys  me with IDO though: when writing  a new file, IDO
      +;; wants me  to select  from a  list of existing  files.  Since  it is
      +;; nearly impossible to disable ido mode for write-file, which I HATE,
      +;; I came up with this:
      +
      +;; I added a  new global variable, 'tvd-ido-disabled, which  is nil by
      +;; default. Whenever I  hit C-x C-w (in order  to execute write-file),
      +;; it will be  set to t, ido mode will  be disabled and ido-write-file
      +;; will be called.  Since ido mode is now disabled,  it just calls the
      +;; original write-file, which is what I really want.
      +
      +;; When I'm finished  selecting a filename and writing,  ido mode will
      +;; be turned  on again and the  variable will be set  to nil. However,
      +;; sometimes I may abort the process  using C-g. In that case ido mode
      +;; may end  up being disabled  because the  :after advice will  not be
      +;; called on C-g.
      +
      +;; So,  I   also  advice  the   minibuffer  C-g  function,   which  is
      +;; 'abort-recursive-edit, and  re-enable ido mode  from here if  it is
      +;; still disabled. So far I haven't seen any bad side effects of this.
      +
      +(defvar tvd-ido-disabled nil)
      +(advice-add 'ido-write-file :before '(lambda (&rest args) (ido-mode 0) (setq tvd-ido-disabled t)))
      +(advice-add 'ido-write-file :after  '(lambda (&rest args) (ido-mode 1) (setq tvd-ido-disabled nil)))
      +
      +(defun tvd-keyboard-quit-advice (fn &rest args)
      +  (when tvd-ido-disabled
      +    (ido-mode 1)
      +    (setq tvd-ido-disabled nil))
      +  (apply fn args))
      +
      +(advice-add 'abort-recursive-edit :around #'tvd-keyboard-quit-advice)
      +
      +;; from emacs wiki
      +;; Display ido results vertically, rather than horizontally
      +(setq ido-decorations (quote ("\n-> " "" "\n   " "\n   ..." "[" "]"
      +                              " [No match]" " [Matched]" " [Not readable]"
      +                              " [Too big]" " [Confirm]")))
      +
      +(defun ido-disable-line-truncation () (set (make-local-variable 'truncate-lines) nil))
      +(add-hook 'ido-minibuffer-setup-hook 'ido-disable-line-truncation)
      +(defun ido-define-keys ()
      +  (define-key ido-completion-map (kbd "") 'ido-next-match)
      +  (define-key ido-completion-map (kbd "") 'ido-prev-match))
      +(add-hook 'ido-setup-hook 'ido-define-keys)
      +
      +;; quickly go to home via ~ wherever I am
      +;; via [[http://whattheemacsd.com/setup-ido.el-02.html][whattheemacs.d]]
      +(add-hook 'ido-setup-hook
      + (lambda ()
      +   ;; Go straight home
      +   (define-key ido-file-completion-map
      +     (kbd "~")
      +     (lambda ()
      +       (interactive)
      +       (if (looking-back "/")
      +           (insert "~/")
      +         (call-interactively 'self-insert-command))))
      +   ;; same thing, but for ssh/tramp triggered by :
      +   (define-key ido-file-completion-map
      +     (kbd ":")
      +     (lambda ()
      +       (interactive)
      +       (if (looking-back "/")
      +           (progn
      +             (ido-set-current-directory "/ssh:")
      +             (ido-reread-directory))
      +         (call-interactively 'self-insert-command))))))
      +
      +;; by howardism: [re]open non-writable file with sudo
      +(defadvice ido-find-file (after find-file-sudo activate)
      +  "Find file as root if necessary."
      +  (unless (and buffer-file-name
      +               (file-writable-p buffer-file-name))
      +    (let* ((file-name (buffer-file-name))
      +           (file-root (if (string-match "/ssh:\\([^:]+\\):\\(.*\\)" file-name)
      +                          (concat "/ssh:"  (match-string 1 file-name)
      +                                  "|sudo:" (match-string 1 file-name)
      +                                  ":"      (match-string 2 file-name))
      +                        (concat "/sudo:localhost:" file-name))))
      +      (find-alternate-file file-root))))
      +
      +;; FIXME: add ido-ignore-files defun.
      diff --git a/conf-lisp/conf.el b/conf-lisp/conf.el
      new file mode 100644
      index 0000000..70843e5
      --- /dev/null
      +++ b/conf-lisp/conf.el
      @@ -0,0 +1,12 @@
      +;; *** conf-mode
      +
      +;; conf-mode annoyingly overwrites the  global keybinding C-c C-c with
      +;; some of its internal crab. So, force  it to use my own defun. Also,
      +;; while  we're  at it,  disable  electric  indent, it's  annoying  in
      +;; configs. Applies for derivates as well.
      +
      +(defun tvd-disarm-conf-mode()
      +  (local-set-key  (kbd "C-c C-c") 'comment-or-uncomment-region-or-line)
      +  (electric-indent-local-mode 0))
      +
      +(add-something-to-mode-hooks '(conf cisco fundamental conf-space pod) 'tvd-disarm-conf-mode)
      diff --git a/conf-lisp/config-general.el b/conf-lisp/config-general.el
      new file mode 100644
      index 0000000..38702be
      --- /dev/null
      +++ b/conf-lisp/config-general.el
      @@ -0,0 +1,125 @@
      +;; *** Config::General mode
      +;; **** Config and doc
      +;; [[https://github.com/TLINDEN/config-general-mode][config-general-mode]] (also on Melpa).
      +
      +;; My own mode for [[http://search.cpan.org/dist/Config-General/][Config::General]]
      +;; config files. Whenever I write some perl stuff, which needs a config file, I use
      +;; this module (and I do this a lot). Previously I used conf-mode or html-mode, but
      +;; both did not satisfy me. Now (as of 20170625) I solved this mess once and for all.
      +
      +(use-package config-general-mode
      +             :ensure nil ;; static install
      +
      +             :config
      +             (require 'sh-script)
      +
      +             (when (fboundp 'hippie-expand)
      +               (defun config-general-completion-at-point ()
      +                 "Complete word at point using hippie-expand, if not on a comment."
      +                 (interactive)
      +                 (when (looking-back "[-%$_a-zA-Z0-9]")
      +                   (unless (eq (get-text-property (point) 'face) 'font-lock-comment-face)
      +                     (hippie-expand nil))))
      +
      +               (local-set-key (kbd "") 'config-general-tab-or-expand)
      +
      +               ;; Inserting a brace or quote automatically inserts the matching pair
      +               ;; use smartparens now
      +               ;; (electric-pair-mode t)
      +               (setq-local hippie-expand-only-buffers '(config-general-mode))
      +
      +               ;; configure order of expansion functions
      +               (if (version< emacs-version "25.1")
      +                   (set (make-local-variable 'hippie-expand-try-functions-list)
      +                        '(try-expand-dabbrev ;; use patched version
      +                          config-general--try-expand-dabbrev-all-buffers
      +                          try-complete-file-name-partially
      +                          try-complete-file-name))
      +                 (set (make-local-variable 'hippie-expand-try-functions-list)
      +                      '(try-expand-dabbrev
      +                        try-expand-dabbrev-all-buffers
      +                        try-complete-file-name-partially
      +                        try-complete-file-name))))
      +
      +             (defun config-general-do-electric-tab ()
      +               "Enter a  or goto current indentation."
      +               (interactive)
      +               (if (eq (point) (line-end-position))
      +                   (indent-for-tab-command)
      +                 (back-to-indentation)))
      +
      +             ;; FIXME: Use this  patched version for older emacsen  and the default
      +             ;; for version which contain the patch (if any, ever).
      +             ;;
      +             ;; The original  function try-expand-dabbrev-all-buffers  doesn't work
      +             ;; correctly, it ignores a buffer-local configuration of the variables
      +             ;; hippie-expand-only-buffers  and hippie-expand-ignore-buffers.  This
      +             ;; is the patched version of the function.
      +             ;;
      +             ;; Bugreport: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=27501
      +             (defun config-general--try-expand-dabbrev-all-buffers (old)
      +               "Try to expand word \"dynamically\", searching all other buffers.
      +The argument OLD has to be nil the first call of this function, and t
      +for subsequent calls (for further possible expansions of the same
      +string).  It returns t if a new expansion is found, nil otherwise."
      +               (let ((expansion ())
      +                     (buf (current-buffer))
      +                     (orig-case-fold-search case-fold-search)
      +                     (heib hippie-expand-ignore-buffers)
      +                     (heob hippie-expand-only-buffers)
      +                     )
      +                 (if (not old)
      +                     (progn
      +                       (he-init-string (he-dabbrev-beg) (point))
      +                       (setq he-search-bufs (buffer-list))
      +                       (setq he-searched-n-bufs 0)
      +                       (set-marker he-search-loc 1 (car he-search-bufs))))
      +
      +                 (if (not (equal he-search-string ""))
      +                     (while (and he-search-bufs
      +                                 (not expansion)
      +                                 (or (not hippie-expand-max-buffers)
      +                                     (< he-searched-n-bufs hippie-expand-max-buffers)))
      +                       (set-buffer (car he-search-bufs))
      +                       (if (and (not (eq (current-buffer) buf))
      +                                (if heob
      +                                    (he-buffer-member heob)
      +                                  (not (he-buffer-member heib))))
      +                           (save-excursion
      +                             (save-restriction
      +                               (if hippie-expand-no-restriction
      +                                   (widen))
      +                               (goto-char he-search-loc)
      +                               (setq expansion
      +                                     (let ((case-fold-search orig-case-fold-search))
      +                                       (he-dabbrev-search he-search-string nil)))
      +                               (set-marker he-search-loc (point))
      +                               (if (not expansion)
      +                                   (progn
      +                                     (setq he-search-bufs (cdr he-search-bufs))
      +                                     (setq he-searched-n-bufs (1+ he-searched-n-bufs))
      +                                     (set-marker he-search-loc 1 (car he-search-bufs))))))
      +                         (setq he-search-bufs (cdr he-search-bufs))
      +                         (set-marker he-search-loc 1 (car he-search-bufs)))))
      +
      +                 (set-buffer buf)
      +                 (if (not expansion)
      +                     (progn
      +                       (if old (he-reset-string))
      +                       ())
      +                   (progn
      +                     (he-substitute-string expansion t)
      +                     t))))
      +
      +             (electric-indent-mode)
      +
      +             ;; de-activate some senseless bindings
      +             (local-unset-key (kbd "C-c C-c"))
      +             (local-unset-key (kbd "C-c C-p"))
      +             (local-unset-key (kbd "C-c C-u"))
      +             (local-unset-key (kbd "C-c C-w"))
      +             (local-unset-key (kbd "C-c C-x"))
      +             (local-unset-key (kbd "C-c :"))
      +
      +             ;; from shell-script-mode, turn << into here-doc
      +             (sh-electric-here-document-mode 1))
      diff --git a/conf-lisp/dired.el b/conf-lisp/dired.el
      new file mode 100644
      index 0000000..9924724
      --- /dev/null
      +++ b/conf-lisp/dired.el
      @@ -0,0 +1,267 @@
      +;; *** Dired
      +
      +;; I use dired  for two things: from inside magit  as a convenient way
      +;; to add or remove files from a  repository. Or if I want to rename a
      +;; bunch of files using search/replace and other editing commands.
      +
      +;; But as with everything else I use,  it must fit and so I managed to
      +;; tune this as well.
      +
      +;; [[http://ergoemacs.org/emacs/emacs_dired_tips.html][More Hints]]
      +
      +;; **** dired-k
      +
      +;; dired-k is k  for dired/emacs: it colorizes files  and directory by
      +;; age, that is, the older the  greyer they get. And it displays flags
      +;; about the git status of each file, which is really handy.
      +
      +;; However,  it only  works with  git installed  and if  enabled stops
      +;; dired to work  completely. So I define an exception  here and don't
      +;; load k if there's no git (e.g. on my notebook at work)
      +(when (string-match "version" (shell-command-to-string "git version"))
      +  (use-package dired-k
      +               :init
      +               (add-hook 'dired-initial-position-hook 'dired-k)
      +               (add-hook 'dired-after-readin-hook #'dired-k-no-revert)
      +
      +               :config
      +               (setq dired-k-padding 2)))
      +
      +;; **** dired-hacks
      +
      +;; [[https://github.com/Fuco1/dired-hacks][Fuco1s dired-hacks]] is a
      +;; place to find the really cool stuff, I mostly use the filters.
      +(use-package dired-filter
      +             :config
      +
      +             (defun tvd-dired-quit-or-filter-pop (&optional arg)
      +               "Remove a filter from the filter stack. If none left, quit the dired buffer."
      +               (interactive "p")
      +               (if dired-filter-stack
      +                   (dired-filter-pop arg)
      +                 (quit-window))))
      +
      +(use-package dired-ranger)
      +
      +;; **** dired sort helpers
      +
      +;; This sort function by [[http://ergoemacs.org/emacs/dired_sort.html][Xah Lee]]
      +;; is easy to use and does what it should, great!, However, I added some -desc
      +;; sister sorts for reverse sorting.
      +(defun xah-dired-sort ()
      +  "Sort dired dir listing in different ways.
      +Prompt for a choice.
      +URL `http://ergoemacs.org/emacs/dired_sort.html'
      +Version 2015-07-30"
      +  (interactive)
      +  (let (sort-by arg)
      +    (setq sort-by (ido-completing-read "Sort by:" '( "date" "size" "name" "dir" "date-desc" "size-desc" "name-desc" "dir-desc" )))
      +    (cond
      +     ((equal sort-by "name") (setq arg "-Al --si --time-style long-iso "))
      +     ((equal sort-by "date") (setq arg "-Al --si --time-style long-iso -t"))
      +     ((equal sort-by "size") (setq arg "-Al --si --time-style long-iso -S"))
      +     ((equal sort-by "dir") (setq arg "-Al --si --time-style long-iso --group-directories-first"))
      +     ((equal sort-by "name-desc") (setq arg "-Al --si --time-style long-iso -r"))
      +     ((equal sort-by "date-desc") (setq arg "-Al --si --time-style long-iso -t -r"))
      +     ((equal sort-by "size-desc") (setq arg "-Al --si --time-style long-iso -S -r"))
      +     ((equal sort-by "dir-desc") (setq arg "-Al --si --time-style long-iso --group-directories-first -r"))
      +     (t (error "logic error 09535" )))
      +    (dired-sort-other arg )))
      +
      +;; **** dired git helpers
      +
      +;; [[http://blog.binchen.org/posts/the-most-efficient-way-to-git-add-file-in-dired-mode-emacsendiredgit.html][via bin chen]]:
      +;; make git commands available from dired  buffer, which can be used in
      +;; those rare cases, where my wrappers below don't fit.
      +(defun diredext-exec-git-command-in-shell (command &optional arg file-list)
      +  "Run a shell command git COMMAND  ' on the marked files.  if no
      +files marked, always operate on current line in dired-mode"
      +  (interactive
      +   (let ((files (dired-get-marked-files t current-prefix-arg)))
      +     (list
      +      ;; Want to give feedback whether this file or marked files are used:
      +      (dired-read-shell-command "git command on %s: " current-prefix-arg files)
      +      current-prefix-arg
      +      files)))
      +  (unless (string-match "[?][ \t]\'" command)
      +    (setq command (concat command " *")))
      +  (setq command (concat "git " command))
      +  (dired-do-shell-command command arg file-list)
      +  (message command))
      +
      +;; some git  commandline wrappers  which directly  work on  git files,
      +;; called with "hydras".
      +(defun tvd-dired-git-add(&optional arg file-list)
      +  "Add marked or current file to current repository (stash)."
      +  (interactive
      +    (let ((files (dired-get-marked-files t current-prefix-arg)))
      +      (list current-prefix-arg files)))
      +  (dired-do-shell-command "git add -v * " arg file-list)
      +  (revert-buffer))
      +
      +(defun tvd-dired-git-rm(&optional arg file-list)
      +  "Remove marked or current file from current repository and filesystem."
      +  (interactive
      +   (let ((files (dired-get-marked-files t current-prefix-arg)))
      +     (list current-prefix-arg files)))
      +  (dired-do-shell-command "git rm -rf * " arg file-list)
      +  (revert-buffer))
      +
      +(defun tvd-dired-git-ungit(&optional arg file-list)
      +  "Like `tvd-dired-git-rm' but keep the files in the filesystem (unstage)."
      +  (interactive
      +   (let ((files (dired-get-marked-files t current-prefix-arg)))
      +     (list current-prefix-arg files)))
      +  (dired-do-shell-command "git rm -rf --cached * " arg file-list)
      +  (revert-buffer))
      +
      +;; **** dired navigation
      +
      +;; I'm used to jump around with pos1+end
      +(defun tvd-dired-begin ()
      +  "Move point to the first directory in the listing .."
      +  (interactive)
      +  (goto-char (point-min))
      +  (dired-next-dirline 2))
      +
      +(defun tvd-dired-end ()
      +  "Move point to the last file or directory in the listing."
      +  (interactive)
      +  (goto-char (point-max))
      +  (dired-previous-line 1))
      +
      +;; **** dired buffer names
      +
      +;; This took  me a long time  to figure out,  but I finally got  it: I
      +;; really  hate it  how  dired names  its buffers,  it  just uses  the
      +;; basename part of  the current working directory as  buffer name. So
      +;; when there are  a couple of dozen  buffers open and one  of them is
      +;; named "tmp"  I just can't see  it. So what  I do here is  to rename
      +;; each   dired  buffer   right   after  its   creation  by   advising
      +;; `dired-internal-noselect'. My  dired buffers  have such  names now:
      +;; *dired: ~/tmp*. I  can find them easily, and I  can reach all dired
      +;; buffers very  fast thanks to  the *dired  prefix. And they  are now
      +;; clearly  marked  as  non-file  buffers. In  fact  I  consider  this
      +;; behavior as a bug, but I doubt many people would agree :)
      +
      +(advice-add 'dired-internal-noselect
      +            :filter-return
      +            '(lambda (buffer)
      +               "Modify dired buffer names to this pattern: *dired: full-path*"
      +               (interactive)
      +               (with-current-buffer buffer
      +                 (rename-buffer (format "*dired: %s*" default-directory)))
      +               buffer))
      +
      +;; **** dired config and key bindings
      +
      +;; and finally put everything together.
      +
      +(eval-after-load 'dired
      +  '(progn
      +     ;; dired vars
      +     (setq dired-listing-switches "-lt")
      +
      +     ;; stay  with 1  dired buffer  per instance
      +     ;; when changing directories
      +     (define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
      +     (define-key dired-mode-map (kbd "") 'dired-find-alternate-file)
      +     (define-key dired-mode-map (kbd "^") (lambda () (interactive) (find-alternate-file "..")))
      +     (define-key dired-mode-map (kbd "") (lambda () (interactive) (find-alternate-file "..")))
      +
      +     ;; Xah Lee'S custom sort's
      +     (define-key dired-mode-map (kbd "s") 'xah-dired-sort)
      +
      +     ;; my git "hydras"
      +     (define-prefix-command 'tvd-dired-git-map)
      +     (define-key dired-mode-map (kbd "g") 'tvd-dired-git-map)
      +     (define-key tvd-dired-git-map (kbd "a") 'tvd-dired-git-add)
      +     (define-key tvd-dired-git-map (kbd "d") 'tvd-dired-git-rm)
      +     (define-key tvd-dired-git-map (kbd "u") 'tvd-dired-git-ungit)
      +
      +     ;; edit filenames
      +     (defalias 'edit-dired 'wdired-change-to-wdired-mode)
      +     (define-key dired-mode-map (kbd "C-c C-c") 'wdired-change-to-wdired-mode)
      +
      +     ;; dired-hacks filters
      +     (define-key dired-mode-map (kbd "f") dired-filter-map)
      +     (define-key dired-mode-map (kbd "q") 'tvd-dired-quit-or-filter-pop)
      +     (define-key dired-mode-map (kbd "Q") 'dired-filter-pop-all)
      +
      +     ;; ranger, multi file copy/move
      +     (define-prefix-command 'tvd-dired-ranger-map)
      +     (define-key dired-mode-map (kbd "r") 'tvd-dired-ranger-map)
      +     (define-key tvd-dired-ranger-map (kbd "c") 'dired-ranger-copy)
      +     (define-key tvd-dired-ranger-map (kbd "p") 'dired-ranger-paste)
      +     (define-key tvd-dired-ranger-map (kbd "m") 'dired-ranger-move)
      +
      +     ;; navigation,  use TAB  and C-TAB  to move
      +     ;; point to  next or prev dir  like in info
      +     ;; mode, and  HOME+END to reach the  end or
      +     ;; beginning of the listing.
      +     (define-key dired-mode-map (kbd "") 'dired-next-dirline)
      +     (define-key dired-mode-map (kbd "") 'dired-prev-dirline)
      +     (define-key dired-mode-map (kbd "") 'tvd-dired-begin)
      +     (define-key dired-mode-map (kbd "") 'tvd-dired-end)
      +
      +     ;; overwrite some defaults I do not use anyway
      +     (define-key dired-mode-map (kbd "n") 'dired-create-directory)
      +     ))
      +;; **** Dired Hydra
      +
      +;; FIXME: not yet customized to fit my own config
      +(when (fboundp 'defhydra)
      +  (defhydra hydra-dired (:hint nil :color pink)
      +    "
      +_+_ mkdir          _v_iew           _m_ark             _(_ details        _i_nsert-subdir    _W_dired (EDIT FILENAMES)
      +_C_opy             _O_ view other   _U_nmark all       _)_ omit-mode      _$_ hide-subdir    C-c C-c : edit
      +_D_elete           _o_pen other     _u_nmark           _l_ redisplay      _w_ kill-subdir
      +_R_ename           _M_ chmod        _t_oggle           _g_ revert buf     _e_ ediff          _q_uit
      +_Y_ rel symlink    _G_ chgrp        _E_xtension mark   _s_ort             _=_ pdiff
      +_S_ymlink          ^ ^              _F_ind marked      _._ toggle hydra   \\ flyspell
      +_r_sync            ^ ^              ^ ^                ^ ^                _?_ summary
      +_z_ compress-file  _A_ find regexp   / Filter
      +_Z_ compress       _Q_ repl regexp
      +
      +T - tag prefix
      +
      +"
      +    ("\\" dired-do-ispell nil)
      +    ("(" dired-hide-details-mode nil)
      +    (")" dired-omit-mode nil)
      +    ("+" dired-create-directory nil)
      +    ("=" diredp-ediff nil)         ;; smart diff
      +    ("?" dired-summary nil)
      +    ("$" diredp-hide-subdir-nomove nil)
      +    ("A" dired-do-find-regexp nil)
      +    ("C" dired-do-copy nil)        ;; Copy all marked files
      +    ("D" dired-do-delete nil)
      +    ("E" dired-mark-extension nil)
      +    ("e" dired-ediff-files nil)
      +    ("F" dired-do-find-marked-files nil)
      +    ("G" dired-do-chgrp nil)
      +    ("g" revert-buffer nil)        ;; read all directories again (refresh nil)
      +    ("i" dired-maybe-insert-subdir nil)
      +    ("l" dired-do-redisplay nil)   ;; relist the marked or singel directory
      +    ("M" dired-do-chmod nil)
      +    ("m" dired-mark nil)
      +    ("O" dired-display-file nil)
      +    ("o" dired-find-file-other-window nil)
      +    ("Q" dired-do-find-regexp-and-replace nil)
      +    ("R" dired-do-rename nil)
      +    ("r" dired-do-rsynch nil)
      +    ("S" dired-do-symlink nil)
      +    ("s" dired-sort-toggle-or-edit nil)
      +    ("t" dired-toggle-marks nil)
      +    ("U" dired-unmark-all-marks nil)
      +    ("u" dired-unmark nil)
      +    ("v" dired-view-file nil)      ;; q to exit, s to search, = gets line #
      +    ("w" dired-kill-subdir nil)
      +    ("W" wdired-change-to-wdired-mode nil)
      +    ("Y" dired-do-relsymlink nil)
      +    ("z" diredp-compress-this-file nil)
      +    ("Z" dired-do-compress nil)
      +    ("q" nil nil)
      +    ("." nil nil :color blue))
      +
      +  (define-key dired-mode-map "?" 'hydra-dired/body))
      diff --git a/conf-lisp/display.el b/conf-lisp/display.el
      new file mode 100644
      index 0000000..c401183
      --- /dev/null
      +++ b/conf-lisp/display.el
      @@ -0,0 +1,17 @@
      +;;; Display settings
      +
      +;; better visibility of cursor in console sessions
      +(unless (display-graphic-p)
      +  ;; instead of closing the terminal, just kill the buffer
      +  (global-set-key (kbd "C-x c") 'kill-this-buffer)
      +  (set-face-attribute 'fringe nil :inverse-video t)
      +  (invert-face 'default)
      +  (invert-face 'mode-line))
      +
      +(use-package solarized-theme
      +             :ensure t
      +             :config
      +             (load-theme 'solarized-dark t))
      +
      +;;; ** increase default font size on startup
      +(set-face-attribute 'default nil :height 133)
      diff --git a/conf-lisp/dumpjump.el b/conf-lisp/dumpjump.el
      new file mode 100644
      index 0000000..36681be
      --- /dev/null
      +++ b/conf-lisp/dumpjump.el
      @@ -0,0 +1,24 @@
      +;; *** Dumpjump
      +;; https://github.com/jacktasia/dumb-jump/raw/master/dumb-jump.el
      +(use-package dumb-jump
      +             :config
      +
      +             (add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
      +             (setq xref-show-definitions-function #'xref-show-definitions-completing-read)
      +
      +             (setq dumb-jump-quiet t)
      +
      +             (when (fboundp 'defhydra)
      +               (defhydra hydra-dumb-jump (:color blue :columns 3)
      +                 "Dumb Jump"
      +                 ("j" dumb-jump-go "Go")
      +                 ("o" dumb-jump-go-other-window "Other window")
      +                 ("e" dumb-jump-go-prefer-external "Go external")
      +                 ("x" dumb-jump-go-prefer-external-other-window "Go external other window")
      +                 ("i" dumb-jump-go-prompt "Prompt")
      +                 ("l" dumb-jump-quick-look "Quick look")
      +                 ("b" dumb-jump-back "Back"))
      +
      +               (global-set-key (kbd "C-x j") 'hydra-dumb-jump/body))
      +             (global-set-key (kbd "C-c j") 'dumb-jump-go)
      +             (global-set-key (kbd "C-c b") 'dumb-jump-back))
      diff --git a/conf-lisp/ediff.el b/conf-lisp/ediff.el
      new file mode 100644
      index 0000000..5355509
      --- /dev/null
      +++ b/conf-lisp/ediff.el
      @@ -0,0 +1,61 @@
      +;; *** Ediff Config
      +
      +;; Force ediff to use  1 frame (the current) and not  open a new frame
      +;; for control  and help. Also  changing the split  orientation doesnt
      +;; open a new frame.
      +
      +(eval-after-load "ediff"
      +  '(progn
      +     (setq ediff-diff-options   "-w"
      +           ediff-split-window-function 'split-window-horizontally
      +           ediff-window-setup-function 'ediff-setup-windows-plain)
      +
      +     (add-hook 'ediff-startup-hook 'ediff-toggle-wide-display)
      +     (add-hook 'ediff-cleanup-hook 'ediff-toggle-wide-display)
      +     (add-hook 'ediff-suspend-hook 'ediff-toggle-wide-display)
      +
      +     (add-hook 'ediff-mode-hook
      +               (lambda ()
      +                 (ediff-setup-keymap)
      +                 ;; merge left to right
      +                 (define-key ediff-mode-map ">" 'ediff-copy-A-to-B)
      +                 ;; merge right to left
      +                 (define-key ediff-mode-map "<" 'ediff-copy-B-to-A)))
      +
      +     ;; restore window config on quit
      +     (add-hook 'ediff-after-quit-hook-internal 'winner-undo)
      +     ))
      +
      +;; from emacswiki:
      +;; Usage: emacs -diff file1 file2
      +(defun command-line-diff (switch)
      +  (let ((file1 (pop command-line-args-left))
      +        (file2 (pop command-line-args-left)))
      +    (ediff file1 file2)))
      +(add-to-list 'command-switch-alist '("diff" . command-line-diff))
      +
      +
      +
      +;; *** Smerge Config
      +
      +;; smerge-mode is being issued during editing of conflicts from magit,
      +;; however, I  hate its default  prefix, but don't have  any practical
      +;; prefixes  left AND  am using  it far  too rare  to deserve  its own
      +;; prefix. So just a hydra will do.
      +
      +(when (fboundp 'defhydra)
      +  (defhydra hydra-smerge (:color blue :timeout 30.0)
      +    "
      +^Smerge Mode^
      +^^-------------------------------------------------------
      +_n_ext conflict         keep _u_pper    m_e_rge conflicts in Ediff
      +_p_revious conflict     keep _l_ower    _q_uit"
      +
      +    ("n"  smerge-next       nil :exit nil)
      +    ("p"  smerge-prev       nil :exit nil)
      +    ("u"  smerge-keep-upper nil :exit nil)
      +    ("l"  smerge-keep-lower nil :exit nil)
      +    ("e"  smerge-ediff      nil :color red)
      +    ("q"  nil               nil :color red))
      +
      +  (defalias 'merge      'hydra-smerge/body))
      diff --git a/conf-lisp/elget.el b/conf-lisp/elget.el
      new file mode 100644
      index 0000000..21e2a70
      --- /dev/null
      +++ b/conf-lisp/elget.el
      @@ -0,0 +1,98 @@
      +;;; setup el-get for non-package modes
      +
      +;; This MUST be the first init file to be loaded.
      +
      +;; I use el-get to install  non-(m)elpa packages from github or direct
      +;; download. That way I don't have to manually keep'em up to date.
      +
      +(add-to-list 'load-path (expand-file-name "el-get/el-get" tvd-config-dir))
      +
      +(unless (require 'el-get nil 'noerror)
      +  (package-refresh-contents)
      +  (package-install 'el-get)
      +  (require 'el-get))
      +
      +(el-get-bundle viking-mode
      +               :type github
      +               :pkgname "tlinden/viking-mode"
      +               :features viking-mode)
      +
      +(el-get-bundle autoscratch
      +               :type github
      +               :pkgname "tlinden/autoscratch"
      +               :features autoscratch-mode)
      +
      +(el-get-bundle novel-mode
      +               :type github
      +               :pkgname "tlinden/novel-mode"
      +               :features novel-mode)
      +
      +(el-get-bundle config-general-mode
      +               :type github
      +               :pkgname "tlinden/config-general-mode"
      +               :features config-general-mode)
      +
      +(el-get-bundle mark-copy-yank-things-mode
      +               :type github
      +               :pkgname "tlinden/mark-copy-yank-things-mode"
      +               :features mark-copy-yank-things-mode)
      +
      +(el-get-bundle followcursor-mode
      +               :type github
      +               :pkgname "tlinden/followcursor-mode"
      +               :features followcursor-mode)
      +
      +(el-get-bundle novel-mode
      +               :type github
      +               :pkgname "tlinden/novel-mode"
      +               :features novel-mode)
      +
      +(el-get-bundle cisco-mode
      +               :type http-tar
      +               :options ("xzf")
      +               :url "https://www.daemon.de/idisk/Scripts/cisco-mode-0.2.tar.gz")
      +
      +(el-get-bundle pod-mode
      +               :type http-tar
      +               :options ("xzf")
      +               :url "https://cpan.metacpan.org/authors/id/F/FL/FLORA/pod-mode-1.04.tar.gz")
      +
      +(el-get-bundle info+
      +               :type http
      +               :features info+
      +               :url "https://www.emacswiki.org/emacs/download/info+.el")
      +
      +(el-get-bundle narrow-indirect
      +               :type http
      +               :features narrow-indirect
      +               :url "https://www.emacswiki.org/emacs/download/narrow-indirect.el")
      +
      +(el-get-bundle rotate-text
      +               :type http
      +               :url "http://nschum.de/src/emacs/rotate-text/rotate-text.el")
      +
      +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      +;; These packages doesn't install via melpa for unknown reasons
      +;; see https://github.com/melpa/melpa/issues/8480
      +;; (el-get-bundle expand-region
      +;;        :type github
      +;;        :pkgname "magnars/expand-region.el"
      +;;        :website "https://github.com/magnars/expand-region.el#readme")
      +
      +;; ;; same thing, dependes on the latter
      +;; (el-get-bundle change-inner
      +;;        :type github
      +;;        :pkgname "magnars/change-inner.el"
      +;;        :website "https://github.com/magnars/change-inner.el#readme")
      +
      +;; (el-get-bundle iedit
      +;;        :type github
      +;;        :pkgname "victorhge/iedit"
      +;;        :website "https://github.com/victorhge/iedit/")
      +
      +;; (el-get-bundle tablist
      +;;        :type github
      +;;        :pkgname "emacsorphanage/tablist"
      +;;        :website "https://github.com/emacsorphanage/tablist")
      +
      +(el-get 'sync)
      diff --git a/conf-lisp/elisp.el b/conf-lisp/elisp.el
      new file mode 100644
      index 0000000..ff81099
      --- /dev/null
      +++ b/conf-lisp/elisp.el
      @@ -0,0 +1,185 @@
      +;; *** Emacs LISP interactive
      +
      +;; General configuration for all things elisp.
      +
      +;; By using C-x-e I can push region or buffer
      +;; of lisp code (i.e. inside *scratch*) into
      +;; REPL where it will be evaluated
      +
      +(defun tvd-get-code()
      +  "helper: returns marked region or the whole buffer contents"
      +  ;; FIXME: mv to string helpers?
      +  (if mark-active
      +      (let (  ;; save region and buffer
      +            (partb (buffer-substring-no-properties (region-beginning) (region-end)))
      +            (whole (buffer-substring-no-properties (point-min) (point-max)))
      +            )
      +        (if (> (length partb) 0)
      +            partb
      +          whole
      +          )
      +        )
      +    ;; no mark, also return everything
      +    (buffer-substring-no-properties (point-min) (point-max))))
      +
      +(defun tvd-send-region-to-repl ()
      +  "put region or buffer into elisp repl and eval"
      +  (interactive)
      +  (let ( ;; fetch region or buffer contents
      +        (code  (tvd-get-code)))
      +    (progn
      +      (if (not (get-buffer "*ielm*"))
      +          ;; ielm not yet running, start it in split window but stay here
      +          (progn
      +            (split-window-horizontally)
      +            (other-window 1)
      +            (ielm)
      +            (other-window 1)))
      +      ;; finially, paste content into ielm and evaluate it
      +      ;; still we stay where we are
      +      (with-current-buffer "*ielm*"
      +        (goto-char (point-max))
      +        (insert code)
      +        (ielm-return)))))
      +
      +(defun tvd-elisp-eval()
      +  "just eval region or buffer whatever feasible"
      +  (interactive)
      +  (progn
      +    (if mark-active
      +        (eval-region)
      +      (eval-buffer))))
      +
      +(defun ff ()
      +  "Jump to function definition at point."
      +  (interactive)
      +  (find-function-other-window (symbol-at-point)))
      +
      +(defun tvd-make-defun-links ()
      +  "experimental: make function calls clickable, on click, jump to definition of it"
      +  (interactive)
      +  (let ((beg 0)
      +        (end 0)
      +        (fun nil))
      +    (goto-char (point-min))
      +    (while (re-search-forward "(tvd[-a-z0-9]*" nil t)
      +      (setq end (point))
      +      (re-search-backward "(" nil t)
      +      (forward-char 1)
      +      (setq beg (point))
      +      (setq fun (buffer-substring-no-properties beg end))
      +      (make-button beg end 'action
      +                   (lambda (x)
      +                     (find-function-other-window (symbol-at-point))))
      +      (goto-char end))))
      +
      +(defun emacs-change-version (v)
      +  "Change version of .emacs (must be the current buffer).
      +Returns t if version changed, nil otherwise."
      +  (interactive
      +   (list
      +    (completing-read "New config version (press TAB for old): "
      +                     (list tvd-emacs-version))))
      +  (if (equal v tvd-emacs-version)
      +      nil
      +    (save-excursion
      +      (show-all)
      +      (beginning-of-buffer)
      +      (tvd-replace-all (format "\"%s\"" tvd-emacs-version)
      +                       (format "\"%s\"" v))
      +      (setq tvd-emacs-version v)
      +      (message (format "New config version set: %s" v))
      +      t)))
      +
      +(defun emacs-change-log (entry)
      +  "Add a changelog entry to .emacs Changelog"
      +  (interactive "Menter change log entry: ")
      +  (let ((newversion (call-interactively 'emacs-change-version)))
      +      (save-excursion
      +        (show-all)
      +        (beginning-of-buffer)
      +        (re-search-forward ";; .. Changelog")
      +        (next-line)
      +        (tvd-outshine-end-of-section)
      +        (when newversion
      +          (insert (format "\n;; %s\n" tvd-emacs-version)))
      +        (insert (format ";;    - %s\n" entry)))))
      +
      +;; elisp config
      +(add-hook 'emacs-lisp-mode-hook
      +          (lambda()
      +            ;; non-separated x-e == eval hidden, aka current buffer
      +            (local-set-key (kbd "C-x C-e")  'tvd-elisp-eval)
      +            ;; separate 'e' == separate buffer
      +            (local-set-key (kbd "C-x e")    'tvd-send-region-to-repl)
      +            (setq mode-name "EL"
      +                  show-trailing-whitespace t)
      +            (eldoc-mode t)
      +
      +            ;; enable outline (with outshine)
      +            (outline-minor-mode)
      +
      +            ;; enable outshine mode
      +            (outshine-hook-function)
      +
      +            (electric-indent-mode t)))
      +
      +;; use UP arrow for history in *ielm* as well, just as C-up
      +(add-hook 'comint-mode-hook
      +          (lambda()
      +            (define-key comint-mode-map [up] 'comint-previous-input)))
      +
      +;; sometimes I use lisp in minibuffer
      +(defun ee()
      +  (interactive)
      +  (electric-pair-mode)
      +  (call-interactively 'eval-expression)
      +  (electric-pair-mode))
      +
      +;; sometimes I eval regions
      +(defalias 'er        'eval-region)
      +
      +;; ... or defuns
      +(defalias 'ef        'eval-defun)
      +
      +;; I like to have some functions fontified differently
      +(font-lock-add-keywords
      + 'emacs-lisp-mode
      + '(("(\\s-*\\(eq\\|if\\|cond\\|and\\|set\\|or\\|not\\|when\\|setq\\|let**\\|lambda\\|kbd\\|defun\\|car\\|cdr\\)\\s-+"
      +    1 'font-lock-keyword-face)))
      +
      +;; same applies for quoted symbols
      +(font-lock-add-keywords
      + 'emacs-lisp-mode
      + '(("'[-a-zA-Z_][-a-zA-Z0-9_]*\\>" 0 'font-lock-constant-face)))
      +
      +;; I  hate it  when help,  debug,  ielm and  other peripheral  buffers
      +;; litter  my emacs  window setup.  So, this  function fixes  this: it
      +;; opens a new frame with all those buffers already opened and pinned.
      +
      +(defun dev ()
      +  "Open a new emacs frame with some development peripheral buffers."
      +  (interactive)
      +  (let ((F (make-frame)))
      +    (with-selected-frame F
      +      (with-current-buffer (get-buffer-create "*Help*")
      +        (help-mode))
      +      (with-current-buffer (get-buffer-create "*ielm*")
      +        (ielm))
      +      (with-current-buffer (get-buffer-create "*suggest*")
      +        (suggest))
      +      (switch-to-buffer "*ielm*")
      +      (split-window-horizontally)
      +      (split-window-vertically)
      +      (windmove-down)
      +      (switch-to-buffer "*suggest*")
      +      (tvd-suggest-reload)
      +      (tvd-suggest-reload)
      +      (windmove-right)
      +      (switch-to-buffer "*Help*")
      +      (split-window-vertically)
      +      (windmove-down)
      +      (switch-to-buffer "*scratch*")
      +      (set-window-dedicated-p (selected-window) t)
      +      (set-background-color "azure"))))
      +
      diff --git a/conf-lisp/eshell.el b/conf-lisp/eshell.el
      new file mode 100644
      index 0000000..bed2bea
      --- /dev/null
      +++ b/conf-lisp/eshell.el
      @@ -0,0 +1,210 @@
      +;; *** eShell stuff, or if interactive stuff is needed, use ansi-term
      +
      +;; I am  a hardcore bash  user, but from time  to time eshell  is good
      +;; enough. It's great when used remote when only sftp is supported.
      +
      +(require 'eshell)
      +
      +;; fac'ifier
      +(defmacro with-face (str &rest properties)
      +  `(propertize ,str 'face (list ,@properties)))
      +
      +;; custom prompt, which resembles my bash prompt
      +(defun shk-eshell-prompt ()
      +  (let ((header-bg "Azure"))
      +    (concat
      +     (with-face "\n")
      +     (with-face (format-time-string
      +                 "[%Y-%m-%d %H:%M] --- ["
      +                 (current-time)) :background header-bg :foreground "Black")
      +     (with-face (concat (eshell/pwd) "") :background header-bg :foreground "Blue")
      +     (with-face "] --- " :background header-bg :foreground "Black")
      +     (with-face  (or
      +                  (ignore-errors (format "(%s)" (vc-responsible-backend default-directory)))
      +                  "") :background header-bg)
      +     (with-face "\n" :background header-bg)
      +     (with-face user-login-name :foreground "blue")
      +     "@"
      +     (with-face "localhost" :foreground "blue")
      +     (if (= (user-uid) 0)
      +         (with-face " #" :foreground "red")
      +       " $")
      +     " ")))
      +
      +(setq eshell-prompt-function 'shk-eshell-prompt)
      +(setq eshell-highlight-prompt nil)
      +
      +;; I use my own virtual loggin target /dev/log, just redirect
      +;; command output to /dev/log and it will be saved to
      +;; the *LOG* buffer. > inserts, >> appends
      +;; N.B: /dev/kill puts the stuff into the kill-ring.
      +(defun log-comment ()
      +  (with-current-buffer (get-buffer-create "*LOG*")
      +    (insert (format "# %s\n" (time-stamp-string)))))
      +
      +(defun log-insert (string)
      +  (with-current-buffer (get-buffer-create "*LOG*")
      +    (delete-region (point-min) (point-max))
      +    (log-comment)
      +    (insert string)
      +    (message "wrote output to *LOG* buffer")))
      +
      +(defun log-append (string)
      +  (with-current-buffer (get-buffer-create "*LOG*")
      +    (end-of-buffer)
      +    (newline)
      +    (log-comment)
      +    (insert string)
      +    (message "wrote output to *LOG* buffer")))
      +
      +;; must return a defun which gets the stuff as ARG1
      +;; 'mode is 'overwrite or 'append
      +(add-to-list 'eshell-virtual-targets '("/dev/log" (lambda (mode)
      +                                              (if (eq mode 'overwrite)
      +                                                  'log-insert
      +                                                'log-append))
      +                                      t
      +                                      ))
      +
      +;; eshell config
      +(eval-after-load "eshell"
      +  '(progn
      +     (add-hook 'eshell-mode-hook
      +               (lambda ()
      +                 (local-unset-key (kbd "C-c C-r")) ; we're already using this for windresize
      +                 (add-to-list 'eshell-visual-commands "tail")
      +                 (add-to-list 'eshell-visual-commands "top")
      +                 (add-to-list 'eshell-visual-commands "vi")
      +                 (add-to-list 'eshell-visual-commands "ssh")
      +                 (add-to-list 'eshell-visual-commands "tail")
      +                 (add-to-list 'eshell-visual-commands "mutt")
      +                 (add-to-list 'eshell-visual-commands "note")
      +                 (setenv "TERM" "xterm")
      +                 (local-set-key (kbd "C-l") 'eshell/clear)
      +                 (define-key viking-mode-map (kbd "C-d") nil) ;; need to undef C-d first
      +                 (local-set-key (kbd "C-d") 'eshell/x)
      +                 (setq mode-name "ESH"
      +                       eshell-hist-ignoredups t
      +                       eshell-history-size 5000
      +                       eshell-where-to-jump 'begin
      +                       eshell-review-quick-commands nil
      +                       eshell-smart-space-goes-to-end t
      +                       eshell-scroll-to-bottom-on-input 'all
      +                       eshell-error-if-no-glob t
      +                       eshell-save-history-on-exit t
      +                       eshell-prefer-lisp-functions t)))))
      +
      +;; exit and restore viking key binding afterwards
      +(defun eshell/x (&rest args)
      +  (interactive)
      +  (eshell-life-is-too-much)
      +  (define-key viking-mode-map (kbd "C-d") 'viking-kill-thing-at-point))
      +
      +;; open files in emacs, split the shell if not already splitted
      +;; open empty window if no file argument given.
      +(defun eshell/emacs (&rest args)
      +  "Editor commands fired from eshell will be handled by emacs, which already runs anyway."
      +  (interactive)
      +  (let* ((framesize (frame-width))
      +         (winsize (window-body-width)))
      +    (progn
      +      (if (eq winsize framesize)
      +          (split-window-horizontally))
      +      (other-window 1)
      +      (if (null args)
      +          (bury-buffer)
      +        (mapc #'find-file (mapcar #'expand-file-name (eshell-flatten-list (reverse args))))))))
      +
      +(defun eshell/clear ()
      +  "Better clear  command than (recenter  0) which doesn't work  as I
      +want.  This version really removes  the output of previous commands
      +and puts the shell to the beginning of a really (then) empty eshell
      +buffer. However,  just to be sure  that I do no  accidentally clear
      +some  shell output  that might  be useful  in the  future, it  also
      +copies   the   cleared   stuff   into   a   backup   buffer   named
      +*eshell-log-buffer*, just in case."
      +  (interactive)
      +  (let ((beg (point-min))
      +        (end (point-max))
      +        (savebuffer "*eshell-log-buffer*")
      +        (log (buffer-substring-no-properties (point-min) (point-max))))
      +    (progn
      +      (if (not (get-buffer savebuffer))
      +          (get-buffer-create savebuffer))
      +      (with-current-buffer savebuffer
      +        (goto-char (point-max))
      +        (insert log))
      +      (delete-region beg end)
      +      (eshell-emit-prompt))))
      +
      +(defun eshell/perldoc (&rest args)
      +  "Like `eshell/man', but invoke `perldoc'."
      +  (funcall 'eshell/perldoc (apply 'eshell-flatten-and-stringify args)))
      +
      +(defun eshell/perldoc (man-args)
      +  (interactive "sPerldoc: ")
      +  (require 'man)
      +  (let ((manual-program "perldoc"))
      +    (man man-args)))
      +
      +(defun eshell-here ()
      +  "Opens up a new shell in the directory associated with the
      +current buffer's file. The eshell is renamed to match that
      +directory to make multiple eshell windows easier."
      +  (interactive)
      +  (let* ((parent (if (buffer-file-name)
      +                     (file-name-directory (buffer-file-name))
      +                   default-directory))
      +         (height (/ (window-total-height) 3))
      +         (name   (car (last (split-string parent "/" t)))))
      +    (split-window-vertically (- height))
      +    (other-window 1)
      +    (eshell "new")
      +    (rename-buffer (concat "*eshell: " name "*"))
      +    (insert (concat "ls"))
      +    (eshell-send-input)))
      +
      +;; via howardism
      +(defun eshell-there (host)
      +  "Opens a shell on a remote host using tramp."
      +  (interactive "sHost: ")
      +  (let ((default-directory (format "/%s:" host)))
      +    (eshell host)))
      +
      +(defalias 'es        'eshell-here)
      +(defalias 'et        'eshell-there)
      +(defalias 'eshell/vi 'eshell/emacs)
      +
      +;; plan9 smart command, edit while exec if not silent or successful
      +(require 'em-smart)
      +
      +;; eshell shell aliases. I set the global
      +;; defvar here so there's no need to transport
      +;; ~/.emacs.d/eshell/aliases across networks
      +(setq eshell-command-aliases-list ())
      +
      +(defun +alias (al cmd)
      +  "handy wrapper function to convert alias symbols
      +to alias strings to avoid writing 4 quotes per alias.
      +AL is a single-word symbol naming the alias, CMD is
      +a list symbol describing the command."
      +  (add-to-list 'eshell-command-aliases-list
      +               (list (symbol-name al)
      +                     (mapconcat 'symbol-name cmd " "))))
      +
      +;; actual aliases
      +(+alias 'l      '(ls -laF $*))
      +(+alias 'll     '(ls -l $*))
      +(+alias 'la     '(ls -a $*))
      +(+alias 'lt     '(ls -ltr $*))
      +(+alias '..     '(cd ..))
      +(+alias '...    '(cd ../..))
      +(+alias '....   '(cd ../../..))
      +(+alias '.....  '(cd ../../../..))
      +(+alias 'md     '(mkdir -p $*))
      +(+alias 'emacs  '(find-file $1))
      +(+alias 'less   '(find-file-read-only $1))
      +(+alias 'x      '(eshell/exit))
      +
      +;; no need for less or more, this is emacs, isn't it?
      +(setenv "PAGER" "cat")
      diff --git a/conf-lisp/ewww.el b/conf-lisp/ewww.el
      new file mode 100644
      index 0000000..045c158
      --- /dev/null
      +++ b/conf-lisp/ewww.el
      @@ -0,0 +1,36 @@
      +;; *** EWW browser stuff
      +
      +;; Emacs has a builtin browser, which is not too bad.
      +
      +(require 'eww)
      +
      +;; see also: shr-render-[buffer|region] !
      +(defun eww-render-current-buffer ()
      +  "Render HTML in the current buffer with EWW"
      +  (interactive)
      +  (beginning-of-buffer)
      +  (eww-display-html 'utf8 (buffer-name)))
      +
      +(defalias 'render-html 'eww-render-current-buffer)
      +
      +;; eww config
      +(add-hook 'eww-mode-hook #'toggle-word-wrap)
      +(add-hook 'eww-mode-hook #'visual-line-mode)
      +
      +;; custom short commands, see ? for the defaults
      +(define-key eww-mode-map "o" 'eww) ; aka other page
      +(define-key eww-mode-map "f" 'eww-browse-with-external-browser) ; aka firefox
      +(define-key eww-mode-map "j" 'next-line)
      +(define-key eww-mode-map "r" 'eww-reload)
      +(define-key eww-mode-map "s" 'shr-save-contents)
      +(define-key eww-mode-map "v" 'eww-view-source)
      +(define-key eww-mode-map "b" 'eww-add-bookmark)
      +(define-key eww-mode-map "p" 'eww-back-url)
      +(define-key eww-mode-map "n" 'eww-forward-url)
      +
      +;; link short commands
      +(define-key eww-link-keymap "c" 'shr-copy-url)
      +(define-key eww-link-keymap "s" 'shr-save-contents)
      +
      +;; FIXME:  latest GIT  version  of eww  contains 'eww-readable,  which
      +;; hides menus and distractions! Update emacs.
      diff --git a/conf-lisp/followcursor.el b/conf-lisp/followcursor.el
      new file mode 100644
      index 0000000..e40b346
      --- /dev/null
      +++ b/conf-lisp/followcursor.el
      @@ -0,0 +1,17 @@
      +;; *** Followcursor Mode
      +
      +;; [[https://github.com/TLINDEN/followcursor-mode][source on github]]
      +
      +;; From time to time I need to  refactor configs and the like based on
      +;; lists. For example  in the left window  I have a list  of bgp peers
      +;; and in the right window a config file for all peers which I have to
      +;; modify based on current settings.  With followcursor-mode I can put
      +;; point on an  ip address and the line in  the config containing this
      +;; ip address  will be highlighted. If  I move on to  the next address
      +;; the next line on the right will be highlighted.
      +
      +;; The mode is a work-in-progress...
      +
      +(use-package followcursor-mode
      +             :ensure nil)
      +
      diff --git a/conf-lisp/functions.el b/conf-lisp/functions.el
      new file mode 100644
      index 0000000..24fb1c1
      --- /dev/null
      +++ b/conf-lisp/functions.el
      @@ -0,0 +1,620 @@
      +;; * Productivity Functions
      +;; --------------------------------------------------------------------------------
      +;; ** goto line with tmp line numbers
      +
      +;; I stole this somewhere, as far as I remember, emacswiki, however, I
      +;; always had F7 for goto-line
      +
      +(defun goto-line-with-feedback ()
      +  "Show line numbers temporarily, while prompting for the line number input"
      +  (interactive)
      +  (unwind-protect
      +      (progn
      +        (linum-mode 1)
      +        (call-interactively 'goto-line))
      +    (linum-mode -1)))
      +
      +(global-set-key (kbd "")            'goto-line-with-feedback)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** invert fore- and background
      +
      +;; Sometimes when  sitting in a  very dark enviroment, my  usual light
      +;; emacs frame is  a too stark contrast to the  environment. With this
      +;; function  I can  just  invert  my current  color  settings to  dark
      +;; background and light foreground.
      +
      +;; remember last inverse
      +(defvar tvd-invert-state t)
      +
      +;; invert everything, reverse it when called again
      +(defun tvd-invert()
      +  "invert fg-bg"
      +  (interactive)
      +  (invert-face 'default)
      +  (invert-face 'mode-line)
      +  (set-face-attribute 'fringe nil :inverse-video tvd-invert-state)
      +  (setq tvd-invert-state (not tvd-invert-state)) ;; cycle variable tvd-invert-state
      +  )
      +
      +;; fast
      +(global-set-key (kbd "C-c C-i")           'tvd-invert)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Some useful bindings  for Home and End keys Hit  the key once to
      +
      +;; Go to the beginning/end  of a line, hit it twice in a  row to go to
      +;; the beginning/end of  the window, three times in a  row goes to the
      +;; beginning/end of the buffer.  NB that there is no timeout involved.
      +
      +;; Uses a function of viking-mode to establish key repeats, see below.
      +
      +(defun pc-keys-home ()
      +  "Go to beginning of  line/window/buffer. First hitting key goes
      +to  beginning of  line,  second in  a row  goes  to beginning  of
      +window, third in a row goes to beginning of buffer."
      +  (interactive)
      +  (let* ((key-times (viking-last-key-repeats)))
      +    (cond
      +     ((eq key-times 3)
      +      (if mark-active
      +          (goto-char (point-min))
      +        (beginning-of-buffer)))
      +     ((eq key-times 2)
      +      (if mark-active () (push-mark))
      +      (move-to-window-line 0))
      +     ((eq key-times 1)
      +      (beginning-of-line)))))
      +
      +(defun pc-keys-end ()
      +  "Go to end of  line/window/buffer. First hitting key goes
      +to end  of line, second  in a  row goes to  end of
      +window, third in a row goes to end of buffer."
      +  (interactive)
      +  (let* ((key-times (viking-last-key-repeats)))
      +    (cond
      +     ((eq key-times 3)
      +      (if mark-active
      +          (goto-char (point-max))
      +        (end-of-buffer)))
      +     ((eq key-times 2)
      +      (if mark-active () (push-mark))
      +      (move-to-window-line -1)
      +      (end-of-line))
      +     ((eq key-times 1)
      +      (end-of-line)))))
      +
      +;; This is the most natural use for those keys
      +(global-set-key (kbd "")          'pc-keys-home)
      +(global-set-key (kbd "")           'pc-keys-end)
      +
      +
      +
      +;; --------------------------------------------------------------------------------
      +;; ** percent function
      +;; by Jens Heunemann: jump to percent position into current buffer
      +
      +(defun goto-percent (p)                        ;goto Prozentwert (0-100): F8
      +  (interactive "nProzent: ")
      +  (if (> (point-max) 80000)
      +      (goto-char (* (/ (point-max) 100) p))    ;Ueberlauf vermeiden: (max/100)*p
      +    (goto-char (/ (* p (point-max)) 100)))     ;Rundungsfehler verm.: (max*p)/100
      +  (beginning-of-line))
      +
      +(global-set-key (kbd "")            'goto-percent)                                    ;F8 goto percent
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Simulate vi's % (percent) function
      +
      +;; There's not  a lot  about vi[m]  I like,  but jumping  with %  to a
      +;; matching paren is one of THOSE features, I also need in emacs.
      +
      +;; with ideas from [[https://www.emacswiki.org/emacs/NavigatingParentheses#toc2][emacswiki]]
      +
      +;; If (point)  is on a paren,  jump to the matching  paren, otherwise,
      +;; just insert a literal ?%. Only make sense if bound to %.
      +;; Does not jump in inside () though
      +(defun jump-paren-match-or-insert-percent (arg)
      +"Go to  the matching  parenthesis if on  parenthesis. Otherwise
      +insert %. Mimics vi stle of % jumping to matching brace."
      +(interactive "p")
      +(cond ((looking-at "\\s\(\\|\{\\|\\[") (forward-list 1) (backward-char 1))
      +      ((and (looking-at "\\s\)\\|\}\\|\\]")
      +            (not (looking-back "\\s\(\\|\{\\|\\[")))
      +       (forward-char 1) (backward-list 1))
      +       (t (insert "%"))))
      +
      +;; only useful in programming modes
      +(define-key prog-mode-map (kbd "%") 'jump-paren-match-or-insert-percent)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Move region
      +
      +;; Mark a region, then use M-up|down to move it around
      +;; via [[https://www.emacswiki.org/emacs/MoveRegion][emacswiki]]
      +;; code from [[https://github.com/targzeta/move-lines/blob/master/move-lines.el][move-lines]]
      +
      +(defun move-lines--internal (n)
      +  (let* ((start (point)) ;; The position of beginning of line of the first line
      +         (end start)     ;; The position of eol+\n of the end line
      +         col-init        ;; The current column for the first line
      +         (col-end (current-column)) ;; The current column for the end line
      +         exchange_pm     ;; If I had exchanged point and mark
      +         delete-latest-newline) ;; If I had inserted a newline at the end
      +
      +    ;; STEP 1: Identifying the line(s) to cut.
      +    ;; ---
      +    ;; If region is actives, I ensure that point always is at the end of the
      +    ;; region and mark at the beginning.
      +    (when (region-active-p)
      +      (when (< (point) (mark))
      +        (setq exchange_pm t)
      +        (exchange-point-and-mark))
      +      (setq start (mark)
      +            end (point)
      +            col-end (current-column)))
      +
      +    (goto-char start) (setq col-init (current-column))
      +    (beginning-of-line) (setq start (point))
      +
      +    (goto-char end) (end-of-line)
      +    ;; If point == point-max, this buffers doesn't have the trailing newline.
      +    ;; In this case I have to insert a newline otherwise the following
      +    ;; `forward-char' (to keep the "\n") will fail.
      +    (when (= (point) (point-max))
      +      (setq delete-latest-newline t)
      +      (insert-char ?\n) (forward-char -1))
      +    (forward-char 1) (setq end (point))
      +
      +    ;; STEP 2: Moving the lines.
      +    ;; ---
      +    ;; The region I'm cutting span from the beginning of line of the current
      +    ;; line (or current region) to the end of line + 1 (newline) of the current
      +    ;; line (or current region).
      +    (let ((line-text (delete-and-extract-region start end)))
      +      (forward-line n)
      +      ;; If the current-column != 0, I have moved the region at the bottom of a
      +      ;; buffer doesn't have the trailing newline.
      +      (when (not (= (current-column) 0))
      +        (insert-char ?\n)
      +        (setq delete-latest-newline t))
      +      (setq start (+ (point) col-init)) ;; Now, start is the start of new region
      +      (insert line-text))
      +
      +    ;; STEP 3: Restoring
      +    ;; ---
      +    ;; I'm at the end of new region (or line) and start has setted at the
      +    ;; beginning of new region (if a region is active).
      +    ;; Restoring the end column.
      +    (forward-line -1)
      +    (forward-char col-end)
      +
      +    (when delete-latest-newline
      +      (save-excursion
      +        (goto-char (point-max))
      +        (delete-char -1)))
      +
      +    (when (region-active-p)
      +      (setq deactivate-mark nil)
      +      (set-mark start)
      +      (if exchange_pm
      +          (exchange-point-and-mark)))))
      +
      +(defun move-lines-up (n)
      +  "Moves the current line or, if region is actives, the lines surrounding
      +region, up by N lines, or 1 line if N is nil."
      +  (interactive "p")
      +  (if (eq n nil)
      +      (setq n 1))
      +  (move-lines--internal (- n)))
      +
      +(defun move-lines-down (n)
      +  "Moves the current line or, if region is actives, the lines surrounding
      +region, down by N lines, or 1 line if N is nil."
      +  (interactive "p")
      +  (if (eq n nil)
      +      (setq n 1))
      +  (move-lines--internal n))
      +
      +(global-set-key (kbd "M-")          'move-lines-up)
      +(global-set-key (kbd "M-")        'move-lines-down)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** comment-uncomment region with one key binding
      +;; via [[http://stackoverflow.com/a/9697222/3350881][stackoverflow]]
      +(defun comment-or-uncomment-region-or-line ()
      +  "Comments or uncomments the region or the current line if there's no active region."
      +  (interactive)
      +  (let (beg end)
      +    (if (region-active-p)
      +        (setq beg (region-beginning) end (region-end))
      +      (setq beg (line-beginning-position) end (line-end-position)))
      +    (comment-or-uncomment-region beg end)))
      +
      +(global-set-key (kbd "C-c C-c")         'comment-or-uncomment-region-or-line)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** search for symbol at point
      +
      +;; Simulate the # function of vi,  marks the symbol at point, C-s then
      +;; searches for it. I use this a lot.
      +
      +;; via [[http://ergoemacs.org/emacs/modernization_isearch.html][ergomacs]]
      +
      +(defun xah-search-current-word ()
      +  "Call `isearch' on current word or text selection.
      +   'word' here is A to Z, a to z, and hyphen and underline, independent of syntax table.
      +URL `[[http://ergoemacs.org/emacs/modernization_isearch.html'][ergomacs]]
      +Version 2015-04-09"
      +  (interactive)
      +  (let ( xahp1 xahp2 )
      +    (if (use-region-p)
      +        (progn
      +          (setq xahp1 (region-beginning))
      +          (setq xahp2 (region-end)))
      +      (save-excursion
      +        (skip-chars-backward "-_A-Za-z0-9")
      +        (setq xahp1 (point))
      +        (right-char)
      +        (skip-chars-forward "-_A-Za-z0-9")
      +        (setq xahp2 (point))))
      +    (setq mark-active nil)
      +    (when (< xahp1 (point))
      +      (goto-char xahp1))
      +    (isearch-mode t)
      +    (isearch-yank-string (buffer-substring-no-properties xahp1 xahp2))
      +    (message "Now use C-s to search for it ...")
      +    ))
      +
      +(global-set-key (kbd "C-#")             'xah-search-current-word)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Window Margin
      +
      +;; Kinda screen reader  for the poor.  I use this  sometimes with info
      +;; or woman mode. I also use a full featured screen reader: nove-mode,
      +;; see below.
      +
      +;; left+right margin on demand (but nothing else)
      +(defun margin(m)
      +  "set left and right margins for better readability"
      +  (interactive "nEnter Margin (0 to disable) [0-9]+: ")
      +  (set-window-margins (car (get-buffer-window-list (current-buffer) nil t)) m m) ;; set immediately
      +  (setq left-margin-width m) ;; persist until reset
      +  (setq right-margin-width m)
      +  (message "To reset, change Buffer or call again with arg 0.")
      +  )
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Fill and justify a paragraph
      +
      +;; this is just a shortcut for:
      +;;    C-u 70  M-x fill-paragraph
      +;; but C-q is just easier to remember
      +
      +;; however, if pressed again it un-fills the paragraph,
      +;; idea via: [[http://endlessparentheses.com/fill-and-unfill-paragraphs-with-a-single-key.html][endlessparentheses]]
      +(defun tvd-fill-and-justify-or-unfill()
      +  (interactive)
      +  (let ((fill-column
      +         (if (eq last-command 'tvd-fill-and-justify-or-unfill)
      +             (progn (setq this-command nil)
      +                    (point-max))
      +           fill-column)))
      +    (fill-paragraph 70)))
      +
      +(global-set-key (kbd "C-q")             'tvd-fill-and-justify-or-unfill)                   ; like M-q, which is bound to x-window-quit in xmonad: fill+justify
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Make a read-only copy of the current buffer
      +
      +;; I just create  a new read-only buffer and copy  the contents of the
      +;; current one  into it, which  can be used as  backup. I use  this in
      +;; cases where I need to re-factor a file and do lots of changes. With
      +;; the buffer copy  I have a reference to compare  without the need to
      +;; leave emacs and look at revision  control diffs or the like, and if
      +;; a file is not maintained via VC anyway.
      +
      +(defvar copy-counter 0)
      +
      +(defun get-copy-buffer-name()
      +  "return unique copy buffer name"
      +  (let ((name (concat "*COPY " (buffer-name (current-buffer)) " (RO)")))
      +    (if (not (get-buffer name))
      +        (progn
      +          (setq copy-counter (1+ copy-counter))
      +          (concat name "<" (number-to-string copy-counter) ">"))
      +      (concat name))))
      +
      +(defun copy-buffer-read-only()
      +  "Create a read-only copy of the current buffer"
      +  (interactive)
      +  (let ((old-buffer (current-buffer))
      +        (new-buffer-name (get-copy-buffer-name)))
      +    (progn
      +      (delete-other-windows)
      +      (split-window-horizontally)
      +      (other-window 1)
      +      (if (not (eq (get-buffer new-buffer-name) nil))
      +          (kill-buffer (get-buffer new-buffer-name)))
      +      (set-buffer (get-buffer-create new-buffer-name))
      +      (insert-buffer-substring old-buffer)
      +      (read-only-mode)
      +      (switch-to-buffer new-buffer-name)
      +      (other-window 1))))
      +
      +(defalias 'cp        'copy-buffer-read-only)
      +
      +(global-set-key (kbd "C-c C-p")         'copy-buffer-read-only)                           ; make read-only buffer copy
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Cleanup, close all windows and kill all buffers
      +
      +;; From  time  to  time  I  get annoyed  by  the  many  dozen  buffers
      +;; opened. In such cases I like to close them all at once.
      +
      +;; No key binding though,  just in case I stumble upon  it and kill my
      +;; setup accidentally.
      +
      +(defun kill-all-buffers ()
      +  "Kill all buffers, clean up, close all windows"
      +  (interactive)
      +  (when (y-or-n-p "Close all windows and kill all buffers?")
      +    (delete-other-windows)
      +    (clean-buffer-list)
      +    (dolist (buffer (buffer-list))
      +      (kill-buffer buffer))
      +    (delete-minibuffer-contents)
      +    (if (fboundp 'tramp-cleanup-all-connections)
      +        (tramp-cleanup-all-connections))
      +    (with-current-buffer (get-buffer-create "*text*")
      +      (text-mode))
      +    (autoscratch-buffer)))
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Cleanup current buffer
      +
      +;; Remove TABs, leading and trailing spaces, re-indent a buffer.
      +
      +;; via [[http://whattheemacsd.com/buffer-defuns.el-01.html][whattheemacs.d]]
      +
      +(defun cleanup-buffer ()
      +  "Perform a bunch of safe operations on the whitespace content of a buffer.
      +Does not indent buffer, because it is used for a before-save-hook, and that
      +might be bad."
      +  (interactive)
      +  (untabify (point-min) (point-max))
      +  (delete-trailing-whitespace)
      +  (save-excursion
      +    (replace-regexp "^\n\\{3,\\}" "\n\n" nil (point-min) (point-max)))
      +  (set-buffer-file-coding-system 'utf-8)
      +  (indent-region (point-min) (point-max)))
      +
      +(defalias 'cb        'cleanup-buffer)
      +
      +;; related, I  use this  to cleanup directories  and rename  files and
      +;; directories to  my liking.  Sometimes  I get  a disk or  stick from
      +;; Windows  users and  they  use every  character  available on  their
      +;; keyboards to name files and dirs. I can't have this shit.
      +;;
      +(defun cleanup-dired-buffer ()
      +  "If inside a wdired (edit) buffer, rename everything"
      +  (interactive)
      +  (delete-trailing-whitespace)
      +  (save-excursion
      +    (replace-regexp "[\(\)'`#,_&\!]" "" nil (point-min) (point-max))
      +    (replace-string " " "-" nil (point-min) (point-max))
      +    (replace-regexp "--*" "-" nil (point-min) (point-max))
      +    (replace-string "ä" "ae" nil (point-min) (point-max))
      +    (replace-string "ö" "oe" nil (point-min) (point-max))
      +    (replace-string "ü" "ue" nil (point-min) (point-max))
      +    (replace-string "Ä" "Ae" nil (point-min) (point-max))
      +    (replace-string "Ö" "Oe" nil (point-min) (point-max))
      +    (replace-string "Ü" "Ue" nil (point-min) (point-max))
      +    (replace-string "ß" "ss" nil (point-min) (point-max))
      +    (replace-string ".." "." nil (point-min) (point-max))))
      +
      +(defun cleanup-dir()
      +  "Cleanup wdired buffer in one whole step, used for emacsclient buffers"
      +  (interactive)
      +  (wdired-change-to-wdired-mode)
      +  (cleanup-dired-buffer)
      +  (wdired-finish-edit)
      +  (kill-this-buffer))
      +
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Remove Umlauts and other crab in current buffer
      +
      +;; converts:
      +;;            Stan Lem - ein schönes Leben & sonst nix(ungekuerzte Ausgabe)
      +;; to:
      +;;            Stan_Lem-ein_schoenes_Leben_sonst_nix_ungekuerzte_Ausgabe
      +;;
      +;; used in dired buffers to cleanup filenames by german windows users.
      +(defun umlaute-weg()
      +  (interactive)
      +  (let ((umlaute '((Ü . Ue)
      +                   (Ä . Ae)
      +                   (Ö . Oe)
      +                   (ü . ue)
      +                   (ä . ae)
      +                   (ö . oe)
      +                   (ß . ss)))
      +        (regs (list
      +               '(" "       . "_")
      +               '("_-_"     . "-")
      +               '("[\(\)&]" . "_")
      +               '("__*"     . "_")
      +               '("_$"      . "")
      +               )))
      +    (save-excursion
      +      (dolist (pair umlaute)
      +        (replace-regexp (symbol-name (car pair))
      +                        (symbol-name (cdr pair))
      +                        nil
      +                        (point-min) (point-max)))
      +      (dolist (reg regs)
      +        (replace-regexp (car reg) (cdr reg) nil
      +                        (point-min) (point-max))))))
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Better newline(s)
      +
      +;; Add newline  and jump to indent  from wherever I am  in the current
      +;; line, that is it is not required to be on the end of line.
      +
      +;; via [[http://whattheemacsd.com/editing-defuns.el-01.html][whattheemacs.d]]
      +
      +(defun open-line-below ()
      +  (interactive)
      +  (end-of-line)
      +  (newline)
      +  (indent-for-tab-command))
      +
      +(defun open-line-above ()
      +  (interactive)
      +  (end-of-line)
      +  (beginning-of-line)
      +  (newline)
      +  (forward-line -1)
      +  (indent-for-tab-command))
      +
      +;; disabled, interferes with modes.
      +
      +;; (global-set-key (kbd "")      'open-line-below)
      +
      +;; (global-set-key (kbd "")    'open-line-above)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** Mouse Rectangle
      +
      +;; There's not  much use for  the mouse in  emacs, but this  gimick is
      +;; funny and works like a charm.
      +
      +;; via [[http://emacs.stackexchange.com/a/7261][stackoverflow]]
      +(defun mouse-start-rectangle (start-event)
      +  (interactive "e")
      +  (deactivate-mark)
      +  (mouse-set-point start-event)
      +  (rectangle-mark-mode +1)
      +  (let ((drag-event))
      +    (track-mouse
      +      (while (progn
      +               (setq drag-event (read-event))
      +               (mouse-movement-p drag-event))
      +        (mouse-set-point drag-event)))))
      +
      +(global-set-key (kbd "S-") 'mouse-start-rectangle)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** DOS <=> UNIX conversion helpers
      +
      +(defun dos2unix ()
      +  (interactive)
      +  (set-buffer-file-coding-system 'utf-8-unix)
      +  (message (format "converted current buffer to %s" buffer-file-coding-system)))
      +
      +(defun unix2dos ()
      +  (interactive)
      +  (set-buffer-file-coding-system 'utf-8-dos)
      +  (message (format "converted current buffer to %s" buffer-file-coding-system)))
      +;; --------------------------------------------------------------------------------
      +;; ** helper do add the same thing to multiple mode hooks
      +;; via [[http://stackoverflow.com/posts/3900056/revisions][stackoverflow]]
      +;; usage samples below.
      +(defun add-something-to-mode-hooks (mode-list something)
      +  "helper function to add a callback to multiple hooks"
      +  (dolist (mode mode-list)
      +    (add-hook (intern (concat (symbol-name mode) "-mode-hook")) something)))
      +
      +;; --------------------------------------------------------------------------------
      +
      +;; ** helper to catch load errors
      +
      +;; Try to  eval 'fn,  catch errors,  if any but  make it  possible for
      +;; emacs to continue undisturbed, used with SMEX, see below.
      +(defmacro safe-wrap (fn &rest clean-up)
      +  `(unwind-protect
      +       (let (retval)
      +         (condition-case ex
      +             (setq retval (progn ,fn))
      +           ('error
      +            (message (format "Caught exception: [%s]" ex))
      +            (setq retval (cons 'exception (list ex)))))
      +         retval)
      +     ,@clean-up))
      +;; --------------------------------------------------------------------------------
      +;; ** Alignment Wrappers
      +
      +;; align-regexp is already  a very usefull tool,  however, sometimes I
      +;; want  to repeat  the alignment  and I  hate C-u,  so here  are some
      +;; wrappers to make this easier.
      +
      +(defun align-repeat (regex &optional alignment)
      +  "Aply  REGEX  to all  columns  not  just  the first.  Align  by
      +ALIGNMENT which must be 'left or 'right. The default is 'left.
      +
      +Right alignment:
      +
      +col1 ,col2
      +col1 ,col2
      +
      +Left alignment:
      +
      +col1, col2
      +col1, col2"
      +  (interactive  "MRepeat Align Regex [ ]: ")
      +  (let ((spc " ")
      +        (beg (point-min))
      +        (end (point-max))
      +        (areg "%s\\(\\s-*\\)" ; default left aligned
      +              ))
      +    (when (string= regex "")
      +      (setq regex spc))
      +    (when (region-active-p)
      +      (setq beg (region-beginning))
      +      (setq end (region-end)))
      +    (when (eq alignment 'right)
      +        (setq areg "\\(\\s-*\\)%s"))
      +    (align-regexp beg end (format areg regex) 1 1 t)))
      +
      +(defun align-repeat-left (regex)
      +  (interactive  "MRepeat Left Align Regex [ ]: ")
      +  (align-regexp-repeat regex 'left))
      +
      +(defun align-repeat-right (regex)
      +  (interactive  "MRepeat Left Align Regex [ ]: ")
      +  (align-regexp-repeat regex 'right))
      +
      +
      +;; ** String Helpers
      +
      +;; Some helper functions I use here and there.
      +
      +(defun tvd-alist-keys (A)
      +  "return a list of keys of alist A"
      +  (let ((K ()))
      +    (dolist (e A)
      +            (push (car e) K)
      +            )
      +    K))
      +
      +(defun tvd-get-line ()
      +  "return current line in current buffer"
      +  (buffer-substring-no-properties
      +   (line-beginning-position)
      +   (line-end-position)))
      +
      +(defun tvd-starts-with (s begins)
      +  "Return non-nil if string S starts with BEGINS."
      +  (cond ((>= (length s) (length begins))
      +         (string-equal (substring s 0 (length begins)) begins))
      +        (t nil)))
      +
      +(defun tvd-replace-all (regex replace)
      +  "Replace all matches of REGEX with REPLACE in current buffer."
      +  (interactive)
      +  (goto-char (point-min))
      +  (while (re-search-forward regex nil t)
      +    (replace-match replace)))
      diff --git a/conf-lisp/globalbindings.el b/conf-lisp/globalbindings.el
      new file mode 100644
      index 0000000..f572c19
      --- /dev/null
      +++ b/conf-lisp/globalbindings.el
      @@ -0,0 +1,93 @@
      +;;; * Global Key Bindings
      +;; --------------------------------------------------------------------------------
      +;; ** c-h != delete
      +(keyboard-translate ?\C-h ?\C-?)
      +(keyboard-translate ?\C-? ?\C-h)
      +
      +;; --------------------------------------------------------------------------------
      +;; ** general keys (re-)mappings
      +;(global-set-key (kbd "C-s")             'isearch-forward-regexp)
      +;(global-set-key (kbd "C-r")             'isearch-backward-regexp)
      +(global-set-key (kbd "M-C-s")           'isearch-forward)
      +(global-set-key (kbd "M-C-r")           'isearch-backward)
      +(global-set-key (kbd "M-%")             'query-replace-regexp)
      +(global-set-key (kbd "")       'dabbrev-completion)                              ; shift-tab, inline completion
      +
      +(global-set-key (kbd "")            'html-mode)
      +(global-set-key (kbd "")        'delete-char)                                     ; Entf            Char loeschen
      +(global-set-key (kbd "")     'backward-delete-char)                            ; Shift+Backspace dito
      +(global-set-key (kbd "S-")      'kill-word)                                       ; Shift+Entf      Wort loeschen
      +(global-set-key (kbd "S-")   'backward-kill-word)                              ; Shift+Backspace dito
      +(global-set-key (kbd "C-")      'kill-word)                                       ; Shift+Entf      dito
      +(global-set-key (kbd "C-")   'backward-kill-word)                              ; Shift+Backspace dito
      +(global-unset-key (kbd "C-z"))
      +(global-set-key (kbd "C-x k")           'kill-this-buffer)                                ; C-x k  really kill current buffer w/o asking
      +(global-set-key (kbd "C-x C-b")         'buffer-menu)
      +
      +
      +
      +;; --------------------------------------------------------------------------------
      +;; ** display a list of my own global key bindings and aliases
      +;; via [[https://www.emacswiki.org/emacs/OccurMode#toc9][emacswiki]]
      +
      +;; Inside *Occur*: q - quit, e - edit, g - reload
      +;; more help with: describe-function occur-mode
      +
      +(defun occur-mode-clean-buffer ()
      +  "Removes all commentary from the *Occur* buffer, leaving the
      + unadorned lines."
      +  (interactive)
      +  (if (get-buffer "*Occur*")
      +      (save-excursion
      +        (set-buffer (get-buffer "*Occur*"))
      +        (goto-char (point-min))
      +        (toggle-read-only 0)
      +        (if (looking-at "^[0-9]+ lines matching \"")
      +            (kill-line 1))
      +        (while (re-search-forward "^[ \t]*[0-9]+:"
      +                                  (point-max)
      +                                  t)
      +          (replace-match "")
      +          (forward-line 1)))
      +    (message "There is no buffer named \"*Occur*\".")))
      +
      +(defun show-definition(REGEX)
      +  (interactive)
      +  (let ((dotemacs-loaded nil)
      +        (occur-b "*Occur*")
      +        (occur-c ""))
      +    (if (get-buffer ".emacs")
      +        (progn
      +          (switch-to-buffer ".emacs")
      +          (setq dotemacs-loaded t))
      +      (find-file "~/.emacs"))
      +    (occur REGEX)
      +    (with-current-buffer occur-b
      +      (occur-mode-clean-buffer)
      +      (setq occur-c (current-buffer))
      +      (let ((inhibit-read-only t)) (set-text-properties (point-min) (point-max) ()))
      +      (while (re-search-forward "[0-9]*:" nil t)
      +        (replace-match ""))
      +      (beginning-of-buffer)
      +      (kill-line)
      +      (sort-lines nil (point-min) (point-max))
      +      (emacs-lisp-mode)
      +      (beginning-of-buffer)
      +      (insert (format ";; *SHOW*:   %s\n" REGEX))
      +      (highlight-regexp REGEX)
      +      (beginning-of-buffer))
      +    (switch-to-buffer occur-b)
      +    (delete-other-windows)
      +    (if (eq dotemacs-loaded nil)
      +        (kill-buffer ".emacs"))))
      +
      +(defun show-keys()
      +  (interactive)
      +  (show-definition "^(global-set-key"))
      +
      +(defun show-aliases()
      +  (interactive)
      +  (show-definition "^(defalias"))
      +
      +(defalias 'sk        'show-keys)
      +(defalias 'sa        'show-aliases)
      diff --git a/conf-lisp/go.el b/conf-lisp/go.el
      new file mode 100644
      index 0000000..a252f80
      --- /dev/null
      +++ b/conf-lisp/go.el
      @@ -0,0 +1,13 @@
      +;; *** Go Lang
      +
      +(use-package go-mode
      +             :mode "\\.go\\'"
      +             :mode "\\.mod\\'"
      +
      +             :config
      +             (setq gofmt-args '("-s"))
      +             (setq tab-width 4)
      +             (setq indent-tabs-mode 1)
      +
      +             :init
      +             (add-hook 'before-save-hook 'gofmt-before-save))
      diff --git a/conf-lisp/help.el b/conf-lisp/help.el
      new file mode 100644
      index 0000000..d5daf26
      --- /dev/null
      +++ b/conf-lisp/help.el
      @@ -0,0 +1,22 @@
      +;; *** Help Mode
      +
      +;; I even customize help windows! ... at least a little :)
      +
      +(defun tvd-close-help ()
      +  (interactive)
      +  (kill-this-buffer)
      +  (winner-undo))
      +
      +(eval-after-load "Help"
      +  '(progn
      +     (add-hook 'help-mode-hook
      +               (lambda ()
      +                 ; doesn' work the way I like
      +                 ;(local-set-key (kbd "q") 'tvd-close-help)
      +                 (local-set-key (kbd "q") 'quit-window)
      +                 (local-set-key (kbd "p") 'help-go-back)
      +                 (local-set-key (kbd "b") 'help-go-back)
      +                 (local-set-key (kbd "n") 'help-go-forward)
      +                 (local-set-key (kbd "f") 'help-go-forward)
      +                 (setq help-window-select t)
      +                 ))))
      diff --git a/conf-lisp/hydra.el b/conf-lisp/hydra.el
      new file mode 100644
      index 0000000..a92bdf0
      --- /dev/null
      +++ b/conf-lisp/hydra.el
      @@ -0,0 +1,2 @@
      +;; Used here and there below, loaded as early as possible
      +(use-package hydra)
      diff --git a/conf-lisp/ibuffer.el b/conf-lisp/ibuffer.el
      new file mode 100644
      index 0000000..dbceb4b
      --- /dev/null
      +++ b/conf-lisp/ibuffer.el
      @@ -0,0 +1,134 @@
      +;; *** iBuffer mode
      +
      +;; iBuffer is a great interactive buffer management tool included with
      +;; emacs.   I  use  it  with  a   couple  of  custom  groups,  my  own
      +;; collapse-code () and formats.
      +
      +(require 'ibuffer)
      +
      +;; from github:
      +(use-package ibuffer-vc)
      +(use-package ibuffer-tramp)
      +
      +;; replace default list-buffers with ibuffer
      +(global-set-key (kbd "C-x C-b")         'ibuffer)
      +
      +;; group name
      +(setq tvd-ibuffer-filter-group-name "tvd-filters")
      +
      +;; filter group config
      +;; with hints from [[https://ogbe.net/emacsconfig.html][Ogbe]] et.al.
      +(setq ibuffer-saved-filter-groups
      +      (list (nreverse
      +             `(
      +               ("Org" (mode . org-mode))
      +               ("Shell" (or (mode . term-mode)
      +                            (mode . eshell-mode)
      +                            (mode . shell-mode)))
      +               ("Emacs-Config"  (filename . "emacs"))
      +               ("Cisco-Config" (mode . cisco-mode))
      +               ("Code" (or (mode . cperl-mode)
      +                           (mode . c-mode)
      +                           (mode . python-mode)
      +                           (mode . shell-script-mode)
      +                           (mode . makefile-mode)
      +                           (mode . cc-mode)))
      +               ("Text" (or (mode . text-mode)
      +                           (filename . "\\.pod$")))
      +               ("LaTeX" (mode . latex-mode))
      +               ("Interactive" (or
      +                               (mode . inferior-python-mode)
      +                               (mode . slime-repl-mode)
      +                               (mode . inferior-lisp-mode)
      +                               (mode . inferior-scheme-mode)
      +                               (name . "*ielm*")))
      +               ("Crab" (or
      +                        (name . "^\\*\\(Help\\|scratch\\|Messages\\)\\*")
      +                          ))
      +               ,tvd-ibuffer-filter-group-name))))
      +
      +;; Reverse the  order of the  filter groups. Kind of  confusing: Since
      +;; I'm reversing the  order of the groups above,  this snippet ensures
      +;; that the groups are ordered in the way they are written above, with
      +;; the "Default" group on top. This  advice might need to be ported to
      +;; the new advice system soon.
      +
      +(defadvice ibuffer-generate-filter-groups
      +    (after reverse-ibuffer-groups () activate)
      +  (setq ad-return-value (nreverse ad-return-value)))
      +
      +(defun ibuffer-add-dynamic-filter-groups ()
      +  (interactive)
      +  (dolist (group (ibuffer-vc-generate-filter-groups-by-vc-root))
      +    (add-to-list 'ibuffer-filter-groups group))
      +  (dolist (group (ibuffer-tramp-generate-filter-groups-by-tramp-connection))
      +    (add-to-list 'ibuffer-filter-groups group)))
      +
      +(defun tvd-ibuffer-hooks ()
      +  (ibuffer-auto-mode 1)
      +  (ibuffer-switch-to-saved-filter-groups tvd-ibuffer-filter-group-name)
      +  (ibuffer-add-dynamic-filter-groups)
      +  (ibuffer-vc-set-filter-groups-by-vc-root)
      +  )
      +(add-hook 'ibuffer-mode-hook 'tvd-ibuffer-hooks)
      +
      +;; Only show groups that have active buffers
      +(setq ibuffer-show-empty-filter-groups nil)
      +
      +;; Don't show the summary or headline
      +(setq ibuffer-display-summary nil)
      +
      +;; do not prompt for every action
      +(setq ibuffer-expert t)
      +
      +;; buffers to always ignore
      +(add-to-list 'ibuffer-never-show-predicates "^\\*\\(Completions\\|tramp/\\)")
      +
      +;; Use human readable Size column instead of original one
      +(define-ibuffer-column size-h
      +  (:name "Size" :inline t)
      +  (cond
      +   ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
      +   ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0)))
      +   ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
      +   (t (format "%8d" (buffer-size)))))
      +
      +;; Modify the default ibuffer-formats
      +(setq ibuffer-formats
      +      '((mark modified read-only " "
      +              (name 20 40 :left :elide)
      +              " "
      +              (size-h 9 -1 :right)
      +              " "
      +              (mode 16 16 :left :elide)
      +              " "
      +              (vc-status 16 16 :left)
      +              " "
      +              filename-and-process)))
      +
      +;; hide annoying groups, but keep its buffers available
      +(defvar ibuffer-collapsed-groups (list "Crab"))
      +
      +(advice-add 'ibuffer :after '(lambda (&rest args)
      +  (ignore args)
      +  (save-excursion
      +    (dolist (group ibuffer-collapsed-groups)
      +      (ignore-errors
      +        (ibuffer-jump-to-filter-group group)
      +        (ibuffer-toggle-filter-group))))))
      +
      +;; move point to most recent buffer when entering ibuffer
      +(defadvice ibuffer (around ibuffer-point-to-most-recent) ()
      +           "Open ibuffer with cursor pointed to most recent (non-minibuffer) buffer name"
      +           (let ((recent-buffer-name
      +                  (if (minibufferp (buffer-name))
      +                      (buffer-name
      +                       (window-buffer (minibuffer-selected-window)))
      +                    (buffer-name (other-buffer)))))
      +             ad-do-it
      +             (ibuffer-jump-to-buffer recent-buffer-name)))
      +(ad-activate 'ibuffer)
      +
      +;; override ibuffer M-o binding
      +(define-key ibuffer-mode-map (kbd "M-o")    'other-window-or-switch-buffer)
      +
      diff --git a/conf-lisp/imenu.el b/conf-lisp/imenu.el
      new file mode 100644
      index 0000000..01e0eaa
      --- /dev/null
      +++ b/conf-lisp/imenu.el
      @@ -0,0 +1,58 @@
      +;;; ** load imenu
      +(require 'imenu)
      +(define-key global-map [C-down-mouse-2] 'imenu)
      +
      +;; via https://superuser.com/questions/601982/how-to-quickly-navigate-jump-between-functions-on-emacs
      +(defun ido-imenu ()
      +  "Update the imenu index and then use ido to select a symbol to navigate to.
      +Symbols matching the text at point are put first in the completion list."
      +  (interactive)
      +  (imenu--make-index-alist)
      +  (let ((name-and-pos '())
      +        (symbol-names '()))
      +    (flet ((addsymbols
      +            (symbol-list)
      +            (when (listp symbol-list)
      +              (dolist (symbol symbol-list)
      +                (let ((name nil) (position nil))
      +                  (cond
      +                   ((and (listp symbol) (imenu--subalist-p symbol))
      +                    (addsymbols symbol))
      +
      +                   ((listp symbol)
      +                    (setq name (car symbol))
      +                    (setq position (cdr symbol)))
      +
      +                   ((stringp symbol)
      +                    (setq name symbol)
      +                    (setq position
      +                          (get-text-property 1 'org-imenu-marker symbol))))
      +
      +                  (unless (or (null position) (null name))
      +                    (add-to-list 'symbol-names name)
      +                    (add-to-list 'name-and-pos (cons name position))))))))
      +      (addsymbols imenu--index-alist))
      +    ;; If there are matching symbols at point, put them at the beginning
      +    ;; of `symbol-names'.
      +    (let ((symbol-at-point (thing-at-point 'symbol)))
      +      (when symbol-at-point
      +        (let* ((regexp (concat (regexp-quote symbol-at-point) "$"))
      +               (matching-symbols
      +                (delq nil (mapcar
      +                           (lambda (symbol)
      +                             (if (string-match regexp symbol) symbol))
      +                           symbol-names))))
      +          (when matching-symbols
      +            (sort matching-symbols (lambda (a b) (> (length a) (length b))))
      +            (mapc
      +             (lambda (symbol)
      +               (setq symbol-names (cons symbol (delete symbol symbol-names))))
      +             matching-symbols)))))
      +    (let* ((selected-symbol (ido-completing-read "Symbol? " symbol-names))
      +           (position (cdr (assoc selected-symbol name-and-pos))))
      +      (push-mark)
      +      (if (overlayp position)
      +          (goto-char (overlay-start position))
      +        (goto-char position)))))
      +
      +(global-set-key (kbd "C-c C-j") 'ido-imenu)
      diff --git a/conf-lisp/indentation.el b/conf-lisp/indentation.el
      new file mode 100644
      index 0000000..fdbb9b7
      --- /dev/null
      +++ b/conf-lisp/indentation.el
      @@ -0,0 +1,34 @@
      +;; *** Highlighting Indentation
      +;; provides: highlight-indentation-mode and highlight-indentation-current-column-mode
      +(use-package highlight-indentation
      +             :config
      +
      +             (add-something-to-mode-hooks
      +              '(yaml python ruby) 'highlight-indentation-current-column-mode)
      +
      +             (set-face-background 'highlight-indentation-face "#e3e3d3")
      +             (set-face-background 'highlight-indentation-current-column-face "#c3b3b3"))
      +
      +
      +;;; ** global TAB/Indent config
      +
      +;; I  use spaces  everywhere  but  Makefiles. If  I  encounter TABs  I
      +;; replace them with  spaces, if I encounter users  entering TABs into
      +;; files, I block them.
      +
      +;; FIXME: also check [[https://github.com/glasserc/ethan-wspace][ethan-wspace]] !
      +
      +(setq indent-line-function 'insert-tab)
      +(setq tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120)))
      +(setq tab-always-indent 'complete) ; FIXME: doesnt work in cperl-mode
      +(setq show-trailing-whitespace t)
      +
      +(defun indent-buffer ()
      +  ;; Author: Mathias Creutz
      +  "Re-Indent every line in the current buffer."
      +  (interactive)
      +  (indent-region (point-min) (point-max) nil))
      +
      +;; Use normal tabs in makefiles
      +(add-hook 'makefile-mode-hook '(lambda() (setq indent-tabs-mode t)))
      +
      diff --git a/conf-lisp/info.el b/conf-lisp/info.el
      new file mode 100644
      index 0000000..d96dae7
      --- /dev/null
      +++ b/conf-lisp/info.el
      @@ -0,0 +1,105 @@
      +;; *** INFO Mode
      +
      +(require 'info)
      +
      +;; open an info file somewhere outside %infodir% with info-mode
      +(defun info-find-file (file)
      +  (interactive "f")
      +  (info-setup file
      +              (pop-to-buffer-same-window
      +               (format "*info*<%s>"
      +                       (file-name-sans-extension
      +                        (file-name-nondirectory file))))))
      +
      +;; easier navigation in Info mode, intuitive history back and forth.
      +(eval-after-load "Info"
      +  '(progn
      +     (define-key Info-mode-map (kbd "")  'Info-history-back)
      +     (define-key Info-mode-map (kbd "") 'Info-history-forward)
      +     (use-package info+
      +                  :ensure nil)))
      +
      +;; make Info great again!
      +;; [[http://mbork.pl/2014-12-27_Info_dispatch][based on Marcins]] info dispatch,
      +;; contains (interactive) code from 'info-display-manual for manual selection.
      +(defun i (manual)
      +    "Read documentation for MANUAL in the info system.  Name the
      +buffer '*Info MANUAL*'.  If that buffer is already present, just
      +switch to it.
      +
      +If MANUAL not given as argument, ask interactively with completion
      +to select from a list of installed manuals."
      +  (interactive
      +   (list
      +    (progn
      +      (info-initialize)
      +      (ido-completing-read "Manual name: "
      +                       (info--manual-names current-prefix-arg)
      +                       nil t))))
      +  (let ((buffer (format "*Info %s*" manual)))
      +    (if (get-buffer buffer)
      +      (switch-to-buffer bufer)
      +      (info manual buffer))))
      +
      +;; from examples, I love this one!, replaces the ? buffer
      +(define-key Info-mode-map (kbd "?") #'hydra-info/body)
      +(defhydra hydra-info (:color blue
      +                      :hint nil)
      +      "
      +Info-mode:
      +  ^^_]_ forward  (next logical node)       ^^_l_ast (←)        _u_p (↑)                             _f_ollow reference       _T_OC
      +  ^^_[_ backward (prev logical node)       ^^_r_eturn (→)      _m_enu (↓) (C-u for new window)      _i_ndex                  _d_irectory
      +  ^^_n_ext (same level only)               ^^_H_istory         _g_oto (C-u for new window)          _,_ next index item      _c_opy node name
      +  ^^_p_rev (same level only)               _<_/_t_op           _b_eginning of buffer                virtual _I_ndex          _C_lone buffer
      +  regex _s_earch (_S_ case sensitive)      ^^_>_ final         _e_nd of buffer                      ^^                       _a_propos
      +
      +  _1_ .. _9_ Pick first .. ninth item in the node's menu.
      +
      +"
      +      ("]"   Info-forward-node nil)
      +      ("["   Info-backward-node nil)
      +      ("n"   Info-next nil)
      +      ("p"   Info-prev nil)
      +      ("s"   Info-search nil)
      +      ("S"   Info-search-case-sensitively nil)
      +
      +      ("l"   Info-history-back nil)
      +      ("r"   Info-history-forward nil)
      +      ("H"   Info-history nil)
      +      ("t"   Info-top-node nil)
      +      ("<"   Info-top-node nil)
      +      (">"   Info-final-node nil)
      +
      +      ("u"   Info-up nil)
      +      ("^"   Info-up nil)
      +      ("m"   Info-menu nil)
      +      ("g"   Info-goto-node nil)
      +      ("b"   beginning-of-buffer nil)
      +      ("e"   end-of-buffer nil)
      +
      +      ("f"   Info-follow-reference nil)
      +      ("i"   Info-index nil)
      +      (","   Info-index-next nil)
      +      ("I"   Info-virtual-index nil)
      +
      +      ("T"   Info-toc nil)
      +      ("d"   Info-directory nil)
      +      ("c"   Info-copy-current-node-name nil)
      +      ("C"   clone-buffer nil)
      +      ("a"   info-apropos nil)
      +
      +      ("1"   Info-nth-menu-item nil)
      +      ("2"   Info-nth-menu-item nil)
      +      ("3"   Info-nth-menu-item nil)
      +      ("4"   Info-nth-menu-item nil)
      +      ("5"   Info-nth-menu-item nil)
      +      ("6"   Info-nth-menu-item nil)
      +      ("7"   Info-nth-menu-item nil)
      +      ("8"   Info-nth-menu-item nil)
      +      ("9"   Info-nth-menu-item nil)
      +
      +      ("?"   Info-summary "Info summary")
      +      ("h"   Info-help "Info help")
      +      ("q"   Info-exit "Info exit")
      +      ("C-g" nil "cancel" :color blue))
      +
      diff --git a/conf-lisp/macros.el b/conf-lisp/macros.el
      new file mode 100644
      index 0000000..3c8c848
      --- /dev/null
      +++ b/conf-lisp/macros.el
      @@ -0,0 +1,170 @@
      +;; *** MACROs
      +
      +;; help: [[https://www.emacswiki.org/emacs/KeyboardMacrosTricks][emacswiki macro tricks]].
      +
      +;; Default keybindings:
      +;; start-kbd-macro default binding: ‘C-x (’     — Starts recording a keyboard macro.
      +;; end-kbd-macro default binding: ‘C-x )’       — Ends recording of a keyboard macro.
      +;; call-last-kbd-macro default binding: ‘C-x e’ — Executes the last keyboard macro defined.
      +
      +;; however, I use [[https://github.com/Silex/elmacro][elmacro]].
      +
      +(use-package elmacro
      +             :config
      +             (elmacro-mode)
      +
      +             (setq tvd-macro-name "last-macro")
      +
      +             ;; ignore stuff
      +             (add-to-list 'elmacro-unwanted-commands-regexps "^(mouse.*)$")
      +             (add-to-list 'elmacro-unwanted-commands-regexps "^(tvd-start-or-stop-macro)$")
      +
      +             (defun tvd-get-macro-name()
      +               "Ask for a macro name, check for duplicates.
      +If the given name is already defined, ask again (and again until unique).
      +If a buffer with the given name exists, kill it (that is, the buffer is
      +there but has not been saved or evaluated yet). Return the name as string."
      +               (interactive)
      +               (let ((done nil)
      +                     (name nil)
      +                     (mbuf nil)
      +                     (err ""))
      +                 (while (not done)
      +                   (setq name (read-string
      +                               (format "%s - enter macro name (last-macro): " err) nil nil "last-macro"))
      +                   (if (fboundp (intern name))
      +                       (setq err (format "macro '%s is already defined" name))
      +                     (setq mbuf (format "* elmacro - %s *" name))
      +                     (if (get-buffer mbuf)
      +                         (with-current-buffer mbuf
      +                           (kill-buffer mbuf)))
      +                     (setq done t)))
      +                 name))
      +
      +             (defun tvd-get-exec-macro-name()
      +               "Ask for a macro name to be executed"
      +               (interactive)
      +               (let ((macros ())
      +                     (N 1)
      +                     (S nil)
      +                     (T ""))
      +                 (dolist (entry (cdr (assoc tvd-macro-file load-history )))
      +                   (setq S (cdr entry))
      +                   (setq T (symbol-name S))
      +                   (push (list T N) macros)
      +                   (setq N (1+ N)))
      +                 (completing-read "enter macro name: " macros nil t nil)))
      +
      +             ;; the heart of my elmacro stuff
      +             (defun tvd-start-or-stop-macro()
      +               "start macro or stop if started"
      +               (interactive)
      +               (if (eq defining-kbd-macro nil)
      +                   (progn
      +                     (elmacro-clear-command-history)
      +                     (start-kbd-macro nil)
      +                     (message "Recording macro. Finish with  ..."))
      +                 (progn
      +                   (call-interactively 'end-kbd-macro)
      +                   (setq tvd-macro-name (tvd-get-macro-name))
      +                   (elmacro-show-last-macro tvd-macro-name)
      +                   (message "Recording done. Execute with , save or  buffer..."))))
      +
      +             ;; better than the default function
      +             (defun tvd-exec-last-macro(&optional ARG)
      +               "execute last macro (or ARG, if given) repeatedly after every
      +, abort with C-g or q, and repeat until EOF after pressing a.
      +
      +If macro defun is known (i.e. because you evaluated the elmacro buffer
      +containing the generated defun), it will be executed. Otherwise the
      +last kbd-macro will be executed."
      +               (interactive)
      +               (let ((melm-count 0)
      +                     (melm-all nil)
      +                     (melm-abort nil)
      +                     (melm-beg (eobp))
      +                     (melm-code (or ARG tvd-macro-name)))
      +                 (if (eobp)
      +                     (if (yes-or-no-p "(point) is at end of buffer. Jump to top?")
      +                         (goto-char (point-min))))
      +                 (while (and (not melm-abort)
      +                             (not (eobp)))
      +                   (when (not melm-all)
      +                     (message (concat
      +                               (format
      +                                "Executing last macro '%s (%d). Keys:\n"  melm-code melm-count)
      +                               "      repeat once\n"
      +                               "a            repeat until EOF\n"
      +                               "e            enter macro name to execute\n"
      +                               " or q   abort ..\n "))
      +                     (setq K (read-event))
      +                     (cond ((or (eq K 'return) (eq K 'C-f6)) t)
      +                           ((equal (char-to-string K) "q") (setq melm-abort t))
      +                           ((equal (char-to-string K) "a") (message "Repeating until EOF")(setq melm-all t))
      +                           ((equal (char-to-string K) "e") (setq tvd-macro-name (tvd-get-exec-macro-name)))
      +                           (t (setq melm-abort t))))
      +                   (if (not melm-abort)
      +                       (progn
      +                         (if (fboundp (intern melm-code))
      +                             (call-interactively (intern melm-code))
      +                           (call-interactively 'call-last-kbd-macro))
      +                         (setq melm-count (1+ melm-count)))))
      +                 (if (and (eq melm-count 0) (eq (point) (point-max)))
      +                     (message "(point) is at end of buffer, aborted")
      +                   (message (format "executed '%s %d times" melm-code melm-count)))))
      +
      +             ;; My macro recording workflow:
      +             ;; - shift-F6
      +             ;; - ... do things  ...
      +             ;; - shift-F6 again
      +             ;; - enter a  name
      +             ;; - a new buffer with macro defun appears
      +             ;; - C-x C-e evals it
      +             ;; - C-F6 (repeatedly) executes it.
      +             (global-set-key (kbd "")            'tvd-start-or-stop-macro)
      +             (global-set-key (kbd "")          'tvd-exec-last-macro)
      +
      +             ;; I use my own macro file
      +             (setq tvd-macro-file (concat tvd-config-dir "/macros.el"))
      +
      +             ;; but only load if in use
      +             (if (file-exists-p tvd-macro-file)
      +                 (load-file tvd-macro-file))
      +
      +             (defun tvd-macro-store()
      +               "store current macro to emacs config"
      +               (interactive)
      +               (copy-region-as-kill (point-min) (point-max))
      +               (if (not (get-buffer "macros.el"))
      +                   (find-file tvd-macro-file))
      +               (with-current-buffer "macros.el"
      +                 (goto-char (point-max))
      +                 (newline)
      +                 (insert ";;")
      +                 (newline)
      +                 (insert (format ";; elmacro added on %s" (current-time-string)))
      +                 (newline)
      +                 (yank)
      +                 (newline)
      +                 (save-buffer))
      +               (switch-to-buffer nil)
      +               (delete-window))
      +
      +             (defalias 'ms        'tvd-macro-store)
      +
      +             (defun tvd-macro-gen-repeater-and-save()
      +               "generate repeater and save the defun's
      +Runs when (point) is at 0,0 of generated
      +defun."
      +               (next-line)
      +               (goto-char (point-max))
      +               (newline)
      +               (insert (format "(defun %s-repeat()\n" tvd-macro-name))
      +               (insert "  (interactive)\n")
      +               (insert (format "  (tvd-exec-last-macro \"%s\"))\n" tvd-macro-name))
      +               (newline)
      +               (eval-buffer)
      +               (tvd-macro-store))
      +
      +             (advice-add 'elmacro-show-defun :after '(lambda (&rest args)
      +                                                       (tvd-macro-gen-repeater-and-save))))
      diff --git a/conf-lisp/magit.el b/conf-lisp/magit.el
      new file mode 100644
      index 0000000..87196e5
      --- /dev/null
      +++ b/conf-lisp/magit.el
      @@ -0,0 +1,87 @@
      +;; *** Magit
      +
      +;; Not much to  say about Magit
      +(use-package magit
      +             :ensure t
      +             :config
      +
      +             (defun tvd-magit-status ()
      +               "Always call `magit-status' with prefix arg."
      +               (interactive)
      +               (let ((current-prefix-arg t))
      +                 (call-interactively 'magit-status)))
      +
      +             ;; (with-eval-after-load 'info
      +             ;;   (info-initialize)
      +             ;;   (add-to-list 'Info-directory-list
      +             ;;                (expand-file-name (concat "~/.emacs.d/lisp/magit-"
      +             ;;                                          tvd-magit-revision
      +             ;;                                          "/Documentation/"))))
      +             (setq magit-view-git-manual-method 'woman)
      +
      +             (defalias 'git       'magit-status)
      +             (defalias 'gitlog    'magit-log-buffer-file)
      +
      +             ;; configure magit
      +             (with-eval-after-load 'magit
      +               (dolist (dir (list (expand-file-name "~/D/github")
      +                                  (expand-file-name "~/fits/git")
      +                                  (expand-file-name "~/dev/git")))
      +                 (when (file-exists-p dir)
      +                   (add-to-list 'magit-repository-directories (cons dir 1))))
      +               (setq magit-completing-read-function 'magit-ido-completing-read)
      +
      +               ;; use timestamps in log buffers
      +               (setq magit-log-margin '(t "%Y-%m-%d " magit-log-margin-width t 18))
      +
      +               ;; navigate magit buffers as I do everywhere else, I do not automatically
      +               ;; cycle/decycle though, the magit defaults are absolutely sufficient.
      +               (define-key magit-mode-map (kbd "") 'magit-section-forward-sibling)
      +               (define-key magit-mode-map (kbd "")   'magit-section-backward-sibling)
      +               (define-key magit-mode-map (kbd "") 'magit-delete-thing))
      +
      +             ;; one thing though:  on startup it bitches about git  version, but it
      +             ;; works nevertheless. So I disable this specific warning.
      +
      +             (defun tvd-ignore-magit-warnings-if-any ()
      +               (interactive)
      +               (when (get-buffer "*Warnings*")
      +                 (with-current-buffer "*Warnings*"
      +                   (goto-char (point-min))
      +                   (when (re-search-forward "Magit requires Git >=")
      +                     (kill-buffer-and-window)))))
      +
      +             (add-hook 'after-init-hook 'tvd-ignore-magit-warnings-if-any t)
      +
      +             ;; now, THIS is the pure genius me: hit "ls in magit-status buffer
      +             ;; and end up in a dired buffer of current repository. The default
      +             ;; binding for this is C-M-i, which is not memorizable, while "ls"
      +             ;; is. That is, 'l' is a prefix command leading to magit-log-popup
      +             ;; and 's' is undefined, which I define here, which then jumps to
      +             ;; dired.
      +             ;; see: https://github.com/magit/magit/wiki/Converting-popup-modifications-to-transient-modifications#adding-an-action
      +             (transient-append-suffix 'magit-log "l"
      +               '("s" "dired" magit-dired-jump))
      +
      +             ;; after an exhausting discussion on magit#3139 I use this function
      +             ;; to (kind of) switch to another repository from inside magit-status.
      +             (defun tvd-switch-magit-repo ()
      +               (interactive)
      +               (let ((dir (magit-read-repository)))
      +                 (magit-mode-bury-buffer)
      +                 (magit-status dir)))
      +             (define-key magit-mode-map (kbd "C") 'tvd-switch-magit-repo)
      +
      +             ;; via
      +             ;; http://manuel-uberti.github.io/emacs/2018/02/17/magit-bury-buffer/:
      +             ;; a great  enhancement, when closing  the magit status  buffer, ALL
      +             ;; other possibly  still remaining magit  buffers will be  killed as
      +             ;; well AND the window setup will be restored.
      +             (defun tvd-kill-magit-buffers()
      +               "Restore window setup from before magit and kill all magit buffers."
      +               (interactive)
      +               (let ((buffers (magit-mode-get-buffers)))
      +                 (magit-restore-window-configuration)
      +                 (mapc #'kill-buffer buffers)))
      +
      +             (define-key magit-status-mode-map (kbd "q") #'tvd-kill-magit-buffers))
      diff --git a/conf-lisp/markdown.el b/conf-lisp/markdown.el
      new file mode 100644
      index 0000000..e5dc5c0
      --- /dev/null
      +++ b/conf-lisp/markdown.el
      @@ -0,0 +1,40 @@
      +;; *** Markdown
      +
      +;; I rarely use markdown, but sometimes I stumble upon such a file and
      +;; like    to    view    it     with    emacs    without    rendering.
      +;; Source: [[http://jblevins.org/projects/markdown-mode/][jblevins.org]]
      +
      +;; via https://stackoverflow.com/a/26297700
      +(defun tvd-cleanup-org-tables ()
      +  (save-excursion
      +    (goto-char (point-min))
      +    (while (search-forward "-+-" nil t) (replace-match "-|-"))
      +    ))
      +
      +(defun tvd-markdown-todo ()
      +  "Create dynamically highlighted TODO list of MD list"
      +  (interactive)
      +  (highlight-regexp "^- .*" "hi-yellow")
      +  (highlight-regexp "^- .*ok" "hi-green")
      +  (highlight-regexp "^- .*fail" "hi-pink"))
      +
      +(use-package markdown-mode
      +             :mode "\\.text\\'"
      +             :mode "\\.markdown\\'"
      +             :mode "\\.md\\'"
      +
      +             :config
      +             (defun tvd-markdown-hooks ()
      +               (when buffer-file-name
      +                 (add-hook 'after-save-hook
      +                           'check-parens
      +                           nil t)
      +                 (add-hook 'after-save-hook 'tvd-cleanup-org-tables  nil 'make-it-local))
      +
      +               (modify-syntax-entry ?\" "\"" markdown-mode-syntax-table)
      +
      +               (when (fboundb 'orgtbl-mode)
      +                 (add-hook 'markdown-mode-hook 'orgtbl-mode)))
      +
      +             :hook tvd-markdown-hooks
      +             )
      diff --git a/conf-lisp/mmm.el b/conf-lisp/mmm.el
      new file mode 100644
      index 0000000..c88fc02
      --- /dev/null
      +++ b/conf-lisp/mmm.el
      @@ -0,0 +1,22 @@
      +;; *** MMM Mode
      +(use-package mmm-mode
      +             :config
      +             (require 'cl-lib)
      +             (require 'mmm-auto)
      +             (require 'mmm-vars)
      +
      +             (setq mmm-submode-decoration-level 2)
      +
      +             ;; [[https://github.com/purcell/mmm-mode][mmm-mode github]]
      +             ;; see doc for class definition in var 'mmm-classes-alist
      +             ;; **** MMM config for POD mode
      +             (mmm-add-classes
      +              '((html-pod
      +                 :submode html-mode ;; web-mode doesnt work this way!
      +                 :delimiter-mode nil
      +                 :front "=begin html"
      +                 :back "=end html")))
      +
      +             (mmm-add-mode-ext-class 'pod-mode nil 'html-pod)
      +
      +             :hook (pod-mode mmm-mode-on))
      diff --git a/conf-lisp/modeline.el b/conf-lisp/modeline.el
      new file mode 100644
      index 0000000..8581738
      --- /dev/null
      +++ b/conf-lisp/modeline.el
      @@ -0,0 +1,46 @@
      +;; ** mode-line setup (must be the last mode)
      +
      +;; I just append the current version  of my emacs config and leave out
      +;; some stuff  to keep the modeline  short, so that everything  can be
      +;; seen even if I have multiple windows open.
      +
      +;; smaller pos
      +(setq-default mode-line-position
      +              '((-3 "%p") (size-indication-mode ("/" (-4 "%I")))
      +                " "
      +                (line-number-mode
      +                 ("%l" (column-number-mode ":%c")))))
      +
      +;; when macro recording is active,  signal it with coloring instead of
      +;; just a character
      +(defface rec-face
      +  '((t (:background "red" :foreground "white" :weight bold)))
      +  "Flag macro recording in mode-line"
      +  :group 'tvd-mode-line-faces)
      +
      +;; custom modeline
      +(setq-default mode-line-format
      +              (list
      +               "%e"
      +               mode-line-front-space
      +               mode-line-mule-info
      +               mode-line-modified
      +               mode-line-remote
      +               "  "
      +               mode-line-buffer-identification
      +               "  "
      +               mode-line-position
      +               " (%m) "
      +
      +               " [" tvd-emacs-version "] "
      +
      +               ; added because of eyebrowse
      +               mode-line-misc-info
      +
      +               '(:eval (propertize
      +                        (if (eq defining-kbd-macro t)
      +                            "[REC]"
      +                          "")
      +                        'face 'rec-face))
      +
      +               mode-line-end-spaces))
      diff --git a/conf-lisp/narrow.el b/conf-lisp/narrow.el
      new file mode 100644
      index 0000000..ebedf1a
      --- /dev/null
      +++ b/conf-lisp/narrow.el
      @@ -0,0 +1,22 @@
      +;; *** narrowing (no mode but fits here)
      +
      +;; I use narrowing quite frequently, so here are some enhancements.
      +
      +;; easier narrowing with Indirect Buffers
      +;; Source: [[https://www.emacswiki.org/emacs/NarrowIndirect3][emacswiki]]
      +(require 'narrow-indirect)
      +(defalias 'nf 'ni-narrow-to-defun-indirect-other-window)
      +(defalias 'nr 'ni-narrow-to-region-indirect-other-window)
      +
      +;; I  like to  have  an  orange fringe  background  when narrowing  is
      +;; active, since I forget that it is in effect otherwise sometimes.
      +
      +;; via [[https://emacs.stackexchange.com/questions/33288/how-to-find-out-if-narrow-to-region-has-been-called-within-save-restriction][stackoverflow]]
      +(defun tvd-narrowed-fringe-status ()
      +  "Make the fringe background reflect the buffer's narrowing status."
      +  (set-face-attribute
      +   'fringe nil :background (if (buffer-narrowed-p)
      +                               tvd-fringe-narrow-bg
      +                             nil)))
      +
      +(add-hook 'post-command-hook 'tvd-narrowed-fringe-status)
      diff --git a/conf-lisp/novel.el b/conf-lisp/novel.el
      new file mode 100644
      index 0000000..e772a64
      --- /dev/null
      +++ b/conf-lisp/novel.el
      @@ -0,0 +1,8 @@
      +;; *** Novel Mode - Screen Reader
      +
      +;; my own emacs screen reader, very handy to read docs on the road.
      +
      +(use-package novel-mode
      +             :ensure nil
      +             :config
      +             (global-set-key (kbd "C-c C-n")         'novel-mode))
      diff --git a/conf-lisp/occur.el b/conf-lisp/occur.el
      new file mode 100644
      index 0000000..b4eacfd
      --- /dev/null
      +++ b/conf-lisp/occur.el
      @@ -0,0 +1,15 @@
      +;; *** Occur
      +;; https://oremacs.com/2015/01/26/occur-dwim/
      +;; https://github.com/abo-abo/hydra/wiki/Emacs
      +(defun occur-dwim ()
      +  "Call `occur' with a sane default, chosen as the thing under point or selected region"
      +  (interactive)
      +  (push (if (region-active-p)
      +            (buffer-substring-no-properties
      +             (region-beginning)
      +             (region-end))
      +          (let ((sym (thing-at-point 'symbol)))
      +            (when (stringp sym)
      +              (regexp-quote sym))))
      +        regexp-history)
      +  (call-interactively 'occur))
      diff --git a/conf-lisp/org.el b/conf-lisp/org.el
      new file mode 100644
      index 0000000..c42e10e
      --- /dev/null
      +++ b/conf-lisp/org.el
      @@ -0,0 +1,242 @@
      +;; *** org mode
      +
      +;; I use org mode to take notes  mostly at work. I also track projects
      +;; and  TODO  lists  etc.   I  do not,  however,  use  agenda  or  any
      +;; scheduling whatsoever.
      +
      +;; I like custom bullets
      +(use-package org-bullets
      +             :config
      +             (setq org-bullets-bullet-list '("►" "✜" "✸" "✿" "♦")))
      +
      +(use-package org
      +             :config
      +
      +
      +             ;; enable syntax highlighting for embedded source blocks
      +             (require 'ob-python)
      +             (require 'ob-perl)
      +             (require 'ob-shell)
      +
      +
      +             ;; capture target, os-dependend
      +             ;; FIXME: put this file outside emacs?
      +             (setq tvd-org-file (concat tvd-config-dir "/notizen.org")
      +                       org-attach-directory (concat tvd-config-dir "/attachments"))
      +
      +             ;; easier to open that way
      +             (defun notizen()
      +               (interactive)
      +               (switch-to-buffer (find-file tvd-org-file))
      +               (agenda))
      +
      +             ;; text formatting made easy, bound to C-c keys locally
      +             (defun tvd-org-emphasize(CHAR)
      +               "expand once if no region and apply emphasize CHAR"
      +               (interactive)
      +               (unless (region-active-p)
      +                 (er/expand-region 1))
      +               (org-emphasize CHAR))
      +
      +             (defun bold()
      +               "bold text in org mode"
      +               (interactive)
      +               (tvd-org-emphasize '42))
      +
      +             (defun italic()
      +               "italic text in org mode"
      +               (interactive)
      +               (tvd-org-emphasize '47))
      +
      +             (defun code()
      +               "verbatim text in org mode"
      +               (interactive)
      +               (tvd-org-emphasize '126))
      +
      +             (defun underline()
      +               "underline text in org mode"
      +               (interactive)
      +               (tvd-org-emphasize '95))
      +
      +             ;; my org-mode specific  and 
      +             (defun tvd-org-left-or-level-up()
      +               "jump one word to the left if not on a org heading,
      +otherwise fold current level and jump one level up."
      +               (interactive)
      +               (if (and (org-at-heading-p) (looking-at "*"))
      +                   (progn
      +                     (hide-subtree)
      +                     (outline-up-heading 1))
      +                 (left-word)))
      +
      +             (defun tvd-org-heading-up()
      +               "If on a heading, fold current heading, jump one level
      +up and unfold it, otherwise jump paragraph as usual."
      +               (interactive)
      +               (if (and (org-at-heading-p) (looking-at "*"))
      +                   (progn
      +                     (hide-subtree)
      +                     (org-backward-heading-same-level 1)
      +                     (org-cycle))
      +                 (backward-paragraph)))
      +
      +             (defun tvd-org-heading-down()
      +               "If on a heading, fold current heading, jump one level
      +down and unfold it, otherwise jump paragraph as usual."
      +               (interactive)
      +               (if (and (org-at-heading-p) (looking-at "*"))
      +                   (progn
      +                     (hide-subtree)
      +                     (org-forward-heading-same-level 1)
      +                     (org-cycle))
      +                 (forward-paragraph)))
      +
      +             ;; org-mode specific config, after load
      +             (eval-after-load "org"
      +               '(progn
      +                  (add-hook 'org-mode-hook
      +                            (lambda ()
      +                              (setq
      +                               org-M-RET-may-split-line nil
      +                               org-agenda-files (list tvd-org-file)
      +                               org-agenda-restore-windows-after-quit t
      +                               org-blank-before-new-entry (quote ((heading . auto) (plain-list-item . auto)))
      +                               org-catch-invisible-edits (quote error)
      +                               org-columns-default-format "%80ITEM %22Timestamp %TODO %TAGS %0PRIORITY"
      +                               org-insert-heading-always-after-current (quote t)
      +                               org-mouse-1-follows-link nil
      +                               org-remember-store-without-prompt t
      +                               org-reverse-note-order t
      +                               org-startup-indented t
      +                               org-startup-truncated nil
      +                               org-return-follows-link t
      +                               org-use-speed-commands t
      +                               org-yank-adjusted-subtrees t
      +                               org-refile-targets '((nil . (:maxlevel . 5)))
      +                               org-refile-use-outline-path t
      +                               org-outline-path-complete-in-steps nil
      +                               org-completion-use-ido t
      +                               org-support-shift-select t
      +                               org-hide-emphasis-markers t
      +                               org-fontify-done-headline t
      +                               org-pretty-entities t
      +                               org-use-sub-superscripts nil
      +                               org-confirm-babel-evaluate nil)
      +                                        ; shortcuts
      +                              (setq org-speed-commands-user
      +                                    (quote (
      +                                            ("0" . ignore)
      +                                            ("1" . delete-other-windows)
      +                                            ("2" . ignore)
      +                                            ("3" . ignore)
      +                                            ("d" . org-archive-subtree-default-with-confirmation) ; delete, keep track
      +                                            ("v" . org-narrow-to-subtree) ; only show current heading ("view")
      +                                            ("q" . widen)                 ; close current heading and show all ("quit")
      +                                            (":" . org-set-tags-command)  ; add/edit tags
      +                                            ("t" . org-todo)              ; toggle todo type, same as C-t
      +                                            ("z" . org-refile)            ; archive the (sub-)tree
      +                                            ("a" . org-attach)            ; manage attachments
      +                                            )))
      +                                        ; same as toggle
      +                              (local-set-key (kbd "C-t") 'org-todo)
      +
      +                                        ; alt-enter = insert new subheading below current
      +                              (local-set-key (kbd "") 'org-insert-subheading)
      +
      +                                        ; search for tags (ends up in agenda view)
      +                              (local-set-key (kbd "C-f") 'org-tags-view)
      +
      +                                        ; run presenter, org-present must be installed and loadedwhite
      +                              (local-set-key (kbd "C-p") 'org-present)
      +
      +                                        ; todo colors
      +                              (setq org-todo-keyword-faces '(
      +                                                             ("TODO"   . (:foreground "deepskyblue" :weight bold))
      +                                                             ("START"  . (:foreground "olivedrab"        :weight bold))
      +                                                             ("WAIT"   . (:foreground "darkorange"  :weight bold))
      +                                                             ("DONE"   . (:foreground "forestgreen" :weight bold))
      +                                                             ("CANCEL" . (:foreground "red"         :weight bold))
      +                                                             ("FAIL"   . (:foreground "red"         :weight bold))
      +                                                             ))
      +
      +                              (local-set-key (kbd "C-c b") 'bold)
      +                              (local-set-key (kbd "C-c /") 'italic)
      +                              (local-set-key (kbd "C-c 0") 'code) ; aka = without shift
      +                              (local-set-key (kbd "C-c _") 'underline)
      +
      +                                        ; edit babel src block in extra buffer:
      +                                        ; default is C-c ' which is hard to type
      +                                        ; brings me to src code editor buffer
      +                                        ; Also note: enter ")   'tvd-org-heading-up)
      +                              (local-set-key (kbd "") 'tvd-org-heading-down)
      +
      +                              ;; move word left or heading up, depending where point is
      +                              (local-set-key (kbd "") 'tvd-org-left-or-level-up)
      +
      +                              ;; use nicer bullets
      +                              (when (fboundp 'org-bullets-mode)
      +                                (org-bullets-mode 1))
      +
      +                              (org-babel-do-load-languages 'org-babel-load-languages
      +                                                           '((python     . t)
      +                                                             (emacs-lisp . t)
      +                                                             (shell      . t)
      +                                                             (perl       . t)))))))
      +
      +             ;; no more ... at the end of a heading
      +             (setq org-ellipsis " ⤵")
      +
      +             ;; my own keywords, must be set globally, not catched correctly inside hook
      +             (setq org-todo-keywords
      +                   '((sequence "TODO" "START" "WAIT" "|" "DONE" "CANCEL" "FAIL")))
      +
      +             ;; I always want to be able to capture, even if no ORG is running
      +             (global-set-key (kbd "C-n")             (lambda () (interactive) (org-capture)))
      +
      +             ;; must be global since code edit sub buffers run their own major mode, not org
      +             (global-set-key (kbd "C-c C-#")         'org-edit-src-exit)
      +
      +             ;; some org mode vars must be set globally
      +             (setq org-default-notes-file tvd-org-file
      +                   org-startup-indented t
      +                   org-indent-indentation-per-level 4)
      +
      +             ;; my own capture templates
      +             (setq org-capture-templates
      +                   '(("n" "Project" entry (file+headline tvd-org-file "Unsorted Tasks")
      +                      "* TODO %^{title}\n%u\n** Kostenstelle\n** Contact Peer\n** Contact Customer\n** Aufträge\n** Daten\n** Notizen\n  %i%?\n"
      +                      :prepend t :jump-to-captured t)
      +
      +                     ("t" "Todo Item" entry (file+headline tvd-org-file "Manual-Agenda-Tasks")
      +                      "* TODO %^{title}\n:LOGBOOK:\n%u:END:\n" :prepend t :immediate-finish t)
      +
      +                     ("s" "Scheduled Item" entry (file+headline tvd-org-file "Scheduled-Agenda-Tasks")
      +                      "* TODO %^t %^{title}\n:LOGBOOK:\n%u:END:\n" :prepend t :immediate-finish t)
      +
      +                     ("j" "Journal" entry (file+headline tvd-org-file "Kurznotizen")
      +                      "* TODO %^{title}\n%u\n  %i%?\n" :prepend t :jump-to-captured t)
      +
      +                     ("c" "Copy/Paste" entry (file+headline tvd-org-file "Kurznotizen")
      +                      "* TODO %^{title}\n%u\n  %x\n" :immediate-finish t :prepend t :jump-to-captured t)))
      +
      +             ;; follow links using eww, if present
      +             ;; (if (fboundp 'eww-browse-url)
      +             ;;     (setq browse-url-browser-function 'eww-browse-url))
      +
      +             ;; mark narrowing with an orange fringe, the advice for 'widen
      +             ;; is in the outline section.
      +             (advice-add 'org-narrow-to-subtree :after
      +                         '(lambda (&rest args)
      +                            (set-face-attribute 'fringe nil :background tvd-fringe-narrow-bg)))
      +
      +             ;; always use the latest docs
      +             (with-eval-after-load 'info
      +               (info-initialize)
      +               (add-to-list 'Info-directory-list
      +                            (expand-file-name "~/.emacs.d/lisp/org/doc"))))
      diff --git a/conf-lisp/orgagenda.el b/conf-lisp/orgagenda.el
      new file mode 100644
      index 0000000..3654575
      --- /dev/null
      +++ b/conf-lisp/orgagenda.el
      @@ -0,0 +1,208 @@
      +;; *** org agenda mode
      +
      +;; I use org mode  for along time now, primarily at  work, but did not
      +;; use agenda.  Instead  I developed the habit of  maintaining one org
      +;; entry which  contains just a  list with all  things to do  today. I
      +;; just edited this list manually  and it worked.  However, recently I
      +;; found  out  that agenda  provides  lots  of features  and  commands
      +;; precisely for what I already did  manually. So, now, finally (as of
      +;; november 2018) I switch to using the agenda.
      +
      +;; My agenda use is very simple though: I don't use any scheduling, no
      +;; priorities,  no recurring  events,  no daily  or  other time  based
      +;; views. I just keep a list of TODO entries and another of entries in
      +;; WAIT  state, that's  it.  All  those entries  are  located under  a
      +;; special  org entry  with the  title  "Heute" and  the category  (as
      +;; property) WORK, which I use for filtering out agenda items.
      +
      +;; The general workflow is as follows: I execute (agenda) which starts
      +;; directly  my custom  agenda view.   It  lists open  TODO items  and
      +;; waiting WAIT  items below. If  I press `n', I  will be asked  for a
      +;; title and a new TODO item appears  in my agenda. I can press `d' to
      +;; mark it as  DONE, it will also be archived  into a subsibling below
      +;; "HEUTE". I can press `w' to move  an item into WAIT state and I can
      +;; press `a' to  add text to the org entry  under point (like "waiting
      +;; for customer email").
      +
      +;; So, I  don't use my  regular org entries,  which are in  most cases
      +;; very large  containing lots  of information,  as agenda  items, but
      +;; only very short ones which act  as reminders about what work I have
      +;; to  do. However,  since I  have the  org buffer  always opened  and
      +;; visible in a split  buffer next to the agenda, it  is no problem to
      +;; go to such a deep entry for editing or viewing.
      +
      +(when (package-installed-p 'org)
      +  (require 'org-agenda)
      +
      +  ;; This is my one and only  agenda custom view, it displays TODO items
      +  ;; below entries  categorized as  WORK and WAIT  items under  the same
      +  ;; category. The cool  thing here is, that the `tags'  agenda view can
      +  ;; be used  to filter for  properties as well.  In order to  have this
      +  ;; working the following  property drawer must exist in  an entry with
      +  ;; TODO siblings:
      +  ;;
      +  ;;    * START Arbeit
      +  ;;      :PROPERTIES:
      +  ;;      :CATEGORY: WORK
      +  ;;      :END:
      +  ;;    ** TODO a thing to do
      +  ;;    ** WAIT a thing waiting for something
      +  ;;
      +  (setq org-agenda-custom-commands
      +        '(("o" "Daily TODO Tasks"
      +           (
      +            ;; a block containing only items scheduled for today, if any
      +            (agenda ""
      +                    ((org-agenda-span 1)
      +                     (org-agenda-overriding-header "Tasks scheduled:")))
      +            ;; manually created todo items due (state TODO)
      +            (tags "CATEGORY=\"WORK\""
      +                  ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo '("CANCEL" "START" "DONE" "WAIT")))
      +                   (org-agenda-overriding-header "\nTasks to do today:")
      +                   (org-agenda-follow-mode t)
      +                   (org-agenda-entry-text-mode t)))
      +            ;; manually created todo items in wait state
      +            (tags "CATEGORY=\"WORK\""
      +                  ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo '("CANCEL" "START" "DONE" "TODO")))
      +                   (org-agenda-overriding-header "\nTasks Waiting:"))))
      +           ((org-agenda-compact-blocks t)))))
      +
      +  ;; A shortcut to reach my custom view directly
      +  (defun agenda ()
      +    "Visit my org agenda directly, splits left"
      +    (interactive)
      +    (org-agenda nil "o")
      +    (tvd-flip-windows)
      +    (other-window-or-switch-buffer))
      +
      +  ;; Add a line of text to the top of an existing TODO entry and refresh
      +  ;; the agenda
      +  (defun tvd-org-agenda-edit-entry (note)
      +    "Insert a note as plain text into an entry"
      +    (interactive "sEnter note: ")
      +    (save-excursion
      +      (org-agenda-switch-to)
      +      (end-of-line)
      +      (newline)
      +      (insert note))
      +    (switch-to-buffer "*Org Agenda*")
      +    (org-agenda-redo t))
      +
      +  ;; Mark an entry as DONE, archive it to an archive sibling and refresh
      +  ;; the agenda
      +  (defun tvd-org-agenda-done()
      +    (interactive)
      +    (org-agenda-todo 'done)
      +    (org-agenda-archive-to-archive-sibling)
      +    (org-agenda-redo t))
      +
      +  ;; Mark an entry as WAIT, archive it to an archive sibling and refresh
      +  ;; the agenda
      +  (defun tvd-org-agenda-wait()
      +    (interactive)
      +    (org-agenda-todo "WAIT")
      +    (org-agenda-redo t))
      +
      +  ;; A  wrapper which  executes  an  org capture  directly.  `t' is  the
      +  ;; shortcut for the capture, defined above in org mode.
      +  (defun tvd-org-agenda-capture (task)
      +    "Capture a task in agenda mode, using the date at point"
      +    (interactive)
      +    (let ((org-overriding-default-time (org-get-cursor-date)))
      +      (org-capture nil task)
      +      (org-agenda-redo t)))
      +
      +  (defun tvd-org-agenda-capture-todo ()
      +    "Capture a todo task in agenda mode"
      +    (interactive)
      +    (tvd-org-agenda-capture "t"))
      +
      +  (defun tvd-org-agenda-capture-scheduled ()
      +    "Capture a scheduled task in agenda mode"
      +    (interactive)
      +    (tvd-org-agenda-capture "s"))
      +
      +
      +  ;; Sometimes  it  is  nice  to  see  the  agenda  alone,  so  I  press
      +  ;; `o'. However, since follow mode is  enabled, once I move point, the
      +  ;; org buffer re-appears.
      +  (defun tvd-org-agenda-solitair ()
      +    (interactive)
      +    (delete-other-windows)
      +    (setq org-agenda-follow-mode nil)
      +    (message "Org Agenda Follow Mode Disabled"))
      +
      +  ;; The original function scrolls the buffer  every time when it runs a
      +  ;; little bit up, which is annoying, to say the least
      +  (defun tvd-org-agenda-redo()
      +    (interactive)
      +    (org-agenda-redo t)
      +    (beginning-of-buffer))
      +
      +  ;; Since I learned to love hydra, I have one for my agenda as well, of course:
      +  (defhydra hydra-org-agenda (:color blue
      +                                     :pre (setq which-key-inhibit t)
      +                                     :post (setq which-key-inhibit nil)
      +                                     :hint none)
      +    "
      +Org Agenda (_q_uit)
      +
      +^Tasks^                             ^Options^             ^Movement^
      +-^^^^^^-------------------------------------------------------------------------------------
      +_n_: create new todo task           _f_: follow =?f?      ENTER:     switch to entry
      +_N_: create new scheduled task      _e_: entry  =?e?      C-:    go one entry up
      +_d_: mark task done and archive     _o_: one window       C-:  go one entry down
      +_w_: mark task waiting              ^^                    M-:    move entry up
      +_t_: toggle todo state              ^^                    M-:  move entry down
      +_z_: archive task                   ^ ^
      +_+_: increase prio
      +_-_: decrease prio                  ^Marking^
      +_g_: refresh                        _m_: mark entry
      +_s_: save org buffer(s)             _u_: un-mark entry
      +_a_: add a note to the entry        _U_: un-mark all
      +_k_: delete a task w/o archiving    _B_: bulk action
      +
      +"
      +    ("a" tvd-org-agenda-edit-entry nil)
      +    ("n" tvd-org-agenda-capture-todo nil)
      +    ("N" tvd-org-agenda-capture-scheduled nil)
      +    ("o" tvd-org-agenda-solitair nil)
      +    ("g" tvd-org-agenda-redo)
      +    ("t" org-agenda-todo)
      +    ("d" tvd-org-agenda-done nil)
      +    ("w" tvd-org-agenda-wait nil)
      +    ("z" org-agenda-archive-to-archive-sibling nil)
      +    ("+" org-agenda-priority-up nil)
      +    ("-" org-agenda-priority-down nil)
      +    ("s" org-save-all-org-buffers nil)
      +    ("f" org-agenda-follow-mode
      +     (format "% -3S" org-agenda-follow-mode))
      +    ("e" org-agenda-entry-text-mode
      +     (format "% -3S" org-agenda-entry-text-mode))
      +    ("m" org-agenda-bulk-mark nil)
      +    ("u" org-agenda-bulk-unmark nil)
      +    ("U" org-agenda-bulk-remove-all-marks nil)
      +    ("B" org-agenda-bulk-action nil)
      +    ("k" org-agenda-kill nil)
      +    ("q" nil nil :color red))
      +
      +  ;; Configuration and key bindings for org agenda (same as in the hydra)
      +  (add-hook 'org-agenda-mode-hook '(lambda () (progn
      +                                                (setq org-agenda-follow-mode t
      +                                                      org-log-into-drawer t
      +                                                      org-agenda-entry-text-mode t
      +                                                      org-agenda-sorting-strategy '(priority-down timestamp-down))
      +                                                (local-set-key (kbd "n") 'tvd-org-agenda-capture-todo)
      +                                                (local-set-key (kbd "N") 'tvd-org-agenda-capture-scheduled)
      +                                                (local-set-key (kbd "o") 'tvd-org-agenda-solitair)
      +                                                (local-set-key (kbd "a") 'tvd-org-agenda-edit-entry)
      +                                                (local-set-key (kbd "d") 'tvd-org-agenda-done)
      +                                                (local-set-key (kbd "w") 'tvd-org-agenda-wait)
      +                                                (local-set-key (kbd "g") 'tvd-org-agenda-redo)
      +                                                (local-set-key (kbd "f") 'org-agenda-follow-mode)
      +                                                (local-set-key (kbd "e") 'org-agenda-entry-text-mode)
      +                                                (local-set-key (kbd "k") 'org-agenda-kill)
      +                                                (local-set-key (kbd "z") 'org-agenda-archive-to-archive-sibling)
      +                                                (local-set-key (kbd "C-") 'org-agenda-previous-item)
      +                                                (local-set-key (kbd "C-") 'org-agenda-next-item)
      +                                                (local-set-key (kbd "?") 'hydra-org-agenda/body)))))
      diff --git a/conf-lisp/orgtable.el b/conf-lisp/orgtable.el
      new file mode 100644
      index 0000000..7b3582b
      --- /dev/null
      +++ b/conf-lisp/orgtable.el
      @@ -0,0 +1,415 @@
      +;; *** org table mode
      +
      +;; I'm so used to lovely org mode tables, I need them everywhere!
      +(when (package-installed-p 'org)
      +  (require 'org-table)
      +
      +
      +  ;; convert CSV region to table
      +  (defun tablify (regex)
      +    "Convert a whitespace separated column list into
      +an org mode table and enable orgtbl-mode. You can
      +specify another regex for cell splitting."
      +    (interactive "MConvert [region] to table with regex ([\t\s]+): ")
      +    (let ((spc "[\t\s]+"))
      +      (when (string= regex "")
      +        (setq regex spc))
      +      (delete-trailing-whitespace)
      +      (if (org-region-active-p)
      +          (org-table-convert-region (region-beginning) (region-end) regex)
      +        (org-table-convert-region (point-min) (point-max) regex))
      +      (when (not (eq major-mode 'org-mode))
      +        (orgtbl-mode))))
      +
      +  ;; table sorting shortcuts
      +  (defun sort-table-numeric ()
      +    "sort org table numerically by current column"
      +    (interactive)
      +    (org-table-sort-lines nil ?n))
      +
      +  (defun sort-table-numeric-desc ()
      +    "reverse sort org table numerically by current column"
      +    (interactive)
      +    (org-table-sort-lines nil ?N))
      +
      +  (defun sort-table-alphanumeric ()
      +    "sort org table charwise by current column"
      +    (interactive)
      +    (org-table-sort-lines nil ?a))
      +
      +  (defun sort-table-alphanumeric-desc ()
      +    "reverse sort org table charwise by current column"
      +    (interactive)
      +    (org-table-sort-lines nil ?A))
      +
      +  (defun sort-table-time ()
      +    "sort org table by times by current column"
      +    (interactive)
      +    (org-table-sort-lines nil ?t))
      +
      +  (defun sort-table-time-desc ()
      +    "reverse sort org table by times by current column"
      +    (interactive)
      +    (org-table-sort-lines nil ?T))
      +
      +  ;; [[http://irreal.org/blog/?p=3542][via jcs/irreal.org]]
      +  ;; however, I renamed the actual sort wrappers to match my
      +  ;; naming scheme
      +  (defun jcs-ip-lessp (ip1 ip2 &optional op)
      +    "Compare two IP addresses.
      +Unless the optional argument OP is provided, this function will return T
      +if IP1 is less than IP2 or NIL otherwise. The optional argument OP is
      +intended to be #'> to support reverse sorting."
      +    (setq cmp (or op #'<))
      +    (cl-labels ((compare (l1 l2)
      +                         (if (or (null l1) (null l2))
      +                             nil
      +                           (let ((n1 (string-to-number (car l1)))
      +                                 (n2 (string-to-number (car l2))))
      +                             (cond
      +                              ((funcall cmp n1 n2) t)
      +                              ((= n1 n2) (compare (cdr l1) (cdr l2)))
      +                              (t nil))))))
      +      (compare (split-string ip1 "\\.") (split-string ip2 "\\."))))
      +
      +  (defun sort-table-ip ()
      +    (interactive)
      +    (org-table-sort-lines nil ?f #'org-sort-remove-invisible #'jcs-ip-lessp))
      +
      +  (defun sort-table-ip-desc ()
      +    (interactive)
      +    (org-table-sort-lines nil ?F #'org-sort-remove-invisible
      +                          (lambda (ip1 ip2) (jcs-ip-lessp ip1 ip2 #'>))))
      +
      +
      +  ;; easy access for the shortcuts
      +  (defalias 'stn       'sort-table-numeric)
      +  (defalias 'stnd      'sort-table-numeric-desc)
      +  (defalias 'sta       'sort-table-alphanumeric)
      +  (defalias 'stad      'sort-table-alphanumeric-desc)
      +  (defalias 'stt       'sort-table-time)
      +  (defalias 'sttd      'sort-table-time-desc)
      +  (defalias 'sti       'sort-table-ip)
      +  (defalias 'stid      'sort-table-ip-desc)
      +
      +  ;; generic table exporter
      +  (defun tvd-export-org-table (fmt)
      +    "export an org table using format FMT"
      +    (interactive)
      +    (let ((efile "/tmp/org-table-export.tmp")
      +          (ebuf (format "*table-%s*" fmt)))
      +      (when (file-exists-p efile)
      +        (delete-file efile))
      +      (org-table-export efile (format "orgtbl-to-%s" fmt))
      +      (other-window 1)
      +      (if (not (eq (get-buffer ebuf) nil))
      +          (kill-buffer (get-buffer ebuf)))
      +      (set-buffer (get-buffer-create ebuf))
      +      (insert-file-contents efile)
      +      (switch-to-buffer ebuf)
      +      (delete-file efile)))
      +
      +  ;; FIXME: once there's an org solution to this, remove this code
      +  ;; format specific exporters
      +  (defun tvd-org-quote-csv-field (s)
      +    "Quote every field."
      +    (if (string-match "." s)
      +        (concat "=\"" (mapconcat 'identity
      +                                 (split-string s "\"") "\"\"") "\"")
      +      s))
      +
      +  (defun table-to-excel ()
      +    "export current org table to CSV format suitable for MS Excel."
      +    (interactive)
      +    ;; quote everything, map temporarily 'org-quote-csv-field
      +    ;; to my version
      +    (cl-letf (((symbol-function 'org-quote-csv-field)
      +               #'tvd-org-quote-csv-field))
      +      (tvd-export-org-table "csv")))
      +
      +  (defun table-to-csv ()
      +    "export current org table to CSV format"
      +    (interactive)
      +    (tvd-export-org-table "csv"))
      +
      +  (defun table-to-latex ()
      +    "export current org table to LaTeX format"
      +    (interactive)
      +    (tvd-export-org-table "latex"))
      +
      +  (defun table-to-html ()
      +    "export current org table to HTML format"
      +    (interactive)
      +    (tvd-export-org-table "html"))
      +
      +  (defun table-to-csv-tab ()
      +    "export current org table to CSV format, separated by "
      +    (interactive)
      +    (tvd-export-org-table "tsv"))
      +
      +  (defun table-to-aligned ()
      +    "export current org table to space-aligned columns format"
      +    (interactive)
      +    (tvd-export-org-table "csv")
      +    (with-current-buffer "*table-csv*"
      +      (align-regexp (point-min) (point-max) "\\(\\s-*\\)," 1 1 t)
      +      (while (re-search-forward " ," nil t)
      +        (replace-match "    "))))
      +
      +  ;; exporter shortcuts
      +  (defalias 'ttc      'table-to-csv)
      +  (defalias 'tte      'table-to-excel)
      +  (defalias 'ttl      'table-to-latex)
      +  (defalias 'tth      'table-to-html)
      +  (defalias 'ttt      'table-to-csv-tab)
      +  (defalias 'tta      'table-to-aligned)
      +
      +  ;; In org mode I sometimes want to copy the content of a table cell
      +  (defun tvd-beginning-of-cell (&optional arg)
      +    "move (point) to the beginning of a org mode table cell"
      +    (interactive)
      +    (if  (re-search-backward "|" (line-beginning-position) 3 1)
      +        (forward-char)))
      +
      +  (defun tvd-end-of-cell (&optional arg)
      +    "move (point) to the end of a org mode table cell"
      +    (interactive)
      +    (if  (re-search-forward "|" (line-end-position) 3 1)
      +        (backward-char)))
      +
      +  (defun tvd-copy-org-table-cell(&optional arg)
      +    "Copy an org mode table cell to the kill ring using MCYT"
      +    (interactive "P")
      +    (mcyt--blink-and-copy-thing 'tvd-beginning-of-cell 'tvd-end-of-cell arg))
      +
      +  (defun tvd-del-org-table-cell (&optional arg)
      +    "Delete a cell"
      +    (interactive "P")
      +    (let
      +        ((beg (progn (tvd-beginning-of-cell) (point)))
      +         (end (progn (tvd-end-of-cell) (point))))
      +      (delete-region beg end)
      +      (org-table-align)))
      +
      +  (defun tvd-del-org-table-row ()
      +    "Delete a table row's contents"
      +    (interactive)
      +    (org-beginning-of-line 1)
      +    (kill-line)
      +    (org-table-insert-row nil))
      +
      +  (defun tvd-del-org-table-col ()
      +    "Delete a table column's contents, keep heading as is"
      +    (interactive)
      +    (let ((head (org-table-get 1 nil)))
      +      (org-table-delete-column)
      +      (re-search-forward "|")
      +      (org-table-insert-column)
      +      (tvd-org-table-goto-col-beginning)
      +      (insert head)
      +      (org-table-align))
      +    )
      +
      +  ;; Sometimes I need to copy whole columns too:
      +  ;; via [[https://emacs.stackexchange.com/questions/28270/how-to-select-and-copy-a-column-of-an-org-table-without-rectangle-selection][stackoverflow]]
      +
      +  (defun tvd-org-table-goto-col-beginning ()
      +    "Go to beginning of current column and return `point'."
      +    (interactive)
      +    (assert (org-table-p) "Not in org-table.")
      +    (org-table-align)
      +    (let ((col (org-table-current-column)))
      +      (goto-char (org-table-begin))
      +      (org-table-goto-column col))
      +    (point))
      +
      +  (defun tvd-org-table-col-beginning ()
      +    "Return beginning position of current column."
      +    (save-excursion
      +      (tvd-org-table-goto-col-beginning)))
      +
      +  (defun tvd-org-table-goto-col-end ()
      +    "Goto end of current column and return `point'."
      +    (interactive)
      +    (assert (org-table-p) "Not in org-table.")
      +    (org-table-align)
      +    (let ((col (org-table-current-column)))
      +      (goto-char (1- (org-table-end)))
      +      (org-table-goto-column col)
      +      (skip-chars-forward "^|"))
      +    (point))
      +
      +  (defun tvd-org-table-col-end ()
      +    "Return end position of current column."
      +    (save-excursion
      +      (tvd-org-table-goto-col-end)))
      +
      +  (defun tvd-org-table-select-col ()
      +    "Select current column."
      +    (interactive)
      +    (set-mark (tvd-org-table-col-beginning))
      +    (tvd-org-table-goto-col-end)
      +    (rectangle-mark-mode))
      +
      +  (defun tvd-copy-org-table-col ()
      +    "Copy current column."
      +    (interactive)
      +    (tvd-org-table-select-col)
      +    (sit-for 0.2 t)
      +    (copy-region-as-kill nil nil t)
      +    (with-temp-buffer
      +      (yank)
      +      (delete-trailing-whitespace)
      +      (delete-whitespace-rectangle (point-min) (point-max))
      +      (font-lock-unfontify-buffer)
      +      (copy-region-as-kill (point-min) (point-max))))
      +
      +  (defun tvd-copy-org-table-row ()
      +    "Copy current row, space aligned"
      +    (interactive)
      +    (mcyt-copy-line)
      +    (with-temp-buffer
      +      (yank)
      +      (goto-char (point-min))
      +      (let ((spc ""))
      +        (while (re-search-forward "|[ ]*" nil t)
      +          (replace-match spc)
      +          (setq spc " ")))
      +      (delete-trailing-whitespace)
      +      (copy-region-as-kill (point-min) (point-max))))
      +
      +  ;; Move single cells using C-M-up C-M-down C-M-left C-M-right
      +  ;; [[https://cs.gmu.edu/~kauffman/software/org-table-move-single-cell.el][via Kauffmann]]
      +  (defun org-table-swap-cells (i1 j1 i2 j2)
      +    "Swap two cells"
      +    (let ((c1 (org-table-get i1 j1))
      +          (c2 (org-table-get i2 j2)))
      +      (org-table-put i1 j1 c2)
      +      (org-table-put i2 j2 c1)
      +      (org-table-align)))
      +
      +  (defun org-table-move-single-cell (direction)
      +    "Move the current cell in a cardinal direction according to the
      +  parameter symbol: 'up 'down 'left 'right. Swaps contents of
      +  adjacent cell with current one."
      +    (unless (org-at-table-p)
      +      (error "No table at point"))
      +    (let ((di 0) (dj 0))
      +      (cond ((equal direction 'up) (setq di -1))
      +            ((equal direction 'down) (setq di +1))
      +            ((equal direction 'left) (setq dj -1))
      +            ((equal direction 'right) (setq dj +1))
      +            (t (error "Not a valid direction, must be up down left right")))
      +      (let* ((i1 (org-table-current-line))
      +             (j1 (org-table-current-column))
      +             (i2 (+ i1 di))
      +             (j2 (+ j1 dj)))
      +        (org-table-swap-cells i1 j1 i2 j2)
      +        (org-table-goto-line i2)
      +        (org-table-goto-column j2))))
      +
      +  (defun org-table-move-single-cell-up ()
      +    "Move a single cell up in a table; swap with anything in target cell"
      +    (interactive)
      +    (org-table-move-single-cell 'up))
      +
      +  (defun org-table-move-single-cell-down ()
      +    "Move a single cell down in a table; swap with anything in target cell"
      +    (interactive)
      +    (org-table-move-single-cell 'down))
      +
      +  (defun org-table-move-single-cell-left ()
      +    "Move a single cell left in a table; swap with anything in target cell"
      +    (interactive)
      +    (org-table-move-single-cell 'left))
      +
      +  (defun org-table-move-single-cell-right ()
      +    "Move a single cell right in a table; swap with anything in target cell"
      +    (interactive)
      +    (org-table-move-single-cell 'right))
      +
      +  ;; actual org table config
      +  (with-eval-after-load "org"
      +    (add-hook 'org-mode-hook
      +              (lambda ()
      +                (local-set-key (kbd "C-c t l") 'tvd-copy-org-table-col)
      +                (local-set-key (kbd "C-c t r") 'tvd-copy-org-table-row)
      +                (local-set-key (kbd "C-c t c") 'tvd-copy-org-table-cell)
      +                (local-set-key (kbd "C-M-")  'org-table-move-single-cell-left)
      +                (local-set-key (kbd "C-M-") 'org-table-move-single-cell-right)
      +                (local-set-key (kbd "C-M-")    'org-table-move-single-cell-up)
      +                (local-set-key (kbd "C-M-")  'org-table-move-single-cell-down))))
      +
      +  ;; eval-after-load 'orgtbl doesn't work
      +  (add-hook 'orgtbl-mode-hook '(lambda ()
      +                                 (define-key orgtbl-mode-map (kbd "C-c t l") 'tvd-copy-org-table-col)
      +                                 (define-key orgtbl-mode-map (kbd "C-c t r") 'tvd-copy-org-table-row)
      +                                 (define-key orgtbl-mode-map (kbd "C-c t c") 'tvd-copy-org-table-cell)))
      +
      +  ;; integers, reals, positives, set via custom
      +  (setq org-table-number-regexp "^[-+]?\\([0-9]*\\.[0-9]+\\|[0-9]+\\.?[0-9]*\\)$")
      +
      +  ;; table hydras, maybe better than aliases?!
      +  (defhydra hydra-org-tables (:color blue)
      +    "
      +^Sort by^             ^Transform to^      ^Copy/Del what^                ^Modify^                 ^Outside Org^
      +^^^^^^^^-----------------------------------------------------------------------------------------------------------------------
      +_sa_:  alphanumeric   _tc_: CSV           _cl_: Copy Column (C-c t l)    _ic_: Insert Column      _ot_: Table to Org Mode
      +_sA_: -alphanumeric   _te_: Excel         _cr_: Copy Row    (C-c t r)    _ir_: Insert Row         _oe_: Enable Org-Tbl Mode
      +_si_:  ip             _tl_: Latex         _cc_: Copy Cell   (C-c t c)    _il_: Insert Line        _oc_: Turn region to columns
      +_sI_: -ip             _th_: HTML          _dd_: Delete Cell              _tr_: Transpose Table
      +_sn_:  numeric        _tt_: Tab           _dc_: Delete Column            _mr_: Move Cell right
      +_sN_: -numeric        _ta_: Aligned       _dr_: Delete Row               _ml_: Move Cell left
      +_st_:  time           ^^                  _kr_: Kill Row                 _mu_: Move Cell up
      +_sT_: -time           ^^                  _kc_: Kill Column              _md_: Move Cell down     _q_: Cancel
      +
      +
      +^^^^^^^^-----------------------------------------------------------------------------------------------------------------------
      +Reach this hydra with 
      +^^^^^^^^-----------------------------------------------------------------------------------------------------------------------
      +
      +
      +"
      +    ("mr" org-table-move-single-cell-right)
      +    ("ml" org-table-move-single-cell-left)
      +    ("mu" org-table-move-single-cell-up)
      +    ("md" org-table-move-single-cell-down)
      +    ("sa" sort-table-alphanumeric  nil)
      +    ("sA" sort-table-alphanumeric-desc nil)
      +    ("si" sort-table-ip nil)
      +    ("sI" sort-table-ip-desc  nil)
      +    ("sn" sort-table-numeric  nil)
      +    ("sN" sort-table-numeric-desc  nil)
      +    ("st" sort-table-time  nil)
      +    ("sT" sort-table-time-desc  nil)
      +
      +    ("tc" table-to-csv nil)
      +    ("te" table-to-excel    nil)
      +    ("tl" table-to-latex    nil)
      +    ("th" table-to-html     nil)
      +    ("tt" table-to-csv-tab  nil)
      +    ("ta" table-to-aligned  nil)
      +
      +    ("cl" tvd-copy-org-table-col nil)
      +    ("cr" tvd-copy-org-table-row nil)
      +    ("cc" tvd-copy-org-table-cell nil)
      +    ("dd" org-table-blank-field nil)
      +    ("dr" tvd-del-org-table-row nil)
      +    ("dc" tvd-del-org-table-col nil)
      +    ("kc" org-table-delete-column nil)
      +    ("kr" org-table-kill-row nil)
      +
      +    ("ic" org-table-insert-column nil)
      +    ("ir" org-table-insert-row nil)
      +    ("il" org-table-hline-and-move nil)
      +    ("tr" org-table-transpose-table-at-point nil)
      +
      +    ("ot" tablify  nil)
      +    ("oe" orgtbl-mode nil)
      +    ("oc" align-repeat nil)
      +
      +    ("q" nil nil :color red))
      +
      +  ;; allow me to insert org tables everywhere on request
      +  (defalias 'table     'hydra-org-tables/body)
      +  (global-set-key (kbd "C-x t") 'hydra-org-tables/body))
      diff --git a/conf-lisp/outline.el b/conf-lisp/outline.el
      new file mode 100644
      index 0000000..773b79b
      --- /dev/null
      +++ b/conf-lisp/outline.el
      @@ -0,0 +1,72 @@
      +;; *** outline mode
      +
      +;; I use the very same cycle style  as in org mode: when on a heading,
      +;; hide it, jump to next heading on the same level and expand that (or
      +;; vice versa).  however, when NOT on  a heading behave as loved: jump
      +;; paragraphs.
      +
      +;; Note, that  this also  affects outshine  mode, since  that inherits
      +;; from outline.
      +
      +(defun tvd-outline-left-or-level-up()
      +  "jump one word to the left if not on a heading,
      +otherwise fold current level and jump one level up."
      +  (interactive)
      +  (if (outline-on-heading-p)
      +      (progn
      +        (hide-subtree)
      +        (outline-up-heading 1))
      +    (left-word)))
      +
      +(defun tvd-outline-heading-up()
      +  "fold current heading, jump one level up and unfold it"
      +  (interactive)
      +  (if (not (outline-on-heading-p))
      +      (backward-paragraph)
      +    (hide-subtree)
      +    (outline-backward-same-level 1)
      +    (outline-cycle)))
      +
      +(defun tvd-outline-heading-down()
      +  "fold current heading, jump one level down and unfold it"
      +  (interactive)
      +  (if (not (outline-on-heading-p))
      +      (forward-paragraph)
      +    (hide-subtree)
      +    (outline-forward-same-level 1)
      +    (outline-cycle)))
      +
      +;; unused, see tvd-outshine-jump
      +(defun tvd-outline-jump (part)
      +  "Jump interactively to next header containing PART using search."
      +  (interactive "Mjump to: ")
      +  (let ((done nil)
      +        (pwd (point)))
      +    (beginning-of-buffer)
      +    (outline-show-all)
      +    (when (re-search-forward (format "^;; \\*+.*%s" part) (point-max) t)
      +      (when (outline-on-heading-p)
      +        (beginning-of-line)
      +        (setq done t)))
      +    (when (not done)
      +      (message (format "no heading with '%s' found" part))
      +      (goto-char pwd))))
      +
      +;; outline mode config
      +(eval-after-load "outline"
      +  '(progn
      +     (add-hook 'outline-minor-mode-hook
      +               (lambda ()
      +                 ;; narrowing, we use outshine functions, it's loaded anyway
      +                 (defalias 'n 'outshine-narrow-to-subtree)
      +                 (defalias 'w 'widen)
      +                 (define-key outline-minor-mode-map (kbd "")   'tvd-outline-heading-up)
      +                 (define-key outline-minor-mode-map (kbd "") 'tvd-outline-heading-down)
      +                 ;;(define-key outline-minor-mode-map (kbd "") 'tvd-outline-left-or-level-up)
      +                 ))))
      +
      +;; orange fringe when narrowed
      +(advice-add 'outshine-narrow-to-subtree :after
      +            '(lambda (&rest args)
      +               (set-face-attribute 'fringe nil :background tvd-fringe-narrow-bg)))
      +
      diff --git a/conf-lisp/perl.el b/conf-lisp/perl.el
      new file mode 100644
      index 0000000..71de0bb
      --- /dev/null
      +++ b/conf-lisp/perl.el
      @@ -0,0 +1,113 @@
      +;; *** cperl mode
      +
      +;; I am  a perl addict. I  love it, therefore, emacs  must be prepared
      +;; for my addiction.  Most importantly,  I prefer cperl instead of the
      +;; default perl  mode. I do not  use the cperl version  delivered with
      +;; emacs though, but the latest git version.
      +
      +(use-package cperl
      +             :ensure nil ;; builtin
      +
      +             :mode ("\.pl$" . cperl-mode)
      +             :mode ("\.pm$" . cperl-mode)
      +
      +             :config
      +             (defalias 'perl-mode 'cperl-mode)
      +
      +             ;; enable the most important cperl features
      +             (setq cperl-indent-left-aligned-comments nil)
      +             (setq cperl-comment-column 32)
      +             (setq cperl-hairy t)
      +             (setq cperl-electric-linefeed t)
      +             (setq cperl-electric-keywords t)
      +             (setq cperl-electric-parens t)
      +             (setq cperl-electric-parens-string nil)
      +
      +             (defun perl-kill ()
      +               "get rid of hanging perl compile or run buffers"
      +               (interactive)
      +               (delete-windows-on perl-run-out-buffer)
      +               (kill-buffer perl-run-out-buffer))
      +
      +             (defun perl-run (switches parameters prefix)
      +               "execute current perl buffer"
      +               (interactive "sPerl-switches:\nsParameter:\nP")
      +               (let ((file buffer-file-name))
      +                 (if (eq prefix nil)
      +                     (shell-command (concat "perl " switches " " file " " parameters "&"))
      +                   (shell-command (concat "perl -wc " switches " " file " " parameters "&")))
      +                 (save-excursion
      +                   (set-buffer perl-run-out-buffer)
      +                   (setq perl-error-fontified nil
      +                         perl-error-start nil
      +                         perl-error-end nil)
      +                   (goto-char (point-min)))
      +                 ))
      +
      +             (defun perl-next-error ()
      +               "jump to next perl run error, if any"
      +               (interactive)
      +               (let (line
      +                     errorfile
      +                     (window (get-buffer-window (buffer-name)))
      +                     (file buffer-file-name)
      +                     (buffer (buffer-name))
      +                     )
      +                 (select-window (display-buffer perl-run-out-buffer))
      +                 (set-buffer perl-run-out-buffer)
      +                 (if (eq perl-error-fontified t)
      +                     (progn
      +                       (set-text-properties perl-error-start perl-error-end ())
      +                       (setq perl-error-fontified nil)
      +                       )
      +                   )
      +                 (if (re-search-forward (concat "at \\([-a-zA-Z:0-9._~#/\\]*\\) line \\([0-9]*\\)[.,]") (point-max) t)
      +                     ()
      +                   (goto-char (point-min))
      +                   (message "LAST ERROR, jumping to first")
      +                   (re-search-forward (concat "at \\([-a-zA-Z:0-9._~#/\\]*\\) line \\([0-9]*\\)[.,]") (point-max) t)
      +                   )
      +                 (recenter)
      +                 (set-text-properties (match-beginning 1)
      +                                      (match-end 2)
      +                                      (list 'face font-lock-keyword-face))
      +                 (setq perl-error-fontified t
      +                       perl-error-start (match-beginning 1)
      +                       perl-error-end (match-end 2)
      +                       errorfile (buffer-substring
      +                                  (match-beginning 1)
      +                                  (match-end 1))
      +                       line (string-to-int (buffer-substring
      +                                            (match-beginning 2)
      +                                            (match-end 2))))
      +                 (select-window window)
      +                 (find-file errorfile)
      +                 (goto-line line)))
      +
      +             ;; cperl indent region
      +             (defun own-cperl-indent-region-or-paragraph (start end)
      +               (interactive "r")
      +               (if mark-active
      +                   (cperl-indent-region start end)
      +                 (save-excursion
      +                   (mark-paragraph)
      +                   (cperl-indent-region (point) (mark t))
      +                   )))
      +
      +             (defun tvd-cperl-hook()
      +               (make-variable-buffer-local 'perl-error-fontified)
      +                (make-variable-buffer-local 'perl-error-start)
      +                (make-variable-buffer-local 'perl-error-end)
      +                (make-variable-buffer-local 'perl-old-switches)
      +                (make-variable-buffer-local 'perl-old-parameters)
      +                (local-set-key "\C-hF" 'cperl-info-on-current-command)
      +                (local-set-key "\C-hf" 'describe-function)
      +                (local-set-key "\C-hV" 'cperl-get-help)
      +                (local-set-key "\C-hv" 'describe-variable)
      +                (local-set-key "\C-cr" 'perl-run)
      +                (local-set-key "\C-ck" 'perl-kill)
      +                (local-set-key "\C-c#" 'perl-next-error)
      +                (local-set-key "\M-\C-q" 'own-cperl-indent-region-or-paragraph)
      +                (setq mode-name "PL"))
      +
      +             :hook tvd-cperl-hook)
      diff --git a/conf-lisp/pod.el b/conf-lisp/pod.el
      new file mode 100644
      index 0000000..c42e4a3
      --- /dev/null
      +++ b/conf-lisp/pod.el
      @@ -0,0 +1,106 @@
      +;; *** POD mode
      +
      +;; I LOVE POD!  POD is the  documentation format of perl and there's a
      +;; solid toolset available for it. I use it to write documentation and
      +;; manual pages. It's  much more powerfull than lame  markdown and you
      +;; can even program  great tools yourself around POD (like  I did with
      +;; PodWiki years ago!)
      +
      +;; Although cperl mode  already has some POD support, pod  mode is way
      +;; better.
      +
      +;; Source: [[https://github.com/renormalist/emacs-pod-mode][emacs-pod-mode]]
      +(when (package-installed-p 'expand-region)
      +  ;; using expand-region: apply pod entity formatting to word at point.
      +  (defun tvd-outline-emphasize(CHAR)
      +    "expand once if no region and apply emphasize CHAR"
      +    (interactive)
      +    (unless (use-region-p)
      +      (er/expand-region 1))
      +    (save-excursion
      +      (goto-char (region-beginning))
      +      (insert (format "%c<" CHAR))
      +      (goto-char (region-end))
      +      (insert ">")))
      +
      +  (defun pod-bold()
      +    "bold text in outline mode"
      +    (interactive)
      +    (tvd-outline-emphasize ?B))
      +
      +  (defun pod-italic()
      +    "italic text in outline mode"
      +    (interactive)
      +    (tvd-outline-emphasize ?I))
      +
      +  (defun pod-code()
      +    "verbatim text in outline mode"
      +    (interactive)
      +    (tvd-outline-emphasize ?C))
      +
      +  ;; enhance abbrevs and jump into expanded area to the
      +  ;; $ character (if it exists), which it also removes
      +  (setq tvd-abbrev-pos 0)
      +  (advice-add 'expand-abbrev :before
      +              '(lambda () (setq tvd-abbrev-pos (point))))
      +  (advice-add 'expand-abbrev :after
      +              '(lambda ()
      +                 (ignore-errors
      +                   (when (re-search-backward "\\$" (- tvd-abbrev-pos 0))
      +                     (delete-char 1))))))
      +
      +(use-package pod-mode
      +             :ensure nil ;; static install
      +             :mode "\\.pod\\'"
      +
      +             :config
      +             (add-hook 'pod-mode-hook 'font-lock-mode)
      +
      +             ;; tune syntax table
      +             (modify-syntax-entry ?= "w" pod-mode-syntax-table)
      +
      +             ;; POD contains headers and I'm used to outlining if there are headers
      +             ;; so, enable outlining
      +             (setq outline-heading-alist '(("=head1" . 1)
      +                                           ("=head2" . 2)
      +                                           ("=head3" . 3)
      +                                           ("=head4" . 4)
      +                                           ("=over" . 5)
      +                                           ("=item" . 6)
      +                                           ("=begin" . 5)
      +                                           ("=pod" . 5)
      +                                           ))
      +
      +             ;; outline alone, however, works well
      +             (outline-minor-mode)
      +
      +             ;; my own abbrevs for POD using mode-specific abbrev table
      +             (define-abbrev-table 'pod-mode-abbrev-table '(
      +                                                           ("=o" "=over\n\n=item *$\n\n=back\n\n")
      +                                                           ("=i" "=item ")
      +                                                           ("=h1" "=head1 ")
      +                                                           ("=h2" "=head2 ")
      +                                                           ("=h3" "=head3 ")
      +                                                           ("=h4" "=head4 ")
      +                                                           ("=c"  "=cut")
      +                                                           ("=b"  "=begin")
      +                                                           ("=e"  "=end")
      +                                                           ("b"  "B<$>")
      +                                                           ("c"  "C<$>")
      +                                                           ("l"  "L<$>")
      +                                                           ("i"  "I<$>")
      +                                                           ("e"  "E<$>")
      +                                                           ("f"  "F<$>"))
      +               "POD mode abbreviations, see .emacs")
      +
      +             (abbrev-table-put pod-mode-abbrev-table :case-fixed t)
      +             (abbrev-table-put pod-mode-abbrev-table :system t)
      +
      +             ;; enable abbreviations
      +             (setq local-abbrev-table pod-mode-abbrev-table)
      +             (abbrev-mode 1)
      +
      +             ;; POD easy formatting
      +             (local-set-key (kbd "C-c b") 'pod-bold)
      +             (local-set-key (kbd "C-c /") 'pod-italic)
      +             (local-set-key (kbd "C-c c") 'pod-code))
      diff --git a/conf-lisp/printing.el b/conf-lisp/printing.el
      new file mode 100644
      index 0000000..7752984
      --- /dev/null
      +++ b/conf-lisp/printing.el
      @@ -0,0 +1,28 @@
      +;; *** Printing
      +;; overwrites printing default menu, access via menu File => Print
      +;; or:
      +;; - M-x ps-spool-buffer-with-faces
      +;; - go to *spool* buffer
      +;; - save to .ps file
      +;; - print
      +(require 'printing)
      +(pr-menu-bind)
      +
      +;; via [[https://emacs.stackexchange.com/questions/9364/convert-a-text-buffer-to-a-pdf-file][stackoverflow]]
      +(when (executable-find "ps2pdf")
      +  (defun print-to-pdf (&optional filename)
      +    "Print file in the current buffer as pdf, including font, color, and
      +underline information.  This command works only if you are using a window system,
      +so it has a way to determine color values.
      +
      +C-u COMMAND prompts user where to save the Postscript file (which is then
      +converted to PDF at the same location."
      +    (interactive (list (if current-prefix-arg
      +                           (ps-print-preprint 4)
      +                         (concat (file-name-sans-extension (buffer-file-name))
      +                                 ".ps"))))
      +    (ps-print-with-faces (point-min) (point-max) filename)
      +    (shell-command (concat "ps2pdf " filename))
      +    (delete-file filename)
      +    (message "Deleted %s" filename)
      +    (message "Wrote %s" (concat (file-name-sans-extension filename) ".pdf"))))
      diff --git a/conf-lisp/projectile.el b/conf-lisp/projectile.el
      new file mode 100644
      index 0000000..d5256fc
      --- /dev/null
      +++ b/conf-lisp/projectile.el
      @@ -0,0 +1,38 @@
      +;; *** Projectile
      +(use-package projectile
      +             :config
      +             (projectile-mode +1)
      +
      +             (defun tvd-dir-to-projectile ()
      +               "drop a .projectile wherever we are"
      +               (interactive)
      +               (with-temp-file ".projectile"
      +                 (insert "-.snapshot\n-.git\n-.RCS\n"))
      +               (message (format "Turned %s into projectile project" default-directory)))
      +
      +             ;; FIXME: add custom docstring
      +             (when (fboundp 'defhydra)
      +               (defhydra hydra-projectile
      +                 ( :color teal
      +                          :columns 4)
      +                 "Projectile (use C-p for this menu)"
      +                 ("s"   projectile-switch-project           "Switch Project")
      +                 ("f"   projectile-find-file                "Find File")
      +                 ("r"   projectile-recentf                  "Recent Files")
      +                 ("b"   projectile-ibuffer                  "Show Project Buffers")
      +
      +                 ("g"   projectile-grep                     "Grep")
      +                 ("o"   projectile-multi-occur              "Multi Occur")
      +                 ("d"   projectile-dired                    "Project Dired")
      +                 ("R"   projectile-replace                  "Replace in Project")
      +
      +                 ("C"   projectile-invalidate-cache         "Clear Cache")
      +                 ("t"   projectile-regenerate-tags          "Regenerate Tags")
      +                 ("X"   projectile-cleanup-known-projects   "Cleanup Known Projects")
      +                 ("n"   tvd-dir-to-projectile               "Turn current directory into Projectile")
      +
      +                 ("c"   projectile-commander                "Commander")
      +                 ("k"   projectile-kill-buffers             "Kill Buffers")
      +                 ("q"   nil                                 "Cancel" :color blue))
      +
      +               (global-set-key (kbd "C-x p") 'hydra-projectile/body)))
      diff --git a/conf-lisp/python.el b/conf-lisp/python.el
      new file mode 100644
      index 0000000..0ff0b9e
      --- /dev/null
      +++ b/conf-lisp/python.el
      @@ -0,0 +1,12 @@
      +(use-package python
      +  :mode ("\\.py\\'" . python-mode)
      +  :interpreter ("python" . python-mode)
      +  :mode "\\.py\\'"
      +  :hook
      +   (function
      +    (lambda()
      +      (local-set-key  [delete] 'py-electric-delete)
      +      (setq-default indent-tabs-mode nil)
      +      (setq mode-name "PY")
      +      (outline-minor-mode 0) ;; turn off outline here. FIXME: find out where it's turned on!
      +      )))
      diff --git a/conf-lisp/recentfiles.el b/conf-lisp/recentfiles.el
      new file mode 100644
      index 0000000..c730989
      --- /dev/null
      +++ b/conf-lisp/recentfiles.el
      @@ -0,0 +1,61 @@
      +;;; *** Recent Files
      +
      +;; You know the  file you edited yesterday had "kri"  in its name, but
      +;; where was it? You don't remember.  But don't worry, recent files is
      +;; your friend.  It shows the last  N files you edited  recently.
      +;; I use it permanently.
      +
      +;; see also: ido-mode and smex
      +
      +(defun tvd-buffer-exists-p (bufname)
      +  (not (eq nil (get-file-buffer bufname))))
      +
      +;; setup
      +(use-package recentf
      +             :config
      +             (require 'cl-lib)
      +             (setq recentf-auto-cleanup 'never) ;; avoid stat() on tramp buffers
      +             (recentf-mode 1)
      +
      +             ;; I like to have a longer list reaching deeper into the past
      +             (setq recentf-max-menu-items 200
      +                   recentf-max-saved-items nil)
      +
      +             ;; enable IDO completion
      +             ;; via [[http://emacsredux.com/blog/2013/04/05/recently-visited-files/][emacsredux]]
      +             ;; modified to exclude already visited files
      +             (defun recentf-ido-find-file ()
      +               "Find a recent file using ido."
      +               (interactive)
      +               (let ((file (ido-completing-read
      +                            "Choose recent file: "
      +                            (cl-remove-if 'tvd-buffer-exists-p recentf-list) nil t)))
      +                 (when file
      +                   (find-file file))))
      +
      +             (global-set-key (kbd "C-x C-r")         'recentf-ido-find-file)                           ; open recent files, same as M-x rf
      +
      +             ;; now if I incidentally closed a  buffer, I can re-open it, thanks to
      +             ;; recent-files
      +             (defun undo-kill-buffer (arg)
      +               "Re-open the last buffer killed.  With ARG, re-open the nth buffer."
      +               (interactive "p")
      +               (let ((recently-killed-list (copy-sequence recentf-list))
      +                     (buffer-files-list
      +                      (delq nil (mapcar (lambda (buf)
      +                                          (when (buffer-file-name buf)
      +                                            (expand-file-name (buffer-file-name buf)))) (buffer-list)))))
      +                 (mapc
      +                  (lambda (buf-file)
      +                    (setq recently-killed-list
      +                          (delq buf-file recently-killed-list)))
      +                  buffer-files-list)
      +                 (find-file
      +                  (if arg (nth arg recently-killed-list)
      +                    (car recently-killed-list)))))
      +
      +             ;; exclude some auto generated files
      +             (setq recentf-exclude (list "ido.last"
      +                                         "/elpa/"
      +                                         ".el.gz$"
      +                                         '(not (file-readable-p)))))
      diff --git a/conf-lisp/rust.el b/conf-lisp/rust.el
      new file mode 100644
      index 0000000..0d7bbb1
      --- /dev/null
      +++ b/conf-lisp/rust.el
      @@ -0,0 +1,13 @@
      +;; *** rust  mode
      +(use-package rust-mode
      +             :config
      +
      +             (defun rustlings-done ()
      +               "I use this with rustlings"
      +               (interactive)
      +               (search-backward "DONE")
      +               (move-beginning-of-line 1)
      +               (kill-line)
      +               (save-buffer))
      +
      +             :mode "\\.rs\\'")
      diff --git a/conf-lisp/sgml.el b/conf-lisp/sgml.el
      new file mode 100644
      index 0000000..b6c43e9
      --- /dev/null
      +++ b/conf-lisp/sgml.el
      @@ -0,0 +1,18 @@
      +;; *** sgml
      +
      +;; Used for XML and the likes.
      +
      +(setq sgml-set-face t)
      +(setq sgml-balanced-tag-edit t)
      +(setq sgml-omittag-transparent nil)
      +(setq sgml-auto-insert-required-elements t)
      +
      +(setq sgml-markup-faces
      +      '((start-tag . font-lock-function-name-face)
      +        (end-tag . font-lock-function-name-face)
      +        (comment . font-lock-comment-face)
      +        (pi . font-lock-other-type-face)
      +        (sgml . font-lock-variable-name-face)
      +        (doctype . font-lock-type-face)
      +        (entity . font-lock-string-face)
      +        (shortref . font-lock-keyword-face)))
      diff --git a/conf-lisp/shellscript.el b/conf-lisp/shellscript.el
      new file mode 100644
      index 0000000..edc1390
      --- /dev/null
      +++ b/conf-lisp/shellscript.el
      @@ -0,0 +1,8 @@
      +;; *** Shell-Script Mode
      +
      +;; C-c C-c [un-]comments everywhere, force in shell-script-mode as well
      +(add-hook
      + 'sh-mode-hook
      + (function
      +  (lambda()
      +    (local-set-key (kbd "C-c C-c")  'comment-or-uncomment-region-or-line))))
      diff --git a/conf-lisp/smartparens.el b/conf-lisp/smartparens.el
      new file mode 100644
      index 0000000..1b709d5
      --- /dev/null
      +++ b/conf-lisp/smartparens.el
      @@ -0,0 +1,200 @@
      +;; I'm trying  to migrate  to smart-parens, since  it supports  all of
      +;; paredit but can do more
      +
      +;; Also look at:
      +;; https://github.com/Fuco1/.emacs.d/blob/master/files/smartparens.el
      +;; https://github.com/Fuco1/smartparens/wiki
      +;; https://ebzzry.io/en/emacs-pairs/
      +
      +(defun tvd-disable-par-and-pair()
      +  "Disables Paredit and Electric-Pair-Mode if currently active.
      +Used when enabling smartparens-mode."
      +  (interactive)
      +  (when electric-pair-mode
      +    (electric-pair-mode))
      +  (when (fboundp 'pparedit-mode)
      +    (when paredit-mode
      +      (disable-paredit-mode))))
      +
      +;; I use my own lisp comment tool until sp#942 is fixed
      +(defun tvd-lisp-comment ()
      +  (interactive)
      +  (if (not (looking-at "\s*\("))
      +      (self-insert-command 1)
      +    (let ((beg (point)))
      +      (forward-list 1)
      +      (when (looking-at "\s*\)")
      +        (insert "\n"))
      +      (comment-region beg (point))
      +      (indent-for-tab-command)
      +      (goto-char beg))))
      +
      +(use-package smartparens
      +             :config
      +             (require 'smartparens-config)
      +             (require 'cl-lib)
      +
      +             ;; enable sp in minibuffer as well
      +             ;; maybe, see: https://github.com/Fuco1/smartparens/issues/33:
      +             ;; (sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil)
      +             (setq sp-ignore-modes-list
      +                   (delete 'minibuffer-inactive-mode sp-ignore-modes-list))
      +
      +             ;; automatically enable where needed
      +             (add-something-to-mode-hooks
      +              '(rust emacs-lisp ielm lisp lisp-interaction scheme slime-repl ) 'smartparens-mode)
      +
      +             ;; also in some select prog modes
      +             (add-something-to-mode-hooks
      +              '(perl ruby c c++ sh makefile config-general yaml go) 'smartparens-mode)
      +
      +             ;; via https://ebzzry.io/en/emacs-pairs/:
      +             (defmacro def-pairs (pairs)
      +               "Define functions for pairing. PAIRS is an alist of (NAME . STRING)
      +conses, where NAME is the function name that will be created and
      +STRING is a single-character string that marks the opening character.
      +
      +  (def-pairs ((paren . \"(\")
      +              (bracket . \"[\"))
      +
      +defines the functions WRAP-WITH-PAREN and WRAP-WITH-BRACKET,
      +respectively."
      +               `(progn
      +                  ,@(cl-loop for (key . val) in pairs
      +                          collect
      +                          `(defun ,(read (concat
      +                                          "wrap-with-"
      +                                          (prin1-to-string key)
      +                                          "s"))
      +                               (&optional arg)
      +                             (interactive "p")
      +                             (sp-wrap-with-pair ,val)))))
      +
      +             (def-pairs ((paren . "(")
      +                         (bracket . "[")
      +                         (brace . "{")
      +                         (single-quote . "'")
      +                         (double-quote . "\"")
      +                         (back-quote . "`")))
      +
      +             ;;(add-hook 'smartparens-enabled-hook #'tvd-disable-par-and-pair)
      +             ;;(add-hook 'smartparens-enabled-hook #'turn-on-smartparens-strict-mode)
      +
      +             ;; auto wrapping w/o region
      +             (define-key smartparens-mode-map (kbd "C-c (")  'wrap-with-parens)
      +             (define-key smartparens-mode-map (kbd "C-c [")  'wrap-with-brackets)
      +             (define-key smartparens-mode-map (kbd "C-c {")  'wrap-with-braces)
      +             (define-key smartparens-mode-map (kbd "C-c '")  'wrap-with-single-quotes)
      +             (define-key smartparens-mode-map (kbd "C-c \"") 'wrap-with-double-quotes)
      +             (define-key smartparens-mode-map (kbd "C-c `")  'wrap-with-back-quotes)
      +
      +             ;; modification
      +             (define-key smartparens-mode-map (kbd "C-k")           'sp-kill-hybrid-sexp)
      +             (define-key smartparens-mode-map (kbd "C-")      'sp-forward-slurp-sexp)
      +             (define-key smartparens-mode-map (kbd "C-")     'sp-forward-barf-sexp)
      +
      +             ;; movement
      +             ;; Also Check: https://github.com/Fuco1/smartparens/wiki/Working-with-expressions
      +             ;; (look for "quick summary for each navigation function")
      +             ;;
      +             ;; Jump after  the next  balanced expression.  If inside  one and
      +             ;; there is no forward exp., jump after its closing pair.
      +             (define-key smartparens-mode-map (kbd "C-M-") 'sp-forward-sexp)
      +             ;; Jump before  the previous  balanced expression. If  inside one
      +             ;; and there is no previous exp., jump before its opening pair.
      +             (define-key smartparens-mode-map (kbd "C-M-")  'sp-backward-sexp)
      +             ;; Jump up one  level from the current  balanced expression. This
      +             ;; means skipping  all the  enclosed expressions within  this and
      +             ;; then jumping after the closing pair.
      +             (define-key smartparens-mode-map (kbd "C-M-")    'sp-up-sexp)
      +             ;; Jump after the opening pair  of next balanced expression. This
      +             ;; effectively  descends  one  level   down  in  the  "expression
      +             ;; hierarchy".  If there  is no  expression to  descend to,  jump
      +             ;; after current expression's  opening pair. This can  be used to
      +             ;; quickly  navigate   to  the  beginning  of   current  balanced
      +             ;; expression.
      +             (define-key smartparens-mode-map (kbd "C-M-")  'sp-down-sexp)
      +             ;;  Jump to  the beginning  of following balanced  expression. If
      +             ;;  there is no  following expression on the  current level, jump
      +             ;;  one level up backward, effectively doing sp-backward-up-sexp.
      +             (define-key smartparens-mode-map (kbd "C-S-")  'sp-next-sexp)
      +             ;; Jump to the end of  the previous balanced expression. If there
      +             ;; is no previous expression on the current level, jupm one level
      +             ;; up forward, effectively doing sp-up-sexp.
      +             (define-key smartparens-mode-map (kbd "C-S-") 'sp-previous-sexp)
      +
      +             ;; comment the whole sexp
      +             (define-key smartparens-mode-map (kbd ";") 'tvd-lisp-comment)
      +
      +             ;; replace my global setting
      +             ;; FIXME: fhceck/fix M!
      +             (define-key smartparens-mode-map (kbd "M-")   'sp-forward-symbol)
      +             (define-key smartparens-mode-map (kbd "M-")    'sp-backward-symbol)
      +
      +             (when (fboundp 'defhydra)
      +               (defhydra hydra-smartparens (:hint nil)
      +                 "
      +Sexps [quit with _q_, reach this hydra with 'C-x (']
      +
      +^Nav^                       ^Barf/Slurp^                           ^Depth^
      +^---^-----------------------^----------^---------------------------^-----^-----------------
      +_f_: forward  (C-M-right)   _→_:          slurp forward (C-right)  _R_: splice
      +_b_: backward (C-M-left)    _←_:          barf forward  (C-left)   _r_: raise
      +_u_: backward ↑             _C-_:  slurp backward           _↑_: raise backward
      +_d_: forward  ↓ (C-M-down)  _C-_:   barf backward            _↓_: raise forward
      +_p_: backward ↓
      +_n_: forward  ↑ (C-M-up)
      +
      +^Kill^           ^Misc^                       ^Wrap^
      +^----^-----------^----^-----------------------^----^------------------
      +_w_: copy        _j_: join                    _(_: wrap with ( )
      +_k_: kill (C-k)  _s_: split                   _{_: wrap with { }
      +^^               _t_: transpose               _'_: wrap with ' '
      +^^               _c_: convolute               _\"_: wrap with \" \"
      +^^               _i_: indent defun
      +
      +"
      +                 ("q" nil)
      +                 ;; Wrapping
      +                 ("(" (lambda (_) (interactive "P") (sp-wrap-with-pair "(")))
      +                 ("{" (lambda (_) (interactive "P") (sp-wrap-with-pair "{")))
      +                 ("'" (lambda (_) (interactive "P") (sp-wrap-with-pair "'")))
      +                 ("\"" (lambda (_) (interactive "P") (sp-wrap-with-pair "\"")))
      +                 ;; Navigation
      +                 ("f" sp-forward-sexp )
      +                 ("b" sp-backward-sexp)
      +                 ("u" sp-backward-up-sexp)
      +                 ("d" sp-down-sexp)
      +                 ("p" sp-backward-down-sexp)
      +                 ("n" sp-up-sexp)
      +                 ;; Kill/copy
      +                 ("w" sp-copy-sexp)
      +                 ("k" sp-kill-sexp)
      +                 ;; Misc
      +                 ("t" sp-transpose-sexp)
      +                 ("j" sp-join-sexp)
      +                 ("s" sp-split-sexp)
      +                 ("c" sp-convolute-sexp)
      +                 ("i" sp-indent-defun)
      +                 ;; Depth changing
      +                 ("R" sp-splice-sexp)
      +                 ("r" sp-splice-sexp-killing-around)
      +                 ("" sp-splice-sexp-killing-backward)
      +                 ("" sp-splice-sexp-killing-forward)
      +                 ;; Barfing/slurping
      +                 (""     sp-forward-slurp-sexp)
      +                 (""    sp-forward-barf-sexp)
      +                 ("C-"   sp-backward-barf-sexp)
      +                 ("C-"  sp-backward-slurp-sexp))
      +
      +               (define-key smartparens-mode-map (kbd "C-x (")         'hydra-smartparens/body)
      +               ))
      +
      +;;; Parens config goes here as well
      +
      +;; display matching braces
      +(show-paren-mode 1)
      +
      +;; 'mixed: highlight all if the other paren is invisible
      +;; 'expression: highlight the whole sexp
      +(setq show-paren-style 'mixed)
      diff --git a/conf-lisp/suggest.el b/conf-lisp/suggest.el
      new file mode 100644
      index 0000000..6320165
      --- /dev/null
      +++ b/conf-lisp/suggest.el
      @@ -0,0 +1,43 @@
      +;; *** Suggest Mode
      +
      +;; [[https://github.com/Wilfred/suggest.el][suggest mode]] is a great
      +;; elisp development tool. Execute `M-x suggest' and try it.
      +
      +;; FIXME: doesn't install, seems to use a different version from elpa, which requires spinner ?!?!:
      +;; Error (use-package): Failed to install suggest: Opening output file:
      +;; No such file or directory, /home/scip/.emacs-init.d/elpa-27.1/spinner-1.7.4/spinner-autoloads.el
      +;; spinner is here: https://elpa.gnu.org/packages/spinner.html
      +(when nil
      +  (use-package suggest
      +               :config
      +
      +               ;; I use my own clearing function, since suggest doesn't provide this
      +               (defun tvd-suggest-reload ()
      +                 "Clear suggest buffer and re-paint it."
      +                 (interactive)
      +                 (let ((inhibit-read-only t))
      +                   (erase-buffer)
      +                   (suggest--insert-heading suggest--inputs-heading)
      +                   (insert "\n\n\n")
      +                   (suggest--insert-heading suggest--outputs-heading)
      +                   (insert "\n\n\n")
      +                   (suggest--insert-heading suggest--results-heading)
      +                   (insert "\n")
      +                   (suggest--nth-heading 1)
      +                   (forward-line 1)))
      +
      +               (defun tvd-suggest-jump ()
      +                 "Jump between input and output suggest buffer."
      +                 (interactive)
      +                 (forward-line -1)
      +                 (if (eq (line-number-at-pos) 1)
      +                     (suggest--nth-heading 2)
      +                   (suggest--nth-heading 1))
      +                 (forward-line 1))
      +
      +               (eval-after-load "suggest"
      +                 '(progn
      +                    (add-hook 'suggest-mode-hook
      +                              (lambda ()
      +                                (local-set-key (kbd "C-l") 'tvd-suggest-reload)
      +                                (local-set-key (kbd "") 'tvd-suggest-jump)))))))
      diff --git a/conf-lisp/system.el b/conf-lisp/system.el
      new file mode 100644
      index 0000000..f9e0db7
      --- /dev/null
      +++ b/conf-lisp/system.el
      @@ -0,0 +1,252 @@
      +;;; Backup Config
      +
      +;; I save backup files in a  central location below the init dir, that
      +;; way they don't clutter productive file systems or repos.
      +
      +(setq tvd-backup-directory (expand-file-name "backups" tvd-config-dir))
      +(if (not (file-exists-p tvd-backup-directory))
      +    (make-directory tvd-backup-directory t))
      +
      +;; there's even a trash
      +(setq tvd-trash-directory (expand-file-name "trash" tvd-backup-directory))
      +
      +
      +;; actual configuration of all things backup related:
      +(setq make-backup-files t               ; backup of a file the first time it is saved.
      +      backup-by-copying t               ; don't clobber symlinks
      +      version-control t                 ; version numbers for backup files
      +      delete-old-versions t             ; delete excess backup files silently
      +      delete-by-moving-to-trash t
      +      kept-old-versions 6               ; oldest versions to keep when a new numbered backup is made (default: 2)
      +      kept-new-versions 9               ; newest versions to keep when a new numbered backup is made (default: 2)
      +      auto-save-default t               ; auto-save every buffer that visits a file
      +      auto-save-timeout 20              ; number of seconds idle time before auto-save (default: 30)
      +      auto-save-interval 200            ; number of keystrokes between auto-saves (default: 300)
      +      delete-by-moving-to-trash t
      +      trash-directory tvd-trash-directory
      +      backup-directory-alist `(("emacs.d/\\(recentf\\|ido.last\\|places\\)" . nil) ; do not backup state files
      +                               ("." . ,tvd-backup-directory))) ; backup everything else
      +
      +;; However, if the file to be backed up is remote, backup
      +;; per remote directory. that way, no root owned files end
      +;; up in my home directory, ready to be read by everyone.
      +;; This is system specific and only matches special host names.
      +;; FIXME: find out programatically hostname und remote user to make this generic
      +(advice-add 'make-backup-file-name-1 :before
      +            '(lambda (&rest file)
      +               (let ((filename (car file)))
      +                 (if (string-match "\\(/ssh:.devel[0-9]+\\):/" filename)
      +                     (setq backup-directory-alist `(("." . ,(concat (match-string 1 filename) ":/root/.emacs.d/backups"))))
      +                   (setq backup-directory-alist `(("." . ,tvd-backup-directory)))))))
      +
      +;; FIXME: and/or check [[https://www.gnu.org/software/tramp/#Auto_002dsave-and-Backup][gnu.org]]
      +;; + tramp-default-proxies-alist
      +
      +
      +
      +;;; console backspace fix
      +
      +;; make backspace work in console sessions
      +(define-key key-translation-map [?\C-h] [?\C-?])
      +
      +
      +;;; ** hide menu- and tool-bar
      +
      +;; I prefer a bare bones emacs window without any distractions, so turn them off.
      +(menu-bar-mode -1)
      +(tool-bar-mode -1)
      +(setq use-dialog-box nil)
      +(scroll-bar-mode 0)
      +
      +
      +;;; ** stay silent on startup
      +(setq initial-scratch-message "")
      +(setq inhibit-startup-message t)
      +(setq inhibit-startup-screen t)
      +(setq inhibit-startup-echo-area-message "scip")
      +
      +
      +;;; ** y means yes
      +;; y is shorter than yes and less error prone.
      +(defalias 'yes-or-no-p 'y-or-n-p)
      +
      +
      +;;; ** show col in modeline
      +;; very useful to know current column
      +(column-number-mode t)
      +
      +;;; ** file or buffer in title
      +;; this can be seen in xmobar
      +(setq frame-title-format '(buffer-file-name "emacs %f" ("emacs %b")))
      +
      +
      +;;; ** avoid invalid files
      +(setq require-final-newline t)
      +
      +
      +;;; ** byte-compile all of them, if needed
      +;; ;; handy function to recompile all lisp files
      +;; (defun recompile-el()
      +;;   (interactive)
      +;;   (byte-recompile-directory tvd-config-dir 0))
      +
      +
      +;;; ** re-read a modified buffer
      +
      +;; F5 == reload file if it has been modified by another process, shift
      +;; because Xmonad
      +(global-set-key (kbd "S-")                                                            ; re-read a buffer from disk (revert)
      +                (lambda (&optional force-reverting)
      +                  "Interactive call to revert-buffer. Ignoring the auto-save
      + file and not requesting for confirmation. When the current buffer
      + is modified, the command refuses to revert it, unless you specify
      + the optional argument: force-reverting to true."
      +                  (interactive "P")
      +                  ;;(message "force-reverting value is %s" force-reverting)
      +                  (if (or force-reverting (not (buffer-modified-p)))
      +                      (revert-buffer :ignore-auto :noconfirm)
      +                    (error "The buffer has been modified"))))
      +
      +
      +
      +;;; ** handy aliases
      +
      +;; M-x q r  is short enough  for me, no need for key bindings for
      +;; those
      +
      +(defalias 'qrr       'query-replace-regexp)
      +(defalias 'qr        'query-replace)
      +(defalias 'cr        'comment-region)
      +(defalias 'ur        'uncomment-region)
      +(defalias 'ir        'indent-region)
      +(defalias 'dv        'describe-variable)
      +(defalias 'dk        'describe-key)
      +(defalias 'df        'describe-function)
      +(defalias 'dp        'describe-char)
      +(defalias 'dm        'describe-mode)
      +(defalias 'db        'describe-bindings)
      +(defalias 'dl        'finder-commentary) ; aka "describe library"
      +(defalias 'repl      'ielm)
      +(defalias 'ws        'window-configuration-to-register) ; save window config
      +(defalias 'wr        'jump-to-register)                 ; restore window config
      +(defalias 'rec       'rectangle-mark-mode)
      +(defalias '|         'shell-command-on-region) ; apply shell command on region
      +
      +
      +;;; ** various settings
      +
      +;; point stays while scrolling
      +(setq scroll-preserve-screen-position t)
      +
      +;; do not save until I hit C-x-s
      +(setq auto-save-default nil)
      +
      +;; show all buffers in buffer menu
      +(setq buffers-menu-max-size nil)
      +
      +;; start to wrap at 30 entries
      +(setq mouse-buffer-menu-mode-mult 30)
      +
      +;; I'm grown up!
      +(setq disabled-command-function nil)
      +
      +
      +;;; ** copy/paste Config
      +
      +;; Related:
      +;; - see also mark-copy-yank-things-mode below!
      +;; - see also: move-region below (for M-)
      +;; - see also: expand-region below (for C-0)
      +
      +;; middle mouse button paste at click not where cursor is
      +(setq mouse-yank-at-point t)
      +
      +;; highlight selected stuff (also allows DEL of active region)
      +(setq transient-mark-mode t)
      +
      +;; pasting onto selection deletes it
      +(delete-selection-mode t)
      +
      +;; delete whole lines
      +(setq kill-whole-line t)
      +
      +;; middle-mouse and C-y use both X-selection and Emacs-clipboard
      +;; (if (null tvd-win-home)
      +;;     (progn  ; unix
      +;;       (setq x-select-enable-primary t)
      +;;       (setq x-select-enable-clipboard nil))
      +;;   (progn    ; win
      +;;     (global-set-key (kbd "") 'yank)))
      +
      +;; marked region automatically copied, also on win
      +(setq mouse-drag-copy-region t)
      +
      +
      +;;; ** use more mem
      +(setq gc-cons-threshold 20000000)
      +
      +
      +;;; ** better file name completion
      +
      +;; Complete filenames case insensitive and ignore certain files during completion.
      +(setq read-file-name-completion-ignore-case t)
      +(setq read-buffer-completion-ignore-case t)
      +
      +;; via [[http://endlessparentheses.com/improving-emacs-file-name-completion.html][endlessparantheses]]
      +(mapc (lambda (x)
      +        (add-to-list 'completion-ignored-extensions x))
      +      '(".aux" ".bbl" ".blg" ".exe"
      +        ".log" ".meta" ".out" ".pdf"
      +        ".synctex.gz" ".tdo" ".toc"
      +        "-pkg.el" "-autoloads.el" ".elc"
      +        ".dump" ".ps" ".png" ".jpg"
      +        ".gz" ".tgz" ".zip"
      +        "Notes.bib" "auto/"))
      +
      +
      +;;; ** abbreviations
      +
      +;; Do I really need those anymore? Added ca 1999...
      +
      +(define-abbrev-table 'global-abbrev-table '(
      +                                            ("oe" "ö" nil 0)
      +                                            ("ue" "ü" nil 0)
      +                                            ("ae" "ä" nil 0)
      +                                            ("Oe" "Ö" nil 0)
      +                                            ("Ue" "Ü" nil 0)
      +                                            ("Ae" "Ä" nil 0)
      +                                            ("
    • " "
    • " nil 0) + ("
        " "
        " nil 0) + )) + +;; do NOT ask to save abbrevs on exit +(setq save-abbrevs nil) + + +;;; ** meaningful names for buffers with the same name + +;; from ([[https://github.com/bbatsov/prelude][prelude]]) + +(require 'uniquify) +(setq uniquify-buffer-name-style 'forward) +(setq uniquify-separator "/") +(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified +(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers + + +;;; ** My own global variables + +;; narrowed fringe background +(defvar tvd-fringe-narrow-bg "OrangeRed") + + +;;; ** Recenter config + +;; [[http://oremacs.com/2015/03/28/recenter/][via abo abo]] + +;; However, I set the first position to 1, which causes the window to +;; be recentered on the second line, that is, I can see one line above +;; the current one. It works the same with bottom, which I intend, but +;; I think this is a recenter calculation bug. + +(setq recenter-positions '(1 middle bottom)) diff --git a/conf-lisp/tablist.el b/conf-lisp/tablist.el new file mode 100644 index 0000000..046b2a5 --- /dev/null +++ b/conf-lisp/tablist.el @@ -0,0 +1,33 @@ +;; *** Tabulated List Mode +;; built-in, used by many interactive major modes + + (defun tvd-close-window () + (interactive) + (kill-this-buffer) + (delete-window)) + +;; +tablist, which provides many cool features +;; [[https://github.com/politza/tablist][github source]] +;; important commands: +;; - < shrink column +;; - > enlarge column +;; - s sort column +;; - / prefix for filter commands +;; / e edit filter, e.g. do not list auto-complete sub-packages in melpa: +;; / a ! Package =~ ac- +(use-package tablist + :ensure t + + :config + + ;; we need to kill tablist's binding in order to have ours run (see below) + (define-key tablist-minor-mode-map (kbd "q") nil) + (define-key tablist-minor-mode-map (kbd "q") 'tvd-close-window) + + (eval-after-load "tabulated-list" + '(progn + (add-hook 'tabulated-list-mode-hook + (lambda () + (tablist-minor-mode) + (local-set-key (kbd "Q") 'delete-other-windows) + (hl-line-mode)))))) diff --git a/conf-lisp/test.el b/conf-lisp/test.el new file mode 100644 index 0000000..0b19fd4 --- /dev/null +++ b/conf-lisp/test.el @@ -0,0 +1,2 @@ +(message (format "DEBUG: default-text-scale installed: %s" (package-installed-p 'default-text-scale))) +(package-install 'default-text-scale) diff --git a/conf-lisp/textmanipulation.el b/conf-lisp/textmanipulation.el new file mode 100644 index 0000000..0a94c46 --- /dev/null +++ b/conf-lisp/textmanipulation.el @@ -0,0 +1,279 @@ +;; ** Text Manupilation +;; *** expand-region + +;; One of the best modes I ever discovered. Press C-= multiple times +;; to create a larger and larger region. I use C-0 (zero) because on a +;; german keyboard this is the same as C-= without pressing shift. + +(use-package expand-region + :config + (global-set-key (kbd "C-0") 'er/expand-region)) ; C-= without pressing shift on DE keyboard + +;; related to ER: +;; *** Mark, Copy, Yank Things + +;; For a long time this stuff was located here in my emacs config. As +;; it grew larger and larger I decided to put it into its own mode: +;; mark-copy-yank-things-mode, which can be found on github these +;; days. + +;; With this, you can quickly mark or copy or copy+yank things like +;; words, ip's, url's, lines or defun's with one key binding. I use +;; this permanently and couldn't live without it anymore. + +;; A special feature is the copy+yanking, this is something vi offers: +;; go to a line, press yy, then p and the current line will be yanked +;; below. Prefix with a number and copy+yank more lines. This is +;; really cool and (in vi) often used. So, with this mode, I can use +;; it with emacs as well. For example, say you edit a configuration +;; file and added a complicated statement. Next you need to add +;; another very similar statement. Instead of entering it again, you +;; just hit and the current line appears as a copy +;; below. Change the differences and you're done! + +(use-package mark-copy-yank-things-mode + :ensure nil ;; instaled by el-get + :config + (mark-copy-yank-things-global-mode) + + ;; The mode has a rather impractical prefix since it's published on + ;; github and therefore must be written in a way not to disturb other + ;; modes. However, I myself need those simple prefixes: + (define-key mark-copy-yank-things-mode-map (kbd "C-c") 'mcyt-copy-map) + (define-key mark-copy-yank-things-mode-map (kbd "M-a") 'mcyt-mark-map) + ;; I use the default yank map + + ;; With this I put the last thing copied into a register 'c. I can + ;; then later yank this using C-v anytime without browsing the + ;; kill-ring if I kill things between yanking. So, C-v always inserts + ;; the last copied thing, while C-y yanks the last thing killed, which + ;; might be something else. + (advice-add 'mcyt--copy-thing + :after + '(lambda (&rest args) + (with-temp-buffer + (yank) + (copy-to-register 'c (point-min) (point-max))))) + + (defun tvd-insert-c-register () + "Paste from the global yank register, fed by mcyt-copy-*" + (interactive) + (insert-register 'c)) + + (global-set-key (kbd "C-v") 'tvd-insert-c-register) + + ;; copy a real number and convert it to german punctuation upon + ;; yanking, so I can do some calculations in 'calculator, copy the + ;; result NNN.NN and paste it into my online banking formular, where + ;; it appears as NNN,NN. + (defun tvd-mcyt-copy-euro (&optional arg) + "Copy euro at point into kill-ring and convert to german punctuation" + (interactive "P") + (mcyt--blink-and-copy-thing 'mcyt-beginning-of-ip 'mcyt-end-of-ip arg) + (with-temp-buffer + (yank) + (beginning-of-buffer) + (while (re-search-forward "\\." nil t) + (replace-match ",")) + (kill-region (point-min) (point-max)))) + + (define-key mcyt-copy-map (kbd "g") 'tvd-mcyt-copy-euro)) + + +;; -------------------------------------------------------------------------------- + +;; *** change-inner + +;; I use change-inner with a prefix key and some wrappers around +;; mark-copy-yank-things-mode, which is related to change-inner +;; and expand-region. + +;; first some functions: +(defun tvd-ci (beg end &optional ins) + "change-inner simulator which works with symbols instead of strings. + +BEG and END must be executable elisp symbols moving (point). Everything +in between will be killed. If INS is non-nil, it will be inserted then." + (interactive) + (let ((B nil)) + (funcall beg) + (setq B (point)) + (funcall end) + (kill-region B (point)) + (when ins + (insert ins)))) + +;; define some custom change-inner's based on mcyt mode +(when (fboundp 'mcyt-beginning-of-comment-block) + (defun tvd-ci-comment () + "\"change inner\" a whole comment [block]." + (interactive) + (tvd-ci 'mcyt-beginning-of-comment-block + 'mcyt-end-of-comment-block + (format "%s;# " comment-start))) + + (defun tvd-ci-quote () + "\"change inner\" quoted text." + (interactive) + (tvd-ci 'mcyt-beginning-of-quote + 'mcyt-end-of-quote)) + + (defun tvd-ci-word () + "\"change inner\" a word (like cw in vi)." + (interactive) + (tvd-ci 'mcyt-beginning-of-symbol + 'mcyt-end-of-symbol))) + +;; some more +(defun tvd-ci-line () + "\"change inner\" a whole line." + (interactive) + (tvd-ci 'beginning-of-line + 'end-of-line)) + +(defun tvd-ci-paragraph () + "\"change inner\" a whole paragraph." + (interactive) + (tvd-ci 'backward-paragraph + 'forward-paragraph)) + +(defun tvd-ci-buffer () + "\"change inner\" a whole buffer." + (interactive) + (tvd-ci 'point-min + 'point-max)) + +(defun tvd-ci-sexp () + "\"change inner\" a whole sexp." + (interactive) + (er/mark-inside-pairs) + (call-interactively 'kill-region)) + +;; [[https://github.com/magnars/change-inner.el][github source]]: +(use-package change-inner + :config + + ;; Define ALT_R (AltGR) + i as my prefix command for change-inner stuff. + ;; Since I use a german keyboard, this translates to →. + ;; I'll refrence it here now as + (define-prefix-command 'ci-map) + (global-set-key (kbd "→") 'ci-map) + + ;; typing the prefix key twice calls the real change-inner + (define-key ci-map (kbd "→") 'change-inner) ;; + + (when (fboundp 'mcyt-beginning-of-comment-block) + (define-key ci-map (kbd "c") 'tvd-ci-comment) ;; + (define-key ci-map (kbd "¢") 'tvd-ci-comment) ;; + + (define-key ci-map (kbd "q") 'tvd-ci-quote) ;; + (define-key ci-map (kbd "@") 'tvd-ci-quote) ;; + + (define-key ci-map (kbd "w") 'tvd-ci-word) ;; + (define-key ci-map (kbd "ł") 'tvd-ci-word)) ;; + + (define-key ci-map (kbd "l") 'tvd-ci-line) ;; + + (define-key ci-map (kbd "s") 'tvd-ci-sexp) ;; + (define-key ci-map (kbd "ſ") 'tvd-ci-sexp) ;; + + (define-key ci-map (kbd "p") 'tvd-ci-paragraph) ;; + (define-key ci-map (kbd "þ") 'tvd-ci-paragraph) ;; + + (define-key ci-map (kbd "a") 'tvd-ci-buffer) ;; + (define-key ci-map (kbd "æ") 'tvd-ci-buffer)) ;; + +;; -------------------------------------------------------------------------------- +;; *** Rotate text + +;; This one is great as well, I use it to toggle flags and such stuff +;; in configs or code with just one key binding. + +;; Source: [[http://nschum.de/src/emacs/rotate-text/][nschum.de]] + +;; (autoload 'rotate-text "rotate-text" nil t) +;; (autoload 'rotate-text-backward "rotate-text" nil t) + +(use-package rotate-text + :ensure nil ;; installed by el-get + :config + + ;; my toggle list + (setq rotate-text-words '(("width" "height") + ("left" "right" "top" "bottom") + ("ja" "nein") + ("off" "on") + ("true" "false") + ("nil" "t") + ("yes" "no"))) + + ;; C-t normally used by transpose-chars, so, unbind it first + (global-unset-key (kbd "C-t")) + + ;; however, we cannot re-bind it globally since then it could not be + ;; used in org-mode for org-todo (see below) FIXME: I only use the "t" + ;; short command anymore, so C-t would be free now, wouldn't it? + (add-something-to-mode-hooks + '(c c++ cperl vala web emacs-lisp python ruby) + '(lambda () + (local-set-key (kbd "C-t") 'rotate-text)))) + +;; -------------------------------------------------------------------------------- + +;; *** Word wrapping +;; same as word-wrap but without the fringe which I hate the most! +(add-something-to-mode-hooks '(tex text eww) 'visual-line-mode) + +;; however, it's required when coding, so enable it globally +;; overwritten by visual-line-mode above for specifics +(setq word-wrap t) +;; -------------------------------------------------------------------------------- + +;; *** Viking Mode + +;; Delete stuff fast. Press the key multiple times - delete more +;; things. Inspired by expand-region. Written by myself. + +(use-package viking-mode + :ensure nil ;; installed by el-get + :config + (viking-global-mode) + (setq viking-greedy-kill nil) + (define-key viking-mode-map (kbd "M-d") 'viking-repeat-last-kill)) +;; -------------------------------------------------------------------------------- + +;; *** HTMLize + +;; extracted from debian package emacs-goodies-el-35.2+nmu1, since +;; there's no other source left. Generates a fontified html version of +;; the current buffer, however it looks. + +(use-package htmlize + :config + (setq htmlize-output-type "inline-css")) + + +;; *** iEdit (inline edit multiple searches) + +;; Edit all occurences of something at once. Great for re-factoring. + +;; (global-set-key (kbd "C-c C-e") 'iedit-mode) +(setq tvd-buffer-undo-list nil) + +(use-package iedit + :config + + ;; Keep buffer-undo-list as is while iedit is active, that is, as long + ;; as I am inside iedit I can undo/redo current occurences. However, + ;; if I leave iedit and issue the undo command, ALL changes made with + ;; iedit are undone, whereas the default behaviour would be to go + ;; through every change made iside iedit, which I hate. + + ;; iedit doesn't provide a customizable flag to configure it's undo + ;; behavior, so, I modify it myself using defadvice. + + (advice-add 'iedit-mode :before '(lambda (&rest args) ;; save current + (setq tvd-buffer-undo-list buffer-undo-list))) + + (advice-add 'iedit-mode :after '(lambda (&rest args) ;; restore previously saved + (setq buffer-undo-list tvd-buffer-undo-list)))) diff --git a/conf-lisp/textscale.el b/conf-lisp/textscale.el new file mode 100644 index 0000000..3ac229d --- /dev/null +++ b/conf-lisp/textscale.el @@ -0,0 +1,21 @@ +;;; ** increase fontsize with ctrl-+ and ctrl-- + +;; I use those bindings everywhere (firefox, terminal, etc), and in +;; emacs as well. +;; using https://github.com/purcell/default-text-scale +(use-package default-text-scale + :config + (defun tvd-global-font-size-bigger () + "Make font size larger." + (interactive) + ;; (text-scale-increase 0.5) + (default-text-scale-increase)) + + (defun tvd-global-font-size-smaller () + "Change font size back to original." + (interactive) + ;; (text-scale-increase -0.5) + (default-text-scale-decrease)) + + (global-set-key (kbd "C-+") 'tvd-global-font-size-bigger) + (global-set-key (kbd "C--") 'tvd-global-font-size-smaller)) diff --git a/conf-lisp/tramp.el b/conf-lisp/tramp.el new file mode 100644 index 0000000..b5a2ee4 --- /dev/null +++ b/conf-lisp/tramp.el @@ -0,0 +1,13 @@ +;; *** tramp mode + +;; Edit remote files, one of the best things in emacs. I use it every day heavily. + +;; Sample: C-x-f /$host:/$file ($host as of .ssh/config or direct, $file including completion) + +;; doku: [[http://www.gnu.org/software/tramp/][gnu.org]] +(setq tramp-default-method "ssh" + tramp-default-user nil + tramp-verbose 1 + ido-enable-tramp-completion t) + +;; see also backup section in system.el diff --git a/conf-lisp/ui.el b/conf-lisp/ui.el new file mode 100644 index 0000000..3b07c6d --- /dev/null +++ b/conf-lisp/ui.el @@ -0,0 +1,173 @@ +;;; *** highlight todo keywords (such as FIXME) + +;; Absolutely needed! + +(use-package fic-mode + :config + (add-something-to-mode-hooks '(c c++ cperl vala web emacs-lisp ruby python yaml) 'turn-on-fic-mode)) + + +;;; *** UNDO Tree Mode + +;; Better undo, with redo support. + +;; C-_ (`undo-tree-undo') +;; Undo changes. +;; +;; C-: (`undo-tree-redo') +;; Redo changes. +;; +;; more: see undo-tree.el +(use-package undo-tree + :config + + ;; use always + (global-undo-tree-mode) + + ;; M-_ catched by Xmonad + (global-set-key (kbd "C-:") 'undo-tree-redo)) ; C-: == REDO C-_ == UNDO + + + +;;; *** Smarter M-x Mode (smex) + +;; This is really cool and I don't know how I could ever live without it. +(use-package smex + :config + (smex-initialize) + (global-set-key (kbd "M-x") 'smex) + (global-set-key (kbd "M-X") 'smex-major-mode-commands)) + + + +;;; *** Smarter Search + +;; test, replace isearch-forward-regexp first only. +;; dir: ivy/ +(use-package swiper + :config + (setq ivy-wrap t) + (global-set-key "\C-s" 'swiper)) + + + +;;; *** Which Func +;; display current function - if any - in mode line +(add-something-to-mode-hooks + '(c c++ cperl vala makefile ruby shell-script python go) + 'which-func-mode) + + + +;;; *** Show current-line in the Fringe +(use-package fringe-current-line + :config + (global-fringe-current-line-mode 1) + + ;; also change the color (matching the mode line + ;; (set-face-attribute 'fringe nil :foreground "NavyBlue") + ) + + + +;;; *** Save cursor position + +;; So the next time I start emacs and open a file I were editing +;; previously, (point) will be in the exact places where it was +;; before. +(save-place-mode 1) + + + +;;; *** Hightligt TABs + +;; not a mode, but however: higlight TABs in certain modes + +(defface extra-whitespace-face + '((t (:background "pale green"))) + "Used for tabs and such.") + +(defvar tvd-extra-keywords + '(("\t" . 'extra-whitespace-face))) + +(add-something-to-mode-hooks '(c c++ vala cperl emacs-lisp python shell-script ruby) + (lambda () (font-lock-add-keywords nil tvd-extra-keywords))) + + +;;; *** Browse kill-ring + +;; when active use n and p to browse, to select, it's the same +;; as and I never really use it... + +(use-package browse-kill-ring + :config + (setq browse-kill-ring-highlight-current-entry t + browse-kill-ring-highlight-inserted-item t)) + + +;;; *** goto-last-change + +;; Very handy, jump to last change[s]. + +(use-package goto-last-change + :config + (global-set-key (kbd "C-b") 'goto-last-change)) + + + +;;; *** Bookmarks + +;; I use the builtin bookmark feature quite a lot and am happy with +;; it. Especially at work, where many files are located in large +;; path's on remote storage systems, it great to jump quickly to such +;; places. + +;; everytime bookmark is changed, automatically save it +(setq bookmark-save-flag 1 + bookmark-version-control t) + +;; I use the same aliases as in apparix for bash (since I'm used to them) +(defalias 'to 'bookmark-jump) +(defalias 'bm 'bookmark-set) +(defalias 'bl 'bookmark-bmenu-list) + + + +;;; *** which-key + +;; One of the best unobstrusive modes for key help ever. Just start +;; entering a key chord, prefix or whatever, and it pops a small +;; buffer (on the right side in my case) showing the avialable keys to +;; press from there along with the associated functions. + +(use-package which-key + :config + (which-key-mode) + (which-key-setup-side-window-right)) + + + +;;; *** Beacon mode (pointer blink) +;; Source: [[https://github.com/Malabarba/beacon][beacon mode]] + +;; Blink the cursor shortly when moving across large text sections or +;; when changing windows. That way it is easier to find the current +;; editing position. + +(use-package beacon + :config + + (setq beacon-blink-duration 0.1 + beacon-blink-when-point-moves-vertically 10 + beacon-color 0.3) + + (add-hook 'beacon-dont-blink-predicates + (lambda () (bound-and-true-p novel-mode))) + + (beacon-mode)) + + + +;;; other aliases +;; show available colors: +(defalias 'colors 'list-colors-display) diff --git a/conf-lisp/webmode.el b/conf-lisp/webmode.el new file mode 100644 index 0000000..68457a5 --- /dev/null +++ b/conf-lisp/webmode.el @@ -0,0 +1,57 @@ +;; *** web-mode (JS, HTML, CSS combined) + +;; Web development is shit. Tech involved is a mess, and in most cases +;; intermixed. web-mode provides a great fix for this: it handles +;; HTML, CSS and Javascript in the same buffer very well. + +;; See: [[http://web-mode.org/][web-mode.org]] + +(use-package web-mode + :mode "\\.html\\'" + :mode "\\.tpl\\'" + :mode "\\.php\\'" + :mode "\\.sp\\'" + :mode "\\.erb\\'" + :mode "\\.mustache\\'" + :mode "\\.js\\'" + + :config + (setq web-mode-markup-indent-offset 2) + (setq web-mode-css-indent-offset 2) + (setq web-mode-code-indent-offset 2) + (setq web-mode-style-padding 1) + (setq web-mode-script-padding 1) + (setq web-mode-block-padding 0) + (setq web-mode-enable-auto-pairing t) + (setq web-mode-enable-auto-expanding t) + + ;; some handy html code inserters + (defun html-insert-p() + (interactive) + (web-mode-element-wrap "p")) + + (defun html-insert-li() + (interactive) + (web-mode-element-wrap "li")) + + (defun html-insert-ul() + (interactive) + (web-mode-element-wrap "ul")) + + (defun html-insert-b() + (interactive) + (web-mode-element-wrap "b")) + + ;; convert a text list into a html list. + (defun html-listify (beg end) + (interactive "r") + (save-excursion + (let* ((lines (split-string (buffer-substring beg end) "\n" t))) + (delete-region beg end) + (insert "
          \n") + (while lines + (insert "
        • ") + (insert (pop lines)) + (insert "
        • \n")) + (insert "
        \n")))) + ) diff --git a/conf-lisp/windowmgmt.el b/conf-lisp/windowmgmt.el new file mode 100644 index 0000000..e7c1610 --- /dev/null +++ b/conf-lisp/windowmgmt.el @@ -0,0 +1,215 @@ +;; NOTDONE +;;; ** WINDOW management stuff +;; *** resize windows by keyboard + +;; Very practical: resize windows easily. + +;; hit C-c C-r then use cursor keys to resize, to finish +(use-package windresize + :config + (global-set-key (kbd "C-c C-r") 'windresize)) + +;; *** switch windows with MS-WINDOWS key +(use-package windmove + :ensure nil + :config + (windmove-default-keybindings 'super) + (setq windmove-wrap-around t)) + +;; *** M-o switch window or buffer + +;; The key M-o has different functions depending on context: +;; +;; If there's only 1 window open, switch to the last active. +;; +;; If there are 2 windows open, switch back and forth between the +;; two. In order to flip them, Use M-O (that is: ALT+shift+o). +;; +;; And if there are more than 2 windows open, call the hydra, which +;; allows to switch to another window using the arrow keys. The hydra +;; stays for 1 second unles an arrow key has been pressed. So, I can +;; press multiple arrow keys in a row as long as I'm fast enough +;; between key presses. If I stop,the hydra disappears and I end up +;; whereever I was last. +;; +;; Also, within the hydra 'o' jumps to the last active window and +;; 'f' flips all windows. + +;; from https://github.com/lukhas/buffer-move +(use-package buffer-move) + +(defun tvd-previous-window (&optional ignore) + "Toggle between the last two selected windows." + (interactive) + (let ((win (get-mru-window t t t))) + (unless win (error "Last window not found.")) + (select-window win))) + +;; via +;; [[http://whattheemacsd.com/buffer-defuns.el-02.html][whattheemacs.d]]: +;; exchange left with right buffer (or up and down), love it. +(defun tvd-flip-windows () + "Rotate your windows" + (interactive) + (cond ((not (> (count-windows)1)) + (message "You can't rotate a single window!")) + (t + (setq i 1) + (setq numWindows (count-windows)) + (while (< i numWindows) + (let* ( + (w1 (elt (window-list) i)) + (w2 (elt (window-list) (+ (% i numWindows) 1))) + (b1 (window-buffer w1)) + (b2 (window-buffer w2)) + (s1 (window-start w1)) + (s2 (window-start w2)) + ) + (set-window-buffer w1 b2) + (set-window-buffer w2 b1) + (set-window-start w1 s2) + (set-window-start w2 s1) + (setq i (1+ i))))))) + +(when (and (fboundp 'windmove-up) (fboundp 'buf-move-up) (fboundp 'defhydra)) + (defhydra hydra-switch-windows (:color pink: :timeout 2.5) + " +Switch to buffer: ← ↑ → ↓ | _o_: previous | _f_: flip | MOVE: _u_: up _d_: down _l_: left _r_: right" + ("" windmove-up nil) + ("" windmove-down nil) + ("" windmove-left nil) + ("" windmove-right nil) + ("o" tvd-previous-window nil :color blue) + ("f" tvd-flip-windows nil :color blue) + ("u" buf-move-up nil :color blue) + ("d" buf-move-down nil :color blue) + ("l" buf-move-left nil :color blue) + ("r" buf-move-right nil :color blue) + ("q" nil nil :color red)) + + ;; via [[http://mbork.pl/2017-02-26_other-window-or-switch-buffer][mbork]] + ;; modified to call the above hydra if there are more than 2 windows + (defun other-window-or-switch-buffer () + "Call `other-window' if more than one window is visible, switch +to next buffer otherwise." + (interactive) + (if (one-window-p) + (switch-to-buffer nil) + (progn + (if (= (length (window-list)) 2) + (other-window 1) + (hydra-switch-windows/body))))) + + (global-set-key (kbd "M-o") 'other-window-or-switch-buffer) + + ;; M-o doesn't work when using emacs via Win->RDP->VNC->X11->Xmonad, + ;; so fall back to C-o. + (global-set-key (kbd "C-o") 'other-window-or-switch-buffer) + + ;; Use only in X11 emacs - setting M-O inside console causes and + ;; to stop working properly, for whatever reasons. + (if (display-graphic-p) + (global-set-key (kbd "M-O") 'tvd-flip-windows))) + +;; -------------------------------------------------------------------------------- +;; *** Split window to 4 parts + +(defun tvd-quarter-windows () + (interactive) + (split-window-vertically) + (split-window-horizontally) + (windmove-down) + (split-window-horizontally)) + +(global-set-key (kbd "C-x 4") 'tvd-quarter-windows) + +;; -------------------------------------------------------------------------------- + +;; *** Remember and Restore Window Configurations - winner mode + +(winner-mode 1) + +;; keybindings: C-c left - winner-undo +;; keybindings: C-c right - winner-redo + + +;; *** Window Hydra + +;; brightness wrappers +(defun tvd-bg-brighter () + (interactive) + (doremi-increment-background-color-1 ?v -1)) + +(defun tvd-bg-darker () + (interactive) + (doremi-increment-background-color-1 ?v 1)) + +(defun tvd-pre-resize () + "Called as pre execute hook py hydra-windows-resize/body and +executes the called key once, so that no key press gets lost from +hydra-windows (a,s,d,w)" + (interactive) + (let + ((key (car (reverse (append (recent-keys) nil))))) + (cond + ((eq key ?a) + (shrink-window-horizontally 1)) + ((eq key ?d) + (enlarge-window-horizontally 1)) + ((eq key ?w) + (shrink-window 1)) + ((eq key ?s) + (enlarge-window 1))))) + +(when (fboundp 'defhydra) + (defhydra hydra-windows-resize (:color pink :pre (tvd-pre-resize)) + ;; small sub hydra for window resizing, it leaves as much room for + ;; windows as possible + " +_a_ || _d_ |---| _w_ --- _s_ =" + ("a" shrink-window-horizontally nil) + ("d" enlarge-window-horizontally nil) + ("w" shrink-window nil) + ("s" enlarge-window nil) + ("q" nil nil :color red)) + + (defhydra hydra-windows (:color blue) + " + +^Window Management^ +^^------------------------------------------------------------------------ +_+_ Increase Font | _-_ Decrease Font Resize ^ ^ _w_ ^ ^ +_f_: Flip Windows ^^ Current _a_ ^ ^ _d_ +_4_: Quarter Windows ^^ Window: ^ ^ _s_ ^ ^ +_u_: Windows Undo +_r_: Windows Redo ^^ _l_: Adjust Background brighter +_i_: Invert Colors ^^ _b_: Adjust Background darker + +_h_: Toggle Highlight Line Mode ^^ _e_: Eyebrowse Workspaces (C-x C-x) +_n_: Toogle Line Number Mode + +^^------------------------------------------------------------------------ +Reach this hydra with +^^------------------------------------------------------------------------ + +" + ("+" tvd-global-font-size-bigger nil :color pink) + ("-" tvd-global-font-size-smaller nil :color pink) + ("f" tvd-flip-windows nil) + ("4" tvd-quarter-windows nil) + ("u" winner-undo nil) + ("r" winner-redo nil) + ("i" tvd-invert nil) + ("b" tvd-bg-darker nil :color pink) + ("l" tvd-bg-brighter nil :color pink) + ("a" hydra-windows-resize/body nil) + ("d" hydra-windows-resize/body nil) + ("w" hydra-windows-resize/body nil) + ("s" hydra-windows-resize/body nil) + ("e" hydra-eyebrowse/body nil) + ("h" hl-line-mode nil) + ("n" linum-mode nil) + ("q" nil nil :color red)) + + (global-set-key (kbd "C-x w") 'hydra-windows/body)) + diff --git a/conf-lisp/workspaces.el b/conf-lisp/workspaces.el new file mode 100644 index 0000000..82c10ef --- /dev/null +++ b/conf-lisp/workspaces.el @@ -0,0 +1,68 @@ +;; *** Eyebrowse Workspaces +;; workspace configuration, like desktops. Seems to be a good implementation, w/o save though + + +(use-package eyebrowse + :init + ;; "prefix key" has to be set before loading, keep in mind, that + ;; if you change it here, you need to change it below as well! + (setq eyebrowse-keymap-prefix (kbd "C-x C-x")) + (global-unset-key (kbd "C-x C-x")) + + :config + + (defun tvd-new-eyebrowse-workspace () + "Create new scratch buffer and ask for a name" + (interactive) + (eyebrowse-rename-window-config (eyebrowse--get 'current-slot) (read-string "Workspace: ")) + (autoscratch-buffer)) + + ;; always enable + (eyebrowse-mode t) + + (setq eyebrowse-new-workspace 'tvd-new-eyebrowse-workspace + eyebrowse-switch-back-and-forth t + eyebrowse-wrap-around t + eyebrowse-mode-line-style t + eyebrowse-slot-format "%s:init") + + ;; add a hydra, just in case, it contains hydra commands and hints + ;; about the actual key bindings, it's also being refered from + ;; hydra-window/body with "e" + (when (fboundp 'defhydra) + (defhydra hydra-eyebrowse (:color blue) + " +^Eyebrowse Workspace Management^ +^^-------------------------------------- +_l_: last window (C-x C-x C-x) +_n_: next window (C-x C-x ) +_p_: prev window (C-x C-x ) +_x_: close workspace (C-x C-x q) +_t_: rename workspace (C-x C-x t) +_c_: create workspace (C-x C-x n) + +Use C-x C-x to access eyebrowse directly. +" + ("l" eyebrowse-last-window-config nil) + ("n" eyebrowse-next-window-config nil) + ("p" eyebrowse-prev-window-config nil) + ("x" eyebrowse-close-window-config nil) + ("t" eyebrowse-rename-window-config nil) + ("c" eyebrowse-create-window-config nil) + ("q" nil nil :color red))) + + ;;Modifying the eyebrowse keymap directly doesn't work because it's + ;; not setup correctly. I sent a pull request to fix this: + ;; https://github.com/wasamasa/eyebrowse/pull/94, however, vaslilly choosed + ;; not to accept it. So, I need to configure the whole chords for every + ;; function I use AND set the "prefix key" using the weird way above + ;; (before loading). + (global-set-key (kbd "C-x C-x C-x") 'eyebrowse-last-window-config) + (global-set-key (kbd "C-x C-x ") 'eyebrowse-next-window-config) + (global-set-key (kbd "C-x C-x ") 'eyebrowse-prev-window-config) + (global-set-key (kbd "C-x C-x q") 'eyebrowse-close-window-config) + (global-set-key (kbd "C-x C-x t") 'eyebrowse-rename-window-config) + (global-set-key (kbd "C-x C-x n") 'eyebrowse-create-window-config) + (global-set-key (kbd "C-x C-x ?") 'hydra-eyebrowse/body)) + +;; There's also some face config, see defcustom at end of file! diff --git a/conf-lisp/xmodmap.el b/conf-lisp/xmodmap.el new file mode 100644 index 0000000..5b0ddb1 --- /dev/null +++ b/conf-lisp/xmodmap.el @@ -0,0 +1,11 @@ +;; *** Xmodmap Mode + +;; the shortest mode ever, [[https://www.emacswiki.org/emacs/XModMapMode][via emacswiki]]. + +(define-generic-mode 'xmodmap-mode + '(?!) + '("add" "clear" "keycode" "keysym" "pointer" "remove") + '(("[0-9]+" . 'font-lock-variable-name-face)) + '("[xX]modmap\\(rc\\)?\\'") + nil + "Simple mode for xmodmap files.") diff --git a/conf-lisp/yaml.el b/conf-lisp/yaml.el new file mode 100644 index 0000000..b48672f --- /dev/null +++ b/conf-lisp/yaml.el @@ -0,0 +1,71 @@ +;; *** Yaml Mode + +(use-package yaml-mode + :mode "\\.yml\\'" + :mode "\\.yaml\\'" + :mode "\\.j2\\'" + + :config + (defun yaml-point-in-comment-p () + "Test if character at cursor is a comment." + (interactive) + (save-excursion + (right-char) ; visible cursor position needed + (nth 4 (syntax-ppss)))) + + (defun yaml-goto-beginning() + "Move cursor to beginning of yaml key on current line" + (interactive) + (beginning-of-line) + (skip-chars-forward " ")) + + (defun yaml-next-block() + "Jump to the next yaml block with the same indent as the current one" + (interactive) + (yaml-goto-beginning) + (next-line) + (while (or (looking-at " ") (yaml-point-in-comment-p)) + (next-line)) + (yaml-goto-beginning)) + + (defun yaml-prev-block() + "Jump to the previous yaml block with the same indent as the current one" + (interactive) + (yaml-goto-beginning) + (previous-line) + (while (or (looking-at " ") (yaml-point-in-comment-p)) + (previous-line)) + (yaml-goto-beginning)) + + (defun yaml-level-down() + "Jump down to the next yaml child block" + (interactive) + (yaml-goto-beginning) + (next-line) + (while (or (not (looking-at " ")) (yaml-point-in-comment-p)) + (next-line)) + (skip-chars-forward " ")) + + (defun yaml-level-up() + "Jump up to the next yaml parent block" + (interactive) + (yaml-goto-beginning) + (left-char) + (previous-line) + (while (or (looking-at " ") (yaml-point-in-comment-p)) + (previous-line)) + (yaml-goto-beginning)) + + (define-key yaml-mode-map "\C-m" 'newline-and-indent) + + ;; works, but then cannot be used for re-indenting :( + ;; (outline-minor-mode) + ;; (define-key yaml-mode-map (kbd "TAB") 'outline-toggle-children) + ;; (setq outline-regexp "^ *\\([A-Za-z0-9_-]*: *[>|]?$\\|-\\b\\)") + (define-key smartparens-mode-map (kbd "") nil) + (define-key smartparens-mode-map (kbd "") nil) + + (define-key yaml-mode-map (kbd "") 'yaml-next-block) + (define-key yaml-mode-map (kbd "") 'yaml-prev-block) + (define-key yaml-mode-map (kbd "") 'yaml-level-down) + (define-key yaml-mode-map (kbd "") 'yaml-level-up)) diff --git a/init.el b/init.el new file mode 100644 index 0000000..dd0c898 --- /dev/null +++ b/init.el @@ -0,0 +1,157 @@ +;; ** .emacs config version + +;; My emacs config has a version (consisting of a timestamp with a +;; serial), which I display in the mode line. So I can clearly see, if +;; I'm using an outdated config somewhere. +(defvar tvd-emacs-version "20230412.01") + +;; from purcell's config +(defun sanityinc/add-subdirs-to-load-path (parent-dir) + "Add every non-hidden subdir of PARENT-DIR to `load-path'." + (let ((default-directory parent-dir)) + (setq load-path + (append + (cl-remove-if-not + #'file-directory-p + (directory-files (expand-file-name parent-dir) t "^[^\\.]")) + load-path)))) + + +;;; setup loading of init files, this is our base directory: ~/.emacs-init.d/ +(setq tvd-config-dir (expand-file-name "~/.emacs.d")) +(setq user-emacs-directory tvd-config-dir) + +;;; ~/.emacs-init.d/init/ contains the rest of the init files +(setq tvd-init-dir (expand-file-name "init" tvd-config-dir)) + +;;; initialize package manager +(require 'package) + +;;; Install into separate package dirs for each Emacs version, to prevent bytecode incompatibility +(setq package-user-dir + (expand-file-name (format "elpa-%s.%s" emacs-major-version emacs-minor-version) + tvd-config-dir)) + +(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/")) +(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) + +(package-initialize) + +;; load'em +(sanityinc/add-subdirs-to-load-path package-user-dir) + +;;; dont mess around +(setq package-enable-at-startup nil) + +;;; setup use-package +(unless (package-installed-p 'use-package) + ;; (package-refresh-contents) + (package-install 'use-package)) +(eval-and-compile + (setq use-package-always-ensure t + use-package-expand-minimally t)) + + + +;;; iterate over init dir and load all configs +(defun tvd-load-init-file (f) + (load-file f)) +(mapc 'tvd-load-init-file (directory-files (expand-file-name "init" tvd-config-dir) t ".*el")) + + +;;; ** Some globals +;; no comment margins +(setq-default comment-column 0) + +;; indent defaults, also look for indentation.el +(setq-default indent-tabs-mode nil) +(setq-default tab-width 4) + + + + + +;; ** mode-line setup (must be the last mode) + +;; I just append the current version of my emacs config and leave out +;; some stuff to keep the modeline short, so that everything can be +;; seen even if I have multiple windows open. + +;; smaller pos +(setq-default mode-line-position + '((-3 "%p") (size-indication-mode ("/" (-4 "%I"))) + " " + (line-number-mode + ("%l" (column-number-mode ":%c"))))) + +;; when macro recording is active, signal it with coloring instead of +;; just a character +(defface rec-face + '((t (:background "red" :foreground "white" :weight bold))) + "Flag macro recording in mode-line" + :group 'tvd-mode-line-faces) + +;; custom modeline +(setq-default mode-line-format + (list + "%e" + mode-line-front-space + mode-line-mule-info + mode-line-modified + mode-line-remote + " " + mode-line-buffer-identification + " " + mode-line-position + " (%m) " + + " [" tvd-emacs-version "] " + + ; added because of eyebrowse + mode-line-misc-info + + '(:eval (propertize + (if (eq defining-kbd-macro t) + "[REC]" + "") + 'face 'rec-face)) + + mode-line-end-spaces)) + + + + + +;; clean up modeline after loading everyting +(message "") + +;; FIXME: modeline emacs version not set and wrong color! + + +;;; ** END OF MANUAL CONFIG + +;; If I ever use custom-group to customize a mode, then I create a +;; manual config section for it using the values, custom has added +;; here. So, in normal times this should be empty, but needs to exist. + +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(package-selected-packages + '(beacon which-key goto-last-change browse-kill-ring fringe-current-line swiper smex undo-tree fic-mode cmake-mode yaml-mode windresize web-mode use-package tablist solarized-theme smartparens rust-mode projectile persistent-scratch org-bullets markdown-mode magit iedit ibuffer-vc ibuffer-tramp hydra htmlize highlight-indentation go-mode eyebrowse elmacro dumb-jump dired-ranger dired-k dired-filter default-text-scale change-inner buffer-move)) + '(safe-local-variable-values '((ruby-indent-level 4)))) + +;; ** done + +;; Finally, this message is being displayed. If this isn't the case I +;; know easily that something went wrong. + +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) + diff --git a/init/00-display.el b/init/00-display.el new file mode 120000 index 0000000..7cd16db --- /dev/null +++ b/init/00-display.el @@ -0,0 +1 @@ +../conf-lisp/display.el \ No newline at end of file diff --git a/init/01-elget.el b/init/01-elget.el new file mode 120000 index 0000000..89c9f3a --- /dev/null +++ b/init/01-elget.el @@ -0,0 +1 @@ +../conf-lisp/elget.el \ No newline at end of file diff --git a/init/02-system.el b/init/02-system.el new file mode 120000 index 0000000..66e36f3 --- /dev/null +++ b/init/02-system.el @@ -0,0 +1 @@ +../conf-lisp/system.el \ No newline at end of file diff --git a/init/03-windowmgmt.el b/init/03-windowmgmt.el new file mode 120000 index 0000000..a7732e0 --- /dev/null +++ b/init/03-windowmgmt.el @@ -0,0 +1 @@ +../conf-lisp/windowmgmt.el \ No newline at end of file diff --git a/init/04-imenu.el b/init/04-imenu.el new file mode 120000 index 0000000..a47bd5d --- /dev/null +++ b/init/04-imenu.el @@ -0,0 +1 @@ +../conf-lisp/imenu.el \ No newline at end of file diff --git a/init/05-scratch.el b/init/05-scratch.el new file mode 120000 index 0000000..4d6efe5 --- /dev/null +++ b/init/05-scratch.el @@ -0,0 +1 @@ +../conf-lisp/autoscratch.el \ No newline at end of file diff --git a/init/06-globalbindings.el b/init/06-globalbindings.el new file mode 120000 index 0000000..68f5a89 --- /dev/null +++ b/init/06-globalbindings.el @@ -0,0 +1 @@ +../conf-lisp/globalbindings.el \ No newline at end of file diff --git a/init/07-textscale.el b/init/07-textscale.el new file mode 120000 index 0000000..7de8d98 --- /dev/null +++ b/init/07-textscale.el @@ -0,0 +1 @@ +../conf-lisp/textscale.el \ No newline at end of file diff --git a/init/08-hydra.el b/init/08-hydra.el new file mode 120000 index 0000000..e97d529 --- /dev/null +++ b/init/08-hydra.el @@ -0,0 +1 @@ +../conf-lisp/hydra.el \ No newline at end of file diff --git a/init/09-productivity-functions.el b/init/09-productivity-functions.el new file mode 120000 index 0000000..95ae07f --- /dev/null +++ b/init/09-productivity-functions.el @@ -0,0 +1 @@ +../conf-lisp/functions.el \ No newline at end of file diff --git a/init/10-dumpjump.el b/init/10-dumpjump.el new file mode 120000 index 0000000..da79fc6 --- /dev/null +++ b/init/10-dumpjump.el @@ -0,0 +1 @@ +../conf-lisp/dumpjump.el \ No newline at end of file diff --git a/init/11-smartparens.el b/init/11-smartparens.el new file mode 120000 index 0000000..6893432 --- /dev/null +++ b/init/11-smartparens.el @@ -0,0 +1 @@ +../conf-lisp/smartparens.el \ No newline at end of file diff --git a/init/20-rust.el b/init/20-rust.el new file mode 120000 index 0000000..82a1583 --- /dev/null +++ b/init/20-rust.el @@ -0,0 +1 @@ +../conf-lisp/rust.el \ No newline at end of file diff --git a/init/21-shellscript.el b/init/21-shellscript.el new file mode 120000 index 0000000..0e619ae --- /dev/null +++ b/init/21-shellscript.el @@ -0,0 +1 @@ +../conf-lisp/shellscript.el \ No newline at end of file diff --git a/init/22-perl.el b/init/22-perl.el new file mode 120000 index 0000000..e597db1 --- /dev/null +++ b/init/22-perl.el @@ -0,0 +1 @@ +../conf-lisp/perl.el \ No newline at end of file diff --git a/init/23-go.el b/init/23-go.el new file mode 120000 index 0000000..ef72e9a --- /dev/null +++ b/init/23-go.el @@ -0,0 +1 @@ +../conf-lisp/go.el \ No newline at end of file diff --git a/init/24-sgml.el b/init/24-sgml.el new file mode 120000 index 0000000..ecd3265 --- /dev/null +++ b/init/24-sgml.el @@ -0,0 +1 @@ +../conf-lisp/sgml.el \ No newline at end of file diff --git a/init/25-webmode.el b/init/25-webmode.el new file mode 120000 index 0000000..91e26c9 --- /dev/null +++ b/init/25-webmode.el @@ -0,0 +1 @@ +../conf-lisp/webmode.el \ No newline at end of file diff --git a/init/26-cisco.el b/init/26-cisco.el new file mode 120000 index 0000000..0cc8052 --- /dev/null +++ b/init/26-cisco.el @@ -0,0 +1 @@ +../conf-lisp/cisco.el \ No newline at end of file diff --git a/init/27-markdown.el b/init/27-markdown.el new file mode 120000 index 0000000..9f4bab0 --- /dev/null +++ b/init/27-markdown.el @@ -0,0 +1 @@ +../conf-lisp/markdown.el \ No newline at end of file diff --git a/init/29-conf.el b/init/29-conf.el new file mode 120000 index 0000000..462bb69 --- /dev/null +++ b/init/29-conf.el @@ -0,0 +1 @@ +../conf-lisp/conf.el \ No newline at end of file diff --git a/init/30-config-general.el b/init/30-config-general.el new file mode 120000 index 0000000..8474e5a --- /dev/null +++ b/init/30-config-general.el @@ -0,0 +1 @@ +../conf-lisp/config-general.el \ No newline at end of file diff --git a/init/31-xmodmap.el b/init/31-xmodmap.el new file mode 120000 index 0000000..e7728d9 --- /dev/null +++ b/init/31-xmodmap.el @@ -0,0 +1 @@ +../conf-lisp/xmodmap.el \ No newline at end of file diff --git a/init/32-yaml.el b/init/32-yaml.el new file mode 120000 index 0000000..7290163 --- /dev/null +++ b/init/32-yaml.el @@ -0,0 +1 @@ +../conf-lisp/yaml.el \ No newline at end of file diff --git a/init/40-textmanipulation.el b/init/40-textmanipulation.el new file mode 120000 index 0000000..28192e4 --- /dev/null +++ b/init/40-textmanipulation.el @@ -0,0 +1 @@ +../conf-lisp/textmanipulation.el \ No newline at end of file diff --git a/init/41-eshell.el b/init/41-eshell.el new file mode 120000 index 0000000..7d466e5 --- /dev/null +++ b/init/41-eshell.el @@ -0,0 +1 @@ +../conf-lisp/eshell.el \ No newline at end of file diff --git a/init/41-pod.el b/init/41-pod.el new file mode 120000 index 0000000..9a67bdd --- /dev/null +++ b/init/41-pod.el @@ -0,0 +1 @@ +../conf-lisp/pod.el \ No newline at end of file diff --git a/init/42-elisp.el b/init/42-elisp.el new file mode 120000 index 0000000..6339ca0 --- /dev/null +++ b/init/42-elisp.el @@ -0,0 +1 @@ +../conf-lisp/elisp.el \ No newline at end of file diff --git a/init/43-tramp.el b/init/43-tramp.el new file mode 120000 index 0000000..0a3e71b --- /dev/null +++ b/init/43-tramp.el @@ -0,0 +1 @@ +../conf-lisp/tramp.el \ No newline at end of file diff --git a/init/44-org.el b/init/44-org.el new file mode 120000 index 0000000..67fbed8 --- /dev/null +++ b/init/44-org.el @@ -0,0 +1 @@ +../conf-lisp/org.el \ No newline at end of file diff --git a/init/45-orgagenda.el b/init/45-orgagenda.el new file mode 120000 index 0000000..78e59f6 --- /dev/null +++ b/init/45-orgagenda.el @@ -0,0 +1 @@ +../conf-lisp/orgagenda.el \ No newline at end of file diff --git a/init/46-orgtable.el b/init/46-orgtable.el new file mode 120000 index 0000000..6d574f3 --- /dev/null +++ b/init/46-orgtable.el @@ -0,0 +1 @@ +../conf-lisp/orgtable.el \ No newline at end of file diff --git a/init/47-outline.el b/init/47-outline.el new file mode 120000 index 0000000..a3806c9 --- /dev/null +++ b/init/47-outline.el @@ -0,0 +1 @@ +../conf-lisp/outline.el \ No newline at end of file diff --git a/init/50-narrow.el b/init/50-narrow.el new file mode 120000 index 0000000..eb3285f --- /dev/null +++ b/init/50-narrow.el @@ -0,0 +1 @@ +../conf-lisp/narrow.el \ No newline at end of file diff --git a/init/51-ansiterm.el b/init/51-ansiterm.el new file mode 120000 index 0000000..ed5252b --- /dev/null +++ b/init/51-ansiterm.el @@ -0,0 +1 @@ +../conf-lisp/ansiterm.el \ No newline at end of file diff --git a/init/52-info.el b/init/52-info.el new file mode 120000 index 0000000..82531b3 --- /dev/null +++ b/init/52-info.el @@ -0,0 +1 @@ +../conf-lisp/info.el \ No newline at end of file diff --git a/init/53-novel.el b/init/53-novel.el new file mode 120000 index 0000000..09f4dc3 --- /dev/null +++ b/init/53-novel.el @@ -0,0 +1 @@ +../conf-lisp/novel.el \ No newline at end of file diff --git a/init/54-macros.el b/init/54-macros.el new file mode 120000 index 0000000..a271349 --- /dev/null +++ b/init/54-macros.el @@ -0,0 +1 @@ +../conf-lisp/macros.el \ No newline at end of file diff --git a/init/55-ewww.el b/init/55-ewww.el new file mode 120000 index 0000000..10898d4 --- /dev/null +++ b/init/55-ewww.el @@ -0,0 +1 @@ +../conf-lisp/ewww.el \ No newline at end of file diff --git a/init/56-tablist.el b/init/56-tablist.el new file mode 120000 index 0000000..3491775 --- /dev/null +++ b/init/56-tablist.el @@ -0,0 +1 @@ +../conf-lisp/tablist.el \ No newline at end of file diff --git a/init/57-help.el b/init/57-help.el new file mode 120000 index 0000000..21211d0 --- /dev/null +++ b/init/57-help.el @@ -0,0 +1 @@ +../conf-lisp/help.el \ No newline at end of file diff --git a/init/58-suggest.el b/init/58-suggest.el new file mode 120000 index 0000000..bc22c3a --- /dev/null +++ b/init/58-suggest.el @@ -0,0 +1 @@ +../conf-lisp/suggest.el \ No newline at end of file diff --git a/init/59-followcursor.el b/init/59-followcursor.el new file mode 120000 index 0000000..936a6f8 --- /dev/null +++ b/init/59-followcursor.el @@ -0,0 +1 @@ +../conf-lisp/followcursor.el \ No newline at end of file diff --git a/init/60-magit.el b/init/60-magit.el new file mode 120000 index 0000000..69becd0 --- /dev/null +++ b/init/60-magit.el @@ -0,0 +1 @@ +../conf-lisp/magit.el \ No newline at end of file diff --git a/init/61-dired.el b/init/61-dired.el new file mode 120000 index 0000000..8a4dee2 --- /dev/null +++ b/init/61-dired.el @@ -0,0 +1 @@ +../conf-lisp/dired.el \ No newline at end of file diff --git a/init/62-ediff.el b/init/62-ediff.el new file mode 120000 index 0000000..f8685ec --- /dev/null +++ b/init/62-ediff.el @@ -0,0 +1 @@ +../conf-lisp/ediff.el \ No newline at end of file diff --git a/init/63-projectile.el b/init/63-projectile.el new file mode 120000 index 0000000..5b1d47f --- /dev/null +++ b/init/63-projectile.el @@ -0,0 +1 @@ +../conf-lisp/projectile.el \ No newline at end of file diff --git a/init/64-occur.el b/init/64-occur.el new file mode 120000 index 0000000..a38089c --- /dev/null +++ b/init/64-occur.el @@ -0,0 +1 @@ +../conf-lisp/occur.el \ No newline at end of file diff --git a/init/65-windowmgmt.el b/init/65-windowmgmt.el new file mode 120000 index 0000000..a7732e0 --- /dev/null +++ b/init/65-windowmgmt.el @@ -0,0 +1 @@ +../conf-lisp/windowmgmt.el \ No newline at end of file diff --git a/init/66-workspaces.el b/init/66-workspaces.el new file mode 120000 index 0000000..cb3f6e6 --- /dev/null +++ b/init/66-workspaces.el @@ -0,0 +1 @@ +../conf-lisp/workspaces.el \ No newline at end of file diff --git a/init/67-indentation.el b/init/67-indentation.el new file mode 120000 index 0000000..7135bac --- /dev/null +++ b/init/67-indentation.el @@ -0,0 +1 @@ +../conf-lisp/indentation.el \ No newline at end of file diff --git a/init/68-completion.el b/init/68-completion.el new file mode 120000 index 0000000..d8a7a91 --- /dev/null +++ b/init/68-completion.el @@ -0,0 +1 @@ +../conf-lisp/completion.el \ No newline at end of file diff --git a/init/69-recentfiles.el b/init/69-recentfiles.el new file mode 120000 index 0000000..c884190 --- /dev/null +++ b/init/69-recentfiles.el @@ -0,0 +1 @@ +../conf-lisp/recentfiles.el \ No newline at end of file diff --git a/init/70-ibuffer.el b/init/70-ibuffer.el new file mode 120000 index 0000000..17f2401 --- /dev/null +++ b/init/70-ibuffer.el @@ -0,0 +1 @@ +../conf-lisp/ibuffer.el \ No newline at end of file diff --git a/init/71-printing.el b/init/71-printing.el new file mode 120000 index 0000000..bbbb973 --- /dev/null +++ b/init/71-printing.el @@ -0,0 +1 @@ +../conf-lisp/printing.el \ No newline at end of file diff --git a/init/72-ui.el b/init/72-ui.el new file mode 120000 index 0000000..6de904f --- /dev/null +++ b/init/72-ui.el @@ -0,0 +1 @@ +../conf-lisp/ui.el \ No newline at end of file diff --git a/tom-past-century-theme.el b/site-lisp/tom-past-century-theme.el similarity index 100% rename from tom-past-century-theme.el rename to site-lisp/tom-past-century-theme.el diff --git a/tvd-outshine-ido-jump.el b/tvd-outshine-ido-jump.el deleted file mode 100644 index bdd5a85..0000000 --- a/tvd-outshine-ido-jump.el +++ /dev/null @@ -1,71 +0,0 @@ -;; Generate an alist of all headings with each position in buffer and -;; use this later to jump to those positions with IDO. -(make-variable-buffer-local 'tvd-headings) - -(defun tvd-outshine-get-level (heading) - "Return level of HEADING as number, or nil" - (if (string-match " \\(*+\\) " heading) ; normal outline heading - (length (match-string 1 heading)) - (when (string-match "^;;\\(;+\\) " heading) ; else look for elisp heading - (length (match-string 1 heading))))) - -(defun tvd-outshine-cl-heading (heading) - (let ((regex (cadar outshine-imenu-preliminary-generic-expression))) - (when (string-match regex heading) - (match-string-no-properties 1 heading)))) - -(defun tvd-outshine-parse-headings () - "extract outshine headings of current buffer" - (interactive) - (let ((line nil)) - (save-excursion - (setq tvd-headings ()) - (beginning-of-buffer) - (while (not (eobp)) - (setq line (tvd-get-line)) - (when (outline-on-heading-p t) - (add-to-list 'tvd-headings (cons (tvd-outshine-cl-heading line) (point)))) - (forward-line))))) - -(defun tvd-outshine-sparse-tree () - "expand outline tree from current position as sparse tree" - (interactive) - (let ((done nil) - (pos (point)) - (tree (list (list (point) 5))) - (l 0)) - (while (not done) - (outline-up-heading 1) - (setq l (tvd-outshine-get-level (tvd-get-line))) - (add-to-list 'tree (list (point) l)) - (when (eq l 1) - (setq done t))) - (outline-hide-other) - (dolist (pos tree) - (goto-char (car pos)) - (outline-cycle)))) - -(defun tvd-outshine-jump () - "jump to an outshine heading with IDO prompt, -update heading list if neccessary." - (interactive) - (let ((heading nil)) - (when (or (not tvd-headings) - (buffer-modified-p)) - (tvd-outshine-parse-headings)) - (if (not tvd-headings) - (message "Current buffer doesn't contain any outshine headings!") - (setq heading (ido-completing-read "Jump to heading: " (tvd-alist-keys tvd-headings))) - (when heading - (show-all) - (goto-char (cdr (assoc heading tvd-headings))) - (tvd-outshine-sparse-tree))))) - -(eval-after-load "outline" - '(progn - (add-hook - 'outline-minor-mode-hook - (lambda () - (define-key outline-minor-mode-map (kbd "C-c C-j") 'tvd-outshine-jump))))) - -;; test