structure in layers

This commit is contained in:
Jean-Philippe Bernardy 2016-08-31 21:58:55 +02:00
parent d753df2dc1
commit 86c040b54f
13 changed files with 605 additions and 526 deletions

View file

@ -1,20 +1,20 @@
Boon: An Ergonomic Command Mode for Emacs
==========================================
Boon is another package for modal editing.
Boon is a complete package for modal editing, which is not Evil.
Selling points:
- Ergonomic: common commands are easy to type. (See below)
- Lightweight: ~300 loc for its core.
- Good emacs integration: takes advantage of, and leverages existing
emacs infrastructure instead of re-inventing the wheel.
- Good Emacs integration: integrates with existing Emacs
infrastructure and takes advantage of it.
Design
------
Ergonomic Design
----------------
It is largely accepted that modal edition is more ergonomic than using
keychord. Boon attempts to make modal editing as comfortable as
key-chords. Boon attempts to make modal editing as comfortable as
possible, by adhering to the following design principles:
- Spacial allocation first, mnemonics second: the allocation of keys
@ -49,20 +49,53 @@ manipulation) are bound to the home row. The top row is (mainly) for
searching. The bottom row gives access to regular Emacs stuff (C-x
...) (C-c ...) and registers.
Emacs Integration: Reusable Modules
-----------------------------------
Boon is designed as a layer of modules, which are reusable and
customizable, in full agreement with the Emacs spirit. This means that
even if you disagree with the frontend choices made above, you may
still want to use parts of Boon, as these are re-usable.
1. boon-moves, boon-search: a set of move and search commands. These
work the same way as standard Emacs commands; they are merely
(maybe) more powerful. Frontends typically bind these commands (and
more) in boon-moves-map, which is active in 'command mode'.
2. boon-arguments: a set of combinators to define regions. Combinators
include plain regions (words, lines, paragraphs, ...), but also
region transformers (think: exclude borders, just borders,
including spaces, foreach, etc.). Additionally every move command in
boon-moves-map can be used to define a region. The system supports
multiple cursors.
3. boon-core: An infrastructure for modal editing, inspired from
evil-core.
4. boon-main: A set of commands similar to standard Emacs commands,
but which uses the system of combinators. (Additionally some random
extra commands are thrown in for good measure.) These commands may
be used in combination with a modal system, or not. A few commands
also switch to insert mode.
5. boon-keys, boon-colemak, boon-qwerty, ...: frontends. Those
'require all the above and provide a mapping of moves, combinators
and commands onto keys. They may also bind keys for other 'modes',
such as helm.
Installation/Configuration
--------------------------
REQUIREMENTS
- Emacs version >= 24.5
- Colemak layout
- Colemak layout (qwerty version exists but tutorial assumes colemak
layout)
Install Boon (perhaps using
[![MELPA](http://stable.melpa.org/packages/boon-badge.svg)](http://stable.melpa.org/#/boon)),
and add the following to your configuration:
(require 'boon-colemak) ;; qwerty mode not implemented (contributions welcome)
(require 'boon-extras) ;; optional
(boon-mode) ;; enable boon everywhere (use turn-on-boon-mode) to try locally
(require 'boon-colemak)
;; (require 'boon-qwerty) ;; for qwerty port (alpha quality)
(boon-powerline-theme) ;; if you want use powerline with Boon
(boon-mode) ;; to enable boon everywhere (use M-x turn-on-boon-mode) to try locally
You can jump-start by reading the
[cheat sheet](https://pdf.yt/d/hSKUThNNSxrNFXkQ) directly, but reading
@ -81,13 +114,26 @@ As far as I know, none of the other modal mode care about ergonomics
Evil is a (quite) complete vi emulation layer for Emacs.
In boon, quite a bit of Emacs structure and user experience is
retained. Examples: the x key gives the C-x prefix map.
Interactive arguments are used for text objects.
In Boon, quite a bit of Emacs structure and user experience is
retained. Examples: the x key gives the C-x prefix map. The usual
Emacs (interactive) arguments are used for text objects. Thus most of
Boon remains usable even if one does not wish to use modal editing.
Besides, Emacs is already customizable enough as it is: the core of
Boon is just 200 lines or so. Figuring out all the ins and outs of
Evil to do what I want would probably require more effort.
Boon is just 300 lines or so. Figuring out all the ins and outs of
Evil to do what I want would probably have required more effort than
implementing Boon.
Finally, evil use vi bindings (by default at least), which do not
feature the best ergonomics.
- Fingers https://github.com/fgeller/fingers.el
Fingers borrows a few ideas from Boon, including the division of work
between left and right hand. fgeller gives a detailed account of the
particular differences with Boon. My opinion is that fingers is
compatible with Boon concepts and could be implemented as a Boon
'frontend'.
- God-mode https://github.com/chrisdone/god-mode
@ -98,10 +144,11 @@ As far as I know, none of the other modal mode care about ergonomics
- Modal Mode http://retroj.net/modal-mode
Perhaps the work which is the closest to Boon in principle
(lightweight and integration with Emacs). However, as far as I can
see, there is no special attention to ergonomics.
Another modal layer for Emacs, which is also lightweight and aims to
integrate with Emacs. However, as far as I can see, there is no
special attention to ergonomics.
- Modal Emacs https://github.com/joelmccracken/modal-emacs
Modal Emacs does not appear to be complete.

View file

@ -2,11 +2,20 @@
;;; Commentary:
;; This file defines functions which are intended to be used as
;; 'interactive' specifications: boon-spec-region and
;; boon-spec-enclosure. These are used by boon commands, but can be
;; used by any commands.
;;
;; In this module can also be found functions which are bound in
;; boon-select-map. Those functions return a no-argument lambda which
;; returns a list of boon-regs.
;;; Code:
(require 'boon-core)
(require 'boon-regs)
(require 'boon-utils)
(require 'multiple-cursors)
(require 'dash)
@ -58,16 +67,6 @@ This item is either the symbol at point, or, if this fails, the sexp at point."
(lambda () (boon-regs-from-bounds (or (bounds-of-thing-at-point 'symbol)
(bounds-of-thing-at-point 'sexp)))))
(defun boon-jump-over-blanks-forward ()
"Jump over blanks, forward."
(interactive)
(skip-chars-forward "\n\t "))
(defun boon-jump-over-blanks-backward ()
"Jump over blanks, backward."
(interactive)
(skip-chars-backward "\n\t "))
(defun boon-select-org-table-cell ()
"Return the region between pipes (|)."
(interactive)

View file

@ -2,10 +2,7 @@
;;; Commentary:
;;; Code:
(require 'boon-core)
(require 'boon-main)
(require 'boon-search)
(require 'boon-keys)
(require 'boon)
(define-key boon-select-map "q" 'boon-select-outside-quotes)
(define-key boon-select-map "w" 'boon-select-word)
@ -54,46 +51,44 @@
(define-key boon-moves-map "H" 'avy-goto-char)
(eval-after-load 'ivy
'(progn
(define-key ivy-minibuffer-map (kbd "RET") 'ivy-done)
(define-key ivy-minibuffer-map (kbd "<C-return>") 'ivy-call)
;; (define-key ivy-minibuffer-map (kbd "C-j") 'ivy-alt-done)
;; (define-key ivy-minibuffer-map (kbd "C-M-j") 'ivy-immediate-done)
(define-key ivy-minibuffer-map (kbd "C-n") 'ivy-partial)
(define-key ivy-minibuffer-map (kbd "C-y") 'ivy-next-line)
(define-key ivy-minibuffer-map (kbd "C-u") 'ivy-previous-line)
(define-key ivy-minibuffer-map (kbd "<down>") 'ivy-next-line)
(define-key ivy-minibuffer-map (kbd "<up>") 'ivy-previous-line)
;; (define-key ivy-minibuffer-map (kbd "C-s") 'ivy-next-line-or-history)
;; (define-key ivy-minibuffer-map (kbd "C-r") 'ivy-reverse-i-search)
(define-key ivy-minibuffer-map (kbd "SPC") 'boon-completer-space)
(define-key ivy-minibuffer-map (kbd "DEL") 'ivy-backward-delete-char)
(define-key ivy-minibuffer-map (kbd "C-w") 'ivy-backward-kill-word)
(define-key ivy-minibuffer-map (kbd "C-d") 'ivy-delete-char)
(define-key ivy-minibuffer-map (kbd "C-f") 'ivy-forward-char)
;; (define-key ivy-minibuffer-map (kbd "M-<") 'ivy-beginning-of-buffer)
;; (define-key ivy-minibuffer-map (kbd "M->") 'ivy-end-of-buffer)
(define-key ivy-minibuffer-map (kbd "C-.") 'ivy-next-history-element)
(define-key ivy-minibuffer-map (kbd "C-,") 'ivy-previous-history-element)
(define-key ivy-minibuffer-map (kbd "<escape>") 'minibuffer-keyboard-quit)
;; (define-key ivy-minibuffer-map (kbd "C-v") 'ivy-scroll-up-command)
;; (define-key ivy-minibuffer-map (kbd "M-v") 'ivy-scroll-down-command)
;; (define-key ivy-minibuffer-map (kbd "C-M-n") 'ivy-next-line-and-call)
;; (define-key ivy-minibuffer-map (kbd "C-M-p") 'ivy-previous-line-and-call)
(define-key ivy-minibuffer-map (kbd "C-q") 'ivy-toggle-regexp-quote)
;; (define-key ivy-minibuffer-map (kbd "M-j") 'ivy-yank-word)
(define-key ivy-minibuffer-map (kbd "C-v") 'ivy-insert-current)
(define-key ivy-minibuffer-map (kbd "TAB") 'ivy-partial) ;; for counsel-find-file
(define-key ivy-minibuffer-map (kbd "C-TAB") 'ivy-dispatching-call)
(define-key ivy-minibuffer-map (kbd "C-k") 'ivy-kill-line)
(define-key ivy-minibuffer-map (kbd "S-SPC") 'ivy-restrict-to-matches)
(define-key ivy-minibuffer-map (kbd "C-t") 'ivy-kill-ring-save)
;; (define-key ivy-minibuffer-map (kbd "C-h") 'ivy-avy)
;; (define-key ivy-minibuffer-map (kbd "C-M-a") 'ivy-read-action)
(define-key ivy-minibuffer-map (kbd "C-o") 'ivy-occur)
)
)
(with-eval-after-load 'ivy
(define-key ivy-minibuffer-map (kbd "RET") 'ivy-done)
(define-key ivy-minibuffer-map (kbd "<C-return>") 'ivy-call)
;; (define-key ivy-minibuffer-map (kbd "C-j") 'ivy-alt-done)
;; (define-key ivy-minibuffer-map (kbd "C-M-j") 'ivy-immediate-done)
(define-key ivy-minibuffer-map (kbd "C-n") 'ivy-partial)
(define-key ivy-minibuffer-map (kbd "C-y") 'ivy-next-line)
(define-key ivy-minibuffer-map (kbd "C-u") 'ivy-previous-line)
(define-key ivy-minibuffer-map (kbd "<down>") 'ivy-next-line)
(define-key ivy-minibuffer-map (kbd "<up>") 'ivy-previous-line)
;; (define-key ivy-minibuffer-map (kbd "C-s") 'ivy-next-line-or-history)
;; (define-key ivy-minibuffer-map (kbd "C-r") 'ivy-reverse-i-search)
(define-key ivy-minibuffer-map (kbd "SPC") 'boon-completer-space)
(define-key ivy-minibuffer-map (kbd "DEL") 'ivy-backward-delete-char)
(define-key ivy-minibuffer-map (kbd "C-w") 'ivy-backward-kill-word)
(define-key ivy-minibuffer-map (kbd "C-d") 'ivy-delete-char)
(define-key ivy-minibuffer-map (kbd "C-f") 'ivy-forward-char)
;; (define-key ivy-minibuffer-map (kbd "M-<") 'ivy-beginning-of-buffer)
;; (define-key ivy-minibuffer-map (kbd "M->") 'ivy-end-of-buffer)
(define-key ivy-minibuffer-map (kbd "C-.") 'ivy-next-history-element)
(define-key ivy-minibuffer-map (kbd "C-,") 'ivy-previous-history-element)
(define-key ivy-minibuffer-map (kbd "<escape>") 'minibuffer-keyboard-quit)
;; (define-key ivy-minibuffer-map (kbd "C-v") 'ivy-scroll-up-command)
;; (define-key ivy-minibuffer-map (kbd "M-v") 'ivy-scroll-down-command)
;; (define-key ivy-minibuffer-map (kbd "C-M-n") 'ivy-next-line-and-call)
;; (define-key ivy-minibuffer-map (kbd "C-M-p") 'ivy-previous-line-and-call)
(define-key ivy-minibuffer-map (kbd "C-q") 'ivy-toggle-regexp-quote)
;; (define-key ivy-minibuffer-map (kbd "M-j") 'ivy-yank-word)
(define-key ivy-minibuffer-map (kbd "C-v") 'ivy-insert-current)
(define-key ivy-minibuffer-map (kbd "TAB") 'ivy-partial) ;; for counsel-find-file
(define-key ivy-minibuffer-map (kbd "C-TAB") 'ivy-dispatching-call)
(define-key ivy-minibuffer-map (kbd "C-k") 'ivy-kill-line)
(define-key ivy-minibuffer-map (kbd "S-SPC") 'ivy-restrict-to-matches)
(define-key ivy-minibuffer-map (kbd "C-t") 'ivy-kill-ring-save)
;; (define-key ivy-minibuffer-map (kbd "C-h") 'ivy-avy)
;; (define-key ivy-minibuffer-map (kbd "C-M-a") 'ivy-read-action)
(define-key ivy-minibuffer-map (kbd "C-o") 'ivy-occur)
)
(with-eval-after-load 'helm
(define-helm-key (kbd "u") 'helm-previous-line)

View file

@ -8,39 +8,6 @@
;;; Code:
(require 'boon-core)
(require 'boon-main)
(defun boon-adjust-indent ()
"Adjust indentation of the region or current line."
(interactive)
(unless (use-region-p)
(set-mark (line-beginning-position))
(end-of-line))
(call-interactively 'indent-rigidly))
(defun boon-query-replace ()
"Query replace; but if the region is active, replace its contents"
(interactive)
(if (and (use-region-p) (eq (- (line-number-at-pos (region-end)) (line-number-at-pos (region-beginning))) 0))
(let ((selection (buffer-substring-no-properties (region-beginning) (region-end))))
(perform-replace
selection
(read-string "Replace region with:")
t ; query
nil ; not a regexp
nil ; not delimited
nil ; no specific repeat count
nil ; default keymap
(point-min-marker)
(point-max-marker) ; replace in the whole buffer
))
(call-interactively 'query-replace)))
(defun boon-toggle-comment (regs)
"Toggle comments in the regions REGS."
(interactive (list (boon-spec-region "toggle comment")))
(dolist (reg regs)
(comment-or-uncomment-region (boon-reg-begin reg)(boon-reg-end reg))))
(define-key boon-x-map "rr" 'boon-query-replace) ; replace the region if it is selected
(define-key boon-x-map "t" 'boon-toggle-comment) ; commenT
@ -64,9 +31,8 @@
(define-key boon-x-map "vv" 'magit-status)
(define-key boon-x-map "x" 'helm-M-x)
(eval-after-load 'flycheck
'(define-key boon-x-map "y" flycheck-command-map)
)
(with-eval-after-load 'flycheck
(define-key boon-x-map "y" flycheck-command-map))
(provide 'boon-extras)

View file

@ -106,5 +106,34 @@
(define-key boon-goto-map "t" 'helm-etags-select)
(define-key boon-goto-map "y" 'helm-flycheck)
(defun boon-god-control-swap (event)
"Swap the control 'bit' in EVENT, if that is a good choice."
(interactive (list (read-key)))
(cond
((memq event '(9 13)) event)
((<= event 27) (+ 96 event))
((not (eq 0 (logand (lsh 1 26) event))) (logxor (lsh 1 26) event))
(t (list 'control event))))
(defun boon-c-god ()
"Input a key sequence, prepend C- to each key, and run the command bound to that sequence."
(interactive)
(let ((keys '((control c)))
(binding (key-binding (kbd "C-c")))
(key-vector (kbd "C-c"))
(prompt "C-c-"))
(while (and binding (not (symbolp binding)))
(let ((key (read-key (format "%s" prompt))))
(if (eq key ?h) (describe-bindings key-vector)
(push (boon-god-control-swap key) keys)
(setq key-vector (vconcat (reverse keys)))
(setq prompt (key-description key-vector))
(setq binding (key-binding key-vector)))))
(setq this-command-keys key-vector)
(cond
((not binding) (error "No command bound to %s" prompt))
((commandp binding) (call-interactively binding))
(t (error "Key not bound to a command: %s" binding)))))
(provide 'boon-keys)
;;; boon-keys.el ends here

View file

@ -2,74 +2,19 @@
;;; Commentary:
;; This file contains (most of) the boon commands. These commands are
;; typically bound to a key in boon-keys or boon-colemak.
;; This file contains boon actions (modification of text). These
;; commands are typically bound to a key in boon-command-map. They
;; can be bound to any desired key though (in global-map as well).
;;; Code:
(require 'boon-core)
(require 'boon-utils)
(require 'boon-arguments)
(require 'er-basic-expansions)
(require 'multiple-cursors)
(require 'subr-x)
(require 'dash)
;;; Jumping to definitions (at point):
(defun boon-find-elisp-thing-at-point ()
"Find an elisp thing at point.
Search preferentially for a function, then a variable."
(interactive)
(let ((symb (symbol-at-point)))
(cond
((fboundp symb) (find-function-do-it symb nil 'switch-to-buffer))
((boundp symb) (find-function-do-it symb 'defvar 'switch-to-buffer))
(t (call-interactively 'helm-apropos)))))
(defun boon-find-tag-at-point ()
"Find the symbol at point in the current tags table."
(interactive)
(let ((symb (thing-at-point 'symbol)))
(cond (symb
(find-tag symb (when (and current-prefix-arg (bound-and-true-p last-tag))
(if (< (prefix-numeric-value current-prefix-arg) 0)
'-
t))))
(t (call-interactively 'find-tag)))))
(defcustom boon-find-definition-dispatch '()
"An alist mapping major modes to finding the symbol at point."
:group 'boon
:type '(alist :key-type symbol :value-type function))
(setq boon-find-definition-dispatch
'((c-mode . boon-find-tag-at-point)
(emacs-lisp-mode . boon-find-elisp-thing-at-point)
(lisp-interaction-mode . boon-find-elisp-thing-at-point)
(haskell-mode . (lambda () (interactive) (if intero-mode (intero-goto-definition) (haskell-mode-jump-to-def-or-tag))))))
(defun boon-find-definition ()
"Find a definition, in a way which is adapted to the 'major-mode'.
If possible, prompt the symbol at point."
(interactive)
;; TODO (ring-insert find-tag-marker-ring (point-marker))
(let ((mode-fap (assoc major-mode boon-find-definition-dispatch)))
(if mode-fap (call-interactively (cdr mode-fap))
(error "Finding definitions is not defined for %s. Update the variable 'boon-find-definition-dispatch'."
major-mode))))
(defcustom boon-hints-enabled 't "Display hints." :group 'boon)
(defun boon-hint (msg)
"Provide MSG as a hint."
(when boon-hints-enabled
(message msg)))
(defmacro boon-with-ordered-region (body)
"Run the BODY, ensuring that the point is before the mark."
`(if (< (point) (mark))
,body
(progn (exchange-point-and-mark) ,body (exchange-point-and-mark))))
(defun boon-drop-or-extend-mark ()
"Drop a mark; or extend the region to the next full line; or revert to original state."
@ -79,12 +24,12 @@ If possible, prompt the symbol at point."
(if (and (bolp)
(save-excursion (goto-char (mark)) (bolp))
(not (eq (point) (mark))))
(progn ;; here we have a number of full lines selected, and that number is more than 0
(progn ;; here we have a number of full lines selected, and that number is more than 0
(pop-mark) ;; load the saved position into the mark
(goto-char (mark));; jump there
(deactivate-mark))
(boon-with-ordered-region
(progn ;; here we have at least one non-full line selected. Extend to the full lines.
(progn ;; here we have at least one non-full line selected. Extend to the full lines.
(beginning-of-line)
(exchange-point-and-mark)
(end-of-line)
@ -106,12 +51,6 @@ If possible, prompt the symbol at point."
(if mark-active (boon-deactivate-mark)
(call-interactively 'boon-mark-region)))
(defun boon-current-line-indentation ()
"Return the indentation of the curent line."
(save-excursion
(back-to-indentation)
(current-column)))
(defun boon-enclose (enclosure regs)
"Wrap with the given ENCLOSURE the regions given as REGS."
(interactive (list (boon-spec-enclosure) (boon-spec-region "enclose")))
@ -123,43 +62,6 @@ If possible, prompt the symbol at point."
(goto-char (boon-reg-begin reg))
(insert (car enclosure)))))
(defun boon-find-char-backward (char)
"Move the cursor backwards, until finding an occurence of the character CHAR."
(interactive "cType the character to find")
(search-backward (make-string 1 char))
(forward-char 1))
(defun boon-find-char-forward (char)
"Find the given character (as CHAR), forwards."
(interactive "cType the character to find")
(search-forward (make-string 1 char))
(backward-char 1))
(defun boon-edge-of-expression (forward)
"Jump to the forward or backward (as FORWARD) limit of the current expression."
(interactive "P")
(let ((orig-point (point)))
(goto-char
(save-excursion
(deactivate-mark)
(if (boon-in-string-p)
(er/mark-inside-quotes) (er/mark-inside-pairs))
(when forward (exchange-point-and-mark))
(point)))
;; make sure we make some progress
(when (eq (point) orig-point)
(forward-char (if forward 1 -1)))))
(defun boon-end-of-expression ()
"Jump to the end of the current expression."
(interactive)
(boon-edge-of-expression 't))
(defun boon-beginning-of-expression ()
"Jump to the beginning of the current expression."
(interactive)
(boon-edge-of-expression nil))
(defun boon-delete-region ()
"Delete the region if it is active."
(when (use-region-p)
@ -221,176 +123,6 @@ Return nil if no changes are made."
;; done this way because 'or' is lazy
(or fix-here fix-there)))
(defun boon-line-prefix ()
"Return the text between beginning of line and point."
(buffer-substring-no-properties
(line-beginning-position)
(point)))
(defun boon-line-suffix ()
"Return the text between end of line and point."
(buffer-substring-no-properties
(line-end-position)
(point)))
(defun boon-at-indent-or-more-p ()
"Return non-nil if the point is at the current line indentation; or to the right."
(or (eolp)
(and (not (boon-at-indent-p))
(string-blank-p (boon-line-prefix)))))
(defun boon-at-indent-p ()
"Return non-nil if the point is at the current line indentation."
(eq (save-excursion (back-to-indentation) (point)) (point)))
(defun boon-smarter-upward (count)
"Move upward, to a line with the same level of indentation, or less, COUNT times."
(interactive "p")
(dotimes (_number count)
(previous-logical-line)
(while (boon-at-indent-or-more-p) (previous-logical-line)))
(back-to-indentation))
(defun boon-smarter-downward (count)
"Move downward, to a line with the same level of indentation, or less COUNT times."
(interactive "p")
(dotimes (_number count)
(next-logical-line)
(while (boon-at-indent-or-more-p) (next-logical-line)))
(back-to-indentation))
(defun boon-smarter-backward (count)
"Move backward, over COUNT whole syntactic units."
(interactive "p")
(dotimes (_number count)
(boon-jump-over-blanks-backward)
(cond
((boon-looking-at-comment -1)
(forward-comment -1))
((looking-back "\\s\"")
(backward-char)
(er--move-point-backward-out-of-string))
((looking-back "\\s)")
(backward-list))
((looking-back "\\s_") ;; symbol
(skip-syntax-backward "_"))
((looking-back "\\s(")
(backward-char))
((looking-back "\\s!") ;; generic comment delimiter
(skip-syntax-backward "!"))
((looking-back "\\sw")
(if (not (looking-at "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-backward "w")
(skip-syntax-backward "w_")))
(t
(backward-char)))))
(defun boon-smarter-forward (count)
"Move forward, over COUNT whole syntactic unit."
(interactive "p")
(dotimes (_number count)
(boon-jump-over-blanks-forward)
(cond
((boon-looking-at-line-comment-start-p)
(end-of-line)
(boon-jump-over-blanks-forward))
((boon-looking-at-comment 1);;
(forward-comment 1))
((looking-at "\\s\"")
(forward-char)
(er--move-point-forward-out-of-string))
((looking-at "\\s(")
(forward-list))
((looking-at "\\s_") ;; symbol
(skip-syntax-forward "_"))
((looking-at "\\s)")
(forward-char))
((looking-at "\\s!") ;; generic comment delimiter
(skip-syntax-forward "!"))
((looking-at "\\sw")
(if (not (looking-back "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-forward "w")
(skip-syntax-forward "w_")))
(t
(forward-char)))))
(defun boon-smarter-forward-spaces (count)
"Move forward, over COUNT whole syntactic unit.
Handle spaces cleverly."
(interactive "p")
(declare (obsolete "does not seem very useful" "20151120"))
(dotimes (_number count)
(let ((spaces-skipped (not (equal (boon-jump-over-blanks-forward) 0)))
(in-middle nil)
(at-bol (string-blank-p (boon-line-prefix))))
(cond
((boon-looking-at-line-comment-start-p)
(end-of-line)
(forward-char))
((boon-looking-at-comment 1);;
(forward-comment 1))
((looking-at "\\s\"")
(forward-char)
(er--move-point-forward-out-of-string))
((looking-at "\\s(")
(forward-list))
((looking-at "\\s_") ;; symbol
(skip-syntax-forward "_"))
((looking-at "\\s)")
(forward-char)
(setq in-middle 't))
((looking-at "\\s!") ;; generic comment delimiter
(skip-syntax-forward "!"))
((looking-at "\\sw")
(setq in-middle 't)
(if (not (looking-back "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-forward "w")
(skip-syntax-forward "w_")))
(t
(forward-char)
(setq in-middle 't)))
(unless (or spaces-skipped in-middle)
(if at-bol
(skip-chars-forward "\t\n ")
(skip-chars-forward "\t "))))))
(defun boon-smarter-backward-spaces (count)
"Move backward, over COUNT whole syntactic unit.
Handles spaces smartly."
(interactive "p")
(declare (obsolete "does not seem very useful" "20151120"))
(dotimes (_number count)
(let ((spaces-skipped (not (equal (boon-jump-over-blanks-backward) 0)))
(in-middle nil)
(at-eol (string-blank-p (boon-line-suffix))))
(cond
((boon-looking-at-comment -1)
(forward-comment -1))
((looking-back "\\s\"")
(backward-char)
(er--move-point-backward-out-of-string))
((looking-back "\\s)")
(backward-list))
((looking-back "\\s_") ;; symbol
(skip-syntax-backward "_"))
((looking-back "\\s(")
(backward-char)
(setq in-middle 't))
((looking-back "\\s!") ;; generic comment delimiter
(skip-syntax-backward "!"))
((looking-back "\\sw")
(setq in-middle 't)
(if (not (looking-at "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-backward "w")
(skip-syntax-backward "w_")))
(t
(backward-char)
(setq in-middle 't)))
(unless (or spaces-skipped in-middle)
(if at-eol
(skip-chars-backward "\t\n ")
(skip-chars-backward "\t "))))))
(defun boon-toggle-character-case ()
"Toggle the case of the character at point."
(interactive)
@ -440,68 +172,10 @@ NOTE: Do not run for every cursor."
(message "mark placed at point"))
(activate-mark)))
(defun boon-visible-beginning-of-line ()
"Move point leftwards to the first visible beginning of line."
(interactive)
(beginning-of-line)
(while (bound-and-true-p outline-invisible-p)
(backward-char 1)
(beginning-of-line 1)))
(defun boon-beginning-of-line ()
"Move point to the first non-whitespace character on this line.
If point was already at that position, move point to beginning of
line."
(interactive)
(let ((oldpos (point)))
(back-to-indentation)
(when (or (and (fboundp 'outline-invisible-p)
(outline-invisible-p))
(= oldpos (point)))
(boon-visible-beginning-of-line))))
(defun boon-looking-at-comment (how-many)
"Is the current point looking at HOW-MANY comments? (negative for backwards)?"
(save-excursion
(forward-comment how-many)))
(defun boon-in-string-p ()
"Determine if the point is inside a string."
(nth 3 (syntax-ppss)))
(defun boon-looking-at-line-comment-start-p ()
"Are we looking at a comment-start?"
(interactive)
(and (bound-and-true-p comment-start)
(looking-at comment-start)
(not (boon-in-string-p))))
(defun boon-end-of-line ()
"Intelligently jump to the end of line.
This function toggles between jumping to 1. the last character of code on the
line 2. the last non-blank char on the line 3. the true end of
line."
(interactive)
(let* ((orig (point))
(orig-eol (eolp))
(progress (lambda () (and (not (bolp)) (or orig-eol (> (point) orig))))))
(beginning-of-line)
(while (not (or (boon-looking-at-line-comment-start-p) (eolp)))
(forward-char))
;; we're now at the last non-comment character of the line
(skip-chars-backward "\n\t " (line-beginning-position))
;; we're now at the last non-blank, non-comment character of the line
(unless (funcall progress)
(end-of-line)
(skip-chars-backward "\n\t " (line-beginning-position))
;; we're now at the last non-blank character of the line
(unless (funcall progress)
(end-of-line)))))
(defun boon-open-line-and-insert ()
"Open a new line, indented as much as the current one, and switch to insert mode."
(interactive)
(let ((indent-lvl (boon-current-line-indentation)))
(let ((indent-lvl (boon-current-line-indentation)))
(beginning-of-line)
(open-line 1)
(insert (make-string indent-lvl 32))
@ -526,24 +200,6 @@ line."
(forward-char 1)
(insert line-prefix))))))
(defun boon-switch-mark ()
"If mark active, switch point and mark, otherwise pop mark from mark ring."
(interactive)
(if mark-active
(exchange-point-and-mark)
(if (mark)
(progn
(goto-char (mark))
(pop-mark)))))
(defun boon-switch-mark-quick ()
"Pop the mark ring until we find ourselves on a different line."
(interactive)
(let ((orig-line (line-number-at-pos)))
(while (> 1 (abs (- orig-line (line-number-at-pos))))
(goto-char (mark))
(pop-mark))))
(defun boon-split-line ()
"Split the current line."
(interactive)
@ -585,19 +241,8 @@ If there is more than one, use mc/create-fake-cursor-at-point."
(goto-char (boon-reg-point reg))) regs)
(activate-mark))
(defun boon-end-of-region (regs)
"Move the point the end region REGS."
(interactive (list (boon-spec-region "go to end")))
(dolist (reg regs)
(goto-char (boon-reg-end reg))))
(defun boon-beginning-of-region (regs)
"Move the point to the beginning region REGS."
(interactive (list (boon-spec-region "go to beginning")))
(dolist (reg regs)
(goto-char (boon-reg-begin reg))))
(defun boon-execute-for-cursor (cursor fun)
"In the context of the fake CURSOR, run FUN."
(if cursor
(mc/save-excursion
(mc/save-window-scroll
@ -616,7 +261,7 @@ If there is more than one, use mc/create-fake-cursor-at-point."
;; We can't run 'kill-region' on markers. Indeed, using
;; markers messes the logic used in kill-region to
;; determine whether to prepend or append the thing
;; just killed to the top of the kill ring.
;; just killed to the top of the kill ring.
(kill-region (boon-reg-mark reg) (boon-reg-point reg)))))))
(defun boon-treasure-region (regs)
@ -683,44 +328,8 @@ NOTE: do not run for every cursor."
(t
(keyboard-quit))))
(defun boon-stuff-at-point ()
"Return a meaningful piece of text around at point.
If no such text exists, throw an error."
(interactive)
(if (use-region-p)
(buffer-substring-no-properties (region-beginning) (region-end))
(or (thing-at-point 'symbol)
(error "Nothing relevant at point; move to a symbol or select a region"))))
;; TODO: remove
(require 'skeleton)
(setq skeleton-pair t)
(defun boon-empty-pair-p ()
"Is the point at the middle of an empty pair of matched parens?"
(interactive)
(declare (obsolete "emacs 24.5 electric pair mode is good enough" "20150527"))
(eq (caddr
(assq (preceding-char)
(or skeleton-pair-alist skeleton-pair-default-alist)))
(following-char)))
(defun boon-empty-quotes-p ()
"Is the point in the middle of an empty pair of quotes?"
(interactive)
(declare (obsolete "emacs 24.5 electric pair mode is good enough" "20150527"))
(and (eq (preceding-char) (following-char))
(member (following-char) '(?\" ?\'))))
(defun boon-smart-insert-backspace2 ()
(interactive)
(declare (obsolete "emacs 24.5 electric pair mode is good enough" "20150527"))
(when (or (boon-empty-pair-p) (boon-empty-quotes-p))
(delete-char 1))
(backward-delete-char-untabify 1))
(defun boon-god-control-swap (event)
"Swap the control 'bit' in an event, for event where it makes sense."
"Swap the control 'bit' in EVENT, if that is a good choice."
(interactive (list (read-key)))
(cond
((memq event '(9 13)) event)
@ -729,7 +338,7 @@ If no such text exists, throw an error."
(t (list 'control event))))
(defun boon-c-god ()
"Handle C key"
"Input a key sequence, prepend C- to each key, and run the command bound to that sequence."
(interactive)
(let ((keys '((control c)))
(binding (key-binding (kbd "C-c")))
@ -746,7 +355,39 @@ If no such text exists, throw an error."
(cond
((not binding) (error "No command bound to %s" prompt))
((commandp binding) (call-interactively binding))
(t (error "key not bound to a command: %s" binding)))))
(t (error "Key not bound to a command: %s" binding)))))
(defun boon-adjust-indent ()
"Adjust indentation of the region or current line."
(interactive)
(unless (use-region-p)
(set-mark (line-beginning-position))
(end-of-line))
(call-interactively 'indent-rigidly))
(defun boon-query-replace ()
"Query replace; but if the region is active, replace its contents."
(interactive)
(if (and (use-region-p) (eq (- (line-number-at-pos (region-end)) (line-number-at-pos (region-beginning))) 0))
(let ((selection (buffer-substring-no-properties (region-beginning) (region-end))))
(perform-replace
selection
(read-string "Replace region with:")
t ; query
nil ; not a regexp
nil ; not delimited
nil ; no specific repeat count
nil ; default keymap
(point-min-marker)
(point-max-marker) ; replace in the whole buffer
))
(call-interactively 'query-replace)))
(defun boon-toggle-comment (regs)
"Toggle comments in the regions REGS."
(interactive (list (boon-spec-region "toggle comment")))
(dolist (reg regs)
(comment-or-uncomment-region (boon-reg-begin reg)(boon-reg-end reg))))
(provide 'boon-main)
;;; boon-main.el ends here

309
boon-moves.el Normal file
View file

@ -0,0 +1,309 @@
;;; boon-moves.el --- An Ergonomic Command Mode -*- lexical-binding: t -*-
;;; Commentary:
;; This file contains boon moves (jumping around somewhere). These
;; commands are typically bound to a key in boon-moves-map. They
;; can be bound to any desired key though (in global-map as well).
;;; Code:
(require 'boon-core)
(require 'boon-utils)
(require 'er-basic-expansions)
(require 'find-func)
(require 'boon-utils)
;;; Jumping to definitions (at point):
(defun boon-find-elisp-thing-at-point ()
"Find an elisp thing at point.
Search preferentially for a function, then a variable."
(interactive)
(let ((symb (symbol-at-point)))
(cond
((fboundp symb) (find-function-do-it symb nil 'switch-to-buffer))
((boundp symb) (find-function-do-it symb 'defvar 'switch-to-buffer))
(t (call-interactively 'helm-apropos)))))
(defun boon-find-tag-at-point ()
"Find the symbol at point in the current tags table."
(interactive)
(let ((symb (thing-at-point 'symbol)))
(cond (symb
(find-tag symb (when (and current-prefix-arg (bound-and-true-p last-tag))
(if (< (prefix-numeric-value current-prefix-arg) 0)
'-
t))))
(t (call-interactively 'find-tag)))))
(defcustom boon-find-definition-dispatch '()
"An alist mapping major modes to finding the symbol at point."
:group 'boon
:type '(alist :key-type symbol :value-type function))
(setq boon-find-definition-dispatch
'((c-mode . boon-find-tag-at-point)
(emacs-lisp-mode . boon-find-elisp-thing-at-point)
(lisp-interaction-mode . boon-find-elisp-thing-at-point)
(haskell-mode . (lambda () (interactive) (if intero-mode (intero-goto-definition) (haskell-mode-jump-to-def-or-tag))))))
(defun boon-find-definition ()
"Find a definition, in a way which is adapted to the 'major-mode'.
If possible, prompt the symbol at point."
(interactive)
;; TODO (ring-insert find-tag-marker-ring (point-marker))
(let ((mode-fap (assoc major-mode boon-find-definition-dispatch)))
(if mode-fap (call-interactively (cdr mode-fap))
(error "Finding definitions is not defined for %s. Update the variable 'boon-find-definition-dispatch'"
major-mode))))
(defun boon-find-char-backward (char)
"Move the cursor backwards, until finding an occurence of the character CHAR."
(interactive "cType the character to find")
(search-backward (make-string 1 char))
(forward-char 1))
(defun boon-find-char-forward (char)
"Find the given character (as CHAR), forwards."
(interactive "cType the character to find")
(search-forward (make-string 1 char))
(backward-char 1))
(defun boon-edge-of-expression (forward)
"Jump to the forward or backward (as FORWARD) limit of the current expression."
(interactive "P")
(let ((orig-point (point)))
(goto-char
(save-excursion
(deactivate-mark)
(if (boon-in-string-p)
(er/mark-inside-quotes) (er/mark-inside-pairs))
(when forward (exchange-point-and-mark))
(point)))
;; make sure we make some progress
(when (eq (point) orig-point)
(forward-char (if forward 1 -1)))))
(defun boon-end-of-expression ()
"Jump to the end of the current expression."
(interactive)
(boon-edge-of-expression 't))
(defun boon-beginning-of-expression ()
"Jump to the beginning of the current expression."
(interactive)
(boon-edge-of-expression nil))
(defun boon-smarter-upward (count)
"Move upward, to a line with the same level of indentation, or less, COUNT times."
(interactive "p")
(dotimes (_number count)
(previous-logical-line)
(while (boon-at-indent-or-more-p) (previous-logical-line)))
(back-to-indentation))
(defun boon-smarter-downward (count)
"Move downward, to a line with the same level of indentation, or less COUNT times."
(interactive "p")
(dotimes (_number count)
(next-logical-line)
(while (boon-at-indent-or-more-p) (next-logical-line)))
(back-to-indentation))
(defun boon-smarter-backward (count)
"Move backward, over COUNT whole syntactic units."
(interactive "p")
(dotimes (_number count)
(boon-jump-over-blanks-backward)
(cond
((boon-looking-at-comment -1)
(forward-comment -1))
((looking-back "\\s\"")
(backward-char)
(er--move-point-backward-out-of-string))
((looking-back "\\s)")
(backward-list))
((looking-back "\\s_") ;; symbol
(skip-syntax-backward "_"))
((looking-back "\\s(")
(backward-char))
((looking-back "\\s!") ;; generic comment delimiter
(skip-syntax-backward "!"))
((looking-back "\\sw")
(if (not (looking-at "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-backward "w")
(skip-syntax-backward "w_")))
(t
(backward-char)))))
(defun boon-smarter-forward (count)
"Move forward, over COUNT whole syntactic unit."
(interactive "p")
(dotimes (_number count)
(boon-jump-over-blanks-forward)
(cond
((boon-looking-at-line-comment-start-p)
(end-of-line)
(boon-jump-over-blanks-forward))
((boon-looking-at-comment 1);;
(forward-comment 1))
((looking-at "\\s\"")
(forward-char)
(er--move-point-forward-out-of-string))
((looking-at "\\s(")
(forward-list))
((looking-at "\\s_") ;; symbol
(skip-syntax-forward "_"))
((looking-at "\\s)")
(forward-char))
((looking-at "\\s!") ;; generic comment delimiter
(skip-syntax-forward "!"))
((looking-at "\\sw")
(if (not (looking-back "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-forward "w")
(skip-syntax-forward "w_")))
(t
(forward-char)))))
(defun boon-smarter-forward-spaces (count)
"Move forward, over COUNT whole syntactic unit.
Handle spaces cleverly."
(interactive "p")
(declare (obsolete "does not seem very useful" "20151120"))
(dotimes (_number count)
(let ((spaces-skipped (not (equal (boon-jump-over-blanks-forward) 0)))
(in-middle nil)
(at-bol (string-blank-p (boon-line-prefix))))
(cond
((boon-looking-at-line-comment-start-p)
(end-of-line)
(forward-char))
((boon-looking-at-comment 1);;
(forward-comment 1))
((looking-at "\\s\"")
(forward-char)
(er--move-point-forward-out-of-string))
((looking-at "\\s(")
(forward-list))
((looking-at "\\s_") ;; symbol
(skip-syntax-forward "_"))
((looking-at "\\s)")
(forward-char)
(setq in-middle 't))
((looking-at "\\s!") ;; generic comment delimiter
(skip-syntax-forward "!"))
((looking-at "\\sw")
(setq in-middle 't)
(if (not (looking-back "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-forward "w")
(skip-syntax-forward "w_")))
(t
(forward-char)
(setq in-middle 't)))
(unless (or spaces-skipped in-middle)
(if at-bol
(skip-chars-forward "\t\n ")
(skip-chars-forward "\t "))))))
(defun boon-smarter-backward-spaces (count)
"Move backward, over COUNT whole syntactic unit.
Handles spaces smartly."
(interactive "p")
(declare (obsolete "does not seem very useful" "20151120"))
(dotimes (_number count)
(let ((spaces-skipped (not (equal (boon-jump-over-blanks-backward) 0)))
(in-middle nil)
(at-eol (string-blank-p (boon-line-suffix))))
(cond
((boon-looking-at-comment -1)
(forward-comment -1))
((looking-back "\\s\"")
(backward-char)
(er--move-point-backward-out-of-string))
((looking-back "\\s)")
(backward-list))
((looking-back "\\s_") ;; symbol
(skip-syntax-backward "_"))
((looking-back "\\s(")
(backward-char)
(setq in-middle 't))
((looking-back "\\s!") ;; generic comment delimiter
(skip-syntax-backward "!"))
((looking-back "\\sw")
(setq in-middle 't)
(if (not (looking-at "\\(\\s-\\|\\s(\\|\\s)\\)"))
(skip-syntax-backward "w")
(skip-syntax-backward "w_")))
(t
(backward-char)
(setq in-middle 't)))
(unless (or spaces-skipped in-middle)
(if at-eol
(skip-chars-backward "\t\n ")
(skip-chars-backward "\t "))))))
(defun boon-visible-beginning-of-line ()
"Move point leftwards to the first visible beginning of line."
(interactive)
(beginning-of-line)
(while (bound-and-true-p outline-invisible-p)
(backward-char 1)
(beginning-of-line 1)))
(defun boon-beginning-of-line ()
"Move point to the first non-whitespace character on this line.
If point was already at that position, move point to beginning of
line."
(interactive)
(let ((oldpos (point)))
(back-to-indentation)
(when (or (and (fboundp 'outline-invisible-p)
(outline-invisible-p))
(= oldpos (point)))
(boon-visible-beginning-of-line))))
(defun boon-end-of-line ()
"Intelligently jump to the end of line.
This function toggles between jumping to 1. the last character of code on the
line 2. the last non-blank char on the line 3. the true end of
line."
(interactive)
(let* ((orig (point))
(orig-eol (eolp))
(progress (lambda () (and (not (bolp)) (or orig-eol (> (point) orig))))))
(beginning-of-line)
(while (not (or (boon-looking-at-line-comment-start-p) (eolp)))
(forward-char))
;; we're now at the last non-comment character of the line
(skip-chars-backward "\n\t " (line-beginning-position))
;; we're now at the last non-blank, non-comment character of the line
(unless (funcall progress)
(end-of-line)
(skip-chars-backward "\n\t " (line-beginning-position))
;; we're now at the last non-blank character of the line
(unless (funcall progress)
(end-of-line)))))
(defun boon-switch-mark ()
"If mark active, switch point and mark, otherwise pop mark from mark ring."
(interactive)
(if mark-active
(exchange-point-and-mark)
(if (mark)
(progn
(goto-char (mark))
(pop-mark)))))
(defun boon-switch-mark-quick ()
"Pop the mark ring until we find ourselves on a different line."
(interactive)
;; obsolete
(let ((orig-line (line-number-at-pos)))
(while (> 1 (abs (- orig-line (line-number-at-pos))))
(goto-char (mark))
(pop-mark))))
(provide 'boon-moves)
;;; boon-moves.el ends here

View file

@ -2,10 +2,7 @@
;;; Commentary:
;;; Code:
(require 'boon-core)
(require 'boon-main)
(require 'boon-search)
(require 'boon-keys)
(require 'boon)
(define-key boon-select-map "@" 'boon-select-occurences)

View file

@ -4,7 +4,7 @@
;;; Code:
(require 'boon-main)
(require 'boon-utils)
(defvar-local boon-regexp nil "Current regexp search. Use boon-set-search-regexp to set this variable.")
(defvar-local boon-search-success t "Last search was successful or non-existent.")

94
boon-utils.el Normal file
View file

@ -0,0 +1,94 @@
;;; boon-utils.el --- An Ergonomic Command Mode -*- lexical-binding: t -*-
;;; Commentary:
;; This file contains several utilities, which shoud probably be part
;; of Emacs. (Maybe they are and I did not find them.)
;;; Code:
(require 'subr-x)
(defmacro boon-with-ordered-region (body)
"Run the BODY, ensuring that the point is before the mark."
`(if (< (point) (mark))
,body
(progn (exchange-point-and-mark) ,body (exchange-point-and-mark))))
(defcustom boon-hints-enabled 't "Display hints." :group 'boon)
(defun boon-hint (msg)
"Provide MSG as a hint."
(when boon-hints-enabled
(message msg)))
(defun boon-current-line-indentation ()
"Return the indentation of the curent line."
(save-excursion
(back-to-indentation)
(current-column)))
(defun boon-line-prefix ()
"Return the text between beginning of line and point."
(buffer-substring-no-properties
(line-beginning-position)
(point)))
(defun boon-line-suffix ()
"Return the text between end of line and point."
(buffer-substring-no-properties
(line-end-position)
(point)))
(defun boon-at-indent-or-more-p ()
"Return non-nil if the point is at the current line indentation; or to the right."
(or (eolp)
(and (not (boon-at-indent-p))
(string-blank-p (boon-line-prefix)))))
(defun boon-at-indent-p ()
"Return non-nil if the point is at the current line indentation."
(eq (save-excursion (back-to-indentation) (point)) (point)))
(defun boon-looking-at-comment (how-many)
"Is the current point looking at HOW-MANY comments? (negative for backwards)?"
;; (declare (obsolete "emacs 24.5 electric pair mode is good enough" "20150527"))
;; (obsolete) 20160901
(save-excursion
(forward-comment how-many)))
(defun boon-in-string-p ()
"Determine if the point is inside a string."
(nth 3 (syntax-ppss)))
(defun boon-looking-at-line-comment-start-p ()
"Are we looking at a comment-start?"
(interactive)
(and (bound-and-true-p comment-start)
(looking-at comment-start)
(not (boon-in-string-p))))
(defun boon-stuff-at-point ()
"Return a meaningful piece of text around at point.
If no such text exists, throw an error."
(interactive)
(if (use-region-p)
(buffer-substring-no-properties (region-beginning) (region-end))
(or (thing-at-point 'symbol)
(error "Nothing relevant at point; move to a symbol or select a region"))))
(defun boon-jump-over-blanks-forward ()
"Jump over blanks, forward."
(interactive)
(skip-chars-forward "\n\t "))
(defun boon-jump-over-blanks-backward ()
"Jump over blanks, backward."
(interactive)
(skip-chars-backward "\n\t "))
(provide 'boon-utils)
;;; boon-utils.el ends here

View file

@ -3,10 +3,7 @@
;;; Commentary:
;; fgeller's workman port (WIP, contributions welcome)
;;; Code:
(require 'boon-core)
(require 'boon-main)
(require 'boon-search)
(require 'boon-keys)
(require 'boon)
(define-key boon-select-map (kbd "g") 'boon-select-document)
(define-key boon-select-map (kbd "w") 'boon-select-paragraph)
@ -40,8 +37,8 @@
(define-key boon-moves-map (kbd ".") 'boon-end-of-expression)
(define-key boon-moves-map (kbd "e") 'backward-char)
(define-key boon-moves-map (kbd "o") 'forward-char)
(define-key boon-moves-map (kbd "<") 'boon-beginning-of-region)
(define-key boon-moves-map (kbd ">") 'boon-end-of-region)
(define-key boon-moves-map (kbd "<") 'beginning-of-buffer)
(define-key boon-moves-map (kbd ">") 'end-of-buffer)
(define-key boon-moves-map (kbd "C-,") 'beginning-of-buffer)
(define-key boon-moves-map (kbd "C-.") 'end-of-buffer)

View file

@ -10,8 +10,12 @@
;;; Code:
(require 'boon-colemak)
(require 'boon-main)
(require 'boon-keys)
(require 'boon-search)
(require 'boon-extras)
(require 'boon-core)
(require 'boon-moves)
(provide 'boon)
;;; boon.el ends here

View file

@ -1,5 +1,7 @@
{-# OPTIONS_GHC -XTypeSynonymInstances -XOverloadedStrings -XRecursiveDo -pgmF marxup -F #-}
{-# LANGUAGE TupleSections #-}
module CC where
import Data.Char (toUpper)
import Prelude hiding (mapM,sequence,Num(..),(/))
import MarXup
@ -57,7 +59,6 @@ argColor a = case a of
Bin _ _ -> "purple"
_ -> "white"
reserved :: (TeX,Argument)
reserved = (italic "reserved",Reserved)
@ -72,7 +73,7 @@ leftHandL = [[("escape",Char), ("search backward",SearchObject), ("search forwar
]
leftHandR = [[("quotes (string)",None), ("word",None), ("word",None), ("paragraph",None), reserved]
,[("enclosure",TextRegion), ("whole-line",None), ("symbol",None), reserved, ("document",None), ("previous-region",None)]
,[("enclosure",TextRegion), ("whole-line",None), ("symbol",None), ("whitespace+",TextRegion), ("document",None), ("previous-region",None)]
,[("inclosure",TextRegion), ("s-expr",None), ("s-expr contents",None), reserved, reserved]
]