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.
|
|
* Editing** IEdit mode#+BEGIN_SRC emacs-lisp (use-package iedit :bind ("C-;" . iedit-mode))#+END_SRC** Spellcheck#+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-!") 'ispell-buffer)#+END_SRC** Undo tree#+BEGIN_SRC emacs-lisp (use-package undo-tree :config (global-undo-tree-mode))#+END_SRC* Added functionality** Multiline sexp with symbolJump to symbol, go up list, lispy-multiline. Great for diff-friendly custom#+BEGIN_SRC emacs-lisp (require 'isearch) (require 'lispy) (defun rlbr/multiline-sexp-with-symbol (symbol-name) (save-excursion (beginning-of-buffer) (search-forward-regexp (isearch-symbol-regexp symbol-name)) (backward-up-list) (lispy-alt-multiline)))#+END_SRC** Output matchesRun command for each matching exe and see if output-p is true when fed the command output#+BEGIN_SRC emacs-lisp (defun rlbr/output-matches (output-matches-p exe args) "locate the executable whose output satisfies output-matches-p when fed args and return the full-path" (let ((exec-path exec-path) (output) (bad) (command-output) (current-exe) (failed)) (while (not (or output failed)) (setq current-exe (executable-find exe)) (if current-exe (progn (setq command-output (shell-command-to-string (format "%s %s" (rlbr/quote-exe current-exe) args))) (if (funcall output-matches-p command-output) (setq output current-exe) (progn (setq bad (replace-regexp-in-string "/$" "" (file-name-directory current-exe))) (setq exec-path (seq-filter (lambda (item) (not (rlbr/case-insensitive-match item bad))) exec-path))))) (setq failed t))) output))#+END_SRC** Save buffer-output to fileThis handy function is a customized ripoff of custom-save-all#+BEGIN_SRC emacs-lisp (defun rlbr/save-buffer-func-to-file (visit-file func args) "Rip off of custom-save-all" (let* ((filename visit-file) (recentf-exclude (if recentf-mode (append `(,(concat "\\`" (regexp-quote (recentf-expand-file-name visit-file)) "\\'") ,(concat "\\`" (regexp-quote (file-truename (recentf-expand-file-name visit-file))) "\\'")) recentf-exclude))) (old-buffer (find-buffer-visiting filename)) old-buffer-name) (with-current-buffer (let ((find-file-visit-truename t)) (or old-buffer (let ((delay-mode-hooks t)) (find-file-noselect filename)))) (when old-buffer (setq old-buffer-name (buffer-file-name)) (set-visited-file-name (file-chase-links filename))) (unless (eq major-mode 'emacs-lisp-mode) (delay-mode-hooks (emacs-lisp-mode))) (let ((inhibit-read-only t) (print-length nil) (print-level nil)) (apply func args)) (let ((file-precious-flag t)) (save-buffer)) (if old-buffer (progn (set-visited-file-name old-buffer-name) (set-buffer-modified-p nil)) (kill-buffer (current-buffer))))))#+END_SRC* Save/load** Backup/auto-save#+BEGIN_SRC emacs-lisp (let ((backup-dir "~/.emacs.d/backup") (auto-save-dir "~/.emacs.d/autosave")) (if (not (file-directory-p backup-dir)) (make-directory backup-dir)) (if (not (file-directory-p auto-save-dir)) (make-directory auto-save-dir)))#+END_SRC** On save#+BEGIN_SRC emacs-lisp (add-hook 'before-save-hook 'delete-trailing-whitespace)#+END_SRC** Recent files mode#+BEGIN_SRC emacs-lisp (use-package recentf :config (recentf-mode 1))#+END_SRC* Platform dependent** Windows#+BEGIN_SRC emacs-lisp (when (string-equal system-type "windows-nt") (progn (defun rlbr/quote-exe (path) (w32-short-file-name path)) (defun rlbr/start-external-shell () (interactive) (start-process-shell-command (format "cmd(%s)" default-directory) nil "start default.bat")) (global-set-key (kbd "C-S-C") 'rlbr/start-external-shell) (defun rlbr/start-windows-explorer-here () (interactive) (start-process-shell-command "explorer" nil (format "explorer %s" (replace-regexp-in-string "/" (regexp-quote "\\") (expand-file-name default-directory))))) (global-set-key (kbd "C-S-E") 'rlbr/start-windows-explorer-here) (defun rlbr/case-insensitive-match (string1 string2) (apply 'string-equal (mapcar 'downcase (list string1 string2)))) (let ((find) (grep) (ls)) (progn (setq find (rlbr/output-matches (lambda (output) (string-equal ".\n" output)) "find" "-maxdepth 0")) (if find (setq find-program (rlbr/quote-exe find))) (setq grep (rlbr/output-matches (lambda (output) (string-match "grep (\\w+ grep)" output)) "grep" "-V")) (if grep (setq grep-program (rlbr/quote-exe grep))) (setq ls (rlbr/output-matches (lambda (output) (string-match "ls: .*'\\?/': No such file or directory" output)) "ls" "?/")) (if ls (setq insert-directory-program (rlbr/quote-exe ls)))))))#+END_SRC* Tramp configuration** Tramp append plist to connection properties#+BEGIN_SRC emacs-lisp (use-package kv :config (defun rlbr/add-config-to-tramp (matches-regexp config-plist) (let ((config-alist (kvplist->alist config-plist))) (dolist (pair config-alist) (let ((config (list matches-regexp (car pair) (cdr pair)))) (add-to-list 'tramp-connection-properties config))))))#+END_SRC** Android#+BEGIN_SRC emacs-lisp (use-package tramp :config (let ((android-config (let ((default-directory "/data/data/com.termux/files")) (list "tmpdir" (expand-file-name "home/temp/") "remote-shell" (expand-file-name "usr/bin/sh") "remote-process-environment" (append (list (concat "PREFIX=" default-directory "usr")) tramp-remote-process-environment) "remote-path" (append (mapcar 'expand-file-name '("home/.local/bin" "usr/bin" "usr/bin/applets")) '("/sbin" "/vendor/bin" "/system/sbin" "/system/bin" "/system/xbin")))))) (rlbr/add-config-to-tramp "/ssh:termux.*:" android-config)))#+END_SRC* Major modes** Java** JavaScript#+BEGIN_SRC emacs-lisp (use-package js2-mode :mode "\\.js\\'" :hook ((js2-mode . js2-imenu-extras-mode) (js2-mode . (lambda () (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t)))) :config (use-package js2-refactor :hook (js2-mode . js2-refactor-mode) :bind (:map js2-mode-map ("C-k" . js2r-kill)) :config (js2r-add-keybindings-with-prefix "C-c C-r")) (use-package xref-js2 :demand t) (define-key js-mode-map (kbd "M-.") nil) (defun rlbr/jump-to-definition () "Jump to a definition." (interactive) (condition-case-unless-debug nil (js2-jump-to-definition) (error (progn (ignore-errors (xref-pop-marker-stack)) (xref-find-definitions (xref-backend-identifier-at-point (xref-find-backend))))))) (define-key js-mode-map (kbd "M-.") #'rlbr/jump-to-definition))#+END_SRC** Magit#+BEGIN_SRC emacs-lisp (use-package magit :bind (("C-x g" . magit-status)) :config (use-package git-commit :hook (git-commit-setup . git-commit-turn-on-flyspell)))#+END_SRC** Python*** Platform specific#+BEGIN_SRC emacs-lisp (setq elpy-rpc-python-command (cond ((string-equal system-type "gnu/linux") "python3") ((string-equal system-type "windows-nt") "pythonw.exe")))#+END_SRC*** custom feature#+BEGIN_SRC emacs-lisp (defun rlbr/split-venv-with-number (name-number) "Split a virtualenv name with either a ~ seperating the name and the number, or nothing" (let ((split-result (split-string name-number (regexp-quote "~"))) (ret)) (if (= 1 (length split-result)) (progn (setq ret (car split-result)) (push 0 ret)) (progn (setq ret (string-join (butlast split-result) "~")) (push (string-to-number (car (last split-result))) ret))) ret))
(defun rlbr/join-venv-with-number (number-name) "Join a list with a name and a number" (let ((number (car number-name)) (name (cdr number-name))) (if (= number 0) name (string-join (list name (number-to-string number)) "~"))))
(defun rlbr/get-venv-name (&optional library-root) "Generate venv name based off of the base-name of the library root" (file-name-base (directory-file-name (if library-root library-root (elpy-library-root)))))
(defun rlbr/handle-name-conflicts (venv-name) "Deal with potential name conflicts in venv" (let ((venv-conflicts) (venv-partition-name)) (setq venv-partition-name (rlbr/split-venv-with-number venv-name)) (setq venv-conflicts (seq-filter (lambda (item) (string-equal (cdr item) venv-name)) (mapcar #'rlbr/split-venv-with-number (pyvenv-virtualenv-list)))) (when venv-conflicts (setcar venv-partition-name (1+ (apply 'max (mapcar #'car venv-conflicts))))) (rlbr/join-venv-with-number venv-partition-name)))
(require 'vc) (defun rlbr/setup-python-venv-dirlocals (&optional library-root venv-name) "Setup .dir-locals file in library root and tell vc system to ignore .dir-locals file" (let* ((library-root (if library-root library-root (elpy-library-root))) (venv-name (if venv-name venv-name (rlbr/get-venv-name library-root))) (default-directory library-root) (dir-locals-path (expand-file-name ".dir-locals.el"))) (rlbr/save-buffer-func-to-file dir-locals-path 'add-dir-local-variable `(python-mode pyvenv-workon ,venv-name)) (let* ((vc-root (vc-find-root dir-locals-path ".git")) (vc-ignore-file (vc-call-backend 'Git 'find-ignore-file vc-root))) (if (apply 'string-equal (mapcar 'directory-file-name (mapcar 'file-truename (list vc-root library-root)))) (progn (unless (file-exists-p vc-ignore-file) (with-temp-buffer (write-file vc-ignore-file))) (vc-ignore ".dir-locals.el")) (when (y-or-n-p (format "Ignore .dir-locals.el in repo '%s' ?" vc-root)) (unless (file-exists-p vc-ignore-file) (with-temp-buffer (write-file vc-ignore-file))) (vc-ignore ".dir-locals.el"))))))
(defun rlbr/get-python-executable () (read-file-name "Python interpreter to use: " (file-name-directory (executable-find "python")) nil nil "python"))
(defun rlbr/init-python-venv-in-library-root (&optional library-root) "Prompt to either create one or use default" (let ((venv-name (rlbr/get-venv-name)) (library-root (if library-root library-root (elpy-library-root)))) (setq venv-name (rlbr/handle-name-conflicts venv-name)) (if (y-or-n-p (format "Create venv '%s'?" venv-name)) (pyvenv-create venv-name (rlbr/get-python-executable)) (progn (unless (member "emacs-default-venv" (pyvenv-virtualenv-list)) (pyvenv-create venv-name (rlbr/get-python-executable))) (setq venv-name "emacs-default-venv"))) (rlbr/setup-python-venv-dirlocals library-root venv-name) venv-name)) (require 'dash) (defun rlbr/init-venv () (when (eq major-mode 'python-mode) (unless (let ((buffer-file-name (file-truename buffer-file-name))) (-any (lambda (file-prefix) (string-prefix-p file-prefix buffer-file-name)) (mapcar 'file-truename (list (elpy-rpc-get-or-create-virtualenv) (pyvenv-workon-home))))) (cond ((and pyvenv-workon (not (member pyvenv-workon (pyvenv-virtualenv-list)))) (if (y-or-n-p (format "Venv '%s' is specified but does not exist. Create it?" pyvenv-workon)) (progn (pyvenv-create pyvenv-workon (rlbr/get-python-executable)) (pyvenv-workon pyvenv-workon)) (rlbr/save-buffer-func-to-file (let ((default-directory (elpy-library-root))) (expand-file-name ".dir-locals.el")) 'add-dir-local-variable '(python-mode pyvenv-workon "emacs-default-venv")) (setq-local pyvenv-workon "emacs-default-venv"))) ((not pyvenv-workon) (setq-local pyvenv-workon (rlbr/init-python-venv-in-library-root)))) (pyvenv-workon pyvenv-workon))))#+END_SRC*** bindings/settings#+BEGIN_SRC emacs-lisp (use-package python :hook ((python-mode . blacken-mode) (python-mode . pyvenv-mode) (hack-local-variables . rlbr/init-venv)) :config (use-package elpy :bind (("C-=" . elpy-goto-assignment)) :config (when (require 'flycheck nil t) (setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))) (elpy-enable))#+END_SRC** SSH config mode#+BEGIN_SRC emacs-lisp (use-package ssh-config-mode :mode "~/.ssh/config\\'")#+END_SRC** Tramp** Webmode#+BEGIN_SRC emacs-lisp (use-package web-mode :mode (("\\.phtml\\'" . web-mode) ("\\.tpl\\.php\\'" . web-mode) ("\\.[agj]sp\\'" . web-mode) ("\\.as[cp]x\\'" . web-mode) ("\\.erb\\'" . web-mode) ("\\.mustache\\'" . web-mode) ("\\.djhtml\\'" . web-mode) ("\\.html?\\'" . web-mode)))#+END_SRC** YAML#+BEGIN_SRC emacs-lisp (use-package yaml-mode :mode "\\.yml\\'")#+END_SRC* Minor modes/misc** Kill the things*** Buffer#+BEGIN_SRC emacs-lisp(global-set-key (kbd "C-x k") 'kill-this-buffer)#+END_SRC*** Emacs#+BEGIN_SRC emacs-lisp(global-set-key (kbd "C-x C-k C-x C-k") 'kill-emacs)#+END_SRC** Lispy#+BEGIN_SRC emacs-lisp (use-package lispy :hook ((emacs-lisp-mode) . lispy-mode))#+END_SRC** Custom custom#+BEGIN_SRC emacs-lisp (advice-add 'custom-save-faces :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-faces"))) (advice-add 'custom-save-variables :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-variables")))#+END_SRC* Navigation/auto-completion** Ace window#+BEGIN_SRC emacs-lisp (use-package ace-window :bind (("M-Q" . ace-window)))#+END_SRC** Hippie expand#+BEGIN_SRC emacs-lisp (use-package hippie-exp :bind ("M-/" . hippie-expand))#+END_SRC** IBuffer mode#+BEGIN_SRC emacs-lisp (use-package ibbufer-vc :hook ((ibuffer-mode . ibuffer-vc-set-filter-groups-by-vc-root))) (use-package ibuffer :bind (("C-x C-b" . ibuffer)) :config (define-ibuffer-column size-h ;; Use human readable Size column instead of original one (:name "Size" :inline t) (cond ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0))) ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0))) ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0))) (t (format "%8d" (buffer-size))))))#+END_SRC** Ivy#+BEGIN_SRC emacs-lisp (use-package ivy :config (use-package swiper :bind ("C-s" . swiper)) (ivy-mode))#+END_SRC* Look and feel** Line numbers#+BEGIN_SRC emacs-lisp (global-display-line-numbers-mode)#+END_SRC** Mode line bell#+BEGIN_SRC emacs-lisp (use-package mode-line-bell :config (mode-line-bell-mode))#+END_SRC** Spaceline#+BEGIN_SRC emacs-lisp (use-package spaceline-config :config (use-package winum :init (setq winum-keymap (let ((map (make-sparse-keymap))) (define-key map (kbd "M-0") 'winum-select-window-0-or-10) (define-key map (kbd "M-1") 'winum-select-window-1) (define-key map (kbd "M-2") 'winum-select-window-2) (define-key map (kbd "M-3") 'winum-select-window-3) (define-key map (kbd "M-4") 'winum-select-window-4) (define-key map (kbd "M-5") 'winum-select-window-5) (define-key map (kbd "M-6") 'winum-select-window-6) (define-key map (kbd "M-7") 'winum-select-window-7) (define-key map (kbd "M-8") 'winum-select-window-8) map))) (spaceline-spacemacs-theme) (winum-mode))#+END_SRC
|