Skip to content

Commit

Permalink
Merge pull request #4441 from beetbox/exact-prefix
Browse files Browse the repository at this point in the history
Change the prefix for exact match queries
  • Loading branch information
wisp3rwind authored Aug 18, 2022
2 parents e995019 + 32ce44f commit 0ae7d66
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 11 deletions.
2 changes: 1 addition & 1 deletion beets/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -1387,7 +1387,7 @@ def parse_query_parts(parts, model_cls):
# Get query types and their prefix characters.
prefixes = {
':': dbcore.query.RegexpQuery,
'~': dbcore.query.StringQuery,
'=~': dbcore.query.StringQuery,
'=': dbcore.query.MatchQuery,
}
prefixes.update(plugins.queries())
Expand Down
4 changes: 3 additions & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ New features:
* :doc:`/plugins/kodiupdate`: Now supports multiple kodi instances
:bug:`4101`
* Add the item fields ``bitrate_mode``, ``encoder_info`` and ``encoder_settings``.
* Add query prefixes ``=`` and ``~``.
* Add :ref:`exact match <exact-match>` queries, using the prefixes ``=`` and
``=~``.
:bug:`4251`
* :doc:`/plugins/discogs`: Permit appending style to genre
* :doc:`/plugins/convert`: Add a new `auto_keep` option that automatically
converts files but keeps the *originals* in the library.
Expand Down
14 changes: 8 additions & 6 deletions docs/reference/query.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,17 @@ backslashes are not part of beets' syntax; I'm just using the escaping
functionality of my shell (bash or zsh, for instance) to pass ``the rebel`` as a
single argument instead of two.

.. _exact-match:

Exact Matches
-------------

While ordinary queries perform *substring* matches, beets can also match whole
strings by adding either ``=`` (case-sensitive) or ``~`` (ignore case) after the
field name's colon and before the expression::
strings by adding either ``=`` (case-sensitive) or ``=~`` (ignore case) after
the field name's colon and before the expression::

$ beet list artist:air
$ beet list artist:~air
$ beet list artist:=~air
$ beet list artist:=AIR

The first query is a simple substring one that returns tracks by Air, AIR, and
Expand All @@ -112,16 +114,16 @@ returns tracks by AIR only.

Exact matches may be performed on phrases as well::

$ beet list artist:~"dave matthews"
$ beet list artist:=~"dave matthews"
$ beet list artist:="Dave Matthews"

Both of these queries return tracks by Dave Matthews, but not by Dave Matthews
Band.

To search for exact matches across *all* fields, just prefix the expression with
a single ``=`` or ``~``::
a single ``=`` or ``=~``::

$ beet list ~crash
$ beet list =~crash
$ beet list ="American Football"

.. _regex:
Expand Down
6 changes: 3 additions & 3 deletions test/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def test_get_one_keyed_exact(self):
self.assert_items_matched(results, ['beets 4 eva'])

def test_get_one_keyed_exact_nocase(self):
q = 'genre:~"hard rock"'
q = 'genre:=~"hard rock"'
results = self.lib.items(q)
self.assert_items_matched(results, ['beets 4 eva'])

Expand All @@ -170,7 +170,7 @@ def test_get_one_unkeyed_exact(self):
self.assert_items_matched(results, ['foo bar'])

def test_get_one_unkeyed_exact_nocase(self):
q = '~"hard rock"'
q = '=~"hard rock"'
results = self.lib.items(q)
self.assert_items_matched(results, ['beets 4 eva'])

Expand Down Expand Up @@ -220,7 +220,7 @@ def test_key_case_insensitive(self):
self.assert_items_matched(results, ['beets 4 eva'])

def test_keyed_matches_exact_nocase(self):
q = 'genre:~rock'
q = 'genre:=~rock'
results = self.lib.items(q)
self.assert_items_matched(results, [
'foo bar',
Expand Down

0 comments on commit 0ae7d66

Please sign in to comment.