Sunteți pe pagina 1din 68

Builder Documentation

Release 3.27.1

Christian Hergert, et al.

Oct 25, 2017


Contents

1 Contents 3
1.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 via Flatpak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1.1 Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.2 Local Flatpak Builds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.3 via JHBuild . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.3.1 Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.4 via Release Tarball . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.5 Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Exploring the Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.1 Project Greeter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.2 Workbench Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.3 Header Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.4 Switching Perspectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.5 Showing and Hiding Panels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.6 Build your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.7 Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2.8 Autocompletion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.9 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.10 Splitting Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.11 Searching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.12 Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.2.13 Command Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2.14 Transfers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.3 Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3.1 Creating and Importing Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3.1.1 Creating a new Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3.1.2 Cloning an Existing Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3.2 Building your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3.3 Debugging your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.3.4 Profiling your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.3.5 Sharing your Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.4 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4.1 Enabling and Disabling Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4.2 Creating Your First Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.4.2.1 Loading our Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

i
1.4.2.2 Embedding Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.4.3 Extending the Workbench . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.4.3.1 Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.4.3.2 Registering Workbench Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1.4.3.3 Adding Widgets to the Header Bar . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.4.3.4 Registering Perspectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.4.3.5 Adding Panels to the Workbench . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.4.4 Extending the Greeter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.4.4.1 Project Miners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.4.4.2 Project Creation Workflows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.4.5 Extending the Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.4.5.1 Extending the Editor View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.4.5.2 Managing Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.4.5.3 Syntax Highlighting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.4.5.4 Diagnostics and Fix-Its . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.5.5 Autocompletion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.5.6 Snippets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.5.7 File Settings and Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.6 Symbols and Semantic Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.6.1 Go To Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.6.2 Extending the Symbol Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.6.3 Renaming Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.7 Extending the Build Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.7.1 Implementing a Build System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.4.7.2 Extending the Build Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
1.4.8 Processes and Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.4.8.1 Application Runtimes and Containers . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.4.8.2 Subprocesses and Psuedo Terminals . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.4.9 Extending the Device Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.4.10 Extending the Run Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
1.4.11 Registering Keybindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.4.12 Integrating Language Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.4.13 Extending Project Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.4.14 Extending Application Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.4.14.1 Extended Menu Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
1.4.14.2 Accessing Merged Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.4.15 Registering Application Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
1.4.16 Creating and Performing Transfers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
1.4.17 Managing Worker Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.4.18 Integrating Version Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.5 How-To Guides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.5.1 Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.5.1.1 Changing Indentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
1.5.1.2 Search and Replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
1.5.1.3 Jump to Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
1.5.1.4 Searching for Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
1.6 Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
1.6.1 Verbose Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
1.6.2 Support Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
1.6.3 Counters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
1.6.4 Test Builder Nightly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
1.6.5 File a Bug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
1.7 Contributing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
1.7.1 Planning and Project Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

ii
1.7.1.1 Responsibilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
1.7.2 Writing Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
1.7.2.1 Submitting Patches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
1.7.2.2 Creating a Patch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
1.7.2.3 Submitting a Patch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
1.7.2.4 GNOME git Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.7.3 Contributing Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.7.3.1 Where to Contribute? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.7.4 IRC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.7.5 File A Bug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.7.6 Find A Bug To Work On . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
1.7.7 Building From Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
1.8 Credits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

iii
iv
Builder Documentation, Release 3.27.1

Welcome to the Builder project!


We’re excited to have you here! The Builder project started out of a class teaching people to program for the GNOME
platform. In the process, we realized that we need to improve our tooling so we started creating Builder! We hope you
love using Builder to create great software for GNOME!

Contents 1
Builder Documentation, Release 3.27.1

2 Contents
CHAPTER 1

Contents

Installation

The preferred installation method for Builder is via Flatpak. This provides a bandwidth efficient and safe to use
installation method that can be easily kept up to date. It is also the engine behind Builder’s powerful SDK!

via Flatpak

If you have a recent Linux distribution, such as Fedora 26, simply download the Stable Flatpak and click Install when
Software opens. If Software does not automatically open, try opening the Stable flatpakref by double clicking it in
your file browser.
If you want to track Builder development, you might want the Nightly channel instead of Stable.

Note: To build flatpak-based applications, ensure that the flatpak-builder program is installed. On Fedora,
this is the flatpak-builder package.

Command Line

You can also use the command line to install Builder:


Stable

$ flatpak install --from https://flathub.org/repo/appstream/org.gnome.Builder.


˓→flatpakref

$ flatpak run org.gnome.Builder

Nightly

3
Builder Documentation, Release 3.27.1

$ flatpak install --user --from https://git.gnome.org/browse/gnome-apps-nightly/plain/


˓→gnome-builder.flatpakref

$ flatpak run org.gnome.Builder

Note: Nightly builds are built with tracing enabled. The tracing is fairly lightweight, but it includes a great deal of
more debugging information.

Local Flatpak Builds

You can also build Builder as a flatpak yourself to test local changes. First, make a repo for your local builds:

$ mkdir ~/my-flatpak-builds
$ flatpak remote-add --user --no-gpg-verify my-flatpak-builds ~/my-flatpak-builds

Now, in Builder’s source directory, use flatpak-builder to build a Builder flatpak and install it

$ git clone https://git.gnome.org/browse/gnome-builder/


$ cd gnome-builder
$ mkdir app
$ flatpak-builder --ccache --repo=$HOME/my-flatpak-builds app org.gnome.Builder.json
$ flatpak install --user my-flatpak-builds org.gnome.Builder

Note: After following these steps once you can omit adding the remote or creating the app directory. You’ll also
need to add the --force-clean option to flatpak-builder and use flatpak update rather than flatpak
install.

via JHBuild

If you plan on contributing to the GNOME desktop and application suite, you may want to install Builder via JHBuild.
See the Newcomers Tutorial for more information on joining the community and installing JHBuild.
We are aggressively moving towards using Flatpak for contributing to Builder, but we aren’t quite there yet.

Command Line

Note: Please review the GNOME Newcomers Tutorial on how to build a GNOME application before proceeding.

# Make sure you have the following packages installed before starting

# On Fedora
$ sudo dnf install clang-devel llvm-devel libssh2-devel

# On Ubuntu
$ sudo apt-get install clang-3.9 libclang-3.9-dev llvm-3.9-dev libssh2-1-dev

4 Chapter 1. Contents
Builder Documentation, Release 3.27.1

$ git clone git://git.gnome.org/jhbuild.git


$ cd jhbuild
$ ./autogen.sh --simple-install
$ make
$ make install
$ jhbuild sysdeps --install gnome-builder
$ jhbuild build gnome-builder
$ jhbuild run gnome-builder

Warning: While it may be tempting to install jhbuild using your Linux distribution’s package manager, it will
lack an updated description of the GNOME modules and is therefore insufficient. Always install jhbuild from git.

via Release Tarball

We do not recommend installing from release tarballs unless you are a Linux distribution. Builder has a complex set
of dependencies which heavily target the current release of GNOME. Keeping up with these requires updating much
of the GNOME desktop.
Please install via Flatpak, which does not have this restriction.
We use Meson (and thereby Ninja) to build Builder.

$ meson . build
$ ninja -C build install

Troubleshooting

If you are having trouble running Builder, start Builder with verbose output. This will log more information about
the running system. The gnome-builder program can take multiple arguments of -v to increase verbosity. For
example, if running from flatpak:

$ flatpak run org.gnome.Builder -vvvv

If you’re running from a system installed package of Builder, the binary name is gnome-builder.

$ gnome-builder -vvvv

If your issue persists, please consider filing a bug.

Exploring the Interface

The following sections will help you get to know Builder.


• Project Greeter
• Workbench Window
• Header Bar
• Switching Perspectives
• Showing and Hiding Panels

1.2. Exploring the Interface 5


Builder Documentation, Release 3.27.1

• Build your Project


• Editor
• Autocompletion
• Documentation
• Splitting Windows
• Searching
• Preferences
• Command Bar
• Transfers

Project Greeter

When you start Builder, you will be asked to select a project to be opened:

The window displays projects that were discovered on your system. By default, the ~/Projects directory will be
scanned for projects when Builder starts. Projects you have previously opened will be shown at the top.
Selecting a project row opens the project or pressing “Enter” will open the last project that was open. You can also
start typing to search the projects followed by “Enter” to open.
If you’d like to remove a previously opened project from the list, activate Selection mode. Press the “Select” button in
the top right corner to the left of the close application button and then select the row you would like to remove. Select
the row(s) you’d like to remove and then click “Remove” in the lower left corner of the window.

