Custom Fleet Plugins for Your Kotlin Codebase | Vitaly Bragilevsky

Kotlin by JetBrains
14 Jul 202414:58

Summary

TLDRVitali Brail from JetBrains introduces the concept of custom Fleet plugins for coding projects. Fleet, a multi-language code editor, offers built-in tools for remote development and collaboration. However, for specific needs like custom views or external tool integration, custom plugins are essential. Brail demonstrates creating a simple 'count functions' plugin, emphasizing the importance of understanding Fleet's database and structured concurrency. He highlights the ease of developing plugins with just 100 lines of code and encourages developers to look forward to the public preview of Fleet plugins.

Takeaways

  • 😀 Vitali Brail from JetBrains is introducing custom Fleet plugins for coding bases.
  • 🔍 Fleet is a multi-language code editor designed for remote development and collaboration.
  • 🛠 Sometimes, out-of-the-box features aren't enough, and custom plugins are needed for specific tasks.
  • 📚 Custom plugins can provide additional insights, like code base size or cyclomatic complexity.
  • 💡 Creating a custom Fleet plugin involves writing code, running it in development, and publishing it on the marketplace.
  • 🚧 Fleet plugins are a work in progress and not yet available to everyone, but a public preview is coming.
  • 🌐 The architecture of Fleet centers around a workspace that manages projects and communicates with other components.
  • 🔧 Plugins for Fleet involve implementing components for the front end, workspace, and backend (which is an IntelliJ IDEA plugin).
  • 📝 The script provides a simple example of a 'count functions' plugin that updates a notification based on the number of functions in a code base.
  • 🔑 Two key principles for coding with Fleet are using transactions for changes and embracing Kotlin's structured concurrency.
  • 📈 The 'count functions' plugin is a concise example, implemented in under 100 lines of code, demonstrating the potential for more complex plugins.

Q & A

  • Who is Vitali Brailo, and what is his role at JetBrains?

    -Vitali Brailo is a Developer Advocate at JetBrains, where he works with the Fleet team to make Fleet plugins a reality.

  • What is Fleet, and what is its primary purpose?

    -Fleet is a code editor designed to support many programming languages simultaneously. It is aimed at providing a pleasant remote development experience and implementing collaboration scenarios.

  • Why might someone need to create a custom Fleet plugin?

    -One might need a custom Fleet plugin for various reasons, such as using unique resources in their codebase, integrating with external tools not available out of the box, or obtaining additional information about their codebase like total size or cyclomatic complexity.

  • How easy is it to create a custom Fleet plugin according to the transcript?

    -Creating a custom Fleet plugin is described as very easy. It involves writing code for the plugin, running Fleet with the plugin in development, and then publishing it on the marketplace for easy installation.

  • What is the current status of Fleet plugins according to the talk?

    -As of the talk, Fleet plugins are a work in progress and are not yet available to everyone. The team is working towards making them available for public preview.

  • Can you explain the 'count functions' plugin example mentioned in the script?

    -The 'count functions' plugin is a simple example that counts the number of top-level functions in a codebase. It updates a notification to reflect the current number of functions whenever changes are made to the code.

  • What are the two basic principles of coding when developing plugins for Fleet?

    -The two principles are: 1) Fleet is a distributed database with reactive queries, where every change is made through transactions, and 2) Fleet embraces Kotlin's structured concurrency, requiring developers to be proficient in its use.

  • How does the 'count functions' plugin interact with the Fleet database?

    -The plugin uses reactive queries to monitor changes in the abstract syntax tree of the file loaded into the editor. It performs a transaction to create and update a notification reflecting the current count of functions in the codebase.

  • What is the significance of the 'L' function in the context of the plugin?

    -The 'L' function is crucial as it is executed when the plugin is loaded into Fleet. It is where all the functionality of the plugin, such as registering actions and notifications, is registered.

  • How does the plugin manage notifications and actions?

    -The plugin registers a notification category and creates notifications within a transaction block. Actions are defined using a DSL (Domain-Specific Language) in Fleet, which specifies conditions for the action's availability and the function to execute when the action is triggered.

  • What is the role of structured concurrency in the plugin's coroutine execution?

    -Structured concurrency ensures that every coroutine is executed within a specific scope. If the plugin is unloaded, all coroutines within that scope are automatically cancelled, providing control over the plugin's functionality.

