def rb_gets(prompt, config={}) # yield field
      if config.is_a? Hash
        # okay
        #
      elsif config.is_a? Array
        # an array is supplied, and tabbing helps complete from that
        # array.
        options = config
        completion_proc = Proc.new{|str| 
          options.dup.grep Regexp.new("^#{str}");
        }
        config = {}
        config[:tab_completion] = completion_proc
      elsif config == Pathname
        # we need to return a pathname TODO and prepend dirname
        # allow user to specify startdir else take current
        completion_proc = Proc.new {|str| Dir.glob(str +"*").collect { |f| File.directory?(f) ? f+"/" : f  } }
        help_text = "Enter start of filename and tab to get completion"
        config = {}
        config[:tab_completion] = completion_proc
        config[:help_text] = help_text
      elsif config == Integer
        config = {}
        config[:datatype] = 1.class
        config[:type] = :integer
      elsif config == Float
        config = {}
        v = 0.11
        config[:datatype] = v.class
        config[:type] = :float
      elsif config == :phone

        config = {}
      end
      begin
        win = __create_footer_window
        form = Form.new win
        r = 0; c = 1;
        default = config[:default] || ""
        prompt = "#{prompt} [#{default}]:" if default.size > 0
        _max = FFI::NCurses.COLS-1-prompt.size-4
        displen = config[:width] || [config[:maxlen] || 999, _max].min
        maxlen = config[:maxlen] || _max
        field = LabeledField.new form, :row => r, :col => c, :maxlen => maxlen, :default => default, :label => prompt,
          :width => displen
        field.datatype(config[:datatype]) if config[:datatype]
        field.type(config[:type]) if config[:type]
        bg = Ncurses.COLORS >= 236 ? 233 : :blue
        field.bgcolor = bg
        field.cursor_end if default.size > 0
        def field.default=(x); default(x);end

        # if user wishes to use the yield and say "field.history = [x,y,z] then
        # we should alredy have extended this, so lets make it permanent
        require 'canis/core/include/rhistory'
        field.extend(FieldHistory)
        field.history = config[:history]

        yield field if block_given?
        form.repaint
        win.wrefresh
        prevchar = 0
        entries = nil
        oldstr = nil # for tab completion, origal word entered by user
        while ((ch = win.getchar()) != 999)
          if ch == 10 || ch == 13 || ch == KEY_ENTER
            begin
              # validate in case ranges or other validation given
              field.on_leave
              break
            rescue FieldValidationException => err # added 2011-10-2 v1.3.1 so we can rollback
              #alert err.to_s
              # unable to use alert now, since closing alert repaints root window and clears the
              # window this was on (command window in numbered menu).
              print_this(win, err.to_s, $errorcolor, 1, 0)
              form.setpos
            rescue => err
              Ncurses.beep
              break
            end
          end
          #return -1, nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
          return nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
          #if ch == ?\M-h.getbyte(0) #                            HELP KEY
          #help_text = config[:help_text] || "No help provided"
          #color = $datacolor
          #print_help(win, r, c, color, help_text)
          ## this will come over our text
          #end
          # tab completion and help_text print on F1
          # that field objects can extend, same for tab completion and gmail completion
          if ch == KEY_TAB
            if config
              str = field.text
              # tab_completion
              # if previous char was not tab, execute tab_completion_proc and push first entry
              # else push the next entry
              if prevchar == KEY_TAB
                if !entries.nil? && !entries.empty?
                  str = entries.delete_at(0)
                else
                  str = oldstr if oldstr
                  prevchar = ch = nil # so it can start again completing
                end
              else
                tabc = config[:tab_completion] unless tabc
                next unless tabc
                oldstr = str.dup
                entries = tabc.call(str).dup
                $log.debug " tab got #{entries} for str=#{str}"
                str = entries.delete_at(0) unless entries.nil? || entries.empty?
                str = str.to_s.dup
              end
              if str
                field.text = str
                field.cursor_end
                field.set_form_col # shit why are we doign this, text sets curpos to 0
              end
              form.repaint
              win.wrefresh
            end

          elsif ch == KEY_F1
            help_text = config[:help_text] || "No help provided. C-c/C-g aborts. <TAB> completion. Alt-h history. C-a/e"
            print_status_message help_text, :wait => 7
          else
            form.handle_key ch
          end
          prevchar = ch
          win.wrefresh
        end
      rescue => err
        Ncurses.beep
        textdialog [err.to_s, *err.backtrace], :title => "Exception"
        $log.error "EXC in rb_getstr #{err} "
        $log.error(err.backtrace.join("\n")) 
      ensure
        win.destroy if win
      end
      config[:history] << field.text if config[:history] && field.text
      return field.text
    end
