diff --git a/ChangeLog b/ChangeLog index c7cb1796c..7184046c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -118,6 +118,7 @@ - TW-1648 Typo in Documentation (thanks to Simon W. Jackson). - TW-1651 Provide opt-out of filter parser's id treatment (thanks to Daniel Shahaf). +- TW-1652 task rm misparsed (thanks to Daniel Shahaf). - Prevent potential task duplication during import for non-pending tasks. - Show the active context in "context list", if any is active. - Fix "task edit" dropping annotation text after newlines. diff --git a/NEWS b/NEWS index 933b2241f..c053ad9bf 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,7 @@ Removed features in 2.4.5 forms all contain sequences of digits that make the identification of IDs, UUIDs, and various date/time formats problematic. - Comma-separated UUID lists are no longer supported. + - DOM references may no longer be abbreviated. Known Issues diff --git a/src/CLI2.cpp b/src/CLI2.cpp index 1b9d55b6e..5faa78ca3 100644 --- a/src/CLI2.cpp +++ b/src/CLI2.cpp @@ -854,11 +854,11 @@ void CLI2::aliasExpansion () } else if (_aliases.find (raw) != _aliases.end ()) { - for (auto& l : Lexer::split (_aliases[raw])) - { - A2 a (l, Lexer::Type::word); - reconstructed.push_back (a); - } + std::string lexeme; + Lexer::Type type; + Lexer lex (_aliases[raw]); + while (lex.token (lexeme, type)) + reconstructed.push_back (A2 (lexeme, type)); action = true; changes = true; @@ -884,8 +884,11 @@ void CLI2::aliasExpansion () } else if (_aliases.find (i) != _aliases.end ()) { - for (auto& l : Lexer::split (_aliases[i])) - reconstructedOriginals.push_back (l); + std::string lexeme; + Lexer::Type type; + Lexer lex (_aliases[i]); + while (lex.token (lexeme, type)) + reconstructedOriginals.push_back (lexeme); action = true; changes = true; diff --git a/src/Lexer.cpp b/src/Lexer.cpp index 7212d369c..4ed409292 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -1115,7 +1115,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) std::size_t checkpoint = _cursor; // [prefix]tags. - if (isLiteral ("tags", true, false) && + if (isLiteral ("tags", false, false) && isLiteral (".", false, false) && isWord (partialToken, partialType)) { @@ -1127,7 +1127,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) _cursor = checkpoint; // [prefix]attribute - if (isOneOf (attributes, true, true)) + if (isOneOf (attributes, false, true)) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::dom; @@ -1135,7 +1135,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) } // [prefix]attribute. - if (isOneOf (attributes, true, false)) + if (isOneOf (attributes, false, false)) { if (isLiteral (".", false, false)) { @@ -1146,7 +1146,7 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) isOneOf ({"year", "month", "day", "week", "weekday", "julian", - "hour", "minute", "second"}, true, true)) + "hour", "minute", "second"}, false, true)) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::dom; @@ -1171,24 +1171,24 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) { if (isLiteral (".", false, false)) { - if (isLiteral ("description", true, true)) + if (isLiteral ("description", false, true)) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::dom; return true; } - else if (isLiteral ("entry", true, true)) + else if (isLiteral ("entry", false, true)) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::dom; return true; } - else if (isLiteral ("entry", true, false) && + else if (isLiteral ("entry", false, false) && isLiteral (".", false, false) && isOneOf ({"year", "month", "day", "week", "weekday", "julian", - "hour", "minute", "second"}, true, true)) + "hour", "minute", "second"}, false, true)) { token = _text.substr (marker, _cursor - marker); type = Lexer::Type::dom; diff --git a/test/alias.t b/test/alias.t index 34c9fdb42..98039f3ef 100755 --- a/test/alias.t +++ b/test/alias.t @@ -142,6 +142,20 @@ class TestAliasesCommand(TestCase): code, out, err = self.t("_aliases") self.assertIn("foo", out) +class TestBug1652(TestCase): + def setUp(self): + """Executed before each test in the class""" + self.t = Task() + self.t("add one") + + def test_odd_alias(self): + """Verify that 'delete' is not lexed further""" + self.t.config("alias.rm", "delete") + self.t.config("confirmation", "off") + code, out, err = self.t("1 rm") + self.assertIn("Deleted 1 task.", out) + self.assertNotIn("No matches.", out) + if __name__ == "__main__": from simpletap import TAPTestRunner