Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何完成readline参数?_Ruby - Fatal编程技术网

Ruby 如何完成readline参数?

Ruby 如何完成readline参数?,ruby,Ruby,我有一个Ruby应用程序,它使用readline命令完成 键入第一个字符串(命令)后,我希望能够完成它的参数。参数列表应基于所选命令 有人举个简单的例子吗 以下是命令: COMMANDS = [ 'collect', 'watch' ].sort COLLECT = [ 'stuff', 'otherstuff' ].sort comp = proc do |s| COMMANDS.grep( /^#{Regexp.escape(s)}/ ) end Read

我有一个Ruby应用程序,它使用readline命令完成

键入第一个字符串(命令)后,我希望能够完成它的参数。参数列表应基于所选命令

有人举个简单的例子吗

以下是命令:

COMMANDS = [
  'collect', 'watch'
].sort

COLLECT = [
  'stuff', 'otherstuff'
].sort

comp = proc do |s| 
  COMMANDS.grep( /^#{Regexp.escape(s)}/ )        
end

Readline.completion_proc = comp
每次按TAB键时,都会执行proc块,并匹配来自
COMMANDS
数组的命令。
其中一个命令完全匹配后,我只想开始在
COLLECT
数组中搜索参数。

经过思考,解决方案非常简单:

comp = proc do |s| 
  if Readline.line_buffer =~ /^.* /
    COLLECT.grep( /^#{Regexp.escape(s)}/ ) 
  else
    COMMANDS.grep( /^#{Regexp.escape(s)}/ ) 
  end
end

现在我只需要把它变成更灵活/可用的东西。

经过思考,解决方案非常简单:

comp = proc do |s| 
  if Readline.line_buffer =~ /^.* /
    COLLECT.grep( /^#{Regexp.escape(s)}/ ) 
  else
    COMMANDS.grep( /^#{Regexp.escape(s)}/ ) 
  end
end

现在我只需要将它转换成更灵活/可用的东西。

因为每次我查找类似的东西时都会首先出现您的问题,所以我想与其他人分享我的代码

#!/usr/bin/env ruby
require 'readline'

module Shell
  PROMPT = "shell> "
  module InputCompletor
    CORE_WORDS = %w[ clear help show exit export]
    SHOW_ARGS = %w[ list user ]
    EXPORT_ARGS = %w[ file ]
    COMPLETION_PROC = proc { |input|
      case input
      when /^(show|export) (.*)/
        command = $1
        receiver = $2
        DISPATCH_TABLE[$1].call($2)
      when /^(h|s|c|e.*)/
        receiver = $1
        CORE_WORDS.grep(/^#{Regexp.quote(receiver)}/)
      when /^\s*$/
        puts
        CORE_WORDS.map{|d| print "#{d}\t"}
        puts
        print PROMPT
      end
    }
    def self.show(receiver)
      if SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).length > 1
        SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/)
      elsif SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).length == 1
        "show #{SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).join}"
      end
    end
    def self.export(receiver)
      if EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).length > 1
        EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/)
      elsif EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).length == 1
        "export #{EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).join}"
      end
    end
    DISPATCH_TABLE = {'show' => lambda {|x| show(x)} ,
                      'export' => lambda {|x| export(x)}}
  end
  class CLI
    Readline.completion_append_character = ' '
    Readline.completer_word_break_characters = "\x00"
    Readline.completion_proc = Shell::InputCompletor::COMPLETION_PROC
    def initialize
      while line = Readline.readline("#{PROMPT}",true)
        Readline::HISTORY.pop if /^\s*$/ =~ line
        begin
          if Readline::HISTORY[-2] == line
            Readline::HISTORY.pop
          end
        rescue IndexError
        end
        cmd = line.chomp
        case cmd
        when /^clear/
          system('clear')
        when /^help/
          puts 'no help here'
        when /show list/
          puts 'nothing to show'
        when /^show\s$/
          puts 'missing args'
        when /export file/
          puts 'nothing to export'
        when /^export\s$/
          puts 'missing args'
        when /^exit/
          exit
        end
      end
    end
  end
end
Shell::CLI.new

因为每次我寻找类似的东西时,你的问题都会首先出现,所以我想与其他人分享我的代码

#!/usr/bin/env ruby
require 'readline'

module Shell
  PROMPT = "shell> "
  module InputCompletor
    CORE_WORDS = %w[ clear help show exit export]
    SHOW_ARGS = %w[ list user ]
    EXPORT_ARGS = %w[ file ]
    COMPLETION_PROC = proc { |input|
      case input
      when /^(show|export) (.*)/
        command = $1
        receiver = $2
        DISPATCH_TABLE[$1].call($2)
      when /^(h|s|c|e.*)/
        receiver = $1
        CORE_WORDS.grep(/^#{Regexp.quote(receiver)}/)
      when /^\s*$/
        puts
        CORE_WORDS.map{|d| print "#{d}\t"}
        puts
        print PROMPT
      end
    }
    def self.show(receiver)
      if SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).length > 1
        SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/)
      elsif SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).length == 1
        "show #{SHOW_ARGS.grep(/^#{Regexp.quote(receiver)}/).join}"
      end
    end
    def self.export(receiver)
      if EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).length > 1
        EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/)
      elsif EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).length == 1
        "export #{EXPORT_ARGS.grep(/^#{Regexp.quote(receiver)}/).join}"
      end
    end
    DISPATCH_TABLE = {'show' => lambda {|x| show(x)} ,
                      'export' => lambda {|x| export(x)}}
  end
  class CLI
    Readline.completion_append_character = ' '
    Readline.completer_word_break_characters = "\x00"
    Readline.completion_proc = Shell::InputCompletor::COMPLETION_PROC
    def initialize
      while line = Readline.readline("#{PROMPT}",true)
        Readline::HISTORY.pop if /^\s*$/ =~ line
        begin
          if Readline::HISTORY[-2] == line
            Readline::HISTORY.pop
          end
        rescue IndexError
        end
        cmd = line.chomp
        case cmd
        when /^clear/
          system('clear')
        when /^help/
          puts 'no help here'
        when /show list/
          puts 'nothing to show'
        when /^show\s$/
          puts 'missing args'
        when /export file/
          puts 'nothing to export'
        when /^export\s$/
          puts 'missing args'
        when /^exit/
          exit
        end
      end
    end
  end
end
Shell::CLI.new

你试过写些什么吗?当然,举个例子。我试图通过在proc块中工作来找到解决方案。Readline.line\u buffer返回正在写入的整个字符串,我确信它可以帮助我仅为参数创建一个单独的搜索上下文,而不是使用数组来执行
命令和
收集
,使用散列。如果用户键入了一个完整的单词,您的查找是即时的:
命令[s]
。如果您想要部分命中,那么使用过滤器/regex搜索
命令的
,并返回可能的命中,或者查看Ruby的内置,它有助于提供子字符串来匹配部分键入的单词。您尝试过写什么吗?当然,添加了一个示例。我试图通过在proc块中工作来找到解决方案。Readline.line\u buffer返回正在写入的整个字符串,我确信它可以帮助我仅为参数创建一个单独的搜索上下文,而不是使用数组来执行
命令和
收集
,使用散列。如果用户键入了一个完整的单词,您的查找是即时的:
命令[s]
。如果您想要部分命中,那么使用过滤器/regex来搜索
命令的
散列并返回可能的命中,或者查看Ruby的内置项,这有助于提供子字符串来匹配部分键入的单词。