Workbench Window

The application window containing your project is called the “Workbench Window”. The Workbench is split up into
two main areas. At the top is the Header Bar and below is the current “Perspective”.
Builder has many perspectives, including the Editor, Build Preferences, Application Preferences, and the Profiler.

6 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Header Bar

The header bar is shown below. This contains a button in the top left for Switching Perspectives. In the center is the
“OmniBar” which can be used to Build your Project.

To the right of the OmniBar is the Run button. Clicking the arrow next to Run allows you to change how Builder will
run your application. You can run normally, with a debugger, profiler, or event with Valgrind.
On the right is the search box. Type a few characters from the file you would like to open and it will fuzzy search your
project tree. Use “Enter” to complete the request and open the file.
To the right of the search box is the workbench menu. You can find less-used features here.

Switching Perspectives

To switch perspectives, click the perspective selector button in the top left of the workbench window. Perspectives that
support a keyboard accelerator will display the appropriate accelerator next to name of the perspective.

Select the row to change perspectives.

Showing and Hiding Panels

Sometimes panels get in the way of focusing on code. You can move them out of the way using the buttons in the top
left of the workbench window.

When entering Fullscreen mode, Builder will automatically dismiss the panels for your convenience.
Additionally, you can use the “left-visible” or “bottom-visible” commands from the Command Bar to toggle their
visibility.

Build your Project

To build your project, use the OmniBar in the center of the header bar. To the right of the OmniBar is a button for
starting a build as shown in the image below.

1.2. Exploring the Interface 7


Builder Documentation, Release 3.27.1

You can also use the “build”, “rebuild”, “install”, or “clean” commands from the command bar.
While the project is building, the build button will change to a cancel button. Clicking the cancel button will abort the
current build.

8 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Editor

When Builder opens your project, it will place you in the editor perspective. This is where you develop your project.

1.2. Exploring the Interface 9


Builder Documentation, Release 3.27.1

10 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Along the left is the project sidebar. It contains the project tre, list of open documents, todo items, and build errors.
Generally, it contains the “source” or things to work on in your project.
Along the bottom is the utilities panel. Here you will find things like the debugger, terminal, build, and application
console.

Autocompletion

Builder has built-in support for various autocompletion engines. Start typing to get word suggestions.

Documentation

If you hover the pointer over API that Builder knows about, it can show you the documentation. You can also use F2 to
bring up the documentation with your insertion cursor on the word. Use Shift+K if you’re using Vim keybindings.

1.2. Exploring the Interface 11


Builder Documentation, Release 3.27.1

Splitting Windows

Builder can show you multiple editors side-by-side. In the editor view use “Open in New Frame” to split a document
into two views.

12 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Afterwards, you’ll see the editors side-by-side like such:

1.2. Exploring the Interface 13


Builder Documentation, Release 3.27.1

To close a split, use the close button in the top right of the editor.

Searching

You can search for files and symbols in your project using the search entry at the top right. To focus the search entry
with the keyboard use Control+..
You can fuzzy search for files by typing a few characters from the file name.

14 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Builder will automatically index your project into a database if it uses a supported language. You can search this
database to jump to code such as functions or classes.

Preferences

The preferences perspective allows you to change settings for Builder and its plugins. You can search for preferences
using the keyword search in the top left of the preferences perspective.

1.2. Exploring the Interface 15


Builder Documentation, Release 3.27.1

Command Bar

The command bar provides a command line interface into Builder. You can type various actions to activate them.
To display the command bar, use the Control+Enter keyboard shortcut. You can release the command bar by
pressing Escape and return to the editor.
The command bar includes completion using Tab, similar to the terminal. Use this to explore the availble commands.

16 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Transfers

Sometimes it might be necessary for Builder to download content from the internet to build your project. When this
happens, you’ll see a transfers button displaying the progress in the top right.

1.2. Exploring the Interface 17


Builder Documentation, Release 3.27.1

Projects

Whether you want to create a new project or import an existing project, Builder has features that can help you. Take a
look below to learn how to create or import a project, build, and profile your application. As we add new features you
can learn about them here.

Creating and Importing Projects

Builder supports creating new projects and importing existing projects. When importing a project, you can either open
it from your local computer or clone it from a remote git repository.

Creating a new Project

To create a new project, select “New” from the project greeter. The project creation guide will be displayed.

18 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Give your project a meaningful name, as this is not easily changeable later. The project name should not include
spaces and if the project needs multiple words, use a hyphen “-” to separate the words.
Choose the language you would like to use for the project. Depending on the language, different templates are
available.
Choosing a license helps promote sharing of your application. Builder is licensed as GPLv3 or newer and we suggest
using GPLv3 when writing new applications for GNOME.
If you do not want git-based version control, turn off the switch to disable git support.
Lastly, select a suitable template for your application. Some patterns are available to speed up the bootstrapping of
your project.

1.3. Projects 19
Builder Documentation, Release 3.27.1

Cloning an Existing Project

To clone an existing project, you will need the URL of your git repository. For example, to clone the Builder project,
you could specify: git://git.gnome.org/gnome-builder.git

After entering the URL, press the “Clone” button in the upper-right corner of the window and wait for the operation
to complete. Once the project has been cloned, you will be shown the workbench window.

Note: If the remote repository requires authorization a dialog will be displayed for you to input your credentials.

Building your Project

There are multiple ways to activate a build for your project:

20 Chapter 1. Contents
Builder Documentation, Release 3.27.1

• Press the Build Button on the right of the OmniBar as shown in the figure below
• Press the Control and F7 keys together
• Activate the command bar at the bottom of the Builder window by pressing Control and Enter and typing
“build” followed by the Enter key
• Click the OmniBar and press the Build button in the lower-left corner of the dialog window

Debugging your Project

Builder provides a debugger interface which can be extended for various languages. Currently, there is support for the
GNU Debugger which supports C, C++, and to some degree Rust, and Vala.
To start the debugger, select “Run with Debugger” from the Run button.

Warning: If Builder fails to locate a debugger that is compatible with your project, an error message will be
displayed.

After Builder has started the debugger, you’ll be greeted with a series of controls to step through your application.

1.3. Projects 21
Builder Documentation, Release 3.27.1

Note: The debugger support in Builder is currently limited, and will be expanded in future releases.

You can currently do a few things with the debugger in Builder.

22 Chapter 1. Contents
Builder Documentation, Release 3.27.1

• Step through execution in a variety of fashions


• Browse threads and thread stacks
• Explore current register values
• View the values of locals and parameters
• Add and remove breakpoints to aid in stepping through execution
• View disassembly when no source is available

Profiling your Project

Builder integrates with the Sysprof profiler to provide a robust sampling profiler.
Select “Run with Profiler” from the run button.

While the application is running, you’ll see a screen like this indicating that Sysprof is recording CPU samples on
your system.

1.3. Projects 23
Builder Documentation, Release 3.27.1

After stopping or exiting your program, you will be presented with a callgraph like the following. You can select a
time range within the CPU visualizer to limit the callgraph to samples recorded witin the selection.

24 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Sharing your Project

By default the application templates in Builder will use Flatpak. This makes it easy to bundle your project and share
it with a friend.
When using Flatpak, you can click the “Export Bundle” button in the build popover.

At this point Builder will build and install your project using the Flatpak build tooling. After it completes, Files will
open the build directory to reveal your new flatpak. This can be opened with Software to install on your or a friends
system.

1.3. Projects 25
Builder Documentation, Release 3.27.1

Extensions

The following provides examples of various ways you can extend Builder. All examples are provided in the Python 3
language for succinctness and clarity. You may also chooser to implement extensions in C or Vala.

Enabling and Disabling Extensions

Builder is built to be extensible from the ground up. In fact, many features of Builder are created as extensions. To
customize Builder for your workflow you may want to enable or disable some extensions.
To enable or disable an extension, use the perspective selector and navigate to “Preferences”. You can also use the
keyboard shortcut Control+,.

26 Chapter 1. Contents
Builder Documentation, Release 3.27.1

You’ll be presented with the preferences perspective which looks like:

1.4. Extensions 27
Builder Documentation, Release 3.27.1

Select “Extensions” from the menu on the left. Then use the switches on the right to enable or disable an extension.

Tip: Use the search entry in the upper left to search for an extension

28 Chapter 1. Contents
Builder Documentation, Release 3.27.1

1.4. Extensions 29
Builder Documentation, Release 3.27.1

