Hello community,

here is the log from the commit of package xonsh for openSUSE:Factory checked 
in at 2018-06-29 22:27:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xonsh (Old)
 and      /work/SRC/openSUSE:Factory/.xonsh.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xonsh"

Fri Jun 29 22:27:06 2018 rev:6 rq:617152 version:0.6.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/xonsh/xonsh.changes      2018-05-29 
10:38:07.723532753 +0200
+++ /work/SRC/openSUSE:Factory/.xonsh.new/xonsh.changes 2018-06-29 
22:27:08.406450056 +0200
@@ -1,0 +2,28 @@
+Sun Jun 10 20:20:03 UTC 2018 - [email protected]
+
+- update to version 0.6.6:
+ * Added:
+  * A multipurpose add method to EnvPath.
+  * Added ``pygments-cache`` project in order to reduce startup time.
+ * Changed:
+  * built_ins.py, corrected a typo.
+  * test/test_news.py
+    It now uses regex to verify the format of rst files
+  * Mercurial (``hg``) will no longer run in a threadable subprocess when
+    it is run in interactive mode.
+ * Fixed:
+  * issue 2313
+
+-------------------------------------------------------------------
+Thu May 31 21:20:01 UTC 2018 - [email protected]
+
+- update to version 0.6.5:
+ * Added:
+  * Wizard ``FileInsterter`` node class now has ``dumps()`` method for
+    converting a mapping to a string to insert in a file.
+ * Fixed:
+  * Fixed issue with ``xonfig wizard`` writer failing to write valid run 
control
+    files for environment variables that are containter types. In particular,
+    the storage of ``$XONSH_HISTORY_SIZE`` has been fixed.
+
+-------------------------------------------------------------------

Old:
----
  0.6.4.tar.gz

New:
----
  0.6.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xonsh.spec ++++++
--- /var/tmp/diff_new_pack.NLVPom/_old  2018-06-29 22:27:08.986449617 +0200
+++ /var/tmp/diff_new_pack.NLVPom/_new  2018-06-29 22:27:08.990449615 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           xonsh
-Version:        0.6.4
+Version:        0.6.6
 Release:        0
 Summary:        A general purpose, Python-ish shell
 License:        BSD-3-Clause AND BSD-2-Clause

++++++ 0.6.4.tar.gz -> 0.6.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/.appveyor.yml 
new/xonsh-0.6.6/.appveyor.yml
--- old/xonsh-0.6.4/.appveyor.yml       2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/.appveyor.yml       2018-06-06 19:12:10.000000000 +0200
@@ -1,4 +1,4 @@
-version: 0.6.4.{build}
+version: 0.6.6.{build}
 os: Windows Server 2012 R2
 environment:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/.travis.yml new/xonsh-0.6.6/.travis.yml
--- old/xonsh-0.6.4/.travis.yml 2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/.travis.yml 2018-06-06 19:12:10.000000000 +0200
@@ -42,7 +42,7 @@
   - if [[ $BUILD_DOCS = true ]]; then
       python setup.py install;
       pip install -r requirements-docs.txt;
-      pip install pygments prompt_toolkit ply psutil ipykernel matplotlib;
+      pip install pygments prompt_toolkit<2 ply psutil ipykernel matplotlib;
       pip install doctr;
     else
       pip install -r requirements-tests.txt;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/CHANGELOG.rst 
new/xonsh-0.6.6/CHANGELOG.rst
--- old/xonsh-0.6.4/CHANGELOG.rst       2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/CHANGELOG.rst       2018-06-06 19:12:10.000000000 +0200
@@ -4,6 +4,64 @@
 
 .. current developments
 
+v0.6.6
+====================
+
+**Added:**
+
+* A multipurpose add method to EnvPath. For example:
+
+  .. code-block:: xonshcon
+
+    $ $PATH
+    EnvPath(
+    ['/usr/bin', '/usr/local/bin', '/bin']
+    )
+    $ $PATH.add('~/.local/bin', front=True); $PATH
+    EnvPath(
+    ['/home/user/.local/bin', '/usr/bin', '/usr/local/bin', '/bin']
+    )
+    $ $PATH.add('/usr/bin', front=True, replace=True); $PATH
+    EnvPath(
+    ['/usr/bin', '/home/user/.local/bin', '/usr/local/bin', '/bin']
+    )
+* Added ``pygments-cache`` project in order to reduce startup time.
+
+
+**Changed:**
+
+* built_ins.py, corrected a typo.
+* test/test_news.py
+  It now uses regex to verify the format of rst files
+* Mercurial (``hg``) will no longer run in a threadable subprocess when
+  it is run in interactive mode.
+
+
+**Fixed:**
+
+* issue 2313
+
+
+
+
+v0.6.5
+====================
+
+**Added:**
+
+* Wizard ``FileInsterter`` node class now has ``dumps()`` method for
+  converting a mapping to a string to insert in a file.
+
+
+**Fixed:**
+
+* Fixed issue with ``xonfig wizard`` writer failing to write valid run control
+  files for environment variables that are containter types. In particular,
+  the storage of ``$XONSH_HISTORY_SIZE`` has been fixed.
+
+
+
+
 v0.6.4
 ====================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/requirements-docs.txt 
