Skip to content

Commit 7d3ff07

Browse files
0.5.0-preview
1 parent a6a8486 commit 7d3ff07

19 files changed

+724
-171
lines changed

ChangeLog.md

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
# ChangeLog for PSFunctionInfo
22

3-
## 0.4.0
3+
## 0.5.0-preview
4+
5+
+ Added an autocompleter for the `-Tag` parameter in `Get-PSFunctionInfo`. ([Issue #4](https://github.com/jdhitsolutions/PSFunctionInfo/issues/4))
6+
+ Added a private function, `new_psfunctioninfo`, to create a new PSFunctionInfo object from the metadata block.
7+
+ Changed `Name` parameter in `Get-PSFunctionInfo` to `FunctionName`. The parameter is positional, so it shouldn't make much difference. **This is a breaking change.**
8+
+ Modified `Get-PSFunctionInfo` to get metadata from files. ([Issue #3](https://github.com/jdhitsolutions/PSFunctionInfo/issues/3))
9+
+ Modified `PSFunctionInfo` class to not require Tags in the constructor.
10+
+ Added missing online help links.
11+
+ Added a table view called `tags` to `psfunctioninfor.format.ps1xml`.
12+
+ Modified `psfunctioninfor.format.ps1xml` to reduce the `Alias` column to 15.
13+
+ Added integration into the PowerShell ISE.
14+
+ Added integration into VS Code. ([Issue #2](https://github.com/jdhitsolutions/PSFunctionInfo/issues/2))
15+
+ Updated help documentation.
16+
+ Updated `README.md`.
17+
18+
## 0.4.0-preview
419

520
+ Added `Set-PSFunctionInfoDefaults` and `Get-PSFunctionInfoDefaults` to store default values. The defaults are stored in a JSON file at `$home\psfunctioninfo-defaults.json`. If the file is found when the module is imported, it will be used to set $PSDefaultParameterValues for this module.
621
+ Added `Update-PSFunctionInfoDefaults` which can be used to update defaults if they are changed after the module has been loaded.
722
+ Added `about_PSFunctionInfo` help.
823
+ Minor help updates.
924
+ Updated `README.md`.
1025

11-
## 0.3.0
26+
## 0.3.0-preview
1227

1328
+ Added online help links.
1429
+ Published pre-release module to the PowerShell Gallery.

PSFunctionInfo.psd1

0 Bytes
Binary file not shown.

PSFunctionInfo.psm1

+159
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,155 @@ if (Test-Path -path $defaults) {
1212
}
1313
}
1414

15+
#Add VSCode Shortcuts
16+
if ($host.name -eq 'Visual Studio Code Host') {
17+
$global:PSDefaultParameterValues["New-PSFunctionInfo:Path"] = {$pseditor.GetEditorContext().CurrentFile.Path}
18+
19+
#create an argument completer for the Name parameter
20+
Register-ArgumentCompleter -CommandName New-PSFunctionInfo -ParameterName Name -ScriptBlock {
21+
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
22+
23+
#PowerShell code to populate $wordtoComplete
24+
$asttokens = $pseditor.GetEditorContext().CurrentFile.tokens
25+
$namelist = @()
26+
for ($i=0;$i -lt $asttokens.count;$i++) {
27+
if ($asttokens[$i].text -eq 'function') {
28+
$namelist+= $asttokens[$i+1].text
29+
}
30+
}
31+
$namelist | Where-Object {$_ -like "$WordtoComplete*"} |
32+
ForEach-Object {
33+
# completion text,listitem text,result type,Tooltip
34+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
35+
}
36+
}
37+
}
38+
elseif ($host.name -eq 'Windows PowerShell ISE Host') {
39+
#create shortcut for the ISE
40+
$global:PSDefaultParameterValues["New-PSFunctionInfo:Path"] = {$psise.CurrentFile.fullpath}
41+
42+
#add a menu item
43+
$sb = {
44+
45+
Function PickList {
46+
# A WPF function picker for the PowerShell ISE
47+
Param([string[]]$Name)
48+
49+
$title = "New-PSFunctionInfo"
50+
51+
$form = New-Object System.Windows.Window
52+
#define what it looks like
53+
$form.Title = $Title
54+
$form.Height = 200
55+
$form.Width = 300
56+
$form.WindowStartupLocation = [System.Windows.WindowStartupLocation]::CenterScreen
57+
58+
$grid = New-Object System.Windows.Controls.Grid
59+
60+
$label = New-Object System.Windows.Controls.Label
61+
$label.Content = "Select a function from the list and click OK."
62+
$label.HorizontalAlignment = "left"
63+
$label.VerticalAlignment = "top"
64+
$grid.AddChild($label)
65+
66+
$combo = New-Object System.Windows.Controls.ListBox
67+
$combo.AllowDrop = $true
68+
69+
$combo.Width = 160
70+
$combo.Height = 75
71+
$combo.HorizontalAlignment = "left"
72+
$combo.VerticalAlignment = "top"
73+
$combo.Margin = "15,25,0,0"
74+
75+
foreach ($item in $Name) {
76+
[void]$combo.items.Add($item)
77+
}
78+
$combo.SelectedIndex = 0
79+
80+
$grid.AddChild($combo)
81+
#initialize an array to hold all processed objects
82+
83+
$ok = New-Object System.windows.controls.button
84+
$ok.Content = "_OK"
85+
$ok.IsDefault = $True
86+
$ok.Width = 75
87+
$ok.Height = 25
88+
$ok.HorizontalAlignment = "left"
89+
$ok.Margin = "25,100,0,0"
90+
$OK.Add_Click( {
91+
$global:SelectedPickItem = $combo.SelectedItem
92+
#$combo.SelectedItem | Out-Default
93+
$form.Close()
94+
})
95+
$grid.AddChild($ok)
96+
97+
$cancel = New-Object System.Windows.Controls.Button
98+
$cancel.Content = "_Cancel"
99+
$cancel.Width = 75
100+
$cancel.Height = 25
101+
#$cancel.HorizontalAlignment = "right"
102+
$cancel.Margin = "150,100,0,0"
103+
$cancel.Add_Click( {
104+
$form.Close()
105+
})
106+
107+
$grid.AddChild($cancel)
108+
109+
$form.AddChild($grid)
110+
[void]($form.ShowDialog())
111+
}
112+
113+
if ($psise.CurrentFile.IsSaved) {
114+
$Path = $psise.CurrentFile.FullPath
115+
116+
New-Variable astTokens -Force
117+
New-Variable astErr -Force
118+
$AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr)
119+
120+
$file = [System.Collections.Generic.list[string[]]]::new()
121+
Get-Content $path | ForEach-Object { $file.Add($_) }
122+
123+
$name = @()
124+
for ($i = 0; $i -lt $asttokens.count; $i++) {
125+
if ($asttokens[$i].text -eq 'function') {
126+
$name += $asttokens[$i + 1].text
127+
}
128+
} #for
129+
if ($name) {
130+
Remove-Variable -Name SelectedPickItem -ErrorAction SilentlyContinue
131+
picklist -name $name
132+
#| Out-GridView -Title "Select a function" -OutputMode Single
133+
134+
if ($SelectedPickItem) {
135+
New-PSFunctionInfo -Name $SelectedPickItem -path $path
136+
137+
$idx = $file.findIndex( { $args[0] -match "[Ff]unction(\s+)$SelectedPickItem" })
138+
$idx++
139+
#save and re-open the file
140+
[void]$psISE.CurrentPowerShellTab.files.Remove($psise.CurrentFile)
141+
[void]$psise.CurrentPowerShellTab.Files.Add($path)
142+
$r = $psise.CurrentPowerShellTab.Files.where( { $_.fullpath -eq $path })
143+
$r.Editor.Focus()
144+
145+
if ($idx -ge 0) {
146+
$r.Editor.SetCaretPosition($idx, 1)
147+
$r.Editor.SelectCaretLine()
148+
$r.Editor.EnsureVisible($idx)
149+
}
150+
}
151+
} #if names found
152+
else {
153+
[System.Windows.MessageBox]::Show("No matching functions found in $Path", "New-PSFunctionInfo", "OK", "Information")
154+
}
155+
} #if saved
156+
else {
157+
[System.Windows.MessageBox]::Show("Please save your file first:$Path and then try again.", "New-PSFunctionInfo", "OK", "Warning")
158+
}
159+
}
160+
161+
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.add("New-PSFunctionInfo", $sb, $Null)
162+
}
163+
15164
#create an argument completer
16165
Register-ArgumentCompleter -CommandName Get-PSFunctionInfo -ParameterName Name -ScriptBlock {
17166
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
@@ -21,4 +170,14 @@ Register-ArgumentCompleter -CommandName Get-PSFunctionInfo -ParameterName Name -
21170
# completion text,listitem text,result type,Tooltip
22171
[System.Management.Automation.CompletionResult]::new($_.name, $_.name, 'ParameterValue', $_.name)
23172
}
173+
}
174+
175+
Register-ArgumentCompleter -CommandName Get-PSFunctionInfo -ParameterName Tag -ScriptBlock {
176+
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
177+
178+
(Get-PSFunctionInfoTag).where({$_ -like "$wordToComplete*"}) |
179+
ForEach-Object {
180+
# completion text,listitem text,result type,Tooltip
181+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
182+
}
24183
}

README.md

+55-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# PSFunctionInfo
22

3+
[![PSGallery Version](https://img.shields.io/powershellgallery/v/PSFunctionInfo.png?style=plastic&logo=powershell&label=PowerShell%20Gallery)](https://www.powershellgallery.com/packages/PSFunctionInfo/) ![PSGallery Downloads](https://img.shields.io/powershellgallery/dt/PSFunctionInfo.png?style=plastic&&logo=powershell&label=Downloads)
4+
35
## Synopsis
46

57
This module contains a set of PowerShell commands to add and manage metadata in stand-alone PowerShell functions.
@@ -18,7 +20,7 @@ The module should work on both Windows PowerShell and PowerShell 7.x, even cross
1820

1921
The purpose of this code is to provide a way to get versioning and other metadata information for functions that may not belong to a module. This is information you want to get after the function has been loaded into your PowerShell session. I have numerous stand-alone functions. These functions don't belong to a module, so there is no version or source information. However, I'd like to use that type of information for non-module files.
2022

21-
The code in this module isn't concerned with loading, running, or finding functions. It queries whatever is in the `Function:` PSDrive. If the PowerShell function belongs to a module, then you'll get the module version and source. Otherwise, you can use the function metadata.
23+
The code in this module isn't concerned with loading, running, or finding functions. By default, [Get-PSFunctionInfo](docs/Get-PSFunctionInfo.md) queries whatever is in the `Function:` PSDrive. If the PowerShell function belongs to a module, then you'll get the module version and source. Otherwise, you can use the function metadata.
2224

2325
![Get a single function](assets/get-psfunctioninfo-1.png)
2426

@@ -30,9 +32,28 @@ You can also get functions by tag. Use `Get-PSFunctionInfoTag` to get a list of
3032

3133
![Get functions by tag](assets/get-psfunctioninfo-3.png)
3234

35+
The PSFunctionInfo object includes a PropertySet called AuthorInfo.
36+
37+
```dos
38+
PS C:\> Get-PSFunctionInfo -Tag modules | Select-Object -property AuthorInfo
39+
40+
41+
Name : Test-HelpLink
42+
Version : 0.9.0
43+
Source : C:\scripts\update-helplinks.ps1
44+
CompanyName : JDH IT Solutions, Inc.
45+
Copyright : (c) JDH IT Solutions, Inc.
46+
Description : Test if help file is missing the online link
47+
LastUpdate : 4/23/2021 9:21:00 AM
48+
```
49+
50+
Finally, you can also search .ps1 files for PSFunctionInfo metadata.
51+
52+
![Get function info from file](assets/get-psfunctioninfo-file.png)
53+
3354
## Creating PSFunctionInfo
3455

35-
Use the `New-PSFunctionInfo` command to insert the metadata tag into your script file.
56+
Use the [New-PSFunctionInfo](docs/New-PSFunctionInfo.md) command to insert the metadata tag into your script file.
3657

3758
```powershell
3859
New-PSFunctionInfo -Path c:\scripts\Test-ConsoleColors.ps1 -Description "show console color combinations" -Name Test-ConsoleColor -Author "Jeff Hicks" -CompanyName "JDH IT Solutions" -Copyright "2021 JDH IT Solutions, Inc." -Tags "scripting","console"
@@ -91,24 +112,51 @@ There are no commands to modify or remove function metadata. It is assumed that
91112

92113
## PSFunctionInfo Defaults
93114

94-
Because you might define function metadata often, and want to maintain consistency, you can define a set of default values for `New-PSFunctionInfo`. Use the command, `Set-PSFunctionInfoDefaults`:
115+
Because you might define function metadata often, and want to maintain consistency, you can define a set of default values for `New-PSFunctionInfo`. Use the command, [Set-PSFunctionInfoDefaults](docs/Set-PSFunctionInfoDefaults):
95116

96117
```powershell
97118
Set-PSFunctionInfoDefaults -Tags "stand-alone" -Copyright "(c) JDH IT Solutions, Inc." -author "Jeff Hicks" -company "JDH IT Solutions, Inc."
98119
```
99120

100-
The defaults will be stored in a JSON file at `$home\psfunctioninfo-defaults.json`. When you import this module, these values will be used to define entries in `$PSDefaultParameterValues`. Or, run `Update-PSFunctionInfoDefaults` to update parameter defaults.
121+
The defaults will be stored in a JSON file at `$home\psfunctioninfo-defaults.json`. When you import this module, these values will be used to define entries in `$PSDefaultParameterValues`. Or, run [Update-PSFunctionInfoDefaults](docs/Update-PSFunctionInfoDefaults) to update parameter defaults.
122+
123+
You can use [Get-PSFunctionInfoDefaults](docs/Get-PSFunctionInfoDefaults.md) to see the current values.
124+
125+
## Editor Integration
126+
127+
When you import the module into an editor, you will get additional features to make it easier to insert PSFunctionInfo metadata into your file. It is recommended that you explicitly import the module into the editor's integrated console session. You could add an `Import-Module PSFunctionInfo` command into the editor's PowerShell profile script.
101128

102-
You can use `Get-PSFunctionInfoDefaults` to see the current values.
129+
### Visual Studio Code
130+
131+
If you have an open file, in the integrated PowerShell console, you can run `New-PSFunctionfo` and press <kbd>TAB</kbd> to tab-complete the detected functions in the current file. The file path will automatically be detected. You can enter other values such as version, or simply press <kbd>ENTER</kbd> to insert the metadata, which you can then edit.
132+
133+
![vscode integration](assets/psfunctioninfo-vscode.png)
134+
135+
This example is taking advantage of saved defaults.
136+
137+
### PowerShell ISE
138+
139+
When you import the module in the PowerShell ISE, it will add a menu shortcut.
140+
141+
![ISE Menu](assets/ise-psfunction-menu.png)
142+
143+
With a loaded file, you could run `New-PSFunctionInfo` in the console specifying the function name. The Path will be auto-detected. Or use the menu shortcut which will give you a graphical "function picker"
144+
145+
![function picker](assets/ise-function-picker.png)
146+
147+
Select a function and click OK. The metadata block will be inserted into the file. This will not work with a file that has unsaved changes. When you insert new function metadata, the file in the ISE will be closed, re-opened, and focus should jump to the function.
148+
149+
![ISE metadata](assets/ise-psfunctioninfo.png)
103150

104151
## Background
105152

106153
This code is a prototype for a [suggestion](https://github.com/PowerShell/PowerShell/issues/11667) I made for PowerShell 7. Early versions of this code were published as [https://gist.github.com/jdhitsolutions/65070cd51b5cfb572bc6375f67bcbc3d](https://gist.github.com/jdhitsolutions/65070cd51b5cfb572bc6375f67bcbc3d "view the Github gist")
107154

155+
This module was first described at <https://jdhitsolutions.com/blog/powershell/8343/a-better-way-to-manage-powershell-functions/>.
156+
108157
## Roadmap
109158

110159
+ Add VS Code integration.
111-
+ Extract function metadata from files directly.
112160
+ Add function metadata by file, autodetecting the function name.
113161

114-
Last Updated 2021-04-22 13:04:23Z
162+
Last Updated 2021-04-26 14:06:13Z

assets/get-psfunctioninfo-file.png

85.1 KB
Loading

assets/ise-function-picker.png

52.6 KB
Loading

assets/ise-psfunction-menu.png

16.1 KB
Loading

assets/ise-psfunctioninfo.png

77.1 KB
Loading

assets/psfunctioninfo-vscode.png

108 KB
Loading

0 commit comments

Comments
 (0)