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.

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