[geany/geany] dc6c58: Merge remote-tracking branch 'upstream/master' into bibtex-parser

Mirco Schoenfeld git-noreply at xxxxx
Wed Oct 30 00:12:17 UTC 2019


Branch:      refs/heads/master
Author:      Mirco Schoenfeld <mirco.schoenfeld at tum.de>
Committer:   Mirco Schoenfeld <mirco.schoenfeld at tum.de>
Date:        Wed, 18 Sep 2019 10:53:17 UTC
Commit:      dc6c58c86b41cb9bb10a02c656bf518971264d80
             https://github.com/geany/geany/commit/dc6c58c86b41cb9bb10a02c656bf518971264d80

Log Message:
-----------
Merge remote-tracking branch 'upstream/master' into bibtex-parser


Modified Paths:
--------------
    HACKING
    data/Makefile.am
    data/filedefs/filetypes.CUDA.conf
    data/filedefs/filetypes.Groovy.conf
    data/filedefs/filetypes.Kotlin.conf
    data/filedefs/filetypes.TypeScript.conf
    data/filetype_extensions.conf
    doc/geany.txt
    m4/geany-doxygen.m4
    po/ja.po
    po/ku.po
    src/about.c
    src/build.c
    src/build.h
    src/editor.c
    src/filetypes.c
    src/keybindings.c
    src/keyfile.c
    src/keyfile.h
    src/sciwrappers.c
    src/sciwrappers.h
    src/socket.c
    src/stash.c
    src/stash.h
    src/ui_utils.c

Modified: HACKING
8 lines changed, 6 insertions(+), 2 deletions(-)
===================================================================
@@ -214,11 +214,15 @@ Coding
   to will not be mutated within the function.
 * Don't let variable names shadow outer variables - use gcc's -Wshadow
   option.
-* Use the strictest possible data type where practical. For example
-  for an enumeration, use the actual enum type rather than just a
+* Use the strictest possible data type where practical.
+  Avoid using untyped pointers (e.g. gpointer) where practical.
+  For an enumeration, use the actual enum type rather than just a
   ``gint``, use a ``gchar`` for individual (ASCII/UTF-8) string
   characters rather than ``gint``, and use a ``guint`` for integers
   which cannot be negative rather than ``gint``.
+* Prefer loops to calling ``some_type_foreach()`` with a ``user_data``
+  argument. (Note: Some containers don't support external iteration,
+  e.g. for tree structures, so ``*_foreach`` is fine for those).
 * Do not use G_LIKELY or G_UNLIKELY (except in critical loops). These
   add noise to the code with little real benefit.
 


Modified: data/Makefile.am
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -38,6 +38,7 @@ filetypes = \
 	filedefs/filetypes.glsl \
 	filedefs/filetypes.go \
 	filedefs/filetypes.Graphviz.conf \
+	filedefs/filetypes.Groovy.conf \
 	filedefs/filetypes.haskell \
 	filedefs/filetypes.haxe \
 	filedefs/filetypes.html \
@@ -47,6 +48,7 @@ filetypes = \
 	filedefs/filetypes.latex \
 	filedefs/filetypes.lisp \
 	filedefs/filetypes.lua \
+	filedefs/filetypes.Kotlin.conf \
 	filedefs/filetypes.makefile \
 	filedefs/filetypes.markdown \
 	filedefs/filetypes.matlab \
@@ -67,6 +69,7 @@ filetypes = \
 	filedefs/filetypes.sh \
 	filedefs/filetypes.sql \
 	filedefs/filetypes.Swift.conf \
+	filedefs/filetypes.TypeScript.conf \
 	filedefs/filetypes.tcl \
 	filedefs/filetypes.txt2tags \
 	filedefs/filetypes.vala \


Modified: data/filedefs/filetypes.CUDA.conf
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -52,4 +52,4 @@ context_action_cmd=
 compiler=nvcc -c "%f"
 linker=nvcc -o "%e" "%f"
 run_cmd="./%e"
-
+error_regex=^(.+)\\(([0-9]+)\\)


Modified: data/filedefs/filetypes.Groovy.conf
30 lines changed, 30 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,30 @@
+[styling=C]
+stringeol=string_1
+
+[keywords]
+# http://docs.groovy-lang.org/docs/next/html/documentation/#_keywords
+primary=as assert break case catch class const continue def default do else enum extends false finally for goto if implements import in instanceof interface new null package return super switch this throw throws trait true try while
+# http://groovy-lang.org/objectorientation.html#_primitive_types
+secondary=boolean byte char double float int long short void
+# documentation keywords for javadoc
+doccomment=author deprecated exception param return see serial serialData serialField since throws todo version
+typedefs=
+
+[lexer_properties=C]
+lexer.cpp.allow.dollars=1
+lexer.cpp.triplequoted.strings=1
+
+[settings]
+lexer_filetype=C
+tag_parser=C++
+extension=groovy
+mime_type=text/x-groovy
+
+[build-menu]
+FT_00_LB=_Compile
+FT_00_CM=groovyc "%f"
+FT_00_WD=
+
+EX_00_LB=Execute _Script
+EX_00_CM=groovy "%f"
+EX_00_WD=


Modified: data/filedefs/filetypes.Kotlin.conf
31 lines changed, 31 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,31 @@
+[styling=C]
+
+[keywords]
+# https://kotlinlang.org/docs/reference/keyword-reference.html
+primary=abstract assert break case catch class const continue default do else enum extends final finally for goto if implements import instanceof interface native new package private protected public return static strictfp super switch synchronized this throw throws transient try volatile while true false null as fun in object typealias val var when by constructor delegate dynamic field file get init param property receiver set setparam where actual annotation companion const crossinline data expect external infix inline inner internal lateinit noinline open operator out reified sealed suspend tailrec vararg field it
+# https://kotlinlang.org/docs/reference/basic-types.html
+secondary=Double Float Long Int Short Byte NaN Void
+# documentation keywords for javadoc
+doccomment=author deprecated exception param return see serial serialData serialField since throws todo version
+typedefs=
+
+[lexer_properties=C]
+
+[settings]
+lexer_filetype=C
+tag_parser=C
+extension=kt
+mime_type=text/x-kotlin
+
+[build-menu]
+FT_00_LB=_Compile
+FT_00_CM=kotlinc "%f"
+FT_00_WD=
+
+EX_00_LB=_Execute
+EX_00_CM=kotlin "%eKt"
+EX_00_WD=
+
+EX_01_LB=Execute _Script
+EX_01_CM=kotlinc -script "%f"
+EX_01_WD=


Modified: data/filedefs/filetypes.TypeScript.conf
54 lines changed, 54 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,54 @@
+# based on JavaScript file
+# For complete documentation of this file, please see Geany's main documentation
+[styling=C]
+
+[keywords]
+# all items must be in one line
+primary=break case catch class const continue debugger default delete do else enum export extends extend false finally for function get if import in Infinity instanceof let NaN new null return set static super switch this throw true try typeof undefined var let while with yield prototype async await declare aliased interfaced Alias Interface interface
+secondary=Array Boolean boolean Date Function Math Number number Object String string RegExp EvalError Error RangeError ReferenceError SyntaxError TypeError URIError constructor prototype decodeURI decodeURIComponent encodeURI encodeURIComponent eval isFinite isNaN parseFloat parseInt protected public private keyof void any never readonly as
+
+[lexer_properties=C]
+# partially handles ES6 template strings
+lexer.cpp.backquoted.strings=1
+
+[settings]
+# default extension used when saving files
+extension=ts
+lexer_filetype=C
+
+# MIME type
+mime_type=text/x-typescript
+
+# the following characters are these which a "word" can contains, see documentation
+#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+
+# single comments, like # in this file
+comment_single=//
+# multiline comments
+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=
+
+[indentation]
+#width=4
+# 0 is spaces, 1 is tabs, 2 is tab & spaces
+#type=1
+
+[build-menu]
+# %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)
+#FT_02_LB=_Lint
+#FT_02_CM=jshint "%f"
+#FT_02_WD=
+#error_regex=([^:]+): line ([0-9]+), col ([0-9]+)


