(*)~changes

This commit is contained in:
2023-04-25 13:00:25 +01:00
parent 0d3c0b9d9c
commit 5dfa0b0c2a
9 changed files with 513 additions and 712 deletions

View File

@@ -3,7 +3,8 @@
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
'(safe-local-variable-values
(flycheck-mode . t))))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.

View File

@@ -184,9 +184,12 @@ any buffers in ~+oreo/keep-buffer~ and kills the rest.
#+end_src
* Aesthetics
General look and feel of Emacs (mostly disabling stuff I don't like).
** Custom theme
Load my custom "personal-primary" theme which is stored in the Emacs
lisp folder (look at [[file:elisp/personal-primary-theme.el][this file]]).
** Themes
*** Dark theme
My preferred dark theme is my own "personal-primary" theme which is
stored in the Emacs lisp folder (look at [[file:elisp/personal-primary-theme.el][this file]]). It tries to use
the primary colours for everything, leading to a colour -> meaning
relation.
I have an older version of this theme that uses a homogeneous colour
scheme ([[file:elisp/personal-theme.el][this file]])
@@ -199,6 +202,35 @@ scheme ([[file:elisp/personal-theme.el][this file]])
:config
(load-theme 'personal-primary t))
#+end_src
*** Light theme
I'm not very good at designing light themes as I don't really use
them. However they are necessary in high light situations where a
dark mode would strain the eyes too much. So I built a custom theme
on top of the default Emacs theme, "personal-light" (look at [[file:elisp/personal-light-theme.el][this
file]]).
I don't use it by default but I may need to switch between light and
dark easily, so here's a command to switch between them.
#+begin_src emacs-lisp
(use-package custom
:defer t
:straight nil
:commands +oreo/switch-theme
:init
(defvar +oreo/theme 'dark)
:config
(defun +oreo/switch-theme ()
(interactive)
(cond
((eq +oreo/theme 'dark)
(load-theme 'personal-light t)
(setq +oreo/theme 'light))
((eq +oreo/theme 'light)
(load-theme 'personal-primary t)
(setq +oreo/theme 'dark)))))
#+end_src
** Font size
Set font size to 140 if on my desktop (oldboy) or 175 if on my laptop
(spiderboy).
@@ -393,8 +425,8 @@ code.
;; General which key definitions for leaders
(general-def
:states '(normal motion)
"SPC" nil
"SPC ," '(nil :which-key "Local leader")
"SPC" 'nil
"\\" '(nil :which-key "Local leader")
"SPC c" '(nil :which-key "Code")
"SPC f" '(nil :which-key "File")
"SPC t" '(nil :which-key "Shell")
@@ -413,7 +445,7 @@ code.
(general-create-definer local-leader
:states '(normal motion)
:prefix "SPC ,")
:prefix "\\")
(general-create-definer code-leader
:states '(normal motion)
@@ -475,47 +507,46 @@ code.
*** Some binds in Emacs
Some bindings that I couldn't fit elsewhere easily.
#+begin_src emacs-lisp
(use-package emacs
:straight nil
:general
(general-def
"C-x d" #'delete-frame)
(use-package emacs
:straight nil
:general
(general-def
"C-x d" #'delete-frame)
(nmmap
"C--" #'text-scale-decrease
"C-=" #'text-scale-increase)
(nmmap
"C--" #'text-scale-decrease
"C-=" #'text-scale-increase)
(leader
"SPC" '(execute-extended-command :which-key "M-x")
"'" '(browse-url-emacs :which-key "Open url in Emacs")
"u" 'universal-argument
";" 'eval-expression
":" `(,(proc (interactive) (switch-to-buffer "*scratch*"))
:which-key "Switch to *scratch*")
"!" '(async-shell-command :which-key "Async shell command")
"h" '(help-command :which-key "Help"))
(leader
"SPC" '(execute-extended-command :which-key "M-x")
"'" '(browse-url-emacs :which-key "Open url in Emacs")
"u" 'universal-argument
";" 'eval-expression
":" `(,(proc (interactive) (switch-to-buffer "*scratch*"))
:which-key "Switch to *scratch*")
"!" '(async-shell-command :which-key "Async shell command")
"h" '(help-command :which-key "Help"))
(code-leader
"j" #'next-error
"k" #'previous-error
"c" #'compile
"C" #'recompile
"F" (list (proc (interactive) (find-file "~/Code/")) ':which-key "Open ~/Code/"))
(mode-leader
"t" #'+oreo/switch-theme)
(file-leader
"f" #'find-file
"F" #'find-file-other-frame
"s" #'save-buffer
"p" (list (proc (interactive) (find-file (concat user-emacs-directory "config.org")))
':which-key "Open config.org"))
(code-leader
"F" (list (proc (interactive) (find-file "~/Code/")) ':which-key "Open ~/Code/"))
(quit-leader
"q" #'save-buffers-kill-terminal
"c" #'+literate/compile-config
"l" #'+literate/load-config
"d" #'delete-frame)
(file-leader
"f" #'find-file
"F" #'find-file-other-frame
"s" #'save-buffer
"p" (list (proc (interactive) (find-file (concat user-emacs-directory "config.org")))
':which-key "Open config.org"))
(search-leader "i" #'imenu))
(quit-leader
"q" #'save-buffers-kill-terminal
"c" #'+literate/compile-config
"l" #'+literate/load-config
"d" #'delete-frame)
(search-leader "i" #'imenu))
#+end_src
** Evil
My editor journey started off with Vim rather than Emacs, so my brain
@@ -698,7 +729,7 @@ Setup for counsel. Load after ivy and helpful.
[remap describe-bindings] #'counsel-descbinds
[remap load-theme] #'counsel-load-theme)
:config
(setq ivy-initial-inputs-alist nil
(setq ivy-initial-inputs-alist '((org-insert-link . "^"))
counsel-describe-function-function #'helpful-callable
counsel-describe-variable-function #'helpful-variable
counsel-grep-swiper-limit 1500000
@@ -1000,36 +1031,27 @@ with abstracting a few things away.
(prog-mode-hook . abbrev-mode)
(text-mode-hook . abbrev-mode)
:init
(defmacro +autotyping/deff-abbrev (ABBREV-TABLE ABBREV EXPANSION)
"Wraps around define-abbrev to fill in some repeated stuff
when expansion is a function."
`(define-abbrev
,ABBREV-TABLE
,ABBREV
""
(proc (insert ,EXPANSION))))
(defmacro +abbrev/define-abbrevs (abbrev-table &rest abbrevs)
`(progn
,@(mapcar #'(lambda (abbrev)
`(define-abbrev
,abbrev-table
,(car abbrev)
""
(proc (insert ,(cadr abbrev)))))
abbrevs)))
(setq save-abbrevs nil)
:config
(+autotyping/deff-abbrev
(+abbrev/define-abbrevs
global-abbrev-table
"sdate"
(format-time-string "%Y-%m-%d" (current-time)))
(+autotyping/deff-abbrev
global-abbrev-table
"stime"
(format-time-string "%H:%M:%S" (current-time)))
(+autotyping/deff-abbrev
text-mode-abbrev-table
"sday"
(format-time-string "%A" (current-time)))
(+autotyping/deff-abbrev
text-mode-abbrev-table
"smon"
(format-time-string "%B" (current-time))))
("sdate"
(format-time-string "%Y-%m-%d" (current-time)))
("stime"
(format-time-string "%H:%M:%S" (current-time)))
("sday"
(format-time-string "%A" (current-time)))
("smon"
(format-time-string "%B" (current-time)))))
#+end_src
*** Skeletons
Defining some basic skeletons and a macro to help generate an abbrev
@@ -1225,8 +1247,9 @@ setups for programming without heavier packages like [[*Eglot][Eglot]].
Highlights the current line, much better than a blinking cursor.
#+begin_src emacs-lisp
(use-package hl-line
:defer t
:hook (text-mode-hook . hl-line-mode))
:straight t
:hook (text-mode-hook . hl-line-mode)
:hook (prog-mode-hook . hl-line-mode))
#+end_src
** Recentf
Recentf provides a method of keeping track of recently opened files.
@@ -2009,9 +2032,6 @@ don't need to write everything myself.
(display-buffer-same-window))
:general
(leader "g" '(magit-status :which-key "Magit"))
(nmmap
:keymaps 'magit-status-mode-map
"TAB" #'magit-section-toggle)
:init
(setq vc-follow-symlinks t)
(with-eval-after-load "autoinsert"
@@ -2197,7 +2217,12 @@ flyspell-mode should be hooked to text-mode.
(nmmap
:keymaps 'text-mode-map
(kbd "M-C") #'flyspell-correct-word-before-point
(kbd "M-c") #'flyspell-auto-correct-word))
(kbd "M-c") #'flyspell-auto-correct-word)
(local-leader
:keymaps 'flyspell-mode-map
"S" #'flyspell-region)
(mode-leader
"s" #'flyspell-mode))
#+end_src
*** Undo tree
Undo tree sits on top of the incredible Emacs undo capabilities.
@@ -2274,6 +2299,19 @@ context and easier to use.
(sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p))
(require 'smartparens-config))
#+end_src
*** Thesaurus
=le-thesaurus= is a great extension for quickly searching up words for
synonyms or antonyms. I may need it anywhere so I bind it to all
keymaps.
#+begin_src emacs-lisp
(use-package le-thesaurus
:straight t
:general
(local-leader
:keymaps 'override
"[" #'le-thesaurus-get-synonyms
"]" #'le-thesaurus-get-antonyms))
#+end_src
* Programming modes
Packages that help with programming in general, providing IDE like
capabilities.
@@ -2375,7 +2413,8 @@ I hook it to prog-mode.
:init
(setq hl-todo-keyword-faces
'(("TODO" . "#E50000")
("WAIT" . "#00CC00")
("WIP" . "#ffa500")
("NOTE" . "#00CC00")
("FIXME" . "#d02090"))))
#+end_src
** Hide-show mode
@@ -2398,6 +2437,385 @@ I give won't do it justice.
:hook
(prog-mode-hook . aggressive-indent-mode))
#+end_src
* Org mode
2023-03-30: finally decided to give org mode its own section.
Org is, at its most basic, a markup language. Files use the ".org"
extension and use =org-mode= to write text, with the ability to export
to a few formats, all within Emacs. However, this is a massive
disservice to its incredible capabilities:
+ Complete spreadsheet system, with formulas (including
[[*Calculator][calc-mode]] integration)
+ Evaluation of code blocks, even using the results of them in exports
(to, say, a $\LaTeX$ or HTML document)
+ This includes exporting all code blocks of a document to a code
file, say all the emacs-lisp files in this document to ~config.el~
([[file:elisp/literate.el][literate]])
+ Complete calendar/todo system with deadlines, scheduling and
repeaters
+ Export to a variety of formats or make your own export engine using
the org AST!
+ Writing latex in document, with ability to render them on demand,
and exporting to PDFs through Latex
** Aesthetic defaults
Org has a ton of settings to tweak, which change your experience quite
a bit. My setup should be as portable as possible and (/sometimes/) I
need to access org mode files in other editors, so org files should be
as close to clear text as possible. This is the guiding philosophy
that essentially makes most of my options pretty immediate.
Some arbitrary notes:
+ By default =~/Text= is my directory for text files. I actually have
a repository that manages this directory for agenda files and other
documents
+ Indentation in file should not be allowed, i.e. text indentation,
as that forces other editors to read it a certain way as well. It
seems obtrusive hence it's off.
+ Org startup indented is on by default as most documents do benefit
from the indentation, but I do turn it off for some files via
~#+startup:noindent~
+ When opening an org document there can be a lot of headings, so I
set folding to just content
+ Org documents can also have a lot of latex previews, which make
opening some after a while a massive hassle. If I want to see the
preview, I'll do it myself, so turn it off.
+ Org manages windowing itself, to some extent, so I set those options
to be as unobtrusive as possible
#+begin_src emacs-lisp
(use-package org
:defer t
:straight t
:init
(setq
org-directory "~/Text"
org-adapt-indentation nil
org-indent-mode nil
org-startup-indented t
org-startup-folded 'content
org-startup-with-latex-preview nil
org-imenu-depth 10
org-src-window-setup 'current-window
org-indirect-buffer-display 'current-window
org-link-frame-setup '((vm . vm-visit-folder-other-frame)
(vm-imap . vm-visit-imap-folder-other-frame)
(file . find-file))))
#+end_src
** Latex options
Org mode has deep integration with latex, can export to PDF and even
display latex fragments in the document directly. I setup the
pdf-process, code listing options via minted and the format options
for latex fragments.
#+begin_src emacs-lisp
(use-package org
:defer t
:init
(setq org-format-latex-options '(:foreground default :background default :scale 2
:html-foreground "Black" :html-background "Transparent"
:html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))
org-latex-listings 'minted
org-latex-minted-langs '((emacs-lisp "common-lisp")
(ledger "text")
(cc "c++")
(cperl "perl")
(shell-script "bash")
(caml "ocaml"))
org-latex-packages-alist '(("" "minted"))
org-latex-pdf-process
'("latexmk -pdfxe -bibtex -f -shell-escape %f")
org-latex-minted-options '(("style" "colorful")
("linenos")
("frame" "single")
("mathescape")
("fontfamily" "courier")
("samepage" "false")
("breaklines" "true")
("breakanywhere" "true"))))
#+end_src
** Org Core Variables
Tons of variables for org-mode, including a ton of latex ones. Can't
really explain because it sets up quite a lot of local stuff. Also I
copy pasted the majority of this, tweaking it till it felt good. Doom
Emacs was very helpful here.
#+begin_src emacs-lisp
(use-package org
:init
(setq org-edit-src-content-indentation 0
org-goto-interface 'outline
org-imenu-depth 10
org-export-backends '(ascii html latex odt icalendar)
org-eldoc-breadcrumb-separator ""
org-enforce-todo-dependencies t
org-fontify-quote-and-verse-blocks t
org-fontify-whole-heading-line t
org-footnote-auto-label t
org-hide-leading-stars t
org-hide-emphasis-markers nil
org-image-actual-width nil
org-priority-faces '((?A . error) (?B . warning) (?C . success))
org-link-descriptive nil
org-tags-column 0
org-todo-keywords
'((sequence "TODO" "WIP" "DONE")
(sequence "PROJ" "WAIT" "COMPLETE"))
org-use-sub-superscripts '{}
org-babel-load-languages '((emacs-lisp . t)
(lisp . t)
(C . t)
(python . t)
(shell . t))))
#+end_src
** Org Core Functionality
Hooks, prettify-symbols and records for auto insertion.
#+begin_src emacs-lisp
(use-package org
:hook
(org-mode-hook . prettify-symbols-mode)
:display
("\\*Org Src.*"
(display-buffer-same-window))
:pretty
(org-mode-hook
("#+begin_src" . "")
("#+end_src" . ""))
:init
(with-eval-after-load "autoinsert"
(define-auto-insert '("\\.org\\'" . "Org skeleton")
'("Enter title: "
"#+title: " str | (buffer-file-name) "\n"
"#+author: " (read-string "Enter author: ") | user-full-name "\n"
"#+description: " (read-string "Enter description: ") | "Description" "\n"
"#+date: " (format-time-string "%Y-%m-%d" (current-time)) "\n"
"* " _))))
#+end_src
** Org Core Bindings
Some bindings for org mode.
#+begin_src emacs-lisp
(use-package org
:after counsel
:config
(defun +org/swiper-goto ()
(interactive)
(swiper "^\\* "))
:general
(file-leader
"w" #'org-capture
"l" #'org-store-link
"i" #'org-insert-last-stored-link)
(code-leader
"D" #'org-babel-detangle)
(nmmap
:keymaps 'org-mode-map
[remap imenu] #'+org/swiper-goto)
(local-leader
:keymaps 'org-mode-map
"l" '(nil :which-key "Links")
"'" '(nil :which-key "Tables")
"c" '(nil :which-key "Clocks"))
(local-leader
:keymaps 'org-mode-map
:infix "l"
"i" #'org-insert-link
"l" #'org-open-at-point)
(local-leader
:keymaps 'org-mode-map
:infix "'"
"a" #'org-table-align
"f" #'org-table-edit-formulas
"t" #'org-table-toggle-coordinate-overlays
"s" #'org-table-sum
"e" #'org-table-calc-current-TBLFM
"E" #'org-table-eval-formula)
(local-leader
:keymaps 'org-mode-map
"i" #'org-clock-clock-in
"o" #'org-clock-clock-out
"c" #'org-clock-in-last
"d" #'org-clock-display)
(local-leader
:keymaps 'org-mode-map
"d" #'org-date-from-calendar
"t" #'org-todo
"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))
#+end_src
** Agenda
Org agenda provides a nice viewing for schedules. With org mode it's
a very tidy way to manage your time.
#+begin_src emacs-lisp
(use-package org-agenda
:after org
:straight nil
:init
(defconst +org/agenda-root "~/Text"
"Root directory for all agenda files")
(setq org-agenda-files (list (expand-file-name +org/agenda-root))
org-agenda-window-setup 'current-window
org-agenda-skip-deadline-prewarning-if-scheduled t
org-agenda-skip-scheduled-if-done t
org-agenda-skip-deadline-if-done t
org-agenda-start-with-entry-text-mode nil)
:config
(evil-set-initial-state 'org-agenda-mode 'normal)
:general
(file-leader
"a" `(,(proc (interactive)
(find-file (completing-read "Enter directory: " org-agenda-files nil t)))
:which-key "Open agenda directory"))
(app-leader
"a" #'org-agenda)
(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
"J" #'org-agenda-later
"K" #'org-agenda-earlier
"t" #'org-agenda-todo
"." #'org-agenda-goto-today
"," #'org-agenda-goto-date
"q" #'org-agenda-quit
"r" #'org-agenda-redo))
#+end_src
** Org clock-in
Org provides a nice timekeeping system that allows for managing how
much time is taken per task. It even has an extensive reporting
system to see how much time you spend on specific tasks or overall.
#+begin_src emacs-lisp
(use-package org-clock
:after org
:straight nil
:init
(defvar +org/clock-out-toggle-report nil
"Non-nil means update the first clock report in the file every
time a clock out occurs.")
:config
(advice-add #'org-clock-out
:after
(proc (interactive)
(if +org/clock-out-toggle-report
(org-clock-report t))))
:general
(local-leader
:keymaps 'org-mode-map
:infix "c"
"c" #'org-clock-in
"o" #'org-clock-out
"r" #'org-clock-report
"t" (proc (interactive)
(setq-local +org/clock-out-toggle-report
(not +org/clock-out-toggle-report)))))
#+end_src
** Org on save
If ~+org/compile-to-pdf-on-save-p~ is non-nil, then compile to
\(\LaTeX\) and run an async process to compile it to a PDF. Doesn't
make Emacs hang (like ~org-latex-export-to-pdf~) and doesn't randomly
crash (like the async handler for org-export). Works really well with
~pdf-view-mode~.
#+begin_src emacs-lisp
(use-package org
:defer t
:init
(defvar +org/compile-to-pdf-on-save-p
nil
"Non-nil to activate compile functionality.")
:general
(local-leader
:keymaps 'org-mode-map
"C" (proc (interactive)
(if (+org/compile-to-pdf-on-save-f)
(setq-local +org/compile-to-pdf-on-save-p nil)
(setq-local +org/compile-to-pdf-on-save-p t))))
:config
(+oreo/create-auto-save
(and (eq major-mode 'org-mode) +org/compile-to-pdf-on-save-p)
(start-process-shell-command "" "*pdflatex*" (concat "pdflatex -shell-escape "
(org-latex-export-to-latex)))))
#+end_src
** Org ref
#+begin_src emacs-lisp
(use-package org-ref
:straight t
:defer t
:init
(setq bibtex-files '("~/Text/bibliography.bib")
bibtex-completion-bibliography '("~/Text/bibliography.bib")
bibtex-completion-additional-search-fields '(keywords)))
#+end_src
*** Org ref ivy integration
Org ref requires ivy-bibtex to work properly with ivy, so we need to
set that up as well
#+begin_src emacs-lisp
(use-package ivy-bibtex
:straight t
:after org-ref
:config
(require 'org-ref-ivy))
#+end_src
** Org message
Org message allows for the use of org mode when composing mails,
generating HTML multipart emails. This integrates the WYSIWYG
experience with mail in Emacs while also providing powerful text
features with basically no learning curve (as long as you've already
learnt the basics of org).
#+begin_src emacs-lisp
(use-package org-msg
:hook (message-mode-hook . org-msg-mode)
:config
(setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng"
org-msg-greeting-name-limit 3)
(add-to-list 'org-msg-enforce-css
'(img latex-fragment-inline
((transform . ,(format "translateY(-1px) scale(%.3f)"
(/ 1.0 (if (boundp 'preview-scale)
preview-scale 1.4))))
(margin . "0 -0.35em")))))
#+end_src
** Org for evil
Evil org for some nice bindings.
#+begin_src emacs-lisp
(use-package evil-org
:hook (org-mode-hook . evil-org-mode))
#+end_src
** Org reveal
Org reveal allows one to export org files as HTML presentations via
reveal.js. Pretty nifty and it's easy to use.
#+begin_src emacs-lisp
(use-package ox-reveal
:defer t
:init
(setq org-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js"
org-reveal-theme "sky"))
#+end_src
** Org fragtog
Toggle latex fragments in org mode so you get fancy maths symbols. I
use latex a bit in org mode as it is the premier way of getting
mathematical symbols rendered, but org mode > latex.
Delimited environments are aplenty, escaped brackets and dollar signs
are my favourite. Here's a snippet:
$\int_{-\infty}^{\infty}e^{-x^2}dx = \sqrt{\pi}$.
#+begin_src emacs-lisp
(use-package org-fragtog
:hook (org-mode-hook . org-fragtog-mode))
#+end_src
** Org superstar
Org superstar adds cute little Unicode symbols for headers, much
better than the default asterisks.
#+begin_src emacs-lisp
(use-package org-superstar
:hook (org-mode-hook . org-superstar-mode))
#+end_src
* Languages
Configuration for specific languages or file formats.
** PDF
@@ -2481,304 +2899,6 @@ the [[https://elpa.gnu.org/packages/nhexl-mode.html][page]] yourself.
:straight t
:mode "\\.bin")
#+end_src
** Org
Org mode
*** Org Core Variables
Tons of variables for org-mode, including a ton of latex ones. Can't
really explain because it sets up quite a lot of local stuff. Also I
copy pasted the majority of this, tweaking it till it felt good. Doom
Emacs was very helpful here.
#+begin_src emacs-lisp
(use-package org
:defer t
:custom
(org-directory "~/Text")
(org-edit-src-content-indentation 0)
(org-goto-interface 'outline)
(org-adapt-indentation nil)
(org-indent-mode nil)
(org-src-window-setup 'current-window)
(org-indirect-buffer-display 'current-window)
(org-export-backends '(ascii html latex odt icalendar))
(org-imenu-depth 10)
(org-link-frame-setup '((vm . vm-visit-folder-other-frame)
(vm-imap . vm-visit-imap-folder-other-frame)
(gnus . org-gnus-no-new-news)
(file . find-file-other-frame)
(wl . wl-other-frame)))
(org-eldoc-breadcrumb-separator "")
(org-enforce-todo-dependencies t)
(org-fontify-quote-and-verse-blocks t)
(org-fontify-whole-heading-line t)
(org-footnote-auto-label 'plain)
(org-hide-leading-stars t)
(org-hide-emphasis-markers nil)
(org-image-actual-width nil)
(org-priority-faces '((?A . error) (?B . warning) (?C . success)))
(org-startup-indented t)
(org-startup-with-latex-preview t)
(org-startup-folded 'content)
(org-tags-column 0)
(org-todo-keywords
'((sequence "TODO" "DONE")
(sequence "PROJ" "WAIT" "COMPLETE")))
(org-use-sub-superscripts '{})
(org-babel-load-languages '((emacs-lisp . t)
(lisp . t)
(C . t)
(python . t)
(shell . t)))
(org-format-latex-options '(:foreground default :background default :scale 2
:html-foreground "Black" :html-background "Transparent"
:html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")))
(org-latex-listings 'minted)
(org-latex-minted-langs '((emacs-lisp "common-lisp")
(ledger "text")
(cc "c++")
(cperl "perl")
(shell-script "bash")
(caml "ocaml")))
(org-latex-packages-alist '(("" "minted")))
(org-latex-pdf-process
'("latexmk -pdfxe -bibtex -f -shell-escape %f"))
(setq org-latex-minted-options '(("style" "colorful")
("linenos")
("frame" "single")
("mathescape")
("fontfamily" "courier")
("samepage" "false")
("breaklines" "true")
("breakanywhere" "true")
)))
#+end_src
*** Org Core Functionality
Hooks, prettify-symbols and records for auto insertion.
#+begin_src emacs-lisp
(use-package org
:hook
(org-mode-hook . prettify-symbols-mode)
:display
("\\*Org Src.*"
(display-buffer-same-window))
:pretty
(org-mode-hook
("#+begin_src" . "")
("#+end_src" . ""))
:init
(with-eval-after-load "autoinsert"
(define-auto-insert '("\\.org\\'" . "Org skeleton")
'("Enter title: "
"#+title: " str | (buffer-file-name) "\n"
"#+author: " (read-string "Enter author: ") | user-full-name "\n"
"#+description: " (read-string "Enter description: ") | "Description" "\n"
"#+date: " (format-time-string "%Y-%m-%d" (current-time)) "\n"
"* " _))))
#+end_src
*** Org Core Bindings
Some bindings for org mode.
#+begin_src emacs-lisp
(use-package org
:after counsel
:config
(defun +org/swiper-goto ()
(interactive)
(swiper "^\\* "))
:general
(file-leader
"w" #'org-capture
"l" #'org-store-link
"i" #'org-insert-last-stored-link)
(code-leader
"D" #'org-babel-detangle)
(nmmap
:keymaps 'org-mode-map
[remap imenu] #'+org/swiper-goto)
(local-leader
:keymaps 'org-mode-map
:infix "l"
"i" #'org-insert-link
"l" #'org-open-at-point)
(local-leader
:keymaps 'org-mode-map
:infix "'"
"a" #'org-table-align
"f" #'org-table-edit-formulas
"t" #'org-table-toggle-coordinate-overlays
"s" #'org-table-sum
"e" #'org-table-eval-formula)
(local-leader
:keymaps 'org-mode-map
"t" #'org-todo
"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))
#+end_src
*** Org agenda
Org agenda provides a nice viewing for schedules. With org mode it's
a very tidy way to manage your time.
#+begin_src emacs-lisp
(use-package org-agenda
:after (org evil)
:straight nil
:init
(defconst +org/agenda-root "~/Text"
"Root directory for all agenda files")
(setq org-agenda-files (list (expand-file-name +org/agenda-root) (expand-file-name "~/Projects/lpv/"))
org-agenda-window-setup 'current-window
org-agenda-skip-deadline-prewarning-if-scheduled t
org-agenda-skip-scheduled-if-done t
org-agenda-skip-deadline-if-done t
org-agenda-start-with-entry-text-mode nil)
:config
(evil-set-initial-state 'org-agenda-mode 'normal)
:general
(file-leader
"a" `(,(proc (interactive)
(find-file (completing-read "Enter directory: " org-agenda-files nil t)))
:which-key "Open agenda directory"))
(app-leader
"aa" #'org-agenda)
(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
"J" #'org-agenda-later
"K" #'org-agenda-earlier
"t" #'org-agenda-todo
"." #'org-agenda-goto-today
"," #'org-agenda-goto-date
"q" #'org-agenda-quit
"r" #'org-agenda-redo))
#+end_src
*** Org clock-in
Org provides a nice timekeeping system that allows for managing how
much time is taken per task. It even has an extensive reporting
system to see how much time you spend on specific tasks or overall.
#+begin_src emacs-lisp
(use-package org-clock
:after org
:straight nil
:init
(defvar +org/clock-out-toggle-report nil
"Non-nil means update the first clock report in the file every
time a clock out occurs.")
:config
(advice-add #'org-clock-out
:after
(proc (interactive)
(if +org/clock-out-toggle-report
(org-clock-report t))))
:general
(local-leader
:keymaps 'org-mode-map
:infix "c"
"c" #'org-clock-in
"o" #'org-clock-out
"r" #'org-clock-report
"t" (proc (interactive)
(setq-local +org/clock-out-toggle-report
(not +org/clock-out-toggle-report)))))
#+end_src
*** Org on save
If ~+org/compile-to-pdf-on-save-p~ is non-nil, then compile to
\(\LaTeX\) and run an async process to compile it to a PDF. Doesn't
make Emacs hang (like ~org-latex-export-to-pdf~) and doesn't randomly
crash (like the async handler for org-export). Works really well with
~pdf-view-mode~.
#+begin_src emacs-lisp
(use-package org
:defer t
:init
(defvar +org/compile-to-pdf-on-save-p
nil
"Non-nil to activate compile functionality.")
:general
(local-leader
:keymaps 'org-mode-map
"C" (proc (interactive)
(if (+org/compile-to-pdf-on-save-f)
(setq-local +org/compile-to-pdf-on-save-p nil)
(setq-local +org/compile-to-pdf-on-save-p t))))
:config
(+oreo/create-auto-save
(and (eq major-mode 'org-mode) +org/compile-to-pdf-on-save-p)
(start-process-shell-command "" "*pdflatex*" (concat "pdflatex -shell-escape "
(org-latex-export-to-latex)))))
#+end_src
*** Org ref
#+begin_src emacs-lisp
(use-package org-ref
:straight t
:defer t
:init
(setq bibtex-files '("~/Text/bibliography.bib")
bibtex-completion-bibliography '("~/Text/bibliography.bib")
bibtex-completion-additional-search-fields '(keywords)))
#+end_src
*** Org message
Org message allows for the use of org mode when composing mails,
generating HTML multipart emails. This integrates the WYSIWYG
experience with mail in Emacs while also providing powerful text
features with basically no learning curve (as long as you've already
learnt the basics of org).
#+begin_src emacs-lisp
(use-package org-msg
:hook (message-mode-hook . org-msg-mode)
:config
(setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng"
org-msg-greeting-name-limit 3)
(add-to-list 'org-msg-enforce-css
'(img latex-fragment-inline
((transform . ,(format "translateY(-1px) scale(%.3f)"
(/ 1.0 (if (boundp 'preview-scale)
preview-scale 1.4))))
(margin . "0 -0.35em")))))
#+end_src
*** Org for evil
Evil org for some nice bindings.
#+begin_src emacs-lisp
(use-package evil-org
:hook (org-mode-hook . evil-org-mode))
#+end_src
*** Org reveal
Org reveal allows one to export org files as HTML presentations via
reveal.js. Pretty nifty and it's easy to use.
#+begin_src emacs-lisp
(use-package ox-reveal
:after org
:init
(setq org-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js"
org-reveal-theme "sky"))
#+end_src
*** Org fragtog
Toggle latex fragments in org mode so you get fancy maths symbols. I
use latex a bit in org mode as it is the premier way of getting
mathematical symbols rendered, but org mode > latex.
Delimited environments are aplenty, escaped brackets and dollar signs
are my favourite. Here's a snippet:
$\int_{-\infty}^{\infty}e^{-x^2}dx = \sqrt{\pi}$.
#+begin_src emacs-lisp
(use-package org-fragtog
:hook (org-mode-hook . org-fragtog-mode))
#+end_src
*** Org superstar
Org superstar adds cute little Unicode symbols for headers, much
better than the default asterisks.
#+begin_src emacs-lisp
(use-package org-superstar
:hook (org-mode-hook . org-superstar-mode))
#+end_src
** C/C++
Setup for C and C++ modes via the cc-mode package. C and C++ are
great languages for general purpose programming. My preferred choice
@@ -2998,10 +3118,15 @@ Just setup a style and some pretty symbols.
** Haskell
Haskell is a static lazy functional programming language (what a
mouthful). It's quite a beautiful language and really learning it will
change the way you think about programming.
change the way you think about programming. However, my preferred
functional language is still unfortunately Lisp so no extra brownie
points there.
Here I configure the REPL for Haskell via the
~haskell-interactive-mode~ as well.
~haskell-interactive-mode~. I also load my custom package
[[file:elisp/haskell-multiedit.el][haskell-multiedit]] which allows a user to create temporary
~haskell-mode~ buffers that, upon completion, will run in the REPL.
Even easier than making your own buffer.
#+begin_src emacs-lisp
(use-package haskell-mode
:hook
@@ -3150,7 +3275,8 @@ development on Emacs.
"s" #'+shell/toggle-sly
"c" #'sly-compile-file
"a" #'sly-apropos
"d" #'sly-describe-symbol)
"d" #'sly-describe-symbol
"E" #'sly-eval-defun)
(local-leader
:keymaps 'lisp-mode-map
:infix "e"

View File

@@ -22,9 +22,9 @@
;; To be used in a haskell-interactive-mode buffer. It'll generate a
;; new buffer with haskell-mode and this minor mode activated. Once
;; finished with the code, using another keybind it'll close this
;; buffer and paste the code into haskell-interactive-mode, evaluating
;; it all line by line with indenting and multi-line guards.
;; finished with the code, using another keybind to close the buffer
;; and paste the code into haskell-interactive-mode, evaluating it all
;; line by line with indenting and multi-line guards.
;;; Code:
@@ -59,8 +59,7 @@ full multi-edit commands"
(haskell-interactive-mode-return)))
(define-key haskell-interactive-mode-map (kbd "C-c '") #'haskell-multiedit)
(define-key haskell-multiedit-mode-map (kbd "C-c '") #'haskell-multiedit-evaluate-at-repl)
)
(define-key haskell-multiedit-mode-map (kbd "C-c '") #'haskell-multiedit-evaluate-at-repl))
(provide 'haskell-multiedit)
;;; haskell-interactive-multiedit.el ends here

View File

@@ -1,61 +0,0 @@
(deftheme monokai
"Created 2021-03-10.")
(custom-theme-set-faces
'monokai
'(cursor ((t (:background "white"))))
'(fixed-pitch ((t (:family "Monospace"))))
'(variable-pitch ((((type w32)) (:foundry "outline" :family "Arial")) (t (:family "Sans Serif"))))
'(escape-glyph ((((background dark)) (:foreground "cyan")) (((type pc)) (:foreground "magenta")) (t (:foreground "brown"))))
'(homoglyph ((((background dark)) (:foreground "cyan")) (((type pc)) (:foreground "magenta")) (t (:foreground "brown"))))
'(minibuffer-prompt ((t (:foreground "#fd971f"))))
'(highlight ((t (:background "firebrick4" :foreground "white"))))
'(region ((t (:extend t :background "#4e4e4e"))))
'(shadow ((t (:foreground "#555556"))))
'(secondary-selection ((t (:extend t :background "#525254"))))
'(trailing-whitespace ((t (:background "#e74c3c"))))
'(font-lock-builtin-face ((t (:foreground "#fd971f"))))
'(font-lock-comment-delimiter-face ((t (:inherit font-lock-comment-face))))
'(font-lock-comment-face ((t (:foreground "#555556" :slant italic))))
'(font-lock-constant-face ((t (:inherit font-lock-variable-name-face))))
'(font-lock-doc-face ((t (:foreground "#7f7f80" :inherit (font-lock-comment-face)))))
'(font-lock-function-name-face ((t (:foreground "#b6e63e"))))
'(font-lock-keyword-face ((t (:foreground "#fb2874" :height 0.95 :family "Fira Code"))))
'(font-lock-negation-char-face ((t (:foreground "#9c91e4" :inherit (bold)))))
'(font-lock-preprocessor-face ((t (:foreground "#9c91e4" :inherit (bold)))))
'(font-lock-regexp-grouping-backslash ((t (:foreground "#9c91e4" :inherit (bold)))))
'(font-lock-regexp-grouping-construct ((t (:foreground "#9c91e4" :inherit (bold)))))
'(font-lock-string-face ((t (:foreground "yellow green"))))
'(font-lock-type-face ((t (:foreground "#66d9ef"))))
'(font-lock-variable-name-face ((t (:foreground "#fd971f"))))
'(font-lock-warning-face ((t (:inherit (warning)))))
'(button ((t (:inherit (link)))))
'(link ((t (:weight bold :underline (:color foreground-color :style line) :foreground "#fd971f"))))
'(link-visited ((t (:foreground "violet" :inherit (link)))))
'(fringe ((t (:foreground "#4e4e4e" :inherit (default)))))
'(header-line ((t (:foreground "#d6d6d4" :background "#1c1e1f"))))
'(tooltip ((t (:foreground "#d6d6d4" :background "#2d2e2e"))))
'(mode-line ((t (:box nil :background "#2d2e2e"))))
'(mode-line-buffer-id ((t (:weight bold))))
'(mode-line-emphasis ((t (:foreground "#fd971f"))))
'(mode-line-highlight ((t (:inherit (highlight)))))
'(mode-line-inactive ((t (:box nil :foreground "#4e4e4e" :background "#171819"))))
'(isearch ((t (:foreground "#1B2229" :background "#b6e63e"))))
'(isearch-fail ((t (:weight bold :foreground "#1B2229" :background "#e74c3c"))))
'(lazy-highlight ((t (:weight bold :foreground "#1B2229" :background "#9c91e4"))))
'(match ((t (:weight bold :foreground "#b6e63e" :background "#1B2229"))))
'(next-error ((t (:inherit (region)))))
'(query-replace ((t (:inherit (isearch)))))
'(outline-1 ((t (:foreground "#fb2874"))))
'(org-block ((t (:background "gray8"))))
'(ido-subdir ((t (:foreground "deepskyblue"))))
'(eshell-prompt ((t (:foreground "deepskyblue" :weight bold))))
'(company-tooltip-common ((((background light)) (:foreground "darkred")) (((background dark)) (:foreground "red"))))
'(company-tooltip ((t (:background "gray10" :foreground "white"))))
'(company-tooltip-selection ((t (:background "firebrick4"))))
'(org-quote ((t (:inherit org-block :slant italic :family "Liberation Mono"))))
'(org-verse ((t (:inherit org-block :slant oblique :family "Liberation Mono"))))
'(hl-line ((t (:extend t :background "gray9"))))
'(default ((t (:inherit nil :extend nil :stipple nil :background "black" :foreground "#d6d6d4" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :foundry "ADBO" :family "ibm plex mono")))))
(provide-theme 'monokai)

View File

@@ -16,7 +16,7 @@
'(region ((t (:extend t :background "gray25"))))
'(shadow ((((class color grayscale) (min-colors 88) (background light)) (:foreground "grey50")) (((class color grayscale) (min-colors 88) (background dark)) (:foreground "grey70")) (((class color) (min-colors 8) (background light)) (:foreground "green")) (((class color) (min-colors 8) (background dark)) (:foreground "yellow"))))
'(secondary-selection ((((class color) (min-colors 88) (background light)) (:extend t :background "yellow1")) (((class color) (min-colors 88) (background dark)) (:extend t :background "SkyBlue4")) (((class color) (min-colors 16) (background light)) (:extend t :background "yellow")) (((class color) (min-colors 16) (background dark)) (:extend t :background "SkyBlue4")) (((class color) (min-colors 8)) (:extend t :foreground "black" :background "cyan")) (t (:inverse-video t))))
'(trailing-whitespace ((((class color) (background light)) (:background "red1")) (((class color) (background dark)) (:background "red1")) (t (:inverse-video t))))
'(trailing-whitespace ((((class color) (background light)) (:background "red1")) (((class color) (background dark)) (:background "red1")))) ;;(t (:inverse-video t))))
'(font-lock-builtin-face ((t (:foreground "powder blue"))))
'(font-lock-comment-delimiter-face ((t (:slant italic :foreground "gray24"))))
'(font-lock-comment-face ((t (:slant italic :foreground "#868686"))))
@@ -58,6 +58,7 @@
'(eshell-prompt ((t (:foreground "deep sky blue" :weight bold))))
'(whitespace-tab ((t (:background "gray5" :foreground "gray20"))))
'(whitespace-space ((t (:background "gray2" :foreground "darkgray"))))
'(whitespace-line ((t (:background "black" :foreground "violet"))))
'(haskell-interactive-face-prompt ((t (:foreground "green"))))
'(org-verbatim ((t (:foreground "red3"))))
'(org-code ((t (:foreground "green3"))))

View File

@@ -1,64 +0,0 @@
(deftheme personal
"Created 2021-10-20.")
(custom-theme-set-faces
'personal
'(line-number ((t (:foreground "aquamarine1" :background "gray1"))))
'(cursor ((((background light)) (:background "black")) (((background dark)) (:background "white"))))
'(fixed-pitch ((t (:family "Monospace"))))
'(variable-pitch ((((type w32)) (:foundry "outline" :family "Arial")) (t (:family "Sans Serif"))))
'(escape-glyph ((((background dark)) (:foreground "cyan")) (((type pc)) (:foreground "magenta")) (t (:foreground "brown"))))
'(homoglyph ((((background dark)) (:foreground "cyan")) (((type pc)) (:foreground "magenta")) (t (:foreground "brown"))))
'(minibuffer-prompt ((((background dark)) (:foreground "cyan")) (((type pc)) (:foreground "magenta")) (t (:foreground "medium blue"))))
'(highlight ((t (:background "gray14"))))
'(region ((t (:extend t :background "gray25"))))
'(shadow ((((class color grayscale) (min-colors 88) (background light)) (:foreground "grey50")) (((class color grayscale) (min-colors 88) (background dark)) (:foreground "grey70")) (((class color) (min-colors 8) (background light)) (:foreground "green")) (((class color) (min-colors 8) (background dark)) (:foreground "yellow"))))
'(secondary-selection ((((class color) (min-colors 88) (background light)) (:extend t :background "yellow1")) (((class color) (min-colors 88) (background dark)) (:extend t :background "SkyBlue4")) (((class color) (min-colors 16) (background light)) (:extend t :background "yellow")) (((class color) (min-colors 16) (background dark)) (:extend t :background "SkyBlue4")) (((class color) (min-colors 8)) (:extend t :foreground "black" :background "cyan")) (t (:inverse-video t))))
'(trailing-whitespace ((((class color) (background light)) (:background "red1")) (((class color) (background dark)) (:background "red1")) (t (:inverse-video t))))
'(font-lock-builtin-face ((((class grayscale) (background light)) (:weight bold :foreground "LightGray")) (((class grayscale) (background dark)) (:weight bold :foreground "DimGray")) (((class color) (min-colors 88) (background light)) (:foreground "dark slate blue")) (((class color) (min-colors 88) (background dark)) (:foreground "LightSteelBlue")) (((class color) (min-colors 16) (background light)) (:foreground "Orchid")) (((class color) (min-colors 16) (background dark)) (:foreground "LightSteelBlue")) (((class color) (min-colors 8)) (:weight bold :foreground "blue")) (t (:weight bold))))
'(font-lock-comment-delimiter-face ((t (:slant italic :foreground "gray24"))))
'(font-lock-comment-face ((t (:slant italic :foreground "#868686"))))
'(font-lock-constant-face ((t (:foreground "slate blue" :weight semi-bold :height 0.99 :family "Source Code Pro"))))
'(font-lock-doc-face ((t (:inherit (font-lock-string-face)))))
'(font-lock-function-name-face ((t (:weight semi-bold))))
'(font-lock-keyword-face ((t (:foreground "DeepSkyBlue2" :weight bold :height 0.95 :family "Fira Code"))))
'(font-lock-negation-char-face ((t nil)))
'(font-lock-preprocessor-face ((t (:family "Source Code Pro" :foreground "#868686"))))
'(font-lock-regexp-grouping-backslash ((t (:inherit (bold)))))
'(font-lock-regexp-grouping-construct ((t (:inherit (bold)))))
'(font-lock-string-face ((t (:family "Fira Code" :foreground "yellow4"))))
'(font-lock-type-face ((t (:foreground "chartreuse" :family "Liberation Mono"))))
'(font-lock-variable-name-face ((t (:family "Source Code Variable" :foreground "#e6e6e6"))))
'(font-lock-warning-face ((t (:inherit (error)))))
'(button ((t (:inherit (link)))))
'(link ((t (:underline (:color foreground-color :style line) :foreground "cyan1"))))
'(link-visited ((t (:foreground "violet" :inherit (link)))))
'(fringe ((t (:background "grey4"))))
'(header-line ((t (:box nil :foreground "grey90" :background "grey20" :inherit (mode-line)))))
'(tooltip ((t (:foreground "black" :background "lightyellow" :inherit (variable-pitch)))))
'(mode-line ((t (:box (:line-width -1 :color nil :style released-button) :foreground "white" :background "black"))))
'(mode-line-buffer-id ((t (:weight bold))))
'(mode-line-emphasis ((t (:weight bold))))
'(mode-line-highlight ((((class color) (min-colors 88)) (:box (:line-width 2 :color "grey40" :style released-button))) (t (:inherit (highlight)))))
'(mode-line-inactive ((t (:weight light :box (:line-width -1 :color "grey40" :style nil) :foreground "grey30" :background "grey7" :inherit (mode-line)))))
'(isearch ((t (:foreground "brown4" :background "white"))))
'(isearch-fail ((((class color) (min-colors 88) (background light)) (:background "RosyBrown1")) (((class color) (min-colors 88) (background dark)) (:background "red4")) (((class color) (min-colors 16)) (:background "red")) (((class color) (min-colors 8)) (:background "red")) (((class color grayscale)) (:foreground "grey")) (t (:inverse-video t))))
'(lazy-highlight ((((class color) (min-colors 88) (background light)) (:background "paleturquoise")) (((class color) (min-colors 88) (background dark)) (:background "paleturquoise4")) (((class color) (min-colors 16)) (:background "turquoise3")) (((class color) (min-colors 8)) (:background "turquoise3")) (t (:underline (:color foreground-color :style line)))))
'(match ((((class color) (min-colors 88) (background light)) (:background "yellow1")) (((class color) (min-colors 88) (background dark)) (:background "RoyalBlue3")) (((class color) (min-colors 8) (background light)) (:foreground "black" :background "yellow")) (((class color) (min-colors 8) (background dark)) (:foreground "white" :background "blue")) (((type tty) (class mono)) (:inverse-video t)) (t (:background "gray"))))
'(next-error ((t (:inherit (region)))))
'(query-replace ((t (:inherit (isearch)))))
'(company-tooltip ((t (:background "navy blue" :foreground "white"))))
'(company-tooltip-selection ((t (:background "gray31"))))
'(company-tooltip-annotation ((t (:foreground "grey" :slant italic))))
'(company-preview ((((background light)) (:inherit (company-tooltip-selection company-tooltip))) (((background dark)) (:foreground "wheat" :background "blue4"))))
'(company-preview-common ((t (:inherit company-preview :foreground "grey"))))
'(org-block ((t (:background "gray3" :inherit shadow))))
'(eshell-prompt ((t (:foreground "deep sky blue" :weight bold))))
'(whitespace-tab ((t (:background "gray5" :foreground "gray20"))))
'(whitespace-space ((t (:background "gray2" :foreground "darkgray"))))
'(haskell-interactive-face-prompt ((t (:foreground "green"))))
'(org-verbatim ((t (:foreground "red3"))))
'(org-code ((t (:foreground "green3"))))
'(default ((t (:family "Source Code Pro" :foundry "ADBO" :width normal :height 113 :weight normal :slant normal :underline nil :overline nil :extend nil :strike-through nil :box nil :inverse-video nil :foreground "#b6b6b6" :background "#000000" :stipple nil :inherit nil)))))
(provide-theme 'personal)

View File

@@ -1,202 +0,0 @@
;;; profile-dotemacs.el --- Profile your Emacs init file
;; Copyright (C) 2010, 2012 David Engster
;; Author: David Engster <dengste@eml.cc>
;; This file is NOT part of GNU Emacs.
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License
;; as published by the Free Software Foundation; either version 2
;; of the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This is to easily profile your Emacs init file (or any other
;; script-like Emacs Lisp file, for that matter).
;; It will go over all sexp's (balanced expressions) in the file and
;; run them through `benchmark-run'. It will then show the file with
;; overlays applied in a way that let you easily find out which sexp's
;; take the most time. Since time is relative, it's not the absolute
;; value that counts but the percentage of the total running time.
;;
;; * All other sexp's with a percentage greater than
;; `profile-dotemacs-low-percentage' will be preceded by a
;; highlighted line, showing the results from `benchmark-run'.
;; Also, the more 'reddish' the background of the sexp, the more
;; time it needs.
;; * All other sexp's will be grayed out to indicate that their
;; running time is miniscule. You can still see the benchmark
;; results in the minibuffer by hovering over the sexp with the
;; mouse.
;; You can only benchmark full sexp's, so if you wrapped large parts
;; of your init file in some conditional clause, you'll have to remove
;; that for getting finer granularity.
;;; Usage:
;; Start emacs as follows:
;;
;; emacs -Q -l <PATH>/profile-dotemacs.el -f profile-dotemacs
;;
;; with <PATH> being the path to where this file resides.
;;; Caveats (thanks to Raffaele Ricciardi for reporting those):
;; - The usual `--debug-init' for debugging your init file won't work
;; with profile-dotemacs, so you'll have to call
;; `toggle-debug-on-error', either on the commandline or at the
;; beginning of your init file.
;; - `load-file-name' is nil when the init file is being loaded
;; by the profiler. This might matter if you perform the
;; bulk of initializations in a different file.
;; - Starting external shells like IELM or eshell in your init file
;; might mess with overlay creation, so this must not be done.
;;; Download:
;; You can always get the latest version from
;; http://randomsample.de/profile-dotemacs.el
;; Aryadev Chavali: customised for this emacs specifically.
;;; Code:
(require 'thingatpt)
(require 'benchmark)
;; User variables
(defvar profile-dotemacs-file "~/.config/emacs/init.el"
"File to be profiled.")
(defvar profile-dotemacs-low-percentage 3
"Percentage which should be considered low.
All sexp's with a running time below this percentage will be
grayed out.")
(defface profile-dotemacs-time-face
'((((background dark)) (:background "OrangeRed1"))
(t (:background "red3")))
"Background color to indicate percentage of total time.")
(defface profile-dotemacs-low-percentage-face
'((((background dark)) (:foreground "gray25"))
(t (:foreground "gray75")))
"Face for sexps below `profile-dotemacs-low-percentage'.")
(defface profile-dotemacs-highlight-face
'((((background dark)) (:background "blue"))
(t (:background "yellow")))
"Highlight face for benchmark results.")
;; Main function
(defun profile-dotemacs ()
"Load `profile-dotemacs-file' and benchmark its sexps."
(interactive)
(with-current-buffer (find-file-noselect profile-dotemacs-file t)
(setq buffer-read-only t) ;; just to be sure
(goto-char (point-min))
(let (start end results)
(while
(< (point)
(setq end (progn
(forward-sexp 1)
(point))))
(forward-sexp -1)
(setq start (point))
(add-to-list
'results
`(,start ,end
,(benchmark-run
(eval (sexp-at-point)))))
(goto-char end))
(profile-dotemacs-show-results results)
(switch-to-buffer (current-buffer)))))
;; Helper functions
(defun profile-dotemacs-show-results (results)
"Show timings from RESULTS in current buffer."
(let ((totaltime (profile-dotemacs-totaltime results))
current percentage ov)
(while results
(let* ((current (pop results))
(ov (make-overlay (car current) (cadr current)))
(current (car (last current)))
(percentage (/ (+ (car current) (nth 2 current))
totaltime))
col benchstr lowface)
(setq col
(profile-dotemacs-percentage-color
percentage
(face-background 'default)
(face-background 'profile-dotemacs-time-face)))
(setq percentage (round (* 100 percentage)))
(setq benchstr (profile-dotemacs-make-benchstr current))
(overlay-put ov 'help-echo benchstr)
(if (and (numberp profile-dotemacs-low-percentage)
(< percentage profile-dotemacs-low-percentage))
(overlay-put ov 'face 'profile-dotemacs-low-percentage-face)
(overlay-put ov 'before-string
(propertize benchstr
'face 'profile-dotemacs-highlight-face))
(overlay-put ov 'face
`(:background ,col)))))
(setq ov (make-overlay (1- (point-max)) (point-max)))
(overlay-put ov 'after-string
(propertize
(format "\n-----------------\nTotal time: %.2fs\n"
totaltime)
'face 'profile-dotemacs-highlight-face))))
(defun profile-dotemacs-totaltime (results)
"Calculate total time of RESULTS."
(let ((totaltime 0))
(mapc (lambda (x)
(let ((cur (car (last x))))
(setq totaltime (+ totaltime (car cur) (nth 2 cur)))))
results)
totaltime))
(defun profile-dotemacs-percentage-color (percent col-begin col-end)
"Calculate color according to PERCENT between COL-BEGIN and COL-END."
(let* ((col1 (color-values col-begin))
(col2 (color-values col-end))
(col
(mapcar (lambda (c)
(round
(+ (* (- 1 percent) (nth c col1))
(* percent (nth c col2)))))
'(0 1 2))))
(format "RGB:%04x/%04x/%04x"
(car col)
(nth 1 col)
(nth 2 col))))
(defun profile-dotemacs-make-benchstr (timings)
"Create descriptive benchmark string from TIMINGS."
(format
(concat
"<Percentage: %d ; "
"Time: %.2f ; "
"Number of GC: %d ; "
"Time for GC: %.2f>\n")
percentage
(car timings) (nth 1 timings) (nth 2 timings)))
;; profile-dotemacs.el ends here

View File

@@ -18,3 +18,5 @@ notmuch tag -inbox +jobs from:'*@jobs*' from:'*@indeed.com*'
notmuch tag -inbox +bank from:'*@*hsbc*' from:'*@*lloydsbank*'
notmuch tag +flagged from:'expiry@letsencrypt.org'
notmuch tag -inbox +unread +trading from:"noreply@trading212.com"

View File

@@ -48,7 +48,6 @@ let mapleader = ' '
"" Theming
colorscheme elflord
"" Dir Config