From cd69beabf5aef9e21d98e53689583465577b4718 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Mon, 10 Jun 2019 22:32:50 -0400 Subject: [PATCH] move most of init into normal .el file --- init-notes.org | 1505 ++++++++++++++++++ init.el | 1 + my-init.org | 4014 +----------------------------------------------- myinit.el | 2228 +++++++++++++++++++++++++++ 4 files changed, 3739 insertions(+), 4009 deletions(-) create mode 100644 init-notes.org create mode 100644 myinit.el diff --git a/init-notes.org b/init-notes.org new file mode 100644 index 0000000..af7bad9 --- /dev/null +++ b/init-notes.org @@ -0,0 +1,1505 @@ +* python disabled due to long load time +todo: get smart-operator to work +todo, checkout https://github.com/python-rope/ropemacs refactoring python, +todo, try py-autopep8, autoformatter +todo, check out some python linting stuff. pychecker is one, others are in *packages* +todo, finish reading through python-mode.el functions +;; todo, figure out multi-line input in shell mode + + +usefull m-x commands: +m-x py-describe-mode: doc for mode which is extensive +m-x py-sort-imports +m-x py-guess-indent-offset: setup indent for code i didn't write + +possibly usefull commands: +found via looking through python-mode.el, quit like 1/4 through, cuz its tedious, last spot was at: +(defun py-comment-region (beg end &optional arg) +after finding py-describe-mode, it seemed to do a good job of documenting all the most important stuff + +py-switch-to-python +python-shell-completion-complete-or-indent may be usefull to get completion working in the shell +py-insert-default-shebang +py-electric-* +py-indent-line-outmost +py-newline-and-close-block +py-indent-and-forward (indent line, move to next) +py-fill-* +py-which-function (for showing in the modeline) +py-help-at-point +py-execute-import-or-reload +py-execute-def-or-class +various pdb functions + + +installing jedi +#+begin_src sh :tangle no +pi python-pip +s pip install jedi virtualenv +#+end_src +then do m-x jedi:install-server + + + +disabled because it takes 152 ms to load, +and I don't know how to do it conditioally +#+begin_src emacs-lisp :tangle no + +;; change from default python3 to be compatibile with Pywikibot +(setq py-shell-name "/usr/bin/python") +(require 'python-mode) + +(setq py-autopep8-options '("--max-line-length=110")) + +(defun py-execute-block-or-clause-create-shell () + (interactive) + (cond ((get-buffer "*Python*") + (py--execute-prepare "block-or-clause") + (py-execute-block-or-clause) + (call-interactively 'next-line)) + (t + (py-shell) + ;; py-shell starts the shell but not display the buffer on the first run + ;; subsequent runs, it does. I grabbed this command from inside to + ;; do just the relevant part from the second run, as a hack. + ;; todo: report a bug on this + (py--shell-manage-windows py-buffer-name)))) +(setq py-tab-shifts-region-p t) +(setq py-tab-indents-region-p t) + +(defun py-run () + "default action to run the current buffer" + (basic-save-buffer) + (py-execute-buffer)) + + +(add-hook 'python-mode-hook + (lambda () + (setq run-fun 'py-run) + (define-key python-mode-map (kbd "C-M-a") nil) + (define-key python-mode-map (kbd "C-M-d") nil) + (define-key python-mode-map (kbd "C-M-e") nil) + (define-key python-mode-map (kbd "C-M-h") nil) + (define-key python-mode-map (kbd "C-M-i") nil) + (define-key python-mode-map (kbd "C-M-u") nil) + (define-key python-mode-map (kbd "C-M-x") nil) + (define-key python-mode-map (kbd "") 'indent-for-tab-command) + (define-key python-mode-map (kbd "C-j") nil) + (define-key python-mode-map (kbd "") nil) + ;;(define-key python-mode-map (kbd "C-(") (lambda () (interactive) (basic-save-buffer) (py-execute-buffer))) + ;; fix default return bindings + (define-key python-mode-map (kbd "C-j") nil) + (define-key python-mode-map (kbd "RET") nil) + (define-key python-mode-map (kbd "") 'py-newline-and-indent) + (define-key python-mode-map (kbd "") 'py-indent-line) + (define-key python-mode-map (kbd "C-M-(") 'py-shift-left) + (define-key python-mode-map (kbd "C-M-)") 'py-shift-right) + (define-key python-mode-map (kbd "") 'py-beginning-of-line) + (define-key python-mode-map (kbd "") 'py-end-of-line) + (define-key python-mode-map (kbd "C-t") 'py-execute-block-or-clause-create-shell) + (define-key python-mode-map (kbd "") 'py-ian-execute-line-or-region) + ;; python mode adds these to this list, which is normally empty. + ;; it makes my send-python function not reuse an existing python shell window + ;; there are other ways to override this, but I don't know of any other value of + ;; having this set. + (setq same-window-buffer-names (delete "*Python*" same-window-buffer-names)) + (setq same-window-buffer-names (delete "*IPython*" same-window-buffer-names)))) + +;; i dunno, why, but this didn't work: +;; and we can't eval-after-load cuz it is part of the greater python mode file +(add-hook 'py-shell-hook + (lambda () + (define-key py-shell-map "\r" nil) + (define-key py-shell-map (kbd "") 'comint-send-input) + (define-key py-shell-map (kbd "C-t") 'py-shell-toggle-arrow-keys) + (define-key py-shell-map "\C-d" nil) + (define-key py-shell-map (kbd "") 'my-comint-previous-input) + (define-key py-shell-map (kbd "") 'my-comint-next-input))) + + +(defun py-ian-execute-line-or-region () + (interactive) + (cond ((get-buffer "*Python*") + (if mark-active + (py-execute-region) + (py-execute-statement)) + (call-interactively 'next-line)) + (t (py-shell)))) + +;; http://tkf.github.io/emacs-jedi/latest/ +(add-hook 'python-mode-hook 'jedi:setup) +(setq jedi:complete-on-dot t) + +(defun py-shell-toggle-arrow-keys () + (interactive) + (toggle-arrow-keys py-shell-map)) + +#+end_src + + +;; py-shell window stuff +;; it splits the window if the shell is in a different frame +;; which seems to be a bug, but it can be fixed with this option +;; (setq py-keep-windows-configuration 'force) +;; however, with py-execute-block-or-clause, if the shell is in a different frame, +;; you get errors "buffer is read only", when the point is near the beginning of a command +;; todo: test with emacs -Q and file a bug +;; if you execute py-execute-... without a python shell open, +;; it starts one, doesn't display it, and subsequent py-execute commands +;; give error "buffer is read only" +;; these functions fix / improve these problems + + +** initial python-mode setup + +python-mode seems to be the most canonical package, based on +https://docs.python.org/devguide/emacs.html +much more feature rich than the emacs built in one. + +getting it, it wants you to setup an account on launchpad by default, +there is some way to get anonymous bzr access, but google didn't answer it right away, +so fuck it, ill go the happy path. + +based on error messages, +add public ssh key to https://launchpad.net/people/+me +bzr launchpad-login iank +cd ~/.emacs.d/src/ +bzr branch lp:python-mode + +add lines from INSTALL to init + + +** background on packages +jedi appears most popular based on github stats +pysmell appears dead +ac-python appears dead +https://github.com/proofit404/anaconda-mode seems to be kicking along + + +** misc notes: + +python-mode has a TON of functions that are just aliases or verbatim wrappers of other functions. +also has undocumented/unused vars all around. it is quite annoying. + +the dedicated argument to py-shell does nothing, +and py-dedicated-shell just sets that, so it is a waste + + +** background on sending to python shell + +using the builtin python execute shell functions, sending one line doesn't really work well. +The bulit in functions don't wait for further input if a block is not closed. +And doing a copy/paste thing gets messed up because of indents. +With some hacking, I could probably do copy/paste and remove indents, only to a +certain level if we have entered a block and are waiting to finish it. +But just doing the builtin execute block is a decent work around. + + +Here is the scrapped function for single line built in sending to shell. + + +(setq w32-enable-num-lock nil) +(global-set-key (kbd "") 'left-char) + + +(defun sqlup-find-correct-keywords () + "If emacs is handling the logic for syntax highlighting of SQL keywords, then we piggyback on top of that logic. If not, we use an sql-mode function to create a list of regular expressions and use that." + (mapcar 'car (sql-add-product-keywords sql-product '()))) + + +largest subarray sum, array of pos and neg ints. + +* disabled but saved for documentation purposes +:PROPERTIES: +:header-args: :tangle no +:END: + +** ido keybinds +*** C-j +ido-find-file create file +*** //] +ido goto root +*** C-k] +ido kill buffer/file +*** C-d] +ido open dired buffer +*** M-d] +ido search within all subdirectories +*** M-m] +ido create subdirectory +*** M-s] +ido search recently used directories +*** M-n/p] +ido next/previous recently used directory +*** C-s] +**** TODO implement this keybind, normally ctrl-space +ido use current pattern and start a new one + + +** indent settings for git's perl code +don't have a way to set this automatically or a good place to put this +#+begin_src emacs-lisp +(setq + perl-indent-level 8 + perl-continued-statement-offset 8 + perl-continued-brace-offset -8 + perl-brace-offset 0 + perl-brace-imaginary-offset 0 + indent-tabs-mode t + ) +#+end_src +** org mode website + +#+begin_src emacs-lisp +;; use org-publish-current-project with a project file open +(setq org-publish-project-alist + '(("org" + :base-directory "/a/h/src" + :publishing-directory "/a/h/output" + :base-extension "org" + ;;:publishing-function org-org-publish-to-org + :publishing-function org-html-publish-to-html + :preserve-breaks t + :html-postamble "Everything here is \"Creative" + :html-head "" + :htmlized-source t) + ("othersrc" + :base-directory "/a/h/src" + :base-extension "css\\|el\\|" + :publishing-directory "/a/h/output" + :publishing-function org-publish-attachment) + ("other" + :base-directory "/a/h/other" + :base-extension ".*" + :publishing-directory "/a/h/output" + :publishing-function org-publish-attachment))) +;; default is xhtml-strict. don't really care, but this is more common +(setq org-html-doctype "html4-strict") + +;; this is needed for worg +;; todo: for my own site, I need to define the css in a separate file +;; in order to use this setting. see the variable help for info +(setq org-export-htmlize-output-type t) + + +#+end_src + +** bash-completion +#+begin_src emacs-lisp +;; this eventually gets set in +;; comint-dynamic-complete-functions +;; (car comint-dynamic-complete-functions) +(autoload 'bash-completion-dynamic-complete "bash-completion" + "BASH completion hook") +(add-hook 'shell-dynamic-complete-functions + 'bash-completion-dynamic-complete) + +;; this appears useless, but was in the recommended init code +(add-hook 'shell-command-complete-functions + 'bash-completion-dynamic-complete) + +(defun ac-rlc-setup-sources () + "Add me to shell-mode-hook!" + (setq ac-sources '(ac-source-shell))) +(add-hook 'shell-mode-hook 'ac-rlc-setup-sources) + +#+end_src + +** misc stuff + It is an awesome mode for keyboard navigation. + However, using the mouse takes less thought and works as well + + #+begin_src emacs-lisp + + + ;; whitespace-mode config. minimal for bad whitespace + ;(setq whitespace-line-column 80) ; for style of lines-tail, but I have it disabled + (setq whitespace-style '(face tabs empty trailing)) + ;to enable whitespace mode + (whitespace-mode +1) + + + + (defun org-set-mark-command (arg) + "Do set-mark-command and then org-show-context if the point + moves to invisible text." + (interactive "P") + (let ((initial-point (point))) + (setq this-command 'set-mark-command) + (set-mark-command (arg)) + (if (and (not (= (point) initial-point)) + (or (outline-invisible-p) (org-invisible-p2))) + (org-show-context 'mark-goto)))) + + (defun org-exchange-point-and-mark (&optional arg) + (interactive "P") + (let ((initial-point (point))) + (exchange-point-and-mark) + (if (and (not (= (point) initial-point)) + (or (outline-invisible-p) (org-invisible-p2))) + (org-show-context 'mark-goto)))) + + + (defun toggle-mode-line () + "Toggle mode line on and off." + (interactive) + (if mode-line-format + (progn (setq my-saved-mode-line-format mode-line-format) + (setq mode-line-format nil)) + (setq mode-line-format my-saved-mode-line-format)) + (force-mode-line-update)) + (toggle-mode-line) + (global-set-key (kbd "M-m") 'toggle-mode-line) + (add-hook 'after-change-major-mode-hook + (lambda () (setq my-saved-mode-line-format mode-line-format) + (setq mode-line-format nil))) + + + #+end_src + +** Copy mode-line to the top + #+begin_src emacs-lisp +;; Copy mode-line to the top +(setq-default header-line-format mode-line-format +mode-line-format nil) +;; copied the mode-line theme into the header theme, else it is unreadable +;; this goes after loading the theme +(let ((class '((class color) (min-colors 89)))) +(custom-theme-set-faces + 'leuven + `(header-line ((,class (:box (:line-width 1 :color "#1A2F54") :foreground "#85CEEB" :background "#335EA8")))))) + + #+end_src + +** tab bindings for when I wanted to make tab be for search +#+begin_src emacs-lisp + + (define-key emacs-lisp-mode-map (kbd "") nil) + (define-key button-buffer-map "\t" nil) + (define-key button-buffer-map (kbd "f") 'forward-button) + (define-key Info-mode-map "\t" nil) + (define-key widget-keymap "\t" nil) + (define-key widget-keymap (kbd "") nil) + + (add-hook 'compilation-mode-hook (lambda () + (define-key compilation-mode-map (kbd "") nil) + (define-key compilation-mode-map "\t" nil))) + +;; unbind c-i for yas. it already separately binds + (add-hook 'yas-minor-mode-hook (lambda () + (define-key yas-minor-mode-map "\t" nil))) + + (add-hook 'haskell-interactive-mode-hook + (lambda () + (define-key haskell-interactive-mode-map "\t" nil) + (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-tab))) + + (define-key minibuffer-local-must-match-map "\t" nil) + (define-key minibuffer-local-must-match-map (kbd "") 'minibuffer-complete) + (define-key minibuffer-local-completion-map (kbd "") 'minibuffer-complete) + (define-key minibuffer-local-completion-map "\t" 'minibuffer-complete) + + (add-hook 'ido-setup-hook + (lambda() + (define-key ido-completion-map (kbd "") 'ido-complete) + (define-key ido-completion-map "\t" nil))) + +#+end_src + +** kill buffer and window +#+begin_src emacs-lisp + (defun kill-buffer-and-window () + "Close the current window and kill the buffer it's visiting." + (interactive) + (progn + (kill-buffer) + (delete-window))) +#+end_src +** sending multiple commands to a comint buffer +without waiting for commands to finish is unreliable. +seems like 1 in 100 times, an invisible command to restore prompt didn't work +#+begin_src emacs-lisp +(setq shell-unset-prompt "unset PROMPT_COMMAND; unset PS1") + (setq shell-set-prompt "PROMPT_COMMAND=prompt_command") + +(if (boundp 'shell-unset-prompt) + (send-invisible-string proc shell-unset-prompt)) +(if (boundp 'shell-set-prompt) + (send-invisible-string proc shell-set-prompt)) + + + (defun send-invisible-string (proc string) + "Like send-invisible, but non-interactive" + (comint-snapshot-last-prompt) + (funcall comint-input-sender proc string)) + +#+end_src + + + + +** org-mode auto-complete source + +todo, someday take a look at this. it is broken. + +;(defvar ac-source-eshell-pcomplete +; '((candidates . (pcomplete-completions)))) +;(defun ac-complete-eshell-pcomplete () +; (interactive) +; (auto-complete '(ac-source-eshell-pcomplete))) + +;(add-hook 'org-mode-hook (lambda () (setq ac-sources (cons 'ac-source-eshell-pcomplete ac-sources)))) +;(add-to-list 'ac-modes 'eshell-mode) + + +** gnus nice unicode + + +this looks nice, but it lags gnus just a bit +#+begin_src emacs-lisp + +(defun gnus-pretty-chars-setup () + (when window-system + (setq gnus-sum-thread-tree-indent " " + gnus-sum-thread-tree-root "● " + gnus-sum-thread-tree-false-root "◯ " + gnus-sum-thread-tree-single-indent "◎ " + gnus-sum-thread-tree-leaf-with-other "├─► " + gnus-sum-thread-tree-vertical "│" + gnus-sum-thread-tree-single-leaf "╰─► "))) +;; dunno why, but this didn't work just setting on startup +(add-hook 'gnus-startup-hook 'gnus-pretty-chars-setup) + +#+end_src + +** misc +#+begin_src emacs-lisp + +;; this makes more ergonomic sense, since our eyes are mostly on the left, +;; but after using it a while, it's too much cognitive dissonance that +;; every other program has it on the right +;;(set-scroll-bar-mode 'left) + + + +; todo, is this require things necessary? +; (require 'flyspell) + + + + ; whenever M-tab is completion, swap it with tab + ;(define-key emacs-lisp-mode-map (kbd "") 'completion-at-point) + ;(define-key emacs-lisp-mode-map (kbd "C-M-i") 'indent-for-tab-command) + ;(define-key lisp-interaction-mode-map (kbd "") 'completion-at-point) + ;(define-key lisp-interaction-mode-map (kbd "C-M-i") 'indent-for-tab-command) + ;the global tab keyind. for some reason this totally screws up mini-buffer tab. + ; disabled until I actually find myself using this, and find a fix for the above problem + ;(global-set-key (kbd "") 'complete-symbol) + + + ; todo, make my custom overlays have an underline if they are + ; overriding a paren matching overlay + ; make right click set the mark + ; make search tab do completion instead of meta-tab + ; in isearch, move C-y to C-v + ; in isearch, move c-s to c-f + + ; some testing to figure out the underlining when paren highlight conflicts + ; (let ((extra-overlays (overlays-at (1+ end-point)))) + ; (when extra-overlays (print extra-overlays))) + + + + + ; commented out because it messes up yank-pop. +; todo, fix it someday + ; make yank linewise if it ends in a newline + ;(defadvice yank (before linewise-yank-advice activate) + ; (let ((arg (ad-get-arg 0))) + ; (when (string-match "\n[ \t]*$" (current-kill (cond + ;; ((listp arg) 0) + ;; ((eq arg '-) -2) + ;; (t (1- arg))) t)) + ;; (move-beginning-of-line nil)))) + + + +; todo, look into augmenting auto-complete with hippie expand. +; starter kit has some hippie expand settings to look into: +; (when (boundp 'hippie-expand-try-functions-list) +; (delete 'try-expand-line hippie-expand-try-functions-list) +; (delete 'try-expand-list hippie-expand-try-functions-list)) + + +;; hippie expand is dabbrev expand on steroids +;(setq hippie-expand-try-functions-list '(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 +; try-expand-list +; try-expand-line +; try-complete-lisp-symbol-partially +; try-complete-lisp-symbol)) +;; use hippie-expand instead of dabbrev +;(global-set-key (kbd "M-/") 'hippie-expand) + + +; commented because i haven't had time to check it out yet +;; shorter aliases for ack-and-a-half commands +;(defalias 'ack 'ack-and-a-half) +;(defalias 'ack-same 'ack-and-a-half-same) +;(defalias 'ack-find-file 'ack-and-a-half-find-file) +;(defalias 'ack-find-file-same 'ack-and-a-half-find-file-same) + + + + +; todo. take a look at fixing this +;delete-old-versions t ; fix description in http://www.emacswiki.org/emacs/ForceBackups + + + + +;; prelude uses paredit mode. +;; paredit has some useful stuff but also annoying stuff. +;; if I ever do a ton of lisp coding, I should look into it + + + + + + + ; random notes and example code + + + ; usefull thing + ;(map 'list #'list tabSwapKeys (reverse (getBinds tabSwapKeys))) + + ; example of getting keymap info + ;(car (car (minor-mode-key-binding (kbd "C-/") t))) + ;(cdr (car (minor-mode-key-binding (kbd "C-/") t))) + ;(global-key-binding (kbd "C-M-i") t) + ;(minor-mode-key-binding (kbd "") t) + ;(local-key-binding (kbd "C-M-i") t) + ;(current-minor-mode-maps) + ;(cdr (assq 'undo-tree-mode minor-mode-map-alist)) + + + ; center on incremental search, instead of being at top or bottom of screen. + ; i'm hoping that setting Isearch Allow Scroll is good enough to fix this annoyance + ;from http://stackoverflow.com/questions/11052678/emacs-combine-iseach-forward-and-recenter-top-bottom + + ;example of constant definition of an overlay and propreries + ;(defface mouse-flash-position '((t (:background "Yellow"))) + ; "*Face used to highlight mouse position temporarily." + ; :group 'mouse) + ;(defface mouse-flash-position '((t (:background "Yellow"))) + ; "*Face used to highlight mouse position temporarily." + ; :group 'mouse) + ;(defconst mouse-flash-posn-overlay + ; ;; Create and immediately delete, to get "overlay in no buffer". + ; (let ((ol (make-overlay (point-min) (point-max)))) + ; ;(delete-overlay ol) + ; ;(overlay-put ol 'face 'mouse-flash-position) + ; (overlay-put ol 'mouse-face 'mouse-flash-position) + ; (overlay-put ol 'priority 1000000) + ; ol) + ; "Overlay to highlight current mouse position.") + + + ;tip, put the last interactive command as elisp on the kill ring: + ;C-x C-a C-k C-g + + ; example of overlay testing + ;(setq foo (make-overlay 2 3 nil t nil)) + ;(setq foo2 (make-overlay 3 4 nil t nil)) + ;(overlay-put foo 'face '(:background "red3" :foreground "black")) + ;(overlay-put foo2 'face '(:background "red1" :foreground "black")) + ;(overlay-put foo 'face 'visible-mark-face) + ;(overlay-put foo 'face visible-mark-face2) + + +#+end_src + + +** SQL + +disabled, as I haven't used it in a long time. I think it was good for learning some sql stuff. +#+begin_src emacs-lisp :tangle no +(require 'sqlup-mode) +(add-hook 'sql-mode-hook 'sqlup-mode) +(add-hook 'sql-interactive-mode-hook 'sqlup-mode) + +(setq sql-product 'postgres) +#+end_src + + +** icomplete +#+begin_src emacs-lisp +;; without this, on partial completion return would exit the minibuffer, and i had to +;; keep typing out letters do a full completion before pressing enter. +;; super annoying. So I picked ctrl-j as a free key to put exit, +;; but in practice, I would just use ctrl-g to quit. Anyways, +;; ivy is doing all the minibuffer stuff, so removed this as it's +;; unused, so it can't cause any problems in future +(when (boundp 'icomplete-minibuffer-map) + (define-key icomplete-minibuffer-map (kbd "C-j") 'exit-minibuffer) + (define-key icomplete-minibuffer-map (kbd "") + 'minibuffer-force-complete-and-exit)) + + +#+end_src + +** java eclim + +based on https://github.com/senny/emacs-eclim + + +eclim: eclipse completion, searching, validation, etc inside emacs +install: +cd ~/opt +git clone git://github.com/ervandew/eclim.git +cd eclim +pi ant +ant -Declipse.home=/a/opt/eclipse + + +currently makes emacs hang a bunch. dunno why. just using eclipse instead +#+begin_src emacs-lisp :tangle no +(require 'eclim) +(global-eclim-mode) + +;; just do java +(setq eclim-accepted-file-regexps + '("\\.java")) + +(custom-set-variables + '(eclim-eclipse-dirs '("/a/opt/eclipse")) + '(eclim-executable "/a/opt/eclipse/eclim")) + +(setq help-at-pt-display-when-idle t) +(setq help-at-pt-timer-delay 0.1) +(help-at-pt-set-timer) + +;; dunno if this line is needed +(require 'eclimd) +(setq eclimd-default-workspace "/a/bin/eclipse-workspace") + +;;add the emacs-eclim source +(require 'ac-emacs-eclim-source) +(add-hook 'java-mode-hook 'ac-emacs-eclim-java-setup) + +#+end_src + +#+RESULTS: +| ac-emacs-eclim-java-setup | + + + +* broken & disabled mouse stuff + +all mouse stuff disabled till i have time to figure it out again. +#+begin_src emacs-lisp :tangle no +(defun xterm-mouse-translate-1 (&optional extension) + (save-excursion + (let* ((event (xterm-mouse-event extension)) + (ev-command (nth 0 event)) + (ev-data (nth 1 event)) + (ev-where (nth 1 ev-data)) + (vec (vector event)) + (is-down (string-match "down-" (symbol-name ev-command)))) + + (cond + ((null event) nil) ;Unknown/bogus byte sequence! + (is-down + (setf (terminal-parameter nil 'xterm-mouse-last-down) event) + vec) + (t + (let* ((down (terminal-parameter nil 'xterm-mouse-last-down)) + (down-data (nth 1 down)) + (down-where (nth 1 down-data))) + (setf (terminal-parameter nil 'xterm-mouse-last-down) nil) + (cond + ((null down) + ;; This is an "up-only" event. Pretend there was an up-event + ;; right before and keep the up-event for later. + (push event unread-command-events) + (vector (cons (intern (replace-regexp-in-string + "\\`\\([ACMHSs]-\\)*" "\\&down-" + (symbol-name ev-command) t)) + (cdr event)))) + ((equal ev-where down-where) vec) + (t + (let ((drag (if (symbolp ev-where) + 0 ;FIXME: Why?!? + (list (intern (replace-regexp-in-string + "\\`\\([ACMHSs]-\\)*" "\\&drag-" + (symbol-name ev-command) t)) + down-data ev-data)))) + (if (null track-mouse) + (vector drag) + (push drag unread-command-events) + (vector (list 'mouse-movement ev-data)))))))))))) + +#+end_src + + +** cursor highlight +disabled until fixed +#+begin_src emacs-lisp :tangle no + (defun mouse-follow-cursor () + ;(if (not (equal this-command last-command)) (print this-command)) +;debug + ; (print this-command) + (when (and this-command (not (string= this-command "show-pointer"))) + (let* ((pos (posn-col-row (posn-at-point))) + (x (1+ (car pos))) ; no idea why this is off by 1 + (y (cdr pos))) + (setq ignore-mouse-visibility t) + (set-mouse-position (selected-frame) x y)) + ;(sleep-for 0 100) + (frame-make-pointer-invisible))) + + ; (when this-command + ; (if (string= this-command "show-pointer") + ; (frame-make-pointer-visible) + ;)) + + + + (defun show-pointer () + (interactive) + (if ignore-mouse-visibility + (setq ignore-mouse-visibility nil) +; (print "visible") + (frame-make-pointer-visible))) + + (setq ignore-mouse-visibility t) +; disabled + ; (global-set-key (kbd "") 'show-pointer) + + ; (add-hook 'post-command-hook 'mouse-follow-cursor t) + + + ; status. working, except that all scroll wheel actions send a mouse-movement command before doing their actual command, which makes the pointer flicker. + ; this is just an artifact of xbindkeys. when i do my own mouse chip, it will fix this. + +; we could set track-mouse to nil, then do the command, then set it back. i like that idea a bit better. + ; we could do the same thing in the other case of ignore-mouse-visibility. + + ; there are also other issues, it doesn't work with changing buffers on a split screen. + ; i think a good idea along with this would be for the cursor to follow the mouse all the time. + ; i have done code for that in my mouse 1 function, + ; i just need to read it again and try it out. + + + + + ; this does not take care of scrolling, + ; a post-command hook function below does, + ; but it breaks when the frame is split. + ; the bug is specifically in mouse-pixel-position + ; todo, fix this eventually + (defun mouse-highlight-event (event) + (interactive "e") + (when (or (not event) (mouse-movement-p event) + (memq (car-safe event) '(switch-frame select-window))) + (let ((pos (posn-point (event-end event)))) + (if (eq (overlay-buffer mouse-hi-ov) (current-buffer)) + (move-overlay mouse-hi-ov pos (1+ pos)) + (delete-overlay mouse-hi-ov) + (setq mouse-hi-ov + (make-overlay pos (1+ pos))) + (overlay-put mouse-hi-ov + 'insert-in-front-hooks (list 'mouse-hi-modification)) + (overlay-put mouse-hi-ov 'priority 1001)) + (cond ((save-excursion (goto-char pos) (eolp)) + (overlay-put mouse-hi-ov 'face nil) + (overlay-put mouse-hi-ov 'before-string + (propertize + " " + 'cursor t + 'face 'mouse-cursor-face))) + (t + (overlay-put mouse-hi-ov 'face 'mouse-cursor-face) + (overlay-put mouse-hi-ov 'before-string nil)))))) + + + ; overlay changed hook function + (defun mouse-hi-modification (ov timing beginning end &optional length) + "Make an overlay of length 1 not expand when text is inserted at the front." + (when timing + (let ((start (overlay-start ov))) + (move-overlay ov start (1+ start))))) + + + + + (defun mouse-hi-command-hook () + ; not sure if I need to deal with case of a nil mouse position in some unforseen situation. + (let ((x-y (cdr (mouse-pixel-position)))) + (when (wholenump (car x-y)) + (let ((pos (posn-point (posn-at-x-y (car x-y) (cdr x-y) nil t)))) + (when pos + (if (eq (overlay-buffer mouse-hi-ov) (current-buffer)) + (move-overlay mouse-hi-ov pos (1+ pos)) + (delete-overlay mouse-hi-ov) + (setq mouse-hi-ov + (make-overlay pos (1+ pos))) + + (overlay-put mouse-hi-ov 'priority 1001)) + (cond ((save-excursion (goto-char pos) (eolp)) + + (overlay-put mouse-hi-ov 'face nil) + (overlay-put mouse-hi-ov 'before-string + (propertize + " " + 'cursor t + 'face 'mouse-cursor-face))) + (t + (overlay-put mouse-hi-ov 'face 'mouse-cursor-face) + (overlay-put mouse-hi-ov 'before-string nil)))))))) + ; (pcase-let ((`(,_ ,x . ,y) (mouse-pixel-position))) + ; (posn-point (posn-at-x-y x y))))) + ; equivalent of above to find pos. todo, learn about the above syntax + + (setq mouse-hi-ov (make-overlay 1 1)) + (delete-overlay mouse-hi-ov) + ; initialized overlay + ; temporarily set to nil instead of t because it is broken and + ; also has a bug that makes emacs not remember the column when + ; doing up and down movements. + ; it also messes up yas/insert-snippet, dunno why. +; i should test out whether it is something in the post-command hook +; (setq track-mouse t) + ;(add-hook 'post-command-hook 'mouse-hi-command-hook) + + ;(mouse-hi-command-hook) + ;(setq debug-on-error nil) + + #+end_src +** mouse 1 drag func + +disabled as it breaks in newer emacs versions with this error, when +clicking on info links + +"and: Symbol's function definition is void: mouse--remap-link-click-p" + +#+begin_src emacs-lisp :tangle no + + ; Copied from mouse.el and modified. + ; my modifications have comments prefaced by "ian" + (defun mouse-drag-track (start-event &optional + do-mouse-drag-region-post-process) + "Track mouse drags by highlighting area between point and cursor. + The region will be defined with mark and point. + DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by + `mouse-drag-region'." + (mouse-minibuffer-check start-event) + (setq mouse-selection-click-count-buffer (current-buffer)) + ; ian. removed as unneeded since I don't use TMM + ;(deactivate-mark) + (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541). + (original-window (selected-window)) + ;; We've recorded what we needed from the current buffer and + ;; window, now let's jump to the place of the event, where things + ;; are happening. + (_ (mouse-set-point start-event)) + (echo-keystrokes 0) + (start-posn (event-start start-event)) + (start-point (posn-point start-posn)) + (start-window (posn-window start-posn)) + (start-window-start (window-start start-window)) + (start-hscroll (window-hscroll start-window)) + (bounds (window-edges start-window)) + (make-cursor-line-fully-visible nil) + (top (nth 1 bounds)) + (bottom (if (window-minibuffer-p start-window) + (nth 3 bounds) + ;; Don't count the mode line. + (1- (nth 3 bounds)))) + (on-link (and mouse-1-click-follows-link + ;; Use start-point before the intangibility + ;; treatment, in case we click on a link inside + ;; intangible text. + (mouse-on-link-p start-posn))) + (click-count (1- (event-click-count start-event))) + (remap-double-click (and on-link + (eq mouse-1-click-follows-link 'double) + (= click-count 1))) + ;; Suppress automatic hscrolling, because that is a nuisance + ;; when setting point near the right fringe (but see below). + (auto-hscroll-mode-saved auto-hscroll-mode) + (auto-hscroll-mode nil) + moved-off-start event end end-point) + + (setq mouse-selection-click-count click-count) + ;; In case the down click is in the middle of some intangible text, + ;; use the end of that text, and put it in START-POINT. + (if (< (point) start-point) + (goto-char start-point)) + (setq start-point (point)) + (if remap-double-click + (setq click-count 0)) + + ;; Activate the region, using `mouse-start-end' to determine where + ;; to put point and mark (e.g., double-click will select a word). + (setq transient-mark-mode + (if (eq transient-mark-mode 'lambda) + '(only) + (cons 'only transient-mark-mode))) + (delete-overlay mouse-hi-ov) ; ian, added this. + + (let ((range (mouse-start-end start-point start-point click-count))) + (push-mark (nth 0 range) t t) + (goto-char (nth 1 range))) + + ;; Track the mouse until we get a non-movement event. + (track-mouse + (while (progn + (setq event (read-event)) + (or (mouse-movement-p event) + (memq (car-safe event) '(switch-frame select-window)))) + (unless (memq (car-safe event) '(switch-frame select-window)) + ;; Automatic hscrolling did not occur during the call to + ;; `read-event'; but if the user subsequently drags the + ;; mouse, go ahead and hscroll. + (let ((auto-hscroll-mode auto-hscroll-mode-saved)) + (redisplay)) + (setq end (event-end event) + end-point (posn-point end)) + ;; Note whether the mouse has left the starting position. + (unless (eq end-point start-point) + (setq moved-off-start t)) + (if (and (eq (posn-window end) start-window) + (integer-or-marker-p end-point)) + (mouse--drag-set-mark-and-point start-point + end-point click-count) + (let ((mouse-row (cdr (cdr (mouse-position))))) + (cond + ((null mouse-row)) + ((< mouse-row top) + (mouse-scroll-subr start-window (- mouse-row top) + nil start-point)) + ((>= mouse-row bottom) + (mouse-scroll-subr start-window (1+ (- mouse-row bottom)) + nil start-point)))))) + (visible-mark-move-overlays))) ; ian, added this + + + ;; Handle the terminating event if possible. + (when (consp event) + ;; Ensure that point is on the end of the last event. + (when (and (setq end-point (posn-point (event-end event))) + (eq (posn-window end) start-window) + (integer-or-marker-p end-point) + (/= start-point end-point)) + (mouse--drag-set-mark-and-point start-point + end-point click-count)) + + ;; Find its binding. + (let* ((fun (key-binding (vector (car event)))) + (do-multi-click (and (> (event-click-count event) 0) + (functionp fun) + (not (memq fun '(mouse-set-point + mouse-set-region)))))) + (if (and (/= (mark) (point)) + (not do-multi-click)) + + ;; If point has moved, finish the drag. + (let* (last-command this-command) + (and mouse-drag-copy-region + do-mouse-drag-region-post-process + (let (deactivate-mark) + (copy-region-as-kill (mark) (point))))) + + ;; Otherwise, run binding of terminating up-event. + (if do-multi-click + (goto-char start-point) + (deactivate-mark) + (unless moved-off-start + ;; ian: poping the mark is a poor choice of behavior. + ;; we should delete the mark instead. + ;; The first way I found to delete it is to pop it first + (pop-mark) + (setq mark-ring (nbutlast mark-ring)))) + + (when (and (functionp fun) + (= start-hscroll (window-hscroll start-window)) + ;; Don't run the up-event handler if the window + ;; start changed in a redisplay after the + ;; mouse-set-point for the down-mouse event at + ;; the beginning of this function. When the + ;; window start has changed, the up-mouse event + ;; contains a different position due to the new + ;; window contents, and point is set again. + (or end-point + (= (window-start start-window) + start-window-start))) + + (when (and on-link + (= start-point (point)) + (mouse--remap-link-click-p start-event event)) + + ;; If we rebind to mouse-2, reselect previous selected + ;; window, so that the mouse-2 event runs in the same + ;; situation as if user had clicked it directly. Fixes + ;; the bug reported by juri@jurta.org on 2005-12-27. + (if (or (vectorp on-link) (stringp on-link)) + (setq event (aref on-link 0)) + (select-window original-window) + (setcar event 'mouse-2) + ;; If this mouse click has never been done by the + ;; user, it doesn't have the necessary property to be + ;; interpreted correctly. + (put 'mouse-2 'event-kind 'mouse-click))) + (push event unread-command-events))))))) +#+end_src + +** mouse 3 +#+begin_src emacs-lisp :tangle no + + + (defun mouse3-range-mark (start click click-count) + (let* ((range (mouse-start-end start click click-count)) + (beg (nth 0 range)) + (end (nth 1 range))) + (cond ((<= click start) + (set-mark beg)) + (t + (set-mark end)))) + (visible-mark-move-overlays)) + + + (defun mouse3-set-mark (event) + "in development" + (interactive "e") + (mouse-minibuffer-check event) + ;; Use event-end in case called from mouse-drag-region. + ;; If EVENT is a click, event-end and event-start give same value. + (set-mark (posn-point (event-end event))) + (visible-mark-move-overlays)) + + + (defun mouse3-func (start-event) + "in development" + (interactive "e") + + (run-hooks 'mouse-leave-buffer-hook) + + (mouse-minibuffer-check start-event) + (setq mouse-selection-click-count-buffer (current-buffer)) + (push-mark (posn-point (event-end start-event))) + + (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541). + (original-window (selected-window)) + ;; We've recorded what we needed from the current buffer and + ;; window, now let's jump to the place of the event, where things + ;; are happening. + ;(_ (mouse-set-point start-event)) ; ian: commented, replaced + (echo-keystrokes 0) + (start-posn (event-start start-event)) + (start-point (posn-point start-posn)) + (start-window (posn-window start-posn)) + (start-window-start (window-start start-window)) + (start-hscroll (window-hscroll start-window)) + (bounds (window-edges start-window)) + (make-cursor-line-fully-visible nil) + (top (nth 1 bounds)) + (bottom (if (window-minibuffer-p start-window) + (nth 3 bounds) + ;; Don't count the mode line. + (1- (nth 3 bounds)))) + (click-count (1- (event-click-count start-event))) + ;; Suppress automatic hscrolling, because that is a nuisance + ;; when setting point near the right fringe (but see below). + (auto-hscroll-mode-saved auto-hscroll-mode) + (auto-hscroll-mode nil) + moved-off-start event end end-point) + + (setq mouse-selection-click-count click-count) + ;; In case the down click is in the middle of some intangible text, + ;; use the end of that text, and put it in START-POINT. + (if (< (mark) start-point) ; ian: change point to the mark + (set-mark start-point) + (visible-mark-move-overlays)) + (setq start-point (mark)) + + (delete-overlay mouse-hi-ov) ; ian, added this. + + ;; Activate the region, using `mouse-start-end' to determine where + ;; to put point and mark (e.g., double-click will select a word). + (let ((range (mouse-start-end start-point start-point click-count))) + (set-mark (nth 1 range))) + (visible-mark-move-overlays) + + + ;; Track the mouse until we get a non-movement event. + (track-mouse + + (while (progn + (setq event (read-event)) + (or (mouse-movement-p event) + (memq (car-safe event) '(switch-frame select-window)))) + (unless (memq (car-safe event) '(switch-frame select-window)) + + ;; Automatic hscrolling did not occur during the call to + ;; `read-event'; but if the user subsequently drags the + ;; mouse, go ahead and hscroll. + (let ((auto-hscroll-mode auto-hscroll-mode-saved)) + (redisplay)) + (setq end (event-end event) + end-point (posn-point end)) + ;; Note whether the mouse has left the starting position. + + (unless (eq end-point start-point) + (setq moved-off-start t)) + (if (and (eq (posn-window end) start-window) + (integer-or-marker-p end-point)) + (mouse3-range-mark start-point end-point click-count); ian, set mark + + ; do scrolling if needed + (let ((mouse-row (cdr (cdr (mouse-position))))) + (cond + ((null mouse-row)) + ((< mouse-row top) + (mouse-scroll-subr start-window (- mouse-row top) + nil start-point)) + ((>= mouse-row bottom) + (mouse-scroll-subr start-window (1+ (- mouse-row bottom)) + nil start-point)))))))) + + ;; Handle the terminating event if possible. + (when (consp event) + ;; Ensure that point is on the end of the last event. + (when (and (setq end-point (posn-point (event-end event))) + (eq (posn-window end) start-window) + (integer-or-marker-p end-point) + (/= start-point end-point)) + ;(mouse--drag-set-mark-and-point start-point ; ian, set mark + ;end-point click-count)) + (mouse3-range-mark start-point end-point click-count)); ian, set mark + + ;; Find its binding. + (let* ((fun (key-binding (vector (car event)))) + (do-multi-click (and (> (event-click-count event) 0) + (functionp fun) + (not (memq fun '(mouse3-set-mark)))))) + (if (and (/= end-point start-point) + (not do-multi-click)) + + ;; If point has moved, finish the drag. + (let* (last-command this-command) + (and mouse-drag-copy-region + do-mouse-drag-region-post-process + (let (deactivate-mark) + (copy-region-as-kill (mark) (point))))) + + ;; Otherwise, run binding of terminating up-event. + (when do-multi-click + (set-mark start-point)) ; ian, change this. why? + (visible-mark-move-overlays) + + + (when (and (functionp fun) + (= start-hscroll (window-hscroll start-window)) + ;; Don't run the up-event handler if the window + ;; start changed in a redisplay after the + ;; mouse-set-point for the down-mouse event at + ;; the beginning of this function. When the + ;; window start has changed, the up-mouse event + ;; contains a different position due to the new + ;; window contents, and point is set again. + (or end-point + (= (window-start start-window) + start-window-start))) + + (push event unread-command-events))))))) + +#+end_src + + + + + +* disabled planning to fix +** speedbar +(sr-speedbar-close) +(sr-speedbar-open) + + #+begin_src emacs-lisp :tangle no +(require 'sr-speedbar) + (setq speedbar-hide-button-brackets-flag t ;; didn't notice a diff + speedbar-file-unshown-regexp "flycheck-.*" + sr-speedbar-width 40 + sr-speedbar-width-x 40 + sr-speedbar-auto-refresh nil + sr-speedbar-skip-other-window-p t + sr-speedbar-right-side nil +speedbar-hide-button-brackets-flag nil) + #+end_src + +* TODO fix auto save to be reliable and not rely on idle time +sometimes emacs or computer stays busy and idle never comes +* TODO try out which key mode +* TODO make installed emacs package declarative +* TODO see if there are more cool functions in sh-script +like sh-cd-here, and bind that to a key +* TODO assign a key to append-next-kill +* TODO keybinds to remember + +keys worth memorizing + +c-2 +c-m-3 + +s-return + +in isearch, C-o +isearch-occur + +org, C-c / t +make just todo items visible + +C-mouse-1 +buffer list menu + +C-up/down +move up/down fast + +M-right-scroll +forward/back sexp + +C-M-right-scroll +scroll + +C-S-scroll +change text size + +how to control+left scroll on kinesis +right shift = control + +C-left-scroll +forward/backward word + +C-M-d +swap buffers across windows + +shell-cd-to-file +M-2 + +* TODO add simpler keybind for make-frame-command +current one is C-x 5 2. + +* TODO learn some more ivy mode stuff +* TODO declarative package installations, +with documentation. +* TODO shell mode reverse search hides 2nd+ line of multi-line result +* TODO figure out browsing files with broken nfs mount +causes emacs to freeze until I kill -9 it. +* TODO make a keybind to print var under cursor +and actually, putting the start of it in th emodeline might be cool +* TODO make recent files save periodically, +normally it just saves on exit, but half the time I don't exit cleanly +so they don't get saved, because I leave emacs running until it crashes +* TODO fix undo tree outside visible buffer bug +* TODO c- in shell mode should send over +previous line if current line is empty +* TODO make c-m-s be just a control key for easier use +* TODO try out avy mode for laptop +i used to have ace jump mode, but google says avy is better. +* TODO bind a in group mode of gnus to c-u a, +also, make a default for number of articles +* TODO make auto-complete be on by default in sql-mode +* TODO make an easy bind for open previous buffer +* TODO i think my autosave for sudo-edit might be too fast +it sometimes leaves #_asdfjasdf files littered +* TODO readline-compleste doesn't work when you cat a file without a newline, +and so the prompt is messed up. not sure exactly what needs to be in end, or if its anything +* TODO figure out how to paste a path into find file +probably have to use the old kind of find file +* TODO readline-complete doesn't escape special chars in filenames +* TODO readline-complete dev + + + +** misc fixes + +bad code, the comment this relates to was removed, but not the comment + /* If waiting for this channel, arrange to return as + soon as no more input to be processed. No more + waiting. */ + + +(status_notify): New arg WAIT_PROC. this is unused, this is a bug. +The change in status_notify's return is just passing more information +from what it did already. No changes at all inside this function. + +* TODO consider whether to bind indent-for-tab-command +I removed it from m-tab for terminal compatibility. +It's the default tab command, which yasnippet replaces. +* TODO readline-complete: remove the hardcoded rlc-no-readline-hook +* TODO isearch doesn't automatically wrap in info +* TODO look into fixing shell mode reverse search +and why auto-complete dies +caveat is that it doesn't work well with certain unusual prompts, for example if $/# is not used at the end +see if we can load history, or reverse search with history commands +* TODO keybinds for s-delete/tab etc +* TODO fix bbdb info packaging in melpa +* TODO figure out why my emacs startup script doesn't work from dmenu +* TODO post idea to make customize group show function var names so we can read doc strings +* TODO report/fix bug that kill-whole-line doesn't work right with append kill +* TODO make bash keybind for copy paste interoperate with x windows +* TODO fix org stderr redirection +make this produce output of "ok" +#+begin_src sh +echo ok >&2 + +#+end_src +* TODO make ido keybinds better +* TODO fix indenting in org + + (defun my-org-indent-region (start end) + "Indent region." + (interactive "r") + (save-excursion + (let ((line-end (org-current-line end))) + (goto-char start) + (while (< (org-current-line) line-end) + (cond ((org-in-src-block-p) (org-babel-do-in-edit-buffer (indent-according-to-mode))) + (t (call-interactively 'org-indent-line))) + (move-beginning-of-line 2))))) + + + +org-indent-region is broken for source blocks +the above function works, but has several problems. +first: it should not have separate logic from org-indent-line +second: it runs way too slow, mainly the command + (org-babel-do-in-edit-buffer (indent-according-to-mode))) + + +* TODO figure out newline in prompt shell issue +setting this before readline-complete is loaded allows completion to work, +but auto-completion still fails. Need to debug readline-complete to figure this out. +(setq shell-prompt-pattern "^[^#$%>]*[#$]\n") +* TODO setup bind for find tag / lisp function at point + +* TODO org-delete-char should also work for the delete/backspace keys! + fix and send patch + +* TODO checkout projectile / graphene's project settings + +* TODO check up on recent changes to 3rd party default configs +- last checked apr 24 + https://github.com/eschulte/emacs24-starter-kit/commits/master + +last checked mayish +https://github.com/bbatsov/prelude +- redefined mouse functions from this file + +* TODO figure out how to setup emacs to format text nicely like thunderbird +* TODO it appears impossible make C-[ not be the same as escape +* TODO movement within info buffer after opening a link doesn't cancel isearch +leads to many frustrations +* TODO fix org resolve clock message. it is innacurate + i is not the same, becuase it does not make org realize there is an active clock + +* TODO add apropos commands to help prefix, from + http://stackoverflow.com/questions/3124844/what-are-your-favorite-global-key-bindings-in-emacs +* TODO my autosave goes into an endless prompting loop +when running save buffer, and the buffer has been changed +outside of emacs +* TODO smart peren does not see ?\\) as a valid paren + +* TODO why does org-end-of-line not go all the way to the end on a closed headline? +* TODO org makes random ... things, and delete right before them does ctrl-i +* TODO try mark word, which might be a useful keybind +* TODO fix org-cycle: it assumes which key it is bound to for its last alternative +* TODO checkout lisp-complete-symbol to augment auto-complete +* TODO emacs keylogger to optimize key binds +* TODO remap/investigate find tag, find tag at point +* TODO set key to cycle buffers by mode, example below + +(defun cycle-buffer-by-mode (p-mode) + "Cycle buffers by mode name" + (interactive) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when (buffer-live-p buffer) + (if (string-match p-mode mode-name) ;(regexp-quote p-mode) + (setq switch2buffer buffer))))) + (when (boundp 'switch2buffer) + (switch-to-buffer switch2buffer))) + +And I have bound this to my F9 key + +(global-set-key [f9] '(lambda () (interactive) (cycle-buffer-by-mode "Shell$"))) + +* TODO test out usefulness of forward/back sexp in different languages + +* TODO major mode settings to check out in future +** emacs24 starter kit +- Nxhtml -- utilities for web development +[[http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html][Nxhtml]] is a large package of utilities for web development and for +embedding multiple major modes in a single buffer. + +Nxhtml is not installed in this version of the starter-kit by default, +for information on installing nxhtml see [[http://www.emacswiki.org/emacs/NxhtmlMode][EmacsWiki-Nxhtml]]. + +web-mode is competing package and actively developed, so i'm using that instead + + + (dolist (package '(yaml-mode js2-mode)) + (unless (package-installed-p package) + +- Associate modes with file extensions + +(add-to-list 'auto-mode-alist '("COMMIT_EDITMSG$" . diff-mode)) +(add-to-list 'auto-mode-alist '("\\.css$" . css-mode)) +(require 'yaml-mode) +(add-to-list 'auto-mode-alist '("\\.ya?ml$" . yaml-mode)) +(add-to-list 'auto-mode-alist '("\\.rb$" . ruby-mode)) +(add-to-list 'auto-mode-alist '("Rakefile$" . ruby-mode)) +(add-to-list 'auto-mode-alist '("\\.js\\(on\\)?$" . js2-mode)) +;; (add-to-list 'auto-mode-alist '("\\.xml$" . nxml-mode)) + +- clojure in starter-kit-lisp.org + +- others = gnus, js, publish, perl, python, perl, ruby + they each have their own starter kit file. + +- snippets for various modes other than org-mode + +* TODO update yasnippet documentation + yas expand key customization is rediculously hard to figure out + and completely undocumented +* TODO fix org source indenting, send patch +* TODO check out bundling aka compiling yasnippet +* TODO try xml/html mode url func + +(defun view-url () + "Open a new buffer containing the contents of URL." + (interactive) + (let* ((default (thing-at-point-url-at-point)) + (url (read-from-minibfer "URL: " default))) + (switch-to-buffer (url-retrieve-synchronously url)) + (rename-buffer url t) + ;; TODO: switch to nxml/nxhtml mode + (cond ((search-forward ". - -* things that should be at the beginning -#+begin_src emacs-lisp -;; todo, evaluating this manually disables debug on error instead of toggling it -;;(toggle-debug-on-error) ;uncomment to help debug and catch errors - -#+end_src - - -packages installed from package manager: i pretty much prioritize repos this way: gnu, then melpa, then marmalade. - -package-activated-list: -ac-dabbrev ac-haskell-process ack-and-a-half alect-themes auctex bash-completion bbdb csv-mode cyberpunk-theme dot-mode expand-region f find-file-in-project flycheck foreign-regexp ggtags ghc gnuplot-mode goto-chg haskell-mode heroku-theme highlight-indentation highlight-symbol htmlize inf-ruby info+ inkpot-theme jedi auto-complete jedi-core epc ctable concurrent key-chord leuven-theme logstash-conf magit git-commit magit-popup misc-fns mouse+ naquadah-theme nginx-mode occidental-theme org paredit pcsv php-mode pkg-info epl popup py-autopep8 python-environment deferred python-info python-mode rainbow-mode rust-mode rw-hunspell s smartparens smex smooth-scroll sr-speedbar strings swiper ivy tabulated-list tangotango-theme thingatpt+ undo-tree vimrc-mode volatile-highlights web-mode with-editor dash async ws-butler yasnippet - -alternate keyboards -#+begin_src emacs-lisp -;; todo, figure out an easy way to disable this when using external keyboard -(if (display-graphic-p) - (setq - enter-key (kbd "") - s-enter-key (kbd "") - c-m-enter-key (kbd "") - m-enter (kbd "") - c-enter (kbd "")) - (setq - enter-key (kbd "C-m") - s-enter-key (kbd "C-8") - c-m-enter-key (kbd "C-M-8") - m-enter (kbd "M-m") - c-enter (kbd "C-8"))) - -(setq tp (string= (system-name) "tp")) -(setq x200 (string= (system-name) "x2")) -(setq laptop-keyboard (or tp x200)) -#+end_src - -- Ubiquitous Packages which should be loaded on startup rather than - autoloaded on demand since they are likely to be used in every - session. - #+name: starter-kit-load-on-startup - #+begin_src emacs-lisp - (require 'saveplace) - (require 'ffap) - (require 'uniquify) - (require 'ansi-color) - (require 'recentf) - - #+end_src - - -- Better to have a list of packages in here vs installed manually. - However, I install manually because sometimes there are two - versions and it is not necessarily easy to reconcile that. - #+begin_src emacs-lisp - ;; based on marmalage website front page. -(require 'package) - -;; little kit to help remove a down server -;; (setq package-archives nil) - -;;(add-to-list 'package-archives -;; '("marmalade" . -;; "http://marmalade-repo.org/packages/")) - -(add-to-list 'package-archives - '("melpa" . "http://melpa.milkbox.net/packages/") t) -(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) - - #+end_src - - - keep our init.el clean, by moving customization elisp to it's own file -#+name: m-x-customize-customizations -#+begin_src emacs-lisp -(setq custom-file "~/.emacs.d/custom.el") -(load custom-file 'noerror) -#+end_src - -undo tree stuff -#+begin_src emacs-lisp -;; 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) -#+end_src - -* Stuff that I do not recommend that others use without reading, -understanding, and customizing themselves are - -all mouse stuff disabled till i have time to figure it out again. -#+begin_src emacs-lisp :tangle no -(defun xterm-mouse-translate-1 (&optional extension) - (save-excursion - (let* ((event (xterm-mouse-event extension)) - (ev-command (nth 0 event)) - (ev-data (nth 1 event)) - (ev-where (nth 1 ev-data)) - (vec (vector event)) - (is-down (string-match "down-" (symbol-name ev-command)))) - - (cond - ((null event) nil) ;Unknown/bogus byte sequence! - (is-down - (setf (terminal-parameter nil 'xterm-mouse-last-down) event) - vec) - (t - (let* ((down (terminal-parameter nil 'xterm-mouse-last-down)) - (down-data (nth 1 down)) - (down-where (nth 1 down-data))) - (setf (terminal-parameter nil 'xterm-mouse-last-down) nil) - (cond - ((null down) - ;; This is an "up-only" event. Pretend there was an up-event - ;; right before and keep the up-event for later. - (push event unread-command-events) - (vector (cons (intern (replace-regexp-in-string - "\\`\\([ACMHSs]-\\)*" "\\&down-" - (symbol-name ev-command) t)) - (cdr event)))) - ((equal ev-where down-where) vec) - (t - (let ((drag (if (symbolp ev-where) - 0 ;FIXME: Why?!? - (list (intern (replace-regexp-in-string - "\\`\\([ACMHSs]-\\)*" "\\&drag-" - (symbol-name ev-command) t)) - down-data ev-data)))) - (if (null track-mouse) - (vector drag) - (push drag unread-command-events) - (vector (list 'mouse-movement ev-data)))))))))))) - -#+end_src -* how to find auto-saved files that need recovering -find a recently dated file in ~/.emacs.d/auto-save-list/, and see the files listed in it. -#file# is an auto-save file. It may or may not be different than the file is corresponds to. -If it is different, emacs will give a message about recovering it when you open it. - - -* TODO try out which key mode -* TODO make installed emacs package declarative -* TODO see if there are more cool functions in sh-script -like sh-cd-here, and bind that to a key -* TODO assign a key to append-next-kill -* TODO keybinds to remember - -keys worth memorizing - -c-2 -c-m-3 - -s-return - -in isearch, C-o -isearch-occur - -org, C-c / t -make just todo items visible - -C-mouse-1 -buffer list menu - -C-up/down -move up/down fast - -M-right-scroll -forward/back sexp - -C-M-right-scroll -scroll - -C-S-scroll -change text size - -how to control+left scroll on kinesis -right shift = control - -C-left-scroll -forward/backward word - -C-M-d -swap buffers across windows - -shell-cd-to-file -M-2 - -* TODO add simpler keybind for make-frame-command -current one is C-x 5 2. - -* TODO learn some more ivy mode stuff -* TODO declarative package installations, -with documentation. -* TODO shell mode reverse search hides 2nd+ line of multi-line result -* TODO figure out browsing files with broken nfs mount -causes emacs to freeze until I kill -9 it. -* TODO make a keybind to print var under cursor -and actually, putting the start of it in th emodeline might be cool -* TODO make recent files save periodically, -normally it just saves on exit, but half the time I don't exit cleanly -so they don't get saved, because I leave emacs running until it crashes -* TODO fix undo tree outside visible buffer bug -* TODO c- in shell mode should send over -previous line if current line is empty -* TODO make c-m-s be just a control key for easier use -* TODO try out avy mode for laptop -i used to have ace jump mode, but google says avy is better. -* TODO bind a in group mode of gnus to c-u a, -also, make a default for number of articles -* TODO make auto-complete be on by default in sql-mode -* TODO make an easy bind for open previous buffer -* TODO i think my autosave for sudo-edit might be too fast -it sometimes leaves #_asdfjasdf files littered -* TODO readline-compleste doesn't work when you cat a file without a newline, -and so the prompt is messed up. not sure exactly what needs to be in end, or if its anything -* TODO figure out how to paste a path into find file -probably have to use the old kind of find file -* TODO readline-complete doesn't escape special chars in filenames -* TODO readline-complete dev - - - -** misc fixes - -bad code, the comment this relates to was removed, but not the comment - /* If waiting for this channel, arrange to return as - soon as no more input to be processed. No more - waiting. */ - - -(status_notify): New arg WAIT_PROC. this is unused, this is a bug. -The change in status_notify's return is just passing more information -from what it did already. No changes at all inside this function. - -* TODO consider whether to bind indent-for-tab-command -I removed it from m-tab for terminal compatibility. -It's the default tab command, which yasnippet replaces. -* TODO readline-complete: remove the hardcoded rlc-no-readline-hook -* TODO isearch doesn't automatically wrap in info -* TODO look into fixing shell mode reverse search -and why auto-complete dies -caveat is that it doesn't work well with certain unusual prompts, for example if $/# is not used at the end -see if we can load history, or reverse search with history commands -* TODO keybinds for s-delete/tab etc -* TODO fix bbdb info packaging in melpa -* TODO figure out why my emacs startup script doesn't work from dmenu -* TODO post idea to make customize group show function var names so we can read doc strings -* TODO report/fix bug that kill-whole-line doesn't work right with append kill -* TODO make bash keybind for copy paste interoperate with x windows -* TODO fix org stderr redirection -make this produce output of "ok" -#+begin_src sh -echo ok >&2 - -#+end_src -* TODO make ido keybinds better -* TODO fix indenting in org - - (defun my-org-indent-region (start end) - "Indent region." - (interactive "r") - (save-excursion - (let ((line-end (org-current-line end))) - (goto-char start) - (while (< (org-current-line) line-end) - (cond ((org-in-src-block-p) (org-babel-do-in-edit-buffer (indent-according-to-mode))) - (t (call-interactively 'org-indent-line))) - (move-beginning-of-line 2))))) - - - -org-indent-region is broken for source blocks -the above function works, but has several problems. -first: it should not have separate logic from org-indent-line -second: it runs way too slow, mainly the command - (org-babel-do-in-edit-buffer (indent-according-to-mode))) - - -* TODO figure out newline in prompt shell issue -setting this before readline-complete is loaded allows completion to work, -but auto-completion still fails. Need to debug readline-complete to figure this out. -(setq shell-prompt-pattern "^[^#$%>]*[#$]\n") -* TODO setup bind for find tag / lisp function at point - -* TODO org-delete-char should also work for the delete/backspace keys! - fix and send patch - -* TODO checkout projectile / graphene's project settings - -* TODO check up on recent changes to 3rd party default configs -- last checked apr 24 - https://github.com/eschulte/emacs24-starter-kit/commits/master - -last checked mayish -https://github.com/bbatsov/prelude -- redefined mouse functions from this file - -* TODO figure out how to setup emacs to format text nicely like thunderbird -* TODO it appears impossible make C-[ not be the same as escape -* TODO movement within info buffer after opening a link doesn't cancel isearch -leads to many frustrations -* TODO fix org resolve clock message. it is innacurate - i is not the same, becuase it does not make org realize there is an active clock - -* TODO add apropos commands to help prefix, from - http://stackoverflow.com/questions/3124844/what-are-your-favorite-global-key-bindings-in-emacs -* TODO my autosave goes into an endless prompting loop -when running save buffer, and the buffer has been changed -outside of emacs -* TODO smart peren does not see ?\\) as a valid paren - -* TODO why does org-end-of-line not go all the way to the end on a closed headline? -* TODO org makes random ... things, and delete right before them does ctrl-i -* TODO try mark word, which might be a useful keybind -* TODO fix org-cycle: it assumes which key it is bound to for its last alternative -* TODO checkout lisp-complete-symbol to augment auto-complete -* TODO emacs keylogger to optimize key binds -* TODO remap/investigate find tag, find tag at point -* TODO set key to cycle buffers by mode, example below - -(defun cycle-buffer-by-mode (p-mode) - "Cycle buffers by mode name" - (interactive) - (dolist (buffer (buffer-list)) - (with-current-buffer buffer - (when (buffer-live-p buffer) - (if (string-match p-mode mode-name) ;(regexp-quote p-mode) - (setq switch2buffer buffer))))) - (when (boundp 'switch2buffer) - (switch-to-buffer switch2buffer))) - -And I have bound this to my F9 key - -(global-set-key [f9] '(lambda () (interactive) (cycle-buffer-by-mode "Shell$"))) - -* TODO test out usefulness of forward/back sexp in different languages - -* TODO major mode settings to check out in future -** emacs24 starter kit -- Nxhtml -- utilities for web development -[[http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html][Nxhtml]] is a large package of utilities for web development and for -embedding multiple major modes in a single buffer. - -Nxhtml is not installed in this version of the starter-kit by default, -for information on installing nxhtml see [[http://www.emacswiki.org/emacs/NxhtmlMode][EmacsWiki-Nxhtml]]. - -web-mode is competing package and actively developed, so i'm using that instead - - - (dolist (package '(yaml-mode js2-mode)) - (unless (package-installed-p package) - -- Associate modes with file extensions - -(add-to-list 'auto-mode-alist '("COMMIT_EDITMSG$" . diff-mode)) -(add-to-list 'auto-mode-alist '("\\.css$" . css-mode)) -(require 'yaml-mode) -(add-to-list 'auto-mode-alist '("\\.ya?ml$" . yaml-mode)) -(add-to-list 'auto-mode-alist '("\\.rb$" . ruby-mode)) -(add-to-list 'auto-mode-alist '("Rakefile$" . ruby-mode)) -(add-to-list 'auto-mode-alist '("\\.js\\(on\\)?$" . js2-mode)) -;; (add-to-list 'auto-mode-alist '("\\.xml$" . nxml-mode)) - -- clojure in starter-kit-lisp.org - -- others = gnus, js, publish, perl, python, perl, ruby - they each have their own starter kit file. - -- snippets for various modes other than org-mode - -* TODO update yasnippet documentation - yas expand key customization is rediculously hard to figure out - and completely undocumented -* TODO fix org source indenting, send patch -* TODO check out bundling aka compiling yasnippet -* TODO try xml/html mode url func - -(defun view-url () - "Open a new buffer containing the contents of URL." - (interactive) - (let* ((default (thing-at-point-url-at-point)) - (url (read-from-minibfer "URL: " default))) - (switch-to-buffer (url-retrieve-synchronously url)) - (rename-buffer url t) - ;; TODO: switch to nxml/nxhtml mode - (cond ((search-forward "") nil) -(define-key ac-completing-map (kbd "") nil) -(define-key ac-completing-map (kbd "") 'ac-expand) -(define-key ac-completing-map "\t" 'ac-complete) -(define-key ac-completing-map (kbd "") 'ac-complete) - - - -#+end_src -* auto-complete readline-complete -#+begin_src emacs-lisp - -(require 'readline-complete) -;; not sure how I made these, but I deleted, and -;; it would be nice to make them again sometime -;;(require 'src-loaddefs) - -;; disabled cuz broken -;; redefining function in readline-complete so ac-complete only uses readline as a source -(defun ac-rlc-setup-sources () - "Add me to shell-mode-hook!" - (setq ac-sources '(ac-source-shell))) -(add-hook 'shell-mode-hook 'ac-rlc-setup-sources) - -;; generally unnecessary, but why not -(setq explicit-shell-file-name "bash") - -;; readline-complete says to add this line. -;; however, it up my procfs directory tracking hook -;; because get-process doesn't notice the child shell. -;; instead, I've removed export EMACS=t from -;; comint-exec-1 (the function which initially sets it) -;; by finding it in emacs sources and redefinind it here -;; and done stty echo in my bashrc -;;(setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash")) - -(setenv "EMACS" "") -(setq explicit-bash-args nil) -(setq comint-process-echoes t) -;; default of 30 is way too slow. todo, consider pushing this upstream -(setq rlc-attempts 5) - -(add-to-list 'ac-modes 'shell-mode) - -;; readline-complete recommends this (i assume this format), -;; but greping finds no reference in emacs or my .emacs.d -;; so I'm assuming it is for an older emacs -;;(setq explicit-ssh-args '("-t")) - -(add-hook 'shell-mode-hook - (lambda () - (define-key shell-mode-map (kbd "") 'auto-complete))) - - -#+end_src -#+RESULTS: -: comint-exec-1 - -** readline complete fix - -I need this function here, where INSIDE_EMACS is replaced with RLC_INSIDE_EMACS. -#+begin_src emacs-lisp -;; ian: last update 2017-1-7. update this periodically from upstream -;; like when we do a major emacs update -(defun comint-exec-1 (name buffer command switches) - (let ((process-environment - (nconc - ;; If using termcap, we specify `emacs' as the terminal type - ;; because that lets us specify a width. - ;; If using terminfo, we specify `dumb' because that is - ;; a defined terminal type. `emacs' is not a defined terminal type - ;; and there is no way for us to define it here. - ;; Some programs that use terminfo get very confused - ;; if TERM is not a valid terminal type. - ;; ;; There is similar code in compile.el. - (if (and (boundp 'system-uses-terminfo) system-uses-terminfo) - (list "TERM=dumb" "TERMCAP=" - (format "COLUMNS=%d" (window-width))) - (list "TERM=emacs" - (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width)))) - (list (format "RLC_INSIDE_EMACS=%s,comint" emacs-version)) - process-environment)) - (default-directory - (if (file-accessible-directory-p default-directory) - default-directory - "/")) - proc decoding encoding changed) - (let ((exec-path (if (and command (file-name-directory command)) - ;; If the command has slashes, make sure we - ;; first look relative to the current directory. - (cons default-directory exec-path) exec-path))) - (setq proc (apply 'start-file-process name buffer command switches))) - ;; Some file name handler cannot start a process, fe ange-ftp. - (unless (processp proc) (error "No process started")) - (let ((coding-systems (process-coding-system proc))) - (setq decoding (car coding-systems) - encoding (cdr coding-systems))) - ;; Even if start-file-process left the coding system for encoding data - ;; sent from the process undecided, we had better use the same one - ;; as what we use for decoding. But, we should suppress EOL - ;; conversion. - (if (and decoding (not encoding)) - (setq encoding (coding-system-change-eol-conversion decoding 'unix) - changed t)) - (if changed - (set-process-coding-system proc decoding encoding)) - proc)) - -#+end_src - -* auto save & backup -#+begin_src emacs-lisp -(setq auto-save-timeout 1) ; idle time before auto-save. - -;; main hook for my auto save -(add-hook 'auto-save-hook 'my-auto-save) -;; additional hook to try to deal with emacs not auto-saving when a buffer isn't active -(add-hook 'window-configuration-change-hook 'my-auto-save-win) - -;; this function from mu4e really does not like buffer saving -(advice-add 'message-send-and-exit :before 'my-as-off) -(advice-add 'message-send-and-exit :after 'my-as-on) - -;; avoid window config hook saving too much, it can -;; get into loops in some random situations -(setq my-auto-save-last nil) -(defun my-auto-save-win () - (unless (eq (current-buffer) my-auto-save-last) - (my-auto-save (current-buffer)))) - -(defun my-auto-save (&optional last) - (when (and - my-as - (buffer-file-name) - ;; mu4e has a bug right now, undo breaks when saving drafts - (not (string= (buffer-file-name) "*draft*")) - (buffer-modified-p) - (not (org-src-edit-buffer-p))) - ;; serial is incremented on each save, so let's do a bit less of them - (not (derived-mode-p 'dns-mode)) - (setq my-auto-save-last last) - (let (message-log-max) - ;; a bit of a hack to partially suppress the constant saving in the echo area - (with-temp-message "" - (basic-save-buffer))))) - -;; in the message-send-and-exit advice, got an error because it passed an arg. -;; didn't look into why, just add ignored args. -(defun my-as-off (&rest ignore) - (interactive) - (setq my-as nil)) - -(defun my-as-off-local (&rest ignore) - (interactive) - (setq-local my-as nil)) - -(defun my-as-on (&rest ignore) - (interactive) - (setq my-as t)) - -(defun my-as-on-local (&rest ignore) - (interactive) - (setq-local my-as on)) - -;; based on suggestion in the emacs docs, redefine these 2 functions -;; to avoid prompt spamming the user when we do auto-save -(defun ask-user-about-supersession-threat (fn) - (discard-input) - (message - "File for %s has changed on disk outside of emacs. Auto-save is overwriting it, however -a backup is being created in case that is not what you intended." buffer-file-name) - (setq buffer-backed-up nil)) - -(defadvice ask-user-about-lock (before lock-deactivate-as activate) - (make-local-variable 'my-as) - (setq my-as nil) - (message "proper autosave has been turned off for this buffer because of lock file problem. - In this buffer, do M-x my-as-on to reenable")) - -;; todo, this doesn't work consistently to override the auto-save message -(defalias 'do-auto-save-original (symbol-function 'do-auto-save)) -(defun do-auto-save (&optional no-message current-only) - "This function has been modified to wrap the original so that NO-MESSAGE -is always set to t, since we auto-save a lot, it spams otherwise. -The original doc string is as follows: - -Auto-save all buffers that need it. -This is all buffers that have auto-saving enabled -and are changed since last auto-saved. -Auto-saving writes the buffer into a file -so that your editing is not lost if the system crashes. -This file is not the file you visited; that changes only when you save. -Normally we run the normal hook `auto-save-hook' before saving. - - -A non-nil NO-MESSAGE argument means do not print any message if successful. -A non-nil CURRENT-ONLY argument means save only current buffer." - (interactive) - (do-auto-save-original t current-only)) - -;; enable MY auto-save -(my-as-on) - -#+end_src - - -backups, separate from auto-save - -#+begin_src emacs-lisp - - ;; set backup file location -(setq backup-directory-alist '(("." . "~/.editor-backups"))) -(setq auto-save-file-name-transforms - '((".*" "~/.editor-backups/" t))) - -(setq version-control t ;; Use version numbers for backups - kept-new-versions 100 - kept-old-versions 2 - delete-old-versions t ;; delete old versions silently - ;; assume hard linked files are done on purpose, don't screw them up - backup-by-copying-when-linked t) - -;; todo, the time needs to be an integer, not a vector type thing -(defun constant-backup () - "Backup conditioned on some time passing since last one. - Hooked into 'before-save-hook." - (cl-flet ((b-time (minutes) - (< last-backup-time - (- (current-time) (* 60 minutes))))) - (when (or (not (boundp 'last-backup-time)) (and (< (buffer-size) 10000000) (b-time 5)) (b-time 30)) - (setq buffer-backed-up nil) - (setq-local last-backup-time (current-time))))) - -;; make a backup on auto-save, because the backup feature is not -;; utilized with my-auto-save, only normal interactive save. -;; todo, enable when fixed -;;(add-hook 'before-save-hook 'constant-backup) - -(add-hook 'auto-save-hook 'auto-save-size-limit) - -(defun auto-save-size-limit () - (when (and (not backup-inhibited) (> (buffer-size) 2000000)) - (message "Backups disabled for this buffer due to size > 2 megs") - (make-local-variable 'backup-inhibited) - (setq backup-inhibited t))) - -#+end_src - - - -background: - the faq suggests to auto-save using -(setq auto-save-visited-file-name t) - and to toggle auto-saving in the current buffer, type `M-x auto-save-mode' - - however, this is buggy. - it leaves around lock files, which can be disabled with - (setq create-lockfiles nil) - but it is also buggy on other things that appear to hook onto file saving - so i created my own function, which originally had bugs, - but new emacs version fixed all that, yay!. - - -; not using, but here for documentation, -; alternate way to enable and specify how long between autosaves. - ; number of input events between autosave. - ; lowest bound of functionality is actually about 15 input events - ;(setq auto-save-interval -** todo keep an eye out for why/when and fix the fact that normal auto-save files are being made soemtimes -they are #filename# -seems they are created - -* bbdb -#+begin_src emacs-lisp -;; 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) -(bbdb-initialize 'message) - -;; recommended by gnus, -;; but seems like it could be good to have set for other stuff -(setq user-full-name "Ian Kelling") -;; general email setting? recommended by mu4e -(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))) - -(require 'bbdb-csv-import) - - #+end_src - -* bookmark settings -#+begin_src emacs-lisp -; save bookmarks whenever they are changed instead of just when emacs quits -(setq bookmark-save-flag 1) -; increase bookmark context size for better functionality -(setq bookmark-search-size 2000) -#+end_src -* c-like settings -#+begin_src emacs-lisp -;; change last thing from gnu. -;; notably this avoids brace indent after if, and 4 space indent -(setq c-default-style '((java-mode . "java") - (awk-mode . "awk") - (other . "stroustrup"))) -;; for emacs itself, use -;; (setq c-default-style '((java-mode . "java") -;; (awk-mode . "awk") -;; (other . "gnu"))) -;; (setq-default c-basic-offset 2) -#+end_src -* color theme - -A Theme builder is available at http://elpa.gnu.org/themes/ along with -a list of pre-built themes at http://elpa.gnu.org/themes/view.html and -themes are available through ELPA. - - -interesting light themes - - - #+begin_src emacs-lisp -(defun override-theme (arg) - (interactive) - (while custom-enabled-themes - (disable-theme (car custom-enabled-themes))) - (load-theme arg t)) -(setq color-theme-is-global t) - -(defun toggle-night () - (interactive) - (cond ((equal (car custom-enabled-themes) 'naquadah) - ;; background off white to be better on the eyes. took this - ;; color from gitweb. - (custom-set-faces `(default ((t (:background "#F6F6F0"))))) - (override-theme 'leuven)) - (t - ;; revert previous background change - (custom-set-faces `(default ((t (:background nil))))) - (override-theme 'naquadah)))) - -(custom-set-faces `(default ((t (:background "#F6F6F0"))))) -(override-theme 'leuven) ;; org mode features, with monitor darkened. part of org-mode i think - - -;; disable color thing with this: -;;(disable-theme (car custom-enabled-themes)) - -;; decent dark themes - -;;(override-theme 'tangotango) -;;(override-theme 'deeper-blue) -;;(override-theme 'tango-dark) -;;(override-theme 'tsdh-dark) - -;;(override-theme 'heroku) -;;(override-theme 'inkpot) ;; part of inkpot-theme package -;;(override-theme 'naquadah) ; org mode features, part of naquadah-theme package -;;(override-theme 'spolsky) ;; part of sublime-themes package -;;(override-theme 'twilight-anti-bright) ;; from twilight-anti-bright-theme package - -;; interesting but not usable colors -;;(override-theme 'cyberpunk) ; cool org mode features, from cyberpunk-theme package -;;(override-theme 'wombat) ; cursor not visible enough. from a wombat package, not sure which -;;(override-theme 'misterioso) ; cursor not visible enough - - - -;;decent light themes -;;(override-theme 'alect-light) ; theres a -alt version, don't see a dif. could use this without dimming. from alect-something package -;;(override-theme 'occidental) ; from occidental-theme package - - -;;color-theme is deprecated in emacs 24. - -;; theme packages i tried then removed: -;; ignored ones that didn't use the new theme engine - -;;66 packages (zenburn-theme-2.1, zen-and-art-theme-1.0.1, waher-theme-20130917.7, ujelly-theme-1.0.35, twilight-theme-1.0.0, twilight-bright-theme-20130605.143, twilight-anti-bright-theme-20120713.316, tronesque-theme-1.3, tron-theme-12, toxi-theme-0.1.0, tommyh-theme-1.2, tango-2-theme-1.0.0, sunny-day-theme-20131203.1250, sublime-themes-20140117.323, subatomic-theme-20131011.1048, soothe-theme-0.3.16, soft-morning-theme-20131211.1342, soft-charcoal-theme-20130924.1206, sea-before-storm-theme-0.3, purple-haze-theme-20130929.1751, phoenix-dark-pink-theme-20130905.941, phoenix-dark-mono-theme-20130306.1215, pastels-on-dark-theme-0.3, obsidian-theme-20130920.937, nzenburn-theme-20130513, noctilux-theme-20131019.31, mustang-theme-20130920.939, monokai-theme-0.0.10, molokai-theme-20130828.0, late-night-theme-0.0, jujube-theme-0.1, ir-black-theme-20130302.2355, gruvbox-theme-20131229.1458, gruber-darker-theme-0.6, grandshell-theme-20140118.1003, github-theme-0.0.3, gandalf-theme-0.1, flatland-theme-20131204.858, django-theme-20131022.202, deep-thought-theme-0.1.1, dakrone-theme-20131212.1159, colorsarenice-theme-20131128.1106, color-theme-wombat+-0.0.2, color-theme-wombat-0.0.1, color-theme-twilight-0.1, color-theme-tango-0.0.2, color-theme-solarized-20120301, color-theme-sanityinc-solarized-2.25, color-theme-railscasts-0.0.2, color-theme-monokai-0.0.5, color-theme-molokai-0.1, color-theme-ir-black-1.0.1, color-theme-heroku-1.0.0, color-theme-github-0.0.3, color-theme-eclipse-0.0.2, color-theme-dpaste-0.0.1, color-theme-dawn-night-1.0, color-theme-colorful-obsolescence-0.0.1, color-theme-cobalt-0.0.2, color-theme-20080305.34, clues-theme-20130908.801, busybee-theme-20130920.942, bubbleberry-theme-0.1.2, mblage-theme-20130715.621, anti-zenburn-theme-20140104.1542, ample-zen-theme-0.2) - - - -#+end_src - -* yasnippet - -cd ~/.emacs.d/src -git clone --recursive https://github.com/capitaomorte/yasnippet -touch snippets/.yas-make-groups - - This all makes it so I can look through the default snippets - in the menu bar, but they don't show up elsewhere, because they are - mostly things I don't want. - -#+begin_src emacs-lisp - - (require 'yasnippet) - ;; this needs to be before yas-global-mode - (setq yas-snippet-dirs (list "~/.emacs.d/snippets")) - (yas-global-mode 1) - - (setq - yas-also-auto-indent-first-line t - yas-choose-tables-first t - yas-use-menu (quote full) - ;; this sets ido-prompt as first function - yas-prompt-functions - '(yas-ido-prompt yas-dropdown-prompt yas-x-prompt yas-completing-prompt yas-no-prompt)) - - ;; todo, explore this option for wrapping region - ;; '(yas/wrap-around-region t)) - -#+end_src - -#+RESULTS: -| yas-ido-prompt | yas-dropdown-prompt | yas-x-prompt | yas-completing-prompt | yas-no-prompt | - -* cross session settings - #+begin_src emacs-lisp - -;; Save a list of recent files visited. -(recentf-mode 1) -(setq recentf-max-saved-items 200 - recentf-max-menu-items 15) - - -(setq save-place t - save-place-version-control 'nospecial - save-place-limit 40000 - save-place-file "~/.emacs.d/places") - - - -;; savehist keeps track of some history -;; search entries -(setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring) - ;; save every minute - savehist-autosave-interval 60 - ;; keep the home clean - savehist-file "~/.emacs.d/.savehist") -(savehist-mode 1) - -#+end_src - -* ediff -#+begin_src emacs-lisp -;; ediff-buffers is the main command to use - -;; ediff - don't start another frame for the control panel -;; unfortunately, this doesn't allow me to use 2 frames for the diff buffers -;; so disable this temporarily with the next line if you want that -;; sometime I should setup 2 functions to explicitly do each type -(setq ediff-window-setup-function 'ediff-setup-windows-plain) -;;(setq ediff-window-setup-function 'ediff-setup-windows-default) - -;; do side by side diffs -(setq ediff-split-window-function 'split-window-horizontally) - - -#+end_src - - - -Things I tried which didn't work, which intuitively I think should work better: I can open the second diff buffer in a new frame, and close it's window in the first frame after starting ediff, but when I hit n to go to the next diff, it restores the window in the first frame. Another thing I tried is to open 2 new frames and set them up as I want. However, if I try to open the *Ediff Control Panel* buffer in a different window from its original one, my mouse jumps to one of the diff frames, or if that isn't visible, the buffer just hangs until I select the original ediff control panel window. This seems like a bug to me. I am using a very recent development version of emacs. - -* dired -#+begin_src emacs-lisp - -;; dired - reuse current buffer by pressing 'a' -(put 'dired-find-alternate-file 'disabled nil) -#+end_src - -* mu4e -[[info:org#External links]] -[[info:mu4e#Keybindings]] - -alsot tried notmuch, it had some glitches, and it's config -has a list of folders which i'd rather not publish, so it's config is archived. - -#+begin_src emacs-lisp -;;(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e") -;;(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e") -(require 'mu4e) - -;; (setq mu4e-headers-results-limit 2000) - -(setq -;; common to gnus. default sendmail-query-once asks us, then sets this via customize. -send-mail-function (quote sendmail-send-it) - ;; use the standard imap folders - mu4e-sent-folder "/Sent" - mu4e-drafts-folder "/Drafts" - mu4e-trash-folder "/Trash" - ;; reindex new mail this often in seconds - ;; show addresses instead of just names - mu4e-view-show-addresses t - mu4e-use-fancy-chars t - mu4e-confirm-quit nil - mu4e-headers-leave-behavior 'apply ;; dont ask, do whatever was marked - mu4e-headers-fields (delq (assoc :mailing-list mu4e-headers-fields) mu4e-headers-fields) - ;; default 500. - mu4e-headers-results-limit 1000 - ;; tell exim to use from: as envelope from. - ;; exim's default is use outgoing_msg_localpart@hostname. - mail-specify-envelope-from t - - ;; looking up the list of maildirs when doing jo from summary - ;; can take a few seconds if we have a ton of messages. - ;; Only take that time for the first lookup. - ;; if we add a new maildir, just restart mu4e for it to be in that list. - mu4e-cache-maildir-list t - ;; default is 8, way too small for my big monitors - mu4e-headers-visible-lines 50 - ) - -;; fucks up reading unread bookmark. when that is fixed, enable it -;; (setq mu4e-update-interval 60) - - -;; this file includes setting up my email addresses, which are not public, -;; including -;; mu4e-user-mail-address-list -;; and a function -;; inspired by mu4e info manual, search for mu4e-compose-pre-hook. -(load "/p/c/mu4e.el") - -(defun my-decrypt () - ;; use for decrypting in mu4e - (interactive) - (beginning-of-buffer) - (when (search-forward "-----BEGIN PGP MESSAGE-----" nil t) - (read-only-mode 0) - (let ((start (match-beginning 0)) - (end (search-forward "-----END PGP MESSAGE-----" nil t))) - (shell-command-on-region start end "gpg2 -dq" nil t shell-command-default-error-buffer t) - ))) -(add-hook 'mu4e-view-mode-hook 'my-decrypt) - -(defun mu-set-from-name (regexes) - "If we find an address matching regex, then set that address as the to, -and whatever was used" - (when mu4e-compose-parent-message - (let ((found nil)) - (while (and regexes (not found)) - (setq re (car regexes) - regexes (cdr regexes) - found (mu4e-message-contact-field-matches - mu4e-compose-parent-message :to re))) - (when found (setq user-mail-address (cdr found) - user-full-name (car found))) - found))) -(defun mu-set-from (regexes) - "If we find an address matching regex, then set that address as the to, -and Ian Kelling as the name" - (when mu4e-compose-parent-message - (let ((found nil)) - (while (and regexes (not found)) - (setq re (car regexes) - regexes (cdr regexes) - found (cdr (mu4e-message-contact-field-matches - mu4e-compose-parent-message :to re)))) - (when found (setq user-mail-address found - user-full-name "Ian Kelling")) - found))) - - -(defun my-mu4e-to-fsf () - "inspired by mu4e info manual, search for mu4e-compose-pre-hook." - (cond - ((mu-set-from '("iank@fsf.org" - "iank@gnu.org"))) - ((setq user-mail-address "iank@fsf.org" - user-full-name "Ian Kelling")))) - - -;; on first run mkdir -p /nocow/user/.mufsf; mu index --maildir=/nocow/user/fsfmd -(defun mu-exit-wait () - (interactive) - ;; taken from the mu source - (let* ((buf (get-buffer mu4e~proc-name)) - (proc (and (buffer-live-p buf) (get-buffer-process buf)))) - (mu4e-quit) - ;; without sleep, we get database locked by another process error when hitting u - ;; if another mu was running. - (if proc (sleep-for 0 1000)))) - -(defun fsf-mu4e () - (interactive) - (unless (equal mu4e-maildir "/nocow/user/fsfmd") (mu-exit-wait)) - (setq - ;; fsf monitor is smaller - mu4e-headers-visible-lines 15 - mu4e-maildir "/nocow/user/fsfmd" - mu4e-refile-folder "/Spam" - mu4e-index-lazy-check nil - mu4e-get-mail-command "true" - user-mail-address "iank@fsf.org" - mail-signature " - --- -Ian Kelling | Senior Systems Administrator, Free Software Foundation -GPG Key: B125 F60B 7B28 7FF6 A2B7 DF8F 170A F0E2 9542 95DF -https://fsf.org | https://gnu.org -" - - mu4e-user-mail-address-list '("iank@fsf.org" - "iank@gnu.org") - mu4e-maildir-shortcuts - '( ("/INBOX" . ?i) - ("/sysadmin" . ?a) - ("/sec" . ?x) - ("/rtcc" . ?c) - ("/Drafts" . ?d) - ("/Sent" . ?s) - ) - ) ;; end setq - (call-process "/a/exe/lnf" nil nil nil "-T" "/nocow/user/.mufsf" (concat (getenv "HOME") "/.mu")) - (add-hook 'mu4e-compose-pre-hook 'my-mu4e-to-fsf) - (remove-hook 'mu4e-compose-pre-hook 'my-mu4e-to) - (mu4e)) ;; end defun fsf-mu4e - - -;; it's implemented in mu4e, but not in the actions list for -;; some reason. -(add-to-list 'mu4e-view-actions - '("browser view" . mu4e-action-view-in-browser) t) - -;; normally, you would add to this, but we want to -;; modify unread messages. the first 4 are defined by default. -(setq mu4e-bookmarks - `( ,(make-mu4e-bookmark - :name "Unread messages" - ;; old less restrictive unread, for adapting in the future: - ;; flag:unread AND NOT flag:trashed AND NOT maildir:/Junk AND NOT maildir:/fwfw AND NOT maildir:/log - :query "flag:unread maildir:/INBOX" - :key ?u) - ,(make-mu4e-bookmark - :name "Today's messages" - :query "date:today..now" - :key ?t) - ,(make-mu4e-bookmark - :name "Last 7 days" - :query "date:7d..now" - :key ?w) - ,(make-mu4e-bookmark - :name "Messages with images" - :query "mime:image/*" - :key ?p)) - ) - - -(defun mu4e-action-msgs-by-this-sender (msg) - "In header view, view messages by the sender of the message under point." - (let ((from (mu4e-message-field msg :from))) - (unless from - (mu4e-error "No from header for this message")) - ;; from is structured like: (("Anacron" . "root@x2.lan")) - (mu4e-headers-search (concat "f:" (cdar from))))) - -(add-to-list 'mu4e-headers-actions - '("from this sender" . mu4e-action-msgs-by-this-sender) t) -(add-to-list 'mu4e-view-actions - '("from this sender" . mu4e-action-msgs-by-this-sender) t) -#+end_src - - - -* disabled but saved for documentation purposes -:PROPERTIES: -:header-args: :tangle no -:END: - -** ido keybinds -*** C-j -ido-find-file create file -*** //] -ido goto root -*** C-k] -ido kill buffer/file -*** C-d] -ido open dired buffer -*** M-d] -ido search within all subdirectories -*** M-m] -ido create subdirectory -*** M-s] -ido search recently used directories -*** M-n/p] -ido next/previous recently used directory -*** C-s] -**** TODO implement this keybind, normally ctrl-space -ido use current pattern and start a new one - - -** indent settings for git's perl code -don't have a way to set this automatically or a good place to put this -#+begin_src emacs-lisp -(setq - perl-indent-level 8 - perl-continued-statement-offset 8 - perl-continued-brace-offset -8 - perl-brace-offset 0 - perl-brace-imaginary-offset 0 - indent-tabs-mode t - ) -#+end_src -** org mode website - -#+begin_src emacs-lisp -;; use org-publish-current-project with a project file open -(setq org-publish-project-alist - '(("org" - :base-directory "/a/h/src" - :publishing-directory "/a/h/output" - :base-extension "org" - ;;:publishing-function org-org-publish-to-org - :publishing-function org-html-publish-to-html - :preserve-breaks t - :html-postamble "Everything here is \"Creative" - :html-head "" - :htmlized-source t) - ("othersrc" - :base-directory "/a/h/src" - :base-extension "css\\|el\\|" - :publishing-directory "/a/h/output" - :publishing-function org-publish-attachment) - ("other" - :base-directory "/a/h/other" - :base-extension ".*" - :publishing-directory "/a/h/output" - :publishing-function org-publish-attachment))) -;; default is xhtml-strict. don't really care, but this is more common -(setq org-html-doctype "html4-strict") - -;; this is needed for worg -;; todo: for my own site, I need to define the css in a separate file -;; in order to use this setting. see the variable help for info -(setq org-export-htmlize-output-type t) - - -#+end_src - -** bash-completion -#+begin_src emacs-lisp -;; this eventually gets set in -;; comint-dynamic-complete-functions -;; (car comint-dynamic-complete-functions) -(autoload 'bash-completion-dynamic-complete "bash-completion" - "BASH completion hook") -(add-hook 'shell-dynamic-complete-functions - 'bash-completion-dynamic-complete) - -;; this appears useless, but was in the recommended init code -(add-hook 'shell-command-complete-functions - 'bash-completion-dynamic-complete) - -(defun ac-rlc-setup-sources () - "Add me to shell-mode-hook!" - (setq ac-sources '(ac-source-shell))) -(add-hook 'shell-mode-hook 'ac-rlc-setup-sources) - -#+end_src - -** misc stuff - It is an awesome mode for keyboard navigation. - However, using the mouse takes less thought and works as well - - #+begin_src emacs-lisp - - - ;; whitespace-mode config. minimal for bad whitespace - ;(setq whitespace-line-column 80) ; for style of lines-tail, but I have it disabled - (setq whitespace-style '(face tabs empty trailing)) - ;to enable whitespace mode - (whitespace-mode +1) - - - - (defun org-set-mark-command (arg) - "Do set-mark-command and then org-show-context if the point - moves to invisible text." - (interactive "P") - (let ((initial-point (point))) - (setq this-command 'set-mark-command) - (set-mark-command (arg)) - (if (and (not (= (point) initial-point)) - (or (outline-invisible-p) (org-invisible-p2))) - (org-show-context 'mark-goto)))) - - (defun org-exchange-point-and-mark (&optional arg) - (interactive "P") - (let ((initial-point (point))) - (exchange-point-and-mark) - (if (and (not (= (point) initial-point)) - (or (outline-invisible-p) (org-invisible-p2))) - (org-show-context 'mark-goto)))) - - - (defun toggle-mode-line () - "Toggle mode line on and off." - (interactive) - (if mode-line-format - (progn (setq my-saved-mode-line-format mode-line-format) - (setq mode-line-format nil)) - (setq mode-line-format my-saved-mode-line-format)) - (force-mode-line-update)) - (toggle-mode-line) - (global-set-key (kbd "M-m") 'toggle-mode-line) - (add-hook 'after-change-major-mode-hook - (lambda () (setq my-saved-mode-line-format mode-line-format) - (setq mode-line-format nil))) - - - #+end_src - -** Copy mode-line to the top - #+begin_src emacs-lisp -;; Copy mode-line to the top -(setq-default header-line-format mode-line-format -mode-line-format nil) -;; copied the mode-line theme into the header theme, else it is unreadable -;; this goes after loading the theme -(let ((class '((class color) (min-colors 89)))) -(custom-theme-set-faces - 'leuven - `(header-line ((,class (:box (:line-width 1 :color "#1A2F54") :foreground "#85CEEB" :background "#335EA8")))))) - - #+end_src - -** tab bindings for when I wanted to make tab be for search -#+begin_src emacs-lisp - - (define-key emacs-lisp-mode-map (kbd "") nil) - (define-key button-buffer-map "\t" nil) - (define-key button-buffer-map (kbd "f") 'forward-button) - (define-key Info-mode-map "\t" nil) - (define-key widget-keymap "\t" nil) - (define-key widget-keymap (kbd "") nil) - - (add-hook 'compilation-mode-hook (lambda () - (define-key compilation-mode-map (kbd "") nil) - (define-key compilation-mode-map "\t" nil))) - -;; unbind c-i for yas. it already separately binds - (add-hook 'yas-minor-mode-hook (lambda () - (define-key yas-minor-mode-map "\t" nil))) - - (add-hook 'haskell-interactive-mode-hook - (lambda () - (define-key haskell-interactive-mode-map "\t" nil) - (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-tab))) - - (define-key minibuffer-local-must-match-map "\t" nil) - (define-key minibuffer-local-must-match-map (kbd "") 'minibuffer-complete) - (define-key minibuffer-local-completion-map (kbd "") 'minibuffer-complete) - (define-key minibuffer-local-completion-map "\t" 'minibuffer-complete) - - (add-hook 'ido-setup-hook - (lambda() - (define-key ido-completion-map (kbd "") 'ido-complete) - (define-key ido-completion-map "\t" nil))) - -#+end_src - -** kill buffer and window -#+begin_src emacs-lisp - (defun kill-buffer-and-window () - "Close the current window and kill the buffer it's visiting." - (interactive) - (progn - (kill-buffer) - (delete-window))) -#+end_src -** sending multiple commands to a comint buffer -without waiting for commands to finish is unreliable. -seems like 1 in 100 times, an invisible command to restore prompt didn't work -#+begin_src emacs-lisp -(setq shell-unset-prompt "unset PROMPT_COMMAND; unset PS1") - (setq shell-set-prompt "PROMPT_COMMAND=prompt_command") - -(if (boundp 'shell-unset-prompt) - (send-invisible-string proc shell-unset-prompt)) -(if (boundp 'shell-set-prompt) - (send-invisible-string proc shell-set-prompt)) - - - (defun send-invisible-string (proc string) - "Like send-invisible, but non-interactive" - (comint-snapshot-last-prompt) - (funcall comint-input-sender proc string)) - -#+end_src - - - - -** org-mode auto-complete source - -todo, someday take a look at this. it is broken. - -;(defvar ac-source-eshell-pcomplete -; '((candidates . (pcomplete-completions)))) -;(defun ac-complete-eshell-pcomplete () -; (interactive) -; (auto-complete '(ac-source-eshell-pcomplete))) - -;(add-hook 'org-mode-hook (lambda () (setq ac-sources (cons 'ac-source-eshell-pcomplete ac-sources)))) -;(add-to-list 'ac-modes 'eshell-mode) - - -** gnus nice unicode - - -this looks nice, but it lags gnus just a bit -#+begin_src emacs-lisp - -(defun gnus-pretty-chars-setup () - (when window-system - (setq gnus-sum-thread-tree-indent " " - gnus-sum-thread-tree-root "● " - gnus-sum-thread-tree-false-root "◯ " - gnus-sum-thread-tree-single-indent "◎ " - gnus-sum-thread-tree-leaf-with-other "├─► " - gnus-sum-thread-tree-vertical "│" - gnus-sum-thread-tree-single-leaf "╰─► "))) -;; dunno why, but this didn't work just setting on startup -(add-hook 'gnus-startup-hook 'gnus-pretty-chars-setup) - -#+end_src - -** misc -#+begin_src emacs-lisp - -;; this makes more ergonomic sense, since our eyes are mostly on the left, -;; but after using it a while, it's too much cognitive dissonance that -;; every other program has it on the right -;;(set-scroll-bar-mode 'left) - - - -; todo, is this require things necessary? -; (require 'flyspell) - - - - ; whenever M-tab is completion, swap it with tab - ;(define-key emacs-lisp-mode-map (kbd "") 'completion-at-point) - ;(define-key emacs-lisp-mode-map (kbd "C-M-i") 'indent-for-tab-command) - ;(define-key lisp-interaction-mode-map (kbd "") 'completion-at-point) - ;(define-key lisp-interaction-mode-map (kbd "C-M-i") 'indent-for-tab-command) - ;the global tab keyind. for some reason this totally screws up mini-buffer tab. - ; disabled until I actually find myself using this, and find a fix for the above problem - ;(global-set-key (kbd "") 'complete-symbol) - - - ; todo, make my custom overlays have an underline if they are - ; overriding a paren matching overlay - ; make right click set the mark - ; make search tab do completion instead of meta-tab - ; in isearch, move C-y to C-v - ; in isearch, move c-s to c-f - - ; some testing to figure out the underlining when paren highlight conflicts - ; (let ((extra-overlays (overlays-at (1+ end-point)))) - ; (when extra-overlays (print extra-overlays))) - - - - - ; commented out because it messes up yank-pop. -; todo, fix it someday - ; make yank linewise if it ends in a newline - ;(defadvice yank (before linewise-yank-advice activate) - ; (let ((arg (ad-get-arg 0))) - ; (when (string-match "\n[ \t]*$" (current-kill (cond - ;; ((listp arg) 0) - ;; ((eq arg '-) -2) - ;; (t (1- arg))) t)) - ;; (move-beginning-of-line nil)))) - - - -; todo, look into augmenting auto-complete with hippie expand. -; starter kit has some hippie expand settings to look into: -; (when (boundp 'hippie-expand-try-functions-list) -; (delete 'try-expand-line hippie-expand-try-functions-list) -; (delete 'try-expand-list hippie-expand-try-functions-list)) - - -;; hippie expand is dabbrev expand on steroids -;(setq hippie-expand-try-functions-list '(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 -; try-expand-list -; try-expand-line -; try-complete-lisp-symbol-partially -; try-complete-lisp-symbol)) -;; use hippie-expand instead of dabbrev -;(global-set-key (kbd "M-/") 'hippie-expand) - - -; commented because i haven't had time to check it out yet -;; shorter aliases for ack-and-a-half commands -;(defalias 'ack 'ack-and-a-half) -;(defalias 'ack-same 'ack-and-a-half-same) -;(defalias 'ack-find-file 'ack-and-a-half-find-file) -;(defalias 'ack-find-file-same 'ack-and-a-half-find-file-same) - - - - -; todo. take a look at fixing this -;delete-old-versions t ; fix description in http://www.emacswiki.org/emacs/ForceBackups - - - - -;; prelude uses paredit mode. -;; paredit has some useful stuff but also annoying stuff. -;; if I ever do a ton of lisp coding, I should look into it - - - - - - - ; random notes and example code - - - ; usefull thing - ;(map 'list #'list tabSwapKeys (reverse (getBinds tabSwapKeys))) - - ; example of getting keymap info - ;(car (car (minor-mode-key-binding (kbd "C-/") t))) - ;(cdr (car (minor-mode-key-binding (kbd "C-/") t))) - ;(global-key-binding (kbd "C-M-i") t) - ;(minor-mode-key-binding (kbd "") t) - ;(local-key-binding (kbd "C-M-i") t) - ;(current-minor-mode-maps) - ;(cdr (assq 'undo-tree-mode minor-mode-map-alist)) - - - ; center on incremental search, instead of being at top or bottom of screen. - ; i'm hoping that setting Isearch Allow Scroll is good enough to fix this annoyance - ;from http://stackoverflow.com/questions/11052678/emacs-combine-iseach-forward-and-recenter-top-bottom - - ;example of constant definition of an overlay and propreries - ;(defface mouse-flash-position '((t (:background "Yellow"))) - ; "*Face used to highlight mouse position temporarily." - ; :group 'mouse) - ;(defface mouse-flash-position '((t (:background "Yellow"))) - ; "*Face used to highlight mouse position temporarily." - ; :group 'mouse) - ;(defconst mouse-flash-posn-overlay - ; ;; Create and immediately delete, to get "overlay in no buffer". - ; (let ((ol (make-overlay (point-min) (point-max)))) - ; ;(delete-overlay ol) - ; ;(overlay-put ol 'face 'mouse-flash-position) - ; (overlay-put ol 'mouse-face 'mouse-flash-position) - ; (overlay-put ol 'priority 1000000) - ; ol) - ; "Overlay to highlight current mouse position.") - - - ;tip, put the last interactive command as elisp on the kill ring: - ;C-x C-a C-k C-g - - ; example of overlay testing - ;(setq foo (make-overlay 2 3 nil t nil)) - ;(setq foo2 (make-overlay 3 4 nil t nil)) - ;(overlay-put foo 'face '(:background "red3" :foreground "black")) - ;(overlay-put foo2 'face '(:background "red1" :foreground "black")) - ;(overlay-put foo 'face 'visible-mark-face) - ;(overlay-put foo 'face visible-mark-face2) - - -#+end_src - - -** SQL - -disabled, as I haven't used it in a long time. I think it was good for learning some sql stuff. -#+begin_src emacs-lisp :tangle no -(require 'sqlup-mode) -(add-hook 'sql-mode-hook 'sqlup-mode) -(add-hook 'sql-interactive-mode-hook 'sqlup-mode) - -(setq sql-product 'postgres) -#+end_src - - -** icomplete -#+begin_src emacs-lisp -;; without this, on partial completion return would exit the minibuffer, and i had to -;; keep typing out letters do a full completion before pressing enter. -;; super annoying. So I picked ctrl-j as a free key to put exit, -;; but in practice, I would just use ctrl-g to quit. Anyways, -;; ivy is doing all the minibuffer stuff, so removed this as it's -;; unused, so it can't cause any problems in future -(when (boundp 'icomplete-minibuffer-map) - (define-key icomplete-minibuffer-map (kbd "C-j") 'exit-minibuffer) - (define-key icomplete-minibuffer-map (kbd "") - 'minibuffer-force-complete-and-exit)) - - -#+end_src -* elisp settings -#+begin_src emacs-lisp -; when manually evaluating lisp, go into debugger on error -(setq eval-expression-debug-on-error t) -;reminder of useful var: debug-on-error -#+end_src - - - - - -* gnus - -good info http://www.emacswiki.org/emacs/GnusTutorial -good info http://www.emacs.uniyar.ac.ru/doc/em24h/emacs183.htm - - -After downloading mailing list archives, once you have an mbox file, -there are rather straightforward ways to get it into any mail program, -but I will cover gnus, which I use and is a bit tricky. - -gnus has a native search (limited, too slow for body text searches), and external search engine integration. -gnus manual recommends converting to maildir for searching local mail, but importing lots of maildir messages to gnus -takes 10+ minutes, so scratch that option. it suggests 2 alternate options -mairix. for mbox, it doesn't integrate 100% with gnus, it copies the search results to a mbox -and tells gnus to make a group of that mbox and display it. This means the read state won't be persistent, but otherwise -works great. - -local imap server which will use the mbox and provide search. -dovecot is modular, theres a dovecot-common which uses recommends to install i guess it's most used modules. Its -description is completely not useful. Anyways, I'm not sure if there is any benefit to installing this over just the -module we need. -pi dovecot-imapd - -dovecot by default also makes a an inbox folder based on the normal local mail location /var/mail/ -those locations are adjustable and well documented via the var mail_location in -/etc/dovecot/conf.d/10-mail.conf -I forward my local mail, didn't see immediately how to turn off the inbox, but it will always be empty, so I left as -is. you could make the var be empty, which apparently has the same effect. - -Originally just linked the default location ~/.mail, but I changed to altering the config since ~/.mail since it seems -other things like postfix use that location - -based on http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html -other links that poped up contained outdated, innacurate information -http://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/ -http://www.emacswiki.org/emacs/JamesFerguson -http://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/ - -Within emacs you can move messages between mbox and maildir etc, which is a nice flexibility. - - - -doc group for mbox: -in gnus, do gnus-group-make-doc-group (G f in groups buffer) and point to the file - -info about groups created within gnus is stored in ~/.newsrc.eld -also stored is a duplication of what email messages are read/unread, -what newsgroups are subsribed to and read/unread, -probably more stuff, everything that gnus saves. - - -searching the body of the messages, i cut off after a few minutes. -i can grep the file in just a couple seconds - - -random side note -we can also get mbox from gmane -http://notmuchmail.org/howto/#index7h2 - - -gnus can't search mboxes except with its builtin search which is extremely slow. mairix can do mbox files from the command -line, but not from within gnus, but from mairix.el, which can then open the results in gnus - -mbox can be converted to maildir easily, but gnus loads lots of maildir messages extremely slow. it parses all the -headers and generates a nov file for each. - -nnfolder-generate-active-file - -to reset things, when changing mail group. I duno all the proper way, but it works to delete -~/Mail ~/.newsrc.eld ~/.dribble (or something) - - -** mail sources vs select methods background -I found this very confusing when first reading through the manual. "mail sources" is a term that does not simply mean -sources of mail, it is much narrower for gnus. sources of mail can be either "mail sources" or select methods. Mail -sources will move mail to ~/Mail (not sure what format), and split it into groups according to variables. You can use -"mail sources" for maildir / imap, but those can also be read via select methods, which do not move the mail from their -location, but use them in their native format. This is what I want to do, and I can simply ignore mail -sources. Confusing terminology is that "fetching mail" "scanning mail", lots of things mail doesn't mean all mail, it -means specifically from "mail sources". The words "articles" and "news" is used in connection with select methods, aka my actual mail. - - - -** caching background - -caching: -there is also ~/News/cache, filled with a bunch of articles, like 300 megs. can't figure out why. -Grepped for caching in the manual, found 2 main things. -cache is for 2 purposes. to cache locally, and to keep articles from expiring, called persistence -gnus-use-cache, which puts things if they are -gnus-cache-enter-articles -things go in cache when they are marked certain ways by default, ticked and dormant -and read articles are moved out of the cache -still no idea why i have a bunch in the cache, but I set a var so that my mail won't get cached -I'm gonna delete the cache, and check on it later see what exactly is going in there -And of course, I moved ~/News to my encrypted drive and symlinked it - - -* haskell -:LOGBOOK: -:END: - -useful comint-shell mode commands. If not prefaced with *, it means it is not in the haskell custom repl -*todo: setup haskell c-t toggle arrow keys -tab completion -C-q insert prev arg -C-( history search -c-m-left/right move to next/prev prompts -*c-enter, multi-line input -*s-delete, send input across windows. (i can implement this) -*c-m-l clear screen -*haskell-process-interrupt, c-cc terminate job (i can implement this maybe) - -nice bash/readline functions missing in comint: -yank-nth-arg -operate-get-next -menu-complete - -usefull comint commands: -c-cl : list historic command in temp buffer -C-c C-o comint-delete-output -comint-restore-input, todo: put this on a randomish c-c key - - - -todo: -checkout haskell repl functions: -c-cv haskell-check, hlint -C-M-q prog-indent-sexp -c-c. haskell-mode-format-imports -C-c M-/ haskell-doc-check-active -haskell-process-generate-tags -haskell-process-cabal-build -haskell-cabal-command.. or something -haskell-process-restart -C-h v haskell-process-log -C-h v haskell-process-show-debug-tips - -various not immediately useful functions: -haskell-process-add-dependency -haskell-process-touch-buffer -haskell-process-cd -haskell-process-unignore -haskell-process-reload-devel-main - - -rebind -home: C-a haskell-interactive-mode-beginning -c-return: C-j haskell-interactive-mode-newline-indent -up/down: haskell-interactive-mode-history-next - -todo haskell mode better binds for: -'haskell-process-load-file -'haskell-process-do-type -'haskell-process-do-info -'inferior-haskell-send-decl - - -commands which don't work in haskell-interactive-mode(hi) vs inferior-haskell-mode(ih, default) -functions not in hi: -inferior-haskell-find-definition, use tags instead -inferior-haskell-find-haddock, todo, test if this works - -redefined ih to hi -switch-to-haskell -> 'haskell-interactive-switch -haskell-process-load-file -> inferior-haskell-load-file -haskell-process-do-type -> inferior-haskell-type -switch-to-haskell -> haskell-interactive-switch -inferior-haskell-load-file -> 'haskell-process-load-file - - -haskell-mode installation from source, based on its readme -in the git directory, -make all - -#+begin_src emacs-lisp - - - -;; remove default option to not link the file -(setq haskell-compile-command "ghc -Wall -ferror-spans -fforce-recomp %s") -(add-hook 'haskell-indentation-mode-hook - (lambda () - (define-key haskell-indentation-mode-map [?\C-d] nil) - (define-key haskell-indentation-mode-map - (kbd "") - 'haskell-indentation-delete-char))) - -;;copied from haskell-mode docs in order to use the new, better, nondefault -;;interactive mode. -(eval-after-load "haskell-mode" - '(progn - (define-key haskell-mode-map (kbd "C-x C-d") nil) - (define-key haskell-mode-map (kbd "C-c C-z") 'haskell-interactive-switch) - (define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-file) - (define-key haskell-mode-map (kbd "C-c C-b") 'haskell-interactive-switch) - (define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type) - (define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info) - (define-key haskell-mode-map (kbd "C-c M-.") nil) - (define-key haskell-mode-map (kbd "C-c C-d") nil))) - -;; ghc-mod install http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html -;; todo, try this out -;; (autoload 'ghc-init "ghc" nil t) -;;(add-hook 'haskell-mode-hook (lambda () (ghc-init) (flymake-mode))) - - - -;; from the package readme for ghci-completion -(require 'ghci-completion) -(add-hook 'inferior-haskell-mode-hook 'turn-on-ghci-completion) - - -;; disable some rebinds. they are set to appropriate keys in the keybinds section -(eval-after-load "haskell-mode" - '(progn - (define-key haskell-mode-map (kbd "C-a") 'nil) - (define-key haskell-mode-map (kbd "C-j") 'nil))) - -(eval-after-load "python-mode" - '(progn -(define-key python-mode-map (kbd "C-j") nil))) - -(defun pretty-lambdas-haskell () - (font-lock-add-keywords - nil `((,(concat "(?\\(" (regexp-quote "\\") "\\)") - (0 (progn (compose-region (match-beginning 1) (match-end 1) - ,(make-char 'greek-iso8859-7 107)) - nil)))))) -;; from haskell-mode manual -(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan) -(when (window-system) - (add-hook 'haskell-mode-hook 'pretty-lambdas-haskell)) - -;; added from haskell-mode website install instructions - ;(load "/usr/share/emacs/site-lisp/haskell-mode/haskell-site-file") -(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) -;;the three indentation modules are mutually exclusive - add at most one. Trying out the "most advanced" -(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation) -;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent) -;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent) - - -;; todo, set this to some other key -;; (local-set-key (kbd "C-e") 'my-haskell-load-and-run) - -(defun my-haskell-load-and-run () - "Loads and runs the current Haskell file." - (interactive) - (let ((start-buffer (current-buffer))) - (inferior-haskell-load-and-run inferior-haskell-run-command) - (sleep-for 0 100) - (end-of-buffer) - (pop-to-buffer start-buffer))) - -;; show haskell function in mode line -;; todo, this broke after updating emacs -;;(eval-after-load "which-func" -;; '(add-to-list 'which-func-modes 'haskell-mode)) - - - -(add-hook 'interactive-haskell-mode-hook 'ac-haskell-process-setup) -(add-hook 'haskell-interactive-mode-hook 'ac-haskell-process-setup) -(eval-after-load "auto-complete" - '(add-to-list 'ac-modes 'haskell-interactive-mode)) - -(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))))) -(add-hook 'haskell-cabal-mode-hook - (lambda () (define-key haskell-cabal-mode-map (kbd "C-(") 'haskell-compile))) - - - -(add-hook 'haskell-interactive-mode-hook - (lambda () - (define-key haskell-interactive-mode-map "\r" nil) - (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-return))) -(add-hook 'haskell-indentation-mode-hook (lambda () (define-key haskell-indentation-mode-map "\r" nil))) - - - -(add-hook 'haskell-interactive-mode-hook - (lambda () - (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-newline-indent))) - - #+end_src - -#+RESULTS: -| (lambda nil (define-key haskell-interactive-mode-map (kbd ) (quote haskell-interactive-mode-newline-indent))) | (lambda nil (define-key haskell-interactive-mode-map \n nil) (define-key haskell-interactive-mode-map (kbd ) (quote haskell-interactive-mode-return))) | ac-haskell-process-setup | - -* isearch -#+begin_src emacs-lisp -(setq -isearch-allow-scroll t -search-ring-update t) ;; dont start an edit when going to previous search - - (defun isearch-yank-regexp (regexp) - "Pull REGEXP into search regexp." - (let ((isearch-regexp nil)) ;; Dynamic binding of global. - (isearch-yank-string regexp)) - (isearch-search-and-update)) - - (defun isearch-yank-symbol (&optional partialp backward) - "Put symbol at current point into search string. - - If PARTIALP is non-nil, find all partial matches." - (interactive "P") - - (let (from to bound sym) - (setq sym - ; this block taken directly from find-tag-default - ; we couldn't use the function because we need the internal from and to values - (when (or (progn - ;; Look at text around `point'. - (save-excursion - (skip-syntax-backward "w_") (setq from (point))) - (save-excursion - (skip-syntax-forward "w_") (setq to (point))) - (> to from)) - ;; Look between `line-beginning-position' and `point'. - (save-excursion - (and (setq bound (line-beginning-position)) - (skip-syntax-backward "^w_" bound) - (> (setq to (point)) bound) - (skip-syntax-backward "w_") - (setq from (point)))) - ;; Look between `point' and `line-end-position'. - (save-excursion - (and (setq bound (line-end-position)) - (skip-syntax-forward "^w_" bound) - (< (setq from (point)) bound) - (skip-syntax-forward "w_") - (setq to (point))))) - (buffer-substring-no-properties from to))) - (cond ((null sym) - (message "No symbol at point")) - ((null backward) - (goto-char (1+ from))) - (t - (goto-char (1- to)))) - (isearch-search) - (if partialp - (isearch-yank-string sym) - (isearch-yank-regexp - (concat "\\_<" (regexp-quote sym) "\\_>"))))) - - (defun isearch-current-symbol (&optional partialp) - "Incremental search forward with symbol under point. - - Prefixed with \\[universal-argument] will find all partial - matches." - (interactive "P") - (let ((start (point))) - (isearch-forward-regexp nil 1) - (isearch-yank-symbol partialp))) -;; todo, make this - - (defun isearch-backward-current-symbol (&optional partialp) - "Incremental search backward with symbol under point. - - Prefixed with \\[universal-argument] will find all partial - matches." - (interactive "P") - (let ((start (point))) - (isearch-backward-regexp nil 1) - (isearch-yank-symbol partialp))) - - - - ; lets look through emacs starter kit before we throw this out. - - - ; automatically wrap to the top of the buffer when isearch fails - (defadvice isearch-search (after isearch-no-fail activate) - (unless isearch-success - (ad-disable-advice 'isearch-search 'after 'isearch-no-fail) - (ad-activate 'isearch-search) - (isearch-repeat (if isearch-forward 'forward)) - (ad-enable-advice 'isearch-search 'after 'isearch-no-fail) - (ad-activate 'isearch-search))) - - ;; Activate occur easily inside isearch - (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)))))) - - -#+end_src - -* lisp / elisp mode setings -#+begin_src emacs-lisp - - (add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save) - (defun starter-kit-remove-elc-on-save () - "If you're saving an elisp file, likely the .elc is no longer valid." - (make-local-variable 'after-save-hook) - (add-hook 'after-save-hook - (lambda () - (if (file-exists-p (concat buffer-file-name "c")) - (delete-file (concat buffer-file-name "c")))))) - - - (defun emacs-lisp-mode-defaults () - ;; checkdoc has an annoying feature that wants a header and footer - ;; in every elisp buffer as if they all were packages - ;; todo, see if there is a way - ;; to make checkdoc usable instead of just disabling it as I do here - (if (boundp 'flycheck-checkers) - (setq flycheck-checkers (remove 'emacs-lisp-checkdoc flycheck-checkers))) - (eldoc-mode 1)) - (add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-defaults) - - (define-key lisp-mode-map (kbd "") 'backward-up-list) - (define-key lisp-mode-map (kbd "") 'down-list) - (define-key emacs-lisp-mode-map (kbd "") 'backward-up-list) - (define-key emacs-lisp-mode-map (kbd "") 'down-list) - (define-key emacs-lisp-mode-map (kbd "") 'find-function-at-point) - - ;; interactive modes don't need whitespace checks - (defun interactive-lisp-coding-defaults () - (whitespace-mode -1)) - (setq prelude-interactive-lisp-coding-hook 'prelude-interactive-lisp-coding-defaults) - - - ;; ielm is an interactive Emacs Lisp shell - (defun ielm-mode-defaults () - (run-hooks 'prelude-interactive-lisp-coding-hook) - (turn-on-eldoc-mode)) - (add-hook 'ielm-mode-hook 'ielm-mode-defaults) - -#+end_src - - -* java eclim - -based on https://github.com/senny/emacs-eclim - - -eclim: eclipse completion, searching, validation, etc inside emacs -install -#+begin_src sh :tangle no -cd ~/opt -git clone git://github.com/ervandew/eclim.git -cd eclim -pi ant -ant -Declipse.home=/a/opt/eclipse -#+end_src - - -currently makes emacs hang a bunch. dunno why. just using eclipse instead -#+begin_src emacs-lisp :tangle no -(require 'eclim) -(global-eclim-mode) - -;; just do java -(setq eclim-accepted-file-regexps - '("\\.java")) - -(custom-set-variables - '(eclim-eclipse-dirs '("/a/opt/eclipse")) - '(eclim-executable "/a/opt/eclipse/eclim")) - -(setq help-at-pt-display-when-idle t) -(setq help-at-pt-timer-delay 0.1) -(help-at-pt-set-timer) - -;; dunno if this line is needed -(require 'eclimd) -(setq eclimd-default-workspace "/a/bin/eclipse-workspace") - -;;add the emacs-eclim source -(require 'ac-emacs-eclim-source) -(add-hook 'java-mode-hook 'ac-emacs-eclim-java-setup) - -#+end_src - -#+RESULTS: -| ac-emacs-eclim-java-setup | - -* mediawiki -#+begin_src emacs-lisp - -(eval-after-load "mediawiki" - '(progn - (remove-hook 'outline-minor-mode-hook 'mediawiki-outline-magic-keys) - (add-hook 'mediawiki-mode-hook - (lambda () (define-key mediawiki-mode-map (kbd "C-(") 'mediawiki-save-reload))) - - ;; mediawiki mode has a bug that it will claim an edit conflict unless you reload after saving. - ;; I also like to save with no edit summary for previewing on my local mw instance - (defun mediawiki-save-reload () - (interactive) - (and (mediawiki-save "") (mediawiki-reload))))) -#+end_src -* modes with little configuration needed - #+begin_src emacs-lisp -;; busted: - ;;(require 'csv-mode) -;;(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode)) - -(require 'outshine) -(add-hook 'outline-minor-mode-hook 'outshine-hook-function) -(add-hook 'emacs-lisp-mode-hook 'outline-minor-mode) -(add-hook 'sh-mode-hook 'outline-minor-mode) - - - -(setq org-caldav-url "https://cal.iankelling.org" -org-caldav-calendar-id "ian" -org-caldav-inbox "/p/cal.org") -;;(org-caldav-sync) - - -;;(require 'dtrt-indent) -;;(setq dtrt-indent-mode t) - -(setq css-indent-offset 2) - -(load-file "/a/h/iank-mod.el") - -;; from when i was running my own patches -;;(add-to-list 'load-path "/a/opt/ws-butler") - -(require 'ws-butler) -;; todo: I think this is broken, it keeps collapsing the last line -;; for empty messages. - -;; the main problem is when it deletes the blank line at the end -;; of a message with an empty body. but I might also -;; be pasting whitespace significant things in here, so -;; just don't do anything. -;; todo: propose this upstream -(add-to-list 'ws-butler-global-exempt-modes 'message-mode) - -(ws-butler-global-mode) - - - -(require 'nginx-mode) -;;The mode should automatically activate for files called nginx.conf and files under /etc/nginx - if not, you can add something like this to your init file: -;;(add-to-list 'auto-mode-alist '("/etc/nginx/sites-available/.*" . nginx-mode)) - -;; todo, put this on a hook with prog mode -;;(highlight-indentation-mode 1) - -(add-hook 'auto-revert-tail-mode-hook - (lambda () - (when (string= - buffer-file-name - "/var/log/cloudman/development/cm-service.log") - (setq-local prev-auto-revert-max 0) - ;; set buffer-local hook - (add-hook 'after-revert-hook 'tail-colorize nil t)))) -(defun tail-colorize () - (ansi-color-apply-on-region prev-auto-revert-max (point-max)) - (setq-local prev-auto-revert-max (point-max))) - - -;; gnu global -(require 'ggtags) -(add-hook 'c-mode-common-hook - (lambda () (ggtags-mode 1) - (setq c-label-minimum-indentation 0))) - -;; specific to my unusual keybind setup, you may want to -;; pick different keys -(define-key ggtags-mode-map (kbd "C-M-o") 'ggtags-find-tag-dwim) -(define-key ggtags-mode-map (kbd "C-M-m") 'ggtags-grep) - -(defun gtags-update-single(filename) - "Update Gtags database for changes in a single file" - (interactive) - (start-process "update-gtags" "update-gtags" "bash" "-c" (concat "cd " ggtags-project-root " ; gtags --single-update " filename ))) - -(defun gtags-update-current-file() - (interactive) - (let ((rel-filename (replace-regexp-in-string - ggtags-project-root "." - (buffer-file-name (current-buffer))))) - (gtags-update-single rel-filename))) - -(defun gtags-update-hook() - "Update GTAGS file incrementally upon saving a file" - (when (and ggtags-mode ggtags-project-root) - (gtags-update-current-file))) - -(add-hook 'after-save-hook 'gtags-update-hook) - -;; i'd like to make some elisp which modifies a keymap to remove -;; all binds which don't match a predicate. -;; I tried setting a keymap to a new keymap, -;; but that didn't register as functional. -;; so I'd need to modify the list in place. - -(require 'magit) - - -;; colorize hex colors: use rainbow mode - - -;; message mode prompted me on first message. -;; a function which describes options then sets this -;; the other options were to use smtp directly or pass to another mail client -;; here we use the standard sendmail interface, which I use postfix for -(setq send-mail-function (quote sendmail-send-it)) - -(require 'spray) -(global-set-key (kbd "C-M-w") 'spray-mode) -;; remember, h/l = move. f/s = faster/slower, space = pause, all others quit - -;; delete active selection with self-insert commands -(delete-selection-mode t) - -;; Transparently open compressed files -(auto-compression-mode t) - -;; Highlight matching parenthesesq when the pointq is on them. -;; not needed since smart paren mode? -;; (show-paren-mode 1) - - -;; not documented, but looking at the source, I find this -;; stops me from being asked what command on every C-c-c -;; when doing a latex document. -(setq TeX-command-force "LaTeX") - -;; dot mode, repeats last action -(require 'dot-mode) -(add-hook 'find-file-hooks 'dot-mode-on) - - -;; clean up obsolete buffers automatically at midnight -(require 'midnight) - - -;; disabled because it takes 400ms on startup -;; ;; emacs regexes are too limited. -;; (require 'foreign-regexp) -;; ;; perl is most powerful, but javascript is pretty close and -;; ;; I'd rather know javascript stuff than perl -;; (custom-set-variables -;; '(foreign-regexp/regexp-type 'javascript) ;; Choose by your preference. -;; '(reb-re-syntax 'foreign-regexp)) ;; Tell re-builder to use foreign regexp. -;; ;; it would be nice to add documentation to do this for more commands to that package -;; ;; disabled because it's too slow. but I'd still m-x it for advanced replacements -;; ;;(define-key global-map [remap isearch-forward-regexp] 'foreign-regexp/isearch-forward) - - -;; saner regex syntax -(require 're-builder) -(setq reb-re-syntax 'string) - - -;; use shift + arrow keys to switch between visible buffers -;; todo, set these keys to something else -(require 'windmove) -(windmove-default-keybindings) - - -;; show the name of the current function definition in the modeline -(require 'which-func) -(setq which-func-modes t) -(which-function-mode 1) - - -;; enable winner-mode to manage window configurations -(winner-mode +1) - -;; meaningful names for buffers with the same name -(require 'uniquify) -(setq uniquify-buffer-name-style 'forward - uniquify-separator "/" - ;; for sdx work. until I figure out a better way. - ;; maybe something like projectile can do it, - ;; or hacking around the status bar - uniquify-min-dir-content 2 - uniquify-after-kill-buffer-p t ; rename after killing uniquified - uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers - - -;; makefiles require tabs -;; todo: find a makefile indent function that works, -;; best I could find is this one which means don't indent at all -;; -(add-hook 'makefile-mode-hook - (lambda () - (setq indent-tabs-mode t) - (setq indent-line-function (lambda () 'no-indent)))) - - -;; todo, turn on auto-fill just for txt files -;;(add-hook 'text-mode-hook 'turn-on-auto-fill) -(add-hook 'text-mode-hook 'turn-on-flyspell) - - -;; auto indent shell script comments -(setq sh-indent-comment t) - -;; random extra highlights -(require 'volatile-highlights) -(volatile-highlights-mode t) - - -;; make help buffers smaller when it makes sense -(temp-buffer-resize-mode 1) - - -(require 'info+) -;; based on suggestions in info+.el, I also installed misc-fns, strings, and thingatpt+ -;; remove some bad keybinds from info+ -(define-key Info-mode-map [mouse-4] nil) -(define-key Info-mode-map [mouse-5] nil) - - -(require 'smooth-scroll) -;; long gnus summary buffers lags too much with this, -;; but I like it enough to leave it enabled by default -;; and crank up the step size to be faster -;; and it doesn't have a way to enable it only for certain modes etc. -;; todo sometime, make it work for certain modes only -(smooth-scroll-mode t) -;; its too slow with the default of 2 -(setq smooth-scroll/vscroll-step-size 7) -;; sublimity doesn't work as good going fast by default -;; smooth-scrolling.el, does not do smooth scrolling. its about cursor location - - -(setq sh-here-document-word "'EOF'") - -(setq tramp-default-method "ssh") - #+end_src -* misc general settings - -#+begin_src emacs-lisp -;; https://www.emacswiki.org/emacs/FillParagraph -;; make list items start paragraphs. -(setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ") - -(setq sh-basic-offset 2) -(setq vc-follow-symlinks t) - -;; give us a shell to start instead of scratch -;;(setq initial-buffer-choice (lambda () (new-shell))) - -;; disable this nasty function, as I always use a gui -(defun suspend-frame() (interactive)) - -;; Seed the random-number generator -(random t) - -;; easier to remember than keybinds -(defalias 'scrypt 'mml-secure-message-encrypt-pgpmime) -(defalias 'sign 'mml-secure-message-sign-pgpmime) -(defun encrypt () - (interactive) - (mml-secure-message-encrypt-pgpmime 'dontsign)) - -;; don't highlight the region. -(set-face-background 'region nil) - -;; this fixes save error for python example code -(define-coding-system-alias 'UTF-8 'utf-8) - -;; i don't use frame titles, but if I ever do -;; this starter kit setting is probably good -(if window-system (setq frame-title-format '(buffer-file-name "%f" ("%b")))) - - -;;(prefer-coding-system 'utf-8-unix) - -;; remove ugly 3d box feature -(set-face-attribute 'mode-line nil :box nil) - -(add-to-list 'default-frame-alist - '(font . "DejaVu Sans Mono-11")) -; the default will jump 2 sizes. -(setq text-scale-mode-step 1.1) -(setq font-lock-maximum-decoration t - inhibit-startup-message t - transient-mark-mode t - delete-by-moving-to-trash t - shift-select-mode nil - truncate-partial-width-windows nil - uniquify-buffer-name-style 'forward - oddmuse-directory "~/.emacs.d/oddmuse" - echo-keystrokes 0.1 - mark-ring-max 160 - sort-fold-case t ; case insensitive line sorting - global-mark-ring-max 1000 - ;; the visible bell seems to lag the ui - ;;visible-bell t - ;; turn off audible bell - ;; https://www.emacswiki.org/emacs/AlarmBell - ring-bell-function 'ignore - case-replace nil - revert-without-query '(".*") - ;; don't pause display code on input. - ;; smoother display performance at slight cost of input performance - redisplay-dont-pause t - font-lock-maximum-decoration t) ; probably default and not necesary - - -(setq-default indent-tabs-mode nil ;; don't use tabs to indent - cursor-type 'box - fill-column 72 - - ;; wrap at word boundaries instead of mid-word - word-wrap t - imenu-auto-rescan t - indicate-empty-lines t) ; mark end of buffer - - -(blink-cursor-mode '(-4)) -(menu-bar-mode -1) -(tool-bar-mode -1) - - -;; enable various commands -(put 'narrow-to-region 'disabled nil) -(put 'narrow-to-page 'disabled nil) -(put 'narrow-to-defun 'disabled nil) -(put 'upcase-region 'disabled nil) -(put 'downcase-region 'disabled nil) -(put 'scroll-left 'disabled nil) -;; these from graphene, haven't read about them yet -(put 'ido-complete 'disabled nil) -(put 'ido-exit-minibuffer 'disabled nil) -(put 'dired-find-alternate-file 'disabled nil) -(put 'autopair-newline 'disabled nil) - - - -;;disable and minimize various prompts/messages -(fset 'yes-or-no-p 'y-or-n-p) -(setq confirm-nonexistent-file-or-buffer nil - inhibit-startup-message t - inhibit-startup-echo-area-message t - inhibit-startup-screen t - compilation-read-command nil ;; just don't compile with unsafe file local vars - kill-buffer-query-functions (remq 'process-kill-buffer-query-function - kill-buffer-query-functions)) - - -;; exit without bothering me -;; http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway/2708042#2708042 -(add-hook 'comint-exec-hook - (lambda () (set-process-query-on-exit-flag (get-buffer-process (current-buffer)) nil))) -;; based on save-buffers-kill-emacs help string, don't ask about clients when exiting -;; apparently this would need to be in some later hook. dunno where is best, but this works -(defadvice save-buffers-kill-emacs (before no-client-prompt-advice activate) - (setq kill-emacs-query-functions (delq 'server-kill-emacs-query-function kill-emacs-query-functions))) - - - -;; (custom-set-faces -;; ;; setting header-line-format to " " as a hack for a top margin the oly thning I could find to do a top margin -;; '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil)))) -;; ;; don't highlight the region -;; '(region ((t nil)))) -(setq-default header-line-format " ") - - -(setq initial-scratch-message nil) - #+end_src - - -vertical margin background. -google turned up: http://lists.gnu.org/archive/html/help-gnu-emacs/2014-03/msg00544.html -the xresource doesn't work for me, probably an xmonad thing. - -figured out I needed to customize the header line face. To find the face, M-x list-faces-display or just google / search -info, -then M-x customize-face -header-line -unchecked some stuff so that it inherits from default. - -* misc function definitions -#+begin_src emacs-lisp - - -(defun fill-buffer () - (interactive) - (save-mark-and-excursion - (beginning-of-buffer) - (while (= (forward-line) 0) - (fill-paragraph)))) - - -(defun next-backup-dir () -"In a directory listing from rsync -n, -Go to the next directory based on where the cursor is." - (interactive) - (let* ((start-col (current-column)) - (end-col (progn (skip-chars-forward "^/\n") (current-column))) - (dir (progn - (beginning-of-line 1) - (buffer-substring-no-properties (point) (+ (point) end-col))))) - (message dir) - (forward-line 1) - (while (and (not (eobp)) - (string= dir (buffer-substring-no-properties (point) (+ (point) end-col)))) - (forward-line 1)) - (forward-char-same-line start-col))) -;; copy paste this for fast keybind -;;(local-set-key (kbd "")) - - -(defun goto-buffer-or-find-file (file-name) - "If buffer is with FILE-NAME exists, go to it, else open the file using full path." - (interactive) - (let ((b (get-buffer (file-name-nondirectory file-name)))) - (if b - (switch-to-buffer b) - (find-file file-name)))) - - - - -;; todo, i think this is broken. perhaps the last goto-char is not accounting for buffer or something -(defun unpop-global-mark () - "Unpop off global mark ring. Does nothing if mark ring is empty." - (interactive) - (when global-mark-ring - (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring)) - (let ((lm (car (last global-mark-ring)))) - (set-marker (mark-marker) (marker-position lm) (marker-buffer lm))) - (when (null (mark t)) (ding)) - (setq global-mark-ring (nbutlast global-mark-ring)) - (goto-char (marker-position (mark-marker))))) - -(defun indent-buffer () - "Indents the entire buffer." - (interactive) - (cond ((derived-mode-p 'org-mode) - (org-indent-region (point-min) (point-max))) - ((derived-mode-p 'python-mode) - (py-autopep8)) - (t - (indent-region (point-min) (point-max))))) - - -;; TODO doesn't work with uniquify -(defun rename-file-and-buffer () - "Renames current buffer and file it is visiting." - (interactive) - (let ((name (buffer-name)) - (filename (buffer-file-name))) - (if (not (and filename (file-exists-p filename))) - (message "Buffer '%s' is not visiting a file!" name) - (let ((new-name (read-file-name "New name: " filename))) - (cond ((get-buffer new-name) - (message "A buffer named '%s' already exists!" new-name)) - (t - (rename-file name new-name 1) - (rename-buffer new-name) - (set-visited-file-name new-name) - (set-buffer-modified-p nil))))))) - - - -(defun sudo-edit (&optional arg) - (interactive "P") - (if (or arg (not buffer-file-name)) - (find-file (concat "/sudo::" (ido-read-file-name "File: "))) - (find-alternate-file (concat "/sudo::" buffer-file-name)))) - - - -(defun backward-symbol (arg) - (interactive "p") - (forward-symbol (- arg))) - -#+end_src - -* mode line -#+begin_src emacs-lisp -;; make window title be the buffer name -(setq frame-title-format "%b") - - ; ----------------------------- - ; fixing up the mode line - ; modified from mastering emacs blog - ; ---------------------------- - - (defvar mode-line-cleaner-alist - `((auto-complete-mode . "") - (yas/minor-mode . "") - (paredit-mode . "") - (auto-fill-function . "") - (eldoc-mode . "") - (abbrev-mode . "") - (flyspell-mode . "") - (glasses-mode . "") - (dot-mode . "") - (yas-global-mode . "") - (yas-minor-mode . "") - (undo-tree-mode . "") - (volatile-highlights-mode . "") - (highlight-symbol-mode . "") - ;; Major modes - (lisp-interaction-mode . "λ") - (hi-lock-mode . "") - (python-mode . "Py") - (emacs-lisp-mode . "EL") - (nxhtml-mode . "nx")) - "Alist for `clean-mode-line'. - - When you add a new element to the alist, keep in mind that you - must pass the correct minor/major mode symbol and a string you - want to use in the modeline *in lieu of* the original.") - - - (defun clean-mode-line () - (interactive) - (loop for cleaner in mode-line-cleaner-alist - do (let* ((mode (car cleaner)) - (mode-str (cdr cleaner)) - (old-mode-str (cdr (assq mode minor-mode-alist)))) - (when old-mode-str - (setcar old-mode-str mode-str)) - ;; major mode - (when (eq mode major-mode) - (setq mode-name mode-str))))) - -; disabled -; (add-hook 'after-change-major-mode-hook 'clean-mode-line) - - - ;;; alias the new `flymake-report-status-slim' to - ;;; `flymake-report-status' - (defalias 'flymake-report-status 'flymake-report-status-slim) - (defun flymake-report-status-slim (e-w &optional status) - "Show \"slim\" flymake status in mode line." - (when e-w - (setq flymake-mode-line-e-w e-w)) - (when status - (setq flymake-mode-line-status status)) - (let* ((mode-line " Φ")) - (when (> (length flymake-mode-line-e-w) 0) - (setq mode-line (concat mode-line ":" flymake-mode-line-e-w))) - (setq mode-line (concat mode-line flymake-mode-line-status)) - (setq flymake-mode-line mode-line) - (force-mode-line-update))) - - -(defun my-after-change-major-mode-hook () - (setq mode-line-mule-info nil - minor-mode-alist nil - mode-line-position nil)) ; todo, make only flymake status show up - -(add-hook 'after-change-major-mode-hook 'my-after-change-major-mode-hook) -#+end_src - -* mouse related -** settings -#+begin_src emacs-lisp - (setq focus-follows-mouse t - mouse-autoselect-window t - xterm-mouse-mode t) -#+end_src -** move-mouse-to-point -todo, this is buggy with multiple windows open. -#+begin_src emacs-lisp -(defun move-mouse-to-point () - (interactive) - (let* ((pos (posn-col-row (posn-at-point))) - (x (+ (car pos) 2)) ; no idea why this is off by 1-2 - (y (cdr pos))) - (set-mouse-position (selected-frame) x y))) -#+end_src -** cursor highlight -disabled until fixed -#+begin_src emacs-lisp :tangle no - (defun mouse-follow-cursor () - ;(if (not (equal this-command last-command)) (print this-command)) -;debug - ; (print this-command) - (when (and this-command (not (string= this-command "show-pointer"))) - (let* ((pos (posn-col-row (posn-at-point))) - (x (1+ (car pos))) ; no idea why this is off by 1 - (y (cdr pos))) - (setq ignore-mouse-visibility t) - (set-mouse-position (selected-frame) x y)) - ;(sleep-for 0 100) - (frame-make-pointer-invisible))) - - ; (when this-command - ; (if (string= this-command "show-pointer") - ; (frame-make-pointer-visible) - ;)) - - - - (defun show-pointer () - (interactive) - (if ignore-mouse-visibility - (setq ignore-mouse-visibility nil) -; (print "visible") - (frame-make-pointer-visible))) - - (setq ignore-mouse-visibility t) -; disabled - ; (global-set-key (kbd "") 'show-pointer) - - ; (add-hook 'post-command-hook 'mouse-follow-cursor t) - - - ; status. working, except that all scroll wheel actions send a mouse-movement command before doing their actual command, which makes the pointer flicker. - ; this is just an artifact of xbindkeys. when i do my own mouse chip, it will fix this. - -; we could set track-mouse to nil, then do the command, then set it back. i like that idea a bit better. - ; we could do the same thing in the other case of ignore-mouse-visibility. - - ; there are also other issues, it doesn't work with changing buffers on a split screen. - ; i think a good idea along with this would be for the cursor to follow the mouse all the time. - ; i have done code for that in my mouse 1 function, - ; i just need to read it again and try it out. - - - - - ; this does not take care of scrolling, - ; a post-command hook function below does, - ; but it breaks when the frame is split. - ; the bug is specifically in mouse-pixel-position - ; todo, fix this eventually - (defun mouse-highlight-event (event) - (interactive "e") - (when (or (not event) (mouse-movement-p event) - (memq (car-safe event) '(switch-frame select-window))) - (let ((pos (posn-point (event-end event)))) - (if (eq (overlay-buffer mouse-hi-ov) (current-buffer)) - (move-overlay mouse-hi-ov pos (1+ pos)) - (delete-overlay mouse-hi-ov) - (setq mouse-hi-ov - (make-overlay pos (1+ pos))) - (overlay-put mouse-hi-ov - 'insert-in-front-hooks (list 'mouse-hi-modification)) - (overlay-put mouse-hi-ov 'priority 1001)) - (cond ((save-excursion (goto-char pos) (eolp)) - (overlay-put mouse-hi-ov 'face nil) - (overlay-put mouse-hi-ov 'before-string - (propertize - " " - 'cursor t - 'face 'mouse-cursor-face))) - (t - (overlay-put mouse-hi-ov 'face 'mouse-cursor-face) - (overlay-put mouse-hi-ov 'before-string nil)))))) - - - ; overlay changed hook function - (defun mouse-hi-modification (ov timing beginning end &optional length) - "Make an overlay of length 1 not expand when text is inserted at the front." - (when timing - (let ((start (overlay-start ov))) - (move-overlay ov start (1+ start))))) - - - - - (defun mouse-hi-command-hook () - ; not sure if I need to deal with case of a nil mouse position in some unforseen situation. - (let ((x-y (cdr (mouse-pixel-position)))) - (when (wholenump (car x-y)) - (let ((pos (posn-point (posn-at-x-y (car x-y) (cdr x-y) nil t)))) - (when pos - (if (eq (overlay-buffer mouse-hi-ov) (current-buffer)) - (move-overlay mouse-hi-ov pos (1+ pos)) - (delete-overlay mouse-hi-ov) - (setq mouse-hi-ov - (make-overlay pos (1+ pos))) - - (overlay-put mouse-hi-ov 'priority 1001)) - (cond ((save-excursion (goto-char pos) (eolp)) - - (overlay-put mouse-hi-ov 'face nil) - (overlay-put mouse-hi-ov 'before-string - (propertize - " " - 'cursor t - 'face 'mouse-cursor-face))) - (t - (overlay-put mouse-hi-ov 'face 'mouse-cursor-face) - (overlay-put mouse-hi-ov 'before-string nil)))))))) - ; (pcase-let ((`(,_ ,x . ,y) (mouse-pixel-position))) - ; (posn-point (posn-at-x-y x y))))) - ; equivalent of above to find pos. todo, learn about the above syntax - - (setq mouse-hi-ov (make-overlay 1 1)) - (delete-overlay mouse-hi-ov) - ; initialized overlay - ; temporarily set to nil instead of t because it is broken and - ; also has a bug that makes emacs not remember the column when - ; doing up and down movements. - ; it also messes up yas/insert-snippet, dunno why. -; i should test out whether it is something in the post-command hook -; (setq track-mouse t) - ;(add-hook 'post-command-hook 'mouse-hi-command-hook) - - ;(mouse-hi-command-hook) - ;(setq debug-on-error nil) - - #+end_src -** mouse 1 drag func - -disabled as it breaks in newer emacs versions with this error, when -clicking on info links - -"and: Symbol's function definition is void: mouse--remap-link-click-p" - -#+begin_src emacs-lisp :tangle no - - ; Copied from mouse.el and modified. - ; my modifications have comments prefaced by "ian" - (defun mouse-drag-track (start-event &optional - do-mouse-drag-region-post-process) - "Track mouse drags by highlighting area between point and cursor. - The region will be defined with mark and point. - DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by - `mouse-drag-region'." - (mouse-minibuffer-check start-event) - (setq mouse-selection-click-count-buffer (current-buffer)) - ; ian. removed as unneeded since I don't use TMM - ;(deactivate-mark) - (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541). - (original-window (selected-window)) - ;; We've recorded what we needed from the current buffer and - ;; window, now let's jump to the place of the event, where things - ;; are happening. - (_ (mouse-set-point start-event)) - (echo-keystrokes 0) - (start-posn (event-start start-event)) - (start-point (posn-point start-posn)) - (start-window (posn-window start-posn)) - (start-window-start (window-start start-window)) - (start-hscroll (window-hscroll start-window)) - (bounds (window-edges start-window)) - (make-cursor-line-fully-visible nil) - (top (nth 1 bounds)) - (bottom (if (window-minibuffer-p start-window) - (nth 3 bounds) - ;; Don't count the mode line. - (1- (nth 3 bounds)))) - (on-link (and mouse-1-click-follows-link - ;; Use start-point before the intangibility - ;; treatment, in case we click on a link inside - ;; intangible text. - (mouse-on-link-p start-posn))) - (click-count (1- (event-click-count start-event))) - (remap-double-click (and on-link - (eq mouse-1-click-follows-link 'double) - (= click-count 1))) - ;; Suppress automatic hscrolling, because that is a nuisance - ;; when setting point near the right fringe (but see below). - (auto-hscroll-mode-saved auto-hscroll-mode) - (auto-hscroll-mode nil) - moved-off-start event end end-point) - - (setq mouse-selection-click-count click-count) - ;; In case the down click is in the middle of some intangible text, - ;; use the end of that text, and put it in START-POINT. - (if (< (point) start-point) - (goto-char start-point)) - (setq start-point (point)) - (if remap-double-click - (setq click-count 0)) - - ;; Activate the region, using `mouse-start-end' to determine where - ;; to put point and mark (e.g., double-click will select a word). - (setq transient-mark-mode - (if (eq transient-mark-mode 'lambda) - '(only) - (cons 'only transient-mark-mode))) - (delete-overlay mouse-hi-ov) ; ian, added this. - - (let ((range (mouse-start-end start-point start-point click-count))) - (push-mark (nth 0 range) t t) - (goto-char (nth 1 range))) - - ;; Track the mouse until we get a non-movement event. - (track-mouse - (while (progn - (setq event (read-event)) - (or (mouse-movement-p event) - (memq (car-safe event) '(switch-frame select-window)))) - (unless (memq (car-safe event) '(switch-frame select-window)) - ;; Automatic hscrolling did not occur during the call to - ;; `read-event'; but if the user subsequently drags the - ;; mouse, go ahead and hscroll. - (let ((auto-hscroll-mode auto-hscroll-mode-saved)) - (redisplay)) - (setq end (event-end event) - end-point (posn-point end)) - ;; Note whether the mouse has left the starting position. - (unless (eq end-point start-point) - (setq moved-off-start t)) - (if (and (eq (posn-window end) start-window) - (integer-or-marker-p end-point)) - (mouse--drag-set-mark-and-point start-point - end-point click-count) - (let ((mouse-row (cdr (cdr (mouse-position))))) - (cond - ((null mouse-row)) - ((< mouse-row top) - (mouse-scroll-subr start-window (- mouse-row top) - nil start-point)) - ((>= mouse-row bottom) - (mouse-scroll-subr start-window (1+ (- mouse-row bottom)) - nil start-point)))))) - (visible-mark-move-overlays))) ; ian, added this - - - ;; Handle the terminating event if possible. - (when (consp event) - ;; Ensure that point is on the end of the last event. - (when (and (setq end-point (posn-point (event-end event))) - (eq (posn-window end) start-window) - (integer-or-marker-p end-point) - (/= start-point end-point)) - (mouse--drag-set-mark-and-point start-point - end-point click-count)) - - ;; Find its binding. - (let* ((fun (key-binding (vector (car event)))) - (do-multi-click (and (> (event-click-count event) 0) - (functionp fun) - (not (memq fun '(mouse-set-point - mouse-set-region)))))) - (if (and (/= (mark) (point)) - (not do-multi-click)) - - ;; If point has moved, finish the drag. - (let* (last-command this-command) - (and mouse-drag-copy-region - do-mouse-drag-region-post-process - (let (deactivate-mark) - (copy-region-as-kill (mark) (point))))) - - ;; Otherwise, run binding of terminating up-event. - (if do-multi-click - (goto-char start-point) - (deactivate-mark) - (unless moved-off-start - ;; ian: poping the mark is a poor choice of behavior. - ;; we should delete the mark instead. - ;; The first way I found to delete it is to pop it first - (pop-mark) - (setq mark-ring (nbutlast mark-ring)))) - - (when (and (functionp fun) - (= start-hscroll (window-hscroll start-window)) - ;; Don't run the up-event handler if the window - ;; start changed in a redisplay after the - ;; mouse-set-point for the down-mouse event at - ;; the beginning of this function. When the - ;; window start has changed, the up-mouse event - ;; contains a different position due to the new - ;; window contents, and point is set again. - (or end-point - (= (window-start start-window) - start-window-start))) - - (when (and on-link - (= start-point (point)) - (mouse--remap-link-click-p start-event event)) - - ;; If we rebind to mouse-2, reselect previous selected - ;; window, so that the mouse-2 event runs in the same - ;; situation as if user had clicked it directly. Fixes - ;; the bug reported by juri@jurta.org on 2005-12-27. - (if (or (vectorp on-link) (stringp on-link)) - (setq event (aref on-link 0)) - (select-window original-window) - (setcar event 'mouse-2) - ;; If this mouse click has never been done by the - ;; user, it doesn't have the necessary property to be - ;; interpreted correctly. - (put 'mouse-2 'event-kind 'mouse-click))) - (push event unread-command-events))))))) -#+end_src - -** mouse 3 -#+begin_src emacs-lisp :tangle no - - - (defun mouse3-range-mark (start click click-count) - (let* ((range (mouse-start-end start click click-count)) - (beg (nth 0 range)) - (end (nth 1 range))) - (cond ((<= click start) - (set-mark beg)) - (t - (set-mark end)))) - (visible-mark-move-overlays)) - - - (defun mouse3-set-mark (event) - "in development" - (interactive "e") - (mouse-minibuffer-check event) - ;; Use event-end in case called from mouse-drag-region. - ;; If EVENT is a click, event-end and event-start give same value. - (set-mark (posn-point (event-end event))) - (visible-mark-move-overlays)) - - - (defun mouse3-func (start-event) - "in development" - (interactive "e") - - (run-hooks 'mouse-leave-buffer-hook) - - (mouse-minibuffer-check start-event) - (setq mouse-selection-click-count-buffer (current-buffer)) - (push-mark (posn-point (event-end start-event))) - - (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541). - (original-window (selected-window)) - ;; We've recorded what we needed from the current buffer and - ;; window, now let's jump to the place of the event, where things - ;; are happening. - ;(_ (mouse-set-point start-event)) ; ian: commented, replaced - (echo-keystrokes 0) - (start-posn (event-start start-event)) - (start-point (posn-point start-posn)) - (start-window (posn-window start-posn)) - (start-window-start (window-start start-window)) - (start-hscroll (window-hscroll start-window)) - (bounds (window-edges start-window)) - (make-cursor-line-fully-visible nil) - (top (nth 1 bounds)) - (bottom (if (window-minibuffer-p start-window) - (nth 3 bounds) - ;; Don't count the mode line. - (1- (nth 3 bounds)))) - (click-count (1- (event-click-count start-event))) - ;; Suppress automatic hscrolling, because that is a nuisance - ;; when setting point near the right fringe (but see below). - (auto-hscroll-mode-saved auto-hscroll-mode) - (auto-hscroll-mode nil) - moved-off-start event end end-point) - - (setq mouse-selection-click-count click-count) - ;; In case the down click is in the middle of some intangible text, - ;; use the end of that text, and put it in START-POINT. - (if (< (mark) start-point) ; ian: change point to the mark - (set-mark start-point) - (visible-mark-move-overlays)) - (setq start-point (mark)) - - (delete-overlay mouse-hi-ov) ; ian, added this. - - ;; Activate the region, using `mouse-start-end' to determine where - ;; to put point and mark (e.g., double-click will select a word). - (let ((range (mouse-start-end start-point start-point click-count))) - (set-mark (nth 1 range))) - (visible-mark-move-overlays) - - - ;; Track the mouse until we get a non-movement event. - (track-mouse - - (while (progn - (setq event (read-event)) - (or (mouse-movement-p event) - (memq (car-safe event) '(switch-frame select-window)))) - (unless (memq (car-safe event) '(switch-frame select-window)) - - ;; Automatic hscrolling did not occur during the call to - ;; `read-event'; but if the user subsequently drags the - ;; mouse, go ahead and hscroll. - (let ((auto-hscroll-mode auto-hscroll-mode-saved)) - (redisplay)) - (setq end (event-end event) - end-point (posn-point end)) - ;; Note whether the mouse has left the starting position. - - (unless (eq end-point start-point) - (setq moved-off-start t)) - (if (and (eq (posn-window end) start-window) - (integer-or-marker-p end-point)) - (mouse3-range-mark start-point end-point click-count); ian, set mark - - ; do scrolling if needed - (let ((mouse-row (cdr (cdr (mouse-position))))) - (cond - ((null mouse-row)) - ((< mouse-row top) - (mouse-scroll-subr start-window (- mouse-row top) - nil start-point)) - ((>= mouse-row bottom) - (mouse-scroll-subr start-window (1+ (- mouse-row bottom)) - nil start-point)))))))) - - ;; Handle the terminating event if possible. - (when (consp event) - ;; Ensure that point is on the end of the last event. - (when (and (setq end-point (posn-point (event-end event))) - (eq (posn-window end) start-window) - (integer-or-marker-p end-point) - (/= start-point end-point)) - ;(mouse--drag-set-mark-and-point start-point ; ian, set mark - ;end-point click-count)) - (mouse3-range-mark start-point end-point click-count)); ian, set mark - - ;; Find its binding. - (let* ((fun (key-binding (vector (car event)))) - (do-multi-click (and (> (event-click-count event) 0) - (functionp fun) - (not (memq fun '(mouse3-set-mark)))))) - (if (and (/= end-point start-point) - (not do-multi-click)) - - ;; If point has moved, finish the drag. - (let* (last-command this-command) - (and mouse-drag-copy-region - do-mouse-drag-region-post-process - (let (deactivate-mark) - (copy-region-as-kill (mark) (point))))) - - ;; Otherwise, run binding of terminating up-event. - (when do-multi-click - (set-mark start-point)) ; ian, change this. why? - (visible-mark-move-overlays) - - - (when (and (functionp fun) - (= start-hscroll (window-hscroll start-window)) - ;; Don't run the up-event handler if the window - ;; start changed in a redisplay after the - ;; mouse-set-point for the down-mouse event at - ;; the beginning of this function. When the - ;; window start has changed, the up-mouse event - ;; contains a different position due to the new - ;; window contents, and point is set again. - (or end-point - (= (window-start start-window) - start-window-start))) - - (push event unread-command-events))))))) - -#+end_src - - - - - -* org mode - -#+begin_src emacs-lisp - -;; todo work on org-cycle-emulate-tab - -;; todo, this doesn't work for a non-standard keybind -;;(setq org-special-ctrl-k t) - -;; todo, generally fix org mode keys -;; todo, org-mark-element, unbdind from M-h, bind to mark defun key - -;(org-babel-do-load-languages -; 'org-babel-load-languages -; '((emacs-lisp . t) -; (sh . t))) - -;; make shell work like interactive bash shell -(setq org-babel-default-header-args:sh - '((:results . "output") (:shebang . "#!/bin/bash -l"))) - -;; my patch to output stderr -(setq org-babel-use-error-buffer nil) - - ; -;; org-mode manual suggests these, but I haven't used them. -;;(global-set-key "\C-cl" 'org-store-link) -;;(global-set-key "\C-ca" 'org-agenda) -;; this got in the way of a haskell mode command -;;(global-set-key "\C-cb" 'org-iswitchb) - - - - ;; org-src-tab-acts-natively t ; broken option. using next instead, todo fix - -(setq org-src-fontify-natively t ; make babel blocks nice - org-adapt-indentation nil - org-src-preserve-indentation t - ;; The most basic logging is to keep track of when a TODO item was finished. - org-log-done 'time - ;; use a drawer to keep the logs tidy - org-log-into-drawer t - org-extend-today-until 0 - org-startup-truncated nil - org-clock-persist t - org-clock-mode-line-total 'today - ;; global STYLE property values for completion - org-global-properties (quote (("STYLE_ALL" . "habit"))) - org-special-ctrl-a/e t ;; home and end work special in headlines - org-completion-use-ido t - org-catch-invisible-edits 'smart) - - ;; non universally recommended settings -(setq - org-default-notes-file (concat org-directory "/a/t.org") - org-agenda-files (quote ("/a/t.org")) - org-mobile-directory "/p/org-mobile" - org-mobile-inbox-for-pull "/p/from-mobile.org" - org-directory "/p") - -;; modeilne populated from (org-clock-get-clocked-time) -;; which is populated from the var org-clock-total-time -;; which is populated by a function which starts from (org-clock-get-sum-start) -;; - -(org-clock-persistence-insinuate) - - -(defun time-to-org-day (time) - (round (time-to-number-of-days - (time-subtract time (list 0 (* 3600 org-extend-today-until) 0))))) - - -(defun my-org-confirm-babel-evaluate (lang body) - (not (or (string= (buffer-file-name) "/a/t.org") - (string= (buffer-file-name) "/home/iank/.emacs.d/my-init.org") - ))) -(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate) - - -(defun org-time-stamp-with-time (arg) - (interactive "P") - ;; '(4) is the argument passed by universal prefix - (org-time-stamp (if arg arg '(4)) t)) - -(defun ian-org-work-time () - (interactive) - (save-excursion - (set-buffer "t.org") - (goto-char (org-find-entry-with-id "ian-identifier-1")) - (org-clock-in))) - -(defun ian-org-idle-time () - (interactive) - (save-excursion - (goto-char (org-find-entry-with-id "ian-identifier-2")) - (set-buffer "t.org") - (org-clock-in))) - - - -;; based on http://stackoverflow.com/questions/3758139/variable-pitch-for-org-mode-fixed-pitch-for-tables -;; keywords: proportional font, monospace - -(defun variable-pitch-on () - (variable-pitch-mode 1)) -(add-hook 'fundamental-mode-hook 'variable-pitch-on) -(add-hook 'org-mode-hook 'variable-pitch-on) -(add-hook 'text-mode-hook 'variable-pitch-on) -(defun variable-pitch-off () - (variable-pitch-mode 0)) -(add-hook 'yaml-mode-hook 'variable-pitch-off) - - -(set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family)) -(set-face-attribute 'org-code nil :family (face-attribute 'fixed-pitch :family)) -(set-face-attribute 'org-formula nil :family (face-attribute 'fixed-pitch :family)) -(set-face-attribute 'org-link nil :family (face-attribute 'fixed-pitch :family)) -(set-face-attribute 'org-block nil :family (face-attribute 'fixed-pitch :family)) -(set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family)) - - -(defun remove-org-binds () - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "C-'") nil) - (define-key org-mode-map (kbd "C-y") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "C-,") nil) - (define-key org-mode-map (kbd "C-M-m") nil) - (define-key org-mode-map (kbd "C-k") nil) - (define-key org-mode-map (kbd "C-j") nil) - (define-key org-mode-map (kbd "C-M-i") nil) - (define-key org-mode-map (kbd "C-M-t") nil) - (define-key org-mode-map (kbd "M-a") 'nil) - (define-key org-mode-map (kbd "C-a") nil) - (define-key org-mode-map (kbd "M-e") nil) - (define-key org-mode-map (kbd "C-e") nil) - (define-key org-mode-map (kbd "C-3") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map (kbd "") nil) - (define-key org-mode-map "\t" nil)) -(add-hook 'org-mode-hook 'remove-org-binds) - -#+end_src - - -* org drill - - -#+begin_src emacs-lisp :tangle no - - (setq - ;; account actual time, not just scheduled time - org-drill-adjust-intervals-for-early-and-late-repetitions-p t - - ;; still show leeches, but warn - org-drill-leech-method (quote warn) - ;; increased from default 20 - org-drill-maximum-duration 60 - ;; especially when starting, I want to drill hard - org-drill-maximum-items-per-session nil - ;; don't prompt to save buffer, auto-save will do that - org-drill-save-buffers-after-drill-sessions-p nil -;; this one deals with varying difficulty items better -;; sm2 is similar, but more simplistic - org-drill-spaced-repetition-algorithm (quote simple8) -) -#+end_src -;; todo, make the prompting text reflect this number. - ;; org-drill-failure-quality - -* os specific settings - -disabled cuz I have none yet - #+begin_src emacs-lisp :tangle no - (cond ((eq system-type 'darwin)) - ((eq system-type 'gnu/linux)) - ((eq system-type 'windows-nt)) - (t )) - #+end_src - - -* prog-mode-defaults - -#+begin_src emacs-lisp - - -(defun prog-mode-defaults () - "Default coding hook, useful with any programming language." - ;; so that I can do completion before the dialog pops up - (local-set-key (kbd "") 'auto-complete) - ;; todo, this is causing error message on loading file, prolly not working - ;;(flycheck-mode +1) - (setq ac-sources (delq 'ac-source-dictionary ac-sources)) - (highlight-symbol-mode) - (make-local-variable 'column-number-mode) - ;; this says do autofilling using newcomment.el. The "only" is a misnomer. - (set (make-local-variable 'comment-auto-fill-only-comments) t) - (column-number-mode t) - (turn-on-smartparens-mode) - - ;; prettify lambdas - (font-lock-add-keywords - nil `(("(\\(lambda\\>\\)" - (0 (progn (compose-region (match-beginning 1) (match-end 1) - ,(make-char 'greek-iso8859-7 107)) - nil)))))) -(add-hook 'prog-mode-hook 'prog-mode-defaults) - -;; enable flyspell in prog mode. text mode is handled -(add-hook 'prog-mode-hook 'flyspell-prog-mode) - - - -#+end_src - -** yank auto-indent -#+begin_src emacs-lisp -;; automatically indenting yanked text if in programming-modes -(defvar yank-indent-modes - '(LaTeX-mode TeX-mode) - "Modes in which to indent regions that are yanked (or yank-popped). -Only modes that don't derive from `prog-mode' should be listed here.") - -(defvar yank-indent-blacklisted-modes - '(python-mode slim-mode haml-mode) - "Modes for which auto-indenting is suppressed.") - -(defvar yank-advised-indent-threshold 2000 - "Threshold (# chars) over which indentation does not automatically occur.") - -(defun yank-advised-indent-function (beg end) - "Do indentation, as long as the region isn't too large." - (if (<= (- end beg) yank-advised-indent-threshold) - (indent-region beg end nil))) - -(defadvice yank (after yank-indent activate) - "If current mode is one of 'yank-indent-modes, -indent yanked text (with prefix arg don't indent)." - (if (and (not (ad-get-arg 0)) - (not (member major-mode yank-indent-blacklisted-modes)) - (or (derived-mode-p 'prog-mode) - (member major-mode yank-indent-modes))) - (let ((transient-mark-mode nil)) - (yank-advised-indent-function (region-beginning) (region-end))))) - -(defadvice yank-pop (after yank-pop-indent activate) - "If current mode is one of 'yank-indent-modes, -indent yanked text (with prefix arg don't indent)." - (if (and (not (ad-get-arg 0)) - (not (member major-mode yank-indent-blacklisted-modes)) - (or (derived-mode-p 'prog-mode) - (member major-mode yank-indent-modes))) - (let ((transient-mark-mode nil)) - (yank-advised-indent-function (region-beginning) (region-end))))) - -#+end_src - - -* shell mode - #+begin_src emacs-lisp -;; avoid stupid git crap like "warning, terminal not fully functional" -(setenv "PAGER" "cat") -;; don't store successive duplicates in comint command history -(setq comint-input-ignoredups t) - -(defun add-mode-line-dirtrack () - (add-to-list 'mode-line-buffer-identification - '(:propertize (" " default-directory " ") face dired-directory))) -(add-hook 'shell-mode-hook 'add-mode-line-dirtrack) - - -;; don't fully understand it, but it works. -;; http://www.emacswiki.org/emacs/ShellDirtrackByProcfs -(defun track-shell-directory/procfs () - (shell-dirtrack-mode 0) - (add-hook 'comint-preoutput-filter-functions - (lambda (str) - (prog1 str - (when (string-match comint-prompt-regexp str) - (cd (file-symlink-p - (format "/proc/%s/cwd" (process-id - (get-buffer-process - (current-buffer))))))))) - nil t)) -(setq comint-buffer-maximum-size 100000) -(add-to-list 'comint-output-filter-functions 'comint-truncate-buffer) -(defun new-shell () - (interactive) - (shell (generate-new-buffer-name "*shell*"))) -;; -(defun shell-wrap (prefix) -"wrap the shell function, automatically generate a new name for a prefix arg" - (interactive "P") - (if prefix - (new-shell) - (shell))) - -(add-hook 'shell-mode-hook 'track-shell-directory/procfs) -#+end_src -* smartparens -the melpa git version had a catastrophic bug I reported. -downgraded to marmalade version and everything is working fine. -#+begin_src emacs-lisp -(require 'smartparens-config) -(show-smartparens-global-mode t) - - -(defun gp/sp/pair-on-newline-and-indent (id action context) - "Open a new brace or bracket expression, with relevant newlines and indent. " - (save-excursion - (newline) - (indent-according-to-mode)) - (indent-according-to-mode)) - -;; when opening a pair, and then inserting a newline, push the closing pair to another newline -(sp-pair "{" nil :post-handlers - '(:add ((lambda (id action context) - (gp/sp/pair-on-newline-and-indent id action context)) (kbd "")))) -(sp-pair "[" nil :post-handlers - '(:add ((lambda (id action context) - (gp/sp/pair-on-newline-and-indent id action context)) (kbd "")))) - - -;; in my version, this is not a pairing. -;; not sure if it is in a future version since I reverted to marmalade -;; Don't need c-comments in strings -- they frustrate filename globs -;; (sp-pair "/*" nil :unless '(sp-in-string-p)) - -;; Don't need quotes to pair next to words -(sp-pair "\"" nil :unless '(sp-point-before-word-p sp-point-after-word-p)) -(sp-pair "'" nil :unless '(sp-point-before-word-p sp-point-after-word-p)) - - -;; todo, testout these mode specific settings from graphene. -;; Ruby-specific pairs and handlers -(require 'smartparens-ruby) - -;; Markdown -(sp-local-pair '(markdown-mode gfm-mode) "*" "*" - :unless '(sp-in-string-p) - :actions '(insert wrap)) - -;; Except in HTML -(sp-local-pair 'html-mode "\"" nil :unless '(:rem sp-point-after-word-p)) - - - #+end_src -* smex - todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings. - #+begin_src emacs-lisp -; these must be before smex-initialize - (setq - smex-save-file "~/.emacs.d/.smex-items") - - (smex-initialize) - #+end_src -* speedbar -(sr-speedbar-close) -(sr-speedbar-open) - -** todo, disabled cuz of broken package - #+begin_src emacs-lisp :tangle no -(require 'sr-speedbar) - (setq speedbar-hide-button-brackets-flag t ;; didn't notice a diff - speedbar-file-unshown-regexp "flycheck-.*" - sr-speedbar-width 40 - sr-speedbar-width-x 40 - sr-speedbar-auto-refresh nil - sr-speedbar-skip-other-window-p t - sr-speedbar-right-side nil -speedbar-hide-button-brackets-flag nil) - #+end_src -* spell correction -#+begin_src emacs-lisp - (setq - ispell-program-name "hunspell" - ispell-silently-savep t) ; don't prompt to save personal dictionary - - (require 'rw-hunspell) -#+end_src -rw-hunspell sets up hunspell dictionary automagically. - - -Rant: Hunspell SHOULD be standard. its used by firefox and openoffice and -osx. In contrast, the first few words I added to aspell dictionary were -"emacs" "customizable" and "timestamp". Hunspell already has those, -thank god. - -ispell-personal-dictionary does not document where the hunspell -dictionary goes by default, but it is ~/.hunspell_en_US for me - - -* tex -#+begin_src emacs-lisp -(setq-default TeX-PDF-mode t) ; use pdf - -; more sensible defaults based on info manual quickstart - (setq TeX-auto-save t) - (setq TeX-parse-self t) - - -#+end_src -* undo tree -#+begin_src emacs-lisp - - ;; 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 - - -#+end_src - -* visible mark mode - -these colors were better for dark theme -#+begin_src emacs-lisp :tangle no - - - -(defface visible-mark-face1 - '((((type tty) (class mono))) - (t (:background "LimeGreen"))) "") - (defface visible-mark-face2 - '((((type tty) (class mono))) - (t (:background "red4"))) "") - (defface visible-mark-forward-face1 - '((((type tty) (class mono))) - (t (:background "dark magenta"))) "") - (defface visible-mark-active - '((((type tty) (class mono))) - (t (:background "gold"))) "") - (defface mouse-cursor-face - '((((type tty) (class mono))) - (t (:background "DeepPink1"))) "") - -#+end_src - - -#+begin_src emacs-lisp - - - ;; since it is not easy to change the mark overlay priority, I change this one. - (setq show-paren-priority 999) - - - (defface visible-mark-active - '((((type tty) (class mono))) - (t (:background "magenta"))) "") - - - - (defface mouse-cursor-face - '((((type tty) (class mono))) - (t (:background "DeepPink1"))) "") - - - (require 'visible-mark) - -(setq visible-mark-faces '(visible-mark-face1 visible-mark-face2)) - (setq visible-mark-forward-faces '(visible-mark-forward-face1)) - - - ; highlight the last 2 marks - (setq visible-mark-max 2) - ; highlight 1 forward mark - (setq visible-mark-forward-max 1) - ; globally activate visible-mark-mode - (global-visible-mark-mode +1) - - -;; todo, it doesn't seem to be exposed in elisp, but it would be nice -;; if I could define overlay faces to use inverse foreground color - - -#+end_src - -#+RESULTS: -: t - - -* zrc -#+begin_src emacs-lisp -(require 'znc) -(setq erc-fill-prefix "") -(defun chirp() - (interactive) - (setq vol 50) - (when (string= (system-name) "tp") (setq vol 40)) - (start-process-shell-command "ignoreme" nil (format "mpv --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol))) -;; from https://www.emacswiki.org/emacs/ErcSound - -(defun erc-my-privmsg-sound (proc parsed) - (let* ((tgt (car (erc-response.command-args parsed))) - (privp (erc-current-nick-p tgt))) - (and - privp (chirp) - ;; We must return nil. See help for `erc-server-PRIVMSG-functions' - nil))) - -(add-hook 'erc-server-PRIVMSG-functions - 'erc-my-privmsg-sound) - -(defun erc-sound-if-not-server (match-type nickuserhost msg) - (unless (string-match "Server:[0-9]+" nickuserhost) - (chirp))) -(add-hook 'erc-text-matched-hook 'erc-sound-if-not-server) - -(erc-track-mode 1) - (setq - ;; consider invisible frames to be unseen. seems like an obvious default - erc-track-visibility 'visible - ;; switch to buffer where i've been mentioned, etc instead of oldest - erc-track-switch-direction 'importance) - -#+end_src * key binds. keep at end of file @@ -4078,12 +400,12 @@ plan to use calc. [calc edit mode, to edit the top of stack] ** single/special keys -*** tab key +*** tab isearch #+begin_src emacs-lisp (define-key isearch-mode-map (kbd "") 'isearch-query-replace) #+end_src -*** tab +*** f12 isearch-forward #+begin_src emacs-lisp ;; explained in http://stackoverflow.com/questions/7411920/how-to-bind-search-and-search-repeat-to-c-f-in-emacs @@ -5728,7 +2050,9 @@ org-edit-src-exit *** C-y] undo-tree-redo #+begin_src emacs-lisp - (global-set-key (kbd "C-y") 'undo-tree-redo) +(global-set-key (kbd "C-y") 'undo-tree-redo) +(add-hook 'org-mode-hook + (lambda () (define-key org-mode-map (kbd "C-y") nil))) #+end_src *** M-y @@ -6053,21 +2377,6 @@ dunno why but it takes doing ctrl-c twice to update this |-----------------+--------------------------------+---------------------------------+-------------------------------+--------------------------| #+END: -* 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. - -I'm using persistent registers instead of bookmarks. I dun use them -much, so the added hassle of having to set it within this file is -worth the benefit of only having one concept in my mind. -#+begin_src emacs-lisp - (dolist - (r `( - (?i (file . ,"~/.emacs.d/my-init.org")) - (?t (file . ,"/a/x.txt")) - )) - (set-register (car r) (cadr r))) -#+end_src * keybind notes common keys, which would be better off doing swaps than rebinds: @@ -6089,111 +2398,8 @@ occur command to make more accessible, ... -* misc useful functions I'd rather have in a list than burried -#+begin_src emacs-lisp :tangle no -;; these are usefull with (goto-char) -;; find named entity, other than headline -(org-find-entry-with-id "string-number-or-symbol") - -(org-find-exact-headline-in-buffer "heading" nil t) - -(byte-recompile-file (expand-file-name "~/.emacs.d/my-init.el") t 0) -(byte-recompile-directory (expand-file-name "~/.emacs.d") 0) -(byte-recompile-directory (expand-file-name "~/.emacs.d/src/haskell-mode") 0) - -;; remove any indent level which is throughout the buffer -(org-do-remove-indentation) - -#+end_src - * TESTING / DEVELOPMENT AREA -** new -#+begin_src emacs-lisp - - -#+end_src - -** key logging -this article convinced me that trying to experiment with modal editing is a waste. -http://chrisdone.com/posts/speculations-on-exclusive-editing -I want to record my emacs commands simply to find optimiaztions, like if I often do some M-x command and should bind it -to a key. - - -#+begin_src emacs-lisp :tangle no - -(setq keylog-list nil) -(setq keylog-mode nil) - -(defun keylog-save () - - ;; Check that the lock file does not exist - (when (keyfreq-file-is-unlocked) - ;; Lock the file - (keyfreq-file-claim-lock) - - ;; Check that we have the lock - (if (eq (keyfreq-file-owner) (emacs-pid)) -(unwind-protect -(progn -;; Load values and merge them with the current keyfreq-table -(keyfreq-table-load table) - -;; Write the new frequencies -(with-temp-file keyfreq-file -(prin1 (cdr (keyfreq-list table 'no-sort)) (current-buffer)))) - -;; Release the lock and reset the hash table. -(keyfreq-file-release-lock) -(clrhash table)) - ))) - -(defun my-keylogger-function () - (setq keylog-list (cons (list (current-time) current-prefix-arg this-command) keylog-list))) -(add-hook 'pre-command-hook 'my-keylogger-function) - -#+end_src - -in a lisp expression, ; \\[ throws off forward-sexp -when not in emacs lisp mode, -even with (with-syntax-table emacs-lisp-mode-syntax-table -forward-sexp) -which is found in preceding-sexp -potentially a bug, either in with-syntax-table, or -in scan-lists, which is implemented in C - - - - -why did it go to the init file? -change EDITOR to emacsclient -xserver-xorg-core=2:1.14.3-3ubuntu2 -(setq-default header-line-format nil) ; Copy mode-line -(setq-default mode-line-format nil) ; - - -#+RESULTS: -: set-food-completions - - - -useless gnus group keys: -a -c - - -(add-to-list 'load-path "~/.emacs.d/emacs/site-lisp/org") - -#+begin_src emacs-lisp - (add-hook 'org-mode-hook - (lambda () (define-key org-mode-map (kbd "C-y") nil))) - -#+end_src - - - - (defun comint-send-string (process string) "Like `process-send-string', but also does extra bookkeeping for Comint mode." (if process @@ -6205,213 +2411,3 @@ c (process-send-string process string)) -* python -todo: get smart-operator to work -todo, checkout https://github.com/python-rope/ropemacs refactoring python, -todo, try py-autopep8, autoformatter -todo, check out some python linting stuff. pychecker is one, others are in *packages* -todo, finish reading through python-mode.el functions -;; todo, figure out multi-line input in shell mode - - -usefull m-x commands: -m-x py-describe-mode: doc for mode which is extensive -m-x py-sort-imports -m-x py-guess-indent-offset: setup indent for code i didn't write - -possibly usefull commands: -found via looking through python-mode.el, quit like 1/4 through, cuz its tedious, last spot was at: -(defun py-comment-region (beg end &optional arg) -after finding py-describe-mode, it seemed to do a good job of documenting all the most important stuff - -py-switch-to-python -python-shell-completion-complete-or-indent may be usefull to get completion working in the shell -py-insert-default-shebang -py-electric-* -py-indent-line-outmost -py-newline-and-close-block -py-indent-and-forward (indent line, move to next) -py-fill-* -py-which-function (for showing in the modeline) -py-help-at-point -py-execute-import-or-reload -py-execute-def-or-class -various pdb functions - - -installing jedi -#+begin_src sh :tangle no -pi python-pip -s pip install jedi virtualenv -#+end_src -then do m-x jedi:install-server - - - -disabled because it takes 152 ms to load, -and I don't know how to do it conditioally -#+begin_src emacs-lisp :tangle no - -;; change from default python3 to be compatibile with Pywikibot -(setq py-shell-name "/usr/bin/python") -(require 'python-mode) - -(setq py-autopep8-options '("--max-line-length=110")) - -(defun py-execute-block-or-clause-create-shell () - (interactive) - (cond ((get-buffer "*Python*") - (py--execute-prepare "block-or-clause") - (py-execute-block-or-clause) - (call-interactively 'next-line)) - (t - (py-shell) - ;; py-shell starts the shell but not display the buffer on the first run - ;; subsequent runs, it does. I grabbed this command from inside to - ;; do just the relevant part from the second run, as a hack. - ;; todo: report a bug on this - (py--shell-manage-windows py-buffer-name)))) -(setq py-tab-shifts-region-p t) -(setq py-tab-indents-region-p t) - -(defun py-run () - "default action to run the current buffer" - (basic-save-buffer) - (py-execute-buffer)) - - -(add-hook 'python-mode-hook - (lambda () - (setq run-fun 'py-run) - (define-key python-mode-map (kbd "C-M-a") nil) - (define-key python-mode-map (kbd "C-M-d") nil) - (define-key python-mode-map (kbd "C-M-e") nil) - (define-key python-mode-map (kbd "C-M-h") nil) - (define-key python-mode-map (kbd "C-M-i") nil) - (define-key python-mode-map (kbd "C-M-u") nil) - (define-key python-mode-map (kbd "C-M-x") nil) - (define-key python-mode-map (kbd "") 'indent-for-tab-command) - (define-key python-mode-map (kbd "C-j") nil) - (define-key python-mode-map (kbd "") nil) - ;;(define-key python-mode-map (kbd "C-(") (lambda () (interactive) (basic-save-buffer) (py-execute-buffer))) - ;; fix default return bindings - (define-key python-mode-map (kbd "C-j") nil) - (define-key python-mode-map (kbd "RET") nil) - (define-key python-mode-map (kbd "") 'py-newline-and-indent) - (define-key python-mode-map (kbd "") 'py-indent-line) - (define-key python-mode-map (kbd "C-M-(") 'py-shift-left) - (define-key python-mode-map (kbd "C-M-)") 'py-shift-right) - (define-key python-mode-map (kbd "") 'py-beginning-of-line) - (define-key python-mode-map (kbd "") 'py-end-of-line) - (define-key python-mode-map (kbd "C-t") 'py-execute-block-or-clause-create-shell) - (define-key python-mode-map (kbd "") 'py-ian-execute-line-or-region) - ;; python mode adds these to this list, which is normally empty. - ;; it makes my send-python function not reuse an existing python shell window - ;; there are other ways to override this, but I don't know of any other value of - ;; having this set. - (setq same-window-buffer-names (delete "*Python*" same-window-buffer-names)) - (setq same-window-buffer-names (delete "*IPython*" same-window-buffer-names)))) - -;; i dunno, why, but this didn't work: -;; and we can't eval-after-load cuz it is part of the greater python mode file -(add-hook 'py-shell-hook - (lambda () - (define-key py-shell-map "\r" nil) - (define-key py-shell-map (kbd "") 'comint-send-input) - (define-key py-shell-map (kbd "C-t") 'py-shell-toggle-arrow-keys) - (define-key py-shell-map "\C-d" nil) - (define-key py-shell-map (kbd "") 'my-comint-previous-input) - (define-key py-shell-map (kbd "") 'my-comint-next-input))) - - -(defun py-ian-execute-line-or-region () - (interactive) - (cond ((get-buffer "*Python*") - (if mark-active - (py-execute-region) - (py-execute-statement)) - (call-interactively 'next-line)) - (t (py-shell)))) - -;; http://tkf.github.io/emacs-jedi/latest/ -(add-hook 'python-mode-hook 'jedi:setup) -(setq jedi:complete-on-dot t) - -(defun py-shell-toggle-arrow-keys () - (interactive) - (toggle-arrow-keys py-shell-map)) - -#+end_src - - -;; py-shell window stuff -;; it splits the window if the shell is in a different frame -;; which seems to be a bug, but it can be fixed with this option -;; (setq py-keep-windows-configuration 'force) -;; however, with py-execute-block-or-clause, if the shell is in a different frame, -;; you get errors "buffer is read only", when the point is near the beginning of a command -;; todo: test with emacs -Q and file a bug -;; if you execute py-execute-... without a python shell open, -;; it starts one, doesn't display it, and subsequent py-execute commands -;; give error "buffer is read only" -;; these functions fix / improve these problems - - -** initial python-mode setup - -python-mode seems to be the most canonical package, based on -https://docs.python.org/devguide/emacs.html -much more feature rich than the emacs built in one. - -getting it, it wants you to setup an account on launchpad by default, -there is some way to get anonymous bzr access, but google didn't answer it right away, -so fuck it, ill go the happy path. - -based on error messages, -add public ssh key to https://launchpad.net/people/+me -bzr launchpad-login iank -cd ~/.emacs.d/src/ -bzr branch lp:python-mode - -add lines from INSTALL to init - - -** background on packages -jedi appears most popular based on github stats -pysmell appears dead -ac-python appears dead -https://github.com/proofit404/anaconda-mode seems to be kicking along - - -** misc notes: - -python-mode has a TON of functions that are just aliases or verbatim wrappers of other functions. -also has undocumented/unused vars all around. it is quite annoying. - -the dedicated argument to py-shell does nothing, -and py-dedicated-shell just sets that, so it is a waste - - -** background on sending to python shell - -using the builtin python execute shell functions, sending one line doesn't really work well. -The bulit in functions don't wait for further input if a block is not closed. -And doing a copy/paste thing gets messed up because of indents. -With some hacking, I could probably do copy/paste and remove indents, only to a -certain level if we have entered a block and are waiting to finish it. -But just doing the builtin execute block is a decent work around. - - -Here is the scrapped function for single line built in sending to shell. - - -(setq w32-enable-num-lock nil) -(global-set-key (kbd "") 'left-char) - - -(defun sqlup-find-correct-keywords () - "If emacs is handling the logic for syntax highlighting of SQL keywords, then we piggyback on top of that logic. If not, we use an sql-mode function to create a list of regular expressions and use that." - (mapcar 'car (sql-add-product-keywords sql-product '()))) - - -largest subarray sum, array of pos and neg ints. diff --git a/myinit.el b/myinit.el new file mode 100644 index 0000000..9df7a86 --- /dev/null +++ b/myinit.el @@ -0,0 +1,2228 @@ +;;; copyright + +;; Copyright (C) 2019 Ian Kelling + +;; 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 . + +;;; misc emacs documentation + +;;;; how to find auto-saved files that need recovering +;; find a recently dated file in ~/.emacs.d/auto-save-list/, and see the files listed in it. +;; #file# is an auto-save file. It may or may not be different than the file is corresponds to. +;; If it is different, emacs will give a message about recovering it when you open it. + +;;;; misc org functions + +;; ;; these are usefull with (goto-char) +;; ;; find named entity, other than headline +;; (org-find-entry-with-id "string-number-or-symbol") + +;; (org-find-exact-headline-in-buffer "heading" nil t) + +;; ;; remove any indent level which is throughout the buffer +;; (org-do-remove-indentation) + + +;;;; gnus + +;; good info http://www.emacswiki.org/emacs/GnusTutorial +;; good info http://www.emacs.uniyar.ac.ru/doc/em24h/emacs183.htm + + +;; After downloading mailing list archives, once you have an mbox file, +;; there are rather straightforward ways to get it into any mail program, +;; but I will cover gnus, which I use and is a bit tricky. + +;; gnus has a native search (limited, too slow for body text searches), and external search engine integration. +;; gnus manual recommends converting to maildir for searching local mail, but importing lots of maildir messages to gnus +;; takes 10+ minutes, so scratch that option. it suggests 2 alternate options +;; mairix. for mbox, it doesn't integrate 100% with gnus, it copies the search results to a mbox +;; and tells gnus to make a group of that mbox and display it. This means the read state won't be persistent, but otherwise +;; works great. + +;; local imap server which will use the mbox and provide search. +;; dovecot is modular, theres a dovecot-common which uses recommends to install i guess it's most used modules. Its +;; description is completely not useful. Anyways, I'm not sure if there is any benefit to installing this over just the +;; module we need. +;; pi dovecot-imapd + +;; dovecot by default also makes a an inbox folder based on the normal local mail location /var/mail/ +;; those locations are adjustable and well documented via the var mail_location in +;; /etc/dovecot/conf.d/10-mail.conf +;; I forward my local mail, didn't see immediately how to turn off the inbox, but it will always be empty, so I left as +;; is. you could make the var be empty, which apparently has the same effect. + +;; Originally just linked the default location ~/.mail, but I changed to altering the config since ~/.mail since it seems +;; other things like postfix use that location + +;; based on http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html +;; other links that poped up contained outdated, innacurate information +;; http://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/ +;; http://www.emacswiki.org/emacs/JamesFerguson +;; http://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/ + +;; Within emacs you can move messages between mbox and maildir etc, which is a nice flexibility. + + + +;; doc group for mbox: +;; in gnus, do gnus-group-make-doc-group (G f in groups buffer) and point to the file + +;; info about groups created within gnus is stored in ~/.newsrc.eld +;; also stored is a duplication of what email messages are read/unread, +;; what newsgroups are subsribed to and read/unread, +;; probably more stuff, everything that gnus saves. + + +;; searching the body of the messages, i cut off after a few minutes. +;; i can grep the file in just a couple seconds + + +;; random side note +;; we can also get mbox from gmane +;; http://notmuchmail.org/howto/#index7h2 + + +;; gnus can't search mboxes except with its builtin search which is extremely slow. mairix can do mbox files from the command +;; line, but not from within gnus, but from mairix.el, which can then open the results in gnus + +;; mbox can be converted to maildir easily, but gnus loads lots of maildir messages extremely slow. it parses all the +;; headers and generates a nov file for each. + +;; nnfolder-generate-active-file + +;; to reset things, when changing mail group. I duno all the proper way, but it works to delete +;; ~/Mail ~/.newsrc.eld ~/.dribble (or something) + + +;;;;; mail sources vs select methods background +;; I found this very confusing when first reading through the manual. "mail sources" is a term that does not simply mean +;; sources of mail, it is much narrower for gnus. sources of mail can be either "mail sources" or select methods. Mail +;; sources will move mail to ~/Mail (not sure what format), and split it into groups according to variables. You can use +;; "mail sources" for maildir / imap, but those can also be read via select methods, which do not move the mail from their +;; location, but use them in their native format. This is what I want to do, and I can simply ignore mail +;; sources. Confusing terminology is that "fetching mail" "scanning mail", lots of things mail doesn't mean all mail, it +;; means specifically from "mail sources". The words "articles" and "news" is used in connection with select methods, aka my actual mail. + + + +;;;;; caching background + +;; caching: +;; there is also ~/News/cache, filled with a bunch of articles, like 300 megs. can't figure out why. +;; Grepped for caching in the manual, found 2 main things. +;; cache is for 2 purposes. to cache locally, and to keep articles from expiring, called persistence +;; gnus-use-cache, which puts things if they are +;; gnus-cache-enter-articles +;; things go in cache when they are marked certain ways by default, ticked and dormant +;; and read articles are moved out of the cache +;; still no idea why i have a bunch in the cache, but I set a var so that my mail won't get cached +;; I'm gonna delete the cache, and check on it later see what exactly is going in there +;; And of course, I moved ~/News to my encrypted drive and symlinked it + + + +;;; 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 + +;; packages installed from package manager: i pretty much prioritize repos this way: gnu, then melpa, then marmalade. + +;; package-activated-list: +;; ac-dabbrev ac-haskell-process ack-and-a-half alect-themes auctex bash-completion bbdb csv-mode cyberpunk-theme dot-mode expand-region f find-file-in-project flycheck foreign-regexp ggtags ghc gnuplot-mode goto-chg haskell-mode heroku-theme highlight-indentation highlight-symbol htmlize inf-ruby info+ inkpot-theme jedi auto-complete jedi-core epc ctable concurrent key-chord leuven-theme logstash-conf magit git-commit magit-popup misc-fns mouse+ naquadah-theme nginx-mode occidental-theme org paredit pcsv php-mode pkg-info epl popup py-autopep8 python-environment deferred python-info python-mode rainbow-mode rust-mode rw-hunspell s smartparens smex smooth-scroll sr-speedbar strings swiper ivy tabulated-list tangotango-theme thingatpt+ undo-tree vimrc-mode volatile-highlights web-mode with-editor dash async ws-butler yasnippet + +;;;; alternate keyboards +;; todo, figure out an easy way to disable this when using external keyboard +(if (display-graphic-p) + (setq + enter-key (kbd "") + s-enter-key (kbd "") + c-m-enter-key (kbd "") + m-enter (kbd "") + c-enter (kbd "")) + (setq + enter-key (kbd "C-m") + s-enter-key (kbd "C-8") + c-m-enter-key (kbd "C-M-8") + m-enter (kbd "M-m") + c-enter (kbd "C-8"))) + +(setq tp (string= (system-name) "tp")) +(setq x200 (string= (system-name) "x2")) +(setq laptop-keyboard (or tp x200)) + +;; Ubiquitous Packages which should be loaded on startup rather than +;; autoloaded on demand since they are likely to be used in every +;; session. +(require 'saveplace) +(require 'ffap) +(require 'uniquify) +(require 'ansi-color) +(require 'recentf) + +;; Better to have a list of packages in here vs installed manually. +;; However, I install manually because sometimes there are two +;; versions and it is not necessarily easy to reconcile that. +;; based on marmalage website front page. +(require 'package) + +;; little kit to help remove a down server +;; (setq package-archives nil) + +;;(add-to-list 'package-archives +;; '("marmalade" . +;; "http://marmalade-repo.org/packages/")) + +(add-to-list 'package-archives + '("melpa" . "http://melpa.milkbox.net/packages/") t) +(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) + + +;; keep our init.el clean, by moving customization elisp to it's own file +(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 +;; turn on abbrev mode globally +(setq-default abbrev-mode t) + +;; default abbreviation mode file is .emacs.d/abbrev_defs. +;; add-global-abbrev, add-mode-abbrev for expansion at point +;; if all else fails, edit the abbrev file + + + + +;;; auto-complete + +;; auto-completion in minibuffer +;; disabled while I look for another alternative +;;(icomplete-mode) + +(require 'auto-complete-config) +(ac-config-default) + + +;; complete after 1 char instead of default 2 +(setq ac-auto-start 1) +(setq ac-delay 0.001) + +(add-to-list 'ac-modes 'org-mode 'sql-mode) + +(defun ac-common-setup () + (add-to-list 'ac-sources 'ac-source-yasnippet)) + +;; for org mode completion source taken from wiki. +;; it did not work. no idea why. todo, investigate +;; the ac-sources code is at http://www.emacswiki.org/emacs/AutoCompleteSources +;; i've deleted it here so as to save space and not spam this file +;;(defun my-ac-org-mode () +;; (setq ac-sources (append ac-sources '(ac-source-org)))) + + +;; this makes the org-self-insert command not do a flyspell spell check. +;; low priority thing to look into sometime +(ac-flyspell-workaround) + + +(define-key ac-completing-map (kbd "") nil) +(define-key ac-completing-map (kbd "") nil) +(define-key ac-completing-map (kbd "") 'ac-expand) +(define-key ac-completing-map "\t" 'ac-complete) +(define-key ac-completing-map (kbd "") 'ac-complete) + + + +;;; auto-complete readline-complete + +(require 'readline-complete) +;; not sure how I made these, but I deleted, and +;; it would be nice to make them again sometime +;;(require 'src-loaddefs) + +;; disabled cuz broken +;; redefining function in readline-complete so ac-complete only uses readline as a source +(defun ac-rlc-setup-sources () + "Add me to shell-mode-hook!" + (setq ac-sources '(ac-source-shell))) +(add-hook 'shell-mode-hook 'ac-rlc-setup-sources) + +;; generally unnecessary, but why not +(setq explicit-shell-file-name "bash") + +;; readline-complete says to add this line. +;; however, it up my procfs directory tracking hook +;; because get-process doesn't notice the child shell. +;; instead, I've removed export EMACS=t from +;; comint-exec-1 (the function which initially sets it) +;; by finding it in emacs sources and redefinind it here +;; and done stty echo in my bashrc +;;(setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash")) + +(setenv "EMACS" "") +(setq explicit-bash-args nil) +(setq comint-process-echoes t) +;; default of 30 is way too slow. todo, consider pushing this upstream +(setq rlc-attempts 5) + +(add-to-list 'ac-modes 'shell-mode) + +;; readline-complete recommends this (i assume this format), +;; but greping finds no reference in emacs or my .emacs.d +;; so I'm assuming it is for an older emacs +;;(setq explicit-ssh-args '("-t")) + +(add-hook 'shell-mode-hook + (lambda () + (define-key shell-mode-map (kbd "") 'auto-complete))) + + +;;; readline complete fix + +;; I need this function here, where INSIDE_EMACS is replaced with RLC_INSIDE_EMACS. +;; ian: last update 2017-1-7. update this periodically from upstream +;; like when we do a major emacs update +(defun comint-exec-1 (name buffer command switches) + (let ((process-environment + (nconc + ;; If using termcap, we specify `emacs' as the terminal type + ;; because that lets us specify a width. + ;; If using terminfo, we specify `dumb' because that is + ;; a defined terminal type. `emacs' is not a defined terminal type + ;; and there is no way for us to define it here. + ;; Some programs that use terminfo get very confused + ;; if TERM is not a valid terminal type. + ;; ;; There is similar code in compile.el. + (if (and (boundp 'system-uses-terminfo) system-uses-terminfo) + (list "TERM=dumb" "TERMCAP=" + (format "COLUMNS=%d" (window-width))) + (list "TERM=emacs" + (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width)))) + (list (format "RLC_INSIDE_EMACS=%s,comint" emacs-version)) + process-environment)) + (default-directory + (if (file-accessible-directory-p default-directory) + default-directory + "/")) + proc decoding encoding changed) + (let ((exec-path (if (and command (file-name-directory command)) + ;; If the command has slashes, make sure we + ;; first look relative to the current directory. + (cons default-directory exec-path) exec-path))) + (setq proc (apply 'start-file-process name buffer command switches))) + ;; Some file name handler cannot start a process, fe ange-ftp. + (unless (processp proc) (error "No process started")) + (let ((coding-systems (process-coding-system proc))) + (setq decoding (car coding-systems) + encoding (cdr coding-systems))) + ;; Even if start-file-process left the coding system for encoding data + ;; sent from the process undecided, we had better use the same one + ;; as what we use for decoding. But, we should suppress EOL + ;; conversion. + (if (and decoding (not encoding)) + (setq encoding (coding-system-change-eol-conversion decoding 'unix) + changed t)) + (if changed + (set-process-coding-system proc decoding encoding)) + proc)) + +;;; auto save & backup +(setq auto-save-timeout 1) ; idle time before auto-save. + +;; main hook for my auto save +(add-hook 'auto-save-hook 'my-auto-save) +;; additional hook to try to deal with emacs not auto-saving when a buffer isn't active +(add-hook 'window-configuration-change-hook 'my-auto-save-win) + +;; this function from mu4e really does not like buffer saving +(advice-add 'message-send-and-exit :before 'my-as-off) +(advice-add 'message-send-and-exit :after 'my-as-on) + +;; avoid window config hook saving too much, it can +;; get into loops in some random situations +(setq my-auto-save-last nil) +(defun my-auto-save-win () + (unless (eq (current-buffer) my-auto-save-last) + (my-auto-save (current-buffer)))) + +(defun my-auto-save (&optional last) + (when (and + my-as + (buffer-file-name) + ;; mu4e has a bug right now, undo breaks when saving drafts + (not (string= (buffer-file-name) "*draft*")) + (buffer-modified-p) + (not (org-src-edit-buffer-p))) + ;; serial is incremented on each save, so let's do a bit less of them + (not (derived-mode-p 'dns-mode)) + (setq my-auto-save-last last) + (let (message-log-max) + ;; a bit of a hack to partially suppress the constant saving in the echo area + (with-temp-message "" + (basic-save-buffer))))) + +;; in the message-send-and-exit advice, got an error because it passed an arg. +;; didn't look into why, just add ignored args. +(defun my-as-off (&rest ignore) + (interactive) + (setq my-as nil)) + +(defun my-as-off-local (&rest ignore) + (interactive) + (setq-local my-as nil)) + +(defun my-as-on (&rest ignore) + (interactive) + (setq my-as t)) + +(defun my-as-on-local (&rest ignore) + (interactive) + (setq-local my-as on)) + +;; based on suggestion in the emacs docs, redefine these 2 functions +;; to avoid prompt spamming the user when we do auto-save +(defun ask-user-about-supersession-threat (fn) + (discard-input) + (message + "File for %s has changed on disk outside of emacs. Auto-save is overwriting it, however +a backup is being created in case that is not what you intended." buffer-file-name) + (setq buffer-backed-up nil)) + +(defadvice ask-user-about-lock (before lock-deactivate-as activate) + (make-local-variable 'my-as) + (setq my-as nil) + (message "proper autosave has been turned off for this buffer because of lock file problem. + In this buffer, do M-x my-as-on to reenable")) + +;; todo, this doesn't work consistently to override the auto-save message +(defalias 'do-auto-save-original (symbol-function 'do-auto-save)) +(defun do-auto-save (&optional no-message current-only) + "This function has been modified to wrap the original so that NO-MESSAGE +is always set to t, since we auto-save a lot, it spams otherwise. +The original doc string is as follows: + +Auto-save all buffers that need it. +This is all buffers that have auto-saving enabled +and are changed since last auto-saved. +Auto-saving writes the buffer into a file +so that your editing is not lost if the system crashes. +This file is not the file you visited; that changes only when you save. +Normally we run the normal hook `auto-save-hook' before saving. + + +A non-nil NO-MESSAGE argument means do not print any message if successful. +A non-nil CURRENT-ONLY argument means save only current buffer." + (interactive) + (do-auto-save-original t current-only)) + +;; enable MY auto-save +(my-as-on) + +;;; backups, separate from auto-save + + +;; set backup file location +(setq backup-directory-alist '(("." . "~/.editor-backups"))) +(setq auto-save-file-name-transforms + '((".*" "~/.editor-backups/" t))) + +(setq version-control t ;; Use version numbers for backups + kept-new-versions 100 + kept-old-versions 2 + delete-old-versions t ;; delete old versions silently + ;; assume hard linked files are done on purpose, don't screw them up + backup-by-copying-when-linked t) + +;; todo, the time needs to be an integer, not a vector type thing +(defun constant-backup () + "Backup conditioned on some time passing since last one. + Hooked into 'before-save-hook." + (cl-flet ((b-time (minutes) + (< last-backup-time + (- (current-time) (* 60 minutes))))) + (when (or (not (boundp 'last-backup-time)) (and (< (buffer-size) 10000000) (b-time 5)) (b-time 30)) + (setq buffer-backed-up nil) + (setq-local last-backup-time (current-time))))) + +;; make a backup on auto-save, because the backup feature is not +;; utilized with my-auto-save, only normal interactive save. +;; todo, enable when fixed +;;(add-hook 'before-save-hook 'constant-backup) + +(add-hook 'auto-save-hook 'auto-save-size-limit) + +(defun auto-save-size-limit () + (when (and (not backup-inhibited) (> (buffer-size) 2000000)) + (message "Backups disabled for this buffer due to size > 2 megs") + (make-local-variable 'backup-inhibited) + (setq backup-inhibited t))) + + +;; ;; background: +;; ;; the faq suggests to auto-save using +;; (setq auto-save-visited-file-name t) +;; and to toggle auto-saving in the current buffer, type `M-x auto-save-mode' + +;; however, this is buggy. +;; it leaves around lock files, which can be disabled with +;; (setq create-lockfiles nil) +;; but it is also buggy on other things that appear to hook onto file saving +;; so i created my own function, which originally had bugs, +;; but new emacs version fixed all that, yay!. + + + ; not using, but here for documentation, + ; alternate way to enable and specify how long between autosaves. + ; number of input events between autosave. + ; lowest bound of functionality is actually about 15 input events + ;(setq auto-save-interval + +;;; 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) +(bbdb-initialize 'message) + +;; recommended by gnus, +;; but seems like it could be good to have set for other stuff +(setq user-full-name "Ian Kelling") +;; general email setting? recommended by mu4e +(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))) + +(require 'bbdb-csv-import) + +;;; bookmark settings + ; save bookmarks whenever they are changed instead of just when emacs quits +(setq bookmark-save-flag 1) + ; increase bookmark context size for better functionality +(setq bookmark-search-size 2000) + +;;; c-like settings +;; change last thing from gnu. +;; notably this avoids brace indent after if, and 4 space indent +(setq c-default-style '((java-mode . "java") + (awk-mode . "awk") + (other . "stroustrup"))) +;; for emacs itself, use +;; (setq c-default-style '((java-mode . "java") +;; (awk-mode . "awk") +;; (other . "gnu"))) +;; (setq-default c-basic-offset 2) + +;;; color theme + +;; A Theme builder is available at http://elpa.gnu.org/themes/ along with +;; a list of pre-built themes at http://elpa.gnu.org/themes/view.html and +;; themes are available through ELPA. + + +;; interesting light themes + + +(defun override-theme (arg) + (interactive) + (while custom-enabled-themes + (disable-theme (car custom-enabled-themes))) + (load-theme arg t)) +(setq color-theme-is-global t) + +(defun toggle-night () + (interactive) + (cond ((equal (car custom-enabled-themes) 'naquadah) + (override-theme 'occidental)) + (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) + + +;; disable color thing with this: +;;(disable-theme (car custom-enabled-themes)) + +;; decent dark themes + +;;(override-theme 'tangotango) +;;(override-theme 'deeper-blue) +;;(override-theme 'tango-dark) +;;(override-theme 'tsdh-dark) + +;;(override-theme 'heroku) +;;(override-theme 'inkpot) ;; part of inkpot-theme package +;;(override-theme 'naquadah) ; org mode features, part of naquadah-theme package +;;(override-theme 'spolsky) ;; part of sublime-themes package +;;(override-theme 'twilight-anti-bright) ;; from twilight-anti-bright-theme package + +;; interesting but not usable colors +;;(override-theme 'cyberpunk) ; cool org mode features, from cyberpunk-theme package +;;(override-theme 'wombat) ; cursor not visible enough. from a wombat package, not sure which +;;(override-theme 'misterioso) ; cursor not visible enough + + + +;;decent light themes +;;(override-theme 'alect-light) ; theres a -alt version, don't see a dif. could use this without dimming. from alect-something package +;;(override-theme 'occidental) ; from occidental-theme package + + +;;color-theme is deprecated in emacs 24. + +;; theme packages i tried then removed: +;; ignored ones that didn't use the new theme engine + +;;66 packages (zenburn-theme-2.1, zen-and-art-theme-1.0.1, waher-theme-20130917.7, ujelly-theme-1.0.35, twilight-theme-1.0.0, twilight-bright-theme-20130605.143, twilight-anti-bright-theme-20120713.316, tronesque-theme-1.3, tron-theme-12, toxi-theme-0.1.0, tommyh-theme-1.2, tango-2-theme-1.0.0, sunny-day-theme-20131203.1250, sublime-themes-20140117.323, subatomic-theme-20131011.1048, soothe-theme-0.3.16, soft-morning-theme-20131211.1342, soft-charcoal-theme-20130924.1206, sea-before-storm-theme-0.3, purple-haze-theme-20130929.1751, phoenix-dark-pink-theme-20130905.941, phoenix-dark-mono-theme-20130306.1215, pastels-on-dark-theme-0.3, obsidian-theme-20130920.937, nzenburn-theme-20130513, noctilux-theme-20131019.31, mustang-theme-20130920.939, monokai-theme-0.0.10, molokai-theme-20130828.0, late-night-theme-0.0, jujube-theme-0.1, ir-black-theme-20130302.2355, gruvbox-theme-20131229.1458, gruber-darker-theme-0.6, grandshell-theme-20140118.1003, github-theme-0.0.3, gandalf-theme-0.1, flatland-theme-20131204.858, django-theme-20131022.202, deep-thought-theme-0.1.1, dakrone-theme-20131212.1159, colorsarenice-theme-20131128.1106, color-theme-wombat+-0.0.2, color-theme-wombat-0.0.1, color-theme-twilight-0.1, color-theme-tango-0.0.2, color-theme-solarized-20120301, color-theme-sanityinc-solarized-2.25, color-theme-railscasts-0.0.2, color-theme-monokai-0.0.5, color-theme-molokai-0.1, color-theme-ir-black-1.0.1, color-theme-heroku-1.0.0, color-theme-github-0.0.3, color-theme-eclipse-0.0.2, color-theme-dpaste-0.0.1, color-theme-dawn-night-1.0, color-theme-colorful-obsolescence-0.0.1, color-theme-cobalt-0.0.2, color-theme-20080305.34, clues-theme-20130908.801, busybee-theme-20130920.942, bubbleberry-theme-0.1.2, mblage-theme-20130715.621, anti-zenburn-theme-20140104.1542, ample-zen-theme-0.2) + + + + +;;; yasnippet + +;; cd ~/.emacs.d/src +;; git clone --recursive https://github.com/capitaomorte/yasnippet +;; touch snippets/.yas-make-groups + +;; This all makes it so I can look through the default snippets +;; in the menu bar, but they don't show up elsewhere, because they are +;; mostly things I don't want. + + +(require 'yasnippet) +;; this needs to be before yas-global-mode +(setq yas-snippet-dirs (list "~/.emacs.d/snippets")) +(yas-global-mode 1) + +(setq + yas-also-auto-indent-first-line t + yas-choose-tables-first t + yas-use-menu (quote full) + ;; this sets ido-prompt as first function + yas-prompt-functions + '(yas-ido-prompt yas-dropdown-prompt yas-x-prompt yas-completing-prompt yas-no-prompt)) + +;; todo, explore this option for wrapping region +;; '(yas/wrap-around-region t)) + +;;; cross session settings + +;; Save a list of recent files visited. +(recentf-mode 1) +(setq recentf-max-saved-items 200 + recentf-max-menu-items 15) + + +(setq save-place t + save-place-version-control 'nospecial + save-place-limit 40000 + save-place-file "~/.emacs.d/places") + + + +;; savehist keeps track of some history +;; search entries +(setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring) + ;; save every minute + savehist-autosave-interval 60 + ;; keep the home clean + savehist-file "~/.emacs.d/.savehist") +(savehist-mode 1) + + +;;; ediff +;; ediff-buffers is the main command to use + +;; ediff - don't start another frame for the control panel +;; unfortunately, this doesn't allow me to use 2 frames for the diff buffers +;; so disable this temporarily with the next line if you want that +;; sometime I should setup 2 functions to explicitly do each type +(setq ediff-window-setup-function 'ediff-setup-windows-plain) +;;(setq ediff-window-setup-function 'ediff-setup-windows-default) + +;; do side by side diffs +(setq ediff-split-window-function 'split-window-horizontally) + + + +;; Things I tried which didn't work, which intuitively I think should +;; work better: I can open the second diff buffer in a new frame, and +;; close it's window in the first frame after starting ediff, but when I +;; hit n to go to the next diff, it restores the window in the first +;; frame. Another thing I tried is to open 2 new frames and set them up +;; as I want. However, if I try to open the *Ediff Control Panel* buffer +;; in a different window from its original one, my mouse jumps to one of +;; the diff frames, or if that isn't visible, the buffer just hangs +;; until I select the original ediff control panel window. This seems +;; like a bug to me. I am using a very recent development version of +;; emacs. + +;;; dired + +;; dired - reuse current buffer by pressing 'a' +(put 'dired-find-alternate-file 'disabled nil) + +;;; mu4e + +;; alsot tried notmuch, it had some glitches, and it's config has a list +;; of folders which i'd rather not publish, so it's config is archived. + +;;(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e") +;;(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e") +(require 'mu4e) + +;; (setq mu4e-headers-results-limit 2000) + +(setq + ;; common to gnus. default sendmail-query-once asks us, then sets this via customize. + send-mail-function (quote sendmail-send-it) + ;; use the standard imap folders + mu4e-sent-folder "/Sent" + mu4e-drafts-folder "/Drafts" + mu4e-trash-folder "/Trash" + ;; reindex new mail this often in seconds + ;; show addresses instead of just names + mu4e-view-show-addresses t + mu4e-use-fancy-chars t + mu4e-confirm-quit nil + mu4e-headers-leave-behavior 'apply ;; dont ask, do whatever was marked + mu4e-headers-fields (delq (assoc :mailing-list mu4e-headers-fields) mu4e-headers-fields) + ;; default 500. + mu4e-headers-results-limit 1000 + ;; tell exim to use from: as envelope from. + ;; exim's default is use outgoing_msg_localpart@hostname. + mail-specify-envelope-from t + + ;; looking up the list of maildirs when doing jo from summary + ;; can take a few seconds if we have a ton of messages. + ;; Only take that time for the first lookup. + ;; if we add a new maildir, just restart mu4e for it to be in that list. + mu4e-cache-maildir-list t + ;; default is 8, way too small for my big monitors + mu4e-headers-visible-lines 50 + ) + +;; fucks up reading unread bookmark. when that is fixed, enable it +;; (setq mu4e-update-interval 60) + + +;; this file includes setting up my email addresses, which are not public, +;; including +;; mu4e-user-mail-address-list +;; and a function +;; inspired by mu4e info manual, search for mu4e-compose-pre-hook. +(load "/p/c/mu4e.el") + +(defun my-decrypt () + ;; use for decrypting in mu4e + (interactive) + (beginning-of-buffer) + (when (search-forward "-----BEGIN PGP MESSAGE-----" nil t) + (read-only-mode 0) + (let ((start (match-beginning 0)) + (end (search-forward "-----END PGP MESSAGE-----" nil t))) + (shell-command-on-region start end "gpg2 -dq" nil t shell-command-default-error-buffer t) + ))) +(add-hook 'mu4e-view-mode-hook 'my-decrypt) + +(defun mu-set-from-name (regexes) + "If we find an address matching regex, then set that address as the to, +and whatever was used" + (when mu4e-compose-parent-message + (let ((found nil)) + (while (and regexes (not found)) + (setq re (car regexes) + regexes (cdr regexes) + found (mu4e-message-contact-field-matches + mu4e-compose-parent-message :to re))) + (when found (setq user-mail-address (cdr found) + user-full-name (car found))) + found))) +(defun mu-set-from (regexes) + "If we find an address matching regex, then set that address as the to, +and Ian Kelling as the name" + (when mu4e-compose-parent-message + (let ((found nil)) + (while (and regexes (not found)) + (setq re (car regexes) + regexes (cdr regexes) + found (cdr (mu4e-message-contact-field-matches + mu4e-compose-parent-message :to re)))) + (when found (setq user-mail-address found + user-full-name "Ian Kelling")) + found))) + + +(defun my-mu4e-to-fsf () + "inspired by mu4e info manual, search for mu4e-compose-pre-hook." + (cond + ((mu-set-from '("iank@fsf.org" + "iank@gnu.org"))) + ((setq user-mail-address "iank@fsf.org" + user-full-name "Ian Kelling")))) + + +;; on first run mkdir -p /nocow/user/.mufsf; mu index --maildir=/nocow/user/fsfmd +(defun mu-exit-wait () + (interactive) + ;; taken from the mu source + (let* ((buf (get-buffer mu4e~proc-name)) + (proc (and (buffer-live-p buf) (get-buffer-process buf)))) + (mu4e-quit) + ;; without sleep, we get database locked by another process error when hitting u + ;; if another mu was running. + (if proc (sleep-for 0 1000)))) + +(defun fsf-mu4e () + (interactive) + (unless (equal mu4e-maildir "/nocow/user/fsfmd") (mu-exit-wait)) + (setq + ;; fsf monitor is smaller + mu4e-headers-visible-lines 15 + mu4e-maildir "/nocow/user/fsfmd" + mu4e-refile-folder "/Spam" + mu4e-index-lazy-check nil + mu4e-get-mail-command "true" + user-mail-address "iank@fsf.org" + mail-signature " + +-- +Ian Kelling | Senior Systems Administrator, Free Software Foundation +GPG Key: B125 F60B 7B28 7FF6 A2B7 DF8F 170A F0E2 9542 95DF +https://fsf.org | https://gnu.org +" + + mu4e-user-mail-address-list '("iank@fsf.org" + "iank@gnu.org") + mu4e-maildir-shortcuts + '( ("/INBOX" . ?i) + ("/sysadmin" . ?a) + ("/sec" . ?x) + ("/rtcc" . ?c) + ("/Drafts" . ?d) + ("/Sent" . ?s) + ) + ) ;; end setq + (call-process "/a/exe/lnf" nil nil nil "-T" "/nocow/user/.mufsf" (concat (getenv "HOME") "/.mu")) + (add-hook 'mu4e-compose-pre-hook 'my-mu4e-to-fsf) + (remove-hook 'mu4e-compose-pre-hook 'my-mu4e-to) + (mu4e)) ;; end defun fsf-mu4e + + +;; it's implemented in mu4e, but not in the actions list for +;; some reason. +(add-to-list 'mu4e-view-actions + '("browser view" . mu4e-action-view-in-browser) t) + +;; normally, you would add to this, but we want to +;; modify unread messages. the first 4 are defined by default. +(setq mu4e-bookmarks + `( ,(make-mu4e-bookmark + :name "Unread messages" + ;; old less restrictive unread, for adapting in the future: + ;; flag:unread AND NOT flag:trashed AND NOT maildir:/Junk AND NOT maildir:/fwfw AND NOT maildir:/log + :query "flag:unread maildir:/INBOX" + :key ?u) + ,(make-mu4e-bookmark + :name "Today's messages" + :query "date:today..now" + :key ?t) + ,(make-mu4e-bookmark + :name "Last 7 days" + :query "date:7d..now" + :key ?w) + ,(make-mu4e-bookmark + :name "Messages with images" + :query "mime:image/*" + :key ?p)) + ) + + +(defun mu4e-action-msgs-by-this-sender (msg) + "In header view, view messages by the sender of the message under point." + (let ((from (mu4e-message-field msg :from))) + (unless from + (mu4e-error "No from header for this message")) + ;; from is structured like: (("Anacron" . "root@x2.lan")) + (mu4e-headers-search (concat "f:" (cdar from))))) + +(add-to-list 'mu4e-headers-actions + '("from this sender" . mu4e-action-msgs-by-this-sender) t) +(add-to-list 'mu4e-view-actions + '("from this sender" . mu4e-action-msgs-by-this-sender) t) + + +;;; elisp settings + ; when manually evaluating lisp, go into debugger on error +(setq eval-expression-debug-on-error t) + ;reminder of useful var: debug-on-error + + +;;; haskell + +;; useful comint-shell mode commands. If not prefaced with *, it means it is not in the haskell custom repl +;; *todo: setup haskell c-t toggle arrow keys +;; tab completion +;; C-q insert prev arg +;; C-( history search +;; c-m-left/right move to next/prev prompts +;; *c-enter, multi-line input +;; *s-delete, send input across windows. (i can implement this) +;; *c-m-l clear screen +;; *haskell-process-interrupt, c-cc terminate job (i can implement this maybe) + +;; nice bash/readline functions missing in comint: +;; yank-nth-arg +;; operate-get-next +;; menu-complete + +;; usefull comint commands: +;; c-cl : list historic command in temp buffer +;; C-c C-o comint-delete-output +;; comint-restore-input, todo: put this on a randomish c-c key + + + +;; todo: +;; checkout haskell repl functions: +;; c-cv haskell-check, hlint +;; C-M-q prog-indent-sexp +;; c-c. haskell-mode-format-imports +;; C-c M-/ haskell-doc-check-active +;; haskell-process-generate-tags +;; haskell-process-cabal-build +;; haskell-cabal-command.. or something +;; haskell-process-restart +;; C-h v haskell-process-log +;; C-h v haskell-process-show-debug-tips + +;; various not immediately useful functions: +;; haskell-process-add-dependency +;; haskell-process-touch-buffer +;; haskell-process-cd +;; haskell-process-unignore +;; haskell-process-reload-devel-main + + +;; rebind +;; home: C-a haskell-interactive-mode-beginning +;; c-return: C-j haskell-interactive-mode-newline-indent +;; up/down: haskell-interactive-mode-history-next + +;; todo haskell mode better binds for: +;; 'haskell-process-load-file +;; 'haskell-process-do-type +;; 'haskell-process-do-info +;; 'inferior-haskell-send-decl + + +;; commands which don't work in haskell-interactive-mode(hi) vs inferior-haskell-mode(ih, default) +;; functions not in hi: +;; inferior-haskell-find-definition, use tags instead +;; inferior-haskell-find-haddock, todo, test if this works + +;; redefined ih to hi +;; switch-to-haskell -> 'haskell-interactive-switch +;; haskell-process-load-file -> inferior-haskell-load-file +;; haskell-process-do-type -> inferior-haskell-type +;; switch-to-haskell -> haskell-interactive-switch +;; inferior-haskell-load-file -> 'haskell-process-load-file + + +;; haskell-mode installation from source, based on its readme +;; in the git directory, +;; make all + + + + +;; remove default option to not link the file +(setq haskell-compile-command "ghc -Wall -ferror-spans -fforce-recomp %s") +(add-hook 'haskell-indentation-mode-hook + (lambda () + (define-key haskell-indentation-mode-map [?\C-d] nil) + (define-key haskell-indentation-mode-map + (kbd "") + 'haskell-indentation-delete-char))) + +;;copied from haskell-mode docs in order to use the new, better, nondefault +;;interactive mode. +(eval-after-load "haskell-mode" + '(progn + (define-key haskell-mode-map (kbd "C-x C-d") nil) + (define-key haskell-mode-map (kbd "C-c C-z") 'haskell-interactive-switch) + (define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-file) + (define-key haskell-mode-map (kbd "C-c C-b") 'haskell-interactive-switch) + (define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type) + (define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info) + (define-key haskell-mode-map (kbd "C-c M-.") nil) + (define-key haskell-mode-map (kbd "C-c C-d") nil))) + +;; ghc-mod install http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html +;; todo, try this out +;; (autoload 'ghc-init "ghc" nil t) +;;(add-hook 'haskell-mode-hook (lambda () (ghc-init) (flymake-mode))) + + + +;; from the package readme for ghci-completion +(require 'ghci-completion) +(add-hook 'inferior-haskell-mode-hook 'turn-on-ghci-completion) + + +;; disable some rebinds. they are set to appropriate keys in the keybinds section +(eval-after-load "haskell-mode" + '(progn + (define-key haskell-mode-map (kbd "C-a") 'nil) + (define-key haskell-mode-map (kbd "C-j") 'nil))) + +(eval-after-load "python-mode" + '(progn + (define-key python-mode-map (kbd "C-j") nil))) + +(defun pretty-lambdas-haskell () + (font-lock-add-keywords + nil `((,(concat "(?\\(" (regexp-quote "\\") "\\)") + (0 (progn (compose-region (match-beginning 1) (match-end 1) + ,(make-char 'greek-iso8859-7 107)) + nil)))))) +;; from haskell-mode manual +(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan) +(when (window-system) + (add-hook 'haskell-mode-hook 'pretty-lambdas-haskell)) + +;; added from haskell-mode website install instructions + ;(load "/usr/share/emacs/site-lisp/haskell-mode/haskell-site-file") +(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) +;;the three indentation modules are mutually exclusive - add at most one. Trying out the "most advanced" +(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation) +;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent) +;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent) + + +;; todo, set this to some other key +;; (local-set-key (kbd "C-e") 'my-haskell-load-and-run) + +(defun my-haskell-load-and-run () + "Loads and runs the current Haskell file." + (interactive) + (let ((start-buffer (current-buffer))) + (inferior-haskell-load-and-run inferior-haskell-run-command) + (sleep-for 0 100) + (end-of-buffer) + (pop-to-buffer start-buffer))) + +;; show haskell function in mode line +;; todo, this broke after updating emacs +;;(eval-after-load "which-func" +;; '(add-to-list 'which-func-modes 'haskell-mode)) + + + +(add-hook 'interactive-haskell-mode-hook 'ac-haskell-process-setup) +(add-hook 'haskell-interactive-mode-hook 'ac-haskell-process-setup) +(eval-after-load "auto-complete" + '(add-to-list 'ac-modes 'haskell-interactive-mode)) + +(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))))) +(add-hook 'haskell-cabal-mode-hook + (lambda () (define-key haskell-cabal-mode-map (kbd "C-(") 'haskell-compile))) + + + +(add-hook 'haskell-interactive-mode-hook + (lambda () + (define-key haskell-interactive-mode-map "\r" nil) + (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-return))) +(add-hook 'haskell-indentation-mode-hook (lambda () (define-key haskell-indentation-mode-map "\r" nil))) + + + +(add-hook 'haskell-interactive-mode-hook + (lambda () + (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-newline-indent))) + +;;; isearch +(setq + isearch-allow-scroll t + search-ring-update t) ;; dont start an edit when going to previous search + +(defun isearch-yank-regexp (regexp) + "Pull REGEXP into search regexp." + (let ((isearch-regexp nil)) ;; Dynamic binding of global. + (isearch-yank-string regexp)) + (isearch-search-and-update)) + +(defun isearch-yank-symbol (&optional partialp backward) + "Put symbol at current point into search string. + + If PARTIALP is non-nil, find all partial matches." + (interactive "P") + + (let (from to bound sym) + (setq sym + ; this block taken directly from find-tag-default + ; we couldn't use the function because we need the internal from and to values + (when (or (progn + ;; Look at text around `point'. + (save-excursion + (skip-syntax-backward "w_") (setq from (point))) + (save-excursion + (skip-syntax-forward "w_") (setq to (point))) + (> to from)) + ;; Look between `line-beginning-position' and `point'. + (save-excursion + (and (setq bound (line-beginning-position)) + (skip-syntax-backward "^w_" bound) + (> (setq to (point)) bound) + (skip-syntax-backward "w_") + (setq from (point)))) + ;; Look between `point' and `line-end-position'. + (save-excursion + (and (setq bound (line-end-position)) + (skip-syntax-forward "^w_" bound) + (< (setq from (point)) bound) + (skip-syntax-forward "w_") + (setq to (point))))) + (buffer-substring-no-properties from to))) + (cond ((null sym) + (message "No symbol at point")) + ((null backward) + (goto-char (1+ from))) + (t + (goto-char (1- to)))) + (isearch-search) + (if partialp + (isearch-yank-string sym) + (isearch-yank-regexp + (concat "\\_<" (regexp-quote sym) "\\_>"))))) + +(defun isearch-current-symbol (&optional partialp) + "Incremental search forward with symbol under point. + + Prefixed with \\[universal-argument] will find all partial + matches." + (interactive "P") + (let ((start (point))) + (isearch-forward-regexp nil 1) + (isearch-yank-symbol partialp))) +;; todo, make this + +(defun isearch-backward-current-symbol (&optional partialp) + "Incremental search backward with symbol under point. + + Prefixed with \\[universal-argument] will find all partial + matches." + (interactive "P") + (let ((start (point))) + (isearch-backward-regexp nil 1) + (isearch-yank-symbol partialp))) + + + + ; lets look through emacs starter kit before we throw this out. + + + ; automatically wrap to the top of the buffer when isearch fails +(defadvice isearch-search (after isearch-no-fail activate) + (unless isearch-success + (ad-disable-advice 'isearch-search 'after 'isearch-no-fail) + (ad-activate 'isearch-search) + (isearch-repeat (if isearch-forward 'forward)) + (ad-enable-advice 'isearch-search 'after 'isearch-no-fail) + (ad-activate 'isearch-search))) + +;; Activate occur easily inside isearch +(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)))))) +;;; lisp / elisp mode setings + +(add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save) +(defun starter-kit-remove-elc-on-save () + "If you're saving an elisp file, likely the .elc is no longer valid." + (make-local-variable 'after-save-hook) + (add-hook 'after-save-hook + (lambda () + (if (file-exists-p (concat buffer-file-name "c")) + (delete-file (concat buffer-file-name "c")))))) + + +(defun emacs-lisp-mode-defaults () + ;; checkdoc has an annoying feature that wants a header and footer + ;; in every elisp buffer as if they all were packages + ;; todo, see if there is a way + ;; to make checkdoc usable instead of just disabling it as I do here + (if (boundp 'flycheck-checkers) + (setq flycheck-checkers (remove 'emacs-lisp-checkdoc flycheck-checkers))) + (eldoc-mode 1)) +(add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-defaults) + +(define-key lisp-mode-map (kbd "") 'backward-up-list) +(define-key lisp-mode-map (kbd "") 'down-list) +(define-key emacs-lisp-mode-map (kbd "") 'backward-up-list) +(define-key emacs-lisp-mode-map (kbd "") 'down-list) +(define-key emacs-lisp-mode-map (kbd "") 'find-function-at-point) + +;; interactive modes don't need whitespace checks +(defun interactive-lisp-coding-defaults () + (whitespace-mode -1)) +(setq prelude-interactive-lisp-coding-hook 'prelude-interactive-lisp-coding-defaults) + + +;; ielm is an interactive Emacs Lisp shell +(defun ielm-mode-defaults () + (run-hooks 'prelude-interactive-lisp-coding-hook) + (turn-on-eldoc-mode)) +(add-hook 'ielm-mode-hook 'ielm-mode-defaults) + +;;; mediawiki + +(eval-after-load "mediawiki" + '(progn + (remove-hook 'outline-minor-mode-hook 'mediawiki-outline-magic-keys) + (add-hook 'mediawiki-mode-hook + (lambda () (define-key mediawiki-mode-map (kbd "C-(") 'mediawiki-save-reload))) + + ;; mediawiki mode has a bug that it will claim an edit conflict unless you reload after saving. + ;; I also like to save with no edit summary for previewing on my local mw instance + (defun mediawiki-save-reload () + (interactive) + (and (mediawiki-save "") (mediawiki-reload))))) +;;; modes with little configuration needed +;; busted: +;;(require 'csv-mode) +;;(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode)) + +(require 'outshine) +(add-hook 'outline-minor-mode-hook 'outshine-hook-function) +(add-hook 'emacs-lisp-mode-hook 'outline-minor-mode) +(add-hook 'sh-mode-hook 'outline-minor-mode) + + + +(setq org-caldav-url "https://cal.iankelling.org" + org-caldav-calendar-id "ian" + org-caldav-inbox "/p/cal.org") +;;(org-caldav-sync) + + +;;(require 'dtrt-indent) +;;(setq dtrt-indent-mode t) + +(setq css-indent-offset 2) + +(load-file "/a/h/iank-mod.el") + +;; from when i was running my own patches +;;(add-to-list 'load-path "/a/opt/ws-butler") + +(require 'ws-butler) +;; todo: I think this is broken, it keeps collapsing the last line +;; for empty messages. + +;; the main problem is when it deletes the blank line at the end +;; of a message with an empty body. but I might also +;; be pasting whitespace significant things in here, so +;; just don't do anything. +;; todo: propose this upstream +(add-to-list 'ws-butler-global-exempt-modes 'message-mode) + +(ws-butler-global-mode) + + + +(require 'nginx-mode) +;;The mode should automatically activate for files called nginx.conf and files under /etc/nginx - if not, you can add something like this to your init file: +;;(add-to-list 'auto-mode-alist '("/etc/nginx/sites-available/.*" . nginx-mode)) + +;; todo, put this on a hook with prog mode +;;(highlight-indentation-mode 1) + +(add-hook 'auto-revert-tail-mode-hook + (lambda () + (when (string= + buffer-file-name + "/var/log/cloudman/development/cm-service.log") + (setq-local prev-auto-revert-max 0) + ;; set buffer-local hook + (add-hook 'after-revert-hook 'tail-colorize nil t)))) +(defun tail-colorize () + (ansi-color-apply-on-region prev-auto-revert-max (point-max)) + (setq-local prev-auto-revert-max (point-max))) + + +;; gnu global +(require 'ggtags) +(add-hook 'c-mode-common-hook + (lambda () (ggtags-mode 1) + (setq c-label-minimum-indentation 0))) + +;; specific to my unusual keybind setup, you may want to +;; pick different keys +(define-key ggtags-mode-map (kbd "C-M-o") 'ggtags-find-tag-dwim) +(define-key ggtags-mode-map (kbd "C-M-m") 'ggtags-grep) + +(defun gtags-update-single(filename) + "Update Gtags database for changes in a single file" + (interactive) + (start-process "update-gtags" "update-gtags" "bash" "-c" (concat "cd " ggtags-project-root " ; gtags --single-update " filename ))) + +(defun gtags-update-current-file() + (interactive) + (let ((rel-filename (replace-regexp-in-string + ggtags-project-root "." + (buffer-file-name (current-buffer))))) + (gtags-update-single rel-filename))) + +(defun gtags-update-hook() + "Update GTAGS file incrementally upon saving a file" + (when (and ggtags-mode ggtags-project-root) + (gtags-update-current-file))) + +(add-hook 'after-save-hook 'gtags-update-hook) + +;; i'd like to make some elisp which modifies a keymap to remove +;; all binds which don't match a predicate. +;; I tried setting a keymap to a new keymap, +;; but that didn't register as functional. +;; so I'd need to modify the list in place. + +(require 'magit) + + +;; colorize hex colors: use rainbow mode + + +;; message mode prompted me on first message. +;; a function which describes options then sets this +;; the other options were to use smtp directly or pass to another mail client +;; here we use the standard sendmail interface, which I use postfix for +(setq send-mail-function (quote sendmail-send-it)) + +(require 'spray) +(global-set-key (kbd "C-M-w") 'spray-mode) +;; remember, h/l = move. f/s = faster/slower, space = pause, all others quit + +;; delete active selection with self-insert commands +(delete-selection-mode t) + +;; Transparently open compressed files +(auto-compression-mode t) + +;; Highlight matching parenthesesq when the pointq is on them. +;; not needed since smart paren mode? +;; (show-paren-mode 1) + + +;; not documented, but looking at the source, I find this +;; stops me from being asked what command on every C-c-c +;; when doing a latex document. +(setq TeX-command-force "LaTeX") + +;; dot mode, repeats last action +(require 'dot-mode) +(add-hook 'find-file-hooks 'dot-mode-on) + + +;; clean up obsolete buffers automatically at midnight +(require 'midnight) + + +;; disabled because it takes 400ms on startup +;; ;; emacs regexes are too limited. +;; (require 'foreign-regexp) +;; ;; perl is most powerful, but javascript is pretty close and +;; ;; I'd rather know javascript stuff than perl +;; (custom-set-variables +;; '(foreign-regexp/regexp-type 'javascript) ;; Choose by your preference. +;; '(reb-re-syntax 'foreign-regexp)) ;; Tell re-builder to use foreign regexp. +;; ;; it would be nice to add documentation to do this for more commands to that package +;; ;; disabled because it's too slow. but I'd still m-x it for advanced replacements +;; ;;(define-key global-map [remap isearch-forward-regexp] 'foreign-regexp/isearch-forward) + + +;; saner regex syntax +(require 're-builder) +(setq reb-re-syntax 'string) + + +;; use shift + arrow keys to switch between visible buffers +;; todo, set these keys to something else +(require 'windmove) +(windmove-default-keybindings) + + +;; show the name of the current function definition in the modeline +(require 'which-func) +(setq which-func-modes t) +(which-function-mode 1) + + +;; enable winner-mode to manage window configurations +(winner-mode +1) + +;; meaningful names for buffers with the same name +(require 'uniquify) +(setq uniquify-buffer-name-style 'forward + uniquify-separator "/" + ;; for sdx work. until I figure out a better way. + ;; maybe something like projectile can do it, + ;; or hacking around the status bar + uniquify-min-dir-content 2 + uniquify-after-kill-buffer-p t ; rename after killing uniquified + uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers + + +;; makefiles require tabs +;; todo: find a makefile indent function that works, +;; best I could find is this one which means don't indent at all +;; +(add-hook 'makefile-mode-hook + (lambda () + (setq indent-tabs-mode t) + (setq indent-line-function (lambda () 'no-indent)))) + + +;; todo, turn on auto-fill just for txt files +;;(add-hook 'text-mode-hook 'turn-on-auto-fill) +(add-hook 'text-mode-hook 'turn-on-flyspell) + + +;; auto indent shell script comments +(setq sh-indent-comment t) + +;; random extra highlights +(require 'volatile-highlights) +(volatile-highlights-mode t) + + +;; make help buffers smaller when it makes sense +(temp-buffer-resize-mode 1) + + +(require 'info+) +;; based on suggestions in info+.el, I also installed misc-fns, strings, and thingatpt+ +;; remove some bad keybinds from info+ +(define-key Info-mode-map [mouse-4] nil) +(define-key Info-mode-map [mouse-5] nil) + + +(require 'smooth-scroll) +;; long gnus summary buffers lags too much with this, +;; but I like it enough to leave it enabled by default +;; and crank up the step size to be faster +;; and it doesn't have a way to enable it only for certain modes etc. +;; todo sometime, make it work for certain modes only +(smooth-scroll-mode t) +;; its too slow with the default of 2 +(setq smooth-scroll/vscroll-step-size 7) +;; sublimity doesn't work as good going fast by default +;; smooth-scrolling.el, does not do smooth scrolling. its about cursor location + + +(setq sh-here-document-word "'EOF'") + +(setq tramp-default-method "ssh") +;;; misc general settings + +;; https://www.emacswiki.org/emacs/FillParagraph +;; make list items start paragraphs. +(setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ") + +(setq sh-basic-offset 2) +(setq vc-follow-symlinks t) + +;; give us a shell to start instead of scratch +;;(setq initial-buffer-choice (lambda () (new-shell))) + +;; disable this nasty function, as I always use a gui +(defun suspend-frame() (interactive)) + +;; Seed the random-number generator +(random t) + +;; easier to remember than keybinds +(defalias 'scrypt 'mml-secure-message-encrypt-pgpmime) +(defalias 'sign 'mml-secure-message-sign-pgpmime) +(defun encrypt () + (interactive) + (mml-secure-message-encrypt-pgpmime 'dontsign)) + +;; don't highlight the region. +(set-face-background 'region nil) + +;; this fixes save error for python example code +(define-coding-system-alias 'UTF-8 'utf-8) + +;; i don't use frame titles, but if I ever do +;; this starter kit setting is probably good +(if window-system (setq frame-title-format '(buffer-file-name "%f" ("%b")))) + + +;;(prefer-coding-system 'utf-8-unix) + +;; remove ugly 3d box feature +(set-face-attribute 'mode-line nil :box nil) + +(add-to-list 'default-frame-alist + '(font . "DejaVu Sans Mono-11")) + ; the default will jump 2 sizes. +(setq text-scale-mode-step 1.1) +(setq font-lock-maximum-decoration t + inhibit-startup-message t + transient-mark-mode t + delete-by-moving-to-trash t + shift-select-mode nil + truncate-partial-width-windows nil + uniquify-buffer-name-style 'forward + oddmuse-directory "~/.emacs.d/oddmuse" + echo-keystrokes 0.1 + mark-ring-max 160 + sort-fold-case t ; case insensitive line sorting + global-mark-ring-max 1000 + ;; the visible bell seems to lag the ui + ;;visible-bell t + ;; turn off audible bell + ;; https://www.emacswiki.org/emacs/AlarmBell + ring-bell-function 'ignore + case-replace nil + revert-without-query '(".*") + ;; don't pause display code on input. + ;; smoother display performance at slight cost of input performance + redisplay-dont-pause t + font-lock-maximum-decoration t) ; probably default and not necesary + + +(setq-default indent-tabs-mode nil ;; don't use tabs to indent + cursor-type 'box + fill-column 72 + + ;; wrap at word boundaries instead of mid-word + word-wrap t + imenu-auto-rescan t + indicate-empty-lines t) ; mark end of buffer + + +(blink-cursor-mode '(-4)) +(menu-bar-mode -1) +(tool-bar-mode -1) + + +;; enable various commands +(put 'narrow-to-region 'disabled nil) +(put 'narrow-to-page 'disabled nil) +(put 'narrow-to-defun 'disabled nil) +(put 'upcase-region 'disabled nil) +(put 'downcase-region 'disabled nil) +(put 'scroll-left 'disabled nil) +;; these from graphene, haven't read about them yet +(put 'ido-complete 'disabled nil) +(put 'ido-exit-minibuffer 'disabled nil) +(put 'dired-find-alternate-file 'disabled nil) +(put 'autopair-newline 'disabled nil) + + + +;;disable and minimize various prompts/messages +(fset 'yes-or-no-p 'y-or-n-p) +(setq confirm-nonexistent-file-or-buffer nil + inhibit-startup-message t + inhibit-startup-echo-area-message t + inhibit-startup-screen t + compilation-read-command nil ;; just don't compile with unsafe file local vars + kill-buffer-query-functions (remq 'process-kill-buffer-query-function + kill-buffer-query-functions)) + + +;; exit without bothering me +;; http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway/2708042#2708042 +(add-hook 'comint-exec-hook + (lambda () (set-process-query-on-exit-flag (get-buffer-process (current-buffer)) nil))) +;; based on save-buffers-kill-emacs help string, don't ask about clients when exiting +;; apparently this would need to be in some later hook. dunno where is best, but this works +(defadvice save-buffers-kill-emacs (before no-client-prompt-advice activate) + (setq kill-emacs-query-functions (delq 'server-kill-emacs-query-function kill-emacs-query-functions))) + + + +;; (custom-set-faces +;; ;; setting header-line-format to " " as a hack for a top margin the oly thning I could find to do a top margin +;; '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil)))) +;; ;; don't highlight the region +;; '(region ((t nil)))) +(setq-default header-line-format " ") + + +(setq initial-scratch-message nil) + + +;; vertical margin background. +;; google turned up: http://lists.gnu.org/archive/html/help-gnu-emacs/2014-03/msg00544.html +;; the xresource doesn't work for me, probably an xmonad thing. + +;; figured out I needed to customize the header line face. To find the face, M-x list-faces-display or just google / search +;; info, +;; then M-x customize-face +;; header-line +;; unchecked some stuff so that it inherits from default. + +;;; misc function definitions + + +(defun fill-buffer () + (interactive) + (save-mark-and-excursion + (beginning-of-buffer) + (while (= (forward-line) 0) + (fill-paragraph)))) + + +(defun next-backup-dir () + "In a directory listing from rsync -n, +Go to the next directory based on where the cursor is." + (interactive) + (let* ((start-col (current-column)) + (end-col (progn (skip-chars-forward "^/\n") (current-column))) + (dir (progn + (beginning-of-line 1) + (buffer-substring-no-properties (point) (+ (point) end-col))))) + (message dir) + (forward-line 1) + (while (and (not (eobp)) + (string= dir (buffer-substring-no-properties (point) (+ (point) end-col)))) + (forward-line 1)) + (forward-char-same-line start-col))) +;; copy paste this for fast keybind +;;(local-set-key (kbd "")) + + +(defun goto-buffer-or-find-file (file-name) + "If buffer is with FILE-NAME exists, go to it, else open the file using full path." + (interactive) + (let ((b (get-buffer (file-name-nondirectory file-name)))) + (if b + (switch-to-buffer b) + (find-file file-name)))) + + + + +;; todo, i think this is broken. perhaps the last goto-char is not accounting for buffer or something +(defun unpop-global-mark () + "Unpop off global mark ring. Does nothing if mark ring is empty." + (interactive) + (when global-mark-ring + (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring)) + (let ((lm (car (last global-mark-ring)))) + (set-marker (mark-marker) (marker-position lm) (marker-buffer lm))) + (when (null (mark t)) (ding)) + (setq global-mark-ring (nbutlast global-mark-ring)) + (goto-char (marker-position (mark-marker))))) + +(defun indent-buffer () + "Indents the entire buffer." + (interactive) + (cond ((derived-mode-p 'org-mode) + (org-indent-region (point-min) (point-max))) + ((derived-mode-p 'python-mode) + (py-autopep8)) + (t + (indent-region (point-min) (point-max))))) + + +;; TODO doesn't work with uniquify +(defun rename-file-and-buffer () + "Renames current buffer and file it is visiting." + (interactive) + (let ((name (buffer-name)) + (filename (buffer-file-name))) + (if (not (and filename (file-exists-p filename))) + (message "Buffer '%s' is not visiting a file!" name) + (let ((new-name (read-file-name "New name: " filename))) + (cond ((get-buffer new-name) + (message "A buffer named '%s' already exists!" new-name)) + (t + (rename-file name new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + (set-buffer-modified-p nil))))))) + + + +(defun sudo-edit (&optional arg) + (interactive "P") + (if (or arg (not buffer-file-name)) + (find-file (concat "/sudo::" (ido-read-file-name "File: "))) + (find-alternate-file (concat "/sudo::" buffer-file-name)))) + + + +(defun backward-symbol (arg) + (interactive "p") + (forward-symbol (- arg))) + +;;; mode line +;; make window title be the buffer name +(setq frame-title-format "%b") + + ; ----------------------------- + ; fixing up the mode line + ; modified from mastering emacs blog + ; ---------------------------- + +(defvar mode-line-cleaner-alist + `((auto-complete-mode . "") + (yas/minor-mode . "") + (paredit-mode . "") + (auto-fill-function . "") + (eldoc-mode . "") + (abbrev-mode . "") + (flyspell-mode . "") + (glasses-mode . "") + (dot-mode . "") + (yas-global-mode . "") + (yas-minor-mode . "") + (undo-tree-mode . "") + (volatile-highlights-mode . "") + (highlight-symbol-mode . "") + ;; Major modes + (lisp-interaction-mode . "λ") + (hi-lock-mode . "") + (python-mode . "Py") + (emacs-lisp-mode . "EL") + (nxhtml-mode . "nx")) + "Alist for `clean-mode-line'. + + When you add a new element to the alist, keep in mind that you + must pass the correct minor/major mode symbol and a string you + want to use in the modeline *in lieu of* the original.") + + +(defun clean-mode-line () + (interactive) + (loop for cleaner in mode-line-cleaner-alist + do (let* ((mode (car cleaner)) + (mode-str (cdr cleaner)) + (old-mode-str (cdr (assq mode minor-mode-alist)))) + (when old-mode-str + (setcar old-mode-str mode-str)) + ;; major mode + (when (eq mode major-mode) + (setq mode-name mode-str))))) + + ; disabled + ; (add-hook 'after-change-major-mode-hook 'clean-mode-line) + + + ;;; alias the new `flymake-report-status-slim' to + ;;; `flymake-report-status' +(defalias 'flymake-report-status 'flymake-report-status-slim) +(defun flymake-report-status-slim (e-w &optional status) + "Show \"slim\" flymake status in mode line." + (when e-w + (setq flymake-mode-line-e-w e-w)) + (when status + (setq flymake-mode-line-status status)) + (let* ((mode-line " Φ")) + (when (> (length flymake-mode-line-e-w) 0) + (setq mode-line (concat mode-line ":" flymake-mode-line-e-w))) + (setq mode-line (concat mode-line flymake-mode-line-status)) + (setq flymake-mode-line mode-line) + (force-mode-line-update))) + + +(defun my-after-change-major-mode-hook () + (setq mode-line-mule-info nil + minor-mode-alist nil + mode-line-position nil)) ; todo, make only flymake status show up + +(add-hook 'after-change-major-mode-hook 'my-after-change-major-mode-hook) + +;;; mouse related +;;;; settings +(setq focus-follows-mouse t + mouse-autoselect-window t + xterm-mouse-mode t) +;;;; move-mouse-to-point +;; todo, this is buggy with multiple windows open. +(defun move-mouse-to-point () + (interactive) + (let* ((pos (posn-col-row (posn-at-point))) + (x (+ (car pos) 2)) ; no idea why this is off by 1-2 + (y (cdr pos))) + (set-mouse-position (selected-frame) x y))) + +;;; org mode + +;; todo work on org-cycle-emulate-tab + +;; todo, this doesn't work for a non-standard keybind +;;(setq org-special-ctrl-k t) + +;; todo, generally fix org mode keys +;; todo, org-mark-element, unbdind from M-h, bind to mark defun key + + ;(org-babel-do-load-languages + ; 'org-babel-load-languages + ; '((emacs-lisp . t) + ; (sh . t))) + + + +;; make shell work like interactive bash shell +(setq org-babel-default-header-args:sh + '((:results . "output") (:shebang . "#!/bin/bash -l"))) + +;; my patch to output stderr +(setq org-babel-use-error-buffer nil) + + ; +;; org-mode manual suggests these, but I haven't used them. +;;(global-set-key "\C-cl" 'org-store-link) +;;(global-set-key "\C-ca" 'org-agenda) +;; this got in the way of a haskell mode command +;;(global-set-key "\C-cb" 'org-iswitchb) + + + +;; org-src-tab-acts-natively t ; broken option. using next instead, todo fix + +(setq org-src-fontify-natively t ; make babel blocks nice + org-adapt-indentation nil + org-src-preserve-indentation t + ;; The most basic logging is to keep track of when a TODO item was finished. + org-log-done 'time + ;; use a drawer to keep the logs tidy + org-log-into-drawer t + org-extend-today-until 0 + org-startup-truncated nil + org-clock-persist t + org-clock-mode-line-total 'today + ;; global STYLE property values for completion + org-global-properties (quote (("STYLE_ALL" . "habit"))) + org-special-ctrl-a/e t ;; home and end work special in headlines + org-completion-use-ido t + org-catch-invisible-edits 'smart) + +;; non universally recommended settings +(setq + org-default-notes-file (concat org-directory "/a/t.org") + org-agenda-files (quote ("/a/t.org")) + org-mobile-directory "/p/org-mobile" + org-mobile-inbox-for-pull "/p/from-mobile.org" + org-directory "/p") + +;; modeilne populated from (org-clock-get-clocked-time) +;; which is populated from the var org-clock-total-time +;; which is populated by a function which starts from (org-clock-get-sum-start) +;; + +(org-clock-persistence-insinuate) + + +(defun time-to-org-day (time) + (round (time-to-number-of-days + (time-subtract time (list 0 (* 3600 org-extend-today-until) 0))))) + + +(defun my-org-confirm-babel-evaluate (lang body) + (not (or (string= (buffer-file-name) "/a/t.org") + (string= (buffer-file-name) "/home/iank/.emacs.d/my-init.org") + ))) +(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate) + + +(defun org-time-stamp-with-time (arg) + (interactive "P") + ;; '(4) is the argument passed by universal prefix + (org-time-stamp (if arg arg '(4)) t)) + +(defun ian-org-work-time () + (interactive) + (save-excursion + (set-buffer "t.org") + (goto-char (org-find-entry-with-id "ian-identifier-1")) + (org-clock-in))) + +(defun ian-org-idle-time () + (interactive) + (save-excursion + (goto-char (org-find-entry-with-id "ian-identifier-2")) + (set-buffer "t.org") + (org-clock-in))) + + + +;; based on http://stackoverflow.com/questions/3758139/variable-pitch-for-org-mode-fixed-pitch-for-tables +;; keywords: proportional font, monospace + +(defun variable-pitch-on () + (variable-pitch-mode 1)) +(add-hook 'fundamental-mode-hook 'variable-pitch-on) +(add-hook 'org-mode-hook 'variable-pitch-on) +(add-hook 'text-mode-hook 'variable-pitch-on) +(defun variable-pitch-off () + (variable-pitch-mode 0)) +(add-hook 'yaml-mode-hook 'variable-pitch-off) + + +(set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family)) +(set-face-attribute 'org-code nil :family (face-attribute 'fixed-pitch :family)) +(set-face-attribute 'org-formula nil :family (face-attribute 'fixed-pitch :family)) +(set-face-attribute 'org-link nil :family (face-attribute 'fixed-pitch :family)) +(set-face-attribute 'org-block nil :family (face-attribute 'fixed-pitch :family)) +(set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family)) + + +(defun remove-org-binds () + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "C-'") nil) + (define-key org-mode-map (kbd "C-y") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "C-,") nil) + (define-key org-mode-map (kbd "C-M-m") nil) + (define-key org-mode-map (kbd "C-k") nil) + (define-key org-mode-map (kbd "C-j") nil) + (define-key org-mode-map (kbd "C-M-i") nil) + (define-key org-mode-map (kbd "C-M-t") nil) + (define-key org-mode-map (kbd "M-a") 'nil) + (define-key org-mode-map (kbd "C-a") nil) + (define-key org-mode-map (kbd "M-e") nil) + (define-key org-mode-map (kbd "C-e") nil) + (define-key org-mode-map (kbd "C-3") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map (kbd "") nil) + (define-key org-mode-map "\t" nil)) +(add-hook 'org-mode-hook 'remove-org-binds) + +;;; prog-mode-defaults + + +(defun prog-mode-defaults () + "Default coding hook, useful with any programming language." + ;; so that I can do completion before the dialog pops up + (local-set-key (kbd "") 'auto-complete) + ;; todo, this is causing error message on loading file, prolly not working + ;;(flycheck-mode +1) + (setq ac-sources (delq 'ac-source-dictionary ac-sources)) + (highlight-symbol-mode) + (make-local-variable 'column-number-mode) + ;; this says do autofilling using newcomment.el. The "only" is a misnomer. + (set (make-local-variable 'comment-auto-fill-only-comments) t) + (column-number-mode t) + (turn-on-smartparens-mode) + + ;; prettify lambdas + (font-lock-add-keywords + nil `(("(\\(lambda\\>\\)" + (0 (progn (compose-region (match-beginning 1) (match-end 1) + ,(make-char 'greek-iso8859-7 107)) + nil)))))) +(add-hook 'prog-mode-hook 'prog-mode-defaults) + +;; enable flyspell in prog mode. text mode is handled +(add-hook 'prog-mode-hook 'flyspell-prog-mode) + + + +;;; yank auto-indent +;; automatically indenting yanked text if in programming-modes +(defvar yank-indent-modes + '(LaTeX-mode TeX-mode) + "Modes in which to indent regions that are yanked (or yank-popped). +Only modes that don't derive from `prog-mode' should be listed here.") + +(defvar yank-indent-blacklisted-modes + '(python-mode slim-mode haml-mode) + "Modes for which auto-indenting is suppressed.") + +(defvar yank-advised-indent-threshold 2000 + "Threshold (# chars) over which indentation does not automatically occur.") + +(defun yank-advised-indent-function (beg end) + "Do indentation, as long as the region isn't too large." + (if (<= (- end beg) yank-advised-indent-threshold) + (indent-region beg end nil))) + +(defadvice yank (after yank-indent activate) + "If current mode is one of 'yank-indent-modes, +indent yanked text (with prefix arg don't indent)." + (if (and (not (ad-get-arg 0)) + (not (member major-mode yank-indent-blacklisted-modes)) + (or (derived-mode-p 'prog-mode) + (member major-mode yank-indent-modes))) + (let ((transient-mark-mode nil)) + (yank-advised-indent-function (region-beginning) (region-end))))) + +(defadvice yank-pop (after yank-pop-indent activate) + "If current mode is one of 'yank-indent-modes, +indent yanked text (with prefix arg don't indent)." + (if (and (not (ad-get-arg 0)) + (not (member major-mode yank-indent-blacklisted-modes)) + (or (derived-mode-p 'prog-mode) + (member major-mode yank-indent-modes))) + (let ((transient-mark-mode nil)) + (yank-advised-indent-function (region-beginning) (region-end))))) + + +;;; shell mode +;; avoid stupid git crap like "warning, terminal not fully functional" +(setenv "PAGER" "cat") +;; don't store successive duplicates in comint command history +(setq comint-input-ignoredups t) + +(defun add-mode-line-dirtrack () + (add-to-list 'mode-line-buffer-identification + '(:propertize (" " default-directory " ") face dired-directory))) +(add-hook 'shell-mode-hook 'add-mode-line-dirtrack) + + +;; don't fully understand it, but it works. +;; http://www.emacswiki.org/emacs/ShellDirtrackByProcfs +(defun track-shell-directory/procfs () + (shell-dirtrack-mode 0) + (add-hook 'comint-preoutput-filter-functions + (lambda (str) + (prog1 str + (when (string-match comint-prompt-regexp str) + (cd (file-symlink-p + (format "/proc/%s/cwd" (process-id + (get-buffer-process + (current-buffer))))))))) + nil t)) +(setq comint-buffer-maximum-size 100000) +(add-to-list 'comint-output-filter-functions 'comint-truncate-buffer) +(defun new-shell () + (interactive) + (shell (generate-new-buffer-name "*shell*"))) +;; +(defun shell-wrap (prefix) + "wrap the shell function, automatically generate a new name for a prefix arg" + (interactive "P") + (if prefix + (new-shell) + (shell))) + +(add-hook 'shell-mode-hook 'track-shell-directory/procfs) +;;; smartparens +;; the melpa git version had a catastrophic bug I reported. +;; downgraded to marmalade version and everything is working fine. +(require 'smartparens-config) +(show-smartparens-global-mode t) + + +(defun gp/sp/pair-on-newline-and-indent (id action context) + "Open a new brace or bracket expression, with relevant newlines and indent. " + (save-excursion + (newline) + (indent-according-to-mode)) + (indent-according-to-mode)) + +;; when opening a pair, and then inserting a newline, push the closing pair to another newline +(sp-pair "{" nil :post-handlers + '(:add ((lambda (id action context) + (gp/sp/pair-on-newline-and-indent id action context)) (kbd "")))) +(sp-pair "[" nil :post-handlers + '(:add ((lambda (id action context) + (gp/sp/pair-on-newline-and-indent id action context)) (kbd "")))) + + +;; in my version, this is not a pairing. +;; not sure if it is in a future version since I reverted to marmalade +;; Don't need c-comments in strings -- they frustrate filename globs +;; (sp-pair "/*" nil :unless '(sp-in-string-p)) + +;; Don't need quotes to pair next to words +(sp-pair "\"" nil :unless '(sp-point-before-word-p sp-point-after-word-p)) +(sp-pair "'" nil :unless '(sp-point-before-word-p sp-point-after-word-p)) + + +;; todo, testout these mode specific settings from graphene. +;; Ruby-specific pairs and handlers +(require 'smartparens-ruby) + +;; Markdown +(sp-local-pair '(markdown-mode gfm-mode) "*" "*" + :unless '(sp-in-string-p) + :actions '(insert wrap)) + +;; Except in HTML +(sp-local-pair 'html-mode "\"" nil :unless '(:rem sp-point-after-word-p)) + + +;;; smex +;; todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings. + ; these must be before smex-initialize +(setq + smex-save-file "~/.emacs.d/.smex-items") + +(smex-initialize) +;;; spell correction +(setq + ispell-program-name "hunspell" + ispell-silently-savep t) ; don't prompt to save personal dictionary + +(require 'rw-hunspell) +;; rw-hunspell sets up hunspell dictionary automagically. + + +;; Rant: Hunspell SHOULD be standard. its used by firefox and openoffice and +;; osx. In contrast, the first few words I added to aspell dictionary were +;; "emacs" "customizable" and "timestamp". Hunspell already has those, +;; thank god. + +;; ispell-personal-dictionary does not document where the hunspell +;; dictionary goes by default, but it is ~/.hunspell_en_US for me + + +;;; tex +(setq-default TeX-PDF-mode t) ; use pdf + + ; more sensible defaults based on info manual quickstart +(setq TeX-auto-save t) +(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 + +;; since it is not easy to change the mark overlay priority, I change this one. +(setq show-paren-priority 999) + + +(defface visible-mark-active + '((((type tty) (class mono))) + (t (:background "magenta"))) "") + + + +(defface mouse-cursor-face + '((((type tty) (class mono))) + (t (:background "DeepPink1"))) "") + + +(require 'visible-mark) + +(setq visible-mark-faces '(visible-mark-face1 visible-mark-face2)) +(setq visible-mark-forward-faces '(visible-mark-forward-face1)) + + + ; highlight the last 2 marks +(setq visible-mark-max 2) + ; highlight 1 forward mark +(setq visible-mark-forward-max 1) + ; globally activate visible-mark-mode +(global-visible-mark-mode +1) + + +;; todo, it doesn't seem to be exposed in elisp, but it would be nice +;; if I could define overlay faces to use inverse foreground color + + +;;; zrc +(require 'znc) +(setq erc-fill-prefix "") +(defun chirp() + (interactive) + (setq vol 50) + (when (string= (system-name) "tp") (setq vol 40)) + (start-process-shell-command "ignoreme" nil (format "mpv --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol))) +;; from https://www.emacswiki.org/emacs/ErcSound + +(defun erc-my-privmsg-sound (proc parsed) + (let* ((tgt (car (erc-response.command-args parsed))) + (privp (erc-current-nick-p tgt))) + (and + privp (chirp) + ;; We must return nil. See help for `erc-server-PRIVMSG-functions' + nil))) + +(add-hook 'erc-server-PRIVMSG-functions + 'erc-my-privmsg-sound) + +(defun erc-sound-if-not-server (match-type nickuserhost msg) + (unless (string-match "Server:[0-9]+" nickuserhost) + (chirp))) +(add-hook 'erc-text-matched-hook 'erc-sound-if-not-server) + +(erc-track-mode 1) +(setq + ;; consider invisible frames to be unseen. seems like an obvious default + erc-track-visibility 'visible + ;; switch to buffer where i've been mentioned, etc instead of oldest + erc-track-switch-direction 'importance) + + +;;; 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. + +;; I'm using persistent registers instead of bookmarks. I dun use them +;; much, so the added hassle of having to set it within this file is +;; worth the benefit of only having one concept in my mind. +(dolist + (r `( + (?i (file . ,"~/.emacs.d/my-init.org")) + (?t (file . ,"/a/x.txt")) + )) + (set-register (car r) (cadr r))) -- 2.30.2