diff --git a/CHANGELOG.md b/CHANGELOG.md index 988de12822..65f9a83ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### New features +- [PR 1443] (https://github.com/bbatsov/prelude/pull/1443): Add user configuration for `org-mode` specfic `S-[arrow]` bindings. - [PR 1432](https://github.com/bbatsov/prelude/pull/1432): Allow directories of custom Emacs Lisp files in `personal/preload`. - Enable `org-habits`. - Neatly track `TODO` state changes in a drawer (LOGBOOK), thereby improving readability. diff --git a/docs/configuration.md b/docs/configuration.md index e79210b350..6862bc5564 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -210,3 +210,19 @@ to disable this behaviour, set the following variable to nil before loading prel ```emacs-lisp (setq prelude-override-package-user-dir nil) ``` + +### Enable org-mode shift arrow Keybindings + +By default, windmove keybindings take precedence for binding to the S+[arrow] keys. +Org-mode keybindings are overridden. This is a [know issue][1] described in org-mode's +manual. + +[1]: https://orgmode.org/manual/Conflicts.html + +To have org-mode S+[arrow key] keybindings in org buffers, add this to your configs: + +```lisp +(prelude-enable-org-mode-shift-bindings) +``` + +Other buffers should continue to be bound to windmove keybindings. diff --git a/docs/modules/orgmode.md b/docs/modules/orgmode.md index f961af4656..10cde71598 100644 --- a/docs/modules/orgmode.md +++ b/docs/modules/orgmode.md @@ -13,6 +13,18 @@ It establishes a few extra keybidings: - `C-c a` (`org-agenda`) - `C-c b` (`org-switchb`) +### Shift-arrow keybinding conflicts + +Windmove arrow keybindings are the default for Prelude, but org-mode has some +specific bindings for the S-[arrow keys]. + +If a user adds the following code, org-mode buffers will have standard org-mode +bindings, but other buffers will use windmove bindings. + +```lisp +(prelude-enable-org-mode-shift-bindings) +``` + ## org-habits It enables [org-habits](https://orgmode.org/manual/Tracking-your-habits.html "org-habits") and [tracks TODO state changes](https://orgmode.org/manual/Tracking-TODO-state-changes.html "todo-state-changes") into a diff --git a/modules/prelude-org.el b/modules/prelude-org.el index 692f0c96b8..8c7442e51d 100644 --- a/modules/prelude-org.el +++ b/modules/prelude-org.el @@ -58,6 +58,42 @@ (add-hook 'org-mode-hook (lambda () (run-hooks 'prelude-org-mode-hook))) +(defun prelude-enable-org-mode-shift-bindings () + "Enable `windmove' advice to use `org-mode' shift functions in org buffers." + (interactive) + (message "Prelude: Installing org-mode shift key bindings to supersede windmove bindings") + + ;; Advice to redirect windmove commands to org-mode functions in org buffers + (defun ap/windmove-left-advice (orig-fun &rest args) + "Use `org-shiftleft' in org buffers, ORIG-FUN with ARGS elsewhere." + (if (derived-mode-p 'org-mode) + (org-shiftleft) + (apply orig-fun args))) + + (defun ap/windmove-right-advice (orig-fun &rest args) + "Use `org-shiftright' in org buffers, ORIG-FUN with ARGS elsewhere." + (if (derived-mode-p 'org-mode) + (org-shiftright) + (apply orig-fun args))) + + (defun ap/windmove-up-advice (orig-fun &rest args) + "Use `org-shiftup' in org buffers, ORIG-FUN with ARGS elsewhere." + (if (derived-mode-p 'org-mode) + (org-shiftup) + (apply orig-fun args))) + + (defun ap/windmove-down-advice (orig-fun &rest args) + "Use `org-shiftdown' in org buffers, ORIG-FUN with ARGS elsewhere." + (if (derived-mode-p 'org-mode) + (org-shiftdown) + (apply orig-fun args))) + + ;; Apply advice to all windmove functions + (advice-add 'windmove-left :around #'ap/windmove-left-advice) + (advice-add 'windmove-right :around #'ap/windmove-right-advice) + (advice-add 'windmove-up :around #'ap/windmove-up-advice) + (advice-add 'windmove-down :around #'ap/windmove-down-advice)) + (provide 'prelude-org) ;;; prelude-org.el ends here