Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When "go to line" is out of bounds, go to beginning or end of document #2973

Merged
merged 9 commits into from Nov 9, 2021
29 changes: 6 additions & 23 deletions src/callbacks.c
Expand Up @@ -911,21 +911,6 @@ void on_find_in_files1_activate(GtkMenuItem *menuitem, gpointer user_data)
}


static void get_line_and_offset_from_text(const gchar *text, gint *line_no, gint *offset)
{
if (*text == '+' || *text == '-')
{
*line_no = atoi(text + 1);
*offset = (*text == '+') ? 1 : -1;
}
else
{
*line_no = atoi(text) - 1;
*offset = 0;
}
}


void on_go_to_line_activate(GtkMenuItem *menuitem, gpointer user_data)
{
static gchar value[16] = "";
Expand All @@ -937,12 +922,11 @@ void on_go_to_line_activate(GtkMenuItem *menuitem, gpointer user_data)
if (result != NULL)
{
GeanyDocument *doc = document_get_current();
gint offset;
gint line_no;

g_return_if_fail(doc != NULL);

get_line_and_offset_from_text(result, &line_no, &offset);
gint line_no = atoi(result);
gboolean offset = (*result == '+' || *result == '-');

if (! editor_goto_line(doc->editor, line_no, offset))
utils_beep();
/* remember value for future calls */
Expand All @@ -956,12 +940,11 @@ void on_go_to_line_activate(GtkMenuItem *menuitem, gpointer user_data)
void on_toolbutton_goto_entry_activate(GtkAction *action, const gchar *text, gpointer user_data)
{
GeanyDocument *doc = document_get_current();
gint offset;
gint line_no;

g_return_if_fail(doc != NULL);

get_line_and_offset_from_text(text, &line_no, &offset);
gint line_no = atoi(text);
gboolean offset = (*text == '+' || *text == '-');

if (! editor_goto_line(doc->editor, line_no, offset))
utils_beep();
else
Expand Down
36 changes: 20 additions & 16 deletions src/editor.c
Expand Up @@ -4699,29 +4699,33 @@ void editor_set_indent(GeanyEditor *editor, GeanyIndentType type, gint width)
}


/* Convenience function for editor_goto_pos() to pass in a line number. */
gboolean editor_goto_line(GeanyEditor *editor, gint line_no, gint offset)
/* Convenience function for editor_goto_pos() to pass in a line number.
*
* If @a offset is FALSE, goes to line @a line_no. Otherwise, goes to
* the current line + @a line_no. Sets the line marker.
*
* If the destination line is not in the document, goes to the nearest
* line and does not set the marker.
*
* @param editor Editor.
* @param line_no The line to go to or an offset from the current line.
* The first line of the document is 1.
* @param offset Whether @a line_no is an offset from the current line.
* @return @c TRUE if action has been performed, otherwise @c FALSE.
*/
gboolean editor_goto_line(GeanyEditor *editor, gint line_no, gboolean offset)
{
/* line number is always positive,
* so it is a programming error if line_no < 0 */
g_return_val_if_fail(line_no >= 0, FALSE);
g_return_val_if_fail(editor, FALSE);

gulong line_count = sci_get_line_count(editor->sci);

/* sign is communicated in offset */
if (offset != 0)
{
gint current_line = sci_get_current_line(editor->sci);
line_no *= offset;
line_no = current_line + line_no;
}
if (offset)
line_no += sci_get_current_line(editor->sci) + 1;

/* ensure line_no is in bounds and determine whether to set line marker */
gboolean set_marker = line_no >= 0 && line_no < line_count;
line_no = (line_no < 0) ? 0
gboolean set_marker = line_no > 0 && line_no < line_count;
line_no = (line_no <= 0) ? 0
: (line_no >= line_count) ? line_count - 1
: line_no;
: line_no - 1;

gint pos = sci_get_position_from_line(editor->sci, line_no);
return editor_goto_pos(editor, pos, set_marker);
Expand Down