new/xonsh-0.6.6/requirements-docs.txt
--- old/xonsh-0.6.4/requirements-docs.txt       2018-05-17 19:50:38.000000000 
+0200
+++ new/xonsh-0.6.6/requirements-docs.txt       2018-06-06 19:12:10.000000000 
+0200
@@ -1,4 +1,4 @@
 cloud_sptheme
 numpydoc==0.5
 Sphinx==1.5.6
-prompt_toolkit
+prompt_toolkit<2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/requirements-tests.txt 
new/xonsh-0.6.6/requirements-tests.txt
--- old/xonsh-0.6.4/requirements-tests.txt      2018-05-17 19:50:38.000000000 
+0200
+++ new/xonsh-0.6.6/requirements-tests.txt      2018-06-06 19:12:10.000000000 
+0200
@@ -5,7 +5,7 @@
 pytest-flake8==0.5
 pytest-cov==2.3.0
 pytest-timeout==1.0.0
-prompt-toolkit==1.0.3
+prompt-toolkit<2
 pygments==2.1.3
 codecov==2.0.5
 flake8==2.6.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/setup.cfg new/xonsh-0.6.6/setup.cfg
--- old/xonsh-0.6.4/setup.cfg   2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/setup.cfg   2018-06-06 19:12:10.000000000 +0200
@@ -1,5 +1,7 @@
 [pytest]
 flake8-max-line-length = 180
+flake8-exclude =
+    xonsh/pygments_cache.py
 flake8-ignore =
     *.py E122
     *.py E402
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/tests/test_news.py 
new/xonsh-0.6.6/tests/test_news.py
--- old/xonsh-0.6.4/tests/test_news.py  2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/tests/test_news.py  2018-06-06 19:12:10.000000000 +0200
@@ -19,42 +19,41 @@
     name = fname.name
     with open(fname.path) as f:
         lines = f.read().splitlines()
-    nlines = len(lines)
-    for i, line in enumerate(lines):
-        if line.startswith('**'):
-            cat, *_ = line[2:].rsplit(':')
+    form = ""
+    for i, l in enumerate(lines):
+        # search the graves
+        if '`' in l:
+            if single_grave_reg.search(l):
+                pytest.fail("{}:{}: single grave accents"
+                            " are not valid rst".format(name, i+1),
+                            pytrace=False)
+
+        # determine the form of line
+        if l.startswith('**'):
+            cat = l[2:].rsplit(':')[0]
             if cat not in CATEGORIES:
                 pytest.fail('{}:{}: {!r} not a proper category '
                             'must be one of {}'
                             ''.format(name, i+1, cat, list(CATEGORIES)),
                             pytrace=False)
-            if i+1 == nlines:
-                continue
-            if not lines[i+1].strip() == '':
-                pytest.fail('{}:{}: empty line required after category'
-                            ''.format(name, i+1), pytrace=False)
-            if i > 0 and not lines[i-1].strip() == '':
-                pytest.fail('{}:{}: empty line required before category'
-                            ''.format(name, i+1), pytrace=False)
-            if line.endswith('None'):
-                if not lines[i+2].startswith('**'):
-                    pytest.fail("{}:{}: can't have entries after None"
-                                ''.format(name, i+1), pytrace=False)
+            if l.endswith('None'): 
+                form += '3'
             else:
-                if lines[i+2].startswith('**'):
-                    pytest.fail("{}:{}: must have entry if not None"
-                                ''.format(name, i+1), pytrace=False)
+                form += '2'
+        elif l.startswith('* ') or l.startswith('  '):
+            form += '1'
+        elif l.strip() == '':
+            form += '0'
         else:
