1.. _module-pw_ide-guide-vscode-code-intelligence: 2 3================= 4Code intelligence 5================= 6.. pigweed-module-subpage:: 7 :name: pw_ide 8 9The Pigweed Visual Studio Code extension bridges Bazel and ``clangd`` to provide 10the smoothest possible C++ embedded development system. For background on the 11tools and approaches Pigweed uses, check out the :ref:`design docs<module-pw_ide-design-cpp>`. 12This doc is a user guide to the way those concepts are applied in Visual Studio 13Code. 14 15------------------------- 16Configuring target groups 17------------------------- 18In Bazel projects, :ref:`target groups<module-pw_ide-design-cpp-target-groups>` 19are defined in a top-level ``BUILD.bazel`` file with something like this: 20 21.. code-block:: 22 23 refresh_compile_commands( 24 name = "refresh_compile_commands", 25 out_dir = ".compile_commands", 26 target_groups = { 27 "host_simulator": [ 28 "//apps/blinky:simulator_blinky", 29 "//apps/production:simulator", 30 "//modules/blinky:blinky_test", 31 "//modules/buttons:manager_test", 32 ], 33 "test_only": "//tests/test:run_tests", 34 "dev_board": [ 35 ["//apps/blinky:dev_board_blinky.elf", "--config=dev_board"], 36 ["//apps/factory:dev_board.elf", "--config=dev_board"], 37 ["//apps/production:dev_board.elf", "--config=dev_board"], 38 ], 39 }, 40 ) 41 42Each target group should contain one or more targets that are "related", in the 43sense that they are pertinent to the way code is compiled for a particular 44platform. For example, as in the example above, it's common to have at least two 45target groups, one for code running on target, and one for code running on host. 46 47As the example illustrates, each target group's value can be either: 48 49* A single string target name 50* A list/array of target names 51* A list/array of tuples, where the first value is the target name and the 52 second value contains build flags 53 54.. tip:: 55 56 The name of the Bazel target that refreshes compile commands can be set to 57 whatever you want via the ``name`` attribute. Just make sure to update the 58 :ref:`corresponding editor setting<module-pw_ide-guide-vscode-settings-refresh-compile-commands-target>` 59 so that the Pigweed extension knows which target to run. 60 61.. warning:: 62 63 The order of the targets in each target group matters, as it dictates the 64 ordering of the compile commands in the resulting compilation database. 65 ``clangd`` will use the *first* relevant compile command it encounters to 66 provide code intelligence for a particular file. So if a target group 67 contains two targets that build the same file in different ways, the way 68 the first listed target builds the file will dictate how ``clangd`` 69 interprets the file. 70 71---------------------------------------------- 72Selecting a target group for code intelligence 73---------------------------------------------- 74The currently-selected code intelligence target group is displayed in the 75Visual Studio Code status bar: 76 77.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-target.png 78 :alt: Visual Studio Code screenshot showing the target status bar item 79 80You can click the status bar item to select a new target group from a dropdown 81list at the top of the screen. 82 83.. figure:: https://storage.googleapis.com/pigweed-media/vsc-dropdown-select-target.png 84 :alt: Visual Studio Code screenshot showing the target selector 85 86------------------------------------ 87Keeping code intelligence data fresh 88------------------------------------ 89As you work on your project, the build graph will change, new compilation 90databases will need to be built, and ``clangd`` will need to be re-configured 91to provide accurate code intelligence. 92 93The Pigweed extension handles this for you automatically. Whenever you make a 94change that could alter the build graph, a background process is launched to 95regenerate fresh compile commands. You'll see the status bar icon change to 96look like this while the refresh process is running, and during that time, you 97can click on the status bar item to open the output window and monitor progress. 98 99.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-refreshing.png 100 :alt: Visual Studio Code screenshot showing the target status bar item 101 refreshing 102 103When the refresh process is complete, the status bar item will look like this: 104 105.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-finished.png 106 :alt: Visual Studio Code screenshot showing the target status bar item in the 107 finished state 108 109.. tip:: 110 111 In most cases, you don't have to wait around for the refresh process to 112 finish to keep working. You can still switch between targets, and code 113 intelligence still works (though it may be a little stale for any files 114 affected by the change that triggered the refresh). 115 116No automatic process is perfect, and if an error occurs during the refresh 117process, that will be indicated with this icon in the status bar: 118 119.. figure:: https://storage.googleapis.com/pigweed-media/vsc-status-bar-fault.png 120 :alt: Visual Studio Code screenshot showing the target status bar item in an 121 error state 122 123You can click the status bar item to trigger a retry, or you can 124:ref:`open the output panel<module-pw_ide-guide-vscode-commands-open-output-panel>` 125to get more details about the error. 126 127.. note:: 128 129 * You can always trigger a manual compilation database refresh by running 130 :ref:`Pigweed: Refresh Compile Commands<module-pw_ide-guide-vscode-commands-refresh-compile-commands>`. 131 132 * If you don't want to use the automatic refresh process, you can 133 :ref:`disable it<module-pw_ide-guide-vscode-settings-disable-compile-commands-file-watcher>`. 134 135---------------------------------- 136Inactive and orphaned source files 137---------------------------------- 138As discussed in the :ref:`design docs<module-pw_ide-design-cpp>`, some source 139files will be compiled in several different targets, possibly with different 140compiler and linker options. Likewise, some files may not be compiled as part 141of a particular selected target, perhaps because the file is not relevant to 142the target (for example, hardware support implementations for a host simulator 143target). Finally, some source files may not be compiled by *any* defined target 144group, either because those files have not yet been brought into the build 145graph, or because none of the defined target groups contain a target that builds 146that source file. 147 148We need to care about this because ``clangd`` tries to be helpful in a way that 149is very counterproductive in Pigweed projects: If it encounters a file but 150cannot find a corresponding compile command in the compilation database, it 151will *infer* a compile command for that file from other similar files that *are* 152in the compilation database. 153 154Since the compilation databases that Pigweed generates are specifically 155engineered to only include compile commands pertinent to the selected target 156group, the *inferred* code intelligence ``clangd`` provides for other files 157is invalid. So the Pigweed extension provides mechanisms to exclude those files 158from ``clangd`` and prevent misleading code intelligence information. 159 160.. glossary:: 161 162 Active source file 163 A source file that is built in the currently-selected target group 164 165 Inactive source file 166 A source file that is *not* built in the currently-selected target group 167 168 Orphaned source file 169 A source file that is not built by *any* defined target groups 170 171Disabling ``clangd`` for inactive and orphaned files 172==================================================== 173By default, Pigweed will disable ``clangd`` for inactive and orphaned files to 174prevent inaccurate and distracting information from appearing in the editor. 175You can see that ``clangd`` is disabled for those files when you see this icon 176in the status bar: 177 178.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-clangd-disabled.png 179 :alt: Visual Studio Code screenshot showing code intelligence disabled for 180 inactive files 181 182You can click the icon to *enable* ``clangd`` for all files, regardless of 183whether they are in the current target's build graph or not. That state will be 184indicated with this icon: 185 186.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-clangd-enabled.png 187 :alt: Visual Studio Code screenshot showing code intelligence enabled for 188 inactive files 189 190You can click it again to toggle it back to the default state. 191 192File status indicators 193====================== 194The Visual Studio Code explorer (file tree) displays an indicator next to 195inactive and orphaned files to help you understand which files will not have 196code intelligence. These indicators will change as you change targets and as 197you change the build graph. 198 199.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-file-indicators.png 200 :alt: Visual Studio Code screenshot file indicators for inactive and 201 orphaned files 202 :figwidth: 250 203 204Inactive files are indicated like this: 205 206.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-file-indicators-inactive.png 207 :alt: Visual Studio Code screenshot file indicators for inactive files 208 :figwidth: 250 209 210Orphaned files are indicated like this: 211 212.. figure:: https://storage.googleapis.com/pigweed-media/vsc-inactive-file-indicators-orphaned.png 213 :alt: Visual Studio Code screenshot file indicators for orphaned files 214 :figwidth: 250 215 216Note that the colors may vary depending on your Visual Studio Code theme. 217 218.. tip:: 219 220 By default, file status indicators will be shown even if ``clangd`` is 221 enabled for all files. You can change this behavior with 222 :ref:`this setting<module-pw_ide-guide-vscode-settings-hide-inactive-file-indicators>`. 223