From 60c67643661c04f35da82140668cb46e44e1680c Mon Sep 17 00:00:00 2001 From: Levi Olson Date: Wed, 10 Apr 2019 09:38:41 -0500 Subject: [PATCH] Mail; Diary; Calendar; Agenda/Todos --- init.el | 43 +++- init.elc | Bin 44276 -> 45299 bytes init.org | 565 ++++++++++++++++++++++------------------- scripts/expand-mime.sh | 0 4 files changed, 338 insertions(+), 270 deletions(-) mode change 100644 => 100755 scripts/expand-mime.sh diff --git a/init.el b/init.el index d8bf476..7661312 100644 --- a/init.el +++ b/init.el @@ -158,6 +158,17 @@ (defalias 'yes-or-no-p 'y-or-n-p) +(defvar diary-file (expand-file-name "~/.emacs.d/diary/main")) + +(add-hook 'diary-list-entries-hook 'diary-sort-entries t) +(add-hook 'diary-list-entries-hook 'diary-include-other-diary-files) +(add-hook 'diary-mark-entries-hook 'diary-mark-included-diary-files) +(add-hook 'calendar-today-visible-hook 'calendar-mark-today) + +(setq calendar-latitude 44 + calendar-longitude -97 + calendar-location-name "Hayti, SD") + (require 'font-lock) (defvar openhab-mode-hook nil) @@ -566,6 +577,7 @@ mu4e-context-policy 'pick-first mu4e-get-mail-command "mbsync -a" ;; MBSYNC is the mail cmd mu4e-html2text-command "/usr/local/bin/w3m -T text/html" ;; HTML to text command + mu4e-headers-include-related nil ;; Stop threading in INBOX mu4e-sent-messages-behavior 'delete ;; Delete sent messages mu4e-update-interval 300 ;; 5 mins mu4e-use-fancy-chars t ;; use 'fancy' chars @@ -584,9 +596,23 @@ smtpmail-smtp-service 587 ) -(defun mdmail-send-buffer () +(defun leo/convert-message-set-point () + "Set the point to the start of the message body." (interactive) - (shell-command-on-region (point-min) (point-max) "mdmail")) + (beginning-of-buffer) + (search-forward "--text follows this line--") + (forward-char) + ) +(defun leo/convert-message-from-markdown () + "Convert a markdown flavored mail buffer to html w/mime support." + (interactive) + (if (y-or-n-p "Convert to HTML? ") + ((leo/convert-message-set-point) + (save-excursion + (message-goto-body) + (shell-command-on-region (point) (point-max) "~/.emacs.d/scripts/expand-mime.sh" nil t))) + (message "Aborting.")) + ) (setq mu4e-contexts `( @@ -1342,6 +1368,7 @@ ARGS may be amongst :timeout, :icon, :urgency, :app and :category." (define-key custom-bindings (kbd "C-x C-l j") 'jabber) (define-key custom-bindings (kbd "C-x C-l f") 'elfeed) (define-key custom-bindings (kbd "C-x C-l a") 'org-agenda) +(define-key custom-bindings (kbd "C-x C-l c") 'calendar) (define-key custom-bindings (kbd "M-SPC") #'hyperspace) ;; (dolist (n (number-sequence 1 9)) ;; (global-set-key (kbd (concat "M-" (int-to-string n))) @@ -1460,3 +1487,15 @@ ARGS may be amongst :timeout, :icon, :urgency, :app and :category." ;; Whether display mu4e notifications or not. Requires `mu4e-alert' package. (setq doom-modeline-mu4e t) +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(magit-log-section-arguments (quote ("--graph" "--color" "--decorate" "-n256")))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) diff --git a/init.elc b/init.elc index 7952997ec6afc0f93527c40da355ce665995826c..ec3359202b3f5f5535f3d56bbf428dc95b52c495 100644 GIT binary patch delta 1945 zcmah~U2GIp6lQj(q!yc2lqm&5uUoZU?Cj3mduL`RrUC+5eyoI+2W1;N-I;Btot-H& z)0Rr=8c`655^{|Ni3lVWj4_zpnDFA8zW8RM1~r8EpfSdu7>Szjpl7E)fDigGC-;8$ z%$@I?^PMv{zDoW6ZR&#qjY2C68wdII#sPu#Hnld`t`$zpW!H1qZ+Ew?NVfTk<@y=6 zrfyx8D0+Jlt4fh51Re^HQOw*zYA33C2Z8}1i-<~_VXNH(MqdfWC=#sPU&M-$LHkOU z=lHf2%AOUw@r3Q5TS(v!15~{eD}i6&%f3}{kY(HQNDz#n`3O8Wie<--L)VFJ$D<%z z!cn~7?D{1SJ|_q9h!e`UQV=biSFCU>xvcuH+meHYx9vM#Tw)#vwlytJx{*8NIrB`G z&XU&?2Sh27O#@|mtm)Y8LVa5^D0B`?xS@l}fgj6WP#PORDVk;DlEmVs%Oa&JW(r=% z{!Z2Noy|Av(gmXM?NVA0bycH$cgs~+QPp6BGcD}e>`Jz`_2;x{Qnqc)*P@{sI%{9s zTW1i{$g;n-ZQ$qD9$Jwu6ewTc(JQ2>PFc`7mo6wOYsubBo4UzYZMc#WRg5Y7tm}=m zi3uN-O+kd}>Fi?eR}mAF@Hg{wLR!}h{+ODtOY0_PO_#RwkMwiPMP0!Lx4M5y?|-OB z2$nj)5~&j`m9k(pX#-eYdKj!Cb%8Y`Ia%k5gep=VtSW)TD3;U&2XRp%ffOl~K#WwA zG{7l;XY&;y?YkZy*s?;9MjXp_!bo1MbLfD=9BysZg=+gIYN9?TMo@b+9=JZNf@BlL zRv4q8oNOvi6j{R#8Vc;`Tw6n@?UXIgwIbBvIYGV@_>&F@Yr#v7oLHW}t9_q>GSDRo zT4)mBtzc06d=E`j7qma*47tbX7DlJ`Nr8{}GqNpdv5by%aSBtJd0^tXfu!8^VT)DP%Dj zbg*i}9%`oO@E8wflUV?RA(l$>%;LK{?@Oc07I;^M$;iX-d1Xya+i;D zG+tls5?~q>F!7aI;vozu-VglU`15Se>wfO zAk?$h&O9O9#lJjrzt9S`+p`R0tM)Bh{N3UD+Q4DWZ~fUadOHYCV~Oi1TYt8=GHGk@ r1vpON2|juD{ZvzCb+KH^Ed9`U=DZKZ#k#^@pPQ=X6Ux?f={xZsB)eSP delta 1007 zcmZ8gOK6={5YD;(xglvu^=kanq_*DNpvg^plm9&bb1-7Dv^JYIY3PgQHi^lf=9-sH zj0MGlRw9ix5(e8sDA7o0i^T}zA`8Kd;!3Sh@qr7wP^chXD6|k?bL-B<`Is~3%<#?3 zH^1LZ{qcS3!;>{^3ryAYZxm6lQi6_b#OpPEEHjmyoGDEu+2P5F=L=(#gQL)PUjt+_ zA9Lknfj?y)sSK3!nA#jLZepRZy8b(|d~Bh6rVjpW_$M$%!QWec;5JqUetdXe+InO2 z@O5V^9^LxV#z1R@-?r>yK_nHlw5|loMsU4#JuuSYm)qA;Jc^xyxwi9xb`qP~J>$Ys zuKwsY7v4zh5i2Z^!s5DYPY2Qn*mSKEo=_p4b90p`V}PB02>J%oD4)C$9DTH0VE7oJ z3Y!Ua*g|N+JYf{J654S4J$naX92R<&j>0xV5w_p+Q=7C5sZm;ml2C`LS49?+U26;* zcW+?0cTYPz(lV3`4~&%trnAlCL*oObvBGpRF;sYFW_UQ6$~GN~vN;Nik|9FT)GMPn zmpwK;l8lWN1}DeI2k7tQL}4m9QJS2{=Kf2OD`qtmpK5@eTkCPXv!gOCyl@UXx~?!X zjn#Oo`*Bt!y!R?!%mdqB2dxJiu-MZR@W?w09~~-jA%%y=!w0!g(!q;|SGdr^VbhUc zIhWcP%oO)BE}iyJJbr;I;RN12-pn{P%|cWE0#`HwT}K!keWXj9cMj%#3zy;4Y?r-7~9IK@^bAij)dK`J}2EBP{VCU>Ik@FIMnZ3xBu@YZ>eW6T_ z%Bnm20?`pt!@}G}u1zGc@J21Utch{=xr8jQV))?AtIGGD u3b^&oow||#xu2~lKaRqkcYCq4d^Lr+m2sM)R58NUQz>elj&akqpZUKxNG>t} diff --git a/init.org b/init.org index 896be2c..0fa3551 100644 --- a/init.org +++ b/init.org @@ -197,6 +197,19 @@ (defalias 'yes-or-no-p 'y-or-n-p) #+END_SRC +*** Diary + #+BEGIN_SRC emacs-lisp :results silent + (defvar diary-file (expand-file-name "~/.emacs.d/diary/main")) + + (add-hook 'diary-list-entries-hook 'diary-sort-entries t) + (add-hook 'diary-list-entries-hook 'diary-include-other-diary-files) + (add-hook 'diary-mark-entries-hook 'diary-mark-included-diary-files) + (add-hook 'calendar-today-visible-hook 'calendar-mark-today) + + (setq calendar-latitude 44 + calendar-longitude -97 + calendar-location-name "Hayti, SD") + #+END_SRC ** Custom Modes #+BEGIN_SRC emacs-lisp :results silent (require 'font-lock) @@ -284,252 +297,252 @@ #+END_SRC ** Custom Packages *** Hyperspace -#+BEGIN_SRC emacs-lisp :results silent - ;;; hyperspace.el --- Get there from here -*- lexical-binding: t; -*- - - ;; Copyright (C) 2017-2019 Ian Eure - - ;; Author: Ian Eure - ;; URL: https://github.com/ieure/hyperspace-el - ;; Version: 0.8.4 - ;; Package-Requires: ((emacs "25") (s "1.12.0")) - ;; Keywords: tools, convenience - - ;; This program is free software; you can redistribute it and/or modify - ;; it under the terms of the GNU General Public License as published by - ;; the Free Software Foundation, either version 3 of the License, or - ;; (at your option) any later version. - - ;; This program is distributed in the hope that it will be useful, - ;; but WITHOUT ANY WARRANTY; without even the implied warranty of - ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - ;; GNU General Public License for more details. - - ;; You should have received a copy of the GNU General Public License - ;; along with this program. If not, see . - - ;;; Commentary: - - ;; Hyperspace is a way to get nearly anywhere from wherever you are, - ;; whether that's within Emacs or on the web. It's somewhere in - ;; between Quicksilver and keyword URLs, giving you a single, - ;; consistent interface to get directly where you want to go. It’s - ;; for things that you use often, but not often enough to justify a - ;; dedicated binding. - ;; - ;; When you enter Hyperspace, it prompts you where to go: - ;; - ;; HS: - ;; - ;; This prompt expects a keyword and a query. The keyword picks where - ;; you want to go, and the remainder of the input is an optional - ;; argument which can be used to further search or direct you within - ;; that space. - ;; - ;; Some concrete examples: - ;; - ;; | *If you enter* | *then Hyperspace* | - ;; |------------------+----------------------------------------------------------| - ;; | "el" | opens info node "(elisp)Top" | - ;; | "el eval-region" | searches for "eval-region" in the elisp Info index | - ;; | "bb" | shows all BBDB entries | - ;; | "bb kenneth" | shows all BBDB entries with a name matching "kenneth" | - ;; | "ddg foo" | searches DuckDuckGo for "foo" using browse-url | - ;; | "wp foo" | searches Wikipedia for "foo" using browse-url | - ;; - - ;;; Code: - - (require 'subr-x) - (require 's) - - ;; Action helpers - - (defun hyperspace-action->browse-url-pattern (pattern query) - "Browse a URL former from PATTERN and QUERY." - (browse-url (format pattern query))) - - (defun hyperspace-action->info (node &optional query) - "Open an Info buffer for NODE. - - If QUERY is present, look it up in the index." - (info node) - (when query - (Info-index query))) - - ;; Package definitions - - (defvar hyperspace-history nil - "History of Hyperspace actions.") - - (defgroup hyperspace nil - "Getting there from here" - :prefix "hyperspace-" - :group 'applications) - - (defcustom hyperspace-actions - '(("ddg" . "https://duckduckgo.com/?q=%s") - ("dis" . "https://duckduckgo.com/?q=%s&iax=images&ia=images") - ("wp" . "https://en.wikipedia.org/wiki/%s") - ("g" . "https://www.google.com/search?q=%s") - ("gi" . "https://www.google.com/search?tbm=isch&q=%s") - ("gm" . "https://www.google.com/maps/search/%s") - ("yt" . "https://www.youtube.com/results?search_query=%s") - ("clp" . "https://portland.craigslist.org/search/sss?query=%s") - ("eb" . "https://www.ebay.com/sch/i.html?_nkw=%s") - ("nf" . "https://www.netflix.com/search?q=%s") - ("sh" . (lambda (query) (interactive) (shell-command query))) - ("imdb" . "https://www.imdb.com/find?q=peter+jackson&s=all") - ("bb" . bbdb-search-name) - ("el" . (apply-partially #'hyperspace-action->info "(elisp)Top")) - ("av" . apropos-variable) - ("ac" . apropos-command) - ("af" . (lambda (query) (apropos-command query t)))) - - "Where Hyperspace should send you. - - Hyperspace actions are a cons of (KEYWORD . DISPATCHER). When - Hyperspace is invoked, the keyword is extracted from the user - input and looked up in this alist. The remainder of the - string is passed to the dispatcher as its QUERY argument. - - DISPATCHER can be a function which performs the action. - - DISPATCHER can also be an expression which returns a function - to perform the action. - - Finally, DISPATCHER can be a string with a URL pattern containing - '%s'. The '%s' will be replaced with the query, and the URL browsed." - - :group 'hyperspace - :type '(alist :key-type (string :tag "Keyword") - :value-type (choice - (function :tag "Function") - (string :tag "URL Pattern") - (sexp :tag "Expression")))) - - (defcustom hyperspace-default-action - (caar hyperspace-actions) - "A place to go if you don't specify one." - :group 'hyperspace - :type `(radio - ,@(mapcar (lambda (action) (list 'const (car action))) hyperspace-actions))) - - (defcustom hyperspace-max-region-size 256 - "Maximum size of a region to consider for a Hyperspace query. - - If the region is active when Hyperspace is invoked, it's used - as the default query, unless it's more than this number of - characters." - :group 'hyperspace - :type 'integer) - - - - (defun hyperspace--cleanup (text) - "Clean TEXT so it can be used for a Hyperspace query." - (save-match-data - (string-trim - (replace-regexp-in-string (rx (1+ (or blank "\n"))) " " text)))) - - (defun hyperspace--initial-text () - "Return the initial text. - - This is whatever's in the active region, but cleaned up." - (when (use-region-p) - (let* ((start (region-beginning)) - (end (region-end)) - (size (- end start))) - (when (<= size hyperspace-max-region-size) - (hyperspace--cleanup - (buffer-substring-no-properties start end)))))) - - (defun hyperspace--initial (initial-text) - "Turn INITIAL-TEXT into INITIAL-CONTENTS for reading." - (when initial-text (cons (concat " " initial-text) 1))) - - (defun hyperspace--process-input (text) - "Process TEXT into an actionable keyword and query." - (let ((kw-text (s-split-up-to "\\s-+" text 1))) - (if (assoc (car kw-text) hyperspace-actions) - kw-text - (list hyperspace-default-action text)))) - - (defun hyperspace--query () - "Ask the user for the Hyperspace action and query. - - Returns (KEYWORD . QUERY). - - If the region isn't active, the user is prompted for the - action and query. - - If the region is active, its text is used as the initial value - for the query, and the user enters the action. - - If a prefix argument is specified and the region is active, - `HYPERSPACE-DEFAULT-ACTION' is chosen without prompting." - - (let ((initial (hyperspace--initial-text))) - (if (and initial current-prefix-arg) - (list hyperspace-default-action initial) - (hyperspace--process-input - (read-from-minibuffer "HS: " (hyperspace--initial initial) nil nil - 'hyperspace-history))))) - - (defun hyperspace--evalable-p (form) - "Can FORM be evaluated?" - (and (listp form) - (or (functionp (car form)) - (subrp (car form))))) - - (defun hyperspace--dispatch (action &optional query) - "Execute ACTION, with optional QUERY argument." - (pcase action - ((pred functionp) (funcall action query)) - ((pred hyperspace--evalable-p) (funcall (eval action) query)) - ((pred stringp) (hyperspace-action->browse-url-pattern action query)) - (_ (error "Unknown action")))) - - ;;;###autoload - (defun hyperspace (keyword &optional query) - "Execute action for keyword KEYWORD, with optional QUERY." - (interactive (hyperspace--query)) - (let ((action (cdr (assoc keyword hyperspace-actions)))) - (hyperspace--dispatch (or action hyperspace-default-action) query))) - - ;;;###autoload - (defun hyperspace-enter (&optional query) - "Enter Hyperspace, sending QUERY to the default action. - - If the region is active, use that as the query for - ‘hyperspace-default-action’. Otherwise, prompt the user." - (interactive (list (hyperspace--initial-text))) - (hyperspace - hyperspace-default-action - (or query - (read-from-minibuffer - (format "HS: %s " hyperspace-default-action) nil nil - 'hyperspace-history)))) - - ;; Minor mode - - (defvar hyperspace-minor-mode-map - (let ((kmap (make-sparse-keymap))) - (define-key kmap (kbd "H-SPC") #'hyperspace) - (define-key kmap (kbd "") #'hyperspace-enter) - kmap)) - - ;;;###autoload - (define-minor-mode hyperspace-minor-mode - "Global (universal) minor mode to jump from here to there." - nil nil hyperspace-minor-mode-map - :group 'hyperspace - :global t) - - (provide 'hyperspace) - - ;;; hyperspace.el ends here -#+END_SRC + #+BEGIN_SRC emacs-lisp :results silent + ;;; hyperspace.el --- Get there from here -*- lexical-binding: t; -*- + + ;; Copyright (C) 2017-2019 Ian Eure + + ;; Author: Ian Eure + ;; URL: https://github.com/ieure/hyperspace-el + ;; Version: 0.8.4 + ;; Package-Requires: ((emacs "25") (s "1.12.0")) + ;; Keywords: tools, convenience + + ;; This program is free software; you can redistribute it and/or modify + ;; it under the terms of the GNU General Public License as published by + ;; the Free Software Foundation, either version 3 of the License, or + ;; (at your option) any later version. + + ;; This program is distributed in the hope that it will be useful, + ;; but WITHOUT ANY WARRANTY; without even the implied warranty of + ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ;; GNU General Public License for more details. + + ;; You should have received a copy of the GNU General Public License + ;; along with this program. If not, see . + + ;;; Commentary: + + ;; Hyperspace is a way to get nearly anywhere from wherever you are, + ;; whether that's within Emacs or on the web. It's somewhere in + ;; between Quicksilver and keyword URLs, giving you a single, + ;; consistent interface to get directly where you want to go. It’s + ;; for things that you use often, but not often enough to justify a + ;; dedicated binding. + ;; + ;; When you enter Hyperspace, it prompts you where to go: + ;; + ;; HS: + ;; + ;; This prompt expects a keyword and a query. The keyword picks where + ;; you want to go, and the remainder of the input is an optional + ;; argument which can be used to further search or direct you within + ;; that space. + ;; + ;; Some concrete examples: + ;; + ;; | *If you enter* | *then Hyperspace* | + ;; |------------------+----------------------------------------------------------| + ;; | "el" | opens info node "(elisp)Top" | + ;; | "el eval-region" | searches for "eval-region" in the elisp Info index | + ;; | "bb" | shows all BBDB entries | + ;; | "bb kenneth" | shows all BBDB entries with a name matching "kenneth" | + ;; | "ddg foo" | searches DuckDuckGo for "foo" using browse-url | + ;; | "wp foo" | searches Wikipedia for "foo" using browse-url | + ;; + + ;;; Code: + + (require 'subr-x) + (require 's) + + ;; Action helpers + + (defun hyperspace-action->browse-url-pattern (pattern query) + "Browse a URL former from PATTERN and QUERY." + (browse-url (format pattern query))) + + (defun hyperspace-action->info (node &optional query) + "Open an Info buffer for NODE. + + If QUERY is present, look it up in the index." + (info node) + (when query + (Info-index query))) + + ;; Package definitions + + (defvar hyperspace-history nil + "History of Hyperspace actions.") + + (defgroup hyperspace nil + "Getting there from here" + :prefix "hyperspace-" + :group 'applications) + + (defcustom hyperspace-actions + '(("ddg" . "https://duckduckgo.com/?q=%s") + ("dis" . "https://duckduckgo.com/?q=%s&iax=images&ia=images") + ("wp" . "https://en.wikipedia.org/wiki/%s") + ("g" . "https://www.google.com/search?q=%s") + ("gi" . "https://www.google.com/search?tbm=isch&q=%s") + ("gm" . "https://www.google.com/maps/search/%s") + ("yt" . "https://www.youtube.com/results?search_query=%s") + ("clp" . "https://portland.craigslist.org/search/sss?query=%s") + ("eb" . "https://www.ebay.com/sch/i.html?_nkw=%s") + ("nf" . "https://www.netflix.com/search?q=%s") + ("sh" . (lambda (query) (interactive) (shell-command query))) + ("imdb" . "https://www.imdb.com/find?q=peter+jackson&s=all") + ("bb" . bbdb-search-name) + ("el" . (apply-partially #'hyperspace-action->info "(elisp)Top")) + ("av" . apropos-variable) + ("ac" . apropos-command) + ("af" . (lambda (query) (apropos-command query t)))) + + "Where Hyperspace should send you. + + Hyperspace actions are a cons of (KEYWORD . DISPATCHER). When + Hyperspace is invoked, the keyword is extracted from the user + input and looked up in this alist. The remainder of the + string is passed to the dispatcher as its QUERY argument. + + DISPATCHER can be a function which performs the action. + + DISPATCHER can also be an expression which returns a function + to perform the action. + + Finally, DISPATCHER can be a string with a URL pattern containing + '%s'. The '%s' will be replaced with the query, and the URL browsed." + + :group 'hyperspace + :type '(alist :key-type (string :tag "Keyword") + :value-type (choice + (function :tag "Function") + (string :tag "URL Pattern") + (sexp :tag "Expression")))) + + (defcustom hyperspace-default-action + (caar hyperspace-actions) + "A place to go if you don't specify one." + :group 'hyperspace + :type `(radio + ,@(mapcar (lambda (action) (list 'const (car action))) hyperspace-actions))) + + (defcustom hyperspace-max-region-size 256 + "Maximum size of a region to consider for a Hyperspace query. + + If the region is active when Hyperspace is invoked, it's used + as the default query, unless it's more than this number of + characters." + :group 'hyperspace + :type 'integer) + + + + (defun hyperspace--cleanup (text) + "Clean TEXT so it can be used for a Hyperspace query." + (save-match-data + (string-trim + (replace-regexp-in-string (rx (1+ (or blank "\n"))) " " text)))) + + (defun hyperspace--initial-text () + "Return the initial text. + + This is whatever's in the active region, but cleaned up." + (when (use-region-p) + (let* ((start (region-beginning)) + (end (region-end)) + (size (- end start))) + (when (<= size hyperspace-max-region-size) + (hyperspace--cleanup + (buffer-substring-no-properties start end)))))) + + (defun hyperspace--initial (initial-text) + "Turn INITIAL-TEXT into INITIAL-CONTENTS for reading." + (when initial-text (cons (concat " " initial-text) 1))) + + (defun hyperspace--process-input (text) + "Process TEXT into an actionable keyword and query." + (let ((kw-text (s-split-up-to "\\s-+" text 1))) + (if (assoc (car kw-text) hyperspace-actions) + kw-text + (list hyperspace-default-action text)))) + + (defun hyperspace--query () + "Ask the user for the Hyperspace action and query. + + Returns (KEYWORD . QUERY). + + If the region isn't active, the user is prompted for the + action and query. + + If the region is active, its text is used as the initial value + for the query, and the user enters the action. + + If a prefix argument is specified and the region is active, + `HYPERSPACE-DEFAULT-ACTION' is chosen without prompting." + + (let ((initial (hyperspace--initial-text))) + (if (and initial current-prefix-arg) + (list hyperspace-default-action initial) + (hyperspace--process-input + (read-from-minibuffer "HS: " (hyperspace--initial initial) nil nil + 'hyperspace-history))))) + + (defun hyperspace--evalable-p (form) + "Can FORM be evaluated?" + (and (listp form) + (or (functionp (car form)) + (subrp (car form))))) + + (defun hyperspace--dispatch (action &optional query) + "Execute ACTION, with optional QUERY argument." + (pcase action + ((pred functionp) (funcall action query)) + ((pred hyperspace--evalable-p) (funcall (eval action) query)) + ((pred stringp) (hyperspace-action->browse-url-pattern action query)) + (_ (error "Unknown action")))) + + ;;;###autoload + (defun hyperspace (keyword &optional query) + "Execute action for keyword KEYWORD, with optional QUERY." + (interactive (hyperspace--query)) + (let ((action (cdr (assoc keyword hyperspace-actions)))) + (hyperspace--dispatch (or action hyperspace-default-action) query))) + + ;;;###autoload + (defun hyperspace-enter (&optional query) + "Enter Hyperspace, sending QUERY to the default action. + + If the region is active, use that as the query for + ‘hyperspace-default-action’. Otherwise, prompt the user." + (interactive (list (hyperspace--initial-text))) + (hyperspace + hyperspace-default-action + (or query + (read-from-minibuffer + (format "HS: %s " hyperspace-default-action) nil nil + 'hyperspace-history)))) + + ;; Minor mode + + (defvar hyperspace-minor-mode-map + (let ((kmap (make-sparse-keymap))) + (define-key kmap (kbd "H-SPC") #'hyperspace) + (define-key kmap (kbd "") #'hyperspace-enter) + kmap)) + + ;;;###autoload + (define-minor-mode hyperspace-minor-mode + "Global (universal) minor mode to jump from here to there." + nil nil hyperspace-minor-mode-map + :group 'hyperspace + :global t) + + (provide 'hyperspace) + + ;;; hyperspace.el ends here + #+END_SRC ** Tools *** General @@ -631,6 +644,7 @@ mu4e-context-policy 'pick-first mu4e-get-mail-command "mbsync -a" ;; MBSYNC is the mail cmd mu4e-html2text-command "/usr/local/bin/w3m -T text/html" ;; HTML to text command + mu4e-headers-include-related nil ;; Stop threading in INBOX mu4e-sent-messages-behavior 'delete ;; Delete sent messages mu4e-update-interval 300 ;; 5 mins mu4e-use-fancy-chars t ;; use 'fancy' chars @@ -649,9 +663,23 @@ smtpmail-smtp-service 587 ) - (defun mdmail-send-buffer () + (defun leo/convert-message-set-point () + "Set the point to the start of the message body." (interactive) - (shell-command-on-region (point-min) (point-max) "mdmail")) + (beginning-of-buffer) + (search-forward "--text follows this line--") + (forward-char) + ) + (defun leo/convert-message-from-markdown () + "Convert a markdown flavored mail buffer to html w/mime support." + (interactive) + (if (y-or-n-p "Convert to HTML? ") + ((leo/convert-message-set-point) + (save-excursion + (message-goto-body) + (shell-command-on-region (point) (point-max) "~/.emacs.d/scripts/expand-mime.sh" nil t))) + (message "Aborting.")) + ) (setq mu4e-contexts `( @@ -1007,26 +1035,26 @@ (run-at-time time nil (lambda (msg) (terminal-notifier-notify "Emacs" msg)) msg)) #+END_SRC *** Hyperspace -#+BEGIN_SRC emacs-lisp :results silent - (defun hyperspace-action->mu4e (&optional query) - "Search mu4e with QUERY. - - If QUERY is unspecified, use the first bookmark in variable - ‘mu4e-bookmarks’ and update mail and index." - - (mu4e-headers-search (or query (caar mu4e-bookmarks))) - (unless query - (mu4e-update-mail-and-index nil))) - (add-to-list 'hyperspace-actions '("m4" . hyperspace-action->mu4e)) - - (defun hyperspace-action->elfeed (&optional query) - "Load elfeed, optionally searching for QUERY." - (elfeed) - (if query - (elfeed-search-set-filter query) - (elfeed-search-fetch nil))) - (add-to-list 'hyperspace-actions '("lf" . hyperspace-action->elfeed)) -#+END_SRC + #+BEGIN_SRC emacs-lisp :results silent + (defun hyperspace-action->mu4e (&optional query) + "Search mu4e with QUERY. + + If QUERY is unspecified, use the first bookmark in variable + ‘mu4e-bookmarks’ and update mail and index." + + (mu4e-headers-search (or query (caar mu4e-bookmarks))) + (unless query + (mu4e-update-mail-and-index nil))) + (add-to-list 'hyperspace-actions '("m4" . hyperspace-action->mu4e)) + + (defun hyperspace-action->elfeed (&optional query) + "Load elfeed, optionally searching for QUERY." + (elfeed) + (if query + (elfeed-search-set-filter query) + (elfeed-search-fetch nil))) + (add-to-list 'hyperspace-actions '("lf" . hyperspace-action->elfeed)) + #+END_SRC ** Development Specific *** General #+BEGIN_SRC emacs-lisp :results silent @@ -1468,6 +1496,7 @@ (define-key custom-bindings (kbd "C-x C-l j") 'jabber) (define-key custom-bindings (kbd "C-x C-l f") 'elfeed) (define-key custom-bindings (kbd "C-x C-l a") 'org-agenda) + (define-key custom-bindings (kbd "C-x C-l c") 'calendar) (define-key custom-bindings (kbd "M-SPC") #'hyperspace) ;; (dolist (n (number-sequence 1 9)) ;; (global-set-key (kbd (concat "M-" (int-to-string n))) diff --git a/scripts/expand-mime.sh b/scripts/expand-mime.sh old mode 100644 new mode 100755