-            if not (line.startswith('* ')
-                    or line.startswith('  ')
-                    or (line.strip() == '')):
-                pytest.fail('{}:{}: invalid rst'.format(name, i+1),
-                            pytrace=False)
-            if '`' in line:
-                if single_grave_reg.search(line):
-                    pytest.fail("{}:{}: single grave accents"
-                                " are not valid rst".format(name, i+1),
-                                pytrace=False)
+            pytest.fail('{}:{}: invalid rst'.format(name, i+1),
+                        pytrace=False)
+    # The file should have:
+    #   empty lines around categories
+    #   at least one content line in a non null category
+    reg = re.compile(r'^(3(0|$)|201(1|0)*0)+$')
+    if not reg.match(form):
+        pytest.fail('{}: invalid rst'.format(name),
+                    pytrace=False)
 
 
 @pytest.mark.parametrize('fname', list(scandir(NEWSDIR)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/tests/test_wizard.py 
new/xonsh-0.6.6/tests/test_wizard.py
--- old/xonsh-0.6.4/tests/test_wizard.py        2018-05-17 19:50:38.000000000 
+0200
+++ new/xonsh-0.6.6/tests/test_wizard.py        2018-06-06 19:12:10.000000000 
+0200
@@ -6,7 +6,7 @@
 import pytest
 
 from xonsh.wizard import (Node, Wizard, Pass, PrettyFormatter,
-    Message, Question, StateVisitor)
+    Message, Question, StateVisitor, FileInserter)
 
 
 TREE0 = Wizard(children=[Pass(), Message(message='yo')])
@@ -57,3 +57,26 @@
                 }
     flat_obs = sv.flatten()
     assert flat_exp == flat_obs
+
+
+def dump_xonfig_env_mock(path, value):
+    name = os.path.basename(path.rstrip('/'))
+    return '${name} = {val!r}'.format(name=name, val=value)
+
+
+def test_tuple_store_and_write():
+    # setup
+    sv = StateVisitor()
+    sv.store('/env/XONSH_HISTORY_SIZE', (1073741824, 'b'))
+    dump_rules = {'/': None, '/env/': None,
+                  '/env/*': dump_xonfig_env_mock,
+                  '/env/*/[0-9]*': None}
+    fi = FileInserter(prefix='# XONSH WIZARD START', suffix='# XONSH WIZARD 
END',
+                      dump_rules=dump_rules, default_file=None,
+                      check=False, ask_filename=False)
+    # run test
+    exp = ("# XONSH WIZARD START\n"
+           "$XONSH_HISTORY_SIZE = (1073741824, 'b')\n"
+           "# XONSH WIZARD END\n")
+    obs = fi.dumps(sv.flatten())
+    assert exp == obs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/__init__.py 
new/xonsh-0.6.6/xonsh/__init__.py
--- old/xonsh-0.6.4/xonsh/__init__.py   2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/xonsh/__init__.py   2018-06-06 19:12:10.000000000 +0200
@@ -1,8 +1,8 @@
-__version__ = '0.6.4'
+__version__ = '0.6.6'
 
 
 # amalgamate exclude jupyter_kernel parser_table parser_test_table pyghooks
-# amalgamate exclude winutils wizard pytest_plugin fs macutils
+# amalgamate exclude winutils wizard pytest_plugin fs macutils pygments_cache
 import os as _os
 if _os.getenv('XONSH_DEBUG', ''):
     pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/ansi_colors.py 
new/xonsh-0.6.6/xonsh/ansi_colors.py
--- old/xonsh-0.6.4/xonsh/ansi_colors.py        2018-05-17 19:50:38.000000000 
+0200
+++ new/xonsh-0.6.6/xonsh/ansi_colors.py        2018-06-06 19:12:10.000000000 
+0200
@@ -890,7 +890,7 @@
         return ANSI_STYLES[name]
     elif not HAS_PYGMENTS:
         raise KeyError('could not find style {0!r}'.format(name))
-    from pygments.styles import get_style_by_name
+    from xonsh.pygments_cache import get_style_by_name
     pstyle = get_style_by_name(name)
     palette = make_palette(pstyle.styles.values())
     astyle = make_ansi_style(palette)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/commands_cache.py 
new/xonsh-0.6.6/xonsh/commands_cache.py
--- old/xonsh-0.6.4/xonsh/commands_cache.py     2018-05-17 19:50:38.000000000 
+0200
+++ new/xonsh-0.6.6/xonsh/commands_cache.py     2018-06-06 19:12:10.000000000 
+0200
@@ -70,12 +70,21 @@
         else:
             return [name]
 
+    @staticmethod
+    def remove_dups(p):
+        ret = list()
+        for e in p:
+            if e not in ret:
+                ret.append(e)
+        return ret
+
     @property
     def all_commands(self):
         paths = builtins.__xonsh_env__.get('PATH', [])
-        pathset = frozenset(x for x in paths if os.path.isdir(x))
+        paths = CommandsCache.remove_dups(paths)
+        path_immut = tuple(x for x in paths if os.path.isdir(x))
         # did PATH change?
-        path_hash = hash(pathset)
+        path_hash = hash(path_immut)
         cache_valid = path_hash == self._path_checksum
         self._path_checksum = path_hash
         # did aliases change?
@@ -85,7 +94,7 @@
         self._alias_checksum = al_hash
         # did the contents of any directory in PATH change?
         max_mtime = 0
