Index: scintilla/makefile.win32
===================================================================
--- scintilla/makefile.win32	(revision 3421)
+++ scintilla/makefile.win32	(working copy)
@@ -60,7 +60,7 @@
 #++Autogenerated -- run src/LexGen.py to regenerate
 #**LEXOBJS=\\\n\(\*.o \)
 LEXOBJS=\
-LexBash.o LexAsm.o LexCSS.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
+LexAda.o LexBash.o LexAsm.o LexCSS.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
 LexPerl.o LexPython.o LexSQL.o LexCaml.o LexOMS.o LexTCL.o LexRuby.o LexFortran.o LexVHDL.o LexMatlab.o \
 LexD.o LexLua.o LexHaskell.o LexBasic.o LexR.o LexYAML.o LexCmake.o LexNsis.o
 #--Autogenerated -- end of automatically generated section
Index: scintilla/KeyWords.cxx
===================================================================
--- scintilla/KeyWords.cxx	(revision 3421)
+++ scintilla/KeyWords.cxx	(working copy)
@@ -141,6 +141,7 @@
 
 //++Autogenerated -- run src/LexGen.py to regenerate
 //**\(\tLINK_LEXER(\*);\n\)
+	LINK_LEXER(lmAda);
 	LINK_LEXER(lmAsm);
 	LINK_LEXER(lmBash);
 	LINK_LEXER(lmFreeBasic);
