diff --git a/init.el b/init.el index 195d04c..6097bc7 100644 --- a/init.el +++ b/init.el @@ -20,6 +20,7 @@ '(all-the-icons anzu base16-theme + bbdb better-defaults company company-go @@ -28,6 +29,7 @@ dash-at-point diminish dockerfile-mode + doom-modeline doom-themes ein eldoc-eval @@ -46,6 +48,7 @@ magit material-theme multiple-cursors + nnir-est projectile py-autopep8 rainbow-delimiters @@ -67,6 +70,10 @@ (when (not (package-installed-p p)) (package-install p))) +(require 'edit-server) + +(edit-server-start) + (require 'better-defaults) ;; Instead of the annoying giant warning icon, just flash the modeline. @@ -116,6 +123,10 @@ (add-to-list 'default-frame-alist (cons 'top 0)) (add-to-list 'default-frame-alist (cons 'left 1000)) +(put 'narrow-to-region 'disabled nil) +(put 'upcase-region 'disabled nil) +(put 'downcase-region 'disabled nil) + (setq inhibit-splash-screen nil fancy-splash-image "~/.emacs.d/public/emacs-logo.png" fancy-splash-image-file "~/.emacs.d/public/emacs-logo.png") @@ -145,6 +156,89 @@ (defalias 'yes-or-no-p 'y-or-n-p) +(require 'font-lock) + +(defvar openhab-mode-hook nil) + +(defvar openhab-mode-map + (let ((map (make-keymap))) + (define-key map "\C-j" 'newline-and-indent) + map) + "Keymap for OPENHAB major mode.") + +(add-to-list 'auto-mode-alist '("\\.sitemap\\'" . openhab-mode)) +(add-to-list 'auto-mode-alist '("\\.items\\'" . openhab-mode)) +(add-to-list 'auto-mode-alist '("\\.rules\\'" . openhab-mode)) +(add-to-list 'auto-mode-alist '("\\.things\\'" . openhab-mode)) + +(defconst openhab-font-lock-keywords + `( + ("\<.*\>" . font-lock-constant-face) + (,(regexp-opt + '( + ;; KEYWORDS + "Selection" "Slider" "List" "Setpoint" "Video" "Chart" "Webview" "Colorpicker" + "Timer" "Number" "String" + "Switch" "Rollershutter" "Number" "String" "Dimmer" "Contact" "DateTime" "Color" + "Text" "Group" "Image" "Frame" + "Thing" "Bridge" + "Time" "System" + "sitemap" + + "rule" "when" "then" "end" + "if" "val" + "import" "var" "say" "postUpdate" "switch" "println" "case" "or" "sendCommand" + ) + 'words) + (1 font-lock-keyword-face)) + (,(regexp-opt + '( + "ON" "OFF" "on" "off" + "AND" "OR" "NAND" "NOR" "AVG" "SUM" "MAX" "MIN" + "true" "false" + ) + 'words) + (1 font-lock-constant-face)) + (,(regexp-opt + '( + "name" "label" "item" "period" "refresh" "icon" "mappings" "minValue" "maxValue" "step" "switchsupport" "url" "height" "refresh" "visibility" "valuecolor" + ) + 'words) + (1 font-lock-type-face)) + ("\(.*\)" . font-lock-variable-name-face) + ("[^a-zA-Z0-9_:]\\([0-9]*\\)[^a-zA-Z0-9_:]" . (1 font-lock-variable-name-face)) + ("\s@\s" . font-lock-variable-name-face) + ("\s\\([a-zA-Z0-9_:]*\\)\\(\s\\|$\\)" . (1 font-lock-type-face)) + ("=\\([a-zA-Z_]*\\)" . (1 font-lock-string-face)) + ("\\([a-zA-Z]*\\)=" . (1 font-lock-type-face)) + ) + "The regexps to highlight in openHAB mode.") + +(defvar openhab-mode-syntax-table + (let ((st (make-syntax-table))) + (modify-syntax-entry ?/ ". 12b" st) ;; C-style comments // ... + (modify-syntax-entry ?\n "> b" st) ;; \n ends comment + ;; Block comments /*...*/ + (modify-syntax-entry ?\/ ". 14" st) + (modify-syntax-entry ?* ". 23" st) + st) + "Syntax table for openhab-mode.") + +(defun openhab-mode () + "Major mode for editing OPENHAB config files." + (interactive) + (kill-all-local-variables) + (set-syntax-table openhab-mode-syntax-table) + (use-local-map openhab-mode-map) + (set (make-local-variable 'font-lock-defaults) '(openhab-font-lock-keywords nil t)) + (electric-pair-mode -1) + (flycheck-mode -1) + (setq major-mode 'openhab-mode) + (setq mode-name "OpenHAB") + (run-hooks 'openhab-mode-hook)) + +(provide 'openhab-mode) + (require 'which-key) (which-key-setup-minibuffer) (which-key-mode) @@ -214,6 +308,87 @@ (global-set-key (kbd "C-c g") 'magit-status) (setq magit-completing-read-function 'ivy-completing-read) +(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu/mu4e") +(require 'mu4e) + +;; default +(setq mu4e-maildir "~/Mail" + mu4e-mu-binary "/usr/local/bin/mu" + mu4e-get-mail-command "offlineimap" ;; Allow updating with the "U" command + mu4e-sent-messages-behavior 'delete ;; Delete sent messages + mu4e-view-show-images t ;; attempt to show images + mu4e-view-image-max-width 400 ;; max image size + message-kill-buffer-on-exit t ;; don't keep messages around + mu4e-use-fancy-chars t ;; use 'fancy' chars + mu4e-update-interval 300 ;; 5 mins + ) + +(setq mu4e-contexts + `( ,(make-mu4e-context + :name "Vlocity" + :enter-func (lambda () (mu4e-message "Entering Vlocity")) + :leave-func (lambda () (mu4e-message "Leaving Vlocity")) + ;; we match based on the contact-fields of the message + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/Vlocity"))) + :vars '( ( user-mail-address . "lolson@vlocity.com" ) + ( smtpmail-mail-address . "lolson@vlocity.com" ) + ( user-full-name . "Levi Olson" ) + ( mu4e-compose-signature . + (concat + "--\n" + "Levi Olson\n" + "Senior UI Developer")) + ( mu4e-sent-folder . "/Vlocity/[Gmail].Sent Mail" ) + ( mu4e-drafts-folder . "/Vlocity/[Gmail].Drafts" ) + ( mu4e-trash-folder . "/Vlocity/[Gmail].Trash" ) + ( mu4e-maildir-shortcuts . (("/Vlocity/INBOX" . ?i) + ("/Vlocity/[Gmail].Sent Mail" . ?s) + ("/Vlocity/[Gmail].Trash" . ?t) + ("/Vlocity/[Gmail].All Mail" . ?a))))) + ,(make-mu4e-context + :name "Gmail" + :enter-func (lambda () (mu4e-message "Entering Gmail")) + :leave-func (lambda () (mu4e-message "Leaving Gmail")) + ;; this matches maildir /Arkham and its sub-directories + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/Gmail"))) + :vars '( ( user-mail-address . "olson.levi@gmail.com" ) + ( smtpmail-mail-address . "olson.levi@gmail.com" ) + ( user-full-name . "Levi Olson" ) + ( mu4e-compose-signature . + (concat + "--\n" + "Levi\n")) + ( mu4e-sent-folder . "/Gmail/[Gmail].Sent Mail" ) + ( mu4e-drafts-folder . "/Gmail/[Gmail].Drafts" ) + ( mu4e-trash-folder . "/Gmail/[Gmail].Trash" ) + ( mu4e-maildir-shortcuts . (("/Gmail/INBOX" . ?i) + ("/Gmail/[Gmail].Sent Mail" . ?s) + ("/Gmail/[Gmail].Trash" . ?t) + ("/Gmail/[Gmail].All Mail" . ?a)) + ))))) + +;; (defcustom smtpmail-smtp-user nil +;; "User name to use when looking up credentials in the authinfo file. +;; If non-nil, only consider credentials for the specified user." +;; :version "24.1" +;; :type '(choice (const nil) string) +;; :group 'smtpmail) + + + +;; How to handle HTML emails +;; (setq mu4e-html2text-command "textutil -stdin -format html -convert txt -stdout") + +;; Add option to view HTML in browser +(add-to-list 'mu4e-headers-actions + '("in browser" . mu4e-action-view-in-browser) t) +(add-to-list 'mu4e-view-actions + '("in browser" . mu4e-action-view-in-browser) t) + (require 'projectile) (require 'counsel-projectile) @@ -581,7 +756,7 @@ (global-set-key (kbd "C-x .") 'dash-at-point) (global-set-key (kbd "C-x ,") 'dash-at-point-with-docset) (global-set-key (kbd "C-s") (lambda () (interactive) (swiper (format "%s" (thing-at-point 'symbol))))) - +(global-set-key (kbd "M-m") 'mu4e) ;; (dolist (n (number-sequence 1 9)) ;; (global-set-key (kbd (concat "M-" (int-to-string n))) ;; (lambda () (interactive) (switch-shell n)))) @@ -632,770 +807,70 @@ (cond ((member "PragmataPro" (font-family-list)) (set-face-attribute 'default nil :font "PragmataPro-14"))) -(require 'use-package) -(require 'anzu) -(require 'eldoc-eval) -(require 'iedit) -(require 'projectile) -(require 'all-the-icons) - -(defsubst doom--prepare-modeline-segments (segments) - (cl-loop for seg in segments - if (stringp seg) - collect seg - else - collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg)))))) - -(defvar doom--transient-counter 0) -(defmacro add-transient-hook! (hook &rest forms) - "Attaches transient forms to a HOOK. - -HOOK can be a quoted hook or a sharp-quoted function (which will be advised). - -These forms will be evaluated once when that function/hook is first invoked, -then it detaches itself." - (declare (indent 1)) - (let ((append (eq (car forms) :after)) - (fn (intern (format "doom-transient-hook-%s" (cl-incf doom--transient-counter))))) - `(when ,hook - (fset ',fn - (lambda (&rest _) - ,@forms - (cond ((functionp ,hook) (advice-remove ,hook #',fn)) - ((symbolp ,hook) (remove-hook ,hook #',fn))) - (unintern ',fn nil))) - (cond ((functionp ,hook) - (advice-add ,hook ,(if append :after :before) #',fn)) - ((symbolp ,hook) - (add-hook ,hook #',fn ,append)))))) - - -(defmacro add-hook! (&rest args) - "A convenience macro for `add-hook'. Takes, in order: - 1. Optional properties :local and/or :append, which will make the hook - buffer-local or append to the list of hooks (respectively), - 2. The hooks: either an unquoted major mode, an unquoted list of major-modes, - a quoted hook variable or a quoted list of hook variables. If unquoted, the - hooks will be resolved by appending -hook to each symbol. - 3. A function, list of functions, or body forms to be wrapped in a lambda. -Examples: - (add-hook! 'some-mode-hook 'enable-something) - (add-hook! some-mode '(enable-something and-another)) - (add-hook! '(one-mode-hook second-mode-hook) 'enable-something) - (add-hook! (one-mode second-mode) 'enable-something) - (add-hook! :append (one-mode second-mode) 'enable-something) - (add-hook! :local (one-mode second-mode) 'enable-something) - (add-hook! (one-mode second-mode) (setq v 5) (setq a 2)) - (add-hook! :append :local (one-mode second-mode) (setq v 5) (setq a 2)) -Body forms can access the hook's arguments through the let-bound variable -`args'." - (declare (indent defun) (debug t)) - (let ((hook-fn 'add-hook) - append-p local-p) - (while (keywordp (car args)) - (pcase (pop args) - (:append (setq append-p t)) - (:local (setq local-p t)) - (:remove (setq hook-fn 'remove-hook)))) - (let ((hooks (doom--resolve-hook-forms (pop args))) - (funcs - (let ((val (car args))) - (if (memq (car-safe val) '(quote function)) - (if (cdr-safe (cadr val)) - (cadr val) - (list (cadr val))) - (list args)))) - forms) - (dolist (fn funcs) - (setq fn (if (symbolp fn) - `(function ,fn) - `(lambda (&rest _) ,@args))) - (dolist (hook hooks) - (push (if (eq hook-fn 'remove-hook) - `(remove-hook ',hook ,fn ,local-p) - `(add-hook ',hook ,fn ,append-p ,local-p)) - forms))) - `(progn ,@(nreverse forms))))) - -(defmacro def-modeline-segment! (name &rest forms) - "Defines a modeline segment and byte compiles it." - (declare (indent defun) (doc-string 2)) - (let ((sym (intern (format "doom-modeline-segment--%s" name)))) - `(progn - (defun ,sym () ,@forms) - ,(unless (bound-and-true-p byte-compile-current-file) - `(let (byte-compile-warnings) - (byte-compile #',sym)))))) - -(defmacro def-modeline! (name lhs &optional rhs) - "Defines a modeline format and byte-compiles it. NAME is a symbol to identify -it (used by `doom-modeline' for retrieval). LHS and RHS are lists of symbols of -modeline segments defined with `def-modeline-segment!'. -Example: - (def-modeline! minimal - (bar matches \" \" buffer-info) - (media-info major-mode)) - (doom-set-modeline 'minimal t)" - (let ((sym (intern (format "doom-modeline-format--%s" name))) - (lhs-forms (doom--prepare-modeline-segments lhs)) - (rhs-forms (doom--prepare-modeline-segments rhs))) - `(progn - (defun ,sym () - (let ((lhs (list ,@lhs-forms)) - (rhs (list ,@rhs-forms))) - (let ((rhs-str (format-mode-line rhs))) - (list lhs - (propertize - " " 'display - `((space :align-to (- (+ right right-fringe right-margin) - ,(+ 1 (string-width rhs-str)))))) - rhs-str)))) - ,(unless (bound-and-true-p byte-compile-current-file) - `(let (byte-compile-warnings) - (byte-compile #',sym)))))) - -(defun doom-modeline (key) - "Returns a mode-line configuration associated with KEY (a symbol). Throws an -error if it doesn't exist." - (let ((fn (intern (format "doom-modeline-format--%s" key)))) - (when (functionp fn) - `(:eval (,fn))))) - -(defun doom-set-modeline (key &optional default) - "Set the modeline format. Does nothing if the modeline KEY doesn't exist. If -DEFAULT is non-nil, set the default mode-line for all buffers." - (when-let ((modeline (doom-modeline key))) - (setf (if default - (default-value 'mode-line-format) - (buffer-local-value 'mode-line-format (current-buffer))) - modeline))) - -(use-package eldoc-eval - :config - (defun +doom-modeline-eldoc (text) - (concat (when (display-graphic-p) - (+doom-modeline--make-xpm - (face-background 'doom-modeline-eldoc-bar nil t) - +doom-modeline-height - +doom-modeline-bar-width)) - text)) - - ;; Show eldoc in the mode-line with `eval-expression' - (defun +doom-modeline--show-eldoc (input) - "Display string STR in the mode-line next to minibuffer." - (with-current-buffer (eldoc-current-buffer) - (let* ((str (and (stringp input) input)) - (mode-line-format (or (and str (or (+doom-modeline-eldoc str) str)) - mode-line-format)) - mode-line-in-non-selected-windows) - (force-mode-line-update) - (sit-for eldoc-show-in-mode-line-delay)))) - (setq eldoc-in-minibuffer-show-fn #'+doom-modeline--show-eldoc) - - (eldoc-in-minibuffer-mode +1)) - -;; anzu and evil-anzu expose current/total state that can be displayed in the -;; mode-line. -(use-package anzu - :init - ;; (add-transient-hook! #'ex-start-search (require 'anzu)) - ;; (add-transient-hook! #'ex-start-word-search (require 'anzu)) - :config - (setq anzu-cons-mode-line-p nil - anzu-minimum-input-length 1 - anzu-search-threshold 250) - ;; Avoid anzu conflicts across buffers - (mapc #'make-variable-buffer-local - '(anzu--total-matched anzu--current-position anzu--state - anzu--cached-count anzu--cached-positions anzu--last-command - anzu--last-isearch-string anzu--overflow-p)) - ;; Ensure anzu state is cleared when searches & iedit are done - (add-hook 'isearch-mode-end-hook #'anzu--reset-status t) - ;; (add-hook '+evil-esc-hook #'anzu--reset-status t) - (add-hook 'iedit-mode-end-hook #'anzu--reset-status)) - - -;; Keep `+doom-modeline-current-window' up-to-date -(defvar +doom-modeline-current-window (frame-selected-window)) -(defun +doom-modeline|set-selected-window (&rest _) - "Sets `+doom-modeline-current-window' appropriately" - (when-let ((win (frame-selected-window))) - (unless (minibuffer-window-active-p win) - (setq +doom-modeline-current-window win)))) - -(add-hook 'window-configuration-change-hook #'+doom-modeline|set-selected-window) -(add-hook 'focus-in-hook #'+doom-modeline|set-selected-window) -(advice-add #'handle-switch-frame :after #'+doom-modeline|set-selected-window) -(advice-add #'select-window :after #'+doom-modeline|set-selected-window) - -;; fish-style modeline -(use-package shrink-path - :commands (shrink-path-prompt shrink-path-file-mixed)) - - -;; -;; Variables -;; - -(defvar +doom-modeline-height 29 - "How tall the mode-line should be (only respected in GUI emacs).") - -(defvar +doom-modeline-bar-width 3 - "How wide the mode-line bar should be (only respected in GUI emacs).") +(require 'doom-modeline) +(doom-modeline-mode 1) -(defvar +doom-modeline-vspc - (propertize " " 'face 'variable-pitch) - "TODO") -(defvar +doom-modeline-buffer-file-name-style 'truncate-upto-project - "Determines the style used by `+doom-modeline-buffer-file-name'. - -Given ~/Projects/FOSS/emacs/lisp/comint.el -truncate-upto-project => ~/P/F/emacs/lisp/comint.el -truncate-upto-root => ~/P/F/e/lisp/comint.el -truncate-all => ~/P/F/e/l/comint.el -relative-from-project => emacs/lisp/comint.el -relative-to-project => lisp/comint.el -file-name => comint.el") - -;; externs -(defvar anzu--state nil) -(defvar evil-mode nil) -(defvar evil-state nil) -(defvar evil-visual-selection nil) -(defvar iedit-mode nil) -(defvar all-the-icons-scale-factor) -(defvar all-the-icons-default-adjust) +;; How tall the mode-line should be (only respected in GUI Emacs). +(setq doom-modeline-height 35) +;; How wide the mode-line bar should be (only respected in GUI Emacs). +(setq doom-modeline-bar-width 4) +;; Determines the style used by `doom-modeline-buffer-file-name'. ;; -;; Custom faces +;; Given ~/Projects/FOSS/emacs/lisp/comint.el +;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el +;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el +;; truncate-with-project => emacs/l/comint.el +;; truncate-except-project => ~/P/F/emacs/l/comint.el +;; truncate-upto-root => ~/P/F/e/lisp/comint.el +;; truncate-all => ~/P/F/e/l/comint.el +;; relative-from-project => emacs/lisp/comint.el +;; relative-to-project => lisp/comint.el +;; file-name => comint.el +;; buffer-name => comint.el<2> (uniquify buffer name) ;; +;; If you are expereicing the laggy issue, especially while editing remote files +;; with tramp, please try `file-name' style. +;; Please refer to https://github.com/bbatsov/projectile/issues/657. +(setq doom-modeline-buffer-file-name-style 'truncate-upto-project) -(defgroup +doom-modeline nil - "" - :group 'doom) - -(defface doom-modeline-buffer-path - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the dirname part of the buffer path." - :group '+doom-modeline) - -(defface doom-modeline-buffer-file - '((t (:inherit (mode-line-buffer-id bold)))) - "Face used for the filename part of the mode-line buffer path." - :group '+doom-modeline) - -(defface doom-modeline-buffer-modified - '((t (:inherit (error bold) :background nil))) - "Face used for the 'unsaved' symbol in the mode-line." - :group '+doom-modeline) - -(defface doom-modeline-buffer-major-mode - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the major-mode segment in the mode-line." - :group '+doom-modeline) - -(defface doom-modeline-highlight - '((t (:inherit mode-line-emphasis))) - "Face for bright segments of the mode-line." - :group '+doom-modeline) - -(defface doom-modeline-panel - '((t (:inherit mode-line-highlight))) - "Face for 'X out of Y' segments, such as `+doom-modeline--anzu', `+doom-modeline--evil-substitute' and -`iedit'" - :group '+doom-modeline) - -(defface doom-modeline-info - `((t (:inherit (success bold)))) - "Face for info-level messages in the modeline. Used by `*vc'." - :group '+doom-modeline) - -(defface doom-modeline-warning - `((t (:inherit (warning bold)))) - "Face for warnings in the modeline. Used by `*flycheck'" - :group '+doom-modeline) - -(defface doom-modeline-urgent - `((t (:inherit (error bold)))) - "Face for errors in the modeline. Used by `*flycheck'" - :group '+doom-modeline) - -;; Bar -(defface doom-modeline-bar '((t (:inherit highlight))) - "The face used for the left-most bar on the mode-line of an active window." - :group '+doom-modeline) - -(defface doom-modeline-eldoc-bar '((t (:inherit shadow))) - "The face used for the left-most bar on the mode-line when eldoc-eval is -active." - :group '+doom-modeline) - -(defface doom-modeline-inactive-bar '((t (:inherit warning :inverse-video t))) - "The face used for the left-most bar on the mode-line of an inactive window." - :group '+doom-modeline) +;; What executable of Python will be used (if nil nothing will be showed). +(setq doom-modeline-python-executable "python") +;; Whether show `all-the-icons' or not (if nil nothing will be showed). +(setq doom-modeline-icon t) -;; -;; Modeline helpers -;; +;; Whether show the icon for major mode. It respects `doom-modeline-icon'. +(setq doom-modeline-major-mode-icon t) -(defsubst active () - (eq (selected-window) +doom-modeline-current-window)) - -;; Inspired from `powerline's `pl/make-xpm'. -(defun +doom-modeline--make-xpm (color height width) - "Create an XPM bitmap." - (propertize - " " 'display - (let ((data (make-list height (make-list width 1))) - (color (or color "None"))) - (create-image - (concat - (format "/* XPM */\nstatic char * percent[] = {\n\"%i %i 2 1\",\n\". c %s\",\n\" c %s\"," - (length (car data)) - (length data) - color - color) - (apply #'concat - (cl-loop with idx = 0 - with len = (length data) - for dl in data - do (cl-incf idx) - collect - (concat "\"" - (cl-loop for d in dl - if (= d 0) collect (string-to-char " ") - else collect (string-to-char ".")) - (if (eq idx len) "\"};" "\",\n"))))) - 'xpm t :ascent 'center)))) - -(defun +doom-modeline-buffer-file-name () - "Propertized `buffer-file-name' based on `+doom-modeline-buffer-file-name-style'." - (propertize - (pcase +doom-modeline-buffer-file-name-style - ('truncate-upto-project (+doom-modeline--buffer-file-name 'shrink)) - ('truncate-upto-root (+doom-modeline--buffer-file-name-truncate)) - ('truncate-all (+doom-modeline--buffer-file-name-truncate t)) - ('relative-to-project (+doom-modeline--buffer-file-name-relative)) - ('relative-from-project (+doom-modeline--buffer-file-name-relative 'include-project)) - ('file-name (propertize (file-name-nondirectory buffer-file-name) - 'face - (let ((face (or (and (buffer-modified-p) - 'doom-modeline-buffer-modified) - (and (active) - 'doom-modeline-buffer-file)))) - (when face `(:inherit ,face)))))) - 'help-echo buffer-file-truename)) - -(defun +doom-modeline--buffer-file-name-truncate (&optional truncate-tail) - "Propertized `buffer-file-name' that truncates every dir along path. -If TRUNCATE-TAIL is t also truncate the parent directory of the file." - (let ((dirs (shrink-path-prompt (file-name-directory buffer-file-truename))) - (active (active))) - (if (null dirs) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (let ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((dirname (car dirs)) - (basename (cdr dirs)) - (dir-faces (or modified-faces (if active 'doom-modeline-project-root-dir))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (concat (propertize (concat dirname - (if truncate-tail (substring basename 0 1) basename) - "/") - 'face (if dir-faces `(:inherit ,dir-faces))) - (propertize (file-name-nondirectory buffer-file-name) - 'face (if file-faces `(:inherit ,file-faces))))))))) - -(defun +doom-modeline--buffer-file-name-relative (&optional include-project) - "Propertized `buffer-file-name' showing directories relative to project's root only." - (let ((root (projectile-project-root)) - (active (active))) - (if (null root) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (let* ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified)) - (relative-dirs (file-relative-name (file-name-directory buffer-file-truename) - (if include-project (concat root "../") root))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (if (equal "./" relative-dirs) (setq relative-dirs "")) - (concat (propertize relative-dirs 'face (if relative-faces `(:inherit ,relative-faces))) - (propertize (file-name-nondirectory buffer-file-truename) - 'face (if file-faces `(:inherit ,file-faces)))))))) - -(defun +doom-modeline--buffer-file-name (truncate-project-root-parent) - "Propertized `buffer-file-name'. -If TRUNCATE-PROJECT-ROOT-PARENT is t space will be saved by truncating it down -fish-shell style. - -Example: -~/Projects/FOSS/emacs/lisp/comint.el => ~/P/F/emacs/lisp/comint.el" - (let* ((project-root (projectile-project-root)) - (file-name-split (shrink-path-file-mixed project-root - (file-name-directory buffer-file-truename) - buffer-file-truename)) - (active (active))) - (if (null file-name-split) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (pcase-let ((`(,root-path-parent ,project ,relative-path ,filename) file-name-split)) - (let ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((sp-faces (or modified-faces (if active 'font-lock-comment-face))) - (project-faces (or modified-faces (if active 'font-lock-string-face))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (let ((sp-props `(,@(if sp-faces `(:inherit ,sp-faces)) ,@(if active '(:weight bold)))) - (project-props `(,@(if project-faces `(:inherit ,project-faces)) ,@(if active '(:weight bold)))) - (relative-props `(,@(if relative-faces `(:inherit ,relative-faces)))) - (file-props `(,@(if file-faces `(:inherit ,file-faces))))) - (concat (propertize (if truncate-project-root-parent - root-path-parent - (abbreviate-file-name project-root)) - 'face sp-props) - (propertize (concat project "/") 'face project-props) - (if relative-path (propertize relative-path 'face relative-props)) - (propertize filename 'face file-props))))))))) - - -;; -;; Segments -;; +;; Display color icons for `major-mode'. It respects `all-the-icons-color-icons'. +(setq doom-modeline-major-mode-color-icon nil) -(def-modeline-segment! buffer-default-directory - "Displays `default-directory'. This is for special buffers like the scratch -buffer where knowing the current project directory is important." - (let ((face (if (active) 'doom-modeline-buffer-path))) - (concat (if (display-graphic-p) " ") - (all-the-icons-octicon - "file-directory" - :face face - :v-adjust -0.05 - :height 1.25) - (propertize (concat " " (abbreviate-file-name default-directory)) - 'face face)))) +;; Whether display minor modes or not. Non-nil to display in mode-line. +(setq doom-modeline-minor-modes nil) -;; -(def-modeline-segment! buffer-info - "Combined information about the current buffer, including the current working -directory, the file name, and its state (modified, read-only or non-existent)." - (concat (cond (buffer-read-only - (concat (all-the-icons-octicon - "lock" - :face 'doom-modeline-warning - :v-adjust -0.05) - " ")) - ((buffer-modified-p) - (concat (all-the-icons-faicon - "floppy-o" - :face 'doom-modeline-buffer-modified - :v-adjust -0.0575) - " ")) - ((and buffer-file-name - (not (file-exists-p buffer-file-name))) - (concat (all-the-icons-octicon - "circle-slash" - :face 'doom-modeline-urgent - :v-adjust -0.05) - " ")) - ((buffer-narrowed-p) - (concat (all-the-icons-octicon - "fold" - :face 'doom-modeline-warning - :v-adjust -0.05) - " "))) - (if buffer-file-name - (+doom-modeline-buffer-file-name) - "%b"))) +;; If non-nil, a word count will be added to the selection-info modeline segment. +(setq doom-modeline-enable-word-count nil) -;; -(def-modeline-segment! buffer-info-simple - "Display only the current buffer's name, but with fontification." - (propertize - "%b" - 'face (cond ((and buffer-file-name (buffer-modified-p)) - 'doom-modeline-buffer-modified) - ((active) 'doom-modeline-buffer-file)))) +;; If non-nil, only display one number for checker information if applicable. +(setq doom-modeline-checker-simple-format t) -;; -(def-modeline-segment! buffer-encoding - "Displays the encoding and eol style of the buffer the same way Atom does." - (concat (pcase (coding-system-eol-type buffer-file-coding-system) - (0 "LF ") - (1 "CRLF ") - (2 "CR ")) - (let ((sys (coding-system-plist buffer-file-coding-system))) - (cond ((memq (plist-get sys :category) '(coding-category-undecided coding-category-utf-8)) - "UTF-8") - (t (upcase (symbol-name (plist-get sys :name)))))) - " ")) +;; Whether display perspective name or not. Non-nil to display in mode-line. +(setq doom-modeline-persp-name t) -;; -(def-modeline-segment! major-mode - "The major mode, including process, environment and text-scale info." - (propertize - (concat (format-mode-line mode-name) - (when (stringp mode-line-process) - mode-line-process) - (and (featurep 'face-remap) - (/= text-scale-mode-amount 0) - (format " (%+d)" text-scale-mode-amount))) - 'face (if (active) 'doom-modeline-buffer-major-mode))) +;; Whether display `lsp' state or not. Non-nil to display in mode-line. +(setq doom-modeline-lsp t) -;; -(def-modeline-segment! vcs - "Displays the current branch, colored based on its state." - (when (and vc-mode buffer-file-name) - (let* ((backend (vc-backend buffer-file-name)) - (state (vc-state buffer-file-name backend))) - (let ((face 'mode-line-inactive) - (active (active)) - (all-the-icons-default-adjust -0.1)) - (concat " " - (cond ((memq state '(edited added)) - (if active (setq face 'doom-modeline-info)) - (all-the-icons-octicon - "git-compare" - :face face - :v-adjust -0.05)) - ((eq state 'needs-merge) - (if active (setq face 'doom-modeline-info)) - (all-the-icons-octicon "git-merge" :face face)) - ((eq state 'needs-update) - (if active (setq face 'doom-modeline-warning)) - (all-the-icons-octicon "arrow-down" :face face)) - ((memq state '(removed conflict unregistered)) - (if active (setq face 'doom-modeline-urgent)) - (all-the-icons-octicon "alert" :face face)) - (t - (if active (setq face 'font-lock-doc-face)) - (all-the-icons-octicon - "git-compare" - :face face - :v-adjust -0.05))) - " " - (propertize (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2)) - 'face (if active face)) - " "))))) +;; Whether display github notifications or not. Requires `ghub` package. +(setq doom-modeline-github nil) -;; -(defun +doom-ml-icon (icon &optional text face voffset) - "Displays an octicon ICON with FACE, followed by TEXT. Uses -`all-the-icons-octicon' to fetch the icon." - (concat (if vc-mode " " " ") - (when icon - (concat - (all-the-icons-material icon :face face :height 1.1 :v-adjust (or voffset -0.2)) - (if text +doom-modeline-vspc))) - (when text - (propertize text 'face face)) - (if vc-mode " " " "))) - -(def-modeline-segment! flycheck - "Displays color-coded flycheck error status in the current buffer with pretty -icons." - (when (boundp 'flycheck-last-status-change) - (pcase flycheck-last-status-change - ('finished (if flycheck-current-errors - (let-alist (flycheck-count-errors flycheck-current-errors) - (let ((sum (+ (or .error 0) (or .warning 0)))) - (+doom-ml-icon "do_not_disturb_alt" - (number-to-string sum) - (if .error 'doom-modeline-urgent 'doom-modeline-warning) - -0.25))) - (+doom-ml-icon "check" nil 'doom-modeline-info))) - ('running (+doom-ml-icon "access_time" nil 'font-lock-doc-face -0.25)) - ('no-checker (+doom-ml-icon "sim_card_alert" "-" 'font-lock-doc-face)) - ('errored (+doom-ml-icon "sim_card_alert" "Error" 'doom-modeline-urgent)) - ('interrupted (+doom-ml-icon "pause" "Interrupted" 'font-lock-doc-face))))) -;; ('interrupted (+doom-ml-icon "x" "Interrupted" 'font-lock-doc-face))))) - -;; -(defsubst doom-column (pos) - (save-excursion (goto-char pos) - (current-column))) - -(def-modeline-segment! selection-info - "Information about the current selection, such as how many characters and -lines are selected, or the NxM dimensions of a block selection." - (when (and (active) (or mark-active (eq evil-state 'visual))) - (let ((reg-beg (region-beginning)) - (reg-end (region-end))) - (propertize - (let ((lines (count-lines reg-beg (min (1+ reg-end) (point-max))))) - (cond ((or (bound-and-true-p rectangle-mark-mode) - (eq 'block evil-visual-selection)) - (let ((cols (abs (- (doom-column reg-end) - (doom-column reg-beg))))) - (format "%dx%dB" lines cols))) - ((eq 'line evil-visual-selection) - (format "%dL" lines)) - ((> lines 1) - (format "%dC %dL" (- (1+ reg-end) reg-beg) lines)) - (t - (format "%dC" (- (1+ reg-end) reg-beg))))) - 'face 'doom-modeline-highlight)))) - - -;; -(defun +doom-modeline--macro-recording () - "Display current Emacs or evil macro being recorded." - (when (and (active) (or defining-kbd-macro executing-kbd-macro)) - (let ((sep (propertize " " 'face 'doom-modeline-panel))) - (concat sep - (propertize (if (bound-and-true-p evil-this-macro) - (char-to-string evil-this-macro) - "Macro") - 'face 'doom-modeline-panel) - sep - (all-the-icons-octicon "triangle-right" - :face 'doom-modeline-panel - :v-adjust -0.05) - sep)))) - -(defsubst +doom-modeline--anzu () - "Show the match index and total number thereof. Requires `anzu', also -`evil-anzu' if using `evil-mode' for compatibility with `evil-search'." - (when (and anzu--state (not iedit-mode)) - (propertize - (let ((here anzu--current-position) - (total anzu--total-matched)) - (cond ((eq anzu--state 'replace-query) - (format " %d replace " total)) - ((eq anzu--state 'replace) - (format " %d/%d " here total)) - (anzu--overflow-p - (format " %s+ " total)) - (t - (format " %s/%d " here total)))) - 'face (if (active) 'doom-modeline-panel)))) - -(defsubst +doom-modeline--evil-substitute () - "Show number of matches for evil-ex substitutions and highlights in real time." - (when (and evil-mode - (or (assq 'evil-ex-substitute evil-ex-active-highlights-alist) - (assq 'evil-ex-global-match evil-ex-active-highlights-alist) - (assq 'evil-ex-buffer-match evil-ex-active-highlights-alist))) - (propertize - (let ((range (if evil-ex-range - (cons (car evil-ex-range) (cadr evil-ex-range)) - (cons (line-beginning-position) (line-end-position)))) - (pattern (car-safe (evil-delimited-arguments evil-ex-argument 2)))) - (if pattern - (format " %s matches " (how-many pattern (car range) (cdr range))) - " - ")) - 'face (if (active) 'doom-modeline-panel)))) - -(defun doom-themes--overlay-sort (a b) - (< (overlay-start a) (overlay-start b))) - -(defsubst +doom-modeline--iedit () - "Show the number of iedit regions matches + what match you're on." - (when (and iedit-mode iedit-occurrences-overlays) - (propertize - (let ((this-oc (or (let ((inhibit-message t)) - (iedit-find-current-occurrence-overlay)) - (progn (iedit-prev-occurrence) - (iedit-find-current-occurrence-overlay)))) - (length (length iedit-occurrences-overlays))) - (format " %s/%d " - (if this-oc - (- length - (length (memq this-oc (sort (append iedit-occurrences-overlays nil) - #'doom-themes--overlay-sort))) - -1) - "-") - length)) - 'face (if (active) 'doom-modeline-panel)))) - -(def-modeline-segment! matches - "Displays: 1. the currently recording macro, 2. A current/total for the -current search term (with anzu), 3. The number of substitutions being conducted -with `evil-ex-substitute', and/or 4. The number of active `iedit' regions." - (let ((meta (concat (+doom-modeline--macro-recording) - (+doom-modeline--anzu) - (+doom-modeline--evil-substitute) - (+doom-modeline--iedit)))) - (or (and (not (equal meta "")) meta) - (if buffer-file-name " %I ")))) - -;; TODO Include other information -(def-modeline-segment! media-info - "Metadata regarding the current file, such as dimensions for images." - (cond ((eq major-mode 'image-mode) - (cl-destructuring-bind (width . height) - (image-size (image-get-display-property) :pixels) - (format " %dx%d " width height))))) - -(def-modeline-segment! bar - "The bar regulates the height of the mode-line in GUI Emacs. -Returns \"\" to not break --no-window-system." - (if (display-graphic-p) - (+doom-modeline--make-xpm - (face-background (if (active) - 'doom-modeline-bar - 'doom-modeline-inactive-bar) - nil t) - +doom-modeline-height - +doom-modeline-bar-width) - "")) - - -;; -;; Mode lines -;; - -(def-modeline! main - (bar matches " " buffer-info " %l:%c %p " selection-info) - (buffer-encoding major-mode vcs flycheck)) - -(def-modeline! minimal - (bar matches " " buffer-info) - (media-info major-mode)) - -(def-modeline! special - (bar matches " " buffer-info-simple " %l:%c %p " selection-info) - (buffer-encoding major-mode flycheck)) - -(def-modeline! project - (bar buffer-default-directory) - (major-mode)) - -(def-modeline! media - (bar " %b ") - (media-info major-mode)) - - -;; -;; Hooks -;; - -(defun +doom-modeline|init () - "Set the default modeline." - (doom-set-modeline 'main t) - - ;; This scratch buffer is already created and doesn't get a modeline. For the - ;; love of Emacs, someone give the man a modeline! - (with-current-buffer "*scratch*" - (doom-set-modeline 'main))) - -(defun +doom-modeline|set-special-modeline () - (doom-set-modeline 'special)) - -(defun +doom-modeline|set-media-modeline () - (doom-set-modeline 'media)) - -(defun +doom-modeline|set-project-modeline () - (doom-set-modeline 'project)) - - -;; -;; Bootstrap -;; +;; The interval of checking github. +(setq doom-modeline-github-interval (* 30 60)) -(add-hook 'emacs-startup-hook #'+doom-modeline|init) -;; (add-hook 'doom-scratch-buffer-hook #'+doom-modeline|set-special-modeline) -;; (add-hook '+doom-dashboard-mode-hook #'+doom-modeline|set-project-modeline) +;; Whether display environment version or not. +(setq doom-modeline-env-version t) -(add-hook 'image-mode-hook #'+doom-modeline|set-media-modeline) -(add-hook 'org-src-mode-hook #'+doom-modeline|set-special-modeline) -(add-hook 'circe-mode-hook #'+doom-modeline|set-special-modeline) +;; Whether display mu4e notifications or not. Requires `mu4e-alert' package. +(setq doom-modeline-mu4e t) diff --git a/init.elc b/init.elc index 0d1863e..656cbdd 100644 Binary files a/init.elc and b/init.elc differ diff --git a/init.org b/init.org index e5a1c00..894ee64 100644 --- a/init.org +++ b/init.org @@ -49,6 +49,7 @@ '(all-the-icons anzu base16-theme + bbdb better-defaults company company-go @@ -57,6 +58,7 @@ dash-at-point diminish dockerfile-mode + doom-modeline doom-themes ein eldoc-eval @@ -75,6 +77,7 @@ magit material-theme multiple-cursors + nnir-est projectile py-autopep8 rainbow-delimiters @@ -96,7 +99,12 @@ (when (not (package-installed-p p)) (package-install p))) #+END_SRC +** Server + #+BEGIN_SRC emacs-lisp :results silent + (require 'edit-server) + (edit-server-start) + #+END_SRC ** Better Defaults #+BEGIN_SRC emacs-lisp :results silent (require 'better-defaults) @@ -148,12 +156,17 @@ (add-to-list 'default-frame-alist (cons 'top 0)) (add-to-list 'default-frame-alist (cons 'left 1000)) #+END_SRC - +** Enable Disabled Commands +#+BEGIN_SRC emacs-lisp :results silent + (put 'narrow-to-region 'disabled nil) + (put 'upcase-region 'disabled nil) + (put 'downcase-region 'disabled nil) +#+END_SRC ** Splash Screen #+BEGIN_SRC emacs-lisp :results silent - (setq inhibit-splash-screen nil - fancy-splash-image "~/.emacs.d/public/emacs-logo.png" - fancy-splash-image-file "~/.emacs.d/public/emacs-logo.png") + (setq inhibit-splash-screen nil + fancy-splash-image "~/.emacs.d/public/emacs-logo.png" + fancy-splash-image-file "~/.emacs.d/public/emacs-logo.png") #+END_SRC ** Basic Customization #+BEGIN_SRC emacs-lisp :results silent @@ -182,7 +195,91 @@ (defalias 'yes-or-no-p 'y-or-n-p) #+END_SRC - +** Custom Modes + #+BEGIN_SRC emacs-lisp :results silent + (require 'font-lock) + + (defvar openhab-mode-hook nil) + + (defvar openhab-mode-map + (let ((map (make-keymap))) + (define-key map "\C-j" 'newline-and-indent) + map) + "Keymap for OPENHAB major mode.") + + (add-to-list 'auto-mode-alist '("\\.sitemap\\'" . openhab-mode)) + (add-to-list 'auto-mode-alist '("\\.items\\'" . openhab-mode)) + (add-to-list 'auto-mode-alist '("\\.rules\\'" . openhab-mode)) + (add-to-list 'auto-mode-alist '("\\.things\\'" . openhab-mode)) + + (defconst openhab-font-lock-keywords + `( + ("\<.*\>" . font-lock-constant-face) + (,(regexp-opt + '( + ;; KEYWORDS + "Selection" "Slider" "List" "Setpoint" "Video" "Chart" "Webview" "Colorpicker" + "Timer" "Number" "String" + "Switch" "Rollershutter" "Number" "String" "Dimmer" "Contact" "DateTime" "Color" + "Text" "Group" "Image" "Frame" + "Thing" "Bridge" + "Time" "System" + "sitemap" + + "rule" "when" "then" "end" + "if" "val" + "import" "var" "say" "postUpdate" "switch" "println" "case" "or" "sendCommand" + ) + 'words) + (1 font-lock-keyword-face)) + (,(regexp-opt + '( + "ON" "OFF" "on" "off" + "AND" "OR" "NAND" "NOR" "AVG" "SUM" "MAX" "MIN" + "true" "false" + ) + 'words) + (1 font-lock-constant-face)) + (,(regexp-opt + '( + "name" "label" "item" "period" "refresh" "icon" "mappings" "minValue" "maxValue" "step" "switchsupport" "url" "height" "refresh" "visibility" "valuecolor" + ) + 'words) + (1 font-lock-type-face)) + ("\(.*\)" . font-lock-variable-name-face) + ("[^a-zA-Z0-9_:]\\([0-9]*\\)[^a-zA-Z0-9_:]" . (1 font-lock-variable-name-face)) + ("\s@\s" . font-lock-variable-name-face) + ("\s\\([a-zA-Z0-9_:]*\\)\\(\s\\|$\\)" . (1 font-lock-type-face)) + ("=\\([a-zA-Z_]*\\)" . (1 font-lock-string-face)) + ("\\([a-zA-Z]*\\)=" . (1 font-lock-type-face)) + ) + "The regexps to highlight in openHAB mode.") + + (defvar openhab-mode-syntax-table + (let ((st (make-syntax-table))) + (modify-syntax-entry ?/ ". 12b" st) ;; C-style comments // ... + (modify-syntax-entry ?\n "> b" st) ;; \n ends comment + ;; Block comments /*...*/ + (modify-syntax-entry ?\/ ". 14" st) + (modify-syntax-entry ?* ". 23" st) + st) + "Syntax table for openhab-mode.") + + (defun openhab-mode () + "Major mode for editing OPENHAB config files." + (interactive) + (kill-all-local-variables) + (set-syntax-table openhab-mode-syntax-table) + (use-local-map openhab-mode-map) + (set (make-local-variable 'font-lock-defaults) '(openhab-font-lock-keywords nil t)) + (electric-pair-mode -1) + (flycheck-mode -1) + (setq major-mode 'openhab-mode) + (setq mode-name "OpenHAB") + (run-hooks 'openhab-mode-hook)) + + (provide 'openhab-mode) + #+END_SRC ** Tools *** General #+BEGIN_SRC emacs-lisp :results silent @@ -270,6 +367,89 @@ (setq magit-completing-read-function 'ivy-completing-read) #+END_SRC +*** Mu4e +#+BEGIN_SRC emacs-lisp :results silent + (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu/mu4e") + (require 'mu4e) + + ;; default + (setq mu4e-maildir "~/Mail" + mu4e-mu-binary "/usr/local/bin/mu" + mu4e-get-mail-command "offlineimap" ;; Allow updating with the "U" command + mu4e-sent-messages-behavior 'delete ;; Delete sent messages + mu4e-view-show-images t ;; attempt to show images + mu4e-view-image-max-width 400 ;; max image size + message-kill-buffer-on-exit t ;; don't keep messages around + mu4e-use-fancy-chars t ;; use 'fancy' chars + mu4e-update-interval 300 ;; 5 mins + ) + + (setq mu4e-contexts + `( ,(make-mu4e-context + :name "Vlocity" + :enter-func (lambda () (mu4e-message "Entering Vlocity")) + :leave-func (lambda () (mu4e-message "Leaving Vlocity")) + ;; we match based on the contact-fields of the message + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/Vlocity"))) + :vars '( ( user-mail-address . "lolson@vlocity.com" ) + ( smtpmail-mail-address . "lolson@vlocity.com" ) + ( user-full-name . "Levi Olson" ) + ( mu4e-compose-signature . + (concat + "--\n" + "Levi Olson\n" + "Senior UI Developer")) + ( mu4e-sent-folder . "/Vlocity/[Gmail].Sent Mail" ) + ( mu4e-drafts-folder . "/Vlocity/[Gmail].Drafts" ) + ( mu4e-trash-folder . "/Vlocity/[Gmail].Trash" ) + ( mu4e-maildir-shortcuts . (("/Vlocity/INBOX" . ?i) + ("/Vlocity/[Gmail].Sent Mail" . ?s) + ("/Vlocity/[Gmail].Trash" . ?t) + ("/Vlocity/[Gmail].All Mail" . ?a))))) + ,(make-mu4e-context + :name "Gmail" + :enter-func (lambda () (mu4e-message "Entering Gmail")) + :leave-func (lambda () (mu4e-message "Leaving Gmail")) + ;; this matches maildir /Arkham and its sub-directories + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/Gmail"))) + :vars '( ( user-mail-address . "olson.levi@gmail.com" ) + ( smtpmail-mail-address . "olson.levi@gmail.com" ) + ( user-full-name . "Levi Olson" ) + ( mu4e-compose-signature . + (concat + "--\n" + "Levi\n")) + ( mu4e-sent-folder . "/Gmail/[Gmail].Sent Mail" ) + ( mu4e-drafts-folder . "/Gmail/[Gmail].Drafts" ) + ( mu4e-trash-folder . "/Gmail/[Gmail].Trash" ) + ( mu4e-maildir-shortcuts . (("/Gmail/INBOX" . ?i) + ("/Gmail/[Gmail].Sent Mail" . ?s) + ("/Gmail/[Gmail].Trash" . ?t) + ("/Gmail/[Gmail].All Mail" . ?a)) + ))))) + + ;; (defcustom smtpmail-smtp-user nil + ;; "User name to use when looking up credentials in the authinfo file. + ;; If non-nil, only consider credentials for the specified user." + ;; :version "24.1" + ;; :type '(choice (const nil) string) + ;; :group 'smtpmail) + + + + ;; How to handle HTML emails + ;; (setq mu4e-html2text-command "textutil -stdin -format html -convert txt -stdout") + + ;; Add option to view HTML in browser + (add-to-list 'mu4e-headers-actions + '("in browser" . mu4e-action-view-in-browser) t) + (add-to-list 'mu4e-view-actions + '("in browser" . mu4e-action-view-in-browser) t) +#+END_SRC *** Projectile #+BEGIN_SRC emacs-lisp :results silent (require 'projectile) @@ -663,7 +843,7 @@ (global-set-key (kbd "C-x .") 'dash-at-point) (global-set-key (kbd "C-x ,") 'dash-at-point-with-docset) (global-set-key (kbd "C-s") (lambda () (interactive) (swiper (format "%s" (thing-at-point 'symbol))))) - + (global-set-key (kbd "M-m") 'mu4e) ;; (dolist (n (number-sequence 1 9)) ;; (global-set-key (kbd (concat "M-" (int-to-string n))) ;; (lambda () (interactive) (switch-shell n)))) @@ -718,774 +898,73 @@ (set-face-attribute 'default nil :font "PragmataPro-14"))) #+END_SRC -*** Modeline - #+BEGIN_SRC emacs-lisp :results silent - (require 'use-package) - (require 'anzu) - (require 'eldoc-eval) - (require 'iedit) - (require 'projectile) - (require 'all-the-icons) - - (defsubst doom--prepare-modeline-segments (segments) - (cl-loop for seg in segments - if (stringp seg) - collect seg - else - collect (list (intern (format "doom-modeline-segment--%s" (symbol-name seg)))))) - - (defvar doom--transient-counter 0) - (defmacro add-transient-hook! (hook &rest forms) - "Attaches transient forms to a HOOK. - - HOOK can be a quoted hook or a sharp-quoted function (which will be advised). - - These forms will be evaluated once when that function/hook is first invoked, - then it detaches itself." - (declare (indent 1)) - (let ((append (eq (car forms) :after)) - (fn (intern (format "doom-transient-hook-%s" (cl-incf doom--transient-counter))))) - `(when ,hook - (fset ',fn - (lambda (&rest _) - ,@forms - (cond ((functionp ,hook) (advice-remove ,hook #',fn)) - ((symbolp ,hook) (remove-hook ,hook #',fn))) - (unintern ',fn nil))) - (cond ((functionp ,hook) - (advice-add ,hook ,(if append :after :before) #',fn)) - ((symbolp ,hook) - (add-hook ,hook #',fn ,append)))))) - - - (defmacro add-hook! (&rest args) - "A convenience macro for `add-hook'. Takes, in order: - 1. Optional properties :local and/or :append, which will make the hook - buffer-local or append to the list of hooks (respectively), - 2. The hooks: either an unquoted major mode, an unquoted list of major-modes, - a quoted hook variable or a quoted list of hook variables. If unquoted, the - hooks will be resolved by appending -hook to each symbol. - 3. A function, list of functions, or body forms to be wrapped in a lambda. - Examples: - (add-hook! 'some-mode-hook 'enable-something) - (add-hook! some-mode '(enable-something and-another)) - (add-hook! '(one-mode-hook second-mode-hook) 'enable-something) - (add-hook! (one-mode second-mode) 'enable-something) - (add-hook! :append (one-mode second-mode) 'enable-something) - (add-hook! :local (one-mode second-mode) 'enable-something) - (add-hook! (one-mode second-mode) (setq v 5) (setq a 2)) - (add-hook! :append :local (one-mode second-mode) (setq v 5) (setq a 2)) - Body forms can access the hook's arguments through the let-bound variable - `args'." - (declare (indent defun) (debug t)) - (let ((hook-fn 'add-hook) - append-p local-p) - (while (keywordp (car args)) - (pcase (pop args) - (:append (setq append-p t)) - (:local (setq local-p t)) - (:remove (setq hook-fn 'remove-hook)))) - (let ((hooks (doom--resolve-hook-forms (pop args))) - (funcs - (let ((val (car args))) - (if (memq (car-safe val) '(quote function)) - (if (cdr-safe (cadr val)) - (cadr val) - (list (cadr val))) - (list args)))) - forms) - (dolist (fn funcs) - (setq fn (if (symbolp fn) - `(function ,fn) - `(lambda (&rest _) ,@args))) - (dolist (hook hooks) - (push (if (eq hook-fn 'remove-hook) - `(remove-hook ',hook ,fn ,local-p) - `(add-hook ',hook ,fn ,append-p ,local-p)) - forms))) - `(progn ,@(nreverse forms))))) - - (defmacro def-modeline-segment! (name &rest forms) - "Defines a modeline segment and byte compiles it." - (declare (indent defun) (doc-string 2)) - (let ((sym (intern (format "doom-modeline-segment--%s" name)))) - `(progn - (defun ,sym () ,@forms) - ,(unless (bound-and-true-p byte-compile-current-file) - `(let (byte-compile-warnings) - (byte-compile #',sym)))))) - - (defmacro def-modeline! (name lhs &optional rhs) - "Defines a modeline format and byte-compiles it. NAME is a symbol to identify - it (used by `doom-modeline' for retrieval). LHS and RHS are lists of symbols of - modeline segments defined with `def-modeline-segment!'. - Example: - (def-modeline! minimal - (bar matches \" \" buffer-info) - (media-info major-mode)) - (doom-set-modeline 'minimal t)" - (let ((sym (intern (format "doom-modeline-format--%s" name))) - (lhs-forms (doom--prepare-modeline-segments lhs)) - (rhs-forms (doom--prepare-modeline-segments rhs))) - `(progn - (defun ,sym () - (let ((lhs (list ,@lhs-forms)) - (rhs (list ,@rhs-forms))) - (let ((rhs-str (format-mode-line rhs))) - (list lhs - (propertize - " " 'display - `((space :align-to (- (+ right right-fringe right-margin) - ,(+ 1 (string-width rhs-str)))))) - rhs-str)))) - ,(unless (bound-and-true-p byte-compile-current-file) - `(let (byte-compile-warnings) - (byte-compile #',sym)))))) - - (defun doom-modeline (key) - "Returns a mode-line configuration associated with KEY (a symbol). Throws an - error if it doesn't exist." - (let ((fn (intern (format "doom-modeline-format--%s" key)))) - (when (functionp fn) - `(:eval (,fn))))) - - (defun doom-set-modeline (key &optional default) - "Set the modeline format. Does nothing if the modeline KEY doesn't exist. If - DEFAULT is non-nil, set the default mode-line for all buffers." - (when-let ((modeline (doom-modeline key))) - (setf (if default - (default-value 'mode-line-format) - (buffer-local-value 'mode-line-format (current-buffer))) - modeline))) - - (use-package eldoc-eval - :config - (defun +doom-modeline-eldoc (text) - (concat (when (display-graphic-p) - (+doom-modeline--make-xpm - (face-background 'doom-modeline-eldoc-bar nil t) - +doom-modeline-height - +doom-modeline-bar-width)) - text)) - - ;; Show eldoc in the mode-line with `eval-expression' - (defun +doom-modeline--show-eldoc (input) - "Display string STR in the mode-line next to minibuffer." - (with-current-buffer (eldoc-current-buffer) - (let* ((str (and (stringp input) input)) - (mode-line-format (or (and str (or (+doom-modeline-eldoc str) str)) - mode-line-format)) - mode-line-in-non-selected-windows) - (force-mode-line-update) - (sit-for eldoc-show-in-mode-line-delay)))) - (setq eldoc-in-minibuffer-show-fn #'+doom-modeline--show-eldoc) - - (eldoc-in-minibuffer-mode +1)) - - ;; anzu and evil-anzu expose current/total state that can be displayed in the - ;; mode-line. - (use-package anzu - :init - ;; (add-transient-hook! #'ex-start-search (require 'anzu)) - ;; (add-transient-hook! #'ex-start-word-search (require 'anzu)) - :config - (setq anzu-cons-mode-line-p nil - anzu-minimum-input-length 1 - anzu-search-threshold 250) - ;; Avoid anzu conflicts across buffers - (mapc #'make-variable-buffer-local - '(anzu--total-matched anzu--current-position anzu--state - anzu--cached-count anzu--cached-positions anzu--last-command - anzu--last-isearch-string anzu--overflow-p)) - ;; Ensure anzu state is cleared when searches & iedit are done - (add-hook 'isearch-mode-end-hook #'anzu--reset-status t) - ;; (add-hook '+evil-esc-hook #'anzu--reset-status t) - (add-hook 'iedit-mode-end-hook #'anzu--reset-status)) - - - ;; Keep `+doom-modeline-current-window' up-to-date - (defvar +doom-modeline-current-window (frame-selected-window)) - (defun +doom-modeline|set-selected-window (&rest _) - "Sets `+doom-modeline-current-window' appropriately" - (when-let ((win (frame-selected-window))) - (unless (minibuffer-window-active-p win) - (setq +doom-modeline-current-window win)))) - - (add-hook 'window-configuration-change-hook #'+doom-modeline|set-selected-window) - (add-hook 'focus-in-hook #'+doom-modeline|set-selected-window) - (advice-add #'handle-switch-frame :after #'+doom-modeline|set-selected-window) - (advice-add #'select-window :after #'+doom-modeline|set-selected-window) - - ;; fish-style modeline - (use-package shrink-path - :commands (shrink-path-prompt shrink-path-file-mixed)) - - - ;; - ;; Variables - ;; - - (defvar +doom-modeline-height 29 - "How tall the mode-line should be (only respected in GUI emacs).") - - (defvar +doom-modeline-bar-width 3 - "How wide the mode-line bar should be (only respected in GUI emacs).") - - (defvar +doom-modeline-vspc - (propertize " " 'face 'variable-pitch) - "TODO") - - (defvar +doom-modeline-buffer-file-name-style 'truncate-upto-project - "Determines the style used by `+doom-modeline-buffer-file-name'. - - Given ~/Projects/FOSS/emacs/lisp/comint.el - truncate-upto-project => ~/P/F/emacs/lisp/comint.el - truncate-upto-root => ~/P/F/e/lisp/comint.el - truncate-all => ~/P/F/e/l/comint.el - relative-from-project => emacs/lisp/comint.el - relative-to-project => lisp/comint.el - file-name => comint.el") - - ;; externs - (defvar anzu--state nil) - (defvar evil-mode nil) - (defvar evil-state nil) - (defvar evil-visual-selection nil) - (defvar iedit-mode nil) - (defvar all-the-icons-scale-factor) - (defvar all-the-icons-default-adjust) - - - ;; - ;; Custom faces - ;; - - (defgroup +doom-modeline nil - "" - :group 'doom) - - (defface doom-modeline-buffer-path - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the dirname part of the buffer path." - :group '+doom-modeline) - - (defface doom-modeline-buffer-file - '((t (:inherit (mode-line-buffer-id bold)))) - "Face used for the filename part of the mode-line buffer path." - :group '+doom-modeline) - - (defface doom-modeline-buffer-modified - '((t (:inherit (error bold) :background nil))) - "Face used for the 'unsaved' symbol in the mode-line." - :group '+doom-modeline) - - (defface doom-modeline-buffer-major-mode - '((t (:inherit (mode-line-emphasis bold)))) - "Face used for the major-mode segment in the mode-line." - :group '+doom-modeline) - - (defface doom-modeline-highlight - '((t (:inherit mode-line-emphasis))) - "Face for bright segments of the mode-line." - :group '+doom-modeline) - - (defface doom-modeline-panel - '((t (:inherit mode-line-highlight))) - "Face for 'X out of Y' segments, such as `+doom-modeline--anzu', `+doom-modeline--evil-substitute' and - `iedit'" - :group '+doom-modeline) - - (defface doom-modeline-info - `((t (:inherit (success bold)))) - "Face for info-level messages in the modeline. Used by `*vc'." - :group '+doom-modeline) - - (defface doom-modeline-warning - `((t (:inherit (warning bold)))) - "Face for warnings in the modeline. Used by `*flycheck'" - :group '+doom-modeline) - - (defface doom-modeline-urgent - `((t (:inherit (error bold)))) - "Face for errors in the modeline. Used by `*flycheck'" - :group '+doom-modeline) - - ;; Bar - (defface doom-modeline-bar '((t (:inherit highlight))) - "The face used for the left-most bar on the mode-line of an active window." - :group '+doom-modeline) - - (defface doom-modeline-eldoc-bar '((t (:inherit shadow))) - "The face used for the left-most bar on the mode-line when eldoc-eval is - active." - :group '+doom-modeline) - - (defface doom-modeline-inactive-bar '((t (:inherit warning :inverse-video t))) - "The face used for the left-most bar on the mode-line of an inactive window." - :group '+doom-modeline) - - - ;; - ;; Modeline helpers - ;; - - (defsubst active () - (eq (selected-window) +doom-modeline-current-window)) - - ;; Inspired from `powerline's `pl/make-xpm'. - (defun +doom-modeline--make-xpm (color height width) - "Create an XPM bitmap." - (propertize - " " 'display - (let ((data (make-list height (make-list width 1))) - (color (or color "None"))) - (create-image - (concat - (format "/* XPM */\nstatic char * percent[] = {\n\"%i %i 2 1\",\n\". c %s\",\n\" c %s\"," - (length (car data)) - (length data) - color - color) - (apply #'concat - (cl-loop with idx = 0 - with len = (length data) - for dl in data - do (cl-incf idx) - collect - (concat "\"" - (cl-loop for d in dl - if (= d 0) collect (string-to-char " ") - else collect (string-to-char ".")) - (if (eq idx len) "\"};" "\",\n"))))) - 'xpm t :ascent 'center)))) - - (defun +doom-modeline-buffer-file-name () - "Propertized `buffer-file-name' based on `+doom-modeline-buffer-file-name-style'." - (propertize - (pcase +doom-modeline-buffer-file-name-style - ('truncate-upto-project (+doom-modeline--buffer-file-name 'shrink)) - ('truncate-upto-root (+doom-modeline--buffer-file-name-truncate)) - ('truncate-all (+doom-modeline--buffer-file-name-truncate t)) - ('relative-to-project (+doom-modeline--buffer-file-name-relative)) - ('relative-from-project (+doom-modeline--buffer-file-name-relative 'include-project)) - ('file-name (propertize (file-name-nondirectory buffer-file-name) - 'face - (let ((face (or (and (buffer-modified-p) - 'doom-modeline-buffer-modified) - (and (active) - 'doom-modeline-buffer-file)))) - (when face `(:inherit ,face)))))) - 'help-echo buffer-file-truename)) - - (defun +doom-modeline--buffer-file-name-truncate (&optional truncate-tail) - "Propertized `buffer-file-name' that truncates every dir along path. - If TRUNCATE-TAIL is t also truncate the parent directory of the file." - (let ((dirs (shrink-path-prompt (file-name-directory buffer-file-truename))) - (active (active))) - (if (null dirs) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (let ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((dirname (car dirs)) - (basename (cdr dirs)) - (dir-faces (or modified-faces (if active 'doom-modeline-project-root-dir))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (concat (propertize (concat dirname - (if truncate-tail (substring basename 0 1) basename) - "/") - 'face (if dir-faces `(:inherit ,dir-faces))) - (propertize (file-name-nondirectory buffer-file-name) - 'face (if file-faces `(:inherit ,file-faces))))))))) - - (defun +doom-modeline--buffer-file-name-relative (&optional include-project) - "Propertized `buffer-file-name' showing directories relative to project's root only." - (let ((root (projectile-project-root)) - (active (active))) - (if (null root) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (let* ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified)) - (relative-dirs (file-relative-name (file-name-directory buffer-file-truename) - (if include-project (concat root "../") root))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (if (equal "./" relative-dirs) (setq relative-dirs "")) - (concat (propertize relative-dirs 'face (if relative-faces `(:inherit ,relative-faces))) - (propertize (file-name-nondirectory buffer-file-truename) - 'face (if file-faces `(:inherit ,file-faces)))))))) - - (defun +doom-modeline--buffer-file-name (truncate-project-root-parent) - "Propertized `buffer-file-name'. - If TRUNCATE-PROJECT-ROOT-PARENT is t space will be saved by truncating it down - fish-shell style. - - Example: - ~/Projects/FOSS/emacs/lisp/comint.el => ~/P/F/emacs/lisp/comint.el" - (let* ((project-root (projectile-project-root)) - (file-name-split (shrink-path-file-mixed project-root - (file-name-directory buffer-file-truename) - buffer-file-truename)) - (active (active))) - (if (null file-name-split) - (propertize "%b" 'face (if active 'doom-modeline-buffer-file)) - (pcase-let ((`(,root-path-parent ,project ,relative-path ,filename) file-name-split)) - (let ((modified-faces (if (buffer-modified-p) 'doom-modeline-buffer-modified))) - (let ((sp-faces (or modified-faces (if active 'font-lock-comment-face))) - (project-faces (or modified-faces (if active 'font-lock-string-face))) - (relative-faces (or modified-faces (if active 'doom-modeline-buffer-path))) - (file-faces (or modified-faces (if active 'doom-modeline-buffer-file)))) - (let ((sp-props `(,@(if sp-faces `(:inherit ,sp-faces)) ,@(if active '(:weight bold)))) - (project-props `(,@(if project-faces `(:inherit ,project-faces)) ,@(if active '(:weight bold)))) - (relative-props `(,@(if relative-faces `(:inherit ,relative-faces)))) - (file-props `(,@(if file-faces `(:inherit ,file-faces))))) - (concat (propertize (if truncate-project-root-parent - root-path-parent - (abbreviate-file-name project-root)) - 'face sp-props) - (propertize (concat project "/") 'face project-props) - (if relative-path (propertize relative-path 'face relative-props)) - (propertize filename 'face file-props))))))))) - - - ;; - ;; Segments - ;; - - (def-modeline-segment! buffer-default-directory - "Displays `default-directory'. This is for special buffers like the scratch - buffer where knowing the current project directory is important." - (let ((face (if (active) 'doom-modeline-buffer-path))) - (concat (if (display-graphic-p) " ") - (all-the-icons-octicon - "file-directory" - :face face - :v-adjust -0.05 - :height 1.25) - (propertize (concat " " (abbreviate-file-name default-directory)) - 'face face)))) - - ;; - (def-modeline-segment! buffer-info - "Combined information about the current buffer, including the current working - directory, the file name, and its state (modified, read-only or non-existent)." - (concat (cond (buffer-read-only - (concat (all-the-icons-octicon - "lock" - :face 'doom-modeline-warning - :v-adjust -0.05) - " ")) - ((buffer-modified-p) - (concat (all-the-icons-faicon - "floppy-o" - :face 'doom-modeline-buffer-modified - :v-adjust -0.0575) - " ")) - ((and buffer-file-name - (not (file-exists-p buffer-file-name))) - (concat (all-the-icons-octicon - "circle-slash" - :face 'doom-modeline-urgent - :v-adjust -0.05) - " ")) - ((buffer-narrowed-p) - (concat (all-the-icons-octicon - "fold" - :face 'doom-modeline-warning - :v-adjust -0.05) - " "))) - (if buffer-file-name - (+doom-modeline-buffer-file-name) - "%b"))) - - ;; - (def-modeline-segment! buffer-info-simple - "Display only the current buffer's name, but with fontification." - (propertize - "%b" - 'face (cond ((and buffer-file-name (buffer-modified-p)) - 'doom-modeline-buffer-modified) - ((active) 'doom-modeline-buffer-file)))) - - ;; - (def-modeline-segment! buffer-encoding - "Displays the encoding and eol style of the buffer the same way Atom does." - (concat (pcase (coding-system-eol-type buffer-file-coding-system) - (0 "LF ") - (1 "CRLF ") - (2 "CR ")) - (let ((sys (coding-system-plist buffer-file-coding-system))) - (cond ((memq (plist-get sys :category) '(coding-category-undecided coding-category-utf-8)) - "UTF-8") - (t (upcase (symbol-name (plist-get sys :name)))))) - " ")) - - ;; - (def-modeline-segment! major-mode - "The major mode, including process, environment and text-scale info." - (propertize - (concat (format-mode-line mode-name) - (when (stringp mode-line-process) - mode-line-process) - (and (featurep 'face-remap) - (/= text-scale-mode-amount 0) - (format " (%+d)" text-scale-mode-amount))) - 'face (if (active) 'doom-modeline-buffer-major-mode))) - - ;; - (def-modeline-segment! vcs - "Displays the current branch, colored based on its state." - (when (and vc-mode buffer-file-name) - (let* ((backend (vc-backend buffer-file-name)) - (state (vc-state buffer-file-name backend))) - (let ((face 'mode-line-inactive) - (active (active)) - (all-the-icons-default-adjust -0.1)) - (concat " " - (cond ((memq state '(edited added)) - (if active (setq face 'doom-modeline-info)) - (all-the-icons-octicon - "git-compare" - :face face - :v-adjust -0.05)) - ((eq state 'needs-merge) - (if active (setq face 'doom-modeline-info)) - (all-the-icons-octicon "git-merge" :face face)) - ((eq state 'needs-update) - (if active (setq face 'doom-modeline-warning)) - (all-the-icons-octicon "arrow-down" :face face)) - ((memq state '(removed conflict unregistered)) - (if active (setq face 'doom-modeline-urgent)) - (all-the-icons-octicon "alert" :face face)) - (t - (if active (setq face 'font-lock-doc-face)) - (all-the-icons-octicon - "git-compare" - :face face - :v-adjust -0.05))) - " " - (propertize (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2)) - 'face (if active face)) - " "))))) - - ;; - (defun +doom-ml-icon (icon &optional text face voffset) - "Displays an octicon ICON with FACE, followed by TEXT. Uses - `all-the-icons-octicon' to fetch the icon." - (concat (if vc-mode " " " ") - (when icon - (concat - (all-the-icons-material icon :face face :height 1.1 :v-adjust (or voffset -0.2)) - (if text +doom-modeline-vspc))) - (when text - (propertize text 'face face)) - (if vc-mode " " " "))) - - (def-modeline-segment! flycheck - "Displays color-coded flycheck error status in the current buffer with pretty - icons." - (when (boundp 'flycheck-last-status-change) - (pcase flycheck-last-status-change - ('finished (if flycheck-current-errors - (let-alist (flycheck-count-errors flycheck-current-errors) - (let ((sum (+ (or .error 0) (or .warning 0)))) - (+doom-ml-icon "do_not_disturb_alt" - (number-to-string sum) - (if .error 'doom-modeline-urgent 'doom-modeline-warning) - -0.25))) - (+doom-ml-icon "check" nil 'doom-modeline-info))) - ('running (+doom-ml-icon "access_time" nil 'font-lock-doc-face -0.25)) - ('no-checker (+doom-ml-icon "sim_card_alert" "-" 'font-lock-doc-face)) - ('errored (+doom-ml-icon "sim_card_alert" "Error" 'doom-modeline-urgent)) - ('interrupted (+doom-ml-icon "pause" "Interrupted" 'font-lock-doc-face))))) - ;; ('interrupted (+doom-ml-icon "x" "Interrupted" 'font-lock-doc-face))))) - - ;; - (defsubst doom-column (pos) - (save-excursion (goto-char pos) - (current-column))) - - (def-modeline-segment! selection-info - "Information about the current selection, such as how many characters and - lines are selected, or the NxM dimensions of a block selection." - (when (and (active) (or mark-active (eq evil-state 'visual))) - (let ((reg-beg (region-beginning)) - (reg-end (region-end))) - (propertize - (let ((lines (count-lines reg-beg (min (1+ reg-end) (point-max))))) - (cond ((or (bound-and-true-p rectangle-mark-mode) - (eq 'block evil-visual-selection)) - (let ((cols (abs (- (doom-column reg-end) - (doom-column reg-beg))))) - (format "%dx%dB" lines cols))) - ((eq 'line evil-visual-selection) - (format "%dL" lines)) - ((> lines 1) - (format "%dC %dL" (- (1+ reg-end) reg-beg) lines)) - (t - (format "%dC" (- (1+ reg-end) reg-beg))))) - 'face 'doom-modeline-highlight)))) - - - ;; - (defun +doom-modeline--macro-recording () - "Display current Emacs or evil macro being recorded." - (when (and (active) (or defining-kbd-macro executing-kbd-macro)) - (let ((sep (propertize " " 'face 'doom-modeline-panel))) - (concat sep - (propertize (if (bound-and-true-p evil-this-macro) - (char-to-string evil-this-macro) - "Macro") - 'face 'doom-modeline-panel) - sep - (all-the-icons-octicon "triangle-right" - :face 'doom-modeline-panel - :v-adjust -0.05) - sep)))) - - (defsubst +doom-modeline--anzu () - "Show the match index and total number thereof. Requires `anzu', also - `evil-anzu' if using `evil-mode' for compatibility with `evil-search'." - (when (and anzu--state (not iedit-mode)) - (propertize - (let ((here anzu--current-position) - (total anzu--total-matched)) - (cond ((eq anzu--state 'replace-query) - (format " %d replace " total)) - ((eq anzu--state 'replace) - (format " %d/%d " here total)) - (anzu--overflow-p - (format " %s+ " total)) - (t - (format " %s/%d " here total)))) - 'face (if (active) 'doom-modeline-panel)))) - - (defsubst +doom-modeline--evil-substitute () - "Show number of matches for evil-ex substitutions and highlights in real time." - (when (and evil-mode - (or (assq 'evil-ex-substitute evil-ex-active-highlights-alist) - (assq 'evil-ex-global-match evil-ex-active-highlights-alist) - (assq 'evil-ex-buffer-match evil-ex-active-highlights-alist))) - (propertize - (let ((range (if evil-ex-range - (cons (car evil-ex-range) (cadr evil-ex-range)) - (cons (line-beginning-position) (line-end-position)))) - (pattern (car-safe (evil-delimited-arguments evil-ex-argument 2)))) - (if pattern - (format " %s matches " (how-many pattern (car range) (cdr range))) - " - ")) - 'face (if (active) 'doom-modeline-panel)))) - - (defun doom-themes--overlay-sort (a b) - (< (overlay-start a) (overlay-start b))) - - (defsubst +doom-modeline--iedit () - "Show the number of iedit regions matches + what match you're on." - (when (and iedit-mode iedit-occurrences-overlays) - (propertize - (let ((this-oc (or (let ((inhibit-message t)) - (iedit-find-current-occurrence-overlay)) - (progn (iedit-prev-occurrence) - (iedit-find-current-occurrence-overlay)))) - (length (length iedit-occurrences-overlays))) - (format " %s/%d " - (if this-oc - (- length - (length (memq this-oc (sort (append iedit-occurrences-overlays nil) - #'doom-themes--overlay-sort))) - -1) - "-") - length)) - 'face (if (active) 'doom-modeline-panel)))) - - (def-modeline-segment! matches - "Displays: 1. the currently recording macro, 2. A current/total for the - current search term (with anzu), 3. The number of substitutions being conducted - with `evil-ex-substitute', and/or 4. The number of active `iedit' regions." - (let ((meta (concat (+doom-modeline--macro-recording) - (+doom-modeline--anzu) - (+doom-modeline--evil-substitute) - (+doom-modeline--iedit)))) - (or (and (not (equal meta "")) meta) - (if buffer-file-name " %I ")))) - - ;; TODO Include other information - (def-modeline-segment! media-info - "Metadata regarding the current file, such as dimensions for images." - (cond ((eq major-mode 'image-mode) - (cl-destructuring-bind (width . height) - (image-size (image-get-display-property) :pixels) - (format " %dx%d " width height))))) - - (def-modeline-segment! bar - "The bar regulates the height of the mode-line in GUI Emacs. - Returns \"\" to not break --no-window-system." - (if (display-graphic-p) - (+doom-modeline--make-xpm - (face-background (if (active) - 'doom-modeline-bar - 'doom-modeline-inactive-bar) - nil t) - +doom-modeline-height - +doom-modeline-bar-width) - "")) - - - ;; - ;; Mode lines - ;; - - (def-modeline! main - (bar matches " " buffer-info " %l:%c %p " selection-info) - (buffer-encoding major-mode vcs flycheck)) - - (def-modeline! minimal - (bar matches " " buffer-info) - (media-info major-mode)) - - (def-modeline! special - (bar matches " " buffer-info-simple " %l:%c %p " selection-info) - (buffer-encoding major-mode flycheck)) - - (def-modeline! project - (bar buffer-default-directory) - (major-mode)) - - (def-modeline! media - (bar " %b ") - (media-info major-mode)) - - - ;; - ;; Hooks - ;; - - (defun +doom-modeline|init () - "Set the default modeline." - (doom-set-modeline 'main t) - - ;; This scratch buffer is already created and doesn't get a modeline. For the - ;; love of Emacs, someone give the man a modeline! - (with-current-buffer "*scratch*" - (doom-set-modeline 'main))) - - (defun +doom-modeline|set-special-modeline () - (doom-set-modeline 'special)) - - (defun +doom-modeline|set-media-modeline () - (doom-set-modeline 'media)) - - (defun +doom-modeline|set-project-modeline () - (doom-set-modeline 'project)) - - - ;; - ;; Bootstrap - ;; - - (add-hook 'emacs-startup-hook #'+doom-modeline|init) - ;; (add-hook 'doom-scratch-buffer-hook #'+doom-modeline|set-special-modeline) - ;; (add-hook '+doom-dashboard-mode-hook #'+doom-modeline|set-project-modeline) - - (add-hook 'image-mode-hook #'+doom-modeline|set-media-modeline) - (add-hook 'org-src-mode-hook #'+doom-modeline|set-special-modeline) - (add-hook 'circe-mode-hook #'+doom-modeline|set-special-modeline) +*** Doom Modeline +#+BEGIN_SRC emacs-lisp :results silent + (require 'doom-modeline) + (doom-modeline-mode 1) - #+END_SRC + + ;; How tall the mode-line should be (only respected in GUI Emacs). + (setq doom-modeline-height 35) + + ;; How wide the mode-line bar should be (only respected in GUI Emacs). + (setq doom-modeline-bar-width 4) + + ;; Determines the style used by `doom-modeline-buffer-file-name'. + ;; + ;; Given ~/Projects/FOSS/emacs/lisp/comint.el + ;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el + ;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el + ;; truncate-with-project => emacs/l/comint.el + ;; truncate-except-project => ~/P/F/emacs/l/comint.el + ;; truncate-upto-root => ~/P/F/e/lisp/comint.el + ;; truncate-all => ~/P/F/e/l/comint.el + ;; relative-from-project => emacs/lisp/comint.el + ;; relative-to-project => lisp/comint.el + ;; file-name => comint.el + ;; buffer-name => comint.el<2> (uniquify buffer name) + ;; + ;; If you are expereicing the laggy issue, especially while editing remote files + ;; with tramp, please try `file-name' style. + ;; Please refer to https://github.com/bbatsov/projectile/issues/657. + (setq doom-modeline-buffer-file-name-style 'truncate-upto-project) + + ;; What executable of Python will be used (if nil nothing will be showed). + (setq doom-modeline-python-executable "python") + + ;; Whether show `all-the-icons' or not (if nil nothing will be showed). + (setq doom-modeline-icon t) + + ;; Whether show the icon for major mode. It respects `doom-modeline-icon'. + (setq doom-modeline-major-mode-icon t) + + ;; Display color icons for `major-mode'. It respects `all-the-icons-color-icons'. + (setq doom-modeline-major-mode-color-icon nil) + + ;; Whether display minor modes or not. Non-nil to display in mode-line. + (setq doom-modeline-minor-modes nil) + + ;; If non-nil, a word count will be added to the selection-info modeline segment. + (setq doom-modeline-enable-word-count nil) + + ;; If non-nil, only display one number for checker information if applicable. + (setq doom-modeline-checker-simple-format t) + + ;; Whether display perspective name or not. Non-nil to display in mode-line. + (setq doom-modeline-persp-name t) + + ;; Whether display `lsp' state or not. Non-nil to display in mode-line. + (setq doom-modeline-lsp t) + + ;; Whether display github notifications or not. Requires `ghub` package. + (setq doom-modeline-github nil) + + ;; The interval of checking github. + (setq doom-modeline-github-interval (* 30 60)) + + ;; Whether display environment version or not. + (setq doom-modeline-env-version t) + + ;; Whether display mu4e notifications or not. Requires `mu4e-alert' package. + (setq doom-modeline-mu4e t) +#+END_SRC