gnome

This week in GNOME Builder #2

This week we fixed some specific topics which were planned for the previous cycle. If anyone wants to contribute so see some of our “Builder wishlist” go there: Builder/ThreePointThirtyfive

Last time i had forgotten to mention the great work of our translation team which contributed various translations to Builder. Thank you!

New Features

For several releases now Builder allows to debug applications with gdb. However it was not possible to interact with gdb directly. This shortcoming got fixed now and there is now an entry to execute commands against the gdb process.

Debugger Console

We are happy if you can test this feature to iron most of the problems out before the release this cycle.

Plugins

Recently podman got major changes and announced V2 of the project. This changed also some APIs from the tool which broke our podman plugin. Harry to the rescue: he fixed the plugin and made it even backwards compatible. So you can use still the older version.

The Rust Analyzer Plugin got an alternative algorithm for resolving the actual workspace. Most of the time this would be the open project (as Cargo.toml can be found on the root of the project). But in hybrid projects where you maybe try to RiiR the Cargo.toml file can be found in a deeper folder. The idea now is to search for the Cargo-file in the root of the open project and if there is no file found trying to start the search from the opened Rust-file upwards till we reach the root folder again.

Christian tweaked some colours for the gutter for the new upcoming Adwaita colortheme (work in progress!)

Issues

  • Vanadiae fix the CSS to proper render shadows for attention dots - MR-282
  • Matthew fixed the modeline in modeline-parser.c

This week in GNOME Builder #1

Hello! My name is Günther Wagner and i try to give some insights in the current development of GNOME Builder. All these changes can already been tested with GNOME Builder Nightly so go ahead and give us feedback! This newsletter is called “This week in …” but probably we won’t post every week. So the interval will be a little bit arbitrary. Let’s start!

New Features

We included a new code spellchecker plugin leverage the fantastic codespell-project.

codespell

It is now possible to open files in the Project Tree with any external Program.

external program

Honourable mentions

The Markdown previewer faced some problems with incorrect escapes. Several problems got fixed along the way!

Alberto added an extension point to allow the distribution of out-of-tree plugins via flatpak-extensions. Currently there are no out-of-tree plugins as the model in GNOME Builder is currently similar to the linux-kernel. Assimilation of the plugins allows us to link them statically which improves the startup performance significantly. Christian also enabled the usage of libportal if there would be the need for plugins.

C++ detection got improved so clang is able to provide the correct completions and diagnostics.

The highlighting for diagnostic got improved. Before we always marked the element from the beginning of the problem till the end of the line. Now ranges getting considered aswell and mark only the affected range of the problem. If there is only the start point given we mark only the element affected element instead of the whole line. Speaking about diagnostic marker we fixed a bug which only showed the first diagnostic on a line. Now all diagnostics are getting shown in the popover.

Before

diagnostic before

After

diagnostic after

Diego streamlined and fixed several tooltip positioning problems and visual shortcomings.

Fixed Issues:

GNOME Builder ❤️ Rust Analyzer Part 2

As promised i wanted to show off the remaining features which found their way into GNOME Builder. Be warned this is a Video heavy post!

Goto definition

There are two 2 ways to trigger this action. First you can hold off Ctrl and hover the symbol you are interested in. Clicking brings you to that symbol definition.

The second option is, if you use the vim keyboard movements, to trigger gd in normal mode. As the real vim equivalent this brings you to the definition.

Show references

This is the opposite direction to Goto definition. Show references is triggered via the right click menu of a symbol. This could be a costly operation so you may have to wait some seconds for an solution.

Format via cargo fmt

Formatting the sourcefile is especially convenient in Rust as the formatter is built into cargo/rustc. Its possible to be triggered if you use the vim movement keybindings via gq.

Rename support

Renaming a symbol with all their references? This is possible now. Just hit Ctrl+Shift+R and a popup asks what the new name should look like. Hitting Enter considers all references of that symbol too.

Hover support

It is possible to show documentation when you hover a symbol or method. Due to not that perfect markdown support in a GtkLabel it is not perfect.

Workspace search provider

This is in my opinion the best feature right now. Searching symbols across the workspace is particular convenient if you remember the names of the symbol.

Roadmap

I have several ideas how to go from here:

  • Getting all diagnostic messages into the diagnostic sidebar for workspace wide diagnostic handling.
  • The Workspace search provider is currently a Rust Analyzer only feature but not restricted to it. I want to make the implementation generic enough to handle all LSP servers out there.
  • Rust Analyzer provides very useful CodeActions to refactor code in a convenient way. GNOME Builder does not support these right now therefore i want to try a design and elaborate how to go from there.

