X-Git-Url: https://iankelling.org/git/?p=dot-emacs;a=blobdiff_plain;f=myinit.el;h=5c5d1023b2b206a1a6b62e863f637c0200b09a9e;hp=2e1f3835a1d88bb4fee0bc2bf3793a02e1fafe1f;hb=87395fc29e64efbbef5c52bb0ac905cea46e6698;hpb=7c3660936ebc15b70a005c78df9cd32516e0c196 diff --git a/myinit.el b/myinit.el index 2e1f383..5c5d102 100644 --- a/myinit.el +++ b/myinit.el @@ -15,6 +15,40 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . +;;; Weird package bug workaround + + +;; without this, when installing a package, this message happens +;; +;; custom-handle-keyword: Unknown keyword :group +;; +;; but when i lookup the function, i get the following, and if +;; I evaluate it, the error goes away. so I think the real +;; definition is happening somewhere else + +(defun custom-handle-keyword (symbol keyword value type) + "For customization option SYMBOL, handle KEYWORD with VALUE. +Fourth argument TYPE is the custom option type." + (if purify-flag + (setq value (purecopy value))) + (cond ((eq keyword :group) + (custom-add-to-group value symbol type)) + ((eq keyword :version) + (custom-add-version symbol value)) + ((eq keyword :package-version) + (custom-add-package-version symbol value)) + ((eq keyword :link) + (custom-add-link symbol value)) + ((eq keyword :load) + (custom-add-load symbol value)) + ((eq keyword :tag) + (put symbol 'custom-tag value)) + ((eq keyword :set-after) + (custom-add-dependencies symbol value)) + (t + (error "Unknown keyword %s" keyword)))) + + ;;; misc emacs documentation ;;;; how to find auto-saved files that need recovering @@ -135,7 +169,7 @@ ;;; things that should be at the beginning ;; todo, evaluating this manually disables debug on error instead of toggling it -;;(toggle-debug-on-error) ;uncomment to help debug and catch errors +(toggle-debug-on-error) ;uncomment to help debug and catch errors ;; packages installed from package manager: i pretty much prioritize repos this way: gnu, then melpa, then marmalade. @@ -193,11 +227,6 @@ (setq custom-file "~/.emacs.d/custom.el") (load custom-file 'noerror) -;; undo tree stuff -;; more resilient undo-tree-history if we have their locations set up front. -(setq undo-tree-history-directory-alist '(("." . "~/.undo-tree-history"))) -;; Undo in region just happens accidentally, and throws me off, and it's been buggy in the past -(setq undo-tree-enable-undo-in-region nil) ;;; abreviations @@ -497,9 +526,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer." ;;; bbdb ;; based on bbdb manual -;; also has instructions to initialize upon launching gnus, etc -;; but I figure try this to make sure everything works all the time first -(require 'bbdb) +;; also has instructions to integrate with gnus, + (bbdb-initialize 'message) ;; recommended by gnus, @@ -509,18 +537,19 @@ A non-nil CURRENT-ONLY argument means save only current buffer." (setq message-kill-buffer-on-exit t) -;; based on emacs24-starter-kit -(setq bbdb-offer-save 'auto - bbdb-notice-auto-save-file t - bbdb-expand-mail-aliases t - bbdb-canonicalize-redundant-nets-p t - bbdb-complete-name-allow-cycling t) ;; use d instead (add-hook 'bbdb-mode-hook - (lambda () (define-key bbdb-mode-map (kbd "C-k") nil))) + (lambda () (define-key bbdb-mode-map (kbd "C-k") nil)) + ;; based on emacs24-starter-kit + (setq bbdb-offer-save 'auto + bbdb-notice-auto-save-file t + bbdb-expand-mail-aliases t + bbdb-canonicalize-redundant-nets-p t + bbdb-complete-name-allow-cycling t) + ) -(require 'bbdb-csv-import) +;;(require 'bbdb-csv-import) ;;; bookmark settings ; save bookmarks whenever they are changed instead of just when emacs quits @@ -560,12 +589,16 @@ A non-nil CURRENT-ONLY argument means save only current buffer." (defun toggle-night () (interactive) (cond ((equal (car custom-enabled-themes) 'naquadah) - (override-theme 'occidental)) + (override-theme 'leuven)) (t (override-theme 'naquadah)))) -;; for a long time i used leuven plus this, but it doesn't like dark terminal -;;(custom-set-faces `(default ((t (:background "#F6F6F0"))))) -(override-theme 'occidental) + + +;; in the leuven theme file, i made this change. will need to remake it +;; on package updates. I could fork, but its a pretty simple change +;; < `(default ((,class (:foreground "#333333" :background "#FFFFFF")))) +;; > `(default ((,class (:foreground "#333333" :background "#F6F6F0")))) +(override-theme 'leuven) ;; disable color thing with this: @@ -1056,10 +1089,10 @@ https://fsf.org | https://gnu.org (add-hook 'haskell-mode-hook (lambda () (define-key haskell-mode-map (kbd "C-(") - (lambda () (interactive) - (basic-save-buffer) - (haskell-compile) - (run-with-timer .3 nil 'repeat-shell))))) + (lambda () (interactive) + (basic-save-buffer) + (haskell-compile) + (run-with-timer .3 nil 'repeat-shell))))) (add-hook 'haskell-cabal-mode-hook (lambda () (define-key haskell-cabal-mode-map (kbd "C-(") 'haskell-compile))) @@ -1233,7 +1266,7 @@ https://fsf.org | https://gnu.org ;;(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode)) (require 'outshine) -(add-hook 'outline-minor-mode-hook 'outshine-hook-function) +(add-hook 'outline-minor-mode-hook 'outshine-mode) (add-hook 'emacs-lisp-mode-hook 'outline-minor-mode) (add-hook 'sh-mode-hook 'outline-minor-mode) @@ -1464,6 +1497,14 @@ https://fsf.org | https://gnu.org (setq tramp-default-method "ssh") ;;; misc general settings +(ivy-mode 1) +(add-hook 'text-mode-hook (lambda () (auto-fill-mode t))) +(setq counsel-find-file-at-point t) + +;; easier to read with just spaces as separator +(setf (nth 2 ido-decorations) " ") + + ;; https://www.emacswiki.org/emacs/FillParagraph ;; make list items start paragraphs. (setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ") @@ -1721,7 +1762,6 @@ Go to the next directory based on where the cursor is." (dot-mode . "") (yas-global-mode . "") (yas-minor-mode . "") - (undo-tree-mode . "") (volatile-highlights-mode . "") (highlight-symbol-mode . "") ;; Major modes @@ -1791,6 +1831,14 @@ Go to the next directory based on where the cursor is." (y (cdr pos))) (set-mouse-position (selected-frame) x y))) +;;;; keybinds for wow mouse + +(global-set-key (kbd "") 'move-mouse-to-point) +(global-set-key (kbd "") 'indent-region) +(global-set-key (kbd "") 'mark-defun) +(global-set-key (kbd "") 'ibuffer) +(global-set-key (kbd "") 'delete-horizontal-space) + ;;; org mode ;; todo work on org-cycle-emulate-tab @@ -2129,22 +2177,6 @@ indent yanked text (with prefix arg don't indent)." (setq TeX-parse-self t) -;;; undo tree - -;; undo-tree checks for minor modes which override -;; its minor mode keymap, and sets global keybinds if -;; that happens. this will prevent that, but I have no -;; reason to do that, so it is commented. -;; (defun undo-tree-overridden-undo-bindings-p () nil) - -;; todo, send patch undo-tree-visualize should scroll with the scroll key, instead of just pgup pgdn (aka next/prior) -(global-undo-tree-mode) -;; disabled due to bug, something like unknown entry in undo tree canary -;; (setq undo-tree-auto-save-history t) -(setq undo-outer-limit 100000000 ; per undo command - undo-limit 500000000 ; undo history limit - undo-strong-limit 600000000) ; undo history limit plus some extra - ;;; visible mark mode @@ -2215,6 +2247,19 @@ indent yanked text (with prefix arg don't indent)." erc-track-switch-direction 'importance) +;;; named commands +(defun rm-file-and-buffer () + "Removes file connected to current buffer and kills buffer." + (interactive) + (let ((filename (buffer-file-name)) + (buffer (current-buffer)) + (name (buffer-name))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (delete-file filename) + (kill-buffer buffer) + (message "File '%s' successfully removed" filename)))) + ;;; persistent registers ;; This needs to be at the end, because I visit a file, thus setting a ;; mode, and the mode hook needs to be setup before that. @@ -2229,3 +2274,1295 @@ indent yanked text (with prefix arg don't indent)." (?x (file . ,"/a/x.txt")) )) (set-register (car r) (cadr r))) + +(setq undo-outer-limit 100000000 ; per undo command + undo-limit 500000000 ; undo history limit + undo-strong-limit 600000000) ; undo history limit plus some extra + +;;; keybinds + +;;;; misc +(global-set-key (kbd "C-x C-b") 'ibuffer) + + +;; isearch-occur +;; Activate occur easily inside isearch +;; from starter-kit + +(define-key isearch-mode-map (kbd "C-o") + (lambda () (interactive) + (let ((case-fold-search isearch-case-fold-search)) + (occur (if isearch-regexp + isearch-string + (regexp-quote isearch-string)))))) + + +(defun my-isearch-toggle-regexp () + (interactive) + (isearch-toggle-regexp) + (cond (isearch-regexp + (global-set-key (kbd "C-r") 'isearch-backward-regexp) + (define-key global-map (kbd "") 'isearch-forward-regexp)) + (t + (global-set-key (kbd "C-r") 'isearch-backward) + (define-key global-map (kbd "") 'isearch-forward)))) +(define-key isearch-mode-map (kbd "M-r") 'my-isearch-toggle-regexp) + + +(define-key Info-mode-map "x" 'Info-follow-nearest-node) + + +;;;; single/special keys +;;;;; tab - isearch +(define-key isearch-mode-map (kbd "") 'isearch-query-replace) + +;;;;; f12 - isearch-forward +;; explained in http://stackoverflow.com/questions/7411920/how-to-bind-search-and-search-repeat-to-c-f-in-emacs +(global-set-key (kbd "") 'isearch-forward) +(global-set-key (kbd "") 'isearch-forward) +(define-key isearch-mode-map "\t" nil) +(define-key isearch-mode-map (kbd "") 'isearch-repeat-forward) +(define-key isearch-mode-map (kbd "") 'isearch-repeat-forward) +;; get rid of the standard completion binding, always use auto-complete +;; this didn't work very well +;;(global-set-key (kbd "TAB") 'auto-complete) +(define-key global-map [remap completion-at-point] 'auto-complete) + +;;;;; end - move-end-of-line +;; taken from emacs wiki, along with home function +;; http://www.emacswiki.org/emacs/BackToIndentationOrBeginning +(defun 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 end-of-code-or-line (arg) + "Move to end of line, or before start of comments depending on situation. + Toggle back and forth positions if we are already at one. + Comments are recognized in any mode that sets syntax-ppss + properly." + (interactive "P") + (when (catch 'bol + (let ((start (point)) + (bol (save-excursion + (beginning-of-line) + (point))) + (eol (progn (move-end-of-line arg) (point)))) + (while (point-in-comment) + (backward-char) + (when (= (point) bol) + (throw 'bol t))) + (throw 'bol (and (not (= eol start)) (>= start (point)))))) + (move-end-of-line arg))) + +(global-set-key (kbd "") 'end-of-code-or-line)(add-hook 'org-mode-hook (lambda () (define-key org-mode-map (kbd "") 'org-end-of-line))) + +;;;;; home - back-to-indentation +(defun back-to-indentation-or-beginning () + (interactive) + (if (= (point) (progn (back-to-indentation) (point))) + (if (derived-mode-p 'org-mode) + (org-beginning-of-line) + (beginning-of-line)))) +(global-set-key (kbd "") 'back-to-indentation-or-beginning) + +;;;;; s-tab - indent-buffer +(global-set-key (kbd "") 'indent-buffer) +;;;;; s-delete - send-shell + +(global-set-key (kbd "") 'send-shell) + +;; optional variables used by send-shell +(setq shell-send-yank-key nil) + +(defun repeat-shell () + (interactive) + "Repeat the last command in shell-mode, displaying the window if needed." + (let ((shell-buffer (get-buffer "*shell*"))) + (if shell-buffer + (buffer-window-show shell-buffer) + (let ((original-buffer (current-buffer))) + (funcall 'shell) + (setq shell-buffer (current-buffer)) + (switch-to-buffer original-buffer))) + (with-current-buffer shell-buffer + (goto-char (point-max)) + (call-interactively 'comint-previous-input) + ;; the t flag makes the buffer advance + (comint-send-input nil t)))) + +(setq compilation-filenames '("Makefile" "makefile")) + +(defun get-nearest-compilation-file () + "Search for the compilation file traversing up the directory tree." + (interactive) + (let ((dir default-directory) + (parent-dir (file-name-directory (directory-file-name default-directory))) + (nearest-compilation-file 'nil)) + (while (and (not (string= dir parent-dir)) + (not nearest-compilation-file)) + (dolist (filename compilation-filenames) + (setq file-path (concat dir filename)) + (when (file-readable-p file-path) + (setq nearest-compilation-file file-path))) + (setq dir parent-dir + parent-dir (file-name-directory (directory-file-name parent-dir)))) + nearest-compilation-file)) +(defun run () + (interactive) + "call run-fun if it is set, else run make if there is a makefile, +else save and repeat last shell command. +run-fun is meant to store file local variables, which show how to +do the main thing we want on this file, generally compile and +run. + +example of setting it in a file: +;; Local Variables: +;; run-fun: merge-test +;; End: " + (basic-save-buffer) + (if (and (boundp 'run-fun) run-fun) + (funcall run-fun) + (let ((makefile (get-nearest-compilation-file))) + (if (and makefile (stringp mode-name) (string= mode-name "C/l")) + (compile (format + "make -f %s" (get-nearest-compilation-file))) + (repeat-shell))))) + + +(defun send-shell () + (interactive) + (send-shell-buffer "*shell*" 'shell (kbd "C-v"))) + +(defun send-python () + (interactive) + (send-shell-buffer "*Python*" 'py-shell (kbd "C-v"))) + + +(defun send-shell-buffer (buffer-name &optional init shell-send-yank-key) + "Send current line or region to shell-mode buffer. +When in shell-mode, copy the current line to the +most recently visited visible window. + +SHELL-SEND-YANK-KEY: key to use instead +of yank to paste into recent window. This allows compatibility with +modes like org-mode which have their own yank function." + (if (string= (buffer-name) buffer-name) + ;; this section is copied out of comint-send-input + (progn + (let ((proc (get-buffer-process (current-buffer)))) + (if (not proc) (user-error "Current buffer has no process") + (widen) + + (let* ((pmark (process-mark proc)) + (intxt (if (>= (point) (marker-position pmark)) + (progn (if comint-eol-on-send (end-of-line)) + (buffer-substring pmark (point))) + (let ((copy (funcall comint-get-old-input))) + (goto-char pmark) + (insert copy) + copy)))) + + (if (= (length intxt) 0) + (kill-new (comint-previous-matching-input-string "." 1)) + (kill-new intxt))))) + (kill-append "\n" nil) + (select-window (previous-window nil nil 'visible)) + (if (and (boundp 'shell-send-yank-key) shell-send-yank-key) + (call-interactively (global-key-binding shell-send-yank-key)) + (yank)) + (select-window (next-window nil nil 'visible))) + (let (start end) + (if mark-active + (setq start (mark) + end (point)) + (setq start (save-excursion (beginning-of-line) (point)) + end (save-excursion (end-of-line) (point))) + (let (line-move-visual) + (call-interactively 'next-line))) + (send-comint-input buffer-name start end init)))) + +;; supporting functions +(defun send-comint-input (buffer-name start end &optional init) + "Input the region to BUFFER-NAME, assuming it is a comint-derived buffer. + Show BUFFER-NAME if it is not show. + Call INIT if BUFFER-NAME does not exist." + (let ((input (filter-buffer-substring start end))) + (send-comint-string buffer-name input init))) + +(defun send-comint-string (buffer-name string &optional init) + "Input the string to BUFFER-NAME, assuming it is a comint-derived buffer. + Show BUFFER-NAME if it is not show. + Call INIT if BUFFER-NAME does not exist." + (let ((buffer (get-buffer buffer-name))) + (unless buffer + (message "nobuffer") + ;; save-excursion etc. don't work for (shell), so I do this instead + (if init (let ((original-buffer (current-buffer))) + (funcall init (and (boundp 'send-shell-buffer-name) send-shell-buffer-name)) + (switch-to-buffer original-buffer) + (setq buffer (get-buffer buffer-name))) + (error "No existing buffer found and no init function argument. "))) + (buffer-window-show buffer) + (with-current-buffer buffer + (let ((proc (get-buffer-process buffer))) + (goto-char (process-mark proc)) + (insert string) + (comint-send-input nil t))))) + +(defun buffer-window-show (&optional buffer action) + "Like temp-buffer-window-show, but removed stuff + relevant to it being temp or help." + (let (window frame) + (with-current-buffer buffer + (when (let ((window-combination-limit + ;; When `window-combination-limit' equals + ;; `temp-buffer' or `temp-buffer-resize' and + ;; `temp-buffer-resize-mode' is enabled in this + ;; buffer bind it to t so resizing steals space + ;; preferably from the window that was split. + (if (or (eq window-combination-limit 'temp-buffer) + (and (eq window-combination-limit + 'temp-buffer-resize) + temp-buffer-resize-mode)) + t + window-combination-limit))) + ;; debug + ;;(message "window-combination-limit") + ;;(print window-combination-limit) + (setq window (display-buffer buffer action))) + (setq frame (window-frame window)) + (unless (eq frame (selected-frame)) + (raise-frame frame)) + (setq minibuffer-scroll-window window) + (set-window-hscroll window 0) + ;; Return the window. + window)))) + + +;; when poping help, etc, allow reusing a window in a different frame if it is visible +;; figured this out after spending quite a while reading doc string for display-buffer +;; which is the main function which uses this. +;; it will use other vars or its arg to override this, +;; but those things are often nil. +;; aha moments in reading it: ACTION = (FUNCTION-or-FUNCTIONLIST ALIST) +;; FRAME adds an association to ACTION's alist, but it's not used if ACTION arg is nil. +(setq display-buffer-fallback-action `(,(car display-buffer-fallback-action) . '(reusable-frames . visible))) +;; stop splitting windows verticallly when I open a buffer or shell +(setq split-height-threshold nil) + +;;;;; s-left arrow - shell +(global-set-key (kbd "") 'shell-wrap) +(add-hook 'org-mode-hook + (lambda () + (define-key org-mode-map (kbd "") nil))) + +;;;;; s-right arrow - keyboard-yank-primary +(defun keyboard-yank-primary () + (interactive) + (let ((mouse-yank-at-point t)) + (mouse-yank-primary nil))) +;; paste selection +(global-set-key (kbd "") 'keyboard-yank-primary) +(add-hook 'org-mode-hook + (lambda () + (define-key org-mode-map (kbd "") nil))) +;;;;; esc + ; todo, test out if this can be used +;;;;; return - new line + +;; todo, this doesn't set the keybind for the help minibuffer + + +(global-set-key (kbd "\r") 'indent-new-comment-line) + +;; don't use enter for autocomplete, we use tab or something +(define-key ac-completing-map (kbd "") nil) +(define-key ac-completing-map "\r" nil) + +(add-hook 'org-mode-hook + (lambda () + ;; copied from org-mode, replace org-enter with org-enter-indent + (org-defkey org-mode-map "\C-m" 'org-return-indent))) + + +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map "\r" nil) + (define-key comint-mode-map (kbd "") 'comint-send-input))) + +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map "\C-m" nil) + (define-key comint-mode-map "\C-d" nil))) + +;;;;; s-return - auto-correct-prev-word +(global-set-key (kbd "") 'flyspell-auto-correct-previous-word) +;; kp-enter is shift return in terminal +(global-set-key (kbd "") 'flyspell-auto-correct-previous-word) + +;;;;; s-down arrow - my-contract-region +(global-set-key (kbd "") 'my-contract-region) +;;;;; c-up/down move 8 lines + +;; compiling warns that next-line should be called interactively, +;; but we would have to do something dumb, like give it a +;; vector of keys in order to supply the 8 argument +(defun down-fast () + (interactive) + (next-line 8)) +(defun up-fast () + (interactive) + (next-line -8)) + +(global-set-key (kbd "") 'up-fast) +(global-set-key (kbd "") 'down-fast) + +;;;;; c-scroll comint prev/next prompt + +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map (kbd "") 'comint-previous-prompt) + (define-key comint-mode-map (kbd "") 'comint-next-prompt))) +;;;;; m-scroll prev/next sexp +(global-set-key (kbd "") 'backward-sexp) +(global-set-key (kbd "") 'forward-sexp) +;;;;; S-scroll expand/contract region +(global-set-key (kbd "") 'my-contract-region) +(global-set-key (kbd "") 'er/expand-region) +(global-set-key (kbd "") 'my-contract-region) +(global-set-key (kbd "") 'er/expand-region) + +(defun my-contract-region (arg) + (interactive "p") + (let ((current-prefix-arg '-)) + (call-interactively 'er/expand-region))) + +;; todo: define c-m scroll. i manually set to normal scrolling, i dunno why + + +;;;;; c-s-scroll scale text + +(global-set-key (kbd "") 'text-scale-increase) +(global-set-key (kbd "") 'text-scale-decrease) +(global-set-key (kbd "") 'text-scale-increase) +(global-set-key (kbd "") 'text-scale-decrease) +(global-set-key (kbd "") 'text-scale-increase) +(global-set-key (kbd "") 'text-scale-decrease) + + +;;;;; s-up arrow er/expand-region +(global-set-key (kbd "") 'er/expand-region) +;;;;; c-left/right move symbol + +(global-set-key (kbd "") 'backward-symbol) +(global-set-key (kbd "") 'forward-symbol) + +;;;; left primary + +;;;;; C-2 copy-symbol + +(global-unset-key (kbd "C-2")) +(defun copy-symbol (&optional arg) + "Copy symbol at point into kill-ring" + (interactive "P") + (kill-new (thing-at-point 'symbol))) + +(global-set-key (kbd "C-2") 'copy-symbol) + +;;;;; M-2 shell-cd-to-file + + +(defun shell-cd-to-file () + (interactive) + (let ((file (buffer-file-name))) + (if file + (send-comint-string "*shell*" + (concat "c " (file-name-directory file)) + 'shell) + (message "%s" "shell-cd-to-file: buffer has no file name")))) +(global-set-key (kbd "M-2") 'shell-cd-to-file) + +;;;;; C-M-2 --- + ; todo. whats going on here? +(global-unset-key (kbd "C-M-2")) + +;;;;; C-3 dot-mode-execute + +(global-set-key (kbd "C-3") 'dot-mode-execute) + +;;;;; C-M-3 recenter-top-bottom + +(global-set-key (kbd "C-M-3") 'recenter-top-bottom) + +;;;;; C-q org-cycle, comint previous arg + +(global-set-key (kbd "C-q") 'bicycle-cycle) +(add-hook 'org-mode-hook + (lambda () (define-key org-mode-map (kbd "C-q") 'org-cycle))) +(define-key widget-keymap (kbd "C-q") 'widget-forward) +(add-hook 'comint-mode-hook + (lambda () (define-key comint-mode-map (kbd "C-q") 'comint-insert-previous-argument))) + +;;;;; M-q org-archive-to-archive-sibling + +(global-set-key (kbd "M-q") 'org-archive-to-archive-sibling) + +;;;;; C-M-q quoted-insert + +(global-set-key (kbd "C-M-q") 'quoted-insert) + +;;;;; C-w --- +;; in terminal, it's ctrl-backspace, duplicate keybind. +;;;;; M-w org-clock-in + +(global-set-key (kbd "M-w") 'org-clock-in) + +;;;;; C-e copy-line + +;; todo, make repeated calls to this append the kills +(defun copy-line (&optional arg) + "Copy lines (as many as prefix argument) in the kill ring. + Ease of use features: + - Move to start of next line. + - Appends the copy on sequential calls. + - Use newline as last char even on the last line of the buffer. + - If region is active, copy its lines." + (interactive "p") + (let ((beg (line-beginning-position)) + (end (line-end-position (or arg 1)))) + (when mark-active + (if (> (point) (mark)) + (setq beg (save-excursion (goto-char (mark)) (line-beginning-position))) + (setq end (save-excursion (goto-char (mark)) (line-end-position))))) + (if (eq last-command 'copy-line) + (kill-append (buffer-substring beg end) (< end beg)) + (kill-ring-save beg end))) + (kill-append "\n" nil) + ;; dun need cuz I have yank-better + ;;(beginning-of-line (or (and arg (1+ arg)) 2)) + (if (and arg (not (= 1 arg))) (message "%d lines copied" arg))) + +(global-set-key (kbd "C-e") 'copy-line) + +;;;;; M-e org-clock-in-last + +(global-set-key (kbd "M-e") 'org-clock-in-last) + +;;;;; C-r isearch-backward + +(global-set-key (kbd "C-r") 'isearch-backward) +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map (kbd "C-r") 'comint-history-isearch-backward-regexp))) + +;;;;; M-r org-clock-out + +(global-set-key (kbd "M-r") 'org-clock-out) + +;;;;; C-a copy buffer + +(defun copy-all () + "Copy entire buffer to clipboard" + (interactive) + (clipboard-kill-ring-save (point-min) (point-max))) +(global-set-key (kbd "C-a") 'copy-all) + +;;;;; C-s - c-x prefix + ; prefix key binds. + ; good info http://www.masteringemacs.org/articles/2011/02/08/mastering-key-bindings-emacs/ + ; rebinding the prefix keys are tricky. apparently, some modes ignore any redefinition of a prefix key and use it explicitly, + ; so you have to dig into their key maps and redo things. + ; There are 2 simpler alternatives which have their own downsides. + ; One is cua mode, which I do not like because it smashes 2 keybinds onto 1 and limits what you can do. + ; The other is keyboard-translate, which translates the key presses before anything else. + ; The downside is that it translates them when you aren't using them as a prefix. + ; Since the swaps I'm using are all very accessible, the only downside is some mental jugling when reading docs etc about these keybinds. + + ; I've seen this as an another suggestion, it was a total fail. The prefix command took over both keys. + ; (define-key key-translation-map [f12] "\C-c") + ; (define-key key-translation-map "\C-c" [left]) + + + ;idea to remove the hook later since it is only needed at startup. + ; did not work however, and there is not a real need to fix it, so I did not investigate + ;(defun removeSwapHook () + ; (remove-hook 'buffer-list-update-hook 'myKeySwap) + ; (remove-hook 'change-major-mode-hook 'removeSwapHook)) + ;(add-hook 'change-major-mode-hook 'removeSwapHook) + + + ; went through almost all the relevant standard hooks, + ; this overcomes a known bug that (keyboard-translate) does not get applied when running emacs daemon + (add-hook 'buffer-list-update-hook (lambda () (interactive) + (keyboard-translate ?\C-x ?\C-s) + (keyboard-translate ?\C-s ?\C-x) + (keyboard-translate ?\C-c ?\C-d) + (keyboard-translate ?\C-d ?\C-c))) + + + + ; these all don't work + ; don't know why this doesn't error but reversing the keys does + ;(keyboard-translate ?\t ?\M-\t) + ;(keyboard-translate [M-tab] [tab]) + ; from what i can tell, it wants to use a keyboard-translate-table, + ; which is a char table, which is a vector indexed by chars, + ; and mod+tab is not a char (it has too many bits), it is an integer + ; it actually says it can hold vectors or strings, but that it is obsolete to do so + ;(characterp ?\M-a) + ;(characterp ?\C-a) + +;;;;; C-M-s - split-window-vertically + +(global-set-key (kbd "C-M-s") 'split-window-vertically) + +;;;;; C-d - C-c prefix +;;;;; C-M-d - swap buffer across windows +;; from http://www.emacswiki.org/emacs/TransposeWindows + +(setq swapping-buffer nil) +(setq swapping-window nil) +(defun swap-buffers-in-windows () + "Swap buffers between two windows" + (interactive) + (if (and swapping-window + swapping-buffer) + (let ((this-buffer (current-buffer)) + (this-window (selected-window))) + (if (and (window-live-p swapping-window) + (buffer-live-p swapping-buffer)) + (progn (switch-to-buffer swapping-buffer) + (select-window swapping-window) + (switch-to-buffer this-buffer) + (select-window this-window) + (message "Swapped buffers.")) + (message "Old buffer/window killed. Aborting.")) + (setq swapping-buffer nil) + (setq swapping-window nil)) + (progn + (setq swapping-buffer (current-buffer)) + (setq swapping-window (selected-window)) + (message "Buffer and window marked for swapping.")))) + +(global-set-key (kbd "C-M-d") 'swap-buffers-in-windows) + +;;;;; C-f] - kill-whole-line + +(global-set-key (kbd "C-f") 'kill-whole-line-wrapper) +(defun kill-whole-line-wrapper (&optional arg) + "If we are at the end of the file, kill backwards instead of doing nothing." + (interactive "P") + (if (= (point) (point-max)) + (kill-whole-line -1) + (kill-whole-line arg))) + +;;;;; M-f - print-var-at-point + +(defun print-var-at-point () + (interactive) + (let ((v (variable-at-point))) + (if (symbolp v) + (message "%s: %s" v (symbol-value v)) + (message "no symbol found at point")))) +(global-set-key (kbd "M-f") 'print-var-at-point) + + +;;;;; C-M-f - kill rest of line + + +(add-hook 'org-mode-hook + (lambda () + (define-key org-mode-map (kbd "C-M-f") 'org-kill-line))) + +(global-set-key (kbd "C-M-f") 'kill-line) +;;;;; C-g - cancel / other window + +(global-set-key (kbd "C-g") 'other-window) + +;;;;; M-g - abort-recursive-edit + +(global-set-key (kbd "M-g") 'abort-recursive-edit) + +;;;;; C-M-g - gnus + +(global-set-key (kbd "C-M-g") 'mu4e) + +;;;;; C-z - undo-only + +(global-set-key (kbd "C-z") 'undo-only) + +;;;;; C-x - kill-region + +(global-set-key (kbd "C-s") 'kill-region) + +;;;;; M-x - smex + +(global-set-key (kbd "M-x") 'smex) + +;;;;; C-M-x - cut-to-register + +;; same args as copy-to-register +(defun cut-to-register (register start end &optional delete-flag region) + (interactive (list (register-read-with-preview "Cut to register: ") + (region-beginning) + (region-end) + current-prefix-arg + t)) + (copy-to-register register start end t region)) + +(global-set-key (kbd "C-M-x") 'cut-to-register) + +;;;;; C-c - copy + +(global-set-key (kbd "C-d") 'kill-ring-save) +(add-hook 'c-mode-hook + (lambda () (define-key c-mode-map (kbd "C-d") nil))) +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map (kbd "C-d") nil))) +;; the base map is shared by many c-modes, like java +(add-hook 'c-mode-hook + (lambda () + (define-key c-mode-base-map "\C-d" nil) + (define-key c-mode-base-map (kbd "") 'c-electric-delete-forward))) + + +;;;;; M-c - org-capture + +(define-key global-map "\M-c" 'org-capture) + +;;;;; C-M-c - copy-to-register + +(global-set-key (kbd "C-M-c") 'copy-to-register) + +;;;;; C-v - yank + +(global-set-key (kbd "C-v") 'yank-better) + + + +(defun yank-better (arg) + "Paste, linewise if our kill ends with a newline. + I change the behavior of plain prefix. It makes it not do linewise paste, + because sometimes you want to yank pop and a linewise paste screws that up. + c-u with no number normally makes the point go before the yank. + That is pointless for me, as it would be just as easier and less + thought to pop the mark after yanking cuz it is set to before the mark." + (interactive "*P") + (if (and (not (equal arg '(4))) (string-suffix-p "\n" (current-kill 0 t))) + (beginning-of-line)) + (if (and (stringp mode-name) (string= mode-name "Org")) + (call-interactively 'org-yank) + (setq this-command 'yank) + (call-interactively 'yank (and (not (equal arg '(4))))))) + +(put 'yank-better 'delete-selection 'yank) + +;;;;; M-v - insert-register + +(global-set-key (kbd "M-v") 'insert-register) + +;;;;; C-M-v - yank-pop + +(global-set-key (kbd "C-M-v") 'yank-pop) + +;;;;; C-b - delete-other-windows + +(global-set-key (kbd "C-b") 'delete-other-windows) + +;;;;; M-b - isearch-backward-current-symbol + +(global-set-key (kbd "M-b") 'isearch-backward-current-symbol) + +;;;;; C-M-b - isearch-current-symbol + +(global-set-key (kbd "C-M-b") 'isearch-current-symbol) + +;;;;; C-tab - --- +;; in terminal, it's just TAB, duplicate keybind. +;;;;; M-tab - --- +;; in terminal it's duplicated of C-M-i +;;;;; C-delete - kill-symbol + +(global-set-key (kbd "") 'kill-symbol) +(defun kill-symbol (arg) + (interactive "p") + (kill-region (point) (save-excursion (forward-symbol arg) (point)))) + + +;;;;; C-M-delete - kill-sexp + +(global-set-key (kbd "") 'kill-sexp) + +;;;;; C-left-arrow - compile / comint search + +(defun set-p (var) + (and (bound-and-true-p var) + (not (eq var 'unset)))) +(global-set-key (kbd "C-(") 'run) + +;; make compile work from the gtags root dir +(defadvice compile (before pre-compile-advice activate) + (basic-save-buffer) + (when (set-p ggtags-project-root) + (setq-local compile-saved-dir default-directory) + (setq default-directory ggtags-project-root))) +(defadvice compile (after post-compile-advice activate) + (when (bound-and-true-p compile-saved-dir) + (setq default-directory compile-saved-dir))) + + +(add-hook 'c-mode-hook (lambda () (define-key c-mode-map (kbd "C-(") 'compile))) +(add-hook 'comint-mode-hook + (lambda () + (define-key isearch-mode-map (kbd "C-(") 'isearch-repeat-backward) + (define-key comint-mode-map (kbd "C-(") 'isearch-backward))) + + +;;;;; C-M-left-arrow - org-shiftup + +(add-hook 'org-mode-hook + (lambda () (define-key org-mode-map (kbd "C-M-(") 'org-shiftup))) + +;;;;; C-right-arrow - forward-symbol +;;;;; C-M-right-arrow - org-shiftdown +(add-hook 'org-mode-hook +(lambda () (define-key org-mode-map (kbd "C-M-)") 'org-shiftdown))) + +;;;;; C-backspace - backward-kill-symbol + +(global-set-key (kbd "") 'backward-kill-symbol) +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map (kbd "") 'backward-kill-word))) +(defun backward-kill-symbol (arg) + (interactive "p") + (kill-region (point) (save-excursion (backward-symbol arg) (point)))) + +;;;;; C-M-backspace - backward-kill-sexp + +(global-set-key (kbd "") 'backward-kill-sexp) + +;;;; right primary +;;;;; C-* - split-window-horizontally + +(global-set-key (kbd "C-*") 'split-window-horizontally) + +;;;;; C-M-* - calc-dispatch + +(global-set-key (kbd "C-M-*") 'calc-dispatch) + +;;;;; C-9 - delete-window-or-exit + +(global-set-key (kbd "C-9") 'delete-window-or-exit) + +(defun delete-window-or-exit () + "Delete window or exit emacs." + (interactive) + (if (condition-case nil (delete-window) (error t)) + (if (or (boundp 'server-process) (> (length (frame-list)) 1)) + (progn (basic-save-buffer) (delete-frame)) + (save-buffers-kill-terminal t)))) + +;;;;; M-9 - kill-buffer + +(defun kill-buffer-no-ido () + "kill-buffer, avoid the ido remapping" + (interactive) + (kill-buffer)) +(global-set-key (kbd "M-9") 'kill-buffer-no-ido) + +;; strangely, in simple mode, this is overridden. +;; I found this map to override, but it didn't work, so it seems its being bound some other way. +;; I did a grep of the emacs sources, but couldn't find anything. +;; (define-key universal-argument-map [?9 nil) + +;;;;; C-M-9 - end server edit +;; save & kill buffer if it was opened externally via emacsclient + + + (defun server-edit-save () + (interactive) + (save-buffer) + (server-edit)) + (global-set-key (kbd "C-M-9") 'server-edit-save) + +;;;;; C-u - universal-argument +;;;;; C-M-u - search-keybind + + (global-set-key (kbd "C-M-u") 'search-keybind) + + (defun search-keybind (regexp &optional nlines) + (interactive (occur-read-primary-args)) + (save-excursion + (describe-bindings) + (set-buffer "*Help*") + (occur regexp) + (delete-windows-on "*Help*") + )) + +;;;;; C-i - ----- +;;;;; C-M-i - query-replace-regexp + + (global-set-key (kbd "C-M-i") 'query-replace-regexp) + (add-hook 'flyspell-mode-hook + (lambda () (define-key flyspell-mode-map (kbd "C-M-i") nil))) + (add-hook 'text-mode-hook + (lambda () (define-key text-mode-map (kbd "C-M-i") nil))) + + +;;;;; C-o - occur + + (global-set-key (kbd "C-o") 'occur) + +;;;;; C-M-o - counsel-imenu + + (global-set-key (kbd "C-M-o") 'counsel-imenu) + +;;;;; C-p - move-mouse-to-point + + (global-set-key (kbd "C-p") 'move-mouse-to-point) + +;;;;; C-M-p - delete-horizontal-space + + (global-set-key (kbd "C-M-p") 'delete-horizontal-space) + +;;;;; C-j - pop-to-mark + + (defun my-pop-to-mark-command () + "Jump to mark, and pop a new position for mark off the ring. + \(Does not affect global mark ring\)." + (interactive) + (pop-to-mark-command) + (if (and (derived-mode-p 'org-mode) (outline-invisible-p)) + (org-show-context 'mark-goto))) + + (global-set-key (kbd "C-j") 'my-pop-to-mark-command) + (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text) + (add-hook 'ido-setup-hook + (lambda () (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text))) + (add-hook 'lisp-interaction-mode-hook + (lambda () + (define-key lisp-interaction-mode-map (kbd "C-j") nil))) + + +;;;;; M-j - previous-error + + (global-set-key (kbd "M-j") 'previous-error) + +;;;;; C-M-j - register prefix + + (define-key global-map (kbd "C-M-j") ctl-x-r-map) + (define-key ctl-x-r-map "m" 'kmacro-to-register) + + +;;;;; C-k - jump-to-register + + + (global-set-key (kbd "C-k") 'jump-to-register) + +;;;;; M-k - next-error + + (global-set-key (kbd "M-k") 'next-error) + +;;;;; C-M-k - man + + (global-set-key (kbd "C-M-k") 'man) + +;;;;; C-l - ivy-switch-buffer + + (global-set-key (kbd "C-l") 'ivy-switch-buffer) + +;;;;; C-M-l - move cursor top bottom mid, comint clear screen + + (global-set-key (kbd "C-M-l") 'move-to-window-line-top-bottom) + +;;;;; C-; - used in flyspell, not sure what for, otherwise unbound +;;;;; M-; - comment-dwim +;;;;; C-M-; - comment-current-line-dwim + + (defun comment-current-line-dwim () + "Comment or uncomment the current line." + (interactive) + (save-excursion + (push-mark (beginning-of-line) t t) + (end-of-line) + (comment-dwim nil)) + (move-beginning-of-line 2)) + (global-set-key (kbd "C-M-;") 'comment-current-line-dwim) + +;;;;; C-M-m - recursive grep + + (define-key global-map (kbd "C-M-m") 'rgrep) + +;;;;; C-, - ounsel-find-file + + (global-set-key (kbd "C-,") 'counsel-find-file) + (add-hook 'flyspell-mode-hook + (lambda () (define-key flyspell-mode-map (kbd "C-,") nil))) + +;;;;; C-M-, - ind-file-in-project + + (global-set-key (kbd "C-M-,") 'find-file-in-project) + +;;;;; C-. - find recent file +;; Taken from starter kit. + + (defun recentf-ido-find-file () + "Find a recent file using Ido." + (interactive) + (let* ((file-assoc-list + (mapcar (lambda (x) + (cons (file-name-nondirectory x) + x)) + recentf-list)) + (filename-list + (remove-duplicates (mapcar #'car file-assoc-list) + :test #'string=)) + (filename (ido-completing-read "Choose recent file: " + filename-list + nil + t))) + (when filename + (find-file (cdr (assoc filename + file-assoc-list)))))) + + (add-hook 'flyspell-mode-hook + (lambda () (define-key flyspell-mode-map (kbd "C-.") nil))) + (define-key dot-mode-map (kbd "C-.") nil) + (global-set-key (kbd "C-.") 'recentf-ido-find-file) + (add-hook 'php-mode-hook + (lambda () (define-key php-mode-map (kbd "C-.") nil))) + +;;;;; C-M-. - - + + (define-key dot-mode-map (kbd "C-M-.") nil) + ;; (global-set-key (kbd "C-M-.") 'execute-extended-command) + +;;;;; C-/ - join lines + + (defun vim-style-join-line () + (interactive) + (join-line '(4))) + (global-set-key (kbd "C-/") 'vim-style-join-line) + +;;;;; C-M-/ - copy-buffer-file-name + + ;; haven't bound this atm, todo, maybe someday? + (defun copy-variable (variable) + (interactive + (let ((v (variable-at-point)) + (enable-recursive-minibuffers t) + val) + (setq val (completing-read (if (symbolp v) + (format + "Describe variable (default %s): " v) + "Describe variable: ") + obarray + (lambda (vv) + (or (get vv 'variable-documentation) + (and (boundp vv) (not (keywordp vv))))) + t nil nil + (if (symbolp v) (symbol-name v)))) + (list (if (equal val "") + v (intern val))))) + (kill-new (symbol-value variable))) + + (defun copy-buffer-file-name () + (interactive) + (let ((name (cond + ((derived-mode-p 'mu4e-view-mode) (mu4e-message-field-at-point :path)) + (t buffer-file-name)) + )) + (kill-new name) + (message name))) + + + (global-set-key (kbd "C-M-/") 'copy-buffer-file-name) + + + +;;;;; C-8 - calc-embedded-word + + (global-set-key (kbd "C-8") 'calc-embedded-word) + +;;;;; C-up-arrow - org prev headline + + ;; disabled just because i don't want to accidentally hit it + (define-key global-map "\C-_" nil) + (global-set-key (kbd "") 'beginning-of-defun) + + (add-hook 'org-mode-hook + (lambda () + (define-key org-mode-map (kbd "\C-_") 'outline-previous-visible-heading))) + + + + +;;;;; C-S-up-arrow - winner undo + + (global-set-key (kbd "") 'winner-undo) + +;;;;; C-down-arrow - org next headline + + (global-set-key (kbd "") 'end-of-defun) + + (add-hook 'org-mode-hook + (lambda () + (define-key org-mode-map (kbd "") 'outline-next-visible-heading))) + + + + +;;;;; C-M-down-arrow - toggle-mark-activation + + (defun toggle-mark-activation () + (interactive) + (if mark-active + (deactivate-mark t) + (activate-mark))) + + (global-set-key (kbd "") 'toggle-mark-activation) + +;;;;; C-S-down-arrow winner redo + + (global-set-key (kbd "") 'winner-redo) + + +;;;;; C-S-down-arrow - m-x for major mode + + (global-set-key (kbd "") 'smex-major-mode-commands) + +;;;;; C-lbracket - ---- +;;;;; C-M-lbracket - scroll-right + + (global-set-key (kbd "C-M-[") 'scroll-right) + +;;;;; C-rbracket - fill-paragraph + + (global-set-key (kbd "C-]") 'fill-paragraph) + +;;;;; C-M-rbracket - scroll-left + + (global-set-key (kbd "C-M-]") 'scroll-left) + +;;;;; C-return - newline-anywhere + + (defun newline-anywhere () + "Add a newline from anywhere in the line." + (interactive) + (end-of-line) + (newline-and-indent)) + (global-set-key (kbd "") 'newline-anywhere) + + +;;;;; M-return - plain newline + + (defun plain-newline () + (interactive) + (insert "\n")) + (global-set-key (kbd "") 'plain-newline) + + +;;;;; C-M-return - newline-anywhere-previous +(defun newline-anywhere-previous () + "Add a newline from anywhere in the line." + (interactive) + (forward-line -1) + (end-of-line) + (newline-and-indent)) +(global-set-key (kbd "") 'newline-anywhere-previous) + +;;;;; C-space - org-edit-special + +;; commented due to new keyboard needing ctrl-space for mark +;; (kbd "") does not work, (kbd "C-SPC") should work +;; (add-hook 'org-mode-hook +;; (lambda () +;; (define-key org-mode-map (kbd "C-SPC") 'org-edit-special) +;; ;; org-src-mode-map is broken in git version of emacs. +;; ;; temporarily use this for exiting edit-special mode. +;; (global-set-key (kbd "C-M--") 'org-edit-src-exit) +;; (define-key org-src-mode-map (kbd "C-SPC") 'org-edit-src-exit))) + +;;;;; C-M-space - before or under cursor + +(global-set-key (kbd "C-M-SPC") 'ispell-word) +;;;; left secondary +;;;;; C-M-4 - widen + +(global-set-key (kbd "C-M-4") 'widen) + +;;;;; C-tab-key - query-replace + + +(global-set-key (kbd "") 'query-replace) + +;;;;; C-t - org cycle todo / toggle comint motion + +(add-hook 'org-mode-hook + (lambda () + (define-key org-mode-map (kbd "C-t") 'org-todo))) + +(defun my-comint-previous-input (arg) + (interactive "*p") + (if (comint-after-pmark-p) + (comint-previous-input arg) + (forward-line -1))) + +(defun my-comint-next-input (arg) + (interactive "*p") + (if (comint-after-pmark-p) + (comint-next-input arg) + (forward-line))) + +(add-hook 'comint-mode-hook + (lambda () + (define-key comint-mode-map (kbd "C-t") 'comint-toggle-arrow-keys) + (define-key comint-mode-map (kbd "") 'my-comint-previous-input) + (define-key comint-mode-map (kbd "") 'my-comint-next-input))) + + +(defun comint-toggle-arrow-keys () + (interactive) + (toggle-arrow-keys comint-mode-map)) + +(setq-default comint-arrow-movement nil) +(defun toggle-arrow-keys (map) + (cond ((lookup-key map (kbd "")) + (setq-local comint-arrow-movement t) + (define-key map (kbd "") nil) + (define-key map (kbd "") nil)) + (t + (setq-local comint-arrow-movement nil) + (define-key map (kbd "") 'my-comint-previous-input) + (define-key map (kbd "") 'my-comint-next-input) + (goto-char (point-max))))) + +(eval-after-load "message" + '(define-key message-mode-map (kbd "C-t") 'mail-signature)) + + +;;;;; C-M-t - org timestamp + +(global-set-key (kbd "C-M-t") 'org-time-stamp-with-time) + +;;;;; C-home - start of buffer +;;;;; C-end - end of buffer +;;;; right secondary +;;;;; C-6 - save-buffers-kill-emacs + +(global-set-key (kbd "C-6") 'save-buffers-kill-emacs) + +;;;;; C-M-6 - insert-small-copyright + +(defun insert-small-copyright () + (interactive) + (beginning-of-line) + (let ((beg (point))) + (insert "Copyright (C) 2017 Ian Kelling\nThis program is under GPL v. 3 or later, see ") + (comment-region beg (point)))) + +(global-set-key (kbd "C-M-6") 'insert-small-copyright) + +;;;;; C-M-7 - insert-full-copyright + +(defun insert-full-copyright () + (interactive) + (beginning-of-line) + (let ((beg (point))) + (insert "Copyright (C) 2017 Ian Kelling\n") + (insert "\n") + (insert "This program is free software: you can redistribute it and/or modify\n") + (insert "it under the terms of the GNU General Public License as published by\n") + (insert "the Free Software Foundation, either version 3 of the License, or\n") + (insert "(at your option) any later version.\n") + (insert "\n") + (insert "This program is distributed in the hope that it will be useful,\n") + (insert "but WITHOUT ANY WARRANTY; without even the implied warranty of\n") + (insert "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") + (insert "GNU General Public License for more details.\n") + (insert "\n") + (insert "You should have received a copy of the GNU General Public License\n") + (insert "along with this program. If not, see .\n") + (comment-region beg (point)))) + +(global-set-key (kbd "C-M-7") 'insert-full-copyright) + + +;;;;; C-0 - text-scale-reset + +(defun text-scale-reset () + (interactive) + (text-scale-set 0)) +(global-set-key (kbd "C-0") 'text-scale-reset) + +;;;;; C-M-0 - insert-apache + +(defun insert-apache () + (interactive) + (beginning-of-line) + (let ((beg (point))) + (insert "Copyright (C) 2017 Ian Kelling\n") + (insert "\n") + (insert "Licensed under the Apache License, Version 2.0 (the \"License\");\n") + (insert "you may not use this file except in compliance with the License.\n") + (insert "You may obtain a copy of the License at\n") + (insert "\n") + (insert " http://www.apache.org/licenses/LICENSE-2.0\n") + (insert "\n") + (insert "Unless required by applicable law or agreed to in writing, software\n") + (insert "distributed under the License is distributed on an \"AS IS\" BASIS,\n") + (insert "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n") + (insert "See the License for the specific language governing permissions and\n") + (insert "limitations under the License.\n") + (comment-region beg (point)))) +(global-set-key (kbd "C-M-0") 'insert-apache) + + +;;;;; C-M-- - org-edit-src-exit +;;;;; C-y - undo + +(global-set-key (kbd "C-y") 'undo) +(add-hook 'org-mode-hook + (lambda () (define-key org-mode-map (kbd "C-y") nil))) + + +;;;;; C-\ - sr-speedbar-toggle +(global-set-key (kbd "C-\\") 'sr-speedbar-toggle) + +;;;;; C-M-\ - mark-defun + +(global-set-key (kbd "C-M-\\") 'mark-defun) + +;;;;; C-h - help-prefix + +;;;;; C-' - val-expression + +(global-set-key (kbd "C-'") 'eval-expression) + +;;;;; C-n - unpop to mark + +(defun unpop-to-mark-command () + "Unpop off mark ring. Does nothing if mark ring is empty." + (interactive) + (when mark-ring + (let ((pos (marker-position (car (last mark-ring))))) + (if (not (= (point) pos)) + (goto-char pos) + (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring)) + (set-marker (mark-marker) pos) + (setq mark-ring (nbutlast mark-ring)) + (goto-char (marker-position (car (last mark-ring)))))))) + +(global-set-key (kbd "C-n") 'unpop-to-mark-command) + +;;;;; C-M-n - narrow-to-region + +(global-set-key (kbd "C-M-n") 'narrow-to-region) + +;;;;; C-escape - find-tag + +(global-set-key (kbd "") 'find-tag)