Creating Your First Extension

Plugins consist of two things. First, a meta-data file describing the extension which includes things like a name, the
author, and where to find the extension. Second, the code which can take the form of a shared library or python
module.
Builder supports writing extensions in C, Vala, or Python. We will be using Python for our examples in this tutorial
because it is both succinct and easy to get started with.
First, we will look at our extension meta-data file. The file should have the file-suffix of ”.plugin” and it’s format is
familiar. It starts with a line containing “[Plugin]” indicating this is extension metadata. Then it is followed by a series
of “Key=Value” key-pairs.

Note: We often use the words “extension” and “plugin” interchangeably.

# my_plugin.plugin
[Plugin]
Name=My Plugin
Loader=python3
Module=my_plugin
Author=Angela Avery

Now we can create a simple plugin that will print “hello” when Builder starts and “goodbye” when Builder exits.

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Ide

class MyAppAddin(GObject.Object, Ide.ApplicationAddin):

def do_load(self, application):


print("hello")

def do_unload(self, application):


print("goodbye")

In the python file above, we define a new extension called MyAppAddin. It inherits from GObject.Object (which
is our base object) and implements the interface Ide.ApplicationAddin. We wont get too much into objects
and interfaces here, but the plugin manager uses this information to determine when and how to load our extension.
The Ide.ApplicationAddin requires that two methods are implemented. The first is called do_load and is
executed when the extension should load. And the second is called do_unload and is executed when the plugin
should cleanup after itself. Each of the two functions take a parameter called application which is an Ide.
Application instance.

Loading our Extension

Now place the two files in ~/.local/share/gnome-builder/plugins as my_plugin.plugin and


my_plugin.py. If we run Builder from the command line, we should see the output from our plugin!

[angela@localhost ~] gnome-builder
hello

30 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Now if we close the window, we should see that our plugin was unloaded.

[angela@localhost ~] gnome-builder
hello
goodbye

Embedding Resources

Sometimes plugins need to embed resources. Builder will automatically load a file that matches the name
$module_name.gresource if it placed alongside the $module_name.plugin file.

Note: If you are writing an extension in C or Vala, simply embed GResources as normal.

Listing 1.1: First we need to create a my-plugin.gresource.xml file describing our resources
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/builder/plugins/my-plugin">
<file preprocess="xml-stripblanks" compressed="true">gtk/menus.ui</file>
</gresource>
</gresources>

Next, compile the resources using glib-compile-resources.

glib-compile-resources --generate my-plugin.gresource my-plugin.gresource.xml

Now you should have a file named my-plugin.gresource in the current directory. Ship this file along with your
my-plugin.plugin and Python module.
Next, continue on to learn about other interfaces you can implement in Builder to extend it’s features!

Extending the Workbench

Basics

The basic mechanics of extending the workbench requires first creating an Ide.WorkbenchAddin. Your subclass
will created for each instance of the Ide.Workbench. This conveniently allows you to track the state needed for
your plugin for each workbench.

Listing 1.2: A Basic WorkbenchAddin to demonstrate scaffolding


import gi

from gi.repository import GObject


from gi.repository import Ide

class BasicWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):

def do_load(self, workbench: Ide.Workbench):


pass

def do_unload(self, workbench: Ide.Workbench):


pass

1.4. Extensions 31
Builder Documentation, Release 3.27.1

You will notice that at the top we import the packages we’ll be using. Here we use the GObject and Ide packages
from GObject Introspection.
We then create a class which inherits from GObject.Object and implements the Ide.WorkbenchAddin in-
terface. The Ide.WorkbenchAddin interface has two virtual methods to override, Ide.WorkbenchAddin.
load() and Ide.WorkbenchAddin.unload().

Note: PyGObject uses do_ prefix to indicate we are overriding a virtual method.

The load virtual method is called to allow the plugin to initialize itself. This method is called when the workbench
is setup or your plugin is loaded.
When the unload virtual method is called the plugin should clean up after itself to leave Builder and the workbench
in a consistent state. This method is called when the workbench is destroyed or your plugin is unloaded.

Registering Workbench Actions

Using Gio.Action is a convenient way to attach actions to the workbench that contain state. For example, maybe
for use by a button that should be insensitive when it cannot be used. Additionally, actions registered on the workbench
can be activated using the command bar plugin.

Listing 1.3: Registering an action on the workbench


import gi

from gi.repository import GObject


from gi.repository import Gio
from gi.repository import Ide

class MyWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):

def do_load(self, workbench):


action = Gio.SimpleAction.new('hello', None)
action.connect('activate', self.hello_activate)
workbench.add_action(action)

# If you have a lot of actions to add, you might


# consider creating an action group.
group = Gio.SimpleActionGroup.new()
group.add_action(action)
workbench.insert_action_group('my-actions', group)

def do_unload(self, workbench):


workbench.remove_action('hello')

# And if you used an action group


workbench.insert_action_group('my-actions', None)

def hello_activate(self, action, param):


print('Hello activated!')

This adds a new action named hello to the workbench. It can be connected to widgets by using the win.hello
action-name. Additionally, you can call the action with hello from the command bar.
To toggle whether or not the action can be activated, set the Gio.SimpleAction:enabled property.

32 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Adding Widgets to the Header Bar

You might want to add a button to the workbench header bar. To do this, use an Ide.WorkbenchAddin and fetch
the header bar using Ide.Workbench.get_headerbar(). You can attach your widget to either the left or the
right side of the Ide.OmniBar in the center of the header bar. Additionally, by specifying a Gtk.PackType, you
can align the button within the left or right of the header bar.
We suggest using Gio.SimpleAction to attach an action to the workbench and then activating the action using
the Gtk.Button:action-name property.

Listing 1.4: Adding a button to the workbench header bar


import gi

from gi.repository import GObject


from gi.repository import Ide

class MyWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):

def do_load(self, workbench):


headerbar = workbench.get_headerbar()

# Add button to top-center-left


self.button = Gtk.Button(label='Click', action_name='win.hello', visible=True)
headerbar.insert_left(self.button, Gtk.PackType.PACK_END, 0)

def do_unload(self, workbench):


# remove the button we added
self.button.destroy()
self.button = None

Registering Perspectives

Everything in Builder below the header bar is implemented as a “Perspective”. For example, the editor is a perspective
and so is the preferences interface.
You may want to create a perspective if you require the users full attention and other editor components may be
distracting.

Note: We generally suggest looking for alternatives to creating a perspective as it can be cumbersome for the user to
switch contexts.

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Ide
from gi.repository import Gtk

class MyPerspective(Gtk.Bin, Ide.Perspective):


def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.add(Gtk.Label(label='My Perspective', visible=True))

1.4. Extensions 33
Builder Documentation, Release 3.27.1

def do_get_icon_name(self):
return 'gtk-missing'

def do_get_title(self):
return 'My Perspective'

def do_get_accelerator(self):
return '<Control><Shift><Alt>Z'

class MyWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):


perspective = None

def do_load(self, workbench):


self.perspective = MyPerspective(visible=True)
workbench.add_perspective(self.perspective)

def do_unload(self, workbench):


self.perspective.destroy()
self.perspective = None

Adding Panels to the Workbench

You may want to write an extension that adds a panel which displays information to the user. Builder provides API
for this via the “Editor Perspective”.
At a high level, the design of the editor is broken into four parts.
• The code editors in the center of the perspective
• The left panel, which contains the “sources” of actions
• The bottom panel, which contains utilities
• The right panel, which is transient and contextual to the operation at hand
The easiest way to add a panel is to register an Ide.EditorAddin which adds the panels in the do_load()
function. You’ll be provided access to the editor perspective with the editor variable.

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Ide
from gi.repository import Gtk
from gi.repository import Dazzle

class MyEditorAddin(GObject.Object, Ide.EditorAddin):

def do_load(self, editor):

# Add a widget to the left panel (aka Sidebar)


self.panel = Gtk.Label(visible=True, label='My Left Panel')
left_panel = editor.get_sidebar()
left_panel.add_section('my-section',
'My Section Title',
'my-section-icon-name',

34 Chapter 1. Contents
Builder Documentation, Release 3.27.1

None, # Menu id if necessary


None, # Menu icon name if necessary
self.panel,
100) # Sort priority

# To add a utility section


