Skip to content
Daniel Nicolai edited this page Aug 8, 2021 · 2 revisions

Welcome to the pdf-tools reverse engineering notes!

Initialization

Like most major modes, pdf-tools is activated directly after visiting a pdf file (buffer). From the pdf-view-mode definition its body we find that it adds a bunch of hooks, after which it runs (image-mode-setup-winprops). By calling M-x pp-macroexpand-last-sexp with the cursor just after the pdf-view-mode major mode definition, we find that the last step of activating pdf-view-mode is running the pdf-view-mode-hook. However, by printing the value of the pdf-view=mode=hook just before it is called, we find that its value is nil.

Two of the hooks added are the window-configuration-change-hook and image-mode-new-window-functions. To find out which hook runs first we add to both hooks a (lambda () (print "SPECIFIED-HOOK")) (note that from the image-mode-new-window-functions docstring we find that its hook functions require one argument). We find that the image-mode-new-window-functions runs first. From its docstring we find:

Special hook run when image data is requested in a new window. It is called with one argument, the initial WINPROPS.

Checking its (local) value from a pdf buffer, we find that the hook runs the function pdf-view-new-window-function (and passes the winprops as an argument). To find the value of the winprops we ‘edebug’ pdf-view-new-window-function. We find that the value of winprops is t. By printing (image-mode-winprops) just after the (image-mode-setup-winprops) in the pdf-view-mode definition we find that the value is (t (overlay . #<overlay in no buffer>)).

To track down how the winprops obtain the value t we use debug-on-entry on pdf-view-new-window-function and we find that pdf-history-minor-mode, which gets enabled via the pdf-tools-enable-minor-modes function in the pdf-view-mode-hook, creates and pushes an item onto the pdf-history-stack using pdf-history-create-item and pdf-history-push. pdf-history-create-item just creates a list with the value of pdf-view-current-page, of which the body only contains (image-mode-window-get 'page window). Now running the image-mode-new-window-functions (i.e. the pdf-view-new-window-function) gets triggered because the function image-mode-window-get calls image-mode-winprops (how the value of winprops became just (t) is unclear to me=).

Note that from the pdf-mode-hook (or the pdf-view-new-window-function backtrace) we actually find that this hook runs pdf-tools-enable-minor-modes. To see which modes get enabled we ‘edebug’ the function and find that all modes in the list pdf-tools-enabled-modes get enabled, i.e.:

(pdf-history-minor-mode
  pdf-isearch-minor-mode
  pdf-links-minor-mode
  pdf-misc-minor-mode
  pdf-outline-minor-mode
  pdf-misc-size-indication-minor-mode
  pdf-misc-menu-bar-minor-mode
  pdf-annot-minor-mode
  pdf-sync-minor-mode
  pdf-misc-context-menu-minor-mode
  pdf-cache-prefetch-minor-mode
  pdf-occur-global-minor-mode
  ;; pdf-virtual-global-minor-mode
  )

Subsequently the pdf-history gets cleared and a new item gets created and pushed with pdf-history-create-item and pdf-history-push. pdf-history-create-item adds the value of pdf-view-current-page to a list as already mentioned above.

To be continued (and ‘refactored’)…

Clone this wiki locally