* package setup
** standard emacs package stuff
#+BEGIN_SRC emacs-lisp
;;; handle setting stuff so I can work with packages.
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
#+END_SRC
** use-package bootstrapping
#+BEGIN_SRC emacs-lisp
;; bootstrap use-package, so I can use it to manage everything else
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile (require 'use-package))
(use-package use-package
:config
(setq use-package-always-ensure t))
#+END_SRC
* show-paren-mode
#+BEGIN_SRC emacs-lisp
(use-package paren
:config
(show-paren-mode 1)
;; Highlight the parenthesis at point and its match.
;; http://www.emacswiki.org/emacs/ShowParenMode
(setq show-paren-style 'expression)
;; zck make this highlight less important than the selection, so I
;; know what's selected. Maybe make a different highlight for text
;; that is both in the paren /and/ selected?
;; Highlight the entire expression
;; http://www.emacsblog.org/2007/08/07/quick-tip-show-paren-mode/
(set-face-background 'show-paren-match "#C0FFFF")
(set-face-background 'show-paren-mismatch "#FF4040")
(set-face-foreground 'show-paren-mismatch "#FFFFFF")
(set-face-attribute 'show-paren-mismatch nil
:weight 'bold)
;; change colors/fonts
;;http://emacs-fu.blogspot.com/2009/01/balancing-your-parentheses.html
)
#+END_SRC
* stuff to make each pixel of my screen use Emacs better
#+BEGIN_SRC emacs-lisp
(cl-pushnew '(fullscreen . maximized) initial-frame-alist)
(tool-bar-mode -1)
;; remove toolbar
;; http://www.emacswiki.org/emacs/ToolBar
(menu-bar-mode -1)
;; who needs 'em?
;; http://www.emacswiki.org/emacs/ToolBar
(set-scroll-bar-mode 'right)
;; http://www.emacswiki.org/emacs/ScrollBar
(mouse-avoidance-mode 'exile)
;; move the mouse pointer to the corner of the screen when approached
;; http://www.emacswiki.org/emacs/MouseAvoidance
#+END_SRC
* all my helm settings
#+BEGIN_SRC emacs-lisp
(use-package helm
:bind (("M-x" . helm-M-x)
("M-y" . helm-show-kill-ring)
("C-x C-f" . helm-find-files)
("M-s o" . helm-occur))
:config
(helm-mode 1)
(setq helm-echo-input-in-header-line t))
(use-package helm-files
:ensure helm
:config
;; These are mainly for choosing directories, when need be.
;; For example, when running dired.
(bind-key "C-<return>" #'helm-maybe-exit-minibuffer helm-find-files-map)
(bind-key "C-<return>" #'helm-maybe-exit-minibuffer helm-read-file-map)
(bind-key "<return>" #'helm-find-files-return helm-find-files-map)
(bind-key "<return>" #'helm-find-files-return helm-read-file-map))
(use-package helm-descbinds
:config
(helm-descbinds-mode))
(use-package helm-swoop
:bind (("C-c s s" . helm-swoop)
("C-c s b" . helm-swoop-back-to-last-point)
("C-c s m" . helm-multi-swoop)
("C-c s M" . helm-multi-swoop-all))
:config
(setq helm-swoop-use-line-number-face t)
(setq helm-swoop-split-direction 'split-window-horizontally)
(setq helm-swoop-pre-input-function (lambda () "")))
(use-package helm-projectile
:config
(helm-projectile-on))
#+END_SRC
** a few helm helper functions
#+BEGIN_SRC emacs-lisp
(defun helm-find-files-return ()
(interactive)
(if (file-directory-p (helm-get-selection))
(helm-execute-persistent-action)
(helm-maybe-exit-minibuffer)))
(defun helm-find-files-navigate-back (orig-fun &rest args)
(if (= (length helm-pattern) (length (helm-find-files-initial-input)))
(helm-find-files-up-one-level 1)
(apply orig-fun args)))
(advice-add 'helm-ff-delete-char-backward :around #'helm-find-files-navigate-back)
#+END_SRC
* open files in the right mode
#+BEGIN_SRC emacs-lisp
(add-to-list 'auto-mode-alist '("\\.arc\\'" . lisp-mode))
;; make .arc files open in lisp-mode
;; http://www.emacswiki.org/emacs/AutoModeAlist
(add-to-list 'auto-mode-alist '("\\.ps1\\'" . shell-script-mode))
(add-to-list 'auto-mode-alist '("\\.pp\\'" . ruby-mode))
(add-to-list 'auto-mode-alist '("\\.backup\\'" nil t))
(add-to-list 'auto-mode-alist '("\\.bak\\'" nil t))
#+END_SRC
* make emacs look right
#+BEGIN_SRC emacs-lisp
(column-number-mode t)
;; show the column number in the mode line
(size-indication-mode t)
;; show the buffer size in the mode line
;; http://www.emacswiki.org/emacs/ModeLineConfiguration
(which-function-mode)
;; Display the function I'm in in the modeline.
;; It could also be in the header.
;; From http://emacsredux.com/blog/2014/04/05/which-function-mode/
(setq frame-title-format '("%b - " invocation-name "@" system-name))
;; change the title of emacs
;; http://www.gnu.org/software/emacs/elisp/html_node/Frame-Titles.html
(setq truncate-partial-width-windows nil)
;; don't truncate lines of text when multiple windows; wrap them instead
;; http://www.emacswiki.org/emacs/TruncateLines
(setq split-width-threshold 120)
#+END_SRC
* bind some keys
#+BEGIN_SRC emacs-lisp
;; about binding keys: http://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html#Init-Rebinding
(bind-key "C-;" #'comment-dwim)
(bind-key "C-." #'other-window)
(bind-key "C-," #'prev-window)
(defun prev-window ()
(interactive)
(other-window -1))
(bind-key "C-x g" #'goto-line)
(global-unset-key (kbd "C-z"))
#+END_SRC
* some misc settings
#+BEGIN_SRC emacs-lisp
(setq confirm-kill-emacs 'y-or-n-p)
;; yell at me before going away
;; http://www.gnu.org/software/emacs/manual/html_node/emacs/Exiting.html
(setq inhibit-startup-message t)
(setq indicate-empty-lines t)
;; http://www.emacswiki.org/emacs/TheFringe
;; (setq tab-width 2)
;; (setq c-basic-offset 4)
(setq-default indent-tabs-mode nil)
;; Use spaces instead of tabs to indent
;; http://www.jwz.org/doc/tabs-vs-spaces.html
;; (desktop-save-mode 1)
;; save the state of the desktop
;; http://www.gnu.org/software/emacs/manual/html_node/emacs/Saving-Emacs-Sessions.html
#+END_SRC
* uniquify
#+BEGIN_SRC emacs-lisp
(use-package uniquify
:ensure nil ;;it's built-in
:config
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified
;; http://www.gnu.org/software/emacs/manual/html_node/emacs/Uniquify.html
;; http://trey-jackson.blogspot.com/2008/01/emacs-tip-11-uniquify.html
)
#+END_SRC
* go away, custom file!
#+BEGIN_SRC emacs-lisp
(setq custom-file "~/.emacs.d/custom.el")
(when (file-exists-p custom-file)
(load custom-file))
#+END_SRC
* table customization
#+BEGIN_SRC emacs-lisp
(use-package table
:config
(set-face-attribute 'table-cell nil
:background "light cyan"
:foreground "black"))
#+END_SRC
* org
#+BEGIN_SRC emacs-lisp
;; autoload functions "not immediately loaded when Org mode starts
;; http://orgmode.org/manual/Installation.html#Installation
(use-package org
:config
(add-hook 'org-mode-hook
'(lambda ()
(local-set-key (kbd "C-c f") 'org-footnote-action)
(local-set-key (kbd "C-,") 'prev-window)))
;; Keybinding for org-mode
;; http://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Commands.html
(setq org-startup-indented 't)
;; Display org-mode's indenting with spaces.
;; http://orgmode.org/manual/Clean-view.html
(setq org-startup-truncated nil)
;; Wrap long lines. This looks good with org-startup-indented.
(setq org-log-done 'time)
;; When we mark an item as done, timestamp it.
(push 'org-habit org-modules)
(setq org-src-fontify-natively t)
(push '(sh . t) org-babel-load-languages)
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
;; C-a, C-e should move to the beginning/end of the headline.
(setq org-special-ctrl-a/e t))
;;backported from org's git repo.
;;it fixes what happens when buffer-invisibility-spec is not a list.
;;Once Emacs updates its version of org, this can be removed.
(when (version<= (org-release)
"8.2.10")
(defun org-move-to-column (column &optional force _buffer)
"Move to column COLUMN.
Pass COLUMN and FORCE to `move-to-column'."
(let ((buffer-invisibility-spec
(if (listp buffer-invisibility-spec)
(remove '(org-filtered) buffer-invisibility-spec)
buffer-invisibility-spec)))
(move-to-column column force))))
;;from http://stackoverflow.com/questions/25437069/how-can-i-mark-org-habits-as-done-in-the-past
(defun org-todo-custom-date (&optional arg)
"Like org-todo-yesterday, but prompt the user for a date. The time
of change will be 23:59 on that day"
(interactive "P")
(let* ((hour (nth 2 (decode-time
(org-current-time))))
(daysback (- (date-to-day (current-time-string))
(org-time-string-to-absolute (org-read-date))))
(org-extend-today-until (+ 1
(* 24 (- daysback 1))
hour))
(org-use-effective-time t)) ; use the adjusted timestamp for logging
(if (eq major-mode 'org-agenda-mode)
(org-agenda-todo arg)
(org-todo arg))))
(use-package org-agenda
:ensure org
:bind
(("C-c a" . org-agenda))
:config
;;only match files that end in .org
(setq org-agenda-files (directory-files "~/org/" t "\.org$"))
;; We need both of these to bind the key both in agenda /and/ in regular .org files.
;; You would think org-agenda-keymap would inherit from org-mode-map, but apparently not.
(define-key org-agenda-keymap (kbd "C-c t") #'org-todo-custom-date)
(define-key org-mode-map (kbd "C-c t") #'org-todo-custom-date)
;; Start org agenda one day ago
(setq org-agenda-start-day "-1d")
(setq org-agenda-span 5)
(setq org-agenda-start-on-weekday nil)
;;custom agenda view
(push '("u"
"Unscheduled TODOs"
todo
""
((org-agenda-overriding-header "Unscheduled TODOs")
(org-agenda-skip-function '(org-agenda-skip-entry-if 'scheduled))))
org-agenda-custom-commands))
(use-package org-habit
:ensure org
:config
;; In org agenda, show habits whenever they occur
(setq org-habit-show-habits-only-for-today nil))
(use-package org-faces
:ensure org
:config
(set-face-attribute 'org-scheduled-previously nil :background "#ffff90" :foreground "Red")
(set-face-attribute 'org-agenda-clocking nil
:underline t
:overline t))
#+END_SRC
* ediff
#+BEGIN_SRC emacs-lisp
(use-package ediff-wind
:ensure ediff
:config
(setq ediff-split-window-function 'split-window-horizontally)
;; http://www.gnu.org/software/emacs/manual/html_node/ediff/Miscellaneous.html#Miscellaneous
)
#+END_SRC
* flycheck
#+BEGIN_SRC emacs-lisp
(use-package flycheck
:config
(global-flycheck-mode)
(bind-key "C-c C-." #'flycheck-next-error)
(bind-key "C-c C-," #'flycheck-previous-error))
(use-package flycheck-package
:config
(flycheck-package-setup))
#+END_SRC
* auto-complete
#+BEGIN_SRC emacs-lisp
(use-package auto-complete-config
:ensure auto-complete
:config
(ac-config-default)
(setq ac-show-menu-immediately-on-auto-complete t))
#+END_SRC
* projectile
#+BEGIN_SRC emacs-lisp
(use-package projectile
:config
(projectile-global-mode))
#+END_SRC
* web-mode
#+BEGIN_SRC emacs-lisp
(use-package web-mode
:config
(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.jsp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)))
#+END_SRC
* narrowing stuff
#+BEGIN_SRC emacs-lisp
;; I promise I can use this responsibly.
(put 'narrow-to-region 'disabled nil)
#+END_SRC
* font size
#+BEGIN_SRC emacs-lisp
;; Font size
(define-key global-map (kbd "C-+") 'text-scale-increase)
(define-key global-map (kbd "C-=") 'text-scale-increase)
(define-key global-map (kbd "C-_") 'text-scale-decrease)
(define-key global-map (kbd "C--") 'text-scale-decrease)
#+END_SRC
* smartparens
#+BEGIN_SRC emacs-lisp
(use-package smartparens
:init
(bind-key "C-M-f" #'sp-forward-sexp smartparens-mode-map)
(bind-key "C-M-b" #'sp-backward-sexp smartparens-mode-map)
(bind-key "C-)" #'sp-forward-slurp-sexp smartparens-mode-map)
(bind-key "C-(" #'sp-backward-slurp-sexp smartparens-mode-map)
(bind-key "M-)" #'sp-forward-barf-sexp smartparens-mode-map)
(bind-key "M-(" #'sp-backward-barf-sexp smartparens-mode-map)
(bind-key "C-S-s" #'sp-splice-sexp)
(bind-key "C-M-<backspace>" #'backward-kill-sexp)
(bind-key "C-M-S-<SPC>" (lambda () (interactive) (mark-sexp -1)))
:config
(smartparens-global-mode t)
(sp-pair "'" nil :actions :rem)
(sp-pair "`" nil :actions :rem)
(setq sp-highlight-pair-overlay nil))
#+END_SRC
* join next line
#+BEGIN_SRC emacs-lisp
(defun join-next-line ()
"Join this line to the next one. This is the dual of M-^, which joins the current line to the previous one."
(interactive)
(join-line t))
(bind-key "C-^" #'join-next-line)
#+END_SRC
* move-file
#+BEGIN_SRC emacs-lisp
(defun move-file (new-location)
"Write this file to NEW-LOCATION, and delete the old one."
(interactive (list (if buffer-file-name
(read-file-name "Move file to: ")
(read-file-name "Move file to: "
default-directory
(expand-file-name (file-name-nondirectory (buffer-name))
default-directory)))))
(let ((old-location (buffer-file-name)))
(write-file new-location t)
(when (and old-location
(file-exists-p new-location))
(delete-file old-location))))
(bind-key "C-x C-m" #'move-file)
#+END_SRC
* shrink-whitespace
#+BEGIN_SRC emacs-lisp
(use-package shrink-whitespace
:bind (("M-<SPC>" . shrink-whitespace)))
#+END_SRC
* count words non-crazily
#+BEGIN_SRC emacs-lisp
;; M-= is set to #'count-words-region by default, which uses the last selected region
;; when none is selected.
(bind-key "M-=" #'count-words)
#+END_SRC
* case dwim bindings
#+BEGIN_SRC emacs-lisp
(bind-key "M-u" #'upcase-dwim)
(bind-key "M-l" #'downcase-dwim)
(bind-key "M-c" #'capitalize-dwim)
#+END_SRC
* java
** eclim (disabled for now, to test meghanada) :noexport:
#+BEGIN_SRC emacs-lisp
(use-package eclim
;;When installing eclipse:
;; https://github.com/ervandew/eclim/issues/436
;; On the Eclipse installer: open the menu (bars button), switch to advanced mode, disable Bundle Pool and install Eclipse. Now it should work.
:init
(require 'cl)
:config
(global-eclim-mode)
(push "/home/zck/eclipse/mars/eclipse" eclim-eclipse-dirs)
(setq eclim-executable "/home/zck/eclipse/mars/eclipse/plugins/org.eclim_2.5.0/bin/eclim"))
(use-package eclimd
:ensure eclim)
;;for the daemon. Otherwise, /home/zck/eclipse/mars/eclipse/eclimd
#+END_SRC
** meghanada
#+BEGIN_SRC emacs-lisp
(use-package meghanada
:config
(add-hook 'java-mode-hook
(lambda ()
;; meghanada-mode on
(meghanada-mode t))))
#+END_SRC
* clojure stuff
#+BEGIN_SRC emacs-lisp
(use-package clojure-mode)
(use-package cider
:bind (("C-<return>" . cider-find-var)))
(use-package clj-refactor)
#+END_SRC
* scala stuff
#+BEGIN_SRC emacs-lisp
(use-package scala-mode)
#+END_SRC
* csharp stuff
#+BEGIN_SRC emacs-lisp
(use-package csharp-mode)
#+END_SRC
* echo keystrokes
#+BEGIN_SRC emacs-lisp
(setq echo-keystrokes 0.1)
#+END_SRC
* multi-term
#+BEGIN_SRC emacs-lisp
(use-package multi-term)
#+END_SRC
* easily repeat popping mark
#+BEGIN_SRC emacs-lisp
(setq set-mark-command-repeat-pop t)
#+END_SRC
* whitespace butler
#+BEGIN_SRC emacs-lisp
(use-package ws-butler
:config
(ws-butler-global-mode))
#+END_SRC
* backspace and delete should always go backward and forward, respectively
#+BEGIN_SRC emacs-lisp
(bind-key "M-<backspace>" #'backward-kill-word)
(bind-key "M-<delete>" #'kill-word)
#+END_SRC
* geiser
#+BEGIN_SRC emacs-lisp
(use-package geiser
:bind (("C-." . other-window)))
;; http://www.nongnu.org/geiser/
#+END_SRC
* narrow-to-enclosing-sexp
#+BEGIN_SRC emacs-lisp
(defvar narrow-to-enclosing-sexp-last-level 0
"Indicates the last narrow-to-enclosing-sexp operation performed.
Possible values: any non-negative integer.")
(defvar narrow-to-enclosing-sexp-repeat-sequence (kbd "s")
"The key to press to repeat narrow-to-enclosing-sexp.")
(defun narrow-to-enclosing-sexp (levels-out)
"Narrow to the LEVELS-OUTth enclosing s-expression.
If this function is called multiple times in a row, it will progressively widen
the narrowed region on s-expression out.
For the wider narrowing feature, this can be easily repeated with the key
in the variable narrow-to-enclosing-sexp-repeat-sequence."
(interactive "P")
(let ((current-level (cond (levels-out
(abs (prefix-numeric-value levels-out)))
((eq this-command last-command)
(1+ narrow-to-enclosing-sexp-last-level))
(t 1))))
(widen)
(save-excursion
(mark-enclosing-sexp current-level t)
(narrow-to-region (point) (mark)))
(recenter)
(setq narrow-to-enclosing-sexp-last-level current-level))
(set-transient-map
(let ((map (make-sparse-keymap)))
(define-key map narrow-to-enclosing-sexp-repeat-sequence #'narrow-to-enclosing-sexp)
map))
(message "Press %s to widen to the enclosing sexp." narrow-to-enclosing-sexp-repeat-sequence))
(defun mark-enclosing-sexp (levels-out &optional skip-whitespace-at-beginning)
"Mark the LEVELS-OUTth enclosing sexp.
If SKIP-WHITESPACE-AT-BEGINNING is true, then after going up LEVELS-OUT many sexps, move backward past any whitespace before marking the sexp."
(interactive "p")
(backward-up-list levels-out t t)
(when skip-whitespace-at-beginning
(skip-chars-backward " \t"))
(push-mark)
(forward-sexp))
(bind-key (kbd "C-x n s") #'narrow-to-enclosing-sexp)
#+END_SRC
* magit
#+BEGIN_SRC emacs-lisp
(use-package magit)
#+END_SRC
* backup files
#+BEGIN_SRC emacs-lisp
;; from http://pragmaticemacs.com/emacs/auto-save-and-backup-every-save/
(setq auto-save-interval 20)
(setq backup-by-copying t)
(setq version-control t)
(setq vc-make-backup-files t)
(setq delete-old-versions t)
(defvar backup-location
"~/emacs-backups")
(unless (file-exists-p backup-location)
(make-directory backup-location))
(setq backup-directory-alist
`(("." . ,backup-location)))
#+END_SRC
* delete file visited by buffer
#+BEGIN_SRC emacs-lisp
(defun delete-file-visited-by-buffer (buffername)
"Delete the file visited by the buffer named BUFFERNAME."
(interactive "bDelete file visited by buffer ")
(let* ((buffer (get-buffer buffername))
(filename (buffer-file-name buffer)))
(when buffer
(when (and filename
(file-exists-p filename))
(delete-file filename))
(kill-buffer buffer))))
#+END_SRC
* copy-line
#+BEGIN_SRC emacs-lisp
(defun copy-line (&optional copy-above)
"Copy the line point is on, placing the copy below the current line.
With prefix argument COPY-ABOVE, put the copy above the current line."
(interactive "P")
(save-excursion
(let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
(if copy-above
(progn (beginning-of-line)
(open-line 1))
(progn (end-of-line)
(insert "\n")))
(insert line)))
(set-transient-map
(lexical-let ((map (make-sparse-keymap))
(above-val copy-above))
(define-key map "c" (lambda () (interactive) (copy-line above-val)))
map))
(message "press c to copy again!"))
(bind-key "C-x c" #'copy-line)
#+END_SRC
* zarduino
#+BEGIN_SRC emacs-lisp :tangle no
(defvar zarduino-location "~/code/zarduino.el/zarduino.el")
(when (file-exists-p zarduino-location)
(package-install-file zarduino-location)
(require 'zarduino)
(setq zarduino/arduino-executable-path "~/programs/arduino-ide/arduino-1.6.10/arduino"))
#+END_SRC
* indent-specified
#+BEGIN_SRC emacs-lisp
(defun indent-specified (indent-amount region-start region-end)
"Make the region indented by INDENT-AMOUNT.
The region is between REGION-START and REGION-END, but also includes anything
on the same line as REGION-START, but before REGION-START."
(interactive "nindent by: \nr")
(save-excursion
(goto-char region-start)
(beginning-of-line)
(looking-at "\\([ \t]*\\)")
(let ((start-before-whitespace (point))
(whitespaces (- (match-end 0)
(match-beginning 0)))
(region-end-marker (make-marker)))
(set-marker region-end-marker region-end)
(delete-from-lines whitespaces region-start region-end)
(goto-char region-end)
(beginning-of-line)
(string-insert-rectangle start-before-whitespace
(point)
(make-string indent-amount ?\s))
;;v2: get leading spaces in all lines, don't dedent below that.
(lexical-let ((keymap (make-sparse-keymap))
(region-start region-start)
(region-end (marker-position region-end-marker)))
(message "press a number to indent that much, or enter to prompt for a number 10 or greater.")
(dotimes (num 10)
(define-key keymap
(kbd (format "%d" num))
`(lambda () (interactive) (indent-specified ,num ,region-start ,region-end))))
(define-key keymap (kbd "<return>") (lambda () (interactive) (call-interactively #'indent-specified)))
(set-transient-map keymap)))))
(defun delete-from-lines (chars region-start region-end)
"Delete CHARS characters from the beginning of each line between REGION-START and REGION-END."
(let ((end-marker (make-marker)))
(set-marker end-marker region-end)
(save-excursion
(goto-char region-start)
(beginning-of-line)
(while (< (point)
(marker-position end-marker))
(delete-char chars)
(end-of-line)
(unless (eobp)
(forward-line)
(beginning-of-line))))))
#+END_SRC
* rectangle changes
#+BEGIN_SRC emacs-lisp
(bind-key "C-x r DEL" #'delete-rectangle)
#+END_SRC
* secondary selection colors
#+BEGIN_SRC emacs-lisp
(set-face-background 'secondary-selection "#F0F0B0")
#+END_SRC
* TODOs
* bucket o' lisp
#+BEGIN_SRC emacs-lisp
;;toggle-debug-on-error doesn't seem to work with this init file...?
#+END_SRC
* shell-mode -- display shell buffer in same window.
#+BEGIN_SRC emacs-lisp
(add-to-list 'display-buffer-alist
'("^\\*shell\\*$" . (display-buffer-same-window)))
#+END_SRC
* gnus setup
#+BEGIN_SRC emacs-lisp
(setq gnus-select-method '(nntp "news.gmane.org"))
#+END_SRC
* custom scrolling
Also maybe instead of using scroll-up, this should move MINI-SCROLL-AMOUNT lines down/up, then recenter?
#+BEGIN_SRC emacs-lisp
(defvar mini-scroll-amount 5
"The number of lines to mini-scroll.")
(defvar mini-scroll-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "<up>") #'mini-scroll-down)
(define-key map (kbd "<down>") #'mini-scroll-up)
(define-key map (kbd "<prior>") #'mini-scroll-down)
(define-key map (kbd "<next>") #'mini-scroll-up)
(define-key map (kbd "<SPC>") #'mini-scroll-up)
(define-key map (kbd "S-<SPC>") #'mini-scroll-down)
(define-key map (kbd "<backspace>") #'mini-scroll-down)
(define-key map (kbd "C-v") #'mini-scroll-up)
(define-key map (kbd "M-v") #'mini-scroll-down)
map))
(defun mini-scroll (lines)
"Mini-scroll by LINES lines."
(interactive)
(scroll-up lines)
(set-transient-map mini-scroll-map)
(message "Mini-scroll! (C-v to scroll down by %s lines, M-v to scroll up)" mini-scroll-amount))
(defun mini-scroll-down ()
"Mini-scroll down."
(interactive)
(mini-scroll (- mini-scroll-amount)))
(defun mini-scroll-up ()
"Mini-scroll up."
(interactive)
(mini-scroll mini-scroll-amount))
(bind-key "C-S-v" #'mini-scroll-up)
(bind-key "M-S-v" #'mini-scroll-down)
#+END_SRC
* mercurial (ahg)
#+BEGIN_SRC emacs-lisp
(use-package ahg)
#+END_SRC
* camelcase and snake case functions.
on this test data:
arst_tsra__
camelcase-word results in:
arst_tsra__
on:
arst_tsra__
result:
arst_tsra__
#+BEGIN_SRC emacs-lisp
(defun camelcase-dwim (arg)
"Camelcase words in the region, if active; if not, camelcase word at point.
If the region is active, this function calls `camelcase-region'.
Otherwise, it calls `camelcase-word', with prefix argument passed to it
to camelcase ARG words."
(interactive "*p")
(if (use-region-p)
(camelcase-region (region-beginning) (region-end))
(progn (camelcase-word arg)
(while (looking-at "_+\\w")
(camelcase-word 1)))))
;;how does this work on caps?
(defun camelcase-region (region-beginning region-end)
"Camelcase the region between REGION-BEGINNING and REGION-END.
This converts it from snake_case to camelCase."
(interactive "*r")
(downcase-region region-beginning region-end)
(let ((end-marker (make-marker)))
(move-marker end-marker region-end)
(goto-char region-beginning)
(while (re-search-forward "_+\\(\\w\\)?"
;;zck check difference between "\\(\\w\\)?" and "\\(\\w?\\)"
(marker-position end-marker)
t)
(let ((first-char-after (match-string 1)))
(replace-match "")
(if (looking-back "\\w")
(insert (upcase first-char-after))
(insert first-char-after))))
(goto-char (marker-position end-marker))))
(defun downcase-char ()
"Downcase the char at point."
(interactive)
(downcase-region (point)
(1+ (point))))
(defun upcase-char ()
"Upcase the char at point."
(interactive)
(upcase-region (point)
(1+ (point))))
(defun camelcase-word (words)
"Camelcase WORDS words forward from point."
(interactive "p")
(camelcase-region (point)
(progn (forward-word words)
(point))))
(defun snakecase-dwim (arg)
"Snakecase words in the region, if active; if not, snakecase word at point.
If the region is active, this function calls `snakecase-region'.
Otherwise, it calls `snakecase-word', with prefix argument passed to it
to snakecase ARG words."
(interactive "*p")
(if (use-region-p)
(snakecase-region (region-beginning) (region-end))
(snakecase-word arg)))
(defun snakecase-region (region-beginning region-end)
"Snakecase the region between REGION-BEGINNING and REGION-END.
This converts it from camelCase to snake_case."
(interactive "*r")
(goto-char region-beginning)
(let ((end-marker (make-marker))
(case-fold-search nil))
(move-marker end-marker region-end)
;;We want insertions before the marker, not after.
;;This prevents the marker being not at the end of a word we've already snakecased,
;;if the word ends with capital letters. (e.g., myIP)
(set-marker-insertion-type end-marker t)
(goto-char region-beginning)
(while (re-search-forward "\\([[:lower:]]?\\)\\([[:upper:]]+\\)"
(marker-position end-marker)
t)
(let ((before-underscore (match-string 1))
(after-underscore (downcase (match-string 2))))
(replace-match "")
;;Don't insert an undescore for words beginning with a capital letter,
;;like IPAddress.
(when (> (length before-underscore)
0)
(insert before-underscore "_"))
(insert after-underscore)
;;when we have multiple capital letters before lowercase ones,
;;treat all of them but the last one as one word,
;;and the last one as the start of a new word.
;;so myIPAddress becomes my_ip_address
;;but myIP becomes my_ip
(when (and (> (length after-underscore)
1)
(looking-at "[[:lower:]]"))
(backward-char)
(insert "_"))))
(goto-char (marker-position end-marker))))
(defun snakecase-region-old (region-beginning region-end)
"Snakecase the region between REGION-BEGINNING and REGION-END.
This converts it from camelCase to snake_case."
(interactive "*r")
(goto-char region-beginning)
(let ((end-marker (make-marker))
(case-fold-search nil))
(move-marker end-marker region-end)
(while (< (point)
(marker-position end-marker))
(let ((found (re-search-forward "[[:upper:]]" nil t)))
(if (and found
(< (point)
(marker-position end-marker)))
(progn (backward-char 1)
(when (looking-back "[[:word:]]")
(insert "_"))
(downcase-char)
;;now handle repeated caps, as in my_iPAddress -> my_ip_address
(when (looking-at "[[:upper:]]")
(while (looking-at "[[:upper:]]")
(downcase-char))
(when (looking-at "[[:word:]]")
(backward-char 1)
(insert "_"))))
(goto-char (marker-position end-marker)))))))
(defun snakecase-word (words)
"Snakecase WORDS words forward from point."
(interactive "p")
(snakecase-region (point)
(progn (forward-word words)
(point))))
(bind-key "M-C" #'camelcase-dwim)
(bind-key "M-S" #'snakecase-dwim)
#+END_SRC
* markdown-mode
#+BEGIN_SRC emacs-lisp
(use-package markdown-mode)
#+END_SRC
* reactivate-mark
#+BEGIN_SRC emacs-lisp
(defun reactivate-mark ()
"Reactivate the mark."
(interactive)
(activate-mark))
(bind-key "C-S-<SPC>" #'reactivate-mark)
#+END_SRC
* region customization
make the region a little less bold, so it's easier to read stuff
#+BEGIN_SRC emacs-lisp
(set-face-background 'region "#ffa020")
#+END_SRC
* python
#+BEGIN_SRC emacs-lisp
;;after installing, run `M-x elpy-config`
(use-package elpy)
#+END_SRC
* help-mode
#+BEGIN_SRC emacs-lisp
(use-package help
:ensure nil ;;built-in
:bind (:map help-mode-map
("b" . help-go-back)
("p" . help-go-back)
("f" . help-go-forward)
("n" . help-go-forward)))
#+END_SRC