Module: Mailmate::CLI::Tags Private

Extended by:
Tags
Included in:
Tags
Defined in:
lib/mailmate/cli/tags.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

‘mmtags` — list user tags MailMate knows about.

Default: tags actually present on messages, counted from the ‘#flags` index (system flags like `Seen`, `$Forwarded` are excluded — only user tags). Sorted by count desc.

‘–defined`: tags MailMate has registered in Preferences → Tags (read from Tags.plist). May include tags that aren’t on any message yet.

Constant Summary collapse

TAGS_PLIST_FILENAME =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

"Tags.plist"

Instance Method Summary collapse

Instance Method Details

#defined_tag_namesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



78
79
80
81
82
83
84
85
86
# File 'lib/mailmate/cli/tags.rb', line 78

def defined_tag_names
  path = File.join(Mailmate.config.app_support_dir, TAGS_PLIST_FILENAME)
  return [] unless File.exist?(path)
  # plutil -convert json is more robust than reading binary plist directly.
  data = JSON.parse(`plutil -convert json -o - #{shellesc(path)}`)
  Array(data["tags"]).map { |t| t["displayName"] }.compact
rescue StandardError
  []
end

#emit_definedObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

—- tags defined in Preferences (Tags.plist) ————————–



74
75
76
# File 'lib/mailmate/cli/tags.rb', line 74

def emit_defined
  defined_tag_names.each { |name| $stdout.puts name }
end

#emit_usedObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

—- tags in use (#flags index) —————————————-



47
48
49
50
51
52
53
54
55
# File 'lib/mailmate/cli/tags.rb', line 47

def emit_used
  counts = used_tag_counts
  width  = counts.keys.map(&:length).max || 3
  width  = [width, "tag".length].max
  $stdout.puts "#{"tag".ljust(width)}  count"
  counts.sort_by { |tag, n| [-n, tag] }.each do |tag, n|
    $stdout.puts "#{tag.ljust(width)}  #{n}"
  end
end

#parse_options(argv) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/mailmate/cli/tags.rb', line 32

def parse_options(argv)
  opts = { defined: false }
  OptionParser.new do |o|
    o.banner = "Usage: mmtags [--defined]"
    o.separator ""
    o.separator "Default: tags actually applied to messages, with usage counts"
    o.separator "(read from MailMate's #flags index; system flags excluded)."
    o.separator ""
    o.on("--defined", "List tags defined in MailMate Preferences → Tags") { opts[:defined] = true }
  end.parse!(argv)
  opts
end

#run(argv) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



22
23
24
25
26
27
28
29
30
# File 'lib/mailmate/cli/tags.rb', line 22

def run(argv)
  opts = parse_options(argv)
  if opts[:defined]
    emit_defined
  else
    emit_used
  end
  0
end

#shellesc(s) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



88
89
90
# File 'lib/mailmate/cli/tags.rb', line 88

def shellesc(s)
  "'#{s.gsub("'", "'\\\\''")}'"
end

#used_tag_countsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/mailmate/cli/tags.rb', line 57

def used_tag_counts
  counts = Hash.new(0)
  Mailmate::IndexReader.for("#flags").each_record do |_eml_id, raw|
    next if raw.nil? || raw.empty?
    raw.split.each do |token|
      next if token.start_with?("\\", "$") # IMAP/Thunderbird system flags
      counts[token] += 1
    end
  end
  counts
rescue ArgumentError
  # #flags index not available — fail gracefully (returns no tags).
  {}
end