Beta Testing Focus Areas
The following features of Nova 12 are particularly important as focus areas during beta testing:
- Back / Forward in the Editor (aka Cursor Navigation History), and how it feels and behaves.
- The Find Sidebar, which has been rewritten from the ground up to be faster and use less memory in very large projects.
- New APIs for Language and Completion Extensions (detailed below)
- Languages: all of the built-in Tree-sitter grammars have been synced up with their upstream projects.
New
- Editor: One of several color palettes can now be chosen when using multi-color (“rainbow”) brackets
- Editor: A new Character Inspector allows introspecting the Unicode and numeric values of selected characters
- Editor: Added the ability to “Copy with Syntax Highlighting”
- Editor: The Find bar now displays the current match index beside the total count
- Editor: Printing support has been enhanced with many new options related to page layout and design
- Editor: Added support for syntax highlighting within heredocs
- Preview: Tabs containing playing audio or video now show a mute / unmute button
- Preview: Pages may now request microphone and camera access
- Python: Added support for autocompleting variables within f-strings
- Settings: Copying stored server passwords now authenticates using Touch ID or Apple Watch, if available
- Workspace: Preview tab content can now be printed
- Workspace: Sidebars can now be open and closed independently
- Workspace: New Filetype Icons (3D, Xcode projects, and more)
- Workspace: Line numbers can now be toggled from the “Editor” menu
- Workspace: Added Key bindings for “Copy Path”, “Copy Relative Path”, and “Copy URL”
New for Extensions
- The Syntax Inspector has been enhanced to show Tree-sitter S-expressions and more when developing language extensions
Improved
- Editor: Soft line wrapping behaviors have been improved, especially for CJK text
- Editor: Bracket and quote auto-pairing behaviors have been refined
- Editor: Switching between document encodings now shows a clarified alert message and option descriptions
- Editor: Rendering of invisible Unicode control characters has been improved
- Find sidebar: Pressing Return with the Replace field focused now starts a search operation
- Find sidebar: Search scope can now be quickly set to any folder containing the focused document
- Find sidebar: “Only in open files” is now a toggle button and can be scoped to specific folders
- Find sidebar: Filters can now be individually toggled quickly from an inline disclosable section
- Find sidebar: A “quick pattern” field has been added for easily filtering using shell-style “glob” patterns
- Find sidebar: Multiple filters can now be combined using both inclusive / “or” & exclusive / “and” boolean logic
- Languages: The Perl syntax has been migrated to Tree-sitter
- Languages: The SQL syntax has been migrated to Tree-sitter
- Open Quickly: The fuzzy match algorithm has been enhanced to better handle many previously ambiguous cases
- Open Quickly: File results are now shown using Nova’s rich filetype icons
- Preview: Opening a new preview tab now focuses the web view instead of the address bar
- SSH: Added support for importing keys generated in the 1Password app
- Workspace: Path Bar now shows file paths without document structure
Fixed
- CSS: Fixed syntax highlighting of grid templates
- Editor: Fixed a crash that could occur when parsing specific html documents
- Editor: Addressed potential flickering of code structure headers
- Editor: “Ensure a trailing newline” no longer moves the cursor to a new line after saving a document
- Editor: Find Bar text count no longer overlaps match count label in certain cases
- Editor: Resolved a case where fenced sub-language regions could fail to update after typing
- File Browser: Contextual menus now work as expected when a window is backgrounded
- Lua: Improved highlighting of function declarations
- PHP: Added support for highlighting of magic constants
- PHP: Inline PHP tags immediately before a
#
character no longer breaks syntax highlighting
- PHP-HTML: PHP completions should no longer be offered within HTML elements
- Python: ‘@property’ declarations are now parsed as properties instead of as methods
- JavaScript: Fixed syntax highlighting of variables contained in template strings
- Terminal: Fixed an issue where
fnm
failed to infer the current shell type
- Terminal: Addressed a case where drawing can could be clipped when using macOS 14
- Terminal: Resolved an emulation issue when using
irssi
in screen
- Terminal: Option-clicking in the Terminal now works as expected when scrollbars are visible
- Terminal: Toggling font size with GPU acceleration enabled no longer results in potential rendering issues
- Terminal: Fixed a crash when using accessibility tools to parse text from the terminal buffer
- Themes: The
punctuation
selector is now applied to closing parenthesis in Markdown documents
- Themes: Unified display of italicize comments for “Bright” and “Dark” themes
- Workspace: Resolved an issue that prevented Ctrl+Shift+Cmd+Space from being used as a custom keybinding
- Workspace: Invoking the “Show Next / Previous Tab” shortcuts no longer swaps window tabs if no document tabs are open
What’s New for Extension Developers
New APIs have been added for language and completion extensions. The first set are new query predicates and directives, and the second set allows a language’s “highlights” query to capture arbitrary metadata about the parse tree when a completion request is performed, and pass that metadata to a completion provider’s JavaScript handler.
Full documentation of these changes will be provided before the final release of Nova 12, but for now these notes detail the important bits.
“Any” Query Predicates / Directives
A new set of “any” predicates / directives have been implemented for Tree-sitter queries. These are useful when working with captures which might match multiple parse tree nodes, such as on nodes using the regex-style *
and +
operators.
These will evaluate true if any of the nodes which are captured match, and act as counterparts to the existing “non-any” versions, which only evaluate true if all captured nodes match.
Filter Predicates
any-eq?
: truthy if any captured node equals a value
any-not-eq?
: truthy if any captured node does not equal a value
any-contains?
: truthy if any captured node contains a value
any-not-contains?
: truthy if any captured node does not contain a value
any-match?
: truthy if any captured node matches a regex
any-not-match?
: truthy if any captured node does not match a regex
Property Set Directives
set-if-any-eq!
: sets a value if any captured node equals a value
set-if-any-not-eq!
: sets a value if any captured node does not equal a value
set-if-any-contains!
: sets a value if any captured node contains a value
set-if-any-not-contains!
: sets a value if any captured node does not contain a value
set-if-any-match!
: sets a value if any captured node matches a regex
set-if-any-not-match!
: sets a value if any captured node does not match a regex
Query Metadata for Captures
Queries have previously had the capability to set metadata on a matched parse tree node by using the set*!
family of directives. Such metadata was, until now, only utilized by the parser’s internals as a way for queries to specify contextual info (such as for symbolication).
Now, metadata can also be set on specific captures of a match. To do this, a capture name can be specified immediately preceding the variable
parameter of the directive. For directives which already take a capture parameter to compare (such as #set-if-eq!
), the existing parameter is being renamed compareCapture
in documentation to clarify. Otherwise, the behavior of these directives remains the same.
For example, using the following directive will set variableName
to variableValue
on the captured node @myNode
, if the text of the node @nodeToCompare
is foobar
:
(#set-if-eq! @nodeToCompare "foobar" @myNode "variableName" "variableValue")
Completion Provider API for Query Metadata
Additionally, extensions vending a Completion Provider via JavaScript can now access the metadata applied by a language’s “highlights” query during a completion request. This should allow completion provider logic to access much richer parse tree information.
The CompletionContext
type has a new matches
property, which is an array of ParseTreeMatch
objects matched during evaluation of the relevant language’s highlights query when a completion request is made at the cursor’s location.
Each ParseTreeMatch
object in the array has two properties: metadata
and captures
. The metadata
is a simple object mapping metadata variable keys to values. The captures
is a simple object mapping capture names to ParseTreeCapture
objects. Each capture object, in turn, has a metadata
property (containing any metadata set on that capture), as well as text
(the text captured) and range
(the range of the captured node). Note: the text
property is the final result which may have been transformed by query directives (such as prefix!
); the range
is the range of the original text.
For example, taking the directive used above, a completion provider can access the metadata like so:
provideCompletionItems(editor, context) {
var items = [];
let matches = context.matches;
for match of matches {
let value = match.captures["myNode"].metadata["variableValue"];
if value == "variableValue" {
// Do something interesting!
}
}
return items;
}