implement: type hinting

implement: .gitattributes
implement: .python-verison
implement: f'strings

fix: libs -> lib
fix: Sublime Menus
This commit is contained in:
TheSecEng 2020-04-15 19:09:43 -04:00
parent a9fab727fd
commit 623e810569
No known key found for this signature in database
GPG Key ID: A7C3BA459E8C5C4E
17 changed files with 76 additions and 111 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
/tests export-ignore

1
.python-version Normal file
View File

@ -0,0 +1 @@
3.8

View File

@ -12,7 +12,7 @@
"command": "un_pretty_json" "command": "un_pretty_json"
}, },
{ {
"caption": "Pretty JSON: JSON 2 XML", "caption": "Pretty JSON: json2xml",
"command": "json_to_xml" "command": "json_to_xml"
}, },
{ {
@ -24,17 +24,11 @@
"command": "pretty_json_validate" "command": "pretty_json_validate"
}, },
{ {
"caption": "Preferences: Pretty JSON Settings - User", "caption": "Preferences: Pretty JSON Settings",
"command": "open_file", "args": "command": "edit_settings",
{ "args": {
"file": "${packages}/User/Pretty JSON.sublime-settings" "base_file": "${packages}/Pretty JSON/Pretty JSON.sublime-settings",
} "default": "{\n\t$0\n}\n"
},
{
"caption": "Preferences: Pretty JSON Settings - Default",
"command": "open_file", "args":
{
"file": "${packages}/Pretty JSON/Pretty JSON.sublime-settings"
} }
} }
] ]

View File

@ -1,38 +1,29 @@
[ [
{
"mnemonic": "n",
"caption": "Preferences",
"id": "preferences",
"children": [
{ {
"mnemonic": "n", "mnemonic": "P",
"caption": "Preferences", "caption": "Package Settings",
"id": "preferences", "id": "package-settings",
"children": [ "children": [
{
"caption": "Pretty JSON",
"children": [
{ {
"mnemonic": "P", "caption": "Settings",
"caption": "Package Settings", "command": "edit_settings",
"id": "package-settings", "args":
"children": [ {
{ "base_file": "${packages}/Pretty JSON/Pretty JSON.sublime-settings",
"caption": "Pretty JSON", "default": "{\n\t$0\n}\n",
"children": [ }
{ },
"caption": "Settings Default", {
"args": { "caption": "-"
"file": "${packages}/Pretty JSON/Pretty JSON.sublime-settings" }]
}, }]
"command": "open_file" }]
}, }]
{
"caption": "Settings User",
"args": {
"file": "${packages}/User/Pretty JSON.sublime-settings"
},
"command": "open_file"
},
{
"caption": "-"
}
]
}
]
}
]
}
]

View File

@ -9,5 +9,9 @@
"max_arrays_line_length": 120, "max_arrays_line_length": 120,
"pretty_on_save": false, "pretty_on_save": false,
"validate_on_save": true, "validate_on_save": true,
"reindent_block": false "reindent_block": false,
// Name or Path to jq binary
// Example: /usr/bin/local/jq
// Example: jq
"jq_binary": "jq"
} }

View File