Modified: data/filetype_extensions.conf
7 lines changed, 5 insertions(+), 2 deletions(-)
===================================================================
@@ -36,12 +36,14 @@ Genie=*.gs;
 GLSL=*.glsl;*.frag;*.vert;
 Go=*.go;
 Graphviz=*.gv;*.dot;
+Groovy=*.groovy;*.gradle;
 Haskell=*.hs;*.lhs;*.hs-boot;*.lhs-boot;
 Haxe=*.hx;
 HTML=*.htm;*.html;*.shtml;*.hta;*.htd;*.htt;*.cfm;*.tpl;
 Java=*.java;*.jsp;
 Javascript=*.js;
 JSON=*.json;
+Kotlin=*.kt;*.kts;
 LaTeX=*.tex;*.sty;*.idx;*.ltx;*.latex;*.aux;
 Lisp=*.lisp;
 Lua=*.lua;
@@ -67,6 +69,7 @@ SQL=*.sql;
 Swift=*.swift;
 Tcl=*.tcl;*.tk;*.wish;*.exp;
 Txt2tags=*.t2t;
+TypeScript=*.ts;
 Vala=*.vala;*.vapi;
 Verilog=*.v;
 VHDL=*.vhd;*.vhdl;
@@ -77,8 +80,8 @@ None=*;
 
 # Note: restarting is required after editing groups
 [Groups]
-Programming=Arduino;Clojure;CUDA;Cython;Genie;Scala;Swift;
-Script=Graphviz;
+Programming=Arduino;Clojure;CUDA;Cython;Genie;Groovy;Kotlin;Scala;Swift;
+Script=Graphviz;TypeScript;
 Markup=
 Misc=JSON;
 None=


Modified: doc/geany.txt
90 lines changed, 57 insertions(+), 33 deletions(-)
===================================================================
@@ -2539,7 +2539,7 @@ documents before restart.
 ================================  ===========================================  ==========  ===========
 Key                               Description                                  Default     Applies
 ================================  ===========================================  ==========  ===========