self.bottom = Dazzle.DockWidget(title='My Bottom Panel', icon_name='gtk-
˓→missing', visible=True)

self.bottom.add(Gtk.Label(lable='Hello, Bottom Panel', visible=True))


editor.get_utilties().add(self.bottom)

def do_unload(self, editor):

# Remove our widgets


self.panel.destroy()
self.bottom.destroy()

self.bottom = None
self.panel = None

Extending the Greeter

The greeter is the view the user is presented with when starting Builder. In the following image, you can see the
various ways to create a new project in the top left along with existing projects in the main content area.

Project Miners

To add projects to the project list section of the greeter, you must implement a project miner. You might want one of
these if you would like to show projects that are found through an external service such as gitlab or from mining the
users home directory.
To do this, we must implement an Ide.ProjectMiner which emits the Ide.
ProjectMiner::discovered() signal when a project has been discovered.

1.4. Extensions 35
Builder Documentation, Release 3.27.1

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Gio
from gi.repository import Ide

class MyProjectMiner(GObject.Object, Ide.ProjectMiner):

def do_mine_async(self, cancellable, callback, data):


task = Gio.Task.new(self, cancellable, callback)

# ... Now run your discovery code.

info = Ide.ProjectInfo()
info.set_name('Secret Project')
info.set_file(Gio.File.new_for_path('Projects/.secret_project'))
info.set_languages(['C', 'Python'])

# If you set the project as recent, it will show up in the upper


# section rather than "Other Projects"
info.set_is_recent(True)

# See libide/projects/ide-project-info.h for more options you


# can provide on the Ide.ProjectInfo.

# Now notify of the discovered info.


self.emit_discovered(info)

task.return_boolean(True)

def do_mine_finish(self, task):


return task.propagate_boolean()

Project Creation Workflows

You can add a new button to the project creation bar using an Ide.GenesisAddin.

Note: Adding buttons to the project creation section does not scale well. If you really think you need something here,
talk to our designers so that we can accomidate a new design for your use case.

It is also possible to add a project creation workflow without adding a button to the headerbar. Some plugins such as
flatpak use this to clone sources via a hidden gnome-builder command line switch.
# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Gio
from gi.repository import Gtk
from gi.repository import Ide

class MyGenisisAddin(GObject.Object, Ide.GenesisAddin):

36 Chapter 1. Contents
Builder Documentation, Release 3.27.1

widget = None

def do_get_title(self, application):


return "Magic Wand"

def do_get_label(self, application):


return "Magic Wand"

def do_get_widget(self, application):


if not self.widget:
self.widget = Gtk.Label(label='My New Genesis Addin', visible=True)
return self.widget

def do_get_priority(self):
# for positioning within the buttons
return 100

def do_run_async(self, cancellable, callback, data):


task = Gio.Task.new(self, cancellable, callback)
# Do async project creation, and then open project.
task.return_boolean(True)

def do_run_finish(self, task):


return task.propagate_boolean()

Extending the Editor

Extending the Editor View

You might want to add additional widgets or perform various operations on the view as the user interacts with the
code-editor. One way to do this is to create an Ide.EditorViewAddin in your plugin. Implementing this interface
allows you to be notified whenever a new view is created as well as when the current language changes.
Additionally, if you only want your plugin to be enabled when certain languages are active, you can set the
X-Editor-View-Languages=c,cplusplus keyword in your .plugin file. In the example provided, the
plugin interface would be enabled for C and C++ files.

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Gtk
from gi.repository import GtkSource
from gi.repository import Ide

class MyEditorViewAddin(GObject.Object, Ide.EditorViewAddin):

def do_load(self, view):


"""
@view is an Ide.EditorView which contains the buffer and sourceview.
"""

# You get get the Ide.Buffer using


buffer = view.get_buffer()

1.4. Extensions 37
Builder Documentation, Release 3.27.1

# Or the Ide.SourceView widget


source_view = view.get_view()

# Toggle the overview map


view.set_show_map(True)
view.set_auto_hide_map(True)

# Scroll to a given line


view.scroll_to_line(100)

# Change the language


lang = GtkSource.LanguageManager.get_default().get_language('c')
view.set_language(lang)

# Jump to the next error


view.move_next_error()

# Jump to the next search result


view.move_next_search_result()

def do_unload(self, view):


"""
This should undo anything you setup when loading the addin.
"""

def do_language_changed(self, lang_id):


print("language was changed to", lang_id)

def do_stack_set(self, stack):


print("View was moved to document stack", stack)

# If you have an Ide.LayoutStackAddin, you might want to coordinate


# between them. To locate your stack addin, you can fetch it like
# the following:
#
# Note that the module name must match Module= inyour .plugin file.
module_name = 'my-plugin-module'
other_addin = Ide.LayoutStackAddin.find_by_module_name(stack, module_name)

Managing Buffers

Syntax Highlighting

Regex-based Highlighting

Syntax highlighting in Builder is performed by the GtkSourceView project. By providing an XML description of the
syntax, GtkSourceView can automatically highlight the language of your choice. Thankfully, GtkSourceView already
supports a large number of languages so the chances you need to add a new language is low. However, if you do, we
suggest that you work with GtkSourceView to ensure that all applications, such as Gedit, benefit from your work.
Chances are you can find existing language syntax files on your system in /usr/share/gtksourceview-3.0/
language-specs/. These language-spec files serve as a great example of how to make your own. If it is not there,
chances are there is already a .lang file created but it has not yet been merged upstream.

38 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Bundling Language Specs

Should you need to bundle your own language-spec, consider using GResources to embed the language-spec within
your plugin. Then append the directory path of your language-specs to the GtkSource.LanguageManager so it
knows where to locate them.

from gi.repository import GtkSource

manager = GtkSource.LanguageManager.get_default()
paths = manager.get_search_path()
paths.append('resources:///org/gnome/builder/plugins/my-plugin/language-specs/')
manager.set_search_path(paths)

Symantic Highlighting

If the language you are using provides an AST you may want to highlight additional information not easily decern-
able by a regex-based highlighter. To simplify this, Builder provides the Ide.HighlightEngine and Ide.
Highlighter abstractions.
The Ide.HighlightEngine provides background updating of the document so that your Ide.Highlighter
implementation can focus on highlighting without dealing with performance impacts.
Out of simplicity, most Ide.Highlighter implementations in Builder today use a simple word index and highlight
based on the word. However, this is not required if you prefer to do something more technical such as matching ranges
to the AST.

Diagnostics and Fix-Its

Autocompletion

Snippets

File Settings and Indentation

Symbols and Semantic Analysis

Go To Definition

Extending the Symbol Tree

Renaming Symbols

Extending the Build Pipeline

Implementing a Build System

Builder has support for many build systems such as autotools, meson, cmake, etc. The build system knows how to
find build targets (binaries or scripts that are installed) for the runner, knows how to find build flags used by the clang
service, and it can define where the build directory is. It also has an associated Ide.BuildPipelineAddin (see
the next section) that specifies how to do operations like build, rebuild, clean, etc.

1.4. Extensions 39
Builder Documentation, Release 3.27.1

Listing 1.5: An outline for a Buildsystem


import gi

from gi.repository import Gio, Ide

class BasicBuildSystem(Ide.Object, Ide.BuildSystem, Gio.AsyncInitable):

def do_init_async(self, priority, cancel, callback, data=None):


task = Gio.Task.new(self, cancel, callback)
task.set_priority(priority)
# do something, like check if a build file exists
task.return_boolean(True)

def do_init_finish(self, result):


return result.propagate_boolean()

def do_get_priority(self):
return 0 # Choose a priority based on other build systems' priority

def do_get_build_flags_async(self, ifile, cancellable, callback, data=None):


task = Gio.Task.new(self, cancellable, callback)
task.ifile = ifile
task.build_flags = []
# get the build flags
task.return_boolean(True)

def do_get_build_flags_finish(self, result):


if result.propagate_boolean():
return result.build_flags

def do_get_build_targets_async(self, cancellable, callback, data=None):


task = Gio.Task.new(self, cancellable, callback)
task.build_targets = []
# get the build targets
task.return_boolean(True)

def do_get_build_targets_finish(self, result):


if result.propagate_boolean():
return result.build_targets

How does Builder know which build system to use for a project? Each has an associated “project file” (configure.ac
for autotools) that has to exist in the source directory for the build system to be used. If a project has multiple project
files, the priorities of each are used to decide which to use. You can see where the priority is defined in the code above.
The project file is defined in the .plugin file with these lines (in the case of the make plugin):

40 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Listing 1.6: A snippet from a .plugin file


X-Project-File-Filter-Pattern=Makefile
X-Project-File-Filter-Name=Makefile Project

When a project has the right file, the build system will be initialized by IdeContext during its own initialization
process.

Extending the Build Pipeline

Builder uses the concept of a “Build Pipeline” to build a project. The build pipeline consistes of multiple “phases” and
build “stages” run in a given phase.
For example, in the Ide.BuildPhase.DOWNLAODS phase, you might have a stage that downloads and installs the
dependencies for your project. The Flatpak extension does this when building Flatpak-based project configurations.
The various phases of the build pipeline are the following and are always executed in exactly this sequence up to the
requested phase.

Build Phases

• Ide.BuildPhase.PREPARE is the first phase of the build pipeline. Use this to create necessary directories
and other preparation steps.
• Ide.BuildPhase.DOWNLOADS should be used to download and cache any build artifacts that are needed
during the build.
• Ide.BuildPhase.DEPENDENCIES should build any dependencies that are needed to successfully build
the project.
• Ide.BuildPhase.AUTOGEN should generate any necessary project files. Contrast this with the Ide.
BuildPhase.CONFIGURE phase which runs the configuration scripts.
• Ide.BuildPhase.CONFIGURE should run configuration scripts such as ./configure, meson, or
cmake.
• Ide.BuildPhase.BUILD should perform the incremental build process such as make or ninja.
• Ide.BuildPhase.INSTALL should install the project to the configured prefix.
• Ide.BuildPhase.EXPORT should be used to attach export hooks such as buliding a Flatpak bundle, Debian,
or RPM package.
Additionally, there are phases which have special meaning.
• Ide.BuildPhase.BEFORE can be XOR’d with any previous phase to indicate it should run as part of the
phase, but before the phase has started.
• Ide.BuildPhase.AFTER can be XOR’d with any previous phase to indicate it should run as part of the
phase, but after the phase has completed.
• Ide.BuildPhase.FINISHED indicates that a previous build request has finished.
• Ide.BuildPhase.FAILED indicates that a previous build request has failed.

1.4. Extensions 41
Builder Documentation, Release 3.27.1

Creating a Build Stage

To add a build stage, we start by creating a build pipeline addin. When it loads we will register our stage in the
appropriate phase.

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Ide

class MyBuildStage(Ide.Object, Ide.BuildStage):

def do_execute(self, pipeline, cancellable):


"""
This is a synchronous build stage, which will block the
main loop. If what you need to do is long running, you
might consider using do_execute_async() and
do_execute_finish().
"""
print("Running my build stage!")

def do_clean_async(self, pipeline, cancellable, callback, data):


"""
When the user requests that the build pipeline run the
clean operation (often before a "rebuild"), this function
will be executed. Use it to delete stale directories, etc.
"""
task = Gio.Task.new(self, cancellable, callback)
task.return_boolean(True)

def do_clean_finish(self, task):


return task.propagate_boolean()

def do_query(self, pipeline, cancellable):


"""
If you need to check if this stage still needs to
be run, use the query signal to check an external
resource.

By default, stages are marked completed after they


run. That means a second attempt to run the stage
will be skipped unless set_completed() is set to False.

If you need to do something asynchronous, call


self.pause() to pause the stage until the async
operation has completed, and then call unpause()
to resume execution of the stage.
"""
# This will run on every request to run the phase
self.set_completed(False)

def do_chain(self, next):


"""
Sometimes, you have build stages that are next to
each other in the pipeline and they can be coalesced
into a single operation.

42 Chapter 1. Contents
Builder Documentation, Release 3.27.1

One such example is "make" followed by "make install".

You can detect that here and reduce how much work is
done by the build pipeline.
"""
return False

class MyPipelineAddin(GObject.Object, Ide.BuildPipelineAddin):

def do_load(self, pipeline):


stage = MyBuildStage()
phase = Ide.BuildPhase.BUILD | Ide.BuildPhase.AFTER
stage_id = pipeline.connect(phase, 100, stage)

# track() can be used to auto-unregister the phase when


# the pipeline is removed.
self.track(stage_id)

Note: connect() was an unfortunate API choice and will likely be changed in a future release to avoid collisions with
signals.

Processes and Containers

Builder needs to support a wide variety of ways to spawn processes. Whether that is inside a build environment,
container, on the host, terminals, or even a remote system. The following sections describe some of the scenarios and
how to best perform the task at hand.

Application Runtimes and Containers

A core abstraction in the design of builder is Ide.Runtime. This provides a way to setup and execute processes
within a given environment. That environment could be your host operating system, a container, a build environment,
or even a remote system.
For example, if we want to run the make command for your project and that project is targeting the GNOME Sdk we
need to first enter the SDK environment. The Flatpak plugin provides an Ide.Runtime implementation to do this
so that before your subprocess is lanched, the runtime is setup and initialized for execution with an alternate mount
namespace, network namespace, and more.

How to get a runtime

If you need to run a process within the build environment you will want to access the runtime for the current build
configuration. The current build configuration can be accessed from the Ide.ConfigurationManager object.

config_manager = context.get_configuration_manager()
config = config_manager.get_current()
runtime = config.get_runtime()

Note: It is possible that the configured runtime does not yet exist, so remember to check for None.

1.4. Extensions 43
Builder Documentation, Release 3.27.1

Creating a Subprocess

To create a subprocess in the runtime, use the Ide.Subprocess.create_launcher() method and then spawn
a process using that launcher.

try:
launcher = runtime.create_launcher()
launcher.push_argv('which')
launcher.push_argv('make')
subprocess = launcher.spawn(None)
_, stdout, stderr = subprocess.communicate_utf8(None, None)
except Exception as ex:
print("Failed to create launcher: " + repr(ex))
return

Subprocesses and Psuedo Terminals

Creating Subprocesses

Builder provides a powerful abstraction for creating subprocesses. Ide.Subprocess allows you to setup and
modify how a processes should be launched without the burden of how to launch the subprocess. This means that
Builder can use different strategies based on the host system, subprocess requirements, and plugins that may need to
modify the program arguments.
When Builder is not running in a sandbox, it can generally execute subprocesses the normal way using fork and exec.
However, if Builder is sandboxed, it may need to run the subprocess on the host rather than inside the sandbox. To
ensure your subprocess is run on the host, use Ide.Subprocess.set_run_on_host().

Note: You can only run programs on the host that are already installed. Use which program-name to determine
if the process is available on the host.

If you are integrating an external tool, such as Valgrind, you might need to inject arguments into the argument array.
For the Valgrind case, Ide.Subprocess.prepend_argv() of "valgrind" would be appropriate.
Some runtime plugins may need to modify the argument array even further. For example, the Flatpak plugin will
require that all commands start with flatpak build ... so that the commands are never run on the host system,
but instead inside the runtime. Plugins that require this should inject their additional arguments from the Ide.
SubprocessLauncher.spawn() virtual-method so that plugins do not get confused about the placement of
arguments.

from gi.repository import GLib


from gi.repository import Ide

# You may want access to stdin/stdout/stderr. If so, ensure you specify


# the appropriate Gio.SubprocessFlags for your subprocess.
launcher = Ide.SubprocessLauncher.new(Gio.SubprocessFlags.STDOUT_PIPE |
Gio.SubprocessFlags.STDERR_PIPE |
Gio.SubprocessFlags.STDIN_PIPE)

# If you need to specify where to launch the process. The default


# is the home directory.
launcher.set_cwd(os.path.join(GLib.get_home_dir(), 'Projects'))

# Push some arguments onto argv

44 Chapter 1. Contents
Builder Documentation, Release 3.27.1

launcher.push_argv('which')
launcher.push_argv('ls')

# Set some environment variables


launcher.setenv('LANG', 'C', True)

# Spawn the process. If you pass in a Gio.Cancellable, you can kill the
# subprocess by calling Gio.Cancellable.cancel().
subprocess = launcher.spawn(None)

# We need to wait for the child to complete. If you want to read the
# output of the subprocess, see Ide.Subprocess.communicate_utf8().
# wait_check() will ensure the return value is zero. If you do not
# care about the return value, just use wait().
try:
subprocess.wait_check(None)
except Exception as ex:
print(repr(ex))

# May Ide.Subprocess API have async variants. Consider using them to


# avoid needlessly blocking threads.

Supervising Subprocesses

There are times where you might want to respawn a process in case it exits prematurely. Builder provides the Ide.
SubprocessSupervisor abstraction to simplify this for you.
The Ide.SubprocessSupervisor has a simple API. Just attach your Ide.SubprocessLauncher using
Ide.SubprocessSupervisor.set_launcher() and call Ide.SubprocessSupervisor.start().
If the subprocess begins flapping (exiting immediately after spawning) some delay will be added to slow things down.
To stop the subprocess, use Ide.SubprocessSupervisor.stop().
If you need access to the subprocess, you can access it either via the Ide.SubprocessSupervisor.
get_subprocess() method or by connecting to the Ide.SubprocessSupervisor::spawned() signal.

def on_subprocess_spawned(supervisor, subprocess):


print("Spawned process " + subprocess.get_identifier())

launcher = create_launcher()

supervisor = Ide.SubprocessSupervisor()
supervisor.set_launcher(launcher)
supervisor.connect('spawned', on_subprocess_spawned)
supervisor.start()

Psuedo Terminals

Psuedo terminals are tricky business. In general, if you need access to a PTY, use the VTE library like Builder’s
terminal plugin. For an example of how to setup the PTY, we use a flow like this.

// This code does little to no error checking.


// Your code should be more careful.

1.4. Extensions 45
Builder Documentation, Release 3.27.1

// First create our PTY master


VtePty *pty = vte_terminal_pty_new_sync (terminal,
VTE_PTY_DEFAULT | VTE_PTY_NO_LASTLOG | VTE_
˓→PTY_NO_UTMP | VTE_PTY_NO_WTMP,

NULL, &error);

// Now go through the PTY slave setup


int master_fd = vte_pty_get_fd (pty);

assert (grantpt (master_fd) != 0);


assert (unlockpt (master_fd) != 0);

// Get the path to the PTY slave


char name[PATH_MAX];
assert (ptsname_r (master_fd, name, sizeof name - 1) != 0);
name [sizeof name - 1] = '\0';

// Open the PTY slave


int slave_fd = open (name, O_RDWR | O_CLOEXEC);

// Now, when spawning a process, you can set stdin/stdout/stderr to the FD


// of the slave. We use dup() because the callee takes ownership.
ide_subprocess_launcher_take_stdin_fd (launcher, dup (slave_fd));
ide_subprocess_launcher_take_stdout_fd (launcher, dup (slave_fd));
ide_subprocess_launcher_take_stderr_fd (launcher, dup (slave_fd));
close (slave_fd);

When launching the subprocess with Builder, it will detect that stdin, stdout, or stderr are pseudo terminals
and perform the proper ioctl() setup for you. This allows for the PTY to cross the sandbox boundary to the host,
ensuring that you may have a host-based shell with a PTY from within the sandbox.

Extending the Device Manager

Builder provides an abstraction for external hardware devices. In fact, the local development machine is a special
device called the “local” device.
Devices are used in determining how to compile for the target architecture. In the future, we expect to gain additional
features such as deploying applications to the device and debugging. However it is too soon to speculate on that API.
You might want to provide support for an external device such as a embedded board, tablet, or phone. To do this, use
an Ide.DeviceProvider.

# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Ide

class MyDevice(Ide.Device):
def do_get_system_type(self):
return 'x86_64-linux-gnu'

class MyDeviceProvider(Ide.Object, Ide.DeviceProvider):


settled = GObject.Property(type=bool)

def __init__(self, *args, **kwargs):

46 Chapter 1. Contents
Builder Documentation, Release 3.27.1

super().__init__(*args, **kwargs)

self.devices = []

# Start loading the devices, and then emit device-added


# when it is added.
device = MyDevice(id='my-device', display_name='My Device')
self.devices.add(device)

# Since we are in __init__ here, this isn't really necesssary


# because it's impossible to connect and receive the signal.
# However, if you do some background work, you'll need to
# do this to notify the device manager of the new device.
self.emit_device_added(device)

# Mark us as "settled" which lets the device manager know


# that we've completed our initial scan of devices.
self.settled = True
self.notify('settled')

def do_get_devices(self):
return self.devices

Extending the Run Manager

Running projects is managed by the Ide.RunManager. You can provide special “run handlers” to alter how the
applications are executed.
For example, the Sysprof-based profiler uses a custom run handler to ensure that the profiler can monitor the process.
Additionally, Builder’s GDB debugger backend will alter the arguments so that GDB is used to launch the program.
Generally, hooking into the run manager involves adding a menu entry to the “Run Button” and a callback to process
the launch request.
Let’s take a look at a practical example using the Valgrind plugin.

Listing 1.7: Embed file as a resource matching /org/gnome/Builder/plugins/$module_name/gtk/menus.ui


<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="run-menu">
<section id="run-menu-section">
<item>
<attribute name="id">valgrind-run-handler</attribute>
<attribute name="after">default-run-handler</attribute>
<attribute name="action">run-manager.run-with-handler</attribute>
<attribute name="target">valgrind</attribute>
<attribute name="label" translatable="yes">Run with Valgrind</attribute>
<attribute name="verb-icon-name">system-run-symbolic</attribute>
<attribute name="accel">&lt;Control&gt;F10</attribute>
</item>
</section>
</menu>
</interface>

For more information on embedding resources with Python-based plugins, see creating embedded GResources.
Now register a run handler to handle the launch request.

1.4. Extensions 47
Builder Documentation, Release 3.27.1

from gi.repository import Ide


from gi.repository import GLib
from gi.repository import GObject

_ = Ide.gettext

class ValgrindWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):