Index: scintilla/LexAda.cxx
===================================================================
--- scintilla/LexAda.cxx	(revision 0)
+++ scintilla/LexAda.cxx	(revision 0)
@@ -0,0 +1,524 @@
+// Scintilla source code edit control
+/** @file LexAda.cxx
+ ** Lexer for Ada 95
+ **/
+// Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "Platform.h"
+
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "PropSet.h"
+#include "KeyWords.h"
+#include "SciLexer.h"
+#include "SString.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/*
+ * Interface
+ */
+
+static void ColouriseDocument(
+    unsigned int startPos,
+    int length,
+    int initStyle,
+    WordList *keywordlists[],
+    Accessor &styler);
+
+static const char * const adaWordListDesc[] = {
+	"Keywords",
+	0
+};
+
+LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc);
+
+/*
+ * Implementation
+ */
+
+// Functions that have apostropheStartsAttribute as a parameter set it according to whether
+// an apostrophe encountered after processing the current token will start an attribute or
+// a character literal.
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL);
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute);
+
+static inline bool IsDelimiterCharacter(int ch);
+static inline bool IsNumberStartCharacter(int ch);
+static inline bool IsNumberCharacter(int ch);
+static inline bool IsSeparatorOrDelimiterCharacter(int ch);
+static bool IsValidIdentifier(const SString& identifier);
+static bool IsValidNumber(const SString& number);
+static inline bool IsWordStartCharacter(int ch);
+static inline bool IsWordCharacter(int ch);
+
+static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) {
+	apostropheStartsAttribute = true;
+
+	sc.SetState(SCE_ADA_CHARACTER);
+
+	// Skip the apostrophe and one more character (so that '' is shown as non-terminated and '''
+	// is handled correctly)
+	sc.Forward();
+	sc.Forward();
+
+	ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL);
+}
+
+static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) {
+	while (!sc.atLineEnd && !sc.Match(chEnd)) {
+		sc.Forward();
+	}
+
+	if (!sc.atLineEnd) {
+		sc.ForwardSetState(SCE_ADA_DEFAULT);
+	} else {
+		sc.ChangeState(stateEOL);
+	}
+}
+
+static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+	// Apostrophe meaning is not changed, but the parameter is present for uniformity
+
+	sc.SetState(SCE_ADA_COMMENTLINE);
+
+	while (!sc.atLineEnd) {
+		sc.Forward();
+	}
+}
+
+static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
+	apostropheStartsAttribute = sc.Match (')');
+	sc.SetState(SCE_ADA_DELIMITER);
+	sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+	apostropheStartsAttribute = false;
+
+	sc.SetState(SCE_ADA_LABEL);
+
+	// Skip "<<"
+	sc.Forward();
+	sc.Forward();
+
+	SString identifier;
+
+	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+		identifier += static_cast<char>(tolower(sc.ch));
+		sc.Forward();
+	}
+
+	// Skip ">>"
+	if (sc.Match('>', '>')) {
+		sc.Forward();
+		sc.Forward();
+	} else {
+		sc.ChangeState(SCE_ADA_ILLEGAL);
+	}
+
+	// If the name is an invalid identifier or a keyword, then make it invalid label
+	if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) {
+		sc.ChangeState(SCE_ADA_ILLEGAL);
+	}
+
+	sc.SetState(SCE_ADA_DEFAULT);
+
+}
+
+static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
+	apostropheStartsAttribute = true;
+
+	SString number;
+	sc.SetState(SCE_ADA_NUMBER);
+
+	// Get all characters up to a delimiter or a separator, including points, but excluding
+	// double points (ranges).
+	while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
+		number += static_cast<char>(sc.ch);
+		sc.Forward();
+	}
+
+	// Special case: exponent with sign
+	if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
+	        (sc.ch == '+' || sc.ch == '-')) {
+		number += static_cast<char>(sc.ch);
+		sc.Forward ();
+
+		while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
+			number += static_cast<char>(sc.ch);
+			sc.Forward();
+		}
+	}
+
+	if (!IsValidNumber(number)) {
+		sc.ChangeState(SCE_ADA_ILLEGAL);
+	}
+
+	sc.SetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) {
+	apostropheStartsAttribute = true;
+
+	sc.SetState(SCE_ADA_STRING);
+	sc.Forward();
+
+	ColouriseContext(sc, '"', SCE_ADA_STRINGEOL);
+}
+
+static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) {
+	// Apostrophe meaning is not changed, but the parameter is present for uniformity
+	sc.SetState(SCE_ADA_DEFAULT);
+	sc.ForwardSetState(SCE_ADA_DEFAULT);
+}
+
+static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) {
+	apostropheStartsAttribute = true;
+	sc.SetState(SCE_ADA_IDENTIFIER);
+
+	SString word;
+
+	while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
+		word += static_cast<char>(tolower(sc.ch));
+		sc.Forward();
+	}
+
+	if (!IsValidIdentifier(word)) {
+		sc.ChangeState(SCE_ADA_ILLEGAL);
+
+	} else if (keywords.InList(word.c_str())) {
+		sc.ChangeState(SCE_ADA_WORD);
+
+		if (word != "all") {
+			apostropheStartsAttribute = false;
+		}
+	}
+
+	sc.SetState(SCE_ADA_DEFAULT);
+}
+
+//
+// ColouriseDocument
+//
+
+static void ColouriseDocument(
+    unsigned int startPos,
+    int length,
+    int initStyle,
+    WordList *keywordlists[],
+    Accessor &styler) {
+	WordList &keywords = *keywordlists[0];
+
+	StyleContext sc(startPos, length, initStyle, styler);
+
+	int lineCurrent = styler.GetLine(startPos);
+	bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
+
+	while (sc.More()) {
+		if (sc.atLineEnd) {
+			// Go to the next line
+			sc.Forward();
+			lineCurrent++;
+
+			// Remember the line state for future incremental lexing
+			styler.SetLineState(lineCurrent, apostropheStartsAttribute);
+
+			// Don't continue any styles on the next line
+			sc.SetState(SCE_ADA_DEFAULT);
+		}
+
+		// Comments
+		if (sc.Match('-', '-')) {
+			ColouriseComment(sc, apostropheStartsAttribute);
+
+		// Strings
+		} else if (sc.Match('"')) {
+			ColouriseString(sc, apostropheStartsAttribute);
+
+		// Characters
+		} else if (sc.Match('\'') && !apostropheStartsAttribute) {
+			ColouriseCharacter(sc, apostropheStartsAttribute);
+
+		// Labels
+		} else if (sc.Match('<', '<')) {
+			ColouriseLabel(sc, keywords, apostropheStartsAttribute);
+
+		// Whitespace
+		} else if (IsASpace(sc.ch)) {
+			ColouriseWhiteSpace(sc, apostropheStartsAttribute);
+
+		// Delimiters
+		} else if (IsDelimiterCharacter(sc.ch)) {
+			ColouriseDelimiter(sc, apostropheStartsAttribute);
+
+		// Numbers
+		} else if (IsADigit(sc.ch) || sc.ch == '#') {
+			ColouriseNumber(sc, apostropheStartsAttribute);
+
+		// Keywords or identifiers
+		} else {
+			ColouriseWord(sc, keywords, apostropheStartsAttribute);
+		}
+	}
+
+	sc.Complete();
+}
+
+static inline bool IsDelimiterCharacter(int ch) {
+	switch (ch) {
+	case '&':
+	case '\'':
+	case '(':
+	case ')':
+	case '*':
+	case '+':
+	case ',':
+	case '-':
+	case '.':
+	case '/':
+	case ':':
+	case ';':
+	case '<':
+	case '=':
+	case '>':
+	case '|':
+		return true;
+	default:
+		return false;
+	}
+}
+
+static inline bool IsNumberCharacter(int ch) {
+	return IsNumberStartCharacter(ch) ||
+	       ch == '_' ||
+	       ch == '.' ||
+	       ch == '#' ||
+	       (ch >= 'a' && ch <= 'f') ||
+	       (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool IsNumberStartCharacter(int ch) {
+	return IsADigit(ch);
+}
+
+static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
+	return IsASpace(ch) || IsDelimiterCharacter(ch);
+}
+
+static bool IsValidIdentifier(const SString& identifier) {
+	// First character can't be '_', so initialize the flag to true
+	bool lastWasUnderscore = true;
+
+	size_t length = identifier.length();
+
+	// Zero-length identifiers are not valid (these can occur inside labels)
+	if (length == 0) {
+		return false;
+	}
+
+	// Check for valid character at the start
+	if (!IsWordStartCharacter(identifier[0])) {
+		return false;
+	}
+
+	// Check for only valid characters and no double underscores
+	for (size_t i = 0; i < length; i++) {
+		if (!IsWordCharacter(identifier[i]) ||
+		        (identifier[i] == '_' && lastWasUnderscore)) {
+			return false;
+		}
+		lastWasUnderscore = identifier[i] == '_';
+	}
+
+	// Check for underscore at the end
+	if (lastWasUnderscore == true) {
+		return false;
+	}
+
+	// All checks passed
+	return true;
+}
+
+static bool IsValidNumber(const SString& number) {
+	int hashPos = number.search("#");
+	bool seenDot = false;
+
+	size_t i = 0;
+	size_t length = number.length();
+
+	if (length == 0)
+		return false; // Just in case
+
+	// Decimal number
+	if (hashPos == -1) {
+		bool canBeSpecial = false;
+
+		for (; i < length; i++) {
+			if (number[i] == '_') {
+				if (!canBeSpecial) {
+					return false;
+				}
+				canBeSpecial = false;
+			} else if (number[i] == '.') {
+				if (!canBeSpecial || seenDot) {
+					return false;
+				}
+				canBeSpecial = false;
+				seenDot = true;
+			} else if (IsADigit(number[i])) {
+				canBeSpecial = true;
+			} else {
+				break;
+			}
+		}
+
+		if (!canBeSpecial)
+			return false;
+	} else {
+		// Based number
+		bool canBeSpecial = false;
+		int base = 0;
+
+		// Parse base
+		for (; i < length; i++) {
+			int ch = number[i];
+			if (ch == '_') {
+				if (!canBeSpecial)
+					return false;
+				canBeSpecial = false;
+			} else if (IsADigit(ch)) {
+				base = base * 10 + (ch - '0');
+				if (base > 16)
+					return false;
+				canBeSpecial = true;
+			} else if (ch == '#' && canBeSpecial) {
+				break;
+			} else {
+				return false;
+			}
+		}
+
+		if (base < 2)
+			return false;
+		if (i == length)
+			return false;
+
+		i++; // Skip over '#'
+
+		// Parse number
+		canBeSpecial = false;
+
+		for (; i < length; i++) {
+			int ch = tolower(number[i]);
+
+			if (ch == '_') {
+				if (!canBeSpecial) {
+					return false;
+				}
+				canBeSpecial = false;
+
+			} else if (ch == '.') {
+				if (!canBeSpecial || seenDot) {
+					return false;
+				}
+				canBeSpecial = false;
+				seenDot = true;
+
+			} else if (IsADigit(ch)) {
+				if (ch - '0' >= base) {
+					return false;
+				}
+				canBeSpecial = true;
+
+			} else if (ch >= 'a' && ch <= 'f') {
+				if (ch - 'a' + 10 >= base) {
+					return false;
+				}
+				canBeSpecial = true;
+
+			} else if (ch == '#' && canBeSpecial) {
+				break;
+
+			} else {
+				return false;
+			}
+		}
+
+		if (i == length) {
+			return false;
+		}
+
+		i++;
+	}
+
+	// Exponent (optional)
+	if (i < length) {
+		if (number[i] != 'e' && number[i] != 'E')
+			return false;
+
+		i++; // Move past 'E'
+
+		if (i == length) {
+			return false;
+		}
+
+		if (number[i] == '+')
+			i++;
+		else if (number[i] == '-') {
+			if (seenDot) {
+				i++;
+			} else {
+				return false; // Integer literals should not have negative exponents
+			}
+		}
+
+		if (i == length) {
+			return false;
+		}
+
+		bool canBeSpecial = false;
+
+		for (; i < length; i++) {
+			if (number[i] == '_') {
+				if (!canBeSpecial) {
+					return false;
+				}
+				canBeSpecial = false;
+			} else if (IsADigit(number[i])) {
+				canBeSpecial = true;
+			} else {
+				return false;
+			}
+		}
+
+		if (!canBeSpecial)
+			return false;
+	}
+
+	// if i == length, number was parsed successfully.
+	return i == length;
+}
+
+static inline bool IsWordCharacter(int ch) {
+	return IsWordStartCharacter(ch) || IsADigit(ch);
+}
+
+static inline bool IsWordStartCharacter(int ch) {
+	return (isascii(ch) && isalpha(ch)) || ch == '_';
+}
Index: scintilla/Makefile.am
===================================================================
--- scintilla/Makefile.am	(revision 3421)
+++ scintilla/Makefile.am	(working copy)
@@ -6,6 +6,7 @@
 AM_CXXFLAGS = -DNDEBUG -DGTK -DGTK2 -DSCI_LEXER -DG_THREADS_IMPL_NONE
 
 LEXER_SRCS= \
+LexAda.cxx \
 LexAsm.cxx \
 LexBasic.cxx \
 LexBash.cxx \
Index: src/templates.c
===================================================================
--- src/templates.c	(revision 3421)
+++ src/templates.c	(working copy)
@@ -608,6 +608,7 @@
 			break;
 		}
 
