aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormms <git@sapka.me>2024-11-22 23:35:51 +0100
committermms <git@sapka.me>2024-11-22 23:37:42 +0100
commitc2623f1aa3638c988026b28f6a4131df6c61e0c6 (patch)
treec9a685d2997214bcb90f3659febc56f7ac85cbbb
parent64ab548e16fdc8fa862e2b432464f3d67f5d9db8 (diff)
feat: allow to search for thread
-rw-r--r--.rubocop_todo.yml8
-rw-r--r--lib/.chotto.rb.swpbin12288 -> 0 bytes
-rw-r--r--lib/chotto.rb5
-rw-r--r--lib/chotto/message.rb10
-rw-r--r--lib/chotto/message_thread.rb22
-rw-r--r--lib/chotto/messages.rb76
-rw-r--r--lib/chotto/ruleset.rb4
-rw-r--r--lib/chotto/token.rb12
-rw-r--r--lib/chotto/token_group.rb30
-rw-r--r--spec/.chotto_spec.rb.swpbin12288 -> 0 bytes
-rw-r--r--spec/chotto_spec.rb5
-rw-r--r--spec/lib/message_spec.rb21
-rw-r--r--spec/lib/messages_spec.rb11
-rw-r--r--spec/lib/ruleset_spec.rb5
-rw-r--r--tags107
-rw-r--r--todo.txt4
16 files changed, 251 insertions, 69 deletions
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index a1404a9..fbaf0c0 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -12,13 +12,7 @@ Style/Documentation:
Exclude:
- 'spec/**/*'
- 'test/**/*'
- - 'lib/chotto.rb'
- - 'lib/chotto/config.rb'
- - 'lib/chotto/database.rb'
- - 'lib/chotto/helpers.rb'
- - 'lib/chotto/message.rb'
- - 'lib/chotto/messages.rb'
- - 'lib/chotto/tags.rb'
+ - 'lib/**/*'
# Offense count: 2
# Configuration parameters: AllowedVariables.
diff --git a/lib/.chotto.rb.swp b/lib/.chotto.rb.swp
deleted file mode 100644
index 288ee5d..0000000
--- a/lib/.chotto.rb.swp
+++ /dev/null
Binary files differ
diff --git a/lib/chotto.rb b/lib/chotto.rb
index 62e9a0d..61f149b 100644
--- a/lib/chotto.rb
+++ b/lib/chotto.rb
@@ -9,6 +9,9 @@ require_relative 'chotto/helpers'
require_relative 'chotto/message'
require_relative 'chotto/messages'
require_relative 'chotto/ruleset'
+require_relative 'chotto/token'
+require_relative 'chotto/token_group'
+require_relative 'chotto/message_thread'
module Chotto
class << self
@@ -34,7 +37,7 @@ module Chotto
end
def rule_set(name, &block)
- @rule_sets << RuleSet.new(name, db, block)
+ @rule_sets << RuleSet.new(name, db, config.only_new, block)
end
def close_db
diff --git a/lib/chotto/message.rb b/lib/chotto/message.rb
index 282a030..cc3a134 100644
--- a/lib/chotto/message.rb
+++ b/lib/chotto/message.rb
@@ -2,11 +2,12 @@
module Chotto
class Message
+ attr_reader :message, :messages, :db
attr_accessor :tags
- attr_reader :message
- def initialize(msg:)
+ def initialize(msg:, db:)
@message = msg
+ @db = db
@tags = @message.tags
end
@@ -21,6 +22,11 @@ module Chotto
end
end
+ def thread
+ thread_id = message.thread_id
+ MessageThread.new(thread_id: thread_id, db: db)
+ end
+
private
def handle_get_header(header_name)
diff --git a/lib/chotto/message_thread.rb b/lib/chotto/message_thread.rb
new file mode 100644
index 0000000..87227cd
--- /dev/null
+++ b/lib/chotto/message_thread.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Chotto
+ class MessageThread
+ attr_reader :thread_id, :db
+
+ def initialize(thread_id:, db:)
+ @thread_id = thread_id
+ @db = db
+ end
+
+ def each
+ db.search_messages("thread:#{thread_id}").each do |msg|
+ yield(
+ Message.new(
+ msg: msg,
+ db: db
+ ))
+ end
+ end
+ end
+end
diff --git a/lib/chotto/messages.rb b/lib/chotto/messages.rb
index 0d48c72..ce2cb55 100644
--- a/lib/chotto/messages.rb
+++ b/lib/chotto/messages.rb
@@ -1,59 +1,26 @@
# frozen_string_literal: true
module Chotto
- class Messages
- AND_CONJUCTION = :and
- OR_CONJUCTION = :or
- DEFAULT_CONJUCTION = AND_CONJUCTION
- OLDEST_FIRST_ORDER = 'oldest_first'
- NEWEST_FIRST_ORDER = 'newest_first'
- DEFAULT_ORDER = OLDEST_FIRST_ORDER
-
- Token = Struct.new(:conjuction, :field, :value, :messages) do
- def to_query
- conjuction_to_use = messages.next_token_id > 1 ? conjuction : ''
- return "#{conjuction_to_use} (#{value})" if field == :direct
-
- "#{conjuction_to_use} (#{field}:#{value})"
- end
- end
-
- TokenGroup = Struct.new(:conjuction, :tokens, :messages) do
- def initialize(*)
- super
- end
+ AND_CONJUCTION = :and
+ OR_CONJUCTION = :or
+ DEFAULT_CONJUCTION = AND_CONJUCTION
+ OLDEST_FIRST_ORDER = 'oldest_first'
+ NEWEST_FIRST_ORDER = 'newest_first'
+ DEFAULT_ORDER = OLDEST_FIRST_ORDER
- def to_query
- tokens.flat_map(&:to_query).join(' ').to_s
- end
-
- def push_token(field, value)
- if value.is_a? String
- tokens.push(Token.new(conjuction, field, value, messages))
- elsif value.is_a? Array
- group = TokenGroup.new(OR_CONJUCTION, [], messages)
- value.each do |val|
- group.push_token(field, val)
- end
- tokens.push group
-
- end
- end
-
- def next_token_id
- @token_count += 1
- end
- end
-
- attr_accessor :query, :current_conjuction, :token_count, :order
+ class Messages
+ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new
attr_reader :db
- def initialize(db:)
+ include Enumerable
+
+ def initialize(db:, only_new:)
@db = db
- @query = []
@current_conjuction = AND_CONJUCTION
@token_count = 0
@order = DEFAULT_ORDER
+ @only_new = only_new
+ clear_filter!
end
def or
@@ -77,6 +44,10 @@ module Chotto
self
end
+ def clear_filter!
+ @query = []
+ end
+
def newest_first
@order = NEWEST_FIRST_ORDER
@@ -91,7 +62,11 @@ module Chotto
def each
db.search_messages(query_string).each do |msg|
- yield(Message.new(msg: msg))
+ yield(
+ Message.new(
+ msg: msg,
+ db: db
+ ))
end
end
@@ -108,7 +83,12 @@ module Chotto
end
def query_string
- query.map(&:to_query).join(' ')
+ string_from_filters = query.map(&:to_query).join(' ')
+ if only_new
+ "tag:new AND (#{string_from_filters})"
+ else
+ string_from_filters
+ end
end
def next_token_id
diff --git a/lib/chotto/ruleset.rb b/lib/chotto/ruleset.rb
index 08c9dbd..b76da1e 100644
--- a/lib/chotto/ruleset.rb
+++ b/lib/chotto/ruleset.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module Chotto
- RuleSet = Struct.new(:name, :db, :rule) do
+ RuleSet = Struct.new(:name, :db, :only_new, :rule) do
def messages
- Messages.new(db: db)
+ Messages.new(db: db, only_new: only_new)
end
def run
diff --git a/lib/chotto/token.rb b/lib/chotto/token.rb
new file mode 100644
index 0000000..fe46877
--- /dev/null
+++ b/lib/chotto/token.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Chotto
+ Token = Struct.new(:conjuction, :field, :value, :messages) do
+ def to_query
+ conjuction_to_use = messages.next_token_id > 1 ? conjuction : ''
+ return "#{conjuction_to_use} (#{value})" if field == :direct
+
+ "#{conjuction_to_use} (#{field}:#{value})"
+ end
+ end
+end
diff --git a/lib/chotto/token_group.rb b/lib/chotto/token_group.rb
new file mode 100644
index 0000000..7f8085e
--- /dev/null
+++ b/lib/chotto/token_group.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Chotto
+ TokenGroup = Struct.new(:conjuction, :tokens, :messages) do
+ def initialize(*)
+ super
+ end
+
+ def to_query
+ tokens.flat_map(&:to_query).join(' ').to_s
+ end
+
+ def push_token(field, value)
+ if value.is_a? String
+ tokens.push(Token.new(conjuction, field, value, messages))
+ elsif value.is_a? Array
+ group = TokenGroup.new(OR_CONJUCTION, [], messages)
+ value.each do |val|
+ group.push_token(field, val)
+ end
+ tokens.push group
+
+ end
+ end
+
+ def next_token_id
+ @token_count += 1
+ end
+ end
+end
diff --git a/spec/.chotto_spec.rb.swp b/spec/.chotto_spec.rb.swp
deleted file mode 100644
index f54f5fd..0000000
--- a/spec/.chotto_spec.rb.swp
+++ /dev/null
Binary files differ
diff --git a/spec/chotto_spec.rb b/spec/chotto_spec.rb
index 41d949c..7593a48 100644
--- a/spec/chotto_spec.rb
+++ b/spec/chotto_spec.rb
@@ -12,7 +12,6 @@ describe Chotto do
before do
$db_double = db_double # we need to access this double within block evaled elsewhere
- p $db_double
allow(db_double).to receive(:new).with('/path', mode: Notmuch::MODE_READ_WRITE).and_return(db_instance_double)
allow(db_instance_double).to receive(:query).with(' (from:baltar@galactica.com)').and_return(db_query_double)
@@ -36,7 +35,7 @@ describe Chotto do
end
it 'sends the rules to Notmuch - scenario 1' do
- expect(message_double).to receive(:tags).and_return([])
+ expect(message_double).to receive(:tags)
expect(message_double).to receive(:header).with('Subject').and_return('Number Six')
expect(message_double).to receive(:remove_all_tags)
expect(message_double).to receive(:add_tag).with('todo')
@@ -46,7 +45,7 @@ describe Chotto do
end
it 'sends the rules to Notmuch - scenario 2' do
- expect(message_double).to receive(:tags).and_return([])
+ expect(message_double).to receive(:tags)
expect(message_double).to receive(:header).with('Subject').and_return('Boomer')
expect(message_double).to receive(:remove_all_tags)
expect(message_double).to receive(:add_tag).with('spam')
diff --git a/spec/lib/message_spec.rb b/spec/lib/message_spec.rb
index 2605117..8994216 100644
--- a/spec/lib/message_spec.rb
+++ b/spec/lib/message_spec.rb
@@ -7,8 +7,9 @@ require_relative '../../lib/chotto/helpers'
RSpec.describe Chotto::Message do
let(:tags) { [] }
let(:msg) { double('Notmuch::Message', tags: tags) }
+ let(:db_double) { double('Chotto::Database') }
- let(:subject) { Chotto::Message.new(msg: msg) }
+ let(:subject) { Chotto::Message.new(msg: msg, db: db_double) }
it 'reads headers' do
expect(msg).to receive(:header).with('A-Header')
@@ -43,4 +44,22 @@ RSpec.describe Chotto::Message do
subject.save!
end
end
+
+ describe 'thread' do
+ let(:thread_id) { '1' }
+ let(:tester) { double }
+ let(:msg_in_thread) { double('Chotto:Message') }
+
+ it 'fetches messages for thread' do
+ expect(msg).to receive(:thread_id).and_return(thread_id)
+ expect(db_double).to receive(:search_messages).with("thread:#{thread_id}").and_return([msg_in_thread])
+ expect(msg_in_thread).to receive(:tags)
+
+ expect(tester).to receive(:test).with(an_instance_of(Chotto::Message))
+
+ subject.thread.each do |msg|
+ tester.test(msg)
+ end
+ end
+ end
end
diff --git a/spec/lib/messages_spec.rb b/spec/lib/messages_spec.rb
index 79551b7..4abc2c6 100644
--- a/spec/lib/messages_spec.rb
+++ b/spec/lib/messages_spec.rb
@@ -4,7 +4,7 @@ require 'rspec'
require_relative '../../lib/chotto/messages'
RSpec.describe Chotto::Messages do
- let(:subject) { Chotto::Messages.new(db: double('Notmuch')) }
+ let(:subject) { Chotto::Messages.new(db: double('Notmuch'), only_new: false) }
describe 'direct filters' do
it { expect(subject.filter('from:baltar@battlestar.com').query_string).to eq(' (from:baltar@battlestar.com)') }
@@ -74,4 +74,13 @@ RSpec.describe Chotto::Messages do
it { expect(subject.filter('from:baltar@battlestar.com').newest_first.order).to eq('newest_first') }
it { expect(subject.filter('from:baltar@battlestar.com').newest_first.oldest_first.order).to eq('oldest_first') }
end
+
+ context 'with only_new' do
+ let(:subject) { Chotto::Messages.new(db: double('Notmuch'), only_new: true) }
+
+ it 'prepends the filter with tag:new' do
+ expect(subject.filter('from:baltar@battlestar.com').query_string)
+ .to eq('tag:new AND ( (from:baltar@battlestar.com))')
+ end
+ end
end
diff --git a/spec/lib/ruleset_spec.rb b/spec/lib/ruleset_spec.rb
index e7a6904..7b77e3e 100644
--- a/spec/lib/ruleset_spec.rb
+++ b/spec/lib/ruleset_spec.rb
@@ -7,18 +7,19 @@ require_relative '../../lib/chotto/messages'
RSpec.describe Chotto::RuleSet do
let(:db) { instance_double('Chotto::Database') }
let(:messages) { double('Chotto::Messages', mth: true) }
+ let(:only_new) { true }
let(:rule) do
proc do
messages.mth
end
end
let(:subject) do
- Chotto::RuleSet.new('a name', db, rule)
+ Chotto::RuleSet.new('a name', db, only_new, rule)
end
describe '#run' do
it 'evaluates the run block' do
- expect(Chotto::Messages).to receive(:new).with(db: db).and_return(messages)
+ expect(Chotto::Messages).to receive(:new).with(db: db, only_new: true).and_return(messages)
expect(messages).to receive(:mth)
subject.run
diff --git a/tags b/tags
new file mode 100644
index 0000000..e9732b7
--- /dev/null
+++ b/tags
@@ -0,0 +1,107 @@
+!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/
+!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/
+!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/
+!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/
+!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/
+!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/
+!_TAG_FIELD_DESCRIPTION input /input file/
+!_TAG_FIELD_DESCRIPTION name /tag name/
+!_TAG_FIELD_DESCRIPTION pattern /pattern/
+!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/
+!_TAG_FIELD_DESCRIPTION!Ruby mixin /how the class or module is mixed in (mixin:HOW:MODULE)/
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_KIND_DESCRIPTION!Ruby A,accessor /accessors/
+!_TAG_KIND_DESCRIPTION!Ruby C,constant /constants/
+!_TAG_KIND_DESCRIPTION!Ruby L,library /libraries/
+!_TAG_KIND_DESCRIPTION!Ruby S,singletonMethod /singleton methods/
+!_TAG_KIND_DESCRIPTION!Ruby a,alias /aliases/
+!_TAG_KIND_DESCRIPTION!Ruby c,class /classes/
+!_TAG_KIND_DESCRIPTION!Ruby f,method /methods/
+!_TAG_KIND_DESCRIPTION!Ruby m,module /modules/
+!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/
+!_TAG_OUTPUT_FILESEP slash /slash or backslash/
+!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
+!_TAG_OUTPUT_VERSION 0.0 /current.age/
+!_TAG_PARSER_VERSION!Ruby 0.0 /current.age/
+!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/
+!_TAG_PROC_CWD /home/mms/ghq/git.sr.ht/~mms/some/ //
+!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
+!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
+!_TAG_PROGRAM_URL https://ctags.io/ /official site/
+!_TAG_PROGRAM_VERSION 6.1.0 //
+!_TAG_ROLE_DESCRIPTION!Ruby!library loaded /loaded by "load" method/
+!_TAG_ROLE_DESCRIPTION!Ruby!library required /loaded by "require" method/
+!_TAG_ROLE_DESCRIPTION!Ruby!library requiredRel /loaded by "require_relative" method/
+AND_CONJUCTION ./lib/chotto/messages.rb /^ AND_CONJUCTION = :and$/;" C module:Chotto
+Chotto ./lib/chotto.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/config.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/database.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/helpers.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/message.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/messages.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/ruleset.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/token.rb /^module Chotto$/;" m
+Chotto ./lib/chotto/token_group.rb /^module Chotto$/;" m
+Config ./lib/chotto/config.rb /^ Config = Struct.new(:database_path, :db_class, :only_new)$/;" C module:Chotto
+DEFAULT_CONJUCTION ./lib/chotto/messages.rb /^ DEFAULT_CONJUCTION = AND_CONJUCTION$/;" C module:Chotto
+DEFAULT_ORDER ./lib/chotto/messages.rb /^ DEFAULT_ORDER = OLDEST_FIRST_ORDER$/;" C module:Chotto
+Database ./lib/chotto/database.rb /^ class Database$/;" c module:Chotto
+Helpers ./lib/chotto/helpers.rb /^ module Helpers$/;" m module:Chotto
+Message ./lib/chotto/message.rb /^ class Message$/;" c module:Chotto
+Messages ./lib/chotto/messages.rb /^ class Messages$/;" c module:Chotto
+NEWEST_FIRST_ORDER ./lib/chotto/messages.rb /^ NEWEST_FIRST_ORDER = 'newest_first'$/;" C module:Chotto
+OLDEST_FIRST_ORDER ./lib/chotto/messages.rb /^ OLDEST_FIRST_ORDER = 'oldest_first'$/;" C module:Chotto
+OR_CONJUCTION ./lib/chotto/messages.rb /^ OR_CONJUCTION = :or$/;" C module:Chotto
+RuleSet ./lib/chotto/ruleset.rb /^ RuleSet = Struct.new(:name, :db, :only_new, :rule) do$/;" C module:Chotto
+Token ./lib/chotto/token.rb /^ Token = Struct.new(:conjuction, :field, :value, :messages) do$/;" C module:Chotto
+TokenGroup ./lib/chotto/token_group.rb /^ TokenGroup = Struct.new(:conjuction, :tokens, :messages) do$/;" C module:Chotto
+add_filter_from_hash ./lib/chotto/messages.rb /^ def add_filter_from_hash(hash)$/;" f class:Chotto.Messages
+add_filter_from_string ./lib/chotto/messages.rb /^ def add_filter_from_string(string)$/;" f class:Chotto.Messages
+and ./lib/chotto/messages.rb /^ def and$/;" f class:Chotto.Messages
+close ./lib/chotto/database.rb /^ def close$/;" f class:Chotto.Database
+close_db ./lib/chotto.rb /^ def close_db$/;" S module:Chotto
+config ./lib/chotto.rb /^ attr_reader :rule_sets, :config$/;" A module:Chotto
+configure ./lib/chotto.rb /^ def configure(&block)$/;" S module:Chotto
+current_conjuction ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+current_conjuction= ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+db ./lib/chotto.rb /^ def db$/;" S module:Chotto
+db ./lib/chotto/database.rb /^ attr_reader :db$/;" A class:Chotto.Database
+db ./lib/chotto/messages.rb /^ attr_reader :db$/;" A class:Chotto.Messages
+each ./lib/chotto/messages.rb /^ def each$/;" f class:Chotto.Messages
+eval_rules ./lib/chotto.rb /^def eval_rules(options = {})$/;" f
+filter ./lib/chotto/messages.rb /^ def filter(params)$/;" f class:Chotto.Messages
+force_fresh_config ./lib/chotto.rb /^ def force_fresh_config$/;" S module:Chotto
+handle_get_header ./lib/chotto/message.rb /^ def handle_get_header(header_name)$/;" f class:Chotto.Message
+header_name_from_dsl ./lib/chotto/helpers.rb /^ def self.header_name_from_dsl(method_name)$/;" S module:Chotto.Helpers
+initialize ./lib/chotto/database.rb /^ def initialize(path:, db_class:)$/;" f class:Chotto.Database
+initialize ./lib/chotto/message.rb /^ def initialize(msg:)$/;" f class:Chotto.Message
+initialize ./lib/chotto/messages.rb /^ def initialize(db:, only_new:)$/;" f class:Chotto.Messages
+initialize ./lib/chotto/token_group.rb /^ def initialize(*)$/;" S module:Chotto
+message ./lib/chotto/message.rb /^ attr_reader :message$/;" A class:Chotto.Message
+messages ./lib/chotto/ruleset.rb /^ def messages$/;" S module:Chotto
+method_missing ./lib/chotto/message.rb /^ def method_missing(method_name, *_args)$/;" f class:Chotto.Message
+newest_first ./lib/chotto/messages.rb /^ def newest_first$/;" f class:Chotto.Messages
+next_token_id ./lib/chotto/messages.rb /^ def next_token_id$/;" f class:Chotto.Messages
+next_token_id ./lib/chotto/token_group.rb /^ def next_token_id$/;" S module:Chotto
+oldest_first ./lib/chotto/messages.rb /^ def oldest_first$/;" f class:Chotto.Messages
+only_new ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+only_new= ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+or ./lib/chotto/messages.rb /^ def or$/;" f class:Chotto.Messages
+order ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+order= ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+push_token ./lib/chotto/token_group.rb /^ def push_token(field, value)$/;" S module:Chotto
+query ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+query= ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+query_string ./lib/chotto/messages.rb /^ def query_string$/;" f class:Chotto.Messages
+rule_set ./lib/chotto.rb /^ def rule_set(name, &block)$/;" S module:Chotto
+rule_sets ./lib/chotto.rb /^ attr_reader :rule_sets, :config$/;" A module:Chotto
+run ./lib/chotto/ruleset.rb /^ def run$/;" S module:Chotto
+save! ./lib/chotto/message.rb /^ def save!$/;" f class:Chotto.Message
+search_messages ./lib/chotto/database.rb /^ def search_messages(query)$/;" f class:Chotto.Database
+tags ./lib/chotto/message.rb /^ attr_accessor :tags$/;" A class:Chotto.Message
+tags= ./lib/chotto/message.rb /^ attr_accessor :tags$/;" A class:Chotto.Message
+to_query ./lib/chotto/token.rb /^ def to_query$/;" S module:Chotto
+to_query ./lib/chotto/token_group.rb /^ def to_query$/;" S module:Chotto
+token_count ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
+token_count= ./lib/chotto/messages.rb /^ attr_accessor :query, :current_conjuction, :token_count, :order, :only_new$/;" A class:Chotto.Messages
diff --git a/todo.txt b/todo.txt
index 2df882e..1d3fdfe 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,8 +1,8 @@
Task list for 0.1.0
[x] allow for selecting order of messages in filter
-[ ] add helper for searching other messages in the same thread as first
+[x] add helper for searching other messages in the same thread as first
[ ] add default filter: mailing lists
[ ] add default filter: spam
-[ ] add "--new" to bin script. Adds default "tag:new" filter
+[x] add "--new" to bin script. Adds default "tag:new" filter
[ ] add gemspec