Skip to content

channel-42/gmacs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gmacs Logo

Gmacs

Table of Contents

init-file

To be able to configure emacs in org-mode, put this code into init.el

(org-babel-load-file
 (expand-file-name
  "README.org"
  user-emacs-directory))

About

This is my GNU Emacs config, adopted from DT’s emacs config. It is oriented towards efficient note-taking with org-mode and general productivity.

Furthermore it includes configuration of lsp-mode, tree-sitter, ligatures, dap-mode, etc. to enhace the programing experience.

Generally, what I do with this emacs config is:

  • write org-documents, e.g.
    • lectures notes
    • summaries
  • code in c/c++ and python
  • write LaTeX-documents
  • read and write mail

Speed up load times

To speed up loading, I have Emacs running as a daemon in the background and then create a new window through emacsclient. The following code increase the garbage-collector threshold to speed up Emacs even more.

;; The default is 800 kilobytes.  Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))

Package Management

Adding MELPA

Melpa is used for package-management, thus we make sure to add it to the repo list and to activivate Emacs’ package feature.

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
;;uncomment the following line to check for updates on each startup 
;;(package-refresh-contents)
(package-initialize)

Installing use-package

use-package makes configuring packages easier, as it provides convenient flags (e.g. :hook, :after, etc.).

(unless (package-installed-p 'use-package)
  (package-install 'use-package))
;;don't try to install missing packages as default. Uncomment to change.
;;(setq use-package-always-ensure t)

Cleanup

Keep Emacs from littering directories with cache files. We use the XDG $HOME/.cache/ dir for this.

;; NOTE: If you want to move everything out of the ~/.emacs.d folder
;; reliably, set `user-emacs-directory` before loading no-littering!
;(setq user-emacs-directory "~/.cache/emacs")
(use-package no-littering)
;; no-littering doesn't set this by default so we must place
;; auto save files in the same path as it uses for sessions
(setq auto-save-file-name-transforms
      `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))

Icons

Lets add some nice icons to Emacs! These are needed for doom-modeline as well as treemacs.

(use-package all-the-icons
:config
;;tweak this value for should the icons be too large/small
(setq all-the-icons-scale-factor 1.1))

evil-mode

Evil-mode provides extensive vim-like keybindings for Emacs as well as many other packages. I’m using it since I used to use vim/nvim for all my writing and got used to the bindings. We load evil-mode before the custom bindings, so that personal bindings are not accidentally overwritten.

(use-package evil
  :init                            ;; tweak evil's configuration before loading it
  (setq evil-want-integration t    ;; This is optional since it's already set to t by default.
        evil-want-keybinding nil
        evil-undo-system 'undo-tree
        evil-vsplit-window-right t
        evil-split-window-below t)
  (evil-mode))

;; add redo functionality
(use-package undo-tree
  :after evil
  :init
  (global-undo-tree-mode 1))

;; add evil-support for more packages
(use-package evil-collection
  :after evil
  :config
  (evil-collection-init))

Keybindings

General makes binding keys easy, especially when using evil-mode, by allowing mode-specific mappings (insert, normal, visual). Most Bindings are are accessible through SPACE+<key>, with window/tab movement and zooming as an exception.

(use-package general
  :config
  (general-evil-setup t))
;; tab movement
(nvmap "L" '(tab-bar-switch-to-next-tab :whichkey "next tab"))
(nvmap "H" '(tab-bar-switch-to-prev-tab  :whichkey "prev tab"))
(nvmap "F" '(tab-bar-close-tab :which-key "close tab"))

;; zooming
(nvmap "s-+" '(default-text-scale-increase :which-key "increase text"))
(nvmap "s--" '(default-text-scale-decrease :which-key "increase text"))

;; window movement
(nvmap "C-h" '(windmove-left :which-key "left"))
(nvmap "C-j" '(windmove-down :which-key "down"))
(nvmap "C-k" '(windmove-up :which-key "up"))
(nvmap "C-l" '(windmove-right :which-key "right"))

(nvmap :prefix "SPC"
       ;; general
       "SPC"   '(counsel-M-x :which-key "M-x")
       "O"   '(tab-bar-new-tab :which-key "new tab")
       "C"   '(evilnc-comment-or-uncomment-lines :which-key "(un)comment")
       "G"   '(ffap :which-key "goto file")
       "TAB" '(gmacs/toggle-fold :which-key "toggle fold")
       ;;"e"   '(neotree-toggle :which-key "neotree")
       "e"   '(treemacs :which-key "treemacs")
       "F" '(lsp-format-buffer :which-key "format")
       "m" '(:which-key "mail")
       "m m"   '(mu4e :which-key "mu4e")
       "m e"   '(mml-secure-message-encrypt-pgpmime :which-key "encrypt")
       "m s"   '(mml-secure-message-sign-pgpmime :which-key "sing")
       "m o"   '(org-mime-edit-mail-in-org-mode :which-key "org-edit")
       "m O"   '(org-mime-htmlize :which-key "org-htmlize")
       ;; insert
       "i" '(:which-key "insert")
       "i e" '(emojify-insert-emoji :which-key "emoji")
       ;; org and org-agenda 
       "o" '(:which-key "org")
       "o i" '(org-indent-block :which-key "indent")
       "o o" '(org-ctrl-c-ctrl-c :which-key "C-c C-c")
       "o a" '((lambda () (interactive) (evil-window-new (cfw:open-org-calendar))) :which-key "agenda")
       "o A" '((lambda () (interactive) (find-file-other-window "~/Documents/share/Org/agenda.org")) :which-key "agenda-file")
       "o s" '(org-schedule :which-key "schedule")
       "o t" '(org-todo :which-key "todo")
       "o RET" '(org-meta-return :which-key "re-insert")
       ;; compilation 
       "c" '(:which-key "compile")
       "c l"     '(texfrag-document :which-key "latex preview")
       "c c"     '(gmacs/compile :which-key "compile project")
       ;; fix
       "f" '(:which-key "fix")
       "f w"     '(ispell-word :which-key "word")
       "f a"     '(ispell-buffer :which-key "all")
       ;; git 
       "g" '(:which-key "git")
       "g g"     '(magit-status :which-key "status")
       "g l"     '(magit-log :which-key "log")
       "g b"     '(magit-blame :which-key "blame")
       ;; lsp 
       "l"   '(:which-key "lsp")
       "l f" '(lsp-format-buffer :which-key "format")
       "l g" '(projectile-find-file :which-key "go to proj. file")
       "l d" '(lsp-ui-peek-find-definitions :which-key "peek defs")
       "l r" '(lsp-ui-peek-find-references  :which-key "peek refs")
       "l R" '(lsp-rename :which-key "rename symbol")
       "l s" '(lsp-ivy-workspace-symbol :which-key "search symbol")
       "l e" '(lsp-treemacs-errors-list :which-key "show errors")
       ;; dap 
       "d"   '(:which-key "dap")
       "d d" '(dap-debug :which-key "debug")
       "d l" '(dap-debug-last :which-key "debug last")
       "d b" '(dap-breakpoint-toggle :which-key "breakpoint")
       "d m" '(dap-breakpoint-log-message :which-key "bmesg")
       "d w" '(dap-ui-expressions-add :which-key "watch")
       "d h" '(dap-hydra :which-key "hydra")
       ;; telega
       "u" '(:which-key "telega")
       "u u"  '(telega :which-key "main")
       "u m"  '(telega-chat-with :which-key "message")
       "u c"  '(telega-view-contacts :which-key "contacts")
       "u b"  '(telega-switch-buffer :which-key "buffer")
       "u r"  '(telega-view-reset :which-key "reset view")
       "u a"  '(telega-chatbuf-attach-media :which-key "attach")
       ;; search
       "s" '(:which-key "search")
       "s f"  '(find-file :which-key "files")
       "s r"   '(counsel-recentf :which-key "recent")
	 "s h" '(dired-jump :which-key "here")
	 "s s" '(swiper :which-key "search")
       ;; buffers
       "b" '(:which-key "buffer")
       "b b"   '(counsel-switch-buffer :which-key "switch buffer")
       "b k"   '(kill-current-buffer :which-key "kill")
       "b n"   '(next-buffer :which-key "next")
       "b p"   '(previous-buffer :which-key "previous")
       "b B"   '(ibuffer-list-buffers :which-key "Ibuffer list buffers")
       "b K"   '(kill-buffer :which-key "Killall")
       ;; eshell
       ;;"e" '(:which-key "eshell")
       ;;"e h"   '(counsel-esh-history :which-key "history")
       ;;"e s"   '(eshell :which-key "Eshell")
       "r" '(:which-key "reload")
       "r c" '((lambda () (interactive) (load-file "~/.emacs.d/init.el")) :which-key "config")
       ;; toggle
       "t" '(:which-key "toggle")
       "t t"   '(vterm-toggle-cd :which-key "vterm")
       "t w"   '(toggle-truncate-lines :which-key "truncate lines")
       "t v"   '(visual-line-mode :which-key "visual lines")
       "t z"   '(olivetti-mode :which-key "zen mode")
       "t f"   '(focus-mode :which-key "focus mode")
       "t s"   '(languagetool-check :which-key "spell checking")
       ;; window splits
       "w" '(:which-key "window")
       "w c"   '(evil-window-delete :which-key "close")
       "w n"   '(evil-window-new :which-key "new")
       "w s"   '(evil-win ow-split :which-key "hsplit")
       "w v"   '(evil-window-vsplit :which-key "vsplit")
       ;; window motions
       "w w"   '(evil-window-next :which-key "Goto next window"))

Dashboard

Dashboard displays a nice home-page on startup. It provides an entry point to recent files, agenda and bookmarks.

Configuring Dashboard

(use-package dashboard
  :init
  (setq dashboard-set-heading-icons t
        dashboard-set-file-icons t
        dashboard-set-navigator t
        dashboard-banner-logo-title "hello there"
        ;; custom header image 
        dashboard-startup-banner "~/.emacs.d/gmacs.txt"
        dashboard-center-content t
        dashboard-week-agenda nil
        dashboard-agenda-time-string-format "%H:%M ::"
        dashboard-agenda-prefix-format " %i %s "
        dashboard-filter-agenda-entry 'dashboard-filter-agenda-by-time
        dashboard-items '((recents . 5)
                          (projects . 5))
	dashboard-item-names '(("Recent Files:" . "Recent:")
                               ("Agenda for today:" . "Schedule:")
                               ("Agenda for the coming week:" . "Agenda:")))
  :config
  (dashboard-setup-startup-hook)
  (dashboard-modify-heading-icons '((recents . "file-text")
				    (bookmarks . "book"))))

;; custom footer with emacs icon
(setq dashboard-footer-messages '("made with   by channel-42")
      dashboard-footer-icon (all-the-icons-fileicon "emacs"
                                                   :height 1.1
                                                   :v-adjust -0.05
                                                   :face 'font-lock-keyword-face))

;; Format: "(icon title help action face prefix suffix)"
(setq dashboard-navigator-buttons
      `(;; line1
        ((,(all-the-icons-faicon "history" :height 1.0 :v-adjust 0.0)
         "Update"
         "Update Packages"
         (lambda (&rest _) 
		       (package-refresh-contents)
		       (list-packages)
		       (package-menu-mark-upgrades)))

	 (,(all-the-icons-faicon "cogs" :height 1.0 :v-adjust 0.0)
          "Config"
          "Edit gmacs config"
          (lambda (&rest _) (find-file "~/.emacs.d/README.org")))

	(,(all-the-icons-octicon "mark-github" :height 1.0 :v-adjust 0.0)
          "Repo"
          "Go to gmacs repo"
          (lambda (&rest _) (browse-url "https://github.com/channel-42/gmacs"))))
	;; Line 2
	((,(all-the-icons-faicon "calendar" :height 1.0 :v-adjust 0.0)
          "Calendar"
          "Open calendar"
          (lambda (&rest _) (cfw:open-org-calendar))))))

       
;; custom font faces
(custom-set-faces
'(dashboard-banner-logo-title((t (
:inherit font-lock-keyword-face :height 200))))