workbench = None
has_handler = False

def do_load(self, workbench):


self.workbench = workbench

build_manager = self.workbench.get_context().get_build_manager()
build_manager.connect('notify::pipeline', self.notify_pipeline)
self.notify_pipeline(build_manager, None)

def notify_pipeline(self, build_manager, pspec):


run_manager = self.workbench.get_context().get_run_manager()

# When the pipeline changes, we need to check to see if we can find


# valgrind inside the runtime environment.
pipeline = build_manager.get_pipeline()
if pipeline:
runtime = pipeline.get_configuration().get_runtime()
if runtime and runtime.contains_program_in_path('valgrind'):
if not self.has_handler:
run_manager.add_handler('valgrind', _('Run with Valgrind'),
˓→'system-run-symbolic', '<primary>F10', self.valgrind_handler)

self.has_handler = True
return

if self.has_handler:
run_manager.remove_handler('valgrind')

def do_unload(self, workbench):


if self.has_handler:
run_manager = self.workbench.get_context().get_run_manager()
run_manager.remove_handler('valgrind')
self.workbench = None

def valgrind_handler(self, run_manager, runner):


# We want to run with valgrind --log-fd=N so that we get the valgrind
# output redirected to our temp file. Then when the process exits, we
# we will open the temp file in the builder editor.
source_fd, name = GLib.file_open_tmp('gnome-builder-valgrind-XXXXXX.txt')
map_fd = runner.take_fd(source_fd, -1)
runner.prepend_argv('--track-origins=yes')
runner.prepend_argv('--log-fd='+str(map_fd))
runner.prepend_argv('valgrind')
runner.connect('exited', self.runner_exited, name)

