简体   繁体   English

Powershell如何在按键上进行快速更改?

[英]Powershell how to make the prompt change on key press?

I'm new to Powershell. 我是Powershell的新手。 I'm trying to create my own custom prompt that shows a truncated version of the current dir unless you expand it by pressing CTRL + R . 我正在尝试创建自己的自定义提示,显示当前目录的截断版本,除非您通过按CTRL + R展开它。 Moreover, I would like to do this: 而且,我想这样做:

$short\dir\path...>
*user presses CTRL+R*
$really\really\long\full\dir\path>
*Full dir path is shown as long as CTLR + R is held down*

This isn't a super elegant solution, but it basically turns Ctrl + Alt + R into a hotkey for displaying the current directory. 这不是一个超级优雅的解决方案,但它基本上将Ctrl + Alt + R转换为热键以显示当前目录。 You can change the chord to "Ctrl+R" but you'll be overwriting a default PSReadlineKeyHandler for powershell. 您可以将和弦更改为“Ctrl + R”,但是您将覆盖PowerShell的默认PSReadlineKeyHandler。 It looks like it gets stuck on the command, but if you begin typing the next line will appear. 看起来它会卡在命令上,但是如果你开始键入,则会出现下一行。 You will need to add both of these to your Microsoft.Powershell_Profile.ps1 located in $env:USERPROFILE\\Documents\\WindowsPowershell\\ 您需要将这两者添加到位于$env:USERPROFILE\\Documents\\WindowsPowershell\\ Microsoft.Powershell_Profile.ps1 $env:USERPROFILE\\Documents\\WindowsPowershell\\

function prompt {
    if(($pwd | split-path -Parent | Split-Path -Leaf) -match ':')
    {
        "$pwd\>"
    }
    elseif (($pwd | Split-Path -Leaf) -match ':')
    {
        "$pwd>"
    }
    else {
        "...\$($pwd | split-path -Parent | Split-Path -Leaf)\$($pwd | Split-path -Leaf)\>"
    }
}

Set-PSReadlineKeyHandler -Chord "Ctrl+Alt+R" -ScriptBlock {
    write-host $pwd -nonewLine
}

Hopefully that helps! 希望这有帮助!

I don't think there is a way to do that, but I can share with you a custom prompt I like to use instead: 我认为没有办法做到这一点,但我可以与你分享一个我喜欢使用的自定义提示:

function prompt {
    $Host.UI.RawUI.WindowTitle = Get-Location
    "[$env:COMPUTERNAME] PS> "
}

This puts the current computer name in the prompt (you may have no need for this), but puts the current path in the window title, where long paths especially are out of the way and don't clutter the prompt. 这会将当前计算机名称放在提示符中(您可能不需要这样做),但是将当前路径放在窗口标题中,其中长路径特别是不在路上并且不会使提示混乱。

The following is a way to do this, but it involves a lot of compromises. 以下是一种方法,但它涉及很多妥协。 First it only while work in the PS console, not the ISE, or not in any application that hosts PS. 首先它只在PS控制台中工作,而不是在ISE中工作,或者不在任何承载PS的应用程序中工作。 Second it will involve a lot of work, depending on how, ummm, "smooth" you want the experience to be. 其次,它将涉及大量的工作,取决于你想要体验的“顺畅”。 Third, it'll probably cause other unexpected stuff to happen. 第三,它可能会导致其他意想不到的事情发生。

Basically you write a script for the prompt function that polls the keyboard looking either for Ctrl-R or any other "action" character. 基本上你为一个提示函数编写了一个脚本,该函数轮询键盘,查找Ctrl-R或任何其他“动作”字符。 By "action" character I mean something like enter, tab, backspace, up-arrow, down-arrow, etc. that causes something to happen. 通过“动作”字符,我的意思是输入,制表符,退格键,向上箭头,向下箭头等会导致某些事情发生。 If the script sees Ctrl-R then you can output the full path, either in the title bar, or to the console. 如果脚本看到Ctrl-R,那么您可以在标题栏或控制台中输出完整路径。 If you output it to the console, then your script will have to figure out which row of the console contains the current prompt. 如果将其输出到控制台,那么您的脚本必须确定控制台的哪一行包含当前提示。 The Rawui member contains this info. Rawui成员包含此信息。