-        for path in pathset:
+        for path in path_immut:
             mtime = os.stat(path).st_mtime
             if mtime > max_mtime:
                 max_mtime = mtime
@@ -94,7 +103,7 @@
         if cache_valid:
             return self._cmds_cache
         allcmds = {}
-        for path in reversed(paths):
+        for path in reversed(path_immut):
             # iterate backwards so that entries at the front of PATH overwrite
             # entries at the back.
             for cmd in executables_in(path):
@@ -332,6 +341,23 @@
     return pred
 
 
+@lazyobject
+def HG_PREDICTOR_PARSER():
+    p = argparse.ArgumentParser('hg', add_help=False)
+    p.add_argument('command')
+    p.add_argument('-i', '--interactive', action='store_true', default=False,
+                   dest='interactive')
+    return p
+
+
+def predict_hg(args):
+    """Predict if mercurial is about to be run in interactive mode.
+    If it is interactive, predict False. If it isn't, predict True.
+    """
+    ns, _ = HG_PREDICTOR_PARSER.parse_known_args(args)
+    return not ns.interactive
+
+
 def default_threadable_predictors():
     """Generates a new defaultdict for known threadable predictors.
     The default is to predict true.
@@ -348,6 +374,7 @@
         'emacsclient': predict_false,
         'fish': predict_shell,
         'gvim': predict_help_ver,
+        'hg': predict_hg,
         'htop': predict_help_ver,
         'ipython': predict_shell,
         'ksh': predict_shell,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/pyghooks.py 
new/xonsh-0.6.6/xonsh/pyghooks.py
--- old/xonsh-0.6.4/xonsh/pyghooks.py   2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/xonsh/pyghooks.py   2018-06-06 19:12:10.000000000 +0200
@@ -8,21 +8,12 @@
 from collections import ChainMap
 from collections.abc import MutableMapping
 
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-#           DO NOT MOVE
-# must come before pygments imports
-from xonsh.lazyasd import load_module_in_background
-load_module_in_background('pkg_resources', debug='XONSH_DEBUG',
-                          replacements={'pygments.plugin': 'pkg_resources'})
-# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
 from pygments.lexer import inherit, bygroups, include
 from pygments.lexers.agile import PythonLexer
 from pygments.token import (Keyword, Name, Comment, String, Error, Number,
                             Operator, Generic, Whitespace, Token, Punctuation,
                             Text)
 from pygments.style import Style
-from pygments.styles import get_style_by_name
 import pygments.util
 
 from xonsh.commands_cache import CommandsCache
@@ -34,6 +25,7 @@
 from xonsh.style_tools import norm_name
 from xonsh.lazyimps import terminal256
 from xonsh.platform import os_environ
+from xonsh.pygments_cache import get_style_by_name
 
 
 def _command_is_valid(cmd):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/pygments_cache.py 
new/xonsh-0.6.6/xonsh/pygments_cache.py
--- old/xonsh-0.6.4/xonsh/pygments_cache.py     1970-01-01 01:00:00.000000000 
+0100
+++ new/xonsh-0.6.6/xonsh/pygments_cache.py     2018-06-06 19:12:10.000000000 
+0200
@@ -0,0 +1,417 @@
+"""A fast, drop-in replacement for pygments ``get_*()`` and ``guess_*()`` 
funtions.
+
+The following pygments API functions are currently supplied here::
+
+    from pygments_cache import get_lexer_for_filename, guess_lexer_for_filename
+    from pygments_cache import get_formatter_for_filename, 
get_formatter_by_name
+    from pygments_cache import get_style_by_name
+    from pygments_cache import get_filter_by_name
+
+The cache itself is stored at the location given by the 
``$PYGMENTS_CACHE_FILE``
+environment variable, or by default at 
``~/.local/share/pygments-cache/cache.py``.
+The cache file is created on first use, if it does not already exist.
+
+
+"""
+import os
+import importlib
+
+
+# Global storage variables
+__version__ = '0.1.1'
+CACHE = None
+DEBUG = False
+
+
+def _print_duplicate_message(duplicates):
+    import sys
+    for filename, vals in sorted(duplicates.items()):
+        msg = 'for {0} ambiquity between:\n  '.format(filename)
+        vals = [m + ':' + c for m, c in vals]
+        msg += '\n  '.join(sorted(vals))
+        print(msg, file=sys.stderr)
+
+
+def _discover_lexers():
+    import inspect
+    from pygments.lexers import get_all_lexers, find_lexer_class
+    # maps file extension (and names) to (module, classname) tuples
+    default_exts = {
+        # C / C++
+        '.h': ('pygments.lexers.c_cpp', 'CLexer'),
+        '.hh': ('pygments.lexers.c_cpp', 'CppLexer'),
+        '.cp': ('pygments.lexers.c_cpp', 'CppLexer'),
+        # python
+        '.py': ('pygments.lexers.python', 'Python3Lexer'),
+        '.pyw': ('pygments.lexers.python', 'Python3Lexer'),
+        '.sc': ('pygments.lexers.python', 'Python3Lexer'),
+        '.tac': ('pygments.lexers.python', 'Python3Lexer'),
+        'SConstruct': ('pygments.lexers.python', 'Python3Lexer'),
+        'SConscript': ('pygments.lexers.python', 'Python3Lexer'),
+        '.sage': ('pygments.lexers.python', 'Python3Lexer'),
+        '.pytb': ('pygments.lexers.python', 'Python3TracebackLexer'),
+        # perl
+        '.t': ('pygments.lexers.perl', 'Perl6Lexer'),
+        '.pl': ('pygments.lexers.perl', 'Perl6Lexer'),
+        '.pm': ('pygments.lexers.perl', 'Perl6Lexer'),
+        # asm
+        '.s': ('pygments.lexers.asm', 'GasLexer'),
+        '.S': ('pygments.lexers.asm', 'GasLexer'),
+        '.asm': ('pygments.lexers.asm', 'NasmLexer'),
+        '.ASM': ('pygments.lexers.asm', 'NasmLexer'),
+        # Antlr
+        '.g': ('pygments.lexers.parsers', 'AntlrCppLexer'),
+        '.G': ('pygments.lexers.parsers', 'AntlrCppLexer'),
+        # XML
+        '.xml': ('pygments.lexers.html', 'XmlLexer'),
+        '.xsl': ('pygments.lexers.html', 'XsltLexer'),
+        '.xslt': ('pygments.lexers.html', 'XsltLexer'),
+        # ASP
+        '.axd': ('pygments.lexers.dotnet', 'CSharpAspxLexer'),
+        '.asax': ('pygments.lexers.dotnet', 'CSharpAspxLexer'),
+        '.ascx': ('pygments.lexers.dotnet', 'CSharpAspxLexer'),
+        '.ashx': ('pygments.lexers.dotnet', 'CSharpAspxLexer'),
+        '.asmx': ('pygments.lexers.dotnet', 'CSharpAspxLexer'),
+        '.aspx': ('pygments.lexers.dotnet', 'CSharpAspxLexer'),
+        # misc
+        '.b': ('pygments.lexers.esoteric', 'BrainfuckLexer'),
+        '.j': ('pygments.lexers.jvm', 'JasminLexer'),
+        '.m': ('pygments.lexers.matlab', 'MatlabLexer'),
+        '.n': ('pygments.lexers.dotnet', 'NemerleLexer'),
+        '.p': ('pygments.lexers.pawn', 'PawnLexer'),
+        '.v': ('pygments.lexers.theorem', 'CoqLexer'),
+        '.as': ('pygments.lexers.actionscript', 'ActionScript3Lexer'),
+        '.fs': ('pygments.lexers.forth', 'ForthLexer'),
+        '.hy': ('pygments.lexers.lisp', 'HyLexer'),
+        '.ts': ('pygments.lexers.javascript', 'TypeScriptLexer'),
+        '.rl': ('pygments.lexers.parsers', 'RagelCppLexer'),
+        '.bas': ('pygments.lexers.basic', 'QBasicLexer'),
+        '.bug': ('pygments.lexers.modeling', 'BugsLexer'),
+        '.ecl': ('pygments.lexers.ecl', 'ECLLexer'),
+        '.inc': ('pygments.lexers.php', 'PhpLexer'),
+        '.inf': ('pygments.lexers.configs', 'IniLexer'),
+        '.pro': ('pygments.lexers.prolog', 'PrologLexer'),
+        '.sql': ('pygments.lexers.sql', 'SqlLexer'),
+        '.txt': ('pygments.lexers.special', 'TextLexer'),
+        '.html': ('pygments.lexers.html', 'HtmlLexer'),
+        }
+    exts = {}
+    lexers = {'exts': exts}
+    if DEBUG:
+        from collections import defaultdict
+        duplicates = defaultdict(set)
+    for longname, aliases, filenames, mimetypes in get_all_lexers():
+        cls = find_lexer_class(longname)
+        mod = inspect.getmodule(cls)
+        val = (mod.__name__, cls.__name__)
+        for filename in filenames:
+            if filename.startswith('*.'):
+                filename = filename[1:]
+            if '*' in filename:
+                continue
+            if (DEBUG and filename in exts and exts[filename] != val
+                    and filename not in default_exts):
+                duplicates[filename].add(val)
+                duplicates[filename].add(exts[filename])
+            exts[filename] = val
+    # remove some ambiquity
+    exts.update(default_exts)
+    # print duplicate message
+    if DEBUG:
+        _print_duplicate_message(duplicates)
+    return lexers
+
+
+def _discover_formatters():
+    import inspect
+    from pygments.formatters import get_all_formatters
+    # maps file extension (and names) to (module, classname) tuples
+    default_exts = {}
+    exts = {}
+    # maps formatter 'name' (not the class name) and alias to (module, 
classname) tuples
+    default_names = {}
+    names = {}
+    formatters = {'exts': exts, 'names': names}
+    if DEBUG:
+        from collections import defaultdict
+        duplicates = defaultdict(set)
+    for cls in get_all_formatters():
+        mod = inspect.getmodule(cls)
+        val = (mod.__name__, cls.__name__)
+        # add extentions
+        for filename in cls.filenames:
+            if filename.startswith('*.'):
+                filename = filename[1:]
+            if '*' in filename:
+                continue
+            if (DEBUG and filename in exts and exts[filename] != val
+                    and filename not in default_exts):
+                duplicates[filename].add(val)
+                duplicates[filename].add(exts[filename])
+            exts[filename] = val
+        # add names and aliases
+        names[cls.name] = val
+        for alias in cls.aliases:
+            if (DEBUG and alias in names and names[alias] != val
+                    and alias not in default_names):
+                duplicates[alias].add(val)
+                duplicates[alias].add(names[alias])
+            names[alias] = val
+    # remove some ambiquity
+    exts.update(default_exts)
+    names.update(default_names)
+    # print dumplicate message
+    if DEBUG:
+        _print_duplicate_message(duplicates)
+    return formatters
+
+
+def _discover_styles():
+    import inspect
+    from pygments.styles import get_all_styles, get_style_by_name
+    # maps style 'name' (not the class name) and aliases to (module, 
classname) tuples
+    default_names = {}
+    names = {}
+    styles = {'names': names}
+    if DEBUG:
+        from collections import defaultdict
+        duplicates = defaultdict(set)
+    for name in get_all_styles():
+        cls = get_style_by_name(name)
+        mod = inspect.getmodule(cls)
+        val = (mod.__name__, cls.__name__)
+        if (DEBUG and name in names and names[name] != val
+                and name not in default_names):
+            duplicates[name].add(val)
+            duplicates[name].add(names[name])
+        names[name] = val
+    # remove some ambiquity
+    names.update(default_names)
+    # print dumplicate message
+    if DEBUG:
+        _print_duplicate_message(duplicates)
+    return styles
+
+
+def _discover_filters():
+    import inspect
+    from pygments.filters import get_all_filters, get_filter_by_name
+    # maps filter 'name' (not the class name) to (module, classname) tuples
+    default_names = {}
+    names = {}
+    filters = {'names': names}
+    if DEBUG:
+        from collections import defaultdict
+        duplicates = defaultdict(set)
+    for name in get_all_filters():
+        filter = get_filter_by_name(name)
+        cls = type(filter)
+        mod = inspect.getmodule(cls)
+        val = (mod.__name__, cls.__name__)
+        if (DEBUG and name in names and names[name] != val
+                and name not in default_names):
+            duplicates[name].add(val)
+            duplicates[name].add(names[name])
+        names[name] = val
+    # remove some ambiquity
+    names.update(default_names)
+    # print dumplicate message
+    if DEBUG:
+        _print_duplicate_message(duplicates)
+    return filters
+
+
+def build_cache():
+    """Does the hard work of building a cache from nothing."""
+    cache = {}
+    cache['lexers'] = _discover_lexers()
+    cache['formatters'] = _discover_formatters()
+    cache['styles'] = _discover_styles()
+    cache['filters'] = _discover_filters()
+    return cache
+
+
+def cache_filename():
+    """Gets the name of the cache file to use."""
+    # Configuration variables read from the environment
+    if 'PYGMENTS_CACHE_FILE' in os.environ:
+        return os.environ['PYGMENTS_CACHE_FILE']
+    else:
+        return os.path.join(os.environ.get('XDG_DATA_HOME',
+                                           
os.path.join(os.path.expanduser('~'),
+                                                        '.local', 'share')),
+                            'pygments-cache',
+                            'cache.py'
+                            )
+
+
+def load(filename):
+    """Loads the cache from a filename."""
+    global CACHE
+    with open(filename) as f:
+        s = f.read()
+    ctx = globals()
+    CACHE = eval(s, ctx, ctx)
+    return CACHE
+
+
+def write_cache(filename):
+    """Writes the current cache to the file"""
+    from pprint import pformat
+    d = os.path.dirname(filename)
+    os.makedirs(d, exist_ok=True)
+    s = pformat(CACHE)
+    with open(filename, 'w') as f:
+        f.write(s)
+
+
+def load_or_build():
+    """Loads the cache from disk. If the cache does not exist,
+    this will build and write it out.
+    """
+    global CACHE
+    fname = cache_filename()
+    if os.path.exists(fname):
+        load(fname)
+    else:
+        import sys
+        print('pygments cache not found, building...', file=sys.stderr)
+        CACHE = build_cache()
+        print('...writing cache to ' + fname, file=sys.stderr)
+        write_cache(fname)
+
+
+#
+# pygments interface
+#
+
+def get_lexer_for_filename(filename, text='', **options):
+    """Gets a lexer from a filename (usually via the filename extension).
+    This mimics the behavior of ``pygments.lexers.get_lexer_for_filename()``
+    and ``pygments.lexers.guess_lexer_for_filename()``.
+    """
+    if CACHE is None:
+        load_or_build()
+    exts = CACHE['lexers']['exts']
+    fname = os.path.basename(filename)
+    key = fname if fname in exts else os.path.splitext(fname)[1]
+    if key in exts:
+        modname, clsname = exts[key]
+        mod = importlib.import_module(modname)
+        cls = getattr(mod, clsname)
+        lexer = cls(**options)
+    else:
+        # couldn't find lexer in cache, fallback to the hard way
+        import inspect
+        from pygments.lexers import guess_lexer_for_filename
+        lexer = guess_lexer_for_filename(filename, text, **options)
+        # add this filename to the cache for future use
+        cls = type(lexer)
+        mod = inspect.getmodule(cls)
+        exts[fname] = (mod.__name__, cls.__name__)
+        write_cache(cache_filename())
+    return lexer
+
+
+guess_lexer_for_filename = get_lexer_for_filename
+
+
+def get_formatter_for_filename(fn, **options):
+    """Gets a formatter instance from a filename (usually via the filename
+    extension). This mimics the behavior of
+    ``pygments.formatters.get_formatter_for_filename()``.
+    """
+    if CACHE is None:
+        load_or_build()
+    exts = CACHE['formatters']['exts']
+    fname = os.path.basename(fn)
+    key = fname if fname in exts else os.path.splitext(fname)[1]
+    if key in exts:
+        modname, clsname = exts[key]
+        mod = importlib.import_module(modname)
+        cls = getattr(mod, clsname)
+        formatter = cls(**options)
+    else:
+        # couldn't find formatter in cache, fallback to the hard way
+        import inspect
+        from pygments.formatters import get_formatter_for_filename
+        formatter = get_formatter_for_filename(fn, **options)
+        # add this filename to the cache for future use
+        cls = type(formatter)
+        mod = inspect.getmodule(cls)
+        exts[fname] = (mod.__name__, cls.__name__)
+        write_cache(cache_filename())
+    return formatter
+
+
+def get_formatter_by_name(alias, **options):
+    """Gets a formatter instance from its name or alias.
+    This mimics the behavior of 
``pygments.formatters.get_formatter_by_name()``.
+    """
+    if CACHE is None:
+        load_or_build()
+    names = CACHE['formatters']['names']
+    if alias in names:
+        modname, clsname = names[alias]
+        mod = importlib.import_module(modname)
+        cls = getattr(mod, clsname)
+        formatter = cls(**options)
+    else:
+        # couldn't find formatter in cache, fallback to the hard way
+        import inspect
+        from pygments.formatters import get_formatter_by_name
+        formatter = get_formatter_by_name(alias, **options)
+        # add this filename to the cache for future use
+        cls = type(formatter)
+        mod = inspect.getmodule(cls)
+        names[alias] = (mod.__name__, cls.__name__)
+        write_cache(cache_filename())
+    return formatter
+
+
+def get_style_by_name(name):
+    """Gets a style class from its name or alias.
+    This mimics the behavior of ``pygments.styles.get_style_by_name()``.
+    """
+    if CACHE is None:
+        load_or_build()
+    names = CACHE['styles']['names']
+    if name in names:
+        modname, clsname = names[name]
+        mod = importlib.import_module(modname)
+        style = getattr(mod, clsname)
+    else:
+        # couldn't find style in cache, fallback to the hard way
+        import inspect
+        from pygments.styles import get_style_by_name
+        style = get_style_by_name(name)
+        # add this style to the cache for future use
+        mod = inspect.getmodule(style)
+        names[name] = (mod.__name__, style.__name__)
+        write_cache(cache_filename())
+    return style
+
+
+def get_filter_by_name(filtername, **options):
+    """Gets a filter instance from its name. This mimics the behavior of
+    ``pygments.filters.get_filtere_by_name()``.
+    """
+    if CACHE is None:
+        load_or_build()
+    names = CACHE['filters']['names']
+    if filtername in names:
+        modname, clsname = names[filtername]
+        mod = importlib.import_module(modname)
+        cls = getattr(mod, clsname)
+        filter = cls(**options)
+    else:
+        # couldn't find style in cache, fallback to the hard way
+        import inspect
+        from pygments.filters import get_filter_by_name
+        filter = get_filter_by_name(filtername, **options)
+        # add this filter to the cache for future use
+        cls = type(filter)
+        mod = inspect.getmodule(cls)
+        names[filtername] = (mod.__name__, cls.__name__)
+        write_cache(cache_filename())
+    return filter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/tools.py 
new/xonsh-0.6.6/xonsh/tools.py
--- old/xonsh-0.6.4/xonsh/tools.py      2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/xonsh/tools.py      2018-06-06 19:12:10.000000000 +0200
@@ -228,6 +228,36 @@
             other = other._l
         return EnvPath(other + self._l)
 
+    def add(self, data, front=False, replace=False):
+        """Add a value to this EnvPath,
+
+        path.add(data, front=bool, replace=bool) -> ensures that path contains 
data, with position determined by kwargs
+
+        Parameters
+        ----------
+        data : string or bytes or pathlib.Path
+            value to be added
+        front : bool
+            whether the value should be added to the front, will be
+            ignored if the data already exists in this EnvPath and
+            replace is False
+            Default : False
+        replace : bool
+            If True, the value will be removed and added to the
+            start or end(depending on the value of front)
+            Default : False
+
+        Returns
+        -------
+        None
+
+        """
+        if data not in self._l:
+            self._l.insert(0 if front else len(self._l), data)
+        elif replace:
+            self._l.remove(data)
+            self._l.insert(0 if front else len(self._l), data)
+
 
 class DefaultNotGivenType(object):
     """Singleton for representing when no default value is given."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/wizard.py 
