Use Emacs' xref framework to jump to classes/defines/types #127
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Emacs 25 introduced the
xref
package providing a generic framework to jump to function definitions. This PR updatespuppet-mode
to hook into this framework and implements easy navigation to classes, defined types, data types and functions located in other modules.The idea for this feature was also introduced in #29.
Usage:
Imagine you are editing the following
acme
class:The following navigation options are available:
Stdlib::Absolutepath
data type:M-.
opens the data type definitionacme::params
subclass:M-.
opens the class definitionnginx
class:M-.
opens the class definitionnginx::resource::server
defined type:M-.
opens the type definitionstdlib::ensure
function:M-.
opens the function definitionpostgresql::server
string:M-.
opens the class definitionNavigation to foreign classes only needs a list of directories to search. After jumping to a definition you can return back using
M-,
. These keybindings are defined by thexref
package.Implementation:
The code takes the identifier at point, dissects it into a module name and possible file paths below that module where the identifier could be defined according to Puppet's auto-loader rules. For
foo::bar
the following paths are checked:manifests/bar.pp
,types/bar.pp
andfunctions/bar.pp
.First these paths are checked for the current module. In this case the module name does not need to be a path component (e.g. coding the module in
~/src/puppet-acme
would work, so you can check out modules from Github into your home directory). Then all directories from the new customization optionpuppet-module-path
are checked. This option should have all directories where you keep modules (default:/etc/puppetlabs/code/environments/production
). In this case there is a requirement, that the module directory must be named after the module as Puppet dictates.Then the code visits every file that actually exists and looks for the definition. It returns the file name and line number back to the
xref
framework to perform the heavy lifting.Look-ups are performed on the fly when needed since the number of possible candidate files is small due to the auto-loader rules. Therefore it seems adequate to handle it without maintaining some sort of 'database' like a TAGS file (which could get out of sync).
Caveats:
xref
is only available out of the box for Emacs 25 or later.This code seems to work for my use cases. Obviously more people testing it would be a bonus!
Your feedback is appreciated!