A bare outline might look like: 裸露的轮廓可能看起来像:

  do {
    sleep -milli 250
    if ($host.ui.rawui.keyavailable) {
      $key = $host.ui.rawui.readkey()
      if ($key.character -eq [char]'x') {
        write-host burp
      } else { break}
    }
  } while ($true)

Every quarter second the script sees if a key is available. 每隔四分之一秒脚本就会看到一个密钥是否可用。 If so it reads the key. 如果是这样,它会读取密钥。 If the key is 'x' (ctrl-r for you) it outputs "burp". 如果键是'x'(ctrl-r为你),它输出“burp”。 But you'd change 'burp' to the full path, along with logic to put the message in the right place (title bar or the right row on the console). 但是你要将'burp'更改为完整路径,以及将消息放在正确位置的逻辑(标题栏或控制台上的右行)。

If the key isn't 'x' then this simple example just returns. 如果键不是'x',那么这个简单的例子就会返回。 That means the 'x' gets "eaten" and the 'x' functionality no longer works until the next prompt is output. 这意味着'x'被“吃掉”而'x'功能在输出下一个提示之前不再有效。 However you could instead handle all of the "action" keys yourself instead of returning. 但是,您可以自己处理所有“操作”键而不是返回。 If up-arrow is pressed you'd retrieve the previous command and output it to the console. 如果按下向上箭头,您将检索上一个命令并将其输出到控制台。 If backarrow is pressed you'd delete the character before the cursor. 如果按下后退轴,则删除光标前的字符。 If tab is pressed you'd have to interact with PS' built-in command completion (not sure if that's possible). 如果按下tab,你必须与PS'内置命令完成交互(不确定是否可能)。 Etc. 等等。

Eventually when the user presses return, you'd need to either feed all the keys that make up the command line to the console (you can use the SendKeys method of the WScript host), or you can execute the command directly from you prompt function, using Invoke-Expression (iex). 最后,当用户按下返回时,您需要将组成命令行的所有键提供给控制台(您可以使用WScript主机的SendKeys方法),或者您可以直接从您的提示函数执行命令,使用Invoke-Expression(iex)。 If you use iex the command history that PS keeps (ie get-history) won't work, unless you figure out a way to handle that (maybe Add-History?). 如果你使用iex,PS保留的命令历史记录(即get-history)将不起作用,除非你找到一种方法来处理它(可能是Add-History?)。 If you use SendKeys there's a chance that someone typing fast will get his key strokes interspersed with SendKeys. 如果您使用SendKeys,那么有人可能会快速打字,使得他的关键笔划穿插在SendKeys中。

As a compromise, instead of handling all the "action" keys yourself, you could just exit the prompt when a key besides ctrl-r is pressed and use SendKeys to send that one key to the console, to prevent the char from getting "eaten". 作为妥协,不是自己处理所有“动作”键,你可以在按下ctrl-r之外的键时退出提示并使用SendKeys将一个键发送到控制台,以防止char被“吃掉” ”。 That way you could probably get by with 20 lines of script instead of a few hundred, at the expense of ctrl-r only working before any characters are typed. 这样你就可以得到20行脚本而不是几百行,代价是ctrl-r仅在键入任何字符之前工作。

Another complication. 另一个复杂因素。 readkey() does allow you to get both down and up keystrokes. readkey()允许您同时获得向下和向上键击。 So you could display the full path as long as the 'r' in ctrl-r is pressed. 因此,只要按下ctrl-r中的'r',就可以显示完整路径。 However your script would need to understand up/down keystrokes elsewhere. 但是,您的脚本需要了解其他位置的向上/向下键击。 That might be as simple as just ignoring the down keystrokes. 这可能就像忽略向下击键一样简单。

There is one bright side to this. 这有一个好的方面。 You could implement key-handling functionality over and above what PS normally does. 您可以在PS通常执行的范围之外实现密钥处理功能。 So if you wanted ctrl-t to show the current time, you could do that. 因此,如果你想让ctrl-t显示当前时间,你可以这样做。 If you wanted ctrl-w to delete the current word under the cursor you could. 如果你想让ctrl-w删除光标下的当前单词。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM