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.

347 lines
11 KiB

  1. * Global
  2. ** Add features/modes
  3. *** ibuffer-mode
  4. #+BEGIN_SRC emacs-lisp
  5. (require 'ibuffer-vc)
  6. (add-hook 'ibuffer-mode-hook (lambda ()
  7. (ibuffer-vc-set-filter-groups-by-vc-root)))
  8. (global-set-key (kbd "C-x C-b") 'ibuffer)
  9. ;; Use human readable Size column instead of original one
  10. (define-ibuffer-column size-h
  11. (:name "Size" ;; :inline t
  12. )
  13. (cond
  14. ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
  15. ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0)))
  16. ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
  17. (t (format "%8d" (buffer-size)))))
  18. ;; Modify the default ibuffer-formats
  19. (setq ibuffer-formats
  20. '((mark modified read-only " "
  21. (name 18 18 :left :elide)
  22. " "
  23. (size-h 9 -1 :right)
  24. " "
  25. (mode 16 16 :left :elide)
  26. " "
  27. filename-and-process)))
  28. #+END_SRC
  29. *** string-inflection
  30. #+BEGIN_SRC emacs-lisp
  31. (require 'string-inflection)
  32. ;; C-q C-u is the key bindings similar to Vz Editor.
  33. (global-set-key (kbd "C-M-,") 'my-string-inflection-cycle-auto)
  34. (defun my-string-inflection-cycle-auto ()
  35. "switching by major-mode"
  36. (interactive)
  37. (cond
  38. ;; for emacs-lisp-mode
  39. ((eq major-mode 'emacs-lisp-mode)
  40. (string-inflection-all-cycle))
  41. ;; for python
  42. ((eq major-mode 'python-mode)
  43. (string-inflection-python-style-cycle))
  44. ;; for java
  45. ((eq major-mode 'java-mode)
  46. (string-inflection-java-style-cycle))
  47. (t
  48. ;; default
  49. (string-inflection-ruby-style-cycle))))
  50. #+END_SRC
  51. *** undo-tree
  52. #+begin_src emacs-lisp
  53. (require 'undo-tree)
  54. (global-undo-tree-mode)
  55. #+end_src
  56. *** ssh-config-mode
  57. #+begin_src emacs-lisp
  58. (require 'ssh-config-mode)
  59. (add-to-list 'auto-mode-alist '("~/.ssh/config\\'" . ssh-config-mode))
  60. #+end_src
  61. *** yaml-mode
  62. #+begin_src emacs-lisp
  63. (require 'yaml-mode)
  64. (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
  65. #+end_src
  66. *** elpy move line up and down globally
  67. #+begin_src emacs-lisp
  68. (require 'elpy)
  69. (global-set-key (kbd "M-<up>") 'elpy-nav-move-line-or-region-up)
  70. (global-set-key (kbd "M-<down>") 'elpy-nav-move-line-or-region-down)
  71. (global-set-key (kbd "C-c <left>") 'windmove-left)
  72. (global-set-key (kbd "C-c <right>") 'windmove-right)
  73. (global-set-key (kbd "C-c <up>") 'windmove-up)
  74. (global-set-key (kbd "C-c <down>") 'windmove-down)
  75. #+end_src
  76. *** iedit-mode
  77. #+begin_src emacs-lisp
  78. (global-set-key (kbd "C-;") 'iedit-mode)
  79. #+end_src
  80. *** spellcheck entire buffer
  81. #+begin_src emacs-lisp
  82. (global-set-key (kbd "C-!") 'ispell-buffer)
  83. #+end_src
  84. *** find/replace
  85. #+begin_src emacs-lisp
  86. (require 'visual-regexp-steroids)
  87. (define-key global-map (kbd "C-c r") 'vr/replace)
  88. (define-key global-map (kbd "C-c q") 'vr/query-replace)
  89. #+end_src
  90. *** duplicate line function
  91. #+begin_src emacs-lisp
  92. (defun duplicate-line()
  93. (interactive)
  94. (move-beginning-of-line 1)
  95. (kill-line)
  96. (yank)
  97. (open-line 1)
  98. (next-line 1)
  99. (yank))
  100. (global-set-key (kbd "C-c d") 'duplicate-line)
  101. #+end_src
  102. *** magit
  103. #+begin_src emacs-lisp
  104. (global-set-key (kbd "C-x g") 'magit-status)
  105. #+end_src
  106. #+begin_src emacs-lisp
  107. (add-hook 'git-commit-setup-hook 'git-commit-turn-on-flyspell)
  108. #+end_src
  109. *** filename completion
  110. #+BEGIN_SRC emacs-lisp
  111. (global-set-key (kbd "C->") 'comint-dynamic-complete-filename)
  112. #+END_SRC
  113. *** hippie expand
  114. #+BEGIN_SRC emacs-lisp
  115. (global-set-key (kbd "M-/") 'hippie-expand)
  116. (setq hippie-expand-try-functions-list '(try-expand-dabbrev try-expand-dabbrev-all-buffers try-expand-dabbrev-from-kill
  117. try-complete-file-name-partially try-complete-file-name
  118. try-expand-all-abbrevs try-expand-list try-expand-line
  119. try-complete-lisp-symbol-partially try-complete-lisp-symbol))
  120. #+END_SRC
  121. *** window numbering mode
  122. #+BEGIN_SRC emacs-lisp
  123. (window-numbering-mode)
  124. #+END_SRC
  125. ** options
  126. *** global
  127. **** recent files
  128. #+begin_src emacs-lisp
  129. (require 'recentf)
  130. (recentf-mode 1)
  131. #+end_src
  132. **** backup
  133. #+begin_src emacs-lisp
  134. (let ((backup-dir (concat user-emacs-directory "backup"))
  135. (auto-save-dir (concat user-emacs-directory "autosave"))
  136. )
  137. (if (not (file-directory-p backup-dir))
  138. (make-directory backup-dir))
  139. (if (not(file-directory-p auto-save-dir))
  140. (make-directory auto-save-dir)
  141. )
  142. (setq backup-directory-alist
  143. `((".*" . , backup-dir)))
  144. (setq auto-save-file-name-transforms
  145. `((".*" , (concat auto-save-dir "/") t))))
  146. #+end_src
  147. **** kill buffer option
  148. #+begin_src emacs-lisp
  149. (global-set-key (kbd "C-x k") 'kill-this-buffer)
  150. #+end_src
  151. **** inhibit start screen
  152. #+begin_src emacs-lisp
  153. (setq inhibit-startup-screen t)
  154. #+end_src
  155. **** save options
  156. #+begin_src emacs-lisp
  157. (add-hook 'before-save-hook 'delete-trailing-whitespace)
  158. #+end_src
  159. **** theming
  160. #+begin_src emacs-lisp
  161. (load-theme 'dracula t)
  162. #+end_src
  163. **** bell
  164. #+BEGIN_SRC emacs-lisp
  165. (mode-line-bell-mode)
  166. #+END_SRC
  167. **** ivy
  168. #+BEGIN_SRC emacs-lisp
  169. (ivy-mode)
  170. (global-set-key (kbd "C-s") 'swiper)
  171. #+END_SRC
  172. **** kill-emacs key
  173. #+BEGIN_SRC emacs-lisp
  174. (global-set-key (kbd "C-x C-k C-x C-k") 'kill-emacs)
  175. #+END_SRC
  176. **** linum
  177. #+BEGIN_SRC emacs-lisp
  178. (global-display-line-numbers-mode)
  179. #+END_SRC
  180. **** enable commands
  181. #+BEGIN_SRC emacs-lisp
  182. (put 'downcase-region 'disabled nil)
  183. #+END_SRC
  184. *** dired
  185. #+begin_src emacs-lisp
  186. (setq ls-lisp-use-insert-directory-program t)
  187. #+end_src
  188. #+begin_src emacs-lisp
  189. (setq dired-listing-switches "-alh")
  190. #+end_src
  191. * Tramp configuration
  192. ** Tramp append plist to connection properties
  193. #+BEGIN_SRC emacs-lisp
  194. (require 'kv)
  195. (defun rlbr/add-config-to-tramp (matches-regexp config-plist)
  196. (let ((config-alist (kvplist->alist config-plist)))
  197. (dolist (pair config-alist)
  198. (let ((config (list
  199. matches-regexp
  200. (car pair)
  201. (cdr pair))))
  202. (add-to-list
  203. 'tramp-connection-properties
  204. config)))))
  205. #+END_SRC
  206. ** Android
  207. #+begin_src emacs-lisp
  208. (let ((android-config (let ((default-directory "/data/data/com.termux/files"))
  209. (list "tmpdir" (expand-file-name "home/temp/")
  210. "remote-shell" (expand-file-name "usr/bin/sh")
  211. "remote-process-environment" (append (list (concat "PREFIX=" default-directory "usr")) tramp-remote-process-environment)
  212. "remote-path" (append (mapcar 'expand-file-name '("home/.local/bin" "usr/bin" "usr/bin/applets")) '("/sbin" "/vendor/bin" "/system/sbin" "/system/bin" "/system/xbin"))))))
  213. (rlbr/add-config-to-tramp "/ssh:termux.*:" android-config))
  214. #+end_src
  215. * Web things
  216. ** javascript stuff
  217. #+begin_src emacs-lisp
  218. (require 'js2-mode)
  219. (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
  220. (add-hook 'js2-mode-hook #'js2-imenu-extras-mode)
  221. (require 'js2-refactor)
  222. (require 'xref-js2)
  223. (add-hook 'js2-mode-hook #'js2-refactor-mode)
  224. (js2r-add-keybindings-with-prefix "C-c C-r")
  225. (define-key js2-mode-map (kbd "C-k") #'js2r-kill)
  226. (define-key js-mode-map (kbd "M-.") nil)
  227. (add-hook 'js2-mode-hook (lambda ()
  228. (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t)))
  229. (define-key js2-mode-map (kbd "C-k") #'js2r-kill)
  230. #+end_src
  231. ** web mode
  232. #+begin_src emacs-lisp
  233. (require 'web-mode)
  234. (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
  235. (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
  236. (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
  237. (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
  238. (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
  239. (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
  240. (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
  241. (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
  242. #+end_src
  243. * Platform Specific
  244. #+begin_src emacs-lisp
  245. (cond
  246. #+end_src
  247. ** Windows
  248. #+begin_src emacs-lisp
  249. ((string-equal system-type "windows-nt")
  250. (progn
  251. (defun rlbr/quote-exe (path)
  252. (w32-short-file-name path))
  253. (defun rlbr/start-external-shell ()
  254. (interactive)
  255. (start-process-shell-command (format "cmd(%s)" default-directory) nil "start default.bat"))
  256. (global-set-key (kbd "C-S-C") 'rlbr/start-external-shell)
  257. (defun rlbr/start-windows-explorer-here ()
  258. (interactive)
  259. (start-process-shell-command "explorer" nil
  260. (format "explorer %s"
  261. (replace-regexp-in-string "/" (regexp-quote "\\") (expand-file-name default-directory))))
  262. )
  263. (global-set-key (kbd "C-S-E") 'rlbr/start-windows-explorer-here)
  264. (defun rlbr/case-insensitive-match (string1 string2)
  265. (apply 'string-equal (mapcar 'downcase (list string1 string2))))
  266. (defun rlbr/output-matches (output-matches-p exe args)
  267. "locate the executable whose output satifies output-matches-p when fed args and return the fullpath"
  268. (let
  269. (
  270. (exec-path exec-path)
  271. (output)
  272. (bad)
  273. (command-output)
  274. (current-exe)
  275. (failed)
  276. )
  277. (while (not (or output failed))
  278. (setq current-exe (executable-find exe))
  279. (if current-exe
  280. (progn
  281. (setq command-output (shell-command-to-string (format "%s %s" (rlbr/quote-exe current-exe) args)))
  282. (if (funcall output-matches-p command-output)
  283. (setq output current-exe)
  284. (progn
  285. (setq bad (replace-regexp-in-string "/$" "" (file-name-directory current-exe)))
  286. (setq exec-path (seq-filter (lambda (item) (not (rlbr/case-insensitive-match item bad))) exec-path)))))
  287. (setq failed t)))
  288. output))
  289. (let
  290. ((find)
  291. (grep)
  292. (ls))
  293. (progn
  294. (setq find (rlbr/output-matches (lambda (output) (string-equal ".\n" output)) "find" "-maxdepth 0"))
  295. (if find
  296. (setq find-program (rlbr/quote-exe find)))
  297. (setq grep (rlbr/output-matches (lambda (output) (string-match "grep (\\w+ grep)" output)) "grep" "-V"))
  298. (if grep
  299. (setq grep-program (rlbr/quote-exe grep)))
  300. (setq ls (rlbr/output-matches (lambda (output) (string-match "ls: .*'\\?/': No such file or directory" output)) "ls" "?/"))
  301. (if ls
  302. (setq insert-directory-program (rlbr/quote-exe ls)))))
  303. (setq python-shell-interpreter (rlbr/quote-exe (executable-find "python")))
  304. (setq python-check-command (rlbr/quote-exe (executable-find "flake8")))
  305. (setq delete-by-moving-to-trash t)
  306. (defun python-shell-interpreter-refresh ()
  307. (interactive)
  308. (setq python-shell-interpreter (rlbr/quote-exe (executable-find "python"))))
  309. (add-hook 'python-django-project-root-hook 'python-shell-interpreter-refresh)
  310. ))
  311. #+end_src
  312. ** Linux
  313. #+begin_src emacs-lisp
  314. ((string-equal system-type "gnu/linux")
  315. (progn
  316. (setq python-shell-interpreter "python3")
  317. (setq elpy-rpc-python-command python-shell-interpreter)
  318. (defun get-elpa-package-install-directory (pkg)
  319. "Return the install directory of elpa PKG. Return nil if it is not found."
  320. (let ((elpa-dir package-user-dir))
  321. (when (file-exists-p elpa-dir)
  322. (let* ((pkg-match (concat "\\`" (symbol-name pkg) "-[0-9]+"))
  323. (dir (car (directory-files elpa-dir 'full pkg-match))))
  324. (when dir (file-name-as-directory dir))))))
  325. (setq vr/command-python
  326. (format "python3 %s" (expand-file-name "regexp.py" (get-elpa-package-install-directory 'visual-regexp-steroids))))
  327. )))
  328. #+end_src
  329. * Python
  330. #+begin_src emacs-lisp
  331. (elpy-enable)
  332. (when (require 'flycheck nil t)
  333. (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
  334. (add-hook 'elpy-mode-hook 'flycheck-mode))
  335. (require 'blacken)
  336. (defun python-mode-keys ()
  337. "Modify python-mode local key map"
  338. (local-set-key (kbd "C-=") 'elpy-goto-assignment))
  339. (add-hook 'python-mode-hook 'python-mode-keys)
  340. (add-hook 'elpy-mode-hook 'blacken-mode)
  341. (setq elpy-syntax-check-command python-check-command)
  342. #+end_src