Outlines

00:00

😀 Introduction to Custom Fleet Plugins

Vitali Brailo, a Developer Advocate at JetBrains, introduces the concept of custom Fleet plugins. Fleet is a versatile code editor designed for multiple programming languages, with a focus on remote development and collaboration. Although Fleet offers built-in support for languages like C and Kotlin, as well as tools like Amper for project building, there are instances where developers might require custom functionality. This could include custom views for unique resources, integration with external tools, or additional insights into the codebase such as cyclomatic complexity. Vitali explains that creating a custom Fleet plugin is straightforward, involving writing code, testing it in development mode, and then publishing it on the marketplace for easy installation. However, he notes that Fleet plugins are a work in progress and not yet available to everyone, but the team is working towards a public preview.

05:00

đŸ› ïž Building a Simple 'Function Counter' Plugin

The speaker proceeds to demonstrate the process of creating a simple plugin for Fleet, using the 'Function Counter' as an example. He outlines the basic principles of coding for Fleet, emphasizing its nature as a distributed database with reactive queries and the importance of structured concurrency. The 'Function Counter' plugin, which counts the number of top-level functions in a Kotlin source file, is explained in detail. The plugin class is simple, with the main functionality registered in the 'load' function, including the creation and management of notifications and actions. The speaker describes how to create and update notifications within a transactional database context and how to define actions using a DSL (Domain-Specific Language) in Fleet. The core functionality involves querying changes in the abstract syntax tree of the file and updating the notification accordingly, showcasing the plugin's ability to interact with the Fleet database and editor.

10:01

🔍 Deep Dive into Plugin Implementation and Future Outlook

In the final paragraph, the speaker delves deeper into the implementation details of the 'Function Counter' plugin, highlighting the simplicity of the code, which consists of less than 100 lines. He explains the use of transactions for database changes and the structured concurrency approach that Fleet employs to manage plugin functionality. The speaker also discusses the reactive query mechanism that allows the plugin to respond to changes in the code, such as counting functions and updating the UI in real-time. The 'Count Functions' function is described as a straightforward interaction with the abstract syntax tree of the file loaded into the editor. The speaker concludes by expressing the team's ongoing efforts to make Fleet plugins publicly available, inviting users to look forward to the public preview and encouraging them to vote for the feature, adding a humorous note about the potential consequences of not receiving enough votes.

Mindmap

Keywords

💡Fleet

Fleet is a code editor developed by JetBrains, designed to support multiple programming languages simultaneously. It is central to the video's theme as the speaker discusses the development of custom plugins for enhancing its functionality. The script mentions Fleet's capabilities for remote development and collaboration, as well as its integration with other tools like Kotlin and Amper.

💡Developer Advocate

A Developer Advocate is a professional who acts as a bridge between a software company and its developer community. In the video, Vitali Brail, the speaker, identifies himself as a Developer Advocate at JetBrains, emphasizing his role in promoting the adoption and understanding of Fleet among developers.

💡Custom Fleet plugins

Custom Fleet plugins refer to user-created extensions for the Fleet code editor that add specific functionalities not available by default. The video's main focus is on how developers can create these plugins to tailor Fleet to their unique coding needs, such as integrating with external tools or obtaining additional insights into their codebase.

💡Remote development

Remote development is the ability to develop software remotely, often using cloud-based tools or services. The script mentions that Fleet was designed with remote development in mind, suggesting that it can connect to remote servers and provide a seamless coding experience away from a local development environment.

💡Collaboration scenarios

Collaboration scenarios refer to the various ways in which multiple developers can work together on a project. The video script indicates that Fleet is designed to implement effective collaboration features, which is a key aspect of its appeal to development teams.

