In 10.4, we’ve reworked code completion and other features. It’s one of the most significant changes to the IDE in a decade.
First, some background. If you’re familiar with Code Insight, skip ahead...
Code Insight is our name for a set of IDE productivity features in the editor. For the purposes of this blog post, those features are:
These features have been available in Delphi for many years. Features like this are a key benefit to you when coding an IDE. Code completion especially saves a lot of typing, and error insight helps you make sure your code is working before you spend time compiling.
As the language has grown and time has passed, these features have no longer always worked as well as we have wanted. The technology was cutting-edge when it was introduced, but there were definite improvements we could make today.
It’s been common to see bug reports about spurious errors (ie errors reported in the editor or in the Structure view when the source code is actually perfectly correct code.) Or that the IDE worked in the main thread, so would not respond to keystrokes while it was working to show the code completion list. (You could only press Escape to cancel.) Sometimes, for gigantic projects, calculating the data for code completion could use a lot of memory in the IDE. In addition, the features were implemented with multiple code parsers: code completion and error insight each had a different understanding of the code. And finally, code insight was disabled while debugging, so if you wrote code while debugging you had no productivity assistance.
We did not want this to continue. Our goals for 10.4 have been to:
All of this is in Delphi 10.4.
Excited? We are. This is one of the biggest and best changes to the Delphi IDE in fifteen years.
(And don’t worry - if you need, classic code insight is still there, complete with a few new bug fixes, and can be turned on in 10.4 if you want.)
In 10.4, the above Code insight features are implemented using a ‘LSP Server’. You may have heard of this technology, but if not, LSP refers to the Language Server Protocol, which is a standardized way to implement code insight-like features for many languages. An IDE talks to a ‘language server’, which is a small helper app that calculates and generates the information the IDE displays. It does so using a defined protocol, and that’s the language server protocol.
In other words, the IDE now talks to a helper app when you do something like open a project, or type a keystroke in your file, and the IDE can periodically ask it questions, such as: ‘What are the completion results at this location?’. That helper app keeps track of your code, and sends back an answer to any questions, plus any errors it ran into in the code along the way.
Our server app is built around the compiler, using the compiler as a service to provide LSP results. That means that what the IDE displays to you, including ‘red squiggly’ errors, is all data that comes from the compiler itself.
This means a few things:
These are all very good things.
But enough text. Let’s see what it looks like in action!
It’s hard to show responsiveness in a blog. In these static screenshots, just imagine that you’re typing and you never see Windows wait cursor.
Imagination will become reality when we ship 10.4!
The first new feature is a big one, that doesn’t need many words. You can use Code Insight while debugging.
Want to debug your app and type code at the same time, and get code completion? You can.
Yes, what you're seeing is correct - that's code completion and error insight both working while you are actively debugging the application.
Getting code completion is the same as in 10.3.3, with the exception that the IDE remains responsive in 10.4. But we've added another new feature, which allows you to find what you want through code completion more easily. In 10.4, code completion will now show more useful results than in the past - yet while still keeping 10.3.3's items at the top of the results list.
Here’s 10.3.3's code completion, typing 'act' after a VCL TButton instance:
Note that 10.3.3 shows very few results - only one, in fact. Classic code completion listed only items that start with what you typed.
Here’s 10.4 in action (pun intended) for the same completion:
In 10.4, code completion lists all items that contain what you typed. Other IDEs do this too, Visual Studio for example, but until now Delphi has shown a more limited list. This is useful because it allows you to search through completion.
For example, suppose you remember that a control has a something-Rect property but you can’t remember what it’s called. In 10.3.3, you’d have to google. In 10.4, just type ‘rect’ and you’ll see:
You can explore your code by typing.
Having more results may not always be what you seek, and you may expect only items that start with what you typed from habit. By default, and to keep the behaviour close to what you’re familiar with from 10.3.3, we sort the completion list so that all starts-with identifiers are placed above all contains identifiers. In other words, the list will give the same results as 10.3.3, but with extra results appended. You don’t need to use those if you don’t want to; they are located after the items that 10.3.3 would have shown you.
If you want behaviour like other IDEs, listing all results together, we have a setting: currently a registry key but we may expose it as UI. That means if you’re more used to what VSCode provides, you can get that too.
Code completion automatically selects the best items in the list for you (so you can just press Enter or Space or ‘.’ or similar to choose that item and keep coding) in the following order:
Prioritising starts-with over contains means the completion list will automatically select ‘Parent’ over ‘SetParent’. Choosing the shortest match means it will select ‘Parent’ over ‘ParentFont’. (You can see this in the above screenshots.) Generally, we find this matches what you are most likely to be typing. Of course you can scroll and press the up and down arrow to select anything you want.
Note in these screenshots you can see live Error Insight, which updates as you type. The partially-typed identifier 'pare', which is not valid code, is correctly underlined in red. (The underline will go away when you select an item from the completion list.) Error Insight results come from the compiler itself, and reflect and report exactly what the compiler sees.
You should never see incorrect errors in the editor or the Structure pane. What you see onscreen is accurate.
The following is not important for features, but may interest you on a technical level.
I mentioned that the LSP server runs as a separate process, which has a number of benefits including a dedicated 4GB memory address space for code insight. If you look at 10.4 running in the Windows Task manager, you will see multiple DelphiLSP processes. The first controls multiple agents, and we have one agent dedicated to providing completion and other results, and one agent dedicated to providing error insight.
To my knowledge, we are the only LSP server that uses a multiprocess architecture.
While implementing this, we have also found and fixed a number of issues that affected code completion in the past.
The new code completion is different to 10.3.3 and earlier’s code completion. We’ve worked to make it as similar as possible, including tweaks like sorting starts-with items above others, to make it familiar to you when you first use it. We hope that within a few minutes you’ll get so used to it that you never want to go back to 10.3.3! But we don’t want to present this as exactly the same: you will find differences.
The new Code Insight in Delphi 10.4 solves a lot of issues, and makes using the IDE a much more pleasant and responsive experience for you as well. That’s not to mention the extra results, which can be extremely useful. We plan to continue working on it to move forward by the goals written above. In 10.4 though, we and our beta testers have found it’s a great addition to the IDE.
In addition, we even added two new features: allowing you to explore your code through code completion, and using Code Insight including code completion and other Code Insight features while debugging.
We’re really excited about this feature. Asynchronous. Responsive IDE. Modern protocol. Support for other languages. Code completion while debugging. It’s great stuff. We can’t wait for you to get 10.4 and try it out yourself.
The new LSP-based CodeInsight is fantastic. This is going to revolutionize the product.
— Nick Hodges, who has used a beta preview
If you have update subscription, one of the perks is accessing beta builds of upcoming releases. There’s still time to join our beta program for 10.4!
This is a preview of an upcoming release of RAD Studio. There can always be last-minute bugs or changes. Nothing here is final until the release is officially made available.
UPDATE: 10.4 Sydney is now available! Download your 30 day free trial from our website!
Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder. Design. Code. Compile. Deploy.
Start Free Trial
Free Delphi Community Edition
Free C++Builder Community Edition
Is the "Auto invoke" setting disabled for LSP?
A common completion is Result in functions. Classic: Type R and you are good to go. LSP, type "r" followed by control-space then "esu" to get "Result."
I'm not sure if LSP pays off. I am already used to Error-Insight being off. The blitz fast Delphi compile times compared to C++ makes up for the missed typos. Just my 2 cents.
As for LSP in C++, too slow and sometimes not even there. I wonder if the difference in LSP response times of Delphi vs. C++ are related to the faster compile times of Delphi as a single pass compiler. Expecting any better C++ performance might be unrealistic in that case.
I really hope the LSP auto-invoke be fixed. Is there an issue created for it (yet)?