Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Different indentation level in the same file
Different indentation level in the same file [message #1860578] Fri, 18 August 2023 07:47 Go to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Hi,

I have a specific language where i developed a grammar and I'm working on the formatter.
Here is an example of my file:
__Mask GenericMask {
    __MaskDefault = Typ;
    __Spec = ProductSpec;
    __Spec = genericSpec;
        run_vddio = Meas;
        run_vddiob = Meas;
}


I have the following grammar:
Mask:
 '__Mask' name=ID '{'
 ('__MaskDefault' '=' default_range=Range ';')?
 ('__Spec' '=' spec_table_names+=ID ';')*
 spec_var+=MaskElement*
 '}';

MaskElement:
 spec_name=ID '=' spec_range=Range ';';

Range:
 'Min' | 'Typ' | 'Max' | 'Meas';


As you can see in the file example, the file is indented with 4 spaces except for the MaskElement rule where there is 8 spaces.
Initially I had issue with indentation where it was 1 tab. I managed to change it with updateing the preferences as follow:
	def void setIndentation4SpacesInsteadOfTabs()
	{
		val preferences = getPreferences
		val newMap = Maps.<String, String> newLinkedHashMap
		newMap.put(FormatterPreferenceKeys.indentation.id, '    ') // $NON-NLS-1$
		val result = new MapBasedPreferenceValues(preferences, newMap)
		request.preferences = result
	}

This apply for the entire generated file.
Here the the formatter code for those rules:
	def dispatch void format(Mask mask, extension IFormattableDocument document) {
		setIndentation4SpacesInsteadOfTabs()		
		val open = mask.regionFor.keyword("{")
		open.append[setNewLines(1)]
		val close = mask.regionFor.keyword("}")
		close.append[setNewLines(1)]
		interior(open, close)[indent]
		
		for ( ISemanticRegion keyword : mask.regionFor.keywords( ";" ) )
		{
			keyword.prepend[noSpace]
			keyword.append[setNewLines(1)]
		}
			
		for ( MaskElement element: mask.spec_var)
		{
			element.format()
		}
	}		

	def dispatch void format(MaskElement mask_var, extension IFormattableDocument document) {
		for ( ISemanticRegion keyword : mask_var.regionFor.keywords( ";" ) )
		{
			keyword.prepend[noSpace]
			keyword.append[setNewLines(1)]
		}
	}		


My problem now, is how to solve the 8 spaces on the MaskElement rule ?

I looked into the TextReplacer but without any success
	def dispatch void format(MaskElement mask_var, extension IFormattableDocument document) {
		for ( ISemanticRegion keyword : mask_var.regionFor.keywords( ";" ) )
		{
			keyword.prepend[noSpace]
			keyword.append[setNewLines(1)]
		}
		val region = mask_var.regionFor.feature(UnaDslPackage.Literals.MASK_ELEMENT__SPEC_NAME)
		val r = new AbstractTextReplacer(document, region) {
            override createReplacements(ITextReplacerContext it) {
                val offset = region.offset
                it.addReplacement(region.textRegionAccess.rewriter.createReplacement(offset, 0, "                 "))
                it
                }
            }
            addReplacer(r)
	}	


I removed the call to setIndentation4SpacesInsteadOfTabs() in case this was overloading everything but it's not working eithe (I'm back with the 1 tab indentation).
Any ideas please ?