💡Codlin

Codlin, likely a misspelling or specific term within the context of the video, seems to refer to a feature or tool within the Fleet ecosystem that supports Kotlin, a popular programming language. The script mentions Codlin as being available out of the box, indicating it as a built-in feature of Fleet.

💡Structured concurrency

Structured concurrency is a programming concept that organizes concurrent tasks in a way that makes it easier to manage their lifecycle, especially in the context of Kotlin's coroutines. The script emphasizes the importance of understanding structured concurrency when developing plugins for Fleet, as it is a core principle in the editor's architecture.

💡Reactive queries

Reactive queries are a mechanism for observing and responding to changes in data. In the context of the video, Fleet uses a distributed database with reactive queries, allowing plugins to be notified of and react to changes in the codebase, which is a key feature for creating dynamic and responsive plugins.

💡Abstract syntax tree (AST)

An abstract syntax tree is a tree representation of the syntactic structure of source code. The script uses the term when describing how the custom plugin counts functions in the code. It is a fundamental concept in programming language processing, allowing for operations like code analysis and transformation.

💡Plugin marketplace

The plugin marketplace is a platform where developers can publish and distribute their custom plugins for others to use. The video mentions the process of publishing a Fleet plugin to the marketplace, allowing for easy installation by other Fleet users with a single click.

💡IntelliJ IDEA plugin

IntelliJ IDEA is a widely used integrated development environment (IDE) by JetBrains, and the script mentions that the backend part of Fleet plugins is essentially an IntelliJ IDEA plugin. This indicates that developers familiar with IntelliJ IDEA will find it easier to create backend components for their Fleet plugins.

Highlights

Vitali Brailo, a developer advocate at JetBrains, discusses the creation of custom Fleet plugins for coding code bases.

Fleet is a multi-programming language code editor designed for remote development and collaboration.

Fleet comes with built-in support for languages like C and Kotlin, and tools like Amper for project building.

Custom plugins are needed for unique requirements such as custom views, external tool integration, and additional code base insights.

Creating a custom Fleet plugin involves writing code, running it in development mode, and publishing it to the marketplace.

Fleet plugins are currently a work in progress and not yet available to everyone.

A simple plugin example called 'count functions' dynamically updates the number of functions in a code base.

Fleet's architecture centers around a workspace that manages projects and interacts with various components.

Fleet's front end communicates with users, while the backend, such as IntelliJ's, handles heavy tasks like indexing and static analysis.

Plugin development for Fleet requires implementing components for the front end, workspace, and sometimes the backend.

Two fundamental principles of coding for Fleet include its distributed database nature and embracing Kotlin's structured concurrency.

The 'count functions' plugin is a concise example, implemented in under 100 lines of code.

The plugin class in Fleet is basic and may not provide an API, focusing instead on functionality registration.

Notifications in Fleet are managed through categories and editor entities, with updates handled via transactions.

Actions in Fleet are defined using a DSL, requiring an editor and reacting to changes in the code base.

Structured concurrency is utilized to manage plugin functionality, ensuring coroutines are cancelled when a plugin is unloaded.

The core of the 'count functions' plugin involves querying the abstract syntax tree for changes and updating notifications accordingly.

JetBrains aims to make Fleet plugin development open to everyone once the public preview is ready.

The talk concludes with an invitation for attendees to vote for the plugin feature, emphasizing its upcoming availability.

Transcripts

play00:06

[Music]

play00:10

so hi hi folks hi hi everyone I am

play00:13

Vitali brail I work at jet brains as a

play00:15

developer Advocate and I work with the

play00:18

fleet team to to make Fleet plugins

play00:22

actually happening so uh today I'm going

play00:26

to talk about Custom Fleet plugins for

play00:28

your codling code base so just to start

play00:32

uh Fleet is a code editor for many many

play00:36

programming languages at the same time

play00:40

and uh it was designed to make nice to

play00:42

have nice remote development to have to

play00:45

implement nice collaboration scenarios

play00:48

