提示用户输入密码并使用Sublime Text隐藏输入

时间:2019-11-23 11:45:21

标签: sublimetext3 sublimetext2 sublimetext sublime-text-plugin

我想提示您查询Sublime Text 2/3插件中的密码,并使用****隐藏输入。这不起作用,甚至会使SublimeText崩溃:

import sublime_plugin, sublime

class ExampleOneCommand(sublime_plugin.WindowCommand):
    def run(self):
        self.window.show_input_panel("Enter Password", "", self.on_done, self.getpwd, None)

    def getpwd(self, password):
        stars = "*" * len(password)
        self.window.show_input_panel("Enter Password", stars, self.on_input, self.getpwd, None)

    def on_done(self, password):
        pass

    def on_input(self, password):
        pass

如何正确执行?

1 个答案:

答案 0 :(得分:1)

如上所述,当我调用您的命令时,它使RuntimeErrormaximum recursion depth reached的插件主机崩溃。发生这种情况的原因也许可以通过以下简单示例得到最好的说明:

class ExampleTwoCommand(sublime_plugin.WindowCommand):
    def run(self):
        self.window.show_input_panel("Sample", "Initial Text", None, self.on_change, None)

    def on_change(self, pwd):
        print('on_change("%s")' % pwd)

如果调用该命令,然后立即在控制台中查找而不与输入进行交互,则会看到以下内容:

>>> window.run_command("example_two")
on_change("Initial Text")

因此,本质上您的问题是,当打开输入面板时,它会告诉on_change()处理程序有关初始文本的信息,并且您的命令会通过立即再次打开输入面板来对此做出响应,这将执行相同的操作,然后卡布姆。

要解决这个问题,您需要有一个防护装置来阻止这种情况的发生;例如:

class ExampleThreeCommand(sublime_plugin.WindowCommand):
    def run(self):
        self.initial = ""
        self.window.show_input_panel("Sample", "", None, self.on_change, None)

    def on_change(self, pwd):
        if self.initial != pwd:
            stars = "*" * len(pwd)
            self.initial = pwd
            self.window.show_input_panel("Sample", stars, None, self.on_change, None)

现在on_change()处理程序将仅在文本更改时重新打开输入处理程序。

其结果是,最终返回给您的文本是经过编辑的初始文本,因此,当最终调用on_done时,它得到的文本将包含所有{{1} }字符,归因于此处的操作。

要解决此问题,您需要检查*中提供的password,以查看其中包含的不是on_change字符的哪些字符,以知道实际键入的内容,然后保留分开,以便您在用户编辑文本时保留文本。同样,如果密码的长度发生变化,则由于某些人从输入中删除了一个或多个字符,您需要丢弃保存的字符。您还需要注意用户也在面板内移动光标的情况(例如插入字符)。

话虽如此,下面是完成所有这些操作的最简单示例,该示例使用*设置告诉输入面板,无论键入什么内容,都应将其遮盖:< / p>

password

我不确定Sublime Text 2是否支持此设置;当您在此处输入密码时,它会在Sublime Merge的密码输入中使用,因此可能是在那时添加的。

如果需要Sublime Text 2支持,那么下一个最好的事情就是类似这种插件和关联的键绑定的组合(我认为应该在那儿工作,但是我没有要测试的副本):< / p>

class ExampleFourCommand(sublime_plugin.WindowCommand):
    def run(self):
        panel = self.window.show_input_panel("Enter Password", "", self.on_done, None, None)
        panel.settings().set("password", True)

    def on_done(self, password):
        sublime.message_dialog("Password entered: '%s'" % password)
_password = ""
class ExampleFiveCommand(sublime_plugin.WindowCommand):
    def run(self):
        panel = self.window.show_input_panel("Enter Password", "", self.on_done, None, None)
        panel.settings().set("password_input", True)

        global _password
        _password = ""

    def on_done(self, password):
        sublime.message_dialog("Password entered: '%s'" % _password)


class PasswordInputCommand(sublime_plugin.TextCommand):
    def run(self, edit, character):
        global _password
        _password += character
        self.view.run_command("insert", {"characters": '*'})

在此,键绑定在您输入字符时执行自定义命令,但仅在视图具有设置 { "keys": ["<character>"], "command": "password_input", "context": [ { "key": "setting.password_input", "operator": "equal", "operand": true }, ], }, 并且其设置为true时才执行。关联的命令以字符串形式跟踪实际密码,然后打开输入面板将应用设置。结果是,只要打开面板并在其中键入内容,定制命令就会抓取文本并将其保留。

对于更完整的示例,您还需要绑定退格键,以防用户想要进行更正。您还可以在视图中使用该选择,以确定所输入字符应在现有密码中的何处。

总的来说,password_input设置是最干净的解决方案。