76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
"""
|
|
Contains the python specific FileManager.
|
|
"""
|
|
import ast
|
|
import re
|
|
from pyqode.core.api import TextBlockHelper
|
|
from pyqode.core.managers import FileManager
|
|
|
|
|
|
class PyFileManager(FileManager):
|
|
"""
|
|
Extends file manager to override detect_encoding. With python, we can
|
|
detect encoding by reading the two first lines of a file and extracting its
|
|
encoding tag.
|
|
|
|
"""
|
|
#: True to fold import statements on open.
|
|
fold_imports = False
|
|
|
|
#: True to fold docstring on open
|
|
fold_docstrings = False
|
|
|
|
def detect_encoding(self, path):
|
|
"""
|
|
For the implementation of encoding definitions in Python, look at:
|
|
- http://www.python.org/dev/peps/pep-0263/
|
|
|
|
.. note:: code taken and adapted from
|
|
```jedi.common.source_to_unicode.detect_encoding```
|
|
"""
|
|
with open(path, 'rb') as file:
|
|
source = file.read()
|
|
# take care of line encodings (not in jedi)
|
|
source = source.replace(b'\r', b'')
|
|
source_str = str(source).replace('\\n', '\n')
|
|
|
|
byte_mark = ast.literal_eval(r"b'\xef\xbb\xbf'")
|
|
if source.startswith(byte_mark):
|
|
# UTF-8 byte-order mark
|
|
return 'utf-8'
|
|
|
|
first_two_lines = re.match(r'(?:[^\n]*\n){0,2}', source_str).group(0)
|
|
possible_encoding = re.search(r"coding[=:]\s*([-\w.]+)",
|
|
first_two_lines)
|
|
if possible_encoding:
|
|
return possible_encoding.group(1)
|
|
return 'UTF-8'
|
|
|
|
def open(self, path, encoding=None, use_cached_encoding=True):
|
|
if encoding is None:
|
|
encoding = self.detect_encoding(path)
|
|
super(PyFileManager, self).open(
|
|
path, encoding=encoding, use_cached_encoding=use_cached_encoding)
|
|
try:
|
|
folding_panel = self.editor.panels.get('FoldingPanel')
|
|
except KeyError:
|
|
pass
|
|
else:
|
|
# fold imports and/or docstrings
|
|
blocks_to_fold = []
|
|
sh = self.editor.syntax_highlighter
|
|
|
|
if self.fold_imports and sh.import_statements:
|
|
blocks_to_fold += sh.import_statements
|
|
if self.fold_docstrings and sh.docstrings:
|
|
blocks_to_fold += sh.docstrings
|
|
|
|
for block in blocks_to_fold:
|
|
if TextBlockHelper.is_fold_trigger(block):
|
|
folding_panel.toggle_fold_trigger(block)
|
|
|
|
def clone_settings(self, original):
|
|
super(PyFileManager, self).clone_settings(original)
|
|
self.fold_docstrings = original.fold_docstrings
|
|
self.fold_imports = original.fold_imports
|