Regards,
Re: Different indentation level in the same file [message #1862905 is a reply to message #1860578] Fri, 05 January 2024 14:10 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Hi,
Anyone ?
Re: Different indentation level in the same file [message #1862916 is a reply to message #1862905] Sat, 06 January 2024 06:48 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
i fear there is no one reading with deeps formatter knowledge
=> you need to debug


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Different indentation level in the same file [message #1862941 is a reply to message #1862916] Mon, 08 January 2024 10:17 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Not sure how to start right now.
I will dig into that later on.
Thanks.
Re: Different indentation level in the same file [message #1862943 is a reply to message #1862941] Mon, 08 January 2024 11:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
naive question: a simple if in the formatter does not work?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Different indentation level in the same file [message #1862947 is a reply to message #1862943] Mon, 08 January 2024 15:33 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Not sure to see what kind of if you are mentioning here and where to put such conditional statement.
Re: Different indentation level in the same file [message #1862948 is a reply to message #1862947] Mon, 08 January 2024 15:35 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
inside your format methods

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Different indentation level in the same file [message #1862950 is a reply to message #1862948] Mon, 08 January 2024 15:36 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
but an 'if' to test what ?
Re: Different indentation level in the same file [message #1862952 is a reply to message #1862950] Mon, 08 January 2024 15:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
maybe i did not understand your problem.

class MyDslParsingTest {
	@Inject
	FormatterTestHelper h
	
	@Test
	def void testIt() {
		h.assertFormatted[
			toBeFormatted = '''
			__Mask GenericMask {
			    __MaskDefault = Typ;
			    __Spec = ProductSpec;
			    __Spec = genericSpec;
			        run_vddio = Meas;
			        run_vddiob = Meas;
			}
			'''
			expectation = '''
			__Mask GenericMask {
			    __MaskDefault = Typ;
			    __Spec = ProductSpec;
			    __Spec = genericSpec;
			    run_vddio = Meas;
			    run_vddiob = Meas;
			}
			'''
		]
	}	
	
}
	

is green.
so do you want the duplicate indent or not?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Different indentation level in the same file [message #1862953 is a reply to message #1862952] Mon, 08 January 2024 16:00 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
Yes I do want the duplicate indent on the 2 lines run_vddio and run_vddiob (maching the rule MaskElement)
Re: Different indentation level in the same file [message #1862955 is a reply to message #1862953] Mon, 08 January 2024 16:46 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
what about
def dispatch void format(MaskElement mask_var, extension IFormattableDocument document) {
val reg = mask_var.regionForEObject
set(reg.previousHiddenRegion,reg.nextHiddenRegion)[indent]
...


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Different indentation level in the same file [message #1863038 is a reply to message #1862955] Fri, 12 January 2024 08:09 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
I tried your code and it's working perfectly.
I dig a little bit to understand what it was doing and how to apply it on my other cases.
What I haven't said in my original message is that for this element I needed 8 spaces instead of 4 but I also have other elements where I need 3 spaces.... (the supplier did not do a coherent job in their indentation).

At the end, I did a simpler solution (at least simpler in my mind).
On the top element of my language, in the formatter, I configure the preferences to set 1 space for indentation.
Then for each element I need to indent, it's usually between '{' and '}' so I call a function doing a for loop on the number of indentation I need.

	def void setIndentation( ISemanticRegion open, ISemanticRegion close, int indentLevel, extension IFormattableDocument document )
	{
		for ( var index = 0; index < indentLevel; index++ )
		{
			interior(open, close)[indent]
		}
	}

Thanks for pointing me to the right direction, I really appreciate the support.
Re: Different indentation level in the same file [message #1863238 is a reply to message #1863038] Fri, 19 January 2024 15:18 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
And I'm back to square one :(

My strategy applied above is working in most of the cases expect for 1 I've just discovered: I have one rule where the indentation is not 4 spaces but 1 tab (1 tab sized for 4 spaces).

My preference indentation is set to 1 space then I do some loop on the indentation to reach the expected number of spaces to indent.

I know that the preference is applied for the entire file. And it makes sense before on Eclipse IDE, the formatter is configured with the same indentation for your workspace. And I think we can't have some custom indentation space/tabs in the formatter configuration.

Could it be possible somehow to insert text at the generation time so I can insert a tab for example ?
Re: Different indentation level in the same file [message #1863259 is a reply to message #1863238] Sat, 20 January 2024 06:42 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
Just create a custom text replacer does not work e.g.
https://stackoverflow.com/questions/50904789/formatting-string-content-xtext-2-14


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Different indentation level in the same file [message #1863287 is a reply to message #1863259] Tue, 23 January 2024 15:55 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
does NOT work or does work ?

Because nothing is specified in the link you provided indicating it won't work so I'm confused.
Re: Different indentation level in the same file [message #1863290 is a reply to message #1863287] Tue, 23 January 2024 19:36 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
My strategy applied above is working in most of the cases expect for 1 I've just discovered: I have one rule where the indentation is not 4 spaces but 1 tab (1 tab sized for 4 spaces).
doing this with a replacer instead of indent does not work?

=> maybe you provide a reproducer with unit test of what you want to achive


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Tue, 23 January 2024 19:37]

Report message to a moderator

Re: Different indentation level in the same file [message #1863328 is a reply to message #1863290] Fri, 26 January 2024 10:26 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
From your post where you gave me the link related to use a StringReplacer, you said: "Just create a custom text replacer does not work e.g.".
Was it a typo from your message or is it really not possible to use the StringReplacer ?

I've just played with it and I was not able to replace anything....
Re: Different indentation level in the same file [message #1863329 is a reply to message #1863328] Fri, 26 January 2024 10:46 Go to previous messageGo to next message
Ronan Babin is currently offline Ronan BabinFriend
Messages: 18
Registered: July 2023
Junior Member
I have another piece of my language that behave differently with indentation.

Unison:SyntaxRevision1709.19;
__Levels TL_Opens {
    __AlwaysExec = __Expression { __String = "FALSE"; __Type = BOOLEAN; }
    __Column[0] {
        __LevelsColumnType = __DCTestType;
        __Group = __Expression { __String = "PD_IOs_pl-pads_t5p5_pl+pads_analog_pl-boardRes_pl-USB0ID_pl-ResetN_pl"; }
        __ForceValue = __Expression { __String = "-pad_i_esd_min"; }
        __ForceRange = __Expression { __String = "-pad_i_esd_min*1.1"; }
        __MeasureRange = __Expression { __String = "-pad_vt_esd_max*1.1"; }
        __LowClamp = __Expression { __String = "max(-pad_vt_esd_max*1.3-Dx_Gx_V_Clamp_Acc_Offset,Tester_AbsoluteMaximumRatings_GX1x_V_min)"; }
        __HighClamp = __Expression { __String = "0V+Dx_Gx_V_Clamp_Acc_Offset"; }
        __LowLimit = __Expression { __String = "-pad_vt_esd_max"; }
    }
}


Between the parenthesis of the __Columns object I'm currently generating 4 spaces of indentation. But the real indentation for just between those parenthesis should be a tabulation (\t).
For example:
- The indentation before __AlwaysExec is still 4 spaces
- The indentation before __LevelsColumnType is a tabulation

The simplified grammar to manage just this example:
UnaFile:
 header=Header (una_elements+=Levels)*;

Header:
 'Unison:SyntaxRevision' version=Decimal ';';

Levels:
 '__Levels' name=ID '{'
 ('__AlwaysExec' '=' always_exec=ExpressionType)?
 (columns_list+=Column)*
 '}';

Column:
 '__Column' '[' index=INT ']' '{'
 '__LevelsColumnType' '=' column_type=('__VIType' | '__DigitalType' | '__DCTestType' | '__SeqPowerType') ';'
 ('__Title' '=' title=ID ';')?
 statements+=LevelColumnStatement*
 '}';

LevelColumnStatement:
(level_param_type=('__Group' | 'PowerSupply' | 'StepSize' | '__ForceValue' | '__ForceRange' | '__LowClamp' | '__HighClamp' | '__MeasureRange' | '__LowLimit' | '__HighLimit' | 
  'ExecSeq' | 'Delay' | 'Vil' | 'Vih' | 'Vol' | 'Voh' | 'Iol' | 'Ioh' | 'Vref' | 'Rlv' | 'ClampLo' | 'ClampHi'
) '=' level_param_value=ExpressionType);

ExpressionType:{ExpressionType}
 '__Expression' '{' ('__String' '=' expr=STRING ';')? ('__Type' '=' type=ExpressionTypeValue ';')? ('__Mode' '=' dir=Direction ';')?
 '}';

ExpressionTypeValue:
 'ANY_REAL' | 'PIN' | 's' | 'BOOLEAN' | 'INTEGER' | 'SyncType:';



my formatter is like this:
	def void setIndentationPreferences( )
	{
		val preferences = getPreferences
		val newMap = Maps.<String, String> newLinkedHashMap
		newMap.put(FormatterPreferenceKeys.indentation.id, ' ') // $NON-NLS-1$
		val result = new MapBasedPreferenceValues(preferences, newMap)
		request.preferences = result
	}
        def void setIndentation( ISemanticRegion open, ISemanticRegion close, int indentLevel, extension IFormattableDocument document )
	{
		for ( var index = 0; index < indentLevel; index++ )
		{
			interior(open, close)[indent]
		}
	}
	def void setIndentationWith4Spaces( ISemanticRegion open, ISemanticRegion close, extension IFormattableDocument document )
	{
		setIndentation(open, close, FOUR_SPACES, document )
	}

	def dispatch void format(UnaFile unaFile, extension IFormattableDocument document) {
		setIndentationPreferences( )
		unaFile.header.format
		for (UnaElement unaElements : unaFile.una_elements) {
			unaElements.format;
		}
	}

	def dispatch void format(Header header, extension IFormattableDocument document) {
		header.append[setNewLines(1)]
		header.regionFor.keyword( "Unison:SyntaxRevision" ).append[noSpace]
		header.regionFor.keyword( ";" ).prepend[noSpace]
	}

	def dispatch void format(Levels level, extension IFormattableDocument document) {

		level.append[setNewLines(1)]
		val open = level.regionFor.keyword("{")
		val close = level.regionFor.keyword("}")
		open.append[setNewLines(1)]
		setIndentationWith4Spaces(open, close, document)
		
		level.always_exec.format()
		for ( Column column: level.columns_list)
		{
			column.format()
		}	
	}
			
	def dispatch void format(Column col, extension IFormattableDocument document) {

		col.append[setNewLines(1)]
		val open = col.regionFor.keyword("{")
		val close = col.regionFor.keyword("}")
		open.append[setNewLines(1)]
		setIndentationWith4Spaces(open, close, document)
		
		for ( ISemanticRegion keyword : col.regionFor.keywords( ";" ) )
		{
			keyword.prepend[noSpace]
			keyword.append[setNewLines(1)]
		}
		col.regionFor.keyword( "[" ).prepend[noSpace]
		col.regionFor.keyword( "[" ).append[noSpace]
		col.regionFor.keyword( "]" ).prepend[noSpace]
		
		
		for ( LevelColumnStatement col_statement: col.statements)
		{
			col_statement.format()
		}
	}
		
	def dispatch void format(LevelColumnStatement col_statement, extension IFormattableDocument document) {
		col_statement.level_param_value.format()
	}	

	def dispatch void format(ExpressionType expression, extension IFormattableDocument document) {
		for ( ISemanticRegion keyword : expression.regionFor.keywords( ";" ) )
		{
			keyword.prepend[noSpace]
		}
		expression.regionFor.keyword( "}" ).append[setNewLines(1)]
	}


I don't really know what kind of unit test I can provide.
Re: Different indentation level in the same file [message #1863330 is a reply to message #1863329] Fri, 26 January 2024 11:19 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14699
Registered: July 2009
Senior Member
i fear you need to debug into the formatter to find out how it is working.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:Remove the hierarchy from the name of cross reference
Next Topic:Eclipse platform URIs in command line
Goto Forum:
  


Current Time: Sat Jul 27 10:32:56 GMT 2024

Powered by FUDForum. Page generated in 0.05051 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top