Final update

This commit is contained in:
Henrik Lissner 2015-06-04 18:23:21 -04:00
parent d1aaf44255
commit c49a53f9d3
74 changed files with 4405 additions and 2866 deletions

23
Cask
View file

@ -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")

View file

@ -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"))'

532
core/autoloads.el Normal file
View file

@ -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] <NUMBER> 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

44
core/benchmark.el Normal file
View file

@ -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)

95
core/core-company.el Normal file
View file

@ -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

162
core/core-editor.el Normal file
View file

@ -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

319
core/core-evil.el Normal file
View file

@ -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

4
core/core-linux.el Normal file
View file

@ -0,0 +1,4 @@
(provide 'core-linux)
;; Nothing here yet

54
core/core-osx.el Normal file
View file

@ -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

145
core/core-splash.el Normal file
View file

@ -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, wouldnt 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 wont 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 didnt 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

217
core/core-ui.el Normal file
View file

@ -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

320
core/core.el Normal file
View file

@ -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

289
core/defuns-buffers.el Normal file
View file

@ -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 <https://github.com/syl20bnr/spacemacs/blob/master/spacemacs/funcs.el>
;;;###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 "<!><a>")
(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 "<!><a>")
(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 "<!><a>")
(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 "<a>")
(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 "<f>")
(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 "<f><!>")
(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 "<r><!>")
(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 "<f>")
(cd (if (zerop (length dir)) "~" dir)))
(provide 'defuns-buffers)
;;; defuns-buffers.el ends here

83
core/defuns-code.el Normal file
View file

@ -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 "<sh>")
(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 "<r>")
(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 "<r>")
(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

View file

@ -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 "<a>")
(let (message-log-max)
(message "%s" message)))
(provide 'defuns-debug)

126
core/defuns-edit.el Normal file
View file

@ -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"
"<a href=\"mailto:\\1\">\\1</a>"
nil beg end))
;;;###autoload
(defun narf:replace-url2anchor (beg end)
"Link with anchor"
(interactive "r")
(replace-regexp "\\bhttps?://.+?\\b"
"<a href=\"\\1\">\\1</a>"
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 "<r><a><!>")
(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 "<r>")
(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 "<r>")
(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

37
core/defuns-extern.el Normal file
View file

@ -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 "<tmux>"
"Ex tmux argument (a mix between <sh> <f> and <fsh>)"
: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 "<tmux><!>")
(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 "<f><!>")
(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

39
core/defuns-mouse.el Normal file
View file

@ -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

92
core/defuns-org.el Normal file
View file

@ -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 "<f>")
(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 "<f><!>")
(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 "<file:%s>" (f-relative dest (f-dirname (buffer-file-name)))))
(indent-according-to-mode))))
(provide 'defuns-org)
;;; defuns-org.el ends here

106
core/defuns-search.el Normal file
View file

@ -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 "<r><a><!>")
(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 "<r><a><!>")
(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 "<r><a><!>")
(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 "<r><a><!>")
(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 "<a><!>")
(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 "<!><a>")
(if bang
(narf:ido-find-file SNIPPETS-DIR)
(helm-yas-visit-snippet-file)))
(provide 'defuns-search)
;;; defuns-search.el ends here

View file

@ -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

27
core/defuns-ui.el Normal file
View file

@ -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)))

299
core/defuns.el Normal file
View file

@ -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 ?\\
:<evil state> 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 \"<escape>\", 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

39
core/startup.el Normal file
View file

@ -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

View file

@ -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 "<sh>")
(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 "<r>")
(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

View file

@ -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
"<s-left>" 'move-beginning-of-line
"<s-right>" 'move-beginning-of-line
"<s-backspace>" '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 "<f>")
(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 "<f><!>")
(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 "<f>")
(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 "<r><!>")
(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 "<r><a><!>")
(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 "<r>")
(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 "<r>")
(evil-normal-state)
(my-narrow-to-region-indirect beg end)))))
(provide 'core-evil)

View file

@ -1,5 +0,0 @@
(when is-linux (add-to-list 'load-path "~/.cask"))
(provide 'core-linux)
;; Nothing here yet

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 <https://github.com/syl20bnr/spacemacs/blob/master/spacemacs/funcs.el>
;;;###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)))))

View file

@ -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)))

View file

@ -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)

