Compare commits
1 Commits
develop
...
356818b98c
| Author | SHA1 | Date | |
|---|---|---|---|
| 356818b98c |
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Module
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Package
|
|
||||||
"""
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Example Completer",
|
|
||||||
"author": "John Doe",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"support": "",
|
|
||||||
"requests": {}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.dto.base_event import BaseEvent
|
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
|
||||||
|
|
||||||
from .provider import Provider
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginCode):
|
|
||||||
def __init__(self):
|
|
||||||
super(Plugin, self).__init__()
|
|
||||||
|
|
||||||
self.provider: Provider = None
|
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
self.provider = Provider()
|
|
||||||
|
|
||||||
event = Event_Factory.create_event(
|
|
||||||
"register_provider",
|
|
||||||
provider_name = "Example Completer",
|
|
||||||
provider = self.provider,
|
|
||||||
language_ids = []
|
|
||||||
)
|
|
||||||
self.message_to("completion", event)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
...
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GObject
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from .provider_response_cache import ProviderResponseCache
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Provider(GObject.GObject, GtkSource.CompletionProvider):
|
|
||||||
"""
|
|
||||||
This is a custom Completion Example Provider.
|
|
||||||
# NOTE: used information from here --> https://warroom.rsmus.com/do-that-auto-complete/
|
|
||||||
"""
|
|
||||||
__gtype_name__ = 'ExampleCompletionProvider'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Provider, self).__init__()
|
|
||||||
|
|
||||||
self.response_cache: ProviderResponseCache = ProviderResponseCache()
|
|
||||||
|
|
||||||
|
|
||||||
def do_get_name(self):
|
|
||||||
""" Returns: a new string containing the name of the provider. """
|
|
||||||
return 'Example Code Completion'
|
|
||||||
|
|
||||||
def do_match(self, context):
|
|
||||||
# word = context.get_word()
|
|
||||||
# if not word or len(word) < 2: return False
|
|
||||||
|
|
||||||
""" Get whether the provider match the context of completion detailed in context. """
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
if not word or len(word) < 2: return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def do_get_priority(self):
|
|
||||||
""" Determin position in result list along other providor results. """
|
|
||||||
return 5
|
|
||||||
|
|
||||||
def do_activate_proposal(self, proposal, iter_):
|
|
||||||
""" Manually handle actual completion insert or set flags and handle normally. """
|
|
||||||
|
|
||||||
buffer = iter_.get_buffer()
|
|
||||||
# Note: Flag mostly intended for SourceViewsMultiInsertState
|
|
||||||
# to insure marker processes inserted text correctly.
|
|
||||||
buffer.is_processing_completion = True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_get_activation(self):
|
|
||||||
""" The context for when a provider will show results """
|
|
||||||
# return GtkSource.CompletionActivation.NONE
|
|
||||||
# return GtkSource.CompletionActivation.USER_REQUESTED
|
|
||||||
# return GtkSource.CompletionActivation.USER_REQUESTED | GtkSource.CompletionActivation.INTERACTIVE
|
|
||||||
return GtkSource.CompletionActivation.INTERACTIVE
|
|
||||||
|
|
||||||
def do_populate(self, context):
|
|
||||||
results = self.response_cache.filter_with_context(context)
|
|
||||||
proposals = []
|
|
||||||
|
|
||||||
for entry in results:
|
|
||||||
proposals.append(
|
|
||||||
self.response_cache.create_completion_item(
|
|
||||||
entry["label"],
|
|
||||||
entry["text"],
|
|
||||||
entry["info"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
context.add_proposals(self, proposals, True)
|
|
||||||
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Code_Event_Types
|
|
||||||
|
|
||||||
from core.widgets.code.completion_providers.provider_response_cache_base import ProviderResponseCacheBase
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProviderResponseCache(ProviderResponseCacheBase):
|
|
||||||
def __init__(self):
|
|
||||||
super(ProviderResponseCache, self).__init__()
|
|
||||||
|
|
||||||
self.matchers: dict = {
|
|
||||||
"hello": {
|
|
||||||
"label": "Hello, World!",
|
|
||||||
"text": "Hello, World!",
|
|
||||||
"info": GLib.markup_escape_text( "<b>Says the first ever program developers write...</b>" )
|
|
||||||
},
|
|
||||||
"foo": {
|
|
||||||
"label": "foo",
|
|
||||||
"text": "foo }}"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"label": "bar",
|
|
||||||
"text": "bar }}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_save(self, event: Code_Event_Types.SavedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def filter(self, word: str) -> list[dict]:
|
|
||||||
...
|
|
||||||
|
|
||||||
def filter_with_context(self, context) -> list[dict]:
|
|
||||||
"""
|
|
||||||
In this instance, it will do 2 things:
|
|
||||||
1) always provide Hello World! (Not ideal but an option so its in the example)
|
|
||||||
2) Utilizes the Gtk.TextIter from the TextBuffer to determine if there is a jinja
|
|
||||||
example of '{{ custom.' if so it will provide you with the options of foo and bar.
|
|
||||||
If selected it will insert foo }} or bar }}, completing your syntax...
|
|
||||||
|
|
||||||
PLEASE NOTE the GtkTextIter Logic and regex are really rough and should be adjusted and tuned
|
|
||||||
"""
|
|
||||||
|
|
||||||
proposals: list[dict] = [
|
|
||||||
{
|
|
||||||
"label": self.matchers[ "hello" ]["label"],
|
|
||||||
"text": self.matchers[ "hello" ]["text"],
|
|
||||||
"info": self.matchers[ "hello" ]["info"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
# Gtk Versions differ on get_iter responses...
|
|
||||||
end_iter = context.get_iter()
|
|
||||||
if not isinstance(end_iter, Gtk.TextIter):
|
|
||||||
_, end_iter = context.get_iter()
|
|
||||||
|
|
||||||
if not end_iter: return
|
|
||||||
|
|
||||||
buf = end_iter.get_buffer()
|
|
||||||
mov_iter = end_iter.copy()
|
|
||||||
if mov_iter.backward_search('{{', Gtk.TextSearchFlags.VISIBLE_ONLY):
|
|
||||||
mov_iter, _ = mov_iter.backward_search('{{', Gtk.TextSearchFlags.VISIBLE_ONLY)
|
|
||||||
left_text = buf.get_text(mov_iter, end_iter, True)
|
|
||||||
else:
|
|
||||||
left_text = ''
|
|
||||||
|
|
||||||
if re.match(r'.*\{\{\s*custom\.$', left_text):
|
|
||||||
# optionally proposed based on left search via regex
|
|
||||||
proposals.append(
|
|
||||||
{
|
|
||||||
"label": self.matchers[ "foo" ]["label"],
|
|
||||||
"text": self.matchers[ "foo" ]["text"],
|
|
||||||
"info": ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# optionally proposed based on left search via regex
|
|
||||||
proposals.append(
|
|
||||||
{
|
|
||||||
"label": self.matchers[ "bar" ]["label"],
|
|
||||||
"text": self.matchers[ "bar" ]["text"],
|
|
||||||
"info": ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return proposals
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Module
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Package
|
|
||||||
"""
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "LSP Completer",
|
|
||||||
"author": "ITDominator",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"support": "",
|
|
||||||
"requests": {}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.dto.base_event import BaseEvent
|
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
|
||||||
|
|
||||||
from .provider import Provider
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginCode):
|
|
||||||
def __init__(self):
|
|
||||||
super(Plugin, self).__init__()
|
|
||||||
|
|
||||||
self.provider: Provider = None
|
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
self.provider = Provider()
|
|
||||||
|
|
||||||
event = Event_Factory.create_event(
|
|
||||||
"register_provider",
|
|
||||||
provider_name = "LSP Completer",
|
|
||||||
provider = self.provider,
|
|
||||||
language_ids = []
|
|
||||||
)
|
|
||||||
self.message_to("completion", event)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def generate_plugin_element(self):
|
|
||||||
...
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GObject
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from .provider_response_cache import ProviderResponseCache
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Provider(GObject.GObject, GtkSource.CompletionProvider):
|
|
||||||
"""
|
|
||||||
This code is an LSP code completion plugin for Newton.
|
|
||||||
# NOTE: Some code pulled/referenced from here --> https://github.com/isamert/gedi
|
|
||||||
"""
|
|
||||||
__gtype_name__ = 'LSPProvider'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Provider, self).__init__()
|
|
||||||
|
|
||||||
self.response_cache: ProviderResponseCache = ProviderResponseCache()
|
|
||||||
|
|
||||||
|
|
||||||
def pre_populate(self, context):
|
|
||||||
...
|
|
||||||
|
|
||||||
def do_get_name(self):
|
|
||||||
return "LSP Code Completion"
|
|
||||||
|
|
||||||
def do_match(self, context):
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
if not word or len(word) < 2: return False
|
|
||||||
|
|
||||||
iter = self.response_cache.get_iter_correctly(context)
|
|
||||||
iter.backward_char()
|
|
||||||
ch = iter.get_char()
|
|
||||||
# NOTE: Look to re-add or apply supprting logic to use spaces
|
|
||||||
# As is it slows down the editor in certain contexts...
|
|
||||||
# if not (ch in ('_', '.', ' ') or ch.isalnum()):
|
|
||||||
if not (ch in ('_', '.') or ch.isalnum()):
|
|
||||||
return False
|
|
||||||
|
|
||||||
buffer = iter.get_buffer()
|
|
||||||
if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def do_get_priority(self):
|
|
||||||
return 5
|
|
||||||
|
|
||||||
def do_activate_proposal(self, proposal, iter_):
|
|
||||||
buffer = iter_.get_buffer()
|
|
||||||
# Note: Flag mostly intended for SourceViewsMultiInsertState
|
|
||||||
# to insure marker processes inserted text correctly.
|
|
||||||
buffer.is_processing_completion = True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_get_activation(self):
|
|
||||||
""" The context for when a provider will show results """
|
|
||||||
# return GtkSource.CompletionActivation.NONE
|
|
||||||
return GtkSource.CompletionActivation.USER_REQUESTED
|
|
||||||
# return GtkSource.CompletionActivation.INTERACTIVE
|
|
||||||
|
|
||||||
def do_populate(self, context):
|
|
||||||
results = self.response_cache.filter_with_context(context)
|
|
||||||
proposals = []
|
|
||||||
|
|
||||||
for entry in results:
|
|
||||||
proposals.append(
|
|
||||||
self.response_cache.create_completion_item(
|
|
||||||
entry["label"],
|
|
||||||
entry["text"],
|
|
||||||
entry["info"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
context.add_proposals(self, proposals, True)
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Code_Event_Types
|
|
||||||
|
|
||||||
from core.widgets.code.completion_providers.provider_response_cache_base import ProviderResponseCacheBase
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProviderResponseCache(ProviderResponseCacheBase):
|
|
||||||
def __init__(self):
|
|
||||||
super(ProviderResponseCache, self).__init__()
|
|
||||||
|
|
||||||
|
|
||||||
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_save(self, event: Code_Event_Types.SavedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def filter(self, word: str) -> list[dict]:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def filter_with_context(self, context: GtkSource.CompletionContext) -> list[dict]:
|
|
||||||
proposals = [
|
|
||||||
{
|
|
||||||
"label": "LSP Class",
|
|
||||||
"text": "LSP Code",
|
|
||||||
"info": "A test LSP completion item..."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
return proposals
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Module
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Package
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
from .parser import load, loads
|
|
||||||
from .writer import dump, dumps
|
|
||||||
from .speg import ParseError
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
from .speg import peg
|
|
||||||
import re, sys
|
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
_chr = unichr
|
|
||||||
else:
|
|
||||||
_chr = chr
|
|
||||||
|
|
||||||
def load(fin):
|
|
||||||
return loads(fin.read())
|
|
||||||
|
|
||||||
def loads(s):
|
|
||||||
if isinstance(s, bytes):
|
|
||||||
s = s.decode('utf-8')
|
|
||||||
if s.startswith(u'\ufeff'):
|
|
||||||
s = s[1:]
|
|
||||||
return peg(s.replace('\r\n', '\n'), _p_root)
|
|
||||||
|
|
||||||
def _p_ws(p):
|
|
||||||
p('[ \t]*')
|
|
||||||
|
|
||||||
def _p_nl(p):
|
|
||||||
p(r'([ \t]*(?:#[^\n]*)?\r?\n)+')
|
|
||||||
|
|
||||||
def _p_ews(p):
|
|
||||||
with p:
|
|
||||||
p(_p_nl)
|
|
||||||
p(_p_ws)
|
|
||||||
|
|
||||||
def _p_id(p):
|
|
||||||
return p(r'[$a-zA-Z_][$0-9a-zA-Z_]*')
|
|
||||||
|
|
||||||
_escape_table = {
|
|
||||||
'r': '\r',
|
|
||||||
'n': '\n',
|
|
||||||
't': '\t',
|
|
||||||
'f': '\f',
|
|
||||||
'b': '\b',
|
|
||||||
}
|
|
||||||
def _p_unescape(p):
|
|
||||||
esc = p('\\\\(?:u[0-9a-fA-F]{4}|[^\n])')
|
|
||||||
if esc[1] == 'u':
|
|
||||||
return _chr(int(esc[2:], 16))
|
|
||||||
return _escape_table.get(esc[1:], esc[1:])
|
|
||||||
|
|
||||||
_re_indent = re.compile(r'[ \t]*')
|
|
||||||
def _p_block_str(p, c):
|
|
||||||
p(r'{c}{c}{c}'.format(c=c))
|
|
||||||
lines = [['']]
|
|
||||||
with p:
|
|
||||||
while True:
|
|
||||||
s = p(r'(?:{c}(?!{c}{c})|[^{c}\\])*'.format(c=c))
|
|
||||||
l = s.split('\n')
|
|
||||||
lines[-1].append(l[0])
|
|
||||||
lines.extend([x] for x in l[1:])
|
|
||||||
if p(r'(?:\\\n[ \t]*)*'):
|
|
||||||
continue
|
|
||||||
p.commit()
|
|
||||||
lines[-1].append(p(_p_unescape))
|
|
||||||
p(r'{c}{c}{c}'.format(c=c))
|
|
||||||
|
|
||||||
lines = [''.join(l) for l in lines]
|
|
||||||
strip_ws = len(lines) > 1
|
|
||||||
if strip_ws and all(c in ' \t' for c in lines[-1]):
|
|
||||||
lines.pop()
|
|
||||||
|
|
||||||
indent = None
|
|
||||||
for line in lines[1:]:
|
|
||||||
if not line:
|
|
||||||
continue
|
|
||||||
if indent is None:
|
|
||||||
indent = _re_indent.match(line).group(0)
|
|
||||||
continue
|
|
||||||
for i, (c1, c2) in enumerate(zip(indent, line)):
|
|
||||||
if c1 != c2:
|
|
||||||
indent = indent[:i]
|
|
||||||
break
|
|
||||||
|
|
||||||
ind_len = len(indent or '')
|
|
||||||
if strip_ws and all(c in ' \t' for c in lines[0]):
|
|
||||||
lines = [line[ind_len:] for line in lines[1:]]
|
|
||||||
else:
|
|
||||||
lines[1:] = [line[ind_len:] for line in lines[1:]]
|
|
||||||
|
|
||||||
return '\n'.join(lines)
|
|
||||||
|
|
||||||
_re_mstr_nl = re.compile(r'(?:[ \t]*\n)+[ \t]*')
|
|
||||||
_re_mstr_trailing_nl = re.compile(_re_mstr_nl.pattern + r'\Z')
|
|
||||||
def _p_multiline_str(p, c):
|
|
||||||
p('{c}(?!{c}{c})(?:[ \t]*\n[ \t]*)?'.format(c=c))
|
|
||||||
string_parts = []
|
|
||||||
with p:
|
|
||||||
while True:
|
|
||||||
string_parts.append(p(r'[^{c}\\]*'.format(c=c)))
|
|
||||||
if p(r'(?:\\\n[ \t]*)*'):
|
|
||||||
string_parts.append('')
|
|
||||||
continue
|
|
||||||
p.commit()
|
|
||||||
string_parts.append(p(_p_unescape))
|
|
||||||
p(c)
|
|
||||||
string_parts[-1] = _re_mstr_trailing_nl.sub('', string_parts[-1])
|
|
||||||
string_parts[::2] = [_re_mstr_nl.sub(' ', part) for part in string_parts[::2]]
|
|
||||||
return ''.join(string_parts)
|
|
||||||
|
|
||||||
def _p_string(p):
|
|
||||||
with p:
|
|
||||||
return p(_p_block_str, '"')
|
|
||||||
with p:
|
|
||||||
return p(_p_block_str, "'")
|
|
||||||
with p:
|
|
||||||
return p(_p_multiline_str, '"')
|
|
||||||
return p(_p_multiline_str, "'")
|
|
||||||
|
|
||||||
def _p_array_value(p):
|
|
||||||
with p:
|
|
||||||
p(_p_nl)
|
|
||||||
return p(_p_object)
|
|
||||||
with p:
|
|
||||||
p(_p_ws)
|
|
||||||
return p(_p_line_object)
|
|
||||||
p(_p_ews)
|
|
||||||
return p(_p_simple_value)
|
|
||||||
|
|
||||||
def _p_key(p):
|
|
||||||
with p:
|
|
||||||
return p(_p_id)
|
|
||||||
return p(_p_string)
|
|
||||||
|
|
||||||
def _p_flow_kv(p):
|
|
||||||
k = p(_p_key)
|
|
||||||
p(_p_ews)
|
|
||||||
p(':')
|
|
||||||
with p:
|
|
||||||
p(_p_nl)
|
|
||||||
return k, p(_p_object)
|
|
||||||
with p:
|
|
||||||
p(_p_ws)
|
|
||||||
return k, p(_p_line_object)
|
|
||||||
p(_p_ews)
|
|
||||||
return k, p(_p_simple_value)
|
|
||||||
|
|
||||||
def _p_flow_obj_sep(p):
|
|
||||||
with p:
|
|
||||||
p(_p_ews)
|
|
||||||
p(',')
|
|
||||||
p(_p_ews)
|
|
||||||
return
|
|
||||||
|
|
||||||
p(_p_nl)
|
|
||||||
p(_p_ws)
|
|
||||||
|
|
||||||
def _p_simple_value(p):
|
|
||||||
with p:
|
|
||||||
p('null')
|
|
||||||
return None
|
|
||||||
|
|
||||||
with p:
|
|
||||||
p('false')
|
|
||||||
return False
|
|
||||||
with p:
|
|
||||||
p('true')
|
|
||||||
return True
|
|
||||||
|
|
||||||
with p:
|
|
||||||
return int(p('0b[01]+')[2:], 2)
|
|
||||||
with p:
|
|
||||||
return int(p('0o[0-7]+')[2:], 8)
|
|
||||||
with p:
|
|
||||||
return int(p('0x[0-9a-fA-F]+')[2:], 16)
|
|
||||||
with p:
|
|
||||||
return float(p(r'-?(?:[1-9][0-9]*|0)?\.[0-9]+(?:[Ee][\+-]?[0-9]+)?|(?:[1-9][0-9]*|0)(?:\.[0-9]+)?[Ee][\+-]?[0-9]+'))
|
|
||||||
with p:
|
|
||||||
return int(p('-?[1-9][0-9]*|0'), 10)
|
|
||||||
|
|
||||||
with p:
|
|
||||||
return p(_p_string)
|
|
||||||
|
|
||||||
with p:
|
|
||||||
p(r'\[')
|
|
||||||
r = []
|
|
||||||
with p:
|
|
||||||
p.set('I', '')
|
|
||||||
r.append(p(_p_array_value))
|
|
||||||
with p:
|
|
||||||
while True:
|
|
||||||
with p:
|
|
||||||
p(_p_ews)
|
|
||||||
p(',')
|
|
||||||
rr = p(_p_array_value)
|
|
||||||
if not p:
|
|
||||||
p(_p_nl)
|
|
||||||
with p:
|
|
||||||
rr = p(_p_object)
|
|
||||||
if not p:
|
|
||||||
p(_p_ews)
|
|
||||||
rr = p(_p_simple_value)
|
|
||||||
r.append(rr)
|
|
||||||
p.commit()
|
|
||||||
with p:
|
|
||||||
p(_p_ews)
|
|
||||||
p(',')
|
|
||||||
p(_p_ews)
|
|
||||||
p(r'\]')
|
|
||||||
return r
|
|
||||||
|
|
||||||
p(r'\{')
|
|
||||||
|
|
||||||
r = {}
|
|
||||||
p(_p_ews)
|
|
||||||
with p:
|
|
||||||
p.set('I', '')
|
|
||||||
k, v = p(_p_flow_kv)
|
|
||||||
r[k] = v
|
|
||||||
with p:
|
|
||||||
while True:
|
|
||||||
p(_p_flow_obj_sep)
|
|
||||||
k, v = p(_p_flow_kv)
|
|
||||||
r[k] = v
|
|
||||||
p.commit()
|
|
||||||
p(_p_ews)
|
|
||||||
with p:
|
|
||||||
p(',')
|
|
||||||
p(_p_ews)
|
|
||||||
p(r'\}')
|
|
||||||
return r
|
|
||||||
|
|
||||||
def _p_line_kv(p):
|
|
||||||
k = p(_p_key)
|
|
||||||
p(_p_ws)
|
|
||||||
p(':')
|
|
||||||
p(_p_ws)
|
|
||||||
with p:
|
|
||||||
p(_p_nl)
|
|
||||||
p(p.get('I'))
|
|
||||||
return k, p(_p_indented_object)
|
|
||||||
with p:
|
|
||||||
return k, p(_p_line_object)
|
|
||||||
with p:
|
|
||||||
return k, p(_p_simple_value)
|
|
||||||
p(_p_nl)
|
|
||||||
p(p.get('I'))
|
|
||||||
p('[ \t]')
|
|
||||||
p(_p_ws)
|
|
||||||
return k, p(_p_simple_value)
|
|
||||||
|
|
||||||
def _p_line_object(p):
|
|
||||||
k, v = p(_p_line_kv)
|
|
||||||
r = { k: v }
|
|
||||||
with p:
|
|
||||||
while True:
|
|
||||||
p(_p_ws)
|
|
||||||
p(',')
|
|
||||||
p(_p_ws)
|
|
||||||
k, v = p(_p_line_kv)
|
|
||||||
r[k] = v # uniqueness
|
|
||||||
p.commit()
|
|
||||||
return r
|
|
||||||
|
|
||||||
def _p_object(p):
|
|
||||||
p.set('I', p.get('I') + p('[ \t]*'))
|
|
||||||
r = p(_p_line_object)
|
|
||||||
with p:
|
|
||||||
while True:
|
|
||||||
p(_p_ws)
|
|
||||||
with p:
|
|
||||||
p(',')
|
|
||||||
p(_p_nl)
|
|
||||||
p(p.get('I'))
|
|
||||||
rr = p(_p_line_object)
|
|
||||||
r.update(rr) # unqueness
|
|
||||||
p.commit()
|
|
||||||
return r
|
|
||||||
|
|
||||||
def _p_indented_object(p):
|
|
||||||
p.set('I', p.get('I') + p('[ \t]'))
|
|
||||||
return p(_p_object)
|
|
||||||
|
|
||||||
def _p_root(p):
|
|
||||||
with p:
|
|
||||||
p(_p_nl)
|
|
||||||
|
|
||||||
with p:
|
|
||||||
p.set('I', '')
|
|
||||||
r = p(_p_object)
|
|
||||||
p(_p_ws)
|
|
||||||
with p:
|
|
||||||
p(',')
|
|
||||||
|
|
||||||
if not p:
|
|
||||||
p(_p_ws)
|
|
||||||
r = p(_p_simple_value)
|
|
||||||
|
|
||||||
p(_p_ews)
|
|
||||||
p(p.eof)
|
|
||||||
return r
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
from .peg import peg, ParseError
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
import sys, re
|
|
||||||
|
|
||||||
class ParseError(Exception):
|
|
||||||
def __init__(self, msg, text, offset, line, col):
|
|
||||||
self.msg = msg
|
|
||||||
self.text = text
|
|
||||||
self.offset = offset
|
|
||||||
self.line = line
|
|
||||||
self.col = col
|
|
||||||
super(ParseError, self).__init__(msg, offset, line, col)
|
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
_basestr = basestring
|
|
||||||
else:
|
|
||||||
_basestr = str
|
|
||||||
|
|
||||||
def peg(s, r):
|
|
||||||
p = _Peg(s)
|
|
||||||
try:
|
|
||||||
return p(r)
|
|
||||||
except _UnexpectedError as e:
|
|
||||||
offset = max(p._errors)
|
|
||||||
err = p._errors[offset]
|
|
||||||
raise ParseError(err.msg, s, offset, err.line, err.col)
|
|
||||||
|
|
||||||
class _UnexpectedError(RuntimeError):
|
|
||||||
def __init__(self, state, expr):
|
|
||||||
self.state = state
|
|
||||||
self.expr = expr
|
|
||||||
|
|
||||||
class _PegState:
|
|
||||||
def __init__(self, pos, line, col):
|
|
||||||
self.pos = pos
|
|
||||||
self.line = line
|
|
||||||
self.col = col
|
|
||||||
self.vars = {}
|
|
||||||
self.commited = False
|
|
||||||
|
|
||||||
class _PegError:
|
|
||||||
def __init__(self, msg, line, col):
|
|
||||||
self.msg = msg
|
|
||||||
self.line = line
|
|
||||||
self.col = col
|
|
||||||
|
|
||||||
class _Peg:
|
|
||||||
def __init__(self, s):
|
|
||||||
self._s = s
|
|
||||||
self._states = [_PegState(0, 1, 1)]
|
|
||||||
self._errors = {}
|
|
||||||
self._re_cache = {}
|
|
||||||
|
|
||||||
def __call__(self, r, *args, **kw):
|
|
||||||
if isinstance(r, _basestr):
|
|
||||||
compiled = self._re_cache.get(r)
|
|
||||||
if not compiled:
|
|
||||||
compiled = re.compile(r)
|
|
||||||
self._re_cache[r] = compiled
|
|
||||||
st = self._states[-1]
|
|
||||||
m = compiled.match(self._s[st.pos:])
|
|
||||||
if not m:
|
|
||||||
self.error(expr=r, err=kw.get('err'))
|
|
||||||
|
|
||||||
ms = m.group(0)
|
|
||||||
st.pos += len(ms)
|
|
||||||
nl_pos = ms.rfind('\n')
|
|
||||||
if nl_pos < 0:
|
|
||||||
st.col += len(ms)
|
|
||||||
else:
|
|
||||||
st.col = len(ms) - nl_pos
|
|
||||||
st.line += ms[:nl_pos].count('\n') + 1
|
|
||||||
return ms
|
|
||||||
else:
|
|
||||||
kw.pop('err', None)
|
|
||||||
return r(self, *args, **kw)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
pos = self._states[-1].pos
|
|
||||||
vars = {}
|
|
||||||
for st in self._states:
|
|
||||||
vars.update(st.vars)
|
|
||||||
return '_Peg(%r, %r)' % (self._s[:pos] + '*' + self._s[pos:], vars)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def eof(p):
|
|
||||||
if p._states[-1].pos != len(p._s):
|
|
||||||
p.error()
|
|
||||||
|
|
||||||
def error(self, err=None, expr=None):
|
|
||||||
st = self._states[-1]
|
|
||||||
if err is None:
|
|
||||||
err = 'expected {!r}, found {!r}'.format(expr, self._s[st.pos:st.pos+4])
|
|
||||||
self._errors[st.pos] = _PegError(err, st.line, st.col)
|
|
||||||
raise _UnexpectedError(st, expr)
|
|
||||||
|
|
||||||
def get(self, key, default=None):
|
|
||||||
for state in self._states[::-1]:
|
|
||||||
if key in state.vars:
|
|
||||||
return state.vars[key][0]
|
|
||||||
return default
|
|
||||||
|
|
||||||
def set(self, key, value):
|
|
||||||
self._states[-1].vars[key] = value, False
|
|
||||||
|
|
||||||
def set_global(self, key, value):
|
|
||||||
self._states[-1].vars[key] = value, True
|
|
||||||
|
|
||||||
def opt(self, *args, **kw):
|
|
||||||
with self:
|
|
||||||
return self(*args, **kw)
|
|
||||||
|
|
||||||
def not_(self, s, *args, **kw):
|
|
||||||
with self:
|
|
||||||
self(s)
|
|
||||||
self.error()
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
self._states[-1].committed = False
|
|
||||||
self._states.append(_PegState(self._states[-1].pos, self._states[-1].line, self._states[-1].col))
|
|
||||||
|
|
||||||
def __exit__(self, type, value, traceback):
|
|
||||||
if type is None:
|
|
||||||
self.commit()
|
|
||||||
self._states.pop()
|
|
||||||
return type == _UnexpectedError
|
|
||||||
|
|
||||||
def commit(self):
|
|
||||||
cur = self._states[-1]
|
|
||||||
prev = self._states[-2]
|
|
||||||
|
|
||||||
for key in cur.vars:
|
|
||||||
val, g = cur.vars[key]
|
|
||||||
if not g:
|
|
||||||
continue
|
|
||||||
if key in prev.vars:
|
|
||||||
prev.vars[key] = val, prev.vars[key][1]
|
|
||||||
else:
|
|
||||||
prev.vars[key] = val, True
|
|
||||||
|
|
||||||
prev.pos = cur.pos
|
|
||||||
prev.line = cur.line
|
|
||||||
prev.col = cur.col
|
|
||||||
prev.committed = True
|
|
||||||
|
|
||||||
def __nonzero__(self):
|
|
||||||
return self._states[-1].committed
|
|
||||||
|
|
||||||
__bool__ = __nonzero__
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
import re, json, sys
|
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
def _is_num(o):
|
|
||||||
return isinstance(o, int) or isinstance(o, long) or isinstance(o, float)
|
|
||||||
def _stringify(o):
|
|
||||||
if isinstance(o, str):
|
|
||||||
return unicode(o)
|
|
||||||
if isinstance(o, unicode):
|
|
||||||
return o
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
def _is_num(o):
|
|
||||||
return isinstance(o, int) or isinstance(o, float)
|
|
||||||
def _stringify(o):
|
|
||||||
if isinstance(o, bytes):
|
|
||||||
return o.decode()
|
|
||||||
if isinstance(o, str):
|
|
||||||
return o
|
|
||||||
return None
|
|
||||||
|
|
||||||
_id_re = re.compile(r'[$a-zA-Z_][$0-9a-zA-Z_]*\Z')
|
|
||||||
|
|
||||||
class CSONEncoder:
|
|
||||||
def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
|
|
||||||
indent=None, default=None):
|
|
||||||
self._skipkeys = skipkeys
|
|
||||||
self._ensure_ascii = ensure_ascii
|
|
||||||
self._allow_nan = allow_nan
|
|
||||||
self._sort_keys = sort_keys
|
|
||||||
self._indent = ' ' * (indent or 4)
|
|
||||||
self._default = default
|
|
||||||
if check_circular:
|
|
||||||
self._obj_stack = set()
|
|
||||||
else:
|
|
||||||
self._obj_stack = None
|
|
||||||
|
|
||||||
def _format_simple_val(self, o):
|
|
||||||
if o is None:
|
|
||||||
return 'null'
|
|
||||||
if isinstance(o, bool):
|
|
||||||
return 'true' if o else 'false'
|
|
||||||
if _is_num(o):
|
|
||||||
return str(o)
|
|
||||||
s = _stringify(o)
|
|
||||||
if s is not None:
|
|
||||||
return self._escape_string(s)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _escape_string(self, s):
|
|
||||||
r = json.dumps(s, ensure_ascii=self._ensure_ascii)
|
|
||||||
return u"'{}'".format(r[1:-1].replace("'", r"\'"))
|
|
||||||
|
|
||||||
def _escape_key(self, s):
|
|
||||||
if s is None or isinstance(s, bool) or _is_num(s):
|
|
||||||
s = str(s)
|
|
||||||
s = _stringify(s)
|
|
||||||
if s is None:
|
|
||||||
if self._skipkeys:
|
|
||||||
return None
|
|
||||||
raise TypeError('keys must be a string')
|
|
||||||
if not _id_re.match(s):
|
|
||||||
return self._escape_string(s)
|
|
||||||
return s
|
|
||||||
|
|
||||||
def _push_obj(self, o):
|
|
||||||
if self._obj_stack is not None:
|
|
||||||
if id(o) in self._obj_stack:
|
|
||||||
raise ValueError('Circular reference detected')
|
|
||||||
self._obj_stack.add(id(o))
|
|
||||||
|
|
||||||
def _pop_obj(self, o):
|
|
||||||
if self._obj_stack is not None:
|
|
||||||
self._obj_stack.remove(id(o))
|
|
||||||
|
|
||||||
def _encode(self, o, obj_val=False, indent='', force_flow=False):
|
|
||||||
if isinstance(o, list):
|
|
||||||
if not o:
|
|
||||||
if obj_val:
|
|
||||||
yield ' []\n'
|
|
||||||
else:
|
|
||||||
yield indent
|
|
||||||
yield '[]\n'
|
|
||||||
else:
|
|
||||||
if obj_val:
|
|
||||||
yield ' [\n'
|
|
||||||
else:
|
|
||||||
yield indent
|
|
||||||
yield '[\n'
|
|
||||||
indent = indent + self._indent
|
|
||||||
self._push_obj(o)
|
|
||||||
for v in o:
|
|
||||||
for chunk in self._encode(v, obj_val=False, indent=indent, force_flow=True):
|
|
||||||
yield chunk
|
|
||||||
self._pop_obj(o)
|
|
||||||
yield indent[:-len(self._indent)]
|
|
||||||
yield ']\n'
|
|
||||||
elif isinstance(o, dict):
|
|
||||||
items = [(self._escape_key(k), v) for k, v in o.items()]
|
|
||||||
if self._skipkeys:
|
|
||||||
items = [(k, v) for k, v in items if k is not None]
|
|
||||||
if self._sort_keys:
|
|
||||||
items.sort()
|
|
||||||
if force_flow or not items:
|
|
||||||
if not items:
|
|
||||||
if obj_val:
|
|
||||||
yield ' {}\n'
|
|
||||||
else:
|
|
||||||
yield indent
|
|
||||||
yield '{}\n'
|
|
||||||
else:
|
|
||||||
if obj_val:
|
|
||||||
yield ' {\n'
|
|
||||||
else:
|
|
||||||
yield indent
|
|
||||||
yield '{\n'
|
|
||||||
indent = indent + self._indent
|
|
||||||
self._push_obj(o)
|
|
||||||
for k, v in items:
|
|
||||||
yield indent
|
|
||||||
yield k
|
|
||||||
yield ':'
|
|
||||||
for chunk in self._encode(v, obj_val=True, indent=indent + self._indent, force_flow=False):
|
|
||||||
yield chunk
|
|
||||||
self._pop_obj(o)
|
|
||||||
yield indent[:-len(self._indent)]
|
|
||||||
yield '}\n'
|
|
||||||
else:
|
|
||||||
if obj_val:
|
|
||||||
yield '\n'
|
|
||||||
self._push_obj(o)
|
|
||||||
for k, v in items:
|
|
||||||
yield indent
|
|
||||||
yield k
|
|
||||||
yield ':'
|
|
||||||
for chunk in self._encode(v, obj_val=True, indent=indent + self._indent, force_flow=False):
|
|
||||||
yield chunk
|
|
||||||
self._pop_obj(o)
|
|
||||||
else:
|
|
||||||
v = self._format_simple_val(o)
|
|
||||||
if v is None:
|
|
||||||
self._push_obj(o)
|
|
||||||
v = self.default(o)
|
|
||||||
for chunk in self._encode(v, obj_val=obj_val, indent=indent, force_flow=force_flow):
|
|
||||||
yield chunk
|
|
||||||
self._pop_obj(o)
|
|
||||||
else:
|
|
||||||
if obj_val:
|
|
||||||
yield ' '
|
|
||||||
else:
|
|
||||||
yield indent
|
|
||||||
yield v
|
|
||||||
yield '\n'
|
|
||||||
|
|
||||||
def iterencode(self, o):
|
|
||||||
return self._encode(o)
|
|
||||||
|
|
||||||
def encode(self, o):
|
|
||||||
return ''.join(self.iterencode(o))
|
|
||||||
|
|
||||||
def default(self, o):
|
|
||||||
if self._default is None:
|
|
||||||
raise TypeError('Cannot serialize an object of type {}'.format(type(o).__name__))
|
|
||||||
return self._default(o)
|
|
||||||
|
|
||||||
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None,
|
|
||||||
indent=None, default=None, sort_keys=False, **kw):
|
|
||||||
if indent is None and cls is None:
|
|
||||||
return json.dump(obj, fp, skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular,
|
|
||||||
allow_nan=allow_nan, default=default, sort_keys=sort_keys, separators=(',', ':'))
|
|
||||||
|
|
||||||
if cls is None:
|
|
||||||
cls = CSONEncoder
|
|
||||||
encoder = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular,
|
|
||||||
allow_nan=allow_nan, sort_keys=sort_keys, indent=indent, default=default, **kw)
|
|
||||||
|
|
||||||
for chunk in encoder.iterencode(obj):
|
|
||||||
fp.write(chunk)
|
|
||||||
|
|
||||||
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None,
|
|
||||||
default=None, sort_keys=False, **kw):
|
|
||||||
if indent is None and cls is None:
|
|
||||||
return json.dumps(obj, skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular,
|
|
||||||
allow_nan=allow_nan, default=default, sort_keys=sort_keys, separators=(',', ':'))
|
|
||||||
|
|
||||||
if cls is None:
|
|
||||||
cls = CSONEncoder
|
|
||||||
encoder = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular,
|
|
||||||
allow_nan=allow_nan, sort_keys=sort_keys, indent=indent, default=default, **kw)
|
|
||||||
|
|
||||||
return encoder.encode(obj)
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Snippets Completer",
|
|
||||||
"author": "ITDominator",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"support": "",
|
|
||||||
"requests": {}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.dto.base_event import BaseEvent
|
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
|
||||||
|
|
||||||
from .provider import Provider
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginCode):
|
|
||||||
def __init__(self):
|
|
||||||
super(Plugin, self).__init__()
|
|
||||||
|
|
||||||
self.provider: Provider = None
|
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
self.provider = Provider()
|
|
||||||
|
|
||||||
event = Event_Factory.create_event(
|
|
||||||
"register_provider",
|
|
||||||
provider_name = "Snippets Completer",
|
|
||||||
provider = self.provider,
|
|
||||||
language_ids = []
|
|
||||||
)
|
|
||||||
self.message_to("completion", event)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
...
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GObject
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from .provider_response_cache import ProviderResponseCache
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Provider(GObject.GObject, GtkSource.CompletionProvider):
|
|
||||||
"""
|
|
||||||
This is a Snippits Completion Provider.
|
|
||||||
# NOTE: used information from here --> https://warroom.rsmus.com/do-that-auto-complete/
|
|
||||||
"""
|
|
||||||
__gtype_name__ = 'SnippetsCompletionProvider'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Provider, self).__init__()
|
|
||||||
|
|
||||||
self.response_cache: ProviderResponseCache = ProviderResponseCache()
|
|
||||||
|
|
||||||
|
|
||||||
def do_get_name(self):
|
|
||||||
return 'Snippits Completion'
|
|
||||||
|
|
||||||
def do_match(self, context):
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
if not word or len(word) < 2: return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def do_get_priority(self):
|
|
||||||
return 2
|
|
||||||
|
|
||||||
def do_activate_proposal(self, proposal, iter_):
|
|
||||||
buffer = iter_.get_buffer()
|
|
||||||
# Note: Flag mostly intended for SourceViewsMultiInsertState
|
|
||||||
# to insure marker processes inserted text correctly.
|
|
||||||
buffer.is_processing_completion = True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_get_activation(self):
|
|
||||||
""" The context for when a provider will show results """
|
|
||||||
# return GtkSource.CompletionActivation.NONE
|
|
||||||
return GtkSource.CompletionActivation.USER_REQUESTED
|
|
||||||
# return GtkSource.CompletionActivation.INTERACTIVE
|
|
||||||
|
|
||||||
def do_populate(self, context):
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
results = self.response_cache.filter(word)
|
|
||||||
proposals = []
|
|
||||||
|
|
||||||
for entry in results:
|
|
||||||
proposals.append(
|
|
||||||
self.response_cache.create_completion_item(
|
|
||||||
entry["label"],
|
|
||||||
entry["text"],
|
|
||||||
entry["info"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
context.add_proposals(self, proposals, True)
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
from os import path
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GLib
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Code_Event_Types
|
|
||||||
|
|
||||||
from core.widgets.code.completion_providers.provider_response_cache_base import ProviderResponseCacheBase
|
|
||||||
|
|
||||||
from . import cson
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProviderResponseCache(ProviderResponseCacheBase):
|
|
||||||
def __init__(self):
|
|
||||||
super(ProviderResponseCache, self).__init__()
|
|
||||||
|
|
||||||
self.matchers: dict = {}
|
|
||||||
|
|
||||||
self.load_snippets()
|
|
||||||
|
|
||||||
|
|
||||||
def load_snippets(self):
|
|
||||||
fpath = path.join(path.dirname(path.realpath(__file__)), "snippets.cson")
|
|
||||||
with open(fpath, 'rb') as f:
|
|
||||||
self.snippets = cson.load(f)
|
|
||||||
for group in self.snippets:
|
|
||||||
self.snippets[group]
|
|
||||||
for entry in self.snippets[group]:
|
|
||||||
data = self.snippets[group][entry]
|
|
||||||
self.matchers[ data["prefix"] ] = {
|
|
||||||
"label": entry,
|
|
||||||
"text": data["body"],
|
|
||||||
"info": GLib.markup_escape_text( data["body"] )
|
|
||||||
}
|
|
||||||
|
|
||||||
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_save(self, event: Code_Event_Types.SavedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def filter(self, word: str) -> list[dict]:
|
|
||||||
response: list[dict] = []
|
|
||||||
|
|
||||||
for entry in self.matchers:
|
|
||||||
if not word in entry: continue
|
|
||||||
data = self.matchers[entry]
|
|
||||||
response.append(data)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def filter_with_context(self, context: GtkSource.CompletionContext) -> list[dict]:
|
|
||||||
response: list[dict] = []
|
|
||||||
|
|
||||||
return response
|
|
||||||
@@ -1,614 +0,0 @@
|
|||||||
# Your snippets
|
|
||||||
#
|
|
||||||
# Atom snippets allow you to enter a simple prefix in the editor and hit tab to
|
|
||||||
# expand the prefix into a larger code block with templated values.
|
|
||||||
#
|
|
||||||
# You can create a new snippet in this file by typing "snip" and then hitting
|
|
||||||
# tab.
|
|
||||||
#
|
|
||||||
# An example CoffeeScript snippet to expand log to console.log:
|
|
||||||
#
|
|
||||||
# '.source.coffee':
|
|
||||||
# 'Console log':
|
|
||||||
# 'prefix': 'log'
|
|
||||||
# 'body': 'console.log $1'
|
|
||||||
#
|
|
||||||
# Each scope (e.g. '.source.coffee' above) can only be declared once.
|
|
||||||
#
|
|
||||||
# This file uses CoffeeScript Object Notation (CSON).
|
|
||||||
# If you are unfamiliar with CSON, you can read more about it in the
|
|
||||||
# Atom Flight Manual:
|
|
||||||
# http://flight-manual.atom.io/using-atom/sections/basic-customization/#_cson
|
|
||||||
|
|
||||||
|
|
||||||
### HTML SNIPPETS ###
|
|
||||||
'.text.html.basic':
|
|
||||||
|
|
||||||
'HTML Template':
|
|
||||||
'prefix': 'html'
|
|
||||||
'body': """<!DOCTYPE html>
|
|
||||||
<html lang="en" dir="ltr">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title></title>
|
|
||||||
<link rel="shortcut icon" href="fave_icon.png">
|
|
||||||
<link rel="stylesheet" href="resources/css/base.css">
|
|
||||||
<link rel="stylesheet" href="resources/css/main.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script src="resources/js/.js" charset="utf-8"></script>
|
|
||||||
<script src="resources/js/.js" charset="utf-8"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
'Canvas Tag':
|
|
||||||
'prefix': 'canvas'
|
|
||||||
'body': """<canvas id="canvas" width="800" height="600" style="border:1px solid #c3c3c3;"></canvas>"""
|
|
||||||
|
|
||||||
'Img Tag':
|
|
||||||
'prefix': 'img'
|
|
||||||
'body': """<img class="" src="" alt="" />"""
|
|
||||||
|
|
||||||
'Br Tag':
|
|
||||||
'prefix': 'br'
|
|
||||||
'body': """<br/>"""
|
|
||||||
|
|
||||||
'Hr Tag':
|
|
||||||
'prefix': 'hr'
|
|
||||||
'body': """<hr/>"""
|
|
||||||
|
|
||||||
'Server Side Events':
|
|
||||||
'prefix': 'sse'
|
|
||||||
'body': """// SSE events if supported
|
|
||||||
if(typeof(EventSource) !== "undefined") {
|
|
||||||
let source = new EventSource("resources/php/sse.php");
|
|
||||||
source.onmessage = (event) => {
|
|
||||||
if (event.data === "<yourDataStringToLookFor>") {
|
|
||||||
// code here
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
console.log("SSE Not Supported In Browser...");
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
'AJAX Template Function':
|
|
||||||
'prefix': 'ajax template'
|
|
||||||
'body': """const doAjax = async (actionPath, data) => {
|
|
||||||
let xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
if (this.readyState === 4 && this.status === 200) {
|
|
||||||
if (this.responseText != null) { // this.responseXML if getting XML fata
|
|
||||||
handleReturnData(JSON.parse(this.responseText));
|
|
||||||
} else {
|
|
||||||
console.log("No content returned. Check the file path.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xhttp.open("POST", actionPath, true);
|
|
||||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
|
||||||
// Force return to be JSON NOTE: Use application/xml to force XML
|
|
||||||
xhttp.overrideMimeType('application/json');
|
|
||||||
xhttp.send(data);
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
'CSS Message Colors':
|
|
||||||
'prefix': 'css colors'
|
|
||||||
'body': """.error { color: rgb(255, 0, 0); }
|
|
||||||
.warning { color: rgb(255, 168, 0); }
|
|
||||||
.success { color: rgb(136, 204, 39); }
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
### JS SNIPPETS ###
|
|
||||||
'.source.js':
|
|
||||||
|
|
||||||
'Server Side Events':
|
|
||||||
'prefix': 'sse'
|
|
||||||
'body': """// SSE events if supported
|
|
||||||
if(typeof(EventSource) !== "undefined") {
|
|
||||||
let source = new EventSource("resources/php/sse.php");
|
|
||||||
source.onmessage = (event) => {
|
|
||||||
if (event.data === "<yourDataStringToLookFor>") {
|
|
||||||
// code here
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
console.log("SSE Not Supported In Browser...");
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
'AJAX Template Function':
|
|
||||||
'prefix': 'ajax template'
|
|
||||||
'body': """const doAjax = async (actionPath, data) => {
|
|
||||||
let xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onreadystatechange = function() {
|
|
||||||
if (this.readyState === 4 && this.status === 200) {
|
|
||||||
if (this.responseText != null) { // this.responseXML if getting XML fata
|
|
||||||
handleReturnData(JSON.parse(this.responseText));
|
|
||||||
} else {
|
|
||||||
console.log("No content returned. Check the file path.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xhttp.open("POST", actionPath, true);
|
|
||||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
|
||||||
// Force return to be JSON NOTE: Use application/xml to force XML
|
|
||||||
xhttp.overrideMimeType('application/json');
|
|
||||||
xhttp.send(data);
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
'SE6 Function':
|
|
||||||
'prefix': 'function se6'
|
|
||||||
'body': """const funcName = (arg = "") => {
|
|
||||||
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
### CSS SNIPPETS ###
|
|
||||||
'.source.css':
|
|
||||||
|
|
||||||
'CSS Message Colors':
|
|
||||||
'prefix': 'css colors'
|
|
||||||
'body': """.error { color: rgb(255, 0, 0); }
|
|
||||||
.warning { color: rgb(255, 168, 0); }
|
|
||||||
.success { color: rgb(136, 204, 39); }
|
|
||||||
"""
|
|
||||||
|
|
||||||
### PHP SNIPPETS ###
|
|
||||||
'.text.html.php':
|
|
||||||
|
|
||||||
'SSE PHP':
|
|
||||||
'prefix': 'sse php'
|
|
||||||
'body': """<?php
|
|
||||||
// Start the session
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
header('Content-Type: text/event-stream');
|
|
||||||
header('Cache-Control: no-cache');
|
|
||||||
|
|
||||||
echo "data:dataToReturn\\\\n\\\\n";
|
|
||||||
|
|
||||||
flush();
|
|
||||||
?>
|
|
||||||
"""
|
|
||||||
|
|
||||||
'PHP Template':
|
|
||||||
'prefix': 'php'
|
|
||||||
'body': """<?php
|
|
||||||
// Start the session
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
|
|
||||||
// Determin action
|
|
||||||
chdir("../../"); // Note: If in resources/php/
|
|
||||||
if (isset($_POST['yourPostID'])) {
|
|
||||||
// code here
|
|
||||||
} else {
|
|
||||||
$message = "Server: [Error] --> Illegal Access Method!";
|
|
||||||
serverMessage("error", $message);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
"""
|
|
||||||
'HTML Template':
|
|
||||||
'prefix': 'html'
|
|
||||||
'body': """<!DOCTYPE html>
|
|
||||||
<html lang="en" dir="ltr">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title></title>
|
|
||||||
<link rel="shortcut icon" href="fave_icon.png">
|
|
||||||
<link rel="stylesheet" href="resources/css/base.css">
|
|
||||||
<link rel="stylesheet" href="resources/css/main.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script src="resources/js/.js" charset="utf-8"></script>
|
|
||||||
<script src="resources/js/.js" charset="utf-8"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
### BASH SNIPPETS ###
|
|
||||||
'.source.shell':
|
|
||||||
|
|
||||||
'Bash or Shell Template':
|
|
||||||
'prefix': 'bash template'
|
|
||||||
'body': """#!/bin/bash
|
|
||||||
|
|
||||||
# . CONFIG.sh
|
|
||||||
|
|
||||||
# set -o xtrace ## To debug scripts
|
|
||||||
# set -o errexit ## To exit on error
|
|
||||||
# set -o errunset ## To exit if a variable is referenced but not set
|
|
||||||
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
echo "Working Dir: " $(pwd)
|
|
||||||
|
|
||||||
file="$1"
|
|
||||||
if [ -z "${file}" ]; then
|
|
||||||
echo "ERROR: No file argument supplied..."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f "${file}" ]]; then
|
|
||||||
echo "SUCCESS: The path and file exists!"
|
|
||||||
else
|
|
||||||
echo "ERROR: The path or file '${file}' does NOT exist..."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
main "$@";
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
'Bash or Shell Config':
|
|
||||||
'prefix': 'bash config'
|
|
||||||
'body': """#!/bin/bash
|
|
||||||
|
|
||||||
shopt -s expand_aliases
|
|
||||||
|
|
||||||
alias echo="echo -e"
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
### PYTHON SNIPPETS ###
|
|
||||||
'.source.python':
|
|
||||||
|
|
||||||
'Glade __main__ Class Template':
|
|
||||||
'prefix': 'glade __main__ class'
|
|
||||||
'body': """#!/usr/bin/python3
|
|
||||||
|
|
||||||
|
|
||||||
# Python imports
|
|
||||||
import argparse
|
|
||||||
import faulthandler
|
|
||||||
import traceback
|
|
||||||
import signal
|
|
||||||
from setproctitle import setproctitle
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from app import Application
|
|
||||||
|
|
||||||
|
|
||||||
def run():
|
|
||||||
try:
|
|
||||||
setproctitle('<replace this>')
|
|
||||||
faulthandler.enable() # For better debug info
|
|
||||||
|
|
||||||
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, Gtk.main_quit)
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
# Add long and short arguments
|
|
||||||
parser.add_argument("--debug", "-d", default="false", help="Do extra console messaging.")
|
|
||||||
parser.add_argument("--trace-debug", "-td", default="false", help="Disable saves, ignore IPC lock, do extra console messaging.")
|
|
||||||
parser.add_argument("--no-plugins", "-np", default="false", help="Do not load plugins.")
|
|
||||||
|
|
||||||
parser.add_argument("--new-tab", "-t", default="", help="Open a file into new tab.")
|
|
||||||
parser.add_argument("--new-window", "-w", default="", help="Open a file into a new window.")
|
|
||||||
|
|
||||||
# Read arguments (If any...)
|
|
||||||
args, unknownargs = parser.parse_known_args()
|
|
||||||
|
|
||||||
main = Application(args, unknownargs)
|
|
||||||
Gtk.main()
|
|
||||||
except Exception as e:
|
|
||||||
traceback.print_exc()
|
|
||||||
quit()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
''' Set process title, get arguments, and create GTK main thread. '''
|
|
||||||
run()
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
'Glade __main__ Testing Template':
|
|
||||||
'prefix': 'glade testing class'
|
|
||||||
'body': """#!/usr/bin/python3
|
|
||||||
|
|
||||||
|
|
||||||
# Python imports
|
|
||||||
import traceback
|
|
||||||
import faulthandler
|
|
||||||
import signal
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
|
|
||||||
|
|
||||||
app_name = "Gtk Quick Test"
|
|
||||||
|
|
||||||
|
|
||||||
class Application(Gtk.ApplicationWindow):
|
|
||||||
def __init__(self):
|
|
||||||
super(Application, self).__init__()
|
|
||||||
self._setup_styling()
|
|
||||||
self._setup_signals()
|
|
||||||
self._load_widgets()
|
|
||||||
|
|
||||||
self.add(Gtk.Box())
|
|
||||||
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
|
|
||||||
def _setup_styling(self):
|
|
||||||
self.set_default_size(1670, 830)
|
|
||||||
self.set_title(f"{app_name}")
|
|
||||||
# self.set_icon_from_file( settings.get_window_icon() )
|
|
||||||
self.set_gravity(5) # 5 = CENTER
|
|
||||||
self.set_position(1) # 1 = CENTER, 4 = CENTER_ALWAYS
|
|
||||||
|
|
||||||
def _setup_signals(self):
|
|
||||||
self.connect("delete-event", Gtk.main_quit)
|
|
||||||
|
|
||||||
|
|
||||||
def _load_widgets(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def run():
|
|
||||||
try:
|
|
||||||
faulthandler.enable() # For better debug info
|
|
||||||
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, Gtk.main_quit)
|
|
||||||
|
|
||||||
main = Application()
|
|
||||||
Gtk.main()
|
|
||||||
except Exception as e:
|
|
||||||
traceback.print_exc()
|
|
||||||
quit()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
''' Set process title, get arguments, and create GTK main thread. '''
|
|
||||||
run()
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
'Glade _init_ Class Template':
|
|
||||||
'prefix': 'glade __init__ class'
|
|
||||||
'body': """# Python imports
|
|
||||||
import inspect
|
|
||||||
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from utils import Settings
|
|
||||||
from signal_classes import CrossClassSignals
|
|
||||||
|
|
||||||
|
|
||||||
class Main:
|
|
||||||
def __init__(self, args):
|
|
||||||
settings = Settings()
|
|
||||||
builder = settings.returnBuilder()
|
|
||||||
|
|
||||||
# Gets the methods from the classes and sets to handler.
|
|
||||||
# Then, builder connects to any signals it needs.
|
|
||||||
classes = [CrossClassSignals(settings)]
|
|
||||||
|
|
||||||
handlers = {}
|
|
||||||
for c in classes:
|
|
||||||
methods = inspect.getmembers(c, predicate=inspect.ismethod)
|
|
||||||
handlers.update(methods)
|
|
||||||
|
|
||||||
builder.connect_signals(handlers)
|
|
||||||
window = settings.createWindow()
|
|
||||||
window.show()
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
'Class Method':
|
|
||||||
'prefix': 'def1'
|
|
||||||
'body': """
|
|
||||||
def fname(self):
|
|
||||||
...
|
|
||||||
"""
|
|
||||||
|
|
||||||
'Gtk Class Method':
|
|
||||||
'prefix': 'def2'
|
|
||||||
'body': """
|
|
||||||
def fname(self, widget, eve):
|
|
||||||
...
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
'Python Glade Settings Template':
|
|
||||||
'prefix': 'glade settings class'
|
|
||||||
'body': """# Python imports
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi, cairo
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
gi.require_version('Gdk', '3.0')
|
|
||||||
|
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import Gdk
|
|
||||||
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
|
|
||||||
|
|
||||||
class Settings:
|
|
||||||
def __init__(self):
|
|
||||||
self.SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__)) + "/"
|
|
||||||
self.builder = Gtk.Builder()
|
|
||||||
self.builder.add_from_file(self.SCRIPT_PTH + "../resources/Main_Window.glade")
|
|
||||||
|
|
||||||
# 'Filters'
|
|
||||||
self.office = ('.doc', '.docx', '.xls', '.xlsx', '.xlt', '.xltx', '.xlm',
|
|
||||||
'.ppt', 'pptx', '.pps', '.ppsx', '.odt', '.rtf')
|
|
||||||
self.vids = ('.mkv', '.avi', '.flv', '.mov', '.m4v', '.mpg', '.wmv',
|
|
||||||
'.mpeg', '.mp4', '.webm')
|
|
||||||
self.txt = ('.txt', '.text', '.sh', '.cfg', '.conf')
|
|
||||||
self.music = ('.psf', '.mp3', '.ogg' , '.flac')
|
|
||||||
self.images = ('.png', '.jpg', '.jpeg', '.gif')
|
|
||||||
self.pdf = ('.pdf')
|
|
||||||
|
|
||||||
|
|
||||||
def createWindow(self):
|
|
||||||
# Get window and connect signals
|
|
||||||
window = self.builder.get_object("Main_Window")
|
|
||||||
window.connect("delete-event", gtk.main_quit)
|
|
||||||
self.setWindowData(window, False)
|
|
||||||
return window
|
|
||||||
|
|
||||||
def setWindowData(self, window, paintable):
|
|
||||||
screen = window.get_screen()
|
|
||||||
visual = screen.get_rgba_visual()
|
|
||||||
|
|
||||||
if visual != None and screen.is_composited():
|
|
||||||
window.set_visual(visual)
|
|
||||||
|
|
||||||
# bind css file
|
|
||||||
cssProvider = gtk.CssProvider()
|
|
||||||
cssProvider.load_from_path(self.SCRIPT_PTH + '../resources/stylesheet.css')
|
|
||||||
screen = Gdk.Screen.get_default()
|
|
||||||
styleContext = Gtk.StyleContext()
|
|
||||||
styleContext.add_provider_for_screen(screen, cssProvider, gtk.STYLE_PROVIDER_PRIORITY_USER)
|
|
||||||
|
|
||||||
window.set_app_paintable(paintable)
|
|
||||||
if paintable:
|
|
||||||
window.connect("draw", self.area_draw)
|
|
||||||
|
|
||||||
def getMonitorData(self):
|
|
||||||
screen = self.builder.get_object("Main_Window").get_screen()
|
|
||||||
monitors = []
|
|
||||||
for m in range(screen.get_n_monitors()):
|
|
||||||
monitors.append(screen.get_monitor_geometry(m))
|
|
||||||
|
|
||||||
for monitor in monitors:
|
|
||||||
print(str(monitor.width) + "x" + str(monitor.height) + "+" + str(monitor.x) + "+" + str(monitor.y))
|
|
||||||
|
|
||||||
return monitors
|
|
||||||
|
|
||||||
def area_draw(self, widget, cr):
|
|
||||||
cr.set_source_rgba(0, 0, 0, 0.54)
|
|
||||||
cr.set_operator(cairo.OPERATOR_SOURCE)
|
|
||||||
cr.paint()
|
|
||||||
cr.set_operator(cairo.OPERATOR_OVER)
|
|
||||||
|
|
||||||
|
|
||||||
def returnBuilder(self): return self.builder
|
|
||||||
|
|
||||||
# Filter returns
|
|
||||||
def returnOfficeFilter(self): return self.office
|
|
||||||
def returnVidsFilter(self): return self.vids
|
|
||||||
def returnTextFilter(self): return self.txt
|
|
||||||
def returnMusicFilter(self): return self.music
|
|
||||||
def returnImagesFilter(self): return self.images
|
|
||||||
def returnPdfFilter(self): return self.pdf
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
'Python Glade CrossClassSignals Template':
|
|
||||||
'prefix': 'glade crossClassSignals class'
|
|
||||||
'body': """# Python imports
|
|
||||||
import threading
|
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
|
|
||||||
|
|
||||||
def threaded(fn):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
threading.Thread(target=fn, args=args, kwargs=kwargs).start()
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class CrossClassSignals:
|
|
||||||
def __init__(self, settings):
|
|
||||||
self.settings = settings
|
|
||||||
self.builder = self.settings.returnBuilder()
|
|
||||||
|
|
||||||
|
|
||||||
def getClipboardData(self):
|
|
||||||
proc = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout=subprocess.PIPE)
|
|
||||||
retcode = proc.wait()
|
|
||||||
data = proc.stdout.read()
|
|
||||||
return data.decode("utf-8").strip()
|
|
||||||
|
|
||||||
def setClipboardData(self, data):
|
|
||||||
proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
|
|
||||||
proc.stdin.write(data)
|
|
||||||
proc.stdin.close()
|
|
||||||
retcode = proc.wait()
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
'Python Glade Generic Template':
|
|
||||||
'prefix': 'glade generic class'
|
|
||||||
'body': """# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
|
|
||||||
|
|
||||||
class GenericClass:
|
|
||||||
def __init__(self):
|
|
||||||
super(GenericClass, self).__init__()
|
|
||||||
|
|
||||||
self._setup_styling()
|
|
||||||
self._setup_signals()
|
|
||||||
self._subscribe_to_events()
|
|
||||||
self._load_widgets()
|
|
||||||
|
|
||||||
|
|
||||||
def _setup_styling(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def _setup_signals(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
def _subscribe_to_events(self):
|
|
||||||
event_system.subscribe("handle_file_from_ipc", self.handle_file_from_ipc)
|
|
||||||
|
|
||||||
def _load_widgets(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Module
|
|
||||||
"""
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
"""
|
|
||||||
Pligin Package
|
|
||||||
"""
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GObject
|
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from .provider_response_cache import ProviderResponseCache
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Provider(GtkSource.CompletionWords):
|
|
||||||
"""
|
|
||||||
This is a Words Completion Provider.
|
|
||||||
# NOTE: used information from here --> https://warroom.rsmus.com/do-that-auto-complete/
|
|
||||||
"""
|
|
||||||
__gtype_name__ = 'WordsCompletionProvider'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Provider, self).__init__()
|
|
||||||
|
|
||||||
self.response_cache: ProviderResponseCache = ProviderResponseCache()
|
|
||||||
|
|
||||||
|
|
||||||
def do_get_name(self):
|
|
||||||
return 'Words Completion'
|
|
||||||
|
|
||||||
def do_match(self, context):
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
if not word or len(word) < 2: return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def do_get_priority(self):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def do_activate_proposal(self, proposal, iter_):
|
|
||||||
buffer = iter_.get_buffer()
|
|
||||||
# Note: Flag mostly intended for SourceViewsMultiInsertState
|
|
||||||
# to insure marker processes inserted text correctly.
|
|
||||||
buffer.is_processing_completion = True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_get_activation(self):
|
|
||||||
""" The context for when a provider will show results """
|
|
||||||
# return GtkSource.CompletionActivation.NONE
|
|
||||||
# return GtkSource.CompletionActivation.USER_REQUESTED
|
|
||||||
return GtkSource.CompletionActivation.INTERACTIVE
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Words Completer",
|
|
||||||
"author": "ITDominator",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"support": "",
|
|
||||||
"requests": {}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.dto.base_event import BaseEvent
|
|
||||||
from libs.event_factory import Event_Factory
|
|
||||||
|
|
||||||
from plugins.plugin_types import PluginCode
|
|
||||||
|
|
||||||
from .provider import Provider
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Plugin(PluginCode):
|
|
||||||
def __init__(self):
|
|
||||||
super(Plugin, self).__init__()
|
|
||||||
|
|
||||||
self.provider: Provider = None
|
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: BaseEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
self.provider = Provider()
|
|
||||||
|
|
||||||
event = Event_Factory.create_event(
|
|
||||||
"register_provider",
|
|
||||||
provider_name = "Words Completer",
|
|
||||||
provider = self.provider,
|
|
||||||
language_ids = []
|
|
||||||
)
|
|
||||||
self.message_to("completion", event)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
...
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
import re
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GObject
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from .provider_response_cache import ProviderResponseCache
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Provider(GObject.GObject, GtkSource.CompletionProvider):
|
|
||||||
"""
|
|
||||||
This is a Words Completion Provider.
|
|
||||||
# NOTE: used information from here --> https://warroom.rsmus.com/do-that-auto-complete/
|
|
||||||
"""
|
|
||||||
# __gtype_name__ = 'WordsCompletionProvider'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(Provider, self).__init__()
|
|
||||||
|
|
||||||
self.response_cache: ProviderResponseCache = ProviderResponseCache()
|
|
||||||
|
|
||||||
|
|
||||||
def do_get_name(self):
|
|
||||||
return 'Words Completion'
|
|
||||||
|
|
||||||
def do_match(self, context):
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
if not word or len(word) < 2: return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def do_get_priority(self):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def do_activate_proposal(self, proposal, iter_):
|
|
||||||
buffer = iter_.get_buffer()
|
|
||||||
# Note: Flag mostly intended for SourceViewsMultiInsertState
|
|
||||||
# to insure marker processes inserted text correctly.
|
|
||||||
buffer.is_processing_completion = True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_get_activation(self):
|
|
||||||
""" The context for when a provider will show results """
|
|
||||||
# return GtkSource.CompletionActivation.NONE
|
|
||||||
# return GtkSource.CompletionActivation.USER_REQUESTED
|
|
||||||
return GtkSource.CompletionActivation.INTERACTIVE
|
|
||||||
|
|
||||||
def do_populate(self, context):
|
|
||||||
word = self.response_cache.get_word(context)
|
|
||||||
results = self.response_cache.filter_with_context(context)
|
|
||||||
# results = self.response_cache.filter(word)
|
|
||||||
|
|
||||||
# if not results:
|
|
||||||
# results = self.response_cache.filter_with_context(context)
|
|
||||||
|
|
||||||
proposals = []
|
|
||||||
for entry in results:
|
|
||||||
proposals.append(
|
|
||||||
self.response_cache.create_completion_item(
|
|
||||||
entry["label"],
|
|
||||||
entry["text"],
|
|
||||||
entry["info"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
context.add_proposals(self, proposals, True)
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# Python imports
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
# Lib imports
|
|
||||||
import gi
|
|
||||||
gi.require_version('GtkSource', '4')
|
|
||||||
|
|
||||||
from gi.repository import GLib
|
|
||||||
from gi.repository import GtkSource
|
|
||||||
|
|
||||||
# Application imports
|
|
||||||
from libs.event_factory import Code_Event_Types
|
|
||||||
|
|
||||||
from core.widgets.code.completion_providers.provider_response_cache_base import ProviderResponseCacheBase
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProviderResponseCache(ProviderResponseCacheBase):
|
|
||||||
def __init__(self):
|
|
||||||
super(ProviderResponseCache, self).__init__()
|
|
||||||
|
|
||||||
self.matchers: dict = {}
|
|
||||||
|
|
||||||
|
|
||||||
def process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
|
||||||
buffer = event.file.buffer
|
|
||||||
asyncio.run( self._handle_change(buffer) )
|
|
||||||
|
|
||||||
def process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
|
||||||
self.matchers[event.file.buffer] = set()
|
|
||||||
del self.matchers[event.file.buffer]
|
|
||||||
|
|
||||||
def process_file_save(self, event: Code_Event_Types.SavedFileEvent):
|
|
||||||
...
|
|
||||||
|
|
||||||
def process_file_change(self, event: Code_Event_Types.TextChangedEvent):
|
|
||||||
buffer = event.file.buffer
|
|
||||||
asyncio.run( self._handle_change(buffer) )
|
|
||||||
|
|
||||||
async def _handle_change(self, buffer):
|
|
||||||
start_itr = buffer.get_start_iter()
|
|
||||||
end_itr = buffer.get_end_iter()
|
|
||||||
data = buffer.get_text(start_itr, end_itr, False)
|
|
||||||
|
|
||||||
if not data:
|
|
||||||
GLib.idle_add(self.load_empty_set, buffer)
|
|
||||||
return
|
|
||||||
|
|
||||||
if not buffer in self.matchers:
|
|
||||||
GLib.idle_add(self.load_as_new_set, buffer, data)
|
|
||||||
return
|
|
||||||
|
|
||||||
new_words = self.get_all_words(data)
|
|
||||||
GLib.idle_add(self.load_into_set, buffer, new_words)
|
|
||||||
|
|
||||||
def filter(self, word: str) -> list[dict]:
|
|
||||||
response: list[dict] = []
|
|
||||||
|
|
||||||
for entry in self.matchers:
|
|
||||||
if not word in entry: continue
|
|
||||||
data = self.matchers[entry]
|
|
||||||
response.append(data)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def filter_with_context(self, context: GtkSource.CompletionContext) -> list[dict]:
|
|
||||||
buffer = self.get_iter_correctly(context).get_buffer()
|
|
||||||
word = self.get_word(context).rstrip()
|
|
||||||
|
|
||||||
response: list[dict] = []
|
|
||||||
for entry in self.matchers[buffer]:
|
|
||||||
if not entry.rstrip().startswith(word): continue
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"label": entry,
|
|
||||||
"text": entry,
|
|
||||||
"info": ""
|
|
||||||
}
|
|
||||||
|
|
||||||
response.append(data)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
def load_empty_set(self, buffer):
|
|
||||||
self.matchers[buffer] = set()
|
|
||||||
|
|
||||||
def load_into_set(self, buffer, new_words):
|
|
||||||
self.matchers[buffer].update(new_words)
|
|
||||||
|
|
||||||
def load_as_new_set(self, buffer, data):
|
|
||||||
self.matchers[buffer] = self.get_all_words(data)
|
|
||||||
|
|
||||||
def get_all_words(self, data: str):
|
|
||||||
words = set()
|
|
||||||
|
|
||||||
def is_word_char(c):
|
|
||||||
return c.isalnum() or c == '_'
|
|
||||||
|
|
||||||
size = len(data)
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
while i < size:
|
|
||||||
# Skip non-word characters
|
|
||||||
while i < size and not is_word_char(data[i]):
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
start = i
|
|
||||||
# Consume word characters
|
|
||||||
while i < size and is_word_char(data[i]):
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
word = data[start:i]
|
|
||||||
if not word: continue
|
|
||||||
words.add(word)
|
|
||||||
|
|
||||||
return words
|
|
||||||
@@ -38,10 +38,10 @@ class ProviderResponseCacheBase:
|
|||||||
def process_file_change(self, buffer: GtkSource.Buffer):
|
def process_file_change(self, buffer: GtkSource.Buffer):
|
||||||
raise ProviderResponseCacheException("ProviderResponseCacheBase 'process_change' not implemented...")
|
raise ProviderResponseCacheException("ProviderResponseCacheBase 'process_change' not implemented...")
|
||||||
|
|
||||||
def filter(self, word: str) -> list[dict]:
|
def filter(self, word: str):
|
||||||
raise ProviderResponseCacheException("ProviderResponseCacheBase 'filter' not implemented...")
|
raise ProviderResponseCacheException("ProviderResponseCacheBase 'filter' not implemented...")
|
||||||
|
|
||||||
def filter_with_context(self, context: GtkSource.CompletionContext) -> list[dict]:
|
def filter_with_context(self, context: GtkSource.CompletionContext):
|
||||||
raise ProviderResponseCacheException("ProviderResponseCacheBase 'filter_with_context' not implemented...")
|
raise ProviderResponseCacheException("ProviderResponseCacheBase 'filter_with_context' not implemented...")
|
||||||
|
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ class ProviderResponseCacheBase:
|
|||||||
label: str = "",
|
label: str = "",
|
||||||
text: str = "",
|
text: str = "",
|
||||||
info: str = "",
|
info: str = "",
|
||||||
icon: any = None
|
completion: any = None
|
||||||
) -> dict:
|
):
|
||||||
if not label or not text: return
|
if not label or not text: return
|
||||||
|
|
||||||
comp_item = GtkSource.CompletionItem.new()
|
comp_item = GtkSource.CompletionItem.new()
|
||||||
@@ -62,58 +62,26 @@ class ProviderResponseCacheBase:
|
|||||||
comp_item.set_info(info)
|
comp_item.set_info(info)
|
||||||
# comp_item.set_markup(f"<h3>{info}</h3>")
|
# comp_item.set_markup(f"<h3>{info}</h3>")
|
||||||
|
|
||||||
if icon:
|
if completion:
|
||||||
comp_item.set_icon(
|
comp_item.set_icon(
|
||||||
self.get_icon_for_type(icon.type)
|
self.get_icon_for_type(completion.type)
|
||||||
)
|
)
|
||||||
|
|
||||||
return comp_item
|
return comp_item
|
||||||
|
|
||||||
def get_all_marks(self, buffer) -> list:
|
def get_word(self, context):
|
||||||
marks: list = []
|
start_iter = context.get_iter()
|
||||||
iter_ = buffer.get_start_iter()
|
end_iter = None
|
||||||
|
|
||||||
while iter_:
|
if not isinstance(start_iter, Gtk.TextIter):
|
||||||
marks = iter_.get_marks()
|
_, start_iter = context.get_iter()
|
||||||
|
|
||||||
for mark in marks:
|
|
||||||
if mark and mark not in marks:
|
|
||||||
marks.append(mark)
|
|
||||||
|
|
||||||
if not iter_.forward_char():
|
|
||||||
break
|
|
||||||
|
|
||||||
return marks
|
|
||||||
|
|
||||||
def get_all_insert_marks(self, buffer) -> list:
|
|
||||||
marks: list = []
|
|
||||||
iter_ = buffer.get_start_iter()
|
|
||||||
|
|
||||||
while iter_:
|
|
||||||
marks = iter_.get_marks()
|
|
||||||
|
|
||||||
for mark in marks:
|
|
||||||
if mark.get_name() and "multi_insert_" in mark.get_name():
|
|
||||||
marks.append(mark)
|
|
||||||
|
|
||||||
if not iter_.forward_char():
|
|
||||||
break
|
|
||||||
|
|
||||||
return marks
|
|
||||||
|
|
||||||
def get_word(self, context) -> str:
|
|
||||||
start_iter = self.get_iter_correctly(context)
|
|
||||||
end_iter = start_iter.copy()
|
end_iter = start_iter.copy()
|
||||||
|
|
||||||
if not start_iter.starts_word():
|
if not start_iter.starts_word():
|
||||||
start_iter.backward_word_start()
|
start_iter.backward_word_start()
|
||||||
|
|
||||||
if not end_iter.ends_word():
|
|
||||||
end_iter.forward_word_end()
|
end_iter.forward_word_end()
|
||||||
|
|
||||||
buffer = start_iter.get_buffer()
|
buffer = start_iter.get_buffer()
|
||||||
|
|
||||||
return buffer.get_text(start_iter, end_iter, False)
|
return buffer.get_text(start_iter, end_iter, False)
|
||||||
|
|
||||||
def get_iter_correctly(self, context) -> Gtk.TextIter:
|
|
||||||
return context.get_iter()[1] if isinstance(context.get_iter(), tuple) else context.get_iter()
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ class CompletionController(ControllerBase):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CompletionController, self).__init__()
|
super(CompletionController, self).__init__()
|
||||||
|
|
||||||
|
self.words_provider = GtkSource.CompletionWords.new("words", None)
|
||||||
|
self.words_provider.props.activation = GtkSource.CompletionActivation.INTERACTIVE
|
||||||
|
|
||||||
self._completers: list[GtkSource.Completion] = []
|
self._completers: list[GtkSource.Completion] = []
|
||||||
self._providers: dict[str, GtkSource.CompletionProvider] = {}
|
self._providers: dict[str, GtkSource.CompletionProvider] = {}
|
||||||
|
|
||||||
@@ -42,12 +45,10 @@ class CompletionController(ControllerBase):
|
|||||||
def register_completer(self, completer: GtkSource.Completion):
|
def register_completer(self, completer: GtkSource.Completion):
|
||||||
self._completers.append(completer)
|
self._completers.append(completer)
|
||||||
|
|
||||||
|
completer.add_provider(self.words_provider)
|
||||||
for provider in self._providers.values():
|
for provider in self._providers.values():
|
||||||
completer.add_provider(provider)
|
completer.add_provider(provider)
|
||||||
|
|
||||||
def unregister_completer(self, completer: GtkSource.Completion):
|
|
||||||
self._completers.remove(completer)
|
|
||||||
|
|
||||||
def register_provider(
|
def register_provider(
|
||||||
self,
|
self,
|
||||||
provider_name: str,
|
provider_name: str,
|
||||||
@@ -67,10 +68,14 @@ class CompletionController(ControllerBase):
|
|||||||
completer.remove_provider(provider)
|
completer.remove_provider(provider)
|
||||||
|
|
||||||
def provider_process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
def provider_process_file_load(self, event: Code_Event_Types.AddedNewFileEvent):
|
||||||
|
self.words_provider.register(event.file.buffer)
|
||||||
|
|
||||||
for provider in self._providers.values():
|
for provider in self._providers.values():
|
||||||
provider.response_cache.process_file_load(event)
|
provider.response_cache.process_file_load(event)
|
||||||
|
|
||||||
def provider_process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
def provider_process_file_close(self, event: Code_Event_Types.RemovedFileEvent):
|
||||||
|
self.words_provider.unregister(event.file.buffer)
|
||||||
|
|
||||||
for provider in self._providers.values():
|
for provider in self._providers.values():
|
||||||
provider.response_cache.process_file_close(event)
|
provider.response_cache.process_file_close(event)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
# Python imports
|
# Python imports
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
import gi
|
|
||||||
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.controllers.controller_base import ControllerBase
|
from libs.controllers.controller_base import ControllerBase
|
||||||
@@ -22,15 +19,11 @@ class TabsController(ControllerBase):
|
|||||||
|
|
||||||
self.active_view: SourceView = None
|
self.active_view: SourceView = None
|
||||||
self.tabs_widget: TabsWidget = TabsWidget()
|
self.tabs_widget: TabsWidget = TabsWidget()
|
||||||
self.tabs_widget.message = self.message
|
|
||||||
|
|
||||||
|
|
||||||
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
def _controller_message(self, event: Code_Event_Types.CodeEvent):
|
||||||
if isinstance(event, Code_Event_Types.FocusedViewEvent):
|
if isinstance(event, Code_Event_Types.FocusedViewEvent):
|
||||||
self.active_view = event.view
|
self.active_view = event.view
|
||||||
self.tabs_widget.view_changed(
|
|
||||||
event.view.get_buffer()
|
|
||||||
)
|
|
||||||
elif isinstance(event, Code_Event_Types.FilePathSetEvent):
|
elif isinstance(event, Code_Event_Types.FilePathSetEvent):
|
||||||
self.update_tab_label(event)
|
self.update_tab_label(event)
|
||||||
elif isinstance(event, Code_Event_Types.AddedNewFileEvent):
|
elif isinstance(event, Code_Event_Types.AddedNewFileEvent):
|
||||||
@@ -44,32 +37,48 @@ class TabsController(ControllerBase):
|
|||||||
return self.tabs_widget
|
return self.tabs_widget
|
||||||
|
|
||||||
def update_tab_label(self, event: Code_Event_Types.FilePathSetEvent):
|
def update_tab_label(self, event: Code_Event_Types.FilePathSetEvent):
|
||||||
for page_widget in self.tabs_widget.get_children():
|
for tab in self.tabs_widget.get_children():
|
||||||
tab = self.tabs_widget.get_tab_label(page_widget)
|
|
||||||
if not event.file == tab.file: continue
|
if not event.file == tab.file: continue
|
||||||
|
|
||||||
tab.label.set_label(event.file.fname)
|
tab.label.set_label(event.file.fname)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
def add_tab(self, event: Code_Event_Types.AddedNewFileEvent):
|
def add_tab(self, event: Code_Event_Types.AddedNewFileEvent):
|
||||||
box = Gtk.Separator()
|
def set_active_tab(tab, eve, file):
|
||||||
tab = TabWidget()
|
event = Event_Factory.create_event(
|
||||||
|
"set_active_file",
|
||||||
|
buffer = tab.get_parent().file.buffer
|
||||||
|
)
|
||||||
|
|
||||||
|
self.active_view.set_buffer(
|
||||||
|
tab.get_parent().file.buffer
|
||||||
|
)
|
||||||
|
|
||||||
|
self.message(event)
|
||||||
|
|
||||||
|
def close_tab(tab, eve, file):
|
||||||
|
event = Event_Factory.create_event(
|
||||||
|
"remove_file",
|
||||||
|
buffer = tab.get_parent().file.buffer
|
||||||
|
)
|
||||||
|
|
||||||
|
self.message(event)
|
||||||
|
|
||||||
|
tab = TabWidget()
|
||||||
tab.file = event.file
|
tab.file = event.file
|
||||||
tab.label.set_label(event.file.fname)
|
tab.label.set_label(event.file.fname)
|
||||||
|
tab.set_select_signal(set_active_tab)
|
||||||
|
tab.set_close_signal(close_tab)
|
||||||
|
|
||||||
self.tabs_widget.append_page(box, tab)
|
self.tabs_widget.add(tab)
|
||||||
tab.show_all()
|
tab.show()
|
||||||
|
|
||||||
def remove_tab(self, event: Code_Event_Types.RemovedFileEvent):
|
def remove_tab(self, event: Code_Event_Types.RemovedFileEvent):
|
||||||
for page_widget in self.tabs_widget.get_children():
|
for tab in self.tabs_widget.get_children():
|
||||||
tab = self.tabs_widget.get_tab_label(page_widget)
|
|
||||||
if not event.file == tab.file: continue
|
if not event.file == tab.file: continue
|
||||||
|
|
||||||
tab.clear_signals_and_data()
|
tab.clear_signals_and_data()
|
||||||
self.tabs_widget.remove_page(
|
tab.run_dispose()
|
||||||
self.tabs_widget.page_num(page_widget)
|
tab.destroy()
|
||||||
)
|
|
||||||
|
|
||||||
|
del tab
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -33,10 +33,8 @@ class SourceViewsController(ControllerBase, list):
|
|||||||
if isinstance(event, Code_Event_Types.TextChangedEvent):
|
if isinstance(event, Code_Event_Types.TextChangedEvent):
|
||||||
if not self.signal_mapper.active_view: return
|
if not self.signal_mapper.active_view: return
|
||||||
self.signal_mapper.active_view.command.exec("update_info_bar")
|
self.signal_mapper.active_view.command.exec("update_info_bar")
|
||||||
elif isinstance(event, Code_Event_Types.SetActiveFileEvent):
|
elif isinstance(event, Code_Event_Types.TextChangedEvent):
|
||||||
self.signal_mapper.active_view.set_buffer(
|
self.signal_mapper.active_view.command.exec("update_info_bar")
|
||||||
event.buffer
|
|
||||||
)
|
|
||||||
elif isinstance(event, Code_Event_Types.TextInsertedEvent):
|
elif isinstance(event, Code_Event_Types.TextInsertedEvent):
|
||||||
self.signal_mapper.insert_text(event.file, event.text)
|
self.signal_mapper.insert_text(event.file, event.text)
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,6 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
|
|||||||
if not self.insert_markers: return False
|
if not self.insert_markers: return False
|
||||||
|
|
||||||
buffer = file.buffer
|
buffer = file.buffer
|
||||||
if buffer.is_processing_completion:
|
|
||||||
self.insert_completion_text(buffer, text)
|
|
||||||
return True
|
|
||||||
|
|
||||||
# freeze buffer and insert to each mark (if any)
|
# freeze buffer and insert to each mark (if any)
|
||||||
buffer.block_insert_after_signal()
|
buffer.block_insert_after_signal()
|
||||||
@@ -52,32 +49,6 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def insert_completion_text(self, buffer, text):
|
|
||||||
buffer.is_processing_completion = False
|
|
||||||
|
|
||||||
# freeze buffer and insert to each mark (if any)
|
|
||||||
buffer.block_insert_after_signal()
|
|
||||||
buffer.begin_user_action()
|
|
||||||
|
|
||||||
with buffer.freeze_notify():
|
|
||||||
for mark in self.insert_markers:
|
|
||||||
end_itr = buffer.get_iter_at_mark(mark)
|
|
||||||
start_itr = end_itr.copy()
|
|
||||||
|
|
||||||
if not start_itr.starts_word():
|
|
||||||
start_itr.backward_word_start()
|
|
||||||
|
|
||||||
if not end_itr.ends_word():
|
|
||||||
end_itr.forward_word_end()
|
|
||||||
|
|
||||||
buffer.delete(start_itr, end_itr)
|
|
||||||
buffer.insert(end_itr, text, -1)
|
|
||||||
|
|
||||||
buffer.end_user_action()
|
|
||||||
buffer.unblock_insert_after_signal()
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def move_cursor(self, source_view, step, count, extend_selection, emit):
|
def move_cursor(self, source_view, step, count, extend_selection, emit):
|
||||||
buffer = source_view.get_buffer()
|
buffer = source_view.get_buffer()
|
||||||
|
|
||||||
@@ -124,7 +95,7 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
is_future = key_mapper._key_release_event(eve)
|
is_future = key_mapper._key_release_event(eve)
|
||||||
if is_future: return True
|
if is_future: return False
|
||||||
|
|
||||||
command = key_mapper._key_press_event(eve)
|
command = key_mapper._key_press_event(eve)
|
||||||
if not command: return False
|
if not command: return False
|
||||||
@@ -137,7 +108,7 @@ class SourceViewsMultiInsertState(MarkEventsMixin):
|
|||||||
command = key_mapper._key_release_event(eve)
|
command = key_mapper._key_release_event(eve)
|
||||||
is_past = key_mapper._key_press_event(eve)
|
is_past = key_mapper._key_press_event(eve)
|
||||||
|
|
||||||
if is_past: return True
|
if is_past: return False
|
||||||
if not command: return False
|
if not command: return False
|
||||||
|
|
||||||
source_view.command.exec(command)
|
source_view.command.exec(command)
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ class SourceBuffer(GtkSource.Buffer):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SourceBuffer, self).__init__()
|
super(SourceBuffer, self).__init__()
|
||||||
|
|
||||||
self.is_processing_completion: bool = False
|
|
||||||
|
|
||||||
self._handler_ids = []
|
self._handler_ids = []
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,62 +10,52 @@ from gi.repository import Gtk
|
|||||||
|
|
||||||
|
|
||||||
class TabWidget(Gtk.Box):
|
class TabWidget(Gtk.Box):
|
||||||
"""docstring for TabWidget"""
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(TabWidget, self).__init__()
|
super(TabWidget, self).__init__()
|
||||||
|
|
||||||
self._close_tab = None
|
self.file = None
|
||||||
|
|
||||||
self._setup_styling()
|
self._setup_styling()
|
||||||
self._setup_signals()
|
self._setup_signals()
|
||||||
|
self._subscribe_to_events()
|
||||||
self._load_widgets()
|
self._load_widgets()
|
||||||
|
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
ctx = self.get_style_context()
|
ctx = self.get_style_context()
|
||||||
ctx.add_class("tab-widget")
|
ctx.add_class("tab-widget")
|
||||||
|
|
||||||
self.set_orientation(0)
|
|
||||||
self.set_hexpand(False)
|
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
def _subscribe_to_events(self):
|
||||||
|
...
|
||||||
|
|
||||||
def _load_widgets(self):
|
def _load_widgets(self):
|
||||||
self.label = Gtk.Label()
|
self._label_eve_box = Gtk.EventBox()
|
||||||
self.close_btn = Gtk.Button()
|
self.label = Gtk.Label(label = "")
|
||||||
icon = Gtk.Image(stock = Gtk.STOCK_CLOSE)
|
self.close_btn = Gtk.Button(label = "X")
|
||||||
|
|
||||||
ctx = self.label.get_style_context()
|
ctx = self.label.get_style_context()
|
||||||
ctx.add_class("tab-label")
|
ctx.add_class("tab-label")
|
||||||
ctx = self.close_btn.get_style_context()
|
ctx = self.close_btn.get_style_context()
|
||||||
ctx.add_class("tab-close-bttn")
|
ctx.add_class("tab-close-bttn")
|
||||||
|
|
||||||
self.label.set_xalign(0.0)
|
|
||||||
self.label.set_margin_left(25)
|
|
||||||
self.label.set_margin_right(25)
|
|
||||||
self.label.set_hexpand(True)
|
self.label.set_hexpand(True)
|
||||||
|
|
||||||
self.close_btn.add(icon)
|
self._label_eve_box.add(self.label)
|
||||||
self.add(self.label)
|
self.add(self._label_eve_box)
|
||||||
self.add(self.close_btn)
|
self.add(self.close_btn)
|
||||||
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
def clear_signals_and_data(self):
|
def clear_signals_and_data(self):
|
||||||
self.close_btn.disconnect(self._handler_id)
|
del self.file
|
||||||
self._close_tab = None
|
self._label_eve_box.disconnect(self._label_eve_box_id)
|
||||||
self._handler_id = None
|
self.close_btn.disconnect(self.close_btn_id)
|
||||||
|
|
||||||
for child in self.get_children():
|
def set_select_signal(self, callback):
|
||||||
child.unparent()
|
self._label_eve_box_id = self._label_eve_box.connect('button-release-event', callback, self.file)
|
||||||
child.run_dispose()
|
|
||||||
child.destroy()
|
|
||||||
|
|
||||||
def set_close_signal(self, callback):
|
def set_close_signal(self, callback):
|
||||||
self._handler_id = self.close_btn.connect(
|
self.close_btn_id = self.close_btn.connect('button-release-event', callback, self.file)
|
||||||
'button-release-event',
|
|
||||||
callback,
|
|
||||||
self.file
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -6,13 +6,16 @@ gi.require_version('Gtk', '3.0')
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from libs.event_factory import Event_Factory, Code_Event_Types
|
from libs.event_factory import Code_Event_Types
|
||||||
|
|
||||||
|
from .source_view import SourceView
|
||||||
|
from .source_file import SourceFile
|
||||||
|
|
||||||
from .tab_widget import TabWidget
|
from .tab_widget import TabWidget
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TabsWidget(Gtk.Notebook):
|
class TabsWidget(Gtk.ButtonBox):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(TabsWidget, self).__init__()
|
super(TabsWidget, self).__init__()
|
||||||
|
|
||||||
@@ -23,12 +26,10 @@ class TabsWidget(Gtk.Notebook):
|
|||||||
|
|
||||||
|
|
||||||
def _setup_styling(self):
|
def _setup_styling(self):
|
||||||
...
|
self.set_layout(Gtk.ButtonBoxStyle.CENTER)
|
||||||
|
|
||||||
def _setup_signals(self):
|
def _setup_signals(self):
|
||||||
self.connect("page-added", self._page_added)
|
...
|
||||||
self.switch_page_id = \
|
|
||||||
self.connect_after("switch-page", self._switch_page)
|
|
||||||
|
|
||||||
def _subscribe_to_events(self):
|
def _subscribe_to_events(self):
|
||||||
...
|
...
|
||||||
@@ -36,40 +37,51 @@ class TabsWidget(Gtk.Notebook):
|
|||||||
def _load_widgets(self):
|
def _load_widgets(self):
|
||||||
...
|
...
|
||||||
|
|
||||||
def _page_added(self, notebook, page_widget, page_num):
|
def add_tab(self, event: Code_Event_Types.CodeEvent):
|
||||||
tab = self.get_tab_label(page_widget)
|
"""Add a tab widget for the given file event."""
|
||||||
tab.set_close_signal(self._close_tab)
|
if not hasattr(self, 'tabs'):
|
||||||
|
return
|
||||||
|
|
||||||
page_widget.show()
|
tab = TabWidget()
|
||||||
self.set_tab_detachable(page_widget, True)
|
tab.file = event.file
|
||||||
self.set_tab_reorderable(page_widget, True)
|
|
||||||
|
|
||||||
def _close_tab(self, tab, eve, file):
|
tab.label.set_label(event.file.fname)
|
||||||
event = Event_Factory.create_event(
|
|
||||||
"remove_file",
|
def select_signal(widget, eve, file):
|
||||||
buffer = tab.get_parent().file.buffer
|
self.code_base.active_view.command.exec_with_args(
|
||||||
|
"set_buffer",
|
||||||
|
(self.code_base.active_view, file)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.message(event)
|
def close_signal(widget, eve, file):
|
||||||
|
self.code_base.files_controller.remove_file(file.buffer)
|
||||||
|
|
||||||
def _switch_page(self, notebook, page_widget, page_num):
|
tab.set_select_signal(select_signal)
|
||||||
tab = self.get_tab_label(page_widget)
|
tab.set_close_signal(close_signal)
|
||||||
event = Event_Factory.create_event(
|
|
||||||
"set_active_file",
|
|
||||||
buffer = tab.file.buffer
|
|
||||||
)
|
|
||||||
|
|
||||||
self.message(event)
|
self.tabs.add(tab)
|
||||||
|
|
||||||
def view_changed(self, buffer):
|
def remove_tab(self, event: Code_Event_Types.CodeEvent):
|
||||||
for page_widget in self.get_children():
|
"""Remove a tab widget for the given file event."""
|
||||||
tab = self.get_tab_label(page_widget)
|
if not hasattr(self, 'tabs'):
|
||||||
if not buffer == tab.file.buffer: continue
|
return
|
||||||
|
|
||||||
self.handler_block(self.switch_page_id)
|
for child in self.tabs.get_children():
|
||||||
|
if not child.file == event.file: continue
|
||||||
|
|
||||||
self.set_current_page(
|
self.tabs.remove(child)
|
||||||
self.page_num(page_widget)
|
child.clear_signals_and_data()
|
||||||
)
|
del child
|
||||||
|
|
||||||
self.handler_unblock(self.switch_page_id)
|
return
|
||||||
|
|
||||||
|
def update_tab_label(self, event: Code_Event_Types.CodeEvent):
|
||||||
|
"""Update tab label for the given file event."""
|
||||||
|
if not hasattr(self, 'tabs'):
|
||||||
|
return
|
||||||
|
|
||||||
|
for tab in self.tabs.get_children():
|
||||||
|
if not tab.file == event.file: continue
|
||||||
|
tab.label.set_label(event.file.fname)
|
||||||
|
|
||||||
|
return
|
||||||
|
|||||||
@@ -1,56 +1,21 @@
|
|||||||
/* ---- Overrides ---- */
|
/* ---- Make most desired things base transparent ---- */
|
||||||
text selection {
|
|
||||||
background-color: #44475a;
|
|
||||||
color: #FFA500;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- Make most desired things base transparent ---- */
|
/* ---- Make most desired things base transparent ---- */
|
||||||
popover,
|
popover,
|
||||||
popover > box,
|
popover > box,
|
||||||
notebook,
|
notebook,
|
||||||
header,
|
header,
|
||||||
stack {
|
stack,
|
||||||
|
scrolledwindow,
|
||||||
|
viewport {
|
||||||
background: rgba(0, 0, 0, 0.0);
|
background: rgba(0, 0, 0, 0.0);
|
||||||
color: rgba(255, 255, 255, 1);
|
color: rgba(255, 255, 255, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrolledwindow * {
|
||||||
/* The scrolled window itself */
|
background: rgba(0, 0, 0, 0.0);
|
||||||
scrolledwindow,
|
|
||||||
scrolledwindow viewport,
|
|
||||||
textview,
|
|
||||||
textview text {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollbar {
|
|
||||||
background-color: #2a2a2a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The track */
|
|
||||||
scrollbar trough {
|
|
||||||
background-color: transparent;
|
|
||||||
/*background-color: #2a2a2a;*/
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The draggable handle */
|
|
||||||
scrollbar slider {
|
|
||||||
background-color: #555;
|
|
||||||
border-radius: 6px;
|
|
||||||
min-width: 10px;
|
|
||||||
min-height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollbar slider:hover {
|
|
||||||
background-color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollbar slider:active {
|
|
||||||
background-color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
border {
|
border {
|
||||||
background: rgba(39, 43, 52, 0.84);
|
background: rgba(39, 43, 52, 0.84);
|
||||||
}
|
}
|
||||||
@@ -76,20 +41,6 @@ tab:checked {
|
|||||||
color: rgba(255, 255, 255, 1);
|
color: rgba(255, 255, 255, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* the mini view container of text */
|
|
||||||
.mini-view > text {
|
|
||||||
background: rgba(39, 43, 52, 0.64);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draggable overlay of the miniview */
|
|
||||||
.mini-view > * {
|
|
||||||
background-color: rgba(124, 124, 124, 0.34);
|
|
||||||
color: rgba(255, 255, 255, 1);
|
|
||||||
font-size: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.base-container {
|
.base-container {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
@@ -145,9 +96,177 @@ tab:checked {
|
|||||||
color: rgba(255, 0, 0, 0.64);
|
color: rgba(255, 0, 0, 0.64);
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-txt { color: rgb(170, 18, 18); }
|
|
||||||
.warning-txt { color: rgb(255, 168, 0); }
|
|
||||||
.success-txt { color: rgb(136, 204, 39); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*popover,*/
|
||||||
|
/*popover > box*/
|
||||||
|
/*.main-window > box,*/
|
||||||
|
/*.main-window > box > box,*/
|
||||||
|
/*.main-window > box > box > paned,*/
|
||||||
|
/*.main-window > box > box > paned > notebook,*/
|
||||||
|
/*.main-window > box > box > paned > notebook > stack,*/
|
||||||
|
/*.main-window > box > box > paned > notebook > stack > scrolledwindow > textview > * {*/
|
||||||
|
/* background: rgba(0, 0, 0, 0.0);*/
|
||||||
|
/* color: rgba(255, 255, 255, 1);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- top controls ---- */
|
||||||
|
/*.main-window > box > box > button,*/
|
||||||
|
/*.main-window > box > box > buttonbox > button {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.64);*/
|
||||||
|
/* margin-left: 12px;*/
|
||||||
|
/* margin-right: 12px;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* status bar */
|
||||||
|
/*.main-window > box > statusbar {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.64);*/
|
||||||
|
/* padding-left: 96px;*/
|
||||||
|
/* padding-right: 96px;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- notebook headers ---- */
|
||||||
|
/*notebook > header {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.72);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*notebook > header > tabs > tab {*/
|
||||||
|
/* color: rgba(255, 255, 255, 1);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*notebook > header > tabs > tab:active {*/
|
||||||
|
/* background: rgba(0, 0, 0, 0.0);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- notebook tab buttons ---- */
|
||||||
|
/*tab > box > button {*/
|
||||||
|
/* background: rgba(116, 0, 0, 0.64);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*tab > box > button:hover {*/
|
||||||
|
/* background: rgba(256, 0, 0, 0.64);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*notebook > header > tabs > tab:checked {*/
|
||||||
|
/* Neon Blue 00e8ff */
|
||||||
|
/* background-color: rgba(0, 232, 255, 0.2); */
|
||||||
|
|
||||||
|
/* background-color: rgba(255, 255, 255, 0.46);*/
|
||||||
|
|
||||||
|
/* Dark Bergundy */
|
||||||
|
/* background-color: rgba(116, 0, 0, 0.25); */
|
||||||
|
|
||||||
|
/* color: rgba(255, 255, 255, 0.8);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*.notebook-selected-focus {*/
|
||||||
|
/* Neon Blue 00e8ff border */
|
||||||
|
/* border: 2px solid rgba(0, 232, 255, 0.34); */
|
||||||
|
|
||||||
|
/* border: 2px solid rgba(255, 255, 255, 0.46);*/
|
||||||
|
|
||||||
|
/* Dark Bergundy */
|
||||||
|
/* border: 2px solid rgba(116, 0, 0, 0.64); */
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- source code notebooks ---- */
|
||||||
|
/*notebook > stack > scrolledwindow > textview {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.64);*/
|
||||||
|
/* color: rgba(255, 255, 255, 1);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*textview {*/
|
||||||
|
/* padding-bottom: 50em;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* any popover */
|
||||||
|
/*popover {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.86);*/
|
||||||
|
/* color: rgba(255, 255, 255, 1);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/* ---- make text selection slightly transparent ---- */
|
||||||
|
/** selection {*/
|
||||||
|
/* background-color: rgba(0, 115, 115, 0.34);*/
|
||||||
|
/* Bergundy */
|
||||||
|
/* background-color: rgba(116, 0, 0, 0.64); */
|
||||||
|
/* color: rgba(255, 255, 255, 0.5);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- miniview properties ---- */
|
||||||
|
/*.source-view,*/
|
||||||
|
/*.mini-view {*/
|
||||||
|
/* font-family: Monospace;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/* the mini view container of text */
|
||||||
|
/*.mini-view > text {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.64);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/* draggable overlay of the miniview */
|
||||||
|
/*.mini-view > * {*/
|
||||||
|
/* background: rgba(64, 64, 64, 0.32);*/
|
||||||
|
/* color: rgba(255, 255, 255, 1);*/
|
||||||
|
/* font-size: 1px;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*.mini-view > text {*/
|
||||||
|
/* background: rgba(39, 43, 52, 0.64);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* other properties */
|
||||||
|
/*.buffer_changed {*/
|
||||||
|
/* color: rgba(255, 168, 0, 1.0);*/
|
||||||
|
/* color: rgba(0, 232, 255, 0.64); */
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*.searching,*/
|
||||||
|
/*.search_success,*/
|
||||||
|
/*.search_fail {*/
|
||||||
|
/* border-style: solid;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*.searching {*/
|
||||||
|
/* border-color: rgba(0, 225, 225, 0.64);*/
|
||||||
|
/*}*/
|
||||||
|
/*.search_success {*/
|
||||||
|
/* background: rgba(136, 204, 39, 0.12);*/
|
||||||
|
/* border-color: rgba(136, 204, 39, 1);*/
|
||||||
|
/*}*/
|
||||||
|
/*.search_fail {*/
|
||||||
|
/* background: rgba(170, 18, 18, 0.12);*/
|
||||||
|
/* border-color: rgba(200, 18, 18, 1);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.error_txt { color: rgb(170, 18, 18); }
|
||||||
|
.warning_txt { color: rgb(255, 168, 0); }
|
||||||
|
.success_txt { color: rgb(136, 204, 39); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user