5

I would like that when I open a file of certain type (say *.abc) certain function (say my-function) automatically executes at the opening.

Edit. The function is a buffer-dependent function and should run at the buffer containing the file *.abc, i.e., it should run after loading the file .abc not before.

The function I would like to execute is shr-render-buffer (but it may arise for other functions). It renders html codes. Note that the file may have an arbitrary suffix not just .html

After the hints in the answer of Mark an using the links in my comment below it, I tried the following:

Attempt 1:

(require 'shr)
(add-hook 'find-file-hook 'my-function)
(defun my-function ()
  (when (and (stringp buffer-file-name)
             (string-match "\\.html\\'" buffer-file-name))
             '(shr-render-buffer)))

Attempt 2:

(require 'shr)
(add-to-list 'auto-mode-alist
             '("\\.abc\\'" . (lambda ()
                              '(shr-render-buffer))))

Attempt 3:

(require 'shr)
(add-hook 'find-file-hook 'my-function)
(defun my-function ()
  (when (string= (file-name-extension buffer-file-name) "abc")
    '(shr-render-buffer)
    ))

Then after the suggetion of Lidydancer, I tried to define a major mode for .abc types. For simplicity I considered them as html-mode and I used the following (already provided by one of the answers in the below links):

Attempt 4:

(require 'shr)
(add-to-list 'auto-mode-alist '("\\.abc\\'" . html-mode))
(add-hook 'html-mode-hook 'shr-render-buffer)

All my attempts were unsuccessful.

Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179
Name
  • 7,689
  • 4
  • 38
  • 84
  • Is there some associated major mode for this sort of files? Something like `abc-mode`? – Mark Karpov Jul 13 '15 at 03:21
  • 1
    @Mark No, there is no major mode for this sort of files. – Name Jul 13 '15 at 03:23
  • 1
    Why not define your own major mode, say `abc-mode`, and add your function to `abc-mode-hook`? – Lindydancer Jul 13 '15 at 06:04
  • 1
    @Lindydancer, the problem is that even by defining an `abc-mode` the problem persists, i.e., the function executes *before* displaying of buffer (for example take the example where `my-function` is `split-window-vertically`). – Name Jul 13 '15 at 07:27

2 Answers2

3

You can use find-file-hook. From doc-string:

List of functions to be called after a buffer is loaded from a file. The buffer's local variables (if any) will have been processed before the functions are called.

Thus, you can do this:

(add-hook 'find-file-hook #'your-function)

In your-function your should test if buffer-file-name has the extension you target. Then you can execute some code.

There may be better solution I don't know of.

Mark Karpov
  • 4,893
  • 1
  • 24
  • 53
  • Your idea can be used in certain circumstances (for example when `my-function` is `(message "yes")`). But there are the situations where I have no control on the content of `my-function`. – Name Jul 13 '15 at 05:14
  • Apart from this, using your idea and some similar questions given in http://emacs.stackexchange.com/q/12396/ and http://stackoverflow.com/q/6886643/ I tried to do by writing `(add-hook 'find-file-hook 'my-function) (defun my-function () (when (string= (file-name-extension buffer-file-name) "abc") (end-of-buffer) )) ` it when `my-function` is `end-of-buffer` but it doesn't work. – Name Jul 13 '15 at 05:15
  • Similarly when `my-function2` is `split-window-vertically` I wrote `(defun my-function2 () (when (and (stringp buffer-file-name) (string-match "\\.abc\\'" buffer-file-name)) (split-window-vertically) ) ) (add-hook 'find-file-hook 'my-function2) ` does not split the window of the file `.abc` instead it split the window in one half is `.abc` and in the other half is `scratch` buffer. – Name Jul 13 '15 at 05:15
  • 1
    @Name, ah, problem here is that this hook is called *before* displaying of buffer. Take a look at `display-buffer-alist`, this might help you to do what you want to do, although it's pretty hairy. – Mark Karpov Jul 13 '15 at 05:27
  • 4
    @Name, also, it feels like XY problem, could you describe your final aim? – Mark Karpov Jul 13 '15 at 05:30
  • What you said is exactly what I want to do, i.e., executing the command *after* displaying of buffer. – Name Jul 13 '15 at 06:57
  • 1
    @Name It will help if you update the question with what you tried and didn't work. What is the function that you are trying to call after displaying the buffer? – Kaushal Modi Jul 13 '15 at 11:44
3

Your attempt 1 is almost correct. Your attempt 3 will also work with the same fixes I have done below.

Here are the two things that needed to be fixed:

  1. You do not quote the function you are calling. If you want to call function FN, you simply do (FN). When you do '(FN) it simply is a list with one element: the symbol FN.
  2. You were missing a mandatory argument that shr-render-buffer needed; you need to specify which buffer you want that function to act upon.

Here's something I quickly tried out and works:

(require 'shr)
(add-hook 'find-file-hook #'my-function)
(defun my-function ()
  (when (and (stringp buffer-file-name)
             (string-match "\\.html\\'" buffer-file-name))
    (shr-render-buffer (current-buffer)))) ; FIXED line 
Kaushal Modi
  • 25,203
  • 3
  • 74
  • 179