add folding.c
This commit is contained in:
parent
e13b24e0ce
commit
cb1507bdd4
138
src/folding.c
Normal file
138
src/folding.c
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
* folding.c -- This file is part of GNU nano. *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2022 rexy712 *
|
||||||
|
* *
|
||||||
|
* GNU nano is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, *
|
||||||
|
* or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* GNU nano is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty *
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program. If not, see http://www.gnu.org/licenses/. *
|
||||||
|
* *
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "prototypes.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
/* isspace */
|
||||||
|
|
||||||
|
#ifdef ENABLE_FOLDING
|
||||||
|
|
||||||
|
/* Remove a folded segment from the given line until end of segment */
|
||||||
|
void unfold_folded_segment_from(linestruct *line)
|
||||||
|
{
|
||||||
|
if (line != NULL)
|
||||||
|
refresh_needed = TRUE;
|
||||||
|
for(;line != NULL && line->folded;line = line->next)
|
||||||
|
line->folded = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove a folded segment containing the given line */
|
||||||
|
void unfold_folded_segment(linestruct *line)
|
||||||
|
{
|
||||||
|
unfold_folded_segment_from(get_start_of_folded_segment(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the first member of the folded segment */
|
||||||
|
linestruct *get_start_of_folded_segment(linestruct *line)
|
||||||
|
{
|
||||||
|
if (!line->folded)
|
||||||
|
return line;
|
||||||
|
|
||||||
|
while (line->prev != NULL && line->prev->folded)
|
||||||
|
line = line->prev;
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
/* Get the last member of the folded segment */
|
||||||
|
linestruct *get_end_of_folded_segment(linestruct *line)
|
||||||
|
{
|
||||||
|
if (!line->folded)
|
||||||
|
return line;
|
||||||
|
|
||||||
|
while (line->next != NULL && line->next->folded)
|
||||||
|
line = line->next;
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the span length of a folded_segment */
|
||||||
|
int get_folded_segment_length(linestruct *line)
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
|
||||||
|
if (!line->folded)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
line = get_start_of_folded_segment(line);
|
||||||
|
for (;line->next != NULL && line->next->folded;line = line->next)
|
||||||
|
++i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove any folded_segments within the range [top, bottom].
|
||||||
|
* Returns true if any segments are removed. */
|
||||||
|
bool do_unfold_segment(linestruct *line)
|
||||||
|
{
|
||||||
|
/* Attempt to find a bracketed region first.
|
||||||
|
* If not, top is unmodified. */
|
||||||
|
if (!line->folded) {
|
||||||
|
linestruct *bot;
|
||||||
|
find_bracketed_region(openfile->current, &line, &bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line->folded) {
|
||||||
|
unfold_folded_segment(line);
|
||||||
|
move_cursor_to_proper_column();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fold the currently selected lines unless the current selection
|
||||||
|
* already contains a folded_segment. In that case, remove any
|
||||||
|
* segments that are selected. */
|
||||||
|
void do_fold_segment(void)
|
||||||
|
{
|
||||||
|
linestruct *top, *bot;
|
||||||
|
get_range(&top, &bot);
|
||||||
|
|
||||||
|
if (top == bot) {
|
||||||
|
/* First try to unfold if this line/bracketed region is folded */
|
||||||
|
if (do_unfold_segment(top))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* When not selecting multiple lines, try to find bounding
|
||||||
|
* brackets to act as top and bot. */
|
||||||
|
if (!find_bracketed_region(openfile->current, &top, &bot)) {
|
||||||
|
statusline(AHEM, _("No valid region found for automatic fold"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (linestruct* line = top;line != bot->next;line = line->next)
|
||||||
|
line->folded = TRUE;
|
||||||
|
|
||||||
|
if (top->lineno < openfile->edittop->lineno &&
|
||||||
|
bot->lineno > openfile->edittop->lineno)
|
||||||
|
openfile->edittop = top;
|
||||||
|
|
||||||
|
/* Place the cursor at the start of the fold segment.
|
||||||
|
* Anywhere else within the segment is invalid. */
|
||||||
|
if (openfile->current->folded)
|
||||||
|
openfile->current = get_start_of_folded_segment(top);
|
||||||
|
openfile->mark = NULL;
|
||||||
|
|
||||||
|
refresh_needed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_FOLDING */
|
||||||
Loading…
x
Reference in New Issue
Block a user