From 2ecb3887246484b3fbaca727d7ee79b78fcd81d1 Mon Sep 17 00:00:00 2001 From: Daniel Borchmann Date: Sun, 16 Jul 2017 18:07:00 +0200 Subject: [PATCH] Initial commit --- .gitignore | 30 + .gitmodules | 3 + abbrev_defs | 577 +++++++++ bbdb | 1 + bookmarks | 1 + custom.el | 1 + eshell/alias | 5 + exot-main-theme.el | 38 + gnus | 657 ++++++++++ init.el | 1657 +++++++++++++++++++++++++ network-security.data | 1 + private | 1 + site-lisp/db-emacsclient.el | 61 + site-lisp/db-org.el | 837 +++++++++++++ site-lisp/db-private.el | 1 + site-lisp/db-utils.el | 341 +++++ site-lisp/ical2org.el | 262 ++++ site-lisp/term/screen-256color.el | 7 + snippets/latex-mode/vorlage-gutachten | 53 + snippets/text-mode/.yas-parents | 1 + snippets/text-mode/horg | 5 + snippets/text-mode/sc | 5 + snippets/text-mode/worg | 5 + 23 files changed, 4550 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 abbrev_defs create mode 120000 bbdb create mode 120000 bookmarks create mode 120000 custom.el create mode 100644 eshell/alias create mode 100644 exot-main-theme.el create mode 100644 gnus create mode 100644 init.el create mode 120000 network-security.data create mode 160000 private create mode 100644 site-lisp/db-emacsclient.el create mode 100644 site-lisp/db-org.el create mode 120000 site-lisp/db-private.el create mode 100644 site-lisp/db-utils.el create mode 100644 site-lisp/ical2org.el create mode 100644 site-lisp/term/screen-256color.el create mode 100644 snippets/latex-mode/vorlage-gutachten create mode 100644 snippets/text-mode/.yas-parents create mode 100644 snippets/text-mode/horg create mode 100644 snippets/text-mode/sc create mode 100644 snippets/text-mode/worg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..543979e --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +/.cider-history +/.mc-lists.el +/.org-id-locations +/TAGS +/auto-save-list +/eautosave/ +/ebackup/ +/el-get/ +/elpa/ +/emms/ +/eshell/history +/eshell/lastdir +/image-dired/ +/org-clock-save.el +/projectile-bookmarks.eld +/recentf +/savehist +/semanticdb/ +/srecode-map.el +/tramp +/url/cookies +/org-clock-save.el~ +/gnus.registry.eioioi +/helm-adaptive-history +/url/ +/mastodon.plstore +/smex-items +/games/bubbles-default-2-10-10-scores +/games/tetris-scores +/mthesaur.txt.cache diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..655f43b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "private"] + path = private + url = documenter:Private/repositories/emacs-private.git diff --git a/abbrev_defs b/abbrev_defs new file mode 100644 index 0000000..f86d626 --- /dev/null +++ b/abbrev_defs @@ -0,0 +1,577 @@ +;;-*-coding: utf-8;-*- +(define-abbrev-table 'Buffer-menu-mode-abbrev-table '()) + +(define-abbrev-table 'Custom-mode-abbrev-table '()) + +(define-abbrev-table 'Info-edit-mode-abbrev-table '()) + +(define-abbrev-table 'Man-mode-abbrev-table '()) + +(define-abbrev-table 'Rd-mode-abbrev-table + '( + ("`ag" "\\arguments" nil 0) + ("`al" "\\alias" nil 0) + ("`au" "\\author" nil 0) + ("`bf" "\\bold" nil 0) + ("`co" "\\code" nil 0) + ("`de" "\\describe" nil 0) + ("`dn" "\\description" nil 0) + ("`dt" "\\details" nil 0) + ("`em" "\\emph" nil 0) + ("`en" "\\enumerate" nil 0) + ("`ex" "\\examples" nil 0) + ("`fi" "\\file" nil 0) + ("`fo" "\\format" nil 0) + ("`it" "\\item" nil 0) + ("`iz" "\\itemize" nil 0) + ("`kw" "\\keyword" nil 0) + ("`li" "\\link" nil 0) + ("`me" "\\method" nil 0) + ("`na" "\\name" nil 0) + ("`no" "\\note" nil 0) + ("`re" "\\references" nil 0) + ("`sa" "\\seealso" nil 0) + ("`se" "\\section" nil 0) + ("`so" "\\source" nil 0) + ("`ss" "\\subsection" nil 0) + ("`sy" "\\synopsis" nil 0) + ("`ta" "\\tabular" nil 0) + ("`ti" "\\title" nil 0) + ("`us" "\\usage" nil 0) + ("`va" "\\value" nil 0) + )) + +(define-abbrev-table 'TeX-error-overview-mode-abbrev-table '()) + +(define-abbrev-table 'TeX-output-mode-abbrev-table '()) + +(define-abbrev-table 'apropos-mode-abbrev-table '()) + +(define-abbrev-table 'awk-mode-abbrev-table '()) + +(define-abbrev-table 'bbdb-mode-abbrev-table '()) + +(define-abbrev-table 'biblio-selection-mode-abbrev-table '()) + +(define-abbrev-table 'bibtex-mode-abbrev-table '()) + +(define-abbrev-table 'bookmark-bmenu-mode-abbrev-table '()) + +(define-abbrev-table 'bookmark-edit-annotation-mode-abbrev-table '()) + +(define-abbrev-table 'bsh-script-mode-abbrev-table '()) + +(define-abbrev-table 'c++-mode-abbrev-table '()) + +(define-abbrev-table 'c-mode-abbrev-table '()) + +(define-abbrev-table 'calc-trail-mode-abbrev-table '()) + +(define-abbrev-table 'calendar-mode-abbrev-table '()) + +(define-abbrev-table 'change-log-mode-abbrev-table '()) + +(define-abbrev-table 'cider-browse-ns-mode-abbrev-table '()) + +(define-abbrev-table 'cider-connections-buffer-mode-abbrev-table '()) + +(define-abbrev-table 'cider-docview-mode-abbrev-table '()) + +(define-abbrev-table 'cider-inspector-mode-abbrev-table '()) + +(define-abbrev-table 'cider-repl-history-mode-abbrev-table '()) + +(define-abbrev-table 'cider-repl-mode-abbrev-table '()) + +(define-abbrev-table 'cider-stacktrace-mode-abbrev-table '()) + +(define-abbrev-table 'cider-test-report-mode-abbrev-table '()) + +(define-abbrev-table 'cljr--change-signature-mode-abbrev-table '()) + +(define-abbrev-table 'clojure-mode-abbrev-table '()) + +(define-abbrev-table 'clojurec-mode-abbrev-table '()) + +(define-abbrev-table 'clojurescript-mode-abbrev-table '()) + +(define-abbrev-table 'clojurex-mode-abbrev-table '()) + +(define-abbrev-table 'comint-mode-abbrev-table '()) + +(define-abbrev-table 'completion-list-mode-abbrev-table '()) + +(define-abbrev-table 'conf-colon-mode-abbrev-table '()) + +(define-abbrev-table 'conf-javaprop-mode-abbrev-table '()) + +(define-abbrev-table 'conf-ppd-mode-abbrev-table '()) + +(define-abbrev-table 'conf-space-mode-abbrev-table '()) + +(define-abbrev-table 'conf-unix-mode-abbrev-table '()) + +(define-abbrev-table 'conf-windows-mode-abbrev-table '()) + +(define-abbrev-table 'conf-xdefaults-mode-abbrev-table '()) + +(define-abbrev-table 'cperl-mode-abbrev-table + '( + ("=head1" "=head1" cperl-electric-pod 0) + ("=head2" "=head2" cperl-electric-pod 0) + ("=over" "=over" cperl-electric-pod 0) + ("=pod" "=pod" cperl-electric-pod 0) + ("continue" "continue" cperl-electric-else 0) + ("do" "do" cperl-electric-keyword 0) + ("else" "else" cperl-electric-else 4) + ("elsif" "elsif" cperl-electric-keyword 1) + ("for" "for" cperl-electric-keyword 2) + ("foreach" "foreach" cperl-electric-keyword 0) + ("foreachmy" "foreachmy" cperl-electric-keyword 0) + ("formy" "formy" cperl-electric-keyword 0) + ("head1" "head1" cperl-electric-pod 0) + ("head2" "head2" cperl-electric-pod 0) + ("if" "if" cperl-electric-keyword 4) + ("over" "over" cperl-electric-pod 0) + ("pod" "pod" cperl-electric-pod 0) + ("unless" "unless" cperl-electric-keyword 0) + ("until" "until" cperl-electric-keyword 0) + ("usedump" "use Data::Dumper qw(Dumper);" pde-abbv-no-blank 0) + ("useenc" "use Encode qw(encode decode from_to);" pde-abbv-no-blank 0) + ("usegtk" "use Gtk2 '-init'; +use Glib qw(TRUE FALSE); + +my $window = Gtk2::Window->new('toplevel'); +$window->signal_connect('delete_event' => sub { Gtk2->main_quit; });" pde-abbv-no-blank 0) + ("useopt" "use Getopt::Long; +GetOptions();" pde-abbv-no-blank 0) + ("while" "while" cperl-electric-keyword 4) + )) + +(define-abbrev-table 'css-mode-abbrev-table '()) + +(define-abbrev-table 'data-debug-mode-abbrev-table '()) + +(define-abbrev-table 'debugger-mode-abbrev-table '()) + +(define-abbrev-table 'diary-fancy-display-mode-abbrev-table '()) + +(define-abbrev-table 'diary-mode-abbrev-table '()) + +(define-abbrev-table 'diff-mode-abbrev-table '()) + +(define-abbrev-table 'dig-mode-abbrev-table '()) + +(define-abbrev-table 'direx:direx-mode-abbrev-table '()) + +(define-abbrev-table 'display-time-world-mode-abbrev-table '()) + +(define-abbrev-table 'doctex-mode-abbrev-table '()) + +(define-abbrev-table 'dsssl-mode-abbrev-table '()) + +(define-abbrev-table 'edebug-eval-mode-abbrev-table '()) + +(define-abbrev-table 'edit-abbrevs-mode-abbrev-table '()) + +(define-abbrev-table 'edit-list-mode-abbrev-table '()) + +(define-abbrev-table 'elisp-byte-code-mode-abbrev-table '()) + +(define-abbrev-table 'elpy-refactor-mode-abbrev-table '()) + +(define-abbrev-table 'emacs-lisp-byte-code-mode-abbrev-table '()) + +(define-abbrev-table 'emacs-lisp-mode-abbrev-table '()) + +(define-abbrev-table 'emms-lyrics-mode-abbrev-table '()) + +(define-abbrev-table 'emms-show-all-mode-abbrev-table '()) + +(define-abbrev-table 'emms-tag-editor-mode-abbrev-table '()) + +(define-abbrev-table 'epa-info-mode-abbrev-table '()) + +(define-abbrev-table 'epa-key-list-mode-abbrev-table '()) + +(define-abbrev-table 'epa-key-mode-abbrev-table '()) + +(define-abbrev-table 'ert-results-mode-abbrev-table '()) + +(define-abbrev-table 'ert-simple-view-mode-abbrev-table '()) + +(define-abbrev-table 'eshell-mode-abbrev-table '()) + +(define-abbrev-table 'ess-julia-mode-abbrev-table '()) + +(define-abbrev-table 'finder-mode-abbrev-table '()) + +(define-abbrev-table 'flycheck-error-list-mode-abbrev-table '()) + +(define-abbrev-table 'ftp-mode-abbrev-table '()) + +(define-abbrev-table 'fundamental-mode-abbrev-table '()) + +(define-abbrev-table 'gap-mode-abbrev-table '()) + +(define-abbrev-table 'gap-process-mode-abbrev-table '()) + +(define-abbrev-table 'gdb-script-mode-abbrev-table '()) + +(define-abbrev-table 'geiser-messages-mode-abbrev-table '()) + +(define-abbrev-table 'geiser-repl-mode-abbrev-table '()) + +(define-abbrev-table 'gfm-mode-abbrev-table '()) + +(define-abbrev-table 'git-commit-mode-abbrev-table '()) + +(define-abbrev-table 'git-rebase-mode-abbrev-table '()) + +(define-abbrev-table 'global-abbrev-table + '( + ("brd" "Best regards, + + Daniel" nil 6) + ("brdb" "Best regards, + + Daniel Borchmann" nil 0) + ("btw" "by the way" nil 4) + ("wrt" "with respect to" nil 1) + )) + +(define-abbrev-table 'gnus-article-edit-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-article-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-browse-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-category-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-custom-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-edit-form-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-group-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-score-mode-abbrev-table '()) + +(define-abbrev-table 'gnus-sticky-article-mode-abbrev-table '()) + +(define-abbrev-table 'google-maps-static-mode-abbrev-table '()) + +(define-abbrev-table 'grep-mode-abbrev-table '()) + +(define-abbrev-table 'gud-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-cabal-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-compilation-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-debug-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-error-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-interactive-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-mode-abbrev-table '()) + +(define-abbrev-table 'haskell-presentation-mode-abbrev-table '()) + +(define-abbrev-table 'helm-grep-mode-abbrev-table '()) + +(define-abbrev-table 'helm-major-mode-abbrev-table '()) + +(define-abbrev-table 'helm-moccur-mode-abbrev-table '()) + +(define-abbrev-table 'help-mode-abbrev-table '()) + +(define-abbrev-table 'html-mode-abbrev-table '()) + +(define-abbrev-table 'hy-mode-abbrev-table '()) + +(define-abbrev-table 'ibuffer-mode-abbrev-table '()) + +(define-abbrev-table 'idl-mode-abbrev-table '()) + +(define-abbrev-table 'image-dired-display-image-mode-abbrev-table '()) + +(define-abbrev-table 'image-dired-thumbnail-mode-abbrev-table '()) + +(define-abbrev-table 'imenu-tree-mode-abbrev-table '()) + +(define-abbrev-table 'inf-perl-mode-abbrev-table '()) + +(define-abbrev-table 'inferior-emacs-lisp-mode-abbrev-table '()) + +(define-abbrev-table 'inferior-haskell-mode-abbrev-table '()) + +(define-abbrev-table 'inferior-julia-mode-abbrev-table '()) + +(define-abbrev-table 'inferior-lisp-mode-abbrev-table '()) + +(define-abbrev-table 'inferior-python-mode-abbrev-table '()) + +(define-abbrev-table 'inferior-scheme-mode-abbrev-table '()) + +(define-abbrev-table 'ivy-occur-grep-mode-abbrev-table '()) + +(define-abbrev-table 'ivy-occur-mode-abbrev-table '()) + +(define-abbrev-table 'java-mode-abbrev-table '()) + +(define-abbrev-table 'jde-mode-abbrev-table + '( + ("catch" "catch" c-electric-continued-statement 0) + ("else" "else" c-electric-continued-statement 0) + ("finally" "finally" c-electric-continued-statement 0) + ("while" "while" c-electric-continued-statement 0) + )) + +(define-abbrev-table 'jde-run-mode-abbrev-table '()) + +(define-abbrev-table 'julia-mode-abbrev-table '()) + +(define-abbrev-table 'latex-mode-abbrev-table + '( + ("sqc" "sqcap" nil 2) + ("sqse" "sqsubseteq" nil 1) + ("sqsn" "sqsubsetneq" nil 0) + )) + +(define-abbrev-table 'lisp-mode-abbrev-table '()) + +(define-abbrev-table 'literate-haskell-mode-abbrev-table '()) + +(define-abbrev-table 'locate-mode-abbrev-table '()) + +(define-abbrev-table 'log-edit-mode-abbrev-table '()) + +(define-abbrev-table 'magit-annex-list-mode-abbrev-table '()) + +(define-abbrev-table 'magit-annex-unused-mode-abbrev-table '()) + +(define-abbrev-table 'magit-branch-manager-mode-abbrev-table '()) + +(define-abbrev-table 'magit-cherry-mode-abbrev-table '()) + +(define-abbrev-table 'magit-commit-mode-abbrev-table '()) + +(define-abbrev-table 'magit-diff-mode-abbrev-table '()) + +(define-abbrev-table 'magit-log-mode-abbrev-table '()) + +(define-abbrev-table 'magit-log-select-mode-abbrev-table '()) + +(define-abbrev-table 'magit-merge-preview-mode-abbrev-table '()) + +(define-abbrev-table 'magit-mode-abbrev-table '()) + +(define-abbrev-table 'magit-popup-mode-abbrev-table '()) + +(define-abbrev-table 'magit-process-mode-abbrev-table '()) + +(define-abbrev-table 'magit-reflog-mode-abbrev-table '()) + +(define-abbrev-table 'magit-refs-mode-abbrev-table '()) + +(define-abbrev-table 'magit-repolist-mode-abbrev-table '()) + +(define-abbrev-table 'magit-revision-mode-abbrev-table '()) + +(define-abbrev-table 'magit-stash-mode-abbrev-table '()) + +(define-abbrev-table 'magit-stashes-mode-abbrev-table '()) + +(define-abbrev-table 'magit-status-mode-abbrev-table '()) + +(define-abbrev-table 'magit-submodule-list-mode-abbrev-table '()) + +(define-abbrev-table 'magit-wazzup-mode-abbrev-table '()) + +(define-abbrev-table 'mail-abbrevs + '( + )) + +(define-abbrev-table 'markdown-mode-abbrev-table '()) + +(define-abbrev-table 'message-mode-abbrev-table + '( + ("bd" "Best, + + Daniel" nil 54) + ("bdb" "Best, + + Daniel Borchmann" nil 0) + ("bgd" "Beste Grüße, + + Daniel" nil 0) + ("bgdb" "Beste Grüße, + + Daniel Borchmann" nil 9) + ("lg" "Liebe Grüße, + + Daniel" nil 18) + ("mbg" "Mit besten Grüßen, + + Daniel Borchmann" nil 0) + ("vgd" "Viele Grüße, + + Daniel" nil 6) + ("vgdb" "Viele Grüße, + + Daniel Borchmann" nil 2) + )) + +(define-abbrev-table 'messages-buffer-mode-abbrev-table '()) + +(define-abbrev-table 'net-utils-mode-abbrev-table '()) + +(define-abbrev-table 'network-connection-mode-abbrev-table '()) + +(define-abbrev-table 'notmuch-hello-mode-abbrev-table '()) + +(define-abbrev-table 'notmuch-message-mode-abbrev-table '()) + +(define-abbrev-table 'notmuch-search-mode-abbrev-table '()) + +(define-abbrev-table 'notmuch-show-mode-abbrev-table '()) + +(define-abbrev-table 'notmuch-tree-mode-abbrev-table '()) + +(define-abbrev-table 'nrepl-connections-buffer-mode-abbrev-table '()) + +(define-abbrev-table 'nrepl-messages-mode-abbrev-table '()) + +(define-abbrev-table 'nrepl-mode-abbrev-table '()) + +(define-abbrev-table 'nslookup-mode-abbrev-table '()) + +(define-abbrev-table 'nxml-mode-abbrev-table '()) + +(define-abbrev-table 'objc-mode-abbrev-table '()) + +(define-abbrev-table 'occur-edit-mode-abbrev-table '()) + +(define-abbrev-table 'occur-mode-abbrev-table '()) + +(define-abbrev-table 'org-export-stack-mode-abbrev-table '()) + +(define-abbrev-table 'org-mode-abbrev-table '()) + +(define-abbrev-table 'outline-mode-abbrev-table '()) + +(define-abbrev-table 'package-menu-mode-abbrev-table '()) + +(define-abbrev-table 'pdf-annot-list-mode-abbrev-table '()) + +(define-abbrev-table 'pdf-occur-buffer-mode-abbrev-table '()) + +(define-abbrev-table 'pdf-outline-buffer-mode-abbrev-table '()) + +(define-abbrev-table 'perl-mode-abbrev-table '()) + +(define-abbrev-table 'perldoc-mode-abbrev-table '()) + +(define-abbrev-table 'pike-mode-abbrev-table '()) + +(define-abbrev-table 'plain-tex-mode-abbrev-table '()) + +(define-abbrev-table 'process-menu-mode-abbrev-table '()) + +(define-abbrev-table 'prog-mode-abbrev-table '()) + +(define-abbrev-table 'python-mode-abbrev-table '()) + +(define-abbrev-table 'python-mode-skeleton-abbrev-table + '( + )) + +(define-abbrev-table 'reb-lisp-mode-abbrev-table '()) + +(define-abbrev-table 'reb-mode-abbrev-table '()) + +(define-abbrev-table 'reftex-select-bib-mode-abbrev-table '()) + +(define-abbrev-table 'reftex-select-label-mode-abbrev-table '()) + +(define-abbrev-table 'ruby-mode-abbrev-table '()) + +(define-abbrev-table 'scheme-mode-abbrev-table '()) + +(define-abbrev-table 'select-tags-table-mode-abbrev-table '()) + +(define-abbrev-table 'sepia-cpan-mode-abbrev-table '()) + +(define-abbrev-table 'sepia-mode-abbrev-table '()) + +(define-abbrev-table 'sepia-repl-mode-abbrev-table '()) + +(define-abbrev-table 'sepia-scratchpad-mode-abbrev-table '()) + +(define-abbrev-table 'sgml-mode-abbrev-table '()) + +(define-abbrev-table 'sh-mode-abbrev-table '()) + +(define-abbrev-table 'shell-mode-abbrev-table '()) + +(define-abbrev-table 'sldb-mode-abbrev-table '()) + +(define-abbrev-table 'slime-compiler-notes-mode-abbrev-table '()) + +(define-abbrev-table 'slime-connection-list-mode-abbrev-table '()) + +(define-abbrev-table 'slime-fuzzy-completions-mode-abbrev-table '()) + +(define-abbrev-table 'slime-inspector-mode-abbrev-table '()) + +(define-abbrev-table 'slime-thread-control-mode-abbrev-table '()) + +(define-abbrev-table 'slime-trace-dialog--detail-mode-abbrev-table '()) + +(define-abbrev-table 'slime-trace-dialog-mode-abbrev-table '()) + +(define-abbrev-table 'slime-xref-mode-abbrev-table '()) + +(define-abbrev-table 'slitex-mode-abbrev-table '()) + +(define-abbrev-table 'smbclient-mode-abbrev-table '()) + +(define-abbrev-table 'smime-mode-abbrev-table '()) + +(define-abbrev-table 'snippet-mode-abbrev-table '()) + +(define-abbrev-table 'special-mode-abbrev-table '()) + +(define-abbrev-table 'speedbar-mode-abbrev-table '()) + +(define-abbrev-table 'synonyms-mode-abbrev-table '()) + +(define-abbrev-table 'tablist-mode-abbrev-table '()) + +(define-abbrev-table 'tabulated-list-mode-abbrev-table '()) + +(define-abbrev-table 'tar-mode-abbrev-table '()) + +(define-abbrev-table 'telnet-mode-abbrev-table '()) + +(define-abbrev-table 'term-mode-abbrev-table '()) + +(define-abbrev-table 'tex-mode-abbrev-table '()) + +(define-abbrev-table 'tex-shell-abbrev-table '()) + +(define-abbrev-table 'text-mode-abbrev-table '()) + +(define-abbrev-table 'tree-mode-abbrev-table '()) + +(define-abbrev-table 'url-cookie-mode-abbrev-table '()) + +(define-abbrev-table 'vc-git-log-edit-mode-abbrev-table '()) + +(define-abbrev-table 'vc-git-log-view-mode-abbrev-table '()) + +(define-abbrev-table 'vc-git-region-history-mode-abbrev-table '()) + +(define-abbrev-table 'xref--xref-buffer-mode-abbrev-table '()) + diff --git a/bbdb b/bbdb new file mode 120000 index 0000000..dc91f5a --- /dev/null +++ b/bbdb @@ -0,0 +1 @@ +private/bbdb \ No newline at end of file diff --git a/bookmarks b/bookmarks new file mode 120000 index 0000000..0497f25 --- /dev/null +++ b/bookmarks @@ -0,0 +1 @@ +private/bookmarks \ No newline at end of file diff --git a/custom.el b/custom.el new file mode 120000 index 0000000..448cfa9 --- /dev/null +++ b/custom.el @@ -0,0 +1 @@ +private/custom.el \ No newline at end of file diff --git a/eshell/alias b/eshell/alias new file mode 100644 index 0000000..9357561 --- /dev/null +++ b/eshell/alias @@ -0,0 +1,5 @@ +alias ff find-file-other-window $1 +alias d dired-other-window $1 +alias la ls -al $* +alias ll ls -l $* +alias l ls -1 diff --git a/exot-main-theme.el b/exot-main-theme.el new file mode 100644 index 0000000..a93a56d --- /dev/null +++ b/exot-main-theme.el @@ -0,0 +1,38 @@ +(deftheme exot-main + "Created 2017-03-17.") + +(custom-theme-set-faces + 'exot-main + '(aw-leading-char-face ((t (:foreground "red" :height 1.0)))) + '(cursor ((t (:background "red" :foreground "#002b36" :inverse-video t :weight ultra-bold)))) + '(emms-browser-artist-face ((t (:foreground "RoyalBlue1")))) + '(emms-browser-composer-face ((t (:foreground "RoyalBlue1")))) + '(emms-browser-performer-face ((t (:foreground "#aaaaff")))) + '(emms-browser-track-face ((t (:foreground "DodgerBlue3" :height 1.0)))) + '(emms-playlist-selected-face ((t (:foreground "medium sea green")))) + '(org-agenda-date ((t (:background "#002b36" :foreground "#586e75" :inverse-video nil :box (:line-width 2 :color "#002b36") :overline nil :slant normal :weight bold :height 1.2)))) + '(org-agenda-dimmed-todo-face ((t nil))) + '(org-agenda-structure ((t (:foreground "#93a1a1" :inverse-video nil :box (:line-width 2 :color "#002b36") :underline nil :slant normal :weight bold :height 1.1)))) + '(org-clock-overlay ((t (:background "black")))) + '(org-column ((t (:strike-through nil :underline nil :slant normal :weight normal :height 110 :family "DejaVu Sans Mono")))) + '(org-headline-done ((t (:foreground "#859900")))) + '(org-level-1 ((t (:inherit default :foreground "#cb4b16" :height 1.0)))) + '(org-level-2 ((t (:inherit default :foreground "#859900" :height 1.0)))) + '(org-level-3 ((t (:inherit default :foreground "#268bd2" :height 1.0)))) + '(org-level-4 ((t (:inherit default :foreground "#b58900" :height 1.0)))) + '(org-level-5 ((t (:inherit default :foreground "#2aa198" :height 1.0)))) + '(org-warning ((t (:foreground "#dc322f" :weight normal)))) + '(outline-4 ((t (:inherit org-level-4)))) + '(flyspell-duplicate ((t (:underline (:color "orange red" :style wave))))) + '(flyspell-incorrect ((t (:underline (:color "orange red" :style wave))))) + '(gnus-group-mail-2 ((t (:inherit outline-4 :weight normal)))) + '(gnus-group-mail-3 ((t (:inherit gnus-group-mail-3-empty :weight normal)))) + '(gnus-group-news-3 ((t (:inherit outline-5 :weight normal)))) + '(gnus-summary-high-ancient ((t (:foreground "#268bd2" :weight normal)))) + '(gnus-summary-high-read ((t (:foreground "#859900" :weight normal)))) + '(gnus-summary-high-unread ((t (:foreground "#839496" :weight normal)))) + '(gnus-summary-low-ancient ((t (:foreground "dim gray")))) + '(gnus-summary-low-unread ((t (:foreground "dim gray")))) + '(default ((t (:height 108))))) + +(provide-theme 'exot-main) diff --git a/gnus b/gnus new file mode 100644 index 0000000..e47e134 --- /dev/null +++ b/gnus @@ -0,0 +1,657 @@ +;;; gnus --- Daniel's Gnus Configuration + +;;; Commentary: + +;; Sources: +;; - http://page.math.tu-berlin.de/~freundt/.gnus +;; - Formatting from http://www.emacswiki.org/emacs/GnusFormatting, Version 3 +;; - http://www.emacswiki.org/emacs/GnusDemon +;; - http://people.irisa.fr/Nicolas.Berthier/file:.gnus.el + +;;; Code: + + +;;; General + +;; Requires + +(require 'gnus) +(require 'message) +(require 'gnus-util) +(require 'gnus-start) +(require 'gnus-group) +(require 'gnus-sum) +(require 'gnus-art) +(require 'gnus-score) +(require 'nntp) +(require 'gnus-agent) +(require 'nnml) +(require 'gnus-async) + +;; Debugging + +(setq gnus-verbose 10) + +;; Accounts + +(setq-default message-dont-reply-to-names + (regexp-opt (list db/personal-mail-address db/work-mail-address) + 'words)) + +(setq gnus-select-method '(nnnil "") + gnus-secondary-select-methods + `((nntp "dfn" + (nntp-open-connection-function nntp-open-tls-stream) + (nntp-port-number 563) + (nntp-address "news.cis.dfn.de")) + (nntp "gmane" + (nntp-open-connection-function nntp-open-tls-stream) + (nntp-port-number 563) + (nntp-address "news.gmane.org")) + (nnimap "tu" + (nnimap-stream shell) + (nnimap-shell-program "/usr/lib/dovecot/imap -o mail_location=maildir:$HOME/Mail/zih") + (nnimap-inbox "INBOX") + (nnimap-split-methods nnimap-split-fancy) + (nnimap-split-fancy ,db/work-gnus-filter-rules)) + (nnimap "algebra20" + (nnimap-stream shell) + (nnimap-shell-program "/usr/lib/dovecot/imap -o mail_location=maildir:$HOME/Mail/algebra20") + (nnimap-split-methods nnimap-split-fancy) + (nnimap-inbox "INBOX") + (nnimap-split-fancy ,db/personal-gnus-filter-rules)) + (nnml "" + (nnmail-split-methods nnmail-split-fancy) + (nnmail-split-fancy + (| ("subject" ".*Tiger Auditing Report for.*" "mail.tiger") + "mail.misc"))) + (nnmaildir "archive" + (directory "~/Mail/archive/") + (directory-files nnheader-directory-files-safe) + (nnir-search-engine notmuch) + (nnir-notmuch-remove-prefix ,(expand-file-name "~/Mail/archive/"))))) + +;; General Configuration + +(setq gnus-ignored-from-addresses message-dont-reply-to-names + message-directory (expand-file-name "mail/" gnus-directory) + nnmail-message-id-cache-file (expand-file-name ".nnmail-cache" gnus-directory) + nnml-directory message-directory + mail-sources '((file)) + mail-source-delete-incoming t + nntp-nov-is-evil t + gnus-asynchronous t + gnus-save-killed-list nil + gnus-save-newsrc-file nil + gnus-read-newsrc-file nil + gnus-check-new-newsgroups nil + gnus-use-cache 'passive + gnus-read-active-file 'some + gnus-build-sparse-threads 'some + gnus-subscribe-newsgroup-method 'gnus-subscribe-killed + gnus-group-list-inactive-groups nil + gnus-suppress-duplicates nil + gnus-large-newsgroup 200 + nnmail-expiry-wait 7 + nnmail-cache-accepted-message-ids t + gnus-summary-next-group-on-exit nil + gnus-use-full-window nil + gnus-always-force-window-configuration t + gnus-fetch-old-headers nil) + +(setq gnus-visible-headers (regexp-opt '("From:" + "Newsgroups:" + "Subject:" + "Date:" + "Followup-To:" + "Reply-To:" + "Organization:" + "Summary:" + "Keywords:" + "Mail-Copies-To:" + "To:" + "Cc:" + "BCC:" + "X-Newsreader:" + "X-Mailer:" + "X-Sent:" + "Posted-To:" + "Mail-Copies-To:" + "Apparently-To:" + "Gnus-Warning:" + "Resent-From:" + "gpg-key-ID:" + "fingerprint:" + "X-Jabber-ID:" + "User-Agent:"))) + +(defadvice gnus-group-mail (before inhibit-no-argument activate) + (unless (ad-get-arg 0) + (ad-set-arg 0 1))) + +(remove-hook 'gnus-mark-article-hook + 'gnus-summary-mark-read-and-unread-as-read) +(add-hook 'gnus-mark-article-hook 'gnus-summary-mark-unread-as-read) + +(add-hook 'kill-emacs-hook + #'(lambda () + (interactive) + (when (get-buffer "*Group*") + (gnus-group-exit)))) + +(bind-key "q" #'gnus-summary-expand-window gnus-article-mode-map) + + +;;; Appearence + +(setq gnus-group-line-format "%S%p%P%5y(%2i):%B%(%-70g%) +" + gnus-auto-select-first nil + gnus-auto-select-next nil) + +(setq gnus-summary-line-format "%U%O%R%6k %(%&user-date; %-13,13f %B%s%)\n" + gnus-thread-sort-functions '(gnus-thread-sort-by-most-recent-date) + gnus-subthread-sort-functions '(gnus-thread-sort-by-date) + gnus-thread-hide-subtree t + gnus-user-date-format-alist '((t . "%Y-%m-%d %H:%M")) + gnus-sum-thread-tree-indent " " + gnus-sum-thread-tree-root "● " + gnus-sum-thread-tree-false-root "◎ " + gnus-sum-thread-tree-single-indent "◯ " + gnus-sum-thread-tree-single-leaf "╰► " + gnus-sum-thread-tree-leaf-with-other "├► " + gnus-sum-thread-tree-vertical "│" + gnus-summary-thread-gathering-function 'gnus-gather-threads-by-references + + ;; Yay (seen here: `https://github.com/cofi/dotfiles/blob/master/gnus.el') + gnus-ancient-mark ?✓ + ;; gnus-cached-mark ?☍ + gnus-canceled-mark ?↗ + gnus-del-mark ?✗ + ;; gnus-dormant-mark ?⚐ + gnus-expirable-mark ?♻ + gnus-forwarded-mark ?↪ + ;; gnus-killed-mark ?☠ + ;; gnus-process-mark ?⚙ + gnus-read-mark ?✓ + gnus-recent-mark ?✩ + gnus-replied-mark ?↺ + gnus-unread-mark ?✉ + ;; gnus-unseen-mark ?★ + ;; gnus-ticked-mark ?⚑ + ) + +;; we need to do some magic as otherwise the agent does not delete articles from +;; its .overview when we move them around +(defadvice gnus-summary-move-article (around + no-cancel-mark + (&optional n to-newsgroup + select-method action) + activate) + (let ((articles (gnus-summary-work-articles n)) + (return ad-do-it)) + (when (or (null action) + (eq action 'move)) + (dolist (article articles) + (gnus-summary-mark-article article gnus-expirable-mark))) + return)) + +(add-hook 'gnus-group-mode-hook 'gnus-topic-mode) + +(setq gnus-treat-hide-boring-headers 'head + gnus-treat-strip-multiple-blank-lines nil + gnus-treat-display-smileys t + gnus-treat-emphasize 'head + gnus-treat-unsplit-urls t) + + +;;; Adaptive Scoring + +(setq gnus-use-scoring nil + gnus-use-adaptive-scoring nil + gnus-adaptive-word-length-limit 5 + gnus-adaptive-word-no-group-words t + gnus-default-adaptive-score-alist + '((gnus-unread-mark) + (gnus-ticked-mark (from 4)) + (gnus-dormant-mark (from 5)) + (gnus-del-mark (from -4) (subject -1)) + (gnus-read-mark (from 4) (subject 2)) + (gnus-expirable-mark (from -1) (subject -1)) + (gnus-killed-mark (from -1) (subject -3)) + (gnus-kill-file-mark) + (gnus-ancient-mark) + (gnus-low-score-mark) + (gnus-catchup-mark (from -1) (subject -1)))) + +(setq-default gnus-summary-mark-below nil) + +(setq gnus-parameters + '(("^nnimap.*" + (gnus-use-scoring nil)) + ("^nnimap.*:lists.*" + (gnus-use-scoring t) + (gnus-use-adaptive-scoring '(word line))) + ("^nntp.*" + (gnus-use-scoring nil) + (gnus-summary-mark-below -1000) + (gnus-use-adaptive-scoring '(word line))))) + +(add-hook 'gnus-summary-exit-hook + 'gnus-summary-bubble-group) + + +;;; Gnus Registry + +(require 'gnus-registry) + +(setq gnus-registry-split-strategy 'majority + gnus-registry-ignored-groups '(("^nntp" t) + ("^nnfolder" t) + ("^nnir" t) + ("^nnmaildir" t) + ("INBOX$" t)) + gnus-registry-max-entries nil + gnus-registry-track-extra '(sender subject recipient) + gnus-registry-cache-file (expand-file-name "gnus.registry.eioioi" + emacs-d)) + +(setq gnus-refer-article-method + '(current (nnregistry))) + +(gnus-registry-initialize) + + +;;; MIME + +(use-package dash + :demand t + :ensure t) + +(add-to-list 'gnus-boring-article-headers 'long-to) + +(setq gnus-ignored-mime-types '("text/x-vcard") + mm-discouraged-alternatives '("text/richtext" "text/html") + mm-automatic-display (-difference mm-automatic-display + '("text/html" + "text/enriched" + "text/richtext")) + message-forward-as-mime t + gnus-inhibit-mime-unbuttonizing nil + gnus-buttonized-mime-types '("multipart/signed" "multipart/encrypted") + gnus-inhibit-images t) + +(setq message-citation-line-function + (lambda () + (when message-reply-headers + (insert "ghItlhpu' "(mail-header-from message-reply-headers) ":") + (newline)))) + +(use-package mm-decode + :config (progn + ;; Tells Gnus to inline the part + (add-to-list 'mm-inlined-types "application/pgp$") + ;; Tells Gnus how to display the part when it is requested + (add-to-list 'mm-inline-media-tests + '("application/pgp$" mm-inline-text identity)) + ;; Tell Gnus not to wait for a request, just display the thing + ;; straight away. + (add-to-list 'mm-automatic-display "application/pgp$") + + (setq mm-text-html-renderer 'shr))) + + +;;; Signing and Encryption + +(setq mm-encrypt-option nil + mm-sign-option nil + mm-decrypt-option 'known + mm-verify-option 'known + mml-smime-use 'epg + ;;mml2015-encrypt-to-self t + mml2015-display-key-image nil + gnus-message-replysign t + gnus-message-replyencrypt t + gnus-message-replysignencrypted t + mml-secure-cache-passphrase nil + mml-smime-cache-passphrase nil) + +;; Automatic encryption if all necessary keys are present + +(require 'mail-extr) + +(defun db/public-key (address &optional method) + "Return valid public keys for ADDRESS and given METHOD. + +METHOD can be \"smime\" or \"pgpmime\"; defaults to \"pgpmime\". +ADDRESS is a string containing exactly one email address." + (check-type address string) + (unless method (setq method "pgpmime")) + (epg-list-keys (epg-make-context + (cond + ((string= method "smime") + 'CMS) + ((string= method "pgpmime") + 'OpenPGP) + (t (error "Unknown method %s" method)))) + address)) + +(defun db/encryption-possible-p (recipients method) + "Check whether sending encrypted emails to all RECIPIENTS is possible. + +METHOD specifies the encrypt method used. Can be either +\"smime\" or \"pgpmime\"." + (every (lambda (recipient) + (not (null (db/public-key recipient method)))) + recipients)) + +(defun db/message-recipients () + "Return all recipients of the email in the current buffer." + (cl-mapcan (lambda (field) + (let ((field-value (message-field-value field))) + (when field-value + (mapcar #'cadr + (mail-extract-address-components field-value t))))) + (list "to" "cc" "bcc"))) + +(defun db/signencrypt-message-when-possible () + "Add mml markers for signing and encryption of an email if possible." + (interactive) + (when (eq major-mode 'message-mode) + (let ((from (message-field-value "from"))) + (when from + (let ((methods (if (string-match "@tu-dresden\.de>" from) + (list "smime" "pgpmime") + (list "pgpmime" "smime"))) + (recipients (db/message-recipients))) + + ;; if there is no recipient, encrypt with default method + (if (null recipients) + (mml-secure-message (first methods) 'signencrypt) + + ;; go through available keys + (let ((available-method + (cl-find-if (lambda (method) + (db/encryption-possible-p recipients method)) + methods))) + + (if available-method + (mml-secure-message available-method 'signencrypt) + + ;; if nothing works, sign with default method + (mml-secure-message (first methods) 'sign))))))))) + +(add-hook 'gnus-message-setup-hook + #'db/signencrypt-message-when-possible) + +;; inspired by https://www.emacswiki.org/emacs/ExtendSMIME + +(use-package ldap + :config (progn + (setq ldap-default-host "") + (setq ldap-default-base "O=DFN-Verein,C=DE" + ldap-ldapsearch-args '("-x" "-tt" "-H ldaps://ldap.pca.dfn.de")))) + +(defun db/lookup-smime-key (mail) + "Look up `MAIL' on ldap-server of the DFN. + +If found, imports the certificate via gpgsm." + (interactive "sMail: ") + (when (get-buffer " *ldap-value*") + (kill-buffer " *ldap-value*")) + (ldap-search (format "(mail=%s)" mail)) + (let ((bufval (get-buffer " *ldap-value*"))) + (when bufval + (with-current-buffer bufval + (save-restriction + (widen) ; just to be sure + (let ((result (call-process-region (point-min) (point-max) + "gpgsm" + nil nil nil + "--import"))) + (if (zerop result) + (message "Successfully imported certificate for <%s>" mail) + (error "Could not import certificate for <%s>" mail)))))))) + +;; Fix + +(defun mm-view-pkcs7-verify (handle) + (let ((verified nil)) + (with-temp-buffer + (if (eq mml-smime-use 'epg) + ;; Use gpgsm + (progn + (insert-buffer-substring (mm-handle-buffer handle)) + (setq verified (epg-verify-string (epg-make-context 'CMS) + (base64-decode-string (buffer-string))))) + ;; FIXME: insert valid signature + ;; use openssl + (progn + (insert "MIME-Version: 1.0\n") + (mm-insert-headers "application/pkcs7-mime" "base64" "smime.p7m") + (insert-buffer-substring (mm-handle-buffer handle)) + (setq verified (smime-verify-region (point-min) (point-max)))))) + (goto-char (point-min)) + (mm-insert-part handle) + (if (search-forward "Content-Type: " nil t) + (delete-region (point-min) (match-beginning 0))) + (goto-char (point-max)) + (if (re-search-backward "--\r?\n?" nil t) + (delete-region (match-end 0) (point-max))) + (unless verified + (insert-buffer-substring smime-details-buffer))) + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + t) + + + +;;; Custom commands + +(bind-key "v u" + '(lambda () + (interactive) + (save-mark-and-excursion + (when (gnus-topic-select-group) + (gnus-summary-exit)))) + gnus-group-mode-map) + +(bind-key "v j" + '(lambda () + (interactive) + (gnus-agent-toggle-plugged nil) + (gnus-agent-toggle-plugged t) + (gnus-group-get-new-news 3)) + gnus-group-mode-map) + +(add-hook 'gnus-get-new-news-hook + (lambda () + (when gnus-plugged + (gnus-agent-toggle-plugged nil) + (gnus-agent-toggle-plugged t)))) + +;; (bind-key "v g" #'db/get-mail gnus-group-mode-map) + +(bind-key "v c" + (lambda () + (interactive) + (save-mark-and-excursion + (gnus-topic-jump-to-topic "News") + (gnus-topic-read-group))) + gnus-group-mode-map) + +(defun db/gnus-summary-open-Link () + "Open link named \"Link\" in current article." + (interactive) + (save-window-excursion + (save-mark-and-excursion + (save-restriction + (widen) + (let ((url nil)) + (unless (eq major-mode 'gnus-article-mode) + (gnus-summary-select-article-buffer)) + (goto-char (point-min)) + (while (and (not url) + (search-forward "Link")) + (backward-char) + (setq url (get-text-property (point) 'shr-url))) + (when url + (browse-url url))))))) + +(bind-key "C-" #'db/gnus-summary-open-Link gnus-summary-mode-map) +(bind-key "C-" #'db/gnus-summary-open-Link gnus-article-mode-map) + + +;;; Timeout for fetching news + +(setq nntp-connection-timeout nil) + + +;;; Agents + +(setq gnus-agent-mark-unread-after-downloaded nil + gnus-agent-synchronize-flags t + gnus-agent-go-online t) + + +;;; Do some pretty printing before saving the newsrc file + +(defun db/gnus-save-newsrc-with-whitespace-1 () + "Save ~/.newsrc.eld with extra whitespace." + ;; http://ding.gnus.narkive.com/pq3Z8ZjQ/pretty-printing-newsrc-eld#post3 + (gnus-message 5 "Adding whitespace to .newsrc.eld") + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "(\\\"\\| ((\\| (nn" nil t) + (replace-match "\n \\&" t)) + (delete-trailing-whitespace))) + +(add-hook 'gnus-save-quick-newsrc-hook #'db/gnus-save-newsrc-with-whitespace-1) + + +;;; Mail Formatting + +(setq gnus-posting-styles + `((".*" + (name ,user-full-name) + (address ,db/work-mail-address) + (signature-file "~/.signature-minimal") + ("X-Jabber-ID" ,db/jabber-id)) + (message-mail-p + (signature-file "~/.signature")) + ("algebra20:.*" + (address ,db/personal-mail-address) + (signature-file "~/.signature")) + ("tu:.*" + (name ,user-full-name) + (address ,db/work-mail-address) + (signature-file "~/.signature-official")))) + +;; http://mbork.pl/2015-11-28_Fixing_mml-attach-file_using_advice +(defun db/mml-attach-file--go-to-eob (orig-fun &rest args) + "Go to the end of buffer before attaching files." + (save-excursion + (save-restriction + (widen) + (goto-char (point-max)) + (apply orig-fun args)))) + +(advice-add 'mml-attach-file :around #'db/mml-attach-file--go-to-eob) + + +;;; Archiving + +;; FIXME: this is obsolete +(setq gnus-message-archive-method + `(nnfolder "archive" + (nnfolder-inhibit-expiry t) + (nnfolder-active-file ,(expand-file-name "archive/active" gnus-directory)) + (nnfolder-directory ,(expand-file-name "archive/" gnus-directory))) + gnus-update-message-archive-method t + gnus-message-archive-group "archive" + gnus-gcc-mark-as-read t) + + +;;; SMTP configuration + +(require 'smtpmail) +(require 'starttls) + +(defadvice smtpmail-send-it (around display-trace-buffer disable) + "If an error is signalled, display the process buffer." + (condition-case signals-data + ad-do-it + (error (shrink-window-if-larger-than-buffer + (display-buffer (get-buffer (format "*trace of SMTP session to %s*" + smtpmail-smtp-server)))) + (signal (car signals-data) (cdr signals-data))))) + +(setq send-mail-function 'smtpmail-send-it + smtpmail-stream-type 'starttls + smtpmail-smtp-service 587 + starttls-use-gnutls t + starttls-extra-arguments '("--strict-tofu") + smtpmail-smtp-server (nth 1 (car db/smtp-accounts)) + smtpmail-smtp-user (nth 4 (car db/smtp-accounts))) + +(defun db/set-smtp-server-from-header (orig-fun &rest args) + "Choose smtp-settings dynamically, based on the From: header +entry of the current mail." + (require 'mail-extr) + (let* ((from (or (save-restriction + (message-narrow-to-headers) + (mail-fetch-field "From")) + user-mail-address)) + (address (cadr (mail-extract-address-components from))) + ;; db/smtp-accounts set in db-private + (account (assoc address db/smtp-accounts))) + (message "Using address: %s" address) + (if account + (progn + (message "Sending with account for %s" address) + (cl-destructuring-bind (smtpmail-smtp-server + smtpmail-stream-type + smtpmail-smtp-service + smtpmail-smtp-user) + (cdr account) + (apply orig-fun args))) + (progn + (message "Sending with default account settings") + (apply orig-fun args))))) + +(advice-add 'smtpmail-via-smtp + :around #'db/set-smtp-server-from-header) + +(setq smtpmail-debug-info t) + + +;;; Notmuch + +(require 'nnir) + +(setq nnir-method-default-engines '((nnimap . imap) + (nnmaildir . notmuch) + (nntp . gmane))) + +(use-package notmuch + :config (progn + ;; (bind-key "GG" 'notmuch-search gnus-group-mode-map) + + (defun db/notmuch-search-update-index (orig-fun &rest args) + "Update notmuch index before searching" + (message "Indexing new Mail...") + (shell-command "notmuch new --quiet 2>&1 | grep -v \"Note: Ignoring\"") + (message "Indexing new Mail... done.") + (apply orig-fun args)) + + (advice-add 'notmuch-search + :around #'db/notmuch-search-update-index) + (advice-add 'nnir-run-notmuch + :around #'db/notmuch-search-update-index) + + (setq notmuch-fcc-dirs nil))) + +;;; + +t diff --git a/init.el b/init.el new file mode 100644 index 0000000..2571b85 --- /dev/null +++ b/init.el @@ -0,0 +1,1657 @@ +;;; Init.el --- Daniel's Emacs Configuration + +;;; Commentary: + +;;; Code: + + +;; * Packages + +(defconst emacs-d (file-name-directory + (file-chase-links load-file-name)) + "The giant turtle on which the world rests.") + +(require 'package) + +(setq package-user-dir (expand-file-name "elpa" emacs-d)) + +(setq package-archives + '(("melpa" . "https://melpa.org/packages/") + ("gnu" . "https://elpa.gnu.org/packages/") + ("melpa-stable" . "https://stable.melpa.org/packages/") + ("org" . "http://orgmode.org/elpa/"))) + +(setq package-enable-at-startup nil) + +(package-initialize) + +(dolist (package '(diminish use-package bind-key)) + (unless (package-installed-p package) + (package-install package)) + (require package)) + +(put 'use-package 'common-lisp-indent-function 1) + +(use-package auto-compile + :ensure t) + + +;; * Mode activation + +(defun db/run-init () + "Run main initialization after everything is set up." + + ;; Activate modes + (show-paren-mode 1) + (transient-mark-mode 1) + (global-font-lock-mode 1) + (column-number-mode 1) + ;; (display-time) + (delete-selection-mode 1) + + (dolist (mode '(tool-bar-mode + scroll-bar-mode + menu-bar-mode + blink-cursor-mode)) + (when (fboundp mode) + (funcall mode 0))) + + (when (<= 24 emacs-major-version) + (electric-indent-mode -1)) + + (appt-activate +1) + (savehist-mode 1) + (midnight-mode +1) + + (quietly-read-abbrev-file) + + (global-undo-tree-mode 1) + (ace-window-display-mode +1) + (electric-pair-mode +1) + (electric-quote-mode +1) + (key-chord-mode +1) + + (size-indication-mode 1) + (display-battery-mode -1) + (sml/setup) + + (ivy-mode +1) + + (recentf-mode t) + (which-key-mode 1) + (winner-mode 1) + + (global-auto-revert-mode -1) + + (projectile-mode +1) + (which-function-mode +1) + ;; (semantic-mode +1) + (persp-mode +1) + + ;; setting this in `custom-file’ does not work, so we set it here + (custom-set-variables + '(custom-enabled-themes (quote (exot-main solarized-dark smart-mode-line-dark)))) + + ;; Hooks + + (add-hook 'minibuffer-setup-hook #'conditionally-enable-lispy) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) + (add-hook 'text-mode-hook #'turn-on-auto-fill) + (add-hook 'before-save-hook #'db/delete-trailing-whitespace-maybe) + (add-hook 'prog-mode-hook #'turn-on-page-break-lines-mode) + (when (<= 24 emacs-major-version) + (add-hook 'prog-mode-hook #'electric-indent-local-mode)) + (add-hook 'lisp-mode-hook #'lispy-mode) + + ;; Keybindings + + (bind-key "" #'winner-undo) + (bind-key "" #'winner-redo) + (bind-key "" #'db/run-or-hide-eshell) + (bind-key " i" #'counsel-info-lookup-symbol) + (bind-key " u" #'counsel-unicode-char) + (bind-key "" #'counsel-ag) + (bind-key "" #'hydra-zoom/body) + (bind-key "" #'dictcc) + (bind-key "" #'counsel-locate) + (bind-key "" #'counsel-org-goto-all) + (bind-key "" #'magit-status) + (bind-key "" nil) + (bind-key "" #'db/helm-shortcuts) + (bind-key "C-<" #'mc/mark-previous-like-this) + (bind-key "C->" #'mc/mark-next-like-this) + (bind-key "C-@" #'er/expand-region) + (bind-key "C-M-\\" #'crux-cleanup-buffer-or-region) + (bind-key "C-S-c C-S-c" #'mc/edit-lines) + (bind-key "C-Z" #'undo-tree-redo) + (bind-key "C-c C-<" #'mc/mark-all-like-this) + (bind-key "C-c C-r" #'ivy-resume) + (bind-key "C-c D" #'define-word) + (bind-key "C-c J" #'avy-goto-word-or-subword-1) + (bind-key "C-c P" #'ivy-pages) + (bind-key "C-c a" #'org-agenda) + (bind-key "C-c c" #'org-capture) + (bind-key "C-c d" #'define-word-at-point) + (bind-key "C-c e" #'crux-eval-and-replace) + (bind-key "C-c h #" #'helm-emms) + (bind-key "C-c h" #'helm-command-prefix) + (bind-key "C-c i" #'hydra-ispell/body) + (bind-key "C-c j" #'avy-goto-char-timer) + (bind-key "C-c l" #'org-store-link) + (bind-key "C-c m" #'emms-control/body) + (bind-key "C-c o" #'hydra-org-clock/body) + (bind-key "C-c s" #'synonyms) + (bind-key "C-h C-f" #'find-function) + (bind-key "C-h C-k" #'find-function-on-key) + (bind-key "C-h f" #'counsel-describe-function) + (bind-key "C-h v" #'counsel-describe-variable) + (bind-key "C-s" #'isearch-forward) + (bind-key "C-S-s" #'counsel-grep-or-swiper) + (bind-key "M-i" #'swiper-from-isearch isearch-mode-map) + (bind-key "C-x C-d" #'dired) + (bind-key "C-x C-f" #'counsel-find-file) + (bind-key "C-x C-r" #'revert-buffer) + (bind-key "C-x SPC" #'hydra-rectangle/body) + (bind-key "C-x o" #'ace-window) + (bind-key "C-x r v" #'list-registers) + (bind-key "C-x t" #'hydra-toggle/body) + (bind-key "C-z" #'undo) + (bind-key "M-/" #'hippie-expand) + (bind-key "M-:" #'pp-eval-expression) + (bind-key "M-=" #'count-words) + (bind-key "M-SPC" #'cycle-spacing) + (bind-key "M-Z" #'zap-to-char) + (bind-key "M-g M-g" #'avy-goto-line) + (bind-key "M-g g" #'avy-goto-line) + (bind-key "M-g j b" #'dumb-jump-back) + (bind-key "M-g j g" #'dumb-jump-go) + (bind-key "M-j" #'(lambda () (interactive) (join-line -1))) + (bind-key "M-o" nil) + (bind-key "M-x" #'counsel-M-x) ; gets nicer sorting with smex installed + (bind-key "M-y" #'helm-show-kill-ring) + (bind-key "M-z" #'zap-up-to-char) + (bind-key [insert] nil) + (bind-key [kp-insert] nil) + (bind-key [remap fill-paragraph] #'endless/fill-or-unfill) + (bind-key [remap kill-whole-line] #'crux-kill-whole-line) + (bind-key [remap open-line] #'crux-smart-open-line-above) + + ;; Timers + + (run-with-timer 0 3600 #'org-clock-save) + (run-with-timer 0 3600 #'recentf-save-list) + (run-with-timer 0 3600 #'bbdb-save) + (run-with-timer 0 3600 #'emms-cache-save) + (run-with-idle-timer 1200 t #'db/export-diary) + (run-at-time "00:01" 86400 #'db/org-agenda-to-appt) + + ;; Environment Variables + + (setenv "SSH_AUTH_SOCK" "/run/user/1000/ssh-agent.socket") + (setenv "SSH_AGENT_PID" + (substring (shell-command-to-string "systemctl show --user ssh-agent.service -p MainPID --value") + 0 -1)) + (setenv "PATH" (concat (concat (getenv "HOME") "/.local/bin") + ":" + (getenv "PATH"))) + (setq exec-path (append (list (concat (getenv "HOME") "/.local/bin")) + exec-path)) + (setenv "TEXMFHOME" (expand-file-name "~/Documents/texmf")) + + t) + +(add-hook 'after-init-hook #'db/run-init) + + +;; * Builtin Variables + +(use-package db-private + :load-path "site-lisp" + :defines (db/personal-mail-address + db/work-mail-address + db/jabber-id + db/smtp-accounts + db/work-gnus-filter-rules + db/personal-gnus-filter-rules)) + +(setq user-full-name "Daniel Borchmann" + user-mail-address db/personal-mail-address) + +(setq custom-file (expand-file-name "custom.el" emacs-d)) +(load-file custom-file) + +(use-package cl-lib) + +(use-package warnings + :config (cl-pushnew '(undo discard-info) warning-suppress-types + :test #'equal)) + +(set-default-coding-systems 'utf-8) +(prefer-coding-system 'utf-8) +(set-terminal-coding-system 'utf-8) +(set-keyboard-coding-system 'utf-8) +(setq buffer-file-coding-system 'utf-8) +(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) + +(setq inhibit-startup-message t + initial-scratch-message nil + initial-major-mode 'org-mode + ring-bell-function #'ignore + garbage-collection-messages nil + load-prefer-newer nil) ; t breaks `org-reload' + +(fset 'yes-or-no-p 'y-or-n-p) + +(setq-default fill-column 80) +(setq-default indent-tabs-mode nil) + +(setq frame-title-format "emacs") + +(setq select-enable-clipboard t + select-enable-primary t + save-interprogram-paste-before-kill t + mouse-yank-at-point t + require-final-newline nil + sentence-end-double-space t + recenter-positions '(top middle bottom) + scroll-conservatively 10 + message-log-max t + inhibit-eol-conversion nil + tab-always-indent 'complete + enable-recursive-minibuffers t + set-mark-command-repeat-pop t + large-file-warning-threshold 100000000 + echo-keystrokes 0.1 + delete-by-moving-to-trash t + delete-trailing-lines nil + x-underline-at-descent-line t + search-whitespace-regexp "[ \t\r\n]+" + apropos-sort-by-scores 'verbose) + +(setq-default cursor-type 'bar) + +;; don't let the cursor go into minibuffer prompt +(setq minibuffer-prompt-properties '(read-only t + face minibuffer-prompt + cursor-intangible t)) + +;; Make M-v undo C-v +(setq scroll-preserve-screen-position 'always) + +;; Backups and Autosave +(defvar backup-dir (expand-file-name "ebackup/" emacs-d)) +(defvar autosave-dir (expand-file-name "eautosave/" emacs-d)) +(setq make-backup-files t + backup-directory-alist (list (cons ".*" backup-dir)) + auto-save-list-file-prefix autosave-dir + auto-save-file-name-transforms `((".*" ,autosave-dir t)) + version-control t + kept-old-versions 2 + kept-new-versions 4 + delete-old-versions t + vc-make-backup-files t) + +(setq-default async-shell-command-buffer 'new-buffer) +(add-to-list 'display-buffer-alist + '("^\*Async Shell Command*" . (display-buffer-no-window))) + +(put 'set-goal-column 'disabled nil) +(put 'upcase-region 'disabled nil) +(put 'downcase-region 'disabled nil) +(put 'narrow-to-region 'disabled nil) + +(require 'time) +(require 'calendar) + +(setq display-time-24hr-format t + calendar-date-style 'iso + calendar-view-diary-initially-flag t + diary-show-holidays-flag nil + holiday-hebrew-holidays nil + holiday-islamic-holidays nil + holiday-bahai-holidays nil + holiday-oriental-holidays nil + holiday-solar-holidays nil + holiday-general-holidays nil + holiday-other-holidays '((holiday-fixed 5 1 "Labour Day") + (holiday-fixed 10 3 "German Unity Day") + (holiday-fixed 10 31 "Reformation Day") + (holiday-float 11 3 -1 "Day of Repentance and Prayer" 22))) + +(setq-default font-lock-maximum-decoration '((t . t))) +(setq-default savehist-file (expand-file-name "savehist" emacs-d)) + +(require 'tramp) +(setq tramp-save-ad-hoc-proxies t) + +(require 'bookmark) +(setq bookmark-default-file (concat user-emacs-directory "bookmarks")) + +(require 'browse-url) +(setq browse-url-browser-function 'browse-url-generic + browse-url-generic-program "start-tor-browser") + +(require 're-builder) +(setq reb-re-syntax 'string) + +(setq lisp-indent-function 'common-lisp-indent-function) + + +;; * Basic Builtin Packages + +(use-package misc + :commands (zap-up-to-char zap-to-char)) + +(use-package grep + :commands (rgrep zrgrep) + :config (progn + (bind-key "C-x C-q" #'wgrep-change-to-wgrep-mode grep-mode-map) + (bind-key "C-c C-c" #'wgrep-finish-edit grep-mode-map))) + +(use-package winner + :commands (winner-mode winner-undo winner-redo)) + +(use-package abbrev + :commands (quitely-read-abbrev-file) + :config (progn + (setq-default abbrev-mode t) + (setq save-abbrevs 'silently)) + :diminish abbrev-mode) + +(use-package appt + :commands (appt-activate) + :config (setq appt-display-mode-line nil)) + +(use-package ediff + :config (progn + (setq ediff-diff-options "-w" + ediff-window-setup-function 'ediff-setup-windows-plain + ediff-split-window-function 'split-window-horizontally) + + (add-hook 'ediff-keymap-setup-hook + '(lambda () + (bind-key "j" 'ediff-next-difference ediff-mode-map) + (bind-key "k" 'ediff-previous-difference ediff-mode-map))) + + (add-hook 'ediff-after-quit-hook-internal 'winner-undo))) + +(use-package ispell + :commands (ispell-change-directory) + :init (progn + (setq ispell-dictionary "en_US" + ispell-really-hunspell t))) + +(use-package mailcap + :config (progn + ;;Remove doc-view so pdf will open with ocular + (setcdr + (assoc "application" mailcap-mime-data) + (remove '("pdf" + (viewer . doc-view-mode) + (type . "application/pdf") + (test eq window-system 'x)) + (cdr (assoc "application" mailcap-mime-data)))))) + +(use-package quail + :defer t + :config (progn + (defun db/add-symbols-to-TeX-input-method () + (when (string= current-input-method "TeX") + (let ((quail-current-package (assoc "TeX" quail-package-alist))) + (quail-define-rules + ((append . t)) + ("\\land" ?∧) + ("\\lor" ?∨) + ("\\lnot" ?¬) + ("\\implies" ?⇒) + ("\\powerset" ?𝔓) + ("\\mathbbK" ?𝕂) + ("\\mathbbR" ?ℝ) + ("\\mathbbN" ?ℕ) + ("\\mathbbZ" ?ℤ) + ("\\mathbbP" ?ℙ) + ("\\mathcalA" ?𝒜) + ("\\mathcalB" ?ℬ) + ("\\mathcalC" ?𝒞) + ("\\mathcalD" ?𝒟) + ("\\mathcalE" ?ℰ) + ("\\mathcalH" ?ℋ) + ("\\mathcalI" ?ℐ) + ("\\mathcalJ" ?𝒥) + ("\\mathcalK" ?𝒦) + ("\\mathcalL" ?ℒ) + ("\\mathcalM" ?ℳ) + ("\\mathcalR" ?ℛ) + ("\\mathcalQ" ?𝒬) + ("\\mathcalS" ?𝒮) + ("\\mathfrakP" ?𝔓))))) + (add-hook 'input-method-activate-hook + #'db/add-symbols-to-TeX-input-method))) + + +;; * Org Mode + +(use-package org + :mode (("\\.org\\'" . org-mode)) + :commands (org-agenda + org-capture + org-store-link + db/export-diary + org-clock-save + db/org-agenda-to-appt + hydra-org-clock/body) + :config (progn + (bind-key [remap org-return] 'org-return-indent org-mode-map) + + (use-package db-org + :load-path "site-lisp") + + ;; avoid important buffers to end up in `org-agenda-new-buffers’ by + ;; opening them manually + (mapc #'find-file-noselect org-agenda-files) + + (org-clock-persistence-insinuate) + + (require 'hydra) + + (defhydra hydra-org-clock (:color blue) + " +Current Task: %`org-clock-current-task; " + ("w" (lambda () + (interactive) + (clock-in-task-by-id org-working-task-id))) + ("h" (lambda () + (interactive) + (clock-in-task-by-id org-home-task-id))) + ("b" (lambda () + (interactive) + (clock-in-task-by-id org-break-task-id))) + ("i" (lambda () + (interactive) + (org-clock-in '(4)))) + ("a" counsel-org-goto-all) + ("o" org-clock-out) + ("l" db/org-clock-in-last-task) + ("p" db/play-playlist) + ("d" (lambda () + (interactive) + (when (org-clock-is-active) + (save-window-excursion + (org-clock-goto) + (let ((org-inhibit-logging 'note)) + (org-todo 'done) + (org-save-all-org-buffers))))))))) + +(use-package org-ref + :config (progn + (require 'org-ref-pdf) + (require 'org-ref-url-utils) + + (setq org-ref-default-bibliography '("~/Documents/uni/research/references.bib") + org-ref-pdf-directory "~/Documents/library/.bibtex-pdfs/" + org-ref-bibliography-notes "~/Documents/uni/research/references.org"))) + + +;; * Some essential packages + +(use-package crux + :commands (crux-eval-and-replace + crux-smart-open-line-above + crux-kill-whole-line + crux-cleanup-buffer-or-region)) + +(use-package db-utils + :load-path "site-lisp/" + :commands (endless/fill-or-unfill + db/delete-trailing-whitespace-maybe + db/go-dark + db/go-light + db/show-current-org-task + db/run-or-hide-shell + db/run-or-hide-eshell + db/run-or-hide-ansi-term + db/helm-shortcuts)) + +(use-package db-emacsclient + :load-path "site-lisp/") + +(use-package hydra + :commands (defhydra hydra-toggle/body hydra-zoom/body hydra-rectangle/body hydra-ispell/body) + :config (progn + (defhydra hydra-toggle (:color blue) + "toggle" + ("c" column-number-mode "column") + ("d" toggle-debug-on-error "debug-on-error") + ("e" toggle-debug-on-error "debug-on-error") + ("f" auto-fill-mode "auto-fill") + ("l" toggle-truncate-lines "truncate lines") + ("q" toggle-debug-on-quit "debug-on-quit") + ("r" read-only-mode "read-only")) + + ;; zooming with single keystrokes (from oremacs) + (defhydra hydra-zoom (:color red) + "zoom" + ("g" text-scale-increase "increase") + ("l" text-scale-decrease "decrease")) + + ;; rectangle mode + (defhydra hydra-rectangle (:body-pre (rectangle-mark-mode 1) + :color pink + :post (deactivate-mark)) + " + ^_k_^ _d_elete _s_tring +_h_ _l_ _o_k _y_ank + ^_j_^ _n_ew-copy _r_eset +^^^^ _e_xchange _u_ndo +^^^^ ^ ^ _p_aste +" + ("h" backward-char nil) + ("l" forward-char nil) + ("k" previous-line nil) + ("j" next-line nil) + ("e" ora-ex-point-mark nil) + ("n" copy-rectangle-as-kill nil) + ("d" delete-rectangle nil) + ("r" (if (region-active-p) + (deactivate-mark) + (rectangle-mark-mode 1)) + nil) + ("y" yank-rectangle nil) + ("u" undo nil) + ("s" string-rectangle nil) + ("p" kill-rectangle nil) + ("o" nil nil)) + + (defhydra hydra-ispell (:color blue) + "ispell" + ("g" (lambda () + (interactive) + (setq ispell-dictionary "de_DE") + (ispell-change-dictionary "de_DE")) + "german") + ("e" (lambda () + (interactive) + (setq ispell-dictionary "en_US") + (ispell-change-dictionary "en_US")) + "english")))) + +(use-package magit + :ensure magit + :commands (magit-status) + :config (progn + (setq magit-diff-refine-hunk t + magit-commit-show-diff nil + magit-popup-use-prefix-argument 'default) + + (add-to-list 'magit-no-confirm 'stage-all-changes) + + (setq magit-repository-directories + (mapcar + (lambda (dir) + (substring dir 0 -1)) + (cl-remove-if-not + (lambda (project) + (unless (file-remote-p project) + (file-exists-p (concat project "/.git")))) + (projectile-relevant-known-projects)))))) + +(use-package projectile + :ensure projectile + :commands (projectile-relevant-known-projects projectile-mode) + :config (progn + (setq projectile-switch-project-action 'projectile-dired + projectile-completion-system 'ivy)) + :diminish projectile-mode) + +(use-package perspective + :commands (persp-mode)) + + +;; * Mail + +(use-package bbdb + :ensure bbdb + :commands (bbdb-search-name bbab-initialize bbdb-mua-auto-update-init bbdb-save) + :config (progn + (setq bbdb-completion-display-record nil + bbdb-complete-mail-allow-cycling t + bbdb-mua-auto-update-p 'query + bbdb-default-country "Germany" + bbdb-user-mail-address-re (regexp-opt (list db/personal-mail-address + db/work-mail-address))) + (add-hook 'message-setup-hook 'bbdb-mail-aliases) + (add-hook 'mail-setup-hook 'bbdb-mail-aliases))) + +(use-package gnus + :defines (gnus-init-file) + :commands (gnus) + :init (setq gnus-group-update-tool-bar nil) + :config (progn + (bbdb-initialize 'gnus 'message) + (bbdb-mua-auto-update-init 'message) + (setq gnus-init-file (expand-file-name "gnus" emacs-d) + gnus-home-directory (expand-file-name "~/Mail/news/") + gnus-directory (expand-file-name "~/Mail/news/") + gnus-kill-files-directory gnus-directory + gnus-startup-file (expand-file-name "~/Mail/gnus-newsrc") + gnus-cache-directory (expand-file-name "cache/" gnus-directory)))) + + +;; * Crypto + +(use-package nsm + :config (progn (setq network-security-level 'medium + nsm-save-host-names t))) + +(use-package gnutls + :config (progn + (setq gnutls-log-level 0 + gnutls-min-prime-bits 1024 + gnutls-verify-error t) + + ;; add own trustfiles + (dolist (cert-file + (directory-files "~/.local/etc/certs" t "\.crt$")) + (add-to-list 'gnutls-trustfiles cert-file)))) + +(use-package epg + :config (progn + (setq epg-program "/usr/bin/gpg2" + epg-debug t))) + + +;; * Appearance + +(use-package solarized-theme + :init (setq solarized-use-less-bold t + solarized-emphasize-indicators t + solarized-use-variable-pitch nil)) + +(use-package smart-mode-line + :init (setq sml/use-projectile-p t)) + + +;; * Dired + +(use-package dired + :config (progn + (setq dired-dwim-target t) + (put 'dired-find-alternate-file 'disabled nil) + (setq dired-listing-switches "-alLh") + (setq dired-hide-details-hide-information-lines nil) + + (setq dired-recursive-copies 'top) + (setq dired-recursive-deletes 'top) + + (require 'dired-x) + (require 'gnus-dired) + + (add-hook 'dired-mode-hook #'turn-on-gnus-dired-mode) + (add-hook 'dired-mode-hook #'dired-omit-mode) + + (setq dired-omit-files "^\\...+$" + dired-omit-verbose nil + dired-omit-extensions nil) + + (setq dired-guess-shell-alist-user + '(("\\.pdf\\'" "evince") + ("\\.ps\\'" "evince") + ("\\.\\(?:djvu\\|eps\\)\\'" "evince") + ("\\.\\(?:jpg\\|jpeg\\|png\\|gif\\|xpm\\)\\'" "geeqie") + ("\\.\\(?:xcf\\)\\'" "gimp") + ("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\|ogv\\)\\(?:\\.part\\)?\\'" + "vlc") + ("\\.\\(?:mp3\\|flac\\|ogg\\)\\'" "mplayer") + ("\\.html?\\'" "firefox") + ("\\.docx?\\'" "loffice"))) + + (unbind-key "C-M-o" dired-mode-map) + + (require 'dired+) + (setq diredp-hide-details-initially-flag nil) + + ;; disable exaggerated fontification of dired+ + (require 'font-lock) + (add-to-list 'font-lock-maximum-decoration '(wdired-mode . 1)) + (add-to-list 'font-lock-maximum-decoration '(dired-mode . 1)) + + ;; https://oremacs.com/2017/03/18/dired-ediff/ + + (defun ora-ediff-files () + (interactive) + (lexical-let ((files (dired-get-marked-files)) + (wnd (current-window-configuration))) + (if (<= (length files) 2) + (lexical-let ((file1 (car files)) + (file2 (if (cdr files) + (cadr files) + (read-file-name + "file: " + (dired-dwim-target-directory))))) + (if (file-newer-than-file-p file1 file2) + (ediff-files file2 file1) + (ediff-files file1 file2)) + (add-hook 'ediff-after-quit-hook-internal + (lambda () + (setq ediff-after-quit-hook-internal nil) + (set-window-configuration wnd)))) + (error "no more than 2 files should be marked")))) + + (require 'dired-quick-sort) + (dired-quick-sort-setup) + + (bind-key [remap beginning-of-buffer] + #'dired-back-to-top dired-mode-map) + (bind-key [remap end-of-buffer] + #'dired-jump-to-bottom dired-mode-map) + (bind-key "z" 'dired-get-size dired-mode-map) + (unbind-key "s" dired-mode-map) + (unbind-key "" dired-mode-map) + (bind-key "e" #'ora-ediff-files dired-mode-map) + + )) + +(use-package find-dired + :commands (find-dired) + :config (setq find-ls-option '("-print0 | xargs -0 ls -ld" . "-ld"))) + + +;; * Completion + +(use-package hippie-exp + :commands (hippie-expand)) + +(use-package helm + :commands (helm-command-prefix + helm-show-kill-ring) + :ensure helm + :pin "melpa-stable" + :diminish helm-mode + :defines (helm-command-prefix-key + helm-command-prefix + helm-command-map + helm-completing-read-handlers-alist) + :init (require 'helm-config) + :config (progn + (setq helm-input-idle-delay 0.0 + helm-M-x-fuzzy-match t + helm-M-x-requires-pattern nil + helm-buffers-fuzzy-matching t + helm-recentf-fuzzy-match t + helm-mode-fuzzy-match t + helm-autoresize-min-height 20 + helm-ff-auto-update-initial-value t + helm-ff-file-name-history-use-recentf t + helm-ff-search-library-in-sexp t + helm-ff-skip-boring-files nil + helm-split-window-in-side-p t + helm-move-to-line-cycle-in-source nil + helm-scroll-amount nil + helm-locate-command nil + helm-candidate-number-limit 100 + helm-follow-mode-persistent t + helm-buffer-details-flag t + helm-buffer-skip-remote-checking t) + + (unbind-key helm-command-prefix-key) + + (bind-key "" 'helm-execute-persistent-action helm-map) + (bind-key "C-i" 'helm-execute-persistent-action helm-map) + (bind-key "C-z" 'helm-select-action helm-map) + + (require 'db-utils) + + (setq helm-mini-default-sources '(helm-source-buffers-list + helm-source-recentf + db/helm-frequently-used-features + db/helm-frequently-visited-locations + helm-source-buffer-not-found + helm-source-bookmarks + helm-source-bookmark-set)) + + )) + +(use-package ivy + :commands (ivy-mode + ivy-resume) + :diminish ivy-mode + :config (setq ivy-use-virtual-buffers t + enable-recursive-minibuffers t)) + +(use-package counsel + :commands (counsel-org-goto-all + counsel-ag + counsel-M-x + counsel-find-file + counsel-info-lookup-symbol + counsel-unicode-char + counsel-describe-variable + counsel-describe-function)) + +(use-package swiper + :commands (swiper)) + +(use-package recentf + :commands (recentf-mode recentf-save-list) + :init (setq recentf-max-saved-items 20)) + +(use-package company + :commands (company-mode global-company-mode)) + + +;; * Navigation + +(use-package ace-window + :ensure t + :commands (ace-window ace-window-display-mode) + :demand t + :config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l) + aw-background nil + aw-leading-char-style 'char + aw-scope 'frame)) +(use-package avy + :commands (avy-goto-char-timer + avy-goto-word-or-subword-1 + avy-goto-line)) + +(use-package dumb-jump + :commands (dumb-jump-go-other-window + dumb-jump-go + dumb-jump-back + dumb-jump-quick-look + dumb-jump-go-prefer-external + dumb-jump-go-prefer-external-other-window) + :config (setq dumb-jump-selector 'helm)) + + +;; * EMMS + +(use-package emms + :ensure t + :commands (emms + emms-stream-init + db/play-playlist + emms-cache-save + emms-play-directory-tree + emms-control/body) + :defines (emms-playlist-mode-map) + :config (progn + + (require 'emms-setup) + + (emms-all) + (emms-default-players) + + (setq emms-source-file-default-directory "~/Documents/media/audio/") + + (defadvice emms-tag-editor-submit (after delete-window activate) + (delete-window)) + + (bind-key "S s" #'emms-shuffle emms-playlist-mode-map) + + (add-hook 'emms-player-started-hook 'emms-show) + (setq emms-show-format "NP: %s") + + (emms-mode-line -1) + (emms-playing-time-enable-display) + (setq emms-player-list + '(emms-player-mplayer emms-player-mplayer-playlist)) + + (defun db/play-playlist () + (interactive) + (save-window-excursion + (let ((music-buffer-name "*EMMS Playlist* -- Misc")) + (unless (get-buffer music-buffer-name) + (emms-playlist-new music-buffer-name)) + (with-current-buffer (get-buffer music-buffer-name) + (emms-stop) + (emms-playlist-set-playlist-buffer) + (emms-playlist-current-clear) + (emms-playlist-current-insert-source + 'emms-insert-playlist + "~/Documents/home/misc/playlist-daniel.pls") + (beginning-of-buffer) + (emms-shuffle) + ;; (emms-playlist-sort-by-play-count) + (emms-playlist-select-first) + (emms-start))))) + + ;; adapt track description + (defun db/emms-track-description (track) + (require 'seq) + (let* ((artist (propertize (emms-track-get track 'info-artist "") + 'face 'emms-browser-artist-face)) + (composer (propertize (emms-track-get track 'info-composer "") + 'face 'emms-browser-composer-face)) + (performer (propertize (emms-track-get track 'info-performer "") + 'face 'emms-browser-performer-face)) + (title (propertize (emms-track-get track 'info-title "") + 'face 'emms-browser-track-face)) + (note (emms-track-get track 'info-note ""))) + (let ((main-description (if (not (seq-empty-p title)) + (cond + ((and (not (seq-empty-p composer)) + (not (seq-empty-p performer))) + (if (string= composer performer) + (format "“%s” by %s" + title composer) + (format "“%s” by %s, performed by %s" + title + composer + performer))) + ((not (seq-empty-p artist)) + (format "“%s” by %s" title artist)) + (t title)) + (emms-track-simple-description track))) + (note (if (seq-empty-p note) + "" + (concat " [" note "]")))) + (concat main-description note)))) + + (setq emms-track-description-function + 'db/emms-track-description) + + ;; don't set face in playlist to emms-playlist-track-face + (defun db/emms-playlist-mode-insert-track (track &optional no-newline) + "Insert the description of TRACK at point. +When NO-NEWLINE is non-nil, do not insert a newline after the track." + (emms-playlist-ensure-playlist-buffer) + (emms-with-inhibit-read-only-t + (insert (emms-propertize (emms-track-force-description track) + 'emms-track track + ;'face 'emms-playlist-track-face + )) + (when (emms-playlist-selected-track-at-p) + (emms-playlist-mode-overlay-selected)) + (unless no-newline + (insert "\n")))) + + (add-hook 'emms-playlist-mode-hook + (lambda () + (setq emms-playlist-insert-track-function + #'db/emms-playlist-mode-insert-track))) + + ;; streams + (require 'emms-stream-info) + (setq emms-stream-default-action "play") + + (defun db/emms-track-status () + (if emms-player-playing-p + (format "%s" (emms-track-description + (emms-playlist-current-selected-track))) + "«nothing»")) + + ;; easy control + (defhydra emms-control (:color red :hint none) + " +Playing: %s(db/emms-track-status) + + _n_: ?n? _p_: ?p? +_RET_: ?RET? _M_: ?M? + _-_: lower volume _+_: ?+? + +" + ("n" emms-next "next") + ("p" emms-previous "previous") + ("RET" emms-pause "play/pause") + ("s" emms-show "show title") + ("-" emms-volume-lower "lower volume") + ("+" emms-volume-raise "raise volume") + ("M" emms "show playlist")) + + t)) + +(use-package helm-emms + :commands (helm-emms) + :config (setq helm-emms-default-sources + '(helm-source-emms-streams + helm-source-emms-dired + helm-source-emms-files))) + + +;; * Shells and such + +(use-package comint + :config (progn + (setq comint-scroll-to-bottom-on-input t) + (setq comint-scroll-to-bottom-on-output nil) + (setq comint-scroll-show-maximum-output t) + (setq comint-completion-addsuffix t) + (setq comint-buffer-maximum-size 100000) + (setq comint-input-ring-size 5000))) + +(use-package term + :commands (term-send-string) + :config (progn + (add-hook 'term-exec-hook ; oremacs.com + (lambda () + (let* ((buff (current-buffer)) + (proc (get-buffer-process buff))) + (set-process-sentinel + proc + `(lambda (process event) + (if (string= event "finished\n") + (kill-buffer ,buff))))))) + + ;; does not work; C-c is shadowed by some minor modes like semantic, + ;; projectile, and winner + (bind-key "C-c" 'term-send-raw term-raw-map) + + ;; unbind some keys to allow the global keymap to handle them + (unbind-key "M-:" term-raw-map) + (unbind-key "C-h" term-raw-map) + (unbind-key "M-x" term-raw-map) + (unbind-key "M-o" term-raw-map) + + ;; we need to set keys starting with C-x after `ansi-term' has been + ;; called, as it resets the escape character to C-x. + (defadvice ansi-term (after ansi-term-set-keys activate) + (unbind-key "C-x C-j" term-raw-map) + (unbind-key "C-x g" term-raw-map)))) + +(use-package ansi-color + :commands (ansi-color-for-comint-mode-on) + :config (progn + ;; http://endlessparentheses.com/ansi-colors-in-the-compilation-buffer-output.html + (defun endless/colorize-compilation () + "Colorize from `compilation-filter-start' to `point'." + (let ((inhibit-read-only t)) + (ansi-color-apply-on-region compilation-filter-start (point)))) + + (add-hook 'compilation-filter-hook #'endless/colorize-compilation))) + +(use-package shell + :init (setq explicit-shell-file-name "/usr/bin/zsh") + :config (progn + (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) + (add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m))) + +(use-package eshell + :commands (eshell) + :config (progn + + (require 'em-prompt) + (require 'em-term) + (require 'em-cmpl) + + (setq eshell-cmpl-cycle-completions nil + eshell-save-history-on-exit t + eshell-scroll-to-bottom-on-input t + eshell-prefer-lisp-functions nil) + + (setenv "PAGER" "cat") + + (defun eshell-clear-buffer () + "Clear terminal." + (interactive) + (let ((inhibit-read-only t)) + (erase-buffer) + (eshell-send-input))) + + ;; eshell is a bit strange and sets up its mode map as a local map; + ;; because of this we need to put key definitions into a hook + (add-hook 'eshell-mode-hook + (lambda () + (bind-key "C-a" #'eshell-bol eshell-mode-map) + (bind-key "C-l" #'eshell-clear-buffer eshell-mode-map))) + + (add-to-list 'eshell-command-completions-alist + '("gunzip" "gz\\'")) + + (add-to-list 'eshell-command-completions-alist + '("tar" "\\(\\.tar|\\.tgz\\|\\.tar\\.gz\\)\\'")) + + (setq eshell-prompt-function + (lambda () + (concat + "[" (user-login-name) + "@" (getenv "HOST") + ":" (abbreviate-file-name (eshell/pwd)) + "]\n→ ")) + eshell-prompt-regexp + "^→ ") + + (add-hook 'eshell-mode-hook + (lambda () + (add-hook 'eshell-output-filter-functions 'eshell-truncate-buffer))) + + ;; Git Completion + ;; https://tsdh.wordpress.com/2013/05/31/eshell-completion-for-git-bzr-and-hg/ + + (require 'pcomplete) + + (defun pcmpl-git-commands () + "Return the most common git commands by parsing the git output." + (with-temp-buffer + (call-process "git" nil (current-buffer) nil "help" "--all") + (goto-char 0) + (search-forward "available git commands in") + (let (commands) + (while (re-search-forward + "^[[:blank:]]+\\([[:word:]-.]+\\)[[:blank:]]*\\([[:word:]-.]+\\)?" + nil t) + (push (match-string 1) commands) + (when (match-string 2) + (push (match-string 2) commands))) + (sort commands #'string<)))) + + (defconst pcmpl-git-commands (pcmpl-git-commands) + "List of `git' commands.") + + (defvar pcmpl-git-ref-list-cmd "git for-each-ref refs/ --format='%(refname)'" + "The `git' command to run to get a list of refs.") + + (defun pcmpl-git-get-refs (type) + "Return a list of `git' refs filtered by TYPE." + (with-temp-buffer + (insert (shell-command-to-string pcmpl-git-ref-list-cmd)) + (goto-char (point-min)) + (let (refs) + (while (re-search-forward (concat "^refs/" type "/\\(.+\\)$") nil t) + (push (match-string 1) refs)) + (nreverse refs)))) + + (defun pcmpl-git-remotes () + "Return a list of remote repositories." + (split-string (shell-command-to-string "git remote"))) + + (defun pcomplete/git () + "Completion for `git'." + ;; Completion for the command argument. + (pcomplete-here* pcmpl-git-commands) + (cond + ((pcomplete-match "help" 1) + (pcomplete-here* pcmpl-git-commands)) + ((pcomplete-match (regexp-opt '("pull" "push")) 1) + (pcomplete-here (pcmpl-git-remotes))) + ;; provide branch completion for the command `checkout'. + ((pcomplete-match (regexp-opt '("checkout" "co")) 1) + (pcomplete-here* (append (pcmpl-git-get-refs "heads") + (pcmpl-git-get-refs "tags")))) + (t + (while (pcomplete-here (pcomplete-entries)))))))) + + +;; * Lisp + +;; General Stuff first + +(use-package lispy + ;; note: this will load org-mode + :commands (lispy-mode conditionally-enable-lispy) + :diminish lispy-mode + :config (progn + (defun conditionally-enable-lispy () + (when (or (eq this-command 'eval-expression) + (eq this-command 'pp-eval-expression)) + (lispy-mode 1))))) + +(use-package eldoc + :commands (eldoc-mode) + :diminish eldoc-mode) + +;; Lisp Dialects + +(use-package elisp-mode + :config (progn (add-hook 'emacs-lisp-mode-hook #'lispy-mode) + + (defun db/add-use-package-to-imenu () + (add-to-list 'imenu-generic-expression + '("Used Packages" + "\\(^\\s-*(use-package +\\)\\(\\_<.+\\_>\\)" + 2))) + (add-hook 'emacs-lisp-mode-hook #'db/add-use-package-to-imenu) + + (add-hook 'ielm-mode-hook #'eldoc-mode) + (add-hook 'emacs-lisp-mode-hook #'eldoc-mode))) + +(use-package geiser + :commands (geiser-mode)) + +(use-package cider + :commands (cider-jack-in) + :config (progn + (setq nrepl-hide-special-buffers t + cider-auto-select-error-buffer t + cider-stacktrace-default-filters '(tooling dup) + cider-stacktrace-fill-column 80 + cider-prompt-save-file-on-load nil + cider-repl-result-prefix ";; => " + cider-repl-use-clojure-font-lock t + cider-repl-wrap-history t + cider-repl-history-size 1000 + ;;cider-lein-parameters "trampoline repl :headless" + cider-lein-parameters "repl :headless" + cider-repl-history-file (expand-file-name ".cider-history" emacs-d) + cider-repl-display-help-banner nil) + + (add-hook 'cider-repl-mode-hook #'subword-mode) + (add-hook 'cider-repl-mode-hook #'lispy-mode) + (add-hook 'cider-repl-mode-hook #'cider-repl-toggle-pretty-printing) + (add-hook 'cider-mode-hook #'eldoc-mode) + + (setq cider-cljs-lein-repl "(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))"))) + +(use-package clojure-mode + :mode (("\\.clj\\'" . clojure-mode)) + :config (progn (define-clojure-indent + (forall 'defun) + (exists 'defun) + (dopar 'defun)) + (add-hook 'clojure-mode-hook #'lispy-mode) + (add-hook 'clojure-mode-hook #'clj-refactor-mode) + (add-hook 'clojure-mode-hook #'yas-minor-mode))) + +(use-package clj-refactor + :commands (clj-refactor-mode) + :config (progn + (cljr-add-keybindings-with-prefix "C-c C-m") + (setq cljr-eagerly-build-asts-on-startup nil + cljr-warn-on-eval nil))) + +(use-package slime + :commands (slime slime-mode slime-connect) + :mode (("\\.cl\\'" . lisp-mode) + ("\\.lisp\\'" . lisp-mode)) + :init (progn + (setq inferior-lisp-program "sbcl --noinform --no-linedit") + (add-hook 'lisp-mode-hook '(lambda () (slime-mode +1)) t)) + :config (progn + (setq slime-compile-file-options '(:fasl-directory "/tmp/slime-fasls/")) + (make-directory "/tmp/slime-fasls/" t) + + (slime-setup '(slime-repl slime-fancy slime-autodoc)) + + (setq slime-net-coding-system 'utf-8-unix + slime-completion-at-point-functions 'slime-fuzzy-complete-symbol) + (add-hook 'slime-mode-hook 'slime-redirect-inferior-output) + + (defun db/slime-reload () + (interactive) + (mapc 'load-library + (reverse (cl-remove-if-not + (lambda (feature) (string-prefix-p "slime" feature)) + (mapcar 'symbol-name features)))) + (setq slime-protocol-version (slime-changelog-date)) + (load-slime)) + + (setq slime-lisp-implementations + '((sbcl ("sbcl") :coding-system utf-8-unix) + (cmucl ("cmucl") :coding-system utf-8-unix) + (ccl ("ccl") :coding-system utf-8-unix))) + + (setq slime-repl-history-remove-duplicates t + slime-repl-history-trim-whitespaces t))) + +(use-package hy-mode + :commands (hy-mode org-babel-execute:hy) + :config (progn + (add-hook 'hy-mode-hook #'lispy-mode) + (add-hook 'hy-mode-hook #'inferior-lisp) + + (defun org-babel-execute:hy (body params) + ;; http://kitchingroup.cheme.cmu.edu/blog/2016/03/30/OMG-A-Lisp-that-runs-python/ + (let* ((temporary-file-directory ".") + (tempfile (make-temp-file "hy-"))) + (with-temp-file tempfile + (insert body)) + (unwind-protect + (shell-command-to-string + (format "hy %s" tempfile)) + (delete-file tempfile)))))) + + +;; * TeX + +(use-package reftex + :commands (turn-on-reftex) + :init (add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode + :config (progn + (eval-after-load 'helm-mode + '(add-to-list 'helm-completing-read-handlers-alist '(reftex-citation . nil))) + (setq reftex-plug-into-AUCTeX t) + (setq reftex-default-bibliography + '("~/Documents/uni/research/references.bib")))) + +(use-package tex + :ensure auctex + :mode ("\\.tex\\'" . TeX-mode) + :init (progn + (dolist (extension '(".out" ".synctex.gz" ".thm")) + (add-to-list 'completion-ignored-extensions extension))) + :config (progn + (require 'latex) + (require 'tex-buf) + (require 'reftex) + + (TeX-engine-set 'default) + + (setq-default TeX-auto-save t + TeX-save-query nil + TeX-parse-self t + TeX-master t + TeX-electric-sub-and-superscript t + TeX-electric-math '("$" . "$") + TeX-electric-escape nil + LaTeX-electric-left-right-brace t + LaTeX-fill-break-at-separators nil) + + (add-hook 'LaTeX-mode-hook #'turn-on-flyspell) + (add-hook 'LaTeX-mode-hook #'turn-on-visual-line-mode) + (add-hook 'LaTeX-mode-hook #'LaTeX-math-mode) + (add-hook 'LaTeX-mode-hook #'outline-minor-mode) + (add-hook 'LaTeX-mode-hook #'turn-on-page-break-lines-mode) + (add-hook 'LaTeX-mode-hook #'turn-on-reftex) + + (put 'TeX-narrow-to-group 'disabled nil) + (put 'LaTeX-narrow-to-environment 'disabled nil) + + (setq TeX-fold-math-spec-list '(("≤" ("le")) + ("≥" ("ge")) + ("∉" ("notin")))) + + (setq TeX-source-correlate-start-server nil) + + (setq LaTeX-eqnarray-label "eqn:" + LaTeX-equation-label "eqn:" + LaTeX-figure-label "fig:" + LaTeX-table-label "tab:" + TeX-newline-function 'reindent-then-newline-and-indent + LaTeX-section-hook '(LaTeX-section-heading + LaTeX-section-title + LaTeX-section-section + LaTeX-section-label)) + + (add-hook 'LaTeX-mode-hook '(lambda () + (TeX-PDF-mode 1) + (TeX-source-correlate-mode 1) + (TeX-fold-mode 1))) + + ;; Use pdf-tools + (eval-after-load 'pdf-tools + `(progn + (add-to-list 'TeX-view-program-selection '(output-pdf "PDF Tools")) + (add-to-list 'TeX-after-compilation-finished-functions + #'TeX-revert-document-buffer))) + + + ;; Printer + (add-to-list 'TeX-printer-list '("Remote" "lp-remote %o" "ssh lat lpstat -o")) + (setq TeX-printer-default "Remote") + + (TeX-add-style-hook + "mydefs" + (lambda () + (TeX-run-style-hooks "etex" + "etoolbox" + "ifthen" + "amsmath" + "amssymb" + "latexsym" + "mathabx" + "stmaryrd" + "verbatim" + "graphicx" + "enumerate" + "array" + "booktabs" + "ulem" + "nicefrac" + "listings" + "microtype" + "tabularx" + "tikz" + "csquotes" + "ntheorem" + "xspace") + (LaTeX-add-environments + '("Exercise" LaTeX-env-label) + '("Theorem" LaTeX-env-label) + '("Proposition" LaTeX-env-label) + '("Lemma" LaTeX-env-label) + '("Corollary" LaTeX-env-label) + '("Remark" LaTeX-env-label) + '("Example" LaTeX-env-label) + '("Definition" LaTeX-env-label) + '("Proof" LaTeX-env-label)) + + ;; https://tex.stackexchange.com/questions/217799/auctex-11-88-bug-on-latex-env-label-cannot-automatically-insert-label + (setf (cadr reftex-insert-label-flags) + (concat (cadr reftex-insert-label-flags) "TLPDRCE")) + + (dolist (label-spec '(("Theorem" ?T "thm:" "~\\ref{%s}" t ("Theorem" "Thm.") nil) + ("Lemma" ?L "lem:" "~\\ref{%s}" t ("Lemma" "Lem.") nil) + ("Proposition" ?P "prop:" "~\\ref{%s}" t ("Proposition" "Prop.") nil) + ("Satz" ?T "thm:" "~\\ref{%s}" t ("Satz") nil) + ("Definition" ?D "def:" "~\\ref{%s}" t ("Definition" "Def.") nil) + ("Remark" ?R "rem:" "~\\ref{%s}" t ("Remark" "Rem.") nil) + ("Corollary" ?C "cor:" "~\\ref{%s}" t ("Corollary" "Cor.") nil) + ("Example" ?E "expl:" "~\\ref{%s}" t ("Example") nil))) + (add-to-list 'reftex-label-alist label-spec) + (add-to-list 'LaTeX-label-alist (cons (nth 0 label-spec) + (nth 2 label-spec)))))) + + (TeX-add-style-hook + "cleveref" + (lambda () + (add-to-list 'reftex-ref-style-alist + '("Cleveref" "cleveref" + (("\\cref" ?c) ("\\Cref" ?C) + ("\\cpageref" ?d) ("\\Cpageref" ?D)))) + (reftex-ref-style-activate "Cleveref") + (TeX-add-symbols + '("cref" TeX-arg-ref) + '("Cref" TeX-arg-ref) + '("cpageref" TeX-arg-ref) + '("Cpageref" TeX-arg-ref)))) + + (add-hook 'TeX-language-de-hook + (lambda () (ispell-change-dictionary "de_DE"))) + + (add-hook 'TeX-language-en-hook + (lambda () (ispell-change-dictionary "en_US"))) + + ;; LaTeXMk + (when (require 'auctex-latexmk nil 'no-error) + (auctex-latexmk-setup) + (setq auctex-latexmk-inherit-TeX-PDF-mode t)))) + +(use-package ebib + :commands (ebib)) + +(use-package helm-bibtex + :commands (helm-bibtex) + :config (progn + (setq bibtex-completion-bibliography "~/Documents/uni/research/references.bib" + bibtex-completion-library-path "~/Documents/library/.bibtex-pdfs/" + bibtex-completion-notes-path "~/Documents/uni/research/references.org"))) + + +;; * Various Mode Configurations + +;; These are packages that are not essential, but still nice to have. They +;; provide optional functionality and may redefine builtin commands. + +(use-package define-word + :commands (define-word-at-point define-word)) + +(use-package dictcc + :commands (dictcc)) + +(use-package edit-list + :commands edit-list) + +(use-package electric + :commands (electric-quote-mode)) + +(use-package elec-pair + :commands (electric-pair-mode) + :config (progn + (add-to-list 'electric-pair-pairs '(?“ . ?”)) + (add-to-list 'electric-pair-text-pairs '(?“ . ?”)) + (add-to-list 'electric-pair-pairs '(?„ . ?“)) + (add-to-list 'electric-pair-text-pairs '(?„ . ?“)))) + +(use-package expand-region + :commands (er/expand-region)) + +(use-package flycheck + :commands (global-flycheck-mode flycheck-mode)) + +(use-package flyspell + :commands (flyspell-mode turn-on-flyspell) + :init (add-hook 'text-mode-hook #'turn-on-flyspell) + :config (progn + (unbind-key "C-M-i" flyspell-mode-map) + (unbind-key "C-c $" flyspell-mode-map))) + +(use-package haskell-mode + :mode (("\\.hs\\'" . haskell-mode) + ("\\.lhs\\'" . haskell-mode)) + :defines (haskell-program-name) + :config (progn + (setq haskell-program-name "ghci") + (add-hook 'haskell-mode-hook 'haskell-doc-mode) + (add-hook 'haskell-mode-hook 'turn-on-haskell-indent) + (add-hook 'haskell-mode-hook 'company-mode) + (add-hook 'haskell-mode-hook + (lambda () + (set (make-local-variable 'company-backends) + (append '((company-capf company-dabbrev-code)) + company-backends)))) + (add-hook 'haskell-mode-hook 'flycheck-mode) + + (require 'haskell-indentation) + (add-hook 'haskell-mode-hook + 'haskell-indentation-mode) + + (add-hook 'haskell-mode-hook + 'interactive-haskell-mode))) + +(use-package ivy-pages + :commands (ivy-pages)) + +(use-package highlight-indentation + :commands highlight-indentation-mode) + +(use-package iedit + :commands (iedit-mode)) + +(use-package key-chord + :commands (key-chord-mode) + :config (progn + (key-chord-define-global "``" "“") + (key-chord-define-global "''" "”") + (key-chord-define-global ",," "„"))) + +(use-package markdown-mode + :mode (("\\.md\\'" . markdown-mode))) + +(use-package mastodon + :config (progn + (setq mastodon-instance-url "https://mastodon.blue/"))) + +(use-package multiple-cursors + :commands (mc/edit-lines + mc/mark-next-like-this + mc/mark-previous-like-this + mc/mark-all-like-this)) + +(use-package nxml + :mode (("\\.html\\'" . nxml-mode) + ("\\.xml\\'" . nxml-mode))) + +(use-package page-break-lines + :commands (turn-on-page-break-lines-mode) + :diminish page-break-lines-mode) + +(use-package pdf-tools + :pin "melpa-stable" + :config (pdf-tools-install)) + +(use-package perl-mode + :commands (perl-mode) + :mode (("\\.pl\\'" . perl-mode) + ("\\.pm\\'" . perl-mode)) + :config (progn + (add-hook 'perl-mode-hook 'flycheck-mode) + (add-hook 'perl-mode-hook 'prettify-symbols-mode) + (setq perl-indent-level 2))) + +(use-package pp + :commands (db/eval-last-sexp-or-region + pp-eval-expression) + :config (progn + (defun db/eval-last-sexp-or-region (prefix) + ;; http://pages.sachachua.com/.emacs.d/Sacha.html#orgheadline140 + "Eval region from BEG to END if active, otherwise the last sexp." + (interactive "P") + (if (and (mark) (use-region-p)) + (eval-region (min (point) (mark)) (max (point) (mark))) + (pp-eval-last-sexp prefix))))) + +(use-package python + :config (progn + (setq python-indent-offset 4 + python-shell-interpreter "/usr/bin/python") + (add-hook 'python-mode-hook #'highlight-indentation-mode))) + +(use-package scala-mode + :mode (("\\.scala\\'" . scala-mode))) + +(use-package semantic + :commands (semantic-mode) + :config (progn + (require 'semantic/ia) + (require 'semantic/bovine/el) + + ;; recognize `use-package' as include statement; for some reason, + ;; this form needs to be wrapped in a backquote so that the lambda + ;; form is evaluated before parser is installed; otherwise, the + ;; lambda-form is not recognized as a function and the parsing does + ;; not work + (eval-after-load 'semantic/bovine/el + `(semantic-elisp-setup-form-parser + ,(lambda (form start end) + (semantic-tag-new-include (symbol-name (nth 1 form)) nil)) + use-package)))) + +(use-package synonyms + :config (setq synonyms-file "~/.local/share/thesaurus/mthesaur.txt" + synonyms-cache-file "~/.emacs.d/mthesaur.txt.cache") + :commands (synonyms)) + +(use-package undo-tree + :commands (global-undo-tree-mode + undo + undo-tree-redo) + :config (setq undo-tree-visualizer-timestamps t + undo-tree-visualizer-diff t) + :diminish undo-tree-mode) + +(use-package wgrep + :commands (wgrep-finish-edit + wgrep-change-to-wgrep-mode)) + +(use-package which-key + :commands (which-key-mode) + :diminish which-key-mode + :config (progn (which-key-setup-side-window-bottom) + (setq which-key-side-window-max-width 0.33 + which-key-side-window-max-height 0.25))) + +(use-package yasnippet + :commands (yas-minor-mode-on yas-minor-mode) + :diminish yas-minor-mode + :init (add-hook 'text-mode-hook #'yas-minor-mode-on) + :config (progn + (add-hook 'term-mode-hook (lambda () (yas-minor-mode -1))) + (yas-reload-all))) + + +;; * End + +(provide 'init) + +;;; init.el ends here diff --git a/network-security.data b/network-security.data new file mode 120000 index 0000000..e83f51b --- /dev/null +++ b/network-security.data @@ -0,0 +1 @@ +private/network-security.data \ No newline at end of file diff --git a/private b/private new file mode 160000 index 0000000..99f8648 --- /dev/null +++ b/private @@ -0,0 +1 @@ +Subproject commit 99f86481e53f4a48e8b71ab60ec828b46953685b diff --git a/site-lisp/db-emacsclient.el b/site-lisp/db-emacsclient.el new file mode 100644 index 0000000..f572a13 --- /dev/null +++ b/site-lisp/db-emacsclient.el @@ -0,0 +1,61 @@ +;;; db-emacsclient.el --- Execute functions called from emacsclient + +;;; Commentary: +;; +;; + +;;; Code: + +(defvar db/emacsclient-map (make-sparse-keymap) + "Keymap used for keys called from emacsclient.") + +(defun db/emacsclient-key (key) + "Run command associated with `KEY' in `db/emacsclient-map'." + (let ((function (lookup-key db/emacsclient-map key))) + (when function (apply function nil)))) + +(define-key db/emacsclient-map "w" + (lambda () + (interactive) + (clock-in-task-by-id org-working-task-id) + ;;; FIXME: duplicate code + (call-process "xrandr" nil nil nil + "--output" "HDMI-3" "--primary" "--right-of" "LVDS-1" "--auto") + (call-process "xkbcomp" nil nil nil + "-I" "$HOME/.local/share/xkb/" + "~/.local/share/xkb/keymap/xkbtest $DISPLAY"))) + +(define-key db/emacsclient-map "2" + (lambda () + (call-process "xrandr" nil nil nil + "--output" "HDMI-3" "--primary" "--right-of" "LVDS-1" "--auto") + (call-process "xkbcomp" nil nil nil + "-I" "$HOME/.local/share/xkb/" + "~/.local/share/xkb/keymap/xkbtest $DISPLAY"))) + +(define-key db/emacsclient-map "o" + #'org-clock-out) + +(define-key db/emacsclient-map "b" + (lambda () + (interactive) + (clock-in-task-by-id org-break-task-id))) + +(define-key db/emacsclient-map "h" + (lambda () + (interactive) + (clock-in-task-by-id org-home-task-id) + ;;; FIXME: duplicate code + (call-process "xrandr" nil nil nil + "--output" "HDMI-3" "--off"))) + +(define-key db/emacsclient-map "1" + (lambda () + (call-process "xrandr" nil nil nil + "--output" "HDMI-3" "--off"))) + +;;; + +(provide 'db-emacsclient) + +;;; db-emacsclient.el ends here diff --git a/site-lisp/db-org.el b/site-lisp/db-org.el new file mode 100644 index 0000000..5a86a95 --- /dev/null +++ b/site-lisp/db-org.el @@ -0,0 +1,837 @@ +;;; org.el -- Daniel's org mode configuration + +;;; Commentary: + +;;; Code: + + +;;; Basic Setup + +(setq org-deadline-warning-days 14 + org-read-date-popup-calendar t + org-insert-heading-respect-content t + org-list-description-max-indent 5 + org-adapt-indentation nil + org-edit-timestamp-down-means-later t + org-archive-location "%s_archive.gpg::" + org-image-actual-width nil + org-footnote-section nil) + +(setq org-todo-keywords + '((sequence "TODO(t)" "CONT(n!)" "|" "DONE(d@)") + (sequence "GOTO(g)" "ATTN(a)" "|" "DONE(d@)") + (sequence "READ(r)" "CONT(n!)" "|" "DONE(d@)") + (sequence "DELG(e@/!)" "WAIT(w@/!)" "HOLD(h@/!)" "|" "CANC(c@/!)" "PHONE" "MEETING"))) + +(setq org-todo-state-tags-triggers + '(("WAIT" ("WAIT" . t)) + ("HOLD" ("HOLD" . t)) + (done ("HOLD") ("WAIT") ("NO_EXPORT" . t)) + ("TODO" ("HOLD") ("WAIT") ("NO_EXPORT")) + ("READ" ("READ" . t) ("HOLD") ("WAIT")) + ("GOTO" ("DATE" . t) ("HOLD") ("WAIT")) + ("CONT" ("HOLD") ("WAIT")) + ("ATTN" ("HOLD") ("WAIT")))) + +(setq org-tag-alist + '((:startgroup . nil) + ("WORK" . ?w) + ("HOME" . ?h) + ("FUN" . ?f) + ("UNTAGGED" . ?u) + (:endgroup . nil) + ("NOTE" . ?n))) + +(setq org-treat-S-cursor-todo-selection-as-state-change nil + org-fast-tag-selection-single-key 'expert) + +(setq org-global-properties + '(("Effort_ALL" . "0:00 0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00"))) + +(setq org-columns-default-format + "%80ITEM(Task) %10Effort(Effort){:} %10CLOCKSUM") + + +;;; Faces + +(setq org-todo-keyword-faces + '(("TODO" :foreground "red" :weight normal) + ("GOTO" :foreground "red" :weight normal) + ("READ" :foreground "red" :weight normal) + ("CONT" :foreground "DeepSkyBlue" :weight normal) + ("ATTN" :foreground "DeepSkyBlue" :weight normal) + ("DONE" :foreground "forest green" :weight normal) + ("DELG" :foreground "dark orange" :weight normal) + ("WAIT" :foreground "orange" :weight normal) + ("HOLD" :foreground "magenta" :weight normal) + ("CANC" :foreground "lime green" :weight normal) + ("MEETING" :foreground "forest green" :weight normal) + ("PHONE" :foreground "forest green" :weight normal) + ("REPEAT" :foreground "indian red" :weight normal))) + +(setq org-fontify-done-headline nil) + +(setq org-priority-faces + '((?A . (:foreground "Red" :weight bold)) + (?B . (:foreground "firebrick")) + (?C . (:foreground "tomato")))) + + +;;; Clocking + +(setq org-clock-history-length 23 + org-clock-in-resume t + org-clock-into-drawer t + org-clock-idle-time nil + org-log-into-drawer "LOGBOOK" + org-log-reschedule 'time + org-clock-out-remove-zero-time-clocks t + org-clock-out-when-done '("DONE" "CANC" "WAIT" "HOLD") + org-clock-persist t + org-clock-persist-query-resume nil + org-clock-auto-clock-resolution 'when-no-clock-is-running + org-clock-mode-line-total 'auto + org-clock-in-switch-to-state (lambda (kw) + (when (and (not + (and (boundp 'org-capture-mode) + org-capture-mode))) + (cond + ((member (org-get-todo-state) + (list "TODO" "READ")) + "CONT") + ((member (org-get-todo-state) + (list "GOTO")) + "ATTN")))) + org-clock-continuously t + org-time-stamp-rounding-minutes '(1 1) + org-clock-report-include-clocking-task t + org-time-clocksum-format '(:hours "%d" + :require-hours t + :minutes ":%02d" + :require-minutes t) + org-catch-invisible-edits 'error + org-clone-delete-id t) + +;; Default Tasks for Working, Home, Breaks + +(defvar org-working-task-id + "e56f201f-64a7-4f4a-8c3c-4151e3fdf880") +(defvar org-break-task-id + "c921affd-91f0-4ba9-8462-6c50dc1ed34e") +(defvar org-home-task-id + "ade37344-ccd9-4c93-aa15-406886a86627") + +(add-hook 'org-clock-in-hook ; mark current default task + (lambda () + (let ((current-id (org-id-get org-clock-marker))) + (when (member current-id (list org-working-task-id + org-home-task-id)) + (org-clock-mark-default-task))))) + +;; Clock in default task if no other task is given + +(defun db/find-parent-task () + ;; http://doc.norang.ca/org-mode.html#Clocking + "Return point of the nearest parent task, and NIL if no such task exists." + (save-mark-and-excursion + (save-restriction + (widen) + (let ((parent-task nil)) + (or (org-at-heading-p) + (org-back-to-heading t)) + (while (and (not parent-task) + (org-up-heading-safe)) + (let ((tags (nth 5 (org-heading-components)))) + (unless (and tags (member "NOP" (split-string tags ":" t))) + (setq parent-task (point))))) + parent-task)))) + +(defun db/ensure-running-clock () + "Clocks in into the parent task, if it exists, or the default task." + (when (and (not org-clock-clocking-in) + (not org-clock-resolving-clocks-due-to-idleness)) + (let ((parent-task (db/find-parent-task))) + (save-mark-and-excursion + (cond + (parent-task + ;; found parent task + (org-with-point-at parent-task + (org-clock-in))) + ((and (markerp org-clock-default-task) + (marker-buffer org-clock-default-task)) + ;; default task is set + (org-with-point-at org-clock-default-task + (org-clock-in))) + (t + (org-clock-in '(4)))))))) + +(add-hook 'org-clock-out-hook #'db/ensure-running-clock 'append) + +;; clock-in helpers + +(defun clock-in-task-by-id (task-id) + "Clock in org mode task as given by TASK-ID." + (org-with-point-at (org-id-find task-id 'marker) + (org-clock-in)) + (org-save-all-org-buffers)) + +(defun clock-out-task-by-id (task-id) + "Clock out org mode task as given by TASK-ID." + (org-with-point-at (org-id-find task-id 'marker) + (org-clock-out)) + (org-save-all-org-buffers)) + +(defun db/org-clock-in-last-task (&optional arg) + ;; from doc.norang.ca, originally bh/clock-in-last-task + "Clock in the interrupted task if there is one. + +Skip the default task and get the next one. If ARG is given, +forces clocking in of the default task." + (interactive "p") + (let ((clock-in-to-task + (cond + ((eq arg 4) org-clock-default-task) + ((and (org-clock-is-active) + (equal org-clock-default-task (cadr org-clock-history))) + (caddr org-clock-history)) + ((org-clock-is-active) (cadr org-clock-history)) + ((equal org-clock-default-task (car org-clock-history)) + (cadr org-clock-history)) + (t (car org-clock-history))))) + (widen) + (org-with-point-at clock-in-to-task + (org-clock-in nil)))) + +;; Communicate the currently clocked in task to the outside world + +(defvar db/org-clock-current-task-file + "~/.org-current-task") + +(defun db/org-current-task () + "Format currently clocked task and write it to +`db/org-clock-current-task-file'." + (with-temp-file db/org-clock-current-task-file + (let ((clock-buffer (marker-buffer org-clock-marker))) + (if (null clock-buffer) + (insert "No running clock")) + (let ((current-task org-clock-heading) + (current-file (file-name-sans-extension + (file-name-nondirectory + (buffer-file-name clock-buffer))))) + (insert current-file "/" current-task))))) + +(add-hook 'org-clock-in-hook #'db/org-current-task) + +(defun db/select-clocking-task () + "Select task from recent clocked-in tasks." + (interactive) + (org-clock-in '(4))) + + +;;; Agenda Customization + +(defvar db/org-default-work-file + "~/Documents/uni/admin/misc/work.org") + +(defvar db/org-default-home-file + "~/Documents/home/home.org") + +(defvar db/org-default-notes-file + "~/Documents/home/notes.org") + +(defvar db/org-default-refile-file + "~/Desktop/refile.org") + +(defvar db/org-default-pensieve-file + "~/Documents/home/pensieve.org.gpg") + +(setq org-agenda-files (list db/org-default-home-file + db/org-default-work-file + db/org-default-refile-file + db/org-default-notes-file)) + +(setq org-agenda-include-diary nil + org-agenda-span 1 + org-agenda-diary-file db/org-default-refile-file + org-agenda-insert-diary-strategy 'top-level + org-catch-invisible-edits 'show + org-ellipsis "⤵" + org-agenda-sorting-strategy '((agenda time-up habit-up priority-down) + (todo category-keep) + (tags category-keep) + (search category-keep))) + +(setq org-agenda-window-setup 'current-window + org-agenda-restore-windows-after-quit t + org-agenda-compact-blocks nil) + +(setq org-agenda-todo-ignore-with-date nil + org-agenda-todo-ignore-deadlines nil + org-agenda-todo-ignore-scheduled nil + org-agenda-todo-ignore-timestamp nil + org-agenda-skip-deadline-if-done t + org-agenda-skip-scheduled-if-done t + org-agenda-skip-timestamp-if-done t + org-agenda-skip-scheduled-if-deadline-is-shown 'not-today + org-agenda-tags-todo-honor-ignore-options t + org-agenda-start-with-log-mode nil + org-agenda-log-mode-items '(closed state) + org-agenda-remove-tags t + org-agenda-sticky nil + org-agenda-inhibit-startup t + org-agenda-tags-todo-honor-ignore-options t + org-agenda-dim-blocked-tasks nil + org-enforce-todo-checkbox-dependencies t + org-enforce-todo-dependencies t + org-agenda-use-time-grid t + org-agenda-persistent-filter t + org-agenda-search-headline-for-time nil) + +(setq org-agenda-clock-consistency-checks + '(:max-duration 999999999 + :min-duration 0 + :max-gap 0 + :gap-ok-around nil + :default-face ((:background "DarkRed") (:foreground "white")) + :overlap-face nil :gap-face nil :no-end-time-face nil + :long-face nil :short-face nil)) + +(eval-after-load 'org-agenda + '(bind-key "i" 'org-agenda-clock-in org-agenda-mode-map)) + +(add-hook 'org-agenda-mode-hook #'hl-line-mode 'append) + +(setq org-agenda-clockreport-parameter-plist + '(:link t :maxlevel 4 :compact t :narrow 60 :fileskip0 t)) + +(setq org-stuck-projects + '("-REGULAR-HOLD-NOTE+TODO=\"\"" + ("CONT" "TODO" "READ" "WAIT" "GOTO" "DELG") + ("DATE" "NOP" "HOLD") + "")) + +(setq org-agenda-prefix-format + '((agenda . " %11s%-4c %4e %?-12t") + (timeline . "% s") + (todo . " %-4c ") + (tags . " %-4c ") + (search . " %-4c "))) + +(defun db/org-agenda-list-deadlines (&optional match) + ;; XXX org-agenda-later does not work, fix this + "Prepare agenda view that only lists upcoming deadlines. + +Ignores MATCH." + (interactive "P") + (catch 'exit + (org-agenda-prepare "Deadlines") + (org-compile-prefix-format 'agenda) + (org-set-sorting-strategy 'agenda) + + (let* ((today (org-today)) + (thefiles (org-agenda-files nil 'ifmode)) + (inhibit-redisplay (not debug-on-error)) + s rtn rtnall file files date start-pos end-pos) + + ;; headline + (unless org-agenda-compact-blocks + (setq s (point)) + (if org-agenda-overriding-header + (insert (org-add-props (copy-sequence org-agenda-overriding-header) + nil 'face 'org-agenda-structure) "\n")) + (org-agenda-mark-header-line s)) + + ;; actual content + (setq date (calendar-gregorian-from-absolute today) + s (point) + start-pos (point) + files thefiles + rtnall nil) + (while (setq file (pop files)) + (catch 'nextfile + (org-check-agenda-file file) + (setq rtn (apply 'org-agenda-get-day-entries + file date + '(:deadline))) + (setq rtnall (append rtnall rtn)))) ;; all entries + (when rtnall + (insert (org-agenda-finalize-entries rtnall 'agenda) + "\n")) + + ;; finalize + (goto-char (point-min)) + (or org-agenda-multi (org-agenda-fit-window-to-buffer)) + (unless (and (pos-visible-in-window-p (point-min)) + (pos-visible-in-window-p (point-max))) + (goto-char (1- (point-max))) + (recenter -1) + (if (not (pos-visible-in-window-p (or start-pos 1))) + (progn + (goto-char (or start-pos 1)) + (recenter 1)))) + (goto-char (or start-pos 1)) + (add-text-properties + (point-min) (point-max) + `(org-agenda-type agenda + org-redo-cmd + (db/org-agenda-list-deadlines ,match))) + (org-agenda-finalize) + (setq buffer-read-only t) + (message "")))) + +(defun db/org-agenda-skip-tag (tag &optional others) + ;; https://stackoverflow.com/questions/10074016/org-mode-filter-on-tag-in-agenda-view + "Skip all entries that correspond to TAG. + +If OTHERS is true, skip all entries that do not correspond to TAG." + (let* ((next-headline (save-mark-and-excursion + (or (outline-next-heading) (point-max)))) + (current-headline (or (and (org-at-heading-p) + (point)) + (save-mark-and-excursion + ;; remember to also consider invisible headings + (org-back-to-heading t)))) + (has-tag (member tag (org-get-tags-at current-headline)))) + (if (or (and others (not has-tag)) + (and (not others) has-tag)) + next-headline + nil))) + +(defun db/cmp-date-property (prop) + ;; https://emacs.stackexchange.com/questions/26351/custom-sorting-for-agenda + "Compare two `org-mode' agenda entries, `A' and `B', by some date property. + +If a is before b, return -1. If a is after b, return 1. If they +are equal return nil." + (lexical-let ((prop prop)) + #'(lambda (a b) + (let* ((a-pos (get-text-property 0 'org-marker a)) + (b-pos (get-text-property 0 'org-marker b)) + (a-date (or (org-entry-get a-pos prop) + (format "<%s>" (org-read-date t nil "now")))) + (b-date (or (org-entry-get b-pos prop) + (format "<%s>" (org-read-date t nil "now")))) + (cmp (compare-strings a-date nil nil b-date nil nil))) + (if (eq cmp t) nil (signum cmp)))))) + +(setq org-agenda-custom-commands + `(("A" "Main List" + ((agenda + "" + ((org-agenda-entry-types '(:timestamp :sexp :scheduled :deadline)) + (org-deadline-warning-days 0) + (org-agenda-files (append org-agenda-files + (mapcar #'second db/ical-org-links))))) + (db/org-agenda-list-deadlines + "" + ((org-agenda-overriding-header "Deadlines") + (org-agenda-sorting-strategy '(deadline-up priority-down)) + (org-agenda-skip-deadline-prewarning-if-scheduled t) + (org-deadline-warning-days 30))) + (tags-todo "-NOAGENDA/WAIT|DELG" + ((org-agenda-overriding-header "Waiting-fors") + (org-agenda-todo-ignore-deadlines t) + (org-agenda-todo-ignore-scheduled t))) + (tags "REFILE" + ((org-agenda-files (list db/org-default-refile-file)) + (org-agenda-overriding-header "Things to refile"))))) + ("R" "Reading List" + ((tags-todo "READ/-DONE-CANC" + ((org-agenda-overriding-header "To Read (unscheduled)") + (org-agenda-cmp-user-defined (db/cmp-date-property "CREATED")) + (org-agenda-sorting-strategy '(user-defined-up)) + (org-agenda-todo-ignore-scheduled t))))) + ("E" "Everything" + ((tags-todo "/WAIT" + ((org-agenda-overriding-header "Tasks requiring response/input"))) + (tags-todo "-HOLD-READ-SOMEWHEN/-DONE" + ((org-agenda-overriding-header "Things not being scheduled or deadlined") + (org-tags-match-list-sublevels t) + (org-agenda-todo-ignore-with-date t) + (org-agenda-sorting-strategy + '(priority-down time-up category-keep)))) + (stuck "" + ((org-agenda-overriding-header "Stuck Tasks"))))) + ("S" "Somewhen" + ((tags "SOMEWHEN/-CANC-DONE" + ((org-agenda-overriding-header "Things to do somewhen") + (org-use-tag-inheritance nil))) + (tags-todo "/HOLD" + ((org-agenda-overriding-header "Tasks on Hold"))))) + ("W" "Weekly Review" + ((agenda "" + ((org-agenda-span 7) + (org-agenda-archives-mode t) + (org-agenda-dim-blocked-tasks nil) + (org-agenda-skip-deadline-prewarning-if-scheduled t))))) + ("M" "Monthly Preview" + ((db/org-agenda-list-deadlines + "" + ((org-agenda-overriding-header "Deadlines") + (org-agenda-sorting-strategy '(deadline-up priority-down)) + (org-deadline-warning-days 90))) + (agenda "" + ((org-agenda-span 'month) + (org-agenda-dim-blocked-tasks nil) + (org-deadline-warning-days 0) ; covered by display above + )))) + ("N" "Notes" tags "NOTE" + ((org-agenda-overriding-header "Notes") + (org-use-tag-inheritance nil) + (org-agenda-prefix-format '((tags . " "))))))) + +(defun db/org-add-clocking-time () + "Add \"CLOCK:\" line to the task under point in the agenda. + +Start and end time will be queried interactively." + (interactive) + ;; FIXME: make this function to take two optional arguments + ;; FIXME: check that we are in org-agenda-mode + (let* ((starting-time (org-read-date 4 'totime nil "Start:" (current-time) nil t)) + (ending-time (org-read-date 4 'totime nil "End:" (current-time) nil t))) + (save-window-excursion + (org-agenda-switch-to) + (org-clock-find-position nil) + (open-line 1) + (indent-according-to-mode) + (insert "CLOCK: ") + (org-insert-time-stamp starting-time t t) + (insert "--") + (org-insert-time-stamp ending-time t t) + (org-clock-update-time-maybe)))) + +(eval-after-load 'org-agenda + '(bind-key "V u" #'db/org-add-clocking-time org-agenda-mode-map)) + +;; A Hydra for changing agenda appearance +;; http://oremacs.com/2016/04/04/hydra-doc-syntax/ + +(defun db/org-agenda-span () + "Return the display span of the current shown agenda." + (let ((args (get-text-property + (min (1- (point-max)) (point)) + 'org-last-args))) + (nth 2 args))) + +(defhydra hydra-org-agenda-view (:hint none) + " +_d_: ?d? day _g_: time grid=?g? _a_: arch-trees +_w_: ?w? week _[_: inactive _A_: arch-files +_t_: ?t? fortnight _F_: follow=?F? _r_: report=?r? +_m_: ?m? month _e_: entry =?e? _D_: diary=?D? +_y_: ?y? year _q_: quit _L__l__c_: ?l? + +" + ("SPC" org-agenda-reset-view) + ("d" org-agenda-day-view + (if (eq 'day (db/org-agenda-span)) + "[x]" "[ ]")) + ("w" org-agenda-week-view + (if (eq 'week (db/org-agenda-span)) + "[x]" "[ ]")) + ("t" org-agenda-fortnight-view + (if (eq 'fortnight (db/org-agenda-span)) + "[x]" "[ ]")) + ("m" org-agenda-month-view + (if (eq 'month (db/org-agenda-span)) "[x]" "[ ]")) + ("y" org-agenda-year-view + (if (eq 'year (db/org-agenda-span)) "[x]" "[ ]")) + ("l" org-agenda-log-mode + (format "% -3S" org-agenda-show-log)) + ("L" (org-agenda-log-mode '(4))) + ("c" (org-agenda-log-mode 'clockcheck)) + ("F" org-agenda-follow-mode + (format "% -3S" org-agenda-follow-mode)) + ("a" org-agenda-archives-mode) + ("A" (org-agenda-archives-mode 'files)) + ("r" org-agenda-clockreport-mode + (format "% -3S" org-agenda-clockreport-mode)) + ("e" org-agenda-entry-text-mode + (format "% -3S" org-agenda-entry-text-mode)) + ("g" org-agenda-toggle-time-grid + (format "% -3S" org-agenda-use-time-grid)) + ("D" org-agenda-toggle-diary + (format "% -3S" org-agenda-include-diary)) + ("!" org-agenda-toggle-deadlines) + ("[" + (let ((org-agenda-include-inactive-timestamps t)) + (org-agenda-check-type t 'timeline 'agenda) + (org-agenda-redo))) + ("q" (message "Abort") :exit t)) + +(eval-after-load 'org-agenda + '(bind-key "v" #'hydra-org-agenda-view/body org-agenda-mode-map)) + +(defun db/org-agenda-to-appt () + ;; doc.norang.ca/org-mode.html + "Rebuild reminders for today from the agenda." + (interactive) + (org-agenda-to-appt t)) + +(add-hook 'org-agenda-finalize-hook 'db/org-agenda-to-appt 'append) + + +;;; Capturing + +;; disable usage of helm for `org-capture' +(eval-after-load 'helm-mode + '(add-to-list 'helm-completing-read-handlers-alist '(org-capture . nil))) + +(setq org-capture-templates + `(("t" "todo" + entry + (file db/org-default-refile-file) + ,(concat "* TODO %^{What}\n" + "SCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n" + ":PROPERTIES:\n:CREATED: %U\n:END:\n" + "\n%?")) + ("n" "note" + entry + (file+olp db/org-default-notes-file "Notes") + "* %^{About} :NOTE:\n%T\n\n%?" + :clock-in t :clock-resume t) + ("d" "date" + entry + (file db/org-default-refile-file) + "* GOTO %^{What} :DATE:\n%^{When}t\n%a" + :immediate-finish t) + ("i" "interruption" + entry + (file db/org-default-refile-file) + "* DONE %^{What}\n\n%a\n%?" + :clock-in t :clock-resume t) + ("j" "journal entry" + plain + (file+datetree db/org-default-pensieve-file) + "\n%i%U\n\n%?\n\n") + ("r" "respond" + entry + (file db/org-default-refile-file) + ,(concat "* TODO E-Mail: %:subject (%:from) :EMAIL:\n" + "SCHEDULED: %^{Reply when?}t\n" + ":PROPERTIES:\n:CREATED: %U\n:END:\n" + "\n%a") + :immediate-finish t) + ("R" "read" + entry + (file db/org-default-refile-file) + ,(concat "* READ %:subject :READ:\n" + ;; "DEADLINE: <%(org-read-date nil nil \"+1m\")>\n" + ":PROPERTIES:\n:CREATED: %U\n:END:\n" + "\n%a") + :immediate-finish t) + ("U" "Read current content of clipboard" + entry + (file db/org-default-refile-file) + ,(concat "* READ %^{Description} :READ:\n" + "DEADLINE: <%(org-read-date nil nil \"+1m\")>\n" + ":PROPERTIES:\n:CREATED: %U\n:END:\n" + "\n%(current-kill 0)") + :immediate-finish t) + ("m" "Meeting" + entry + (file db/org-default-refile-file) + ,(concat "* MEETING with %^{With}: %^{What} :MEETING:\n" + ":PROPERTIES:\n:CREATED: %U\n:END:\n" + "\n%?") + :clock-in t :clock-resume t) + ("p" "Phone call" + entry + (file db/org-default-refile-file) + ,(concat "* PHONE %^{Calling} :PHONE:\n" + ":PROPERTIES:\n:CREATED: %U\n:END:\n" + "\n%?") + :clock-in t :clock-resume t) + ("w" "Weekly Summary" + entry + (file+datetree db/org-default-pensieve-file) + "* Weekly Review\n\n%?"))) + +(setq org-capture-use-agenda-date nil) + +;; (add-to-list 'display-buffer-alist +;; `(,(rx bos "*Capture*" eos) +;; (display-buffer-in-side-display . window-buffer-reuse-window) +;; (reusable-frames . visible) +;; (side . bottom) +;; (window-height . 0.4))) + +;; TODO: bind pop-to-buffer-same-window to pop-to-buffer in +;; org-capture-place-template + + +;;; Refiling + +;; Refiling targets include this file and any file contributing to the agenda, +;; up to 9 levels deep +(setq org-refile-targets '((org-agenda-files . (:maxlevel . 9)))) + +;; Use full outline paths for refile targets +(setq org-refile-use-outline-path 'file) + +(setq org-refile-allow-creating-parent-nodes 'confirm) +(setq org-indirect-buffer-display 'current-window) +(setq org-outline-path-complete-in-steps nil) + + +;;; Babel + +(setq org-structure-template-alist + '(("s" "#+begin_src ?\n\n#+end_src" "\n\n") + ("e" "#+begin_example\n?\n#+end_example" "\n?\n") + ("q" "#+begin_quote\n?\n#+end_quote" "\n?\n") + ("Q" "#+begin_equation\n?\n#+end_equation" + "\n?\n") + ("v" "#+begin_verse\n?\n#+end_verse" "\n?\n") + ("V" "#+begin_verbatim\n?\n#+end_verbatim" "\n?\n") + ("c" "#+begin_center\n?\n#+end_center" "
\n?\n
") + ("l" "#+begin_latex\n?\n#+end_latex" + "\n?\n") + ("l" "#+latex: " "?") + ("h" "#+begin_html\n?\n#+end_html" + "\n?\n") + ("h" "#+html: " "?") + ("a" "#+begin_ascii\n?\n#+end_ascii" "") + ("a" "#+ascii: " "") + ("i" "#+index: ?" "#+index: ?") + ("i" "#+include: %file ?" + ""))) + +(setq org-src-fontify-natively t + org-src-preserve-indentation t) + + +;;; Other Packages + +(eval-after-load 'org-agenda + '(use-package org-habit + :config (progn + (setq org-habit-graph-column 73) + (setq org-habit-show-habits-only-for-today nil) + (setq org-habit-following-days 7)))) + +(require 'org-checklist) + + +;;; Calendar + +(use-package ox-icalendar + :commands (org-icalendar-combine-agenda-files) + :config (progn + (setq org-icalendar-include-body nil + org-icalendar-store-UID t + org-icalendar-use-deadline nil + org-icalendar-use-scheduled nil + org-icalendar-include-todo nil + org-icalendar-exclude-tags '("NO_EXPORT") + org-icalendar-combined-agenda-file "~/Public/daniel.ics"))) + +(defun db/export-diary () + "Export diary.org as ics file to ~/Public." + (interactive) + (require 'ox-icalendar) + (org-save-all-org-buffers) + (let ((org-agenda-files (list db/org-default-home-file + db/org-default-work-file)) + (org-agenda-new-buffers nil)) + ;; check whether we need to do something + (when (some (lambda (org-file) + (file-newer-than-file-p org-file + org-icalendar-combined-agenda-file)) + org-agenda-files) + (message "Exporting diary ...") + ;; open files manually to avoid polluting `org-agenda-new-buffers’; we don’t + ;; want these buffers to be closed after exporting + (mapc #'find-file-noselect org-agenda-files) + ;; actual export; calls `org-release-buffers’ and may thus close buffers + ;; we want to keep around … which is why we set `org-agenda-new-buffers’ + ;; to nil + (org-icalendar-combine-agenda-files) + (message "Exporting diary ... done.")))) + +(defun db/ical-to-org (ical-file-name org-file-name category filetags) + "Convert ICAL-FILE-NAME to ORG-FILE-NAME using ical2org. + +CATEGORY and FILETAGS specify the category and the filetags of +the resulting org mode file, respectively." + (when (string-match "^https?://" ical-file-name) + (let ((tmp-file (make-temp-file "/tmp/emacs-ical-"))) + (url-copy-file ical-file-name tmp-file t) + (setq ical-file-name tmp-file))) + (unless (zerop (call-process "ical2org.pl" + ical-file-name + `(:file ,org-file-name) + nil + "-c" category + "-f" filetags)) + (error (concat "Error in converting ical file «%s» into org file;" + " see «%s» for more information") + ical-file-name org-file-name))) + +(defvar db/ical-org-links nil + "List of ical-file-names and their linked org mode files.") + +(defun db/add-ical-org-link (ical-file-name org-file-name category filetags) + "Add a new link from ICAL-FILE-NAME to ORG-FILE-NAME. + +Resulting org mode file will have CATEGORY and FILETAGS set." + (cl-pushnew (list ical-file-name org-file-name category filetags) + db/ical-org-links + :test #'equal)) + +(defun db/update-ical-org-files () + "Update all org mode files that are linked to some iCal file." + (interactive) + (dolist (entry db/ical-org-links) + (cl-destructuring-bind (url target category filetags) entry + (condition-case ex + (progn + ;; update TARGET + (db/ical-to-org url target category filetags) + ;; revert buffers visiting TARGET + (with-current-buffer (find-buffer-visiting target) + (let ((revert-without-query (list (regexp-quote (file-truename target))))) + (revert-buffer)))) + (error + (warn "Error in generating %s: %s" target (cadr ex))))))) + +(defun db/sync-all-iCal () + "Sync all iCal sources." + (interactive) + (db/export-diary) + (db/update-ical-org-files)) + + +;;; Fixes + +(defun endless/org-ispell () + "Configure `ispell-skip-region-alist' for `org-mode'." + (make-local-variable 'ispell-skip-region-alist) + (add-to-list 'ispell-skip-region-alist '(org-property-drawer-re)) + (add-to-list 'ispell-skip-region-alist '("~" "~")) + (add-to-list 'ispell-skip-region-alist '("=" "=")) + (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_SRC" . "^#\\+END_SRC"))) + +(add-hook 'org-mode-hook #'endless/org-ispell) + + +;;; Exporting + +(eval-after-load 'ox + '(progn + (add-to-list 'org-latex-classes + '("scrartcl" "\\documentclass[11pt]{scrartcl}\n\\usepackage{babel}\n" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + + (require 'ox-md))) + + +;;; End + +(provide 'db-org) + +;;; db-org.el ends here diff --git a/site-lisp/db-private.el b/site-lisp/db-private.el new file mode 120000 index 0000000..a27c8ad --- /dev/null +++ b/site-lisp/db-private.el @@ -0,0 +1 @@ +private/db-private.el \ No newline at end of file diff --git a/site-lisp/db-utils.el b/site-lisp/db-utils.el new file mode 100644 index 0000000..ff0ee06 --- /dev/null +++ b/site-lisp/db-utils.el @@ -0,0 +1,341 @@ +;;; db-utils.el --- Utility Functions for Daniel's Emacs Configuration + +;;; Commentary: +;; +;; Some functions used in my ~/.emacs.d/init.el. Most of them are copied from +;; various sources around the internet. +;; + +;;; Code: + +(defgroup personal-settings nil + "A bunch of functions and variables for personalizing emacs." + :prefix "db/" + :group 'convenience + :group 'help + :tag "Personal settings") + + +;;; application shortcuts + +(defun db/run-or-hide-ansi-term () + "Find `*ansi-term*' or run `ansi-term' with `explicit-shell-file-name'. +If already in `*ansi-term*' buffer, bury it." + (interactive) + (if (string= "term-mode" major-mode) + (bury-buffer) + (if (get-buffer "*ansi-term*") + (switch-to-buffer "*ansi-term*") + (ansi-term explicit-shell-file-name)))) + +(defun db/gnus () + "Switch to the `*Group*' buffer, starting `gnus' if not existent." + (interactive) + (require 'gnus) + (if (get-buffer "*Group*") + (switch-to-buffer "*Group*") + (gnus))) + +(defun db/org-agenda () + "Show the main `org-agenda'." + (interactive) + (org-agenda nil "A")) + +(defun db/scratch () + "Switch to `*scratch*'." + (interactive) + (switch-to-buffer "*scratch*")) + +(defun db/find-user-init-file () + "Edit `user-init-file'." + (interactive) + (find-file user-init-file)) + +(defun db/run-or-hide-eshell (arg) + "Opens an eshell buffer if not already in one, and otherwise + returns to where we have been before." + ;; idea to split the current window is from + ;; http://howardism.org/Technical/Emacs/eshell-fun.html + (interactive "P") + (if (string= "eshell-mode" major-mode) + ;; bury buffer; reopen with current working directory if arg is given + (progn + (bury-buffer) + (delete-window) + (and arg (db/run-or-hide-eshell arg))) + (if-let ((eshell-window (db/find-window-by-buffer-mode 'eshell-mode))) + (select-window eshell-window) + ;; open eshell + (let ((current-dir (expand-file-name (dired-default-directory))) + (height (/ (window-total-height) 3))) + (split-window-vertically (- height)) + (other-window 1) + (eshell 1) + (when arg + (end-of-line) + (eshell-kill-input) + (insert (format "cd %s" current-dir)) + (eshell-send-input)))))) + +(defun db/run-or-hide-shell (arg) + "Opens an shell buffer if not already in one, and otherwise + returns to where we have been before." + (interactive "P") + (if (string= "shell-mode" major-mode) + (progn + (bury-buffer) + (other-window -1)) + (shell))) + + +;;; helpers + +(defun db/get-url-from-link () + "Copy url of link under point into clipboard." + (interactive) + (let ((url (plist-get (text-properties-at (point)) 'help-echo))) + (if url + (kill-new url) + (error "No link found.")))) + +(defun db/test-emacs () + ;; from oremacs + "Test whether emacs' configuration is not throwing any errors." + (interactive) + (require 'async) + (async-start + (lambda () (shell-command-to-string + "emacs --batch --eval \" +(condition-case e + (progn + (load \\\"~/.emacs.d/init.el\\\") + (message \\\"-OK-\\\")) + (error + (message \\\"ERROR!\\\") + (signal (car e) (cdr e))))\"")) + `(lambda (output) + (if (string-match "-OK-" output) + (when ,(called-interactively-p 'any) + (message "All is well")) + (switch-to-buffer-other-window "*startup error*") + (delete-region (point-min) (point-max)) + (insert output) + (search-backward "ERROR!"))))) + +(defun db/get-mail (arg) + "Use offlineimap to get emails from remote accounts. +With optional ARG, fetch only personal email addresses." + (interactive "P") + (if arg + (message "Receiving Mail... (personal only)") + (message "Receiving Mail...")) + (let ((process (apply #'start-process + "offlineimap" + " *offlineimap*" + "systemctl" + `("--user" "start" ,(format "offlineimap@%s" (getenv "DISPLAY")))))) + (set-process-sentinel process + (lambda (process event) + (if (string= event "finished\n") + (progn (gnus-group-get-new-news 2) + (message "Receiving Mail... done")) + (error "Receiving Mail... failed")))))) + +(defun db/isearch-forward-symbol-with-prefix (p) + ;; http://endlessparentheses.com/quickly-search-for-occurrences-of-the-symbol-at-point.html + "Like `isearch-forward', unless prefix argument is provided. +With a prefix argument P, isearch for the symbol at point." + (interactive "P") + (let ((current-prefix-arg nil)) + (call-interactively + (if p + #'isearch-forward-symbol-at-point + #'isearch-forward)))) + +(defun db/go-dark () + "Enable dark themes." + (interactive) + (load-theme 'solarized-dark) + (load-theme 'smart-mode-line-dark)) + +(defun db/go-light () + "Enable light themes." + (interactive) + (load-theme 'solarized-light) + (load-theme 'smart-mode-line-light)) + +(defun endless/fill-or-unfill () + "Like `fill-paragraph', but unfill if used twice." + ;; http://endlessparentheses.com/fill-and-unfill-paragraphs-with-a-single-key.html + (interactive) + (let ((fill-column + (if (eq last-command 'endless/fill-or-unfill) + (progn (setq this-command nil) + (point-max)) + fill-column))) + (call-interactively #'fill-paragraph))) + +(defun db/delete-trailing-whitespace-maybe () + "Call `delete-trailing-whitespace', but not in `message-mode'." + (unless (derived-mode-p 'message-mode) + (delete-trailing-whitespace))) + +(defun db/find-window-by-buffer-mode (mode) + "Return first window in current frame displaying a buffer with +major mode MODE." + (cl-find-if (lambda (window) + (with-current-buffer (window-buffer window) + (eq major-mode mode))) + (window-list-1))) + +(defun db/ssh-keys () + "Return list of private ssh keys available on the system." + (cl-flet ((file-ssh-key-p (file) + (string-suffix-p ": PEM RSA private key\n" + (shell-command-to-string (format "file %s" file))))) + (cl-remove-if-not #'file-ssh-key-p (directory-files "~/.ssh/" t)))) + +(defun db/add-to-keyring (&optional file) + "Add FILE to local keyring. +If FILE is not given, prompt for one." + (interactive) + (if file + (let ((return-value (call-process "ssh-add" nil nil nil "-t" "86400" (expand-file-name file)))) + (unless (zerop return-value) + (error "Aborted: %s" return-value))) + (let ((ssh-keys `((name . "SSH Keys") + (candidates . ,(mapcar (lambda (file) + (cons (file-name-nondirectory file) file)) + (db/ssh-keys))) + (action . (("Add to keyring" . db/add-to-keyring)))))) + (helm :sources (list ssh-keys))))) + +(defun db/show-current-org-task () + "Show title of currently clock in task in modeline." + (interactive) + (message org-clock-current-task)) + + +;;; dired + +(defun dired-back-to-top () + "Jump to first non-trivial line in dired." + (interactive) + (beginning-of-buffer) + (dired-next-line 4)) + +(defun dired-jump-to-bottom () + "Jump to last non-trivial line in dired." + (interactive) + (end-of-buffer) + (dired-next-line -1)) + +(defun dired-get-size () ; from emacswiki, via oremacs + "print size of all files marked in the current dired buffer." + (interactive) + (let ((files (dired-get-marked-files))) + (with-temp-buffer + (apply 'call-process "/usr/bin/du" nil t nil "-sch" files) + (message + "size of all marked files: %s" + (progn + (re-search-backward "\\(^[0-9.,]+[a-za-z]+\\).*total$") + (match-string 1)))))) + +(defun dired-open-term () ; from oremacs + "Open an `ansi-term' that corresponds to current directory." + (interactive) + (let ((current-dir (dired-current-directory))) + (term-send-string + (db/ansi-term) + (if (file-remote-p current-dir) + (let ((v (tramp-dissect-file-name current-dir t))) + (format "ssh %s@%s\n" + (aref v 1) (aref v 2))) + (format "cd '%s'\n" current-dir))))) + + +;;; helm configuration + +(defcustom db/helm-frequently-used-features + '((name . "Frequently Used") + (candidates . (("Mail" . db/gnus) + ("Agenda" . db/org-agenda) + ("Init File" . db/find-user-init-file) + ("EMMS" . emms) + ("Gnus" . (lambda () + (interactive) + (find-file gnus-init-file))) + ("scratch" . db/scratch))) + (action . (("Open" . funcall))) + (filtered-candidate-transformer . helm-adaptive-sort)) + "Helm shortcuts for frequently used features." + :group 'personal-settings + :type '(alist :key-type symbol :value-type sexp)) + +(defcustom db/helm-frequently-visited-locations + '((name . "Locations") + (candidates . (("db-utils" . "~/.emacs.d/site-lisp/db-utils.el") + ("db-org" . "~/.emacs.d/site-lisp/db-org.el") + ("db-private" . "~/.emacs.d/site-lisp/db-private.el") + ("notes" . "~/Documents/home/notes.org") + ("pensieve" . "~/Documents/home/pensieve.org.gpg") + ("things (home)" . "~/Documents/home/misc/things.gpg") + ("things (work)" . "~/Documents/uni/admin/misc/things.gpg") + ("research ideas" . "~/Documents/uni/research/ideas.org") + ("teaching ideas" . "~/Documents/uni/lehre/ideas.org"))) + (action . (("Open" . find-file))) + (filtered-candidate-transformer . helm-adaptive-sort)) + "Helm shortcuts to frequentely visited locations" + :group 'personal-settings + :type '(alist :key-type symbol :value-type sexp)) + +(defun db/helm-shortcuts () + "Open helm completion on common locations." + (interactive) + (helm :sources `(db/helm-frequently-used-features + db/helm-frequently-visited-locations))) + + +;;; Other Utilities + +(defun db/bank-csv-to-org-table () + (interactive) + (goto-char (point-min)) + (kill-line 8) + (replace-regexp "^\"" "| ") + (goto-char (point-min)) + (replace-regexp "\"$" " |") + (goto-char (point-min)) + (replace-regexp "\";\"" " | ") + (goto-char (point-min)) + (org-mode) + (org-table-align) + ;; move columns around + (cl-loop + for (word . count) in '(("Wertstellung" . 6) ("Umsatzart" . 6) ("Buchungsdetails" . 3)) + do (progn (goto-char (point-min)) + (search-forward word) + (dotimes (i count) + (org-table-move-column-right)))) + (goto-char (point-min))) + +(defun db/org-cleanup-continuous-clocks () + "Join continuous clock lines in the current buffer." + (interactive) + (let* ((inactive-timestamp (org-re-timestamp 'inactive)) + (clock-line (concat "\\(^ *\\)CLOCK: " inactive-timestamp "--" inactive-timestamp " => .*" + "\n" + " *CLOCK: " inactive-timestamp "--\\[\\2\\] => .*$"))) + (save-excursion + (goto-char (point-min)) + (while (search-forward-regexp clock-line nil t) + (replace-match "\\1CLOCK: [\\4]--[\\3]") + (org-clock-update-time-maybe))))) + + +;;; + +(provide 'db-utils) + +;;; db-utils.el ends here diff --git a/site-lisp/ical2org.el b/site-lisp/ical2org.el new file mode 100644 index 0000000..70592a7 --- /dev/null +++ b/site-lisp/ical2org.el @@ -0,0 +1,262 @@ +;;; ics2org.el -- convert icalendar to org + +;; Copyright (C) 2010, 2011 Michael Markert +;; Author: Michael Markert +;; Created: 2010/12/29 +;; Version: 0.3.1 +;; Keywords: org, calendar + +;; This file is NOT part of Emacs. +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +;; MA 02110-1301, USA. + +;;; Commentary: +;; +;; Installation: +;; +;; (require 'ical2org) +;; + +;;; Code: + +(require 'icalendar) +(require 'org) +(eval-when-compile + (require 'cl)) + +(defconst ical2org/version "0.3.1") + +(defgroup ical2org nil + "Convert iCalendar files to orgmode files." + :link '(url-link :tag "Homepage" "http://github.com/cofi/ical2org") + :group 'calendar + :prefix "ical2org/") + +(defcustom ical2org/event-format +"* {SUMMARY} at {LOCATION} :{CATEGORY}: + {TIME} + {ORGANIZER} + {URL} + {DESCRIPTION}" + "String used to format an event. +Syntax is {FIELD} valid values for FIELD are: SUMMARY, LOCATION, TIME, URL, +DESCRIPTION, ORGANIZER, CATEGORY. Namely the slots of the `ical2org/event' +struct (capitalized)." + :type '(string)) + +(defcustom ical2org/category-separator ":" + "String used to separate multiple categories." + :type '(string)) + +(defcustom ical2org/completing-read #'ido-completing-read + "Function used for completing read. +Has to be compatible to `completing-read'." + :type '(function)) + +(defun ical2org/convert-file (fname outfile &optional nosave) + "Convert ical events from file `FNAME' to `OUTFILE' and save when `NOSAVE' is non-nil." + (interactive "fFile to convert: \nFSave as: \nP") + (let ((events + (with-temp-buffer + (insert-file-contents (expand-file-name fname)) + (ical2org/import-buffer (current-buffer))))) + (save-current-buffer + (find-file outfile) + (goto-char (point-max)) + (newline) + (dolist (e events) + (insert (ical2org/format e)) + (newline)) + (unless nosave + (save-buffer))))) + +(defun ical2org/import-to-agenda (fname &optional nosave) + "Import ical events from file `FNAME' to agenda file (will be prompted). +Saves when `NOSAVE' is non-nil." + (interactive "fFile to import: \nP") + (let ((agenda-file (funcall ical2org/completing-read + "Agenda file: " + (org-agenda-files))) + (events + (with-temp-buffer + (insert-file-contents (expand-file-name fname)) + (ical2org/import-buffer (current-buffer))))) + (save-current-buffer + (find-file agenda-file) + (goto-char (point-max)) + (newline) + (dolist (e events) + (insert (ical2org/format e)) + (newline)) + (unless nosave + (save-buffer))))) + +(defun ical2org/buffer-to-buffer (in out) + "Convert ical events from buffer `IN' to buffer `OUT'." + (interactive "bIn: \nBOut: ") + (save-current-buffer + (let ((events (ical2org/import-buffer in))) + (set-buffer (generate-new-buffer out)) + (dolist (e events) + (insert (ical2org/format e)) + (newline)) + (set-window-buffer nil out) + (org-mode)))) + +;; private + +;; output formatting +(defun ical2org/format (event) + "Replace formatstrings with slots of `EVENT'." + (replace-regexp-in-string "{.*?}" + (lambda (z) + (cdr (assoc z + `(("{SUMMARY}" . ,(ical2org/event-summary event)) + ("{LOCATION}" . ,(ical2org/event-location event)) + ("{TIME}" . ,(ical2org/event-org-timestr event)) + ("{URL}" . ,(ical2org/event-url event)) + ("{DESCRIPTION}" . ,(ical2org/event-description event)) + ("{ORGANIZER}" . ,(ical2org/event-organizer event)) + ("{CATEGORY}" . ,(mapconcat 'identity + (ical2org/event-category event) + ical2org/category-separator))) + ))) + ical2org/event-format + t t)) + +(defun ical2org/org-recurrent (event start-decoded start-time end-time) + "Wrap `icalendar--convert-recurring-to-diary' diary in an org timestamp." + (format "<%s>" + (icalendar--convert-recurring-to-diary event start-decoded + start-time end-time))) + +(defun ical2org/org-timestamp (start end) + "Format `START' and `END' as `org-time-stamp'." + (let ((start-time (nth 2 start)) + (end-time (nth 2 end)) + (start (car start)) + (end (car end))) + (if end + (format "%s--%s" (ical2org/org-time-fmt start start-time) + (ical2org/org-time-fmt end end-time)) + (if start + (ical2org/org-time-fmt start start-time))))) + +(defun ical2org/org-time-fmt (time &optional with-hm) + "Format `TIME' as `org-time-stamp', if `WITH-HM' is non-nil included hh:mm. +`TIME' is an decoded time as returned from `decode-time'." + (let ((fmt (if with-hm + (cdr org-time-stamp-formats) + (car org-time-stamp-formats))) + (encoded-time (apply 'encode-time time))) + (format-time-string fmt encoded-time))) + +;; entry processing + +(defstruct ical2org/event + (summary "") + (location "") + (org-timestr "") + (url "") + (description "") + (organizer "") + (category '())) + +(defun ics2org/datetime (property event zone-map) + "Return datetime values for `PROPERTY' of `EVENT' with `ZONE-MAP'. +Return a triple of (decoded isodate time). +Where `decoded' is a decoded datetime, + `isodate' a date as yy mm dd string, + `time' a time as hh:mm string." + (let* ((dt (icalendar--get-event-property event property)) + (zone (icalendar--find-time-zone + (icalendar--get-event-property-attributes event property) zone-map)) + (decoded (icalendar--decode-isodatetime dt nil zone-map))) + (list decoded + (icalendar--datetime-to-iso-date decoded) + (ignore-errors + (icalendar--datetime-to-colontime decoded))))) + +(defun ical2org/get-property (event property &optional default clean) + "Return `PROPERTY' of `EVENT' or `DEFAULT'." + (let ((prop (or (icalendar--get-event-property event property) + default))) + (if clean + (icalendar--convert-string-for-import prop) + prop))) + +(defun ical2org/get-org-timestr (event zone-map) + "Return org-timestring for `EVENT' with `ZONE-MAP'." + (let* ((start (ics2org/datetime 'DTSTART event zone-map)) + (start-day (nth 1 start)) + (start-time (nth 2 start)) + (end (ics2org/datetime 'DTEND event zone-map)) + (end-day (or (nth 1 end) start-day)) + (end-time (or (nth 2 end) start-time)) + (rrule (icalendar--get-event-property event 'RRULE)) + (rdate (icalendar--get-event-property event 'RDATE)) + (duration (icalendar--get-event-property event 'DURATION))) + (when duration + (let ((new-end (icalendar--add-decoded-times + (car start) + (icalendar--decode-isoduration duration)))) + (setq end-day (icalendar--datetime-to-iso-date new-end)) + (setq end-time (icalendar--datetime-to-colontime new-end)) + (setq end (list new-end end-day end-time)))) + + (cond + (rrule (ical2org/org-recurrent event (car start) start-time end-time)) + (t (ical2org/org-timestamp start end))))) + +(defun ical2org/extract-event (ical-event zone-map) + "Extracts `ical2org/event' from `ICAL-EVENT' using the timezone map `ZONE-MAP'." + (let ((summary (ical2org/get-property ical-event 'SUMMARY "" t)) + (location (ical2org/get-property ical-event 'LOCATION "" t)) + (org-timestr (ical2org/get-org-timestr ical-event zone-map)) + (url (ical2org/get-property ical-event 'URL "")) + (description (ical2org/get-property ical-event 'DESCRIPTION "" t)) + (organizer (ical2org/get-property ical-event 'ORGANIZER "" t)) + (category (split-string (ical2org/get-property ical-event 'CATEGORIES "" t) + "," t))) + (make-ical2org/event :summary summary + :location location + :org-timestr org-timestr + :url url + :description description + :organizer organizer + :category category))) + +(defun ical2org/import-elements (ical-elements) + "Collects events from `ICAL-ELEMENTS' into a list of `ical2org/event's." + (let ((events (icalendar--all-events ical-elements)) + (zone-map (icalendar--convert-all-timezones ical-elements))) + (loop for event in events + collect (ical2org/extract-event event zone-map)))) + +(defun ical2org/import-buffer (buffer) + "Return all events in icalendar `BUFFER' as `ical2org/event's." + (save-current-buffer + (set-buffer (icalendar--get-unfolded-buffer buffer)) + (goto-char (point-min)) + (if (re-search-forward "^BEGIN:VCALENDAR\\s-*$" nil t) + (progn + (beginning-of-line) + (ical2org/import-elements (icalendar--read-element nil nil))) + (message "Buffer does not contain icalendar contents!")))) + +(provide 'ical2org) + +;;; ical2org.el ends here diff --git a/site-lisp/term/screen-256color.el b/site-lisp/term/screen-256color.el new file mode 100644 index 0000000..f151dc0 --- /dev/null +++ b/site-lisp/term/screen-256color.el @@ -0,0 +1,7 @@ +(load "term/xterm") + +(defun terminal-init-screen () + "Terminal initialization function for screen." + ;; Use the xterm color initialization code. + (xterm-register-default-colors) + (tty-set-up-initial-frame-faces)) diff --git a/snippets/latex-mode/vorlage-gutachten b/snippets/latex-mode/vorlage-gutachten new file mode 100644 index 0000000..7505143 --- /dev/null +++ b/snippets/latex-mode/vorlage-gutachten @@ -0,0 +1,53 @@ +# -*- mode: snippet -*- +# name: gutachten-bachelorarbeit +# key: gutachten-bachelorarbeit +# -- +\documentclass[german]{tudletter} + +\usepackage[utf8]{inputenc} + +\usepackage{csquotes} +\usepackage[hidelinks]{hyperref} +%\renewcommand{\UrlFont}{\ttfamily\footnotesize} +\usepackage{textcomp} +\usepackage{ragged2e} +\usepackage{mathtools} + +\einrichtung{Fakultät Informatik} +\institut{Institut für Theoretische Informatik} +\professur{Professur für Automatentheorie} + +\bearbeiter{Daniel Borchmann} +\telefon{38351} +\telefax{37959} +\email{daniel.borchmann@tu-dresden.de} + +\besucheradrA{Sekretariat: Zi.~3021} +\besucheradrB{Nöthnitzer Straße 46} +\besucheradrC{01178 Dresden} +%\rollstuhladresse{N\"othnitzer Stra\ss{}e 46} +%\rollstuhlanmerkungen{Aufzug} +%\internet{http://lat.inf.tu-dresden.de/{\raise.2ex\hbox{$\scriptscriptstyle\sim$}}borch} +\internet{http://lat.inf.tu-dresden.de/\texttildelow{}borch} + +\signature{Daniel Borchmann} + +\subject{${1:Gutachten für Bachelorarbeit ...}} + +\begin{document} + +\makeatletter +\renewcommand{\@contact}{Gutachter:} +\makeatother + +\justifying{} + +\begin{letter}{} + + \opening{} + + $0 + +\end{letter} + +\end{document} diff --git a/snippets/text-mode/.yas-parents b/snippets/text-mode/.yas-parents new file mode 100644 index 0000000..d58dacb --- /dev/null +++ b/snippets/text-mode/.yas-parents @@ -0,0 +1 @@ +text-mode \ No newline at end of file diff --git a/snippets/text-mode/horg b/snippets/text-mode/horg new file mode 100644 index 0000000..4bf0e1b --- /dev/null +++ b/snippets/text-mode/horg @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: horg +# key: horg +# -- +[Misc] Updating org files \ No newline at end of file diff --git a/snippets/text-mode/sc b/snippets/text-mode/sc new file mode 100644 index 0000000..2fe6d4e --- /dev/null +++ b/snippets/text-mode/sc @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: sc +# key: sc +# -- +[Misc] Snapshot \ No newline at end of file diff --git a/snippets/text-mode/worg b/snippets/text-mode/worg new file mode 100644 index 0000000..b3b3b82 --- /dev/null +++ b/snippets/text-mode/worg @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: worg +# key: worg +# -- +[Admin] Updating org files \ No newline at end of file