@ -2,14 +2,15 @@ import decimal
import os import os
import re import re
import subprocess import subprocess
import shutil
import sys import sys
from xml.etree import ElementTree from xml.etree import ElementTree
import sublime import sublime
import sublime_plugin import sublime_plugin
from .libs import simplejson as json from .lib import simplejson as json
from .libs.simplejson import OrderedDict from .lib.simplejson import OrderedDict
SUBLIME_MAJOR_VERSION = int(sublime.version()) / 1000 SUBLIME_MAJOR_VERSION = int(sublime.version()) / 1000
@ -20,34 +21,20 @@ json_syntax = 'Packages/JSON/JSON.tmLanguage'
jq_exists = False jq_exists = False
jq_init = False jq_init = False
jq_path = str()
''' for OSX we need to manually add brew bin path so jq can be found '''
if sys.platform != 'win32' and '/usr/local/bin' not in os.environ['PATH']:
os.environ['PATH'] += os.pathsep + '/usr/local/bin'
''' defer jq presence check until the user tries to use it, include Package "Fix Mac Path" to resolve
all homebrew issues (https://github.com/int3h/SublimeFixMacPath) '''
def check_jq(): def check_jq():
global jq_exists global jq_init, jq_exists, jq_path
global jq_init
if not jq_init: if not jq_init:
jq_init = True jq_init = True
jq_test = s.get('jq_binary', 'jq')
try: try:
# checking if ./jq tool is available so we can use it jq_path = shutil.which(jq_test)
s = subprocess.Popen(
['jq', '--version'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
)
out, err = s.communicate()
jq_exists = True jq_exists = True
except OSError: except OSError as ex:
os_exception = sys.exc_info()[1] print(str(ex))
print(str(os_exception))
jq_exists = False jq_exists = False
@ -58,14 +45,13 @@ class PrettyJsonBaseCommand:
force_sorting = False force_sorting = False
@staticmethod @staticmethod
def json_loads(selection): def json_loads(selection: str) -> dict:
return json.loads( return json.loads(
selection, object_pairs_hook=OrderedDict, parse_float=decimal.Decimal selection, object_pairs_hook=OrderedDict, parse_float=decimal.Decimal
) )
@staticmethod @staticmethod
def json_dumps(obj, minified=False): def json_dumps(obj, minified: bool = False) -> str:
sort_keys = s.get('sort_keys', False) sort_keys = s.get('sort_keys', False)
if PrettyJsonBaseCommand.force_sorting: if PrettyJsonBaseCommand.force_sorting:
sort_keys = True sort_keys = True
@ -102,7 +88,7 @@ class PrettyJsonBaseCommand:
return output_json return output_json
def reindent(self, text, selection): def reindent(self, text: str, selection: str):
current_line = self.view.line(selection.begin()) current_line = self.view.line(selection.begin())
text_before_sel = sublime.Region(current_line.begin(), selection.begin()) text_before_sel = sublime.Region(current_line.begin(), selection.begin())
@ -122,14 +108,14 @@ class PrettyJsonBaseCommand:
return '\n'.join(lines) return '\n'.join(lines)
def show_exception(self, region, msg): def show_exception(self, region: sublime.Region, msg):
sublime.status_message('[Error]: {}'.format(msg)) sublime.status_message(f'[Error]: {msg}')
if region is None: if region is None:
sublime.message_dialog(msg) sublime.message_dialog(msg)
return return
self.highlight_error(region=region, message='{}'.format(msg)) self.highlight_error(region=region, message=f'{msg}')
def highlight_error(self, region, message): def highlight_error(self, region: sublime.Region, message: str):
self.phantom_set = sublime.PhantomSet(self.view, 'json_errors') self.phantom_set = sublime.PhantomSet(self.view, 'json_errors')
char_match = self.json_char_matcher.search(message) char_match = self.json_char_matcher.search(message)
@ -155,21 +141,19 @@ class PrettyJsonBaseCommand:
# Description: Taken from https://github.com/sublimelsp/LSP/blob/master/plugin/diagnostics.py # Description: Taken from https://github.com/sublimelsp/LSP/blob/master/plugin/diagnostics.py
# - Thanks to the LSP Team # - Thanks to the LSP Team
def create_phantom_html(self, content: str, severity: str) -> str: def create_phantom_html(self, content: str, severity: str) -> str:
stylesheet = sublime.load_resource('Packages/SublimePrettyJson/phantom.css') stylesheet = sublime.load_resource('Packages/Pretty JSON/phantom.css')
return '''<body id=inline-error> return f'''<body id=inline-error>
<style>{}</style> <style>{stylesheet}</style>
<div class="{}-arrow"></div> <div class="{severity}-arrow"></div>
<div class="{} container"> <div class="{severity} container">
<div class="toolbar"> <div class="toolbar">
<a href="hide">×</a> <a href="hide">×</a>
</div> </div>
<div class="content">{}</div> <div class="content">{content}</div>
</div> </div>
</body>'''.format( </body>'''
stylesheet, severity, severity, content
)
def navigation(self, href): def navigation(self, href: str):
self.clear_phantoms() self.clear_phantoms()
def clear_phantoms(self): def clear_phantoms(self):
@ -180,7 +164,7 @@ class PrettyJsonBaseCommand:
self.phantom_set.update(self.phantoms) self.phantom_set.update(self.phantoms)
def syntax_to_json(self): def syntax_to_json(self):
' Changes syntax to JSON if its in plain text ' ''' Changes syntax to JSON if its in plain text '''
if 'Plain text' in self.view.settings().get('syntax'): if 'Plain text' in self.view.settings().get('syntax'):
self.view.set_syntax_file(json_syntax) self.view.set_syntax_file(json_syntax)
@ -335,10 +319,10 @@ class JqPrettyJson(sublime_plugin.WindowCommand):
selection = region selection = region
return view.substr(selection) return view.substr(selection)
def done(self, query): def done(self, query: str):
try: try:
p = subprocess.Popen( p = subprocess.Popen(
["jq", query], [jq_path, query],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
@ -424,7 +408,7 @@ class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
class JqPrettyJsonOut(sublime_plugin.TextCommand): class JqPrettyJsonOut(sublime_plugin.TextCommand):
def run(self, edit, jq_output=str()): def run(self, edit, jq_output: str = str()):
self.view.insert(edit, 0, jq_output) self.view.insert(edit, 0, jq_output)

View File

@ -1,30 +1,20 @@
import sublime import sublime
import sublime_plugin import sublime_plugin
try: from .PrettyJson import PrettyJsonBaseCommand
# python 3 / Sublime Text 3
from .PrettyJson import PrettyJsonBaseCommand
except ValueError:
from PrettyJson import PrettyJsonBaseCommand
s = sublime.load_settings("Pretty JSON.sublime-settings") s = sublime.load_settings("Pretty JSON.sublime-settings")
class PrettyJsonLintListener(sublime_plugin.EventListener, PrettyJsonBaseCommand): class PrettyJsonLintListener(sublime_plugin.EventListener, PrettyJsonBaseCommand):
def on_post_save(self, view): def on_post_save(self, view):
# will work only in json syntax and once validate_on_save setting is true validate = s.get('validate_on_save', True)
validate = s.get("validate_on_save", True) as_json = s.get('as_json', ['JSON'])
as_json = s.get("as_json", ["JSON"])
if validate and any( if validate and any(
syntax in view.settings().get("syntax") for syntax in as_json syntax in view.settings().get("syntax") for syntax in as_json
): ):
self.view = view self.view = view
PrettyJsonBaseCommand.clear_phantoms(self)
self.view.erase_regions("json_errors") json_content = self.view.substr(sublime.Region(0, self.view.size()))
self.view.erase_status("json_errors")
json_content = self.view.substr(sublime.Region(0, view.size()))
try: try:
self.json_loads(json_content) self.json_loads(json_content)
except Exception as ex: except Exception as ex:
@ -33,9 +23,9 @@ class PrettyJsonLintListener(sublime_plugin.EventListener, PrettyJsonBaseCommand
class PrettyJsonAutoPrettyOnSaveListener(sublime_plugin.EventListener): class PrettyJsonAutoPrettyOnSaveListener(sublime_plugin.EventListener):
def on_pre_save(self, view): def on_pre_save(self, view):
auto_pretty = s.get("pretty_on_save", False) auto_pretty = s.get('pretty_on_save', False)
as_json = s.get("as_json", ["JSON"]) as_json = s.get('as_json', ['JSON'])
if auto_pretty and any( if auto_pretty and any(
syntax in view.settings().get("syntax") for syntax in as_json syntax in view.settings().get('syntax') for syntax in as_json
): ):
sublime.active_window().run_command("pretty_json") sublime.active_window().run_command('pretty_json')

View File

@ -2,7 +2,7 @@ import sys
import os import os
# parent folder holds libraries which needs to be included # parent folder holds libraries which needs to be included
sys.path.append(os.path.realpath('..')) sys.path.append(os.path.realpath('../lib'))
import simplejson as json import simplejson as json
from simplejson import OrderedDict from simplejson import OrderedDict