2005-11-22 12:26:26 +00:00
|
|
|
/*
|
2006-09-30 11:13:58 +00:00
|
|
|
* highlighting.c - this file is part of Geany, a fast and lightweight IDE
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
2012-06-18 01:13:05 +02:00
|
|
|
* Copyright 2005-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
|
|
|
* Copyright 2006-2012 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
|
|
|
* Copyright 2011-2012 Colomban Wendling <ban(at)herbesfolles(dot)org>
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
2012-08-24 19:25:57 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2005-11-22 12:26:26 +00:00
|
|
|
*/
|
|
|
|
|
2008-08-26 12:43:46 +00:00
|
|
|
/**
|
|
|
|
* @file highlighting.h
|
2007-02-24 11:41:56 +00:00
|
|
|
* Syntax highlighting for the different filetypes, using the Scintilla lexers.
|
|
|
|
*/
|
|
|
|
|
2009-05-30 11:57:56 +00:00
|
|
|
#include "geany.h"
|
|
|
|
|
2006-05-05 16:03:55 +00:00
|
|
|
#include <stdlib.h>
|
2009-05-30 11:57:56 +00:00
|
|
|
#include <ctype.h>
|
2009-06-03 15:42:01 +00:00
|
|
|
#include <string.h>
|
2013-04-20 15:48:14 +02:00
|
|
|
#include <glib.h>
|
|
|
|
#include <glib/gprintf.h>
|
2006-01-03 12:45:31 +00:00
|
|
|
|
2006-07-04 21:31:08 +00:00
|
|
|
#include "SciLexer.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
#include "highlighting.h"
|
2007-05-28 16:07:30 +00:00
|
|
|
#include "editor.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
#include "utils.h"
|
2006-08-20 20:39:59 +00:00
|
|
|
#include "filetypes.h"
|
2006-10-02 11:31:54 +00:00
|
|
|
#include "symbols.h"
|
2009-01-14 19:19:08 +00:00
|
|
|
#include "ui_utils.h"
|
2009-07-07 11:57:50 +00:00
|
|
|
#include "utils.h"
|
2009-11-04 12:36:56 +00:00
|
|
|
#include "main.h"
|
|
|
|
#include "support.h"
|
2009-12-07 14:17:40 +00:00
|
|
|
#include "sciwrappers.h"
|
2012-05-29 17:59:37 +01:00
|
|
|
#include "document.h"
|
|
|
|
#include "dialogs.h"
|
|
|
|
#include "filetypesprivate.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
#include "highlightingmappings.h"
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2009-11-04 12:36:56 +00:00
|
|
|
#define GEANY_COLORSCHEMES_SUBDIR "colorschemes"
|
|
|
|
|
2007-07-07 11:33:32 +00:00
|
|
|
/* Whitespace has to be set after setting wordchars. */
|
2007-08-31 12:01:22 +00:00
|
|
|
#define GEANY_WHITESPACE_CHARS " \t" "!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~"
|
2007-07-07 11:33:32 +00:00
|
|
|
|
2009-11-04 12:36:56 +00:00
|
|
|
|
2007-07-07 11:33:32 +00:00
|
|
|
static gchar *whitespace_chars;
|
|
|
|
|
2009-11-04 12:36:56 +00:00
|
|
|
|
2006-09-30 11:13:58 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2009-05-30 11:57:56 +00:00
|
|
|
gsize count; /* number of styles */
|
2008-08-26 12:43:46 +00:00
|
|
|
GeanyLexerStyle *styling; /* array of styles, NULL if not used or uninitialised */
|
2009-05-30 11:57:56 +00:00
|
|
|
gchar **keywords;
|
|
|
|
gchar *wordchars; /* NULL used for style sets with no styles */
|
2009-11-18 16:48:17 +00:00
|
|
|
gchar **property_keys;
|
|
|
|
gchar **property_values;
|
2006-09-30 11:13:58 +00:00
|
|
|
} StyleSet;
|
|
|
|
|
2009-12-07 18:08:35 +00:00
|
|
|
/* each filetype has a styleset but GEANY_FILETYPES_NONE uses common_style_set for styling */
|
2009-08-14 11:05:47 +00:00
|
|
|
static StyleSet *style_sets = NULL;
|
2006-09-30 11:13:58 +00:00
|
|
|
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
enum /* Geany common styling */
|
2006-09-30 11:13:58 +00:00
|
|
|
{
|
2007-03-09 18:14:34 +00:00
|
|
|
GCS_DEFAULT,
|
2006-09-30 11:13:58 +00:00
|
|
|
GCS_SELECTION,
|
|
|
|
GCS_BRACE_GOOD,
|
|
|
|
GCS_BRACE_BAD,
|
|
|
|
GCS_MARGIN_LINENUMBER,
|
|
|
|
GCS_MARGIN_FOLDING,
|
2010-07-01 14:33:41 +00:00
|
|
|
GCS_FOLD_SYMBOL_HIGHLIGHT,
|
2006-09-30 11:13:58 +00:00
|
|
|
GCS_CURRENT_LINE,
|
|
|
|
GCS_CARET,
|
|
|
|
GCS_INDENT_GUIDE,
|
|
|
|
GCS_WHITE_SPACE,
|
2008-03-07 15:42:46 +00:00
|
|
|
GCS_LINE_WRAP_VISUALS,
|
|
|
|
GCS_LINE_WRAP_INDENT,
|
|
|
|
GCS_TRANSLUCENCY,
|
2008-03-23 14:57:53 +00:00
|
|
|
GCS_MARKER_LINE,
|
|
|
|
GCS_MARKER_SEARCH,
|
2009-07-08 22:22:28 +00:00
|
|
|
GCS_MARKER_MARK,
|
2008-03-23 14:57:53 +00:00
|
|
|
GCS_MARKER_TRANSLUCENCY,
|
2009-07-08 22:21:45 +00:00
|
|
|
GCS_LINE_HEIGHT,
|
2009-12-29 18:45:21 +00:00
|
|
|
GCS_CALLTIPS,
|
2006-09-30 11:13:58 +00:00
|
|
|
GCS_MAX
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct
|
|
|
|
{
|
2008-08-26 12:43:46 +00:00
|
|
|
GeanyLexerStyle styling[GCS_MAX];
|
2009-09-27 15:59:58 +00:00
|
|
|
|
2010-04-22 17:16:46 +00:00
|
|
|
/* icon style, 1-4 */
|
2009-09-27 15:59:58 +00:00
|
|
|
gint fold_marker;
|
2010-04-22 17:16:46 +00:00
|
|
|
/* vertical line style, 0-2 */
|
2009-09-27 15:59:58 +00:00
|
|
|
gint fold_lines;
|
2010-04-22 17:16:46 +00:00
|
|
|
/* horizontal line when folded, 0-2 */
|
2009-09-27 15:59:58 +00:00
|
|
|
gint fold_draw_line;
|
|
|
|
|
2009-05-30 11:57:56 +00:00
|
|
|
gchar *wordchars;
|
2006-09-30 11:13:58 +00:00
|
|
|
} common_style_set;
|
|
|
|
|
|
|
|
|
2009-05-30 11:57:56 +00:00
|
|
|
/* For filetypes.common [named_styles] section.
|
2009-06-22 15:26:44 +00:00
|
|
|
* 0xBBGGRR format.
|
|
|
|
* e.g. "comment" => &GeanyLexerStyle{0x0000d0, 0xffffff, FALSE, FALSE} */
|
2009-05-30 11:57:56 +00:00
|
|
|
static GHashTable *named_style_hash = NULL;
|
|
|
|
|
2009-09-28 15:33:05 +00:00
|
|
|
/* 0xBBGGRR format, set by "default" named style. */
|
2009-06-18 14:20:07 +00:00
|
|
|
static GeanyLexerStyle gsd_default = {0x000000, 0xffffff, FALSE, FALSE};
|
2009-05-30 11:57:56 +00:00
|
|
|
|
|
|
|
|
2009-10-14 16:00:40 +00:00
|
|
|
/* Note: use sciwrappers.h instead where possible.
|
|
|
|
* Do not use SSM in files unrelated to scintilla. */
|
2009-10-04 11:19:46 +00:00
|
|
|
#define SSM(s, m, w, l) scintilla_send_message(s, m, w, l)
|
|
|
|
|
2009-11-18 16:48:17 +00:00
|
|
|
/* filetypes should use the filetypes.foo [lexer_properties] group instead of hardcoding */
|
2009-10-04 11:15:26 +00:00
|
|
|
static void sci_set_property(ScintillaObject *sci, const gchar *name, const gchar *value)
|
|
|
|
{
|
|
|
|
SSM(sci, SCI_SETPROPERTY, (uptr_t) name, (sptr_t) value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-06 01:12:42 +01:00
|
|
|
static void new_styleset(guint file_type_id, gsize styling_count)
|
2006-09-30 11:13:58 +00:00
|
|
|
{
|
2008-08-26 09:48:18 +00:00
|
|
|
StyleSet *set = &style_sets[file_type_id];
|
|
|
|
|
|
|
|
set->count = styling_count;
|
2008-08-26 12:43:46 +00:00
|
|
|
set->styling = g_new0(GeanyLexerStyle, styling_count);
|
2006-09-30 11:13:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-06 01:12:42 +01:00
|
|
|
static void free_styleset(guint file_type_id)
|
2009-07-13 11:58:21 +00:00
|
|
|
{
|
|
|
|
StyleSet *style_ptr;
|
|
|
|
style_ptr = &style_sets[file_type_id];
|
|
|
|
|
|
|
|
style_ptr->count = 0;
|
|
|
|
g_free(style_ptr->styling);
|
|
|
|
style_ptr->styling = NULL;
|
|
|
|
g_strfreev(style_ptr->keywords);
|
|
|
|
style_ptr->keywords = NULL;
|
|
|
|
g_free(style_ptr->wordchars);
|
|
|
|
style_ptr->wordchars = NULL;
|
2009-11-18 16:48:17 +00:00
|
|
|
g_strfreev(style_ptr->property_keys);
|
|
|
|
style_ptr->property_keys = NULL;
|
|
|
|
g_strfreev(style_ptr->property_values);
|
|
|
|
style_ptr->property_values = NULL;
|
2009-07-13 11:58:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-29 12:54:56 +00:00
|
|
|
static void get_keyfile_keywords(GKeyFile *config, GKeyFile *configh,
|
2011-11-06 01:12:42 +01:00
|
|
|
const gchar *key, guint ft_id, guint pos)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2011-10-06 16:18:31 +00:00
|
|
|
style_sets[ft_id].keywords[pos] =
|
|
|
|
utils_get_setting(string, configh, config, "keywords", key, "");
|
2006-04-27 18:06:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-23 11:42:10 +00:00
|
|
|
static void get_keyfile_wordchars(GKeyFile *config, GKeyFile *configh, gchar **wordchars)
|
2006-04-27 18:06:35 +00:00
|
|
|
{
|
2011-10-06 16:18:31 +00:00
|
|
|
*wordchars = utils_get_setting(string, configh, config,
|
|
|
|
"settings", "wordchars", GEANY_WORDCHARS);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-18 17:13:59 +00:00
|
|
|
static gboolean read_named_style(const gchar *named_style, GeanyLexerStyle *style)
|
2009-05-30 11:57:56 +00:00
|
|
|
{
|
2009-06-03 15:42:01 +00:00
|
|
|
GeanyLexerStyle *cs;
|
2009-06-18 14:20:07 +00:00
|
|
|
gchar *comma, *name = NULL;
|
2009-06-03 15:42:01 +00:00
|
|
|
const gchar *bold = NULL;
|
|
|
|
const gchar *italic = NULL;
|
|
|
|
|
2010-10-18 17:13:59 +00:00
|
|
|
g_return_val_if_fail(named_style, FALSE);
|
2009-07-07 11:57:50 +00:00
|
|
|
name = utils_strdupa(named_style); /* named_style must not be written to, may be a static string */
|
2009-06-03 15:42:01 +00:00
|
|
|
|
|
|
|
comma = strstr(name, ",");
|
|
|
|
if (comma)
|
|
|
|
{
|
|
|
|
bold = strstr(comma, ",bold");
|
|
|
|
italic = strstr(comma, ",italic");
|
|
|
|
*comma = '\0'; /* terminate name to make lookup work */
|
|
|
|
}
|
|
|
|
cs = g_hash_table_lookup(named_style_hash, name);
|
2009-05-30 11:57:56 +00:00
|
|
|
|
|
|
|
if (cs)
|
2009-06-03 15:42:01 +00:00
|
|
|
{
|
2009-06-18 14:20:07 +00:00
|
|
|
*style = *cs;
|
|
|
|
if (bold)
|
|
|
|
style->bold = !style->bold;
|
|
|
|
if (italic)
|
|
|
|
style->italic = !style->italic;
|
2009-06-03 15:42:01 +00:00
|
|
|
}
|
2009-05-30 11:57:56 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
*style = gsd_default;
|
|
|
|
}
|
2010-10-18 17:13:59 +00:00
|
|
|
return (cs != NULL);
|
2009-05-30 11:57:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-25 13:41:16 -08:00
|
|
|
/* Parses a color in `str` which can be an HTML color (ex. #0099cc),
|
|
|
|
* an abbreviated HTML color (ex. #09c) or a hex string color
|
|
|
|
* (ex. 0x0099cc). The result of the conversion is stored into the
|
|
|
|
* location pointed to by `clr`. */
|
2011-12-25 14:11:47 -08:00
|
|
|
static void parse_color(GKeyFile *kf, const gchar *str, gint *clr)
|
2009-06-05 15:59:58 +00:00
|
|
|
{
|
|
|
|
gint c;
|
2011-12-25 14:11:47 -08:00
|
|
|
gchar *named_color = NULL;
|
2011-12-25 13:41:16 -08:00
|
|
|
|
|
|
|
g_return_if_fail(clr != NULL);
|
2009-06-05 15:59:58 +00:00
|
|
|
|
2013-08-11 14:10:57 +01:00
|
|
|
if (G_UNLIKELY(EMPTY(str)))
|
2009-06-05 15:59:58 +00:00
|
|
|
return;
|
|
|
|
|
2011-12-25 14:11:47 -08:00
|
|
|
named_color = g_key_file_get_string(kf, "named_colors", str, NULL);
|
2013-12-02 22:58:54 +01:00
|
|
|
if (named_color)
|
2011-12-25 14:11:47 -08:00
|
|
|
str = named_color;
|
|
|
|
|
2013-12-04 15:31:17 +01:00
|
|
|
c = utils_parse_color_to_bgr(str);
|
2013-12-02 22:58:54 +01:00
|
|
|
if (c == -1)
|
2011-12-26 00:37:16 -08:00
|
|
|
geany_debug("Bad color '%s'", str);
|
2011-12-25 13:41:16 -08:00
|
|
|
else
|
2013-12-02 22:58:54 +01:00
|
|
|
*clr = c;
|
2011-12-25 13:41:16 -08:00
|
|
|
|
2011-12-25 14:11:47 -08:00
|
|
|
g_free(named_color);
|
2009-06-05 15:59:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-25 14:11:47 -08:00
|
|
|
static void parse_keyfile_style(GKeyFile *kf, gchar **list,
|
2009-05-30 11:57:56 +00:00
|
|
|
const GeanyLexerStyle *default_style, GeanyLexerStyle *style)
|
2006-10-27 11:30:23 +00:00
|
|
|
{
|
2009-06-05 15:59:58 +00:00
|
|
|
gsize len;
|
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
g_return_if_fail(default_style);
|
|
|
|
g_return_if_fail(style);
|
2006-10-27 11:30:23 +00:00
|
|
|
|
2009-06-05 15:59:58 +00:00
|
|
|
*style = *default_style;
|
2009-05-30 11:57:56 +00:00
|
|
|
|
2009-06-05 15:59:58 +00:00
|
|
|
if (!list)
|
|
|
|
return;
|
2006-10-27 11:30:23 +00:00
|
|
|
|
2009-06-05 15:59:58 +00:00
|
|
|
len = g_strv_length(list);
|
2011-12-26 00:37:16 -08:00
|
|
|
if (len == 0)
|
|
|
|
return;
|
|
|
|
else if (len == 1)
|
2010-10-18 17:13:59 +00:00
|
|
|
{
|
2011-12-26 00:37:16 -08:00
|
|
|
gchar **items = g_strsplit(list[0], ",", 0);
|
|
|
|
if (items != NULL)
|
|
|
|
{
|
|
|
|
if (g_strv_length(items) > 0)
|
|
|
|
{
|
|
|
|
if (g_hash_table_lookup(named_style_hash, items[0]) != NULL)
|
|
|
|
{
|
|
|
|
if (!read_named_style(list[0], style))
|
|
|
|
geany_debug("Unable to read named style '%s'", items[0]);
|
|
|
|
g_strfreev(items);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (strchr(list[0], ',') != NULL)
|
|
|
|
{
|
|
|
|
geany_debug("Unknown named style '%s'", items[0]);
|
|
|
|
g_strfreev(items);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g_strfreev(items);
|
|
|
|
}
|
2010-10-18 17:13:59 +00:00
|
|
|
}
|
2011-12-25 16:40:18 -08:00
|
|
|
|
|
|
|
switch (len)
|
2009-06-05 15:59:58 +00:00
|
|
|
{
|
2011-12-25 16:40:18 -08:00
|
|
|
case 4:
|
|
|
|
style->italic = utils_atob(list[3]);
|
|
|
|
case 3:
|
|
|
|
style->bold = utils_atob(list[2]);
|
|
|
|
case 2:
|
|
|
|
parse_color(kf, list[1], &style->background);
|
|
|
|
case 1:
|
|
|
|
parse_color(kf, list[0], &style->foreground);
|
2009-06-05 15:59:58 +00:00
|
|
|
}
|
2009-05-30 11:57:56 +00:00
|
|
|
}
|
|
|
|
|
2006-10-27 11:30:23 +00:00
|
|
|
|
2009-05-30 11:57:56 +00:00
|
|
|
static void get_keyfile_style(GKeyFile *config, GKeyFile *configh,
|
2009-09-28 15:33:05 +00:00
|
|
|
const gchar *key_name, GeanyLexerStyle *style)
|
2009-05-30 11:57:56 +00:00
|
|
|
{
|
|
|
|
gchar **list;
|
|
|
|
gsize len;
|
|
|
|
|
|
|
|
g_return_if_fail(config);
|
|
|
|
g_return_if_fail(configh);
|
|
|
|
g_return_if_fail(key_name);
|
|
|
|
g_return_if_fail(style);
|
|
|
|
|
|
|
|
list = g_key_file_get_string_list(configh, "styling", key_name, &len, NULL);
|
|
|
|
if (list == NULL)
|
2011-12-25 14:11:47 -08:00
|
|
|
{
|
2009-05-30 11:57:56 +00:00
|
|
|
list = g_key_file_get_string_list(config, "styling", key_name, &len, NULL);
|
2011-12-25 14:11:47 -08:00
|
|
|
parse_keyfile_style(config, list, &gsd_default, style);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
parse_keyfile_style(configh, list, &gsd_default, style);
|
2009-05-30 11:57:56 +00:00
|
|
|
|
2006-10-27 11:30:23 +00:00
|
|
|
g_strfreev(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-27 16:38:37 +00:00
|
|
|
static void convert_int(const gchar *int_str, gint *val)
|
|
|
|
{
|
|
|
|
gchar *end;
|
|
|
|
gint v = strtol(int_str, &end, 10);
|
|
|
|
|
|
|
|
if (int_str != end)
|
|
|
|
*val = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get first and second integer numbers, store in foreground and background fields of @a style. */
|
2006-09-30 11:13:58 +00:00
|
|
|
static void get_keyfile_int(GKeyFile *config, GKeyFile *configh, const gchar *section,
|
|
|
|
const gchar *key, gint fdefault_val, gint sdefault_val,
|
2008-08-26 12:43:46 +00:00
|
|
|
GeanyLexerStyle *style)
|
2006-04-27 18:06:35 +00:00
|
|
|
{
|
|
|
|
gchar **list;
|
|
|
|
gsize len;
|
2009-09-27 16:38:37 +00:00
|
|
|
GeanyLexerStyle def = {fdefault_val, sdefault_val, FALSE, FALSE};
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
g_return_if_fail(config);
|
|
|
|
g_return_if_fail(configh);
|
|
|
|
g_return_if_fail(section);
|
|
|
|
g_return_if_fail(key);
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2006-05-15 19:49:30 +00:00
|
|
|
list = g_key_file_get_string_list(configh, section, key, &len, NULL);
|
2009-04-05 21:07:40 +00:00
|
|
|
if (list == NULL)
|
|
|
|
list = g_key_file_get_string_list(config, section, key, &len, NULL);
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2009-09-27 16:38:37 +00:00
|
|
|
*style = def;
|
|
|
|
if (!list)
|
|
|
|
return;
|
2006-05-09 16:07:27 +00:00
|
|
|
|
2009-09-27 16:38:37 +00:00
|
|
|
if (list[0])
|
|
|
|
{
|
|
|
|
convert_int(list[0], &style->foreground);
|
|
|
|
if (list[1])
|
|
|
|
{
|
|
|
|
convert_int(list[1], &style->background);
|
|
|
|
}
|
|
|
|
}
|
2006-04-27 18:06:35 +00:00
|
|
|
g_strfreev(list);
|
|
|
|
}
|
|
|
|
|
2006-09-30 11:13:58 +00:00
|
|
|
|
2009-09-27 15:59:58 +00:00
|
|
|
/* first or second can be NULL. */
|
|
|
|
static void get_keyfile_ints(GKeyFile *config, GKeyFile *configh, const gchar *section,
|
|
|
|
const gchar *key,
|
|
|
|
gint fdefault_val, gint sdefault_val,
|
|
|
|
gint *first, gint *second)
|
|
|
|
{
|
|
|
|
GeanyLexerStyle tmp_style;
|
|
|
|
|
|
|
|
get_keyfile_int(config, configh, section, key, fdefault_val, sdefault_val, &tmp_style);
|
|
|
|
if (first)
|
|
|
|
*first = tmp_style.foreground;
|
|
|
|
if (second)
|
|
|
|
*second = tmp_style.background;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-16 14:28:53 +00:00
|
|
|
static guint invert(guint icolour)
|
|
|
|
{
|
2009-09-14 11:53:08 +00:00
|
|
|
if (interface_prefs.highlighting_invert_all)
|
2013-12-04 15:46:05 +01:00
|
|
|
return 0xffffff - icolour;
|
2006-06-16 14:28:53 +00:00
|
|
|
|
|
|
|
return icolour;
|
|
|
|
}
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2008-08-26 12:43:46 +00:00
|
|
|
static GeanyLexerStyle *get_style(guint ft_id, guint styling_index)
|
2006-02-10 20:52:17 +00:00
|
|
|
{
|
2009-08-14 11:05:47 +00:00
|
|
|
g_assert(ft_id < filetypes_array->len);
|
2006-09-30 11:13:58 +00:00
|
|
|
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(ft_id == GEANY_FILETYPES_NONE))
|
2008-08-26 09:48:18 +00:00
|
|
|
{
|
2009-04-15 22:47:33 +00:00
|
|
|
g_assert(styling_index < GCS_MAX);
|
2008-08-26 09:48:18 +00:00
|
|
|
return &common_style_set.styling[styling_index];
|
|
|
|
}
|
2006-09-30 11:13:58 +00:00
|
|
|
else
|
2008-08-26 09:48:18 +00:00
|
|
|
{
|
|
|
|
StyleSet *set = &style_sets[ft_id];
|
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
g_assert(styling_index < set->count);
|
2008-08-26 09:48:18 +00:00
|
|
|
return &set->styling[styling_index];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-06 01:12:42 +01:00
|
|
|
static void set_sci_style(ScintillaObject *sci, guint style, guint ft_id, guint styling_index)
|
2008-08-26 09:48:18 +00:00
|
|
|
{
|
2008-08-26 12:43:46 +00:00
|
|
|
GeanyLexerStyle *style_ptr = get_style(ft_id, styling_index);
|
2006-09-30 11:13:58 +00:00
|
|
|
|
|
|
|
SSM(sci, SCI_STYLESETFORE, style, invert(style_ptr->foreground));
|
|
|
|
SSM(sci, SCI_STYLESETBACK, style, invert(style_ptr->background));
|
|
|
|
SSM(sci, SCI_STYLESETBOLD, style, style_ptr->bold);
|
|
|
|
SSM(sci, SCI_STYLESETITALIC, style, style_ptr->italic);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-10 01:41:01 +01:00
|
|
|
void highlighting_free_styles(void)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2009-08-14 11:05:47 +00:00
|
|
|
guint i;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2009-08-14 11:05:47 +00:00
|
|
|
for (i = 0; i < filetypes_array->len; i++)
|
2009-08-14 11:13:22 +00:00
|
|
|
free_styleset(i);
|
2009-05-30 11:57:56 +00:00
|
|
|
|
|
|
|
if (named_style_hash)
|
|
|
|
g_hash_table_destroy(named_style_hash);
|
2009-08-14 11:05:47 +00:00
|
|
|
|
2010-09-09 17:21:05 +00:00
|
|
|
g_free(style_sets);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-09 12:04:15 +00:00
|
|
|
static GString *get_global_typenames(gint lang)
|
2006-11-08 11:42:05 +00:00
|
|
|
{
|
|
|
|
GString *s = NULL;
|
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
if (app->tm_workspace)
|
2006-11-08 11:42:05 +00:00
|
|
|
{
|
|
|
|
GPtrArray *tags_array = app->tm_workspace->global_tags;
|
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
if (tags_array)
|
2006-11-08 11:42:05 +00:00
|
|
|
{
|
2007-10-09 12:04:15 +00:00
|
|
|
s = symbols_find_tags_as_string(tags_array, TM_GLOBAL_TYPE_MASK, lang);
|
2006-11-08 11:42:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-07 11:33:32 +00:00
|
|
|
static gchar*
|
|
|
|
get_keyfile_whitespace_chars(GKeyFile *config, GKeyFile *configh)
|
|
|
|
{
|
2011-10-06 16:18:31 +00:00
|
|
|
return utils_get_setting(string, configh, config,
|
|
|
|
"settings", "whitespace_chars", GEANY_WHITESPACE_CHARS);
|
2007-07-07 11:33:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-22 15:26:44 +00:00
|
|
|
static void add_named_style(GKeyFile *config, const gchar *key)
|
|
|
|
{
|
|
|
|
const gchar group[] = "named_styles";
|
|
|
|
gchar **list;
|
|
|
|
gsize len;
|
|
|
|
|
|
|
|
list = g_key_file_get_string_list(config, group, key, &len, NULL);
|
|
|
|
/* we allow a named style to reference another style above it */
|
|
|
|
if (list && len >= 1)
|
|
|
|
{
|
|
|
|
GeanyLexerStyle *style = g_new0(GeanyLexerStyle, 1);
|
|
|
|
|
2011-12-25 14:11:47 -08:00
|
|
|
parse_keyfile_style(config, list, &gsd_default, style);
|
2009-06-22 15:26:44 +00:00
|
|
|
g_hash_table_insert(named_style_hash, g_strdup(key), style);
|
|
|
|
}
|
|
|
|
g_strfreev(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-30 11:57:56 +00:00
|
|
|
static void get_named_styles(GKeyFile *config)
|
|
|
|
{
|
|
|
|
const gchar group[] = "named_styles";
|
|
|
|
gchar **keys = g_key_file_get_keys(config, group, NULL, NULL);
|
|
|
|
gchar **ptr = keys;
|
|
|
|
|
|
|
|
if (!ptr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
const gchar *key = *ptr;
|
|
|
|
|
|
|
|
if (!key)
|
|
|
|
break;
|
|
|
|
|
2009-06-22 15:26:44 +00:00
|
|
|
/* don't replace already read default style with system one */
|
|
|
|
if (!g_str_equal(key, "default"))
|
|
|
|
add_named_style(config, key);
|
2009-05-30 11:57:56 +00:00
|
|
|
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
g_strfreev(keys);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-04 12:36:56 +00:00
|
|
|
static GKeyFile *utils_key_file_new(const gchar *filename)
|
|
|
|
{
|
|
|
|
GKeyFile *config = g_key_file_new();
|
|
|
|
|
|
|
|
g_key_file_load_from_file(config, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-04 14:47:07 +00:00
|
|
|
static void load_named_styles(GKeyFile *config, GKeyFile *config_home)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2009-11-04 12:36:56 +00:00
|
|
|
const gchar *scheme = editor_prefs.color_scheme;
|
2009-11-05 18:03:34 +00:00
|
|
|
gboolean free_kf = FALSE;
|
2009-11-04 12:36:56 +00:00
|
|
|
|
2009-07-13 11:58:21 +00:00
|
|
|
if (named_style_hash)
|
2009-07-15 14:23:02 +00:00
|
|
|
g_hash_table_destroy(named_style_hash); /* reloading */
|
|
|
|
|
|
|
|
named_style_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
2009-06-22 15:26:44 +00:00
|
|
|
|
2013-08-11 14:10:57 +01:00
|
|
|
if (!EMPTY(scheme))
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
2009-11-05 18:03:34 +00:00
|
|
|
gchar *path, *path_home;
|
|
|
|
|
|
|
|
path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_COLORSCHEMES_SUBDIR, scheme, NULL);
|
|
|
|
path_home = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_COLORSCHEMES_SUBDIR, scheme, NULL);
|
|
|
|
|
|
|
|
if (g_file_test(path, G_FILE_TEST_EXISTS) || g_file_test(path_home, G_FILE_TEST_EXISTS))
|
|
|
|
{
|
|
|
|
config = utils_key_file_new(path);
|
|
|
|
config_home = utils_key_file_new(path_home);
|
|
|
|
free_kf = TRUE;
|
|
|
|
}
|
|
|
|
/* if color scheme is missing, use default */
|
|
|
|
g_free(path);
|
|
|
|
g_free(path_home);
|
2009-11-04 12:36:56 +00:00
|
|
|
}
|
2009-06-22 15:26:44 +00:00
|
|
|
/* first set default to the "default" named style */
|
|
|
|
add_named_style(config, "default");
|
2009-11-04 14:59:16 +00:00
|
|
|
read_named_style("default", &gsd_default); /* in case user overrides but not with both colors */
|
2009-06-22 15:26:44 +00:00
|
|
|
add_named_style(config_home, "default");
|
|
|
|
read_named_style("default", &gsd_default);
|
|
|
|
|
2009-06-01 13:46:21 +00:00
|
|
|
get_named_styles(config);
|
2009-06-22 15:26:44 +00:00
|
|
|
/* home overrides any system named style */
|
2009-06-01 13:46:21 +00:00
|
|
|
get_named_styles(config_home);
|
|
|
|
|
2009-11-05 18:03:34 +00:00
|
|
|
if (free_kf)
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
|
|
|
g_key_file_free(config);
|
|
|
|
g_key_file_free(config_home);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-26 12:56:30 +00:00
|
|
|
static void styleset_common_init(GKeyFile *config, GKeyFile *config_home)
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
2009-11-04 14:47:07 +00:00
|
|
|
load_named_styles(config, config_home);
|
2009-11-04 12:36:56 +00:00
|
|
|
|
2009-09-28 15:33:05 +00:00
|
|
|
get_keyfile_style(config, config_home, "default", &common_style_set.styling[GCS_DEFAULT]);
|
|
|
|
get_keyfile_style(config, config_home, "selection", &common_style_set.styling[GCS_SELECTION]);
|
|
|
|
get_keyfile_style(config, config_home, "brace_good", &common_style_set.styling[GCS_BRACE_GOOD]);
|
|
|
|
get_keyfile_style(config, config_home, "brace_bad", &common_style_set.styling[GCS_BRACE_BAD]);
|
|
|
|
get_keyfile_style(config, config_home, "margin_linenumber", &common_style_set.styling[GCS_MARGIN_LINENUMBER]);
|
|
|
|
get_keyfile_style(config, config_home, "margin_folding", &common_style_set.styling[GCS_MARGIN_FOLDING]);
|
2010-07-01 14:33:41 +00:00
|
|
|
get_keyfile_style(config, config_home, "fold_symbol_highlight", &common_style_set.styling[GCS_FOLD_SYMBOL_HIGHLIGHT]);
|
2009-09-28 15:33:05 +00:00
|
|
|
get_keyfile_style(config, config_home, "current_line", &common_style_set.styling[GCS_CURRENT_LINE]);
|
|
|
|
get_keyfile_style(config, config_home, "caret", &common_style_set.styling[GCS_CARET]);
|
|
|
|
get_keyfile_style(config, config_home, "indent_guide", &common_style_set.styling[GCS_INDENT_GUIDE]);
|
|
|
|
get_keyfile_style(config, config_home, "white_space", &common_style_set.styling[GCS_WHITE_SPACE]);
|
|
|
|
get_keyfile_style(config, config_home, "marker_line", &common_style_set.styling[GCS_MARKER_LINE]);
|
|
|
|
get_keyfile_style(config, config_home, "marker_search", &common_style_set.styling[GCS_MARKER_SEARCH]);
|
|
|
|
get_keyfile_style(config, config_home, "marker_mark", &common_style_set.styling[GCS_MARKER_MARK]);
|
2009-12-29 18:45:21 +00:00
|
|
|
get_keyfile_style(config, config_home, "calltips", &common_style_set.styling[GCS_CALLTIPS]);
|
2009-09-27 15:59:58 +00:00
|
|
|
|
|
|
|
get_keyfile_ints(config, config_home, "styling", "folding_style",
|
|
|
|
1, 1, &common_style_set.fold_marker, &common_style_set.fold_lines);
|
|
|
|
get_keyfile_ints(config, config_home, "styling", "folding_horiz_line",
|
|
|
|
2, 0, &common_style_set.fold_draw_line, NULL);
|
|
|
|
get_keyfile_ints(config, config_home, "styling", "caret_width",
|
|
|
|
1, 0, &common_style_set.styling[GCS_CARET].background, NULL); /* caret.foreground used earlier */
|
|
|
|
get_keyfile_int(config, config_home, "styling", "line_wrap_visuals",
|
|
|
|
3, 0, &common_style_set.styling[GCS_LINE_WRAP_VISUALS]);
|
|
|
|
get_keyfile_int(config, config_home, "styling", "line_wrap_indent",
|
|
|
|
0, 0, &common_style_set.styling[GCS_LINE_WRAP_INDENT]);
|
|
|
|
get_keyfile_int(config, config_home, "styling", "translucency",
|
|
|
|
256, 256, &common_style_set.styling[GCS_TRANSLUCENCY]);
|
|
|
|
get_keyfile_int(config, config_home, "styling", "marker_translucency",
|
|
|
|
256, 256, &common_style_set.styling[GCS_MARKER_TRANSLUCENCY]);
|
|
|
|
get_keyfile_int(config, config_home, "styling", "line_height",
|
|
|
|
0, 0, &common_style_set.styling[GCS_LINE_HEIGHT]);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-11-23 11:42:10 +00:00
|
|
|
get_keyfile_wordchars(config, config_home, &common_style_set.wordchars);
|
2007-07-07 11:33:32 +00:00
|
|
|
whitespace_chars = get_keyfile_whitespace_chars(config, config_home);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-10-06 01:32:54 +02:00
|
|
|
static void set_character_classes(ScintillaObject *sci, guint ft_id)
|
|
|
|
{
|
|
|
|
const gchar *word = (ft_id == GEANY_FILETYPES_NONE ?
|
|
|
|
common_style_set.wordchars : style_sets[ft_id].wordchars);
|
|
|
|
gchar *whitespace;
|
|
|
|
guint i, j;
|
|
|
|
|
|
|
|
SSM(sci, SCI_SETWORDCHARS, 0, (sptr_t) word);
|
|
|
|
|
|
|
|
/* setting wordchars resets character classes, so we have to set whitespaces after
|
|
|
|
* wordchars, but we want wordchars to have precenence over whitepace chars */
|
|
|
|
whitespace = g_malloc0(strlen(whitespace_chars) + 1);
|
|
|
|
for (i = 0, j = 0; whitespace_chars[i] != 0; i++)
|
|
|
|
{
|
|
|
|
if (! strchr(word, whitespace_chars[i]))
|
|
|
|
whitespace[j++] = whitespace_chars[i];
|
|
|
|
}
|
|
|
|
whitespace[j] = 0;
|
|
|
|
|
|
|
|
SSM(sci, SCI_SETWHITESPACECHARS, 0, (sptr_t) whitespace);
|
|
|
|
|
|
|
|
g_free(whitespace);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-06 01:12:42 +01:00
|
|
|
static void styleset_common(ScintillaObject *sci, guint ft_id)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2012-06-03 17:34:33 +01:00
|
|
|
GeanyLexerStyle *style;
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
SSM(sci, SCI_STYLECLEARALL, 0, 0);
|
|
|
|
|
2012-10-06 01:32:54 +02:00
|
|
|
set_character_classes(sci, ft_id);
|
2009-08-14 11:05:47 +00:00
|
|
|
|
2008-03-07 15:42:46 +00:00
|
|
|
/* caret colour, style and width */
|
2006-09-30 11:13:58 +00:00
|
|
|
SSM(sci, SCI_SETCARETFORE, invert(common_style_set.styling[GCS_CARET].foreground), 0);
|
2007-03-20 18:15:07 +00:00
|
|
|
SSM(sci, SCI_SETCARETWIDTH, common_style_set.styling[GCS_CARET].background, 0);
|
2008-03-07 15:42:46 +00:00
|
|
|
if (common_style_set.styling[GCS_CARET].bold)
|
|
|
|
SSM(sci, SCI_SETCARETSTYLE, CARETSTYLE_BLOCK, 0);
|
|
|
|
else
|
|
|
|
SSM(sci, SCI_SETCARETSTYLE, CARETSTYLE_LINE, 0);
|
2006-07-30 16:02:21 +00:00
|
|
|
|
2009-07-08 22:21:45 +00:00
|
|
|
/* line height */
|
|
|
|
SSM(sci, SCI_SETEXTRAASCENT, common_style_set.styling[GCS_LINE_HEIGHT].foreground, 0);
|
|
|
|
SSM(sci, SCI_SETEXTRADESCENT, common_style_set.styling[GCS_LINE_HEIGHT].background, 0);
|
|
|
|
|
2009-05-11 15:56:08 +00:00
|
|
|
/* colourise the current line */
|
2006-09-30 11:13:58 +00:00
|
|
|
SSM(sci, SCI_SETCARETLINEBACK, invert(common_style_set.styling[GCS_CURRENT_LINE].background), 0);
|
2008-03-07 15:42:46 +00:00
|
|
|
/* bold=enable current line */
|
|
|
|
SSM(sci, SCI_SETCARETLINEVISIBLE, common_style_set.styling[GCS_CURRENT_LINE].bold, 0);
|
|
|
|
|
|
|
|
/* Translucency for current line and selection */
|
|
|
|
SSM(sci, SCI_SETCARETLINEBACKALPHA, common_style_set.styling[GCS_TRANSLUCENCY].foreground, 0);
|
|
|
|
SSM(sci, SCI_SETSELALPHA, common_style_set.styling[GCS_TRANSLUCENCY].background, 0);
|
|
|
|
|
|
|
|
/* line wrapping visuals */
|
|
|
|
SSM(sci, SCI_SETWRAPVISUALFLAGS,
|
|
|
|
common_style_set.styling[GCS_LINE_WRAP_VISUALS].foreground, 0);
|
|
|
|
SSM(sci, SCI_SETWRAPVISUALFLAGSLOCATION,
|
|
|
|
common_style_set.styling[GCS_LINE_WRAP_VISUALS].background, 0);
|
|
|
|
SSM(sci, SCI_SETWRAPSTARTINDENT, common_style_set.styling[GCS_LINE_WRAP_INDENT].foreground, 0);
|
2009-07-04 09:21:44 +00:00
|
|
|
SSM(sci, SCI_SETWRAPINDENTMODE, common_style_set.styling[GCS_LINE_WRAP_INDENT].background, 0);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-10-25 18:57:00 +00:00
|
|
|
/* Error indicator */
|
2012-09-22 12:47:29 +10:00
|
|
|
SSM(sci, SCI_INDICSETSTYLE, GEANY_INDICATOR_ERROR, INDIC_SQUIGGLEPIXMAP);
|
2013-12-04 15:49:47 +01:00
|
|
|
SSM(sci, SCI_INDICSETFORE, GEANY_INDICATOR_ERROR, invert(0x0000FF /* red, in BGR */));
|
2008-10-25 18:57:00 +00:00
|
|
|
|
|
|
|
/* Search indicator, used for 'Mark' matches */
|
|
|
|
SSM(sci, SCI_INDICSETSTYLE, GEANY_INDICATOR_SEARCH, INDIC_ROUNDBOX);
|
2009-07-08 22:22:28 +00:00
|
|
|
SSM(sci, SCI_INDICSETFORE, GEANY_INDICATOR_SEARCH,
|
|
|
|
invert(common_style_set.styling[GCS_MARKER_SEARCH].background));
|
|
|
|
SSM(sci, SCI_INDICSETALPHA, GEANY_INDICATOR_SEARCH, 60);
|
2006-07-14 10:15:12 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* define marker symbols
|
|
|
|
* 0 -> line marker */
|
2005-11-22 12:26:26 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, 0, SC_MARK_SHORTARROW);
|
2008-03-23 14:57:53 +00:00
|
|
|
SSM(sci, SCI_MARKERSETFORE, 0, invert(common_style_set.styling[GCS_MARKER_LINE].foreground));
|
|
|
|
SSM(sci, SCI_MARKERSETBACK, 0, invert(common_style_set.styling[GCS_MARKER_LINE].background));
|
|
|
|
SSM(sci, SCI_MARKERSETALPHA, 0, common_style_set.styling[GCS_MARKER_TRANSLUCENCY].foreground);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* 1 -> user marker */
|
2005-11-22 12:26:26 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, 1, SC_MARK_PLUS);
|
2009-07-08 22:22:28 +00:00
|
|
|
SSM(sci, SCI_MARKERSETFORE, 1, invert(common_style_set.styling[GCS_MARKER_MARK].foreground));
|
|
|
|
SSM(sci, SCI_MARKERSETBACK, 1, invert(common_style_set.styling[GCS_MARKER_MARK].background));
|
2008-03-23 14:57:53 +00:00
|
|
|
SSM(sci, SCI_MARKERSETALPHA, 1, common_style_set.styling[GCS_MARKER_TRANSLUCENCY].background);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* 2 -> folding marker, other folding settings */
|
2006-02-26 18:19:28 +00:00
|
|
|
SSM(sci, SCI_SETMARGINTYPEN, 2, SC_MARGIN_SYMBOL);
|
|
|
|
SSM(sci, SCI_SETMARGINMASKN, 2, SC_MASK_FOLDERS);
|
2006-11-07 18:53:39 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* drawing a horizontal line when text if folded */
|
2009-09-27 15:59:58 +00:00
|
|
|
switch (common_style_set.fold_draw_line)
|
2006-11-07 18:53:39 +00:00
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
SSM(sci, SCI_SETFOLDFLAGS, 4, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
SSM(sci, SCI_SETFOLDFLAGS, 16, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
SSM(sci, SCI_SETFOLDFLAGS, 0, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-02-26 18:19:28 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* choose the folding style - boxes or circles, I prefer boxes, so it is default ;-) */
|
2010-04-22 17:16:46 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY);
|
2009-09-27 15:59:58 +00:00
|
|
|
switch (common_style_set.fold_marker)
|
2006-04-27 18:06:35 +00:00
|
|
|
{
|
|
|
|
case 2:
|
2010-04-22 17:16:46 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_CIRCLEMINUS);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_CIRCLEPLUS);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_CIRCLEPLUSCONNECTED);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_CIRCLEMINUSCONNECTED);
|
2006-04-27 18:06:35 +00:00
|
|
|
break;
|
2006-05-09 16:07:27 +00:00
|
|
|
default:
|
2010-04-22 17:16:46 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_BOXMINUS);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_BOXPLUS);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_BOXPLUSCONNECTED);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_BOXMINUSCONNECTED);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_ARROWDOWN);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_ARROW);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_PLUS);
|
2006-04-27 18:06:35 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* choose the folding style - straight or curved, I prefer straight, so it is default ;-) */
|
2009-09-27 15:59:58 +00:00
|
|
|
switch (common_style_set.fold_lines)
|
2006-04-27 18:06:35 +00:00
|
|
|
{
|
|
|
|
case 2:
|
2009-09-16 14:13:38 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE);
|
2010-04-22 17:16:46 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
|
2006-04-27 18:06:35 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-09-16 14:13:38 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNER);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNER);
|
2010-04-22 17:16:46 +00:00
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY);
|
|
|
|
SSM(sci, SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY);
|
2006-04-27 18:06:35 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-07-01 14:33:41 +00:00
|
|
|
{
|
|
|
|
gint markers[] = {
|
|
|
|
SC_MARKNUM_FOLDEROPEN,
|
|
|
|
SC_MARKNUM_FOLDER,
|
|
|
|
SC_MARKNUM_FOLDERSUB,
|
|
|
|
SC_MARKNUM_FOLDERTAIL,
|
|
|
|
SC_MARKNUM_FOLDEREND,
|
|
|
|
SC_MARKNUM_FOLDEROPENMID,
|
|
|
|
SC_MARKNUM_FOLDERMIDTAIL
|
|
|
|
};
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
foreach_range(i, G_N_ELEMENTS(markers))
|
|
|
|
{
|
|
|
|
SSM(sci, SCI_MARKERSETFORE, markers[i],
|
|
|
|
invert(common_style_set.styling[GCS_FOLD_SYMBOL_HIGHLIGHT].foreground));
|
|
|
|
SSM(sci, SCI_MARKERSETBACK, markers[i],
|
|
|
|
invert(common_style_set.styling[GCS_MARGIN_FOLDING].foreground));
|
|
|
|
}
|
|
|
|
}
|
2006-02-26 18:19:28 +00:00
|
|
|
|
2010-07-01 11:49:30 +00:00
|
|
|
/* set some common defaults */
|
2009-10-04 11:15:26 +00:00
|
|
|
sci_set_property(sci, "fold", "1");
|
|
|
|
sci_set_property(sci, "fold.compact", "0");
|
2010-06-30 11:34:11 +00:00
|
|
|
sci_set_property(sci, "fold.comment", "1");
|
2009-10-04 11:15:26 +00:00
|
|
|
sci_set_property(sci, "fold.preprocessor", "1");
|
|
|
|
sci_set_property(sci, "fold.at.else", "1");
|
2006-02-26 18:19:28 +00:00
|
|
|
|
2012-06-03 17:34:33 +01:00
|
|
|
style = &common_style_set.styling[GCS_SELECTION];
|
2012-06-03 18:04:03 +01:00
|
|
|
if (!style->bold && !style->italic)
|
|
|
|
{
|
2012-06-08 13:28:07 +01:00
|
|
|
geany_debug("selection style is set to invisible - ignoring!");
|
2012-06-03 18:04:03 +01:00
|
|
|
style->italic = TRUE;
|
|
|
|
style->background = 0xc0c0c0;
|
|
|
|
}
|
2008-02-27 13:17:29 +00:00
|
|
|
/* bold (3rd argument) is whether to override default foreground selection */
|
2012-06-03 17:34:33 +01:00
|
|
|
SSM(sci, SCI_SETSELFORE, style->bold, invert(style->foreground));
|
2008-02-27 13:17:29 +00:00
|
|
|
/* italic (4th argument) is whether to override default background selection */
|
2012-06-03 17:34:33 +01:00
|
|
|
SSM(sci, SCI_SETSELBACK, style->italic, invert(style->background));
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-09-28 18:07:08 +00:00
|
|
|
SSM(sci, SCI_SETSTYLEBITS, SSM(sci, SCI_GETSTYLEBITSNEEDED, 0, 0), 0);
|
2006-06-16 14:28:53 +00:00
|
|
|
|
2006-09-30 11:13:58 +00:00
|
|
|
SSM(sci, SCI_SETFOLDMARGINCOLOUR, 1, invert(common_style_set.styling[GCS_MARGIN_FOLDING].background));
|
2010-05-08 13:10:14 +00:00
|
|
|
SSM(sci, SCI_SETFOLDMARGINHICOLOUR, 1, invert(common_style_set.styling[GCS_MARGIN_FOLDING].background));
|
2008-05-07 13:54:21 +00:00
|
|
|
set_sci_style(sci, STYLE_LINENUMBER, GEANY_FILETYPES_NONE, GCS_MARGIN_LINENUMBER);
|
|
|
|
set_sci_style(sci, STYLE_BRACELIGHT, GEANY_FILETYPES_NONE, GCS_BRACE_GOOD);
|
|
|
|
set_sci_style(sci, STYLE_BRACEBAD, GEANY_FILETYPES_NONE, GCS_BRACE_BAD);
|
|
|
|
set_sci_style(sci, STYLE_INDENTGUIDE, GEANY_FILETYPES_NONE, GCS_INDENT_GUIDE);
|
2006-08-13 15:04:30 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* bold = common whitespace settings enabled */
|
2006-09-30 11:13:58 +00:00
|
|
|
SSM(sci, SCI_SETWHITESPACEFORE, common_style_set.styling[GCS_WHITE_SPACE].bold,
|
|
|
|
invert(common_style_set.styling[GCS_WHITE_SPACE].foreground));
|
2007-05-15 15:39:26 +00:00
|
|
|
SSM(sci, SCI_SETWHITESPACEBACK, common_style_set.styling[GCS_WHITE_SPACE].italic,
|
2006-09-30 11:13:58 +00:00
|
|
|
invert(common_style_set.styling[GCS_WHITE_SPACE].background));
|
2009-12-29 18:45:21 +00:00
|
|
|
|
|
|
|
if (common_style_set.styling[GCS_CALLTIPS].bold)
|
|
|
|
SSM(sci, SCI_CALLTIPSETFORE, invert(common_style_set.styling[GCS_CALLTIPS].foreground), 1);
|
|
|
|
if (common_style_set.styling[GCS_CALLTIPS].italic)
|
|
|
|
SSM(sci, SCI_CALLTIPSETBACK, invert(common_style_set.styling[GCS_CALLTIPS].background), 1);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-07 13:24:11 +00:00
|
|
|
/* Merge & assign global typedefs and user secondary keywords.
|
|
|
|
* keyword_idx is used for both style_sets[].keywords and scintilla keyword style number */
|
2011-11-06 01:12:42 +01:00
|
|
|
static void merge_type_keywords(ScintillaObject *sci, guint ft_id, guint keyword_idx)
|
2007-03-02 16:04:29 +00:00
|
|
|
{
|
2009-12-07 13:24:11 +00:00
|
|
|
const gchar *user_words = style_sets[ft_id].keywords[keyword_idx];
|
2007-03-02 16:04:29 +00:00
|
|
|
GString *s;
|
2007-03-09 13:52:26 +00:00
|
|
|
|
2009-12-07 13:24:11 +00:00
|
|
|
s = get_global_typenames(filetypes[ft_id]->lang);
|
2009-04-05 21:07:40 +00:00
|
|
|
if (G_UNLIKELY(s == NULL))
|
2007-03-02 16:04:29 +00:00
|
|
|
s = g_string_sized_new(200);
|
|
|
|
else
|
2008-02-27 13:17:29 +00:00
|
|
|
g_string_append_c(s, ' '); /* append a space as delimiter to the existing list of words */
|
2007-03-09 13:52:26 +00:00
|
|
|
|
2007-03-02 16:04:29 +00:00
|
|
|
g_string_append(s, user_words);
|
2007-03-09 13:52:26 +00:00
|
|
|
|
2009-12-07 13:24:11 +00:00
|
|
|
sci_set_keywords(sci, keyword_idx, s->str);
|
2007-03-02 16:04:29 +00:00
|
|
|
g_string_free(s, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-08 23:30:34 +01:00
|
|
|
static void styleset_init_from_mapping(guint ft_id, GKeyFile *config, GKeyFile *config_home,
|
|
|
|
const HLStyle *styles, gsize n_styles,
|
|
|
|
const HLKeyword *keywords, gsize n_keywords)
|
2009-06-18 14:20:07 +00:00
|
|
|
{
|
2011-11-08 23:30:34 +01:00
|
|
|
gsize i;
|
2009-06-18 14:20:07 +00:00
|
|
|
|
2011-11-08 23:30:34 +01:00
|
|
|
/* styles */
|
|
|
|
new_styleset(ft_id, n_styles);
|
2011-11-08 22:50:53 +01:00
|
|
|
foreach_range(i, n_styles)
|
2009-06-18 14:20:07 +00:00
|
|
|
{
|
2011-11-08 23:30:34 +01:00
|
|
|
GeanyLexerStyle *style = &style_sets[ft_id].styling[i];
|
2009-06-18 14:20:07 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
get_keyfile_style(config, config_home, styles[i].name, style);
|
2009-06-18 14:20:07 +00:00
|
|
|
}
|
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
/* keywords */
|
|
|
|
if (n_keywords < 1)
|
|
|
|
style_sets[ft_id].keywords = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
style_sets[ft_id].keywords = g_new(gchar*, n_keywords + 1);
|
|
|
|
foreach_range(i, n_keywords)
|
|
|
|
get_keyfile_keywords(config, config_home, keywords[i].key, ft_id, i);
|
|
|
|
style_sets[ft_id].keywords[i] = NULL;
|
|
|
|
}
|
2010-10-06 17:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-08 23:30:34 +01:00
|
|
|
/* STYLE_DEFAULT will be set to match the first style. */
|
2011-11-08 22:50:53 +01:00
|
|
|
static void styleset_from_mapping(ScintillaObject *sci, guint ft_id, guint lexer,
|
|
|
|
const HLStyle *styles, gsize n_styles,
|
|
|
|
const HLKeyword *keywords, gsize n_keywords,
|
|
|
|
const HLProperty *properties, gsize n_properties)
|
2010-10-20 15:45:25 +00:00
|
|
|
{
|
2011-11-08 22:50:53 +01:00
|
|
|
gsize i;
|
2010-10-20 15:45:25 +00:00
|
|
|
|
2011-11-10 15:40:30 +01:00
|
|
|
g_assert(ft_id != GEANY_FILETYPES_NONE);
|
|
|
|
|
|
|
|
/* lexer */
|
2012-02-12 22:35:08 -08:00
|
|
|
sci_set_lexer(sci, lexer);
|
2011-11-10 15:40:30 +01:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
/* styles */
|
2011-11-10 15:40:30 +01:00
|
|
|
styleset_common(sci, ft_id);
|
2011-11-08 23:30:34 +01:00
|
|
|
if (n_styles > 0)
|
|
|
|
{
|
|
|
|
/* first style is also default one */
|
|
|
|
set_sci_style(sci, STYLE_DEFAULT, ft_id, 0);
|
|
|
|
foreach_range(i, n_styles)
|
2011-11-09 17:14:05 +01:00
|
|
|
{
|
|
|
|
if (styles[i].fill_eol)
|
|
|
|
SSM(sci, SCI_STYLESETEOLFILLED, styles[i].style, TRUE);
|
2011-11-08 23:30:34 +01:00
|
|
|
set_sci_style(sci, styles[i].style, ft_id, i);
|
2011-11-09 17:14:05 +01:00
|
|
|
}
|
2011-11-08 23:30:34 +01:00
|
|
|
}
|
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
/* keywords */
|
|
|
|
foreach_range(i, n_keywords)
|
|
|
|
{
|
|
|
|
if (keywords[i].merge)
|
|
|
|
merge_type_keywords(sci, ft_id, i);
|
|
|
|
else
|
|
|
|
sci_set_keywords(sci, keywords[i].id, style_sets[ft_id].keywords[i]);
|
|
|
|
}
|
2011-11-08 23:30:34 +01:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
/* properties */
|
|
|
|
foreach_range(i, n_properties)
|
|
|
|
sci_set_property(sci, properties[i].property, properties[i].value);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-11-06 01:12:42 +01:00
|
|
|
static void styleset_default(ScintillaObject *sci, guint ft_id)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2012-02-12 22:35:08 -08:00
|
|
|
sci_set_lexer(sci, SCLEX_NULL);
|
2007-03-09 15:38:31 +00:00
|
|
|
|
2008-10-15 14:14:48 +00:00
|
|
|
/* we need to set STYLE_DEFAULT before we call SCI_STYLECLEARALL in styleset_common() */
|
2008-05-07 13:54:21 +00:00
|
|
|
set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_NONE, GCS_DEFAULT);
|
2007-03-09 15:38:31 +00:00
|
|
|
|
2009-08-14 11:05:47 +00:00
|
|
|
styleset_common(sci, ft_id);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
static void get_key_values(GKeyFile *config, const gchar *group, gchar **keys, gchar **values)
|
2009-11-24 15:47:44 +00:00
|
|
|
{
|
2011-11-08 22:50:53 +01:00
|
|
|
while (*keys)
|
|
|
|
{
|
|
|
|
gchar *str = g_key_file_get_string(config, group, *keys, NULL);
|
2007-05-11 11:58:56 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
if (str)
|
2012-01-25 16:26:16 +00:00
|
|
|
SETPTR(*values, str);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
keys++;
|
|
|
|
values++;
|
2008-10-18 17:00:03 +00:00
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
2005-11-27 20:46:36 +00:00
|
|
|
|
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
static void read_properties(GeanyFiletype *ft, GKeyFile *config, GKeyFile *configh)
|
2008-12-21 20:31:09 +00:00
|
|
|
{
|
2011-11-08 22:50:53 +01:00
|
|
|
gchar group[] = "lexer_properties";
|
|
|
|
gchar **keys;
|
|
|
|
gchar **keysh = g_key_file_get_keys(configh, group, NULL, NULL);
|
|
|
|
gchar **ptr;
|
|
|
|
|
|
|
|
/* remove overridden keys from system keyfile */
|
|
|
|
foreach_strv(ptr, keysh)
|
|
|
|
g_key_file_remove_key(config, group, *ptr, NULL);
|
2009-11-24 15:47:44 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
/* merge sys and user keys */
|
|
|
|
keys = g_key_file_get_keys(config, group, NULL, NULL);
|
|
|
|
keys = utils_strv_join(keys, keysh);
|
2009-11-24 15:47:44 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
if (keys)
|
|
|
|
{
|
|
|
|
gchar **values = g_new0(gchar*, g_strv_length(keys) + 1);
|
2008-12-21 20:31:09 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
style_sets[ft->id].property_keys = keys;
|
|
|
|
style_sets[ft->id].property_values = values;
|
2009-11-24 15:47:44 +00:00
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
get_key_values(config, group, keys, values);
|
|
|
|
get_key_values(configh, group, keys, values);
|
|
|
|
}
|
2008-12-21 20:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-08 22:50:53 +01:00
|
|
|
static guint get_lexer_filetype(GeanyFiletype *ft)
|
2008-09-28 16:32:49 +00:00
|
|
|
{
|
2013-08-11 14:10:57 +01:00
|
|
|
ft = FALLBACK(ft->lexer_filetype, ft);
|
2011-11-08 22:50:53 +01:00
|
|
|
return ft->id;
|
2008-09-28 16:32:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-10 15:35:03 +01:00
|
|
|
#define init_styleset_case(LANG_NAME) \
|
2011-11-08 22:50:53 +01:00
|
|
|
case (GEANY_FILETYPES_##LANG_NAME): \
|
2011-11-11 20:02:59 +01:00
|
|
|
styleset_init_from_mapping(filetype_idx, config, configh, \
|
|
|
|
highlighting_styles_##LANG_NAME, \
|
|
|
|
HL_N_ENTRIES(highlighting_styles_##LANG_NAME), \
|
|
|
|
highlighting_keywords_##LANG_NAME, \
|
|
|
|
HL_N_ENTRIES(highlighting_keywords_##LANG_NAME)); \
|
2011-11-08 22:50:53 +01:00
|
|
|
break
|
2007-11-02 17:44:05 +00:00
|
|
|
|
|
|
|
/* Called by filetypes_load_config(). */
|
2011-11-06 01:12:42 +01:00
|
|
|
void highlighting_init_styles(guint filetype_idx, GKeyFile *config, GKeyFile *configh)
|
2007-11-02 17:44:05 +00:00
|
|
|
{
|
2009-11-18 16:48:17 +00:00
|
|
|
GeanyFiletype *ft = filetypes[filetype_idx];
|
2011-11-06 01:12:42 +01:00
|
|
|
guint lexer_id = get_lexer_filetype(ft);
|
2012-05-29 17:59:37 +01:00
|
|
|
gchar *default_str;
|
2009-11-18 16:48:17 +00:00
|
|
|
|
2009-12-07 18:08:35 +00:00
|
|
|
if (!style_sets)
|
|
|
|
style_sets = g_new0(StyleSet, filetypes_array->len);
|
|
|
|
|
|
|
|
/* Clear old information if necessary - e.g. when reloading config */
|
|
|
|
free_styleset(filetype_idx);
|
|
|
|
|
|
|
|
read_properties(ft, config, configh);
|
2012-05-29 17:59:37 +01:00
|
|
|
/* If a default style exists, check it uses a named style
|
|
|
|
* Note: almost all filetypes have a "default" style, except HTML ones */
|
|
|
|
default_str = utils_get_setting(string, configh, config,
|
|
|
|
"styling", "default", "default");
|
|
|
|
ft->priv->warn_color_scheme = !g_ascii_isalpha(*default_str);
|
|
|
|
g_free(default_str);
|
2009-12-07 18:08:35 +00:00
|
|
|
|
2009-12-07 17:23:33 +00:00
|
|
|
/* None filetype handled specially */
|
|
|
|
if (filetype_idx == GEANY_FILETYPES_NONE)
|
|
|
|
{
|
2011-12-26 12:56:30 +00:00
|
|
|
styleset_common_init(config, configh);
|
2009-12-07 17:23:33 +00:00
|
|
|
return;
|
|
|
|
}
|
2007-11-02 17:44:05 +00:00
|
|
|
/* All stylesets depend on filetypes.common */
|
2009-12-07 17:23:33 +00:00
|
|
|
filetypes_load_config(GEANY_FILETYPES_NONE, FALSE);
|
2007-11-02 17:44:05 +00:00
|
|
|
|
2009-11-24 16:47:35 +00:00
|
|
|
switch (lexer_id)
|
2007-11-02 17:44:05 +00:00
|
|
|
{
|
2012-12-03 15:17:43 +01:00
|
|
|
init_styleset_case(ABAQUS);
|
2011-11-10 15:35:03 +01:00
|
|
|
init_styleset_case(ADA);
|
|
|
|
init_styleset_case(ASM);
|
|
|
|
init_styleset_case(BASIC);
|
2013-08-12 21:51:00 +02:00
|
|
|
init_styleset_case(BATCH);
|
2011-11-10 15:35:03 +01:00
|
|
|
init_styleset_case(C);
|
|
|
|
init_styleset_case(CAML);
|
|
|
|
init_styleset_case(CMAKE);
|
|
|
|
init_styleset_case(COBOL);
|
|
|
|
init_styleset_case(CONF);
|
|
|
|
init_styleset_case(CSS);
|
|
|
|
init_styleset_case(D);
|
|
|
|
init_styleset_case(DIFF);
|
|
|
|
init_styleset_case(LISP);
|
|
|
|
init_styleset_case(ERLANG);
|
|
|
|
init_styleset_case(DOCBOOK);
|
|
|
|
init_styleset_case(FERITE);
|
|
|
|
init_styleset_case(F77);
|
|
|
|
init_styleset_case(FORTH);
|
|
|
|
init_styleset_case(FORTRAN);
|
|
|
|
init_styleset_case(HASKELL);
|
|
|
|
init_styleset_case(HAXE);
|
|
|
|
init_styleset_case(AS);
|
|
|
|
init_styleset_case(HTML);
|
|
|
|
init_styleset_case(JAVA);
|
|
|
|
init_styleset_case(JS);
|
|
|
|
init_styleset_case(LATEX);
|
|
|
|
init_styleset_case(LUA);
|
|
|
|
init_styleset_case(MAKE);
|
|
|
|
init_styleset_case(MATLAB);
|
|
|
|
init_styleset_case(MARKDOWN);
|
|
|
|
init_styleset_case(NSIS);
|
2011-11-13 00:45:12 +01:00
|
|
|
init_styleset_case(OBJECTIVEC);
|
2011-11-10 15:35:03 +01:00
|
|
|
init_styleset_case(PASCAL);
|
|
|
|
init_styleset_case(PERL);
|
|
|
|
init_styleset_case(PHP);
|
|
|
|
init_styleset_case(PO);
|
2013-04-10 20:54:59 +03:00
|
|
|
init_styleset_case(POWERSHELL);
|
2011-11-10 15:35:03 +01:00
|
|
|
init_styleset_case(PYTHON);
|
|
|
|
init_styleset_case(R);
|
|
|
|
init_styleset_case(RUBY);
|
2013-10-16 17:19:29 -04:00
|
|
|
init_styleset_case(RUST);
|
2011-11-10 15:35:03 +01:00
|
|
|
init_styleset_case(SH);
|
|
|
|
init_styleset_case(SQL);
|
|
|
|
init_styleset_case(TCL);
|
|
|
|
init_styleset_case(TXT2TAGS);
|
|
|
|
init_styleset_case(VHDL);
|
|
|
|
init_styleset_case(VERILOG);
|
|
|
|
init_styleset_case(XML);
|
|
|
|
init_styleset_case(YAML);
|
2009-12-07 17:23:33 +00:00
|
|
|
default:
|
|
|
|
if (ft->lexer_filetype)
|
|
|
|
geany_debug("Filetype %s has a recursive lexer_filetype %s set!",
|
|
|
|
ft->name, ft->lexer_filetype->name);
|
2007-11-02 17:44:05 +00:00
|
|
|
}
|
2009-11-18 16:48:17 +00:00
|
|
|
|
2009-08-11 14:18:44 +00:00
|
|
|
/* should be done in filetypes.c really: */
|
2009-12-07 17:23:33 +00:00
|
|
|
get_keyfile_wordchars(config, configh, &style_sets[filetype_idx].wordchars);
|
2007-11-02 17:44:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-11-10 15:35:03 +01:00
|
|
|
#define styleset_case(LANG_NAME) \
|
2011-11-08 22:50:53 +01:00
|
|
|
case (GEANY_FILETYPES_##LANG_NAME): \
|
2011-11-11 20:02:59 +01:00
|
|
|
styleset_from_mapping(sci, ft->id, highlighting_lexer_##LANG_NAME, \
|
|
|
|
highlighting_styles_##LANG_NAME, \
|
|
|
|
HL_N_ENTRIES(highlighting_styles_##LANG_NAME), \
|
|
|
|
highlighting_keywords_##LANG_NAME, \
|
|
|
|
HL_N_ENTRIES(highlighting_keywords_##LANG_NAME), \
|
|
|
|
highlighting_properties_##LANG_NAME, \
|
|
|
|
HL_N_ENTRIES(highlighting_properties_##LANG_NAME)); \
|
2011-11-08 22:50:53 +01:00
|
|
|
break
|
|
|
|
|
2010-03-12 18:15:48 +00:00
|
|
|
/** Sets up highlighting and other visual settings.
|
2009-10-15 16:54:15 +00:00
|
|
|
* @param sci Scintilla widget.
|
|
|
|
* @param ft Filetype settings to use. */
|
|
|
|
void highlighting_set_styles(ScintillaObject *sci, GeanyFiletype *ft)
|
2007-11-02 17:44:05 +00:00
|
|
|
{
|
2011-11-06 01:12:42 +01:00
|
|
|
guint lexer_id = get_lexer_filetype(ft);
|
2009-11-24 15:47:44 +00:00
|
|
|
|
2009-10-15 16:54:15 +00:00
|
|
|
filetypes_load_config(ft->id, FALSE); /* load filetypes.ext */
|
2008-02-26 17:11:02 +00:00
|
|
|
|
2009-11-24 15:47:44 +00:00
|
|
|
switch (lexer_id)
|
2007-11-02 17:44:05 +00:00
|
|
|
{
|
2012-12-03 15:17:43 +01:00
|
|
|
styleset_case(ABAQUS);
|
2011-11-10 15:35:03 +01:00
|
|
|
styleset_case(ADA);
|
|
|
|
styleset_case(ASM);
|
|
|
|
styleset_case(BASIC);
|
2013-08-12 21:51:00 +02:00
|
|
|
styleset_case(BATCH);
|
2011-11-10 15:35:03 +01:00
|
|
|
styleset_case(C);
|
|
|
|
styleset_case(CAML);
|
|
|
|
styleset_case(CMAKE);
|
|
|
|
styleset_case(COBOL);
|
|
|
|
styleset_case(CONF);
|
|
|
|
styleset_case(CSS);
|
|
|
|
styleset_case(D);
|
|
|
|
styleset_case(DIFF);
|
|
|
|
styleset_case(LISP);
|
|
|
|
styleset_case(ERLANG);
|
|
|
|
styleset_case(DOCBOOK);
|
|
|
|
styleset_case(FERITE);
|
|
|
|
styleset_case(F77);
|
|
|
|
styleset_case(FORTH);
|
|
|
|
styleset_case(FORTRAN);
|
|
|
|
styleset_case(HASKELL);
|
|
|
|
styleset_case(HAXE);
|
|
|
|
styleset_case(AS);
|
|
|
|
styleset_case(HTML);
|
|
|
|
styleset_case(JAVA);
|
|
|
|
styleset_case(JS);
|
|
|
|
styleset_case(LATEX);
|
|
|
|
styleset_case(LUA);
|
|
|
|
styleset_case(MAKE);
|
|
|
|
styleset_case(MARKDOWN);
|
|
|
|
styleset_case(MATLAB);
|
|
|
|
styleset_case(NSIS);
|
2011-11-13 00:45:12 +01:00
|
|
|
styleset_case(OBJECTIVEC);
|
2011-11-10 15:35:03 +01:00
|
|
|
styleset_case(PASCAL);
|
|
|
|
styleset_case(PERL);
|
|
|
|
styleset_case(PHP);
|
|
|
|
styleset_case(PO);
|
2013-04-10 20:54:59 +03:00
|
|
|
styleset_case(POWERSHELL);
|
2011-11-10 15:35:03 +01:00
|
|
|
styleset_case(PYTHON);
|
|
|
|
styleset_case(R);
|
|
|
|
styleset_case(RUBY);
|
2013-10-16 17:19:29 -04:00
|
|
|
styleset_case(RUST);
|
2011-11-10 15:35:03 +01:00
|
|
|
styleset_case(SH);
|
|
|
|
styleset_case(SQL);
|
|
|
|
styleset_case(TCL);
|
|
|
|
styleset_case(TXT2TAGS);
|
|
|
|
styleset_case(VHDL);
|
|
|
|
styleset_case(VERILOG);
|
|
|
|
styleset_case(XML);
|
|
|
|
styleset_case(YAML);
|
2009-08-14 11:05:47 +00:00
|
|
|
case GEANY_FILETYPES_NONE:
|
2007-11-02 17:44:05 +00:00
|
|
|
default:
|
2009-10-15 16:54:15 +00:00
|
|
|
styleset_default(sci, ft->id);
|
2007-11-02 17:44:05 +00:00
|
|
|
}
|
2009-11-18 16:48:17 +00:00
|
|
|
/* [lexer_properties] settings */
|
|
|
|
if (style_sets[ft->id].property_keys)
|
|
|
|
{
|
|
|
|
gchar **prop = style_sets[ft->id].property_keys;
|
|
|
|
gchar **val = style_sets[ft->id].property_values;
|
|
|
|
|
|
|
|
while (*prop)
|
|
|
|
{
|
|
|
|
sci_set_property(sci, *prop, *val);
|
|
|
|
prop++;
|
|
|
|
val++;
|
|
|
|
}
|
|
|
|
}
|
2007-11-02 17:44:05 +00:00
|
|
|
}
|
2007-12-16 11:27:59 +00:00
|
|
|
|
|
|
|
|
2010-03-12 18:15:48 +00:00
|
|
|
/** Retrieves a style @a style_id for the filetype @a ft_id.
|
2008-08-26 12:43:46 +00:00
|
|
|
* If the style was not already initialised
|
2007-12-16 11:27:59 +00:00
|
|
|
* (e.g. by by opening a file of this type), it will be initialised. The returned pointer is
|
|
|
|
* owned by Geany and must not be freed.
|
2008-08-26 12:43:46 +00:00
|
|
|
* @param ft_id Filetype ID, e.g. @c GEANY_FILETYPES_DIFF.
|
|
|
|
* @param style_id A Scintilla lexer style, e.g. @c SCE_DIFF_ADDED. See scintilla/include/SciLexer.h.
|
|
|
|
* @return A pointer to the style struct.
|
2010-01-25 15:53:54 +00:00
|
|
|
* @see Scintilla messages @c SCI_STYLEGETFORE, etc, for use with scintilla_send_message(). */
|
2008-08-26 12:43:46 +00:00
|
|
|
const GeanyLexerStyle *highlighting_get_style(gint ft_id, gint style_id)
|
2007-12-16 11:27:59 +00:00
|
|
|
{
|
2011-11-06 01:12:42 +01:00
|
|
|
g_return_val_if_fail(ft_id >= 0 && (guint) ft_id < filetypes_array->len, NULL);
|
|
|
|
g_return_val_if_fail(style_id >= 0, NULL);
|
2007-12-16 11:27:59 +00:00
|
|
|
|
2008-08-26 09:48:18 +00:00
|
|
|
/* ensure filetype loaded */
|
2011-11-06 01:12:42 +01:00
|
|
|
filetypes_load_config((guint) ft_id, FALSE);
|
2007-12-16 11:27:59 +00:00
|
|
|
|
2008-08-26 09:48:18 +00:00
|
|
|
/* TODO: style_id might not be the real array index (Scintilla styles are not always synced
|
|
|
|
* with array indices) */
|
2011-11-06 01:12:42 +01:00
|
|
|
return get_style((guint) ft_id, (guint) style_id);
|
2007-12-16 11:27:59 +00:00
|
|
|
}
|
2009-11-04 12:36:56 +00:00
|
|
|
|
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
static GtkWidget *scheme_tree = NULL;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
SCHEME_MARKUP,
|
|
|
|
SCHEME_FILE,
|
|
|
|
SCHEME_COLUMNS
|
|
|
|
};
|
|
|
|
|
2012-05-27 20:12:31 +02:00
|
|
|
static void on_color_scheme_changed(GtkTreeSelection *treesel, gpointer dummy)
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
2012-03-14 16:56:55 +00:00
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
2009-11-04 12:36:56 +00:00
|
|
|
gchar *fname;
|
|
|
|
gchar *path;
|
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
if (!gtk_tree_selection_get_selected(treesel, &model, &iter))
|
|
|
|
return;
|
|
|
|
gtk_tree_model_get(model, &iter, SCHEME_FILE, &fname, -1);
|
|
|
|
|
2009-11-04 12:36:56 +00:00
|
|
|
/* check if default item */
|
2012-03-14 16:56:55 +00:00
|
|
|
if (!fname)
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
2012-01-25 16:26:16 +00:00
|
|
|
SETPTR(editor_prefs.color_scheme, NULL);
|
2009-11-04 15:06:56 +00:00
|
|
|
filetypes_reload();
|
2009-11-04 12:36:56 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-01-25 16:26:16 +00:00
|
|
|
SETPTR(fname, utils_get_locale_from_utf8(fname));
|
2009-11-04 12:36:56 +00:00
|
|
|
|
|
|
|
/* fname is just the basename from the menu item, so prepend the custom files path */
|
|
|
|
path = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL);
|
|
|
|
if (!g_file_test(path, G_FILE_TEST_EXISTS))
|
|
|
|
{
|
|
|
|
/* try the system path */
|
|
|
|
g_free(path);
|
|
|
|
path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL);
|
|
|
|
}
|
|
|
|
if (g_file_test(path, G_FILE_TEST_EXISTS))
|
|
|
|
{
|
2012-01-25 16:26:16 +00:00
|
|
|
SETPTR(editor_prefs.color_scheme, fname);
|
2009-11-04 12:36:56 +00:00
|
|
|
fname = NULL;
|
2009-11-04 15:06:56 +00:00
|
|
|
filetypes_reload();
|
2009-11-04 12:36:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-25 16:26:16 +00:00
|
|
|
SETPTR(fname, utils_get_utf8_from_locale(fname));
|
2009-11-04 12:36:56 +00:00
|
|
|
ui_set_statusbar(TRUE, _("Could not find file '%s'."), fname);
|
|
|
|
}
|
|
|
|
g_free(path);
|
|
|
|
g_free(fname);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-03 15:18:52 +00:00
|
|
|
static gchar *utils_get_setting_locale_string(GKeyFile *keyfile,
|
|
|
|
const gchar *group, const gchar *key, const gchar *default_value)
|
|
|
|
{
|
|
|
|
gchar *result = g_key_file_get_locale_string(keyfile, group, key, NULL, NULL);
|
|
|
|
|
2013-08-11 14:10:57 +01:00
|
|
|
return FALLBACK(result, g_strdup(default_value));
|
2011-05-03 15:18:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
static void add_color_scheme_item(GtkListStore *store,
|
|
|
|
gchar *name, gchar *desc, const gchar *fn)
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
2012-03-14 16:56:55 +00:00
|
|
|
GtkTreeIter iter;
|
|
|
|
gchar *markup;
|
|
|
|
|
|
|
|
/* reuse parameters */
|
|
|
|
name = g_markup_escape_text(name, -1);
|
|
|
|
desc = g_markup_escape_text(desc, -1);
|
|
|
|
markup = g_strdup_printf("<big><b>%s</b></big>\n%s", name, desc);
|
|
|
|
g_free(name);
|
|
|
|
g_free(desc);
|
|
|
|
|
|
|
|
gtk_list_store_append(store, &iter);
|
|
|
|
gtk_list_store_set(store, &iter, SCHEME_MARKUP, markup,
|
|
|
|
SCHEME_FILE, fn, -1);
|
|
|
|
g_free(markup);
|
|
|
|
|
|
|
|
if (utils_str_equal(fn, editor_prefs.color_scheme))
|
2010-10-20 11:49:50 +00:00
|
|
|
{
|
2012-03-14 16:56:55 +00:00
|
|
|
GtkTreeSelection *treesel =
|
|
|
|
gtk_tree_view_get_selection(GTK_TREE_VIEW(scheme_tree));
|
2011-04-30 16:24:53 +00:00
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
gtk_tree_selection_select_iter(treesel, &iter);
|
|
|
|
}
|
|
|
|
}
|
2011-04-30 16:24:53 +00:00
|
|
|
|
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
static void add_color_scheme_file(GtkListStore *store, const gchar *fname)
|
|
|
|
{
|
|
|
|
GKeyFile *hkeyfile, *skeyfile;
|
|
|
|
gchar *path, *theme_name, *theme_desc;
|
|
|
|
gchar *theme_fn = utils_get_utf8_from_locale(fname);
|
2009-11-04 12:36:56 +00:00
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
path = g_build_filename(app->configdir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL);
|
|
|
|
hkeyfile = utils_key_file_new(path);
|
|
|
|
SETPTR(path, g_build_filename(app->datadir, GEANY_COLORSCHEMES_SUBDIR, fname, NULL));
|
|
|
|
skeyfile = utils_key_file_new(path);
|
2012-01-30 21:32:16 -08:00
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
theme_name = utils_get_setting(locale_string, hkeyfile, skeyfile, "theme_info", "name", theme_fn);
|
|
|
|
theme_desc = utils_get_setting(locale_string, hkeyfile, skeyfile, "theme_info", "description", NULL);
|
|
|
|
add_color_scheme_item(store, theme_name, theme_desc, theme_fn);
|
2009-11-04 12:36:56 +00:00
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
g_free(path);
|
|
|
|
g_free(theme_fn);
|
|
|
|
g_free(theme_name);
|
|
|
|
g_free(theme_desc);
|
|
|
|
g_key_file_free(hkeyfile);
|
|
|
|
g_key_file_free(skeyfile);
|
2009-11-04 12:36:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
static gboolean add_color_scheme_items(GtkListStore *store)
|
2009-11-04 12:36:56 +00:00
|
|
|
{
|
2010-10-20 11:49:50 +00:00
|
|
|
GSList *list, *node;
|
|
|
|
|
2012-03-14 16:56:55 +00:00
|
|
|
add_color_scheme_item(store, _("Default"), _("Default"), NULL);
|
2010-10-20 11:49:50 +00:00
|
|
|
list = utils_get_config_files(GEANY_COLORSCHEMES_SUBDIR);
|
2009-11-04 12:36:56 +00:00
|
|
|
|
|
|
|
foreach_slist(node, list)
|
|
|
|
{
|
|
|
|
gchar *fname = node->data;
|
|
|
|
|
|
|
|
if (g_str_has_suffix(fname, ".conf"))
|
2012-03-14 16:56:55 +00:00
|
|
|
add_color_scheme_file(store, fname);
|
2010-10-20 11:49:50 +00:00
|
|
|
|
2009-11-04 12:36:56 +00:00
|
|
|
g_free(fname);
|
|
|
|
}
|
|
|
|
g_slist_free(list);
|
|
|
|
return list != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 16:12:32 +00:00
|
|
|
static void on_color_scheme_dialog_response(GtkWidget *dialog,
|
|
|
|
gint response, gpointer *dialog_ptr)
|
|
|
|
{
|
|
|
|
*dialog_ptr = NULL;
|
|
|
|
gtk_widget_destroy(dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-27 01:03:18 +02:00
|
|
|
void highlighting_show_color_scheme_dialog(void)
|
2012-03-14 16:56:55 +00:00
|
|
|
{
|
|
|
|
static GtkWidget *dialog = NULL;
|
|
|
|
GtkListStore *store = gtk_list_store_new(SCHEME_COLUMNS,
|
|
|
|
G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
GtkCellRenderer *text_renderer;
|
|
|
|
GtkTreeViewColumn *column;
|
2012-05-27 20:12:31 +02:00
|
|
|
GtkTreeSelection *treesel;
|
2012-03-14 16:56:55 +00:00
|
|
|
GtkWidget *vbox, *swin, *tree;
|
2012-05-29 17:59:37 +01:00
|
|
|
GeanyDocument *doc;
|
|
|
|
|
|
|
|
doc = document_get_current();
|
|
|
|
if (doc && doc->file_type->priv->warn_color_scheme)
|
|
|
|
dialogs_show_msgbox_with_secondary(GTK_MESSAGE_WARNING,
|
|
|
|
_("The current filetype overrides the default style."),
|
|
|
|
_("This may cause color schemes to display incorrectly."));
|
2012-03-14 16:56:55 +00:00
|
|
|
|
|
|
|
scheme_tree = tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
|
|
|
g_object_unref(store);
|
|
|
|
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE);
|
|
|
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE);
|
|
|
|
|
|
|
|
text_renderer = gtk_cell_renderer_text_new();
|
|
|
|
g_object_set(text_renderer, "wrap-mode", PANGO_WRAP_WORD, NULL);
|
|
|
|
column = gtk_tree_view_column_new_with_attributes(
|
|
|
|
NULL, text_renderer, "markup", SCHEME_MARKUP, NULL);
|
|
|
|
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
|
|
|
|
|
|
|
|
add_color_scheme_items(store);
|
|
|
|
|
2012-05-27 20:12:31 +02:00
|
|
|
treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
|
|
|
|
g_signal_connect(treesel, "changed", G_CALLBACK(on_color_scheme_changed), NULL);
|
|
|
|
|
2012-03-15 16:12:32 +00:00
|
|
|
/* old dialog may still be showing */
|
2012-03-14 16:56:55 +00:00
|
|
|
if (dialog)
|
|
|
|
gtk_widget_destroy(dialog);
|
|
|
|
dialog = gtk_dialog_new_with_buttons(_("Color Schemes"),
|
|
|
|
GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
|
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
|
|
|
|
vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
|
|
|
|
gtk_box_set_spacing(GTK_BOX(vbox), 6);
|
|
|
|
gtk_widget_set_name(dialog, "GeanyDialog");
|
|
|
|
gtk_window_set_default_size(GTK_WINDOW(dialog),
|
|
|
|
GEANY_DEFAULT_DIALOG_HEIGHT * 7/4, GEANY_DEFAULT_DIALOG_HEIGHT);
|
|
|
|
|
|
|
|
swin = gtk_scrolled_window_new(NULL, NULL);
|
2012-03-15 15:48:52 +00:00
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_ETCHED_IN);
|
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
|
|
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
2012-03-14 16:56:55 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(swin), tree);
|
2012-09-28 03:27:35 +02:00
|
|
|
gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
|
2012-03-15 16:12:32 +00:00
|
|
|
g_signal_connect(dialog, "response", G_CALLBACK(on_color_scheme_dialog_response), &dialog);
|
2012-03-14 16:56:55 +00:00
|
|
|
gtk_widget_show_all(dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-16 15:07:40 +00:00
|
|
|
/** Checks whether the given style is a string for the given lexer.
|
|
|
|
*
|
|
|
|
* @param lexer Scintilla lexer type (@c SCLEX_*).
|
|
|
|
* @param style Scintilla style (@c SCE_*).
|
|
|
|
*
|
|
|
|
* @return @c TRUE if the style is a string, @c FALSE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean highlighting_is_string_style(gint lexer, gint style)
|
|
|
|
{
|
|
|
|
/* Don't forget STRINGEOL, to prevent completion whilst typing a string with no closing char. */
|
|
|
|
|
|
|
|
switch (lexer)
|
|
|
|
{
|
|
|
|
case SCLEX_CPP:
|
|
|
|
return (style == SCE_C_CHARACTER ||
|
|
|
|
style == SCE_C_STRING ||
|
2011-06-26 21:47:28 +00:00
|
|
|
style == SCE_C_STRINGEOL ||
|
|
|
|
style == SCE_C_STRINGRAW ||
|
|
|
|
style == SCE_C_VERBATIM ||
|
2012-06-26 23:16:45 +02:00
|
|
|
style == SCE_C_TRIPLEVERBATIM ||
|
2014-05-17 22:17:44 +02:00
|
|
|
style == SCE_C_HASHQUOTEDSTRING ||
|
|
|
|
style == SCE_C_ESCAPESEQUENCE);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_PASCAL:
|
|
|
|
return (style == SCE_PAS_CHARACTER ||
|
|
|
|
style == SCE_PAS_STRING ||
|
|
|
|
style == SCE_PAS_STRINGEOL);
|
|
|
|
|
|
|
|
case SCLEX_D:
|
|
|
|
return (style == SCE_D_STRING ||
|
|
|
|
style == SCE_D_STRINGEOL ||
|
|
|
|
style == SCE_D_CHARACTER ||
|
|
|
|
style == SCE_D_STRINGB ||
|
|
|
|
style == SCE_D_STRINGR);
|
|
|
|
|
|
|
|
case SCLEX_PYTHON:
|
|
|
|
return (style == SCE_P_STRING ||
|
|
|
|
style == SCE_P_TRIPLE ||
|
|
|
|
style == SCE_P_TRIPLEDOUBLE ||
|
|
|
|
style == SCE_P_CHARACTER ||
|
|
|
|
style == SCE_P_STRINGEOL);
|
|
|
|
|
|
|
|
case SCLEX_F77:
|
|
|
|
case SCLEX_FORTRAN:
|
|
|
|
return (style == SCE_F_STRING1 ||
|
|
|
|
style == SCE_F_STRING2 ||
|
|
|
|
style == SCE_F_STRINGEOL);
|
|
|
|
|
|
|
|
case SCLEX_PERL:
|
2011-10-19 15:37:34 +02:00
|
|
|
return (style == SCE_PL_STRING ||
|
2010-11-16 15:07:40 +00:00
|
|
|
style == SCE_PL_CHARACTER ||
|
|
|
|
style == SCE_PL_HERE_DELIM ||
|
|
|
|
style == SCE_PL_HERE_Q ||
|
|
|
|
style == SCE_PL_HERE_QQ ||
|
|
|
|
style == SCE_PL_HERE_QX ||
|
|
|
|
style == SCE_PL_POD ||
|
|
|
|
style == SCE_PL_STRING_Q ||
|
|
|
|
style == SCE_PL_STRING_QQ ||
|
|
|
|
style == SCE_PL_STRING_QX ||
|
|
|
|
style == SCE_PL_STRING_QR ||
|
|
|
|
style == SCE_PL_STRING_QW ||
|
2011-10-19 15:37:34 +02:00
|
|
|
style == SCE_PL_POD_VERB ||
|
|
|
|
style == SCE_PL_XLAT
|
|
|
|
/* we don't include any STRING_*_VAR for autocompletion */);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
2012-10-24 23:15:38 +02:00
|
|
|
case SCLEX_PO:
|
|
|
|
return (style == SCE_PO_MSGCTXT_TEXT ||
|
|
|
|
style == SCE_PO_MSGCTXT_TEXT_EOL ||
|
|
|
|
style == SCE_PO_MSGID_TEXT ||
|
|
|
|
style == SCE_PO_MSGID_TEXT_EOL ||
|
|
|
|
style == SCE_PO_MSGSTR_TEXT ||
|
|
|
|
style == SCE_PO_MSGSTR_TEXT_EOL);
|
|
|
|
|
2010-11-16 15:07:40 +00:00
|
|
|
case SCLEX_R:
|
|
|
|
return (style == SCE_R_STRING);
|
|
|
|
|
|
|
|
case SCLEX_RUBY:
|
|
|
|
return (style == SCE_RB_CHARACTER ||
|
|
|
|
style == SCE_RB_STRING ||
|
|
|
|
style == SCE_RB_HERE_DELIM ||
|
|
|
|
style == SCE_RB_HERE_Q ||
|
|
|
|
style == SCE_RB_HERE_QQ ||
|
|
|
|
style == SCE_RB_HERE_QX ||
|
|
|
|
style == SCE_RB_POD);
|
|
|
|
|
|
|
|
case SCLEX_BASH:
|
|
|
|
return (style == SCE_SH_STRING);
|
|
|
|
|
|
|
|
case SCLEX_SQL:
|
|
|
|
return (style == SCE_SQL_STRING);
|
|
|
|
|
|
|
|
case SCLEX_TCL:
|
|
|
|
return (style == SCE_TCL_IN_QUOTE);
|
|
|
|
|
|
|
|
case SCLEX_LUA:
|
|
|
|
return (style == SCE_LUA_LITERALSTRING ||
|
|
|
|
style == SCE_LUA_CHARACTER ||
|
|
|
|
style == SCE_LUA_STRINGEOL ||
|
|
|
|
style == SCE_LUA_STRING);
|
|
|
|
|
|
|
|
case SCLEX_HASKELL:
|
2013-07-21 19:45:28 +03:00
|
|
|
case SCLEX_LITERATEHASKELL:
|
2010-11-16 15:07:40 +00:00
|
|
|
return (style == SCE_HA_CHARACTER ||
|
2013-05-22 03:33:46 +02:00
|
|
|
style == SCE_HA_STRINGEOL ||
|
2010-11-16 15:07:40 +00:00
|
|
|
style == SCE_HA_STRING);
|
|
|
|
|
|
|
|
case SCLEX_FREEBASIC:
|
|
|
|
return (style == SCE_B_STRING ||
|
|
|
|
style == SCE_B_STRINGEOL);
|
|
|
|
|
|
|
|
case SCLEX_OCTAVE:
|
|
|
|
return (style == SCE_MATLAB_STRING ||
|
|
|
|
style == SCE_MATLAB_DOUBLEQUOTESTRING);
|
|
|
|
|
2012-04-13 17:08:49 +01:00
|
|
|
case SCLEX_XML:
|
2010-11-16 15:07:40 +00:00
|
|
|
case SCLEX_HTML:
|
|
|
|
return (
|
|
|
|
style == SCE_HBA_STRING ||
|
|
|
|
style == SCE_HBA_STRINGEOL ||
|
|
|
|
style == SCE_HB_STRING ||
|
|
|
|
style == SCE_HB_STRINGEOL ||
|
|
|
|
style == SCE_H_CDATA ||
|
|
|
|
style == SCE_H_DOUBLESTRING ||
|
|
|
|
style == SCE_HJA_DOUBLESTRING ||
|
|
|
|
style == SCE_HJA_SINGLESTRING ||
|
|
|
|
style == SCE_HJA_STRINGEOL ||
|
|
|
|
style == SCE_HJ_DOUBLESTRING ||
|
|
|
|
style == SCE_HJ_SINGLESTRING ||
|
|
|
|
style == SCE_HJ_STRINGEOL ||
|
|
|
|
style == SCE_HPA_CHARACTER ||
|
|
|
|
style == SCE_HPA_STRING ||
|
|
|
|
style == SCE_HPA_TRIPLE ||
|
|
|
|
style == SCE_HPA_TRIPLEDOUBLE ||
|
|
|
|
style == SCE_HP_CHARACTER ||
|
|
|
|
style == SCE_HPHP_HSTRING || /* HSTRING is a heredoc */
|
|
|
|
style == SCE_HPHP_HSTRING_VARIABLE ||
|
|
|
|
style == SCE_HPHP_SIMPLESTRING ||
|
|
|
|
style == SCE_HP_STRING ||
|
|
|
|
style == SCE_HP_TRIPLE ||
|
|
|
|
style == SCE_HP_TRIPLEDOUBLE ||
|
|
|
|
style == SCE_H_SGML_DOUBLESTRING ||
|
|
|
|
style == SCE_H_SGML_SIMPLESTRING ||
|
|
|
|
style == SCE_H_SINGLESTRING);
|
|
|
|
|
|
|
|
case SCLEX_CMAKE:
|
|
|
|
return (style == SCE_CMAKE_STRINGDQ ||
|
|
|
|
style == SCE_CMAKE_STRINGLQ ||
|
|
|
|
style == SCE_CMAKE_STRINGRQ ||
|
|
|
|
style == SCE_CMAKE_STRINGVAR);
|
|
|
|
|
|
|
|
case SCLEX_NSIS:
|
|
|
|
return (style == SCE_NSIS_STRINGDQ ||
|
|
|
|
style == SCE_NSIS_STRINGLQ ||
|
|
|
|
style == SCE_NSIS_STRINGRQ ||
|
|
|
|
style == SCE_NSIS_STRINGVAR);
|
|
|
|
|
|
|
|
case SCLEX_ADA:
|
|
|
|
return (style == SCE_ADA_CHARACTER ||
|
|
|
|
style == SCE_ADA_STRING ||
|
|
|
|
style == SCE_ADA_CHARACTEREOL ||
|
|
|
|
style == SCE_ADA_STRINGEOL);
|
2012-12-03 15:17:43 +01:00
|
|
|
|
|
|
|
case SCLEX_ABAQUS:
|
|
|
|
return (style == SCE_ABAQUS_STRING);
|
2013-10-16 17:19:29 -04:00
|
|
|
|
|
|
|
case SCLEX_RUST:
|
|
|
|
return (style == SCE_RUST_CHARACTER ||
|
|
|
|
style == SCE_RUST_STRING ||
|
|
|
|
style == SCE_RUST_STRINGR ||
|
|
|
|
style == SCE_RUST_LEXERROR);
|
2010-11-16 15:07:40 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Checks whether the given style is a comment for the given lexer.
|
|
|
|
*
|
|
|
|
* @param lexer Scintilla lexer type (@c SCLEX_*).
|
|
|
|
* @param style Scintilla style (@c SCE_*).
|
|
|
|
*
|
|
|
|
* @return @c TRUE if the style is a comment, @c FALSE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean highlighting_is_comment_style(gint lexer, gint style)
|
|
|
|
{
|
|
|
|
switch (lexer)
|
|
|
|
{
|
2011-01-30 15:03:51 +00:00
|
|
|
case SCLEX_COBOL:
|
2010-11-16 15:07:40 +00:00
|
|
|
case SCLEX_CPP:
|
|
|
|
return (style == SCE_C_COMMENT ||
|
|
|
|
style == SCE_C_COMMENTLINE ||
|
|
|
|
style == SCE_C_COMMENTDOC ||
|
2012-07-14 15:29:10 +02:00
|
|
|
style == SCE_C_PREPROCESSORCOMMENT ||
|
2013-05-22 03:33:46 +02:00
|
|
|
style == SCE_C_PREPROCESSORCOMMENTDOC ||
|
2010-11-16 15:07:40 +00:00
|
|
|
style == SCE_C_COMMENTLINEDOC ||
|
|
|
|
style == SCE_C_COMMENTDOCKEYWORD ||
|
2014-05-17 22:17:44 +02:00
|
|
|
style == SCE_C_COMMENTDOCKEYWORDERROR ||
|
|
|
|
style == SCE_C_TASKMARKER);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_PASCAL:
|
|
|
|
return (style == SCE_PAS_COMMENT ||
|
|
|
|
style == SCE_PAS_COMMENT2 ||
|
|
|
|
style == SCE_PAS_COMMENTLINE);
|
|
|
|
|
|
|
|
case SCLEX_D:
|
|
|
|
return (style == SCE_D_COMMENT ||
|
|
|
|
style == SCE_D_COMMENTLINE ||
|
|
|
|
style == SCE_D_COMMENTDOC ||
|
|
|
|
style == SCE_D_COMMENTNESTED ||
|
|
|
|
style == SCE_D_COMMENTLINEDOC ||
|
|
|
|
style == SCE_D_COMMENTDOCKEYWORD ||
|
|
|
|
style == SCE_D_COMMENTDOCKEYWORDERROR);
|
|
|
|
|
|
|
|
case SCLEX_PYTHON:
|
|
|
|
return (style == SCE_P_COMMENTLINE ||
|
|
|
|
style == SCE_P_COMMENTBLOCK);
|
|
|
|
|
|
|
|
case SCLEX_F77:
|
|
|
|
case SCLEX_FORTRAN:
|
|
|
|
return (style == SCE_F_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_PERL:
|
|
|
|
return (style == SCE_PL_COMMENTLINE);
|
|
|
|
|
|
|
|
case SCLEX_PROPERTIES:
|
|
|
|
return (style == SCE_PROPS_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_PO:
|
2012-10-24 23:15:38 +02:00
|
|
|
return (style == SCE_PO_COMMENT ||
|
|
|
|
style == SCE_PO_PROGRAMMER_COMMENT);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_LATEX:
|
2011-10-19 15:37:34 +02:00
|
|
|
return (style == SCE_L_COMMENT ||
|
|
|
|
style == SCE_L_COMMENT2);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_MAKEFILE:
|
|
|
|
return (style == SCE_MAKE_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_RUBY:
|
|
|
|
return (style == SCE_RB_COMMENTLINE);
|
|
|
|
|
|
|
|
case SCLEX_BASH:
|
|
|
|
return (style == SCE_SH_COMMENTLINE);
|
|
|
|
|
|
|
|
case SCLEX_R:
|
|
|
|
return (style == SCE_R_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_SQL:
|
|
|
|
return (style == SCE_SQL_COMMENT ||
|
|
|
|
style == SCE_SQL_COMMENTLINE ||
|
2011-11-05 23:56:33 +01:00
|
|
|
style == SCE_SQL_COMMENTDOC ||
|
|
|
|
style == SCE_SQL_COMMENTLINEDOC ||
|
|
|
|
style == SCE_SQL_COMMENTDOCKEYWORD ||
|
|
|
|
style == SCE_SQL_COMMENTDOCKEYWORDERROR);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_TCL:
|
|
|
|
return (style == SCE_TCL_COMMENT ||
|
|
|
|
style == SCE_TCL_COMMENTLINE ||
|
|
|
|
style == SCE_TCL_COMMENT_BOX ||
|
|
|
|
style == SCE_TCL_BLOCK_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_OCTAVE:
|
|
|
|
return (style == SCE_MATLAB_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_LUA:
|
|
|
|
return (style == SCE_LUA_COMMENT ||
|
|
|
|
style == SCE_LUA_COMMENTLINE ||
|
|
|
|
style == SCE_LUA_COMMENTDOC);
|
|
|
|
|
|
|
|
case SCLEX_HASKELL:
|
2013-07-21 19:45:28 +03:00
|
|
|
case SCLEX_LITERATEHASKELL:
|
2010-11-16 15:07:40 +00:00
|
|
|
return (style == SCE_HA_COMMENTLINE ||
|
|
|
|
style == SCE_HA_COMMENTBLOCK ||
|
|
|
|
style == SCE_HA_COMMENTBLOCK2 ||
|
2013-05-22 03:33:46 +02:00
|
|
|
style == SCE_HA_COMMENTBLOCK3 ||
|
2013-07-21 19:45:28 +03:00
|
|
|
style == SCE_HA_LITERATE_COMMENT ||
|
|
|
|
style == SCE_HA_LITERATE_CODEDELIM);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_FREEBASIC:
|
2014-04-14 16:36:05 +02:00
|
|
|
return (style == SCE_B_COMMENT ||
|
|
|
|
style == SCE_B_COMMENTBLOCK ||
|
|
|
|
style == SCE_B_DOCLINE ||
|
|
|
|
style == SCE_B_DOCBLOCK ||
|
|
|
|
style == SCE_B_DOCKEYWORD);
|
2010-11-16 15:07:40 +00:00
|
|
|
|
|
|
|
case SCLEX_YAML:
|
|
|
|
return (style == SCE_YAML_COMMENT);
|
|
|
|
|
2012-04-13 17:08:49 +01:00
|
|
|
case SCLEX_XML:
|
2010-11-16 15:07:40 +00:00
|
|
|
case SCLEX_HTML:
|
|
|
|
return (
|
|
|
|
style == SCE_HBA_COMMENTLINE ||
|
|
|
|
style == SCE_HB_COMMENTLINE ||
|
|
|
|
style == SCE_H_COMMENT ||
|
|
|
|
style == SCE_HJA_COMMENT ||
|
|
|
|
style == SCE_HJA_COMMENTDOC ||
|
|
|
|
style == SCE_HJA_COMMENTLINE ||
|
|
|
|
style == SCE_HJ_COMMENT ||
|
|
|
|
style == SCE_HJ_COMMENTDOC ||
|
|
|
|
style == SCE_HJ_COMMENTLINE ||
|
|
|
|
style == SCE_HPA_COMMENTLINE ||
|
|
|
|
style == SCE_HP_COMMENTLINE ||
|
|
|
|
style == SCE_HPHP_COMMENT ||
|
|
|
|
style == SCE_HPHP_COMMENTLINE ||
|
|
|
|
style == SCE_H_SGML_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_CMAKE:
|
|
|
|
return (style == SCE_CMAKE_COMMENT);
|
|
|
|
|
|
|
|
case SCLEX_NSIS:
|
|
|
|
return (style == SCE_NSIS_COMMENT ||
|
|
|
|
style == SCE_NSIS_COMMENTBOX);
|
|
|
|
|
|
|
|
case SCLEX_ADA:
|
|
|
|
return (style == SCE_ADA_COMMENTLINE ||
|
|
|
|
style == SCE_NSIS_COMMENTBOX);
|
2011-11-05 23:56:33 +01:00
|
|
|
|
2012-12-03 15:17:43 +01:00
|
|
|
case SCLEX_ABAQUS:
|
|
|
|
return (style == SCE_ABAQUS_COMMENT ||
|
|
|
|
style == SCE_ABAQUS_COMMENTBLOCK);
|
|
|
|
|
2011-11-05 23:56:33 +01:00
|
|
|
case SCLEX_ASM:
|
|
|
|
return (style == SCE_ASM_COMMENT ||
|
|
|
|
style == SCE_ASM_COMMENTBLOCK ||
|
|
|
|
style == SCE_ASM_COMMENTDIRECTIVE);
|
2013-10-16 17:19:29 -04:00
|
|
|
|
|
|
|
case SCLEX_RUST:
|
|
|
|
return (style == SCE_RUST_COMMENTBLOCK ||
|
|
|
|
style == SCE_RUST_COMMENTLINE ||
|
|
|
|
style == SCE_RUST_COMMENTBLOCKDOC ||
|
|
|
|
style == SCE_RUST_COMMENTLINEDOC);
|
2010-11-16 15:07:40 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Checks whether the given style is normal code (not string, comment, preprocessor, etc).
|
|
|
|
*
|
|
|
|
* @param lexer Scintilla lexer type (@c SCLEX_*).
|
|
|
|
* @param style Scintilla style (@c SCE_*).
|
|
|
|
*
|
|
|
|
* @return @c TRUE if the style is code, @c FALSE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean highlighting_is_code_style(gint lexer, gint style)
|
|
|
|
{
|
|
|
|
switch (lexer)
|
|
|
|
{
|
|
|
|
case SCLEX_CPP:
|
2013-07-21 19:45:28 +03:00
|
|
|
{
|
2010-11-16 15:07:40 +00:00
|
|
|
if (style == SCE_C_PREPROCESSOR)
|
|
|
|
return FALSE;
|
|
|
|
break;
|
2013-07-21 19:45:28 +03:00
|
|
|
}
|
2013-04-27 18:30:17 +02:00
|
|
|
case SCLEX_HASKELL:
|
2013-07-21 19:45:28 +03:00
|
|
|
case SCLEX_LITERATEHASKELL:
|
|
|
|
{
|
2013-04-27 18:30:17 +02:00
|
|
|
if (style == SCE_HA_PREPROCESSOR)
|
|
|
|
return FALSE;
|
|
|
|
break;
|
2013-07-21 19:45:28 +03:00
|
|
|
}
|
2010-11-16 15:07:40 +00:00
|
|
|
}
|
|
|
|
return !(highlighting_is_comment_style(lexer, style) ||
|
|
|
|
highlighting_is_string_style(lexer, style));
|
|
|
|
}
|