def runner_exited(self, runner, name):


# If we weren't unloaded in the meantime, we can open the file using
# the "editor" hint to ensure the editor opens the file.
if self.workbench:
uri = Ide.Uri.new('file://'+name, 0)
self.workbench.open_uri_async(uri, 'editor', 0, None, None, None)

48 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Registering Keybindings

Integrating Language Servers

Extending Project Search

Builder provides a global search box in the top right of the workbench. It can be extended to provide new types of
search results.
For example, the file-search extension provides search results based on files found in the project tree.

Additionally, the code-index extension provides search results based on an index built from your project code.

To add new search results, implement the Ide.SearchProvider interface in your plugin.
# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Gio
from gi.repository import Ide

1.4. Extensions 49
Builder Documentation, Release 3.27.1

class MySearchResult(Ide.SearchResult):
def __index__(self, context, i)
self.context = context
self.title = 'Item ' + str(i)
self.score = i / 100.0

def do_get_source_location(self):
"""
Currently, search results must point to a source location.

This may change in a future release to allow for more


flexability. Get in touch with us if you need this.
"""
return Ide.SourceLocation.new(self.context, line, line_offset, 0)

class MySearchProvider(Ide.Object, Ide.SearchProvider):

def do_search_async(self, query, max_results, cancellable, callback, data):


"""
Asynchronously searches for results.

The search engine will take the results from do_search_finish()


and add it to the search results list, sorted by score.
"""
task = Gio.Task.new(self, cancellable, callback)
task.results = []

