This proposal shouldn't be too bad. But please tell me if you see thing that should be changed.

If it's OK, I will make a proper pull request.

show code diff
diff --git a/src/build.c b/src/build.c
index 56ec9d613..4e7a5a48b 100644
--- a/src/build.c
+++ b/src/build.c
@@ -168,6 +168,7 @@ static void run_exit_cb(GPid child_pid, gint status, gpointer user_data);
 static void on_set_build_commands_activate(GtkWidget *w, gpointer u);
 static void on_build_next_error(GtkWidget *menuitem, gpointer user_data);
 static void on_build_previous_error(GtkWidget *menuitem, gpointer user_data);
+static void on_build_current_line_error(GtkWidget *menuitem, gpointer user_data);
 static void kill_process(GPid *pid);
 static void show_build_result_message(gboolean failure);
 static void process_build_output_line(gchar *msg, gint color);
@@ -1030,6 +1031,7 @@ static void process_build_output_line(gchar *msg, gint color)
 		{
 			gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_NEXT_ERROR], TRUE);
 			gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_PREV_ERROR], TRUE);
+			gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_CUR_LINE_ERROR], TRUE);
 		}
 	}
 	g_free(filename);
@@ -1318,7 +1320,8 @@ static void on_build_menu_item(GtkWidget *w, gpointer user_data)
 /* the fixed items */
 #define MENU_NEXT_ERROR  (MENU_SEPARATOR + 1)
 #define MENU_PREV_ERROR  (MENU_NEXT_ERROR + 1)
-#define MENU_COMMANDS	(MENU_PREV_ERROR + 1)
+#define MENU_CUR_LINE_ERROR  (MENU_PREV_ERROR + 1)
+#define MENU_COMMANDS	(MENU_CUR_LINE_ERROR + 1)
 #define MENU_DONE		(MENU_COMMANDS + 1)
 
 
@@ -1352,6 +1355,8 @@ static struct BuildMenuItemSpec {
 		GBF_NEXT_ERROR, N_("_Next Error"), on_build_next_error},
 	{GTK_STOCK_GO_UP, GEANY_KEYS_BUILD_PREVIOUSERROR, MENU_PREV_ERROR,
 		GBF_PREV_ERROR, N_("_Previous Error"), on_build_previous_error},
+	{NULL, GEANY_KEYS_BUILD_CURRENTLINEERROR, MENU_CUR_LINE_ERROR,
+		GBF_CUR_LINE_ERROR, N_("_Current Line Error"), on_build_current_line_error},
 	{NULL, -1, MENU_SEPARATOR,
 		GBF_SEP_3, NULL, NULL},
 	{GTK_STOCK_EXECUTE, GEANY_KEYS_BUILD_RUN, GBO_TO_GBG(GEANY_GBO_EXEC),
@@ -1489,6 +1494,7 @@ void build_menu_update(GeanyDocument *doc)
 				break;
 			case MENU_NEXT_ERROR:
 			case MENU_PREV_ERROR:
+			case MENU_CUR_LINE_ERROR:
 				gtk_widget_set_sensitive(menu_items.menu_item[GBG_FIXED][bs->build_cmd], have_errors);
 				vis |= TRUE;
 				break;
@@ -1702,6 +1708,18 @@ static void on_build_previous_error(GtkWidget *menuitem, gpointer user_data)
 }
 
 
