Human Readable Emacs Configuration using Org mode
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

970 lines
38 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. #+TITLE: Emacs Configuration
  2. #+AUTHOR: Levi Olson
  3. #+EMAIL: olson.levi@gmail.com
  4. #+DATE: <2019-01-30 Wed>
  5. #+LANGUAGE: en
  6. #+BABEL: :cache yes
  7. #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="public/style.css" />
  8. #+EXPORT_FILE_NAME: index.html
  9. #+PROPERTY: header-args :tangle yes
  10. #+OPTIONS: num:10 whn:nil toc:10 H:10
  11. #+STARTUP: content
  12. * Summary
  13. I've really been wanting to have a nicely formatted emacs config file and this is my attempt at it.
  14. * Required Magic
  15. ** Lexical Binding
  16. #+BEGIN_SRC emacs-lisp :results silent
  17. ;;; -*- lexical-binding: t -*-
  18. ;;; DO NOT EDIT THIS FILE DIRECTLY
  19. ;;; EDIT ~init.org~ instead
  20. #+END_SRC
  21. ** The Magical Glue
  22. The following auto compiles the emacs-lisp within the =init.org= file.
  23. Simply run `org-babel-tangle` to make it RAIN!
  24. #+BEGIN_SRC emacs-lisp :results silent
  25. ;; (setq byte-compile-warnings nil)
  26. (defun tangle-init ()
  27. "If the current buffer is 'init.org' the code-blocks are tangled, and the tangled file is compiled."
  28. (when (equal (buffer-file-name)
  29. (expand-file-name (concat user-emacs-directory "init.org")))
  30. ;; Avoid running hooks when tangling.
  31. (let ((prog-mode-hook nil))
  32. (org-babel-tangle)
  33. (byte-compile-file (concat user-emacs-directory "init.el")))))
  34. (add-hook 'after-save-hook 'tangle-init)
  35. #+END_SRC
  36. * Config
  37. ** Packages
  38. #+BEGIN_SRC emacs-lisp :results silent
  39. (require 'package)
  40. (defvar my-packages
  41. '(all-the-icons
  42. anzu
  43. base16-theme
  44. bbdb
  45. better-defaults
  46. company
  47. company-go
  48. counsel
  49. counsel-projectile
  50. dash-at-point
  51. diminish
  52. dockerfile-mode
  53. doom-modeline
  54. doom-themes
  55. ein
  56. eldoc-eval
  57. elpy
  58. expand-region
  59. fic-mode
  60. gitignore-mode
  61. go-mode
  62. go-playground
  63. gorepl-mode
  64. flycheck
  65. iedit
  66. ivy
  67. ivy-hydra
  68. json-mode
  69. magit
  70. material-theme
  71. multiple-cursors
  72. nnir-est
  73. projectile
  74. py-autopep8
  75. rainbow-delimiters
  76. shrink-path
  77. tide
  78. typescript-mode
  79. use-package
  80. web-mode
  81. which-key))
  82. (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
  83. (add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/"))
  84. (when (not package-archive-contents)
  85. (package-refresh-contents))
  86. (package-initialize)
  87. (dolist (p my-packages)
  88. (when (not (package-installed-p p))
  89. (package-install p)))
  90. #+END_SRC
  91. ** Server
  92. #+BEGIN_SRC emacs-lisp :results silent
  93. (require 'edit-server)
  94. (edit-server-start)
  95. #+END_SRC
  96. ** Better Defaults
  97. #+BEGIN_SRC emacs-lisp :results silent
  98. (require 'better-defaults)
  99. ;; Instead of the annoying giant warning icon, just flash the modeline.
  100. ;; (this happens when you do something like C-g)
  101. (setq ring-bell-function
  102. (lambda ()
  103. (let ((orig-fg (face-foreground 'mode-line)))
  104. (set-face-foreground 'mode-line "#F2804F")
  105. (run-with-idle-timer 0.1 nil
  106. (lambda (fg) (set-face-foreground 'mode-line fg))
  107. orig-fg))))
  108. (defun set-frame-size-according-to-resolution ()
  109. "Set the Emacs window size on startup."
  110. (interactive)
  111. (if window-system
  112. (progn
  113. ;; WIDTH
  114. (if (> (x-display-pixel-width) 1280)
  115. ;; Large Screen (only show 120 cols)
  116. (add-to-list 'default-frame-alist (cons 'width 240))
  117. ;; Small Screen (fill window)
  118. (add-to-list 'default-frame-alist (cons 'width (/ (x-display-pixel-width) (frame-char-width)))))
  119. ;; HEIGHT
  120. (if (> (x-display-pixel-height) 1080)
  121. ;; Large Screen (only fill half screen)
  122. (add-to-list 'default-frame-alist (cons 'height (/ (/ (x-display-pixel-height) 2)
  123. (frame-char-height))))
  124. ;; Small Screen (fill window)
  125. (add-to-list 'default-frame-alist (cons 'height (/ (x-display-pixel-height) (frame-char-height)))))
  126. )))
  127. (set-frame-size-according-to-resolution)
  128. (defun window-px-width ()
  129. "Get the width of the Emacs window in pixels."
  130. (interactive)
  131. (* (* (window-total-width) 2.874) (frame-char-width)))
  132. (defun window-px-left-pos ()
  133. "Calculate the left position of the Emacs window."
  134. (interactive)
  135. (/ (- (x-display-pixel-width) (window-px-width)) 2))
  136. (add-to-list 'default-frame-alist (cons 'top 0))
  137. (add-to-list 'default-frame-alist (cons 'left 1000))
  138. #+END_SRC
  139. ** Enable Disabled Commands
  140. #+BEGIN_SRC emacs-lisp :results silent
  141. (put 'narrow-to-region 'disabled nil)
  142. (put 'upcase-region 'disabled nil)
  143. (put 'downcase-region 'disabled nil)
  144. #+END_SRC
  145. ** Splash Screen
  146. #+BEGIN_SRC emacs-lisp :results silent
  147. (setq inhibit-splash-screen nil
  148. fancy-splash-image "~/.emacs.d/public/emacs-logo.png"
  149. fancy-splash-image-file "~/.emacs.d/public/emacs-logo.png")
  150. #+END_SRC
  151. ** Basic Customization
  152. #+BEGIN_SRC emacs-lisp :results silent
  153. (defvar backup-dir (expand-file-name "~/.emacs.d/backup/"))
  154. (defvar autosave-dir (expand-file-name "~/.emacs.d/autosave/"))
  155. (setq initial-scratch-message nil
  156. backup-directory-alist (list (cons ".*" backup-dir))
  157. auto-save-list-file-prefix autosave-dir
  158. auto-save-file-name-transforms `((".*" ,autosave-dir t)))
  159. (menu-bar-mode 0)
  160. (scroll-bar-mode 0)
  161. (tool-bar-mode 0)
  162. ;; (load-theme 'doom-city-lights t)
  163. ;; (load-theme 'doom-dracula t)
  164. ;; (load-theme 'doom-nord t)
  165. (load-theme 'doom-one t)
  166. ;; (load-theme 'doom-spacegrey t)
  167. ;; (load-theme 'base16-ocean t)
  168. (load-theme 'base16-onedark t)
  169. (global-linum-mode t)
  170. (global-auto-revert-mode t)
  171. (defalias 'yes-or-no-p 'y-or-n-p)
  172. #+END_SRC
  173. ** Custom Modes
  174. #+BEGIN_SRC emacs-lisp :results silent
  175. (require 'font-lock)
  176. (defvar openhab-mode-hook nil)
  177. (defvar openhab-mode-map
  178. (let ((map (make-keymap)))
  179. (define-key map "\C-j" 'newline-and-indent)
  180. map)
  181. "Keymap for OPENHAB major mode.")
  182. (add-to-list 'auto-mode-alist '("\\.sitemap\\'" . openhab-mode))
  183. (add-to-list 'auto-mode-alist '("\\.items\\'" . openhab-mode))
  184. (add-to-list 'auto-mode-alist '("\\.rules\\'" . openhab-mode))
  185. (add-to-list 'auto-mode-alist '("\\.things\\'" . openhab-mode))
  186. (defconst openhab-font-lock-keywords
  187. `(
  188. ("\<.*\>" . font-lock-constant-face)
  189. (,(regexp-opt
  190. '(
  191. ;; KEYWORDS
  192. "Selection" "Slider" "List" "Setpoint" "Video" "Chart" "Webview" "Colorpicker"
  193. "Timer" "Number" "String"
  194. "Switch" "Rollershutter" "Number" "String" "Dimmer" "Contact" "DateTime" "Color"
  195. "Text" "Group" "Image" "Frame"
  196. "Thing" "Bridge"
  197. "Time" "System"
  198. "sitemap"
  199. "rule" "when" "then" "end"
  200. "if" "val"
  201. "import" "var" "say" "postUpdate" "switch" "println" "case" "or" "sendCommand"
  202. )
  203. 'words)
  204. (1 font-lock-keyword-face))
  205. (,(regexp-opt
  206. '(
  207. "ON" "OFF" "on" "off"
  208. "AND" "OR" "NAND" "NOR" "AVG" "SUM" "MAX" "MIN"
  209. "true" "false"
  210. )
  211. 'words)
  212. (1 font-lock-constant-face))
  213. (,(regexp-opt
  214. '(
  215. "name" "label" "item" "period" "refresh" "icon" "mappings" "minValue" "maxValue" "step" "switchsupport" "url" "height" "refresh" "visibility" "valuecolor"
  216. )
  217. 'words)
  218. (1 font-lock-type-face))
  219. ("\(.*\)" . font-lock-variable-name-face)
  220. ("[^a-zA-Z0-9_:]\\([0-9]*\\)[^a-zA-Z0-9_:]" . (1 font-lock-variable-name-face))
  221. ("\s@\s" . font-lock-variable-name-face)
  222. ("\s\\([a-zA-Z0-9_:]*\\)\\(\s\\|$\\)" . (1 font-lock-type-face))
  223. ("=\\([a-zA-Z_]*\\)" . (1 font-lock-string-face))
  224. ("\\([a-zA-Z]*\\)=" . (1 font-lock-type-face))
  225. )
  226. "The regexps to highlight in openHAB mode.")
  227. (defvar openhab-mode-syntax-table
  228. (let ((st (make-syntax-table)))
  229. (modify-syntax-entry ?/ ". 12b" st) ;; C-style comments // ...
  230. (modify-syntax-entry ?\n "> b" st) ;; \n ends comment
  231. ;; Block comments /*...*/
  232. (modify-syntax-entry ?\/ ". 14" st)
  233. (modify-syntax-entry ?* ". 23" st)
  234. st)
  235. "Syntax table for openhab-mode.")
  236. (defun openhab-mode ()
  237. "Major mode for editing OPENHAB config files."
  238. (interactive)
  239. (kill-all-local-variables)
  240. (set-syntax-table openhab-mode-syntax-table)
  241. (use-local-map openhab-mode-map)
  242. (set (make-local-variable 'font-lock-defaults) '(openhab-font-lock-keywords nil t))
  243. (electric-pair-mode -1)
  244. (flycheck-mode -1)
  245. (setq major-mode 'openhab-mode)
  246. (setq mode-name "OpenHAB")
  247. (run-hooks 'openhab-mode-hook))
  248. (provide 'openhab-mode)
  249. #+END_SRC
  250. ** Tools
  251. *** General
  252. #+BEGIN_SRC emacs-lisp :results silent
  253. (require 'which-key)
  254. (which-key-setup-minibuffer)
  255. (which-key-mode)
  256. (require 'fic-mode)
  257. (add-hook 'js-mode-hook 'fic-mode)
  258. #+END_SRC
  259. *** Company
  260. #+BEGIN_SRC emacs-lisp :results silent
  261. (require 'company)
  262. (add-hook 'after-init-hook 'global-company-mode)
  263. (setq company-dabbrev-downcase nil)
  264. (setq company-idle-delay 0.1)
  265. #+END_SRC
  266. *** Diminish
  267. #+BEGIN_SRC emacs-lisp :results silent
  268. (require 'diminish)
  269. (diminish 'auto-revert-mode)
  270. (eval-after-load "company" '(diminish 'company-mode))
  271. (eval-after-load "counsel" '(diminish 'counsel-mode))
  272. (eval-after-load "elpy" '(diminish 'elpy-mode))
  273. (eval-after-load "go-mode" '(diminish 'go-mode))
  274. (eval-after-load "go-playground" '(diminish 'go-playground-mode))
  275. (eval-after-load "gorepl-mode" '(diminish 'gorepl-mode))
  276. (eval-after-load "flycheck" '(diminish 'flycheck-mode))
  277. (eval-after-load "ivy" '(diminish 'ivy-mode))
  278. (eval-after-load "projectile" '(diminish 'projectile-mode))
  279. (eval-after-load "which-key" '(diminish 'which-key-mode))
  280. #+END_SRC
  281. *** Dired
  282. #+BEGIN_SRC emacs-lisp :results silent
  283. (defun dired-mode-setup ()
  284. "Will run as hook for `dired-mode'."
  285. (dired-hide-details-mode 1))
  286. (add-hook 'dired-mode-hook 'dired-mode-setup)
  287. #+END_SRC
  288. *** Ivy
  289. #+BEGIN_SRC emacs-lisp :results silent
  290. (require 'ivy-hydra)
  291. (require 'ivy)
  292. (require 'swiper)
  293. (ivy-mode 1)
  294. (counsel-mode)
  295. (setq ivy-use-virtual-buffers t
  296. enable-recursive-minibuffers t
  297. ivy-height 25
  298. ivy-initial-inputs-alist nil
  299. ivy-extra-directories nil)
  300. (global-set-key (kbd "C-s") 'swiper)
  301. (global-set-key (kbd "C-c C-r") 'ivy-resume)
  302. (global-set-key (kbd "M-x") 'counsel-M-x)
  303. (global-set-key (kbd "C-x C-f") 'counsel-find-file)
  304. (global-set-key (kbd "C-c g") 'counsel-git)
  305. (global-set-key (kbd "C-c j") 'counsel-git-grep)
  306. (global-set-key (kbd "C-c k") 'counsel-ag)
  307. (define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history)
  308. (defun ivy-open-current-typed-path ()
  309. (interactive)
  310. (when ivy--directory
  311. (let* ((dir ivy--directory)
  312. (text-typed ivy-text)
  313. (path (concat dir text-typed)))
  314. (delete-minibuffer-contents)
  315. (ivy--done path))))
  316. (define-key ivy-minibuffer-map (kbd "<return>") 'ivy-alt-done)
  317. (define-key ivy-minibuffer-map (kbd "C-f") 'ivy-open-current-typed-path)
  318. #+END_SRC
  319. *** Magit
  320. #+BEGIN_SRC emacs-lisp :results silent
  321. (require 'magit)
  322. (global-set-key (kbd "C-x g") 'magit-status)
  323. (global-set-key (kbd "C-c g") 'magit-status)
  324. (setq magit-completing-read-function 'ivy-completing-read)
  325. #+END_SRC
  326. *** Mu4e
  327. #+BEGIN_SRC emacs-lisp :results silent
  328. (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu/mu4e")
  329. (require 'mu4e)
  330. ;; default
  331. (setq mu4e-maildir "~/Mail"
  332. mu4e-mu-binary "/usr/local/bin/mu"
  333. mu4e-get-mail-command "offlineimap" ;; Allow updating with the "U" command
  334. mu4e-sent-messages-behavior 'delete ;; Delete sent messages
  335. mu4e-view-show-images t ;; attempt to show images
  336. mu4e-view-image-max-width 400 ;; max image size
  337. message-kill-buffer-on-exit t ;; don't keep messages around
  338. mu4e-use-fancy-chars t ;; use 'fancy' chars
  339. mu4e-update-interval 300 ;; 5 mins
  340. )
  341. (setq mu4e-contexts
  342. `( ,(make-mu4e-context
  343. :name "Vlocity"
  344. :enter-func (lambda () (mu4e-message "Entering Vlocity"))
  345. :leave-func (lambda () (mu4e-message "Leaving Vlocity"))
  346. ;; we match based on the contact-fields of the message
  347. :match-func (lambda (msg)
  348. (when msg
  349. (string= (mu4e-message-field msg :maildir) "/Vlocity")))
  350. :vars '( ( user-mail-address . "lolson@vlocity.com" )
  351. ( smtpmail-mail-address . "lolson@vlocity.com" )
  352. ( user-full-name . "Levi Olson" )
  353. ( mu4e-compose-signature .
  354. (concat
  355. "--\n"
  356. "Levi Olson\n"
  357. "Senior UI Developer"))
  358. ( mu4e-sent-folder . "/Vlocity/[Gmail].Sent Mail" )
  359. ( mu4e-drafts-folder . "/Vlocity/[Gmail].Drafts" )
  360. ( mu4e-trash-folder . "/Vlocity/[Gmail].Trash" )
  361. ( mu4e-maildir-shortcuts . (("/Vlocity/INBOX" . ?i)
  362. ("/Vlocity/[Gmail].Sent Mail" . ?s)
  363. ("/Vlocity/[Gmail].Trash" . ?t)
  364. ("/Vlocity/[Gmail].All Mail" . ?a)))))
  365. ,(make-mu4e-context
  366. :name "Gmail"
  367. :enter-func (lambda () (mu4e-message "Entering Gmail"))
  368. :leave-func (lambda () (mu4e-message "Leaving Gmail"))
  369. ;; this matches maildir /Arkham and its sub-directories
  370. :match-func (lambda (msg)
  371. (when msg
  372. (string= (mu4e-message-field msg :maildir) "/Gmail")))
  373. :vars '( ( user-mail-address . "olson.levi@gmail.com" )
  374. ( smtpmail-mail-address . "olson.levi@gmail.com" )
  375. ( user-full-name . "Levi Olson" )
  376. ( mu4e-compose-signature .
  377. (concat
  378. "--\n"
  379. "Levi\n"))
  380. ( mu4e-sent-folder . "/Gmail/[Gmail].Sent Mail" )
  381. ( mu4e-drafts-folder . "/Gmail/[Gmail].Drafts" )
  382. ( mu4e-trash-folder . "/Gmail/[Gmail].Trash" )
  383. ( mu4e-maildir-shortcuts . (("/Gmail/INBOX" . ?i)
  384. ("/Gmail/[Gmail].Sent Mail" . ?s)
  385. ("/Gmail/[Gmail].Trash" . ?t)
  386. ("/Gmail/[Gmail].All Mail" . ?a))
  387. )))))
  388. ;; (defcustom smtpmail-smtp-user nil
  389. ;; "User name to use when looking up credentials in the authinfo file.
  390. ;; If non-nil, only consider credentials for the specified user."
  391. ;; :version "24.1"
  392. ;; :type '(choice (const nil) string)
  393. ;; :group 'smtpmail)
  394. ;; How to handle HTML emails
  395. ;; (setq mu4e-html2text-command "textutil -stdin -format html -convert txt -stdout")
  396. ;; Add option to view HTML in browser
  397. (add-to-list 'mu4e-headers-actions
  398. '("in browser" . mu4e-action-view-in-browser) t)
  399. (add-to-list 'mu4e-view-actions
  400. '("in browser" . mu4e-action-view-in-browser) t)
  401. #+END_SRC
  402. *** Projectile
  403. #+BEGIN_SRC emacs-lisp :results silent
  404. (require 'projectile)
  405. (require 'counsel-projectile)
  406. (projectile-mode)
  407. (setq projectile-mode-line '(:eval (format " %s" (projectile-project-name)))
  408. projectile-remember-window-configs t
  409. projectile-completion-system 'ivy)
  410. (counsel-projectile-mode)
  411. #+END_SRC
  412. ** Development Specific
  413. *** General
  414. #+BEGIN_SRC emacs-lisp :results silent
  415. (require 'rainbow-delimiters)
  416. (global-flycheck-mode)
  417. (add-hook 'before-save-hook 'delete-trailing-whitespace)
  418. (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
  419. (setq-default indent-tabs-mode nil
  420. tab-width 4)
  421. (defvaralias 'c-basic-offset 'tab-width)
  422. (defvaralias 'cperl-indent-level 'tab-width)
  423. (electric-pair-mode 1)
  424. (show-paren-mode 1)
  425. (require 'dockerfile-mode)
  426. (add-to-list 'auto-mode-alist '("Dockerfile*\\'" . dockerfile-mode))
  427. (require 'gitignore-mode)
  428. (add-to-list 'auto-mode-alist '("gitignore\\'" . gitignore-mode))
  429. (require 'json-mode)
  430. (add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode))
  431. (require 'web-mode)
  432. (add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
  433. #+END_SRC
  434. *** Python
  435. #+BEGIN_SRC emacs-lisp :results silent
  436. (elpy-enable)
  437. (setq python-shell-interpreter "jupyter"
  438. python-shell-interpreter-args "console --simple-prompt")
  439. (when (require 'flycheck nil t)
  440. (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
  441. (add-hook 'elpy-mode-hook 'flycheck-mode))
  442. (require 'py-autopep8)
  443. (setq py-autopep8-options '("--ignore=E501"))
  444. (add-hook 'elpy-mode-hook 'py-autopep8-enable-on-save)
  445. #+END_SRC
  446. *** Go
  447. #+BEGIN_SRC emacs-lisp :results silent
  448. (require 'go-mode)
  449. (require 'go-playground)
  450. (require 'gorepl-mode)
  451. (require 'company-go)
  452. (add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode))
  453. (add-hook 'go-mode-hook (lambda ()
  454. (add-hook 'before-save-hook 'gofmt-before-save)
  455. (local-set-key (kbd "M-.") 'godef-jump)
  456. (local-set-key (kbd "M-,") 'pop-tag-mark)
  457. (local-set-key (kbd "C-c C-c") (lambda ()
  458. (interactive)
  459. (ansi-term)
  460. (comint-send-string "*ansi-term*" "make\n")))
  461. (set (make-local-variable 'company-backends) '(company-go))
  462. (setq company-tooltip-limit 20
  463. company-echo-delay 0
  464. company-begin-commands '(self-insert-command))
  465. (gorepl-mode)))
  466. (defun set-exec-path-from-shell-PATH ()
  467. (let ((path-from-shell (replace-regexp-in-string
  468. "[ \t\n]*$"
  469. ""
  470. (shell-command-to-string "$SHELL --login -i -c 'echo $PATH'"))))
  471. (setenv "PATH" path-from-shell)
  472. (setq eshell-path-env path-from-shell)
  473. (setq exec-path (split-string path-from-shell path-separator))))
  474. (when window-system (set-exec-path-from-shell-PATH))
  475. (setenv "GOPATH" "/Users/leviolson/go")
  476. (add-to-list 'exec-path "/Users/leviolson/go/bin")
  477. #+END_SRC
  478. *** TypeScript
  479. #+BEGIN_SRC emacs-lisp :results silent
  480. (defun setup-tide-mode ()
  481. "Tide setup function."
  482. (interactive)
  483. (tide-setup)
  484. (flycheck-mode +1)
  485. (setq flycheck-check-syntax-automatically '(save mode-enabled))
  486. (eldoc-mode +1)
  487. (tide-hl-identifier-mode +1)
  488. (company-mode +1))
  489. ;; aligns annotation to the right hand side
  490. (setq company-tooltip-align-annotations t)
  491. ;; formats the buffer before saving
  492. (add-hook 'before-save-hook 'tide-format-before-save)
  493. (add-hook 'typescript-mode-hook #'setup-tide-mode)
  494. (require 'typescript-mode)
  495. (require 'tide)
  496. (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))
  497. (add-hook 'typescript-mode-hook
  498. '(lambda ()
  499. (set (make-local-variable 'company-backends) '(company-tide))
  500. (setq company-tooltip-limit 20
  501. company-echo-delay 0
  502. company-begin-commands '(self-insert-command)
  503. tide-format-options '(:insertSpaceAfterFunctionKeywordForAnonymousFunctions t :placeOpenBraceOnNewLineForFunctions nil))
  504. (tide-setup)))
  505. #+END_SRC
  506. **** TSX
  507. #+BEGIN_SRC emacs-lisp :results silent
  508. (require 'web-mode)
  509. (add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))
  510. (add-hook 'web-mode-hook
  511. (lambda ()
  512. (when (string-equal "tsx" (file-name-extension buffer-file-name))
  513. (setup-tide-mode))))
  514. ;; enable typescript-tslint checker
  515. (flycheck-add-mode 'typescript-tslint 'web-mode)
  516. #+END_SRC
  517. **** JSX
  518. #+BEGIN_SRC emacs-lisp :results silent
  519. (require 'web-mode)
  520. (add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
  521. (add-hook 'web-mode-hook
  522. (lambda ()
  523. (when (string-equal "jsx" (file-name-extension buffer-file-name))
  524. (setup-tide-mode))))
  525. ;; configure jsx-tide checker to run after your default jsx checker
  526. (flycheck-add-mode 'javascript-eslint 'web-mode)
  527. (flycheck-add-next-checker 'javascript-eslint 'jsx-tide 'append)
  528. #+END_SRC
  529. *** Org
  530. #+BEGIN_SRC emacs-lisp :results silent
  531. (org-babel-do-load-languages
  532. 'org-babel-load-languages
  533. '((js . t)
  534. (shell . t)
  535. (emacs-lisp . t)))
  536. (defvar org-src-tab-acts-natively)
  537. (setq org-src-tab-acts-natively t)
  538. ;; (setenv "NODE_PATH"
  539. ;; (getenv "NODE_PATH"))
  540. (defvar org-confirm-babel-evaluate)
  541. (defun my-org-confirm-babel-evaluate (lang body)
  542. "Execute certain languages without confirming.
  543. Takes LANG to allow and BODY to execute."
  544. (not (or (string= lang "js")
  545. (string= lang "restclient")
  546. (string= lang "emacs-lisp")
  547. (string= lang "shell"))))
  548. (setq org-confirm-babel-evaluate #'my-org-confirm-babel-evaluate)
  549. (add-to-list 'org-structure-template-alist
  550. (list "e" (concat "#+BEGIN_SRC emacs-lisp :results silent\n"
  551. "\n"
  552. "#+END_SRC")))
  553. (add-to-list 'org-structure-template-alist
  554. (list "j" (concat "#+BEGIN_SRC js :cmd \"babel-node\"\n"
  555. "\n"
  556. "#+END_SRC")))
  557. (add-to-list 'org-structure-template-alist
  558. (list "r" (concat "#+BEGIN_SRC restclient :results raw\n"
  559. "\n"
  560. "#+END_SRC")))
  561. #+END_SRC
  562. ** Functions
  563. #+BEGIN_SRC emacs-lisp :results silent
  564. (defun find-user-init-file ()
  565. "Edit the `~/.emacs.d/init.org' file."
  566. (interactive)
  567. (find-file "~/.emacs.d/init.org"))
  568. (defun load-user-init-file ()
  569. "LO: Reload the `~/.emacs.d/init.elc' file."
  570. (interactive)
  571. (load-file "~/.emacs.d/init.elc"))
  572. (defun jump-to-symbol-internal (&optional backwardp)
  573. "Jumps to the next symbol near the point if such a symbol exists. If BACKWARDP is non-nil it jumps backward."
  574. (let* ((point (point))
  575. (bounds (find-tag-default-bounds))
  576. (beg (car bounds)) (end (cdr bounds))
  577. (str (isearch-symbol-regexp (find-tag-default)))
  578. (search (if backwardp 'search-backward-regexp
  579. 'search-forward-regexp)))
  580. (goto-char (if backwardp beg end))
  581. (funcall search str nil t)
  582. (cond ((<= beg (point) end) (goto-char point))
  583. (backwardp (forward-char (- point beg)))
  584. (t (backward-char (- end point))))))
  585. (defun jump-to-previous-like-this ()
  586. "Jumps to the previous occurrence of the symbol at point."
  587. (interactive)
  588. (jump-to-symbol-internal t))
  589. (defun jump-to-next-like-this ()
  590. "Jumps to the next occurrence of the symbol at point."
  591. (interactive)
  592. (jump-to-symbol-internal))
  593. (defun match-paren (arg)
  594. "Go to the matching paren if on a paren; otherwise insert ARG (a literal % sign)."
  595. (interactive "p")
  596. (cond ((looking-at "\\s(") (forward-list 1))
  597. ((looking-back "\\s(" 2) (backward-char 1) (forward-list 1))
  598. ((looking-at "\\s)") (forward-char 1) (backward-list 1))
  599. ((looking-back "\\s)" 2) (backward-list 1))
  600. (t (self-insert-command (or arg 1)))))
  601. (defun kill-this-buffer-unless-scratch ()
  602. "Works like `kill-this-buffer' unless the current buffer is the *scratch* buffer. In which case the buffer content is deleted and the buffer is buried."
  603. (interactive)
  604. (if (not (string= (buffer-name) "*scratch*"))
  605. (kill-this-buffer)
  606. (delete-region (point-min) (point-max))
  607. (switch-to-buffer (other-buffer))
  608. (bury-buffer "*scratch*")))
  609. (defun delete-backward-sentence ()
  610. "LO: Delete to the beginning of the sentence/line."
  611. (interactive)
  612. (delete-region (point) (progn (backward-sentence) (point))))
  613. (defun delete-backward-to-boundary (arg)
  614. "LO: Delete backward to the previous word boundary. With ARG, do this many times."
  615. (interactive "p")
  616. (let ((a (point))
  617. (b (progn
  618. (backward-word arg)
  619. (forward-word)
  620. (point))))
  621. (if (< a b)
  622. (delete-region a (progn (backward-word arg) (point)))
  623. (if (= a b)
  624. (delete-region a (progn (backward-word arg) (point)))
  625. (delete-region a b)))))
  626. (defun comment-or-uncomment-region-or-line ()
  627. "Comments or uncomments the region or the current line if there's no active region."
  628. (interactive)
  629. (let (beg end)
  630. (if (region-active-p)
  631. (setq beg (region-beginning) end (region-end))
  632. (setq beg (line-beginning-position) end (line-end-position)))
  633. (comment-or-uncomment-region beg end)))
  634. (defun fold-toggle (column)
  635. "Code folding by COLUMN."
  636. (interactive "P")
  637. (set-selective-display
  638. (or column
  639. (unless selective-display
  640. (1+ (current-column))))))
  641. (defun new-line-below ()
  642. "LO: Create a new line below current line."
  643. (interactive)
  644. (move-end-of-line 1)
  645. (newline-and-indent))
  646. (defun new-line-above ()
  647. "LO: Create a new line above current line."
  648. (interactive)
  649. (move-beginning-of-line 1)
  650. (newline)
  651. (forward-line -1))
  652. (defun duplicate-thing (comment)
  653. "LO: Duplicates the current line, or the region if active. If an argument (COMMENT) is given, the duplicated region will be commented out."
  654. (interactive "P")
  655. (save-excursion
  656. (let ((start (if (region-active-p) (region-beginning) (point-at-bol)))
  657. (end (if (region-active-p) (region-end) (point-at-eol))))
  658. (goto-char end)
  659. (unless (region-active-p)
  660. (newline))
  661. (insert (buffer-substring start end))
  662. (when comment (comment-region start end)))))
  663. (defun tidy ()
  664. "LO: Ident, untabify and unwhitespacify current buffer, or region if active."
  665. (interactive)
  666. (let ((beg (if (region-active-p) (region-beginning) (point-min)))
  667. (end (if (region-active-p) (region-end) (point-max))))
  668. (let ((inhibit-message t))
  669. (indent-region beg end))
  670. (whitespace-cleanup)
  671. (untabify beg (if (< end (point-max)) end (point-max)))
  672. (if (region-active-p) (message "Indenting Region...Done") (message "Indenting File...Done"))))
  673. (defun phil-columns ()
  674. "LO: Good 'ol Phil-Columns."
  675. (interactive)
  676. (message "Good 'ol fill-columns")
  677. (with-output-to-temp-buffer "*PHIL-COLUMN*"
  678. (shell-command "mpv --no-video 'https://www.youtube.com/watch?v=YkADj0TPrJA&t=3m16s' > /dev/null 2>&1 & sleep 8; pkill mpv"))
  679. (other-window 1)
  680. (delete-window))
  681. (declare-function first "Goto FIRST shell.")
  682. (declare-function goto-non-shell-buffer "Goto something other than a shell buffer.")
  683. (declare-function switch-shell "Switch shell.")
  684. (let ((last-shell ""))
  685. (defun toggle-shell ()
  686. (interactive)
  687. (cond ((string-match-p "^\\*shell<[1-9][0-9]*>\\*$" (buffer-name))
  688. (goto-non-shell-buffer))
  689. ((get-buffer last-shell) (switch-to-buffer last-shell))
  690. (t (shell (setq last-shell "*shell<1>*")))))
  691. (defun switch-shell (n)
  692. (let ((buffer-name (format "*shell<%d>*" n)))
  693. (setq last-shell buffer-name)
  694. (cond ((get-buffer buffer-name)
  695. (switch-to-buffer buffer-name))
  696. (t (shell buffer-name)
  697. (rename-buffer buffer-name)))))
  698. (defun goto-non-shell-buffer ()
  699. (let* ((r "^\\*shell<[1-9][0-9]*>\\*$")
  700. (shell-buffer-p (lambda (b) (string-match-p r (buffer-name b))))
  701. (non-shells (cl-remove-if shell-buffer-p (buffer-list))))
  702. (when non-shells
  703. (switch-to-buffer (first non-shells))))))
  704. (defadvice shell (after kill-with-no-query nil activate)
  705. "."
  706. (set-process-query-on-exit-flag (get-buffer-process ad-return-value) nil))
  707. (declare-function comint-truncate-buffer ".")
  708. (defun clear-comint ()
  709. "Run `comint-truncate-buffer' with the `comint-buffer-maximum-size' set to zero."
  710. (interactive)
  711. (let ((comint-buffer-maximum-size 0))
  712. (comint-truncate-buffer)))
  713. (defun c-setup ()
  714. "Compile."
  715. (local-set-key (kbd "C-c C-c") 'compile))
  716. #+END_SRC
  717. ** Bindings
  718. #+BEGIN_SRC emacs-lisp :results silent
  719. (require 'company)
  720. (add-hook 'comint-mode-hook (lambda () (local-set-key (kbd "C-l") 'clear-comint)))
  721. (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
  722. (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode)
  723. (add-hook 'c-mode-common-hook 'c-setup)
  724. (add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
  725. (defvar company-active-map (make-keymap)
  726. "Company Mode keymap.")
  727. (defvar custom-bindings (make-keymap)
  728. "A keymap of custom bindings.")
  729. (define-key global-map (kbd "M-p") 'jump-to-previous-like-this)
  730. (define-key global-map (kbd "M-n") 'jump-to-next-like-this)
  731. (define-key global-map (kbd "M-<tab>") 'switch-to-next-buffer)
  732. (define-key global-map (kbd "M-<backspace>")'delete-backward-to-boundary)
  733. (define-key global-map (kbd "C-<backspace>")'delete-backward-to-boundary)
  734. (global-set-key (kbd "C-S-<down>") 'mc/mark-next-like-this)
  735. (global-set-key (kbd "C->") 'mc/mark-next-like-this-symbol)
  736. (global-set-key (kbd "C-S-<up>") 'mc/mark-previous-like-this)
  737. (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
  738. (global-set-key (kbd "C-c C->") 'mc/mark-all-like-this)
  739. (global-set-key "%" 'match-paren)
  740. (global-set-key (kbd "C-x .") 'dash-at-point)
  741. (global-set-key (kbd "C-x ,") 'dash-at-point-with-docset)
  742. (global-set-key (kbd "C-s") (lambda () (interactive) (swiper (format "%s" (thing-at-point 'symbol)))))
  743. (global-set-key (kbd "M-m") 'mu4e)
  744. ;; (dolist (n (number-sequence 1 9))
  745. ;; (global-set-key (kbd (concat "M-" (int-to-string n)))
  746. ;; (lambda () (interactive) (switch-shell n))))
  747. (define-key company-active-map (kbd "C-d") 'company-show-doc-buffer)
  748. (define-key company-active-map (kbd "C-n") 'company-select-next)
  749. (define-key company-active-map (kbd "C-p") 'company-select-previous)
  750. (define-key company-active-map (kbd "<tab>") 'company-complete)
  751. (define-key custom-bindings (kbd "C-c p") 'counsel-projectile-switch-project)
  752. (define-key custom-bindings (kbd "C-c f") 'counsel-projectile-find-file)
  753. (define-key custom-bindings (kbd "C-c m") 'magit-status)
  754. (define-key custom-bindings (kbd "C-c D") 'define-word-at-point)
  755. (define-key custom-bindings (kbd "C-@") 'er/expand-region)
  756. (define-key custom-bindings (kbd "C-#") 'er/contract-region)
  757. (define-key custom-bindings (kbd "C-S-c C-S-c") 'mc/edit-lines)
  758. (define-key custom-bindings (kbd "C-c b") 'ivy-switch-buffer)
  759. (define-key custom-bindings (kbd "C-c l") 'org-store-link)
  760. (define-key custom-bindings (kbd "C-c t") 'org-set-tags)
  761. (define-key custom-bindings (kbd "M-u") 'upcase-dwim)
  762. (define-key custom-bindings (kbd "M-c") 'capitalize-dwim)
  763. (define-key custom-bindings (kbd "M-l") 'downcase-dwim)
  764. (define-key custom-bindings (kbd "M-o") 'other-window)
  765. (define-key custom-bindings (kbd "C-c s") 'ispell-word)
  766. (define-key custom-bindings (kbd "C-c C-d") 'org-capture)
  767. (define-key custom-bindings (kbd "C-c <up>") 'windmove-up)
  768. (define-key custom-bindings (kbd "C-c <down>") 'windmove-down)
  769. (define-key custom-bindings (kbd "C-c <left>") 'windmove-left)
  770. (define-key custom-bindings (kbd "C-c <right>") 'windmove-right)
  771. (define-key custom-bindings (kbd "C-c a") (lambda () (interactive) (org-agenda nil "n")))
  772. (define-key custom-bindings (kbd "C-c e") 'find-user-init-file)
  773. (define-key custom-bindings (kbd "C-x f") 'phil-columns)
  774. (define-key custom-bindings (kbd "C-x k") 'kill-this-buffer-unless-scratch)
  775. (define-key custom-bindings (kbd "C-c d") 'duplicate-thing)
  776. (define-key custom-bindings (kbd "C-c c") 'comment-or-uncomment-region-or-line)
  777. (define-key custom-bindings (kbd "C-;") 'comment-or-uncomment-region-or-line)
  778. (define-key custom-bindings (kbd "C-o") 'new-line-below)
  779. (define-key custom-bindings (kbd "C-S-o") 'new-line-above)
  780. (define-key custom-bindings (kbd "<C-tab>") 'tidy)
  781. (define-key custom-bindings (kbd "M-q") 'kill-this-buffer)
  782. (define-key custom-bindings (kbd "M-RET") '(lambda () (interactive) (term (getenv "SHELL"))))
  783. (define-minor-mode custom-bindings-mode
  784. "A mode that activates custom-bindings."
  785. t nil custom-bindings)
  786. #+END_SRC
  787. ** UI
  788. #+BEGIN_SRC emacs-lisp :results silent
  789. (cond ((member "PragmataPro" (font-family-list))
  790. (set-face-attribute 'default nil :font "PragmataPro-14")))
  791. #+END_SRC
  792. *** Doom Modeline
  793. #+BEGIN_SRC emacs-lisp :results silent
  794. (require 'doom-modeline)
  795. (doom-modeline-mode 1)
  796. ;; How tall the mode-line should be (only respected in GUI Emacs).
  797. (setq doom-modeline-height 35)
  798. ;; How wide the mode-line bar should be (only respected in GUI Emacs).
  799. (setq doom-modeline-bar-width 4)
  800. ;; Determines the style used by `doom-modeline-buffer-file-name'.
  801. ;;
  802. ;; Given ~/Projects/FOSS/emacs/lisp/comint.el
  803. ;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el
  804. ;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
  805. ;; truncate-with-project => emacs/l/comint.el
  806. ;; truncate-except-project => ~/P/F/emacs/l/comint.el
  807. ;; truncate-upto-root => ~/P/F/e/lisp/comint.el
  808. ;; truncate-all => ~/P/F/e/l/comint.el
  809. ;; relative-from-project => emacs/lisp/comint.el
  810. ;; relative-to-project => lisp/comint.el
  811. ;; file-name => comint.el
  812. ;; buffer-name => comint.el<2> (uniquify buffer name)
  813. ;;
  814. ;; If you are expereicing the laggy issue, especially while editing remote files
  815. ;; with tramp, please try `file-name' style.
  816. ;; Please refer to https://github.com/bbatsov/projectile/issues/657.
  817. (setq doom-modeline-buffer-file-name-style 'truncate-upto-project)
  818. ;; What executable of Python will be used (if nil nothing will be showed).
  819. (setq doom-modeline-python-executable "python")
  820. ;; Whether show `all-the-icons' or not (if nil nothing will be showed).
  821. (setq doom-modeline-icon t)
  822. ;; Whether show the icon for major mode. It respects `doom-modeline-icon'.
  823. (setq doom-modeline-major-mode-icon t)
  824. ;; Display color icons for `major-mode'. It respects `all-the-icons-color-icons'.
  825. (setq doom-modeline-major-mode-color-icon nil)
  826. ;; Whether display minor modes or not. Non-nil to display in mode-line.
  827. (setq doom-modeline-minor-modes nil)
  828. ;; If non-nil, a word count will be added to the selection-info modeline segment.
  829. (setq doom-modeline-enable-word-count nil)
  830. ;; If non-nil, only display one number for checker information if applicable.
  831. (setq doom-modeline-checker-simple-format t)
  832. ;; Whether display perspective name or not. Non-nil to display in mode-line.
  833. (setq doom-modeline-persp-name t)
  834. ;; Whether display `lsp' state or not. Non-nil to display in mode-line.
  835. (setq doom-modeline-lsp t)
  836. ;; Whether display github notifications or not. Requires `ghub` package.
  837. (setq doom-modeline-github nil)
  838. ;; The interval of checking github.
  839. (setq doom-modeline-github-interval (* 30 60))
  840. ;; Whether display environment version or not.
  841. (setq doom-modeline-env-version t)
  842. ;; Whether display mu4e notifications or not. Requires `mu4e-alert' package.
  843. (setq doom-modeline-mu4e t)
  844. #+END_SRC