diff options
-rw-r--r-- | Emacs/.config/emacs/config.org | 449 |
1 files changed, 329 insertions, 120 deletions
diff --git a/Emacs/.config/emacs/config.org b/Emacs/.config/emacs/config.org index a5c4900..a6b39e0 100644 --- a/Emacs/.config/emacs/config.org +++ b/Emacs/.config/emacs/config.org @@ -820,58 +820,141 @@ intentionally built to be modular and switchable. rg-default-alias-fallback "all" rg-buffer-name "*ripgrep*")) #+end_src +* Applications +** Mail +*** Preamble +Mail is a funny thing; most people use it just for business or +advertising and it's come out of use in terms of personal +communication in the west for the most part (largely due to "social" +media applications). However, this isn't true for the open source and +free software movement who heavily use mail for communication. + +Integrating mail into Emacs helps as I can send source code and +integrate it into my workflow just a bit better. +*** Notmuch +#+begin_src emacs-lisp +(setq +mail/signature "---------------\nAryadev Chavali") +(defconst +mail/local-dir (concat user-emacs-directory ".mail/")) +(defun +mail/sync-mail () + "Sync mail via mbsync." + (interactive) + (start-process-shell-command "" nil "mbsync -a")) -(use-package evil-magit - :after magit) +(use-package notmuch + :commands notmuch + :general + (leader "am" #'notmuch) + :custom + ((notmuch-show-logo nil) + (mail-signature +mail/signature) + (mail-default-directory +mail/local-dir) + (mail-source-directory +mail/local-dir) + (message-signature +mail/signature) + (message-auto-save-directory +mail/local-dir) + (message-directory +mail/local-dir)) + :config + ;; sync mail after refresh + (advice-add #'notmuch-poll-and-refresh-this-buffer :before + #'+mail/sync-mail) + (evil-collection-notmuch-setup)) #+end_src -* Company -Company is the auto complete system I use. I don't like having heavy -setups for company, as it only makes it worse to use. In this case, -just setup some evil binds for company +*** Smtpmail #+begin_src emacs-lisp -(use-package company - :hook (prog-mode-hook . company-mode) - :bind (("C-SPC" . company-complete) - :map company-active-map - ("M-j" . company-select-next) - ("M-k" . company-select-previous))) +(use-package smtpmail + :commands mail-send + :after notmuch + :custom + ((smtpmail-smtp-server "mail.aryadevchavali.com") + (smtpmail-smtp-user "aryadev") + (smtpmail-smtp-service 587) + (smtpmail-stream-type 'starttls)) + :init + (setq send-mail-function #'smtpmail-send-it + message-send-mail-function #'smtpmail-send-it)) #+end_src -* Elfeed -Elfeed is the perfect RSS feed reader, integrated into Emacs -perfectly. I've got a set of feeds that I use for a large variety of -stuff, mostly media and entertainment. I've also bound "<leader> ar" -to elfeed for loading the system. +*** Org message +Org message allows for the use of org mode when composing mails, +generating HTML multipart emails. This integrates the WYSIWYG +experience into 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 elfeed - :general - (leader "ar" #'elfeed) - :init - (setq +rss/feed-urls - '(("Arch Linux" "https://www.archlinux.org/feeds/news/" Linux) - ("LEMMiNO" "https://www.youtube.com/feeds/videos.xml?channel_id=UCRcgy6GzDeccI7dkbbBna3Q" YouTube Stories) - ("Dark Sominium" "https://www.youtube.com/feeds/videos.xml?channel_id=UC_e39rWdkQqo5-LbiLiU10g" YouTube Stories) - ("Dark Sominium Music" "https://www.youtube.com/feeds/videos.xml?channel_id=UCkLiZ_zLynyNd5fd62hg1Kw" YouTube Music) - ("Nexpo" "https://www.youtube.com/feeds/videos.xml?channel_id=UCpFFItkfZz1qz5PpHpqzYBw" YouTube) - ("Techquickie" "https://www.youtube.com/feeds/videos.xml?channel_id=UC0vBXGSyV14uvJ4hECDOl0Q" YouTube) - ("Captain Sinbad" "https://www.youtube.com/feeds/videos.xml?channel_id=UC8XKyvQ5Ne_bvYbgv8LaIeg" YouTube) - ("3B1B" "https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw" YouTube) - ("Fredrik Knusden" "https://www.youtube.com/feeds/videos.xml?channel_id=UCbWcXB0PoqOsAvAdfzWMf0w" YouTube Stories) - ("Barely Sociable" "https://www.youtube.com/feeds/videos.xml?channel_id=UC9PIn6-XuRKZ5HmYeu46AIw" YouTube Stories) - ("Atrocity Guide" "https://www.youtube.com/feeds/videos.xml?channel_id=UCn8OYopT9e8tng-CGEWzfmw" YouTube Stories) - ("Philip Defranco" "https://www.youtube.com/feeds/videos.xml?channel_id=UClFSU9_bUb4Rc6OYfTt5SPw" YouTube News) - ("Hacker News" "http://morss.aryadevchavali.com/news.ycombinator.com/rss" Social) - ("Hacker Factor" "https://www.hackerfactor.com/blog/index.php?/feeds/index.rss2" Social) - ("BBC Top News" "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/rss.xml" News) - ("BBC Tech News" "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/technology/rss.xml" News))) - (setq elfeed-db-directory (concat user-emacs-directory "elfeed")) +(use-package org-msg + :after notmuch + :hook (message-mode-hook . org-msg-mode) :config - (evil-collection-elfeed-setup) - (evil-define-key 'normal elfeed-search-mode-map "gr" #'elfeed-update) - (evil-define-key 'normal elfeed-search-mode-map "s" #'elfeed-search-live-filter) - (evil-define-key 'normal elfeed-search-mode-map "<return>" #'elfeed-search-show-entry) - (setq elfeed-feeds (cl-map 'list #'(lambda (item) (append (list (nth 1 item)) (cdr (cdr item)))) +rss/feed-urls))) + (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" + org-msg-greeting-fmt "Dear %s,\n" + org-msg-greeting-name-limit 3 + org-msg-text-plain-alternative t) + + (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 +** Xwidget +*** Preamble +Xwidget is a package (that must be compiled at source) which allows +for the insertion of arbitrary xwidgets into Emacs through +buffers. One of its premier uses is in navigating the web which it +provides through the function =xwidget-webkit-browse-url=. This +renders a fully functional web browser within Emacs. + +Though I am not to keen on using Emacs to browse the web /via/ xwidget +(EWW does a good job on its own), I am very interested in its +capability to render full fledged HTML documents, as it may come of +use when doing web development. I can see the results of work very +quickly without switching windows or workspaces. +*** Core +Define a function =+xwidget/render-file= that reads a file name and +presents it in an xwidget. If the current file is an HTML file, ask if +user wants to open current file. Bind it to =au= in the leader. + +#+begin_src emacs-lisp + (use-package xwidget + :straight nil + :general + (leader "aU" #'xwidget-webkit-browse-url) + (general-def + :states 'normal + :keymaps 'xwidget-webkit-mode-map + "q" #'quit-window + "h" #'xwidget-webkit-scroll-backward + "j" #'xwidget-webkit-scroll-up + "k" #'xwidget-webkit-scroll-down + "l" #'xwidget-webkit-scroll-forward + (kbd "C-f") #'xwidget-webkit-scroll-up + (kbd "C-b") #'xwidget-webkit-scroll-down + "H" #'xwidget-webkit-back + "L" #'xwidget-webkit-forward + "gu" #'xwidget-webkit-browse-url + "gr" #'xwidget-webkit-reload + "gg" #'xwidget-webkit-scroll-top + "G" #'xwidget-webkit-scroll-bottom) + :config + (defun +xwidget/render-file (&optional FORCE) + "Find file (or use current file) and render in xwidget." + (interactive) + (cond + ((and (not FORCE) (or (string= (replace-regexp-in-string ".*.html" "html" (buffer-name)) + "html") + (eq major-mode 'web-mode) + (eq major-mode 'html-mode))) ; If in html file + (if (y-or-n-p "Open current file?: ") ; Maybe they want to open a separate file + (xwidget-webkit-browse-url (format "file://%s" (buffer-file-name))) + (+xwidget/render-file t))) ; recurse and open file via prompt + (t + (xwidget-webkit-browse-url (format "file://%s" (read-file-name "Enter file to open: ")))))) + + (leader "au" #'+xwidget/render-file)) #+end_src -* Eshell + +** Eshell +*** Preamble Eshell is the integrated shell environment for Emacs. Though it isn't necessarily *the best* shell, it really suits the 'integrated computing environment' moniker that Emacs gets. @@ -886,6 +969,7 @@ it's separation (or perhaps better phrased, *integration*) of two you can mix and match at will for use in the shell, which grants greater power than many shells I know of. +*** Configuration Setup a function that /toggles/ the eshell window rather than just opening it via =+dx/toggle-buffer=. @@ -896,55 +980,113 @@ just opening it via =+dx/toggle-buffer=. "tt" #'+shell/toggle-eshell) :init (setq eshell-cmpl-ignore-case t - eshell-cd-on-directory t) + eshell-cd-on-directory t) + (with-eval-after-load "prog-mode" + (+pretty/set-alist + eshell-mode-hook + ("lambda" . "λ") + ("numberp" . "ℤ") + ("t" . "𝕋") + ("nil" . "∅") + ("for" . "∀"))) :config - (defun +shell/toggle-eshell () - (interactive) - (+dx/toggle-buffer "*eshell*" #'eshell))) + (+dx/create-toggle-function +shell/toggle-eshell + "*eshell*" + eshell)) #+end_src -* Window management -Window management is really important. I find the default window -handling of Emacs incredibly annoying: sometimes consuming my windows, -sometimes creating new ones. So, as Emacs is the ultimate editor, I -want to configure and fine tune the window management of Emacs. +** Elfeed +Elfeed is the perfect RSS feed reader, integrated into Emacs +perfectly. I've got a set of feeds that I use for a large variety of +stuff, mostly media and entertainment. I've also bound "<leader> ar" +to elfeed for loading the system. +#+begin_src emacs-lisp +(use-package elfeed + :general + (leader "ar" #'elfeed) + (general-def + :states 'normal + :keymaps 'elfeed-search-mode-map + "gr" #'elfeed-update + "s" #'elfeed-search-live-filter + "<return>" #'elfeed-search-show-entry) + :init + (setq +rss/feed-urls + '(("Arch Linux" + "https://www.archlinux.org/feeds/news/" + Linux) + ("LEMMiNO" + "https://www.youtube.com/feeds/videos.xml?channel_id=UCRcgy6GzDeccI7dkbbBna3Q" + YouTube Stories) + ("Dark Sominium" + "https://www.youtube.com/feeds/videos.xml?channel_id=UC_e39rWdkQqo5-LbiLiU10g" + YouTube Stories) + ("Dark Sominium Music" + "https://www.youtube.com/feeds/videos.xml?channel_id=UCkLiZ_zLynyNd5fd62hg1Kw" + YouTube Music) + ("Nexpo" + "https://www.youtube.com/feeds/videos.xml?channel_id=UCpFFItkfZz1qz5PpHpqzYBw" + YouTube) + ("Techquickie" + "https://www.youtube.com/feeds/videos.xml?channel_id=UC0vBXGSyV14uvJ4hECDOl0Q" + YouTube) + ("Captain Sinbad" + "https://www.youtube.com/feeds/videos.xml?channel_id=UC8XKyvQ5Ne_bvYbgv8LaIeg" + YouTube) + ("3B1B" + "https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw" + YouTube) + ("Fredrik Knusden" + "https://www.youtube.com/feeds/videos.xml?channel_id=UCbWcXB0PoqOsAvAdfzWMf0w" + YouTube Stories) + ("Barely Sociable" + "https://www.youtube.com/feeds/videos.xml?channel_id=UC9PIn6-XuRKZ5HmYeu46AIw" + YouTube Stories) + ("Atrocity Guide" + "https://www.youtube.com/feeds/videos.xml?channel_id=UCn8OYopT9e8tng-CGEWzfmw" + YouTube Stories) + ("Philip Defranco" + "https://www.youtube.com/feeds/videos.xml?channel_id=UClFSU9_bUb4Rc6OYfTt5SPw" + YouTube News) + ("Hacker News" + "http://morss.aryadevchavali.com/news.ycombinator.com/rss" + Social) + ("Hacker Factor" + "https://www.hackerfactor.com/blog/index.php?/feeds/index.rss2" + Social) + ("BBC Top News" + "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/rss.xml" + News) + ("BBC Tech News" + "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/technology/rss.xml" + News))) + (setq elfeed-db-directory (concat user-emacs-directory "elfeed")) + :config + (with-eval-after-load "evil-collection" + (evil-collection-elfeed-setup)) + (setq elfeed-feeds (cl-map 'list #'(lambda (item) (append (list (nth 1 item)) (cdr (cdr item)))) +rss/feed-urls))) +#+end_src +* Projectile +Setup projectile, along with the tags command. Also bind "C-c C-p" to +the projectile command map for quick access. #+begin_src emacs-lisp -(setq display-buffer-alist - '(("\\*Org Src.*" - (display-buffer-same-window)) - ("\\*e?shell\\*" - (display-buffer-at-bottom) - (window-height . 0.25)) - ("\\*[Hh]elp.*" - (display-buffer-at-bottom) - (inhibit-duplicate-buffer . t) - (window-height . 0.25)) - ("magit:.*" - (display-buffer-same-window) - (inhibit-duplicate-buffer . t)) - ("magit-diff:.*" - (display-buffer-below-selected)) - ("magit-log:.*" - (display-buffer-same-window)) - ("\\*compilation\\*" - (display-buffer-at-bottom) - (window-height . 0.25)) - ("\\*Flycheck.*" - (display-buffer-at-bottom) - (window-height . 0.25)) - ("grep\\*" - (display-buffer-at-bottom) - (window-height . 0.25)) - ("\\*Python\\*" - (display-buffer-at-bottom) - (window-height . 0.25)) - ("\\*Org Export.*" - (display-buffer-at-bottom) - (window-height . 0.25)) - ("\\*Async Shell Command\\*" - (display-buffer-at-bottom) - (window-height . 0.25)) - )) +(use-package projectile + :after evil + :hook (prog-mode-hook . projectile-mode) + :general + (leader "p" #'projectile-command-map) + :init + (setq projectile-tags-command "ctags -Re -f \"%s\" %s \"%s\"") + :config + (projectile-global-mode)) +#+end_src +** Counsel projectile +Counsel projectile provides the ivy interface to projectile commands, which is really useful. +#+begin_src emacs-lisp :tangle no +(use-package counsel-projectile + :after (projectile counsel) + :config + (counsel-projectile-mode +1)) #+end_src * Text modes ** Flyspell @@ -954,20 +1096,13 @@ software, but I also need it in commit messages and so on. So flyspell-mode should be hooked to text-mode. #+begin_src emacs-lisp (use-package flyspell - :hook (text-mode-hook . flyspell-mode)) -#+end_src - -As I use ivy I'd like the flyspell correct interface (which allow for -corrections to real words) to use ivy. -#+begin_src emacs-lisp -(use-package flyspell-correct-ivy - :after flyspell + :hook (text-mode-hook . flyspell-mode) :general (general-def - :states '(normal insert) - :map flyspell-mode-map - "M-a" #'flyspell-correct-at-point - "M-A" #'ispell-word)) + :states 'normal + :keymaps 'text-mode-map + (kbd "M-a") #'flyspell-correct-word-before-point + (kbd "M-A") #'flyspell-auto-correct-word)) #+end_src ** Set auto-fill-mode for all text-modes Auto fill mode is nice for most text modes, 80 char limit is great. @@ -1009,6 +1144,7 @@ Now, the binding (kbd "M-d") #'+text/delete-till-sentence) #+end_src ** PDF +*** Preamble PDFs are a great format for (somewhat) immutable text and reports with great formatting options. Though Emacs isn't really the premier solution for viewing PDFs (I highly recommend [[https://pwmt.org/projects/zathura/][Zathura]]), similar to @@ -1052,16 +1188,27 @@ use the current buffer?) but it works out. "M-g" #'pdfgrep)) #+end_src * Org -** Org default with evil +** Core Setup for org mode, currently basically nothing. Has evil-org for evil bindings. Also setup a lot of variables, particularly for latex exports. #+begin_src emacs-lisp (use-package org - :hook (org-mode-hook . yas-minor-mode) - :bind (:map org-mode-map - ([remap imenu] . counsel-org-goto)) + :hook ((org-mode-hook . yas-minor-mode) + (org-mode-hook . org-shifttab) + (org-mode-hook . prettify-symbols-mode)) + :general + (with-eval-after-load "counsel" + (leader + :keymaps 'org-mode-map + "si" #'counsel-org-goto)) + :init + (with-eval-after-load "prog-mode" + (+pretty/set-alist + org-mode-hook + ("#+begin_src" . "≫") + ("#+end_src" . "≪"))) :custom ((org-edit-src-content-indentation 0) (org-src-window-setup 'current-window) @@ -1170,13 +1317,16 @@ any symbol. This is very useful when programming as it: #+begin_src emacs-lisp (use-package eldoc - :hook (prog-mode-hook . eldoc-mode)) + :straight nil + :hook (prog-mode-hook . eldoc-mode) + :init + (global-eldoc-mode 1)) (use-package eldoc-box :hook (eldoc-mode-hook . eldoc-box-hover-mode) - :custom - ((eldoc-box-position-function #'eldoc-box--default-upper-corner-position-function) - (eldoc-box-clear-with-C-g t)) + :init + (setq eldoc-box-position-function #'eldoc-box--default-upper-corner-position-function + eldoc-box-clear-with-C-g t) :config (advice-add #'evil-force-normal-state :before #'eldoc-box-quit-frame)) #+end_src @@ -1205,8 +1355,10 @@ Flycheck is the checking system for Emacs. I don't necessarily like having all my code checked all the time, so I haven't added a hook to prog-mode as it would be better for me to decide when I want checking and when I don't. + #+begin_src emacs-lisp (use-package flycheck + :defer t :commands flycheck-mode :config (defun +flycheck/list-errors-load-flycheck () @@ -1231,7 +1383,7 @@ Add a function to activate tabs mode for any modes you want tabs in. #+end_src ** C/C++ Setup for C and C++ modes via the cc-mode package. - +*** Preamble C and C++ are great languages for general purpose programming. Though lisp is more aesthetically and mentally pleasing, they get the job done. Furthermore, they provide speed and finer control in trade of @@ -1263,6 +1415,7 @@ that it best suits them. Furthermore, tabs produce smaller source files. However, this isn't set in stone and I will return to no tabs when needed in projects. +*** Configuration #+begin_src emacs-lisp (use-package cc-mode :hook (c-mode-hook . dx:activate-tabs) @@ -1272,6 +1425,42 @@ when needed in projects. (setq c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "user"))) + + (with-eval-after-load "prog-mode" + (+pretty/set-alist + c-mode-hook + ("NULL" . "∅") + ("true" . "𝕋") + ("false" . "𝔽") + ("char" . "ℂ") + ("int" . "ℤ") + ("float" . "ℝ") + ("bool" . "𝔹") + ("!" . "¬") + ("&&" . "∧") + ("||" . "∨") + ("for" . "∀") + ("return" . "⟼")) + + (+pretty/set-alist + c++-mode-hook + ("nullptr" . "∅") + ("std::vector" . "𝕃") + ("vector" . "𝕃") + ("std::string" . "𝕊") + ("string" . "𝕊") + ("NULL" . "∅") + ("true" . "𝕋") + ("false" . "𝔽") + ("char" . "ℂ") + ("int" . "ℤ") + ("float" . "ℝ") + ("bool" . "𝔹") + ("!" . "¬") + ("&&" . "∧") + ("||" . "∨") + ("for" . "∀") + ("return" . "⟼"))) :config (c-add-style "user" @@ -1305,7 +1494,15 @@ Clang format for when: (bind-key "C-c '" #'clang-format-region c++-mode-map)) #+end_src ** Python -Setup for python, including a toggle option +Basic, haven't used python in this configuration yet. +#+begin_src emacs-lisp +(use-package python + :straight nil + :init + (setq python-indent-offset 4)) +#+end_src +*** Python shell +Setup for python shell, including a toggle option #+begin_src emacs-lisp (use-package python :straight nil @@ -1314,14 +1511,11 @@ Setup for python, including a toggle option :general (leader "tp" #'+python/toggle-repl) - :init - (setq python-indent-offset 4) :config - (defun +python/toggle-repl () - "Create a repl for python" - (interactive) - (+dx/toggle-buffer "*Python*" #'run-python))) -#+END_SRC + (+dx/create-toggle-function +python/toggle-repl + "*Python*" + run-python)) +#+end_src ** HTML/CSS/JS Firstly, web mode for consistent colouring of syntax. #+begin_src emacs-lisp @@ -1350,7 +1544,22 @@ Then emmet for super speed Add a new lisp indent function which indents newline lists more appropriately. #+begin_src emacs-lisp -(with-eval-after-load "lisp-mode" +(use-package lisp-mode + :straight nil + :init + (with-eval-after-load "prog-mode" + (+pretty/set-alist + emacs-lisp-mode-hook + ("lambda" . "λ") + ("numberp" . "ℤ") + ("t" . "𝕋") + ("nil" . "∅") + ("and" . "∧") + ("or" . "∨") + ("for" . "∀") + ("mapc" . "∀") + ("mapcar" . "∀"))) + :config (defun +modded/lisp-indent-function (indent-point state) "This function is the normal value of the variable `lisp-indent-function'. The function `calculate-lisp-indent' calls this to determine |