diff --git a/features/data/configs/deletion_filters.yaml b/features/data/configs/deletion_filters.yaml new file mode 100644 index 00000000..73a88e4d --- /dev/null +++ b/features/data/configs/deletion_filters.yaml @@ -0,0 +1,12 @@ +default_hour: 9 +default_minute: 0 +editor: "" +encrypt: false +highlight: true +journals: + default: features/journals/deletion_filters.journal +linewrap: 80 +tagsymbols: "@" +template: false +timeformat: "%Y-%m-%d %H:%M" +indent_character: "|" diff --git a/features/data/journals/deletion_filters.journal b/features/data/journals/deletion_filters.journal new file mode 100644 index 00000000..9a3747db --- /dev/null +++ b/features/data/journals/deletion_filters.journal @@ -0,0 +1,14 @@ +[2019-10-01 08:00] It's just another day in October. +Not much to write about. + +[2020-01-01 08:00] Happy New Year! +So this is the New Year. @holidays + +[2020-03-01 08:00] It's just another day in March. +A stick, a stone, it's the end of the road. + +[2020-05-01 09:00] Happy May Day! +@holidays @springtime Several holidays fall on this date. + +[2020-05-02 12:10] Writing tests. * +@springtime They will help prevent bugs. diff --git a/features/delete.feature b/features/delete.feature index 197746df..d12fe8f8 100644 --- a/features/delete.feature +++ b/features/delete.feature @@ -1,5 +1,4 @@ Feature: Delete entries from journal - @skip Scenario: --delete flag allows deletion of single entry Given we use the config "deletion.yaml" When we run "jrnl -n 1" @@ -18,3 +17,133 @@ Feature: Delete entries from journal """ 2019-10-29 11:11 Second entry. """ + + Scenario: Backing out of interactive delete does not change journal + Given we use the config "deletion.yaml" + When we run "jrnl --delete -n 1" and enter + """ + N + """ + Then the journal should have 3 entries + And the journal should contain "[2019-10-29 11:11] First entry." + And the journal should contain "[2019-10-29 11:11] Second entry." + And the journal should contain "[2019-10-29 11:13] Third entry." + + Scenario: --delete flag with nonsense input deletes nothing (issue #932) + Given we use the config "deletion.yaml" + When we run "jrnl --delete asdfasdf" + When we run "jrnl -n 1" + Then the output should contain + """ + 2019-10-29 11:13 Third entry. + """ + And the journal should have 3 entries + + Scenario: --delete flag with tag only deletes tagged entries + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete @holidays" and enter + """ + Y + Y + """ + Then the journal should have 3 entries + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should contain "[2020-05-02 12:10] Writing tests." + + Scenario: --delete flag with multiple tags deletes all entries matching any of the tags + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete @holidays @springtime" and enter + """ + Y + Y + Y + """ + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should not contain "[2020-01-01 08:00] Happy New Year!" + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should not contain "[2020-05-01 09:00] Happy May Day!" + and the journal should not contain "[2020-05-02 12:10] Writing tests. *" + and the journal should have 2 entries + + Scenario: --delete flag with -and and tags only deletes boolean AND of tagged entries + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete -and @holidays @springtime" and enter + """ + Y + """ + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should contain "[2020-01-01 08:00] Happy New Year!" + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should not contain "[2020-05-01 09:00] Happy May Day!" + and the journal should contain "[2020-05-02 12:10] Writing tests. *" + and the journal should have 4 entries + + Scenario: --delete flag with -not does not delete entries with -not tag + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete @holidays -not @springtime" and enter + """ + Y + """ + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should not contain "[2020-01-01 08:00] Happy New Year!" + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should contain "[2020-05-01 09:00] Happy May Day!" + and the journal should contain "[2020-05-02 12:10] Writing tests. *" + and the journal should have 4 entries + + Scenario: --delete flag with -from only deletes entries since a specified date + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete -from 2020-01-02" and enter + """ + Y + Y + Y + """ + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should contain "[2020-01-01 08:00] Happy New Year!" + and the journal should not contain "[2020-03-01 08:00] It's just another day in March." + and the journal should not contain "[2020-05-01 09:00] Happy May Day!" + and the journal should not contain "[2020-05-02 12:10] Writing tests." + and the journal should have 2 entries + + Scenario: --delete flag with -to only deletes entries up to specified date + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete -to 2020-01-02" and enter + """ + Y + Y + """ + Then the journal should not contain "[2019-10-01 08:00] It's just another day in October." + and the journal should not contain "[2020-01-01 08:00] Happy New Year!" + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should contain "[2020-05-01 09:00] Happy May Day!" + and the journal should contain "[2020-05-02 12:10] Writing tests." + and the journal should have 3 entries + + Scenario: --delete flag with -starred only deletes starred entries + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete -starred" and enter + """ + Y + """ + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should contain "[2020-01-01 08:00] Happy New Year!" + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should contain "[2020-05-01 09:00] Happy May Day!" + and the journal should not contain "[2020-05-02 12:10] Writing tests. *" + and the journal should have 4 entries + + Scenario: --delete flag with -contains only entries containing expression + Given we use the config "deletion_filters.yaml" + When we run "jrnl --delete -contains happy" and enter + """ + Y + Y + """ + Then the journal should contain "[2019-10-01 08:00] It's just another day in October." + and the journal should not contain "[2020-01-01 08:00] Happy New Year!" + and the journal should contain "[2020-03-01 08:00] It's just another day in March." + and the journal should not contain "[2020-05-01 09:00] Happy May Day!" + and the journal should contain "[2020-05-02 12:10] Writing tests. *" + and the journal should have 3 entries diff --git a/features/steps/core.py b/features/steps/core.py index b69edb9e..8465c4a9 100644 --- a/features/steps/core.py +++ b/features/steps/core.py @@ -257,6 +257,13 @@ def check_journal_content(context, text, journal_name="default"): assert text in journal, journal +@then('the journal should not contain "{text}"') +@then('journal "{journal_name}" should not contain "{text}"') +def check_not_journal_content(context, text, journal_name="default"): + journal = read_journal(journal_name) + assert text not in journal, journal + + @then('journal "{journal_name}" should not exist') def journal_doesnt_exist(context, journal_name="default"): with open(install.CONFIG_FILE_PATH) as config_file: diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 64b245ff..c5503392 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -234,8 +234,14 @@ class Journal: self.entries = result + def delete_entries(self, entries_to_delete): + """Deletes specific entries from a journal.""" + for entry in entries_to_delete: + self.entries.remove(entry) + def prompt_delete_entries(self): - """Prompts for deletion of entries in a journal.""" + """Prompts for deletion of each of the entries in a journal. + Returns the entries the user wishes to delete.""" to_delete = [] @@ -248,8 +254,7 @@ class Journal: if ask_delete(entry): to_delete.append(entry) - self.entries = [entry for entry in self.entries if entry not in to_delete] - self.write() + return to_delete def new_entry(self, raw, date=None, sort=True): """Constructs a new entry from some raw text input. diff --git a/jrnl/cli.py b/jrnl/cli.py index d1c88ea7..2426e17c 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -187,14 +187,12 @@ def parse_args(args=None): action="store_true", ) - # Disabling this momentarily due to critical bug - # @see https://github.com/jrnl-org/jrnl/issues/932 - # exporting.add_argument( - # "--delete", - # dest="delete", - # action="store_true", - # help="Opens an interactive interface for deleting entries.", - # ) + exporting.add_argument( + "--delete", + dest="delete", + action="store_true", + help="Opens an interactive interface for deleting entries.", + ) # Handle '-123' as a shortcut for '-n 123' num = re.compile(r"^-(\d+)$") @@ -304,9 +302,6 @@ def configure_logger(debug=False): def run(manual_args=None): args = parse_args(manual_args) - # temporary until bring back --delete - args.delete = False # TODO: remove me - configure_logger(args.debug) if args.version: version_str = f"{jrnl.__title__} version {jrnl.__version__}" @@ -341,6 +336,7 @@ def run(manual_args=None): config = util.scope_config(config, journal_name) log.debug('Using journal "%s"', journal_name) + mode_compose, mode_export, mode_import = guess_mode(args, config) # How to quit writing? @@ -484,5 +480,16 @@ def run(manual_args=None): journal.write() elif args.delete: - journal.prompt_delete_entries() - journal.write() + if journal.entries: + entries_to_delete = journal.prompt_delete_entries() + + if entries_to_delete: + journal.entries = old_entries + journal.delete_entries(entries_to_delete) + + journal.write() + else: + print( + "No entries deleted, because the search returned no results.", + file=sys.stderr, + )