systemhalted's Emacs

Table of Contents

Why Emacs?

I started using Emacs in 2010 and my relationship with it has been on and off. I mostly use Jetbrains IntelliJ IDEA for my work. But the idea of Emacs - everything inside is awesome. You can configure IDEA to an extent but after that it just gives up. Checking emails, managing schedule, and taking notes - few things that are lacking in IDEA. Emacs on the other hand is an Operating System in itself. You can configure it the way you want and for your comfort and there is a huge community to help, guide and support you.

About

This is my personal Emacs configuration. Over past few years, I had been using Emacs configuration by others. I used to modify few things here and there in my old configuration but not before spending several hours and without understanding what is going on. So, after reading r/emacs discussions, I decided that I will get rid of all the Emacs configurations and start it at the very beginning. I have not used Emacs for any coding purposes. I code in Java and IntelliJ IDEA is the best IDE for that. Therefore, I decided that in the beginning, I do not need many configurations. Since the discussion on the r/emacs was all about Literate Programming and how org-mode facilitates that, I decided to start with setting up org-mode first

Configurations

About this file

Org File Tweaks

There are a few tweaks included in this org file that make it a little easier to work with.

  • Automatically Tangle

    First there is a property defined on the file:

    header-args :tangle yes
    		    

    This tells emacs to automatically tangle (include) all code blocks in this file when generating the code for the config, unless the code block explicitly includes :tangle no as the above code block does.

    You will notice that I explicitly use :tangle property in all source blocks. It is a temporary thing as I am still trying to test out my configuration by turning on and off the source code blocks from auto tangle.

  • Visibility Settings

    Next we have a property that defines the visibility for org to show it's direct children on startup. This way a clean outline of all sub headings under Configuration is shown each time this file is opened in org-mode.

    :PROPERTIES:
    		      :VISIBILITY: children
    		      :END:
    		    
  • Table of Contents

    Finally, there is a Table of Contents heading that includes the tag: :TOC_5_gh:. This tells an org-mode package toc-org to generate a table of contents under this heading that has a max depth of 3 and is created using Github-style hrefs. This table of contents is updated everytime the file is saved and makes for a functional table of contents that works property directly on github.

  • Org Babel

    This file is loaded using org-babel. Create init.el file in /.emacs.d/ folder and put following code

    		    

Global Settings

Load Customizations from folder

I put some scripts in customizations folder. Lets load this folder.

(add-to-list 'load-path "~/.emacs.d/customizations")
		

Setup Proxy

I use Emacs on my work laptop and there is a firewall that I need to pass through. Proxy settings allow me to do that. Save the below code under customizations and call it setup-proxy.el

(setq url-proxy-services
		  '(("no_proxy" . "^\\(localhost\\|10.*\\)")
		  ("http" . "proxy:port")
		  ("https" . "proxy:prt")))

		  (setq url-http-proxy-basic-auth-storage
		  (list (list "proxy:port"
                  (cons "Input your LDAP UID !"
                  (base64-encode-string "UserName:Password")))))
		

Custom File

Emacs has an Easy Customization Interface, which can be invoked by M-x customize. When you use it, it puts the custom-set-variables in init.el. But I hardly use it as I have all my configurations as part of this config file. Thus, I want Emacs to use a different file to put these configurations. And since Emacs is Emacs, it does not mind.

(setq custom-file "~/.emacs.d/emacs-custom.el")
		  (load custom-file)  
		

Here we are asking Emacs to use a different file emacs-custom.el to store these customizations and are loading this file so that in case anything is there, it can be loaded for next session.

Package Configuration

Emacs is an ecosystem of packages, which are important to make Emacs your home. Traditionally, Elpa was the repository of choice for Emacs but lately more modern repositories have started flourishing. If you type command M-x list-packages in the Emacs without loading this config file, you will see a list of packages from ELPA. Here we will define the repositories to let Emacs know where to go and fetch the packages from.

