From 77349a20466f19cdc0ed9f45655e1714dc83128f Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 5 Dec 2014 17:28:03 -0500 Subject: [PATCH] Rewrote initfiles --- .gitignore | 2 +- Cask | 72 ++++--- Makefile | 12 ++ cleanup.sh | 3 - init.el | 117 ++++++------ init/core-defuns.el | 237 ----------------------- init/core-editor.el | 245 ++---------------------- init/core-evil.el | 367 +++++++++++++++++++++++++++++++++++ init/core-osx.el | 47 +++-- init/core-ui.el | 92 ++++----- init/core.el | 382 ++++++++++++++++++++++++------------- init/defuns-buffers.el | 56 ++++++ init/defuns-text.el | 123 ++++++++++++ init/defuns-ui.el | 47 +++++ init/defuns-util.el | 42 ++++ init/defuns.el | 94 +++++++++ init/init-auto-complete.el | 25 +-- init/init-auto-insert.el | 21 +- init/init-company.el | 113 +++++++++++ init/init-cpp.el | 6 +- init/init-cscope.el | 8 +- init/init-csharp.el | 20 +- init/init-dev.el | 95 ++++++++- init/init-elisp.el | 25 +++ init/init-eshell.el | 48 +++++ init/init-fly.el | 36 +++- init/init-git.el | 44 ++++- init/init-go.el | 10 +- init/init-helm.el | 181 ++++++++++++++++++ init/init-ido.el | 8 +- init/init-java.el | 22 ++- init/init-love.el | 22 --- init/init-lua.el | 19 ++ init/init-org.el | 2 +- init/init-project.el | 126 ++---------- init/init-projectile.el | 29 +++ init/init-python.el | 16 +- init/init-regex.el | 29 +++ init/init-ruby.el | 85 +++++---- init/init-sh.el | 18 ++ init/init-snippets.el | 62 ------ init/init-text.el | 4 +- init/init-tmux.el | 35 ++++ init/init-webdev.el | 89 +++++---- init/init-yasnippet.el | 128 +++++++++++++ init/my-bindings.el | 194 +++++++++++++++++++ init/my-coderunner.el | 66 ------- init/my-commands.el | 248 ------------------------ init/my-keymaps.el | 236 ----------------------- init/my-settings.el | 140 ++++++++++++-- 50 files changed, 2478 insertions(+), 1670 deletions(-) create mode 100644 Makefile delete mode 100755 cleanup.sh delete mode 100644 init/core-defuns.el create mode 100644 init/core-evil.el create mode 100644 init/defuns-buffers.el create mode 100644 init/defuns-text.el create mode 100644 init/defuns-ui.el create mode 100644 init/defuns-util.el create mode 100644 init/defuns.el create mode 100644 init/init-company.el create mode 100644 init/init-elisp.el create mode 100644 init/init-eshell.el create mode 100644 init/init-helm.el delete mode 100644 init/init-love.el create mode 100644 init/init-lua.el create mode 100644 init/init-projectile.el create mode 100644 init/init-regex.el delete mode 100644 init/init-snippets.el create mode 100644 init/init-tmux.el create mode 100644 init/init-yasnippet.el create mode 100644 init/my-bindings.el delete mode 100644 init/my-coderunner.el delete mode 100644 init/my-commands.el delete mode 100644 init/my-keymaps.el diff --git a/.gitignore b/.gitignore index e47a4039d..9e5cf8add 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ eshell/ -tmp +init/autoload.el .* # compiled files diff --git a/Cask b/Cask index 8ad2d7228..2761beb90 100644 --- a/Cask +++ b/Cask @@ -9,45 +9,59 @@ (depends-on "s") (depends-on "f") (depends-on "deferred") -(depends-on "exec-path-from-shell") (depends-on "fuzzy") (depends-on "use-package") (depends-on "smex") -;; Editing -(depends-on "smooth-scrolling") -(depends-on "smart-mode-line") +;; OSX +(depends-on "exec-path-from-shell") +(depends-on "dash-at-point") + +;; Core (depends-on "shut-up") +(depends-on "popwin") +(depends-on "saveplace") +;; (depends-on "key-chord") + +;; Editing +(depends-on "smart-mode-line") (depends-on "dired+") (depends-on "expand-region") (depends-on "flycheck") (depends-on "flyspell") (depends-on "rainbow-delimiters") (depends-on "smartparens") -(depends-on "anzu") -(depends-on "key-chord") (depends-on "yasnippet") (depends-on "git-gutter-fringe+") -(depends-on "popwin") -(depends-on "dash-at-point") -(depends-on "auto-complete") -(depends-on "auto-complete-clang") -(depends-on "auto-complete-c-headers") -(depends-on "ac-etags") -(depends-on "xcscope") -(depends-on "ac-ispell") (depends-on "ace-jump-mode") -(depends-on "ace-window") -(depends-on "smart-forward") -(depends-on "regex-tool") +;; (depends-on "ace-window") +;; (depends-on "regex-tool") (depends-on "pcre2el") -(depends-on "perspective") -(depends-on "persp-projectile") +(depends-on "emr") +;;(depends-on "smart-forward") ;;(depends-on "multiple-cursors") ;;(depends-on "git-gutter") -;;(depends-on "saveplace") +;;(depends-on "anzu") +;;(depends-on "smooth-scrolling") + +;; Auto-completion +(depends-on "company") +(depends-on "company-c-headers") +(depends-on "company-tern") +;; (depends-on "company-anaconda") +(depends-on "company-inf-ruby") +;;(depends-on "auto-complete") +;;(depends-on "auto-complete-clang") +;;(depends-on "auto-complete-c-headers") +;;(depends-on "ac-etags") +;;(depends-on "ac-ispell") +;;(depends-on "tern-auto-complete") +;;(depends-on "ac-inf-ruby") +;;(depends-on "jedi") + ;; Eeeevil +(depends-on "god-mode") (depends-on "evil") (depends-on "evil-matchit") (depends-on "evil-surround") @@ -58,22 +72,24 @@ (depends-on "evil-indent-textobject") (depends-on "evil-jumper") (depends-on "evil-god-state") -(depends-on "god-mode") ;; evil-nerd-commenter chokes if it's installed via cask for some reason... -;;(depends-on "evil-nerd-commenter") +(depends-on "evil-nerd-commenter") ;; Project management -(depends-on "ag") (depends-on "projectile") (depends-on "helm") (depends-on "helm-ag") (depends-on "helm-css-scss") (depends-on "helm-projectile") (depends-on "helm-swoop") +(depends-on "helm-company") (depends-on "neotree") (depends-on "ido-ubiquitous") (depends-on "ido-vertical-mode") (depends-on "flx-ido") +(depends-on "perspective") +(depends-on "persp-projectile") +(depends-on "xcscope") ;;(depends-on "grizzl") ;; Modes/mode-specific @@ -100,20 +116,18 @@ (depends-on "emmet-mode") (depends-on "web-beautify") +(depends-on "tern") (depends-on "js2-mode") (depends-on "js2-refactor") -(depends-on "tern") -(depends-on "tern-auto-complete") (depends-on "rspec-mode") (depends-on "inf-ruby") -;;(depends-on "ac-inf-ruby") (depends-on "robe") -(depends-on "jedi") +;; (depends-on "anaconda") -;;(depends-on "omnisharp") -;;(depends-on "csharp-mode") +(depends-on "omnisharp") +(depends-on "csharp-mode") (depends-on "emacs-eclim") (depends-on "git-commit-mode") diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..6fd6d2a9e --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +EMACS=emacs + +all: clean compile + +clean: + @rm -rf init.elc init/*.elc elisp/*.elc + @rm -rf auto-save-list recentf places ido.last async-bytecomp.log + +compile: + ${EMACS} -Q --batch -L . -f batch-byte-compile init.el init/*.el elisp/*.el + @rm -rf init/autoload.* + ${EMACS} -Q --batch -L . -f update-directory-autoloads init elisp diff --git a/cleanup.sh b/cleanup.sh deleted file mode 100755 index 0a9e3803b..000000000 --- a/cleanup.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -rm -f init.elc init/*.elc elisp/*.elc &> /dev/null diff --git a/init.el b/init.el index 707be4d4d..97f2040ef 100644 --- a/init.el +++ b/init.el @@ -6,74 +6,81 @@ ;; My emacs.d, which sets out to rustle emacs users' jimmies by making ;; emacs as vim-like as possible. ;; +;;; Description: +;; +;; Naming conventions: +;; * my-- ; interal defuns, meant for use via elisp +;; * my- ; interactive command, can be used via M-x +;; * my. ; commands with buffer side-effects (for keybinds) +;; * my: ; defuns meant to be used from Ex mode +;; * my/ ; defuns meant to be used from Ex mode +;; * * ; for altering the visual state +;; +;; ;;; Code: -;; instead of / -(cd "~") -(setq use-package-verbose t) ; for debug purposes +(defconst *debug-mode nil) -(require 'cask) -(cask-initialize) +(defconst my-dir user-emacs-directory) +(defconst my-init-dir (concat my-dir "init/")) +(defconst my-elisp-dir (concat my-dir "elisp/")) +(defconst my-themes-dir (concat my-dir "themes/")) +(defconst my-snippets-dir (concat my-dir "snippets/")) +(defconst my-ac-dicts-dir (concat my-dir "ac-dict/")) +(defconst my-tmp-dir (concat my-dir ".cache/")) -(setq user-mail-address "henrik@lissner.net") +(defconst *dark-theme 'brin) +(defconst *light-theme 'github) ; wtb better light theme... -(defconst *dir (file-name-directory load-file-name)) -(defconst *init-dir (concat *dir "init/")) -(defconst *themes-dir (concat *dir "themes/")) -(defconst *elisp-dir (concat *dir "elisp/")) -(defconst *snippets-dir (concat *dir "snippets/")) -(defconst *ac-dicts-dir (concat *dir "ac-dict/")) -(defconst *tmp-dir (concat *dir "tmp/")) +(defconst *default-font "Ubuntu Mono") +(defconst *default-font-size (if (eq system-name "ganymede.local") 12 14)) -(defconst *theme 'brin) -(defconst *font - (if (string-equal system-name "ganymede.local") - "Ubuntu Mono-12" ; Use smaller font on my laptop - "Ubuntu Mono-14")) ; And larger font everywhere else +(defconst *presentation-font *default-font) +(defconst *presentation-font-size 18) -(add-to-list 'load-path *init-dir) +(add-to-list 'load-path my-init-dir) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Just the... bear necessities... -(mapc 'require +(defconst my-modules + ;; ls -1 init/{init,my}* | xargs basename | sed -e 's/\..*$//' '(core - core-defuns ; Defun library - core-editor ; Global editor behavior (w/ evil) - core-ui ; User interface layout & behavior - core-osx ; Mac-specific config - ;; Essential plugins & modules - init-ido ; Ido setup - init-project ; Project nav+search tools (projectile, helm, ag) - init-snippets ; Snippet engine - init-git ; GIT tools/settings - init-fly ; Syntax & spell checker - init-auto-complete ; Auto-complete engine - init-auto-insert ; File auto-insert templates - init-cscope ; Global code indexing - - ;; Modes & environments - init-text ; Plain text editing (markdown, text) - init-sh ; Shell script editing (sh, zsh) - init-org ; Org-mode: personal gtd/notes - init-dev ; Generic dev tools & environment for all programming - init-ruby + ;; init-auto-complete + init-company + init-auto-insert + ;; init-cpp + ;; init-cscope + ;; init-csharp + init-dev + init-elisp + ;; init-eshell + init-fly + init-git + ;; init-go + init-helm + init-ido + init-java + init-lua + init-org + init-project ; project management settings & tools + init-projectile init-python - ;;init-php - init-webdev ; Environment for webdev (SCSS, PHP, Rails, Javascript) - init-love ; Love.app gamedev - init-cpp ; C++ gamedev - init-java ; Java-specific settings (including eclim) - ;; init-go ; Go-lang - ;; init-swift ; iOS/Mac dev environment for swift - ;; init-csharp ; Emacs as a Csharp/Unity IDE + init-regex + init-ruby + init-sh + ;; init-swift + init-text + init-tmux + init-webdev + init-yasnippet - ;; My homebaked packages - my-commands ; Ex commands & evil operators/commands - my-coderunner ; Code/REPL runners - - ;; Personal settings (must be last!) - my-settings ; Any other custom settings - my-keymaps ; My keybindings + my-bindings + my-settings )) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Load them in +(setq after-init-hook '((lambda() (mapc 'require my-modules)))) + ;; I've created a monster! diff --git a/init/core-defuns.el b/init/core-defuns.el deleted file mode 100644 index 69b2bba86..000000000 --- a/init/core-defuns.el +++ /dev/null @@ -1,237 +0,0 @@ -(provide 'core-defuns) - -;;;; Convenience ;;;;;;;;;;;;;;;;;;; -(defun associate-mode (match mode) - (add-to-list 'auto-mode-alist (cons match mode))) -(defun associate-minor-mode (match mode) - (add-to-list 'auto-minor-mode-alist (cons match mode))) - -(defmacro λ (&rest body) - `(lambda () (interactive) ,@body)) -(defmacro λ! (&rest body) - `(lambda () ,@body)) -(defmacro add-hook! (hook &rest body) - `(add-hook ,hook (lambda() ,@body))) - -;; Backwards compatibility -(unless (fboundp 'with-eval-after-load) - (defmacro with-eval-after-load (file &rest body) - `(eval-after-load ,file - `(funcall (function ,(lambda () ,@body)))))) - -(defmacro after (feature &rest forms) - `(,(if (or (not (boundp 'byte-compile-current-file)) - (not byte-compile-current-file) - (if (symbolp feature) - (require feature nil :no-error) - (load feature :no-message :no-error))) - 'progn - (message "after: cannot find %s" feature) - 'with-no-warnings) - (with-eval-after-load ',feature ,@forms))) - -;; vimmish keymapping shortcuts -(defalias 'defcmd 'evil-ex-define-cmd) - -(defmacro ibind (key command) - `(key-chord-define evil-insert-state-map ,key ,command)) - -(defun bind (state &rest keys) - (let ((state-list state) - (is-global (or (stringp state) - (vectorp state))) - keymap) - - (if is-global - (setq keys (-insert-at 0 state keys)) - (progn - (if (keymapp (first keys)) - (setq keymap (pop keys))) - - (if (or (keymapp state) - (not (listp state))) - (setq state-list (list state))))) - - (while keys - (let ((-key (pop keys)) - (-def (pop keys))) - - (if is-global - (global-set-key -key -def) - (dolist (-state state-list) - (cond ((evil-state-p -state) - (define-key - (if keymap - (evil-get-auxiliary-keymap keymap -state t) - (evil-state-property -state :keymap t)) -key -def)) - ((keymapp -state) - (define-key -state -key -def))))))))) - - -;; Hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun enable-comment-hard-wrap () - (set (make-local-variable 'comment-auto-fill-only-comments) t) - (turn-on-auto-fill)) - -(defun enable-tab-width-2 () - (setq tab-width 2 - evil-shift-width 2)) - -(defun disable-final-newline () - (set (make-local-variable 'require-final-newline) nil)) - - -;;; Text Defuns ;;;;;;;;;;;;;;;;;;;;;;;; -(defun my/surrounded-p () - (and (looking-back "[[{(]\\(\s+\\|\n\\)?\\(\s\\|\t\\)*") - (let* ((whitespace (match-string 1)) - (match-str (concat whitespace (match-string 2) "[])}]"))) - (looking-at-p match-str)))) - -(defun my/empty-line-p () - (zerop (length (s-trim (my/get-line))))) - -(defun my/get-line () - (buffer-substring (line-beginning-position) (line-end-position))) - -(defun my.backward-kill-to-bol-and-indent () - "Kill line to the first non-blank character. If invoked again -afterwards, kill line to column 1." - (interactive) - (let ((empty-line (my/empty-line-p))) - (evil-delete (point-at-bol) (point)) - (if (not empty-line) - (indent-according-to-mode)))) - -(defun my.point-at-first-non-blank() - (save-excursion (evil-first-non-blank) (point))) - -(defun my.move-to-bol () - "Moves cursor to the first non-blank character on the line. If -already there, move it to the true bol." - (interactive) - (evil-save-goal-column - (let ((point-at-bol (my.point-at-first-non-blank)) - (point (point))) - (if (= point-at-bol point) - (evil-move-beginning-of-line) - (unless (= (point-at-bol) point) - (evil-first-non-blank)))))) - -(defun my.move-to-eol () - (interactive) - (evil-save-goal-column - (let ((old-point (point))) - (when (comment-search-forward (point-at-eol) t) - (goto-char (match-beginning 0)) - (skip-syntax-backward " ^<*" (my.point-at-first-non-blank)) - - (if (eq old-point (point)) ; - (evil-move-end-of-line)))))) - -;; Mimic expandtab in vim -(defun my.backward-delete-whitespace-to-column () - "Delete back to the previous column of whitespace, or as much -whitespace as possible, or just one char if that's not possible." - (interactive) - (cond ;; If in a string - ((sp-point-in-string) - (call-interactively 'backward-delete-char-untabify)) - ;; If using tabs (or at bol), just delete normally - ((or indent-tabs-mode - (= (point-at-bol) (point))) - (call-interactively 'backward-delete-char)) - ;; Otherwise, delete up to the nearest tab column - (t (let ((movement (% (current-column) tab-width)) - (p (point))) - (when (= movement 0) - (setq movement tab-width)) - (save-match-data - (if (string-match "\\w*\\(\\s-+\\)$" (buffer-substring-no-properties (- p movement) p)) - (backward-delete-char (- (match-end 1) (match-beginning 1))) - (call-interactively 'backward-delete-char-untabify))))))) - -(defun my.dumb-indent () - "Inserts a tab character (or spaces x tab-width). Checks if the -auto-complete window is open." - (interactive) - (if indent-tabs-mode - (insert "\t") - (let* ((movement (% (current-column) tab-width)) - (spaces (if (zerop movement) tab-width (- tab-width movement)))) - (insert (s-repeat spaces " "))))) - -(defun my.inflate-space-maybe () - "Checks if point is surrounded by {} [] () delimiters and adds a -space on either side of the point if so." - (interactive) - (if (my/surrounded-p) - (progn (call-interactively 'self-insert-command) - (save-excursion (call-interactively 'self-insert-command))) - (call-interactively 'self-insert-command))) - -(defun my.deflate-space-maybe () - "Checks if point is surrounded by {} [] () delimiters, and deletes -spaces on either side of the point if so. Resorts to -`my.backward-delete-whitespace-to-column' otherwise." - (interactive) - (save-match-data - (if (my/surrounded-p) - (let ((whitespace-match (match-string 1))) - (cond ((not whitespace-match) - (call-interactively 'delete-backward-char)) - ((string-match "\n" whitespace-match) - (evil-delete (point-at-bol) (point)) - (delete-char -1) - (save-excursion (delete-char 1))) - (t - (just-one-space 0)))) - (my.backward-delete-whitespace-to-column)))) - -(defun my.newline-and-indent () - "Newline and indent; if in a comment, auto-comment and properly -indent the next line." - (interactive) - (cond ((sp-point-in-string) - (evil-ret)) - ((evil-in-comment-p) - (if (eq major-mode 'js2-mode) - (js2-line-break) - (call-interactively 'indent-new-comment-line))) - (t - (evil-ret-and-indent)))) - -(defun s-lines? (s) (length (s-lines s))) - - -;; Utility ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defun what-face (pos) - "Tells you the name of the face (point) is on." - (interactive "d") - (let ((face (or (get-char-property (point) 'read-face-name) - (get-char-property (point) 'face)))) - (if face (message "Face: %s" face) (message "No face at %d" pos)))) - -(defun what-col () - (interactive) - (message "Column %d" (current-column))) - -(defun my/append-to-list (list-var elements) - "Append ELEMENTS to the end of LIST." - (unless (consp elements) - (error "ELEMENTS must be a list")) - (let ((list (symbol-value list-var))) - (if list - (setcdr (last list) elements) - (set list-var elements))) - (symbol-value list-var)) - -(defun my/project-root (&optional force-pwd) - (if (and (not force-pwd) - (projectile-project-p)) - (projectile-project-root) - default-directory)) - -(defmacro f--exists? (file dir) - `(f-exists? (expand-file-name ,file ,dir))) diff --git a/init/core-editor.el b/init/core-editor.el index 3888422f7..21d6cce85 100644 --- a/init/core-editor.el +++ b/init/core-editor.el @@ -1,257 +1,38 @@ +;; Global editor behavior (+ evil) (provide 'core-editor) -;;;; Editor behavior ;;;;;;;;;;;;;;;; -(setq sentence-end-double-space nil) -;; (setq require-final-newline nil) -;; (setq mode-require-final-newline nil) -(setq-default fill-column 80) -(electric-indent-mode -1) ; In case of emacs 24.4 -(setq-default tab-width 4 - tab-always-indent nil - indent-tabs-mode nil) ; spaces instead of tabs - -;; Show tab characters -(global-whitespace-mode 1) -(setq whitespace-style '(face tabs tab-mark) ; needs to be re-set in every buffer - whitespace-display-mappings - '((tab-mark ?\t [?| ?\t] [?\\ ?\t]) - (newline-mark 10 [36 10]))) - -;;;; Modes 'n hooks ;;;;;;;;;;;;;;;;; -(associate-mode "/LICENSE[^/]*$" 'text-mode) -(associate-mode "zsh\\(env\\|rc\\)?$" 'sh-mode) -(associate-mode "z\\(profile\\|login\\|logout\\)?$" 'sh-mode) -(associate-mode "zsh/" 'sh-mode) -(associate-mode "\\.applescript$" 'applescript-mode) -(associate-mode "Cask$" 'emacs-lisp-mode) -(associate-mode "\\.el\\.gz$" 'emacs-lisp-mode) -(associate-mode "/Makefile$" 'makefile-gmake-mode) -(associate-mode "\\.plist$" 'nxml-mode) - -(add-hook 'before-save-hook 'delete-trailing-whitespace) -;; Kill special (\\*.+\\*) buffers that are buried -(run-with-idle-timer 10 t 'my:kill-other-buffers) - - -;;;; Evil ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(use-package evil - :pre-load (defvar evil-want-C-u-scroll t) - :init - (progn - (evil-mode 1) - - (setq evil-want-visual-char-semi-exclusive t - evil-search-module 'evil-search - evil-magic 'very-magic - - ;; Color-coded state cursors - evil-normal-state-cursor '("white" box) - evil-visual-state-cursor '("cyan" box) - evil-god-state-cursor '("orange" box)) - - ;; Fixes C-i's synonymity with TAB - (keyboard-translate ?\C-i ?\H-i) - - (add-hook! 'find-file-hook (setq evil-shift-width tab-width)) - - ;; modes to map to different default states - (dolist (mode-map '((cider-repl-mode . emacs) - (comint-mode . emacs) - (eshell-mode . emacs) - (fundamental-mode . normal) - (git-commit-mode . insert) - (git-rebase-mode . emacs) - (help-mode . normal) - (term-mode . emacs))) - (evil-set-initial-state `,(car mode-map) `,(cdr mode-map))) - - (use-package evil-ex-registers) - (use-package evil-exchange) - (use-package evil-indent-textobject) ; vii/vai/vaI - (use-package evil-numbers) - (use-package evil-visualstar) - (use-package evil-nerd-commenter :pre-load (setq evilnc-hotkey-comment-operator "g/")) - (use-package evil-space :init (evil-space-default-setup)) - (use-package evil-matchit :init (global-evil-matchit-mode 1)) - (use-package evil-surround :init (global-evil-surround-mode 1)) - (use-package evil-god-state) - (use-package evil-jumper - :pre-load (defvar evil-jumper-file (expand-file-name "jumplist" *tmp-dir)) - :config - (progn - (setq evil-jumper-auto-center t - evil-jumper-auto-save-interval 3600) - - (define-key evil-motion-state-map (kbd "H-i") 'evil-jumper/forward))) - - ;;;; ace-jump ;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Enable half-cursor blink when using ace-jump - (defadvice evil-ace-jump-char-mode (before evil-ace-jump-char-mode-op activate) (evil-half-cursor)) - (defadvice evil-ace-jump-word-mode (before evil-ace-jump-word-mode-op activate) (evil-half-cursor)) - (setq ace-jump-mode-scope 'global) ; limit ace-jump to current window - (setq ace-jump-mode-move-keys ; use a-z, 0-9 - (nconc (loop for i from ?a to ?z collect i) - (loop for i from ?A to ?Z collect i))) - ;; (setq ace-jump-mode-move-keys ; use a-z - ;; (loop for i from ?a to ?z collect i)) - - ;; Exit evil-exchange mode with (silently) -- and close - ;; minibuffer remotely if it happens to be left open - (defadvice evil-force-normal-state (before evil-esc-quit-exchange activate) - (shut-up (evil-exchange-cancel) - (if (minibuffer-window-active-p (minibuffer-window)) - (my:minibuffer-quit)))) - - (defadvice evil-visual-line (before spc-for-line-jump activate) - (define-key evil-motion-state-map (kbd "SPC") #'evil-ace-jump-line-mode)) - (defadvice evil-visual-char (before spc-for-char-jump activate) - (define-key evil-motion-state-map (kbd "SPC") #'evil-ace-jump-char-mode)) - (defadvice evil-visual-block (before spc-for-char-jump activate) - (define-key evil-motion-state-map (kbd "SPC") #'evil-ace-jump-char-mode)) - - ;; Switch to new splits after splitting - (defadvice evil-window-split (after evil-window-split-then-switch activate) - (evil-window-down 1)) - (defadvice evil-window-vsplit (after evil-window-vsplit-then-switch activate) - (evil-window-right 1)) - - ;; Add new filename symbols for ex-commands (aside from % and #) - (defun evil-ex-replace-special-filenames (file-name) - "Replace special symbols in FILE-NAME." - (let ((current-fname (buffer-file-name)) - (alternate-fname (and (other-buffer) - (buffer-file-name (other-buffer))))) - (setq file-name - ;; %:p => the project root (or current directory otherwise) - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:p\\)" - (my/project-root) file-name t t 2)) - (when current-fname - (setq file-name - ;; %:e => ext - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:e\\)" - (f-ext current-fname) file-name t t 2)) - (setq file-name - ;; %:r => filename - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:r\\)" - (f-no-ext current-fname) file-name t t 2)) - (setq file-name - ;; %:t => filename.ext - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:t\\)" - (f-base current-fname) file-name t t 2)) - (setq file-name - ;; % => file path for current frame - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)" - current-fname file-name t t 2))) - (when alternate-fname - (setq file-name - ;; # => file path for alternative frame - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)" - alternate-fname file-name t t 2))) - (setq file-name - (replace-regexp-in-string "\\\\\\([#%]\\)" - "\\1" file-name t))) - file-name))) - - ;;;; Editing plugins ;;;;;;;;;;;;;;;;;;; -(use-package anzu :init (global-anzu-mode)) -(use-package expand-region :commands (er/expand-region er/contract-region)) -(use-package rotate-text :commands (rotate-word-at-point rotate-region)) -(use-package smart-forward) +(use-package expand-region + :commands (er/expand-region er/contract-region)) + +(use-package rotate-text + :commands (rotate-word-at-point rotate-region)) (use-package smartparens + :init (require 'smartparens-config) :config (progn - (require 'smartparens-config) (smartparens-global-mode 1) - (setq blink-matching-paren nil) + (setq blink-matching-paren t) (setq sp-autowrap-region nil ; let evil-surround handle this sp-highlight-pair-overlay nil sp-show-pair-delay 0 sp-autoescape-string-quote nil) + ;; Handle newlines (sp-pair "{" nil :post-handlers '(("||\n[i]" "RET"))) (sp-pair "[" nil :post-handlers '(("||\n[i]" "RET"))) (sp-with-modes '(emacs-lisp-mode lisp-mode) (sp-local-pair "[" nil :post-handlers '(("|" "RET")))) + ;; Auto-close more conservatively (sp-pair "[" nil :unless '(sp-point-before-word-p sp-point-before-same-p)) (sp-pair "(" nil :unless '(sp-point-before-word-p sp-point-before-same-p)) (sp-pair "\"" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) (sp-pair "'" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) (sp-pair "\"" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) - (after yasnippet - (defadvice yas-expand (before advice-for-yas-expand activate) - (sp-remove-active-pair-overlay))))) - - -;;;; Keymap Fixes ;;;;;;;;;;;;;;;;;;;;;; -;; This section is dedicated to keymaps that "fix" certain keys so -;; that they behave more like vim (or how I like it). - -;; Restores "dumb" indentation to the tab key. This rustles a lot of -;; peoples' jimmies, apparently, but it's how I like it. -(bind 'insert (kbd "TAB") 'my.dumb-indent) -;; Except for lisp -(bind 'insert lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) -(bind 'insert emacs-lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) - -;; Highjacks backspace and space to: -;; a) expand spaces between delimiters intelligently: (|) -> ( | ) -;; b) the reverse of A: ( | ) -> (|) -;; c) allow backspace to delete indented blocks intelligently -;; d) and not do any of this magic when inside a string -(bind 'insert - (kbd "SPC") 'my.inflate-space-maybe - [remap backward-delete-char-untabify] 'my.deflate-space-maybe - [remap newline] 'my.newline-and-indent - - ;; Smarter move-to-beginning-of-line - [remap move-beginning-of-line] 'my.move-to-bol - - ;; Restore bash-esque keymaps in insert mode; C-w and C-a already exist - "\C-e" 'my.move-to-eol - "\C-u" 'my.backward-kill-to-bol-and-indent - - ;; Fixes delete - (kbd "") 'delete-char - - ;; Textmate-esque insert-line before/after - (kbd "") 'evil-open-below - (kbd "") 'evil-open-above) - -;; Fix osx keymappings and then some -(bind (kbd "") 'my.move-to-bol - (kbd "") 'my.move-to-eol - (kbd "") 'smart-up - (kbd "") 'smart-down - (kbd "") 'my.backward-kill-to-bol-and-indent) - -(add-hook! 'ido-setup-hook - (bind ido-completion-map - (kbd "") 'ido-delete-backward-updir - "\C-w" 'ido-delete-backward-word-updir)) - -;; Make ESC quit all the things -(bind [escape] 'keyboard-escape-quit) -(bind (list minibuffer-local-map - minibuffer-local-ns-map - minibuffer-local-completion-map - minibuffer-local-must-match-map - minibuffer-local-isearch-map) [escape] 'my:minibuffer-quit) - -(bind 'god [escape] 'evil-god-state-bail) -(bind 'normal special-mode-map [escape] 'popwin:close-popup-window) -(bind isearch-mode-map "\C-w" 'isearch-abort) -;; Close help/compilation windows with escape -(bind messages-buffer-mode-map [escape] 'kill-this-buffer) -(bind special-mode-map [escape] 'popwin:close-popup-window) -;;(bind 'normal diff-mode-map -;; [escape] 'kill-this-buffer -;; "q" 'kill-this-buffer) -; (bind 'normal c -; scope-minor-mode-keymap -; [escape] 'kill-this-buffer -; "q" 'kill-this-buffer) + (after "yasnippet" + (defadvice yas-expand (before advice-for-yas-expand activate) + (sp-remove-active-pair-overlay))))) diff --git a/init/core-evil.el b/init/core-evil.el new file mode 100644 index 000000000..0f28c82e4 --- /dev/null +++ b/init/core-evil.el @@ -0,0 +1,367 @@ +(provide 'core-evil) + +;;;; Eeeeeeevil ;;;;;;;;;;;;;;;;;;;;;;;; +(use-package evil + :pre-load + (setq evil-want-visual-char-semi-exclusive t + evil-search-module 'evil-search + evil-magic 'very-magic + evil-want-C-u-scroll t ; enable C-u for scrolling + evil-ex-visual-char-range t ; column range for ex commands + + ;; Color-coded state cursors + evil-normal-state-cursor '("white" box) + evil-emacs-state-cursor '("cyan" bar) + evil-insert-state-cursor '("white" bar) + evil-god-state-cursor '("orange" box) + evil-visual-state-cursor 'hollow + + ace-jump-mode-scope 'window + ace-jump-mode-move-keys (nconc (loop for i from ?a to ?z collect i) + (loop for i from ?A to ?Z collect i))) + :config + (progn + (evil-mode) + ;; Always ensure evil-shift-width is consistent with tab-width + (add-hook! 'find-file-hook (setq evil-shift-width tab-width)) + ;; highlight matching delimiters (only in insert mode) + (add-hook 'evil-insert-state-entry-hook 'show-paren-mode) + (add-hook 'evil-insert-state-exit-hook (λ (show-paren-mode -1))) + ;; Disable highlights on insert-mode + (add-hook 'evil-insert-state-entry-hook 'evil-ex-nohighlight) + + ;; Evil command window + ;;(my/cleanup-buffers-add "^\\*Command Line\\*$") + + ;; modes to map to different default states + (dolist (mode-map '((cider-repl-mode . emacs) + (comint-mode . emacs) + (fundamental-mode . normal) + (help-mode . normal) + (term-mode . emacs))) + (evil-set-initial-state `,(car mode-map) `,(cdr mode-map))) + + (progn ; evil plugins + (use-package evil-space :init (evil-space-default-setup)) + + (use-package evil-exchange + :config + (defadvice evil-force-normal-state (before evil-esc-quit-exchange activate) + (shut-up (evil-exchange-cancel)))) + + (use-package evil-ex-registers) + + (use-package evil-indent-textobject) ; vii/vai/vaI + + (use-package evil-numbers) + + (use-package evil-god-state) + + (use-package evil-matchit :init (global-evil-matchit-mode 1)) + + (use-package evil-surround :init (global-evil-surround-mode 1)) + + (use-package evil-nerd-commenter + :pre-load (setq evilnc-hotkey-comment-operator "gc")) + + (use-package evil-jumper + :pre-load (setq evil-jumper-file (expand-file-name "jumplist" my-tmp-dir)) + :config + (progn + (setq evil-jumper-auto-center t + evil-jumper-auto-save-interval 3600) + (define-key evil-motion-state-map (kbd "H-i") 'evil-jumper/forward))) + + (use-package ace-window) + + (use-package evil-visualstar)) + + (bind evil-ex-completion-map + "C-r" #'evil-ex-paste-from-register ; registers in ex-mode + "C-a" 'move-beginning-of-line + "" 'move-beginning-of-line + "" 'move-beginning-of-line + "" 'evil-delete-whole-line) + + (progn ; evil hacks + (defadvice evil-force-normal-state (before evil-esc-quit activate) + (shut-up (evil-ex-nohighlight) ; turn off highlights + ;; Exit minibuffer is alive + (if (minibuffer-window-active-p (minibuffer-window)) + (my--minibuffer-quit)))) + + ;; Popwin: close popup window, if any + (after "popwin" + (defadvice evil-force-normal-state (before evil-esc-quit-popwin activate) + (shut-up (popwin:close-popup-window)))) + + ;; Ace-Jump: Enable half-cursor blink when using ace-jump + (defadvice evil-ace-jump-char-mode (before evil-ace-jump-char-mode-op activate) + (evil-half-cursor)) + (defadvice evil-ace-jump-word-mode (before evil-ace-jump-word-mode-op activate) + (evil-half-cursor)) + (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) + ;; (setq ace-jump-mode-move-keys + ;; (nconc (loop for i from ?a to ?z collect i) + ;; (loop for i from ?A to ?Z collect i)) + + ;; https://github.com/winterTTr/ace-jump-mode/issues/23 + (defun ace-jump-two-chars-mode (&optional query-char query-char-2) + "AceJump two chars mode" + (interactive) + + (evil-half-cursor) + (setq query-char (or query-char (read-char ">"))) + (setq query-char-2 (or query-char-2 (read-char (concat ">" (string query-char))))) + + (if (eq (ace-jump-char-category query-char) 'other) + (error "[AceJump] Non-printable character")) + + ;; others : digit , alpha, punc + (setq ace-jump-query-char query-char) + (setq ace-jump-current-mode 'ace-jump-char-mode) + (ace-jump-do (regexp-quote (concat (char-to-string query-char) + (char-to-string query-char-2))))) + + ;; Jump to new splits + (defadvice evil-window-split (after evil-window-split-jump activate) + (evil-window-down 1)) + (defadvice evil-window-vsplit (after evil-window-vsplit-jump activate) + (evil-window-right 1))) + + (progn ; extensions + (defun evil-visual-line-state-p () + "Returns non-nil if in visual-line mode, nil otherwise." + (and (evil-visual-state-p) + (eq (evil-visual-type) 'line))) + + (defun evil-ex-replace-special-filenames (file-name) + "Replace special symbols in FILE-NAME. + + % => full path to file (/project/src/thing.c) + # => alternative file path (/project/include/thing.h) + %:p => path to project root (/project/) + %:d => path to current directory (/project/src/) + %:e => the file's extension (c) + %:r => the full path without its extension (/project/src/thing) + %:t => the file's basename (thing.c)" + (let ((current-fname (buffer-file-name)) + (alternate-fname (and (other-buffer) + (buffer-file-name (other-buffer))))) + (setq file-name + ;; %:p:h => the project root (or current directory otherwise) + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:p\\)" + (my--project-root) file-name t t 2)) + (setq file-name + ;; %:p => the project root (or current directory otherwise) + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:d\\)" + default-directory file-name t t 2)) + (when current-fname + (setq file-name + ;; %:e => ext + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:e\\)" + (f-ext current-fname) file-name t t 2)) + (setq file-name + ;; %:r => filename + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:r\\)" + (f-no-ext current-fname) file-name t t 2)) + (setq file-name + ;; %:t => filename.ext + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:t\\)" + (f-base current-fname) file-name t t 2)) + (setq file-name + ;; % => file path for current frame + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)" + current-fname file-name t t 2))) + (when alternate-fname + (setq file-name + ;; # => file path for alternative frame + (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)" + alternate-fname file-name t t 2))) + (setq file-name + (replace-regexp-in-string "\\\\\\([#%]\\)" + "\\1" file-name t))) + file-name)) + + ;; (evil-ex-define-cmd "r[esize]" 'my:resize-window) + + (progn ; ex-commands + (evil-ex-define-cmd "full[scr]" 'toggle-frame-fullscreen) + (evil-ex-define-cmd "present" 'toggle-theme) + (evil-ex-define-cmd "k[ill]" 'kill-this-buffer) ; Kill current buffer + (evil-ex-define-cmd "k[ill]o" 'cleanup-buffers) ; Kill current project buffers + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (evil-ex-define-cmd "echo" 'my:echo) + (evil-define-command my:echo (&optional output) + (interactive "") + (message "%s" output)) + + (evil-ex-define-cmd "k[ill]all" 'my:kill-buffers) ; Kill all buffers (bang = project buffers only) + (evil-define-command my:kill-buffers (&optional bang) + :repeat nil + (interactive "") + (if (and bang (projectile-project-p)) + (projectile-kill-buffers) + (mapc 'kill-buffer (buffer-list))) + (delete-other-windows)) + + (evil-ex-define-cmd "ini" 'my:init-files) + (evil-define-command my:init-files (&optional bang) + :repeat nil + (interactive "") + (if bang + (ido-find-file-in-dir my-init-dir) + (ido-find-file-in-dir my-dir))) + + (evil-ex-define-cmd "n[otes]" 'my:notes) + (evil-define-command my:notes () + :repeat nil + (interactive) + (ido-find-file-in-dir org-directory)) + + (evil-ex-define-cmd "recompile" 'my:byte-compile) + (evil-define-command my:byte-compile (&optional bang) + :repeat nil + (interactive "") + (if bang + (byte-recompile-directory (concat my-dir ".cask") 0 t) + (byte-recompile-directory my-dir 0 t))) + + (evil-ex-define-cmd "build" 'my:build) + (evil-define-command my:build (arguments &optional bang) + :repeat t + (interactive "") + (my-build arguments)) + + (evil-ex-define-cmd "cd" 'my:cd) + (evil-define-command my:cd (dir) + :repeat nil + (interactive "") + (cd (if (zerop (length dir)) "~" dir))) + + (defun --save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit)) + (evil-ex-define-cmd "en[ew]" 'my:create-file) + (evil-define-command my:create-file (path &optional bang) + "Deploy files (and their associated templates) quickly. Will prompt +you to fill in each snippet field before buffer closes unless BANG is +provided." + :repeat nil + (interactive "") + (let ((dir (f-dirname path)) + (fullpath (f-full path)) + (is-auto t)) + (when (and bang (not (f-exists? dir))) (f-mkdir dir)) + (if (f-exists? dir) + (if (f-exists? fullpath) + (error "File already exists: %s" path) + (find-file fullpath) + (add-hook 'yas-after-exit-snippet-hook '--save-exit) + (if bang (--save-exit))) + (error "Directory doesn't exist: %s" dir)))) + + (evil-ex-define-cmd "ren[ame]" 'my:rename-this-file) ; Rename file . Bang: Delete old one + (evil-define-command my:rename-this-file (new-name &optional bang) + "Renames current buffer and file it is visiting. Replaces %, # and other + variables (see `evil-ex-replace-special-filenames')" + :repeat nil + (interactive "") + (let ((name (buffer-name)) + (filename (buffer-file-name))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (let ((new-name + (evil-ex-replace-special-filenames (if new-name + new-name + (read-file-name "New name: " filename))))) + (if (get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name) + (rename-file filename new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + (set-buffer-modified-p nil) + (save-place-forget-unreadable-files) + (when bang + (delete-file filename)) + (message "File '%s' successfully renamed to '%s'" + name (file-name-nondirectory new-name))))))) + + (evil-ex-define-cmd "x" 'my:scratch-buffer) + (evil-define-operator my:scratch-buffer (beg end &optional bang) + "Send a selection to the scratch buffer. If BANG, then send it to org-capture + instead." + :move-point nil + :type inclusive + (interactive "") + (let ((mode major-mode) + (text (when (and (evil-visual-state-p) beg end) + (buffer-substring beg end)))) + (if bang + ;; use org-capture with bang + (if text + (org-capture-string text) + (org-capture)) + ;; or scratch buffer by default + (let ((project-dir (projectile-project-root)) + (buffer-name (if (projectile-project-p) + (format "*scratch* (%s)" (projectile-project-name)) + "*scratch*"))) + (popwin:popup-buffer (get-buffer-create buffer-name)) + (when (eq (get-buffer buffer-name) (current-buffer)) + (cd project-dir) + (if text (insert text)) + (funcall mode)))))) + + (evil-ex-define-cmd "al[ign]" 'my:align) + (evil-define-command my:align (beg end &optional regexp bang) + :repeat nil + (interactive "") + (when regexp + (align-regexp beg end + (concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1))) + + (evil-ex-define-cmd "retab" 'my:retab) + (evil-define-operator my:retab (beg end) + "Akin to vim's :retab, this changes all tabs-to-spaces or spaces-to-tabs, + depending on `indent-tab-mode'. Untested." + :motion nil + :move-point nil + :type line + (interactive "") + (unless (and beg end) + (setq beg (point-min)) + (setq end (point-max))) + (if indent-tabs-mode + (tabify beg end) + (untabify beg end))) + + (evil-ex-define-cmd "run" 'my:run-code) + (evil-define-operator my:run-code (beg end) + :move-point nil + (interactive "") + (cond ((and beg end) + (my-run-code-region beg end)) + (t + (my-run-code-buffer)))) + + (evil-ex-define-cmd "sq[uint]" 'my:narrow-indirect) ; Narrow buffer to selection + (evil-define-operator my:narrow-indirect (beg end) + "Indirectly narrow the region from BEG to END." + :move-point nil + :type exclusive + :repeat nil + (interactive "") + (evil-normal-state) + (narrow-to-region-indirect beg end)) + + (evil-define-operator my:send-region-to-repl (beg end &optional bang) + :motion nil + :move-point nil + :type exclusive + :repeat nil + (interactive "") + (cond ((and beg end) + (my-send-region-to-repl beg end)) + (t + (my-switch-to-repl))))))) diff --git a/init/core-osx.el b/init/core-osx.el index 11657f1f0..74df39ae2 100644 --- a/init/core-osx.el +++ b/init/core-osx.el @@ -1,21 +1,46 @@ +;; Mac-specific settings (provide 'core-osx) -(when is-mac - ;; Use a shared clipboard - (setq x-select-enable-clipboard t) - ;; Curse Lion and its sudden but inevitable fullscreen mode! - (setq ns-use-native-fullscreen nil) - ;; Don't open files from the workspace in a new frame - (setq ns-pop-up-frames nil) +;; Use a shared clipboard +(setq x-select-enable-clipboard t) +;; Curse Lion and its sudden but inevitable fullscreen mode! +(setq ns-use-native-fullscreen nil) +;; Don't open files from the workspace in a new frame +(setq ns-pop-up-frames nil) - ;; fix emacs PATH on OSX (GUI only) - (use-package exec-path-from-shell - :if (memq window-system '(mac ns)) - :init (exec-path-from-shell-initialize)) +;; fix emacs PATH on OSX (GUI only) +(use-package exec-path-from-shell + :if (memq window-system '(mac ns)) + :init (exec-path-from-shell-initialize)) +(after "evil" ;; On OSX, stop copying each visual state move to the clipboard: ;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on ;; Most of this code grokked from: ;; http://stackoverflow.com/questions/15873346/elisp-rename-macro (defadvice evil-visual-update-x-selection (around clobber-x-select-text activate) (unless (featurep 'ns) ad-do-it))) + +;; Send current file to OSX apps +(defun my--open-file-with (path &optional appName) + (if (and appName + (stringp appName) + (not (string= "" appName))) + (setq appName (concat "-a " appName ".app"))) + (shell-command (concat "open " appName " " (shell-quote-argument path)))) + +(defun my-open-with (appName) + (interactive "sApp name: ") + (my--open-file-with buffer-file-name appName)) + +(defun my-send-to-transmit () + (interactive) (my-open-with "Transmit")) + +(defun my-send-to-launchbar () + (interactive) (my-open-with "LaunchBar")) + +(defun my-send-dir-to-launchbar () + (interactive) (my--open-file-with default-directory "LaunchBar")) + +(defun my-send-dir-to-finder () + (interactive) (my--open-file-with default-directory "Finder")) diff --git a/init/core-ui.el b/init/core-ui.el index 0683ac33b..4eb750df7 100644 --- a/init/core-ui.el +++ b/init/core-ui.el @@ -1,54 +1,55 @@ +;; User interface layout & behavior (provide 'core-ui) +;;;; Load Theme ;;;;;;;;;;;;;;;;;;;;;;;; +(when window-system + ;; No transparency! + (set-frame-parameter nil 'alpha 100) + + (unless (member *default-font (font-family-list)) + (error "Font %s isn't installed" *default-font)) + + (let ((font-str (concat *default-font "-" (number-to-string *default-font-size)))) + (add-to-list 'default-frame-alist `(font . ,font-str)) + (add-to-list 'initial-frame-alist `(font . ,font-str)))) + +(add-to-list 'custom-theme-load-path my-themes-dir) +(load-dark-theme) + + ;;;; GUI Settings ;;;;;;;;;;;;;;;;;;;;;; -(setq ring-bell-function 'ignore) -(add-to-list 'default-frame-alist `(font . ,*font)) -(add-to-list 'default-frame-alist '(alpha . 100)) ; *slightly* transparent window - -(when (functionp 'scroll-bar-mode) (scroll-bar-mode -1)) ; no scrollbar -(when (functionp 'tool-bar-mode) (tool-bar-mode -1)) ; no toolbar -(when (functionp 'menu-bar-mode) (menu-bar-mode -1)) ; no menubar -(when (fboundp 'fringe-mode) (fringe-mode '(5 . 10))) ; no nonsense - -(defun toggle-transparency () - (interactive) - (let ((frame (selected-frame))) - (if (= (frame-parameter frame 'alpha) 0) - (set-frame-parameter frame 'alpha 100) - (set-frame-parameter frame 'alpha 0)))) - - -;;;; Other Settings ;;;;;;;;;;;;;;;;;;;; -(blink-cursor-mode 1) ; blink cursor -(global-hl-line-mode -1) ; highlight line -(line-number-mode 1) ; hide line no in modeline -(column-number-mode 1) ; hide col no in modeline -(show-paren-mode -1) ; highlight matching delimiters -(setq show-paren-delay 0) - -(setq linum-format (quote "%4d ")) -;; (add-hook 'text-mode-hook 'linum-mode) -;; (add-hook 'prog-mode-hook 'linum-mode) - -;; Show full path in window title -(setq frame-title-format - '(:eval (if (buffer-file-name) (abbreviate-file-name (buffer-file-name)) "%b"))) +(tooltip-mode -1) +(blink-cursor-mode 1) ; blink cursor +;; (global-hl-line-mode 1) ; highlight line ;; Multiple cursors across buffers cause a strange redraw delay for ;; some things, like auto-complete or evil-mode's cursor color ;; switching. (setq-default cursor-in-non-selected-windows nil) -;; do not soft-wrap lines -(setq-default truncate-lines t) -(setq truncate-partial-width-windows nil) -(add-hook! 'help-mode-hook (setq truncate-lines nil)) - -(setq ediff-window-setup-function 'ediff-setup-windows-plain) -(setq indicate-buffer-boundaries nil) -(setq indicate-empty-lines nil) (setq-default visible-bell nil) ; silence of the bells (setq-default use-dialog-box nil) ; avoid GUI +(setq-default redisplay-dont-pause t) + +;; do not soft-wrap lines +(setq-default truncate-lines t) +(setq-default truncate-partial-width-windows nil) +(setq-default indicate-buffer-boundaries nil) +(setq-default indicate-empty-lines nil) + +(when (functionp 'scroll-bar-mode) (scroll-bar-mode -1)) ; no scrollbar +(when (functionp 'tool-bar-mode) (tool-bar-mode -1)) ; no toolbar +(when (functionp 'menu-bar-mode) (menu-bar-mode -1)) ; no menubar +(when (fboundp 'fringe-mode) (fringe-mode '(5 . 10))) ; no nonsense + +(when window-system + (setq frame-title-format '(buffer-file-name "%f" ("%b"))) + (tooltip-mode -1) + (blink-cursor-mode 1)) + +;; Show full path in window title +(setq frame-title-format + '(:eval (if (buffer-file-name) (abbreviate-file-name (buffer-file-name)) "%b"))) ;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -69,16 +70,16 @@ " Abbrev" " WS" " GitGutter" - " Anzu" " Undo-Tree" - " AC" " Projectile\\[.+\\]" + " hs" + " ElDoc" ) "\\|")) :init (progn (setq sml/no-confirm-load-theme t sml/mode-width 'full - sml/extra-filler 2 + sml/extra-filler (if window-system 1 0) sml/show-remote nil sml/modified-char "*" sml/encoding-format nil) @@ -86,7 +87,7 @@ (setq sml/replacer-regexp-list '(("^~/Dropbox/Projects/" "PROJECTS:") ("^~/.emacs.d/" "EMACS.D:"))) - (after evil (setq evil-mode-line-format nil)) + (after "evil" (setq evil-mode-line-format nil)) (setq-default mode-line-misc-info '((which-func-mode ("" which-func-format "")) @@ -94,9 +95,8 @@ (add-hook! 'after-change-major-mode-hook (setq mode-line-format - '(" " + '((if window-system " ") "%e" - ;; anzu--mode-line-format mode-line-mule-info mode-line-client mode-line-remote diff --git a/init/core.el b/init/core.el index ffd273957..7332d2976 100644 --- a/init/core.el +++ b/init/core.el @@ -1,159 +1,275 @@ (provide 'core) +(cd "~") ; instead of / + +(require 'cask) +(cask-initialize) + (defconst is-mac (eq system-type 'darwin)) (defconst is-linux (eq system-type 'gnu/linux)) -;;;; Load theme ;;;;;;;;;;;;;;;;;;;;;;;;;; -(add-to-list 'custom-theme-load-path *themes-dir) -(load-theme *theme t) - - -;;;; Emacs under the hood ;;;;;;;;;;;;;;;; -(prefer-coding-system 'utf-8) -(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no -(setq-default - load-prefer-newer t ; load newer .el over older .elc - gc-cons-threshold 50000000 ; avoid garbage collection (default is 400k) - enable-recursive-minibuffers nil - redisplay-dont-pause t - confirm-kill-emacs nil - compilation-scroll-output t) - -;; Sane scroll settings -(setq scroll-margin 5 - scroll-conservatively 100000 - scroll-preserve-screen-position 1 - echo-keystrokes 0.02 ; Show keystrokes - inhibit-startup-screen t ; don't show EMACs start screen - inhibit-splash-screen t - inhibit-startup-buffer-menu t - initial-major-mode 'text-mode - initial-scratch-message nil - initial-scratch-buffer nil) ; empty scratch buffer - ;; Make sure undo/backup folders exist -(require 'f) -(defconst *tmp-dir-undo (f-expand "undo" *tmp-dir)) -(defconst *tmp-dir-backup (f-expand "backup" *tmp-dir)) -(defconst *tmp-dir-autosave (f-expand "autosave" *tmp-dir)) -(unless (f-dir? *tmp-dir) - (f-mkdir *tmp-dir - *tmp-dir-undo - *tmp-dir-backup - *tmp-dir-autosave)) +(defconst my-tmp-dir-undo (expand-file-name "undo" my-tmp-dir)) +(defconst my-tmp-dir-backup (expand-file-name "backup" my-tmp-dir)) +(defconst my-tmp-dir-autosave (expand-file-name "autosave" my-tmp-dir)) +(unless (file-directory-p my-tmp-dir) + (make-directory my-tmp-dir-undo t) + (make-directory my-tmp-dir-backup t) + (make-directory my-tmp-dir-autosave t)) -;; Disable all backups (that's what git/dropbox are for) -(setq make-backup-files nil - create-lockfiles nil - auto-save-default nil - auto-save-list-file-name (concat *tmp-dir-autosave ".auto-save") - ;; In case I want to reactivate backup files - backup-directory-alist `((".*" . ,*tmp-dir-backup)) - auto-save-file-name-transforms `((".*" ,*tmp-dir-autosave t))) +(setq load-prefer-newer t) +(setq debug-on-quit *debug-mode) -;; Remember undo history -(setq-default undo-tree-history-directory-alist `(("." . ,*tmp-dir-undo))) -(setq-default undo-tree-auto-save-history t) +(require 'shut-up) +(setq shut-up-ignore *debug-mode) +(when noninteractive (shut-up-silence-emacs)) ; http://youtu.be/Z6woIRLnbmE -;;;; Save history across sessions -;; search entries -(defvar savehist-additional-variables '(search ring regexp-search-ring)) -;; keep the home clean -(defvar savehist-file (f-expand "savehist" *tmp-dir)) -(savehist-mode 1) +(shut-up + ;;;; Sane defaults ;;;;;;;;;;;;;;;;;;;;;;; + (line-number-mode 1) ; hide line no in modeline + (column-number-mode 1) ; hide col no in modeline + (auto-compression-mode t) ; Transparently open compressed files + (global-font-lock-mode t) ; Enable syntax highlighting for older emacs + (global-auto-revert-mode 1) ; revert buffers for changed files + (electric-indent-mode -1) ; In case of emacs 24.4 + + ;;; window layout undo/redo + (winner-mode 1) + (setq winner-boring-buffers '("*Completions*" "*Help*")) + + ;;; UTF-8 please + (setq locale-coding-system 'utf-8) ; pretty + (set-terminal-coding-system 'utf-8) ; pretty + (set-keyboard-coding-system 'utf-8) ; pretty + (set-selection-coding-system 'utf-8) ; please + (prefer-coding-system 'utf-8) ; with sugar on top + + (fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no + + ;;; Show tab characters + ;; (global-whitespace-mode 1) + (setq whitespace-style '(face tabs tab-mark) ; needs to be re-set in every buffer + whitespace-display-mappings + '((tab-mark ?\t [?| ?\t] [?\\ ?\t]) + (newline-mark 10 [36 10]))) ; for whitespace-newline-mode + + ;; avoid garbage collection (default is 400k) + (setq-default gc-cons-threshold 20000000) + (setq-default confirm-kill-emacs nil) + + (setq-default fill-column 80) + + ;; minibufferception? Nay! + (setq-default enable-recursive-minibuffers nil) + + ;; Sane scroll settings + (setq scroll-margin 5) + (setq scroll-conservatively 9999) + (setq scroll-preserve-screen-position 1) + + ;; Show me those keystrokes + (setq echo-keystrokes 0.02) + + ;; I'll use visual mode, kthxbai + (setq shift-select-mode nil) + + (setq ring-bell-function 'ignore) + + (setq inhibit-startup-screen t) ; don't show EMACs start screen + (setq inhibit-splash-screen t) + (setq inhibit-startup-buffer-menu t) + + (setq initial-major-mode 'text-mode) ; initial scratch buffer mode + (setq initial-scratch-message nil) + (setq initial-scratch-buffer nil) ; empty scratch buffer + + (setq compilation-always-kill t) + (setq compilation-ask-about-save nil) + (setq compilation-scroll-output t) + + (setq sentence-end-double-space nil) ; sentences end with periods. Period. + + (setq eval-expression-print-level nil) + + (setq show-paren-delay 0) + + (setq ediff-diff-options "-w") + (setq ediff-split-window-function 'split-window-horizontally) ; side-by-side diffs + (setq ediff-window-setup-function 'ediff-setup-windows-plain) ; no extra frames + + ;; Fixes C-i's synonymity with TAB + (keyboard-translate ?\C-i ?\H-i) + + ;;;; Backup ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Disable all backups (that's what git/dropbox are for) + (setq bookmark-save-flag t) + (setq bookmark-default-file (expand-file-name "bookmarks" my-tmp-dir)) + (setq auto-save-default nil) + (setq auto-save-list-file-name (expand-file-name ".auto-save" my-tmp-dir-autosave)) + (setq auto-save-file-name-transforms `((".*" ,my-tmp-dir-autosave t))) + ;; In case I want to reactivate backup files + (setq make-backup-files nil) + (setq create-lockfiles nil) + (setq backup-directory-alist `((".*" . ,my-tmp-dir-backup))) + ;; Remember undo history + (setq-default undo-tree-auto-save-history t) + (setq-default undo-tree-history-directory-alist `(("." . ,my-tmp-dir-undo))) + ;;;; Save history across sessions + (setq savehist-additional-variables '(search ring regexp-search-ring)) + (setq savehist-file (f-expand "savehist" my-tmp-dir)) ; keep the home clean + (savehist-mode 1) + + ;; Save cursor location across sessions + (require 'saveplace) + (setq save-place-file (f-expand "saveplace" my-tmp-dir)) + (add-hook 'find-file-hook ; activate save-place for files that exist + (lambda() + (if (file-exists-p buffer-file-name) + (setq save-place t)))) + + (require 'recentf) + (setq recentf-max-menu-items 0) + (setq recentf-max-saved-items 1000) + (setq recentf-auto-cleanup 'never) + (setq recentf-save-file (concat my-tmp-dir "recentf")) + (setq recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last\\'" "\\.revive\\'", "/TAGS\\'")) + (recentf-mode 1) + + ;; What we do every night, Pinkie... + (defun display-startup-echo-area-message () + (message "What're we gonna do tonight, Brain? (Loaded in %s)" (emacs-init-time))) -;;;; My personal global mode ;;;;;;;;;;;;; -(defvar my-mode-map (make-sparse-keymap)) -(define-minor-mode my-mode - "My personal global mode." - :global t - :keymap my-mode-map) + ;;;; Editor behavior ;;;;;;;;;;;;;;;; + ;; spaces instead of tabs + (setq-default indent-tabs-mode nil) ; spaces instead of tabs + (setq-default tab-always-indent nil) + (setq-default tab-width 4) + + (setq delete-trailing-lines nil) + (add-hook 'before-save-hook 'delete-trailing-whitespace) + (add-hook 'makefile-mode-hook 'indent-tabs-mode) ; Use normal tabs in makefiles + ;; Make sure scratch buffer is always "in a project" + (add-hook 'find-file-hook + (lambda() + (let ((buffer (get-buffer "*scratch*")) + (pwd (my--project-root))) + (when (buffer-live-p buffer) + (save-window-excursion + (switch-to-buffer buffer) + (unless (eq (my--project-root) pwd) + (cd pwd) + (rename-buffer (format "*scratch* (%s)" (file-name-base (directory-file-name pwd)))))))))) + + ;; My own minor mode! + (define-minor-mode my-mode :global t :keymap (make-sparse-keymap)) -;;;; Behavior adjustments ;;;;;;;;;;;;;;;; -;; Make next/previous-buffer skip special buffers -(defadvice next-buffer (after void-messages-buffer-in-next-buffer activate) - "Advice around `next-buffer' to avoid going into the *Messages* buffer." - (when (string-match "\\`\\*.+\\*\\'" (buffer-name)) (next-buffer))) -(defadvice previous-buffer (after avoid-messages-buffer-in-previous-buffer activate) - "Advice around `previous-buffer' to avoid going into the *Messages* buffer." - (when (string-match "\\`\\*.+\\*\\'" (buffer-name)) (previous-buffer))) + ;;;; Behavior adjustments ;;;;;;;;;;;;;;;; + ;; Skip special buffers on next/previous-buffer + (defadvice next-buffer (after void-messages-buffer-in-next-buffer activate) + (when (string-match "\\`\\*.+\\*\\'" (buffer-name)) (next-buffer))) + (defadvice previous-buffer (after avoid-messages-buffer-in-previous-buffer activate) + (when (string-match "\\`\\*.+\\*\\'" (buffer-name)) (previous-buffer))) + ;; Don't kill the scratch buffer, just empty and bury it + (defadvice kill-this-buffer (around kill-this-buffer-or-empty-scratch activate) + (if (string-match-p "^\\*scratch\\*" (buffer-name)) + (bury-buffer) + ad-do-it)) -;;;; Automatic minor modes ;;;;;;;;;;;;;;; -(defvar auto-minor-mode-alist () - "Alist of filename patterns vs correpsonding minor mode functions, + ;;;; Automatic minor modes ;;;;;;;;;;;;;;; + (defvar auto-minor-mode-alist () + "Alist of filename patterns vs correpsonding minor mode functions, see `auto-mode-alist' All elements of this alist are checked, meaning you can enable multiple minor modes for the same regexp.") -(defun enable-minor-mode-based-on-extension () - "check file name against auto-minor-mode-alist to enable minor modes + (defun enable-minor-mode-based-on-extension () + "check file name against auto-minor-mode-alist to enable minor modes the checking happens for all pairs in auto-minor-mode-alist" - (when buffer-file-name - (let ((name buffer-file-name) - (remote-id (file-remote-p buffer-file-name)) - (alist auto-minor-mode-alist)) - ;; Remove backup-suffixes from file name. - (setq name (file-name-sans-versions name)) - ;; Remove remote file name identification. - (when (and (stringp remote-id) - (string-match-p (regexp-quote remote-id) name)) - (setq name (substring name (match-end 0)))) - (while (and alist (caar alist) (cdar alist)) - (if (string-match (caar alist) name) - (funcall (cdar alist) 1)) - (setq alist (cdr alist)))))) - -(add-hook 'find-file-hook 'enable-minor-mode-based-on-extension) - -(global-auto-revert-mode 1) ; revert buffers for changed files -(require 'shut-up) -(when noninteractive (shut-up-silence-emacs)) - -;; What we do every night, Pinkie... -(defun my/greeter () (message "What're we gonna do tonight, Brain?")) -(defalias 'display-startup-echo-area-message 'my/greeter) - -(when (fboundp 'winner-mode) (winner-mode 1)) ; window layout undo/redo + (when buffer-file-name + (let ((name buffer-file-name) + (remote-id (file-remote-p buffer-file-name)) + (alist auto-minor-mode-alist)) + ;; Remove backup-suffixes from file name. + (setq name (file-name-sans-versions name)) + ;; Remove remote file name identification. + (when (and (stringp remote-id) + (string-match-p (regexp-quote remote-id) name)) + (setq name (substring name (match-end 0)))) + (while (and alist (caar alist) (cdar alist)) + (if (string-match (caar alist) name) + (funcall (cdar alist) 1)) + (setq alist (cdr alist)))))) + (add-hook 'find-file-hook 'enable-minor-mode-based-on-extension) -;;;; Utility plugins ;;;;;;;;;;;;;;;;;; -;; Package management bootstrap -(require 'use-package) -(setq package-enable-at-startup nil - delete-old-versions t) -;; Add ./elisp/* to load-path -(let ((default-directory *elisp-dir)) + ;;;; Utility plugins ;;;;;;;;;;;;;;;;;; + (require 'defuns) ; all the defuns + (require 'use-package) ; Package management bootstrap + (setq use-package-verbose *debug-mode) + + ;; Generate autoloads if necessary + (defun my-update-autoloads (&optional forcep) + (interactive) + (setq generated-autoload-file (concat my-init-dir "autoload.el")) + (when (or forcep (not (file-exists-p generated-autoload-file))) + (if forcep (delete-file generated-autoload-file)) + (update-directory-autoloads my-init-dir my-elisp-dir)) + (require 'autoload)) + + (my-update-autoloads) + + ;; Add elisp dirs to load-path + (let ((default-directory my-elisp-dir)) (normal-top-level-add-to-load-path '(".")) (normal-top-level-add-subdirs-to-load-path)) -(use-package key-chord - :init (key-chord-mode 1) - :config (setq key-chord-two-keys-delay 0.5)) + (use-package smex + :commands (smex smex-major-mode-commands) + :config + (progn + (smex-initialize) + ;; Hook up smex to auto-update, rather than update on every run + (defun smex-update-after-load (unused) + (when (boundp 'smex-cache) (smex-update))) -(use-package recentf - :init - (progn (setq recentf-max-menu-items 0 - recentf-max-saved-items 100 - recentf-auto-cleanup 'never - recentf-save-file (concat *tmp-dir "recentf") - recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last\\'" "\\.revive\\'", "/TAGS\\'")) - (recentf-mode 1))) + (add-hook 'after-load-functions 'smex-update-after-load))) -(use-package smex - :commands (smex smex-major-mode-commands) - :config - (progn (smex-initialize) - ;; Hook up smex to auto-update, rather than update on every run - (defun smex-update-after-load (unused) - (when (boundp 'smex-cache) (smex-update))) - (add-hook 'after-load-functions 'smex-update-after-load))) + (use-package popwin + :init (popwin-mode 1) + :config + (progn ; popwin config + (setq popwin:popup-window-height 0.45) -(use-package popwin - :init (popwin-mode 1) - :config - (progn (setq popwin:popup-window-height 0.45) - (push '(diff-mode :position bottom :stick t) popwin:special-display-config) - (push '("*Backtrace*") popwin:special-display-config) - (push '("*Warnings*") popwin:special-display-config) - (push '("*Process List*") popwin:special-display-config))) + (push '(diff-mode :position bottom :stick t) popwin:special-display-config) + (push '("*Backtrace*") popwin:special-display-config) + (push '("*Warnings*") popwin:special-display-config) + (push '("*Process List*") popwin:special-display-config) + (push '("*Compile-Log*" :height 0.3 :position bottom :noselect t) popwin:special-display-config) + (push '(" *undo-tree*" :width 0.3 :position right) popwin:special-display-config) + (push '("^\\*scratch\\*.*" :regexp t :stick t) popwin:special-display-config) + + (after "evil" + (evil-ex-define-cmd "l[ast]" 'popwin:popup-last-buffer) + (evil-ex-define-cmd "m[sg]" 'popwin:messages)) + + (defun popwin:toggle-popup-window () + (interactive) + (if (popwin:popup-window-live-p) + (popwin:close-popup-window) + (popwin:popup-last-buffer))))) + + ;; (require 'key-chord) + ;; (key-chord-mode 1) + ;; (setq key-chord-two-keys-delay 0.2) + + + ;;;; Start the party ;;;;;;;;;;;;;;;;;;; + (if is-mac (require 'core-osx)) + (require 'core-ui) + (require 'core-evil) + (require 'core-editor) + + (require 'server) + (unless (server-running-p) + (server-start))) diff --git a/init/defuns-buffers.el b/init/defuns-buffers.el new file mode 100644 index 000000000..7c2a942a3 --- /dev/null +++ b/init/defuns-buffers.el @@ -0,0 +1,56 @@ +;; Inspired by http://demonastery.org/2013/04/emacs-evil-narrow-region/ +;;;###autoload +(defun my-narrow-to-region-indirect (start end) + "Restrict editing in this buffer to the current region, indirectly." + (interactive "r") + (deactivate-mark) + (let ((buf (clone-indirect-buffer nil nil))) + (with-current-buffer buf + (narrow-to-region start end)) + (switch-to-buffer buf))) + + +;; Killing Buffers ;;;;;;;;;;;;;;;;;;;;; +;; Buffer defuns +(defvar my-cleanup-buffers-alist '("^ \\*" + "^\\*Backtrace\\*$" + "^\\*Warnings\\*$" + "^\\*Compile-Log\\*$" + "^\\*Ediff.*\\*$" + help-mode + dired-mode + reb-mode) + "A list of buffer name regexps or major-mode symbols. If buried buffers + match/have that mode active, `cleanup-buffers' will kill them.") + +;;;###autoload +(defun my--cleanup-buffers-add (regexp) + (add-to-list 'my-cleanup-buffers-alist regexp)) + +;;;###autoload +(defun my-cleanup-buffers () + "Kill left-over temporary, dired or buried special buffers" + (interactive) + (let* ((this-frame (selected-frame)) + (kill-list (buffer-list this-frame))) + (setq kill-list + (-filter (lambda (b) + (unless (get-buffer-window b) ; don't kill if visible + (-any? (lambda (pred) + (cond ((stringp pred) + (s-matches? pred (buffer-name b))) + ((symbolp pred) + (eq (buffer-local-value 'major-mode b) pred)))) + my-cleanup-buffers-alist))) + kill-list)) + + (message "Cleaned up %s buffers" (length kill-list)) + (mapc 'kill-buffer kill-list))) + +;;;###autoload +(defun my-kill-matching-buffers (regexp &optional buffer-list) + (interactive) + (mapc (lambda (b) + (if (s-matches? regexp (buffer-name b)) + (kill-buffer b))) + (if buffer-list buffer-list (buffer-list)))) diff --git a/init/defuns-text.el b/init/defuns-text.el new file mode 100644 index 000000000..9b3afac64 --- /dev/null +++ b/init/defuns-text.el @@ -0,0 +1,123 @@ +;;;###autoload +(defun my--point-at-bol-non-blank() + (save-excursion (evil-first-non-blank) (point))) + +;;;###autoload +(defun my--surrounded-p () + (and (looking-back "[[{(]\\(\s+\\|\n\\)?\\(\s\\|\t\\)*") + (let* ((whitespace (match-string 1)) + (match-str (concat whitespace (match-string 2) "[])}]"))) + (looking-at-p match-str)))) + +;;;###autoload +(defun my.backward-kill-to-bol-and-indent () + "Kill line to the first non-blank character. If invoked again +afterwards, kill line to column 1." + (interactive) + (let ((empty-line (sp-point-in-blank-line))) + (evil-delete (point-at-bol) (point)) + (if (not empty-line) + (indent-according-to-mode)))) + +;;;###autoload +(defun my.move-to-bol () + "Moves cursor to the first non-blank character on the line. If +already there, move it to the true bol." + (interactive) + (evil-save-goal-column + (let ((point-at-bol (my--point-at-bol-non-blank)) + (point (point))) + (if (= point-at-bol point) + (evil-move-beginning-of-line) + (unless (= (point-at-bol) point) + (evil-first-non-blank)))))) + +;;;###autoload +(defun my.move-to-eol () + (interactive) + (evil-save-goal-column + (let ((old-point (point))) + (when (comment-search-forward (point-at-eol) t) + (goto-char (match-beginning 0)) + (skip-syntax-backward " ^<*" (my--point-at-bol-non-blank)) + + (if (eq old-point (point)) ; + (evil-move-end-of-line)))))) + +;; Mimic expandtab in vim +;;;###autoload +(defun my.backward-delete-whitespace-to-column () + "Delete back to the previous column of whitespace, or as much +whitespace as possible, or just one char if that's not possible." + (interactive) + (cond ;; If in a string + ((sp-point-in-string) + (call-interactively 'backward-delete-char-untabify)) + ;; If using tabs (or at bol), just delete normally + ((or indent-tabs-mode + (= (point-at-bol) (point))) + (call-interactively 'backward-delete-char)) + ;; Otherwise, delete up to the nearest tab column + (t (let ((movement (% (current-column) tab-width)) + (p (point))) + (when (= movement 0) + (setq movement tab-width)) + (save-match-data + (if (string-match "\\w*\\(\\s-+\\)$" + (buffer-substring-no-properties (- p movement) p)) + (backward-delete-char (- (match-end 1) (match-beginning 1))) + (call-interactively 'backward-delete-char-untabify))))))) + +;;;###autoload +(defun my.dumb-indent () + "Inserts a tab character (or spaces x tab-width). Checks if the +auto-complete window is open." + (interactive) + (if indent-tabs-mode + (insert "\t") + (let* ((movement (% (current-column) tab-width)) + (spaces (if (zerop movement) tab-width (- tab-width movement)))) + (insert (s-repeat spaces " "))))) + +;;;###autoload +(defun my.inflate-space-maybe () + "Checks if point is surrounded by {} [] () delimiters and adds a +space on either side of the point if so." + (interactive) + (if (my--surrounded-p) + (progn (call-interactively 'self-insert-command) + (save-excursion (call-interactively 'self-insert-command))) + (call-interactively 'self-insert-command))) + +;;;###autoload +(defun my.deflate-space-maybe () + "Checks if point is surrounded by {} [] () delimiters, and deletes +spaces on either side of the point if so. Resorts to +`my.backward-delete-whitespace-to-column' otherwise." + (interactive) + (save-match-data + (if (my--surrounded-p) + (let ((whitespace-match (match-string 1))) + (cond ((not whitespace-match) + (call-interactively 'delete-backward-char)) + ((string-match "\n" whitespace-match) + (evil-delete (point-at-bol) (point)) + (delete-char -1) + (save-excursion (delete-char 1))) + (t + (just-one-space 0)))) + (my.backward-delete-whitespace-to-column)))) + +;;;###autoload +(defun my.newline-and-indent () + "Newline and indent; if in a comment, auto-comment and properly +indent the next line." + (interactive) + (cond ((sp-point-in-string) + (evil-ret)) + ((evil-in-comment-p) + (if (eq major-mode 'js2-mode) + (js2-line-break) + (call-interactively 'indent-new-comment-line))) + (t + (evil-ret-and-indent)))) diff --git a/init/defuns-ui.el b/init/defuns-ui.el new file mode 100644 index 000000000..18a24032b --- /dev/null +++ b/init/defuns-ui.el @@ -0,0 +1,47 @@ +(eval-when-compile (require 'cl)) + +(defvar my/dark-theme-p t) +(defvar my/presentation-mode-p nil) + +;;;###autoload +(defun load-dark-theme() + (interactive) + ;; (sml/apply-theme 'respectful) + (load-theme *dark-theme t)) + +;;;###autoload +(defun load-light-theme() + (interactive) + ;; (sml/apply-theme 'light) + (load-theme *light-theme t)) + +;;;###autoload +(defun load-font (font size) + (interactive) + (when window-system + (let ((font-str (concat font "-" (number-to-string size)))) + (if (member font (font-family-list)) + (set-frame-font font-str t t) + (error "Font %s not installed" font))))) + +;;;###autoload +(defun toggle-transparency () + (interactive) + (if (/= (frame-parameter nil 'alpha) 100) + (set-frame-parameter nil 'alpha 100) + (set-frame-parameter nil 'alpha 0))) + +;;;###autoload +(defun toggle-theme () + (interactive) + (if my/dark-theme-p + (load-light-theme) + (load-dark-theme))) + +;;;###autoload +(defun toggle-presentation-mode () + (interactive) + (if my/presentation-mode-p + (load-font *default-font *default-font-size) + (load-font *presentation-font *presentation-font-size)) + (setq my/presentation-mode-p (not my/presentation-mode-p))) diff --git a/init/defuns-util.el b/init/defuns-util.el new file mode 100644 index 000000000..25ae7c129 --- /dev/null +++ b/init/defuns-util.el @@ -0,0 +1,42 @@ + +;; String Defuns ;;;;;;;;;;;;;;;;;;;;;;; +;;;###autoload +(after "s" + (defun s-count-lines (s) + "Get number of lines in a string" + (length (s-lines s)))) + +;; File Defuns ;;;;;;;;;;;;;;;;;;;;;;;;; +;;;###autoload +(after "f" + (defmacro f--exists? (file dir) + `(f-exists? (expand-file-name ,file ,dir)))) + +;;;###autoload +(after "projectile" + (defun my--project-root (&optional force-pwd) + (if (and (not force-pwd) + (projectile-project-p)) + (projectile-project-root) + default-directory))) + +;; Misc Defuns ;;;;;;;;;;;;;;;;;;;;;;;;; +;;;###autoload +(defun what-face (pos) + "Tells you the name of the face (point) is on." + (interactive "d") + (let ((face (or (get-char-property (point) 'read-face-name) + (get-char-property (point) 'face)))) + (if face (message "Face: %s" face) (message "No face at %d" pos)))) + +;;;###autoload +(defun what-col () + (interactive) + (message "Column %d" (current-column))) + +;;;###autoload +(defun what-bindings (key) + (list + (minor-mode-key-binding key) + (local-key-binding key) + (global-key-binding key))) diff --git a/init/defuns.el b/init/defuns.el new file mode 100644 index 000000000..d18d5a2e9 --- /dev/null +++ b/init/defuns.el @@ -0,0 +1,94 @@ +(provide 'defuns) + +;; Convenience ;;;;;;;;;;;;;;;;;;;;; +(defun associate-mode (match mode) + (add-to-list 'auto-mode-alist (cons match mode))) + +(defun associate-minor-mode (match mode) + (add-to-list 'auto-minor-mode-alist (cons match mode))) + +(defmacro λ (&rest body) + `(lambda () (interactive) ,@body)) + +(defmacro add-hook! (hook &rest body) + `(add-hook ,hook (lambda() ,@body))) + +;; Backwards compatibility +(unless (fboundp 'with-eval-after-load) + (defmacro with-eval-after-load (file &rest body) + `(eval-after-load ,file + `(funcall (function ,(lambda () ,@body)))))) + +(defmacro after (feature &rest forms) + `(,(if (or (not (boundp 'byte-compile-current-file)) + (not byte-compile-current-file) + (if (symbolp feature) + (require feature nil :no-error) + (load feature :no-message :no-error))) + 'progn + (message "after: cannot find %s" feature) + 'with-no-warnings) + (with-eval-after-load ',feature ,@forms))) + + +;; Keybindings ;;;;;;;;;;;;;;;;;;;;;;;;; +(defun bind (state &rest keys) + (let ((state-list state) + (is-global (or (stringp state) + (vectorp state))) + keymap) + (if is-global + (setq keys (-insert-at 0 state keys)) + (progn + (if (keymapp (car keys)) + (setq keymap (pop keys))) + (if (or (keymapp state) + (not (listp state))) + (setq state-list (list state))))) + (while keys + (let ((-key (pop keys)) + (-def (pop keys))) + (if (stringp -key) + (setq -key (kbd -key))) + (if is-global + (global-set-key -key -def) + (dolist (-state state-list) + (cond ((evil-state-p -state) + (define-key + (if keymap + (evil-get-auxiliary-keymap keymap -state t) + (evil-state-property -state :keymap t)) -key -def)) + ((keymapp -state) + (define-key -state -key -def))))))))) + + +;; Hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun enable-comment-hard-wrap () + (set (make-local-variable 'comment-auto-fill-only-comments) t) + (turn-on-auto-fill)) + +(defun enable-tab-width-2 () + (setq tab-width 2 evil-shift-width 2)) + +(defun disable-final-newline () + (set (make-local-variable 'require-final-newline) nil)) + +(defun load-init-files () + ;; (mapc 'require io-modules) + (dolist (module my-modules) + (message "%s" (symbol-name module)) + (with-demoted-errors "#### ERROR: %s" + (require module)))) + + +;;;; Global Defuns ;;;;;;;;;;;;;;;;;;;;; +(defun my--minibuffer-quit () + "Abort recursive edit. In Delete Selection mode, if the mark is +active, just deactivate it; then it takes a second \\[keyboard-quit] +to abort the minibuffer." + (interactive) + (if (and delete-selection-mode transient-mark-mode mark-active) + (setq deactivate-mark t) + (when (get-buffer "*Completions*") + (delete-windows-on "*Completions*")) + (abort-recursive-edit))) diff --git a/init/init-auto-complete.el b/init/init-auto-complete.el index 61a5f74cc..e40e9bd55 100644 --- a/init/init-auto-complete.el +++ b/init/init-auto-complete.el @@ -3,6 +3,7 @@ (setq tags-case-fold-search nil) (use-package auto-complete + :disabled t :init (progn (require 'auto-complete-config) @@ -13,7 +14,7 @@ ac-use-quick-help t ; Don't show tooltips unless invoked (see core-keymaps.el) ac-use-fuzzy t ac-candidate-limit 25) - (setq ac-comphist-file (concat *tmp-dir "ac-comphist.dat")) + (setq ac-comphist-file (concat my-tmp-dir "ac-comphist.dat")) (setq-default ac-sources '(ac-source-yasnippet ac-source-abbrev ac-source-dictionary ac-source-words-in-same-mode-buffers)) @@ -31,11 +32,13 @@ (global-auto-complete-mode t) - (add-to-list 'ac-dictionary-files (expand-file-name "global" *ac-dicts-dir)) - (add-to-list 'ac-dictionary-directories *ac-dicts-dir) + (add-to-list 'ac-dictionary-files (expand-file-name "global" my-ac-dicts-dir)) + (add-to-list 'ac-dictionary-directories my-ac-dicts-dir) + + (push '("*Popup Help*" :position bottom :height 0.35 :noselect t) popwin:special-display-config) ;; Tell ido not to care about case - (setq completion-ignore-case t) + ;; (setq completion-ignore-case t) (bind 'insert ac-mode-map (kbd "C-x C-k") 'ac-complete-dictionary @@ -48,13 +51,13 @@ (kbd "C-SPC") 'auto-complete) (bind ac-completing-map - (kbd "") 'ac-complete - (kbd "C-n") 'ac-next - (kbd "C-p") 'ac-previous - (kbd "") 'ac-quick-help - (kbd "C-") 'ac-help - (kbd "ESC") 'ac-stop - (kbd "RET") 'ac-complete) + (kbd "") 'ac-complete + (kbd "C-n") 'ac-next + (kbd "C-p") 'ac-previous + (kbd "S-C-") 'ac-quick-help + (kbd "C-") 'ac-help + (kbd "") 'ac-stop + (kbd "") 'ac-complete) (use-package ac-etags :commands (ac-complete-etags) diff --git a/init/init-auto-insert.el b/init/init-auto-insert.el index 2d165df9f..b5abb6680 100644 --- a/init/init-auto-insert.el +++ b/init/init-auto-insert.el @@ -1,15 +1,18 @@ (provide 'init-auto-insert) -(use-package autoinsert) -;; (setq auto-insert-directory "%/.emacs.d/templates/") -(setq auto-insert-query nil) ; Don't prompt before insertion -(setq auto-insert-alist (list)) ; Don't prompt before insertion -(auto-insert-mode 1) +(use-package autoinsert + :init (auto-insert-mode 1) + :config + (progn + ;; (setq auto-insert-directory "%/.emacs.d/templates/") + (setq auto-insert-query nil) ; Don't prompt before insertion + (setq auto-insert-alist '()))) -(after yasnippet +(after "yasnippet" (defun template (file-regexp uuid mode &optional project-only) - (define-auto-insert file-regexp `(lambda () (template-insert ,uuid ',mode ,project-only)))) - (defun template-insert (uuid mode &optional project-only) + (define-auto-insert file-regexp `(lambda () (my--template-insert ,uuid ',mode ,project-only)))) + + (defun my--template-insert (uuid mode &optional project-only) "Expand snippet template in MODE by its UUID" (unless (and project-only (not (projectile-project-p))) @@ -50,7 +53,7 @@ ;; ;; (template "\\.php$" "%%" 'php-mode) ;; ;; ;; Markdown - ;; (template "/README\\.md$" "%README.md%" 'markdown-mode) + (template "/README\\.md$" "%README.md%" 'markdown-mode) ;; ;; (template "/_posts/.+\\.md$" "%jekyll-post" 'markdown-mode) ;; ;; (template "/_layouts/.+\\.html$" "%jekyll-layout%" 'web-mode) diff --git a/init/init-company.el b/init/init-company.el new file mode 100644 index 000000000..4a1e3f953 --- /dev/null +++ b/init/init-company.el @@ -0,0 +1,113 @@ +(provide 'init-company) + +(use-package company + :init + (global-company-mode 1) + :config + (progn + (setq company-idle-delay nil) + (setq company-minimum-prefix-length 1) + (setq company-show-numbers nil) + (setq company-tooltip-limit 20) + + (setq company-dabbrev-downcase nil) + (setq company-dabbrev-ignore-case nil) + (setq company-tooltip-align-annotations t) + (setq company-require-match 'never) + + (setq company-global-modes + '(not eshell-mode comint-mode org-mode erc-mode message-mode help-mode)) + + (require 'color) + (let ((bg (face-attribute 'default :background))) + (custom-set-faces + `(company-tooltip ((t (:inherit default :background ,(color-lighten-name bg 9))))) + `(company-scrollbar-bg ((t (:background ,(color-lighten-name bg 15))))) + `(company-scrollbar-fg ((t (:background ,(color-lighten-name bg 5))))) + `(company-search ((t (:background ,(color-lighten-name bg 15))))) + `(company-tooltip-selection ((t (:inherit font-lock-function-name-face)))) + `(company-tooltip-common ((t (:inherit font-lock-constant-face)))))) + + ;; Sort candidates by + (add-to-list 'company-transformers 'company-sort-by-occurrence) + ;; (add-to-list 'company-transformers 'company-sort-by-backend-importance) + + (progn ; frontends + (setq-default company-frontends '(company-pseudo-tooltip-unless-just-one-frontend + company-echo-metadata-frontend + company-preview-if-just-one-frontend))) + + (progn ; backends + (setq-default company-backends '(company-capf (company-yasnippet company-keywords))) + (make-variable-buffer-local 'company-backends) + + (defun company--backend-on (hook backends) + (add-hook hook `(lambda() (setq company-backends (append '((,backends company-yasnippet company-capf)) company-backends))))) + + (company--backend-on 'scss-mode-hook 'company-css) + (company--backend-on 'nxml-mode-hook 'company-nxml) + (company--backend-on 'js2-mode-hook 'company-tern) + (company--backend-on 'emacs-lisp-mode-hook 'company-elisp) + + (company--backend-on 'ruby-mode-hook 'company-robe) + (company--backend-on 'inf-ruby-mode-hook 'company-inf-ruby) + + (company--backend-on 'python-mode-hook 'company-anaconda) + (add-hook 'python-mode-hook 'anaconda-mode) + (add-hook 'python-mode-hook 'eldoc-mode) + + ;; Rewrite evil-complete to use company-dabbrev + (setq company-dabbrev-code-other-buffers t) + (setq company-dabbrev-code-buffers nil) + + (setq evil-complete-next-func + (lambda(arg) + (if company-candidates + (call-interactively 'company-select-next) + (call-interactively 'company-dabbrev)))) + + (setq evil-complete-previous-func + (lambda (arg) + (let ((company-selection-wrap-around t)) + (call-interactively 'company-dabbrev) + (call-interactively 'company-select-previous)))) + + (progn ; keybinds + (bind 'insert company-mode-map + "C-SPC" 'company-complete-common + "C-x C-k" 'company-keywords + "C-x C-f" 'company-files + "C-x C-]" 'company-etags + "C-x s" 'company-ispell + "C-x C-s" 'company-yasnippet + "C-x C-o" 'company-complete + "C-x C-n" 'company-dabbrev-code + "C-x C-p" (λ (let ((company-selection-wrap-around t)) + (call-interactively 'company-dabbrev-code) + (company-select-previous-or-abort)))) + + (bind company-active-map + "C-w" nil + "C-o" 'company-search-kill-others + "C-n" 'company-select-next-or-abort + "C-p" 'company-select-previous-or-abort + "C-h" 'company-show-doc-buffer + "C-S-h" 'company-show-location + "C-S-s" 'company-search-candidates + "C-s" 'company-filter-candidates + "C-SPC" 'company-complete-common + [tab] 'company-complete + "" 'company-select-previous + [escape] 'company-abort) + + (bind company-search-map + "C-n" 'company-search-repeat-forward + "C-p" 'company-search-repeat-backward + [escape] 'company-abort) + + ;; (bind company-filter-map + ;; [escape] 'company-filterd) + + (after "helm-company" + (bind company-mode-map "" 'helm-company) + (bind company-active-map "" 'helm-company)))))) diff --git a/init/init-cpp.el b/init/init-cpp.el index c6fd933e6..f51d799d5 100644 --- a/init/init-cpp.el +++ b/init/init-cpp.el @@ -19,9 +19,9 @@ "/System/Library/Frameworks" "/Library/Frameworks")) - (after flycheck (setq flycheck-clang-include-path my/clang-includes)) - (after auto-complete - (setq ac-clang-flags (mapcar (lambda (item)(concat "-I" item)) my/clang-includes))) + (after "flycheck" (setq flycheck-clang-include-path my/clang-includes)) + (after "auto-complete" + (setq ac-clang-flags (mapcar (lambda (item) (concat "-I" item)) my/clang-includes))) ) (add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) diff --git a/init/init-cscope.el b/init/init-cscope.el index 33bab2e6e..03945965f 100644 --- a/init/init-cscope.el +++ b/init/init-cscope.el @@ -1,9 +1,7 @@ (provide 'init-cscope) (use-package xcscope - :config - (progn - (cscope-setup) - (add-hook 'ruby-mode-hook (function cscope-minor-mode)) + :init (cscope-setup) + :config (push '("*cscope*" :position bottom) popwin:special-display-config)) - (push '("*cscope*" :position bottom) popwin:special-display-config))) +(add-hook 'ruby-mode-hook (function cscope-minor-mode)) diff --git a/init/init-csharp.el b/init/init-csharp.el index 1f15059d7..601859590 100644 --- a/init/init-csharp.el +++ b/init/init-csharp.el @@ -1,12 +1,18 @@ (provide 'init-csharp) -;; (use-package omnisharp :defer t -;; :config -;; (progn -;; (setq omnisharp-server-executable-path "~/Dropbox/projects/lib/Omnisharp/server/OmniSharp/bin/Debug/OmniSharp.exe") -;; (use-package company -;; :config -;; (add-to-list 'company-backends 'company-omnisharp)))) +(use-package omnisharp :defer t + :config + (progn + (setq omnisharp-server-executable-path "~/Dropbox/projects/lib/Omnisharp/server/OmniSharp/bin/Debug/OmniSharp.exe") + + (bind 'normal omnisharp-mdoe-map + "gd" 'omnisharp-go-to-definition + "") + + (after "company" + (company--backend-on 'csharpmode 'company-omnisharp) + (add-hook 'csharp-mode-hook 'eldoc-mode)) + )) (use-package csharp-mode :mode "\\.cs$") ;; (use-package csharp-mode diff --git a/init/init-dev.el b/init/init-dev.el index 4f1ee6ed5..64f86d70b 100644 --- a/init/init-dev.el +++ b/init/init-dev.el @@ -1,5 +1,7 @@ (provide 'init-dev) +(add-hook 'find-file-hook 'hl-todo-mode) + (use-package dash-at-point :commands (dash-at-point dash-at-point-with-docset) :if is-mac) @@ -9,17 +11,96 @@ :init (add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)) ;;; Config modes -(use-package yaml-mode :defer t +(use-package yaml-mode + :defer t :config (add-hook 'yaml-mode-hook 'enable-tab-width-2)) (use-package json-mode :mode (("\\.json\\'" . json-mode) ("\\.jshintrc\\'" . json-mode))) -(use-package hl-todo - :init (add-hook 'find-file-hook 'hl-todo-mode)) +(use-package emr + :commands (emr-initialize emr-show-refactor-menu) + :init (add-hook 'prog-mode-hook 'emr-initialize) + :config + (progn + (bind 'normal "gR" 'emr-show-refactor-menu) -(use-package regex-tool - :commands regex-tool - :config (setq regex-tool-backend 'perl) - :init (add-hook 'regex-tool-mode-hook 'whitespace-newline-mode)) + (after "evil" (evil-ex-define-cmd "ref[actor]" 'emr-show-refactor-menu)))) + + +;; Variables +(defvar-local my-run-code-interpreter nil) +(defvar-local my-run-code-func 'my--run-code-shell) +(defvar-local my-run-code-region-func 'my--run-code-region-shell) +(defvar-local my-switch-to-repl-func nil) +(defvar-local my-send-region-to-repl-func nil) +(defvar-local my-build-func nil) + +;; usage +(defvar-local my-test-single-func nil) +(defvar-local my-test-fixture-func nil) +(defvar-local my-test-all-func nil) + +(defun my--run-code-shell (file-path) + (if (stringp my-run-code-interpreter) + (message (concat my-run-code-interpreter " " file-path)) + (error "No interpreter set for %s. See `my-run-code-interpreter'" + (symbol-name major-mode)))) + +(defun my--run-code-region-shell (beg end) + (if (stringp my-run-code-interpreter) + (shell-command-on-region beg end my-run-code-interpreter) + (error "No interpreter set for %s. See `my-run-code-interpreter'" + (symbol-name major-mode)))) + +(defun my-switch-to-repl () + (interactive) + (if (functionp my-switch-to-repl-func) + (funcall my-switch-to-repl-func) + (error "No REPL was set for %s. See `my-switch-to-repl-func'" + (symbol-name major-mode)))) + +(defun my-send-region-to-repl (beg end) + (interactive "r") + (if (functionp my-send-region-to-repl-func) + (funcall my-send-region-to-repl-func beg end) + (error "No region runner set for %s. See `my-send-region-to-repl-func'" + (symbol-name major-mode)))) + +(defun my-run-code-buffer () + (interactive) + (let ((mode-name (symbol-name major-mode))) + (if (or (buffer-modified-p) + (not (f-exists? buffer-file-name))) + (my:run-code-region (point-min) (point-max)) + (if (functionp my-run-code-func) + (funcall my-run-code-func buffer-file-name) + (error "No runner set for %s. See `my-run-code-func'" mode-name))))) + +(defun my-run-code-region (beg end) + (interactive "r") + (if (functionp my-run-code-region-func) + (funcall my-run-code-region-func beg end) + (error "No region runner set for %s. See `my-run-code-region-func'" + (symbol-name major-mode)))) + +(defun my-build (&optional arguments) + (interactive) + (if (functionp my-build-func) + (funcall my-build-func arguments) + (error "No build function set for %s. See `my-build-func'" + (symbol-name major-mode)))) + + + +(after "evil" + ;; (evil-ex-define-cmd "test[s]" 'my-test-single-func) + ;; (evil-ex-define-cmd "testf[ixture]" 'my-test-fixture-func) + ;; (evil-ex-define-cmd "testa[ll]" 'my-test-all-func) + + (require 'evil-snipe) + (global-evil-snipe-mode 1) + + (evil-snipe-surround-compatibility) + (evil-define-key 'visual evil-surround-mode-map (kbd "S") 'evil-surround-region)) diff --git a/init/init-elisp.el b/init/init-elisp.el new file mode 100644 index 000000000..f5f7ed917 --- /dev/null +++ b/init/init-elisp.el @@ -0,0 +1,25 @@ +(provide 'init-elisp) + +(defun remove-elc-on-save () + "If you're saving an elisp file, likely the .elc is no longer valid." + (make-local-variable 'after-save-hook) + (add-hook 'after-save-hook + (lambda () + (if (file-exists-p (concat buffer-file-name "c")) + (delete-file (concat buffer-file-name "c")))))) + +(add-hook 'after-save-hook 'remove-elc-on-save) +(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) +(add-hook! 'emacs-lisp-mode-hook + (setq my-run-code-func 'eval-buffer + my-run-code-region-func 'eval-region)) + +;; Real go-to-definition for elisp +(bind 'motion emacs-lisp-mode-map "gd" + (λ (let ((func (function-called-at-point))) + (if func (find-function func))))) + +;; Go-to-definition in other buffer +(bind 'motion emacs-lisp-mode-map "gD" + (λ (let ((func (function-called-at-point))) + (if func (find-function-other-window func))))) diff --git a/init/init-eshell.el b/init/init-eshell.el new file mode 100644 index 000000000..42969aa86 --- /dev/null +++ b/init/init-eshell.el @@ -0,0 +1,48 @@ +(provide 'init-eshell) + +;; (evil-set-initial-state 'eshell-mode 'emacs) + +;; (push '("*eshell*" :position left :width 80 :stick t) popwin:special-display-config) + +;; ;; eshell +;; (setq eshell-directory-name (concat my-tmp-dir "eshell")) +;; (setq eshell-scroll-to-bottom-on-input 'all) +;; (setq eshell-buffer-shorthand t) + + +;; ;; em-alias +;; (setq eshell-aliases-file (concat my-tmp-dir ".eshell-aliases")) + + +;; ;; em-glob +;; (setq eshell-glob-case-insensitive t) +;; (setq eshell-error-if-no-glob t) + + +;; ;; em-hist +;; (setq eshell-history-size 1024) + + +;; ;; plan 9 smart shell +;; ;; (after "esh-module" +;; ;; (add-to-list 'eshell-modules-list 'eshell-smart) +;; ;; (setq eshell-where-to-jump 'begin) +;; ;; (setq eshell-review-quick-commands nil) +;; ;; (setq eshell-smart-space-goes-to-end t)) + +;; (defun my-current-git-branch () +;; (let ((branch (car (loop for match in (split-string (shell-command-to-string "git branch") "\n") +;; when (string-match "^\*" match) +;; collect match)))) +;; (if (not (eq branch nil)) +;; (concat " [" (substring branch 2) "]") +;; ""))) + +;; (defun my-eshell-prompt () +;; (concat (propertize (abbreviate-file-name (eshell/pwd)) 'face 'eshell-prompt) +;; (propertize (my-current-git-branch) 'face 'font-lock-function-name-face) +;; (propertize " $ " 'face 'font-lock-constant-face))) + + +;; ;; em-prompt +;; (setq eshell-prompt-function 'my-eshell-prompt) diff --git a/init/init-fly.el b/init/init-fly.el index 3e15ece53..a11141793 100644 --- a/init/init-fly.el +++ b/init/init-fly.el @@ -1,14 +1,36 @@ (provide 'init-fly) (use-package flycheck - :init - (progn + :defer t + :init (add-hook 'prog-mode-hook 'flycheck-mode) + :config + (progn ; flycheck settings (setq-default flycheck-indication-mode 'right-fringe ;; Removed checks on idle/change for snappiness - flycheck-check-syntax-automatically - '(save mode-enabled) - flycheck-disabled-checkers - '(emacs-lisp-checkdoc make)) - (add-hook 'after-init-hook #'global-flycheck-mode))) + flycheck-check-syntax-automatically '(save mode-enabled) + flycheck-disabled-checkers '(emacs-lisp-checkdoc make)) + + (my--cleanup-buffers-add "^\\*Flycheck.*\\*$") + + (bind 'normal flycheck-error-list-mode-map + [escape] 'kill-this-buffer + "q" 'kill-this-buffer) + + (evil-initial-state 'flycheck-error-list-mode 'emacs) + + (evil-ex-define-cmd "er[rors]" 'flycheck-list-errors) + + (defun my/evil-flycheck-buffer () + (if (and (featurep 'flycheck) flycheck-mode) + (flycheck-buffer))) + + ;; Check buffer when normal mode is entered + (add-hook 'evil-normal-state-entry-hook 'my/evil-flycheck-buffer) + ;; And on ESC in normal mode. + (defadvice evil-force-normal-state (after evil-esc-flycheck-buffer activate) + (my/evil-flycheck-buffer)) + + (push '("^\\*Flycheck.*\\*$" :regexp t :position bottom :height 0.25) + popwin:special-display-config))) (use-package flyspell :commands flyspell-mode) diff --git a/init/init-git.el b/init/init-git.el index 8c9c04d58..d4a68468d 100644 --- a/init/init-git.el +++ b/init/init-git.el @@ -1,6 +1,6 @@ (provide 'init-git) -(use-package git-commit-mode +(use-package git-commit-mode ; :mode (("/COMMIT_EDITMSG\\'" . git-commit-mode) ("/NOTES_EDITMSG\\'" . git-commit-mode) ("/MERGE_MSG\\'" . git-commit-mode) @@ -19,11 +19,15 @@ :mode (("/\\.gitignore\\'" . gitignore-mode) ("/\\.git/info/exclude\\'" . gitignore-mode) ("/git/ignore\\'" . gitignore-mode))) - +;; (use-package git-gutter-fringe+ :init (global-git-gutter+-mode +1) :config (progn + (evil-ex-define-cmd "gstage" 'git-gutter+-stage-hunks) + (evil-ex-define-cmd "grevert" 'git-gutter+-revert-hunks) + (evil-ex-define-cmd "gdiff" 'git-gutter+-show-hunk) + (fringe-helper-define 'git-gutter-fr+-added nil "X......." "X......." @@ -38,6 +42,17 @@ "X......." "X......." "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." "X.......") (fringe-helper-define 'git-gutter-fr+-deleted nil @@ -54,6 +69,17 @@ "........" "........" "........" + "........" + "........" + "........" + "........" + "........" + "........" + "........" + "........" + "........" + "........" + "........" "........") (fringe-helper-define 'git-gutter-fr+-modified nil @@ -70,4 +96,18 @@ "X......." "X......." "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." + "X......." "X......."))) + +(evil-set-initial-state 'git-commit-mode 'insert) +(evil-set-initial-state 'git-rebase-mode 'insert) diff --git a/init/init-go.el b/init/init-go.el index 6e5b6c389..2f0ed3585 100644 --- a/init/init-go.el +++ b/init/init-go.el @@ -1,7 +1,7 @@ (provide 'init-go) -(use-package go-mode - :mode "\\.go\\'" - :interpreter "go" - :init - (require 'go-autocomplete)) +;; (use-package go-mode +;; :mode "\\.go\\'" +;; :interpreter "go" +;; :init +;; (require 'go-autocomplete)) diff --git a/init/init-helm.el b/init/init-helm.el new file mode 100644 index 000000000..d4f80d0cb --- /dev/null +++ b/init/init-helm.el @@ -0,0 +1,181 @@ +(provide 'init-helm) + +(use-package helm + :config + (progn ; helm settings + (defvar helm-global-prompt ">>> ") + + (setq helm-quick-update t + helm-idle-delay 0.01 + helm-input-idle-delay 0.01 + helm-reuse-last-window-split-state t + helm-buffers-fuzzy-matching nil + helm-bookmark-show-location t) + + (my--cleanup-buffers-add "^\\*[Hh]elm.*\\*$") + + (bind helm-map + (kbd "C-w") 'evil-delete-backward-word + (kbd "C-u") 'helm-delete-minibuffer-contents + (kbd "C-r") 'evil-ex-paste-from-register ; Evil registers in helm! Glorious! + [escape] 'helm-keyboard-quit) + + (evil-ex-define-cmd "a" 'helm-projectile-find-other-file) + (evil-ex-define-cmd "proj[ect]" 'helm-projectile-switch-project) + (evil-ex-define-cmd "ag" 'my:helm-ag-search) + (evil-ex-define-cmd "ag[cw]d" 'my:helm-ag-search-cwd) + (evil-ex-define-cmd "sw[oop]" 'my:helm-swoop) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (use-package helm-ag + :commands (my:helm-ag-search my:helm-ag-search-cwd helm-ag helm-do-ag my:helm-ag-search) + :config + (progn + ;; Ex-mode interface for `helm-ag'. If `bang', then `search' is interpreted as + ;; regexp. + (evil-define-operator my:helm-ag-search (beg end &optional bang search pwd-p) + :motion nil + :move-point nil + :type inclusive + :repeat nil + (message "%s" bang) + (let* ((helm-ag-default-directory (my--project-root pwd-p)) + (header-name (format "Search in %s" helm-ag-default-directory)) + (input "") + (helm-ag--last-input "")) + (if search + (progn + (helm-attrset 'search-this-file nil helm-ag-source) + (setq helm-ag--last-query + (concat "ag " (unless bang "-Q") " --nogroup --nocolor -- '" + (s-replace "'" "" search) "'"))) + (helm-ag-save-current-context) + (if (and beg end) + (setq input (buffer-substring-no-properties beg end)))) + (helm-attrset 'name header-name helm-ag-source) + (helm :sources (if search (helm-ag--select-source) '(helm-source-do-ag)) + :buffer "*helm-ag*" + :input input + :prompt helm-global-prompt))) + + ;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted + ;; as regexp + (evil-define-operator my:helm-ag-search-cwd (beg end &optional bang search) + :motion nil + :move-point nil + :type inclusive + :repeat nil + (interactive "") + (my:helm-ag-search beg end search bang t)))) + + (use-package helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss + :commands (helm-css-scss + helm-css-scss-multi + helm-css-scss-insert-close-comment)) + + (use-package helm-swoop ; https://github.com/ShingoFukuyama/helm-swoop + :commands (my:helm-swoop helm-swoop helm-multi-swoop) + :config + (progn + (setq helm-swoop-use-line-number-face t + helm-swoop-split-with-multiple-windows t + helm-swoop-speed-or-color t + helm-swoop-split-window-function 'popwin:popup-buffer) + + (after "helm-css-scss" + ;; Ex-mode interface for `helm-swoop', `helm-multi-swoop-all' (if `bang'), or + ;; `helm-css-scss' and `helm-css-scss-multi' (if `bang') if major-mode is + ;; `scss-mode' + (evil-define-command my:helm-swoop (&optional search bang) + :repeat nil + (interactive "") + (if (eq major-mode 'scss-mode) + (if bang (helm-css-scss-multi search) (helm-css-scss search)) + (if bang (helm-multi-swoop-all search) (helm-swoop :$query search))))))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (after "projectile" + (use-package helm-projectile + :config + (setq projectile-switch-project-action 'helm-projectile))) + + (after "winner" + ;; Tell winner-mode to ignore helm buffers + (dolist (bufname '("*helm recentf*" + "*helm projectile*" + "*helm imenu*" + "*helm company*" + "*helm buffers*" + ;; "*helm tags*" + "*helm-ag*" + "*Helm Swoop*")) + (push bufname winner-boring-buffers))) + + (after "company" + (use-package helm-company + :config + (defun helm-company () + (interactive) + (unless company-candidates + (company-complete)) + (when company-point + (helm :sources 'helm-source-company + :buffer "*helm company*" + :prompt helm-global-prompt + :candidate-number-limit helm-company-candidate-number-limit))))) + + (progn ; helm hacks + ;; Don't show the project name in the prompts; I already know. + (defun projectile-prepend-project-name (string) + (format helm-global-prompt string)) + + ;; No persistent header + (defadvice helm-display-mode-line (after undisplay-header activate) + (setq header-line-format nil)) + + ;; Reconfigured `helm-recentf' to use `helm', instead of `helm-other-buffer' + (defun helm-recentf () + (interactive) + (let ((helm-ff-transformer-show-only-basename nil)) + (helm :sources '(helm-source-recentf) + :buffer "*helm recentf*" + :prompt helm-global-prompt))) + + ;; Hide the mode-line in helm (<3 minimalism) + (defun helm-display-mode-line (source &optional force) + (set (make-local-variable 'helm-mode-line-string) + (helm-interpret-value (or (and (listp source) ; Check if source is empty. + (assoc-default 'mode-line source)) + (default-value 'helm-mode-line-string)) + source)) + (let ((follow (and (eq (cdr (assq 'follow source)) 1) "(HF) "))) + (if helm-mode-line-string + (setq mode-line-format nil) + (setq mode-line-format (default-value 'mode-line-format))) + (let* ((hlstr (helm-interpret-value + (and (listp source) + (assoc-default 'header-line source)) + source)) + (hlend (make-string (max 0 (- (window-width) (length hlstr))) ? ))) + (setq header-line-format + (propertize (concat " " hlstr hlend) 'face 'helm-header)))) + (when force (force-mode-line-update)))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (progn ; popwin + (push '("^\\*helm.*\\*$" :position bottom :regexp t :height 18) + popwin:special-display-config)) + + (progn ; evil + (evil-set-initial-state 'helm-mode 'emacs) + + ;; Ex-mode interface for `helm-recentf' and `helm-projectile-recentf'. If + ;; `bang', then `search' is interpreted as regexp + (evil-ex-define-cmd "rec[ent]" 'my:helm-recentf) + (evil-define-command my:helm-recentf (&optional bang) + :repeat nil + (interactive "") + (if bang (helm-recentf) (helm-projectile-recentf)))))) diff --git a/init/init-ido.el b/init/init-ido.el index 7c0e1cec7..5413e12e5 100644 --- a/init/init-ido.el +++ b/init/init-ido.el @@ -13,9 +13,9 @@ ;; (set-keymap-parent ido-file-completion-map ido-file-dir-completion-map) ;; (set-keymap-parent ido-buffer-completion-map ido-common-completion-map) -(use-package ido-ubiquitous) -(use-package ido-vertical-mode) -(use-package flx-ido) +(require 'ido-ubiquitous) +(require 'ido-vertical-mode) +(require 'flx-ido) (ido-mode 1) (ido-vertical-mode 1) @@ -31,7 +31,7 @@ ido-create-new-buffer 'always ido-enable-tramp-completion t ido-enable-last-directory-history t - ido-save-directory-list-file (concat *tmp-dir "ido.last")) + ido-save-directory-list-file (concat my-tmp-dir "ido.last")) (add-to-list 'ido-ignore-files "\\`.DS_Store$") (setq ido-ignore-buffers diff --git a/init/init-java.el b/init/init-java.el index 083ffb05f..02f73f641 100644 --- a/init/init-java.el +++ b/init/init-java.el @@ -15,16 +15,24 @@ (use-package eclim-project) (use-package eclimd) - (require 'ac-emacs-eclim-source) - (add-hook! 'java-mode-hook - (setq ac-sources '(ac-source-emacs-eclim ac-source-yasnippet ac-source-abbrev ac-source-dictionary ac-source-words-in-same-mode-buffers))) - (setq help-at-pt-display-when-idle t) (setq help-at-pt-timer-delay 0.1) (help-at-pt-set-timer) + (after "company" + (use-package company-emacs-eclim + :init (company-emacs-eclim-setup))) + + (after "auto-complete" + (add-hook! 'java-mode-hook + (setq ac-sources '(ac-source-emacs-eclim + ac-source-yasnippet + ac-source-abbrev + ac-source-dictionary + ac-source-words-in-same-mode-buffers)))) + (bind 'motion java-mode-map "gd" 'eclim-java-find-declaration))) -(use-package groovy-mode :mode "\\.gradle$" - :config - (add-to-list 'ac-modes 'groovy-mode)) +(use-package groovy-mode + :mode "\\.gradle$" + :config (after "auto-complete" (add-to-list 'ac-modes 'groovy-mode))) diff --git a/init/init-love.el b/init/init-love.el deleted file mode 100644 index 0e70905a7..000000000 --- a/init/init-love.el +++ /dev/null @@ -1,22 +0,0 @@ -(provide 'init-love) - -(defun my/build-love () - (shell-command (format "open -a love.app %s" (my/project-root)))) - -(use-package lua-mode - :mode "\\.lua$" - :interpreter "lua" - :init - (progn - (define-minor-mode love-mode - "Buffer local minor mode for Love2D" - :init-value nil - :lighter " <3" - :keymap (make-sparse-keymap)) - - (add-hook! 'lua-mode-hook - (setq my-run-code-interpreter "lua") - (when (and (s-matches-p "[\\.-]love/.+\\.lua$" (buffer-file-name)) - (f--traverse-upwards (f--exists? "main.lua" it))) - (love-mode t) - (setq my-build-func 'my/build-love))))) diff --git a/init/init-lua.el b/init/init-lua.el new file mode 100644 index 000000000..1e73128e5 --- /dev/null +++ b/init/init-lua.el @@ -0,0 +1,19 @@ +(provide 'init-lua) + +(use-package lua-mode + :mode "\\.lua$" + :interpreter "lua" + :init + (progn + (define-minor-mode love-mode + "Buffer local minor mode for Love2D" + :init-value nil + :lighter " <3" + :keymap (make-sparse-keymap)) + (associate-minor-mode "[\\.-]love/.+\\.lua$" 'love-mode) + + (defun my--build-love () + (shell-command (format "open -a love.app %s" (my--project-root)))) + + (add-hook! 'lua-mode-hook (setq my-run-code-interpreter "lua")) + (add-hook! 'love-mode-hook (setq my-build-func 'my/build-love)))) diff --git a/init/init-org.el b/init/init-org.el index 5eda5ee61..239bf2b5f 100644 --- a/init/init-org.el +++ b/init/init-org.el @@ -31,7 +31,7 @@ (point-max))) ;; -(use-package org) +(require 'org) (define-minor-mode evil-org-mode "Buffer local minor mode for evil-org" diff --git a/init/init-project.el b/init/init-project.el index 8f86509d9..cca7ff829 100644 --- a/init/init-project.el +++ b/init/init-project.el @@ -1,21 +1,30 @@ +;; Project nav+search tools (projectile, helm, ag) (provide 'init-project) (use-package neotree - :commands (neotree-show neotree-hide neotree-toggle)) - -(use-package ag - :commands (ag ag-search ag-regexp) + :commands (neotree-show neotree-hide neotree-toggle) :config - (progn (setq ;ag-reuse-window nil - ag-reuse-buffers nil - ag-highlight-search t) + (progn (setq neo-create-file-auto-open t + neo-smart-open t + neo-persist-show nil) + (add-hook! 'neotree-mode-hook + (setq mode-line-format nil) + (bind evil-motion-state-local-map + (kbd "TAB") 'neotree-enter + (kbd "RET") 'neotree-enter)))) - (push '(ag-mode :position bottom :height 0.5 :stick t) popwin:special-display-config) +(use-package perspective + :init (persp-mode 1) + :config + (progn + (defun my-kill-persp () + (interactive) + (persp-kill (persp-name persp-curr))) - ;; Close Ag on ESC - (bind ag-mode-map [escape] "q"))) + (evil-ex-define-cmd "k[ill]persp" 'my-kill-persp))) (use-package dired + :disabled t :init (progn (setq dired-recursive-deletes 'always dired-recursive-copies 'always @@ -29,99 +38,4 @@ (push '(dired-mode :position bottom :height 0.5 :stick t) popwin:special-display-config) (add-hook! 'dired-mode-hook - (use-package 'dired+ :config (toggle-diredp-find-file-reuse-dir 1))))) - -(use-package projectile - :init - (progn (setq-default projectile-cache-file (concat *tmp-dir "projectile.cache")) - (setq-default projectile-known-projects-file (concat *tmp-dir "projectile.projects")) - (setq-default projectile-enable-caching t) - - (add-to-list 'projectile-globally-ignored-files "ido.last") - (add-to-list 'projectile-globally-ignored-directories "assets") - (add-to-list 'projectile-other-file-alist '("scss" "css")) - (add-to-list 'projectile-other-file-alist '("css" "scss")) - - (projectile-global-mode +1) - - (defvar persp-modestring-dividers '("" " |" ",")) - (use-package perspective) - (use-package persp-projectile) - (persp-mode 1))) - -(use-package helm - :pre-load (defvar helm-mode-line-string "") - :init - (progn - (use-package helm-ag :commands (helm-do-ag)) - (use-package helm-projectile) - (add-hook! 'scss-mode-hook (use-package helm-css-scss)) - - (push '("^\\*helm.+\\*$" :position bottom :regexp t :height 18) popwin:special-display-config) - - (setq helm-quick-update t - helm-idle-delay 0.01 - helm-input-idle-delay 0.01) - - (bind helm-map (kbd "C-w") 'evil-delete-backward-word) - - ;; All this for a smaller prompt (it was redundant with helm headers) - (defmacro helm-projectile-command (command source prompt) - `(defun ,(intern (concat "helm-projectile-" command)) (&optional arg) - (interactive "P") - (if (projectile-project-p) - (projectile-maybe-invalidate-cache arg)) - (let ((helm-ff-transformer-show-only-basename nil) - ;; for consistency, we should just let Projectile take care of ignored files - (helm-boring-file-regexp-list nil)) - (helm :sources ,source - :buffer "*helm projectile*" - :prompt ">>> ")))) - - (helm-projectile-command "switch-project" 'helm-source-projectile-projects ">>> ") - (helm-projectile-command "find-file" helm-source-projectile-files-and-dired-list ">>> ") - (helm-projectile-command "find-file-in-known-projects" 'helm-source-projectile-files-in-all-projects-list ">>> ") - (helm-projectile-command "find-file-dwim" 'helm-source-projectile-files-dwim-list ">>> ") - (helm-projectile-command "find-dir" helm-source-projectile-directories-and-dired-list ">>> ") - (helm-projectile-command "recentf" 'helm-source-projectile-recentf-list ">>> ") - (helm-projectile-command "switch-to-buffer" 'helm-source-projectile-buffers-list ">>> ") - - ;; Hide the mode-line in helm (<3 minimalism) - (defun helm-display-mode-line (source &optional force) - "Setup mode-line and header-line for `helm-buffer'." - (set (make-local-variable 'helm-mode-line-string) - (helm-interpret-value (or (and (listp source) ; Check if source is empty. - (assoc-default 'mode-line source)) - (default-value 'helm-mode-line-string)) - source)) - (let ((follow (and (eq (cdr (assq 'follow source)) 1) "(HF) "))) - ;; Setup mode-line. - (if helm-mode-line-string - (setq mode-line-format nil) - (setq mode-line-format (default-value 'mode-line-format))) - ;; Setup header-line. - (let* ((hlstr (helm-interpret-value - (and (listp source) - (assoc-default 'header-line source)) - source)) - (hlend (make-string (max 0 (- (window-width) (length hlstr))) ? ))) - (setq header-line-format - (propertize (concat " " hlstr hlend) 'face 'helm-header)))) - (when force (force-mode-line-update))) - - ;; No persistent header - (defadvice helm-display-mode-line (after undisplay-header activate) - (setq header-line-format nil)))) - -;; For setting project-specific settings -(defmacro project-settings (name &rest body) - (declare (indent 1)) - `(progn - (add-hook 'find-file-hook - (lambda () - (when (string-match-p ,name (buffer-file-name)) - ,@body))) - (add-hook 'dired-after-readin-hook - (lambda () - (when (string-match-p ,name (dired-current-directory)) - ,@body))))) + (use-package 'dired+ :config (toggle-diredp-find-file-reuse-dir 1))))) diff --git a/init/init-projectile.el b/init/init-projectile.el new file mode 100644 index 000000000..7630e3473 --- /dev/null +++ b/init/init-projectile.el @@ -0,0 +1,29 @@ +(provide 'init-projectile) + +(use-package projectile + :pre-load + (setq-default projectile-cache-file (concat my-tmp-dir "projectile.cache") + projectile-known-projects-file (concat my-tmp-dir "projectile.projects") + projectile-enable-caching t + projectile-indexing-method 'alien) + :init + (projectile-global-mode +1) + :config + (progn + (add-to-list 'projectile-globally-ignored-files "ido.last") + (add-to-list 'projectile-globally-ignored-directories "assets") + (add-to-list 'projectile-other-file-alist '("scss" "css")) + (add-to-list 'projectile-other-file-alist '("css" "scss")) + + ;; For setting project-specific settings + (defmacro my-project-settings (project-name &rest body) + (declare (indent 1)) + `(progn + (add-hook 'find-file-hook + (lambda () + (when (string-match-p ,project-name (projectile-project-name)) + ,@body))))) + + (after "perspective" + (defvar persp-modestring-dividers '("" " |" ",")) + (use-package persp-projectile)))) diff --git a/init/init-python.el b/init/init-python.el index dd9727925..15962c14e 100644 --- a/init/init-python.el +++ b/init/init-python.el @@ -6,7 +6,7 @@ :init (setq python-indent-offset 4) :config (progn - (setq python-environment-directory *tmp-dir) + (setq python-environment-directory my-tmp-dir) (setq python-shell-interpreter "ipython") (add-hook! 'python-mode-hook @@ -18,20 +18,18 @@ (bind python-mode-map (kbd "DEL") nil) (bind 'motion python-mode-map "gd" 'jedi:goto-definition) - (use-package jedi - :config - (progn - (unless (file-directory-p python-environment-directory) - (jedi:install-server)) - (add-hook 'python-mode-hook 'jedi:ac-setup))) + (require 'jedi) + (unless (file-directory-p python-environment-directory) + (jedi:install-server)) + (add-hook 'python-mode-hook 'jedi:ac-setup) (use-package nose - :commands (nose-mode) + :commands nose-mode :init (progn ;; Reset nose keymap, we'll set new ones in my-keymaps.el (defvar nose-mode-map (make-sparse-keymap)) - (associate-minor-mode "/test_.+\\.py\\'" nose-mode)) + (associate-minor-mode "/test_.+\\.py\\'" 'nose-mode)) :config (bind 'normal nose-mode-map ",tr" 'nosetests-again diff --git a/init/init-regex.el b/init/init-regex.el new file mode 100644 index 000000000..2d3e00053 --- /dev/null +++ b/init/init-regex.el @@ -0,0 +1,29 @@ +(provide 'init-regex) + +(use-package re-builder + :defer t + :config + (progn + (bind 'normal reb-mode-map + [escape] 'reb-quit + (kbd "C-g") 'reb-quit + [backtab] 'reb-change-syntax) + + (defun my--reb-cleanup () + (replace-regexp "^[ \n]*" "" nil (point-min) (point-max)) + (text-scale-set 1.5) + (goto-char 2)) + (add-hook 'reb-mode-hook 'my--reb-cleanup) + + (after "evil" + (evil-set-initial-state 'reb-mode 'insert) + (evil-ex-define-cmd "re[gex]" 're-builder)))) + +(use-package pcre2el + :config + (progn + (bind 'normal rxt-help-mode-map [escape] 'kill-buffer-and-window) + + (after "re-builder" (setq reb-re-syntax 'pcre)) + (after "popwin" + (push '("* Regexp Explain *" :position top :height 0.35) popwin:special-display-config)))) diff --git a/init/init-ruby.el b/init/init-ruby.el index f60412728..a9f7670a4 100644 --- a/init/init-ruby.el +++ b/init/init-ruby.el @@ -1,6 +1,5 @@ (provide 'init-ruby) -;; (use-package ruby-mode :mode (("\\.rb$" . ruby-mode) ("\\.ru$" . ruby-mode) @@ -14,66 +13,68 @@ :interpreter "ruby" :config (progn + ;;; Formatting + (setq ruby-indent-level 2) + (setq ruby-deep-indent-paren t) + + (add-hook 'ruby-mode-hook 'enable-tab-width-2) + (define-minor-mode rake-mode "Buffer local minor mode for rake files" :lighter " Rake") (use-package inf-ruby + :commands (inf-ruby inf-ruby-console-auto) :config (progn (evil-set-initial-state 'inf-ruby-mode 'insert) - ;; (use-package ac-inf-ruby) - ;; (add-hook 'inf-ruby-mode-hook 'ac-inf-ruby-enable) + (push '(inf-ruby-mode :position bottom :stick t) popwin:special-display-config) - (push '(inf-ruby-mode :position bottom :stick t) popwin:special-display-config))) + (use-package company-inf-ruby) + )) (use-package rspec-mode :defer t :pre-load - (defvar evilmi-ruby-match-tags - '((("unless" "if") ("elsif" "else") "end") - ("begin" ("rescue" "ensure") "end") - ("case" ("when" "else") "end") - (("class" "def" "while" "do" "module" "for" "until") () "end") - ;; Rake - (("task" "namespace") () "end") - )) + (progn (defvar rspec-mode-verifiable-map (make-sparse-keymap)) + (defvar evilmi-ruby-match-tags + '((("unless" "if") ("elsif" "else") "end") + ("begin" ("rescue" "ensure") "end") + ("case" ("when" "else") "end") + (("class" "def" "while" "do" "module" "for" "until") () "end") + ;; Rake + (("task" "namespace") () "end")))) :init - (progn (associate-minor-mode "\\(/spec_helper\\|_spec\\)\\.rb$" rspec-mode) - (associate-minor-mode "/\\.rspec$" rspec-mode) - (associate-minor-mode "/\\.rake$" rake-mode) - (associate-mode "/\\.rspec$" text-mode)) + (progn (associate-minor-mode "\\(/spec_helper\\|_spec\\)\\.rb$" 'rspec-mode) + (associate-minor-mode "/\\.rspec$" 'rspec-mode) + (associate-minor-mode "/\\.rake$" 'rake-mode) + (associate-mode "/\\.rspec$" 'text-mode)) :config - (progn (bind 'normal rspec-mode-verifiable-keymap - ",tr" 'rspec-rerun - ",ta" 'rspec-verify-all - ",ts" 'rspec-verify-single - ",tv" 'rspec-verify) - (bind 'normal rspec-dired-mode-keymap - ",tv" 'rspec-dired-verify - ",ts" 'rspec-dired-verify-single - ",ta" 'rspec-verify-all - ",tr" 'rspec-rerun))) + (bind 'normal + ",tr" 'rspec-rerun + ",ta" 'rspec-verify-all + ",ts" 'rspec-verify-single + ",tv" 'rspec-verify)) (use-package robe :config (progn - (add-hook! 'after-save-hook - (when (and (eq major-mode 'ruby-mode) - (bound-and-true-p robe-running)) - (ruby-load-file (buffer-file-name)))) + (after "company" (require 'company-robe)) (add-hook! 'ruby-mode-hook - (robe-mode 1) - (ac-robe-setup) - (unless robe-running (robe-start 1)) - (ruby-load-file (buffer-file-name))))) + (robe-mode 1) + (after "auto-complete" (ac-robe-setup)) + (after "company" (add-to-list 'company-backends 'company-robe)) + (unless robe-running (robe-start 1)) + (my/ruby-load-file buffer-file-name) - (add-hook! 'ruby-mode-hook - (setq my-switch-to-repl-func 'ruby-switch-to-inf - my-send-region-to-repl-func 'ruby-send-region - my-run-code-interpreter "ruby")) + (setq my-switch-to-repl-func 'ruby-switch-to-inf + my-send-region-to-repl-func 'ruby-send-region + my-run-code-interpreter "ruby")) - ;;; Formatting - (setq ruby-indent-level 2) - (setq ruby-deep-indent-paren t) - (add-hook 'ruby-mode-hook 'enable-tab-width-2))) + (defun my/ruby-load-file (&optional file) + (let ((file (or file buffer-file-name))) + (when (and (eq major-mode 'ruby-mode) + (bound-and-true-p robe-running) + (file-exists-p buffer-file-name)) + (ruby-load-file file)))) + (add-hook 'after-save-hook 'my/ruby-load-file))))) diff --git a/init/init-sh.el b/init/init-sh.el index 93dd78b1b..65a8272dd 100644 --- a/init/init-sh.el +++ b/init/init-sh.el @@ -1,4 +1,22 @@ (provide 'init-sh) +(after "popwin" + (push '("*ansi-term*" :position bottom :height 0.45 :stick t) popwin:special-display-config) + (push '("*terminal*" :position bottom :height 0.45 :stick t) popwin:special-display-config) + (push '("*Async Shell Command*" :position bottom) popwin:special-display-config)) + +(my--cleanup-buffers-add "^\\*Shell Command Output\\*$") +(my--cleanup-buffers-add "^\\*Async Shell Command\\*$") + ;; Make shell scrips executable on save. Good! (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p) + +;; Color in *Shell Command Output* +(require 'ansi-color) +(defadvice display-message-or-buffer (before ansi-color activate) + "Process ANSI color codes in shell output." + (let ((buf (ad-get-arg 0))) + (and (bufferp buf) + (string= (buffer-name buf) "*Shell Command Output*") + (with-current-buffer buf + (ansi-color-apply-on-region (point-min) (point-max)))))) diff --git a/init/init-snippets.el b/init/init-snippets.el deleted file mode 100644 index 96f0f334c..000000000 --- a/init/init-snippets.el +++ /dev/null @@ -1,62 +0,0 @@ -(provide 'init-snippets) - -(use-package yasnippet - :mode (("emacs\\.d/.+/snippets/" . snippet-mode)) - :pre-load - (progn - ;; Fix yasnippet keymaps so they only work in insert mode (why they - ;; had to make this so complicated I don't know); must be defined - ;; BEFORE we include yasnippet. - (defvar yas-minor-mode-map - (let ((map (make-sparse-keymap))) - (bind 'insert map [(tab)] 'yas-expand) - (bind 'insert map (kbd "TAB") 'yas-expand) - (bind 'visual map (kbd "") 'yas-insert-snippet) - map))) - :config - (progn - (defadvice evil-force-normal-state (before evil-esc-quit-yasnippet activate) - (shut-up (yas-exit-all-snippets))) - - ;; Only load personal snippets - (setq yas-snippet-dirs `(,*snippets-dir)) - (setq yas-prompt-functions '(yas-ido-prompt yas-no-prompt)) - (setq yas-also-auto-indent-first-line t) - - (after auto-complete - ;; (add-hook! 'yas-before-expand-snippet-hook (auto-complete-mode -1)) - ;; (add-hook! 'yas-after-exit-snippet-hook (auto-complete-mode t)) - (defadvice ac-expand (before advice-for-ac-expand activate) - (when (yas-expand) (ac-stop)))) - - (bind yas-keymap (kbd "DEL") 'my/yas-clear-field) - - (yas-reload-all)) - :init - (progn - (add-hook 'snippet-mode-hook 'disable-final-newline) - (add-hook 'text-mode-hook 'yas-minor-mode) - (add-hook 'prog-mode-hook 'yas-minor-mode) - (add-hook 'snippet-mode-hook 'yas-minor-mode) - ;; (add-hook 'markdown-mode-hook 'yas-minor-mode) - (add-hook 'org-mode-hook 'yas-minor-mode))) - -;; Prevents Yas from stepping on my toes when I use backspace -(defun my/yas-clear-field (&optional field) - (interactive) - (let ((field (or field - (and yas--active-field-overlay - (overlay-buffer yas--active-field-overlay) - (overlay-get yas--active-field-overlay 'yas--field))))) - (cond ((and field - (not (yas--field-modified-p field)) - (eq (point) (marker-position (yas--field-start field)))) - (yas--skip-and-clear field)) - (t (delete-char -1))))) - -;; yas snippet helpers -(defvaralias '% 'yas-selected-text) -(defun %! () (if % (s-trim-right %))) -(defun !% () (if % (s-trim-left %))) -(defun !%! () (if % (s-trim %))) -(defun --newline-maybe () (if % "\n")) diff --git a/init/init-text.el b/init/init-text.el index 0d740d1c5..fcbbdb728 100644 --- a/init/init-text.el +++ b/init/init-text.el @@ -4,8 +4,8 @@ (add-hook 'prog-mode-hook 'enable-comment-hard-wrap) (use-package markdown-mode - :mode (("\\.md\\'" . markdown-mode) - ("/README\\'" . markdown-mode)) + :mode (("\\.md$" . markdown-mode) + ("/README$" . markdown-mode)) :pre-load (progn ;; Implement strike-through formatting diff --git a/init/init-tmux.el b/init/init-tmux.el new file mode 100644 index 000000000..b0b5d2ad0 --- /dev/null +++ b/init/init-tmux.el @@ -0,0 +1,35 @@ +(provide 'init-tmux) + +(defun my--tmux-send (command) + (shell-command (format "tmux send-keys %s" command))) + +(after "evil" + (evil-define-interactive-code "" + "Ex tmux argument (a mix between and )" + :ex-arg shell + (list (when (evil-ex-p) (evil-ex-file-arg)))) + + (evil-ex-define-cmd "t" 'ex:tmux-run) + (evil-define-command ex:tmux-run (&optional command bang) + "Sends input to tmux. Use `bang' to append to tmux" + (interactive "") + (my--tmux-send (concat (unless bang "C-u ") + (shell-quote-argument command) + (unless bang " Enter"))) + (when (evil-ex-p) + (message "[Tmux] %s" command))) + + (evil-ex-define-cmd "tcd" 'ex:tmux-chdir) + (evil-define-command ex:tmux-chdir (&optional path bang) + "CDs in tmux using `my--project-root'" + (interactive "") + (let ((dir (shell-quote-argument + (if (and path (not (s-blank? path))) + (if (file-directory-p path) + (file-truename path) + (error "Directory doesn't exist %s" path)) + (my--project-root bang))))) + (my--tmux-send (format "C-u cd Space %s Enter" (shell-quote-argument dir))) + (when (evil-ex-p) + (message "[Tmux] cd %s" dir))))) + diff --git a/init/init-webdev.el b/init/init-webdev.el index e858a3330..e267a2448 100644 --- a/init/init-webdev.el +++ b/init/init-webdev.el @@ -2,29 +2,15 @@ (use-package rainbow-mode :defer t - :init - (progn - (add-hook 'scss-mode-hook 'rainbow-mode) - (add-hook 'sass-mode-hook 'rainbow-mode))) - -(use-package sass-mode - :mode "\\.sass$" - :init (add-hook 'sass-mode-hook 'enable-tab-width-2) - :config - (progn - (add-hook 'sass-mode-hook 'ac-css-mode-setup) - - (add-to-list 'ac-modes 'sass-mode) - (setq-default css-indent-offset 2))) + :init (add-hook 'scss-mode-hook 'rainbow-mode)) (use-package scss-mode :mode "\\.scss$" - :init (add-hook 'scss-mode-hook 'enable-tab-width-2) :config (progn + (add-hook 'scss-mode-hook 'enable-tab-width-2) (add-hook 'scss-mode-hook 'ac-css-mode-setup) - (add-to-list 'ac-modes 'scss-mode) (setq-default css-indent-offset 2) (setq scss-compile-at-save nil) @@ -42,8 +28,7 @@ (progn (add-hook 'web-mode-hook 'enable-tab-width-2) - (setq web-mode-ac-sources-alist - '(("css" . (ac-source-css-property))) + (setq web-mode-ac-sources-alist '(("css" . (ac-source-css-property))) web-mode-markup-indent-offset 2 web-mode-code-indent-offset 2 web-mode-css-indent-offset 2 @@ -56,12 +41,12 @@ "zf" 'web-mode-fold-or-unfold ",t" 'web-mode-element-rename) (bind '(normal visual) web-mode-map - "gQ" 'web-beautify-html - "]a" 'web-mode-attribute-next - "]t" 'web-mode-tag-next - "[t" 'web-mode-tag-previous - "]T" 'web-mode-element-child - "[T" 'web-mode-element-parent))) + "gQ" 'web-beautify-html + "]a" 'web-mode-attribute-next + "]t" 'web-mode-tag-next + "[t" 'web-mode-tag-previous + "]T" 'web-mode-element-child + "[T" 'web-mode-element-parent))) (use-package emmet-mode :defer t @@ -87,36 +72,48 @@ (add-hook! 'php-mode-hook (setq my-run-code-interpreter "php")) (setq php-template-compatibility nil))) -;;; Javascript -(use-package tern - :commands tern-mode - :config - (progn - (require 'tern-auto-complete) - - (setq tern-ac-on-dot nil))) - (use-package js2-mode :mode "\\.js$" :config (progn - (use-package js2-refactor - :config - ;; TODO Set up keymaps - ) (setq-default js2-show-parse-errors nil) - (setq-default js2-global-externs '("module" "require" "buster" "sinon" "assert" "refute" "setTimeout" "clearTimeout" "setInterval" "clearInterval" "location" "__dirname" "console" "JSON" "jQuery" "$" + (setq-default js2-global-externs '("module" "require" "buster" "sinon" "assert" + "refute" "setTimeout" "clearTimeout" + "setInterval" "clearInterval" "location" + "__dirname" "console" "JSON" "jQuery" "$" ;; Launchbar API "LaunchBar" "File" "Action" "HTTP" "include")) - (bind 'insert js2-mode-map [remap auto-complete] 'tern-ac-complete) - (bind 'motion js2-mode-map "gd" 'tern-find-definition) - (bind '(normal visual) js2-mode-map "gQ" 'web-beautify-js)) + (bind '(normal visual) js2-mode-map "gQ" 'web-beautify-js) + + (use-package js2-refactor + ;; :config + ;; TODO Set up keymaps + ) + + (use-package tern + :commands tern-mode + ;; replace auto-complete with tern-ac-complete only in js-mode + :init (add-hook! 'js2-mode-hook + (tern-mode t) + (tern-ac-setup) + (setq my-run-code-interpreter "node")) + :config + (progn + (after "auto-complete" + (require 'tern-auto-complete) + (setq tern-ac-on-dot nil) + (bind 'insert js2-mode-map + [remap auto-complete] 'tern-ac-complete) + (bind 'motion js2-mode-map + "gd" 'tern-find-definition)) + + (after "company-tern" + (add-to-list 'company-backends 'company-tern) + ;; (setq company-tern-meta-as-single-line t) + ;; (setq company-tern-property-marker "") + ;; (setq company-tooltip-align-annotations t) + ))))) - ;; replace auto-complete with tern-ac-complete only in js-mode - :init (add-hook! 'js2-mode-hook - (tern-mode t) - (tern-ac-setup) - (setq my-run-code-interpreter "node"))) (use-package web-beautify :commands (web-beautify-js web-beautify-css web-beautify-html) diff --git a/init/init-yasnippet.el b/init/init-yasnippet.el new file mode 100644 index 000000000..0645c9856 --- /dev/null +++ b/init/init-yasnippet.el @@ -0,0 +1,128 @@ +(provide 'init-yasnippet) + +(use-package yasnippet + :mode (("emacs\\.d/.+/snippets/" . snippet-mode)) + :pre-load + (defvar yas-minor-mode-map + ;; Fix yasnippet keymaps so they only work in insert mode + (let ((map (make-sparse-keymap))) + (bind 'insert map [(tab)] 'yas-expand) + (bind 'insert map (kbd "TAB") 'yas-expand) + (bind 'visual map (kbd "") 'yas-insert-snippet) + map)) + :init + (progn + (add-hook 'snippet-mode-hook 'disable-final-newline) + (add-hook 'snippet-mode-hook 'yas-minor-mode) + (add-hook 'text-mode-hook 'yas-minor-mode) + (add-hook 'prog-mode-hook 'yas-minor-mode) + ;; (add-hook 'markdown-mode-hook 'yas-minor-mode) + (add-hook 'org-mode-hook 'yas-minor-mode)) + :config + (progn + (setq yas-verbosity 0) + (setq yas-indent-line 'auto) + (setq yas-also-auto-indent-first-line t) + (setq yas-wrap-around-region nil) + ;; Only load personal snippets + (setq yas-snippet-dirs `(,my-snippets-dir)) + (setq yas-prompt-functions '(yas-ido-prompt yas-no-prompt)) + + (push '(snippet-mode :position bottom :stick t) popwin:special-display-config) + + (yas-reload-all) + + (after "auto-complete" + (defadvice ac-expand (before advice-for-ac-expand activate) + (when (yas-expand) (ac-stop)))) + + (after "evil" + ;; Exit snippets on ESC in normal mode + (defadvice evil-force-normal-state (before evil-esc-quit-yasnippet activate) + (yas-exit-all-snippets)) + ;; Once you're in normal mode, you're out + (add-hook 'evil-normal-state-entry-hook 'yas-abort-snippet) + + ;; Fixes: evil's visual-line mode gobbles up the newline on the right. + ;; This prevents that by essentially doing (1- (region-end)). + (defadvice yas-expand-snippet (around yas-expand-snippet-visual-line activate) + (if (evil-visual-line-state-p) + (ad-set-arg 2 (1- (ad-get-arg 2)))) ad-do-it) + + ;; Fixes: visual-line includes indentation before the selection. This + ;; strips it out. + (add-hook! 'yas-before-expand-snippet-hook + (if (evil-visual-line-state-p) + (setq-local yas-selected-text + (replace-regexp-in-string + "\\(^ *\\|\n? $\\)" "" + (buffer-substring-no-properties (region-beginning) + (1- (region-end))))))) + ;; Previous hook causes yas-selected-text to persist between expansions. + ;; This little hack gets around it. + (add-hook! 'yas-after-exit-snippet-hook + (setq-local yas-selected-text nil)) + + (evil-ex-define-cmd "snip[pets]" 'ex:snippets) + (evil-define-operator ex:snippets (beg end &optional name) + :motion nil + :move-point nil + :type exclusive + :repeat nil + (interactive "") + (if (and beg end) + (yas-insert-snippet) + (if name + (popwin:find-file (concat my-snippets-dir + (symbol-name major-mode) "/" name)) + (yas-visit-snippet-file))))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; Snippet helpers + (defvaralias '% 'yas-selected-text) + ;; Shorthand defun for snippets: prepends a newline to `yas-selected-text' + ;; IF it contains more than one line. + (defun !% () + (when % + (if (> (s-count-lines %) 1) + (concat "\n" %) + (s-trim %)))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; Inter-field navigation + (defun my/yas-goto-start-of-field () + (interactive) + (let* ((snippet (car (yas--snippets-at-point))) + (position (yas--field-start (yas--snippet-active-field snippet)))) + (if (= (point) position) + (move-beginning-of-line 1) + (goto-char position)))) + (defun my/yas-goto-end-of-field () + (interactive) + (let* ((snippet (car (yas--snippets-at-point))) + (position (yas--field-end (yas--snippet-active-field snippet)))) + (if (= (point) position) + (move-end-of-line 1) + (goto-char position)))) + + ;; Prevents Yas from stepping on my toes when I use backspace + (defun my/yas-clear-field (&optional field) + (interactive) + (let ((field (or field (and yas--active-field-overlay + (overlay-buffer yas--active-field-overlay) + (overlay-get yas--active-field-overlay 'yas--field))))) + (cond ((and field + (not (yas--field-modified-p field)) + (eq (point) (marker-position (yas--field-start field)))) + (yas--skip-and-clear field)) + (t (delete-char -1))))) + + ;; keybinds + (bind yas-keymap + "C-e" 'my/yas-goto-end-of-field + "C-a" 'my/yas-goto-start-of-field + "" 'my/yas-goto-end-of-field + "" 'my/yas-goto-start-of-field + "DEL" 'my/yas-clear-field))) diff --git a/init/my-bindings.el b/init/my-bindings.el new file mode 100644 index 000000000..e956301f0 --- /dev/null +++ b/init/my-bindings.el @@ -0,0 +1,194 @@ +(provide 'my-bindings) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Global keymaps ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(bind (kbd "M-x") 'smex + (kbd "M-X") 'smex-major-mode-commands + (kbd "C-;") 'eval-expression + ;; (kbd "C-`") 'popwin:toggle-eshell-window + (kbd "C-~") 'popwin:toggle-popup-window + + (kbd "s-=") 'text-scale-increase + (kbd "s--") 'text-scale-decrease + (kbd "s-w") 'evil-window-delete + (kbd "s-/") 'evilnc-comment-or-uncomment-lines) + +;; Faster scrolling +(bind '(normal visual) my-mode-map + (kbd "s-j") "6j" + (kbd "s-k") "6k" + (kbd "s-b") 'my:build + (kbd "s-f") 'helm-swoop + (kbd "s-F") 'helm-do-ag) + +(bind 'normal my-mode-map + (kbd "s-r") 'my-run-code-buffer + (kbd "s-R") 'my-switch-to-repl + (kbd "s-t") 'helm-projectile-find-file + (kbd "s-T") 'helm-semantic-or-imenu + (kbd "s-p") 'helm-projectile-switch-project + (kbd "s-P") 'persp-switch + (kbd "s-m") ",m" + (kbd "s-M") ",M" + (kbd "s-o") 'ido-find-file + (kbd "s-d") 'dash-at-point) + +(bind 'visual my-mode-map + (kbd "s-r") 'my-run-code-region + (kbd "s-R") 'my-send-region-to-repl) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Local keymaps ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(bind '(normal visual) my-mode-map + "\\" 'evil-execute-in-god-state ; localleader + ;; ";" 'evil-ex ; Remap ; to : - SPC and shift-SPC replace ; and , + "X" 'evil-exchange + + "g SPC" (λ (call-interactively + (if (evil-visual-line-state-p) + 'evil-ace-jump-line-mode + 'evil-ace-jump-char-mode))) + "g w" 'evil-ace-jump-word-mode ; overwrites evil-fill + "g l" 'evil-ace-jump-line-mode + "g s" 'evil-ace-jump-two-chars-mode + "g t" 'ace-window + "g T" (λ (ace-window 4)) + + "] e" 'next-error + "[ e" 'previous-error + "] g" 'git-gutter+-next-hunk + "[ g" 'git-gutter+-previous-hunk + + "] \\" 'er/expand-region + "[ \\" 'er/contract-region) + +(bind 'normal my-mode-map + ", a" 'helm-projectile-find-other-file + ", e" 'ido-find-file + ", E" 'my:init-files + ", f" 'helm-projectile-find-file-dwim + ", g" 'git-gutter+-show-hunk + ", h" 'helm-apropos + ", m" 'helm-recentf + ", M" 'helm-projectile-recentf ; recent PROJECT files + ", p" 'helm-projectile-switch-project + ", y" 'helm-show-kill-ring + ", ;" 'helm-semantic-or-imenu + ", ," 'helm-projectile-switch-to-buffer + ", <" 'helm-mini + ", ]" 'helm-etags-select + ", /" 'helm-projectile-find-file + ", ." 'helm-resume) + +(bind 'god my-mode-map + ;; + "\\" 'neotree-toggle + ":" 'linum-mode + "=" 'toggle-transparency + + "]" 'next-buffer + "[" 'previous-buffer + + "o f" 'my-send-dir-to-finder + "o u" 'my-send-to-transmit + "o l" 'my-send-to-launchbar + "o L" 'my-send-dir-to-launchbar + + ;; tmux: cd (default-directory) + "o t" (λ (my:tmux-chdir nil t)) + ;; tmux: cd [project root] + "o T" 'my:tmux-chdir) + +(bind 'normal my-mode-map + ;; behave like D and C; yank to end of line + "Y" (λ (evil-yank (point) (point-at-eol))) + + "z x" 'kill-this-buffer + "Z X" 'bury-buffer + + "] b" 'next-buffer + "[ b" 'previous-buffer + "] p" 'persp-next + "[ p" 'persp-prev + + ;; winner-mode: window layout undo/redo (see init-core.el) + "C-w u" 'winner-undo + "C-w C-u" 'winner-undo + "C-w C-r" 'winner-redo + + ;; Increment/decrement number under cursor + "C-=" 'evil-numbers/inc-at-pt + "C--" 'evil-numbers/dec-at-pt) + +(bind 'visual my-mode-map + ", =" 'align-regexp + + ;; vnoremap < >gv + ">" (λ (evil-shift-right (region-beginning) (region-end)) + (evil-normal-state) + (evil-visual-restore))) + +(bind 'insert my-mode-map + "" (λ (evil-forward-word) (evil-delete-backward-word)) + + ;; Newline magic + "" 'backward-delete-char-untabify + "" 'backward-delete-char + "" 'evil-ret-and-indent + "" (kbd " DEL") ; newline and dedent + + ;; Textmate-esque indent shift left/right + "s-[" (kbd "C-o m l C-o I DEL C-o ` l") + "s-]" (λ (evil-shift-right (point-at-bol) (point-at-eol))) + "" (kbd "s-[")) + +;; (bind 'emacs +;; ;; Preserve buffer-movement in emacs mode +;; "C-j" 'evil-next-line +;; "C-k" 'evil-previous-line + +;; "C-w h" 'evil-window-left +;; "C-w l" 'evil-window-right +;; "C-w j" 'evil-window-down +;; "C-w k" 'evil-window-up) + +;; Rotate-text (see elisp/rotate-text.el) +(bind 'normal my-mode-map "!" 'rotate-word-at-point) +(bind 'visual my-mode-map "!" 'rotate-region) + +;; Easy escape from insert mode +;; (ibind "jk" 'evil-normal-state) + +;; Enable TAB to do matchit +(bind '(normal visual) evil-matchit-mode-map [tab] 'evilmi-jump-items) + +;; Additional operators +(bind 'normal my-mode-map "g r" 'my:run-code) ; code eval +(bind 'normal my-mode-map "g R" 'my:send-region-to-repl) ; eval in repl +(bind 'normal my-mode-map "g x" 'my-scratch-buffer) ; send to scratch buffer + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Plugin/mode keymaps ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Peek at file from dired +(bind dired-mode-map "o" (λ (popwin:find-file (dired-get-file-for-visit)))) + +;; Evil registers ;;;;;;;;;;;;;;;;;;;;;; + +(after "help-mode" + (bind 'normal help-mode-map + "]]" 'help-go-forward + "[[" 'help-go-back)) + +(evil-make-overriding-map my-mode-map nil) diff --git a/init/my-coderunner.el b/init/my-coderunner.el deleted file mode 100644 index 27d6a7126..000000000 --- a/init/my-coderunner.el +++ /dev/null @@ -1,66 +0,0 @@ -(provide 'my-coderunner) - -;; Variables -(defvar my-run-code-interpreter nil) -(defvar my-run-code-func 'my/run-code-shell) -(defvar my-run-code-region-func 'my/run-code-region-shell) -(defvar my-switch-to-repl-func nil) -(defvar my-send-region-to-repl-func nil) -(defvar my-build-func nil) - -(make-variable-buffer-local 'my-run-code-interpreter) -(make-variable-buffer-local 'my-run-code-func) -(make-variable-buffer-local 'my-run-code-region-func) -(make-variable-buffer-local 'my-switch-to-repl-func) -(make-variable-buffer-local 'my-send-region-to-repl-func) -(make-variable-buffer-local 'my-build-func) - -(add-hook! 'emacs-lisp-mode-hook - (setq my-run-code-func 'eval-buffer - my-run-code-region-func 'eval-region)) - -(defun my/run-code-shell (file-path) - (if (stringp my-run-code-interpreter) - (shell-command (concat my-run-code-interpreter " " file-path)) - (message "No interpreter set for %s. See `my-run-code-interpreter'" (symbol-name major-mode)))) - -(defun my/run-code-region-shell (beg end) - (if (stringp my-run-code-interpreter) - (shell-command-on-region beg end my-run-code-interpreter) - (message "No interpreter set for %s. See `my-run-code-interpreter'" (symbol-name major-mode)))) - -;; -(defun my:switch-to-repl () - (interactive) - (if (functionp my-switch-to-repl-func) - (funcall my-switch-to-repl-func) - (message "No REPL was set for %s. See `my-switch-to-repl-func'" (symbol-name major-mode)))) - -(defun my:send-region-to-repl (beg end) - (interactive "r") - (if (functionp my-send-region-to-repl-func) - (funcall my-send-region-to-repl-func beg end) - (message "No region runner set for %s. See `my-send-region-to-repl-func'" (symbol-name major-mode)))) - -(defun my:run-code-buffer () - (interactive) - (let ((file-name (buffer-file-name)) - (mode-name (symbol-name major-mode))) - (if (and (not (buffer-modified-p)) - (file-exists-p file-name)) - (if (functionp my-run-code-func) - (funcall my-run-code-func file-name) - (message "No runner set for %s. See `my-run-code-func'" mode-name)) - (my:run-code-region (point-min) (point-max))))) - -(defun my:run-code-region (beg end) - (interactive "r") - (if (functionp my-run-code-region-func) - (funcall my-run-code-region-func beg end) - (message "No region runner set for %s. See `my-run-code-region-func'" (symbol-name major-mode)))) - -(defun my:build (&optional arguments) - (interactive) - (if (functionp my-build-func) - (funcall my-build-func arguments) - (message "No build function set for %s. See `my-build-func'" (symbol-name major-mode)))) diff --git a/init/my-commands.el b/init/my-commands.el deleted file mode 100644 index 62f27747b..000000000 --- a/init/my-commands.el +++ /dev/null @@ -1,248 +0,0 @@ -(provide 'my-commands) - -;;;; Defun Commands ;;;;;;;;;;;;;;;;;;;; -(defun my:minibuffer-quit () - "Abort recursive edit. In Delete Selection mode, if the mark is -active, just deactivate it; then it takes a second \\[keyboard-quit] -to abort the minibuffer." - (interactive) - (if (and delete-selection-mode transient-mark-mode mark-active) - (setq deactivate-mark t) - (when (get-buffer "*Completions*") (delete-windows-on "*Completions*")) - (abort-recursive-edit))) - -;; Buffer defuns -(defun my:kill-other-buffers () - "Kill left-over temporary, dired or buried special buffers" - (interactive) - (mapc (lambda (buffer) - (let ((buffer-name (buffer-name buffer))) - (when (and (not (s-matches? buffer-name "\\*\\(scratch\\|Messages\\)\\*")) - (or (eq 'dired-mode (buffer-local-value 'major-mode buffer)) - (s-matches? "^ ?\\*.+\\*$" buffer-name)) - (not (get-buffer-window buffer))) - (kill-buffer buffer)))) - (buffer-list))) - -;; Inspired by http://demonastery.org/2013/04/emacs-evil-narrow-region/ -(defun my:narrow-to-region-indirect (start end) - "Restrict editing in this buffer to the current region, indirectly." - (interactive "r") - (deactivate-mark) - (let ((buf (clone-indirect-buffer nil nil))) - (with-current-buffer buf - (narrow-to-region start end)) - (switch-to-buffer buf))) - -(defun my:kill-persp () - (interactive) - (persp-kill (persp-name persp-curr))) - -;;;; Tmux defuns ;;;;;;;;;;;;;;;;; -(defun my:tmux-send (command) - (interactive "sSend to Tmux: ") - (shell-command - (concat "/usr/local/bin/tmux send-keys " command))) - -;;;; Mac-specific Defuns ;;;;;;;;; -(when is-mac - ;; Send current file to OSX apps - (defun my:open-file-with (path &optional appName) - (if (and appName - (stringp appName) - (not (string= "" appName))) - (setq appName (concat "-a " appName ".app"))) - (async-shell-command (concat "open " appName " " (shell-quote-argument path)))) - - (defun my:open-with (appName) - (interactive "sApp name: ") - (my:open-file-with buffer-file-name appName)) - - (defun my:send-to-transmit () (interactive) (my:open-with "Transmit")) - (defun my:send-to-launchbar () (interactive) (my:open-with "LaunchBar")) - (defun my:send-dir-to-launchbar () (interactive) (my:open-file-with default-directory "LaunchBar")) - (defun my:send-dir-to-finder () (interactive) (my:open-file-with default-directory "Finder"))) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Ex-commands ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(evil-define-command ex:kill-buffers (&optional bang) :repeat nil - (interactive "") - (if (and bang (projectile-project-p)) - (projectile-kill-buffers) - (mapc 'kill-buffer (buffer-list))) - (delete-other-windows)) - -(evil-define-command ex:init-files (&optional bang) :repeat nil - (interactive "") - (if bang - (ido-find-file-in-dir *init-dir) - (ido-find-file-in-dir *dir))) - -(evil-define-command ex:notes () :repeat nil - (interactive) - (ido-find-file-in-dir org-directory)) - -;; Projects -(evil-define-command ex:ag-search (search &optional bang regex) :repeat nil - (interactive "") - (let ((root (my/project-root bang))) - (if search - (if regex (ag-regexp search root) (ag search root)) - (helm-do-ag root)))) - -(evil-define-command ex:ag-regex-search (search &optional bang) :repeat nil - (interactive "") - (ex:ag-search search bang t)) - -;; Run a command. If , then only type command into tmux -(evil-define-command ex:tmux-send (command &optional bang) :repeat nil - (interactive "") - (let ((cmd-format (if bang "%s" "C-u %s Enter"))) - (my:tmux-send (format cmd-format (shell-quote-argument command))) - (when (evil-ex-p) - (message "[Tmux] %s" command)))) - -(evil-define-command ex:tmux-chdir (&optional path bang) :repeat nil - (interactive "") - (let ((dir (shell-quote-argument - (if (and path - (not (s-blank? path)) - (file-directory-p path)) - (file-truename path) - (my/project-root bang))))) - (ex:tmux-send (format "cd %s" dir)) - (when (evil-ex-p) - (message "[Tmux] cd %s" dir)))) - -(evil-define-command ex:byte-compile-all (&optional bang) :repeat nil - (interactive "") - (require 'async-bytecomp) - ;; (async-byte-recompile-directory *dir 0 bang) - (byte-recompile-directory *dir 0 bang)) - -(evil-define-command ex:build (arguments &optional bang) :repeat nil - (interactive "") - (my:build arguments)) - -(evil-define-command ex:cd (dir) :repeat nil - (interactive "") - (cd (if (zerop (length dir)) "~" dir))) - -(defun --save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit)) -(evil-define-command ex:create-file (path &optional bang) :repeat nil - "Deploy files (and their associated templates) quickly. Will prompt -you to fill in each snippet field before buffer closes unless BANG is -provided." - (interactive "") - (let ((dir (f-dirname path)) - (fullpath (f-full path)) - (is-auto t)) - (when (and bang (not (f-exists? dir))) (f-mkdir dir)) - (if (f-exists? dir) - (if (f-exists? fullpath) - (error "File already exists: %s" path) - (find-file fullpath) - (add-hook 'yas-after-exit-snippet-hook '--save-exit) - (if bang (--save-exit))) - (error "Directory doesn't exist: %s" dir)))) - -(evil-define-command ex:rename-this-file (new-name &optional bang) :repeat nil - "Renames current buffer and file it is visiting." - (interactive "") - (let ((name (buffer-name)) - (filename (buffer-file-name))) - (if (not (and filename (file-exists-p filename))) - (error "Buffer '%s' is not visiting a file!" name) - (let ((new-name (if new-name new-name (read-file-name "New name: " filename)))) - (if (get-buffer new-name) - (error "A buffer named '%s' already exists!" new-name) - (rename-file filename new-name 1) - (rename-buffer new-name) - (set-visited-file-name new-name) - (set-buffer-modified-p nil) - (when bang - (delete-file filename)) - (message "File '%s' successfully renamed to '%s'" - name (file-name-nondirectory new-name))))))) - -;;; -(evil-define-operator ex:scratch-buffer (beg end) - :move-point nil - :type inclusive - (interactive "") - (let ((mode major-mode) - (text (when (and beg end) (buffer-substring beg end)))) - (switch-to-buffer (get-buffer-create "*scratch*")) - (if text (insert text)) - (funcall mode))) - -(evil-define-operator ex:org-capture (beg end) - :move-point nil - :type inclusive - (interactive "") - (let ((mode major-mode) - (text (when (and beg end) (buffer-substring beg end)))) - (if text - (org-capture-string text) - (org-capture)))) - -(evil-define-operator ex:retab (beg end) - :motion nil - :move-point nil - :type line - "Akin to vim's :retab, this changes all tabs-to-spaces or -spaces-to-tabs, depending on `indent-tab-mode'. Untested." - (interactive "") - (unless (and beg end) - (setq beg (point-min)) - (setq end (point-max))) - (if indent-tabs-mode - (tabify beg end) - (untabify beg end))) - -(evil-define-operator ex:run-code (beg end) - :move-point nil - (interactive "") - (cond ((and beg end) - (my:run-code-region beg end)) - (t - (my:run-code-buffer)))) - -(evil-define-operator ex:send-region-to-repl (beg end &optional bang) - :motion nil - :move-point nil - :type exclusive - :repeat nil - (interactive "") - (cond ((and beg end) - (my:send-region-to-repl beg end)) - (t - (my:switch-to-repl)))) - -(evil-define-operator ex:snippets (beg end &optional name) - :motion nil - :move-point nil - :type exclusive - :repeat nil - "Create a new snippet (called `name'), or select from all the - current mode's snippets to edit." - (interactive "") - (cond ((and beg end) - (yas-insert-snippet)) - (t - (if name - (find-file (concat *snippets-dir (symbol-name major-mode) "/" name)) - (yas-visit-snippet-file))))) - -(evil-define-operator ex:narrow-indirect (beg end) - :motion nil - :move-point nil - :type exclusive - :repeat nil - "Indirectly narrow the region from BEG to END." - (interactive "") - (evil-normal-state) - (narrow-to-region-indirect beg end)) diff --git a/init/my-keymaps.el b/init/my-keymaps.el deleted file mode 100644 index 869efeb8f..000000000 --- a/init/my-keymaps.el +++ /dev/null @@ -1,236 +0,0 @@ -(provide 'my-keymaps) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Global keymaps ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(bind (kbd "M-x") 'smex - (kbd "M-X") 'smex-major-mode-commands - (kbd "C-;") 'eval-expression - (kbd "C-`") 'popwin:popup-last-buffer - - (kbd "s-=") 'text-scale-increase - (kbd "s--") 'text-scale-decrease - (kbd "s-w") 'evil-window-delete - (kbd "s-/") 'evilnc-comment-or-uncomment-lines - (kbd "s-") 'toggle-frame-fullscreen) - -;; Faster scrolling -(bind '(normal visual) - (kbd "s-j") "7j" - (kbd "s-k") "7k" - (kbd "s-r") 'my:run-code-buffer - (kbd "s-R") 'my:switch-to-repl) - -(bind 'normal (kbd "s-t") 'projectile-find-file - (kbd "s-T") 'projectile-find-tag - (kbd "s-p") 'projectile-switch-project - (kbd "s-P") 'persp-switch - (kbd "s-f") 'projectile-ag - (kbd "s-S-f") 'helm-do-ag - (kbd "s-m") ",m" - (kbd "s-M") ",M" - (kbd "s-o") 'ido-find-file - (kbd "s-d") 'dash-at-point) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Local keymaps ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(bind 'god - ;; - ":" 'linum-mode - "\\" 'neotree-toggle - "=" 'toggle-transparency - - "of" 'my:send-dir-to-finder - "ou" 'my:send-to-transmit - "ol" 'my:send-to-launchbar - "oL" 'my:send-dir-to-launchbar - - ;; tmux: cd (default-directory) - "ot" (λ (ex:tmux-chdir nil t)) - ;; tmux: cd [project root] - "oT" 'ex:tmux-chdir) - -(bind '(normal visual) - ";" 'evil-ex ; Remap ; to : - SPC and shift-SPC replace ; and , - "\\" 'evil-execute-in-god-state ; localleader - "X" 'evil-exchange - - "gc" 'evil-ace-jump-char-mode - "gw" 'evil-ace-jump-word-mode ; overwrites evil-fill - "gl" 'evil-ace-jump-line-mode - "gt" 'ace-window - "gT" (λ (ace-window 4)) - - "]e" 'next-error - "[e" 'previous-error - "]g" 'git-gutter+-next-hunk - "[g" 'git-gutter+-previous-hunk - - "]\\" 'er/expand-region - "[\\" 'er/contract-region) - -(bind 'normal - ",r" 'my:run-code-buffer - ",R" 'my:switch-to-repl - ",a" 'helm-projectile-find-other-file - ",e" 'ido-find-file - ",E" 'ex:init-files - ",m" 'helm-recentf - ",M" 'helm-projectile-recentf ; recent PROJECT files - ",p" 'helm-projectile-switch-project - ",g" 'git-gutter+-show-hunk - ",;" 'helm-imenu - ",," 'helm-projectile-switch-to-buffer - ",<" 'helm-buffers-list - ",]" 'helm-etags-select - ",/" 'helm-projectile-find-file - ",." 'helm-projectile-find-file-dwim - - ;; Moving rows rather than lines (in case of wrapping) - "j" 'evil-next-visual-line - "k" 'evil-previous-visual-line - - ;; behave like D and C; yank to end of line - "Y" (λ (evil-yank (point) (point-at-eol))) - - "zz" 'kill-this-buffer - "zx" 'bury-buffer - - "]b" 'next-buffer - "[b" 'previous-buffer - "]p" 'persp-next - "[p" 'persp-prev - - ;; winner-mode: window layout undo/redo (see init-core.el) - (kbd "C-w u") 'winner-undo - (kbd "C-w C-r") 'winner-redo - - ;; Increment/decrement number under cursor - (kbd "C--") 'evil-numbers/inc-at-pt - (kbd "C-+") 'evil-numbers/dec-at-pt) - -(bind 'visual - ",=" 'align-regexp - ",r" 'my:run-code-region - ",R" 'my:send-region-to-repl - - ;; vnoremap < >gv - ">" (λ (evil-shift-right (region-beginning) (region-end)) - (evil-normal-state) - (evil-visual-restore))) - -(bind 'insert - ;; Join lines from insert mode - (kbd "") (λ (evil-forward-word) (evil-delete-backward-word)) - - ;; Newline magic - (kbd "") 'backward-delete-char-untabify - (kbd "") 'backward-delete-char - (kbd "") 'evil-ret-and-indent - (kbd "") (kbd " DEL") ; newline and dedent - - ;; Textmate-esque indent shift left/right - (kbd "s-[") (kbd "C-o m l C-o I DEL C-o ` l") - (kbd "s-]") (λ (evil-shift-right (point-at-bol) (point-at-eol))) - (kbd "") (kbd "s-[")) - -(bind 'emacs - ;; Preserve buffer-movement in emacs mode - "\C-j" 'evil-next-line - "\C-k" 'evil-previous-line - - (kbd "C-w h") 'evil-window-left - (kbd "C-w l") 'evil-window-right - (kbd "C-w j") 'evil-window-down - (kbd "C-w k") 'evil-window-up) - -;; Rotate-text (see elisp/rotate-text.el) -(bind 'normal "!" 'rotate-word-at-point) -(bind 'visual "!" 'rotate-region) - -;; Easy escape from insert mode -(ibind "jj" 'evil-normal-state) - -;; Enable TAB to do matchit -(bind '(normal visual) evil-matchit-mode-map [tab] 'evilmi-jump-items) - -;; Additional operators -(bind '(normal motion) "gr" 'ex:run-code) ; code eval -(bind '(normal motion) "gR" 'ex:send-region-to-repl) ; eval in repl -(bind '(normal motion) "gx" 'ex:scratch-buffer) ; send to scratch buffer - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Plugin/mode keymaps ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Real go-to-definition for elisp -(bind 'motion emacs-lisp-mode-map "gd" - (λ (let ((func (function-called-at-point))) - (if func (find-function func))))) -(bind 'motion emacs-lisp-mode-map "gD" - (λ (let ((func (function-called-at-point))) - (if func (find-function-other-window func))))) - -;; Peek at file from dired -(bind dired-mode-map "o" (λ (popwin:find-file (dired-get-file-for-visit)))) - -;; Evil registers ;;;;;;;;;;;;;;;;;;;;;; -(bind evil-ex-completion-map - (kbd "C-r") #'evil-ex-paste-from-register ; registers in ex-mode - (kbd "C-a") 'move-beginning-of-line - (kbd "") 'move-beginning-of-line - (kbd "") 'move-beginning-of-line - (kbd "") 'evil-delete-whole-line) -;; Quickly close/kill the command window -(bind 'normal evil-command-window-mode-map - [escape] 'kill-buffer-and-window - "q" 'kill-buffer-and-window) - -;; Make C-g work like -(bind '(normal visual insert) (kbd "C-g") 'evil-normal-state) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Ex Commands ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defcmd "msg" 'popwin:messages) -(defcmd "recompile" 'ex:byte-compile-all) -(defcmd "n[otes]" 'ex:notes) -(defcmd "ini" 'ex:init-files) -(defcmd "rec[ent]" 'ex:recent-files) -(defcmd "snip[pets]" 'ex:snippets) -(defcmd "retab" 'ex:retab) -(defcmd "ag" 'ex:ag-search) -(defcmd "agr" 'ex:ag-regex-search) -(defcmd "x" 'ex:scratch-buffer) -(defcmd "X" 'ex:org-capture) -(defcmd "a" 'helm-projectile-find-other-file) -(defcmd "cd" 'ex:cd) -(defcmd "tcd" 'ex:tmux-chdir) -(defcmd "t[mux]" 'ex:tmux-send) -(defcmd "r[ege]x" 'regex-tool) -(defcmd "en[ew]" 'ex:create-file) -(defcmd "l[ast]" 'popwin:popup-last-buffer) -(defcmd "run" 'ex:run-code) -(defcmd "build" 'ex:build) -(defcmd "k[ill]" 'kill-this-buffer) ; Kill current buffer -(defcmd "k[ill]all" 'ex:kill-buffers) ; Kill all buffers (bang = project buffers only) -(defcmd "k[ill]persp" 'my:kill-persp) ; Kill current perspective -(defcmd "k[ill]o" 'my:kill-other-buffers) ; Kill current project buffers -(defcmd "sq[uint]" 'ex:narrow-indirect) ; Narrow buffer to selection -(defcmd "ren[ame]" 'ex:rename-this-file) ; Rename file . Bang: Delete old one - -(after git-gutter+ - (defcmd "gstage" 'git-gutter+-stage-hunks) - (defcmd "grevert" 'git-gutter+-revert-hunks) - (defcmd "gdiff" 'git-gutter+-show-hunk)) diff --git a/init/my-settings.el b/init/my-settings.el index a53d0e720..775495f24 100644 --- a/init/my-settings.el +++ b/init/my-settings.el @@ -1,20 +1,128 @@ (provide 'my-settings) -(custom-set-variables - ;; custom-set-variables was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. - '(git-gutter:lighter " !") - ;; Make brin theme safe - '(custom-safe-themes - (quote - ("7fa3f2865322ee4e3fcf061efcf020465d691aed02e6756191fbf1cfb8648ccf" default)))) +;;;; Modes 'n hooks ;;;;;;;;;;;;;;;;; +(associate-mode "/LICENSE[^/]*$" 'text-mode) +(associate-mode "zsh\\(env\\|rc\\)?$" 'sh-mode) +(associate-mode "z\\(profile\\|login\\|logout\\)?$" 'sh-mode) +(associate-mode "zsh/" 'sh-mode) +(associate-mode "\\.applescript$" 'applescript-mode) +(associate-mode "Cask$" 'emacs-lisp-mode) +(associate-mode "\\.el\\.gz$" 'emacs-lisp-mode) +(associate-mode "/Makefile$" 'makefile-gmake-mode) +(associate-mode "\\.plist$" 'nxml-mode) -(set-face-background 'show-paren-match-face "#1f1f1f") -(set-face-foreground 'show-paren-match-face "orange") -(set-face-attribute 'show-paren-match-face nil - :weight 'bold :underline nil :overline nil :slant 'normal) - -(setenv "SHELL" (s-trim (shell-command-to-string "which zsh"))) +;; (setenv "SHELL" (s-trim (shell-command-to-string "which zsh"))) +(setenv "SHELL" "/usr/local/bin/zsh") (setenv "EMACS" "1") + +;; show-paren faces +(set-face-background 'show-paren-match nil) +(set-face-foreground 'show-paren-match "orange") +(set-face-attribute 'show-paren-match nil :weight 'extra-bold) + +(set-register ?. "~/.dotfiles/") +(set-register ?d "~/Dropbox/Projects/") +(set-register ?@ "~/.emacs.d/init.el") +(set-register ?% "~/.emacs.d/init.el") + +(add-hook 'help-mode-hook 'visual-line-mode) + +;; Performance checks +(add-hook! 'find-file-hook + ;; If file is oversized... + (when (> (buffer-size) (* 1024 1024)) + (setq buffer-read-only t) + (buffer-disable-undo) + (fundamental-mode) + (visual-line-mode))) + + +;;;; Keymap Fixes ;;;;;;;;;;;;;;;;;;;;;; +;; This section is dedicated to keymaps that "fix" certain keys so +;; that they behave more like vim (or how I like it). + +;; Restores "dumb" indentation to the tab key. This rustles a lot of +;; peoples' jimmies, apparently, but it's how I like it. +(bind 'insert (kbd "TAB") 'my.dumb-indent) +;; Except for lisp +(bind 'insert lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) +(bind 'insert emacs-lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) + +;; Highjacks backspace and space to: +;; a) expand spaces between delimiters intelligently: (|) -> ( | ) +;; b) the reverse of A: ( | ) -> (|) +;; c) allow backspace to delete indented blocks intelligently +;; d) and not do any of this magic when inside a string +(bind 'insert + (kbd "SPC") 'my.inflate-space-maybe + [remap backward-delete-char-untabify] 'my.deflate-space-maybe + [remap newline] 'my.newline-and-indent + + ;; Smarter move-to-beginning-of-line + [remap move-beginning-of-line] 'my.move-to-bol + + ;; Restore bash-esque keymaps in insert mode; C-w and C-a already exist + "\C-e" 'my.move-to-eol + "\C-u" 'my.backward-kill-to-bol-and-indent + + ;; Fixes delete + (kbd "") 'delete-char + + ;; Textmate-esque insert-line before/after + (kbd "") 'evil-open-below + (kbd "") 'evil-open-above) + +;; Fix osx keymappings and then some +(bind 'insert + (kbd "") 'my.move-to-bol + (kbd "") 'my.move-to-eol + (kbd "") 'beginning-of-buffer + (kbd "") 'end-of-buffer + (kbd "") 'my.backward-kill-to-bol-and-indent) + +(add-hook! 'ido-setup-hook + (bind ido-completion-map + (kbd "") 'ido-delete-backward-updir + "\C-w" 'ido-delete-backward-word-updir)) + +;; Make ESC quit all the things +(bind (list minibuffer-local-map + minibuffer-local-ns-map + minibuffer-local-completion-map + minibuffer-local-must-match-map + minibuffer-local-isearch-map) [escape] 'my--minibuffer-quit) +(bind 'emacs [escape] 'my--minibuffer-quit) + +(bind 'god [escape] 'evil-god-state-bail) +(bind 'normal evil-command-window-mode-map [escape] 'kill-buffer-and-window) +(bind evil-ex-map [escape] 'my--minibuffer-quit) + +(bind (list evil-ex-search-keymap minibuffer-local-map) + "\C-w" 'evil-delete-backward-word) +(bind minibuffer-local-map + "\C-u" 'evil-delete-whole-line) +;; Close help/compilation windows with escape + +;; Redefine to get rid of that silly delete-other-windows nonsense +(defun keyboard-escape-quit () + (interactive) + (cond ((eq last-command 'mode-exited) nil) + ((region-active-p) + (deactivate-mark)) + ((> (minibuffer-depth) 0) + (abort-recursive-edit)) + (current-prefix-arg + nil) + ((> (recursion-depth) 0) + (exit-recursive-edit)) + (buffer-quit-function + (funcall buffer-quit-function)) + ((string-match "^ \\*" (buffer-name (current-buffer))) + (bury-buffer)))) + + +(defun my-emacs-is-not-kill () + (interactive) + (message "Gee, I dunno Brain...")) + +(if is-mac (global-set-key (kbd "s-q") 'my-emacs-is-not-kill))