In-place progress output in the terminal or console

后端 未结 5 427
我寻月下人不归
我寻月下人不归 2020-12-13 09:39

When you run git clone, it updates progress in place. For example, the percentage of the objects received changes in place.

user@athena:~/cloj/s         


        
相关标签:
5条回答
  • 2020-12-13 09:45

    There are a number of curses librbaries for Ruby. I believe rbbcurse is the most maintained.

    0 讨论(0)
  • 2020-12-13 09:54

    git/progress.c

    ...
            eol = done ? done : "   \r";
    ...
                    fprintf(stderr, "...%s", ..., eol);
                    fflush(stderr);
    

    Git simply emits a carriage return and no line feed, which the terminal interprets as "move to first column".

    0 讨论(0)
  • 2020-12-13 09:56

    You'll have to use another method (like Curses) to update two lines in-place.

    ablogaboutcode.com | web.archive.org

    ...and...

    http://www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses.html

    0 讨论(0)
  • 2020-12-13 09:58

    I wrote little class for multiline output update:

    class ConsoleReset
      # Unix
      # Contains a string to clear the line in the shell
      CLR = "\e[0K"
      # ANSI escape sequence for hiding terminal cursor
      ESC_CURS_INVIS = "\e[?25l"
      # ANSI escape sequence for showing terminal cursor
      ESC_CURS_VIS   = "\e[?25h"
      # ANSI escape sequence for clearing line in terminal
      ESC_R_AND_CLR  = "\r#{CLR}"
      # ANSI escape sequence for going up a line in terminal
      ESC_UP_A_LINE = "\e[1A"
    
      def initialize
        @first_call = true
      end
    
      def reset_line(text = '')
        # Initialise ANSI escape string
        escape = ""
    
        # The number of lines the previous message spanned
        lines = text.strip.lines.count - 1
    
        # Clear and go up a line
        lines.times { escape += "#{ESC_R_AND_CLR}#{ESC_UP_A_LINE}" }
    
        # Clear the line that is to be printed on
        # escape += "#{ESC_R_AND_CLR}"
    
        # Console is clear, we can print!
        STDOUT.print escape if !@first_call
        @first_call = false
        print text
      end
    
      def hide_cursor
        STDOUT.print(ESC_CURS_INVIS)
      end
    
      def show_cursor
        STDOUT.print(ESC_CURS_VIS)
      end
    
      def test
        hide_cursor
    
        5.times do |i|
          line = ['===========================================']
          (1..10).each do |num|
            line << ["#{num}:\t#{rand_num}"]
          end
          line << ['===========================================']
          line = line.join("\n")
          reset_line(line)
          sleep 1
        end
    
        show_cursor
    
        puts ''
      end
    
      private
        def rand_num
          rand(10 ** rand(10))
        end
    end
    

    Inspired by prydonius/spinning_cursor. See test method for example usage.

    0 讨论(0)
  • 2020-12-13 10:08

    Use carriage return. '\r' should usually work.

    0 讨论(0)
提交回复
热议问题