The solution was unnecessarily over-complicated.
Below one seems simpler and more intuitive. It requires the hydra package.
(defun org-table-mark-field ()
"Mark the current table field."
(interactive)
;; Do not try to jump to the beginning of field if the point is already there
(when (not (looking-back "|\\s-?"))
(org-table-beginning-of-field 1))
(set-mark-command nil)
(org-table-end-of-field 1))
(defhydra hydra-org-table-mark-field
(:body-pre (org-table-mark-field)
:color pink
:hint nil)
"
^^ _p_ ^^
_b_ selection _f_ | org table mark ▯field▮ |
^^ _n_ ^^
"
("x" exchange-point-and-mark "exchange point/mark")
("f" (lambda (arg)
(interactive "p")
(when (eq 1 arg)
(setq arg 2))
(org-table-end-of-field arg)))
("b" (lambda (arg)
(interactive "p")
(when (eq 1 arg)
(setq arg 2))
(org-table-beginning-of-field arg)))
("n" next-line)
("p" previous-line)
("q" nil "cancel" :color blue))
(bind-keys
:map org-mode-map
:filter (org-at-table-p)
("S-SPC" . hydra-org-table-mark-field/body))