diff --git a/.gitattributes b/.gitattributes index bdd4ea2..17db22f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ -/tests export-ignore \ No newline at end of file +/tests export-ignore +/.github export-ignore +pyproject.toml export-ignore \ No newline at end of file diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 0000000..a524a74 --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,20 @@ +name: Pretty Json Tests + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.8] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Run Tests + run: | + cd tests + python tests.py \ No newline at end of file diff --git a/Pretty JSON.sublime-settings b/Pretty JSON.sublime-settings index d075273..196f29b 100644 --- a/Pretty JSON.sublime-settings +++ b/Pretty JSON.sublime-settings @@ -1,6 +1,7 @@ { "use_entire_file_if_no_selection": true, "indent": 4, + "sort_keys": false, "ensure_ascii": false, "line_separator": ",", @@ -9,7 +10,11 @@ "max_arrays_line_length": 120, "pretty_on_save": false, "validate_on_save": true, - "reindent_block": false, + "brace_newline": true, + "bracket_newline": true, + // Default: False + // Valid Options: False, start, minimal + "reindent_block": "minimal", // Name or Path to jq binary // Example: /usr/bin/local/jq // Example: jq diff --git a/PrettyJson.py b/PrettyJson.py index 4668a36..f393898 100644 --- a/PrettyJson.py +++ b/PrettyJson.py @@ -43,8 +43,10 @@ def check_jq(): class PrettyJsonBaseCommand: phantom_set = sublime.PhantomSet phantoms = list() - json_char_matcher = re.compile(r'char (\d+)') force_sorting = False + json_char_matcher = re.compile(r'char (\d+)') + brace_newline = re.compile(r'^((\s*)".*?":)\s*([{])', re.MULTILINE) + bracket_newline = re.compile(r'^((\s*)".*?":)\s*([\[])', re.MULTILINE) @staticmethod def json_loads(selection: str) -> dict: @@ -87,19 +89,31 @@ class PrettyJsonBaseCommand: replacement = '[' + join_separator.join(items) + ']' if len(replacement) <= s.get('max_arrays_line_length', 120): output_json = output_json.replace(m, replacement, 1) + if s.get("brace_newline", True): + output_json = PrettyJsonBaseCommand.brace_newline.sub(r'\1\n\2\3', output_json) + + if ( + s.get("bracket_newline", True) + and s.get('keep_arrays_single_line', False) is False + ): + output_json = PrettyJsonBaseCommand.bracket_newline.sub(r'\1\n\2\3', output_json) return output_json + def brace_bracket_newline(json_data: str) -> str: + better_json = PrettyJsonBaseCommand.brace_bracket_newline.sub(r'\1\n\2\3', json_data) + return better_json + def reindent(self, text: str, selection: str): current_line = self.view.line(selection.begin()) text_before_sel = sublime.Region(current_line.begin(), selection.begin()) - reindent_mode = s.get('reindent_block', 'minimal') + reindent_mode = s.get('reindent_block', False) if reindent_mode == 'start': space_number = text_before_sel.size() indent_space = ' ' * space_number - else: - indent_space = re.search('^\s*', self.view.substr(text_before_sel)).group(0) + elif reindent_mode == 'minimal': + indent_space = re.search(r'^\s*', self.view.substr(text_before_sel)).group(0) lines = text.split('\n') diff --git a/phantom.css b/phantom.css index c8074d3..5fbf927 100644 --- a/phantom.css +++ b/phantom.css @@ -1,3 +1,6 @@ +/* Description: Taken from LSP +- https://github.com/sublimelsp/LSP/blob/master/plugin/diagnostics.py +*/ div.error-arrow { border-top: 0.4rem solid transparent; border-left: 0.5rem solid color(var(--redish) blend(var(--background) 30%)); diff --git a/tests/tests.py b/tests/tests.py index ab04520..9e86325 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -29,9 +29,9 @@ class TestIssues(unittest.TestCase): # issue 15 def test_float_issue_15(self): tmp_str = '{"real":0.99}' - expected_output = """{ + expected_output = '''{ "real": 0.99 -}""" +}''' obj = json.loads(tmp_str, object_pairs_hook=OrderedDict, parse_float=decimal.Decimal) tmp_str = json.dumps(obj, indent=2, ensure_ascii=False, sort_keys=False, separators=(',', ': '), @@ -52,7 +52,7 @@ class TestIssues(unittest.TestCase): def test_float_issue_16_2(self): tmp_str = '{"test1":0.99, "test2":"1.99", "test3":1.00000000001, "test4":1.99, "test5":1,' \ ' "test6":4.589999999999999999, "test7":1.0}' - expected_output = """{ + expected_output = '''{ "test1": 0.99, "test2": "1.99", "test3": 1.00000000001, @@ -60,7 +60,7 @@ class TestIssues(unittest.TestCase): "test5": 1, "test6": 4.589999999999999999, "test7": 1.0 -}""" +}''' obj = json.loads(tmp_str, object_pairs_hook=OrderedDict, parse_float=decimal.Decimal) tmp_str = json.dumps(obj, indent=2, ensure_ascii=False, sort_keys=False, separators=(',', ': '), @@ -68,9 +68,9 @@ class TestIssues(unittest.TestCase): self.assertEqual(tmp_str, expected_output) def test_compress_feature(self): - tmp_str = """{ + tmp_str = '''{ "real": 0.99 -}""" +}''' expected_output = '{"real":0.99}' obj = json.loads(tmp_str, object_pairs_hook=OrderedDict, parse_float=decimal.Decimal) tmp_str = json.dumps(obj, ensure_ascii=False, sort_keys=False,