# File lib/sup/modes/label-list-mode.rb, line 79
  def regen_text
    @text = []
    labels = LabelManager.all_labels

    counted = labels.map do |label|
      string = LabelManager.string_for label
      total = Index.num_results_for :label => label
      unread = (label == :unread)? total : Index.num_results_for(:labels => [label, :unread])
      [label, string, total, unread]
    end

    if HookManager.enabled? "label-list-filter"
      counts = HookManager.run "label-list-filter", :counted => counted
    else
      counts = counted.sort_by { |l, s, t, u| s.downcase }
    end

    width = counts.max_of { |l, s, t, u| s.length }
    tmax  = counts.max_of { |l, s, t, u| t }
    umax  = counts.max_of { |l, s, t, u| u }

    if @unread_only
      counts.delete_if { | l, s, t, u | u == 0 }
    end

    @labels = []
    counts.map do |label, string, total, unread|
      ## if we've done a search and there are no messages for this label, we can delete it from the
      ## list. BUT if it's a brand-new label, the user may not have sync'ed it to the index yet, so
      ## don't delete it in this case.
      ##
      ## this is all a hack. what should happen is:
      ##   TODO make the labelmanager responsible for label counts
      ## and then it can listen to labeled and unlabeled events, etc.
      if total == 0 && !LabelManager::RESERVED_LABELS.include?(label) && !LabelManager.new_label?(label)
        debug "no hits for label #{label}, deleting"
        LabelManager.delete label
        next
      end

      fmt = HookManager.run "label-list-format", :width => width, :tmax => tmax, :umax => umax
      if !fmt
        fmt = "%#{width + 1}s %5d %s, %5d unread"
      end

      @text << [[(unread == 0 ? :labellist_old_color : :labellist_new_color),
          sprintf(fmt, string, total, total == 1 ? " message" : "messages", unread)]]
      @labels << [label, unread]
      yield i if block_given?
    end.compact

    BufferManager.flash "No labels with unread messages!" if counts.empty? && @unread_only
  end