things like that and chances are that

play00:51

you already have your code base in C in

play00:55

cotlin and you manage them with a fleet

play00:59

and in Fleet we also have codlin

play01:02

multiplatform we also have Amper to

play01:06

build your projects maybe and then all

play01:08

this stuff is already there it is

play01:11

available out of the

play01:12

box but sometimes you need something

play01:16

else you need something

play01:18

custom and it can this can be different

play01:21

things like for example you use your own

play01:23

resources in your code base and you need

play01:26

custom views sometimes you want to

play01:29

integrate with with external tools which

play01:31

are not available out of the box

play01:33

sometimes you want to get some

play01:35

additional information about your code

play01:37

base for example What's the total size

play01:40

or something like cyclomatic complexity

play01:43

if you don't know what it is just in

play01:44

Wikipedia they tell you everything about

play01:47

that or AI or something abstraction

play01:50

complexity so sometimes you want to see

play01:52

if your comments are actually relevant

play01:54

to the code so something custom which is

play01:57

not available and at this very point

play02:00

point you might need to write a Custom

play02:03

Fleet plugin and in fact it's very easy

play02:06

to do you just create a rapper for uh

play02:09

the plug-in you write your code then you

play02:11

write Fleet you can run Fleet with a

play02:14

plugin in development and then you

play02:16

publish it on the marketplace and then

play02:19

everyone can install it just with single

play02:22

click from Fleet itself of course it's

play02:25

something like that like if you're

play02:26

drawing a o but uh I should say one

play02:29

thing here so Fleet plugins are work in

play02:34

progress at this type so they're not

play02:36

available for everyone but we're working

play02:39

towards making them available we're

play02:41

going towards our public uh preview for

play02:43

plugin so just uh uh in this talk I will

play02:47

show you something how you are supposed

play02:50

to do things like that and I will use

play02:53

one very simple example of a plug-in for

play02:56

Fleet so let me show it to you so I have

play03:00

Fleet I have some codlin project here

play03:03

and I have two functions you can see

play03:06

them and I have

play03:08

this action which was designed in this

play03:12

plugin which is called count functions

play03:15

and it shows this small uh notification

play03:18

here and it says that you have two

play03:20

functions in this code base in this file

play03:24

and let me for example add another

play03:26

function with this name and at this very

play03:29

the moment you can see that it was

play03:31

changed to three so you have two

play03:34

functions and then immediately you have

play03:36

three functions three top level

play03:37

functions in this code base so very

play03:40

simple plug-in and that's exactly what

play03:43

I'm going to present in this

play03:46

talk so Fleet is a product with very

play03:49

interesting very modern architecture

play03:52

workspace is in the center of Fleet it

play03:55

manages your project and it knows

play03:57

everything about any other component

play04:00

which is connected to it we also have

play04:03

one or many front end components

play04:06

responsible for actually communicating

play04:08

with the user like views some actions

play04:11

you edit your code with front ends there

play04:14

is syntax highlighting implementing

play04:16

there and then there is also backend

play04:18

part which in case of cotland is

play04:20

intellig backend which is a headless

play04:23

service from intell idea basically and

play04:26

it does heavy lifting like indexing

play04:29

static analysis Advanced code navigation

play04:31

stuff like that and if you develop

play04:34

plugins for Fleet you basically

play04:37

Implement some components for the front

play04:39

end part for the workspace part and also

play04:42

for the bend part now beend part is

play04:46

basically an intell J idea plugin so

play04:49

we're not talking about it here because

play04:51

it works right there on back end but

play04:54

workspace part and front end part they

play04:56

are just parts of app PL in and they

play05:00

become parts of lead itself and my count

play05:04

functions plugin actually works only on

play05:06

the front end part so it's called Fun

play05:08

counter and let's see how we can

play05:11

Implement something like

play05:14

that

play05:15

uh before starting writing code for

play05:18

Fleet we have to remember two basic

play05:21

principles of that coding principle

play05:24

number one Fleet is actually a

play05:27