-**Editor related**
+**``editor`` group**
 use_gtk_word_boundaries           Whether to look for the end of a word        true        to new
                                   when using word-boundary related                         documents
                                   Scintilla commands (see `Scintilla
@@ -2560,17 +2560,10 @@ indent_hard_tab_width             The size of a tab character. Don't change    8
 editor_ime_interaction            Input method editor (IME)'s candidate        0           to new
                                   window behaviour. May be 0 (windowed) or                 documents
                                   1 (inline)
-**Interface related**
+**``interface`` group**
 show_symbol_list_expanders        Whether to show or hide the small            true        to new
                                   expander icons on the symbol list                        documents
                                   treeview.
-allow_always_save                 Whether files can be saved always, even      false       immediately
-                                  if they don't have any changes.
-                                  By default, the Save button and menu
-                                  item are disabled when a file is
-                                  unchanged. When setting this option to
-                                  true, the Save button and menu item are
-                                  always active and files can be saved.
 compiler_tab_autoscroll           Whether to automatically scroll to the       true        immediately
                                   last line of the output in the Compiler
                                   tab.
@@ -2586,7 +2579,7 @@ msgwin_messages_visible           Whether to show the Messages tab in the      t
                                   Messages Window
 msgwin_scribble_visible           Whether to show the Scribble tab in the      true        immediately
                                   Messages Window
-**VTE related**
+**``terminal`` group**
 send_selection_unsafe             By default, Geany strips any trailing        false       immediately
                                   newline characters from the current
                                   selection before sending it to the terminal
@@ -2604,7 +2597,14 @@ send_cmd_prefix                   String with which prefix the commands sent   E
                                   setting this to a space.  Note that leading
                                   spaces must be escaped using `\s` in the
                                   configuration file.
-**File related**
+**``files`` group**
+allow_always_save                 Whether files can be saved always, even      false       immediately
+                                  if they don't have any changes.
+                                  By default, the Save button and menu
+                                  item are disabled when a file is
+                                  unchanged. When setting this option to
+                                  true, the Save button and menu item are
+                                  always active and files can be saved.
 use_atomic_file_saving            Defines the mode how Geany saves files to    false       immediately
                                   disk. If disabled, Geany directly writes
                                   the content of the document to disk. This
@@ -2636,17 +2636,16 @@ reload_clean_doc_on_file_change   Whether to automatically reload documents    f
                                   on disk.
                                   If unsaved changes exist then the user is
                                   prompted to reload manually.
-**Filetype related**
-extract_filetype_regex            Regex to extract filetype name from file     See below.  immediately
+extract_filetype_regex            Regex to extract filetype name from file     See link    immediately
                                   via capture group one.
-**Search related**
+                                  See `ft_regex`_ for default.
+**``search`` group**
 find_selection_type               See `Find selection`_.                       0           immediately
-**Replace related**
 replace_and_find_by_default       Set ``Replace & Find`` button as default so  true        immediately
                                   it will be activated when the Enter key is
                                   pressed while one of the text fields has
                                   focus.
-**Build Menu related**
+**``build`` group**
 number_ft_menu_items              The maximum number of menu items in the      2           on restart
                                   filetype section of the Build menu.
 number_non_ft_menu_items          The maximum number of menu items in the      3           on restart
@@ -2655,8 +2654,6 @@ number_exec_menu_items            The maximum number of menu items in the      2
                                   execute section of the Build menu.
 ================================  ===========================================  ==========  ===========
 
-The extract_filetype_regex has the default value GEANY_DEFAULT_FILETYPE_REGEX.
-
 Statusbar Templates
 ```````````````````
 
@@ -4300,26 +4297,30 @@ type
     =====   =======================
 
 
+[build-menu] filetype section
+`````````````````````````````
+This supports the same keys as the ``geany.conf`` `[build-menu] section`_.
+
+Example::
+
+    FT_00_LB=_Compile
+    FT_00_CM=gcc -c "%f"
+    FT_00_WD=
+    FT_01_LB=_Build
+    FT_01_CM=gcc -o "%e" "%f"
+    FT_01_WD=
+    EX_00_LB=_Execute
+    EX_00_CM="./%e"
+    EX_00_WD=
+    error_regex=^([^:]+):([0-9]+):
+
 [build_settings] section
 ````````````````````````
-
-As of Geany 0.19 this section is supplemented by the `[build-menu] section`_.
+As of Geany 0.19 this section is for legacy support.
 Values that are set in the [build-menu] section will override those in this section.
 
 error_regex
-    This is a Perl-compatible regular expression (PCRE) to parse a filename
-    (absolute or relative) and line number from the build output.
-    If undefined, Geany will fall back to its default error message parsing.
-
-    Only the first two match groups will be read by Geany. These groups can
-    occur in any order: the match group consisting of only digits will be used
-    as the line number, and the other group as the filename.  In no group
-    consists of only digits, the match will fail.
-
-    *Example:* ``error_regex=^(.+):([0-9]+):[0-9]+``
-
-    This will parse a message such as:
-    ``test.py:7:24: E202 whitespace before ']'``
+    See [build-menu] section for details.
 
 **Build commands**
 
@@ -4737,6 +4738,8 @@ section for details.  All the settings can be configured from the dialogs
 except the execute command in filetype files and filetype definitions in
 the project file, so these are the only ones which need hand editing.
 
+Menu commands
+`````````````
 The build-menu section stores one entry for each setting for each menu item that
 is configured.  The keys for these settings have the format:
 
@@ -4758,6 +4761,25 @@ where:
   - CM for command
   - WD for working directory
 
+See `[build-menu] filetype section`_ for an example.
+
+Error regular expression
+````````````````````````
+error_regex
+    This is a Perl-compatible regular expression (PCRE) to parse a filename
+    (absolute or relative) and line number from the build output.
+    If undefined, Geany will fall back to its default error message parsing.
+
+    Only the first two match groups will be read by Geany. These groups can
+    occur in any order: the match group consisting of only digits will be used
+    as the line number, and the other group as the filename.  In no group
+    consists of only digits, the match will fail.
+
+    *Example:* ``error_regex=^(.+):([0-9]+):[0-9]+``
+
+    This will parse a message such as:
+    ``test.py:7:24: E202 whitespace before ']'``
+
 
 Project file format
 -------------------
@@ -5469,6 +5491,8 @@ GEANY_DEFAULT_FILETYPE_REGEX    The default regex to extract filetypes from   Se
                                 files.
 ==============================  ============================================  ==================
 
+.. _ft_regex:
+
 The GEANY_DEFAULT_FILETYPE_REGEX default value is  -\\*-\\s*([^\\s]+)\\s*-\\*- which finds Emacs filetypes.
 
 The GEANY_DEFAULT_TOOLS_TERMINAL default value on Windows is::


Modified: m4/geany-doxygen.m4
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -5,7 +5,7 @@ AC_DEFUN([GEANY_CHECK_DOXYGEN],
 [
 	AC_ARG_ENABLE([api-docs],
 			[AS_HELP_STRING([--enable-api-docs],
-					[generate API documentation using Doxygen [default=no]])],
+					[generate API documentation using Doxygen [default=auto]])],
 			[geany_with_doxygen="$enableval"],
 			[geany_with_doxygen="auto"])
 


Modified: po/ja.po
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -429,7 +429,7 @@ msgstr "名前"
 
 #: ../data/geany.glade.h:84
 msgid "Appearance"
-msgstr "外観"
+msgstr "出現"
 
 #: ../data/geany.glade.h:85
 msgid "Show documents list"


Modified: po/ku.po
5958 lines changed, 5958 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online


Modified: src/about.c
17 lines changed, 17 insertions(+), 0 deletions(-)
===================================================================
@@ -43,6 +43,7 @@
 #define INFO "<span size=\"larger\" weight=\"bold\">%s</span>"
 #define CODENAME "<span weight=\"bold\">\"" GEANY_CODENAME "\"</span>"
 #define BUILDDATE "<span size=\"smaller\">%s</span>"
+#define RUNTIME BUILDDATE
 #define COPYRIGHT _("Copyright (c) 2005\nThe Geany contributors")
 
 static const gchar *translators[][2] = {
@@ -143,6 +144,7 @@ static GtkWidget *create_dialog(void)
 	GtkWidget *label_info;
 	GtkWidget *codename_label;
 	GtkWidget *builddate_label;
+	GtkWidget *runtime_label;
 	GtkWidget *url_button;
 	GtkWidget *cop_label;
 	GtkWidget *label;
@@ -241,6 +243,21 @@ static GtkWidget *create_dialog(void)
 	gtk_widget_show(builddate_label);
 	gtk_box_pack_start(GTK_BOX(info_box), builddate_label, FALSE, FALSE, 0);
 
+	/* GTK+/GLib runtime version label */
+	runtime_label = gtk_label_new(NULL);
+	gtk_label_set_justify(GTK_LABEL(runtime_label), GTK_JUSTIFY_CENTER);
+	gtk_label_set_selectable(GTK_LABEL(runtime_label), TRUE);
+	gtk_label_set_use_markup(GTK_LABEL(runtime_label), TRUE);
+	g_snprintf(buffer2, sizeof(buffer2),
+		_("Using GTK+ v%u.%u.%u and GLib v%u.%u.%u runtime libraries"),
+		gtk_major_version, gtk_minor_version, gtk_micro_version,
+		glib_major_version, glib_minor_version, glib_micro_version);
+	g_snprintf(buffer, sizeof(buffer), RUNTIME, buffer2);
+	gtk_label_set_markup(GTK_LABEL(runtime_label), buffer);
+	gtk_misc_set_padding(GTK_MISC(runtime_label), 2, 2);
+	gtk_widget_show(runtime_label);
+	gtk_box_pack_start(GTK_BOX(info_box), runtime_label, FALSE, FALSE, 0);
+
 	box = gtk_hbutton_box_new();
 	url_button = gtk_button_new();
 	gtk_button_set_relief(GTK_BUTTON(url_button), GTK_RELIEF_NONE);


Modified: src/build.c
190 lines changed, 145 insertions(+), 45 deletions(-)
===================================================================
@@ -81,6 +81,55 @@ static RunInfo *run_info;
 static const gchar RUN_SCRIPT_CMD[] = "geany_run_script_XXXXXX.sh";
 #endif
 
+/* Order is important (see GBO_TO_GBG, GBO_TO_CMD below) */
+/* * Geany Known Build Commands.
+ * These commands are named after their default use.
+ * Only these commands can currently have keybindings.
+ **/
+typedef enum
+{
+	GEANY_GBO_COMPILE,		/* *< default compile file */
+	GEANY_GBO_BUILD,		/* *< default build file */
+	GEANY_GBO_MAKE_ALL,		/* *< default make */
+	GEANY_GBO_CUSTOM,		/* *< default make user specified target */
+	GEANY_GBO_MAKE_OBJECT,	/* *< default make object, make %e.o */
+	GEANY_GBO_EXEC,			/* *< default execute ./%e */
+	GEANY_GBO_COUNT			/* *< count of how many */
+} GeanyBuildType;
+
+/* * Convert @c GeanyBuildType to @c GeanyBuildGroup.
+ *
+ * This macro converts @c GeanyBuildType enum values (the "known" commands)
+ * to the group they are part of.
+ *
+ * @param gbo the @c GeanyBuildType value.
+ *
+ * @return the @c GeanyBuildGroup group that @a gbo is in.
+ *
+ * Note this is a macro so that it can be used in static initialisers.
+ **/
+#define GBO_TO_GBG(gbo) \
+	((gbo) > GEANY_GBO_EXEC ? GEANY_GBG_COUNT : \
+		((gbo) >= GEANY_GBO_EXEC ? GEANY_GBG_EXEC : \
+			 ((gbo) >= GEANY_GBO_MAKE_ALL ? GEANY_GBG_NON_FT : GEANY_GBG_FT)))
+
+/* * Convert @c GeanyBuildType to command index.
+ *
+ * This macro converts @c GeanyBuildType enum values (the "known" commands)
+ * to the index within the group.
+ *
+ * @param gbo the @c GeanyBuildType value.
+ *
+ * @return the index of the @a gbo command in its group.
+ *
+ * Note this is a macro so that it can be used in static initialisers.
+ **/
+#define GBO_TO_CMD(gbo) \
+	((gbo) >= GEANY_GBO_COUNT ? (gbo) - GEANY_GBO_COUNT : \
+		((gbo) >= GEANY_GBO_EXEC ? (gbo) - GEANY_GBO_EXEC : \
+			 ((gbo) >= GEANY_GBO_MAKE_ALL ? \
+				(gbo) - GEANY_GBO_MAKE_ALL : (gbo))))
+
 /* pack group (<8) and command (<32) into a user_data pointer */
 #define GRP_CMD_TO_POINTER(grp, cmd) GUINT_TO_POINTER((((grp)&7) << 5) | ((cmd)&0x1f))
 #define GBO_TO_POINTER(gbo) (GRP_CMD_TO_POINTER(GBO_TO_GBG(gbo), GBO_TO_CMD(gbo)))
@@ -2291,6 +2340,22 @@ static void build_load_menu_grp(GKeyFile *config, GeanyBuildCommand **dst, gint
 }
 
 
+/* set GeanyBuildCommand if it doesn't already exist and there is a command */
+static void assign_cmd(GeanyBuildCommand *type, guint id,
+		const gchar *label, gchar *value)
+{
+	if (!EMPTY(value) && ! type[GBO_TO_CMD(id)].exists)
+	{
+		type[GBO_TO_CMD(id)].exists = TRUE;
+		SETPTR(type[GBO_TO_CMD(id)].label, g_strdup(label));
+		SETPTR(type[GBO_TO_CMD(id)].command, value);
+		SETPTR(type[GBO_TO_CMD(id)].working_dir, NULL);
+		type[GBO_TO_CMD(id)].old = TRUE;
+	}
+	else
+		g_free(value);
+}
+
 /* for the specified source load new format build menu items or try to make some sense of
  * old format setings, not done perfectly but better than ignoring them */
 void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
@@ -2367,21 +2432,6 @@ void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
 
 	/* load old [build_settings] values if there is no value defined by [build-menu] */
 
-	/* set GeanyBuildCommand if it doesn't already exist and there is a command */
-/* TODO: rewrite as function */
-#define ASSIGNIF(type, id, string, value)								\
-	do {																\
-		gchar *ASSIGNF__value = (value);								\
-		if (!EMPTY(ASSIGNF__value) && ! type[GBO_TO_CMD(id)].exists) {	\
-			type[GBO_TO_CMD(id)].exists = TRUE;							\
-			SETPTR(type[GBO_TO_CMD(id)].label, g_strdup(string));		\
-			SETPTR(type[GBO_TO_CMD(id)].command, ASSIGNF__value);		\
-			SETPTR(type[GBO_TO_CMD(id)].working_dir, NULL);				\
-			type[GBO_TO_CMD(id)].old = TRUE;							\
-		} else															\
-			g_free(ASSIGNF__value);										\
-	} while (0)
-
 	switch (src)
 	{
 		case GEANY_BCS_FT:
@@ -2391,21 +2441,21 @@ void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
 			{
 				if (ft->priv->filecmds == NULL)
 					ft->priv->filecmds = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_FT]);
-				ASSIGNIF(ft->priv->filecmds, GEANY_GBO_COMPILE, _("_Compile"), value);
+				assign_cmd(ft->priv->filecmds, GEANY_GBO_COMPILE, _("_Compile"), value);
 			}
 			value = g_key_file_get_string(config, "build_settings", "linker", NULL);
 			if (value != NULL)
 			{
 				if (ft->priv->filecmds == NULL)
 					ft->priv->filecmds = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_FT]);
