Initial commit (brand new NARF)

This commit is contained in:
Henrik Lissner 2015-06-06 06:40:33 -04:00
parent de70863bed
commit d0628e018a
105 changed files with 1837 additions and 16026 deletions

View file

@ -1,532 +0,0 @@
;;; 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
;;;;;; 43589 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" (21871 23781
;;;;;; 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" (21869 43444
;;;;;; 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" (21869 43359
;;;;;; 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" (21869 43512 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" (21869 45131
;;;;;; 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-data.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") (21873 3804 549513 0))
;;;***
(provide 'autoloads)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; autoloads.el ends here

View file

@ -1,44 +0,0 @@
(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)

View file

@ -1,95 +0,0 @@
(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

0
core/core-completion.el Normal file
View file

371
core/core-defuns.el Normal file
View file

@ -0,0 +1,371 @@
(! (defalias '@--concat-forms 'use-package-concat)
(defalias '@--normalize-symbols 'use-package-normalize-symlist)
(defalias '@--normalize-paths 'use-package-normalize-paths)
;; 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 1))
`(,(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 "")))
(defmacro @ (args &rest body)
"A shortcut for: `(lambda ,args ,@body)"
`(lambda ,args ,@body))
(defmacro λ (&rest body)
"A shortcut for: `(lambda () (interactive) ,@body)"
`(lambda () (interactive) ,@body))
(defmacro @add-hook (hook &rest func-or-forms)
"A convenience macro for `add-hook'.
HOOK can be one hook or a list of hooks. If the hook(s) are not quoted, -hook is
appended to them automatically. If they are quoted, they are used verbatim.
FUNC-OR-FORMS can be one quoted symbol, a list of quoted symbols, or a series of
forms. Forms will be wrapped in one lambda. A list of symbols will expand into a
series of add-hook calls.
Examples:
(@add-hook 'some-mode-hook 'enable-something)
=> (add-hook 'some-mode-hook 'enable-something)
(@add-hook some-mode '(enable-something and-another))
=> (add-hook 'some-mode-hook 'enable-something)
(add-hook 'some-mode-hook 'and-another)
(@add-hook '(one-mode-hook second-mode-hook) 'enable-something)
=> (add-hook 'one-mode-hook 'enable-something)
(add-hook 'second-mode-hook 'enable-something)
(@add-hook (one-mode second-mode) 'enable-something)
=> (add-hook 'one-mode-hook 'enable-something)
(add-hook 'second-mode-hook 'enable-something)
(@add-hook (one-mode second-mode) (setq v 5) (setq a 2))
=> (add-hook 'one-mode-hook (lambda () (setq v 5) (setq a 2)))
(add-hook 'second-mode-hook (lambda () (setq v 5) (setq a 2)))"
(declare (indent 1))
(unless func-or-forms
(error "@add-hook: FUNC-OR-FORMS is empty"))
(let* ((val (car func-or-forms))
(quoted (eq (car-safe hook) 'quote))
(hook (if quoted (cadr hook) hook))
(funcs (if (eq (car-safe val) 'quote)
(if (cdr-safe (cadr val))
(cadr val)
(list (cadr val)))
(list func-or-forms)))
(forms '()))
(mapc (@ (f)
(let ((func (cond ((symbolp f) `(quote ,f))
(t `(lambda () ,@func-or-forms)))))
(mapc (@ (h)
(push `(add-hook ',(if quoted h (intern (format "%s-hook" h))) ,func) forms))
(if (listp hook) hook (list hook))))) funcs)
`(progn ,@forms)))
(cl-defmacro @associate (mode &key in
&key match
&key files
&allow-other-keys)
"Associate a major or minor mode to certain patterns and project files."
(let* ((minor-p (memq mode minor-mode-alist))
(modes (@--normalize-symbols ":in" in)))
(@--concat-forms
(when match
`(add-to-list ,(if minor-p 'narf-auto-minor-mode-alist 'auto-mode-alist)
(cons ,match ,mode)))
(when files
`(defun ,(intern (format "narf|init-mode-%s" 'lb6-mode)) ()
(when (and (assq major-mode '(,@(@--normalize-paths ":in" in)))
(narf-project-has-files ,@(@--normalize-paths ":files" files)))
(,mode 1)))))))
(@after evil
;; Placeholders to correct binding indentation. Don't use these.
(defmacro :leader (key &rest rest) (declare (indent 1)))
(defmacro :localleader (key &rest rest) (declare (indent 1)))
(defmacro :map (key &rest rest) (declare (indent 1)))
(defmacro :after (key &rest rest) (declare (indent 1)))
(defmacro :when (key &rest rest) (declare (indent 1)))
(macroexpand `(@map (:map my-map "C-k" 'hello :n "C-p" 'goodbye)))
(defmacro @map (&rest rest)
(declare (indent defun))
(let ((i 0)
key def
first-set
prefix
(default-keymaps '(narf-mode-map))
(keymaps (if (boundp 'keymaps) keymaps))
(states (if (boundp 'states) states '()))
(forms (if (boundp 'forms) forms))
(state-map '(("n" . normal)
("v" . visual)
("i" . insert)
("e" . emacs)
("o" . operator)
("m" . motion)
("r" . replace)
("I" . iedit))))
(unless keymaps
(setq keymaps default-keymaps))
(while rest
(setq key (pop rest))
(message ">>> KEY: %s" key)
(add-to-list
'forms
(cond ((eq key '-)) ; skip this
((listp key) ; it's a sub exp
(macroexpand `(@map ,@key)))
((keywordp key)
(pcase key
;; TODO: Data checks
(:leader (setq prefix (kbd (pop rest))) nil)
(:localleader (setq prefix (kbd (pop rest))) nil)
(:prefix (setq prefix (kbd (pop rest)))
(if (= i 0) (setq first-set `(:prefix . ,prefix)))
nil)
(:map (setq keymaps (-list (pop rest)))
(if (= i 0) (setq first-set `(:map . ,keymaps)))
nil)
(:unset (prog1 `(@map ,(kbd (pop rest)) nil)))
(:after (prog1 `(@after ,(pop rest) ,(macroexp-progn `(@map ,@rest))) (setq rest '())))
(:when (prog1 `(when ,(pop rest) ,(macroexp-progn `(@map ,@rest))) (setq rest '())))
(:unless (prog1 `(unless ,(pop rest) ,(macroexp-progn `(@map ,@rest))) (setq rest '())))
(otherwise ; might be a state prefix
(mapc (lambda (letter)
(when (assoc letter state-map)
(add-to-list 'states (cdr (assoc letter state-map)))))
(s-split "" (substring (symbol-name key) 1) t)) nil)))
;; It's a key-def pair
((or (stringp key)
(characterp key)
(vectorp key))
(when (stringp key)
(setq key (kbd key)))
(when prefix
(cond ((vectorp key)
(setq key (vconcat prefix key)))
(t
(setq key (concat prefix key)))))
(unless (car rest)
(user-error "Map has no definition for %s" key))
(setq def (pop rest))
(let ((first-key (car first-set))
(first-value (cdr first-set))
out-forms)
(dolist (keymap keymaps)
(if (not states)
(add-to-list 'out-forms `(define-key ,keymap ,key ,def) t)
(dolist (state states)
(add-to-list 'out-forms `(define-key (evil-get-auxiliary-keymap ,keymap ,state t) ,key ,def) t))))
(setq prefix (if (eq first-key :prefix) first-value))
(setq keymaps (if (eq first-key :map) first-value default-keymaps))
(setq states '())
out-forms))
(t (user-error "" key)))
t)
(cl-incf i))
`(progn ,@(apply #'nconc (delete nil (delete (list nil) forms))))))
;; (defmacro @map (&rest keys)
;; "A minimalistic and evil-centric way of binding keys. KEYS is
;;made up of either:
;;
;;1. Any of the following keywords:
;;
;;:when CONDITION
;;:unless CONDITION
;;: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
;;
;;
;;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 defun))
;; (let* ((keymaps (-list map))
;; (states (-list in))
;; (forms '())
;; item def)
;; (while keys
;; (setq item (pop keys))
;; (cond ((keywordp item)
;; (let ((val (pop keys)))
;; (pcase item
;; (:after)
;; (:when)
;; (:unless)
;; (:keymap)
;; (:in)
;; (otherwise)
;; )
;; ))
;;
;; ((or (and (symbolp item)
;; (evil-state-p item))
;; (and (listp item)
;; (--all? (evil-state-p it) item)))
;; (setq states (-list item)))
;;
;; ;; item-definition pairs
;; ((consp item)
;; (let ((def (cdr item))
;; (item (car item)))
;; (message "k %s : d %s" item def)
;;
;; ;;(or (stringp item)
;; ;; (vectorp item)
;; ;; (characterp item))
;; ;;(unless items (signal 'bind-no-definition item))
;; ;;(setq def (pop items))
;; (when condition
;; ;; Process the item
;; (cond ((stringp item) (setq item (kbd item)))
;; ((characterp item) (setq item (string item))))
;; (when prefix
;; (setq item (if (vectorp item)
;; (vconcat prefix item)
;; (concat (kbd prefix) item))))
;; ;; Do the binding
;; `(,@(if (null states)
;; (push (mapcar
;; (lambda (keymap) `(define-key ,keymap ,item ,def)) keymaps)
;; forms)
;; (push (mapcar (lambda (state)
;; (mapcar (lambda (keymap)
;; `(define-key (evil-get-auxiliary-keymap ,keymap ',state t) ,item ,def))
;; keymaps))
;; states) forms))))))
;;
;; ;; fallback
;; (t (signal 'bind-invalid-key key)))
;; `(progn ,@forms))))
(defmacro @exmap (command func)
(evil-ex-define-cmd
,command
,(cond ((autoloadp (symbol-function `,func))
`(lambda () (interactive) (call-interactively ,func)))
((symbolp `,func) func)
(t (user-error "Command for %s is invalid" command)))))))
;; 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))
(defun narf|update-scratch-buffer-cwd () ; see core-editor.el
"Make sure scratch buffer is always 'in a project.'"
(let ((dir (narf-project-root)))
(with-current-buffer (get-buffer-create "*scratch*")
(cd dir))))
;;;; 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 ;;;;;;;;;;;;;;;;;;;;
(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))))
(provide 'core-defuns)
;;; core-defuns.el ends here

View file

@ -1,62 +1,193 @@
;;; 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 " ?"))
;;;; Editor behavior ;;;;;;;;;;;;;;;;
(setq-default
;; spaces instead of tabs
indent-tabs-mode nil
tab-always-indent t
tab-width 4
(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)
require-final-newline t
delete-trailing-lines 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)
fill-column 80
(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
;; Sane scroll settings
scroll-margin 5
scroll-conservatively 9999
scroll-preserve-screen-position t
(after "isearch" (diminish 'isearch-mode))
shift-select-mode nil
whitespace-style '(trailing face tabs tab-mark)
whitespace-display-mappings
'((tab-mark ?\t [?| ?\t] [?\\ ?\t])
(newline-mark 10 [36 10]))
truncate-lines t ; do not soft-wrap lines
truncate-partial-width-windows nil)
;; Modes 'n hooks ;;;;;;;;;;;;;;;;;;;
(@associate text-mode :match "/LICENSE[^/]*$")
(@associate sh-mode :match "zsh\\(env\\|rc\\)?$")
(@associate sh-mode :match "z\\(profile\\|login\\|logout\\)?$")
(@associate sh-mode :match "zsh/")
(@associate applescript-mode :match "\\.applescript$")
(@associate emacs-lisp-mode :match "Cask$")
(@associate emacs-lisp-mode :match "\\.el\\.gz$")
(@associate makefile-gmake-mode :match "/Makefile$")
(@associate nxml-mode :match "\\.plist$")
(@add-hook help-mode 'visual-line-mode)
(@add-hook python-mode 'electric-indent-local-mode)
(@add-hook emacs-lisp-mode 'turn-on-eldoc-mode)
(@add-hook eldoc-mode (diminish 'eldoc-mode " ?"))
(@add-hook makefile-mode 'narf|enable-tabs) ; Use normal tabs in makefiles
;; 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)
;; (@add-hook prog-mode (unless (bound-and-true-p hs-minor-mode)
;; (hs-minor-mode 1)
;; (diminish 'hs-minor-mode)))
(@add-hook find-file 'narf|update-scratch-buffer-cwd)
;; (add-hook 'before-save-hook 'delete-trailing-whitespace)
;; If file is oversized...
(@add-hook find-file (when (> (buffer-size) (* 1024 1024))
(setq buffer-read-only t)
(buffer-disable-undo)
(fundamental-mode)
(visual-line-mode)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (global-whitespace-mode 1) ; Show whitespace
(global-font-lock-mode t) ; Enable syntax highlighting for older emacs
(global-auto-revert-mode 1) ; revert buffers for changed files
(electric-indent-mode -1)
(winner-mode 1) ; window config undo/redo
;; 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 'narf|enable-minor-mode-maybe)
;; Plugins ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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)
:init (setq ace-jump-mode-scope 'window
ace-jump-mode-gray-background t)
:config
(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))))))
(use-package ace-link
:commands
(ace-link-info ace-link-help ace-link-compilation ace-link-custom ace-link-org)
:init
(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 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 emr
;; :commands (emr-initialize emr-show-refactor-menu emr-declare-command)
;; :bind (:map popup-menu-keymap [escape] 'keyboard-quit))
(use-package expand-region
:commands (er/expand-region er/contract-region er/mark-symbol er/mark-word))
(use-package goto-last-change :defer 3)
(use-package hl-todo
:commands hl-todo-mode
:init
(@add-hook prog-mode 'hl-todo-mode)
(defvar hl-todo-keyword-faces)
'(("\\(\\bTODO\\((.*)\\)?:?\\)" . "#cc9393")
("\\(\\bNOTE\\((.*)\\)?:?\\)" . "#d0bf8f")
("\\(\\bFIXME\\((.*)\\)?:?\\)" . "#cc9393")))
(use-package hideshow
:diminish hs-minor-mode
:init (@add-hook (prog-mode org-mode) 'hs-minor-mode))
(use-package rainbow-delimiters
:commands rainbow-delimiters-mode
:init (@add-hook (emacs-lisp-mode js2-mode scss-mode) 'rainbow-delimiters-mode)
:config (setq rainbow-delimiters-outermost-only-face-count 1))
(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 smartparens
:diminish smartparens-mode
:commands smartparens-global-mode
:init (@add-init-hook evil-insert-state-entry 'smartparens-global-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-autowrap-region nil ; let evil-surround handle this
sp-highlight-pair-overlay nil
sp-show-pair-delay 0)
(use-package smartparens-config)
;; 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))
@ -73,89 +204,19 @@
(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))))
(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
(use-package smex
:commands (smex smex-major-mode-commands smex-initialize smex-update)
:init (setq smex-save-file (! (expand-file-name "smex-items" TMP-DIR)))
:config
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
aw-scope 'frame
aw-background nil))
(smex-initialize)
(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))
;; 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))
(provide 'core-editor)

View file

@ -1,303 +1,261 @@
;;;; Eeeeeeevil ;;;;;;;;;;;;;;;;;;;;;;;;
;;; core-evil.el --- the root of all evil
(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 'show-paren-mode)
(@add-hook evil-insert-state-exit 'show-paren-mode-off)
(@add-hook evil-visual-state-entry 'show-paren-mode)
(@add-hook evil-visual-state-exit 'show-paren-mode-off)
(@add-hook evil-motion-state-entry 'show-paren-mode)
(@add-hook evil-motion-state-exit 'show-paren-mode-off)
(@add-hook evil-operator-state-entry 'show-paren-mode)
(@add-hook evil-operator-state-exit 'show-paren-mode-off)
;; 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 'evil-ex-nohighlight)
;; 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)))
(@add-hook undo-tree-mode (diminish 'undo-tree-mode))
;; Always ensure evil-shift-width is consistent with tab-width
(@add-hook evil-local-mode (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)))
(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
;; 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))))
;; 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))
(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
(evil-mode 1)
(evil-select-search-module 'evil-search-module 'evil-search)
(add-to-list 'evil-overriding-maps 'narf-mode-map)
;; 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))
(defadvice evil-ex-hl-do-update-highlight (around evil-ex-hl-shut-up activate)
"Silence 'Error running timer `evil-ex-hl-do-update-highlight': (error
\"Invalid use of `\\' in replacement text\") errors.
(add-to-list 'evil-overriding-maps '(narf-mode-map))
(evil-mode 1)
(evil-select-search-module 'evil-search-module 'evil-search)
See `https://bitbucket.org/lyro/evil/issue/527'"
(ignore-errors ad-do-it))
(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)
(term-mode . emacs)
(fundamental-mode . normal)
(help-mode . normal)
(message-mode . normal)
(compilation-mode . normal)))
(evil-set-initial-state `,(car mode-map) `,(cdr mode-map)))
;; 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)))
(progn ; evil plugins
(use-package evil-anzu)
;; 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))))
(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))
(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))))
(use-package evil-ex-registers
:commands (evil-get-spec-register
evil-ex-paste-from-register))
(progn ; evil plugins
(use-package evil-anzu)
(use-package evil-exchange
:commands evil-exchange
:config
(defadvice evil-force-normal-state (before evil-esc-quit-exchange activate)
"Remove `evil-exchange' overlays on ESC"
(when evil-exchange--overlays (evil-exchange-cancel))))
(lambda ()
(interactive)
(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-iedit-state
:functions (iedit-current-occurrence-string iedit-restrict-region)
:commands (evil-iedit-state evil-iedit-state/iedit-mode)
:config
(@map ; Don't interfere with evil-snipe
:I :unset "s"
:I :unset "S"
(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
:I "V" 'evil-visual-line
:I "C" 'evil-iedit-state/substitute ; instead of s/S
:I "za" 'iedit-toggle-unmatched-lines-visible
visual "SPC" (λ (if (iedit-current-occurrence-string)
(let ((current-prefix-arg '(4)))
(iedit-done)
(call-interactively 'iedit-mode)
(save-excursion (iedit-restrict-region (region-beginning) (region-end)))
(evil-previous-line))
(call-interactively 'evil-ret))))))
:v "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-indent-textobject
:commands (evil-indent-i-indent
evil-indent-a-indent
evil-indent-a-indent-lines)
:init
(@map :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-search-highlight-persist
:config (global-evil-search-highlight-persist t))
(use-package evil-jumper
:init
(setq evil-jumper-file (! (expand-file-name "jumplist" narf-temp-dir))
evil-jumper-auto-center t
evil-jumper-auto-save-interval 3600))
(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-matchit
:commands (evilmi-jump-items global-evil-matchit-mode)
:config (global-evil-matchit-mode 1))
(use-package evil-ex-registers
:commands (evil-get-spec-register
evil-ex-paste-from-register))
(use-package evil-numbers
:commands (evil-numbers/inc-at-pt
evil-numbers/dec-at-pt))
(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)))
(use-package evil-search-highlight-persist
:config (global-evil-search-highlight-persist t))
;; 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)))))
(use-package evil-snipe
:diminish evil-snipe-mode
:commands (evil-snipe-s evil-snipe-S
evil-snipe-x evil-snipe-X
evil-snipe-f evil-snipe-F
evil-snipe-t evil-snipe-T)
:init
(setq-default
evil-snipe-smart-case t
evil-snipe-scope 'line
evil-snipe-repeat-scope 'buffer
evil-snipe-override-evil-repeat-keys nil
evil-snipe-symbol-groups '((?\[ "[[{(]")
(?\] "[]})]")))
:config
(evil-snipe-mode 1)
(evil-snipe-override-mode 1))
(global-evil-surround-mode 1)
(use-package evil-space
:diminish (evil-space-mode . "_")
:config
(progn
(add-to-list 'evil-overriding-maps 'evil-space-mode-map)
(push '(?\C-\[ . ("" . "")) evil-surround-pairs-alist)))
(evil-space-setup "/" "n" "N")
(evil-space-setup "?" "N" "n")
(use-package evil-numbers
:commands (evil-numbers/inc-at-pt
evil-numbers/dec-at-pt))
(@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)))
(use-package evil-matchit
:commands (evilmi-jump-items global-evil-matchit-mode)
:config (global-evil-matchit-mode 1))
(@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)))
(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))
(@after evil-visualstar
(let ((map (evil-get-auxiliary-keymap evil-visualstar-mode-map 'visual)))
(evil-space-setup "*" "n" "N" map)
(evil-space-setup "#" "n" "N" map)))
(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))
(evil-space-mode)))
(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-surround
:commands (global-evil-surround-mode
evil-surround-edit
evil-Surround-edit
evil-surround-region)
:config
(global-evil-surround-mode 1)
(use-package evil-visualstar
:commands (global-evil-visualstar-mode
evil-visualstar/begin-search-forward
evil-visualstar/begin-search-backward)
:config
(global-evil-visualstar-mode 1))
;; 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)))))
(use-package evil-snipe
:diminish evil-snipe-mode
:init
(setq evil-snipe-smart-case t
evil-snipe-scope 'line
evil-snipe-repeat-scope 'buffer
evil-snipe-symbol-groups '((?\[ "[[{(]")
(?\] "[]})]")))
:config
(progn
(evil-snipe-mode 1)
(evil-snipe-override-mode 1)
(push '(?\\ . evil-surround-escaped) evil-surround-pairs-alist))
(bind motion :map evil-snipe-mode-map
"C-;" 'evil-snipe-repeat
"C-," 'evil-snipe-repeat-reverse)))
(use-package evil-visualstar
:commands (global-evil-visualstar-mode
evil-visualstar/begin-search
evil-visualstar/begin-search-forward
evil-visualstar/begin-search-backward)
:config
;; 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)
(use-package evil-space
:diminish (evil-space-mode . "_")
:config
(progn
(evil-space-mode 1)
(global-evil-visualstar-mode 1)))
(evil-space-setup "/" "n" "N")
(evil-space-setup "?" "n" "N")
(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))))
(after "evil-snipe"
(evil-space-setup evil-snipe-f evil-snipe-repeat evil-snipe-repeat-reverse)
(evil-space-setup evil-snipe-F evil-snipe-repeat evil-snipe-repeat-reverse)
(evil-space-setup evil-snipe-t evil-snipe-repeat evil-snipe-repeat-reverse)
(evil-space-setup evil-snipe-T evil-snipe-repeat evil-snipe-repeat-reverse)
(evil-space-setup evil-snipe-s evil-snipe-repeat evil-snipe-repeat-reverse)
(evil-space-setup evil-snipe-S evil-snipe-repeat evil-snipe-repeat-reverse))
;; 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))
(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 isearch ; Restore vimmish ex-mode keymaps to isearch
;; Hide keystroke display while isearch is active
(@add-hook isearch-mode (setq echo-keystrokes 0))
(@add-hook isearch-mode-end (setq echo-keystrokes 0.02))
(@map :map isearch-mode-map
:unset "C-r"
(after "evil-visualstar"
(let ((map (evil-get-auxiliary-keymap evil-visualstar-mode-map 'visual)))
(evil-space-setup "*" "*" "#" map)
(evil-space-setup "#" "#" "*" map))))))
"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
(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)))))
"C-w" 'narf:isearch-delete-word
"C-u" 'narf:isearch-delete-line
"M-v" 'narf:isearch-paste-from-clipboard))))
(provide 'core-evil)

View file

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

9
core/core-os-linux.el Normal file
View file

@ -0,0 +1,9 @@
;;; core-os-linux.el --- Debian-specific settings
(defun narf-open-with (&optional app-name path)
(interactive)
(error "Not yet implemented"))
(provide 'core-os-linux)
;;; core-os-linux.el ends here

View file

@ -1,4 +1,4 @@
;; Mac-specific settings
;;; core-os-osx.el --- Mac-specific settings
;; Use a shared clipboard
(setq x-select-enable-clipboard t
@ -13,18 +13,15 @@
;; fix emacs PATH on OSX (GUI only)
(when window-system
(setenv "SHELL" "/usr/local/bin/zsh")
(setenv "EMACS" "1")
(setenv "EMACS" "1") ; make sure the world knows
(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))
(setq exec-path (! (require 'exec-path-from-shell)
(exec-path-from-shell-initialize)
exec-path)))
(narf/init-exec-path))
;; OSX Related Plugins ;;;;;;;;;;;;;;;;;
(use-package applescript-mode
:mode "\\.applescript$")
(use-package applescript-mode :mode "\\.applescript$")
(use-package dash-at-point
:commands (dash-at-point dash-at-point-with-docset)
@ -32,7 +29,9 @@
(add-to-list 'dash-at-point-mode-alist
'(java-mode . "java,droid,javafx,grails,groovy,playjava,spring,cvj,processing,javadoc")))
(after "evil"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(@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
@ -42,7 +41,7 @@
(unless (featurep 'ns) ad-do-it))))
;; Send current file to OSX apps
(defun narf:osx-open-with (&optional app-name path)
(defun narf-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 "'")))
@ -50,5 +49,5 @@
(shell-command command)))
(provide 'core-osx)
;;; core-osx.el ends here
(provide 'core-os-osx)
;;; core-os-osx.el ends here

9
core/core-os-win32.el Normal file
View file

@ -0,0 +1,9 @@
;;; core-os-win32.el --- Windows-specific settings
(defun narf-open-with (&optional app-name path)
(interactive)
(error "Not yet implemented"))
(provide 'core-os-win32)
;;; core-os-win32.el ends here

View file

@ -1,145 +0,0 @@
(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

View file

@ -1,6 +1,9 @@
;;; core-ui.el -- User interface layout & behavior
;;; core-ui.el --- interface settings
(when (fboundp 'fringe-mode) (fringe-mode '(2 . 8)))
(when window-system ; more informative window title
(setq frame-title-format '(buffer-file-name "%f" ("%b"))))
;; theme and GUI elements are loaded in init.el early
(setq show-paren-delay 0)
@ -18,199 +21,180 @@
(setq-default
cursor-in-non-selected-windows nil
visible-bell nil ; silence of the bells
use-dialog-box nil ; avoid GUI
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)
fringes-outside-margins t) ; fringes on the other side of line numbers
(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
(@add-hook after-init
(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)))
;;;; Line numbers ;;;;;;;;;;;;;;;;;;;;;;
(use-package nlinum
:defines nlinum--width
:commands nlinum-mode
:preface
(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)
(defvar narf--hl-nlinum-overlay nil)
(defvar narf--hl-nlinum-line nil)
(defvar nlinum-format " %4d ")
:init
;; Highlight line number
(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-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 text-mode 'narf|nlinum-enable)
(@add-hook prog-mode 'narf|nlinum-enable)
(@add-hook org-mode 'narf|nlinum-disable)
;; Preset width nlinum
(@add-hook nlinum-mode
(setq nlinum--width (length (number-to-string (count-lines (point-min) (point-max)))))))
;;;; Modeline ;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package smart-mode-line
:init (setq-default
sml/no-confirm-load-theme t
sml/mode-width 'full
sml/extra-filler -7
sml/show-remote nil
sml/encoding-format nil
sml/modified-char "*"
sml/numbers-separator "/"
sml/line-number-format "%3l"
sml/col-number-format "%2c"
sml/pre-modes-separator " : "
sml/pre-minor-modes-separator " "
sml/pos-minor-modes-separator ": "
sml/replacer-regexp-list '(("^~/Dropbox/Projects/" "PROJECTS:")
("^~/.emacs.d/" "EMACS.D:")
("^~/Dropbox/notes/" "NOTES:")
("^/usr/local/Cellar/" "HOMEBREW:"))
mode-line-misc-info
'((which-func-mode ("" which-func-format ""))
(global-mode-string ("" global-mode-string ""))))
: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))
;; Hide evil state indicator
(after "evil" (setq evil-mode-line-format nil))
(sml/setup)
(sml/apply-theme 'respectful)
(setq-default mode-line-misc-info
'((which-func-mode ("" which-func-format ""))
(global-mode-string ("" global-mode-string ""))))
;; 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))
(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)))))
(sml/setup)
(sml/apply-theme 'respectful)
;; Remove extra spaces in format lists
(pop mode-line-modes)
(nbutlast mode-line-modes)
;; 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))
;; 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")))))
;; 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))
(@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))
(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
))))
;; 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)

44
core/core-vars.el Normal file
View file

@ -0,0 +1,44 @@
;;; core-vars.el --- narf emacs configuration
(defgroup narf nil
"Narf variables."
:group 'convenience
:prefix 'narf-)
(defcustom narf-leader-key "," "The prefix for leader keybindings."
:group 'narf :type 'string)
(defcustom narf-localleader-key "\\" "The prefix for localleader keybindings."
:group 'narf)
;; Buffers/Files ;;;;;;;;;;;;;;;;;;;;;;;
(defconst narf--splash-buffer-name "*narf*")
(defvar narf-ignore-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*"
"*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*"
"*Buffer List*" "*Ibuffer*" "*esh command on file*")
"List of buffer names to ignore when using `switch-to-next-buffer',
`switch-to-previous-buffer', `winner-undo', `winner-redo', or
`narf:cleanup-buffers'")
(defvar narf-ignore-buffers '("*Completions*" "*Compile-Log*" "*inferior-lisp*"
"*Fuzzy Completions*" "*Apropos*" "*Help*" "*cvs*"
"*Buffer List*" "*Ibuffer*" "*esh command on file*")
"List of buffer names to ignore when using `switch-to-next-buffer',
`switch-to-previous-buffer', `winner-undo', `winner-redo', or
`narf:cleanup-buffers'")
(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.")
(provide 'core-vars)
;;; core-vars.el ends here

View file

@ -1,319 +1,234 @@
;;; The core of Narfy Emacs
;;; core.el --- The heart of the beast
;;
;;; Naming Conventions
;;; Naming conventions:
;;
;; narf/* public defun/variable
;; narf--* private defun/variable
;; narf|* hook defuns
;; narf:* interactive/keybind defuns
;; :* ex commands
;; narf-* A public variable/constant or function
;; narf--* A private variable or function (non-interactive)
;; narf/* An autoloaded interactive function
;; narf:* An ex command
;; narf|* A hook
;; @* Macro call
;;
;;; Bootstrap:
(setq package-enable-at-startup nil
debug-on-quit DEBUG-MODE)
(cd "~") ; instead of /
(require 'core-splash)
(fset '! 'eval-when-compile)
;; 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
(defconst narf-emacs-dir user-emacs-directory)
(defconst narf-core-dir (! (concat narf-emacs-dir "core/")))
(defconst narf-modules-dir (! (concat narf-emacs-dir "modules/")))
(defconst narf-contrib-dir (! (concat narf-emacs-dir "contrib/")))
(defconst narf-private-dir (! (concat narf-emacs-dir "private/")))
(defconst narf-elpa-dir (! (concat narf-emacs-dir ".cask/" emacs-version "/elpa/")))
(defconst narf-temp-dir (concat narf-private-dir "cache/" (system-name) "/"))
(defconst narf-snippet-dirs (! (list (concat narf-private-dir "snippets/")
(concat narf-private-dir "templates/"))))
(! (defun --subdirs (path)
(let ((result '())
(paths (ignore-errors (directory-files path t "^[^.]" t))))
(dolist (file paths)
(when (file-directory-p file)
(add-to-list 'result file)))
result)))
;; Scan various folders to populate the load-dirs
(setq custom-theme-load-path
(! (append (--subdirs (concat narf-private-dir "themes/"))
custom-theme-load-path)))
(setq load-path
(! (setq load-path (append (list narf-core-dir narf-contrib-dir narf-modules-dir narf-private-dir)
(list (concat narf-core-dir "defuns"))
load-path
(--subdirs narf-contrib-dir)
(--subdirs narf-contrib-dir)))
(require 'cask)
(cask-initialize)
load-path))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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)))
;; (require 'benchmark) ; records load times in `require-times'; also see `list-times'
(require 'autoloads nil t) ; generate autoloads with `make autoloads`
(require 'core-vars)
(require 'core-defuns)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(! (require 's)
(require 'dash)
(require 'f)
(add-to-list 'load-path (concat narf-core-dir "macros/"))
(setq use-package-verbose narf-debug-mode)
;; (setq use-package-expand-minimally (not narf-debug-mode))
(require 'use-package)
(defun use-package--add-keyword (keyword after)
(setq use-package-keywords
(-insert-at (-find-index (lambda (key) (eq key after)) use-package-keywords)
keyword use-package-keywords)))
(progn ; add :after to use-package
(use-package--add-keyword :after :load-path)
(setq use-package-keywords
(-insert-at (--find-index (eq it :load-path) use-package-keywords)
:after use-package-keywords))
(defalias 'use-package-normalize/:after 'use-package-normalize-symlist)
(defun use-package-handler/:after (name-symbol keyword arg rest state)
(let ((body (use-package-process-keywords name-symbol rest state)))
(if (null arg)
body
(use-package-concat
(use-package-process-keywords name-symbol
(use-package-sort-keywords (use-package-plist-maybe-put rest :defer t)) state)
(apply #'nconc
(mapcar (lambda (feature)
`(,(macroexpand `(@after ,feature (require ',name-symbol)))))
(delete-dups arg))))))))
(progn ; add :map for in-house key binding macro
(use-package--add-keyword :map :bind)
(defalias 'use-package-normalize/:map 'use-package-normalize-forms)
;; TODO: Write :map
(defun use-package-handler/:map (name-symbol keyword arg rest state)
(use-package-process-keywords name-symbol rest state))
)
)
(require 'diminish)
;; Emacs configuration ;;;;;;;;;;;;;;;;;
(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
(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
(fset 'yes-or-no-p 'y-or-n-p) ; y/n instead of yes/no
;; avoid garbage collection (default is 400k)
(setq-default
gc-cons-threshold 20000000
confirm-kill-emacs nil
;; minibufferception? Yay!
enable-recursive-minibuffers t)
confirm-kill-emacs (lambda (prompt) (y-or-n-p ">> Gee, I dunno Brain... Are you sure?"))
;; Show me those keystrokes
(setq echo-keystrokes 0.02
gc-cons-threshold 20000000 ; avoid garbage collection
enable-recursive-minibuffers t ; minibufferception
echo-keystrokes 0.02 ; show me those keystrokes
ring-bell-function 'ignore ; silence of the bells!
ring-bell-function 'ignore
inhibit-startup-screen t ; don't show emacs start screen
inhibit-startup-echo-area-message "hlissner" ; username shuts up emacs
initial-major-mode 'text-mode ; initial scratch buffer mode
initial-scratch-message nil
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
compilation-always-kill t
compilation-ask-about-save nil
compilation-scroll-output t
initial-major-mode 'text-mode ; initial scratch buffer mode
initial-scratch-message nil
sentence-end-double-space nil ; sentences end with periods. period.
compilation-always-kill t
compilation-ask-about-save nil
compilation-scroll-output t
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
sentence-end-double-space nil ; sentences end with periods. Period.
;; Don't save clipboard contents into kill-ring before replacing them
save-interprogram-paste-before-kill nil
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 let the cursor go into minibuffer prompt
;; from Xah Lee: http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html
minibuffer-prompt-properties
'(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)
;; Don't save clipboard contents into kill-ring before replacing them
(setq save-interprogram-paste-before-kill nil)
;; remove annoying ellipsis when printing sexp in message buffer
eval-expression-print-length nil
eval-expression-print-level 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))
history-length 1000
;; remove annoying ellipsis when printing sexp in message buffer
(setq eval-expression-print-length nil
eval-expression-print-level nil)
;; Backups ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Disable all backups (that's what git/dropbox are for)
bookmark-save-flag t
bookmark-default-file (! (concat narf-temp-dir "bookmarks"))
auto-save-default nil
auto-save-list-file-name (! (concat narf-temp-dir "autosave"))
;; In case I want to reactivate backup files
make-backup-files nil
create-lockfiles nil
backup-directory-alist `((".*" . ,(! (concat narf-temp-dir "backup/"))))
;; Remember undo history
undo-tree-auto-save-history t
undo-tree-history-directory-alist `(("." . ,(! (concat narf-temp-dir "undo/")))))
;; Make any folders needed
(! (dolist (file '("" "undo" "backup"))
(let ((path (concat narf-temp-dir file)))
(unless (file-exists-p path)
(make-directory path t)))))
;; 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))))
(require 'saveplace)
(setq save-place-file (! (concat narf-temp-dir "saveplace")))
(@add-hook find-file (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)))
(require 'savehist)
(setq savehist-file (! (concat narf-temp-dir "savehist"))
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)))
(require 'recentf)
(setq recentf-save-file (! (concat narf-temp-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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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 help-fns+ ; Improved help commands
:commands (describe-buffer describe-command describe-file
describe-keymap describe-option describe-option-of-type))
(use-package popwin :config (popwin-mode 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(cond (IS-MAC (require 'core-os-osx))
(IS-LINUX (require 'core-os-linux))
(IS-WINDOWS (require 'core-os-win32)))
(require 'core-ui)
(require 'core-evil)
;; (require 'core-editor)
;; (require 'core-completion)
;; (require 'core-syntax-checker)
;; (require 'core-snippets)
;; (require 'core-templates)
;; (require 'core-project)
;; (require 'core-vcs)
;; (require 'core-sessions)
;; (require 'core-quickrun)
;; (@add-hook after-init
;; (use-package my-bindings)
;; (use-package my-commands))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package server :config (unless (server-running-p) (server-start)))
(provide 'core)

View file

@ -1,289 +0,0 @@
;; 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

View file

@ -1,83 +0,0 @@
;;;; 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 (if (> lines 25) 25 (1+ 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,30 +0,0 @@
;; Misc Defuns ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;###autoload
(defun what-face (pos)
"Tells you the name of the face (point) is on."
(interactive "d")
(let ((face (or (get-char-property (point) 'read-face-name)
(get-char-property (point) 'face))))
(if face (message "Face: %s" face) (message "No face at %d" pos))))
;;;###autoload
(defun what-col ()
(interactive)
(message "Column %d" (current-column)))
;;;###autoload
(defun what-bindings (key)
(list
(minor-mode-key-binding key)
(local-key-binding key)
(global-key-binding key)))
;;;###autoload (autoload 'narf::echo "defuns-debug")
(evil-define-command narf::echo (message)
"Display MSG in echo-area without logging it in *Messages* buffer."
(interactive "<a>")
(let (message-log-max)
(message "%s" message)))
(provide 'defuns-debug)

View file

@ -1,126 +0,0 @@
;;;; 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

View file

@ -1,37 +0,0 @@
;;; 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

View file

@ -1,39 +0,0 @@
;;;###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

View file

@ -1,92 +0,0 @@
;;;###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

View file

@ -1,106 +0,0 @@
;;;###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,135 +0,0 @@
;;;###autoload
(defun narf--point-at-bol-non-blank()
(save-excursion (evil-first-non-blank) (point)))
;;;###autoload
(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 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)
(let ((empty-line (sp-point-in-blank-line)))
(evil-delete (point-at-bol) (point))
(if (not empty-line)
(indent-according-to-mode))))
;;;###autoload
(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 (narf--point-at-bol-non-blank))
(point (point)))
(if (= point-at-bol point)
(evil-move-beginning-of-line)
(unless (= (point-at-bol) point)
(evil-first-non-blank))))))
;;;###autoload
(defun 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 " ^<*" (narf--point-at-bol-non-blank))
(if (eq old-point (point)) ;
(evil-move-end-of-line))))))
;; Mimic expandtab in vim
;;;###autoload
(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)
(cond ;; If in a string
((sp-point-in-string)
(call-interactively 'backward-delete-char-untabify))
;; If using tabs (or at bol), just delete normally
((or indent-tabs-mode
(= (point-at-bol) (point)))
(call-interactively 'backward-delete-char))
;; Delete up to the nearest tab column IF only whitespace between point
;; and bol.
((looking-back "^[\\t ]*" (point-at-bol))
(let ((movement (% (current-column) tab-width))
(p (point)))
(when (= movement 0)
(setq movement tab-width))
(save-match-data
(if (string-match "\\w*\\(\\s-+\\)$"
(buffer-substring-no-properties (- p movement) p))
(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))))
;;;###autoload
(defun narf:dumb-indent ()
"Inserts a tab character (or spaces x tab-width). Checks if the
auto-complete window is open."
(interactive)
(if indent-tabs-mode
(insert "\t")
(let* ((movement (% (current-column) tab-width))
(spaces (if (zerop movement) tab-width (- tab-width movement))))
(insert (s-repeat spaces " ")))))
;;;###autoload
(defun 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 (narf/surrounded-p)
(progn (call-interactively 'self-insert-command)
(save-excursion (call-interactively 'self-insert-command)))
(call-interactively 'self-insert-command)))
;;;###autoload
(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
`narf:backward-delete-whitespace-to-column' otherwise."
(interactive)
(save-match-data
(if (narf/surrounded-p)
(let ((whitespace-match (match-string 1)))
(cond ((not whitespace-match)
(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))))
(narf:backward-delete-whitespace-to-column))))
;;;###autoload
(defun narf:newline-and-indent ()
(interactive)
(cond
((sp-point-in-string)
(newline))
((sp-point-in-comment)
(cond ((eq major-mode 'js2-mode)
(js2-line-break))
((-contains? '(java-mode php-mode) major-mode)
(c-indent-new-comment-line))
((-contains? '(c-mode c++-mode objc-mode css-mode scss-mode) major-mode)
(newline-and-indent)
(insert "* ")
(indent-according-to-mode))
(t (indent-new-comment-line))))
(t (newline-and-indent))))
(provide 'defuns-text)
;;; defuns-text.el ends here

View file

@ -1,27 +0,0 @@
(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)))

View file

@ -1,299 +0,0 @@
(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 1))
`(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

View file

@ -0,0 +1,32 @@
;;; defuns-compile.el
(! (require 'f)
(setq narf-important-dirs (append (list narf-core-dir narf-modules-dir narf-contrib-dir narf-private-dir)
(f-directories narf-core-dir nil t)
(f-directories narf-modules-dir nil t)
(f-directories narf-contrib-dir nil t))))
;;;###autoload (autoload 'narf:byte-compile "defuns-compile")
(evil-define-command narf:byte-compile (&optional bang)
:repeat nil
(interactive "<!>")
(when emacs-lisp-mode
(if (not bang)
(progn
(byte-recompile-file (! (f-expand "core-defuns.el" narf-core-dir)) t 0)
(byte-recompile-file (buffer-file-name) t 0))
(byte-recompile-file (! (f-expand "init.el" narf-emacs-dir)) nil 0)
(byte-recompile-file (! (f-expand "startup.el" narf-emacs-dir)) nil 0)
(dolist (dir (! narf-impotant-dirs))
(byte-recompile-directory dir 0 nil)))))
;;;###autoload (autoload 'narf:autoload-compile "defuns-compile")
(evil-define-command narf:autoload-compile (&optional bang)
:repeat nil
(interactive "<!>")
(defvar generated-autoload-file (! (f-expand "autoloads.el" narf-core-dir)))
(apply #'update-directory-autoloads (! narf-impotant-dirs)))
(provide 'defuns-compile)
;;; defuns-compile.el ends here

View file

@ -0,0 +1,33 @@
;;; defuns-evil.el
;;;###autoload (autoload 'narf:evil-open-folds "defuns-evil")
(evil-define-command narf/evil-open-folds (count)
"Instead of `evil-open-folds'. Accepts COUNT for dictating fold level."
(interactive "P")
(if count (hs-hide-level count) (evil-open-folds)))
;;;###autoload (autoload 'narf:evil-open-folds "defuns-evil")
(evil-define-command narf/evil-close-folds (count)
"Instead of `evil-close-folds'. Accepts COUNT for dictating fold level."
(interactive "P")
(if count (hs-hide-level count) (evil-close-folds)))
;;;; Ace Jump ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; https://github.com/winterTTr/ace-jump-mode/issues/23
;;;###autoload (autoload 'narf:evil-ace-jump-two-chars "defuns-evil")
(evil-define-motion narf/evil-ace-jump-two-chars (count)
:type exclusive
:repeat abort
(evil-without-repeat
(evil-enclose-ace-jump-for-motion
(call-interactively 'ace-jump-two-chars-mode))))
;;;###autoload
(defun narf/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)))
(provide 'defuns-evil)
;;; defuns-evil.el ends here

View file

@ -0,0 +1,34 @@
;;;###autoload
(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)))
;;;###autoload
(defun narf/isearch-delete-line ()
(interactive)
(let ((num (length isearch-string)))
(dotimes (i num) (isearch-pop-state))
(isearch-update)))
;;;###autoload
(defun narf/isearch-paste-from-register (reg)
(interactive)
(let ((str (evil-get-register reg t)))
(when (> (length str) 0)
(isearch-yank-string str))))
;;;###autoload
(defun narf/isearch-paste-from-clipboard ()
(interactive)
(narf:isearch-paste-from-register ?+))
(provide 'defuns-isearch)
;;; defuns-isearch.el ends here

View file

@ -0,0 +1,12 @@
;;; defuns-nlinum.el
;;;###autoload
(defun narf/nlinum-toggle ()
(interactive)
(if nlinum-mode
(narf|nlinum-disable)
(narf|nlinum-enable)))
(provide 'defuns-nlinum)
;;; defuns-nlinum.el ends here

View file

@ -0,0 +1,10 @@
;;;###autoload
(defun narf/popwin-toggle ()
(interactive)
(if (popwin:popup-window-live-p)
(popwin:close-popup-window)
(popwin:popup-last-buffer)))
(provide 'defuns-popwin)
;;; defuns-popwin.el ends here

View file

@ -0,0 +1,4 @@
(provide 'macros-company)
;;; macros-company.el ends here

View file

@ -0,0 +1,14 @@
;;; macros-popwin.el
;;;###autoload
(defmacro @popwin-register (&rest forms)
"Register a rule for popwin. See `popwin:special-display-config'.
Example:
(@popwin-register (\"^\\*Flycheck.*\\*$\" :regexp t :position bottom :height 0.25 :noselect t))"
(declare (indent defun))
`(push (,@forms) form))
(provide 'macros-popwin)
;;; macros-popwin.el ends here

View file

@ -1,39 +0,0 @@
(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 ELPA-DIR t "^[^.]" t)
(directory-files CONTRIB-DIR t "^[^.]" t)))
(when (file-directory-p dir)
(push dir paths)))
`(setq load-path ',(append (list CORE-DIR CONTRIB-DIR MODULES-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