new/xonsh-0.6.6/xonsh/wizard.py
--- old/xonsh-0.6.4/xonsh/wizard.py     2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/xonsh/wizard.py     2018-06-06 19:12:10.000000000 +0200
@@ -334,6 +334,11 @@
             dr[r] = func
         self._dr = dr
 
+    @staticmethod
+    def _find_rule_key(x):
+        """Key function for sorting regular expression rules"""
+        return (x[0], len(x[1].pattern))
+
     def find_rule(self, path):
         """For a path, find the key and conversion function that should be 
used to
         dump a value.
@@ -350,10 +355,25 @@
         if len(len_funcs) == 0:
             # No dump rule function for path
             return path, None
-        len_funcs.sort(reverse=True)
+        len_funcs.sort(reverse=True, key=self._find_rule_key)
         _, rule, func = len_funcs[0]
         return rule, func
 
+    def dumps(self, flat):
+        """Dumps a flat mapping of (string path keys, values) pairs and returns
+        a formatted string.
+        """
+        lines = [self.prefix]
+        for path, value in sorted(flat.items()):
+            rule, func = self.find_rule(path)
+            if func is None:
+                continue
+            line = func(path, value)
+            lines.append(line)
+        lines.append(self.suffix)
+        new = '\n'.join(lines) + '\n'
+        return new
+
 
 def create_truefalse_cond(prompt='yes or no [default: no]? ', path=None):
     """This creates a basic condition function for use with nodes like While