-				ASSIGNIF(ft->priv->filecmds, GEANY_GBO_BUILD, _("_Build"), value);
+				assign_cmd(ft->priv->filecmds, GEANY_GBO_BUILD, _("_Build"), value);
 			}
 			value = g_key_file_get_string(config, "build_settings", "run_cmd", NULL);
 			if (value != NULL)
 			{
 				if (ft->priv->execcmds == NULL)
 					ft->priv->execcmds = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_EXEC]);
-				ASSIGNIF(ft->priv->execcmds, GEANY_GBO_EXEC, _("_Execute"), value);
+				assign_cmd(ft->priv->execcmds, GEANY_GBO_EXEC, _("_Execute"), value);
 			}
 			if (ft->error_regex_string == NULL)
 				ft->error_regex_string = g_key_file_get_string(config, "build_settings", "error_regex", NULL);
@@ -2450,11 +2500,11 @@ void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
 			{
 				if (non_ft_pref == NULL)
 					non_ft_pref = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_NON_FT]);
-				ASSIGNIF(non_ft_pref, GEANY_GBO_CUSTOM, _("Make Custom _Target..."),
+				assign_cmd(non_ft_pref, GEANY_GBO_CUSTOM, _("Make Custom _Target..."),
 						g_strdup_printf("%s ", value));
-				ASSIGNIF(non_ft_pref, GEANY_GBO_MAKE_OBJECT, _("Make _Object"),
+				assign_cmd(non_ft_pref, GEANY_GBO_MAKE_OBJECT, _("Make _Object"),
 						g_strdup_printf("%s %%e.o",value));
-				ASSIGNIF(non_ft_pref, GEANY_GBO_MAKE_ALL, _("_Make"), value);
+				assign_cmd(non_ft_pref, GEANY_GBO_MAKE_ALL, _("_Make"), value);
 			}
 			break;
 		default:
@@ -2509,41 +2559,29 @@ static guint build_save_menu_grp(GKeyFile *config, GeanyBuildCommand *src, gint
 }
 
 
-typedef struct ForEachData
+static gboolean save_project_filetype(GeanyFiletype *ft, GKeyFile *config)
 {
-	GKeyFile *config;
-	GPtrArray *ft_names;
-} ForEachData;
-
-
-static void foreach_project_filetype(gpointer data, gpointer user_data)
-{
-	GeanyFiletype *ft = data;
-	ForEachData *d = user_data;
 	guint i = 0;
 	gchar *regkey = g_strdup_printf("%serror_regex", ft->name);
 
-	i += build_save_menu_grp(d->config, ft->priv->projfilecmds, GEANY_GBG_FT, ft->name);
-	i += build_save_menu_grp(d->config, ft->priv->projexeccmds, GEANY_GBG_EXEC, ft->name);
+	i += build_save_menu_grp(config, ft->priv->projfilecmds, GEANY_GBG_FT, ft->name);
+	i += build_save_menu_grp(config, ft->priv->projexeccmds, GEANY_GBG_EXEC, ft->name);
 	if (!EMPTY(ft->priv->projerror_regex_string))
 	{
-		g_key_file_set_string(d->config, build_grp_name, regkey, ft->priv->projerror_regex_string);
+		g_key_file_set_string(config, build_grp_name, regkey, ft->priv->projerror_regex_string);
 		i++;
 	}
 	else
-		g_key_file_remove_key(d->config, build_grp_name, regkey, NULL);
+		g_key_file_remove_key(config, build_grp_name, regkey, NULL);
 	g_free(regkey);
-	if (i > 0)
-		g_ptr_array_add(d->ft_names, ft->name);
+	return (i > 0);
 }
 
-
 /* TODO: untyped ptr is too ugly (also for build_load_menu) */
 void build_save_menu(GKeyFile *config, gpointer ptr, GeanyBuildSource src)
 {
 	GeanyFiletype *ft;
 	GeanyProject *pj;
-	ForEachData data;
 
 	switch (src)
 	{
@@ -2576,15 +2614,21 @@ void build_save_menu(GKeyFile *config, gpointer ptr, GeanyBuildSource src)
 				g_key_file_remove_key(config, build_grp_name, "error_regex", NULL);
 			if (pj->priv->build_filetypes_list != NULL)
 			{
-				data.config = config;
-				data.ft_names = g_ptr_array_new();
-				g_ptr_array_foreach(pj->priv->build_filetypes_list, foreach_project_filetype, (gpointer)(&data));
-				if (data.ft_names->pdata != NULL)
+				GPtrArray *ft_names = g_ptr_array_new();
+				const GPtrArray *build_fts = pj->priv->build_filetypes_list;
+				
+				for (guint i = 0; i < build_fts->len; i++)
+				{
+					ft = build_fts->pdata[i];
+					if (save_project_filetype(ft, config))
+						g_ptr_array_add(ft_names, ft->name);
+				}
+				if (ft_names->pdata != NULL)
 					g_key_file_set_string_list(config, build_grp_name, "filetypes",
-								(const gchar**)(data.ft_names->pdata), data.ft_names->len);
+						(const gchar**)ft_names->pdata, ft_names->len);
 				else
 					g_key_file_remove_key(config, build_grp_name, "filetypes", NULL);
-				g_ptr_array_free(data.ft_names, TRUE);
+				g_ptr_array_free(ft_names, TRUE);
 			}
 			break;
 		default: /* defaults and GEANY_BCS_FT can't save */
@@ -2729,3 +2773,59 @@ void build_init(void)
 	/* set the submenu to the toolbar item */
 	geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION(widgets.build_action), toolmenu);
 }
