Change folding behavior when no lines are selected as suggested by the nano dev
This commit is contained in:
parent
05fa7110ec
commit
01b30a5a0e
@ -21,6 +21,9 @@
|
||||
#include "prototypes.h"
|
||||
|
||||
#include <string.h>
|
||||
/* strlen */
|
||||
#include <ctype.h>
|
||||
/* isspace */
|
||||
|
||||
#ifdef ENABLE_FOLDING
|
||||
|
||||
@ -80,18 +83,10 @@ bool do_unfold_segments(linestruct *top, linestruct *bot)
|
||||
if (top != bot)
|
||||
return FALSE;
|
||||
|
||||
linestruct *match_line = openfile->current;
|
||||
size_t match_x = openfile->current_x;
|
||||
|
||||
if (!top->folded && !find_matching_bracket_pos(&match_line, &match_x)){
|
||||
if (openfile->current->lineno > match_line->lineno) {
|
||||
top = match_line->next;
|
||||
bot = openfile->current->prev;
|
||||
} else {
|
||||
top = openfile->current->next;
|
||||
bot = match_line->prev;
|
||||
}
|
||||
}
|
||||
/* Attempt to find a bracketed region first.
|
||||
* If not, top is unmodified. */
|
||||
if (!top->folded)
|
||||
find_bracketed_region(openfile->current, &top, &bot);
|
||||
|
||||
if (top->folded) {
|
||||
unfold_folded_segment(top);
|
||||
@ -112,35 +107,26 @@ void do_fold_segment(void)
|
||||
if (do_unfold_segments(top, bot)) {
|
||||
return;
|
||||
}
|
||||
if (top == bot) {
|
||||
linestruct *match_line = openfile->current;
|
||||
size_t match_x = openfile->current_x;
|
||||
|
||||
if (!find_matching_bracket_pos(&match_line, &match_x)){
|
||||
int linedist = openfile->current->lineno - match_line->lineno;
|
||||
linedist = linedist < 0 ? -linedist : linedist;
|
||||
/* When not selecting multiple lines, try to find bounding
|
||||
* brackets to act as top and bot. */
|
||||
if (top == bot)
|
||||
if (!find_bracketed_region(openfile->current, &top, &bot)) {
|
||||
statusline(AHEM, _("No valid region found for automatic fold"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (linedist >= 2) {
|
||||
if (openfile->current->lineno > match_line->lineno) {
|
||||
top = match_line->next;
|
||||
bot = openfile->current->prev;
|
||||
} else {
|
||||
top = openfile->current->next;
|
||||
bot = match_line->prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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->next;
|
||||
openfile->edittop = top;
|
||||
|
||||
/* Place the cursor at the start of the fold segment.
|
||||
* Anywhere else within the segment is invalid. */
|
||||
openfile->current = get_start_of_folded_segment(openfile->current);
|
||||
openfile->mark = NULL;
|
||||
|
||||
refresh_needed = TRUE;
|
||||
}
|
||||
|
||||
@ -472,6 +472,8 @@ void goto_line_and_column(ssize_t line, ssize_t column, bool retain_answer,
|
||||
void do_gotolinecolumn(void);
|
||||
#ifndef NANO_TINY
|
||||
int find_matching_bracket_pos(linestruct **line, size_t *xpos);
|
||||
bool find_bracketed_region(linestruct *in_region,
|
||||
linestruct **top, linestruct **bot);
|
||||
void do_find_bracket(void);
|
||||
void put_or_lift_anchor(void);
|
||||
void to_prev_anchor(void);
|
||||
|
||||
89
src/search.c
89
src/search.c
@ -880,6 +880,92 @@ void do_gotolinecolumn(void)
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Search backwards for a line ending with a bracket, including the current line.
|
||||
* top is an in/out parameter. The passed value is the start line for searching.
|
||||
* xpos is an out parameter. It is the position in the line where the bracket is
|
||||
* found. bracket_half is the halfway mark in the matchbrackets array. This way in
|
||||
* a loop the halfway value isn't recomputed. */
|
||||
bool find_start_of_bracketed_region(linestruct **top, size_t *xpos, size_t bracket_half)
|
||||
{
|
||||
/* Search backwards for a line ending with a bracket, including the current line */
|
||||
for (;(*top) != NULL;*top = (*top)->prev) {
|
||||
char *found;
|
||||
const char *bracket;
|
||||
int len = strlen((*top)->data);
|
||||
|
||||
/* Find the last bracket on the search line */
|
||||
found = mbrevstrpbrk((*top)->data, matchbrackets, (*top)->data + len);
|
||||
if (found == NULL)
|
||||
continue;
|
||||
|
||||
*xpos = found - (*top)->data;
|
||||
bracket = mbstrchr(matchbrackets, found);
|
||||
|
||||
/* We're looking for opening braces, not closing */
|
||||
if (bracket >= matchbrackets + bracket_half)
|
||||
continue;
|
||||
|
||||
/* Check if this is the last character in the line */
|
||||
char *next = (*top)->data + step_right((*top)->data, *xpos);
|
||||
if (*next == '\0')
|
||||
return TRUE;
|
||||
}
|
||||
*xpos = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the halfway point in matchbrackets, where open and close
|
||||
* brackets meet. */
|
||||
size_t get_matchbrackets_halfway(void)
|
||||
{
|
||||
size_t charcount = mbstrlen(matchbrackets) / 2;
|
||||
size_t halfway = 0;
|
||||
|
||||
for (size_t i = 0;i < charcount;++i)
|
||||
halfway += char_length(matchbrackets + halfway);
|
||||
return halfway;
|
||||
}
|
||||
/* Get a region surrounding the line in_region. A region here is defined
|
||||
* as a block of text starting with an opening bracket at the end of a line,
|
||||
* and ending with a matching closing bracket.
|
||||
* top and bot are out parameters. Returns the top/bottom line of the region.
|
||||
* top_pos and bot_pos are out parameters. Returns the position within the
|
||||
* top and bottom lines where the brackets are found. */
|
||||
bool find_bracketed_region(linestruct *in_region,
|
||||
linestruct **top, linestruct **bot)
|
||||
{
|
||||
size_t bracket_half = get_matchbrackets_halfway();
|
||||
size_t top_pos;
|
||||
size_t bot_pos;
|
||||
linestruct *was_top = *top;
|
||||
linestruct *was_bot = *bot;
|
||||
*top = in_region;
|
||||
|
||||
for (;find_start_of_bracketed_region(top, &top_pos, bracket_half)
|
||||
;*top = (*top)->prev)
|
||||
{
|
||||
*bot = *top;
|
||||
bot_pos = top_pos;
|
||||
|
||||
if (!find_matching_bracket_pos(bot, &bot_pos)) {
|
||||
if ((*bot)->lineno < in_region->lineno)
|
||||
continue;
|
||||
|
||||
int linedist = (*bot)->lineno - (*top)->lineno;
|
||||
|
||||
if (linedist >= 2) {
|
||||
*top = (*top)->next;
|
||||
*bot = (*bot)->prev;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*top = was_top;
|
||||
*bot = was_bot;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Search, starting from the current position, for any of the two characters
|
||||
* in bracket_pair. If reverse is TRUE, search backwards, otherwise forwards.
|
||||
* Return TRUE when one of the brackets was found, and FALSE otherwise. */
|
||||
@ -997,8 +1083,7 @@ int find_matching_bracket_pos(linestruct **line, size_t *xpos)
|
||||
bool reversed;
|
||||
/* The direction we search. */
|
||||
|
||||
br_ch = mbstrchr(matchbrackets,
|
||||
openfile->current->data + openfile->current_x);
|
||||
br_ch = mbstrchr(matchbrackets, (*line)->data + (*xpos));
|
||||
|
||||
if (br_ch == NULL)
|
||||
return NOT_A_BRACKET;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user