distributed database with reactor qu

play05:30

queries every change that you are doing

play05:33

goes in a transaction so you write

play05:35

transactions to change everything in

play05:38

Fleet and you also have reactive queries

play05:41

so that you can uh quer make a query for

play05:44

something and then you get notifications

play05:47

about changes in that database and

play05:50

principle number two Fleet Embraces

play05:53

cortin structured concurrency scoped

play05:56

concurrency everything that you like in

play05:59

cotland it's there in Fleet so you have

play06:01

to be like professional in that stuff to

play06:05

develop plugins for Fleet okay um very

play06:10

uh like this this plugin that I showed

play06:13

you it's uh in 100 lines of code just

play06:17

single file we have uh special class for

play06:20

a plug-in and then several functions for

play06:23

managing notifications for actually

play06:26

counting functions so let's see what's

play06:29

inside that

play06:30

implementation so plug-in class is just

play06:33

a basic class very small one and in

play06:37

general plugins can Implement some API

play06:40

and in fact real Fleet code base is

play06:44

already it has a lot of plugins there

play06:46

and some of them provide some API for

play06:48

this plugin it's not needed so it's just

play06:50

unit my API is just unit nothing

play06:53

interesting so we don't provide anything

play06:55

we just do some other stuff then we also

play06:58

have some book keeping arguments here

play07:01

values it's for loading and unloading

play07:04

plugins it's for Fleet itself so this

play07:06

class basically is loaded using service

play07:09

loader like as usual in in Java uh gvm

play07:13

so this is for for that stuff and now

play07:16

the most important part of this

play07:17

definition is the L function L function

play07:21

is executed when you actually lowed your

play07:25

plugin in Fleet so every piece of

play07:28

functionality is registered here this

play07:31

low function so for example in this

play07:34

particular example we have a

play07:36

notification so we register category for

play07:39

it and we also have an action count

play07:41

functions action so these two things are

play07:44

right here in this uh low out function

play07:48

right uh it's very simple to manage

play07:51

notifications so we have a category so

play07:54

we register it so we say like there may

play07:57

be like several files and chance say are

play07:59

we have several notifications at the

play08:01

same time so we need a category for them

play08:04

so we register it and we also create

play08:08

notification and then we should think

play08:11

about updating it so creating

play08:14

notification is very easy so you create

play08:17

it from an editor and you see that

play08:19

argument there editor entity above on

play08:22

the first line so entity it's just some

play08:26

component from database basically so you

play08:29

have an editor you create a notification

play08:32

for that specific editor then you

play08:34

consult Editor to just get name of the

play08:37

file which is loaded into that editor so

play08:39

you describe all that stuff and now the

play08:41

most important uh part here

play08:45

change this change block is actually a

play08:48

transaction so in cotland we Define a

play08:51

transaction and in that transaction we

play08:55

create that

play08:56

notification and we also do some

play08:58

bookkeeping in with this database for

play09:01

example with Cascade delete call there

play09:04

we just say Okay this notification

play09:06

depends on that editor if editor is

play09:08

deleted then this notification should be

play09:11

deleted as well so it's real database

play09:16

and change block is a transaction there

play09:19

so this function returns a notification

play09:21

and then if you want to update the

play09:23

notification you need to issue another

play09:26

transaction so you see change block here

play09:29

again so you change

play09:31

description and that means that it will

play09:33

be changed in the database and it will

play09:36

also be updated in the UI of course but

play09:39

uh so that's an idea Fleet is a database

play09:42

and you change everything in that

play09:44

database with

play09:46

transactions now action the most

play09:50

important part here we have uh DSL for

play09:54

defining actions in Fleet so this is an

play09:57

example of it so it's an AC ction and we

play10:01

say that for this action we need an

play10:04

editor if there is no editor in Fleet

play10:07

then it's impossible to have this action

play10:09

because we it it's uh too tightly

play10:12

connected with it so we require an

play10:15

editor then we say so if there is no

play10:18

editor then there will be no that action

play10:20

