Nova

Extensions


Readme

C-Dragon™ - C, C++, and Objective-C Extension

C-Dragon provides rich support for C, C++, and Objective-C development in Nova via a language server like clangd, and fast syntactic analysis thanks to Tree-sitter. (Some limited support for Objective-C++ is also present.)

If you have installed our C extension, this extension is a complete superset and you can use this instead.

This extension requires Nova 10.0 or better, and because of at least one fixed bug, we highly recommend updating to Nova 10.4 or better.

✨ Features ✨

  • C, C++, and Objective-C
  • Syntax Highlighting
  • Indentation (automatic, somewhat limited)
  • Symbols
  • Code Folding
  • Format Selection or File (per .clang-format), including On Save
  • Jump to Definition, Declaration, Implementation, Type Definition
  • Find References
  • Find Symbol
  • Rename Symbol
  • Hover Tooltips
  • Signature Assistance
  • Code Quality Hints
  • Code Actions
  • Experimental Debugger via lldb-vscode

📸 Screenshots 📸

⚙️ Language Server Integration ⚙️

C-Dragon requires a language server, either clangd or ccls, for full functionality.

By default, it will offer to download and use a current version of clangd from the official GitHub releases for that project. (The binary it downloads will be stored in the extension private directory.) It will also check for a newer version when you first start the editor. Additionally you can check for a newer version manually by using the Extensions → C-Dragon → Check for Update menu selection.

You may elect instead to use the bundled Apple clangd, or an installation of either clangd or ccls installed elsewhere. See the the Extension Preferences for details.

Note that some features may not work completely with older releases of clangd or ccls, and that the Apple version of clangd typically trails a bit behind the LLVM version. Also, ccls doesn't understand Objective-C at all.

You may also disable the use of a language server entirely. This may be helpful for some very large projects that are too big for clangd to index quickly. Of course, this will result in reduced functionality.

Note that use of ccls can be challenging, and we do not recommend it unless you are already familiar with it.

Configuration of clangd

Configuration of clangd is almost entirely via the .clangd file, as it does not offer the language server protocol methods for configuration (at least as of version 15.0.3.). Please see the clangd site for configuration guidance.

Format Control

Likewise, formatting is controlled via a .clang-format file. The details of this are available on the clang site. (Formatting on save is disabled by default.)

Compile Commands

The extension will start when editing a C or C++ source file. In order to provide project-context specific information, your project will need to provide a compile_commands.json file. Tools like CMake, meson-build, and similar can generate one for you. More information can be found at https://clang.llvm.org/docs/JSONCompilationDatabase.html

The directory where your compile_commands.json file is stored can be specified in global or project preferences, if it is not in the root of the project directory. (Note that clangd will also search in a top-level directory called build, but ccls will not.)

🐞 Debugging Support (Experimental 🥽) 🐞

Initial support for debugging tasks, is available, but requires lldb-vscode to be installed. This is available as part of the llvm homebrew recipe, but will be installed in a Cellar. Configure the path to lldb-vscode in the Extension Settings. Debug tasks can be created in the Tasks area of the Project Settings.

This will make use of LLDB under the hood, and offers source level debugging support.

Future updates should make this more automatic, and we will investigate providing an automatic download of the debug adapter itself.

🛡️ Security Considerations 🛡️

You may notice that this extension needs entitlements to access the network and to read and write local files. These are used solely to support updating the language server. No files outside of the extension's private area are accessed directly. The only requests made are read-only unauthenticated requests to access the public release information and actually download the binary needed for clangd.

If you are concerned, you may download and configure your own copy of clangd, or use the Apple version, and disable the automatic downloads. This will prevent both direct access to the network by this extension, as well as direct filesystem access. Note however that clangd may itself perform those activities.

You can also disable the use of a language server altogether.

🔮 Future Directions 🔮

Further integration of Clang-Tidy support might be nice.

We would like to see richer configuration support, but this is contingent upon clangd providing for it.

Objective C++ support could probably be improved, but we need a good Tree-sitter grammar for it.

We would like to add localizations, but we don't know any other languages confidently enough to provide them ourselves. (See below for more information.)

Tighter integration with build tools (like CMake or Meson) is something we plan to add.

The debug support can be improved to better support automatic detection of likely targets, as well as automatic management of the debug adapter as we do for clangd. It would be nice to support remote debugging via DAP, but it looks like lldb-vscode does not support it at present. (As a workaround, you can create a wrapper script, that runs it remotely via SSH.)

Other Recommended Extensions

It is recommended to enable support for one of CMake, Meson, or Makefile parsing, assuming your project uses one of these to build. Staysail has published extensions for the former two.

🐜 Bugs 🐜

  • Symbol renames can mess up highlighting. Make a subsequent change to refresh the tree-sitter grammar's view of things. This appears to be a Nova defect.
  • clangd (and probably ccls) has various limitations around symbol renaming. YMMV.

  • Some things that should be code actions are not.

  • Objective C++ support is quite primitive, and doesn't understand C++ yet. We need a decent Tree-sitter grammar for it.

  • Objective C preprocessor statements are not well highlighted, as well as things inside such conditionals. This is due to the limitations of the Tree-sitter grammar we have used. We'll probably need to fork that grammar to fix it.

  • Objective C symbolication is a best-effort. It should be close, but since we don't use Objective C we can't be certain. We welcome bug reports and PRs from folks who make use of Objective C.

🌐 Localizations 🌐

If you'd like to help with localizing this extension, please submit an issue or contact us directly. We have designed the extension to make this a very easy task for anyone able to perform the actual translations.

⚖️ Legal Notices ⚖️

C-Dragon™ is a trademark of Staysail Systems, Inc.

Copyright © 2022 Staysail Systems, Inc.

This extension is made available under the terms of the MIT License.