def rb_gets(prompt, config={}) # yield field
      if config.is_a? Hash
        # okay
        #
      elsif config.is_a? Array
        # an array is supplied, and tabbing helps complete from that
        # array.
        options = config
        completion_proc = Proc.new{|str| 
          options.dup.grep Regexp.new("^#{str}");
        }
        config = {}
        config[:tab_completion] = completion_proc
      elsif config == Pathname
        # we need to return a pathname TODO and prepend dirname
        # allow user to specify startdir else take current
        completion_proc = Proc.new {|str| Dir.glob(str +"*").collect { |f| File.directory?(f) ? f+"/" : f  } }
        help_text = "Enter start of filename and tab to get completion"
        config = {}
        config[:tab_completion] = completion_proc
        config[:help_text] = help_text
      elsif config == Integer
        config = {}
        config[:datatype] = 1.class
        config[:type] = :integer
      elsif config == Float
        config = {}
        v = 0.11
        config[:datatype] = v.class
        config[:type] = :float
      elsif config == :phone

        config = {}
      end
      begin
        win = __create_footer_window
        form = Form.new win
        r = 0; c = 1;
        default = config[:default] || ""
        prompt = "#{prompt} [#{default}]:" if default.size > 0
        _max = FFI::NCurses.COLS-1-prompt.size-4
        displen = config[:width] || [config[:maxlen] || 999, _max].min
        maxlen = config[:maxlen] || _max
        field = LabeledField.new form, :row => r, :col => c, :maxlen => maxlen, :default => default, :label => prompt,
          :width => displen
        field.datatype(config[:datatype]) if config[:datatype]
        field.type(config[:type]) if config[:type]
        bg = Ncurses.COLORS >= 236 ? 233 : :blue
        field.bgcolor = bg
        field.cursor_end if default.size > 0
        def field.default=(x); default(x);end

        # if user wishes to use the yield and say "field.history = [x,y,z] then
        # we should alredy have extended this, so lets make it permanent
        require 'canis/core/include/rhistory'
        field.extend(FieldHistory)
        field.history = config[:history]

        yield field if block_given?
        form.repaint
        win.wrefresh
        prevchar = 0
        entries = nil
        oldstr = nil # for tab completion, origal word entered by user
        while ((ch = win.getchar()) != 999)
          if ch == 10 || ch == 13 || ch == KEY_ENTER
            begin
              # validate in case ranges or other validation given
              field.on_leave
              break
            rescue FieldValidationException => err # added 2011-10-2 v1.3.1 so we can rollback
              #alert err.to_s
              # unable to use alert now, since closing alert repaints root window and clears the
              # window this was on (command window in numbered menu).
              print_this(win, err.to_s, $errorcolor, 1, 0)
              form.setpos
            rescue => err
              Ncurses.beep
              break
            end
          end
          #return -1, nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
          return nil if ch == ?\C-c.getbyte(0) || ch == ?\C-g.getbyte(0)
          #if ch == ?\M-h.getbyte(0) #                            HELP KEY
          #help_text = config[:help_text] || "No help provided"
          #color = $datacolor
          #print_help(win, r, c, color, help_text)
          ## this will come over our text
          #end
          # tab completion and help_text print on F1
          # that field objects can extend, same for tab completion and gmail completion
          if ch == KEY_TAB
            if config
              str = field.text
              # tab_completion
              # if previous char was not tab, execute tab_completion_proc and push first entry
              # else push the next entry
              if prevchar == KEY_TAB
                if !entries.nil? && !entries.empty?
                  str = entries.delete_at(0)
                else
                  str = oldstr if oldstr
                  prevchar = ch = nil # so it can start again completing
                end
              else
                tabc = config[:tab_completion] unless tabc
                next unless tabc
                oldstr = str.dup
                entries = tabc.call(str).dup
                $log.debug " tab got #{entries} for str=#{str}"
                str = entries.delete_at(0) unless entries.nil? || entries.empty?
                str = str.to_s.dup
              end
              if str
                field.text = str
                field.cursor_end
                field.set_form_col # shit why are we doign this, text sets curpos to 0
              end
              form.repaint
              win.wrefresh
            end

          elsif ch == KEY_F1
            help_text = config[:help_text] || "No help provided. C-c/C-g aborts. <TAB> completion. Alt-h history. C-a/e"
            print_status_message help_text, :wait => 7
          else
            form.handle_key ch
          end
          prevchar = ch
          win.wrefresh
        end
      rescue => err
        Ncurses.beep
        textdialog [err.to_s, *err.backtrace], :title => "Exception"
        $log.error "EXC in rb_getstr #{err} "
        $log.error(err.backtrace.join("\n")) 
      ensure
        win.destroy if win
      end
      config[:history] << field.text if config[:history] && field.text
      return field.text
    end
2011-11-27 I have replaced the getting of chars with a field
 get a string at the bottom of the screen

 @param [String] prompt - label to show
 @param [Hash] config - :default, :width of Field, :help_text, :tab_completion
 help_text is displayed on F1
 tab_completion is a proc which helps to complete user input
 @yield [Field] for overriding or customization
 @return [String, nil] String if entered, nil if canceled