(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
("melpa" . "http://melpa.org/packages/")
("org" . "http://orgmode.org/elpa/")))
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(setq-default
ad-redefinition-action 'accept ; Silence warnings for redefinition
cursor-in-non-selected-windows t ; Hide the cursor in inactive windows
display-time-default-load-average nil ; Don't display load average
fill-column 80 ; Set width for automatic line breaks
help-window-select t ; Focus new help windows when opened
indent-tabs-mode nil ; Prefers spaces over tabs
inhibit-startup-screen t ; Disable start-up screen
initial-scratch-message "" ; Empty the initial *scratch* buffer
kill-ring-max 128 ; Maximum length of kill ring
load-prefer-newer t ; Prefers the newest version of a file
mark-ring-max 128 ; Maximum length of mark ring
read-process-output-max (* 1024 1024) ; Increase the amount of data reads from the process
scroll-conservatively most-positive-fixnum ; Always scroll by one line
select-enable-clipboard t ; Merge system's and Emacs' clipboard
tab-width 4 ; Set width for tabs
use-package-always-ensure t ; Avoid the :ensure keyword for each package
user-full-name "greensponge" ; Set the full name of the current user
user-mail-address "[email protected]" ; Set the email address of the current user
vc-follow-symlinks t ; Always follow the symlinks
view-read-only t) ; Always open read-only buffers in view-mode
(cd "~/") ; Move to the user directory
(display-time-mode 1) ; Enable time in the mode-line
(fset 'yes-or-no-p 'y-or-n-p) ; Replace yes/no prompts with y/n
(set-default-coding-systems 'utf-8) ; Default to utf-8 encoding
(show-paren-mode 1) ; Show the parent
(blink-cursor-mode 0) ; Stops cursor blinking
(setq inhibit-startup-message t)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(global-hl-line-mode +1)
(delete-selection-mode 1)
(setq split-height-threshold nil)
(setq split-width-threshold 0)
(setq backup-directory-alist '(("." . "~/.saves")))
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
Set bookmarks file
(setq bookmark-default-file "~/.emacs.d/bookmarks")
Save bookmarks when modified
(setq bookmark-save-flag 1)
(setq-default truncate-lines t)
(setq create-lockfiles nil)
(use-package move-text
:bind (("M-<up>" . move-text-up)
("M-<down>" . move-text-down))
:config (move-text-default-bindings))
(global-auto-revert-mode t)
(use-package shell-pop
:ensure t
:config
(global-set-key (kbd "C-f") 'shell-pop) ; I never use the forward char shortcut anyway.
(setq shell-pop-term-shell "/bin/bash")
(setq shell-pop-window-position "bottom")
(setq shell-pop-autocd-to-working-dir t)
(push (cons "\\*shell\\*" display-buffer--same-window-action) display-buffer-alist))
(use-package expand-region
:ensure t
:bind
("C-+" . er/expand-region)
("C--" . er/contract-region))
Run `M-x company-tabnine-install-binary` to install the TabNine binary for your system.
(use-package company
:ensure t
:init
(add-hook 'after-init-hook 'global-company-mode)
(setq company-idle-delay 0
company-minimum-prefix-length 3
company-selection-wrap-around 1
company-tooltip-align-annotations t
company-show-numbers t)
(company-tng-configure-default))
(use-package company-lsp
:commands company-lsp
:ensure t
:after (company lsp)
:config
(setq company-transformers nil
company-lsp-async t
company-lsp-cache-candidates nil)
(push 'company-lsp company-backends))
(use-package ibuffer
:ensure t
:bind ("C-x C-b" . ibuffer))
(use-package ibuffer-projectile
:after ibuffer
:preface
(defun my/ibuffer-projectile ()
(ibuffer-projectile-set-filter-groups)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic)))
:hook (ibuffer . my/ibuffer-projectile))
(defvar *protected-buffers* '("*scratch*" "*Messages*")
"Buffers that cannot be killed.")
(defun my/protected-buffers ()
"Protects some buffers from being killed."
(dolist (buffer *protected-buffers*)
(with-current-buffer buffer
(emacs-lock-mode 'kill))))
(add-hook 'after-init-hook #'my/protected-buffers)
(defun toggle-maximize-buffer () "Maximize buffer"
(interactive)
(if (= 1 (length (window-list)))
(jump-to-register '_)
(progn
(window-configuration-to-register '_)
(delete-other-windows))))
(define-key global-map (kbd "C-c f") 'toggle-maximize-buffer)
(use-package undo-tree
:ensure t
:diminish undo-tree-mode
:init
(global-undo-tree-mode 1)
:config
(defalias 'redo 'undo-tree-redo)
:bind (("C-z" . undo)
("C-S-z" . redo)))
(global-set-key [remap kill-buffer] #'kill-this-buffer)
(use-package window
:ensure nil
:bind (("C-x 3" . hsplit-last-buffer)
("C-x 2" . vsplit-last-buffer))
:preface
(defun hsplit-last-buffer ()
"Gives the focus to the last created horizontal window."
(interactive)
(split-window-horizontally)
(other-window 1))
(defun vsplit-last-buffer ()
"Gives the focus to the last created vertical window."
(interactive)
(split-window-vertically)
(other-window 1)))
(use-package switch-window
:bind (("C-x o" . switch-window)
("C-x w" . switch-window-then-swap-buffer)))
(use-package windmove
:bind (("C-c <left>" . windmove-left)
("C-c <down>" . windmove-down)
("C-c <up>" . windmove-up)
("C-c <right>" . windmove-right)))
Tangle after-save-hook, only on org-files
(defun dw/org-babel-tangle-dont-ask ()
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle)))
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'dw/org-babel-tangle-dont-ask
'run-at-end 'only-in-org-mode)))
(set-register ?b '(file . "~/.bashrc"))
(set-register ?c '(file . "~/.emacs.d/.config.org"))
(use-package doom-themes
:ensure t
:config
(load-theme 'doom-gruvbox 'no-confirm))
(use-package doom-modeline
:ensure t
:hook (after-init . doom-modeline-mode))
(use-package all-the-icons
:ensure t)
(set-face-attribute 'default nil :font "Source Code Pro Medium")
(set-fontset-font t 'latin "Noto Sans")
(setq ido-everywhere t)
(setq ido-enable-flex-matching t)
(ido-mode t)
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)))
;; stop asking for confirmation
(setq org-confirm-babel-evaluate nil)
(use-package org-bullets
:ensure t
:config
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
(setq org-support-shift-select t)
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture)
(global-set-key (kbd "C-c m c") (lambda() (interactive)(find-file "~/.emacs.d/config.org")))
(global-set-key (kbd "C-c m n") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/notes.org")))
(global-set-key (kbd "C-c m r") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/reports.org")))
(global-set-key (kbd "C-c m j") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/journal.org")))
(setq org-tags-column 0)
(global-set-key (kbd "<f5>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/gtd.org")))
(global-set-key (kbd "<f6>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/inbox.org")))
(global-set-key (kbd "<f7>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/tickler.org")))
(global-set-key (kbd "<f8>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/someday.org")))
(setq org-agenda-start-on-weekday 1)
(setq org-agenda-files '("~/.emacs.d/org-mode/org"))
(setq org-refile-targets '(("~/.emacs.d/org-mode/org/gtd.org" :maxlevel . 3)
("~/.emacs.d/org-mode/org/someday.org" :maxlevel . 1)
("~/.emacs.d/org-mode/org/tickler.org" :maxlevel . 2)))
(setq org-capture-templates '(("t" "Todo [inbox]" entry
(file+headline "~/.emacs.d/org-mode/org/inbox.org" "Tasks")
"* TODO %i%?")
("T" "Tickler" entry
(file+headline "~/.emacs.d/org-mode/org/tickler.org" "Tickler")
"* %i%? \n %U")
("j" "Journal entry" entry
(file+datetree "~/.emacs.d/org-mode/org/journal.org")
"**** %U %^{Title}\n %?")))
(setq org-todo-keywords '((sequence "TODO(t)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)")))
;; Documentation: https://orgmode.org/org.html#Tags
(setq org-tag-alist '((:startgroup . nil)
("@work" . ?w) ("@home" . ?h)
(:endgroup . nil)))
You need to install pandoc
separately on your system for preview to work.
(use-package markdown-mode
:ensure t
:commands (markdown-mode gfm-mode)
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:init (setq markdown-command "/usr/bin/pandoc"))
(use-package lsp-mode
:ensure t
:hook ((clojure-mode . lsp)
(css-mode . lsp)
(lsp-mode . lsp-enable-which-key-integration))
:commands lsp
:custom ((lsp-clojure-server-command '("java" "-jar" "/home/greensponge/clj-kondo/clj-kondo-lsp-server.jar")))
:config
(dolist (m '(clojure-mode
clojurescript-mode))
(add-to-list 'lsp-language-id-configuration `(,m . "clojure")))
(setq lsp-file-watch-ignored
'("[/\\\\]\\.git$"
"[/\\\\]_build$"
"[/\\\\]assets$"
"[/\\\\]cover$"
"[/\\\\]node_modules$"
"[/\\\\]submodules$")))
(use-package lsp-ui
:ensure t
:after (lsp-mode))
(use-package dap-mode :after lsp-mode :config (dap-auto-configure-mode))
(use-package which-key
:ensure t
:config(which-key-mode))
(use-package projectile
:ensure t
:config
(define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map)
(projectile-mode +1))
(use-package dashboard
:ensure t
:init
(progn
(setq dashboard-items '((recents . 5)
(agenda . 10)
(projects . 5)
(bookmarks .5)))
(setq dashboard-center-content nil)
(setq dashboard-banner-logo-title "Wherever you go, there you are.")
(setq dashboard-set-file-icons t)
(setq dashboard-set-heading-icons t)
(setq dashboard-startup-banner "~/.emacs.d/assets/images/emacs-logo.png")
(setq show-week-agenda-p t)
(setq dashboard-set-navigator t)
(setq dashboard-navigator-buttons
`(
((,nil
"config file"
"Open config file"
(lambda (&rest _) (find-file "~/.emacs.d/config.org"))
))))
)
:config
(dashboard-setup-startup-hook))
(use-package treemacs
:ensure t
:config
(setq treemacs-show-hidden-files t)
(setq treemacs-git-mode 'extended)
(setq treemacs-follow-mode t)
(setq treemacs-project-follow-cleanup t))
(global-set-key (kbd "C-b") 'treemacs) ; I never use the backward char shortcut anyway.
(use-package treemacs-projectile
:after (treemacs projectile)
:ensure t)
(use-package treemacs-magit
:after (treemacs magit)
:ensure t)
(use-package magit
:ensure t
:bind ("C-x g" . magit-status))
(use-package flycheck
:ensure t)
(use-package swiper
:ensure t)
(use-package ivy
:diminish
:bind (("C-s" . swiper)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-j" . ivy-next-line)
("C-k" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:init
(ivy-mode 1)
:config
(setq ivy-use-virtual-buffers t)
(setq ivy-wrap t)
(setq ivy-count-format "(%d/%d) ")
(setq enable-recursive-minibuffers t)
;; Use different regex strategies per completion command
(push '(completion-at-point . ivy--regex-fuzzy) ivy-re-builders-alist) ;; This doesn't seem to work...
(push '(swiper . ivy--regex-ignore-order) ivy-re-builders-alist)
(push '(counsel-M-x . ivy--regex-ignore-order) ivy-re-builders-alist)
;; Set minibuffer height for different commands
(setf (alist-get 'counsel-projectile-ag ivy-height-alist) 15)
(setf (alist-get 'counsel-projectile-rg ivy-height-alist) 15)
(setf (alist-get 'swiper ivy-height-alist) 15)
(setf (alist-get 'counsel-switch-buffer ivy-height-alist) 7))
(use-package ivy-rich
:init
(ivy-rich-mode 1))
(use-package counsel
:bind (("M-x" . counsel-M-x)
("C-x b" . counsel-ibuffer)
("C-x C-f" . counsel-find-file)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history))
:config
(setq ivy-initial-inputs-alist nil)) ;; Don't start searches with ^
(use-package flx ;; Improves sorting for fuzzy-matched results
:defer t
:init
(setq ivy-flx-limit 10000))
(use-package smex ;; Adds M-x recent command sorting for counsel-M-x
:defer 1
:after counsel)
(use-package helpful
:ensure t
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key))
(use-package calfw
:ensure t)
(use-package calfw-org
:ensure t)
(setq calendar-week-start-day 1)
(global-set-key (kbd "C-c m a") 'cfw:open-org-calendar)
Highlights TODOs throughout all programming modes, add custom keywords as needed.
(use-package hl-todo
:hook (prog-mode . hl-todo-mode)
:config
(setq hl-todo-highlight-punctuation ":"
hl-todo-keyword-faces
`(("TODO" warning bold)
("FIXME" error bold)
("HACK" font-lock-constant-face bold)
("REVIEW" font-lock-keyword-face bold)
("NOTE" success bold)
("DEPRECATED" font-lock-doc-face bold))))
(use-package multiple-cursors
:ensure t
:bind (("C->" . mc/mark-next-like-this)
("C-<" . mc/unmark-next-like-this)
("C-c C-<" . mc/mark-all-like-this)
("C-S-<mouse-1>" . mc/add-cursor-on-click)))
(use-package centaur-tabs
:demand
:config
(centaur-tabs-mode t)
:bind
("C-<prior>" . centaur-tabs-backward)
("C-<next>" . centaur-tabs-forward))
(use-package csharp-mode
:hook
((csharp-mode . lsp-deferred)))
(use-package dockerfile-mode
:ensure t)
(use-package editorconfig
:ensure t
:config
(editorconfig-mode 1))
(use-package emmet-mode
:hook (css-mode sgml-mode web-mode))
Press [TAB]
and [RET]
if language server prompts you when opening a .Java
file.
Source: lsp-java
(use-package lsp-java :config (add-hook 'java-mode-hook 'lsp))
(use-package dap-java :ensure nil)
(use-package json-mode
:mode "\\.json\\'"
:hook (before-save . my/json-mode-before-save-hook)
:preface
(defun my/json-mode-before-save-hook ()
(when (eq major-mode 'json-mode)
(json-pretty-print-buffer)))
(defun my/json-array-of-numbers-on-one-line (encode array)
"Prints the arrays of numbers in one line."
(let* ((json-encoding-pretty-print
(and json-encoding-pretty-print
(not (loop for x across array always (numberp x)))))
(json-encoding-separator (if json-encoding-pretty-print "," ", ")))
(funcall encode array)))
:config (advice-add 'json-encode-array :around #'my/json-array-of-numbers-on-one-line))
Install the needed packages to use slime-helper by following these steps:
1. Install SBCL
2. Fetch quicklisp
3. Load quicklisp into SBCL context
```sh
sudo apt-get install sbcl
curl -O http://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp
```
Step into SBCL context by typing `sbcl` in your terminal and setup quick-lisp:
```sh
(quicklisp-quickstart:install)
(ql:quickload "quicklisp-slime-helper")
```
(load (expand-file-name "~/quicklisp/slime-helper.el"))
(setq inferior-lisp-program "/usr/bin/sbcl")
You can run the Common Lisp REPL like this: `M-x slime`
(use-package aggressive-indent
:hook ((css-mode . aggressive-indent-mode)
(emacs-lisp-mode . aggressive-indent-mode)
(clojure-mode . aggressive-indent-mode)
(lisp-mode . aggressive-indent-mode))
:custom (aggressive-indent-comments-too))
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
(use-package smartparens
:ensure t
:config (smartparens-global-mode 1)
:bind (("C-M-a" . sp-beginning-of-sexp)
("C-M-e" . sp-end-of-sexp)
("C-<down>" . sp-down-sexp)
("C-<up>" . sp-up-sexp)
("M-<down>" . sp-backward-down-sexp)
("M-<up>" . sp-backward-up-sexp)
("C-M-f" . sp-forward-sexp)
("C-M-b" . sp-backward-sexp)
("C-M-n" . sp-next-sexp)
("C-M-p" . sp-previous-sexp)
("C-S-b" . sp-backward-symbol)
("C-S-f" . sp-forward-symbol)
("C-S-M->" . sp-backward-unwrap)
("C-M-<" . sp-unwrap-sexp)
("C-<right>" . sp-forward-slurp-sexp)
("M-<right>" . sp-forward-barf-sexp)
("C-<left>" . sp-backward-slurp-sexp)
("M-<left>" . sp-backward-barf-sexp)
("C-M-t" . sp-transpose-sexp)
("C-M-k" . sp-kill-sexp)
("C-k" . sp-kill-hybrid-sexp)
("M-k" . sp-backward-kill-sexp)))
(add-hook 'prog-mode-hook 'turn-on-smartparens-strict-mode)
(use-package clojure-mode
:ensure t
:mode (("\\.clj\\'" . clojure-mode)
("\\.edn\\'" . clojure-mode))
:init
(add-hook 'clojure-mode-hook #'eldoc-mode))
(use-package cider
:ensure t
:config
(setq cider-font-lock-dynamically '(macro core function var)))
Note you need to have tslint
installed globally for it to be enabled.
Installing TypeScript
globally might also be a good idea at this point.
`npm install -g tslint`
`npm install -g typescript`
You can execute `C-c ! v` to check what syntax checkers are running to confirm that everything works.
(defun setup-tide-mode ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
(company-mode +1))
;; aligns annotation to the right hand side
(setq company-tooltip-align-annotations t)
;; formats the buffer before saving
(add-hook 'before-save-hook 'tide-format-before-save)
(add-hook 'typescript-mode-hook #'setup-tide-mode)
(use-package tide
:after typescript-mode
:ensure t)
(use-package typescript-mode
:ensure t)