Compare commits
14 Commits
master
...
build-exec
Author | SHA1 | Date | |
---|---|---|---|
|
b7f525852d | ||
|
381024d333 | ||
|
dfc55085a0 | ||
|
f24d43e7d2 | ||
|
ca8490ffd9 | ||
|
ce0f57d176 | ||
|
8de8571c4c | ||
|
84e07f25da | ||
|
e4cd4a09e7 | ||
|
d138d56cd6 | ||
|
9219e983c1 | ||
|
1f7d846cc9 | ||
|
e5e2a28dac | ||
|
78a26acdde |
1
TODO
1
TODO
@ -15,7 +15,6 @@ Note: features included in brackets have lower priority.
|
||||
programming languages (done for C-like filetypes using
|
||||
filetypes.common named styles)
|
||||
o asynchronous build commands on Windows
|
||||
o (filetype-independent run command in build dialog & keybinding)
|
||||
o (better custom filetype support)
|
||||
o (custom template insertion - so user can add licenses, etc)
|
||||
o (selectable menu of arguments to use for Make, from Make Custom)
|
||||
|
@ -2651,7 +2651,9 @@ number_ft_menu_items The maximum number of menu items in the 2
|
||||
number_non_ft_menu_items The maximum number of menu items in the 3 on restart
|
||||
independent build section.
|
||||
number_exec_menu_items The maximum number of menu items in the 2 on restart
|
||||
execute section of the Build menu.
|
||||
filetype execute section.
|
||||
number_exec_ind_menu_items The maximum number of menu items in the 2 on restart
|
||||
independent execute section.
|
||||
================================ =========================================== ========== ===========
|
||||
|
||||
Statusbar Templates
|
||||
@ -3027,24 +3029,26 @@ in to be configured. For example, if you change one of the default make
|
||||
commands to run say 'waf' you can also change the label to match.
|
||||
These settings are saved automatically when Geany is shut down.
|
||||
|
||||
The build menu is divided into four groups of items each with different
|
||||
The build menu has four configurable groups of items each with different
|
||||
behaviors:
|
||||
|
||||
* Filetype build commands - are configurable and depend on the filetype of the
|
||||
current document; they capture output in the compiler tab and parse it for
|
||||
- *Filetype build commands* - these depend on the filetype of the
|
||||
current document. They capture output in the compiler tab and parse it for
|
||||
errors.
|
||||
* Independent build commands - are configurable and mostly don't depend on the
|
||||
filetype of the current document; they also capture output in the
|
||||
compiler tab and parse it for errors.
|
||||
* Execute commands - are configurable and intended for executing your
|
||||
program or other long running programs. The output is not parsed for
|
||||
errors and is directed to the terminal command selected in `Tools
|
||||
preferences`_.
|
||||
* Fixed commands - these perform built-in actions:
|
||||
- *Independent build commands* - these (mostly) don't depend on the
|
||||
current filetype. They also capture and parse the output.
|
||||
- *Filetype execute commands* - these depend on the current filetype
|
||||
and they are intended for executing your program or other long running
|
||||
programs. The output is not parsed for errors and is directed to the
|
||||
terminal command selected in `Tools preferences`_.
|
||||
- *Independent execute commands* - as above but not dependent on the
|
||||
current filetype.
|
||||
|
||||
* Go to the next error.
|
||||
* Go to the previous error.
|
||||
* Show the build menu commands dialog.
|
||||
The menu also has fixed commands - these perform built-in actions:
|
||||
|
||||
* Go to the next error.
|
||||
* Go to the previous error.
|
||||
* Show the build menu commands dialog.
|
||||
|
||||
The maximum numbers of items in each of the configurable groups can be
|
||||
configured in `Various preferences`_. Even though the maximum number of
|
||||
@ -3085,15 +3089,18 @@ is shown in the following table:
|
||||
| | | | | Label: Make _Object |
|
||||
| | | | | Command: make %e.o |
|
||||
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
|
||||
| Execute | Loads From: project | Loads From: | Loads From: | Label: _Execute |
|
||||
| | file or else | geany.conf file in | filetypes.xxx in | Command: ./%e |
|
||||
| | filetype defined in | ~/.config/geany or else | Geany install | |
|
||||
| | project file | filetypes.xxx file in | | |
|
||||
| | | ~/.config/geany/filedefs | Saves To: as user | |
|
||||
| | Saves To: | | preferences left. | |
|
||||
| | project file | Saves To: | | |
|
||||
| | | filetypes.xxx file in | | |
|
||||
| | | ~/.config/geany/filedefs | | |
|
||||
| Filetype | Loads From: | Loads From: | Loads From: | Label: _Execute |
|
||||
| Execute | filetype setting | filetypes.xxx file in | filetypes.xxx in | Command: ./%e |
|
||||
| | stored in | ~/.config/geany/filedefs | Geany install | |
|
||||
| | project file | | | |
|
||||
| | | Saves To: Same | Saves To: as user | |
|
||||
| | Saves To: Same | | preferences left. | |
|
||||
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
|
||||
| Independent | Loads From: project | Loads From: | None | None |
|
||||
| Execute | file | geany.conf file in | | |
|
||||
| | | ~/.config/geany | | |
|
||||
| | Saves To: Same | | | |
|
||||
| | | Saves To: Same | | |
|
||||
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
|
||||
|
||||
The following notes on the table may reference cells by coordinate as *(group, source)*:
|
||||
@ -3114,10 +3121,9 @@ The following notes on the table may reference cells by coordinate as *(group, s
|
||||
filetype-independent commands in a filetype file, this provides the ability to
|
||||
define filetype dependent default menu items.
|
||||
|
||||
* *(Execute, Project and Preferences)* - the project independent
|
||||
execute and preferences independent execute commands can only be set by hand
|
||||
editing the appropriate file, see `Preferences file format`_ and `Project file
|
||||
format`_.
|
||||
* Independent execute - the project and preferences independent execute
|
||||
commands can only be set by hand editing the appropriate file, see
|
||||
`Preferences file format`_ and `Project file format`_.
|
||||
|
||||
Set Build Commands dialog
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -3190,7 +3196,8 @@ Keyboard shortcuts can be defined for:
|
||||
|
||||
* the first two filetype build menu items
|
||||
* the first three independent build menu items
|
||||
* the first execute menu item
|
||||
* the first filetype execute menu item
|
||||
* the first independent execute menu item
|
||||
* the fixed menu items (Next/Previous Error, Set Commands)
|
||||
|
||||
In the keybindings configuration dialog (see `Keybinding preferences`_)
|
||||
|
239
src/build.c
239
src/build.c
@ -69,14 +69,6 @@ GeanyBuildInfo build_info = {GEANY_GBG_FT, 0, 0, NULL, GEANY_FILETYPES_NONE, NUL
|
||||
|
||||
static gchar *current_dir_entered = NULL;
|
||||
|
||||
typedef struct RunInfo
|
||||
{
|
||||
GPid pid;
|
||||
gint file_type_id;
|
||||
} RunInfo;
|
||||
|
||||
static RunInfo *run_info;
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
static const gchar RUN_SCRIPT_CMD[] = "geany_run_script_XXXXXX.sh";
|
||||
#endif
|
||||
@ -155,7 +147,7 @@ static struct
|
||||
}
|
||||
widgets;
|
||||
|
||||
static guint build_groups_count[GEANY_GBG_COUNT] = { 3, 4, 2 };
|
||||
static guint build_groups_count[GEANY_GBG_COUNT] = { 3, 4, 2, 2 };
|
||||
static guint build_items_count = 9;
|
||||
|
||||
static void build_exit_cb(GPid pid, gint status, gpointer user_data);
|
||||
@ -349,84 +341,102 @@ static void printfcmds(void)
|
||||
}
|
||||
|
||||
|
||||
/* macros to save typing and make the logic visible */
|
||||
#define return_cmd_if(src, cmds)\
|
||||
if (cmds != NULL && cmds[cmdindex].exists && below>src)\
|
||||
{ \
|
||||
*fr=src; \
|
||||
if (printbuildcmds) \
|
||||
printf("cmd[%u,%u]=%u\n",cmdgrp,cmdindex,src); \
|
||||
return &(cmds[cmdindex]); \
|
||||
}
|
||||
|
||||
#define return_ft_cmd_if(src, cmds)\
|
||||
if (ft != NULL && ft->priv->cmds != NULL \
|
||||
&& ft->priv->cmds[cmdindex].exists && below>src)\
|
||||
{ \
|
||||
*fr=src; \
|
||||
if (printbuildcmds) \
|
||||
printf("cmd[%u,%u]=%u\n",cmdgrp,cmdindex,src); \
|
||||
return &(ft->priv->cmds[cmdindex]); \
|
||||
}
|
||||
|
||||
|
||||
/* get the next lowest command taking priority into account */
|
||||
static GeanyBuildCommand *get_next_build_cmd(GeanyDocument *doc, guint cmdgrp, guint cmdindex,
|
||||
guint below, guint *from)
|
||||
typedef struct CommandSet
|
||||
{
|
||||
/* Note: parameter below used in macros above */
|
||||
GeanyFiletype *ft = NULL;
|
||||
guint sink, *fr = &sink;
|
||||
GeanyBuildSource src;
|
||||
GeanyBuildCommand *cmds;
|
||||
} CommandSet;
|
||||
|
||||
// Note: Could return CommandSet instead of using psrc
|
||||
/* get the next lowest command taking priority into account
|
||||
* below = only consider GeanyBuildSource values less than this parameter
|
||||
* psrc = Address to write GeanyBuildSource */
|
||||
static GeanyBuildCommand *get_next_build_cmd(GeanyDocument *doc,
|
||||
guint cmdgrp, guint cmdindex, guint below, guint *psrc)
|
||||
{
|
||||
g_return_val_if_fail(doc == NULL || doc->is_valid, NULL);
|
||||
|
||||
if (printbuildcmds)
|
||||
printfcmds();
|
||||
if (cmdgrp >= GEANY_GBG_COUNT)
|
||||
return NULL;
|
||||
if (from != NULL)
|
||||
fr = from;
|
||||
if (doc == NULL)
|
||||
doc = document_get_current();
|
||||
if (doc != NULL)
|
||||
ft = doc->file_type;
|
||||
|
||||
GeanyFiletypePrivate empty_ftp = {}, *ftp =
|
||||
doc ? doc->file_type->priv : &empty_ftp; // avoid checking for null
|
||||
CommandSet overloads[6] = {};
|
||||
|
||||
switch (cmdgrp)
|
||||
{
|
||||
case GEANY_GBG_FT: /* order proj ft, home ft, ft, defft */
|
||||
if (ft != NULL)
|
||||
{
|
||||
return_ft_cmd_if(GEANY_BCS_PROJ, projfilecmds);
|
||||
return_ft_cmd_if(GEANY_BCS_PREF, homefilecmds);
|
||||
return_ft_cmd_if(GEANY_BCS_FT, filecmds);
|
||||
}
|
||||
return_cmd_if(GEANY_BCS_DEF, ft_def);
|
||||
case GEANY_GBG_FT: /* order proj ft, home ft, ft, def ft */
|
||||
{
|
||||
CommandSet cs[] = {
|
||||
{GEANY_BCS_PROJ, ftp->projfilecmds},
|
||||
{GEANY_BCS_PREF, ftp->homefilecmds},
|
||||
{GEANY_BCS_FT, ftp->filecmds},
|
||||
{GEANY_BCS_DEF, ft_def},
|
||||
};
|
||||
memcpy(overloads, cs, sizeof(cs));
|
||||
break;
|
||||
}
|
||||
case GEANY_GBG_NON_FT: /* order proj, pref, def */
|
||||
return_cmd_if(GEANY_BCS_PROJ, non_ft_proj);
|
||||
return_cmd_if(GEANY_BCS_PREF, non_ft_pref);
|
||||
return_ft_cmd_if(GEANY_BCS_FT, ftdefcmds);
|
||||
return_cmd_if(GEANY_BCS_DEF, non_ft_def);
|
||||
{
|
||||
CommandSet cs[] = {
|
||||
{GEANY_BCS_PROJ, non_ft_proj},
|
||||
{GEANY_BCS_PREF, non_ft_pref},
|
||||
{GEANY_BCS_FT, ftp->ftdefcmds},
|
||||
{GEANY_BCS_DEF, non_ft_def},
|
||||
};
|
||||
memcpy(overloads, cs, sizeof(cs));
|
||||
break;
|
||||
case GEANY_GBG_EXEC: /* order proj, proj ft, pref, home ft, ft, def */
|
||||
return_cmd_if(GEANY_BCS_PROJ, exec_proj);
|
||||
return_ft_cmd_if(GEANY_BCS_PROJ_FT, projexeccmds);
|
||||
return_cmd_if(GEANY_BCS_PREF, exec_pref);
|
||||
return_ft_cmd_if(GEANY_BCS_FT, homeexeccmds);
|
||||
return_ft_cmd_if(GEANY_BCS_FT, execcmds);
|
||||
return_cmd_if(GEANY_BCS_DEF, exec_def);
|
||||
}
|
||||
case GEANY_GBG_EXEC: /* order proj ft, home ft, ft, def */
|
||||
{
|
||||
CommandSet cs[] = {
|
||||
{GEANY_BCS_PROJ_FT, ftp->projexeccmds},
|
||||
{GEANY_BCS_FT, ftp->homeexeccmds},
|
||||
{GEANY_BCS_FT, ftp->execcmds},
|
||||
{GEANY_BCS_DEF, exec_def},
|
||||
};
|
||||
memcpy(overloads, cs, sizeof(cs));
|
||||
break;
|
||||
}
|
||||
case GEANY_GBG_EXEC_IND: /* order proj, pref */
|
||||
{
|
||||
CommandSet cs[] = {
|
||||
{GEANY_BCS_PROJ, exec_proj},
|
||||
{GEANY_BCS_PREF, exec_pref},
|
||||
};
|
||||
memcpy(overloads, cs, sizeof(cs));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
for (guint i = 0; i < G_N_ELEMENTS(overloads); i++)
|
||||
{
|
||||
GeanyBuildCommand *cmds = overloads[i].cmds;
|
||||
guint src = overloads[i].src;
|
||||
|
||||
if (cmds != NULL && cmds[cmdindex].exists && src < below)
|
||||
{
|
||||
if (psrc)
|
||||
*psrc = src;
|
||||
if (printbuildcmds)
|
||||
g_print("cmd[%u,%u]=%u below=%u; %s\n", cmdgrp, cmdindex, src, below, cmds[cmdindex].command);
|
||||
return &(cmds[cmdindex]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* shortcut to start looking at the top */
|
||||
static GeanyBuildCommand *get_build_cmd(GeanyDocument *doc, guint grp, guint cmdindex, guint *from)
|
||||
// Note: could remove psrc parameter, only passed once
|
||||
static GeanyBuildCommand *get_build_cmd(GeanyDocument *doc, guint grp, guint cmdindex, guint *psrc)
|
||||
{
|
||||
return get_next_build_cmd(doc, grp, cmdindex, GEANY_BCS_COUNT, from);
|
||||
return get_next_build_cmd(doc, grp, cmdindex, GEANY_BCS_COUNT, psrc);
|
||||
}
|
||||
|
||||
|
||||
@ -505,14 +515,21 @@ static GeanyBuildCommand **get_build_group_pointer(const GeanyBuildSource src, c
|
||||
case GEANY_BCS_FT: return ft ? &(ft->priv->execcmds): NULL;
|
||||
case GEANY_BCS_HOME_FT: return ft ? &(ft->priv->homeexeccmds): NULL;
|
||||
case GEANY_BCS_PROJ_FT: return ft ? &(ft->priv->projexeccmds): NULL;
|
||||
default: return NULL;
|
||||
}
|
||||
break;
|
||||
case GEANY_GBG_EXEC_IND:
|
||||
switch (src)
|
||||
{
|
||||
case GEANY_BCS_PREF: return &(exec_pref);
|
||||
case GEANY_BCS_PROJ: return &(exec_proj);
|
||||
default: return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -833,16 +850,13 @@ static void build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *d
|
||||
* the command; otherwise the command itself is returned. working_dir is a pointer
|
||||
* to the working directory from which the command is executed. Both strings are
|
||||
* in the locale encoding. */
|
||||
static gchar *prepare_run_cmd(GeanyDocument *doc, gchar **working_dir, guint cmdindex)
|
||||
static gchar *prepare_run_cmd(GeanyDocument *doc, GeanyBuildCommand *cmd, gchar **working_dir)
|
||||
{
|
||||
GeanyBuildCommand *cmd = NULL;
|
||||
const gchar *cmd_working_dir;
|
||||
gboolean autoclose = FALSE;
|
||||
gchar *cmd_string_utf8, *working_dir_utf8, *run_cmd, *cmd_string;
|
||||
GError *error = NULL;
|
||||
|
||||
cmd = get_build_cmd(doc, GEANY_GBG_EXEC, cmdindex, NULL);
|
||||
|
||||
cmd_string_utf8 = build_replace_placeholder(doc, cmd->command);
|
||||
cmd_working_dir = cmd->working_dir;
|
||||
if (EMPTY(cmd_working_dir))
|
||||
@ -900,20 +914,31 @@ static gchar *prepare_run_cmd(GeanyDocument *doc, gchar **working_dir, guint cmd
|
||||
}
|
||||
|
||||
|
||||
static void build_run_cmd(GeanyDocument *doc, guint cmdindex)
|
||||
// array of filetype run IDs followed by independent run IDs
|
||||
static GPid *run_pids = NULL;
|
||||
|
||||
static GPid *get_run_pid(GeanyBuildGroup grp, guint cmd)
|
||||
{
|
||||
if (grp == GEANY_GBG_EXEC_IND)
|
||||
cmd += build_groups_count[GEANY_GBG_EXEC];
|
||||
return &run_pids[cmd];
|
||||
}
|
||||
|
||||
static void build_run_cmd(GeanyDocument *doc, guint group, guint cmdindex)
|
||||
{
|
||||
gchar *working_dir;
|
||||
gchar *run_cmd = NULL;
|
||||
|
||||
if (! DOC_VALID(doc) || doc->file_name == NULL)
|
||||
return;
|
||||
|
||||
run_cmd = prepare_run_cmd(doc, &working_dir, cmdindex);
|
||||
GeanyBuildCommand *cmd = get_build_cmd(doc, group, cmdindex, NULL);
|
||||
if (!cmd)
|
||||
return;
|
||||
|
||||
run_cmd = prepare_run_cmd(doc, cmd, &working_dir);
|
||||
if (run_cmd == NULL)
|
||||
return;
|
||||
|
||||
run_info[cmdindex].file_type_id = doc->file_type->id;
|
||||
|
||||
#ifdef HAVE_VTE
|
||||
if (vte_info.have_vte && vc->run_in_vte)
|
||||
{
|
||||
@ -943,7 +968,7 @@ static void build_run_cmd(GeanyDocument *doc, guint cmdindex)
|
||||
gtk_widget_grab_focus(vc->vte);
|
||||
msgwin_show_hide(TRUE);
|
||||
|
||||
run_info[cmdindex].pid = 1;
|
||||
*get_run_pid(group, cmdindex) = 1;
|
||||
g_free(vte_cmd);
|
||||
}
|
||||
else
|
||||
@ -969,11 +994,11 @@ static void build_run_cmd(GeanyDocument *doc, guint cmdindex)
|
||||
|
||||
utils_str_replace_all(&locale_term_cmd, "%c", run_cmd);
|
||||
|
||||
if (spawn_async(working_dir, locale_term_cmd, NULL, NULL, &(run_info[cmdindex].pid),
|
||||
GPid *pid = get_run_pid(group, cmdindex);
|
||||
if (spawn_async(working_dir, locale_term_cmd, NULL, NULL, pid,
|
||||
&error))
|
||||
{
|
||||
g_child_watch_add(run_info[cmdindex].pid, (GChildWatchFunc) run_exit_cb,
|
||||
(gpointer) &(run_info[cmdindex]));
|
||||
g_child_watch_add(*pid, run_exit_cb, pid);
|
||||
build_menu_update(doc);
|
||||
}
|
||||
else
|
||||
@ -986,10 +1011,9 @@ static void build_run_cmd(GeanyDocument *doc, guint cmdindex)
|
||||
#ifndef G_OS_WIN32
|
||||
g_unlink(run_cmd);
|
||||
#endif
|
||||
run_info[cmdindex].pid = (GPid) 0;
|
||||
*get_run_pid(group, cmdindex) = (GPid) 0;
|
||||
}
|
||||
}
|
||||
|
||||
g_free(working_dir);
|
||||
g_free(run_cmd);
|
||||
}
|
||||
@ -1127,11 +1151,11 @@ static void build_exit_cb(GPid child_pid, gint status, gpointer user_data)
|
||||
|
||||
static void run_exit_cb(GPid child_pid, gint status, gpointer user_data)
|
||||
{
|
||||
RunInfo *run_info_data = user_data;
|
||||
GPid *pid = user_data;
|
||||
|
||||
g_spawn_close_pid(child_pid);
|
||||
|
||||
run_info_data->pid = 0;
|
||||
*pid = 0;
|
||||
/* reset the stop button and menu item to the original meaning */
|
||||
build_menu_update(NULL);
|
||||
}
|
||||
@ -1274,11 +1298,12 @@ static void on_build_menu_item(GtkWidget *w, gpointer user_data)
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (grp == GEANY_GBG_EXEC)
|
||||
else if (grp == GEANY_GBG_EXEC || grp == GEANY_GBG_EXEC_IND)
|
||||
{
|
||||
if (run_info[cmd].pid > (GPid) 1)
|
||||
GPid *pid = get_run_pid(grp, cmd);
|
||||
if (*pid > (GPid) 1)
|
||||
{
|
||||
kill_process(&run_info[cmd].pid);
|
||||
kill_process(pid);
|
||||
return;
|
||||
}
|
||||
bc = get_build_cmd(doc, grp, cmd, NULL);
|
||||
@ -1294,7 +1319,7 @@ static void on_build_menu_item(GtkWidget *w, gpointer user_data)
|
||||
g_free(uri);
|
||||
}
|
||||
else
|
||||
build_run_cmd(doc, cmd);
|
||||
build_run_cmd(doc, grp, cmd);
|
||||
}
|
||||
else
|
||||
build_command(doc, grp, cmd, NULL);
|
||||
@ -1308,6 +1333,7 @@ static void on_build_menu_item(GtkWidget *w, gpointer user_data)
|
||||
#define MENU_FT_REST (GEANY_GBG_COUNT + GEANY_GBG_FT)
|
||||
#define MENU_NON_FT_REST (GEANY_GBG_COUNT + GEANY_GBG_NON_FT)
|
||||
#define MENU_EXEC_REST (GEANY_GBG_COUNT + GEANY_GBG_EXEC)
|
||||
#define MENU_EXEC_IND_REST (GEANY_GBG_COUNT + GEANY_GBG_EXEC_IND)
|
||||
/* the separator */
|
||||
#define MENU_SEPARATOR (2*GEANY_GBG_COUNT)
|
||||
/* the fixed items */
|
||||
@ -1353,6 +1379,12 @@ static struct BuildMenuItemSpec {
|
||||
GBO_TO_CMD(GEANY_GBO_EXEC), NULL, on_build_menu_item},
|
||||
{NULL, -1, MENU_EXEC_REST,
|
||||
GBO_TO_CMD(GEANY_GBO_EXEC) + 1, NULL, on_build_menu_item},
|
||||
{NULL, -1, MENU_SEPARATOR,
|
||||
GBF_SEP_5, NULL, NULL},
|
||||
{GTK_STOCK_EXECUTE, GEANY_KEYS_BUILD_RUNINDEPENDENT, GEANY_GBG_EXEC_IND,
|
||||
0, NULL, on_build_menu_item},
|
||||
{NULL, -1, MENU_EXEC_IND_REST,
|
||||
1, NULL, on_build_menu_item},
|
||||
{NULL, -1, MENU_SEPARATOR,
|
||||
GBF_SEP_4, NULL, NULL},
|
||||
{GTK_STOCK_PREFERENCES, GEANY_KEYS_BUILD_OPTIONS, MENU_COMMANDS,
|
||||
@ -1395,6 +1427,7 @@ static void create_build_menu(BuildMenuItems *build_menu_items)
|
||||
build_menu_items->menu_item[GEANY_GBG_FT] = g_new0(GtkWidget*, build_groups_count[GEANY_GBG_FT]);
|
||||
build_menu_items->menu_item[GEANY_GBG_NON_FT] = g_new0(GtkWidget*, build_groups_count[GEANY_GBG_NON_FT]);
|
||||
build_menu_items->menu_item[GEANY_GBG_EXEC] = g_new0(GtkWidget*, build_groups_count[GEANY_GBG_EXEC]);
|
||||
build_menu_items->menu_item[GEANY_GBG_EXEC_IND] = g_new0(GtkWidget*, build_groups_count[GEANY_GBG_EXEC_IND]);
|
||||
build_menu_items->menu_item[GBG_FIXED] = g_new0(GtkWidget*, GBF_COUNT);
|
||||
|
||||
for (i = 0; build_menu_specs[i].build_grp != MENU_DONE; ++i)
|
||||
@ -1527,7 +1560,7 @@ void build_menu_update(GeanyDocument *doc)
|
||||
else
|
||||
{
|
||||
GtkWidget *image;
|
||||
exec_running = run_info[cmd].pid > (GPid) 1;
|
||||
exec_running = *get_run_pid(grp, cmd) > (GPid) 1;
|
||||
cmd_sensitivity = (bc != NULL) || exec_running;
|
||||
gtk_widget_set_sensitive(menu_item, cmd_sensitivity);
|
||||
if (cmd == GBO_TO_CMD(GEANY_GBO_EXEC))
|
||||
@ -2200,20 +2233,16 @@ static gboolean build_read_commands(BuildDestination *dst, BuildTableData table_
|
||||
|
||||
void build_read_project(GeanyFiletype *ft, BuildTableData build_properties)
|
||||
{
|
||||
BuildDestination menu_dst;
|
||||
BuildDestination menu_dst = {0};
|
||||
|
||||
if (ft != NULL)
|
||||
{
|
||||
menu_dst.dst[GEANY_GBG_FT] = &(ft->priv->projfilecmds);
|
||||
menu_dst.dst[GEANY_GBG_EXEC] = &ft->priv->projexeccmds;
|
||||
menu_dst.fileregexstr = &(ft->priv->projerror_regex_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_dst.dst[GEANY_GBG_FT] = NULL;
|
||||
menu_dst.fileregexstr = NULL;
|
||||
}
|
||||
menu_dst.dst[GEANY_GBG_NON_FT] = &non_ft_proj;
|
||||
menu_dst.dst[GEANY_GBG_EXEC] = &exec_proj;
|
||||
menu_dst.dst[GEANY_GBG_EXEC_IND] = &exec_proj;
|
||||
menu_dst.nonfileregexstr = ®ex_proj;
|
||||
|
||||
build_read_commands(&menu_dst, build_properties, GTK_RESPONSE_ACCEPT);
|
||||
@ -2228,7 +2257,6 @@ static void show_build_commands_dialog(void)
|
||||
const gchar *title = _("Set Build Commands");
|
||||
gint response;
|
||||
BuildTableData table_data;
|
||||
BuildDestination prefdsts;
|
||||
|
||||
if (doc != NULL)
|
||||
ft = doc->file_type;
|
||||
@ -2243,6 +2271,7 @@ static void show_build_commands_dialog(void)
|
||||
/* run modally to prevent user changing idx filetype */
|
||||
response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
|
||||
BuildDestination prefdsts = {0};
|
||||
prefdsts.dst[GEANY_GBG_NON_FT] = &non_ft_pref;
|
||||
if (ft != NULL)
|
||||
{
|
||||
@ -2250,12 +2279,6 @@ static void show_build_commands_dialog(void)
|
||||
prefdsts.fileregexstr = &(ft->priv->homeerror_regex_string);
|
||||
prefdsts.dst[GEANY_GBG_EXEC] = &(ft->priv->homeexeccmds);
|
||||
}
|
||||
else
|
||||
{
|
||||
prefdsts.dst[GEANY_GBG_FT] = NULL;
|
||||
prefdsts.fileregexstr = NULL;
|
||||
prefdsts.dst[GEANY_GBG_EXEC] = NULL;
|
||||
}
|
||||
prefdsts.nonfileregexstr = ®ex_pref;
|
||||
if (build_read_commands(&prefdsts, table_data, response) && ft != NULL)
|
||||
filetypes_save_commands(ft);
|
||||
@ -2289,7 +2312,7 @@ static const gchar *build_grp_name = "build-menu";
|
||||
* where gg = FT, NF, EX for the command group
|
||||
* nn = 2 digit command number
|
||||
* xx = LB for label, CM for command and WD for working dir */
|
||||
static const gchar *groups[GEANY_GBG_COUNT] = { "FT", "NF", "EX" };
|
||||
static const gchar *groups[GEANY_GBG_COUNT] = { "FT", "NF", "EX", "EX" };
|
||||
static const gchar *fixedkey="xx_xx_xx";
|
||||
|
||||
#define set_key_grp(key, grp) (key[prefixlen + 0] = grp[0], key[prefixlen + 1] = grp[1])
|
||||
@ -2391,12 +2414,12 @@ void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
|
||||
break;
|
||||
case GEANY_BCS_PREF:
|
||||
build_load_menu_grp(config, &non_ft_pref, GEANY_GBG_NON_FT, NULL, FALSE);
|
||||
build_load_menu_grp(config, &exec_pref, GEANY_GBG_EXEC, NULL, FALSE);
|
||||
build_load_menu_grp(config, &exec_pref, GEANY_GBG_EXEC_IND, NULL, FALSE);
|
||||
SETPTR(regex_pref, g_key_file_get_string(config, build_grp_name, "error_regex", NULL));
|
||||
break;
|
||||
case GEANY_BCS_PROJ:
|
||||
build_load_menu_grp(config, &non_ft_proj, GEANY_GBG_NON_FT, NULL, FALSE);
|
||||
build_load_menu_grp(config, &exec_proj, GEANY_GBG_EXEC, NULL, FALSE);
|
||||
build_load_menu_grp(config, &exec_proj, GEANY_GBG_EXEC_IND, NULL, FALSE);
|
||||
SETPTR(regex_proj, g_key_file_get_string(config, build_grp_name, "error_regex", NULL));
|
||||
pj = (GeanyProject*)p;
|
||||
if (p == NULL)
|
||||
@ -2481,7 +2504,7 @@ void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
|
||||
if (!EMPTY(value))
|
||||
{
|
||||
if (exec_proj == NULL)
|
||||
exec_proj = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_EXEC]);
|
||||
exec_proj = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_EXEC_IND]);
|
||||
if (! exec_proj[GBO_TO_CMD(GEANY_GBO_EXEC)].exists)
|
||||
{
|
||||
exec_proj[GBO_TO_CMD(GEANY_GBO_EXEC)].exists = TRUE;
|
||||
@ -2598,7 +2621,7 @@ void build_save_menu(GKeyFile *config, gpointer ptr, GeanyBuildSource src)
|
||||
break;
|
||||
case GEANY_BCS_PREF:
|
||||
build_save_menu_grp(config, non_ft_pref, GEANY_GBG_NON_FT, NULL);
|
||||
build_save_menu_grp(config, exec_pref, GEANY_GBG_EXEC, NULL);
|
||||
build_save_menu_grp(config, exec_pref, GEANY_GBG_EXEC_IND, NULL);
|
||||
if (!EMPTY(regex_pref))
|
||||
g_key_file_set_string(config, build_grp_name, "error_regex", regex_pref);
|
||||
else
|
||||
@ -2607,7 +2630,7 @@ void build_save_menu(GKeyFile *config, gpointer ptr, GeanyBuildSource src)
|
||||
case GEANY_BCS_PROJ:
|
||||
pj = (GeanyProject*)ptr;
|
||||
build_save_menu_grp(config, non_ft_proj, GEANY_GBG_NON_FT, NULL);
|
||||
build_save_menu_grp(config, exec_proj, GEANY_GBG_EXEC, NULL);
|
||||
build_save_menu_grp(config, exec_proj, GEANY_GBG_EXEC_IND, NULL);
|
||||
if (!EMPTY(regex_proj))
|
||||
g_key_file_set_string(config, build_grp_name, "error_regex", regex_proj);
|
||||
else
|
||||
@ -2703,7 +2726,8 @@ void build_init(void)
|
||||
ft_def = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_FT]);
|
||||
non_ft_def = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_NON_FT]);
|
||||
exec_def = g_new0(GeanyBuildCommand, build_groups_count[GEANY_GBG_EXEC]);
|
||||
run_info = g_new0(RunInfo, build_groups_count[GEANY_GBG_EXEC]);
|
||||
run_pids = g_new0(GPid, build_groups_count[GEANY_GBG_EXEC] +
|
||||
build_groups_count[GEANY_GBG_EXEC_IND]);
|
||||
|
||||
for (cmdindex = 0; default_cmds[cmdindex].command != NULL; ++cmdindex)
|
||||
{
|
||||
@ -2815,6 +2839,9 @@ gboolean build_keybinding(guint key_id)
|
||||
case GEANY_KEYS_BUILD_RUN:
|
||||
item = menu_items->menu_item[GEANY_GBG_EXEC][GBO_TO_CMD(GEANY_GBO_EXEC)];
|
||||
break;
|
||||
case GEANY_KEYS_BUILD_RUNINDEPENDENT:
|
||||
item = menu_items->menu_item[GEANY_GBG_EXEC_IND][0];
|
||||
break;
|
||||
case GEANY_KEYS_BUILD_OPTIONS:
|
||||
item = menu_items->menu_item[GBG_FIXED][GBF_COMMANDS];
|
||||
break;
|
||||
|
@ -36,6 +36,7 @@ typedef enum
|
||||
GEANY_GBG_FT, /**< filetype items */
|
||||
GEANY_GBG_NON_FT, /**< non filetype items.*/
|
||||
GEANY_GBG_EXEC, /**< execute items */
|
||||
GEANY_GBG_EXEC_IND, /**< independent execute items */
|
||||
GEANY_GBG_COUNT /**< count of groups. */
|
||||
} GeanyBuildGroup;
|
||||
|
||||
@ -87,6 +88,7 @@ enum GeanyBuildFixedMenuItems
|
||||
GBF_SEP_2,
|
||||
GBF_SEP_3,
|
||||
GBF_SEP_4,
|
||||
GBF_SEP_5,
|
||||
GBF_COUNT
|
||||
};
|
||||
|
||||
|
@ -704,6 +704,8 @@ static void init_default_kb(void)
|
||||
0, 0, "build_previouserror", _("Previous error"), NULL);
|
||||
add_kb(group, GEANY_KEYS_BUILD_RUN, NULL,
|
||||
GDK_F5, 0, "build_run", _("Run"), NULL);
|
||||
add_kb(group, GEANY_KEYS_BUILD_RUNINDEPENDENT, NULL,
|
||||
GDK_F5, GDK_SHIFT_MASK, "build_run_ind", _("_Independent Run"), NULL);
|
||||
add_kb(group, GEANY_KEYS_BUILD_OPTIONS, NULL,
|
||||
0, 0, "build_options", _("Build options"), NULL);
|
||||
|
||||
|
@ -273,8 +273,9 @@ enum GeanyKeyBindingID
|
||||
GEANY_KEYS_FORMAT_SENDTOCMD8, /**< Keybinding. */
|
||||
GEANY_KEYS_FORMAT_SENDTOCMD9, /**< Keybinding. */
|
||||
GEANY_KEYS_EDITOR_DELETELINETOBEGINNING, /**< Keybinding. */
|
||||
GEANY_KEYS_DOCUMENT_STRIPTRAILINGSPACES, /**< Keybinding.
|
||||
* @since 1.34 (API 238) */
|
||||
GEANY_KEYS_DOCUMENT_STRIPTRAILINGSPACES, /**< Keybinding. */
|
||||
GEANY_KEYS_BUILD_RUNINDEPENDENT, /**< Keybinding.
|
||||
* @since 1.34 (API 239) */
|
||||
GEANY_KEYS_COUNT /* must not be used by plugins */
|
||||
};
|
||||
|
||||
|
@ -117,6 +117,7 @@ static struct
|
||||
gint number_ft_menu_items;
|
||||
gint number_non_ft_menu_items;
|
||||
gint number_exec_menu_items;
|
||||
gint number_exec_ind_menu_items;
|
||||
}
|
||||
build_menu_prefs;
|
||||
|
||||
@ -284,6 +285,8 @@ static void init_pref_groups(void)
|
||||
"number_non_ft_menu_items", 0);
|
||||
stash_group_add_integer(group, &build_menu_prefs.number_exec_menu_items,
|
||||
"number_exec_menu_items", 0);
|
||||
stash_group_add_integer(group, &build_menu_prefs.number_exec_ind_menu_items,
|
||||
"number_exec_ind_menu_items", 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1000,6 +1003,7 @@ static void load_dialog_prefs(GKeyFile *config)
|
||||
build_set_group_count(GEANY_GBG_FT, build_menu_prefs.number_ft_menu_items);
|
||||
build_set_group_count(GEANY_GBG_NON_FT, build_menu_prefs.number_non_ft_menu_items);
|
||||
build_set_group_count(GEANY_GBG_EXEC, build_menu_prefs.number_exec_menu_items);
|
||||
build_set_group_count(GEANY_GBG_EXEC_IND, build_menu_prefs.number_exec_ind_menu_items);
|
||||
build_load_menu(config, GEANY_BCS_PREF, NULL);
|
||||
}
|
||||
|
||||
|
@ -443,6 +443,7 @@ static void destroy_project(gboolean open_default)
|
||||
/* remove project non filetype build menu items */
|
||||
build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_NON_FT, -1);
|
||||
build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_EXEC, -1);
|
||||
build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_EXEC_IND, -1);
|
||||
|
||||
g_free(app->project->name);
|
||||
g_free(app->project->description);
|
||||
@ -810,8 +811,6 @@ static gboolean update_config(const PropertyDialogElements *e, gboolean new_proj
|
||||
GtkTextIter start, end;
|
||||
GtkTextBuffer *buffer;
|
||||
GeanyDocument *doc = document_get_current();
|
||||
GeanyBuildCommand *oldvalue;
|
||||
GeanyFiletype *ft = doc ? doc->file_type : NULL;
|
||||
GtkWidget *widget;
|
||||
gchar *tmp;
|
||||
GString *str;
|
||||
@ -827,16 +826,25 @@ static gboolean update_config(const PropertyDialogElements *e, gboolean new_proj
|
||||
stash_group_update(node->data, e->dialog);
|
||||
|
||||
/* read the project build menu */
|
||||
oldvalue = ft ? ft->priv->projfilecmds : NULL;
|
||||
build_read_project(ft, e->build_properties);
|
||||
|
||||
if (ft != NULL && ft->priv->projfilecmds != oldvalue && ft->priv->project_list_entry < 0)
|
||||
GeanyFiletype *ft = doc ? doc->file_type : NULL;
|
||||
if (ft && ft->priv->project_list_entry < 0)
|
||||
{
|
||||
if (p->priv->build_filetypes_list == NULL)
|
||||
p->priv->build_filetypes_list = g_ptr_array_new();
|
||||
ft->priv->project_list_entry = p->priv->build_filetypes_list->len;
|
||||
g_ptr_array_add(p->priv->build_filetypes_list, ft);
|
||||
GeanyBuildCommand *oldbuild = ft->priv->projfilecmds;
|
||||
GeanyBuildCommand *oldexec = ft->priv->projexeccmds;
|
||||
build_read_project(ft, e->build_properties);
|
||||
|
||||
if (ft->priv->projfilecmds != oldbuild ||
|
||||
ft->priv->projexeccmds != oldexec)
|
||||
{
|
||||
if (p->priv->build_filetypes_list == NULL)
|
||||
p->priv->build_filetypes_list = g_ptr_array_new();
|
||||
ft->priv->project_list_entry = p->priv->build_filetypes_list->len;
|
||||
g_ptr_array_add(p->priv->build_filetypes_list, ft);
|
||||
}
|
||||
}
|
||||
else
|
||||
build_read_project(NULL, e->build_properties);
|
||||
|
||||
build_menu_update(doc);
|
||||
|
||||
widget = ui_lookup_widget(e->dialog, "radio_long_line_disabled_project");
|
||||
|
Loading…
x
Reference in New Issue
Block a user