Emacs changes... lots of them

This commit is contained in:
2025-06-08 14:06:10 +01:00
parent 4f025811bc
commit 64808681e3
7 changed files with 213 additions and 157 deletions

View File

@@ -84,22 +84,26 @@ Let's setup a few absolute essentials:
:demand t :demand t
:init :init
(setq auth-sources '("~/.authinfo.gpg") (setq auth-sources '("~/.authinfo.gpg")
auto-revert-stop-on-user-input nil
auto-revert-use-notify nil auto-revert-use-notify nil
auto-revert-verbose nil auto-revert-verbose nil
backup-directory-alist `(("." . ,(no-littering-expand-var-file-name "saves/"))) backup-directory-alist `(("." . ,(no-littering-expand-var-file-name "saves/")))
buffer-file-coding-system 'utf-8-unix buffer-file-coding-system 'utf-8-unix
delete-by-moving-to-trash t delete-by-moving-to-trash t
global-auto-revert-non-file-buffers t global-auto-revert-non-file-buffers t
read-answer-short t
read-extended-command-predicate #'command-completion-default-include-p
remote-file-name-inhibit-delete-by-moving-to-trash t remote-file-name-inhibit-delete-by-moving-to-trash t
revert-without-query '(".")
save-buffer-coding-system 'utf-8-unix save-buffer-coding-system 'utf-8-unix
select-enable-clipboard t select-enable-clipboard t
use-dialog-box nil use-dialog-box nil
use-file-dialog nil use-file-dialog nil
use-short-answers t
user-full-name "Aryadev Chavali" user-full-name "Aryadev Chavali"
user-mail-address "aryadev@aryadevchavali.com" user-mail-address "aryadev@aryadevchavali.com"
warning-minimum-level :error) warning-minimum-level :error)
:config :config
(fset 'yes-or-no-p 'y-or-n-p)
(global-auto-revert-mode)) (global-auto-revert-mode))
#+end_src #+end_src
* Custom functionality and libraries * Custom functionality and libraries
@@ -546,6 +550,12 @@ Setup the evil package, with some opinionated settings:
evil-respect-visual-line-mode nil) evil-respect-visual-line-mode nil)
:config :config
(evil-mode) (evil-mode)
(defun +evil/select-pasted ()
(interactive)
(evil-goto-mark 91)
(evil-visual-char)
(evil-goto-mark 93))
:general :general
(leader (leader
"w" #'evil-window-map "w" #'evil-window-map
@@ -569,6 +579,7 @@ Setup the evil package, with some opinionated settings:
:keymaps 'override :keymaps 'override
"gu" #'evil-upcase "gu" #'evil-upcase
"gU" #'evil-downcase "gU" #'evil-downcase
"g C-v" #'+evil/select-pasted
"M-y" #'yank-pop "M-y" #'yank-pop
"T" 'nil) "T" 'nil)
@@ -634,6 +645,8 @@ in it.
completion-category-overrides completion-category-overrides
'((file (styles flex partial-completion substring))) '((file (styles flex partial-completion substring)))
completion-ignore-case t completion-ignore-case t
minibuffer-prompt-properties
'(read-only t intangible t cursor-intangible t face minibuffer-prompt)
read-file-name-completion-ignore-case t read-file-name-completion-ignore-case t
read-buffer-completion-ignore-case t) read-buffer-completion-ignore-case t)
:general :general
@@ -753,7 +766,7 @@ embark act more like how you wish, which I've barely touch on here.
:straight t :straight t
:general :general
(:keymaps 'override (:keymaps 'override
"M-m" #'embark-act) "M-/" #'embark-act)
:display :display
("\\*Embark Collect \\(Live\\|Completions\\)\\*" ("\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil nil
@@ -798,14 +811,13 @@ search system.
([remap imenu] #'consult-imenu ([remap imenu] #'consult-imenu
[remap switch-to-buffer] #'consult-buffer [remap switch-to-buffer] #'consult-buffer
[remap info] #'consult-info) [remap info] #'consult-info)
(leader
"'" #'consult-register)
(search-leader (search-leader
"s" #'consult-line "s" #'consult-line
"r" #'consult-ripgrep "r" #'consult-ripgrep
"f" #'consult-fd "f" #'consult-fd
"o" #'consult-org-agenda "o" #'consult-org-agenda
"e" #'consult-compile-error) "e" #'consult-compile-error
"m" #'consult-register)
:config :config
(with-eval-after-load "vertico-multiform" (with-eval-after-load "vertico-multiform"
(add-multiple-to-list vertico-multiform-commands (add-multiple-to-list vertico-multiform-commands
@@ -853,7 +865,7 @@ setup some evil binds for company.
:defer t :defer t
:straight t :straight t
:hook :hook
((prog-mode-hook eshell-mode-hook) . company-mode) (prog-mode-hook . company-mode)
:init :init
(setq company-idle-delay nil (setq company-idle-delay nil
company-minimum-prefix-length 3 company-minimum-prefix-length 3
@@ -1011,7 +1023,7 @@ fundamental mode and call it a day.
(format "Emacs v%s - %s\n" emacs-version) (format "Emacs v%s - %s\n" emacs-version)
(insert)))))) (insert))))))
#+end_src #+end_src
** Blinking cursor ** Cursor and the highlighted line
Configure the blinking cursor. Configure the blinking cursor.
#+begin_src emacs-lisp #+begin_src emacs-lisp
@@ -1020,9 +1032,10 @@ Configure the blinking cursor.
:init :init
(setq blink-cursor-delay 0.2) (setq blink-cursor-delay 0.2)
:config :config
(blink-cursor-mode)) (blink-cursor-mode -1)
(global-hl-line-mode))
#+end_src #+end_src
** Mode line ** Better Mode line
The mode line is the little bar at the bottom of the buffer, just The mode line is the little bar at the bottom of the buffer, just
above the minibuffer. It can store essentially any text, but above the minibuffer. It can store essentially any text, but
generally details about the current buffer (such as name, major mode, generally details about the current buffer (such as name, major mode,
@@ -1435,6 +1448,7 @@ to the kill ring and bind it to "Y".
(when date (when date
(setq date (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date))) (setq date (encode-time 0 0 0 (nth 1 date) (nth 0 date) (nth 2 date)))
(kill-new (format-time-string "%Y-%m-%d" date)))))) (kill-new (format-time-string "%Y-%m-%d" date))))))
(with-eval-after-load "evil-collection" (with-eval-after-load "evil-collection"
(evil-collection-calendar-setup))) (evil-collection-calendar-setup)))
#+end_src #+end_src
@@ -1464,6 +1478,9 @@ from the remote server.
(nmap (nmap
:keymaps 'notmuch-search-mode-map :keymaps 'notmuch-search-mode-map
"f" #'+mail/flag-thread) "f" #'+mail/flag-thread)
(nmmap
:keymaps 'notmuch-hello-mode-map
"t" #'notmuch-search-by-tag)
:init :init
(defconst +mail/local-dir (no-littering-expand-var-file-name "mail/")) (defconst +mail/local-dir (no-littering-expand-var-file-name "mail/"))
(setq notmuch-show-logo nil (setq notmuch-show-logo nil
@@ -1555,7 +1572,9 @@ Here I setup dired with a few niceties
dired-omit-files "^\\." ; dotfiles dired-omit-files "^\\." ; dotfiles
dired-omit-verbose nil dired-omit-verbose nil
dired-dwim-target t dired-dwim-target t
dired-recursive-copies 'always
dired-kill-when-opening-new-dired-buffer t dired-kill-when-opening-new-dired-buffer t
dired-deletion-confirmer 'y-or-n-p
dired-auto-revert-buffer t) dired-auto-revert-buffer t)
:general :general
(nmmap (nmmap
@@ -1825,6 +1844,8 @@ them.
("\\*eshell\\*" ("\\*eshell\\*"
(display-buffer-same-window) (display-buffer-same-window)
(reusable-frames . t)) (reusable-frames . t))
:hook
(eshell-mode-hook . completion-preview-mode)
:init :init
(defun +eshell/banner-message () (defun +eshell/banner-message ()
(concat (shell-command-to-string "fortune") "\n")) (concat (shell-command-to-string "fortune") "\n"))
@@ -1855,14 +1876,14 @@ them.
(local-leader (local-leader
:keymaps 'eshell-mode-map :keymaps 'eshell-mode-map
"g" (proc-int "g" (proc-int
(let ((buffer (current-buffer))) (let ((buffer (current-buffer)))
(eshell/goto) (eshell/goto)
(with-current-buffer buffer (with-current-buffer buffer
(eshell-send-input)))) (eshell-send-input))))
"l" (proc-int "l" (proc-int
(eshell-return-to-prompt) (eshell-return-to-prompt)
(insert "ls") (insert "ls")
(eshell-send-input)) (eshell-send-input))
"c" #'+eshell/good-clear "c" #'+eshell/good-clear
"k" #'eshell-kill-process)))) "k" #'eshell-kill-process))))
#+end_src #+end_src
@@ -1883,7 +1904,7 @@ internals without autoloading.
(use-package eshell-prompt (use-package eshell-prompt
:load-path "elisp/" :load-path "elisp/"
:config :config
(setq eshell-prompt-function #'+eshell-prompt/make-prompt)) (setq eshell-prompt-function #'eshell-prompt/make-prompt))
#+end_src #+end_src
*** EShell additions *** EShell additions
Using my external library Using my external library
@@ -2118,6 +2139,13 @@ IBuffer is the dired of buffers. Nothing much else to be said.
:general :general
(buffer-leader (buffer-leader
"i" #'ibuffer) "i" #'ibuffer)
:init
(setq ibuffer-formats
'((mark modified read-only locked
" " (name 40 40 :left :elide)
" " (size 8 -1 :right)
" " (mode 18 18 :left :elide) " " filename-and-process)
(mark " " (name 16 -1) " " filename)))
:config :config
(with-eval-after-load "evil-collection" (with-eval-after-load "evil-collection"
(evil-collection-ibuffer-setup))) (evil-collection-ibuffer-setup)))
@@ -2396,12 +2424,15 @@ in an Emacs-only map.
:straight (:host github :repo "unmonoqueteclea/jira.el") :straight (:host github :repo "unmonoqueteclea/jira.el")
:init :init
(setq jira-base-url "https://reframe.atlassian.net") (setq jira-base-url "https://reframe.atlassian.net")
(with-eval-after-load "evil"
(evil-set-initial-state 'jira-detail-mode 'motion)
(evil-set-initial-state 'jira-issues-mode 'motion))
:general :general
(app-leader (app-leader
"j" #'jira-issues) "j" #'jira-issues)
(nmmap (mmap
:keymaps 'jira-issues-mode-map :keymaps 'jira-issues-mode-map
"M-RET" #'jira-issues-actions-menu)) "@" #'jira-issues-actions-menu))
#+end_src #+end_src
* Text packages * Text packages
Standard packages and configurations for dealing with text, usually Standard packages and configurations for dealing with text, usually
@@ -2416,6 +2447,9 @@ into text-mode.
(use-package flyspell (use-package flyspell
:defer t :defer t
:hook ((org-mode-hook text-mode-hook) . flyspell-mode) :hook ((org-mode-hook text-mode-hook) . flyspell-mode)
:init
(setq flyspell-issue-message-flag nil
flyspell-issue-welcome-flag nil)
:general :general
(nmmap (nmmap
:keymaps 'text-mode-map :keymaps 'text-mode-map
@@ -2713,7 +2747,7 @@ description I give won't do it justice.
:hook ((scheme-mode-hook lisp-mode-hook emacs-lisp-mode-hook) :hook ((scheme-mode-hook lisp-mode-hook emacs-lisp-mode-hook)
. aggressive-indent-mode)) . aggressive-indent-mode))
#+end_src #+end_src
** compile-mode ** Compilation
Compilation mode is an incredibly useful subsystem of Emacs which Compilation mode is an incredibly useful subsystem of Emacs which
allows one to run arbitrary commands. If those commands produce allows one to run arbitrary commands. If those commands produce
errors (particularly errors that have a filename, column and line) errors (particularly errors that have a filename, column and line)
@@ -2757,8 +2791,21 @@ so you can actually read the text.
:init :init
(setq compilation-scroll-output 'first-error (setq compilation-scroll-output 'first-error
compilation-context-lines nil compilation-context-lines nil
compilation-always-kill t
compilation-ask-about-save nil
next-error-recenter '(4)
next-error-highlight 'fringe-arrow) next-error-highlight 'fringe-arrow)
:config :config
(require 'notifications)
(defun +compilation/notify (buffer str)
(with-current-buffer buffer
(let ((cwd default-directory)
(command compile-command))
(notifications-notify
:title (format "%s\n%s" command cwd)
:body str))))
(add-to-list 'compilation-finish-functions #'+compilation/notify)
(add-hook 'compilation-filter-hook #'ansi-color-compilation-filter)) (add-hook 'compilation-filter-hook #'ansi-color-compilation-filter))
#+end_src #+end_src
** xref ** xref
@@ -3006,6 +3053,7 @@ write the code.
(org-leader (org-leader
"l" #'org-store-link "l" #'org-store-link
"a" #'org-agenda
"d" #'org-babel-detangle "d" #'org-babel-detangle
"i" #'org-insert-last-stored-link "i" #'org-insert-last-stored-link
"o" #'org-open-at-point) "o" #'org-open-at-point)
@@ -3015,18 +3063,18 @@ write the code.
"TAB" #'org-cycle) "TAB" #'org-cycle)
(local-leader (local-leader
:states '(normal motion)
:keymaps 'org-mode-map :keymaps 'org-mode-map
"r" #'org-list-repair "d" #'org-deadline
"d" #'org-date-from-calendar "s" #'org-schedule
"t" #'org-todo "t" #'org-todo
"r" #'org-list-repair
"," #'org-priority "," #'org-priority
"T" #'org-babel-tangle
"i" #'org-insert-structure-template "i" #'org-insert-structure-template
"p" #'org-latex-preview "p" #'org-latex-preview
"s" #'org-property-action
"e" #'org-export-dispatch "e" #'org-export-dispatch
"o" #'org-edit-special "o" #'org-edit-special
"T" #'org-babel-tangle
"S" #'org-property-action
"R" #'org-refile "R" #'org-refile
"O" #'org-open-at-point) "O" #'org-open-at-point)
@@ -3076,18 +3124,21 @@ a very tidy way to manage your time.
(find-file it)))) (find-file it))))
(nmmap (nmmap
:keymaps 'org-agenda-mode-map :keymaps 'org-agenda-mode-map
"zd" #'org-agenda-day-view "," #'org-agenda-goto-date
"zw" #'org-agenda-week-view "." #'org-agenda-goto-today
"zm" #'org-agenda-month-view
"gd" #'org-agenda-goto-date
"RET" #'org-agenda-switch-to
"J" #'org-agenda-later "J" #'org-agenda-later
"K" #'org-agenda-earlier "K" #'org-agenda-earlier
"t" #'org-agenda-todo "RET" #'org-agenda-switch-to
"." #'org-agenda-goto-today "d" #'org-agenda-deadline
"," #'org-agenda-goto-date "gd" #'org-agenda-goto-date
"q" #'org-agenda-quit "q" #'org-agenda-quit
"r" #'org-agenda-redo)) "r" #'org-agenda-redo
"s" #'org-agenda-schedule
"t" #'org-agenda-todo
"zd" #'org-agenda-day-view
"zm" #'org-agenda-month-view
"zw" #'org-agenda-week-view
"f" #'org-agenda-filter-by-tag))
#+end_src #+end_src
*** Org Capture *** Org Capture
Org capture provides a system for quickly "capturing" some information Org capture provides a system for quickly "capturing" some information
@@ -4129,11 +4180,7 @@ I may disagree with some. So I use it in a mode to mode basis.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package evil-collection (use-package evil-collection
:after evil :after evil
:straight t :straight t)
:init
;; (setq evil-collection-mode-list '(eww flycheck magit calendar notmuch
;; ibuffer proced calc image))
)
#+end_src #+end_src
*** Evil number *** Evil number
Increment/decrement a number at point like Vim does, but use bindings Increment/decrement a number at point like Vim does, but use bindings
@@ -4222,27 +4269,6 @@ but I prefer Emacs' hence the configuration here.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package register (use-package register
:config :config
(defvar +register/--choice 0)
(defconst +register/quick-registers
(list ?a ?s ?d ?f ?g ?h ?j ?k ?l))
(defun +register/--quick-jump ()
(let ((choice (nth +register/--choice +register/quick-registers)))
(if (assoc choice register-alist)
(jump-to-register choice))))
(defun +register/jump-prev ()
(interactive)
(setq +register/--choice (mod (- +register/--choice 1)
(length +register/quick-registers)))
(+register/--quick-jump))
(defun +register/jump-next ()
(interactive)
(setq +register/--choice (mod (+ 1 +register/--choice)
(length +register/quick-registers)))
(+register/--quick-jump))
:general
(leader
"," #'+register/jump-prev
"." #'+register/jump-next)
(nmmap (nmmap
"m" #'point-to-register "m" #'point-to-register
"'" #'jump-to-register)) "'" #'jump-to-register))

View File

@@ -67,8 +67,8 @@ extreme end to CENTRE-SEGMENT."
(:eval (bml/--generate-padding (:eval (bml/--generate-padding
bml/left-segment)) bml/left-segment))
,bml/centre-segment ,bml/centre-segment
(:eval (bml/--generate-padding ;; NOTE: Emacs 30!
bml/right-segment)) mode-line-format-right-align
,bml/right-segment))) ,bml/right-segment)))
(provide 'better-mode-line) (provide 'better-mode-line)

View File

@@ -55,9 +55,7 @@ Uses tramp to figure out if we're in sudo mode or not. "
(let ((wrapped-dir (concat "/sudo::" default-directory))) (let ((wrapped-dir (concat "/sudo::" default-directory)))
(eshell/cd wrapped-dir))) (eshell/cd wrapped-dir)))
((string= user "root") ((string= user "root")
(thread-last 'localname (eshell/cd (file-remote-p default-directory 'localname))))))
(file-remote-p default-directory)
eshell/cd)))))
;; Additional functions ;; Additional functions
(defun +eshell/at-cwd (&optional arg) (defun +eshell/at-cwd (&optional arg)
@@ -80,6 +78,19 @@ Pass argument to `+eshell/open'."
collect collect
(cons (buffer-name buffer) buffer))) (cons (buffer-name buffer) buffer)))
(defun +eshell/--choose-instance ()
(let* ((current-instances (+eshell/--current-instances))
(answer (completing-read "Enter name: " (mapcar #'car current-instances)))
(result (assoc answer current-instances)))
(cond
(result (switch-to-buffer (cdr result))
(cdr result))
((not (string= answer ""))
(let ((eshell-buffer-name (format "*%s-eshell*" answer)))
(eshell nil)))
(t
(eshell)))))
(defun +eshell/open (&optional arg) (defun +eshell/open (&optional arg)
"Open an instance of EShell, displaying it. "Open an instance of EShell, displaying it.
@@ -89,35 +100,28 @@ Otherwise, create an instance with the name given.
If `arg' is non nil, then always prompt user to select an instance." If `arg' is non nil, then always prompt user to select an instance."
(interactive "P") (interactive "P")
(let ((current-instances (+eshell/--current-instances)) (cond
(buffer nil)) ((null arg)
(cond ;; No arg => Choose a default instance
((and (null current-instances) (let* ((candidates (+eshell/--current-instances))
(null arg)) (default-cand (assoc "*eshell*" candidates #'string=))
(setq buffer (eshell))) (vacuous-cand (car candidates)))
((and (= (length current-instances) 1) (if-let ((cand (or default-cand vacuous-cand)))
(null arg)) (switch-to-buffer (cdr cand))
(setq buffer (cdar current-instances)) (eshell))))
(switch-to-buffer (cdar current-instances))) ((= (car arg) 4)
(t ;; Arg => Choose an instance
(let* ((answer (completing-read "Enter name: " (mapcar #'car current-instances))) (+eshell/--choose-instance))
(result (assoc answer current-instances))) (t
(cond ;; Double arg => Choose an instance then choose the directory
(result (switch-to-buffer (cdr result)) (let ((instance (+eshell/--choose-instance)))
(setq buffer (cdr result))) (with-current-buffer instance
((not (string= answer "")) (thread-last (read-file-name "Enter directory: ")
(let ((eshell-buffer-name (format "*%s-eshell*" answer))) file-name-directory
(setq buffer (eshell nil)))) list
(t eshell/cd)
(setq buffer (eshell))))))) (eshell-send-input))
(if (and (consp arg) (> (car arg) 4)) instance))))
(with-current-buffer buffer
(thread-last (read-file-name "Enter directory: ")
file-name-directory
list
eshell/cd)
(eshell-send-input)))
buffer))
(provide 'eshell-additions) (provide 'eshell-additions)
;;; eshell-additions.el ends here ;;; eshell-additions.el ends here

View File

@@ -28,13 +28,41 @@
"Prompt for user to input.") "Prompt for user to input.")
(defvar ep/dir-colour "deepskyblue") (defvar ep/dir-colour "deepskyblue")
(defvar ep/success-colour "forestgreen") (defvar ep/success-colour "green2")
(defvar ep/failure-colour "red") (defvar ep/failure-colour "red")
(defvar ep/branch-name-colour "LightSalmon") (defvar ep/branch-name-colour "LightSalmon")
(defvar ep/pipe-colour "green2") (defvar ep/pipe-colour "green4")
(defvar ep/ahead-colour "dodger blue") (defvar ep/ahead-colour "dodger blue")
(defvar ep/remote-colour "DarkGoldenrod") (defvar ep/remote-colour "DarkGoldenrod")
(defun ep/make-prompt ()
(let ((git (ep/--git-status)))
(thread-last
`(("┌──" :foreground ,ep/pipe-colour)
"["
(,(ep/--user-and-remote) :foreground ,ep/remote-colour)
(,(abbreviate-file-name (tramp-file-local-name (eshell/pwd)))
:foreground ,ep/dir-colour)
,(if (string= git "")
""
(concat "]─[" git))
"]"
"\n"
("└─>" :foreground ,ep/pipe-colour)
(,ep/user-prompt :foreground ,(ep/--colour-on-last-command)))
(mapconcat
#'(lambda (item)
(if (listp item)
(propertize (car item)
'font-lock-face (cdr item)
'front-sticky '(font-lock-face read-only)
'rear-nonsticky '(font-lock-face read-only))
item))))))
(defun ep/--with-fg-colour (s colour)
"Helper which propertises a string `s' with foreground colour `colour'"
(propertize s 'font-lock-face `(:foreground ,colour)))
(defun ep/--colour-on-last-command () (defun ep/--colour-on-last-command ()
"Returns an Emacs colour based on ESHELL-LAST-COMMAND-STATUS." "Returns an Emacs colour based on ESHELL-LAST-COMMAND-STATUS."
(if (zerop eshell-last-command-status) (if (zerop eshell-last-command-status)
@@ -57,38 +85,58 @@ behind or ahead the local repository is."
(status (nth 3 branch-status)) (status (nth 3 branch-status))
(diff (cl-position "by" branch-status :test #'string=))) (diff (cl-position "by" branch-status :test #'string=)))
(if (null diff) (if (null diff)
(propertize "=" 'font-lock-face `(:foreground ,ep/success-colour)) (ep/--with-fg-colour "=" ep/success-colour)
(let ((n (nth (+ 1 diff) branch-status))) (let ((n (nth (+ 1 diff) branch-status)))
(concat (concat
(cond (cond
((string= status "ahead") ((string= status "ahead")
(propertize "" 'font-lock-face `(:foreground ,ep/ahead-colour))) (ep/--with-fg-colour "" ep/ahead-colour))
((string= status "behind") ((string= status "behind")
(propertize "" 'font-lock-face `(:foreground ,ep/failure-colour)))) (ep/--with-fg-colour "" ep/failure-colour)))
n))))) n)))))
(defun ep/--git-change-status () (defun ep/--git-change-status ()
"Returns a propertized string for the condition of the worktree in "Returns a propertized string for the condition of the worktree in
a repository. If there are no changes i.e. the worktree is clean a repository.
then a green tick is returned, but if there are changes then the
number of files affected are returned in red." If there are no changes i.e. the worktree is clean then a green tick is
returned.
If there are changes then we characterise it by the following parameters:
- staged changes in green
- unstaged but tracked changes in blue
- untracked files in red
"
(let* ((git-cmd "git status -s") (let* ((git-cmd "git status -s")
(command-output (split-string (shell-command-to-string git-cmd) "\n")) (command-output
(changed-files (- (length command-output) 1))) (thread-first (shell-command-to-string git-cmd)
(if (= changed-files 0) (split-string "\n")
(propertize "" butlast))
'font-lock-face (status-codes (mapcar #'(lambda (s) (cons (substring s 0 1) (substring s 1 2)))
`(:foreground ,ep/success-colour)) command-output))
(propertize (number-to-string changed-files) (filter-f (lambda (x) (not (or (string= x "?") (string= x " ")))))
'font-lock-face (total (length status-codes))
`(:foreground ,ep/failure-colour))))) (staged (cl-count-if (lambda (x) (funcall filter-f (car x))) status-codes))
(modified (cl-count-if (lambda (x) (funcall filter-f (cdr x))) status-codes))
(not-tracked (cl-count-if (lambda (x) (string= (cdr x) "?")) status-codes)))
(if (= total 0)
(ep/--with-fg-colour "" ep/success-colour)
(thread-last
(list
(ep/--with-fg-colour (number-to-string staged) ep/success-colour)
(ep/--with-fg-colour (number-to-string modified) ep/ahead-colour)
(ep/--with-fg-colour (number-to-string not-tracked) ep/failure-colour))
(cl-remove-if #'(lambda (s) (string= s "0")))
(mapconcat #'(lambda (s) (concat s "/")))))))
(defun ep/--git-branch-name () (defun ep/--git-branch-name ()
"Get the branch name of the current working directory. W" "Get the branch name of the current working directory.
If a deteached head, return the SHA."
(let* ((branch-name (thread-last (let* ((branch-name (thread-last
(split-string (shell-command-to-string "git branch") "\n") (split-string (shell-command-to-string "git branch") "\n")
(cl-remove-if (lambda (s) (= (length s) 0))) (cl-remove-if #'(lambda (s) (= (length s) 0)))
(cl-find-if (lambda (s) (string= "*" (substring s 0 1)))))) (cl-find-if #'(lambda (s) (string= "*" (substring s 0 1))))))
(branch-name (if (null branch-name) nil (branch-name (if (null branch-name) nil
(substring branch-name 2)))) (substring branch-name 2))))
(cond (cond
@@ -100,57 +148,33 @@ number of files affected are returned in red."
(t branch-name)))) (t branch-name))))
(defun ep/--git-status () (defun ep/--git-status ()
"Returns a completely formatted string of "Returns a completely formatted string of form
form (BRANCH-NAME<CHANGES>[REMOTE-STATUS])." BRANCH-NAME(REMOTE-STATUS)(CHANGES)."
(let ((git-branch (ep/--git-branch-name))) (let ((git-branch (ep/--git-branch-name)))
(if (null git-branch) (if (null git-branch)
"" ""
(format (format
"%s(%s)(%s)" "%s(%s)(%s)"
(propertize git-branch 'font-lock-face `(:foreground ,ep/branch-name-colour)) (ep/--with-fg-colour git-branch ep/branch-name-colour)
(ep/--git-remote-status) (ep/--git-remote-status)
(ep/--git-change-status))))) (ep/--git-change-status)))))
(defun ep/--user-and-remote () (defun ep/--user-and-remote ()
"If in a remote directory, return a string representing that host,
otherwise empty string."
(if (file-remote-p default-directory) (if (file-remote-p default-directory)
(let ((user (file-remote-p default-directory 'user)) (let ((user (file-remote-p default-directory 'user))
(host (file-remote-p default-directory 'host))) (host (file-remote-p default-directory 'host)))
(if user (concat
(format "%s@%s " user host) (if user
(concat host " "))) (format "%s@%s" user host)
host)
":"))
"")) ""))
(defun ep/make-prompt ()
(let ((git (ep/--git-status)))
(mapconcat
(lambda (item)
(if (listp item)
(propertize (car item)
'font-lock-face (cdr item)
'front-sticky '(font-lock-face read-only)
'rear-nonsticky '(font-lock-face read-only))
item))
(list
`("┌──"
:foreground ,ep/pipe-colour)
"["
`(,(ep/--user-and-remote)
:foreground ,ep/remote-colour)
`(,(abbreviate-file-name (tramp-file-local-name (eshell/pwd)))
:foreground ,ep/dir-colour)
(if (string= git "")
""
(concat "]─[" git))
"]"
"\n"
`("└─>"
:foreground ,ep/pipe-colour)
(list ep/user-prompt ':foreground (ep/--colour-on-last-command))))))
(provide 'eshell-prompt) (provide 'eshell-prompt)
;;; eshell-prompt.el ends here ;;; eshell-prompt.el ends here
;; Local Variables: ;; Local Variables:
;; read-symbol-shorthands: (("ep" . "+eshell-prompt")) ;; read-symbol-shorthands: (("ep" . "eshell-prompt"))
;; End: ;; End:

View File

@@ -12,6 +12,7 @@
'(child-frame-border ((t (:background "white")))) '(child-frame-border ((t (:background "white"))))
'(company-preview ((t (:foreground "wheat" :background "blue4")))) '(company-preview ((t (:foreground "wheat" :background "blue4"))))
'(company-preview-common ((t (:inherit company-preview :foreground "grey")))) '(company-preview-common ((t (:inherit company-preview :foreground "grey"))))
'(company-template-field ((t (:inherit company-preview :foreground "grey" :slant italic))))
'(company-tooltip ((t (:background "black" :foreground "white")))) '(company-tooltip ((t (:background "black" :foreground "white"))))
'(company-tooltip-annotation ((t (:foreground "grey")))) '(company-tooltip-annotation ((t (:foreground "grey"))))
'(company-tooltip-selection ((t (:background "grey31")))) '(company-tooltip-selection ((t (:background "grey31"))))

View File

@@ -53,7 +53,7 @@ Returns a list of files with the directory preprended to them."
(thread-last (+search/get-all-candidates) (thread-last (+search/get-all-candidates)
(cl-remove-if #'directory-name-p) (cl-remove-if #'directory-name-p)
(mapcar #'(lambda (x) (concat "\"" x "\" "))) (mapcar #'(lambda (x) (concat "\"" x "\" ")))
(string-join))) string-join))
(defun +search/search-all () (defun +search/search-all ()
(interactive) (interactive)
@@ -61,7 +61,7 @@ Returns a list of files with the directory preprended to them."
(candidates (+search/-format-grep-candidates))) (candidates (+search/-format-grep-candidates)))
(thread-last candidates (thread-last candidates
(format "grep --color=auto -nIHZe \"%s\" -- %s" term) (format "grep --color=auto -nIHZe \"%s\" -- %s" term)
(grep)) grep)
(next-error))) (next-error)))
(provide 'search) (provide 'search)

View File

@@ -45,10 +45,10 @@
(load bootstrap-file nil 'nomessage)) (load bootstrap-file nil 'nomessage))
;; Setup benchmark to get current statistics - enable only if profiling. ;; Setup benchmark to get current statistics - enable only if profiling.
;; (straight-use-package 'benchmark-init) (straight-use-package 'benchmark-init)
;; (require 'benchmark-init) (require 'benchmark-init)
;; (add-hook 'after-init-hook 'benchmark-init/deactivate) (add-hook 'after-init-hook 'benchmark-init/deactivate)
;; (benchmark-init/activate) (benchmark-init/activate)
(setq use-package-enable-imenu-support t (setq use-package-enable-imenu-support t
use-package-always-demand nil use-package-always-demand nil
@@ -77,6 +77,7 @@
(+literate/load-config) (+literate/load-config)
(when (daemonp) (when (daemonp)
;; No need to lazy load this stuff
(require 'general) (require 'general)
(require 'evil) (require 'evil)
(require 'dired) (require 'dired)
@@ -86,7 +87,6 @@
(require 'org) (require 'org)
(require 'company) (require 'company)
(require 'eshell) (require 'eshell)
(require 'org)
(require 'eglot)) (require 'eglot))
(setq gc-cons-threshold (* 100 1024 1024) ; ~100MiB (setq gc-cons-threshold (* 100 1024 1024) ; ~100MiB
@@ -95,7 +95,8 @@
;; FIXME: Problem with memory-report after running Emacs for a ;; FIXME: Problem with memory-report after running Emacs for a
;; bit, causes a Lisp nesting error, so I just set it up really ;; bit, causes a Lisp nesting error, so I just set it up really
;; high so it doesn't reach that. ;; high so it doesn't reach that.
max-lisp-eval-depth 999999) max-lisp-eval-depth 999999
garbage-collection-messages t)
(provide 'init) (provide 'init)
;;; init.el ends here ;;; init.el ends here