+		case GEANY_FILETYPES_ADA:
 		case GEANY_FILETYPES_HASKELL:
 		case GEANY_FILETYPES_VHDL:
 		case GEANY_FILETYPES_LUA:
Index: src/highlighting.c
===================================================================
--- src/highlighting.c	(revision 3421)
+++ src/highlighting.c	(working copy)
@@ -3330,7 +3330,59 @@
 	styleset_c_like(sci, GEANY_FILETYPES_HAXE);
 }
 
+static void styleset_ada_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
+{
+	new_style_array(GEANY_FILETYPES_ADA, 12);
 
+	get_keyfile_hex(config, config_home, "styling", "default", "0x000000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[0]);
+	get_keyfile_hex(config, config_home, "styling", "commentline", "0xd00000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[1]);
+	get_keyfile_hex(config, config_home, "styling", "number", "0x007f00", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[2]);
+	get_keyfile_hex(config, config_home, "styling", "delimiter", "0x301010", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[3]);
+	get_keyfile_hex(config, config_home, "styling", "word", "0x00007f", "0xffffff", "true", &style_sets[GEANY_FILETYPES_ADA].styling[4]);
+	get_keyfile_hex(config, config_home, "styling", "string", "0xff901e", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[5]);
+	get_keyfile_hex(config, config_home, "styling", "character", "0xff901e", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[6]);
+	get_keyfile_hex(config, config_home, "styling", "charactereol", "0x000000", "0xe0c0e0", "false", &style_sets[GEANY_FILETYPES_ADA].styling[7]);
+	get_keyfile_hex(config, config_home, "styling", "identifier", "0x000000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[8]);
+	get_keyfile_hex(config, config_home, "styling", "stringeol", "0x000000", "0xe0c0e0", "false", &style_sets[GEANY_FILETYPES_ADA].styling[9]);
+	get_keyfile_hex(config, config_home, "styling", "label", "0xaaaaaa", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[10]);
+	get_keyfile_hex(config, config_home, "styling", "illegal", "0xff0000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_ADA].styling[11]);
+
+	style_sets[GEANY_FILETYPES_ADA].keywords = g_new(gchar*, 3);
+	get_keyfile_keywords(config, config_home, "keywords", "primary", GEANY_FILETYPES_ADA, 0, "abort else new return abs elsif not reverse abstract end null accept entry select access exception of separate aliased exit or subtype all others synchronized and for out array function overriding tagged at task generic package terminate begin goto pragma then body private type if procedure case in protected until constant interface use is raise declare range when delay limited record while delta loop rem with digits renames do mod requeue xor");
+	get_keyfile_keywords(config, config_home, "keywords", "secondary", GEANY_FILETYPES_ADA, 1, "Boolean Integer Natural Positive Float String True False null");
+	style_sets[GEANY_FILETYPES_ADA].keywords[2] = NULL;
+
+	get_keyfile_wordchars(config, config_home,
+		&style_sets[GEANY_FILETYPES_ADA].wordchars);
+}
+
+
+static void styleset_ada(ScintillaObject *sci)
+{
+	const filetype_id ft_id = GEANY_FILETYPES_ADA;
+
+	apply_filetype_properties(sci, SCLEX_ADA, ft_id);
+
+	SSM(sci, SCI_SETKEYWORDS, 0, (sptr_t) style_sets[GEANY_FILETYPES_ADA].keywords[0]);
+	SSM(sci, SCI_SETKEYWORDS, 1, (sptr_t) style_sets[GEANY_FILETYPES_ADA].keywords[1]);
+
+	set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_ADA, 0);
+	set_sci_style(sci, SCE_ADA_DEFAULT, GEANY_FILETYPES_ADA, 0);
+	set_sci_style(sci, SCE_ADA_WORD, GEANY_FILETYPES_ADA, 4);
+	set_sci_style(sci, SCE_ADA_IDENTIFIER, GEANY_FILETYPES_ADA, 8);
+	set_sci_style(sci, SCE_ADA_NUMBER, GEANY_FILETYPES_ADA, 2);
+	set_sci_style(sci, SCE_ADA_DELIMITER, GEANY_FILETYPES_ADA, 3);
+	set_sci_style(sci, SCE_ADA_CHARACTER, GEANY_FILETYPES_ADA, 6);
+	set_sci_style(sci, SCE_ADA_CHARACTEREOL, GEANY_FILETYPES_ADA, 7);
+	set_sci_style(sci, SCE_ADA_STRING, GEANY_FILETYPES_ADA, 5);
+	set_sci_style(sci, SCE_ADA_STRINGEOL, GEANY_FILETYPES_ADA, 9);
+	set_sci_style(sci, SCE_ADA_LABEL, GEANY_FILETYPES_ADA, 10);
+	set_sci_style(sci, SCE_ADA_COMMENTLINE, GEANY_FILETYPES_ADA, 1);
+	set_sci_style(sci, SCE_ADA_ILLEGAL, GEANY_FILETYPES_ADA, 11);
+}
+
+
+
 /* lang_name is the name used for the styleset_foo_init function, e.g. foo. */
 #define init_styleset_case(ft_id, lang_name) \
 	case (ft_id): \
@@ -3347,6 +3399,7 @@
 	switch (filetype_idx)
 	{
 		init_styleset_case(GEANY_FILETYPES_NONE,	common);
+		init_styleset_case(GEANY_FILETYPES_ADA,		ada);
 		init_styleset_case(GEANY_FILETYPES_ASM,		asm);
 		init_styleset_case(GEANY_FILETYPES_BASIC,	basic);
 		init_styleset_case(GEANY_FILETYPES_C,		c);
@@ -3408,6 +3461,7 @@
 
 	switch (filetype_idx)
 	{
+		styleset_case(GEANY_FILETYPES_ADA,		ada);
 		styleset_case(GEANY_FILETYPES_ASM,		asm);
 		styleset_case(GEANY_FILETYPES_BASIC,	basic);
 		styleset_case(GEANY_FILETYPES_C,		c);
Index: src/filetypes.c
===================================================================
--- src/filetypes.c	(revision 3421)
+++ src/filetypes.c	(working copy)
@@ -551,6 +551,17 @@
 	ft->comment_close = NULL;
 	ft->group = GEANY_FILETYPE_GROUP_MISC;
 
+#define ADA
+	ft = filetypes[GEANY_FILETYPES_ADA];
+	ft->lang = -2;
+	ft->name = g_strdup("ADA");
+	ft->title = g_strdup_printf(_("%s source file"), "ADA");
+	ft->extension = g_strdup("adb");
+	ft->pattern = utils_strv_new("*.adb", "*.ads", NULL);
+	ft->comment_open = g_strdup("--");
+	ft->comment_close = NULL;
+	ft->group = GEANY_FILETYPE_GROUP_COMPILED;
+
 #define ALL
 	ft = filetypes[GEANY_FILETYPES_NONE];
 	ft->lang = -2;
Index: src/filetypes.h
===================================================================
--- src/filetypes.h	(revision 3421)
+++ src/filetypes.h	(working copy)
@@ -37,6 +37,7 @@
 {
 	/* normally compiled languages */
 	GEANY_FILETYPES_ASM = 0,
+	GEANY_FILETYPES_ADA,
 	GEANY_FILETYPES_C,
 	GEANY_FILETYPES_CPP,
 	GEANY_FILETYPES_CS,
Index: data/filetype_extensions.conf
===================================================================
--- data/filetype_extensions.conf	(revision 3421)
+++ data/filetype_extensions.conf	(working copy)
@@ -5,6 +5,7 @@
 #See Geany's main documentation for details.
 [Extensions]
 ASM=*.asm;
+ADA=*.adb;*.ads;
 C=*.c;*.h;
 C++=*.cpp;*.cxx;*.c++;*.cc;*.h;*.hpp;*.hxx;*.h++;*.hh;*.C;
 C#=*.cs;
@@ -41,9 +42,9 @@
 Conf=*.conf;*.ini;config;*rc;*.cfg;
 Diff=*.diff;*.patch;*.rej;
 NSIS=*.nsi;*.nsh;
+Po=*.po;*.pot;
 LaTeX=*.tex;*.sty;*.idx;*.ltx;
 reStructuredText=*.rest;*.reST;*.rst;
 SQL=*.sql;
-Po=*.po;*.pot;
 YAML=*.yaml;*.yml;
 None=*;
Index: data/filetypes.ada
===================================================================
--- data/filetypes.ada	(revision 0)
+++ data/filetypes.ada	(revision 0)
@@ -0,0 +1,61 @@
+# For complete documentation of this file, please see Geany's main documentation
+[styling]
+# foreground;background;bold;italic
+default=0x000000;0xffffff;false;false
+commentline=0xd00000;0xffffff;false;false
+number=0x007f00;0xffffff;false;false
+delimiter=0x301010;0xffffff;false;false
+word=0x00007f;0xffffff;true;false
+string=0xff901e;0xffffff;false;false
+character=0xff901e;0xffffff;false;false
+charactereol=0x000000;0xe0c0e0;false;false
+operator=0x301010;0xffffff;false;false
+identifier=0x000000;0xffffff;false;false
+stringeol=0x000000;0xe0c0e0;false;false
+label=0xaaaaaa;0xffffff;false;true
+illegal=0xff0000;0xffffff;false;true
+# whether arguments of preprocessor commands should be styled (only first argument is used)
+# 1 to enable, 0 to disable
+#styling_within_preprocessor=1;0;false;false
+
+[keywords]
+# all items must be in one line
+primary=abort else new return abs elsif not reverse abstract end null accept entry select access exception of separate aliased exit or subtype all others synchronized and for out array function overriding tagged at task generic package terminate begin goto pragma then body private type if procedure case in protected until constant interface use is raise declare range when delay limited record while delta loop rem with digits renames do mod requeue xor
+secondary=Integer Natural Positive Float String True False null
+# these are some doxygen keywords (incomplete)
+#docComment=attention author brief bug class code date def enum example exception file fn namespace note param remarks return see since struct throw todo typedef var version warning union
+
+[settings]
+# default extension used when saving files
+extension=adb
+
+# the following characters are these which a "word" can contains, see documentation
+wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
+# if only single comment char is supported like # in this file, leave comment_close blank
+comment_open=--
+comment_close=
+# this is an alternative way, so multiline comments are used
+#comment_open=/*
+#comment_close=*/
+
+# set to false if a comment character/string should start at column 0 of a line, true uses any
+# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d
+	#command_example();
+# setting to false would generate this
+#	command_example();
+# This setting works only for single line comments
+comment_use_indent=true
+
+# context action command (please see Geany's main documentation for details)
+context_action_cmd=
+
+[build_settings]
+# %f will be replaced by the complete filename
+# %e will be replaced by the filename without extension
+# (use only one of it at one time)
+compiler=gcc -c "%f"
+linker=gnatbind "%e" && gnatlink "%e"
+run_cmd="./%e"
+
+
