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 "prototypes.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
/* strlen */
|
||||||
|
#include <ctype.h>
|
||||||
|
/* isspace */
|
||||||
|
|
||||||
#ifdef ENABLE_FOLDING
|
#ifdef ENABLE_FOLDING
|
||||||
|
|
||||||
@ -80,18 +83,10 @@ bool do_unfold_segments(linestruct *top, linestruct *bot)
|
|||||||
if (top != bot)
|
if (top != bot)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
linestruct *match_line = openfile->current;
|
/* Attempt to find a bracketed region first.
|
||||||
size_t match_x = openfile->current_x;
|
* If not, top is unmodified. */
|
||||||
|
if (!top->folded)
|
||||||
if (!top->folded && !find_matching_bracket_pos(&match_line, &match_x)){
|
find_bracketed_region(openfile->current, &top, &bot);
|
||||||
if (openfile->current->lineno > match_line->lineno) {
|
|
||||||
top = match_line->next;
|
|
||||||
bot = openfile->current->prev;
|
|
||||||
} else {
|
|
||||||
top = openfile->current->next;
|
|
||||||
bot = match_line->prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (top->folded) {
|
if (top->folded) {
|
||||||
unfold_folded_segment(top);
|
unfold_folded_segment(top);
|
||||||
@ -112,35 +107,26 @@ void do_fold_segment(void)
|
|||||||
if (do_unfold_segments(top, bot)) {
|
if (do_unfold_segments(top, bot)) {
|
||||||
return;
|
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)){
|
/* When not selecting multiple lines, try to find bounding
|
||||||
int linedist = openfile->current->lineno - match_line->lineno;
|
* brackets to act as top and bot. */
|
||||||
linedist = linedist < 0 ? -linedist : linedist;
|
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)
|
for (linestruct* line = top;line != bot->next;line = line->next)
|
||||||
line->folded = TRUE;
|
line->folded = TRUE;
|
||||||
|
|
||||||
if (top->lineno < openfile->edittop->lineno &&
|
if (top->lineno < openfile->edittop->lineno &&
|
||||||
bot->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.
|
/* Place the cursor at the start of the fold segment.
|
||||||
* Anywhere else within the segment is invalid. */
|
* Anywhere else within the segment is invalid. */
|
||||||
openfile->current = get_start_of_folded_segment(openfile->current);
|
openfile->current = get_start_of_folded_segment(openfile->current);
|
||||||
|
openfile->mark = NULL;
|
||||||
|
|
||||||
refresh_needed = TRUE;
|
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);
|
void do_gotolinecolumn(void);
|
||||||
#ifndef NANO_TINY
|
#ifndef NANO_TINY
|
||||||
int find_matching_bracket_pos(linestruct **line, size_t *xpos);
|
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 do_find_bracket(void);
|
||||||
void put_or_lift_anchor(void);
|
void put_or_lift_anchor(void);
|
||||||
void to_prev_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
|
#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
|
/* Search, starting from the current position, for any of the two characters
|
||||||
* in bracket_pair. If reverse is TRUE, search backwards, otherwise forwards.
|
* in bracket_pair. If reverse is TRUE, search backwards, otherwise forwards.
|
||||||
* Return TRUE when one of the brackets was found, and FALSE otherwise. */
|
* 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;
|
bool reversed;
|
||||||
/* The direction we search. */
|
/* The direction we search. */
|
||||||
|
|
||||||
br_ch = mbstrchr(matchbrackets,
|
br_ch = mbstrchr(matchbrackets, (*line)->data + (*xpos));
|
||||||
openfile->current->data + openfile->current_x);
|
|
||||||
|
|
||||||
if (br_ch == NULL)
|
if (br_ch == NULL)
|
||||||
return NOT_A_BRACKET;
|
return NOT_A_BRACKET;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user