+
+
+gboolean build_keybinding(guint key_id)
+{
+	GtkWidget *item;
+	BuildMenuItems *menu_items;
+	GeanyDocument *doc = document_get_current();
+
+	if (doc == NULL)
+		return TRUE;
+
+	if (!gtk_widget_is_sensitive(ui_lookup_widget(main_widgets.window, "menu_build1")))
+		return TRUE;
+
+	menu_items = build_get_menu_items(doc->file_type->id);
+	/* TODO make it a table??*/
+	switch (key_id)
+	{
+		case GEANY_KEYS_BUILD_COMPILE:
+			item = menu_items->menu_item[GEANY_GBG_FT][GBO_TO_CMD(GEANY_GBO_COMPILE)];
+			break;
+		case GEANY_KEYS_BUILD_LINK:
+			item = menu_items->menu_item[GEANY_GBG_FT][GBO_TO_CMD(GEANY_GBO_BUILD)];
+			break;
+		case GEANY_KEYS_BUILD_MAKE:
+			item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_MAKE_ALL)];
+			break;
+		case GEANY_KEYS_BUILD_MAKEOWNTARGET:
+			item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_CUSTOM)];
+			break;
+		case GEANY_KEYS_BUILD_MAKEOBJECT:
+			item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_MAKE_OBJECT)];
+			break;
+		case GEANY_KEYS_BUILD_NEXTERROR:
+			item = menu_items->menu_item[GBG_FIXED][GBF_NEXT_ERROR];
+			break;
+		case GEANY_KEYS_BUILD_PREVIOUSERROR:
+			item = menu_items->menu_item[GBG_FIXED][GBF_PREV_ERROR];
+			break;
+		case GEANY_KEYS_BUILD_RUN:
+			item = menu_items->menu_item[GEANY_GBG_EXEC][GBO_TO_CMD(GEANY_GBO_EXEC)];
+			break;
+		case GEANY_KEYS_BUILD_OPTIONS:
+			item = menu_items->menu_item[GBG_FIXED][GBF_COMMANDS];
+			break;
+		default:
+			item = NULL;
+	}
+	/* Note: For Build menu items it's OK (at the moment) to assume they are in the correct
+	 * sensitive state, but some other menus don't update the sensitive status until
+	 * they are redrawn. */
+	if (item && gtk_widget_is_sensitive(item))
+		gtk_menu_item_activate(GTK_MENU_ITEM(item));
+	return TRUE;
+}
+


Modified: src/build.h
46 lines changed, 2 insertions(+), 44 deletions(-)
===================================================================
@@ -75,53 +75,9 @@ guint build_get_group_count(const GeanyBuildGroup grp);
 
 #ifdef GEANY_PRIVATE
 
-/* Order is important (see GBO_TO_GBG, GBO_TO_CMD below) */
-/* * Geany Known Build Commands.
- * These commands are named after their default use.
- * Only these commands can currently have keybindings.
- **/
-typedef enum
-{
-	GEANY_GBO_COMPILE,		/* *< default compile file */
-	GEANY_GBO_BUILD,		/* *< default build file */
-	GEANY_GBO_MAKE_ALL,		/* *< default make */
-	GEANY_GBO_CUSTOM,		/* *< default make user specified target */
-	GEANY_GBO_MAKE_OBJECT,	/* *< default make object, make %e.o */
-	GEANY_GBO_EXEC,			/* *< default execute ./%e */
-	GEANY_GBO_COUNT			/* *< count of how many */
-} GeanyBuildType;
-
 /* include the fixed widgets in an array indexed by groups */
 #define GBG_FIXED GEANY_GBG_COUNT
 