'(dashboard-footer((t (
:inherit font-lock-keyword-face :height 140)))))

Dashboard in Emacsclient

This setting ensures that emacsclient always opens on dashboard rather than scratch.

(setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))

Treemacs

Treemacs adds a tree-style file browser, similar to neotree. This especially useful for project navigation. In conjunction with lsp, treemacs can furthermore display project symbols.

(use-package treemacs
:config)
;; some lsp features (symbol-trees)
(use-package lsp-treemacs
:after lsp)

Recent Files

Recentf is used for searching recently opened files.

(use-package recentf
  :commands counsel-recentf 
  :config
  (recentf-mode)
;; exclude the littering dirs
(add-to-list 'recentf-exclude no-littering-var-directory)
(add-to-list 'recentf-exclude no-littering-etc-directory))

Dired

Dired is the default file-manager within Emacs. Here we add icons as well as external program support.

(use-package all-the-icons-dired)
(use-package dired-open)
(use-package peep-dired)

(setq peep-dired-cleanup-on-disable t)
(setq dired-recursive-copies 'always)
(setq dired-recursive-deletes 'always)
(setq dired-listing-switches
        "-AGFhlv --group-directories-first --time-style=long-iso")
;; dired and peep-dired bindings
(evil-define-key '(normal visual) dired-mode-map (kbd "P") 'peep-dired
                                                 (kbd "h") 'dired-up-directory
                                                 (kbd "l") 'dired-open-file)

(evil-define-key '(normal visual) peep-dired-mode-map (kbd "<SPC>") 'peep-dired-scroll-page-down
                                             (kbd "C-<SPC>") 'peep-dired-scroll-page-up
                                             (kbd "<backspace>") 'peep-dired-scroll-page-up
                                             (kbd "j") 'peep-dired-next-file
                                             (kbd "k") 'peep-dired-prev-file)
(add-hook 'peep-dired-hook 'evil-normalize-keymaps)

;; Get file icons in dired
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
;; start up minimal
(add-hook 'dired-mode-hook #'dired-hide-details-mode)
(add-hook 'dired-mode-hook #'hl-line-mode)
;; With dired-open plugin, you can launch external programs for certain extensions
;; For example, I set all .png files to open in 'sxiv' and all .mp4 files to open in 'mpv'
(setq dired-open-extensions '(("gif" . "sxiv")
                              ("jpg" . "sxiv")
                              ("png" . "sxiv")
                              ("mkv" . "mpv")
                              ("mp4" . "mpv")))
(use-package dired-subtree
:after dired)
(setq dired-subtree-use-backgrounds nil)
(let ((map dired-mode-map))
    (define-key map (kbd "<tab>") #'dired-subtree-toggle)
    (define-key map (kbd "<backtab>") #'dired-subtree-remove)) ; S-TAB

Fonts

All font settings

Setting The Font Face

(set-face-attribute 'default nil
  :font "FiraCode Nerd Font 13"
  :weight 'medium)
(set-face-attribute 'variable-pitch nil
  :font "Iosevka Aile 13"
  :weight 'medium)
(set-face-attribute 'fixed-pitch nil
  :font "FiraCode Nerd Font 13"
  :weight 'medium)
;; Makes commented text italics (working in emacsclient but not emacs)
(set-face-attribute 'font-lock-comment-face nil
  :slant 'italic)
;; Makes keywords italics (working in emacsclient but not emacs)
(set-face-attribute 'font-lock-keyword-face nil :slant 'italic)

;; make emojis work in emacs-client
;;-------------------
;; Add Apple Color Emoji to the default symbol fontset used by Emacs
(defun custom/set-emoji-font ()
  (set-fontset-font "fontset-default" 'symbol "Apple Color Emoji" nil 'prepend))
;; Call the config function once and then remove the handler
(defun custom/set-emoji-font-in-frame (frame)
  (with-selected-frame frame
    (custom/set-emoji-font))
  ;; Unregister this hook once its run
  (remove-hook 'after-make-frame-functions
               'custom/set-emoji-font-in-frame))
;; Attach the function to the hook only if in Emacs server
;; otherwise just call the config function directly
(add-hook 'after-make-frame-functions
              'custom/set-emoji-font-in-frame)
  (custom/set-emoji-font)

;;-------------------
;; Uncomment the following line if line spacing needs adjusting.
(setq-default line-spacing 0.12)
;; Needed if using emacsclient. Otherwise, your fonts will be smaller than expected.
(add-to-list 'default-frame-alist '(font . "FiraCode Nerd Font 13"))
;; changes certain keywords to symbols, such as lamda!
(setq global-prettify-symbols-mode t)

Ligatures

Adding nice looking code ligatures (only for fira code)

(use-package fira-code-mode
  :hook prog-mode)

Zooming In and Out

Settings for zooming (text-size)

;; zoom in/out like we do everywhere else.
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "<C-wheel-up>") 'text-scale-increase)
(global-set-key (kbd "<C-wheel-down>") 'text-scale-decrease)

Emojis

Add emoji support as well as nice emoji menu. Uses Apple’s emoji font, which is configured here

(use-package emojify
:hook (after-init . global-emojify-mode)
:config
(setq emojify-display-style 'unicode)
(setq emojify-emoji-styles '(unicode)))

GUI Tweaks

Disable some GUI-features and configure line numbers as well as the statusbar

Disable Menu-, Tool-, and Scrollbars

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

Relative Line Numbers

;; no line numbers by default
(setq display-line-numbers nil)
;; relative line-nums in prog
(add-hook 'prog-mode-hook (lambda () (setq display-line-numbers 'relative)))
;; no line-nums in org (due to var-pitch font)
(add-hook 'org-mode-hook (lambda () (setq display-line-numbers 'nil)))
;; always truncate lines
(setq truncate-lines t)

Modeline

Spaceline is spacemacs default modeline. The colors are adjusted in the themes section.

(use-package powerline
  :config
  (powerline-center-theme)
(setq powerline-default-separator 'wave))

(use-package spaceline
  :config
  (require 'spaceline-config)
  (setq spaceline-highlight-face-func 'spaceline-highlight-face-evil-state))
  ;; (spaceline-emacs-theme))

(use-package spaceline-all-the-icons
  :after spaceline
  :config (spaceline-all-the-icons-theme)
  (setq spaceline-all-the-icons-separator-type 'wave))

;;;; old doom config
;;(use-package doom-modeline
;;  :init (doom-modeline-mode 1))
;;;; enable icons
;;(setq doom-modeline-icon 1)

Ivy, Counsel and Swiper

taken from the official gihub:

Ivy, a generic completion mechanism for Emacs.

Counsel, a collection of Ivy-enhanced versions of common Emacs commands.

Swiper, an Ivy-enhanced alternative to Isearch.

(use-package counsel
  :after ivy
  :config (counsel-mode))
(use-package ivy
  :defer 0.1
  :diminish
  :bind (("C-c C-r" . ivy-resume)
         ("C-x B" . ivy-switch-buffer-other-window))
  :custom
  (ivy-count-format "(%d/%d) ")
  (ivy-use-virtual-buffers t)
  :config (ivy-mode))

;; add features and eye-candy to ivy
(use-package ivy-rich
  :after ivy
  :custom
  (ivy-virtual-abbreviate 'full
   ivy-rich-switch-buffer-align-virtual-buffer t
   ivy-rich-path-style 'abbrev)
  :config
  (ivy-set-display-transformer 'ivy-switch-buffer
                               'ivy-rich-switch-buffer-transformer))
(ivy-rich-mode)
(use-package all-the-icons-ivy-rich
  :after ivy
  :init (all-the-icons-ivy-rich-mode 1))

(use-package swiper
  :after ivy
;; alternate binding to leader+s+s
  :bind (("C-s" . swiper)))

Additionally I use counsel as a system-wide app-laucher. All this is acomplished with the following function taken from this reddit post. To use the launcher, call the function through emacsclient using your hotkey-daemon of choice.

The command is:

emacsclient -a "" -n -e "(call-interactively 'emacs-run-launcher)" &> /dev/null
;; used as systems main program launcher
(defun emacs-run-launcher ()
"Create and select a frame called emacs-run-launcher which consists only of a minibuffer and has specific dimensions. Run counsel-linux-app on that frame, which is an emacs command that prompts you to select an app and open it in a dmenu like behaviour. Delete the frame after that command has exited"
(interactive)
(setq counsel-linux-app-format-function 'counsel-linux-app-format-function-name-pretty)
(let ((win (get-mru-window)))
   (with-selected-frame (make-frame '((name . "emacs-run-launcher")
      (window-system . x)
      (minibuffer . only)
      (width . 120)
      (height . 11)))
      (unwind-protect
           (counsel-linux-app)
           (progn
             (delete-frame)
             (select-window win))))))

IVY-POSFRAME

Ivy-posframe is an ivy extension, which lets ivy use posframe to show its candidate menu. Some of the settings below involve:

  • ivy-posframe-display-functions-alist – sets the display position for specific programs
  • ivy-posframe-height-alist – sets the height of the list displayed for specific programs

Available functions (positions) for ‘ivy-posframe-display-functions-alist’

  • ivy-posframe-display-at-frame-center
  • ivy-posframe-display-at-window-center
  • ivy-posframe-display-at-frame-bottom-left
  • ivy-posframe-display-at-window-bottom-left
  • ivy-posframe-display-at-frame-bottom-window-center
  • ivy-posframe-display-at-point
  • ivy-posframe-display-at-frame-top-center

NOTE: If the setting for ‘ivy-posframe-display’ is set to ‘nil’ (false), anything that is set to ‘ivy-display-function-fallback’ will just default to their normal position in Doom Emacs (usually a bottom split). However, if this is set to ‘t’ (true), then the fallback position will be centered in the window.

  (use-package ivy-posframe
    :init
;; display at `ivy-posframe-style'
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-center)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-window-center)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-bottom-left)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-window-bottom-left)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-top-center)))
(setq ivy-posframe-parameters
      '((left-fringe . 15)
        (right-fringe . 15)
        (down-fringe . 15)
        (upper-fringe . 15)))
(setq ivy-posframe-display-functions-alist
	  '((swiper                     . ivy-posframe-display-at-window-center)
	    (complete-symbol            . ivy-posframe-display-at-point)
	    (counsel-M-x                . ivy-display-function-fallback)
	    (counsel-esh-history        . ivy-posframe-display-at-window-center)
	    (counsel-switch-buffer      . ivy-posframe-display-at-frame-center)
	    (counsel-describe-function  . ivy-display-function-fallback)
	    (counsel-describe-variable  . ivy-display-function-fallback)
	    (counsel-find-file          . ivy-display-function-fallback)
	    (counsel-recentf            . ivy-display-function-fallback)
	    (counsel-register           . ivy-posframe-display-at-frame-bottom-window-center)
	    (dmenu                      . ivy-posframe-display-at-frame-top-center)
	    (nil                        . ivy-posframe-display))
	  ivy-posframe-height-alist
	  '((swiper . 20)
	    (dmenu . 20)
	    (t . 10)))
  :config
  (ivy-posframe-mode 1)) ; 1 enables posframe-mode, 0 disables it.

Magit

Magit is used for managing git projects. It is one of Emacs’ most well-know packages

(use-package magit
:commands  magit-status)
(use-package magit-todos
:after magit
  ;; show comments with TODO in magit 
  :config (magit-todos-mode))

Git Gutter

Git gutter adds a vscode-style colored bar to sections that were added, modified or removed in a git project.

(use-package git-gutter
  :hook (prog-mode . git-gutter-mode)
  :config
  (setq git-gutter:update-interval 0.02))

(use-package git-gutter-fringe
  :config
  (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil'(center repeated))
  (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
  (define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240] nil nil 'bottom))

Org Mode

THE mode I use Emacs for and the main reason I originally switched to it. Very powerful notetaking with a ton of additional functionality.

keys

Override Org header-jumping with windmove bindings

;;(defun custom/org-evil-wind-override
  (evil-define-key 'normal org-mode-map
    (kbd "C-j") 'windmove-down)
  (evil-define-key 'normal org-mode-map
    (kbd "C-k") 'windmove-up)
;;)

;;(add-hook 'org-mode-hook 'custom/org-evil-wind-override)
;; override outline-bwd/fwd-same-level

Visual lines

Make lines wrap instead of continuing off-screen

(setq-default truncate-lines t)
(setq-default global-visual-line-mode t)

Olivetti

Olivetti mode centers text.

(use-package olivetti
:config
(setq olivetti-body-width 0.65
      olivetti-minimum-body-width 72
      olivetti-recall-visual-line-mode-entry t))

Focus

(use-package focus
:config
(set-face-attribute 'focus-unfocused nil :foreground(doom-lighten (doom-color 'bg) 2)))

org-modern

;; Enable org-modern-mode
(add-hook 'org-mode-hook #'org-modern-mode)
(add-hook 'org-agenda-finalize-hook #'org-modern-agenda)

Defining A Few Things

Define some settings and hooks for org-mode

;;(add-hook 'org-mode-hook 'org-indent-mode)
(setq org-startup-indented t
      org-startup-with-inline-images t)
(add-hook 'org-mode-hook 'texfrag-mode)
(add-hook 'org-mode-hook #'visual-line-mode)
(add-hook 'org-mode-hook #'olivetti-mode)
(setq org-directory "~/Documents/share/Org"
      org-agenda-files (list org-directory)
      org-default-notes-file (expand-file-name "notes.org" org-directory)
      org-ellipsis ""
      org-log-done 'time
      org-journal-dir "~/Documents/share/Org/journal/"
      org-journal-date-format "%B %d, %Y (%A) "
      org-journal-file-format "%Y-%m-%d.org"
      org-hide-emphasis-markers t)

(setq org-agenda-category-icon-alist
      `(("planner" ,(list (all-the-icons-faicon "clock-o" :height 1.0 :v-adjust -0.05)) nil nil :ascent center)))

(add-to-list 'org-src-lang-modes '("conf" . conf))

Enabling Org Bullets

Org-bullets provides glyph-style bullets instead of asterisks.

(use-package org-bullets)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))

Org Link Abbreviations

This allows for the use of abbreviations that will get expanded out into a lengthy URL.

;; An example of how this works.
;; [[arch-wiki:Name_of_Page][Description]]
(setq org-link-abbrev-alist    ; This overwrites the default Doom org-link-abbrev-list
        '(("google" . "http://www.google.com/search?q=")
          ("arch-wiki" . "https://wiki.archlinux.org/index.php/")
          ("ddg" . "https://duckduckgo.com/?q=")
          ("wiki" . "https://en.wikipedia.org/wiki/")))

Org Todo Keywords

Some custom settings for agenda items.

(setq org-todo-keywords        ; This overwrites the default Doom org-todo-keywords
         '((sequence
            "TODO(t)"           ; A task that is ready to be tackled
            "BLOG(b)"           ; Blog writing assignments
            "UNI(u)"            ; Things to accomplish at the gym
            "PROJ(p)"           ; A project that contains other tasks
            "CODE(e)"          ; Video assignments
            "WAIT(w)"           ; Something is holding up this task
            "|"                 ; The pipe necessary to separate "active" states and "inactive" states
            "DONE(d)"           ; Task has been completed
            "CANCELLED(c)" )))  ; Task has been cancelled

(setq org-fontify-done-headline t)
;; strike through things marked as done
(set-face-attribute 'org-done nil :strike-through t)
(set-face-attribute 'org-headline-done nil
                      :strike-through t
                      :foreground "#657b83")

Source Code Block Tag Expansion

Org-tempo org-block expansion. Includes:

Characters Preceding TABExpands to …
<a’#+BEGIN_EXPORT ascii’ … ‘#+END_EXPORT
<c’#+BEGIN_CENTER’ … ‘#+END_CENTER’
<C’#+BEGIN_COMMENT’ … ‘#+END_COMMENT’
<e’#+BEGIN_EXAMPLE’ … ‘#+END_EXAMPLE’
<E’#+BEGIN_EXPORT’ … ‘#+END_EXPORT’
<h’#+BEGIN_EXPORT html’ … ‘#+END_EXPORT’
<l’#+BEGIN_EXPORT latex’ … ‘#+END_EXPORT’
<q’#+BEGIN_QUOTE’ … ‘#+END_QUOTE’
<s’#+BEGIN_SRC’ … ‘#+END_SRC’
<v’#+BEGIN_VERSE’ … ‘#+END_VERSE’
(use-package org-tempo
  :after org
  :ensure nil
  :config
  (add-to-list 'org-structure-template-alist '("cp" . "src cpp :noweb no-export"))
  (add-to-list 'org-structure-template-alist '("c" . "src C :noweb no-export")))

Source Code Block stuff

Add syntax highlighting, preserve indentation and enable C, C++ and Python

(setq org-src-fontify-natively t
     org-src-tab-acts-natively t
     org-confirm-babel-evaluate nil
     org-src-preserve-indentation t 
     org-edit-src-content-indentation 0
     org-adapt-indentation nil)

;; load langs for code blocks (needed for eval)
(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)))
(org-babel-do-load-languages
 'org-babel-load-languages
 '((C . t)))

(defun org-babel-edit-prep:cpp (babel-info)
  (setq-local buffer-file-name (->> babel-info caddr (alist-get :file-name)))
  (setq-local lsp-buffer-uri (->> babel-info caddr (alist-get :file-name) lsp--path-to-uri))
  (lsp))

(defun org-babel-edit-prep:C (babel-info)
  (setq-local buffer-file-name (->> babel-info caddr (alist-get :file-name)))
  (setq-local lsp-buffer-uri (->> babel-info caddr (alist-get :file-name) lsp--path-to-uri))
  (lsp))

;; src-block colors in export
;; set #+LaTeX_HEADER: \usemintedstyle{style from "pygmentize -L styles"}

(require 'ox-latex)
(setq org-latex-listings 'minted
      org-latex-packages-alist '(("" "minted"))
      org-latex-pdf-process
      '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

Heading formatting

Make headings different sizes

;; colors
(custom-set-faces
  '(org-level-1 ((t (:inherit outline-1))))
  '(org-level-2 ((t (:inherit outline-2))))
  '(org-level-3 ((t (:inherit outline-3))))
  '(org-level-4 ((t (:inherit outline-4))))
  '(org-level-5 ((t (:inherit outline-5))))
)

;; use non-mono font
(add-hook 'org-mode-hook 'variable-pitch-mode 1)

;; heading sizes
(set-face-attribute 'org-document-title nil :font "Iosevka Aile" :weight 'bold :height 1.3)
(dolist (face '((org-level-1 . 1.5)
                (org-level-2 . 1.4)
                (org-level-3 . 1.3)
                (org-level-4 . 1.2)
                (org-level-5 . 1.1)
                (org-level-6 . 1.0)
                (org-level-7 . 1.0)
                (org-level-8 . 1.0)))
  (set-face-attribute (car face) nil :font "Iosevka Aile" :weight 'medium :height (cdr face)))

;; Make sure org-indent face is available
(require 'org-indent)

;; Ensure that anything that should be fixed-pitch in Org files appears that way
(set-face-attribute 'org-block nil  :inherit 'fixed-pitch)
(set-face-attribute 'org-table nil  :inherit 'fixed-pitch)
(set-face-attribute 'org-formula nil  :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil   :inherit '(fixed-pitch))
(set-face-attribute 'org-indent nil :inherit '(org-hide fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '( fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)

Automatically Create Table of Contents

Use ‘:TOC:’ to generate it in org documents

(use-package toc-org
  :commands toc-org-enable
  :init (add-hook 'org-mode-hook 'toc-org-enable))

Latex Export

Place the TOC on a separate page after the cover page

(setq org-latex-toc-command "\\newpage \\tableofcontents \\clearpage")

Calendar

The calfw calendar provides a more intuitive way of viewing the org-mode agenda.

(use-package calfw
:commands cfw:open-org-calendar
:config
;; Unicode characters
(setq cfw:fchar-junction ?╋
      cfw:fchar-vertical-line ?┃
      cfw:fchar-horizontal-line ?━
      cfw:fchar-left-junction ?┣
      cfw:fchar-right-junction ?┫
      cfw:fchar-top-junction ?┯
      cfw:fchar-top-left-corner ?┏
      cfw:fchar-top-right-corner ?┓))
(use-package calfw-org)

Projectile

A tool for project management.

(use-package projectile
  :config
  (projectile-global-mode 1))

Scrolling

Remove half page jumps and add acceleratted scrolling.

(setq scroll-conservatively 101 ;; value greater than 100 gets rid of half page jumping
      mouse-wheel-scroll-amount '(1 ((shift) . 1)) ;; how many lines at a time
      mouse-wheel-progressive-speed t ;; accelerate scrolling
      mouse-wheel-follow-mouse 't) ;; scroll window under mouse

PDF-tools

Improve PDF viewing in Emacs. Useful for writing LaTeX docs or taking lecture notes, as this allows for synctex support.

(use-package pdf-tools
:config
(pdf-tools-install)
;; sync emacs and pdf-tools themes
(add-hook 'pdf-tools-enabled-hook 'pdf-view-themed-minor-mode)
;; disable blinking cursor
(evil-set-initial-state 'pdf-view-mode 'emacs)
(add-hook 'pdf-view-mode-hook
  (lambda ()
    (set (make-local-variable 'evil-emacs-state-cursor) (list nil))))
)

Shells

Eshell

I don’t use this, but still keep it around. Taken from DT’s config

Eshell is an Emacs ‘shell’ that is written in Elisp.

  • ‘eshell-syntax-highlighting’ – adds fish/zsh-like syntax highlighting.
  • ‘eshell-aliases-file’ – sets an aliases file for the eshell.
(use-package eshell-syntax-highlighting
  :after esh-mode
  :config
  (eshell-syntax-highlighting-global-mode +1))
(setq eshell-aliases-file "~/.config/doom/aliases"
      eshell-history-size 5000
      eshell-buffer-maximum-lines 5000
      eshell-hist-ignoredups t
      eshell-scroll-to-bottom-on-input t
      eshell-destroy-buffer-when-process-dies t
      eshell-visual-commands'("bash" "htop" "ssh" "top" "zsh"))

Vterm

Adding vterm with custom function so that it opens in a new buffer at the bottom, similar to the vscode terminal.

(use-package vterm
:commands vterm
:config
;; which shell to use
(setq vterm-shell "/bin/zsh"))
(setq shell-file-name "/bin/sh"
      vterm-max-scrollback 5000)
(use-package vterm-toggle
:commands (vterm-toggle vterm-toggle-cd)
:config
;; show vterm at the bottom
(setq vterm-toggle-fullscreen-p nil)
(add-to-list 'display-buffer-alist
             '((lambda(bufname _) (with-current-buffer bufname (equal major-mode 'vterm-mode)))
                (display-buffer-reuse-window display-buffer-at-bottom)
                ;;(display-buffer-reuse-window display-buffer-in-direction)
                ;;display-buffer-in-direction/direction/dedicated is added in emacs27
                ;;(direction . bottom)
                ;;(dedicated . t) ;dedicated is supported in emacs27
                (reusable-frames . visible)
                (window-height . 0.3))))

Theme

Recently switched to modus-themes after using doom-themes for a while. I keep the doom stuff arround for completness and treemacs colors.

(use-package doom-themes)
(setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
      doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-github-dark-default t)

(require 'doom-themes)
(set-face-attribute 'spaceline-evil-normal nil :background (doom-darken (doom-color 'blue) 0.5))
(set-face-attribute 'spaceline-evil-insert nil :background (doom-darken (doom-color 'green) 0.5))
(set-face-attribute 'spaceline-evil-visual nil :background (doom-darken (doom-color 'violet) 0.5))
(set-face-attribute 'dashboard-text-banner-face nil :foreground (doom-color 'blue) :weight 'bold :slant 'italic)
(set-face-attribute 'dashboard-heading-face nil :foreground (doom-color 'blue) :weight 'bold :slant 'italic)
(setq pdf-view-midnight-colors `(,(doom-color 'fg) . ,(doom-color 'bg)))

;;(doom-themes-neotree-config)
;;(use-package modus-themes
;;  :init
;;  ;; Add all your customizations prior to loading the themes
;;  (setq modus-themes-subtle-line-numbers t
;;        modus-themes-italic-constructs t
;;        modus-themes-bold-constructs t 
;;        modus-themes-diffs 'desaturated
;;        modus-themes-region '(bg-only no-extend)
;;        modus-themes-org-blocks 'nil
;;        modus-themes-syntax (quote (alt-syntax yellow-comments))
;;        modus-themes-completions (quote (super-opinionated))
;;        modus-themes-mode-line (quote (borderless)))
;;
;;
;;  (setq modus-themes-vivendi-color-overrides
;;         '((bg-completion-intense . "#323232")))
;;  ;; Load the theme files before enabling a theme
;;  (modus-themes-load-themes)
;;  :config
;;  (modus-themes-load-vivendi)
;;  ;; customize spaceline colors
;;  (set-face-attribute 'mode-line-inactive nil :box nil)
;;  (set-face-attribute 'mode-line nil :box nil)
;;  (set-face-attribute 'powerline-active1 nil :foreground (modus-themes-color 'fg-active):background (modus-themes-color 'bg-active-accent))
;;  (set-face-attribute 'powerline-inactive2 nil :background (modus-themes-color 'bg-main))
;;  (set-face-attribute 'powerline-active2 nil :foreground (modus-themes-color 'fg-active):background (modus-themes-color 'bg-main))
;;  (set-face-attribute 'spaceline-evil-normal nil :foreground (modus-themes-color 'fg-active):background (modus-themes-color 'bg-active))
;;  (set-face-attribute 'spaceline-evil-insert nil :background (modus-themes-color 'green-active))
;;  (set-face-attribute 'spaceline-evil-visual nil :background (modus-themes-color 'cyan-active))
;;   ;; fix fringe bg (white bar)
;;  (set-face-attribute 'modus-themes-fringe-green nil :foreground (modus-themes-color 'bg-main))
;;  (set-face-attribute 'modus-themes-fringe-red nil :foreground (modus-themes-color 'bg-main))
;;  (set-face-attribute 'modus-themes-fringe-yellow nil :foreground (modus-themes-color 'bg-main))
;;  (set-face-attribute 'modus-themes-box-button nil :background (modus-themes-color 'bg-main) :box nil)
;;)

(setq doom-themes-treemacs-theme "doom-colors")
(doom-themes-treemacs-config)

;; set opacity
;;(set-frame-parameter (selected-frame) 'alpha '(93 . 93))
;;(add-to-list 'default-frame-alist '(alpha . (93 . 93)))

Which key

Which-Key is a shortcut helper menu displayed below the modeline. Another very well-known Emacs package replicated in other editors.

(use-package which-key
:after evil
:config
 ;; Set the time delay (in seconds) for the which-key popup to appear. A value of
;; zero might cause issues so a non-zero value is recommended.
(setq which-key-idle-delay 0.25))
(which-key-mode)

Brackets

Enabling autoclosing brackets

(electric-pair-mode)

;; inhibit "<>" from auto-pairing in org-mode (for org-blocks)
(add-hook
 'org-mode-hook
 (lambda ()
   (setq-local electric-pair-inhibit-predicate
               `(lambda (c)
                  (if (char-equal c ?<) t (,electric-pair-inhibit-predicate c))))))

LSP

Make emacs a very powerful IDE

LSP-Mode

Configure lsp-mode for python and c/c++

(setq byte-compile-warnings '(cl-functions))
(use-package lsp-mode
  :init
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  (setq lsp-keymap-prefix "C-c l"
        lsp-headerline-breadcrumb-enable nil)

(setq lsp-pyls-server-command '("$HOME/.local/bin/pyls"))
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         ;;(prog-mode . lsp)
         (c-mode . lsp)
         (c++-mode . lsp)
         (python-mode . lsp)
         (LaTeX-mode . lsp)
         (html-mode . lsp)
         ;; if you want which-key integration
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp
:config
;; font lock tweaks
 (add-hook 'lsp-after-initialize-hook '(lambda () (set-face-attribute 'lsp-face-semhl-class nil :inherit 'font-lock-warning-face)))
 (add-hook 'lsp-after-initialize-hook '(lambda () (set-face-attribute 'lsp-face-semhl-interface nil :inherit 'font-lock-function-name-face)))
 (add-hook 'lsp-after-initialize-hook '(lambda () (set-face-attribute 'lsp-face-semhl-namespace nil :inherit 'font-lock-warning-face)))
(add-hook 'lsp-before-initialize-hook '(lambda () (set-face-attribute 'tree-sitter-hl-face:function.call nil :inherit 'font-lock-type-face)))

 

;; needed for yasnippets to work
(setq lsp-completion-provider :capf
      read-process-output-max (* 1024 1024) ;; 1mb
      lsp-enable-semantic-highlighting t
      lsp-idle-delay 0.5
      lsp-modeline-diagnostics-enable t
      lsp-prefer-flymake t
      lsp-lens-enable nil
      lsp-completion-show-detail nil)
)

;; tab width and coding style
(setq c-basic-offset 4
      c-default-style "k&r")

;;;; use ccls instead of clangd -> avr-programming
;;(use-package ccls
;;  :hook ((c-mode c++-mode objc-mode cuda-mode) .
;;         (lambda () (require 'ccls) (lsp)))
;;:config (setq ccls-executable "/usr/bin/ccls")
;; (setq ccls-args `(,(format "--log-file=/tmp/ccls_%d.log" (emacs-pid)) "-v=2")))

;; configure ui settings (doc position, always peek)
(use-package lsp-ui
  :hook (lsp-mode . lsp-ui-mode)
  :config
  (setq lsp-ui-sideline-enable t
        lsp-ui-sideline-show-symbol t
        lsp-ui-sideline-show-hover nil
        lsp-ui-sideline-show-flycheck t
        lsp-ui-sideline-show-code-actions t 
        lsp-ui-sideline-show-diagnostics t)

  (setq lsp-ui-doc-enable t)
  (setq lsp-ui-doc-position 'at-point)
  (setq lsp-ui-doc-show-with-cursor t)
  (setq lsp-ui-peek-always-show t))

yasnippet

Add useful snippets to speed up coding

(use-package yasnippet
  :hook (prog-mode . yas-minor-mode)
  :config
  (yas-reload-all))

(use-package yasnippet-snippets)

github-copilot

; Load copilot.el, modify this path to your local path.
(load-file "~/.emacs.d/copilot.el/copilot.el")
(setq copilot-idle-delay 0.5)

; complete by copilot first, then company-mode
(defun my-tab ()
  (interactive)
  (or (copilot-complete)
      (company-indent-or-complete-common nil)))

; modify company-mode behaviors
(with-eval-after-load 'company
  ; disable inline previews
  (delq 'company-preview-if-just-one-frontend company-frontends)
  ; enable tab completion
  (define-key company-mode-map (kbd "<tab>") 'my-tab)
  (define-key company-mode-map (kbd "<backtab>") 'copilot-accept-completion)
  (define-key company-active-map (kbd "<tab>") 'my-tab)
  (define-key company-active-map (kbd "TAB") 'my-tab))

; provide completion when typing
(add-hook 'post-command-hook (lambda ()
                               (copilot-clear-overlay)
                               (when (evil-insert-state-p)
                                 (copilot-complete))))

company-mode

Enhace the default autocompletion with company-mode (added support for yasnippets)

(use-package company
  :after lsp-mode
  :hook (prog-mode . company-mode)
  :custom
  (company-minimum-prefix-length 1)
  (company-idle-delay 0.0)
:config
(define-key company-active-map (kbd "<tab>") 'company-complete-selection)
(define-key company-active-map (kbd "RET") 'nil)
(setq company-transformers '(company-sort-prefer-same-case-prefix)))

(use-package company-box
  :hook (company-mode . company-box-mode))

compilation

Ehance compilation experience by providing integration of emacs’ compile (and recompile) commands with projectile. To compile a project press SPC c-c. Then, to recompile, press r in the *compilation* buffer. To dismiss said buffer, press q.

The variable gmacs/compile-command defines the shell command to be executed in the projects root directory provided by the function projectile-project-root.

(defvar gmacs/compile-command "cd build && cmake .. && cmake --build ./ -j12 && ./bin/*"
  "Command passed to compile by gmacs/compile")

These is the code that runs the compilation, fixes shell color codes and adds some helpful bindings.

;; fix shell color codes and add recompile binding
(require 'ansi-color)
(with-eval-after-load 'compile
  ;; set cursor to follow compilation output
  (setq compilation-scroll-output t)
  (evil-define-key '(normal) compilation-mode-map  (kbd "r") 'recompile))

;; apply ansi color to the entire buffer
(defun colorize-compilation-buffer ()
  (let ((inhibit-read-only t))
    (ansi-color-apply-on-region (point-min) (point-max))))

;; apply ansi color to every *compilation* buffer
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

;; main compile function
(defun gmacs/compile ()
  "Save and compile the project using the compilation command defined in 
the variable `gmacs/compile-command', with output going to the buffer 
`*compilation*'."
(interactive)
;; get project root and concat it with cd (to navigate to it)
;; and the compile command
(let* ((project-root (projectile-project-root))
       (project-compile-command (concat
				 "cd "
				 project-root
				 " && "
				 gmacs/compile-command
				 )))
  ;; save all project buffers 
  (projectile-save-project-buffers)
  ;; run compile command through emacs' compile
  (compile project-compile-command)
  ;; focus on output buffer
  (switch-to-buffer-other-window "*compilation*")))

visual

;; indent guides 
(use-package highlight-indent-guides
:config
(add-hook 'prog-mode-hook 'highlight-indent-guides-mode)
(setq highlight-indent-guides-method 'character
      highlight-indent-guides-responsive 'top))

;; colorful brackets
(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode)
  :config
 (set-face-attribute 'rainbow-delimiters-depth-1-face  nil :inherit 'font-lock-warning-face)
)
(use-package rainbow-mode)
(rainbow-mode)

;; folding
(defun gmacs/toggle-fold ()
  (interactive)
    (interactive)
    (save-excursion
      (end-of-line)
      ;; check if cursor is on overlay
      (if (hs-overlay-at (point))
	  ;; go to start of line, otherwise folding doesn't work
	  (beginning-of-line))
      (hs-toggle-hiding)))

(add-hook 'c-mode-common-hook   'hs-minor-mode)
(add-hook 'c++-mode-hook        'hs-minor-mode)
(add-hook 'emacs-lisp-mode-hook 'hs-minor-mode)
(add-hook 'java-mode-hook       'hs-minor-mode)
(add-hook 'lisp-mode-hook       'hs-minor-mode)
(add-hook 'perl-mode-hook       'hs-minor-mode)
(add-hook 'python-mode-hook     'hs-minor-mode)
(add-hook 'sh-mode-hook         'hs-minor-mode)

commenting

;; easily toggle comments
(use-package evil-nerd-commenter)

DAP

Add debugging functionality. Currently only configured for c/c++

(use-package dap-mode
:hook (c-mode) 
:config
(require 'dap-gdb-lldb)
(dap-gdb-lldb-setup))

Tree-sitter

Enhanced syntax highlighting in prog-mode. Clashes with code blocks sometimes (background color of brackets)

(use-package tree-sitter)
(use-package tree-sitter-langs)
;; (global-tree-sitter-mode)
;; (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode)
(add-hook 'c++-mode-hook #'tree-sitter-hl-mode)
(add-hook 'c-mode-hook #'tree-sitter-hl-mode)
(add-hook 'python-mode-hook #'tree-sitter-hl-mode)
(add-hook 'json-mode-hook #'tree-sitter-hl-mode)

;; change type face as it clashes with the function face (doom-themes)
(custom-set-faces
'(tree-sitter-hl-face:type.builtin ((t (
:inherit font-lock-type-face)))))

Telega

A telegram UI inside Emacs. This required Telegram’s tdlib to be installed. For more information on how to install and configure telega, read the official manual

(use-package telega
:commands telega)
(add-hook 'telega-load-hook #'visual-line-mode)

Spell Checking

Spell checking with LTeX-ls. Requires the language server to be installed. AUR Packages available.

;; (use-package lsp-ltex
;;   :ensure t
;;   :hook (text-mode . (lambda ()
;;                        (require 'lsp-ltex)
;;                        (lsp)))  ; or lsp-deferred
;;   :init
;;   (setq lsp-ltex-version "15.2.0"
;;         lsp-ltex-language "de-DE")) 
(use-package languagetool
  :defer t
  :commands (languagetool-check
             languagetool-clear-buffer
             languagetool-server-start
             languagetool-correct-at-point
             languagetool-correct-buffer
             languagetool-set-language)
  :config
  (setq languagetool-java-arguments '("-Dfile.encoding=UTF-8"
                                    "-cp" "/usr/share/languagetool:/usr/share/java/languagetool/*")
      languagetool-console-command "org.languagetool.commandline.Main"
      languagetool-server-command "org.languagetool.server.HTTPServer"
      languagetool-default-language "de-DE"
      languagetool-correction-language "de-DE"))

mu4e

Manage mail comortably in emacs. Includes:

  • encrypted passwords
  • pgp signing
  • org to html conversion
  • org capture templates (useful if you use org-agenda)

All this makes integration into the general emacs workflow very convinient

;; needed for encrypted passwords
(use-package epa-file)
(epa-file-enable)
(setq mm-sign-option 'nil)
(use-package smtpmail :after mu4e)
(use-package org-mime :after org
:config
;; custom org-to-html-conversion settings
(setq org-mime-export-options '(:section-numbers nil
                                :with-author nil
                                :with-toc nil))

;; custom code block styling (html)
(add-hook 'org-mime-html-hook
          (lambda ()
            (org-mime-change-element-style
            "pre" (format "color: %s; background-color: %s; padding: 0.5em;"
                          "#ffffff" "#1d1f21")))))
(use-package mu4e
  :ensure nil
  :load-path "/usr/share/emacs/site-lisp/mu4e/"
  ;; :defer 20 ; Wait until 20 seconds after startup
  :commands mu4e
  :config
;; enable custom modes when reading/writing
(add-hook 'mu4e-view-mode-hook #'visual-line-mode) 
(add-hook 'mu4e-view-mode-hook #'olivetti-mode) 
(add-hook 'mu4e-compose-mode-hook 'flyspell-mode)
;; org capture stuff
(require 'mu4e-org)
(setq org-capture-templates
  `(("m" "Email Workflow")
    ("mf" "Follow Up" entry (file+olp "~/Documents/share/Org/Mail.org" "Beantworten")
          "* TODO AW an %:fromname über %:subject\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%a\n\n%i" :immediate-finish t) ("mr" "Read Later" entry (file+olp "~/Documents/share/Org/Mail.org" "Lesen")
          "* TODO LESEN: %:subject\nSCHEDULED:%t\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%a\n\n%i" :immediate-finish t)))
;; custom capture vars
(defun efs/capture-mail-follow-up (msg)
  (interactive)
  (call-interactively 'org-store-link)
  (org-capture nil "mf"))

(defun efs/capture-mail-read-later (msg)
  (interactive)
  (call-interactively 'org-store-link)
  (org-capture nil "mr"))

;; Add custom actions for our capture templates
(add-to-list 'mu4e-headers-actions
  '("antwort vormerken" . efs/capture-mail-follow-up) t)
(add-to-list 'mu4e-view-actions
  '("antwort vormerken" . efs/capture-mail-follow-up) t)
(add-to-list 'mu4e-headers-actions
  '("lesen vormerken" . efs/capture-mail-read-later) t)
(add-to-list 'mu4e-view-actions
  '("lesen vormerken" . efs/capture-mail-read-later) t)

(setq mml-secure-openpgp-sign-with-sender t)
(setq mu4e-view-show-images t)
;; Only ask if a context hasn't been previously picked
(setq mu4e-compose-context-policy 'ask-if-none)
;; Make sure plain text mails flow correctly for recipients
(setq mu4e-compose-format-flowed t)

;; load the mail account configs
(load "~/.emacs.d/mail.el")
;; file contains list of mue4e-contexts, this allows for multiple accounts
;; looks like this
;;
;; (setq mu4e-contexts
;;       (list
;;        ;; first account
;;        (make-mu4e-context
;;         :name "1st-acc"
;;         :match-func
;;           (lambda (msg)
;;             (when msg
;;               (string-prefix-p "/first_acc" (mu4e-message-field msg :maildir))))
;;         :vars '((user-mail-address . "example@domain.net")
;;                 (mu4e-compose-signature . "Your Name (CEO Mail Inc.)"
;;                 (user-full-name    . "Your Name")
;;                 (mu4e-drafts-folder  . "/first_acc/Drafts")
;;                 (mu4e-sent-folder  . "/first_acc/Sent")
;;                 (mu4e-trash-folder  . "/first_acc/Trash")
;;                 (smtpmail-auth-credentials . (expand-file-name "~/.authinfo.gpg"))
;;                 (message-send-mail-function . smtpmail-send-it)
;;                 (smtpmail-starttls-credentials . (("your.smpt.net" 587 nil nil)))
;;                 (smtpmail-smtp-server . "your.smpt.net")
;;                 (smtpmail-smtp-user . "example@domain.net")
;;                 (smtpmail-debug-info . t)
;; 	          (smtpmail-debug-verbose . t)
;;                 (smtpmail-smtp-service . 587)
;;                 (mu4e-maildir-shortcuts . ( ("/first_acc/Inbox" . ?i)
;; 					("/first_acc/Sent"        . ?s)
;; 					("/first_acc/Trash"       . ?t)
;; 					("/first_acc/Spam"        . ?j)
;; 					("/first_acc/Drafts"      . ?d)))
;;                )
;;         )
;; 
;;  
;; ))
;;

;; This is set to 't' to avoid mail syncing issues when using mbsync
(setq mu4e-change-filenames-when-moving t)
(setq mu4e-use-fancy-chars t)

(setq mu4e-headers-thread-child-prefix '("├>" . "├▶ "))
(setq mu4e-headers-thread-last-child-prefix '("└>" . "└▶ "))
(setq mu4e-headers-thread-connection-prefix '("" . ""))
(setq mu4e-headers-thread-orphan-prefix '("┬>" . "┬▶ "))
(setq mu4e-headers-thread-single-orphan-prefix '("─>" . "─▶ "))

;; Refresh mail using isync every 10 minutes
(setq mu4e-update-interval (* 10 60))
(setq mu4e-get-mail-command "mbsync -a -c ~/.config/mbsync/mbsyncrc"))

;; enable mail notifications for dunst, etc.
(use-package mu4e-alert)
(mu4e-alert-set-default-style 'libnotify)
(add-hook 'after-init-hook #'mu4e-alert-enable-notifications)
(add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display)

texfrag-mode

Display inline Latex code blocks in org-mode.

(use-package texfrag
:after org
:config
(setq texfrag-preview-buffer-at-start t
      texfrag-scale 0.9))

LaTeX

Setup auctex to work together with pdftools, lsp, company, and yasnippets. Xenops mode additionally provides inline previews similar to texfrag in org-mode.

(use-package company-auctex)
;; this line also needs to go into init.el
;; all other settings work for some reason
(setq TeX-engine 'xetex) ;enable autosave on during LaTeX-mode
(setq TeX-auto-save t) ;enable autosave on during LaTeX-mode
(setq TeX-parse-self t) ; enable autoparsing
(setq TeX-save-query nil) 
;; pdftools to view compiled file
;; has autorefresh on recompile
(setq TeX-view-program-selection '((output-pdf "PDF Tools"))
      TeX-view-program-list '(("PDF Tools" TeX-pdf-tools-sync-view))
      TeX-source-correlate-start-server t)
(add-hook 'TeX-after-compilation-finished-functions
          #'TeX-revert-document-buffer)
;; enable some specific minor modes
(setq predictive-latex-electric-environments 1)
(add-hook 'LaTeX-mode-hook 'company-mode)
(add-hook 'LaTeX-mode-hook 'yas-minor-mode)
(setq-default fill-column 100)
(add-hook 'LaTeX-mode-hook 'auto-fill-mode)
(add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
(add-hook 'LaTeX-mode-hook 'visual-line-mode)
(add-hook 'pdf-view-mode-hook ( lambda() (company-mode -1)))
(setq TeX-source-correlate-method 'synctex)
(setq TeX-source-correlate-start-server t)

(setq org-latex-toc-command "\\tableofcontents \\clearpage")
(setq org-latex-pdf-process
      '("latexmk -pdflatex='pdflatex -interaction nonstopmode' -pdf -bibtex -f %f"))

(unless (boundp 'org-latex-classes)
  (setq org-latex-classes nil))
(use-package xenops
:hook  'latex-mode-hook 'LaTeX-mode-hook
:config (setq xenops-math-image-scale-factor 1.5))
(add-hook 'latex-mode-hook #'xenops-mode)
(add-hook 'LaTeX-mode-hook #'xenops-mode)
(add-to-list 'org-latex-classes
             '("ethz"
               "\\documentclass[a4paper,11pt,titlepage]{memoir}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
\\usepackage{fixltx2e}
\\usepackage{graphicx}
\\usepackage{longtable}
\\usepackage{float}
\\usepackage{wrapfig}
\\usepackage{rotating}
\\usepackage[normalem]{ulem}
\\usepackage{amsmath}
\\usepackage{textcomp}
\\usepackage{marvosym}
\\usepackage{wasysym}
\\usepackage{amssymb}
\\usepackage{hyperref}
\\usepackage{mathpazo}
\\usepackage{color}
\\usepackage{enumerate}
\\definecolor{bg}{rgb}{0.95,0.95,0.95}
\\tolerance=1000
      [NO-DEFAULT-PACKAGES]
      [PACKAGES]
      [EXTRA]
\\linespread{1.1}
\\hypersetup{pdfborder=0 0 0}"
               ("\\chapter{%s}" . "\\chapter*{%s}")
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))


(add-to-list 'org-latex-classes
             '("article"
               "\\documentclass[11pt,a4paper]{article}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
%\\renewcommand*\\familydefault{\\sfdefault}
\\usepackage{lmodern}
\\usepackage{graphicx}
\\usepackage{float}
\\usepackage{wrapfig}
\\usepackage{rotating}
\\usepackage[normalem]{ulem}
\\usepackage{amsmath}
\\usepackage{textcomp}
\\usepackage{amssymb}
\\usepackage{hyperref}
\\usepackage{color}
\\usepackage{xcolor}
\\usepackage{enumerate}
\\definecolor{bg}{rgb}{0.95,0.95,0.95}
\\tolerance=1000
      [NO-DEFAULT-PACKAGES]
      [PACKAGES]
      [EXTRA]
\\linespread{1.1}

\\usepackage{tcolorbox}
\\newtcolorbox{mymerke}{colback=red!5!white, colframe=red!75!black}
\\newtcolorbox{myquote}{colback=gray!5!white, colframe=gray!0}
\\newenvironment{merke}{\\begin{mymerke}}{\\end{mymerke}}
\\renewenvironment{quote}{\\begin{myquote}\\begin{em}}{\\end{em}\\end{myquote}}

\\hypersetup{pdfborder=0 0 0}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\begin{quote}" . "\\test{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")))


(add-to-list 'org-latex-classes '("ebook"
                                  "\\documentclass[11pt, oneside]{memoir}
\\setstocksize{9in}{6in}
\\settrimmedsize{\\stockheight}{\\stockwidth}{*}
\\setlrmarginsandblock{2cm}{2cm}{*} % Left and right margin
\\setulmarginsandblock{2cm}{2cm}{*} % Upper and lower margin
\\checkandfixthelayout
% Much more laTeX code omitted
"
                                  ("\\chapter{%s}" . "\\chapter*{%s}")
                                  ("\\section{%s}" . "\\section*{%s}")
                                  ("\\subsection{%s}" . "\\subsection*{%s}")))

(setq org-latex-inputenc-alist '(("utf8" . "utf8x")))
(add-hook 'LaTeX-mode-hook #'reftex-mode)
(add-hook 'latex-mode-hook #'reftex-mode)

Matlab

(autoload 'matlab-mode "matlab" "Matlab Editing Mode" t)
(add-to-list
 'auto-mode-alist
 '("\\.m$" . matlab-mode))
(setq matlab-shell-command "~/.local/bin/matlab")
(setq matlab-shell-command-switches (list "-nodesktop"))

Reset gc to keep emacs snappy

;; Make gc pauses faster by decreasing the threshold.
(setq gc-cons-threshold (* 2 1000 1000))

(setq neo-window-width 35)

About

My personal GNU emacs config(s)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published