[Builder] LibIDE Update
- From: Christian Hergert <christian hergert me>
- To: builder-list gnome org
- Subject: [Builder] LibIDE Update
- Date: Tue, 17 Feb 2015 17:39:01 -0800
Hi Everyone!
Many of you know I've been busy working on LibIDE. It has come a long
way since I started. I finally have a better understanding of how things
are going to work going forward.
I'm currently deciding whether or not we should start pushing this into
what will be 3.16. We have a few weeks left, and to be honest, I think
it's more important to get people testing this than adhering to code
freezes.
So, what has been implemented since we last talked?
## Extension Points
LibIDE does not have plugins in the traditional sense. Everything is
done with `GIOExtensionPoint` and the implementation is compiled inside
of the library. It's sort of a dependency injection without all the
brittleness. It works well combined with `GAsyncInitable` to create
instances without knowing the concrete implemention. It allows the
implementations to self-test if they can support the requested feature
with what is loaded in the `IdeContext`.
## Language Abstractions
The language abstractions have landed. You can get an `IdeLangauge` for
a given `IdeFile` using `ide_file_get_language()`.
We use a combination of `GtkSourceLanguageManager` and
`GIOExtensionPoint` to load these so that we can provide exceptional
features for certain languages. For example, C will use an
implementation named `IdeCLanguage` where as other languages will use
the generic `IdeLanguage` base class.
The `IdeLanguage` class has various properties that will allow us to
simplify the editor view in Builder. For example:
* `ide_language_get_diagnostician()` returns an `IdeDiagnostician`
which is a collection of `IdeDiagnosticProvider`s. `IdeCLanguage` will
return a diagnostician with a provider which accesses clang in process.
We needed to bring clang in process to get some of the interactivity
performance we want. However, they can also use remote providers, such
as those coming from `gnome-code-assistance`.
* `ide_language_get_indenter()` returns an `IdeIdenter` that can be
attached to a `GtkSourceView` to provide identing features. The
implementation for these still need to be brought down from
`GbSourceAutoIndenter`.
* `ide_language_get_highlighter()` will return a `IdeHighlighter`.
This isn't a replacement for `GtkSourceView` highlighting, but an
extension to it. It will provide semantic highlighting of things like
type names and functions. The `IdeCLanguage` will return an
`IdeClangHighlighter` that will use the translation units provided via
`IdeClangService` to extract tokens in the file.
* `ide_language_get_symbol_resolver()` will return an
`IdeSymbolResolver`. This can be used to get an `IdeSymbol` for an item
at a given `IdeSourceLocation`. This will let us also find other
locations that the symbol exists. (Imagine highlighting all instances of
a local when it is hovered). We will also have support via this class to
get all the symbols in a file. That will get used in a symbol list
popover or something to that nature.
* `ide_language_get_refactory()` returns an `IdeRefactory`. This is
still a bit of a gray area as to what will be supported. But the handy
wavy design is that it will get us access to a series of commands to do
common features like rename methods or locals. Extract
## Diagnostics
You can test out the new diagnostics engine using
`./ide-list-diagnostics configure.ac myfile.c`. It is language agnostic,
so if you use C it will use the C diagnostics provider, and if you use
Python it will be provided via `gnome-code-assistance`. Either way, you
get a nice clang style printout on the command line.
https://pbs.twimg.com/media/B93wC5xCcAEDqKf.png:large
## File Settings
We haven't had a good story for editor settings as of late. Everything
is backed by GSettings. Clearly not ideal.
So this week I added `IdeFileSettings`. This is an abstract base class
that can have various implementations, provided via extension points.
The idea is that you can asynchronously load the file settings for an
`IdeFile` and it will discover the most accurate file settings for the
file. This might come via modelines (still todo), editorconfig via
`IdeEditorconfigFileSettings`, or gsettings via `IdeGsettingsFileSettings`.
`ide_file_get_settings_async()` will perform the operation. You can
test it with `./ide-list-file-settings configure.ac test.c`. We require
the `configure.ac` so we can load the project. Not ideal, but that is
what is there now.
## Search
I've been moving search down into LibIDE. This is going to allow for
lots of cool things like using the scripting engine to add your own
search provider. Probably useful if you have some custom bug tracker at
your company.
You can test the engine with `./ide-search configure.ac [KEYWORDS...]`.
## Building
I started plumbing support for building projects. It's not very far
along yet, but a basic build command works for the local project. We are
doing all builds out of tree. (In
~/.cache/gnome-builder/builds/<project>/<arch>/). The root build
directory can be changed. But I definitely want to try to do all builds
out of tree. It really simplfies the problem when compiling for external
devices.
You can test this out using `./ide-build configure.ac`. It is not good
about dealing with the situation where the tree has been configured
locally, but we'll work through that in the not too distant future.
## Project Files
When the `IdeContext` is loaded, the discovered `IdeVcs` will load all
the project files into the project tree. I went back and forth decided
if the BuildSystem or the Vcs should load this content, and I think the
Vcs is the right place to do it.
You can test this from the command line using `./ide-list-files`.
## Device Management
You can fetch the `IdeDeviceManager` from the `IdeContext` using
`ide_context_get_device_manager()`. The device manager as a series of
`IdeDeviceProvider`s loaded. When they discover a new device (such as a
tablet, phone, simulator, etc) they notify the device manager.
When we build, we build for a particular device. The `IdeLocalDevice` is
probably the most common device we'll be using.
You can list the discovered devices using `./ide-list-devices`.
$ ./ide-list-devices
local "starlight" (x86_64-linux-gnu)
## Unsaved Files
One of the things we have wanted for a while is the ability to track
unsaved buffers and persist them to a drafts directory when closing
Builder. Support for this is in LibIDE but not yet taken advantage of in
the Builder UI.
The abstraction also plays nicely with background diagnosticians since
we need the unsaved buffers constantly to generate accurate warnings and
errors.
When we load the IdeContext, the unsaved buffers will be brought back
into memory, and the documents loaded into the document manager (still a
todo item).
## Code Navigation
I added `IdeBackForwardList` to LibIDE not too long ago. This will serve
as the navigation stack for browsing through code. Whenever we reach a
jump location in the editor, we'll push or position onto the stack.
There are some non-obvious implementation details here to make things
"feel right". Go check out the code to see how we deal with branching
and merging histories.
## IDE Scripting
LibIDE gained support for IDE Scripting this week. Currently, we only
have one scripting language engine, which is GJS based. I bit the bullet
and had to write some C++ to host the JS runtime, but was pleasently
surprised how well this works with automake these days. We still have a
C library with C linker yet some code calls into C++ libraries. Lovely.
So what can you do from the scripting environment? Turns out quite a
bit. For example, you can implement your own search provider. You could
also navigate the project tree, extract information from the version
control system, and before long, register commands.
We'll also make it easy to hook into the file save/load pipeline as soon
as the document manager is moved into LibIDE.
Garrett Regier, the libpeas mantainer, also started work on a Python
loader. I expect that will merge into wip/libide relatively soon. This
is great news from an extensability perspective.
I've tried to be careful about what I've exposed in the LibIDE API. That
means that many constructors and helper functions are not exposed, but
kept internal to LibIDE. By doing so, it is pretty clear what you can
and cannot do from the scripting environment.
-- Christian
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]