<commit_before>"""Parse arguments and run Porcupine using ``_run.py``."""

import argparse
import logging
import os
import pathlib
import sys
import typing

from porcupine import _logs, pluginloader, get_tab_manager, tabs, utils
import porcupine.plugins    # .plugins for porcupine.plugins.__path__

log = logging.getLogger(__name__)


# these actions are based on argparse's source code

class _PrintPlugindirAction(argparse.Action):

    def __init__(   # type: ignore
            self, option_strings, dest=argparse.SUPPRESS,
            default=argparse.SUPPRESS, help=None):
        super().__init__(option_strings=option_strings, dest=dest,
                         default=default, nargs=0, help=help)

    def __call__(   # type: ignore
            self, parser, namespace, values, option_string=None):
        print("You can install plugins here:\n\n    %s\n"
              % porcupine.plugins.__path__[0])
        parser.exit()


# "porcupine -n a b c -n" works, but unfortunately "porcupine a -n b" doesn't
class _ExtendAction(argparse.Action):

    def __init__(   # type: ignore
            self, option_strings, dest, nargs=None, const=None,
            default=None, type=None, choices=None, required=False,
            help=None, metavar=None):
        assert nargs != 0 and (const is None or nargs == argparse.OPTIONAL)
        super().__init__(option_strings=option_strings, dest=dest, nargs=nargs,
                         const=const, default=default, type=type,
                         choices=choices, required=required, help=help,
                         metavar=metavar)

    def __call__(   # type: ignore
            self, parser, namespace, values, option_string=None):
        if getattr(namespace, self.dest) is None:
            setattr(namespace, self.dest, [])
        getattr(namespace, self.dest).extend(values)


_EPILOG = r"""
Examples:
  %(prog)s                    # run Porcupine normally
  %(prog)s file1.py file2.js  # open the given files on startup
  %(prog)s -nnn               # create 3 new files
  %(prog)s --no-plugins       # understand the power of plugins
  %(prog)s --verbose          # produce lots of nerdy output
"""


