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.

719 lines
24 KiB

6 years ago
6 years ago
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. ** Imenu
  8. #+BEGIN_SRC emacs-lisp
  9. (use-package imenu
  10. :bind
  11. ("C-S-s" . imenu))
  12. #+END_SRC
  13. ** Spellcheck
  14. #+BEGIN_SRC emacs-lisp
  15. (global-set-key (kbd "C-!") 'ispell-buffer)
  16. #+END_SRC
  17. ** String inflection
  18. #+BEGIN_SRC emacs-lisp
  19. (use-package string-inflection
  20. :bind ("C-M-," . my-string-inflection-cycle-auto)
  21. :config
  22. (defun my-string-inflection-cycle-auto ()
  23. "switching by major-mode"
  24. (interactive)
  25. (cond
  26. ;; for emacs-lisp-mode
  27. ((eq major-mode 'emacs-lisp-mode)
  28. (string-inflection-all-cycle))
  29. ;; for python
  30. ((eq major-mode 'python-mode)
  31. (string-inflection-python-style-cycle))
  32. ;; for java
  33. ((eq major-mode 'java-mode)
  34. (string-inflection-java-style-cycle))
  35. (t
  36. ;; default
  37. (string-inflection-ruby-style-cycle)))))
  38. #+END_SRC
  39. ** Undo tree
  40. #+BEGIN_SRC emacs-lisp
  41. (use-package undo-tree
  42. :config
  43. (global-undo-tree-mode))
  44. #+END_SRC
  45. * Added functionality
  46. ** Kill this buffer
  47. #+BEGIN_SRC emacs-lisp
  48. (defun rlbr/kill-this-buffer ()
  49. (interactive)
  50. (kill-buffer (current-buffer)))
  51. #+END_SRC
  52. ** Low memeory check
  53. #+BEGIN_SRC emacs-lisp
  54. (defun rlbr/high-mem (&optional threshold)
  55. (let ((threshold (or threshold (expt 1024 2)))))
  56. (>= (nth 1 (memory-info))
  57. threshold))
  58. #+END_SRC
  59. ** Multiline sexp with symbol
  60. Jump to symbol, go up list, lispy-multiline. Great for diff-friendly custom
  61. #+BEGIN_SRC emacs-lisp
  62. (require 'isearch)
  63. (require 'lispy)
  64. (defun rlbr/multiline-sexp-with-symbol (symbol-name)
  65. (save-excursion
  66. (beginning-of-buffer)
  67. (search-forward-regexp (isearch-symbol-regexp symbol-name))
  68. (backward-up-list)
  69. (lispy-alt-multiline)))
  70. #+END_SRC
  71. ** Output matches
  72. Run command for each matching exe and see if output-p is true when fed the command output
  73. #+BEGIN_SRC emacs-lisp
  74. (defun rlbr/output-matches (output-matches-p exe args)
  75. "locate the executable whose output satisfies output-matches-p when fed args and return the full-path"
  76. (let ((exec-path exec-path)
  77. (output)
  78. (bad)
  79. (command-output)
  80. (current-exe)
  81. (failed))
  82. (while (not (or output failed))
  83. (setq current-exe
  84. (executable-find exe))
  85. (if current-exe
  86. (progn
  87. (setq command-output
  88. (shell-command-to-string (format "%s %s" (rlbr/quote-exe current-exe)
  89. args)))
  90. (if (funcall output-matches-p command-output)
  91. (setq output current-exe)
  92. (progn
  93. (setq bad
  94. (replace-regexp-in-string "/$" "" (file-name-directory current-exe)))
  95. (setq exec-path
  96. (seq-filter (lambda (item)
  97. (not (rlbr/case-insensitive-match item bad)))
  98. exec-path)))))
  99. (setq failed t)))
  100. output))
  101. #+END_SRC
  102. ** Prefix arg overload
  103. #+BEGIN_SRC emacs-lisp
  104. (defun rlbr/prefix-arg-overload (func alt &optional alt-args)
  105. (let ((advice `(lambda (func &optional arg)
  106. (interactive "P")
  107. (if arg (apply (quote ,alt)
  108. ,alt-args)
  109. (apply func nil)))))
  110. (advice-add func :around advice)
  111. advice))
  112. #+END_SRC
  113. ** Save buffer-output to file
  114. This handy function is a customized ripoff of custom-save-all
  115. #+BEGIN_SRC emacs-lisp
  116. (defun rlbr/save-buffer-func-to-file (visit-file func args)
  117. "Rip off of custom-save-all"
  118. (let* ((filename visit-file)
  119. (recentf-exclude (if recentf-mode (append `(,(concat "\\`" (regexp-quote (recentf-expand-file-name visit-file))
  120. "\\'")
  121. ,(concat "\\`" (regexp-quote (file-truename (recentf-expand-file-name visit-file)))
  122. "\\'"))
  123. recentf-exclude)))
  124. (old-buffer (find-buffer-visiting filename))
  125. old-buffer-name)
  126. (with-current-buffer (let ((find-file-visit-truename t))
  127. (or old-buffer (let ((delay-mode-hooks t))
  128. (find-file-noselect filename))))
  129. (when old-buffer (setq old-buffer-name (buffer-file-name))
  130. (set-visited-file-name (file-chase-links filename)))
  131. (unless (eq major-mode 'emacs-lisp-mode)
  132. (delay-mode-hooks (emacs-lisp-mode)))
  133. (let ((inhibit-read-only t)
  134. (print-length nil)
  135. (print-level nil))
  136. (apply func args))
  137. (let ((file-precious-flag t))
  138. (save-buffer))
  139. (if old-buffer (progn (set-visited-file-name old-buffer-name)
  140. (set-buffer-modified-p nil))
  141. (kill-buffer (current-buffer))))))
  142. #+END_SRC
  143. * Save/load
  144. ** Backup/auto-save
  145. #+BEGIN_SRC emacs-lisp
  146. (let ((backup-dir "~/.emacs.d/backup")
  147. (auto-save-dir "~/.emacs.d/autosave"))
  148. (if (not (file-directory-p backup-dir))
  149. (make-directory backup-dir))
  150. (if (not (file-directory-p
  151. auto-save-dir))
  152. (make-directory auto-save-dir)))
  153. #+END_SRC
  154. ** On save
  155. #+BEGIN_SRC emacs-lisp
  156. (add-hook 'before-save-hook 'delete-trailing-whitespace)
  157. #+END_SRC
  158. ** Recent files mode
  159. #+BEGIN_SRC emacs-lisp
  160. (use-package recentf
  161. :config
  162. (recentf-mode 1))
  163. #+END_SRC
  164. * Platform dependent
  165. ** Windows
  166. #+BEGIN_SRC emacs-lisp
  167. (when (string-equal system-type "windows-nt")
  168. (progn (defun rlbr/quote-exe (path)
  169. (w32-short-file-name path))
  170. (defun rlbr/high-mem (&optional threshold) t)
  171. (defun rlbr/start-external-shell ()
  172. (interactive)
  173. (start-process-shell-command (format "cmd(%s)" default-directory)
  174. nil "start default.bat"))
  175. (global-set-key (kbd "C-S-C")
  176. 'rlbr/start-external-shell)
  177. (defun rlbr/start-windows-explorer-here ()
  178. (interactive)
  179. (start-process-shell-command "explorer" nil (format "explorer %s" (replace-regexp-in-string "/" (regexp-quote "\\")
  180. (expand-file-name default-directory)))))
  181. (global-set-key (kbd "C-S-E")
  182. 'rlbr/start-windows-explorer-here)
  183. (defun rlbr/case-insensitive-match (string1 string2)
  184. (apply 'string-equal (mapcar 'downcase (list string1 string2))))
  185. (let ((find)
  186. (grep)
  187. (ls))
  188. (progn (setq find (rlbr/output-matches (lambda (output)
  189. (string-equal ".\n" output))
  190. "find" "-maxdepth 0"))
  191. (if find (setq find-program (rlbr/quote-exe find)))
  192. (setq grep (rlbr/output-matches (lambda (output)
  193. (string-match "grep (\\w+ grep)" output))
  194. "grep" "-V"))
  195. (if grep (setq grep-program (rlbr/quote-exe grep)))
  196. (setq ls (rlbr/output-matches (lambda (output)
  197. (string-match "ls: .*'\\?/': No such file or directory" output))
  198. "ls" "?/"))
  199. (if ls (setq insert-directory-program (rlbr/quote-exe ls)))))))
  200. #+END_SRC
  201. * Tramp configuration
  202. ** Tramp append plist to connection properties
  203. #+BEGIN_SRC emacs-lisp
  204. (use-package kv
  205. :config
  206. (defun rlbr/add-config-to-tramp (matches-regexp config-plist)
  207. (let ((config-alist (kvplist->alist config-plist)))
  208. (dolist (pair config-alist)
  209. (let ((config (list matches-regexp (car pair)
  210. (cdr pair))))
  211. (add-to-list 'tramp-connection-properties config))))))
  212. #+END_SRC
  213. ** Android
  214. #+BEGIN_SRC emacs-lisp
  215. (use-package tramp
  216. :config
  217. (let ((android-config (let ((default-directory "/data/data/com.termux/files"))
  218. (list "tmpdir" (expand-file-name "home/temp/")
  219. "remote-shell" (expand-file-name "usr/bin/sh")
  220. "remote-process-environment" (append (list (concat "PREFIX=" default-directory "usr")) tramp-remote-process-environment)
  221. "remote-path" (append (mapcar 'expand-file-name '("home/.local/bin" "usr/bin" "usr/bin/applets")) '("/sbin" "/vendor/bin" "/system/sbin" "/system/bin" "/system/xbin"))))))
  222. (rlbr/add-config-to-tramp (rx "/" (or "scp" "ssh") (zero-or-one "x") ":" "termux" (zero-or-more any) ":") android-config)))
  223. #+END_SRC
  224. * Major modes
  225. ** C
  226. #+BEGIN_SRC emacs-lisp
  227. (use-package format-all
  228. :if (executable-find "clang-format")
  229. :hook (c-mode . format-all-mode))
  230. #+END_SRC
  231. ** Docker
  232. *** Docker
  233. *** Dockerfile
  234. *** Docker-compose
  235. #+BEGIN_SRC emacs-lisp
  236. (use-package docker-compose-mode
  237. :mode (rx "docker-compose.yml" eos)
  238. :hook
  239. (docker-compose-mode . company-mode))
  240. #+END_SRC
  241. ** Java
  242. *** Meghanada
  243. #+BEGIN_SRC emacs-lisp
  244. (use-package autodisass-java-bytecode
  245. :defer t)
  246. (use-package meghanada
  247. :if (rlbr/high-mem (* 512 1024))
  248. :defer t
  249. :init
  250. (add-hook 'java-mode-hook
  251. (lambda ()
  252. (meghanada-mode t)
  253. (flycheck-mode +1)
  254. (add-hook 'before-save-hook 'meghanada-code-beautify-before-save)))
  255. :config
  256. (setq indent-tabs-mode nil)
  257. (setq meghanada-server-remote-debug t)
  258. (setq meghanada-javac-xlint "-Xlint:all,-processing")
  259. (advice-add 'meghanada-code-beautify :around (lambda (old)
  260. (interactive)
  261. (let ((p (line-number-at-pos)))
  262. (apply old nil)
  263. (goto-line p)
  264. (reposition-window))))
  265. (defhydra hydra-meghanada (:hint nil :exit t)
  266. "
  267. ^Edit^ ^Tast or Task^
  268. ^^^^^^-------------------------------------------------------
  269. _f_: meghanada-compile-file _m_: meghanada-restart
  270. _c_: meghanada-compile-project _t_: meghanada-run-task
  271. _o_: meghanada-optimize-import _j_: meghanada-run-junit-test-case
  272. _s_: meghanada-switch-test-case _J_: meghanada-run-junit-class
  273. _v_: meghanada-local-variable _R_: meghanada-run-junit-recent
  274. _i_: meghanada-import-all _r_: meghanada-reference
  275. _g_: magit-status _T_: meghanada-typeinfo
  276. _q_: exit
  277. "
  278. ("f" meghanada-compile-file)
  279. ("m" meghanada-restart)
  280. ("c" meghanada-compile-project)
  281. ("o" meghanada-optimize-import)
  282. ("s" meghanada-switch-test-case)
  283. ("v" meghanada-local-variable)
  284. ("i" meghanada-import-all)
  285. ("g" magit-status)
  286. ("t" meghanada-run-task)
  287. ("T" meghanada-typeinfo)
  288. ("j" meghanada-run-junit-test-case)
  289. ("J" meghanada-run-junit-class)
  290. ("R" meghanada-run-junit-recent)
  291. ("r" meghanada-reference)
  292. ("q" exit)
  293. ("z" nil "leave"))
  294. :bind
  295. (:map meghanada-mode-map
  296. ("C-S-t" . meghanada-switch-testcase)
  297. ("M-RET" . meghanada-local-variable)
  298. ("M-r" . meghanada-reference)
  299. ("M-t" . meghanada-typeinfo)
  300. ("C-z" . hydra-meghanada/body))
  301. :commands
  302. (meghanada-mode))
  303. #+END_SRC
  304. ** JavaScript
  305. #+BEGIN_SRC emacs-lisp
  306. (use-package js2-mode
  307. :mode "\\.js\\'"
  308. :hook ((js2-mode . js2-imenu-extras-mode)
  309. (js2-mode . (lambda () (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t))))
  310. :config
  311. (use-package js2-refactor
  312. :hook (js2-mode . js2-refactor-mode)
  313. :bind
  314. (:map js2-mode-map
  315. ("C-k" . js2r-kill))
  316. :config
  317. (js2r-add-keybindings-with-prefix "C-c C-r"))
  318. (use-package xref-js2
  319. :demand t)
  320. (define-key js-mode-map (kbd "M-.") nil)
  321. (defun rlbr/jump-to-definition ()
  322. "Jump to a definition."
  323. (interactive)
  324. (condition-case-unless-debug nil
  325. (js2-jump-to-definition)
  326. (error
  327. (progn
  328. (ignore-errors
  329. (xref-pop-marker-stack))
  330. (xref-find-definitions (xref-backend-identifier-at-point (xref-find-backend)))))))
  331. (define-key js-mode-map (kbd "M-.") #'rlbr/jump-to-definition))
  332. #+END_SRC
  333. ** Lisp
  334. *** Emacs lisp
  335. #+BEGIN_SRC emacs-lisp
  336. (use-package elisp-mode
  337. :hook (emacs-lisp-mode . company-mode))
  338. #+END_SRC
  339. ** Magit
  340. #+BEGIN_SRC emacs-lisp
  341. (use-package magit
  342. :bind (("C-x g" . magit-status))
  343. :config
  344. (use-package git-commit
  345. :hook (git-commit-setup . git-commit-turn-on-flyspell)))
  346. #+END_SRC
  347. ** Python
  348. *** Platform specific
  349. Set python command
  350. #+BEGIN_SRC emacs-lisp
  351. (setq elpy-rpc-python-command
  352. (cond
  353. ((string-equal system-type "gnu/linux")
  354. "python3")
  355. ((string-equal system-type "windows-nt")
  356. "pythonw.exe")))
  357. #+END_SRC
  358. put executables in elpy-rpc-venv in path
  359. #+BEGIN_SRC emacs-lisp
  360. (defun rlbr/elpy-append-to-path ()
  361. (setenv "PATH" (string-join (list (getenv "PATH")
  362. (let ((default-directory (elpy-rpc-get-or-create-virtualenv))
  363. (path-entry)
  364. (elpy-binpath))
  365. (if (string-equal system-type "windows-nt")
  366. (progn (setq elpy-binpath (expand-file-name "Scripts"))
  367. (setq path-entry (replace-regexp-in-string (regexp-quote "/")
  368. (regexp-quote "\\")
  369. elpy-binpath)))
  370. (setq elpy-binpath (expand-file-name "bin"))
  371. (setq path-entry elpy-binpath))
  372. (nconc exec-path (list elpy-binpath))
  373. elpy-binpath))
  374. path-separator)))
  375. #+END_SRC
  376. #+BEGIN_SRC emacs-lisp
  377. (defun rlbr/fix-for-android ()
  378. (unless (= 0 (call-process elpy-rpc-python-command nil nil nil "-c" "import multiprocessing;multiprocessing.Pool()"))
  379. (setq python-check-command
  380. (string-join `(,python-check-command "--jobs=1") " "))))
  381. #+END_SRC
  382. *** Custom feature
  383. #+BEGIN_SRC emacs-lisp
  384. (defun rlbr/join-venv-with-number (number-name)
  385. "Join a list with a name and a number"
  386. (let
  387. ((number (car number-name))
  388. (name (cdr number-name)))
  389. (if (= number 0)
  390. name
  391. (string-join (list name (number-to-string number))
  392. "~"))))
  393. (defun rlbr/split-venv-with-number (name-number)
  394. "Split a virtualenv name with either a ~ seperating the name and the number, or nothing"
  395. (let ((split-result (split-string name-number (regexp-quote "~")))
  396. (ret))
  397. (if (= 1 (length split-result))
  398. (progn
  399. (setq ret (car split-result))
  400. (push 0 ret))
  401. (progn
  402. (setq ret
  403. (string-join
  404. (butlast split-result)
  405. "~"))
  406. (push
  407. (string-to-number
  408. (car (last split-result)))
  409. ret)))
  410. ret))
  411. (defun rlbr/get-venv-name (&optional library-root)
  412. "Generate venv name based off of the base-name of the library root"
  413. (file-name-base
  414. (directory-file-name
  415. (if library-root
  416. library-root
  417. (elpy-library-root)))))
  418. (defun rlbr/handle-name-conflicts (venv-name)
  419. "Deal with potential name conflicts in venv"
  420. (let ((venv-conflicts)
  421. (venv-partition-name))
  422. (setq venv-partition-name (rlbr/split-venv-with-number venv-name))
  423. (setq venv-conflicts
  424. (seq-filter
  425. (lambda (item)
  426. (string-equal (cdr item)
  427. venv-name))
  428. (mapcar #'rlbr/split-venv-with-number (pyvenv-virtualenv-list))))
  429. (when venv-conflicts
  430. (setcar venv-partition-name (1+ (apply 'max (mapcar #'car venv-conflicts)))))
  431. (rlbr/join-venv-with-number venv-partition-name)))
  432. (require 'vc)
  433. (defun rlbr/setup-python-venv-dirlocals (&optional library-root venv-name)
  434. "Setup .dir-locals file in library root and tell vc system to ignore .dir-locals file"
  435. (let* ((library-root (if library-root
  436. library-root
  437. (elpy-library-root)))
  438. (venv-name (if venv-name venv-name (rlbr/get-venv-name library-root)))
  439. (default-directory library-root)
  440. (dir-locals-path (expand-file-name
  441. ".dir-locals.el")))
  442. (rlbr/save-buffer-func-to-file dir-locals-path 'add-dir-local-variable
  443. `(python-mode pyvenv-workon ,venv-name))
  444. (let ((vc-root (vc-find-root dir-locals-path ".git")))
  445. (when vc-root
  446. ;; If the directory is under version control
  447. (let ((vc-ignore-file (vc-call-backend 'Git 'find-ignore-file vc-root)))
  448. (if (apply 'string-equal (mapcar 'directory-file-name (mapcar 'file-truename (list vc-root library-root))))
  449. ;; If the vc-root is the same as the library root, don't ask any questions
  450. (vc-ignore ".dir-locals.el")
  451. ;; Otherwise prompt to ignore
  452. (when (y-or-n-p (format "Ignore .dir-locals.el in repo '%s' ?" vc-root))
  453. (vc-ignore ".dir-locals.el"))))))))
  454. (defun rlbr/get-python-executable ()
  455. (read-file-name "Python interpreter to use: " (file-name-directory (executable-find "python"))
  456. nil nil "python"))
  457. (defun emacs-default-venv ()
  458. (unless (member "emacs-default-venv" (pyvenv-virtualenv-list))
  459. (pyvenv-create "emacs-default-venv" (rlbr/get-python-executable)))
  460. "emacs-default-venv")
  461. (defun rlbr/init-python-venv-in-library-root (&optional library-root)
  462. "Prompt to either create one or use default" (let ((venv-name (rlbr/get-venv-name))
  463. (library-root (if library-root library-root (elpy-library-root))))
  464. (setq venv-name (rlbr/handle-name-conflicts venv-name))
  465. (if (y-or-n-p (format "Create venv '%s'?" venv-name))
  466. (pyvenv-create venv-name (rlbr/get-python-executable))
  467. (progn
  468. (setq venv-name (emacs-default-venv))))
  469. (rlbr/setup-python-venv-dirlocals library-root venv-name)
  470. venv-name))
  471. (require 'dash)
  472. (defun rlbr/init-venv ()
  473. (when (eq major-mode 'python-mode)
  474. (cond ((file-remote-p buffer-file-name)
  475. ;; If the file is remote, don't try and do anything fancy
  476. (setq-local pyvenv-workon (emacs-default-venv)))
  477. ((let ((buffer-file-name (file-truename buffer-file-name)))
  478. ;; Don't change anything if entering a file in a python install's lib (ie for a file located with xref)
  479. (string-match-p (rx bos (or
  480. ;; Windows
  481. (and letter ":/" (one-or-more not-newline)
  482. "/Lib")
  483. ;; Rest of the sane world
  484. (and (or
  485. ;; In the home directory
  486. (and (zero-or-more not-newline)
  487. "/home/" (zero-or-more not-newline)
  488. (or
  489. ;; System python user installed package
  490. "/.local"
  491. ;; In a virtualenv
  492. (and "/.virtualenvs/" (one-or-more (not (any "/"))))
  493. ;; Elpy-rpc venv
  494. (and "/.emacs.d/elpy/rpc-venv")
  495. ;; Using Pyenv
  496. (and "/.pyenv/versions/"
  497. (one-or-more (not (any "/"))))))
  498. ;; System python
  499. (and (zero-or-more not-newline)
  500. "/usr"
  501. (opt "/local")))
  502. ;; Standard */lib/python3.7/ etc
  503. (or
  504. ;; Standard python
  505. (and "/lib/python" (one-or-more (any digit ".")))
  506. ;; PyPy
  507. (and (or "/lib-python" "/lib_pypy")))))
  508. (zero-or-more not-newline))
  509. buffer-file-name))
  510. nil)
  511. (t
  512. ;; Upon failing all conditions, prompt to create virtual environment if it doesn't exist
  513. (cond ((and pyvenv-workon (not (member pyvenv-workon (pyvenv-virtualenv-list))))
  514. ;; If there is a virtualenv specified and it doesn't exist, prompt to create it or set to default virtual environment
  515. (if (y-or-n-p (format "Venv '%s' is specified but does not exist. Create it?" pyvenv-workon))
  516. (progn (pyvenv-create pyvenv-workon (rlbr/get-python-executable))
  517. (pyvenv-workon pyvenv-workon))
  518. (rlbr/save-buffer-func-to-file (let ((default-directory (elpy-library-root)))
  519. (expand-file-name ".dir-locals.el"))
  520. 'add-dir-local-variable '(python-mode pyvenv-workon (emacs-default-venv)))
  521. (setq-local pyvenv-workon (emacs-default-venv))))
  522. ((not pyvenv-workon)
  523. ;; If nothing has already set pyvenv-workon, create venv
  524. (setq-local pyvenv-workon (rlbr/init-python-venv-in-library-root))))))
  525. (pyvenv-workon pyvenv-workon)))
  526. #+END_SRC
  527. *** Bindings/settings
  528. #+BEGIN_SRC emacs-lisp
  529. (use-package python
  530. :hook
  531. ((python-mode . pyvenv-mode)
  532. (python-mode . flycheck-mode)
  533. (python-mode . (lambda () (add-hook 'before-save-hook 'elpy-black-fix-code nil 'local))))
  534. :bind
  535. (:map python-mode-map
  536. (("C-<" . flycheck-previous-error)
  537. ("C->" . flycheck-next-error)))
  538. :config
  539. (use-package elpy
  540. :hook (hack-local-variables . rlbr/init-venv)
  541. :bind (:map python-mode-map
  542. (("C-=" . elpy-goto-assignment)
  543. ("M-." . elpy-goto-definition)))
  544. :config
  545. (when (require 'flycheck nil t)
  546. (setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))
  547. (rlbr/prefix-arg-overload 'elpy-goto-definition 'elpy-goto-definition-other-window)
  548. (rlbr/prefix-arg-overload 'elpy-goto-assignment 'elpy-goto-assignment-other-window)
  549. (rlbr/elpy-append-to-path)
  550. (rlbr/fix-for-android))
  551. (use-package realgud
  552. :bind (:map python-mode-map
  553. (("C-c d b" . realgud:pdb))))
  554. (elpy-enable))
  555. #+END_SRC
  556. ** SSH config mode
  557. #+BEGIN_SRC emacs-lisp
  558. (use-package ssh-config-mode
  559. :mode "~/.ssh/config\\'")
  560. #+END_SRC
  561. ** Tramp
  562. ** Webmode
  563. #+BEGIN_SRC emacs-lisp
  564. (use-package web-mode
  565. :mode
  566. (("\\.phtml\\'" . web-mode)
  567. ("\\.tpl\\.php\\'" . web-mode)
  568. ("\\.[agj]sp\\'" . web-mode)
  569. ("\\.as[cp]x\\'" . web-mode)
  570. ("\\.erb\\'" . web-mode)
  571. ("\\.mustache\\'" . web-mode)
  572. ("\\.djhtml\\'" . web-mode)
  573. ("\\.html?\\'" . web-mode)))
  574. #+END_SRC
  575. ** YAML
  576. #+BEGIN_SRC emacs-lisp
  577. (use-package yaml-mode
  578. :mode "\\.yml\\'")
  579. #+END_SRC
  580. * Minor modes/misc
  581. ** Better shell
  582. #+BEGIN_SRC emacs-lisp
  583. (use-package better-shell
  584. :bind
  585. (("C-M-;" . better-shell-shell)
  586. ("C-M-:" . better-shell-remote-open)
  587. ("C-#" . better-shell-sudo-here)))
  588. #+END_SRC
  589. ** Custom custom
  590. #+BEGIN_SRC emacs-lisp
  591. (advice-add 'custom-save-faces :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-faces")))
  592. (advice-add 'custom-save-variables :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-variables")))
  593. #+END_SRC
  594. ** Elmacro
  595. #+BEGIN_SRC emacs-lisp
  596. (use-package elmacro
  597. :demand
  598. :config
  599. (elmacro-mode +1))
  600. #+END_SRC
  601. ** Kill the things
  602. *** Buffer
  603. #+BEGIN_SRC emacs-lisp
  604. (global-set-key (kbd "C-x k") 'rlbr/kill-this-buffer)
  605. #+END_SRC
  606. *** Emacs
  607. #+BEGIN_SRC emacs-lisp
  608. (global-set-key (kbd "C-x C-k C-x C-k") 'save-buffers-kill-emacs)
  609. #+END_SRC
  610. ** Lispy
  611. #+BEGIN_SRC emacs-lisp
  612. (use-package lispy
  613. :hook ((emacs-lisp-mode) . lispy-mode))
  614. #+END_SRC
  615. * Navigation/auto-completion
  616. ** Ace window
  617. #+BEGIN_SRC emacs-lisp
  618. (use-package ace-window
  619. :bind (("M-Q" . ace-window)))
  620. #+END_SRC
  621. ** Hippie expand
  622. #+BEGIN_SRC emacs-lisp
  623. (use-package hippie-exp
  624. :bind ("M-/" . hippie-expand))
  625. #+END_SRC
  626. ** IBuffer mode
  627. #+BEGIN_SRC emacs-lisp
  628. (use-package ibbufer-vc
  629. :hook
  630. ((ibuffer-mode . ibuffer-vc-set-filter-groups-by-vc-root)))
  631. ;; Use human readable Size column instead of original one
  632. (use-package ibuffer :bind (("C-x C-b" . ibuffer))
  633. :bind (:map ibuffer-mode-map
  634. (("C-c t" . ibuffer-tramp-set-filter-groups-by-tramp-connection)
  635. ("C-c g" . ibuffer-vc-set-filter-groups-by-vc-root)))
  636. :config (define-ibuffer-column size-h (:name "Size" :inline t)
  637. (cond ((> (buffer-size)
  638. 1000000)
  639. (format "%7.1fM" (/ (buffer-size)
  640. 1000000.0)))
  641. ((> (buffer-size)
  642. 100000)
  643. (format "%7.0fk" (/ (buffer-size)
  644. 1000.0)))
  645. ((> (buffer-size)
  646. 1000)
  647. (format "%7.1fk" (/ (buffer-size)
  648. 1000.0)))
  649. (t (format "%8d" (buffer-size))))))
  650. #+END_SRC
  651. ** Ivy
  652. #+BEGIN_SRC emacs-lisp
  653. (use-package ivy
  654. :config
  655. (use-package swiper
  656. :bind ("C-s" . swiper))
  657. (ivy-mode))
  658. #+END_SRC
  659. * Look and feel
  660. ** Line numbers
  661. #+BEGIN_SRC emacs-lisp
  662. (global-display-line-numbers-mode)
  663. #+END_SRC
  664. ** Mode line bell
  665. #+BEGIN_SRC emacs-lisp
  666. (use-package mode-line-bell
  667. :config
  668. (mode-line-bell-mode))
  669. #+END_SRC
  670. ** Spaceline
  671. #+BEGIN_SRC emacs-lisp
  672. (use-package spaceline-config
  673. :config (use-package winum
  674. :bind
  675. (:map winum-keymap
  676. (("M-0" . winum-select-window-0-or-10)
  677. ("M-1" . winum-select-window-1)
  678. ("M-2" . winum-select-window-2)
  679. ("M-3" . winum-select-window-3)
  680. ("M-4" . winum-select-window-4)
  681. ("M-5" . winum-select-window-5)
  682. ("M-6" . winum-select-window-6)
  683. ("M-7" . winum-select-window-7)
  684. ("M-8" . winum-select-window-8))))
  685. (spaceline-spacemacs-theme)
  686. (winum-mode))
  687. #+END_SRC
  688. ** Theme
  689. #+BEGIN_SRC emacs-lisp
  690. (use-package dracula-theme
  691. :config
  692. (load-theme 'dracula t))
  693. #+END_SRC
  694. * Clipboard manager
  695. ** Browse kill ring settings
  696. #+BEGIN_SRC emacs-lisp
  697. (use-package browse-kill-ring
  698. :defer nil
  699. :bind
  700. (:map browse-kill-ring-mode-map
  701. ("c" . rlbr/update-sys-clipboard-move-to-top))
  702. :config
  703. (defun rlbr/update-sys-clipboard-move-to-top (&optional quit)
  704. "Move the entry to the front." (interactive "P")
  705. (let ((buf (current-buffer))
  706. (pt (point)))
  707. (let ((str (browse-kill-ring-current-string buf pt)))
  708. (browse-kill-ring-delete)
  709. (kill-new str)))
  710. (unless quit (browse-kill-ring-update)))
  711. (browse-kill-ring-default-keybindings))
  712. #+END_SRC
  713. ** Clipmon settings
  714. #+BEGIN_SRC emacs-lisp
  715. (use-package clipmon
  716. :if (display-graphic-p)
  717. :hook ((after-init . clipmon-mode-start)
  718. (after-init . clipmon-persist)))
  719. #+END_SRC