~rest of the config

Moved into applications: mail, elfeed, xwidget, eshell

Also added pretty symbols to org-mode, c/c++ and lisp
This commit is contained in:
2020-08-23 17:18:47 +01:00
parent a0a3994889
commit 726132d633

View File

@@ -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.
(use-package evil-magit
:after magit)
#+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
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
(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)))
#+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.
#+begin_src emacs-lisp
(use-package elfeed
(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 notmuch
:commands notmuch
: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"))
(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
(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)))
;; sync mail after refresh
(advice-add #'notmuch-poll-and-refresh-this-buffer :before
#'+mail/sync-mail)
(evil-collection-notmuch-setup))
#+end_src
* Eshell
*** Smtpmail
#+begin_src emacs-lisp
(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
*** 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 org-msg
:after notmuch
: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-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
*** 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
(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 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
(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