diff --git a/settings/eaf-settings.el b/settings/eaf-settings.el new file mode 100644 index 00000000..20f3e25a --- /dev/null +++ b/settings/eaf-settings.el @@ -0,0 +1,34 @@ +;;; eaf-settings.el --- eaf settings -*- lexical-binding: t -*- + +;;; Commentary: +;; https://www.emacswiki.org/emacs/EmacsApplicationFramework +;; https://github.com/manateelazycat/emacs-application-framework + +;;; Code: +(use-package eaf + :load-path (lambda() (concat user-emacs-directory "lisp/emacs-application-framework")) + ;;:after (org) ;; eaf requires eaf-interleave requires org + ;;:defer 2 + :commands (eaf-open + eaf-open-browser + eaf-open-browser-with-history + eaf-open-mail-as-html + eaf-open-camera + eaf-open-terminal + eaf-file-sender-qrcode eaf-file-sender-qrcode-in-dired + eaf-file-browser-qrcode + eaf-open-airshare + eaf-open-rss-reader + eaf-open-mindmap eaf-create-minmap + eaf-open-office + eaf-open-demo) + ;; :unless (string= (system-name) "hasp138dw") + ;;:when (if (require 'dbus) (dbus-ping :session "org.freedesktop.Notifications")) + :if my-dbusp ;; EAF use DBus' session bus, it must run by a general user (DO NOT USE as root). + :config + (setq eaf-find-alternate-file-in-dired t) + (setq eaf-config-location (concat user-cache-directory "eaf/")) + ) + +(provide 'eaf-settings) +;;; eaf-settings.el ends here diff --git a/settings/ess-settings.el b/settings/ess-settings.el new file mode 100644 index 00000000..db90fadc --- /dev/null +++ b/settings/ess-settings.el @@ -0,0 +1,36 @@ +;;; ess-settings.el --- ess settings -*- lexical-binding: t -*- + +;;; Commentary: +;; R (ESS) +;; https://melpa.org/#/ess +;; https://github.com/emacs-ess/ESS +;; https://ess.r-project.org/ +;; https://ess.r-project.org/Manual/ess.html +;; https://www.emacswiki.org/emacs/EmacsSpeaksStatistics + +;; Requirements: +;; ess +;; ess-R-data-view +;; ctable popup + +;; TODO: +;; install lintr for syntax checking + +;;; Code: +(use-package ess-site ;; all ESS features + :load-path (lambda() (concat user-emacs-directory "lisp/ess")) + :commands ess-r-mode ;; only R related features + ) +(use-package ess-R-data-view + :after (ess-r-mode)) + +(use-package company-statistics + :after (ess-r-mode company) + :config + (setq company-statistics-file (concat user-cache-directory + "company-statistics-cache.el")) + ;;(add-hook 'company-mode-hook 'company-statistics-mode) + ) + +(provide 'ess-settings) +;;; ess-settings.el ends here diff --git a/settings/filetype-settings.el b/settings/filetype-settings.el new file mode 100644 index 00000000..ca787439 --- /dev/null +++ b/settings/filetype-settings.el @@ -0,0 +1,27 @@ +;;; filetype-settings.el --- Summary -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Requirements: +;; markdown-mode https://melpa.org/#/markdown-mode +;; sql-indent https://elpa.gnu.org/packages/sql-indent.html https://github.com/alex-hhh/emacs-sql-indent +;; sqlup-mode also? +;; systemd https://melpa.org/#/systemd + +;;; Code: + +(use-package markdown-mode + :commands markdown-mode + :mode "\\.md\\'") + +(use-package sql-indent + :load-path (lambda() (concat user-emacs-directory "lisp/sql-indent")) + :commands sqlind-minor-mode) + +(use-package systemd + :load-path (lambda() (concat user-emacs-directory "lisp/systemd")) + :commands systemd-mode + :mode (("\\.service\\'" . systemd-mode) ("\\.mount\\'" . systemd-mode))) + +(provide 'filetype-settings) +;;; filetype-settings.el ends here diff --git a/settings/ledger-settings.el b/settings/ledger-settings.el new file mode 100644 index 00000000..418a102d --- /dev/null +++ b/settings/ledger-settings.el @@ -0,0 +1,44 @@ +;;; ledger-settings.el --- ledger settings -*- lexical-binding: t -*- + +;;; Commentary: +;; https://github.com/ledger/ledger-mode + +;; Requirements: +;; programs +;; ledger https://www.ledger-cli.org/download.html +;; Emacs packages +;; ledger-mode ;; https://melpa.org/#/ledger-mode +;; org +;; flycheck-ledger ;; https://melpa.org/#/flycheck-ledger +;; company-ledger ;; https://melpa.org/#/company-ledger + +;;; Code: +(use-package ledger-mode + :load-path (lambda() (concat user-emacs-directory "lisp/ledger-mode")) + :delight + (ledger-mode "๐Ÿ…›๏ฝ„") ; "Le " + (ledger-report-mode "๐Ÿ…›dr") ; "LeR ๐Ÿ…–โ’ญ" + :commands ledger-mode + :mode "\\.ledger\\'" + :config + (setq ledger-post-account-alignment-column 2) + (setq ledger-post-amount-alignment-column 62) + ) + +(use-package flycheck-ledger + :after (ledger-mode flycheck) + ) + +(use-package company-ledger + :after (ledger-mode company) + :config + ;;(add-to-list 'company-backends 'company-ledger) + ;; Only use company-mode with company-ledger in ledger-mode + (add-hook 'ledger-mode-hook + (lambda () + (set (make-local-variable 'company-backends) + '(company-ledger company-capf company-files)))) + ) + +(provide 'ledger-settings) +;;; ledger-settings.el ends here diff --git a/settings/mail-settings.el b/settings/mail-settings.el new file mode 100644 index 00000000..d256a361 --- /dev/null +++ b/settings/mail-settings.el @@ -0,0 +1,354 @@ +;;; mail-settings.el --- Mail settings -*- lexical-binding: t -*- + +;;; Commentary: +;; https://kkatsuyuki.github.io/notmuch-conf/ +;; https://opensource.com/article/20/1/organize-email-notmuch +;; https://notmuchmail.org/emacstips/ +;; https://bostonenginerd.com/posts/notmuch-of-a-mail-setup-part-2-notmuch-and-emacs/ + +;; `mm-text-html-renderer' + +;; `mailcap-parse-mailcaps' in mailcap.el uses a given path or the +;; value of environment variable MAILCAPS if set or either +;; ("~/.mailcap", "/etc/mailcap", "/usr/etc/mailcap", +;; "/usr/local/etc/mailcap") for *nix or ("~/.mailcap", "~/mail.cap", +;; "~/etc/mail.cap") for `mailcap-poor-system-types'. parsed +;; mailcaps, see `mailcap-parsed-p', are in `mailcap-mime-data'. + +;; `notmuch-show-view-part' `mm-inlined-types' +;; `notmuch-show-attachment-debug' + +;;; Requirments: +;; (mu / mu4e) +;; mu4e-maildirs-extension https://melpa.org/#/mu4e-maildirs-extension https://github.com/agpchil/mu4e-maildirs-extension https://www.djcbsoftware.nl/code/mu/mu4e/ +;; (notmuch) + +;;; Code: +(use-package message + :defer t + :config + (set-face-attribute 'message-header-name nil :foreground "#4f97d7") + (set-face-attribute 'message-header-subject nil :foreground "#bc6ec5") + (set-face-attribute 'message-header-to nil :foreground "#c56ec3") + (set-face-attribute 'message-header-cc nil :foreground "#c56ec3") + (set-face-attribute 'message-header-other nil :foreground "#ce537a") + (set-face-attribute 'message-cited-text nil :foreground "#9f8766") + (set-face-attribute 'message-mml nil :foreground "#86dc2f") ;; mime meta language + ;; define in custom.el user-mail-address, user-full-name + (setq message-directory "~/.local/share/mail/") ;; sent mails + (setq message-auto-save-directory "~/.local/share/mail/drafts/") ;; drafts + (setq message-kill-buffer-on-exit t) ;; after sending mail + (setq mm-text-html-renderer 'shr)) + +(defgroup my-mu4e nil + "My mu4e concept mapping" + :prefix "my-mu4e-" + :group 'my) + +(defcustom my-mu4e-sync 'test + "One of `test', `offlineimap' and `mbsync'. +see also `my-mu4e-offlineimap-command' and `my-mu4e-mbsync-command'. + +`mu4e-get-mail-command' and `mu4e-change-filenames-when-moving' will +be set according to this variable." + :group 'my-mu4e + :type '(choice + symbol + (const :tag "test" test) + (const :tag "offlineimap" offlineimap) + (const :tag "mbsync" mbsync))) + +(defcustom my-mu4e-offlineimap-command "offlineimap" + "Oflineimap command used for mu4e if set in `my-mu4e-sync'." + :group 'my-mu4e + :type '(choice string (const :tag "offlineimap" "offlineimap"))) + +(defcustom my-mu4e-mbsync-command "mbsync" + "mbsync command used for mu4e if set in `my-mu4e-sync'." + :group 'my-mu4e + :type '(choice string (const :tag "mbsync" "mbsync"))) + +(defcustom my-mu4e-bookmarks + '((:name "Unread messages" + :query "flag:unread AND NOT flag:trashed" + :key ?u) + (:name "Today's messages" + :query "date:today..now" + :key ?t) + (:name "Last 7 days" + :query "date:7d..now" + :hide-unread t + :key ?w) + (:name "Messages with images" + :query "mime:image/*" + :key ?p)) + "Documention see `mu4e-bookmarks' in `mu4e-vars.el'. + +:query same as \"mu find xxx\"" + :group 'my-mu4e + :type '(repeat (plist))) + +(defcustom my-mu4e-attachment-dir (expand-file-name "~/") + "Documention see `mu4e-attachment-dir' in `mu4e-vars.el'." + :group 'my-mu4e + :type '(choice + directory + (const :tag "~/" "~/") + (const :tag "~/Downloads" "~/Downloads")) + :safe 'stringp) + +(defcustom my-mu4e-contexts nil + "Documention see `mu4e-contexts' in `mu4e-context.el'." + :group 'my-mu4e + :type '(list)) + +(defcustom my-mu4e-user-mailing-lists nil + "Documention see `mu4e-user-mailing-lists' in `mu4e-lists.el'." + :group 'my-mu4e + :type '(repeat (cons string string))) + +;; note `mu4e-headers-results-limit' +;; headers view +;; [/] `mu4e-headers-search-narrow' - filter messages in current search query (x AND y) +;; [\] `mu4e-headers-query-prev' - go back to previous search query +(use-package mu4e + :delight + (mu4e-main-mode "๐Ÿ…œ๏ฝ") + (mu4e-headers-mode "๐Ÿ…œ๏ฝˆ") ;; will be overwitten with `mu4e~headers-search-execute' + (mu4e-view-mode "๐Ÿ…œ๏ฝ–") + (mu4e~update-mail-mode "๐Ÿ…œ๏ฝ•") + :commands mu4e + :config + ;; allow to display emoji in the subject lines of the emails + (delete 'mu4e-headers-mode emojify-inhibit-major-modes) ;; https://github.com/iqbalansari/emacs-emojify/issues/39 + + ;; set `mu4e-get-mail-command' (runs mu index afterwards, by default key U in main or C-c C-u else) + ;; and `mu4e-change-filenames-when-moving' + ;; no default cond for custom settings + (cond ((eq my-mu4e-sync 'test) + "reset to saved (`custom-set-variables') or standard (if not saved) value" + (custom-reevaluate-setting 'mu4e-get-mail-command) ;; true for testing + (custom-reevaluate-setting 'mu4e-change-filenames-when-moving)) + ((eq my-mu4e-sync 'offlineimap) + (setq mu4e-get-mail-command my-mu4e-offlineimap-command) + (setq mu4e-change-filenames-when-moving nil)) ;; nil better for offlineimap + ((eq my-mu4e-sync 'mbsync) + (setq mu4e-get-mail-command my-mu4e-mbsync-command) + (setq mu4e-change-filenames-when-moving t))) ;; t better for mbsync + + ;;; vars + (setq mu4e-completing-read-function 'ivy-completing-read) + (setq mu4e-confirm-quit nil) + (setq mu4e-use-fancy-chars nil) ;; use unicodes for fancy tags etc. But this does not means emojis are activated. + (setq mu4e-bookmarks my-mu4e-bookmarks) + (setq mu4e-attachment-dir my-mu4e-attachment-dir) + + ;;; headers + ;;(setq mu4e-headers-results-limit 500) ;; to ignore the limit for one query press a C-u before invoking the search. consider narrowing the search instead of increasing the limit number + (setq mu4e-headers-fields '((:human-date . 12) + (:flags . 6) + (:mailing-list . 10) + ;;(:from . 22) + (:from-or-to . 22) ;; :from-or-to shows From: except when the e-mail was sent by the user (i.e., you) in that case it shows To: (prefixed by To, see also `mu4e-headers-from-or-to-prefix') + (:subject))) + ;;(setq mu4e-headers-from-or-to-prefix '("" . "To ")) ;; prefix "To " for sent messages + + ;;; message + ;;(setq mu4e-html2text-command ...) + + ;;; view + (setq mu4e-view-show-images t) + (setq mu4e-view-show-addresses t) + (add-to-list 'mu4e-headers-actions '("view in browser" . mu4e-action-view-in-browser)) + (add-to-list 'mu4e-view-actions '("view in browser" . mu4e-action-view-in-browser)) + + ;;; actions + (setq mu4e-action-tags-header "X-Keywords") ;; for e.g. gmail + + ;;; compose + ;; use mu4e for e-mail in emacs + (setq mail-user-agent 'mu4e-user-agent) ;; for completion for To, CC, BSS fields + ;; (setq mu4e-sent-messages-behavior 'delete) ;; TODO: sent is automatic done via server? therefore delete? + + ;;; draft + ;;(defalias 'mu4e-compose-signature 'message-signature) ;; point to `message-signature' + (setq mu4e-compose-signature-auto-include nil) ;; see also `mu4e-compose-signature defined in contexts + + ;;; context + ;; switch context with M-x mu4e-context-switch (force reload (if same context) with prefix-argument C-u) + ;; see current context with M-x mu4e-context-current + (setq mu4e-contexts my-mu4e-contexts) + (defun my-mu4e-message-maildir-matches (msg rx) + "helper to determine which account context to use based on the +folder in maildir the email (eg. ~/.mail/work) is located in." + (when rx + (if (listp rx) + ;; If rx is a list, try each one for a match + (or (mu4e-message-maildir-matches msg (car rx)) + (mu4e-message-maildir-matches msg (cdr rx))) + ;; Not a list, check rx + (string-match rx (mu4e-message-field msg :maildir))))) + ;; overwite in custom.el + (defun my-mu4e-refile-folder-work (msg) + "Function for chosing the refile folder for the work account. +MSG is a message p-list from mu4e." + (cond + ;; nil no refiling + )) + + ;; set `mu4e-context-policy` and `mu4e-compose-policy` to tweak when mu4e should + ;; guess or ask the correct context, e.g. + (setq mu4e-context-policy 'pick-first) ;; start with the first (default) context; default is to ask-if-none (ask when there's no context yet, and none match) + ;; (setq mu4e-compose-context-policy nil) ;; compose with the current context is no context matches; default is to ask + + ;;; lists + ;; The shortname (friendly) should a at most 8 characters, camel-case, see also `mu4e-mailing-list-patterns' + (setq mu4e-user-mailing-lists my-mu4e-user-mailing-lists) + + ;;; org + ;;(setq mu4e-org-link-query-in-headers-mode nil) ;; point to message (default) rather then the query + ) + +(use-package mu4e-maildirs-extension + :after mu4e + :config + (setq mu4e-maildirs-extension-title + (concat " Maildirs\t([" + (key-description mu4e-maildirs-extension-toggle-maildir-key) + "] fold, [C-u " + (key-description mu4e-maildirs-extension-toggle-maildir-key) + "] fold w/ children, [RET]/[mouse-2] jump to, [C-u RET] jump to unread only)\n")) + (setq mu4e-maildirs-extension-action-text + (concat "\t* [" + (key-description mu4e-maildirs-extension-action-key) + "]pdate index & cache\t([C-u " + (key-description mu4e-maildirs-extension-action-key) + "] clear cache, [C-u C-u " + (key-description mu4e-maildirs-extension-action-key) + "] clear and refresh)\n")) + (setq mu4e-maildirs-extension-maildir-default-prefix "โ””") ;;โ”œ> โ””> + (setq mu4e-maildirs-extension-fake-maildir-separator "\\.") + + ;; overwrite to remove double entries: + ;; /desy/* + ;; /desy/Drafts + ;; /desy/INBOX + ;; /desy/INBOX.event + ;; /desy/INBOX.Ing + ;; /desy/INBOX/Ing/* + ;; /desy/INBOX.Ing.CAD + ;; /desy/INBOX/Ing/CAD/* + ;; alteration: searching for "/.*/.*" pathes and do not append /* to them. + (defun mu4e-maildirs-extension-paths () + "Get maildirs paths." + (let ((paths (mu4e-maildirs-extension-get-relevant-maildirs)) + (paths-to-show nil)) + + (mapc #'(lambda (name) + (let ((parents (butlast (mu4e-maildirs-extension-parse name))) + (path nil)) + (mapc #'(lambda (parent-name) + (setq path (concat path "/" parent-name)) + (unless (or (member path paths-to-show) + (string-match-p "/.*/.*" path)) + (add-to-list 'paths-to-show (format "%s/*" path) t))) + parents)) + (add-to-list 'paths-to-show name t)) + paths) + paths-to-show)) + + (mu4e-maildirs-extension)) + +(defgroup my-notmuch nil + "My notmuch concept mapping" + :prefix "my-notmuch-" + :group 'my) + +(defcustom my-notmuch-tag-formats + '(("unread" (propertize tag 'face 'notmuch-tag-unread)) + ("flagged" (propertize tag 'face 'notmuch-tag-flagged) + (notmuch-tag-format-image-data tag (notmuch-tag-star-icon)))) + "Documention see `notmuch-tag-formats' in `notmuch-tag.el'." + :group 'my-notmuch + :type 'notmuch-tag-format-type) + +(defcustom my-notmuch-saved-searches + `((:name "inbox" :query "tag:inbox" :key ,(kbd "i")) + (:name "unread" :query "tag:unread" :key ,(kbd "u")) + (:name "flagged" :query "tag:flagged" :key ,(kbd "f")) + (:name "sent" :query "tag:sent" :key ,(kbd "t")) + (:name "drafts" :query "tag:draft" :key ,(kbd "d")) + (:name "all mail" :query "*" :key ,(kbd "a"))) + "Documention see `notmuch-saved-searches' in `notmuch-hello.el'." + :group 'my-notmuch + :get 'notmuch-hello--saved-searches-to-plist + :type '(repeat notmuch-saved-search-plist) + :tag "List of Saved Searches") + +(use-package notmuch + :delight + (notmuch-hello-mode "๐Ÿ…๏ฝˆ") + (notmuch-message-mode "๐Ÿ…๏ฝ") + (notmuch-search-mode "๐Ÿ…๏ฝ“") + (notmuch-show-mode "๐Ÿ…๏ฝ—") + (notmuch-tree-mode "๐Ÿ…๏ฝ”") + :commands notmuch + :config + (set-face-attribute 'notmuch-tag-flagged nil :foreground "#b1951d") + (setq notmuch-tag-formats my-notmuch-tag-formats) + (setq notmuch-search-oldest-first nil) ;; newest first + (setq notmuch-saved-searches my-notmuch-saved-searches) + + (add-to-list 'notmuch-hello-sections 'my-notmuch-hello-insert-footer t) + (defun my-notmuch-hello-insert-footer () + "Insert the notmuch-hello footer." + (widget-insert "\n") + (let ((start (point))) ;; to center text + (widget-insert "To download mails execute ") + (if (executable-find "offlineimap") + (widget-create 'link + :notify (lambda (&rest ignore) + (my-mail-exec-offlineimap)) + :button-prefix "" :button-suffix "" + :help-echo "my-mail-exec-offlineimap" + "OfflineIMAP") + (widget-create 'link + :notify (lambda (&rest ignore) + (message "offlineimap is not installed")) + :button-prefix "" :button-suffix "" + :button-face 'error + :help-echo "offlineimap is not installed" + "OfflineIMAP")) + (widget-insert " (also using ") + (if (executable-find "notmuch") + (widget-insert "notmuch") + (widget-insert (propertize "notmuch" 'face 'error))) + (widget-insert " and ") + (if (executable-find "afew") + (widget-insert "afew") + (widget-insert (propertize "afew" 'face 'error))) + (widget-insert ")") + (let ((fill-column (- (window-width) notmuch-hello-indent))) + (center-region start (point))))) + + (defun my-mail-exec-offlineimap () + "execute offlineimap" + (interactive) + (set-process-sentinel + (start-process-shell-command "offlineimap" + "*offlineimap*" + "offlineimap -o") + '(lambda (process event) + (notmuch-refresh-all-buffers) + (let ((w (get-buffer-window "*offlineimap*"))) + (when w + (with-selected-window w (recenter (window-end))))))) + (popwin:display-buffer "*offlineimap*")) + ;; add a special buffer config + (add-to-list 'popwin:special-display-config + '("*offlineimap*" :dedicated t :position bottom :stick t + :height 0.4 :noselect t)) + ) + +(provide 'mail-settings) +;;; mail-settings.el ends here diff --git a/settings/multiple-cursors-settings.el b/settings/multiple-cursors-settings.el new file mode 100644 index 00000000..8096a324 --- /dev/null +++ b/settings/multiple-cursors-settings.el @@ -0,0 +1,28 @@ +;;; multiple-cursors-settings --- Settings file for multiple cursors + +;;; Commentary: +;; multiple cursors configurations https://melpa.org/#/multiple-cursors + +;; Requirements: + +;;; Code: +(use-package multiple-cursors + :load-path (lambda() (concat user-emacs-directory "lisp/multiple-cursors")) + :bind ( + ;; see kbd prefix description in which-key-settings + ("M-m s m a" . mc/mark-all-dwim) + ("M-m s m b" . mc/mark-all-like-this) + ("M-m s m m" . mc/mark-more-like-this-extended) + ("M-m s m r" . mc/edit-lines) + ;; special bindings manipulate text under cursors + ("M-m s m s l" . mc/insert-letters) + ("M-m s m s m" . mc/mark-sgml-tag-pair) + ("M-m s m s n" . mc/insert-numbers) + ("M-m s m s r" . set-rectangular-region-anchor) + ("M-m s m s s" . mc/sort-regions) + ("M-m s m s t" . mc/reverse-regions) + ) + ) + +(provide 'multiple-cursors-settings) +;;; multiple-cursors-settings.el ends here diff --git a/settings/org-settings.el b/settings/org-settings.el new file mode 100644 index 00000000..b527aef3 --- /dev/null +++ b/settings/org-settings.el @@ -0,0 +1,1038 @@ +;;; org-settings.el --- Org settings -*- lexical-binding: t -*- + +;;; Commentary: +;; direct LaTeX (not org) +;; hyphen via AUCTeX (not installed) +;; https://tex.stackexchange.com/questions/282448/why-does-emacs-or-auctex-turns-into + +;; Requirements: +;; org-mode https://orgmode.org/ +;; org-bullets +;; org-cliplink https://melpa.org/#/org-cliplink + +;;; Code: +(defgroup my-org nil + "My org-mode concept mapping" + :prefix "my-org-" + :group 'my) + +(defcustom my-org-default-notes-file (convert-standard-filename "~/.notes") + "Documention see `org-default-notes-file' in `org.el'." + :group 'my-org + :type '(choice file (const "~/.notes") (const "~/Sync/notes.org"))) + +(defcustom my-org-agenda-files nil + "Documention see `org-agenda-files' in `org.el'." + :group 'my-org + :type '(choice + (repeat :tag "List of files and directories" file) + (file :tag "Store list in a file\n" :value "~/.agenda_files") + (const "~/Sync/tasks.org"))) + +(defcustom my-org-refile-targets nil + "Documention see `org-refile-targets' in `org.el'. + +Example: + Current buffer (nil) :maxlevel 3 + All agenda files (variable org-agenda-files) Max Level number 3 + Variable org-default-notes-file Max Level number 3" + :group 'my-org + :type '(repeat + (cons + (choice :value org-agenda-files + (const :tag "All agenda files" org-agenda-files) + (const :tag "Current buffer" nil) + (function) (variable) (file)) + (choice :tag "Identify target headline by" + (cons :tag "Specific tag" (const :value :tag) (string)) + (cons :tag "TODO keyword" (const :value :todo) (string)) + (cons :tag "Regular expression" (const :value :regexp) (regexp)) + (cons :tag "Level number" (const :value :level) (integer)) + (cons :tag "Max Level number" (const :value :maxlevel) (integer)))))) + +(defcustom my-org-publish-project-base-directory "~/org/project/" + "Documention see :base-directory of `org-publish-project-alist'. + +Used for the example in `my-org-publish-project-alist'." + :group 'my-org + :type '(choice directory (const "~/org/project/") (const "~/Sync/workspace/emacs/org/"))) + +(defcustom my-org-publish-project-publish-directory "~/public_html/" + "Documention see :publish-directory of `org-publish-project-alist'. + +Used for the example in `my-org-publish-project-alist'." + :group 'my-org + :type '(choice directory (const "~/public_html/"))) + +(defcustom my-org-publish-project-alist nil + "Documention see `org-publish-project-alist' in `ox-publish.el'. + +Example defines + org-notes and org-static with + base-directory to `my-org-publish-project-base-directory' + publishing-directory `my-org-publish-project-publish-directory'." + :group 'my-org + :type '(choice alist + (const :tag "Example" :value (list + ;; The notes component + (list "org-notes" + :base-directory my-org-publish-project-base-directory + :base-extension "org" + :publishing-directory my-org-publish-project-publish-directory + :recursive t + :publishing-function org-html-publish-to-html + ;;:publishing-function org-html-publish-to-tufte-html + :headline-levels 4 ; Just the default for this project. + :auto-preamble t + :auto-sitemap t ; Generate sitemap.org automatically... + :sitemap-filename "sitemap.org" ; ... call it sitemap.org (it's the default)... + :sitemap-title "Sitemap" ; ... with title 'Sitemap'. + ) + ;; The static component + (list "org-static" + :base-directory my-org-publish-project-base-directory + :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf" + :publishing-directory my-org-publish-project-publish-directory + :recursive t + :publishing-function org-publish-attachment + ) + ;; The publish component + (list "org" :components (list "org-notes" "org-static")))))) + +(defcustom my-org-brain-path (expand-file-name "brain" "~/org") + "Documention see `org-brain-path' in `ox-brain.el'." + :group 'my-org + :type '(choice directory + (const (expand-file-name "brain" "~/org")) + (const "~/Sync/workspace/emacs/org-brain"))) + +;; uses the org version from the org ELPA repository instead of the +;; one shipped with emacs. Therefore, any org related code should not +;; be loaded before, otherwise both versions will be loaded and will +;; conflict. +(use-package org + :load-path (lambda() (list (concat user-emacs-directory "lisp/org/lisp") + (concat user-emacs-directory "lisp/org/contrib/lisp"))) + :delight (org-mode "๐Ÿ…ž") ;; "Org " + :defer t + :init + (setq org-export-backends '(ascii html icalendar latex odt tufte md)) + :config + (setq org-startup-with-inline-images t) ;; #+STARTUP: inlineimages|noinlineimages, show inline images when loading a new Org file + (setq org-image-actual-width '(600)) ;; image width displayed in org + ;; todo see also org-todo-keyword-faces and org-superstar-todo-bullet-alist + (setq org-todo-keywords ;; (x!) record a time stamp, (x@) add a note (with time), (y/z) entering the state / leaving the state + '((sequence "TODO(t)" "WAIT(w)" "|" "DONE(d)" "CANC(c)"))) + (setq org-hierarchical-todo-statistics nil) ;; TODO statistics covers all entries in the subtree. + (setq org-refile-use-outline-path t) ;; show levels + (setq org-outline-path-complete-in-steps nil) ;; not in steps bc of using ivy completion + (setq org-default-notes-file my-org-default-notes-file) + (setq org-agenda-files my-org-agenda-files) + (setq org-refile-targets + '((nil :maxlevel . 3) ;; current buffer + (org-agenda-files :maxlevel . 3) + (org-default-notes-file :maxlevel . 3))) + (defun my-org-refile-target-verify-function () + "exclude done keywords of todos." + (not + (member + (nth 2 (org-heading-components)) ;; get todo keyword from current heading + org-done-keywords))) ;; is filled buffer-wise + (setq org-refile-target-verify-function 'my-org-refile-target-verify-function) + + ;; C-c C-c for code blocks (otherwise e.g.: No org-babel-execute function for shell) + (org-babel-do-load-languages + 'org-babel-load-languages + '(;; t enabled, nil disabled + (awk . t) + (C . t) + (calc . t) + (csharp . t) + (ditaa . t) + (emacs-lisp . t) + (gnuplot . t) + (haskell . t) + (js . t) + (latex . t) + (octave . t) + (plantuml . t) + (python . t) + (R . t) + ;; Error message regarding R: + ;; (invalid-function org-babel-header-args-safe-fn) + ;; Invalid function: org-babel-header-args-safe-fn + ;; M-x byte-compile-file /ob-R.el + ;; restart emacs. The compilation of ob-R.el must be done twice if necessary + (shell . t) + (sql . t))) + + (add-to-list 'image-file-name-extensions "eps" t)) ;; TODO: eps not needed? + +(use-package org-id ;; used by org-brain + :defer t + :config + ;; (setq org-id-track-globally t) ;; default is t + (setq org-id-locations-file (concat user-cache-directory ".org-id-locations"))) + +(use-package org-faces + :defer t + :config + (setq org-todo-keyword-faces ;; TODO keywords + '(("TODO" . "LightSkyBlue4") ;; org-warning (bold red), DeepSkyBlue3 + ("WAIT" . "LightSkyBlue4") ;; + ("DONE" . "#5e5079") ;; DarkSlateGray4 PaleTurquoise4, CadetBlue4, LightSkyBlue4 + ("CANC" . "#5e5079") ;; + ("STARTED" . "yellow") + ("CANCELED" . (:foreground "blue" :weight bold))))) + +(use-package org-table + :defer t + :config + (setq org-table-convert-region-max-lines 9999)) + +(use-package org-capture + :defer t + :config + ;; https://www.gnu.org/software/emacs/manual/html_node/org/Capture-templates.html + (add-to-list 'org-capture-templates + '(;; put entries under the heading 'Tasks' in default notes file + ("t" "Todo" entry (file+headline "" "Tasks") ;; empty string is the file, e.g. "~/org/gtd.org" + "* TODO %?\n %i\n %a"))) + (add-to-list 'org-capture-templates + '(;; put entries under a date tree (year - month - day - entry) in the default file + ("j" "Journal" entry (file+olp+datetree "") ;; empty string is the file, e.g. "~/org/journal.org" + "* %?\nEntered on %U\n %i\n %a"))) + ;; see also org-cliplink K, org-brain b + ) + +(use-package org-mouse ;; to load mouse features, like clicking on the bullet of a heading + :after (org)) + +(use-package org-tempo ;; expand = min && x <= max) ? x : 1/0 ; \ +set datafile separator '\\t' # treat empty fields in a org-table as 'missing' rather than 'bad' (ignoring, shifting column) ") + (defvar gnuplot-init-dark "reset ; \ +theme_type = 'dark' ; \ +set border lc rgb '#cccccc' ; \ +set title textcolor '#cccccc' ; \ +set xtics textcolor rgb '#cccccc' ; \ +set ytics textcolor rgb '#cccccc' ; \ +set xlabel textcolor rgb '#cccccc' ; \ +set ylabel textcolor rgb '#cccccc' ; \ +set zlabel textcolor rgb '#cccccc' ; \ +set key textcolor rgb '#cccccc' ; \ +set linetype 1 lc rgb '#0060ad' lw 2 pt 5 ; \ +set linetype 2 lc rgb '#dd181f' lw 2 pt 5 ; \ +set linetype 3 lc rgb '#9356a6' lw 2 pt 5 ; \ +set linetype 4 lc rgb '#4d92cc' lw 2 pt 5 ; \ +set linetype 5 lc rgb '#cc5279' lw 2 pt 5 ; \ +set linetype 6 lc rgb '#76ab2f' lw 2 pt 5 ; \ +set linetype 7 lc rgb '#ecb01f' lw 2 pt 5 ; \ +filter(x,min,max) = (x >= min && x <= max) ? x : 1/0 ; \ +set datafile separator '\\t' # treat empty fields in a org-table as 'missing' rather than 'bad' (ignoring, shifting column) ") + + (defun gpl-file (filename) + "\ +FILENAME: the file name + +returns: file name with extension for the org src header :file +- for LaTeX export it is set to: FILENAME.tikz +- for other export it is set to: FILENAME.svg + +usage: #+HEADER: :file (gpl-file \"ledger-income\") + +See also: http://www.gnuplot.info/docs_5.2/Gnuplot_5.2.pdf#section*.519 +" + ;;(concat filename (by-backend (latex ".tex") (t ".svg")) ) + (concat filename (by-backend (latex ".tikz") (t ".svg")) ) + ;;(by-backend (latex "") (t (concat filename ".svg"))) + ) + (defun gpl-term (lsize osize) + "\ +LSIZE: latex export size +OSIZE: other export size + +returns: term settings for the org src gnuplot header :term +- for LaTeX export it is set to: lua tikz size LSIZE color colortext +- for other export it is set to: svg size OSIZE mouse standalone background '#11000000' + +usage: #+HEADER: :term (gpl-term \"15cm,12cm\" \"380,300\") +" + (concat + ;;(by-backend (latex "epslatex size ") (t "svg size ")) + (by-backend (latex "lua tikz size ") (t "svg size ")) + (by-backend (latex lsize) (t osize)) + (by-backend (latex " color") (t " mouse standalone background '#11000000'")))) + ) + +(use-package ob-python + :defer t + :config + (defun mpl-var (filename) + "\ +FILENAME: the file name + +returns: file name varible with extension for the org src header :var +- for LaTeX export it is set to: FILENAME.pgf +- for other export it is set to: FILENAME.svg + +usage: #+HEADER: :var fname=(mpl-var \"ledger-income\") +" + (concat filename (by-backend (latex ".pgf") (t ".svg")))) + (defun mpl-prologue () + "\ +Matplotlib + +returns: style settings for a org src python matplotlib code block +- for LaTeX export it is not set. +- for other export it is set to: import matplotlib.pyplot as plt;plt.style.use('dark_background'); + +usage: #+HEADER: :prologue (mpl-prologue) +" + (by-backend (latex "") (t "import matplotlib.pyplot as plt;plt.style.use('dark_background');")))) + +(use-package ob-ditaa + :defer t + :config + ;; no more needed org-ditaa-jar-path default looks in ~/.config/emacs/lisp/org-9.2.6/contrib/scripts/ditaa.jar + ;; org-ditaa-jar-path (car (directory-files "/usr/share/java/ditaa" 'full "[.]*.jar" #'file-newer-than-file-p)) + ;; config to change from a ditaa.jar file to a ditaa executable file + ;; org-babel-ditaa-java-cmd "" ; default is "java". set to "" because system ditaa executable includes java + ;; org-babel-default-header-args:ditaa ; default is ((:results . "file") (:exports . "results") (:java . "-Dfile.encoding=UTF-8")) + ;; '((:results . "file") + ;; (:exports . "results")) + ;; org-ditaa-jar-option "" ; default is "-jar". set to "" because system ditaa executable includes -jar + ;; org-ditaa-jar-path (concat "" (executable-find "ditaa")) ; default is "~/.config/emacs/lisp/org/contrib/scripts/ditaa.jar" + ;; TODO: find file e.g. (shell-command "cat `which ditaa`") or (shell-command "ls /usr/share/java/ditaa") + (setq org-ditaa-jar-path "/usr/share/java/ditaa/ditaa-0.11.jar")) + +(use-package ob-csharp + :after (org)) + +(use-package ob-async ;; https://melpa.org/#/ob-async execute src blocks async, insert in block header (without argument) :async + :after (org)) + +(use-package ol-notmuch + :after (org)) + +(use-package ox + :defer t + :config + ;; https://orgmode.org/manual/Advanced-Export-Configuration.html + ;; https://en.wikibooks.org/wiki/LaTeX/Internationalization + ;; (defun my-org-export-filter-hyphen-shy (text backend info) + ;; "Convert \"- to ­ in HTML export." + ;; (when (org-export-derived-backend-p backend 'html) + ;; (replace-regexp-in-string "\"-" "­" text)) + ;; ) + ;; (defun my-org-export-filter-hyphen-hard (text backend info) + ;; "Convert \"= to - in HTML export." + ;; (when (org-export-derived-backend-p backend 'html) + ;; (replace-regexp-in-string "\"=" "-" text)) + ;; ) + ;; (add-to-list 'org-export-filter-body-functions + ;; 'my-org-export-filter-hyphen-shy) + ;; (add-to-list 'org-export-filter-body-functions + ;; 'my-org-export-filter-hyphen-hard) + ;;(add-to-list 'org-export-filter-latex-fragment-functions + ;; 'my-org-export-filter-hyphen-shy) + (setq org-export-with-smart-quotes t) ;; OPTIONS keyword, e.g., "โ€™:t". + + ;; http://permalink.gmane.org/gmane.emacs.orgmode/93971 + ;; https://emacs.stackexchange.com/questions/30575/adding-latex-newpage-before-a-heading/30892 + (defun my-org-headline-string-element (headline backend info) + "Return the org element representation of an element. Won't work on ~verb~/=code=-only headers" + (let ((prop-point (next-property-change 0 headline))) + (if prop-point (plist-get (text-properties-at prop-point headline) :parent)))) + (defun my-org-latex-ensure-clearpage (headline backend info) + "Insert a clearpage before the heading if property clearpage is non-nil." + (when (org-export-derived-backend-p backend 'latex) + (let ((elmnt (my-org-headline-string-element headline backend info))) + (when (and elmnt (org-element-property :CLEARPAGE elmnt)) + (concat "\\clearpage\n" headline))))) + (add-to-list 'org-export-filter-headline-functions + 'my-org-latex-ensure-clearpage)) + +(use-package ox-extra + :after (org) ;; defer t is not enough bc/ ox-extra is not loaded by default + :config + ;; https://emacs.stackexchange.com/questions/9492/is-it-possible-to-export-content-of-subtrees-without-their-headings + ;; https://emacs.stackexchange.com/questions/44018/use-package-ensure-not-working-package-downloaded-but-gives-warning-and-skips-c + (ox-extras-activate '(ignore-headlines))) ;; see in variable `ox-extras' + +(use-package ox-html + :defer t ;; will be loaded via `org-export-backends' see above inside `org' + :config + (setq org-html-doctype "html5") + (setq org-html-html5-fancy t) + (setq org-html-validation-link nil) ;; remove the "Validate" link at the bottom of the page + (setq org-html-mathjax-options + '((path "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML") + ;;(path "/js/MathJax-master/MathJax.js?config=TeX-AMS_HTML") + (scale "100") + (align "center") + (font "TeX") + (linebreaks "false") + (autonumber "AMS") + (indent "0em") + (multlinewidth "85%") + (tagindent ".8em") + (tagside "right"))) ;; #+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Euler + ;; http://docs.mathjax.org/en/latest/input/tex/macros/ + (setq org-html-mathjax-template " +") + ) + +(use-package ox-tufte ;; https://melpa.org/#/ox-tufte + :defer t ;; will be loaded via `org-export-backends' see above inside `org' + :config + (defun my-org-tufte-export-to-file (&optional async subtreep visible-only) + "Like `org-tufte-export-to-file' but with additional notification." + (interactive) + (let ((outfile (org-export-output-file-name ".html" subtreep)) + ;; need to bind this because tufte treats footnotes specially, so we + ;; don't want to display them at the bottom + (org-html-footnotes-section (if org-tufte-include-footnotes-at-bottom + org-html-footnotes-section + ""))) + (org-export-to-file 'tufte-html outfile + async subtreep visible-only nil nil + (lambda (file) ;; is called with FILE and has to return a file name. + (progn + (when my-dbusp + (use-package notifications) + (notifications-notify + :title "Emacs Org Tufte (HTML) Export to File" + :body "Export done." + :timeout 60000 + :urgency 'normal + :category "transfer")) + file))))) ;; is needed for the asynchronous task + + (defun my-org-export-html (&optional async) + (interactive) + (save-buffer) + (when (get-buffer "*gnuplot*") + (kill-buffer "*gnuplot*")) ;; to get a new session + (my-org-tufte-export-to-file async)) + + (defun my-org-export-html-async () + (interactive) + (my-org-export-html t)) + + (org-defkey org-mode-map [f5] 'my-org-export-html) + (org-defkey org-mode-map [C-f5] 'my-org-export-html-async) + + (defun org-tufte-src-block (src-block _contents info) + "Transcode a SRC-BLOCK element from Org to HTML. +CONTENTS holds the contents of the item. INFO is a plist holding +contextual information." + (if (org-export-read-attribute :attr_html src-block :textarea) + (org-html--textarea-block src-block) + (let* ((lang (org-element-property :language src-block)) + (code (org-html-format-code src-block info)) + (label (let ((lbl (and (org-element-property :name src-block) + (org-export-get-reference src-block info)))) + (if lbl (format " id=\"%s\"" lbl) ""))) + (klipsify (and (plist-get info :html-klipsify-src) + (member lang '("javascript" "js" + "ruby" "scheme" "clojure" "php" "html"))))) + (if (not lang) (format "
\n%s
" label code) + (format "
\n%s%s\n
" + ;; Build caption. + (let ((caption (org-export-get-caption src-block))) + (if (not caption) "" + (let ((listing-number + (format + "%s " + (format + (org-html--translate "Listing %d:" info) + (org-export-get-ordinal + src-block info nil #'org-html--has-caption-p))))) + (format "" + listing-number + (org-trim (org-export-data caption info)))))) + ;; Contents. + (if klipsify + (format "
%s
" + lang + label + (if (string= lang "html") + " data-editor-type=\"html\"" + "") + code) + (format "
%s
" + lang label code)))))))) + +(use-package ox-latex + :defer t ;; will be loaded via `org-export-backends' see above inside `org' + :config + (setq org-latex-compiler "lualatex") ;; %latex in org-latex-pdf-process + (setq org-latex-bib-compiler "biber") ;; %bib in org-latex-pdf-process + (setq org-latex-pdf-process + '("%latex -shell-escape -interaction nonstopmode -output-directory %o %f" + "%bib %b" + "%latex -shell-escape -interaction nonstopmode -output-directory %o %f" + "%latex -shell-escape -interaction nonstopmode -output-directory %o %f")) + (setq org-latex-listings t) + (setq org-latex-listings-options + '(("numbers" "left") + ;; ("captionpos" "t") ;; not working, see org-latex-caption-above + )) + (setq org-latex-caption-above '(table src-block)) + (setq org-latex-hyperref-template " +%% DON't let hyperref overload the format of index and glossary. +%% I want to do that on my own in the stylefiles for makeindex... +\\makeatletter +\\let\\@old@wrindex=\\@wrindex +\\makeatother +\\hypersetup{%% + pdfauthor={%a}, + pdftitle={%t}, + pdfkeywords={%k}, + pdfsubject={%d}, + pdfcreator={%c}, + pdflang={%L}, + pdfproducer={LaTeX}, + %%pdfpagelabels, + %% Dokument an Fensterbreite anpassen, {XYZ null null 1} + pdfstartview=FitH, + %% Miniaturansicht nicht anzeigen + pdfpagemode=UseNone, + bookmarksopen=true, + bookmarksnumbered=true, + %% use true to enable colors below: + colorlinks=true, + linkcolor=black, + filecolor=darkblue, + menucolor=darkblue, + urlcolor=darkblue, + citecolor=black, + %% PDF link-darstellung, falls colorlinks=false. 0 0 0: nix. 0 0 1: default. + pdfborder=0 0 0, + %%frenchlinks=false, %% small caps instead of colors + %% false bei rรถmisch und arabischen Zahlen + plainpages=false, + %% true bei rรถmisch und arabischen Zahlen; Without hypertexnames it's just counting upwards; bei 4 -> iv + hypertexnames=true, +} +\\makeatletter +\\let\\@wrindex=\\@old@wrindex +\\makeatother +") + + (add-to-list 'org-latex-classes + '("koma-article" "\\documentclass{scrartcl}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))) + + (defun my-org-latex-export-to-pdf + (&optional async subtreep visible-only body-only ext-plist) + "Like `org-latex-export-to-pdf' but with additional notification." + (interactive) + (let ((outfile (org-export-output-file-name ".tex" subtreep))) + (org-export-to-file 'latex outfile + async subtreep visible-only body-only ext-plist + (lambda (file) ;; is called with FILE and has to return a file name. + (let ((output (org-latex-compile file))) + (when my-dbusp + (use-package notifications) + (notifications-notify + :title "Emacs Org Latex Export to PDF" + :body "Export done." + :timeout 60000 + :urgency 'normal + :category "transfer")) + output))))) ;; is needed for the asynchronous task + + (defun my-org-export-pdf (&optional async) + (interactive) + (save-buffer) + (when (get-buffer "*gnuplot*") + (kill-buffer "*gnuplot*")) ;; to get a new session + (my-org-latex-export-to-pdf async)) + + (defun my-org-export-pdf-async () + (interactive) + (my-org-export-pdf t)) + + (org-defkey org-mode-map [f6] 'my-org-export-pdf) + (org-defkey org-mode-map [C-f6] 'my-org-export-pdf-async) + + ;; overwrite org ox-latex + (defun org-latex--inline-image (link info) + "Return LaTeX code for an inline image. +LINK is the link pointing to the inline image. INFO is a plist +used as a communication channel." + (let* ((parent (org-export-get-parent-element link)) + (path (let ((raw-path (org-element-property :path link))) + (if (not (file-name-absolute-p raw-path)) raw-path + (expand-file-name raw-path)))) + (filetype (file-name-extension path)) + (caption (org-latex--caption/label-string parent info)) + (caption-above-p (org-latex--caption-above-p link info)) + ;; Retrieve latex attributes from the element around. + (attr (org-export-read-attribute :attr_latex parent)) + (float (let ((float (plist-get attr :float))) + (cond ((string= float "wrap") 'wrap) + ((string= float "sideways") 'sideways) + ((string= float "multicolumn") 'multicolumn) + ((and (plist-member attr :float) (not float)) 'nonfloat) + ((or float + (org-element-property :caption parent) + (org-string-nw-p (plist-get attr :caption))) + 'figure) + (t 'nonfloat)))) + (placement + (let ((place (plist-get attr :placement))) + (cond + (place (format "%s" place)) + ((eq float 'wrap) "{l}{0.5\\textwidth}") + ((eq float 'figure) + (format "[%s]" (plist-get info :latex-default-figure-position))) + (t "")))) + (center + (if (plist-member attr :center) (plist-get attr :center) + (plist-get info :latex-images-centered))) + (comment-include (if (plist-get attr :comment-include) "%" "")) + ;; It is possible to specify width and height in the + ;; ATTR_LATEX line, and also via default variables. + (width (cond ((plist-get attr :width)) + ((plist-get attr :height) "") + ((eq float 'wrap) "0.48\\textwidth") + (t (plist-get info :latex-image-default-width)))) + (height (cond ((plist-get attr :height)) + ((or (plist-get attr :width) + (memq float '(figure wrap))) "") + (t (plist-get info :latex-image-default-height)))) + (options (let ((opt (or (plist-get attr :options) + (plist-get info :latex-image-default-option)))) + (if (not (string-match "\\`\\[\\(.*\\)\\]\\'" opt)) opt + (match-string 1 opt)))) + image-code) + (if (member filetype '("tikz" "pgf")) + ;; For tikz images: + ;; - use \input to read in image file. + ;; - if options are present, wrap in a tikzpicture environment. + ;; - if width or height are present, use \resizebox to change + ;; the image size. + (progn + (setq image-code (format "\\input{%s}" path)) + (when (org-string-nw-p options) + (setq image-code + (format "\\begin{tikzpicture}[%s]\n%s\n\\end{tikzpicture}" + options + image-code))) + (when (or (org-string-nw-p width) (org-string-nw-p height)) + (setq image-code (format "\\resizebox{%s}{%s}{%s}" + (if (org-string-nw-p width) width "!") + (if (org-string-nw-p height) height "!") + image-code)))) + ;; For other images: + ;; - add width and height to options. + ;; - include the image with \includegraphics. + (when (org-string-nw-p width) + (setq options (concat options ",width=" width))) + (when (org-string-nw-p height) + (setq options (concat options ",height=" height))) + (let ((search-option (org-element-property :search-option link))) + (when (and search-option + (equal filetype "pdf") + (string-match-p "\\`[0-9]+\\'" search-option) + (not (string-match-p "page=" options))) + (setq options (concat options ",page=" search-option)))) + (setq image-code + (format "\\includegraphics%s{%s}" + (cond ((not (org-string-nw-p options)) "") + ((string-prefix-p "," options) + (format "[%s]" (substring options 1))) + (t (format "[%s]" options))) + path)) + (when (equal filetype "eps") + (setq image-code (replace-regexp-in-string "^\\\\includegraphics\\[.+\\]" + "\\input" + image-code + nil t)) + (setq image-code (replace-regexp-in-string "\\.eps}" + ".tex}" + image-code + nil t))) + (when (equal filetype "svg") + (setq image-code (replace-regexp-in-string "^\\\\includegraphics" + "\\includesvg" + image-code + nil t)) + (setq image-code (replace-regexp-in-string "\\.svg}" + "}" + image-code + nil t))) + ) + ;; Return proper string, depending on FLOAT. + (pcase float + (`wrap (format "\\begin{wrapfigure}%s +%s%s +%s%s +%s\\end{wrapfigure}" + placement + (if caption-above-p caption "") + (if center "\\centering" "") + comment-include image-code + (if caption-above-p "" caption))) + (`sideways (format "\\begin{sidewaysfigure} +%s%s +%s%s +%s\\end{sidewaysfigure}" + (if caption-above-p caption "") + (if center "\\centering" "") + comment-include image-code + (if caption-above-p "" caption))) + (`multicolumn (format "\\begin{figure*}%s +%s%s +%s%s +%s\\end{figure*}" + placement + (if caption-above-p caption "") + (if center "\\centering" "") + comment-include image-code + (if caption-above-p "" caption))) + (`figure (format "\\begin{figure}%s +%s%s +%s%s +%s\\end{figure}" + placement + (if caption-above-p caption "") + (if center "\\centering" "") + comment-include image-code + (if caption-above-p "" caption))) + ((guard center) + (format "\\begin{center} +%s%s +%s\\end{center}" + (if caption-above-p caption "") + image-code + (if caption-above-p "" caption))) + (_ + (concat (if caption-above-p caption "") + image-code + (if caption-above-p caption ""))))))) + +(use-package ox-md + :defer t) ;; will be loaded via `org-export-backends' see above inside `org' + +(use-package ox-publish + :defer t + :config + (setq org-publish-timestamp-directory (concat user-cache-directory "org-timestamps/")) + (setq org-publish-project-alist my-org-publish-project-alist)) + +(use-package org-drill ;; requires persist https://elpa.gnu.org/packages/persist.html + :commands org-drill) + +;; define `org-brain-path' in custom. +(use-package org-brain ;; uses org-id If you find that org-brain is missing entries, or list entries which doesnโ€™t exist, try using M-x org-brain-update-id-locations, which syncs the org-brain entries with the org-id caching system. + :commands (org-brain-visualize) + :init + (setq org-brain-path my-org-brain-path) + :config + (require 'org-capture) + ;; make org-brain commands more accessable if you edit entries from org-mode + (bind-key "C-c B" 'org-brain-prefix-map org-mode-map) + ;; org-brain use org-id in order to speed things up. Because of + ;; this, the variable org-id-track-globally should be t (which it + ;; already is by default). You may want to modify + ;; org-id-locations-file too. If you add entries to org-brain + ;; directly from org-mode you must assign headliens an ID. A + ;; comfortable way to do this is with the command + ;; org-brain-ensure-ids-in-buffer. Even more comfortable is to add + ;; that to before-save-hook, so that it runs when saving. + (add-hook 'before-save-hook #'org-brain-ensure-ids-in-buffer) + ;; to add information at the end of an entry, without visiting the file. + (push '("b" "Brain" plain (function org-brain-goto-end) + "* %i%?" :empty-lines 1) + org-capture-templates) + ;; (setq org-brain-visualize-default-choices 'all) + ;; (setq org-brain-show-resources t) + ;; (setq org-brain-show-text t) + ;; (setq org-brain-title-max-length 12) + ;; Some users find it confusing having both headline entries and + ;; file entries (see below). It may be preferable to only use + ;; headline entries, by setting org-brain-include-file-entries to + ;; nil. If doing this, you should probably also set + ;; org-brain-file-entries-use-title to nil. Another possibility is + ;; if youโ€™re only using file entries, in which case you can set + ;; org-brain-scan-for-header-entries to nil. + ;; (setq org-brain-include-file-entries nil) + ;; (setq org-brain-file-entries-use-title nil) + + (require 'deft) + (defun org-brain-deft () + "Use `deft' for files in `org-brain-path'." + (interactive) + (let ((deft-directory org-brain-path) + (deft-recursive t) + (deft-extensions '("org"))) + (deft))) + + (require 'org-cliplink) + (defun org-brain-cliplink-resource () + "Add a URL from the clipboard as an org-brain resource. +Suggest the URL title as a description for resource." + (interactive) + (let ((url (org-cliplink-clipboard-content))) + (org-brain-add-resource + url + (org-cliplink-retrieve-title-synchronously url) + t))) + (define-key org-brain-visualize-mode-map (kbd "L") #'org-brain-cliplink-resource)) + +;; Allows you to edit entries directly from org-brain-visualize +(use-package polymode + :defer t + :config + (add-hook 'org-brain-visualize-mode-hook #'org-brain-polymode)) + +(provide 'org-settings) +;;; org-settings.el ends here diff --git a/settings/plot-settings.el b/settings/plot-settings.el new file mode 100644 index 00000000..13e60457 --- /dev/null +++ b/settings/plot-settings.el @@ -0,0 +1,29 @@ +;;; plot-settings.el --- plot settings -*- lexical-binding: t -*- + +;;; Commentary: +;; .plantuml .pum .plu + +;; Requirements: +;; gnuplot +;; gnuplot-mode https://melpa.org/#/gnuplot-mode drive gnuplot from within Emacs e.g. via org (export) +;; plantuml-mode https://melpa.org/#/plantuml-mode https://github.com/skuro/plantuml-mode +;; dash + +;;; Code: +(use-package gnuplot-mode + :load-path (lambda() (concat user-emacs-directory "lisp/gnuplot")) + :commands gnuplot-mode + :mode "\\.gp\\'" + ) + +(use-package plantuml-mode + :commands (plantuml-mode org-mode) + :config + ;; arch linux aur package path + (setq plantuml-jar-path "/usr/share/java/plantuml/plantuml.jar") + (setq org-plantuml-jar-path "/usr/share/java/plantuml/plantuml.jar") + (with-eval-after-load 'org + (add-to-list 'org-src-lang-modes '("plantuml" . plantuml)))) + +(provide 'plot-settings) +;;; plot-settings.el ends here diff --git a/settings/polymode-settings.el b/settings/polymode-settings.el new file mode 100644 index 00000000..78b64ea4 --- /dev/null +++ b/settings/polymode-settings.el @@ -0,0 +1,25 @@ +;;; polymode-settings.el --- Polymode settings -*- lexical-binding: t -*- +;;; Commentary: +;;; Code: +(use-package polymode + :load-path (lambda() (concat user-emacs-directory "lisp/polymode")) + :commands poly-python-web-mode + :config + + (define-hostmode poly-python-hostmode :mode 'python-mode) + + (define-innermode poly-python-web-expr-innermode + :mode 'web-mode + :head-matcher (rx "r" (= 3 (char "\"'")) (* (any space))) + ;;:head-matcher (rx (= 3 (char "\"'")) (* (any space))) + :tail-matcher (rx (= 3 (char "\"'"))) + :head-mode 'host + :tail-mode 'host) + + (define-polymode poly-python-web-mode + :hostmode 'poly-python-hostmode + :innermodes '(poly-python-web-expr-innermode)) + ) + +(provide 'polymode-settings) +;;; polymode-settings.el ends here diff --git a/settings/post-settings.el b/settings/post-settings.el new file mode 100644 index 00000000..d414073b --- /dev/null +++ b/settings/post-settings.el @@ -0,0 +1,13 @@ +;;; post-settings.el --- Summary -*- lexical-binding: t -*- +;;; Commentary: +;;; Code: +(setq gc-cons-threshold (* 2 1000 1000)) ;; Make gc pauses faster by decreasing back the threshold. See also above. + +(use-package cus-edit + :config + (setq custom-file (concat user-emacs-directory "custom.el")) + (setq custom-buffer-done-kill t) + (load custom-file t t)) + +(provide 'post-settings) +;;; post-settings.el ends here diff --git a/settings/python-settings.el b/settings/python-settings.el new file mode 100644 index 00000000..6a9017b7 --- /dev/null +++ b/settings/python-settings.el @@ -0,0 +1,144 @@ +;;; python-settings.el --- Python settings -*- mode: emacs-lisp; lexical-binding: t -*- + +;;; Commentary: + +;; Requirements: +;; program: python +;; Emacs packages: anaconda-mode company-anaconda sphinx-doc + +;;; Code: +(use-package python + :delight (python-mode "๐Ÿ…Ÿ") ;; "Py " + :commands (python-mode) + :bind (:map python-mode-map + ;; swap C-u C-c C-c with C-c C-c, so C-c C-c sends __main__ + ("C-c C-c" . my-python-shell-send-buffer-w-main) + ("C-u C-c C-c" . my-python-shell-send-buffer) + ("M-m m c c" . my-python-execute-file) + ("M-m m c C" . my-python-execute-file-switch) + ("M-m m s b" . my-python-shell-send-buffer-w-main)) + :config + (setq python-indent-offset 2) ; python-indent is obsolete since 24.3; use python-indent-offset instead. + (setq python-indent-guess-indent-offset nil) ; default t. nil to use the config value python-indent-offset + (setq python-indent-guess-indent-offset-verbose nil) ; hide message like: Canโ€™t guess python-indent-offset, using defaults: 2 + ;;(setq python-shell-interpreter "ipython") + ;;(setq python-shell-interpreter-args "-i") + + (defun my-pyenv-executable-find (command) + "Find executable taking pyenv shims into account. +If the executable is a system executable and not in the same path +as the pyenv version then also return nil. This works around https://github.com/pyenv/pyenv-which-ext +" + (if (executable-find "pyenv") + (progn + (let ((pyenv-string (shell-command-to-string (concat "pyenv which " command))) + (pyenv-version-names (split-string (string-trim (shell-command-to-string "pyenv version-name")) ":")) + (executable nil) + (i 0)) + (if (not (string-match "not found" pyenv-string)) + (while (and (not executable) + (< i (length pyenv-version-names))) + (if (string-match (elt pyenv-version-names i) (string-trim pyenv-string)) + (setq executable (string-trim pyenv-string))) + (if (string-match (elt pyenv-version-names i) "system") + (setq executable (string-trim (executable-find command)))) + (setq i (1+ i)))) + executable)) + (executable-find command))) + + (defun my-python-execute-file (arg) + "Execute a python script in a shell." + (interactive "P") + ;; set compile command to buffer-file-name + ;; universal argument put compile buffer in comint mode + (let ((universal-argument t) + (compile-command (format "%s %s" + (my-pyenv-executable-find python-shell-interpreter) + (shell-quote-argument (file-name-nondirectory buffer-file-name))))) + (if arg + (call-interactively 'compile) + (compile compile-command t) + (with-current-buffer (get-buffer "*compilation*") + (inferior-python-mode))))) + + (defun my-python-execute-file-switch (arg) + "Execute a python script in a shell and switch to the shell buffer in `insert state'." + (interactive "P") + (my-python-execute-file arg) + (switch-to-buffer-other-window "*compilation*") + (end-of-buffer) + (evil-insert-state)) + + (defun my-python-shell-send-buffer (&optional send-main) + "Send buffer content to shell." + (interactive) + (let ((python-mode-hook nil)) ;; TODO: why? + (python-shell-send-buffer send-main))) + + (defun my-python-shell-send-buffer-w-main () + "Send buffer content to shell with main." + (interactive) + (my-python-shell-send-buffer t)) + + (defadvice run-python + (after my-advice-run-python activate) + "set flag to allow exit without query on any active python +process." + (set-process-query-on-exit-flag ad-return-value nil)) + + (defun my-python-shell-send-buffer-w-args (args) + "Send buffer content to shell with main and arguments." + (interactive "sPython arguments: ") + (let ((source-buffer (current-buffer))) + (with-temp-buffer + (insert "import sys; sys.argv = '''" args "'''.split()\n") + (insert-buffer-substring source-buffer) + (my-python-shell-send-buffer-w-main)))) + ) + +(use-package anaconda-mode ;; works with company-mode via company-anaconda + :after python + :delight (anaconda-mode "โ’ถ") ;; โ’ถ a + :bind (([remap anaconda-mode-show-doc] . my-anaconda-mode-show-doc)) ;; M-? + :hook (python-mode + (python-mode . anaconda-eldoc-mode)) ;; if cursor is between function's parenthesis show parameter in echo area + :config + (setq anaconda-mode-installation-directory (concat user-cache-directory "anaconda-mode")) + ;; compared to `anaconda-mode-show-doc' using `my-anaconda-mode-show-doc-callback' + (defun my-anaconda-mode-show-doc () + "Show documentation for context at point." + (interactive) + ;;(anaconda-mode-call "show_doc" 'anaconda-mode-show-doc-callback) ;; removed + (anaconda-mode-call "show_doc" 'my-anaconda-mode-show-doc-callback) ;; instead + ) + ;; compared to `anaconda-mode-show-doc-callback' no change of focus + (defun my-anaconda-mode-show-doc-callback (result) + "Process view doc RESULT." + (if (> (length result) 0) + (if (and anaconda-mode-use-posframe-show-doc + (require 'posframe nil 'noerror) + (posframe-workable-p)) + (anaconda-mode-documentation-posframe-view result) + ;;(pop-to-buffer (anaconda-mode-documentation-view result) t) ;; removed + (anaconda-mode-documentation-view result) ;; instead + ) + (message "No documentation available"))) + ) + +(use-package company-anaconda + :after (python anaconda-mode company) + :bind (([remap anaconda-mode-complete] . company-anaconda)) + :config + (add-to-list 'company-backends '(company-anaconda :with company-capf)) ;; to see anaconda-mode completions together with ones comes from inferior python process + ) + +;; https://melpa.org/#/sphinx-doc +;; https://github.com/naiquevin/sphinx-doc.el +;; enable the sphinx-doc-mode and bind the interactive function sphinx-doc to C-c M-d. +(use-package sphinx-doc + :delight (sphinx-doc-mode "โ“ˆ") ;; โ“ˆ s + :hook (python-mode . sphinx-doc-mode) + ) + +(provide 'python-settings) +;;; python-settings.el ends here diff --git a/settings/shell-settings.el b/settings/shell-settings.el new file mode 100644 index 00000000..9ba2bf84 --- /dev/null +++ b/settings/shell-settings.el @@ -0,0 +1,19 @@ +;;; shell-settings.el --- Summary -*- lexical-binding: t -*- +;;; Commentary: +;;; Code: +(use-package sh-script + :defer t + :config + (setq sh-basic-offset 2) + ) + +(use-package powershell ;; https://melpa.org/#/powershell + :commands powershell-mode) + +(use-package eshell-mode + :defer t + :init + (setq eshell-directory-name (concat user-cache-directory "eshell/"))) + +(provide 'shell-settings) +;;; shell-settings.el ends here diff --git a/settings/web-settings.el b/settings/web-settings.el new file mode 100644 index 00000000..cb52d39f --- /dev/null +++ b/settings/web-settings.el @@ -0,0 +1,49 @@ +;;; web-settings.el --- Summary -*- lexical-binding: t -*- + +;;; Commentary: + +;; Requirements: +;; js2-mode https://melpa.org/#/js2-mode +;; tern (npm install -g tern) +;; php-mode https://melpa.org/#/php-mode +;; web-mode https://melpa.org/#/web-mode +;; company-web https://melpa.org/#/company-web +;; web-completion-data https://melpa.org/#/web-completion-data + +;;; Code: + +(use-package css-mode + :defer t + :config + (setq css-indent-offset 2)) + +(use-package js2-mode + :load-path (lambda() (concat user-emacs-directory "lisp/js2-mode")) + :commands js2-mode) + +(use-package php-mode + :load-path (lambda() (concat user-emacs-directory "lisp/php-mode")) + :commands php-mode) + +(use-package web-mode + :commands (web-mode)) + +(use-package web-completion-data + :load-path (lambda() (concat user-emacs-directory "lisp/web-completion-data")) + :defer t) + +(use-package company-web-html + :after (web-mode company) + :load-path (lambda() (concat user-emacs-directory "lisp/company-web")) + :bind (([remap complete-symbol] . company-complete)) ;; M-C-i and + :config + ;;(add-to-list 'company-backends 'company-web-html) + ;; Only use company-mode with company-web-html in web-mode + (add-hook 'web-mode-hook + (lambda () + (set (make-local-variable 'company-backends) + '(company-web-html company-capf company-files)))) + ) + +(provide 'web-settings) +;;; web-settings.el ends here