Smart indent macros can be written for any language, but are usually more difficult to write than highlighting patterns. A good place to start, of course, is to look at the existing macros for C and C++.
Smart indent macros for a language mode consist of standard XNEdit macro language code attached to any or all of the following three activation conditions: 1) When smart indent is first turned on for a text window containing code of the language, 2) When a newline is typed and smart indent is expected, 3) after any character is typed. To attach macro code to any of these code "hooks", enter it in the appropriate section in the Preferences -> Default Settings -> Auto Indent -> Program Smart Indent dialog.
Typically most of the code should go in the initialization section, because that is the appropriate place for subroutine definitions, and smart indent macros are complicated enough that you are not likely to want to write them as one monolithic run of code. You may also put code in the Common/Shared Initialization section (accessible through the button in the upper left corner of the dialog). Unfortunately, since the C/C++ macros also reside in the common/shared section, when you add code there, you run some risk of missing out on future upgrades to these macros, because your changes will override the built-in defaults.
The newline macro is invoked after the user types a newline, but before the newline is entered in the buffer. It takes a single argument ($1) which is the position at which the newline will be inserted. It must return the number of characters of indentation the line should have, or -1. A return value of -1 means to do a standard auto-indent. You must supply a newline macro, but the code: "return -1" (auto-indent), or "return 0" (no indent) is sufficient.
The type-in macro takes two arguments. $1 is the insert position, and $2 is the character just typed, and does not return a value. It also is invoked before the character is inserted into the buffer. You can do just about anything here, but keep in mind that this macro is executed for every keystroke typed, so if you try to get too fancy, you may degrade performance.