for i in range(0, 10):


result = MySearchResult(self.get_context(), i)
task.results.append(result)

task.return_boolean(True)

def do_search_finish(self, task):


return task.results

Extending Application Menus

Menus in Builder are implemented using the GtkBuilder based menu definitions. These are created in gtk/
menus.ui files within your extensions resources.
Menus are automatically merged into the application when your plugin is loaded. If the plugin is unloaded by the user,
they will be automatically unloaded as well.

Extended Menu Features

The GMenu abstraction is somewhat limited in features that Builder requires. In particular, Builder needs advanced
sorting, icons, and accelerators for menu items. To overcome this, Builder has special “menu merging” code which
has been extrated into libdazzle (a utility library).
Here is an example of how the valgrind plugin extends the Run menu.

50 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Listing 1.8: Embed file as a resource matching /org/gnome/Builder/plugins/valgrind_plugin/gtk/menus.ui


<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- "run-menu" is the unique name of the run menu -->
<menu id="run-menu">
<!-- The menu has sections in it, just like GMenu -->
<section id="run-menu-section">
<item>
<!-- by specifying an id, we can position other items relatively -->
<attribute name="id">valgrind-run-handler</attribute>

<!-- after/before can be used to position this menu relative to others -->
<attribute name="after">default-run-handler</attribute>

<!-- the GAction name and action target to activate -->


<attribute name="action">run-manager.run-with-handler</attribute>
<attribute name="target">valgrind</attribute>

<!-- The label to display -->


<attribute name="label" translatable="yes">Run with Valgrind</attribute>

<!-- An "icon-name" to show if icons are to be visible in the menu -->


<attribute name="verb-icon-name">system-run-symbolic</attribute>

<!-- An accelerator to display if accelerators are to be displayed -->


<attribute name="accel">&lt;Control&gt;F10</attribute>
</item>
</section>
</menu>
</interface>

For more information on embedding resources with Python-based plugins, see creating embedded GResources.

Accessing Merged Menus

Merged menus are available via the Dzl.Application base class of Ide.Application.

menu = Ide.Application.get_default().get_menu_by_id('run-menu')

Registering Application Preferences

Builder’s preferences are designed in such a way that the core application preferences and extension preferences feel
cohesive. This is often not the case with “plugin-based” applications.
To do this, we created the Ide.Preferences interface. Extensions can implement the Ide.
PreferencesAddin interface and register preferences with the Ide.Preferences instance. This allows the
preferences to be seamlessly merged together based on the desired page, group, and preference type. They are even
searchable!

# my_plugin.py

import gi

from gi.repository import GObject

1.4. Extensions 51
Builder Documentation, Release 3.27.1

from gi.repository import Ide

_ = Ide.gettext

class MyPreferencesAddin(GObject.Object, Ide.PreferencesAddin):

def do_load(self, prefs):

# add a new switch row


self.completion_id = prefs.add_switch(
# to the code-insight page
'code-insight',

# in the completion group


'completion',

# mapping to the gsettings schema


'org.gnome.builder.extension-type',

# with the gsettings schema key


'enabled',

# And the gsettings path


'/',

# The target GVariant value if necessary (usually not)


None,

# title
_("Suggest Python completions"),

# subtitle
_("Use Jedi to provide completions for the Python language"),

# keywords
_("jedi python search autocompletion API"),

# with sort priority


30)

# there are plenty of other types of things you can add.


# see dzl-preferences.h for an example of the API you can call
# such as:
#
# - add_group()
# - add_list_group()
# - add_font_button()
# - add_radio()
# - add_spin_button()
# - add_file_chooser()
# - add_custom() (custom widgets)

def do_unload(self, prefs):


prefs.remove_id(self.completion_id)

52 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Creating and Performing Transfers

Builder provides a transfers button similar to a web browser. It should feel familiar to users of Nautilus (Files) and
Epiphany (Web).

To integrate with the transfers button, you need to create a subclass of Ide.Transfer and add it to the Ide.
TransferManager.
Builder provides a convenience transfer class called Ide.PkconTransfer which can be used to install packages
on the host machine.
# my_plugin.py

import gi

from gi.repository import GObject


from gi.repository import Gio
from gi.repository import Ide

class MyTransfer(Ide.Transfer):
def do_execute_async(self, cancellable, callback, data):
task = Gio.Task.new(self, cancellable, callback)

# ... perform transfer asynchronously, and update


# progress from the main thread occasionally, using

1.4. Extensions 53
Builder Documentation, Release 3.27.1

# self.set_progress(0..1)

self.set_status('Downloading...')
self.set_progress(0.1)
self.set_icon_name('gtk-missing')

# When finished, complete the task


task.return_boolean(True)

# Unless there was a failure, return the error


task.return_error(GLib.Error(my_exception))

def do_execute_finish(self, task):


return task.propagate_boolean()

# From your other plugin code, get the transfer manager and
# queue the transfer.

app = Gio.Application.get_default()
xfermgr = app.get_transfer_manager()

xfer = MyTransfer(title='Downloading Foo')


xfermgr.execute_async(xfer, None, None, None)

Managing Worker Processes

Integrating Version Control

How-To Guides

These quick and to the point “How To” articles are meant to help you answer common questions. If you have an
addition to the list, please let us know!

Contents

Changing Indentation

To change the indentation rules you have two options. Either globally for your system, or for just the current project.

Project-Wide

If you would like to change settings for just your project, use a .editorconfig file. You can add a .
editorconfig file to the root of your project in the editorconfig format.
It looks something like:
root = true

[*]
charset = utf-8
end_of_line = lf

54 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Globally

If you would like to change the indentation rules for your user, and thereby all projects which do not contain an .
editorconfig file, use the application preferences. You can access the preferences through the perspective selector
or using the Control+, keyboard shortcut.
First select “Programming Languages” from the sidebar on the left. Then select the programming language from the
list of options. On the right you will now see a list of preferences that may be tweaked for that language. Change the
indentation level to your desired preference.

Search and Replace

Search and replace can be used to replace all instances of a keyword with another form of text. To bring up the “Search
and Replace” tool, use Ctrl+h while focused in the editor.

Note: If you are using an alternate keyboard shortcut theme, your shortcut might be different.

Enter the search text in the first text entry. Enter the replacement text in the second text entry.

Tip: The replacement text may contain “regex backreferences” such as \1 and others. See the g_regex_replace
documentation for more information.

Select “Replace” to replace the next match or “Replace All” to replace all matches.

Using Special Characters

If you want to insert or replace a tab character using “search and replace”, you need to use the escaped form of tab
(\t). You can also do this for new lines with \n.

Jump to Definition

Builder supports jumping to the definition of a symbol. It is a quick and easy way to navigate the source of your
project.
If you’re using thd default or Emacs-based keybindings, use Alt+. while the insertion mark is on the symbol name.
If you’re using Vim-based keybindings, use the gd while the cursor is on the symbol name.
If you’re located at the declaration of a symbol (such as in a header file), you can jump to the implimentation using
this method. This requires that the code-index plugin is enabled.

Searching for Symbols

Builder supports searching for a symbol by name.


First, focus the search entry with Control+.. Then start typing the name of the symbol. Fuzzy searching is
supported. For example, searching for GcWin might match the symbol GcalWindow.
Press Up or Down arrows to move between the results. Press Enter to activate the search result and jump to the
symbol. You can press Escape to return to the editor.

1.5. How-To Guides 55


Builder Documentation, Release 3.27.1

Note: This feature requires that the code-index plugin is enabled.

Filtering searches

You can narrow search results by prefixing searches with the following keys:
• f for functions
• v for variables
• s for structs
• u for unions
• e for enums
• c for class
• a for constants
• m for macros

Troubleshooting

If you are having trouble with Builder you can help us help you by trying to do some basic troubleshooting. Here are
some steps you can go through to try to discover what is going wrong.

Verbose Output

You can increase the log verbosity of Builder by adding up to four -v when launching from the command line.

# If running from flatpak


flatpak run org.gnome.Builder -vvvv

# If using distribution packages


gnome-builder -vvvv

Support Log

Builder has support to generate a support log which can provide us with details. From the application menu, select
“Generate Support Log”. It will place a log file in your home directory.

Counters

Builder has internal counters which can be useful to debug problems. Use the command bar (activated by
Control+Enter) and type “counters” followed by Enter. This will bring up a new window containing the current
values of the counters.
If Builder has locked up, you can access the counters from outside of Builder. The command line tool
dazzle-list-counters, can be used to access the counters.