View file

@ -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)

View file

@ -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 "@\\<interface\\>"
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))))
))

View file

@ -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
"<backtab>" '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 "<C-return>" 'helm-company)))))
(provide 'init-company)
;;; init-company.el ends here

View file

@ -7,4 +7,5 @@
(add-hook 'ruby-mode-hook (function cscope-minor-mode))
(provide 'init-cscope)

View file

@ -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

11
init/init-data.el Normal file
View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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 "<r><a><!>")
(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 "<r><a><!>")
(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 "<r><a><!>")
(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 "<r><a><!>")
(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 "<a><!>")
(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

View file

@ -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)

View file

@ -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)

View file

@ -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

19
init/init-lisp.el Normal file
View file

@ -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

View file

@ -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)

View file

@ -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
"<M-left>" 'org-beginning-of-line
"<M-right>" 'org-end-of-line
"<M-up>" 'org-up-element
"<M-down>" 'org-down-element)
"<M-down>" '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
"<S-M-return>" 'my--org-insert-item-before
"<S-M-return>" 'narf/org-insert-item-before
;; Add new header line after this line
"<M-return>" 'my--org-insert-item-after
"<M-return>" '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
",<return>" 'org-archive-subtree
"<S-M-return>" 'my--org-insert-item-before
"<M-return>" 'my--org-insert-item-after
"<S-M-return>" 'narf/org-insert-item-before
"<M-return>" '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
"<escape>" '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 "<r><!>")
(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 "<f><!>")
(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 "<f><!>")
(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 "<file:%s>" (f-relative dest (f-dirname (buffer-file-name)))))
(indent-according-to-mode))))))
"C-p" 'org-agenda-previous-item)))))
(provide 'init-org)

View file

@ -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

View file

@ -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

View file

@ -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)

10
init/init-r.el Normal file
View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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
"<backspace>" nil
"<M-left>" nil
"<M-right>" 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 "<backspace>") nil
(kbd "<M-left>") nil
(kbd "<M-right>") 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)

View file

@ -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 "<tmux>"
"Ex tmux argument (a mix between <sh> <f> and <fsh>)"
: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 "<tmux><!>")
(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 "<f><!>")
(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

View file

@ -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

7
init/init-vim.el Normal file
View file

@ -0,0 +1,7 @@
(use-package vimrc-mode
:mode (("/\\.?g?vimrc$" . vimrc-mode)
("\\.vim$" . vimrc-mode)))
(provide 'init-vim)
;;; init-vim.el ends here

View file

@ -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))

View file

