Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Web editing of DSLs
Web editing of DSLs [message #1728201] Thu, 31 March 2016 20:37 Go to next message
Daniel Cardin is currently offline Daniel CardinFriend
Messages: 109
Registered: July 2009
Senior Member
Hi everyone,

I'm curious about the web editing process. I read the page at : http://www.eclipse.org/Xtext/documentation/330_web_support.html

but I have to admit many things are still very unclear.

The editing works very well, with auto complete etc. But I don't understand where things end up. For example, I see that when I create new models, the jvm inferrer gets called and everything works as I expected, with linking / scoping.
But where are the Java classes ? Are they held in memory only? Is there any way to have the files output in a "real" eclipse project ? Would it be possible to edit more than one source file in that scenario ? I don't mind handling all the loading /saving etc., but I'd like to understand what happens to the inferred java models.

Thanks Smile

Re: Web editing of DSLs [message #1728203 is a reply to message #1728201] Thu, 31 March 2016 20:51 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
The basic answer is.

It is not yet there.

You can Tweak the Generator Service to deliver the inferred stuff to the client.
https://github.com/eclipse/xtext/blob/master/web/org.eclipse.xtext.web.example.jetty/src/main/webapp/ace-statemachine-resource.html

You can implement Multi resource Support yourself.
https://github.com/eclipse/xtext/blob/master/web/org.eclipse.xtext.web.example.jetty/src/main/webapp/ace-statemachine-resource-multi.html

(The links are starting points only)

No Workspace Support.
Maybe the upcoming work on eclipse che will help with that


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1728257 is a reply to message #1728203] Fri, 01 April 2016 11:33 Go to previous messageGo to next message
Daniel Cardin is currently offline Daniel CardinFriend
Messages: 109
Registered: July 2009
Senior Member
Thank you Christian,

I now understand this is really a work in progress!
But my main question still remains... The jvm inferrer is called... does that mean some java classes are built? or is that strictly an EMF representation ?

Thanks again.
Re: Web editing of DSLs [message #1728260 is a reply to message #1728257] Fri, 01 April 2016 12:14 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 67
Registered: March 2015
Location: Kiel, Germany
Member

All inferred JVM types are held in memory. That is not work in progress, but intended, since the web integration of Xtext is not an implementation of an online IDE, but just a set of services that can be used by clients running a text editor. You can extend the Xtext server with additional services for saving the JVM types to a persistence layer if you want. For a full IDE implementation have a look at Orion or Che. However, the integration of Xtext into these online IDEs is indeed work in progress.
Re: Web editing of DSLs [message #1728277 is a reply to message #1728260] Fri, 01 April 2016 14:56 Go to previous messageGo to next message
Daniel Cardin is currently offline Daniel CardinFriend
Messages: 109
Registered: July 2009
Senior Member
Through persistence and automated tasks it would be doable to maintain / build the state on the server. I wonder though about scoping. I don't think I need a full blown IDE, I just need to create models and link across a couple of files.

So, do you think it would be possible to load other models in the "working" memory so as to support cross file references ?

Thanks again
Re: Web editing of DSLs [message #1728279 is a reply to message #1728277] Fri, 01 April 2016 15:01 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
yes this is possible. the "manual" extra work should not be too much, if the resources are put all to the same resource set they will see each other (see the example link i gave you)

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1728298 is a reply to message #1728279] Fri, 01 April 2016 17:34 Go to previous messageGo to next message
Daniel Cardin is currently offline Daniel CardinFriend
Messages: 109
Registered: July 2009
Senior Member
I'll have a look.
Thanks for the hints.
Re: Web editing of DSLs [message #1732907 is a reply to message #1728279] Sun, 22 May 2016 21:49 Go to previous messageGo to next message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
Hi Christian

I am trying to cross link my dsls in a web editor (Ace). As suggested by you in the thread below, I tried putting the resources in the same resource set but the cross linking could not happen.

I am trying this on the Github statemachine sample code at https://github.com/eclipse/xtext/blob/master/web/org.eclipse.xtext.web.example.jetty/src/main/webapp/ace-statemachine-resource-multi.html

So this is how I modified MyXtextServlet.java

      Injector injector  =_statemachineWebSetup.createInjectorAndDoEMFRegistration();
      XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
      resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
      URI uri = URI.createURI("../../../test-files/multi-resource/right.statemachine");
      Resource r = resourceSet.createResource(uri);
      uri = URI.createURI("../../../test-files/multi-resource/left.statemachine");
      r = resourceSet.createResource(uri);


I also modified ace-statemachine-resource-multi.html (Attached)

What I hoped to achieve was that right.statmachine would be linked to the left.statemachine since they are in the same resource set and references would be solved on the editor.

I am unable to achieve that, can you please guide me on this.

Thanks
Shiv

Re: Web editing of DSLs [message #1732967 is a reply to message #1732907] Mon, 23 May 2016 13:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
my comments where not about jumping from one editor to the other.
if this is your intent then file a bug (enhancement) for that


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733019 is a reply to message #1732967] Mon, 23 May 2016 11:00 Go to previous messageGo to next message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
Hi

I think I was not able to convey my point clearly. So I have 2 dsls (infomodel and fbmodel).

The infomodel file
Quote:

namespace com.bosch.nutrunner
version 1.0.0
displayname "Bosch Nexo Nutrunner"
description "Information model for BoschNexoNutrunner"
category demo
using com.bosch.nutrunner.Nutrunner ; 1.0.0
infomodel BoschNexoNutrunner {
functionblocks {
nutrunner as Nutrunner
}
}


The fbmodel
Quote:

namespace com.bosch.nutrunner
version 1.0.0
displayname "Nutrunner"
description "Function block model for the Bosch Nexo Nutrunner"
category demo
using com.bosch.nutrunner.ProgramConfiguration ; 1.0.0
using com.bosch.nutrunner.SystemStatus ; 1.0.0
using com.bosch.nutrunner.TighteningResult ; 1.0.0

functionblock Nutrunner {
configuration {
optional program as int
}
}


I have created an Ace web-editor for my infomodels. As you can see, the infomodel has a reference to the fbmodel Nutrunner. I load the infomodel file on my web-editor.
However I am unable to link this infomodel file to the fbmodel and I keep getting the error 'Unresolved reference to Nutrunner' on my web editor.

How can I resolve these reference issues?

I have already tried adding these files to my resource set but that does not seem to solve the issue

Thanks
Shiv
Re: Web editing of DSLs [message #1733021 is a reply to message #1732967] Mon, 23 May 2016 18:56 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
Hi,

i still cannot follow you

(1) create a new xtext web example with this grammar

Model:
	greetings+=Greeting*;
	
Greeting:
	'Hello' name=ID ('from' from=[Greeting])? '!';


Take the impl and bindings from the statmachine example

<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta http-equiv="Content-Language" content="en-us">
	<title>Example Web Editor</title>
	<link rel="stylesheet" type="text/css" href="xtext/2.9.2/xtext-ace.css"/>
	<link rel="stylesheet" type="text/css" href="style.css"/>
	<script src="webjars/requirejs/2.1.20/require.min.js"></script>
	<script type="text/javascript">
		var baseUrl = window.location.pathname;
		var fileIndex = baseUrl.indexOf("index.html");
		if (fileIndex > 0)
			baseUrl = baseUrl.slice(0, fileIndex);
		require.config({
			baseUrl: baseUrl,
			paths: {
				"jquery": "webjars/jquery/2.1.4/jquery.min",
				"ace/ext/language_tools": "webjars/ace/1.2.0/src/ext-language_tools",
				"xtext/xtext-ace": "xtext/2.9.2/xtext-ace"
			}
		});
		require(["webjars/ace/1.2.0/src/ace"], function() {
			require(["xtext/xtext-ace"], function(xtext) {
				var editors = xtext.createEditor({
					position: "absolute",
					syntaxDefinition: "xtext-resources/generated/mode-mydsl"
				});
				var leftServices = editors[0].xtextServices;
				var rightServices = editors[1].xtextServices;
				leftServices.editorContext.addServerStateListener(function(params) {
					if (!params.forceUpdate)
						rightServices.update({forceUpdate: true});
				});
				rightServices.editorContext.addServerStateListener(function(params) {
					if (!params.forceUpdate)
						leftServices.update({forceUpdate: true});
				});
			});
		});
	</script>
</head>
<body>


<div class="container-left">
	<div class="xtext-editor"
		data-editor-resource-id="multi-resource/left.mydsl">
	</div>
</div>
<div class="container-right">
	<div class="xtext-editor"
		data-editor-resource-id="multi-resource/right.mydsl">
	</div>
</div>


</body>
</html>



body {
	font: 16px Helvetica,sans-serif;
}

iframe {
	width: 100%;
	height: 100%;
	border: 1px solid #aaa;
	background-color: #f0f0f0;
}

a {
	color: #22a;
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

h1 {
	color: #555;
	font-style: italic;
}

h2 {
	color: #555;
	padding-left: 15px;
	border-bottom: 1px solid #aab;
}

h3 {
	font-size: 16px;
}

.text-container {
	width: 800px;
	margin: 40px;
}

.container {
	display: block;
	position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
	width: 640px;
	margin: 20px;
}

.container-left {
	display: block;
	position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
	width: 450px;
	margin: 20px;
}

.container-right {
	display: block;
	position: absolute;
    top: 0;
    bottom: 0;
    left: 480px;
	width: 450px;
	margin: 20px;
}

.xtext-editor {
	display: block;
	position: absolute;
    top: 0;
    bottom: 30px;
    left: 0;
    right: 0;
	padding: 4px;
	border: 1px solid #aaa;
}

#xtext-editor {
	display: block;
	position: absolute;
	top: 0;
	bottom: 30px;
	left: 0;
	right: 0;
	border: 1px solid #aaa;
}

.status-wrapper {
	display: block;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
	height: 20px;
	margin-top: 10px;
}

.button-wrapper {
	display: block;
	position: absolute;
	top: 0;
	bottom: 0;
	left: 640px;
	margin: 20px;
}

#generator-result {
	display: block;
	position: absolute;
    top: 20px;
    bottom: 50px;
    left: 680px;
	right: 20px;
}

#dirty-indicator {
	display: inline;
	color: #e8e8e8;
	padding: 1px 8px 1px 8px;
	border: 1px solid #ccc;
	margin-left: 10px;
}

#dirty-indicator.dirty {
	background-color: #88e;
}

#status {
	display: inline;
}

.output-icon {
	background-image: url("images/output.gif");
	background-repeat: no-repeat;
}

.InputSignal {
	font-style: italic;
	color: #2222ff
}

.OutputSignal {
	font-style: italic;
	color: #11aa11
}



class MyDslResourceSetProvider implements IWebResourceSetProvider {
	
	static val MULTI_RESOURCE_PREFIX = 'multi-resource'
		
	@Inject Provider<ResourceSet> provider
	
	override get(String resourceId, IServiceContext serviceContext) {
		if (resourceId !== null && resourceId.startsWith(MULTI_RESOURCE_PREFIX)) {
			val pathEnd = Math.max(resourceId.indexOf('/'), MULTI_RESOURCE_PREFIX.length)
			return serviceContext.session.get(ResourceSet -> resourceId.substring(0, pathEnd), [provider.get])
		} else
			return provider.get
	}
	
}


/*
 * generated by Xtext 2.9.2
 */
package org.xtext.example.mydsl.web

import com.google.inject.Provider
import java.util.List
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import javax.servlet.annotation.WebServlet
import org.eclipse.xtext.web.server.persistence.ResourceBaseProviderImpl
import org.eclipse.xtext.web.servlet.XtextServlet

/**
 * Deploy this class into a servlet container to enable DSL-specific services.
 */
@WebServlet(name = 'XtextServices', urlPatterns = '/xtext-service/*')
class MyDslServlet extends XtextServlet {
	
	val List<ExecutorService> executorServices = newArrayList
	
	override init() {
		super.init()
		val resourceBaseProvider = new ResourceBaseProviderImpl('./test-files')
		val Provider<ExecutorService> executorServiceProvider = [Executors.newCachedThreadPool => [executorServices += it]]
		new MyDslWebSetup(executorServiceProvider, resourceBaseProvider).createInjectorAndDoEMFRegistration()
	}
	
	override destroy() {
		executorServices.forEach[shutdown()]
		executorServices.clear()
		super.destroy()
	}
	
}



/*
 * generated by Xtext 2.9.2
 */
package org.xtext.example.mydsl.web

import com.google.inject.Binder
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
import org.eclipse.xtext.web.server.model.IWebResourceSetProvider
import org.eclipse.xtext.web.server.persistence.FileResourceHandler
import org.eclipse.xtext.web.server.persistence.IResourceBaseProvider
import org.eclipse.xtext.web.server.persistence.IServerResourceHandler

/**
 * Use this class to register additional components to be used within the web application.
 */
@FinalFieldsConstructor
class MyDslWebModule extends AbstractMyDslWebModule {
	
	val IResourceBaseProvider resourceBaseProvider
	
	def Class<? extends IWebResourceSetProvider> bindIWebResourceSetProvider() {
		return MyDslResourceSetProvider
	}
	
	def void configureResourceBaseProvider(Binder binder) {
		if (resourceBaseProvider !== null) binder.bind(IResourceBaseProvider).toInstance(resourceBaseProvider)
	}

	def Class<? extends IServerResourceHandler> bindIServerResourceHandler() {
		return FileResourceHandler
	}
}



/*
 * generated by Xtext 2.9.2
 */
package org.xtext.example.mydsl.web

import com.google.inject.Guice
import com.google.inject.Injector
import com.google.inject.Provider
import com.google.inject.util.Modules
import java.util.concurrent.ExecutorService
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
import org.eclipse.xtext.web.server.persistence.IResourceBaseProvider
import org.xtext.example.mydsl.MyDslRuntimeModule
import org.xtext.example.mydsl.MyDslStandaloneSetup

/**
 * Initialization support for running Xtext languages in web applications.
 */
@FinalFieldsConstructor
class MyDslWebSetup extends MyDslStandaloneSetup {
	
	val Provider<ExecutorService> executorServiceProvider
	val IResourceBaseProvider resourceBaseProvider
	
	override Injector createInjector() {
		val runtimeModule = new MyDslRuntimeModule()
		val webModule = new MyDslWebModule(executorServiceProvider, resourceBaseProvider)
		return Guice.createInjector(Modules.override(runtimeModule).with(webModule))
	}
	
	
	
}






Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733023 is a reply to message #1733021] Mon, 23 May 2016 19:20 Go to previous messageGo to next message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
Hi Christian

So in your example above, you create 2 editors ( one for left.statemachine and the other for right.statemachine ). You link these 2 files together, left.statemachine can now reference State2 from right.statemachine. Correct me if I am wrong here but this cross linking has been added in Javascript using the lines

				leftServices.editorContext.addServerStateListener(function(params) {
					if (!params.forceUpdate)
						rightServices.update({forceUpdate: true});
				});
				rightServices.editorContext.addServerStateListener(function(params) {
					if (!params.forceUpdate)
						leftServices.update({forceUpdate: true});
				});


Is there any way to do this cross linking on the server itself?
What I am trying to do here is to create a web editor for left.statemachine, but I want the editor to have references to right.statemachine. I want to resolve the references of left.statemachine before I load it on my web editor. What is the way to resolve these references on the server (assuming both left.statemachine and right.statemachine are on the server)
Re: Web editing of DSLs [message #1733024 is a reply to message #1733023] Mon, 23 May 2016 19:37 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
I am not that deep into the details. A said before this is not solved out of the box yet

I'd try to add it to the webresourceprovider.
Just make sure the resource set contains both resources


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733030 is a reply to message #1733024] Mon, 23 May 2016 20:07 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
something like


class MyDslResourceSetProvider implements IWebResourceSetProvider {
	
	static val MULTI_RESOURCE_PREFIX = 'multi-resource'
		
	@Inject Provider<ResourceSet> provider
	
	override get(String resourceId, IServiceContext serviceContext) {
		val result = if (resourceId !== null && resourceId.startsWith(MULTI_RESOURCE_PREFIX)) {
			val pathEnd = Math.max(resourceId.indexOf('/'), MULTI_RESOURCE_PREFIX.length)
			serviceContext.session.get(ResourceSet -> resourceId.substring(0, pathEnd), [provider.get])
		} else
			provider.get
		result => [
			System.err.println("1111")
			val ry = getResource(URI.createURI("dummy.mydsl"),false) 
			if (ry == null) {
				val r = createResource(URI.createURI("dummy.mydsl"))
			val in = new StringInputStream('''
			Hello X! Hello Y! Hello Z!
			'''.toString)
			r.load(in, null)
			println(r.contents+"1111")
			}
			
			
			
			
		]	
		result
	}
	
}


works for me


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733144 is a reply to message #1733030] Tue, 24 May 2016 18:12 Go to previous messageGo to next message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
Hi Christian

Firstly, thanks a lot for your help.

The solution you suggested partially solves my problem. As you suggested, I have added all my dsls to the resource set in the web resource provider. I am able to work on the statemachine web app.

Now I am trying to do the same thing on my project. I am putting the dsls here.

Infomodel dsl
namespace com.bosch.nutrunner
version 1.0.0
displayname "Bosch Nexo Nutrunner"
description "Information model for BoschNexoNutrunner"
category demo
using com.bosch.nutrunner.Nutrunner ; 1.0.0
infomodel BoschNexoNutrunner {
functionblocks {
nutrunner as Nutrunner
}
}


Fbmodel dsl
namespace com.bosch.nutrunner
version 1.0.0
displayname "Nutrunner"
description "Function block model for the Bosch Nexo Nutrunner"
category demo
using com.bosch.nutrunner.ProgramConfiguration ; 1.0.0
using com.bosch.nutrunner.SystemStatus ; 1.0.0
using com.bosch.nutrunner.TighteningResult ; 1.0.0

functionblock Nutrunner {
configuration {
optional program as int
}
}


In my project, I have added these files in my resource set in the web resource provider. However, my infomodel file is still not able to get a reference to the Nutrunner function block present in the fbmodel file.

Could you suggest something else that I can try, would implementing a custom scope help me in any way?

Re: Web editing of DSLs [message #1733147 is a reply to message #1733144] Tue, 24 May 2016 18:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
Can you create a small demo dsl reprod. Your problem

Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733271 is a reply to message #1733147] Thu, 26 May 2016 04:25 Go to previous messageGo to next message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
Do you need the entire project with the web app or would the .xtext files for the 2 dsls suffice?
Re: Web editing of DSLs [message #1733274 is a reply to message #1733271] Thu, 26 May 2016 05:38 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
Shiv Kandikuppa <forums-noreply@xxxxxxxx> wrote:
> Do you need the entire project with the web app or would the .xtext files
> for the 2 dsls suffice?
>

I need something I can import and run


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733294 is a reply to message #1733274] Thu, 26 May 2016 09:07 Go to previous messageGo to next message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
I have created a git repository with all the relevant files here : https://github.com/shiv12095/vorto_info_web_app

The web app will be run from org.eclipse.vorto.editor.informationmodel.parent/org.eclipse.vorto.editor.informationmodel.web/xtend-gen/org/eclipse/vorto/editor/web/ServerLauncher.java

Re: Web editing of DSLs [message #1733300 is a reply to message #1733294] Thu, 26 May 2016 02:51 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13209
Registered: July 2009
Senior Member
Hi,

the code in the repo is incomplete. seems like some parents are missing.

if you want to have different!!!! dsls in web make sure you call the standalonesetups for ALL dependencent dsls.
you dont do that for .fbmodel and . type

instead you do some strange things inside

InformationModelStandaloneSetupGenerated

calling FunctionblockStandaloneSetup.doSetup(); inside InformationModelWebSetup should be fine.


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Web editing of DSLs [message #1733310 is a reply to message #1733294] Thu, 26 May 2016 11:48 Go to previous message
Shiv Kandikuppa is currently offline Shiv KandikuppaFriend
Messages: 10
Registered: May 2016
Junior Member
HI Christian

Quote:

calling FunctionblockStandaloneSetup.doSetup(); inside InformationModelWebSetup should be fine.


That solved the problem. Thanks a lot Very Happy
Previous Topic:Terminal rule keywords highlighting
Next Topic:Separate model project
Goto Forum:
  


Current Time: Wed Nov 20 13:01:00 GMT 2019

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

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

Back to the top