-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Formatting the source code
We have strict style guidelines for the C++ code, and any files written in similar languages like plain C or Objective C, but not to third-party code.
The guidelines are enforced in pull requests by the codestyle CI check, which uses Uncrustify to format the code, and gives an error if any style violations were detected.
You can save time by running Uncrustify on your local machine before you push code to GitHub.
Make sure you get Uncrustify version 0.73, as this is the version used by the codestyle check.
- Windows: Download the official binary.
- Linux: Download our binary for x86_64, or compile the uncrustify-0.73.0 tag yourself (it's quite easy).
-
macOS: Compile the uncrustify-0.73.0 tag.
- If you're getting build errors relating to
std::map
, it is likely you need to move#include <map>
outside the WIN32#ifdef
at the top ofsrc/output.cpp
.
- If you're getting build errors relating to
Don't try to install Uncrustify from a package manager as this will give you the wrong version.
Once extracted/compiled, you'll need to add the location of the uncrustify
binary to your PATH
environment variable, or move it to a location that's already in PATH
.
You could use the scripts in tools/codestyle
to run Uncrustify on a single file, a directory of files, or the entire repository.
You'd need to do this every time you change the code, so it's probably better to use the automatic methods given below.
This method uses a pre-commit hook to ensure that code is formatted with Uncrustify before it gets committed. This works regardless of how you edit the code, but you won't see the benefit in your IDE until you create a commit. Also, when you create the commit, the modification timestamp will update on any files that Uncrustify changes, which means these files will get recompiled on the next build. For best results, use this method in combination with running Uncrustify in your IDE.
Run this command once in MuseScore's source folder to enable our pre-commit hook:
# Linux and macOS
ln -s ../../hooks/pre-commit .git/hooks/pre-commit
# Git Bash with sudo (creates a real symbolic link)
MSYS=winsymlinks:nativestrict sudo ln -s ../../hooks/pre-commit .git/hooks/pre-commit
# Git Bash without sudo (creates a Windows .lnk shortcut that simulates a symlink)
MSYS=winsymlinks:lnk ln -s ../../hooks/pre-commit .git/hooks/pre-commit
# CMD (Administrator prompt or sudo required)
mklink .git\hooks\pre-commit ..\..\hooks\pre-commit
# PowerShell (Administrator prompt or sudo required)
cmd /c mklink .git\hooks\pre-commit ..\..\hooks\pre-commit
Now Git will run Uncrustify for you each time you commit code, so you never have to think about it!
If you need to disable the pre-commit hook later on, run this command:
# CMD and PowerShell
del .git\hooks\pre-commit
# All other shells (also works in PowerShell)
rm .git/hooks/pre-commit
Or you can disable the hook temporarily by passing the -n
/--no-verify
option to git commit
.
Many IDEs provide an option to reformat code every time you save a file. This means you don't have to create a commit to see the improvements, and the modification timestamp is never updated unnecessarily. However, this method won't format files edited outside the IDE, so for best results you should use this method in combination with the pre-commit hook.
- Go to Help → About Plugins → C++.
- Enable Beautifier (experimental).
- Click OK and restart Qt Creator.
- Go to Edit → Preferences → Beautifier.
- Enable Automatic Formatting on File Save.
- Below this, change the Tool dropdown to "Uncrustify".
- Go to the Uncrustify tab.
- In Uncrustify command, enter the full path to your Uncrustify binary (or browse to it).
- Disable Use file uncrustify.cfg defined in project files.
- Enable Use file specific uncrustify.cfg and browse to
tools/codestyle/uncrustify_musescore.cfg
.
- Install the "Uncrustify" extension.
- Open VS Code Settings and find Uncrustify.
- Set Config Path to
/path/to/MuseScore/tools/codestyle/uncrustify_musescore.cfg
- Go to Format.
- Enable Editor: Format On Save.
- Restart VS Code.
We don't have automatic style checks for any languages besides C++ and friends, but we do have recommendations for other languages.
We recommend that you enable the following settings in your IDE as the default for all newly created files:
- Encoding: UTF-8
- Line ending: Unix-style (LF - linefeed,
\n
) - Indentation: 4 spaces (not tabs)
- Trim trailing whitespace
- Insert newline at end of file
In general, we recommend that you adopt whatever style conventions are commonly used in each language, or when there is no consensus, do whatever is most similar to our C++ style. The CodeGuidelines provide more explicit rules for certain languages.
Existing files should continue to use whatever style is already most prevalent in that file. See Editing without changing style.
If you're rewriting substantial portions of a file anyway then you could consider reformatting the entire file to follow our recommendations for new files.
If you find several files that are not following the recommendations, you could consider reformatting them all in one big PR that is free of any semantic changes. Create a commit with the style change then add this commit's SHA to .git-blame-ignore-revs
in a second commit on the same PR. Make sure you update the SHA when rebasing.
Similarly, if you want to move lots of files or rename a directory, it's best to do this in a separate PR that is free of other changes.
When making semantic changes, sometimes it's best to disable automatic formatting in your IDE so that the important changes are not obscured by lots of whitespace changes elsewhere in the file. This makes it easier for team members to review your PR.
In VS Code, you can use the shortcut Ctrl+K followed by Ctrl+Shift+S to save a file without reformatting it. Or you could edit the file in a simple text editor that doesn't support automatic formatting, such as Notepad or nano
. Make sure you don't leave any trailing whitespace on the lines you edit.
Alternatively, you can allow your IDE to reformat the file, then you can filter out unwanted changes with git add -p [file]
. When prompted by Git, type y
to accept a change, n
to reject it, s
to split the change into smaller changes (if possible), or e
to edit manually. This enables you to commit the semantic changes (with git commit
), then you can use git checkout -- [file]
to discard the unwanted style changes.
Ideally we wouldn't change third-party code at all, but it is sometimes necessary to make small changes in order to integrate it with MuseScore Studio. If this happens, we need to be able to compare our version to the original to see what we changed. Also, when pulling in new upstream code, we want to see what changed upstream, and whether our own patches are still required.
To make this comparison straightforward, code borrowed from other open source projects must be added verbatim. Any semantic changes must be made in separate commits after the initial import. No style changes are allowed.
To prevent our Uncrustify scripts from modifying these files, add an empty file called .untidy
to the directory of the third-party library/module (which should be named after the library/module) or to the parent directory (which should be named thirdparty
).
If you need to edit the third-party files, see editing without changing style.
Testing
- Manual testing
- Automatic testing
Translation
Compilation
- Set up developer environment
- Install Qt and Qt Creator
- Get MuseScore's source code
- Install dependencies
- Compile on the command line
- Compile in Qt Creator
Beyond compiling
Misc. development
Architecture general
- Architecture overview
- AppShell
- Modularity
- Interact workflow
- Channels and Notifications
- Settings and Configuration
- Error handling
- Launcher and Interactive
- Keyboard Navigation
Audio
Engraving
- Style settings
- Working with style files
- Style parameter changes for 4.0
- Style parameter changes for 4.1
- Style parameter changes for 4.2
- Style parameter changes for 4.3
- Style parameter changes for 4.4
Extensions
- Extensions overview
- Manifest
- Forms
- Macros
- Api
- Legacy plugin API
Google Summer of Code
References