nushell/crates/nu-command/src
Christopher Durham b5e09b8a30
Improve registry value return types (#10806)
r? @fdncred
Last one, I hope. At least short of completely redesigning `registry
query`'s interface. (Which I wouldn't implement without asking around
first.)

# Description

User-Facing Changes has the general overview. Inline comments provide a
lot of justification on specific choices. Most of the type conversions
should be reasonably noncontroversial, but expanding `REG_EXPAND_SZ`
needs some justification. First, an example of the behavior there:

```shell
> # release nushell:
> version | select version commit_hash | to md --pretty
| version | commit_hash                              |
| ------- | ---------------------------------------- |
| 0.85.0  | a6f62e05ae |
> registry query --hkcu Environment TEMP | get value
%USERPROFILE%\AppData\Local\Temp

> # with this patch:
> version | select version commit_hash | to md --pretty
| version | commit_hash                              |
| ------- | ---------------------------------------- |
| 0.86.1  | 0c5a4c991f |
> registry query --hkcu Environment TEMP | get value
C:\Users\CAD\AppData\Local\Temp

> # Microsoft CLI tooling behavior:
> ^pwsh -c `(Get-ItemProperty HKCU:\Environment).TEMP`
C:\Users\CAD\AppData\Local\Temp
> ^reg query HKCU\Environment /v TEMP
HKEY_CURRENT_USER\Environment
    TEMP    REG_EXPAND_SZ    %USERPROFILE%\AppData\Local\Temp
```

As noted in the inline comments, I'm arguing that it makes more sense to
eagerly expand the %EnvironmentString% placeholders, as none of
Nushell's path functionality will interpret these placeholders. This
makes the behavior of `registry query` match the behavior of pwsh's
`Get-ItemProperty` registry access, and means that paths (the most
common use of `REG_EXPAND_SZ`) are actually usable.

This does *not* break nu_script's
[`update-path`](https://github.com/nushell/nu_scripts/blob/main/sourced/update-path.nu);
it will just be slightly inefficient as it will not find any
`%Placeholder%`s to manually expand anymore. But also, note that
`update-path` is currently *wrong*, as a path including
`%LocalAppData%Low` is perfectly valid and sometimes used (to go to
`Appdata\LocalLow`); expansion isn't done solely on a path segment
basis, as is implemented by `update-path`.

I believe that the type conversions implemented by this patch are
essentially always desired. But if we want to keep `registry query`
"pure", we could easily introduce a `registry get`[^get] which does the
more complete interpretation of registry types, and leave `registry
query` alone as doing the bare minimum. Or we could teach `path expand`
to do `ExpandEnvironmentStringsW`. But REG_EXPAND_SZ being the odd one
out of not getting its registry type semantics decoded by `registry
query` seems wrong.

[^get]: This is the potential redesign I alluded to at the top. One
potential change could be to make `registry get Environment` produce
`record<Path: string, TEMP: string, TMP: string>` instead of `registry
query`'s `table<name: string, value: string, type: string>`, the idea
being to make it feel as native as possible. We could even translate
between Nu's cell-path and registry paths -- cell paths with spaces do
actually work, if a bit awkwardly -- or even introduce lazy records so
the registry can be traversed with normal data manipulation ... but that
all seems a bit much.

# User-Facing Changes

- `registry query`'s produced `value` has changed. Specifically:
-  Rows `where type == REG_EXPAND_SZ` now expand `%EnvironmentVarable%`
placeholders for you. For example, `registry query --hkcu Environment
TEMP | get value` returns `C:\Users\CAD\AppData\Local\Temp` instead of
`%USERPROFILE%\AppData\Local\Temp`.
- You can restore the old behavior and preserve the placeholders by
passing a new `--no-expand` switch.
- Rows `where type == REG_MULTI_SZ` now provide a `list<string>` value.
They previously had that same list, but `| str join "\n"`.
- Rows `where type == REG_DWORD_BIG_ENDIAN` now provide the correct
numeric value instead of a byte-swapped value.
- Rows `where type == REG_QWORD` now provide the correct numeric
value[^sign] instead of the value modulo 2<sup>32</sup>.
- Rows `where type == REG_LINK` now provide a string value of the link
target registry path instead of an internal debug string representation.
(This should never be visible, as links should be transparently
followed.)
- Rows `where type =~ RESOURCE` now provide a binary value instead of an
internal debug string representation.

[^sign]: Nu's `int` is a signed 64-bit integer. As such, values >=
2<sup>63</sup> will be reported as their negative two's compliment
value. This might sometimes be the correct interpretation -- the
registry does not distinguish between signed and unsigned integer values
-- but regedit and pwsh display all values as unsigned.
2023-10-23 07:21:27 -05:00
..
bytes Add long options for bits and bytes (#10601) 2023-10-05 18:45:28 +02:00
charting Move Value to helpers, separate span call (#10121) 2023-09-03 07:27:29 -07:00
conversions remove into decimal (#10341) 2023-10-10 20:05:44 +02:00
database Move Value to helpers, separate span call (#10121) 2023-09-03 07:27:29 -07:00
date fix clippy (#10659) 2023-10-10 03:31:15 +13:00
debug Finish removing profile command and related data (#10807) 2023-10-22 14:06:53 +03:00
env Fix editor config for reedline and config nu/env (#10535) 2023-09-29 16:36:03 +02:00
experimental Add functions for each Value case (#9736) 2023-07-21 08:20:33 -05:00
filesystem Finish removing profile command and related data (#10807) 2023-10-22 14:06:53 +03:00
filters Finish removing profile command and related data (#10807) 2023-10-22 14:06:53 +03:00
formats Remove to xml --pretty (#10668) 2023-10-19 18:41:54 +02:00
generators add unfold back with a deprecation warning (#10771) 2023-10-19 19:23:06 +02:00
hash Move Value to helpers, separate span call (#10121) 2023-09-03 07:27:29 -07:00
help Add 'help escapes' command for quick reference of nushell string escapes (#10522) 2023-09-30 09:04:27 -05:00
math Add long options for generators and math (#10752) 2023-10-19 18:17:42 +02:00
misc Add long options for misc and network (#10753) 2023-10-19 18:16:44 +02:00
network Add long options for misc and network (#10753) 2023-10-19 18:16:44 +02:00
path Add long options for path (#10775) 2023-10-19 22:07:01 +02:00
platform Move ansi link from extra to default feature, close #10792 (#10801) 2023-10-21 11:04:37 -05:00
random Add long options for platform and random (#10776) 2023-10-19 22:04:33 +02:00
removed Rename misused "deprecation" to removal (#10000) 2023-08-15 07:17:31 +12:00
shells Fix usage for the exit command. (#9450) 2023-06-16 10:09:02 +02:00
strings Deprecate size to str stats (#10798) 2023-10-21 11:21:34 -05:00
system Improve registry value return types (#10806) 2023-10-23 07:21:27 -05:00
viewers Finish removing profile command and related data (#10807) 2023-10-22 14:06:53 +03:00
default_context.rs Finish removing profile command and related data (#10807) 2023-10-22 14:06:53 +03:00
example_test.rs feat: Add unfold command (#10489) 2023-09-30 09:08:06 -05:00
lib.rs Move eval_hook to nu-cmd-base (#10146) 2023-08-29 23:46:50 +02:00
progress_bar.rs cp progress bar implementation (#8012) 2023-02-22 11:57:38 -08:00
sort_utils.rs Use slices directly instead of &Vec (#10328) 2023-09-12 11:38:20 +08:00