-/* * Convert @c GeanyBuildType to @c GeanyBuildGroup.
- *
- * This macro converts @c GeanyBuildType enum values (the "known" commands)
- * to the group they are part of.
- *
- * @param gbo the @c GeanyBuildType value.
- *
- * @return the @c GeanyBuildGroup group that @a gbo is in.
- *
- * Note this is a macro so that it can be used in static initialisers.
- **/
-#define GBO_TO_GBG(gbo) ((gbo)>GEANY_GBO_EXEC?GEANY_GBG_COUNT:((gbo)>=GEANY_GBO_EXEC?GEANY_GBG_EXEC: \
-						 ((gbo) >= GEANY_GBO_MAKE_ALL ? GEANY_GBG_NON_FT : GEANY_GBG_FT)))
-
-/* * Convert @c GeanyBuildType to command index.
- *
- * This macro converts @c GeanyBuildType enum values (the "known" commands)
- * to the index within the group.
- *
- * @param gbo the @c GeanyBuildType value.
- *
- * @return the index of the @a gbo command in its group.
- *
- * Note this is a macro so that it can be used in static initialisers.
- **/
-#define GBO_TO_CMD(gbo) ((gbo)>=GEANY_GBO_COUNT?(gbo)-GEANY_GBO_COUNT:((gbo)>=GEANY_GBO_EXEC?(gbo)-GEANY_GBO_EXEC: \
-						 ((gbo) >= GEANY_GBO_MAKE_ALL ? (gbo)-GEANY_GBO_MAKE_ALL : (gbo))))
-
 enum GeanyBuildFixedMenuItems
 {
 	GBF_NEXT_ERROR,
@@ -211,6 +167,8 @@ void build_set_group_count(GeanyBuildGroup grp, gint count);
 
 gchar **build_get_regex(GeanyBuildGroup grp, GeanyFiletype *ft, guint *from);
 
+gboolean build_keybinding(guint key_id);
+
 #endif /* GEANY_PRIVATE */
 
 G_END_DECLS


Modified: src/editor.c
7 lines changed, 4 insertions(+), 3 deletions(-)
===================================================================
@@ -4591,19 +4591,20 @@ void editor_ensure_final_newline(GeanyEditor *editor)
 
 void editor_set_font(GeanyEditor *editor, const gchar *font)
 {
-	gint style, size;
+	gint style;
 	gchar *font_name;
 	PangoFontDescription *pfd;
+	gdouble size;
 
 	g_return_if_fail(editor);
 
 	pfd = pango_font_description_from_string(font);
-	size = pango_font_description_get_size(pfd) / PANGO_SCALE;
+	size = pango_font_description_get_size(pfd) / (gdouble) PANGO_SCALE;
 	font_name = g_strdup_printf("!%s", pango_font_description_get_family(pfd));
 	pango_font_description_free(pfd);
 
 	for (style = 0; style <= STYLE_MAX; style++)
-		sci_set_font(editor->sci, style, font_name, size);
+		sci_set_font_fractional(editor->sci, style, font_name, size);
 
 	g_free(font_name);
 


Modified: src/filetypes.c
50 lines changed, 19 insertions(+), 31 deletions(-)
===================================================================
@@ -464,27 +464,21 @@ void filetypes_init(void)
 }
 
 
-static gboolean match_basename(const GeanyFiletype *ft, const gchar *base_filename)
+static guint match_basename(const GeanyFiletype *ft, const gchar *base_filename)
 {
-	gint j;
-	gboolean ret = FALSE;
-
 	if (G_UNLIKELY(ft->id == GEANY_FILETYPES_NONE))
-		return FALSE;
+		return 0;
 
-	for (j = 0; ft->pattern[j] != NULL; j++)
+	for (guint j = 0; ft->pattern[j] != NULL; j++)
 	{
-		GPatternSpec *pattern = g_pattern_spec_new(ft->pattern[j]);
-
-		if (g_pattern_match_string(pattern, base_filename))
+		gchar *pat = ft->pattern[j];
+		
+		if (g_pattern_match_simple(pat, base_filename))
 		{
-			ret = TRUE;
-			g_pattern_spec_free(pattern);
-			break;
+			return strlen(pat);
 		}
-		g_pattern_spec_free(pattern);
 	}
-	return ret;
+	return 0;
 }
 
 
@@ -522,7 +516,7 @@ GeanyFiletype *filetypes_detect_from_extension(const gchar *utf8_filename)
 {
 	gchar *base_filename;
 	GeanyFiletype *ft;
-	guint i;
+	guint plen = 0;
 
 	ft = detect_filetype_conf_file(utf8_filename);
 	if (ft)
@@ -535,25 +529,19 @@ GeanyFiletype *filetypes_detect_from_extension(const gchar *utf8_filename)
 	SETPTR(base_filename, g_utf8_strdown(base_filename, -1));
 #endif
 
-	for (i = 0; i < filetypes_array->len; i++)
+	for (guint i = 0; i < filetypes_array->len; i++)
 	{
-		if (match_basename(filetypes[i], base_filename))
-		{
+		guint mlen = match_basename(filetypes[i], base_filename);
+		
+		if (mlen > plen)
+		{	// longest pattern match wins
+			plen = mlen;
 			ft = filetypes[i];
-			break;
 		}
-	}
-	// check if user config overrides found ft
-	if (ft && !ft->priv->user_extensions)
-	{
-		for (i++; i < filetypes_array->len; i++)
-		{
-			if (filetypes[i]->priv->user_extensions &&
-				match_basename(filetypes[i], base_filename))
-			{
-				ft = filetypes[i];
-				break;
-			}
+		else if (mlen == plen && ft && !ft->priv->user_extensions &&
+			filetypes[i]->priv->user_extensions)
+		{	// user config overrides system if pattern len same
+			ft = filetypes[i];
 		}
 	}
 	if (ft == NULL)


Modified: src/keybindings.c
58 lines changed, 1 insertions(+), 57 deletions(-)
===================================================================
@@ -89,7 +89,6 @@ static gboolean cb_func_search_action(guint key_id);
 static gboolean cb_func_goto_action(guint key_id);
 static gboolean cb_func_switch_action(guint key_id);
 static gboolean cb_func_clipboard_action(guint key_id);
-static gboolean cb_func_build_action(guint key_id);
 static gboolean cb_func_document_action(guint key_id);
 static gboolean cb_func_view_action(guint key_id);
 
@@ -320,7 +319,7 @@ static void init_default_kb(void)
 	ADD_KB_GROUP(GEANY_KEY_GROUP_VIEW, _("View"), cb_func_view_action);
 	ADD_KB_GROUP(GEANY_KEY_GROUP_DOCUMENT, _("Document"), cb_func_document_action);
 	ADD_KB_GROUP(GEANY_KEY_GROUP_PROJECT, _("Project"), cb_func_project_action);
-	ADD_KB_GROUP(GEANY_KEY_GROUP_BUILD, _("Build"), cb_func_build_action);
+	ADD_KB_GROUP(GEANY_KEY_GROUP_BUILD, _("Build"), build_keybinding);
 	ADD_KB_GROUP(GEANY_KEY_GROUP_TOOLS, _("Tools"), NULL);
 	ADD_KB_GROUP(GEANY_KEY_GROUP_HELP, _("Help"), NULL);
 	ADD_KB_GROUP(GEANY_KEY_GROUP_FOCUS, _("Focus"), cb_func_switch_action);
@@ -1653,61 +1652,6 @@ static void cb_func_menu_messagewindow(G_GNUC_UNUSED guint key_id)
 }
 
 
-static gboolean cb_func_build_action(guint key_id)
-{
-	GtkWidget *item;
-	BuildMenuItems *menu_items;
-	GeanyDocument *doc = document_get_current();
-
-	if (doc == NULL)
-		return TRUE;
-
-	if (!gtk_widget_is_sensitive(ui_lookup_widget(main_widgets.window, "menu_build1")))
-		return TRUE;
-
-	menu_items = build_get_menu_items(doc->file_type->id);
-	/* TODO make it a table??*/
-	switch (key_id)
-	{
-		case GEANY_KEYS_BUILD_COMPILE:
-			item = menu_items->menu_item[GEANY_GBG_FT][GBO_TO_CMD(GEANY_GBO_COMPILE)];
-			break;
-		case GEANY_KEYS_BUILD_LINK:
-			item = menu_items->menu_item[GEANY_GBG_FT][GBO_TO_CMD(GEANY_GBO_BUILD)];
-			break;
-		case GEANY_KEYS_BUILD_MAKE:
-			item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_MAKE_ALL)];
-			break;
-		case GEANY_KEYS_BUILD_MAKEOWNTARGET:
-			item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_CUSTOM)];
-			break;
-		case GEANY_KEYS_BUILD_MAKEOBJECT:
-			item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_MAKE_OBJECT)];
-			break;
-		case GEANY_KEYS_BUILD_NEXTERROR:
-			item = menu_items->menu_item[GBG_FIXED][GBF_NEXT_ERROR];
-			break;
-		case GEANY_KEYS_BUILD_PREVIOUSERROR:
-			item = menu_items->menu_item[GBG_FIXED][GBF_PREV_ERROR];
-			break;
-		case GEANY_KEYS_BUILD_RUN:
-			item = menu_items->menu_item[GEANY_GBG_EXEC][GBO_TO_CMD(GEANY_GBO_EXEC)];
-			break;
-		case GEANY_KEYS_BUILD_OPTIONS:
-			item = menu_items->menu_item[GBG_FIXED][GBF_COMMANDS];
-			break;
-		default:
-			item = NULL;
-	}
-	/* Note: For Build menu items it's OK (at the moment) to assume they are in the correct
-	 * sensitive state, but some other menus don't update the sensitive status until
-	 * they are redrawn. */
-	if (item && gtk_widget_is_sensitive(item))
-		gtk_menu_item_activate(GTK_MENU_ITEM(item));
-	return TRUE;
-}
-
-
 static gboolean read_current_word(GeanyDocument *doc, gboolean sci_word)
 {
 	g_return_val_if_fail(DOC_VALID(doc), FALSE);


Modified: src/keyfile.c
39 lines changed, 26 insertions(+), 13 deletions(-)
===================================================================
@@ -132,11 +132,13 @@ void configuration_add_pref_group(struct StashGroup *group, gboolean for_prefs_d
 }
 
 
-/* The group will be free'd on quitting. */
-void configuration_add_various_pref_group(struct StashGroup *group)
+/* The group will be free'd on quitting.
+ * prefix can be NULL to use group name */
+void configuration_add_various_pref_group(struct StashGroup *group,
+	const gchar *prefix)
 {
 	configuration_add_pref_group(group, TRUE);
-	stash_group_set_various(group, TRUE);
+	stash_group_set_various(group, TRUE, prefix);
 }
 
 
@@ -225,7 +227,7 @@ static void init_pref_groups(void)
 
 	/* various geany prefs */
 	group = stash_group_new(PACKAGE);
-	configuration_add_various_pref_group(group);
+	configuration_add_various_pref_group(group, "editor");
 
 	stash_group_add_boolean(group, &editor_prefs.show_scrollbars,
 		"show_editor_scrollbars", TRUE);
@@ -235,6 +237,15 @@ static void init_pref_groups(void)
 		"use_gtk_word_boundaries", TRUE);
 	stash_group_add_boolean(group, &editor_prefs.complete_snippets_whilst_editing,
 		"complete_snippets_whilst_editing", FALSE);
