Skip to content

eliaskanelis/.emacs.d

Repository files navigation

Kanelis Elias’s Emacs Configuration

./img/screen.png

Bugfixes

Package cl is deprecated in Emacs-27 kiwanami/emacs-epc#35

(setq byte-compile-warnings '(cl-functions))

Environment variables

(setq tedi-org-directory "~/org/")

Quick visit my files

Notes

(defun tedi:visit-notes ()
  "Visits my notes"
  (interactive)
  (find-file (concat tedi-org-directory "notes.org")))
(global-set-key (kbd "C-c n") 'tedi:visit-notes)

Todo

(defun tedi:visit-todo ()
  "Visits my todos"
  (interactive)
  (find-file (concat tedi-org-directory "todo.org")))
(global-set-key (kbd "C-c t") 'tedi:visit-todo)

Startup

Garbage collection

This fixed garbage collection, makes emacs start up faster.

(setq gc-cons-threshold 402653184 gc-cons-percentage 0.6)

(defvar startup/file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)

(defun startup/revert-file-name-handler-alist ()
  (setq file-name-handler-alist startup/file-name-handler-alist))

(defun startup/reset-gc ()
  (setq gc-cons-threshold 16777216 gc-cons-percentage 0.1))

(add-hook 'emacs-startup-hook 'startup/revert-file-name-handler-alist)
(add-hook 'emacs-startup-hook 'startup/reset-gc)

Customization file

This save customizations somewhere other than the initialization file.

(setq custom-file (expand-file-name "custom.el" init-el-directory))
(when (file-exists-p custom-file)
(load custom-file))

Configuration

Visiting the configuration

Quickly visit the configuration file.

(defun tedi:config-visit ()
  "Visits the emacs config file"
  (interactive)
  (find-file (concat init-el-directory "config.org")))
(global-set-key (kbd "C-c e") 'tedi:config-visit)

Reloading the configuration

Quickly reloads the configuration file.

(defun tedi:config-reload ()
  "Reloads the configuration file"
  (interactive)
  (org-babel-load-file (concat init-el-directory "config.org"))
  )
(global-set-key (kbd "C-c r") 'tedi:config-reload)

Basic Settings

These are setting that do not depend on packages and are built-in enhancements to the UI.

Looks

Remove default startup screen

(setq inhibit-startup-message t)

Remove toolbar

(tool-bar-mode -1)

Remove menubar

(menu-bar-mode -1)

Remove scrollbar

(scroll-bar-mode -1)

Show line numbers

(global-display-line-numbers-mode t)

Make fullscreen

(set-frame-parameter nil 'fullscreen 'fullboth)

Fonts

(when (member "Source Code Pro" (font-family-list)) (set-frame-font "Source Code Pro-10" t t))
(set-face-attribute 'default nil :height 100)     ;;Default font size %

Theme

(use-package monokai-theme
  :ensure t
  :config (load-theme 'monokai t))

;;(use-package zenburn-theme
;;  :ensure t
;;  :config (load-theme 'zenburn t))

;;(add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
;;(load-theme 'tedi t)

Disable scratch message

(setq initial-scratch-message nil)

Do not blink cursor

(blink-cursor-mode -1)

Disable bell

This is annoying, remove this line if you like being visually reminded of events.

(setq ring-bell-function 'ignore)

Set UTF-8 encoding

(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)

Highligh current line

hl-line is awesome! It’s not very awesome in the terminal version of emacs though, so we don’t use that. Besides, it’s only used for programming.

(when window-system (add-hook 'prog-mode-hook 'hl-line-mode))

Pretty symbols

Changes lambda to an actual symbol and a few others as well, only in the GUI version though.

(when window-system
  (use-package pretty-mode
    :ensure t
    :config
    (global-pretty-mode nil)))

Visualize whitespace

(require 'whitespace)

(setq whitespace-style '(face empty tabs tab-mark lines-tail trailing))

;;Visualize tabs as a pipe character - "|"
(custom-set-faces '(whitespace-tab ((t (:foreground "#636363")))))
(setq whitespace-display-mappings '((tab-mark 9 [124 9] [92 9]))) ; 124 is the ascii ID for '\|'

(global-whitespace-mode t)

Functionality

I do not care about system buffers

See only buffers that are associated to a file buffer-predicate decides which buffers you want to see in the cycle for windows in that frame. The function buffer-file-name returns nil for buffers that are not associated to files and a non-nil value (the filename) for those that are. After doing so, C-x <left> and C-x <right> called from windows in that frame will only cycle through buffers with associated files. In short it will Cycle through buffers whose name does not start with an asterisk

;;(defun tedi:let-cycle-on-my-buffers-only ()
;;  (interactive)
;;    (set-frame-parameter (selected-frame) 'buffer-predicate #'buffer-file-name))
;;(add-hook 'after-init-hook #'tedi:let-cycle-on-my-buffers-only)

(add-to-list 'default-frame-alist '(buffer-predicate . buffer-file-name))

ibuffer

Use ‘ibuffer’ instead of ‘list-buffers’

(defalias 'list-buffers 'ibuffer)

Hide all buffers that start with an asterisk

(require 'ibuf-ext)
(add-to-list 'ibuffer-never-show-predicates "^\\*")

Hide groups that are empty

(setq ibuffer-show-empty-filter-groups nil)

Automatically update the ibuffer

(add-hook 'ibuffer-mode-hook
          (lambda ()
             (ibuffer-auto-mode 1)
             (ibuffer-switch-to-saved-filter-groups "home")))

ibuffer formats

(setq ibuffer-formats
      '((mark modified read-only " "
              (name 18 18 :left :elide)
              " "
              (size 9 -1 :right)
              " "
              (mode 16 16 :left :elide)
              " " filename-and-process)
        (mark modified read-only " "
              (name 45 45 :left :elide)
              " "
              (size 9 -1 :right)
              " "
              (mode 16 16 :left :elide))))

Group my buffer by version control

(use-package ibuffer-vc
  :ensure t
  :config
  (add-hook 'ibuffer-hook
            (lambda ()
              (ibuffer-vc-generate-filter-groups-by-vc-root)
              (ibuffer-vc-set-filter-groups-by-vc-root)
              (unless (eq ibuffer-sorting-mode 'alphabetic)
                (ibuffer-do-sort-by-alphabetic))))
  (add-to-list 'ibuffer-fontification-alist '(5 buffer-file-name 'font-lock-keyword-face)))

Dired

Change information shown

(setq dired-listing-switches "-aBhl  --group-directories-first")

Make dired open in the same window when using RET or ^

(eval-after-load "dired"
  (lambda ()
    (define-key dired-mode-map (kbd "RET") 'dired-find-file)
    (define-key dired-mode-map (kbd "^") (lambda () (interactive) (find-alternate-file "..")))
    )
  )

Typing replaces marked region

(delete-selection-mode 1)

Move line up/down

(defun tedi:move-line-up ()
  "Move up the current line."
  (interactive)
  (transpose-lines 1)
  (forward-line -2)
  (indent-according-to-mode))

(defun tedi:move-line-down ()
  "Move down the current line."
  (interactive)
  (forward-line 1)
  (transpose-lines 1)
  (forward-line -1)
  (indent-according-to-mode))

(global-set-key [(meta up)]   'tedi:move-line-up)
(global-set-key [(meta down)] 'tedi:move-line-down)

Go to line

(global-set-key (kbd "M-g") 'goto-line)

Kill buffer

(global-set-key (kbd "C-x k") 'kill-this-buffer)

Multiplexing emacs and emacsclient

Opening a new file in the same emacs-session requires the use of emacsclient. The emacs command can be itself wrapped to do the smarter job to open the file if the session exists. To start session you need to start-server. This snippet will create server in first session of emacs. Add this to your emacs configuration file.

(require 'server)
(unless (server-running-p)
  (server-start))

Disable backups and auto-saves

(setq make-backup-files nil)
(setq auto-save-default nil)

Disable lockfiles

Emacs keeps track of files that you are currently editing by creating a symbolic link that looks like .#-emacsa08196. I do not need it.

(setq create-lockfiles nil)

Smooth Scrolling

;; Vertical Scroll
(setq scroll-step 1)
(setq scroll-margin 16)
(setq scroll-conservatively 101)
(setq scroll-up-aggressively 0.01)
(setq scroll-down-aggressively 0.01)
(setq auto-window-vscroll nil)
(setq fast-but-imprecise-scrolling nil)
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(setq mouse-wheel-progressive-speed nil)
;; Horizontal Scroll
(setq hscroll-step 1)
(setq hscroll-margin 1)

Change yes-or-no questions into y-or-n questions

(defalias 'yes-or-no-p 'y-or-n-p)

Async

Lets us use asynchronous processes wherever possible, pretty useful.

(use-package async
  :ensure t
  :init (dired-async-mode 1))

Navigate throught buffers

(windmove-default-keybindings)

Blindly follow symlinks without asking me

(setq vc-follow-symlinks nil)

Auto refresh file if changed outside

(global-auto-revert-mode t)

GDB

Debugging environment

(setq
 ;; use gdb-many-windows by default
 gdb-many-windows t

 ;; ?
 gdb-use-separate-io-buffer t

 ;; Non-nil means display source file containing the main routine at startup
 gdb-show-main t
 )

Fix source file opens in the wrong window

;; Toggle window dedication
(defun tedi:toggle-window-dedicated ()
  "Toggle whether the current active window is dedicated or not"
  (interactive)
  (message
   (if (let (window (get-buffer-window (current-buffer)))
         (set-window-dedicated-p window
                                 (not (window-dedicated-p window))))
       "Window '%s' is dedicated"
     "Window '%s' is normal")
   (current-buffer)))

;; Sets up the windows to make the command window dedicated
(advice-add 'gdb-setup-windows :after
            (lambda () (set-window-dedicated-p (selected-window) t)))

;; Prevent gdb from popping i/o window to the foreground on every output op
(setq-default gdb-display-io-nopopup t)

Quitting messes up the window configuration

How do you quit anyway? I think the correct way is just to run quit in the command window. But no matter how you quit GUD always messes up whatever window configuration you had before you opened it.

We can fix that by saving the window layout when we run M-x gdb by storing the layout into a register in gud-mode-hook. The gud-sentinal function runs when some event occurs on the inferior gdb process. We can hook that to restore the window state when the process exits.

(defconst gud-window-register 123456)

(defun gud-quit ()
  (interactive)
  (gud-basic-call "quit"))

(add-hook 'gud-mode-hook
          (lambda ()
            (gud-tooltip-mode)
            (window-configuration-to-register gud-window-register)
            (local-set-key (kbd "C-c q") 'gud-quit)))

(advice-add 'gud-sentinel :after
            (lambda (proc msg)
              (when (memq (process-status proc) '(signal exit))
                (jump-to-register gud-window-register)
                (bury-buffer))))

Debugging keybindings

TODO: http://emacs.1067599.n8.nabble.com/Gud-keybindings-td328833.html

(require 'gud)

(defun tedi:gud-toggle-breakpoint ()
  "Enable/disable breakpoint at the current line of source buffer."
  (interactive)
  (save-excursion
    (beginning-of-line)
    (let* ((bol (point))
           (ovl (overlay-get (car (overlays-in bol bol)) 'before-string))
           (bptno (get-text-property 0 'gdb-bptno ovl))
           (bpten (get-text-property 0 'gdb-enabled ovl)))
      (if bpten (gud-basic-call (format "-break-disable %s" bptno))
        (gud-basic-call (format "-break-enable %s" bptno))))))

(add-hook 'prog-mode-hook
          (lambda ()
            (local-set-key [f1]    'gud-run)
            (local-set-key [f2]    'gud-cont)

            ;;(local-set-key [f3]    'gdb)

            (local-set-key [f5]    'gud-next)
            (local-set-key [f6]    'gud-step)
            (local-set-key [f7]    'gud-until)
            ;;(local-set-key [f8]    'gud-cont)
            (local-set-key [f9]    'tedi:gud-toggle-breakpoint)
            ;;(local-set-key [f9]    'gud-break)
            )
          )

Coding style

Bash/sh

(add-hook 'sh-mode-hook
          (lambda ()
            (setq sh-basic-offset 2
                  sh-indentation 2
                  sh-indent-for-case-label 0
                  indent-tabs-mode nil
                  sh-indent-for-case-alt '+))
          )

C/C++ style is bsd( Allman )

(add-hook 'c-mode-hook
          (lambda ()
            (setq c-default-style "bsd"
                  c-basic-offset 8)))

(add-hook 'c++-mode-hook
          (lambda ()
            (setq c-default-style "bsd"
                  c-basic-offset 8)))

C/C++ Indentation is tabs

(add-hook 'c-mode-hook
          (lambda ()
            (setq-default indent-tabs-mode t)))

(add-hook 'c++-mode-hook
          (lambda ()
            (setq-default indent-tabs-mode t)))

C/C++ Tab is 8 spaces

(add-hook 'c-mode-hook
          (lambda ()
            (setq-default tab-width 8)))

(add-hook 'c++-mode-hook
          (lambda ()
            (setq-default tab-width 8)))

Python Indentation is tabs and each tab is 8 spaces

Since python.el indents only 4 columns, by default, the above will use tabs when the indent is a multiple of 8 and tabs followed by spaces for other indents. If you need to use a single tab for every indent level, you’ll also need to set python-indent to 8. Then you can set tab-width to whatever width you want to see the tabs displayed as.

(add-hook 'python-mode-hook
          (lambda ()
            (setq-default indent-tabs-mode nil)
            (setq-default tab-width 4)
            (setq python-indent-offset 4)))

Html

Indentation

(use-package web-mode
  :mode
  (("\\.phtml\\'" . web-mode)
   ("\\.tpl\\.php\\'" . web-mode)
   ("\\.jsp\\'" . web-mode)
   ("\\.as[cp]x\\'" . web-mode)
   ("\\.erb\\'" . web-mode)
   ("\\.mustache\\'" . web-mode)
   ("\\.djhtml\\'" . web-mode)
   ("\\.jst.ejs\\'" . web-mode)
   ("\\.html?\\'" . web-mode))
  :init
  (setq web-mode-enable-block-face t)
  (setq web-mode-enable-comment-keywords t)
  (setq web-mode-enable-current-element-highlight t)
  (setq web-mode-enable-current-column-highlight t)
  (setq web-mode-script-padding 2)
  (setq web-mode-style-padding 2)
  (setq web-mode-comment-style 2)
  (setq web-mode-code-indent-offset 2)
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-engines-alist
        '(("django" . "focus/.*\\.html\\'")
          ("ctemplate" . "realtimecrm/.*\\.html\\'")
          )
        )
  )

Indentation

Auto indent

(use-package aggressive-indent
  :ensure t
  :init
  (setq aggressive-indent-comments-too t)
  :config
  (global-aggressive-indent-mode 1))

Indent this buffer

(defun tedi:indent-c-buffer ()
  "Use astyle command to auto format c/c++ code."
  (interactive "r")
  (if (executable-find "astyle")
      (progn
        (setq cursorPosition (point))
        (shell-command-on-region
         (point-min) (point-max)
         (concat
          "astyle")
         (current-buffer) t
         (get-buffer-create "*Astyle Errors*") t)
        (goto-char cursorPosition))
    (message "Cannot find binary \"astyle\", please install first.")))

Indent buffer before save

(defun tedi:indent-before-save ()
    "Auto styling before saving."
    (interactive)
    (when (member major-mode '(cc-mode c++-mode c-mode))
      (tedi:indent-c-buffer)))

(add-hook 'c-mode-common-hook (lambda () (add-hook 'before-save-hook 'tedi:indent-before-save)))

Packages

General

(use-package general)

Ag

The Silver Searcher https://github.com/Wilfred/ag.el

The binary is also needed: https://github.com/ggreer/the_silver_searcher

(use-package ag
  :ensure t
  :config
  ;; Show colors
  (setq ag-highlight-search t)
  ;; Reuse the same *ag* buffer for all your searches:
  (setq ag-reuse-buffers 't)
  :bind
  ("C-c C-q" . ag-project)
  ("C-c C-d" . ag-dired))

Hydra

(use-package hydra
  :ensure t)

Evil-mode

  (use-package evil
    :ensure t
    :config (evil-mode 1))

;; Default state shall be emacs for now
(setq evil-default-state 'emacs)

Yasnippet

(use-package yasnippet
  :ensure t
  :config
  (use-package yasnippet-snippets
    :ensure t)
  (yas-reload-all))

All the icons

Run ‘M-x all-the-icons-install-fonts’ in order to download the icon fonts

(use-package all-the-icons
  :ensure t)

(use-package all-the-icons-dired
  :ensure t
  :requires all-the-icons
  :config
  (add-hook 'dired-mode-hook 'all-the-icons-dired-mode))

Dashboard

(use-package dashboard
  :ensure t
  :requires all-the-icons
  :config
  (dashboard-setup-startup-hook)
  (setq initial-buffer-choice
        (lambda ()
          (let ((buf (get-buffer "*dashboard*")))
            (unless buf
              (setq buf (get-buffer-create "*dashboard*")))
            buf)))
  (setq dashboard-startup-banner (concat init-el-directory "img/dashLogo.png"))
  (setq dashboard-banner-logo-title "First, solve the problem. Then, write the code.")

  (setq dashboard-items '((recents  . 5)
                          (bookmarks . 5)
                          (projects . 5)
                          (agenda . 5)
                          (registers . 5)))

  ;; Do not center content.
  (setq dashboard-center-content nil)

  ;; Do not show info about the packages loaded and the init time
  (setq dashboard-set-init-info nil)

  ;; Disable shortcut "jump" indicators for each section.
  (setq dashboard-show-shortcuts nil)

  ;; Disable footer with random quotes
  (setq dashboard-set-footer nil)

  ;; Add icons
  (setq dashboard-set-heading-icons t)
  (setq dashboard-set-file-icons t)

  ;;To show agenda for the upcoming seven days set the variable show-week-agenda-p to t.
  (setq show-week-agenda-p t)
  (setq dashboard-org-agenda-categories '("Tasks" "Appointments")))

Disable mouse

Disable the mouse only inside emacs. This is usefull in a laptop and as an exercise to not use the mouse at all.

(use-package disable-mouse
  :ensure t
  :config
  (global-disable-mouse-mode))

Which key

Brings up help on key combinations.

(use-package which-key
  :ensure t
  :config
  (which-key-mode))

Try

Let’s you try packages without installing them.

(use-package try
  :ensure t)

nwim

Smart move when you browse in code.

(use-package mwim
  :bind
  ("C-a" . mwim-beginning-of-code-or-line)
  ("C-e" . mwim-end-of-code-or-line))

Projectile

Projectile is an awesome project manager, mostly because it recognizes directories with a .git directory as projects and helps you manage them accordingly.

(use-package projectile
  :ensure t
  :init
  (projectile-mode 1))

Magit

(use-package magit
  :requires projectile
  :bind ("C-x g" . magit-status)
  :init
  (setq projectile-switch-project-action 'magit-status)
  (setq magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1))

Swiper

Counsel is a requirement for swiper. Swiper makes search easier.

(use-package counsel
  :ensure t)

(use-package swiper
  :ensure counsel
  :config
  (progn
    (ivy-mode 1)
    (setq ivy-use-virtual-buffers t)
    (global-set-key "\C-s" 'swiper)
    (global-set-key (kbd "C-c C-r") 'ivy-resume)
    (global-set-key (kbd "<f6>") 'ivy-resume)
    (global-set-key (kbd "M-x") 'counsel-M-x)
    (global-set-key (kbd "C-x C-f") 'counsel-find-file)
    (global-set-key (kbd "<f1> f") 'counsel-describe-function)
    (global-set-key (kbd "<f1> v") 'counsel-describe-variable)
    (global-set-key (kbd "<f1> l") 'counsel-load-library)
    (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
    (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
    (global-set-key (kbd "C-c g") 'counsel-git)
    (global-set-key (kbd "C-c j") 'counsel-git-grep)
    (global-set-key (kbd "C-c k") 'counsel-ag)
    (global-set-key (kbd "C-x l") 'counsel-locate)
    (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
    (define-key read-expression-map (kbd "C-r") 'counsel-expression-history)))

Neotree

[Config issue] When emacs starts in daemon mode the icons are not shown from a gui client jaypei/emacs-neotree#194

(use-package neotree
  :requires swiper
  :requires all-the-icons
  :requires projectile
  :defer 1
  :init
  ;; Autorefresh
  (setq neo-autorefresh t)

  :config
  (global-set-key [f8] 'neotree-toggle)
  ;; Use nerd for GUI and ascii for the terminal.
  (setq neo-theme (if (display-graphic-p) 'icons 'nerd))

  ;; Every time when the neotree window is opened, let it find current file and jump to node.
  (setq neo-smart-open t)
  ;; When running ‘projectile-switch-project’ (C-c p p), ‘neotree’ will change root automatically.
  (setq projectile-switch-project-action 'neotree-projectile-action)
  ;; Show hidden files
  (setq-default neo-show-hidden-files t)

  (setq neo-vc-integration '(face char))
  (setq neo-toggle-window-keep-p t)
  (setq neo-force-change-root t)

  (add-hook 'neotree-mode-hook
            (lambda ()
              ;;(setq-local mode-line-format nil)
              (setq-local display-line-numbers nil)
              (local-set-key (kbd "C-f") 'swiper)
              (local-set-key (kbd "C-s") 'isearch-forward)
              (local-set-key (kbd "C-M-s") 'isearch-forward-regexp)
              (local-set-key (kbd "C-r") 'isearch-backward)
              (local-set-key (kbd "C-M-r") 'isearch-backward-regexp)
              (local-set-key (kbd "o") 'neotree-open-file-in-system-application)
              (local-set-key (kbd "r") 'neotree-refresh)))

  ;; Add icons
  (add-to-list 'all-the-icons-icon-alist
               '("^build\.boot$" all-the-icons-alltheicon "clojure-line" :height 1.0 :face all-the-icons-blue :v-adjust 0.0))

  ;; face customizations
  (set-face-attribute 'neo-vc-edited-face nil
                      :foreground "#E2C08D")
  (set-face-attribute 'neo-vc-added-face nil
                      :foreground "green4")
  )

Keyfreq

Record keybind use This will help me setup ergonomics

(use-package keyfreq
  :config
  (keyfreq-mode 1)
  (keyfreq-autosave-mode 1))

Helpful

(use-package helpful
  :bind
  ("C-h f" . helpful-function)
  ("C-h v" . helpful-variable))

Smex

Make counsel-M-x to remember (and sort) commands

(use-package smex)

Modeline

The modeline is the heart of emacs, it offers information at all times, it’s persistent and verbose enough to gain a full understanding of modes and states you are in.

I use the modeline from spacemacs.

(use-package spaceline
  :ensure t
  :config
  (require 'spaceline-config)

  ;; Show full filepath
  ;;(spaceline-define-segment buffer-id
  ;;  (if (buffer-file-name)
  ;;      (abbreviate-file-name (buffer-file-name))
  ;;    (powerline-buffer-id)))

  ;; Hide minor mode
  (spaceline-toggle-minor-modes-off)

  ;; Show encoding
  (setq spaceline-buffer-encoding-abbrev-p nil)

  ;; Show line and column
  (setq spaceline-line-column-p t)
  (setq spaceline-line-p t)

  (setq powerline-default-separator (quote arrow))
  (spaceline-spacemacs-theme))

Add icons at the modeline

(use-package mode-icons
  :ensure t
  :after spaceline
  :defer 1
  :config
  (mode-icons-mode))

Minor conveniences

Emacs is at it’s best when it just does things for you, shows you the way, guides you so to speak. This can be best achieved using a number of small extensions. While on their own they might not be particularly impressive. Together they create a nice environment for you to work in.

Subwords

Emacs treats camelCase strings as a single word by default, this changes said behaviour.

(global-subword-mode 1)

Electric

If you write any code, you may enjoy this. Typing the first character in a set of 2, completes the second one after your cursor. Opening a bracket? It’s closed for you already. Quoting something? It’s closed for you already.

You can easily add and remove pairs yourself, have a look.

(setq electric-pair-pairs '(
                           (?\{ . ?\})
                           (?\( . ?\))
                           (?\[ . ?\])
                           (?\" . ?\")
                           ))

And now to enable it

(electric-pair-mode t)

Beacon

While changing buffers or workspaces, the first thing you do is look for your cursor. Unless you know its position, you can not move it efficiently. Every time you change buffers, the current position of your cursor will be briefly highlighted now.

(use-package beacon
  :ensure t
  :config
    (beacon-mode 1))

Rainbow

Mostly useful if you are into web development or game development. Every time emacs encounters a hexadecimal code that resembles a color, it will automatically highlight it in the appropriate color. This is a lot cooler than you may think.

(use-package rainbow-mode
  :ensure t
  :init
    (add-hook 'prog-mode-hook 'rainbow-mode))

Show parens

I forgot about that initially, it highlights matching parens when the cursor is just behind one of them.

(show-paren-mode 1)

Rainbow delimiters

Colors parentheses and other delimiters depending on their depth, useful for any language using them, especially lisp.

(use-package rainbow-delimiters
  :ensure t
  :init
    (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))

Expand region

A pretty simple package, takes your cursor and semantically expands the region, so words, sentences, maybe the contents of some parentheses, it’s awesome, try it out.

(use-package expand-region
  :ensure t
  :bind ("C-q" . er/expand-region))

Hungry deletion

On the list of things I like doing, deleting big whitespaces is pretty close to the bottom. Backspace or Delete will get rid of all whitespace until the next non-whitespace character is encountered. You may not like it, thus disable it if you must, but it’s pretty decent.

(use-package hungry-delete
  :ensure t
  :config
    (global-hungry-delete-mode))

Zapping to char

A nifty little package that kills all text between your cursor and a selected character. A lot more useful than you might think. If you wish to include the selected character in the killed region, change zzz-up-to-char into zzz-to-char.

(use-package zzz-to-char
  :ensure t
  :bind ("M-z" . zzz-up-to-char))

Kill ring

There is a lot of customization to the kill ring, and while I have not used it much before, I decided that it was time to change that.

Maximum entries on the ring

The default is 60, I personally need more sometimes.

(setq kill-ring-max 100)

popup-kill-ring

Out of all the packages I tried out, this one, being the simplest, appealed to me most. With a simple M-y you can now browse your kill-ring like browsing autocompletion items. C-n and C-p totally work for this.

(use-package popup-kill-ring
  :ensure t
  :bind ("M-y" . popup-kill-ring))

Tramp

(setq tramp-default-method "ssh")

The terminal

I have used urxvt for years, and I miss it sometimes, but ansi-term is enough for most of my tasks.

Default shell should be bash

I don’t know why this is a thing, but asking me what shell to launch every single time I open a terminal makes me want to slap babies, this gets rid of it. This goes without saying but you can replace bash with your shell of choice.

(defvar my-term-shell "/bin/bash")
(defadvice ansi-term (before force-bash)
  (interactive (list my-term-shell)))
(ad-activate 'ansi-term)

Programming

Minor, non-completion related settings and plugins for writing code.

Column 80 limit

(setq-default display-fill-column-indicator-column 79)
(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode)

Doxygen

(use-package highlight-doxygen
  :ensure t
  :config
  (highlight-doxygen-global-mode t))

Helm-Gtags

(use-package helm-gtags
  :ensure t
  )

;; Enable helm-gtags-mode
(add-hook 'c-mode-hook 'helm-gtags-mode)
(add-hook 'c++-mode-hook 'helm-gtags-mode)
(add-hook 'asm-mode-hook 'helm-gtags-mode)
;(add-hook 'python-mode-hook 'helm-gtags-mode)

;; customize
(custom-set-variables
 '(helm-gtags-path-style 'relative)
 '(helm-gtags-ignore-case t)
 '(helm-gtags-auto-update t))

;; key bindings
(with-eval-after-load 'helm-gtags
  (define-key helm-gtags-mode-map (kbd "M-.")   'helm-gtags-dwim)
  (define-key helm-gtags-mode-map (kbd "M-,")   'helm-gtags-pop-stack)
  (define-key helm-gtags-mode-map (kbd "M-u")   'helm-gtags-update-tags)

  (define-key helm-gtags-mode-map (kbd "M-t")   'helm-gtags-find-tag)
  (define-key helm-gtags-mode-map (kbd "M-r")   'helm-gtags-find-rtag)
  (define-key helm-gtags-mode-map (kbd "M-s")   'helm-gtags-find-symbol)
  (define-key helm-gtags-mode-map (kbd "M-p")   'helm-gtags-parse-file)

  (define-key helm-gtags-mode-map (kbd "C-c <") 'helm-gtags-previous-history)
  (define-key helm-gtags-mode-map (kbd "C-c >") 'helm-gtags-next-history)
  )

(setq-local imenu-create-index-function #'ggtags-build-imenu-index)

Compiling

(define-key prog-mode-map (kbd "C-,") 'compile)
(define-key prog-mode-map (kbd "C-.") 'recompile)

flycheck

In order for flycheck to work with:

  • C/C++: M-x irony-install-server
  • Python: M-x jedi:install-server

Source: https://www.reddit.com/r/emacs/comments/931la6/tip_how_to_adopt_flycheck_as_your_new_best_friend/

(use-package flycheck
  :ensure t
  :requires hydra
  :bind ("C-c v" . tedi:checkSource/body)
  :init (global-flycheck-mode)
  :custom
  (defhydra tedi:checkSource (:color blue)
    "
      ^
      ^Flycheck^          ^Errors^            ^Checker^
      ^────────^──────────^──────^────────────^───────^─────
      _q_ quit            _<_ previous        _?_ describe
      _M_ manual          _>_ next            _d_ disable
      _v_ verify setup    _f_ check           _m_ mode
      ^^                  _l_ list            _s_ select
      ^^                  ^^                  ^^
    "
    ("q" nil)
    ("<" flycheck-previous-error :color pink)
    (">" flycheck-next-error :color pink)
    ("?" flycheck-describe-checker)
    ("M" flycheck-manual)
    ("d" flycheck-disable-checker)
    ("f" flycheck-buffer)
    ("l" flycheck-list-errors)
    ("m" flycheck-mode)
    ("s" flycheck-select-checker)
    ("v" flycheck-verify-setup))
  (flycheck-display-errors-delay .3)
  ;;(flycheck-stylelintrc "~/.stylelintrc.json")
  )

company mode

I set the delay for company mode to kick in to half a second, I also make sure that it starts doing its magic after typing in only 2 characters.

I prefer C-n and C-p to move around the items, so I remap those accordingly.

(use-package company
  :ensure t
  :config
  (setq company-idle-delay 0.0)
  (setq company-minimum-prefix-length 1)

  ;; set default `company-backends'
  (setq company-backends
        '((company-files          ; files & directory
           company-keywords       ; keywords
           company-capf
           company-yasnippet
           )
          (company-abbrev company-dabbrev)
          ))
  )

(with-eval-after-load 'company
  (define-key company-active-map (kbd "M-n") nil)
  (define-key company-active-map (kbd "M-p") nil)
  (define-key company-active-map (kbd "C-n") #'company-select-next)
  (define-key company-active-map (kbd "C-p") #'company-select-previous)
  (define-key company-active-map (kbd "SPC") #'company-abort))

specific languages

Be it for code or prose, completion is a must. After messing around with auto-completion for a while I decided to drop it in favor of company, and it turns out to have been a great decision.

Each category also has additional settings.

c/c++

yasnippet

(add-hook 'c++-mode-hook 'yas-minor-mode)
(add-hook 'c-mode-hook 'yas-minor-mode)

flycheck

(use-package flycheck-clang-analyzer
  :ensure t
  :config
  (with-eval-after-load 'flycheck
    (require 'flycheck-clang-analyzer)
     (flycheck-clang-analyzer-setup)))

company

Requires libclang to be installed.

(with-eval-after-load 'company
  (add-hook 'c++-mode-hook 'company-mode)
  (add-hook 'c-mode-hook 'company-mode))

(use-package company-c-headers
  :ensure t)

(use-package company-irony
  :ensure t
  :config
  (setq company-backends
        '((company-files          ; files & directory
           company-keywords       ; keywords
           company-capf
           company-yasnippet
           company-c-headers
           company-gtags
           company-clang
           company-dabbrev-code
           company-irony
           )
          (company-abbrev company-dabbrev)
          ))
  )


(use-package irony
  :ensure t
  :config
  (add-hook 'c++-mode-hook 'irony-mode)
  (add-hook 'c-mode-hook 'irony-mode)
  (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options))

python

Interpreter version

(setq python-shell-interpreter "python3")

yasnippet

(add-hook 'python-mode-hook 'yas-minor-mode)

flycheck

(add-hook 'python-mode-hook 'flycheck-mode)

company

;  (with-eval-after-load 'company
;      (add-hook 'python-mode-hook 'company-mode))

;  (use-package company-jedi
;    :ensure t
;    :config
;      (require 'company)
;      (add-to-list 'company-backends 'company-jedi))

;  (defun python-mode-company-init ()
;    (setq-local company-backends '((company-jedi
;                                    company-yasnippet
;                                    company-etags
;                                    company-dabbrev-code))))

;  (use-package company-jedi
;    :ensure t
;    :config
;      (require 'company)
;      (add-hook 'python-mode-hook 'python-mode-company-init))

emacs-lisp

eldoc

(add-hook 'emacs-lisp-mode-hook 'eldoc-mode)

yasnippet

(add-hook 'emacs-lisp-mode-hook 'yas-minor-mode)

company

(add-hook 'emacs-lisp-mode-hook 'company-mode)

(use-package slime
  :ensure t
  :config
  (setq inferior-lisp-program "/usr/bin/sbcl")
  (setq slime-contribs '(slime-fancy)))

(use-package slime-company
  :ensure t
  :init
    (require 'company)
    (slime-setup '(slime-fancy slime-company)))

lua

yasnippet

(add-hook 'lua-mode-hook 'yas-minor-mode)

flycheck

(add-hook 'lua-mode-hook 'flycheck-mode)

company

(add-hook 'lua-mode-hook 'company-mode)

(defun custom-lua-repl-bindings ()
  (local-set-key (kbd "C-c C-s") 'lua-show-process-buffer)
  (local-set-key (kbd "C-c C-h") 'lua-hide-process-buffer))

(defun lua-mode-company-init ()
  (setq-local company-backends '((company-lua
                                  company-etags
                                  company-dabbrev-code))))

(use-package company-lua
  :ensure t
  :config
    (require 'company)
    (setq lua-indent-level 4)
    (setq lua-indent-string-contents t)
    (add-hook 'lua-mode-hook 'custom-lua-repl-bindings)
    (add-hook 'lua-mode-hook 'lua-mode-company-init))

bash

yasnippet

(add-hook 'shell-mode-hook 'yas-minor-mode)

flycheck

(add-hook 'shell-mode-hook 'flycheck-mode)

company

(add-hook 'shell-mode-hook 'company-mode)

(defun shell-mode-company-init ()
  (setq-local company-backends '((company-shell
                                  company-shell-env
                                  company-etags
                                  company-dabbrev-code))))

(use-package company-shell
  :ensure t
  :config
    (require 'company)
    (add-hook 'shell-mode-hook 'shell-mode-company-init))

Org

One of the absolute greatest features of emacs is called “org-mode”. This very file has been written in org-mode, a lot of other configurations are written in org-mode, same goes for academic papers, presentations, schedules, blogposts and guides. Org-mode is one of the most complex things ever, lets make it a bit more usable with some basic configuration.

Those are all rather self-explanatory.

Common settings

(setq org-ellipsis " ")
(setq org-src-fontify-natively t)
(setq org-src-tab-acts-natively t)
(setq org-confirm-babel-evaluate nil)
(setq org-export-with-smart-quotes t)
(setq org-src-window-setup 'current-window)
(add-hook 'org-mode-hook 'org-indent-mode)

Hide asterisks etc characters to behave more like a word processor.

url: https://howardism.org/Technical/Emacs/orgmode-wordprocessor.html

(setq org-hide-emphasis-markers t)

Open org link in the same window

(setf (cdr (assoc 'file org-link-frame-setup)) 'find-file)

Return follows link

(customize-set-variable 'org-return-follows-link t)

Display links as the description provided

(customize-set-variable 'org-link-descriptive t)

Syntax highlighting for documents exported to HTML

(use-package htmlize
  :ensure t)

Install org and configure

(use-package org
  ;; It is first installed in init.el so tell elpaca to use that one.
  :elpaca nil
  :ensure t
  :config
  (org-babel-do-load-languages
   'org-babel-load-languages
   '(
     ;; https://orgmode.org/worg/org-contrib/babel/languages.html
     (awk . t)
     (ditaa . t)
     (dot . t)
     (css . t)
     (calc .t)
     (C . t)
     (emacs-lisp . t)
     (haskell . t)
     (gnuplot . t)
     (latex . t)
     ;;(ledger . t)
     (js . t)
     ;;(http . t)
     (perl . t)
     (python . t)
     (R . t)
     (scheme . t)
     ;;(sh . t)
     (shell . t)
     (sql . t)
     (sqlite . t)
     )))

Keybindings

(global-set-key (kbd "C-c '") 'org-edit-src-code)

Line wrapping

(add-hook 'org-mode-hook
          (lambda ()
             (visual-line-mode 1)))

Org Bullets

Makes it all look a bit nicer, I hate looking at asterisks.

(use-package org-bullets
  :ensure t
  :config
  (add-hook 'org-mode-hook (lambda () (org-bullets-mode))))

Easy-to-add emacs-lisp template

Hitting tab after an “<el” in an org-mode file will create a template for elisp insertion.

(add-to-list 'org-structure-template-alist
             '("el" . "src emacs-lisp"))

(add-to-list 'org-structure-template-alist
             '("py" . "src python -n"))

(add-to-list 'org-structure-template-alist
             '("cl" . "src C"))

(add-to-list 'org-structure-template-alist
             '("sh" . "src shell"))
(add-hook 'org-mode-hook 'yas-minor-mode)

Exporting options

One of the best things about org is the ability to export your file to many formats. Here is how we add more of them!

Hugo

(use-package ox-hugo
  :ensure t
  :after ox)

latex

(when (file-directory-p "/usr/share/emacs/site-lisp/tex-utils")
  (add-to-list 'load-path "/usr/share/emacs/site-lisp/tex-utils")
  (require 'xdvi-search))

Twitter Bootstrap

(use-package ox-twbs
  :ensure t)

Reveal.js

(use-package ox-reveal
  :ensure t
  :config
  (setq org-reveal-root "file:///home/tedi/.emacs.d/reveal.js-4.1.0/")
  (setq org-reveal-title-slide nil))

Org Roam

Fast note insertion for a smoother writing flow

Sometimes while writing, you’ll want to create a new node in your Org Roam notes without interrupting your writing flow! Typically you would use org-roam-node-insert, but when you create a new note with this command, it will open the new note after it gets created.

We can define a function that enables you to create a new note and insert a link in the current document without opening the new note’s buffer.

This will allow you to quickly create new notes for topics you’re mentioning while writing so that you can go back later and fill those notes in with more details!

(defun my/org-roam-node-insert-immediate (arg &rest args)
  (interactive "P")
  (let ((args (cons arg args))
        (org-roam-capture-templates (list (append (car org-roam-capture-templates)
                                                  '(:immediate-finish t)))))
    (apply #'org-roam-node-insert args)))

Install and configure org-roam

(use-package org-roam
:ensure t
:custom

;; This is where all my org-roam notes are stored.
(org-roam-directory "~/org/roam")

;; This is the relative path to *org-roam-directory* where dailies are stored.
(setq org-roam-dailies-directory "daily/")

;; Display the org-roam note type in the mini-buffer.
;;(setq org-roam-node-display-template
;;      (concat "Hello: ${type:15} ${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
;;(setq org-roam-node-display-template "${title:*} {tags:50}")
;;(setq org-roam-node-display-template "{tags:50}")

;; My templates
(org-roam-completion-everywhere t)
;;(org-roam-completion-system 'default)

;; My templates for new notes
(org-roam-capture-templates
 '(
   ("d" "default" plain
    (file "~/.emacs.d/templates/org-roam/default.org")
    :if-new (file+head "notes/${slug}-%<%Y%m%d%H%M%S>.org" "#+title: ${title}\n#+filetags: :fleeting:\n")
    :unnarrowed t)
   ("n" "note" plain
    (file "~/.emacs.d/templates/org-roam/default.org")
    :if-new (file+head "notes/${slug}-%<%Y%m%d%H%M%S>.org" "#+title: ${title}\n#+filetags: :fleeting:\n")
    :unnarrowed t)
   ("p" "blog post" plain
    (file "~/.emacs.d/templates/org-roam/default.org")
    :if-new (file+head "blog/${slug}.org" "#+title: ${title}\n#+filetags: :blog:\n")
    :immediate-finish t
    :unnarrowed t)
   ))

;; Template for org-roam dailies.
(setq org-roam-dailies-capture-templates
    '(("d" "default" entry
       (file "~/.emacs.d/templates/org-roam/daily.org")
       :target (file+head "%<%Y-%m-%d>.org"
                          "#+title: %<%Y-%m-%d>\n"))))

;; Configuring what is displayed in the buffer
(setq org-roam-mode-sections
      (list #'org-roam-backlinks-section
            #'org-roam-reflinks-section
            #'org-roam-unlinked-references-section
            ))
:bind (("C-c l" . org-roam-buffer-toggle)
       ("C-c f" . org-roam-node-find)
       ("C-c i" . org-roam-node-insert)
       ("C-c a" . my/org-roam-node-insert-immediate)
       ("C-c v" . org-roam-node-random))
:config
;;(org-roam-setup)
(require 'org-roam-dailies) ;; Ensure the keymap is available
;; Publish org-roam
(require 'org-roam-export)
(org-roam-db-autosync-mode))

UI

; Dependency of org-roam-ui
(use-package websocket
    :after org-roam)

  (use-package org-roam-ui
      :after org-roam ;; or :after org
  ;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;;         a hookable mode anymore, you're advised to pick something yourself
  ;;         if you don't care about startup time, use
  ;;  :hook (after-init . org-roam-ui-mode)
      :config
      (setq org-roam-ui-sync-theme t
            org-roam-ui-follow t
            org-roam-ui-update-on-save t
            org-roam-ui-open-on-start t))

Iedit

Edit multiple regions simultaneously

(use-package iedit
  :ensure t)
  ;; :config
  ;; This is a bug in Mac but in linux works.(I do not need a fix)
  ;; (define-key global-map (kbd "C-c ;") 'iedit-mode)

Avy

Navigation to any place inside the window

(use-package avy
  :ensure t
  :bind ("M-s" . avy-goto-char))

Stack Overflow

(use-package sx
  :ensure t
  :config
  (bind-keys :prefix "C-c s"
             :prefix-map my-sx-map
             :prefix-docstring "Global keymap for SX."
             ("q" . sx-tab-all-questions)
             ("i" . sx-inbox)
             ("o" . sx-open-link)
             ("u" . sx-tab-unanswered-my-tags)
             ("a" . sx-ask)
             ("s" . sx-search)))

LSP

Add icons to company

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

Glue company and lsp

After emacs 27 update this stopped working.

;;  (use-package company-lsp
;;    :after (company lsp-mode)
;;    :ensure t)

Lsp-mode

May need to run lsp-install-server and select the language of choice For python also run: pip install python-language-server[all]

(use-package lsp-mode
  :ensure t
  :after (
          flycheck
          which-key)
  :init
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  ; (setq lsp-keymap-prefix "C-c l")
  ;; Ignore tabs for identation and lines bigger than 80 chars
  (setq lsp-pyls-plugins-pycodestyle-ignore '("W191" "E501"))
  ; (setq lsp-headline-breadcrumb-mode -1)
  :hook (
         (sh-mode . lsp)
         (python-mode . lsp)
         ;; if you want which-key integration
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp)

Lsp-mode UI

(use-package lsp-ui
  :commands lsp-ui-mode
  :config
  (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
  (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)
  (setq lsp-ui-sideline-enable t
        lsp-ui-doc-enable t
        lsp-ui-flycheck-enable t
        lsp-ui-imenu-enable t
        lsp-ui-sideline-ignore-duplicate t))

Extra (not all needed)

;; if you are helm user
  ;(use-package helm-lsp :commands helm-lsp-workspace-symbol)
  ;; if you are ivy user
  (use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
  ;(use-package lsp-treemacs :commands lsp-treemacs-errors-list)

  ;; optionally if you want to use debugger
  (use-package dap-mode)
  ;; (use-package dap-LANGUAGE) to load the dap adapter for your language

New

Bindings

;;  (general-define-key                                          ;"M-x" 'smex
;;   "C-s" 'counsel-grep-or-swiper)

;;  (general-define-key
;;   :prefix "C-c"
;;   ;; bind "C-c a" to 'org-agenda
;;   "j" 'counsel-git-grep
;;   "s" 'eshell
;;   "b" 'butterfly
;;   )

Git

;;Display line changes in gutter based on git history. Enable it everywhere.

;;(use-package git-gutter
;;  :config
;;  (global-git-gutter-mode t))

;;(use-package git-gutter+
;;  :config
;;  (global-git-gutter+-mode))

(use-package git-gutter-fringe+
  :bind
  (("C-c m d" . git-gutter+-show-hunk-inline-at-point)
   ("C-c m p" . git-gutter+-previous-hunk)
   ("C-c m n" . git-gutter+-next-hunk))
  :init
  (global-git-gutter+-mode))

;;(use-package diff-hl
;;  :init
;;  (message "Loading diff-hl!")
;;  :config
;;  (message "Loaded diff-hl!")
;;  (global-diff-hl-mode)

;;  (diff-hl-margin-mode)
;;  ;;(diff-hl-flydiff-mode)
;;  )

Reformat Python code

;(defun reformat-code ()
;  (interactive)
;  (let ((file-extension (file-name-extension buffer-file-name)))
;    (cond
;     ((string= file-extension "c")
;      (shell-command-on-region (point-min) (point-max) "your-c-formatter"))
;     ((string= file-extension "py")
;      (py-autopep8-enable-on-save) (py-autopep8)))))
;
;(add-hook 'before-save-hook #'reformat-code)

org faces

(add-hook 'org-mode-hook
          (lambda ()
            (let* ((variable-tuple (cond ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
                                         ((x-list-fonts "Lucida Grande")   '(:font "Lucida Grande"))
                                         ((x-list-fonts "Verdana")         '(:font "Verdana"))
                                         ((x-family-fonts "Sans Serif")    '(:family "Sans Serif"))
                                         (nil (warn "Cannot find a Sans Serif Font.  Install Source Sans Pro."))))
                   (base-font-color     (face-foreground 'default nil 'default))
                   (headline           '(:inherit default :weight bold)))

              (custom-set-faces
                                      '(org-level-8 ((t (,@headline ,@variable-tuple))))
                                      '(org-level-7 ((t (,@headline ,@variable-tuple))))
                                      '(org-level-6 ((t (,@headline ,@variable-tuple))))
                                      '(org-level-5 ((t (,@headline ,@variable-tuple))))
                                      '(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1 :foreground "#66d9ef"))))
                                      '(org-level-3 ((t (,@headline ,@variable-tuple :height 1.15 :foreground "Yellow"))))
                                      '(org-level-2 ((t (,@headline ,@variable-tuple :height 1.25 :foreground "#a6e22e"))))
                                      '(org-level-1 ((t (,@headline ,@variable-tuple :height 1.5 :foreground "Orange"))))
                                      '(org-document-title ((t (,@headline ,@variable-tuple :height 1.5 :underline nil))))

                                      '(org-block                 ((t (:inherit fixed-pitch))))
                                      '(org-document-info         ((t (:foreground "Red"))))
                                      '(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
                                      '(org-link                  ((t (:foreground "#a6e22e" :underline t))))
                                      '(org-meta-line             ((t (:inherit (font-lock-comment-face fixed-pitch)))))
                                      '(org-property-value        ((t (:inherit fixed-pitch))) t)
                                      '(org-special-keyword       ((t (:inherit (font-lock-comment-face fixed-pitch)))))
                                      '(org-tag                   ((t (:inherit (shadow fixed-pitch) :weight bold :height 0.8))))
                                      '(org-verbatim              ((t (:inherit (shadow fixed-pitch)))))
                                      '(org-indent                ((t (:inherit (org-hide fixed-pitch)))))
                                      '(org-table                 ((t (:inherit (org-hide fixed-pitch)))))
                                      ;; check if this works
                                      '(org-comment               ((t (:inherit (org-hide fixed-pitch) :height 0.8))))

                                      ))
            ))
;; (let* ((variable-tuple (cond ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
;;                              ((x-list-fonts "Lucida Grande")   '(:font "Lucida Grande"))
;;                              ((x-list-fonts "Verdana")         '(:font "Verdana"))
;;                              ((x-family-fonts "Sans Serif")    '(:family "Sans Serif"))
;;                              (nil (warn "Cannot find a Sans Serif Font.  Install Source Sans Pro."))))
;;        (base-font-color     (face-foreground 'default nil 'default))
;;        (headline           '(:inherit default :weight bold)))

;;   (custom-theme-set-faces 'user
;;                           '(org-level-8 ((t (,@headline ,@variable-tuple))))
;;                           '(org-level-7 ((t (,@headline ,@variable-tuple))))
;;                           '(org-level-6 ((t (,@headline ,@variable-tuple))))
;;                           '(org-level-5 ((t (,@headline ,@variable-tuple))))
;;                           '(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1 :foreground "#66d9ef"))))
;;                           '(org-level-3 ((t (,@headline ,@variable-tuple :height 1.15 :foreground "Yellow"))))
;;                           '(org-level-2 ((t (,@headline ,@variable-tuple :height 1.25 :foreground "#a6e22e"))))
;;                           '(org-level-1 ((t (,@headline ,@variable-tuple :height 1.5 :foreground "Orange"))))
;;                           '(org-document-title ((t (,@headline ,@variable-tuple :height 1.5 :underline nil))))

;;                           '(org-block                 ((t (:inherit fixed-pitch))))
;;                           '(org-document-info         ((t (:foreground "Red"))))
;;                           '(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
;;                           '(org-link                  ((t (:foreground "#a6e22e" :underline t))))
;;                           '(org-meta-line             ((t (:inherit (font-lock-comment-face fixed-pitch)))))
;;                           '(org-property-value        ((t (:inherit fixed-pitch))) t)
;;                           '(org-special-keyword       ((t (:inherit (font-lock-comment-face fixed-pitch)))))
;;                           '(org-tag                   ((t (:inherit (shadow fixed-pitch) :weight bold :height 0.8))))
;;                           '(org-verbatim              ((t (:inherit (shadow fixed-pitch)))))
;;                           '(org-indent                ((t (:inherit (org-hide fixed-pitch)))))
;;                           '(org-table                 ((t (:inherit (org-hide fixed-pitch)))))
;;                           ;; check if this works
;;                           '(org-comment               ((t (:inherit (org-hide fixed-pitch) :height 0.8))))

;;                           ))