diff options
| -rw-r--r-- | README.org | 57 | ||||
| -rw-r--r-- | doc/changelog.org | 19 | ||||
| -rw-r--r-- | doc/keythemes.org | 21 | ||||
| -rw-r--r-- | evil-org.el | 187 |
4 files changed, 182 insertions, 102 deletions
@@ -18,24 +18,49 @@ See [[file:doc/changelog.org][changelog]] for a history of changes. ** Keybindings - |----------------+---------------------------| - | key | explanation | - |----------------+---------------------------| - | M-ret | insert heading | - | TAB | fold / unfold headings | - | gh, gj, gk, gl | navigate between elements | - | vae | select an element | - | var | select a subtree | - | M-h or << | promote a heading | - | M-l or >> | demote a heading | - | M-k | move subtree up | - | M-j | move subtree down | - | M-S-h or <ar | promote a subtree | - | M-S-l or >ar | demote a subtree | - |----------------+---------------------------| - [[file:doc/keythemes.org][Full overview of bindings and configuration]] +*** Quick overview + + |----------------+---------------------------| + | key | explanation | + |----------------+---------------------------| + | gh, gj, gk, gl | navigate between elements | + | vae | select an element | + |----------------+---------------------------| + +**** Headings and items + + |--------------+------------------------| + | key | explanation | + |--------------+------------------------| + | M-ret | insert heading | + | TAB | fold / unfold headings | + | M-h or << | promote a heading | + | M-l or >> | demote a heading | + | M-k | move subtree up | + | M-j | move subtree down | + | M-S-h or <aR | promote a subtree | + | M-S-l or >aR | demote a subtree | + | vaR | select a subtree | + |--------------+------------------------| + +**** Tables + + |-----------+--------------------------------| + | key | explanation | + |-----------+--------------------------------| + | ( | previous table cell | + | ) | next table cell | + | { | beginning of table | + | } | end of table | + | M-h / M-l | move table column left / right | + | M-k / M-j | move table column up / down | + | vae | select table cell | + | vaE | select table row | + | var | select whole table | + |-----------+--------------------------------| + ** Requirements - org-mode, git://orgmode.org/org-mode.git diff --git a/doc/changelog.org b/doc/changelog.org index 37f56a7..bf6fd6d 100644 --- a/doc/changelog.org +++ b/doc/changelog.org @@ -1,18 +1,25 @@ -* Version 0.7.0 - - A hook is no longer created automatically +* Version 0.7.* + - A hook is no longer created automatically. The following line of code is from now on required in a user config: #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook 'evil-org-mode) ;; only load with org-mode #+END_SRC - This line is from now on required in a user config. - - Leader key bindings are removed. See [[file:example_config.el][example config]] for an example how you can set them up yourself. + - Redone text objects + - Sentence (is/as) and paragraph (ip/ap) text objects no longer get special treatment in tables. Use ie/ae for cells and ir/ar for tables instead. + - Move element text object bindings from ie/ae to iE/aE + - New text object ie/ae that works on elements and a few smaller objects. + - Move subtree text object bindings from ir/ar to iR/aR + - New text object ir/ar that works on recursive objects. Repeatable in visual mode. * Between versions 0.1.2 and 0.6.3 - less controversial default keybindings (see issue [[https://github.com/edwtjo/evil-org-mode/issues/13][#13]]) t, T, O and leader bindings are no longer bound by default, but can be enabled using key themes. - leader keys are deprecated and evil-leader is no longer required - customizable movement keys (as a courtesy to dvorak users) - - operators (>, <) for promotion, demotion. Can also be used for plain indentation when in a code block - - text objects (ae, ar, ap, as) + - new operators (>, <) for promotion, demotion. Can also be used for plain indentation when in a code block. + That means < and > are no longer bound to org-meta-left/right. + - new text objects + - ae, ar to match element, subheading + - ap, as to match whole table, table cell in table context - optional insert mode bindings C-d and C-t - table support for keys: x, X, (, ), { and }. diff --git a/doc/keythemes.org b/doc/keythemes.org index 6519343..9a5241e 100644 --- a/doc/keythemes.org +++ b/doc/keythemes.org @@ -66,17 +66,18 @@ |-----+----------------------+-------------------| ** Text objects - "var" to select an element + "vae" to select an element "dar" to delete a subtree - "2yar" to yank the parent of a subtree - - |-----+-------------+------------------------------------------------| - | key | function | explanation | - |-----+-------------+------------------------------------------------| - | ae | org-element | An org element | - | ar | org-subtree | A subtree. Use a count to select parent trees. | - |-----+-------------+------------------------------------------------| - + "2yaR" to yank the parent of a subtree + + |---------+---------------------+-------------------------------------------------| + | key | function | explanation | + |---------+---------------------+-------------------------------------------------| + | ae / ie | org-object | An / inner object (markup, table cell) | + | aE / iE | org-element | An / inner element (code block, table row) | + | ar / ir | org-greater-element | An / inner recursive element (item list, table) | + | aR / iR | org-subtree | An / inner subtree starting with a * | + |---------+---------------------+-------------------------------------------------| ** Additional If you don't want to use hjkl, you can customize evil-org-movement-bindings. diff --git a/evil-org.el b/evil-org.el index f9952c8..77251bd 100644 --- a/evil-org.el +++ b/evil-org.el @@ -7,7 +7,7 @@ ;; Git-Repository: git://github.com/Somelauw/evil-org-mode.git ;; Created: 2012-06-14 ;; Forked-since: 2017-02-12 -;; Version: 0.7.1 +;; Version: 0.7.2 ;; Package-Requires: ((emacs "24.4") (evil "1.0") (org "8.0.0")) ;; Keywords: evil vim-emulation org-mode key-bindings presets @@ -365,73 +365,123 @@ If a prefix argument is given, links are opened in incognito mode." (evil-org-generic-open-links beg end t)) ;;; text-objects -(evil-define-text-object org-element-textobj (count &optional beg end type) - "An org element." - (let ((element (org-element-at-point))) - (list (org-element-property :begin element) +(defun evil-org-select-an-element (element) + "Select an org ELEMENT." + (list (org-element-property :begin element) + (org-element-property :end element))) + +(defun evil-org-select-inner-element (element) + "Select inner org ELEMENT." + (list (or (org-element-property :contents-begin element) + (org-element-property :begin element)) + (or (org-element-property :contents-end element) + ;; Prune post-blank lines from :end element + (save-excursion + (goto-char (org-element-property :end element)) + (let ((post-blank (org-element-property :post-blank element))) + (unless (zerop post-blank) + (forward-line (- post-blank)))) + (point))))) + +(defun evil-org-parent (element) + "Find a parent or nearest heading of ELEMENT." + (or (org-element-property :parent element) + (save-excursion + (goto-char (org-element-property :begin element)) + (if (org-with-limited-levels (org-at-heading-p)) + (org-up-heading-safe) + (org-with-limited-levels (org-back-to-heading))) + (org-element-at-point)))) + +(evil-define-text-object evil-org-an-object (count beg end type) + "An org object. +Matches urls and table cells." + (when (null end) (setq end (point))) + (when (null beg) (setq beg (point))) + (let* ((first (org-element-context)) + (element first)) + ;; select next object on repetitive presses + (goto-char end) + (when (<= (org-element-property :end element) end) + (setq element (org-element-context))) + (dotimes (_ (1- count)) + (goto-char (org-element-property :end element)) + (setq element (org-element-context))) + (list (min beg (org-element-property :begin first)) + (org-element-property :end element)))) + +(evil-define-text-object evil-org-inner-object (count &optional beg end type) + "Select an org object. +Matches urls and table cells." + (evil-org-select-inner-element (org-element-context))) + +(evil-define-text-object evil-org-an-element (count &optional beg end type) + "An org element. +Includes paragraphs, table rows and code blocks. +" + (let* ((first (org-element-at-point)) + (element first)) + (when (and end (>= end (org-element-property :end element))) + (org-forward-element) + (setq element (org-element-at-point))) + (dotimes (_ (1- count)) + (org-forward-element) + (setq element (org-element-at-point))) + (list (min (or beg (point)) (org-element-property :begin first)) (org-element-property :end element)))) -(evil-define-text-object org-subtree-textobj (count &optional beg end type) +(evil-define-text-object evil-org-inner-element (count &optional beg end type) + "Inner org element. +Includes paragraphs, table rows and code blocks. +" + (evil-org-select-inner-element (org-element-at-point))) + +(evil-define-text-object evil-org-a-greater-element (count &optional beg end type) + "A greater (recursive) org element. +Includes tables, list items and subtrees." + (when (null count) (setq count 1)) + (save-excursion + (when beg (goto-char beg)) + (let ((element (org-element-at-point))) + (when (or (not (memq (first element) org-element-greater-elements)) + (and end (>= end (org-element-property :end element)))) + (setq element (evil-org-parent element))) + (dotimes (_ (1- count)) + (setq element (evil-org-parent element))) + (evil-org-select-an-element element)))) + +(evil-define-text-object evil-org-inner-greater-element (count &optional beg end type) + "Inner greater (recursive) org element. +Includes tables, list items and subtrees." + (when (null count) (setq count 1)) + (save-excursion + (when beg (goto-char beg)) + (let ((element (org-element-at-point))) + (unless (memq (first element) org-element-greater-elements) + (setq element (evil-org-parent element))) + (dotimes (_ (1- count)) + (setq element (evil-org-parent element))) + (evil-org-select-inner-element element)))) + +(evil-define-text-object evil-org-a-subtree (count &optional beg end type) "An org subtree." + (when (null count) (setq count 1)) (org-with-limited-levels (cond ((org-at-heading-p) (beginning-of-line)) ((org-before-first-heading-p) (user-error "Not in a subtree")) (t (outline-previous-visible-heading 1)))) (when count (while (and (> count 1) (org-up-heading-safe)) (cl-decf count))) - (let ((element (org-element-at-point))) - (list (org-element-property :begin element) - (org-element-property :end element)))) - -(evil-define-text-object evil-org-table-inner-cell (count &optional beg end type) - "Inner org table cell." - (save-excursion - (when (not (looking-back "|\\s-?")) (org-table-beginning-of-field 1)) - (let* ((b (point)) - (e (progn (when (looking-at "\\s-*|") ; empty cells - (right-char) - (setq count (1- count))) - (when (> count 0) (org-table-end-of-field count)) - (point)))) - (list b e)))) - -(evil-define-text-object evil-org-table-a-cell (count &optional beg end type) - "An org table cell." - (save-excursion - (when (not (looking-back "|\\s-?")) (org-table-beginning-of-field 1)) - (list (point) - (dotimes (_ count (point)) - (org-table-next-field))))) - -(evil-define-text-object evil-org-inner-sentence (count &optional beg end type) - "Inner sentence or table cell when in an org table." - (if (org-at-table-p) - (evil-org-table-inner-cell count beg end type) - (evil-a-sentence count beg end type))) - -(evil-define-text-object evil-org-a-sentence (count &optional beg end type) - "Outer sentence or table cell when in an org table." - (if (org-at-table-p) - (evil-org-table-a-cell) - (evil-a-sentence count beg end type))) - -(evil-define-text-object evil-org-inner-paragraph (count &optional beg end type) - "Inner paragraph or table when in an org table." - :type line - (if (org-at-table-p) - (list (org-table-begin) (org-table-end)) - (evil-select-inner-object 'evil-paragraph beg end type count t))) - -(evil-define-text-object evil-org-a-paragraph (count &optional beg end type) - "A paragraph or table when in an org table." - :type line - (if (org-at-table-p) - (let ((p (point)) - (b (org-table-begin)) - (e (org-table-end))) - (list (min (or beg p) b) - (max (or end p) e))) - (evil-select-an-object 'evil-paragraph beg end type count t))) + (evil-org-select-an-element (org-element-at-point))) +(evil-define-text-object evil-org-inner-subtree (count &optional beg end type) + "Inner org subtree." + (when (null count) (setq count 1)) + (org-with-limited-levels + (cond ((org-at-heading-p) (beginning-of-line)) + ((org-before-first-heading-p) (user-error "Not in a subtree")) + (t (outline-previous-visible-heading 1)))) + (when count (while (and (> count 1) (org-up-heading-safe)) (cl-decf count))) + (evil-org-select-inner-element (org-element-at-point))) ;;; Keythemes (defun evil-org--populate-base-bindings () "Bindings that are always available." @@ -467,12 +517,14 @@ If a prefix argument is given, links are opened in incognito mode." (defun evil-org--populate-textobjects-bindings () "Text objects." (dolist (state '(visual operator)) - (evil-define-key state evil-org-mode-map "ae" 'org-element-textobj) - (evil-define-key state evil-org-mode-map "ar" 'org-subtree-textobj) - (evil-define-key state evil-org-mode-map "is" 'evil-org-inner-sentence) - (evil-define-key state evil-org-mode-map "as" 'evil-org-a-sentence) - (evil-define-key state evil-org-mode-map "ip" 'evil-org-inner-paragraph) - (evil-define-key state evil-org-mode-map "ap" 'evil-org-a-paragraph))) + (evil-define-key state evil-org-mode-map "ae" 'evil-org-an-object) + (evil-define-key state evil-org-mode-map "ie" 'evil-org-inner-object) + (evil-define-key state evil-org-mode-map "aE" 'evil-org-an-element) + (evil-define-key state evil-org-mode-map "iE" 'evil-org-inner-element) + (evil-define-key state evil-org-mode-map "ir" 'evil-org-inner-greater-element) + (evil-define-key state evil-org-mode-map "ar" 'evil-org-a-greater-element) + (evil-define-key state evil-org-mode-map "aR" 'evil-org-a-subtree) + (evil-define-key state evil-org-mode-map "iR" 'evil-org-inner-subtree))) (defun evil-org--populate-insert-bindings () "Define insert mode bindings." @@ -525,11 +577,6 @@ If a prefix argument is given, links are opened in incognito mode." (kbd (concat "C-S-" .up)) 'org-shiftcontrolup (kbd (concat "C-S-" .down)) 'org-shiftcontroldown)))) -;; (let ((state (if evil-org-use-additional-insert '(normal insert) 'normal))) -;; (evil-define-key state evil-org-mode-map -;; (kbd "M-o") 'evil-org-insert-subheading -;; (kbd "M-t") 'evil-org-insert-subtodo)) - (defun evil-org--populate-shift-bindings () "Shift bindings that conflict with evil bindings." (let-alist evil-org-movement-bindings |
