# encoding: ascii # api: powershell # title: # description: Dot Sourced PSISE Snippet Editor Form # version: 8.25 # type: function # license: CC0 # function: Select-ItemV2 # x-poshcode-id: 4342 # x-archived: 2016-11-11T11:19:40 # # PowershellISE form to easily select, create and modify PSISE snippet XML files stored in the standard location, while protecting the portions of the XML that should not be changed. # Includes full control of the CaretOffset field for manipulating the insertion point when the snippet is loaded into the PSISE. # Intended to be run as a .\DotSourced script that can be added to the PSISE AddOn menu for quick access. # This is a complete working stand alone form, tested on V3 only. # # PSISE Snippet Editor function Select-ItemV2 { PARAM ( [Parameter(Mandatory=$true, ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$true,Position=0)] $options, [Parameter(Mandatory=$true, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, Position=1)] $displayProperty, [Parameter(Mandatory=$false, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true)] [string]$title="Select an item from the list", [Parameter(Mandatory=$false, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$true, HelpMessage='Form Size format is an Array of two interger values as: @(width, height)`nMinimum form width: 225, minimum form height: 250!')] [ValidateRange(225,1050)] [array]$PopupFormSize ) # Create the popup form and all controls [Windows.Forms.form]$PopupForm = new-object Windows.Forms.form [System.Windows.Forms.ListBox]$lstOptions = New-Object System.Windows.Forms.ListBox [System.Windows.Forms.Button]$btnOK = New-Object System.Windows.Forms.Button [System.Windows.Forms.Button]$btnCancel = New-Object System.Windows.Forms.Button Add-Member -InputObject $PopupForm -MemberType NoteProperty -Name gv_ReturnItem -Value $null $PopupForm.StartPosition = "CenterParent" #"CenterScreen" $PopupForm.ControlBox = $False $PopupForm.KeyPreview = $True $PopupForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") {if (($btnOk.Enabled)) {& $btnOkClick}}}) $PopupForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") {& $btnCancelClick}}) # form control scripts $btnOkClick = {if ($lstOptions.SelectedIndex -lt 0) { $PopupForm.gv_ReturnItem = $null } else { $PopupForm.gv_ReturnItem = $options[$lstOptions.SelectedIndex] $PopupForm.Close() } } $btnCancelClick = {$PopupForm.gv_ReturnItem = $null;$PopupForm.Close()} $lstOptionsChanged = {if ($lstOptions.SelectedIndex -ge 0) {$btnOk.Enabled = $true} else {$btnOk.Enabled = $false} } # form initialize code if ($PopupFormSize) { if ($PopupFormsize[0] -lt 225) {$PopupFormsize[0] = 225} if ($PopupFormsize[1] -lt 250) {$PopupFormsize[1] = 250} } else { $PopupFormsize = @(225,250) } $lstsize = @(($PopupFormsize[0]-25),($PopupFormsize[1]-70)) $btnOksize = @([int](($PopupFormsize[0]/2)-100),($PopupFormsize[1]-65)) $btnCancelsize = @([int](($PopupFormsize[0]/2)+5),($PopupFormsize[1]-65)) $PopupForm.Size = new-object System.Drawing.Size @($PopupFormsize[0],$PopupFormsize[1]) $PopupForm.text = $title $lstOptions.Name = "lstOptions" $lstOptions.Width = $lstsize[0] $lstOptions.Height = $lstsize[1] $lstOptions.Location = New-Object System.Drawing.Size(5,5) $lstOptions.Add_SelectedIndexChanged($lstOptionsChanged) $lstOptions.Add_MouseDoubleClick($btnOkClick) $btnOK.Width=75 $btnOK.Location = New-Object System.Drawing.Size($btnOksize[0], $btnOksize[1]) $btnOK.Text = "OK" $btnOK.add_click($btnOkClick) $btnOk.Enabled = $false $PopupForm.Controls.Add($lstOptions) $PopupForm.Controls.Add($btnOK) $btnCancel.Width=75 $btnCancel.Location = New-Object System.Drawing.Size($btnCancelsize[0], $btnCancelsize[1]) $btnCancel.Text = "Cancel" $btnCancel.Add_Click($btnCancelClick) $PopupForm.Controls.Add($btnCancel) #Populate ListBox foreach ($option in $options) { $lstOptions.Items.Add($option.$displayProperty) | Out-Null } $PopupForm.ShowDialog() | Out-Null return ($PopupForm.gv_ReturnItem) } cls #Create the main form [System.Windows.Forms.Application]::EnableVisualStyles() [Windows.Forms.form]$form = new-object Windows.Forms.form $form.Size = new-object System.Drawing.Size (933, 575) $form.StartPosition = "CenterParent" #"CenterScreen" $form.text = "PowerShellISE Snippet Editor: by " $form.BackColor = "lightgray" $form.MinimizeBox = $False $form.MaximizeBox = $False $form.WindowState = "Normal" $lblTitle = new-object System.Windows.Forms.Label $txtTitle = new-object System.Windows.Forms.TextBox $lblAuthor = new-object System.Windows.Forms.Label $txtAuthor = new-object System.Windows.Forms.TextBox $lblDescription = new-object System.Windows.Forms.Label $txtDescription = new-object System.Windows.Forms.TextBox $lblScriptCode = new-object System.Windows.Forms.Label $txtScriptCode = new-object System.Windows.Forms.TextBox $lblLanguage = new-object System.Windows.Forms.Label $txtLanguage = new-object System.Windows.Forms.TextBox $lblExpansion = new-object System.Windows.Forms.Label $txtSnippetType = new-object System.Windows.Forms.TextBox $lblCursorOffset = new-object System.Windows.Forms.Label $txtCursorOffset = new-object System.Windows.Forms.TextBox $lblVarOffset = new-object System.Windows.Forms.Label $txtVarOffset = new-object System.Windows.Forms.TextBox $lblCaretOffset = new-object System.Windows.Forms.Label $txtCaretOffset = new-object System.Windows.Forms.TextBox $lblCodeEndOffset = new-object System.Windows.Forms.Label $txtCodeEndOffset = new-object System.Windows.Forms.TextBox $lblFilePath = new-object System.Windows.Forms.Label $txtFilePath = new-object System.Windows.Forms.TextBox $lblStatus = new-object System.Windows.Forms.Label $ckbAutoEdit = New-Object System.Windows.Forms.CheckBox $ckbNoBlanks = New-Object System.Windows.Forms.CheckBox $btnPsIse = new-object System.Windows.Forms.Button $btnOpen = new-object System.Windows.Forms.Button $btnNew = new-object System.Windows.Forms.Button $btnEdit = new-object System.Windows.Forms.Button $btnFixOffset = new-object System.Windows.Forms.Button $rdbFirstVar = New-Object System.Windows.Forms.RadioButton $rdbCodeEnd = New-Object System.Windows.Forms.RadioButton $rdbCursorPos = New-Object System.Windows.Forms.RadioButton $rdbFirstElipsis = New-Object System.Windows.Forms.RadioButton $btnSave = new-object System.Windows.Forms.Button Add-Member -InputObject $form -MemberType NoteProperty -Name gv_ProgramAuthor -Value 'Larry Coffey' -TypeName [string] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_SnippetAuthor -Value 'Larry Coffey' -TypeName [string] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_FileElipsisOffset -Value 0 -TypeName [int32] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_FileVariableOffset -Value 0 -TypeName [int32] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_FileCursorOffset -Value 0 -TypeName [int32] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_FileCodeEndOffset -Value 1 -TypeName [int32] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_FileLastWriteTime -Value $null Add-Member -InputObject $form -MemberType NoteProperty -Name gv_SnippetModified -Value $false -TypeName [bool] Add-Member -InputObject $form -MemberType NoteProperty -Name gv_SaveSnippetFlag -Value $false -TypeName [bool] # Script function code $scriptFldr = Split-Path -parent $MyInvocation.MyCommand.Definition $configPath = join-path -Path $scriptFldr -ChildPath "SnippetEditorConfig.txt" $LoadAuthor = { if (!(Test-Path $configPath)) { out-file -FilePath $configPath -InputObject $form.gv_SnippetAuthor -Encoding string } [array]$configs = Get-Content -Path $configPath $form.gv_SnippetAuthor = $configs[0] } $SaveAuthor = { Set-Content -Path $configPath -Value $form.gv_SnippetAuthor -Encoding String -Force } $ValidateAuthor = { if (!($txtAuthor.ReadOnly) -and ($txtAuthor.TabStop)) { $form.KeyPreview = $false $txtAuthor.ReadOnly = $true $txtAuthor.TabStop = $false $txtAuthor.ResetBackColor() if (($txtAuthor.Text.Trim()) -match "^\w*\s+\w*" ) { $form.gv_SnippetAuthor = ($txtAuthor.Text.Trim()) & $SaveAuthor $lblStatus.Text = (($form.gv_SnippetAuthor) + ", your name has been permanently saved for future use!`n") } else {$lblStatus.Text = ("Your name was NOT entered correctly, and has reverted to the previous entry!`nAuthor: " + ($form.gv_SnippetAuthor))} $txtAuthor.Text = ($txtAuthor.TempAuthor) } } $ChangeDefaultAuthor = { $txtAuthor.Add_LostFocus($ValidateAuthor) $txtAuthor.TempAuthor = ($txtAuthor.Text) $lblStatus.Text = "Enter your first and last name into the Author TextBox.`nPress the Enter ot Tab key to Save your name or Escape to cancel Saving your name!" $txtAuthor.Text = $null $txtAuthor.ReadOnly = $false $txtAuthor.BackColor = 0xffC0ffC0 $txtAuthor.TabStop = $true $form.KeyPreview = $true $txtAuthor.Focus() } & $LoadAuthor $Paths = $env:PSModulePath.Split(";") $Path = $paths[0] $parentArray = $Path.Split("\") $parentPath = "" for($i=0;$i -lt (($parentArray.Count)-1);$i++) {$parentPath = $parentPath + $parentArray[($i)] + "\"} $snippetPath = Join-Path -Path $parentPath -ChildPath Snippets $snippetWild = Join-Path -Path $parentPath -ChildPath Snippets\*.ps1xml Write-Warning ("Hi " + ($form.gv_SnippetAuthor) + ", your snippet path is...`n '" + $snippetPath + "'") $form.gv_SnippetModified = $false $form.gv_SaveSnippetFlag = $false $form.Tag = $null function Check_UnsavedSnippet($form) { if (($form.gv_SnippetModified) -and ($txtTitle.Text)) { $FileName = ($txtFilePath.Text).Split("\")[-1] $msg = ("Save your changes to this snippet file?`n`nTitle: " + ($txtTitle.Text) + "`n`nFileName: " + $FileName) $answ = [windows.forms.messagebox]::show($msg,"SAVE SNIPPET CHANGES:",[system.windows.forms.messageboxbuttons]::yesno,[System.Windows.Forms.MessageBoxIcon]::Question) if ($answ -eq "Yes") {& $btnSaveClick} } } function RadioButton_CheckedChanged( $rdbObject ){ if (($rdbObject.Checked)) { switch ($rdbObject.Name) { ($rdbFirstElipsis.Name) { if (($txtScriptCode.Elipsis1Pos) -gt 0) { $lblStatus.Text = ("First Elipsis found at position " + ($form.gv_FileElipsisOffset) + ".") $lblVarOffset.Text = "1st Elipsis:" $txtVarOffset.Text = ($form.gv_FileElipsisOffset) $txtScriptCode.SelectionStart = ($txtScriptCode.Elipsis1Pos) $txtScriptCode.Focus() } else { $lblStatus.Text = "Elipsis not found in snippet code." } } ($rdbFirstVar.Name) { if (($txtScriptCode.Variable1Pos) -gt 0) { $lblStatus.Text = ("First Variable found at position " + ($form.gv_FileVariableOffset) + ".") $lblVarOffset.Text = "1st Variable:" $txtVarOffset.Text = ($form.gv_FileVariableOffset) $txtScriptCode.SelectionStart = ($txtScriptCode.Variable1Pos) $txtScriptCode.Focus() } else { $lblStatus.Text = "Variable not found in snippet code." } } ($rdbCursorPos.Name) { if (($txtScriptCode.CursorPos) -gt 0) { $lblStatus.Text = ("Cursor position to be set at location " + ($form.gv_FileCursorOffset) + ".") $txtScriptCode.SelectionStart = ($txtScriptCode.CursorPos) $txtScriptCode.Focus() } else { $lblStatus.Text = "Cursor Offset at start of snippet code." } } ($rdbCodeEnd.Name) { if (($txtScriptCode.CodeEndPos) -gt 0) { $lblStatus.Text = ("Cursor position to be set at end of script code, at location " + ($txtCodeEndOffset.Text) + ".") $txtScriptCode.SelectionStart = ($txtScriptCode.CodeEndPos) $txtScriptCode.Focus() } else { $lblStatus.Text = "Cursor Offset at end of snippet script code." } } } } } function Get-CodeOffset ($selStart) { if ($selStart -eq 0) { $OF = 0 } else { $OL = ($txtScriptCode.GetLineFromCharIndex($selStart)) $OF = ($selStart - $OL) } return $OF } function Get-CodeLine ($selStart) { if ($selStart -eq 0) { $OL = 0 } else { $OL = ($txtScriptCode.GetLineFromCharIndex($selStart)) } return $OL } $form.Text = ($form.Text + $form.gv_ProgramAuthor) # Open snippet in PsIse $btnPsIseClick = {$lblStatus.Text="Select a snippet file to edit in the PowershellISE" $snippets = Get-ChildItem -File -Path $snippetWild $ht = @{options=$snippets;displayProperty="Name";title="Select one of the following PowershellISE Snippets";formSize=@(450,500)} $ReturnedItem = Select-ItemV2 @ht #SPLATTING the hashtable! if ($ReturnedItem) { Write-Warning "Opening: $ReturnedItem in PSISE" $psISE.CurrentPowerShellTab.Files.Add(($ReturnedItem.FullName)) $form.Close() } else {$lblStatus.Text="No valid snippet file path provided for PowershellISE..."} } # Open snippet in Snippet Editor $btnOpenClick = {$lblStatus.Text="Select a snippet file to edit in the Snippet Editer" $snippets = Get-ChildItem -File -Path $snippetWild $ht = @{options=$snippets;displayProperty="Name";title="Select one of the following PowershellISE Snippets";PopupFormSize=@(450,500)} $ReturnedItem = Select-ItemV2 @ht #SPLATTING the hashtable! if ($ReturnedItem) {$txtFilePath.Text = $ReturnedItem.FullName & $nullEdits & $loadXml } else {$lblStatus.Text="No valid snippet file path provided for editing..."} } # New Snippet $do_btnNew = { if (!($txtTitle.Modified) -and !($txtDescription.Modified) -and !($txtScriptCode.Modified)) { $form.Tag = "Only the Title, Description and ScriptCode fields are enabled for a new snippet! Filename generated upon leaving the Title field." $txtFilePath.Text=$null $txtCaretOffset.Text = 1 ($form.gv_FileCursorOffset) = 0 $txtCursorOffset.Text = 0 $form.gv_SnippetModified = $false & $nullEdits & $enableEdits $md = (Get-Date) $mds = "{0:MMM-dd-yyyy}" -f $md $form.gv_FileLastWriteTime = $mds $txtDescription.Text = ([char]27 + " ; Modified: " + $mds + [char]29) $txtTitle.Focus() } else { $lblStatus.Text="Unable to clear fields for a new snippet as you have unsaved work in progress!" } } # Get Snippet Fields $loadXml = {[xml]$snippetXml = Get-Content ($txtFilePath.Text) $txtTitle.Text = $snippetXml.Snippets.Snippet.Header.Title $txtDescription.Text = $snippetXml.Snippets.Snippet.Header.Description $txtAuthor.Text = $snippetXml.Snippets.Snippet.Header.Author $txtSnippetType.Text = $snippetXml.Snippets.Snippet.Header.SnippetTypes.SnippetType $txtLanguage.Text = $snippetXml.Snippets.Snippet.Code.Script.GetAttribute("Language") $txtCaretOffset.Text = $snippetXml.Snippets.Snippet.Code.Script.GetAttribute("CaretOffset") $txtCursorOffset.Text = $txtCaretOffset.Text $form.gv_FileCursorOffset = $txtCursorOffset.Text $txtCodeEndOffset.Text = "0" $txtScriptCode.CursorPos = -1 $form.gv_SnippetModified = $false if (($ckbNoBlanks.Checked)) { $tmptxt = $snippetXml.Snippets.Snippet.Code.Script.InnerText if (($tmptxt.indexOf("`r`n`r`n") -ge 0)) {$tmptxt = ($tmptxt.Replace("`r`n`r`n","`r`n"))} if (($tmptxt.indexOf("`n`n") -ge 0)) {$tmptxt = ($tmptxt.Replace("`n`n","`n"))} } else { $tmptxt = $snippetXml.Snippets.Snippet.Code.Script.InnerText if (($tmptxt.indexOf("`r`n") -ge 0)) {$tmptxt = ($tmptxt.Replace("`r`n","`n"))} } $txtScriptCode.Text = $tmptxt.Replace("`n","`r`n") $btnFixOffset.Enabled = $false $form.gv_FileLastWriteTime = (Get-Item ($txtFilePath.Text)).LastWriteTime.DateTime & $UpdateDescription if ($ckbAutoEdit.Checked) { $lblStatus.Text=("CaretOffset fixing is only enabled before editing. (File CaretOffset: " + ($txtCaretOffset.Text) + ", Script CodeEndOffset: " + ($txtcodeEndOffset.Text) + ", " + ($lblVarOffset.Text) + " " + ($txtVarOffset.Text) +")`nDisable AutoEdit as the time to fix it is just after snippet opening, or use the save button when done editing!") & $enableEdits $txtScriptCode.SelectionStart = 0 $txtScriptCode.Focus() } else { & $disableEdits $btnFixOffset.Enabled = $true $txtScriptCode.SelectionStart = 0 $txtScriptCode.Focus() $lblStatus.Text="CarretOffset fixing is only enabled before editing!" } $txtTitle.Modified = $false $txtDescription.Modified = $false $txtScriptcode.Modified = $false $form.gv_SnippetModified = $false & $txtScriptCode_TextChanged if($rdbFirstElipsis.Checked -eq $true) { & RadioButton_CheckedChanged($rdbFirstElipsis)} if($rdbFirstVar.Checked -eq $true) { & RadioButton_CheckedChanged($rdbFirstVar)} if($rdbCursorPos.Checked -eq $true) { & RadioButton_CheckedChanged($rdbCursorPos)} if($rdbCodeEnd.Checked -eq $true) { & RadioButton_CheckedChanged($rdbCodeEnd)} } # Erase field content $nullEdits = { $txtTitle.Text=$null $txtDescription.Text=$null $txtScriptCode.Text=$null $txtTitle.Modified = $false $txtDescription.Modified = $false $txtScriptcode.Modified = $false } # Toggle Edit Lock $btnEditClick = {if($btnEdit.Text -eq "Edit") { $lblStatus.Text="Only the Title, Description and ScriptCode fields are enabled for edit!" & $enableEdits if (!($txtTitle.Text)) { $txtTitle.Focus() } else { $txtScriptCode.SelectionStart = $txtCaretOffset.Text $txtScriptCode.Focus() } } else { $lblStatus.Text="All fields are view only. (Editing is disabled)" & $disableEdits } } # Allow Edits $enableEdits = { $btnFixOffset.Enabled = $false $txtTitle.ReadOnly=$false $txtDescription.ReadOnly=$false $txtScriptCode.ReadOnly=$false $txtTitle.Modified=$false $txtDescription.Modified=$false $txtScriptCode.Modified=$false $btnEdit.Text = "Lock" } # Prevent edits $disableEdits = { $txtTitle.ReadOnly=$true $txtDescription.ReadOnly=$true $txtScriptCode.ReadOnly=$true $btnEdit.Text = "Edit" } # Verify file ready for Saving $btnSaveClick = { $form.gv_SaveSnippetFlag = $true if (($txtFilePath.text.Length) -lt 10) { $lblStatus.Text="No Title or File Name provided for snippet!" $form.gv_SaveSnippetFlag = $false } if (($txtDescription.text.Length) -lt 10) { if ($form.gv_SaveSnippetFlag) { $lblStatus.Text="No snippet description provided yet, please add it!" $form.gv_SaveSnippetFlag = $false } else { $lblStatus.Text=($lblStatus.Text + " No snippet description provided yet, please add it!") } } if (($txtScriptCode.text.Length) -lt 10) { if ($form.gv_SaveSnippetFlag) { $lblStatus.Text="No snippet script Code provided yet, please add it!" $form.gv_SaveSnippetFlag = $false } else { $lblStatus.Text=($lblStatus.Text + " No snippet script Code provided yet, please add it!") } } if ($form.gv_SaveSnippetFlag -eq $true) { $oldFileName = ($txtFilePath.Text).Split("\")[-1] $msg = ("Confirm overwriting the existing file name:`r`n" + $oldFileName) $answ = [windows.forms.messagebox]::show($msg,"SAVE SNIPPET: Confirm Overwrite?",[system.windows.forms.messageboxbuttons]::yesno,[System.Windows.Forms.MessageBoxIcon]::Question) if ($answ -eq "Yes") { $form.gv_SaveSnippetFlag = $true $lblStatus.Text=("File is to be overwritten (add save file code)`r`nsaveFlag: " + $form.gv_SaveSnippetFlag) } else { $form.gv_SaveSnippetFlag = $false $lblStatus.Text=("File Exists. Overwrite denied. Change the Title to create a new filename...`r`nsaveFlag: " + $form.gv_SaveSnippetFlag) $txtTitle.Focus() } } else { $lblStatus.Text=("New file Editing is incomplete, the new filename is generated by the Title entry...") } if ($form.gv_SaveSnippetFlag -eq $true) {& $saveSnippetXml} } # duh $confirmFilenameChange = { $answ = $null $oldFileName = ($txtFilePath.Text).Split("\")[-1] $tmp = $txtTitle.Text $t = '*,_,?,_,/,_,|,_,\,_,<,_,>,_,[,_,],_' $tmpFileName = Invoke-Expression ('$tmp' + -join $(foreach($e in $t.Split(',')) {'.Replace("{0}","{1}")' -f $e, $([void]$foreach.MoveNext();$foreach.Current)} )) $tmpFileName = ($tmpFileName + ".snippets.ps1xml") $msg = ("Confirm existing file name:`n" + $oldFileName + "`n`nIs to be replaced with new file name:`n" + $tmpFileName + "`n`nAnswering No changes the Title without changing the FileName!") if ($txtFilePath.Text) { $answ = [windows.forms.messagebox]::show($msg,"TITLE CHANGED: Confirm File Name Change?",[system.windows.forms.messageboxbuttons]::yesno,[System.Windows.Forms.MessageBoxIcon]::Question) } else { $answ = "Yes" } if ($answ -eq "Yes") { $txtFilePath.Text = Join-Path -Path $snippetPath -ChildPath $tmpFileName $md = "{0:y}" -f (Get-Date) $form.gv_FileLastWriteTime = $md & $UpdateDescription } } # Update Filename on exit $txtTitle_LostFocus = { if ($txtTitle.Modified) { if (($txtTitle.Text)) { & $confirmFilenameChange $txtTitle.Modified } else { $txtTitle.Modified $lblStatus.Text = (($form.Tag) + "`nA Title is required as Filename is generated by the Title entry...") } } } $txtTitle_TextChanged = { if ($btnEdit.Text -eq "Lock") { $form.gv_SnippetModified = $true } } $txtDescription_TextChanged = { if ($btnEdit.Text -eq "Lock") { $form.gv_SnippetModified = $true } } # Auto Calculate CaretOffset $txtScriptCode_TextChanged = { if ($btnEdit.Text -eq "Lock") {$form.gv_SnippetModified = $true} $txtScriptCode.CodeEndPos = ($txtScriptCode.Text.Length) $txtCodeEndOffset.Text = (1 + ($txtScriptCode.CodeEndPos) - ($txtScriptCode.Lines.Count)) if ($txtScriptCode.CursorPos -eq -1) { #just loaded snippet $txtScriptCode.CursorLine = Get-CodeLine(($txtCursorOffset.Text)) $tempOffset = (($txtScriptCode.CursorLine) + ($txtCursorOffset.Text)) $txtScriptCode.CursorPos = ($tempOffset) } elseif ($txtScriptCode.SelectionStart -gt 0) { $txtScriptCode.CursorPos = $txtScriptCode.SelectionStart $txtScriptCode.CursorLine = Get-CodeLine($txtScriptCode.CursorPos) if ($txtScriptCode.CursorPos -gt 0) { $form.gv_FileCursorOffset = Get-CodeOffset($txtScriptCode.CursorPos) } $txtCursorOffset.Text = ($form.gv_FileCursorOffset) } & $getCaretOffset $lblStatus.Text = (($form.Tag) + "`nLast insertion point Cursor Offset position: " + ($form.gv_FileCursorOffset) + ", Code End insertion point will be " + ($txtCodeEndOffset.Text) + ".") } $UpdateDescription = { $tmpDesc = $txtDescription.Text $sFlag = $tmpDesc.IndexOf([char]27) $lFlag = $tmpDesc.LastIndexOf([char]27) $eFlag = $tmpDesc.IndexOf([char]29) $patterns = @("\s*\;\s*Filename:\s","\s*Filename:\s","\s*\;\s*Modified:\s","\s*Modified:\s","\;\s+") for ($i=0;$i -lt $patterns.Count;$i++) { $pattern = $patterns[($i)] $f = $tmpDesc | Select-String -Pattern $pattern if ($f.Matches.Index -ge 0) { $fFlag = $f.Matches.Index $i = $patterns.Count } } $regex = "\x1B.*\x1D" if (($form.gv_FileLastWriteTime)) { $dts = "{0:MMM-dd-yyyy}" -f (get-date ($form.gv_FileLastWriteTime)) } else { $dts = "{0:MMM-dd-yyyy}" -f (get-date) } if ($c) {} $FileName = ($txtFilePath.Text).Split("\")[-1] if (!$FileName) {$FileName = "''"} $newd = ([char]27 + "; Filename: " + $FileName + "; Modified: " + $dts + [char]29) if (($eFlag -ge 0) -and ($sFlag -ge 0)) { # All present! $s = $tmpDesc.Substring(0,$sFlag) $s = ($s.trim() + $newd) $txtDescription.Text = $s } else { # look for more signs if ($eFlag -ge 0) { if ($fFlag -ge 0) { $s = $tmpDesc.Substring(0,$fFlag) $s = ($s.Trim() + $newd) $txtDescription.Text = $s } else { $s = $tmpDesc.Replace([char]29,$null) $s = ($s.Trim() + $newd) $txtDescription.Text = $s } } else { # No Sign, just add it $s = ($tmpDesc.Trim() + $newd) $txtDescription.Text = $s } } } # Save snippet (Template required for New) $saveSnippetXml = { $template = @"
$form.gv_SnippetAuthor Expansion
"@ if (!(Test-Path ($txtFilePath.Text))) { Out-File -InputObject $template -FilePath ($txtFilePath.Text) -Encoding utf8 -NoClobber } $caretOffset = $txtCodeEndOffset.Text if (($rdbFirstElipsis.Checked)) {$caretOffset = $txtVarOffset.Text} if (($rdbFirstVar.Checked)) {$caretOffset = $txtVarOffset.Text} if (($rdbCursorPos.Checked)) {$caretOffset = $txtCursorOffset.Text} [xml]$snippetXml = Get-Content ($txtFilePath.Text) $snippetXml.Snippets.Snippet.Header.Title = $txtTitle.Text $snippetXml.Snippets.Snippet.Header.Description = $txtDescription.Text $snippetXml.Snippets.Snippet.Header.Author = $txtAuthor.Text $snippetXml.Snippets.Snippet.Header.SnippetTypes.SnippetType = $txtSnippetType.Text $snippetXml.Snippets.Snippet.Code.Script.SetAttribute('Language', $txtLanguage.Text) $snippetXml.Snippets.Snippet.Code.Script.SetAttribute('CaretOffset', $CaretOffset) [array]$codeLines = $txtScriptCode.Lines [string]$codeText = "" $max = ($codeLines.Count - 1) for ($i=0;$i -lt $max;$i++) { $codeText = ($codeText + $codeLines[($i)] + "`n") } $codeText = ($codeText + $codeLines[($i)]) $snippetXml.Snippets.Snippet.Code.Script.FirstChild.InnerText = ($codeText) $snippetXml.Save(($txtFilePath.Text)) $lblStatus.Text = ("Snippet: " + $txtTitle.Text + " saved.") Write-Warning $snippetXml.InnerXml $txtCaretOffset.text = $CaretOffset & $loadXml } # Get CaretOffset based on preference $getCaretOffset = { $txtScriptCode.Elipsis1Pos = (1 + ($txtScriptCode.Text.IndexOf('{'))) $form.gv_FileElipsisOffset = Get-CodeOffset($txtScriptCode.Elipsis1Pos) $lblVarOffset.Text = "1st Elipsis:" $txtVarOffset.Text = ($form.gv_FileElipsisOffset) $txtScriptCode.Variable1Pos = (1 + ($txtScriptCode.Text.IndexOf('$'))) $form.gv_FileVariableOffset = Get-CodeOffset($txtScriptCode.Variable1Pos) if (($form.gv_FileVariableOffset) -gt 0) {$form.Tag = (($form.Tag) + "Variable found at position " + ($form.gv_FileVariableOffset) + ".")} else {$form.Tag = (($form.Tag) + "Variable not found in snippet code.")} if (!($rdbFirstElipsis.Checked)) { $lblVarOffset.Text = "1st Variable:" $txtVarOffset.Text = ($form.gv_FileVariableOffset) } } # Update just the CaretOffset field $fixCaretOffset = { $caretOffset = $txtCodeEndOffset.Text if (($rdbFirstElipsis.Checked)) {$caretOffset = $txtVarOffset.Text} if (($rdbFirstVar.Checked)) {$caretOffset = $txtVarOffset.Text} if (($rdbCursorPos.Checked)) {$caretOffset = $txtCursorOffset.Text} if (!($txtTitle.Modified) -and !($txtDescription.Modified) -and !($txtScriptCode.Modified) -and (($txtFilePath.Text) -ne "") ) { if (($txtFilePath.Text) -ne $null) { $msg = ("Confirm saving changes to ONLY the CaretOffset Field?`n`nNew CaretOffset value: $caretOffset`n`nNote: Offset based on your RadioButton selection below!") $answ = [windows.forms.messagebox]::show($msg,"CHANGE CARET OFFSET:",[system.windows.forms.messageboxbuttons]::yesno,[System.Windows.Forms.MessageBoxIcon]::Question) if ($answ -eq "Yes") { [xml]$snippetXml = Get-Content ($txtFilePath.Text) $oldOffset = $snippetXml.Snippets.Snippet.Code.Script.GetAttribute('CaretOffset') $snippetXml.Snippets.Snippet.Code.Script.SetAttribute('CaretOffset', $caretOffset) $snippetXml.Save(($txtFilePath.Text)) $txtCaretOffset.Text = $caretOffset $lblStatus.Text=("Old CaretOffset value: " + $oldOffset + " replaced with current (" + ($txtCaretOffset.Text) + ")") & $enableEdits } } } } $AutoEditHelp = {$lblStatus.Text = "A check here Opens snippets directly in Edit mode (not locked), in the future."} $RemoveBlankLines = { $lines = @($txtScriptCode.Lines) $txtScriptCode.Text = $null for($i=0;$i -lt $lines.Count;$i++) { if ($lines[($i)] -notmatch '^\s*$') { $txtScriptCode.Text = ($txtScriptCode.Text + $lines[($i)] + "`r`n") } } } $NoBlanksHelp = { $lblStatus.Text = "A check here removes all blank lines from snippets opened in the future too." if ($ckbNoBlanks.Checked -eq $true) {& $RemoveBlankLines} } $lblFont = new-object System.Drawing.Font("Microsoft Sans Serif", 8.25, [System.Drawing.FontStyle]::Bold) $lblTitle.AutoSize = $true $lblTitle.Font = $lblFont $lblTitle.Location = new-object System.Drawing.Point(35, 9) $lblTitle.Name = "lblTitle" $lblTitle.Size = new-object System.Drawing.Size(32, 13) $lblTitle.Text = "Title:" $form.Controls.Add($lblTitle) $txtTitle.Location = new-object System.Drawing.Point(12, 27) $txtTitle.Name = "txtTitle" $txtTitle.ReadOnly = $true $txtTitle.Size = new-object System.Drawing.Size(473, 20) $txtTitle.TabIndex = 0 $txtTitle.Add_LostFocus($txtTitle_LostFocus) $txtTitle.Add_TextChanged($txtTitle_TextChanged) $form.Controls.Add($txtTitle) $lblAuthor.AutoSize = $true $lblAuthor.Font = $lblFont $lblAuthor.Location = new-object System.Drawing.Point(567, 9) $lblAuthor.Name = "lblAuthor" $lblAuthor.Size = new-object System.Drawing.Size(44, 13) $lblAuthor.Text = "Author:" $lblAuthor.Add_MouseDoubleClick($ChangeDefaultAuthor) $lblAuthor.Add_Click({$lblStatus.Text = ("A DoubleClick in the Author Label will allow you to enter your name...`nA DoubleClick on the Author TextBox below it will replace the current Author with " + ($form.gv_SnippetAuthor))}) $form.Controls.Add($lblAuthor) $txtAuthor.Location = new-object System.Drawing.Point(555, 27) $txtAuthor.Name = "txtAuthor" $txtAuthor.ReadOnly = $true $txtAuthor.AcceptsReturn = $false $txtAuthor.AcceptsTab = $false $txtAuthor.Multiline = $false $txtAuthor.Size = new-object System.Drawing.Size(145, 20) $txtAuthor.Text = $form.gv_SnippetAuthor $txtAuthor.TabStop = $false $txtAuthor.Add_MouseDoubleClick({$this.Text = ($form.gv_SnippetAuthor)}) $txtAuthor.Add_Click({$lblStatus.Text = ("A DoubleClick in the Author TextBox will replace the current Author with " + ($form.gv_SnippetAuthor) + "`nA DoubleClick on the Author Label above it will allow you to enter your name...")}) Add-Member -InputObject $txtAuthor -MemberType NoteProperty -Name TempAuthor -Value "" -TypeName [string] $form.Controls.Add($txtAuthor) $lblDescription.AutoSize = $true $lblDescription.Font = $lblFont $lblDescription.Location = new-object System.Drawing.Point(35, 58) $lblDescription.Name = "lblDescription" $lblDescription.Size = new-object System.Drawing.Size(71, 13) $lblDescription.Text = "Description:" $form.Controls.Add($lblDescription) $txtDescription.Location = new-object System.Drawing.Point(12, 76) $txtDescription.Name = "txtDescription" $txtDescription.ReadOnly = $true $txtDescription.Size = new-object System.Drawing.Size(886, 20) $txtDescription.TabIndex = 1 $txtDescription.Add_TextChanged($txtDescription_TextChanged) $form.Controls.Add($txtDescription) $lblExpansion.Font = $lblFont $lblExpansion.Location = new-object System.Drawing.Point(765, 9) $lblExpansion.Name = "lblExpansion" $lblExpansion.Size = new-object System.Drawing.Size(82, 13) $lblExpansion.Text = "Snippet Type:" $form.Controls.Add($lblExpansion) $txtSnippetType.Location = new-object System.Drawing.Point(753, 27) $txtSnippetType.Name = "txtSnippetType" $txtSnippetType.ReadOnly = $true $txtSnippetType.Size = new-object System.Drawing.Size(145, 20) $txtSnippetType.Text = "Expansion" $txtSnippetType.TabStop = $false $form.Controls.Add($txtSnippetType) $lblLanguage.Font = $lblFont $lblLanguage.Location = new-object System.Drawing.Point(230, 119) $lblLanguage.Name = "lblLanguage" $lblLanguage.Size = new-object System.Drawing.Size(63, 13) $lblLanguage.Text = "Language:" #$lblLanguage.Click += new-object System.EventHandler($label2_Click_1) $form.Controls.Add($lblLanguage) $txtLanguage.Location = new-object System.Drawing.Point(300, 116) $txtLanguage.Name = "txtLanguage" $txtLanguage.ReadOnly = $true $txtLanguage.Size = new-object System.Drawing.Size(145, 20) $txtLanguage.Text = "Powershell" $txtLanguage.TabStop = $false $form.Controls.Add($txtLanguage) $lblCursorOffset.Font = $lblFont $lblCursorOffset.Location = new-object System.Drawing.Point(600, 119) $lblCursorOffset.Name = "lblCursorOffset" $lblCursorOffset.Size = new-object System.Drawing.Size(80, 13) $lblCursorOffset.Text = "Cursor Offset:" $form.Controls.Add($lblCursorOffset) $txtCursorOffset.Location = new-object System.Drawing.Point(685, 116) $txtCursorOffset.Name = "txtCursorOffset" $txtCursorOffset.ReadOnly = $true $txtCursorOffset.Size = new-object System.Drawing.Size(55, 20) $txtCursorOffset.Text = "0" $txtCursorOffset.TabStop = $false $form.Controls.Add($txtCursorOffset) $lblVarOffset.Font = $lblFont $lblVarOffset.Location = new-object System.Drawing.Point(600, 100) $lblVarOffset.Name = "lblVarOffset" $lblVarOffset.Size = new-object System.Drawing.Size(75, 13) $lblVarOffset.Text = "1st Variable:" $form.Controls.Add($lblVarOffset) $txtVarOffset.Location = new-object System.Drawing.Point(685, 97) $txtVarOffset.Name = "txtVarOffset" $txtVarOffset.ReadOnly = $true $txtVarOffset.Size = new-object System.Drawing.Size(55, 20) $txtVarOffset.Text = "0" $txtVarOffset.TabStop = $false $form.Controls.Add($txtVarOffset) $lblCaretOffset.Font = $lblFont $lblCaretOffset.Location = new-object System.Drawing.Point(762, 119) $lblCaretOffset.Name = "lblCaretOffset" $lblCaretOffset.Size = new-object System.Drawing.Size(75, 13) $lblCaretOffset.Text = "Caret Offset:" $lblCaretOffset.Add_Click($fixCaretOffset) $form.Controls.Add($lblCaretOffset) $txtCaretOffset.Location = new-object System.Drawing.Point(843, 116) $txtCaretOffset.Name = "txtCaretOffset" $txtCaretOffset.ReadOnly = $true $txtCaretOffset.Size = new-object System.Drawing.Size(55, 20) $txtCaretOffset.Text = "1" $txtCaretOffset.TabStop = $false $txtCaretOffset.Add_Click($fixCaretOffset) $form.Controls.Add($txtCaretOffset) $lblCodeEndOffset.Font = $lblFont $lblCodeEndOffset.Location = new-object System.Drawing.Point(761, 100) $lblCodeEndOffset.Name = "lblCodeEndOffset" $lblCodeEndOffset.Size = new-object System.Drawing.Size(75, 13) $lblCodeEndOffset.Text = "Code End:" $form.Controls.Add($lblCodeEndOffset) $txtCodeEndOffset.Location = new-object System.Drawing.Point(843, 97) $txtCodeEndOffset.Name = "txtCodeEndOffset" $txtCodeEndOffset.ReadOnly = $true $txtCodeEndOffset.Size = new-object System.Drawing.Size(55, 20) $txtCodeEndOffset.Text = "1" $txtCodeEndOffset.TabStop = $false $form.Controls.Add($txtCodeEndOffset) $lblScriptCode.Font = $lblFont $lblScriptCode.Location = new-object System.Drawing.Point(35, 116) $lblScriptCode.Name = "lblScriptCode" $lblScriptCode.Size = new-object System.Drawing.Size(73, 13) $lblScriptCode.Text = "Script Code:" $form.Controls.Add($lblScriptCode) $txtScriptCode.AcceptsReturn = $true $txtScriptCode.AcceptsTab = $true $txtScriptCode.AllowDrop = $true $txtScriptCode.Location = new-object System.Drawing.Point(12, 142) $txtScriptCode.Multiline = $true $txtScriptCode.ScrollBars = [System.Windows.Forms.ScrollBars]::Both $txtScriptCode.Name = "txtScriptCode" $txtScriptCode.ReadOnly = $true $txtScriptCode.Size = new-object System.Drawing.Size(886, 294) $txtScriptCode.TabIndex = 2 $txtScriptCode.WordWrap = $false $txtScriptCode.Add_TextChanged($txtScriptCode_TextChanged) Add-Member -InputObject $txtScriptCode -MemberType NoteProperty -Name Elipsis1Pos -Value 0 Add-Member -InputObject $txtScriptCode -MemberType NoteProperty -Name Variable1Pos -Value 0 Add-Member -InputObject $txtScriptCode -MemberType NoteProperty -Name CursorPos -Value 0 Add-Member -InputObject $txtScriptCode -MemberType NoteProperty -Name CursorLine -Value 0 Add-Member -InputObject $txtScriptCode -MemberType NoteProperty -Name CodeEndPos -Value 1 $form.Controls.Add($txtScriptCode) $lblFilePath.Font = $lblFont $lblFilePath.Location = new-object System.Drawing.Point(35, 455) $lblFilePath.Name = "lblFilePath" $lblFilePath.Size = new-object System.Drawing.Size(65, 13) $lblFilePath.Text = "File Path:" $form.Controls.Add($lblFilePath) $txtFilePath.Location = new-object System.Drawing.Point(105, 450) $txtFilePath.Name = "txtFilePath" $txtFilePath.ReadOnly = $true $txtFilePath.Size = new-object System.Drawing.Size(791, 20) $txtFilePath.Text = "" $form.Controls.Add($txtFilePath) $lblStatus.Location = new-object System.Drawing.Point(12, 505) $lblStatus.Name = "lblStatus" $lblStatus.Size = new-object System.Drawing.Size(886, 30) $lblStatus.Text = "" $lblStatus.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter $form.Controls.Add($lblStatus) $btnPsIse.Location = new-object System.Drawing.Point(25, 480) $btnPsIse.Name = "btnPsIse" $btnPsIse.Size = new-object System.Drawing.Size(75, 23) $btnPsIse.TabIndex = 3 $btnPsIse.Text = "In PsIse" $btnPsIse.UseVisualStyleBackColor = $true $btnPsIse.add_click($btnPsIseClick) $form.Controls.Add($btnPsIse) $btnOpen.Location = new-object System.Drawing.Point(125, 480) $btnOpen.Name = "btnOpen" $btnOpen.Size = new-object System.Drawing.Size(75, 23) $btnOpen.TabIndex = 4 $btnOpen.Text = "Open" $btnOpen.UseVisualStyleBackColor = $true $btnOpen.add_click($btnOpenClick) $form.Controls.Add($btnOpen) $ckbAutoEdit.Location = new-object System.Drawing.Point(215, 472) $ckbAutoEdit.Name = "ckbAutoEdit" $ckbAutoEdit.TabIndex = 5 $ckbAutoEdit.Text = "Auto Edit" $ckbAutoEdit.AutoSize = $true $ckbAutoEdit.Add_Click($AutoEditHelp) $form.Controls.Add($ckbAutoEdit) $ckbNoBlanks.Location = new-object System.Drawing.Point(215, 490) $ckbNoBlanks.Name = "ckbNoBlanks" $ckbNoBlanks.TabIndex = 5 $ckbNoBlanks.Text = "No Blanks" $ckbNoBlanks.AutoSize = $true $ckbNoBlanks.Add_Click($NoBlanksHelp) $form.Controls.Add($ckbNoBlanks) $btnNew.Location = new-object System.Drawing.Point(300, 480) $btnNew.Name = "btnNew" $btnNew.Size = new-object System.Drawing.Size(75, 23) $btnNew.TabIndex = 6 $btnNew.Text = "New" $btnNew.UseVisualStyleBackColor = $true $btnNew.Add_click($do_btnNew) $form.Controls.Add($btnNew) $btnEdit.Location = new-object System.Drawing.Point(400, 480) $btnEdit.Name = "btnEdit" $btnEdit.Size = new-object System.Drawing.Size(75, 23) $btnEdit.TabIndex = 7 $btnEdit.Text = "Edit" $btnEdit.UseVisualStyleBackColor = $true $btnEdit.add_click($btnEditClick) $form.Controls.Add($btnEdit) $btnFixOffset.Location = new-object System.Drawing.Point(500, 480) $btnFixOffset.Name = "btnFixOffset" $btnFixOffset.Size = new-object System.Drawing.Size(75, 23) $btnFixOffset.TabIndex = 8 $btnFixOffset.Text = "Fix Offset" $btnFixOffset.UseVisualStyleBackColor = $true $btnFixOffset.Enabled = $false $btnFixOffset.add_click($fixCaretOffset) $form.Controls.Add($btnFixOffset) $rdbFirstElipsis.Location = new-object System.Drawing.Point(600, 472) $rdbFirstElipsis.Name = "rdbFirstElipsis" $rdbFirstElipsis.TabIndex = 10 $rdbFirstElipsis.Text = "1st Elipsis" $rdbFirstElipsis.AutoSize = $true $rdbFirstElipsis.Add_Click({RadioButton_CheckedChanged($this)}) $form.Controls.Add($rdbFirstElipsis) $rdbFirstVar.Location = new-object System.Drawing.Point(600, 490) $rdbFirstVar.Name = "rdbFirstVar" $rdbFirstVar.TabIndex = 9 $rdbFirstVar.Text = "1st Variable" $rdbFirstVar.AutoSize = $true $rdbFirstVar.Add_Click({RadioButton_CheckedChanged($this)}) $form.Controls.Add($rdbFirstVar) $rdbCursorPos.Location = new-object System.Drawing.Point(685, 472) $rdbCursorPos.Name = "rdbCursorPos" $rdbCursorPos.TabIndex = 10 $rdbCursorPos.Text = "Cursor Pos" $rdbCursorPos.AutoSize = $true $rdbCursorPos.Checked = $true $rdbCursorPos.Add_Click({RadioButton_CheckedChanged($this)}) #$rdbCursorPos.Add_CheckedChanged({RadioButton_CheckedChanged($this)}) $form.Controls.Add($rdbCursorPos) $rdbCodeEnd.Location = new-object System.Drawing.Point(685, 490) $rdbCodeEnd.Name = "rdbCodeEnd" $rdbCodeEnd.TabIndex = 10 $rdbCodeEnd.Text = "Code End" $rdbCodeEnd.AutoSize = $true $rdbCodeEnd.Add_Click({RadioButton_CheckedChanged($this)}) $form.Controls.Add($rdbCodeEnd) $btnSave.Location = new-object System.Drawing.Point(800, 480) $btnSave.Name = "btnSave" $btnSave.Size = new-object System.Drawing.Size(75, 23) $btnSave.TabIndex = 11 $btnSave.Text = "Save" $btnSave.UseVisualStyleBackColor = $true $btnSave.add_click($btnSaveClick) $form.Controls.Add($btnSave) $form.Add_Closing({Check_UnsavedSnippet($form)}) $form.KeyPreview = $false #only enabled on demand $form.Add_KeyDown({if ($_.KeyCode -eq "Enter") {if (($txtAuthor.TabStop)) {& $ValidateAuthor}}}) $form.Add_KeyDown({if ($_.KeyCode -eq "Escape") {if (($txtAuthor.TabStop)) {$txtAuthor.Text = $null; & $ValidateAuthor}}}) $form.ShowDialog() | Out-Null