@@ -771,16 +791,7 @@
 
     def visit_fileinserter(self, node):
         # perform the dumping operation.
-        lines = [node.prefix]
-        flat = self.flatten()
-        for path, value in sorted(flat.items()):
-            rule, func = node.find_rule(path)
-            if func is None:
-                continue
-            line = func(path, value)
-            lines.append(line)
-        lines.append(node.suffix)
-        new = '\n'.join(lines) + '\n'
+        new = node.dumps(self.flatten())
         # check if we should write this out
         if node.check:
             msg = 'The current state to insert is:\n\n{0}\n'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xonsh-0.6.4/xonsh/xonfig.py 
new/xonsh-0.6.6/xonsh/xonfig.py
--- old/xonsh-0.6.4/xonsh/xonfig.py     2018-05-17 19:50:38.000000000 +0200
+++ new/xonsh-0.6.6/xonsh/xonfig.py     2018-06-06 19:12:10.000000000 +0200
@@ -161,7 +161,7 @@
 
 
 def _dump_xonfig_env(path, value):
-    name = os.path.basename(path)
+    name = os.path.basename(path.rstrip('/'))
     ensurer = builtins.__xonsh_env__.get_ensurer(name)
     dval = ensurer.detype(value)
     return '${name} = {val!r}'.format(name=name, val=dval)
@@ -177,6 +177,7 @@
             '/env/': None,
             '/foreign_shells/*/': _dump_xonfig_foreign_shell,
             '/env/*': _dump_xonfig_env,
+            '/env/*/[0-9]*': None,
             '/xontribs/': _dump_xonfig_xontribs,
             }
 


Reply via email to