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.

PythonNut
  • 10,243
  • 2
  • 29
  • 75
  • What do you mean by "*selected*" ("*not by `find-file-noselect`*")? Do you mean displayed? – Drew Aug 07 '15 at 18:43
  • Essentially. `find-file-noselect` finds the file but does not display it (the documentation calls it "selecting" a file?) – PythonNut Aug 07 '15 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 07 '15 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 07 '15 at 21:40
  • @lawlist I'd expect something like that would be the only solution. – PythonNut Aug 07 '15 at 23:32
  • @Drew Does the newly edited question make more sense? – PythonNut Aug 07 '15 at 23:38
  • I guess so. It's certainly different from before anyway. Do you mean visited *or* displayed, perhaps? If not, I would think that just displayed covers *and* - a file buffer cannot be displayed without visiting the buffer. Besides this, I guess it's still not clear to me what you are asking. I wonder if you are looking for what file handlers offer, perhaps. Anyway, hopefully someone else will understand the question and answer it usefully. – Drew Aug 08 '15 at 02:10

2 Answers2

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.

-2
(advice-add 'find-file :after
            (lambda (&rest _args)
              (message "Called after `find-file' but not `find-file-no-select'")))
  • 4
    Please add more to this answer to give context and better flesh out the answer. – Jonathan Leech-Pepin Aug 11 '15 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 03 '15 at 00:55