From d85a959b4e0d1ab2f70fbd1e25fe2c35faa1b433 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Wed, 27 Nov 2013 01:37:25 +0100 Subject: Do away with literate programming --- .emacs.d/init.el | 198 ++++++++++++++++++++- .emacs.d/init.org | 504 ------------------------------------------------------ 2 files changed, 196 insertions(+), 506 deletions(-) delete mode 100644 .emacs.d/init.org (limited to '.emacs.d') diff --git a/.emacs.d/init.el b/.emacs.d/init.el index 3f1a90d..9a60f81 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -2,9 +2,203 @@ ;;; Commentary: ;;; Code: +(defmacro stante-after (feature &rest forms) + "After FEATURE is loaded, evaluate FORMS. + +FEATURE may be an unquoted feature symbol or a file name, see +`eval-after-load'." + (declare (indent 1) (debug t)) + ;; Byte compile the body. If the feature is not available, ignore + ;; warnings. Taken from + ;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2012-11/msg01262.html + (let ((loaded (if (symbolp feature) + (require feature nil :no-error) + (load feature :no-error :no-message)))) + `(,(if loaded + 'progn + (message "stante-after: cannot find %s" feature) + 'with-no-warnings) + (eval-after-load ',feature + `(funcall (function ,(lambda () ,@forms))))))) + +(defmacro eval-after-init (&rest body) + "Defer execution of BODY until after Emacs init." + (declare (indent 0)) + `(add-hook 'emacs-startup-hook #'(lambda () ,@body))) + (eval-and-compile - (add-to-list 'load-path user-emacs-directory) - (load "init2")) + (defun loadpath-add-and-autoload (path) + "Add PATH to `load-path' and load a `loaddefs.el' if it exists." + (add-to-list 'load-path path) + (let ((loaddefs (concat path "/loaddefs.el"))) + (when (file-exists-p loaddefs) + (load loaddefs)))) + + (mapc #'loadpath-add-and-autoload + '("~/.emacs.d/site-lisp" "~/projects/emacs/pony-mode/src" + "~/.emacs.d/vendor-lisp/org/lisp" + "~/.emacs.d/vendor-lisp/org/contrib/lisp" + "~/.emacs.d/vendor-lisp/mozrepl" + "~/.emacs.d/vendor-lisp/eap" "/usr/share/emacs/site-lisp"))) + +(defalias 'yes-or-no-p 'y-or-n-p) + +(defalias 'list-buffers 'ibuffer) + +(defalias 'dabbrev-expand 'hippie-expand) + +(require 'uniquify) + +(stante-after uniquify + (setq uniquify-buffer-name-style 'post-forward)) + +(defvar gnus-init-file) +(setq gnus-init-file "~/.emacs.d/site-lisp/gnus-init") + +(defmacro turn-off (&rest modes) + "Turn off each mode in MODES." + `(progn ,@(mapcar (lambda (m) `(,m -1)) modes))) + +(turn-off menu-bar-mode scroll-bar-mode tool-bar-mode blink-cursor-mode + column-number-mode line-number-mode tooltip-mode) + +(let ((theme (if (equal system-name "drd") + 'yoshi + 'leuven))) + (let ((setp (not (daemonp)))) + (defun init-set-theme (frame) + "Try to set the theme for the current (first) frame." + (ignore frame) + (unless setp + (run-at-time .1 nil (lambda () (setq setp (load-theme theme t))))))) + + (if (daemonp) + (add-hook 'after-make-frame-functions #'init-set-theme) + (eval-after-init (load-theme theme t)))) + +(setq eww-download-path "~/downloads/") + +(defun init-locally-enable-double-spaces () + (setq-local sentence-end-double-space t)) + +(add-hook 'emacs-lisp-mode-hook #'init-locally-enable-double-spaces) + +(defun init-set-emacs-lisp-symbols () + (when (boundp 'prettify-symbols-alist) + (setq prettify-symbols-alist + (append prettify-symbols-alist + '(("<=" . ?≤) + (">=" . ?≥) + ("sqrt" . ?√)))))) + +(add-hook 'emacs-lisp-mode-hook #'init-set-emacs-lisp-symbols) + +(defun init-set-python-symbols () + (when (boundp 'prettify-symbols-alist) + (setq prettify-symbols-alist + '(("lambda" . ?λ) + ("<=" . ?≤) + (">=" . ?≥) + ("!=" . ?≠))))) + +(add-hook 'python-mode-hook #'init-set-python-symbols) + +(when (and (>= emacs-major-version 24) + (> emacs-minor-version 3)) + (add-hook 'prog-mode-hook 'prettify-symbols-mode)) + +(stante-after slime + (setq slime-lisp-implementations + '((sbcl ("sbcl" "--noinform") :coding-system utf-8-unix) + (clisp ("clisp") :coding-system utf-8-unix)) + slime-default-lisp 'sbcl)) + +(set-fontset-font "fontset-default" 'unicode + (font-spec :family "Liberation Mono" + :width 'normal + :size 12.4 + :weight 'normal)) + +(defun sort-imports () + (interactive) + (save-excursion + (sort-lines nil (1+ (search-backward "(")) + (1- (search-forward ")"))))) + +(stante-after simple + (define-key special-mode-map "z" #'kill-this-buffer)) + +(defvar init-stumpish-program + (expand-file-name + "~/.local/share/quicklisp/local-projects/stumpwm/contrib/stumpish") + "The location of the stumpish executable.") + +(defun stumpwm-command (cmd) + "Execute CMD in stumpwm." + (call-process init-stumpish-program nil nil nil cmd)) + +(defadvice windmove-do-window-select + (around init-windmove-stumpwm activate) + "If no window can be moved to, move stumpwm." + (condition-case err + ad-do-it + (error (stumpwm-command (format "move-focus %s" (ad-get-arg 0)))))) + +(defmacro stumpwm (&rest body) + "Execute BODY in stumpwm." + (declare (indent 0)) + `(call-process init-stumpish-program nil nil nil + ,(format "eval '%S'" `(progn ,@body)))) + +(global-set-key (kbd "C-c S") #'split-window-right) +(global-set-key (kbd "C-c s") #'split-window-below) +(global-set-key (kbd "C-c Q") #'delete-other-windows) +(global-set-key (kbd "C-c R") #'delete-window) + +(add-to-list 'load-path "/usr/lib/node_modules/tern/emacs/") +(autoload 'tern-mode "tern" nil t) + +(stante-after tern + (require 'tern-auto-complete) + (tern-ac-setup)) + +(add-hook 'js2-mode-hook #'tern-mode) + +(defun init-switch-to-other-buffer () + "Switch to the most recently viewed buffer." + (interactive) + (switch-to-buffer (other-buffer))) + +(global-set-key (kbd "C-. C-.") #'init-switch-to-other-buffer) + +(stante-after woman + (setq woman-fill-column 72)) + +(add-hook 'c-mode-hook #'smartparens-strict-mode) + +(autoload 'moz-minor-mode "moz" nil t) +(add-hook 'javascript-mode-hook 'moz-minor-mode) + +(defun change-number-at-point (change-func) + "Use CHANGE-FUNC to change the number at `point'." + (let ((num (number-to-string (funcall change-func (number-at-point)))) + (bounds (bounds-of-thing-at-point 'word))) + (save-excursion + (delete-region (car bounds) (cdr bounds)) + (insert num)))) + +(defun decrease-number-at-point () + "Take the number at `point' and replace it with it decreased by 1." + (interactive) + (change-number-at-point #'1-)) + +(defun increase-number-at-point () + "Take the number at `point' and replace it with it increased by 1." + (interactive) + (change-number-at-point #'1+)) + +(global-set-key (kbd "C-c -") #'decrease-number-at-point) +(global-set-key (kbd "C-c +") #'increase-number-at-point) (eval-when-compile (package-initialize) diff --git a/.emacs.d/init.org b/.emacs.d/init.org deleted file mode 100644 index 1f37c7b..0000000 --- a/.emacs.d/init.org +++ /dev/null @@ -1,504 +0,0 @@ -# -*- ispell-local-dictionary: "en"; -*- -#+TITLE: Emacs init -#+HTML_HEAD: -#+OPTIONS: num:nil toc:nil -#+PROPERTY: tangle init2.el -#+STARTUP: showall - -* First things first: Lexical binding - - To make sure that the code in this file follows the correct rules, - make sure it uses lexical binding. - - #+BEGIN_SRC emacs-lisp :padline no - ;;; -*- lexical-binding: t -*- - #+END_SRC - -* Improved eval-after-load - - A lot of the options and functionality isn't necessary until a - certain package has been loaded. So in order to keep start-up as - fast as possible, while still taking advantage of byte-compiling - everything, I wrap most settings in the following macro, which is - explained [[http://lunaryorn.com/2013/05/31/byte-compiling-eval-after-load/][here]]. - - #+BEGIN_SRC emacs-lisp - (defmacro stante-after (feature &rest forms) - "After FEATURE is loaded, evaluate FORMS. - - FEATURE may be an unquoted feature symbol or a file name, see - `eval-after-load'." - (declare (indent 1) (debug t)) - ;; Byte compile the body. If the feature is not available, ignore - ;; warnings. Taken from - ;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2012-11/msg01262.html - (let ((loaded (if (symbolp feature) - (require feature nil :no-error) - (load feature :no-error :no-message)))) - `(,(if loaded - 'progn - (message "stante-after: cannot find %s" feature) - 'with-no-warnings) - (eval-after-load ',feature - `(funcall (function ,(lambda () ,@forms))))))) - #+END_SRC - -* Executing things after initialization has finished - - Some functionality, for example everything loaded with ~package.el~, - is only available after the initialization process has finished. So - code that requires ~package.el~ packages to be available or other - things that the initialization process does to be done should only - be executed after initialization has finished. The - =emacs-startup-hook= is good for this. This also seems more efficient - than using =(package-initialize)=. - - #+BEGIN_SRC emacs-lisp - (defmacro eval-after-init (&rest body) - "Defer execution of BODY until after Emacs init." - (declare (indent 0)) - `(add-hook 'emacs-startup-hook #'(lambda () ,@body))) - #+END_SRC - -* Preparing the load-path - - For anything that isn't loaded with ~package.el~ (like a manually - installed ~org-mode~) its directory should be in =load-path=. If there - happens to be a ~loaddefs.el~ in that same directory, load it so that - it can add some autoloads. These directories contain manually - installed packages, my local ~site-lisp~ directory and any project - directories for projects which I (occasionally) work on. - - All of it is put in an =eval-and-compile= block so it is run both at - compile-time and run-time, since it is necessary to properly compile - my init file as well. - - #+BEGIN_SRC emacs-lisp - (eval-and-compile - (defun loadpath-add-and-autoload (path) - "Add PATH to `load-path' and load a `loaddefs.el' if it exists." - (add-to-list 'load-path path) - (let ((loaddefs (concat path "/loaddefs.el"))) - (when (file-exists-p loaddefs) - (load loaddefs)))) - - (mapc #'loadpath-add-and-autoload - '("~/.emacs.d/site-lisp" "~/projects/emacs/pony-mode/src" - "~/.emacs.d/vendor-lisp/org/lisp" - "~/.emacs.d/vendor-lisp/org/contrib/lisp" - "~/.emacs.d/vendor-lisp/mozrepl" - "~/.emacs.d/vendor-lisp/eap" "/usr/share/emacs/site-lisp"))) - #+END_SRC - -* Speeding up yes/no questions - - Typing ~yes~ or ~no~ when just ~y~ or ~n~ would suffice seems unnecessary. - I've been using it almost as long as Emacs and I haven't had any - accidents yet. - - #+BEGIN_SRC emacs-lisp - (defalias 'yes-or-no-p 'y-or-n-p) - #+END_SRC - -* Getting a more feature-full buffer list - - ~ibuffer~ has a lot more features than regular =list-buffers=, plus does - everything =list-buffers= does. - - #+BEGIN_SRC emacs-lisp - (defalias 'list-buffers 'ibuffer) - #+END_SRC - -* Getting more feature-full text-completion - - One of the completion mechanisms of =hippie-expand= is a ~dabbrev~ based - expansion, so it should do everything =dabbrev-expand= does, plus - more. It also doesn't use =dabbrev-expand= directly, so it shouldn't - be a problem to switch them. - - #+BEGIN_SRC emacs-lisp - (defalias 'dabbrev-expand 'hippie-expand) - #+END_SRC - -* Making buffer names unique and understandable - - The problem with the default way of making buffer names unique is - that it doesn't tell me anything about what makes them unique. I - don't know what makes ~init.el<1>~ different from ~init.el<2>~. However, - seeing it as, for example, ~init.el|.emacs.d~ and ~init.el|dotemacs~ - tells me a lot more. - - #+BEGIN_SRC emacs-lisp - (require 'uniquify) - - (stante-after uniquify - (setq uniquify-buffer-name-style 'post-forward)) - #+END_SRC - -* Telling gnus where to look for its initialization file - - I prefer to keep everything in my =~/.emacs.d/= directory, so =~/.gnus= - wouldn't work with that. To silence a compiler warning I define a - "vacuous" variable first, so Emacs knows the name is defined. I - don't specify an ~init-value~ with the =defvar= so that if it happens to - already be defined, =setq= will still change it (=defvar= won't). - - #+BEGIN_SRC emacs-lisp - (defvar gnus-init-file) - (setq gnus-init-file "~/.emacs.d/site-lisp/gnus-init") - #+END_SRC - -* Clean up the UI - - There are things, like a blinking cursor, a menu bar, etc. that I - just don't need, so I want to turn them off. Since they all have the - same API, just loop through the symbols and turn each off. - - #+BEGIN_SRC emacs-lisp - (defmacro turn-off (&rest modes) - "Turn off each mode in MODES." - `(progn ,@(mapcar (lambda (m) `(,m -1)) modes))) - - (turn-off menu-bar-mode scroll-bar-mode tool-bar-mode blink-cursor-mode - column-number-mode line-number-mode tooltip-mode) - #+END_SRC - -* Loading a theme at the correct time - - A problem with loading some themes immediately at start-up, while - using the ~--daemon~ switch is that there is no guarantee that it will - ever use a window system, so it's like starting from the terminal. - This may affect the colors of some themes. - - To get around this I use =lexical-binding= (because I'm not sure - dynamic binding will work here) and create a closure that tracks if - I've set the theme, so it doesn't reset it every time a new frame is - created. Then I have this executed one tenth of a second after a - frame is created, at which point there should be a window system and - colors should be correct. - - One more problem is that when starting Emacs without the ~--daemon~ - switch the =after-make-frame-functions= aren't run, so if we're not - running a daemon, just set the theme. - - #+BEGIN_SRC emacs-lisp - (let ((theme (if (equal system-name "drd") - 'yoshi - 'leuven))) - (let ((setp (not (daemonp)))) - (defun init-set-theme (frame) - "Try to set the theme for the current (first) frame." - (ignore frame) - (unless setp - (run-at-time .1 nil (lambda () (setq setp (load-theme theme t))))))) - - (if (daemonp) - (add-hook 'after-make-frame-functions #'init-set-theme) - (eval-after-init (load-theme theme t)))) - #+END_SRC - -* Browsing with eww - - =eww= is a very cool project, but I don't like where it downloads things. - - #+BEGIN_SRC emacs-lisp - (setq eww-download-path "~/downloads/") - #+END_SRC - -* Double space to end a sentence in Emacs Lisp - - The Emacs Lisp syntax checker is hell-bent on forcing me to use a - double space at the end of sentences in comments and docstrings. - Fine, then I will use double spaces in Emacs Lisp. - - #+BEGIN_SRC emacs-lisp - (defun init-locally-enable-double-spaces () - (setq-local sentence-end-double-space t)) - - (add-hook 'emacs-lisp-mode-hook #'init-locally-enable-double-spaces) - #+END_SRC - -* Show pretty symbols - - Emacs lisp has the default of showing ~lambda~ as ~λ~. I also want to - show ~<=~ as ~≤~, ~>=~ as ~≥~ and ~sqrt~ as ~√~. - - #+BEGIN_SRC emacs-lisp - (defun init-set-emacs-lisp-symbols () - (when (boundp 'prettify-symbols-alist) - (setq prettify-symbols-alist - (append prettify-symbols-alist - '(("<=" . ?≤) - (">=" . ?≥) - ("sqrt" . ?√)))))) - - (add-hook 'emacs-lisp-mode-hook #'init-set-emacs-lisp-symbols) - #+END_SRC - - Aside from Emacs lisp, I would also like to show most of these in - Python. Though the ~sqrt~ doesn't seem applicable, I do want to show - ~!=~ as ~≠~ here. - - #+BEGIN_SRC emacs-lisp - (defun init-set-python-symbols () - (when (boundp 'prettify-symbols-alist) - (setq prettify-symbols-alist - '(("lambda" . ?λ) - ("<=" . ?≤) - (">=" . ?≥) - ("!=" . ?≠))))) - - (add-hook 'python-mode-hook #'init-set-python-symbols) - #+END_SRC - - Now just turn it on for =prog-mode=. - - #+BEGIN_SRC emacs-lisp - (when (and (>= emacs-major-version 24) - (> emacs-minor-version 3)) - (add-hook 'prog-mode-hook 'prettify-symbols-mode)) - #+END_SRC - -* Slime implementations - - I usually use [[http://sbcl.org][SBCL]], but sometimes also [[http://www.clisp.org/][GNU CLISP]]. - - #+BEGIN_SRC emacs-lisp - (stante-after slime - (setq slime-lisp-implementations - '((sbcl ("sbcl" "--noinform") :coding-system utf-8-unix) - (clisp ("clisp") :coding-system utf-8-unix)) - slime-default-lisp 'sbcl)) - #+END_SRC - -* Use Liberation Mono font for unicode - - [[http://paratype.com/public/][PT Mono]] is a very nice font, but is misses some unicode characters I - would like to use. [[https://www.redhat.com/promo/fonts/][Liberation Mono]] on the other hand does seem to - contain these characters, so I use that for any unicode fonts. - - #+BEGIN_SRC emacs-lisp - (set-fontset-font "fontset-default" 'unicode - (font-spec :family "Liberation Mono" - :width 'normal - :size 12.4 - :weight 'normal)) - #+END_SRC - -* A command to sort python includes - - At work I use Python. Our project is getting bigger and bigger, - import statements are growing. We use the following style: - - #+BEGIN_SRC python :tangle no - from somemodule import ( - Class1, - Class2, - Class3, - ) - #+END_SRC - - Which we found to be one of the better-looking ways to handle - multi-line import statements. To sort these lines I wrote a very - simplistic (and error-prone, but I'll handle it when I get to it) - command. - - All it does is save the current point, searches backwards for a ~(~, - then forwards for a ~)~ and sorts the region in between (not - including) the ~()~. - - #+BEGIN_SRC emacs-lisp - (defun sort-imports () - (interactive) - (save-excursion - (sort-lines nil (1+ (search-backward "(")) - (1- (search-forward ")"))))) - #+END_SRC - -* Bring back the z! - - One or two versions of Emacs ago it was decided that the ~z~ character - was too easy to press accidentally, killing the current buffer if it - was based on =special-mode=. I disagree. I don't like the fact that - using ~q~ leaves the buffers open, usually I want to kill the buffers - when I'm done with them, though not always. So I want back my ~z~! - - I don't, however, want to overwrite the ~z~ key in, say, =magit=, so I - define it in the =special-mode-map= so it only gets redefined if modes - based on =special-mode= don't rebind it themselves. - - #+BEGIN_SRC emacs-lisp - (stante-after simple - (define-key special-mode-map "z" #'kill-this-buffer)) - #+END_SRC - -* Falling back to WM to switch windows - - Emacs and any window manager have a difference op opinion on what - windows are. It doesn't have to matter, Emacs can manage its windows - and stumpwm can do the rest. When moving around with ~windmove~ and it - finds that there's no way to move in that direction, let stumpwm do - it. - - First we have to know where the stumpish program is. SLIME could - also be used, but calling stumpish might be easier for now. - - #+BEGIN_SRC emacs-lisp - (defvar init-stumpish-program - (expand-file-name - "~/.local/share/quicklisp/local-projects/stumpwm/contrib/stumpish") - "The location of the stumpish executable.") - #+END_SRC - - Now that we know that, we should have an easy way to send stuff to - it. - - #+BEGIN_SRC emacs-lisp - (defun stumpwm-command (cmd) - "Execute CMD in stumpwm." - (call-process init-stumpish-program nil nil nil cmd)) - #+END_SRC - - And then we can advise =windmove-do-window-select=, so that when it - finds there are no more windows to move to, it asks stumpwm to move - in the same direction. - - #+BEGIN_SRC emacs-lisp - (defadvice windmove-do-window-select - (around init-windmove-stumpwm activate) - "If no window can be moved to, move stumpwm." - (condition-case err - ad-do-it - (error (stumpwm-command (format "move-focus %s" (ad-get-arg 0)))))) - #+END_SRC - - Now, whenever I try to move out of my Emacs windows, it just moves - to the next X11 window, whatever it might be. My stumpwm config has - a matching command that checks to see if the current window is - Emacs, and if so sends the ~S-~ key to Emacs, which in turn - calls stumpwm when it can't (getting a little crazy here). - - I also wrote a simplistic macro to execute some stumpwm lisp in - Emacs. - - #+BEGIN_SRC emacs-lisp - (defmacro stumpwm (&rest body) - "Execute BODY in stumpwm." - (declare (indent 0)) - `(call-process init-stumpish-program nil nil nil - ,(format "eval '%S'" `(progn ,@body)))) - #+END_SRC - - Which is pretty much the same as my =elisp= macro in my stumpwm - config. - -* Simplify window management in Emacs - - stumpwm uses ~ S~, ~ s~, ~ Q~ and ~ R~ to - split horizontally, split vertically, remove all but the focused - frame and remove the current frame. Somehow that seems easier than - Emacs' ~C-x 3~, ~C-x 2~, ~C-x 1~ and ~C-x 0~. Just because ~S~, ~s~, ~Q~ and ~R~ are - easier to reach, even though three of the four need a modifier key. - - #+BEGIN_SRC emacs-lisp - (global-set-key (kbd "C-c S") #'split-window-right) - (global-set-key (kbd "C-c s") #'split-window-below) - (global-set-key (kbd "C-c Q") #'delete-other-windows) - (global-set-key (kbd "C-c R") #'delete-window) - #+END_SRC - -* Use ternjs for javascript development - - Ternjs seems like an interesting project. Add its location to the - =load-path=, autoload it and after it loads setup the auto-complete - functionality. - - #+BEGIN_SRC emacs-lisp - (add-to-list 'load-path "/usr/lib/node_modules/tern/emacs/") - (autoload 'tern-mode "tern" nil t) - - (stante-after tern - (require 'tern-auto-complete) - (tern-ac-setup)) - #+END_SRC - -* Turn on tern for javascript - - Torn on tern when working in =js2-mode=. It adds eldoc-like - functionality and autocompletion. - - #+BEGIN_SRC emacs-lisp - (add-hook 'js2-mode-hook #'tern-mode) - #+END_SRC - -* Switch to most recent buffer - - Like GNU Screen has the =C-a C-a= (at least with a =C-a= prefix) - combination and stumpwm has =C-z C-z= (at least with a =C-z= prefix) I - really need to be able to switch between the two most recently - viewed buffers easily. - - #+BEGIN_SRC emacs-lisp - (defun init-switch-to-other-buffer () - "Switch to the most recently viewed buffer." - (interactive) - (switch-to-buffer (other-buffer))) - - (global-set-key (kbd "C-. C-.") #'init-switch-to-other-buffer) - #+END_SRC - -* Fill lines to 72 columns when using woman - - It's a little bit nicer to read that way, 65 characters on a line is - a little small. - - #+BEGIN_SRC emacs-lisp - (stante-after woman - (setq woman-fill-column 72)) - #+END_SRC - -* Turn on smartparens for C coding - - C is not as well-structured as Lisp, but it still has a lot of - braces, brackets and other things. - - #+BEGIN_SRC emacs-lisp - (add-hook 'c-mode-hook #'smartparens-strict-mode) - #+END_SRC - -* Autoload and start moz-minor-mode - - When using javascript, mozrepl is awesome. - - #+BEGIN_SRC emacs-lisp - (autoload 'moz-minor-mode "moz" nil t) - (add-hook 'javascript-mode-hook 'moz-minor-mode) - #+END_SRC - -* Change numbers at point - - Sometimes you just want to increase or decrease the number under the - cursor, no fuss. - - #+BEGIN_SRC emacs-lisp - (defun change-number-at-point (change-func) - "Use CHANGE-FUNC to change the number at `point'." - (let ((num (number-to-string (funcall change-func (number-at-point)))) - (bounds (bounds-of-thing-at-point 'word))) - (save-excursion - (delete-region (car bounds) (cdr bounds)) - (insert num)))) - - (defun decrease-number-at-point () - "Take the number at `point' and replace it with it decreased by 1." - (interactive) - (change-number-at-point #'1-)) - - (defun increase-number-at-point () - "Take the number at `point' and replace it with it increased by 1." - (interactive) - (change-number-at-point #'1+)) - - (global-set-key (kbd "C-c -") #'decrease-number-at-point) - (global-set-key (kbd "C-c +") #'increase-number-at-point) - #+END_SRC -- cgit v1.2.3-54-g00ecf