in the actions list then we say it's a

play10:23

dynamic actions meaning that if that

play10:26

editor contains a file which is not

play10:29

cotlin Source then we are not

play10:32

interested this action will be disabled

play10:36

so if it's a cotlin source we say it

play10:39

right there Then in that case we

play10:43

Define a function which will be executed

play10:48

whenever this action is

play10:50

triggered and what is actually we're

play10:52

doing when it's triggered we launch a

play10:55

core routine and we launch it in the

play10:58

so-called plug-in scope do you see that

play11:00

plug-in scope argument that's piece of

play11:03

structured concurrency stuff so every

play11:06

cortin is executed inside that scope so

play11:10

Fleet knows when it loads this plugin it

play11:13

knows that scope so if it decided to

play11:16

unload that plug-in then every coroutine

play11:19

will be cancelled on this time so we

play11:22

control every uh piece of functionality

play11:25

using structured concurrency here so we

play11:27

launch that coroutine and we actually

play11:29

perform that action now remember what is

play11:32

in that action so I change some code in

play11:36

file and then this change should be

play11:39

propagated to the

play11:41

notification so change here change there

play11:45

so we need to describe this somehow and

play11:47

this is actually the core part of this

play11:51

plugin so this function works with with

play11:55

an editor and if you see that with

play11:58

entities there so that means that it

play12:01

will be cancelled if there is no editor

play12:04

anymore automatically for us now we

play12:08

create notification using the function

play12:10

that we saw earlier and we'll say we do

play12:12

that while the notification is alive

play12:15

when it's deleted from the database then

play12:18

once again this Corin is going to be

play12:20

cancelled okay and now the central part

play12:23

of that Fleet database remember that

play12:26

stuff about reactive queries so we say

play12:29

basically here query for every change in

play12:36

abstract syntax Tre of the file loaded

play12:39

of the document loaded into that

play12:41

editor so for every change we get an

play12:46

asynchronous

play12:47

flow and we need to do some processing

play12:50

with that flow so query we say what we

play12:54

are interested in and then in the second

play12:58

part in colle

play12:59

latest so we are collecting elements

play13:02

from the flow we count functions in the

play13:07

particular abstract syntax tree from

play13:09

that editor and then we update a

play13:12

notification so basic idea we have a

play13:15

query reactive database and we have

play13:19

collecting latest values sometimes we

play13:22

can skip some changes that's fine

play13:24

because we always have an access to the

play13:26

latest stuff right there

play13:30

and the final piece of code here is

play13:33

Count functions function so it's

play13:36

basically very simple exercise in uh

play13:39

communicating with the abstract syntax

play13:41

tree so syntax of that file that is

play13:44

loaded into the editor so we're going to

play13:46

the root look at the Children's and

play13:49

we're interested in top level functions

play13:51

only so that's why that's enough for me

play13:54

so no much too much navigation over over

play13:57

there and then that's it so below 100

play14:00

lines of code we've implemented this uh

play14:04

staff for Fleet and of course it takes

play14:08

much more lines of course to implement

play14:10

something much more meaningful much more

play14:13

sophisticated but it's still possible or

play14:17

will be possible for everyone whenever

play14:20

we are ready with our Fleet plugins

play14:22

public preview so the goal of this stock

play14:26

was to make you aware of that stuff so

play14:29

we are working on it and we will make it

play14:32

open very soon so that everyone can try

play14:36

to implement their own plugins for Fleet

play14:39

okay and uh thank you very much and

play14:41

please don't forget to vote if you like

play14:44

it otherwise I'll be

play14:46

fired thank you very much folks thanks

play14:49

for coming

play14:53

[Music]

Rate This
★
★
★
★
★

5.0 / 5 (0 votes)

Étiquettes Connexes
Fleet PluginsCode EditorCustomizationRemote DevelopmentCollaboration ToolsAbstract Syntax TreeStructured ConcurrencyDatabase TransactionsPlugin DevelopmentCoding Enhancements
Besoin d'un résumé en anglais ?