From 1c5c8045928eae251e766c2f44c2a5c8d2bb4eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Fri, 15 Jul 2016 10:03:18 -0500 Subject: [PATCH 1/6] Improve extensions parsing from pygments lexer --- spyderlib/config/utils.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/spyderlib/config/utils.py b/spyderlib/config/utils.py index 20c5d107611..8b6a8a5dc45 100644 --- a/spyderlib/config/utils.py +++ b/spyderlib/config/utils.py @@ -80,15 +80,23 @@ def _get_pygments_extensions(): """Return all file type extensions supported by Pygments""" # NOTE: Leave this import here to keep startup process fast! import pygments.lexers as lexers + extensions = [] - all_lexers = lexers.get_all_lexers() - for lx in all_lexers: + for lx in lexers.get_all_lexers(): lexer_exts = lx[2] + if lexer_exts: - lexer_exts = [le[1:] for le in lexer_exts] + # Reference: This line was included for leaving untrimmed the + # extensions not starting with `*` + other_exts = [le for le in lexer_exts if not le.startswith('*')] + # Reference: This commented line was replaced by the following one + # to trim only extensions that start with '*' + # lexer_exts = [le[1:] for le in lexer_exts] + lexer_exts = [le[1:] for le in lexer_exts if le.startswith('*')] lexer_exts = [le for le in lexer_exts if not le.endswith('_*')] - extensions = extensions + list(lexer_exts) - return extensions + extensions = extensions + list(lexer_exts) + list(other_exts) + + return sorted(extensions) #============================================================================== From 6cddebb19c01e8141a0295c239cce5cd4affd7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Fri, 15 Jul 2016 10:03:49 -0500 Subject: [PATCH 2/6] Improve include patterns generation --- spyderlib/plugins/findinfiles.py | 38 ++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/spyderlib/plugins/findinfiles.py b/spyderlib/plugins/findinfiles.py index abb3cc5097a..c68a0c1b0f6 100644 --- a/spyderlib/plugins/findinfiles.py +++ b/spyderlib/plugins/findinfiles.py @@ -11,6 +11,9 @@ # pylint: disable=R0911 # pylint: disable=R0201 +# Standard library imports +import sys + # Third party imports from qtpy.QtWidgets import QApplication from qtpy.QtCore import Signal, Slot @@ -18,11 +21,11 @@ # Local imports from spyderlib.config.base import _ from spyderlib.config.utils import get_edit_extensions -from spyderlib.plugins import SpyderPluginMixin from spyderlib.py3compat import getcwd from spyderlib.utils import icon_manager as ima from spyderlib.utils.qthelpers import create_action from spyderlib.widgets.findinfiles import FindInFilesWidget +from spyderlib.plugins import SpyderPluginMixin class FindInFiles(FindInFilesWidget, SpyderPluginMixin): @@ -94,14 +97,23 @@ def findinfiles_callback(self): if text: self.find() - def include_patterns(self): - edit_ext = get_edit_extensions() - patterns = [r'|'.join(['\\'+_ext+r'$' for _ext in edit_ext if _ext])+\ + @staticmethod + def include_patterns(): + """Generate regex common usage patterns to include section.""" + # Change special characters, like + and . to convert into valid re + clean_exts = [] + for ext in get_edit_extensions(): + ext = ext.replace('.', r'\.') + ext = ext.replace('+', r'\+') + clean_exts.append(ext) + + patterns = [r'|'.join([ext + r'$' for ext in clean_exts if ext]) + r'|README|INSTALL', - r'\.pyw?$|\.ipy$|\.txt$|\.rst$', - '.'] + r'\.ipy$|\.pyw?$|\.rst$|\.txt$', + '.', + ] return patterns - + #------ SpyderPluginMixin API --------------------------------------------- def switch_to_plugin(self): """Switch to plugin @@ -171,3 +183,15 @@ def closing_plugin(self, cancelable=False): self.set_option('in_python_path', in_python_path) self.set_option('more_options', more_options) return True + + +def test(): + from spyderlib.utils.qthelpers import qapplication + app = qapplication() + widget = FindInFiles() + widget.show() + sys.exit(app.exec_()) + + +if __name__ == '__main__': + test() From 4b54a4e10e9298492a6b7adedf5115ad31c477d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Fri, 15 Jul 2016 10:04:20 -0500 Subject: [PATCH 3/6] Add test to validate include and exclude patterns as valid regex --- spyderlib/plugins/tests/test_findinfiles.py | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 spyderlib/plugins/tests/test_findinfiles.py diff --git a/spyderlib/plugins/tests/test_findinfiles.py b/spyderlib/plugins/tests/test_findinfiles.py new file mode 100644 index 00000000000..1b67fde8925 --- /dev/null +++ b/spyderlib/plugins/tests/test_findinfiles.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# ----------------------------------------------------------------------------- +# Copyright © 2009- The Spyder Development Team +# +# Licensed under the terms of the MIT License +# (see spyderlib/__init__.py for details) +# ----------------------------------------------------------------------------- +"""Test scripts for `findinfiles` plugin.""" + +# Standard library imports +import re + +# Local imports +from spyderlib.config.main import EXCLUDE_PATTERNS + + +class TestFindInFilesPlugin: + + def check_regex(self, patterns): + """ + Check that regular expression patterns provided by compiling them. + Return a list of booleans for each of the provided patterns. + """ + checks = [] + for pattern in patterns: + try: + re.compile(pattern) + is_valid = True + except re.error: + is_valid = False + checks.append(is_valid) + return checks + + def test_include_patterns_are_valid_regex(self, qtbot): + # qtawesome requires a QApplication to exist, so widgets import must + # happen inside the test (or with fixtures) + from spyderlib.plugins.findinfiles import FindInFiles + patterns = FindInFiles.include_patterns() + checks = self.check_regex(patterns) + assert all(checks) + + def test_exclude_patterns_are_valid_regex(self): + checks = self.check_regex(EXCLUDE_PATTERNS) + assert all(checks) From 1835c59956d497fb52e2532f1021dd907f0b7224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Fri, 15 Jul 2016 11:12:26 -0500 Subject: [PATCH 4/6] Remove duplicates and sort extension list --- spyderlib/config/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spyderlib/config/utils.py b/spyderlib/config/utils.py index 8b6a8a5dc45..da201a99658 100644 --- a/spyderlib/config/utils.py +++ b/spyderlib/config/utils.py @@ -96,7 +96,7 @@ def _get_pygments_extensions(): lexer_exts = [le for le in lexer_exts if not le.endswith('_*')] extensions = extensions + list(lexer_exts) + list(other_exts) - return sorted(extensions) + return sorted(list(set(extensions))) #============================================================================== From 797ea2843cd94de92182efaaa67ff8420a88c9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Sat, 16 Jul 2016 08:21:10 -0500 Subject: [PATCH 5/6] Remove uneeded space --- spyderlib/plugins/findinfiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spyderlib/plugins/findinfiles.py b/spyderlib/plugins/findinfiles.py index c68a0c1b0f6..5c7dade56e2 100644 --- a/spyderlib/plugins/findinfiles.py +++ b/spyderlib/plugins/findinfiles.py @@ -113,7 +113,7 @@ def include_patterns(): '.', ] return patterns - + #------ SpyderPluginMixin API --------------------------------------------- def switch_to_plugin(self): """Switch to plugin From ed4d12479fc1b92bb2c544224d4d758150b7dd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Pe=C3=B1a-Castellanos?= Date: Sat, 16 Jul 2016 08:21:23 -0500 Subject: [PATCH 6/6] /Hide advanced options by default --- spyderlib/config/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spyderlib/config/main.py b/spyderlib/config/main.py index b3b539352e7..2568abb88ea 100644 --- a/spyderlib/config/main.py +++ b/spyderlib/config/main.py @@ -288,7 +288,7 @@ 'search_text': [''], 'search_text_samples': [codeanalysis.TASKS_PATTERN], 'in_python_path': False, - 'more_options': True, + 'more_options': False, }), ('workingdir', { @@ -585,7 +585,7 @@ # or if you want to *rename* options, then you need to do a MAJOR update in # version, e.g. from 3.0.0 to 4.0.0 # 3. You don't need to touch this value if you're just adding a new option -CONF_VERSION = '27.1.0' +CONF_VERSION = '27.2.0' # XXX: Previously we had load=(not DEV) here but DEV was set to *False*.