Skip to content

Markdown: Unordered list - fix extending #1632

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

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 75 additions & 43 deletions plugins/markdown-actions/markdown-actions.vala
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,32 @@ public class Code.Plugins.MarkdownActions : Peas.ExtensionBase, Scratch.Services
}

if (evt.keyval == Gdk.Key.Return) {
char ul_marker;
int ol_number = 1;
string item_text;
// Get line text on which return was pressed
var line = get_current_line ();
if (parse_unordered_list_item (line, out ul_marker)) {
if (line.length <= 3) { // empty item
if (line.strip () == "") {
return false;
}

string ul_marker;
int indent_spaces, ol_number;
string item_text = "";
if (parse_unordered_list_item (line, out ul_marker, out item_text)) {
if (item_text.strip () == "") { // empty list item
delete_empty_item ();
} else {
string to_insert = "\n%c ".printf (ul_marker);
string to_insert = "\n%s".printf (ul_marker);
current_source.buffer.insert_at_cursor (to_insert, to_insert.length);
}

return true;
} else if (parse_ordered_list_item (line, ref ol_number, out item_text)) {
} else if (parse_ordered_list_item (line, out ol_number, out item_text, out indent_spaces, null)) {
if (item_text.length == 0) {
delete_empty_item ();
} else {
string to_insert = "\n%d. ".printf (ol_number + 1);
string to_insert = "\n%s%d. ".printf (string.nfill (indent_spaces, ' '), ++ol_number);
current_source.buffer.insert_at_cursor (to_insert, to_insert.length);
fix_ordered_list_numbering ();
// Check following lines to see if renumbering required
fix_ordered_list_numbering (indent_spaces, ol_number);
}
return true;
}
Expand All @@ -111,36 +118,43 @@ public class Code.Plugins.MarkdownActions : Peas.ExtensionBase, Scratch.Services
end.forward_to_line_end ();
current_buffer.delete (ref start, ref end);
current_buffer.insert_at_cursor ("\n", 1);
current_buffer.get_iter_at_offset (out start, current_buffer.cursor_position);
}

private void fix_ordered_list_numbering () {
// Starting on the line where a numered list item was inserted, check if renumbering required
private void fix_ordered_list_numbering (int indent_spaces, int inserted_number) {
Gtk.TextIter next;
var count = 1;
var item_text = "";
var current_buffer = current_source.buffer;

current_buffer.get_iter_at_offset (out next, current_buffer.cursor_position);
var line = get_current_line (next).strip ();
// Get list item number from current line
parse_ordered_list_item (line, ref count, out item_text);
// Start checking following lines
next.forward_line ();
line = get_current_line (next).strip ();
while (parse_ordered_list_item (line, ref count, out item_text)) {
count++;
var next_mark = current_buffer.create_mark (null, next, true);
var point_offset = line.index_of_char ('.');
var start = next;
var end = start;
end.forward_chars (point_offset);

current_buffer.delete (ref start, ref end);
current_buffer.get_iter_at_mark (out next, next_mark);

var to_insert = "%d".printf (count);
current_buffer.insert (ref next, to_insert, to_insert.length);
next.forward_line ();
line = get_current_line (next).strip ();
int point_offset = 0, next_indent_spaces = 0, count = inserted_number, next_count = 0;
string item_text = "";
// Search for ordered list lines at the same level until level falls below or end of doc
while (next.forward_line () &&
parse_ordered_list_item (
get_current_line (next),
out next_count,
out item_text,
out next_indent_spaces,
out point_offset
) &&
next_indent_spaces >= indent_spaces
) {
// Only update lines at same indent within same block
if (next_indent_spaces == indent_spaces) {
count++;
next.forward_chars (indent_spaces);
var next_mark = current_buffer.create_mark (null, next, true);
var start = next;
var end = start;
end.forward_chars (point_offset);

current_buffer.delete (ref start, ref end);
current_buffer.get_iter_at_mark (out next, next_mark);

var to_insert = "%d".printf (count);
current_buffer.insert (ref next, to_insert, to_insert.length);
}
}
}

Expand All @@ -159,28 +173,46 @@ public class Code.Plugins.MarkdownActions : Peas.ExtensionBase, Scratch.Services
return current_buffer.get_text (start, end, false);
}

private bool parse_ordered_list_item (string line, ref int current_number, out string item_text) {
private bool parse_ordered_list_item (
string line,
out int current_number,
out string item_text,
out int indent_spaces,
out int first_point_pos
) {

item_text = "";
int first_point_character = line.index_of_char ('.');
if (first_point_character < 0) {
indent_spaces = -1;
current_number = -1;
first_point_pos = line.index_of_char ('.'); //TODO Handle ")" Ignored escaped?

if (first_point_pos < 0) {
return false;
}

item_text = line.substring (first_point_character + 1).strip ();

var line_start = line.substring (0, first_point_character);
item_text = line.substring (first_point_pos + 1).strip ();

var line_start = line.substring (0, first_point_pos);
indent_spaces = line_start.last_index_of_char (' ') + 1;
if (!int.try_parse (line_start, out current_number)) {
return false;
}
return true;

return indent_spaces >= 0 && current_number >= 1;
}

private bool parse_unordered_list_item (string line, out char ul_marker) {
if ((line[0] == '*' || line[0] == '-') && line[1] == ' ') {
ul_marker = line[0];
private bool parse_unordered_list_item (string line, out string ul_marker, out string item_text) {
var chugged_line = line.chug ();
if ((chugged_line[0] == '*' || chugged_line[0] == '-') &&
chugged_line[1] == ' ') {
var ul_marker_index = line.index_of_char (chugged_line[0]);
ul_marker = "%s%c ".printf (string.nfill (ul_marker_index, ' '), chugged_line[0]);
item_text = chugged_line.substring (2, -1);
return true;
}
ul_marker = '\0';

ul_marker = "";
return false;
}

Expand Down