56 Chapter 1. Contents
Builder Documentation, Release 3.27.1

dazzle-list-counters `pidof gnome-builder`

Note: When running Builder from Flatpak, we do not currently expose the counters to the host. Use flatpak
enter $PID /bin/bash to enter the mount namespace and then run dazzle-list-counters.

Test Builder Nightly

If you are running the stable branch or an older distribution package, please consider trying our Nightly release to see
if the bug has already been fixed. Doing this before reporting bugs helps reduce the amount of bug traffic we need to
look at. We’ll usually ask you to try Nightly anyway before continuing the troubleshooting process.
See installing from Flatpak for installation notes.

File a Bug

We can help you troubleshoot! File a bug if you’re stuck and we can help you help us.
See the Builder Bugzilla for creating a bug report.

Contributing

If you’re interested in contributing to Builder and GNOME at large, we would love for you to join us! Only with people
like you can GNOME exist. We love seeing people that use GNOME transform into people that create GNOME.

Planning and Project Management

Many of us that work on the Builder code-base are great at writing code. But we are not so great at managing schedules,
planning feature priorities, and coordinating with other projects. Helping us do this in Builder will make you a shepard
of geeks.

Responsibilities

• Helping us stay on schedule with GNOME releases and releasing tarballs on time.
• Ensure that we plan the feature before writing it.
• Helping to plan features on realistic timelines.
• Planning a roadmap that makes sense. Some features do not matter unless other features are implemented first.
• Help us find new contributors and ensure that our community is healthy towards new recruits.

Writing Documentation

We are using sphinix to write our new documentation.


In conf.py you’ll see that we use the theme from readthedocs.io. That means you need to install that theme as well
as sphinx to build the documetnation.

1.7. Contributing 57
Builder Documentation, Release 3.27.1

Listing 1.9: Install dependencies for building documentation (Fedora 25)


sudo dnf install python3-sphinx python3-sphinx_rtd_theme

Listing 1.10: Now build the documentation with sphinx


[user@host gnome-builder/]$ cd doc
[user@host doc/]$ sphinx-build . _build
[user@host doc/]$ xdg-open _build/index.html

The first command builds the documentation. Pay attention to warnings which will be shown in red. Some of them
may be useful to help you track down issues quickly.
To open the documentation with your web browser, use xdg-open _build/index.html.

Submitting Patches

We will accept patches for documentation no matter how you get them to us. However, you will save us a lot of time
if you can:
• Create a patch with git.
• Create a new bug on Builder Bugzilla and attach the patch.

Creating a Patch

First off, if you have not configured git to include your full name and email, type the following in a terminal:

$ git config --global user.name 'My Full Name'


$ git config --global user.email 'example@example.com'

After you have modified the documentation to your liking, prepare the files to be committed to git. The add a short
commit message and commit the files.

[user@host doc/]$ git add path/to/file.rst


[user@host doc/]$ git commit -m 'doc: update example documentation'

Now we can export the patch to be uploaded to Builder Bugzilla

[user@host doc/]$ git format-patch HEAD^

At this point you’ll see a file similar to 0001-doc-update-example-documentation.patch in the current


directory. We want to upload this patch to Builder Bugzilla.

Submitting a Patch

Now that we have our patch file, we need to create a new bug. Head over to Builder Bugzilla and fill out the bug
details.
Just give a bit of information about what you documented, and then find the “Add an Attachment” section near the
bottom. Upload the patch file you exported with git format-patch HEAD^ above.
Click “Submit Bug” and we’ll take care of the rest!

58 Chapter 1. Contents
Builder Documentation, Release 3.27.1

GNOME git Best Practices

To learn more about using git with GNOME, including how to set up git, submitting patches, and good commit
messages, visit the git workflow GNOME wiki page.

Contributing Code

Where to Contribute?

Builder wants to become a powerful tool to enable GNOME developers to build great software. To do this we need
your help.
Do you have knowledge in a particular area of software development? You can use that knowledge to help Builder
expand it’s area of expertise.
Generally, code contributions fall into one of two categories: Application Plumbing or Plugins.

Application Plumbing

If you like working on application plumbing, which is the infrastructure that makes implementing plugins simple, then
you want to look at libide. Many of the core features of Builder are implemented here. That includes the application
window, plugin interfaces and core machinery of Builder.

Plugins

Plugins are how we integrate features into Builder for a specific problem. For example, the git plugin is the glue
between the version control abstraction in libide and git.
There are many existing plugins already. You might want to contribute to an existing one that does not yet serve your
needs well. Or maybe you want to create a new plugin that integrates a feature missing from Builder.

Running

You might find yourself running Builder from Builder. By default, that will activate and bring-forward your previous
instance of Builder. If you run Builder from the command-line with --standalone, it will not communicate with
another instance of Builder.

IRC

One great way to get started is to join us on IRC where you can chat with others who work on the Builder project. The
Builder developer team can be found on the Builder IRC channel.

File A Bug

If you think you’ve found a bug in Builder, head over to Builder Bug Tracker and file a report. We will get back to you
on any further details we need to track down the issue as soon as we can. Filing bugs helps us improve the softwrae
for everyone and we really appreciate your time.
For various spam reasons our bugtracker requires that you create an account. We hope this minor inconvenience is not
too much trouble.

1.7. Contributing 59
Builder Documentation, Release 3.27.1

Find A Bug To Work On

If you wish to start contributing code to Builder, simply pick a bug from this list of newcomer bugs.

Building From Source

Learn out how to install via JHBuild in our installation documentation.


Currently, JHBuild is how we recommend contributing to Builder. We do expect this to change very soon in that you’ll
be able to easily contribute to Builder from our flatpak-version of Builder.

Credits

Builder was started by Christian Hergert in 2014 to improve the quality of software for the GNOME ecosystem. Many
contributors have helped create and improve Builder to the state you find it today.
Artwork, code and documentation by

Alex285
Alexander Larsson
Alexandre Franke
Allan Day
Andreas Brauchli
Andreas Henriksson
anoop chandu
Anoop Chandu
Antoine Jacoutot
Anwar Sadath
Ben Iofel
Boris Egorov
burningTyger
Carlos Soriano
chandu
Christian Hergert
Cosimo Cecchi
Daiki Ueno
Damien Lespiau
Daniel Boles
Daniel Espinosa
David King
Debarshi
Dimitrios Christidis
Dimitris Zenios
Dor Askayo
Ekta Nandwani
Elad Alfassa
Erick Pérez Castellanos
Evgeny Shulgin
Fabiano Fidêncio
Fangwen Yu
Felix Schwarz
Fernando Fernandez
Florian
Florian Bäuerle
Florian Müllner

60 Chapter 1. Contents
Builder Documentation, Release 3.27.1

Garrett Regier
Gautier Pelloux-Prayer
Gennady Kovalev
Georges Basile Stavracas Neto
Georg Vienna
Giovanni Campagna
Günther Wutz
Hashem Nasarat
heroin
Hylke Bons
Ignacio Casal Quinteiro
Igor Gnatenko
Jakub Steiner
Jasper St. Pierre
Joaquim Rocha
Johan Svensson
Jonathon Jongsma
Jürg Billeter
Kris Thomsen
kritarth
Krzesimir Nowak
Lars Uebernickel
Lionel Landwerlin
Lucie Charvat
Lucie Dvorakova
Marcin Kolny
Marek Černocký
Marinus Schraal
Mario Sanchez Prada
Martin Blanchard
Mathieu Bridon
Mathieu Duponchelle
Matthew Leeds
Matthias Clasen
Megh Parikh
Michael Biebl
Michael Catanzaro
Mohammed Sadiq
Mohan R
namanyadav12
Paolo Borelli
Patrick Griffis
Peter Sonntag
Philip Chimento
Philip Withnall
Piotr Drag
˛
Raunaq Abhyankar
Ray Strode
Roberto Majadas
Sam Hewitt
Sebastien Lafargue
Sébastien Lafargue
Simon Schampijer
Sourav
Thibault Saunier
Timm Bäder
Ting-Wei Lan
Tobias Schönberg

1.8. Credits 61
Builder Documentation, Release 3.27.1

Trinh Anh Ngoc


Umang Jain
Wolf Vollprecht
Yannick Inizan
Yosef Or Boczko
Zhang Cheng
zilla@hmt.im

62 Chapter 1. Contents

S-ar putea să vă placă și