diff --git a/init.el b/init.el index f6ed814..0653796 100644 --- a/init.el +++ b/init.el @@ -45,9 +45,15 @@ ;; "C-x t" #'beginning-of-buffer ;; "C-x e" #'end-of-buffer ) - ;; C-h deletes backward - see https://idiomdrottning.org/bad-emacs-defaults + ;; ;; C-h deletes backward - see https://idiomdrottning.org/bad-emacs-defaults (global-set-key (kbd "C-h") 'delete-backward-char) (keyboard-translate ?\C-h ?\C-?) + ;; Faces + (dolist (face '(line-number + line-number-major-tick + line-number-minor-tick + line-number-current-line)) + (:face face '((t (:inherit fixed-pitch))))) ;; Hooks (add-hook 'prog-mode-hook #'turn-on-auto-fill) (add-hook 'prog-mode-hook #'font-lock-todo-insinuate) @@ -71,6 +77,9 @@ (:with-mode authinfo-mode (:local-set truncate-lines t))) +(setup (:require autoinsert) + (auto-insert-mode +1)) + (setup (:require autoinsert) (setf (alist-get "\\.scm" auto-insert-alist nil nil #'equal) '(insert "#!/bin/sh\n#| -*- scheme -*-\nexec csi -s $0 \"$@\"\n|#\n")) @@ -91,7 +100,8 @@ (dolist (var '(safe-local-variable-values warning-suppress-types)) (add-to-list '+custom-variable-allowlist var)) - (+custom-load-ignoring-most-customizations) + (+ensure-after-init + (+custom-load-ignoring-most-customizations)) (advice-add #'custom-buffer-create-internal :after #'+cus-edit-expand-widgets) (:with-mode Custom-mode (:local-set imenu-generic-expression +cus-edit-imenu-generic-expression))) @@ -107,7 +117,7 @@ pulse-delay 0.5 pulse-iterations 1) (dolist (command '(+ace-window-or-switch-buffer - pop-mark pop-globl-mark)) + pop-mark pop-global-mark)) (add-to-list '+pulse-location-commands command)) (+ensure-after-init #'+pulse-location-mode)) @@ -125,9 +135,9 @@ (setup +key (+ensure-after-init #'+key-global-mode)) -;;(setup _work -;; (+with-ensure-after-init -;; (require '_work))) +(setup _work + (+with-ensure-after-init + (require '_work))) (setup abbrev (:option abbrev-file-name (sync/ "abbrev.el") @@ -485,7 +495,7 @@ (setup notmuch (:load-from "~/usr/share/emacs/site-lisp/") - (:load-after org-contacts) + (:load-after bbdb) (:also-load +notmuch +message) (+define-dir notmuch/ (sync/ "emacs/notmuch") "Notmuch configuration and data.") @@ -529,7 +539,9 @@ (list :name "drafts" :query "tag:draft" :key "d") (list :name "all mail" :query "*" :key "a")))) (:+leader "m" #'+notmuch-goto "C-m" #'+notmuch-goto - "n" #'notmuch "C-n" #'notmuch)) + "n" #'notmuch "C-n" #'notmuch) + ;; For `focus' + (put 'notmuch-message 'bounds-of-thing-at-point 'notmuch-show-message-extent)) (setup org ;; Plain org with the `setup' form for sorting, but I install with straight. @@ -552,6 +564,7 @@ load-path)) (:also-load +org) (:option org-adapt-indentation nil + org-auto-align-tags t org-archive-mark-done t org-catch-invisible-edits 'show-and-error org-clock-clocked-in-display 'mode-line @@ -575,6 +588,7 @@ org-imenu-depth 3 org-indent-indentation-per-level 0 org-indent-mode-turns-on-hiding-stars nil + org-insert-heading-respect-content t org-list-demote-modify-bullet '(("-" . "+") ("+" . "-")) org-log-done 'time @@ -595,7 +609,7 @@ org-src-window-setup 'current-window org-startup-truncated nil org-startup-with-inline-images t - org-tags-column (- (- fill-column (length org-ellipsis))) + org-tags-column 1 ;; (- (- fill-column (length org-ellipsis))) org-todo-keywords '((sequence "TODO(t)" "WAIT(w@/!)" "ONGOING(o@)" "|" "DONE(d!)") (sequence "|" "CANCELED(k@)") @@ -621,13 +635,25 @@ "C-c l" #'org-store-link) (:hook #'variable-pitch-mode #'turn-off-auto-fill - #'org-indent-mode) + #'org-indent-mode + #'prettify-symbols-mode + ;; TODO: This is only the beginning of a larger idea: I really want the + ;; "buffer stats" section of the mode-line to change depending on the + ;; mode. So like, org-mode would be a word count (maybe other text + ;; modes?), lui-modes could be .... something? etc. + (defun turn-off-column-number-mode () (setq-local column-number-mode nil))) + (:local-set prettify-symbols-alist '(("DEADLINE:" . ?⏰) + ("SCHEDULED:" . ?📅) + ("CLOSED:" ?✅)) + ;;+modeline-position-function #'+org-count-words-stupidly + ) (:local-hook user-save-hook #'+org-before-save@prettify-buffer) (advice-add #'org-delete-backward-char :override #'+org-delete-backward-char) ;; (define-advice org-open-at-point (:around (fn &rest r) open-external) ;; "Open links from org externally." ;; (let ((browse-url-browser-function browse-url-secondary-browser-function)) ;; (apply fn r))) + ;; (add-to-list '+custom-variable-allowlist 'org-agenda-files) (with-eval-after-load 'org (setf (alist-get "\\.x?html?\\'" org-file-apps nil nil #'equal) #'+org-open-html) @@ -653,11 +679,10 @@ (0 ;; (progn (compose-region (match-beginning 1) (match-end 1) "→") 'fixed-pitch) 'fixed-pitch t)) ;; Fancy numbered lists (well, monospaced) - ("^[ \t]*\\(\\(?:[0-9]+\\|[A-Za-z]\\)[.)]\\) " 0 'fixed-pitch t))) - ;; Make nobreak-space fixed-pitch as well, for better alignment (is this the - ;; best way to do this? probably not!) - (:face org-indent ((t (:inherit (fixed-pitch)))) - nobreak-space ((t (:inherit (fixed-pitch))))) + ("^[ \t]*\\(\\(?:[0-9]+\\|[A-Za-z]\\)[.)]\\) " 0 'fixed-pitch t) + ;; Make leading org-heading stars fixed-pitch + ("^\*+ " 0 'fixed-pitch t) + )) (with-eval-after-load 'form-feed ;; Horizontal lines (font-lock-add-keywords @@ -672,6 +697,13 @@ (:option org-agenda-skip-deadline-if-done t org-agenda-skip-scheduled-if-done t org-agenda-span 10 + org-agenda-block-separator ?─ + org-agenda-time-grid + '((daily today require-timed) + (800 1000 1200 1400 1600 1800 2000) + " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄") + org-agenda-current-time-string + "← now ─────────────────────────────────────────────────" org-agenda-include-diary nil ; I use the org-diary features org-agenda-todo-ignore-deadlines 'near org-agenda-todo-ignore-scheduled 'future @@ -679,12 +711,12 @@ org-deadline-warning-days 0 org-agenda-show-future-repeats 'next org-agenda-window-setup 'current-window) + (unless after-init-time + (:option org-agenda-files (list (sync/ "org/")))) (dolist (var '(org-agenda-files org-agenda-file-regexp org-agenda-templates)) (add-to-list '+custom-variable-allowlist var)) - (with-eval-after-load 'org - (add-to-list 'org-agenda-files (sync/ "org/" t))) (:+leader "a" #'org-agenda "C-a" #'org-agenda) (:hook #'hl-line-mode) (add-hook 'org-agenda-after-show-hook 'org-narrow-to-subtree)) @@ -770,6 +802,9 @@ (:option password-cache t password-cache-expiry (* 60 60))) +(setup prettify-symbols-mode + (:option prettify-symbols-unprettify-at-point t)) + (setup prog (:local-set comment-auto-fill-only-comments t) (:hook #'prettify-symbols-mode)) @@ -815,7 +850,7 @@ tab-bar-format-tabs tab-bar-separator tab-bar-format-add-tab - tab-bar-format-align-right + +tab-bar-format-align-right ;;+tab-bar-misc-info +tab-bar-org-clock +tab-bar-bongo @@ -852,9 +887,10 @@ They are completed by \"M-x TAB\" only in Tramp debug buffers." (:require +ace-window) (:option aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l) aw-display-mode-overlay nil - aw-scope 'frame) + aw-scope 'frame + aw-minibuffer-flag t) (:+key "M-o" #'+ace-window-or-switch-buffer) - (:face aw-mode-line-face ((t (:foreground "red")))) + (:face 'aw-mode-line-face '((t (:foreground "red")))) (+ace-window-display-mode +1)) (setup (:straight (actually-selected-window @@ -902,8 +938,8 @@ They are completed by \"M-x TAB\" only in Tramp debug buffers." '(avy-lead-face avy-lead-face-1 avy-lead-face-1 avy-lead-face-1 avy-lead-face-1 avy-lead-face-1 avy-lead-face-1)) - (:face avy-background-face - ((t (:foreground "#888888")))) + (:face 'avy-background-face + '((t (:foreground "#888888")))) (:+key "M-j" #'avy-goto-char-timer) (:bind-into isearch "M-j" #'avy-isearch) @@ -1126,11 +1162,11 @@ They are completed by \"M-x TAB\" only in Tramp debug buffers." (0x0-upload-text (0x0--choose-server))) (current-kill 0))) (add-to-list '+pulse-location-commands #'lui-track-jump-to-indicator) - (:face lui-track-bar ((t (:height 10 - :underline (:color foreground-color - :style line - :position line) - :extend t :inhert (default))))) + (:face 'lui-track-bar '((t ( :height 10 + :underline ( :color foreground-color + :style line + :position line) + :extend t :inhert (default))))) (:hook #'visual-line-mode #'enable-lui-track #'visual-fill-column-mode @@ -1305,9 +1341,9 @@ They are completed by \"M-x TAB\" only in Tramp debug buffers." (:hook #'turn-off-+key-mode) (:option crossword-save-path (sync/ "emacs/crosswords/" t) crossword-empty-position-char "=") - (:face crossword-grid-face ((t :inherit 'font-lock-string-face)) - crossword-current-face ((t :inherit 'highlight)) - crossword-other-dir-face ((t :inherit 'font-lock-keyword-face)))) + (:face 'crossword-grid-face '((t :inherit 'font-lock-string-face)) + 'crossword-current-face '((t :inherit 'highlight)) + 'crossword-other-dir-face '((t :inherit 'font-lock-keyword-face)))) (setup (:straight crux) ;; yes it's silly I have an addon to this addon. @@ -1531,7 +1567,7 @@ See also `crux-reopen-as-root-mode'." (setup (:straight (filldent :host github :repo "duckwork/filldent.el")) - (:+key "M-q" #'filldent-dwim)) + (:+key "M-q" #'filldent-unfill-toggle)) (setup (:straight (flymake-collection :host github @@ -1550,6 +1586,21 @@ See also `crux-reopen-as-root-mode'." (with-eval-after-load 'vertico-multiform (setf (alist-get 'flyspell vertico-multiform-categories) nil))) +(setup (:straight focus) + (:require) + (add-hook 'modus-themes-after-load-theme-hook + (defun focus-update@after-modus-load () + (modus-themes-with-colors + (:face 'focus-unfocused `((t ( :foreground ,fg-inactive + :background ,bg-inactive + :weight normal + :slant normal + :extend t))))))) + ;; XXX: This doesn't work, because notmuch overlays shit on the buffer + (setf (alist-get 'notmuch-show-mode focus-mode-to-thing) + 'notmuch-message) + (:hook-into notmuch-show-mode)) + (setup (:straight-when (forge :host github :repo "magit/forge") (eq system-type 'gnu/linux)) @@ -1582,7 +1633,9 @@ See also `crux-reopen-as-root-mode'." scheme-complete) (:require +chicken) (setf (alist-get "\\.scm\\'" auto-mode-alist nil nil #'string=) - 'scheme-mode)) + 'scheme-mode) + (setf (alist-get "\\.scm\\'" auto-mode-alist nil nil #'string=) + '(insert "#!/bin/sh\n#| -*- scheme -*-\nexec csi -s $0 \"$@\"\n|#\n"))) (setup (:straight (git-modes :host github :repo "magit/git-modes")) @@ -1674,9 +1727,9 @@ See also `crux-reopen-as-root-mode'." :host nil))) (:also-load +jabber) (:option jabber-account-list '(("acdw@hmm.st")) - jabber-groupchat-buffer-format "xmpp:%n" - jabber-chat-buffer-format "xmpp:%n" - jabber-muc-private-buffer-format "xmpp:%n(%g)" + jabber-groupchat-buffer-format "X:%n" + jabber-chat-buffer-format "X:%n" + jabber-muc-private-buffer-format "X:%n(%g)" jabber-activity-show-p #'ignore jabber-muc-decorate-presence-patterns '(("\\( enters the room ([^)]+)\\| has left the chatroom\\)$") @@ -1804,7 +1857,7 @@ See also `crux-reopen-as-root-mode'." :fork (:host github :repo "duckwork/mode-line-bell" :branch "remap-face"))) ;; This is still, annoyingly, not quite working right. - (:face mode-line-bell ((t (:inherit mode-line-highlight)))) + (:face 'mode-line-bell '((t (:inherit mode-line-highlight)))) (:option mode-line-bell-flash-time 0.1) (mode-line-bell-mode +1)) @@ -1812,11 +1865,10 @@ See also `crux-reopen-as-root-mode'." :host gitlab :repo "protesilaos/modus-themes")) (require 'modus-themes (.etc "straight/build/modus-themes/modus-themes")) - (:also-load dawn) (:option modus-themes-mixed-fonts t modus-themes-bold-constructs t modus-themes-italic-constructs t - modus-themes-headings '((t . (background regular rainbow)))) + modus-themes-headings '((t t))) (dotimes (facen-1 8) (let ((facen (1+ facen-1))) (custom-set-faces @@ -1825,9 +1877,16 @@ See also `crux-reopen-as-root-mode'." (,(intern (format "modus-themes-heading-%s" facen)) fixed-pitch)) :now))))) - (:face modus-themes-tab-active ((t :bold nil)) - modus-themes-tab-inactive ((t :italic t))) + (:face 'modus-themes-tab-active '((t :bold nil)) + 'modus-themes-tab-inactive '((t :italic t))) + ;; Fix a "nil is not a Modus theme" error + ;; XXX: Need to register a bug report + (define-advice modus-themes--current-theme (:around (fn &rest r)) + (or (apply fn r) + 'modus-operandi)) + + ;; This needs to be after the themes are loaded, I think. (add-hook 'modus-themes-after-load-theme-hook (defun +modus-themes-mostly-monochrome () "Set up mdous-themes to be mostly monochrome." @@ -1861,6 +1920,7 @@ See also `crux-reopen-as-root-mode'." :foreground ,fg-header :background ,yellow-intense-bg))))))) + (require 'dawn) (dawn-schedule #'modus-themes-load-operandi #'modus-themes-load-vivendi)) @@ -1930,9 +1990,19 @@ See also `crux-reopen-as-root-mode'." (defun org-mime-setup@org-mode () (local-set-key (kbd "C-c M-o") 'org-mime-org-buffer-htmlize)))) -(setup (:straight org-sticky-header) - ;; (:hook-into org-mode) - ) +(setup (:straight org-modern) + (:option org-modern-hide-stars nil + org-modern-star nil + org-modern-list nil) + (:face 'org-modern-label '((t ( :height 1.0 + :weight regular + :underline nil + :inherit fixed-pitch)))) + (advice-add 'org-modern--update-label-face :override #'ignore) + (:hook-into org-mode)) + +(setup (:straight org-sticky-header) (:quit) + (:hook-into org-mode)) (setup (:straight (org-taskwise :host github @@ -2018,6 +2088,8 @@ See also `crux-reopen-as-root-mode'." (setup (:straight rainbow-mode) (:hook-into prog-mode)) +(setup (:straight restart-emacs)) + (setup (:straight (shell-command+ :host nil :repo "https://git.sr.ht/~pkal/shell-command-plus")) @@ -2037,14 +2109,10 @@ See also `crux-reopen-as-root-mode'." (readonly . "=") (modified . "+") (t . "-")) - ;; '((ephemeral . "🥞") - ;; (special . "🥐") - ;; (readonly . "🦞") - ;; (modified . "🥪") - ;; (t . "🍞")) - +modeline-minions-icon ";" - simple-modeline-segments + +modeline-buffer-name-max-length 0.35) + ;; Segments + (:option simple-modeline-segments `(( ; left +modeline-ace-window-display +modeline-modified @@ -2070,10 +2138,7 @@ See also `crux-reopen-as-root-mode'." +modeline-narrowed) ",") +modeline-input-method - ,(+modeline-concat - '(+modeline-region - +modeline-line-column - +modeline-file-percentage)) + +modeline-position ))) (simple-modeline-mode +1)) @@ -2201,10 +2266,7 @@ See also `crux-reopen-as-root-mode'." (:require) (:hook-into text-mode prog-mode)) -(setup (:straight unfill)) - -(setup (:straight valign) - (:hook-into org-mode)) +(setup (:straight unfill)) ;; XXX: Is this necessary with changes to filldent? (setup (:straight valign) (:quit "Doesn't work with narrowed tables.") (:option valign-fancy-bar t) @@ -2325,7 +2387,9 @@ See also `crux-reopen-as-root-mode'." "https://invidious.snopyta.org")) (:bind "y" #'+ytdious-watch)) -(setup (:straight zoom-frm)) +(setup (:straight zoom-frm) + (:+key "M-+" #'zoom-frm-in + "M-_" #'zoom-frm-out)) (setup (:straight zzz-to-char) (:require +zzz-to-char) diff --git a/lisp/+ace-window.el b/lisp/+ace-window.el index fca27d9..9e631a2 100644 --- a/lisp/+ace-window.el +++ b/lisp/+ace-window.el @@ -10,15 +10,21 @@ ;; This is stolen from ace-window.el but with the mode-line stuff ripped out. :global t (if +ace-window-display-mode - (progn + (progn ; Enable (aw-update) (force-mode-line-update t) (add-hook 'window-configuration-change-hook 'aw-update) (add-hook 'after-make-frame-functions 'aw--after-make-frame t) (advice-add 'aw--lead-overlay :override 'ignore)) - (remove-hook 'window-configuration-change-hook 'aw-update) - (remove-hook 'after-make-frame-functions 'aw--after-make-frame) - (advice-remove 'aw--lead-overlay 'ignore))) + (progn ; Disable + (remove-hook 'window-configuration-change-hook 'aw-update) + (remove-hook 'after-make-frame-functions 'aw--after-make-frame) + (advice-remove 'aw--lead-overlay 'ignore)))) + +;; (defun +ace-window--mode-line-hint (path leaf) +;; (let ((wnd (cdr leaf))) +;; (with-selected-window wnd +;; ()))) ;;;###autoload (defun +ace-window-or-switch-buffer (arg) @@ -30,8 +36,5 @@ Switch to most recent buffer otherwise." (switch-to-buffer nil) (ace-window arg))) -(defun +ace-window@disable-overlay (_fn &rest _args) - "ADVICE for FN `aw--lead-overlay' (and ARGS) to not show overlays.") - (provide '+ace-window) ;;; +ace-window.el ends here diff --git a/lisp/+modeline.el b/lisp/+modeline.el index 3cc8806..3a922e3 100644 --- a/lisp/+modeline.el +++ b/lisp/+modeline.el @@ -32,7 +32,7 @@ functions), though it can also contain cons cells of the form (SEGMENT . PREDICATE). Segments are separated from each other using SEPARATOR, which -defaults to a \" \". space. Only segments that evaluate to a +defaults to a \" \". Only segments that evaluate to a non-trivial string (that is, a string not equal to \"\") will be separated, for a cleaner look. @@ -42,18 +42,18 @@ This function makes a lambda, so you can throw it straight into (lambda () (apply #'concat (let (this-sep result-list) - (dolist (segment segments) - (push (funcall (or (car-safe segment) segment) - this-sep) - result-list) - (if (or (cdr-safe segment) - (and (car result-list) - (not (equal (car result-list) "")))) - (setq this-sep separator) - (setq this-sep nil))) - (unless (seq-some #'null result-list) - (push +modeline-default-spacer result-list)) - (nreverse result-list))))) + (dolist (segment segments) + (push (funcall (or (car-safe segment) segment) + this-sep) + result-list) + (if (or (cdr-safe segment) + (and (car result-list) + (not (equal (car result-list) "")))) + (setq this-sep separator) + (setq this-sep nil))) + (unless (seq-some #'null result-list) + (push +modeline-default-spacer result-list)) + (nreverse result-list))))) ;;; Modeline segments @@ -62,14 +62,36 @@ This function makes a lambda, so you can throw it straight into (when string (string-replace "%" "%%" string))) +(defcustom +modeline-buffer-name-max-length 0 + "Maximum length of `+modeline-buffer-name'. +If > 0 and < 1, use that portion of the window's width. If > 1, +use that many characters. If anything else, don't limit. If the +buffer name is longer than the max length, it will be shortened +and appended with `truncate-string-ellipsis'." + :type '(choice (const :tag "No maximum length" 0) + (natnum :tag "Number of characters") + (float :tag "Fraction of window's width"))) + (defun +modeline-buffer-name (&optional spacer) ; gonsie "Display the buffer name." (let ((bufname (string-trim (string-replace "%" "" (buffer-name))))) (concat (or spacer +modeline-default-spacer) - (propertize bufname - 'help-echo (or (buffer-file-name) - (buffer-name)) - 'mouse-face 'mode-line-highlight)))) + (propertize (cond + ((ignore-errors + (and (> +modeline-buffer-name-max-length 0) + (< +modeline-buffer-name-max-length 1))) + (truncate-string-to-width bufname + (* (window-total-width) +modeline-buffer-name-max-length) + nil nil t)) + ((ignore-errors + (> +modeline-buffer-name-max-length 1)) + (truncate-string-to-width bufname + +modeline-buffer-name-max-length + nil nil t)) + (t bufname)) + 'help-echo (or (buffer-file-name) + (buffer-name)) + 'mouse-face 'mode-line-highlight)))) (defcustom +modeline-minions-icon "&" "The \"icon\" for `+modeline-minions' button." @@ -188,20 +210,49 @@ The order of elements matters: whichever one matches first is applied." "Toggle the percentage display in the mode line (File Percentage Mode)." :init-value t :global t :group 'mode-line) +(defun +modeline--percentage () + "Return point's progress through current file as a percentage." + (let ((tot (count-screen-lines (point-min) (point-max) :ignore-invisible))) + (floor (* 100 (/ (float (line-number-at-pos)) tot))))) + +(defun +modeline--buffer-contained-in-window-p () + "Whether the buffer is totally contained within its window." + (let ((window-min (save-excursion (move-to-window-line 0) (point))) + (window-max (save-excursion (move-to-window-line -1) (point)))) + (and (<= window-min (point-min)) + (>= window-max (point-max))))) + (defun +modeline-file-percentage (&optional spacer) "Display the position in the current file." (when file-percentage-mode - (let* ((tot (count-lines (point-min) (point-max) :ignore-invisible)) - (perc (/ (* 100 (line-number-at-pos)) tot)) - (window-min (save-excursion (move-to-window-line 0) - (point))) - (window-max (save-excursion (move-to-window-line -1) - (point)))) + ;; (let ((perc (+modeline--percentage))) + ;; (propertize (concat (or spacer +modeline-default-spacer) + ;; (cond + ;; ((+modeline--buffer-contained-in-window-p) "All") + ;; ((= (line-number-at-pos) (line-number-at-pos (point-min))) "Top") + ;; ((= (line-number-at-pos) (line-number-at-pos (point-max))) "Bot") + ;; ;; Why the 10 %s? Not sure. `format' knocks them + ;; ;; down to 5, then `format-mode-line' kills all but + ;; ;; two. If I use only 8, the margin is much too + ;; ;; large. Something else is obviously going on, but + ;; ;; I'm at a loss as to what it could be. + ;; (t (format "%d%%%%%%%%%%" perc)))) + ;; ;; TODO: add scroll-up and scroll-down bindings. + ;; )) + (let ((perc (format-mode-line '(-3 "%p")))) + (concat (or spacer +modeline-default-spacer) + perc + (unless (seq-some (lambda (s) (string= perc s)) + '("Top" "Bot" "All")) + "%%%%"))))) + +(defun +modeline-file-percentage-icon (&optional spacer) + "Display the position in the current file as an icon." + (when file-percentage-mode + (let ((perc (+modeline--percentage))) (propertize (concat (or spacer +modeline-default-spacer) (cond - ((and (<= window-min (point-min)) - (>= window-max (point-max))) - "█") + ((+modeline--buffer-contained-in-window-p) "⏹") ((= perc 0) "▇") ((< perc 20) "▆") ((< perc 40) "▅") @@ -231,24 +282,37 @@ The order of elements matters: whichever one matches first is applied." 'font-lock-face 'font-lock-variable-name-face)) "")) +(defun +modeline-line (&optional spacer) + (when line-number-mode + (concat (or spacer +modeline-default-spacer) "%2l"))) + +(defun +modeline-column (&optional spacer) + (when column-number-mode + (concat (or spacer +modeline-default-spacer) + (if column-number-indicator-zero-based "%2c" "%2C")))) + (defun +modeline-line-column (&optional spacer) ; adapted from `simple-modeline' "Display the current cursor line and column depending on modes." - (let ((sep "|") (before "") (after "") - (line-fmt (if line-number-mode "%2l" "")) - (col-fmt (if column-number-mode - (if column-number-indicator-zero-based - "%2c" - "%2C") - ""))) - (concat (or spacer +modeline-default-spacer) - before line-fmt sep col-fmt after))) + (funcall (+modeline-concat '(+modeline-line + +modeline-column) + "|"))) + +(defcustom +modeline-position-function nil + "Function to use instead of `+modeline-position' in modeline." + :type '(choice (const :tag "None" nil) + function) + :local t) (defun +modeline-position (&optional _) "Display the current cursor position. -See `line-number-mode', `column-number-mode', `file-percentage-mode'" - (append (+modeline-line-column) - (+modeline-region) - (+modeline-file-percentage))) +See `line-number-mode', `column-number-mode', and +`file-percentage-mode'. If `+modeline-position-function' is set +to a function in the current buffer, call that function instead." + (funcall (if +modeline-position-function + +modeline-position-function + (+modeline-concat '(+modeline-region + +modeline-line-column + +modeline-file-percentage))))) (defun +modeline-vc (&optional spacer) "Display the version control branch of the current buffer in the modeline." diff --git a/lisp/+org.el b/lisp/+org.el index 2a57fe2..e39bdc1 100644 --- a/lisp/+org.el +++ b/lisp/+org.el @@ -338,6 +338,7 @@ Return as a list." (save-mark-and-excursion (mark-whole-buffer) ;;(org-fill-paragraph nil t) + (+org-unsmartify) (+org-fix-blank-lines t) (org-align-tags t)))) diff --git a/lisp/+setup.el b/lisp/+setup.el index 7c658b6..02d2f09 100644 --- a/lisp/+setup.el +++ b/lisp/+setup.el @@ -35,7 +35,7 @@ Good for commenting.") (setup-define :face (lambda (face spec) - `(custom-set-faces '(,face ,spec 'now "Customized by `setup'."))) + `(custom-set-faces (list ,face ,spec 'now "Customized by `setup'."))) :documentation "Customize FACE with SPEC using `custom-set-faces'." :repeatable t) diff --git a/lisp/+tab-bar.el b/lisp/+tab-bar.el index 1f4745d..2c39dae 100644 --- a/lisp/+tab-bar.el +++ b/lisp/+tab-bar.el @@ -99,10 +99,10 @@ emms-player-playing-p) (let ((now-playing (+string-truncate (emms-mode-line-playlist-current) (- +tab-bar-emms-max-length 2)))) - `((emms-now-playing menu-item - ,(concat "{" now-playing "}" " ") - emms-pause - :help ,(emms-mode-line-playlist-current)))))) + `(emms-now-playing menu-item + ,(concat "{" now-playing "}" " ") + emms-pause + ( :help ,(emms-mode-line-playlist-current)))))) (defun +tab-bar-bongo () "Display Bongo now playing information." @@ -218,6 +218,17 @@ name to the left." (max 0 (- l-name tab-bar-tab-name-truncated-max l-ell)))) 'help-echo tab-name)))) +(defun +tab-bar-format-align-right () + "Align the rest of tab bar items to the right, pixel-wise." + ;; XXX: ideally, wouldn't require `shr' here + (require 'shr) ; `shr-string-pixel-width' + (let* ((rest (cdr (memq '+tab-bar-format-align-right tab-bar-format))) + (rest (tab-bar-format-list rest)) + (rest (mapconcat (lambda (item) (nth 2 item)) rest "")) + (hpos (shr-string-pixel-width rest)) + (str (propertize " " 'display `(space :align-to (- right (,hpos)))))) + `((align-right menu-item ,str ignore)))) + ;;; Menu bar ;; stole from https://github.com/emacs-mirror/emacs/blob/master/lisp/tab-bar.el