0

I am using adaptive wrapping (see Correct indentation for wrapped lines) but it applies to all major modes. I would like to only use it for html. What I have tried so far is adding the following to my .emacs file:

(add-hook 'html-mode-hook 
           ;;(setq-default adaptive-wrap-extra-indent 2)
           (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode)
           (global-visual-line-mode +1)
           ;;(setq adaptive-wrap-prefix-mode t)
           )

This does not work since the adaptive line wrap is still active in all major modes. How should I change the snippet to make it work?

Vincent
  • 216
  • 1
  • 8

3 Answers3

2

I think what you're trying to do is:

(add-hook 'html-mode-hook 'adaptive-wrap-prefix-mode)

That is, add adaptive-wrap-prefix-mode directly to the html-mode hook. Adding it to visual-line-mode-hook will make it active whenever visual-line-mode is enabled, and you've enabled that globally with (global-visual-line-mode 1).

Resorting to advice-add may appear to work, but it's a round-about way to do it, and the results might not be consistent.

Tyler
  • 21,719
  • 1
  • 52
  • 92
2

The arguments of add-hook are HOOK, FUNCTION, APPEND, and LOCAL (see quote of the docstring for add-hook below).

The 1st arg in your code is 'html-mode-hook which is fine.

The 2nd is (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode) which is not good. It is a form that is evaluated and its return value is used as argument to add-hook. Effectively (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode) is run where you wanted to run (add-hook 'html-mode ...).

The third arg is (global-visual-line-mode +1). It is also run where you wanted to run (add-hook 'html-mode ...). The help of function global-visual-line-mode does not specify a return value. Therefore the return value is open to the developer. It is a general no-go to use that return value if you are not the developer.

You should put the stuff from add-hook in your code into a function, say my-html-mode-hook-fun and hook my-html-mode-hook-fun to html-mode-hook.

Furthermore, it does not make sense to put (global-visual-line-mode) into html-mode-hook. I replaced it by (visual-line-mode).

(defun my-html-mode-hook-fun ()
  "I want to have fun in `html-mode-hook';-)."
  (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode nil 'buffer-local)
  (visual-line-mode)
  ;; further nice stuff you want to do after (de-)activating html-mode
)

(add-hook 'html-mode-hook #'my-html-mode-hook-fun)

Some folks use a lambda instead of a named function. I do very much prefer named functions:

  1. It is easier to instrument named functions for debugging.
  2. The named function can easily be modified and redefined.
  3. They can easily be removed from the hook:

    (setq html-mode-hook (cl-remove 'my-html-mode-hook-fun html-mode-hook))
    

Quote of the docstring of add-hook:

add-hook is a compiled Lisp function in subr.el.

(add-hook HOOK FUNCTION &optional APPEND LOCAL)

For more information check the manuals.

Add to the value of HOOK the function FUNCTION. FUNCTION is not added if already present. FUNCTION is added (if necessary) at the beginning of the hook list unless the optional argument APPEND is non-nil, in which case FUNCTION is added at the end.

The optional fourth argument, LOCAL, if non-nil, says to modify the hook’s buffer-local value rather than its global value. This makes the hook buffer-local, and it makes t a member of the buffer-local value. That acts as a flag to run the hook functions of the global value as well as in the local value.

HOOK should be a symbol, and FUNCTION may be any valid function. If HOOK is void, it is first set to nil. If HOOK’s value is a single function, it is changed to a list of functions.

Tobias
  • 32,569
  • 1
  • 34
  • 75
0

Adding the following code to my .emacs eventually worked for me:

(defun myAdWrap ()
  (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode)
  (global-visual-line-mode +1))
(advice-add 'html-mode :before #'myAdWrap)
Vincent
  • 216
  • 1
  • 8