+	/* for backwards-compatibility */
+	stash_group_add_integer(group, &editor_prefs.indentation->hard_tab_width,
+		"indent_hard_tab_width", 8);
+	stash_group_add_integer(group, &editor_prefs.ime_interaction,
+		"editor_ime_interaction", SC_IME_WINDOWED);
+
+	group = stash_group_new(PACKAGE);
+	configuration_add_various_pref_group(group, "files");
+
 	stash_group_add_boolean(group, &file_prefs.use_safe_file_saving,
 		atomic_file_saving_key, FALSE);
 	stash_group_add_boolean(group, &file_prefs.gio_unsafe_save_backup,
@@ -247,23 +258,25 @@ static void init_pref_groups(void)
 		"show_keep_edit_history_on_reload_msg", TRUE);
 	stash_group_add_boolean(group, &file_prefs.reload_clean_doc_on_file_change,
 		"reload_clean_doc_on_file_change", FALSE);
-	/* for backwards-compatibility */
-	stash_group_add_integer(group, &editor_prefs.indentation->hard_tab_width,
-		"indent_hard_tab_width", 8);
-	stash_group_add_integer(group, (gint*)&search_prefs.find_selection_type,
-		"find_selection_type", GEANY_FIND_SEL_CURRENT_WORD);
 	stash_group_add_string(group, &file_prefs.extract_filetype_regex,
 		"extract_filetype_regex", GEANY_DEFAULT_FILETYPE_REGEX);
+	stash_group_add_boolean(group, &ui_prefs.allow_always_save,
+		"allow_always_save", FALSE);
+
+	group = stash_group_new(PACKAGE);
+	configuration_add_various_pref_group(group, "search");
+
+	stash_group_add_integer(group, (gint*)&search_prefs.find_selection_type,
+		"find_selection_type", GEANY_FIND_SEL_CURRENT_WORD);
 	stash_group_add_boolean(group, &search_prefs.replace_and_find_by_default,
 		"replace_and_find_by_default", TRUE);
-	stash_group_add_integer(group, &editor_prefs.ime_interaction,
-		"editor_ime_interaction", SC_IME_WINDOWED);
 
 	/* Note: Interface-related various prefs are in ui_init_prefs() */
 
 	/* various build-menu prefs */
+	// Warning: don't move PACKAGE group name items here 
 	group = stash_group_new("build-menu");
-	configuration_add_various_pref_group(group);
+	configuration_add_various_pref_group(group, "build");
 
 	stash_group_add_integer(group, &build_menu_prefs.number_ft_menu_items,
 		"number_ft_menu_items", 0);
@@ -903,7 +916,7 @@ static void load_dialog_prefs(GKeyFile *config)
 		 * this can't be done in init_pref_groups() because we need to know the value of
 		 * vte_info.load_vte, and `vc` to be initialized */
 		group = stash_group_new("VTE");
-		configuration_add_various_pref_group(group);
+		configuration_add_various_pref_group(group, "terminal");
 
 		stash_group_add_string(group, &vc->send_cmd_prefix, "send_cmd_prefix", "");
 		stash_group_add_boolean(group, &vc->send_selection_unsafe, "send_selection_unsafe", FALSE);


Modified: src/keyfile.h
3 lines changed, 2 insertions(+), 1 deletions(-)
===================================================================
@@ -37,7 +37,8 @@ struct StashGroup;
 
 void configuration_add_pref_group(struct StashGroup *group, gboolean for_prefs_dialog);
 
-void configuration_add_various_pref_group(struct StashGroup *group);
+void configuration_add_various_pref_group(struct StashGroup *group,
+	const gchar *prefix);
 
 void configuration_save(void);
 


Modified: src/sciwrappers.c
15 lines changed, 13 insertions(+), 2 deletions(-)
===================================================================
@@ -939,6 +939,18 @@ gint sci_find_text(ScintillaObject *sci, gint flags, struct Sci_TextToFind *ttf)
 	return (gint) SSM(sci, SCI_FINDTEXT, (uptr_t) flags, (sptr_t) ttf);
 }
 