def main() -> None:
    prog = os.path.basename(sys.argv[0])
    if prog == '__main__.py':
        prog = f'{utils.short_python_command} -m porcupine'

    parser = argparse.ArgumentParser(
        prog=prog, epilog=_EPILOG,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument(
        '-v', '--version', action='version',
        version=("Porcupine %s" % porcupine.__version__),
        help="display the Porcupine version number and exit")
    parser.add_argument(
        '--print-plugindir', action=_PrintPlugindirAction,
        help="find out where to install custom plugins")
    parser.add_argument(
        'files', metavar='FILES', action=_ExtendAction,
        # FIXME: this uses the system-default encoding :/
        nargs=argparse.ZERO_OR_MORE, type=argparse.FileType("r"),
        help="open these files when Porcupine starts, - means stdin")
    parser.add_argument(
        '-n', '--new-file', dest='files', action='append_const', const=None,
        help='create a "New File" tab, may be given multiple times')

    plugingroup = parser.add_argument_group("plugin loading options")
    plugingroup.add_argument(
        '--no-plugins', action='store_false', dest='yes_plugins',
        help=("don't load any plugins, this is useful for "
              "understanding how much can be done with plugins"))
    plugingroup.add_argument(
        '--without-plugins', metavar='PLUGINS', default='',
        help=("don't load PLUGINS (see --print-plugindir), "
              "e.g. --without-plugins=highlight disables syntax highlighting, "
              "multiple plugin names can be given comma-separated"))
    plugingroup.add_argument(
        '--shuffle-plugins', action='store_true',
        help=("respect setup_before and setup_after, but otherwise setup the "
              "plugins in a random order instead of sorting by name "
              "alphabetically, useful for making sure that your plugin's "
              "setup_before and setup_after define everything needed; usually "
              "plugins are not shuffled in order to make the UI consistent"))

    parser.add_argument(
        '--verbose', action='store_true',
        help=("print all logging messages to stderr, only warnings and errors "
              "are printed by default (but all messages always go to a log "
              "file in %s as well)" % _logs.LOG_DIR))

    args = parser.parse_args()

    filelist: typing.List[typing.Tuple[
        typing.Optional[pathlib.Path], str
    ]] = []
    for file in args.files:
        if file is sys.stdin:
            # don't close stdin so it's possible to do this:
            #
            #   $ porcupine - -
            #   bla bla bla
            #   ^D
            #   bla bla
            #   ^D
            filelist.append((None, file.read()))
        elif file is None:
            # -n or --new-file was used
            filelist.append((None, ''))
        else:
            with file:<commit_msg>-v means --verbose (fixes #57)<commit_after>"""Parse arguments and run Porcupine using ``_run.py``."""

import argparse
import logging
import os
import pathlib
import sys
import typing

from porcupine import _logs, pluginloader, get_tab_manager, tabs, utils
import porcupine.plugins    # .plugins for porcupine.plugins.__path__

log = logging.getLogger(__name__)


# these actions are based on argparse's source code

class _PrintPlugindirAction(argparse.Action):

    def __init__(   # type: ignore
            self, option_strings, dest=argparse.SUPPRESS,
            default=argparse.SUPPRESS, help=None):
        super().__init__(option_strings=option_strings, dest=dest,
                         default=default, nargs=0, help=help)

    def __call__(   # type: ignore
            self, parser, namespace, values, option_string=None):
        print("You can install plugins here:\n\n    %s\n"
              % porcupine.plugins.__path__[0])
        parser.exit()


# "porcupine -n a b c -n" works, but unfortunately "porcupine a -n b" doesn't
class _ExtendAction(argparse.Action):

    def __init__(   # type: ignore
            self, option_strings, dest, nargs=None, const=None,
            default=None, type=None, choices=None, required=False,
            help=None, metavar=None):
        assert nargs != 0 and (const is None or nargs == argparse.OPTIONAL)
        super().__init__(option_strings=option_strings, dest=dest, nargs=nargs,
                         const=const, default=default, type=type,
                         choices=choices, required=required, help=help,
                         metavar=metavar)

    def __call__(   # type: ignore
            self, parser, namespace, values, option_string=None):
        if getattr(namespace, self.dest) is None:
            setattr(namespace, self.dest, [])
        getattr(namespace, self.dest).extend(values)


_EPILOG = r"""
Examples:
  %(prog)s                    # run Porcupine normally
  %(prog)s file1.py file2.js  # open the given files on startup
  %(prog)s -nnn               # create 3 new files
  %(prog)s --no-plugins       # understand the power of plugins
  %(prog)s -v                 # produce lots of output for debugging
"""


def main() -> None:
    prog = os.path.basename(sys.argv[0])
    if prog == '__main__.py':
        prog = f'{utils.short_python_command} -m porcupine'

    parser = argparse.ArgumentParser(
        prog=prog, epilog=_EPILOG,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument(
        '--version', action='version',
        version=("Porcupine %s" % porcupine.__version__),
        help="display the Porcupine version number and exit")
    parser.add_argument(
        '--print-plugindir', action=_PrintPlugindirAction,
        help="find out where to install custom plugins")
    parser.add_argument(
        'files', metavar='FILES', action=_ExtendAction,
        # FIXME: this uses the system-default encoding :/
        nargs=argparse.ZERO_OR_MORE, type=argparse.FileType("r"),
        help="open these files when Porcupine starts, - means stdin")
    parser.add_argument(
        '-n', '--new-file', dest='files', action='append_const', const=None,
        help='create a "New File" tab, may be given multiple times')

    plugingroup = parser.add_argument_group("plugin loading options")
    plugingroup.add_argument(
        '--no-plugins', action='store_false', dest='yes_plugins',
        help=("don't load any plugins, this is useful for "
              "understanding how much can be done with plugins"))
    plugingroup.add_argument(
        '--without-plugins', metavar='PLUGINS', default='',
        help=("don't load PLUGINS (see --print-plugindir), "
              "e.g. --without-plugins=highlight disables syntax highlighting, "
              "multiple plugin names can be given comma-separated"))
    plugingroup.add_argument(
        '--shuffle-plugins', action='store_true',
        help=("respect setup_before and setup_after, but otherwise setup the "
              "plugins in a random order instead of sorting by name "
              "alphabetically, useful for making sure that your plugin's "
              "setup_before and setup_after define everything needed; usually "
              "plugins are not shuffled in order to make the UI consistent"))

    parser.add_argument(
        '-v', '--verbose', action='store_true',
        help=("print all logging messages to stderr, only warnings and errors "
              "are printed by default (but all messages always go to a log "
              "file in %s as well)" % _logs.LOG_DIR))

    args = parser.parse_args()

    filelist: typing.List[typing.Tuple[
        typing.Optional[pathlib.Path], str
    ]] = []
    for file in args.files:
        if file is sys.stdin:
            # don't close stdin so it's possible to do this:
            #
            #   $ porcupine - -
            #   bla bla bla
            #   ^D
            #   bla bla
            #   ^D
            filelist.append((None, file.read()))
        elif file is None:
            # -n or --new-file was used
            filelist.append((None, ''))
        else:
            with file:
{'fraction_non_alphanumeric': 0.10754662286211228, 'fraction_numerical': 0.0015460430959512996, 'mean_word_length': 2.426017874875869, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3060706', 'n_tokens_mistral': 3027, 'n_tokens_neox': 2922, 'n_words': 856}