curses 1.1.0-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/BSDL +22 -0
- data/COPYING +56 -0
- data/README.md +71 -0
- data/ext/curses/curses.c +4618 -0
- data/ext/curses/depend +5 -0
- data/ext/curses/extconf.rb +144 -0
- data/lib/2.2/curses.so +0 -0
- data/lib/2.3/curses.so +0 -0
- data/lib/2.4/curses.so +0 -0
- data/lib/curses.rb +22 -0
- data/sample/hello.rb +29 -0
- data/sample/mouse.rb +53 -0
- data/sample/rain.rb +72 -0
- data/sample/view.rb +76 -0
- data/sample/view2.rb +138 -0
- data/vendor/x64-mingw32/PDCurses/pdcurses.dll +0 -0
- metadata +110 -0
    
        data/ext/curses/depend
    ADDED
    
    
| @@ -0,0 +1,144 @@ | |
| 1 | 
            +
            require 'mkmf'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            def have_all(*args)
         | 
| 4 | 
            +
              old_libs = $libs.dup
         | 
| 5 | 
            +
              old_defs = $defs.dup
         | 
| 6 | 
            +
              result = []
         | 
| 7 | 
            +
              begin
         | 
| 8 | 
            +
                args.each {|arg|
         | 
| 9 | 
            +
                  r = arg.call(*result)
         | 
| 10 | 
            +
                  if !r
         | 
| 11 | 
            +
                    return nil
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  result << r
         | 
| 14 | 
            +
                }
         | 
| 15 | 
            +
                result
         | 
| 16 | 
            +
              ensure
         | 
| 17 | 
            +
                if result.length != args.length
         | 
| 18 | 
            +
                  $libs = old_libs
         | 
| 19 | 
            +
                  $defs = old_defs
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            dir_config('curses')
         | 
| 25 | 
            +
            dir_config('ncurses')
         | 
| 26 | 
            +
            dir_config('termcap')
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            have_library("mytinfo", "tgetent") if /bow/ =~ RUBY_PLATFORM
         | 
| 29 | 
            +
            have_library("tinfo", "tgetent") or have_library("termcap", "tgetent")
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            header_library = nil
         | 
| 32 | 
            +
            [
         | 
| 33 | 
            +
              ["ncursesw/curses.h", ["ncursesw"]],
         | 
| 34 | 
            +
              ["ncurses.h", ["ncursesw", "ncurses"]],
         | 
| 35 | 
            +
              ["ncurses/curses.h", ["ncurses"]],
         | 
| 36 | 
            +
              ["curses_colr/curses.h", ["cur_colr"]],
         | 
| 37 | 
            +
              ["curses.h", ["curses", "pdcurses"]],
         | 
| 38 | 
            +
              # ["xcurses.h", ["XCurses"]], # XCurses (PDCurses for X11)
         | 
| 39 | 
            +
            ].each {|hdr, libs|
         | 
| 40 | 
            +
              header_library = have_all(
         | 
| 41 | 
            +
                lambda { have_header(hdr) && hdr },
         | 
| 42 | 
            +
                lambda {|h| libs.find {|lib| have_library(lib, "initscr", h) } })
         | 
| 43 | 
            +
              if header_library
         | 
| 44 | 
            +
                break;
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            if header_library
         | 
| 49 | 
            +
              header, library = header_library
         | 
| 50 | 
            +
              puts "header: #{header}"
         | 
| 51 | 
            +
              puts "library: #{library}"
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              curses = [header]
         | 
| 54 | 
            +
              if header == 'curses_colr/curses.h'
         | 
| 55 | 
            +
                curses.unshift("varargs.h")
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              for f in %w(beep bkgd bkgdset curs_set deleteln doupdate flash
         | 
| 59 | 
            +
                          getbkgd getnstr init isendwin keyname keypad resizeterm
         | 
| 60 | 
            +
                          scrl set setscrreg ungetch
         | 
| 61 | 
            +
                          wattroff wattron wattrset wbkgd wbkgdset wdeleteln wgetnstr
         | 
| 62 | 
            +
                          wresize wscrl wsetscrreg werase redrawwin
         | 
| 63 | 
            +
                          def_prog_mode reset_prog_mode timeout wtimeout nodelay
         | 
| 64 | 
            +
                          init_color wcolor_set use_default_colors newpad
         | 
| 65 | 
            +
                          unget_wch get_wch wget_wch)
         | 
| 66 | 
            +
                have_func(f) || (have_macro(f, curses) && $defs.push(format("-DHAVE_%s", f.upcase)))
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
              flag = "-D_XOPEN_SOURCE_EXTENDED"
         | 
| 69 | 
            +
              if try_static_assert("sizeof(char*)>sizeof(int)",
         | 
| 70 | 
            +
                                   %w[stdio.h stdlib.h]+curses,
         | 
| 71 | 
            +
                                   flag)
         | 
| 72 | 
            +
                $defs << flag
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
              have_var("ESCDELAY", curses)
         | 
| 75 | 
            +
              have_var("TABSIZE", curses)
         | 
| 76 | 
            +
              have_var("COLORS", curses)
         | 
| 77 | 
            +
              have_var("COLOR_PAIRS", curses)
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              # SVR4 curses has a (undocumented) variable char *curses_version.
         | 
| 80 | 
            +
              # ncurses and PDcurses has a function char *curses_version().
         | 
| 81 | 
            +
              # Note that the original BSD curses doesn't provide version information.
         | 
| 82 | 
            +
              #
         | 
| 83 | 
            +
              # configure option:
         | 
| 84 | 
            +
              #   --with-curses-version=function    for SVR4
         | 
| 85 | 
            +
              #   --with-curses-version=variable    for ncurses and PDcurses
         | 
| 86 | 
            +
              #   (not given)                       automatically determined
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              case with_curses_version = with_config("curses-version")
         | 
| 89 | 
            +
              when "function"
         | 
| 90 | 
            +
                $defs << '-DHAVE_FUNC_CURSES_VERSION'
         | 
| 91 | 
            +
              when "variable"
         | 
| 92 | 
            +
                $defs << '-DHAVE_VAR_CURSES_VERSION'
         | 
| 93 | 
            +
              when nil
         | 
| 94 | 
            +
                func_test_program = cpp_include(curses) + <<-"End"
         | 
| 95 | 
            +
                  int main(int argc, char *argv[])
         | 
| 96 | 
            +
                  {
         | 
| 97 | 
            +
                      curses_version();
         | 
| 98 | 
            +
                      return EXIT_SUCCESS;
         | 
| 99 | 
            +
                  }
         | 
| 100 | 
            +
                End
         | 
| 101 | 
            +
                var_test_program = cpp_include(curses) + <<-"End"
         | 
| 102 | 
            +
                  extern char *curses_version;
         | 
| 103 | 
            +
                  int main(int argc, char *argv[])
         | 
| 104 | 
            +
                  {
         | 
| 105 | 
            +
                      int i = 0;
         | 
| 106 | 
            +
                      for (i = 0; i < 100; i++) {
         | 
| 107 | 
            +
                          if (curses_version[i] == 0)
         | 
| 108 | 
            +
                              return 0 < i ? EXIT_SUCCESS : EXIT_FAILURE;
         | 
| 109 | 
            +
                          if (curses_version[i] & 0x80)
         | 
| 110 | 
            +
                              return EXIT_FAILURE;
         | 
| 111 | 
            +
                      }
         | 
| 112 | 
            +
                      return EXIT_FAILURE;
         | 
| 113 | 
            +
                  }
         | 
| 114 | 
            +
                End
         | 
| 115 | 
            +
                try = method(CROSS_COMPILING ? :try_link : :try_run)
         | 
| 116 | 
            +
                function_p = checking_for(checking_message('function curses_version', curses)) { try[func_test_program] }
         | 
| 117 | 
            +
                variable_p = checking_for(checking_message('variable curses_version', curses)) { try[var_test_program] }
         | 
| 118 | 
            +
                if function_p and variable_p
         | 
| 119 | 
            +
                  if [header, library].grep(/ncurses|pdcurses|xcurses/i)
         | 
| 120 | 
            +
                    variable_p = false
         | 
| 121 | 
            +
                  else
         | 
| 122 | 
            +
                    warn "found curses_version but cannot determine whether it is a"
         | 
| 123 | 
            +
                    warn "function or a variable, so assume a variable in old SVR4"
         | 
| 124 | 
            +
                    warn "ncurses."
         | 
| 125 | 
            +
                    function_p = false
         | 
| 126 | 
            +
                  end
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
                $defs << '-DHAVE_FUNC_CURSES_VERSION' if function_p
         | 
| 129 | 
            +
                $defs << '-DHAVE_VAR_CURSES_VERSION' if variable_p
         | 
| 130 | 
            +
              else
         | 
| 131 | 
            +
                warn "unexpected value for --with-curses-version: #{with_curses_version}"
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
              
         | 
| 134 | 
            +
              if RUBY_VERSION >= '2.1'
         | 
| 135 | 
            +
                create_makefile("curses")
         | 
| 136 | 
            +
              else
         | 
| 137 | 
            +
                # curses is part of ruby-core pre-2.1.0, so this gem is not required. But
         | 
| 138 | 
            +
                # make pre-2.1.0 a no-op rather than failing or listing as unsupported, to
         | 
| 139 | 
            +
                # aid gems offering multi-version Ruby support.
         | 
| 140 | 
            +
                File.open("Makefile", 'w') do |f|
         | 
| 141 | 
            +
                  f.puts dummy_makefile("curses").join
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
              end
         | 
| 144 | 
            +
            end
         | 
    
        data/lib/2.2/curses.so
    ADDED
    
    | Binary file | 
    
        data/lib/2.3/curses.so
    ADDED
    
    | Binary file | 
    
        data/lib/2.4/curses.so
    ADDED
    
    | Binary file | 
    
        data/lib/curses.rb
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            pdcurses_path = File.expand_path("../vendor/#{RUBY_PLATFORM}/PDCurses", __dir__)
         | 
| 2 | 
            +
            pdcurses_bundled = File.directory?(pdcurses_path)
         | 
| 3 | 
            +
            if pdcurses_bundled
         | 
| 4 | 
            +
              path = ENV["PATH"]
         | 
| 5 | 
            +
              dir = File::ALT_SEPARATOR ?
         | 
| 6 | 
            +
                pdcurses_path.tr("/", File::ALT_SEPARATOR) : dir
         | 
| 7 | 
            +
              dirs = path.split(File::PATH_SEPARATOR)
         | 
| 8 | 
            +
              if !dirs.include?(dir)
         | 
| 9 | 
            +
                ENV["PATH"] = [dir, *dirs].join(File::PATH_SEPARATOR)
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            begin
         | 
| 14 | 
            +
              major, minor, _ = RUBY_VERSION.split(/\./)
         | 
| 15 | 
            +
              require "#{major}.#{minor}/curses.so"
         | 
| 16 | 
            +
            rescue LoadError
         | 
| 17 | 
            +
              require "curses.so"
         | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            if pdcurses_bundled
         | 
| 21 | 
            +
              Curses.keyboard_encoding = Encoding::UTF_8
         | 
| 22 | 
            +
            end
         | 
    
        data/sample/hello.rb
    ADDED
    
    | @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "curses"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            def show_message(message)
         | 
| 6 | 
            +
              height = 5
         | 
| 7 | 
            +
              width  = message.length + 6
         | 
| 8 | 
            +
              top    = (Curses.lines - height) / 2
         | 
| 9 | 
            +
              left   = (Curses.cols - width) / 2
         | 
| 10 | 
            +
              win = Curses::Window.new(height, width, top, left)
         | 
| 11 | 
            +
              win.box("|", "-")
         | 
| 12 | 
            +
              win.setpos(2, 3)
         | 
| 13 | 
            +
              win.addstr(message)
         | 
| 14 | 
            +
              win.refresh
         | 
| 15 | 
            +
              win.getch
         | 
| 16 | 
            +
              win.close
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            Curses.init_screen
         | 
| 20 | 
            +
            begin
         | 
| 21 | 
            +
              Curses.crmode
         | 
| 22 | 
            +
              Curses.setpos((Curses.lines - 1) / 2, (Curses.cols - 11) / 2)
         | 
| 23 | 
            +
              Curses.addstr("Hit any key")
         | 
| 24 | 
            +
              Curses.refresh
         | 
| 25 | 
            +
              Curses.getch
         | 
| 26 | 
            +
              show_message("Hello, World!")
         | 
| 27 | 
            +
            ensure
         | 
| 28 | 
            +
              Curses.close_screen
         | 
| 29 | 
            +
            end
         | 
    
        data/sample/mouse.rb
    ADDED
    
    | @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "curses"
         | 
| 4 | 
            +
            include Curses
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            def show_message(*msgs)
         | 
| 7 | 
            +
              message = msgs.join
         | 
| 8 | 
            +
              height, width = 5, message.length + 6
         | 
| 9 | 
            +
              top, left = (lines - height) / 2, (cols - width) / 2
         | 
| 10 | 
            +
              win = Window.new(height, width, top, left)
         | 
| 11 | 
            +
              win.keypad = true
         | 
| 12 | 
            +
              win.attron(color_pair(COLOR_RED)) do
         | 
| 13 | 
            +
                win.box("|", "-", "+")
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              win.setpos(2, 3)
         | 
| 16 | 
            +
              win.addstr(message)
         | 
| 17 | 
            +
              win.refresh
         | 
| 18 | 
            +
              win.getch
         | 
| 19 | 
            +
              win.close
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            init_screen
         | 
| 23 | 
            +
            start_color
         | 
| 24 | 
            +
            init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_WHITE)
         | 
| 25 | 
            +
            init_pair(COLOR_RED, COLOR_RED, COLOR_WHITE)
         | 
| 26 | 
            +
            crmode
         | 
| 27 | 
            +
            noecho
         | 
| 28 | 
            +
            stdscr.keypad(true)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            begin
         | 
| 31 | 
            +
              mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)
         | 
| 32 | 
            +
              setpos((lines - 1) / 2, (cols - 5) / 2)
         | 
| 33 | 
            +
              attron(color_pair(COLOR_BLUE)|A_BOLD) do
         | 
| 34 | 
            +
                addstr("click")
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
              refresh
         | 
| 37 | 
            +
              loop do
         | 
| 38 | 
            +
                c = getch
         | 
| 39 | 
            +
                case c
         | 
| 40 | 
            +
                when KEY_MOUSE
         | 
| 41 | 
            +
                  m = getmouse
         | 
| 42 | 
            +
                  if m
         | 
| 43 | 
            +
                    show_message("getch = #{c.inspect}, ",
         | 
| 44 | 
            +
                                 "mouse event = #{'0x%x' % m.bstate}, ",
         | 
| 45 | 
            +
                                 "axis = (#{m.x},#{m.y},#{m.z})")
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                  break
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
              refresh
         | 
| 51 | 
            +
            ensure
         | 
| 52 | 
            +
              close_screen
         | 
| 53 | 
            +
            end
         | 
    
        data/sample/rain.rb
    ADDED
    
    | @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "curses"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            def onsig(signal)
         | 
| 6 | 
            +
              Curses.close_screen
         | 
| 7 | 
            +
              exit signal
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            def place_string(y, x, string)
         | 
| 11 | 
            +
              Curses.setpos(y, x)
         | 
| 12 | 
            +
              Curses.addstr(string)
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            def cycle_index(index)
         | 
| 16 | 
            +
              (index + 1) % 5
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            %w[HUP INT QUIT TERM].each do |sig|
         | 
| 20 | 
            +
              unless trap(sig, "IGNORE") == "IGNORE"  # previous handler
         | 
| 21 | 
            +
                trap(sig) {|s| onsig(s) }
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Curses.init_screen
         | 
| 26 | 
            +
            Curses.nl
         | 
| 27 | 
            +
            Curses.noecho
         | 
| 28 | 
            +
            Curses.curs_set 0
         | 
| 29 | 
            +
            srand
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            xpos, ypos = {}, {}
         | 
| 32 | 
            +
            x_range = 2..(Curses.cols - 3)
         | 
| 33 | 
            +
            y_range = 2..(Curses.lines - 3)
         | 
| 34 | 
            +
            (0..4).each do |i|
         | 
| 35 | 
            +
              xpos[i], ypos[i] = rand(x_range), rand(y_range)
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            i = 0
         | 
| 39 | 
            +
            loop do
         | 
| 40 | 
            +
              x, y = rand(x_range), rand(y_range)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              place_string(y, x, ".")
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              place_string(ypos[i], xpos[i], "o")
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              i = cycle_index(i)
         | 
| 47 | 
            +
              place_string(ypos[i], xpos[i], "O")
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              i = cycle_index(i)
         | 
| 50 | 
            +
              place_string(ypos[i] - 1, xpos[i],      "-")
         | 
| 51 | 
            +
              place_string(ypos[i],     xpos[i] - 1, "|.|")
         | 
| 52 | 
            +
              place_string(ypos[i] + 1, xpos[i],      "-")
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              i = cycle_index(i)
         | 
| 55 | 
            +
              place_string(ypos[i] - 2, xpos[i],       "-")
         | 
| 56 | 
            +
              place_string(ypos[i] - 1, xpos[i] - 1,  "/ \\")
         | 
| 57 | 
            +
              place_string(ypos[i],     xpos[i] - 2, "| O |")
         | 
| 58 | 
            +
              place_string(ypos[i] + 1, xpos[i] - 1, "\\ /")
         | 
| 59 | 
            +
              place_string(ypos[i] + 2, xpos[i],       "-")
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              i = cycle_index(i)
         | 
| 62 | 
            +
              place_string(ypos[i] - 2, xpos[i],       " ")
         | 
| 63 | 
            +
              place_string(ypos[i] - 1, xpos[i] - 1,  "   ")
         | 
| 64 | 
            +
              place_string(ypos[i],     xpos[i] - 2, "     ")
         | 
| 65 | 
            +
              place_string(ypos[i] + 1, xpos[i] - 1,  "   ")
         | 
| 66 | 
            +
              place_string(ypos[i] + 2, xpos[i],       " ")
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              xpos[i], ypos[i] = x, y
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              Curses.refresh
         | 
| 71 | 
            +
              sleep(0.5)
         | 
| 72 | 
            +
            end
         | 
    
        data/sample/view.rb
    ADDED
    
    | @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "curses"
         | 
| 4 | 
            +
            include Curses
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            unless ARGV.size == 1
         | 
| 7 | 
            +
              puts "usage: #{$0} file"
         | 
| 8 | 
            +
              exit
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            begin
         | 
| 12 | 
            +
              data_lines = File.readlines(ARGV[0])
         | 
| 13 | 
            +
            rescue
         | 
| 14 | 
            +
              raise "cannot open file: #{ARGV[0]}"
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            init_screen
         | 
| 18 | 
            +
            #keypad(stdscr, true)
         | 
| 19 | 
            +
            nonl
         | 
| 20 | 
            +
            cbreak
         | 
| 21 | 
            +
            noecho
         | 
| 22 | 
            +
            #scrollok(stdscr, true)
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            lptr = 0
         | 
| 25 | 
            +
            loop do
         | 
| 26 | 
            +
              lines.times do |i|
         | 
| 27 | 
            +
                setpos(i, 0)
         | 
| 28 | 
            +
                #clrtoeol
         | 
| 29 | 
            +
                addstr(data_lines[lptr + i] || "")
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
              refresh
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              explicit = false
         | 
| 34 | 
            +
              n = 0
         | 
| 35 | 
            +
              c = nil
         | 
| 36 | 
            +
              loop do
         | 
| 37 | 
            +
                c = getch
         | 
| 38 | 
            +
                if c =~ /[0-9]/
         | 
| 39 | 
            +
                  n = 10 * n + c.to_i
         | 
| 40 | 
            +
                  explicit = true
         | 
| 41 | 
            +
                else
         | 
| 42 | 
            +
                  break
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              n = 1 if !explicit && n == 0
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              case c
         | 
| 49 | 
            +
              when "n"  #when KEY_DOWN
         | 
| 50 | 
            +
                i = 0
         | 
| 51 | 
            +
                n.times do
         | 
| 52 | 
            +
                  if lptr + lines < data_lines.size
         | 
| 53 | 
            +
                    lptr += 1
         | 
| 54 | 
            +
                  else
         | 
| 55 | 
            +
                    break
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                  i += 1
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
                #wscrl(i)
         | 
| 60 | 
            +
              when "p"  #when KEY_UP
         | 
| 61 | 
            +
                i = 0
         | 
| 62 | 
            +
                n.times do
         | 
| 63 | 
            +
                  if lptr > 0
         | 
| 64 | 
            +
                    lptr -= 1
         | 
| 65 | 
            +
                  else
         | 
| 66 | 
            +
                    break
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  i += 1
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
                #wscrl(-i)
         | 
| 71 | 
            +
              when "q"
         | 
| 72 | 
            +
                break
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            close_screen
         | 
    
        data/sample/view2.rb
    ADDED
    
    | @@ -0,0 +1,138 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "curses"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            # A curses based file viewer.
         | 
| 7 | 
            +
            class FileViewer
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              # Create a new FileViewer and view the file.
         | 
| 10 | 
            +
              def initialize(filename)
         | 
| 11 | 
            +
                @data_lines = []
         | 
| 12 | 
            +
                @screen = nil
         | 
| 13 | 
            +
                @top = nil
         | 
| 14 | 
            +
                init_curses
         | 
| 15 | 
            +
                load_file(filename)
         | 
| 16 | 
            +
                interact
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              # Perform the curses setup.
         | 
| 20 | 
            +
              def init_curses
         | 
| 21 | 
            +
                Curses.init_screen
         | 
| 22 | 
            +
                Curses.nonl
         | 
| 23 | 
            +
                Curses.cbreak
         | 
| 24 | 
            +
                Curses.noecho
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                @screen = Curses.stdscr
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                @screen.scrollok(true)
         | 
| 29 | 
            +
                #@screen.keypad(true)
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              # Load the file into memory and
         | 
| 33 | 
            +
              # put the first part on the curses display.
         | 
| 34 | 
            +
              def load_file(filename)
         | 
| 35 | 
            +
                @data_lines = File.readlines(filename).map(&:chomp)
         | 
| 36 | 
            +
                @top = 0
         | 
| 37 | 
            +
                @data_lines[0..@screen.maxy-1].each_with_index do |line, idx|
         | 
| 38 | 
            +
                  @screen.setpos(idx, 0)
         | 
| 39 | 
            +
                  @screen.addstr(line)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                @screen.setpos(0, 0)
         | 
| 42 | 
            +
                @screen.refresh
         | 
| 43 | 
            +
              rescue
         | 
| 44 | 
            +
                raise "cannot open file '#{filename}' for reading"
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
             | 
| 48 | 
            +
              # Scroll the display up by one line.
         | 
| 49 | 
            +
              def scroll_up
         | 
| 50 | 
            +
                if @top > 0
         | 
| 51 | 
            +
                  @screen.scrl(-1)
         | 
| 52 | 
            +
                  @top -= 1
         | 
| 53 | 
            +
                  str = @data_lines[@top]
         | 
| 54 | 
            +
                  if str
         | 
| 55 | 
            +
                    @screen.setpos(0, 0)
         | 
| 56 | 
            +
                    @screen.addstr(str)
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                  return true
         | 
| 59 | 
            +
                else
         | 
| 60 | 
            +
                  return false
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              # Scroll the display down by one line.
         | 
| 65 | 
            +
              def scroll_down
         | 
| 66 | 
            +
                if @top + @screen.maxy < @data_lines.length
         | 
| 67 | 
            +
                  @screen.scrl(1)
         | 
| 68 | 
            +
                  @top += 1
         | 
| 69 | 
            +
                  str = @data_lines[@top + @screen.maxy - 1]
         | 
| 70 | 
            +
                  if str
         | 
| 71 | 
            +
                    @screen.setpos(@screen.maxy - 1, 0)
         | 
| 72 | 
            +
                    @screen.addstr(str)
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
                  return true
         | 
| 75 | 
            +
                else
         | 
| 76 | 
            +
                  return false
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              # Allow the user to interact with the display.
         | 
| 81 | 
            +
              # This uses Emacs-like keybindings, and also
         | 
| 82 | 
            +
              # vi-like keybindings as well, except that left
         | 
| 83 | 
            +
              # and right move to the beginning and end of the
         | 
| 84 | 
            +
              # file, respectively.
         | 
| 85 | 
            +
              def interact
         | 
| 86 | 
            +
                loop do
         | 
| 87 | 
            +
                  result = true
         | 
| 88 | 
            +
                  c = Curses.getch
         | 
| 89 | 
            +
                  case c
         | 
| 90 | 
            +
                  when Curses::KEY_DOWN, Curses::KEY_CTRL_N, "j"
         | 
| 91 | 
            +
                    result = scroll_down
         | 
| 92 | 
            +
                  when Curses::KEY_UP, Curses::KEY_CTRL_P, "k"
         | 
| 93 | 
            +
                    result = scroll_up
         | 
| 94 | 
            +
                  when Curses::KEY_NPAGE, " "
         | 
| 95 | 
            +
                    (@screen.maxy - 1).times do |i|
         | 
| 96 | 
            +
                      if !scroll_down && i == 0
         | 
| 97 | 
            +
                        result = false
         | 
| 98 | 
            +
                        break
         | 
| 99 | 
            +
                      end
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                  when Curses::KEY_PPAGE
         | 
| 102 | 
            +
                    (@screen.maxy - 1).times do |i|
         | 
| 103 | 
            +
                      if !scroll_up && i == 0
         | 
| 104 | 
            +
                        result = false
         | 
| 105 | 
            +
                        break
         | 
| 106 | 
            +
                      end
         | 
| 107 | 
            +
                    end
         | 
| 108 | 
            +
                  when Curses::KEY_LEFT, Curses::KEY_CTRL_T, "h"
         | 
| 109 | 
            +
                    while scroll_up
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
                  when Curses::KEY_RIGHT, Curses::KEY_CTRL_B, "l"
         | 
| 112 | 
            +
                    while scroll_down
         | 
| 113 | 
            +
                    end
         | 
| 114 | 
            +
                  when "q"
         | 
| 115 | 
            +
                    break
         | 
| 116 | 
            +
                  else
         | 
| 117 | 
            +
                    @screen.setpos(0, 0)
         | 
| 118 | 
            +
                    @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                  if !result
         | 
| 121 | 
            +
                    Curses.beep
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
                  @screen.setpos(0, 0)
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
                Curses.close_screen
         | 
| 126 | 
            +
              end
         | 
| 127 | 
            +
            end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
             | 
| 130 | 
            +
            # If we are being run as a main program...
         | 
| 131 | 
            +
            if __FILE__ == $0
         | 
| 132 | 
            +
              unless ARGV.size == 1
         | 
| 133 | 
            +
                puts "usage: #{$0} file"
         | 
| 134 | 
            +
                exit
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
              viewer = FileViewer.new(ARGV[0])
         | 
| 138 | 
            +
            end
         |