diff --git a/core/core-evil.el b/core/core-evil.el index 5a28885f4..39e6d673c 100644 --- a/core/core-evil.el +++ b/core/core-evil.el @@ -5,7 +5,7 @@ :config (progn (setq evil-want-visual-char-semi-exclusive t - evil-search-module 'isearch + evil-search-module 'evil-search evil-search-wrap nil evil-magic 'magic evil-want-C-u-scroll t ; enable C-u for scrolling @@ -22,6 +22,7 @@ ;; Always ensure evil-shift-width is consistent with tab-width (add-hook! 'after-change-major-mode-hook (setq evil-shift-width tab-width)) + (add-hook 'prog-mode-hook 'hs-minor-mode) ;; highlight matching delimiters where it's important (defun show-paren-mode-off () (show-paren-mode -1)) @@ -49,21 +50,12 @@ (use-package evil-ex-registers) (use-package evil-indent-textobject) ; vii/vai/vaI (use-package evil-numbers) - (use-package evil-matchit :config (global-evil-matchit-mode 1)) - (use-package evil-surround :config (global-evil-surround-mode 1)) - (use-package evil-visualstar :config (global-evil-visualstar-mode 1)) - - (use-package evil-commentary - :config (evil-commentary-mode 1)) - - ;; (use-package evil-nerd-commenter - ;; :commands (evilnc-comment-operator - ;; evilnc-comment-or-uncomment-lines - ;; evilnc-toggle-invert-comment-line-by-line - ;; evilnc-comment-or-uncomment-paragraphs - ;; evilnc-quick-comment-or-uncomment-to-the-line - ;; evilnc-copy-and-comment-lines) - ;; :init (setq evilnc-hotkey-comment-operator "gc")) + (use-package evil-matchit :config (global-evil-matchit-mode 1)) + (use-package evil-surround :config (global-evil-surround-mode 1)) + (use-package evil-commentary :config (evil-commentary-mode 1)) + (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" my-tmp-dir)) @@ -79,17 +71,23 @@ (when evil-exchange--overlays (evil-exchange-cancel)))) - (use-package evil-search-highlight-persist + (use-package evil-visualstar :config (progn - (global-evil-search-highlight-persist t) - (set-face-attribute 'evil-search-highlight-persist-highlight-face nil :inherit 'evil-ex-lazy-highlight))) + ;; I cut this down because the original visualstar wouldn't remember + ;; the last search if evil-search-module was 'evil-search. + (defun evil-visualstar/begin-search (beg end direction) + (when (evil-visual-state-p) + (evil-exit-visual-state) + (let ((selection (regexp-quote (buffer-substring-no-properties beg end)))) + (setq isearch-forward direction) + (evil-search selection direction t)))) + (global-evil-visualstar-mode 1))) (use-package evil-snipe :config (progn (global-evil-snipe-mode +1) - (setq evil-snipe-smart-case t) (setq evil-snipe-override-evil t) (setq evil-snipe-scope 'line) @@ -117,25 +115,20 @@ (progn ; evil hacks (defadvice evil-force-normal-state (before evil-esc-quit activate) (shut-up (evil-search-highlight-persist-remove-all) ; turn off highlights + (evil-ex-nohighlight) ;; Exit minibuffer is alive (if (minibuffer-window-active-p (minibuffer-window)) (my--minibuffer-quit)))) ;; Popwin: close popup window, if any - (after "popwin" - (defadvice evil-force-normal-state (before evil-esc-quit-popwin activate) - (shut-up (popwin:close-popup-window)))) + (defadvice evil-force-normal-state (before evil-esc-quit-popwin activate) + (shut-up (popwin:close-popup-window))) ;; Jump to new splits (defadvice evil-window-split (after evil-window-split-jump activate) (evil-window-down 1)) (defadvice evil-window-vsplit (after evil-window-vsplit-jump activate) - (evil-window-right 1)) - - (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))) + (evil-window-right 1))) (progn ; extensions (defun evil-visual-line-state-p () @@ -195,7 +188,7 @@ (evil-define-command my:kill-buffers (&optional bang) :repeat nil (interactive "") - (if (and bang (projectile-project-p)) + (if (and (not bang) (projectile-project-p)) (projectile-kill-buffers) (mapc 'kill-buffer (buffer-list))) (delete-other-windows)) diff --git a/core/core-osx.el b/core/core-osx.el index e844f11af..4d2c70a9c 100644 --- a/core/core-osx.el +++ b/core/core-osx.el @@ -27,8 +27,9 @@ ;; Send current file to OSX apps (defun my-open-with (&optional app-name path) (interactive) - (let ((app-name (if app-name (concat "-p " app-name))) + (let ((app-name (if app-name (concat "-a " app-name))) (path (or path (if (eq major-mode 'dired-mode) (dired-get-file-for-visit) (buffer-file-name))))) + (message "Trying: %s" (concat "open " app-name " " (shell-quote-argument path))) (shell-command (concat "open " app-name " " (shell-quote-argument path))))) diff --git a/core/core-ui.el b/core/core-ui.el index 56988d192..0e04caba2 100644 --- a/core/core-ui.el +++ b/core/core-ui.el @@ -24,7 +24,7 @@ (setq-default visible-bell nil) ; silence of the bells (setq-default use-dialog-box nil) ; avoid GUI (setq-default redisplay-dont-pause t) -(setq window-combination-resize t) +;; (setq window-combination-resize nil) ;; do not soft-wrap lines (setq-default truncate-lines t) @@ -73,7 +73,9 @@ " wg" " ~" " s-/" - " yas" + ;; " yas" + " emr" + " Refactor" ) "\\|")) :init (progn diff --git a/core/core.el b/core/core.el index d61976dd2..7e8991656 100644 --- a/core/core.el +++ b/core/core.el @@ -102,7 +102,7 @@ (keyboard-translate ?\C-i ?\H-i) ;; Save clipboard contents into kill-ring before replace them - (setq save-interprogram-paste-before-kill t) + (setq save-interprogram-paste-before-kill nil) ;; don't let the cursor go into minibuffer prompt ;; Tip taken from Xah Lee: http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html @@ -132,7 +132,12 @@ ;; Save history across sessions (require 'savehist) (setq savehist-file (concat my-tmp-dir "savehist") ; keep the home clean - savehist-additional-variables '(kill-ring mark-ring global-mark-ring search-ring regexp-search-ring extended-command-history) + savehist-additional-variables '(kill-ring + mark-ring + global-mark-ring + search-ring + regexp-search-ring + extended-command-history) history-length 1000) (savehist-mode 1) @@ -162,7 +167,6 @@ (setq-default tab-width 4) (setq require-final-newline t) - (setq delete-trailing-lines nil) (add-hook 'makefile-mode-hook 'indent-tabs-mode) ; Use normal tabs in makefiles @@ -184,9 +188,10 @@ determine if a directory is a project." (throw 'found path)))))) default-directory) default-directory)) - (defun project-has-files (&rest files) + (defun project-has-files (files &optional root) "Return non-nil if `file' exists in the project root." - (let ((root (project-root)) + (let ((root (or root (project-root))) + (files (if (listp files) files (list files))) found-p file) (while (and files (not found-p)) (setq file (pop files)) @@ -228,11 +233,15 @@ the checking happens for all pairs in auto-minor-mode-alist" (let* ((scratch-buffer (get-buffer-create "*scratch*")) (project-name (project-name)) (root (project-root))) + (mapc (lambda (b) + (if (string-match-p "\\*scratch\\* (.+)" (buffer-name b)) + (kill-buffer b))) + (buffer-list)) (save-window-excursion (switch-to-buffer scratch-buffer) (erase-buffer) (cd root) - (insert ";; Project: " project-name "\n\n")))) + (rename-buffer (format "*scratch* (%s)" project-name))))) (add-hook 'find-file-hook 'project-create-scratch-buffer) @@ -255,7 +264,26 @@ the checking happens for all pairs in auto-minor-mode-alist" (progn ; popwin config (popwin-mode 1) (setq popwin:popup-window-height 0.45) + ;; (setq display-buffer-function 'popwin:display-buffer) + (push '("\\`\\*helm.*?\\*\\'" :regexp t :position bottom :height 15) popwin:special-display-config) + + (push '("^\\*Flycheck.*\\*$" :regexp t :position bottom :height 0.25 :noselect t) popwin:special-display-config) + (push '(inf-enh-ruby-mode :position bottom :stick t) popwin:special-display-config) + (push '(snippet-mode :position bottom :stick t) popwin:special-display-config) + + (push '("*ansi-term*" :position bottom :height 0.45 :stick t) popwin:special-display-config) + (push '("*terminal*" :position bottom :height 0.45 :stick t) popwin:special-display-config) + (push '("*Async Shell Command*" :position bottom) popwin:special-display-config) + + (push '("* Regexp Explain *" :position top :height 0.35) popwin:special-display-config) + + (push '("*anaconda-doc*" :position bottom :height 15 :noselect t) popwin:special-display-config) + (push '("*anaconda-nav*" :position bottom :height 15 :stick t) popwin:special-display-config) + (push '("^\\*Python.+\\*$" :regexp t :position bottom :height 20 :noselect t) popwin:special-display-config) + + (push '(help-mode :height 0.5 :position bottom :stick t) popwin:special-display-config) + (push '(compilation-mode :height 0.5 :position bottom :noselect t) popwin:special-display-config) (push '(diff-mode :position bottom :stick t) popwin:special-display-config) (push '("*Backtrace*") popwin:special-display-config) (push '("*Warnings*") popwin:special-display-config) @@ -273,9 +301,9 @@ the checking happens for all pairs in auto-minor-mode-alist" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (cond (is-mac (require 'core-osx)) - (is-linux (require 'core-linux)) - (is-windows (require 'core-windows))) + (cond (is-mac (require 'core-osx)) + (is-linux (require 'core-linux)) + (is-windows (require 'core-windows))) (require 'server) (unless (server-running-p) (server-start))) diff --git a/core/defuns-buffers.el b/core/defuns-buffers.el index c11f0f2a8..32690d55d 100644 --- a/core/defuns-buffers.el +++ b/core/defuns-buffers.el @@ -97,7 +97,7 @@ gets killed.") (defun my-kill-matching-buffers (regexp &optional buffer-list) (interactive) (mapc (lambda (b) - (if (s-matches? regexp (buffer-name b)) + (if (string-match-p regexp (buffer-name b)) (kill-buffer b))) (if buffer-list buffer-list (buffer-list)))) diff --git a/init.el b/init.el index 201f69321..7957ecb3b 100644 --- a/init.el +++ b/init.el @@ -46,7 +46,7 @@ (require 'cask) (cask-initialize) -(eval-when-compile (require 'use-package)) +(require 'use-package) (mapc 'require ;; ls init/{init,my}* | xargs basename | sed -e 's/\..*$//' '(core @@ -61,10 +61,9 @@ ;; init-floobits ; when I'm feeling lonely init-fly ; fly(check|spell) init-git ; git-gutter + modes - init-helm ; a search engine for your life init-ido ; a search engine for your car keys + init-helm ; a search engine for your life init-project ; project tools - dired, perspective, neotree - init-projectile ; when you forget where you put your house init-cc ; C/C++/Obj-C madness ;; init-d ; D - It's C, but better! @@ -76,7 +75,7 @@ init-go init-java ; the poster child for carpal tunnel syndome init-js ; alert("not java, javascript!") - init-lua ; zero-based indices? Zero-based indices. + init-lua ; one-based indices? One-based indices. ;; init-org ; for fearless [organized] leader init-php ; making php less painful to work with init-python ; beautiful is better than ugly diff --git a/init/init-auto-complete.el b/init/init-auto-complete.el deleted file mode 100644 index b19ce49b0..000000000 --- a/init/init-auto-complete.el +++ /dev/null @@ -1,89 +0,0 @@ -(provide 'init-auto-complete) - -(defconst my-dicts-dir (concat my-dir "dict/")) - -(setq tags-case-fold-search nil) - -(use-package pos-tip) - -(use-package auto-complete - :init - (progn - (require 'auto-complete-config) - - (setq ac-auto-start nil - ac-auto-show-menu t ; Suggestions box must be invoked manually (see core-keymaps.el) - ac-use-menu-map t ; Enable ac-menu-map map when menu is open - ac-use-quick-help nil ; Don't show tooltips unless invoked (see core-keymaps.el) - ac-use-fuzzy nil - ac-use-comphist t - ac-candidate-limit 25) - (setq ac-comphist-file (concat my-tmp-dir "ac-comphist.dat")) - - (setq-default ac-sources '(ac-source-yasnippet))) - :config - (progn - ;; Redefine this function so auto-complete is available [almost] everywhere - (defun auto-complete-mode-maybe () - (unless (minibufferp (current-buffer)) - (auto-complete-mode 1))) - - (defun auto-complete--backend (hook &rest backends) - (add-hook hook - `(lambda() - (set (make-local-variable 'ac-sources) (append '(,@backends) ac-sources))))) - - (global-auto-complete-mode t) - - (let ((bg (face-attribute 'default :background))) - (require 'color) - (custom-set-faces - ;; `(company-scrollbar-bg ((t (:background ,(color-lighten-name bg 15))))) - ;; `(company-scrollbar-fg ((t (:background ,(color-lighten-name bg 5))))) - `(ac-yasnippet-candidate-face ((t (:inherit ac-candidate-face :background ,(color-lighten-name bg 5))))) - `(ac-yasnippet-selection-face ((t (:inherit ac-selection-face :background ,(color-lighten-name bg 10))))) - `(ac-completion-face ((t (:background ,(color-lighten-name bg 15))))) - `(ac-candidate-face ((t (:inherit font-lock-function-name-face :background ,(color-lighten-name bg 4))))) - `(ac-selection-face ((t (:background ,(color-lighten-name bg 9))))))) - - (add-to-list 'ac-dictionary-directories my-dicts-dir) - - (auto-complete--backend 'emacs-lisp-mode-hook 'ac-source-features 'ac-source-functions 'ac-source-variables 'ac-source-symbols) - (auto-complete--backend 'scss-mode-hook 'ac-source-css-property) - - (push '("*Popup Help*" :position bottom :height 0.35 :noselect t) popwin:special-display-config) - - ;; Tell ido not to care about case - ;; (setq completion-ignore-case t) - - (bind 'insert ac-mode-map - (kbd "C-x C-k") 'ac-complete-dictionary - (kbd "C-x C-f") (λ (let ((ac-sources '(ac-source-filename ac-source-files-in-current-dir))) - (auto-complete))) - (kbd "C-x C-]") 'ac-complete-etags - (kbd "C-x s") 'ac-complete-ispell - (kbd "C-x C-s") 'ac-complete-yasnippet - (kbd "C-x C-n") 'ac-complete-words-in-all-buffer - (kbd "C-x C-p") 'ac-complete-words-in-same-mode-buffers - (kbd "C-x C-o") 'auto-complete - (kbd "C-SPC") 'auto-complete) - - (bind ac-completing-map - (kbd "") 'ac-complete - (kbd "C-n") 'ac-next - (kbd "C-p") 'ac-previous - (kbd "C-h") 'ac-quick-help - (kbd "C-S-h") 'ac-help - (kbd "") 'ac-stop - (kbd "") 'ac-complete) - - (use-package ac-etags - :commands (ac-complete-etags) - :config (ac-etags-setup)) - - (use-package ac-ispell - :commands (ac-complete-ispell ac-complete-ispell-fuzzy) - :config - (progn (ac-ispell-setup) - (setq ac-ispell-requires 1 - ac-ispell-fuzzy-limit 25))))) diff --git a/init/init-cc.el b/init/init-cc.el index d2181cbaa..012a6afd8 100644 --- a/init/init-cc.el +++ b/init/init-cc.el @@ -154,11 +154,6 @@ (looking-at ".*[(,][ \t]*\\[[^]]*\\][ \t]*[({][^}]*$")))) 0 ; no additional indent ad-do-it))) ; default behavior - - - ;; Tools/defuns ;;;;;;;;;;;;;;;;;;;;;;;; - - (push '("*compilation*" :height 0.5 :position bottom :noselect t) popwin:special-display-config) )) diff --git a/init/init-cscope.el b/init/init-cscope.el index 03945965f..332f462c1 100644 --- a/init/init-cscope.el +++ b/init/init-cscope.el @@ -2,6 +2,8 @@ (use-package xcscope :init (cscope-setup) - :config (push '("*cscope*" :position bottom) popwin:special-display-config)) + :config + ;; (push '("*cscope*" :position bottom) popwin:special-display-config) + ) (add-hook 'ruby-mode-hook (function cscope-minor-mode)) diff --git a/init/init-dev.el b/init/init-dev.el index f5fb046fd..7f07a8294 100644 --- a/init/init-dev.el +++ b/init/init-dev.el @@ -39,7 +39,9 @@ (make-variable-buffer-local 'my-build-command) (defun set-build-command (command &optional file) - (setq my-build-command (command . file))) + (when (or (null file) + (project-has-files file)) + (setq my-build-command `(,command . ,file)))) (evil-define-command my:build (arg) "Call a build command in the current directory. diff --git a/init/init-fly.el b/init/init-fly.el index 878d75cb4..00ab6d91e 100644 --- a/init/init-fly.el +++ b/init/init-fly.el @@ -32,10 +32,7 @@ (add-hook 'evil-normal-state-entry-hook 'my--evil-flycheck-buffer) ;; And on ESC in normal mode. (defadvice evil-force-normal-state (after evil-esc-flycheck-buffer activate) - (my--evil-flycheck-buffer)) - - (push '("^\\*Flycheck.*\\*$" :regexp t :position bottom :height 0.25 :noselect t) - popwin:special-display-config))) + (my--evil-flycheck-buffer)))) (use-package flyspell :commands flyspell-mode) diff --git a/init/init-helm.el b/init/init-helm.el index bcb00a99d..31bad040e 100644 --- a/init/init-helm.el +++ b/init/init-helm.el @@ -2,98 +2,14 @@ :config (progn ; helm settings (defvar helm-global-prompt ">>> ") - (setq helm-quick-update t helm-idle-delay 0.01 helm-input-idle-delay 0.01 helm-reuse-last-window-split-state t helm-buffers-fuzzy-matching nil + helm-candidate-number-limit 40 helm-bookmark-show-location t) - (my--cleanup-buffers-add "^\\*[Hh]elm.*\\*$") - - ;; disable popwin-mode in an active Helm session It should be disabled - ;; otherwise it will conflict with other window opened by Helm persistent - ;; action, such as *Help* window. - (add-hook! 'helm-after-initialize-hook (popwin-mode -1)) - - ;; Restore popwin-mode after a Helm session finishes. - (add-hook! 'helm-cleanup-hook (popwin-mode 1)) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - (use-package helm-ag - :config - (progn - ;; Ex-mode interface for `helm-ag'. If `bang', then `search' is interpreted as - ;; regexp. - (evil-define-operator my:helm-ag-search (beg end &optional search hidden-files-p pwd-p regex-p) - :type inclusive - :repeat nil - (interactive "") - (let* ((helm-ag-default-directory (if pwd-p default-directory (project-root))) - (helm-ag-command-option (concat (unless regex-p "-Q ") - (if hidden-files-p "--hidden "))) - (input "") - (header-name (format "Search in %s" helm-ag-default-directory))) - (if search - (progn - (helm-attrset 'search-this-file nil helm-ag-source) - (setq helm-ag--last-query search)) - (if (and beg end (/= beg (1- end))) - (setq input (buffer-substring-no-properties beg end)))) - (helm-attrset 'name header-name helm-ag-source) - (helm :sources (if search (helm-ag--select-source) '(helm-source-do-ag)) - :buffer "*helm-ag*" - :input input - :prompt helm-global-prompt))) - - (evil-define-operator my:helm-ag-regex-search (beg end &optional bang search) - :type inclusive - :repeat nil - (interactive "") - (my:helm-ag-search beg end search bang nil t)) - - ;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted - ;; as regexp - (evil-define-operator my:helm-ag-search-cwd (beg end &optional search bang) - :type inclusive - :repeat nil - (interactive "") - (my:helm-ag-search beg end search bang t nil)) - - (evil-define-operator my:helm-ag-regex-search-cwd (beg end &optional search bang) - :type inclusive - :repeat nil - (interactive "") - (my:helm-ag-search beg end search bang t t)))) - - (use-package helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss - :commands (helm-css-scss - helm-css-scss-multi - helm-css-scss-insert-close-comment)) - - (use-package helm-swoop ; https://github.com/ShingoFukuyama/helm-swoop - :commands (my:helm-swoop helm-swoop helm-multi-swoop) - :config - (progn - (setq helm-swoop-use-line-number-face t - helm-swoop-split-with-multiple-windows t - helm-swoop-speed-or-color t - helm-swoop-split-window-function 'popwin:popup-buffer) - - ;; Ex-mode interface for `helm-swoop', `helm-multi-swoop-all' (if `bang'), or - ;; `helm-css-scss' and `helm-css-scss-multi' (if `bang') if major-mode is - ;; `scss-mode' - (evil-define-command my:helm-swoop (&optional search bang) - :repeat nil - (interactive "") - (if (eq major-mode 'scss-mode) - (if bang (helm-css-scss-multi search) (helm-css-scss search)) - (if bang (helm-multi-swoop-all search) (helm-swoop :$query search)))))) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (after "winner" ;; Tell winner-mode to ignore helm buffers (dolist (bufname '("*helm recentf*" @@ -106,48 +22,109 @@ "*Helm Swoop*")) (push bufname winner-boring-buffers))) - (after "company" - (use-package helm-company - :config - (defun helm-company () - (interactive) - (unless company-candidates - (company-complete)) - (when company-point - (helm :sources 'helm-source-company - :buffer "*helm company*" - :prompt helm-global-prompt - :candidate-number-limit helm-company-candidate-number-limit))))) + (my--cleanup-buffers-add "^\\*[Hh]elm.*\\*$") - (after "projectile" - (use-package helm-projectile - :config - (setq projectile-switch-project-action 'helm-projectile)) + (use-package helm-ag) + (use-package helm-css-scss ; https://github.com/ShingoFukuyama/helm-css-scss + :commands (helm-css-scss + helm-css-scss-multi + helm-css-scss-insert-close-comment)) - ;; Don't show the project name in the prompts; I already know. - (defun projectile-prepend-project-name (string) - (format helm-global-prompt string)) + ;; Ex-mode interface for `helm-ag'. If `bang', then `search' is interpreted as + ;; regexp. + (evil-define-operator my:helm-ag-search (beg end &optional search hidden-files-p pwd-p regex-p) + :type inclusive + :repeat nil + (interactive "") + (let* ((helm-ag-default-directory (if pwd-p default-directory (project-root))) + (helm-ag-command-option (concat (unless regex-p "-Q ") + (if hidden-files-p "--hidden "))) + (input "") + (header-name (format "Search in %s" helm-ag-default-directory))) + (if search + (progn + (helm-attrset 'search-this-file nil helm-ag-source) + (setq helm-ag--last-query search)) + (if (and beg end (/= beg (1- end))) + (setq input (buffer-substring-no-properties beg end)))) + (helm-attrset 'name header-name helm-ag-source) + (helm :sources (if search (helm-ag--select-source) '(helm-source-do-ag)) + :buffer "*helm-ag*" + :input input + :prompt helm-global-prompt))) - ;; All this for a smaller prompt (it was redundant with helm headers) - (defmacro helm-projectile-command (command source prompt) - `(defun ,(intern (concat "helm-projectile-" command)) (&optional arg) - (interactive "P") - (if (projectile-project-p) - (projectile-maybe-invalidate-cache arg)) - (let ((helm-ff-transformer-show-only-basename nil) - ;; for consistency, we should just let Projectile take care of ignored files - (helm-boring-file-regexp-list nil)) - (helm :sources ,source - :buffer "*helm projectile*" - :prompt helm-global-prompt)))) + (evil-define-operator my:helm-ag-regex-search (beg end &optional search bang) + :type inclusive :repeat nil + (interactive "") + (my:helm-ag-search beg end search bang nil t)) + (evil-define-operator my:helm-ag-search-cwd (beg end &optional search bang) + ;; Ex-mode interface for `helm-do-ag'. If `bang', then `search' is interpreted + ;; as regexp + :type inclusive :repeat nil + (interactive "") + (my:helm-ag-search beg end search bang t nil)) + (evil-define-operator my:helm-ag-regex-search-cwd (beg end &optional search bang) + :type inclusive :repeat nil + (interactive "") + (my:helm-ag-search beg end search bang t t)) - (helm-projectile-command "switch-project" 'helm-source-projectile-projects helm-global-prompt) - (helm-projectile-command "find-file" helm-source-projectile-files-and-dired-list helm-global-prompt) - (helm-projectile-command "find-file-in-known-projects" 'helm-source-projectile-files-in-all-projects-list helm-global-prompt) - (helm-projectile-command "find-file-dwim" 'helm-source-projectile-files-dwim-list helm-global-prompt) - (helm-projectile-command "find-dir" helm-source-projectile-directories-and-dired-list helm-global-prompt) - (helm-projectile-command "recentf" 'helm-source-projectile-recentf-list helm-global-prompt) - (helm-projectile-command "switch-to-buffer" 'helm-source-projectile-buffers-list helm-global-prompt)) + (use-package helm-swoop ; https://github.com/ShingoFukuyama/helm-swoop + :commands (helm-swoop helm-multi-swoop) + :config + (setq helm-swoop-use-line-number-face t + helm-swoop-split-with-multiple-windows t + helm-swoop-speed-or-color t + ;; helm-swoop-split-window-function 'popwin:popup-buffer + )) + + ;; Ex-mode interface for `helm-swoop', `helm-multi-swoop-all' (if `bang'), or + ;; `helm-css-scss' and `helm-css-scss-multi' (if `bang') if major-mode is + ;; `scss-mode' + (evil-define-command my:helm-swoop (&optional search bang) + :repeat nil + (interactive "") + (if (eq major-mode 'scss-mode) + (if bang (helm-css-scss-multi search) (helm-css-scss search)) + (if bang (helm-multi-swoop-all search) (helm-swoop :$query search)))) + + (use-package projectile + :init (setq-default projectile-enable-caching t) + :config + (progn + (projectile-global-mode +1) + (setq projectile-sort-order 'recentf + projectile-cache-file (concat my-tmp-dir "projectile.cache") + projectile-known-projects-file (concat my-tmp-dir "projectile.projects") + projectile-indexing-method 'alien) + (add-to-list 'projectile-globally-ignored-files "ido.last") + (add-to-list 'projectile-globally-ignored-directories "assets") + (add-to-list 'projectile-other-file-alist '("scss" "css")) + (add-to-list 'projectile-other-file-alist '("css" "scss")) + (use-package helm-projectile) + + ;; Don't show the project name in the prompts; I already know. + (defun projectile-prepend-project-name (string) (format helm-global-prompt string)) + + ;; All this for a smaller prompt (it was redundant with helm headers) + (defmacro helm-projectile-command (command source prompt) + `(defun ,(intern (concat "helm-projectile-" command)) (&optional arg) + (interactive "P") + (if (projectile-project-p) + (projectile-maybe-invalidate-cache arg)) + (let ((helm-ff-transformer-show-only-basename nil) + ;; for consistency, we should just let Projectile take care of ignored files + (helm-boring-file-regexp-list nil)) + (helm :sources ,source + :buffer "*helm projectile*" + :prompt helm-global-prompt)))) + + (helm-projectile-command "switch-project" 'helm-source-projectile-projects helm-global-prompt) + (helm-projectile-command "find-file" helm-source-projectile-files-and-dired-list helm-global-prompt) + (helm-projectile-command "find-file-in-known-projects" 'helm-source-projectile-files-in-all-projects-list helm-global-prompt) + (helm-projectile-command "find-file-dwim" 'helm-source-projectile-files-dwim-list helm-global-prompt) + (helm-projectile-command "find-dir" helm-source-projectile-directories-and-dired-list helm-global-prompt) + (helm-projectile-command "recentf" 'helm-source-projectile-recentf-list helm-global-prompt) + (helm-projectile-command "switch-to-buffer" 'helm-source-projectile-buffers-list helm-global-prompt))) (progn ; helm hacks ;; No persistent header @@ -182,10 +159,6 @@ (propertize (concat " " hlstr hlend) 'face 'helm-header)))) (when force (force-mode-line-update)))) - (progn ; popwin - (push '("^\\*helm.*\\*$" :position bottom :regexp t :height 18) - popwin:special-display-config)) - (progn ; evil (evil-set-initial-state 'helm-mode 'emacs) diff --git a/init/init-ido.el b/init/init-ido.el index 6944cf116..e23dd9bc6 100644 --- a/init/init-ido.el +++ b/init/init-ido.el @@ -11,15 +11,13 @@ ;; (set-keymap-parent ido-file-completion-map ido-file-dir-completion-map) ;; (set-keymap-parent ido-buffer-completion-map ido-common-completion-map) -(require 'ido-ubiquitous) -(require 'ido-vertical-mode) -(require 'flx-ido) (ido-mode 1) -(ido-vertical-mode 1) (ido-everywhere 1) -(ido-ubiquitous-mode 1) -(flx-ido-mode 1) + +(use-package ido-vertical-mode :config (ido-vertical-mode 1)) +(use-package ido-ubiquitous :config (ido-ubiquitous-mode 1)) +(use-package flx-ido :config (flx-ido-mode 1)) (setq ido-use-faces nil ido-confirm-unique-completion t @@ -37,6 +35,21 @@ "^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-" "_region_" " output\\*$" "^TAGS$" "^\*Ido")) +; sort ido filelist by mtime instead of alphabetically +(add-hook 'ido-make-file-list-hook 'ido-sort-mtime) +(add-hook 'ido-make-dir-list-hook 'ido-sort-mtime) +(defun ido-sort-mtime () + (setq ido-temp-list + (sort ido-temp-list + (lambda (a b) + (time-less-p + (sixth (file-attributes (concat ido-current-directory b))) + (sixth (file-attributes (concat ido-current-directory a))))))) + (ido-to-end ;; move . files to end (again) + (delq nil (mapcar + (lambda (x) (and (char-equal (string-to-char x) ?.) x)) + ido-temp-list)))) + (provide 'init-ido) ;;; init-ido.el ends here diff --git a/init/init-java.el b/init/init-java.el index 02ec7841b..0aa8362e1 100644 --- a/init/init-java.el +++ b/init/init-java.el @@ -10,6 +10,7 @@ "")) (use-package eclim + :disabled t :commands (eclim-mode global-eclim-mode) :config (progn @@ -36,9 +37,12 @@ (use-package android-mode :defer t :init + (add-hook 'android-mode-hook (set-build-command "./gradlew %s" "build.gradle")) (add-hook! 'java-mode-hook - (when (project-has-files "AndroidManifest.xml") - (android-mode +1)))) + (let ((root (project-root))) + (when (or (project-has-files "AndroidManifest.xml" root) + (project-has-files "src/main/AndroidManifest.xml" root)) + (android-mode +1))))) (use-package groovy-mode :mode "\\.gradle$") diff --git a/init/init-js.el b/init/init-js.el index 2d49145cb..846f237bc 100644 --- a/init/init-js.el +++ b/init/init-js.el @@ -61,7 +61,7 @@ :lighter " lb6" :keymap (make-sparse-keymap) (my--init-yas-mode 'lb6-mode)) -(associate-minor-mode "/Contents/\\(Scripts\\|Resources\\)/.*$" 'lb6-mode) +(associate-minor-mode "\\.lb\\(action\\|ext\\)/.*$" 'lb6-mode) (provide 'init-js) ;;; init-js.el ends here diff --git a/init/init-project.el b/init/init-project.el index 3cdb1d7ca..3ba1ea547 100644 --- a/init/init-project.el +++ b/init/init-project.el @@ -11,6 +11,11 @@ (kbd "TAB") 'neotree-enter (kbd "RET") 'neotree-enter)))) +(defun my-ido-find-project-file () + (interactive) + (let ((default-directory (project-root))) + (ido-find-file))) + ;; (use-package dired ;; :disabled t diff --git a/init/init-projectile.el b/init/init-projectile.el deleted file mode 100644 index 986fd7141..000000000 --- a/init/init-projectile.el +++ /dev/null @@ -1,19 +0,0 @@ -(use-package projectile - :init (setq-default projectile-enable-caching t) - :config - (progn - (projectile-global-mode +1) - - (setq projectile-sort-order 'recentf - projectile-cache-file (concat my-tmp-dir "projectile.cache") - projectile-known-projects-file (concat my-tmp-dir "projectile.projects") - projectile-indexing-method 'alien) - - (add-to-list 'projectile-globally-ignored-files "ido.last") - (add-to-list 'projectile-globally-ignored-directories "assets") - (add-to-list 'projectile-other-file-alist '("scss" "css")) - (add-to-list 'projectile-other-file-alist '("css" "scss")))) - - -(provide 'init-projectile) -;;; init-projectile.el ends here diff --git a/init/init-python.el b/init/init-python.el index da9fb64d5..88918ec38 100644 --- a/init/init-python.el +++ b/init/init-python.el @@ -23,10 +23,6 @@ (bind 'motion anaconda-mode-map "gd" 'anaconda-mode-goto-definitions) (bind 'normal anaconda-nav-mode-map [escape] 'anaconda-nav-quit) - (push '("*anaconda-doc*" :position bottom :height 15 :noselect t) popwin:special-display-config) - (push '("*anaconda-nav*" :position bottom :height 15 :stick t) popwin:special-display-config) - (push '("^\\*Python.+\\*$" :regexp t :position bottom :height 20 :noselect t) popwin:special-display-config) - ;; Delete the window on escape or C-g (defadvice anaconda-mode-doc-buffer (after anaconda-doc-buffer-escape-to-close activate) (with-current-buffer (get-buffer "*anaconda-doc*") diff --git a/init/init-regex.el b/init/init-regex.el index 839001043..d171f3452 100644 --- a/init/init-regex.el +++ b/init/init-regex.el @@ -50,9 +50,7 @@ (progn (bind 'normal rxt-help-mode-map [escape] 'kill-buffer-and-window) - (after "re-builder" (setq reb-re-syntax 'pcre)) - (after "popwin" - (push '("* Regexp Explain *" :position top :height 0.35) popwin:special-display-config)))) + (after "re-builder" (setq reb-re-syntax 'pcre)))) (provide 'init-regex) diff --git a/init/init-ruby.el b/init/init-ruby.el index 1a890fbe1..4aafe5c1b 100644 --- a/init/init-ruby.el +++ b/init/init-ruby.el @@ -63,7 +63,6 @@ :config (progn (evil-set-initial-state 'inf-enh-ruby-mode 'insert) - (push '(inf-enh-ruby-mode :position bottom :stick t) popwin:special-display-config) (after "company" (use-package company-inf-ruby @@ -95,11 +94,10 @@ (use-package company-robe :config (company--backend-on 'enh-ruby-mode-hook 'company-robe))) - (add-hook! 'enh-ruby-mode-hook - (unless (f-ext? (buffer-file-name) "org") ;; in case of org-mode - (robe-mode 1) - ;; (after "auto-complete" (ac-robe-setup)) - (my--ruby-load-file buffer-file-name))) + ;; (add-hook! 'enh-ruby-mode-hook + ;; (unless (f-ext? (buffer-file-name) "org") ;; in case of org-mode + ;; (robe-mode 1) + ;; (my--ruby-load-file buffer-file-name))) (defun my--ruby-load-file (&optional file) (let ((file (or file buffer-file-name))) diff --git a/init/init-sh.el b/init/init-sh.el index 8f1081835..33420156d 100644 --- a/init/init-sh.el +++ b/init/init-sh.el @@ -1,8 +1,3 @@ -(after "popwin" - (push '("*ansi-term*" :position bottom :height 0.45 :stick t) popwin:special-display-config) - (push '("*terminal*" :position bottom :height 0.45 :stick t) popwin:special-display-config) - (push '("*Async Shell Command*" :position bottom) popwin:special-display-config)) - (my--cleanup-buffers-add "^\\*Shell Command Output\\*$") (my--cleanup-buffers-add "^\\*Async Shell Command\\*$") diff --git a/init/init-web.el b/init/init-web.el index 1d868cf9c..5412729a9 100644 --- a/init/init-web.el +++ b/init/init-web.el @@ -14,8 +14,7 @@ (progn (add-hook 'web-mode-hook 'enable-tab-width-2) - (setq web-mode-ac-sources-alist '(("css" . (ac-source-css-property))) - web-mode-markup-indent-offset 2 + (setq web-mode-markup-indent-offset 2 web-mode-code-indent-offset 2 web-mode-css-indent-offset 2 web-mode-style-padding 2 @@ -43,6 +42,7 @@ ",t" 'web-mode-element-rename) (bind '(normal visual) web-mode-map "]a" 'web-mode-attribute-next + "[a" 'web-mode-attribute-previous "]t" 'web-mode-tag-next "[t" 'web-mode-tag-previous "]T" 'web-mode-element-child @@ -60,21 +60,29 @@ :config (progn (setq emmet-move-cursor-between-quotes t) - (bind 'insert emmet-mode-keymap - (kbd "M-e") 'emmet-expand-yas - (kbd "M-E") 'emmet-expand-line))) + "M-e" 'emmet-expand-yas + "M-E" 'emmet-expand-line))) (define-minor-mode jekyll-mode :init-value nil :lighter " :{" :keymap (make-sparse-keymap) (my--init-yas-mode 'jekyll-mode)) +(defun jekyll-mode-enable-maybe () + (when (project-has-files '("_config.yml" "_layouts")) + (jekyll-mode 1))) (associate-minor-mode "/_\\(layouts\\|posts\\)/.+$" 'jekyll-mode) (add-hooks '(web-mode-hook scss-mode-hook html-mode-hook markdown-mode markdown-mode-hook) - (lambda () - (when (project-has-files "_config.yml" "_layouts") - (jekyll-mode 1)))) + 'jekyll-mode-enable-maybe) + +(define-minor-mode wordpress-mode + :init-value nil + :lighter " wp" + :keymap (make-sparse-keymap) + (my--init-yas-mode 'wordpress-mode)) +(associate-minor-mode "/wp-\\(content\\|admin\\|includes\\)/.+$" 'wordpress-mode) +(associate-minor-mode "/wp-.+\\.php$" 'wordpress-mode) (provide 'init-web) diff --git a/init/init-yasnippet.el b/init/init-yasnippet.el index f64e1050d..8b0154893 100644 --- a/init/init-yasnippet.el +++ b/init/init-yasnippet.el @@ -1,5 +1,6 @@ (use-package yasnippet :mode (("emacs\\.d/snippets/.+$" . snippet-mode)) + :demand t :init (progn (defvar yas-minor-mode-map @@ -10,12 +11,11 @@ (bind 'visual map (kbd "") 'yas-insert-snippet) map)) - (add-hook 'snippet-mode-hook 'disable-final-newline) - (add-hook 'snippet-mode-hook 'yas-minor-mode) - (add-hook 'text-mode-hook 'yas-minor-mode) - (add-hook 'prog-mode-hook 'yas-minor-mode) - ;; (add-hook 'markdown-mode-hook 'yas-minor-mode) - (add-hook 'org-mode-hook 'yas-minor-mode)) + ;; (add-hook 'snippet-mode-hook 'yas-minor-mode-on) + ;; (add-hook 'text-mode-hook 'yas-minor-mode-on) + ;; (add-hook 'prog-mode-hook 'yas-minor-mode-on) + ;; (add-hook 'org-mode-hook 'yas-minor-mode-on)) + (add-hook 'snippet-mode-hook 'disable-final-newline)) :config (progn (setq yas-verbosity 0) @@ -26,53 +26,50 @@ (setq yas-snippet-dirs `(,my-snippets-dir)) (setq yas-prompt-functions '(yas-ido-prompt yas-no-prompt)) - (push '(snippet-mode :position bottom :stick t) popwin:special-display-config) - + (yas-global-mode 1) (yas-reload-all) - (after "auto-complete" - (defadvice ac-expand (before advice-for-ac-expand activate) - (when (yas-expand) (ac-stop)))) + (after "helm" + (add-to-list 'yas-dont-activate 'helm-alive-p)) - (after "evil" - ;; Exit snippets on ESC in normal mode - (defadvice evil-force-normal-state (before evil-esc-quit-yasnippet activate) - (yas-exit-all-snippets)) - ;; Once you're in normal mode, you're out - (add-hook 'evil-normal-state-entry-hook 'yas-abort-snippet) + ;; Exit snippets on ESC in normal mode + (defadvice evil-force-normal-state (before evil-esc-quit-yasnippet activate) + (yas-exit-all-snippets)) + ;; Once you're in normal mode, you're out + (add-hook 'evil-normal-state-entry-hook 'yas-abort-snippet) - ;; Fixes: evil's visual-line mode gobbles up the newline on the right. - ;; This prevents that by essentially doing (1- (region-end)). - (defadvice yas-expand-snippet (around yas-expand-snippet-visual-line activate) - (if (evil-visual-line-state-p) - (ad-set-arg 2 (1- (ad-get-arg 2)))) ad-do-it) + ;; Fixes: evil's visual-line mode gobbles up the newline on the right. + ;; This prevents that by essentially doing (1- (region-end)). + (defadvice yas-expand-snippet (around yas-expand-snippet-visual-line activate) + (if (evil-visual-line-state-p) + (ad-set-arg 2 (1- (ad-get-arg 2)))) ad-do-it) - ;; Fixes: visual-line includes indentation before the selection. This - ;; strips it out. - (add-hook! 'yas-before-expand-snippet-hook - (if (evil-visual-line-state-p) - (setq-local yas-selected-text - (replace-regexp-in-string - "\\(^ *\\|\n? $\\)" "" - (buffer-substring-no-properties (region-beginning) - (1- (region-end))))))) - ;; Previous hook causes yas-selected-text to persist between expansions. - ;; This little hack gets around it. - (add-hook! 'yas-after-exit-snippet-hook - (setq-local yas-selected-text nil)) + ;; Fixes: visual-line includes indentation before the selection. This + ;; strips it out. + (add-hook! 'yas-before-expand-snippet-hook + (if (evil-visual-line-state-p) + (setq-local yas-selected-text + (replace-regexp-in-string + "\\(^ *\\|\n? $\\)" "" + (buffer-substring-no-properties (region-beginning) + (1- (region-end))))))) + ;; Previous hook causes yas-selected-text to persist between expansions. + ;; This little hack gets around it. + (add-hook! 'yas-after-exit-snippet-hook + (setq-local yas-selected-text nil)) - (evil-define-operator ex:snippets (beg end &optional name) - :motion nil - :move-point nil - :type exclusive - :repeat nil - (interactive "") - (if (and beg end) - (yas-insert-snippet) - (if name - (popwin:find-file (concat my-snippets-dir - (symbol-name major-mode) "/" name)) - (yas-visit-snippet-file))))) + (evil-define-operator my:snippets (beg end &optional name) + :motion nil + :move-point nil + :type exclusive + :repeat nil + (interactive "") + (if (and beg end) + (yas-insert-snippet) + (if name + (popwin:find-file (concat my-snippets-dir + (symbol-name major-mode) "/" name)) + (yas-visit-snippet-file)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/init/my-bindings.el b/init/my-bindings.el index d62065240..e82d4f00a 100644 --- a/init/my-bindings.el +++ b/init/my-bindings.el @@ -4,12 +4,13 @@ (bind "A-x" 'smex "A-X" 'smex-major-mode-commands + "A-M-x" 'helm-M-x "A-;" 'eval-expression "C-`" 'popwin:toggle-popup-window "M-=" 'text-scale-increase "M--" 'text-scale-decrease "M-w" 'evil-window-delete - "M-/" 'evilnc-comment-or-uncomment-lines + "M-/" 'evil-commentary-line "M-b" 'my:build) (bind 'motion @@ -20,6 +21,7 @@ 'normal "M-o" 'ido-find-file + "M-O" 'my-ido-find-project-file "M-d" 'dash-at-point "M-R" 'my:eval-buffer) @@ -36,24 +38,34 @@ ;; (bind my-leader-map "," 'helm-projectile-switch-to-buffer - "." 'helm-resume + "." 'ido-find-file + ">" 'my-ido-find-project-file "/" 'helm-projectile-find-file ";" 'helm-semantic-or-imenu "<" 'helm-mini - "E" 'my:init-files "M" 'helm-projectile-recentf ; recent PROJECT files "]" 'helm-etags-select "a" 'helm-projectile-find-other-file - "b" 'my:build - "e" 'ido-find-file + "E" 'my:init-files "g" 'git-gutter+-show-hunk "h" 'helm-apropos "m" 'helm-recentf "p" 'helm-projectile-switch-project + "r" 'emr-show-refactor-menu ; init-dev.el "qq" 'evil-save-and-quit "QQ" 'evil-quit-all - "r" 'emr-show-refactor-menu ; init-dev.el - "y" 'helm-show-kill-ring) + + "oo" 'my-open-with + "of" (λ (my-open-with "Finder.app" default-directory)) + "oF" (λ (my-open-with "Finder.app" (project-root))) + "ou" (λ (my-open-with "Transmit")) + "oU" (λ (my-open-with "Transmit" default-directory)) + "ol" (λ (my-open-with "LaunchBar")) + "oL" (λ (my-open-with "LaunchBar" default-directory)) + ;; tmux: cd (default-directory) + "ot" (λ (my:tmux-chdir nil t)) + ;; tmux: cd [project root] + "oT" 'my:tmux-chdir) ;; (bind my-localleader-map @@ -62,19 +74,6 @@ "=" 'toggle-transparency "E" 'evil-emacs-state - "oo" 'my-open-with - "of" (λ (my-open-with "Finder" default-directory)) - "oF" (λ (my-open-with "Finder" (project-root))) - "ou" (λ (my-open-with "Transmit")) - "oU" (λ (my-open-with "Transmit" default-directory)) - "ol" (λ (my-open-with "LaunchBar")) - "oL" (λ (my-open-with "LaunchBar" default-directory)) - - ;; tmux: cd (default-directory) - "ot" (λ (my:tmux-chdir nil t)) - ;; tmux: cd [project root] - "oT" 'my:tmux-chdir - "]" 'next-buffer "[" 'previous-buffer @@ -115,9 +114,9 @@ (evil-normal-state) (evil-visual-restore)) - 'motion - "X" 'evil-exchange + 'normal "X" 'evil-exchange + 'motion "]g" 'git-gutter+-next-hunk "[g" 'git-gutter+-previous-hunk @@ -180,13 +179,13 @@ (when is-mac ;; Restore text nav keys - (bind (kbd "") 'backward-word - (kbd "") 'forward-word - (kbd "") 'my.backward-kill-to-bol-and-indent - (kbd "M-a") 'mark-whole-buffer - (kbd "M-c") 'evil-yank - (kbd "M-v") 'evil-paste-after - (kbd "M-s") 'save-buffer)) + (bind "" 'backward-word + "" 'forward-word + "" 'my.backward-kill-to-bol-and-indent + "M-a" 'mark-whole-buffer + "M-c" 'evil-yank + "M-s" 'save-buffer + "M-v" 'yank)) ;; Fix osx keymappings and then some (use-package smart-forward diff --git a/init/my-commands.el b/init/my-commands.el index 95e22809c..f26332b0b 100644 --- a/init/my-commands.el +++ b/init/my-commands.el @@ -44,7 +44,7 @@ (exmap "rec[ent]" 'my:helm-recentf)) (after "yasnippet" - (exmap "snip[pets]" 'ex:snippets)) + (exmap "snip[pets]" 'my:snippets)) (after "emr" (exmap "ref[actor]" 'emr-show-refactor-menu)) diff --git a/init/my-settings.el b/init/my-settings.el index 029f9ac92..53bedc716 100644 --- a/init/my-settings.el +++ b/init/my-settings.el @@ -17,6 +17,10 @@ (set-face-background 'show-paren-match nil) (set-face-foreground 'show-paren-match "orange") (set-face-attribute 'show-paren-match nil :weight 'extra-bold) +(let ((face 'evil-search-highlight-persist-highlight-face)) + (set-face-attribute face nil :inherit 'isearch-lazy-highlight-face) + (set-face-foreground face nil) + (set-face-background face nil)) (set-register ?. "~/.dotfiles/") (set-register ?d "~/Dropbox/Projects/")