Signature above the cited text in mu4e

Update 2024-03-10:

With the update of Mu4e to 1.12.0 some functions/variables have been deprecated and/or changed. The fix to accommodate those changes can be seen in the following commit:

https://gitlab.com/aimebertrand/dotemacs/-/commit/e11b484a9fad11baaaa629857e7ccafd5c8b31f0

Issue

By default, when replying or forwarding an email, the signature is put at the end of the email body. This means that it is even below the cited text of the original email.

This is a weird behavior since I want to sign my own text and not all of the body.

I usually scroll down while composing the email cut my automatically added signature and paste it above the cited text.

Recently I saw this post on Reddit that motivated me to change this behaviour which is a nuisance.

Solution

First step

After a few searches on google I found this solution in the issues #706 of the mu/mu4e GitHub repo.

The solution is not to automatically add the signature when composing , replying to or forwarding a message…

(setq mu4e-compose-signature-auto-include nil)

… then to add a hook to mu4e-compose-mode-hook and mu4e-compose-pre-hook.

(defun message-insert-signature-at-point (pmode)
  "Function to insert signature at point."
  (when pmode (mu4e-compose-goto-top))
  (interactive)
  (require 'message)
  (message-goto-body)
  (save-restriction
    (narrow-to-region (point) (point))
    (message-insert-signature))
  (mu4e-compose-goto-top))

;; add them to the hooks with appropriate input arguments
(add-hook 'mu4e-compose-mode-hook (lambda ()
                                    (message-insert-signature-at-point nil)) t)
(add-hook 'mu4e-compose-pre-hook (lambda ()
                                   (message-insert-signature-at-point t)) t)

This would solve the issue putting the signature above the cited text in the email.

However there is another slight issue:

You see, everything that follows -- (the 2 dashes are automatically inserted with the signature) in a message is viewed/handled as a signature/comment. Meaning even the quoted text. This leads to all manners of wrong display in the message.

Second step

I found a solution for the second issue. The easiest way was to change the function message-insert-signature since the two dashes (--) are hard coded here.

I simply switch the -- to .......

(defun timu-func-message-insert-signature (&optional force)
  "Insert a signature at the end of the buffer.

See the documentation for the `message-signature' variable for
more information.

If FORCE is 0 (or when called interactively), the global values
of the signature variables will be consulted if the local ones
are null."
  (interactive (list 0) message-mode)
  (let ((message-signature message-signature)
    (message-signature-file message-signature-file))
    ;; If called interactively and there's no signature to insert,
    ;; consult the global values to see whether there's anything they
    ;; have to say for themselves.  This can happen when using
    ;; `gnus-posting-styles', for instance.
    (when (and (null message-signature)
           (null message-signature-file)
           (eq force 0))
      (setq message-signature (default-value 'message-signature)
        message-signature-file (default-value 'message-signature-file)))
    (let* ((signature
        (cond
         ((and (null message-signature)
           (eq force 0))
          (save-excursion
        (goto-char (point-max))
        (not (re-search-backward message-signature-separator nil t))))
         ((and (null message-signature)
           force)
          t)
         ((functionp message-signature)
          (funcall message-signature))
         ((listp message-signature)
          (eval message-signature t))
         (t message-signature)))
       signature-file)
      (setq signature
        (cond ((stringp signature)
           signature)
          ((and (eq t signature) message-signature-file)
           (setq signature-file
             (if (and message-signature-directory
                  ;; don't actually use the signature directory
                  ;; if message-signature-file contains a path.
                  (not (file-name-directory
                    message-signature-file)))
                 (expand-file-name message-signature-file
                           message-signature-directory)
               message-signature-file))
           (file-exists-p signature-file))))
      (when signature
    (goto-char (point-max))
    ;; Insert the signature.
    (unless (bolp)
      (newline))
    (when message-signature-insert-empty-line
      (newline))
    (insert "...... ")
    (newline)
    (if (eq signature t)
        (insert-file-contents signature-file)
      (insert signature))
    (goto-char (point-max))
    (or (bolp) (newline))))))

With that the complete solution is…

(defun timu-func-message-insert-signature-at-point (pmode)
  "Function to insert signature at point."
  (when pmode (mu4e-compose-goto-top))
  (interactive)
  (require 'message)
  (message-goto-body)
  (save-restriction
    (narrow-to-region (point) (point))
    (timu-func-message-insert-signature))
  (mu4e-compose-goto-top))


(add-hook 'mu4e-compose-mode-hook
          (lambda () (timu-func-message-insert-signature-at-point nil)) t)
(add-hook 'mu4e-compose-pre-hook
          (lambda () (timu-func-message-insert-signature-at-point t)) t)

Conclusion

I am almost completely certain that one is able to find a nicer and shorter solution. Especially looking at “redefining” the function message-insert-signature.

However I find that this works wonderfully for me. Yeah!!!