Hi @Colin Brough, I'm happy to expand on my previous comments.

  1. Yes, this is correct. Exporting a class retrieves whatever is in the system global for that class and builds the text file from it. The serialization happens when the class is imported. That space must be added when the text of the class is converted to the global structure. Therefore, if you manually changed the system global to remove the space it would not show up in the export. NOTE: Please don't actually do that!
  2. Yes, this is correct. Any server functions that export code that export code in a specific format (UDL for VS Code and $SYSTEM.OBJ.ExportUDL() for example) use the same code for performing the export.
  3. The serialization I mentioned in #1 and on GitHub only happens when importing a class in UDL format (the format used for editing in Studio and VS Code), NOT XML. The space must have been removed when someone modified an XML export file directly and then re-imported it.
  4. This won't work for the reason I mentioned in #3.
  5. You could use VS Code to do this. Assuming you have a local folder containing your code open in VS Code, you can right-click on the folder and select the Import and Compile option. This will load all the files in the folder onto the server, compile them, and then refresh the local copies.

@Anna Golitsyna If you goal is to find all globals referenced in a document, you can use a modified version of the code I included in this comment. The code uses the %SyntaxColor class to get a JSON array of semantic tokens for a document, and then loops through them looking for global references. Note that this will only find literal references, not naked references or indirection.

ClassMethod WriteAllGrefs()
{
    Set syn = ##class(%SyntaxColor).%New(), in = ##class(%Stream.TmpCharacter).%New(), out = ##class(%Stream.TmpCharacter).%New()
    #; TODO Put your document's contents into "in"
    Do syn.Color(in,out,"COS" /* or "INT" or "CLS" */,"KE" /* K means JSON output, E means keep empty lines */)
    #; Format of the JSON output:
    #; [
    #;     #; One array for each source line
    #;     [
    #;         {
    #;             #; Language of the token. See Languages() in %Library.SyntaxColor.
    #;             "l": %Integer,
    #;             #; Attribute of the token. See Attributes() in %Library.SyntaxColor.
    #;             "s": %Integer,
    #;             #; Zero-indexed start position of the token on the line
    #;             "p": %Integer,
    #;             #; Length of the token in characters
    #;             "c": %Integer
    #;         }
    #;     ]
    #; ]
    Set json = ##class(%DynamicArray).%FromJSON(out), lineIter = json.%GetIterator()
    While lineIter.%GetNext(.lineNum,.lineTokens) {
        Set tokensIter = lineTokens.%GetIterator()
        While tokensIter.%GetNext(,.token) {
            If (
                #; COS
                (token.l = 1) &&
                #; Global reference
                (token.s = 18)
            ) {
                Write "Gref starting in column ",token.p + 1," of line ",lineNum + 1,!
            }
        }
    }
}

You can combine this with the %Library.RoutineMgr_StudioOpenDialog query to make an index of all globals referenced in a subset of documents.

Hi @Gramen Tontchev, for non-classes and routines on the local file system the main extension needs to use the file name to determine the name of the document on the server. There's no guarantee that all "other" document types will have the name of the document stored in the text, and even if that were true, it would be very difficult for the extension to know how to extract that info from each one. I have a PR open that will improve the client-side editing workflow, but this behavior remains the same. 

TL;DR: The name of the file must match the name of the document on the server.

@David Hockenbroch 
This functionality exists in VS Code. It's provided by the Language Server extension. Here's the description of the feature from that extension's README:

To invoke the command, right-click in a blank line of a class definition body and select the Override Class Members row in the menu that appears. The command will insert the selected class member definition(s) at the cursor position where the command was invoked.

@Igor Barboza 
You can use %Library.SyntaxColor to parse ObjectScript. Here's some code to get you started:

ClassMethod WriteAllCommands()
{
    Set syn = ##class(%SyntaxColor).%New(), in = ##class(%Stream.TmpCharacter).%New(), out = ##class(%Stream.TmpCharacter).%New()
    #; TODO Put your document's contents into "in"
    Do syn.Color(in,out,"COS" /* or "INT" or "CLS" */,"KE" /* K means JSON output, E means keep empty lines */)
    #; Format of the JSON output:
    #; [
    #;     #; One array for each source line
    #;     [
    #;         {
    #;             #; Language of the token. See Languages() in %Library.SyntaxColor.
    #;             "l": %Integer,
    #;             #; Attribute of the token. See Attributes() in %Library.SyntaxColor.
    #;             "s": %Integer,
    #;             #; Zero-indexed start position of the token on the line
    #;             "p": %Integer,
    #;             #; Length of the token in characters
    #;             "c": %Integer
    #;         }
    #;     ]
    #; ]
    Set json = ##class(%DynamicArray).%FromJSON(out), lineIter = json.%GetIterator()
    While lineIter.%GetNext(.lineNum,.lineTokens) {
        Set tokensIter = lineTokens.%GetIterator()
        While tokensIter.%GetNext(,.token) {
            If (
                #; COS
                (token.l = 1) && (
                    #; Command
                    (token.s = 32) ||
                    #; User-defined Z command 
                    (token.s = 52)
                )
            ) {
                Write "Command starting in column ",token.p + 1," of line ",lineNum + 1,!
            }
        }
    }
}

@Alin Soare You can't prevent that. The actual text of the class isn't stored in the database. During a save, it gets converted to a global that gets stored in the database, and then converted back into text. The class's text is always regenerated in "canonical" form, with excess spaces removed, capitalization normalized etc. This process doesn't affect method/query implementation code though, it's purely cosmetic.