0

I defined indent-line-function variable for Makefile corresponding to the problem referred in the link. But when this configuration is activated, pressing TAB key does not insert tab letter at the point. How can I fix it ?

Following is from my init.el

(defun yh/makefile-indent-line ()
    "https://emacs.stackexchange.com/questions/3074/customizing-indentation-in-makefile-mode"
    (save-excursion
      (forward-line 0)
      (cond
       ;; keep TABs
       ((looking-at "\t")
        t)
       ;; indent continuation lines to 4
       ((and (not (bobp))
             (= (char-before (1- (point))) ?\\))
        (delete-horizontal-space)
        (indent-to 4))
       ;; delete all other leading whitespace
       ((looking-at "\\s-+")
        (replace-match "")))))

  (add-hook 'makefile-mode-hook
            (lambda ()
              (setq-local indent-line-function 'yh/makefile-indent-line))))
edit:

The first problem was indent-region in Makefile removes tab character at the beginning of all lines. I googled and reached the page linked above, then I just pasted the snippet from the answer into my init.el and it makes indent-region keep tab characters.

The second problem, which I mentioned in this post, was I could not insert tab character at all by pressing the tab key when indent-line-function above is defined. What I thought at that time was "Pressing tab key let emacs insert a tab character in the current position. How function for indentation affect inserting character ?".

Finally, I understand the problem. Tab is assigned to indent-for-tab-command function. And the docstring of the function says

The function called to actually indent the line or insert a tab is given by the variable `indent-line-function'.

So I should modify the function I pasted so that it would insert tab character appropriately. The following is my modification

(defun yh/makefile-indent-line ()
    "https://emacs.stackexchange.com/questions/3074/customizing-indentation-in-makefile-mode"
    (let ((bol (= (point-beginning-of-line) (point)))
          (empty (string= (yh/current-line) "")))
      (message "-- %s %s %s" bol empty (point))
      (if bol
          (progn (when empty (insert "\t")))
        (save-excursion
          (forward-line 0)
          (cond
           ;; keep TABs
           ((looking-at "\t") t (message "1 %s" (point-max)))
           ;; indent continuation lines to 4
           ((and (not (bobp))
                 (= (char-before (1- (point))) ?\\))
            (delete-horizontal-space)
            (indent-to 4)
            (message "2"))
           ;; delete all other leading whitespace
           ((looking-at "\\s-+")
            (replace-match "")
            (message "3"))
           (t (message "4 %s" (point-max))))))))

Actually, this is not the perfect (in some situation, behave badly) but acceptable to me.

  • If you expect this code to make the TAB key insert a TAB character, then you seem to have misunderstood the problem defined in "the link". But maybe you simply haven't described your problem precisely enough? – Stefan Sep 16 at 12:52
  • Usually in modes where the TAB key function is overridden, one types C-Q C-I to obtain a tab character. Similarly with C-Q C-J for newlines when using "query-replace" and friends. – Ben Sep 17 at 0:26
  • Thank you for @Stefan. I understand the problem. – hotoku Sep 17 at 10:52
  • Thank yuo @Ben , too. – hotoku Sep 17 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.