有一个让我非常喜欢Windows PowerShell ISE的理由,就是它将它的基础脚本对象模型暴露给用户,这样就允许用户按照自己的方式和需要去自定义脚本体验。
自定义ISE的核心是$psISE对象。$psISE对象允许用户去控制ISE许多方面的功能。你可以从这里获取关于$psISE的分层对象模型的介绍,和与这些对象相关联的功能。
这篇文章会讨论你怎样利用PowerShell公开提供的解释器接口,来结合ISE对象模型魅力,去创建脚本分析和快速定位的工具。
想象一下,你不得不分析一个相对庞大的PowerShell脚本。那这个脚本可能是别人写的,也有可能是你自己几个月前写的,扔了好久了。PowerShell ISE已经做了件非常棒的工作了,它提供了脚本环境。你可以通过添加Add-On(附加工具)来扩充它的功能,让你的脚本体验更好,更高效。从PowerShell 3.0开始,脚本的抽象语法树(AST)就可以使用语法解释器接口非常方便的获取了。下面的脚本行会获取当前打开的ISE中的脚本的AST:
复制代码 代码如下:
$AbstractSyntaxTree = [System.Management.Automation.Language.Parser]::
ParseInput($psISE.CurrentFile.Editor.Text, [ref]$null, [ref]$null)
接下来让我们查询脚本中所有的函数:
复制代码 代码如下:
$functionsInFile = $AbstractSyntaxTree.FindAll({$args[0] -is
[System.Management.Automation.Language.FunctionDefinitionAst]}, $true)
撇开函数定位的定义,如果我们能回到光标之前出现的位置,那将太漂亮了。实现这个也非常简单。我们所要做的只是存储这些行号,然后按照反转顺序反转他们。(是否有人已经知道了,“堆栈”)
下面的脚本块展示了展示了Go-To Definition的实现。
复制代码 代码如下:
#Define some useful global variables
$global:__ISEGoToAddOncurrLine=1
$global:__ISEGoToAddOncurrcol=1
$global:__ISEGoToAddOnlineToGoTo=1
$global:__ISEGoToAddOncolToGoTo=1
#We need two stacks - one each for line and column
$global:__ISEGoToAddOnstackOfLine = New-Object System.Collections.Stack
$global:__ISEGoToAddOnstackOfCol = New-Object System.Collections.Stack
#This script block has the logic for the implementation of the Go-To definition functionality
$global:__ISEGoToAddOnscriptBlockGoTo =
{
$AbstractSyntaxTree =[System.Management.Automation.Language.Parser]::ParseInput($psISE.CurrentFile.Editor.Text,[ref]$null, [ref]$null)
$functionsInFile = $AbstractSyntaxTree.FindAll(
{$args[0] -is[System.Management.Automation.Language.FunctionDefinitionAst]}, $true)
#Get the text of the line where we have the cursor
$str = $psISE.CurrentFile.Editor.CaretLineText
#Store them on the stack for later use
$global:__ISEGoToAddOnstackOfLine.Push($psISE.CurrentFile.Editor.CaretLine)
$global:__ISEGoToAddOnstackOfCol.Push($psISE.CurrentFile.Editor.CaretColumn)
$global:__ISEGoToAddOncurrLine = $global:__ISEGoToAddOnstackOfLine.Peek()
$global:__ISEGoToAddOncurrcol = $global:__ISEGoToAddOnstackOfCol.Peek()
#Get the selected text so that it can be used for searching existing functions
$selectedFunction = $psISE.CurrentFile.Editor.SelectedText
#Ensure that the cursor is somewhere between the word boundaries of the function
$functionsInFile | %{if(($str.Contains($_.name)) `
–and ($global:__ISEGoToAddOncurrcol -ge
$str.IndexOf($_.name)) `
-and ($global:__ISEGoToAddOncurrcol -le
($str.IndexOf($_.name)+$_.name.length))
)
{$selectedFunction = $_.name}
}
if($selectedFunction -ne "")
{
#See if the selected function exists in the current open file
$functionToGoTo = $functionsInFile | "$selectedFunction"}
$global:__ISEGoToAddOnlineToGoTo = $functionToGoTo.Extent.StartLineNumber
$global:__ISEGoToAddOncolToGoTo = $functionToGoTo.Extent.StartColumnNumber
}
if($functionToGoTo -eq $null)
{
try
{
$comm = Get-Command -Name "$selectedFunction" -ErrorAction SilentlyContinue
$comm.Definition | Out-GridView
}
catch [System.Exception]
{
}
}
else
{
#Select the function definition, assuming the function name immediately follows the keyword 'function'
try
{
$psise.CurrentFile.Editor.Select($global:__ISEGoToAddOnlineToGoTo,
($global:__ISEGoToAddOncolToGoTo+9),
$global:__ISEGoToAddOnlineToGoTo,
($global:__ISEGoToAddOncolToGoTo+8+$selectedFunction.length+1))
}
catch [System.Exception]
{
}
}
}
补充一下,Go-To Definition 功能,如果当前Powershell会话中存在的话,以上脚本会显示选中文本的定义。(另外,上面的脚本只是一个简单的例子,假如你的“function”关键字和函数名出现在脚本的同一行。这在PowerShell中并不是必须的,所以如果你的脚本风格不同,你可能需要微调一下逻辑。)
接下来应当是在Add-on(附加工具)菜单上添加这些脚本,并把它作为选中脚本的一个命令。下面两行就可以做这件事。
复制代码 代码如下:
$global:__ISEGoToAddOnsb1 =
{& $global:__ISEGoToAddOnscriptBlockGoTo | Out-Null}
$null=$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add(
"Go do definition", $global:__ISEGoToAddOnsb1, "F12")
现在来看看我们怎样实现Go-Back 功能,使用我们定义的全局堆栈,几行代码即可:
复制代码 代码如下:
$global:__ISEGoToAddOnscriptBlockGoBack =
{
try
{
#Pop the line and column numbers from the stack to do a reverse traversal
$global:__ISEGoToAddOncurrLine =
$global:__ISEGoToAddOnstackOfLine.Pop()
$global:__ISEGoToAddOncurrcol =
$global:__ISEGoToAddOnstackOfCol.Pop()
$psISE.CurrentFile.Editor.SetCaretPosition(
$global:__ISEGoToAddOncurrLine, $global:__ISEGoToAddOncurrcol)
$psISE.CurrentFile.Editor.SelectCaretLine();
}
catch [System.Exception]
{
}
}
$global:__ISEGoToAddOnsb2 = {& $global:__ISEGoToAddOnscriptBlockGoBack | Out-Null}
$null=$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Go Back",$global:__ISEGoToAddOnsb2, "Shift+F12")
就到这里了,只用了一些PowerShell代码就实现了Visual Studio中的Go-To Definition (转向定义)和Go-Back(返回)功能。
你还可以继续扩展这个脚本,让它包含这些任务:诸如显示脚本中所有函数,点击函数转到函数定义。作为大家进一步扩展功能的鼓励,我给你看下我的 ISE附加工具现在的样子。
扩展PowerShell ISE 中的 “附加工具”菜单
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 王力宏.2015-你的爱【HomeBoy】【WAV+CUE】
- 泰迪罗宾.1984-天外人(2004环球复黑王)【宝丽金】【WAV+CUE】
- 《网络夜色风 2CD》[WAV/分轨][1GB]
- 《发烧金曲金装影视 绝对超值不容错过 2CD》[WAV/分轨][600MB]
- 《林俊杰 最具影响力的创作歌手 JJ林俊杰 2CD》[WAV+CUE][940MB]
- 《CATO 黄油猫》评测:和物理老师说再见……吗?
- 《Ara:不为人知的历史》:抗衡《文明》?4X游戏挑战者
- 《艾诺提亚:失落之歌》:令人失望的意大利特色试验品
- 《蛋仔派对》斯派克皮肤图鉴
- 黑神话悟空九种美酒在哪获得 黑神话悟空九种酒位置一览
- 黑神话悟空全丹药配怎么获取 黑神话悟空全丹药配方获取方式介绍
- 梁汉文2014-听后感[天凯唱片][WAV+CUE]
- 徐小明1984-剑胆琴心(LP版)[文志][WAV+CUE]
- 韩红-精选(庆功版)[WAV整轨]
- 《暗喻幻想:ReFantazio》获IGN法国满分评价:完美的新标杆之作