Emacs changes... lots of them
This commit is contained in:
@@ -84,22 +84,26 @@ Let's setup a few absolute essentials:
|
||||
:demand t
|
||||
:init
|
||||
(setq auth-sources '("~/.authinfo.gpg")
|
||||
auto-revert-stop-on-user-input nil
|
||||
auto-revert-use-notify nil
|
||||
auto-revert-verbose nil
|
||||
backup-directory-alist `(("." . ,(no-littering-expand-var-file-name "saves/")))
|
||||
buffer-file-coding-system 'utf-8-unix
|
||||
delete-by-moving-to-trash 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
|
||||
revert-without-query '(".")
|
||||
save-buffer-coding-system 'utf-8-unix
|
||||
select-enable-clipboard t
|
||||
use-dialog-box nil
|
||||
use-file-dialog nil
|
||||
use-short-answers t
|
||||
user-full-name "Aryadev Chavali"
|
||||
user-mail-address "aryadev@aryadevchavali.com"
|
||||
warning-minimum-level :error)
|
||||
:config
|
||||
(fset 'yes-or-no-p 'y-or-n-p)
|
||||
(global-auto-revert-mode))
|
||||
#+end_src
|
||||
* Custom functionality and libraries
|
||||
@@ -546,6 +550,12 @@ Setup the evil package, with some opinionated settings:
|
||||
evil-respect-visual-line-mode nil)
|
||||
:config
|
||||
(evil-mode)
|
||||
(defun +evil/select-pasted ()
|
||||
(interactive)
|
||||
(evil-goto-mark 91)
|
||||
(evil-visual-char)
|
||||
(evil-goto-mark 93))
|
||||
|
||||
:general
|
||||
(leader
|
||||
"w" #'evil-window-map
|
||||
@@ -569,6 +579,7 @@ Setup the evil package, with some opinionated settings:
|
||||
:keymaps 'override
|
||||
"gu" #'evil-upcase
|
||||
"gU" #'evil-downcase
|
||||
"g C-v" #'+evil/select-pasted
|
||||
"M-y" #'yank-pop
|
||||
"T" 'nil)
|
||||
|
||||
@@ -634,6 +645,8 @@ in it.
|
||||
completion-category-overrides
|
||||
'((file (styles flex partial-completion substring)))
|
||||
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-buffer-completion-ignore-case t)
|
||||
:general
|
||||
@@ -753,7 +766,7 @@ embark act more like how you wish, which I've barely touch on here.
|
||||
:straight t
|
||||
:general
|
||||
(:keymaps 'override
|
||||
"M-m" #'embark-act)
|
||||
"M-/" #'embark-act)
|
||||
:display
|
||||
("\\*Embark Collect \\(Live\\|Completions\\)\\*"
|
||||
nil
|
||||
@@ -798,14 +811,13 @@ search system.
|
||||
([remap imenu] #'consult-imenu
|
||||
[remap switch-to-buffer] #'consult-buffer
|
||||
[remap info] #'consult-info)
|
||||
(leader
|
||||
"'" #'consult-register)
|
||||
(search-leader
|
||||
"s" #'consult-line
|
||||
"r" #'consult-ripgrep
|
||||
"f" #'consult-fd
|
||||
"o" #'consult-org-agenda
|
||||
"e" #'consult-compile-error)
|
||||
"e" #'consult-compile-error
|
||||
"m" #'consult-register)
|
||||
:config
|
||||
(with-eval-after-load "vertico-multiform"
|
||||
(add-multiple-to-list vertico-multiform-commands
|
||||
@@ -853,7 +865,7 @@ setup some evil binds for company.
|
||||
:defer t
|
||||
:straight t
|
||||
:hook
|
||||
((prog-mode-hook eshell-mode-hook) . company-mode)
|
||||
(prog-mode-hook . company-mode)
|
||||
:init
|
||||
(setq company-idle-delay nil
|
||||
company-minimum-prefix-length 3
|
||||
@@ -1011,7 +1023,7 @@ fundamental mode and call it a day.
|
||||
(format "Emacs v%s - %s\n" emacs-version)
|
||||
(insert))))))
|
||||
#+end_src
|
||||
** Blinking cursor
|
||||
** Cursor and the highlighted line
|
||||
Configure the blinking cursor.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
@@ -1020,9 +1032,10 @@ Configure the blinking cursor.
|
||||
:init
|
||||
(setq blink-cursor-delay 0.2)
|
||||
:config
|
||||
(blink-cursor-mode))
|
||||
(blink-cursor-mode -1)
|
||||
(global-hl-line-mode))
|
||||
#+end_src
|
||||
** Mode line
|
||||
** Better Mode line
|
||||
The mode line is the little bar at the bottom of the buffer, just
|
||||
above the minibuffer. It can store essentially any text, but
|
||||
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
|
||||
(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))))))
|
||||
|
||||
(with-eval-after-load "evil-collection"
|
||||
(evil-collection-calendar-setup)))
|
||||
#+end_src
|
||||
@@ -1464,6 +1478,9 @@ from the remote server.
|
||||
(nmap
|
||||
:keymaps 'notmuch-search-mode-map
|
||||
"f" #'+mail/flag-thread)
|
||||
(nmmap
|
||||
:keymaps 'notmuch-hello-mode-map
|
||||
"t" #'notmuch-search-by-tag)
|
||||
:init
|
||||
(defconst +mail/local-dir (no-littering-expand-var-file-name "mail/"))
|
||||
(setq notmuch-show-logo nil
|
||||
@@ -1555,7 +1572,9 @@ Here I setup dired with a few niceties
|
||||
dired-omit-files "^\\." ; dotfiles
|
||||
dired-omit-verbose nil
|
||||
dired-dwim-target t
|
||||
dired-recursive-copies 'always
|
||||
dired-kill-when-opening-new-dired-buffer t
|
||||
dired-deletion-confirmer 'y-or-n-p
|
||||
dired-auto-revert-buffer t)
|
||||
:general
|
||||
(nmmap
|
||||
@@ -1825,6 +1844,8 @@ them.
|
||||
("\\*eshell\\*"
|
||||
(display-buffer-same-window)
|
||||
(reusable-frames . t))
|
||||
:hook
|
||||
(eshell-mode-hook . completion-preview-mode)
|
||||
:init
|
||||
(defun +eshell/banner-message ()
|
||||
(concat (shell-command-to-string "fortune") "\n"))
|
||||
@@ -1855,14 +1876,14 @@ them.
|
||||
(local-leader
|
||||
:keymaps 'eshell-mode-map
|
||||
"g" (proc-int
|
||||
(let ((buffer (current-buffer)))
|
||||
(eshell/goto)
|
||||
(with-current-buffer buffer
|
||||
(eshell-send-input))))
|
||||
(let ((buffer (current-buffer)))
|
||||
(eshell/goto)
|
||||
(with-current-buffer buffer
|
||||
(eshell-send-input))))
|
||||
"l" (proc-int
|
||||
(eshell-return-to-prompt)
|
||||
(insert "ls")
|
||||
(eshell-send-input))
|
||||
(eshell-return-to-prompt)
|
||||
(insert "ls")
|
||||
(eshell-send-input))
|
||||
"c" #'+eshell/good-clear
|
||||
"k" #'eshell-kill-process))))
|
||||
#+end_src
|
||||
@@ -1883,7 +1904,7 @@ internals without autoloading.
|
||||
(use-package eshell-prompt
|
||||
:load-path "elisp/"
|
||||
:config
|
||||
(setq eshell-prompt-function #'+eshell-prompt/make-prompt))
|
||||
(setq eshell-prompt-function #'eshell-prompt/make-prompt))
|
||||
#+end_src
|
||||
*** EShell additions
|
||||
Using my external library
|
||||
@@ -2118,6 +2139,13 @@ IBuffer is the dired of buffers. Nothing much else to be said.
|
||||
:general
|
||||
(buffer-leader
|
||||
"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
|
||||
(with-eval-after-load "evil-collection"
|
||||
(evil-collection-ibuffer-setup)))
|
||||
@@ -2396,12 +2424,15 @@ in an Emacs-only map.
|
||||
:straight (:host github :repo "unmonoqueteclea/jira.el")
|
||||
:init
|
||||
(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
|
||||
(app-leader
|
||||
"j" #'jira-issues)
|
||||
(nmmap
|
||||
(mmap
|
||||
:keymaps 'jira-issues-mode-map
|
||||
"M-RET" #'jira-issues-actions-menu))
|
||||
"@" #'jira-issues-actions-menu))
|
||||
#+end_src
|
||||
* Text packages
|
||||
Standard packages and configurations for dealing with text, usually
|
||||
@@ -2416,6 +2447,9 @@ into text-mode.
|
||||
(use-package flyspell
|
||||
:defer t
|
||||
:hook ((org-mode-hook text-mode-hook) . flyspell-mode)
|
||||
:init
|
||||
(setq flyspell-issue-message-flag nil
|
||||
flyspell-issue-welcome-flag nil)
|
||||
:general
|
||||
(nmmap
|
||||
: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)
|
||||
. aggressive-indent-mode))
|
||||
#+end_src
|
||||
** compile-mode
|
||||
** Compilation
|
||||
Compilation mode is an incredibly useful subsystem of Emacs which
|
||||
allows one to run arbitrary commands. If those commands produce
|
||||
errors (particularly errors that have a filename, column and line)
|
||||
@@ -2757,8 +2791,21 @@ so you can actually read the text.
|
||||
:init
|
||||
(setq compilation-scroll-output 'first-error
|
||||
compilation-context-lines nil
|
||||
compilation-always-kill t
|
||||
compilation-ask-about-save nil
|
||||
next-error-recenter '(4)
|
||||
next-error-highlight 'fringe-arrow)
|
||||
: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))
|
||||
#+end_src
|
||||
** xref
|
||||
@@ -3006,6 +3053,7 @@ write the code.
|
||||
|
||||
(org-leader
|
||||
"l" #'org-store-link
|
||||
"a" #'org-agenda
|
||||
"d" #'org-babel-detangle
|
||||
"i" #'org-insert-last-stored-link
|
||||
"o" #'org-open-at-point)
|
||||
@@ -3015,18 +3063,18 @@ write the code.
|
||||
"TAB" #'org-cycle)
|
||||
|
||||
(local-leader
|
||||
:states '(normal motion)
|
||||
:keymaps 'org-mode-map
|
||||
"r" #'org-list-repair
|
||||
"d" #'org-date-from-calendar
|
||||
"d" #'org-deadline
|
||||
"s" #'org-schedule
|
||||
"t" #'org-todo
|
||||
"r" #'org-list-repair
|
||||
"," #'org-priority
|
||||
"T" #'org-babel-tangle
|
||||
"i" #'org-insert-structure-template
|
||||
"p" #'org-latex-preview
|
||||
"s" #'org-property-action
|
||||
"e" #'org-export-dispatch
|
||||
"o" #'org-edit-special
|
||||
"T" #'org-babel-tangle
|
||||
"S" #'org-property-action
|
||||
"R" #'org-refile
|
||||
"O" #'org-open-at-point)
|
||||
|
||||
@@ -3076,18 +3124,21 @@ a very tidy way to manage your time.
|
||||
(find-file it))))
|
||||
(nmmap
|
||||
:keymaps 'org-agenda-mode-map
|
||||
"zd" #'org-agenda-day-view
|
||||
"zw" #'org-agenda-week-view
|
||||
"zm" #'org-agenda-month-view
|
||||
"gd" #'org-agenda-goto-date
|
||||
"RET" #'org-agenda-switch-to
|
||||
"," #'org-agenda-goto-date
|
||||
"." #'org-agenda-goto-today
|
||||
"J" #'org-agenda-later
|
||||
"K" #'org-agenda-earlier
|
||||
"t" #'org-agenda-todo
|
||||
"." #'org-agenda-goto-today
|
||||
"," #'org-agenda-goto-date
|
||||
"RET" #'org-agenda-switch-to
|
||||
"d" #'org-agenda-deadline
|
||||
"gd" #'org-agenda-goto-date
|
||||
"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
|
||||
*** Org Capture
|
||||
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
|
||||
(use-package evil-collection
|
||||
:after evil
|
||||
:straight t
|
||||
:init
|
||||
;; (setq evil-collection-mode-list '(eww flycheck magit calendar notmuch
|
||||
;; ibuffer proced calc image))
|
||||
)
|
||||
:straight t)
|
||||
#+end_src
|
||||
*** Evil number
|
||||
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
|
||||
(use-package register
|
||||
: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
|
||||
"m" #'point-to-register
|
||||
"'" #'jump-to-register))
|
||||
|
||||
@@ -67,8 +67,8 @@ extreme end to CENTRE-SEGMENT."
|
||||
(:eval (bml/--generate-padding
|
||||
bml/left-segment))
|
||||
,bml/centre-segment
|
||||
(:eval (bml/--generate-padding
|
||||
bml/right-segment))
|
||||
;; NOTE: Emacs 30!
|
||||
mode-line-format-right-align
|
||||
,bml/right-segment)))
|
||||
|
||||
(provide 'better-mode-line)
|
||||
|
||||
@@ -55,9 +55,7 @@ Uses tramp to figure out if we're in sudo mode or not. "
|
||||
(let ((wrapped-dir (concat "/sudo::" default-directory)))
|
||||
(eshell/cd wrapped-dir)))
|
||||
((string= user "root")
|
||||
(thread-last 'localname
|
||||
(file-remote-p default-directory)
|
||||
eshell/cd)))))
|
||||
(eshell/cd (file-remote-p default-directory 'localname))))))
|
||||
|
||||
;; Additional functions
|
||||
(defun +eshell/at-cwd (&optional arg)
|
||||
@@ -80,6 +78,19 @@ Pass argument to `+eshell/open'."
|
||||
collect
|
||||
(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)
|
||||
"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."
|
||||
(interactive "P")
|
||||
(let ((current-instances (+eshell/--current-instances))
|
||||
(buffer nil))
|
||||
(cond
|
||||
((and (null current-instances)
|
||||
(null arg))
|
||||
(setq buffer (eshell)))
|
||||
((and (= (length current-instances) 1)
|
||||
(null arg))
|
||||
(setq buffer (cdar current-instances))
|
||||
(switch-to-buffer (cdar current-instances)))
|
||||
(t
|
||||
(let* ((answer (completing-read "Enter name: " (mapcar #'car current-instances)))
|
||||
(result (assoc answer current-instances)))
|
||||
(cond
|
||||
(result (switch-to-buffer (cdr result))
|
||||
(setq buffer (cdr result)))
|
||||
((not (string= answer ""))
|
||||
(let ((eshell-buffer-name (format "*%s-eshell*" answer)))
|
||||
(setq buffer (eshell nil))))
|
||||
(t
|
||||
(setq buffer (eshell)))))))
|
||||
(if (and (consp arg) (> (car arg) 4))
|
||||
(with-current-buffer buffer
|
||||
(thread-last (read-file-name "Enter directory: ")
|
||||
file-name-directory
|
||||
list
|
||||
eshell/cd)
|
||||
(eshell-send-input)))
|
||||
buffer))
|
||||
(cond
|
||||
((null arg)
|
||||
;; No arg => Choose a default instance
|
||||
(let* ((candidates (+eshell/--current-instances))
|
||||
(default-cand (assoc "*eshell*" candidates #'string=))
|
||||
(vacuous-cand (car candidates)))
|
||||
(if-let ((cand (or default-cand vacuous-cand)))
|
||||
(switch-to-buffer (cdr cand))
|
||||
(eshell))))
|
||||
((= (car arg) 4)
|
||||
;; Arg => Choose an instance
|
||||
(+eshell/--choose-instance))
|
||||
(t
|
||||
;; Double arg => Choose an instance then choose the directory
|
||||
(let ((instance (+eshell/--choose-instance)))
|
||||
(with-current-buffer instance
|
||||
(thread-last (read-file-name "Enter directory: ")
|
||||
file-name-directory
|
||||
list
|
||||
eshell/cd)
|
||||
(eshell-send-input))
|
||||
instance))))
|
||||
|
||||
(provide 'eshell-additions)
|
||||
;;; eshell-additions.el ends here
|
||||
|
||||
@@ -28,13 +28,41 @@
|
||||
"Prompt for user to input.")
|
||||
|
||||
(defvar ep/dir-colour "deepskyblue")
|
||||
(defvar ep/success-colour "forestgreen")
|
||||
(defvar ep/success-colour "green2")
|
||||
(defvar ep/failure-colour "red")
|
||||
(defvar ep/branch-name-colour "LightSalmon")
|
||||
(defvar ep/pipe-colour "green2")
|
||||
(defvar ep/pipe-colour "green4")
|
||||
(defvar ep/ahead-colour "dodger blue")
|
||||
(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 ()
|
||||
"Returns an Emacs colour based on 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))
|
||||
(diff (cl-position "by" branch-status :test #'string=)))
|
||||
(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)))
|
||||
(concat
|
||||
(cond
|
||||
((string= status "ahead")
|
||||
(propertize "→" 'font-lock-face `(:foreground ,ep/ahead-colour)))
|
||||
(ep/--with-fg-colour "→" ep/ahead-colour))
|
||||
((string= status "behind")
|
||||
(propertize "←" 'font-lock-face `(:foreground ,ep/failure-colour))))
|
||||
(ep/--with-fg-colour "←" ep/failure-colour)))
|
||||
n)))))
|
||||
|
||||
(defun ep/--git-change-status ()
|
||||
"Returns a propertized string for the condition of the worktree in
|
||||
a repository. If there are no changes i.e. the worktree is clean
|
||||
then a green tick is returned, but if there are changes then the
|
||||
number of files affected are returned in red."
|
||||
a repository.
|
||||
|
||||
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")
|
||||
(command-output (split-string (shell-command-to-string git-cmd) "\n"))
|
||||
(changed-files (- (length command-output) 1)))
|
||||
(if (= changed-files 0)
|
||||
(propertize "✓"
|
||||
'font-lock-face
|
||||
`(:foreground ,ep/success-colour))
|
||||
(propertize (number-to-string changed-files)
|
||||
'font-lock-face
|
||||
`(:foreground ,ep/failure-colour)))))
|
||||
(command-output
|
||||
(thread-first (shell-command-to-string git-cmd)
|
||||
(split-string "\n")
|
||||
butlast))
|
||||
(status-codes (mapcar #'(lambda (s) (cons (substring s 0 1) (substring s 1 2)))
|
||||
command-output))
|
||||
(filter-f (lambda (x) (not (or (string= x "?") (string= x " ")))))
|
||||
(total (length status-codes))
|
||||
(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 ()
|
||||
"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
|
||||
(split-string (shell-command-to-string "git branch") "\n")
|
||||
(cl-remove-if (lambda (s) (= (length s) 0)))
|
||||
(cl-find-if (lambda (s) (string= "*" (substring s 0 1))))))
|
||||
(cl-remove-if #'(lambda (s) (= (length s) 0)))
|
||||
(cl-find-if #'(lambda (s) (string= "*" (substring s 0 1))))))
|
||||
(branch-name (if (null branch-name) nil
|
||||
(substring branch-name 2))))
|
||||
(cond
|
||||
@@ -100,57 +148,33 @@ number of files affected are returned in red."
|
||||
(t branch-name))))
|
||||
|
||||
(defun ep/--git-status ()
|
||||
"Returns a completely formatted string of
|
||||
form (BRANCH-NAME<CHANGES>[REMOTE-STATUS])."
|
||||
"Returns a completely formatted string of form
|
||||
BRANCH-NAME(REMOTE-STATUS)(CHANGES)."
|
||||
(let ((git-branch (ep/--git-branch-name)))
|
||||
(if (null git-branch)
|
||||
""
|
||||
(format
|
||||
"%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-change-status)))))
|
||||
|
||||
(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)
|
||||
(let ((user (file-remote-p default-directory 'user))
|
||||
(host (file-remote-p default-directory 'host)))
|
||||
(if user
|
||||
(format "%s@%s " user host)
|
||||
(concat host " ")))
|
||||
(concat
|
||||
(if user
|
||||
(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)
|
||||
;;; eshell-prompt.el ends here
|
||||
|
||||
;; Local Variables:
|
||||
;; read-symbol-shorthands: (("ep" . "+eshell-prompt"))
|
||||
;; read-symbol-shorthands: (("ep" . "eshell-prompt"))
|
||||
;; End:
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
'(child-frame-border ((t (:background "white"))))
|
||||
'(company-preview ((t (:foreground "wheat" :background "blue4"))))
|
||||
'(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-annotation ((t (:foreground "grey"))))
|
||||
'(company-tooltip-selection ((t (:background "grey31"))))
|
||||
|
||||
@@ -53,7 +53,7 @@ Returns a list of files with the directory preprended to them."
|
||||
(thread-last (+search/get-all-candidates)
|
||||
(cl-remove-if #'directory-name-p)
|
||||
(mapcar #'(lambda (x) (concat "\"" x "\" ")))
|
||||
(string-join)))
|
||||
string-join))
|
||||
|
||||
(defun +search/search-all ()
|
||||
(interactive)
|
||||
@@ -61,7 +61,7 @@ Returns a list of files with the directory preprended to them."
|
||||
(candidates (+search/-format-grep-candidates)))
|
||||
(thread-last candidates
|
||||
(format "grep --color=auto -nIHZe \"%s\" -- %s" term)
|
||||
(grep))
|
||||
grep)
|
||||
(next-error)))
|
||||
|
||||
(provide 'search)
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
(load bootstrap-file nil 'nomessage))
|
||||
|
||||
;; Setup benchmark to get current statistics - enable only if profiling.
|
||||
;; (straight-use-package 'benchmark-init)
|
||||
;; (require 'benchmark-init)
|
||||
;; (add-hook 'after-init-hook 'benchmark-init/deactivate)
|
||||
;; (benchmark-init/activate)
|
||||
(straight-use-package 'benchmark-init)
|
||||
(require 'benchmark-init)
|
||||
(add-hook 'after-init-hook 'benchmark-init/deactivate)
|
||||
(benchmark-init/activate)
|
||||
|
||||
(setq use-package-enable-imenu-support t
|
||||
use-package-always-demand nil
|
||||
@@ -77,6 +77,7 @@
|
||||
(+literate/load-config)
|
||||
|
||||
(when (daemonp)
|
||||
;; No need to lazy load this stuff
|
||||
(require 'general)
|
||||
(require 'evil)
|
||||
(require 'dired)
|
||||
@@ -86,7 +87,6 @@
|
||||
(require 'org)
|
||||
(require 'company)
|
||||
(require 'eshell)
|
||||
(require 'org)
|
||||
(require 'eglot))
|
||||
|
||||
(setq gc-cons-threshold (* 100 1024 1024) ; ~100MiB
|
||||
@@ -95,7 +95,8 @@
|
||||
;; FIXME: Problem with memory-report after running Emacs for a
|
||||
;; bit, causes a Lisp nesting error, so I just set it up really
|
||||
;; high so it doesn't reach that.
|
||||
max-lisp-eval-depth 999999)
|
||||
max-lisp-eval-depth 999999
|
||||
garbage-collection-messages t)
|
||||
|
||||
(provide 'init)
|
||||
;;; init.el ends here
|
||||
|
||||
Reference in New Issue
Block a user