Personal emacs config
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.

349 lines
10 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. * Editing
  2. ** IEdit mode
  3. #+BEGIN_SRC emacs-lisp
  4. (use-package iedit
  5. :bind ("C-;" . iedit-mode))
  6. #+END_SRC
  7. ** Spellcheck
  8. #+BEGIN_SRC emacs-lisp
  9. (global-set-key (kbd "C-!") 'ispell-buffer)
  10. #+END_SRC
  11. ** Undo tree
  12. #+BEGIN_SRC emacs-lisp
  13. (use-package undo-tree
  14. :config
  15. (global-undo-tree-mode))
  16. #+END_SRC
  17. * Added functionality
  18. ** Multiline sexp with symbol
  19. Jump to symbol, go up list, lispy-multiline. Great for diff-friendly custom
  20. #+BEGIN_SRC emacs-lisp
  21. (require 'isearch)
  22. (require 'lispy)
  23. (defun rlbr/multiline-sexp-with-symbol (symbol-name)
  24. (save-excursion
  25. (beginning-of-buffer)
  26. (search-forward-regexp (isearch-symbol-regexp symbol-name))
  27. (backward-up-list)
  28. (lispy-alt-multiline)))
  29. #+END_SRC
  30. ** Output matches
  31. Run command for each matching exe and see if output-p is true when fed the command output
  32. #+BEGIN_SRC emacs-lisp
  33. (defun rlbr/output-matches (output-matches-p exe args)
  34. "locate the executable whose output satisfies output-matches-p when fed args and return the full-path"
  35. (let ((exec-path exec-path)
  36. (output)
  37. (bad)
  38. (command-output)
  39. (current-exe)
  40. (failed))
  41. (while (not (or output failed))
  42. (setq current-exe
  43. (executable-find exe))
  44. (if current-exe
  45. (progn
  46. (setq command-output
  47. (shell-command-to-string (format "%s %s" (rlbr/quote-exe current-exe) args)))
  48. (if (funcall output-matches-p command-output)
  49. (setq output current-exe)
  50. (progn
  51. (setq bad
  52. (replace-regexp-in-string "/$" "" (file-name-directory current-exe)))
  53. (setq exec-path
  54. (seq-filter (lambda (item) (not (rlbr/case-insensitive-match item bad))) exec-path)))))
  55. (setq failed t)))
  56. output))
  57. #+END_SRC
  58. * Save/load
  59. ** Backup/auto-save
  60. #+BEGIN_SRC emacs-lisp
  61. (let ((backup-dir "~/.emacs.d/backup")
  62. (auto-save-dir "~/.emacs.d/autosave"))
  63. (if (not (file-directory-p backup-dir))
  64. (make-directory backup-dir))
  65. (if (not (file-directory-p
  66. auto-save-dir))
  67. (make-directory auto-save-dir)))
  68. #+END_SRC
  69. ** On save
  70. #+BEGIN_SRC emacs-lisp
  71. (add-hook 'before-save-hook 'delete-trailing-whitespace)
  72. #+END_SRC
  73. ** Recent files mode
  74. #+BEGIN_SRC emacs-lisp
  75. (use-package recentf
  76. :config
  77. (recentf-mode 1))
  78. #+END_SRC
  79. * Platform dependent
  80. ** Windows
  81. #+BEGIN_SRC emacs-lisp
  82. (when (string-equal system-type "windows-nt")
  83. (progn
  84. (defun rlbr/quote-exe (path)
  85. (w32-short-file-name path))
  86. (defun rlbr/start-external-shell ()
  87. (interactive)
  88. (start-process-shell-command (format "cmd(%s)" default-directory) nil "start default.bat"))
  89. (global-set-key (kbd "C-S-C") 'rlbr/start-external-shell)
  90. (defun rlbr/start-windows-explorer-here ()
  91. (interactive)
  92. (start-process-shell-command "explorer" nil (format "explorer %s" (replace-regexp-in-string "/" (regexp-quote "\\") (expand-file-name default-directory)))))
  93. (global-set-key (kbd "C-S-E") 'rlbr/start-windows-explorer-here)
  94. (defun rlbr/case-insensitive-match (string1 string2)
  95. (apply 'string-equal (mapcar 'downcase (list string1 string2))))
  96. (let ((find)
  97. (grep)
  98. (ls))
  99. (progn
  100. (setq find
  101. (rlbr/output-matches
  102. (lambda (output) (string-equal ".\n" output))
  103. "find" "-maxdepth 0"))
  104. (if find
  105. (setq find-program (rlbr/quote-exe find)))
  106. (setq grep (rlbr/output-matches
  107. (lambda (output) (string-match "grep (\\w+ grep)" output))
  108. "grep" "-V"))
  109. (if grep
  110. (setq grep-program
  111. (rlbr/quote-exe grep)))
  112. (setq ls (rlbr/output-matches
  113. (lambda (output) (string-match "ls: .*'\\?/': No such file or directory" output))
  114. "ls" "?/"))
  115. (if ls
  116. (setq insert-directory-program (rlbr/quote-exe ls)))))))
  117. #+END_SRC
  118. * Tramp configuration
  119. ** Tramp append plist to connection properties
  120. #+BEGIN_SRC emacs-lisp
  121. (use-package kv
  122. :config
  123. (defun rlbr/add-config-to-tramp (matches-regexp config-plist)
  124. (let ((config-alist (kvplist->alist config-plist)))
  125. (dolist (pair config-alist)
  126. (let ((config (list
  127. matches-regexp
  128. (car pair)
  129. (cdr pair))))
  130. (add-to-list
  131. 'tramp-connection-properties
  132. config))))))
  133. #+END_SRC
  134. ** Android
  135. #+BEGIN_SRC emacs-lisp
  136. (use-package tramp
  137. :config
  138. (let ((android-config (let ((default-directory "/data/data/com.termux/files"))
  139. (list "tmpdir" (expand-file-name "home/temp/")
  140. "remote-shell" (expand-file-name "usr/bin/sh")
  141. "remote-process-environment" (append (list (concat "PREFIX=" default-directory "usr")) tramp-remote-process-environment)
  142. "remote-path" (append (mapcar 'expand-file-name '("home/.local/bin" "usr/bin" "usr/bin/applets")) '("/sbin" "/vendor/bin" "/system/sbin" "/system/bin" "/system/xbin"))))))
  143. (rlbr/add-config-to-tramp "/ssh:termux.*:" android-config)))
  144. #+END_SRC
  145. * Major modes
  146. ** Java
  147. ** JavaScript
  148. #+BEGIN_SRC emacs-lisp
  149. (use-package js2-mode
  150. :mode "\\.js\\'"
  151. :hook ((js2-mode . js2-imenu-extras-mode)
  152. (js2-mode . (lambda () (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t))))
  153. :config
  154. (use-package js2-refactor
  155. :hook (js2-mode . js2-refactor-mode)
  156. :bind
  157. (:map js2-mode-map
  158. ("C-k" . js2r-kill))
  159. :config
  160. (js2r-add-keybindings-with-prefix "C-c C-r"))
  161. (use-package xref-js2
  162. :demand t)
  163. (define-key js-mode-map (kbd "M-.") nil)
  164. (defun rlbr/jump-to-definition ()
  165. "Jump to a definition."
  166. (interactive)
  167. (condition-case-unless-debug nil
  168. (js2-jump-to-definition)
  169. (error
  170. (progn
  171. (ignore-errors
  172. (xref-pop-marker-stack))
  173. (xref-find-definitions (xref-backend-identifier-at-point (xref-find-backend)))))))
  174. (define-key js-mode-map (kbd "M-.") #'rlbr/jump-to-definition))
  175. #+END_SRC
  176. ** Magit
  177. #+BEGIN_SRC emacs-lisp
  178. (use-package magit
  179. :bind (("C-x g" . magit-status))
  180. :config
  181. (use-package git-commit
  182. :hook (git-commit-setup . git-commit-turn-on-flyspell)))
  183. #+END_SRC
  184. ** Python
  185. *** Platform specific
  186. #+BEGIN_SRC emacs-lisp
  187. (setq elpy-rpc-python-command
  188. (cond
  189. ((string-equal system-type "gnu/linux")
  190. "python3")
  191. ((string-equal system-type "windows-nt")
  192. "pythonw.exe")))
  193. #+END_SRC
  194. *** custom feature
  195. #+BEGIN_SRC emacs-lisp
  196. (defun rlbr/split-venv-with-number (name-number)
  197. "Split a virtualenv name with either a ~ seperating the name and the number, or nothing"
  198. (let ((split-result (split-string name-number (regexp-quote "~")))
  199. (ret))
  200. (if (= 1 (length split-result))
  201. (progn
  202. (setq ret (car split-result))
  203. (push 0 ret))
  204. (progn
  205. (setq ret
  206. (string-join
  207. (butlast split-result)
  208. "~"))
  209. (push
  210. (string-to-number
  211. (car (last split-result)))
  212. ret)))
  213. ret))
  214. (defun rlbr/join-venv-with-number (number-name)
  215. "Join a list with a name and a number"
  216. (let
  217. ((number (car number-name))
  218. (name (cdr number-name)))
  219. (if (= number 0)
  220. name
  221. (string-join (list name (number-to-string number)) "~"))))
  222. #+END_SRC
  223. *** bindings/settings
  224. #+BEGIN_SRC emacs-lisp
  225. (use-package python
  226. :hook ((python-mode . blacken-mode)
  227. (python-mode . pyvenv-mode))
  228. :config
  229. (use-package elpy
  230. :bind (("C-=" . elpy-goto-assignment))
  231. :config (when (require 'flycheck nil t)
  232. (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))))
  233. (elpy-enable))
  234. #+END_SRC
  235. ** SSH config mode
  236. #+BEGIN_SRC emacs-lisp
  237. (use-package ssh-config-mode
  238. :mode "~/.ssh/config\\'")
  239. #+END_SRC
  240. ** Tramp
  241. ** Webmode
  242. #+BEGIN_SRC emacs-lisp
  243. (use-package web-mode
  244. :mode
  245. (("\\.phtml\\'" . web-mode)
  246. ("\\.tpl\\.php\\'" . web-mode)
  247. ("\\.[agj]sp\\'" . web-mode)
  248. ("\\.as[cp]x\\'" . web-mode)
  249. ("\\.erb\\'" . web-mode)
  250. ("\\.mustache\\'" . web-mode)
  251. ("\\.djhtml\\'" . web-mode)
  252. ("\\.html?\\'" . web-mode)))
  253. #+END_SRC
  254. ** YAML
  255. #+BEGIN_SRC emacs-lisp
  256. (use-package yaml-mode
  257. :mode "\\.yml\\'")
  258. #+END_SRC
  259. * Minor modes/misc
  260. ** Kill the things
  261. *** Buffer
  262. #+BEGIN_SRC emacs-lisp
  263. (global-set-key (kbd "C-x k") 'kill-this-buffer)
  264. #+END_SRC
  265. *** Emacs
  266. #+BEGIN_SRC emacs-lisp
  267. (global-set-key (kbd "C-x C-k C-x C-k") 'kill-emacs)
  268. #+END_SRC
  269. ** Lispy
  270. #+BEGIN_SRC emacs-lisp
  271. (use-package lispy
  272. :hook ((emacs-lisp-mode) . lispy-mode))
  273. #+END_SRC
  274. ** Custom custom
  275. #+BEGIN_SRC emacs-lisp
  276. (advice-add 'custom-save-faces :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-faces")))
  277. (advice-add 'custom-save-variables :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-variables")))
  278. #+END_SRC
  279. * Navigation/auto-completion
  280. ** Ace window
  281. #+BEGIN_SRC emacs-lisp
  282. (use-package ace-window
  283. :bind (("M-Q" . ace-window)))
  284. #+END_SRC
  285. ** Hippie expand
  286. #+BEGIN_SRC emacs-lisp
  287. (use-package hippie-exp
  288. :bind ("M-/" . hippie-expand))
  289. #+END_SRC
  290. ** IBuffer mode
  291. #+BEGIN_SRC emacs-lisp
  292. (use-package ibbufer-vc
  293. :hook ((ibuffer-mode . ibuffer-vc-set-filter-groups-by-vc-root)))
  294. (use-package ibuffer
  295. :bind (("C-x C-b" . ibuffer))
  296. :config
  297. (define-ibuffer-column size-h
  298. ;; Use human readable Size column instead of original one
  299. (:name "Size" :inline t)
  300. (cond ((> (buffer-size) 1000000)
  301. (format "%7.1fM" (/ (buffer-size) 1000000.0)))
  302. ((> (buffer-size) 100000)
  303. (format "%7.0fk" (/ (buffer-size) 1000.0)))
  304. ((> (buffer-size) 1000)
  305. (format "%7.1fk" (/ (buffer-size) 1000.0)))
  306. (t
  307. (format "%8d" (buffer-size))))))
  308. #+END_SRC
  309. ** Ivy
  310. #+BEGIN_SRC emacs-lisp
  311. (use-package ivy
  312. :config
  313. (use-package swiper
  314. :bind ("C-s" . swiper))
  315. (ivy-mode))
  316. #+END_SRC
  317. * Look and feel
  318. ** Line numbers
  319. #+BEGIN_SRC emacs-lisp
  320. (global-display-line-numbers-mode)
  321. #+END_SRC
  322. ** Mode line bell
  323. #+BEGIN_SRC emacs-lisp
  324. (use-package mode-line-bell
  325. :config
  326. (mode-line-bell-mode))
  327. #+END_SRC
  328. ** Spaceline
  329. #+BEGIN_SRC emacs-lisp
  330. (use-package spaceline-config
  331. :config
  332. (use-package winum
  333. :init
  334. (setq winum-keymap
  335. (let ((map (make-sparse-keymap)))
  336. (define-key map (kbd "M-0") 'winum-select-window-0-or-10)
  337. (define-key map (kbd "M-1") 'winum-select-window-1)
  338. (define-key map (kbd "M-2") 'winum-select-window-2)
  339. (define-key map (kbd "M-3") 'winum-select-window-3)
  340. (define-key map (kbd "M-4") 'winum-select-window-4)
  341. (define-key map (kbd "M-5") 'winum-select-window-5)
  342. (define-key map (kbd "M-6") 'winum-select-window-6)
  343. (define-key map (kbd "M-7") 'winum-select-window-7)
  344. (define-key map (kbd "M-8") 'winum-select-window-8)
  345. map)))
  346. (spaceline-spacemacs-theme)
  347. (winum-mode))
  348. #+END_SRC