Closed vanillajonathan closed 1 year ago
Something like this:
class CssPropertyCompletionProvider(GObject.GObject, GtkSource.CompletionProvider):
PROPERTIES = [
"all",
"background",
"background-color",
"border",
"border-bottom",
"border-bottom-color",
"border-bottom-style",
"border-bottom-width",
"border-collapse",
"border-color",
"border-radius",
"color",
"justify-content",
"min-height",
"min-width",
"opacity",
"padding",
# Non-standard Gaphor-specific attributes
"dash-style",
"line-style",
"line-width",
"text-color",
]
def __init__(self):
super().__init__()
self._filter_data: FilterData = FilterData()
def do_activate(self, context: GtkSource.CompletionContext, proposal: GtkSource.CompletionProposal) -> None:
buffer = context.get_buffer()
buffer.begin_user_action()
has_selection, begin, end = context.get_bounds()
if has_selection:
buffer.delete(begin, end)
buffer.insert(begin, proposal.text, len(proposal.text))
buffer.end_user_action()
def do_display(self, context: GtkSource.CompletionContext, proposal: GtkSource.CompletionProposal, cell: GtkSource.CompletionCell) -> None:
if cell.props.column == GtkSource.CompletionColumn.ICON:
pass
elif cell.props.column == GtkSource.CompletionColumn.TYPED_TEXT:
cell.set_text(proposal.text)
def do_get_priority(self, context: GtkSource.CompletionContext) -> int:
return 1
def do_get_title(self) -> str:
return "CSS Properties"
def do_is_trigger(self, textiter: Gtk.TextIter, ch :str) -> bool:
buffer = textiter.get_buffer()
if buffer.iter_has_context_class(textiter, "comment"):
return False
if ch.isalpha() or ch == "-":
return True
return False
def do_key_activates(self, context, proposal, keyval: int, state) -> bool:
return True
def do_populate_async(self, context, cancellable, callback, user_data=None) -> None:
task = Gio.Task.new(self, cancellable, callback)
store = Gio.ListStore.new(CssPropertyProposal)
self._filter_data.word = context.get_word()
for prop in self.PROPERTIES:
proposal = CssPropertyProposal(prop)
store.append(proposal)
filter_fn = lambda proposal, data: proposal.text.startswith(data.word)
store_filter = Gtk.CustomFilter.new(filter_fn, self._filter_data)
task.proposals = Gtk.FilterListModel.new(store, store_filter)
task.return_boolean(True)
def do_populate_finish(self, result: Gio.AsyncResult) -> Gio.ListModel:
if result.propagate_boolean():
return result.proposals
def do_refilter(self, context: GtkSource.CompletionContext, model: Gio.ListModel) -> None:
word = context.get_word()
old_word = self._filter_data.word
change = Gtk.FilterChange.DIFFERENT
if old_word and word.startswith(old_word):
change = Gtk.FilterChange.MORE_STRICT
elif old_word and old_word.startswith(word):
change = Gtk.FilterChange.LESS_STRICT
self._filter_data.word = word
model.get_filter().changed(change)
class CssPropertyProposal(GObject.Object, GtkSource.CompletionProposal):
def __init__(self, text: str):
super().__init__()
self.text: str = text
class FilterData:
word: str
Register the completion provider:
source_view = GtkSource.View()
provider = CssPropertyCompletionProvider()
view_completion = source_view.get_completion()
view_completion.add_provider(provider)
Hey @vanillajonathan, great idea! Would you be willing to help implement this?
Then I would have to setup a development environment.
The code above should be a good start, but the PROPERTIES
property would need to be amended to contain all the standard CSS properties. The do_display
method could be modified to also include a icon to symbolize a CSS property if such an icon were to be. The do_is_trigger
method could be modified to inspect the Gtk.TextIter
to conditionally trigger (such as not inside comments), the do_refilter
could be implemented, but I don't know how to. An additional and separate class implementing CompletionProvider
provider could be written for CSS functions. There could also be a CompletionProvider for named colors and at-rules.
The code above kind of works but does print some warning.
Then I would have to setup a development environment
You've got this! 😁
We're also using some non-standard CSS properties, so I suppose it would make sense to update the syntax highlighting as well.
Is your feature request related to a problem?
The user is not too familiar with CSS and which properties and functions exists.
Describe the solution you'd like
A
GtkSource.CompletionProvider
that provides autocompletion for CSS properties and functions.Additional context
https://www.w3.org/Style/CSS/all-properties.en.html https://www.w3schools.com/cssref/index.php https://developer.mozilla.org/en-US/docs/Web/CSS/Reference