diff --git a/elisp/ruby-mode-indent-fix.el b/elisp/ruby-mode-indent-fix.el new file mode 100644 index 000000000..dfd3938f2 --- /dev/null +++ b/elisp/ruby-mode-indent-fix.el @@ -0,0 +1,198 @@ +;;; ruby-mode-indent-fix.el --- + +;; this file is not part of Emacs + +;; Copyright (C) 2012 Le Wang +;; Author: Le Wang +;; Maintainer: Le Wang +;; Description: +;; Author: Le Wang +;; Maintainer: Le Wang + +;; Created: Sun Feb 26 23:27:17 2012 (+0800) +;; Version: 0.1 +;; Last-Updated: Mon Mar 26 11:23:48 2012 (+0800) +;; By: Le Wang +;; Update #: 29 +;; URL: +;; Keywords: +;; Compatibility: + +;;; Installation: + +;; (eval-after-load "ruby-mod" '(require 'ruby-mode-indent-fix)) +;; +;; + +;;; Commentary: + +;; Fix some indentation issues with ruby-mode with advices. +;; +;; Based on work by Dmitry Gutov(dgutov) +;; - http://stackoverflow.com/a/7622971/903943 and +;; - https://gist.github.com/1274520 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Code: + +(eval-when-compile (require 'cl)) + +(provide 'ruby-mode-indent-fix) +(require 'autopair) + + +(defvar ruby--paren-closings-regex + "[])}\"']" + "regex matching closing paren or string delimiter.") + +;; We make this advice around to avoid unnecessary buffer modifications. + +(defadvice ruby-indent-line (around fix-closing-paren activate) + "indent closing paren to line up properly. + +i.e. + + foo_function( {:a => 'foo', + :b => 'bar' + } + ) + +Note that the closing paren is vertically aligned with the opening paren. + +note: `ruby-deep-indent-paren' has to be enabled for this to work." + (let ((column (current-column)) + indent) + (when ruby-deep-indent-paren + (save-excursion + (back-to-indentation) + (let ((state (syntax-ppss))) + (when (and (or (memq (autopair-find-pair (char-after)) ruby-deep-indent-paren) + (and (eq (char-after) ?\}) + (eq 'brace (ruby--point-in-braced-proc)))) + (not (zerop (car state)))) + (goto-char (cadr state)) + (setq indent (current-column)))))) + (if indent + (indent-line-to indent) + ad-do-it))) + +(defun ruby--indent-before-all-sexps () + " +1. search backwards for a closing delimiter ON THIS LINE, then + find the matching opening + +2. if found, recurse, else the point is at a place we don't need + to worry about sexps. +" + (if (re-search-backward ruby--paren-closings-regex (point-at-bol) t) + (let ((ppss (syntax-ppss)) + beg) + (goto-char (match-beginning 0)) + (cond ((setq beg (nth 1 ppss)) ; brace + (goto-char beg)) + ((nth 3 ppss) ; string + (goto-char (nth 8 ppss)))) + (ruby--indent-before-all-sexps)))) + +(defun ruby--point-in-braced-proc () + "returns 'proc if point is in braces where starting bracs is EOL or followed by arg-list + +i.e. + + arr.each { |foo| + // do stuff + } + +or + + 1.times { + // do stuff + } +returns 'brace if point in brace + +return nil otherwise +" + (save-excursion + (let ((ppss (syntax-ppss)) + beg) + (cond ((nth 3 ppss) ; string + nil) + ((setq beg (nth 1 ppss)) ; brace + (goto-char beg) + (if (looking-at-p "{[\t ]*\\(?:$\\||\\)") + 'proc + (when (looking-at-p "{") + 'brace))))))) + +(defadvice ruby-indent-line (around line-up-args activate) + "indent new line after comma at EOL properly: + +i.e. + + foo_function a_param, + b_param, + c_param + +Note that all params line up after the function. +" + (let (indent ppss) + (save-excursion + (back-to-indentation) + (skip-chars-backward " \t\n") + (setq ppss (syntax-ppss)) + ;; check for inside comment, string, or inside braces + (when (and (eq ?, (char-before)) + (not (memq (syntax-ppss-context ppss) '(comment string))) + (zerop (car ppss))) + (ruby--indent-before-all-sexps) + (back-to-indentation) + (if (save-excursion + (skip-chars-backward " \t\n") + (eq (char-before) ?,)) + (setq indent (current-column)) + (skip-syntax-forward "w_.") + (skip-chars-forward " ") + ;; if the first symbol on the line is followed, by a comma, then this + ;; line must be a continuation + (setq indent (current-column))))) + (if indent + (indent-line-to indent) + ad-do-it))) + +;; (defadvice ruby-indent-line (around indent-no-brace-args activate) +;; "indent new line after comma at EOL properly: + +;; i.e. + +;; foo_function a_param, +;; b_param, +;; c_param + +;; Note that all params line up after the function." +;; (let ((res (ruby--point-in-braced-proc))) +;; (cond ((eq 'brace res) +;; (let ((ruby-deep-indent-paren '(?\[ ?\( ?\{ t))) +;; ad-do-it)) +;; (t +;; ad-do-it)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; ruby-mode-indent-fix.el ends here diff --git a/init.el b/init.el index 33c6ee3a3..c386db260 100644 --- a/init.el +++ b/init.el @@ -15,12 +15,12 @@ (unless (server-running-p) (server-start)) ;; Global vars -(defvar my-dir (file-name-directory load-file-name)) -(defvar my-core-dir (expand-file-name "init" my-dir)) -(defvar my-modules-dir (expand-file-name "modules" my-dir)) -(defvar my-themes-dir (expand-file-name "themes" my-dir)) -(defvar my-elisp-dir (expand-file-name "elisp" my-dir)) -(defvar my-tmp-dir (expand-file-name "tmp" my-dir)) +(defvar my-dir (file-name-directory load-file-name)) +(defvar my-core-dir (expand-file-name "init" my-dir)) +(defvar my-modules-dir (expand-file-name "modules" my-dir)) +(defvar my-themes-dir (expand-file-name "themes" my-dir)) +(defvar my-elisp-dir (expand-file-name "elisp" my-dir)) +(defvar my-tmp-dir (expand-file-name "tmp" my-dir)) ;; Setup loadpaths (add-to-list 'load-path my-core-dir) @@ -38,24 +38,24 @@ (dolist (module '( ;; Just the... bear necessities... - core ; Emacs core settings - core-packages ; Package init & management - core-ui ; Look and behavior of the emacs UI - core-editor ; Text/code editor settings and behavior - core-osx ; OSX-specific settings & functions - core-project ; Project navigation settings & packages + core ; Emacs core settings + core-packages ; Package init & management + core-ui ; Look and behavior of the emacs UI + core-editor ; Text/code editor settings and behavior + core-osx ; OSX-specific settings & functions + core-project ; Project navigation settings & packages ;; Modules to improve on emacs' heresy - mod-ac ; Auto-complete engine & settings - ;; mod-shell ; Terminal emulator settings - mod-snippets ; Snippet engine - mod-git ; GIT tools/settings - mod-fly ; Syntax and spell checkers - ; mod-webdev ; Webdev tools (sass, js, etc) - ; mod-gamedev ; Gamedev tools (C++, love2D, html5) + mod-ac ; Auto-complete engine & settings + mod-snippets ; Snippet engine + mod-git ; GIT tools/settings + mod-fly ; Syntax and spell checkers + ; mod-webdev ; Webdev tools (sass, js, etc) + ; mod-gamedev ; Gamedev tools (C++, love2D, html5) + ; mod-shell ; Terminal emulator settings ;; Must be last - core-keymaps ; Global & local keybindings for all modes + core-keymaps ; Global & local keybindings for all modes )) (require module)) @@ -65,17 +65,17 @@ ;; Associates a mode with a path regex. If the third parameter is t, ;; then don't try to install the mode (use for modes that are included ;; with emacs). -(associate-mode 'ruby-mode '("\\.rb\\'" "\\.rake\\'" "Rakefile\\'")) -(associate-mode 'markdown-mode '("\\.md\\'" "\\.markdown\\'" "/README")) -(associate-mode 'scss-mode '("\\.scss\\'")) -(associate-mode 'org-mode '("\\.org\\'" "\\.gtd\\'") t) -(associate-mode 'js-mode '("\\.js\\'") t) -(associate-mode 'json-mode '("\\.json\\'" "\\.jshintrc\\'")) -(associate-mode 'web-mode '("\\.\\(p\\)?htm\\(l\\)?\\'" "\\.tpl\\(\\.php\\)?\\'" "\\.erb\\'")) -(associate-mode 'lua-mode '("\\.lua\\'")) -(associate-mode 'yaml-mode '("\\.yml\\'")) -(associate-mode 'python-mode '("\\.py\\'")) -(associate-mode 'c++-mode '("\\.h\\'") t) +(associate-mode 'ruby-mode '("\\.rb\\'" "\\.rake\\'" "Rakefile\\'")) +(associate-mode 'markdown-mode '("\\.md\\'" "\\.markdown\\'" "/README")) +(associate-mode 'scss-mode '("\\.scss\\'")) +(associate-mode 'org-mode '("\\.org\\'" "\\.gtd\\'") t) +(associate-mode 'js-mode '("\\.js\\'") t) +(associate-mode 'json-mode '("\\.json\\'" "\\.jshintrc\\'")) +(associate-mode 'web-mode '("\\.\\(p\\)?htm\\(l\\)?\\'" "\\.tpl\\(\\.php\\)?\\'" "\\.erb\\'")) +(associate-mode 'lua-mode '("\\.lua\\'")) +(associate-mode 'yaml-mode '("\\.yml\\'")) +(associate-mode 'python-mode '("\\.py\\'")) +(associate-mode 'c++-mode '("\\.h\\'") t) (associate-mode 'shell-script-mode '("\\.zsh\\(rc\\|env\\)?\\'") t) ;; diff --git a/init/core-editor.el b/init/core-editor.el index 0323b2c5f..9270e6b1d 100644 --- a/init/core-editor.el +++ b/init/core-editor.el @@ -1,8 +1,8 @@ (require-package 'evil) -(evil-mode nil) ;; Has to be done this way to ensure special buffers have evil, ;; evil-leader, and all the various keymaps enabled. +(evil-mode nil) (add-hook 'after-init-hook (lambda() (evil-mode 1))) ;; Now we can carry on with the rest... @@ -34,13 +34,13 @@ ;;;; Editor behavior ;;;;;;;;;;;;;;;; (setq initial-scratch-buffer nil) ; empty scratch buffer -(kill-buffer "*scratch*") +(associate-mode 'text-mode '("\\`\\*Messages\\*\\'") t) (electric-indent-mode +1) ; auto-indent on RET (global-hl-line-mode +1) ; highlight the line (setq-default tab-width 4 ; set tab width to 4 for all buffers - indent-tabs-mode t ; always replace tabs with spaces + indent-tabs-mode t ; use tabs, not spaces tab-always-indent nil) ;; do not soft-wrap lines diff --git a/init/core-keymaps.el b/init/core-keymaps.el index e103a368d..a8e463e52 100644 --- a/init/core-keymaps.el +++ b/init/core-keymaps.el @@ -72,11 +72,13 @@ ";" 'helm-imenu "," 'ido-switch-buffer "=" 'align-regexp - "X" 'kill-other-buffers + "x" 'kill-other-buffers + "X" 'kill-all-buffers ) (nmap - ";" 'evil-ex ; Remap ; to : - SPC and shift-SPC replace ; and , + ";" 'evil-ex ; Remap ; to : - SPC and shift-SPC replace ; and , + ":" 'eval-expression ; Elisp command ;; Moving rows rather than lines (in case of wrapping) "j" 'evil-next-visual-line' @@ -128,8 +130,8 @@ (vmap "gc" 'evilnc-comment-or-uncomment-lines) ;; Rotate-text (see elisp/rotate-text.el) -(nmap (kbd "RET") 'rotate-word-at-point) -(vmap (kbd "RET") 'rotate-region) +(nmap "!" 'rotate-word-at-point) +(vmap "!" 'rotate-region) ;; (imap (kbd "RET") 'comment-indent-new-line) ;; Disable return for auto-completion, since tab does the trick (define-key ac-completing-map (kbd "RET") nil) diff --git a/init/core.el b/init/core.el index be5b09ef9..c56c0da95 100644 --- a/init/core.el +++ b/init/core.el @@ -20,11 +20,15 @@ (defun kill-other-buffers () (interactive) - (mapc 'kill-buffer (cdr (buffer-list (current-buffer))))) + (mapc 'kill-buffer (cdr (buffer-list (current-buffer)))) + (message "All other buffers killed") + ) (defun kill-all-buffers () (interactive) - (mapc 'kill-buffer (buffer-list))) + (mapc 'kill-buffer (buffer-list)) + (message "All buffers killed") + ) ;;;; Advice ;;;;;;;;;;;;;;;;;;;;;;;; @@ -52,7 +56,6 @@ ad-do-it)) - ;;;; My personal minor mode ;;;;;;;; (defvar my-mode-map (make-sparse-keymap)) @@ -111,6 +114,8 @@ (defun major-mode-module-path () (expand-file-name (concat (major-mode-module-name) ".el") my-modules-dir)) +;; TODO: Write better eval-and-replace + ;;;; Macros ;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/modules/env-ruby-mode.el b/modules/env-ruby-mode.el new file mode 100644 index 000000000..ac946fd5b --- /dev/null +++ b/modules/env-ruby-mode.el @@ -0,0 +1,10 @@ + +; (require-package 'ruby-end) + +(setq ruby-indent-level 4) +(setq ruby-deep-indent-paren nil) + +(require 'ruby-mode-indent-fix) + +;; +(provide 'env-ruby-mode) diff --git a/modules/mod-ac.el b/modules/mod-ac.el index 29e69c986..b44934ecd 100644 --- a/modules/mod-ac.el +++ b/modules/mod-ac.el @@ -7,7 +7,9 @@ ;;;; Auto-completion ;;;;;;;;;;;;;; (ac-config-default) -(ac-linum-workaround) ; Fix line number flux bug +(ac-linum-workaround) ; Fix line number flux bug +(diminish 'auto-complete-mode) ; Hide mode-line entry +(define-key ac-completing-map [return] nil) (add-hook 'prog-mode-hook 'enable-path-completion) (setq ac-auto-show-menu nil ; Suggestions box must be invoked manually (see core-keymaps.el) diff --git a/modules/mod-fly.el b/modules/mod-fly.el index a18149347..0b4bbb20f 100644 --- a/modules/mod-fly.el +++ b/modules/mod-fly.el @@ -3,15 +3,18 @@ flyspell ; spell checker )) +(diminish 'flyspell-mode " ?") + (setq ispell-program-name "aspell") (setq ispell-list-command "--list") (setq flycheck-indication-mode 'right-fringe) (setq-default flycheck-disabled-checkers '(emacs-lisp-checkdoc)) -(add-hook 'prog-mode-hook #'global-flycheck-mode) -(add-hook 'text-mode-hook (lambda () (flyspell-mode 1))) -(add-hook 'conf-mode-hook (lambda () (flyspell-mode 1))) +(add-hook 'after-init-hook (lambda() (global-flycheck-mode 1))) +(dolist (hook '(markdown-mode-hook git-commit-mode-hook org-mode-hook)) + (add-hook hook (lambda() (flyspell-mode 1)))) + ;; (provide 'mod-fly) diff --git a/modules/mod-snippets.el b/modules/mod-snippets.el new file mode 100644 index 000000000..0694b7657 --- /dev/null +++ b/modules/mod-snippets.el @@ -0,0 +1,23 @@ + +;; Fix yasnippet keymaps so they only work in insert mode (why they +;; had to make this so complicated I don't know); must be defined +;; BEFORE we include yasnippet. +(defvar yas-minor-mode-map + (let ((map (make-sparse-keymap))) + (evil-define-key 'insert map [(tab)] 'yas-expand) + (evil-define-key 'insert map (kbd "TAB") 'yas-expand) + (evil-define-key 'insert map "\C-c&\C-s" 'yas-insert-snippet) + (evil-define-key 'insert map "\C-c&\C-n" 'yas-new-snippet) + (evil-define-key 'insert map "\C-c&\C-v" 'yas-visit-snippet-file) + map)) + +;; Require yasnippet *after* the minor mode map's been overwritten +(require-package 'yasnippet) + +;;;#yasnippet +(yas-global-mode t) +(associate-mode 'snippet-mode '("emacs.+/snippets/") t) +(diminish 'yas-minor-mode) + +;; +(provide 'mod-snippets)