First commit.

This commit is contained in:
2022-01-09 21:19:46 +01:00
commit df36844dcc
107 changed files with 6565 additions and 0 deletions

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
.cache
.org-id-locations
anaconda-mode
ac-comphist.dat
bookmarks
elpa
emms
eshell
org-roam.db
org-roam-db.bak
quelpa
request
recentf~
transient

13
COPYING.org Normal file
View File

@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2022 Mathieu Marques <mathieumarques78@gmail.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

9
README.org Normal file
View File

@@ -0,0 +1,9 @@
#+TITLE: DotEmacs
#+AUTHOR: Adrien SUEUR
This repository contains my personal Emacs configuration.
This configuration is based largely on the [[https://github.com/dholm][David Holm]] [[https://github.com/dholm/dotemacs/tree/master][dotemacs]] I have mosly adapted to my workflow:
* removed/disabled packages (still in progress) that didn't seem to be necessary for me,
* Use langage-servers (still in progress) and remove packages like CEDET, ctags, scope,...,
* Use of [[https://en.wikipedia.org/wiki/Zettelkasten][Zettelkasten]] method (org-roam package).

23
epilogue.el Normal file
View File

@@ -0,0 +1,23 @@
;;; epilogue.el --- Emacs init epilogue
;;; Commentary:
;;; Code:
(eval-when-compile
(load (expand-file-name "prologue.el" user-emacs-directory))
(require 'init-emacs))
;; Load user's machine-local configuration file, if available.
(when (file-exists-p *user-local-init*)
(load *user-local-init*))
;; Load custom after all packages have been installed.
(when (file-exists-p *user-custom-file*)
(load *user-custom-file*))
;; Disable collection of benchmark data.
(when (featurep 'benchmark-init)
(benchmark-init/deactivate))
;;; epilogue.el ends here

36
init.el Normal file
View File

@@ -0,0 +1,36 @@
;;; init.el --- Emacs main initialization -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(when (version< "27.1" emacs-version)
;; Workaround for deprecated parameter referenced by Helm.
(defvar browse-url-mosaic-program "xmosaic"))
;; Bring in package.
(setq-default
package--init-file-ensured t
package-enable-at-startup nil)
(require 'package)
;; Load Emacs init prologue.
(eval-and-compile (load (expand-file-name "prologue.el" user-emacs-directory)))
;; Load utilities.
;;(require 'lib/utils)
;;(require 'lib/hash-tables)
;;(require 'lib/bootstrap)
;;(require 'lib/apps)
;;(require 'lib/introspection)
;; Load full configuration.
(require 'init-utilities)
;;(require 'init-vcs)
(require 'init-modes)
(require 'init-apps)
;; Load Emacs init epilogue.
(load (expand-file-name "epilogue.el" user-emacs-directory))
;;; init.el ends here
(put 'dired-find-alternate-file 'disabled nil)

51
lisp/apps/calc.el Normal file
View File

@@ -0,0 +1,51 @@
;;; calc.el --- Emacs calculator -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package calc
:commands calc
:init
(user/bind-key-global :apps :calculator 'calc)
:config
(validate-setq
;; Location of user calculator configuration.
calc-settings-file (path-join *user-data-directory* "calc.el")
;; Increase calc's undo history.
calc-undo-length 1000
;; Use a different face to display sub-formulas.
calc-highlight-selections-with-faces t)
(use-package calc-units
:ensure calc
:config
;; Add additional units for bits and bytes.
;; Stolen from: `https://github.com/dalehagglund/emacs.d/blob/master/calc.el'
(add-many-to-list
'math-additional-units
'(bit nil "basic unit of information")
'(byte "8 * bit" "eight bits")
'(B "byte" "one byte")
'(KiB "1024 * B" "kibibyte")
'(MiB "1024 * KiB" "mebibyte")
'(GiB "1024 * MiB" "gibibyte")
'(TiB "1024 * GiB" "tebibyte")
'(PiB "1024 * TiB" "pebibyte")
'(EiB "1024 * PiB" "exbibyte")
'(ZiB "1024 * EiB" "zebibyte")
'(YiB "1024 * ZiB" "yobibyte")))
;; Allow yanking using the mouse.
(define-key calc-mode-map [mouse-2] 'calc-yank)
(use-package easy-convert
:quelpa (easy-convert
:fetcher github
:repo "Frozenlock/easy-convert")
:commands easy-convert-interactive
:init
(autoload 'easy-convert-interactive "easy-convert" nil t)
(user/bind-key-global :apps :convert-unit 'easy-convert-interactive)))
(provide 'apps/calc)
;;; calc.el ends here

24
lisp/apps/elfeed.el Normal file
View File

@@ -0,0 +1,24 @@
;;; elfeed.el --- Emacs web feed reader. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; https://github.com/skeeto/elfeed
;; An Emacs web feeds client
(use-package elfeed
:ensure t
:commands elfeed
:init
(user/bind-key-global :apps :feed-reader 'elfeed)
:config
(setq elfeed-feeds
'("http://blog.python.org/feeds/posts/default"
"https://blog.finxter.com/feed"
"https://planetpython.org/rss20.xml"
"http://www.reddit.com/r/emacs/.rss"
"https://sachachua.com/blog/category/emacs-news/feed"
"http://linuxfr.org/journaux.atom"
)))
(provide 'apps/elfeed)
;;; elfeed.el ends here

9
lisp/init-apps.el Normal file
View File

@@ -0,0 +1,9 @@
;;; init-apps.el --- initializes applications -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(load-all-files-from-dir (path-join *user-emacs-lisp-directory* "apps"))
(provide 'init-apps)
;;; init-apps.el ends here

459
lisp/init-bindings.el Normal file
View File

@@ -0,0 +1,459 @@
;;; init-bindings.el --- sets up basic Emacs bindings -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defvar user/global-keymap nil
"Global keymap.")
(defvar user/global-reverse-keymap nil
"Global reverse keymap, mapping bindings back to functions.")
(defvar ctl-l-map (make-keymap)
"Default keymap for \\<ctl-l-map> commands.")
;; Set up prefixes for command groups.
(defcustom user/view-prefix (kbd "C-x v")
"Keyboard prefix to use for view commands."
:type 'key-sequence
:group 'user)
(defcustom user/help-prefix (kbd "C-c h")
"Keyboard prefix to use for help commands."
:type 'key-sequence
:group 'user)
(defcustom user/documentation-prefix (kbd "C-c d")
"Keyboard prefix to use for documentation commands."
:type 'key-sequence
:group 'user)
(defcustom user/code-prefix (kbd "C-c c")
"Keyboard prefix to use for code manipulation commands."
:type 'key-sequence
:group 'user)
(defcustom user/code-eval-prefix (kbd "C-c c e")
"Keyboard prefix to use for code evaluation commands."
:type 'key-sequence
:group 'user)
(defcustom user/vcs-prefix (kbd "C-c v")
"Keyboard prefix to use for version control commands."
:type 'key-sequence
:group 'user)
(defcustom user/utilities-prefix (kbd "C-c u")
"Keyboard prefix to use for utility commands."
:type 'key-sequence
:group 'user)
(defcustom user/apps-prefix (kbd "C-c a")
"Keyboard prefix to use for application commands."
:type 'key-sequence
:group 'user)
(defconst user/prefix-list (list "C-x" "C-c" "C-l")
"List of the registered prefix keys.")
(defun user/make-key (keys)
"Convert KEYS into the internal Emacs key representation."
(kbd (if (listp keys)
(mapconcat 'identity (mapcar 'eval keys) " ")
keys)))
(defun user/get-key (group operation)
"Get the key from GROUP to bind for OPERATION."
(let ((key (cdr (assq operation (cdr (assq group user/global-keymap))))))
(if key
(user/make-key key)
(error (format "Group %s does not contain key for %s!"
(symbol-name group) (symbol-name operation))))))
(defun user/get-key-function (group operation)
"Get the function bound to GROUP OPERATION."
(car (cdr (assq operation
(cdr (assq group user/global-reverse-keymap))))))
(defun user/bind-key-global (group key function)
"Bind GROUP KEY to FUNCTION globally."
(let ((rev-group (assq group user/global-reverse-keymap)))
(setq user/global-reverse-keymap
(append `((,group . ,(append `((,key ,function)) (cdr rev-group))))
(delq (assoc group user/global-reverse-keymap)
user/global-reverse-keymap))))
(global-set-key (user/get-key group key) function))
(defun user/bind-key-local (group key function)
"Bind GROUP KEY to FUNCTION in the current keymap."
(local-set-key (user/get-key group key) function))
(defun user/merge-keymap-groups (overlay base)
"Merge OVERLAY keymap with BASE group."
(let ((group-name (car base))
(overlay-keys (cdr overlay))
(base-keys (cdr base)))
`((,group-name . ,(append overlay-keys base-keys)))))
(defun user/global-keymap-overlay (overlay)
"Load keymap OVERLAY."
(dolist (ovl-group overlay)
(let ((ovl-gname (car ovl-group))
(ovl-keys (cdr ovl-group)))
(dolist (ovl-op (cdr ovl-group))
(let ((ovl-oname (car ovl-op))
(ovl-key (cdr ovl-op)))
;; TODO: Check that ovl-oname exists.
(global-set-key (user/make-key ovl-key)
(user/get-key-function ovl-gname ovl-oname))))
(let ((orig-group (assq ovl-gname user/global-keymap))
(keymap-without-group (assq-delete-all ovl-gname user/global-keymap)))
(setq user/global-keymap
(append (user/merge-keymap-groups ovl-group orig-group)
keymap-without-group)))))
t)
(defun user--global-keymap-config ()
"Initialize the global keymap."
(setq
user/global-keymap
'(;;; (Basic keys) ;;;
(:basic . ((:open-file . "C-x C-f")
(:open-file-context . "C-x f")
(:open-file-tramp . "C-x t")
(:view-file . "C-x C-v")
(:open-buffer . "C-x b")
(:open-buffer-context . "C-x M-b")
(:save . "C-x C-s")
(:save-as . "C-x M-s")
(:close . "C-x k")
(:quit . "C-x C-c")
(:server-edit . "C-x #")
(:undo . "C-_")
(:redo . "M-_")
(:forward-line . "C-n")
(:backward-line . "C-p")
(:forward-word . "M-f")
(:backward-word . "M-b")
(:forward-expr . "C-M-f")
(:backward-expr . "C-M-b")
(:del-char-left . "C-h")
(:del-char-right . "C-d")
(:search-forward . "C-s")
(:search-backward . "C-r")
(:search-files . ("C-l M-f"))
(:swoop . "C-l C-s")
(:swoop-multi . "C-l C-M-s")
(:selection-start . "C-SPC")
(:selection-expand . "M-=")
(:selection-next . "M-.")
(:selection-prev . "M-,")
(:selection-all . "C-c M-.")
(:selection-edit-lines . "C-c M-e")
(:select-paragraph . "M-h")
(:select-function . "C-M-h")
(:select-inside . "M-+")
(:widen . (user/view-prefix "n w"))
(:narrow-to-page . (user/view-prefix "n p"))
(:narrow-to-region . (user/view-prefix "n r"))
(:narrow-to-function . (user/view-prefix "n f"))
(:copy . "C-x C-w")
(:cut . "C-x C-k")
(:copy-expr . "C-M-w")
(:cut-expr . "C-M-k")
(:paste . "C-y")
(:alternate-paste . "C-M-y")
(:cycle-paste . "M-y")
(:cut-word-left . "C-w")
(:cut-word-right . "M-w")
(:zoom . (user/view-prefix "z"))))
;;; (Emacs) ;;;
(:emacs . ((:describe-bindings . (user/help-prefix "b"))
(:describe-coding . (user/help-prefix "C"))
(:describe-char . (user/help-prefix "c"))
(:describe-face . (user/help-prefix "F"))
(:describe-all-faces . (user/help-prefix "M-f"))
(:describe-function . (user/help-prefix "f"))
(:describe-macro . (user/help-prefix "M-m"))
(:describe-command . (user/help-prefix "i"))
(:describe-key . (user/help-prefix "k"))
(:describe-key-extensive . (user/help-prefix "K"))
(:describe-variable . (user/help-prefix "v"))
(:search-variable-value . (user/help-prefix "V"))
(:describe-language . (user/help-prefix "L"))
(:describe-mode . (user/help-prefix "m"))
(:describe-symbol . (user/help-prefix "s"))
(:describe-syntax . (user/help-prefix "S"))
(:find-library . (user/help-prefix "l"))
(:find-package . (user/help-prefix "p"))
(:manual . (user/help-prefix "M"))
(:elisp-search . (user/help-prefix "e"))
(:tutorial . (user/help-prefix "t"))
(:where-is . (user/help-prefix "w"))
(:redraw . "C-l C-l")
(:recenter . "C-l l")
(:fullscreen . "C-c <C-return>")
(:text-scale-reset . "C-0")
(:text-scale-increase . "C-+")
(:text-scale-decrease . "C--")
(:grow-vertical . "C-c C-p")
(:shrink-vertical . "C-c C-n")
(:grow-horizontal . "C-c C-f")
(:shrink-horizontal . "C-c C-b")
(:flop-frame . "C-c C-t")
(:flip-frame . "C-c M-t")
(:rotate-frame-forward . "C-c C-r")
(:rotate-frame-backward . "C-c M-r")
(:profiler-start . (user/utilities-prefix "p p"))
(:profiler-stop . (user/utilities-prefix "p P"))
(:profiler-report . (user/utilities-prefix "p r"))))
;;; (Documentation) ;;;
(:doc . ((:apropos . (user/documentation-prefix "SPC"))
(:manual . (user/documentation-prefix "m"))
(:describe . (user/documentation-prefix "d"))
(:describe-function . (user/documentation-prefix "f"))
(:describe-variable . (user/documentation-prefix "v"))
(:dictionary . (user/documentation-prefix "D"))
(:reference . (user/documentation-prefix "r"))))
;;; (Navigation) ;;;
(:nav . ((:context . ("C-l SPC"))
(:goto-line . ("C-l g"))
(:go-forward . ("C-l f"))
(:go-back . ("C-l b"))
(:scroll-up . "M-n")
(:scroll-down . "M-p")
(:context-cycle . ("C-l C-c"))
(:context-forward . ("C-l C-f"))
(:context-backward . ("C-l C-b"))
(:context-up . ("C-l C-p"))
(:context-down . ("C-l C-n"))
(:next . ("C-l n"))
(:follow-symbol . ("C-l j"))
(:find-symbol . ("C-l s"))
(:jump-spec-impl . ("C-l i"))
(:references . ("C-l r"))
(:find-references . ("C-l M-r"))
(:find-virtuals . ("C-l v"))
(:switch-spec-impl . ("C-l h"))
(:functions/toc . ("C-l t"))
(:file-dependencies . ("C-l d"))
(:history . ("C-l h"))
(:find-todos . ("C-l M-t"))
(:open . (user/utilities-prefix "o"))))
;;; (Programming) ;;;
(:code . ((:compile . (user/code-prefix "c"))
(:clean . (user/code-prefix "M-c"))
(:run . (user/code-prefix "r"))
(:test . (user/code-prefix "t"))
(:compilation-result . (user/view-prefix "c"))
(:repl . (user/code-prefix "M-r"))
(:bookmark-prefix . "C-c b")
(:bookmark-toggle . "C-c b v")
(:bookmark-next . "C-c b n")
(:bookmark-prev . "C-c b p")
(:comment . "M-;")
(:document . (user/code-prefix "="))
(:join-line . ((if (display-graphic-p) "C-x C-6" "C-x C-^")))
(:align . ((if (display-graphic-p) "C-x C-5" "C-x C-]")))
(:fill-paragraph . ((if (display-graphic-p) "C-x C-4" "C-x C-\\")))
(:tidy . ("C-x ="))
(:whitespace-auto-cleanup . (user/code-prefix "w"))
(:itemize . (user/code-prefix "b"))
(:enumerate . (user/code-prefix "e"))
(:complete . "TAB")
(:try-complete . "TAB")
(:auto-complete . "C-TAB")
(:unwrap-expr . "C-M-d")
(:context-promote . (user/code-prefix "P"))
(:context-demote . (user/code-prefix "N"))
(:refactor-rename . (user/code-prefix "M-r"))
(:refactor-extract . (user/code-prefix "M-x"))
(:insert-dependency . (user/code-eval-prefix "M-d"))
(:generate-test . (user/code-prefix "M-t"))
(:library-list . (user/code-prefix "l"))
(:disassemble . (user/code-prefix "D"))
(:warnings/errors . (user/code-prefix "E"))
(:spellcheck-word . (user/code-prefix "s"))
(:spellcheck-add-word . (user/code-prefix "S"))
;; (:thesaurus-lookup . (user/code-prefix "t"))
(:update-index . (user/code-prefix "i"))
(:eval-expression . ("C-x C-e"))
(:eval-buffer . (user/code-eval-prefix "b"))
(:eval-function . (user/code-eval-prefix "f"))
(:eval-selection . (user/code-eval-prefix "s"))
(:macro-expand . (user/code-eval-prefix "m"))
(:virtual . (user/code-prefix "v"))))
;;; (Debugging) ;;;
(:debug . ((:start . (user/code-prefix "d"))
(:break . (user/code-prefix "b"))
(:trace . (user/code-prefix "T"))
(:break-temporary . (user/code-prefix "t"))
(:watch . (user/code-prefix "w"))
(:run . (user/code-prefix "r"))
(:continue . (user/code-prefix "c"))
(:continue-stack . (user/code-prefix "f"))
(:continue-until . (user/code-prefix "u"))
(:step . (user/code-prefix "s"))
(:step-instruction . (user/code-prefix "i"))
(:next . (user/code-prefix "n"))
(:stack-up . (user/code-prefix "p"))
(:stack-down . (user/code-prefix "n"))
(:show-value . (user/code-prefix "p"))))
;;; (Version Control) ;;;
(:vcs . ((:clone . (user/vcs-prefix "c"))
(:status . (user/vcs-prefix "s"))
(:history . (user/vcs-prefix "h"))
(:version . (user/vcs-prefix "v"))
(:describe . (user/vcs-prefix "d"))
(:gutter . (user/vcs-prefix "g"))
(:review . (user/vcs-prefix "r"))
(:add-buffer . (user/vcs-prefix "a"))
(:next-action . (user/vcs-prefix "SPC"))
(:mergetool . (user/vcs-prefix "m"))
(:search . (user/vcs-prefix "M-s"))
(:find-file . ("C-c p"))
(:time-machine . (user/vcs-prefix "t"))))
;;; (Utilities) ;;;
(:util . ((:annotate-buffer . (user/utilities-prefix "a"))
(:draw . (user/utilities-prefix "g"))
(:diff . (user/utilities-prefix "d"))
(:dumb-diff . (user/utilities-prefix "M-d"))
(:ace-jump-mode . ("C-l a"))
(:ecb-toggle . (user/utilities-prefix "e"))
(:google . (user/utilities-prefix "s"))
(:google-at-point . (user/documentation-prefix "s RET"))
(:google-selection . (user/documentation-prefix "s SPC"))
(:stack-overflow-search . (user/documentation-prefix "s"))
(:notifications . (user/utilities-prefix "n"))
(:perspective . ("C-x x s"))
(:presentation . (user/utilities-prefix "P"))
(:popwin-close . (user/view-prefix "0"))
(:popwin-buffer . (user/view-prefix "p"))
(:popwin-messages . (user/view-prefix "m"))
(:undo-tree . (user/utilities-prefix "u"))
(:wc-mode . (user/utilities-prefix "w"))
(:docker . (user/utilities-prefix "d"))))
;;; (Applications) ;;;
(:apps . ((:packages . (user/apps-prefix "M-p"))
(:shell . (user/apps-prefix "s"))
(:processes . (user/apps-prefix "p"))
(:daemons . (user/apps-prefix "M-d"))
(:services . (user/apps-prefix "P"))
(:agenda . (user/apps-prefix "a"))
(:notes . (user/apps-prefix "n"))
(:todo . (user/apps-prefix "t"))
(:capture-task . (user/apps-prefix "M-t"))
(:information-db . (user/apps-prefix "D"))
(:browse . (user/apps-prefix "b"))
(:browse-external . (user/apps-prefix "B"))
(:feed-reader . (user/apps-prefix "f"))
(:stack-exchange . (user/apps-prefix "x"))
(:weather . (user/apps-prefix "w"))
(:cheat-sh . (user/apps-prefix "C"))
(:email . (user/apps-prefix "e"))
(:irc . (user/apps-prefix "i"))
(:instant-messenger . (user/apps-prefix "I"))
(:ipython-notebook . (user/apps-prefix "N"))
(:music . (user/apps-prefix "m"))
(:elnode . (user/apps-prefix "E"))
(:calculator . (user/apps-prefix "c"))
(:convert-unit . (user/apps-prefix "M-c"))
(:statistics . (user/apps-prefix "R"))
(:sage . (user/apps-prefix "S")))))))
(defun user--bindings-config ()
"Initialize key bindings."
(global-unset-key (kbd "C-l"))
(define-prefix-command 'ctl-l-map)
(global-set-key (kbd "C-l") 'ctl-l-map)
;; Initialize global keymap.
(user--global-keymap-config)
;;; (Bindings) ;;;
;; Alias C-x C-m to M-x which is a bit awkward to reach.
(global-set-key (kbd "C-x C-m") 'execute-extended-command)
(global-set-key (kbd "C-x m") 'execute-extended-command)
;; Toggle comments
(global-set-key (kbd "C-x -") 'comment-or-uncomment-region))
(user--bindings-config)
(provide 'init-bindings)
;;; init-bindings.el ends here

44
lisp/init-constants.el Normal file
View File

@@ -0,0 +1,44 @@
;;; init-constants.el --- Set up constants required during initialization -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'lib/path)
(require 'lib/env)
(require 'lib/pkg-config)
;;; (Directories) ;;;
(defconst *user-home-directory*
(getenv-or "HOME" (concat (expand-file-name "~") "/"))
"Path to user home directory.")
(defconst *user-local-directory*
(if (getenv "XDG_DATA_HOME")
(path-dirname (getenv "XDG_DATA_HOME"))
(path-join *user-home-directory* ".local"))
"Path to user's local store.")
(defconst *user-config-directory*
(path-join (getenv-or "XDG_CONFIG_HOME"
(path-join *user-home-directory* ".config"))
"emacs")
"Path to user's local cache store.")
(defconst *user-data-directory*
(path-join (getenv-or "XDG_DATA_HOME"
(path-join *user-local-directory* "share"))
"emacs")
"Path to user's local data store.")
(defconst *user-cache-directory*
(path-join (getenv-or "XDG_CACHE_HOME"
(path-join *user-home-directory* ".cache"))
"emacs")
"Path to user's local cache store.")
(defconst *user-documents-directory*
(path-join *user-home-directory* "Documents")
"Path to user's documents directory.")
(defconst *user-local-init*
(path-join *user-home-directory* ".emacs.local.el")
"Path to user's machine-local configuration file.")
(provide 'init-constants)
;;; init-constants.el ends here

40
lisp/init-emacs.el Normal file
View File

@@ -0,0 +1,40 @@
;;; init-emacs.el --- initializes basic Emacs settings -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-custom-file* (path-join *user-data-directory* "custom.el"))
(when (version< emacs-version "25.3")
;; Plug security hole in enriched text mode.
(eval-after-load "enriched"
'(defun enriched-decode-display-prop (start end &optional param)
(list start end))))
;; Improve init performance.
(setq
;; Increase garbage collection threshold.
gc-cons-threshold (* 128 1024 1024))
;; Restore garbage collection threshold while Emacs is idle.
(run-with-idle-timer
2 nil
(lambda ()
(validate-setq
;; Reduce number of pauses due to garbage collection.
gc-cons-threshold (* 50 1024 1024)
gc-cons-percentage 0.5)))
;; Create data and cache directories
(make-directory *user-cache-directory* t)
(make-directory *user-data-directory* t)
(setq
;; Lines of history in the message buffer.
message-log-max 10000
;; Path to custom-file
custom-file *user-custom-file*)
(provide 'init-emacs)
;;; init-emacs.el ends here

9
lisp/init-modes.el Normal file
View File

@@ -0,0 +1,9 @@
;;; init-modes.el --- initializes major modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(load-all-files-from-dir (path-join *user-emacs-lisp-directory* "modes"))
(provide 'init-modes)
;;; init-modes.el ends here

9
lisp/init-utilities.el Normal file
View File

@@ -0,0 +1,9 @@
;;; init-utilities.el --- initializes utilities -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(load-all-files-from-dir (path-join *user-emacs-lisp-directory* "utilities"))
(provide 'init-utilities)
;;; init-utilities.el ends here

9
lisp/init-ux.el Normal file
View File

@@ -0,0 +1,9 @@
;;; init-ux.el --- initializes user experience -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(load-all-files-from-dir (path-join *user-emacs-lisp-directory* "ux"))
(provide 'init-ux)
;;; init-ux.el ends here

17
lisp/lib/apps.el Normal file
View File

@@ -0,0 +1,17 @@
;;; apps.el --- Support functions for applications -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun osx-app-installed-p (app)
"Return t if APP is installed."
(when (eq system-type 'darwin)
(let ((lsregister
"/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister"))
(and (file-executable-p lsregister)
(not (string-equal "" (shell-command-to-string
(concat lsregister " -dump|grep " app))))))))
(provide 'lib/apps)
;;; apps.el ends here

28
lisp/lib/bootstrap.el Normal file
View File

@@ -0,0 +1,28 @@
;;; bootstrap.el --- Helpers for bootstrapping Emacs. -*- lexical-binding: t; -*-
;;; Commentary:
;; Stolen from Alexx Ott, https://github.com/alexott/dotemacs
;;; Code:
(declare-function 'path-join "path")
(defun load-all-files-from-dir (dir)
"Load all Emacs Lisp files in DIR."
(dolist (f (directory-files dir))
(when (and
(file-directory-p (path-join dir f))
(not (string= "." f))
(not (string= ".." f)))
(load-all-files-from-dir (path-join dir f)))
(when (and
(not (file-directory-p (path-join dir f)))
(not (string= "bootstrapper.el" f))
(not (string= ".#" (substring f 0 2)))
(string= ".el" (substring f (- (length f) 3))))
(load-file (path-join dir f)))))
(provide 'lib/bootstrap)
;;; bootstrap.el ends here

13
lisp/lib/env.el Normal file
View File

@@ -0,0 +1,13 @@
;;; env.el --- support functions for working with environment variables -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun getenv-or (env value)
"Fetch the value of ENV or, if it is not set, return VALUE."
(if (getenv env)
(getenv env)
value))
(provide 'lib/env)
;;; env.el ends here

46
lisp/lib/list.el Normal file
View File

@@ -0,0 +1,46 @@
;;; list.el --- Emacs list utilities -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun add-many-to-list (the-list &rest entries)
"Add to THE-LIST any specified ENTRIES."
(dolist (entry entries)
(add-to-list the-list entry))
(eval the-list))
(defmacro user/filter-form (form list)
"Return list with elements for which FORM are non-nil in LIST."
(declare (debug (form form)))
(let ((r (make-symbol "result")))
`(let (,r)
(--each ,list (when ,form (!cons it ,r)))
(nreverse ,r))))
(defun user/filter-list (condp list)
"Return list with elements for which CONDP are non-nil in LIST."
(delq nil
(mapcar (lambda (x) (and (funcall condp x) x)) list)))
(defun user/toggle-element (list element)
"Return LIST with ELEMENT removed if present or added if not present."
(if (member element list)
(user/filter-form (not (eq element it)) list)
(cons element list)))
(defun user/all-asscs (asslist query)
"A list of all values in ASSLIST corresponding to QUERY (like rassoc)."
(cond
((null asslist) nil)
(t
(if (equal (cdr (car asslist)) query)
(cons (car (car asslist))
(user/all-asscs (cdr asslist) query))
(user/all-asscs (cdr asslist) query)))))
(provide 'lib/list)
;;; list.el ends here

35
lisp/lib/net.el Normal file
View File

@@ -0,0 +1,35 @@
;;; net.el --- Initialize Emacs networking -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'lib/path)
(require 'lib/utils)
(defconst *user-url-cache-directory*
(path-join *user-cache-directory* "url")
"Path to user's url data store.")
(defconst *user-nsm-data-directory*
(path-join *user-data-directory* "nsm")
"Path to user's Wanderlust data store.")
(with-eval-after-load 'url
(setq
;; Set up cache directory.
url-configuration-directory *user-url-cache-directory*
url-cookie-file (path-join *user-url-cache-directory* "cookies")
url-history-file (path-join *user-url-cache-directory* "history")
;; Automatically cache all documents.
url-automatic-caching t))
(make-directory *user-nsm-data-directory* t)
(with-eval-after-load 'nsm
(setq
;; Location of security manager settings.
nsm-settings-file
(path-join *user-nsm-data-directory* "network-security.data")))
(provide 'lib/net)
;;; net.el ends here

97
lisp/lib/packaging.el Normal file
View File

@@ -0,0 +1,97 @@
;;; packaging.el --- initialize package management -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'lib/net)
(with-feature 'package
(setq
;; Configure GNU/Emacs package repositories.
package-archives
'(("GNU ELPA" . "https://elpa.gnu.org/packages/")
("MELPA Stable" . "http://stable.melpa.org/packages/")
("MELPA" . "http://melpa.org/packages/")
("org" . "http://orgmode.org/elpa/"))
;; ("marmalade" . "http://marmalade-repo.org/packages/"))
;; Prefer MELPA Stable over GNU over MELPA.
package-archive-priorities
'(("MELPA Stable" . 20)
("GNU ELPA" . 15)
("MELPA" . 10)
("org" . 5))))
;; ("marmalade" . 0))))
;; Bootstrap `use-package'.
(package-initialize)
(unless (and (package-installed-p 'quelpa-use-package) (package-installed-p 'validate))
(package-refresh-contents)
(package-install 'quelpa-use-package)
(package-install 'validate))
(eval-when-compile
;; Load use-package.
(require 'quelpa-use-package)
(require 'validate))
(use-package use-package
:config
(validate-setq
;; Hooks are verbatim.
use-package-hook-name-suffix nil)
(use-package quelpa-use-package
:config
(validate-setq
;; Only use quelpa for custom packages.
quelpa-checkout-melpa-p nil
;; Only load quelpa on demand.
quelpa-use-package-inhibit-loading-quelpa t)
;; Protect quelpa recipes when forcing ensure.
(quelpa-use-package-activate-advice))
;; Support using keys from init-bindings by using (:key <group> <function>).
(push :bind-wrap (cdr (member :bind use-package-keywords)))
(push :bind*-wrap (cdr (member :bind* use-package-keywords)))
(defun use-package-normalize-bind-wrap (name keyword args)
(let ((arg args)
args*)
(while arg
(let ((x (car arg)))
(cond
;; ((:key :category :function) . COMMAND)
((and (consp x)
(consp (car x))
(equal (caar x) :key))
(setq args* (nconc args*
(list (cons (apply 'user/get-key (cdar x))
(cdar arg)))))
(setq arg (cdr arg)))
;; (KEY . COMMAND)
((and (consp x)
(or (stringp (car x))
(vectorp (car x)))
(or (use-package-recognize-function (cdr x) t #'stringp)))
(setq args* (nconc args* (list x)))
(setq arg (cdr arg)))
;; Nested list.
((listp x)
(setq args*
(nconc args* (use-package-normalize/:bind-wrap name keyword x)))
(setq arg (cdr arg)))
(t
(setq args* (nconc args* (list x)))
(setq arg (cdr arg))))))
(use-package-normalize/:bind name keyword args*)))
(defalias 'use-package-normalize/:bind-wrap 'use-package-normalize-bind-wrap)
(defalias 'use-package-normalize/:bind*-wrap 'use-package-normalize-bind-wrap)
(defun use-package-handler/:bind-wrap (name keyword arg rest state)
(use-package-handler/:bind name keyword arg rest state))
(defun use-package-handler/:bind*-wrap (name keyword arg rest state)
(use-package-handler/:bind name keyword arg rest state 'bind-keys*)))
(provide 'lib/packaging)
;;; packaging.el ends here

26
lisp/lib/path.el Normal file
View File

@@ -0,0 +1,26 @@
;;; path.el --- support functions for working with paths -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun path-abs-buffer ()
"Get the current buffer absolute path."
(file-truename (or (buffer-file-name) default-directory)))
(defun path-dirname (path)
"Get the parent directory of PATH."
(file-name-directory (directory-file-name path)))
(defun path-join (root &rest dirs)
"Join paths together starting at ROOT and proceeding with DIRS.
Ex: (path-join \"/tmp\" \"a\" \"b\" \"c\") => /tmp/a/b/c"
(if (not dirs)
root
(apply 'path-join
(expand-file-name (car dirs) root)
(cdr dirs))))
(provide 'lib/path)
;;; path.el ends here

11
lisp/lib/pkg-config.el Normal file
View File

@@ -0,0 +1,11 @@
;;; pkg-config.el --- pkg-config support -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun pkg-config-has-p (package)
"Check if PACKAGE is available."
(eq (call-process-shell-command "pkg-config" nil nil nil "--exists" package) 0))
(provide 'lib/pkg-config)
;;; pkg-config.el ends here

11
lisp/lib/string.el Normal file
View File

@@ -0,0 +1,11 @@
;;; string.el --- Emacs string functions. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defmacro with-face (str &rest properties)
"Print STR using PROPERTIES."
`(propertize ,str 'face (list ,@properties)))
(provide 'lib/string)
;;; string.el ends here

51
lisp/lib/utils.el Normal file
View File

@@ -0,0 +1,51 @@
;;; utils.el --- miscellaneous support functions -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defmacro try-eval (fn &optional finally)
"Safely evaluate expression FN and run FINALLY after."
(declare (debug t)
(indent 1))
`(let (retval)
(condition-case-unless-debug ex
(setq retval (progn ,fn))
('error
(setq retval (cons 'exception (list ex)))))
,@finally
retval))
(defun feature-p (feature)
"Check if FEATURE is available."
(or (featurep feature)
(when (functionp 'package-installed-p)
(package-installed-p feature))
(locate-library (symbol-name feature))))
(defun add-command-switch (handler &rest switch-list)
"Add HANDLER for SWITCH-LIST."
(dolist (switch switch-list)
(add-to-list 'command-switch-alist (cons switch handler))))
(defun add-auto-mode (mode &rest patterns)
"Use `MODE' for all given files matching `PATTERNS'."
(dolist (pattern patterns)
(add-to-list 'auto-mode-alist (cons pattern mode))))
(defun add-magic-mode (mode &rest patterns)
"Use `MODE' for all files containing header `PATTERNS'."
(dolist (pattern patterns)
(add-to-list 'magic-mode-alist (cons pattern mode))))
(defun add-interpreter-mode (mode &rest interpreters)
"Use `MODE' for all files with shebang `INTERPRETERS'."
(dolist (interpreter interpreters)
(add-to-list 'interpreter-mode-alist (cons interpreter mode))))
(provide 'lib/utils)
;;; utils.el ends here

34
lisp/lib/with.el Normal file
View File

@@ -0,0 +1,34 @@
;;; with.el --- conditional eval wrappers -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defmacro with-feature (feature &rest body)
"If FEATURE is available, load it and evaluate BODY."
(declare (indent defun))
`(when (require ,feature nil :noerror)
,@body))
(defmacro with-function (function &rest body)
"If FUNCTION is available, evaluate BODY."
(declare (indent defun))
`(when (functionp ,function)
,@body))
(defmacro with-executable (executable &rest body)
"If EXECUTABLE is available in path, evaluate BODY."
(declare (indent defun))
`(when (executable-find (symbol-name ,executable))
,@body))
(defmacro with-any-executable (executables &rest body)
"If any of EXECUTABLES are available in the path, evaluate BODY."
(declare (indent defun))
`(when (some (lambda (x) (executable-find (symbol-name x))) ,executables)
,@body))
(provide 'lib/with)
;;; with.el ends here

162
lisp/modes/c-c++.el Normal file
View File

@@ -0,0 +1,162 @@
;;; c-c++.el --- initializes C/C++ modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'cl)
(require 'lsp)
(defun user--c-format-before-save ()
"C/C++ cleanup and format before save buffer."
(delete-trailing-whitespace)
;; Format buffer.
(indent-region (point-min) (point-max) nil)
)
;; From https://www.emacswiki.org/emacs/CompileCommand
(defun* user--c-get-closest-pathname (&optional (file "Makefile"))
"Determine the pathname of the first instance of FILE starting from the current directory towards root.
This may not do the correct thing in presence of links. If it does not find FILE, then it shall return the name
of FILE in the current directory, suitable for creation"
(let ((root (expand-file-name "/"))) ; the win32 builds should translate this correctly
(expand-file-name file
(loop
for d = default-directory then (expand-file-name ".." d)
if (file-exists-p (expand-file-name file d))
return d
if (equal d root)
return nil))))
(defun user--c-lsp-set-priority (server priority)
(setf (lsp--client-priority (gethash server lsp-clients)) priority))
(defun user--c-mode-common-hook ()
"C-like languages mode hook."
(add-many-to-list 'c-default-style '(c-mode . "bsd") '(c++-mode . "bsd"))
(setq tab-width 4)
;; Propertize "#if 0" regions as comments.
(font-lock-add-keywords
nil
'((user/c-mode-font-lock-if0 (0 font-lock-comment-face prepend)))
'add-to-end)
;; Change compile-command.
(set
(make-local-variable 'compile-command)
(format "make -C %s" (directory-file-name (file-name-directory (user--c-get-closest-pathname)))))
;; Avoid to hit enter after compile-command to build.
(setq compilation-read-command nil)
;; Separate camel-case into separate words.
(subword-mode t)
(when (feature-p 'mic-paren)
;; Match context to open parentheses.
(paren-toggle-open-paren-context t))
(setq flycheck-checker-error-threshold 1000)
(setq flycheck-local-checkers '((lsp . ((next-checkers . (flawfinder))))))
;; (flycheck-add-next-checker 'clang-analyzer 'flawfinder)
(user/smartparens-enable))
(defun user/c-mode-font-lock-if0 (limit)
"Propertize '#if 0' regions, up to LIMIT in size, as comments."
(save-restriction
(widen)
(save-excursion
(goto-char (point-min))
(let ((depth 0) str start start-depth)
(while (re-search-forward "^\\s-*#\\s-*\\(if\\|else\\|endif\\)" limit 'move)
(setq str (match-string 1))
(if (string= str "if")
(progn
(setq depth (1+ depth))
(when (and (null start) (looking-at "\\s-+0"))
(setq start (match-end 0)
start-depth depth)))
(when (and start (= depth start-depth))
(c-put-font-lock-face start (match-beginning 0) 'font-lock-comment-face)
(setq start nil))
(when (string= str "endif")
(setq depth (1- depth)))))
(when (and start (> depth 0))
(c-put-font-lock-face start (point) 'font-lock-comment-face)))))
nil)
(defun user/c++-header-file-p ()
"Return non-nil if in a C++ header."
(and (string-match "\\.h$" (or (buffer-file-name) (buffer-name)))
(save-excursion (re-search-forward "\\_<class\\_>" nil t))))
;; https://www.gnu.org/software/emacs/manual/html_mono/ccmode.html
(use-package cc-mode
:defer
:hook
(c-mode-common-hook . user--c-mode-common-hook)
(c-mode-common-hook . hs-minor-mode)
(c-mode-common-hook . lsp-deferred)
(c-mode-common-hook . (lambda ()
(add-hook 'before-save-hook #'user--c-format-before-save nil t)))
:init
;; Detect if inside a C++ header file.
(add-magic-mode 'c++-mode 'user/c++-header-file-p)
:config
(add-many-to-list 'c-default-style '(c-mode . "bsd") '(c++-mode . "bsd")
)
;;; (Packages) ;;;
;; https://github.com/emacs-mirror/emacs/blob/master/lisp/progmodes/cc-vars.el
;; user customization variables for CC Mod
(use-package cc-vars
:disabled
:ensure cc-mode
:config
(validate-setq
;; Support completion using tab.
c-tab-always-indent nil
c-insert-tab-function 'indent-for-tab-command)
)
;; https://github.com/randomphrase/company-c-headers
;; Auto-completion for C/C++ headers using Company
(use-package company-c-headers
:after (company))
;; https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-clangd.el
;; LSP clients for the C Languages Family
(use-package lsp-clangd
:after (company lsp)
;; :defer t
:config
;; set priority to ensure the use of clangd
(setq company-backends '(company-capf))
(user--c-lsp-set-priority 'clangd 1))
;; https://github.com/MaskRay/emacs-ccls
;; Emacs client for ccls, a C/C++ language server
(use-package ccls
:if (executable-find "ccls")
:after lsp
:config
(user--c-lsp-set-priority 'ccls -1)
(validate-setq
ccls-initialization-options
'(:index (:comments 1) :cacheFormat "msgpack")))
;; https://github.com/alexmurray/flycheck-flawfinder
;; Integrate flawfinder with flycheck to automatically check for possible security weaknesses
;; within your C/C++ code on the fly.
(use-package flycheck-flawfinder
:disabled
:ensure t
:if (executable-find "flawfinder")
:config
(flycheck-flawfinder-setup))
)
(provide 'modes/c-c++)
;;; c-c++.el ends here

15
lisp/modes/dot.el Normal file
View File

@@ -0,0 +1,15 @@
;;; markdown --- initializes Dot modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; https://github.com/ppareit/graphviz-dot-mode
;; Emacs mode for the DOT language, used by graphviz.
(use-package graphviz-dot-mode
:init
(use-package company-graphviz-dot)
:config
(setq graphviz-dot-preview-extension "svg")
(setq graphviz-dot-indent-width 2))
(provide 'modes/dot)
;;; dot.el ends here

76
lisp/modes/fundamental.el Normal file
View File

@@ -0,0 +1,76 @@
;;; fundamental.el --- Base mode of all other major modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--fundamental-mode-hook ()
"Fundamental mode hook."
(with-feature 'undo-tree
(undo-tree-mode t))
(auto-fill-mode t)
;; Enable whitespace mode globally.
;;(whitespace-mode t)
(with-feature 'rainbow-delimiters
(rainbow-delimiters-mode t))
;; Enable dtrt-indent to attempt to identify the indentation rules used.
(with-eval-after-load 'dtrt-indent
(dtrt-indent-mode t))
;;; (Bindings) ;;;
(user/bind-key-local :code :align 'align-current)
(when (feature-p 'helm)
(user/bind-key-local :nav :functions/toc 'helm-imenu)))
(defun user--fundamental-mode-config ()
"Initialize Emacs fundamental mode."
(validate-setq
;; When using fill-paragraph or auto-fill-mode break lines at 80 characters by
;; default.
fill-column 120)
;;; (Packages) ;;;
;;; https://github.com/Fanael/rainbow-delimiters
(use-package rainbow-delimiters
:ensure t)
;; https://www.emacswiki.org/emacs/MicParen
(use-package mic-paren
:ensure t
:config
(paren-activate))
;; https://github.com/Lindydancer/dynamic-spaces
(use-package dynamic-spaces
:disabled
:config
(dynamic-spaces-global-mode t))
;; https://github.com/terlar/indent-info.el
(use-package indent-info
:ensure t
:config
(global-indent-info-mode t))
;; https://github.com/shawcm/goldendict-emacs
(use-package goldendict
:disabled
:if (executable-find "goldendict")
:bind-wrap
((:key :doc :dictionary) . goldendict-dwim))
;; https://www.emacswiki.org/emacs/FillAdapt
(use-package filladapt
:disabled)
;; https://github.com/fritzgrabo/cascading-dir-locals
;; Emacs: Apply all (!) .dir-locals.el from root to current directory.
(use-package cascading-dir-locals
:ensure t
:config
(cascading-dir-locals-mode 1)))
(user--fundamental-mode-config)
(provide 'modes/fundamental)
;;; fundamental.el ends here

112
lisp/modes/javascript.el Normal file
View File

@@ -0,0 +1,112 @@
;;; javascript.el --- initializes JavaScript modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--javascript-mode-common-hook ()
"JavaScript common mode hook."
;; ;; Load CEDET
;; (user--javascript-mode-cedet-hook)
;; (user/gnu-global-enable)
(flycheck-mode t)
;; (tern-mode t)
)
(defun user--javascript-mode-hook ()
"JavaScript mode hook."
(user--javascript-mode-common-hook))
(defun user--inferior-js-mode-hook ()
"Inferior JavaScript mode hook."
;; Support ANSI colors.
(ansi-color-for-comint-mode-on))
(defun user--js2-mode-hook ()
"JS2 mode hook."
(user--javascript-mode-common-hook)
;; Enable smart indentation
(smart-tabs-mode t)
;; Enable Flycheck
(flycheck-mode t))
;; (defun user--javascript-mode-cedet-hook ()
;; "JavaScript CEDET support hook."
;; (with-feature 'semantic/wisent/javascript
;; (wisent-javascript-setup-parser)
;; ;; (user--cedet-hook)
;; ))
;;
;;
(use-package js
:defer
:hook ((javascript-mode-hook . user--javascript-mode-hook)
(inferior-js-mode-hook . user--inferior-javascript-mode-hook)))
;; https://github.com/mooz/js2-mode
;; Improved JavaScript editing mode for GNU Emacs
(use-package js2-mode
:defer
:mode "\.[m]js$"
;; :mode "\.ts$"
:magic "#!/usr/bin/env node"
:hook (js2-mode-hook . user--js2-mode-hook)
:config
(validate-setq
;; ;; Configure indentation
;; (setq js2-enter-indents-newline t)
;; (setq js2-auto-indent-p t)
;; Idle timeout before reparsing buffer
js2-idle-timer-delay 0.5
;; Disable error parsing in favor of Flycheck
js2-strict-missing-semi-warning nil)
;; https://github.com/redguardtoo/js-comint
;; js-comint will send the code from Emacs into node.js or rhino
(use-package js-comint
:disabled
:config
(validate-setq
;; Set JavaScript inferior.
inferior-js-program-command
(cond
((executable-find "js") (executable-find "js"))
((executable-find "node")
(concat (executable-find "node") " --interactive"))
(t "java org.mozilla.javascript.tools.shell.Main")))
;; Workaround for Node.js prompt.
(setenv "NODE_NO_READLINE" "1"))
;; https://github.com/prettier/prettier-emacs
;; Minor mode to format JS code on file save
(use-package prettier-js
:disabled)
;; https://emacs-lsp.github.io/lsp-mode/page/lsp-typescript-javascript/
(use-package lsp-javascript-typescript
:disabled
:if (executable-find "javascript-typescript-langserver")
:hook (js2-mode-hook . lsp-javascript-typescript-enable))
;; https://github.com/torgeir/helm-js-codemod.el
;; A helm interface for running js-codemod.el
(use-package helm-js-codemod
:disabled
:if (executable-find "jscodeshift"))
;; https://github.com/js-emacs/xref-js2
;; Jump to references/definitions using ag & js2-mode's AST in Emacs
(use-package xref-js2
:init
(add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t)))
(provide 'modes/javascript)
;;; javascript.el ends here

32
lisp/modes/makefile.el Normal file
View File

@@ -0,0 +1,32 @@
;;; makefile.el --- Initializes Makefile mode -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; Sets some decent defaults for makefile-mode
(defun user--makefile-mode-hook ()
"Initialize makefile mode."
(setq
;; Use tabs for indent.
indent-tabs-mode t)
;; Disable whitespace mode settings that don't make sense in makefiles.
(user/whitespace-disable-style '(indentation space-after-tab))
;; Separate camel-case into separate words.
(subword-mode t)
;; Support for documentation in Doxygen format.
;; (with-feature 'doxymacs
;; (doxymacs-mode t))
(with-feature 'makefile-executor
(makefile-executor-mode t)))
(use-package make-mode
:defer
:mode ("\.\(mak\|mif\|wat\)$" . makefile-mode)
:init
(add-hook 'makefile-mode-hook 'user--makefile-mode-hook)
:config
(use-package makefile-executor))
(provide 'modes/makefile)
;;; makefile.el ends here

91
lisp/modes/markdown.el Normal file
View File

@@ -0,0 +1,91 @@
;;; markdown --- initializes Markdown modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-flymd-cache-directory*
(path-join *user-cache-directory* "flymd")
"Path to user's FLYMD cache store.")
(defun user--markdown-mode-hook ()
"Markdown mode hook."
(user/smartparens-enable)
;; org-mode table editing tools.
(orgtbl-mode t))
;; https://github.com/jrblevin/markdown-mode
;; Emacs Markdown Mode
(use-package markdown-mode
:defer
:hook (markdown-mode-hook . user--markdown-mode-hook)
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:config
(setq markdown-fontify-code-blocks-natively t)
(setq markdown-command "pandoc -f gfm --highlight-style kate")
(setq markdown-css-paths (list (path-join user-emacs-directory "markdown_style.css")))
(setq markdown-xhtml-body-preamble "\<article class=\"markdown-body\">")
;; Thanks to https://gist.github.com/yryozo/5807243
;; Orgtbl Translator function for the GitHub-Flavored-Markdown(GFM)
;; Usage Example:
;;
;; <!-- BEGIN RECEIVE ORGTBL ${1:YOUR_TABLE_NAME} -->
;; <!-- END RECEIVE ORGTBL $1 -->
;;
;; <!--
;; #+ORGTBL: SEND $1 orgtbl-to-gfm
;; | $0 |
;; -->
(defun orgtbl-to-gfm (table params)
"Convert the Orgtbl mode TABLE to GitHub Flavored Markdown."
(let* ((alignment (mapconcat (lambda (x) (if x "|--:" "|---"))
org-table-last-alignment ""))
(params2
(list
:splice t
:hline (concat alignment "|")
:lstart "| " :lend " |" :sep " | ")))
(orgtbl-to-generic table (org-combine-plists params2 params))))
;; https://github.com/mmark-md/flycheck-mmark
;; Flycheck checker for the MMark markdown processor
(use-package flycheck-mmark
:disabled
:if (executable-find "mmark")
:hook (flycheck-mode-hook . flycheck-mmark-setup))
;; https://github.com/polymode/poly-markdown
;; Polymode for markdown-mode
(use-package poly-markdown
:after polymode
:hook (markdown-mode-hook . poly-markdown-mode))
;; https://github.com/niku/markdown-preview-eww
;; Realtime markdown preview by eww
(use-package markdown-preview-eww)
;; https://github.com/ajtulloch/mkdown.el
;; A small library that improves the look of Markdown previews from Emacs, using the style of mkdown.com.
(use-package mkdown
:disabled
:config
(add-to-list 'markdown-css-paths mkdown-css-file-name))
;; https://github.com/shime/emacs-livedown
;; Emacs plugin for Livedown.
(use-package livedown
:disabled
:if (executable-find "livedown")
:quelpa (livedown
:fetcher github
:repo "shime/emacs-livedown")
:init
(require 'livedown)))
(provide 'modes/markdown)
;;; markdown.el ends here

954
lisp/modes/org.el Normal file
View File

@@ -0,0 +1,954 @@
;;; org.el --- Org mode support -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-org-data-directory*
(path-join *user-data-directory* "org")
"Path to user's org data store.")
(defconst *user-org-cache-directory*
(path-join *user-cache-directory* "org")
"Path to user's org cache store.")
(defvar user/org-mobile-sync-timer nil
"Timer used for syncing OrgMobile.")
(defvar user/org-mobile-sync-secs (* 60 20)
"Interval of OrgMobile sync in seconds.")
(defun user--org-mode-hook ()
"Org mode hook."
(unless (derived-mode-p 'text-mode)
(user--text-mode-hook))
(with-feature 'org-sticky-header
;; Enable sticky org mode header.
(org-sticky-header-mode t))
;; Highlighting lines that are too long since it often causes false
;; positives on URLs.
(user/whitespace-disable-style '(lines lines-tail))
(rainbow-delimiters-mode-disable)
(setq
;; Proper filling of org-mode text, form:
;; * http://lists.gnu.org/archive/html/emacs-orgmode/2008-01/msg00375.html
paragraph-separate
"\f\\|\\*+ \\|[ ]*$\\| [ \t]*[:|]\\|^[ \t]+\\[[0-9]\\{4\\}-"
paragraph-start
(concat "\f\\|[ ]*$\\|\\*+ \\|\f\\|[ \t]*\\([-+*][ \t]+\\|"
"[0-9]+[.)][ \t] +\\)\\|[ \t]*[:|]\\|"
"^[ \t]+\\[[0-9]\\{4\\}-"))
(with-feature 'org-table-sticky-header
;; Enable sticky headers for tables.
(org-table-sticky-header-mode t))
(user/smartparens-enable)
(org-bullets-mode t)
;;; (Bindings) ;;;
(user/bind-key-local :basic :open-buffer-context 'org-iswitchb)
(user/bind-key-local :basic :narrow-to-page 'org-narrow-to-subtree)
(user/bind-key-local :basic :narrow-to-region 'org-narrow-to-block)
(user/bind-key-local :basic :narrow-to-function 'org-narrow-to-element)
(user/bind-key-local :code :context-promote 'org-shiftup)
(user/bind-key-local :code :context-demote 'org-shiftdown))
(defun user--org-agenda-finalize-hook ()
"Org agenda display hook."
;; Enable appointment notifications.
(org-agenda-to-appt t))
(defun user--org-load-hook ()
"Org-mode loaded hook."
(when (not noninteractive)
;; Resume clocking tasks when Emacs is restarted.
(org-clock-persistence-insinuate))
;; Load modules.
(when org-modules-loaded
(org-load-modules-maybe 'force))
;; ;; Load Babel languages.
;; (org-babel-do-load-languages 'org-babel-load-languages
;; org-babel-load-languages))
)
(defun user/org-open-at-point (&optional arg)
"Like `org-open-at-point' but will use external browser with prefix ARG."
(interactive "P")
(if (not arg)
(org-open-at-point)
(let ((browse-url-browser-function #'browse-url-default-browser))
(org-open-at-point))))
(defun user/org-annotate-file-storage-file ()
"Get the path to the annotation storage file."
(or (with-project-root project-root (path-abs-buffer)
(path-join project-root (concat (user/proj-name project) ".org")))
org-annotate-file-storage-file))
(defun user/org-annotate-file ()
"Annotate the current buffer."
(interactive)
(with-feature 'org-annotate-file
(let ((storage-file (user/org-annotate-file-storage-file))
(popwin-config '(:position :bottom)))
(popwin:display-buffer-1 (org-annotate-file-show-section storage-file)
:default-config-keywords popwin-config))))
;; (defun user/org-mobile-sync-pull-and-push ()
;; "Sync OrgMobile directory."
;; (org-mobile-pull)
;; (org-mobile-push)
;; (with-eval-after-load 'sauron
;; (sauron-add-event 'my 3 "Called org-mobile-pull and org-mobile-push")))
;; (defun user/org-mobile-sync-start ()
;; "Start automated `org-mobile-push'."
;; (interactive)
;; (setq user/org-mobile-sync-timer
;; (run-with-idle-timer user/org-mobile-sync-secs t
;; 'user/org-mobile-sync-pull-and-push)))
;; (defun user/org-mobile-sync-stop ()
;; "Stop automated `org-mobile-push'."
;; (interactive)
;; (cancel-timer user/org-mobile-sync-timer))
(use-package org
:init
;; Create data and cache stores.
(make-directory *user-org-data-directory* t)
(make-directory *user-org-cache-directory* t)
;; Fix for EIN if org hasn't been setup yet.
(autoload 'org-add-link-type "org" "" t)
:hook
((org-load-hook . user--org-load-hook)
(org-mode-hook . user--org-mode-hook))
:bind
(:map org-mode-map
("C-c C-o" . user/org-open-at-point))
:config
;; https://github.com/sabof/org-bullets
;; utf-8 bullets for org-mode
(use-package org-bullets)
;; (use-package org-plus-contrib
;; :ensure t
;; :no-require t)
(validate-setq
;; Org data store.
org-directory *user-org-data-directory*
;; Notes data store.
;; org-default-notes-file (path-join *user-org-data-directory* "refile.org")
;; Pressing return on a link follows it.
org-return-follows-link t
;; Log time for TODO state changes.
;; org-log-done 'time
;; Log time when rescheduling an entry.
;; org-log-reschedule 'time
;; org-log-redeadline 'time
;; Round clock times to 15 minute increments.
;; org-time-stamp-rounding-minutes (quote (1 15))
;; Log drawer state changes.
;; org-log-into-drawer t
;; Allow single letter commands at beginning of headlines.
;; org-use-speed-commands t
;; Don't use the image width when inlining
org-image-actual-width nil
;; Fontify code blocks by default.
org-src-fontify-natively t
;; Tab should operate according to local mode.
org-src-tab-acts-natively t
;; Disable the indentation increases by one space in a demotion command
org-adapt-indentation nil
;; Don't preserve source code indentation so it can be adapted to document.
org-src-preserve-indentation nil
org-edit-src-content-indentation 0
;; Prevent editing of invisible regions.
org-catch-invisible-edits 'error
;; Allow fast state transitions.
;; org-use-fast-todo-selection 'auto
;; Do not record timestamp when using S-cursor to change state.
;; org-treat-S-cursor-todo-selection-as-state-change nil
;; Start in folded view.
org-startup-folded t
;; Enable speed commands.
org-use-speed-commands t
org-speed-commands-user
'(("0" . 'delete-window)
("1" . 'delete-other-windows)
("2" . 'split-window-vertically)
("3" . 'split-window-horizontally)
("h" . 'hide-other)
("s" . 'org-save-all-org-buffers)
("z" . 'org-add-note)
("N" . 'org-narrow-to-subtree)
("W" . 'widen)
("m" . 'org-mark-subtree)))
(when (eq default-terminal-coding-system 'utf-8)
(validate-setq
;; Prettify content using UTF-8.
org-pretty-entities t))
;; (setq org-todo-keyword-faces
;; (quote (("DONE" :foreground "red" :weight bold))))
;; TODO
;; Incompatible with validate-setq.
;; (setq
;; State transitions (http://doc.norang.ca/org-mode.html).
;; org-todo-keywords
;; (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
;; (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE"
;; "MEETING")))
;; Triggered state changes.
;; org-todo-state-tags-triggers
;; (quote (("CANCELLED" ("CANCELLED" . t))
;; ("WAITING" ("WAITING" . t))
;; ("HOLD" ("WAITING") ("HOLD" . t))
;; (done ("WAITING") ("HOLD"))
;; ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
;; ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
;; ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))
;; (add-many-to-list
;; 'org-modules
;; ;; File attachment manager.
;; 'org-attach
;; ;; Link to BibTeX entries.
;; 'org-bibtex
;; ;; Link to tags.
;; 'org-ctags
;; ;; Link to articles and messages in Gnus.
;; 'org-gnus
;; ;; Habit tracking.
;; 'org-habit
;; ;; Support links to info pages.
;; 'org-info
;; ;; Support links to man pages.
;; 'org-man
;; ;; Export org buffer to MIME email message.
;; 'org-mime
;; ;; Allow external applications to talk to org.
;; 'org-protocol
;; ;; Embed source code in org-mode.
;; 'org-src)
;; (when (feature-p 'bbdb)
;; (add-to-list 'org-modules 'org-bbdb))
;; (when (feature-p 'emacs-w3m)
;; (add-to-list 'org-modules 'org-w3m))
;; (when (feature-p 'wanderlust)
;; (add-to-list 'org-modules 'org-wl))
;; (with-executable 'git
;; (add-to-list 'org-modules 'org-git-link))
;; (setq org-agenda-files '("~/org/GPE_OBIF.org"))
;; (setq org-default-notes-file "~/org/GPE_OBIF.org" initial-buffer-choice org-default-notes-file)
(setq org-duration-format (quote h:mm))
(setq org-hierarchical-todo-statistics nil)
(setq org-startup-folded "folded")
(setq org-todo-keywords '((sequence "TODO" "|" "DONE" "REJECTED")))
(when (display-graphic-p)
(validate-setq
;; Display inline images when starting up.
org-startup-with-inline-images t))
;; https://orgmode.org/manual/Refile-and-Copy.html
(use-package org-refile
:ensure nil
:config
(validate-setq
;; Allow refile to create parent tasks, with confirmation.
org-refile-allow-creating-parent-nodes 'confirm
;; Cache refile operations for performance.
org-refile-use-cache t))
;; https://www.gnu.org/software/emacs/manual/html_node/org/Tables.html
(use-package org-table
:ensure nil
:config
;; https://github.com/cute-jumper/org-table-sticky-header
;; A minor mode to show the sticky header for org-mode tables.
(use-package org-table-sticky-header))
;; https://orgmode.org/manual/Capture.html
;; https://www.labri.fr/perso/nrougier/GTD/index.html
(use-package org-capture
:ensure nil
:init
(user/bind-key-global :apps :capture-task 'org-capture)
:config
;; Incompatible with validate-setq.
;; TODO
;; (setq
;; Capture templates.
;; org-capture-templates
;; (quote (("t" "todo" entry (file org-default-notes-file)
;; "* TODO %?\n%U\n%a\n" :clock-in t :clock-resume t)
;; ("r" "respond" entry (file org-default-notes-file)
;; "* NEXT Respond to %:from on %:subject\nSCHEDULED: %t\n%U\n%a\n"
;; :clock-in t :clock-resume t :immediate-finish t)
;; ("n" "note" entry (file org-default-notes-file)
;; "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t)
;; ("j" "Journal" entry
;; (file+datetree (path-join *user-org-data-directory* "diary.org"))
;; "* %?\n%U\n" :clock-in t :clock-resume t)
;; ("w" "org-protocol" entry (file org-default-notes-file)
;; "* TODO Review %c\n%U\n" :immediate-finish t)
;; ("m" "Meeting" entry (file org-default-notes-file)
;; "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t)
;; ("p" "Phone call" entry (file "~/git/org/refile.org")
;; "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t)
;; ("h" "Habit" entry (file org-default-notes-file)
;; (concat "* NEXT %?\n%U\n%a\n"
;; "SCHEDULED: "
;; "%(format-time-string \"<%Y-%m-%d %a .+1d/3d>\")\n:"
;; "PROPERTIES:\n:STYLE: habit\n"
;; ":REPEAT_TO_STATE: NEXT\n:END:\n")))))
;; https://github.com/tkf/org-mode/blob/master/lisp/org-id.el
;; Global identifiers for Org-mode entries
(use-package org-id
:disabled
:ensure nil
:config
(validate-setq
org-id-locations-file
(path-join *user-org-data-directory* "org-id-locations")))
;; https://github.com/grugrut/helm-books/tree/625aadec1541a5ca36951e4ce1301f4b6fe2bf3f
;; Book search interface for emacs helm.
(use-package helm-books
:disabled
:config
(add-to-list
'org-capture-templates
'("b" "book memo" entry
(file (concat org-directory "book.org"))
"* %(helm-books)")))
;; https://github.com/Chobbes/org-chef
;; A package for making a cookbook and managing recipes with org-mode.
(use-package org-chef
:disabled
:config
(add-to-list
'org-capture-templates
`("c" "Cookbook" entry
(file ,(path-join *user-org-data-directory* "cookbook.org"))
"%(org-chef-get-recipe-from-url)"
:empty-lines 1)))
;; https://github.com/waymondo/org-repo-todo
;; Simple repository todo management with org-mode
(use-package org-repo-todo))
;; https://github.com/emacs-mirror/emacs/blob/master/lisp/org/ob-core.el
;; Working with Code Blocks
(use-package ob-core
:ensure nil
:config
(validate-setq
;; Don't ask for validation.
org-confirm-babel-evaluate nil)
(add-many-to-list
'org-babel-load-languages
;; Emacs Lisp
'(emacs-lisp . t)
;; Shell script
'(shell . t))
(let ((to-load '((emacs-lisp . t) (shell . t))))
(with-executable 'g++
(push '(C . t) to-load)
;; Use of lsp-clangd for C/C++
(setq org-babel-C++-compiler "bear g++"))
(with-executable 'dot
(push '(dot . t) to-load))
(with-executable 'ghc
(push '(haskell . t) to-load))
(with-executable 'gnuplot
(push '(gnuplot . t) to-load))
(with-executable 'latex
(push '(latex . t) to-load))
(with-executable 'perl
(push '(perl . t) to-load))
(with-executable 'python
(push '(python . t) to-load))
(with-executable 'R
(push '(R . t) to-load))
(with-executable 'ruby
(push '(ruby . t) to-load))
(when (feature-p 'plantuml-mode)
;; https://github.com/skuro/plantuml-mode
;; A major mode for editing PlantUML sources in Emacs
(use-package ob-plantuml
:ensure nil
:after modes/plantuml
:config
(validate-setq
org-plantuml-jar-path *user-plantuml-jar-path*))
(push '(plantuml . t) to-load))
(org-babel-do-load-languages 'org-babel-load-languages to-load))
;; https://github.com/dfeich/helm-lib-babel/tree/41bc0cdea8a604c6c8dc83ed5066644d33688fad
;; Emacs helm extension for inserting a reference to an org source block function
(use-package helm-lib-babel)
;; https://github.com/astahlman/ob-async
;; Asynchronous src_block execution for org-babel
(use-package ob-async
:defer
:config
(add-to-list
;; Execute org-babel asynchronously.
'org-ctrl-c-ctrl-c-hook 'ob-async-org-babel-execute-src-block))
;; https://github.com/pope/ob-go
;; Org-Babel support for evaluating go code
(use-package ob-go
:if (executable-find "go")
:init (add-to-list 'org-babel-load-languages '(go . t)))
;; https://github.com/zweifisch/ob-http
;; Org-Babel support for evaluating http
(use-package ob-http
:init (add-to-list 'org-babel-load-languages '(http . t)))
;; https://github.com/micanzhang/ob-rust
;; Org-Babel support for evaluating Rust code
(use-package ob-rust
:if (executable-find "rustc")
:init (add-to-list 'org-babel-load-languages '(rust . t)))
;; https://github.com/krisajenkins/ob-translate
;; Allows you to translate blocks of text within org-mode
(use-package ob-translate
:disabled
:init (add-to-list 'org-babel-load-languages '(translate . t)))
;; https://github.com/andrmuel/ob-uart
;; Org babel support for UART communication
(use-package ob-uart
:disabled
:init (add-to-list 'org-babel-load-languages '(uart . t)))
;; https://github.com/ahendriksen/ob-tmux
;; Ob-tmux is an Emacs library that allows org mode to evaluate code blocks in a tmux session.
(use-package ob-tmux
:if (executable-find "tmux")
:init (add-to-list 'org-babel-load-languages '(tmux . t))))
;; https://github.com/emacs-mirror/emacs/blob/master/lisp/org/ox-org.el
;; Org Back-End for Org Export Engine
(use-package ox
:ensure nil
:config
(validate-setq
;; Export as UTF-8.
org-export-coding-system 'utf-8)
;; Org export modules to load by default.
(add-many-to-list
'org-export-backends
;; Ascii support.
'ascii
;; HTML.
'html
;; OpenDocument Text support.
'odt)
(with-executable 'latex
(add-many-to-list
'org-export-backends
;; Beamer presentation export.
'beamer
;; Plain LaTeX export.
'latex))
;; https://github.com/tomalexander/orgmode-mediawiki/tree/a9327150293e370e500ba55bddfe5fc435c6bf9b
;; A mediawiki export for Emacs org-mode
(use-package ox-mediawiki
:config (add-to-list 'org-export-backends 'mediawiki))
;; https://github.com/larstvei/ox-gfm
;; Github Flavored Markdown Back-End for Org Export Engine
(use-package ox-gfm
:config (add-to-list 'org-export-backends 'gfm))
;; https://github.com/stig/ox-jira.el
;; Org-mode export backend for JIRA markup
(use-package ox-jira
:disabled
:config (add-to-list 'org-export-backends 'jira))
;; https://github.com/kawabata/ox-pandoc
;; Another org-mode exporter via pandoc
(use-package ox-pandoc
:if (executable-find "pandoc")
:pin "MELPA"
:config (add-to-list 'org-export-backends 'pandoc))
;; https://github.com/choppsv1/org-rfc-export/tree/1a49535cf927cd52ffa05c815b890888c4addf86
;; Org-mode export back-end for creating internet-drafts and RFCs using xml2rfc.
(use-package ox-rfc
:disabled
:config (add-to-list 'org-export-backends 'rfc)))
;; Load org agenda.
(add-to-list 'org-modules 'org-agenda)
(add-to-list 'org-modules 'org)
;; https://orgmode.org/manual/Org-Mobile.html
(use-package org-mobile
:disabled
:ensure nil
:config
(validate-setq
;; Location of TODO items to sync.
org-mobile-inbox-for-pull org-default-notes-file
;; MobileOrg sync directory.
org-mobile-directory (path-join *user-org-data-directory* "mobile")
;; Custom agenda view.
org-mobile-force-id-on-agenda-items nil))
;; https://github.com/ifree/org-onenote
;; Post org file to onenote
(use-package org-onenote
:disabled)
;;; (Packages) ;;;
;; https://github.com/unhammer/org-rich-yank
;; Rich text clipboard for org-mode: Paste into a #+BEGIN_SRC block of correct mode, with link to where it came from
(use-package org-rich-yank
:bind-wrap
(:map org-mode-map
((:key :basic :alternate-paste) . org-rich-yank)))
;; https://github.com/tkf/org-mode/blob/master/lisp/org-clock.el
;; The time clocking code for Org-mode
(use-package org-clock
:ensure nil
:config
(validate-setq
;; Clock data store.
org-clock-persist-file (path-join *user-org-cache-directory*
"org-clock-save.el"))
(when (not noninteractive)
;; When running in batch, don't setup time tracking.
(validate-setq
;; Resume clocking task on clock-in if the clock is open.
org-clock-in-resume t
;; Save clock data and state changes and notes in the LOGBOOK drawer.
org-clock-into-drawer t
;; Remove clock line if time is zero.
org-clock-out-remove-zero-time-clocks t
;; Stop clock when entry is marked as DONE.
org-clock-out-when-done t
;; Show the amount of time spent on the current task today.
org-clock-mode-line-total 'today
;; Resume clock when reopening Emacs.
org-clock-persist t
;; Enable auto clock resolution for finding open clocks.
org-clock-auto-clock-resolution 'when-no-clock-is-running
;; Include current clocking task in clock reports.
org-clock-report-include-clocking-task t)))
;; https://github.com/alphapapa/org-sticky-header
;; Show off-screen Org heading at top of window
(use-package org-sticky-header)
;; https://github.com/daimrod/org-sync
;; Synchronize Org documents with external services
(use-package org-sync
:disabled
:config
(validate-setq
;; Org sync cache store.
org-sync-cache-file (path-join *user-org-cache-directory* "org-sync-cache"))
;; Redmine module.
(load "org-sync-redmine")
;; GitHub module.
(load "org-sync-github"))
;; https://github.com/dengste/org-caldav
;; Caldav sync for Emacs orgmode
(use-package org-caldav
:disabled
:config
(validate-setq
;; Path to state synchronization file.
org-caldav-save-directory (path-join *user-org-cache-directory* "org-caldav")
;; Path to inbox file.
org-caldav-inbox (path-join *user-org-data-directory* "org-caldav-inbox.org")
;; Path to backup file.
org-caldav-backup-file (path-join *user-org-data-directory* "org-caldav-backup.org")
;; Link to org agenda.
org-caldav-files org-agenda-files
;; Ask before deleting entries on server.
org-caldav-delete-calendar-entries 'ask)
;; Ensure that state synchronization directory exists.
(make-directory org-caldav-save-directory t))
;; https://github.com/alphapapa/org-web-tools
;; View, capture, and archive Web pages in Org-mode
(use-package org-web-tools)
;; https://github.com/facetframer/orgnav
;; Quickly navigate and search your emacs org trees; use this navigation to capture and organize
(use-package orgnav)
;; https://github.com/rlister/org-present
;; Ultra-minimalist presentation minor-mode for Emacs org-mode
(use-package org-present
:disabled
:config
(with-eval-after-load 'org-present
(add-hook 'org-present-mode-hook
(lambda ()
(org-present-big)
(org-display-inline-images)
(org-present-hide-cursor)
(org-present-read-only)))
(add-hook 'org-present-mode-quit-hook
(lambda ()
(org-present-small)
(org-remove-inline-images)
(org-present-show-cursor)
(org-present-read-write)))))
;; https://github.com/alphapapa/org-rifle
;; Rifle through your Org-mode buffers and acquire your target
(use-package helm-org-rifle)
;; https://github.com/weirdNox/org-noter
;; Emacs document annotator, using Org-mode
(use-package org-noter
:disabled)
;; https://github.com/louietan/anki-editor
;; Emacs minor mode for making Anki cards with Org
(use-package anki-editor)
;; https://github.com/dfeich/org-screenshot
;; screenshots integrated with emacs org mode attachments
(use-package org-attach-screenshot
:disabled)
;; https://github.com/harrybournis/org-fancy-priorities
;; Display Org Mode priorities as custom strings
(use-package org-fancy-priorities
:hook (org-mode-hook . org-fancy-priorities-mode))
;; https://github.com/calvinwyoung/org-autolist
;; Making it even easier to edit lists in org-mode!
(use-package org-autolist
:hook (org-mode-hook . org-autolist-mode))
;; https://github.com/abo-abo/org-download
;; Drag and drop images to Emacs org-mode
(use-package org-download)
;; https://github.com/tarsius/org-elisp-help
;; Org links to emacs-lisp documentation
(use-package org-elisp-help)
;; https://github.com/emacsjanitors/org-fstree
;; Include a filesystem subtree into an org file
(use-package org-fstree
:disabled)
;; https://github.com/flexibeast/org-vcard
;; Export and import vCards from within GNU Emacs' Org mode.
(use-package org-vcard
:disabled
:config
(validate-setq
org-vcard-custom-styles-dir (path-join *user-org-data-directory* "org-vcard-styles")))
;; https://github.com/gizmomogwai/org-kanban
;; Kanban table for org-mode
;; Enables `#+BEGIN: kanban' for producing a kanban table.
(use-package org-kanban
:disabled))
;; https://orgmode.org/manual/Agenda-Commands.html
(use-package org-agenda
:ensure org-plus-contrib
:defer
:hook (org-agenda-finalize-hook . user--org-agenda-finalize-hook)
:bind-wrap
(((:key :apps :agenda) . org-agenda)
((:key :apps :todo) . org-todo-list))
:config
(let ((agenda-data-store (path-join *user-org-data-directory* "agendas")))
(validate-setq
;; Agenda data store.
org-agenda-files `(,agenda-data-store))
;; Ensure that agenda data store exists.
(make-directory agenda-data-store t))
(validate-setq
org-agenda-breadcrumbs-separator ""
;; Ignore agenda files that are unavailable.
org-agenda-skip-unavailable-files t
;; Restore window configuration when done with the agenda.
org-agenda-restore-windows-after-quit t
;; Start on Monday.
org-agenda-start-on-weekday 1
;; Show month by default.
;; org-agenda-span 'month
;; Don't display scheduled todos.
;; org-agenda-todo-ignore-scheduled 'future
;; Don't show nested todos.
;; org-agenda-todo-list-sublevels nil
;; Don't dim blocked tasks.
org-agenda-dim-blocked-tasks nil
;; Compact block agenda view.
;; org-agenda-compact-blocks t
;; Include Emacs' Diary in org-agenda.
org-agenda-include-diary t
;; Switch window when opening org-agenda.
;; org-agenda-window-setup 'other-window
;; Display indirect buffers in the "current" window.
org-indirect-buffer-display 'current-window
;; Reset all custom commands.
org-agenda-custom-commands nil)
(add-many-to-list
'org-agenda-custom-commands
;; `("T", "Daily Timesheet"
;; (my-org-timeline)
;; ))
`("a" "Agenda"
((agenda ""
((org-agenda-prefix-format "%-12:c%?-12t% b% s")
(org-genda-list))))))
;; (
;; (org-agenda-repeating-timestamp-show-all nil)
;; (org-agenda-remove-tags t)
;; (org-agenda-overriding-header "⚡ Calendar")
;; ;; (org-agenda-prefix-format "%?-12t% s")
;; (org-agenda-prefix-format " %?-12t% s")
;; (org-agenda-todo-keyword-format "")
;; (my-org-timeline)
;; )))))
;; '("a" "Agenda" org-agenda-list)
;; '("c" . "COLLECT...")
;; '("cb" "CollectBox" ((alltodo "")))
;; '("f" . "FOCUS...")
;; '("f." "Today"
;; ((agenda ""
;; ((org-agenda-entry-types '(:timestamp :sexp))
;; (org-agenda-overriding-header
;; (concat "CALENDAR Today"
;; (format-time-string "%a %d" (current-time))))
;; (org-agenda-span 'day)))
;; (tags-todo "LEVEL=1+REFILE"
;; ((org-agenda-overriding-header "COLLECTBOX (Unscheduled)")))
;; (tags-todo "DEADLINE=\"<+0d>\""
;; ((org-agenda-overriding-header "DUE TODAY")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notedeadline))
;; (org-agenda-sorting-strategy '(priority-down))))
;; (tags-todo "DEADLINE<\"<+0d>\""
;; ((org-agenda-overriding-header "OVERDUE")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notedeadline))
;; (org-agenda-sorting-strategy '(priority-down))))
;; (agenda ""
;; ((org-agenda-entry-types '(:scheduled))
;; (org-agenda-overriding-header "SCHEDULED")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'todo 'done))
;; (org-agenda-sorting-strategy
;; '(priority-down time-down))
;; (org-agenda-span 'day)
;; (org-agenda-start-on-weekday nil)
;; (org-agenda-time-grid nil)))
;; (todo "DONE"
;; ((org-agenda-overriding-header "COMPLETED"))))
;; ((org-agenda-format-date "")
;; (org-agenda-start-with-clockreport-mode nil)))
;; '("fh" "Hotlist"
;; ((tags-todo "DEADLINE<\"<+0d>\""
;; ((org-agenda-overriding-header "OVERDUE")))
;; (tags-todo "DEADLINE>=\"<+0d>\"+DEADLINE<=\"<+1w>\""
;; ((org-agenda-overriding-header "DUE IN NEXT 7 DAYS")))
;; (tags-todo "DEADLINE=\"\"+FLAGGED|DEADLINE>\"<+1w>\"+FLAGGED"
;; ((org-agenda-overriding-header "FLAGGED"))))
;; ((org-agenda-todo-ignore-scheduled 'future)))
;; '("r" . "REVIEW...")
;; '("ra" . "All Tasks...")
;; '("rad" "All Tasks (grouped by Due Date)"
;; ((tags-todo "DEADLINE<\"<+0d>\""
;; ((org-agenda-overriding-header "OVERDUE")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))))
;; (tags-todo "DEADLINE=\"<+0d>\""
;; ((org-agenda-overriding-header "DUE TODAY")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))))
;; (tags-todo "DEADLINE=\"<+1d>\""
;; ((org-agenda-overriding-header "DUE TOMORROW")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))))
;; (tags-todo "DEADLINE>\"<+1d>\"+DEADLINE<=\"<+7d>\""
;; ((org-agenda-overriding-header "DUE WITHIN A WEEK")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))))
;; (tags-todo "DEADLINE>\"<+7d>\"+DEADLINE<=\"<+28d>\""
;; ((org-agenda-overriding-header "DUE WITHIN A MONTH")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))))
;; (tags-todo "DEADLINE>\"<+28d>\""
;; ((org-agenda-overriding-header "DUE LATER")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))) )
;; (tags-todo "TODO={WAIT}"
;; ((org-agenda-overriding-header "WAITING FOR")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'deadline))))
;; (todo ""
;; ((org-agenda-overriding-header "WAITING FOR")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'deadline)))))
;; ((org-agenda-sorting-strategy '(priority-down))
;; (org-agenda-write-buffer-name "All Tasks (grouped by Due Date)"))
;; "~/Documents/Org/all-tasks-by-due-date.pdf")
;; '("ra1" "All Tasks with a due date"
;; ((alltodo ""))
;; ((org-agenda-overriding-header "All Tasks (sorted by Due Date)")
;; (org-agenda-skip-function
;; '(org-agenda-skip-entry-if 'notdeadline))
;; (org-agenda-sorting-strategy '(deadline-up))))
;; '("rt" . "Timesheet...")
;; '("rtw" "Weekly Timesheet"
;; ((agenda ""))
;; (
;; ;; (org-agenda-format-date "")
;; (org-agenda-overriding-header "WEEKLY TIMESHEET")
;; (org-agenda-skip-function '(org-agenda-skip-entry-if 'timestamp))
;; (org-agenda-span 'week)
;; (org-agenda-start-on-weekday 1)
;; (org-agenda-start-with-clockreport-mode t)
;; (org-agenda-time-grid nil)))
;; '("rc" . "Calendar...")
;; '("rc7" "Events and appointments for 7 days"
;; ((agenda ""))
;; ((org-agenda-entry-types '(:timestamp :sexp))
;; ;; (org-agenda-overriding-header "Calendar for 7 days")
;; ;; (org-agenda-repeating-timestamp-show-all t)
;; (org-agenda-span 'week)
;; (org-agenda-format-date "\n%a %d")
;; ;; (org-agenda-date-weekend ... new face ...)
;; (org-agenda-time-grid nil)))
;; '("rw" "Weekly review"
;; ((tags "CATEGORY={@REFILE}&LEVEL<=2"
;; ((org-agenda-overriding-header "NEW TASKS")))
;; (agenda ""
;; ((org-agenda-clockreport-mode t)
;; (org-agenda-format-date
;; (concat "\n"
;; "%Y-%m-%d" " %a "
;; (make-string (window-width) ?_)))
;; (org-agenda-overriding-header "PAST WEEK")
;; (org-agenda-prefix-format " %?-11t %i %-12:c% s")
;; (org-agenda-show-log 'clockcheck)
;; (org-agenda-span 7)
;; (org-agenda-start-day "-1w")
;; (org-deadline-warning-days 0)))
;; (agenda ""
;; ((org-agenda-overriding-header "NEXT MONTH")
;; (org-agenda-span 'month)
;; (org-agenda-start-day "+0d")
;; (org-deadline-warning-days 0)))
;; (todo "PROJECT"
;; ((org-agenda-overriding-header "PROJECT LIST")))
;; (todo "DONE|PROJECTDONE"
;; ((org-agenda-overriding-header
;; "Candidates to be archived"))))))
;; (when (not noninteractive)
;; ;; When running in batch, don't setup windows.
;; (validate-setq
;; ;; Show agenda in current window.
;; org-agenda-window-setup 'current-window))
)
;; https://github.com/emacs-mirror/emacs/blob/master/lisp/org/org-habit.el
;; The habit tracking code for Org
(use-package org-habit
:ensure nil
:config
(validate-setq
;; Position the habit graph to the right.
org-habit-graph-column 50))
;; https://github.com/alphapapa/org-super-agenda
;; Supercharge your Org daily/weekly agenda by grouping items
(use-package org-super-agenda
:disabled
:config
(add-to-list
'org-agenda-custom-commands
'("u" "Super view"
((agenda "" ((org-super-agenda-groups
'((:name "Today"
:time-grid t)))))
(todo "" ((org-agenda-overriding-header "")
(org-super-agenda-groups
'((:name "Projects"
:children todo)
(:discard (:anything t)))))))))
(org-super-agenda-mode))
;; https://github.com/spegoraro/org-alert
;; System notifications of org agenda items
(use-package org-alert
:after alert
:config
(org-alert-enable))
;; https://github.com/Malabarba/org-agenda-property
;; Display org properties in the agenda buffer
(use-package org-agenda-property)
;; https://github.com/Fuco1/org-timeline
;; Add graphical view of agenda to agenda buffer
(use-package org-timeline
:disabled
:hook (org-agenda-finalize-hook . org-timeline-insert-timeline))
;; https://github.com/tkf/org-mode/blob/master/contrib/lisp/org-annotate-file.el
;; Annotate a file with org syntax
(use-package org-annotate-file
:disabled
:ensure org-plus-contrib
:defer
:init
(autoload 'org-annotate-file "org-annotate-file" nil t)
:bind-wrap
((:key :util :annotate-buffer) . user/org-annotate-file)
:config
(validate-setq
;; Annotations data store.
org-annotate-file-storage-file (path-join *user-org-data-directory*
"annotations.org")
;; Add link to current line number.
org-annotate-file-add-search t))
(provide 'modes/org)
;;; org.el ends here

73
lisp/modes/prog.el Normal file
View File

@@ -0,0 +1,73 @@
;;; prog.el --- setup shared defaults for programming modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--prog-mode-hook ()
"Programming mode hook."
(user--fundamental-mode-hook)
(when (user-flyspell-p)
;; Protect against missing dictionary.
(try-eval
;; Run spell-checker in programming mode.
(flyspell-prog-mode)))
;; Buttonize links.
;;(goto-address-prog-mode t)
;;(outline-minor-mode t)
(validate-setq
;; When using fill-paragraph or auto-fill-mode break lines at 80 characters by
;; default.
fill-column 120)
;; Try to enable completion system.
(cond
;; ((user/auto-complete-p) (auto-complete-mode t))
((user/company-mode-p) (company-mode t)))
;;; (Bindings) ;;;
(user/bind-key-local :code :comment (if (feature-p 'comment-dwim-2)
'comment-dwim-2
'comment-dwim)))
(use-package prog-mode
:ensure nil
:hook (prog-mode-hook . user--prog-mode-hook)
:config
;;; (Packages) ;;;
;; https://github.com/emacs-mirror/emacs/blob/master/lisp/progmodes/subword.el
;; Handling capitalized subwords in a nomenclature
(use-package subword
:disabled
:ensure nil
:diminish subword-mode)
;; https://github.com/remyferre/comment-dwim-2
;; A replacement for the emacs' built-in command `comment-dwim'
(use-package comment-dwim-2)
;; https://github.com/emacsorphanage/quickrun
;; Run command quickly. This packages is inspired quickrun.vim
(use-package quickrun
:bind-wrap
(:map prog-mode-map
((:key :code :eval-buffer) . quickrun)
((:key :code :eval-selection) . quickrun-region)))
;; https://github.com/vincekd/comment-tags
;; Emacs package to highlight and manage comment tags like TODO, BUG, FIXME, etc.
(use-package comment-tags
:diminish comment-tags-mode
:hook (prog-mode-hook . comment-tags-mode)
:config
(setq
comment-tags/keymap-prefix (user/get-key :nav :find-todos)))
;; https://github.com/ignacy/idle-highlight-in-visible-buffers-mode
;; An Emacs minor mode that highlights current word in all visible buffers
(use-package idle-highlight-in-visible-buffers-mode
:disabled
:hook (prog-mode-hook . idle-highlight-in-visible-buffers-mode)))
(provide 'modes/prog)
;;; prog.el ends here

163
lisp/modes/python.el Normal file
View File

@@ -0,0 +1,163 @@
;;; python.el --- initializes Python modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'lsp-pylsp)
(defun user--python-format-before-save ()
"Python cleanup and format before save buffer."
(lsp-format-buffer)
(delete-trailing-whitespace)
)
(defun user--python-mode-hook ()
"Python mode hook."
;; lsp python customization
(lsp-register-custom-settings
'(("pylsp.plugins.pyls_mypy.enabled" t t)
;; ("pylsp.plugins.flake8.maxLineLength" 120)
;; ("pylsp.plugins.pycodestyle.maxLineLength" 120)
("pylsp.plugins.yapf.enabled" t t)
("pylsp.plugins.pylint.enabled" t t)))
;; ("pyls.plugins.pyls_mypy.live_mode" nil t)
;; ("pyls.plugins.pyls_black.enabled" t t)
;; ("pyls.plugins.pyls_isort.enabled" t t)
;; ("pyls.plugins.flake8.enabled" t t)))
(setq lsp-pylsp-plugins-flake8-max-line-length 120)
(setq lsp-pylsp-plugins-pycodestyle-max-line-length 120)
;; Enable virtualenv support.
(when(feature-p 'pyvenv)
(pyvenv-mode t))
(when(feature-p 'anaconda-mode)
(anaconda-mode t))
;; Enable smart parenthesis handling.
(user/smartparens-enable)
;; Separate camel-case into separate words
(subword-mode t)
;; ElDoc shows function documentation as you type
(eldoc-mode t)
;; Select pylint for ckecing
;; (setq flycheck-checker nil)
;; (setq-default flycheck-disabled-checkers '(lsp))
;; (flycheck-add-mode 'python-flake8 'python-mode)
;; (flycheck-select-checker 'python-pycheckers)
;; (flycheck-add-next-checker 'lsp 'python-pycheckers)
;; (setq-local lsp-pylsp-plugins-pylint-enabled nil)
;; (with-eval-after-load "lsp-mode"
;; (add-to-list 'lsp-disabled-clients 'pyls)
;; (add-to-list 'lsp-enabled-clients 'pylsp))
;; (Bindings) ;;
;; (when(feature-p 'nose)
;; (user/bind-key-local: code: test 'nosetests-all))
;; (when(feature-p 'pyvenv)
;; (user/bind-key-local: code: virtual 'pyvenv-workon))
;; (when(feature-p 'lsp-pyright)
;; (require 'lsp-pyright)))
)
(use-package python
:if (executable-find "python")
:defer
:mode ("SCon\(struct\|script\)$" . python-mode)
:interpreter ("python[0-9.]*" . python-mode)
:hook
(python-mode-hook . lsp)
(python-mode-hook . user--python-mode-hook)
(python-mode-hook . (lambda ()
(add-hook 'before-save-hook #'user--python-format-before-save nil t)))
:config
(validate-setq
;; Don't try to guess the indentation.
python-indent-guess-indent-offset nil)
(with-executable 'ipython3
(validate-setq
;; Set IPython as default interpreter.
python-shell-interpreter "ipython3"
python-shell-interpreter-args ""
python-shell-prompt-regexp "In \\[[0-9]+\\]: "
python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
python-shell-completion-setup-code "from IPython.core.completerlib import module_completion"
python-shell-completion-module-string-code "';'.join(module_completion('''%s'''))\n"
python-shell-completion-string-code "';'.join(get_ipython().Completer.all_completions('''%s'''))\n"))
(with-executable 'bpython
(defun user/bpython-term()
"Launch or switch to a `bpython' buffer."
(interactive)
(if (not (get-buffer "*bpython*"))
(progn
(ansi-term "bpython" "bpython"))
(switch-to-buffer "*bpython*"))))
;; (Packages) ;;
;; https://github.com/pythonic-emacs/anaconda-mode
;; Code navigation, documentation lookup and completion for Python.
(use-package anaconda-mode)
;; https://github.com/tsgates/pylookup
;; Emacs mode for searching python documents with convenience
(use-package pylookup
:disabled
:quelpa(pylookup
:fetcher github
:repo "tsgates/pylookup"))
;; https://github.com/syl20bnr/nose.el
;; This gives a bunch of functions that handle running nosetests on a particular buffer or part of a buffer.
(use-package nose
:disabled)
;; https://github.com/tkf/emacs-python-environment
;; Python virtualenv API for Emacs Lisp
(use-package python-environment
:disabled
:config
(validate-setq
;; Locate of Python environment store.
python-environment-directory(path-join *user-cache-directory*
"python-environment")))
;; https://github.com/pwalsh/pipenv.el
;; A Pipenv porcelain inside Emacs.
(use-package pipenv
:disabled
:if (executable-find "pipenv")
:hook(python-mode-hook . pipenv-mode))
;; https://github.com/msherry/flycheck-pycheckers
;; Multiple syntax checker for Python in Emacs, using Flycheck
(use-package flycheck-pycheckers
:disabled
:after flycheck
:hook (flycheck-mode-hook . flycheck-pycheckers-setup)
:config (setq flycheck-pycheckers-checkers (remove 'mypy2 flycheck-pycheckers-checkers))
)
;; https://github.com/chocoelho/flycheck-prospector
;; flycheck support for prospector
(use-package flycheck-prospector
:disabled
:if (executable-find "prospector")
:hook(flycheck-mode-hook . flycheck-prospector-setup))
;; https://github.com/jgosmann/pylint-venv
;; Make pylint respect virtualenvs.
(use-package pyvenv
:ensure t
:config
(pyvenv-mode 1))
;; https://github.com/emacsorphanage/helm-pydoc
;; helm-pydoc.el is pydoc helm interface
(use-package helm-pydoc
:pin "MELPA"))
(provide 'modes/python)
;;; python.el ends here

74
lisp/modes/shell.el Normal file
View File

@@ -0,0 +1,74 @@
;;; shell.el --- initializes shell modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--sh-mode-hook ()
"Initialize mode for shell script editing."
(validate-setq
;; Indent with four spaces.
sh-basic-offset 4
sh-indentation 4))
(defun user--shell-mode-common-hook ()
"Shell mode common hook."
(with-feature 'ansi-color
;; Enable ANSI colors for comint.
(ansi-color-for-comint-mode-on))
(with-feature 'shelldoc
(shelldoc-minor-mode-on)))
(defun user--shell-mode-hook ()
"Initialize mode for interactive shell."
(user--shell-mode-common-hook)
(validate-setq
;; Set up to use Bash with input echoing.
explicit-shell-file-name "bash"
explicit-bash-args '("-c" "export EMACS=; stty echo; bash")
comint-process-echoes t))
(use-package shell
:defer
:hook ((sh-mode-hook . user--sh-mode-hook)
(shell-mode-hook . user--shell-mode-hook))
:config
;;; (Packages) ;;;
;; https://github.com/wilkystyle/lsp-sh
;; Bash support for lsp-mode using Mads Hartmann's bash-language-server
(use-package lsp-sh
:if (executable-find "bash-language-server")
:hook (sh-mode-hook . lsp-sh-enable))
;; https://github.com/szermatt/emacs-bash-completion
;; Add programmable bash completion to Emacs shell-mode
(use-package bash-completion)
;; https://github.com/Alexander-Miller/company-shell
;; Company mode completion backends for your shell scripting
(use-package company-shell
:after (company)
:config
(add-to-list 'company-backends '(company-shell company-shell-env)))
;; https://github.com/charlesdaniels/shelldoc
;; A tool for generating ReST documentation from shell scripts
(use-package shelldoc
:disabled)
;; (use-package shell-command)
;; https://github.com/cuonglm/flycheck-checkbashisms
;; Flycheck linter for checkbashisms
(use-package flycheck-checkbashisms
:if (executable-find "checkbashisms")
:config
(flycheck-checkbashisms-setup))
;; https://github.com/alexmurray/flycheck-bashate
;; Integrate bashate with flycheck to automatically check the style of your bash scripts on the fly.
(use-package flycheck-bashate
:disabled
:if (executable-find "bashate")
:config
(flycheck-bashate-setup)))
(provide 'modes/shell)
;;; shell.el ends here

69
lisp/modes/text.el Normal file
View File

@@ -0,0 +1,69 @@
;;; text.el --- text mode support -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--text-mode-hook ()
"Text mode hook."
(user--fundamental-mode-hook)
(user/smartparens-enable)
(rainbow-delimiters-mode-disable)
(validate-setq
;; Colons are followed by two spaces.
colon-double-space t
;; Sentences end after two spaces.
sentence-end-double-space t
;; When using fill-paragraph or auto-fill-mode break lines at 120 characters
;; by default.
fill-column 120
;; Indent using spaces.
indent-tabs-mode nil)
(when (user-flyspell-p)
;; Protect against missing dictionary.
(try-eval
;; Run spell-checker in programming mode.
(flyspell-prog-mode)))
(when (and (feature-p 'flycheck-vale)
(executable-find "vale"))
(flycheck-vale-setup))
;; TODO
;; (with-feature 'pandoc-mode
;; (pandoc-mode t))
;; Nicely wrap long lines.
(visual-line-mode t)
;;; (Bindings) ;;;
(user/bind-key-local :code :fill-paragraph 'fill-paragraph))
(use-package text-mode
:ensure nil
:defer
:hook (text-mode-hook . user--text-mode-hook)
:config
;; https://github.com/abingham/flycheck-vale
;; Flycheck integration for the vale natural language linter
(use-package flycheck-vale
:if (executable-find "vale")
:config
;; TODO
;; (add-to-list 'flycheck-vale-modes 'org-mode)
)
;; https://github.com/zzkt/smog
;; Analyse the writing style, word use and readability of prose in Emacs.
(use-package smog
:if (executable-find "style"))
;; https://github.com/emacs-straight/ftable
;; This package provides some convenient commands for filling a table.
(use-package ftable))
(provide 'modes/text)
;;; text.el ends here

40
lisp/modes/typescript.el Normal file
View File

@@ -0,0 +1,40 @@
;;; typescript.el --- Initializes TypeScript mode -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun typescript-use-eslint-from-node-modules ()
"Use local eslint from node_modules before global."
(let* ((root (locate-dominating-file
(or (buffer-file-name) default-directory)
"node_modules"))
(eslint (and root
(expand-file-name "node_modules/eslint/bin/eslint.js"
root))))
(when (and eslint (file-executable-p eslint))
(setq-local flycheck-javascript-eslint-executable eslint))))
(defun user--tide-mode-hook ()
"."
(interactive)
(message "user--tide-mode-hook BEG")
(comment-tags-mode t)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(company-mode +1)
(typescript-use-eslint-from-node-modules)
(message "user--tide-mode-hook END")
)
(use-package tide
:ensure t
:after (typescript-mode company flycheck)
:hook (
(typescript-mode . user--tide-mode-hook)
(typescript-mode . tide-hl-identifier-mode)
(before-save . tide-format-before-save))
:config (setq tide-completion-enable-autoimport-suggestions t))
(provide 'modes/typescript)
;; typescript.el ends here

51
lisp/modes/vuejs.el Normal file
View File

@@ -0,0 +1,51 @@
;;; markdown --- initializes VueJs modes -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--web-html-hook ()
"."
(message "user--web-html-hook BEG !!!")
(message "user--web-html-hook END !!!")
)
(defun user--web-vue-hook ()
"."
(message "user--web-vue-hook BEG !!!!")
(user--tide-mode-hook)
(flycheck-add-mode 'javascript-eslint 'web-mode)
(flycheck-select-checker 'javascript-eslint)
(add-to-list (make-local-variable 'company-backends)
'(comany-tide company-web-html company-css company-files))
(message "user--web-vue-hook END !!!!")
)
(defun user--web-format-before-save()
"Python cleanup and format before save buffer."
(delete-trailing-whitespace)
)
(use-package web-mode
:ensure t
:mode ("\\.html\\'" "\\.vue\\'")
:hook ((web-mode-hook . (lambda()
(cond ((equal web-mode-content-type "html")
(user--web-html-hook))
((member web-mode-content-type '("vue"))
(user--web-vue-hook))
)))
(web-mode-hook . (lambda ()
(add-hook 'before-save-hook #'user--web-format-before-save nil t))))
:config
(setq web-mode-markup-indent-offset 4)
(setq web-mode-css-indent-offset 4)
(setq web-mode-code-indent-offset 4)
(setq web-mode-enable-current-element-highlight t)
(setq web-mode-enable-css-colorization t)
(setq web-mode-content-types-alist '(("vue" . "\\.vue\\'")))
;;
;;
(use-package company-web
:ensure t))
(provide 'modes/vuejs)
;; vuejs.el ends here

97
lisp/modes/whitespace.el Normal file
View File

@@ -0,0 +1,97 @@
;;; whitespace.el --- whitespace mode support -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defvar user/whitespace-mode-suppressed nil
"Tracks whether `whitespace-mode' is currently being suppressed.")
(make-variable-buffer-local 'user/prev-whitespace-mode-suppressed)
(defun user--whitespace-mode-hook ()
"Whitespace mode hook."
;;; (Bindings) ;;;
(user/bind-key-local :code :whitespace-auto-cleanup
'user/toggle-whitespace-auto-cleanup))
(defun user/whitespace-mode-suppress (suppress)
"If SUPPRESS is non-nil, disable `whitespace-mode' in current mode."
(when (boundp 'whitespace-mode)
(if suppress
(when (and whitespace-mode (not user/whitespace-mode-suppressed))
(setq user/whitespace-mode-suppressed t)
(whitespace-mode -1))
(when user/whitespace-mode-suppressed
(setq user/whitespace-mode-suppressed nil)
(whitespace-mode 1)))))
(defun user/whitespace-disable-style (styles)
"Disable STYLES in current mode."
(when (boundp 'whitespace-style)
(let ((options (cl-intersection styles whitespace-style)))
(when (and (boundp 'global-whitespace-mode) global-whitespace-mode)
(global-whitespace-toggle-options options))
(when (and (boundp 'whitespace-mode) whitespace-mode)
(whitespace-toggle-options options)))))
(defun user/toggle-whitespace-auto-cleanup ()
"Toggle the state of automatic whitespace cleanup in current buffer."
(interactive)
(setq whitespace-action (user/toggle-element whitespace-action 'auto-cleanup))
(message
(concat "Whitespace cleanup "
(if (member 'auto-cleanup whitespace-action) "enabled" "disabled"))))
;; https://github.com/emacs-mirror/emacs/blob/master/lisp/whitespace.el
;; minor mode to visualize TAB, (HARD) SPACE, NEWLINE
(use-package whitespace
:diminish whitespace-mode
:init
(add-hook 'whitespace-mode-hook 'user--whitespace-mode-hook)
:config
(validate-setq
;; Maximum allowed line length.
whitespace-line-column 120
;; Cleanup whitespace errors on save.
whitespace-action '(auto-cleanup)
;; Kinds of whitespace to visualize.
whitespace-style
'(;; Visualize using faces.
face
;; Mark any tabs.
tab-mark
;; Empty lines at beginning or end of buffer.
empty
;; Trailing whitespace.
trailing
;; Lines that extend beyond `whitespace-line-column.'
lines
;; Wrong kind of indentation (tab when spaces and vice versa.)
indentation
;; Mixture of space and tab on the same line.
space-before-tab space-after-tab))
(when (eq default-terminal-coding-system 'utf-8)
;; Don't use validate-setq due to :inline not being supported.
(setq
;; Special characters for displaying whitespace.
whitespace-display-mappings
'(;; 32 SPACE, 183 MIDDLE DOT 「·」, 46 FULL STOP 「.」
(space-mark ?\s [183] [46])
;; 10 LINE FEED, 9166 RETURN SYMBOL 「⏎」, 36 DOLLAR SIGN 「$」
(newline-mark ?\n [9166 10] [36 10])
;; 9 TAB, 9655 WHITE RIGHT-POINTING TRIANGLE 「▷」, 92 9 CHARACTER TABULATION 「\t」
(tab-mark ?\t [9655 9] [92 9]))))
(defadvice whitespace-cleanup (around whitespace-cleanup-indent-tab
activate)
"Fix whitespace-cleanup indent-tabs-mode bug."
(let ((whitespace-indent-tabs-mode indent-tabs-mode)
(whitespace-tab-width tab-width))
ad-do-it)))
(provide 'modes/whitespace)
;;; whitespace.el ends here

16
lisp/utilities/abbrev.el Normal file
View File

@@ -0,0 +1,16 @@
;;; abbrev.el --- Configure Emacs abbreviations -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;;; Doc: https://www.emacswiki.org/emacs/AbbrevMode
(use-package abbrev
:disabled
:ensure nil
:diminish abbrev-mode
:config
(validate-setq
abbrev-file-name (path-join *user-data-directory* "abbrev_defs")))
(provide 'utilities/abbrev)
;;; abbrev.el ends here

32
lisp/utilities/ag.el Normal file
View File

@@ -0,0 +1,32 @@
;;; ag.el --- interface to The Silver Searcher -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/emacsorphanage/helm-ag
(with-executable 'ag
(when (feature-p 'helm)
(use-package helm-ag
:defer
:config
(validate-setq
;; Insert word at point as search term.
helm-ag-insert-at-point 'word)))
(use-package ag
:defer
:init
(if (and (feature-p 'projectile)
(fboundp 'projectile-ag))
(global-set-key [remap find-grep] 'projectile-ag)
(global-set-key [remap find-grep] 'ag))
:config
(validate-setq
ag-project-root-function
'(lambda ()
(with-project project (path-buffer-abs)
(user/proj-root project))))
;; Search inside compressed files.
(add-to-list 'ag-arguments "--search-zip")))
(provide 'utilities/ag)
;;; ag.el ends here

26
lisp/utilities/alert.el Normal file
View File

@@ -0,0 +1,26 @@
;;; alert.el --- Emacs notifications. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/jwiegley/alert
(defun user/alert-style ()
"Get the preferred alert style."
(cond
((eq system-type 'darwin) 'growl)
((executable-find "notify-send") 'libnotify)
((executable-find "dbus-send") 'notifications)
(t 'mode-line)))
(use-package alert
:defer
:config
;; Undiagnosed issue with validate-setq.
(setq
;; Send alerts to alert buffer.
alert-default-style (user/alert-style))
(validate-setq
;; Disable log.
alert-log-messages nil))
(provide 'utilities/alert)
;;; alert.el ends here

View File

@@ -0,0 +1,28 @@
;;; auth-source.el --- Configure Emacs authentication sources -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/emacs-mirror/emacs/blob/master/lisp/auth-source.el
;;; Doc: https://www.gnu.org/software/emacs/manual/html_mono/auth.html
(use-package auth-source
:disabled
:ensure nil
:defer
:config
(validate-setq
auth-sources
`(,(path-join *user-data-directory* "authinfo.gpg")
,(path-join *user-data-directory* "authinfo")))
(dolist (source auth-sources)
(when (file-exists-p source)
(set-file-modes source #o0600)))
(when (eq system-type 'darwin)
(add-many-to-list 'auth-sources
'macos-keychain-internet
'macos-keychain-generic)))
(provide 'utilities/auth-source)
;;; auth-source.el ends here

View File

@@ -0,0 +1,98 @@
;;; bookmarks.el --- Bookmarks in Emacs -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;;; Doc: https://www.emacswiki.org/emacs/VisibleBookmarks
(defconst *visible-bookmarks-data-file* (path-join *user-data-directory*
"visible-bookmarks"))
(defconst *bookmark+-data-file* (path-join *user-data-directory* "bookmarks"))
(defconst *bookmark+-menu-state-file* (path-join *user-cache-directory*
"bookmark-menu-state.el"))
(defun bookmark--local-directory-bookmarks-to-zsh ()
"Store Emacs bookmarks in ZSH bookmarks file."
(interactive)
(when (and (require 'tramp nil t)
(require 'bookmark nil t))
(set-buffer (find-file-noselect "~/.zsh_bookmarks" t t))
(delete-region (point-min) (point-max))
(insert "# -*- mode:sh -*-\n")
(let (collect-names)
(mapc (lambda (item)
(let ((name (replace-regexp-in-string "-" "_" (car item)))
(file (cdr (assoc 'filename
(if (cddr item) item (cadr item))))))
(when (and (not (tramp-tramp-file-p file))
(file-directory-p file))
(setq collect-names (cons (concat "~" name) collect-names))
(insert (format "%s=\"%s\"\n" name (expand-file-name file))))))
bookmark-alist)
(insert ": " (mapconcat 'identity collect-names " ") "\n"))
(let ((backup-inhibited t)) (save-buffer))
(kill-buffer (current-buffer))))
(use-package bm
:defer
:init
(user/bind-key-global :code :bookmark-toggle 'bm-toggle)
(user/bind-key-global :code :bookmark-next 'bm-next)
(user/bind-key-global :code :bookmark-prev 'bm-previous)
:config
(validate-setq
;; Persistent bookmarks.
bm-repository-file *visible-bookmarks-data-file*
bm-buffer-persistence t)
;; Restore bookmarks on file find.
(add-hook 'find-file-hooks 'bm-buffer-restore)
;; Save bookmarks when killing buffer.
(add-hook 'kill-buffer-hook 'bm-buffer-save)
;; Save all bookmarks on exit.
(add-hook 'kill-emacs-hook 'bm-save)
;; Update repository when saving file.
(add-hook 'after-save-hook 'bm-buffer-save)
;; Restore bookmarks when buffer is reverted.
(add-hook 'after-revert-hook 'bm-buffer-restore))
(use-package bookmark
:disabled
:defer
:init
;; Bind bookmarks to C-c b
(global-set-key (user/get-key :code :bookmark-prefix) 'bookmark-map)
:config
(validate-setq
;; Enable versioned backups.
bookmark-version-control t
bookmark-save-flag 1
;; Put the repository in the data directory.
bookmark-default-file *bookmark+-data-file*)
;; Share Emacs directory bookmarks with ZSH.
(defadvice bookmark-write-file
(after local-directory-bookmarks-to-zsh-advice activate)
(bookmark--local-directory-bookmarks-to-zsh))
(use-package bookmark+
:disabled
:config
(validate-setq
;; Save bookmarks after ten updates.
bmkp-count-multi-mods-as-one-flag t)
;;; (Bindings) ;;;
(define-key bookmark-map (kbd "l") 'bookmark-jump)
(define-key bookmark-map (kbd "e") 'bmkp-edit-bookmark-record)
(define-key bookmark-map (kbd "t") 'bmkp-add-tags)
(use-package bookmark+-bmu
:ensure bookmark+
:config
(validate-setq
;; Put the menu state in the cache directory.
bmkp-bmenu-state-file *bookmark+-menu-state-file*))))
(provide 'utilities/bookmarks)
;;; bookmarks.el ends here

74
lisp/utilities/compile.el Normal file
View File

@@ -0,0 +1,74 @@
;;; compile.el --- sets up Emacs compile support -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--compilation-mode-hook ()
"Compilation mode hook.")
(defun user--compilation-filter-hook ()
"Hook for filtering compilation output."
;; Temporarily make buffer writable.
(let ((inhibit-read-only t))
;; Colorize compilation output.
(ansi-color-apply-on-region (point-min) (point-max))))
(defun user/compile ()
"Compile current context."
(interactive)
(let ((ede-proj (user/proj-from-path user/ede-proj (path-abs-buffer))))
(cond
(ede-proj (user/proj-build ede-proj))
((feature-p 'flex-compile) (call-interactively 'flex-compile-compile))
((fboundp 'mode-compile) (call-interactively 'mode-compile))
(t (call-interactively 'compile)))))
;; https://www.emacswiki.org/emacs/CompileCommand
(use-package compile
:defer
:init
(user/bind-key-global :code :compile 'user/compile)
:hook ((compilation-mode-hook . user--compilation-mode-hook)
(compilation-filter-hook . user--compilation-filter-hook))
:config
(validate-setq
;; Prevent input in compilation buffer.
compilation-disable-input nil
;; Automatically scroll output.
compilation-scroll-output t)
(with-eval-after-load 'popwin
(add-to-list
'popwin:special-display-config
;; Don't select compilation window when shown
'(compilation-mode :height 20 :dedicated t)))
;; https://github.com/plandes/flex-compile
(use-package flex-compile
:disabled
:pin "MELPA")
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation-Mode.html
(use-package mode-compile
:defer
:config
;; Ensure byte-run has been loaded or mode-compile will override
;; `define-obsolete-variable-alias'.
(when (load "byte-run.el" nil :noerror)
(validate-setq
;; Set a sane compilation frame name.
mode-compile-other-frame-name "*compilation*"
;; Run make with low priority and use multiple processes.
mode-compile-make-program "nice make"
mode-compile-default-make-options "-k -j"
;; Save the current buffer on compilation.
mode-compile-always-save-buffer-p t)
(with-executable 'clang
(add-to-list 'cc-compilers-list "clang")
(add-to-list 'c++-compilers-list "clang++")))))
(provide 'utilities/compile)
;;; compile.el ends here

View File

@@ -0,0 +1,11 @@
;;; coverage.el --- Code coverage tools -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/AdamNiederer/cov
;; TODO: Update to use cov for all modes
;; TODO: Add pycoverage management
(use-package cov
:defer)
(provide 'utilities/coverage)
;;; coverage.el ends here

13
lisp/utilities/ctable.el Normal file
View File

@@ -0,0 +1,13 @@
;;; ctable --- Table component for Emacs -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/kiwanami/emacs-ctable
(use-package ctable
:disabled
:defer
:init
(autoload 'make-ctbl:cmodel "ctable"))
(provide 'utilities/ctable)
;;; ctable.el ends here

26
lisp/utilities/dap.el Normal file
View File

@@ -0,0 +1,26 @@
;;; dap.el --- Debug adapter protocol. -*- lexical-binding: t; -*-
;;; Commentary: Emacs client/library for Debug Adapter Protocol is a wire protocol for communication between client and Debug Server.
;;; Code: https://github.com/emacs-lsp/dap-mode
(use-package dap-mode
:disabled
:pin "MELPA"
:hook ((lsp-mode-hook . dap-mode)
(lsp-mode-hook . dap-ui-mode))
:bind-wrap
(:map lsp-mode-map
((:key :debug :break) . dap-breakpoint-toggle)
((:key :debug :step) . dap-step-in)
((:key :debug :next) . dap-next)
((:key :debug :run) . dap-debug)
((:key :debug :continue) . dap-continue)
((:key :debug :show-value) . dap-ui-inspect-thing-at-point))
:config
(validate-setq
;; Location of persistent breakpoints.
dap-breakpoints-file (path-join *user-cache-directory* "dap-breakpoints")))
(provide 'utilities/dap)
;;; dap.el ends here

12
lisp/utilities/dash.el Normal file
View File

@@ -0,0 +1,12 @@
;;; dash.el --- Dash documentation reading -*- lexical-binding: t; -*-
;;; Commentary: This package provides an elisp interface to query and show documenation using Dash docsets.
;;; Code: https://github.com/dash-docs-el/dash-docs
(use-package dash-docs
:if (executable-find "sqlite3")
:bind-wrap
((:key :doc :reference) . helm-dash-at-point))
(provide 'utilities/dash)
;;; dash.el ends here

88
lisp/utilities/dired.el Normal file
View File

@@ -0,0 +1,88 @@
;;; dired.el --- Configuration for dired -*- lexical-binding: t; -*-
;;; Commentary: Dired is the main mode for Emacs file-manager operations. The name “Dired” stands for “directory editor”.
;;; Code:
;;; Docs: https://www.emacswiki.org/emacs/DiredMode
(defun user--dired-mode-hook ()
"Mode hook for dired."
(with-feature 'async
;; Asynchronous operations in dired.
(dired-async-mode t)))
(use-package dired
:ensure nil
:defer
:config
(validate-setq
;; Always copy recursively without asking.
dired-recursive-copies 'always
;; Ask once when recursively deleting a directory.
dired-recursive-deletes 'top
;; Allow dired to be smart about operations.
dired-dwim-target t
;; Default flags for ls.
dired-listing-switches "-alh")
;;; (Packages) ;;;
;; https://github.com/purcell/diredfl
;; Extra font lock rules for a more colourful dired
(use-package diredfl
:disabled)
;; https://github.com/emacsorphanage/dired-k
;; highlights dired buffer like k.
(use-package dired-k
:disabled)
;; https://github.com/clemera/dired-git-info
;; This Emacs packages provides a minor mode which shows git information inside the dired buffer
(use-package dired-git-info
:disabled
:bind (:map dired-mode-map
(")" . dired-git-info-mode)))
;; https://github.com/jwiegley/emacs-async
;; async.el is a module for doing asynchronous processing in Emacs.
(use-package async)
;; https://github.com/juan-leon/dired-efap
;; dired-efap.el allows the user to edit the filename at point, by hitting a key (like f2) or double-clicking it.
(use-package dired-efap
:config
;;; (Bindings) ;;;
(define-key dired-mode-map [R] 'dired-efap)
(when (display-graphic-p)
(define-key dired-mode-map [down-mouse-1] 'dired-efap-click))
(with-eval-after-load 'dired
;; Load dired-efap when dired is loaded.
(require 'dired-efap)))
;; https://github.com/jtbm37/all-the-icons-dired
;; This adds dired support to all-the-icons.
(use-package all-the-icons-dired
:if window-system)
;; https://github.com/stsquad/dired-rsync
;; This package adds a single command dired-rsync which allows the user to copy marked files in a dired buffer via rsync.
(use-package dired-rsync
:disabled
:if (executable-find "rsync")
:bind (:map dired-mode-map
("C-c C-r" . dired-rsync)))
;; https://github.com/vifon/dired-recent.el
;; A history of paths visited with Emacs dired.
(use-package dired-recent
:disabled
:config
(validate-setq
;; Path to history database.
dired-recent-directories-file (path-join *user-cache-directory* "dired-history"))
(dired-recent-mode t))
;;; (Bindings) ;;;
;; Do not open new buffers when going down or up a directory.
(define-key dired-mode-map (kbd "<return>") 'dired-find-alternate-file)
(define-key dired-mode-map (kbd "^") (lambda ()
(interactive)
(find-alternate-file "..")))
(when (display-graphic-p)
(define-key dired-mode-map [double-mouse-1] 'dired-find-file)))
(provide 'utilities/dired)
;;; dired.el ends here

24
lisp/utilities/direx.el Normal file
View File

@@ -0,0 +1,24 @@
;;; direx.el --- a simple directory explorer -*- lexical-binding: t; -*-
;;; Commentary: direx.el is a simple directory explorer. It also works as a generic tree explore library.
;;; Code: https://github.com/emacsorphanage/direx
(use-package direx
:defer
:init
(user/bind-key-global :basic :open-file-context
'direx-project:jump-to-project-root-other-window)
:config
(validate-setq
;; Use the functionality from utilities/project to locate project root
direx-project:project-root-predicate-functions
'((lambda (path)
(with-project-root project-root path
(and path (equal (file-truename path) (file-truename project-root)))))))
(with-eval-after-load 'popwin
(push '(direx:direx-mode :position left :width 30 :dedicated t)
popwin:special-display-config)))
(provide 'utilities/direx)
;;; direx.el ends here

17
lisp/utilities/docker.el Normal file
View File

@@ -0,0 +1,17 @@
;;; docker.el --- Configure Emacs docker support -*- lexical-binding: t; -*-
;;; Commentary : Emacs integration for Docker!
;;; Code: https://github.com/Silex/docker.el
(use-package docker
:disabled
:if (executable-find "docker")
:diminish docker-mode
:bind-wrap ((:key :util :docker) . docker)
:config
;; https://github.com/emacs-pe/docker-tramp.el
;; docker-tramp.el offers a TRAMP method for Docker containers.
(use-package docker-tramp))
(provide 'utilities/docker)
;;; docker.el ends here

92
lisp/utilities/ecb.el Normal file
View File

@@ -0,0 +1,92 @@
;;; ecb --- Emacs Code Browser -*- lexical-binding: t; -*-
;;; Commentary: Emacs Code Browser
;;; Code: https://github.com/ecb-home/ecb
(defvar user/ecb-active nil "Current state of ECB.")
(defun user--ecb-activate-hook ()
"ECB activation hook."
(setq user/ecb-active t)
;; Popwin conflicts with ECB.
(popwin-mode -1)
;; Close compile window if open
(when (ecb-compile-window-live-p)
(ecb-toggle-compile-window))
;;; (Bindings) ;;;
(user/bind-key-local :basic :zoom 'ecb-toggle-ecb-windows)
(user/bind-key-local :nav :context 'ecb-goto-window-edit1)
(user/bind-key-local :basic :open-file-context 'ecb-goto-window-directories)
(user/bind-key-local :nav :history 'ecb-goto-window-history)
(user/bind-key-local :nav :functions/toc 'ecb-goto-window-methods)
(user/bind-key-local :code :compilation-result 'user/ecb-toggle-compile-window))
(defun user--ecb-deactivate-hook ()
"ECB deactivation hook."
(setq user/ecb-active nil)
(popwin-mode t))
(defun user/ecb-toggle-active ()
"Toggle ECB state."
(interactive)
(if user/ecb-active
(ecb-deactivate)
(ecb-activate)))
(defun user/ecb-toggle-compile-window ()
"Toggle the presence of the ECB compilation window."
(interactive)
(if (and (ecb-compile-window-live-p)
(not (ecb-point-in-compile-window)))
(ecb-goto-window-compilation)
(progn
(ecb-toggle-compile-window)
(when (ecb-compile-window-live-p)
(ecb-goto-window-compilation)))))
(when (version<= emacs-version "24.4")
(use-package ecb
:defer
:init
(add-hook 'ecb-activate-hook 'user--ecb-activate-hook)
(add-hook 'ecb-deactivate-hook 'user--ecb-deactivate-hook)
(user/bind-key-global :util :ecb-toggle 'user/ecb-toggle-active)
:config
;; ECB version checking code is very old so that it thinks that the latest
;; CEDET/Emacs is not new enough when in fact it is years newer than the
;; latest version that it is aware of. So simply bypass the version check.
(validate-setq
ecb-version-check nil
ecb-tip-of-the-day nil
;; ECB layout.
ecb-layout-name "left6"
ecb-layout-window-sizes '(("left6"
(ecb-directories-buffer-name 0.17 . 0.41)
(ecb-sources-buffer-name 0.17 . 0.21)
(ecb-methods-buffer-name 0.17 . 0.41)
(ecb-history-buffer-name 0.17 . 0.35)))
ecb-show-sources-in-directories-buffer 'always
ecb-compile-window-height 12)
(defadvice ecb-check-requirements (around no-version-check activate compile)
"AROUND NO-VERSION-CHECK ACTIVATE COMPILE"
(if (or (< emacs-major-version 23)
(and (= emacs-major-version 23)
(< emacs-minor-version 3)))
ad-do-it))
(when (display-graphic-p)
(with-eval-after-load 'ecb-face
;; Use a slightly smaller face for the ECB tree-buffers.
(set-face-attribute 'ecb-default-general-face nil :height 0.8)))))
(provide 'utilities/ecb)
;;; ecb.el ends here

85
lisp/utilities/ediff.el Normal file
View File

@@ -0,0 +1,85 @@
;;; ediff.el --- Configuration for ediff -*- lexical-binding: t; -*-
;;; Commentary: A comprehensive visual interface to Unix diff and patch utilities
;;; Code:
;;; Doc: https://www.gnu.org/software/emacs/manual/html_mono/ediff.html
(eval-when-compile
(require 'cl))
(defun user--ediff-mode-hook ()
"Ediff mode hook."
(setq
;; Don't wrap long lines.
truncate-lines t))
(defun user--ediff-startup-hook ()
"Ediff startup hook."
(validate-setq
;; Split window differently depending on frame width.
ediff-split-window-function (if (> (frame-width) (* 2 80))
'split-window-horizontally
'split-window-vertically))
;; Go to the first difference on startup.
(ediff-next-difference))
(defun user/ediff-mergetool ()
"Launch ediff as mergetool."
(defun ediff-write-merge-buffer ()
"Write merge buffer to file."
(let ((file ediff-merge-store-file))
(set-buffer ediff-buffer-C)
(write-region (point-min) (point-max) file)
(message "Merge buffer saved in: %s" file)
(set-buffer-modified-p nil)
(sit-for 1)))
(validate-setq
ediff-quit-hook 'kill-emacs
ediff-quit-merge-hook 'ediff-write-merge-buffer)
(let ((local (pop command-line-args-left))
(remote (pop command-line-args-left))
(base (pop command-line-args-left))
(merged (pop command-line-args-left)))
(lexical-let (;; Show only conflicts.
(ediff-show-clashes-only t))
(ediff-merge-files-with-ancestor local remote base nil merged))))
(defun user/ediff-difftool ()
"Launch ediff as difftool."
(let ((local (pop command-line-args-left))
(remote (pop command-line-args-left)))
(ediff local remote)))
(use-package ediff
:defer
:init
;; Go to first difference on start.
(add-hook 'ediff-startup-hook 'user--ediff-startup-hook)
:config
(validate-setq
;; Ignore changes in whitespace.
ediff-diff-options "-w"
ediff-ignore-similar-regions t)
(user/bind-key-global :util :diff 'ediff)
;; window manipulation utilities
(use-package ediff-wind
:ensure nil
:config
(validate-setq
;; Don't create a separate frame for ediff.
ediff-window-setup-function 'ediff-setup-windows-plain))
;; https://github.com/fourier/ztree
;; Ztree is a project dedicated to implementation of several text-tree applications
(use-package ztree))
(provide 'utilities/ediff)
;;; ediff.el ends here

14
lisp/utilities/eldoc.el Normal file
View File

@@ -0,0 +1,14 @@
;;; eldoc.el --- Show docstrings in echo area -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/eldoc.el
(use-package eldoc
:diminish eldoc-mode
:config
(use-package eldoc-eval
:config
(eldoc-in-minibuffer-mode t)))
(provide 'utilities/eldoc)
;;; eldoc.el ends here

View File

@@ -0,0 +1,11 @@
;;; emacs-everywhere.el --- Integrate Emacs with any application -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/tecosaur/emacs-everywhere
(use-package emacs-everywhere
:disabled
:ensure t)
(provide 'utilities/emacs-everywhere)
;;; emacs-everywhere.el ends here

15
lisp/utilities/emms.el Normal file
View File

@@ -0,0 +1,15 @@
;;; emms --- Emacs Multimedia System -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://www.gnu.org/software/emms/
(use-package emms
:commands (emms-streams)
:config
(emms-standard)
(emms-default-players)
(emms-mode-line nil)
(require 'emms-streams)
(setq emms-streams-file (path-join *user-data-directory* "streams.emms")))
(provide 'utilities/emms)
;;; emms.el ends here

11
lisp/utilities/epc.el Normal file
View File

@@ -0,0 +1,11 @@
;;; epc.el --- RPC stack for Emacs -*- lexical-binding: t; -*-
;;; Commentary: This program is an asynchronous RPC stack for Emacs
;;; Code: https://github.com/kiwanami/emacs-epc
(use-package epc
:disabled
:defer)
(provide 'utilities/epc)
;;; epc.el ends here

View File

@@ -0,0 +1,87 @@
;;; flycheck.el --- flycheck configuration -*- lexical-binding: t; -*-
;;; Commentary: https://www.flycheck.org/en/latest/
;;; Code: https://github.com/flycheck/flycheck
(defun user--flycheck-mode-hook ()
"Flycheck mode hook."
;;; (Bindings) ;;;
(user/bind-key-local :code :warnings/errors 'helm-flycheck)
(user/bind-key-local :nav :next 'flycheck-next-error))
(defun user/ede-flycheck-setup ()
"Configure `flycheck' using `ede'."
(when (and ede-object
(slot-exists-p ede-object 'compilation)
(oref ede-object compilation))
(let* ((comp (oref ede-object compilation))
(cmd (get-command-line comp)))
(setq
flycheck-clang-includes (get-includes comp)
flycheck-clang-definitions (get-defines comp)
flycheck-clang-include-path (oref comp include-path-common))
(when (string-match " -std=\\([^ ]+\\)" cmd)
(setq
flycheck-clang-language-standard (match-string 1 cmd)
flycheck-gcc-language-standard (match-string 1 cmd)))
(when (string-match " -stdlib=\\([^ ]+\\)" cmd)
(setq flycheck-clang-standard-library (match-string 1 cmd)))
(when (string-match " -fms-extensions " cmd)
(setq flycheck-clang-ms-extensions t))
(when (string-match " -fno-exceptions " cmd)
(setq
flycheck-clang-no-exceptions t
flycheck-gcc-no-exceptions t))
(when (string-match " -fopenmp" cmd)
(setq flycheck-gcc-openmp t))
(when (string-match " -fno-rtti " cmd)
(setq
flycheck-clang-no-rtti t
flycheck-gcc-no-rtti t))
(when (string-match " -fblocks " cmd)
(setq flycheck-clang-blocks t)))))
(use-package flycheck
:commands global-flycheck-mode
:preface
(defvar-local flycheck-local-checkers nil)
(defun +flycheck-checker-get(fn checker property)
(or (alist-get property (alist-get checker flycheck-local-checkers))
(funcall fn checker property)))
(advice-add 'flycheck-checker-get :around '+flycheck-checker-get)
:hook
((flycheck-mode-hook . user--flycheck-mode-hook)
(ede-minor-mode-hook . user/ede-flycheck-setup)
(ede-compdb-project-rescan-hook . user/ede-flycheck-setup))
:config
(validate-setq
;; Wait five seconds before starting checker
flycheck-idle-change-delay 5.0)
(with-eval-after-load 'popwin
;; Use popwin for Flycheck error list.
(push '(flycheck-error-list-mode :stick t) popwin:special-display-config))
;;; (Packages) ;;;
;; https://github.com/flycheck/flycheck-pos-tip
;; This Flycheck extension shows errors under point in pos-tip popups.
(use-package flycheck-pos-tip
:if window-system
:config
;; Make sure flycheck-pos-tip is loaded.
(require 'flycheck-pos-tip nil t))
;; https://github.com/gexplorer/flycheck-indicator
;; An Emacs minor-mode to get a fancy mode line indicator for Flycheck.
(use-package flycheck-indicator
:hook (flycheck-mode-hook . flycheck-indicator-mode))
;; https://github.com/yasuyk/helm-flycheck
;; Show flycheck errors with helm.
(use-package helm-flycheck)
(global-flycheck-mode t))
(provide 'utilities/flycheck)
;;; flycheck.el ends here

View File

@@ -0,0 +1,15 @@
;;; google-this.el --- Google item under point -*- lexical-binding: t; -*-
;;; Commentary: A set of emacs functions and bindings to google under point.
;;; Code: https://github.com/Malabarba/emacs-google-this
(use-package google-this
:defer
:diminish google-this-mode
:init
(user/bind-key-global :util :google 'google-search)
(user/bind-key-global :util :google-at-point 'google-this)
(user/bind-key-global :util :google-selection 'google-region))
(provide 'utilities/google-this)
;;; google-this.el ends here

238
lisp/utilities/helm.el Normal file
View File

@@ -0,0 +1,238 @@
;;; helm.el --- improved Emacs control -*- lexical-binding: t; -*-
;;; Commentary: Helm is an Emacs framework for incremental completions and narrowing selections
;;; Code: https://github.com/emacs-helm/helm
(defun user/helm-apropos ()
"A context-aware helm apropos."
(interactive)
(let ((buffer-name "*helm-apropos*"))
(cond
((derived-mode-p 'emacs-lisp-mode) (helm-apropos))
((derived-mode-p 'sh-mode) (helm-other-buffer
'(helm-source-man-pages
helm-source-info-pages) buffer-name))
((derived-mode-p 'c-mode-common) (helm-other-buffer
'(helm-source-man-pages) buffer-name))
((derived-mode-p 'python-mode) (helm-pydoc))
(t (message (format "Apropos is unavailable for %S" major-mode))))))
(defun user/helm-navigate ()
"A context-aware helm navigation aid."
(interactive)
(cond
((derived-mode-p 'prog-mode) (user/helm-navigate-prog))
(t (user/helm-navigate-generic))))
(defun user/helm-navigate-prog ()
"A context-aware helm for programming modes."
(interactive)
(let ((helm-sources '(helm-source-buffers-list))
(current-file (or (buffer-file-name) default-directory)))
(with-feature 'helm-misc
;; FIXMEs.
(add-to-list 'helm-sources 'helm-source-fixme)
;; Emacs lisp.
(add-to-list 'helm-sources 'helm-source-emacs-source-defun)
(add-to-list 'helm-sources 'helm-source-emacs-lisp-expectations)
(add-to-list 'helm-sources 'helm-source-emacs-lisp-toplevels))
(with-project project current-file
;; Bookmarks.
(add-to-list 'helm-sources 'helm-source-bookmarks)
;; Semantic.
(with-feature 'helm-semantic
(when (user/proj-from-path user/ede-proj current-file)
(add-to-list 'helm-sources 'helm-source-semantic))))
(helm-other-buffer helm-sources "*helm-navigate-prog*")))
(defun user/helm-navigate-generic ()
"A somewhat context-aware generic helm."
(interactive)
(condition-case nil
(let ((helm-sources '(helm-source-buffers-list
helm-source-recentf
helm-source-file-name-history
helm-source-file-cache
helm-source-buffer-not-found
helm-source-man-pages
helm-source-info-pages)))
(cond
((eq system-type 'darwin)
(progn
(add-to-list 'helm-sources 'helm-source-mac-spotlight)))
((eq system-type 'gnu/linux)
(progn
(add-to-list 'helm-sources 'helm-source-tracker-search))))
(helm-other-buffer helm-sources "*helm-navigate-generic*"))
;; Fall back to helm-mini if an error occurs in one of the sources.
(error (helm-mini))))
(defun user/helm-mode ()
"Start helm-mode."
(helm-mode t)
(with-feature 'helm-descbinds
(helm-descbinds-mode t))
;; Filter out boring buffers.
(dolist (pattern
(list "\\*clang-complete" "\\*CEDET global" "\\*tramp/scpc"
"\\*epc con" "\\*Pymacs" "\\*Completions\\*"))
(add-to-list 'helm-boring-buffer-regexp-list pattern))
;; Filter out boring files.
(dolist (pattern
(list "\\.elc$" "\\.pyc$" "^#.+#$" "^G[R]TAGS$" "^GPATH$" "^ID$"))
(add-to-list 'helm-boring-file-regexp-list pattern)))
(use-package helm
:diminish helm-mode
;; :ensure
;; Since Helm depends on `eieio', enable it after package initialization.
:hook (after-init-hook . user/helm-mode)
:init
(user/bind-key-global :nav :context 'user/helm-navigate)
(user/bind-key-global :doc :apropos 'user/helm-apropos)
(user/bind-key-global :emacs :elisp-search 'helm-info-elisp)
:config
(validate-setq
;; Idle delays.
helm-input-idle-delay 0.0
;; Limit the number of candidates per source to a reasonable amount.
helm-candidate-number-limit 75)
(with-eval-after-load 'popwin
(add-to-list
'popwin:special-display-config
'("helm" :regexp t :height 0.4 :position bottom)))
;;; (Packages) ;;;
;; https://github.com/emacs-helm/helm-descbinds
;; Helm Descbinds provides an interface to emacs describe-bindings making the currently active key bindings interactively searchable with helm.
(use-package helm-descbinds
:defer)
;; https://github.com/emacsorphanage/helm-swoop
;; List match lines to another buffer, which is able to squeeze by any words you input
(use-package helm-swoop
:defer
:init
(user/bind-key-global :basic :swoop 'helm-swoop)
(user/bind-key-global :basic :swoop-multi 'helm-multi-swoop)
:config
(validate-setq
;; Split window vertically when swooping.
helm-swoop-split-direction 'split-window-horizontally)
;;; (Bindings) ;;;
(define-key isearch-mode-map
(user/get-key :basic :swoop) 'helm-swoop-from-isearch)
(with-eval-after-load 'helm-swoop
;; From helm-swoop to helm-multi-swoop-all.
(define-key helm-swoop-map
(user/get-key :basic :swoop)
'helm-multi-swoop-all-from-helm-swoop)))
;; https://github.com/emacs-helm/helm/blob/master/helm-adaptive.el
;; Adaptive Sorting of Candidates
(use-package helm-adaptive
:ensure helm
:config
(validate-setq
;; Put adaptive history in cache directory.
helm-adaptive-history-file (path-join *user-cache-directory* "helm-adaptive-history")))
(use-package helm-command
:ensure helm
:bind* ([remap execute-extended-command] . helm-M-x))
(use-package helm-files
:ensure helm
:bind* (([remap find-file] . helm-find-files)
:map helm-find-files-map
("C-k" . helm-ff-persistent-delete))
:config
;; `helm-recentf-fuzzy-match' is set via Customize
;; Reason: https://emacs.stackexchange.com/a/106/5514
(validate-setq
helm-ff-file-name-history-use-recentf t
;; Don't prompt for new buffer.
helm-ff-newfile-prompt-p nil
helm-input-idle-delay 0.1
;; Don't show boring files.
helm-ff-skip-boring-files t
;; Search for library in `require' and `declare-function' sexp.
helm-ff-search-library-in-sexp t
;; Auto-complete in find-files.
helm-ff-auto-update-initial-value t))
(use-package helm-misc
:ensure helm
:bind* ([remap switch-to-buffer] . helm-mini))
(use-package helm-buffers
:ensure helm
:bind (:map helm-buffer-map
("C-k" . helm-buffer-run-kill-persistent))
:config
(validate-setq
;; Use fuzzy matching for buffer names.
helm-buffers-fuzzy-matching t
;; Don't check if remote files exist.
helm-buffer-skip-remote-checking t))
(use-package helm-ring
:ensure helm
:bind* (([remap yank-pop] . helm-show-kill-ring)
("C-c SPC" . helm-all-mark-rings)))
(use-package helm-imenu
:ensure helm
:bind (("C-c n i" . helm-imenu-in-all-buffers)
("C-c n t" . helm-imenu))
:config
(validate-setq
helm-imenu-fuzzy-match t)
;; Incompatible with validate-setq.
(setq
helm-imenu-execute-action-at-once-if-one nil))
(use-package helm-bookmark
:ensure helm
:defer
:bind ("C-x r l" . helm-filtered-bookmarks))
(use-package helm-pages
:ensure helm
:defer
:bind ("C-c n P" . helm-pages))
(use-package helm-eval
:ensure helm
:defer
:bind (("C-c h M-:" . helm-eval-expression-with-eldoc)
("C-c h *" . helm-calcul-expression)))
(use-package helm-external
:ensure helm
:defer
:bind ("C-c h x" . helm-run-external-command))
(use-package helm-build-command
:defer
:quelpa (helm-build-command
:fetcher github
:repo "tkf/helm-build-command"))
(use-package helm-icons
:if (display-graphic-p)
:disabled
:config
(helm-icons-enable)))
(provide 'utilities/helm)
;;; helm.el ends here

View File

@@ -0,0 +1,28 @@
;;; hideshow.el --- Configure hide show -*- lexical-binding: t; -*-
;;; Commentary: Hideshow mode is a buffer-local minor mode that allows you to selectively display portions of a program
;;; Code: https://github.com/emacs-mirror/emacs/blob/master/lisp/progmodes/hideshow.el
(defun user--hs-minor-mode-hook ()
"Minor mode hook for Hide Show."
;;; (Bindings) ;;;
(local-set-key (kbd "C-c SPC") 'user/hs-toggle-level)
(local-set-key (kbd "C-c <right>") 'hs-show-block)
(local-set-key (kbd "C-c <left>") 'hs-hide-block)
(local-set-key (kbd "C-c <up>") 'hs-hide-all)
(local-set-key (kbd "C-c <down>") 'hs-show-all))
(defun user/hs-toggle-level ()
"Toggle hide/show for level at point."
(interactive)
(hs-show-block)
(hs-hide-level 1))
(use-package hideshow
:init
(add-hook 'hs-minor-mode-hook 'user--hs-minor-mode-hook))
(provide 'utilities/hideshow)
;;; hideshow.el ends here

25
lisp/utilities/ibuffer.el Normal file
View File

@@ -0,0 +1,25 @@
;;; ibuffer --- improved buffer management -*- lexical-binding: t; -*-
;;; Commentary: buffer is an advanced replacement for BufferMenu, which lets you operate on buffers much in the same manner as Dired.
;;; Code:
(defun user--ibuffer-hook ()
"Hook for improved buffer."
(ibuffer-vc-set-filter-groups-by-vc-root)
(unless (eq ibuffer-sorting-mode 'filename/process)
(ibuffer-do-sort-by-filename/process)))
(use-package ibuffer
:bind* (([remap list-buffers] . ibuffer))
:init
(add-hook 'ibuffer-hook 'user--ibuffer-hook)
:config
(validate-setq
ibuffer-filter-group-name-face 'font-lock-doc-face)
;; https://github.com/purcell/ibuffer-vc
;; Group buffers in ibuffer list by VC project
(use-package ibuffer-vc
:defer))
(provide 'utilities/ibuffer)
;;; ibuffer.el ends here

33
lisp/utilities/ido.el Normal file
View File

@@ -0,0 +1,33 @@
;;; ido.el --- interactively do things -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/emacs-mirror/emacs/blob/master/lisp/ido.el
(defun user--ido-mode-hook ()
"Mode hook for ido."
(when (feature-p 'flx)
(flx-ido-mode t))
(when (feature-p 'ido-vertical-mode)
(ido-vertical-mode t)))
(use-package ido
:defer
:config
(validate-setq
;; Enable fuzzy matching
ido-enable-flex-matching t
;; Remember buffers that have been open
ido-use-virtual-buffers t
;; Allow the same buffer to be opened in different windows
ido-default-buffer-method 'selected-window)
;; https://github.com/lewang/flx
;; Matching engine
(use-package flx
:config
(validate-setq
;; Flex has its own highlights.
ido-use-faces nil))
(use-package ido-vertical-mode))
(provide 'utilities/ido)
;;; ido.el ends here

51
lisp/utilities/lsp.el Normal file
View File

@@ -0,0 +1,51 @@
;;; lsp.el --- Language server protocol. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/emacs-lsp/lsp-mode
(defun user--lsp-mode-hook ()
"Mode hook for LSP minor modes."
(message "user--lsp-mode-hook"))
(use-package lsp-mode
:pin "MELPA"
:commands lsp
:hook ((lsp-after-open-hook . lsp-enable-imenu)
(lsp-mode-hook . user--lsp-mode-hook))
:config
(validate-setq
;; Automatically try to figure out project root.
lsp-auto-guess-root t
;; Location of persistent LSP session.
lsp-session-file (path-join *user-cache-directory* "lsp-session")
;; Disable yasnippet integration.
lsp-enable-snippet nil
;; Don't watch files for changes, prevents freeze during compilation.
lsp-enable-file-watchers nil
;; Disable headerline
lsp-headerline-breadcrumb-enable nil
;; Increase the amount of data that can be read from a language server.
read-process-output-max (* 3 1024 1024))
;; https://github.com/emacs-lsp/lsp-ui/
;; This package contains all the higher level UI modules of lsp-mode, like flycheck support and code lenses.
(use-package lsp-ui
:hook (lsp-mode-hook . lsp-ui-mode)
:config
;; https://emacs-lsp.github.io/lsp-mode/tutorials/how-to-turn-off/
(validate-setq
lsp-modeline-code-actions-enable nil
lsp-ui-sideline-enable nil
lsp-ui-doc-delay 3
lsp-ui-doc-position 'bottom))
(use-package lsp-treemacs
:ensure t
:defer t
;; :after (lsp treemacs)
:custom
(lsp-treemacs-sync-mode 1)
)
)
(provide 'utilities/lsp)
;;; lsp.el ends here

19
lisp/utilities/pandoc.el Normal file
View File

@@ -0,0 +1,19 @@
;;; pandoc.el --- Interface to Pandoc -*- lexical-binding: t; -*-
;;; Commentary: An Emacs mode for interacting with Pandoc
;;; Code: https://github.com/joostkremers/pandoc-mode
(defun user--pandoc-mode-hook ()
"Pandoc mode hook."
(pandoc-load-default-settings))
(use-package pandoc-mode
:if (executable-find "pandoc")
:defer
:diminish pandoc-mode
:init
(add-hook 'pandoc-mode 'user--pandoc-mode-hook))
(provide 'utilities/pandoc)
;;; pandoc.el ends here

View File

@@ -0,0 +1,10 @@
;;; polymode.el --- Multiple major modes in a single buffer. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code: https://github.com/polymode/polymode
(use-package polymode
:defer)
(provide 'utilities/polymode)
;;; polymode.el ends here

View File

@@ -0,0 +1,22 @@
;;; presentation.el --- Emacs presentation mode -*- lexical-binding: t; -*-
;;; Commentary: Presentation mode is a global minor mode to zoom characters
;;; Code: https://github.com/zonuexe/emacs-presentation-mode
(defun user--presentation-on-hook ()
"Hook executed when enabling presentation mode."
;; Disable Helm.
(helm-mode -1))
(defun user--presentation-off-hook ()
"Hook executed when disabling presentation mode."
;; Enable Helm.
(helm-mode 1))
(use-package presentation
:hook ((presentation-on-hook . user--presentation-on-hook)
(presentation-off-hook . user--presentation-off-hook))
:bind-wrap ((:key :util :presentation) . presentation-mode))
(provide 'utilities/presentation)
;;; presentation.el ends here

View File

@@ -0,0 +1,30 @@
;;; profiler.el --- Configure Emacs profiler -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;;; Doc: https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html
(defun user--profiler-report-mode-hook ()
"Profiler report mode hook."
;;; (Bindings) ;;;
(user/bind-key-local :basic :save 'profiler-report-write-profile)
(user/bind-key-local :basic :save-as 'profiler-report-write-profile))
(use-package profiler
:defer
:init
(add-hook 'profiler-report-mode-hook 'user--profiler-report-mode-hook)
;;; (Bindings) ;;;
(user/bind-key-global :emacs :profiler-start 'profiler-start)
(user/bind-key-global :emacs :profiler-stop 'profiler-stop)
(user/bind-key-global :emacs :profiler-report 'profiler-report)
:config
(validate-setq
;; The maximum number distinct of call-stacks to save.
profiler-log-size 100000
;; Maximum call-stack depth to record.
profiler-max-stack-depth 32))
(provide 'utilities/profiler)
;;; profiler.el ends here

133
lisp/utilities/project.el Normal file
View File

@@ -0,0 +1,133 @@
;;; project.el --- helpers for working with projects -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(with-eval-after-load 'eieio
(defclass user/proj ()
()
"Project class.")
(cl-defgeneric user/proj-name ((project user/proj))
"Get the PROJECT name.")
(cl-defgeneric user/proj-root ((project user/proj))
"Get the PROJECT root path.")
(cl-defgeneric user/proj-include-paths ((project user/proj))
"Get the include paths for PROJECT.")
(cl-defgeneric user/proj-build ((project user/proj))
"Build PROJECT.")
(cl-defmethod user/proj-name ((project user/proj))
(file-name-nondirectory
(directory-file-name (user/proj-root project))))
(cl-defmethod user/proj-include-paths ((project user/proj)))
(with-eval-after-load 'ede
(defclass user/ede-proj (user/proj)
((ede :initarg :ede :initform nil
:documentation "EDE project instance."))
"EDE project class.")
(cl-defmethod user/proj-from-path :static ((project user/ede-proj) &rest args)
"Constructor for EDE project at path in ARGS."
(when (featurep 'ede)
(let ((ede-proj (ede-current-project (expand-file-name (first args)))))
(when (cl-some (lambda (args)
(and (featurep (first args))
(funcall (second args) ede-proj)))
'((ede/cpp-root ede-cpp-root-project-p)
(ede/generic ede-generic-makefile-project-p)
(ede/generic ede-generic-cmake-project-p)
(ede/linux ede-linux-project-p)
(ede/compdb ede-compdb-project-p)))
(make-instance 'user/ede-proj :ede ede-proj)))))
(cl-defmethod user/proj-name ((project user/ede-proj))
(ede-name (oref project :ede)))
(cl-defmethod user/proj-root ((project user/ede-proj))
(ede-project-root-directory (oref project :ede)))
(cl-defmethod user/proj-include-paths ((project user/ede-proj))
(let ((root-path (user/proj-root project))
(include-paths (oref (oref project :ede) include-path)))
(mapcar #'(lambda (path) (expand-file-name path root-path))
include-paths)))
(cl-defmethod user/proj-build ((project user/ede-proj))
(let ((ede-proj (oref project :ede)))
(project-compile-project
ede-proj
(read-string "Build command: " (oref ede-proj compile-command))))))
(with-eval-after-load 'projectile
(defclass user/projectile-proj (user/proj)
((root-path :initarg :root-path
:type string
:documentation "Project root path."))
"Projectile project class.")
(cl-defmethod user/proj-from-path :static ((project user/projectile-proj) &rest args)
"Constructor for projectile project at path in ARGS."
(let ((default-directory (file-name-as-directory (first args)))
(projectile-require-project-root nil))
(when (and (feature-p 'projectile) (projectile-project-p))
(make-instance 'user/projectile-proj :root-path (projectile-project-root)))))
(cl-defmethod user/proj-root ((project user/projectile-proj))
(oref project :root-path)))
(with-eval-after-load 'vc
(defclass user/vc-proj (user/proj)
((root-path :initarg :root-path
:type string
:documentation "Project root path."))
"VC project class.")
(cl-defmethod user/proj-from-path :static ((project user/vc-proj) &rest args)
"Constructor for VC project at path in ARGS."
(let* ((vc-backend (and (fboundp 'vc-responsible-backend)
(ignore-errors
(vc-responsible-backend
(file-truename (first args))))))
(root-path (and vc-backend
(vc-call-backend
vc-backend 'root (file-truename (first args))))))
(when root-path
(make-instance 'user/vc-proj :root-path root-path))))
(cl-defmethod user/proj-root ((project user/vc-proj))
(oref project :root-path)))
(cl-defmethod user/proj-from-path :static ((project user/proj) &rest args)
"Constructor for project at path in ARGS."
(let ((f (lambda (proj-type)
(when (fboundp proj-type)
(funcall #'user/proj-from-path proj-type (first args)))))
(proj-types '(user/ede-proj user/projectile-proj user/vc-proj)))
(cl-some f proj-types))))
(defmacro with-project (project &optional path &rest body)
"Bind PROJECT for PATH and evaluate BODY if project exists."
(declare (indent defun)
(debug let))
`(let ((,project (user/proj-from-path user/proj (or ,path (path-abs-buffer)))))
(when ,project
,@body)))
(defmacro with-project-root (project-root &optional path &rest body)
"Bind PROJECT-ROOT for PATH and evaluate BODY if project exists."
(declare (indent defun)
(debug let))
`(with-project project (or ,path (path-abs-buffer))
(let ((,project-root (user/proj-root project)))
,@body)))
(provide 'utilities/project)
;;; project.el ends here

View File

@@ -0,0 +1,33 @@
;;; projectile.el --- Projectile project management -*- lexical-binding: t; -*-
;;; Commentary: Projectile is a project interaction library for Emacs
;;; Code: https://github.com/bbatsov/projectile
(use-package projectile
:diminish projectile-mode
:defer
:init
;;; (Bindings) ;;;
(user/bind-key-global :basic :open-file-context 'projectile-find-file)
:config
(validate-setq
;; Projectile bookmarks.
projectile-known-projects-file (path-join *user-data-directory*
"projectile-bookmarks.eld")
;; Projectile cache store.
projectile-cache-file (path-join *user-cache-directory* "projectile")
;; Use default completion that will usually be provided by Helm.
projectile-completion-system 'default)
(with-eval-after-load 'smart-mode-line
(validate-setq
;; Enable in smart mode line.
sml/use-projectile-p 'after-prefixes))
(with-executable 'ctags-exuberant
(validate-setq
;; Default to exuberant ctags.
projectile-tags-command "ctags-exuberant -Re %s")))
(provide 'utilities/projectile)
;;; projectile.el ends here

21
lisp/utilities/sauron.el Normal file
View File

@@ -0,0 +1,21 @@
;;; sauron.el --- Emacs event tracker -*- lexical-binding: t; -*-
;;; Commentary: sauron is an emacs mode for keeping track of events happening in the (emacs) world around you.
;;; Code: https://github.com/djcb/sauron
(use-package sauron
:defer
:bind-wrap
((:key :util :notifications) . sauron-toggle-hide-show)
:config
(validate-setq
;; Display sauron in current frame.
sauron-separate-frame nil)
(with-eval-after-load 'alert
(add-hook 'sauron-event-added-functions 'sauron-alert-el-adapter))
(sauron-start-hidden))
(provide 'utilities/sauron)
;;; sauron.el ends here

View File

@@ -0,0 +1,165 @@
;;; smartparens.el --- Set up smartparens. -*- lexical-binding: t; -*-
;;; Commentary: Smartparens is a minor mode for dealing with pairs in Emacs.
;;; Code: https://github.com/Fuco1/smartparens
(defun user/smartparens-enable ()
"Enable smartparens in current mode."
(when (feature-p 'smartparens)
(show-smartparens-mode t)
(smartparens-mode t)))
(defun user--sp-org-point-in-checkbox-p (_id action _context)
"Check if smartparens ACTION is inside checkbox."
(when (eq action 'insert)
(sp--looking-at-p "\\s-*]")))
(defun user--sp-cxx-point-is-template-p (id action context)
"Return t if point with ID using ACTION in CONTEXT is in the right place for C++ angle-brackets."
(and (sp-in-code-p id action context)
(sp-point-after-word-p id action context)))
(defun user--sp-cc-point-after-include-p (id action context)
"Return t if point with ID using ACTION in CONTEXT is in an #include."
(and (sp-in-code-p id action context)
(save-excursion
(goto-char (line-beginning-position))
(looking-at-p "[ ]*#include[^<]+"))))
(defun user--sp-haskell-after-symbol-p (_id action _context)
"Return t if point using ACTION is after a symbol."
(when (eq action 'insert)
(save-excursion
(backward-char 1)
(looking-back "\\sw\\|\\s_\\|\\s'"))))
(defun user--sp-gfm-skip-asterisk (_ms position _me)
"Return t if asterisk should be skipped at point with POSITION."
(save-excursion
(goto-char position)
(save-match-data (looking-at "^\\* "))))
(defun user--sp-php-handle-docstring (&rest _ignored)
"Handle PHP docstrings with smartparens."
(-when-let (line (save-excursion
(forward-line)
(thing-at-point 'line)))
(cond
((string-match-p "function" line)
(save-excursion
(insert "\n")
(let ((args (save-excursion
(forward-line)
(my-php-get-function-args))))
(--each args
(insert (format "* @param %s\n" it)))))
(insert "* "))
((string-match-p ".*class\\|interface" line)
(save-excursion (insert "\n*\n* @author\n"))
(insert "* ")))
(let ((o (sp--get-active-overlay)))
(indent-region (overlay-start o) (overlay-end o)))))
(use-package smartparens
:diminish smartparens-mode
:bind-wrap
(:map smartparens-mode-map
([remap kill-line] . sp-kill-hybrid-sexp)
((:key :basic :selection-next) . sp-select-next-thing-exchange)
((:key :basic :selection-prev) . sp-select-previous-thing)
((:key :basic :forward-word) . sp-forward-symbol)
((:key :basic :backward-word) . sp-backward-symbol)
((:key :basic :forward-expr) . sp-forward-sexp)
((:key :basic :backward-expr) . sp-backward-sexp)
((:key :code :unwrap-expr) . sp-unwrap-sexp)
((:key :code :comment) . sp-comment)
((:key :basic :cut-expr) . sp-kill-sexp)
((:key :basic :copy-expr) . sp-copy-sexp))
:config
(validate-setq
;; Don't kill trailing whitespace with `sp-hybrid-kill'.
sp-hybrid-kill-excessive-whitespace nil)
;; Don't insert pairs automatically if point is at a word.
(sp-pair "{" nil
:post-handlers '(("||\n[i]" "RET") ("| " " "))
:unless '(sp-point-before-word-p sp-point-before-same-p)
:wrap "C-{")
(sp-pair "(" nil
:post-handlers '(("||\n[i]" "RET") ("| " " "))
:unless '(sp-point-before-word-p sp-point-before-same-p)
:wrap "C-(")
(sp-pair "[" nil
:post-handlers '(("| " " "))
:unless '(sp-point-before-word-p sp-point-before-same-p))
(sp-pair "\"" nil :unless '(sp-point-before-word-p sp-point-after-word-p sp-point-before-same-p))
(sp-pair "'" nil :unless '(sp-point-before-word-p sp-point-after-word-p sp-point-before-same-p))
(sp-with-modes '(c-mode c++-mode objc-mode)
;; Automatically add another newline before closing curly brace on enter.
(sp-local-pair "{" nil :post-handlers '(("||\n[i]" "RET")))
(sp-local-pair "/*" "*/" :post-handlers '((" | " "SPC") ("* ||\n[i]" "RET")))
(sp-local-pair "<" ">" :when '(user--sp-cxx-point-is-template-p user--sp-cc-point-after-include-p))
(sp-local-pair "/*" "*/" :post-handlers '(("||\n[i]" "RET") ("| " "SPC")))
;; Doxygen blocks.
(sp-local-pair "/**" "*/" :post-handlers '(("||\n[i]" "RET") ("||\n[i]" "SPC")))
(sp-local-pair "/*!" "*/" :post-handlers '(("||\n[i]" "RET") ("[d-1]< | " "SPC"))))
(sp-with-modes '(css-mode scss-mode less-css-mode stylus-mode)
(sp-local-pair "/*" "*/" :post-handlers '(("[d-3]||\n[i]" "RET") ("| " "SPC"))))
(sp-with-modes '(haskell-mode)
(sp-local-pair "'" nil :unless '(user--sp-haskell-after-symbol-p))
(sp-local-pair "\\(" nil :actions nil))
(sp-with-modes '(javascript-mode js2-mode js3-mode rjsx-mode)
(sp-local-pair "/* " " */" :post-handlers '(("| " "SPC"))))
(sp-with-modes '(sh-mode markdown-mode gfm-mode rts-mode python-mode cython-mode)
(sp-local-pair "`" nil :unless '(sp-point-before-word-p sp-point-after-word-p sp-point-before-same-p)))
(sp-with-modes '(markdown-mode gfm-mode rst-mode)
(sp-local-pair "*" "*" :wrap "C-*" :skip-match 'user--sp-gfm-skip-asterisk)
(sp-local-tag "2" "**" "**")
(sp-local-tag "<" "<_>" "</_>" :transform 'sp-match-sgml-tags))
(sp-with-modes '(tex-mode plain-tex-mode latex-mode)
(sp-local-tag "i" "\"<" "\">")
(sp-local-pair "$" nil :unless '(sp-point-before-word-p))
(sp-local-pair "\\[" " \\]")
(sp-local-pair "\\(" " \\)")
(sp-local-pair "\\{" " \\}")
(sp-local-pair "\\left(" " \\right)")
(sp-local-pair "\\left\\{" " \\right\\}"))
(sp-with-modes '(org-mode)
(sp-local-pair "*" "*"
:post-handlers '(("[d1]" "SPC"))
:unless '(sp-point-after-word-p sp-point-before-word-p sp-point-at-bol-p))
(sp-local-pair "_" "_"
:post-handlers '(("[d1]" "SPC"))
:unless '(sp-point-after-word-p sp-point-before-word-p))
(sp-local-pair "/" "/"
:post-handlers '(("[d1]" "SPC"))
:unless '(sp-point-after-word-p sp-point-before-word-p user--sp-org-point-in-checkbox-p))
(sp-local-pair "~" "~"
:post-handlers '(("[d1]" "SPC"))
:unless '(sp-point-after-word-p sp-point-before-word-p))
(sp-local-pair "=" "="
:post-handlers '(("[d1]" "SPC"))
:unless '(sp-point-after-word-p sp-point-before-word-p))
(sp-local-pair "«" "»"))
(sp-with-modes '(php-mode)
(sp-local-pair "/**" "*/"
:post-handlers '(("| " "SPC") (user--sp-php-handle-docstring "RET")))
(sp-local-pair "/*." ".*/" :post-handlers '(("| " "SPC")))
(sp-local-pair "{" nil :post-handlers '(("||\n[i]" "RET")))
(sp-local-pair "(" nil :prefix "\\(\\sw\\|\\s_\\)*"))
(sp-with-modes '(scala-mode)
(sp-local-pair "'" nil :actions nil)))
(provide 'utilities/smartparens)
;;; smartparens.el ends here

127
lisp/utilities/spelling.el Normal file
View File

@@ -0,0 +1,127 @@
;;; flyspell.el --- spell checking on the fly -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-auto-dictionary-buffer-limit* (* 128 1024)
"Maximum buffer size for automatic dictionary detection.")
(defun user--flyspell-mode-common-hook ()
"Hook for fly spell common mode."
(if (> (buffer-size) *user-auto-dictionary-buffer-limit*)
;; Disables automatic dictionary detection in large buffers.
(guess-language-mode -1)
(with-feature 'flyspell-lazy
(guess-language-mode t)
;; Enables flyspell lazy mode for small buffers.
(flyspell-lazy-mode t)))
(with-feature 'auto-correct
(auto-correct-mode t))
;;; (Bindings) ;;;
(user/bind-key-local :code :spellcheck-word 'ispell-word)
(user/bind-key-local :code :spellcheck-add-word 'user/flyspell-add-word-to-dict))
(defun user--flyspell-mode-hook ()
"Hook for fly spell mode."
(user--flyspell-mode-common-hook))
(defun user--flyspell-prog-mode-hook ()
"Hook for fly spell prog mode."
(user--flyspell-mode-common-hook))
(defun user/flyspell-add-word-to-dict ()
"Add the word at the current location to the private dictionary without question."
(interactive)
;; Use the correct dictionary.
(flyspell-accept-buffer-local-defs)
(setq opoint (point-marker))
(let ((cursor-location (point))
(word (flyspell-get-word nil)))
(if (consp word)
(let ((start (car (cdr word)))
(end (car (cdr (cdr word))))
(word (car word)))
;; The word is incorrect, we have to propose a replacement.
(flyspell-do-correct 'save nil word cursor-location start end opoint)))
(ispell-pdict-save t)))
(defun user-flyspell-p ()
"Check if flyspell is available."
(or (executable-find "ispell")
(executable-find "aspell")
(executable-find "hunspell"))
nil)
(when (user-flyspell-p)
(use-package flyspell
:ensure nil
:diminish flyspell-mode
:hook ((flyspell-mode-hook . user--flyspell-mode-hook)
(flyspell-prog-mode-hook . user--flyspell-prog-mode-hook))
:config
(validate-setq
;; Be silent when checking words.
flyspell-issue-message-flag nil)
(cond
(;; Disable Hunspell due to issues on some machines.
(and nil (executable-find "hunspell"))
(validate-setq
ispell-program-name "hunspell"
ispell-really-hunspell t
ispell-extra-args '("-a" "-i" "utf-8")))
((executable-find "aspell")
(progn
(validate-setq
ispell-program-name "aspell"
ispell-really-aspell t
;; Improve performance by reducing suggestions.
ispell-extra-args '("--sug-mode=ultra" "--dont-suggest"))
(when (boundp 'flyspell-list-command)
(validate-setq
flyspell-list-command "--list")))))
;; http://elpa.gnu.org/packages/auto-correct.html
;; Remembers and automatically fixes past corrections
(use-package auto-correct
:diminish auto-correct-mode)
;; https://github.com/pronobis/helm-flyspell
;; Helm extension for correcting words with Flyspell.
(use-package helm-flyspell
:bind ("C-c c s" . helm-flyspell-correct))
;; https://github.com/rolandwalker/flyspell-lazy
;; This package reduces the amount of work done by flyspell.
;; Instead of checking instantly as you type, spelling will be checked when Emacs has been idle for a short time.
(use-package flyspell-lazy
:config
(validate-setq
;; Idle timeout before running spell check on region.
flyspell-lazy-idle-seconds 10
;; Idle timeout before running spell check on entire buffer.
flyspell-lazy-window-idle-seconds 60))
;; https://github.com/tmalsburg/guess-language.el
;; Emacs minor mode for robust automatic language detection
;; TODO: Add fr
(use-package guess-language
:diminish guess-language-mode
:config
(validate-setq
;; By default only guess English.
guess-language-languages '(en)))
;; https://github.com/ppold/.emacs.d/blob/master/site-lisp/rw-hunspell.el
;; special functions for Hunspell in ispell.el
(use-package rw-hunspell
:if (executable-find "hunspell")
:config
(with-eval-after-load 'ispell
(when ispell-really-hunspell
;; Initialize `rw-hunspell` if Hunspell is in use.
(rw-hunspell-setup))))))
(provide 'utilities/flyspell)
;;; flyspell.el ends here

31
lisp/utilities/term.el Normal file
View File

@@ -0,0 +1,31 @@
;;; term.el --- Initialize the Emacs terminal -*- lexical-binding: t; -*-
;;; Commentary: A terminal in Emacs
;;; Code: Cross-referencing commands
(defun user--term-mode-hook ()
"Term mode hook."
(user--shell-mode-common-hook))
(defun user--term-exec-hook ()
"Term startup hook."
;; Automatically close buffer when finished.
(let* ((buf (current-buffer))
(proc (get-buffer-process buf)))
(set-process-sentinel
proc
`(lambda (process event)
(if (string= event "finished\n")
(kill-buffer ,buf))))))
(use-package term
:defer
:init
(add-hook 'term-exec-hook 'user--term-exec-hook)
(add-hook 'term-mode-hook 'user--term-mode-hook)
:config
(define-key term-raw-map (kbd "C-c C-y") 'term-paste))
(provide 'utilities/term)
;;; term.el ends here

65
lisp/utilities/tramp.el Normal file
View File

@@ -0,0 +1,65 @@
;;; tramp --- remote file access -*- lexical-binding: t; -*-
;;; Commentary: https://www.emacswiki.org/emacs/TrampMode
;;; Code:
(use-package tramp
:ensure nil
:after dash
:commands
(tramp-tramp-file-p
tramp-check-proper-method-and-host)
:config
(validate-setq
;; Auto save storage.
tramp-auto-save-directory (path-join *user-auto-save-directory* "tramp")
;; Default file transfer method.
tramp-default-method "ssh"
;; Cache passwords.
password-cache t
password-cache-expiry 1000
;; SSH is properly configured to share connections.
tramp-use-ssh-controlmaster-options nil
;; Skip looking for dir-local on remote system to speed up tramp.
enable-remote-dir-locals nil
;; Preserve PATH on remote host.
tramp-remote-path (delete 'tramp-default-remote-path tramp-remote-path))
;; Preserve PATH on remote host.
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
(tramp-set-completion-function
"ssh" (mapcar
(lambda (x) (list 'tramp-parse-sconfig x))
(-remove
(lambda (x) (not (file-exists-p x)))
`(,(path-join "/" "etc" "ssh_config")
,(path-join "/" "etc" "ssh" "ssh_config")
,(path-join *user-home-directory* ".ssh" "config")))))
(unless (fboundp 'tramp-compat-split-string)
;; Workaround for Python mode depending on the deleted TRAMP
;; function `tramp-compat-split-string'.
(defun tramp-compat-split-string (string pattern)
"Like `split-string' but omit empty strings.
In Emacs, (split-string \"/foo/bar\" \"/\") returns (\"foo\" \"bar\").
This is, the first, empty, element is omitted. In XEmacs, the first
element is not omitted."
(split-string string pattern 'omit)))
;; http://web.mit.edu/Emacs/source/emacs/lisp/net/tramp-cache.el
;; file information caching for Tramp
(use-package tramp-cache
:ensure tramp
:config
(validate-setq
;; Persistency files.
tramp-persistency-file-name
(path-join *user-cache-directory* "tramp")))
;; https://github.com/masasam/emacs-helm-tramp
;; Tramp helm interface for ssh server and docker and vagrant
(use-package helm-tramp
:init
(user/bind-key-global :basic :open-file-tramp 'helm-tramp)))
(provide 'utilities/tramp)
;;; tramp.el ends here

View File

@@ -0,0 +1,22 @@
;;; transient.el --- Configuration for transient. -*- lexical-binding: t; -*-
;;; Commentary: Taking inspiration from prefix keys and prefix arguments,
;;; Transient implements a similar abstraction involving a prefix command, infix arguments and suffix commands
;;; Code: https://github.com/magit/transient
(use-package transient
:ensure nil
:config
;; Using `validate-setq' here will cause loading to file if the
;; history file does not exist.
(setq
;; Location of transient files.
transient-history-file (path-join *user-cache-directory* "transient" "history.el")
transient-values-file (path-join *user-cache-directory* "transient" "values.el")
transient-levels-file (path-join *user-cache-directory* "transient" "levels.el"))
;; Create the transient cache folder.
(make-directory (path-join *user-cache-directory* "transient") t))
(provide 'utilities/transient)
;;; transient.el ends here

View File

@@ -0,0 +1,16 @@
;;; yasnippet.el --- Configuration for yasnippet -*- lexical-binding: t: -*-
;;; Commentary: YASnippet is a template system for Emacs
;;; Code:
;;; Docs: https://github.com/joaotavora/yasnippet
(use-package yasnippet
:ensure t
:config
(use-package yasnippet-snippets
:ensure t)
(define-key yas-minor-mode-map (kbd "<tab>") nil)
(define-key yas-minor-mode-map (kbd "TAB") nil)
(define-key yas-minor-mode-map (kbd "C-c y") yas-maybe-expand)
(yas-global-mode 1))
;;; yasnippet.el ends here

View File

@@ -0,0 +1,48 @@
;;; zettelkasten.el --- zettelkasten method -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package org-roam
:ensure t
:init
(setq org-roam-v2-ack t)
:custom
(org-roam-directory "~/.local/share/emacs/org/roam")
:bind (("C-c n f" . org-roam-node-find)
("C-c n r" . org-roam-node-random)
(:map org-mode-map
(("C-c n i" . org-roam-node-insert)
("C-c n o" . org-id-get-create)
("C-c n t" . org-roam-tag-add)
("C-c n a" . org-roam-alias-add)
("C-c n l" . org-roam-buffer-toggle))))
:config
;; org-roam-setup is obsolete, use org-roam-db-autosync-enable instead.
(org-roam-db-autosync-enable))
;; Add modified and creation timestamps to the org-roam property drawer.
;; https://github.com/ThomasFKJorna/org-roam-timestamps
(use-package org-roam-timestamps
:ensure t
:after org-roam
:config
;; Overwrite the previous timestamps instead of keeping a list of timestamps.
(setq org-roam-timestamps-remember-timestamps nil)
(org-roam-timestamps-mode))
;; A graphical frontend for exploring your org-roam Zettelkasten.
;; https://github.com/org-roam/org-roam-ui
(use-package org-roam-ui
:ensure t
:after org-roam
:config
(setq
;; Sync the Emacs theme
org-roam-ui-sync-theme t
;; TODO:
org-roam-ui-follow t
;; Enable open in default browser
org-roam-ui-open-on-start t)
)
;;; zettelkasten.el ends here

44
lisp/ux/backups.el Normal file
View File

@@ -0,0 +1,44 @@
;;; backups.el --- Emacs backup system -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; Set up the backups directory.
(defconst *user-backup-directory* (path-join *user-cache-directory* "backups"))
;; Set up the autosaves directory.
(defconst *user-auto-save-directory* (path-join *user-cache-directory* "auto-saves"))
;; Emacs will create the backup dir automatically, but not the autosaves dir.
(make-directory *user-auto-save-directory* t)
(defun user--backups-config ()
"Initialize Emacs backup system."
(validate-setq
;; Put backups in the cache directory
backup-directory-alist `((".*" . ,*user-backup-directory*))
;; Version-control backup files
version-control t
;; Keep 16 new versions and 2 old versions
kept-new-versions 6
kept-old-versions 2
;; Delete old versions without asking
delete-old-versions t
;; Always backup by copy
backup-by-copying t)
(validate-setq
;; Auto-save every minute or 300 events
auto-save-interval 300
auto-save-timeout 60
;; Always auto-save buffers.
auto-save-default t
;; Put autosave files (ie #foo#) and backup files (ie foo~) into a cache dir.
auto-save-file-name-transforms `((".*" ,(concat *user-auto-save-directory* "/\\1") t))
;; Put session backups into the cache directory.
auto-save-list-file-prefix (path-join *user-auto-save-directory* ".saves-")))
(user--backups-config)
(provide 'ux/backups)
;;; backups.el ends here

55
lisp/ux/buffers.el Normal file
View File

@@ -0,0 +1,55 @@
;;; buffers.el --- Configure Emacs buffers -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user/kill-matching-buffers (regexp &optional exclude-p)
"Kill buffers whose name match the specified REGEXP but not EXCLUDE-P."
(interactive "sKill buffers matching this regular expression: \nP")
(dolist (buffer (buffer-list))
(let ((name (buffer-name buffer)))
(when (and name (not (string-equal name ""))
(/= (aref name 0) ?\s)
(string-match regexp name))
(unless (and exclude-p (funcall exclude-p buffer))
(kill-buffer buffer))))))
(defun user/kill-all-buffers ()
"Close all open buffers."
(interactive)
(mapc 'kill-buffer (buffer-list))
(switch-to-buffer "*scratch*"))
(defun user/kill-other-buffers ()
"Close all open buffers except current one."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
(defun user--buffers-config ()
"Initialize Emacs buffers.
;; The library uniquify overrides Emacs default mechanism for making buffer names unique"
(use-package uniquify
:ensure nil
:config
(validate-setq
;; Set up uniquify's style.
uniquify-buffer-name-style 'reverse
uniquify-separator ""
uniquify-after-kill-buffer-p t
uniquify-ignore-buffers-re "^\\*"))
;;; (Bindings) ;;;
(user/bind-key-global :basic :open-file 'find-file)
(user/bind-key-global :basic :open-buffer 'switch-to-buffer)
(user/bind-key-global :basic :save 'save-buffer)
(user/bind-key-global :basic :save-as 'write-file)
(user/bind-key-global :basic :close 'kill-buffer)
(user/bind-key-global :basic :quit 'save-buffers-kill-terminal))
(user--buffers-config)
(provide 'ux/buffers)
;;; buffers.el ends here

15
lisp/ux/cache.el Normal file
View File

@@ -0,0 +1,15 @@
;;; cache.el --- Configure Emacs persistent caches -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
;; https://github.com/sigma/pcache
;; Persistent caching for Emacs
(use-package pcache
:pin "MELPA"
:init
(setq-default
pcache-directory (path-join *user-cache-directory* "pcache")))
(provide 'ux/cache)
;;; cache.el ends here

29
lisp/ux/coding.el Normal file
View File

@@ -0,0 +1,29 @@
;;; coding.el --- Coding system configuration -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--coding-config ()
"Initialize coding system."
;; Prefer UTF-8 if there is a choice
(prefer-coding-system 'utf-8)
(when (eq default-terminal-coding-system 'utf-8)
;; Set coding systems to UTF-8
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(when (eq window-system 'x)
;; Treat X11 clipboard input as UTF-8 string first; compound text next,
;; etc.
(validate-setq
x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))))
;;; (Bindings) ;;;
(user/bind-key-global :emacs :describe-coding 'describe-coding-system)
(user/bind-key-global :emacs :describe-char 'describe-char)
(user/bind-key-global :emacs :describe-language 'describe-language-environment))
(user--coding-config)
(provide 'ux/coding)
;;; coding.el ends here

281
lisp/ux/completion.el Normal file
View File

@@ -0,0 +1,281 @@
;;; completion.el --- Configures automatic code completion -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'cl))
(defun user--company-mode-hook ()
"Company mode hook."
(message "user--company-mode-hook")
(when (derived-mode-p 'prog-mode)
(define-key (current-local-map) (user/get-key :code :complete) 'company-indent-or-complete-common))
;; ;; (user/complete-at-point-install)
;; ;;; (Bindings) ;;;
;; ;; (when (current-local-map)
;; ;; (define-key (current-local-map) (user/get-key :code :auto-complete) 'company-complete))
;; (when (current-local-map)
;; (define-key (current-local-map) (user/get-key :code :complete) 'company-complete))
;; (when (current-local-map)
;; (define-key (current-local-map) (user/get-key :code :complete) 'company-indent-or-complete-common))
)
(defun user/company-mode-p ()
"True if auto-complete should be used."
(and (boundp 'global-company-mode)
global-company-mode))
;; (defun user/complete-at-point-install ()
;; "Install completion backend in complete-at-point."
;; (setq
;; ;; Insert completion backend into `completion-at-point'.
;; completion-at-point-functions
;; (cons 'user/complete-at-point
;; (remove 'user/complete-at-point completion-at-point-functions))))
;; (defun user/company-check-expansion ()
;; "Check if expression can be expanded by company."
;; (save-excursion
;; (if (looking-at "\\_>") t
;; (backward-char 1)
;; (if (looking-at "\\.") t
;; (backward-char 1)
;; (if (looking-at "->") t nil)))))
;; (defun user/complete-at-point ()
;; "Complete thing at point using completion backend."
;; (cond
;; ((minibufferp) (minibuffer-complete))
;; ;; ((and (boundp 'auto-complete-mode) auto-complete-mode) #'auto-complete)
;; ((and (boundp 'company-mode) company-mode (user/company-check-expansion)) #'company-complete-common)
;; (t #'indent-for-tab-command)))
;; (defun ac-pcomplete ()
;; "Auto-complete source for pcomplete."
;; ;; eshell uses `insert-and-inherit' to insert a \t if no completion
;; ;; can be found, but this must not happen as auto-complete source
;; (cl-flet ((insert-and-inherit (&rest args)))
;; ;; this code is stolen from `pcomplete' in pcomplete.el
;; (let* (tramp-mode ;; do not automatically complete remote stuff
;; (pcomplete-stub)
;; (pcomplete-show-list t) ;; inhibit patterns like * being deleted
;; pcomplete-seen pcomplete-norm-func
;; pcomplete-args pcomplete-last pcomplete-index
;; (pcomplete-autolist pcomplete-autolist)
;; (pcomplete-suffix-list pcomplete-suffix-list)
;; (candidates (pcomplete-completions))
;; (beg (pcomplete-begin))
;; ;; note, buffer text and completion argument may be
;; ;; different because the buffer text may bet transformed
;; ;; before being completed (e.g. variables like $HOME may be
;; ;; expanded)
;; (buftext (buffer-substring beg (point)))
;; (arg (nth pcomplete-index pcomplete-args)))
;; ;; we auto-complete only if the stub is non-empty and matches
;; ;; the end of the buffer text
;; (when (and (not (zerop (length pcomplete-stub)))
;; (or (string= pcomplete-stub ; Emacs 23
;; (substring buftext
;; (max 0
;; (- (length buftext)
;; (length pcomplete-stub)))))
;; (string= pcomplete-stub ; Emacs 24
;; (substring arg
;; (max 0
;; (- (length arg)
;; (length pcomplete-stub)))))))
;; ;; Collect all possible completions for the stub. Note that
;; ;; `candidates` may be a function, that's why we use
;; ;; `all-completions`.
;; (let* ((cnds (all-completions pcomplete-stub candidates))
;; (bnds (completion-boundaries pcomplete-stub
;; candidates
;; nil
;; ""))
;; (skip (- (length pcomplete-stub) (car bnds))))
;; ;; We replace the stub at the beginning of each candidate by
;; ;; the real buffer content.
;; (mapcar #'(lambda (cand) (concat buftext (substring cand skip)))
;; cnds))))))
;; (defvar ac-source-pcomplete
;; '((candidates . ac-pcomplete)))
;; (defun add-ac-sources (&rest sources)
;; "Add SOURCES for auto-complete after it has been loaded."
;; (when (user/auto-complete-p)
;; (dolist (source sources)
;; (if (boundp 'ac-sources)
;; (add-to-list 'ac-sources source)
;; (error "Declaration of ac-sources is missing!")))))
;; (defun add-ac-modes (&rest major-modes)
;; "Add MAJOR-MODES for auto-complete after it has been loaded."
;; (when (user/auto-complete-p)
;; (dolist (mode major-modes)
;; (if (boundp 'ac-modes)
;; (add-to-list 'ac-modes mode)
;; (error "Declaration of ac-modes is missing!")))))
;; (defun company-complete-common-or-selection ()
;; "Insert the common part of all candidates, or the selection."
;; (interactive)
;; (when (company-manual-begin)
;; (let ((tick (buffer-chars-modified-tick)))
;; (call-interactively 'company-complete-common)
;; (when (eq tick (buffer-chars-modified-tick))
;; (let ((company-selection-wrap-around t))
;; (call-interactively 'company-complete-selection))))))
;; (defun add-company-sources (&rest sources)
;; "Add SOURCES for company completion in current mode, if it has been loaded."
;; (when (user/company-mode-p)
;; (when (boundp 'company-backends)
;; (setq-local
;; company-backends
;; (append sources company-backends)))))
(defun user--completion-config ()
"Initialize automatic code completion."
(setq
;; Activate completion on tab.
tab-always-indent 'complete
;; Cycle completions in minibuffer below a certain threshold.
completion-cycle-threshold 5)
;; Allow completion of acronyms and initialisms.
(add-to-list 'completion-styles 'initials t)
;;; (Packages) ;;;
;; (use-package auto-complete
;; :disabled
;; :requires popup fuzzy
;; :defer
;; :quelpa (auto-complete
;; :fetcher github
;; :repo "auto-complete/auto-complete")
;; :diminish auto-complete-mode
;; :init
;; (add-hook 'flymake-mode-hook 'ac-flyspell-workaround)
;; (add-hook 'auto-complete-mode-hook 'user--auto-complete-mode-hook)
;; :config
;; (with-feature 'auto-complete-config
;; ;; Load default configuration.
;; (ac-config-default)
;; ;; Don't forcibly enable auto-complete.
;; (global-auto-complete-mode -1))
;; (validate-setq
;; ;; Limit the number of candidates.
;; ac-candidate-limit 40
;; ;; Delay until narrowing completions.
;; ac-delay 0.5
;; ;; Do not trigger completion automatically.
;; ac-auto-start nil
;; ;; Use fuzzy matching.
;; ac-fuzzy-enable t
;; ac-use-fuzzy t
;; ;; Do not pop up menu automatically.
;; ac-auto-show-menu nil
;; ;; Allow normal navigation keys in menu.
;; ac-use-menu-map t
;; ;; Do not auto-expand common candidates.
;; ac-expand-on-auto-complete nil
;; ;; Show quick help popup after half a second.
;; ac-use-quick-help t
;; ac-quick-help-delay 0.5
;; ;; Store the completion history in the cache directory.
;; ac-comphist-file (path-join *user-cache-directory* "ac-comphist.dat"))
;; ;; Set up auto-complete for lisp-interaction- and ielm-mode.
;; (dolist (hook (list 'lisp-interaction-mode-hook
;; 'ielm-mode-hook))
;; (add-hook hook 'ac-emacs-lisp-mode-setup))
;; ;;; (Bindings) ;;;
;; (ac-set-trigger-key (user/get-key :code :try-complete))
;; (validate-setq
;; ac-completing-map
;; (let ((map (make-sparse-keymap)))
;; ;; Expand on tab.
;; (define-key map (user/get-key :code :try-complete) 'ac-expand-common)
;; ;; Complete on enter.
;; (define-key map (user/get-key :code :complete) 'ac-complete)
;; ;; Bind configured auto complete key.
;; (define-key map (user/get-key :code :auto-complete) 'auto-complete)
;; ;; Scroll quick-help using M-n/p.
;; (define-key map (kbd "C-M-n") 'ac-quick-help-scroll-down)
;; (define-key map (kbd "C-M-p") 'ac-quick-help-scroll-up)
;; map)))
(use-package company
:diminish company-mode
:hook (company-mode-hook . user--company-mode-hook)
:config
(validate-setq
;; Do not trigger completion automatically.
;; company-idle-delay nil
;; Complete immediately.
company-minimum-prefix-length 0
;; Show commonly used matches first.
company-transformers '(company-sort-by-occurrence)
;; Align annotations to the right of tooltip.
company-tooltip-align-annotations t
;; Active company frontends.
;; company-frontends
;; '(company-pseudo-tooltip-unless-just-one-frontend
;; company-preview-frontend
;; company-echo-metadata-frontend)
)
;; (define-key company-active-map (user/get-key :code :complete) 'company-complete-selection)
;; (define-key company-active-map
;; (user/get-key :code :try-complete) 'company-complete-common-or-selection)
;; (define-key company-active-map
;; (user/get-key :basic :forward-line) 'company-select-next)
;; (define-key company-active-map
;; (user/get-key :basic :backward-line) 'company-select-previous)
;; (define-key company-active-map (user/get-key :code :complete) 'company-search-candidates)
(use-package company-dabbrev-code
:ensure company
:config
(validate-setq
;; Complete even outside of code.
company-dabbrev-code-everywhere t))
(use-package company-flx
:after (company)
:config
(company-flx-mode t))
(use-package company-quickhelp
:if window-system
:after (company)
:hook (company-mode-hook . company-quickhelp-mode)
:config
(validate-setq
;; Show quick help popup after half a second.
company-quickhelp-delay 0.5))
(use-package company-box
:if (display-graphic-p)
:hook (company-mode . company-box-mode))
(global-company-mode t)))
(user--completion-config)
(provide 'ux/completion)
;;; completion.el ends here

130
lisp/ux/editing.el Normal file
View File

@@ -0,0 +1,130 @@
;;; editing.el --- Configure Emacs editing -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun beginning-or-indentation ()
"Move cursor to beginning of line or to its indentation."
(interactive)
(if (bolp)
(back-to-indentation)
(beginning-of-line)))
(defun point-in-comment ()
"Determine if the point is inside a comment."
(interactive)
(let ((syn (syntax-ppss)))
(and (nth 8 syn)
(not (nth 3 syn)))))
(defun end-of-line-or-code (arg)
"Move point to end of line or forward ARG.
If already there, move back to end of code. By 'end of code' we
mean before a possible comment. Comments are recognized in any
mode that sets `syntax-ppss' properly."
(interactive "P")
(let ((eol (save-excursion
(move-end-of-line arg)
(point))))
(cond ((= (point) eol)
(move-end-of-line arg)
(while (point-in-comment)
(backward-char))
(skip-chars-backward " \t"))
(t (move-end-of-line arg)))))
(defun user--editing-config ()
"Initialize editing in Emacs."
(validate-setq
;; Increase history.
history-length 1000)
;; Enable narrowing.
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'narrow-to-defun 'disabled nil)
;; Enable case modification.
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
;;; (Packages) ;;;
(use-package simple
:ensure nil
:diminish auto-fill-function)
(when (eq window-system 'ns)
(use-package ns-win
:ensure nil
:config
(validate-setq
;; Swap command and option on MacOS X.
mac-option-modifier 'alt
mac-command-modifier 'meta
;; Use right option key for writing special characters.
mac-right-option-modifier nil)))
;; Fix https://github.com/rolandwalker/unicode-fonts/issues/21
;; (use-package unicode-fonts
;; :if (eq default-terminal-coding-system 'utf-8)
;; ;; Ensure `pcache-directory' has been set first.
;; :after ux/cache
;; :config
;; (require 'persistent-soft)
;; (unicode-fonts-setup))
(load-file (path-join *user-cache-directory* "unicode-fonts-setup.el"))
(when (feature-p 'helm)
(use-package helm-unicode
:if (eq default-terminal-coding-system 'utf-8)
:bind ("C-c h 8" . helm-unicode)))
(use-package selected
:ensure t
:diminish selected-minor-mode
:commands selected-minor-mode
:init
(setq
selected-org-mode-map (make-sparse-keymap))
(selected-global-mode t)
:bind (:map selected-keymap
;; Region.
("q" . selected-off)
("e" . er/expand-region)
;; Modification.
("f" . fill-region)
("u" . upcase-region)
("d" . downcase-region)
("s" . sort-lines)
("m" . apply-macro-to-region-lines)
;; Information.
("w" . count-words-region)
;; Motion.
("p" . move-text-up)
("n" . move-text-down)
:map selected-org-mode-map
("t" . org-table-convert-region)))
;;; (Bindings) ;;;
(global-set-key [remap move-beginning-of-line] 'beginning-or-indentation)
(global-set-key [remap move-end-of-line] 'end-of-line-or-code)
(user/bind-key-global :basic :forward-word 'forward-word)
(user/bind-key-global :basic :backward-word 'backward-word)
(user/bind-key-global :basic :forward-expr 'forward-sexp)
(user/bind-key-global :basic :backward-expr 'backward-sexp)
(user/bind-key-global :basic :del-char-left 'delete-backward-char)
(user/bind-key-global :basic :del-char-right 'delete-char)
(user/bind-key-global :basic :widen 'widen)
(user/bind-key-global :basic :narrow-to-page 'narrow-to-page)
(user/bind-key-global :basic :narrow-to-region 'narrow-to-region)
(user/bind-key-global :basic :narrow-to-function 'narrow-to-defun)
(user/bind-key-global :code :join-line 'join-line)
(user/bind-key-global :code :fill-paragraph 'fill-paragraph))
(user--editing-config)
(provide 'ux/editing)
;;; editing.el ends here

108
lisp/ux/frames.el Normal file
View File

@@ -0,0 +1,108 @@
;;; frames.el --- Configure behavior of Emacs frames -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--window-configuration-change-hook ()
;; "Window configuration change hook."
;; (setq
;; ;; Only split frame if it occupies at least 2/3 of the current screen width.
;; split-width-threshold (* (/ (window-total-width (frame-root-window)) 3) 2)))
)
(defun user/iconify-or-deiconify-frame ()
"Iconify the selected frame, or deiconify if it's currently an icon."
(interactive)
(if (display-graphic-p)
(iconify-or-deiconify-frame)
(suspend-frame)))
(defun user/close-and-kill-current-window ()
"If multiple windows are open, close the current one and kill the buffer."
(interactive)
(kill-this-buffer)
(if (not (one-window-p))
(delete-window)))
(defun user/close-and-kill-other-window ()
"If multiple windows are open, close the next one and kill its buffer."
(interactive)
(other-window 1)
(kill-this-buffer)
(if (not (one-window-p))
(delete-window)))
(progn
(validate-setq
;; Inhibit GUI features
use-file-dialog nil
;; Don't split frames horizontally.
split-height-threshold nil)
;; Remove all the mouse-assisted frames
(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
(when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
;;; (Hooks) ;;;
(add-to-list 'window-configuration-change-hook
'user--window-configuration-change-hook)
;;; (Bindings) ;;;
(when (display-graphic-p)
(user/bind-key-global :emacs :fullscreen 'toggle-frame-fullscreen))
(user/bind-key-global :emacs :grow-vertical 'enlarge-window)
(user/bind-key-global :emacs :shrink-vertical 'shrink-window)
(user/bind-key-global :emacs :grow-horizontal 'enlarge-window-horizontally)
(user/bind-key-global :emacs :shrink-horizontal 'shrink-window-horizontally)
;;; (Packages) ;;;
;; https://github.com/tomterl/fullframe
;; Advice commands to execute fullscreen, restoring the window setup when exiting
(use-package fullframe)
;; https://github.com/emacsorphanage/transpose-frame/blob/master/transpose-frame.el
;; Transpose windows arrangement in a frame
(use-package transpose-frame
:defer
:init
(user/bind-key-global :emacs :flip-frame 'flip-frame)
(user/bind-key-global :emacs :flop-frame 'flop-frame)
(user/bind-key-global :emacs :rotate-frame-forward 'rotate-frame-clockwise)
(user/bind-key-global :emacs :rotate-frame-backward
'rotate-frame-anticlockwise))
;; https://github.com/cyrus-and/zoom
;; Fixed and automatic balanced window layout for Emacs
(use-package zoom
:diminish zoom-mode
:config
(validate-setq
;; Ignored buffers.
zoom-ignored-buffer-name-regexps
'("^*calc")
;; Ignore predicate definitions.
zoom-ignore-predicates
'((lambda () (> (count-lines (point-min) (point-max)) 20))))
(zoom-mode t))
(use-package frame
:ensure nil
:config
;; Enable blinking cursor
(blink-cursor-mode))
;;
;;
(use-package framemove
:quelpa (framemove
:fetcher github
:repo "emacsmirror/framemove")
:init
(windmove-default-keybindings)
(setq framemove-hook-into-windmove t)))
(provide 'ux/frames)
;;; frames.el ends here

11
lisp/ux/gc.el Normal file
View File

@@ -0,0 +1,11 @@
;;; gc.el --- Garbage collector settings -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package gcmh
:config
(gcmh-mode t))
(provide 'ux/gc)
;;; gc.el ends here

115
lisp/ux/help.el Normal file
View File

@@ -0,0 +1,115 @@
;;; help.el --- Emacs help -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package help-mode
:ensure nil
:defer
:config
(use-package help-fns
:ensure nil
:init
(user/bind-key-global :emacs :describe-variable 'describe-variable)
(user/bind-key-global :emacs :describe-syntax 'describe-syntax))
(use-package helpful
:init
(user/bind-key-global :emacs :describe-function 'helpful-function)
(user/bind-key-global :emacs :describe-macro 'helpful-macro)
(user/bind-key-global :emacs :describe-command 'helpful-command)
:config
(with-eval-after-load 'popwin
;; Use popwin for helpful buffer.
(add-to-list
'popwin:special-display-config
;; Don't select compilation window when shown
'(helpful-mode :position bottom :height 20)))))
(use-package apropos
:ensure nil
:defer
:init
(user/bind-key-global :emacs :search-variable-value 'apropos-value))
(use-package info-look
:ensure nil
:defer
:init
(user/bind-key-global :emacs :describe-symbol 'info-lookup-symbol))
(use-package help
:ensure nil
:defer
:init
(user/bind-key-global :emacs :describe-bindings 'describe-bindings)
(user/bind-key-global :emacs :describe-key 'describe-key)
(user/bind-key-global :emacs :where-is 'where-is)
(user/bind-key-global :emacs :describe-mode 'describe-mode)
(use-package helm-describe-modes
:init
(global-set-key [remap describe-mode] #'helm-describe-modes)))
(use-package find-func
:ensure nil
:defer
:init
(user/bind-key-global :emacs :find-library 'find-library))
(use-package finder
:ensure nil
:defer
:init
(user/bind-key-global :emacs :find-package 'finder-by-keyword))
(use-package menu-bar
:ensure nil
:defer
:init
(user/bind-key-global :emacs :elisp-search 'elisp-index-search))
(use-package tutorial
:ensure nil
:defer
:init
(user/bind-key-global :emacs :tutorial 'help-with-tutorial))
(use-package which-key
:diminish which-key-mode
:config
(validate-setq
;; Number of seconds until help is shown.
which-key-idle-delay 1.0
which-key-special-keys
'("SPC"
"TAB"
"RET"
"DLT" ; delete key
"BS" ; backspace key
"ESC"))
(when (eq default-terminal-coding-system 'utf-8)
(add-many-to-list
'which-key-replacement-alist
'(("TAB" . nil) . ("" . nil))
'(("RET" . nil) . ("" . nil))
'(("DEL" . nil) . ("" . nil))
'(("deletechar" . nil) . ("" . nil))
'(("DEL" . nil) . ("" . nil))
'(("SPC" . nil) . ("" . nil))))
(which-key-add-key-based-replacements
user/view-prefix "view"
user/help-prefix "help"
user/documentation-prefix "doc"
user/code-prefix "code"
user/code-eval-prefix "eval"
user/vcs-prefix "vcs"
user/utilities-prefix "utils"
user/apps-prefix "apps")
(which-key-mode t))
(provide 'ux/help)
;;; help.el ends here

18
lisp/ux/indentation.el Normal file
View File

@@ -0,0 +1,18 @@
;;; indentation.el --- Configure Emacs indentation behavior -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package dtrt-indent
:config
(validate-setq
dtrt-indent-verbosity 0
global-mode-string (delq 'dtrt-indent-mode-line-info global-mode-string)))
(use-package smart-tabs-mode
:quelpa (smart-tabs-mode
:fetcher github
:repo "jcsalomon/smarttabs"))
(provide 'ux/indentation)
;;; indentation.el ends here

91
lisp/ux/kill-yank.el Normal file
View File

@@ -0,0 +1,91 @@
;;; kill-yank.el --- Configuration for copying and pasting of data -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package mouse
:ensure nil
:config
(validate-setq
;; Mouse selection should not automatically go to kill ring.
mouse-drag-copy-region nil)
(when (eq window-system 'x)
(validate-setq
;; Don't inject mouse selection into X11 clipboard.
mouse-drag-copy-region nil)
;; Set middle mouse button to paste from primary X11 selection.
(global-set-key [mouse-2] 'mouse-yank-primary)))
(use-package select
:if window-system
:ensure nil
:config
(validate-setq
;; Do not interact with X11 primary selection.
select-enable-primary nil
;; Make kill/yank interact with X11 clipboard selection.
select-enable-clipboard t
;; Active region should set primary X11 selection.
select-active-regions t))
(use-package menu-bar
:ensure nil
:config
;; Rebind to new clipboard functions when available.
(when (fboundp 'clipboard-kill-region)
(global-set-key [remap kill-region] 'clipboard-kill-region))
(when (fboundp 'clipboard-kill-ring-save)
(global-set-key [remap kill-ring-save] 'clipboard-kill-ring-save))
(when (fboundp 'clipboard-yank)
(global-set-key [remap yank] 'clipboard-yank)))
(use-package expand-region
:bind-wrap
(((:key :basic :selection-expand) . er/expand-region)
((:key :basic :select-paragraph) . er/mark-paragraph)
((:key :basic :select-function) . er/mark-defun)
((:key :basic :select-inside) . er/mark-inside-pairs)))
(use-package multiple-cursors
:defer
:bind-wrap
(((:key :basic :selection-next) . mc/mark-next-like-this)
((:key :basic :selection-prev) . mc/mark-previous-like-this)
((:key :basic :selection-all) . mc/mark-all-like-this)
((:key :basic :selection-edit-lines) . mc/edit-lines)))
(use-package rect-mark
:defer
:quelpa (rect-mark
:fetcher url
:url "https://www.emacswiki.org/emacs/download/rect-mark.el"))
(use-package simple
:ensure nil
:bind-wrap
(;; Delete words with C/M-w and rebind kill/yank region to C-x C-k/C-x C-w.
((:key :basic :cut-word-left) . backward-kill-word)
((:key :basic :cut-word-right) . kill-word)
;; Set up basic copy/paste
((:key :basic :selection-start) . set-mark-command)
((:key :basic :copy) . kill-ring-save)
((:key :basic :cut) . kill-region)
((:key :basic :paste) . yank)
((:key :basic :cycle-paste) . yank-pop))
:config
(validate-setq
;; Increase the maximum number of saved kill ring entries.
kill-ring-max 200
;; Do not store duplicates in kill ring.
kill-do-not-save-duplicates t
;; Save clipboard before killing it.
save-interprogram-paste-before-kill t))
(use-package move-text
:defer)
(user/bind-key-global :basic :cut-expr 'kill-sexp)
(provide 'ux/kill-yank)
;;; kill-yank.el ends here

51
lisp/ux/mode-line.el Normal file
View File

@@ -0,0 +1,51 @@
;;; mode-line.el --- Mode line configuration -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--modeline-config ()
"Initialize Emacs mode line."
;; Show row and column numbers.
(validate-setq
line-number-mode t
column-number-mode t
display-time-mode nil)
;;; (Packages) ;;;
;; Display the current time and system load.
(use-package time
:disabled
:config
(validate-setq
display-time-24hr-format t
display-time-day-and-date t)
(display-time))
;; Display battery status.
(use-package battery
:disabled
:config
(when (and (functionp battery-status-function)
(not (string-match-p "N/A" (battery-format "%B" (funcall battery-status-function)))))
(validate-setq battery-mode-line-format
(format " [%s%s%s]" "%b%p%" " (%t)"
(if (string-match-p "N/A" (battery-format "%d" (funcall battery-status-function)))
""
" %d°C")))
(display-battery-mode t)))
(use-package doom-modeline
:hook (after-init-hook . doom-modeline-init)
:config
(validate-setq
doom-modeline-height 18))
(use-package mode-line-bell
:config
(mode-line-bell-mode t)))
(user--modeline-config)
(provide 'ux/mode-line)
;;; mode-line.el ends here

60
lisp/ux/navigation.el Normal file
View File

@@ -0,0 +1,60 @@
;;; navigation.el --- Set up Emacs buffer navigation -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user/scroll-up ()
"Scroll page up without moving point."
(interactive)
(scroll-down 1))
(defun user/scroll-down ()
"Scroll page down without moving point."
(interactive)
(scroll-up 1))
(defun user--navigation-config ()
"Set up Emacs buffer navigation."
;; Enable mouse in iTerm2
(when (eq system-type 'darwin)
(with-feature 'mouse
(xterm-mouse-mode t)
(defun track-mouse (e))))
;;; (Bindings) ;;;
(user/bind-key-global :nav :scroll-up 'user/scroll-up)
(user/bind-key-global :nav :scroll-down 'user/scroll-down)
(user/bind-key-global :nav :goto-line 'goto-line)
(user/bind-key-global :nav :go-back 'pop-global-mark)
;; https://github.com/abo-abo/avy
;; Jump to things in Emacs tree-style
(use-package avy
:bind ("M-s" . avy-goto-char)
:config
(avy-setup-default))
;; https://github.com/jcs-elpa/goto-line-preview
;; Preview line when executing goto-line command.
(use-package goto-line-preview
:disabled
:config
(user/bind-key-global :nav :goto-line 'goto-line-preview))
;; https://github.com/magnars/smart-forward.el
;; smart-forward gives you semantic navigation, building on expand-region
(use-package smart-forward
:disabled
:defer
:init
(user/bind-key-global :nav :context-forward 'smart-forward)
(user/bind-key-global :nav :context-backward 'smart-backward)
(user/bind-key-global :nav :context-up 'smart-up)
(user/bind-key-global :nav :context-down 'smart-down)))
(user--navigation-config)
(provide 'ux/navigation)
;;; navigation.el ends here

12
lisp/ux/paths.el Normal file
View File

@@ -0,0 +1,12 @@
;;; paths.el --- Configure system paths in Emacs -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package exec-path-from-shell
:if (memq window-system '(mac ns x))
:config
(exec-path-from-shell-initialize))
(provide 'ux/paths)
;;; paths.el ends here

35
lisp/ux/popups.el Normal file
View File

@@ -0,0 +1,35 @@
;;; popups.el --- Configure Emacs popups -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--popups-config ()
"Initialize Emacs popups."
(validate-setq
;; Timeout for messages shown in minibuffer.
minibuffer-message-timeout 5)
;;; (Packages) ;;;
(use-package popup
:config
;; Install workaround for whitespace-mode bug.
(with-eval-after-load 'modes/whitespace
(defadvice popup-draw (before user/turn-off-whitespace activate compile)
"Turn off whitespace mode before showing popup."
(user/whitespace-mode-suppress t))
(defadvice popup-delete (after user/restore-whitespace activate compile)
"Restore previous whitespace mode when deleting popup."
(user/whitespace-mode-suppress nil))))
(use-package popwin
:init
(user/bind-key-global :util :popwin-close 'popwin:close-popup-window)
(user/bind-key-global :util :popwin-buffer 'popwin:popup-buffer)
:config
(popwin-mode t)))
(user--popups-config)
(provide 'ux/popups)
;;; popups.el ends here

30
lisp/ux/prompts.el Normal file
View File

@@ -0,0 +1,30 @@
;;; prompts.el --- Configure Emacs prompting -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--prompts-config ()
"Initialize Emacs prompting."
(validate-setq
;; Always follow links to version controlled files.
vc-follow-symlinks t
;; Always ask before killing Emacs.
confirm-kill-emacs 'y-or-n-p)
;; Use shorter y/n prompts instead of yes/no.
(fset 'yes-or-no-p 'y-or-n-p)
(when (display-graphic-p)
(validate-setq
;; Don't use graphical dialog boxes when prompting.
use-dialog-box nil))
(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
"Prevent \"Active processes exist\" query when you quit Emacs."
(with-feature 'cl-lib
(cl-flet ((process-list ())) ad-do-it))))
(user--prompts-config)
(provide 'ux/prompts)
;;; prompts.el ends here

53
lisp/ux/rendering.el Normal file
View File

@@ -0,0 +1,53 @@
;;; rendering.el --- Configure Emacs user interface rendering -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defconst *user-fast-font-lock-buffer-limit* (* 128 1024)
"Maximum buffer size for maximum font lock decorations.")
(defun user--rendering-find-file-hook ()
"Rendering hook for `find-file'."
(when (> (buffer-size) *user-fast-font-lock-buffer-limit*)
(setq
;; Reduce the level of fontification.
font-lock-maximum-decoration nil)
(font-lock-refresh-defaults)))
(defun user--rendering-config ()
"Setup Emacs user interface rendering."
(with-eval-after-load 'font-lock
;; Allow reduction of decoration level in large buffers.
(make-variable-buffer-local 'font-lock-maximum-decoration))
(validate-setq
;; Redraw the entire screen before checking for pending input events.
;; This will improve performance in general but might degrade performance of
;; key repeat.
redisplay-dont-pause t
;; Use the maximum amount of decorations by default.
font-lock-maximum-decoration t
;; Always use JIT mode for font-lock.
font-lock-support-mode 'jit-lock-mode
;; Set up font-lock JIT mode to do background parsing.
jit-lock-stealth-time 1.0
jit-lock-stealth-nice 0.03
jit-lock-stealth-load 200
jit-lock-stealth-verbose nil
jit-lock-chunk-size 500
;; Do not reorder text during rendering.
bidi-display-reordering nil)
;;; (Hooks) ;;;
(add-hook 'find-file-hook 'user--rendering-find-file-hook)
;;; (Bindings) ;;;
(user/bind-key-global :emacs :redraw 'redraw-display))
(user--rendering-config)
(provide 'ux/rendering)
;;; rendering.el ends here

34
lisp/ux/scrolling.el Normal file
View File

@@ -0,0 +1,34 @@
;;; scrolling.el --- Configure scrolling in Emacs buffers -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--scrolling-config ()
"Configure Emacs buffer scrolling."
(validate-setq
;; Set distance in line from margin before scrolling commences.
scroll-margin 5
;; Prevent cursor from jumping to center of window on scroll.
scroll-conservatively 100000
;; Try to maintain screen position when scrolling entire pages.
scroll-preserve-screen-position t)
;;; (Bindings) ;;;
(user/bind-key-global :emacs :recenter 'recenter))
(use-package mwheel
:ensure nil
:if window-system
:config
(validate-setq
;; Scroll five lines when using mouse wheel.
mouse-wheel-scroll-amount '(5 ((shift) . 5))
;; Use constant speed when scrolling with mouse wheel.
mouse-wheel-progressive-speed nil
;; Scroll the window that the cursor is over.
mouse-wheel-follow-mouse t))
(user--scrolling-config)
(provide 'ux/scrolling)
;;; scrolling.el ends here

60
lisp/ux/search-replace.el Normal file
View File

@@ -0,0 +1,60 @@
;;; search-replace.el --- Configuration for searching and replacing -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user--search-replace-config ()
"Initialize Emacs search and replace."
(validate-setq
;; Highlight all visible matches.
search-highlight t
query-replace-highlight t
;; Perform certain commands only on the marked region.
transient-mark-mode t)
;;; (Bindings) ;;;
;; Use regular expression searches by default.
(user/bind-key-global :basic :search-forward 'isearch-forward-regexp)
(user/bind-key-global :basic :search-backward 'isearch-backward-regexp)
(user/bind-key-global :basic :search-files 'find-grep)
;;; (Packages) ;;;
(use-package visual-regexp
:defer
:bind* (([remap query-replace-regexp] . vr/query-replace)
([remap replace-regexp] . vr/replace)))
(use-package replace-with-inflections
:bind (:map search-map
("n" . query-replace-names-with-inflections)))
(use-package anzu
:defer
:diminish anzu-mode
:config
(global-anzu-mode t))
(use-package grep
:defer
:config
(validate-setq
;; Highlight matches when using grep.
grep-highlight-matches t)
(when (eq system-type 'darwin)
(-when-let (gnu-find (executable-find "gfind"))
(validate-setq find-program gnu-find)))
(-when-let (gnu-xargs (executable-find "gxargs"))
(validate-setq xargs-program gnu-xargs))
(use-package wgrep
:defer
:config
(use-package wgrep-helm)
(use-package wgrep-ag
:if (executable-find "ag")))))
(user--search-replace-config)
(provide 'ux/search-replace)
;;; search-replace.el ends here

35
lisp/ux/server.el Normal file
View File

@@ -0,0 +1,35 @@
;;; server.el --- Emacs server setup -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun user/server-save ()
"Save and quickly exit from server edit mode."
(interactive)
(save-buffer)
(server-edit))
(defun user--server-after-init-hook ()
"Initialize Emacs server after init has completed."
(with-feature 'server
(unless (server-running-p)
(server-start)
(when (and (display-graphic-p)
(feature-p 'edit-server))
(edit-server-start)))))
(use-package server
;; Emacs clients regularly causes Emacs to crash on Darwin.
:disabled
:if (not (eq system-type 'darwin))
:ensure nil
:hook (after-init-hook . user--server-after-init-hook)
:config
(use-package edit-server
:if window-system))
(provide 'ux/server)
;;; server.el ends here

40
lisp/ux/sessions.el Normal file
View File

@@ -0,0 +1,40 @@
;;; sessions.el --- Set up Emacs to remember things between sessions -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(use-package recentf
;; Prevent entries from loading tramp resulting in the stable
;; version of CEDET being loaded before devel.
:hook (after-init-hook . recentf-mode)
:config
(validate-setq
recentf-max-saved-items 1000
recentf-exclude '("/elpa/" "/tmp/")
recentf-save-file (path-join *user-cache-directory* "recentf")))
(use-package savehist
:init
;; Must be set before enabling savehist so validate cannot be used
;; here.
(setq-default
savehist-file (path-join *user-cache-directory* "savehist")
;; Save minibuffer history.
savehist-save-minibuffer-history t
;; Additional history to save.
savehist-additional-variables '(search-ring regexp-search-ring kill-ring)
;; Autosave every once in a while.
savehist-autosave-interval 180)
(savehist-mode t))
(use-package saveplace
:config
(validate-setq
;; Location of saveplace cache store.
save-place-file (path-join *user-cache-directory* "saveplace")
;; Enable.
save-place-mode t))
(provide 'ux/sessions)
;;; sessions.el ends here

Some files were not shown because too many files have changed in this diff Show More