* Adding single cell movement to org-table @ 2017-07-27 20:20 Chris Kauffman 2017-07-28 8:19 ` Nicolas Goaziou 2017-07-28 8:53 ` Carsten Dominik 0 siblings, 2 replies; 11+ messages in thread From: Chris Kauffman @ 2017-07-27 20:20 UTC (permalink / raw) To: emacs-orgmode; +Cc: Uwe Brauer [-- Attachment #1: Type: text/plain, Size: 965 bytes --] Greetings from a first-time contributor. Another patch contributor, Uwe Brauer, recruited me after finding some code I had written to move single org-table cells up/down/left/right. I found this feature to be useful in certain kinds of tables so wrote the functions for myself but am told that others might benefit from it. I have formalized that code into a git repo with a feature branch on it which may be found here: https://github.com/kauffman77/org-mode/tree/single-cell-table-move I have included documentation in org-table.el for the new functions and tests for them. If further work or documentation needs to be done, please let me know. I am also not sure if I got the commit messages formatted to the specification mentioned on the contributing page. I am happy to explain more if needed. I just mailed assign@gnu.org to get the copyright for the code resolved but thought I would put up this branch now so others can have a look. Cheers, Chris [-- Attachment #2: Type: text/html, Size: 1226 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2017-07-27 20:20 Adding single cell movement to org-table Chris Kauffman @ 2017-07-28 8:19 ` Nicolas Goaziou 2017-07-29 3:00 ` Chris Kauffman 2017-07-28 8:53 ` Carsten Dominik 1 sibling, 1 reply; 11+ messages in thread From: Nicolas Goaziou @ 2017-07-28 8:19 UTC (permalink / raw) To: Chris Kauffman; +Cc: Uwe Brauer, emacs-orgmode Hello, Chris Kauffman <kauffman@cs.gmu.edu> writes: > Greetings from a first-time contributor. Another patch contributor, Uwe > Brauer, recruited me after finding some code I had written to move single > org-table cells up/down/left/right. I found this feature to be useful in > certain kinds of tables so wrote the functions for myself but am told that > others might benefit from it. > > I have formalized that code into a git repo with a feature branch on it > which may be found here: > https://github.com/kauffman77/org-mode/tree/single-cell-table-move > > I have included documentation in org-table.el for the new functions and > tests for them. If further work or documentation needs to be done, please > let me know. I am also not sure if I got the commit messages formatted to > the specification mentioned on the contributing page. I am happy to > explain more if needed. Thank you. Could you send the patch here? It will ease reviewing it. It will also require an entry in ORG-NEWS and some documentation in org.texi. > I just mailed assign@gnu.org to get the copyright for the code resolved but > thought I would put up this branch now so others can have a look. Great! Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2017-07-28 8:19 ` Nicolas Goaziou @ 2017-07-29 3:00 ` Chris Kauffman 2017-08-03 10:37 ` Nicolas Goaziou 0 siblings, 1 reply; 11+ messages in thread From: Chris Kauffman @ 2017-07-29 3:00 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: Uwe Brauer, emacs-orgmode [-- Attachment #1.1: Type: text/plain, Size: 1766 bytes --] Apologies for the earlier diff-blast: I did not see the advice on the org-mode contributions page that patches generated via git format-patch master are preferred. Please find four patches attached which now include modifications to ORG-NEWS, org.texi, orgguid.texi, and keybindings suggested by Carsten: S-up, S-down, S-left, S-right in org.el (via org-shiftup etc.). Cheers, Chris On Fri, Jul 28, 2017 at 4:19 AM, Nicolas Goaziou <mail@nicolasgoaziou.fr> wrote: > Hello, > > Chris Kauffman <kauffman@cs.gmu.edu> writes: > > > Greetings from a first-time contributor. Another patch contributor, Uwe > > Brauer, recruited me after finding some code I had written to move single > > org-table cells up/down/left/right. I found this feature to be useful in > > certain kinds of tables so wrote the functions for myself but am told > that > > others might benefit from it. > > > > I have formalized that code into a git repo with a feature branch on it > > which may be found here: > > https://github.com/kauffman77/org-mode/tree/single-cell-table-move > > > > I have included documentation in org-table.el for the new functions and > > tests for them. If further work or documentation needs to be done, > please > > let me know. I am also not sure if I got the commit messages formatted to > > the specification mentioned on the contributing page. I am happy to > > explain more if needed. > > Thank you. > > Could you send the patch here? It will ease reviewing it. > > It will also require an entry in ORG-NEWS and some documentation in > org.texi. > > > I just mailed assign@gnu.org to get the copyright for the code resolved > but > > thought I would put up this branch now so others can have a look. > > Great! > > Regards, > > -- > Nicolas Goaziou > [-- Attachment #1.2: Type: text/html, Size: 2606 bytes --] [-- Attachment #2: 0005-Modified-orgguide.texi-to-include-documentation-of-s.patch --] [-- Type: text/x-patch, Size: 849 bytes --] From b43054c9892f7e08fa958bcb5d8df978e6392d57 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:46:12 -0400 Subject: [PATCH 5/5] Modified orgguide.texi to include documentation of single cell movement functions. --- doc/orgguide.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/orgguide.texi b/doc/orgguide.texi index 8c91aae3a..fc5c0c22c 100644 --- a/doc/orgguide.texi +++ b/doc/orgguide.texi @@ -647,6 +647,12 @@ Re-align, move to previous field. @item @key{RET} Re-align the table and move down to next row. Creates a new row if necessary. +@c +@item S-@key{up} +@itemx S-@key{down} +@itemx S-@key{left} +@itemx S-@key{right} +Move single cells up, down, left, and right by swapping with adjacent cells. @tsubheading{Column and row editing} @item M-@key{left} -- 2.12.2 [-- Attachment #3: 0004-Modified-org.texi-to-include-documentation-of-single.patch --] [-- Type: text/x-patch, Size: 1125 bytes --] From 6682b22642c34f61feee27cd44a503dd4c21e9cb Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:37:31 -0400 Subject: [PATCH 4/5] Modified org.texi to include documentation of single cell movement functions. --- doc/org.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/org.texi b/doc/org.texi index 101d532e3..55c8ebd27 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -2156,6 +2156,12 @@ NEWLINE, so it can be used to split a table. Move to beginning of the current table field, or on to the previous field. @orgcmd{M-e,org-table-end-of-field} Move to end of the current table field, or on to the next field. +@c +@orgcmd{S-@key{up},org-table-move-single-cell-up} +@orgcmd{S-@key{down},org-table-move-single-cell-down} +@orgcmd{S-@key{left},org-table-move-single-cell-left} +@orgcmd{S-@key{right},org-table-move-single-cell-right} +Move single cells up, down, left, and right by swapping with adjacent cells. @tsubheading{Column and row editing} @orgcmdkkcc{M-@key{left},M-@key{right},org-table-move-column-left,org-table-move-column-right} -- 2.12.2 [-- Attachment #4: 0003-Updates-to-ORG-NEWS-describing-single-cell-movement-.patch --] [-- Type: text/x-patch, Size: 1516 bytes --] From 6be32b39c590d003be75a33033bb3301a11db483 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:18:28 -0400 Subject: [PATCH 3/5] Updates to ORG-NEWS describing single-cell movement functions. --- etc/ORG-NEWS | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index d7bd3e2ce..05efce4f4 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -291,6 +291,11 @@ This variable allow computed durations in tables to be zero-padded. *** New mode switch for table formulas : =U= This mode omits seconds in durations. +*** New single table cell movement options : ~org-table-move-single-cell-up~ +Shift-Up, Shift-Down, Shift-Right, and Shift-Left now move single +table cells in the corresponding directions by swapping with the +adjacent cell. + ** Removed functions *** Org Timeline @@ -368,6 +373,21 @@ It is the reciprocal of ~org-list-to-lisp~, which see. Call ~org-agenda-set-restriction-lock~ from the agenda. +*** ~org-table-move-single-cell~ and related + +Four new user functions to move single table cells in cardinal +directions. + +- ~org-table-move-single-cell-up~ +- ~org-table-move-single-cell-down~ +- ~org-table-move-single-cell-left~ +- ~org-table-move-single-cell-right~ + +Support functions which are used to facilitate single cell movement. +- ~org-table-move-single-cell~ +- ~org-table-swap-cells~ +- ~org-table-max-line-col~ + ** Miscellaneous *** Allow multiple columns view -- 2.12.2 [-- Attachment #5: 0002-Added-keybindings-for-org-table-move-single-cell-fun.patch --] [-- Type: text/x-patch, Size: 4606 bytes --] From 9c900805937ebc21d468612d1c594381cca53cd2 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:06:05 -0400 Subject: [PATCH 2/5] Added keybindings for org-table-move-single-cell-* functions: S-up, S-down, etc. Done via modifications to org-shiftup, org-shiftdown, etc. Dispatching at the end of available contexts between behavior for clock table and function hooks. --- lisp/org.el | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 44abc0dbe..fc740bdca 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -20477,8 +20477,10 @@ commands for more information." (defun org-shiftup (&optional arg) "Increase item in timestamp or increase priority of current headline. -Calls `org-timestamp-up' or `org-priority-up', or `org-previous-item', -depending on context. See the individual commands for more information." +Calls `org-timestamp-up' or `org-priority-up', or +`org-previous-item', or `org-table-move-single-cell-up', +depending on context. See the individual commands for more +information." (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftup-hook)) @@ -20494,6 +20496,7 @@ depending on context. See the individual commands for more information." ((and (not org-support-shift-select) (org-at-item-p)) (call-interactively 'org-previous-item)) ((org-clocktable-try-shift 'up arg)) + ((org-at-table-p) (org-table-move-single-cell-up)) ((run-hook-with-args-until-success 'org-shiftup-final-hook)) (org-support-shift-select (org-call-for-shift-select 'previous-line)) @@ -20501,8 +20504,9 @@ depending on context. See the individual commands for more information." (defun org-shiftdown (&optional arg) "Decrease item in timestamp or decrease priority of current headline. -Calls `org-timestamp-down' or `org-priority-down', or `org-next-item' -depending on context. See the individual commands for more information." +Calls `org-timestamp-down' or `org-priority-down', or +`org-next-item', or `org-table-move-single-cell-down', depending +on context. See the individual commands for more information." (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftdown-hook)) @@ -20518,6 +20522,7 @@ depending on context. See the individual commands for more information." ((and (not org-support-shift-select) (org-at-item-p)) (call-interactively 'org-next-item)) ((org-clocktable-try-shift 'down arg)) + ((org-at-table-p) (org-table-move-single-cell-down)) ((run-hook-with-args-until-success 'org-shiftdown-final-hook)) (org-support-shift-select (org-call-for-shift-select 'next-line)) @@ -20531,7 +20536,8 @@ Depending on context, this does one of the following: - on a headline, switch to the next TODO keyword. - on an item, switch entire list to the next bullet type - on a property line, switch to the next allowed value -- on a clocktable definition line, move time block into the future" +- on a clocktable definition line, move time block into the future +- on a normal table, move a single cell right" (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftright-hook)) @@ -20554,6 +20560,7 @@ Depending on context, this does one of the following: (org-at-property-p)) (call-interactively 'org-property-next-allowed-value)) ((org-clocktable-try-shift 'right arg)) + ((org-at-table-p) (org-table-move-single-cell-right)) ((run-hook-with-args-until-success 'org-shiftright-final-hook)) (org-support-shift-select (org-call-for-shift-select 'forward-char)) @@ -20567,7 +20574,8 @@ Depending on context, this does one of the following: - on a headline, switch to the previous TODO keyword. - on an item, switch entire list to the previous bullet type - on a property line, switch to the previous allowed value -- on a clocktable definition line, move time block into the past" +- on a clocktable definition line, move time block into the past +- on a normal table, move a single cell left" (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftleft-hook)) @@ -20590,6 +20598,7 @@ Depending on context, this does one of the following: (org-at-property-p)) (call-interactively 'org-property-previous-allowed-value)) ((org-clocktable-try-shift 'left arg)) + ((org-at-table-p) (org-table-move-single-cell-left)) ((run-hook-with-args-until-success 'org-shiftleft-final-hook)) (org-support-shift-select (org-call-for-shift-select 'backward-char)) -- 2.12.2 [-- Attachment #6: 0001-org-table-Adding-single-cell-movement-functions-and-.patch --] [-- Type: text/x-patch, Size: 16529 bytes --] From 6f50526fa642ea74716dd4668e2b36b0ff9c6134 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Sun, 23 Jul 2017 00:13:11 -0400 Subject: [PATCH 1/5] org-table: Adding single cell movement functions and tests. * org-mode/lisp/org-table.el: New functions for single table cell movement such as (org-table-move-single-cell-down) * testing/lisp/test-org-table.el: Added tests for single table cell movement such as (test-org-table/move-single-cell-down) --- lisp/org-table.el | 71 ++++++++ testing/lisp/test-org-table.el | 385 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 456 insertions(+) diff --git a/lisp/org-table.el b/lisp/org-table.el index 37e40de1e..2b80bfc3a 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -1437,6 +1437,77 @@ non-nil, the one above is used." (if above min max)))))) ;;;###autoload +(defun org-table-max-line-col () + "Return the maximum line and column of the current table as a +list of two numbers" + (when (not (org-at-table-p)) + (user-error "Not in an org-table")) + (let ((table-end (org-table-end))) + (save-mark-and-excursion + (goto-char table-end) + (org-table-previous-field) + (list (org-table-current-line) (org-table-current-column))))) + +;;;###autoload +(defun org-table-swap-cells (row1 col1 row2 col2) + "Swap two cells indicated by the coordinates provided" + (let ((content1 (org-table-get row1 col1)) + (content2 (org-table-get row2 col2))) + (org-table-put row1 col1 content2) + (org-table-put row2 col2 content1) + (org-table-align))) + +;;;###autoload +(defun org-table-move-single-cell (direction) + "Move the current cell in a cardinal direction according to the +parameter symbol: 'up 'down 'left 'right. Swaps contents of +adjacent cell with current one." + (unless (org-at-table-p) + (error "No table at point")) + (let ((drow 0) (dcol 0)) + (cond ((equal direction 'up) (setq drow -1)) + ((equal direction 'down) (setq drow +1)) + ((equal direction 'left) (setq dcol -1)) + ((equal direction 'right) (setq dcol +1)) + (t (error "Not a valid direction, must be one of 'up 'down 'left 'right"))) + (let* ((row1 (org-table-current-line)) + (col1 (org-table-current-column)) + (row2 (+ row1 drow)) + (col2 (+ col1 dcol)) + (max-row-col (org-table-max-line-col)) + (max-row (car max-row-col)) + (max-col (cadr max-row-col))) + (when (or (< col1 1) (< col2 1) (> col2 max-col) (< row2 1) (> row2 max-row)) + (user-error "Cannot move cell further")) + (org-table-swap-cells row1 col1 row2 col2) + (org-table-goto-line row2) + (org-table-goto-column col2)))) + +;;;###autoload +(defun org-table-move-single-cell-up () + "Move a single cell up in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'up)) + +;;;###autoload +(defun org-table-move-single-cell-down () + "Move a single cell down in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'down)) + +;;;###autoload +(defun org-table-move-single-cell-left () + "Move a single cell left in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'left)) + +;;;###autoload +(defun org-table-move-single-cell-right () + "Move a single cell right in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'right)) + +;;;###autoload (defun org-table-delete-column () "Delete a column from the table." (interactive) diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el index 99f593c25..de9a1ad4b 100644 --- a/testing/lisp/test-org-table.el +++ b/testing/lisp/test-org-table.el @@ -2102,6 +2102,391 @@ is t, then new columns should be added as needed" \f +;;; Moving single cells +(ert-deftest test-org-table/move-single-cell-down () + "Test `org-table-move-single-cell-down' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last row of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a | <point>b |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a | b |\n| <point>c | d |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a | b |\n| c | <point>d |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-down))) + ;; Check for correct cell movement + (should (equal (concat "| c | b |\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b |\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "| c | b |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | <point>b |\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "| e | d |\n" + "| c | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| <point>c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "| c | f |\n" + "| e | b |\n") + (org-test-with-temp-text + (concat "| a |<point> b |\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (org-table-move-single-cell-down) + (buffer-string)))) + ;; Check for correct handling of hlines which should not change + ;; position on single cell moves + (should (equal (concat "| c | b |\n" + "|---+---|\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "|---+---|\n" + "| c | f |\n" + "| e | b |\n") + (org-test-with-temp-text + (concat "| a | <point>b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "|---+---|\n" + "| c | f |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | <point>d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | d |\n" + "|---+---|\n" + "| c | f |\n" + "| e | b |\n") + (org-test-with-temp-text + (concat "| a | <point>b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | f |") + (org-table-move-single-cell-down) + (org-table-move-single-cell-down) + (buffer-string))))) +(ert-deftest test-org-table/move-single-cell-up () + "Test `org-table-move-single-cell-up' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last row of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| <point>a | b |\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| a | <point>b |\n| c | d |\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-up))) + ;; Check for correct cell movement + (should (equal (concat "| c | b |\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| <point>c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "| c | b |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| c | <point>d |\n" + "| e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "| e | d |\n" + "| c | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| c | d |\n" + "| <point>e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | f |\n" + "| c | b |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| c | d |\n" + "| e |<point> f |\n") + (org-table-move-single-cell-up) + (org-table-move-single-cell-up) + (buffer-string)))) + ;; Check for correct handling of hlines which should not change + ;; position on single cell moves + (should (equal (concat "| c | b |\n" + "|---+---|\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| <point>c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | f |\n" + "|---+---|\n" + "| c | b |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | <point>f |\n") + (org-table-move-single-cell-up) + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "|---+---|\n" + "| c | f |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | <point>f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | f |\n" + "|---+---|\n" + "| c | b |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | <point>f |") + (org-table-move-single-cell-up) + (org-table-move-single-cell-up) + (buffer-string))))) +(ert-deftest test-org-table/move-single-cell-right () + "Test `org-table-move-single-cell-right' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last col of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| <point>a |\n| b |\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| a | <point>b |\n| c | d |\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-right))) + ;; Check for correct cell movement + (should (equal (concat "| b | a | c |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b | c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| b | c | a |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b | c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-right) + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| e | f | d |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| <point> d | e | f |\n") + (org-table-move-single-cell-right) + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| d | f | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| d | <point>e | f |\n") + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| e | f | d |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| <point>d | e | f |\n") + (org-table-move-single-cell-right) + (org-table-move-single-cell-right) + (buffer-string)))) + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| e | d | f |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| <point>d | e | f |") + (org-table-move-single-cell-right) + (buffer-string))))) +(ert-deftest test-org-table/move-single-cell-left () + "Test `org-table-move-single-cell-left' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last col of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| <point>a |\n| b |\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| <point>a | b |\n| c | d |\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-left))) + ;; Check for correct cell movement + (should (equal (concat "| b | a | c |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| a | <point>b | c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| c | a | b |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| a | b | <point>c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-left) + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| f | d | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| d | e | <point>f |\n") + (org-table-move-single-cell-left) + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| d | f | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| d | e | <point>f |\n") + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| f | d | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| d | e | <point>f |\n") + (org-table-move-single-cell-left) + (org-table-move-single-cell-left) + (buffer-string)))) + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| e | d | f |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| d | <point>e | f |") + (org-table-move-single-cell-left) + (buffer-string)))) + ) + +\f ;;; Moving rows, moving columns (ert-deftest test-org-table/move-row-down () -- 2.12.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2017-07-29 3:00 ` Chris Kauffman @ 2017-08-03 10:37 ` Nicolas Goaziou 2018-05-04 12:29 ` stardiviner 0 siblings, 1 reply; 11+ messages in thread From: Nicolas Goaziou @ 2017-08-03 10:37 UTC (permalink / raw) To: Chris Kauffman; +Cc: Uwe Brauer, emacs-orgmode Hello, Chris Kauffman <kauffman@cs.gmu.edu> writes: > Apologies for the earlier diff-blast: I did not see the advice on the > org-mode contributions page that patches generated via > git format-patch master > are preferred. Please find four patches attached which now include > modifications to ORG-NEWS, org.texi, orgguid.texi, and keybindings > suggested by Carsten: S-up, S-down, S-left, S-right in org.el (via > org-shiftup etc.). Thank you! Some comments follow. > ;;;###autoload > +(defun org-table-max-line-col () > + "Return the maximum line and column of the current table as a > +list of two numbers" > + (when (not (org-at-table-p)) > + (user-error "Not in an org-table")) > + (let ((table-end (org-table-end))) > + (save-mark-and-excursion > + (goto-char table-end) > + (org-table-previous-field) > + (list (org-table-current-line) (org-table-current-column))))) I don't think this function is necessary. There is already a similar mechanism with `org-table-current-ncol' and `org-table-current-dlines'. Besides, you only need to check if point is within the table, which is trivial: (skip-chars-backward " \t") (or (bolp) (looking-at-p "[ \t]*$")) for the row, `org-table-goto-line' returns nil if there is no such line. > +;;;###autoload > +(defun org-table-swap-cells (row1 col1 row2 col2) > + "Swap two cells indicated by the coordinates provided" Final dot missing. ROW1 COL1 ROW2 COL2 should be explained. > + (let ((content1 (org-table-get row1 col1)) > + (content2 (org-table-get row2 col2))) > + (org-table-put row1 col1 content2) > + (org-table-put row2 col2 content1) > + (org-table-align))) This function can be made internal: no need to autoload it, and rename it as `org-table--swap-cells'. Besides, it shouldn't call `org-table-align', which is out of its scope. > +;;;###autoload > +(defun org-table-move-single-cell (direction) > + "Move the current cell in a cardinal direction according to the First line should be a sentence on its own. DIRECTION should be more explicit in the docstring. > +parameter symbol: 'up 'down 'left 'right. Swaps contents of `up', `down', `left' or `right'. Also, mind the two spaces after a full stop. > +adjacent cell with current one." > + (unless (org-at-table-p) > + (error "No table at point")) > + (let ((drow 0) (dcol 0)) > + (cond ((equal direction 'up) (setq drow -1)) > + ((equal direction 'down) (setq drow +1)) > + ((equal direction 'left) (setq dcol -1)) > + ((equal direction 'right) (setq dcol +1)) > + (t (error "Not a valid direction, must be one of 'up 'down 'left 'right"))) > + (let* ((row1 (org-table-current-line)) > + (col1 (org-table-current-column)) > + (row2 (+ row1 drow)) > + (col2 (+ col1 dcol)) > + (max-row-col (org-table-max-line-col)) > + (max-row (car max-row-col)) > + (max-col (cadr max-row-col))) > + (when (or (< col1 1) (< col2 1) (> col2 max-col) (< row2 1) (> row2 max-row)) > + (user-error "Cannot move cell further")) > + (org-table-swap-cells row1 col1 row2 col2) > + (org-table-goto-line row2) > + (org-table-goto-column col2)))) This should be an internal function: `org-table--move-single-cell', and not autoloaded. As an internal function, there is no need to check for `org-at-table-p'. It's the responsibility of the callers to do so. Also, `org-table-check-inside-data-field' is more appropriate here. > +;;;###autoload > +(defun org-table-move-single-cell-up () > + "Move a single cell up in a table; swap with anything in target cell" Missing final full stop. > + (interactive) > + (org-table-move-single-cell 'up)) Per above, I suggest adding (org-table-check-inside-data-field) after the (interactive). The same goes for the other functions. Could you send an updated patch? Regards, -- Nicolas Goaziou 0x80A93738 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2017-08-03 10:37 ` Nicolas Goaziou @ 2018-05-04 12:29 ` stardiviner 2018-05-04 14:04 ` Chris Kauffman 0 siblings, 1 reply; 11+ messages in thread From: stardiviner @ 2018-05-04 12:29 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: Chris Kauffman, emacs-orgmode, Uwe Brauer Hi, dear Nicolas. Is this patch merged or not? I "git log --grep 'cell'", have not found this commit. Does this patch move single cell or move single row/column? Currently, Org-mode built-in movement support for row and column only. -- [ stardiviner ] don't need to convince with trends. Blog: https://stardiviner.github.io/ IRC(freenode): stardiviner GPG: F09F650D7D674819892591401B5DF1C95AE89AC3 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2018-05-04 12:29 ` stardiviner @ 2018-05-04 14:04 ` Chris Kauffman 2018-05-04 14:31 ` Uwe Brauer 2018-05-05 0:18 ` stardiviner 0 siblings, 2 replies; 11+ messages in thread From: Chris Kauffman @ 2018-05-04 14:04 UTC (permalink / raw) To: numbchild; +Cc: Uwe Brauer, emacs-orgmode, Nicolas Goaziou [-- Attachment #1: Type: text/plain, Size: 1288 bytes --] I was the original person who was working on code for single cell movement but got distracted by a move to the midwest, job change, and marriage. I will attempt to complete the code in the next month to submit a patch. Chris Kauffman On Fri, May 4, 2018 at 7:29 AM, stardiviner <numbchild@gmail.com> wrote: > Hi, dear Nicolas. Is this patch merged or not? > I "git log --grep 'cell'", have not found this commit. > Does this patch move single cell or move single row/column? > Currently, Org-mode built-in movement support for row and column only. > > -- > [ stardiviner ] don't need to convince with trends. > Blog: https://secure-web.cisco.com/1sdj- > xZLR6NqcfmWcqPL8xws9NwGLGIqxtf3bLvpn-RTcdJC0NapZkgAE_S_L7_ > 7FQ8W1k3rTbTZzLaYAAiRF8n8fIQJT5s0Sr-4G3n3a-hyOiksPjPSA_1BnaCm- > Fg7Amnwx2bB5F9wCuHrxtDhxEHh6RXVg03NeXnLzw_YjFaS8w5gvnhWqSIy9hZvn6aOWvlkP > Dy1hes_WNng6C3Qxy6ihxmpaPnSxvogd_rE1Ze31NZLD9Sv78ivAZwFmVIo7XHM > oqs7veAKqUQC34vVSTuuFOHTYwq6owLfaqIjwmM0PfF0pwhisMsEg9TUH_q11NPRKZmq_ > QDFgqNXgPAjptiFrPBU1l9t4IUw_Bv9YCoAoqT7ZLERUfLPj_ > 9osdz3g18A6DgpJuCUNJBlInzsqGSP5zv6-v7yXKRFHr61Q24_z0nNUeUzMneqeCHpRL13- > i7admqXNqD-HAlBD1WxP1g/https%3A%2F%2Fstardiviner.github.io%2F > IRC(freenode): stardiviner > GPG: F09F650D7D674819892591401B5DF1C95AE89AC3 > > > [-- Attachment #2: Type: text/html, Size: 2418 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2018-05-04 14:04 ` Chris Kauffman @ 2018-05-04 14:31 ` Uwe Brauer 2018-05-05 0:18 ` stardiviner 1 sibling, 0 replies; 11+ messages in thread From: Uwe Brauer @ 2018-05-04 14:31 UTC (permalink / raw) To: Chris Kauffman; +Cc: Uwe Brauer, emacs-orgmode, Nicolas Goaziou [-- Attachment #1: Type: text/plain, Size: 373 bytes --] >>> "Chris" == Chris Kauffman <kauffman@cs.gmu.edu> writes: > I was the original person who was working on code for single cell movement > but got distracted by a move to the midwest, job change, and marriage. I > will attempt to complete the code in the next month to submit a patch. All very good reasons, especially the last one! All the best to both of you. [-- Attachment #2: smime.p7s --] [-- Type: application/pkcs7-signature, Size: 5025 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2018-05-04 14:04 ` Chris Kauffman 2018-05-04 14:31 ` Uwe Brauer @ 2018-05-05 0:18 ` stardiviner 2018-05-29 20:29 ` Chris Kauffman 1 sibling, 1 reply; 11+ messages in thread From: stardiviner @ 2018-05-05 0:18 UTC (permalink / raw) To: Chris Kauffman; +Cc: Uwe Brauer, emacs-orgmode, Nicolas Goaziou That's really great. Thanks. -- [ stardiviner ] don't need to convince with trends. Blog: https://stardiviner.github.io/ IRC(freenode): stardiviner GPG: F09F650D7D674819892591401B5DF1C95AE89AC3 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2018-05-05 0:18 ` stardiviner @ 2018-05-29 20:29 ` Chris Kauffman 2018-06-13 13:35 ` Nicolas Goaziou 0 siblings, 1 reply; 11+ messages in thread From: Chris Kauffman @ 2018-05-29 20:29 UTC (permalink / raw) To: 路Ricardo M.; +Cc: Uwe Brauer, emacs-orgmode, Nicolas Goaziou [-- Attachment #1.1: Type: text/plain, Size: 2085 bytes --] All- Attached are the updated patches for single cell movement in org tables. Notes: - Implemented all of Nicolas Goaziou's suggestions on this with some caveats described below - Part of the logic of the code requires boundary checking. I used the (org-table-analyze) to set variables org-table-current-ncol and org-table-dlines which are the limits of the table. This eliminated an internal helper function in the original version. - I made several of the functions internal with the naming convention `org-table--name' as per Nicolas' suggestion - Checks for in-table and table alignment are in the top-level functions `org-table-move-single-cell-up' etc.; I kept alignment in as otherwise the table looks awful as cells move around - Modified org.el to bind these to Shift-up and the like as per Carsten's suggestion - Tests defined in testing/lisp/org-test-table.el and I've done a fair amount of interactive testing to ensure the behavior looks correct. - Not sure if the patches will work exactly correctly due to the large gap in time between my initial work and completion; let me know if things don't look correct. - Attempted to get close to a correctly formatted commit messages but do make any necessary formatting changes for compliance. Cheers, Chris Kauffman On Fri, May 4, 2018 at 7:18 PM, stardiviner <numbchild@gmail.com> wrote: > That's really great. Thanks. > > -- > [ stardiviner ] don't need to convince with trends. > Blog: https://secure-web.cisco.com/1hJRqsuxlpwmP971H8dAeGulRNSKNY > 87qhElIE0kGFNVU8wi5u2jTzEhayLSBa8GhYPZPyxSM3aWcEqi0yTtMPyedB > ey2od2ROikNbAYTnTptEFLNGp6HovNx1ukbSykVmN4jthKPhqhL- > zPqBtiblX6c8EibrNqBfI2YR_DfuTSNew8YeBmyRu0Mr_ > et5PfrTaMoyrIurSC1ogXRXRMh8ds6CXnNjU7bhWZeOcjRQfyLbssZQ- > zuRp5pSm2JMyC0h7QmqikJC6pNGBrSYPaxd37aLkMNyqhF6LyEpq2LrpWkms4s56sq9R4_ > MUrvT16dpqMPPcp1pfA1DAaPt0DBOlZIDWuieyVZSmscuGyWN6hhiYyTc0EY-_ > iwmxe0UCfRK4t0adbHcAj0cYCdGjgliGOk9jHInQTGngBOSNT_htY/https% > 3A%2F%2Fstardiviner.github.io%2F > IRC(freenode): stardiviner > GPG: F09F650D7D674819892591401B5DF1C95AE89AC3 > > > [-- Attachment #1.2: Type: text/html, Size: 3360 bytes --] [-- Attachment #2: 0001-org-table-Adding-single-cell-movement-functions-and-.patch --] [-- Type: text/x-patch, Size: 16530 bytes --] From 6f50526fa642ea74716dd4668e2b36b0ff9c6134 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Sun, 23 Jul 2017 00:13:11 -0400 Subject: [PATCH 1/8] org-table: Adding single cell movement functions and tests. * org-mode/lisp/org-table.el: New functions for single table cell movement such as (org-table-move-single-cell-down) * testing/lisp/test-org-table.el: Added tests for single table cell movement such as (test-org-table/move-single-cell-down) --- lisp/org-table.el | 71 ++++++ testing/lisp/test-org-table.el | 385 +++++++++++++++++++++++++++++++++ 2 files changed, 456 insertions(+) diff --git a/lisp/org-table.el b/lisp/org-table.el index 37e40de1e..2b80bfc3a 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -1436,6 +1436,77 @@ non-nil, the one above is used." (t (setq min mean))))) (if above min max)))))) +;;;###autoload +(defun org-table-max-line-col () + "Return the maximum line and column of the current table as a +list of two numbers" + (when (not (org-at-table-p)) + (user-error "Not in an org-table")) + (let ((table-end (org-table-end))) + (save-mark-and-excursion + (goto-char table-end) + (org-table-previous-field) + (list (org-table-current-line) (org-table-current-column))))) + +;;;###autoload +(defun org-table-swap-cells (row1 col1 row2 col2) + "Swap two cells indicated by the coordinates provided" + (let ((content1 (org-table-get row1 col1)) + (content2 (org-table-get row2 col2))) + (org-table-put row1 col1 content2) + (org-table-put row2 col2 content1) + (org-table-align))) + +;;;###autoload +(defun org-table-move-single-cell (direction) + "Move the current cell in a cardinal direction according to the +parameter symbol: 'up 'down 'left 'right. Swaps contents of +adjacent cell with current one." + (unless (org-at-table-p) + (error "No table at point")) + (let ((drow 0) (dcol 0)) + (cond ((equal direction 'up) (setq drow -1)) + ((equal direction 'down) (setq drow +1)) + ((equal direction 'left) (setq dcol -1)) + ((equal direction 'right) (setq dcol +1)) + (t (error "Not a valid direction, must be one of 'up 'down 'left 'right"))) + (let* ((row1 (org-table-current-line)) + (col1 (org-table-current-column)) + (row2 (+ row1 drow)) + (col2 (+ col1 dcol)) + (max-row-col (org-table-max-line-col)) + (max-row (car max-row-col)) + (max-col (cadr max-row-col))) + (when (or (< col1 1) (< col2 1) (> col2 max-col) (< row2 1) (> row2 max-row)) + (user-error "Cannot move cell further")) + (org-table-swap-cells row1 col1 row2 col2) + (org-table-goto-line row2) + (org-table-goto-column col2)))) + +;;;###autoload +(defun org-table-move-single-cell-up () + "Move a single cell up in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'up)) + +;;;###autoload +(defun org-table-move-single-cell-down () + "Move a single cell down in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'down)) + +;;;###autoload +(defun org-table-move-single-cell-left () + "Move a single cell left in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'left)) + +;;;###autoload +(defun org-table-move-single-cell-right () + "Move a single cell right in a table; swap with anything in target cell" + (interactive) + (org-table-move-single-cell 'right)) + ;;;###autoload (defun org-table-delete-column () "Delete a column from the table." diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el index 99f593c25..de9a1ad4b 100644 --- a/testing/lisp/test-org-table.el +++ b/testing/lisp/test-org-table.el @@ -2102,6 +2102,391 @@ is t, then new columns should be added as needed" \f +;;; Moving single cells +(ert-deftest test-org-table/move-single-cell-down () + "Test `org-table-move-single-cell-down' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last row of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a | <point>b |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a | b |\n| <point>c | d |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| a | b |\n| c | <point>d |\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-down))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-down))) + ;; Check for correct cell movement + (should (equal (concat "| c | b |\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b |\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "| c | b |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | <point>b |\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "| e | d |\n" + "| c | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| <point>c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "| c | f |\n" + "| e | b |\n") + (org-test-with-temp-text + (concat "| a |<point> b |\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (org-table-move-single-cell-down) + (buffer-string)))) + ;; Check for correct handling of hlines which should not change + ;; position on single cell moves + (should (equal (concat "| c | b |\n" + "|---+---|\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "|---+---|\n" + "| c | f |\n" + "| e | b |\n") + (org-test-with-temp-text + (concat "| a | <point>b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (org-table-move-single-cell-down) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "|---+---|\n" + "| c | f |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | <point>d |\n" + "| e | f |\n") + (org-table-move-single-cell-down) + (buffer-string)))) + + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | d |\n" + "|---+---|\n" + "| c | f |\n" + "| e | b |\n") + (org-test-with-temp-text + (concat "| a | <point>b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | f |") + (org-table-move-single-cell-down) + (org-table-move-single-cell-down) + (buffer-string))))) +(ert-deftest test-org-table/move-single-cell-up () + "Test `org-table-move-single-cell-up' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last row of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| <point>a | b |\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| a | <point>b |\n| c | d |\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-up))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-up))) + ;; Check for correct cell movement + (should (equal (concat "| c | b |\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| <point>c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | d |\n" + "| c | b |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| c | <point>d |\n" + "| e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "| e | d |\n" + "| c | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| c | d |\n" + "| <point>e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | f |\n" + "| c | b |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "| c | d |\n" + "| e |<point> f |\n") + (org-table-move-single-cell-up) + (org-table-move-single-cell-up) + (buffer-string)))) + ;; Check for correct handling of hlines which should not change + ;; position on single cell moves + (should (equal (concat "| c | b |\n" + "|---+---|\n" + "| a | d |\n" + "| e | f |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| <point>c | d |\n" + "| e | f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | f |\n" + "|---+---|\n" + "| c | b |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | <point>f |\n") + (org-table-move-single-cell-up) + (org-table-move-single-cell-up) + (buffer-string)))) + (should (equal (concat "| a | b |\n" + "|---+---|\n" + "| c | f |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | <point>f |\n") + (org-table-move-single-cell-up) + (buffer-string)))) + + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | f |\n" + "|---+---|\n" + "| c | b |\n" + "| e | d |\n") + (org-test-with-temp-text + (concat "| a | b |\n" + "|---+---|\n" + "| c | d |\n" + "| e | <point>f |") + (org-table-move-single-cell-up) + (org-table-move-single-cell-up) + (buffer-string))))) +(ert-deftest test-org-table/move-single-cell-right () + "Test `org-table-move-single-cell-right' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last col of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| <point>a |\n| b |\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| a | <point>b |\n| c | d |\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-right))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-right))) + ;; Check for correct cell movement + (should (equal (concat "| b | a | c |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b | c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| b | c | a |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| <point>a | b | c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-right) + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| e | f | d |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| <point> d | e | f |\n") + (org-table-move-single-cell-right) + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| d | f | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| d | <point>e | f |\n") + (org-table-move-single-cell-right) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| e | f | d |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| <point>d | e | f |\n") + (org-table-move-single-cell-right) + (org-table-move-single-cell-right) + (buffer-string)))) + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| e | d | f |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| <point>d | e | f |") + (org-table-move-single-cell-right) + (buffer-string))))) +(ert-deftest test-org-table/move-single-cell-left () + "Test `org-table-move-single-cell-left' specifications." + ;; Error out when cell cannot be moved due to not in table, + ;; in the last col of the table, or is on a hline + (should-error + (org-test-with-temp-text "not in\na table\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| a |" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| a |\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| <point>a |\n| b |\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| <point>a | b |\n| c | d |\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "| <point>a |\n|---|\n" + (org-table-move-single-cell-left))) + (should-error + (org-test-with-temp-text "|<point>---|\n| a |\n" + (org-table-move-single-cell-left))) + ;; Check for correct cell movement + (should (equal (concat "| b | a | c |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| a | <point>b | c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| c | a | b |\n" + "| d | e | f |\n") + (org-test-with-temp-text + (concat "| a | b | <point>c |\n" + "| d | e | f |\n") + (org-table-move-single-cell-left) + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| f | d | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| d | e | <point>f |\n") + (org-table-move-single-cell-left) + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "| d | f | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "| d | e | <point>f |\n") + (org-table-move-single-cell-left) + (buffer-string)))) + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| f | d | e |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| d | e | <point>f |\n") + (org-table-move-single-cell-left) + (org-table-move-single-cell-left) + (buffer-string)))) + ;; Move single cell even without a final newline. Seems that some + (should (equal (concat "| a | b | c |\n" + "|---+---+---|\n" + "| e | d | f |\n") + (org-test-with-temp-text + (concat "| a | b | c |\n" + "|---+---+---|\n" + "| d | <point>e | f |") + (org-table-move-single-cell-left) + (buffer-string)))) + ) + +\f ;;; Moving rows, moving columns (ert-deftest test-org-table/move-row-down () -- 2.17.0 [-- Attachment #3: 0002-Added-keybindings-for-org-table-move-single-cell-fun.patch --] [-- Type: text/x-patch, Size: 4606 bytes --] From 9c900805937ebc21d468612d1c594381cca53cd2 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:06:05 -0400 Subject: [PATCH 2/8] Added keybindings for org-table-move-single-cell-* functions: S-up, S-down, etc. Done via modifications to org-shiftup, org-shiftdown, etc. Dispatching at the end of available contexts between behavior for clock table and function hooks. --- lisp/org.el | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 44abc0dbe..fc740bdca 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -20477,8 +20477,10 @@ commands for more information." (defun org-shiftup (&optional arg) "Increase item in timestamp or increase priority of current headline. -Calls `org-timestamp-up' or `org-priority-up', or `org-previous-item', -depending on context. See the individual commands for more information." +Calls `org-timestamp-up' or `org-priority-up', or +`org-previous-item', or `org-table-move-single-cell-up', +depending on context. See the individual commands for more +information." (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftup-hook)) @@ -20494,6 +20496,7 @@ depending on context. See the individual commands for more information." ((and (not org-support-shift-select) (org-at-item-p)) (call-interactively 'org-previous-item)) ((org-clocktable-try-shift 'up arg)) + ((org-at-table-p) (org-table-move-single-cell-up)) ((run-hook-with-args-until-success 'org-shiftup-final-hook)) (org-support-shift-select (org-call-for-shift-select 'previous-line)) @@ -20501,8 +20504,9 @@ depending on context. See the individual commands for more information." (defun org-shiftdown (&optional arg) "Decrease item in timestamp or decrease priority of current headline. -Calls `org-timestamp-down' or `org-priority-down', or `org-next-item' -depending on context. See the individual commands for more information." +Calls `org-timestamp-down' or `org-priority-down', or +`org-next-item', or `org-table-move-single-cell-down', depending +on context. See the individual commands for more information." (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftdown-hook)) @@ -20518,6 +20522,7 @@ depending on context. See the individual commands for more information." ((and (not org-support-shift-select) (org-at-item-p)) (call-interactively 'org-next-item)) ((org-clocktable-try-shift 'down arg)) + ((org-at-table-p) (org-table-move-single-cell-down)) ((run-hook-with-args-until-success 'org-shiftdown-final-hook)) (org-support-shift-select (org-call-for-shift-select 'next-line)) @@ -20531,7 +20536,8 @@ Depending on context, this does one of the following: - on a headline, switch to the next TODO keyword. - on an item, switch entire list to the next bullet type - on a property line, switch to the next allowed value -- on a clocktable definition line, move time block into the future" +- on a clocktable definition line, move time block into the future +- on a normal table, move a single cell right" (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftright-hook)) @@ -20554,6 +20560,7 @@ Depending on context, this does one of the following: (org-at-property-p)) (call-interactively 'org-property-next-allowed-value)) ((org-clocktable-try-shift 'right arg)) + ((org-at-table-p) (org-table-move-single-cell-right)) ((run-hook-with-args-until-success 'org-shiftright-final-hook)) (org-support-shift-select (org-call-for-shift-select 'forward-char)) @@ -20567,7 +20574,8 @@ Depending on context, this does one of the following: - on a headline, switch to the previous TODO keyword. - on an item, switch entire list to the previous bullet type - on a property line, switch to the previous allowed value -- on a clocktable definition line, move time block into the past" +- on a clocktable definition line, move time block into the past +- on a normal table, move a single cell left" (interactive "P") (cond ((run-hook-with-args-until-success 'org-shiftleft-hook)) @@ -20590,6 +20598,7 @@ Depending on context, this does one of the following: (org-at-property-p)) (call-interactively 'org-property-previous-allowed-value)) ((org-clocktable-try-shift 'left arg)) + ((org-at-table-p) (org-table-move-single-cell-left)) ((run-hook-with-args-until-success 'org-shiftleft-final-hook)) (org-support-shift-select (org-call-for-shift-select 'backward-char)) -- 2.17.0 [-- Attachment #4: 0003-Updates-to-ORG-NEWS-describing-single-cell-movement-.patch --] [-- Type: text/x-patch, Size: 1516 bytes --] From 6be32b39c590d003be75a33033bb3301a11db483 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:18:28 -0400 Subject: [PATCH 3/8] Updates to ORG-NEWS describing single-cell movement functions. --- etc/ORG-NEWS | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index d7bd3e2ce..05efce4f4 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -291,6 +291,11 @@ This variable allow computed durations in tables to be zero-padded. *** New mode switch for table formulas : =U= This mode omits seconds in durations. +*** New single table cell movement options : ~org-table-move-single-cell-up~ +Shift-Up, Shift-Down, Shift-Right, and Shift-Left now move single +table cells in the corresponding directions by swapping with the +adjacent cell. + ** Removed functions *** Org Timeline @@ -368,6 +373,21 @@ It is the reciprocal of ~org-list-to-lisp~, which see. Call ~org-agenda-set-restriction-lock~ from the agenda. +*** ~org-table-move-single-cell~ and related + +Four new user functions to move single table cells in cardinal +directions. + +- ~org-table-move-single-cell-up~ +- ~org-table-move-single-cell-down~ +- ~org-table-move-single-cell-left~ +- ~org-table-move-single-cell-right~ + +Support functions which are used to facilitate single cell movement. +- ~org-table-move-single-cell~ +- ~org-table-swap-cells~ +- ~org-table-max-line-col~ + ** Miscellaneous *** Allow multiple columns view -- 2.17.0 [-- Attachment #5: 0004-Modified-org.texi-to-include-documentation-of-single.patch --] [-- Type: text/x-patch, Size: 1125 bytes --] From 6682b22642c34f61feee27cd44a503dd4c21e9cb Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:37:31 -0400 Subject: [PATCH 4/8] Modified org.texi to include documentation of single cell movement functions. --- doc/org.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/org.texi b/doc/org.texi index 101d532e3..55c8ebd27 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -2156,6 +2156,12 @@ NEWLINE, so it can be used to split a table. Move to beginning of the current table field, or on to the previous field. @orgcmd{M-e,org-table-end-of-field} Move to end of the current table field, or on to the next field. +@c +@orgcmd{S-@key{up},org-table-move-single-cell-up} +@orgcmd{S-@key{down},org-table-move-single-cell-down} +@orgcmd{S-@key{left},org-table-move-single-cell-left} +@orgcmd{S-@key{right},org-table-move-single-cell-right} +Move single cells up, down, left, and right by swapping with adjacent cells. @tsubheading{Column and row editing} @orgcmdkkcc{M-@key{left},M-@key{right},org-table-move-column-left,org-table-move-column-right} -- 2.17.0 [-- Attachment #6: 0005-Modified-orgguide.texi-to-include-documentation-of-s.patch --] [-- Type: text/x-patch, Size: 849 bytes --] From b43054c9892f7e08fa958bcb5d8df978e6392d57 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman@ecs.gmu.edu> Date: Fri, 28 Jul 2017 22:46:12 -0400 Subject: [PATCH 5/8] Modified orgguide.texi to include documentation of single cell movement functions. --- doc/orgguide.texi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/orgguide.texi b/doc/orgguide.texi index 8c91aae3a..fc5c0c22c 100644 --- a/doc/orgguide.texi +++ b/doc/orgguide.texi @@ -647,6 +647,12 @@ Re-align, move to previous field. @item @key{RET} Re-align the table and move down to next row. Creates a new row if necessary. +@c +@item S-@key{up} +@itemx S-@key{down} +@itemx S-@key{left} +@itemx S-@key{right} +Move single cells up, down, left, and right by swapping with adjacent cells. @tsubheading{Column and row editing} @item M-@key{left} -- 2.17.0 [-- Attachment #7: 0006-Code-changes-for-single-cell-movement-with-notes.patch --] [-- Type: text/x-patch, Size: 7332 bytes --] From 4f5a8ae4eaed79b52b5f3529102611e06577e439 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman77@gmail.com> Date: Tue, 29 May 2018 14:37:24 -0500 Subject: [PATCH 6/8] Code changes for single-cell movement with notes. This version has some remaining contents and commented code. --- doc/org-manual.org | 24 ++++++++++ lisp/org-table.el | 94 +++++++++++++++++++++++---------------- testing/examples/pub/link | 1 - 3 files changed, 80 insertions(+), 39 deletions(-) delete mode 120000 testing/examples/pub/link diff --git a/doc/org-manual.org b/doc/org-manual.org index 51884ec99..40f542335 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -1577,6 +1577,30 @@ you, configure the option ~org-table-auto-blank-field~. #+findex: org-table-kill-row Kill the current row or horizontal line. +- {{{kbd(S-UP)}}} (~org-table-move-single-cell-up~) :: + + #+kindex: S-UP + #+findex: org-table-move-single-cell-up + Move single cell up by swapping with adjacent cells. + +- {{{kbd(S-DOWN)}}} (~org-table-move-single-cell-down~) :: + + #+kindex: S-DOWN + #+findex: org-table-move-single-cell-down + Move single cell down by swapping with adjacent cells. + +- {{{kbd(S-LEFT)}}} (~org-table-move-single-cell-left~) :: + + #+kindex: S-LEFT + #+findex: org-table-move-single-cell-left + Move single cell left by swapping with adjacent cells. + +- {{{kbd(S-RIGHT)}}} (~org-table-move-single-cell-right~) :: + + #+kindex: S-RIGHT + #+findex: org-table-move-single-cell-right + Move single cell right by swapping with adjacent cells. + - {{{kbd(M-S-DOWN)}}} (~org-table-insert-row~) :: #+kindex: M-S-DOWN diff --git a/lisp/org-table.el b/lisp/org-table.el index e8898a1cb..009f50d19 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -1441,76 +1441,94 @@ non-nil, the one above is used." (t (setq min mean))))) (if above min max)))))) -;;;###autoload -(defun org-table-max-line-col () - "Return the maximum line and column of the current table as a -list of two numbers" - (when (not (org-at-table-p)) - (user-error "Not in an org-table")) - (let ((table-end (org-table-end))) - (save-mark-and-excursion - (goto-char table-end) - (org-table-previous-field) - (list (org-table-current-line) (org-table-current-column))))) - -;;;###autoload -(defun org-table-swap-cells (row1 col1 row2 col2) - "Swap two cells indicated by the coordinates provided" +;; replaced with call to org-table-analyze and use of variables set by it + +;; ;;;###autoload +;; (defun org-table-max-line-col () +;; "Return the maximum line and column of the current table as a +;; list of two numbers" +;; (when (not (org-at-table-p)) +;; (user-error "Not in an org-table")) +;; (let ((table-end (org-table-end))) +;; (save-mark-and-excursion +;; (goto-char table-end) +;; (org-table-previous-field) +;; (list (org-table-current-line) (org-table-current-column))))) + +; ;;;###autoload ;; told not to autoload by Nicolas Goaziou +(defun org-table--swap-cells (row1 col1 row2 col2) + "Swap two cells indicated by the coordinates provided. +row1, col1, row2, col2 are integers indicating the row/column +position of the two cells that will be swapped in the table." (let ((content1 (org-table-get row1 col1)) (content2 (org-table-get row2 col2))) (org-table-put row1 col1 content2) (org-table-put row2 col2 content1) - (org-table-align))) - -;;;###autoload -(defun org-table-move-single-cell (direction) - "Move the current cell in a cardinal direction according to the -parameter symbol: 'up 'down 'left 'right. Swaps contents of -adjacent cell with current one." - (unless (org-at-table-p) - (error "No table at point")) - (let ((drow 0) (dcol 0)) +; (org-table-align) ;; told by Nicolas Goaziou that this is "out of scope" + )) + +; ;;;###autoload ; told not to auto-load by Nicolas Goaziou, also reformatted comment +(defun org-table--move-single-cell (direction) + "Move the current cell in a cardinal direction. +Parameter direction is a symbol which mathes 'up 'down 'left or +'right. The contents the current cell are swapped with cell in +the indicated direction." +;removed check for in table; moved to public functions + (let ((drow 0) (dcol 0)) (cond ((equal direction 'up) (setq drow -1)) ((equal direction 'down) (setq drow +1)) ((equal direction 'left) (setq dcol -1)) ((equal direction 'right) (setq dcol +1)) (t (error "Not a valid direction, must be one of 'up 'down 'left 'right"))) + (org-table-analyze) ;to set org-table-current-ncol and org-table-dlines (let* ((row1 (org-table-current-line)) (col1 (org-table-current-column)) (row2 (+ row1 drow)) (col2 (+ col1 dcol)) - (max-row-col (org-table-max-line-col)) - (max-row (car max-row-col)) - (max-col (cadr max-row-col))) - (when (or (< col1 1) (< col2 1) (> col2 max-col) (< row2 1) (> row2 max-row)) + (org-table-current-nrow (- (length org-table-dlines) 1))) + (when (or (< col1 1) (< col2 1) (< row2 1) + (> col2 org-table-current-ncol) + (> row2 org-table-current-nrow)) (user-error "Cannot move cell further")) - (org-table-swap-cells row1 col1 row2 col2) + (org-table--swap-cells row1 col1 row2 col2) (org-table-goto-line row2) (org-table-goto-column col2)))) ;;;###autoload (defun org-table-move-single-cell-up () - "Move a single cell up in a table; swap with anything in target cell" + "Move a single cell up in a table; swap with anything in target cell." (interactive) - (org-table-move-single-cell 'up)) + (unless (org-table-check-inside-data-field) + (error "No table at point")) + (org-table--move-single-cell 'up) + (org-table-align)) ;;;###autoload (defun org-table-move-single-cell-down () - "Move a single cell down in a table; swap with anything in target cell" + "Move a single cell down in a table; swap with anything in target cell." (interactive) - (org-table-move-single-cell 'down)) + (unless (org-table-check-inside-data-field) + (error "No table at point")) + (org-table--move-single-cell 'down) + (org-table-align)) ;;;###autoload (defun org-table-move-single-cell-left () - "Move a single cell left in a table; swap with anything in target cell" + "Move a single cell left in a table; swap with anything in target cell." (interactive) - (org-table-move-single-cell 'left)) + (unless (org-table-check-inside-data-field) + (error "No table at point")) + (org-table--move-single-cell 'left) + (org-table-align)) ;;;###autoload (defun org-table-move-single-cell-right () - "Move a single cell right in a table; swap with anything in target cell" + "Move a single cell right in a table; swap with anything in target cell." (interactive) - (org-table-move-single-cell 'right)) + (unless (org-table-check-inside-data-field) + (error "No table at point")) + (org-table--move-single-cell 'right) + (org-table-align)) ;;;###autoload (defun org-table-delete-column () diff --git a/testing/examples/pub/link b/testing/examples/pub/link deleted file mode 120000 index 01bb51522..000000000 --- a/testing/examples/pub/link +++ /dev/null @@ -1 +0,0 @@ -../pub-symlink \ No newline at end of file -- 2.17.0 [-- Attachment #8: 0007-org-table.el-Added-single-cell-movement.patch --] [-- Type: text/x-patch, Size: 2435 bytes --] From 84d576b029f02f4880bc5c3f4eb9f7dd0609a729 Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman77@gmail.com> Date: Tue, 29 May 2018 14:44:26 -0500 Subject: [PATCH 7/8] org-table.el: Added single cell movement * lisp/org-table.el: New functions `org-table-move-single-cell-*' along with supporting internal functions. * doc/org-manual.org: Added documentation associated with single cell movement. --- lisp/org-table.el | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/lisp/org-table.el b/lisp/org-table.el index 009f50d19..1c8c97f43 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -1441,21 +1441,6 @@ non-nil, the one above is used." (t (setq min mean))))) (if above min max)))))) -;; replaced with call to org-table-analyze and use of variables set by it - -;; ;;;###autoload -;; (defun org-table-max-line-col () -;; "Return the maximum line and column of the current table as a -;; list of two numbers" -;; (when (not (org-at-table-p)) -;; (user-error "Not in an org-table")) -;; (let ((table-end (org-table-end))) -;; (save-mark-and-excursion -;; (goto-char table-end) -;; (org-table-previous-field) -;; (list (org-table-current-line) (org-table-current-column))))) - -; ;;;###autoload ;; told not to autoload by Nicolas Goaziou (defun org-table--swap-cells (row1 col1 row2 col2) "Swap two cells indicated by the coordinates provided. row1, col1, row2, col2 are integers indicating the row/column @@ -1463,17 +1448,13 @@ position of the two cells that will be swapped in the table." (let ((content1 (org-table-get row1 col1)) (content2 (org-table-get row2 col2))) (org-table-put row1 col1 content2) - (org-table-put row2 col2 content1) -; (org-table-align) ;; told by Nicolas Goaziou that this is "out of scope" - )) + (org-table-put row2 col2 content1))) -; ;;;###autoload ; told not to auto-load by Nicolas Goaziou, also reformatted comment (defun org-table--move-single-cell (direction) "Move the current cell in a cardinal direction. Parameter direction is a symbol which mathes 'up 'down 'left or 'right. The contents the current cell are swapped with cell in the indicated direction." -;removed check for in table; moved to public functions (let ((drow 0) (dcol 0)) (cond ((equal direction 'up) (setq drow -1)) ((equal direction 'down) (setq drow +1)) -- 2.17.0 [-- Attachment #9: 0008-org-table.el-added-single-cell-movement.patch --] [-- Type: text/x-patch, Size: 926 bytes --] From c780234afee982a231a988d71ea352bab9670f0f Mon Sep 17 00:00:00 2001 From: Chris Kauffman <kauffman77@gmail.com> Date: Tue, 29 May 2018 15:04:25 -0500 Subject: [PATCH 8/8] org-table.el: added single cell movement * lisp/org-table.el: added functions `org-table-move-single-cell-*' along with internal support functions for cell swapping. * lisp/org.el: added bindings for shift+arrows for `org-table-move-single-cell-up' etc. * doc/org-manual.org: added docs for the single cell movement. * testing/lisp/test-org-table.el: added tests associated with single cell movement. --- testing/examples/pub/link | 1 + 1 file changed, 1 insertion(+) create mode 120000 testing/examples/pub/link diff --git a/testing/examples/pub/link b/testing/examples/pub/link new file mode 120000 index 000000000..01bb51522 --- /dev/null +++ b/testing/examples/pub/link @@ -0,0 +1 @@ +../pub-symlink \ No newline at end of file -- 2.17.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2018-05-29 20:29 ` Chris Kauffman @ 2018-06-13 13:35 ` Nicolas Goaziou 0 siblings, 0 replies; 11+ messages in thread From: Nicolas Goaziou @ 2018-06-13 13:35 UTC (permalink / raw) To: Chris Kauffman; +Cc: Uwe Brauer, emacs-orgmode Hello, Chris Kauffman <kauffman@cs.gmu.edu> writes: > Attached are the updated patches for single cell movement in org > tables. Thank you! I squashed the various patches, fixed the docstrings and refactored a bit some functions. I also renamed `org-table-move-single-cell-*' into `org-table-move-cell-*', which is shorter and, IMO, not ambiguous. I pushed it in "next" branch, which will be merged with master once Org 9.2 is out. BTW, what is current status wrt FSF papers now? Regards, -- Nicolas Goaziou 0x80A93738 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Adding single cell movement to org-table 2017-07-27 20:20 Adding single cell movement to org-table Chris Kauffman 2017-07-28 8:19 ` Nicolas Goaziou @ 2017-07-28 8:53 ` Carsten Dominik 1 sibling, 0 replies; 11+ messages in thread From: Carsten Dominik @ 2017-07-28 8:53 UTC (permalink / raw) To: Chris Kauffman; +Cc: Uwe Brauer, org-mode list [-- Attachment #1: Type: text/plain, Size: 1226 bytes --] Hi Chris, I really like this functionality, thank you! Has there been a discussion about a possible key binding for this feature? Carsten On Thu, Jul 27, 2017 at 10:20 PM, Chris Kauffman <kauffman@cs.gmu.edu> wrote: > Greetings from a first-time contributor. Another patch contributor, Uwe > Brauer, recruited me after finding some code I had written to move single > org-table cells up/down/left/right. I found this feature to be useful in > certain kinds of tables so wrote the functions for myself but am told that > others might benefit from it. > > I have formalized that code into a git repo with a feature branch on it > which may be found here: > https://github.com/kauffman77/org-mode/tree/single-cell-table-move > > I have included documentation in org-table.el for the new functions and > tests for them. If further work or documentation needs to be done, please > let me know. I am also not sure if I got the commit messages formatted to > the specification mentioned on the contributing page. I am happy to > explain more if needed. > > I just mailed assign@gnu.org to get the copyright for the code resolved > but thought I would put up this branch now so others can have a look. > > Cheers, > Chris > [-- Attachment #2: Type: text/html, Size: 1855 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2018-06-13 13:35 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-07-27 20:20 Adding single cell movement to org-table Chris Kauffman 2017-07-28 8:19 ` Nicolas Goaziou 2017-07-29 3:00 ` Chris Kauffman 2017-08-03 10:37 ` Nicolas Goaziou 2018-05-04 12:29 ` stardiviner 2018-05-04 14:04 ` Chris Kauffman 2018-05-04 14:31 ` Uwe Brauer 2018-05-05 0:18 ` stardiviner 2018-05-29 20:29 ` Chris Kauffman 2018-06-13 13:35 ` Nicolas Goaziou 2017-07-28 8:53 ` Carsten Dominik
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).