diff --git a/Cask b/Cask index ade95f899..c4b9075cb 100644 --- a/Cask +++ b/Cask @@ -13,29 +13,27 @@ (depends-on "use-package") ;; Editing +(depends-on "smart-mode-line") (depends-on "shut-up") (depends-on "dired+") -(depends-on "autopair") (depends-on "expand-region") (depends-on "flycheck") (depends-on "flyspell") (depends-on "multiple-cursors") (depends-on "rainbow-delimiters") -(depends-on "autopair") +(depends-on "smartparens") (depends-on "anzu") (depends-on "key-chord") (depends-on "saveplace") (depends-on "yasnippet") -(depends-on "git-gutter") +(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 "ace-jump-mode") -(depends-on "highlight-indentation" :git "https://github.com/hlissner/Highlight-Indentation-for-Emacs") -(depends-on "gist") -;;(depends-on "smart-tabs-mode") +;; (depends-on "gist") ;; Eeeevil (depends-on "evil") @@ -46,6 +44,10 @@ (depends-on "evil-space") (depends-on "evil-visualstar") (depends-on "evil-nerd-commenter") +(depends-on "evil-indent-textobject") +(depends-on "evil-jumper") +(depends-on "evil-god-state") +(depends-on "god-mode") ;; Project management (depends-on "projectile") @@ -79,13 +81,11 @@ (depends-on "tern") (depends-on "tern-auto-complete") -(depends-on "rbenv") (depends-on "rspec-mode") (depends-on "inf-ruby") (depends-on "ac-inf-ruby") (depends-on "jedi") -(depends-on "pyenv" :git "https://github.com/cyberved/pyenv.el") (depends-on "omnisharp") (depends-on "csharp-mode") diff --git a/cleanup.sh b/cleanup.sh new file mode 100755 index 000000000..0aa36d61b --- /dev/null +++ b/cleanup.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +rm -f init.elc init/*.elc init/defuns/*.elc elisp/*.elc &> /dev/null diff --git a/elisp/emacs-neotree b/elisp/emacs-neotree deleted file mode 160000 index a0c415ac6..000000000 --- a/elisp/emacs-neotree +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a0c415ac6726e316c1c7da720d96e417c49bd5f4 diff --git a/elisp/evil-ex-registers.el b/elisp/evil-ex-registers.el index 6397e7ff5..c0ef37dcf 100644 --- a/elisp/evil-ex-registers.el +++ b/elisp/evil-ex-registers.el @@ -54,7 +54,7 @@ Support some registers listed below in addition to (defun evil-ex-paste-from-register (&optional register) "Paste from REGISTER in command line." (interactive) - (flet ((evil-get-register (register &optional noerror) + (cl-flet ((evil-get-register (register &optional noerror) (with-current-buffer evil-ex-current-buffer (evil-get-spec-register register noerror)))) (if (called-interactively-p 'any) diff --git a/elisp/org-opml b/elisp/org-opml deleted file mode 160000 index 22a1d4c1a..000000000 --- a/elisp/org-opml +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 22a1d4c1a60ee5d0688197ab85c93031322539a3 diff --git a/elisp/rake-mode.el b/elisp/rake-mode.el new file mode 100644 index 000000000..9f2837258 --- /dev/null +++ b/elisp/rake-mode.el @@ -0,0 +1,95 @@ +;; -*-Emacs-Lisp-*- +;; +;; rake-mode.el --- in-file Rake task running +;; +;; Copyright (C) 2008 Joseph Abrahamson . +;; Released under The Perl Artistic License 2.0 +;; + +;; Code: + +(require 'ido) +(provide 'rake-mode) + +(defvar rake-minor-mode-map (make-sparse-keymap) "Keymap for Rake minor mode") + +(define-minor-mode rake-mode + "Toggle Rake minor mode + +With no argument, this command toggles Rake mode. Non-null prefix +arguments turn the mode on and null deactive it. + +Rake mode enables Rake task calling with autocompletion in the +specified directory." + :init-value nil + :lighter " Rake" + :keymap rake-minor-mode-map + nil) + + +(defvar rake-mode/rakefile nil + "* Path to Rakefile. Rake will be executed here.") + +(defun rake-mode/task (task &optional prefix) + "Run a Rake task from the tasks described by Rakefile. + +If no Rakefile is described use rake-mode/visit-rakefile. + +If prefix is given, the output from Rake is sent to the +minibuffer temporarily instead of being given its own temp buffer" + (interactive + (list (ido-completing-read (concat "Tasks at (" rake-mode/rakefile "): ") (rake-mode/get-tasks)) + current-prefix-arg)) + (when task + (save-current-buffer + (let ((str (concat "*** RAKE TASK: " + task + " ***\n" + (ansi-color-apply + (in-rakepath + (shell-command-to-string + (concat "rake " + task))))))) + (if prefix + (message str) + (with-output-to-temp-buffer "*Rake Output*" + (princ str))))))) + +(defun rake-mode/visit-rakefile (file &optional local) + (interactive (list (ido-read-file-name "Visit Rakefile (default Rakefile): " + default-directory + (expand-file-name "Rakefile" + default-directory) + t) + current-prefix-arg)) + (or (stringp file) (signal 'wrong-type-argument (list 'stringp file))) + (let ((rakefile-name file)) + (save-excursion + (or (find-file-noselect file) + (signal 'file-error (list "Visiting Rakefile" + "file does not exist" + file))))) + (if local + (set (make-local-variable 'rake-mode/rakefile) file) + (setq-default rake-mode/rakefile file))) + +(defmacro in-rakepath (&rest body) + `(let ((default-directory (rake-mode/get-rakefile-path))) ,@body)) + +(defun rake-mode/get-rakefile-path () + (if rake-mode/rakefile + (replace-regexp-in-string "\/\[^/\]\+$" "/" rake-mode/rakefile) + (error "Rakefile not yet visited."))) + +(defun rake-mode/get-tasks () + (in-rakepath + (let ((lines (split-string (shell-command-to-string "rake -P") "\n"))) + (if (string= (car lines) "rake aborted!") + (error "Rake failed. Check Rakefile")) + (loop for str in lines + for task = (save-match-data + (when (and (not (string= "" str)) + (not (string-match "^ +$" str))) + (nth 1 (s-match "^rake \\([^ ]*\\)" str)) + )) + when task collect task)))) diff --git a/elisp/ruby-mode-indent-fix.el b/elisp/ruby-mode-indent-fix.el index 005bbdfed..6e40b42a3 100644 --- a/elisp/ruby-mode-indent-fix.el +++ b/elisp/ruby-mode-indent-fix.el @@ -55,9 +55,6 @@ (eval-when-compile (require 'cl)) -(require 'autopair) - - (defvar ruby--paren-closings-regex "[])}\"']" "regex matching closing paren or string delimiter.") @@ -83,7 +80,7 @@ note: `ruby-deep-indent-paren' has to be enabled for this to work." (save-excursion (back-to-indentation) (let ((state (syntax-ppss))) - (when (and (or (memq (autopair-find-pair (char-after)) ruby-deep-indent-paren) + (when (and (or (memq (sp-get-pair (char-after)) ruby-deep-indent-paren) (and (eq (char-after) ?\}) (eq 'brace (ruby--point-in-braced-proc)))) (not (zerop (car state)))) diff --git a/elisp/use-package b/elisp/use-package deleted file mode 160000 index 019d11383..000000000 --- a/elisp/use-package +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 019d11383d10d39aafc7fe4faae101b01c147146 diff --git a/init.el b/init.el index 1aff957cc..711b89403 100644 --- a/init.el +++ b/init.el @@ -3,62 +3,67 @@ ;; Author: Henrik Lissner ;; URL: https://github.com/hlissner/emacs.d ;; -;; These settings set up a vim-like experience, with some of emacs -;; goodness squeezed into the cracks. +;; My emacs.d, which sets out to rustle emacs users' jimmies by making +;; emacs as vim-like as possible. ;; ;;; Code: -(cd "~") ; Default directory, instead of / -;; (setq use-package-verbose t) +;; instead of / +(cd "~") +;; (setq use-package-verbose t) ; for debug purposes (require 'cask) (cask-initialize) -(when window-system - (server-mode t) - (unless (server-running-p) (server-start))) - -;; Global vars (defconst *dir (file-name-directory load-file-name)) -(defconst *init-dir (expand-file-name "init" *dir)) -(defconst *themes-dir (expand-file-name "themes" *dir)) -(defconst *elisp-dir (expand-file-name "elisp" *dir)) -(defconst *snippets-dir (expand-file-name "snippets" *dir)) -(defconst *ac-dicts-dir (expand-file-name "ac-dict" *dir)) +(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 "/tmp/emacs/") (defconst *theme 'brin) (defconst *font "Inconsolata-16") -;; (defconst my/font "Ubuntu-Mono-15") (add-to-list 'load-path *init-dir) +;; Just the... bear necessities... (mapc 'require - '(core ; Just the... bear necessities... + '(core + my-defuns ; Personal library - ;;; These are implicitly loaded from core.el, leave them commented! - ;; core-editor ; Internal config for global editor behavior - ;; core-ui ; User interface layout & behavior - ;; core-osx ; Mac-specific config - ;; my-keymaps ; My keybindings (loaded on after-init-hook) + ;; Tailoring emacs + core-editor ; Internal config for global editor behavior + core-ui ; User interface layout & behavior + core-osx ; Mac-specific config - my-defuns ; Personal functions + ;; Plugins & modules + init-ido ; Ido setup + init-project ; Project navigation tools & settings + init-ac ; Auto-complete engine & settings + init-snippets ; Snippet engine + init-git ; GIT tools/settings + init-fly ; Syntax & spell checker - ;; Modules to improve on emacs' heresy - init-ido ; Ido setup - init-project ; Project navigation tools & settings - init-ac ; Auto-complete engine & settings - init-snippets ; Snippet engine - init-git ; GIT tools/settings - init-fly ; Syntax and spell checker - init-text ; Plain text editing (markdown, text) - init-org ; Org-mode: personal gtd/notes - init-dev ; Generic environment for all programming + ;; Modes & environments + init-text ; Plain text editing (markdown, text) + init-org ; Org-mode: personal gtd/notes + init-dev ; Generic dev tools & environment for all programming init-ruby init-python - init-webdev ; Environment for webdev (SCSS, PHP, Rails, Jekyll) - init-love ; Love.app gamedev - init-cpp ; C++ gamedev - init-eclim ; Integration into eclipse (for Java) - init-csharp ; Emacs as a Csharp/Unity IDE - ;; init-collab ; For collab programming + init-webdev ; Environment for webdev (SCSS, PHP, Rails, Jekyll) + init-love ; Love.app gamedev + init-cpp ; C++ gamedev + init-eclim ; Integration into eclipse (for Java) + init-csharp ; Emacs as a Csharp/Unity IDE + + my-settings ; Any other custom settings + my-commands ; Interactive defuns & evil operators/commands + my-keymaps ; My keybindings )) + +(require 'server) +(unless (server-running-p) (server-start)) + +;; I've created a monster! diff --git a/init/core-editor.el b/init/core-editor.el index 7ddb1c233..de1b995c3 100644 --- a/init/core-editor.el +++ b/init/core-editor.el @@ -8,16 +8,40 @@ (setq-default indent-tabs-mode nil) (setq-default tab-always-indent nil) +;; In case of emacs 24.4 +(electric-indent-mode -1) + +;; Remember undo history +(setq undo-tree-auto-save-history t) +(setq undo-tree-history-directory-alist `((".*" . ,*tmp-dir-undo))) + +;; Save cursor location across sessions +(require 'saveplace) +(setq-default save-place t) +(setq save-place-file (f-expand "saveplace" *tmp-dir)) + +;; Save history across sessions +(setq savehist-additional-variables + ;; search entries + '(search ring regexp-search-ring) + ;; keep the home clean + savehist-file (f-expand "savehist" *tmp-dir)) +(savehist-mode 1) + ;;;; Modes 'n hooks ;;;;;;;;;;;;;;;;; -(add-to-list 'auto-mode-alist '("\\.plist\\'" . nxml-mode)) -(add-to-list 'auto-mode-alist '("zsh\\(env\\|rc\\)?\\'" . shell-script-mode)) -(add-to-list 'auto-mode-alist '("z\\(profile\\|login\\|logout\\)?\\'" . shell-script-mode)) -(add-to-list 'auto-mode-alist '("zsh/" . shell-script-mode)) -(add-to-list 'auto-mode-alist '("\\.applescript$" . applescript-mode)) +(associate-mode "\\.plist$" nxml-mode) +(associate-mode "zsh\\(env\\|rc\\)?$" shell-script-mode) +(associate-mode "z\\(profile\\|login\\|logout\\)?$" shell-script-mode) +(associate-mode "zsh/" shell-script-mode) +(associate-mode "\\.applescript$" applescript-mode) +(associate-mode "Cask$" emacs-lisp-mode) +(associate-mode "\\.el\\.gz$" emacs-lisp-mode) (add-hook 'text-mode-hook 'enable-hard-wrap) (add-hook 'prog-mode-hook 'enable-comment-hard-wrap) (add-hook 'before-save-hook 'delete-trailing-whitespace) +;; Autosave buffers on focus-out (emacs 24.4 only) +(add-hook! 'focus-out-hook (save-some-buffers t)) ;;;; Evil-mode ;;;;;;;;;;;;;;;;;;;;;;; (use-package evil @@ -26,62 +50,219 @@ (progn (evil-mode 1) - (use-package evil-matchit) - (use-package evil-surround) - (use-package evil-numbers) - (use-package evil-exchange) - (use-package evil-space) - (use-package evil-visualstar) - (use-package evil-nerd-commenter) - (use-package evil-ex-registers) - - (global-evil-matchit-mode 1) - (global-evil-surround-mode 1) - - (evil-exchange-install) - - (evil-space-setup "t" ";" ",") ; Repeat t with space - (evil-space-setup "f" ";" ",") ; Repeat f with space - (evil-space-setup "T" "," ";") ; Repeat T with space - (evil-space-setup "F" "," ";") ; Repeat F with space - (evil-define-operator evil-destroy (beg end type register yank-handler) - (evil-delete beg end type ?_ yank-handler)) - - ;; Enable half-cursor blink when using ace-jump - (defadvice evil-ace-jump-char-mode (around evil-ace-jump-char-mode-operator-mode activate) - (evil-half-cursor) ad-do-it) - (defadvice evil-ace-jump-word-mode (around evil-ace-jump-word-mode-operator-mode activate) - (evil-half-cursor) ad-do-it) + (setq evil-search-module 'evil-search) + (setq evil-magic 'very-magic) + ;; Color-coded state cursors + (setq evil-normal-state-cursor '("white" box)) + (setq evil-visual-state-cursor '("cyan" box)) + (setq evil-god-state-cursor '("orange" box)) (evil-set-initial-state 'comint-mode 'insert) - ;; Enable registers in ex-mode - (define-key evil-ex-completion-map (kbd "C-r") #'evil-ex-paste-from-register) - )) + (use-package evil-ex-registers) + (use-package evil-exchange) + (use-package evil-indent-textobject) + (use-package evil-numbers) + (use-package evil-visualstar) + + (use-package evil-nerd-commenter + :pre-load (setq evilnc-hotkey-comment-operator "g/")) + + (use-package evil-jumper + :pre-load + (defvar evil-jumper-file (expand-file-name "jumplist" *tmp-dir)) + :config + (setq evil-jumper-auto-center t + evil-jumper-auto-save-interval 3600)) + + (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) + :config + (progn + ;; Adds escaped delimiters to evil-surround + (defun my.evil-surround-escaped-pair () + "Evil-surround function to allow escaped delimiters. e.g. \"...\"" + (let* ((input (format "\\%s" (char-to-string (read-char "\\"))))) + (cons input input))) + (setq-default evil-surround-pairs-alist (cons '(?\\ . my.evil-surround-escaped-pair) evil-surround-pairs-alist)) + )) + + (use-package god-mode) + (use-package evil-god-state :diminish god-local-mode) + + (defmap 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) + + ;; Enable half-cursor blink when using ace-jump + (defadvice evil-ace-jump-char-mode (before evil-ace-jump-char-mode-operator-mode activate) + (evil-half-cursor)) + (defadvice evil-ace-jump-word-mode (before evil-ace-jump-word-mode-operator-mode activate) + (evil-half-cursor)) + + ;; Exit evil-exchange mode with (silently) -- and close + ;; minibuffer remotely if it happens to be open + (defadvice evil-force-normal-state (before evil-esc-quit-exchange activate) + (shut-up (evil-exchange-cancel) + (if (minibufferp) + (my:minibuffer-quit)))) + + ;; Shut up beginning/end of buffer/line messages in minibuffer + (defun my.minibuffer-bolp () + "Return t if (point) is truly at the beginning of the +minibuffer/evil-ex (first character after the prompt), otherwise +returns nil." + (<= (- (point) (minibuffer-prompt-end)) 0)) + (defadvice left-char (around left-char-move-on-edges activate) + (if (minibufferp) + (unless (my.minibuffer-bolp) ad-do-it) + ad-do-it)) + (defadvice right-char (around right-char-move-on-edges activate) + (if (minibufferp) + (unless (eolp) ad-do-it) + ad-do-it)) + + ;; 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))) + +;;;; Keymap Fixes ;;;;;;;;;;;;;;;;;;;;;; +;; This section is dedicated to keymaps that "fix" certain keys to +;; behave to be 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. +(-imap (kbd "TAB") 'my.dumb-indent) +;; Except for lisp +(imap lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) +(imap 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) And allow backspace to delete indented blocks intelligently +(-imap (kbd "SPC") 'my.inflate-space-maybe + [remap backward-delete-char-untabify] 'my.deflate-space-maybe + [remap delete-backward-char] '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 + + ;; Fix osx keymappings + (kbd "") 'evil-move-beginning-of-line + (kbd "") 'my.move-to-eol + (kbd "") '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) + +(add-hook! 'ido-setup-hook + (defmap ido-completion-map + (kbd "") 'ido-delete-backward-updir + "\C-w" 'ido-delete-backward-word-updir)) + +;; Make ESC quit all the things +(global-set-key [escape] 'keyboard-escape-quit) +(mapc (lambda (map) + (defmap map [escape] 'my:minibuffer-quit)) + (list minibuffer-local-map + minibuffer-local-ns-map + minibuffer-local-completion-map + minibuffer-local-must-match-map + minibuffer-local-isearch-map)) +(defmap isearch-mode-map [escape] 'isearch-abort) +(defmap evil-god-state-map [escape] 'evil-god-state-bail) +(defmap evil-ex-search-keymap [escape] 'evil-ex-search-exit) +;; Close help/compilation windows with escape +(defmap help-mode-map [escape] 'kill-buffer-and-window) +(defmap compilation-mode-map [escape] 'kill-buffer-and-window) +(emap debugger-mode-map [remap evil-exit-emacs-state] 'kill-buffer-and-window) ;;;; Editing plugins ;;;;;;;;;;;;;;;;;;; (use-package expand-region) -(use-package autopair - :diminish autopair-mode - :init - (progn (autopair-global-mode) - (setq autopair-blink nil) - ;; disable blink-matching-paren - (setq blink-matching-paren nil))) +(use-package smartparens + :config + (progn + (require 'smartparens-config) + (smartparens-global-mode 1) + + (setq blink-matching-paren nil) + (setq sp-autowrap-region nil ; let evil-surround handle this + sp-highlight-pair-overlay nil + sp-show-pair-delay 0 + sp-autoescape-string-quote t) + + (sp-pair "{" nil :post-handlers '(("||\n[i]" "RET"))) + (sp-pair "[" nil :post-handlers '(("||\n[i]" "RET"))) + (sp-local-pair 'emacs-lisp-mode "[" nil :post-handlers '(("|" "RET"))) + + (sp-pair "\"" nil :unless '(sp-point-after-word-p sp-point-before-word-p)) + (sp-pair "'" nil :unless '(sp-point-after-word-p sp-point-before-word-p)) + + (after yasnippet + (defadvice yas-expand (before advice-for-yas-expand activate) + (sp-remove-active-pair-overlay))))) (use-package anzu :diminish anzu-mode - :init (global-anzu-mode)) - -(use-package multiple-cursors - :commands (mc/mark-next-like-this mc/mark-previous-like-this mc/mark-all-like-this) - :config - (progn - ;; I do it this way because hooking mc/keyboard-quit to insert mode's exit - ;; hook breaks multiple-cursors! - (defadvice keyboard-quit (around mc-and-keyboard-quit activate) - (mc/keyboard-quit) ad-do-it))) + :init + (global-anzu-mode)) ;;;; Utility plugins ;;;;;;;;;;;;;;;;;; (use-package key-chord @@ -98,17 +279,20 @@ (when (boundp 'smex-cache) (smex-update))) (add-hook 'after-load-functions 'smex-update-after-load))) -(use-package uniquify - :config - (setq uniquify-buffer-name-style 'forward)) - (use-package recentf :init (progn (recentf-mode 1) (setq recentf-max-menu-items 0 - recentf-max-saved-items 75 - recent5-auto-cleanup 'never - recentf-exclude '("/tmp/" - "/ssh:" - "\\.ido\\.last\\'" - "\\.revive\\'")))) + recentf-max-saved-items 100 + recentf-auto-cleanup 'never + recentf-exclude '("/tmp/" "/ssh:" "\\.ido\\.last\\'" "\\.revive\\'")))) + +(use-package re-builder + :defer t + :config + (progn (setq reb-re-syntax 'string) + (defadvice evil-force-normal-state (before evil-esc-quit-reb-mode activate) + (when (eq 'reb-mode major-mode) + (if reb-subexp-mode + (reb-quit-subexp-mode) + (reb-quit)))))) diff --git a/init/core-osx.el b/init/core-osx.el index 414c7f714..4bbe0f758 100644 --- a/init/core-osx.el +++ b/init/core-osx.el @@ -1,13 +1,14 @@ (provide 'core-osx) -;; Use a shared clipboard -(setq x-select-enable-clipboard t) -;; Curse you Lion-esque 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) +(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) -;; fix emacs PATH on OSX -(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))) diff --git a/init/core-ui.el b/init/core-ui.el index 5ec27c214..c7692d150 100644 --- a/init/core-ui.el +++ b/init/core-ui.el @@ -1,19 +1,23 @@ (provide 'core-ui) ;; (global-linum-mode t) ; line numbers for everybody! -;; (blink-cursor-mode -1) +(blink-cursor-mode -1) +(global-hl-line-mode 1) + +(setq show-paren-delay 0) +(show-paren-mode 1) + +;; 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) ;; Show line/col-no in mode-line (line-number-mode t) (column-number-mode t) - ;; make the fringe unintrusive -(when (fboundp 'fringe-mode) (fringe-mode 8)) - -;; Line numbers with +1 left-padding -;; (defadvice linum-update-window (around linum-dynamic activate) -;; (let* ((w (length (number-to-string (count-lines (point-min) (point-max))))) -;; (linum-format (concat "%" (number-to-string (+ w 1)) "d" " "))) ad-do-it)) +(when (fboundp 'fringe-mode) + (fringe-mode '(0 . 10))) ;; Show full path in window title (setq frame-title-format @@ -25,7 +29,7 @@ ;; do not soft-wrap lines (setq-default truncate-lines t) (setq truncate-partial-width-windows nil) -(add-hook 'help-mode-hook (lambda() (setq truncate-lines nil))) +(add-hook! 'help-mode-hook (setq truncate-lines nil)) (setq ediff-window-setup-function 'ediff-setup-windows-plain) @@ -35,7 +39,7 @@ (setq-default visible-bell nil) (setq-default use-dialog-box nil) -;;;; GUI Settings ;;;;;;;;;;;;;;;;;;;;; +;;;; GUI Settings ;;;;;;;;;;;;;;;;;;;;;; (setq ring-bell-function 'ignore) (add-to-list 'default-frame-alist `(font . ,*font)) (add-to-list 'default-frame-alist '(alpha 98 95)) ; *slightly* transparent window @@ -43,3 +47,21 @@ (when (functionp 'tool-bar-mode) (tool-bar-mode -1)) (when (functionp 'scroll-bar-mode) (scroll-bar-mode -1)) (when (functionp 'menu-bar-mode) (menu-bar-mode -1)) + +;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;; +(use-package smart-mode-line + :config + (mapc (lambda(mode) (add-to-list 'rm-excluded-modes mode)) + '(" Rake" + " SP" + " Fill" + )) + :init + (progn + (setq sml/no-confirm-load-theme t + sml/mode-width 'right + sml/show-remote nil + sml/encoding-format nil) + + (sml/setup) + (sml/apply-theme 'respectful))) diff --git a/init/core.el b/init/core.el index 725eeb07b..b2c68a253 100644 --- a/init/core.el +++ b/init/core.el @@ -1,5 +1,7 @@ (provide 'core) +(require 'f) + (defconst is-mac (eq system-type 'darwin)) (defconst is-linux (eq system-type 'gnu/linux)) @@ -9,16 +11,18 @@ ;; Emacs under-the-hood (global-auto-revert-mode 1) ; revert buffers for changed files +(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no (prefer-coding-system 'utf-8) -(setq-default load-prefer-newer t) ; load newer .el over older .elc -(setq-default gc-cons-threshold 50000000) ; avoid garbage collection (default is 400k) -(setq redisplay-dont-pause t) -(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no -(setq confirm-kill-emacs nil) -(setq-default enable-recursive-minibuffers nil) +(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 + vc-follow-symlinks nil + compilation-scroll-output t) -;; Show keystrokes in [near] realtime +;; Show keystrokes (setq echo-keystrokes 0.02) ;; Sane scroll settings @@ -26,7 +30,7 @@ scroll-conservatively 100000 scroll-preserve-screen-position 1) -(setq inhibit-startup-screen t ; don't show EMACs start screen +(setq inhibit-startup-screen t ; don't show EMACs start screen inhibit-splash-screen t inhibit-startup-buffer-menu t inhibit-startup-echo-area-message t @@ -35,37 +39,28 @@ initial-scratch-buffer nil) ; empty scratch buffer ;;; Backups -;; If I ever enable backups/autosaves, then change where they go -(setq make-backup-files nil ; Don't want any backup files - auto-save-list-file-name nil ; Don't want any .saves files +(defconst *tmp-dir-undo (f-expand "undo" *tmp-dir)) +(defconst *tmp-dir-backup (f-expand "backup" *tmp-dir)) +(unless (f-dir? *tmp-dir) + (f-mkdir *tmp-dir *tmp-dir-undo *tmp-dir-backup)) + +(setq make-backup-files nil ; Don't want any backup + auto-save-list-file-name nil ; Don't want any .saves auto-save-default nil ; Don't want any auto saving create-lockfiles nil) -(setq backup-directory-alist `((".*" . ,"/tmp/emacs/"))) -(setq auto-save-file-name-transforms `((".*" ,"/tmp/emacs/" t))) -;; Save history across sessions -(setq savehist-additional-variables - ;; search entries - '(search ring regexp-search-ring) - ;; save every 5 minutes - savehist-autosave-interval 300 - ;; keep the home clean - savehist-file (expand-file-name "savehist" "/tmp/emacs/")) -(savehist-mode 1) -;; Save cursor location across sessions -(require 'saveplace) -(setq-default save-place t) -(setq save-place-file (expand-file-name "saveplace" "/tmp/emacs/")) +;; In case I want to reactivate backup files +(setq backup-directory-alist `((".*" . ,*tmp-dir-backup))) ;; window layout undo/redo, keymaps in core-keymaps.el (when (fboundp 'winner-mode) (winner-mode 1)) ;;;; Advice ;;;;;;;;;;;;;;;;;;;;;;;; ;; Make next/previous-buffer skip special buffers -(defadvice next-buffer (after avoid-messages-buffer-in-next-buffer) +(defadvice next-buffer (after avoid-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) +(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))) @@ -75,8 +70,10 @@ ;; 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.") + "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 the checking happens for all pairs in auto-minor-mode-alist" @@ -99,16 +96,11 @@ the checking happens for all pairs in auto-minor-mode-alist" ;;;; Load the rest ;;;;;;;;;;;;;;;;;; (require 'shut-up) -;; (when noninteractive -;; (shut-up-silence-emacs)) +(when noninteractive + (shut-up-silence-emacs)) ;; Package management bootstrap (setq package-enable-at-startup nil - package-archive-exclude-alist - '(("melpa" org-trello) - ("melpa" org) - ("marmalade" org) - ("gnu" org)) delete-old-versions t) (let ((default-directory *elisp-dir)) @@ -116,10 +108,3 @@ the checking happens for all pairs in auto-minor-mode-alist" (normal-top-level-add-subdirs-to-load-path)) (require 'use-package) -(require 'diminish) - -(require 'core-ui) -(require 'core-editor) -(if is-mac (require 'core-osx)) - -(add-hook 'after-init-hook (lambda() (require 'my-keymaps))) diff --git a/init/defuns/coderunner.el b/init/defuns/coderunner.el index e69de29bb..e55338df2 100644 --- a/init/defuns/coderunner.el +++ b/init/defuns/coderunner.el @@ -0,0 +1,63 @@ +;; 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/defuns/commands.el b/init/defuns/commands.el index c9901d01e..e69de29bb 100644 --- a/init/defuns/commands.el +++ b/init/defuns/commands.el @@ -1,223 +0,0 @@ -;;;; Defun Commands ;;;;;;;;;;;;;;;;;;;; - -;; File navigation defuns -(defun my:goto-symbol (&optional symbol-list) - "Refresh imenu and jump to a place in the buffer using Ido." - (interactive) - (unless (featurep 'imenu) - (require 'imenu nil t)) - (cond - ((not symbol-list) - (let ((ido-mode ido-mode) - (ido-enable-flex-matching - (if (boundp 'ido-enable-flex-matching) - ido-enable-flex-matching t)) - name-and-pos symbol-names position) - (unless ido-mode - (ido-mode 1) - (setq ido-enable-flex-matching t)) - (while (progn - (imenu--cleanup) - (setq imenu--index-alist nil) - (my:ido-goto-symbol (imenu--make-index-alist)) - (setq selected-symbol - (ido-completing-read "Symbol? " symbol-names)) - (string= (car imenu--rescan-item) selected-symbol))) - (unless (and (boundp 'mark-active) mark-active) - (push-mark nil t nil)) - (setq position (cdr (assoc selected-symbol name-and-pos))) - (cond - ((overlayp position) - (goto-char (overlay-start position))) - (t - (goto-char position))))) - ((listp symbol-list) - (dolist (symbol symbol-list) - (let (name position) - (cond - ((and (listp symbol) (imenu--subalist-p symbol)) - (my:ido-goto-symbol symbol)) - ((listp symbol) - (setq name (car symbol)) - (setq position (cdr symbol))) - ((stringp symbol) - (setq name symbol) - (setq position - (get-text-property 1 'org-imenu-marker symbol)))) - (unless (or (null position) (null name) - (string= (car imenu--rescan-item) name)) - (add-to-list 'symbol-names name) - (add-to-list 'name-and-pos (cons name position)))))))) - -;; Buffer defuns -(defun my:kill-all-buffers () - "Kill all buffers, even the one you're in" - (interactive) - (delete-other-windows) - (mapc 'kill-buffer (buffer-list)) - (message "All buffers killed")) - -(defun my:kill-other-buffers () - "Kill all buffers but the one you're in" - (interactive) - (delete-other-windows) - (mapc 'kill-buffer (cdr (buffer-list (current-buffer)))) - (message "All other buffers killed")) - -(defun my:kill-dired-buffers () - (interactive) - (mapc (lambda (buffer) - (when (eq 'dired-mode (buffer-local-value 'major-mode buffer)) - (kill-buffer buffer))) - (buffer-list))) - -;;;; Tmux defuns ;;;;;;;;;;;;;;;;; -(defun my:tmux-run (command) - "Run command in tmux" - (interactive - (list - (read-shell-command "Tmux command: " nil nil - (let ((filename (cond (buffer-file-name) - ((eq major-mode 'dired-mode) - (dired-get-filename nil t))))) - (and filename (file-relative-name filename)))))) - - (shell-command (concat "/usr/local/bin/tmux send-keys C-u " (shell-quote-argument command) " Enter")) - ;; (call-process "/usr/local/bin/tmux" nil nil nil "C-u" "send-keys" command "C-m") - (message "[Tmux] Command sent: %s" command)) - -(defun my:tmux-paste (command) - (interactive "sSend to Tmux: ") - (shell-command (concat "/usr/local/bin/tmux send-keys " (shell-quote-argument command))) - (message "[Tmux] Text pasted: %s" command)) - -(defun my:tmux-chdir (dir) - "CD into a new directory in tmux" - (interactive "DDirectory: ") - (my:tmux-run (concat "cd " (shell-quote-argument dir))) - (message "[Tmux] Directory changed: %s" dir)) - -(defun my/project-root (&optional force-pwd) - (if (and (not force-pwd) - (projectile-project-p)) - (projectile-project-root) - default-directory)) - -;;;; Mac-specific Defuns ;;;;;;;;; -(when is-mac - ;; Send current file to OSX apps - (defun 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 open-with (appName) - (interactive "sApp name: ") - (open-file-with buffer-file-name appName)) - - (defun send-to-transmit () (interactive) (open-with "Transmit")) - (defun send-to-launchbar () (interactive) (open-with "LaunchBar")) - (defun send-dir-to-launchbar () (interactive) (open-file-with default-directory "LaunchBar")) - (defun send-dir-to-finder () (interactive) (open-file-with default-directory "Finder"))) - - -;;;; Ex-commands ;;;;;;;;;;;;;;;;;;;;;;; -(evil-define-command my:ex:msg-buffer () :repeat nil - (interactive) - (view-echo-area-messages) - (text-mode)) - -(evil-define-command my:ex:kill-buffers (&optional bang) :repeat nil - (interactive "") - (if bang (my:kill-all-buffers) (my:kill-other-buffers))) - -(evil-define-command my: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 my:ex:notes () :repeat nil - (interactive) - (ido-find-file-in-dir org-directory)) - -(evil-define-command my:ex:snippets (&optional bang) :repeat nil - (interactive "") - (if bang - (yas-new-snippet) - (yas-visit-snippet-file))) - -;; Projects -(evil-define-command my:ex:ag-search (search &optional bang) :repeat nil - (interactive "") - (let ((root (my/project-root bang))) - (ag search root))) - -(evil-define-command my:ex:ag-regex-search (search &optional bang) :repeat nil - (interactive "") - (let ((root (my/project-root bang))) - (ag-regexp search root))) - -(evil-define-command my:ex:tmux-chdir (&optional bang) :repeat nil - (interactive "") - (if bang - (my:tmux-chdir default-directory) - (my:tmux-chdir (projectile-project-root)))) - -;; Run a command. If , then only type command into tmux -(evil-define-command my:ex:tmux-send (command &optional bang) :repeat nil - (interactive "") - (if bang - (my:tmux-paste command) - (my:tmux-run command))) - -(evil-define-operator my:ex:scratch-buffer (beg end &optional bang) - :motion nil - :move-point nil - :type line - :repeat nil - (interactive "") - (let ((text nil) - (mode major-mode) - (text-empty-p nil)) - (when (and beg end) - (setq text (buffer-substring beg end))) - (if bang - (if text - (org-capture-string text) - (org-capture)) - (progn - (switch-to-buffer (get-buffer-create "*scratch*")) - (if text (insert text)) - (funcall mode))))) - -(evil-define-operator my:ex:retab (beg end) - :motion nil - :move-point nil - :type line - :repeat nil - "Akin to vim's :retab, this changes all tabs-to-spaces or -spaces-to-tabs, depending on `indent-tab-mode'. Untested." - (interactive "") - (let ((b beg) - (e end)) - (unless (and b e) - (setq b (point-min)) - (setq e (point-max))) - (if indent-tabs-mode - (tabify b e) - (untabify b e)))) - -(evil-define-command my:ex:byte-compile-all (&optional bang) :repeat nil - (interactive "") - (byte-recompile-file (expand-file-name "init.el" *dir) bang 0) - (byte-recompile-directory *init-dir 0 bang) - (byte-recompile-directory *elisp-dir 0 bang)) - -(evil-define-command my:ex:mru () :repeat nil - "Find a recent file using ido." - (interactive) - (let ((file (ido-completing-read "Choose recent file: " recentf-list nil t))) - (when file (find-file file)))) diff --git a/init/defuns/config.el b/init/defuns/config.el index dad1953c0..b639a56d1 100644 --- a/init/defuns/config.el +++ b/init/defuns/config.el @@ -2,45 +2,92 @@ (defmacro λ (&rest body) `(lambda () (interactive) ,@body)) +(defmacro associate-mode (match mode) + `(add-to-list 'auto-mode-alist '(,match . ,mode))) + +(defmacro associate-minor-mode (match minor-mode) + `(add-to-list 'auto-minor-mode-alist '(,match . ,minor-mode))) + +(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 'exmap 'evil-ex-define-cmd) +(defmacro ichmap (key command) + `(key-chord-define evil-insert-state-map ,key ,command)) +(defmacro defmap (map &rest body) + `(evil-define-key nil ,map ,@body)) + (defmacro nmap (map &rest body) - (macroexpand `(evil-define-key 'normal ,map ,@body))) + `(evil-define-key 'normal ,map ,@body)) (defmacro vmap (map &rest body) - (macroexpand `(evil-define-key 'visual ,map ,@body))) + `(evil-define-key 'visual ,map ,@body)) (defmacro imap (map &rest body) - (macroexpand `(evil-define-key 'insert ,map ,@body))) + `(evil-define-key 'insert ,map ,@body)) (defmacro emap (map &rest body) - (macroexpand `(evil-define-key 'emacs ,map ,@body))) + `(evil-define-key 'emacs ,map ,@body)) +(defmacro gmap (map &rest body) + `(evil-define-key 'god ,map ,@body)) +(defmacro mmap (&rest body) + `(evil-define-key 'motion ,map ,@body)) +(defmacro omap (&rest body) + `(evil-define-key 'operator ,map ,@body)) (defmacro nvmap (map &rest body) - (macroexpand-all + (macroexpand `(progn (nmap ,map ,@body) (vmap ,map ,@body)))) -;; insert-mode key-chord mapping -(defmacro ichmap (key command) - `(key-chord-define evil-insert-state-map ,key ,command)) +(defmacro nmap! (&rest body) + `(evil-define-key 'normal my-mode-map ,@body)) +(defmacro vmap! (&rest body) + `(evil-define-key 'visual my-mode-map ,@body)) +(defmacro imap! (&rest body) + `(evil-define-key 'insert my-mode-map ,@body)) +(defmacro emap! (&rest body) + `(evil-define-key 'emacs my-mode-map ,@body)) +(defmacro gmap! (&rest body) + `(evil-define-key 'god my-mode-map ,@body)) +(defmacro mmap! (&rest body) + `(evil-define-key 'motion my-mode-map ,@body)) +(defmacro omap! (&rest body) + `(evil-define-key 'operator my-mode-map ,@body)) +(defmacro nvmap! (&rest body) + (macroexpand + `(progn (nmap! ,@body) + (vmap! ,@body)))) -(defmacro associate-mode (match mode &optional minor-mode-p) - (let ((mode-alist (if minor-mode-p 'auto-minor-mode-alist 'auto-mode-alist))) - `(add-to-list ',mode-alist '(,match . ,mode)))) - - -;;;; Defuns ;;;;;;;;;;;;;;;;;;;;;;;; -(defun run-code-with (interpreter mode-map) - "Set up ,r (and s-r on macs) to run code using a specified -interpreter and print the output in the echo area" - (nmap mode-map (kbd ",r") - `(lambda() - (interactive) - (if (and (not (buffer-modified-p)) - (file-exists-p (buffer-file-name))) - (shell-command (concat ,interpreter " " (buffer-file-name))) - (shell-command-on-region (point-min) (point-max) ,interpreter)))) - (vmap mode-map (kbd ",r") - `(lambda() - (interactive) - (shell-command-on-region (region-beginning) (region-end) ,interpreter))) - - (when is-mac - (nmap mode-map (kbd "s-r") ",r") - (vmap mode-map (kbd "s-r") ",r"))) +(defmacro -nmap (&rest body) + `(evil-define-key nil evil-normal-state-map ,@body)) +(defmacro -vmap (&rest body) + `(evil-define-key nil evil-visual-state-map ,@body)) +(defmacro -imap (&rest body) + `(evil-define-key nil evil-insert-state-map ,@body)) +(defmacro -emap (&rest body) + `(evil-define-key nil evil-emacs-state-map ,@body)) +(defmacro -gmap (&rest body) + `(evil-define-key nil evil-god-state-map ,@body)) +(defmacro -mmap (&rest body) + `(evil-define-key nil evil-motion-state-map ,@body)) +(defmacro -omap (&rest body) + `(evil-define-key nil evil-operator-state-map ,@body)) +(defmacro -nvmap (&rest body) + (macroexpand + `(progn (-nmap ,@body) + (-vmap ,@body)))) diff --git a/init/defuns/hooks.el b/init/defuns/hooks.el index b23468a2b..2768623b6 100644 --- a/init/defuns/hooks.el +++ b/init/defuns/hooks.el @@ -1,10 +1,9 @@ (defun enable-hard-wrap() - (auto-fill-mode 1) - (diminish 'auto-fill-function)) + (auto-fill-mode 1)) (defun enable-comment-hard-wrap () (set (make-local-variable 'comment-auto-fill-only-comments) t) - (auto-fill-mode 1) - (diminish 'auto-fill-function)) + (auto-fill-mode 1)) -(defun enable-tab-width-2 () (setq tab-width 2)) +(defun enable-tab-width-2 () + (setq tab-width 2)) diff --git a/init/defuns/text.el b/init/defuns/text.el index b1cf3ddf9..e793c2fe2 100644 --- a/init/defuns/text.el +++ b/init/defuns/text.el @@ -1,10 +1,9 @@ ;;; Library Defuns ;;;;;;;;;;;;;;;;;;;;; (defun my/surrounded-p () - (and (looking-back "[[{(]\s*") - (looking-at-p "\s*[]})]")) - ;; (and (s-match "[[{(]" (s-right 1 (s-trim (buffer-substring (line-beginning-position) (point))))) - ;; (s-match "[])}]" (s-left 1 (s-trim (buffer-substring (point) (line-end-position)))))) - ) + (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))))) @@ -13,43 +12,69 @@ (buffer-substring (line-beginning-position) (line-end-position))) ;;; Text Defuns ;;;;;;;;;;;;;;;;;;;;;;;; -(defun my.backward-kill-to-bol () - (interactive) - (evil-delete (point-at-bol) (point))) - (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))) - (my.backward-kill-to-bol) + (evil-delete (point-at-bol) (point)) (if (not empty-line) (indent-according-to-mode)))) +(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) + (let ((point-at-bol (save-excursion (evil-first-non-blank) (point)))) + (if (= point-at-bol (point)) + (evil-move-beginning-of-line) + (evil-first-non-blank)))) + +(defun my.move-to-eol () + (interactive) + (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 (using `autopair-backspace') -if that's not possible." +whitespace as possible, or just one char if that's not possible." (interactive) - (if (or indent-tabs-mode - (= (point-at-bol) (point))) - (call-interactively 'backward-delete-char) - (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-untabify (- (match-end 1) (match-beginning 1))) - (call-interactively 'autopair-backspace)))))) + (cond ;; If in a string (workaround for smartparen bug) + ((sp-point-in-string) + (if (sp-point-in-empty-sexp) + (call-interactively 'sp-backward-delete-char) + (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 " "))))) -;; TODO Make inflate/deflate smarter (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 (insert " ") (save-excursion (insert " "))) + (progn (insert " ") + (save-excursion (insert " "))) (insert " "))) (defun my.deflate-space-maybe () @@ -57,33 +82,26 @@ space on either side of the point if so." spaces on either side of the point if so. Resorts to `my.backward-delete-whitespace-to-column' otherwise." (interactive) - (if (my/surrounded-p) - (progn (delete-char -1) (save-excursion (delete-char 1))) - (my.backward-delete-whitespace-to-column))) - -(defun my.dumb-indent () - "Inserts a tab character (or spaces x tab-width). Checks if the -auto-complete window is open." - (interactive) - (let ((indent-mode indent-tabs-mode)) - (insert (if indent-mode "\t" (make-string tab-width ? ))))) + (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) - (when (not (ac-menu-live-p)) - (let ((in-comment (evil-in-comment-p))) - (if in-comment - (indent-new-comment-line) - (progn (autopair-newline) (indent-according-to-mode)))))) - -(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))) + (cond ((in-string-p) + (evil-ret)) + ((evil-in-comment-p) + (indent-new-comment-line)) + (t + (evil-ret-and-indent)))) diff --git a/init/defuns/utility.el b/init/defuns/utility.el index 3e1ed2302..eb3125a24 100644 --- a/init/defuns/utility.el +++ b/init/defuns/utility.el @@ -4,3 +4,22 @@ (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 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/init-ac.el b/init/init-ac.el index 0afb4c6a7..6a156d483 100644 --- a/init/init-ac.el +++ b/init/init-ac.el @@ -1,9 +1,5 @@ (provide 'init-ac) -(defun ac-add-files() - "Set up filepath completion sources" - (setq ac-sources (append '(ac-source-filename ac-source-files-in-current-dir) ac-sources))) - ;; (use-package auto-complete :diminish auto-complete-mode @@ -11,37 +7,25 @@ (progn (require 'auto-complete-config) - (setq ac-auto-start nil) - (setq ac-auto-show-menu t ; Suggestions box must be invoked manually (see core-keymaps.el) + (setq ac-auto-start nil + ac-auto-show-menu t ; Suggestions box must be invoked manually (see core-keymaps.el) ac-use-menu-map t ; Enable ac-menu-map map when menu is open ac-use-quick-help nil ; Don't show tooltips unless invoked (see core-keymaps.el) ac-use-fuzzy nil ac-candidate-limit 25) + (setq ac-comphist-file (concat *tmp-dir "ac-comphist.dat")) (setq-default ac-sources '(ac-source-abbrev ac-source-dictionary ac-source-words-in-same-mode-buffers)) (add-hook 'emacs-lisp-mode-hook 'ac-emacs-lisp-mode-setup) (add-hook 'css-mode-hook 'ac-css-mode-setup) (add-hook 'shell-script-mode-hook 'ac-add-files) ;; (add-hook 'auto-complete-mode-hook 'ac-common-setup) - (global-auto-complete-mode t) - - ;; Fix line number flux bug - (ac-linum-workaround)) + (global-auto-complete-mode t)) :config (progn (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-modes 'nxml-mode) - (imap ac-mode-map (kbd "C-x C-f") 'ac-complete-filename) - (imap ac-mode-map (kbd "C-SPC") 'auto-complete) - ;; (imap ac-mode-map (kbd "C-S-SPC") 'auto-complete) - (define-key ac-completing-map (kbd "") 'ac-expand) - (define-key ac-completing-map (kbd "C-n") 'ac-next) - (define-key ac-completing-map (kbd "C-p") 'ac-previous) - (define-key ac-completing-map (kbd "") 'ac-quick-help) - (define-key ac-completing-map (kbd "ESC") 'ac-stop) - (define-key ac-completing-map (kbd "RET") 'ac-complete) - ;; Tell ido not to care about case (setq completion-ignore-case t))) diff --git a/init/init-cpp.el b/init/init-cpp.el index 04341c2c7..63fae8782 100644 --- a/init/init-cpp.el +++ b/init/init-cpp.el @@ -1,17 +1,31 @@ (provide 'init-cpp) -(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) -(add-hook 'c-mode-common-hook - (lambda() - (use-package auto-complete-clang) - (use-package auto-complete-c-headers) +(setq-default c-basic-offset 4 + c-default-style "linux" + c-tab-always-indent nil) - (setq ac-sources - '(ac-source-clang - ac-source-c-headers - ac-source-yasnippet - ac-source-words-in-same-mode-buffers - )))) +(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) +(add-hook! 'c-mode-common-hook + (use-package auto-complete-clang) + (use-package auto-complete-c-headers) + + (c-toggle-electric-state -1) + (c-toggle-auto-newline -1) + + (defmap c-mode-map (kbd "DEL") nil) + + (c-set-offset 'substatement-open '0) ; brackets should be at same indentation level as the statements they open + (c-set-offset 'inline-open '+) + (c-set-offset 'block-open '+) + (c-set-offset 'brace-list-open '+) ; all "opens" should be indented by the c-indent-level + (c-set-offset 'case-label '+) ; indent case labels by c-indent-level, too + + (setq ac-sources + '(ac-source-clang + ac-source-c-headers + ac-source-yasnippet + ac-source-words-in-same-mode-buffers + ))) (use-package glsl-mode :mode (("\\.glsl\\'" . glsl-mode) @@ -25,4 +39,4 @@ :lighter " C2D" :keymap (make-sparse-keymap)) -(associate-mode "[.-]c2d/" cocoa2d-mode t) +(associate-minor-mode "[.-]c2d/" cocoa2d-mode) diff --git a/init/init-dev.el b/init/init-dev.el index 2827fcd1f..d89836005 100644 --- a/init/init-dev.el +++ b/init/init-dev.el @@ -1,6 +1,5 @@ (provide 'init-dev) -;;; Tools (use-package dash-at-point :commands (dash-at-point dash-at-point-with-docset) :if is-mac @@ -21,11 +20,13 @@ (use-package go-mode :mode "\\.go\\'" :interpreter "go" - :init (require 'go-autocomplete)) + :init + (require 'go-autocomplete)) ;;; Config modes (use-package yaml-mode :defer t - :config (add-hook 'yaml-mode-hook 'enable-tab-width-2)) + :config + (add-hook 'yaml-mode-hook 'enable-tab-width-2)) (use-package json-mode :mode (("\\.json\\'" . json-mode) diff --git a/init/init-fly.el b/init/init-fly.el index c652fc332..fb36cbfdf 100644 --- a/init/init-fly.el +++ b/init/init-fly.el @@ -1,17 +1,19 @@ (provide 'init-fly) (use-package flycheck - :init (add-hook 'after-init-hook #'global-flycheck-mode) - :config - (progn - ;; Removed checks on idle/change for snappiness - (setq flycheck-check-syntax-automatically '(save new-line mode-enabled)) - (setq flycheck-indication-mode 'right-fringe) - (setq-default flycheck-disabled-checkers '(emacs-lisp emacs-lisp-checkdoc)))) + :config + (setq flycheck-indication-mode 'right-fringe + ;; Removed checks on idle/change for snappiness + flycheck-check-syntax-automatically + '(save new-line mode-enabled) + flycheck-disabled-checkers + '(emacs-lisp emacs-lisp-checkdoc)) + :idle + (add-hook 'after-init-hook #'global-flycheck-mode)) (use-package flyspell - :commands flyspell-mode - :diminish (flyspell-mode . " @") - :config - (setq ispell-program-name "aspell" - ispell-list-command "--list")) + :commands flyspell-mode + :diminish (flyspell-mode . " @") + :config + (setq ispell-program-name "aspell" + ispell-list-command "--list")) diff --git a/init/init-git.el b/init/init-git.el index 321fc9fa8..f6c81b26a 100644 --- a/init/init-git.el +++ b/init/init-git.el @@ -11,43 +11,17 @@ :mode ("/git-rebase-todo\\'" . git-rebase-mode)) (use-package gitconfig-mode - :mode (("/\\.gitconfig\\'" . gitconfig-mode) - ("/\\.git/config\\'" . gitconfig-mode) - ("/git/config\\'" . gitconfig-mode) + :mode (("/\\.?git/?config\\'" . gitconfig-mode) ("/\\.gitmodules\\'" . gitconfig-mode)) - :config (add-hook 'gitconfig-mode-hook 'flyspell-mode)) + :config + (add-hook 'gitconfig-mode-hook 'flyspell-mode)) (use-package gitignore-mode :mode (("/\\.gitignore\\'" . gitignore-mode) ("/\\.git/info/exclude\\'" . gitignore-mode) ("/git/ignore\\'" . gitignore-mode))) -(use-package git-gutter-fringe - :diminish git-gutter-mode - :disabled t +(use-package git-gutter+ + :diminish git-gutter+-mode :init - (progn - (global-git-gutter-mode t) - (add-hook 'git-gutter-mode-on-hook - (lambda() (fringe-mode '(4 . 8))))) - :config - (progn - (custom-set-variables '(git-gutter:lighter " !")) - (custom-set-variables '(git-gutter:verbosity 0)) - - (set-face-foreground 'git-gutter-fr:modified "#444444") - (set-face-background 'git-gutter-fr:modified "#444444") - (set-face-foreground 'git-gutter-fr:deleted "#884444") - (set-face-background 'git-gutter-fr:deleted "#884444") - (set-face-foreground 'git-gutter-fr:added "#448844") - (set-face-background 'git-gutter-fr:added "#448844") - )) - -(use-package git-gutter - :diminish git-gutter-mode - :init - (global-git-gutter-mode t) - :config - (progn - (custom-set-variables '(git-gutter:lighter " !")) - (custom-set-variables '(git-gutter:verbosity 0)))) + (global-git-gutter+-mode 1)) diff --git a/init/init-ido.el b/init/init-ido.el index 13c0daa36..38cf72064 100644 --- a/init/init-ido.el +++ b/init/init-ido.el @@ -2,17 +2,16 @@ ;; ido remaps its keys every time it's invoked, this screws with ;; custom mappings. So we've gotta neuter ido. -(defun ido-init-completion-maps ()) +;; (defun ido-init-completion-maps ()) +;; (setq ido-common-completion-map (make-sparse-keymap) +;; ido-file-dir-completion-map (make-sparse-keymap) +;; ido-file-completion-map (make-sparse-keymap) +;; ido-buffer-completion-map (make-sparse-keymap)) -(setq ido-common-completion-map (make-sparse-keymap)) -(setq ido-file-dir-completion-map (make-sparse-keymap)) -(setq ido-file-completion-map (make-sparse-keymap)) -(setq ido-buffer-completion-map (make-sparse-keymap)) - -(set-keymap-parent ido-common-completion-map minibuffer-local-map) -(set-keymap-parent ido-file-dir-completion-map ido-common-completion-map) -(set-keymap-parent ido-file-completion-map ido-file-dir-completion-map) -(set-keymap-parent ido-buffer-completion-map ido-common-completion-map) +;; (set-keymap-parent ido-common-completion-map minibuffer-local-map) +;; (set-keymap-parent ido-file-dir-completion-map ido-common-completion-map) +;; (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) diff --git a/init/init-love.el b/init/init-love.el index 8493c38c6..81495a271 100644 --- a/init/init-love.el +++ b/init/init-love.el @@ -1,10 +1,11 @@ (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" - :config - (run-code-with "lua" lua-mode-map) :init (progn (define-minor-mode love-mode @@ -14,12 +15,9 @@ :keymap (make-sparse-keymap) ; defines love-mode-map :group lua) - ;; (add-to-list 'auto-minor-mode-alist '("[.-]love/.+\\.lua\\'" . love-mode)) - (associate-mode "[.-]love/.+\\.lua\\'" love-mode t) - - (nmap love-mode-map (kbd "s-b") ",b") - (nmap love-mode-map (kbd ",b") - `(lambda() - (interactive) - (let ((root (if (projectile-project-p) (projectile-project-root) default-directory))) - (shell-command (concat "open -a love.app " (projectile-project-root)))))))) + (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-org.el b/init/init-org.el index 591461965..cf7304601 100644 --- a/init/init-org.el +++ b/init/init-org.el @@ -31,154 +31,82 @@ (point-max))) ;; -(use-package org - :init - (progn - (define-minor-mode evil-org-mode - "Buffer local minor mode for evil-org" - :init-value nil - :lighter " EvilOrg" - :keymap (make-sparse-keymap) ; defines evil-org-mode-map - :group 'evil-org) +(use-package org) - ;; Reset evil to ensure certain evil keybindings are prioritized - (add-hook 'org-mode-hook (lambda() (evil-mode nil) (evil-mode 1))) - (add-hook 'org-mode-hook 'evil-org-mode) - (add-hook 'org-mode-hook 'flyspell-mode) - (add-hook 'org-mode-hook 'enable-hard-wrap) +(define-minor-mode evil-org-mode + "Buffer local minor mode for evil-org" + :init-value nil + :lighter " EvilOrg" + :keymap (make-sparse-keymap) ; defines evil-org-mode-map + :group 'evil-org) - (shut-up (load-library "ox-opml")) +;; Reset evil to ensure certain evil keybindings are prioritized +(add-hook 'org-mode-hook 'evil-org-mode) +(add-hook 'org-mode-hook 'flyspell-mode) +(add-hook 'org-mode-hook 'enable-hard-wrap) +(add-hook! 'org-mode-hook (evil-mode nil) (evil-mode 1)) - ;; Formatting shortcuts - (vmap evil-org-mode-map - (kbd "s-b") "s*" ; bold - (kbd "s-i") "s/") ; italics - (imap evil-org-mode-map - (kbd "s-b") (λ (my/org-surround "*")) ; bold - (kbd "s-u") (λ (my/org-surround "_")) ; underline - (kbd "s-i") (λ (my/org-surround "/")) ; italics - (kbd "s-`") (λ (my/org-surround "+")) ; strikethrough +(shut-up (load-library "ox-opml")) - (kbd "") 'org-insert-heading-after-current) +(setq org-export-backends '(ascii html latex md opml)) +(add-hook 'find-file-hooks 'set-buffer-file-format-to-opml) +(add-to-list 'auto-mode-alist '("\\.opml$" . org-mode)) +(add-to-list 'format-alist '(opml "Outline Processor Markup Language" + "<[?]xml version=\"1.0\"[^>]*[?]>[\n]?.*[\n]?.*[\n]?" + "~/.emacs.d/elisp/org-opml/opml2org.py" opml-encode t)) - (nvmap evil-org-mode-map - ",l" 'org-insert-link) +(setq org-directory "~/Dropbox/notes" + org-default-notes-file "~/Dropbox/notes/notes.org" + org-mobile-inbox-for-pull "~/Dropbox/notes/notes.org" + org-mobile-directory "~/Dropbox/Apps/MobileOrg" + org-agenda-files '("~/Dropbox/notes") + org-src-tab-acts-natively t) - (nmap evil-org-mode-map - ",d" 'org-time-stamp - ",D" 'org-time-stamp-inactive - ",s" 'org-schedule - ",a" 'org-attach - ",A" 'org-attach-open - ",t" 'org-todo - ",T" 'org-show-todo-tree - ",/" 'org-match-sparse-tree - ",?" 'org-tags-view - ",+" 'org-align-all-tags - ",r" 'org-refile - "gh" 'outline-up-heading - "gj" 'org-forward-heading-same-level - "gk" 'org-backward-heading-same-level - "gl" 'outline-next-visible-heading - "go" 'org-open-at-point - "ga" 'org-agenda - "H" 'org-beginning-of-line - "L" 'org-end-of-line - "$" 'org-end-of-line - "^" 'org-beginning-of-line - "<" 'org-metaleft - ">" 'org-metaright - "-" 'org-cycle-list-bullet - (kbd ", SPC") 'org-archive-subtree - (kbd "") (λ (org-insert-heading-after-current) (evil-insert-state)) - (kbd "RET") (λ (org-todo 'done)) - (kbd "TAB") 'org-cycle) +(setq org-completion-use-ido t + org-hide-leading-stars t + org-todo-keywords + '((sequence "TODO(t)" "|" "DONE(d)") + (sequence "STARTED(s)" "VERIFY(v)" "WAITING(w)") + (sequence "|" "CANCELLED(c)"))) - ;; normal & insert state shortcuts. - (mapc (lambda (state) - (evil-define-key state evil-org-mode-map - (kbd "M--") 'my/org-insert-list-item - (kbd "M-l") 'org-metaright - (kbd "M-h") 'org-metaleft - (kbd "M-k") 'org-metaup - (kbd "M-j") 'org-metadown - (kbd "M-L") 'org-shiftmetaright - (kbd "M-H") 'org-shiftmetaleft - (kbd "M-K") 'org-shiftmetaup - (kbd "M-J") 'org-shiftmetadown - (kbd "") '(lambda () (interactive) - (my/org-eol-call - '(lambda() - (org-insert-heading) - (org-metaright)))) - (kbd "M-t") '(lambda () (interactive) - (my/org-eol-call - '(lambda() - (org-insert-todo-heading nil) - (org-metaright)))) - )) - '(normal insert)) +(org-babel-do-load-languages 'org-babel-load-languages + '((python . t) + (ruby . t) + (sh . t) + (matlab . t) + (latex . t))) - (setq org-export-backends '(ascii html latex md opml)) - (add-hook 'find-file-hooks 'set-buffer-file-format-to-opml) - (add-to-list 'auto-mode-alist '("\\.opml$" . org-mode)) - (add-to-list 'format-alist '(opml "Outline Processor Markup Language" - "<[?]xml version=\"1.0\"[^>]*[?]>[\n]?.*[\n]?.*[\n]?" - "~/.emacs.d/elisp/org-opml/opml2org.py" opml-encode t)) +(setq org-tag-alist '(("@work" . ?b) + ("@home" . ?h) + ("@writing" . ?w) + ("@errands" . ?e) + ("@drawing" . ?d) + ("@coding" . ?c) + ("@phone" . ?p) + ("@reading" . ?r) + ("projects" . ?q) + ("easy" . ?0) + ("hard" . ?1))) - (setq org-directory "~/Dropbox/notes" - org-default-notes-file "~/Dropbox/notes/notes.org" - org-mobile-inbox-for-pull "~/Dropbox/notes/notes.org" - org-mobile-directory "~/Dropbox/Apps/MobileOrg" - org-agenda-files '("~/Dropbox/notes") - org-src-tab-acts-natively t) +(setq org-capture-templates + '(("t" "TODO" entry (file+headline "~/Dropbox/notes/gtd.org" "Inbox") "* TODO %? %u\n%i") + ("T" "TODO Someday" entry (file+headline "~/Dropbox/notes/gtd.org" "Someday") "* TODO %? %u :someday:\n%i") + ("c" "Changelog" entry (file+headline (concat (projectile-project-root) "/CHANGELOG.org") "Unsorted") "** %u %? :unsorted:\n%i" :prepend t) + ("i" "Invoice" entry (file+headline "~/Dropbox/notes/invoices.org" "Invoices") "** TODO %?\n%i" :prepend t) + ("n" "Note" entry (file+datetree org-default-notes-file) "** %?\n%i") + ("b" "Blog" entry (file+datetree "~/Dropbox/notes/blog.org") "** %i%?") + ("j" "Journal" entry (file+datetree "~/Dropbox/notes/journal.org") "** %?%^g\nAdded: %U\n%i") + ("a" "Trivia" entry (file "~/Dropbox/notes/trivia.org") "* %u %?\n%i" :prepend t) + ("s" "Writing Scraps" entry (file "~/Dropbox/notes/writing.org") "* %u %?\n%i" :prepend t) + ("v" "Vocab" entry (file "~/Dropbox/notes/vocab.org") "* %u %?\n%i" :prepend t) + ("e" "Excerpt" entry (file "~/Dropbox/notes/excerpts.org") "* %u %?\n%i" :prepend t))) - (setq org-completion-use-ido t - org-hide-leading-stars t - org-todo-keywords - '((sequence "TODO(t)" "|" "DONE(d)") - (sequence "STARTED(s)" "VERIFY(v)" "WAITING(w)") - (sequence "|" "CANCELLED(c)"))) - - (org-babel-do-load-languages 'org-babel-load-languages - '((python . t) - (ruby . t) - (sh . t) - (matlab . t) - (latex . t))) - - (setq org-tag-alist '(("@work" . ?b) - ("@home" . ?h) - ("@writing" . ?w) - ("@errands" . ?e) - ("@drawing" . ?d) - ("@coding" . ?c) - ("@phone" . ?p) - ("@reading" . ?r) - ("projects" . ?q) - ("easy" . ?0) - ("hard" . ?1))) - - (setq org-capture-templates - '(("t" "TODO" entry (file+headline "~/Dropbox/notes/gtd.org" "Inbox") "* TODO %? %u\n%i") - ("T" "TODO Someday" entry (file+headline "~/Dropbox/notes/gtd.org" "Someday") "* TODO %? %u :someday:\n%i") - ("c" "Changelog" entry (file+headline (concat (projectile-project-root) "/CHANGELOG.org") "Unsorted") "** %u %? :unsorted:\n%i" :prepend t) - ("i" "Invoice" entry (file+headline "~/Dropbox/notes/invoices.org" "Invoices") "** TODO %?\n%i" :prepend t) - ("n" "Note" entry (file+datetree org-default-notes-file) "** %?\n%i") - ("b" "Blog" entry (file+datetree "~/Dropbox/notes/blog.org") "** %i%?") - ("j" "Journal" entry (file+datetree "~/Dropbox/notes/journal.org") "** %?%^g\nAdded: %U\n%i") - ("a" "Trivia" entry (file "~/Dropbox/notes/trivia.org") "* %u %?\n%i" :prepend t) - ("s" "Writing Scraps" entry (file "~/Dropbox/notes/writing.org") "* %u %?\n%i" :prepend t) - ("v" "Vocab" entry (file "~/Dropbox/notes/vocab.org") "* %u %?\n%i" :prepend t) - ("e" "Excerpt" entry (file "~/Dropbox/notes/excerpts.org") "* %u %?\n%i" :prepend t))) - - (setq org-agenda-custom-commands - '(("x" agenda) - ("y" agenda*) - ("w" todo "WAITING") - ("W" todo-tree "WAITING") - ("to" todo) - ("tp" tags "+Projects") - ("tg" tags-todo "+gamedev") - ("tw" tags-tree "+webdev"))) - )) +(setq org-agenda-custom-commands + '(("x" agenda) + ("y" agenda*) + ("w" todo "WAITING") + ("W" todo-tree "WAITING") + ("to" todo) + ("tp" tags "+Projects") + ("tg" tags-todo "+gamedev") + ("tw" tags-tree "+webdev"))) diff --git a/init/init-project.el b/init/init-project.el index 0d627ed47..430ebcb9b 100644 --- a/init/init-project.el +++ b/init/init-project.el @@ -1,14 +1,16 @@ (provide 'init-project) -(add-hook 'dired-load-hook - (lambda() - (use-package dired+ :config - (setq dired-recursive-deletes 'always - dired-recursive-copies 'always +(add-hook! 'dired-load-hook + (use-package dired+) + (setq dired-recursive-deletes 'always + dired-recursive-copies 'always - ;; if there is a dired buffer displayed in the next window, use its - ;; current subdir, instead of the current subdir of this dired buffer - dired-dwim-target t)))) + ;; if there is a dired buffer displayed in the next window, use its + ;; current subdir, instead of the current subdir of this dired buffer + dired-dwim-target t)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (use-package helm :defer t) (use-package grizzl :defer t) @@ -22,14 +24,13 @@ :config (progn (projectile-global-mode) (setq projectile-completion-system 'grizzl - projectile-enable-caching t))) + projectile-enable-caching t + projectile-cache-file (concat *tmp-dir "projectile.cache") + projectile-known-projects-file (concat *tmp-dir "projectile-bookmarks.eld")))) (use-package ag :commands (ag ag-search ag-regexp) :config - (progn - (setq ag-reuse-window t) - (setq ag-reuse-buffers t) - (setq ag-highlight-search t) - (define-key ag-mode-map [escape] 'ag-kill-buffers) - (define-key ag-mode-map "h" nil))) + (setq ag-reuse-window t + ag-reuse-buffers t + ag-highlight-search t)) diff --git a/init/init-python.el b/init/init-python.el index fa72660fb..0f8b60ce8 100644 --- a/init/init-python.el +++ b/init/init-python.el @@ -3,47 +3,31 @@ (use-package python :mode ("\\.py\\'" . python-mode) :interpreter ("python" . python-mode) + :init + (setq python-indent-offset 4) :config (progn - (use-package pyenv - :init - (progn - (setq pyenv-show-active-python-in-modeline nil) + (use-package jedi) - (global-pyenv-mode) - (add-hook 'python-mode-hook 'pyenv-use-corresponding))) + (unless (file-directory-p "~/.emacs.d/.python-environments/default/") + (jedi:install-server)) - (use-package jedi - :init - (if (not (file-directory-p "~/.emacs.d/.python-environments/default/")) - (jedi:install-server)) - (add-hook 'python-mode-hook 'jedi:ac-setup)) + (add-hook 'python-mode-hook 'jedi:ac-setup) + (setq python-shell-interpreter "ipython") - ;; Let autopair work with triple-quotes - (setq autopair-handle-action-fns - (list #'autopair-default-handle-action - #'autopair-python-triple-quote-action)) + ;; Dont' remap DEL please... + (defmap python-mode-map (kbd "DEL") nil) ;;; Keybindings - (run-code-with "python" python-mode-map) - ;; (nmap python-mode-map (kbd ",r") 'python-shell-send-buffer) - ;; (vmap python-mode-map (kbd ",r") 'python-shell-send-region) + (add-hook! 'python-mode-hook + (setq my-switch-to-repl-func 'python-shell-switch-to-shell + my-send-region-to-repl-func 'python-shell-send-region + my-run-code-interpreter "python")) - ;; Don't remap backspace. Leave it to autopair, please. - (define-key python-mode-map [backspace] nil) - - (use-package nose :commands (nose-mode) - :config - (setq nose-mode-map (make-sparse-keymap)) - (nmap nose-mode-map - ",tr" 'nosetests-again - ",ta" 'nosetests-all - ",ts" 'nosetests-one - ",tv" 'nosetests-module - ",tA" 'nosetests-pdb-all - ",tO" 'nosetests-pdb-one - ",tV" 'nosetests-pdb-module) + (use-package nose + :commands (nose-mode) :init - (associate-mode "/test_.+\\.py\\'" nose-mode) - ;; (add-to-list 'auto-minor-mode-alist '("/test_.+\\.py\\'" . nose-mode))) - ))) + (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))))) diff --git a/init/init-ruby.el b/init/init-ruby.el index d696318db..f5c4f791c 100644 --- a/init/init-ruby.el +++ b/init/init-ruby.el @@ -23,69 +23,47 @@ :interpreter "ruby" :config (progn - ;;; Ruby tools - (use-package rbenv - :init - (progn - (setq rbenv-show-active-ruby-in-modeline nil) - - (global-rbenv-mode) - (add-hook 'ruby-mode-hook 'rbenv-use-corresponding))) - (use-package inf-ruby :config - (evil-set-initial-state 'inf-ruby-mode 'insert) + (progn + (evil-set-initial-state 'inf-ruby-mode 'insert) + (use-package ac-inf-ruby) + (add-hook 'inf-ruby-mode-hook 'ac-inf-ruby-enable)) :init (add-to-list 'ac-modes 'inf-ruby-mode)) (use-package rspec-mode :defer t - :config - (progn - (nmap rspec-mode-verifiable-keymap - ",tr" 'rspec-rerun - ",ta" 'rspec-verify-all - ",ts" 'rspec-verify-single - ",tv" 'rspec-verify) - - (nmap rspec-dired-mode-keymap - ",tv" 'rspec-dired-verify - ",ts" 'rspec-dired-verify-single - ",ta" 'rspec-verify-all - ",tr" 'rspec-rerun)) + :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") + )) :init - (associate-mode "_spec\\.rb\\'" rspec-mode t)) + (associate-minor-mode "_spec\\.rb\\'" rspec-mode)) ;;; Auto-completion ;; Remember to install rsense w/ homebrew! (enable-ruby-rsense) - (use-package ac-inf-ruby - :init - (add-hook 'inf-ruby-mode-hook 'ac-inf-ruby-enable)) + + (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")) ;;; Formatting (setq ruby-indent-level 2) - (setq ruby-deep-indent-paren nil) - (add-hook 'ruby-mode-hook 'enable-tab-width-2) - (require 'ruby-mode-indent-fix) + (setq ruby-deep-indent-paren t) + (add-hook 'ruby-mode-hook 'enable-tab-width-2))) - (setq evilmi-ruby-match-tags - '((("unless" "if") ("elsif" "else") ("end")) - ("begin" ("rescue" "ensure") "end") - ("case" ("when" "else") ("end")) - (("task" "namespace" "class" "def" "while" "do" "module" "for" "until") () ("end")) - )) - - ;; (evil-define-text-object ruby-mode-string-interp-inner (count &optional beg end type) - ;; "Select a string hash block in a string: #{|...|}" - ;; (evil-regexp-range count beg end type "#{" "}" t)) - ;; (evil-define-text-object ruby-mode-string-interp-outer (count &optional beg end type) - ;; "Select a string hash block in a string, including the delimiters: |#{...}|" - ;; (evil-regexp-range count beg end type "[#$]{" "}")) - ;; (evil-define-key 'motion ruby-mode-map "") - - ;;; Keybindings - (nmap ruby-mode-map "gd" 'rsense-jump-to-definition) - - (run-code-with "ruby" ruby-mode-map) - )) +(add-hook! 'find-file-hook + (let ((rake-path + (f--traverse-upwards (f--exists? "Rakefile" it)))) + (when rake-path + (use-package rake-mode) + (rake-mode t) + (rake-mode/visit-rakefile (expand-file-name "Rakefile" rake-path) t)))) diff --git a/init/init-shell.el b/init/init-shell.el deleted file mode 100644 index 2de6627b2..000000000 --- a/init/init-shell.el +++ /dev/null @@ -1,24 +0,0 @@ -(provide 'init-shell) - -(setq shell-file-name "zsh") -(setq comint-process-echoes t) -(setq comint-prompt-regexp "^$ ") -(setq comint-input-ignoredups t) -(setq comint-completion-addsuffix t) -(setq comint-prompt-read-only t) -(setq comint-get-old-input (lambda () "")) - -;; Setup auto-complete-esque path completion -(add-to-list 'ac-modes 'shell-mode) -(add-hook 'shell-mode-hook (lambda () - (linum-mode 0) - (yas-minor-mode -1) - (enable-path-completion) - - ;; I want ac to silently offer completion, but leave - ;; the actual tab-work to the underlying shell (ZSH is - ;; powerful enough!) - (local-unset-key [tab]) - - (evil-define-key 'normal shell-mode-map "j" nil) - (evil-define-key 'normal shell-mode-map "k" nil))) diff --git a/init/init-snippets.el b/init/init-snippets.el index 2669f1866..5ec5e13f6 100644 --- a/init/init-snippets.el +++ b/init/init-snippets.el @@ -3,22 +3,32 @@ (use-package yasnippet :diminish (yas-minor-mode . " $") :mode (("emacs.+/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))) - (imap map [(tab)] 'yas-expand) - (imap map (kbd "TAB") 'yas-expand) - map))) + :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))) + (imap map [(tab)] 'yas-expand) + (imap map (kbd "TAB") 'yas-expand) + 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)) - (define-key yas-keymap (kbd "DEL") 'my/yas-clear-field) + (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)))) + + (defmap yas-keymap (kbd "DEL") 'my/yas-clear-field) (yas-reload-all)) :init @@ -28,6 +38,7 @@ (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 diff --git a/init/init-text.el b/init/init-text.el index 08e6a41e3..2f3c99118 100644 --- a/init/init-text.el +++ b/init/init-text.el @@ -3,45 +3,24 @@ (use-package markdown-mode :mode (("\\.md\\'" . markdown-mode) ("/README\\'" . markdown-mode)) - :config + :pre-load (progn - (let ((map markdown-mode-map)) - (define-key map (kbd "") nil) - (define-key map (kbd "") nil) - (define-key map (kbd "") nil) - - (nvmap map - (kbd ",i") 'markdown-insert-image - (kbd ",l") 'markdown-insert-link - (kbd ",L") 'markdown-insert-reference-link-dwim) - - (imap map (kbd "M--") 'markdown-insert-hr) - - (nmap map - "[p" 'markdown-promote - "]p" 'markdown-demote) - - (define-key map (kbd "s-*") 'markdown-insert-list-item) - (define-key map (kbd "s-b") 'markdown-insert-bold) - (define-key map (kbd "s-i") 'markdown-insert-italic) - (define-key map (kbd "s-`") 'markdown-insert-del)))) - -(defvar markdown-regex-del "\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)") -(defun markdown-insert-del () - "Insert markup to make a region or word bold. -If there is an active region, make the region bold. If the point -is at a non-bold word, make the word bold. If the point is at a -bold word or phrase, remove the bold markup. Otherwise, simply -insert bold delimiters and place the cursor in between them." - (interactive) - (let ((delim "~~")) - (if (markdown-use-region-p) - ;; Active region - (let ((bounds (markdown-unwrap-things-in-region - (region-beginning) (region-end) - markdown-regex-del 2 4))) - (markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds))) - ;; Bold markup removal, bold word at point, or empty markup insertion - (if (thing-at-point-looking-at markdown-regex-del) - (markdown-unwrap-thing-at-point nil 2 4) - (markdown-wrap-or-insert delim delim 'word nil nil))))) + (defvar markdown-regex-del "\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)") + (defun markdown-insert-del () + "Insert markup to make a region or word bold. + If there is an active region, make the region bold. If the point + is at a non-bold word, make the word bold. If the point is at a + bold word or phrase, remove the bold markup. Otherwise, simply + insert bold delimiters and place the cursor in between them." + (interactive) + (let ((delim "~~")) + (if (markdown-use-region-p) + ;; Active region + (let ((bounds (markdown-unwrap-things-in-region + (region-beginning) (region-end) + markdown-regex-del 2 4))) + (markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds))) + ;; Bold markup removal, bold word at point, or empty markup insertion + (if (thing-at-point-looking-at markdown-regex-del) + (markdown-unwrap-thing-at-point nil 2 4) + (markdown-wrap-or-insert delim delim 'word nil nil))))))) diff --git a/init/init-webdev.el b/init/init-webdev.el index 50128c459..d0d3e3368 100644 --- a/init/init-webdev.el +++ b/init/init-webdev.el @@ -2,7 +2,8 @@ (use-package rainbow-mode :defer t - :init (add-hook 'scss-mode 'rainbow-mode)) + :init + (add-hook 'scss-mode 'rainbow-mode)) (use-package scss-mode :mode "\\.scss\\'" @@ -36,35 +37,14 @@ (setq web-mode-ac-sources-alist '(("css" . (ac-source-css-property)))) - (setq web-mode-markup-indent-offset 2 - web-mode-code-indent-offset 2 - web-mode-css-indent-offset 2 - web-mode-style-padding 2 - web-mode-script-padding 2 - web-mode-block-padding 2) - ;; (setq web-mode-tag-auto-close-style 0) - ;; (setq web-mode-enable-auto-opening t) - ;; (setq web-mode-indent-style 1) + (setq web-mode-markup-indent-offset 2 + web-mode-code-indent-offset 2 + web-mode-css-indent-offset 2 + web-mode-style-padding 2 + web-mode-script-padding 2 + web-mode-block-padding 2) - (nvmap web-mode-map - "]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) - - (nmap web-mode-map - "zf" 'web-mode-fold-or-unfold - ",ct" 'web-mode-element-rename) - - (define-key web-mode-map (kbd "s-/") 'web-mode-comment-or-uncomment) - - (add-hook 'web-mode-hook - (lambda() - (setq indent-tabs-mode t) - (setq tab-always-indent t))) - (add-hook 'web-mode-hook 'enable-tab-width-2) - )) + (add-hook 'web-mode-hook 'enable-tab-width-2))) (use-package php-mode :mode (("\\.php\\'" . php-mode) @@ -72,7 +52,7 @@ :interpreter "php" :config (progn - (run-code-with "php" php-mode-map) + (add-hook! 'php-mode-hook (setq my-run-code-interpreter "php")) (setq php-template-compatibility nil))) ;;; Javascript @@ -80,22 +60,18 @@ :commands tern-mode :config (progn - (run-code-with "node" js-mode-map) (use-package tern-auto-complete :config (setq tern-ac-on-dot nil))) :init ;; replace auto-complete with tern-ac-complete only in js-mode - (add-hook 'js-mode-hook - (lambda () - (tern-mode t) - (tern-ac-setup) - (imap js-mode-map [remap auto-complete] 'tern-ac-complete) - ))) + (add-hook! 'js-mode-hook + (tern-mode t) + (tern-ac-setup) + (setq my-run-code-interpreter "node"))) ;; Jekyll support (define-minor-mode jekyll-mode :init-value nil - :lighter " :{" - :keymap (make-sparse-keymap)) + :lighter " :{") -(associate-mode "[.-]jekyll/" jekyll-mode t) +(associate-minor-mode "[.-]jekyll/" jekyll-mode) diff --git a/init/my-commands.el b/init/my-commands.el new file mode 100644 index 000000000..4098b2dee --- /dev/null +++ b/init/my-commands.el @@ -0,0 +1,246 @@ +(provide 'my-commands) + +;;;; Defun Commands ;;;;;;;;;;;;;;;;;;;; +(defun my:git-gutter-refresh () + (interactive) + (git-gutter+-refresh)) + +(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))) + +;; File navigation defuns +(defun my:goto-symbol (&optional symbol-list) + "Refresh imenu and jump to a place in the buffer using Ido." + (interactive) + (unless (featurep 'imenu) + (require 'imenu nil t)) + (cond + ((not symbol-list) + (let ((ido-mode ido-mode) + (ido-enable-flex-matching + (if (boundp 'ido-enable-flex-matching) + ido-enable-flex-matching t)) + name-and-pos symbol-names position) + (unless ido-mode + (ido-mode 1) + (setq ido-enable-flex-matching t)) + (while (progn + (imenu--cleanup) + (setq imenu--index-alist nil) + (my:goto-symbol (imenu--make-index-alist)) + (setq selected-symbol + (ido-completing-read "Symbol? " symbol-names)) + (string= (car imenu--rescan-item) selected-symbol))) + (unless (and (boundp 'mark-active) mark-active) + (push-mark nil t nil)) + (setq position (cdr (assoc selected-symbol name-and-pos))) + (cond + ((overlayp position) + (goto-char (overlay-start position))) + (t + (goto-char position))))) + ((listp symbol-list) + (dolist (symbol symbol-list) + (let (name position) + (cond + ((and (listp symbol) (imenu--subalist-p symbol)) + (my:goto-symbol symbol)) + ((listp symbol) + (setq name (car symbol)) + (setq position (cdr symbol))) + ((stringp symbol) + (setq name symbol) + (setq position + (get-text-property 1 'org-imenu-marker symbol)))) + (unless (or (null position) (null name) + (string= (car imenu--rescan-item) name)) + (add-to-list 'symbol-names name) + (add-to-list 'name-and-pos (cons name position)))))))) + +;; Buffer defuns +(defun my:kill-dired-buffers () + (interactive) + (mapc (lambda (buffer) + (when (eq 'dired-mode (buffer-local-value 'major-mode buffer)) + (kill-buffer buffer))) + (buffer-list))) + +;;;; 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"))) + (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 my:ex:msg-buffer () :repeat nil + (interactive) + (view-echo-area-messages) + (switch-to-buffer-other-window "*Messages*") + ;; Force text-mode for unfettered evil-mode & my keymappings + (text-mode)) + +(evil-define-command my:ex:kill-buffers (&optional bang) :repeat nil + (interactive "") + (let ((buffers (if bang + (cdr (buffer-list (current-buffer))) + (buffer-list)))) + (delete-other-windows) + (mapc 'kill-buffer buffers))) + +(evil-define-command my: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 my:ex:notes () :repeat nil + (interactive) + (ido-find-file-in-dir org-directory)) + +(evil-define-command my:ex:snippets (&optional bang) :repeat nil + (interactive "") + (if bang + (yas-new-snippet) + (yas-visit-snippet-file))) + +;; Projects +(evil-define-command my:ex:ag-search (search &optional bang) :repeat nil + (interactive "") + (let ((root (my/project-root bang))) + (ag search root))) + +(evil-define-command my:ex:ag-regex-search (search &optional bang) :repeat nil + (interactive "") + (let ((root (my/project-root bang))) + (ag-regexp search root))) + +;; Run a command. If , then only type command into tmux +(evil-define-command my: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 my: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))))) + (my:ex:tmux-run (format "cd %s" dir)) + (when (evil-ex-p) + (message "[Tmux] cd %s" dir)))) + +(evil-define-command my:ex:byte-compile-all (&optional bang) :repeat nil + (interactive "") + (byte-recompile-file (expand-file-name "init.el" *dir) bang 0) + (byte-recompile-directory *init-dir 0 bang) + (byte-recompile-directory *elisp-dir 0 bang)) + +(evil-define-command my:ex:mru () :repeat nil + "Find a recent file using ido." + (interactive) + (let ((file (ido-completing-read "Choose recent file: " recentf-list nil t))) + (when file (find-file file)))) + +(evil-define-command my:ex:build (arguments &optional bang) :repeat nil + (interactive "") + (my:build arguments)) + +(evil-define-command my:ex:cd (dir) :repeat nil + (interactive "") + (cd (if (zerop (length dir)) "~" dir))) + +;;; +(evil-define-operator my:ex:scratch-buffer (beg end) + :motion nil + :move-point nil + :type inclusive + :repeat nil + (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 my:ex:org-capture (beg end) + :motion nil + :move-point nil + :type inclusive + :repeat nil + (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 my: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 my:ex:run-code (beg end) :repeat nil + :motion nil + :move-point nil + :type exclusive + :repeat nil + (interactive "") + (cond ((and beg end) + (my:run-code-region beg end)) + (t + (my:run-code-buffer)))) + +(evil-define-operator my:ex:send-region-to-repl (beg end &optional bang) :repeat nil + :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/my-defuns.el b/init/my-defuns.el index fa3dd71b7..d13577b51 100644 --- a/init/my-defuns.el +++ b/init/my-defuns.el @@ -1,10 +1,8 @@ (provide 'my-defuns) -(add-to-list 'load-path (expand-file-name "defuns" *init-dir)) - (shut-up + (load "defuns/utility") (load "defuns/config") - (load "defuns/commands") (load "defuns/text") (load "defuns/hooks") - (load "defuns/utility")) + (load "defuns/coderunner")) diff --git a/init/my-keymaps.el b/init/my-keymaps.el index 0e28ef9df..0e26c73de 100644 --- a/init/my-keymaps.el +++ b/init/my-keymaps.el @@ -4,24 +4,13 @@ ;; Global keymaps ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(global-set-key (kbd "C-c C-p") 'package-list-packages) -(global-set-key (kbd "M-x") 'smex) -(global-set-key (kbd "M-X") 'smex-major-mode-commands) +(global-set-key (kbd "M-x") 'smex) +(global-set-key (kbd "M-X") 'smex-major-mode-commands) +(global-set-key (kbd "C-;") 'eval-expression) +(global-set-key (kbd "C-j") "5j") +(global-set-key (kbd "C-k") "5k") (when is-mac - ;; TODO: Open in tmux - (nmap my-mode-map - (kbd "C-c o") 'send-dir-to-finder - (kbd "C-c u") 'send-to-transmit - (kbd "C-c l") 'send-to-launchbar - (kbd "C-c L") 'send-dir-to-launchbar - (kbd "C-c t") 'my:tmux-chdir - (kbd "C-c T") (λ (my:tmux-chdir (projectile-project-root)))) - - ;; Evaluating elisp - (nmap my-mode-map (kbd "C-c x") 'eval-buffer) - (vmap my-mode-map (kbd "C-c x") 'eval-region) - (when window-system (global-set-key (kbd "s-=") 'text-scale-increase) (global-set-key (kbd "s--") 'text-scale-decrease) @@ -29,47 +18,22 @@ (global-set-key (kbd "s-/") 'evilnc-comment-or-uncomment-lines) (global-set-key (kbd "s-") 'toggle-frame-fullscreen) - (global-set-key (kbd "C-;") 'eval-expression) - (global-set-key (kbd "s-;") 'my:tmux-run) - (global-set-key (kbd "s-:") 'my:tmux-paste) - ;; Faster scrolling (mapc (lambda(map) - (evil-define-key map my-mode-map (kbd "s-j") "5j") - (evil-define-key map my-mode-map (kbd "s-k") "5k")) + (evil-define-key map my-mode-map (kbd "s-j") (kbd "C-j")) + (evil-define-key map my-mode-map (kbd "s-k") (kbd "C-k"))) '(emacs normal visual)) - (nmap my-mode-map - ;; Leader alternatives - (kbd "s-t") 'projectile-find-file - (kbd "s-F") 'projectile-ag - (kbd "s-p") 'projectile-switch-project - (kbd "s-m") 'my:ex:mru - (kbd "s-M") 'projectile-recentf - (kbd "s-o") 'ido-find-file - (kbd "s-d") 'dash-at-point - - (kbd "s-'") 'mc/mark-next-like-this - (kbd "s-\"") 'mc/mark-previous-like-this - (kbd "C-s-'") 'mc/mark-all-like-this) - - (imap my-mode-map - ;; Textmate-esque insert-line before/after - (kbd "") 'evil-open-below - (kbd "") 'evil-open-above - - ;; Fix OSX text navigation shortcuts - (kbd "") 'evil-first-non-blank - (kbd "") 'move-end-of-line - (kbd "") 'my.backward-kill-to-bol-and-indent - - ;; Fixes delete - (kbd "") 'delete-char) - - (imap emmet-mode-keymap - (kbd "s-e") 'emmet-expand-yas - (kbd "s-E") 'emmet-expand-line))) + (nmap! (kbd "s-t") 'projectile-find-file + (kbd "s-p") 'projectile-switch-project + (kbd "s-m") 'my:ex:mru + (kbd "s-M") 'projectile-recentf + (kbd "s-o") 'ido-find-file + (kbd "s-d") 'dash-at-point + (kbd "s-b") 'my:ex:build) + (nvmap! (kbd "s-r") ",r" + (kbd "s-R") ",R"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Local keymaps ;; @@ -77,110 +41,117 @@ ;; Remap ; to : - SPC and shift-SPC replace ; and , - have to use ;; define-key instead of n/vmap for this one to register. -(define-key evil-normal-state-map ";" 'evil-ex) -(define-key evil-visual-state-map ";" 'evil-ex) +(-nvmap ";" 'evil-ex) +(-nvmap "X" 'evil-exchange) -(nvmap my-mode-map - "gc" 'evil-ace-jump-char-mode - "gw" 'evil-ace-jump-word-mode ; overwrites evil-fill - "gl" 'evil-ace-jump-line-mode) +;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;; +(nmap! ",r" 'my:run-code-buffer + ",R" 'my:switch-to-repl + ",b" 'my:build + ",a" 'projectile-find-other-file + ",e" 'ido-find-file + ",E" 'my:ex:init-files + ",m" 'my:ex:mru ; recent GLOBAL files + ",M" 'projectile-recentf ; recent PROJECT files + ",p" 'projectile-switch-project + ",g" 'git-gutter+-show-hunk + ",;" 'helm-imenu + ",:" 'my:goto-symbol + ",," 'ido-switch-buffer + ",." 'projectile-find-file) -(nmap my-mode-map - ;; Leader maps - ",'" 'mc/mark-next-like-this - ",\"" 'mc/mark-all-like-this +(vmap! ",r" 'my:run-code-region + ",R" 'my:send-region-to-repl) - ",e" 'ido-find-file - ",E" 'my:ex:init-files - ",m" 'my:ex:mru ; recent GLOBAL files - ",M" 'projectile-recentf ; recent PROJECT files - ",p" 'projectile-switch-project - ",\\" 'neotree-show - ",|" 'neotree-hide - ",;" 'helm-imenu - ",:" 'my:ido-goto-symbol - ",," 'ido-switch-buffer - ",." 'projectile-find-file - ",=" 'align-regexp +(nvmap! ",x" 'my:ex:scratch-buffer + ",X" 'my:ex:org-capture + ",=" 'align-regexp) - ;; Moving rows rather than lines (in case of wrapping) - "j" 'evil-next-visual-line - "k" 'evil-previous-visual-line +;;;; ;;;;;;;;;;;;;;;;;;;;; +(-nmap "\\" 'evil-execute-in-god-state) +(gmap! ":" 'linum-mode + "\\" 'neotree-show + "|" 'neotree-hide - "X" 'evil-destroy ; Delete without yanking + "oo" 'my:send-dir-to-finder + "ou" 'my:send-to-transmit + "ol" 'my:send-to-launchbar + "oL" 'my:send-dir-to-launchbar - ;; behave like D and C; yank to end of line - "Y" (λ (evil-yank (point) (point-at-eol))) + ;; tmux: cd (default-directory) + "ot" (λ (my:ex:tmux-chdir nil t)) + ;; tmux: cd [project root] + "oT" 'my:ex:tmux-chdir) - "zz" 'kill-this-buffer ; Close buffer - "]b" 'next-buffer - "[b" 'previous-buffer - "]e" 'next-error - "[e" 'previous-error - "]h" 'git-gutter:next-hunk - "[h" 'git-gutter:previous-hunk +;;;; Keybindings ;;;;;;;;;;;;;;;;;;;;;;; +(nvmap! "gc" 'evil-ace-jump-char-mode + "gw" 'evil-ace-jump-word-mode ; overwrites evil-fill + "gl" 'evil-ace-jump-line-mode - ;; For quickly capturing notes and todos - (kbd ", RET") 'org-capture + "]\\" 'er/expand-region + "[\\" 'er/contract-region - ;; winner-mode: window layout undo/redo (see init-core.el) - (kbd "C-w u") 'winner-undo - (kbd "C-w C-r") 'winner-redo + "]g" 'git-gutter+-stage-hunks + "[g" 'git-gutter+-revert-hunks) - ;; Increment/decrement number under cursor - (kbd "C--") 'evil-numbers/inc-at-pt - (kbd "C-+") 'evil-numbers/dec-at-pt) +(nmap! ;; Moving rows rather than lines (in case of wrapping) + "j" 'evil-next-visual-line + "k" 'evil-previous-visual-line -(vmap my-mode-map - ;; vnoremap < >gv - ">" (λ (evil-shift-right (region-beginning) (region-end)) - (evil-normal-state) - (evil-visual-restore)) + ;; behave like D and C; yank to end of line + "Y" (λ (evil-yank (point) (point-at-eol))) - "+" 'er/expand-region - "_" 'er/contract-region) + "zz" 'kill-this-buffer + "zx" 'bury-buffer + "]b" 'next-buffer + "[b" 'previous-buffer + "]e" 'next-error + "[e" 'previous-error + "]h" 'git-gutter+-next-hunk + "[h" 'git-gutter+-previous-hunk -(define-key evil-motion-state-map (kbd "RET") 'evil-ret-and-indent) -(imap my-mode-map - ;; Join lines from insert mode - (kbd "") 'evil-join + ;; winner-mode: window layout undo/redo (see init-core.el) + (kbd "C-w u") 'winner-undo + (kbd "C-w C-r") 'winner-redo - ;; Newline magic - [remap autopair-newline] 'my.newline-and-indent - (kbd "") 'evil-ret-and-indent - (kbd "") (kbd " DEL") ; newline and dedent + ;; Increment/decrement number under cursor + (kbd "C--") 'evil-numbers/inc-at-pt + (kbd "C-+") 'evil-numbers/dec-at-pt) - ;; 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-[")) +(vmap! ;; vnoremap < >gv + ">" (λ (evil-shift-right (region-beginning) (region-end)) + (evil-normal-state) + (evil-visual-restore))) -(emap my-mode-map - ;; Preserve buffer-movement in emacs mode - "j" 'evil-next-line - "k" 'evil-previous-line - ";" 'linum-mode +(imap! ;; Join lines from insert mode + (kbd "") 'evil-join - "o" 'send-dir-to-finder - "u" 'send-to-transmit - "l" 'send-to-launchbar - "L" 'send-dir-to-launchbar - "t" 'my:tmux-chdir - "T" (λ (my:tmux-chdir (projectile-project-root))) + ;; Newline magic + (kbd "") 'evil-ret-and-indent + (kbd "") (kbd " DEL") ; newline and dedent - (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) + ;; 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-[")) + +(emap! ;; 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) -(nmap my-mode-map "!" 'rotate-word-at-point) -(vmap my-mode-map "!" 'rotate-region) +(nmap! "!" 'rotate-word-at-point) +(vmap! "!" 'rotate-region) ;; Easy escape from insert mode (ichmap "jj" 'evil-normal-state) @@ -188,85 +159,215 @@ ;; Enable TAB to do matchit (nmap evil-matchit-mode-map (kbd "TAB") 'evilmi-jump-items) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Plugin/mode keymaps ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Real go-to-definition for elisp (nmap emacs-lisp-mode-map "gd" (λ (let ((func (function-called-at-point))) (if func (find-function func))))) +(after ag + (defmap ag-mode-map + [escape] 'ag-kill-buffers + "h" nil)) + +(after auto-complete + (imap ac-mode-map + (kbd "C-x C-f") 'ac-complete-filename + (kbd "C-SPC") 'auto-complete) + + (defmap ac-completing-map + (kbd "") 'ac-complete + (kbd "C-n") 'ac-next + (kbd "C-p") 'ac-previous + (kbd "") 'ac-quick-help + (kbd "ESC") 'ac-stop + (kbd "RET") 'ac-complete)) + +(after emmet-mode + (imap emmet-mode-keymap + (kbd "s-e") 'emmet-expand-yas + (kbd "s-E") 'emmet-expand-line)) + +(after js-mode + (imap js-mode-map [remap auto-complete] 'tern-ac-complete)) + +(after markdown-mode + (let ((map markdown-mode-map)) + (nvmap map + (kbd ",i") 'markdown-insert-image + (kbd ",l") 'markdown-insert-link + (kbd ",L") 'markdown-insert-reference-link-dwim) + + (nmap map + "[p" 'markdown-promote + "]p" 'markdown-demote) + + (imap map (kbd "M--") 'markdown-insert-hr) + + (defmap map + (kbd "") nil + (kbd "") nil + (kbd "") nil + + (kbd "s-*") 'markdown-insert-list-item + (kbd "s-b") 'markdown-insert-bold + (kbd "s-i") 'markdown-insert-italic + (kbd "s-`") 'markdown-insert-del))) + +(after multiple-cursors + (imap mc/keymap + (kbd "s-'") 'mc/mark-next-like-this + (kbd "s-\"") 'mc/mark-previous-like-this + (kbd "C-s-'") 'mc/mark-all-like-this) + + (vmap mc/keymap + (kbd "s-'") 'mc/mark-next-like-this + (kbd "s-\"") 'mc/mark-previous-like-this + (kbd "C-s-'") 'mc/mark-all-like-this)) + +(after nose + (nmap nose-mode-map + ",tr" 'nosetests-again + ",ta" 'nosetests-all + ",ts" 'nosetests-one + ",tv" 'nosetests-module + ",tA" 'nosetests-pdb-all + ",tO" 'nosetests-pdb-one + ",tV" 'nosetests-pdb-module)) + +(after org + ;; normal & insert state shortcuts. + ;; (mapc (lambda (state) + ;; (evil-define-key state evil-org-mode-map + ;; (kbd "M--") 'my/org-insert-list-item + ;; (kbd "M-l") 'org-metaright + ;; (kbd "M-h") 'org-metaleft + ;; (kbd "M-k") 'org-metaup + ;; (kbd "M-j") 'org-metadown + ;; (kbd "M-L") 'org-shiftmetaright + ;; (kbd "M-H") 'org-shiftmetaleft + ;; (kbd "M-K") 'org-shiftmetaup + ;; (kbd "M-J") 'org-shiftmetadown + ;; (kbd "") '(lambda () (interactive) + ;; (my/org-eol-call + ;; '(lambda() + ;; (org-insert-heading) + ;; (org-metaright)))) + ;; (kbd "M-t") '(lambda () (interactive) + ;; (my/org-eol-call + ;; '(lambda() + ;; (org-insert-todo-heading nil) + ;; (org-metaright)))) + ;; )) + ;; '(normal insert)) + + ;; Formatting shortcuts + + (imap evil-org-mode-map + (kbd "s-b") (λ (my/org-surround "*")) ; bold + (kbd "s-u") (λ (my/org-surround "_")) ; underline + (kbd "s-i") (λ (my/org-surround "/")) ; italics + (kbd "s-`") (λ (my/org-surround "+")) ; strikethrough + + (kbd "") 'org-insert-heading-after-current) + + (nvmap evil-org-mode-map + ",l" 'org-insert-link) + + (vmap evil-org-mode-map + (kbd "s-b") "s*" ; bold + (kbd "s-i") "s/") ; italics + + (nmap evil-org-mode-map + ",d" 'org-time-stamp + ",D" 'org-time-stamp-inactive + ",s" 'org-schedule + ",a" 'org-attach + ",A" 'org-attach-open + ",t" 'org-todo + ",T" 'org-show-todo-tree + ",/" 'org-match-sparse-tree + ",?" 'org-tags-view + ",+" 'org-align-all-tags + ",r" 'org-refile + "gh" 'outline-up-heading + "gj" 'org-forward-heading-same-level + "gk" 'org-backward-heading-same-level + "gl" 'outline-next-visible-heading + "go" 'org-open-at-point + "ga" 'org-agenda + "H" 'org-beginning-of-line + "L" 'org-end-of-line + "$" 'org-end-of-line + "^" 'org-beginning-of-line + "<" 'org-metaleft + ">" 'org-metaright + "-" 'org-cycle-list-bullet + (kbd ", SPC") 'org-archive-subtree + (kbd "") (λ (org-insert-heading-after-current) (evil-insert-state)) + (kbd "RET") (λ (org-todo 'done)) + (kbd "TAB") 'org-cycle)) + +(after ruby-mode + (nmap ruby-mode-map "gd" 'rsense-jump-to-definition)) + +(after rspec-mode + (nmap rspec-mode-verifiable-keymap + ",tr" 'rspec-rerun + ",ta" 'rspec-verify-all + ",ts" 'rspec-verify-single + ",tv" 'rspec-verify) + (nmap rspec-dired-mode-keymap + ",tv" 'rspec-dired-verify + ",ts" 'rspec-dired-verify-single + ",ta" 'rspec-verify-all + ",tr" 'rspec-rerun)) + +(after web-mode + (defmap web-mode-map (kbd "s-/") 'web-mode-comment-or-uncomment) + + (nvmap web-mode-map + "]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) + + (nmap web-mode-map + "zf" 'web-mode-fold-or-unfold + ",t" 'web-mode-element-rename)) + +(after re-builder + (nmap reb-mode-map + ",r" 'reb-enter-subexp-mode + ",b" 'reb-copy + ",i" 'reb-change-syntax + "\C-n" 'reb-next-match + "\C-p" 'reb-prev-match)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Ex Commands ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(evil-ex-define-cmd "msg" 'my:ex:msg-buffer) -(evil-ex-define-cmd "recompile" 'my:ex:byte-compile-all) -(evil-ex-define-cmd "n[otes]" 'my:ex:notes) -(evil-ex-define-cmd "ini" 'my:ex:init-files) -(evil-ex-define-cmd "snip[pets]" 'my:ex:snippets) -(evil-ex-define-cmd "mru" 'my:ex:mru) -(evil-ex-define-cmd "retab" 'my:ex:retab) -(evil-ex-define-cmd "ag" 'my:ex:ag-search) -(evil-ex-define-cmd "agr" 'my:ex:ag-regex-search) -(evil-ex-define-cmd "x" 'my:ex:scratch-buffer) +(exmap "msg" 'my:ex:msg-buffer) +(exmap "recompile" 'my:ex:byte-compile-all) +(exmap "n[otes]" 'my:ex:notes) +(exmap "ini" 'my:ex:init-files) +(exmap "snip[pets]" 'my:ex:snippets) +(exmap "mru" 'my:ex:mru) -(evil-ex-define-cmd "bx" 'my:ex:kill-buffers) -(evil-ex-define-cmd "tcd" 'my:ex:tmux-chdir) -(evil-ex-define-cmd "tmux" 'my:ex:tmux-send) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Keymap fixes ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Restores "dumb" indentation to the tab key. This rustles a lot of -;; peoples' jimmies, apparently, but it's how I like it. -(imap my-mode-map (kbd "") 'my.dumb-indent) -;; Except for lisp -(imap lisp-mode-map (kbd "") 'indent-for-tab-command) -(imap emacs-lisp-mode-map (kbd "") 'indent-for-tab-command) - -;; Highjacks the backspace and space to: -;; a) expand spaces between delimiters intelligently: (|) -> ( | ) -;; b) the reverse of A: ( | ) -> (|) -;; c) And allow backspace to delete indentation blocks intelligently -(define-key evil-insert-state-map - [remap autopair-backspace] 'my.deflate-space-maybe) -(define-key evil-insert-state-map - (kbd "SPC") 'my.inflate-space-maybe) - -;; Make ESC quit all the things -(mapc (lambda (map) - (define-key map [escape] 'my.minibuffer-quit)) - (list minibuffer-local-map - minibuffer-local-ns-map - minibuffer-local-completion-map - minibuffer-local-must-match-map - minibuffer-local-isearch-map)) -(define-key evil-emacs-state-map [escape] 'evil-exit-emacs-state) -;; Close help/compilation windows with escape -(define-key help-mode-map [escape] 'kill-buffer-and-window) -(define-key compilation-mode-map [escape] 'kill-buffer-and-window) -(evil-define-key 'emacs debugger-mode-map [remap evil-exit-emacs-state] 'kill-buffer-and-window) - -;; Restore bash-esque keymaps in insert mode -(imap my-mode-map - (kbd "C-a") 'evil-move-beginning-of-line - (kbd "C-e") 'evil-move-end-of-line - (kbd "C-u") 'my.backward-kill-to-bol-and-indent) - -;; And the minibuffer -(mapc (lambda (map) - (define-key map (kbd "C-a") 'move-beginning-of-line) - (define-key map (kbd "C-e") 'move-end-of-line) - (define-key map (kbd "C-u") 'my.backward-kill-to-bol)) - (list minibuffer-local-map minibuffer-local-ns-map)) -(define-key evil-insert-state-map (kbd "C-w") 'backward-kill-word) -(define-key minibuffer-local-map (kbd "C-w") 'ido-delete-backward-word-updir) - -(add-hook 'ido-setup-hook '(lambda () - ;; take that "Text is read-only" and stick it where emacs don't shine! - (define-key ido-completion-map (kbd "") 'ido-delete-backward-updir) - (define-key ido-completion-map "\C-n" 'ido-next-match) - (define-key ido-completion-map "\C-p" 'ido-prev-match) - - ;; Auto-complete on tab/space (why is it called ido-exit-minibuffer?) - (define-key ido-completion-map " " 'ido-exit-minibuffer))) +(exmap "retab" 'my:ex:retab) +(exmap "ag" 'my:ex:ag-search) +(exmap "agr" 'my:ex:ag-regex-search) +(exmap "x" 'my:ex:scratch-buffer) +(exmap "a" 'projectile-find-other-file) +(exmap "bx" 'my:ex:kill-buffers) +(exmap "tcd" 'my:ex:tmux-chdir) +(exmap "t[mux]" 'my:ex:tmux-send) +(exmap "build" 'my:ex:build) +(exmap "re[gex]" 're-builder) diff --git a/init/my-settings.el b/init/my-settings.el new file mode 100644 index 000000000..b1514aa25 --- /dev/null +++ b/init/my-settings.el @@ -0,0 +1,17 @@ +(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 " !") + ) + +(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 "EMACS" "1") diff --git a/themes/brin-theme.el b/themes/brin-theme.el index 3924a00c0..ab0f64939 100644 --- a/themes/brin-theme.el +++ b/themes/brin-theme.el @@ -41,7 +41,7 @@ (builtin "#d08770") (foreground "#c0c5ce") (invisibles "#65737e") - (lineHighlight "#242428") + (lineHighlight "#353539") (selection "#4f5b66") (text "#c0c5ce") (comments "#65737e")