diff options
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/ravi-ergodox-mode.el | 83 | ||||
-rw-r--r-- | lisp/ravi-init-appearance.el | 315 | ||||
-rw-r--r-- | lisp/ravi-init-cpp.el | 418 | ||||
-rw-r--r-- | lisp/ravi-init-dired.el | 149 | ||||
-rw-r--r-- | lisp/ravi-init-files.el | 159 | ||||
-rw-r--r-- | lisp/ravi-init-function.el | 35 | ||||
-rw-r--r-- | lisp/ravi-init-helm.el | 89 | ||||
-rw-r--r-- | lisp/ravi-init-ido.el | 164 | ||||
-rw-r--r-- | lisp/ravi-init-insertion.el | 136 | ||||
-rw-r--r-- | lisp/ravi-init-layouts.el | 57 | ||||
-rw-r--r-- | lisp/ravi-init-marks.el | 78 | ||||
-rw-r--r-- | lisp/ravi-init-mu.el | 196 | ||||
-rw-r--r-- | lisp/ravi-init-navigation.el | 350 | ||||
-rw-r--r-- | lisp/ravi-init-org.el | 53 | ||||
-rw-r--r-- | lisp/ravi-init-python.el | 166 | ||||
-rw-r--r-- | lisp/ravi-init-repl.el | 67 | ||||
-rw-r--r-- | lisp/ravi-init-tex.el | 189 | ||||
-rw-r--r-- | lisp/ravi-init-vc.el | 185 | ||||
-rw-r--r-- | lisp/ravi-init-web.el | 100 |
19 files changed, 2989 insertions, 0 deletions
diff --git a/lisp/ravi-ergodox-mode.el b/lisp/ravi-ergodox-mode.el new file mode 100644 index 0000000..e393a39 --- /dev/null +++ b/lisp/ravi-ergodox-mode.el @@ -0,0 +1,83 @@ +;;; ravi-ergodox-mode.el --- Keybindings fof Ergodox keyboard + +;; Copyright (C) 2014 Ravikiran Rajagopal + +;; Author: Ravikiran Rajagopal <ravi@nero.lan> +;; Keywords: convenience, hardware + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Set up keymap for ergodox bindings + +;;; Code: + +(defgroup ravi-ergodox-mode nil + "Keybindings for ergodox." + :group 'ravi-ergodox-mode) + +(defvar ravi-ergodox-mode-map (make-sparse-keymap) + "Keymaps for command `ravi-ergodox-mode-map'.") + +(defcustom ravi-ergodox-mode-disable-predicates nil + "List of predicates that disable the mode. +Each function in the list receive no argument." + :group 'ravi-ergodox-mode) + +(defcustom ravi-ergodox-mode-disabled-modes nil + "Modes where `ravi-ergodox-mode' should not activate." + :group 'ravi-ergodox-mode + :type '(repeat symbol)) + +(define-minor-mode ravi-ergodox-mode + "Enable Ergodox keyboard special bindings." + :lighter " RE" :group 'convenience + :keymap ravi-ergodox-mode-map + :global t + (if ravi-ergodox-mode + (progn + (setq x-meta-keysym 'super) + (setq x-super-keysym 'meta)) + (progn + (setq x-meta-keysym nil) + (setq x-super-keysym nil)) + ) + ) + +(define-key ravi-ergodox-mode-map (kbd "H-m") 'magit-status) +(define-key ravi-ergodox-mode-map (kbd "<f6>") 'ff-find-other-file) +(if (and (boundp 'ravi/use-helm-instead-of-ido) ravi/use-helm-instead-of-ido) + (progn + (define-key ravi-ergodox-mode-map (kbd "<f1>") 'helm-multi-files) + (define-key ravi-ergodox-mode-map (kbd "<f2>") 'helm-locate)) + (progn + (define-key ravi-ergodox-mode-map (kbd "<f1>") 'ido-switch-buffer) + (define-key ravi-ergodox-mode-map (kbd "<f2>") 'ido-find-file))) + +(defun ravi-ergodox-mode-enable () + "Turn on ergodox bindings mode." + (and (not (memq major-mode ravi-ergodox-mode-disabled-modes)) + (not (catch 'disable + (dolist (pred ravi-ergodox-mode-disable-predicates) + (and (funcall pred) + (throw 'disable t))))) + (ravi-ergodox-mode 1))) + +(defun ravi-ergodox-mode-disable () + "Turn off ergodox bindings mode." + (ravi-ergodox-mode -1)) + +(provide 'ravi-ergodox-mode) +;;; ravi-ergodox-mode.el ends here diff --git a/lisp/ravi-init-appearance.el b/lisp/ravi-init-appearance.el new file mode 100644 index 0000000..035dc1d --- /dev/null +++ b/lisp/ravi-init-appearance.el @@ -0,0 +1,315 @@ +;;; ravi-init-appearance.el --- Emacs appearance + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Customization of emacs appearance + +;;; Code: + +;; No splash screen please +(setq inhibit-startup-message t) + +;; Allow pasting selection outside of Emacs +(setq x-select-enable-clipboard t) + +;; Show keystrokes in progress +(setq echo-keystrokes 0.1) + +;; Real emacs knights don't use shift to mark things +(setq shift-select-mode nil) + +;; Enable syntax highlighting for older Emacsen that have it off +(global-font-lock-mode t) +(setq font-lock-maximum-decoration t) + +;; Sounds. +;; Turn off sound. +(setq bell-volume 0) +(setq sound-alist nil) + +(add-to-list 'default-frame-alist '(cursor-color . "#ffb90f") t) + +;; Answering just 'y' or 'n' will do +(defalias 'yes-or-no-p 'y-or-n-p) + +;; Customization of modeline. +(line-number-mode 1) +(column-number-mode 1) +(display-time) + +;; Change the way the buffer name is displayed in the modeline. +(setq-default mode-line-buffer-identification '("%17b")) + +;; Undo/redo window configuration with C-c <left>/<right> +(winner-mode 1) + +;; Never insert tabs +(set-default 'indent-tabs-mode nil) + +;; Show me empty lines after buffer end (replaced, see below) +;(set-default 'indicate-empty-lines t) + +(use-package whitespace + :init + (setq whitespace-style '(face trailing indentation tabs)) + :config + (progn + (global-whitespace-mode 1)) + ; No need for 'ensure: t' since whitespace mode is built in + :diminish global-whitespace-mode + ) + +(use-package ws-butler + :config + (progn + (ws-butler-global-mode 1)) + :diminish ws-butler-mode + :ensure t) + +(diminish 'abbrev-mode) + +;; Handling end of files. +(setq require-final-newline t) +;; Prevent addition of lines at end of file when down arrow is pressed. +(setq next-line-add-newlines nil) + +;; Kill the entire line, please +(setq kill-whole-line t) + +;; Delete hungrily +(use-package hungry-delete + :commands (hungry-delete-forward hungry-delete-backward) + :bind (("C-d" . hungry-delete-forward)) + :init + (progn + (defun jschaf/hungry-delete-backward (n &optional killflag) + "Delete non-vertical whitespace backwards on first key press. +Delete all whitespace on a successive key press." + (interactive "p\nP") + (if (eq last-command 'jschaf/hungry-delete-backward) + (hungry-delete-backward n killflag) + (let ((hungry-delete-chars-to-skip " \t\f\v")) + (hungry-delete-backward n killflag)))) + ;;(define-key global-map [remap backward-delete-char-untabify] 'jschaf/hungry-delete-backward) + (define-key global-map [remap backward-delete-char-untabify] 'hungry-delete-backward) + ) + :ensure t) + +(setq sentence-end-double-space nil) +(defun sacha/unfill-paragraph (&optional region) + "Takes a multi-line paragraph and makes it into a single line of text." + (interactive (progn + (barf-if-buffer-read-only) + (list t))) + (let ((fill-column (point-max))) + (fill-paragraph nil region))) +(bind-key "M-Q" 'sacha/unfill-paragraph) + +;; Easily navigate sillycased words +;(global-subword-mode 1) + +;; Keep cursor away from edges when scrolling up/down +(use-package smooth-scrolling + :ensure t + ) + +;; Enable automatic indentation, if possible +(use-package smart-newline + :commands (smart-newline) + :init + (progn + (bind-key "<return>" 'smart-newline prog-mode-map) + (bind-key "<return>" 'smart-newline emacs-lisp-mode-map)) + :ensure t) + +;; Case toggling: from Oleg Krehel http://oremacs.com/2014/12/25/ode-to-toggle/ +(defun oremacs/char-upcasep (letter) + (eq letter (upcase letter))) + +(defun oremacs/capitalize-word-toggle () + (interactive) + (let ((start + (car + (save-excursion + (backward-word) + (bounds-of-thing-at-point 'symbol))))) + (if start + (save-excursion + (goto-char start) + (funcall + (if (oremacs/char-upcasep (char-after)) + 'downcase-region + 'upcase-region) + start (1+ start))) + (capitalize-word -1)))) +(bind-key "M-c" 'oremacs/capitalize-word-toggle) + +(defun oremacs/upcase-word-toggle () + (interactive) + (let ((bounds (bounds-of-thing-at-point 'symbol)) + beg end + (regionp + (if (eq this-command last-command) + (get this-command 'regionp) + (put this-command 'regionp nil)))) + (cond + ((or (region-active-p) regionp) + (setq beg (region-beginning) + end (region-end)) + (put this-command 'regionp t)) + (bounds + (setq beg (car bounds) + end (cdr bounds))) + (t + (setq beg (point) + end (1+ beg)))) + (save-excursion + (goto-char (1- beg)) + (and (re-search-forward "[A-Za-z]" end t) + (funcall (if (oremacs/char-upcasep (char-before)) + 'downcase-region + 'upcase-region) + beg end))))) +(bind-key "M-l" 'oremacs/upcase-word-toggle) + +;; Zap up to char is more useful than zap-char +(use-package zop-to-char + :bind (("M-z" . zop-up-to-char) + ("M-Z" . zop-to-char)) + :ensure t) + +;; Automatic indentation of yanked text +(dolist (command '(yank yank-pop)) + (eval `(defadvice ,command (after indent-region activate) + (and (not current-prefix-arg) + (member major-mode '(emacs-lisp-mode lisp-mode + clojure-mode scheme-mode + haskell-mode ruby-mode + rspec-mode python-mode + c-mode c++-mode + objc-mode latex-mode + plain-tex-mode)) + (let ((mark-even-if-inactive transient-mark-mode)) + (indent-region (region-beginning) (region-end) nil)))))) + +(use-package comment-dwim-2 + :bind (("M-;" . comment-dwim-2)) + :ensure t) + +;; Keep my navigation simple +(setq line-move-visual nil) + +;; Represent undo-history as an actual tree (visualize with C-x u) +(use-package undo-tree + :init + (setq undo-tree-mode-lighter "") + :config + (progn + (global-undo-tree-mode) + (setq undo-tree-auto-save-history t) + (setq undo-tree-history-directory-alist + `(("." . ,(expand-file-name "undotree/" (ravi/emacs-file "past"))))) + ) + :ensure t + ) + +;; Discover emacs +;; Since discover.el replaces keymaps wholesale for "C-x r" and "M-s", it overrides +;; our additions to them. So we use guide-key for "C-x r" and "M-s". +(use-package discover + :config + (progn + (add-hook 'dired-mode-hook 'discover-turn-on-in-dired) + ) + :disabled t ;; unstable API and hosing user-provided keybindings + :ensure t + ) + +;; Help for prefix key-bindings not in discover-mode +(use-package guide-key + :config + (progn + (setq guide-key/guide-key-sequence '("C-c p" ;; projectile + "C-c d" ;; doxymacs + "C-x 4" ;; other-window + "C-x r" ;; rectangles/registers + "M-s" ;; isearch + "C-x v" ;; version control + "M-g" ;; movement + "C-x 5" ;; frames + "C-x n" ;; narrowing + )) + (when (and (boundp ravi/use-helm-instead-of-ido) ravi/use-helm-instead-of-ido) + (add-to-list 'guide-key/guide-key-sequence "<escape>")) + + (guide-key-mode 1) + + (use-package guide-key-tip + :config + (progn + (setq guide-key-tip/enabled t)) + :ensure t + :disabled t ;; popups don't always go away; need to file a bug report + ) + ) + :diminish guide-key-mode + :ensure t + ) + +(bind-key "C-h a" 'apropos) + +(use-package popwin + :init + (progn + (popwin-mode 1) + (push '("*Pp Eval Output*" :height 15) popwin:special-display-config)) + :ensure t + ) + +(use-package import-popwin + :bind (("M-i" . import-popwin)) + :ensure t + ) + +(use-package ace-window + :bind (("M-o" . ace-window)) + :init + (progn + (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l ?i ?e))) + :ensure t + ) + +(defun ravi/split-window-vertically-and-switch (prefix) + (interactive "P") + (split-window-vertically (if (consp prefix) nil prefix)) + (other-window 1) + (unless (consp prefix) (switch-to-next-buffer))) +(bind-key "C-x 2" 'ravi/split-window-vertically-and-switch) + +(defun ravi/split-window-horizontally-and-switch (prefix) + (interactive "P") + (split-window-horizontally (if (consp prefix) nil prefix)) + (other-window 1) + (unless (consp prefix) (switch-to-next-buffer))) +(bind-key "C-x 3" 'ravi/split-window-horizontally-and-switch) + +(provide 'ravi-init-appearance) +;;; ravi-init-appearance.el ends here diff --git a/lisp/ravi-init-cpp.el b/lisp/ravi-init-cpp.el new file mode 100644 index 0000000..5fe9e8f --- /dev/null +++ b/lisp/ravi-init-cpp.el @@ -0,0 +1,418 @@ +;;; ravi-init-cpp.el --- C/C++ handling + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; C/C++ initialization + +;;; Code: + +; Generate a random string (of letters and numbers) of a given length +(defun ravi-random-ucn-string (len) + (coerce (loop for i below len for x = (random 36) collect + (+ x + (cond ((< x 10) 48) + ((< x 36) (- 65 10)) + ))) + 'string)) + +(use-package cmake-mode + :mode (("CMakeLists\\.txt\\'" . cmake-mode) + ("\\.cmake\\'" . cmake-mode)) + ;:ensure t + ) + +(defvar get-buffer-compile-command (lambda (file) (cons file 1))) +(make-variable-buffer-local 'get-buffer-compile-command) + +(setq-default compile-command "") + +(defun compile-dwim (&optional arg) + "Compile Do What I Mean. + Compile using `compile-command'. + When `compile-command' is empty prompt for its default value. + With prefix C-u always prompt for the default value of + `compile-command'. + With prefix C-u C-u prompt for buffer local compile command with + suggestion from `get-buffer-compile-command'. An empty input removes + the local compile command for the current buffer." + (interactive "P") + (cond + ((and arg (> (car arg) 4)) + (let ((cmd (read-from-minibuffer + "Buffer local compile command: " + (funcall get-buffer-compile-command + (or (file-relative-name (buffer-file-name)) "")) + nil nil 'compile-history))) + (cond ((equal cmd "") + (kill-local-variable 'compile-command) + (kill-local-variable 'compilation-directory)) + (t + (set (make-local-variable 'compile-command) cmd) + (set (make-local-variable 'compilation-directory) + default-directory)))) + (when (not (equal compile-command "")) + ;; `compile' changes the default value of + ;; compilation-directory but this is a buffer local + ;; compilation + (let ((dirbak (default-value 'compilation-directory))) + (compile compile-command) + (setq-default compilation-directory dirbak)))) + ((or (and arg (<= (car arg) 4)) + (equal compile-command "")) + (setq-default compile-command (read-shell-command + "Compile command: " + (if (equal compile-command "") + "make " compile-command) + 'compile-history)) + (setq-default compilation-directory default-directory) + (when (not (equal (default-value 'compile-command) "")) + (compile (default-value 'compile-command)))) + (t + (recompile)))) + + +(use-package cc-mode + + :mode (("\\.h\\(h?\\|xx\\|pp\\)\\'" . c++-mode) + ("\\.ccfg\\'" . c++-mode) + ("\\.m\\'" . c-mode) + ("\\.mm\\'" . c++-mode)) + :init + (progn + (use-package doxymacs + :load-path (lambda () (ravi/emacs-file "site-lisp/doxymacs/lisp")) + :config + (progn + (doxymacs-mode) + (setq doxymacs-file-comment-template + '("/**" > n + " * " (doxymacs-doxygen-command-char) "file" > n + " * " > n + " * " (doxymacs-doxygen-command-char) "brief " + (p "Brief description of this file: ") > n + " */" > n) + ) + (setq doxymacs-external-xml-parser-executable + (ravi/emacs-file "site-lisp/doxymacs/c/doxymacs_parser")) + (setq doxymacs-use-external-xml-parser t) + (setq doxymacs-command-character "\\") + ) + :diminish doxymacs-mode + ) + + (defvar printf-index 0) + + (defun insert-counting-printf (arg) + (interactive "P") + (if arg + (setq printf-index 0)) + (if t + (insert (format "std::cerr << \"step %d..\" << std::endl;\n" + (setq printf-index (1+ printf-index)))) + (insert (format "printf(\"step %d..\\n\");\n" + (setq printf-index (1+ printf-index))))) + (forward-line -1) + (indent-according-to-mode) + (forward-line)) + + ) + + :config + (progn + + (defun my-c-mode-common-hook () + (hs-minor-mode 1) + (hs-hide-initial-comment-block) + (hide-ifdef-mode 1) + (which-function-mode 1) + + (diminish 'hs-minor-mode) + (diminish 'hide-ifdef-mode) + + (bind-key "C-c p" 'insert-counting-printf c-mode-base-map) + + (doxymacs-mode 1) + (doxymacs-font-lock) + + ;(define-key c-mode-base-map [return] 'c-context-line-break) + (bind-key "<return>" 'c-context-line-break c-mode-base-map) + + (unbind-key "M-j" c-mode-base-map) + (bind-key "C-c C-i" 'c-includes-current-file c-mode-base-map) + (when (and (featurep 'ravi-ergodox-mode) ravi-ergodox-mode) + (bind-key "H-h" 'compile-dwim c-mode-base-map)) + + (set (make-local-variable 'parens-require-spaces) t) + (setq fill-column 88) + + (bind-key "M-q" 'c-fill-paragraph c-mode-base-map) + + (c-toggle-electric-state 1) + (c-toggle-auto-newline 1) + (c-toggle-hungry-state 1) + + (c-set-style "stroustrup") + (setq c-basic-offset 2) + (setq c-recognize-knr-p nil) + (modify-syntax-entry ?_ "w" c-mode-syntax-table) + (add-to-list 'c-cleanup-list 'empty-defun-braces) + (add-to-list 'c-cleanup-list 'defun-close-semi) + (add-to-list 'c-cleanup-list 'list-close-comma) + (add-to-list 'c-cleanup-list 'scope-operator) + ;; one-liner-defun and comment-close-slash found to be annoying + + (font-lock-add-keywords 'c++-mode '(("\\<\\(assert\\|DEBUG\\)(" + 1 font-lock-warning-face t)))) + + (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) + + (defun my-c++-mode-hook () + (setq c-offsets-alist + (append '((statement-cont . c-lineup-math) + (inline-open . 0)) + c-offsets-alist)) + (let ((innamespaceindent (if (and (buffer-file-name) + (string-equal "ccfg" (file-name-extension (buffer-file-name)))) + 2 0)) + ) + (setq c-offsets-alist + (append `((innamespace . ,innamespaceindent) + ) + c-offsets-alist)) + ) + + (modify-syntax-entry ?_ "w" c++-mode-syntax-table) + (setq c-macro-cppflags "-x c++") + (setq c-macro-prompt-flag t) + ) + (add-hook 'c++-mode-hook 'my-c++-mode-hook) + + ;; Stuff from kde-emacs + (defvar kde-header-protection-parts-to-show 1 + "Set this variable to the number of parts from the file name you want to +be used for the defined word in the header-protection function.. E.g. setting +this to 3 makes header-protection define KIG_MISC_NEWTYPE_H for a file named +/home/domi/src/kdenonbeta/kig/misc/newtype.h") + + (defun kde-header-protection-definable-string () + (let* ((definablestring (concat "_" (ravi-random-ucn-string 6)) ) + (f (buffer-file-name)) + (parts (nreverse (split-string f "/"))) + (i) + (first-iter t) + (iters (min (length parts) kde-header-protection-parts-to-show))) + (dotimes (i iters) + (let ((part (pop parts))) + (setq definablestring + (concat + (upcase (replace-regexp-in-string "[\\.-]" "_" part)) + (if (not first-iter) "_" "") + definablestring + ) + ) + (setq first-iter nil) + ) + ) + definablestring + ) + ) + + ;; Creates the ifndef/define/endif statements necessary for a header file + (defun header-protection () + (interactive) + (let ((s (kde-header-protection-definable-string))) + (save-excursion + (goto-char (point-min)) + (insert "#ifndef " s "\n#define " s "\n\n") + (goto-char (point-max)) + (insert "\n#endif\n") + ) + ) + ) + + (defun ravi-start-c++-header () + "Start a new C++ header by inserting include guards ( see \ + header-protection function ), inserting a license statement \ + and putting (point) at the correct position" + (interactive) + (header-protection) + (insert "\n") + (beginning-of-buffer) + + (save-excursion + (let ((start (point-min)) + (comment-style 'box) + (end) + ) + (goto-char start) + (insert (ravi-license-header)) + (setq end (point)) + (comment-region start end) + ) + ) + + (end-of-buffer) + (next-line -3) + (insert "\n") + (doxymacs-insert-file-comment) + ) + + (setq auto-insert-query nil) + (define-auto-insert "\\.\\([Cc]\\|cc\\|cpp\\|cxx\\|tcc\\)\\'" + 'ravi-auto-insert-cpp) + (define-auto-insert "\\.\\([Hh]\\|hh\\|hpp\\)\\'" 'ravi-start-c++-header) + + (defun ravi-license-insert () + (progn + (let ((start (point-min)) + (comment-style 'box) + (end) + ) + (goto-char start) + (insert (ravi-license-header)) + (insert "\n") + (setq end (point)) + (comment-region start end)))) + + (defun ravi-auto-insert-cpp () + (progn + (ravi-license-insert) + (doxymacs-insert-file-comment))) + + (defun ravi/add-space-before-paren-c (&rest ignored) + (message "Handler invoked") + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\)(") + (save-excursion + (backward-char) + (insert-char ?\s) + ) + )) + + (defadvice c-electric-paren (after ravi/add-space-around-parens activate) + (unless (c-in-literal) + (cond + ((looking-back "([[:space:]]*") + (progn + ;; Open parenthesis was the last command; add a space before it if + ;; necessary, and ensure that the point is placed after a space + (save-excursion + (re-search-backward "([[:space:]]*") + (unless (looking-at "(") (message "Logic error; opening paren not found")) + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)") + (insert-char ?\s))) + (if (and (looking-at " ") (not (looking-at " )"))) + (forward-char) + (insert-char ?\s)) + ) + ) + ((looking-back ")[[:space:]]*") + ;; Closing parenthesis was the last command; add spaces if necessary + (progn + ;; Compact empty function calls + (when (looking-back "([[:space:]]+)[[:space:]]*") + (save-excursion + (re-search-backward ")[[:space:]]*") + (delete-horizontal-space) + ) + ) + + ;; Add space before closing parenthesis + (unless (looking-back "()[[:space:]]*") + (save-excursion + (re-search-backward ")[[:space:]]*") + (unless (looking-at ")") (message "Logic error; closing paren not found")) + (unless (looking-back " ") (insert-char ?\s))) + ) + + (let (need-to-add-newline) + (save-excursion + (c-backward-sexp) + (c-backward-syntactic-ws) + ;; FIXME: do-while loops are not handled correctly + (setq need-to-add-newline (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)")) + ) + (when need-to-add-newline (c-newline-and-indent))) + ) + ) + )) + ) + + (defadvice c-electric-semi&comma (after ravi/add-space-after-comma activate) + (cond + ((looking-back ",") + (if (looking-at " [^)]") (forward-char) (insert-char ?\s))) + ((looking-back ") ;[[:space:]\n]*") + (save-excursion + (re-search-backward " ;[[:space:]\n]*") + (delete-char 1))))) + + ;; Do not activate region as it interferes with region-bindings-mode + (defadvice c-electric-brace (after ravi/do-not-activate-region activate) + (deactivate-mark)) + + (defmacro ravi/fake-send-key (key-to-bind char-to-bind) + (let ((command (key-binding key-to-bind))) + (setq last-command-event char-to-bind) + (setq this-command command) + (call-interactively command)) + ) + + (defun ravi/insert-closing-delimiter() + (interactive) + (if (c-in-literal) + (self-insert-command) + (progn + ;; Find nearest unmatched opening delimiter + (let (brace-type) + (save-excursion + (backward-up-list) + (cond + ((looking-at "{") (setq brace-type 'brace-type-brace)) + ((looking-at "(") (setq brace-type 'brace-type-paren)) + ((looking-at "\\[") (setq brace-type 'brace-type-square)) + (t (setq brace-type 'brace-type-none)) + )) + (cond + ((eq brace-type 'brace-type-brace) (ravi/fake-send-key "}" ?\})) + ((eq brace-type 'brace-type-paren) (ravi/fake-send-key ")" ?\))) + ; Uncommenting the line below would lead to infinite recursion + ;((eq 'brace-type 'brace-type-square) (ravi/fake-send-key "]" ?\])) + (t (self-insert-command 1)) + ) + )))) + + (bind-key "]" 'ravi/insert-closing-delimiter c-mode-base-map) + + (bind-key "<M-f8>" 'compile-dwim c-mode-base-map) + + (bind-key "<M-f5>" 'hs-hide-block c-mode-base-map) + (bind-key "<M-f11>" 'hs-show-block c-mode-base-map) + + (setq hide-ifdef-initially nil) + (bind-key "<S-f5>" 'hide-ifdef-block c-mode-base-map) + (bind-key "<S-f11>" 'show-ifdef-block c-mode-base-map) + + ;; (setq c-syntactic-indentation nil) + ) + ) + +(provide 'ravi-init-cpp) +;;; ravi-init-cpp.el ends here diff --git a/lisp/ravi-init-dired.el b/lisp/ravi-init-dired.el new file mode 100644 index 0000000..0c8fab2 --- /dev/null +++ b/lisp/ravi-init-dired.el @@ -0,0 +1,149 @@ +;;; ravi-init-dired.el --- dired setup + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Mostly stolen from Fuco's configuration + +;; Dired setup + +;;; Code: + +(use-package dired + :defer t + :config + (progn + (defun ravi/dired-init-hook () + (dired-filter-mode t) + (visual-line-mode -1) + (toggle-truncate-lines 1)) + (add-hook 'dired-mode-hook 'ravi/dired-init-hook) + + (use-package image-dired) + (use-package dired-aux) + (use-package dired-x + :config + (defun dired-virtual-revert (&optional _arg _noconfirm) + "Enable revert for virtual direds." + (let ((m (dired-file-name-at-point)) + (buffer-modified (buffer-modified-p))) + (goto-char 1) + (dired-next-subdir 1) + (dired-do-redisplay nil t) + (while (dired-next-subdir 1 t) + (dired-do-redisplay nil t)) + (when m (dired-goto-file m)) + (set-buffer-modified-p buffer-modified)))) + + (use-package dired-details + :commands dired-details-toggle + :ensure t + ) + (use-package w32-browser + :commands dired-w32-browser + :ensure t + ) + + (use-package dired-subtree + :ensure t + :config + (progn + (bind-keys :map dired-mode-map + :prefix "," + :prefix-map dired-subtree-map + :prefix-docstring "Dired subtree map." + ("/" . dired-subtree-apply-filter) + ("k" . dired-subtree-remove) + ("n" . dired-subtree-next-sibling) + ("p" . dired-subtree-previous-sibling) + ("u" . dired-subtree-up) + ("d" . dired-subtree-down) + ("a" . dired-subtree-beginning) + ("e" . dired-subtree-end) + ("m" . dired-subtree-mark-subtree) + ("u" . dired-subtree-unmark-subtree) + ("C-o C-f" . dired-subtree-only-this-file) + ("C-o C-d" . dired-subtree-only-this-directory)) + (bind-key "e" 'dired-subtree-insert dired-mode-map)) + ) + + (defconst my-dired-media-files-extensions '("mp3" "mp4" "MP3" "MP4" "avi" "mpg" "flv" "ogg") + "Media file extensions that should launch in VLC. + +Also used for highlighting.") + + (use-package dired-rainbow + :config + (progn + (dired-rainbow-define html "#4e9a06" ("htm" "html" "xhtml")) + (dired-rainbow-define xml "DarkGreen" ("xml" "xsd" "xsl" "xslt" "wsdl")) + + (dired-rainbow-define document "#fce94f" ("doc" "docx" "odt" "pdb" "pdf" "ps" "rtf")) + (dired-rainbow-define media "#ce5c00" my-dired-media-files-extensions) + (dired-rainbow-define image "#ff4b4b" ("jpg" "png" "jpeg" "gif")) + + (dired-rainbow-define log "#c17d11" ("log")) + (dired-rainbow-define sourcefile "#fcaf3e" ("py" "c" "cc" "h" "java" "pl" "rb")) + + (dired-rainbow-define executable "#8cc4ff" ("exe" "msi")) + (dired-rainbow-define compressed "#ad7fa8" ("zip" "bz2" "tgz" "txz" "gz" "xz" "z" "Z" "jar" "war" "ear" "rar" "sar" "xpi" "apk" "xz" "tar")) + (dired-rainbow-define packaged "#e6a8df" ("deb" "rpm")) + (dired-rainbow-define encrypted "LightBlue" ("gpg" "pgp"))) + :ensure t) + + (add-to-list 'dired-guess-shell-alist-user (list (regexp-opt my-dired-media-files-extensions) + "vlc")) + + (use-package dired-filter + :ensure t + ) + + (use-package dired-open + :config + (progn + (bind-key "E" 'dired-open-xdg dired-mode-map)) + :ensure t) + + (use-package dired-avfs + :ensure t + :disabled t ; avfs not in Fedora repositories yet + ) + + (require 'dash) + (--each '(dired-do-rename + dired-do-copy + dired-create-directory + wdired-abort-changes) + (eval `(defadvice ,it (after revert-buffer activate) + (revert-buffer)))) + + (defun ravi/dired-guide-key-hook () + (guide-key/add-local-guide-key-sequence "%") + (guide-key/add-local-guide-key-sequence "*") + (guide-key/add-local-guide-key-sequence "/") + (guide-key/add-local-guide-key-sequence ",") + (guide-key/add-local-guide-key-sequence "C-t") + ) + (add-hook 'dired-mode-hook 'ravi/dired-guide-key-hook) + + )) + +(provide 'ravi-init-dired) +;;; ravi-init-dired.el ends here diff --git a/lisp/ravi-init-files.el b/lisp/ravi-init-files.el new file mode 100644 index 0000000..9ac482d --- /dev/null +++ b/lisp/ravi-init-files.el @@ -0,0 +1,159 @@ +;;; ravi-init-files.el --- file-handling + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; File handling + +;;; Code: + +(setq auto-save-list-file-prefix (ravi/emacs-file "past/auto-save-list/.saves-")) +(setq delete-auto-save-files t) +(setq dired-listing-switches "-Flag") +(setq completion-ignored-extensions + (append completion-ignored-extensions + (quote (".bak" ".#*#" ".ps" ".pdf")))) + +;; Auto refresh buffers +(global-auto-revert-mode 1) + +;; Also auto refresh dired, but be quiet about it +(setq global-auto-revert-non-file-buffers t) +(setq global-auto-revert-ignore-modes '(TeX-output-mode)) +(setq auto-revert-verbose nil) + +;; Transparently open compressed files +(auto-compression-mode t) + +;; 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 history-length 100) +(setq savehist-file (ravi/emacs-file "past/history")) +(savehist-mode 1) +(setq history-delete-duplicates t) + +(require 'saveplace) +(setq-default save-place t) +(setq save-place-file (ravi/emacs-file "past/places")) + +(use-package recentf + :init + (progn + (setq recentf-save-file (ravi/emacs-file "past/recentf")) + (setq recentf-max-saved-items 100) ;; just 20 is too recent + ) + :config + (progn + (add-to-list 'recentf-exclude "/COMMIT_EDITMSG$") + (add-to-list 'recentf-exclude "/kmail[[:alnum:]]*\\.tmp$") + (add-to-list 'recentf-exclude "/elpa/.*/*-autoloads.el$") + )) + +(require 'uniquify) +(setq uniquify-buffer-name-style 'post-forward) +(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified +(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers + +(setq minibuffer-completion-confirm t) +(setq find-file-confirm-nonexistent-file t) +(setq find-file-visit-truename t) + +;; Automatic loading of file trees +(defun ravi-check-dir-accessible-p (name) + "Check whether NAME is accessible as a directory" + (let* ((topname (file-name-as-directory name)) + (name-exists (and (file-exists-p topname) + (file-directory-p topname) + (file-accessible-directory-p topname) + topname))) + name-exists + )) + +(defun ravi-filecache-add-tree (root recursive simple) + "Add list of directories to filecache for easy opening. +ROOT is the root of the tree to be added. RECURSIVE is a list of +relative paths whose subdirectories are added recursively, while +relative paths in SIMPLE are added non-recursively. If a path does +not exist, it is not added to the filecache." + + (let ((topname (ravi-check-dir-accessible-p root)) + (dirval nil)) + (when topname + (dolist (dir recursive) + (setq dirval (ravi-check-dir-accessible-p + (expand-file-name dir topname))) + (and dirval + (file-cache-add-directory-recursively dirval))) + (dolist (dir simple) + (setq dirval (ravi-check-dir-accessible-p + (expand-file-name dir topname))) + (and dirval + (file-cache-add-directory dirval))) + ))) + +;; Write backup files to own directory +(make-directory (ravi/emacs-file "past/backups/") t) +(setq backup-by-copying t) +(setq backup-directory-alist + `(("." . ,(ravi/emacs-file "past/backups/")) + (,tramp-file-name-regexp nil))) + +;; Make backups of files, even when they're in version control +(setq vc-make-backup-files t) + +;; Git/svn/etc. projects +(use-package projectile + :init + (progn + (use-package pkg-info + :ensure t + ) + (setq projectile-known-projects-file + (ravi/emacs-file "past/projectile-bookmarks.eld")) + ) + :config + (progn + (projectile-global-mode) + + (when (and (boundp 'ravi/use-helm-instead-of-ido) ravi/use-helm-instead-of-ido) + + (setq projectile-completion-system 'helm) + + (use-package helm-projectile + :config + (helm-projectile-on) + :ensure t) + )) + :diminish projectile-mode + :ensure t + ) + +;; Use emacsclient as external editor for kmail +(add-to-list 'auto-mode-alist + (cons (concat temporary-file-directory ".*/kmail[[:alnum:]]*.tmp\\'") 'message-mode)) +(setq gnus-message-highlight-citation t) + +(provide 'ravi-init-files) +;;; ravi-init-files.el ends here diff --git a/lisp/ravi-init-function.el b/lisp/ravi-init-function.el new file mode 100644 index 0000000..671d45c --- /dev/null +++ b/lisp/ravi-init-function.el @@ -0,0 +1,35 @@ +;;; ravi-init-function.el --- functionality + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Enable functionality + +;;; Code: + +;; Enable emacs functionality that is disabled by default +(setq disabled-command-function nil) +;(setq enable-recursive-minibuffers t) + +;; Use emacsclient from other programs +(unless (server-running-p) (server-start)) + +(provide 'ravi-init-function) +;;; ravi-init-function.el ends here diff --git a/lisp/ravi-init-helm.el b/lisp/ravi-init-helm.el new file mode 100644 index 0000000..5ff7f9d --- /dev/null +++ b/lisp/ravi-init-helm.el @@ -0,0 +1,89 @@ +;;; ravi-init-helm.el --- helm initialization -*- lexical-binding: t; -*- + +;; Copyright (C) 2015 + +;; Author: <ravi@nero.lan> +;; Keywords: abbrev + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Initialize helm instead of ido. The code in this file may steal +;; global keybindings that are currently used for ido-mode/smex. + +;;; Code: + +(use-package helm + :bind (("<escape>" . helm-command-prefix) + ("M-x" . helm-M-x) + ("<f1>" . helm-multi-files) + ("<f2>" . helm-locate) + ("M-y" . helm-show-kill-ring) + ("H-`" . helm-all-mark-rings)) + :init + (progn + (require 'helm-config) + (setq helm-candidate-number-limit 100) + + ;; From https://gist.github.com/antifuchs/9238468 + (setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't). + helm-input-idle-delay 0.01 ; this actually updates things + helm-quick-update t + helm-M-x-requires-pattern nil + helm-ff-skip-boring-files t) + + (setq helm-ff-file-name-history-use-recentf t) + + (helm-mode)) + :config + (progn + (unbind-key "C-x c") ; default helm prefix key + (bind-key "<tab>" 'helm-execute-persistent-action helm-map) + (bind-key "H-<tab>" 'helm-select-action helm-map) + + (use-package helm-ag + :ensure t)) + :if ravi/use-helm-instead-of-ido + :diminish helm-mode + :ensure t) + +(use-package helm-swoop + :bind (("M-I" . helm-swoop)) + :commands helm-swoop-from-isearch + :init + (progn + (bind-key "M-i" 'helm-swoop-from-isearch isearch-mode-map) + ) + :config + (progn + (bind-key "M-i" 'helm-multi-swoop-all-from-helm-swoop helm-swoop-map) + + ;; Save buffer when helm-multi-swoop-edit complete + (setq helm-multi-swoop-edit-save t) + + ;; If this value is t, split window inside the current window + ;; (setq helm-swoop-split-with-multiple-windows nil) + + ;; Split direcion. 'split-window-vertically or 'split-window-horizontally + ;; (setq helm-swoop-split-direction 'split-window-vertically) + ) + :ensure t) + +(use-package helm-descbinds + :bind (("C-h b" . helm-descbinds)) + :ensure t) + +(provide 'ravi-init-helm) +;;; ravi-init-helm.el ends here diff --git a/lisp/ravi-init-ido.el b/lisp/ravi-init-ido.el new file mode 100644 index 0000000..93af3e6 --- /dev/null +++ b/lisp/ravi-init-ido.el @@ -0,0 +1,164 @@ +;;; ravi-init-ido.el --- ido initialization + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Ido initialization + +;;; Code: + +;; Almost all of the code below is stolen from jwiegley's .emacs.d. + +(use-package ibuffer + :bind ("C-x C-b" . ibuffer) + :config + (progn + + (use-package ibuffer-vc + :ensure t + :commands ibuffer-vc-set-filter-groups-by-vc-root + ) + + ;; Switching to ibuffer puts the cursor on the most recent past buffer + (defadvice ibuffer (around ibuffer-point-to-most-recent-but-one activate) () + "Open ibuffer with cursor pointed to most recent buffer name" + (let ((recent-buffer-name (buffer-name (other-buffer (current-buffer) t)))) + ad-do-it + (ibuffer-jump-to-buffer recent-buffer-name))) + + (defun ravi/ibuffer-vc-sort-hook () + (ibuffer-vc-set-filter-groups-by-vc-root) + (unless (eq ibuffer-sorting-mode 'alphabetic) + (ibuffer-do-sort-by-alphabetic))) + (add-hook 'ibuffer-hook 'ravi/ibuffer-vc-sort-hook) + ) + ) + +(use-package ace-jump-buffer + :bind (("M-<f1>" . ace-jump-buffer) + ("C-<f1>" . ace-jump-buffer-other-window) + ("S-<f1>" . ace-jump-projectile-buffers)) + ;; :config + ;; (progn + ;; (bind-key "M-<f1>" 'ido-switch-buffer)) + :ensure t) + +;;;_ , ido + +(use-package ido + :defines (ido-cur-item + ido-require-match + ido-selected + ido-final-text + ido-show-confirm-message) + :if (not ravi/use-helm-instead-of-ido) + :init + (ido-mode 1) + + :config + (progn + (use-package ido-hacks + :config + (ido-hacks-mode 1) + :ensure t + ) + + (use-package flx-ido + :config + (progn + (use-package flx + :ensure t) + (flx-ido-mode 1) + ) + :ensure t + ) + (setq ido-use-filename-at-point 'guess) + (setq ido-use-virtual-buffers t) + (setq ido-create-new-buffer 'always) + + (use-package ido-ubiquitous + :config + (ido-ubiquitous-mode t) + :ensure t + ) + + (use-package ido-vertical-mode + :config + (ido-vertical-mode 1) + :ensure t + ) + + (defun ido-smart-select-text () + "Select the current completed item. Do NOT descend into directories." + (interactive) + (when (and (or (not ido-require-match) + (if (memq ido-require-match + '(confirm confirm-after-completion)) + (if (or (eq ido-cur-item 'dir) + (eq last-command this-command)) + t + (setq ido-show-confirm-message t) + nil)) + (ido-existing-item-p)) + (not ido-incomplete-regexp)) + (when ido-current-directory + (setq ido-exit 'takeprompt) + (unless (and ido-text (= 0 (length ido-text))) + (let ((match (ido-name (car ido-matches)))) + (throw 'ido + (setq ido-selected + (if match + (replace-regexp-in-string "/\\'" "" match) + ido-text) + ido-text ido-selected + ido-final-text ido-text))))) + (exit-minibuffer))) + + (add-hook 'ido-minibuffer-setup-hook + #'(lambda () + (bind-key "<return>" 'ido-smart-select-text + ido-file-completion-map))) + + (defun ido-switch-buffer-tiny-frame (buffer) + (interactive (list (ido-read-buffer "Buffer: " nil t))) + (with-selected-frame + (make-frame '((width . 80) + (height . 22) + (left-fringe . 0) + (right-fringe . 0) + (vertical-scroll-bars . nil) + (unsplittable . t) + (has-modeline-p . nil) + ;;(background-color . "grey80") + (minibuffer . nil))) + (switch-to-buffer buffer) + (set (make-local-variable 'mode-line-format) nil))) + + (bind-key "C-x 5 t" 'ido-switch-buffer-tiny-frame))) + +(use-package smex + :init + (global-set-key [remap execute-extended-command] 'smex) + :if (not ravi/use-helm-instead-of-ido) + :ensure t + ) + +(provide 'ravi-init-ido) +;;; ravi-init-ido.el ends here diff --git a/lisp/ravi-init-insertion.el b/lisp/ravi-init-insertion.el new file mode 100644 index 0000000..65ff9db --- /dev/null +++ b/lisp/ravi-init-insertion.el @@ -0,0 +1,136 @@ +;;; ravi-init-insertion.el --- inserting text + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Automatic text insertion + +;;; Code: + +(require 'autoinsert) +(auto-insert-mode) + +(use-package yasnippet + :init + (progn + (setq yas-snippet-dirs + `(,(ravi/emacs-file "snippets") + yas-installed-snippets-dir) + ) + ) + :config + (progn + (yas-global-mode 1) + + ;; No dropdowns + (setq yas/prompt-functions '(yas/ido-prompt yas/completing-prompt)) + + ;; Wrap around region + (setq yas/wrap-around-region t) + + ;; Automatically create throw-away snippets + (use-package auto-yasnippet + :bind (("C-<f4>" . aya-create) + ("<f4>" . aya-expand)) + :ensure t) + ) + :ensure t + :diminish yas-minor-mode + ) + +;; Default completion (some day via "M-/") +(require 'hippie-exp) +(setq hippie-expand-try-functions-list + '(yas/hippie-try-expand + try-expand-dabbrev + try-expand-dabbrev-all-buffers + try-expand-dabbrev-from-kill + try-complete-file-name-partially + try-complete-file-name + try-expand-all-abbrevs + ) + ) + +(use-package company + :init + (progn + (add-hook 'after-init-hook 'global-company-mode)) + :config + (progn + (setq company-tooltip-flip-when-above t + company-idle-delay 0.1 + company-show-numbers t + company-tooltip-align-annotations t + company-require-match nil + company-minimum-prefix-length 2 + company-occurrence-weight-function 'company-occurrence-prefer-any-closest + company-dabbrev-downcase nil) + (defun ravi/complete-or-indent () + (interactive) + (if (company-manual-begin) + (company-complete-common) + (indent-according-to-mode))) + (bind-key "\t" 'ravi/complete-or-indent) + + (use-package company-c-headers + :init + (progn + (add-to-list 'company-backends 'company-c-headers)) + :config + (progn + (defun ravi/get-default-include-paths () + (let* ((gcc-out (shell-command-to-string "g++ -E -x c++ - -v < /dev/null")) + (gcc-list-match (string-match "#include <...> search starts here:\n\\(.*\\(?:\n.*\\)*?\\)End of search list.\n" gcc-out)) + (combined-list (match-string 1 gcc-out)) + ;; Need the following rigamarole to handle paths with spaces in them + (path-list-with-spaces (and combined-list (split-string combined-list "\n" t))) + (path-list (and path-list-with-spaces (mapcar 's-trim-left path-list-with-spaces)))) + path-list)) + (mapc (lambda (dir) (add-to-list 'company-c-headers-path-system dir)) (ravi/get-default-include-paths)) + ) + :ensure t) + + (use-package company-quickhelp + :config + (company-quickhelp-mode 1) + :ensure t) + + (use-package company-statistics + :init + (setq company-statistics-file (expand-file-name "company-statistics-cache.el" + (ravi/emacs-file "past"))) + :config + (progn + (company-statistics-mode)) + :ensure t) + + ;; Get rid of company-semantic as it interferes with clang-based backends + (setq company-backends (delete 'company-semantic company-backends)) + ;; Get rid of company-clang since it is too noisy at this point + (setq company-backends (delete 'company-clang company-backends)) + + (require 'company-yasnippet) + (bind-key "<backtab>" 'company-yasnippet)) + + :diminish company-mode + :ensure t) + +(provide 'ravi-init-insertion) +;;; ravi-init-insertion.el ends here diff --git a/lisp/ravi-init-layouts.el b/lisp/ravi-init-layouts.el new file mode 100644 index 0000000..f6199ce --- /dev/null +++ b/lisp/ravi-init-layouts.el @@ -0,0 +1,57 @@ +;;; ravi-init-layouts.el --- layouts + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Uses undocumented emacs API + +;;; Code: + +(require 'quail) + +(quail-define-package + "english-prog" "English programmer" "EN-P" t + "English programmer's keyboard." + nil t nil nil t nil nil nil nil nil t) + +(quail-define-rules + ("!" ?1) + ("@" ?2) + ("#" ?3) + ("$" ?4) + ("%" ?5) + ("^" ?6) + ("&" ?7) + ("*" ?8) + ("(" ?9) + (")" ?0) + ("1" ?!) + ("2" ?@) + ("3" ?#) + ("4" ?$) + ("5" ?%) + ("6" ?^) + ("7" ?&) + ("8" ?*) + ("9" ?\() + ("0" ?\))) + +(provide 'ravi-init-layouts) +;;; ravi-init-layouts.el ends here diff --git a/lisp/ravi-init-marks.el b/lisp/ravi-init-marks.el new file mode 100644 index 0000000..803b2cb --- /dev/null +++ b/lisp/ravi-init-marks.el @@ -0,0 +1,78 @@ +;;; ravi-init-marks.el --- Handling the mark + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Handling the mark + +;;; Code: + +;; Show active region +(transient-mark-mode 1) +(make-variable-buffer-local 'transient-mark-mode) +(put 'transient-mark-mode 'permanent-local t) +(setq-default transient-mark-mode t) + +;; When popping the mark, continue popping until the cursor actually moves +;; Also, if the last command was a copy - skip past all the expand-region cruft. +;; Stolen from Magnar Sveen's emacs.d on github. +(defadvice pop-to-mark-command (around ensure-new-position activate) + (let ((p (point))) + (when (eq last-command 'save-region-or-current-line) + ad-do-it + ad-do-it + ad-do-it) + (dotimes (i 10) + (when (= p (point)) ad-do-it)))) + +;; Allow mark-based navigation even in transient-mark-mode; see +;; http://www.masteringemacs.org/articles/2010/12/22/fixing-mark-commands-transient-mark-mode/ + +(defun ravi/push-mark-no-activate () + "Pushes `point' to `mark-ring' and does not activate the region +Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled" + (interactive) + (push-mark (point) t nil) + (message "Pushed mark to ring")) +(bind-key "C-`" 'ravi/push-mark-no-activate) + +(defun ravi/jump-to-mark () + "Jumps to the local mark, respecting the `mark-ring' order. +This is the same as using \\[set-mark-command] with the prefix argument." + (interactive) + (set-mark-command 1)) +(bind-key "M-`" 'ravi/jump-to-mark) + +; Prevents C-x C-x from highlighting region +(defun ravi/exchange-point-and-mark-no-activate () + "Identical to \\[exchange-point-and-mark] but will not activate the region." + (interactive) + (exchange-point-and-mark) + (deactivate-mark nil)) +(define-key global-map [remap exchange-point-and-mark] 'ravi/exchange-point-and-mark-no-activate) + +(use-package browse-kill-ring + :config (browse-kill-ring-default-keybindings) + :ensure t + :if (not ravi/use-helm-instead-of-ido) + ) + +(provide 'ravi-init-marks) +;;; ravi-init-marks.el ends here diff --git a/lisp/ravi-init-mu.el b/lisp/ravi-init-mu.el new file mode 100644 index 0000000..b123da2 --- /dev/null +++ b/lisp/ravi-init-mu.el @@ -0,0 +1,196 @@ +;;; ravi-init-mu.el --- mail + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Set up mu4e conditionally +;; - actual account information should be in local.el +;; - requires definitions of ravi/mu4e-account-alist + +;;; Code: + +(defvar ravi/use-mu-for-email nil + "Use mu for email") +(defvar ravi/mu4e-account-alist nil + "An alist containing account information for all accounts") +(defvar ravi/mu4e-update-interval 1800 ; 30 minutes + "Basic update interval; all other update intervals are multiples") + +(setq message-citation-line-format "On %a %Y-%m-%d %l:%M:%S%p %Z, %f wrote:" + message-citation-line-function 'message-insert-formatted-citation-line) + +(when ravi/use-mu-for-email + (use-package mu4e + :load-path (lambda () (ravi/emacs-file "site-lisp/mu/mu4e")) + :commands mu4e + :init + (progn + (add-to-list 'Info-additional-directory-list (ravi/emacs-file "site-lisp/mu/mu4e")) + (unless ravi/mu4e-account-alist (error "Email account list not found")) + (defun ravi/switch-to-mu4e () + (interactive) + (let ((buf (or (and (boundp 'mu4e~headers-buffer-name) + (get-buffer mu4e~headers-buffer-name)) + (get-buffer "*mu4e-main*")))) + (if buf + (if (get-buffer-window buf t) + (select-window (get-buffer-window buf t)) + (switch-to-buffer buf)) + (mu4e)))) + (bind-key "C-'" 'ravi/switch-to-mu4e) + ) + :config + (progn + + ;; Basic identity for sending mail + (require 'smtpmail) + (setq send-mail-function 'smtpmail-send-it) + (setq message-send-mail-function 'smtpmail-send-it) + + ;; Set up defaults from first account on the list + ;; user-full-name + ;; smtp-local-domain + ;; user-mail-address + ;; smtpmail-smtp-user + ;; smtpmail-smtp-server + ;; mu4e-sent-folder + ;; mu4e-trash-folder + ;; mu4e-refile-folder + (let* ((account (caar ravi/mu4e-account-alist)) + (account-vars (cdr (assoc account ravi/mu4e-account-alist)))) + (if account-vars + (mapc #'(lambda (var) + (set (car var) (cadr var))) + account-vars) + (error "No email account found"))) + + ;; Choose correct SMTP identity wisely + (defun ravi/mu4e-set-account () + "Set the account for composing a message." + (let* ((account + (if mu4e-compose-parent-message + (let ((maildir (mu4e-message-field mu4e-compose-parent-message :maildir))) + (string-match "/\\(.*?\\)/" maildir) + (match-string 1 maildir)) + (if (= (length ravi/mu4e-account-alist) 1) + (caar ravi/mu4e-account-alist) + (completing-read (format "Compose with account: (%s) " + (mapconcat #'(lambda (var) (car var)) + ravi/mu4e-account-alist "/")) + (mapcar #'(lambda (var) (car var)) ravi/mu4e-account-alist) + nil t nil nil (caar ravi/mu4e-account-alist))))) + (account-vars (cdr (assoc account ravi/mu4e-account-alist)))) + (if account-vars + (mapc #'(lambda (var) + (set (car var) (cadr var))) + account-vars) + (error "No email account found")))) + (add-hook 'mu4e-compose-pre-hook 'ravi/mu4e-set-account) + + (setq mu4e-compose-dont-reply-to-self t) + (defun ravi/set-self-addresses () + (setq mu4e-user-mail-address-list (list user-mail-address))) + (add-hook 'mu4e-compose-pre-hook 'ravi/set-self-addresses) + + ;; Use async method of sending email, if possible + (use-package async + :config + (progn + (require 'smtpmail-async) + (setq send-mail-function 'async-smtpmail-send-it) + (setq message-send-mail-function 'async-smtpmail-send-it) + ) + :ensure t + ) + + ;; Basic mu4e configuration parameters + (setq mu4e-mu-binary (ravi/emacs-file "site-lisp/mu/mu/mu")) + (setq mu4e-maildir "~/.mail") + + ;; Poll accounts only as often as necessary + (defvar ravi/mu4e-get-mail-attempts 0 + "Number of attempts so far to get mail") + (defun ravi/check-whether-to-get-mail-for-account (account-info) + (let* ((account-interval (assq 'ravi/account-update-interval account-info)) + (account-update-interval (if account-interval (cadr account-interval) 1))) + (if (= (% ravi/mu4e-get-mail-attempts account-update-interval) 0) + (concat " " (car account-info)) + ""))) + (defun ravi/get-mu4e-get-mail-command () + "Figure out arguments to mbsync" + (let ((ravi/all-channels (mapconcat 'ravi/check-whether-to-get-mail-for-account + ravi/mu4e-account-alist ""))) + (setq ravi/mu4e-get-mail-attempts (1+ ravi/mu4e-get-mail-attempts)) + (if (= (length ravi/all-channels) 0) + "true" ;; do nothing command + (concat (ravi/emacs-file "site-lisp/isync/src/mbsync") " -q -q" ravi/all-channels) + ))) + (add-hook 'mu4e-update-pre-hook + (lambda () + (setq mu4e-get-mail-command (ravi/get-mu4e-get-mail-command)))) + ;(message "%d: '%s'" ravi/mu4e-get-mail-attempts (ravi/get-mu4e-get-mail-command)) + ;; Default update command if something goes wrong + (setq mu4e-get-mail-command (concat (ravi/emacs-file "site-lisp/isync/src/mbsync") " -a -q -q")) + (setq mu4e-update-interval ravi/mu4e-update-interval) + (setq mu4e-change-filenames-when-moving t) + + ;; User interface + (setq mu4e-html-renderer 'w3m) + (setq mu4e-html2text-command "w3m -T text/html") + (setq mu4e-view-show-images t) + (when (boundp 'ravi/mu4e-maildir-shortcuts) + (setq mu4e-maildir-shortcuts ravi/mu4e-maildir-shortcuts)) + + (add-to-list 'mu4e-view-actions + '("ViewInBrowser" . mu4e-action-view-in-browser) t) + + ;; Show summary of all folders + (use-package mu4e-maildirs-extension + ;;:config (mu4e-maildirs-extension) ; does not work with mu now + :ensure t + ) + + (setq message-citation-line-function 'message-insert-formatted-citation-line) + (setq message-kill-buffer-on-exit t) + (setq mu4e-compose-signature-auto-include nil) + ;; Allow attaching files from dired + (require 'gnus-dired) + ;; make the `gnus-dired-mail-buffers' function also work on + ;; message-mode derived modes, such as mu4e-compose-mode + (defun gnus-dired-mail-buffers () + "Return a list of active message buffers." + (let (buffers) + (save-current-buffer + (dolist (buffer (buffer-list t)) + (set-buffer buffer) + (when (and (derived-mode-p 'message-mode) + (null message-sent-message-via)) + (push (buffer-name buffer) buffers)))) + (nreverse buffers))) + (setq gnus-dired-mail-mode 'mu4e-user-agent) + (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) + + (imagemagick-register-types) + ) + ) + ) + +(provide 'ravi-init-mu) +;;; ravi-init-mu.el ends here diff --git a/lisp/ravi-init-navigation.el b/lisp/ravi-init-navigation.el new file mode 100644 index 0000000..5a6054d --- /dev/null +++ b/lisp/ravi-init-navigation.el @@ -0,0 +1,350 @@ +;;; ravi-init-navigation.el --- navigation utilities + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Buffer navigation utilities + +;;; Code: + +(use-package region-bindings-mode + :config + (progn + (region-bindings-mode-enable) + (bind-key "f" 'forward-word region-bindings-mode-map) + (bind-key "b" 'backward-word region-bindings-mode-map) + + ;; HJKL cluster to replace arrow keys + (bind-key "h" 'backward-char region-bindings-mode-map) + (bind-key "l" 'forward-char region-bindings-mode-map) + (bind-key "k" 'previous-line region-bindings-mode-map) + (bind-key "j" 'next-line region-bindings-mode-map) + + ;; Most of the time, we mark regions to copy + (bind-key "w" 'kill-ring-save region-bindings-mode-map) + ) + :ensure t + ) + +(use-package ace-jump-mode + :bind (("M-h" . ace-jump-mode) + ("M-H" . ace-jump-line-mode)) + :ensure t + ) + +(use-package ace-isearch + :config + (progn + (setq ace-isearch-use-ace-jump nil) ; prefer dedicated key for ace-jump + (global-ace-isearch-mode +1)) + :ensure t) + +(use-package jump-char + :bind (("M-m" . jump-char-forward)) + :ensure t + ) + +(use-package imenu-anywhere + :bind ("s-." . imenu-anywhere) + :ensure t + ) + +(use-package expand-region + :config + (progn + (bind-key "C-=" 'er/expand-region)) + :ensure t + ) + +(use-package multiple-cursors + :bind (("C-S-c C-S-c" . mc/edit-lines) + + ("C->" . mc/mark-next-like-this) + ("C-<" . mc/mark-previous-like-this) + ("C-c C-<" . mc/mark-all-like-this)) + :config + (progn + (setq mc/list-file (ravi/emacs-file "past/mc-lists.el")) + (bind-key "a" 'mc/mark-all-like-this region-bindings-mode-map) + (bind-key "p" 'mc/mark-previous-like-this region-bindings-mode-map) + (bind-key "n" 'mc/mark-next-like-this region-bindings-mode-map) + (bind-key "m" 'mc/mark-more-like-this-extended region-bindings-mode-map) + ) + :ensure t + ) + +(use-package fold-this + :commands fold-this + :config + (progn + (bind-key "t" 'fold-this region-bindings-mode-map)) + :ensure t + ) + +(use-package indirect + :commands indirect-region + :config + (progn + (bind-key "I" 'indirect-region region-bindings-mode-map)) + ) + +(use-package visual-regexp + :bind (("C-c r" . vr/replace) + ("C-c q" . vr/query-replace) + ("C-c m" . vr/mc-mark)) + :ensure t + ) + +(use-package god-mode + :bind (("<escape>" . god-local-mode)) + :disabled t ; less useful than I thought + :ensure t + ) + +(bind-key "<M-f6>" 'ff-find-other-file) + +(setq compilation-scroll-output 'first-error) + +(use-package smartparens + :commands (smartparens-mode show-smartparens-mode) + :init + (show-smartparens-global-mode 1) + :config + (progn + (require 'smartparens-config) + (add-hook 'emacs-lisp-mode-hook 'smartparens-mode) + (add-hook 'emacs-lisp-mode-hook 'sp-use-smartparens-bindings) + (use-package minor-mode-hack :ensure t) + (raise-minor-mode-map-alist 'region-bindings-mode) + ) + :ensure t + ) + +;; Marking and moving lines + +(defun ravi/pull-up-a-line() + "Pull up the next line" + (interactive) + (join-line -1) + ) + +(bind-key "M-j" 'ravi/pull-up-a-line) + +(use-package move-lines + :bind (("<S-down>" . move-lines-down) + ("<S-up>" . move-lines-up) + ) + ) + +;; From Kyle Sherman's comment at +;; http://emacs-fu.blogspot.com/2010/01/duplicating-lines-and-commenting-them.html +;; \todo Make this work someday with regions too. +(defun ravi/kyle-sherman-duplicate-line (&optional comment line) + "Duplicate the line containing the point. +\nIf COMMENT is non-nil, also comment out the original line. + If LINE is non-nil, duplicate that line instead." + (interactive "P") + (let ((col (current-column))) + (save-excursion + (when line + (goto-line line)) + (let ((line (buffer-substring (point-at-bol) (point-at-eol)))) + (when comment + (comment-region (point-at-bol) (point-at-eol))) + (goto-char (point-at-eol)) + (if (eobp) + (newline) + (forward-line 1)) + (open-line 1) + (insert line))) + (forward-line 1) + (move-to-column col))) + +;; C-: duplicates line, C-u C-: comments first line +(bind-key "C-:" 'ravi/kyle-sherman-duplicate-line) + +(defun ravi/back-to-indentation-or-beginning () (interactive) + (if (bolp) (back-to-indentation) + (beginning-of-line))) +(bind-key "C-a" 'ravi/back-to-indentation-or-beginning) + +(defun ravi/Fuco-point-in-comment () + "Determine if the point is inside a comment" + (interactive) + (let ((syn (syntax-ppss))) + (and (nth 8 syn) + (not (nth 3 syn))))) + +(defun ravi/Fuco-end-of-code-or-line+ (arg) + "Move to the end of line. If already there, move to the end of code. + + Comments are recognized in any mode that sets syntax-ppss properly." + (interactive "P") + (let ((eoc (save-excursion + (move-end-of-line arg) + (while (ravi/Fuco-point-in-comment) + (backward-char)) + (skip-chars-backward " \t") + (point)))) + (cond ((eolp) + (move-end-of-line arg) + (while (ravi/Fuco-point-in-comment) + (backward-char)) + (skip-chars-backward " \t")) + (t + (move-end-of-line arg))))) +(bind-key "C-e" 'ravi/Fuco-end-of-code-or-line+) + +;; Use current line for region-based commands if no region selected +(use-package whole-line-or-region + :config + (progn + (defun turn-on-whole-line-or-region-mode() + (interactive) + (whole-line-or-region-mode 1) + ) + (add-hook 'prog-mode-hook 'turn-on-whole-line-or-region-mode) + ) + :diminish whole-line-or-region-mode + ) + +;; grep and friends + +(use-package wgrep + :ensure t + ) + +(if (executable-find "ag") + ;; Prefer the silver-searcher if available + (use-package ag + :bind (("H-g" . ag) + ("H-G" . ag-files)) + :config + (progn + (setq ag-highlight-search t) + (setq ag-reuse-buffers t) + (use-package wgrep-ag + :ensure t)) + :ensure t) + ;; Use grep if ag is not available on the system + (use-package grep + :bind (("H-g" . grep)))) + +(use-package highlight-symbol + :bind (("H-n" . ravi/highlight-symbol-next) + ("H-N" . highlight-symbol-prev) + ("H-s" . highlight-symbol-query-replace)) + :commands highlight-symbol-next + :config + (progn + (defvar ravi/highlight-symbol-overlay-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "j") 'highlight-symbol-prev) + (define-key map (kbd "k") 'highlight-symbol-next) + (define-key map (kbd "s") 'highlight-symbol-query-replace) + (define-key map (kbd "o") 'highlight-symbol-occur) + map)) + (defun ravi/highlight-symbol-next () + (interactive) + (highlight-symbol-next) + (set-temporary-overlay-map ravi/highlight-symbol-overlay-map t)) + ) + :ensure t + ) + +(let ((ad-redefinition-action 'accept)) + (use-package color-moccur + :commands (isearch-moccur isearch-all) + :bind ("M-s O" . moccur) + :init + (progn + (bind-key "M-o" 'isearch-moccur isearch-mode-map) + (bind-key "M-O" 'isearch-moccur-all isearch-mode-map)) + + :config + (use-package moccur-edit) + + :ensure t + ) + ) + +;; Delete via isearch +(defun zap-to-isearch (rbeg rend) + "Kill the region between the mark and the closest portion of + the isearch match string. The behaviour is meant to be analogous + to zap-to-char; let's call it zap-to-isearch. The deleted region + does not include the isearch word. This is meant to be bound only + in isearch mode. + + The point of this function is that oftentimes you want to delete + some portion of text, one end of which happens to be an active + isearch word. The observation to make is that if you use isearch + a lot to move the cursor around (as you should, it is much more + efficient than using the arrows), it happens a lot that you could + just delete the active region between the mark and the point, not + include the isearch word." + (interactive "r") + (when (not mark-active) + (error "Mark is not active")) + (let* ((isearch-bounds (list isearch-other-end (point))) + (ismin (apply 'min isearch-bounds)) + (ismax (apply 'max isearch-bounds)) + ) + (if (< (mark) ismin) + (kill-region (mark) ismin) + (if (> (mark) ismax) + (kill-region ismax (mark)) + (error "Internal error in isearch kill function."))) + (isearch-exit) + )) +(bind-key "M-z" 'zap-to-isearch isearch-mode-map) + +;; Exit isearch at the beginning +(defun isearch-exit-other-end (rbeg rend) + "Exit isearch, but at the other end of the search string. + This is useful when followed by an immediate kill." + (interactive "r") + (isearch-exit) + (goto-char isearch-other-end)) +(bind-key "<C-return>" 'isearch-exit-other-end isearch-mode-map) + +;; Search the web +(use-package webjump + :bind ("C-x g" . webjump) + :config + (progn + ;; Suggest word at point if possible + (defun webjump-read-string (prompt) + (let* ((prompt (concat prompt (if (word-at-point) (concat " (default: " (word-at-point) ")")) ": ")) + (input (read-string prompt))) + (if (webjump-null-or-blank-string-p input) (word-at-point) input))) + + ;; C++ reference + (add-to-list 'webjump-sites + '("cpp" . [simple-query "en.cppreference.com" + "http://en.cppreference.com/mwiki/index.php?title=Special:Search&search=" + ""])) + ) + ) + +;; to do: add zeal-at-point + +(provide 'ravi-init-navigation) +;;; ravi-init-navigation.el ends here diff --git a/lisp/ravi-init-org.el b/lisp/ravi-init-org.el new file mode 100644 index 0000000..004d2f6 --- /dev/null +++ b/lisp/ravi-init-org.el @@ -0,0 +1,53 @@ +;;; ravi-init-org.el --- org initialization + +;; Copyright (C) 2014 + +;; Author: <ravi@nero> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Org mode initialization + +;;; Code: + +(use-package org + :ensure org-plus-contrib + :mode ("\\.org\\'" . org-mode) + + ;; The following lines are always needed. Choose your own keys. + :bind (("C-c l" . org-store-link) + ("H--" . org-agenda)) + :config + (progn + (use-package htmlize + :ensure t) + (use-package ox-reveal + :load-path (lambda () (ravi/emacs-file "site-lisp/org-reveal")) + ) + (setq org-src-fontify-natively t) + (setq org-modules (quote (org-bbdb + org-bibtex + org-crypt + org-gnus + org-id + org-info))) + ) + ) + +(provide 'ravi-init-org) +;;; ravi-init-org.el ends here + diff --git a/lisp/ravi-init-python.el b/lisp/ravi-init-python.el new file mode 100644 index 0000000..6edc232 --- /dev/null +++ b/lisp/ravi-init-python.el @@ -0,0 +1,166 @@ +;;; ravi-init-python.el --- python support + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Python programming setup + +;;; Code: + +(use-package python + :mode ("\\.py\\'" . python-mode) + :commands python-shell-switch-to-shell + :config + (progn + + (add-hook 'python-mode-hook 'ravi/python-mode-hook) + (defun ravi/python-mode-hook() + ;; Set ipython as our interpreter + (setq python-shell-interpreter "ipython" + python-shell-interpreter-args "--pylab" + python-shell-prompt-regexp "In \\[[0-9]+\\]: " + python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: " + python-shell-completion-setup-code + "from IPython.core.completerlib import module_completion" + python-shell-completion-module-string-code + "';'.join(module_completion('''%s'''))\n" + python-shell-completion-string-code + "';'.join(get_ipython().Completer.all_completions('''%s'''))\n" + ) + + ;; For ipython 0.10, uncomment the following: + ;; (setq python-shell-completion-string-code + ;; "';'.join(__IP.complete('''%s'''))\n" + ;; python-shell-completion-module-string-code "" + ;; ) + + ;; I'd really prefer indentation by 2 spaces, but have too much existing + ;; python code with indentation at 4 spaces. + (setq python-indent-offset 4) + ) + + ;; We no longer use smart-tab-mode + ;(add-to-list 'smart-tab-disabled-major-modes 'inferior-python-mode) + + (define-auto-insert "\\.py\\'" 'ravi/auto-insert-py) + (defun ravi/auto-insert-py () + (progn + (insert "#!/usr/bin/env python\n\n") + ) + ) + + (use-package virtualenvwrapper + :config + (progn + (venv-initialize-interactive-shells) + (venv-initialize-eshell) + (setq venv-location (expand-file-name "~/usr/local/venv/")) + ) + + :ensure t + ) + + ;; Use pymacs+ropemacs for code completion plus documentation browsing. + ;; The main issue is that this requires both python-side and emacs-side + ;; support, and hence cannot be installed as a package from MELPA. + (use-package pymacs + :disabled t + :init + (progn + ;; Many bindings provide same functionality as from other packages. + (setq ropemacs-global-prefix nil) + ;(setq ropemancs-local-prefix nil) + ;(setq ropemacs-enable-shortcuts nil) + ) + :config + (progn + (pymacs-load "ropemacs" "rope-") + (bind-key "C-c C-d" 'rope-show-calltip python-mode-map) + + ;; Auto-complete sources; see + ;; http://www.cx4a.org/pub/auto-complete-python.el + (defvar ac-ropemacs-completions-cache nil) + + (defvar ac-source-ropemacs + '((init + . (lambda () + (setq ac-ropemacs-completions-cache + (mapcar + (lambda (completion) + (concat ac-prefix completion)) + (ignore-errors + (rope-completions)))))) + (candidates . (lambda () + (all-completions ac-prefix ac-ropemacs-completions-cache))))) + + (defun ac-ropemacs-setup () + (ac-ropemacs-require) + ;(setq ac-sources (append (list 'ac-source-ropemacs) ac-sources)) + (setq ac-omni-completion-sources '(("\\." ac-source-ropemacs)))) + + (add-hook 'python-mode-hook 'ac-ropemacs-setup) + + ) + ) + + ;; Use jedi.el for code completion plus documentation browsing. + ;; The main issue is that this requires both python-side and emacs-side + ;; support, but the python-side support cannot be installed as a package + ;; from MELPA. Fedora does not provide python-epc as an RPM either. We + ;; work around it by adding sexpdata, jedi and python-epc as git submodules. + (use-package jedi + :config + (progn + (defun ravi/jedi-setup () + (let ((basic-server-args (list + "--sys-path" (ravi/emacs-file "site-lisp/python-epc") + "--sys-path" (ravi/emacs-file "site-lisp/sexpdata") + "--sys-path" (ravi/emacs-file "site-lisp/jedi")) + )) + (set (make-local-variable 'jedi:server-args) + (if (and (boundp 'extra-jedi-args) + (listp extra-jedi-args)) + (append basic-server-args extra-jedi-args) + basic-server-args)) + (jedi:setup))) + + (defun ravi/python-jedi-hook-installer () + (setq jedi:complete-on-dot t) + (add-hook 'hack-local-variables-hook 'ravi/jedi-setup nil t)) + (add-hook 'python-mode-hook 'ravi/python-jedi-hook-installer) + ) + :ensure t + :disabled t ; casualty of removing auto-complete + ) + + (use-package sphinx-doc + :config + (progn + (defun ravi/sphinx-doc-setup () + (sphinx-doc-mode 1)) + (add-hook 'python-mode-hook 'ravi/sphinx-doc-setup) + ) + :diminish t + :ensure t) + ) + ) + +(provide 'ravi-init-python) + diff --git a/lisp/ravi-init-repl.el b/lisp/ravi-init-repl.el new file mode 100644 index 0000000..8cc343b --- /dev/null +++ b/lisp/ravi-init-repl.el @@ -0,0 +1,67 @@ +;;; ravi-init-repl.el --- REPL utilities + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Read-eval-print-loop support + +;;; Code: + +(use-package comint + :defer t + :config + (progn + (bind-key "<up>" 'comint-previous-matching-input-from-input comint-mode-map) + (bind-key "<down>" 'comint-next-matching-input-from-input comint-mode-map) + ) + ) + +(use-package octave-mod + :mode ("\\.m\\'" . octave-mode) + :config + (progn + (defun ravi/octave-shell-switch-to-shell () + "Make sure that `inferior-octave-buffer' exists and is displayed." + (interactive) + (if (get-buffer inferior-octave-buffer) + (pop-to-buffer (get-buffer inferior-octave-buffer)) + (inferior-octave nil))) ) + ) + +(use-package repl-toggle + :config + (progn + (setq rtog/mode-repl-alist '((python-mode . python-shell-switch-to-shell) + (octave-mode . ravi/octave-shell-switch-to-shell) + (emacs-lisp-mode . ielm))) + (setq rtog/goto-buffer-fun 'pop-to-buffer) + (add-hook 'python-mode-hook 'rtog/activate) + (add-hook 'octave-mode-hook 'rtog/activate) + (add-hook 'emacs-lisp-mode-hook 'rtog/activate) + + ; The default keybinding is not great + (unbind-key "C-c C-z" repl-toggle-mode-map) + (bind-key "<f5>" 'rtog/toggle-repl repl-toggle-mode-map) + ) + :diminish repl-toggle-mode + :ensure t) + +(provide 'ravi-init-repl) +;;; ravi-init-repl.el ends here diff --git a/lisp/ravi-init-tex.el b/lisp/ravi-init-tex.el new file mode 100644 index 0000000..d7725e9 --- /dev/null +++ b/lisp/ravi-init-tex.el @@ -0,0 +1,189 @@ +;;; ravi-init-tex.el --- tex and friends + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; TeX and LaTeX support + +;;; Code: + +(use-package tex-site + :ensure auctex + :mode ("\\.tex\\'" . TeX-latex-mode) + :commands (TeX-latex-mode + TeX-mode + tex-mode + LaTeX-mode + latex-mode) + :config + (progn + (use-package latex + :config + (progn + (use-package reftex + :defer t + :diminish reftex-mode) + ;; fix the "bug" in SP regexp wrap that treats ' as "word" + (modify-syntax-entry ?' ".") + + (require 'smartparens-latex) + (sp-local-pair 'latex-mode "\\begin" "\\end") + (sp-local-tag 'latex-mode "\\ba" "\\begin{align*}" "\\end{align*}") + + (use-package preview) + (use-package font-latex) + (fset 'tex-font-lock-subscript 'ignore) + + (sp-with-modes '(tex-mode plain-tex-mode latex-mode) + (sp-local-pair "\\[" nil :post-handlers '(my-latex-math-block-indent))) + + (defun my-latex-math-block-indent (a action c) + (when (eq action 'insert) + (newline-and-indent) + (save-excursion (newline)))) + + (defun my-latex-compile () + (interactive) + (save-buffer) + (TeX-command "LaTeX" 'TeX-master-file nil)) + (bind-key "C-M-x" 'my-latex-compile LaTeX-mode-map) + + (defvar my-latex-wrap-choices '("emph" + "textsc")) + (defvar my-latex-wrap-history nil) + + (defun my-latex-wrap (macro-name) + (interactive (list (ido-completing-read + "Macro> " + my-latex-wrap-choices + nil 'confirm nil my-latex-wrap-history))) + (when (use-region-p) + (let ((b (region-beginning)) + (e (region-end))) + (goto-char e) + (insert "}") + (goto-char b) + (insert "\\" macro-name "{")))) + (bind-key "C-c w" 'my-latex-wrap LaTeX-mode-map) + + (defun my-end-of-environment () + (interactive) + (LaTeX-mark-environment) + (end-of-region)) + + (defun my-beginning-of-environment () + (interactive) + (LaTeX-mark-environment) + (beginning-of-region) + (deactivate-mark)) + + (bind-key "M-n" 'my-end-of-environment LaTeX-mode-map) + (bind-key "M-p" 'my-beginning-of-environment LaTeX-mode-map) + + ;; Use okular rather than evince + (setq TeX-view-program-selection + '((output-dvi "Okular") + (output-pdf "Okular"))) + + ;; fix italian quote highlight + (push '("\"<" "\">") font-latex-quote-list) + + (defun my-latex-remove-command () + "Unwrap the expression that point is in or before, also +removing the command name. By command we understand a symbol +starting with \\ and followed by a block of text enclosed in {}." + (interactive) + (let ((ok (sp-get-enclosing-sexp))) + (cond + ;; we're inside the { } block + (ok + (progn + (save-excursion + (goto-char (sp-get ok :beg)) + (zap-to-char -1 ?\\ )) + (sp-splice-sexp))) + ;; test if we are in looking at the command fromt he front + ((looking-at "\\\\") + (zap-up-to-char 1 ?{) + (sp-unwrap-sexp)) + ;; otherwise we're inside the command name + (t + (zap-to-char -1 ?\\ ) + (zap-up-to-char 1 ?{) + (sp-unwrap-sexp))))) + (bind-key "C-c d" 'my-latex-remove-command LaTeX-mode-map) + (bind-key "M-RET" 'LaTeX-insert-item LaTeX-mode-map) + + (use-package company-math + :config + (progn + (defun ravi/company-math-setup () + (setq-local company-backends + (append '(company-math-symbols-latex company-latex-commands) + company-backends))) + (add-hook 'TeX-mode-hook 'ravi/company-math-setup)) + :ensure t) + + (use-package latex-extra + :config + (progn + (add-hook 'LaTeX-mode-hook 'latex-extra-mode)) + :diminish latex-extra-mode + :ensure t) + + (defun my-LaTeX-preview-math () + (interactive) + (let ((b (save-excursion (while (texmathp) (backward-char 1)) (1- (point)))) + (e (save-excursion (while (texmathp) (forward-char 1)) (point)))) + (preview-region b e))) + (bind-key "C-<m-key>" 'my-LaTeX-preview-math preview-map) + + (defun my-LaTeX-mode-init () + (setq TeX-auto-save t) + (setq TeX-parse-self t) + (TeX-PDF-mode t) + (setq reftex-plug-into-AUCTeX t) + (reftex-mode t) + (TeX-fold-mode t) + + (smartparens-mode 1) + + (LaTeX-add-environments + '("derivation" LaTeX-env-label)) + (TeX-add-symbols '("emph" 1)) + + (setq fill-column 88) + + ;; Add XeLaTeX support to AucTeX + (add-to-list 'TeX-command-list '("XeLaTeX" "%`xelatex%(mode)%' %t" TeX-run-TeX nil t)) + (setq TeX-command-default "XeLaTeX") + (setq TeX-save-query nil) + (setq TeX-show-compilation t) + + (message "LaTeX mode init complete.")) + ;; ACUTeX replaces latex-mode-hook with LaTeX-mode-hook + (add-hook 'LaTeX-mode-hook 'my-LaTeX-mode-init) + + )) + ) + ) + +(provide 'ravi-init-tex) +;;; ravi-init-tex.el ends here diff --git a/lisp/ravi-init-vc.el b/lisp/ravi-init-vc.el new file mode 100644 index 0000000..e4b273e --- /dev/null +++ b/lisp/ravi-init-vc.el @@ -0,0 +1,185 @@ +;;; ravi-init-vc.el --- vc control + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: vc + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Version control initialization + +;;; Code: + +;; Git +(use-package magit + :bind (("<M-f3>" . magit-status) + ("C-x v F" . magit-file-log)) + :config + (progn + (setq-default + magit-process-popup-time 10 + magit-diff-refine-hunk t + magit-completing-read-function 'magit-ido-completing-read + ) + + ; Since magit-mode-quit-window is used by all magit windows (such as logs), + ; and since mucking with magit's keymap also leads to the same results, we + ; avoid showing magit-status in a fullscreen window until another solution + ; is found. + ;(require 'fullframe) + ;(fullframe magit-status magit-mode-quit-window :magit-fullscreen nil) + + (setq magit-restore-window-configuration t) + (diminish 'magit-auto-revert-mode) + + (use-package vc-git + :defer t + :bind ("C-x v f" . vc-git-grep) + :config + (progn + (global-magit-wip-save-mode) + (diminish 'magit-wip-save-mode) + ) + ) + + ;(after-load 'magit-key-mode + ; (require 'magit-svn)) + + (after-load 'compile + (dolist (defn (list '(git-svn-updated "^\t[A-Z]\t\\(.*\\)$" 1 nil nil 0 1) + '(git-svn-needs-update "^\\(.*\\): needs update$" 1 nil nil 2 1))) + (add-to-list 'compilation-error-regexp-alist-alist defn) + (add-to-list 'compilation-error-regexp-alist (car defn)))) + + (use-package magit-svn + :config (add-hook 'magit-mode-hook 'turn-on-magit-svn) + :ensure t + ) + + (defvar git-svn--available-commands nil "Cached list of git svn subcommands") + + (defun git-svn (dir) + "Run a git svn subcommand in DIR." + (interactive "DSelect directory: ") + (unless git-svn--available-commands + (setq git-svn--available-commands + (sanityinc/string-all-matches + "^ \\([a-z\\-]+\\) +" + (shell-command-to-string "git svn help") 1))) + (let* ((default-directory (vc-git-root dir)) + (compilation-buffer-name-function (lambda (major-mode-name) "*git-svn*"))) + (compile (concat "git svn " + (ido-completing-read "git-svn command: " + git-svn--available-commands nil t)))) + ) + + (defun magit-toggle-whitespace () + (interactive) + (if (member "-w" magit-diff-options) + (magit-dont-ignore-whitespace) + (magit-ignore-whitespace))) + + (defun magit-ignore-whitespace () + (interactive) + (add-to-list 'magit-diff-options "-w") + (magit-refresh)) + + (defun magit-dont-ignore-whitespace () + (interactive) + (setq magit-diff-options (remove "-w" magit-diff-options)) + (magit-refresh)) + + (bind-key "W" 'magit-toggle-whitespace magit-status-mode-map) + + (defun magit-just-amend () + (interactive) + (save-window-excursion + (magit-with-refresh + (shell-command "git --no-pager commit --amend --reuse-message=HEAD")))) + (bind-key "C-a" 'magit-just-amend magit-status-mode-map) + + ) + :ensure t + ) +(use-package git-gutter + :config + (progn + (use-package git-gutter-fringe + :ensure t + ) + (global-git-gutter-mode 1) + ) + :ensure t + :diminish git-gutter-mode + ) +(use-package git-commit-mode + :ensure t + ) +(use-package git-rebase-mode + :ensure t + ) +(use-package gitignore-mode + :ensure t + ) +(use-package gitconfig-mode + :ensure t + ) +(use-package git-messenger + :ensure t + :bind ("C-x v p" . git-messenger:popup-message) + ) +(use-package git-timemachine + :ensure t + :bind ("C-x v t" . git-timemachine) + ) +(use-package magit-blame + :bind (("C-x v B" . magit-blame-mode))) + +;; Stolen almost entirely from Fuco (Matus Goljer) +(use-package ediff + :config + (progn + (defvar my-ediff-before-config nil "Window configuration before ediff.") + (defvar my-ediff-after-config nil "Window configuration after ediff.") + + (defun my-ediff-before-setup () + "Function to be called before any buffers or window setup for + ediff." + (setq my-ediff-before-config (current-window-configuration)) + (set-register ?b (list my-ediff-before-config (point-marker)))) + + (defun my-ediff-after-setup () + "Function to be called after buffers and window setup for ediff." + (setq my-ediff-after-config (current-window-configuration)) + (set-register ?e (list my-ediff-after-config (point-marker)))) + + (defun my-ediff-quit () + "Function to be called when ediff quits." + (when my-ediff-before-config + (set-window-configuration my-ediff-before-config)) + ;; clean up ediff bullshit + (->> (buffer-list) + (-map 'buffer-name) + (--select (string-match-p "\\*[Ee]diff" it)) + (-map 'kill-buffer))) + + (add-hook 'ediff-before-setup-hook 'my-ediff-before-setup) + (add-hook 'ediff-after-setup-windows-hook 'my-ediff-after-setup 'append) + (add-hook 'ediff-quit-hook 'my-ediff-quit))) + +(provide 'ravi-init-vc) +;;; ravi-init-vc.el ends here diff --git a/lisp/ravi-init-web.el b/lisp/ravi-init-web.el new file mode 100644 index 0000000..13dd758 --- /dev/null +++ b/lisp/ravi-init-web.el @@ -0,0 +1,100 @@ +;;; ravi-init-web.el --- Web development -*- lexical-binding: t; -*- + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Web development tools + +;;; Code: + +(use-package emmet-mode + :commands (emmet-mode) + :init + (progn + (add-hook 'css-mode-hook 'emmet-mode) + (add-hook 'sgml-mode-hook 'emmet-mode)) + :config + (progn + (unbind-key "C-j" emmet-mode-keymap) + (bind-key "M-r" 'emmet-expand-line emmet-mode-keymap)) + :ensure t + :diminish t) + +;; Javascript +(use-package js2-mode + :mode (("\\.js$" . js2-mode) + ("\\.json$" . js2-mode) + ("Jakefile$" . js2-mode)) + ;; :interpreter ("node" . js2-mode) + :config + (progn + + (use-package js2-refactor + :config + (progn + (js2r-add-keybindings-with-prefix "C-c C-m")) + :ensure t) + + (defun ravi/js2-mode-hook () + (emmet-mode) + (setq js2-basic-offset 2)) + (add-hook 'js2-mode-hook 'ravi/js2-mode-hook)) + :ensure t + ) + +;; Interact with the browser +(use-package skewer-mode + :config + (progn + (skewer-setup)) + :ensure t) + +;; HTML with web-mode +(use-package web-mode + :mode (("\\.html" . web-mode)) + :config + (progn + + ;; Make it work with smartparens + (defun ravi/web-mode-sp-hook () + (setq web-mode-enable-auto-pairing nil) + (smartparens-mode) + (sp-use-smartparens-bindings)) + (add-hook 'web-mode-hook 'ravi/web-mode-sp-hook) + (add-hook 'web-mode-hook 'emmet-mode) + (defun sp-web-mode-is-code-context (id action context) + (when (and + (eq action 'insert) + (not (or (get-text-property (point) 'part-side) (get-text-property (point) 'block-side)))) + t)) + (sp-local-pair 'web-mode "<" nil :when '(sp-web-mode-is-code-context)) + + ;; Customization + (setq web-mode-enable-current-element-highlight t) + (setq web-mode-markup-indent-offset 2) + (setq web-mode-css-indent-offset 2) + (setq web-mode-code-indent-offset 2) + (setq web-mode-enable-part-face t) + ) + + :ensure t) + +(provide 'ravi-init-web) +;;; ravi-init-web.el ends here |