/*
	Copyright 2009 The Go Authors. All rights reserved.
	Use of this source code is governed by a BSD-style
	license that can be found in the LICENSE file.

	Go.xclangspec
	Go language specification for Xcode 3

	This is a preliminary version that supports basic syntax high-lighting
	(such as keywords, literals, and comments) and an attempt to provide
	some structure information (incomplete).

	There is not much documentation available regarding the format
	of .xclangspec files. As a starting point, see for instance the
	outdated documentation at:
	http://maxao.free.fr/xcode-plugin-interface/specifications.html
	and the files in:
	/Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/

	Place this file in directory:
	~/Library/Application Support/Developer/Shared/Xcode/Specifications/
*/

(

// ----------------------------------------------------------------------------
// Keywords

// TODO How do we get general Unicode identifiers?

	{
		Identifier = "xcode.lang.go.identifier";
		Syntax = {
			StartChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
			Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
			Words = (
				"break",
				"case",
				"chan",
				"const",
				"continue",

				"default",
				"defer",
				"else",
				"fallthrough",
				"for",

				"func",
				"go",
				"goto",
				"if",
				"import",

				"interface",
				"map",
				"package",
				"range",
				"return",

				"select",
				"struct",
				"switch",
				"type",
				"var",
			);
			Type = "xcode.syntax.keyword";
			AltType = "xcode.syntax.identifier";  // non-keywords are identifiers
		};
	},

// TODO decide what should go here, if anything
	{
		Identifier = "xcode.lang.go.interestingOperators";
		Syntax = {
			Words = (
				"...",
				".",
				"*",
				",",
				":",
 			);
			Type = "xcode.syntax.plain";
		};
	},

	{
		Identifier = "xcode.lang.go.rawstring";
		Syntax = {
			Start = "`";
			End = "`";
			Type = "xcode.syntax.string";
		};
	},

// ----------------------------------------------------------------------------
// Syntax Coloring

	{
		Identifier = "xcode.lang.go";
		Description = "Go Coloring";
		BasedOn = "xcode.lang.simpleColoring";
		IncludeInMenu = YES;
		Name = "Go";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer.toplevel";
			IncludeRules = (
				"xcode.lang.go.block",
				"xcode.lang.go.bracketexpr",
				"xcode.lang.go.parenexpr",
			);
			Type = "xcode.syntax.plain";
		};
	},

	// The following rule returns tokens to the other rules
	{
		Identifier = "xcode.lang.go.lexer";
		Syntax = {
			IncludeRules = (
				"xcode.lang.go.comment",
				"xcode.lang.go.comment.singleline",
				"xcode.lang.string",
				"xcode.lang.character",
				"xcode.lang.go.rawstring",
				"xcode.lang.go.identifier",
				"xcode.lang.number",
				"xcode.lang.go.interestingOperators",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.lexer.toplevel";
		Syntax = {
			IncludeRules = (
				"xcode.lang.go.comment",
				"xcode.lang.go.comment.singleline",
				"xcode.lang.string",
				"xcode.lang.character",
				"xcode.lang.go.rawstring",
				"xcode.lang.go.type.declaration",
				"xcode.lang.go.method.declaration",
				"xcode.lang.go.function.declaration",
				"xcode.lang.go.identifier",
				"xcode.lang.number",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.method.declaration";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Rules = (
				"func",
				"xcode.lang.go.parenexpr",
				"xcode.lang.go.identifier",
				"xcode.lang.go.parenexpr",
			);
			Type = "xcode.syntax.declaration.method";
		};
	},

	{
		Identifier = "xcode.lang.go.type.declaration";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Rules = (
				"type",
				"xcode.lang.go.identifier",
			);
			Type = "xcode.syntax.typedef";
		};
	},

	{
		Identifier = "xcode.lang.go.function.declaration";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Rules = (
				"func",
				"xcode.lang.go.identifier",
				"xcode.lang.go.parenexpr",
			);
			Type = "xcode.syntax.declaration.function";
		};
	},

// ----------------------------------------------------------------------------
// Blocks

	{
		Identifier = "xcode.lang.go.block";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Start = "{";
			End = "}";
			Foldable = YES;
			Recursive = YES;
			IncludeRules = (
				"xcode.lang.go.bracketexpr",
				"xcode.lang.go.parenexpr",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.parenexpr";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Start = "(";
			End = ")";
			Recursive = YES;
			IncludeRules = (
				"xcode.lang.go.bracketexpr",
				"xcode.lang.go.block",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.bracketexpr";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Start = "[";
			End = "]";
			Recursive = YES;
			IncludeRules = (
				"xcode.lang.go.parenexpr",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.comment";
		Syntax = {
			Start = "/*";
			End = "*/";
			Foldable = YES;
			IncludeRules = (
				"xcode.lang.url",
				"xcode.lang.url.mail",
				"xcode.lang.comment.mark",
			);
			Type = "xcode.syntax.comment";
		};
	},

	{
		Identifier = "xcode.lang.go.comment.singleline";
		Syntax = {
			Start = "//";
			End = "\n";
			IncludeRules = (
				"xcode.lang.url",
				"xcode.lang.url.mail",
				"xcode.lang.comment.mark",
			);
			Type = "xcode.syntax.comment";
		};
	},

	// This rule recognizes special comments markers and adds them
	// to the list of file markers at the top of the editor window.
	// This overrides the markers specified in
	// /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/BaseSupport.xclangspec
	// and appears to apply them to all languages. Thus, for now
	// "inherit" the existing markers here for backward-compatibility.
	{
		Identifier = "xcode.lang.comment.mark";
		Syntax = {
			StartChars = "BMTF!?";
			Match = (
				// Go-specific markers
				"^\(BUG.*$\)$",			// include "BUG" in the markers list
				"^\(TODO.*$\)$",		// include "TODO" in the markers list
				// inherited markers
				"^MARK:[ \t]+\(.*\)$",
				"^\(TODO:[ \t]+.*\)$",		// include "TODO: " in the markers list
				"^\(FIXME:[ \t]+.*\)$",		// include "FIXME: " in the markers list
				"^\(!!!:.*\)$",			// include "!!!:" in the markers list
				"^\(\\?\\?\\?:.*\)$"		// include "???:" in the markers list
			);
			// This is the order of captures. All of the match strings above need the same order.
			CaptureTypes = (
				"xcode.syntax.mark"
			);
			Type = "xcode.syntax.comment";
		};
	},

)