(require 'package)
		  (setq-default
		  load-prefer-newer t
		  package-enable-at-startup nil)
		  (add-to-list 'package-archives
		  '("gnu" . "https://elpa.gnu.org/packages/") t)
		  (add-to-list 'package-archives
		  '("marmalade" . "http://marmalade-repo.org/packages/") t)
		  (add-to-list 'package-archives
		  '("tromey" . "http://tromey.com/elpa/") t)
		  (add-to-list 'package-archives
		  '("org" . "http://orgmode.org/elpa/") t)
		  (add-to-list 'package-archives
		  '("melpa" . "http://melpa.org/packages/") t)
		  (add-to-list 'package-archives
		  '("melpa-stable" . "http://stable.melpa.org/packages/") t)
		  (package-initialize)
		

Here, we asked Emacs to load a package called package, which is the package manager that comes with Emacs out of the box. Also, we defined a list of package-archives. In the end we initialized and ask Emacs to refresh it’s package list.

Install and Configure use-package

We will be using a few packages that don’t ship with Emacs. We’ll be using use-package to define the configurations. We could have continued using the built-in package manager, but use-package makes the configuration file look neat and clean. In itself it is not a package manager but an efficient way to load packages. It is easy to use. In case you need a tutorial on few of its keywords, read this.

(unless (package-installed-p 'use-package)
		  (package-refresh-contents)
		  (package-install 'use-package t))
		  (setq-default use-package-always-defer t
		  use-package-always-ensure t)
		

We are setting two properties, viz., :defer and :ensure to always be true when using use-package. In other words we are setting this globally for all the packages. Setting :defer to true means, that we are expecting another package to do something to load a particular package by say, :bind. The :ensure settings tell the package manager to install the package automatically if it is not already present.

Custom Functions

  • SpeedTest
    (load "setup-speedtest.el")
    		  

UI Customization

Some of these settings were copied from Sergei Nosov's configurations.

Lean and mean

Emacs doesn’t need a lot of UI elements - it should be lean and mean. Well, and clean.

  • Disable startup/splash screen
    (setq inhibit-startup-screen t)
    		    
  • Setup initial major mode to Org-mode
    (setq-default initial-major-mode (quote org-mode))
    		    
  • Remove scratch message
    (setq-default initial-scratch-message nil)
    		    
  • Disable Unnecessary Interface
    (menu-bar-mode -1)
    		      (tool-bar-mode -1)
    		      (unless (and (display-graphic-p) (eq system-type 'darwin))
    		      (push '(menu-bar-lines . 0) default-frame-alist))
    		      (push '(tool-bar-lines . 0) default-frame-alist)
    		      (push '(vertical-scroll-bars) default-frame-alist)
    		    
  • Reduce the delay echoing the keystrokes

    When you press C-x, for example, and hesitate with a next character, C-x will be displayed in the echo-area after some time. But I don’t see any reason why you should wait for it.

    (setq echo-keystrokes 0.00111)
    		    
  • Full Screen
    (toggle-frame-fullscreen)
    		      (add-to-list 'default-frame-alist '(fullscreen . fullboth))
    		      ;;(add-hook 'window-setup-hook 'toggle-frame-maximized t).
    		    
  • Display Line Numbers on the side
    (global-display-line-numbers-mode t)
    		    
  • But disable line numbers for certain modes
    (dolist (mode '(org-mode-hook
                          term-mode-hook
                          shell-mode-hook
                          eshell-mode-hook
    		      ))
    		      (add-hook mode (lambda() (display-line-numbers-mode 0))))
    
    		    

PDF

(setq doc-view-continuous t)
		

Fonts, Theme and Modeline

  • Font
    (defvar systemhalted/default-font-size 140)
    		      (set-face-attribute 'default nil
                          :font "Fira Code"
                          :height systemhalted/default-font-size)
    
    		      ;; Set the fixed pitch face
    		      (set-face-attribute 'fixed-pitch nil :font "Fira Code" :height 160)
    
    		      ;; Set the variable pitch face
    		      (set-face-attribute 'variable-pitch nil :font "Cantarell" :height 160 :weight 'regular)
    		    
  • Theme
    (use-package doom-themes
    		      :init (load-theme 'doom-palenight t))
    		    
  • Modeline
    • Time and Battery
      (display-time-mode 1)
      			  (display-battery-mode 1)
      			
    • Doom Modeline
      (use-package all-the-icons)     
      
      			  (use-package doom-modeline
      			  :init (doom-modeline-mode 1)
      			  :custom (doom-modeline-height 10))
      
      			
    • Cursor Position
      (setq line-number-mode t)
      			  (setq column-number-mode t)
      			

Which Key?

As a newbie (and also as an experienced) Emacser, it is difficult to remember all the keybindings. And I do not think that anyone needs to remember all of them. Here is where which-key package comes into picture. It is an Emacs Minor Mode, that displays the key bindings following your currently entered incomplete command (a prefix).

(use-package which-key                             
		  :init                                            
		  (which-key-mode)                                         
		  :config                                                  
		  (which-key-setup-side-window-bottom)             
		  (setq which-key-sort-order 'which-key-key-order-alpha 
		  ;; which-key-side-window-max-width 0.33            
		  which-key-idle-delay 0.05)                         
		  :diminish which-key-mode)                               
		

Text Manipulation

Move text

Most of the time, I need to move a the text up an down a bit. There is a transpose-line command that maps to C-x C-t, which is cumbersome and most of the time it messes-up with my flow. So, here we will map it to M-n and M-p following the convention of movement keys. Note: If you need to move the text to some pretty distant place, then, of course, it’s easier to kill and yank it.

(eval-after-load "move-text-autoloads"
		  '(progn
		  (if (require 'move-text nil t)
		  (progn
		  (define-key global-map (kbd "M-n") 'move-text-down)
		  (define-key global-map (kbd "M-p") 'move-text-up))
		  (message "WARNING: move-text not found"))))
		

Duplicate the current line

Equivalent of Ctrl+d (Command+d on Mac) in IntelliJ IDEA Source: https://www.emacswiki.org/emacs/CopyingWholeLines#toc12

(define-key global-map (kbd "C-c k")
		  (defun systemhalted/duplicate-line-or-region (&optional n)
		  "Duplicate current line, or region if active.
		      With argument N, make N copies.
		      With negative N, comment out original line and use the absolute value."
		  (interactive "*p")
		  (let ((use-region (use-region-p)))
		  (save-excursion
		  (let ((text (if use-region        ;Get region if active, otherwise line
                  (buffer-substring (region-beginning) (region-end))
                  (prog1 (thing-at-point 'line)
                  (end-of-line)
                  (if (< 0 (forward-line 1)) ;Go to beginning of next line, or make a new one
                  (newline))))))
		  (dotimes (i (abs (or n 1)))     ;Insert N times, or once if not specified
		  (insert text))))
		  (if use-region nil                  ;Only if we're working with a line (not a region)
		  (let ((pos (- (point) (line-beginning-position)))) ;Save column
		  (if (> 0 n)                             ;Comment out original with negative arg
		  (comment-region (line-beginning-position) (line-end-position)))
		  (forward-line 1)
		  (forward-char pos))))))
		

Join following line

(define-key global-map (kbd "C-c j")
		  (defun systemhalted/join-following-line (arg)
		  "Joins the following line or the whole selected region"
		  (interactive "P")
		  (if (use-region-p)
		  (let ((fill-column (point-max)))
		  (fill-region (region-beginning) (region-end)))
		  (join-line -1))))
		

String manipulations

Emacs 24.4 came with a subr-x library with routines for string manipulations, like string-trim, string-join and etc. It’s better to always have these at hand.

(require 'subr-x nil t)
		

Shortcuts, Longcuts, Miscellaneous Configs

Clipboard. Copy from terminal emacs to the X clipboard.

(use-package xclip
		  :config
		  (xclip-mode 1))

		

Simplify Yes/No Prompts

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

But make it hard to accidentally exit

(setq-default confirm-kill-emacs (quote y-or-n-p))
		

UTF-8 Coding System

Use UTF-8 as much as possible

(set-language-environment 'utf-8)                                                           
		  (setq locale-coding-system 'utf-8)                                                          

		  ;; set the default encoding system                                                          
		  (prefer-coding-system 'utf-8)                                                               
		  (setq default-file-name-coding-system 'utf-8)                                               
		  (set-default-coding-systems 'utf-8)                                                         
		  (set-terminal-coding-system 'utf-8)                                                         
		  (set-keyboard-coding-system 'utf-8)                                                         

		  ;; Treat clipboard input as UTF-8 string first; compound text next, etc.                    
		  (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) 
		

Shut up the bell

(setq ring-bell-function 'ignore) 
		

Disabled Commands

Change nil to t to disable the command. Note: currently not using it. But this is the way to do it

(put 'upcase-region 'disabled nil) 
		

Always kill the buffer

(defun kill-current-buffer ()
		  "Kills the current buffer."
		  (interactive)
		  (kill-buffer (current-buffer)))
		  (global-set-key (kbd "C-x k") 'kill-current-buffer)
		

Visit systemhalted.org

(defun systemhalted/config-visit ()
		  (interactive)
		  (find-file "~/.emacs.d/systemhalted.org"))
		  (global-set-key (kbd "C-c e") 'systemhalted/config-visit)
		

Reload Config

(defun systemhalted/config-reload ()
		  "Reloads ~/.emacs.d/systemhalted.org at runtime"
		  (interactive)
		  (org-babel-load-file (expand-file-name "~/.emacs.d/systemhalted.org")))
		  (global-set-key (kbd "C-c r") 'systemhalted/config-reload)
		

Electric

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

		  (electric-pair-mode t)
		

Show Parens

(show-paren-mode 1)
		

Exile the backup files

Backup files are insanely irritating if you expect clean ls output and don't want to filter out irrelevant junk. The right thing is to exile them to a dedicated directory:

Reference: Somehwhere on Reddit (find the post and link here)

(setq backup-by-copying t
		  backup-directory-alist `(("." . ,(concat user-emacs-directory "backups")))
		  tramp-backup-directory-alist backup-directory-alist
		  delete-old-versions t
		  kept-new-versions 3
		  kept-old-versions 2
		  version-control t
		  vc-cvs-stay-local nil)
		

Try

Try is a package that allows you to try out Emacs packages without installing them.

		  (use-package try)

		

Directory and File Retrieval

Emacs-Helm

Helm is a framework for incremental completion and selection written for Emacs. It helps to rapidly complete file names, buffer names, or any other Emacs interactions requiring selecting an item from a list of possible choices. I am still learning it. I will update this as and when I get more knowledge on this package.

(use-package helm 
		  :bind
		  ("C-x C-f" . 'helm-find-files)
		  ("C-x C-b" . 'helm-buffers-list)
		  ("M-x" . 'helm-M-x)
		  ("C-x f" . 'helm-recentf)
		  :config
		  (setq helm-autoresize-max-height 0
		  helm-autoresize-min-height 40
		  helm-M-x-fuzzy-match t
		  helm-buffers-fuzzy-matching t
		  helm-recentf-fuzzy-match t
		  helm-semantic-fuzzy-match t
		  helm-imenu-fuzzy-match t
		  helm-split-window-in-side-p nil
		  helm-move-to-line-cycle-in-source nil
		  helm-ff-search-library-in-sexp t
		  helm-scroll-amount 8 
		  helm-echo-input-in-header-line t)
		  :init
		  (helm-mode 1))

		  (require 'helm-config)    
		  (helm-autoresize-mode 1)
		  (define-key helm-find-files-map (kbd "C-l") 'helm-find-files-up-one-level)
		  (define-key helm-find-files-map (kbd "C-f") 'helm-execute-persistent-action)

		

iBuffer

Before iPhone, there was iBuffer.

(global-set-key (kbd "C-x b") 'ibuffer)
		  (setq ibuffer-expert t)
		

Treemacs

(use-package treemacs 
		  :init
		  (add-hook 'treemacs-mode-hook
		  (lambda () (treemacs-resize-icons 15))))

		

Reading and Writing

Markdown mode

(use-package markdown-mode
		  :commands (markdown-mode gfm-mode)
		  :mode (("README\\.md\\'" . gfm-mode)
		  ("\\.md\\'" . markdown-mode)
		  ("\\.markdown\\'" . markdown-mode))
		  :init (setq markdown-command "/usr/local/bin/multimarkdown"))
		

YAML mode

(use-package yaml-mode
		  :mode (("\\.yml\\'" . yaml-mode)
		  ("Bogiefile" . yaml-mode))
		  :init
		  (add-hook 'yaml-mode-hook
		  '(lambda ()
		  (define-key yaml-mode-map "\C-m" 'newline-and-indent))))

		

Nov Mode

I prefer reading EPUB books on Emacs. Nov Mode allows me do that

(use-package nov 
		  :demand t)

		  (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

		  ;; set unzip
		  (setq nov-unzip-program "/usr/bin/unzip") ;;nov needs to know the location of unzip package
		

define-word

Word and their meanings and what better way to have this information at point.

(use-package define-word
		  :defer t
		  :init (global-set-key (kbd "C-c d") 'define-word-at-point)
		  (global-set-key (kbd "C-c D") 'define-word))

		

Idle Highlight

Idle highlight mode sets an idle timer that highlights all occurences in the buffer of the word under the point.

(use-package idle-highlight)
		

Pdf Tools

PDF Tools is, among other things, a replacement of DocView for PDF files. The key difference is that pages are not pre-rendered by e.g. ghostscript and stored in the file-system, but rather created on-demand and stored in memory.

Read the prerequisite: https://github.com/politza/pdf-tools

		  (use-package pdf-tools
		  :ensure t)
		  (pdf-tools-install)

		

PDFLatex

		  (setenv "PATH" (concat (getenv "PATH") ":/Library/TeX/texbin/pdflatex"))

		

Org

  • Org Agenda and Todo Setup

    Let's include a newer version of org-mode than the one that is built in. We're going to manually remove the org directories from the load path, to ensure the version we want is prioritized instead.

    (defun systemhalted/org-agenda-setup ()
    		    (setq org-log-done 'time
    		    org-log-done 'note
    		    org-ellipsis " ▾"
    		    org-agenda-files (list "~/org/inbox.org"
                        "~/org/gtd.org" 
                        "~/org/tickler.org"
                        "~/org/references.org")
    		    org-capture-templates '(("t" "Todo [inbox]" entry
                        (file+headline "~/org/inbox.org" "Tasks")
                        "* TODO %i%?")
                        ("T" "Tickler" entry
                        (file+headline "~/org/tickler.org" "Tickler")
                        "* %i%? \n %U"))
    		    org-todo-keywords '((sequence "TODO(t)" "START(s)" "WAIT(w)" "|" "DONE(d)" "CANCEL(c)" "HOLD(h)" "DELEGATE(g)"))))
    
    
    		    (setq org-refile-targets '((org-agenda-files :maxlevel . 4)
                        ("~/org/someday.org" :maxlevel . 1)
                        ("~/org/archive.org" :maxlevel . 4)
                        ))
    
    		  
  • Setup Org Look and Feel
    		    (defun systemhalted/org-mode-look-feel ()
    		    (org-indent-mode)
    		    (variable-pitch-mode 1)
    		    (visual-line-mode 1))
    
    		    (defun systemhalted/org-mode-visual-fill ()
    		    (setq visual-fill-column-width 120
    		    visual-fill-column-center-text t)
    		    (visual-fill-column-mode 1))
    
    		    (use-package visual-fill-column
    		    :hook (org-mode . systemhalted/org-mode-visual-fill)
    		    :hook (yaml-mode . systemhalted/org-mode-visual-fill))
    
    		    (defun systemhalted/org-font-setup ()
    		    ;; Replace list hyphen with dot
    		    (font-lock-add-keywords 'org-mode
                        '(("^ *\\([-]\\) "
                        (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
    
    		    ;; Set faces for heading levels
    		    (dolist (face '((org-level-1 . 1.2)
                        (org-level-2 . 1.1)
                        (org-level-3 . 1.05)
                        (org-level-4 . 1.0)
                        (org-level-5 . 1.1)
                        (org-level-6 . 1.1)
                        (org-level-7 . 1.1)
                        (org-level-8 . 1.1)))
    		    (set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))
    
    		    ;; Ensure that anything that should be fixed-pitch in Org files appears that way
    		    (set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
    		    (set-face-attribute 'org-code nil   :inherit '(shadow fixed-pitch))
    		    (set-face-attribute 'org-table nil   :inherit '(shadow fixed-pitch))
    		    (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
    		    (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
    		    (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
    		    (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch))
    		  
  • Org Setup
    (use-package org
    		    :ensure org-plus-contrib
    		    :pin org
    		    :defer t
    		    :hook (org-mode . systemhalted/org-mode-look-feel)
    		    :config (systemhalted/org-agenda-setup)
    		    (systemhalted/org-font-setup)
    		    :init 
    		    (define-key global-map (kbd "C-c l") 'org-store-link)
    		    (define-key global-map (kbd "C-c a") 'org-agenda)
    		    (define-key global-map (kbd "C-c c") 'org-capture))
    
    		  
  • Org Bullets

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

    (use-package org-bullets
    		    :hook
    		    (( org-mode ) . org-bullets-mode))
    		  
  • Org Tempo
    (require 'org-tempo)
    		  
  • Code editing in same window
    (setq org-src-window-setup 'current-window)
    		  
  • Toc-org

    Let's install and load the toc-org package after org mode is loaded. This is the package that automatically generates an up to date table of contents for us.

    (use-package toc-org
    		    :after org
    		    :hook (org-mode . toc-org-mode))
    		  
  • Org-sidebar

    When I write, I need a map of the document or the table of content on the side. Org-sidebar helps with that:

    (use-package org-sidebar
    		    :custom (org-sidebar-tree-side 'left))
    		  
  • Git Auto commit for Org files
    (use-package git-auto-commit-mode)
    		  
  • HTMLIZE

    Org-mode supports HTML export natively but syntax highlighting is added through htmlize.el.

    (use-package htmlize
    		    :config
    		    (setq org-src-fontify-natively t))
    		  
  • Org Babel Languages
    		    (use-package ob-kotlin)
    
    		    (org-babel-do-load-languages
    		    'org-babel-load-languages
    		    '((java . t)
    		    (groovy . t)
    		    (kotlin . t)
    		    (python . t)))
    
    		  

Programming

Version Control, Git, Github

  • Magit

    The magical git client.

    		      (use-package magit
    		      :if (executable-find "git")
    		      :bind
    		      (("C-x g" . magit-status)
    		      (:map magit-status-mode-map
    		      ("M-RET" . magit-diff-visit-file-other-window)))
    		      :config
    		      (defun magit-log-follow-current-file ()
    		      "A wrapper around `magit-log-buffer-file' with `--follow' argument."
    		      (interactive)
    		      (magit-log-buffer-file t)))
    
    		    
  • Forge

    Forge uses access to Github and provides a way to interact with PRs, Issues, etc.

    (use-package forge)
    
    		    

Projectile

Projectile is a quick and easy project management package that "just works". We're going to install it and make sure it's loaded immediately.

(use-package projectile
		  :diminish projectile-mode
		  :custom ((projectile-completion-system 'helm))
		  :bind-keymap
		  ("C-c p" . projectile-command-map)
		  :config
		  (projectile-mode)
		  :init
		  (when (file-directory-p "~/Workspace")
		  (setq projectile-project-search-path '("~/Workspace")))
		  (setq projectile-switch-project-action 'helm-projectile)
		  (setq projectile-indexing-method 'alien))

		  (use-package helm-projectile
		  :config (helm-projectile-on))


		

Templates

  • yasnippet
    (use-package yasnippet
    		      :config
    		      (use-package yasnippet-snippets)
    		      (yas-reload-all))
    		    
  • 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\n"))
    		    

Rainbow Delimiters

(use-package rainbow-delimiters
		  :hook (prog-mode . rainbow-delimiters-mode))
		

flycheck

(use-package flycheck
		  :ensure t
		  :init (global-flycheck-mode))
		

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.

(use-package company
		  :config
		  (setq company-idle-delay 0)
		  (setq company-minimum-prefix-length 1))

		  (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))
		

Dumb Jump

		  (use-package dumb-jump
		  :bind
		  (:map prog-mode-map
		  (("C-c C-o" . dumb-jump-go-other-window)
		  ("C-c C-j" . dumb-jump-go)
		  ("C-c C-i" . dumb-jump-go-prompt)))
		  :custom (dumb-jump-selector 'ivy))
		

Font-lock

(require 'font-lock)
		

LSP

  • LSP Mode
    (use-package lsp-mode
    		      :defer t
    		      :commands lsp
    		      :custom
    		      (lsp-auto-guess-root nil)
    		      (lsp-prefer-flymake nil) ; Use flycheck instead of flymake
    		      (lsp-file-watch-threshold 2000)
    		      (read-process-output-max (* 1024 1024))
    		      (lsp-eldoc-hook nil)
    		      :bind (:map lsp-mode-map ("C-c C-f" . lsp-format-buffer))
    		      :hook ((java-mode 
    		      js-mode js2-mode typescript-mode web-mode) . lsp))
    
    
    		    
  • LSP UI
    (use-package lsp-ui
    		      :after lsp-mode
    		      :diminish
    		      :commands lsp-ui-mode
    		      :custom-face
    		      (lsp-ui-doc-background ((t (:background nil))))
    		      (lsp-ui-doc-header ((t (:inherit (font-lock-string-face italic)))))
    		      :bind
    		      (:map lsp-ui-mode-map
    		      ([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
    		      ([remap xref-find-references] . lsp-ui-peek-find-references)
    		      ("C-c u" . lsp-ui-imenu)
    		      ("M-i" . lsp-ui-doc-focus-frame))
    		      (:map lsp-mode-map
    		      ("M-n" . forward-paragraph)
    		      ("M-p" . backward-paragraph))
    		      :custom
    		      (lsp-ui-doc-header t)
    		      (lsp-ui-doc-include-signature t)
    		      (lsp-ui-doc-border (face-foreground 'default))
    		      (lsp-ui-sideline-enable nil)
    		      (lsp-ui-sideline-ignore-duplicate t)
    		      (lsp-ui-sideline-show-code-actions nil)
    		      :config
    		      ;; Use lsp-ui-doc-webkit only in GUI
    		      (if (display-graphic-p)
    		      (setq lsp-ui-doc-use-webkit t))
    		      ;; WORKAROUND Hide mode-line of the lsp-ui-imenu buffer
    		      ;; https://github.com/emacs-lsp/lsp-ui/issues/243
    		      (defadvice lsp-ui-imenu (after hide-lsp-ui-imenu-mode-line activate)
    		      (setq mode-line-format nil)))
    
    		    
  • DAP

    Debug Adapter Protocol Mode, a client/library for the Debug Adapter Protocol.

    (use-package dap-mode
    		      :diminish
    		      :bind
    		      (:map dap-mode-map
    		      (("<f12>" . dap-debug)
    		      ("<f8>" . dap-continue)
    		      ("<f9>" . dap-next)
    		      ("<M-f11>" . dap-step-in)
    		      ("C-M-<f11>" . dap-step-out)
    		      ("<f7>" . dap-breakpoint-toggle))))
    
    		    

Languages

  • C/C++
    (add-hook 'c++-mode-hook 'yas-minor-mode)
    		      (add-hook 'c-mode-hook 'yas-minor-mode)
    
    		      (use-package flycheck-clang-analyzer
    		      :config
    		      (with-eval-after-load 'flycheck
    		      (require 'flycheck-clang-analyzer)
    		      (flycheck-clang-analyzer-setup)))
    
    		      (with-eval-after-load 'company
    		      (add-hook 'c++-mode-hook 'company-mode)
    		      (add-hook 'c-mode-hook 'company-mode))
    
    		      (use-package company-c-headers)
    
    		      (use-package company-irony
    		      :config
    		      (setq company-backends '((company-c-headers
                          company-dabbrev-code
                          company-irony))))
    
    		      (use-package irony
    		      :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))
    		    
  • Haskell
    (use-package haskell-mode
    		      :defer t
    		      :init
    		      (progn
    		      (add-hook 'haskell-mode-hook #'haskell-indentation-mode)
    		      (add-hook 'haskell-mode-hook #'turn-on-haskell-doc-mode)
    		      (add-hook 'haskell-mode-hook #'subword-mode))
    		      :config
    		      (progn
    		      (let ((my-cabal-path (expand-file-name "~/.cabal/bin")))
    		      (setenv "PATH" (concat my-cabal-path ":" (getenv "PATH")))
    		      (add-to-list 'exec-path my-cabal-path))
    		      (custom-set-variables '(haskell-tags-on-save t))
    
    		      (custom-set-variables
    		      '(haskell-process-suggest-remove-import-lines t)
    		      '(haskell-process-auto-import-loaded-modules t)
    		      '(haskell-process-log t))
    		      (define-key haskell-mode-map (kbd "C-c C-l")
    		      'haskell-process-load-or-reload)
    		      (define-key haskell-mode-map (kbd "C-c C-z")
    
    
    		      (eval-after-load 'haskell-cabal
    		      '(progn
    		      (define-key haskell-cabal-mode-map (kbd "C-c C-z")
    		      'haskell-interactive-switch)
    		      (define-key haskell-cabal-mode-map (kbd "C-c C-k")
    		      'haskell-interactive-mode-clear)
    		      (define-key haskell-cabal-mode-map (kbd "C-c C-c")
    		      'haskell-process-cabal-build)
    		      (define-key haskell-cabal-mode-map (kbd "C-c c")
    		      'haskell-process-cabal)))
    
    		      (custom-set-variables '(haskell-process-type 'cabal-repl))
    
    		      (autoload 'ghc-init "ghc" nil t)
    		      (autoload 'ghc-debug "ghc" nil t)
    		      (add-hook 'haskell-mode-hook (lambda () (ghc-init)))))
    		    
  • Common Lisp/Slime

    Slime stands for Superior Lisp Interaction Mode for Emacs. For a quick intro, read this.

    (use-package slime
    		      :config
    		      (setq inferior-lisp-program "/usr/local/bin/sbcl"))
    
    		      (slime-setup '(slime-fancy))
    		    
  • Rust
    		      (use-package rust-mode
    		      :bind (:map rust-mode-map
    		      (("C-c C-t" . racer-describe)
                          ([?\t] . company-indent-or-complete-common))))
    		      (use-package flycheck-rust)
    
    		      (use-package cargo
    		      :hook (rust-mode . cargo-minor-mode)
    		      :bind ("C-c C-c C-n" . cargo-process-new))
    
    		      (use-package racer
    		      :hook (rust-mode . racer-mode)
    		      :config
    		      (progn
    		      (defun systemhalted/racer-mode-hook ()
    		      (set (make-local-variable 'company-backends)
    		      '((company-capf company-files)))
    		      (setq company-minimum-prefix-length 1)
    		      (setq indent-tabs-mode nil))
    		      (add-hook 'racer-mode-hook 'systemhalted/racer-mode-hook)
    		      (add-hook 'racer-mode-hook #'company-mode)
    		      (add-hook 'racer-mode-hook #'eldoc-mode)))
    
    
    
    		      (add-hook 'rust-mode-hook 'flycheck-mode)
    		      (add-hook 'flycheck-mode-hook 'flycheck-rust-setup)
    
    		      (add-hook 'before-save-hook (lambda ()
                          (when (eq major-mode 'rust-mode)
                          (rust-format-buffer))))
    
    
    
    
    		    
  • LSP Java
    (use-package lsp-java
    		      :after lsp-mode
    		      :if (executable-find "mvn")
    		      :init
    		      (use-package request :defer t)
    		      :custom
    		      (lsp-java-server-install-dir (expand-file-name "~/.emacs.d/eclipse.jdt.ls/server/"))
    		      (lsp-java-workspace-dir (expand-file-name "~/.emacs.d/eclipse.jdt.ls/workspace/")))
    
    		    
  • Javascript Mode
    (use-package js2-mode
    		      :mode "\\.js\\'"
    		      :interpreter "node")
    		    
  • Typescript
    (use-package tide
    		      :mode "\\.ts\\'"
    		      :ensure t
    		      :after (typescript-mode company flycheck)
    		      :hook ((typescript-mode . tide-setup)
    		      (typescript-mode . tide-hl-identifier-mode)
    		      (before-save . tide-format-before-save)))
    		    

Author: systemhalted

Created: 2020-11-22 Sun 01:34

Validate