Some general rules to write code: Try to follow the same style/format of the file that you are editing (naming, indentation, etc.) or the style of the module. Some submodules, created by us, or by third-parties, have their own style.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/aseprite/aseprite/llms.txt
Use this file to discover all available pages before exploring further.
clang-format
There is a .clang-format file available for Aseprite and laf, and we are using it with Clang 19. You have to configure a pre-commit hook which will help you to do the formatting automatically before committing. There is a .clang-tidy file used in the GitHub actions executed on each PR. These rules are adopted progressively on patches because are only executed in the diff, and if some rule is violated a comment by aseprite-bot is made. (Sometimes the bot will be wrong, so be careful.)Column Limit
We use a column limit of 100. clang-format will break lines to avoid excessing more than 100 lines, but in some extreme cases it might not break this limit, as our PenaltyExcessCharacter is not the highest value.Basics
Basic statements:Namespaces
Define namespaces with lower case:Classes
Define classes withCapitalCase and member functions with camelCase:
Const
We use the const-west notation: There is a problem withclang-tidy that will make comments using East const notation: #4361, but clang-format should fix the const position anyway.
C++17
We are using C++17 standard. Some things might not be used as we’re targetting macOS 10.14, please add some note about its limitations if you find one:- Use
nullptrinstead ofNULLmacro - Use
auto/auto*for complex types/pointers, iterators, or when the variable type is obvious (e.g.auto* s = new Sprite;) - Use range-based for loops (
for (const auto& item : values) { ... }) - Use template alias (
template<typename T> alias = orig<T>;) - Use generic lambda functions
- Use
std::shared_ptr,std::unique_ptr, orbase::Ref, but generally we’d prefer value semantics instead of smart pointers - Use
std::min/std::max/std::clamp - Use
static constexpr T v = ...; - You can use
<atomic>,<thread>,<mutex>, and<condition_variable> - Prefer
using T = ...;instead oftypedef ... T - Use
[[fallthrough]]if needed - Use
= {}only to specify a default argument value of an user-defined type in a function declaration, e.g.void func(const std::string& s = {}) { ... }. In other cases (e.g. a member variable of an user-defined type) it’s not required or we prefer to use the explicit value for built-in types (int m_var = 0;). - We use gcc 9.2 or clang 9.0 on Linux, so check the features available in https://en.cppreference.com/w/cpp/compiler_support

