3

This is pretty simple, I'm trying to find (or build) a hook that fires when files are visited and selected (i.e. immediately displayed).

Background

I'm writing a UI centric entry for find-file-hook, but it turns out that find-file-hook is fired for all sorts of things that I don't need:

  • Semantic assets which are loaded when semantic starts
  • Files opened in the background for my on-the-fly diffing program
  • Probably other stuff, that's all I could think of off the top of my head

Most of this is done by way of find-file-noselect, which associates a buffer with a file, but does not switch-to-buffer on the newly created buffer like find-file does.

I would like my hook to execute only when the current buffer changes.

7
  • What do you mean by "selected" ("not by find-file-noselect")? Do you mean displayed?
    – Drew
    Aug 7, 2015 at 18:43
  • Essentially. find-file-noselect finds the file but does not display it (the documentation calls it "selecting" a file?)
    – PythonNut
    Aug 7, 2015 at 19:52
  • Are you interested in adding a hook to one of the functions in files.el or in window.el, or something else? Consider adding a specific example so that forum participants have a better idea of what you are seeking.
    – lawlist
    Aug 7, 2015 at 21:27
  • find-file-noselect ensures that a buffer has the contents of a file. Buffers are visited, not files. If a buffer already has the file contents in it then that buffer is returned (the buffer contents are also checked wrt the file on disk, and you are alerted if they are out of sync). So a file being "visited and selected" doesn't mean much (to me anyway). When find-file-noselect returns a buffer that is visiting the file, I guess that is what you mean by "visited and selected", but then you add "(i.e., not by find-file-noselect)". So it's unclear to me what you mean.
    – Drew
    Aug 7, 2015 at 21:40
  • @lawlist I'd expect something like that would be the only solution.
    – PythonNut
    Aug 7, 2015 at 23:32

2 Answers 2

2

At the point where find-file-hook is called the buffer is not yet displayed in either case, and you don't know yet whether it's going to be shown in a window or not. You could hook into window-configuration-change-hook, but that in turn does not tell you whether the buffer was selected immediately in find-file, or at some arbitrary later point.

Your best chance to work around these issues is a multi-step process:

  1. In your find-file-hook, remember the value of this-command in a buffer-local variable, and add a local window-configuration-change-hook.
  2. In that hook, check whether the buffer has a window with (get-buffer-window).

If it does, and this-command is still the same as you remembered, there's a good chance that finding the file and showing the buffer came from the same command, i.e. find-file or some variants thereof, and you can start your UI. If this-command has changed without the buffer having a window, however, it was obviously not find-file, and you can remove your hook from window-configuration-change-hook without starting your UI.

That is complicated, for sure, but it's the only way I can think of to work around broken packages which abuse find-file-noselect to load internal assets and data files. You should never do that. If you care, please report these issues to developers whenever you spot them. find-file is only for interactive use.

1
  • Sorry, It's going to be a while before I can test this. Please hang in there :)
    – PythonNut
    Aug 10, 2015 at 23:10
-2
(advice-add 'find-file :after
            (lambda (&rest _args)
              (message "Called after `find-file' but not `find-file-no-select'")))
2
  • 4
    Please add more to this answer to give context and better flesh out the answer. Aug 11, 2015 at 12:06
  • @Finding Nemo, this is not as powerful as find-file-hook because other functions (e.g. ido-find-file) call find-file-hook, but do not use find-file. I don't want to manually collect a list of such functions, hence this question.
    – PythonNut
    Sep 3, 2015 at 0:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.