Repository: getnikola/nikola

Issue:
Missing --list--installed flag from nikola theme command
For `nikola plugin`, we have `--list-installed` flag, but not so for `nikola theme`.

Is it possible to implement this?

Cheers.



Discussion:
Well, it's not really easy to do, since there is nothing to tell apart a theme from any random directory (plugins have a metadata file)


Resolving patch:
diff --git a/nikola/plugins/command/plugin.py b/nikola/plugins/command/plugin.py
--- a/nikola/plugins/command/plugin.py
+++ b/nikola/plugins/command/plugin.py
@@ -50,7 +50,7 @@ class CommandPlugin(Command):
 
     json = None
     name = "plugin"
-    doc_usage = "[[-u][--user] --install name] | [[-u] [-l |--upgrade|--list-installed] | [--uninstall name]]"
+    doc_usage = "[-u url] [--user] [-i name] [-r name] [--upgrade] [-l] [--list-installed]"
     doc_purpose = "manage plugins"
     output_dir = None
     needs_config = False
@@ -177,8 +177,8 @@ def list_installed(self):
             plugins.append([plugin.name, p])
 
         plugins.sort()
-        print('Installed Plugins')
-        print('-----------------')
+        print('Installed Plugins:')
+        print('------------------')
         for name, path in plugins:
             print('{0} at {1}'.format(name, path))
         print('\n\nAlso, you have disabled these plugins: {}'.format(self.site.config['DISABLED_PLUGINS']))
diff --git a/nikola/plugins/command/theme.py b/nikola/plugins/command/theme.py
--- a/nikola/plugins/command/theme.py
+++ b/nikola/plugins/command/theme.py
@@ -36,6 +36,7 @@
 import pygments
 from pygments.lexers import PythonLexer
 from pygments.formatters import TerminalFormatter
+from pkg_resources import resource_filename
 
 from nikola.plugin_categories import Command
 from nikola import utils
@@ -48,7 +49,7 @@ class CommandTheme(Command):
 
     json = None
     name = "theme"
-    doc_usage = "[-i theme_name] [-r theme_name] [-l] [-u url] [-g] [-n theme_name] [-c template_name]"
+    doc_usage = "[-u url] [-i theme_name] [-r theme_name] [-l] [--list-installed] [-g] [-n theme_name] [-c template_name]"
     doc_purpose = "manage themes"
     output_dir = 'themes'
     cmd_options = [
@@ -76,6 +77,13 @@ class CommandTheme(Command):
             'default': False,
             'help': 'Show list of available themes.'
         },
+        {
+            'name': 'list_installed',
+            'long': 'list-installed',
+            'type': bool,
+            'help': "List the installed themes with their location.",
+            'default': False
+        },
         {
             'name': 'url',
             'short': 'u',
@@ -133,6 +141,7 @@ def _execute(self, options, args):
         install = options.get('install')
         uninstall = options.get('uninstall')
         list_available = options.get('list')
+        list_installed = options.get('list_installed')
         get_path = options.get('getpath')
         copy_template = options.get('copy-template')
         new = options.get('new')
@@ -142,6 +151,7 @@ def _execute(self, options, args):
             install,
             uninstall,
             list_available,
+            list_installed,
             get_path,
             copy_template,
             new)].count(True)
@@ -151,6 +161,8 @@ def _execute(self, options, args):
 
         if list_available:
             return self.list_available(url)
+        elif list_installed:
+            return self.list_installed()
         elif install:
             return self.do_install_deps(url, install)
         elif uninstall:
@@ -263,6 +275,18 @@ def list_available(self, url):
             print(theme)
         return 0
 
+    def list_installed(self):
+        """List all installed themes."""
+        print("Installed Themes:")
+        print("-----------------")
+        themes = []
+        themes_dirs = self.site.themes_dirs + [resource_filename('nikola', os.path.join('data', 'themes'))]
+        for tdir in themes_dirs:
+            themes += [(i, os.path.join(tdir, i)) for i in os.listdir(tdir)]
+        for tname, tpath in sorted(set(themes)):
+            if os.path.isdir(tpath):
+                print("{0} at {1}".format(tname, tpath))
+
     def copy_template(self, template):
         """Copy the named template file from the parent to a local theme or to templates/."""
         # Find template


Test patch: