diff --git a/Cask b/Cask index a4fee81e7..1afae7316 100644 --- a/Cask +++ b/Cask @@ -17,6 +17,9 @@ (depends-on "vim-empty-lines-mode") (depends-on "hlinum" :git "https://github.com/tom-tan/hlinum-mode") +;; Themes +(depends-on "solarized-theme") + ;; OSX (depends-on "exec-path-from-shell") (depends-on "dash-at-point") @@ -36,12 +39,15 @@ (depends-on "smartparens") (depends-on "yasnippet") (depends-on "diff-hl") -;; (depends-on "git-gutter-fringe+") -;; (depends-on "ace-jump-mode") +(depends-on "ace-jump-mode") +(depends-on "ace-window") +(depends-on "ace-link") (depends-on "pcre2el") (depends-on "emr") (depends-on "smart-forward") (depends-on "anzu") +(depends-on "iedit") +(depends-on "quickrun") ;; Auto-completion (depends-on "company") @@ -57,15 +63,16 @@ (depends-on "evil-search-highlight-persist") (depends-on "evil-commentary") (depends-on "evil-matchit") -(depends-on "evil-surround") (depends-on "evil-numbers") (depends-on "evil-exchange") -(depends-on "evil-space") (depends-on "evil-visualstar") (depends-on "evil-indent-textobject") (depends-on "evil-jumper") -(depends-on "evil-god-state") +(depends-on "evil-iedit-state") +(depends-on "evil-anzu") (depends-on "evil-snipe") +(depends-on "evil-surround") +(depends-on "evil-space") ;; Project management (depends-on "projectile") @@ -75,6 +82,7 @@ (depends-on "helm-projectile") (depends-on "helm-swoop") (depends-on "helm-company") +(depends-on "helm-c-yasnippet") (depends-on "neotree" :git "https://github.com/jeffplang/emacs-neotree") (depends-on "ido-ubiquitous") (depends-on "ido-vertical-mode") @@ -137,3 +145,8 @@ (depends-on "rust-mode") (depends-on "d-mode") (depends-on "android-mode") + +(depends-on "vimrc-mode") + +;(depends-on "osh") +;(depends-on "sonic-pi" :git "https://github.com/repl-electric/sonic-pi.el") diff --git a/Makefile b/Makefile index 164fc1aec..6affd5c71 100644 --- a/Makefile +++ b/Makefile @@ -8,10 +8,15 @@ update: install autoloads install: cask install -clean: - @rm -rf init.elc init/*.elc contrib/*.elc - @rm -rf auto-save-list recentf places ido.last async-bytecomp.log elpa projectile-bookmarks.eld projectile.cache company-statistics-cache.el tramp smex-items +compile: clean + @cask exec ${EMACS} -f narf::byte-compile + +clean: clean-extras + @rm -rf init.elc init/*.elc contrib/*.elc core/*.elc + +clean-extras: + @rm -rf auto-save-list recentf places ido.last async-bytecomp.log elpa projectile-bookmarks.eld projectile.cache company-statistics-cache.el tramp smex-items semanticdb autoloads: - @rm -rf init/autoloads.el - @cask exec ${EMACS} -Q --batch --eval '(progn (setq generated-autoload-file "~/.emacs.d/init/autoloads.el") (update-directory-autoloads "~/.emacs.d/init" "~/.emacs.d/contrib"))' + @rm -rf core/autoloads.el + @cask exec ${EMACS} -Q --batch --eval $$'(progn (setq generated-autoload-file "~/.emacs.d/core/autoloads.el") (update-directory-autoloads "~/.emacs.d/init" "~/.emacs.d/core" "~/.emacs.d/contrib"))' diff --git a/core/autoloads.el b/core/autoloads.el new file mode 100644 index 000000000..17702ebe8 --- /dev/null +++ b/core/autoloads.el @@ -0,0 +1,532 @@ +;;; autoloads.el --- automatically extracted autoloads +;; +;;; Code: + + +;;;### (autoloads nil "../contrib/goto-last-change" "../contrib/goto-last-change.el" +;;;;;; (21865 37510 0 0)) +;;; Generated autoloads from ../contrib/goto-last-change.el + +(autoload 'goto-last-change "../contrib/goto-last-change" "\ +Go to the point where the last edit was made in the current buffer. +Repeat the command to go to the second last edit, etc. + +To go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse] +or precede this command with \\[universal-argument] - (minus). + +It does not go to the same point twice even if there has been many edits +there. I call the minimal distance between distinguishable edits \"span\". +Set variable `glc-default-span' to control how close is \"the same point\". +Default span is 8. +The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]: +\\[universal-argument] set current span to that number, +\\[universal-argument] (no number) multiplies span by 4, starting with default. +The so set span remains until it is changed again with \\[universal-argument], or the consecutive +repetition of this command is ended by any other command. + +When span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and +every point of edit and a message shows what change was made there. +In this case it may go to the same point twice. + +This command uses undo information. If undo is disabled, so is this command. +At times, when undo information becomes too large, the oldest information is +discarded. See variable `undo-limit'. + +\(fn ARG)" t nil) + +(autoload 'goto-last-change-reverse "../contrib/goto-last-change" "\ +Go back to more recent changes after \\[goto-last-change] have been used. +See `goto-last-change' for use of prefix argument. + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "../contrib/help-fns+" "../contrib/help-fns+.el" +;;;;;; (21631 21029 0 0)) +;;; Generated autoloads from ../contrib/help-fns+.el + +(autoload 'describe-command "../contrib/help-fns+" "\ +Describe an Emacs command (interactive function). +Equivalent to using a prefix arg with `describe-function'. + +If you use Icicles then in Icicle mode keys bound to the commands are +shown next to them in `*Completions*. You can toggle this keys +display on/off using `C-x C-a'. + +\(fn FUNCTION)" t nil) + +(autoload 'describe-option "../contrib/help-fns+" "\ +Describe an Emacs user variable (option). +Same as using a prefix arg with `describe-variable'. + +\(fn VARIABLE &optional BUFFER)" t nil) + +(autoload 'describe-option-of-type "../contrib/help-fns+" "\ +Describe an Emacs user OPTION (variable) of a given `defcustom' TYPE. +A prefix argument determines the type-checking behavior: + - None: OPTION is defined with TYPE or a subtype of TYPE. + - Plain `C-u': OPTION is defined with TYPE or a subtype of TYPE, + or its current value is compatible with TYPE. + - Negative: OPTION is defined with TYPE (exact match). + - Non-negative: OPTION is defined with TYPE (exact match), + or its current value is compatible with TYPE. + +If TYPE is nil (default value) then *all* `defcustom' variables are +potential candidates. That is different from using `describe-option', +because `describe-option' includes user-variable candidates not +defined with `defcustom' (with `*'-prefixed doc strings). + +\(fn TYPE OPTION)" t nil) + +(autoload 'describe-file "../contrib/help-fns+" "\ +Describe the file named FILENAME. +If FILENAME is nil, describe current directory (`default-directory'). + +Starting with Emacs 22, if the file is an image file then: + * Show a thumbnail of the image as well. + * If you have command-line tool `exiftool' installed and in your + `$PATH' or `exec-path', then show EXIF data (metadata) about the + image. See standard Emacs library `image-dired.el' for more + information about `exiftool'. + +If FILENAME is the name of an autofile bookmark and you use library +`Bookmark+', then show also the bookmark information (tags etc.). In +this case, a prefix arg shows the internal form of the bookmark. + +In Lisp code: + +Non-nil optional arg INTERNAL-FORM-P shows the internal form. +Non-nil optional arg NO-ERROR-P prints an error message but does not + raise an error. + +\(fn FILENAME &optional INTERNAL-FORM-P NO-ERROR-P)" t nil) + +;;;*** + +;;;### (autoloads nil "../contrib/hide-mode-line" "../contrib/hide-mode-line.el" +;;;;;; (21641 7940 0 0)) +;;; Generated autoloads from ../contrib/hide-mode-line.el + +(autoload 'hide-mode-line "../contrib/hide-mode-line" "\ +Toggle the hide-mode-line functionality. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "../contrib/hl-todo" "../contrib/hl-todo.el" +;;;;;; (21835 1957 0 0)) +;;; Generated autoloads from ../contrib/hl-todo.el + +(autoload 'hl-todo-mode "../contrib/hl-todo" "\ +Highlight TODO tags in comments. + +\(fn &optional ARG)" t nil) + +(defvar global-hl-todo-mode nil "\ +Non-nil if Global-Hl-Todo mode is enabled. +See the command `global-hl-todo-mode' for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `global-hl-todo-mode'.") + +(custom-autoload 'global-hl-todo-mode "../contrib/hl-todo" nil) + +(autoload 'global-hl-todo-mode "../contrib/hl-todo" "\ +Toggle Hl-Todo mode in all buffers. +With prefix ARG, enable Global-Hl-Todo mode if ARG is positive; +otherwise, disable it. If called from Lisp, enable the mode if +ARG is omitted or nil. + +Hl-Todo mode is enabled in all buffers where +`turn-on-hl-todo-mode-if-desired' would do it. +See `hl-todo-mode' for more information on Hl-Todo mode. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads nil "../contrib/rotate-text" "../contrib/rotate-text.el" +;;;;;; (21631 59390 0 0)) +;;; Generated autoloads from ../contrib/rotate-text.el + +(autoload 'rotate-region "../contrib/rotate-text" "\ +Rotate all matches in `rotate-text-rotations' between point and mark. + +\(fn BEG END)" t nil) + +(autoload 'rotate-word-at-point "../contrib/rotate-text" "\ +Rotate word at point based on sets in `rotate-text-rotations'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "defuns-buffers" "defuns-buffers.el" (21869 +;;;;;; 35086 0 0)) +;;; Generated autoloads from defuns-buffers.el + +(autoload 'narf:narrow-to-region-indirect "defuns-buffers" "\ +Restrict editing in this buffer to the current region, indirectly. + +\(fn START END)" t nil) + +(autoload 'narf:widen "defuns-buffers" "\ + + +\(fn)" t nil) + +(autoload 'narf:set-region-read-only "defuns-buffers" "\ +See http://stackoverflow.com/questions/7410125 + +\(fn BEGIN END)" nil nil) + +(autoload 'narf:set-region-writeable "defuns-buffers" "\ +See http://stackoverflow.com/questions/7410125 + +\(fn BEGIN END)" nil nil) + +(autoload 'narf/living-buffer-list "defuns-buffers" "\ + + +\(fn &optional BUFFER-LIST)" nil nil) + +(autoload 'narf/add-throwaway-buffer "defuns-buffers" "\ + + +\(fn REGEXP)" nil nil) + +(autoload 'narf:cleanup-buffers "defuns-buffers" "\ +Kill left-over temporary, dired or buried special buffers + +\(fn)" t nil) + +(autoload 'narf:cleanup-processes "defuns-buffers" "\ + + +\(fn)" t nil) + +(autoload 'narf:kill-matching-buffers "defuns-buffers" "\ + + +\(fn REGEXP &optional BUFFER-LIST)" t nil) + +(autoload 'narf:next-real-buffer "defuns-buffers" "\ +Switch to the next buffer and avoid special buffers. + +\(fn)" t nil) + +(autoload 'narf:previous-real-buffer "defuns-buffers" "\ +Switch to the previous buffer and avoid special buffers. + +\(fn)" t nil) + +(autoload 'narf:kill-real-buffer "defuns-buffers" "\ +Kill buffer (but only bury scratch buffer) + +\(fn)" t nil) + (autoload 'narf::save-session "defuns-buffers") + (autoload 'narf::load-session "defuns-buffers") + (autoload 'narf::new-workgroup "defuns-buffers") + (autoload 'narf::rename-workgroup "defuns-buffers") + (autoload 'narf::rename-this-file "defuns-buffers") + (autoload 'narf::delete-this-file "defuns-buffers") + (autoload 'narf::create-file "defuns-buffers") + (autoload 'narf::scratch-buffer "defuns-buffers") + (autoload 'narf::kill-buried-buffers "defuns-buffers") + (autoload 'narf::kill-buffers "defuns-buffers") + (autoload 'narf::cd "defuns-buffers") + +;;;*** + +;;;### (autoloads nil "defuns-code" "defuns-code.el" (21869 24069 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-code.el + +(autoload 'narf/set-build-command "defuns-code" "\ + + +\(fn COMMAND &optional FILE)" nil nil) + (autoload 'narf::build "defuns-code") + (autoload 'narf::eval "defuns-code") + (autoload 'narf::eval-region "defuns-code") + (autoload 'narf::eval-buffer "defuns-code") + (autoload 'narf::eval-region-and-replace "defuns-code") + +(autoload 'narf/get-interpreter "defuns-code" "\ + + +\(fn)" nil nil) + +;;;*** + +;;;### (autoloads nil "defuns-debug" "defuns-debug.el" (21867 64619 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-debug.el + +(autoload 'what-face "defuns-debug" "\ +Tells you the name of the face (point) is on. + +\(fn POS)" t nil) + +(autoload 'what-col "defuns-debug" "\ + + +\(fn)" t nil) + +(autoload 'what-bindings "defuns-debug" "\ + + +\(fn KEY)" nil nil) + (autoload 'narf::echo "defuns-debug") + +;;;*** + +;;;### (autoloads nil "defuns-edit" "defuns-edit.el" (21866 40579 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-edit.el + +(autoload 'narf:replace-ms-word-chars "defuns-edit" "\ +Replace smart quotes and other MS Word verbiage into plain text + +\(fn BEG END)" t nil) + +(autoload 'narf:replace-email2mailto "defuns-edit" "\ +Email address with mailto link + +\(fn BEG END)" t nil) + +(autoload 'narf:replace-url2anchor "defuns-edit" "\ +Link with anchor + +\(fn BEG END)" t nil) + +(autoload 'narf:goto-line "defuns-edit" "\ + + +\(fn)" t nil) + (autoload 'narf::align "defuns-edit") + (autoload 'narf::retab "defuns-edit") + (autoload 'narf::narrow-indirect-or-widen "defuns-edit") + +(autoload 'narf:toggle-delete-trailing-whitespace "defuns-edit" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "defuns-extern" "defuns-extern.el" (21866 18425 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-extern.el + +(autoload 'narf/tmux-send "defuns-extern" "\ + + +\(fn COMMAND)" nil nil) + (autoload 'narf::tmux-run "defuns-extern") + (autoload 'narf::tmux-chdir "defuns-extern") + +;;;*** + +;;;### (autoloads nil "defuns-mouse" "defuns-mouse.el" (21865 57645 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-mouse.el + +(autoload 'narf/mouse-line-at-click "defuns-mouse" "\ +Determine the line number at click + +\(fn)" nil nil) + +(autoload 'narf/mouse-select-line "defuns-mouse" "\ +Set point as *linum-mdown-line* + +\(fn EVENT)" t nil) + +(autoload 'narf/mouse-select-block "defuns-mouse" "\ +Select the current block of text between blank lines. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "defuns-org" "defuns-org.el" (21866 45401 0 +;;;;;; 0)) +;;; Generated autoloads from defuns-org.el + +(autoload 'narf/project-org-filename "defuns-org" "\ + + +\(fn CAT)" t nil) + +(autoload 'narf--org-in-list-p "defuns-org" "\ + + +\(fn)" nil nil) + +(autoload 'narf/org-insert-item-after "defuns-org" "\ +Inserts a new heading or item, depending on the context. + +\(fn)" t nil) + +(autoload 'narf/org-insert-item-before "defuns-org" "\ +Inserts a new heading or item, depending on the context. + +\(fn)" t nil) + +(autoload 'narf/org-toggle-checkbox "defuns-org" "\ + + +\(fn)" t nil) + +(autoload 'narf/org-surround "defuns-org" "\ + + +\(fn DELIM)" nil nil) + (autoload 'narf::org-insert-image-url "defuns-org") + (autoload 'narf::org-insert-image "defuns-org") + +;;;*** + +;;;### (autoloads nil "defuns-search" "defuns-search.el" (21866 51196 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-search.el + +(autoload 'narf:ido-find-file "defuns-search" "\ + + +\(fn &optional DIR)" t nil) + +(autoload 'narf:ido-find-file-other-window "defuns-search" "\ + + +\(fn &optional DIR)" t nil) + +(autoload 'narf:ido-find-project-file "defuns-search" "\ + + +\(fn)" t nil) + (autoload 'narf::initfiles "defuns-search") + (autoload 'narf::notes "defuns-search") + (autoload 'narf::recentf "defuns-search") + (autoload 'narf::ag-search "defuns-search") + (autoload 'narf::ag-regex-search "defuns-search") + (autoload 'narf::ag-regex-cwd "defuns-search") + (autoload 'narf::ag-regex-search-cwd "defuns-search") + (autoload 'narf::swoop "defuns-search") + (autoload 'narf::snippets "defuns-search") + +;;;*** + +;;;### (autoloads nil "defuns-text" "defuns-text.el" (21869 14495 +;;;;;; 0 0)) +;;; Generated autoloads from defuns-text.el + +(autoload 'narf--point-at-bol-non-blank "defuns-text" "\ + + +\(fn)" nil nil) + +(autoload 'narf/surrounded-p "defuns-text" "\ + + +\(fn)" nil nil) + +(autoload 'narf:backward-kill-to-bol-and-indent "defuns-text" "\ +Kill line to the first non-blank character. If invoked again +afterwards, kill line to column 1. + +\(fn)" t nil) + +(autoload 'narf:move-to-bol "defuns-text" "\ +Moves cursor to the first non-blank character on the line. If +already there, move it to the true bol. + +\(fn)" t nil) + +(autoload 'narf:move-to-eol "defuns-text" "\ + + +\(fn)" t nil) + +(autoload 'narf:backward-delete-whitespace-to-column "defuns-text" "\ +Delete back to the previous column of whitespace, or as much +whitespace as possible, or just one char if that's not possible. + +\(fn)" t nil) + +(autoload 'narf:dumb-indent "defuns-text" "\ +Inserts a tab character (or spaces x tab-width). Checks if the +auto-complete window is open. + +\(fn)" t nil) + +(autoload 'narf:inflate-space-maybe "defuns-text" "\ +Checks if point is surrounded by {} [] () delimiters and adds a +space on either side of the point if so. + +\(fn)" t nil) + +(autoload 'narf:deflate-space-maybe "defuns-text" "\ +Checks if point is surrounded by {} [] () delimiters, and deletes +spaces on either side of the point if so. Resorts to +`narf:backward-delete-whitespace-to-column' otherwise. + +\(fn)" t nil) + +(autoload 'narf:newline-and-indent "defuns-text" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "defuns-ui" "defuns-ui.el" (21865 64034 0 0)) +;;; Generated autoloads from defuns-ui.el + +(autoload 'narf:toggle-transparency "defuns-ui" "\ + + +\(fn)" t nil) + +(autoload 'narf:toggle-fullscreen "defuns-ui" "\ + + +\(fn)" t nil) + +(autoload 'narf:toggle-big-mode "defuns-ui" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("../contrib/evil-ex-registers.el" "../contrib/flycheck-objc.el" +;;;;;; "../contrib/ruby-mode-indent-fix.el" "../contrib/shaderlab-mode.el" +;;;;;; "../contrib/unityjs-mode.el" "../init/autoloads.el" "../init/init-auto-insert.el" +;;;;;; "../init/init-cc.el" "../init/init-cscope.el" "../init/init-csharp.el" +;;;;;; "../init/init-eshell.el" "../init/init-fly.el" "../init/init-go.el" +;;;;;; "../init/init-helm.el" "../init/init-ido.el" "../init/init-java.el" +;;;;;; "../init/init-js.el" "../init/init-lisp.el" "../init/init-lua.el" +;;;;;; "../init/init-org.el" "../init/init-php.el" "../init/init-project.el" +;;;;;; "../init/init-python.el" "../init/init-r.el" "../init/init-regex.el" +;;;;;; "../init/init-ruby.el" "../init/init-rust.el" "../init/init-scss.el" +;;;;;; "../init/init-sh.el" "../init/init-swift.el" "../init/init-text.el" +;;;;;; "../init/init-vc.el" "../init/init-vim.el" "../init/init-web.el" +;;;;;; "../init/init-workgroups.el" "../init/init-yasnippet.el" +;;;;;; "../init/narf-bindings.el" "../init/narf-commands.el" "../init/narf-settings.el" +;;;;;; "benchmark.el" "core-company.el" "core-editor.el" "core-evil.el" +;;;;;; "core-linux.el" "core-osx.el" "core-splash.el" "core-ui.el" +;;;;;; "core.el" "defuns.el" "startup.el") (21869 35551 604587 0)) + +;;;*** + +(provide 'autoloads) +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; autoloads.el ends here diff --git a/core/benchmark.el b/core/benchmark.el new file mode 100644 index 000000000..fc68df1a1 --- /dev/null +++ b/core/benchmark.el @@ -0,0 +1,44 @@ +(defvar require-times nil + "A list of (FEATURE . LOAD-DURATION). +LOAD-DURATION is the time taken in milliseconds to load FEATURE.") + +(defadvice require + (around build-require-times (feature &optional filename noerror) activate) + "Note in `require-times' the time taken to require each feature." + (let* ((already-loaded (memq feature features)) + (require-start-time (and (not already-loaded) (current-time)))) + (prog1 + ad-do-it + (when (and (not already-loaded) (memq feature features)) + (add-to-list 'require-times + (cons feature + (float-time (time-subtract (current-time) require-start-time))) + t))))) + +(defun list-times () + (interactive) + (let ((temp-buffer (get-buffer-create "*benchmark*")) + (sum 0.0)) + (popwin:popup-buffer temp-buffer :stick t) + (erase-buffer) + (org-mode) + (dolist (feature require-times) + (if (eq feature 'null) + (progn + (insert "|----+----+----|\n") + (insert (format "| %6f | Subtotal |\n" sum)) + (insert "|----+----+----|\n")) + (let ((time (cdr feature))) + (insert (format "| %6f | %s | %s |\n" time (car feature) (cond ((>= time 0.4) "XXX") + ((>= time 0.1) "X") + ((>= time 0.05) ".") + (t " ")))) + (setq sum (+ sum time))))) + (save-excursion + (insert "|----+----+----|\n") + (insert (format "| %6f | Total |\n" sum)) + (insert (format "| %s | On Init |\n" (emacs-init-time)))) + (org-table-align))) + + +(provide 'benchmark) diff --git a/core/core-company.el b/core/core-company.el new file mode 100644 index 000000000..aeaaa8a7e --- /dev/null +++ b/core/core-company.el @@ -0,0 +1,95 @@ +(use-package company + :diminish (company-mode . "=") + :init + (progn + (defvar company-dictionary-alist '()) + (defvar company-dictionary-major-minor-modes '()) + (defvar company-dictionary-dir (concat BASE-DIR "dict/"))) + + (after "abbrev" (diminish 'abbrev-mode "A")) + :config + (progn + (global-company-mode +1) + (setq company-idle-delay nil + company-minimum-prefix-length 1 + company-show-numbers nil + company-tooltip-limit 20 + company-dabbrev-downcase nil + company-dabbrev-ignore-case nil + company-tooltip-align-annotations t + company-require-match 'never + company-global-modes + '(not eshell-mode comint-mode org-mode erc-mode message-mode help-mode)) + + ;; sort candidates by + (setq-default company-frontends + '(company-pseudo-tooltip-unless-just-one-frontend + company-echo-metadata-frontend + company-preview-if-just-one-frontend)) + + (progn ; Rewrite evil-complete to use company-dabbrev + (setq company-dabbrev-code-other-buffers t) + (setq company-dabbrev-code-buffers nil) + (setq evil-complete-next-func + (lambda(arg) + (call-interactively 'company-dabbrev) + (if (eq company-candidates-length 1) + (company-complete)))) + (setq evil-complete-previous-func + (lambda (arg) + (let ((company-selection-wrap-around t)) + (call-interactively 'company-dabbrev) + (if (eq company-candidates-length 1) + (company-complete) + (call-interactively 'company-select-previous)))))) + + (progn ; backends + (setq-default company-backends (append '(company-dictionary company-keywords) company-backends)) + (add-to-list 'company-transformers 'company-sort-by-occurrence) + (after "yasnippet" + (setq-default company-backends (append '(company-capf company-yasnippet) company-backends))) + + (defmacro narf/add-company-backend (hook backends) + "Register a company backend for a mode." + (let ((def-name (intern (format "narf--init-%s" hook)))) + `(progn + (defun ,def-name () + (set (make-local-variable 'company-backends) + (append '((,@backends company-semantic)) company-backends))) + (add-hook ',(intern (format "%s-hook" hook)) ',def-name)))) + (narf/add-company-backend nxml-mode (company-nxml company-yasnippet)) + (narf/add-company-backend emacs-lisp-mode (company-elisp company-yasnippet)) + + + ;; Simulates ac-source-dictionary (without global dictionary) + (defun company-dictionary (command &optional arg &rest ignored) + "`company-mode' back-end for user-provided dictionaries." + (interactive (list 'interactive)) + (unless company-dictionary-alist + ;; initialize dictionary + (dolist (file (f-files company-dictionary-dir)) + (add-to-list 'company-dictionary-alist `(,(intern (f-base file)) ,@(s-split "\n" (f-read file) t))))) + (let ((dict (let ((minor-modes (-filter (lambda (mode) (when (boundp mode) (symbol-value mode))) + company-dictionary-major-minor-modes)) + (dicts (cdr (assq major-mode company-dictionary-alist)))) + (dolist (mode minor-modes) + (setq dicts (append dicts (cdr (assq mode company-dictionary-alist))))) + dicts))) + (cl-case command + (interactive (company-begin-backend 'company-dictionary)) + (prefix (and dict (or (company-grab-symbol) 'stop))) + (candidates + (let ((completion-ignore-case nil) + (symbols dict)) + (all-completions arg symbols))) + (sorted t))))) + + (use-package company-statistics + :config + (shut-up + (setq company-statistics-file (expand-file-name "company-statistics-cache.el" TMP-DIR)) + (company-statistics-mode))))) + + +(provide 'core-company) +;;; core-company.el ends here diff --git a/core/core-editor.el b/core/core-editor.el new file mode 100644 index 000000000..cc734ff34 --- /dev/null +++ b/core/core-editor.el @@ -0,0 +1,162 @@ +;;; Global editor behavior + +(electric-indent-mode -1) +(setq electric-indent-chars '(? ?: ?{)) +(add-hook 'python-mode-hook 'electric-indent-local-mode) +(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) +(add-hook! 'eldoc-mode-hook (diminish 'eldoc-mode " ?")) + +(setq-default fill-column 80) +(diminish 'auto-fill-function) +;; Sane scroll settings +(setq scroll-margin 5 + scroll-conservatively 9999 + scroll-preserve-screen-position t) +;; I'll use visual mode, kthxbai +(setq shift-select-mode nil) + +;;;; Modes 'n hooks ;;;;;;;;;;;;;;;;; +(associate-mode "/LICENSE[^/]*$" 'text-mode) +(associate-mode "zsh\\(env\\|rc\\)?$" 'sh-mode) +(associate-mode "z\\(profile\\|login\\|logout\\)?$" 'sh-mode) +(associate-mode "zsh/" 'sh-mode) +(associate-mode "\\.applescript$" 'applescript-mode) +(associate-mode "Cask$" 'emacs-lisp-mode) +(associate-mode "\\.el\\.gz$" 'emacs-lisp-mode) +(associate-mode "/Makefile$" 'makefile-gmake-mode) +(associate-mode "\\.plist$" 'nxml-mode) + +(add-hook 'help-mode-hook 'visual-line-mode) +(add-hook 'before-save-hook 'delete-trailing-whitespace) +(add-hook 'makefile-mode-hook 'narf|enable-tabs) ; Use normal tabs in makefiles + +(after "isearch" (diminish 'isearch-mode)) + +;; Fix code folding +(defun narf|init-hs-minor-mode-maybe () + (unless (bound-and-true-p hs-minor-mode) + (hs-minor-mode 1) + (diminish 'hs-minor-mode))) +(add-hook 'prog-mode-hook 'narf|init-hs-minor-mode-maybe) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(use-package smartparens + :diminish smartparens-mode + :config + (progn + (use-package smartparens-config) + (smartparens-global-mode 1) + + (setq blink-matching-paren t + sp-autowrap-region nil ; let evil-surround handle this + sp-highlight-pair-overlay nil + sp-show-pair-delay 0) + + ;; Handle newlines + spaces + (sp-pair "{" "}" :post-handlers '(("||\n[i]" "RET") ("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p)) + (sp-pair "(" ")" :post-handlers '(("||\n[i]" "RET") ("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p)) + + ;; Auto-close more conservatively + (sp-pair "[" nil :unless '(sp-point-before-word-p sp-point-before-same-p)) + (sp-pair "'" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) + (sp-pair "\"" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) + (sp-with-modes '(json-mode js2-mode ruby-mode enh-ruby-mode python-mode) + (sp-local-pair "[" nil :post-handlers '(("||\n[i]" "RET")))) + (sp-with-modes '(c-mode c++-mode objc-mode java-mode scss-mode css-mode php-mode) + (sp-local-pair "/* " " */" :post-handlers '(("||\n[i]" "RET"))) + (sp-local-pair "/**" "*/" :post-handlers '(("||\n[i]" "RET")))) + (sp-with-modes '(c-mode c++-mode objc-mode java-mode) ; Support for generics + (sp-local-pair "<" ">" :when '(sp-point-after-word-p) :unless '(sp-point-before-same-p))) + (sp-with-modes '(objc-mode scss-mode css-mode) + (sp-local-pair "/*\n" "\n */" :post-handlers '(("||[i]" "RET")))) + (sp-with-modes '(c-mode c++-mode php-mode java-mode) + (sp-local-pair "/*" "" :post-handlers '((" ||\n[i]*/" "RET")))) + + (after "yasnippet" (advice-add 'yas-expand :before 'sp-remove-active-pair-overlay)))) + +(use-package rotate-text + :commands (rotate-word-at-point rotate-region)) + +(use-package smart-forward + :commands (smart-up smart-down smart-left smart-right)) + +(use-package expand-region + :commands (er/expand-region er/contract-region er/mark-symbol er/mark-word)) + +(use-package hl-todo + :commands hl-todo-mode + :init (add-hook 'prog-mode-hook 'hl-todo-mode)) + +(use-package emr + :commands (emr-initialize emr-show-refactor-menu emr-declare-command) + :config (bind :map popup-menu-keymap [escape] 'keyboard-quit)) + +(use-package rainbow-delimiters + :commands rainbow-delimiters-mode + :init (add-to-hooks 'rainbow-delimiters-mode '(emacs-lisp-mode js2-mode scss-mode)) + :config (setq rainbow-delimiters-outermost-only-face-count 1)) + +(use-package ace-window + :commands ace-window + :config + (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l) + aw-scope 'frame + aw-background nil)) + +(use-package ace-jump-mode + :functions (ace-jump-char-category ace-jump-do) + :commands (ace-jump-line-mode + ace-jump-char-mode + ace-jump-word-mode + ace-jump-two-chars-mode) + :config + (progn + (defun ace-jump-two-chars-mode (&optional query-char query-char-2) + "AceJump two chars mode" + (interactive) + + (evil-half-cursor) + (setq query-char (or query-char (read-char ">"))) + (setq query-char-2 (or query-char-2 (read-char (concat ">" (string query-char))))) + + (if (eq (ace-jump-char-category query-char) 'other) + (error "[AceJump] Non-printable character")) + + ;; others : digit , alpha, punc + (setq ace-jump-query-char query-char) + (setq ace-jump-current-mode 'ace-jump-char-mode) + (ace-jump-do (regexp-quote (concat (char-to-string query-char) + (char-to-string query-char-2))))) + (setq ace-jump-mode-scope 'window + ace-jump-mode-gray-background t))) + +(use-package ace-link + :commands (ace-link-info + ace-link-help + ace-link-compilation + ace-link-custom + ace-link-org) + :init + (progn + (after "help-mode" + (bind motion :map help-mode-map "go" 'ace-link-help)) + (after "compile" + (bind motion :map compilation-mode-map "go" 'ace-link-compilation)) + (after "info" + (bind motion :map Info-mode-map "go" 'ace-link-info)) + (after "org" + (bind motion :map org-mode-map "go" 'ace-link-org)))) + +(use-package quickrun + :commands (quickrun + quickrun-region + quickrun-with-arg + quickrun-shell + quickrun-compile-only + quickrun-replace-region + helm-quickrun)) + + +(provide 'core-editor) +;;; core-editor.el ends here diff --git a/core/core-evil.el b/core/core-evil.el new file mode 100644 index 000000000..6289a1480 --- /dev/null +++ b/core/core-evil.el @@ -0,0 +1,319 @@ +;;;; Eeeeeeevil ;;;;;;;;;;;;;;;;;;;;;;;; +(use-package evil + :init + (progn + (use-package goto-last-change) + + ;; highlight matching delimiters where it's important + (defun show-paren-mode-off () (show-paren-mode -1)) + (add-hook 'evil-insert-state-entry-hook 'show-paren-mode) + (add-hook 'evil-insert-state-exit-hook 'show-paren-mode-off) + (add-hook 'evil-visual-state-entry-hook 'show-paren-mode) + (add-hook 'evil-visual-state-exit-hook 'show-paren-mode-off) + (add-hook 'evil-motion-state-entry-hook 'show-paren-mode) + (add-hook 'evil-motion-state-exit-hook 'show-paren-mode-off) + (add-hook 'evil-operator-state-entry-hook 'show-paren-mode) + (add-hook 'evil-operator-state-exit-hook 'show-paren-mode-off) + + ;; Disable highlights on insert-mode + (add-hook 'evil-insert-state-entry-hook 'evil-ex-nohighlight) + + (add-hook! 'undo-tree-mode-hook (diminish 'undo-tree-mode)) + ;; Always ensure evil-shift-width is consistent with tab-width + (add-hook! 'evil-local-mode-hook (setq evil-shift-width tab-width))) + :config + (progn + (progn ; open/close fold mods + ;; Instead of `evil-open-folds'. Accepts COUNT for dictating fold level. + (evil-define-command narf:open-folds (count) + (interactive "P") + (if count (hs-hide-level count) (evil-open-folds))) + + ;; Instead of `evil-close-folds'. Accepts COUNT for dictating fold level. + (evil-define-command narf:close-folds (count) + (interactive "P") + (if count (hs-hide-level count) (evil-close-folds)))) + + (evil-select-search-module 'evil-search-module 'evil-search) + (setq evil-magic t + evil-want-C-u-scroll t ; enable C-u for scrolling + evil-ex-visual-char-range t ; column range for ex commands + evil-want-fine-undo nil + evil-want-visual-char-semi-exclusive nil + evil-ex-search-vim-style-regexp t + evil-ex-interactive-search-highlight 'selected-window + + ;; Color-coded state cursors + evil-normal-state-cursor '("white" box) + evil-emacs-state-cursor '("cyan" bar) + evil-insert-state-cursor '("white" bar) + evil-visual-state-cursor '("white" hollow) + evil-iedit-state-cursor '("orange" box)) + + (add-to-list 'evil-overriding-maps 'narf-mode-map) + (evil-mode 1) + + (defadvice evil-ex-hl-do-update-highlight (around evil-ex-hl-shut-up activate) + (ignore-errors ad-do-it)) + + ;; modes to map to different default states + (dolist (mode-map '((cider-repl-mode . emacs) + (comint-mode . emacs) + (fundamental-mode . normal) + (help-mode . normal) + (term-mode . emacs) + (message-mode . normal) + (compilation-mode . normal))) + (evil-set-initial-state `,(car mode-map) `,(cdr mode-map))) + + ;; Ace Jump + ;; https://github.com/winterTTr/ace-jump-mode/issues/23 + (evil-define-motion evil-ace-jump-two-chars-mode (count) + :type exclusive + :repeat abort + (evil-without-repeat + (evil-enclose-ace-jump-for-motion + (call-interactively 'ace-jump-two-chars-mode)))) + + (progn ; evil helpers + (defun evil-visual-line-state-p () + "Returns non-nil if in visual-line mode, nil otherwise." + (and (evil-visual-state-p) + (eq (evil-visual-type) 'line)))) + + (progn ; evil plugins + (use-package evil-anzu) + + (use-package evil-iedit-state + :functions (iedit-current-occurrence-string iedit-restrict-region) + :commands (evil-iedit-state evil-iedit-state/iedit-mode) + :config + (progn + (bind :map evil-iedit-state-map ; Don't interfere with evil-snipe + "s" nil + "S" nil) + (bind iedit + "V" 'evil-visual-line + "C" 'evil-iedit-state/substitute ; instead of s/S + "za" 'iedit-toggle-unmatched-lines-visible + + visual "SPC" (λ (if (iedit-current-occurrence-string) + (progn + (save-excursion (iedit-restrict-region (region-beginning) (region-end))) + (evil-previous-line) + (evil-iedit-state/iedit-mode)) + (call-interactively 'evil-ret)))))) + + + (use-package evil-search-highlight-persist + :config (global-evil-search-highlight-persist t)) + + (use-package evil-indent-textobject ; vii/vai/vaI + :commands (evil-indent-i-indent + evil-indent-a-indent + evil-indent-a-indent-lines) + :init + (bind :map evil-inner-text-objects-map + "i" 'evil-indent-i-indent + "i" 'evil-indent-a-indent + "I" 'evil-indent-a-indent-lines)) + + (use-package evil-ex-registers + :commands (evil-get-spec-register + evil-ex-paste-from-register)) + + (use-package evil-surround + :commands (global-evil-surround-mode + evil-surround-edit + evil-Surround-edit + evil-surround-region) + :config + (progn + (evil-define-motion evil-surround-line (count) + "Move COUNT - 1 lines down but return exclusive character motion." + :type exclusive + (let ((beg (line-beginning-position))) + (evil-line count) + (end-of-line) + (let ((range (evil-range beg (point) 'exclusive))) + (evil-expand-range range) + range))) + + ;; Escaped surround characters + (defun evil-surround-escaped () + (let* ((char (string (read-char "\\"))) + (pair (cond ((string-match "[]})[{(]" char) + (let ((-pair (cdr (assoc (string-to-char char) evil-surround-pairs-alist)))) + `(,(car -pair) . ,(cdr -pair)))) + (t + `(,char . ,char)))) + (format (if (sp-point-in-string) "\\\\%s" "\\%s"))) + (cons (format format (car pair)) + (format format (cdr pair))))) + + (global-evil-surround-mode 1) + + (push '(?\C-\[ . ("" . "")) evil-surround-pairs-alist))) + + (use-package evil-numbers + :commands (evil-numbers/inc-at-pt + evil-numbers/dec-at-pt)) + + (use-package evil-matchit + :commands (evilmi-jump-items global-evil-matchit-mode) + :config (global-evil-matchit-mode 1)) + + (use-package evil-commentary + :diminish evil-commentary-mode + :commands (evil-commentary + evil-commentary-mode + evil-commentary-yank + evil-commentary-line) + :config (evil-commentary-mode 1)) + + (use-package evil-jumper + :init (setq 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-exchange + :commands evil-exchange + :config + (defadvice evil-force-normal-state (before evil-esc-quit-exchange activate) + (when evil-exchange--overlays (evil-exchange-cancel)))) + + (use-package evil-visualstar + :commands (global-evil-visualstar-mode + evil-visualstar/begin-search + evil-visualstar/begin-search-forward + evil-visualstar/begin-search-backward) + :config + (progn + ;; I cut this down because the original visualstar wouldn't remember + ;; the last search if evil-search-module was 'evil-search. + (defun narf/evil-visualstar/begin-search (beg end direction) + (when (evil-visual-state-p) + (evil-exit-visual-state) + (let ((selection (regexp-quote (buffer-substring-no-properties beg end)))) + (setq isearch-forward direction) + (evil-search selection direction t)))) + (advice-add 'evil-visualstar/begin-search :override 'narf/evil-visualstar/begin-search) + (global-evil-visualstar-mode 1))) + + (use-package evil-snipe + :diminish evil-snipe-mode + :config + (progn + (setq evil-snipe-smart-case t + evil-snipe-scope 'line + evil-snipe-repeat-scope 'buffer + evil-snipe-override-evil-repeat-keys nil) + + (setq-default evil-snipe-symbol-groups + '((?\[ "[[{(]") + (?\] "[]})]"))) + + (evil-snipe-mode 1) + (evil-snipe-override-mode 1))) + + (use-package evil-space + :disabled t + :diminish (evil-space-mode . "_") + :config + (progn + (add-to-list 'evil-overriding-maps 'evil-space-mode-map) + + (evil-space-setup "/" "n" "N") + (evil-space-setup "?" "N" "n") + + (after "evil-numbers" + (let ((map (evil-get-auxiliary-keymap narf-mode-map 'normal))) + (evil-space-setup "g=" "g=" "g-" map) + (evil-space-setup "g-" "g-" "g=" map))) + + (after "evil-snipe" + (let ((map (evil-get-auxiliary-keymap evil-snipe-override-mode-map 'motion))) + (evil-space-setup "t" "C-;" "C-," map) + (evil-space-setup "f" "C-;" "C-," map) + (evil-space-setup "T" "C-," "C-;" map) + (evil-space-setup "F" "C-," "C-;" map)) + (let ((map (evil-get-auxiliary-keymap evil-snipe-mode-map 'motion))) + (evil-space-setup "s" "C-;" "C-," map) + (evil-space-setup "S" "C-," "C-;" map))) + + (after "evil-visualstar" + (let ((map (evil-get-auxiliary-keymap evil-visualstar-mode-map 'visual))) + (message "VISUALSTAR") + (evil-space-setup "*" "n" "N" map) + (evil-space-setup "#" "n" "N" map))) + + (evil-space-mode)))) + + (progn ; evil hacks + (defadvice evil-force-normal-state (before evil-esc-quit activate) + (ignore-errors + (popwin:close-popup-window) ; close popups, if any + (evil-search-highlight-persist-remove-all) ; turn off highlights + (evil-ex-nohighlight) + ;; Exit minibuffer if alive + (if (minibuffer-window-active-p (minibuffer-window)) + (narf/minibuffer-quit)))) + + ;; Jump to new splits + (defadvice evil-window-split (after evil-window-split-jump activate) + (evil-window-down 1)) + (defadvice evil-window-vsplit (after evil-window-vsplit-jump activate) + (evil-window-right 1)) + + (progn ; Restore vimmish ex-mode keymaps to isearch + (defun narf:isearch-delete-word () + (interactive) + (let ((num (length isearch-string)) + (string (s-reverse isearch-string))) + (when (string-match "[^a-zA-Z0-9]" string 1) + (setq num (match-beginning 0))) + (dotimes (i num) + (isearch-pop-state)) + (isearch-update))) + + (defun narf:isearch-delete-line () + (interactive) + (let ((num (length isearch-string))) + (dotimes (i num) (isearch-pop-state)) + (isearch-update))) + + (defun narf:isearch-paste-from-register (reg) + (interactive) + (let ((str (evil-get-register reg t))) + (when (> (length str) 0) + (isearch-yank-string str)))) + + (defun narf:isearch-paste-from-clipboard () + (interactive) + (narf:isearch-paste-from-register ?+)) + + ;; Hide keystroke display while isearch is active + (add-hook! 'isearch-mode-hook (setq echo-keystrokes 0)) + (add-hook! 'isearch-mode-end-hook (setq echo-keystrokes 0.02)) + + (bind :map isearch-mode-map + "C-r" nil + + "C-r %" (λ (narf:isearch-paste-from-register ?%)) + "C-r #" (λ (narf:isearch-paste-from-register ?#)) + "C-r /" (λ (narf:isearch-paste-from-register ?/)) + "C-r :" (λ (narf:isearch-paste-from-register ?:)) + "C-r ." (λ (narf:isearch-paste-from-register ?.)) + "C-r -" (λ (narf:isearch-paste-from-register ?-)) + "C-r _" (λ (narf:isearch-paste-from-register ?_)) + "C-r =" (λ (narf:isearch-paste-from-register ?=)) + "C-r +" 'narf:isearch-paste-from-clipboard + + "C-w" 'narf:isearch-delete-word + "C-u" 'narf:isearch-delete-line + "M-v" 'narf:isearch-paste-from-clipboard))))) + + +(provide 'core-evil) +;;; core-evil.el ends here diff --git a/core/core-linux.el b/core/core-linux.el new file mode 100644 index 000000000..6f8ca10e6 --- /dev/null +++ b/core/core-linux.el @@ -0,0 +1,4 @@ + +(provide 'core-linux) + +;; Nothing here yet diff --git a/core/core-osx.el b/core/core-osx.el new file mode 100644 index 000000000..d6b7d29ed --- /dev/null +++ b/core/core-osx.el @@ -0,0 +1,54 @@ +;; Mac-specific settings + +;; Use a shared clipboard +(setq x-select-enable-clipboard t + ;; Curse Lion and its sudden but inevitable fullscreen mode! + ns-use-native-fullscreen nil + ;; Don't open files from the workspace in a new frame + ns-pop-up-frames nil + ;; Prefixes: Command = M, Alt = A + mac-command-modifier 'meta + mac-option-modifier 'alt) + +;; fix emacs PATH on OSX (GUI only) +(when window-system + (setenv "SHELL" "/usr/local/bin/zsh") + (setenv "EMACS" "1") + + (defmacro narf/init-exec-path () + "Initialize shell path via `exec-path-from-shell'." + (require 'exec-path-from-shell) + (exec-path-from-shell-initialize) + `(setq exec-path ',exec-path)) + + (narf/init-exec-path)) + +(use-package applescript-mode + :mode "\\.applescript$") + +(use-package dash-at-point + :commands (dash-at-point dash-at-point-with-docset) + :config + (add-to-list 'dash-at-point-mode-alist + '(java-mode . "java,droid,javafx,grails,groovy,playjava,spring,cvj,processing,javadoc"))) + +(after "evil" + (when (featurep 'ns) + ;; On OSX, stop copying each visual state move to the clipboard: + ;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on + ;; Most of this code grokked from: + ;; http://stackoverflow.com/questions/15873346/elisp-rename-macro + (defadvice evil-visual-update-x-selection (around clobber-x-select-text activate) + (unless (featurep 'ns) ad-do-it)))) + +;; Send current file to OSX apps +(defun narf:osx-open-with (&optional app-name path) + (interactive) + (let* ((path (f-full (s-replace "'" "\\'" (or path (if (eq major-mode 'dired-mode) (dired-get-file-for-visit) (buffer-file-name)))))) + (command (concat "open " (when app-name (concat "-a " (shell-quote-argument app-name))) " '" path "'"))) + (message "Running: %s" command) + (shell-command command))) + + +(provide 'core-osx) +;;; core-osx.el ends here diff --git a/core/core-splash.el b/core/core-splash.el new file mode 100644 index 000000000..cf534026b --- /dev/null +++ b/core/core-splash.el @@ -0,0 +1,145 @@ + +(define-derived-mode narf-splash-mode special-mode "NARF" + "Splash screen for Narf emacs.") + +(defun narf/splash-init () + ) + +(defun narf/random-comeback () + (let ((replies '("I think so, Brain, but where are we going to find a duck and a hose at this hour?" + "I think so, but where will we find an open tattoo parlor at this time of night?" + "Wuh, I think so, Brain, but if we didn't have ears, we'd look like weasels." + "Uh... yeah, Brain, but where are we going to find rubber pants our size?" + "Uh, I think so, Brain, but balancing a family and a career ... ooh, it's all too much for me." + "Wuh, I think so, Brain, but isn't Regis Philbin already married?" + "Wuh, I think so, Brain, but burlap chafes me so." + "Sure, Brain, but how are we going to find chaps our size?" + "Uh, I think so, Brain, but we'll never get a monkey to use dental floss." + "Are you pondering cheesesticks?" + "Uh, I think so Brain, but this time, you wear the tutu." + "I think so, Brain, but culottes have a tendency to ride up so." + "I think so, Brain, but if we covered the world in salad dressing wouldn't the aspargus feel left out?" + "I think so, Brain, but if they called them 'Sad Meals', kids wouldn't buy them!" + "I think so, Brain, but me and Pippi Longstocking -- I mean, what would the children look like?" + "I think so, Brain, but what would Pippi Longstocking look like with her hair straight?" + "I think so, Brain, but this time you put the trousers on the chimp." + "Well, I think so, Brain, but I can't memorize a whole opera in Yiddish." + "I think so, Brain, but there's still a bug stuck in here from last time." + "Uh, I think so, Brain, but I get all clammy inside the tent." + "I think so, Brain, but I don't think Kaye Ballard's in the union." + "I think so, Brain, but, the Rockettes? I mean, it's mostly girls, isn't it?" + "I think so, Brain, but pants with horizontal stripes make me look chubby." + "Well, I think so -POIT- but where do you stick the feather and call it macaroni?" + "Well, I think so, Brain, but pantyhose are so uncomfortable in the summertime." + "Well, I think so, Brain, but it's a miracle that this one grew back." + "Well, I think so, Brain, but first you'd have to take that whole bridge apart, wouldn't you?" + "Well, I think so, Brain, but 'apply North Pole' to what?" + "I think so, Brain, but 'Snowball for Windows'?" + "Well, I think so, Brain, but snort no, no, it's too stupid!" + "Umm, I think so, Don Cerebro, but, umm, why would Sophia Loren do a musical?" + "Umm, I think so, Brain, but what if the chicken won't wear the nylons?" + "I think so, Brain, but isn't that why they invented tube socks?" + "Well, I think so Brain, but what if we stick to the seat covers?" + "I think so Brain, but if you replace the 'P' with an 'O', my name would be Oinky, wouldn't it?" + "Oooh, I think so Brain, but I think I'd rather eat the Macarena." + "Well, I think so hiccup, but Kevin Costner with an English accent?" + "I think so, Brain, but don't you need a swimming pool to play Marco Polo?" + "Well, I think so, Brain, but do I really need two tongues?" + "I think so, Brain, but we're already naked." + "Well, I think so, Brain, but if Jimmy cracks corn, and no one cares, why does he keep doing it?" + "I think so, Brain NARF, but don't camels spit a lot?" + "I think so, Brain, but how will we get a pair of Abe Vigoda's pants?" + "I think so, Brain, but Pete Rose? I mean, can we trust him?" + "I think so, Brain, but why would Peter Bogdanovich?" + "I think so, Brain, but isn't a cucumber that small called a gherkin?" + "I think so, Brain, but if we get Sam Spade, we'll never have any puppies." + "I think so, Larry, and um, Brain, but how can we get seven dwarves to shave their legs?" + "I think so, Brain, but calling it pu-pu platter? Huh, what were they thinking?" + "I think so, Brain, but how will we get the Spice Girls into the paella?" + "I think so, Brain, but if we give peas a chance, won't the lima beans feel left out?" + "I think so, Brain, but I am running for mayor of Donkeytown and Tuesdays are booked." + "I think so, Brain, but if we had a snowmobile, wouldn't it melt before summer?" + "I think so, Brain, but what kind of rides do they have in Fabioland?" + "I think so, Brain, but can the Gummi Worms really live in peace with the Marshmallow Chicks?" + "Wuh, I think so, Brain, but wouldn't anything lose its flavor on the bedpost overnight?" + "I think so, Brain, but three round meals a day wouldn't be as hard to swallow." + "I think so, Brain, but if the plural of mouse is mice, wouldn't the plural of spouse be spice?" + "Umm, I think so, Brain, but three men in a tub? Ooh, that's unsanitary!" + "Yes, but why does the chicken cross the road, huh, if not for love? I do not know." + "Wuh, I think so, Brain, but I prefer Space Jelly." + "Yes Brain, but if our knees bent the other way, how would we ride a bicycle?" + "Wuh, I think so, Brain, but how will we get three pink flamingos into one pair of Capri pants?" + "I think so, Brain, but Tuesday Weld isn't a complete sentence." + "I think so, Brain, but why would anyone want to see Snow White and the Seven Samurai?" + "I think so, Brain, but wouldn't mustard make it sting?" + "I think so, Brain, but can you use the word 'asphalt' in polite society?" + "I think so, Mr. Brain, but if the sun'll come out tomorrow, what's it doing right now?" + "I think so, Brain, but aren't we out of shaving cream?" + "Oh yes, Brain! Remind me to tape all our phone calls!" + "Um, I think so, Brain, but I hear Hillary is the jealous type." + "I think so, Brain, but Madonna's stock is sinking." + "I think so, Brain. But does 'Chunk o' Cheesy's' deliver packing material?" + "I think so, Brainwulf, but if we're Danish, where's the cream cheese? Narf!" + "I think so, Bwain, but I don't think newspaper will fit in my underoos." + "Uh, I think so, Brain--but after eating newspaper all day, do I really need the extra fiber?" + "I think so, Brain! But isn't a dreadlock hair extension awfully expensive?" + "I think so, Brain. But will anyone other than Eskimos buy blubber-flavored chewing gum?" + "I think so, Brain, but the ointment expired weeks ago!" + "Uh, I think so Brain, but how are we gonna teach a goat to dance with flippers on?" + "Wuhh... I think so, Brain! But let's use safflower oil this time! It's ever so much healthier!" + "Wuh... I think so, Brain. But Cream of Gorilla Soup—well, we'd have to sell it in awfully big cans, wouldn't we?" + "I think so, Brain. But if he left chocolate bullets instead of silver, they'd get all runny and gooey!" + "Yes, Brain, I think so, but do nuts go with pudding?" + "I think so, Brain, but a codpiece made from a real fish would get smelly after a while, wouldn’t it?" + "I think... so, Brain... *gag* ...but I didn't know Annette used peanut butter in that way." + "I think so, Brain, but do those roost in this neighborhood?" + "I think so, Brain, but is the world ready for angora bellbottoms? I mean I can see wearing them inside out, but that would--" + "I think so, Commander Brain from Outer Space! But do we have time to grease the rockets?" + "I think so, Doctor. But are these really the legs of a show girl?" + "Whuh... I think so, Brain. But this time I get to play the dishwasher repairman!" + "I think so, Brainius. But what if a sudden wind were to blow up my toga?" + "I think so, Brain. But Trojans won’t arrive on the scene for another 300 years." + "I think so, Brain... but where would a yak put PVC tubing?" + "Whuh... I think so, Brain, but... but if Charlton Heston doesn't eat Soylent Green, what will he eat?" + "I think so, Brain, but would Danish flies work just as well?" + "We think so, Brain! But dressing like twins is so tacky." + "I think so, Brain, but practicing docking procedures with a goat at zero G's—it's never been done!" + "I think so, Brain! But shouldn't we let the silk worms finish the boxer shorts before we put them on?" + "I think so, Brain! You draw the bath and I'll fetch the alka-seltzers and candles!" + "I think so, Brain. But the real trick will be getting Demi Moore out of the creamed corn!" + "Wuhhh... I think so, Brain, but if a ham can operate a radio, why can't a pig set a VCR?" + "I think so, Brain, you'd think [Lyndon Johnson would] have left room for baby-kissing, wouldn't you?" + "I think so, Brain! But won't Mr. Hoover notice a missing evening gown?" + "I think so, Brain! But what's the use of having a heart-shaped tattoo if it's going to be covered by hair?" + "I think so, Brain, but couldn't the constant use of a henna rinse lead to premature baldness?" + "I think so, Brain. Just make sure we don't swallow each other's bubbles!" + "I think so, Brain! But ruby-studded stockings would be mighty uncomfortable wouldn't they?" + "I think so, Brain, but if I have my portrait drawn, will we have time to make it to the lifeboats?" + "I think so, Brain! But is Chippendale's ready for 'The Full Pinky?'" + "I think so, Brain! But do I have what it take to be the 'Lord of the Dance'?" + "I think so, Brain! How much deeper would the ocean be if there weren't sponges down there?" + "Oh, I think so, Brain! But doing a clog dance in actual clogs will give me awful blisters." + "I think so, Brain, but nose rings are kinda passé by now." + "I think so, Brain, but where are we going to get a trained octopus at this time of night?" + "I think so, Brain! But no more eels in jelly for me, thanks—I like my gelatin after lunch." + "I think so, Brain, but I didn’t know 90210 was a real zip code! Will Tori be there?" + "I think so, Brain. But if Pinocchio were carved out of bacon it wouldn't be the same story, would it?" + "Um, I think so, Brain, but wasn't Dicky Ducky released on his own recognaissance?" + "I think so, Brain, but Pepper Ann makes me sneeze." + "I think so, Brain. But suppose we do the hokey pokey and turn ourselves around, is that what it's really all about?" + "I think so, Brain, but just how will we get the weasel to hold still?" + "I think so, Brain, but how are we going to get the bacon flavoring into the pencils?" + "I think so, Brain, but instant karma's always so lumpy." + ))) + (nth (random (length replies)) replies))) + +;; TODO: Move this to external file +(add-hook 'after-init-hook + (lambda () (setq initial-scratch-message + (format "\n\n\n\n NARF!\n Emacs: %s\n\n >> Loaded in %s\n >>> %s" + emacs-version + (emacs-init-time) + (narf/random-comeback))))) + +(provide 'core-splash) +;;; core-splash.el ends here diff --git a/core/core-ui.el b/core/core-ui.el new file mode 100644 index 000000000..a03b0d5da --- /dev/null +++ b/core/core-ui.el @@ -0,0 +1,217 @@ +;;; core-ui.el -- User interface layout & behavior + +(when (fboundp 'fringe-mode) (fringe-mode '(2 . 8))) + +;; theme and GUI elements are loaded in init.el early +(setq show-paren-delay 0) + +(global-hl-line-mode 1) ; do highlight line +(blink-cursor-mode 1) ; do blink cursor +(line-number-mode 1) ; do show line no in modeline +(column-number-mode 1) ; do show col no in modeline +(size-indication-mode 1) ; do show file size +(tooltip-mode -1) ; don't show tooltips + +;; 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 + visible-bell nil ; silence of the bells + use-dialog-box nil ; avoid GUI + redisplay-dont-pause t + ;; do not soft-wrap lines + truncate-lines t + truncate-partial-width-windows nil + indicate-buffer-boundaries nil + indicate-empty-lines nil + fringes-outside-margins t) + +(use-package nlinum + :commands nlinum-mode + :init + (progn + (defface linum '((t (:inherit default))) + "Face for line numbers" + :group 'nlinum-mode) + (defface linum-highlight-face '((t (:inherit linum))) + "Face for line highlights" + :group 'nlinum-mode) + + ;; Preset width nlinum + (add-hook! 'nlinum-mode-hook + (setq nlinum--width (length (number-to-string (count-lines (point-min) + (point-max)))))) + + ;; Highlight line number + (defvar narf--hl-nlinum-overlay nil) + (defvar narf--hl-nlinum-line nil) + (defun narf/nlinum-unhl-line () + (when narf--hl-nlinum-overlay + (let* ((ov narf--hl-nlinum-overlay) + (disp (get-text-property 0 'display (overlay-get ov 'before-string))) + (str (nth 1 disp))) + (put-text-property 0 (length str) 'face 'linum str) + (setq narf--hl-nlinum-overlay nil + narf--hl-nlinum-line nil)))) + + (defun narf/nlinum-hl-line (&optional line) + (let ((line-no (or line (line-number-at-pos (point))))) + (when (and nlinum-mode (not (eq line-no narf--hl-nlinum-line))) + (let* ((pbol (if line (save-excursion (goto-char (point-min)) + (forward-line line-no) + (point-at-bol)) + (point-at-bol))) + (peol (1+ pbol))) + ;; Handle EOF case + (when (>= peol (point-max)) + (setq peol (point-max))) + (jit-lock-fontify-now pbol peol) + (let* ((overlays (overlays-in pbol peol)) + (ov (-first (lambda (item) (overlay-get item 'nlinum)) overlays))) + (when ov + (narf/nlinum-unhl-line) + (let* ((disp (get-text-property 0 'display (overlay-get ov 'before-string))) + (str (nth 1 disp))) + (put-text-property 0 (length str) 'face 'linum-highlight-face str) + (put-text-property 0 (length str) 'face 'linum-highlight-face str) + (setq narf--hl-nlinum-overlay ov + narf--hl-nlinum-line line-no)))))))) + + (defun narf:nlinum-toggle () + (interactive) + (if nlinum-mode + (narf/nlinum-disable) + (narf/nlinum-enable))) + (defun narf/nlinum-enable () + (nlinum-mode +1) + (add-hook 'post-command-hook 'narf/nlinum-hl-line)) + (defun narf/nlinum-disable () + (nlinum-mode -1) + (remove-hook 'post-command-hook 'narf/nlinum-hl-line) + (narf/nlinum-unhl-line)) + + (add-hook 'prog-mode-hook 'narf/nlinum-enable) + (add-hook 'org-mode-hook 'narf/nlinum-disable)) + :config + (setq-default nlinum-format " %4d ")) + +(when window-system + (setq frame-title-format '(buffer-file-name "%f" ("%b"))) + (if (string-equal (system-name) "io") + (set-frame-size (selected-frame) 326 119))) + +(add-hook! 'after-init-hook + (defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate) + "Prevent annoying \"Active processes exist\" query when you quit Emacs." + (flet ((process-list ())) ad-do-it))) + + +;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;; +(use-package smart-mode-line + :config + (progn + (setq sml/no-confirm-load-theme t + sml/mode-width 'full + sml/extra-filler -7 + sml/show-remote nil + sml/modified-char "*" + sml/encoding-format nil + sml/replacer-regexp-list '(("^~/Dropbox/Projects/" "PROJECTS:") + ("^~/.emacs.d/" "EMACS.D:") + ("^~/Dropbox/notes/" "NOTES:") + ("^/usr/local/Cellar/" "HOMEBREW:")) + sml/pre-modes-separator " : " + sml/pre-minor-modes-separator " " + sml/pos-minor-modes-separator ": " + sml/numbers-separator "/" + sml/line-number-format "%3l" + sml/col-number-format "%2c") + + ;; Hide evil state indicator + (after "evil" (setq evil-mode-line-format nil)) + + (setq-default mode-line-misc-info + '((which-func-mode ("" which-func-format "")) + (global-mode-string ("" global-mode-string "")))) + + (sml/setup) + (sml/apply-theme 'respectful) + + ;; Hack modeline to be more vim-like, and right-aligned + (defun sml/generate-minor-modes () + (if sml/simplified + "" + (let* ((nameList (rm--mode-list-as-string-list)) + (last nil) + (concatList (mapconcat (lambda (mode) + (setq mode (s-trim mode)) + (if (> (length mode) 1) + (prog1 (concat (if last " ") mode " ") + (setq last nil)) + (prog1 mode + (setq last t)))) + nameList "")) + (size (sml/fill-width-available)) + (finalNameList concatList) + needs-removing filling) + (when (and sml/shorten-modes (> (length finalNameList) size)) + (setq needs-removing + (1+ (sml/count-occurrences-starting-at + " " finalNameList + (- size (string-width sml/full-mode-string)))))) + (when needs-removing + (setcdr (last nameList (1+ needs-removing)) + (list t sml/propertized-full-mode-string))) + (unless sml/shorten-modes + (add-to-list 'nameList sml/propertized-shorten-mode-string t)) + + ;; Padding + (setq filling (- size (+ (length (format-mode-line concatList)) (length mode-name) (length vc-mode)))) + (setq filling (make-string (max 0 filling) sml/fill-char)) + + (list (propertize filling 'face 'sml/modes) + (propertize (or vc-mode "") 'face 'sml/vc) + (propertize sml/pre-modes-separator 'face 'font-lock-comment-delimiter-face) + (propertize mode-name) + 'sml/pre-minor-modes-separator + concatList + (propertize sml/pos-minor-modes-separator 'face + 'font-lock-comment-delimiter-face))))) + + ;; Remove extra spaces in format lists + (pop mode-line-modes) + (nbutlast mode-line-modes) + + ;; Remove spacing in mode-line position so we can put it elsewhere + (setq mode-line-position + '((sml/position-percentage-format + (-3 (:propertize (:eval sml/position-percentage-format) + face sml/position-percentage help-echo "Buffer Relative Position\nmouse-1: Display Line and Column Mode Menu"))))) + + (after "anzu" + ;; Add small gap for anzu + (defun narf/anzu-update-mode-line (here total) + (concat (anzu--update-mode-line-default here total) " ")) + (setq anzu-mode-line-update-function 'narf/anzu-update-mode-line)) + + ;; Rearrange and cleanup + (setq-default mode-line-format + '("%e " + mode-line-mule-info + mode-line-client + mode-line-remote + mode-line-frame-identification + mode-line-buffer-identification + mode-line-modified + mode-line-misc-info + mode-line-modes + mode-line-front-space + mode-line-end-spaces + " " + ":" mode-line-position + )))) + + +(provide 'core-ui) +;;; core-ui.el ends here diff --git a/core/core.el b/core/core.el new file mode 100644 index 000000000..e8361ca88 --- /dev/null +++ b/core/core.el @@ -0,0 +1,320 @@ +;;; The core of Narfy Emacs +;; +;;; Naming Conventions +;; +;; narf/* public defun/variable +;; narf--* private defun/variable +;; narf|* hook defuns +;; narf:* interactive/keybind defuns +;; :* ex commands +;; + +(setq package-enable-at-startup nil + debug-on-quit DEBUG-MODE) +(cd "~") ; instead of / +(require 'core-splash) + +;; This is kept separate so it can jumpstart emacs; this prevents the unstyled +;; flash of emacs pre-makeover. +(load-theme (if window-system DEFAULT-THEME TERM-THEME) t) +(when window-system + (set-frame-font DEFAULT-FONT) + (scroll-bar-mode -1) ; no scrollbar + (tool-bar-mode -1) ; no toolbar + (menu-bar-mode -1)) ; no menubar + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(message ">> %s" "Are you pondering what I'm pondering, Pinky?") +(message "-----------------------------------------------------------------------------------") + +(defun display-startup-echo-area-message () + (message "-----------------------------------------------------------------------------------") + (message ">> %s\n>> Loaded in %s" (narf/random-comeback) (emacs-init-time))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defconst IS-MAC (eq system-type 'darwin)) +(defconst IS-LINUX (eq system-type 'gnu/linux)) +(defconst IS-WINDOWS (eq system-type 'windows-nt)) + +(require 'defuns) + +;; NARF! +(defvar narf-mode-map (make-sparse-keymap)) +(define-minor-mode narf-mode + "Narf, yoink, poit." + :global t :init-value t :lighter "NARF" :keymap narf-mode-map) + +(defvar narf/leader-key ",") +(defvar narf/localleader-key "\\") + +;; Make sure undo/backup folders exist +(defconst TMP-DIR-UNDO (expand-file-name "undo" TMP-DIR)) +(defconst TMP-DIR-BACKUP (expand-file-name "backup" TMP-DIR)) +(defconst TMP-DIR-AUTOSAVE (expand-file-name "autosave" TMP-DIR)) +(unless (file-directory-p TMP-DIR) + (make-directory TMP-DIR-UNDO t) + (make-directory TMP-DIR-BACKUP t) + (make-directory TMP-DIR-AUTOSAVE t)) + +(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no + +;;;; Sane defaults ;;;;;;;;;;;;;;;;;;;;;;; +(global-font-lock-mode t) ; Enable syntax highlighting for older emacs +(global-auto-revert-mode 1) ; revert buffers for changed files + + ;;; window layout undo/redo +(setq winner-boring-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*" + "*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*" + "*Buffer List*" "*Ibuffer*" "*esh command on file*")) +(winner-mode 1) + +;;; UTF-8 please +(setq locale-coding-system 'utf-8) ; pretty +(set-terminal-coding-system 'utf-8) ; pretty +(set-keyboard-coding-system 'utf-8) ; pretty +(set-selection-coding-system 'utf-8) ; please +(prefer-coding-system 'utf-8) ; with sugar on top + +;;; Show tab characters +;; (global-whitespace-mode 1) +(setq whitespace-style '(trailing face tabs tab-mark) ; needs to be re-set in every buffer + whitespace-display-mappings + '((tab-mark ?\t [?| ?\t] [?\\ ?\t]) + (newline-mark 10 [36 10]))) ; for whitespace-newline-mode + +;; avoid garbage collection (default is 400k) +(setq-default + gc-cons-threshold 20000000 + confirm-kill-emacs nil + ;; minibufferception? Yay! + enable-recursive-minibuffers t) + +;; Show me those keystrokes +(setq echo-keystrokes 0.02 + + ring-bell-function 'ignore + + inhibit-startup-screen t ; don't show EMACs start screen + inhibit-splash-screen t + ;; inhibit-startup-message t + inhibit-startup-echo-area-message "hlissner" + ;; inhibit-startup-buffer-menu t + + initial-major-mode 'text-mode ; initial scratch buffer mode + initial-scratch-message nil + + compilation-always-kill t + compilation-ask-about-save nil + compilation-scroll-output t + + sentence-end-double-space nil ; sentences end with periods. Period. + + ediff-diff-options "-w" + ediff-split-window-function 'split-window-horizontally ; side-by-side diffs + ediff-window-setup-function 'ediff-setup-windows-plain) ; no extra frames + +;; Don't save clipboard contents into kill-ring before replacing them +(setq save-interprogram-paste-before-kill nil) + +;; don't let the cursor go into minibuffer prompt +;; Tip taken from Xah Lee: http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html +(setq minibuffer-prompt-properties + '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)) + +;; remove annoying ellipsis when printing sexp in message buffer +(setq eval-expression-print-length nil + eval-expression-print-level nil) + +;; Save cursor location across sessions. Only save for files that exist. +(use-package saveplace + :init (defvar save-place-file (concat TMP-DIR "saveplace")) + :config (add-hook! 'find-file-hook (if (file-exists-p (buffer-file-name)) (setq save-place t)))) + +;; Save history across sessions +(use-package savehist + :config + (progn + (setq savehist-file (concat TMP-DIR "savehist") ; keep the home clean + history-length 1000 + savehist-additional-variables '(kill-ring + global-mark-ring + search-ring + regexp-search-ring + extended-command-history)) + (savehist-mode 1))) + +(use-package recentf + :config + (progn + (setq recentf-save-file (concat TMP-DIR "recentf") + recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$" + "/\\.cache/.+" "emacs\\.d/workgroups/.+$" ".emacs.workgroup" + "/company-statistics-cache.el$") + recentf-max-menu-items 0 + recentf-max-saved-items 250 + recentf-auto-cleanup 600) + (recentf-mode 1))) + + +;;;; Backup ;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Disable all backups (that's what git/dropbox are for) +(setq bookmark-save-flag t + bookmark-default-file (concat TMP-DIR "bookmarks") + auto-save-default nil + auto-save-list-file-name (concat TMP-DIR-AUTOSAVE "auto-save") + auto-save-file-name-transforms `((".*" ,TMP-DIR-AUTOSAVE t)) + ;; In case I want to reactivate backup files + make-backup-files nil + create-lockfiles nil + backup-directory-alist `((".*" . ,TMP-DIR-BACKUP))) + + +;;;; Undo Tree ;;;;;;;;;;;;;;;;;;;;;;;;; +(setq-default ; Remember undo history + undo-tree-auto-save-history t + undo-tree-history-directory-alist `(("." . ,TMP-DIR-UNDO))) + +;; Keep region when undoing in region +(defadvice undo-tree-undo (around keep-region activate) + (if (use-region-p) + (let ((m (set-marker (make-marker) (mark))) + (p (set-marker (make-marker) (point)))) + ad-do-it + (goto-char p) + (set-mark m) + (set-marker p nil) + (set-marker m nil)) + ad-do-it)) + +;; Shut up undo-tree's constant complaining: http://youtu.be/Z6woIRLnbmE +(defadvice undo-tree-load-history-hook (around undo-tree-load-history-shut-up activate) (shut-up ad-do-it)) +(defadvice undo-tree-save-history-hook (around undo-tree-save-history-shut-up activate) (shut-up ad-do-it)) +;; Silences an annoying error: undo-tree-mapc: Wrong type argument: listp, \.\.\. +(defadvice undo-tree-position (around undo-tree-position-silence-type-error activate) + (when (listp (ad-get-args 1)) ad-do-it)) + +;;;; Editor behavior ;;;;;;;;;;;;;;;; +(setq-default ; spaces instead of tabs + indent-tabs-mode nil + tab-always-indent t + tab-width 4) + +(setq require-final-newline t + delete-trailing-lines nil) + +;; Automatic minor modes ;;;;;;;;;;; +(defvar narf/auto-minor-mode-alist () + "Alist of filename patterns vs correpsonding minor mode functions, +see `auto-mode-alist' All elements of this alist are checked, meaning +you can enable multiple minor modes for the same regexp.") +(defun narf|enable-minor-mode-maybe () + "Check file name against `narf/auto-minor-mode-alist'." + (when buffer-file-name + (let ((name buffer-file-name) + (remote-id (file-remote-p buffer-file-name)) + (alist narf/auto-minor-mode-alist)) + ;; Remove backup-suffixes from file name. + (setq name (file-name-sans-versions name)) + ;; Remove remote file name identification. + (when (and (stringp remote-id) + (string-match-p (regexp-quote remote-id) name)) + (setq name (substring name (match-end 0)))) + (while (and alist (caar alist) (cdar alist)) + (if (string-match (caar alist) name) + (funcall (cdar alist) 1)) + (setq alist (cdr alist)))))) +(add-hook 'find-file-hook 'narf|enable-minor-mode-maybe) + + +;;;; Utility plugins ;;;;;;;;;;;;;;;;;; +(use-package smex + :functions (smex-initialize smex-update) + :commands (smex smex-major-mode-commands) + :config + (progn + (setq smex-save-file (expand-file-name "smex-items" TMP-DIR)) + (smex-initialize) + ;; Hook up smex to auto-update, rather than update on every run + (defun smex-update-after-load (unused) + (when (boundp 'smex-cache) (smex-update))) + (add-hook 'after-load-functions 'smex-update-after-load))) + +(use-package popwin + :config + (progn ; popwin config + (popwin-mode 1) + (setq popwin:popup-window-height 0.45 + popwin:special-display-config + (append '(("\\`\\*helm.*?\\*\\'" :regexp t :position bottom :height 15) + ("^\\*Flycheck.*\\*$" :regexp t :position bottom :height 0.25 :noselect t) + (inf-enh-ruby-mode :position bottom :stick t) + (snippet-mode :position bottom :stick t) + ("^\\*eclim.*\\*" :regexp t :position bottom :height 0.25) + ("*ansi-term*" :position bottom :height 0.45 :stick t) + ("*terminal*" :position bottom :height 0.45 :stick t) + ("*Async Shell Command*" :position bottom) + ("*Shell Command Output*" :position bottom :stick t :height 15) + ("* Regexp Explain *" :position top :height 0.35) + ("*anaconda-doc*" :position bottom :height 15 :noselect t) + ("*anaconda-nav*" :position bottom :height 15 :stick t) + ("^\\*Python.+\\*$" :regexp t :position bottom :height 20 :noselect t) + ("*Pp Eval Output*" :position bottom :height 10 :noselect t) + ("*eval*" :position bottom :noselect t) + (help-mode :height 25 :position bottom :stick t) + (compilation-mode :height 0.5 :position bottom :noselect t) + (diff-mode :position bottom :stick t) + ("*Backtrace*") + ("*Warnings*") + ("*Process List*") + ("*Compile-Log*" :height 0.3 :position bottom :noselect t) + (" *undo-tree*" :width 0.3 :position right) + ("^\\*scratch\\*.*" :regexp t :stick t) + (image-mode)) + popwin:special-display-config)) + + (defun popwin:toggle-popup-window () + (interactive) + (if (popwin:popup-window-live-p) + (popwin:close-popup-window) + (popwin:popup-last-buffer))))) + +(use-package semantic + :commands semantic-mode + :init + (progn + (add-hook 'c-mode-common-hook 'semantic-mode) + (defvar semanticdb-default-system-save-directory (concat TMP-DIR "semanticdb")) + (defvar semanticdb-default-save-directory (concat TMP-DIR "semanticdb"))) + :config + (semantic-mode 1)) + +;; Improved help commands +(use-package help-fns+ + :commands (describe-buffer + describe-command + describe-file + describe-keymap + describe-option + describe-option-of-type)) + +(use-package server + :config (unless (server-running-p) (server-start))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(cond (IS-MAC (require 'core-osx)) + (IS-LINUX (require 'core-linux)) + (IS-WINDOWS (require 'core-windows))) + +;; Performance checks +(add-hook! 'find-file-hook + ;; If file is oversized... + (when (> (buffer-size) (* 1024 1024)) + (setq buffer-read-only t) + (buffer-disable-undo) + (fundamental-mode) + (visual-line-mode))) + + +(provide 'core) +;;; core.el ends here diff --git a/core/defuns-buffers.el b/core/defuns-buffers.el new file mode 100644 index 000000000..e9e9eed83 --- /dev/null +++ b/core/defuns-buffers.el @@ -0,0 +1,289 @@ +;; Inspired by http://demonastery.org/2013/04/emacs-evil-narrow-region/ +;;;###autoload +(defun narf:narrow-to-region-indirect (start end) + "Restrict editing in this buffer to the current region, indirectly." + (interactive "r") + (deactivate-mark) + (let ((buf (clone-indirect-buffer nil nil))) + (with-current-buffer buf + (narrow-to-region start end)) + (switch-to-buffer buf))) + +;;;###autoload +(defun narf:widen () + (interactive) + (when (buffer-narrowed-p) + (widen))) + +;;;###autoload +(defun narf:set-region-read-only (begin end) + "See http://stackoverflow.com/questions/7410125" + (let ((modified (buffer-modified-p))) + (add-text-properties begin end '(read-only t)) + (set-buffer-modified-p modified))) + +;;;###autoload +(defun narf:set-region-writeable (begin end) + "See http://stackoverflow.com/questions/7410125" + (let ((modified (buffer-modified-p)) + (inhibit-read-only t)) + (remove-text-properties begin end '(read-only t)) + (set-buffer-modified-p modified))) + +;;;###autoload +(defun narf/living-buffer-list (&optional buffer-list) + (-remove 'get-buffer-window (or buffer-list (buffer-list)))) + + +;; Killing Buffers ;;;;;;;;;;;;;;;;;;;;; +;; Buffer defuns +(defvar narf/cleanup-buffers-list '("^ \\*" + "^\\*Backtrace\\*$" + "^\\*Warnings\\*$" + "^\\*Compile-Log\\*$" + "^\\*Ediff.*\\*$" + help-mode + image-mode + dired-mode + reb-mode) + "A list of buffer name regexps or major-mode symbols. If buried buffers + match/have that mode active, `narf:cleanup-buffers' will kill them.") + +(defvar narf/cleanup-processes-alist '(("pry" . ruby-mode) + ("irb" . ruby-mode) + ("ipython" . python-mode)) + "An alist of (process-name . major-mode), that `narf:cleanup-processes' checks +before killing processes. If there are no buffers with matching major-modes, it +gets killed.") + +;;;###autoload +(defun narf/add-throwaway-buffer (regexp) + (add-to-list 'narf/cleanup-buffers-list regexp)) + +;;;###autoload +(defun narf:cleanup-buffers () + "Kill left-over temporary, dired or buried special buffers" + (interactive) + (let* ((this-frame (selected-frame)) + (kill-list (buffer-list this-frame))) + (setq kill-list + (-filter (lambda (b) + (unless (get-buffer-window b) ; don't kill if visible + (-any? (lambda (pred) + (cond ((stringp pred) + (s-matches? pred (buffer-name b))) + ((symbolp pred) + (eq (buffer-local-value 'major-mode b) pred)))) + narf/cleanup-buffers-list))) + kill-list)) + (message "Cleaned up %s buffers" (length kill-list)) + (mapc 'kill-buffer kill-list) + (narf:cleanup-processes))) + +;;;###autoload +(defun narf:cleanup-processes () + (interactive) + (let ((buffer-list (buffer-list))) + (dolist (p (process-list)) + (let* ((process-name (process-name p)) + (assoc (assoc process-name narf/cleanup-processes-alist))) + (when (and assoc + (not (string= process-name "server")) + (process-live-p p) + (not (-any? (lambda (b) + (let ((mode (buffer-local-value 'major-mode b))) + (eq mode (cdr assoc)))) + buffer-list))) + (message "Cleanup: killing %s" process-name) + (delete-process p)))))) + +;;;###autoload +(defun narf:kill-matching-buffers (regexp &optional buffer-list) + (interactive) + (mapc (lambda (b) + (if (string-match-p regexp (buffer-name b)) + (kill-buffer b))) + (if buffer-list buffer-list (buffer-list)))) + +(defun narf--cycle-real-buffer (&optional n) + "Switch to the previous buffer and avoid special buffers." + (interactive) + (let ((start-buffer (current-buffer)) + (move-func (if (< n 0) 'switch-to-next-buffer 'switch-to-prev-buffer))) + (funcall move-func) + (let ((i 0)) + (while (let ((current-buffer (current-buffer))) + (and (not (eq current-buffer start-buffer)) + (not (eq current-buffer narf--project-scratch-buffer)) + (< i 15) + (string-equal "*" (substring (buffer-name) 0 1)))) + (cl-incf i) + (funcall move-func))))) + +;; From spacemacs +;;;###autoload +(defun narf:next-real-buffer () + "Switch to the next buffer and avoid special buffers." + (interactive) + (narf--cycle-real-buffer +1)) + +;;;###autoload +(defun narf:previous-real-buffer () + "Switch to the previous buffer and avoid special buffers." + (interactive) + (narf--cycle-real-buffer -1)) + +;;;###autoload +(defun narf:kill-real-buffer () + "Kill buffer (but only bury scratch buffer)" + (interactive) + (let ((bname (buffer-name))) + (cond ((string-match-p "^\\*scratch\\*" bname) + (erase-buffer) + (bury-buffer)) + ((string-equal "*" (substring bname 0 1)) + (previous-buffer)) + (t (kill-this-buffer))))) + +;;;###autoload (autoload 'narf::save-session "defuns-buffers") +(evil-define-command narf::save-session (&optional bang session-name) + (interactive "") + (if session-name + (wg-save-session-as (concat wg-workgroup-directory session-name) (not bang)) + (wg-save-session))) + +;;;###autoload (autoload 'narf::load-session "defuns-buffers") +(evil-define-command narf::load-session (&optional bang session-name) + (interactive "") + (wg-open-session (if session-name + (concat wg-workgroup-directory session-name) + wg-session-file))) + +;;;###autoload (autoload 'narf::new-workgroup "defuns-buffers") +(evil-define-command narf::new-workgroup (bang name) + (interactive "") + (unless name + (user-error "No name specified for new workgroup")) + (if bang + (wg-clone-workgroup (wg-current-workgroup) name) + (wg-create-workgroup name t))) + +;;;###autoload (autoload 'narf::rename-workgroup "defuns-buffers") +(evil-define-command narf::rename-workgroup (new-name) + (interactive "") + (wg-rename-workgroup new-name)) + +;;;###autoload (autoload 'narf::rename-this-file "defuns-buffers") +(evil-define-command narf::rename-this-file (new-name) + "Renames current buffer and file it is visiting. Replaces %, # and other + variables (see `evil-ex-replace-special-filenames')" + :repeat nil + (interactive "") + (let ((name (buffer-name)) + (filename (buffer-file-name))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (let ((new-name + (expand-file-name + (evil-ex-replace-special-filenames (if new-name + new-name + (read-file-name "New name: " filename))) + (f-dirname filename)))) + (if (get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name) + (rename-file filename new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + (set-buffer-modified-p nil) + (save-place-forget-unreadable-files) + (message "File '%s' successfully renamed to '%s'" + name (file-name-nondirectory new-name))))))) + +;;;###autoload (autoload 'narf::delete-this-file "defuns-buffers") +(evil-define-command narf::delete-this-file (&optional bang) + "Delete current buffer's file. If bang, then kill the buffer afterwards as well." + :repeat nil + (interactive "") + (let ((filename (file-truename (buffer-file-name)))) + (if (not (file-exists-p filename)) + (error "File doesn't exist: %s" filename) + (delete-file filename) + (when bang (kill-this-buffer)) + (save-place-forget-unreadable-files) + (message "File successfully deleted: %s" filename)))) + +(defun narf--save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit)) +;;;###autoload (autoload 'narf::create-file "defuns-buffers") +(evil-define-command narf::create-file (path &optional bang) + "Deploy files (and their associated templates) quickly. Will prompt +you to fill in each snippet field before buffer closes unless BANG is +provided." + :repeat nil + (interactive "") + (let ((dir (f-dirname path)) + (fullpath (f-full path)) + (is-auto t)) + (when (and bang (not (file-exists-p dir))) (f-mkdir dir)) + (if (file-exists-p dir) + (if (file-exists-p fullpath) + (error "File already exists: %s" path) + (find-file fullpath) + (add-hook 'yas-after-exit-snippet-hook 'narf--save-exit) + (if bang (--save-exit))) + (error "Directory doesn't exist: %s" dir)))) + +;;;###autoload (autoload 'narf::scratch-buffer "defuns-buffers") +(evil-define-operator narf::scratch-buffer (&optional beg end bang) + "Send a selection to the scratch buffer. If BANG, then send it to org-capture + instead." + :move-point nil + :type inclusive + (interactive "") + (let ((mode major-mode) + (text (when (and (evil-visual-state-p) beg end) + (buffer-substring beg end)))) + (if bang + ;; use org-capture with bang + (if text + (org-capture-string text) + (org-capture)) + ;; or scratch buffer by default + (let* ((project-dir (narf/project-root t)) + (buffer-name (if project-dir + (format "*scratch* (%s)" (narf/project-name)) + "*scratch*"))) + (popwin:popup-buffer (get-buffer-create buffer-name)) + (when (eq (get-buffer buffer-name) (current-buffer)) + (when project-dir + (cd project-dir)) + (if text (insert text)) + (funcall mode)))))) + +;;;###autoload (autoload 'narf::kill-buried-buffers "defuns-buffers") +(evil-define-command narf::kill-buried-buffers (&optional bang) + :repeat nil + (interactive "") + (mapc 'kill-buffer + (narf:living-buffer-list (if bang (projectile-project-buffers) (buffer-list))))) + +;;;###autoload (autoload 'narf::kill-buffers "defuns-buffers") +(evil-define-command narf::kill-buffers (&optional bang) + :repeat nil + (interactive "") + (if (and (not bang) (projectile-project-p)) + (projectile-kill-buffers) + (mapc 'kill-buffer (buffer-list))) + (delete-other-windows) + (switch-to-buffer (if (buffer-live-p narf--project-scratch-buffer) + narf--project-scratch-buffer + (get-buffer-create "*scratch*")))) + +;;;###autoload (autoload 'narf::cd "defuns-buffers") +(evil-define-command narf::cd (dir) + :repeat nil + (interactive "") + (cd (if (zerop (length dir)) "~" dir))) + + +(provide 'defuns-buffers) +;;; defuns-buffers.el ends here diff --git a/core/defuns-code.el b/core/defuns-code.el new file mode 100644 index 000000000..35f88ef7f --- /dev/null +++ b/core/defuns-code.el @@ -0,0 +1,83 @@ +;;;; Code building ;;;;;;;;;;;;;;;;;;;;;; +(defvar narf--build-command '("make %s" . "Makefile")) +(make-variable-buffer-local 'narf--build-command) + +;;;###autoload +(defun narf/set-build-command (command &optional file) + (when (or (null file) + (narf/project-has-files file)) + (setq narf--build-command `(,command . ,file)))) + +;;;###autoload (autoload 'narf::build "defuns-code") +(evil-define-command narf::build (arg) + "Call a build command in the current directory. +If ARG is nil this function calls `recompile', otherwise it calls +`compile' passing ARG as build command." + (interactive "") + (when (null narf--build-command) + (user-error "No build command was set")) + (let ((build-file (cdr narf--build-command)) + (build-cmd (car narf--build-command))) + (if (narf/project-has-files build-file) + (compile (format "cd '%s' && %s" build-file (format build-cmd (or arg "")))) + (error "Could not find Makefile")))) + + +;;;; Code running ;;;;;;;;;;;;;;;;;;;;;; +;;;###autoload (autoload 'narf::eval "defuns-code") +(evil-define-operator narf::eval () + :move-point nil + (interactive) + (cond ((region-active-p) + (narf::eval-region (region-beginning) (region-end))) + (t (narf::eval-buffer)))) + +;;;###autoload (autoload 'narf::eval-region "defuns-code") +(evil-define-operator narf::eval-region (beg end) + :move-point nil + (interactive "") + (cond ((eq major-mode 'emacs-lisp-mode) + (let* ((pp-escape-newlines nil) + (out (s-trim (pp-to-string (eval (read (buffer-substring-no-properties beg end)))))) + (lines (length (s-lines out)))) + (if (< lines 5) + (princ out t) + (let ((buf (get-buffer-create "*eval*"))) + (with-current-buffer buf + (read-only-mode -1) + (emacs-lisp-mode) + (setq-local scroll-margin 0) + (erase-buffer) + (insert out) + (beginning-of-buffer) + (read-only-mode 1) + (popwin:popup-buffer buf :height lines)))))) + (t (quickrun-region beg end)))) + +;;;###autoload (autoload 'narf::eval-buffer "defuns-code") +(evil-define-command narf::eval-buffer () + :move-point nil + (interactive) + (cond ((eq major-mode 'emacs-lisp-mode) + (narf::eval-region (point-min) (point-max))) + (t (quickrun)))) + +;;;###autoload (autoload 'narf::eval-region-and-replace "defuns-code") +(evil-define-operator narf::eval-region-and-replace (beg end) + (interactive "") + (cond ((eq major-mode 'emacs-lisp-mode) + (kill-region beg end) + (condition-case nil + (prin1 (eval (read (current-kill 0))) + (current-buffer)) + (error (message "Invalid expression") + (insert (current-kill 0))))) + (t (quickrun-replace-region beg end)))) + +;;;###autoload +(defun narf/get-interpreter () + (car (--first (eq (cdr it) major-mode) interpreter-mode-alist))) + + +(provide 'defuns-code) +;;; defuns-code.el ends here diff --git a/init/defuns-util.el b/core/defuns-debug.el similarity index 70% rename from init/defuns-util.el rename to core/defuns-debug.el index 5b1c125aa..00ce37777 100644 --- a/init/defuns-util.el +++ b/core/defuns-debug.el @@ -1,10 +1,3 @@ - -;; String Defuns ;;;;;;;;;;;;;;;;;;;;;;; -;;;###autoload -(defun s-count-lines (s) - "Get number of lines in a string" - (length (s-lines s))) - ;; Misc Defuns ;;;;;;;;;;;;;;;;;;;;;;;;; ;;;###autoload (defun what-face (pos) @@ -26,9 +19,12 @@ (local-key-binding key) (global-key-binding key))) -;;;###autoload -(defun echo (msg &rest args) +;;;###autoload (autoload 'narf::echo "defuns-debug") +(evil-define-command narf::echo (message) "Display MSG in echo-area without logging it in *Messages* buffer." - (interactive) - (let ((message-log-max nil)) - (apply 'message msg args))) + (interactive "") + (let (message-log-max) + (message "%s" message))) + + +(provide 'defuns-debug) diff --git a/core/defuns-edit.el b/core/defuns-edit.el new file mode 100644 index 000000000..3b307d6be --- /dev/null +++ b/core/defuns-edit.el @@ -0,0 +1,126 @@ +;;;; HTML ;;;; + +;;;###autoload +(defun narf:replace-ms-word-chars (beg end) + "Replace smart quotes and other MS Word verbiage into plain text" + (interactive "r") + (replace-regexp "…" "..." nil beg end) + (replace-regexp "[‘’]" "'" nil beg end) + (replace-regexp "[“”]" "\"" nil beg end)) + +;;;###autoload +(defun narf:replace-email2mailto (beg end) + "Email address with mailto link" + (interactive "r") + (replace-regexp "\\b\\([a-zA-Z0-9._+-%]+@[a-zA-Z0-9-.]+\\.[a-zA-Z]+\\)\\b" + "\\1" + nil beg end)) + +;;;###autoload +(defun narf:replace-url2anchor (beg end) + "Link with anchor" + (interactive "r") + (replace-regexp "\\bhttps?://.+?\\b" + "\\1" + nil beg end)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; A hacky attempt to replace ace-jump line mode that incrementally shows where +;; you will land as you type the line number. +(defun narf--goto-line (line) + (let ((lines (count-lines (point-min) (point-max)))) + (if (and (<= line (1+ lines)) + (> line 0)) + (narf/nlinum-hl-line line) + (narf/nlinum-hl-line)))) + +;;;###autoload +(defun narf:goto-line () + (interactive) + (let ((keys '()) + (orig-point (point)) + (echo-keystrokes 0)) + (evil-save-echo-area + (catch 'abort + (while t + (let* ((keystr (concat keys)) + (key (read-event (concat ":" keystr)))) + (cond ((eq key 'escape) + (message "%s" key) + (throw 'abort t)) + ((eq key 'return) + (when keys + (goto-line (string-to-number keystr))) + (throw 'abort t)) + ((eq key 'backspace) + (let ((key-len (length keys))) + (if (= key-len 0) + (throw 'abort t) + (if (> key-len 1) + (progn + (nbutlast keys) + (narf--goto-line (string-to-number (concat keys)))) + (setq keys '()) + (narf/nlinum-hl-line))))) + ((and (characterp key) + (s-numeric? (char-to-string key))) + (setq keys (append keys (list key))) + (narf--goto-line (string-to-number (concat keys)))) + (t + (if (or (char-equal key ?\C-n) + (char-equal key ?\C-j)) + (progn + (setq keys (number-to-string (1+ (string-to-number (concat keys))))) + (narf--goto-line (string-to-number (concat keys)))) + (when (or (char-equal key ?\C-p) + (char-equal key ?\C-k)) + (setq keys (number-to-string (1- (string-to-number (concat keys))))) + (narf--goto-line (string-to-number (concat keys))))))))))))) + +;;;###autoload (autoload 'narf::align "defuns-edit") +(evil-define-command narf::align (beg end &optional regexp bang) + :repeat nil + (interactive "") + (when regexp + (align-regexp beg end + (concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1))) + +;;;###autoload (autoload 'narf::retab "defuns-edit") +(evil-define-operator narf::retab (beg end) + "Akin to vim's narf::retab, this changes all tabs-to-spaces or spaces-to-tabs, + depending on `indent-tab-mode'. Untested." + :motion nil + :move-point nil + :type line + (interactive "") + (unless (and beg end) + (setq beg (point-min)) + (setq end (point-max))) + (if indent-tabs-mode + (tabify beg end) + (untabify beg end))) + +;;;###autoload (autoload 'narf::narrow-indirect-or-widen "defuns-edit") +(evil-define-operator narf::narrow-indirect-or-widen (beg end) + "Indirectly narrow the region from BEG to END." + :move-point nil + :type exclusive + :repeat nil + (interactive "") + (evil-normal-state) + (if (buffer-narrowed-p) + (narf:widen) + (narf:narrow-to-region-indirect beg end))) + +;;;###autoload +(defun narf:toggle-delete-trailing-whitespace () + (interactive) + (if (-contains-p before-save-hook 'delete-trailing-whitespace) + (progn (narf|disable-delete-trailing-whitespace) + (message "delete-trailing-whitespaces OFF")) + (add-hook 'before-save-hook 'delete-trailing-whitespace) + (message "delete-trailing-whitespaces ON"))) + + +(provide 'defuns-edit) +;;; defuns-edit.el ends here diff --git a/core/defuns-extern.el b/core/defuns-extern.el new file mode 100644 index 000000000..04089d412 --- /dev/null +++ b/core/defuns-extern.el @@ -0,0 +1,37 @@ +;;; defuns-extern.el -- for external operations + +;;;###autoload +(defun narf/tmux-send (command) + (shell-command (format "tmux send-keys %s" command))) + +(evil-define-interactive-code "" + "Ex tmux argument (a mix between and )" + :ex-arg shell + (list (when (evil-ex-p) (evil-ex-file-arg)))) + +;;;###autoload (autoload 'narf::tmux-run "defuns-extern") +(evil-define-command narf::tmux-run (&optional command bang) + "Sends input to tmux. Use `bang' to append to tmux" + (interactive "") + (nerf/tmux-send (format (if bang "C-u %s Enter" "%s") + (shell-quote-argument command))) + (when (evil-ex-p) + (message "[Tmux] %s" command))) + +;;;###autoload (autoload 'narf::tmux-chdir "defuns-extern") +(evil-define-command narf::tmux-chdir (&optional path bang) + "CDs in tmux using `narf/project-root'" + (interactive "") + (let ((dir (shell-quote-argument + (if (and path (not (s-blank? path))) + (if (file-directory-p path) + (file-truename path) + (error "Directory doesn't exist %s" path)) + (if bang default-directory (narf/project-root)))))) + (nerf/tmux-send (format "C-u cd Space %s Enter" (shell-quote-argument dir))) + (when (evil-ex-p) + (message "[Tmux] cd %s" dir)))) + + +(provide 'defuns-extern) +;;; defuns-extern.el ends here diff --git a/core/defuns-mouse.el b/core/defuns-mouse.el new file mode 100644 index 000000000..e622bea9f --- /dev/null +++ b/core/defuns-mouse.el @@ -0,0 +1,39 @@ +;;;###autoload +(defun narf/mouse-line-at-click () + "Determine the line number at click" + (save-excursion + (let ((click-y (cddr (mouse-position))) + (debug-on-error t) + (line-move-visual t)) + (goto-char (window-start)) + (next-line (1- click-y)) + (1+ (line-number-at-pos))))) + +;;;###autoload +(defun narf/mouse-select-line (event) + "Set point as *linum-mdown-line*" + (interactive "e") + (mouse-select-window event) + (goto-line (narf/mouse-line-at-click)) + (evil-visual-line) + (setq *linum-mdown-line* (line-number-at-pos))) + +;;;###autoload +(defun narf/mouse-select-block () + "Select the current block of text between blank lines." + (interactive) + (let (p1 p2) + (progn + (if (re-search-backward "\n[ \t]*\n" nil "move") + (progn (re-search-forward "\n[ \t]*\n") + (setq p1 (point))) + (setq p1 (point))) + (if (re-search-forward "\n[ \t]*\n" nil "move") + (progn (re-search-backward "\n[ \t]*\n") + (setq p2 (point))) + (setq p2 (point)))) + (set-mark p1))) + + +(provide 'defuns-mouse) +;;; defuns-mouse.el ends here diff --git a/core/defuns-org.el b/core/defuns-org.el new file mode 100644 index 000000000..f3f28ca1b --- /dev/null +++ b/core/defuns-org.el @@ -0,0 +1,92 @@ +;;;###autoload +(defun narf/project-org-filename (cat) + (interactive (list (completing-read "Choose category:" + (mapcar 'f-filename (f-directories org-project-directory))))) + (expand-file-name (concat (file-name-nondirectory (directory-file-name (narf/project-root))) ".org") + (expand-file-name cat org-project-directory))) + +;;;###autoload +(defun narf--org-in-list-p () + (and (save-excursion (search-backward-regexp "^ *\\([0-9]+[\.)]\\|[-*+]\\) " + (line-beginning-position) t)) + (org-in-item-p))) + +;;;###autoload +(defun narf/org-insert-item-after () + "Inserts a new heading or item, depending on the context." + (interactive) + (org-end-of-line) + (cond ((org-at-item-checkbox-p) + (org-insert-heading) + (insert "[ ] ")) + ((narf--org-in-list-p) + (org-insert-heading)) + ((org-on-heading-p) + (org-insert-heading-after-current)) + (t + (org-insert-heading-after-current) + (delete-char 1))) + (evil-insert-state)) + +;; TODO Check if this and -forward can be combined +;;;###autoload +(defun narf/org-insert-item-before () + "Inserts a new heading or item, depending on the context." + (interactive) + (evil-first-non-blank) + (cond ((org-at-item-checkbox-p) + (org-insert-heading) + (insert "[ ] ")) + ((narf--org-in-list-p) + (org-insert-heading)) + (t (org-insert-heading))) + (evil-insert-state)) + +;;;###autoload +(defun narf/org-toggle-checkbox () + (interactive) + (save-excursion + (org-end-of-line) + (cond ((org-in-item-p) + (if (search-backward-regexp "\\[[ +-]\\]" (line-beginning-position) t) + (delete-char 4) + (org-beginning-of-line))) + (t (org-insert-heading))) + (insert "[ ] "))) + +;; Formatting shortcuts +;;;###autoload +(defun narf/org-surround (delim) + (insert delim) (save-excursion (insert delim))) + +;;;###autoload (autoload 'narf::org-insert-image-url "defuns-org") +(evil-define-command narf::org-insert-image-url (&optional image-url) + :repeat nil + (interactive "") + (unless image-url + (user-error "You must specify an image URL to insert")) + (let ((dest (f-join org-directory "images/" (concat (format-time-string "%Y%m%d-") (f-filename image-url))))) + (shell-command (format "wget '%s' -O '%s'" image-url dest)) + (insert (format "<%s>" (f-relative dest (f-dirname (buffer-file-name))))) + (indent-according-to-mode))) + +;;;###autoload (autoload 'narf::org-insert-image "defuns-org") +(evil-define-command narf::org-insert-image (&optional filename bang) + :repeat nil + (interactive "") + (if bang + (narf::org-insert-image-url filename) + (unless filename + (user-error "You must specify a file to attach")) + (unless (file-exists-p filename) + (user-error "File %s does not exist" filename)) + (let ((dest (f-join org-directory "images/" (concat (format-time-string "%Y%m%d-") (f-filename filename))))) + (when (file-exists-p dest) + (user-error "File %s already exists at destination!")) + (copy-file filename dest) + (insert (format "" (f-relative dest (f-dirname (buffer-file-name))))) + (indent-according-to-mode)))) + + +(provide 'defuns-org) +;;; defuns-org.el ends here diff --git a/core/defuns-search.el b/core/defuns-search.el new file mode 100644 index 000000000..4f13e6a7d --- /dev/null +++ b/core/defuns-search.el @@ -0,0 +1,106 @@ +;;;###autoload +(defun narf:ido-find-file (&optional dir) + (interactive) + (let ((default-directory (or dir default-directory))) + (ido-find-file))) + +;;;###autoload +(defun narf:ido-find-file-other-window (&optional dir) + (interactive) + (let ((default-directory (or dir default-directory))) + (ido-find-file-other-window))) + +;;;###autoload +(defun narf:ido-find-project-file () + (interactive) + (let ((default-directory (narf/project-root))) + (ido-find-file))) + +;;;###autoload (autoload 'narf::initfiles "defuns-search") +(evil-define-command narf::initfiles (&optional bang) :repeat nil + (interactive "") + (if bang + (ido-find-file-in-dir MODULES-DIR) + (ido-find-file-in-dir BASE-DIR))) + +;;;###autoload (autoload 'narf::notes "defuns-search") +(evil-define-command narf::notes () :repeat nil + (interactive) + (require 'org) + (ido-find-file-in-dir org-directory)) + +;; Ex-mode interface for `helm-recentf' and `helm-projectile-recentf'. If +;; `bang', then `search' is interpreted as regexp +;;;###autoload (autoload 'narf::recentf "defuns-search") +(evil-define-command narf::recentf (&optional bang) + :repeat nil + (interactive "") + (if bang (helm-recentf) (helm-projectile-recentf))) + +;; Ex-mode interface for `helm-ag'. If `bang', then `search' is interpreted as +;; regexp. +;;;###autoload (autoload 'narf::ag-search "defuns-search") +(evil-define-operator narf::ag-search (beg end &optional search hidden-files-p pwd-p regex-p) + :type inclusive + :repeat nil + (interactive "") + (helm-alive-p) + (let* ((helm-ag-default-directory (if pwd-p default-directory (narf/project-root))) + (helm-ag-command-option (concat (unless regex-p "-Q ") + (if hidden-files-p "--hidden "))) + (input "") + (header-name (format "Search in %s" helm-ag-default-directory))) + (if search + (progn + (helm-attrset 'search-this-file nil helm-ag-source) + (setq helm-ag--last-query search)) + (if (and beg end (/= beg (1- end))) + (setq input (buffer-substring-no-properties beg end)))) + (helm-attrset 'name header-name helm-ag-source) + (helm :sources (if search (helm-ag--select-source) '(helm-source-do-ag)) + :buffer "*helm-ag*" + :input input + :prompt helm-global-prompt))) + +;;;###autoload (autoload 'narf::ag-regex-search "defuns-search") +(evil-define-operator narf::ag-regex-search (beg end &optional search bang) + :type inclusive :repeat nil + (interactive "") + (narf::ag-search beg end search bang nil t)) + +;;;###autoload (autoload 'narf::ag-regex-cwd "defuns-search") +(evil-define-operator narf::ag-search-cwd (beg end &optional search bang) + ;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted + ;; as regexp + :type inclusive :repeat nil + (interactive "") + (narf::ag-search beg end search bang t nil)) + +;;;###autoload (autoload 'narf::ag-regex-search-cwd "defuns-search") +(evil-define-operator narf::ag-regex-search-cwd (beg end &optional search bang) + :type inclusive :repeat nil + (interactive "") + (narf::ag-search beg end search bang t t)) + +;; Ex-mode interface for `helm-swoop', `helm-multi-swoop-all' (if `bang'), or +;; `helm-css-scss' and `helm-css-scss-multi' (if `bang') if major-mode is +;; `scss-mode' +;;;###autoload (autoload 'narf::swoop "defuns-search") +(evil-define-command narf::swoop (&optional search bang) + :repeat nil + (interactive "") + (if (eq major-mode 'scss-mode) + (if bang (helm-css-scss-multi search) (helm-css-scss search)) + (if bang (helm-multi-swoop-all search) (helm-swoop :$query search)))) + +;; TODO: Implement helm-find-file +;;;###autoload (autoload 'narf::snippets "defuns-search") +(evil-define-command narf::snippets (&optional bang) + (interactive "") + (if bang + (narf:ido-find-file SNIPPETS-DIR) + (helm-yas-visit-snippet-file))) + + +(provide 'defuns-search) +;;; defuns-search.el ends here diff --git a/init/defuns-text.el b/core/defuns-text.el similarity index 81% rename from init/defuns-text.el rename to core/defuns-text.el index 698358c7a..a781ce4f8 100644 --- a/init/defuns-text.el +++ b/core/defuns-text.el @@ -1,16 +1,16 @@ ;;;###autoload -(defun my--point-at-bol-non-blank() +(defun narf--point-at-bol-non-blank() (save-excursion (evil-first-non-blank) (point))) ;;;###autoload -(defun my--surrounded-p () +(defun narf/surrounded-p () (and (looking-back "[[{(]\\(\s+\\|\n\\)?\\(\s\\|\t\\)*") (let* ((whitespace (match-string 1)) (match-str (concat whitespace (match-string 2) "[])}]"))) (looking-at-p match-str)))) ;;;###autoload -(defun my.backward-kill-to-bol-and-indent () +(defun narf:backward-kill-to-bol-and-indent () "Kill line to the first non-blank character. If invoked again afterwards, kill line to column 1." (interactive) @@ -20,12 +20,12 @@ afterwards, kill line to column 1." (indent-according-to-mode)))) ;;;###autoload -(defun my.move-to-bol () +(defun narf:move-to-bol () "Moves cursor to the first non-blank character on the line. If already there, move it to the true bol." (interactive) (evil-save-goal-column - (let ((point-at-bol (my--point-at-bol-non-blank)) + (let ((point-at-bol (narf--point-at-bol-non-blank)) (point (point))) (if (= point-at-bol point) (evil-move-beginning-of-line) @@ -33,20 +33,20 @@ already there, move it to the true bol." (evil-first-non-blank)))))) ;;;###autoload -(defun my.move-to-eol () +(defun narf:move-to-eol () (interactive) (evil-save-goal-column (let ((old-point (point))) (when (comment-search-forward (point-at-eol) t) (goto-char (match-beginning 0)) - (skip-syntax-backward " ^<*" (my--point-at-bol-non-blank)) + (skip-syntax-backward " ^<*" (narf--point-at-bol-non-blank)) (if (eq old-point (point)) ; (evil-move-end-of-line)))))) ;; Mimic expandtab in vim ;;;###autoload -(defun my.backward-delete-whitespace-to-column () +(defun narf:backward-delete-whitespace-to-column () "Delete back to the previous column of whitespace, or as much whitespace as possible, or just one char if that's not possible." (interactive) @@ -67,14 +67,13 @@ whitespace as possible, or just one char if that's not possible." (save-match-data (if (string-match "\\w*\\(\\s-+\\)$" (buffer-substring-no-properties (- p movement) p)) - (backward-delete-char (- (match-end 1) (match-beginning 1))) + (sp-backward-delete-char (- (match-end 1) (match-beginning 1))) (backward-delete-char-untabify 1))))) ;; Otherwise do a regular delete - (t - (backward-delete-char-untabify 1)))) + (t (backward-delete-char-untabify 1)))) ;;;###autoload -(defun my.dumb-indent () +(defun narf:dumb-indent () "Inserts a tab character (or spaces x tab-width). Checks if the auto-complete window is open." (interactive) @@ -85,36 +84,36 @@ auto-complete window is open." (insert (s-repeat spaces " "))))) ;;;###autoload -(defun my.inflate-space-maybe () +(defun narf: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) + (if (narf/surrounded-p) (progn (call-interactively 'self-insert-command) (save-excursion (call-interactively 'self-insert-command))) (call-interactively 'self-insert-command))) ;;;###autoload -(defun my.deflate-space-maybe () +(defun narf:deflate-space-maybe () "Checks if point is surrounded by {} [] () delimiters, and deletes spaces on either side of the point if so. Resorts to -`my.backward-delete-whitespace-to-column' otherwise." +`narf:backward-delete-whitespace-to-column' otherwise." (interactive) (save-match-data - (if (my--surrounded-p) + (if (narf/surrounded-p) (let ((whitespace-match (match-string 1))) (cond ((not whitespace-match) - (call-interactively 'delete-backward-char)) + (call-interactively 'sp-backward-delete-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)))) + (narf:backward-delete-whitespace-to-column)))) ;;;###autoload -(defun my.newline-and-indent () +(defun narf:newline-and-indent () (interactive) (cond ((sp-point-in-string) @@ -130,3 +129,7 @@ spaces on either side of the point if so. Resorts to (indent-according-to-mode)) (t (indent-new-comment-line)))) (t (newline-and-indent)))) + + +(provide 'defuns-text) +;;; defuns-text.el ends here diff --git a/core/defuns-ui.el b/core/defuns-ui.el new file mode 100644 index 000000000..cdd43943b --- /dev/null +++ b/core/defuns-ui.el @@ -0,0 +1,27 @@ +(eval-when-compile (require 'cl)) + +;;;###autoload +(defun narf:toggle-transparency () + (interactive) + (let* ((alpha (frame-parameter nil 'alpha)) + (alpha-val (if (listp alpha) (car alpha) alpha))) + (if (/= alpha-val 97) + (set-frame-parameter nil 'alpha 100) + (set-frame-parameter nil 'alpha 0)))) + +;;;###autoload +(defun narf:toggle-fullscreen () + (interactive) + (set-frame-parameter nil 'fullscreen + (when (not (frame-parameter nil 'fullscreen)) 'fullboth))) + +(defconst BIG-FONT (font-spec :family "Inconsolata" :size 18 :antialias t)) +(defvar narf--big-mode nil) + +;;;###autoload +(defun narf:toggle-big-mode () + (interactive) + (if narf--big-mode + (set-frame-font DEFAULT-FONT) + (set-frame-font BIG-FONT)) + (setq narf--big-mode (not narf--big-mode))) diff --git a/core/defuns.el b/core/defuns.el new file mode 100644 index 000000000..acdbe47ea --- /dev/null +++ b/core/defuns.el @@ -0,0 +1,299 @@ +(require 's) +(require 'dash) +(require 'f) + +;; Compatibility ;;;;;;;;;;;;;;;;;;; +;; Backwards compatible `with-eval-after-load' +(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) + (declare (indent defun)) + `(,(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))) + +(defmacro shut-up (&rest body) + "Silence message output from code." + (declare (indent defun)) + `(let (message-log-max) + ,@body + (message ""))) + +(eval-when-compile + ;; Convenience ;;;;;;;;;;;;;;;;;;;;; + (defmacro λ (&rest body) + "A shortcut for: `(lambda () (interactive) ,@body)" + `(lambda () (interactive) ,@body)) + + (defmacro associate-mode (match mode) + "Associate a major mode with a filepath through `auto-mode-alist'" + `(add-to-list 'auto-mode-alist (cons ,match ,mode))) + + (defmacro associate-minor-mode (match mode) + "Associate a minor mode with a filepath through `auto-minor-mode-alist'" + `(add-to-list 'narf/auto-minor-mode-alist (cons ,match ,mode))) + + ;; (defmacro add-to-mode (mode funcs)) + ;; (defmacro add-to-modes (func modes) + ;; (add-to-hooks)) + + (defmacro add-to-hook (hook funcs) + "Add a series of FUNCS to a hook. FUNCS can be a list." + (declare (indent 1)) + `(progn ,@(mapcar (lambda (func) `(add-hook ',(eval hook) ',func)) (eval funcs)))) + + (defmacro add-to-hooks (func hooks) + "Add one FUNC to a series of hooks. HOOKS can be a list." + (declare (indent 1)) + `(progn ,@(mapcar (lambda (hook) `(add-hook ',hook ',(eval func))) (eval hooks)))) + + (defmacro add-hook! (hook &rest body) + "A shortcut macro for `add-hook' that auto-wraps `body' in a lambda" + (declare (indent defun)) + `(add-hook ,hook (lambda() ,@body))) + + ;; Keybindings ;;;;;;;;;;;;;;;;;;;;;;;;; + (after "evil" + (defmacro excmd (command func) + "An alternative to `evil-ex-define-cmd' that won't choke on autoload +functions being registered as ex commands." + `(evil-ex-define-cmd ,command ,func)) + + (defmacro excmd! (command func) + `(evil-ex-define-cmd ,command (lambda () (interactive) (call-interactively ,func)))) + + (defmacro bind (&rest keys) + "A minimalistic and evil-centric way of binding keys. KEYS is +made up of either: + +1. Any of the following keywords: + +:if CONDITION Determines where these keymaps should be set. +:prefix PREFIX Key(s) to prefix keymappings with +:map KEYMAP Keymaps to bind keys to. Can be a list. +:global Tags these keymaps for the global keymap +:local Ditto, but for local keymap +:leader Like :prefix ?, +:localleader Like :prefix ?\\ +: e.g. :normal ;visual and so on. Anything that + `evil-state-p' recognizes You can stack to + make a key present in more than one state. + +2. A key (as a vector e.g. [escape], a string \"\", or +character ?\^?). + +3. A key definition: a symbol or a lambda function. " + (declare (indent 9999)) + (let* ((condition t) + (default-keymaps '(narf-mode-map)) + (keymaps default-keymaps) + (forms '()) + (consecutive t) + (states '()) + prefix local-p + key def) + (while keys + (setq key (pop keys)) + (cond ((or (evil-state-p key) + (and (listp key) + (--all? (evil-state-p it) key))) + (setq states (-list key))) + + ((keywordp key) + (cl-case key + (:prefix + (let ((val (pop keys))) + (cond ((or (stringp val) + (characterp val) + (vectorp val)) + (setq prefix val)) + ((eq val 'leader) + (setq prefix narf/leader-key)) + ((eq val 'localleader) + (setq prefix narf/localleader-key)) + (t (signal 'bind-invalid-prefix prefix))))) + (:map + (let ((val (pop keys))) + (cond ((or (symbolp val) (listp val)) + (setq keymaps (-list val))) + ((null val) + (setq keymaps default-keymaps)) + (t (signal 'bind-invalid-keymaps '(key val)))))) + (:if (setq condition (pop keys))) + (:local (setq local-p (pop keys))) + ;; TODO: Deprecated + (otherwise + (let ((keyword (intern-soft (substring (symbol-name key) 1))) + (next-key (cadr keys))) + (when (evil-state-p keyword) + (setq local-p nil) + (if consecutive + (cl-pushnew keyword states) + (setq states (list keyword)))) + (setq consecutive t))))) + + ;; key-definition pairs + ((or (stringp key) + (vectorp key) + (characterp key)) + (unless keys (signal 'bind-no-definition key)) + (setq def (pop keys)) + (when condition + ;; Process the key + (cond ((stringp key) (setq key (kbd key))) + ((characterp key) (setq key (string key)))) + (when prefix + (setq key (if (vectorp key) + (vconcat prefix key) + (concat (kbd prefix) key)))) + ;; Do the binding + (if (null states) + (dolist (keymap keymaps) + (add-to-list 'forms `(define-key ,keymap ,key ,def) t)) + (dolist (state (-list states)) + (when local-p + (setq keymaps (list (make-symbol (format "evil-%s-state-local-mode-map" state))))) + (dolist (keymap keymaps) + (add-to-list 'forms `(define-key ,(if local-p keymap `(evil-get-auxiliary-keymap ,keymap ',state t)) ,key ,def) t))))) + (setq consecutive nil)) + + ;; fallback + (t (signal 'bind-invalid-key key)))) + (when DEBUG-MODE (message "%s" forms)) + `(progn ,@forms))))) + +(after "evil" + (evil-define-command narf:exit-mode-maybe () + "Exits insert mode using jk without the momentary pause caused by +key-chord-define." + :repeat change + (interactive) + (let ((modified (buffer-modified-p))) + (call-interactively 'self-insert-command) + (let ((evt (read-event nil nil 0.4))) + (cond + ((null evt) (message "")) + ((and (integerp evt) (char-equal evt ?k)) + + (if (evil-replace-state-p) + (evil-replace-backspace) + (delete-char -1)) + (set-buffer-modified-p modified) + (push 'escape unread-command-events)) + (t + (setq unread-command-events (append unread-command-events (list evt))))))))) + +;; Hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun narf|enable-comment-hard-wrap () + (set (make-local-variable 'comment-auto-fill-only-comments) t) + (turn-on-auto-fill)) + +(defun narf|enable-hard-wrap () + (turn-on-auto-fill)) + +(defun narf|enable-tab-width-2 () + (setq tab-width 2 evil-shift-width 2)) + +(defun narf|enable-tab-width-4 () + (setq tab-width 4 evil-shift-width 4)) + +(defun narf|disable-final-newline () + (set (make-local-variable 'require-final-newline) nil)) + +(defun narf|enable-tabs () + (setq indent-tabs-mode t)) + +(defun narf|disable-tabs () + (setq indent-tabs-mode nil)) + +(defun narf|disable-delete-trailing-whitespace () + (remove-hook 'before-save-hook 'delete-trailing-whitespace)) + + +;;;; Global Defuns ;;;;;;;;;;;;;;;;;;;;; +(defun narf/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) + (let (message-log-max) + (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)))) + + +;;;; Project defuns ;;;;;;;;;;;;;;;;;;;; +(defvar narf/project-root-files '(".git" ".hg" ".svn" ".project" "local.properties" "project.properties" "rebar.config" "project.clj" "SConstruct" "pom.xml" "build.sbt" "build.gradle" "Gemfile" "requirements.txt" "tox.ini" "package.json" "gulpfile.js" "Gruntfile.js" "bower.json" "composer.json" "Cargo.toml" "mix.exs") + "A list of files that count as 'project files', which determine whether a + folder is the root of a project or not.") +(defun narf/project-root (&optional strict-p) + "Get the path to the root of your project. Uses `narf/project-root-files' to +determine if a directory is a project." + (let ((home (file-truename "~"))) + (catch 'found + (f-traverse-upwards + (lambda (path) + (let ((path (file-truename path))) + (if (file-equal-p home path) + (throw 'found (if strict-p nil default-directory)) + (dolist (file narf/project-root-files) + (when (file-exists-p (expand-file-name file path)) + (throw 'found path)))))) default-directory) + default-directory))) + +(defun narf/project-has-files (files &optional root) + "Return non-nil if `file' exists in the project root." + (let ((root (or root (narf/project-root))) + (files (if (listp files) files (list files))) + found-p file) + (while (and files (not found-p)) + (setq file (pop files)) + (setq found-p (file-exists-p (narf/project-path-to file root)))) + found-p)) + +(defun narf/project-path-to (file &optional root) + (let ((root (or root (narf/project-root)))) + (expand-file-name file root))) + +(defun narf/project-name (&optional root) + (file-name-nondirectory (directory-file-name (or root (narf/project-root))))) + +(defun narf/project-p () + (not (null (narf/project-root t)))) + +;; Make sure scratch buffer is always "in a project" +(defvar narf--project-scratch-buffer nil) +(defun narf/project-create-scratch-buffer () + (let* ((scratch-buffer (get-buffer-create "*scratch*")) + (root (narf/project-root t)) + (project-name (narf/project-name root)) + (current-buffer (current-buffer))) + (when root + (mapc (lambda (b) + (when (and (string-match-p "\\*scratch\\* (.+)" (buffer-name b)) + (not (eq current-buffer b)) + (= (buffer-size b) 0)) + (kill-buffer b))) + (buffer-list)) + (save-window-excursion + (switch-to-buffer scratch-buffer) + (setq narf--project-scratch-buffer scratch-buffer) + (erase-buffer) + (cd root) + (rename-buffer (format "*scratch* (%s)" project-name)))))) +(add-hook 'find-file-hook 'narf/project-create-scratch-buffer) + + +(provide 'defuns) +;; defuns.el ends here diff --git a/core/startup.el b/core/startup.el new file mode 100644 index 000000000..dd8cf43d9 --- /dev/null +++ b/core/startup.el @@ -0,0 +1,39 @@ +(defconst BASE-DIR user-emacs-directory) + +(defconst CORE-DIR (eval-when-compile (concat BASE-DIR "core/"))) +(defconst MODULES-DIR (eval-when-compile (concat BASE-DIR "init/"))) +(defconst CONTRIB-DIR (eval-when-compile (concat BASE-DIR "contrib/"))) +(defconst THEMES-DIR (eval-when-compile (concat BASE-DIR "themes/"))) +(defconst SNIPPETS-DIR (eval-when-compile (concat BASE-DIR "snippets/"))) +(defconst ELPA-DIR (eval-when-compile (concat BASE-DIR ".cask/" emacs-version "/elpa/"))) +(defconst TMP-DIR (eval-when-compile (concat BASE-DIR ".cache-" (system-name) "/"))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(eval-when-compile + (defmacro narf/init-load-path () + "Collect and verify `load-path'. Compile me!" + (let (paths '()) + (dolist (dir (append (directory-files CONTRIB-DIR t "^[^.]" t) + (directory-files ELPA-DIR t "^[^.]" t))) + (when (file-directory-p dir) + (push dir paths))) + `(setq load-path ',(append (list CORE-DIR MODULES-DIR CONTRIB-DIR) + (if (listp load-path) load-path (list load-path)) + paths)))) + + ;; Are you pondering what I'm pondering? + (defmacro narf/init (packages) + `(progn ,@(mapcar (lambda (pkg) `(require ',pkg)) (eval packages))))) + +(narf/init-load-path) +;; (require 'benchmark) +(require 'autoloads nil t) ; use `make autoloads` to generate autoloads file + +(setq custom-theme-directory THEMES-DIR) +(setq use-package-verbose DEBUG-MODE) +(setq use-package-expand-minimally (not DEBUG-MODE)) +(eval-when-compile (require 'use-package)) +(require 'diminish) + +;;; startup.el ends here diff --git a/init/core-editor.el b/init/core-editor.el deleted file mode 100644 index 17a3a252d..000000000 --- a/init/core-editor.el +++ /dev/null @@ -1,185 +0,0 @@ -;; Global editor behavior -(electric-indent-mode -1) -(setq electric-indent-chars '(? ?: ?{)) -(add-hook 'python-mode-hook 'electric-indent-local-mode) - -(add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) -(add-hook! 'eldoc-mode-hook (diminish 'eldoc-mode " ?")) - -(setq-default fill-column 80) -(diminish 'auto-fill-function) -;; Sane scroll settings -(setq scroll-margin 5) -(setq scroll-conservatively 9999) -(setq scroll-preserve-screen-position 1) -;; I'll use visual mode, kthxbai -(setq shift-select-mode nil) - -;;;; Modes 'n hooks ;;;;;;;;;;;;;;;;; -(associate-mode "/LICENSE[^/]*$" 'text-mode) -(associate-mode "zsh\\(env\\|rc\\)?$" 'sh-mode) -(associate-mode "z\\(profile\\|login\\|logout\\)?$" 'sh-mode) -(associate-mode "zsh/" 'sh-mode) -(associate-mode "\\.applescript$" 'applescript-mode) -(associate-mode "Cask$" 'emacs-lisp-mode) -(associate-mode "\\.el\\.gz$" 'emacs-lisp-mode) -(associate-mode "/Makefile$" 'makefile-gmake-mode) -(associate-mode "\\.plist$" 'nxml-mode) - -(add-hook 'help-mode-hook 'visual-line-mode) -(add-hook 'before-save-hook 'delete-trailing-whitespace) - -;; (setenv "SHELL" (s-trim (shell-command-to-string "which zsh"))) -(setenv "SHELL" "/usr/local/bin/zsh") -(setenv "EMACS" "1") - -;; show-paren faces -(set-face-background 'show-paren-match nil) -(set-face-foreground 'show-paren-match "orange") -(set-face-attribute 'show-paren-match nil :weight 'extra-bold) -(setq show-paren-delay 0) - -(let ((face 'evil-search-highlight-persist-highlight-face)) - (set-face-attribute face nil :inherit 'isearch-lazy-highlight-face) - (set-face-foreground face nil) - (set-face-background face nil)) - -(diminish 'isearch-mode) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(use-package anzu - :diminish anzu-mode - :config (global-anzu-mode +1)) - -(use-package smartparens - :diminish smartparens-mode - :config - (progn - (require 'smartparens-config) - (smartparens-global-mode 1) - - (setq blink-matching-paren t) - (setq sp-autowrap-region nil ; let evil-surround handle this - sp-highlight-pair-overlay nil - sp-show-pair-delay 0 - sp-autoescape-string-quote nil) - - ;; Handle newlines + spaces - (sp-pair "{" "}" :post-handlers '(("||\n[i]" "RET") ("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p)) - (sp-pair "(" ")" :post-handlers '(("||\n[i]" "RET") ("| " " ")) :unless '(sp-point-before-word-p sp-point-before-same-p)) - - ;; Auto-close more conservatively - (sp-pair "[" nil :unless '(sp-point-before-word-p sp-point-before-same-p)) - (sp-pair "'" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) - (sp-pair "\"" nil :unless '(sp-point-after-word-p sp-point-before-word-p sp-point-before-same-p)) - - (sp-with-modes '(json-mode js2-mode ruby-mode enh-ruby-mode python-mode) - (sp-local-pair "[" nil :post-handlers '(("||\n[i]" "RET")))) - - (sp-with-modes '(c-mode c++-mode objc-mode java-mode scss-mode css-mode php-mode) - (sp-local-pair "/* " " */" :post-handlers '(("||\n[i]" "RET"))) - (sp-local-pair "/**" "*/" :post-handlers '(("||\n[i]" "RET")))) - - ;; Support for generics - (sp-with-modes '(c-mode c++-mode objc-mode java-mode) - (sp-local-pair "<" ">" :when '(sp-point-after-word-p) :unless '(sp-point-before-same-p))) - - (sp-with-modes '(objc-mode scss-mode css-mode) - (sp-local-pair "/*\n" "\n */" :post-handlers '(("||[i]" "RET")))) - - (sp-with-modes '(c-mode c++-mode php-mode java-mode) - (sp-local-pair "/*" "" :post-handlers '((" ||\n[i]*/" "RET")))) - - (after "yasnippet" - (defadvice yas-expand (before advice-for-yas-expand activate) - (sp-remove-active-pair-overlay))))) - -(use-package rotate-text - :commands (rotate-word-at-point rotate-region)) - -(use-package smart-forward - :commands (smart-up smart-down smart-left smart-right)) - -(use-package expand-region - :commands (er/expand-region er/contract-region er/mark-symbol er/mark-word)) - -(use-package hl-todo - :commands hl-todo-mode - :init (add-hook 'prog-mode-hook 'hl-todo-mode)) - -(use-package emr - :commands (emr-initialize emr-show-refactor-menu) - :config (bind popup-menu-keymap [escape] 'keyboard-quit)) - -(use-package dash-at-point - :if is-mac - :commands (dash-at-point dash-at-point-with-docset) - :config - (add-to-list 'dash-at-point-mode-alist - '(java-mode . "java,droid,javafx,grails,groovy,playjava,spring,cvj,processing,javadoc"))) - -(use-package rainbow-delimiters - :commands rainbow-delimiters-mode - :init (add-hooks '(emacs-lisp-mode-hook js2-mode-hook scss-mode-hook) - 'rainbow-delimiters-mode) - :config - (progn - (setq rainbow-delimiters-outermost-only-face-count 1) - (set-face-attribute 'rainbow-delimiters-depth-1-face nil - :foreground 'unspecified - :inherit 'my-outermost-paren-face))) - -(use-package yaml-mode - :mode "\\.ya?ml$" - :init (add-hook 'yaml-mode-hook 'enable-tab-width-2)) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(progn ; Code building - (defvar my-build-command '("make %s" . "Makefile")) - (make-variable-buffer-local 'my-build-command) - - (defun set-build-command (command &optional file) - (when (or (null file) - (project-has-files file)) - (setq my-build-command `(,command . ,file)))) - - (evil-define-command my:build (arg) - "Call a build command in the current directory. -If ARG is nil this function calls `recompile', otherwise it calls -`compile' passing ARG as build command." - (interactive "") - (when (null my-build-command) - (user-error "No build command was set")) - (let ((build-file (cdr my-build-command)) - (build-cmd (car my-build-command))) - (if (project-has-files build-file) - (compile (format "cd '%s' && %s" build-file (format build-cmd (or arg "")))) - (error "Could not find Makefile"))))) - -(progn ; Code running - (evil-define-operator my:eval-region (beg end) - :move-point nil - (interactive "") - (cond ((eq major-mode 'emacs-lisp-mode) - (eval-region beg end)) - (t - (let ((interp (my--get-interpreter)) - (max-mini-window-height 1)) - (when interp (shell-command-on-region beg end interp)))))) - - (evil-define-command my:eval-buffer () - (interactive) - (cond ((eq major-mode 'emacs-lisp-mode) - (eval-buffer)) - (t - (let ((interp (my--get-interpreter)) - (max-mini-window-height 1)) - (when interp (shell-command-on-region (point-min) (point-max) interp)))))) - - (defun my--get-interpreter () - (car (--first (eq (cdr it) major-mode) interpreter-mode-alist)))) - - -(provide 'core-editor) -;;; core-editor.el ends here diff --git a/init/core-evil.el b/init/core-evil.el deleted file mode 100644 index 0a3c84366..000000000 --- a/init/core-evil.el +++ /dev/null @@ -1,295 +0,0 @@ -;;;; Eeeeeeevil ;;;;;;;;;;;;;;;;;;;;;;;; -(use-package evil - :diminish undo-tree-mode - :config - (progn - (setq evil-want-visual-char-semi-exclusive nil - evil-search-module 'evil-search - evil-search-wrap nil - evil-magic 'magic - evil-want-C-u-scroll t ; enable C-u for scrolling - evil-ex-visual-char-range t ; column range for ex commands - evil-ex-search-vim-style-regexp t - evil-ex-interactive-search-highlight 'selected-window - - ;; Color-coded state cursors - evil-normal-state-cursor '("white" box) - evil-emacs-state-cursor '("cyan" bar) - evil-insert-state-cursor '("white" bar) - evil-visual-state-cursor 'hollow) - - (evil-mode 1) - - ;; Always ensure evil-shift-width is consistent with tab-width - (add-hook! 'evil-local-mode-hook (setq evil-shift-width tab-width)) - ;; Fix code folding - (add-hook! 'prog-mode-hook (hs-minor-mode 1) (diminish 'hs-minor-mode)) - - ;; highlight matching delimiters where it's important - (defun show-paren-mode-off () (show-paren-mode -1)) - (add-hook 'evil-insert-state-entry-hook 'show-paren-mode) - (add-hook 'evil-insert-state-exit-hook 'show-paren-mode-off) - (add-hook 'evil-visual-state-entry-hook 'show-paren-mode) - (add-hook 'evil-visual-state-exit-hook 'show-paren-mode-off) - (add-hook 'evil-motion-state-entry-hook 'show-paren-mode) - (add-hook 'evil-motion-state-exit-hook 'show-paren-mode-off) - (add-hook 'evil-operator-state-entry-hook 'show-paren-mode) - (add-hook 'evil-operator-state-exit-hook 'show-paren-mode-off) - - ;; Disable highlights on insert-mode - (add-hook 'evil-insert-state-entry-hook 'evil-ex-nohighlight) - - ;; modes to map to different default states - (dolist (mode-map '((cider-repl-mode . emacs) - (comint-mode . emacs) - (fundamental-mode . normal) - (help-mode . normal) - (term-mode . emacs))) - (evil-set-initial-state `,(car mode-map) `,(cdr mode-map))) - - ;; predicate for visual line mode - (defun evil-visual-line-state-p () - "Returns non-nil if in visual-line mode, nil otherwise." - (and (evil-visual-state-p) - (eq (evil-visual-type) 'line))) - - - (progn ; evil plugins - (use-package evil-indent-textobject) ; vii/vai/vaI - - ;; (use-package evil-ex-registers) - (use-package evil-surround - :commands (evil-surround-edit - evil-Surround-edit - evil-surround-region) - :config (global-evil-surround-mode 1)) - - (use-package evil-numbers - :commands (evil-numbers/inc-at-pt - evil-numbers/dec-at-pt)) - - (use-package evil-matchit - :commands (evilmi-jump-items) - :config (global-evil-matchit-mode 1)) - - (use-package evil-search-highlight-persist - :config (global-evil-search-highlight-persist t)) - - (use-package evil-commentary - :diminish evil-commentary-mode - :commands (evil-commentary - evil-commentary-yank - evil-commentary-line) - :config (evil-commentary-mode 1)) - - (use-package evil-jumper - :init (setq evil-jumper-file (expand-file-name "jumplist" my-tmp-dir)) - :config - (setq evil-jumper-auto-center t - evil-jumper-auto-save-interval 3600)) - - (use-package evil-exchange - :commands (evil-exchange) - :config - (defadvice evil-force-normal-state (before evil-esc-quit-exchange activate) - (when evil-exchange--overlays - (evil-exchange-cancel)))) - - (use-package evil-visualstar - :commands (evil-visualstar/begin-search - evil-visualstar/begin-search-forward - evil-visualstar/begin-search-backward) - :config - (progn - ;; I cut this down because the original visualstar wouldn't remember - ;; the last search if evil-search-module was 'evil-search. - (defun evil-visualstar/begin-search (beg end direction) - (when (evil-visual-state-p) - (evil-exit-visual-state) - (let ((selection (regexp-quote (buffer-substring-no-properties beg end)))) - (setq isearch-forward direction) - (evil-search selection direction t)))) - (global-evil-visualstar-mode 1))) - - (use-package evil-snipe - :diminish evil-snipe-mode - :config - (progn - (global-evil-snipe-mode +1) - (setq evil-snipe-smart-case t - evil-snipe-override-evil t - evil-snipe-scope 'line - evil-snipe-repeat-scope 'buffer - evil-snipe-override-evil-repeat-keys nil) - (setq-default evil-snipe-symbol-groups - '((?\[ "[[{(]") - (?\] "[]})]"))) - (bind 'motion - "C-;" 'evil-snipe-repeat - "C-," 'evil-snipe-repeat-reverse)))) - - (bind evil-ex-completion-map - "C-r" #'evil-ex-paste-from-register ; registers in ex-mode - "C-a" 'move-beginning-of-line - "" 'move-beginning-of-line - "" 'move-beginning-of-line - "" 'evil-delete-whole-line) - - (progn ; evil hacks - (defadvice evil-force-normal-state (before evil-esc-quit activate) - (shut-up (evil-search-highlight-persist-remove-all) ; turn off highlights - (evil-ex-nohighlight) - ;; Exit minibuffer is alive - (if (minibuffer-window-active-p (minibuffer-window)) - (my--minibuffer-quit)))) - - ;; Popwin: close popup window, if any - (defadvice evil-force-normal-state (before evil-esc-quit-popwin activate) - (shut-up (popwin:close-popup-window))) - - ;; Jump to new splits - (defadvice evil-window-split (after evil-window-split-jump activate) - (evil-window-down 1)) - (defadvice evil-window-vsplit (after evil-window-vsplit-jump activate) - (evil-window-right 1))) - - (progn ; ex-commands - (evil-define-command my:kill-buffers (&optional bang) - :repeat nil - (interactive "") - (if (and (not bang) (projectile-project-p)) - (projectile-kill-buffers) - (mapc 'kill-buffer (buffer-list))) - (delete-other-windows) - (switch-to-buffer (if (buffer-live-p project-scratch-buffer) project-scratch-buffer (get-buffer-create "*scratch*")))) - - (evil-define-command my:kill-buried-buffers (&optional bang) - :repeat nil - (interactive "") - (mapc 'kill-buffer - (my-living-buffer-list (if bang (projectile-project-buffers) (buffer-list))))) - - (evil-define-command my:init-files (&optional bang) :repeat nil - (interactive "") - (if bang - (ido-find-file-in-dir my-modules-dir) - (ido-find-file-in-dir my-dir))) - - (evil-define-command my:notes () :repeat nil - (interactive) - (require 'org) - (ido-find-file-in-dir org-directory)) - - (evil-define-command my:byte-compile (&optional bang) - :repeat nil - (interactive "") - (byte-recompile-file (expand-file-name "init.el" my-dir) bang 0) - (dolist (file (append (f-glob "core*.el" my-modules-dir) - (f-glob "defuns*.el" my-modules-dir) - (f-glob "my*.el" my-modules-dir))) - (byte-recompile-file file bang 0))) - - (evil-define-command my:cd (dir) - :repeat nil - (interactive "") - (cd (if (zerop (length dir)) "~" dir))) - - (defun --save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit)) - (evil-define-command my:create-file (path &optional bang) - "Deploy files (and their associated templates) quickly. Will prompt -you to fill in each snippet field before buffer closes unless BANG is -provided." - :repeat nil - (interactive "") - (let ((dir (f-dirname path)) - (fullpath (f-full path)) - (is-auto t)) - (when (and bang (not (f-exists? dir))) (f-mkdir dir)) - (if (f-exists? dir) - (if (f-exists? fullpath) - (error "File already exists: %s" path) - (find-file fullpath) - (add-hook 'yas-after-exit-snippet-hook '--save-exit) - (if bang (--save-exit))) - (error "Directory doesn't exist: %s" dir)))) - - (evil-define-command my:rename-this-file (new-name) - "Renames current buffer and file it is visiting. Replaces %, # and other - variables (see `evil-ex-replace-special-filenames')" - :repeat nil - (interactive "") - (let ((name (buffer-name)) - (filename (buffer-file-name))) - (if (not (and filename (file-exists-p filename))) - (error "Buffer '%s' is not visiting a file!" name) - (let ((new-name - (evil-ex-replace-special-filenames (if new-name - new-name - (read-file-name "New name: " filename))))) - (if (get-buffer new-name) - (error "A buffer named '%s' already exists!" new-name) - (rename-file filename new-name 1) - (rename-buffer new-name) - (set-visited-file-name new-name) - (set-buffer-modified-p nil) - (save-place-forget-unreadable-files) - (message "File '%s' successfully renamed to '%s'" - name (file-name-nondirectory new-name))))))) - - (evil-define-operator my:scratch-buffer (&optional beg end bang) - "Send a selection to the scratch buffer. If BANG, then send it to org-capture - instead." - :move-point nil - :type inclusive - (interactive "") - (let ((mode major-mode) - (text (when (and (evil-visual-state-p) beg end) - (buffer-substring beg end)))) - (if bang - ;; use org-capture with bang - (if text - (org-capture-string text) - (org-capture)) - ;; or scratch buffer by default - (let ((project-dir (projectile-project-root)) - (buffer-name (if (projectile-project-p) - (format "*scratch* (%s)" (projectile-project-name)) - "*scratch*"))) - (popwin:popup-buffer (get-buffer-create buffer-name)) - (when (eq (get-buffer buffer-name) (current-buffer)) - (cd project-dir) - (if text (insert text)) - (funcall mode)))))) - - (evil-define-command my:align (beg end &optional regexp bang) - :repeat nil - (interactive "") - (when regexp - (align-regexp beg end - (concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1))) - - (evil-define-operator my:retab (beg end) - "Akin to vim's :retab, this changes all tabs-to-spaces or spaces-to-tabs, - depending on `indent-tab-mode'. Untested." - :motion nil - :move-point nil - :type line - (interactive "") - (unless (and beg end) - (setq beg (point-min)) - (setq end (point-max))) - (if indent-tabs-mode - (tabify beg end) - (untabify beg end))) - - (evil-define-operator my:narrow-indirect (beg end) - "Indirectly narrow the region from BEG to END." - :move-point nil - :type exclusive - :repeat nil - (interactive "") - (evil-normal-state) - (my-narrow-to-region-indirect beg end))))) - - -(provide 'core-evil) diff --git a/init/core-linux.el b/init/core-linux.el deleted file mode 100644 index abdf3be9a..000000000 --- a/init/core-linux.el +++ /dev/null @@ -1,5 +0,0 @@ -(when is-linux (add-to-list 'load-path "~/.cask")) - -(provide 'core-linux) - -;; Nothing here yet diff --git a/init/core-osx.el b/init/core-osx.el deleted file mode 100644 index c34d22e4f..000000000 --- a/init/core-osx.el +++ /dev/null @@ -1,38 +0,0 @@ -;; Mac-specific settings - -;; 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) - -;; Prefixes: Command = M, Alt = A -(setq mac-command-modifier 'meta) -(setq mac-option-modifier 'alt) - -;; fix emacs PATH on OSX (GUI only) -(use-package exec-path-from-shell - :config (exec-path-from-shell-initialize)) - -(use-package applescript-mode :mode "\\.applescript$") - -(after "evil" - ;; On OSX, stop copying each visual state move to the clipboard: - ;; https://bitbucket.org/lyro/evil/issue/336/osx-visual-state-copies-the-region-on - ;; Most of this code grokked from: - ;; http://stackoverflow.com/questions/15873346/elisp-rename-macro - (defadvice evil-visual-update-x-selection (around clobber-x-select-text activate) - (unless (featurep 'ns) ad-do-it))) - -;; Send current file to OSX apps -(defun my-open-with (&optional app-name path) - (interactive) - (let* ((path (f-full (s-replace "'" "\\'" (or path (if (eq major-mode 'dired-mode) (dired-get-file-for-visit) (buffer-file-name)))))) - (command (concat "open " (when app-name (concat "-a " (shell-quote-argument app-name))) " '" path "'"))) - (message "Trying: %s" command) - (shell-command command))) - - -(provide 'core-osx) -;;; core-osx.el ends here diff --git a/init/core-ui.el b/init/core-ui.el deleted file mode 100644 index 31bc1a4bb..000000000 --- a/init/core-ui.el +++ /dev/null @@ -1,181 +0,0 @@ -;;; core-ui.el -- User interface layout & behavior - -;;;; Load Theme ;;;;;;;;;;;;;;;;;;;;;;;; - -(when window-system - (set-frame-font *default-font) - (set-frame-parameter nil 'alpha '(100 75))) -(add-to-list 'custom-theme-load-path my-themes-dir) -(load-theme *default-theme t) - - -;;;; GUI Settings ;;;;;;;;;;;;;;;;;;;;;; - -(when window-system - (scroll-bar-mode -1) ; no scrollbar - (tool-bar-mode -1) ; no toolbar - (menu-bar-mode -1) ; no menubar - (fringe-mode '(2 . 8))) ; no nonsense - -(global-hl-line-mode 1) ; do highlight line -(blink-cursor-mode 1) ; do blink cursor -(line-number-mode 1) ; do show line no in modeline -(column-number-mode 1) ; do show col no in modeline -(tooltip-mode -1) ; don't show tooltips - -;; 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 - visible-bell nil ; silence of the bells - use-dialog-box nil ; avoid GUI - redisplay-dont-pause t - ;; do not soft-wrap lines - truncate-lines t - truncate-partial-width-windows nil - indicate-buffer-boundaries nil - indicate-empty-lines nil - fringes-outside-margins t) - -(use-package nlinum - :commands nlinum-mode - :init - (progn - (defface linum-highlight-face '((t (:inherit linum))) - "Face for line highlights") - - ;; Preset width nlinum - (add-hook! 'nlinum-mode-hook - (setq nlinum--width - (length (number-to-string - (count-lines (point-min) (point-max)))))) - - ;; Highlight line number - (setq hl-nlinum-overlay nil) - (setq hl-nlinum-line nil) - (defun hl-nlinum-unhighlight-line () - (when hl-nlinum-overlay - (let* ((ov hl-nlinum-overlay) - (disp (get-text-property 0 'display (overlay-get ov 'before-string))) - (str (nth 1 disp))) - (put-text-property 0 (length str) 'face 'linum str) - (setq hl-nlinum-overlay nil) - (setq hl-nlinum-line nil)))) - - (defun hl-nlinum-highlight-line () - (let ((line-no (line-number-at-pos (point)))) - (when (and nlinum-mode (not (eq line-no hl-nlinum-line))) - (let* ((pbol (point-at-bol)) - (peol (1+ pbol))) - ;; Handle EOF case - (when (>= peol (point-max)) - (setq pbol (line-beginning-position 0)) - (setq peol (line-end-position 0))) - (jit-lock-fontify-now pbol peol) - (let* ((overlays (overlays-in pbol peol)) - (ov (-first (lambda (item) (overlay-get item 'nlinum)) overlays))) - (when ov - (hl-nlinum-unhighlight-line) - (let* ((disp (get-text-property 0 'display (overlay-get ov 'before-string))) - (str (nth 1 disp))) - (put-text-property 0 (length str) 'face 'linum-highlight-face str) - (put-text-property 0 (length str) 'face 'linum-highlight-face str) - (setq hl-nlinum-overlay ov) - (setq hl-nlinum-line line-no)))))))) - - (defun nlinum-toggle () - (interactive) - (if nlinum-mode - (nlinum-disable) - (nlinum-enable))) - (defun nlinum-enable () - (nlinum-mode +1) - (add-hook 'post-command-hook 'hl-nlinum-highlight-line)) - (defun nlinum-disable () - (nlinum-mode -1) - (remove-hook 'post-command-hook 'hl-nlinum-highlight-line) - (hl-nlinum-unhighlight-line)) - - (add-hooks '(text-mode-hook prog-mode-hook) 'nlinum-enable) - (add-hook 'org-mode-hook 'nlinum-disable)) - :config - (setq-default nlinum-format " %4d ")) - -(when window-system - (setq frame-title-format '(buffer-file-name "%f" ("%b"))) - (if (string-equal (system-name) "io") - (set-frame-size (selected-frame) 326 119))) - -(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate) - "Prevent annoying \"Active processes exist\" query when you quit Emacs." - (flet ((process-list ())) ad-do-it)) - -;; [pedantry intensifies] -(rename-mode-name emacs-lisp-mode "Elisp") - -(use-package vim-empty-lines-mode - :config (global-vim-empty-lines-mode +1)) - - -;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;; -(use-package uniquify - :config - (setq uniquify-buffer-name-style 'post-forward-angle-brackets - uniquify-separator ":" - uniquify-ignore-buffers-re "^\\*")) - -(use-package smart-mode-line - :config - (progn - (setq sml/no-confirm-load-theme t - sml/mode-width 'full - sml/extra-filler (if window-system -1 0) - sml/show-remote nil - sml/modified-char "*" - sml/encoding-format nil - sml/replacer-regexp-list '(("^~/Dropbox/Projects/" "PROJECTS:") - ("^~/.emacs.d/" "EMACS.D:") - ("^~/Dropbox/notes/" "NOTES:"))) - - ;; Hide evil state indicator - (after "evil" (setq evil-mode-line-format nil)) - - (setq-default mode-line-misc-info - '((which-func-mode ("" which-func-format "")) - (global-mode-string ("" global-mode-string "")))) - - (add-hook! 'after-change-major-mode-hook - (unless (null mode-line-format) - (setq mode-line-format - '((if window-system " ") - "%e" - ;; mode-line-mule-info - ;; mode-line-client - ;; mode-line-remote - ;; mode-line-frame-identification - mode-line-buffer-identification - mode-line-modified - mode-line-modes - mode-line-misc-info - (vc-mode vc-mode) - " " - mode-line-position - " " - mode-line-front-space - ))) - - (add-to-list 'mode-line-modes - '(sml/buffer-identification-filling - sml/buffer-identification-filling - (:eval (setq sml/buffer-identification-filling - (sml/fill-for-buffer-identification)))))) - - (let ((-linepo mode-line-position)) - (sml/setup) - (sml/apply-theme 'respectful) - (setq mode-line-position -linepo) - (sml/filter-mode-line-list 'mode-line-position)))) - - -(provide 'core-ui) -;;; core-ui.el ends here diff --git a/init/core.el b/init/core.el deleted file mode 100644 index cf9ad1dad..000000000 --- a/init/core.el +++ /dev/null @@ -1,365 +0,0 @@ -(defconst is-mac (eq system-type 'darwin)) -(defconst is-linux (eq system-type 'gnu/linux)) -(defconst is-windows (eq system-type 'windows-nt)) - -(setq use-package-verbose DEBUG-MODE) - -(cd "~") ; instead of / - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(require 'defuns) -(require 'autoloads) ; use make autoloads to generate autoloads file -(use-package shut-up - :config - (progn - (setq shut-up-ignore DEBUG-MODE) - (when noninteractive (shut-up-silence-emacs)))) ; http://youtu.be/Z6woIRLnbmE - -;; Make sure undo/backup folders exist -(defconst my-tmp-dir-undo (expand-file-name "undo" my-tmp-dir)) -(defconst my-tmp-dir-backup (expand-file-name "backup" my-tmp-dir)) -(defconst my-tmp-dir-autosave (expand-file-name "autosave" my-tmp-dir)) -(unless (file-directory-p my-tmp-dir) - (make-directory my-tmp-dir-undo t) - (make-directory my-tmp-dir-backup t) - (make-directory my-tmp-dir-autosave t)) - -;; (setq load-prefer-newer t) -(setq debug-on-quit DEBUG-MODE) - -;;;; Sane defaults ;;;;;;;;;;;;;;;;;;;;;;; -(auto-compression-mode t) ; Transparently open compressed files -(global-font-lock-mode t) ; Enable syntax highlighting for older emacs -;; (global-auto-revert-mode 1) ; revert buffers for changed files - - ;;; window layout undo/redo -(setq winner-boring-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*" - "*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*" - "*Buffer List*" "*Ibuffer*" "*esh command on file*")) -(winner-mode 1) - -(use-package semantic - :commands semantic-mode - :init (add-hook 'prog-mode-hook 'semantic-mode) - :config - (progn - (setq semanticdb-default-save-directory (expand-file-name "semanticdb" my-tmp-dir)) - (semantic-mode 1))) - -;;; UTF-8 please -(setq locale-coding-system 'utf-8) ; pretty -(set-terminal-coding-system 'utf-8) ; pretty -(set-keyboard-coding-system 'utf-8) ; pretty -(set-selection-coding-system 'utf-8) ; please -(prefer-coding-system 'utf-8) ; with sugar on top -(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no - -;;; Show tab characters -;; (global-whitespace-mode 1) -(setq whitespace-style '(trailing face tabs tab-mark) ; needs to be re-set in every buffer - whitespace-display-mappings - '((tab-mark ?\t [?| ?\t] [?\\ ?\t]) - (newline-mark 10 [36 10]))) ; for whitespace-newline-mode - -;; avoid garbage collection (default is 400k) -(setq-default gc-cons-threshold 20000000) -(setq-default confirm-kill-emacs nil) - -;; minibufferception? Yay! -(setq-default enable-recursive-minibuffers t) - -;; Show me those keystrokes -(setq echo-keystrokes 0.02) - -(setq ring-bell-function 'ignore) - -(setq inhibit-startup-screen t ; don't show EMACs start screen - inhibit-splash-screen t - inhibit-startup-buffer-menu t - - initial-major-mode 'fundamental-mode ; initial scratch buffer mode - initial-scratch-message nil - initial-scratch-buffer nil ; empty scratch buffer - - compilation-always-kill t - compilation-ask-about-save nil - compilation-scroll-output t) - -(setq sentence-end-double-space nil) ; sentences end with periods. Period. - -(setq ediff-diff-options "-w" - ediff-split-window-function 'split-window-horizontally ; side-by-side diffs - ediff-window-setup-function 'ediff-setup-windows-plain) ; no extra frames - -;; Don't save clipboard contents into kill-ring before replacing them -(setq save-interprogram-paste-before-kill nil) - -;; don't let the cursor go into minibuffer prompt -;; Tip taken from Xah Lee: http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html -(setq minibuffer-prompt-properties - '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)) - -;; remove annoying ellipsis when printing sexp in message buffer -(setq eval-expression-print-length nil - eval-expression-print-level nil) - -;; Save history across sessions -(use-package savehist - :config - (progn - (setq savehist-file (expand-file-name "savehist" my-tmp-dir) ; keep the home clean - history-length 1000 - savehist-additional-variables '(kill-ring - global-mark-ring - search-ring - regexp-search-ring - extended-command-history)) - (savehist-mode 1))) - -;; Save cursor location across sessions -(use-package saveplace - :config - (progn - (setq-default save-place-file (expand-file-name "saveplace" my-tmp-dir)) - ;; activate save-place only for files that exist - (add-hook! 'find-file-hook (if (file-exists-p buffer-file-name) (setq save-place t))))) - -(use-package recentf - :config - (progn - (add-hook 'kill-emacs-hook 'recentf-cleanup) - (setq recentf-save-file (expand-file-name "recentf" my-tmp-dir) - recentf-exclude '("/tmp/" "/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$" "/\\.cache/.+" "emacs\\.d/workgroups/.+$" ".emacs.workgroup") - recentf-max-menu-items 0 - recentf-max-saved-items 250 - recentf-auto-cleanup 'never) - (recentf-mode 1))) - - - ;;;; Backup ;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Disable all backups (that's what git/dropbox are for) -(setq bookmark-save-flag t) -(setq bookmark-default-file (expand-file-name "bookmarks" my-tmp-dir)) -(setq auto-save-default nil) -(setq auto-save-list-file-name (expand-file-name ".auto-save" my-tmp-dir-autosave)) -(setq auto-save-file-name-transforms `((".*" ,my-tmp-dir-autosave t))) -;; In case I want to reactivate backup files -(setq make-backup-files nil) -(setq create-lockfiles nil) -(setq backup-directory-alist `((".*" . ,my-tmp-dir-backup))) -;; Remember undo history -(setq-default undo-tree-auto-save-history t) -(setq-default undo-tree-history-directory-alist `(("." . ,my-tmp-dir-undo))) -;; Keep region when undoing in region -(defadvice undo-tree-undo (around keep-region activate) - (if (use-region-p) - (let ((m (set-marker (make-marker) (mark))) - (p (set-marker (make-marker) (point)))) - ad-do-it - (goto-char p) - (set-mark m) - (set-marker p nil) - (set-marker m nil)) - ad-do-it)) - -;; Keep region when undoing in region -(defadvice undo-tree-undo (around keep-region activate) - (if (use-region-p) - (let ((m (set-marker (make-marker) (mark))) - (p (set-marker (make-marker) (point)))) - ad-do-it - (goto-char p) - (set-mark m) - (set-marker p nil) - (set-marker m nil)) - ad-do-it)) - -;; Shut up undo-tree's constant complaining -(defadvice undo-tree-load-history-hook (around undo-tree-load-history-shut-up activate) - (shut-up ad-do-it)) -;; (defadvice undo-tree-save-history-hook (around undo-tree-save-history-shut-up activate) -;; (shut-up ad-do-it)) - -;; Silences an annoying error: -;; undo-tree-mapc: Wrong type argument: listp, \.\.\. -(defun undo-tree-position (node list) - (when (listp list) - (let ((i 0)) - (catch 'found - (while (progn - (when (eq node (car list)) (throw 'found i)) - (incf i) - (setq list (cdr list)))) - nil)))) - -;; What we do every night, Pinkie... -(defun display-startup-echo-area-message () - (message "What're we gonna do tonight, Brain? (Loaded in %s)" (emacs-init-time))) - - - ;;;; Editor behavior ;;;;;;;;;;;;;;;; -;; spaces instead of tabs -(setq-default indent-tabs-mode nil ; spaces instead of tabs - tab-always-indent t - tab-width 4) - -(setq require-final-newline t) -(setq delete-trailing-lines nil) -(add-hook! 'makefile-mode-hook (setq indent-tabs-mode t)) ; Use normal tabs in makefiles - -;; Project defuns ;;;;;;;;;;;;;;;;;;;;;; -(require 'f) - -(defvar project-root-files '(".git" ".hg" ".svn" ".project" "local.properties" "project.properties" "rebar.config" "project.clj" "SConstruct" "pom.xml" "build.sbt" "build.gradle" "Gemfile" "requirements.txt" "tox.ini" "package.json" "gulpfile.js" "Gruntfile.js" "bower.json" "composer.json" "Cargo.toml" "mix.exs") - "A list of files that count as 'project files', which determine whether a - folder is the root of a project or not.") -(defun project-root (&optional strict-p) - "Get the path to the root of your project. Uses `project-root-files' to -determine if a directory is a project." - (catch 'found - (f-traverse-upwards - (lambda (path) - (let ((path (file-truename path)) - (home (file-truename "~"))) - (if (f-equal? home path) - (throw 'found (if strict-p nil default-directory)) - (dolist (file project-root-files) - (when (f-exists? (expand-file-name file path)) - (throw 'found path)))))) default-directory) - default-directory)) - -(defun project-has-files (files &optional root) - "Return non-nil if `file' exists in the project root." - (let ((root (or root (project-root))) - (files (if (listp files) files (list files))) - found-p file) - (while (and files (not found-p)) - (setq file (pop files)) - (setq found-p (f-exists? (project-path-to file root)))) - found-p)) - -(defun project-path-to (file &optional root) - (let ((root (or root (project-root)))) - (expand-file-name file root))) - -(defun project-name () - (file-name-nondirectory (directory-file-name (project-root)))) - -(defun project-p () - (not (null (project-root t)))) - -;; Make sure scratch buffer is always "in a project" -(defvar project-scratch-buffer nil) -(defun project-create-scratch-buffer () - (let* ((scratch-buffer (get-buffer-create "*scratch*")) - (project-name (project-name)) - (root (project-root))) - (mapc (lambda (b) - (if (string-match-p "\\*scratch\\* (.+)" (buffer-name b)) - (kill-buffer b))) - (buffer-list)) - (save-window-excursion - (switch-to-buffer scratch-buffer) - (setq project-scratch-buffer scratch-buffer) - (erase-buffer) - (cd root) - (rename-buffer (format "*scratch* (%s)" project-name))))) -(add-hook 'find-file-hook 'project-create-scratch-buffer) - - -;; Automatic minor modes ;;;;;;;;;;; -(defvar auto-minor-mode-alist () - "Alist of filename patterns vs correpsonding minor mode functions, -see `auto-mode-alist' All elements of this alist are checked, meaning -you can enable multiple minor modes for the same regexp.") -(defun enable-minor-mode-based-on-path () - "check file name against auto-minor-mode-alist to enable minor modes -the checking happens for all pairs in auto-minor-mode-alist" - (when buffer-file-name - (let ((name buffer-file-name) - (remote-id (file-remote-p buffer-file-name)) - (alist auto-minor-mode-alist)) - ;; Remove backup-suffixes from file name. - (setq name (file-name-sans-versions name)) - ;; Remove remote file name identification. - (when (and (stringp remote-id) - (string-match-p (regexp-quote remote-id) name)) - (setq name (substring name (match-end 0)))) - (while (and alist (caar alist) (cdar alist)) - (if (string-match (caar alist) name) - (funcall (cdar alist) 1)) - (setq alist (cdr alist)))))) -(add-hook 'find-file-hook 'enable-minor-mode-based-on-path) - - -;;;; Utility plugins ;;;;;;;;;;;;;;;;;; - -(use-package smex - :commands (smex smex-major-mode-commands) - :config - (progn - (smex-initialize) - ;; Hook up smex to auto-update, rather than update on every run - (defun smex-update-after-load (unused) - (when (boundp 'smex-cache) (smex-update))) - (add-hook 'after-load-functions 'smex-update-after-load))) - -(use-package popwin - :config - (progn ; popwin config - (popwin-mode 1) - (setq popwin:popup-window-height 0.45) - (setq popwin:special-display-config - (append '(("\\`\\*helm.*?\\*\\'" :regexp t :position bottom :height 15) - ("^\\*Flycheck.*\\*$" :regexp t :position bottom :height 0.25 :noselect t) - (inf-enh-ruby-mode :position bottom :stick t) - (snippet-mode :position bottom :stick t) - ("^\\*eclim.*\\*" :regexp t :position bottom :height 0.25) - ("*ansi-term*" :position bottom :height 0.45 :stick t) - ("*terminal*" :position bottom :height 0.45 :stick t) - ("*Async Shell Command*" :position bottom) - ("*Shell Command Output*" :position bottom :stick t :height 15) - ("* Regexp Explain *" :position top :height 0.35) - ("*anaconda-doc*" :position bottom :height 15 :noselect t) - ("*anaconda-nav*" :position bottom :height 15 :stick t) - ("^\\*Python.+\\*$" :regexp t :position bottom :height 20 :noselect t) - (help-mode :height 25 :position bottom :stick t) - (compilation-mode :height 0.5 :position bottom :noselect t) - (diff-mode :position bottom :stick t) - ("*Backtrace*") - ("*Warnings*") - ("*Process List*") - ("*Compile-Log*" :height 0.3 :position bottom :noselect t) - (" *undo-tree*" :width 0.3 :position right) - ("^\\*scratch\\*.*" :regexp t :stick t) - (image-mode) - ("*NeoTree*" :position left :width 22 :stick t)) - popwin:special-display-config)) - - (defun popwin:toggle-popup-window () - (interactive) - (if (popwin:popup-window-live-p) - (popwin:close-popup-window) - (popwin:popup-last-buffer))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(cond (is-mac (require 'core-osx)) - (is-linux (require 'core-linux)) - (is-windows (require 'core-windows))) - -;; Performance checks -(add-hook! 'find-file-hook - ;; If file is oversized... - (when (> (buffer-size) (* 1024 1024)) - (setq buffer-read-only t) - (buffer-disable-undo) - (fundamental-mode) - (visual-line-mode))) - -(use-package server - :config (unless (server-running-p) (server-start))) - - -(provide 'core) -;;; core.el ends here diff --git a/init/defuns-buffers.el b/init/defuns-buffers.el deleted file mode 100644 index 32690d55d..000000000 --- a/init/defuns-buffers.el +++ /dev/null @@ -1,135 +0,0 @@ -;; Inspired by http://demonastery.org/2013/04/emacs-evil-narrow-region/ -;;;###autoload -(defun my-narrow-to-region-indirect (start end) - "Restrict editing in this buffer to the current region, indirectly." - (interactive "r") - (deactivate-mark) - (let ((buf (clone-indirect-buffer nil nil))) - (with-current-buffer buf - (narrow-to-region start end)) - (switch-to-buffer buf))) - -;;;###autoload -(defun my--set-region-read-only (begin end) - "See http://stackoverflow.com/questions/7410125" - (let ((modified (buffer-modified-p))) - (add-text-properties begin end '(read-only t)) - (set-buffer-modified-p modified))) - -;;;###autoload -(defun my--set-region-writeable (begin end) - "See http://stackoverflow.com/questions/7410125" - (let ((modified (buffer-modified-p)) - (inhibit-read-only t)) - (remove-text-properties begin end '(read-only t)) - (set-buffer-modified-p modified))) - -;;;###autoload -(defun my-living-buffer-list (&optional buffer-list) - (-remove 'get-buffer-window (or buffer-list (buffer-list)))) - - -;; Killing Buffers ;;;;;;;;;;;;;;;;;;;;; -;; Buffer defuns -(defvar my-cleanup-buffers-list '("^ \\*" - "^\\*Backtrace\\*$" - "^\\*Warnings\\*$" - "^\\*Compile-Log\\*$" - "^\\*Ediff.*\\*$" - help-mode - image-mode - dired-mode - reb-mode) - "A list of buffer name regexps or major-mode symbols. If buried buffers - match/have that mode active, `cleanup-buffers' will kill them.") - -(defvar my-cleanup-processes-alist '(("pry" . ruby-mode) - ("irb" . ruby-mode) - ("ipython" . python-mode)) - "An alist of (process-name . major-mode), that `my-cleanup-processes' checks -before killing processes. If there are no buffers with matching major-modes, it -gets killed.") - -;;;###autoload -(defun my--cleanup-buffers-add (regexp) - (add-to-list 'my-cleanup-buffers-list regexp)) - -;;;###autoload -(defun my-cleanup-buffers () - "Kill left-over temporary, dired or buried special buffers" - (interactive) - (let* ((this-frame (selected-frame)) - (kill-list (buffer-list this-frame))) - (setq kill-list - (-filter (lambda (b) - (unless (get-buffer-window b) ; don't kill if visible - (-any? (lambda (pred) - (cond ((stringp pred) - (s-matches? pred (buffer-name b))) - ((symbolp pred) - (eq (buffer-local-value 'major-mode b) pred)))) - my-cleanup-buffers-list))) - kill-list)) - - (message "Cleaned up %s buffers" (length kill-list)) - (mapc 'kill-buffer kill-list) - - (my-cleanup-processes))) - -;;;###autoload -(defun my-cleanup-processes () - (interactive) - (let ((buffer-list (buffer-list))) - (dolist (p (process-list)) - (let* ((process-name (process-name p)) - (assoc (assoc process-name my-cleanup-processes-alist))) - (when (and assoc - (not (string= process-name "server")) - (process-live-p p) - (not (-any? (lambda (b) - (let ((mode (buffer-local-value 'major-mode b))) - (eq mode (cdr assoc)))) - buffer-list))) - (message "Cleanup: killing %s" process-name) - (delete-process p)))))) - -;;;###autoload -(defun my-kill-matching-buffers (regexp &optional buffer-list) - (interactive) - (mapc (lambda (b) - (if (string-match-p regexp (buffer-name b)) - (kill-buffer b))) - (if buffer-list buffer-list (buffer-list)))) - -;; From spacemacs -;;;###autoload -(defun my-next-real-buffer () - "Switch to the next buffer and avoid special buffers." - (interactive) - (switch-to-next-buffer) - (let ((i 0)) - (while (and (< i 100) (string-equal "*" (substring (buffer-name) 0 1))) - (1+ i) - (switch-to-next-buffer)))) - -;;;###autoload -(defun my-previous-real-buffer () - "Switch to the previous buffer and avoid special buffers." - (interactive) - (switch-to-prev-buffer) - (let ((i 0)) - (while (and (< i 100) (string-equal "*" (substring (buffer-name) 0 1))) - (1+ i) - (switch-to-prev-buffer)))) - -;;;###autoload -(defun my-kill-real-buffer () - "Kill buffer (but only bury scratch buffer)" - (interactive) - (let ((bname (buffer-name))) - (cond ((string-match-p "^\\*scratch\\*" bname) - (erase-buffer) - (bury-buffer)) - ((string-equal "*" (substring bname 0 1)) - (previous-buffer)) - (t (kill-this-buffer))))) diff --git a/init/defuns-ui.el b/init/defuns-ui.el deleted file mode 100644 index c2d548a01..000000000 --- a/init/defuns-ui.el +++ /dev/null @@ -1,17 +0,0 @@ -(eval-when-compile (require 'cl)) - -;;;###autoload -(defun toggle-transparency () - (interactive) - (let* ((alpha (frame-parameter nil 'alpha)) - (alpha-val (if (listp alpha) (car alpha) alpha))) - (if (/= alpha-val 97) - (set-frame-parameter nil 'alpha 97) - (set-frame-parameter nil 'alpha 0)))) - -;;;###autoload -(defun toggle-fullscreen () - (interactive) - (set-frame-parameter nil 'fullscreen - (when (not (frame-parameter nil 'fullscreen)) 'fullboth))) - diff --git a/init/defuns.el b/init/defuns.el deleted file mode 100644 index e5dfcb2ff..000000000 --- a/init/defuns.el +++ /dev/null @@ -1,154 +0,0 @@ -;; Convenience ;;;;;;;;;;;;;;;;;;;;; -(defun associate-mode (match mode) - "Associate a major mode with a filepath through `auto-mode-alist'" - (add-to-list 'auto-mode-alist (cons match mode))) - -(defun associate-minor-mode (match mode) - "Associate a minor mode with a filepath through `auto-minor-mode-alist'" - (add-to-list 'auto-minor-mode-alist (cons match mode))) - -(defmacro λ (&rest body) - "A shortcut for: `(lambda () (interactive) ,@body)" - `(lambda () (interactive) ,@body)) - -(defun add-hooks (hooks funs) - "Add multiple hooks to multiple funs." - (let ((funs (if (listp funs) funs (list funs))) - (hooks (if (listp hooks) hooks (list hooks)))) - (dolist (hook hooks) - (dolist (fun funs) - (add-hook hook fun))))) - -(defmacro add-hook! (hook &rest body) - "A shortcut macro for `add-hook' that auto-wraps `body' in a lambda" - `(add-hook ,hook (lambda() ,@body))) - -;; Backwards compatible `with-eval-after-load' -(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))) - -(defmacro rename-mode-name (mode new-name) - `(defadvice ,mode (after rename-modeline activate) - (setq mode-name ,new-name))) - - -;; Keybindings ;;;;;;;;;;;;;;;;;;;;;;;;; -(defun bind (&rest keys) - (let (state-list keymap key def) - (while keys - (setq key (pop keys)) - (cond ((keymapp key) - (setq keymap key)) - ((or (evil-state-p key) - (and (listp key) (evil-state-p (car key)))) - (setq state-list key)) - (t - (if (stringp key) - (setq key (kbd key))) - (when (eq (length keys) 0) - (user-error "No definition for '%s' keybinding" key)) - (setq def (pop keys)) - (if (null state-list) - (if (null keymap) - (global-set-key key def) - (define-key keymap key def)) - (unless (listp state-list) - (setq state-list (list state-list))) - (dolist (state state-list) - (define-key (if keymap - (evil-get-auxiliary-keymap keymap state t) - (evil-state-property state :keymap t)) key def)))))))) - -(after "evil" - (evil-define-command my--maybe-exit-insert-mode () - "Exits insert mode using jk without the momentary pause caused by -key-chord-define." - :repeat change - (interactive) - (let ((modified (buffer-modified-p))) - (insert "j") - (let ((evt (read-event nil nil 0.4))) - (cond - ((null evt) (message "")) - ((and (integerp evt) (char-equal evt ?k)) - (delete-char -1) - (set-buffer-modified-p modified) - (push 'escape unread-command-events)) - (t (setq unread-command-events (append unread-command-events (list evt))))))))) - -;; Hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun enable-comment-hard-wrap () - (set (make-local-variable 'comment-auto-fill-only-comments) t) - (turn-on-auto-fill)) - -(defun enable-tab-width-2 () - (setq tab-width 2 evil-shift-width 2)) - -(defun enable-tab-width-4 () - (setq tab-width 4 evil-shift-width 4)) - -(defun disable-final-newline () - (set (make-local-variable 'require-final-newline) nil)) - - -;;;; Global Defuns ;;;;;;;;;;;;;;;;;;;;; -(defun my--minibuffer-quit () - "Abort recursive edit. In Delete Selection mode, if the mark is -active, just deactivate it; then it takes a second \\[keyboard-quit] -to abort the minibuffer." - (interactive) - (if (and delete-selection-mode transient-mark-mode mark-active) - (setq deactivate-mark t) - (when (get-buffer "*Completions*") - (delete-windows-on "*Completions*")) - (abort-recursive-edit))) - -(defun my--line-at-click () - "Determine the line number at click" - (save-excursion - (let ((click-y (cddr (mouse-position))) - (debug-on-error t) - (line-move-visual t)) - (goto-char (window-start)) - (next-line (1- click-y)) - (1+ (line-number-at-pos))))) - -(defun my-select-linum (event) - "Set point as *linum-mdown-line*" - (interactive "e") - (mouse-select-window event) - (goto-line (my--line-at-click)) - (evil-visual-line) - (setq *linum-mdown-line* - (line-number-at-pos))) - -(defun my-select-block () - "Select the current block of text between blank lines." - (interactive) - (let (p1 p2) - (progn - (if (re-search-backward "\n[ \t]*\n" nil "move") - (progn (re-search-forward "\n[ \t]*\n") - (setq p1 (point))) - (setq p1 (point))) - (if (re-search-forward "\n[ \t]*\n" nil "move") - (progn (re-search-backward "\n[ \t]*\n") - (setq p2 (point))) - (setq p2 (point)))) - (set-mark p1))) - - -(provide 'defuns) diff --git a/init/init-auto-insert.el b/init/init-auto-insert.el index 0f306984a..61d6f2333 100644 --- a/init/init-auto-insert.el +++ b/init/init-auto-insert.el @@ -1,10 +1,11 @@ (use-package autoinsert - :init (auto-insert-mode 1) :config (progn ;; (setq auto-insert-directory "%/.emacs.d/templates/") (setq auto-insert-query nil) ; Don't prompt before insertion - (setq auto-insert-alist '()))) + (setq auto-insert-alist '()) + + (auto-insert-mode 1))) (after "yasnippet" (defun add-template (regexp-or-major-mode uuid yas-mode &optional project-only) @@ -13,7 +14,7 @@ (defun insert-template (uuid mode &optional project-only) "Expand snippet template in MODE by its UUID" - (unless (or (and project-only (not (project-p))) + (unless (or (and project-only (not (narf/project-p))) (not (or (eq major-mode mode) (symbol-value mode)))) (insert uuid) @@ -47,14 +48,14 @@ ;; ;; Python ;; (add-template "tests?/test_.+\\.py$" "%%" 'nose-mode) ;; (add-template "/setup\\.py$" "%setup%" 'python-mode) - (add-template "\\.py$" "%%" 'python-mode) + (add-template "\\.py$" "%%" 'python-mode) ;; ;; PHP ;; (add-template "\\.class\\.php$" "%class%" 'php-mode) ;; (add-template "\\.php$" "%%" 'php-mode) ;; ;; Markdown - (add-template "/README\\.md$" "%README.md%" 'markdown-mode) + (add-template "\\.md$" "%%" 'markdown-mode) ;; (add-template "/_posts/.+\\.md$" "%jekyll-post" 'markdown-mode) ;; (add-template "/_layouts/.+\\.html$" "%jekyll-layout%" 'web-mode) diff --git a/init/init-cc.el b/init/init-cc.el index 573694bc6..b0998df82 100644 --- a/init/init-cc.el +++ b/init/init-cc.el @@ -4,9 +4,9 @@ (progn (after "company" (use-package company-cmake - :config (company--backend-on 'cmake-mode-hook 'company-cmake 'company-yasnippet))))) + :config + (narf/add-company-backend cmake-mode (company-cmake company-yasnippet)))))) -;; Shaders (use-package glsl-mode :mode (("\\.glsl\\'" . glsl-mode) ("\\.vert\\'" . glsl-mode) @@ -14,10 +14,17 @@ ("\\.geom\\'" . glsl-mode))) (use-package cc-mode + :defines (c-syntactic-context) + :functions (c-toggle-electric-state c-toggle-auto-newline + c-skip-comments-and-strings c-forward-sws c-end-of-macro + c-font-lock-invalid-string csharp-log c-font-lock-declarators + c-get-lang-constant c-forward-keyword-clause + c-fontify-recorded-types-and-refs c-forward-type imenu--split + c-backward-sws c-determine-limit c-beginning-of-decl-1) :commands (c-mode c++-mode objc-mode java-mode) :init (progn - (associate-mode "\\.h$" 'c++-mode) + (associate-mode "\\.h$" 'c++-mode) (associate-mode "\\.mm$" 'objc-mode)) :config (progn @@ -26,42 +33,109 @@ c-tab-always-indent nil c-electric-flag nil) - (when is-mac + (progn ; C/C++ Settings (after "flycheck" - (setq flycheck-clang-language-standard "c++11" - flycheck-clang-standard-library "libc++" - flycheck-c/c++-clang-executable "clang++" - flycheck-clang-include-path '("/usr/local/include")))) + (when IS-MAC + (setq flycheck-clang-language-standard "c++11" + flycheck-clang-standard-library "libc++" + flycheck-c/c++-clang-executable "clang++" + flycheck-clang-include-path '("/usr/local/include")))) - (after "company" - ;; TODO Clang is *really* slow in larger projects, maybe replace it with irony-mode or ycmd? - (company--backend-on 'c-mode-hook 'company-c-headers 'company-clang) - (company--backend-on 'c++-mode-hook 'company-c-headers 'company-clang) - (company--backend-on 'objc-mode-hook 'company-c-headers 'company-xcode)) + (after "company" + ;; TODO Clang is *really* slow in larger projects, maybe replace it with irony-mode or ycmd? + (narf/add-company-backend c-mode (company-c-headers company-clang)) + (narf/add-company-backend c++-mode (company-c-headers company-clang)) + (narf/add-company-backend objc-mode (company-c-headers company-xcode))) - (defun my-c-lineup-inclass (langelem) - (let ((inclass (assoc 'inclass c-syntactic-context))) - (save-excursion - (goto-char (c-langelem-pos inclass)) - (if (or (looking-at "struct") - (looking-at "typedef struct")) - '+ - '++)))) + (defun narf--c-lineup-inclass (langelem) + (let ((inclass (assoc 'inclass c-syntactic-context))) + (save-excursion + (goto-char (c-langelem-pos inclass)) + (if (or (looking-at "struct") + (looking-at "typedef struct")) + '+ + '++)))) + (defun narf|init-c/c++-settings () + (c-toggle-electric-state -1) + (c-toggle-auto-newline -1) + (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 + (c-set-offset 'access-label '-) + (c-set-offset 'inclass 'narf--c-lineup-inclass) + ;; DEL mapping interferes with smartparens and my custom DEL binding + (define-key c-mode-map (kbd "DEL") nil)) + (add-hook 'c-mode-hook 'narf|init-c/c++-settings) + (add-hook 'c++-mode-hook 'narf|init-c/c++-settings) - (defun my-c/c++-settings () - (c-toggle-electric-state -1) - (c-toggle-auto-newline -1) - (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 - (c-set-offset 'access-label '-) - (c-set-offset 'inclass 'my-c-lineup-inclass) - ;; DEL mapping interferes with smartparens and my.deflate-maybe - (define-key c-mode-map (kbd "DEL") nil)) - (add-hook 'c-mode-hook 'my-c/c++-settings) - (add-hook 'c++-mode-hook 'my-c/c++-settings) + ;; C++11 syntax support (until cc-mode is updated) + (require 'font-lock) + (defun --copy-face (new-face face) + "Define NEW-FACE from existing FACE." + (copy-face face new-face) + (eval `(defvar ,new-face nil)) + (set new-face new-face)) + + (--copy-face 'font-lock-label-face ; labels, case, public, private, proteced, namespace-tags + 'font-lock-keyword-face) + (--copy-face 'font-lock-doc-markup-face ; comment markups such as Javadoc-tags + 'font-lock-doc-face) + (--copy-face 'font-lock-doc-string-face ; comment markups + 'font-lock-comment-face) + (global-font-lock-mode t) + (setq font-lock-maximum-decoration t) + + (add-hook! 'c++-mode-hook + ;; We could place some regexes into `c-mode-common-hook', but + ;; note that their evaluation order matters. + (font-lock-add-keywords + nil '(;; complete some fundamental keywords + ("\\<\\(void\\|unsigned\\|signed\\|char\\|short\\|bool\\|int\\|long\\|float\\|double\\)\\>" . font-lock-keyword-face) + ;; namespace names and tags - these are rendered as constants by cc-mode + ("\\<\\(\\w+::\\)" . font-lock-function-name-face) + ;; new C++11 keywords + ("\\<\\(alignof\\|alignas\\|constexpr\\|decltype\\|noexcept\\|nullptr\\|static_assert\\|thread_local\\|override\\|final\\)\\>" . font-lock-keyword-face) + ("\\<\\(char16_t\\|char32_t\\)\\>" . font-lock-keyword-face) + ;; PREPROCESSOR_CONSTANT, PREPROCESSORCONSTANT + ("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face) + ("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face) + ;; hexadecimal numbers + ("\\<0[xX][0-9A-Fa-f]+\\>" . font-lock-constant-face) + ;; integer/float/scientific numbers + ("\\<[\\-+]*[0-9]*\\.?[0-9]+\\([ulUL]+\\|[eE][\\-+]?[0-9]+\\)?\\>" . font-lock-constant-face) + ;; c++11 string literals + ;; L"wide string" + ;; L"wide string with UNICODE codepoint: \u2018" + ;; u8"UTF-8 string", u"UTF-16 string", U"UTF-32 string" + ("\\<\\([LuU8]+\\)\".*?\"" 1 font-lock-keyword-face) + ;; R"(user-defined literal)" + ;; R"( a "quot'd" string )" + ;; R"delimiter(The String Data" )delimiter" + ;; R"delimiter((a-z))delimiter" is equivalent to "(a-z)" + ("\\(\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\)" 1 font-lock-keyword-face t) ; start delimiter + ( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\(.*?\\))[^\\s-\\\\()]\\{0,16\\}\"" 1 font-lock-string-face t) ; actual string + ( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(.*?\\()[^\\s-\\\\()]\\{0,16\\}\"\\)" 1 font-lock-keyword-face t) ; end delimiter + + ;; user-defined types (rather project-specific) + ("\\<[A-Za-z_]+[A-Za-z_0-9]*_\\(type\\|ptr\\)\\>" . font-lock-type-face) + ("\\<\\(xstring\\|xchar\\)\\>" . font-lock-type-face) + )) t) + + ;; Fix enum and C++11 lambda indentation + (defadvice c-lineup-arglist (around c-lineup-arglist-indent-fix activate) + "Improve indentation of continued C++11 lambda function opened as argument." + (setq ad-return-value + (if (and (equal major-mode 'c++-mode) + (ignore-errors + (save-excursion + (goto-char (c-langelem-pos langelem)) + ;; Detect "[...](" or "[...]{". preceded by "," or "(", + ;; and with unclosed brace. + (looking-at ".*[(,][ \t]*\\[[^]]*\\][ \t]*[({][^}]*$")))) + 0 ; no additional indent + ad-do-it)))) (progn ; Obj-C (add-to-list 'magic-mode-alist @@ -70,75 +144,8 @@ (re-search-forward "@\\" magic-mode-regexp-match-limit t))) . objc-mode)) - (after "flycheck" (add-hook! 'objc-mode-hook (use-package flycheck-objc)))) - - - ;; C++11 syntax support (until cc-mode is updated) - (require 'font-lock) - (defun --copy-face (new-face face) - "Define NEW-FACE from existing FACE." - (copy-face face new-face) - (eval `(defvar ,new-face nil)) - (set new-face new-face)) - - (--copy-face 'font-lock-label-face ; labels, case, public, private, proteced, namespace-tags - 'font-lock-keyword-face) - (--copy-face 'font-lock-doc-markup-face ; comment markups such as Javadoc-tags - 'font-lock-doc-face) - (--copy-face 'font-lock-doc-string-face ; comment markups - 'font-lock-comment-face) - (global-font-lock-mode t) - (setq font-lock-maximum-decoration t) - - (add-hook! 'c++-mode-hook - ;; We could place some regexes into `c-mode-common-hook', but - ;; note that their evaluation order matters. - (font-lock-add-keywords - nil '(;; complete some fundamental keywords - ("\\<\\(void\\|unsigned\\|signed\\|char\\|short\\|bool\\|int\\|long\\|float\\|double\\)\\>" . font-lock-keyword-face) - ;; namespace names and tags - these are rendered as constants by cc-mode - ("\\<\\(\\w+::\\)" . font-lock-function-name-face) - ;; new C++11 keywords - ("\\<\\(alignof\\|alignas\\|constexpr\\|decltype\\|noexcept\\|nullptr\\|static_assert\\|thread_local\\|override\\|final\\)\\>" . font-lock-keyword-face) - ("\\<\\(char16_t\\|char32_t\\)\\>" . font-lock-keyword-face) - ;; PREPROCESSOR_CONSTANT, PREPROCESSORCONSTANT - ("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face) - ("\\<[A-Z]\\{3,\\}\\>" . font-lock-constant-face) - ;; hexadecimal numbers - ("\\<0[xX][0-9A-Fa-f]+\\>" . font-lock-constant-face) - ;; integer/float/scientific numbers - ("\\<[\\-+]*[0-9]*\\.?[0-9]+\\([ulUL]+\\|[eE][\\-+]?[0-9]+\\)?\\>" . font-lock-constant-face) - ;; c++11 string literals - ;; L"wide string" - ;; L"wide string with UNICODE codepoint: \u2018" - ;; u8"UTF-8 string", u"UTF-16 string", U"UTF-32 string" - ("\\<\\([LuU8]+\\)\".*?\"" 1 font-lock-keyword-face) - ;; R"(user-defined literal)" - ;; R"( a "quot'd" string )" - ;; R"delimiter(The String Data" )delimiter" - ;; R"delimiter((a-z))delimiter" is equivalent to "(a-z)" - ("\\(\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\)" 1 font-lock-keyword-face t) ; start delimiter - ( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\(.*?\\))[^\\s-\\\\()]\\{0,16\\}\"" 1 font-lock-string-face t) ; actual string - ( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(.*?\\()[^\\s-\\\\()]\\{0,16\\}\"\\)" 1 font-lock-keyword-face t) ; end delimiter - - ;; user-defined types (rather project-specific) - ("\\<[A-Za-z_]+[A-Za-z_0-9]*_\\(type\\|ptr\\)\\>" . font-lock-type-face) - ("\\<\\(xstring\\|xchar\\)\\>" . font-lock-type-face) - )) t) - - ;; Fix enum and C++11 lambda indentation - (defadvice c-lineup-arglist (around c-lineup-arglist-indent-fix activate) - "Improve indentation of continued C++11 lambda function opened as argument." - (setq ad-return-value - (if (and (equal major-mode 'c++-mode) - (ignore-errors - (save-excursion - (goto-char (c-langelem-pos langelem)) - ;; Detect "[...](" or "[...]{". preceded by "," or "(", - ;; and with unclosed brace. - (looking-at ".*[(,][ \t]*\\[[^]]*\\][ \t]*[({][^}]*$")))) - 0 ; no additional indent - ad-do-it))) ; default behavior + (after "flycheck" + (add-hook! 'objc-mode-hook (use-package flycheck-objc)))) )) diff --git a/init/init-company.el b/init/init-company.el deleted file mode 100644 index b39cbecde..000000000 --- a/init/init-company.el +++ /dev/null @@ -1,121 +0,0 @@ -(use-package company - :diminish company-mode - :config - (progn - (global-company-mode 1) - (setq company-idle-delay nil - company-minimum-prefix-length 1 - company-show-numbers nil - company-tooltip-limit 20 - company-dabbrev-downcase nil - company-dabbrev-ignore-case nil - company-tooltip-align-annotations t - company-require-match 'never - company-global-modes - '(not eshell-mode comint-mode org-mode erc-mode message-mode help-mode)) - - (require 'color) - (let ((bg (face-attribute 'default :background))) - (custom-set-faces - `(company-tooltip ((t (:inherit default :background ,(color-lighten-name bg 9))))) - `(company-scrollbar-bg ((t (:background ,(color-lighten-name bg 15))))) - `(company-scrollbar-fg ((t (:background ,(color-lighten-name bg 5))))) - `(company-search ((t (:background ,(color-lighten-name bg 15))))) - `(company-tooltip-selection ((t (:inherit font-lock-function-name-face)))) - `(company-tooltip-common ((t (:inherit font-lock-constant-face)))))) - - ;; Sort candidates by - (add-to-list 'company-transformers 'company-sort-by-occurrence) - (use-package company-statistics - :config - (progn - (setq company-statistics-file (expand-file-name "company-statistics-cache.el" my-tmp-dir)) - (company-statistics-mode))) - - ;; frontends - (setq-default company-frontends '(company-pseudo-tooltip-unless-just-one-frontend - company-echo-metadata-frontend - company-preview-if-just-one-frontend)) - - (progn ; backends - (defun company--backend-on (hook &rest backends) - (add-hook hook - `(lambda() - (set (make-local-variable 'company-backends) - (append '((,@backends company-semantic)) company-backends))))) - - (company--backend-on 'nxml-mode-hook 'company-nxml 'company-yasnippet) - (company--backend-on 'emacs-lisp-mode-hook 'company-elisp 'company-yasnippet) - - ;; Rewrite evil-complete to use company-dabbrev - (setq company-dabbrev-code-other-buffers t) - (setq company-dabbrev-code-buffers nil) - (setq evil-complete-next-func - (lambda(arg) - (call-interactively 'company-dabbrev) - (if (eq company-candidates-length 1) - (company-complete)))) - (setq evil-complete-previous-func - (lambda (arg) - (let ((company-selection-wrap-around t)) - (call-interactively 'company-dabbrev) - (if (eq company-candidates-length 1) - (company-complete) - (call-interactively 'company-select-previous))))) - - ;; Simulates ac-source-dictionary (without global dictionary) - (defconst my-dicts-dir (concat my-dir "dict/")) - (defvar company-dictionary-alist '()) - (defvar company-dictionary-major-minor-modes '()) - (defun company-dictionary-active-minor-modes () - (-filter (lambda (mode) (when (boundp mode) (symbol-value mode))) company-dictionary-major-minor-modes)) - (defun company-dictionary-assemble () - (let ((minor-modes (company-dictionary-active-minor-modes)) - (dicts (cdr (assq major-mode company-dictionary-alist)))) - (dolist (mode minor-modes) - (setq dicts (append dicts (cdr (assq mode company-dictionary-alist))))) - dicts)) - (defun company-dictionary-init () - (dolist (file (f-files my-dicts-dir)) - (add-to-list 'company-dictionary-alist `(,(intern (f-base file)) ,@(s-split "\n" (f-read file) t))))) - (defun company-dictionary (command &optional arg &rest ignored) - "`company-mode' back-end for user-provided dictionaries." - (interactive (list 'interactive)) - (unless company-dictionary-alist (company-dictionary-init)) - (let ((dict (company-dictionary-assemble))) - (cl-case command - (interactive (company-begin-backend 'company-dictionary)) - (prefix (and dict (or (company-grab-symbol) 'stop))) - (candidates - (let ((completion-ignore-case nil) - (symbols dict)) - (all-completions arg symbols))) - (sorted t)))) - - (setq-default company-backends '((company-capf company-yasnippet) (company-dictionary company-keywords))) - - (progn ; keybinds - (define-key company-active-map "C-w" nil) - (bind company-active-map - "C-o" 'company-search-kill-others - "C-n" 'company-select-next-or-abort - "C-p" 'company-select-previous-or-abort - "C-h" 'company-show-doc-buffer - "C-S-h" 'company-show-location - "C-S-s" 'company-search-candidates - "C-s" 'company-filter-candidates - "C-SPC" 'company-complete-common - [tab] 'company-complete - "" 'company-select-previous - [escape] 'company-abort) - - (bind company-search-map - "C-n" 'company-search-repeat-forward - "C-p" 'company-search-repeat-backward - [escape] 'company-abort) - - (bind company-active-map "" 'helm-company))))) - - -(provide 'init-company) -;;; init-company.el ends here diff --git a/init/init-cscope.el b/init/init-cscope.el index 716ad44fa..01fb8e7c0 100644 --- a/init/init-cscope.el +++ b/init/init-cscope.el @@ -7,4 +7,5 @@ (add-hook 'ruby-mode-hook (function cscope-minor-mode)) + (provide 'init-cscope) diff --git a/init/init-csharp.el b/init/init-csharp.el index 43701c0ea..74ad7da78 100644 --- a/init/init-csharp.el +++ b/init/init-csharp.el @@ -1,7 +1,8 @@ (use-package csharp-mode :mode "\\.cs$" + :init + (add-hook 'csharp-mode-hook 'flycheck-mode) :config (progn - (after "flycheck" (add-hook 'csharp-mode-hook 'flycheck-mode)) (use-package omnisharp :defer t :config @@ -9,15 +10,16 @@ (setq omnisharp-server-executable-path "~/Dropbox/projects/lib/Omnisharp/server/OmniSharp/bin/Debug/OmniSharp.exe") - (bind 'normal omnisharp-mode-map + (bind :normal :map omnisharp-mode-map "gd" 'omnisharp-go-to-definition) (after "company" - (company--backend-on 'csharp-mode-hook 'company-omnisharp) - (add-hook 'csharp-mode-hook 'turn-on-eldoc-mode)))))) + (narf/add-company-backend csharp-mode (company-omnisharp)) + (add-hook 'csharp-mode-hook 'turn-on-eldoc-mode)))))) ;; unity shaders (use-package shaderlab-mode :mode "\\.shader$") + (provide 'init-csharp) ;;; init-csharp.el ends here diff --git a/init/init-data.el b/init/init-data.el new file mode 100644 index 000000000..604a96adf --- /dev/null +++ b/init/init-data.el @@ -0,0 +1,11 @@ +(use-package yaml-mode + :mode "\\.ya?ml$" + :init (add-hook 'yaml-mode-hook 'narf|enable-tab-width-2)) + +(use-package json-mode + :mode (("\\.json$" . json-mode) + ("\\.jshintrc$" . json-mode))) + + +(provide 'init-data) +;;; init-data.el ends here diff --git a/init/init-eshell.el b/init/init-eshell.el index a588446f5..c82db062b 100644 --- a/init/init-eshell.el +++ b/init/init-eshell.el @@ -3,13 +3,13 @@ ;; (push '("*eshell*" :position left :width 80 :stick t) popwin:special-display-config) ;; ;; eshell -;; (setq eshell-directory-name (concat my-tmp-dir "eshell")) +;; (setq eshell-directory-name (concat TMP-DIR "eshell")) ;; (setq eshell-scroll-to-bottom-on-input 'all) ;; (setq eshell-buffer-shorthand t) ;; ;; em-alias -;; (setq eshell-aliases-file (concat my-tmp-dir ".eshell-aliases")) +;; (setq eshell-aliases-file (concat TMP-DIR ".eshell-aliases")) ;; ;; em-glob diff --git a/init/init-fly.el b/init/init-fly.el index ead16fcf6..9fff7c27f 100644 --- a/init/init-fly.el +++ b/init/init-fly.el @@ -1,39 +1,42 @@ (use-package flycheck + :functions (flycheck-buffer) :commands (flycheck-mode flycheck-list-errors) :init - (add-hooks '(ruby-mode-hook - python-mode-hook - php-mode-hook - lua-mode-hook - shell-mode-hook - scss-mode-hook - c++-mode-hook - c-mode-hook) - 'flycheck-mode) + (add-to-hooks 'flycheck-mode '(ruby-mode-hook + python-mode-hook + php-mode-hook + lua-mode-hook + shell-mode-hook + scss-mode-hook + c++-mode-hook + c-mode-hook)) :config (progn ; flycheck settings + (defun my-shorter-fly-status (result) + (format "[%s]" (replace-regexp-in-string " FlyC:?" "" result))) + (advice-add 'flycheck-mode-line-status-text :filter-return 'my-shorter-fly-status) + (setq-default flycheck-indication-mode 'right-fringe ;; Removed checks on idle/change for snappiness flycheck-check-syntax-automatically '(save mode-enabled idle-change) flycheck-disabled-checkers '(emacs-lisp-checkdoc make)) - (my--cleanup-buffers-add "^\\*Flycheck.*\\*$") + (narf/add-throwaway-buffer "^\\*Flycheck.*\\*$") - (bind 'normal flycheck-error-list-mode-map + (bind :normal :map flycheck-error-list-mode-map [escape] 'kill-this-buffer "q" 'kill-this-buffer) (evil-initial-state 'flycheck-error-list-mode 'emacs) - (defun my--evil-flycheck-buffer () + (defun narf/evil-flycheck-buffer () (if (and (featurep 'flycheck) flycheck-mode) (flycheck-buffer))) ;; Check buffer when normal mode is entered - (add-hook 'evil-normal-state-entry-hook 'my--evil-flycheck-buffer) + (add-hook 'evil-normal-state-entry-hook 'narf/evil-flycheck-buffer) ;; And on ESC in normal mode. - (defadvice evil-force-normal-state (after evil-esc-flycheck-buffer activate) - (my--evil-flycheck-buffer)))) + (advice-add 'evil-force-normal-state :after 'narf/evil-flycheck-buffer))) (use-package flyspell :commands flyspell-mode) diff --git a/init/init-go.el b/init/init-go.el index f940da5c7..63d858d7d 100644 --- a/init/init-go.el +++ b/init/init-go.el @@ -3,11 +3,11 @@ :interpreter "go" :config (progn - (bind 'normal go-mode-map "gd" 'godef-jump) + (bind normal :map go-mode-map "gd" 'godef-jump) (use-package company-go :config - (company--backend-on 'go-mode-hook 'company-go 'company-yasnippet)))) + (narf/add-company-backend go-mode (company-go company-yasnippet))))) (provide 'init-go) diff --git a/init/init-helm.el b/init/init-helm.el index 1b11a75db..a5445d1f3 100644 --- a/init/init-helm.el +++ b/init/init-helm.el @@ -1,9 +1,64 @@ -;; Ex-mode interface for `helm-recentf' and `helm-projectile-recentf'. If -;; `bang', then `search' is interpreted as regexp -(evil-define-command my:helm-recentf (&optional bang) - :repeat nil - (interactive "") - (if bang (helm-recentf) (helm-projectile-recentf))) +(use-package helm + :commands (helm + helm-etags-select + helm-show-kill-ring + helm-bookmarks + helm-wg + helm-ag + helm-alive-p + helm-attrset) + :init + (progn + (defvar helm-global-prompt ">>> ") + (evil-set-initial-state 'helm-mode 'emacs)) + :config + (progn + (use-package helm-grep) + (use-package helm-ag + :functions (helm-ag--select-source) + :defines (helm-ag-source helm-ag--last-query)) + + ;; No persistent header + (defun narf--helm-display-mode-line (source &optional force) + (setq mode-line-format nil) + (setq header-line-format nil)) + (advice-add 'helm-display-mode-line :override 'narf--helm-display-mode-line) + + ;; Minimalistic split-fn; leaves popwin to handle helm buffers + (defun narf--helm-split-window-fn (window) + (if (one-window-p t) + (let ((helm-full-frame t)) + (selected-window)) + (other-window-for-scrolling))) + + (setq helm-quick-update t + helm-idle-delay 0.05 + helm-input-idle-delay 0.05 + helm-reuse-last-window-split-state t + helm-buffers-fuzzy-matching t + helm-candidate-number-limit 40 + helm-bookmark-show-location t + helm-split-window-default-side 'other + helm-split-window-preferred-function 'narf--helm-split-window-fn) ; let popwin handle this + + (after "winner" + ;; Tell winner-mode to ignore helm buffers + (dolist (bufname '("*helm recentf*" + "*helm projectile*" + "*helm imenu*" + "*helm company*" + "*helm buffers*" + ;; "*helm tags*" + "*helm-ag*" + "*Helm Swoop*")) + (push bufname winner-boring-buffers))) + (narf/add-throwaway-buffer "^\\*[Hh]elm.*\\*$") + + (bind :map helm-map + "C-w" 'evil-delete-backward-word + "C-u" 'helm-delete-minibuffer-contents + "C-r" 'evil-ex-paste-from-register ; Evil registers in helm! Glorious! + [escape] 'helm-keyboard-quit))) (use-package projectile :commands (projectile-ack @@ -28,6 +83,8 @@ projectile-switch-to-buffer projectile-vc projectile-project-p + projectile-global-mode + helm-projectile-switch-to-buffer helm-projectile-find-file helm-projectile-recentf helm-projectile-find-other-file @@ -35,12 +92,15 @@ :diminish projectile-mode :config (progn + (defun narf/project-invalidate-cache-maybe () + (when (projectile-project-p) (projectile-invalidate-cache nil))) + (add-hook 'kill-emacs-hook 'narf/project-invalidate-cache-maybe) (setq-default projectile-enable-caching t) (setq projectile-sort-order 'recentf - projectile-cache-file (concat my-tmp-dir "projectile.cache") - projectile-known-projects-file (concat my-tmp-dir "projectile.projects") + projectile-cache-file (concat TMP-DIR "projectile.cache") + projectile-known-projects-file (concat TMP-DIR "projectile.projects") projectile-indexing-method 'alien - projectile-project-root-files project-root-files) + projectile-project-root-files narf/project-root-files) (add-to-list 'projectile-globally-ignored-files "ido.last") (add-to-list 'projectile-globally-ignored-directories "assets") (add-to-list 'projectile-other-file-alist '("scss" "css")) @@ -52,76 +112,35 @@ ;; Don't show the project name in the prompts; I already know. (defun projectile-prepend-project-name (string) helm-global-prompt))) -(use-package helm - :commands (helm - helm-M-x - helm-buffers-list - helm-semantic-or-imenu - helm-etags-select - helm-apropos - helm-show-kill-ring - helm-bookmarks - helm-wg) - :init - (evil-set-initial-state 'helm-mode 'emacs) +(use-package helm-org + :commands (helm-org-in-buffer-headings + helm-org-agenda-files-headings + helm-org-capture-templates) :config - (progn ; helm settings - (defvar helm-global-prompt ">>> ") - (setq helm-quick-update t - helm-idle-delay 0.01 - helm-input-idle-delay 0.01 - helm-reuse-last-window-split-state t - helm-buffers-fuzzy-matching nil - helm-candidate-number-limit 40 - helm-bookmark-show-location t) - - (after "winner" - ;; Tell winner-mode to ignore helm buffers - (dolist (bufname '("*helm recentf*" - "*helm projectile*" - "*helm imenu*" - "*helm company*" - "*helm buffers*" - ;; "*helm tags*" - "*helm-ag*" - "*Helm Swoop*")) - (push bufname winner-boring-buffers))) - - (my--cleanup-buffers-add "^\\*[Hh]elm.*\\*$") - - (progn ; helm hacks - ;; No persistent header - (defadvice helm-display-mode-line (after undisplay-header activate) - (setq header-line-format nil)) - - ;; Hide the mode-line in helm (<3 minimalism) - (defun helm-display-mode-line (source &optional force) - (set (make-local-variable 'helm-mode-line-string) - (helm-interpret-value (or (and (listp source) ; Check if source is empty. - (assoc-default 'mode-line source)) - (default-value 'helm-mode-line-string)) - source)) - (let ((follow (and (eq (cdr (assq 'follow source)) 1) "(HF) "))) - (if helm-mode-line-string - (setq mode-line-format nil) - (setq mode-line-format (default-value 'mode-line-format))) - (let* ((hlstr (helm-interpret-value - (and (listp source) - (assoc-default 'header-line source)) - source)) - (hlend (make-string (max 0 (- (window-width) (length hlstr))) ? ))) - (setq header-line-format - (propertize (concat " " hlstr hlend) 'face 'helm-header)))) - (when force (force-mode-line-update)))) - - (bind helm-map - "C-w" 'evil-delete-backward-word - "C-u" 'helm-delete-minibuffer-contents - "C-r" 'evil-ex-paste-from-register ; Evil registers in helm! Glorious! - [escape] 'helm-keyboard-quit))) + (defun helm-get-org-candidates-in-file (filename min-depth max-depth + &optional fontify nofname) + (with-current-buffer (pcase filename + ((pred bufferp) filename) + ((pred stringp) (find-file-noselect filename))) + (and fontify (jit-lock-fontify-now)) + (let ((match-fn (if fontify 'match-string 'match-string-no-properties))) + (save-excursion + (goto-char (point-min)) + (cl-loop with width = (window-width) + while (re-search-forward org-complex-heading-regexp nil t) + if (let ((num-stars (length (match-string-no-properties 1)))) + (and (>= num-stars min-depth) (<= num-stars max-depth))) + collect `(,(let ((heading (funcall match-fn 4)) + (file (unless nofname + (concat (f-no-ext (f-relative filename org-directory)) ":"))) + (level (length (match-string-no-properties 1)))) + (org-format-outline-path + (append (org-get-outline-path t level heading) + (list heading)) width file)) + . ,(point-marker)))))))) (use-package helm-files - :commands (helm-recentf) + :commands helm-recentf :config (progn ;; Reconfigured `helm-recentf' to use `helm', instead of `helm-other-buffer' @@ -132,75 +151,26 @@ :buffer "*helm recentf*" :prompt helm-global-prompt))))) -(use-package helm-ag - :commands (helm-ag - my:helm-ag-search - my:helm-ag-regex-search - my:helm-ag-search-cwd - my:helm-ag-regex-search-cwd) - :config - (progn - ;; Ex-mode interface for `helm-ag'. If `bang', then `search' is interpreted as - ;; regexp. - (evil-define-operator my:helm-ag-search (beg end &optional search hidden-files-p pwd-p regex-p) - :type inclusive - :repeat nil - (interactive "") - (let* ((helm-ag-default-directory (if pwd-p default-directory (project-root))) - (helm-ag-command-option (concat (unless regex-p "-Q ") (if hidden-files-p "--hidden "))) - (input "") - (header-name (format "Search in %s" helm-ag-default-directory))) - (if search - (progn - (helm-attrset 'search-this-file nil helm-ag-source) - (setq helm-ag--last-query search)) - (if (and beg end (/= beg (1- end))) - (setq input (buffer-substring-no-properties beg end)))) - (helm-attrset 'name header-name helm-ag-source) - (helm :sources (if search (helm-ag--select-source) '(helm-source-do-ag)) - :buffer "*helm-ag*" - :input input - :prompt helm-global-prompt))) - - (evil-define-operator my:helm-ag-regex-search (beg end &optional search bang) - :type inclusive :repeat nil - (interactive "") - (my:helm-ag-search beg end search bang nil t)) - (evil-define-operator my:helm-ag-search-cwd (beg end &optional search bang) - ;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted - ;; as regexp - :type inclusive :repeat nil - (interactive "") - (my:helm-ag-search beg end search bang t nil)) - (evil-define-operator my:helm-ag-regex-search-cwd (beg end &optional search bang) - :type inclusive :repeat nil - (interactive "") - (my:helm-ag-search beg end search bang t t)))) - -(use-package helm-company :defer t) - (use-package helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss - :commands (helm-css-scss - helm-css-scss-multi - helm-css-scss-insert-close-comment)) + :commands (helm-css-scss + helm-css-scss-multi + helm-css-scss-insert-close-comment)) (use-package helm-swoop ; https://github.com/ShingoFukuyama/helm-swoop - :commands (helm-swoop helm-multi-swoop my:helm-swoop) + :defines (helm-swoop-last-prefix-number) + :commands (helm-swoop helm-multi-swoop helm-multi-swoop-all) :config - (progn - (setq helm-swoop-use-line-number-face t - helm-swoop-split-with-multiple-windows t - helm-swoop-speed-or-color t) + (setq helm-swoop-use-line-number-face t + helm-swoop-split-with-multiple-windows t + helm-swoop-speed-or-color t)) + +(use-package helm-c-yasnippet :commands helm-yas-visit-snippet-file) +(use-package helm-buffers :commands helm-buffers-list) +(use-package helm-semantic :commands helm-semantic-or-imenu) +(use-package helm-elisp :commands helm-apropos) +(use-package helm-command :commands helm-M-x) +(use-package helm-company :defer t) - ;; Ex-mode interface for `helm-swoop', `helm-multi-swoop-all' (if `bang'), or - ;; `helm-css-scss' and `helm-css-scss-multi' (if `bang') if major-mode is - ;; `scss-mode' - (evil-define-command my:helm-swoop (&optional search bang) - :repeat nil - (interactive "") - (if (eq major-mode 'scss-mode) - (if bang (helm-css-scss-multi search) (helm-css-scss search)) - (if bang (helm-multi-swoop-all search) (helm-swoop :$query search)))))) (provide 'init-helm) ;;; init-helm.el ends here diff --git a/init/init-ido.el b/init/init-ido.el index 07bb7fbc6..f06d74f67 100644 --- a/init/init-ido.el +++ b/init/init-ido.el @@ -1,67 +1,61 @@ -;; 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 ()) -;; (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)) +(use-package ido + :defines (flx-ido-mode ido-ubiquitous-debug-mode ido-context-switch-command ido-temp-list) + :functions (ido-to-end) + :commands (ido-mode + ido-everywhere + ido-vertical-mode + flx-ido-mode + ido-ubiquitous-mode + ido-find-file + ido-find-file-in-dir) + :config + (progn + (ido-mode 1) + (ido-everywhere 1) -;; (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-vertical-mode :config (ido-vertical-mode 1)) + (use-package flx-ido :config (flx-ido-mode 1)) + (use-package ido-ubiquitous :config (ido-ubiquitous-mode 1)) + (setq ido-use-faces nil + ido-confirm-unique-completion t + ido-case-fold t + ido-enable-tramp-completion nil + ido-enable-flex-matching t + ido-create-new-buffer 'always + ido-enable-tramp-completion t + ido-enable-last-directory-history t + ido-save-directory-list-file (concat TMP-DIR "ido.last")) -(ido-mode 1) -(ido-everywhere 1) + (add-to-list 'ido-ignore-files "\\`.DS_Store$") + (add-to-list 'ido-ignore-files "Icon\\?$") + (setq ido-ignore-buffers + '("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer" + "^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-" + "_region_" " output\\*$" "^TAGS$" "^\*Ido")) -(use-package ido-vertical-mode :config (ido-vertical-mode 1)) -(use-package flx-ido :config (flx-ido-mode 1)) -(use-package ido-ubiquitous :config (ido-ubiquitous-mode 1)) + ; sort ido filelist by mtime instead of alphabetically + (add-hook 'ido-make-file-list-hook 'ido-sort-mtime) + (add-hook 'ido-make-dir-list-hook 'ido-sort-mtime) + (defun ido-sort-mtime () + (setq ido-temp-list + (sort ido-temp-list + (lambda (a b) + (time-less-p + (sixth (file-attributes (concat ido-current-directory b))) + (sixth (file-attributes (concat ido-current-directory a))))))) + (ido-to-end ;; move . files to end (again) + (delq nil (mapcar + (lambda (x) (and (char-equal (string-to-char x) ?.) x)) + ido-temp-list)))) -(setq ido-use-faces nil - ido-confirm-unique-completion t - ido-case-fold t - ido-enable-tramp-completion nil - ido-enable-flex-matching t - ido-create-new-buffer 'always - ido-enable-tramp-completion t - ido-enable-last-directory-history t - ido-save-directory-list-file (concat my-tmp-dir "ido.last")) - -(add-to-list 'ido-ignore-files "\\`.DS_Store$") -(add-to-list 'ido-ignore-files "Icon\\?$") -(setq ido-ignore-buffers - '("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer" - "^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-" - "_region_" " output\\*$" "^TAGS$" "^\*Ido")) - -; sort ido filelist by mtime instead of alphabetically -(add-hook 'ido-make-file-list-hook 'ido-sort-mtime) -(add-hook 'ido-make-dir-list-hook 'ido-sort-mtime) -(defun ido-sort-mtime () - (setq ido-temp-list - (sort ido-temp-list - (lambda (a b) - (time-less-p - (sixth (file-attributes (concat ido-current-directory b))) - (sixth (file-attributes (concat ido-current-directory a))))))) - (ido-to-end ;; move . files to end (again) - (delq nil (mapcar - (lambda (x) (and (char-equal (string-to-char x) ?.) x)) - ido-temp-list)))) - -;; Press ~ to go to $HOME in ido -(add-hook 'ido-setup-hook - (lambda () - ;; Go straight home - (define-key ido-file-completion-map - (kbd "~") - (lambda () - (interactive) - (if (looking-back "/") - (insert "~/") - (call-interactively 'self-insert-command)))))) + ;; Press ~ to go to $HOME in ido + (add-hook! 'ido-setup-hook + ;; Go straight home + (define-key ido-file-completion-map (kbd "~") + (λ (if (looking-back "/") + (insert "~/") + (call-interactively 'self-insert-command))))))) (provide 'init-ido) diff --git a/init/init-java.el b/init/init-java.el index 1644024a8..cbd3edf06 100644 --- a/init/init-java.el +++ b/init/init-java.el @@ -1,21 +1,22 @@ -(defun my-java-project-package () +(defun narf/java-project-package () (if (eq major-mode 'java-mode) (s-chop-suffix "." (s-replace "/" "." (f-dirname (f-relative (buffer-file-name) - (concat (project-root) "/src/"))))) + (concat (narf/project-root) "/src/"))))) "")) -(defun my-java-class-name () +(defun narf/java-class-name () (if (eq major-mode 'java-mode) (f-no-ext (f-base (buffer-file-name))) "")) (use-package eclim + :functions (eclim--project-dir eclim--project-name) :commands (eclim-mode global-eclim-mode) :init (progn (setq eclim-eclipse-dirs '("/Applications/eclipse") - eclim-executable "/Applications/eclipse/eclim") - (when (f-exists? eclim-executable) + eclim-executable "/Applications/eclipse/eclim") + (when (file-exists-p eclim-executable) (add-hook 'java-mode-hook 'eclim-mode))) :config (progn @@ -35,21 +36,21 @@ (use-package company-emacs-eclim :config (company-emacs-eclim-setup))) - (bind 'motion java-mode-map "gd" 'eclim-java-find-declaration))) - -(use-package groovy-mode :mode "\\.gradle$") + (bind :motion :map java-mode-map "gd" 'eclim-java-find-declaration))) (use-package android-mode - :defer t :commands android-mode :init (progn + ;; yasnippet defuns (defun android-mode-is-layout-file () (and android-mode (eq major-mode 'nxml-mode) (string-equal (file-name-base (directory-file-name default-directory)) "layout"))) + (defun android-mode-in-tags (&rest tags) (-contains? tags (android-mode-tag-name))) + (defun android-mode-tag-name () (save-excursion (let (beg end) @@ -60,18 +61,23 @@ (setq end (1+ (point))) (buffer-substring-no-properties beg end)))) - (defun my-android-mode-enable-maybe () - (let ((root (project-root))) - (when (or (project-has-files "local.properties" root) - (project-has-files "AndroidManifest.xml" root) - (project-has-files "src/main/AndroidManifest.xml" root)) + (defun narf|android-mode-enable-maybe () + (let ((root (narf/project-root))) + (when (or (narf/project-has-files "local.properties" root) + (narf/project-has-files "AndroidManifest.xml" root) + (narf/project-has-files "src/main/AndroidManifest.xml" root)) (android-mode +1) - (set-build-command "./gradlew %s" "build.gradle")))) + (narf/set-build-command "./gradlew %s" "build.gradle")))) + (after "company" (add-to-list 'company-dictionary-major-minor-modes 'android-mode)) - (add-hook 'java-mode-hook 'my-android-mode-enable-maybe) - (add-hook 'groovy-mode-hook 'my-android-mode-enable-maybe) - (add-hook 'nxml-mode-hook 'my-android-mode-enable-maybe) - (add-hook! 'android-mode-hook (my--init-yas-mode 'android-mode)))) + (add-hook 'java-mode-hook 'narf|android-mode-enable-maybe) + (add-hook 'groovy-mode-hook 'narf|android-mode-enable-maybe) + (add-hook 'nxml-mode-hook 'narf|android-mode-enable-maybe) + (add-hook! 'android-mode-hook (narf/init-yas-mode 'android-mode)))) + +(use-package groovy-mode + :functions (is-groovy-mode) + :mode "\\.gradle$") (provide 'init-java) diff --git a/init/init-js.el b/init/init-js.el index 30c27991f..e6552386c 100644 --- a/init/init-js.el +++ b/init/init-js.el @@ -14,29 +14,24 @@ (after "web-beautify" (add-hook! 'js2-mode-hook (setenv "jsbeautify_indent_size" "4")) - (bind 'motion js2-mode-map "gQ" 'web-beautify-js)) + (bind :motion :map js2-mode-map "gQ" 'web-beautify-js)) (after "emr" (use-package js2-refactor)) - (rename-mode-name js2-mode "Javascript2") + ;; [pedantry intensifies] + (defadvice js2-mode (after js2-mode-rename-modeline activate) + (setq mode-name "Javascript2")) (use-package tern :diminish (tern-mode . "tern") :commands tern-mode - :init (add-hook 'js2-mode-hook 'tern-mode) + :init + (add-hook 'js2-mode-hook 'tern-mode) :config (after "company" (use-package company-tern :config - (company--backend-on 'js2-mode-hook 'company-tern) - ;; (setq company-tern-meta-as-single-line t) - ;; (setq company-tern-property-marker "") - ;; (setq company-tooltip-align-annotations t) - ))))) - -(use-package json-mode - :mode (("\\.json$" . json-mode) - ("\\.jshintrc$" . json-mode))) + (narf/add-company-backend js2-mode (company-tern))))))) ;; For UnityScript (use-package unityjs-mode @@ -45,14 +40,18 @@ (progn (add-hook 'unityjs-mode-hook 'flycheck-mode) (add-hook! 'unityjs-mode-hook - (enable-tab-width-2) + (narf|enable-tab-width-2) (setq js-indent-level 2)))) +;; For launchbar script development (define-minor-mode lb6-mode - :lighter " lb6" - :keymap (make-sparse-keymap) - (my--init-yas-mode 'lb6-mode)) + "Launchbar development mode." + :init-value nil + :lighter "lb6" + :keymap (make-sparse-keymap) + (narf/init-yas-mode 'lb6-mode)) (associate-minor-mode "\\.lb\\(action\\|ext\\)/.*$" 'lb6-mode) + (provide 'init-js) ;;; init-js.el ends here diff --git a/init/init-lisp.el b/init/init-lisp.el new file mode 100644 index 000000000..55aac4225 --- /dev/null +++ b/init/init-lisp.el @@ -0,0 +1,19 @@ + +;; TODO: Do this later + +(add-hook! 'hs-minor-mode-hook (when hs-minor-mode (hs-hide-level 3))) + +;; [pedantry intensifies] +(defadvice emacs-lisp-mode (after emacs-lisp-mode-rename-modeline activate) + (setq mode-name "Elisp")) + +;; Real go-to-definition for elisp +(bind :motion :map emacs-lisp-mode-map + "gd" (λ (let ((func (function-called-at-point))) + (if func (find-function func)))) + "gD" (λ (let ((func (function-called-at-point))) + (if func (find-function-other-window func))))) + + +(provide 'init-lisp) +;;; init-lisp.el ends here diff --git a/init/init-lua.el b/init/init-lua.el index 616a954d0..9f3fc9f7d 100644 --- a/init/init-lua.el +++ b/init/init-lua.el @@ -3,21 +3,25 @@ :interpreter "lua" :init (progn - (define-minor-mode love-mode - "Buffer local minor mode for Love2D" - :init-value nil - :lighter " <3" - :keymap (make-sparse-keymap) - (my--init-yas-mode 'love-mode)) - (add-hook! 'lua-mode-hook - (setq lua-indent-level tab-width) - (set-build-command "open -a love.app '%s'" "main.lua") - (when (project-has-files "main.lua") - (love-mode +1))) + (setq lua-indent-level tab-width) + + (when (file-exists-p "/Applications/love.app") + (define-minor-mode love-mode + "Buffer local minor mode for Love2D" + :init-value nil + :lighter " <3" + :keymap (make-sparse-keymap) + (narf/init-yas-mode 'love-mode)) + (add-hook! 'lua-mode-hook + (narf/set-build-command "open -a love.app '%s'" "main.lua") + (when (narf/project-has-files "main.lua") + (love-mode +1)))) (after "company" (add-to-list 'company-dictionary-major-minor-modes 'love-mode)) - (add-hook 'lua-mode-hook 'enable-tab-width-2))) + (add-hook! 'lua-mode-hook + (narf|enable-tab-width-2) + (setq lua-indent-level 2)))) (provide 'init-lua) diff --git a/init/init-org.el b/init/init-org.el index ff1df9a23..29f68d03f 100644 --- a/init/init-org.el +++ b/init/init-org.el @@ -1,16 +1,23 @@ (use-package org + :defines (org-directory) + :functions (org-bookmark-jump-unhide outline-next-heading org-end-of-subtree + outline-flag-region org-remove-inline-images org-display-inline-images + org-at-item-checkbox-p org-toggle-checkbox org-entry-is-todo-p org-todo + org-format-outline-path org-get-outline-path) :commands (org-capture - org-capture-string - my:org-capture) - :mode (("\\.org$" . org-mode) + org-capture-string) + :mode (("\\.org$" . org-mode) ("\\.opml$" . org-mode)) :init (progn - (add-hook 'org-mode-hook 'enable-tab-width-2) - (add-hook 'org-mode-hook 'turn-on-auto-fill) - (add-hook 'org-mode-hook 'iimage-mode) - (add-hook 'org-mode-hook 'org-indent-mode) - (add-hook 'org-mode-hook 'evil-org-mode) + (define-minor-mode evil-org-mode + "Evil-mode bindings for org-mode." + :init-value nil + :lighter "!" + :keymap (make-sparse-keymap) ; defines evil-org-mode-map + :group 'evil-org) + + (add-to-hook 'org-mode-hook '(narf|enable-tab-width-2 'narf|enable-hard-wrap 'iimage-mode 'org-indent-mode 'evil-org-mode)) (add-hook! 'org-mode-hook (hl-line-mode -1))) :config (progn @@ -20,8 +27,8 @@ (setq org-directory "~/Dropbox/notes") (setq org-project-directory (expand-file-name "projects" org-directory) ; custom variable org-default-notes-file (expand-file-name "notes.org" org-directory) - org-agenda-files (append (list org-directory) - (f-entries org-project-directory (lambda (path) (f-ext? path "org")) t)) + org-agenda-files (f-entries org-directory (lambda (path) (and (f-ext? path "org") + (not (f-same? path (f-expand "inbox.org" org-directory))))) t) org-archive-location (concat org-directory "/archive/%s::") org-confirm-babel-evaluate nil org-src-tab-acts-natively t @@ -58,16 +65,11 @@ ("@writing" . ?w) ("@projects" . ?r))) - (defun project-org-filename (cat) - (interactive (list (completing-read "Choose category:" - (mapcar 'f-filename (f-directories org-project-directory))))) - (expand-file-name (concat (f-filename (project-root)) ".org") - (expand-file-name cat org-project-directory))) (setq org-capture-templates '(("t" "TODO" entry (file+headline "~/Dropbox/notes/todo.org" "Inbox") "* TODO %? %u\n%i") - ("T" "Project TODO" entry (file+headline (project-org-filename) "Tasks") "** TODO %?\n%i" :prepend t) - ("N" "Project Note" entry (file+headline (project-org-filename) "Notes") "** %u %?\n%i") - ("c" "Changelog" entry (file+datetree (project-org-filename)) "** %<%H:%M>: %? :unsorted:\n%i" :prepend t) + ("T" "Project TODO" entry (file+headline (narf/project-org-filename) "Tasks") "** TODO %?\n%i" :prepend t) + ("N" "Project Note" entry (file+headline (narf/project-org-filename) "Notes") "** %u %?\n%i") + ("c" "Changelog" entry (file+datetree (narf/project-org-filename)) "** %<%H:%M>: %? :unsorted:\n%i" :prepend t) ("n" "Note" entry (file+datetree org-default-notes-file) "** %<%H:%M>: %?\n%i" :prepend t) ("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) @@ -88,14 +90,7 @@ (latex . t))) ;; Remove occur highlights on ESC in normal mode - (defadvice evil-force-normal-state (before evil-esc-org-remove-highlights activate) - (org-remove-occur-highlights)) - - (define-minor-mode evil-org-mode - :init-value nil - :lighter " !" - :keymap (make-sparse-keymap) ; defines evil-org-mode-map - :group 'evil-org) + (advice-add 'evil-force-normal-state :before 'org-remove-occur-highlights) ;; (progn ; opml support ;; (defun set-buffer-file-format-to-opml () @@ -118,49 +113,6 @@ ;; (shut-up (load-library "ox-opml"))) (progn ; key bindings - (defun my--org-in-list-p () - (and (save-excursion (search-backward-regexp "^ *\\([0-9]+[\.)]\\|[-*+]\\) " (line-beginning-position) t)) - (org-in-item-p))) - (defun my--org-insert-item-after () - "Inserts a new heading or item, depending on the context." - (interactive) - (org-end-of-line) - (cond ((org-at-item-checkbox-p) - (org-insert-heading) - (insert "[ ] ")) - ((my--org-in-list-p) - (org-insert-heading)) - ((org-on-heading-p) - (org-insert-heading-after-current)) - (t - (org-insert-heading-after-current) - (delete-char 1))) - (evil-insert-state)) - - ;; TODO Check if this and -forward can be combined - (defun my--org-insert-item-before () - "Inserts a new heading or item, depending on the context." - (interactive) - (evil-first-non-blank) - (cond ((org-at-item-checkbox-p) - (org-insert-heading) - (insert "[ ] ")) - ((my--org-in-list-p) - (org-insert-heading)) - (t (org-insert-heading))) - (evil-insert-state)) - - (defun my--toggle-checkbox () - (interactive) - (save-excursion - (org-end-of-line) - (cond ((org-in-item-p) - (if (search-backward-regexp "\\[[ +-]\\]" (line-beginning-position) t) - (delete-char 4) - (org-beginning-of-line))) - (t (org-insert-heading))) - (insert "[ ] "))) - ;; Hide properties PERMANENTLY (defun org-cycle-hide-drawers (state) "Re-hide all drawers after a visibility state change." @@ -197,14 +149,14 @@ ("tg" tags-todo "+gamedev") ("tw" tags-tree "+webdev")))) - (bind 'insert org-mode-map [remap my.inflate-space-maybe] 'self-insert-command) - - (bind org-mode-map + (bind :map org-mode-map "RET" nil "C-j" nil - "C-k" nil) + "C-k" nil - (bind '(normal insert) evil-org-mode-map + :insert [remap narf:inflate-space-maybe] 'self-insert-command + + :normal :insert :map evil-org-mode-map "A-l" 'org-metaright ; M-j "A-h" 'org-metaleft ; M-h "A-k" 'org-metaup ; M-k @@ -212,45 +164,37 @@ "A-l" 'org-shiftmetaright ; M-L "A-h" 'org-shiftmetaleft ; M-H "A-k" 'org-shiftmetaup ; M-K - "A-j" 'org-shiftmetadown) ; M-J + "A-j" 'org-shiftmetadown ; M-J - (bind 'insert evil-org-mode-map - "C-e" 'org-end-of-line - "C-a" 'org-beginning-of-line) - (bind '(insert normal) evil-org-mode-map "" 'org-beginning-of-line "" 'org-end-of-line "" 'org-up-element - "" 'org-down-element) + "" 'org-down-element - ;; Formatting shortcuts - (defun my/org-surround (delim) - (insert delim) (save-excursion (insert delim))) - - (bind evil-org-mode-map + ",;" 'helm-org-in-buffer-headings "M-a" 'mark-whole-buffer + ", l" 'org-insert-link - 'insert + :insert + "C-e" 'org-end-of-line + "C-a" 'org-beginning-of-line ;; Add new header line before this line - "" 'my--org-insert-item-before + "" 'narf/org-insert-item-before ;; Add new header line after this line - "" 'my--org-insert-item-after + "" 'narf/org-insert-item-after - "M-b" (λ (my/org-surround "*")) ; bold - "M-u" (λ (my/org-surround "_")) ; underline - "M-i" (λ (my/org-surround "/")) ; italics - "M-`" (λ (my/org-surround "+")) ; strikethrough + "M-b" (λ (narf/org-surround "*")) ; bold + "M-u" (λ (narf/org-surround "_")) ; underline + "M-i" (λ (narf/org-surround "/")) ; italics + "M-`" (λ (narf/org-surround "+")) ; strikethrough - 'visual + :visual "M-b" "S*" "M-u" "S_" "M-i" "S/" "M-`" "S+" - '(normal visual) - ", l" 'org-insert-link - - 'normal + :normal ",=" 'org-align-all-tags ",/" 'org-sparse-tree ",?" 'org-tags-view @@ -283,10 +227,10 @@ "<" 'org-metaleft ">" 'org-metaright "-" 'org-cycle-list-bullet - ",SPC" 'my--toggle-checkbox + ",SPC" 'narf/org-toggle-checkbox "," 'org-archive-subtree - "" 'my--org-insert-item-before - "" 'my--org-insert-item-after + "" 'narf/org-insert-item-before + "" 'narf/org-insert-item-after "RET" (λ (cond ((org-at-item-checkbox-p) (org-toggle-checkbox)) ((org-entry-is-todo-p) @@ -294,49 +238,12 @@ [tab] 'org-cycle) (after "org-agenda" - (bind 'emacs org-agenda-mode-map + (bind :emacs :map org-agenda-mode-map "" 'org-agenda-Quit "C-j" 'org-agenda-next-item "C-k" 'org-agenda-previous-item "C-n" 'org-agenda-next-item - "C-p" 'org-agenda-previous-item))) - - (evil-define-operator my:org-capture (&optional beg end) - "Send a selection to org-capture." - :move-point nil - :type inclusive - (interactive "") - (let ((text (when (and (evil-visual-state-p) beg end) - (buffer-substring beg end)))) - (if text - (org-capture-string text) - (org-capture)))) - - (evil-define-command my:org-insert-image-url (&optional image-url) - :repeat nil - (interactive "") - (unless image-url - (user-error "You must specify an image URL to insert")) - (let ((dest (f-join org-directory "images/" (concat (format-time-string "%Y%m%d-") (f-filename filename))))) - (shell-command (format "wget '%s' -O '%s'" image-url dest)) - (insert (format "<%s>" (f-relative dest (f-dirname (buffer-file-name))))) - (indent-according-to-mode))) - - (evil-define-command my:org-insert-image (&optional filename bang) - :repeat nil - (interactive "") - (if bang - (my:org-insert-image-url filename) - (unless filename - (user-error "You must specify a file to attach")) - (unless (file-exists-p filename) - (user-error "File %s does not exist" filename)) - (let ((dest (f-join org-directory "images/" (concat (format-time-string "%Y%m%d-") (f-filename filename))))) - (when (f-exists? dest) - (user-error "File %s already exists at destination!")) - (copy-file filename dest) - (insert (format "" (f-relative dest (f-dirname (buffer-file-name))))) - (indent-according-to-mode)))))) + "C-p" 'org-agenda-previous-item))))) (provide 'init-org) diff --git a/init/init-php.el b/init/init-php.el index cf8daeef7..d7ea22bc1 100644 --- a/init/init-php.el +++ b/init/init-php.el @@ -6,7 +6,8 @@ (add-hook 'php-mode-hook 'turn-on-eldoc-mode) (use-package php-extras - :config (company--backend-on 'php-mode-hook 'php-extras-company)) + :config + (narf/add-company-backend php-mode (php-extras-company))) ;; TODO Tie into emr (use-package php-refactor-mode diff --git a/init/init-project.el b/init/init-project.el index 32aa3dda5..aa6a44a53 100644 --- a/init/init-project.el +++ b/init/init-project.el @@ -1,21 +1,33 @@ ;; Project nav+search tools (projectile, helm, ag) (use-package neotree - :commands (neotree-show neotree-hide neotree-toggle neo-global--window-exists-p neotree-dir neotree-find) + :functions (neo-buffer--unlock-width neo-buffer--lock-width + projectile-current-project-dirs projectile-file-cached-p + projectile-purge-file-from-cache neo-buffer--insert-with-face + neo-global--get-buffer) + :commands (neotree-show + neotree-hide + neotree-toggle + neo-global--window-exists-p + neotree-dir + neotree-find) :init (progn - (defun my-neotree-open (&optional dir) + (defun narf:neotree-open (&optional dir) (interactive) - (neotree-dir (or dir (project-root)))) - (defun my-neotree-toggle () + (neotree-dir (or dir (narf/project-root)))) + + (defun narf:neotree-toggle () (interactive) (if (neo-global--window-exists-p) (neotree-hide) - (my-neotree-open))) - (defun my-neotree-find () + (narf:neotree-open))) + + (defun narf:neotree-find () (interactive) - (save-excursion (my-neotree-open)) + (save-excursion (narf:neotree-open)) (neotree-find)) - (add-hook 'neotree-mode-hook 'my-neotree-keymap)) + + (add-hook 'neotree-mode-hook 'narf|init-neotree-keymap)) :config (progn (setq neo-create-file-auto-open t @@ -31,14 +43,15 @@ ;; frame. neo-modern-sidebar t) - ;; Custom ascii theme - (defun neo-buffer--insert-fold-symbol (name) + ;; Redefinition for custom ascii theme + (defun narf/neo-buffer-fold-symbol (name) (let ((n-insert-symbol (lambda (n) (neo-buffer--insert-with-face n 'neo-expand-btn-face)))) (or (and (equal name 'open) (funcall n-insert-symbol "- ")) (and (equal name 'close) (funcall n-insert-symbol "> ")) (and (equal name 'leaf) (funcall n-insert-symbol " "))))) + (advice-add 'neo-buffer--insert-fold-symbol :override 'narf/neo-buffer-fold-symbol) ;; Close neotree on window changes, to prevent ensuing mindbuggery (add-hook! 'window-configuration-change-hook @@ -49,8 +62,8 @@ (after "projectile" (setq projectile-switch-project-action 'neotree-projectile-action)) (add-to-list 'evil-motion-state-modes 'neotree-mode) - (defun my-neotree-keymap () - (bind evil-motion-state-local-map + (defun narf|init-neotree-keymap () + (bind :map evil-motion-state-local-map "ESC" 'neotree-hide "\\\\" 'neotree-hide "RET" 'neotree-enter diff --git a/init/init-python.el b/init/init-python.el index b1efb68d1..b2ccfbf55 100644 --- a/init/init-python.el +++ b/init/init-python.el @@ -1,30 +1,25 @@ (use-package python - :mode ("\\.py\\'" . python-mode) - :interpreter ("python" . python-mode) + :mode ("\\.py\\'" . python-mode) + :interpreter ("python" . python-mode) + :commands (python-mode) :init - (progn - (add-hook 'python-mode-hook 'enable-tab-width-4) - (add-hook 'python-mode-hook 'emr-initialize)) + (add-to-hook 'python-mode-hook '(narf|enable-tab-width-4 emr-initialize)) :config (progn (setq-default python-indent-offset 4) - (setq python-environment-directory my-tmp-dir) + (setq python-environment-directory TMP-DIR) (setq python-shell-interpreter "ipython") ;; interferes with smartparens (define-key python-mode-map (kbd "DEL") nil) (use-package anaconda-mode - :init - (progn - (add-hook 'python-mode-hook 'anaconda-mode) - (add-hook 'python-mode-hook 'eldoc-mode) - ;; (add-hook! 'anaconda-mode-hook - ;; (process-buffer (python-shell-get-or-create-process python-shell-interpreter t nil))) - ) + :defines (anaconda-mode-map anaconda-nav-mode-map) + :functions (anaconda-mode-running-p) + :init (add-to-hook 'python-mode-hook '(anaconda-mode eldoc-mode)) :config (progn - (bind 'motion anaconda-mode-map "gd" 'anaconda-mode-goto-definitions) - (bind 'normal anaconda-nav-mode-map [escape] 'anaconda-nav-quit) + (bind :motion :map anaconda-mode-map "gd" 'anaconda-mode-goto-definitions) + (bind :normal :map anaconda-nav-mode-map [escape] 'anaconda-nav-quit) ;; Delete the window on escape or C-g (defadvice anaconda-mode-doc-buffer (after anaconda-doc-buffer-escape-to-close activate) @@ -62,24 +57,23 @@ (after "company" (use-package company-anaconda - :config (company--backend-on 'python-mode-hook 'company-anaconda))))) + :config + (narf/add-company-backend python-mode (company-anaconda)))))) (use-package nose :commands nose-mode - :init - (progn - ;; Reset nose keymap, we'll set new ones in my-keymaps.el - (defvar nose-mode-map (make-sparse-keymap)) - (associate-minor-mode "/test_.+\\.py\\'" 'nose-mode)) + :preface (defvar nose-mode-map (make-sparse-keymap)) + :init (associate-minor-mode "/test_.+\\.py\\'" 'nose-mode) :config - (bind 'normal 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)))) + (bind normal :map nose-mode-map + :prefix leader + "tr" 'nosetests-again + "ta" 'nosetests-all + "ts" 'nosetests-one + "tv" 'nosetests-module + "tA" 'nosetests-pdb-all + "tO" 'nosetests-pdb-one + "tV" 'nosetests-pdb-module)))) (provide 'init-python) diff --git a/init/init-r.el b/init/init-r.el new file mode 100644 index 000000000..67097aafe --- /dev/null +++ b/init/init-r.el @@ -0,0 +1,10 @@ +(use-package ess-site + :config + (progn + (setq ess-indent-level 4) + (setq ess-arg-function-offset 4) + (setq ess-else-offset 4) + )) + +(provide 'init-r) +;;; init-r.el ends here diff --git a/init/init-regex.el b/init/init-regex.el index 16d9915ae..4282a0a36 100644 --- a/init/init-regex.el +++ b/init/init-regex.el @@ -1,29 +1,30 @@ (use-package re-builder - :defer t + :commands (re-builder reb-mode-buffer-p) :config (progn - (bind 'normal reb-mode-map + (bind :normal :map reb-mode-map + "C-g" 'reb-quit [escape] 'reb-quit - (kbd "C-g") 'reb-quit [backtab] 'reb-change-syntax) - (defun my--reb-cleanup () + (defun narf|reb-cleanup () (replace-regexp "^[ \n]*" "" nil (point-min) (point-max)) (text-scale-set 1.5) (goto-char 2)) - (add-hook 'reb-mode-hook 'my--reb-cleanup) + (add-hook 'reb-mode-hook 'narf|reb-cleanup) (use-package pcre2el + :functions (rxt--re-builder-switch-pcre-mode) :config (progn - (bind 'normal rxt-help-mode-map [escape] 'kill-buffer-and-window) + (bind :normal :map rxt-help-mode-map [escape] 'kill-buffer-and-window) (setq reb-re-syntax 'pcre))) (after "evil" (evil-set-initial-state 'reb-mode 'insert) ;; Either a) converts selected (or entered-in) pcre regex into elisp ;; regex, OR b) opens up re-builder. - (evil-define-operator my:regex (beg end type &optional regexstr bang) + (evil-define-operator narf::regex (beg end type &optional regexstr bang) :move-point nil :type inclusive :repeat nil @@ -48,8 +49,7 @@ (setq newregex (s-replace "\\" "\\\\" newregex))) (kill-new newregex) (message "Copied regex to kill ring: %s" newregex))) - (t - (re-builder)))))))) + (t (re-builder)))))))) (provide 'init-regex) diff --git a/init/init-ruby.el b/init/init-ruby.el index bb4bf74b4..4281fc078 100644 --- a/init/init-ruby.el +++ b/init/init-ruby.el @@ -9,16 +9,18 @@ ("/Vagrantfile$" . enh-ruby-mode) ("/Rakefile$" . enh-ruby-mode)) :interpreter "ruby" + :init + (progn + (add-hook 'enh-ruby-mode-hook 'narf|enable-tab-width-2) + (add-hook! 'enh-ruby-mode-hook (set-build-command "rake %s" "Rakefile"))) :config (progn ;;; Formatting - (setq ruby-indent-level 2) - (setq ruby-deep-indent-paren t) - (setq enh-ruby-check-syntax nil) + (setq ruby-indent-level 2 + ruby-deep-indent-paren t + enh-ruby-check-syntax nil) (associate-mode "/\\.rspec$" 'text-mode) - (add-hook 'enh-ruby-mode-hook 'enable-tab-width-2) - (add-hook! 'enh-ruby-mode-hook (set-build-command "rake %s" "Rakefile")) ;; Don't interfere with my custom RET behavior (define-key enh-ruby-mode-map [?\n] nil) @@ -53,7 +55,7 @@ (define-minor-mode rake-mode "Buffer local minor mode for rake files" :lighter " Rake" :keymap (make-sparse-keymap) - (my--init-yas-mode 'rake-mode)) + (narf/init-yas-mode 'rake-mode)) (associate-minor-mode "/\\(Rakefile\\|\\.rake\\)$" 'rake-mode) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -61,7 +63,7 @@ (define-minor-mode vagrant-mode "Buffer local minor mode for vagrant files" :lighter " Va" :keymap (make-sparse-keymap) - (my--init-yas-mode 'vagrant-mode)) + (narf/yas-init-mode 'vagrant-mode)) (associate-minor-mode "/Vagrantfile$" 'vagrant-mode) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -71,7 +73,7 @@ :init (progn (associate-minor-mode "\\(/spec_helper\\|_spec\\)\\.rb$" 'rspec-mode) - (associate-minor-mode "/\\.rspec$" 'rspec-mode) + (associate-minor-mode "/\\.rspec$" 'rspec-mode) (defvar rspec-mode-verifiable-map (make-sparse-keymap)) (defvar evilmi-ruby-match-tags @@ -82,7 +84,7 @@ ;; Rake (("task" "namespace") () "end")))) :config - (bind 'normal + (bind :normal ",tr" 'rspec-rerun ",ta" 'rspec-verify-all ",ts" 'rspec-verify-single @@ -96,16 +98,17 @@ (evil-set-initial-state 'inf-enh-ruby-mode 'insert) (after "company" (use-package company-inf-ruby - :config (company--backend-on 'inf-enh-ruby-mode-hook 'company-inf-ruby))))) + :config (narf/add-company-backend inf-enh-ruby-mode (company-inf-ruby)))))) (use-package robe + :functions (robe-mode robe-start ruby-load-file) :config (progn (after "company" (use-package company-robe - :config (company--backend-on 'enh-ruby-mode-hook 'company-robe))) + :config (narf/add-company-backend enh-ruby-mode (company-robe)))) - (defun my-enable-robe-maybe () + (defun narf|enable-robe-maybe () (let ((file (buffer-file-name))) ;; Don't run in gemfiles, capfiles or vagrantfiles (unless (or (string-equal (f-filename file) "Gemfile") @@ -113,10 +116,10 @@ (string-equal (f-filename file) "Vagrantfile") (f-ext? file "org")) ;; or org-mode (robe-mode 1) - (my--ruby-load-file file)))) - (add-hook 'enh-ruby-mode-hook 'my-enable-robe-maybe) + (narf|ruby-load-file file)))) + (add-hook 'enh-ruby-mode-hook 'narf|enable-robe-maybe) - (defun my--ruby-load-file (&optional file) + (defun narf|ruby-load-file (&optional file) (let ((file (or file buffer-file-name))) (when (and (eq major-mode 'enh-ruby-mode) (featurep 'robe) @@ -124,7 +127,7 @@ (file-exists-p buffer-file-name)) (unless robe-running (robe-start 1)) (when robe-running (ruby-load-file file))))) - (add-hook 'after-save-hook 'my--ruby-load-file))))) + (add-hook 'after-save-hook 'narf|ruby-load-file))))) (provide 'init-ruby) diff --git a/init/init-scss.el b/init/init-scss.el index 27003d4a7..e32620edd 100644 --- a/init/init-scss.el +++ b/init/init-scss.el @@ -1,20 +1,28 @@ -(use-package scss-mode - :mode "\\.scss$" +(use-package sass-mode + :mode "\\.sass$" + :init + (add-hook 'sass-mode-hook 'narf|enable-tab-width-2) :config (progn - ;; Syntax coloring breaks on consecutive loads for some reason. This fixes that: - (add-hook 'scss-mode-hook 'css-mode) - (add-hook 'scss-mode-hook 'enable-tab-width-2) + (after "company" (narf/add-company-backend sass-mode (company-css))))) +(use-package scss-mode + :mode "\\.scss$" + :init + (add-hook 'scss-mode-hook 'narf|enable-tab-width-2) + :config + (progn (setq-default css-indent-offset 2) (setq scss-compile-at-save nil) + ;; Syntax coloring breaks on consecutive loads for some reason. This fixes that: + (add-hook 'scss-mode-hook 'css-mode) + (after "web-beautify" (add-hook! 'scss-mode-hook (setenv "jsbeautify_indent_size" "2")) - (bind 'motion scss-mode-map "gQ" 'web-beautify-css)) + (bind :motion :map scss-mode-map "gQ" 'web-beautify-css)) - (after "auto-complete" (add-hook 'scss-mode-hook 'ac-css-mode-setup)) - (after "company" (company--backend-on 'scss-mode-hook 'company-css)))) + (after "company" (narf/add-company-backend scss-mode (company-css))))) (use-package rainbow-mode :defer t diff --git a/init/init-sh.el b/init/init-sh.el index 33420156d..0e2745109 100644 --- a/init/init-sh.el +++ b/init/init-sh.el @@ -1,5 +1,5 @@ -(my--cleanup-buffers-add "^\\*Shell Command Output\\*$") -(my--cleanup-buffers-add "^\\*Async Shell Command\\*$") +(narf/add-throwaway-buffer "^\\*Shell Command Output\\*$") +(narf/add-throwaway-buffer "^\\*Async Shell Command\\*$") ;; Make shell scrips executable on save? ;; (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p) diff --git a/init/init-swift.el b/init/init-swift.el index 874d6214c..e6eefa4db 100644 --- a/init/init-swift.el +++ b/init/init-swift.el @@ -3,7 +3,7 @@ :config (progn (after "flycheck" (add-to-list 'flycheck-cehckers 'swift)) - (after "company" (company--backend-on 'swift-mode-hook 'company-xcode)))) + (after "company" (narf/add-company-backend swift-mode (company-xcode))))) ;; TODO Set up emacs task runners for fruitstrap diff --git a/init/init-text.el b/init/init-text.el index 79230268a..10e66320f 100644 --- a/init/init-text.el +++ b/init/init-text.el @@ -1,9 +1,11 @@ -(add-hook 'text-mode-hook 'turn-on-auto-fill) -(add-hook 'prog-mode-hook 'enable-comment-hard-wrap) +(add-hook 'text-mode-hook 'narf|enable-hard-wrap) +(add-hook 'prog-mode-hook 'narf|enable-comment-hard-wrap) (use-package markdown-mode :mode (("\\.md$" . markdown-mode) ("/README$" . markdown-mode)) + :functions (markdown-use-region-p markdown-unwrap-things-in-region + markdown-wrap-or-insert markdown-unwrap-thing-at-point) :init ;; Implement strike-through formatting (defvar markdown-regex-del "\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)") @@ -22,31 +24,32 @@ (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))))) - (sp-local-pair 'markdown-mode "*" "*" :unless '(sp-point-after-bol-p sp-point-before-same-p sp-point-after-same-p)) - (let ((map markdown-mode-map)) - (bind '(normal visual) map - ",i" 'markdown-insert-image - ",l" 'markdown-insert-link - ",L" 'markdown-insert-reference-link-dwim - ",b" 'markdown-preview) + (sp-local-pair 'markdown-mode "*" "*" + :unless '(sp-point-after-bol-p sp-point-before-same-p sp-point-after-same-p)) - (bind 'normal map - "[p" 'markdown-promote - "]p" 'markdown-demote) + (bind :map markdown-mode-map + "" nil + "" nil + "" nil - (bind 'insert map - (kbd "M--") 'markdown-insert-hr) + "M-*" 'markdown-insert-list-item + "M-b" 'markdown-insert-bold + "M-i" 'markdown-insert-italic + "M-`" 'markdown-insert-del - (bind map - (kbd "") nil - (kbd "") nil - (kbd "") nil + :normal :visual + ",i" 'markdown-insert-image + ",l" 'markdown-insert-link + ",L" 'markdown-insert-reference-link-dwim + ",b" 'markdown-preview - (kbd "M-*") 'markdown-insert-list-item - (kbd "M-b") 'markdown-insert-bold - (kbd "M-i") 'markdown-insert-italic - (kbd "M-`") 'markdown-insert-del)))) + :normal + "[p" 'markdown-promote + "]p" 'markdown-demote + + :insert + "M--" 'markdown-insert-hr))) (provide 'init-text) diff --git a/init/init-tmux.el b/init/init-tmux.el deleted file mode 100644 index a86b3de2d..000000000 --- a/init/init-tmux.el +++ /dev/null @@ -1,35 +0,0 @@ -;;; init.tmux.el - settings for interacting with tmux - -(defun my--tmux-send (command) - (shell-command (format "tmux send-keys %s" command))) - -(after "evil" - (evil-define-interactive-code "" - "Ex tmux argument (a mix between and )" - :ex-arg shell - (list (when (evil-ex-p) (evil-ex-file-arg)))) - - (evil-define-command my:tmux-run (&optional command bang) - "Sends input to tmux. Use `bang' to append to tmux" - (interactive "") - (my--tmux-send (format (if bang "C-u %s Enter" "%s") - (shell-quote-argument command))) - (when (evil-ex-p) - (message "[Tmux] %s" command))) - - (evil-define-command my:tmux-chdir (&optional path bang) - "CDs in tmux using `project-root'" - (interactive "") - (let ((dir (shell-quote-argument - (if (and path (not (s-blank? path))) - (if (file-directory-p path) - (file-truename path) - (error "Directory doesn't exist %s" path)) - (if bang default-directory (project-root)))))) - (my--tmux-send (format "C-u cd Space %s Enter" (shell-quote-argument dir))) - (when (evil-ex-p) - (message "[Tmux] cd %s" dir))))) - - -(provide 'init-tmux) -;;; init-tmux.el ends here diff --git a/init/init-vc.el b/init/init-vc.el index c989982e2..e98f0a126 100644 --- a/init/init-vc.el +++ b/init/init-vc.el @@ -28,93 +28,6 @@ (setq diff-hl-draw-borders nil) (global-diff-hl-mode +1))) -;; (use-package git-gutter-fringe+ -;; :diminish (git-gutter+-mode . " git") -;; :config -;; (progn -;; ;; (global-git-gutter+-mode +1) -;; (add-hooks '(text-mode-hook prog-mode-hook) 'git-gutter+-mode) -;; ;; Fixes "git-gutter+-process-diff: Wrong number of arguments: nil" error -;; (defadvice git-gutter+-process-diff (before git-gutter+-process-diff-advice activate) -;; (ad-set-arg 0 (file-truename (ad-get-arg 0)))) - -;; (fringe-helper-define 'git-gutter-fr+-added nil -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X....") - -;; (fringe-helper-define 'git-gutter-fr+-deleted nil -;; "....X...." -;; "....XXXXX" -;; "....XXXXX" -;; "....X...." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; "........." -;; ".........") - -;; (fringe-helper-define 'git-gutter-fr+-modified nil -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...." -;; "....X...."))) - (provide 'init-vc) ;;; init-vc.el ends here diff --git a/init/init-vim.el b/init/init-vim.el new file mode 100644 index 000000000..79d878889 --- /dev/null +++ b/init/init-vim.el @@ -0,0 +1,7 @@ +(use-package vimrc-mode + :mode (("/\\.?g?vimrc$" . vimrc-mode) + ("\\.vim$" . vimrc-mode))) + + +(provide 'init-vim) +;;; init-vim.el ends here diff --git a/init/init-web.el b/init/init-web.el index 6d7c29214..84fa50fff 100644 --- a/init/init-web.el +++ b/init/init-web.el @@ -3,17 +3,17 @@ :init (after "css-mode" (add-hook! 'css-mode-hook (setenv "jsbeautify_indent_size" "2")) - (bind 'motion css-mode-map "gQ" 'web-beautify-css))) + (bind :motion :map css-mode-map "gQ" 'web-beautify-css))) (use-package web-mode - :mode (("\\.\\(p\\)?htm\\(l\\)?$" . web-mode) - ("\\.tpl\\(\\.php\\)?$" . web-mode) - ("\\.erb$" . web-mode) - ("wp-content/themes/.+/.+\\.php$" . web-mode)) + :mode (("\\.\\(p\\)?htm\\(l\\)?$" . web-mode) + ("\\.tpl\\(\\.php\\)?$" . web-mode) + ("\\.erb$" . web-mode) + ("wp-content/themes/.+/.+\\.php$" . web-mode)) + :init + (add-hook 'web-mode-hook 'narf|enable-tab-width-2) :config (progn - (add-hook 'web-mode-hook 'enable-tab-width-2) - (setq web-mode-markup-indent-offset 2 web-mode-code-indent-offset 2 web-mode-css-indent-offset 2 @@ -29,18 +29,20 @@ (not (or (get-text-property (point) 'part-side) (get-text-property (point) 'block-side)))) t)) - (sp-local-pair 'web-mode "<" nil :when '(sp-web-mode-is-code-context))) (after "web-beautify" (add-hook! 'web-mode-hook (setenv "jsbeautify_indent_size" "4")) - (bind 'motion web-mode-map "gQ" 'web-beautify-html)) + (bind :motion :map web-mode-map "gQ" 'web-beautify-html)) - (bind web-mode-map (kbd "M-/") 'web-mode-comment-or-uncomment) - (bind 'normal web-mode-map + (bind :map web-mode-map + "M-/" 'web-mode-comment-or-uncomment + + :normal "zf" 'web-mode-fold-or-unfold - ",t" 'web-mode-element-rename) - (bind '(normal visual) web-mode-map + ",t" 'web-mode-element-rename + + :normal :visual "]a" 'web-mode-attribute-next "[a" 'web-mode-attribute-previous "]t" 'web-mode-tag-next @@ -51,39 +53,35 @@ (use-package emmet-mode :defer t :init - (progn - (add-hook 'scss-mode-hook 'emmet-mode) - (add-hook 'web-mode-hook 'emmet-mode) - (add-hook 'html-mode-hook 'emmet-mode) - (add-hook 'haml-mode-hook 'emmet-mode) - (add-hook 'nxml-mode-hook 'emmet-mode)) + (add-to-hooks 'emmet-mode '(scss-mode-hook web-mode-hook html-mode-hook haml-mode-hook nxml-mode-hook)) :config (progn (setq emmet-move-cursor-between-quotes t) - (bind 'insert emmet-mode-keymap + (bind insert :map emmet-mode-keymap "M-e" 'emmet-expand-yas "M-E" 'emmet-expand-line))) (define-minor-mode jekyll-mode + "Jekyll development mode." :init-value nil :lighter " :{" :keymap (make-sparse-keymap) - (my--init-yas-mode 'jekyll-mode)) -(defun jekyll-mode-enable-maybe () - (when (project-has-files '("_config.yml" "_layouts")) + (narf/init-yas-mode 'jekyll-mode)) +(defun narf|jekyll-mode-enable-maybe () + (when (narf/project-has-files '("_config.yml" "_layouts")) (jekyll-mode 1))) (associate-minor-mode "/_\\(layouts\\|posts\\)/.+$" 'jekyll-mode) -(add-hooks '(web-mode-hook scss-mode-hook html-mode-hook markdown-mode markdown-mode-hook) - 'jekyll-mode-enable-maybe) +(add-to-hooks 'narf|jekyll-mode-enable-maybe '(web-mode-hook scss-mode-hook html-mode-hook markdown-mode markdown-mode-hook)) (after "company" (add-to-list 'company-dictionary-major-minor-modes 'jekyll-mode)) (define-minor-mode wordpress-mode + "Wordpress development mode." :init-value nil :lighter " wp" :keymap (make-sparse-keymap) - (my--init-yas-mode 'wordpress-mode)) -(associate-minor-mode "/wp-\\(content\\|admin\\|includes\\)/.+$" 'wordpress-mode) -(associate-minor-mode "/wp-.+\\.php$" 'wordpress-mode) + (narf/init-yas-mode 'wordpress-mode)) +(associate-minor-mode "/wp-\\(content\\|admin\\|includes\\)/.+$" 'wordpress-mode) +(associate-minor-mode "/wp-.+\\.php$" 'wordpress-mode) (after "company" (add-to-list 'company-dictionary-major-minor-modes 'wordpress-mode)) diff --git a/init/init-workgroups.el b/init/init-workgroups.el index 41ad6cb93..f81c0058f 100644 --- a/init/init-workgroups.el +++ b/init/init-workgroups.el @@ -1,63 +1,40 @@ (use-package workgroups2 - :diminish workgroups-mode + :init + (setq wg-session-file (expand-file-name "wg-default" TMP-DIR) + wg-workgroup-directory (expand-file-name "workgroups" TMP-DIR) + wg-first-wg-name "main" + wg-session-load-on-start t + wg-mode-line-display-on nil + ;; What to do on Emacs exit / workgroups-mode exit? + wg-emacs-exit-save-behavior 'save ; Options: 'save 'ask nil + wg-workgroups-mode-exit-save-behavior 'save) :config (progn - (setq wg-session-file "~/.emacs.workgroup" - wg-workgroup-directory "~/.emacs.d/workgroups/" - wg-first-wg-name "main" - wg-session-load-on-start t - wg-mode-line-display-on nil - ;; What to do on Emacs exit / workgroups-mode exit? - wg-emacs-exit-save-behavior 'save ; Options: 'save 'ask nil - wg-workgroups-mode-exit-save-behavior 'save) ; Options: 'save 'ask nil - - (evil-define-command my:save-session (&optional bang session-name) - (interactive "") - (if session-name - (wg-save-session-as (concat wg-workgroup-directory session-name) (not bang)) - (wg-save-session))) - - (evil-define-command my:load-session (&optional bang session-name) - (interactive "") - (wg-open-session (if session-name - (concat wg-workgroup-directory session-name) - wg-session-file))) - - (evil-define-command my:new-workgroup (bang name) - (interactive "") - (unless name - (user-error "No name specified for new workgroup")) - (if bang - (wg-clone-workgroup (wg-current-workgroup) name) - (wg-create-workgroup name t))) - - (evil-define-command my:rename-workgroup (new-name) - (interactive "") - (wg-rename-workgroup new-name)) - (after "helm" - (defun my-wg-switch-to-workgroup (name) + (defun narf/helm-switch-to-workgroup (name) (wg-switch-to-workgroup (wg-get-workgroup name))) - - (defun helm-wg () - (interactive) - (helm :sources '(helm-source-wg))) - - (defvar helm-source-wg - '((name . "Workgroups") + (defvar narf/helm-source-wg + '((name . "Workgroups") (candidates . wg-workgroup-names) - (action . my-wg-switch-to-workgroup)))) + (action . narf/helm-switch-to-workgroup))) + (defun narf:helm-wg () + (interactive) + (helm :sources '(helm-source-wg)))) ;; Turns projectile switch-project interface (or helm's interface to it) ;; create a new workgroup for the new project. (after "projectile" - (defun my-projectile-workgroup-switch-project () - (let ((workgroup-name (file-name-nondirectory (directory-file-name (project-root))))) + (defun narf/wg-projectile-switch-project () + (let ((workgroup-name (file-name-nondirectory (directory-file-name (narf/project-root))))) (wg-create-workgroup workgroup-name t) (helm-projectile-find-file))) - (setq projectile-switch-project-action 'my-projectile-workgroup-switch-project)) + (setq projectile-switch-project-action 'narf/wg-projectile-switch-project)) - (workgroups-mode 1))) + ;; Initialize! + (defun narf|init-workgroups () + (workgroups-mode +1) + (diminish 'workgroups-mode)) + (add-hook 'after-init-hook 'narf|init-workgroups))) (provide 'init-workgroups) diff --git a/init/init-yasnippet.el b/init/init-yasnippet.el index 91cd463ae..0a40e0943 100644 --- a/init/init-yasnippet.el +++ b/init/init-yasnippet.el @@ -1,76 +1,68 @@ (use-package yasnippet - :diminish (yas-minor-mode . " @") - :commands (yas-minor-mode yas-minor-mode-on my--init-yas-mode my:snippets) + :diminish (yas-minor-mode . "Y") + :commands (yas-minor-mode yas-minor-mode-on narf/init-yas-mode) :mode (("emacs\\.d/snippets/.+$" . snippet-mode)) :init (progn + (add-to-hooks 'yas-minor-mode-on '(prog-mode-hook + snippet-mode-hook + markdown-mode-hook + org-mode-hook)) + (add-hook 'snippet-mode-hook 'disable-final-newline) + + ;; Switch to insert mode when expanding a template via backtab, or go back + ;; to normal mode if there are no fields. + (defun narf/insert-yas-snippet () + (interactive) + (yas-insert-snippet) + (evil-insert-state +1)) + (defvar yas-minor-mode-map (let ((map (make-sparse-keymap))) - (bind 'insert map [(tab)] 'yas-expand) - (bind 'visual map "" 'yas-insert-snippet) - map)) - - (add-hook 'snippet-mode-hook 'yas-minor-mode-on) - (add-hook 'text-mode-hook 'yas-minor-mode-on) - (add-hook 'prog-mode-hook 'yas-minor-mode-on) - (add-hook 'js2-mode-hook 'yas-minor-mode-on) - (add-hook 'org-mode-hook 'yas-minor-mode-on) - (add-hook 'snippet-mode-hook 'disable-final-newline)) + (bind insert :map map [(tab)] 'yas-expand) + (bind visual :map map "" 'narf/insert-yas-snippet) + map))) :config (progn - (bind 'insert [(tab)] nil) - (bind 'visual "" nil) - - (setq yas-verbosity 0) - (setq yas-indent-line 'auto) - (setq yas-also-auto-indent-first-line t) - (setq yas-wrap-around-region nil) - - ;; Only load personal snippets - (setq yas-snippet-dirs `(,my-snippets-dir)) - (setq yas-prompt-functions '(yas-ido-prompt yas-no-prompt)) - - (yas-reload-all) + ;; Undo global maps + (bind insert [(tab)] nil) + (bind visual "" nil) (after "helm" (add-to-list 'yas-dont-activate 'helm-alive-p)) + (setq yas-verbosity 0 + yas-indent-line 'auto + yas-also-auto-indent-first-line t + yas-wrap-around-region nil + ;; Only load personal snippets + yas-snippet-dirs `(,SNIPPETS-DIR) + yas-prompt-functions '(yas-ido-prompt yas-no-prompt)) + (yas-reload-all) + ;; Exit snippets on ESC in normal mode - (defadvice evil-force-normal-state (before evil-esc-quit-yasnippet activate) - (yas-exit-all-snippets)) + (advice-add 'evil-force-normal-state :before 'yas-exit-all-snippets) ;; Once you're in normal mode, you're out (add-hook 'evil-normal-state-entry-hook 'yas-abort-snippet) ;; Fixes: evil's visual-line mode gobbles up the newline on the right. ;; This prevents that by essentially doing (1- (region-end)). (defadvice yas-expand-snippet (around yas-expand-snippet-visual-line activate) - (if (evil-visual-line-state-p) - (ad-set-arg 2 (1- (ad-get-arg 2)))) ad-do-it) + (when (evil-visual-line-state-p) + (ad-set-arg 2 (1- (ad-get-arg 2)))) ad-do-it) ;; Fixes: visual-line includes indentation before the selection. This ;; strips it out. (add-hook! 'yas-before-expand-snippet-hook - (if (evil-visual-line-state-p) - (setq-local yas-selected-text - (replace-regexp-in-string - "\\(^ *\\|\n? $\\)" "" - (buffer-substring-no-properties (region-beginning) - (1- (region-end))))))) + (when (evil-visual-line-state-p) + (setq-local yas-selected-text + (replace-regexp-in-string + "\\(^ *\\|\n? $\\)" "" + (buffer-substring-no-properties (region-beginning) + (1- (region-end))))))) ;; Previous hook causes yas-selected-text to persist between expansions. ;; This little hack gets around it. (add-hook! 'yas-after-exit-snippet-hook (setq-local yas-selected-text nil)) - (evil-define-operator my:snippets (beg end &optional name) - :motion nil - :move-point nil - :type exclusive - :repeat nil - (interactive "") - (if (and beg end) - (yas-insert-snippet) - (if name - (popwin:find-file (concat my-snippets-dir (symbol-name major-mode) "/" name)) - (yas-visit-snippet-file)))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Snippet helpers @@ -78,31 +70,30 @@ ;; Shorthand defun to surround text with newlines if more than one line. (defun !%! () (when % - (if (> (s-count-lines %) 1) + (if (> (length (s-lines %)) 1) (concat "\n" % "\n") (s-trim %)))) ;; Shorthand defun for snippets: prepends a newline to `yas-selected-text' ;; IF it contains more than one line. (defun !% () (when % - (if (> (s-count-lines %) 1) + (if (> (length (s-lines %)) 1) (concat "\n" %) (s-trim %)))) - ;; Trim selection; do no further processing (defun %1 () (s-trim %)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Inter-field navigation - (defun my/yas-goto-start-of-field () + (defun narf/yas-goto-start-of-field () (interactive) (let* ((snippet (car (yas--snippets-at-point))) (position (yas--field-start (yas--snippet-active-field snippet)))) (if (= (point) position) (move-beginning-of-line 1) (goto-char position)))) - (defun my/yas-goto-end-of-field () + (defun narf/yas-goto-end-of-field () (interactive) (let* ((snippet (car (yas--snippets-at-point))) (position (yas--field-end (yas--snippet-active-field snippet)))) @@ -111,7 +102,7 @@ (goto-char position)))) ;; Prevents Yas from stepping on my toes when I use backspace - (defun my/yas-backspace (&optional field) + (defun narf/yas-backspace (&optional field) (interactive) (let ((field (or field (and yas--active-field-overlay (overlay-buffer yas--active-field-overlay) @@ -119,7 +110,7 @@ (cond ((eq (point) (marker-position (yas--field-start field))) nil) (t (delete-char -1))))) - (defun my/yas-delete (&optional field) + (defun narf/yas-delete (&optional field) (interactive) (let ((field (or field (and yas--active-field-overlay (overlay-buffer yas--active-field-overlay) @@ -132,7 +123,7 @@ ((eq (point) (marker-position (yas--field-end field))) nil) (t (delete-char 1))))) - (defun my/yas-clear-to-sof (&optional field) + (defun narf/yas-clear-to-sof (&optional field) (interactive) (let* ((field (or field (and yas--active-field-overlay (overlay-buffer yas--active-field-overlay) @@ -141,26 +132,26 @@ (when (and field (> (point) sof)) (delete-region sof (point))))) - (defun my--init-yas-mode (&rest modes) + (defun narf/init-yas-mode (&rest modes) ;; Yasnippet 0.8.1+ (after "yasnippet" - (when (boundp 'yas-extra-modes) - (dolist (mode modes) - (if (symbol-value mode) - (yas-activate-extra-mode mode) - (setq yas-extra-modes (delq mode yas-extra-modes))))))) + (when (boundp 'yas-extra-modes) + (dolist (mode modes) + (if (symbol-value mode) + (yas-activate-extra-mode mode) + (setq yas-extra-modes (delq mode yas-extra-modes))))))) ;; keybinds - (bind yas-keymap - "C-e" 'my/yas-goto-end-of-field - "C-a" 'my/yas-goto-start-of-field - "" 'my/yas-goto-end-of-field - "" 'my/yas-goto-start-of-field + (bind :map yas-keymap + "C-e" 'narf/yas-goto-end-of-field + "C-a" 'narf/yas-goto-start-of-field + "" 'narf/yas-goto-end-of-field + "" 'narf/yas-goto-start-of-field "" 'yas-prev-field - "" 'my/yas-clear-to-sof + "" 'narf/yas-clear-to-sof - [backspace] 'my/yas-backspace - "" 'my/yas-delete))) + [backspace] 'narf/yas-backspace + "" 'narf/yas-delete))) (provide 'init-yasnippet) diff --git a/init/my-bindings.el b/init/my-bindings.el deleted file mode 100644 index 48b01c4ca..000000000 --- a/init/my-bindings.el +++ /dev/null @@ -1,313 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Global keymaps ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(bind "A-x" 'smex - "A-X" 'smex-major-mode-commands - "A-M-x" 'helm-M-x - "A-;" 'eval-expression - "C-`" 'popwin:toggle-popup-window - "M-=" 'text-scale-increase - "M--" 'text-scale-decrease - "M-w" 'evil-window-delete - "M-/" 'evil-commentary-line - "M-b" 'my:build) - -(bind 'motion - ;; Faster scrolling - "M-j" "6j" - "M-k" "6k" - "M-r" 'my:eval-region - - 'normal - "M-o" 'ido-find-file - "M-O" 'my-ido-find-project-file - "" 'dash-at-point - "M-R" 'my:eval-buffer) - -(when is-mac - ;; Restore text nav keys - (bind "" 'backward-word - "" 'forward-word - "" 'my.backward-kill-to-bol-and-indent - "A-SPC" 'just-one-space - "M-a" 'mark-whole-buffer - "M-c" 'evil-yank - "M-s" 'save-buffer - "M-v" 'yank)) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Local keymaps ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(define-prefix-command 'my-leader-map) -(define-prefix-command 'my-localleader-map) - -(bind '(normal motion visual) ";" 'evil-ex) - -;; -(bind my-leader-map - "," (λ (if (projectile-project-p) (helm-projectile-switch-to-buffer) (helm-buffers-list))) - "<" 'helm-buffers-list - "." 'ido-find-file - ">" (λ (let ((default-directory (project-root))) (ido-find-file))) - "/" 'helm-projectile-find-file - ";" 'helm-semantic-or-imenu - "]" 'helm-etags-select - "a" 'helm-projectile-find-other-file - "E" 'my:init-files - "g" 'git-gutter+-show-hunk - "h" 'helm-apropos - "n" 'my:notes - "m" 'helm-recentf - "M" 'helm-projectile-recentf ; recent PROJECT files - "p" 'helm-projectile-switch-project - "r" 'emr-show-refactor-menu ; init-dev.el - "x" 'my:org-capture - "qq" 'evil-save-and-quit - "QQ" (λ (my:kill-buffers t) (evil-quit-all)) - - "oo" 'my-open-with - "ob" (λ (my-open-with "Google Chrome")) - "of" (λ (my-open-with "Finder.app" default-directory)) - "oF" (λ (my-open-with "Finder.app" (project-root))) - "ou" (λ (my-open-with "Transmit")) - "oU" (λ (my-open-with "Transmit" default-directory)) - "ol" (λ (my-open-with "LaunchBar")) - "oL" (λ (my-open-with "LaunchBar" default-directory)) - ;; tmux: cd (default-directory) - "ot" (λ (my:tmux-chdir nil t)) - ;; tmux: cd [project root] - "oT" 'my:tmux-chdir) - -;; -(bind my-localleader-map - "\\" 'my-neotree-toggle - "." 'my-neotree-find - ";" 'nlinum-toggle - "=" 'toggle-transparency - "E" 'evil-emacs-state - - "]" 'next-buffer - "[" 'previous-buffer - - "g" 'git-gutter+-show-hunk - "e" (λ (flycheck-buffer) (flycheck-list-errors)) - "p" 'helm-show-kill-ring - "b" 'helm-bookmarks - "w" 'helm-wg) - - -(bind 'normal - "," 'my-leader-map - "\\" 'my-localleader-map - - ;; behave like D and C; yank to end of line - "Y" (λ (evil-yank (point) (point-at-eol))) - "zx" 'my-kill-real-buffer - "ZX" 'bury-buffer - "]b" 'my-next-real-buffer - "[b" 'my-previous-real-buffer - "]w" 'wg-switch-to-workgroup-right - "[w" 'wg-switch-to-workgroup-left - - ;; Increment/decrement number under cursor - "g=" 'evil-numbers/inc-at-pt - "g-" 'evil-numbers/dec-at-pt - "gR" 'my:eval-buffer ; init-dev.el - "gc" 'evil-commentary - "gy" 'evil-commentary-yank - - 'visual - ",=" 'align-regexp - - ;; vnoremap < >gv - ">" (λ (evil-shift-right (region-beginning) (region-end)) - (evil-normal-state) - (evil-visual-restore)) - - 'motion - "%" 'evilmi-jump-items - [tab] 'evilmi-jump-items ; alias for % - - "]g" 'git-gutter+-next-hunk - "[g" 'git-gutter+-previous-hunk - - "]e" (λ (call-interactively (if flycheck-mode 'flycheck-next-error 'next-error))) - "[e" (λ (call-interactively (if flycheck-mode 'flycheck-previous-error 'previous-error))) - - "C-=" 'er/expand-region - "C--" 'er/contract-region - - ;; "gl" (λ (nlinum-enable) (evil-ex "") (nlinum-disable)) - "gx" 'evil-exchange - "gr" 'my:eval-region ; init-dev.el - "g]" 'smart-down - "g[" 'smart-up - - 'insert - "" 'evil-delete-backward-word - "" (λ (evil-forward-word) (evil-delete-backward-word)) - - ;; Newline magic - "" 'backward-delete-char-untabify - "" 'my.backward-kill-to-bol-and-indent - "" 'evil-ret-and-indent - - ;; Textmate-esque indent shift left/right - "M-[" (kbd "C-o m l C-o I DEL C-o ` l") - "M-]" (λ (evil-shift-right (point-at-bol) (point-at-eol))) - "" (kbd "M-[") - - ;; Easy escape from insert mode (more responsive than using key-chord-define) - "j" 'my--maybe-exit-insert-mode - "C-g" 'evil-normal-state - - ;; Company-mode - "C-SPC" 'company-complete-common - "C-x C-k" 'company-dictionary - "C-x C-f" 'company-files - "C-x C-]" 'company-etags - "C-x s" 'company-ispell - "C-x C-s" 'company-yasnippet - "C-x C-o" 'company-semantic - "C-x C-n" 'company-dabbrev-code - "C-x C-p" (λ (let ((company-selection-wrap-around t)) - (call-interactively 'company-dabbrev-code) - (company-select-previous-or-abort))) - - 'operator - "s" 'evil-surround-edit - "S" 'evil-Surround-edit - - 'visual - "z" 'evil-snipe-s - "Z" 'evil-snipe-S - - "S" 'evil-surround-region - - ;; Rotate-text (see elisp/rotate-text.el) - 'normal "!" 'rotate-word-at-point - 'visual "!" 'rotate-region - - 'emacs - [escape] 'evil-normal-state) - -(bind evil-window-map - ;; winner-mode: window layout undo/redo (see core.el) - "u" 'winner-undo - "C-u" 'winner-undo - "C-r" 'winner-redo) - -;; Real go-to-definition for elisp -(bind 'motion emacs-lisp-mode-map - "gd" (λ (let ((func (function-called-at-point))) - (if func (find-function func)))) - "gD" (λ (let ((func (function-called-at-point))) - (if func (find-function-other-window func))))) - -;; Peek at file from dired -;; (bind dired-mode-map "o" (λ (popwin:find-file (dired-get-file-for-visit)))) - -(after "help-mode" - (bind 'normal help-mode-map - "" (λ (kill-buffer) - (if (eq popwin:popup-buffer (current-buffer)) - (popwin:close-popup-window) - (evil-window-delete))) - "]]" 'help-go-forward - "[[" 'help-go-back)) - -(bind '(insert normal) - ;; Textmate-esque insert-line before/after - (kbd "") 'evil-open-below - (kbd "") 'evil-open-above) - -;; Fix osx keymappings and then some -(bind 'insert - "" 'my.move-to-bol - "" 'my.move-to-eol - "" 'beginning-of-buffer - "" 'end-of-buffer - "" 'smart-up - "" 'smart-down) - -;; Line selection via linum -(bind " " 'my-select-linum - " " 'my-select-linum - " " 'my-select-linum - " " 'my-select-block) - -(bind 'visual - "*" 'evil-visualstar/begin-search-forward - "#" 'evil-visualstar/begin-search-backward) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Keymap fixes ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; This section is dedicated to keymaps that "fix" certain keys so -;; that they behave more like vim (or how I like it). - -;; Restores "dumb" indentation to the tab key. This rustles a lot of -;; peoples' jimmies, apparently, but it's how I like it. -(bind 'insert "" 'my.dumb-indent) -(bind 'insert "" 'indent-for-tab-command) - -;; No dumb-tab for lisp -(bind 'insert lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) -(bind 'insert emacs-lisp-mode-map [remap my.dumb-indent] 'indent-for-tab-command) - -;; Highjacks space/backspace to: -;; a) delete spaces on either side of the cursor, if present ( | ) -> (|) -;; b) allow backspace to delete space-indented blocks intelligently -;; c) and not do any of this magic when inside a string -(bind 'insert - "SPC" 'my.inflate-space-maybe - [remap backward-delete-char-untabify] 'my.deflate-space-maybe - [remap newline] 'my.newline-and-indent - - ;; Smarter move-to-beginning-of-line - [remap move-beginning-of-line] 'my.move-to-bol - - ;; Restore bash-esque keymaps in insert mode; C-w and C-a already exist - "C-e" 'my.move-to-eol - "C-u" 'my.backward-kill-to-bol-and-indent - - ;; Fixes delete - (kbd "") 'delete-char) - -;; Make ESC quit all the things -(dolist (map (list minibuffer-local-map - minibuffer-local-ns-map - minibuffer-local-completion-map - minibuffer-local-must-match-map - minibuffer-local-isearch-map)) - (bind map [escape] 'my--minibuffer-quit)) -(bind 'emacs [escape] 'my--minibuffer-quit) - -;; Redefine to get rid of that silly delete-other-windows nonsense -(defun keyboard-escape-quit () - (interactive) - (cond ((eq last-command 'mode-exited) nil) - ((region-active-p) - (deactivate-mark)) - ((> (minibuffer-depth) 0) - (abort-recursive-edit)) - (current-prefix-arg - nil) - ((> (recursion-depth) 0) - (exit-recursive-edit)) - (buffer-quit-function - (funcall buffer-quit-function)) - ((string-match "^ \\*" (buffer-name (current-buffer))) - (bury-buffer)))) - - -(provide 'my-bindings) -;;; my-bindings.el ends here diff --git a/init/my-commands.el b/init/my-commands.el deleted file mode 100644 index 900643e5c..000000000 --- a/init/my-commands.el +++ /dev/null @@ -1,77 +0,0 @@ -(defalias 'exmap 'evil-ex-define-cmd) - -(exmap "l[ast]" 'popwin:popup-last-buffer) -(exmap "m[sg]" 'popwin:messages) - -(exmap "full[scr]" 'toggle-fullscreen) -(exmap "ini" 'my:init-files) -(exmap "n[otes]" 'my:notes) -(exmap "recompile" 'my:byte-compile) -(exmap "cd" 'my:cd) -(exmap "en[ew]" 'my:create-file) -(exmap "ren[ame]" 'my:rename-this-file) ; rename [NEWNAME] # rename file -(exmap "al[ign]" 'my:align) -(exmap "retab" 'my:retab) -(exmap "sq[uint]" 'my:narrow-indirect) ; Narrow buffer to selection -(exmap "x" 'my:scratch-buffer) - -(exmap "k[ill]" 'kill-this-buffer) ; Kill current buffer -(exmap "k[ill]o" 'my-cleanup-buffers) ; Kill current project buffers -(exmap "k[ill]all" 'my:kill-buffers) ; Kill all buffers (bang = project buffers only) -(exmap "k[ill]buried" 'my:kill-buried-buffers) ; Kill all buffers (bang = project buffers only) - -(exmap "ma[ke]" 'my:build) - -(exmap "t" 'my:tmux-run) -(exmap "tcd" 'my:tmux-chdir) - -(exmap "a" 'helm-projectile-find-other-file) -(exmap "proj[ect]" 'helm-projectile-switch-project) -(exmap "ag" 'my:helm-ag-search) -(exmap "agr" 'my:helm-ag-regex-search) -(exmap "ag[cw]d" 'my:helm-ag-search-cwd) -(exmap "agr[cw]d" 'my:helm-ag-regex-search-cwd) -(exmap "sw[oop]" 'my:helm-swoop) -(exmap "rec[ent]" 'my:helm-recentf) -(exmap "snip[pets]" 'my:snippets) -(exmap "ref[actor]" 'emr-show-refactor-menu) - -(after "flycheck" - (exmap "er[rors]" (λ (flycheck-buffer) (flycheck-list-errors)))) - -(after "git-gutter-fringe+" - (exmap "gstage" 'git-gutter+-stage-hunks) - (exmap "grevert" 'git-gutter+-revert-hunks) - (exmap "gdiff" 'git-gutter+-show-hunk)) - -(after "re-builder" - (exmap "re[gex]" 'my:regex)) - -(after "workgroups2" - (exmap "sl[oad]" 'my:load-session) - (exmap "ss[ave]" 'my:save-session) - (exmap "wg" (λ (message (wg-workgroup-list-display)))) - (exmap "wnew" 'my:new-workgroup) - (exmap "wre[name]" 'my:rename-workgroup) - (exmap "wn[ext]" 'wg-switch-to-workgroup-right) - (exmap "wp[rev]" 'wg-switch-to-workgroup-left) - (exmap "wl[ast]" 'wg-switch-to-previous-workgroup) - (exmap "k[ill]w" 'wg-kill-workgroup) - (exmap "k[ill]ow" (λ (let (workgroup (wg-current-workgroup)) - (dolist (w (wg-workgroup-list)) - (unless (wg-current-workgroup-p w) - (wg-kill-workgroup w))))))) - -(after "org" - (exmap "o[rg]edit" 'org-edit-special) - (exmap "o[rg]refile" 'org-refile) - (exmap "o[rg]archive" 'org-archive-subtree) - (exmap "o[rg]agenda" 'org-agenda) - (exmap "o[rg]todo" 'org-show-todo-tree) - (exmap "o[rg]link" 'org-link) - (exmap "o[rg]align" 'org-align-all-tags) - (exmap "o[rg]image" 'my:org-insert-image)) - - -(provide 'my-commands) -;;; my-commands.el ends here diff --git a/init/my-defuns.el b/init/my-defuns.el deleted file mode 100644 index be9d282b2..000000000 --- a/init/my-defuns.el +++ /dev/null @@ -1,26 +0,0 @@ - -;;;; HTML ;;;; -;; Replace smart quotes and other MS Word verbiage into plain text -(defun replace:plain-textify (beg end) - (interactive "r") - (replace-regexp "…" "..." nil beg end) - (replace-regexp "[‘’]" "'" nil beg end) - (replace-regexp "[“”]" "\"" nil beg end)) - -;; Email address with mailto link -(defun replace:email2mailto (beg end) - (interactive "r") - (replace-regexp "\\b\\([a-zA-Z0-9._+-%]+@[a-zA-Z0-9-.]+\\.[a-zA-Z]+\\)\\b" - "\\1" - nil beg end)) - -;; Link with anchor -(defun replace:url2anchor (beg end) - (interactive "r") - (replace-regexp "\\bhttps?://.+?\\b" - "\\1" - nil beg end)) - - -(provide 'my-defuns) -;;; my-defuns.el ends here diff --git a/init/my-settings.el b/init/my-settings.el deleted file mode 100644 index 05eba688e..000000000 --- a/init/my-settings.el +++ /dev/null @@ -1,27 +0,0 @@ -(set-register ?. "~/.dotfiles/") -(set-register ?d "~/Dropbox/Projects/") -(set-register ?@ "~/.emacs.d/init.el") - -;;;; Keymap Fixes ;;;;;;;;;;;;;;;;;;;;;; -;; Implements some helpful keymappings for emacs sub-modes -(add-hook! 'ido-setup-hook - (bind ido-completion-map - "" 'ido-delete-backward-updir - "C-w" 'ido-delete-backward-word-updir)) - -(bind 'emacs [escape] 'my--minibuffer-quit) -(bind 'normal evil-command-window-mode-map [escape] 'kill-buffer-and-window) -;; (bind evil-ex-map [escape] 'my--minibuffer-quit) - -;; (dolist (map (list evil-ex-search-keymap minibuffer-local-map ido-common-completion-map ido-completion-map)) -;; (bind map "C-w" 'evil-delete-backward-word)) - -(bind minibuffer-local-map "\C-u" 'evil-delete-whole-line) - -(global-unset-key (kbd "")) - -(if is-mac (global-set-key (kbd "M-q") (λ (message "Gee, I dunno Brain...")))) - - -(provide 'my-settings) -;;; my-settings.el ends here diff --git a/init/narf-bindings.el b/init/narf-bindings.el new file mode 100644 index 000000000..e1efa29a7 --- /dev/null +++ b/init/narf-bindings.el @@ -0,0 +1,348 @@ +(eval-when-compile (require 'defuns)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Global keymaps ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(bind "M-x" 'smex + "M-X" 'smex-major-mode-commands + "M-A-x" 'helm-M-x + "M-;" 'eval-expression + "C-`" 'popwin:toggle-popup-window + "M-=" 'text-scale-increase + "M--" 'text-scale-decrease + "M-w" 'evil-window-delete + "M-/" 'evil-commentary-line + "M-b" 'narf::build + "M-t" 'helm-projectile-find-file) + +(bind motion + ;; Faster scrolling + "M-j" "6j" + "M-k" "6k" + "M-r" 'narf::eval + + normal + "M-o" 'narf:ido-find-file + "M-O" 'narf:ido-find-project-file + "" 'dash-at-point + + "M-R" 'narf::eval-buffer) + +;; Restore text nav keys +(bind :if IS-MAC + "" 'backward-word + "" 'forward-word + "" 'narf:backward-kill-to-bol-and-indent + "A-SPC" 'just-one-space + "M-a" 'mark-whole-buffer + "M-c" 'evil-yank + "M-s" 'save-buffer + "M-v" 'clipboard-yank + "M-q" 'evil-quit-all + "M-z" 'undo + "M-Z" 'redo + "C-M-f" 'narf:toggle-fullscreen) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Local keymaps ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(bind (normal motion visual) ";" 'evil-ex) + +(bind normal + :prefix leader + "," (λ (if (narf/project-p) (helm-projectile-switch-to-buffer) (helm-buffers-list))) + "<" 'helm-buffers-list + "." 'narf:ido-find-file + ">" 'narf:ido-find-file-other-window + "/" 'helm-projectile-find-file + ";" 'helm-semantic-or-imenu + + "]" 'helm-etags-select + "a" 'helm-projectile-find-other-file + "E" 'narf::initfiles + "h" 'helm-apropos + "n" 'narf::notes + "m" 'helm-recentf + "M" 'helm-projectile-recentf ; recent PROJECT files + "p" 'helm-projectile-switch-project + "r" 'emr-show-refactor-menu + + "qq" 'evil-save-and-quit + "QQ" (λ (let ((confirm-kill-emacs nil)) (narf::kill-buffers t) (evil-quit-all))) + + ;; insert lines in-place + "jj" (λ (save-excursion (evil-insert-newline-below))) + "kk" (λ (save-excursion (evil-insert-newline-above))) + + "oo" 'narf:osx-open-with + "ob" (λ (narf:osx-open-with "Google Chrome")) + "of" (λ (narf:osx-open-with "Finder.app" default-directory)) + "oF" (λ (narf:osx-open-with "Finder.app" (narf/project-root))) + "ou" (λ (narf:osx-open-with "Transmit")) + "oU" (λ (narf:osx-open-with "Transmit" default-directory)) + "ol" (λ (narf:osx-open-with "LaunchBar")) + "oL" (λ (narf:osx-open-with "LaunchBar" default-directory)) + "ot" (λ (narf::tmux-chdir nil t)) ; tmux: cd (default-directory) + "oT" 'narf::tmux-chdir ; tmux: cd [project root] + + :prefix localleader + "\\" 'narf:neotree-toggle + "." 'narf:neotree-find + ";" 'narf:nlinum-toggle + "=" 'toggle-transparency + "E" 'evil-emacs-state + + "]" 'next-buffer + "[" 'previous-buffer + + "s" (λ (narf::snippets t)) ; ido snippets dir + "g" 'diff-hl-diff-goto-hunk + "e" (λ (call-interactively 'flycheck-buffer) (flycheck-list-errors)) + "p" 'helm-show-kill-ring + "b" 'helm-bookmarks + "w" 'helm-wg) + +(bind normal + "Y" (λ (evil-yank (point) (point-at-eol))) ; yank to eol, like D and C + + "zr" 'narf:open-folds + "zm" 'narf:close-folds + + "zx" 'narf:kill-real-buffer + "zX" 'bury-buffer + + "]b" 'narf:next-real-buffer + "[b" 'narf:previous-real-buffer + "]w" 'wg-switch-to-workgroup-right + "[w" 'wg-switch-to-workgroup-left + + ;; Increment/decrement number under cursor + "g=" 'evil-numbers/inc-at-pt + "g-" 'evil-numbers/dec-at-pt + "gR" 'narf::eval-buffer + "gc" 'evil-commentary + "gy" 'evil-commentary-yank + + visual + "gR" 'narf::eval-region-and-replace + ",=" 'align-regexp + + ;; vnoremap < >gv + ">" (λ (evil-shift-right (region-beginning) (region-end)) + (evil-normal-state) + (evil-visual-restore)) + + ;; undo/redo for regions + ;; "u" 'undo-tree-undo + ;; "C-r" 'redo-tree-redo + + "*" 'evil-visualstar/begin-search-forward + "#" 'evil-visualstar/begin-search-backward + + ;; paste from recent yank register; which isn't overwritten by deletes or + ;; other operations. + "P" "\"0p" + + "S" 'evil-surround-region + "R" 'evil-iedit-state/iedit-mode ; edit all instances of marked region + "v" 'er/expand-region + "V" 'er/contract-region + + motion + ;; aliases for % + "%" 'evilmi-jump-items + [tab] (λ (if (ignore-errors (hs-already-hidden-p)) + (hs-toggle-hiding) + (call-interactively 'evilmi-jump-items))) + + "]g" 'diff-hl-next-hunk + "[g" 'diff-hl-previous-hunk + + "]e" (λ (call-interactively (if (bound-and-true-p flycheck-mode) 'flycheck-next-error 'next-error))) + "[e" (λ (call-interactively (if (bound-and-true-p flycheck-mode) 'flycheck-previous-error 'previous-error))) + + "gl" 'narf:goto-line + "gs" 'evil-ace-jump-two-chars-mode + "gx" 'evil-exchange + "gr" 'narf::eval-region + "g]" 'smart-down + "g[" 'smart-up + + insert + "" 'evil-delete-backward-word + "" (λ (evil-forward-word) (evil-delete-backward-word)) + + ;; Newline magic + "" 'backward-delete-char-untabify + "" 'narf:backward-kill-to-bol-and-indent + "" 'evil-ret-and-indent + + ;; Textmate-esque indent shift left/right + "M-[" (kbd "C-o m l C-o I DEL C-o ` l") + "M-]" (λ (evil-shift-right (point-at-bol) (point-at-eol))) + "" (kbd "M-[") + + ;; Company-mode + "C-SPC" 'company-complete-common + "C-x C-k" 'company-dictionary + "C-x C-f" 'company-files + "C-x C-]" 'company-tags + "C-x s" 'company-ispell + "C-x C-s" 'company-yasnippet + "C-x C-o" 'company-semantic + "C-x C-n" 'company-dabbrev-code + "C-x C-p" (λ (let ((company-selection-wrap-around t)) + (call-interactively 'company-dabbrev-code) + (company-select-previous-or-abort))) + + (insert replace) + ;; escape from insert mode (more responsive than using key-chord-define) + "j" 'narf:exit-mode-maybe + + (insert replace visual) + "C-g" 'evil-normal-state + + operator + "s" 'evil-surround-edit + "S" 'evil-Surround-edit + + ;; Rotate-text (see elisp/rotate-text.el) + normal "!" 'rotate-word-at-point + visual "!" 'rotate-region + emacs [escape] 'evil-normal-state) + +(bind :map evil-window-map + ;; winner-mode: window layout undo/redo (see core.el) + "u" 'winner-undo + "C-u" 'winner-undo + "C-r" 'winner-redo + + "C-w" 'ace-window + "C-S-w" (λ (ace-window 4)) ; swap windows + "C-C" (λ (ace-window 16))) ; delete windows + +(after "help-mode" + (bind normal :map help-mode-map + "" (λ (kill-buffer) + (if (eq popwin:popup-buffer (current-buffer)) + (popwin:close-popup-window) + (evil-window-delete))) + "]]" 'help-go-forward + "[[" 'help-go-back)) + +(bind :map evil-ex-completion-map + "C-r" 'evil-ex-paste-from-register ; registers in ex-mode + "C-a" 'move-beginning-of-line + "" 'move-beginning-of-line + "" 'move-beginning-of-line + "" 'evil-delete-whole-line) + +(bind :map company-active-map + "C-o" 'company-search-kill-others + "C-n" 'company-select-next-or-abort + "C-p" 'company-select-previous-or-abort + "C-h" 'company-show-doc-buffer + "C-S-h" 'company-show-location + "C-S-s" 'company-search-candidates + "C-s" 'company-filter-candidates + "C-SPC" 'company-complete-common + [tab] 'company-complete + "" 'company-select-previous + [escape] 'company-abort + "" 'helm-company + "C-w" nil + + :map company-search-map + "C-n" 'company-search-repeat-forward + "C-p" 'company-search-repeat-backward + [escape] 'company-abort + "C-w" nil) + +(bind :map evil-snipe-override-mode-map + "C-;" 'evil-snipe-repeat + "C-," 'evil-snipe-repeat-reverse) + +;; TODO: Swap helm's C-z and Tab + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Keymap fixes ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; This section is dedicated to keymaps that "fix" certain keys so +;; that they behave more like vim (or how I like it). + +;; Restores "dumb" indentation to the tab key. This rustles a lot of +;; peoples' jimmies, apparently, but it's how I like it. +(bind insert + "" 'narf:dumb-indent + "" 'indent-for-tab-command + + ;; No dumb-tab for lisp + :map lisp-mode-map [remap narf:dumb-indent] 'indent-for-tab-command + :map emacs-lisp-mode-map [remap narf:dumb-indent] 'indent-for-tab-command) + +;; Highjacks space/backspace to: +;; a) delete spaces on either side of the cursor, if present ( | ) -> (|) +;; b) allow backspace to delete space-indented blocks intelligently +;; c) and not do any of this magic when inside a string +(bind insert + "SPC" 'narf:inflate-space-maybe + [remap backward-delete-char-untabify] 'narf:deflate-space-maybe + [remap newline] 'narf:newline-and-indent + + ;; Smarter move-to-beginning-of-line + [remap move-beginning-of-line] 'narf:move-to-bol + + ;; Restore bash-esque keymaps in insert mode; C-w and C-a already exist + "C-e" 'narf:move-to-eol + "C-u" 'narf:backward-kill-to-bol-and-indent + + ;; Fixes delete + "" 'delete-char + + ;; Fix osx keymappings and then some + "" 'narf:move-to-bol + "" 'narf:move-to-eol + "" 'beginning-of-buffer + "" 'end-of-buffer + "" 'smart-up + "" 'smart-down + + ;; Fix emacs motion keys + "A-b" 'evil-backward-word-begin + "A-w" 'evil-forward-word-begin + "A-e" 'evil-forward-word-end + + (insert normal) + ;; Textmate-esque insert-line before/after + "" 'evil-open-below + "" 'evil-open-above) + +;; Make ESC quit all the things +(bind :map (minibuffer-local-map + minibuffer-local-ns-map + minibuffer-local-completion-map + minibuffer-local-must-match-map + minibuffer-local-isearch-map) + [escape] 'narf/minibuffer-quit) +(bind emacs [escape] 'narf/minibuffer-quit) + +(bind :map read-expression-map "C-w" 'evil-delete-backward-word) + +;; Line selection via linum +(bind " " 'narf/mouse-select-line + " " 'narf/mouse-select-line + " " 'narf/mouse-select-line + " " 'narf/mouse-select-block) + + +(provide 'narf-bindings) +;;; narf-bindings.el ends here diff --git a/init/narf-commands.el b/init/narf-commands.el new file mode 100644 index 000000000..2b21dc3fe --- /dev/null +++ b/init/narf-commands.el @@ -0,0 +1,88 @@ +;; ex-commands +(evil-define-command narf::byte-compile (&optional bang) + :repeat nil + (interactive "") + (when emacs-lisp-mode + (if (not bang) + (progn ;; (byte-recompile-file (concat CORE-DIR "defuns.el") t 0) + (byte-recompile-file (buffer-file-name) t 0)) + (byte-recompile-file (expand-file-name "init.el" BASE-DIR) nil 0) + (byte-recompile-directory CORE-DIR 0 nil) + (byte-recompile-directory CONTRIB-DIR 0 nil) + (dolist (path (directory-files MODULES-DIR t "\\(core\\|defuns\\|narf\\).*\\.el$")) + (byte-recompile-file path nil 0))))) + +(evil-define-command narf::autoload-compile (&optional bang) + :repeat nil + (interactive "") + (defvar generated-autoload-file (expand-file-name "autoloads.el" MODULES-DIR)) + (update-directory-autoloads CORE-DIR MODULES-DIR CONTRIB-DIR)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(excmd! "settr[im]" 'narf:toggle-delete-trailing-whitespace) + +(excmd! "echo" 'narf::echo) +(excmd "l[ast]" 'popwin:popup-last-buffer) +(excmd "m[sg]" 'popwin:messages) +(excmd! "full[scr]" 'narf:toggle-fullscreen) +(excmd! "ini" 'narf::initfiles) +(excmd! "bcomp[ile]" 'narf::byte-compile) +(excmd! "acomp[ile]" 'narf::autoload-compile) +(excmd! "cd" 'narf::cd) +(excmd! "en[ew]" 'narf::create-file) +(excmd! "ren[ame]" 'narf::rename-this-file) ; rename [NEWNAME] # rename file +(excmd! "del[ete]" 'narf::delete-this-file) ; delete[!] +(excmd! "al[ign]" 'narf::align) +(excmd! "retab" 'narf::retab) +(excmd! "na[rrow]" 'narf::narrow-indirect-or-widen) ; Narrow buffer to selection +(excmd! "x" 'narf::scratch-buffer) +(excmd "k[ill]" 'kill-this-buffer) ; Kill current buffer +(excmd! "k[ill]o" 'narf:cleanup-buffers) ; Kill current project buffers +(excmd! "k[ill]all" 'narf::kill-buffers) ; Kill all buffers (bang = project buffers only) +(excmd! "k[ill]buried" 'narf::kill-buried-buffers) ; Kill all buffers (bang = project buffers only) +(excmd! "ma[ke]" 'narf::build) +(excmd! "t" 'narf::tmux-run) +(excmd! "tcd" 'narf::tmux-chdir) +(excmd! "a" 'helm-projectile-find-other-file) +(excmd! "proj[ect]" 'helm-projectile-switch-project) +(excmd! "ag" 'narf::ag-search) +(excmd! "agr" 'narf::ag-regex-search) +(excmd! "ag[cw]d" 'narf::ag-search-cwd) +(excmd! "agr[cw]d" 'narf::ag-regex-search-cwd) +(excmd! "sw[oop]" 'narf::swoop) +(excmd! "rec[ent]" 'narf::recentf) +(excmd! "ref[actor]" 'emr-show-refactor-menu) +(excmd! "snip[pets]" 'narf::snippets) ; snip[!] +(excmd! "cap[ture]" 'helm-org-capture-templates) +(excmd! "n[otes]" 'helm-org-agenda-files-headings) +(after "flycheck" + (excmd! "er[rors]" (λ (flycheck-buffer) (flycheck-list-errors)))) +(after "re-builder" + (excmd "re[gex]" 'narf::regex)) +(after "org" + (excmd "o[rg]edit" 'org-edit-special) + (excmd "o[rg]refile" 'org-refile) + (excmd "o[rg]archive" 'org-archive-subtree) + (excmd "o[rg]agenda" 'org-agenda) + (excmd "o[rg]todo" 'org-show-todo-tree) + (excmd "o[rg]link" 'org-link) + (excmd "o[rg]align" 'org-align-all-tags)) +(after "workgroups2" + (excmd! "sl[oad]" 'narf::load-session) + (excmd! "ss[ave]" 'narf::save-session) + (excmd "wg" (λ (message (wg-workgroup-list-display)))) + (excmd! "wnew" 'narf::new-workgroup) + (excmd! "wre[name]" 'narf::rename-workgroup) + (excmd "wn[ext]" 'wg-switch-to-workgroup-right) + (excmd "wp[rev]" 'wg-switch-to-workgroup-left) + (excmd "wl[ast]" 'wg-switch-to-previous-workgroup) + (excmd "k[ill]w" 'wg-kill-workgroup) + (excmd "k[ill]ow" (λ (let (workgroup (wg-current-workgroup)) + (dolist (w (wg-workgroup-list)) + (unless (wg-current-workgroup-p w) + (wg-kill-workgroup w))))))) + + +(provide 'narf-commands) +;;; narf-commands.el ends here diff --git a/init/narf-settings.el b/init/narf-settings.el new file mode 100644 index 000000000..9a8ccd457 --- /dev/null +++ b/init/narf-settings.el @@ -0,0 +1,26 @@ +(set-register ?. "~/.dotfiles/") +(set-register ?d "~/Dropbox/Projects/") +(set-register ?@ "~/.emacs.d/init.el") + +;;;; Keymap Fixes ;;;;;;;;;;;;;;;;;;;;;; +;; Implements some helpful keymappings for emacs sub-modes +(add-hook! 'ido-setup-hook + (bind :map (ido-completion-map ido-file-completion-map) + ;; "" 'ido-delete-backward-updir + "C-w" 'ido-delete-backward-word-updir)) + +(bind :normal :map evil-command-window-mode-map [escape] 'kill-buffer-and-window) +(bind :map evil-ex-map [escape] 'narf/minibuffer-quit) + +(bind :map minibuffer-local-map "\C-u" 'evil-delete-whole-line) + +;; Disable the global drag-mouse map; clicking in new buffers often sends evil +;; into visual mode, which is UN...ACCEPTAABBLLLEEEE! +(global-unset-key (kbd "")) + +;; Don't allow quitting easily. +(setq confirm-kill-emacs (lambda (prompt) (y-or-n-p ">> Gee, I dunno Brain... Are you sure?"))) + + +(provide 'narf-settings) +;;; narf-settings.el ends here diff --git a/themes/narf-dark-theme.el b/themes/narf-dark-theme.el index 6ac4d786b..3cc666408 100644 --- a/themes/narf-dark-theme.el +++ b/themes/narf-dark-theme.el @@ -50,12 +50,12 @@ `(mode-line ((t (:foreground ,white :background ,gutter-light - :box (:line-width 3 :color ,gutter-light) + ;;:box (:line-width 0 :color ,gutter-light) )))) `(mode-line-inactive ((t (:foreground ,gutter-fg :background ,gutters-active - :box (:line-width 3 :color ,gutters-active) + ;;:box (:line-width 0 :color ,gutters-active) )))) `(mode-line-modified-face ((t (:foreground ,builtin)))) diff --git a/themes/narf-light-theme.el b/themes/narf-light-theme.el new file mode 100644 index 000000000..575a826ba --- /dev/null +++ b/themes/narf-light-theme.el @@ -0,0 +1,163 @@ + ;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;; ***************************************************************************************** +;; +;; v0 :- A dark Emacs theme inspired by Space Grey ST2 theme +;; +;; ***************************************************************************************** + +;; +;; By Henrik Lissner +;; + +(deftheme v0 "V-NOUGHT dark theme for Emacs 24+") + + (custom-theme-set-variables 'v0) + + (let (;; (background "#222222") + (background "#2b303b") + ;; (gutters "#262E34") + (gutters "#1f252a") + (gutter-fg "#55616A") + ;; (gutters-active "#2e363c") + (gutters-active "#1c1f26") + (linum "#1e262c") + ;; (gutter-light "#434f58") + (gutter-light "#232830") + (builtin "#d08770") + (foreground "#c0c5ce") + (invisibles "#65737e") + ;; (line-hl "#353539") + (line-hl "#343d46") + (selection "#4f5b66") + (text "#c0c5ce") + (comments "#65737e") + (punctuation "#8fa1b3") + (delimiters "#c0c5ce") + (operators "#c0c5ce") + (keywords "#b48ead") + (variables "#CBECFF") + (functions "#8fa1b3") + (methods "#8fa1b3") + (strings "#a3be8c") + (constants "#d08770") + (white "#ffffff") + (highlight "orange") + (dim-highlight "#556779") + + (git-modified "#55616A") + (git-added "#436b3b") + (git-deleted "#714243")) + + (custom-theme-set-faces + 'v0 + +;; Default colors +;; ***************************************************************************************** + + `(default ((t (:foreground ,text :background ,background) ))) + `(hl-line ((t (:background ,line-hl) ))) + `(region ((t (:background ,selection) ))) + `(cursor ((t (:background ,white) ))) + `(fringe ((t (:background ,background :foreground ,white) ))) + `(linum ((t (:background ,background :foreground ,gutter-fg :weight normal) ))) + + `(vertical-border ((t (:foreground "#000000") ))) + + `(mode-line ((t (:foreground ,white + :background ,gutter-light + :box (:line-width 3 :color ,gutter-light) + )))) + + `(mode-line-inactive ((t (:foreground ,gutter-fg + :background ,gutters-active + :box (:line-width 3 :color ,gutters-active) + )))) + + `(mode-line-modified-face ((t (:foreground ,builtin)))) + + `(sml/folder ((t nil))) + `(sml/modified ((t (:foreground ,highlight)))) + + `(flyspell-incorrect ((t (:underline "#ff5555" :inherit unspecified)))) + + `(helm-source-header ((t (:background ,gutters-active :foreground ,strings :weight bold :height 1.0)))) + `(helm-selection ((t (:background ,selection)))) + +;; Font lock faces +;; ***************************************************************************************** + + `(linum-highlight-face ((t (:foreground ,text :background ,line-hl :inherit linum)))) + + `(font-lock-keyword-face ((t (:foreground ,keywords)))) + `(font-lock-type-face ((t (:foreground ,punctuation)))) + `(font-lock-constant-face ((t (:foreground ,constants)))) + `(font-lock-variable-name-face ((t (:foreground ,variables)))) + `(font-lock-builtin-face ((t (:foreground ,builtin)))) + `(font-lock-string-face ((t (:foreground ,strings)))) + `(font-lock-comment-face ((t (:foreground ,comments)))) + `(font-lock-comment-delimiter-face ((t (:foreground ,comments)))) + `(font-lock-function-name-face ((t (:foreground ,functions)))) + `(font-lock-doc-string-face ((t (:foreground ,comments)))) + `(font-lock-doc-face ((t (:foreground ,comments)))) + + `(trailing-whitespace ((t (:background "#884444")))) + `(whitespace-tab ((t (:foreground "#444444")))) + `(whitespace-newline ((t (:foreground "#444444")))) + `(whitespace-trailing ((t (:background "#553333")))) + + `(git-gutter+-modified ((t (:foreground ,git-modified :background nil)))) + `(git-gutter+-added ((t (:foreground ,git-added :background nil)))) + `(git-gutter+-deleted ((t (:foreground ,git-deleted :background nil)))) + + `(diff-hl-change ((t (:background ,git-modified)))) + `(diff-hl-delete ((t (:background ,git-deleted)))) + `(diff-hl-insert ((t (:background ,git-added)))) + + `(rainbow-delimiters-unmatched-face ((t (:inherit 'error)))) + `(rainbow-delimiters-depth-1-face ((t (:foreground "#CCCCCC" :weight bold :bold t)))) + +;; js2-mode +;; ***************************************************************************************** + + `(js2-function-param ((t (:foreground ,variables)))) + `(js2-jsdoc-tag ((t (:foreground ,comments :weight bold :bold t)))) + + +;; ***************************************************************************************** + + `(persp-selected-face ((t (:foreground ,builtin)))) + + `(org-level-1 ((t (:inherit outline-1 :bold t :foreground ,constants)))) + `(org-level-2 ((t (:inherit outline-2 :bold t :foreground ,variables)))) + + `(show-paren-match ((t (:background nil :foreground ,highlight :weight ultra-bold)))) + + `(evil-snipe-first-match-face ((t (:background ,highlight :foreground "black")))) + `(evil-snipe-matches-face ((t (:foreground ,highlight :background ,dim-highlight)))) + `(isearch ((t (:foreground "black" :background ,highlight :inverse-video nil)))) + `(isearch-lazy-highlight-face ((t (:foreground ,text :background ,dim-highlight)))) + `(evil-search-highlight-persist-highlight-face + ((t (:background nil :foreground nil :inherit isearch-lazy-highlight-face)))) + + )) + + +;; ***************************************************************************************** + +(provide-theme 'v0) + +;; Local Variables: +;; no-byte-compile: t +;; End: