bravosierrasierra · 2022-05-17 08:30
Hello!
I'm like paragraph movement as in vim: blank line and movement between paragraphs in any modes with simple [[ and ]]. My hook function bss/org-mode-hook works only when i'm manually call it single time after emacs start. But in autostart via hook and 5 minutes timer they do not work in org-mode. What i'm doing wrong?
Default paragraph-start "\\(?:\\*+ \\|\\[fn:[-_[:word:]]+\\]\\|%%(\\|[ ]*\\(?:$\\||\\|\\+\\(?:-+\\+\\)+[ ]*$\\|#\\(?: \\|$\\|\\+\\(?:BEGIN_\\S-+\\|\\S-+\\(?:\\[.*\\]\\)?:[ ]*\\)\\)\\|:\\(?: \\|$\\|[-_[:word:]]+:[ ]*$\\)\\|-\\{5,\\}[ ]*$\\|\\\\begin{\\([A-Za-z0-9*]+\\)}\\|CLOCK:\\|\\(?:[-+*]\\|\\(?:[0-9]+\\)[.)]\\)\\(?:[ ]\\|$\\)\\)\\)"
```
(defun bss/org-mode-hook ()
(interactive)
;; paragraph as in vim
;; https://emacs.stackexchange.com/questions/15063/how-to-make-evil-paragraph-movements-work-in-org-mode
(setq-local ;; try set it for every org-buffer on opening
paragraph-separate "[ \t\f]*$"
paragraph-start "\f\\|[ \t]*$")
(setq ;; try set it for every mode. My first file after emacs startup always org-file.
paragraph-separate "[ \t\f]*$"
paragraph-start "\f\\|[ \t]*$")
)
(add-hook 'org-mode-hook 'bss/org-mode-hook)
;; run hook since 5 minutes after emacs startup
(run-with-timer (* 60 5) nil 'bss/org-mode-hook)
```
flyin1501 · 2022-05-17 12:54
`setq-local` / `setq` is not like Vim's setlocal / set:
- `setq-local` makes a variable buffer-local if it isn't already, then `set`'s it to the value.
- `setq` will use the closest scope; with variables that aren't bound temporarily, this means it will set the buffer local value if the variable is buffer local.
- Use `setq-default` to set the global value. This works more like Vim's :set. (The global value of a buffer local variable is called the "default value". Check the docstring of the function `default-value` for details.)
`describe-function` (C-h f) is pretty useful in this sort of situation; I also recommend Helpful as it will show the source code for the function you're searching for. If a macro's source code isn't that helpful, you can also use `emacs-lisp-macroexpand` to see what it will expand to.
---
~~To fix your hook, move the global `setq` outside of the hook function. Right now the setq only happens in the same buffer where those variables have just been made buffer-local, so it ends up not changing the global value.~~ paragraph-start and paragraph-separate are already made buffer-local by Org mode and none of that is relevant. Is there maybe something else that resets it? By "does not work", do you mean that the variables are not set to the values here in Org mode?
Additionally, the function in the timer will run wherever your current cursor happens to be. It's not necessary in this case, so you can just remove it. (If you need to make changes to a particular buffer, you can use `with-current-buffer`.)
---
You might be interested in `setq-mode-local` (use it as `(setq-mode-local org-mode variable value ...)`; use describe-function to check its docstring for details.
You might also be interested in [evil-org](https://github.com/Somelauw/evil-org-mode), which makes Evil commands work more like what you'd expect (I guess) in Org mode.
bravosierrasierra · 2022-05-24 09:31
Thank you, setq-default + setq-mode-local solved my problem.
```
(defun bss/org-mode-hook ()
(interactive)
;; paragraph as in vim with { and } movement between them
;; https://emacs.stackexchange.com/questions/15063/how-to-make-evil-paragraph-movements-work-in-org-mode
(setq-mode-local
org-mode
paragraph-separate "[ \t\f]*$"
paragraph-start "\f\\|[ \t]*$")
(setq-default
paragraph-separate "[ \t\f]*$"
paragraph-start "\f\\|[ \t]*$"))
(add-hook 'org-mode-hook 'bss/org-mode-hook)
```