+static void on_build_current_line_error(GtkWidget *menuitem, gpointer user_data)
+{
+	if (ui_tree_view_find_cur_line(GTK_TREE_VIEW(msgwindow.tree_compiler),
+		msgwin_goto_compiler_file_line))
+	{
+		gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_COMPILER);
+	}
+	else
+		ui_set_statusbar(FALSE, _("No more build errors."));
+}
+
+
 void build_toolbutton_build_clicked(GtkAction *action, gpointer unused)
 {
 	if (last_toolbutton_action == GBO_TO_POINTER(GEANY_GBO_BUILD))
@@ -2807,6 +2825,9 @@ gboolean build_keybinding(guint key_id)
 		case GEANY_KEYS_BUILD_PREVIOUSERROR:
 			item = menu_items->menu_item[GBG_FIXED][GBF_PREV_ERROR];
 			break;
+		case GEANY_KEYS_BUILD_CURRENTLINEERROR:
+			item = menu_items->menu_item[GBG_FIXED][GBF_CUR_LINE_ERROR];
+			break;
 		case GEANY_KEYS_BUILD_RUN:
 			item = menu_items->menu_item[GEANY_GBG_EXEC][GBO_TO_CMD(GEANY_GBO_EXEC)];
 			break;
diff --git a/src/build.h b/src/build.h
index f9d720d06..eab27bfe2 100644
--- a/src/build.h
+++ b/src/build.h
@@ -82,6 +82,7 @@ enum GeanyBuildFixedMenuItems
 {
 	GBF_NEXT_ERROR,
 	GBF_PREV_ERROR,
+	GBF_CUR_LINE_ERROR,
 	GBF_COMMANDS,
 	GBF_SEP_1,
 	GBF_SEP_2,
diff --git a/src/keybindings.c b/src/keybindings.c
index 1721fcd1b..439a212d4 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -705,6 +705,8 @@ static void init_default_kb(void)
 		0, 0, "build_nexterror", _("Next error"), NULL);
 	add_kb(group, GEANY_KEYS_BUILD_PREVIOUSERROR, NULL,
 		0, 0, "build_previouserror", _("Previous error"), NULL);
+	add_kb(group, GEANY_KEYS_BUILD_CURRENTLINEERROR, NULL,
+		GDK_KEY_F3, 0, "build_currentlineerror", _("Current line error"), NULL);
 	add_kb(group, GEANY_KEYS_BUILD_RUN, NULL,
 		GDK_KEY_F5, 0, "build_run", _("Run"), NULL);
 	add_kb(group, GEANY_KEYS_BUILD_OPTIONS, NULL,
diff --git a/src/keybindings.h b/src/keybindings.h
index e88bebc7f..787c0ff41 100644
--- a/src/keybindings.h
+++ b/src/keybindings.h
@@ -229,6 +229,7 @@ enum GeanyKeyBindingID
 	GEANY_KEYS_SELECT_ALL,						/**< Keybinding. */
 	GEANY_KEYS_DOCUMENT_RELOADTAGLIST,			/**< Keybinding. */
 	GEANY_KEYS_BUILD_NEXTERROR,					/**< Keybinding. */
+	GEANY_KEYS_BUILD_CURRENTLINEERROR,			/**< Keybinding. */
 	GEANY_KEYS_NOTEBOOK_MOVETABLAST,			/**< Keybinding. */
 	GEANY_KEYS_SELECT_PARAGRAPH,				/**< Keybinding. */
 	GEANY_KEYS_EDITOR_DELETELINE,				/**< Keybinding. */
diff --git a/src/msgwindow.c b/src/msgwindow.c
index 350ec3880..94b30bf89 100644
--- a/src/msgwindow.c
+++ b/src/msgwindow.c
@@ -180,7 +180,7 @@ static gboolean on_msgwin_key_press_event(GtkWidget *widget, GdkEventKey *event,
 		{
 			case MSG_COMPILER:
 			{	/* key press in the compiler treeview */
-				msgwin_goto_compiler_file_line(enter_or_return);
+				msgwin_goto_compiler_file_line(enter_or_return, FALSE);
 				break;
 			}
 			case MSG_MESSAGE:
@@ -793,7 +793,7 @@ static gboolean goto_compiler_file_line(const gchar *fname, gint line, gboolean
 }
 
 
-gboolean msgwin_goto_compiler_file_line(gboolean focus_editor)
+gboolean msgwin_goto_compiler_file_line(gboolean focus_editor, gboolean cur_line_mode)
 {
 	GtkTreeIter iter;
 	GtkTreeModel *model;
@@ -821,6 +821,9 @@ gboolean msgwin_goto_compiler_file_line(gboolean focus_editor)
 			gchar *filename, *dir;
 			GtkTreePath *path;
 			gboolean ret;
+			GeanyDocument *doc = document_get_current();
+			gint pos = sci_get_current_position(doc->editor->sci);
+			guint cur_line = sci_get_line_from_position(doc->editor->sci, pos) + 1;
 
 			path = gtk_tree_model_get_path(model, &iter);
 			find_prev_build_dir(path, model, &dir);
@@ -829,7 +832,18 @@ gboolean msgwin_goto_compiler_file_line(gboolean focus_editor)
 			g_free(string);
 			g_free(dir);
 
-			ret = goto_compiler_file_line(filename, line, focus_editor);
+			if (cur_line_mode)
+			{
+				ret = FALSE;
+				if (line == cur_line)
+				{
+					ret = goto_compiler_file_line(filename, line, focus_editor);
+				}
+			}
+			else
+			{
+				ret = goto_compiler_file_line(filename, line, focus_editor);
+			}
 			g_free(filename);
 			return ret;
 		}
@@ -1218,7 +1232,7 @@ static gboolean on_msgwin_button_press_event(GtkWidget *widget, GdkEventButton *
 		{
 			case MSG_COMPILER:
 			{	/* mouse click in the compiler treeview */
-				msgwin_goto_compiler_file_line(double_click);
+				msgwin_goto_compiler_file_line(double_click, FALSE);
 				break;
 			}
 			case MSG_MESSAGE:
diff --git a/src/msgwindow.h b/src/msgwindow.h
index 07b06dbc7..9f38f0b6d 100644
--- a/src/msgwindow.h
+++ b/src/msgwindow.h
@@ -100,7 +100,7 @@ void msgwin_show_hide_tabs(void);
 
 void msgwin_menu_add_common_items(GtkMenu *menu);
 
-gboolean msgwin_goto_compiler_file_line(gboolean focus_editor);
+gboolean msgwin_goto_compiler_file_line(gboolean focus_editor, gboolean cur_line);
 
 void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir,
 									  gchar **filename, gint *line);
diff --git a/src/ui_utils.c b/src/ui_utils.c
index 729feae94..a2ae7103c 100644
--- a/src/ui_utils.c
+++ b/src/ui_utils.c
@@ -1768,28 +1768,41 @@ static gboolean tree_model_iter_get_next(GtkTreeModel *model, GtkTreeIter *iter,
 
 /* note: the while loop might be more efficient when searching upwards if it
  * used tree paths instead of tree iters, but in practice it probably doesn't matter much. */
-static gboolean tree_view_find(GtkTreeView *treeview, TVMatchCallback cb, gboolean down)
+static gboolean tree_view_find(GtkTreeView *treeview, TVMatchCallback cb,
+		GeanyMenuCompileErrorSearchMode err_search_mode)
 {
 	GtkTreeSelection *treesel;
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 
 	treesel = gtk_tree_view_get_selection(treeview);
-	if (gtk_tree_selection_get_selected(treesel, &model, &iter))
+	gboolean active_selection = gtk_tree_selection_get_selected(treesel, &model, &iter);
+	gboolean down = err_search_mode == GEANY_MENU_COMPILE_NEXT_ERROR || GEANY_MENU_COMPILE_CUR_LINE_ERROR;
+	if (err_search_mode == GEANY_MENU_COMPILE_CUR_LINE_ERROR)
 	{
-		/* get the next selected item */
-		if (! tree_model_iter_get_next(model, &iter, down))
-			return FALSE;	/* no more items */
+		if (active_selection)
+			tree_model_iter_get_next(model, &iter, TRUE);
+		if (! gtk_tree_model_get_iter_first(model, &iter))
+			return TRUE;
 	}
-	else	/* no selection */
+	else
 	{
-		if (! gtk_tree_model_get_iter_first(model, &iter))
-			return TRUE;	/* no items */
+		if (active_selection)
+		{
+			/* get the next selected item */
+			if (! tree_model_iter_get_next(model, &iter, down))
+				return FALSE;	/* no more items */
+		}
+		else	/* no selection */
+		{
+			if (! gtk_tree_model_get_iter_first(model, &iter))
+				return TRUE;	/* no items */
+		}
 	}
 	while (TRUE)
 	{
 		gtk_tree_selection_select_iter(treesel, &iter);
-		if (cb(FALSE))
+		if (cb(FALSE, err_search_mode == GEANY_MENU_COMPILE_CUR_LINE_ERROR))
 			break;	/* found next message */
 
 		if (! tree_model_iter_get_next(model, &iter, down))
@@ -1811,14 +1824,21 @@ static gboolean tree_view_find(GtkTreeView *treeview, TVMatchCallback cb, gboole
 /* Returns FALSE if the treeview has items but no matching next item. */
 gboolean ui_tree_view_find_next(GtkTreeView *treeview, TVMatchCallback cb)
 {
-	return tree_view_find(treeview, cb, TRUE);
+	return tree_view_find(treeview, cb, GEANY_MENU_COMPILE_NEXT_ERROR);
 }
 
 
 /* Returns FALSE if the treeview has items but no matching next item. */
 gboolean ui_tree_view_find_previous(GtkTreeView *treeview, TVMatchCallback cb)
 {
-	return tree_view_find(treeview, cb, FALSE);
+	return tree_view_find(treeview, cb, GEANY_MENU_COMPILE_PREV_ERROR);
+}
+
+
+/* Returns FALSE if the treeview has items but no matching next item. */
+gboolean ui_tree_view_find_cur_line(GtkTreeView *treeview, TVMatchCallback cb)
+{
+	return tree_view_find(treeview, cb, GEANY_MENU_COMPILE_CUR_LINE_ERROR);
 }
 
 
diff --git a/src/ui_utils.h b/src/ui_utils.h
index f71790a54..eb0a5f94e 100644
--- a/src/ui_utils.h
+++ b/src/ui_utils.h
@@ -232,6 +232,15 @@ typedef enum
 GeanyUIEditorFeatures;
 
 
+typedef enum
+{
+	GEANY_MENU_COMPILE_NEXT_ERROR,
+	GEANY_MENU_COMPILE_PREV_ERROR,
+	GEANY_MENU_COMPILE_CUR_LINE_ERROR
+}
+GeanyMenuCompileErrorSearchMode;
+
+
 void ui_widget_show_hide(GtkWidget *widget, gboolean show);
 
 gchar *ui_menu_item_get_text(GtkMenuItem *menu_item);
@@ -340,7 +349,7 @@ void ui_update_recent_project_menu(void);
 void ui_update_tab_status(GeanyDocument *doc);
 
 
-typedef gboolean TVMatchCallback(gboolean);
+typedef gboolean TVMatchCallback(gboolean, gboolean);
 
 gboolean ui_tree_view_find_next(GtkTreeView *treeview, TVMatchCallback cb);
 


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <geany/geany/issues/3225/1171333665@github.com>