+/* * Sets the font for a particular style.
+ * @param sci Scintilla widget.
+ * @param style The style.
+ * @param font The font name.
+ * @param size The font (fractional) size. */
+void sci_set_font_fractional(ScintillaObject *sci, gint style, const gchar *font, gdouble size)
+{
+	SSM(sci, SCI_STYLESETFONT, (uptr_t) style, (sptr_t) font);
+
+	/* Adding 0.5 is for rounding. */
+	SSM(sci, SCI_STYLESETSIZEFRACTIONAL, (uptr_t) style, (sptr_t) (SC_FONT_SIZE_MULTIPLIER * size + 0.5));
+}
 
 /** Sets the font for a particular style.
  * @param sci Scintilla widget.
@@ -948,8 +960,7 @@ gint sci_find_text(ScintillaObject *sci, gint flags, struct Sci_TextToFind *ttf)
 GEANY_API_SYMBOL
 void sci_set_font(ScintillaObject *sci, gint style, const gchar *font, gint size)
 {
-	SSM(sci, SCI_STYLESETFONT, (uptr_t) style, (sptr_t) font);
-	SSM(sci, SCI_STYLESETSIZE, (uptr_t) style, size);
+	sci_set_font_fractional(sci, style, font, size);
 }
 
 


Modified: src/sciwrappers.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -216,6 +216,8 @@ gint				sci_text_width				(ScintillaObject *sci, gint styleNumber, const gchar *
 void				sci_move_selected_lines_down    (ScintillaObject *sci);
 void				sci_move_selected_lines_up      (ScintillaObject *sci);
 
+void				sci_set_font_fractional		(ScintillaObject *sci, gint style, const gchar *font, gdouble size);
+
 #endif /* GEANY_PRIVATE */
 
 G_END_DECLS


Modified: src/socket.c
31 lines changed, 23 insertions(+), 8 deletions(-)
===================================================================
@@ -421,8 +421,10 @@ static gint socket_fd_open_unix(const gchar *path)
 {
 	gint sock;
 	struct sockaddr_un addr;
-	gint val;
+	gint val, err;
+	gchar *real_dir;
 	gchar *real_path;
+	gchar *basename;
 
 	sock = socket(PF_UNIX, SOCK_STREAM, 0);
 	if (sock < 0)
@@ -439,20 +441,33 @@ static gint socket_fd_open_unix(const gchar *path)
 		return -1;
 	}
 
-	/* fix for #1888561:
-	 * in case the configuration directory is located on a network file system or any other
-	 * file system which doesn't support sockets, we just link the socket there and create the
-	 * real socket in the system's tmp directory assuming it supports sockets */
-	real_path = g_strdup_printf("%s%cgeany_socket.%08x",
-		g_get_tmp_dir(), G_DIR_SEPARATOR, g_random_int());
+	/* Try to place the socket in XDG_RUNTIME_DIR, according to XDG Base
+	 * Directory Specification, see
+	 * https://specifications.freedesktop.org/basedir-spec/latest.
+	 * If that fails, we try to use /tmp as a fallback. The last resort
+	 * is the configuration directory. But the other directories
+	 * are preferred in case the configuration directory is located on
+	 * a network file system or any other file system which doesn't
+	 * support sockets (see #1888561). Append a random int to
+	 * prevent clashes with other instances on the system. */
+	real_dir = g_build_filename(g_get_user_runtime_dir(), "geany", NULL);
+	err = utils_mkdir(real_dir, FALSE);
+	basename = g_strdup_printf("geany_socket.%08x", g_random_int());
+	if (err == 0 || err == EEXIST)
+		real_path = g_build_filename(real_dir, basename, NULL);
+	else
+		real_path = g_build_filename(g_get_tmp_dir(), basename, NULL);
+	g_free(basename);
+	g_free(real_dir);
 
 	if (utils_is_file_writable(real_path) != 0)
 	{	/* if real_path is not writable for us, fall back to ~/.config/geany/geany_socket_*_* */
 		/* instead of creating a symlink and print a warning */
 		g_warning("Socket %s could not be written, using %s as fallback.", real_path, path);
 		SETPTR(real_path, g_strdup(path));
 	}
-	/* create a symlink in e.g. ~/.config/geany/geany_socket_hostname__0 to /tmp/geany_socket.499602d2 */
+	/* create a symlink in e.g. ~/.config/geany/geany_socket_hostname__0 to
+	 * /var/run/user/1000/geany/geany_socket.* */
 	else if (symlink(real_path, path) != 0)
 	{
 		gint saved_errno = errno;


Modified: src/stash.c
14 lines changed, 11 insertions(+), 3 deletions(-)
===================================================================
@@ -126,6 +126,7 @@ struct StashGroup
 	const gchar *name;			/* group name to use in the keyfile */
 	GPtrArray *entries;			/* array of (StashPref*) */
 	gboolean various;		/* mark group for display/edit in stash treeview */
+	const gchar *prefix;	/* text to display for Various UI instead of name */
 	gboolean use_defaults;		/* use default values if there's no keyfile entry */
 };
 
@@ -427,10 +428,13 @@ G_DEFINE_BOXED_TYPE(StashGroup, stash_group, stash_group_dup, stash_group_free);
 
 
 /* Used for selecting groups passed to stash_tree_setup().
- * @c FALSE by default. */
-void stash_group_set_various(StashGroup *group, gboolean various)
+ * @param various @c FALSE by default.
+ * @param prefix @nullable Group prefix or @c NULL to use @c group->name. */
+void stash_group_set_various(StashGroup *group, gboolean various,
+	const gchar *prefix)
 {
 	group->various = various;
+	group->prefix = prefix;
 }
 
 
@@ -1114,15 +1118,19 @@ static void stash_tree_append_pref(StashGroup *group, StashPref *entry, GtkListS
 {
 	GtkTreeIter iter;
 	StashTreeValue *value;
+	gchar *text = NULL;
 
 	value = g_new0(StashTreeValue, 1);
 
 	value->group_name = group->name;
 	value->pref = entry;
 
 	gtk_list_store_append(store, &iter);
-	gtk_list_store_set(store, &iter, STASH_TREE_NAME, entry->key_name,
+	text = g_strconcat(group->prefix ? group->prefix : group->name,
+		".", entry->key_name, NULL);
+	gtk_list_store_set(store, &iter, STASH_TREE_NAME, text,
 		STASH_TREE_VALUE, value, -1);
+	g_free(text);
 }
 
 


Modified: src/stash.h
3 lines changed, 2 insertions(+), 1 deletions(-)
===================================================================
@@ -93,7 +93,8 @@ void stash_group_free_settings(StashGroup *group);
 
 #ifdef GEANY_PRIVATE
 
-void stash_group_set_various(StashGroup *group, gboolean write_once);
+void stash_group_set_various(StashGroup *group, gboolean various,
+	const gchar *prefix);
 
 void stash_group_set_use_defaults(StashGroup *group, gboolean use_defaults);
 


Modified: src/ui_utils.c
4 lines changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -2334,14 +2334,12 @@ void ui_init_prefs(void)
 	StashGroup *group = stash_group_new(PACKAGE);
 
 	/* various prefs */
-	configuration_add_various_pref_group(group);
+	configuration_add_various_pref_group(group, "interface");
 
 	stash_group_add_boolean(group, &interface_prefs.show_symbol_list_expanders,
 		"show_symbol_list_expanders", TRUE);
 	stash_group_add_boolean(group, &interface_prefs.compiler_tab_autoscroll,
 		"compiler_tab_autoscroll", TRUE);
-	stash_group_add_boolean(group, &ui_prefs.allow_always_save,
-		"allow_always_save", FALSE);
 	stash_group_add_string(group, &ui_prefs.statusbar_template,
 		"statusbar_template", _(DEFAULT_STATUSBAR_TEMPLATE));
 	stash_group_add_boolean(group, &ui_prefs.new_document_after_close,



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list