@ -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 "<!><a>")
(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 "<!><a>")
(wg-open-session (if session-name
(concat wg-workgroup-directory session-name)
wg-session-file)))
(evil-define-command my:new-workgroup (bang name)
(interactive "<!><a>")
(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 "<a>")
(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)

View file

@ -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 "<backtab>" '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 "<backtab>" 'narf/insert-yas-snippet)
map)))
:config
(progn
(bind 'insert [(tab)] nil)
(bind 'visual "<backtab>" 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 "<backtab>" 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 "<r><a>")
(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
"<M-right>" 'my/yas-goto-end-of-field
"<M-left>" '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
"<M-right>" 'narf/yas-goto-end-of-field
"<M-left>" 'narf/yas-goto-start-of-field
"<S-tab>" 'yas-prev-field
"<M-backspace>" 'my/yas-clear-to-sof
"<M-backspace>" 'narf/yas-clear-to-sof
[backspace] 'my/yas-backspace
"<delete>" 'my/yas-delete)))
[backspace] 'narf/yas-backspace
"<delete>" 'narf/yas-delete)))
(provide 'init-yasnippet)

View file

@ -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
"<f1>" 'dash-at-point
"M-R" 'my:eval-buffer)
(when is-mac
;; Restore text nav keys
(bind "<A-left>" 'backward-word
"<A-right>" 'forward-word
"<M-backspace>" '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)
;; <leader>
(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)
;; <localleader>
(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-left (region-beginning) (region-end))
(evil-normal-state)
(evil-visual-restore))
;; 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
"<A-backspace>" 'evil-delete-backward-word
"<A-delete>" (λ (evil-forward-word) (evil-delete-backward-word))
;; Newline magic
"<backspace>" 'backward-delete-char-untabify
"<M-backspace>" 'my.backward-kill-to-bol-and-indent
"<C-return>" '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)))
"<backtab>" (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
"<escape>" (λ (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 "<M-return>") 'evil-open-below
(kbd "<S-M-return>") 'evil-open-above)
;; Fix osx keymappings and then some
(bind 'insert
"<M-left>" 'my.move-to-bol
"<M-right>" 'my.move-to-eol
"<M-up>" 'beginning-of-buffer
"<M-down>" 'end-of-buffer
"<A-up>" 'smart-up
"<A-down>" 'smart-down)
;; Line selection via linum
(bind "<left-margin> <down-mouse-1>" 'my-select-linum
"<left-margin> <mouse-1>" 'my-select-linum
"<left-margin> <drag-mouse-1>" 'my-select-linum
"<left-margin> <double-mouse-1>" '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 "<tab>" 'my.dumb-indent)
(bind 'insert "<A-tab>" '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 "<kp-delete>") '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

View file

@ -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

View file

@ -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"
"<a href=\"mailto:\\1\">\\1</a>"
nil beg end))
;; Link with anchor
(defun replace:url2anchor (beg end)
(interactive "r")
(replace-regexp "\\bhttps?://.+?\\b"
"<a href=\"\\1\">\\1</a>"
nil beg end))
(provide 'my-defuns)
;;; my-defuns.el ends here

View file

@ -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
"<backspace>" '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 "<drag-mouse-1>"))
(if is-mac (global-set-key (kbd "M-q") (λ (message "Gee, I dunno Brain..."))))
(provide 'my-settings)
;;; my-settings.el ends here

348
init/narf-bindings.el Normal file
View file

@ -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
"<f1>" 'dash-at-point
"M-R" 'narf::eval-buffer)
;; Restore text nav keys
(bind :if IS-MAC
"<A-left>" 'backward-word
"<A-right>" 'forward-word
"<M-backspace>" '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-left (region-beginning) (region-end))
(evil-normal-state)
(evil-visual-restore))
;; 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
"<A-backspace>" 'evil-delete-backward-word
"<A-delete>" (λ (evil-forward-word) (evil-delete-backward-word))
;; Newline magic
"<backspace>" 'backward-delete-char-untabify
"<M-backspace>" 'narf:backward-kill-to-bol-and-indent
"<C-return>" '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)))
"<backtab>" (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
"<escape>" (λ (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
"<s-left>" 'move-beginning-of-line
"<s-right>" 'move-beginning-of-line
"<s-backspace>" '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
"<backtab>" 'company-select-previous
[escape] 'company-abort
"<C-return>" '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
"<tab>" 'narf:dumb-indent
"<C-tab>" '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
"<kp-delete>" 'delete-char
;; Fix osx keymappings and then some
"<M-left>" 'narf:move-to-bol
"<M-right>" 'narf:move-to-eol
"<M-up>" 'beginning-of-buffer
"<M-down>" 'end-of-buffer
"<C-up>" 'smart-up
"<C-down>" '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
"<M-return>" 'evil-open-below
"<S-M-return>" '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 "<left-margin> <down-mouse-1>" 'narf/mouse-select-line
"<left-margin> <mouse-1>" 'narf/mouse-select-line
"<left-margin> <drag-mouse-1>" 'narf/mouse-select-line
"<left-margin> <double-mouse-1>" 'narf/mouse-select-block)
(provide 'narf-bindings)
;;; narf-bindings.el ends here

88
init/narf-commands.el Normal file
View file

@ -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

26
init/narf-settings.el Normal file
View file

@ -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)
;; "<backspace>" '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 "<drag-mouse-1>"))
;; 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

View file

@ -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))))

163
themes/narf-light-theme.el Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
;; *****************************************************************************************
;;
;; v0 :- A dark Emacs theme inspired by Space Grey ST2 theme
;;
;; *****************************************************************************************
;;
;; By Henrik Lissner <http://github.com/hlissner/emacs.d>
;;
(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: