]> git.cworth.org Git - sup/blobdiff - lib/sup/buffer.rb
Merge branch 'master' into next
[sup] / lib / sup / buffer.rb
index 6f0acf9852ea51d4b45125d035476051ed42d2f4..67ccd86ea533f15e0706233314ebcdd21188af7e 100644 (file)
@@ -28,10 +28,12 @@ module Ncurses
   ## magically, this stuff seems to work now. i could swear it didn't
   ## before. hm.
   def nonblocking_getch
-    if IO.select([$stdin], nil, nil, 1)
-      Ncurses.getch
-    else
-      nil
+    ## INSANTIY
+    ## it is NECESSARY to wrap Ncurses.getch in a select() otherwise all
+    ## background threads will be BLOCKED. (except in very modern versions
+    ## of libncurses-ruby. the current one on ubuntu seems to work well.)
+    if IO.select([$stdin], nil, nil, 0.5)
+      c = Ncurses.getch
     end
   end
 
@@ -108,10 +110,16 @@ class Buffer
 
     @w.attrset Colormap.color_for(opts[:color] || :none, opts[:highlight])
     s ||= ""
-    maxl = @width - x
-    @w.mvaddstr y, x, s[0 ... maxl]
-    unless s.length >= maxl || opts[:no_fill]
-      @w.mvaddstr(y, x + s.length, " " * (maxl - s.length))
+    maxl = @width - x # maximum display width width
+    stringl = maxl    # string "length"
+    ## the next horribleness is thanks to ruby's lack of widechar support
+    stringl += 1 while stringl < s.length && s[0 ... stringl].display_length < maxl
+    @w.mvaddstr y, x, s[0 ... stringl]
+    unless opts[:no_fill]
+      l = s.display_length
+      unless l >= maxl
+        @w.mvaddstr(y, x + l, " " * (maxl - l))
+      end
     end
   end
 
@@ -190,10 +198,13 @@ EOS
     @flash = nil
     @shelled = @asking = false
     @in_x = ENV["TERM"] =~ /(xterm|rxvt|screen)/
-
-    self.class.i_am_the_instance self
+    @sigwinch_happened = false
+    @sigwinch_mutex = Mutex.new
   end
 
+  def sigwinch_happened!; @sigwinch_mutex.synchronize { @sigwinch_happened = true } end
+  def sigwinch_happened?; @sigwinch_mutex.synchronize { @sigwinch_happened } end
+
   def buffers; @name_map.to_a; end
 
   def focus_on buf
@@ -224,14 +235,20 @@ EOS
   ## have to change this. but it's not clear that we will ever actually
   ## do that.
   def roll_buffers
-    @buffers.last.force_to_top = false
-    raise_to_front @buffers.first
+    bufs = rollable_buffers
+    bufs.last.force_to_top = false
+    raise_to_front bufs.first
   end
 
   def roll_buffers_backwards
-    return unless @buffers.length > 1
-    @buffers.last.force_to_top = false
-    raise_to_front @buffers[@buffers.length - 2]
+    bufs = rollable_buffers
+    return unless bufs.length > 1
+    bufs.last.force_to_top = false
+    raise_to_front bufs[bufs.length - 2]
+  end
+
+  def rollable_buffers
+    @buffers.select { |b| !b.system? || @buffers.last == b }
   end
 
   def handle_input c
@@ -255,6 +272,14 @@ EOS
   def completely_redraw_screen
     return if @shelled
 
+    ## this magic makes Ncurses get the new size of the screen
+    Ncurses.endwin
+    Ncurses.stdscr.keypad 1
+    Ncurses.curs_set 0
+    Ncurses.refresh
+    @sigwinch_mutex.synchronize { @sigwinch_happened = false }
+    debug "new screen size is #{Ncurses.rows} x #{Ncurses.cols}"
+
     status, title = get_status_and_title(@focus_buf) # must be called outside of the ncurses lock
 
     Ncurses.sync do
@@ -462,7 +487,7 @@ EOS
     end
 
     if answer
-      answer = 
+      answer =
         if answer.empty?
           spawn_modal "file browser", FileBrowserMode.new
         elsif File.directory?(answer)
@@ -478,7 +503,7 @@ EOS
   ## returns an array of labels
   def ask_for_labels domain, question, default_labels, forbidden_labels=[]
     default_labels = default_labels - forbidden_labels - LabelManager::RESERVED_LABELS
-    default = default_labels.join(" ")
+    default = default_labels.to_a.join(" ")
     default += " " unless default.empty?
 
     # here I would prefer to give more control and allow all_labels instead of
@@ -489,7 +514,7 @@ EOS
 
     return unless answer
 
-    user_labels = answer.symbolistize
+    user_labels = answer.to_set_of_symbols
     user_labels.each do |l|
       if forbidden_labels.include?(l) || LabelManager::RESERVED_LABELS.include?(l)
         BufferManager.flash "'#{l}' is a reserved label!"
@@ -502,7 +527,7 @@ EOS
   def ask_for_contacts domain, question, default_contacts=[]
     default = default_contacts.map { |s| s.to_s }.join(" ")
     default += " " unless default.empty?
-    
+
     recent = Index.load_contacts(AccountManager.user_emails, :num => 10).map { |c| [c.full_address, c.email] }
     contacts = ContactManager.contacts.map { |c| [ContactManager.alias_for(c), c.full_address, c.email] }
 
@@ -717,6 +742,7 @@ EOS
     Ncurses.sync do
       Ncurses.endwin
       system command
+      Ncurses.stdscr.keypad 1
       Ncurses.refresh
       Ncurses.curs_set 0
     end