Repository: fniessink/next-action

Issue:
Merge --config and --no-config options by making the config argument optional

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f38a53a..60da2e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## [Unreleased]
+
+### Removed
+
+- The `--no-config-file` option was removed. To not read any configuration file, use the `--config-file` option without specifying a configuration filename.
+
 ## [0.12.0] - 2018-05-28
 
 ### Added
diff --git a/README.md b/README.md
index 2e858c4..07408b3 100644
--- a/README.md
+++ b/README.md
@@ -15,14 +15,15 @@ Don't know what *Todo.txt* is? See <https://github.com/todotxt/todo.txt> for the
 
 ## Table of contents
 
-  - [Demo](#demo)
-  - [Installation](#installation)
-  - [Usage](#usage)
-    - [Limiting the tasks from which next actions are selected](#limiting-the-tasks-from-which-next-actions-are-selected)
-    - [Showing more than one next action](#showing-more-than-one-next-action)
-    - [Styling the output](#styling-the-output)
-    - [Configuring *Next-action*](#configuring-next-action)
-  - [Develop](#develop)
+- [Demo](#demo)
+- [Installation](#installation)
+- [Usage](#usage)
+  - [Limiting the tasks from which next actions are selected](#limiting-the-tasks-from-which-next-actions-are-selected)
+  - [Showing more than one next action](#showing-more-than-one-next-action)
+  - [Styling the output](#styling-the-output)
+  - [Configuring *Next-action*](#configuring-next-action)
+- [Develop](#develop)
+
 ## Demo
 
 ![gif](https://raw.githubusercontent.com/fniessink/next-action/master/docs/demo.gif)
@@ -37,7 +38,7 @@ Don't know what *Todo.txt* is? See <https://github.com/todotxt/todo.txt> for the
 
 ```console
 $ next-action --help
-usage: next-action [-h] [--version] [-c <config.cfg> | -C] [-f <todo.txt>] [-n <number> | -a] [-o] [-p [<priority>]]
+usage: next-action [-h] [--version] [-c [<config.cfg>]] [-f <todo.txt>] [-n <number> | -a] [-o] [-p [<priority>]]
 [<context|project> ...]
 
 Show the next action in your todo.txt. The next action is selected from the tasks in the todo.txt file based on task
@@ -48,9 +49,9 @@ optional arguments:
   -h, --help            show this help message and exit
   --version             show program's version number and exit
   --write-config-file   generate a sample configuration file and exit
-  -c <config.cfg>, --config-file <config.cfg>
-                        filename of configuration file to read (default: ~/.next-action.cfg)
-  -C, --no-config-file  don't read the configuration file
+  -c [<config.cfg>], --config-file [<config.cfg>]
+                        filename of configuration file to read (default: ~/.next-action.cfg); omit filename to not
+                        read any configuration file
   -f <todo.txt>, --file <todo.txt>
                         filename of todo.txt file to read; can be '-' to read from standard input; argument can be
                         repeated to read tasks from multiple todo.txt files (default: ~/todo.txt)
@@ -175,13 +176,15 @@ style: default
 
 To make this the configuration that *Next-action* reads by default, redirect the output to `~/.next-action.cfg` like this: `next-action --write-config-file > ~/.next-action.cfg`.
 
-If you want to use a configuration file that is not in the default location (`~/.next-action.cfg`), you'll need to explicitly tell *Next-action* its location:
+If you want to use a configuration file that is not in the default location (`~/.next-action.cfg`), you'll need to explicitly specify its location:
 
 ```console
 $ next-action --config-file docs/.next-action.cfg
 (A) Call mom @phone
 ```
 
+To skip reading the default configuration file, and also not read an alternative configuration file, use the `--config-file` option without arguments.
+
 The configuration file format is [YAML](http://yaml.org). The options currently supported are which todo.txt files must be read, how many next actions should be shown, and the styling.
 
 #### Configuring a default todo.txt
@@ -253,7 +256,7 @@ To run the unit tests:
 $ python -m unittest
 ...............................................................................................................................................
 ----------------------------------------------------------------------
-Ran 143 tests in 0.461s
+Ran 143 tests in 0.420s
 
 OK
 ```
diff --git a/docs/update_readme.py b/docs/update_readme.py
index 86a3553..3c77201 100644
--- a/docs/update_readme.py
+++ b/docs/update_readme.py
@@ -21,7 +21,7 @@ def create_toc(lines, toc_header, min_level=2, max_level=3):
         level = line.count("#", 0, 6)
         if level < min_level or level > max_level or line.startswith(toc_header):
             continue
-        indent = (level - 1) * 2
+        indent = (level - min_level) * 2
         title = line.split(" ", 1)[1].rstrip()
         slug = title.lower().replace(" ", "-").replace("*", "").replace(".", "")
         result.append("{0}- [{1}](#{2})".format(" " * indent, title, slug))
@@ -68,17 +68,16 @@ class StateMachine(object):
     def print_toc(self, line):
         """ Print the table of contents. """
         print(self.toc)
-        if line.startswith("  "):
+        if "- [" in line:
             return self.in_old_toc
         print(line)
         return self.default
 
     def in_old_toc(self, line):
         """ Skip the old table of contents. """
-        if line.startswith("  "):
+        if "- [" in line:
             return self.in_old_toc
-        if line:
-            print(line)
+        print(line)
         return self.default
 
 
diff --git a/next_action/arguments/parser.py b/next_action/arguments/parser.py
index fec3e3a..52dc719 100644
--- a/next_action/arguments/parser.py
+++ b/next_action/arguments/parser.py
@@ -22,7 +22,7 @@ class NextActionArgumentParser(argparse.ArgumentParser):
                         "todo.txt file based on task properties such as priority, due date, and creation date. Limit "
                         "the tasks from which the next action is selected by specifying contexts the tasks must have "
                         "and/or projects the tasks must belong to.",
-            usage=textwrap.fill("next-action [-h] [--version] [-c <config.cfg> | -C] [-f <todo.txt>] "
+            usage=textwrap.fill("next-action [-h] [--version] [-c [<config.cfg>]] [-f <todo.txt>] "
                                 "[-n <number> | -a] [-o] [-p [<priority>]] [<context|project> ...]",
                                 width=shutil.get_terminal_size().columns - len("usage: ")))
         self.__default_filenames = ["~/todo.txt"]
@@ -37,10 +37,9 @@ class NextActionArgumentParser(argparse.ArgumentParser):
         config_file.add_argument(
             "--write-config-file", help="generate a sample configuration file and exit", action="store_true")
         config_file.add_argument(
-            "-c", "--config-file", metavar="<config.cfg>", type=str, default="~/.next-action.cfg",
-            help="filename of configuration file to read (default: %(default)s)")
-        config_file.add_argument(
-            "-C", "--no-config-file", help="don't read the configuration file", action="store_true")
+            "-c", "--config-file", metavar="<config.cfg>", type=str, default="~/.next-action.cfg", nargs="?",
+            help="filename of configuration file to read (default: %(default)s); omit filename to not read any "
+                 "configuration file")
         self.add_argument(
             "-f", "--file", action="append", metavar="<todo.txt>", default=self.__default_filenames[:], type=str,
             help="filename of todo.txt file to read; can be '-' to read from standard input; argument can be "
@@ -86,7 +85,7 @@ class NextActionArgumentParser(argparse.ArgumentParser):
         """ Parse the command-line arguments. """
         namespace, remaining = self.parse_known_args(args, namespace)
         self.parse_remaining_args(remaining, namespace)
-        if not namespace.no_config_file:
+        if getattr(namespace, "config_file", self.get_default("config_file")) is not None:
             self.process_config_file(namespace)
         if namespace.write_config_file:
             write_config_file()


Test patch:
diff --git a/tests/unittests/arguments/test_config.py b/tests/unittests/arguments/test_config.py
index d7e02d2..6f126d8 100644
--- a/tests/unittests/arguments/test_config.py
+++ b/tests/unittests/arguments/test_config.py
@@ -85,7 +85,7 @@ class ConfigFileTest(ConfigTestCase):
         self.assertEqual([call(USAGE_MESSAGE), call("next-action: error: can't open file: some problem\n")],
                          mock_stderr_write.call_args_list)
 
-    @patch.object(sys, "argv", ["next-action", "--no-config-file"])
+    @patch.object(sys, "argv", ["next-action", "--config-file"])
     @patch.object(config, "open")
     def test_skip_config(self, mock_file_open):
         """ Test that the config file is not read if the user doesn't want to. """
diff --git a/tests/unittests/arguments/test_parser.py b/tests/unittests/arguments/test_parser.py
index 20358f6..6a262af 100644
--- a/tests/unittests/arguments/test_parser.py
+++ b/tests/unittests/arguments/test_parser.py
@@ -10,7 +10,7 @@ from next_action.arguments import config, parse_arguments
 
 
 USAGE_MESSAGE = textwrap.fill(
-    "usage: next-action [-h] [--version] [-c <config.cfg> | -C] [-f <todo.txt>] [-n <number> | -a] [-o] "
+    "usage: next-action [-h] [--version] [-c [<config.cfg>]] [-f <todo.txt>] [-n <number> | -a] [-o] "
     "[-p [<priority>]] [<context|project> ...]", 120) + "\n"
 
 
diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py
index 4778730..f26c609 100644
--- a/tests/unittests/test_cli.py
+++ b/tests/unittests/test_cli.py
@@ -65,7 +65,7 @@ class CLITest(unittest.TestCase):
         os.environ['COLUMNS'] = "120"  # Fake that the terminal is wide enough.
         self.assertRaises(SystemExit, next_action)
         self.assertEqual(call("""\
-usage: next-action [-h] [--version] [-c <config.cfg> | -C] [-f <todo.txt>] [-n <number> | -a] [-o] [-p [<priority>]]
+usage: next-action [-h] [--version] [-c [<config.cfg>]] [-f <todo.txt>] [-n <number> | -a] [-o] [-p [<priority>]]
 [<context|project> ...]
 
 Show the next action in your todo.txt. The next action is selected from the tasks in the todo.txt file based on task
@@ -76,9 +76,9 @@ optional arguments:
   -h, --help            show this help message and exit
   --version             show program's version number and exit
   --write-config-file   generate a sample configuration file and exit
-  -c <config.cfg>, --config-file <config.cfg>
-                        filename of configuration file to read (default: ~/.next-action.cfg)
-  -C, --no-config-file  don't read the configuration file
+  -c [<config.cfg>], --config-file [<config.cfg>]
+                        filename of configuration file to read (default: ~/.next-action.cfg); omit filename to not
+                        read any configuration file
   -f <todo.txt>, --file <todo.txt>
                         filename of todo.txt file to read; can be '-' to read from standard input; argument can be
                         repeated to read tasks from multiple todo.txt files (default: ~/todo.txt)