GNOME Builder ❤️ Rust Analyzer Part 1

In the last month i actively worked on something i would like to present in this blog post.

It all started with this reddit conversation:

matklad-reddit.png

This got me curious. I thought the LSP specification should be similar in most editors (without knowing a thing) and therefore i investigated my favourite editor: GNOME Builder. In fact i saw immediatly that there are still rough edges regarding the LSP implementation. And still no Rust Analyzer plugin available. This brought me to some lines of code by copying the RLS implementation.

Unsatisfied with the solution i made a complete rewrite as i was not confident enough for python (just occasionally write some lines). I started from scratch implementing a good Rust Analyzer plugin and sharpen the edges of the LSP implementation along the way.

Features Rust Analyzer in GNOME Builder

Speaking of features the first thing you will see if you open a vanilla GNOME Builder rust file in the editor is probably this:

Download offer directly in the IDE

ra_start.png

GNOME Builder will download the binary for you if not installed already. Note: Right now there is no version check implemented to re-download in case there is an update available. It’s on my todo list.

Progress support

Next Rust Analyzer gets started and downloads packages and compiles them in the background. We get a nice progress indicator for these information. This was my first enhancement of the LSP implementation. Implementing the progress/create request. Other LSP server get this now for free which is really nice.

ra_progress.png

Diagnostic for current file

If you have some problems in your opened rust source file you will immediatly see the triangle on the top indicating some errors.

ra_diagnostic.png

These diagnostic information are generated from cargo check called via Rust Analyzer. You can configure RA to use another diagnostic provider (at the moment i only know cargo clippy but its not restricted to that). Therefore i created the necessary plumbing to set this in GNOME Builder.

ra_settings.png

Autocompletion

Of course the plugin supports autocompletion via LSP. Watch it in action:

In my next post i want to show the remainding features like goto definition, show references, rename etc.

Design applications with convergence in mind

Navigation Hackgregator

Developing an application with convergence in mind will be a new space in linux application development. The upcoming Librem5 from Purism allows application developers to run standard applications in a new form factor.

They develop a companion library libhandy with Gtk widgets derived from standard Gtk to accomplish a convergence between desktop and smartphone usage without re-developing everything from scratch. This is really handy (pun intended) because most probably you just have to use a different container for most things. For example you used a GtkBox for a static sidebar in your application then you can use HdyLeaflet now which acts similar but offers in small form factors a different behaviour.

Fractal convergence

To design an application from the scratch its most probably best to think first about the small form factor and try later to fit a good desktop usage. I tried this with a simple hacker news reader application and my design looked like that:

Hackgregator convergence

This worked very well and i have a good understanding about the UX now. The smartphone usage is already implemented and next i want to make the desktop usage better.

Hackgregotar Final

I hope you liked my development logbook. I want to keep up with the development of this application and write from time to time a post about the current status.

Constructor attribute for shared libraries

I often read source code of different projects. Especially when i use them often like glib. I realized that glib has a glib-init file and wondered because i never had to call any initialization. Therefore this must be called by another mechanism.

glib-init.c includes a header called gconstructor.h which i know already from another project: gnome-builder. The header got probably copied but both projects use this for the same purpose:

execute a function to initialize a library on library-loading.

This is a really nice feature, which is not documented in the c standard. It is an extension from C compilers. If we read up the documentation we get:

__attribute__((constructor))

The constructor attribute causes the function to be called automatically before execution enters main ().

The aforementioned header tries to comply to various compilers or at least sets a preprocessor value to inform the user about missing functionality for this constructor attribute. As mentioned in the header file:

#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor)
#endif
G_DEFINE_CONSTRUCTOR(my_constructor)
static void my_constructor(void) {
...
}

Example

To demonstrate this, i created a simple example application with a shared library. The library looks like:

#include "gconstructor.h"
 
G_DEFINE_CONSTRUCTOR (this_runs_before_main)
 
void
this_runs_before_main (void)
{
  printf ("%s\n", "Before main");
}
 
void
library_func (void)
{
  printf ("%s\n", "Library Func");
}

I annotated one function with a constructor attribute. The library_func is exposed via the corresponding headerfile. The executable looks like:

#include "library.h"
 
int
main (int   argc,
      char *argv[])
{
  printf ("%s\n", "Main");
 
  library_func ();
 
  return 0;
}

Not very surprising the output looks like

Before main
Main
Library Func