Some of the code in this extension was adapted from Cameron Little's excellent TypeScript extension for Nova. That extension is also licensed under the MIT license and carries the following copyright notice:

Copyright (c) 2020 Cameron Little

This work started from Ben Beshara's original C++ ClangD extension. That extension carried the following license declaration in its manifest (which we have preserved):

"license": "MIT",


Changelog

Version 1.1.1

Fix minor error when source map is empty.

Version 1.1.0

Initial debugging support via lldb-vscode using custom tasks. This is quite preliminary, and requires manually creating a debug task as we aren't processing build rules yet. Additionally the debug adapter must be supplied externally (lldb-vscode). This does work with homebrew installed LLVM (in, for example, /opt/homebrew/Cellar/llvm/15.0.6/bin).

Version 1.0.5

Find clangd `in MacPorts if installed there.

Version 1.0.4

Improved automatic indentation.

Version 1.0.3

Format on save was not working.

Fix for finding clangd or CCLS when using the custom installation.

Several other minor errors (probably unnoticed by users) corrected.

Version 1.0.2

The update message was not displaying the new version of clangd that is available. While here, also display the user's current version.

Version 1.0.1

Forgot to push the release notes! ;-)

Version 1.0.0

Finally, an "official" release! Essentially we believe that this extension works well enough and has achieved enough of our key release criteria to warrant being released.

Button fix for rename.

Numerous symbolication fixes. More of the symbols should be identified, and properly characterized. There are some extreme cases (for example when using more than 4 levels of pointer indirection) that might be missed.

Objective-C support is still mostly a best effort case. It likely can use additional improvement, especially in the preprocessor handling, but it is also better than anything else available at the moment (for Nova).

Version 0.9.12

Find Symbol dialog. This adds another pane to the side bar, and lets you find symbols by a name or a portion of their name.

The Find References pane got a new quick search button, to make it faster to access if you have the pane open.

Find References no longer opens duplicate documents. (Unfortunately we still have to make sure at least one editor window is opened for each text document, so that we can obtain the details. It would be nice if Nova gave us a better API to get this information directly.)

Format selection.

Extension Preferences added to the editor context menu.

Version 0.9.11

Clear references results (very minor bug) when starting a new search.

Add some more information to the extension metadata and README.

Version 0.9.10

Find References is now a supported menu option. This populates a new side bar.

Workaround for rename in the first two columns.

Version 0.9.9

Bug fix (prepRename not forwarding the error properly).

Version 0.9.8

Initial support for Objective-C, including limited support for Objective-C++ (which is treated as Objective-C for now).

Version 0.9.7

Some improvements to highlighting for both C and C++, making better attempts at labeling function identifiers and certain C++ keywords.

Initial version of Symbolication for C++. Note that we don't use C++ really, so these results are mostly a result of exploring the syntax with the Syntax Inspector looking at CCLS sources (because that's what we had handy.) Consequently they're likely not perfect.

Bug reports and/or pull requests are welcome!

Version 0.9.6

Refactoring. This utilizes the work we did for D-Velop to try to facilitate further development of this Extension.

This also was a "break" in the Git History, as we are are now so different from Ben Beshara's original clangd extension that it felt improper to continue to list that as an "upstream".

Version 0.9.5

Initial swag at symbols for C syntax.

Version 0.9.4

Fixes for GH download. Also, cache results from GitHub.

Fixes for internationalization.

Version 0.9.3

Support for using a private clangd, downloaded from GitHub.

Version 0.9.2

Jump To Declaration, Definition, Type Definition.

Do not select the symbol when trying to perform a rename. This avoids moving the selection, and offers a workaround for renaming symbols that are starting in the first two columns. (Hopefully Panic will actually fix the bug that causes this someday.)

Version 0.9.1

Added ability to manually restart in extension menu.

Fix startup issue with clangd.

Preference values have been renamed, but some effort is made to convert old values to the new automatically.

Version 0.9

Refactored configuration dialog, to make configuration with Apple Clang easier, and fixed several LSP selection/path bugs.

Improved the error pop ups to eliminate ugly numeric JSON-RPC error codes.

Use prepareRename on CLang. (Requires ClangD v 13.0 or better, which we aren't checking, yet.) This gives better diagnostic hints when renaming, and it also provides a nicer UI. For CCLS we check that the symbol passes a basic (ASCII only) regular expression. (When Nova supports Unicode escapes we can do better.)

Converted the code to support localization. (Although no localization is done, PRs for .lproj files gratefully accepted. Ask me if you need guidance on what messages/content needs to be localized.)

Version 0.8

New name, "C-Dragon", with a new icon.

Added support for CCLS language server.

Added menu access to extension preferences.

Added a sponsorship link.

Version 0.7

Initial support for symbol renames. This seems to work well when executed for local symbols, or when done at the declaration site, but there is something preventing renames at other sites.

Version 0.6

Added syntax support via Tree-sitter grammars for C and C++. The C grammar and queries are lifted from our C extension, but the C++ grammar and and queries are new.

This also includes automatic detection of C vs C++ for header files based on content expressions.

The C++ grammar does not include every possible C++ construct, because the upstream Tree-sitter is missing some things. Additionally there is no doubt opportunity to further improve on what is here, and contributions from C++ gurus are welcome. (We don't normally work in C++ ourselves.)

As part of the Tree-sitter support, this includes support for folding, and some simple support for automatic indentation. (Open blocks are now recognized.)

Version 0.5

Staysail release. This includes support automatic formatting, including format on save.

These release notes are from Ben Beshara.

Version 0.1

I really have no idea what I'm doing but it's better than nothing... I think ¯\_(ツ)_/¯


License

The MIT License

Copyright 2022 Staysail Systems, Inc. info@staysail.tech

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.