Created
October 29, 2025 05:12
-
-
Save jamesonknutson/efc3fa3009262c9adf52c491a6c8aa64 to your computer and use it in GitHub Desktop.
nushell locate source def
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # file: locate.nu | |
| # Locate the source / location of a command, alias, module, extern, or variable, and open it in your editor. | |
| # Usage: | |
| # `locate commands <my-command-name>` - Locate the source of a custom command | |
| # `locate --open commands <my-command-name>` - Locate the source of a custom command, and open it | |
| def locate-commands [] { | |
| scope commands | |
| | where ( | |
| # Only include custom commands, as those will have source paths to locate to | |
| $it.type == 'custom' | |
| ) | |
| | rename -c { name: 'value' } | |
| | move --first value description | |
| } | |
| def locate-aliases [] { | |
| scope aliases | |
| | rename -c { name: 'value' } | |
| | move --first value description | |
| } | |
| def locate-modules [] { | |
| scope modules | |
| | where ( | |
| # Do not include modules declared in the REPL / commandline | |
| $it.file != 'unknown' | |
| # Do not include virtual modules (std, std-rfc) | |
| and not ($it.file | str starts-with 'std') | |
| # Only include modules that have a file path that exists | |
| and ($it.file | path exists) | |
| ) | |
| | rename -c { name: 'value' } | |
| | move --first value description | |
| } | |
| def locate-externs [] { | |
| scope externs | |
| | rename -c { name: 'value' } | |
| } | |
| def locate-variables [] { | |
| scope variables | |
| | rename -c { value: 'real_value', name: 'value', type: 'description' } | |
| | move --first value description | |
| } | |
| def locate-any [] { | |
| [] | |
| | append (locate-commands | insert completion_type 'commands') | |
| | append (locate-aliases | insert completion_type 'aliases') | |
| | append (locate-modules | insert completion_type 'modules') | |
| | append (locate-externs | insert completion_type 'externs') | |
| | append (locate-variables | insert completion_type 'variables') | |
| | upsert description {|row| $'[($row.completion_type)] ($in)' } | |
| } | |
| def locate-terms [] { | |
| ['commands', 'aliases', 'modules', 'externs', 'variables'] | |
| } | |
| def locate-completer [context: string] { | |
| let term = $context | split words | where $it in (locate-terms) | first | |
| match $term { | |
| commands => { locate-commands } | |
| aliases => { locate-aliases } | |
| modules => { locate-modules } | |
| externs => { locate-externs } | |
| variables => { locate-variables } | |
| _ => { locate-any } | |
| } | |
| } | |
| # Locate the source code location of a declaration, and optionally open it in your editor. | |
| # | |
| # Returns the file path, line, column, and goto string for the declaration. | |
| @example "Open the source location of a custom command" { locate --open commands my-custom-command } | |
| @example "Open the source location of the locate command itself" { locate --open commands locate } | |
| @category viewers | |
| @search-terms locate open definition source view edit reference goto resolve find | |
| export def main [ | |
| --open(-o) # Open the path using `code --goto` | |
| type: string@locate-terms, # The type of declaration to locate | |
| ...items: string@locate-completer # The name of the declaration to locate | |
| ]: any -> record<file: path, goto: string, line: int, column: int> { | |
| let prefix = $"source '($nu.env-path)';\nsource '($nu.config-path)';\n" | |
| let string = $items | str join ' ' | |
| let text = $"($prefix)($string)" | |
| let path = ($nu.temp-path | path join 'locate.temp.nu') | |
| if not ($path | path dirname | path exists) { | |
| mkdir ($path | path dirname) | |
| } | |
| let ide_goto_def = $prefix | str length | |
| $text | save --force $path | |
| let result = ( | |
| ^nu | |
| --config $nu.config-path | |
| --env-config $nu.env-path | |
| --include-path ($env.NU_LIB_DIRS | str join (char rs)) | |
| --ide-goto-def $ide_goto_def | |
| $path | |
| ) | |
| | complete | |
| if ($result.exit_code != 0) { | |
| print $"stdout: ($result.stdout)" | |
| print $"stderr: ($result.stderr)" | |
| print $"exit_code: ($result.exit_code)" | |
| error make { | |
| msg: $'Exit code was ($result.exit_code) when trying to locate definition for "($string)".', | |
| label: { | |
| span: (metadata $result).span, | |
| text: $'The value for result.exit_code was != 0.' | |
| } | |
| } | |
| } | |
| try { | |
| let json = $result.stdout | from json | |
| let file = $json.file | |
| let before_start = open --raw $file | bytes at 0..$json.start | decode | |
| let before_lines = $before_start | lines | |
| let line = $before_lines | length | |
| let column = $before_lines | last | str length | |
| let output = { | |
| file: $file, | |
| line: $line, | |
| column: $column, | |
| goto: $"($file):($line):($column)" | |
| } | |
| rm $path | |
| if $open { | |
| code --goto $output.goto | |
| } | |
| $output | |
| } catch {|error| | |
| print $"Caught error trying to figure out where ($string) of type '($type)' is located: \n($error.rendered)" | |
| print $"stdout: ($result.stdout)" | |
| print $"stderr: ($result.stdout)" | |
| return null; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment