add code to partition a filestruct between a set of arbitrary
coordinates; given the coordinates of the beginning and end of the mark, this allows proper and easier handling of saving marked selections, replacing text only in marked selections, and spell-checking marked selections using either the internal or alternate spell checker; do all these using a global partition structure git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2050 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
29f03dcff9
commit
40bdb686aa
12
ChangeLog
12
ChangeLog
|
@ -93,6 +93,18 @@ CVS code -
|
||||||
some functions that use them as a parameter to use size_t as
|
some functions that use them as a parameter to use size_t as
|
||||||
well. Also change some related assertions to handle them.
|
well. Also change some related assertions to handle them.
|
||||||
(David Benbennick and DLR)
|
(David Benbennick and DLR)
|
||||||
|
- Add code to partition a filestruct between a set of arbitrary
|
||||||
|
coordinates. Given the coordinates of the beginning and end
|
||||||
|
of the mark, this allows proper and easier handling of saving
|
||||||
|
marked selections, replacing text only in marked selections
|
||||||
|
(suggested by Joseph Birthisel), and spell-checking marked
|
||||||
|
selections using either the internal or alternate spell
|
||||||
|
checker. Do all these using a global partition structure.
|
||||||
|
New functions partition_filestruct(),
|
||||||
|
unpartition_filestruct(), remove_magicline(), and
|
||||||
|
get_totals(); changes to write_marked(), do_int_spell_fix(),
|
||||||
|
do_alt_speller(), handle_sigwinch(), and do_replace_loop().
|
||||||
|
(DLR)
|
||||||
- files.c:
|
- files.c:
|
||||||
do_insertfile()
|
do_insertfile()
|
||||||
- Simplify by reusing variables whereever possible, and add a
|
- Simplify by reusing variables whereever possible, and add a
|
||||||
|
|
3
TODO
3
TODO
|
@ -10,8 +10,7 @@ For version 1.4:
|
||||||
- Rebindable keys?
|
- Rebindable keys?
|
||||||
- Keystroke to implement "Add next sequence as raw" like vi's ^V.
|
- Keystroke to implement "Add next sequence as raw" like vi's ^V.
|
||||||
[DONE for edit window, needs to be done for statusbar prompt]
|
[DONE for edit window, needs to be done for statusbar prompt]
|
||||||
- Spell check selected text only. [DONE for internal spell checker,
|
- Spell check selected text only. [DONE]
|
||||||
partially done for external spell checker]
|
|
||||||
- Make "To Line" (^W^T) and "Read from Command" (^R^X) reenter their
|
- Make "To Line" (^W^T) and "Read from Command" (^R^X) reenter their
|
||||||
parent menu when their keystroke is entered a second time (^W^T^T and
|
parent menu when their keystroke is entered a second time (^W^T^T and
|
||||||
(^R^X^X) (requires figuring out when to keep cursor position and when
|
(^R^X^X) (requires figuring out when to keep cursor position and when
|
||||||
|
|
57
src/files.c
57
src/files.c
|
@ -1720,49 +1720,36 @@ int write_file(const char *name, int tmp, int append, int nonamechange)
|
||||||
int write_marked(const char *name, int tmp, int append)
|
int write_marked(const char *name, int tmp, int append)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
filestruct *fileagebak = fileage;
|
|
||||||
filestruct *filebotbak = filebot;
|
|
||||||
bool old_modified = ISSET(MODIFIED);
|
bool old_modified = ISSET(MODIFIED);
|
||||||
/* write_file() unsets the MODIFIED flag. */
|
/* write_file() unsets the MODIFIED flag. */
|
||||||
size_t topx;
|
bool added_magicline;
|
||||||
/* The column of the beginning of the mark. */
|
/* Whether we added a magicline after filebot. */
|
||||||
char origchar;
|
filestruct *top, *bot;
|
||||||
/* We replace the character at the end of the mark with '\0'.
|
size_t top_x, bot_x;
|
||||||
* We save the original character, to restore it. */
|
|
||||||
char *origcharloc;
|
|
||||||
/* The location of the character we nulled. */
|
|
||||||
|
|
||||||
/* Set fileage as the top of the mark, and filebot as the bottom. */
|
/* Partition the filestruct so that it contains only the marked
|
||||||
if (current->lineno > mark_beginbuf->lineno ||
|
* text. */
|
||||||
(current->lineno == mark_beginbuf->lineno &&
|
mark_order((const filestruct **)&top, &top_x,
|
||||||
current_x > mark_beginx)) {
|
(const filestruct **)&bot, &bot_x);
|
||||||
fileage = mark_beginbuf;
|
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
||||||
topx = mark_beginx;
|
|
||||||
filebot = current;
|
|
||||||
origcharloc = current->data + current_x;
|
|
||||||
} else {
|
|
||||||
fileage = current;
|
|
||||||
topx = current_x;
|
|
||||||
filebot = mark_beginbuf;
|
|
||||||
origcharloc = mark_beginbuf->data + mark_beginx;
|
|
||||||
}
|
|
||||||
origchar = *origcharloc;
|
|
||||||
*origcharloc = '\0';
|
|
||||||
fileage->data += topx;
|
|
||||||
|
|
||||||
/* If the line at filebot is blank, treat it as the magicline and
|
/* If the line at filebot is blank, treat it as the magicline and
|
||||||
* hence the end of the file. Otherwise, treat the line after
|
* hence the end of the file. Otherwise, add a magicline and treat
|
||||||
* filebot as the end of the file. */
|
* it as the end of the file. */
|
||||||
if (filebot->data[0] != '\0' && filebot->next != NULL)
|
added_magicline = (filebot->data[0] != '\0');
|
||||||
filebot = filebot->next;
|
if (added_magicline)
|
||||||
|
new_magicline();
|
||||||
|
|
||||||
retval = write_file(name, tmp, append, TRUE);
|
retval = write_file(name, tmp, append, TRUE);
|
||||||
|
|
||||||
/* Now restore everything. */
|
/* If we added a magicline, remove it now. */
|
||||||
fileage->data -= topx;
|
if (added_magicline)
|
||||||
*origcharloc = origchar;
|
remove_magicline();
|
||||||
fileage = fileagebak;
|
|
||||||
filebot = filebotbak;
|
/* Unpartition the filestruct so that it contains all the text
|
||||||
|
* again. */
|
||||||
|
unpartition_filestruct(filepart);
|
||||||
|
|
||||||
if (old_modified)
|
if (old_modified)
|
||||||
set_modified();
|
set_modified();
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,11 @@ filestruct *edittop = NULL; /* Pointer to the top of the edit
|
||||||
filestruct *filebot = NULL; /* Last node in the file struct */
|
filestruct *filebot = NULL; /* Last node in the file struct */
|
||||||
filestruct *cutbuffer = NULL; /* A place to store cut text */
|
filestruct *cutbuffer = NULL; /* A place to store cut text */
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
partition *filepart = NULL; /* A place to store a portion of the
|
||||||
|
file struct */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_MULTIBUFFER
|
#ifdef ENABLE_MULTIBUFFER
|
||||||
openfilestruct *open_files = NULL; /* The list of open files */
|
openfilestruct *open_files = NULL; /* The list of open files */
|
||||||
#endif
|
#endif
|
||||||
|
|
222
src/nano.c
222
src/nano.c
|
@ -616,6 +616,93 @@ void free_filestruct(filestruct *src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
/* Partition a filestruct so it begins at (top, top_x) and ends at (bot,
|
||||||
|
* bot_x). */
|
||||||
|
partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||||
|
filestruct *bot, size_t bot_x)
|
||||||
|
{
|
||||||
|
partition *p;
|
||||||
|
assert(top != NULL && bot != NULL);
|
||||||
|
|
||||||
|
/* Initialize the partition. */
|
||||||
|
p = (partition *)nmalloc(sizeof(partition));
|
||||||
|
|
||||||
|
/* Save the top and bottom of the filestruct. */
|
||||||
|
p->fileage = fileage;
|
||||||
|
p->filebot = filebot;
|
||||||
|
|
||||||
|
/* Set the top and bottom of the partition to top and bot. */
|
||||||
|
fileage = top;
|
||||||
|
filebot = bot;
|
||||||
|
|
||||||
|
/* Save the line above the top of the partition, detach the top of
|
||||||
|
* the partition from it, and save the text before top_x in
|
||||||
|
* top_data. */
|
||||||
|
p->top_prev = top->prev;
|
||||||
|
top->prev = NULL;
|
||||||
|
p->top_data = mallocstrncpy(NULL, top->data, top_x + 1);
|
||||||
|
p->top_data[top_x] = '\0';
|
||||||
|
|
||||||
|
/* Save the line below the bottom of the partition, detach the
|
||||||
|
* bottom of the partition from it, and save the text after bot_x in
|
||||||
|
* bot_data. */
|
||||||
|
p->bot_next = bot->next;
|
||||||
|
bot->next = NULL;
|
||||||
|
p->bot_data = mallocstrcpy(NULL, bot->data + bot_x);
|
||||||
|
|
||||||
|
/* Remove all text after bot_x at the bottom of the partition. */
|
||||||
|
null_at(&bot->data, bot_x);
|
||||||
|
|
||||||
|
/* Remove all text before top_x at the top of the partition. */
|
||||||
|
charmove(top->data, top->data + top_x, strlen(top->data) -
|
||||||
|
top_x + 1);
|
||||||
|
align(&top->data);
|
||||||
|
|
||||||
|
/* Return the partition. */
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unpartition a filestruct so it begins at (fileage, 0) and ends at
|
||||||
|
* (filebot, strlen(filebot)) again. */
|
||||||
|
void unpartition_filestruct(partition *p)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
/* Reattach the line above the top of the partition, and restore the
|
||||||
|
* text before top_x from top_data. Free top_data when we're done
|
||||||
|
* with it. */
|
||||||
|
tmp = mallocstrcpy(NULL, fileage->data);
|
||||||
|
fileage->prev = p->top_prev;
|
||||||
|
fileage->prev->next = fileage;
|
||||||
|
fileage->data = charealloc(fileage->data, strlen(p->top_data) +
|
||||||
|
strlen(fileage->data) + 1);
|
||||||
|
strcpy(fileage->data, p->top_data);
|
||||||
|
free(p->top_data);
|
||||||
|
strcat(fileage->data, tmp);
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
/* Reattach the line below the bottom of the partition, and restore
|
||||||
|
* the text after bot_x from bot_data. Free bot_data when we're
|
||||||
|
* done with it. */
|
||||||
|
filebot->next = p->bot_next;
|
||||||
|
filebot->next->prev = filebot;
|
||||||
|
filebot->data = charealloc(filebot->data, strlen(filebot->data) +
|
||||||
|
strlen(p->bot_data) + 1);
|
||||||
|
strcat(filebot->data, p->bot_data);
|
||||||
|
free(p->bot_data);
|
||||||
|
|
||||||
|
/* Restore the top and bottom of the filestruct. */
|
||||||
|
fileage = p->fileage;
|
||||||
|
filebot = p->filebot;
|
||||||
|
|
||||||
|
/* Uninitialize the partition. */
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void renumber_all(void)
|
void renumber_all(void)
|
||||||
{
|
{
|
||||||
filestruct *temp;
|
filestruct *temp;
|
||||||
|
@ -1442,6 +1529,8 @@ bool do_int_spell_fix(const char *word)
|
||||||
#endif
|
#endif
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
bool old_mark_set = ISSET(MARK_ISSET);
|
bool old_mark_set = ISSET(MARK_ISSET);
|
||||||
|
filestruct *top, *bot;
|
||||||
|
size_t top_x, bot_x;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make sure spell-check is case sensitive. */
|
/* Make sure spell-check is case sensitive. */
|
||||||
|
@ -1455,10 +1544,6 @@ bool do_int_spell_fix(const char *word)
|
||||||
/* Make sure spell-check doesn't use regular expressions. */
|
/* Make sure spell-check doesn't use regular expressions. */
|
||||||
UNSET(USE_REGEXP);
|
UNSET(USE_REGEXP);
|
||||||
#endif
|
#endif
|
||||||
#ifndef NANO_SMALL
|
|
||||||
/* Make sure the marking highlight is off during spell-check. */
|
|
||||||
UNSET(MARK_ISSET);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save the current search/replace strings. */
|
/* Save the current search/replace strings. */
|
||||||
search_init_globals();
|
search_init_globals();
|
||||||
|
@ -1469,6 +1554,16 @@ bool do_int_spell_fix(const char *word)
|
||||||
last_search = mallocstrcpy(NULL, word);
|
last_search = mallocstrcpy(NULL, word);
|
||||||
last_replace = mallocstrcpy(NULL, word);
|
last_replace = mallocstrcpy(NULL, word);
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
if (old_mark_set) {
|
||||||
|
mark_order((const filestruct **)&top, &top_x,
|
||||||
|
(const filestruct **)&bot, &bot_x);
|
||||||
|
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
||||||
|
edittop = fileage;
|
||||||
|
UNSET(MARK_ISSET);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Start from the top of the file. */
|
/* Start from the top of the file. */
|
||||||
edittop = fileage;
|
edittop = fileage;
|
||||||
current = fileage;
|
current = fileage;
|
||||||
|
@ -1493,9 +1588,17 @@ bool do_int_spell_fix(const char *word)
|
||||||
do_replace_highlight(FALSE, word);
|
do_replace_highlight(FALSE, word);
|
||||||
|
|
||||||
if (!canceled && strcmp(word, answer) != 0) {
|
if (!canceled && strcmp(word, answer) != 0) {
|
||||||
|
bool added_magicline = (filebot->data[0] != '\0');
|
||||||
|
/* Whether we added a magicline after
|
||||||
|
* filebot. */
|
||||||
|
|
||||||
current_x--;
|
current_x--;
|
||||||
do_replace_loop(word, current, ¤t_x, TRUE,
|
do_replace_loop(word, current, ¤t_x, TRUE,
|
||||||
&canceled);
|
&canceled);
|
||||||
|
|
||||||
|
/* If we added a magicline, remove it now. */
|
||||||
|
if (added_magicline)
|
||||||
|
remove_magicline();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1508,6 +1611,15 @@ bool do_int_spell_fix(const char *word)
|
||||||
free(last_replace);
|
free(last_replace);
|
||||||
last_replace = save_replace;
|
last_replace = save_replace;
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
/* If the mark was on, unpartition the filestruct so that it
|
||||||
|
* contains all the text again, and turn the mark back on. */
|
||||||
|
if (old_mark_set) {
|
||||||
|
unpartition_filestruct(filepart);
|
||||||
|
SET(MARK_ISSET);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Restore where we were. */
|
/* Restore where we were. */
|
||||||
edittop = edittop_save;
|
edittop = edittop_save;
|
||||||
current = current_save;
|
current = current_save;
|
||||||
|
@ -1528,11 +1640,6 @@ bool do_int_spell_fix(const char *word)
|
||||||
if (regexp_set)
|
if (regexp_set)
|
||||||
SET(USE_REGEXP);
|
SET(USE_REGEXP);
|
||||||
#endif
|
#endif
|
||||||
#ifndef NANO_SMALL
|
|
||||||
/* Restore marking highlight. */
|
|
||||||
if (old_mark_set)
|
|
||||||
SET(MARK_ISSET);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return !canceled;
|
return !canceled;
|
||||||
}
|
}
|
||||||
|
@ -1737,13 +1844,23 @@ const char *do_alt_speller(char *tempfile_name)
|
||||||
FILE *f;
|
FILE *f;
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
bool old_mark_set = ISSET(MARK_ISSET);
|
bool old_mark_set = ISSET(MARK_ISSET);
|
||||||
|
bool added_magicline = FALSE;
|
||||||
|
/* Whether we added a magicline after filebot. */
|
||||||
int mbb_lineno_cur = 0;
|
int mbb_lineno_cur = 0;
|
||||||
/* We're going to close the current file, and open the output of
|
/* We're going to close the current file, and open the output of
|
||||||
* the alternate spell command. The line that mark_beginbuf
|
* the alternate spell command. The line that mark_beginbuf
|
||||||
* points to will be freed, so we save the line number and
|
* points to will be freed, so we save the line number and
|
||||||
* restore afterwards. */
|
* restore afterwards. */
|
||||||
|
int old_totlines = totlines;
|
||||||
|
/* Our saved value of totlines, used when we spell-check a
|
||||||
|
* marked selection. */
|
||||||
|
long old_totsize = totsize;
|
||||||
|
/* Our saved value of totsize, used when we spell-check a marked
|
||||||
|
* selection. */
|
||||||
|
|
||||||
if (old_mark_set) {
|
if (old_mark_set) {
|
||||||
|
/* If the mark is on, save the number of the line it starts on,
|
||||||
|
* and then turn the mark off. */
|
||||||
mbb_lineno_cur = mark_beginbuf->lineno;
|
mbb_lineno_cur = mark_beginbuf->lineno;
|
||||||
UNSET(MARK_ISSET);
|
UNSET(MARK_ISSET);
|
||||||
}
|
}
|
||||||
|
@ -1798,24 +1915,77 @@ const char *do_alt_speller(char *tempfile_name)
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
if (old_mark_set) {
|
if (old_mark_set) {
|
||||||
|
filestruct *top, *bot;
|
||||||
|
size_t top_x, bot_x;
|
||||||
|
int part_totlines;
|
||||||
|
long part_totsize;
|
||||||
|
|
||||||
|
/* If the mark was on, partition the filestruct so that it
|
||||||
|
* contains only the marked text, and keep track of whether the
|
||||||
|
* temp file (which should contain the spell-checked marked
|
||||||
|
* text) will have a magicline added when it's reloaded. */
|
||||||
|
mark_order((const filestruct **)&top, &top_x,
|
||||||
|
(const filestruct **)&bot, &bot_x);
|
||||||
|
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
||||||
|
added_magicline = (filebot->data[0] != '\0');
|
||||||
|
|
||||||
|
/* Get the number of lines and the number of characters in the
|
||||||
|
* marked text, and subtract them from the saved values of
|
||||||
|
* totlines and totsize. */
|
||||||
|
get_totals(top, bot, &part_totlines, &part_totsize);
|
||||||
|
old_totlines -= part_totlines;
|
||||||
|
old_totsize -= part_totsize;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Reinitialize the filestruct. */
|
||||||
|
free_filestruct(fileage);
|
||||||
|
global_init(TRUE);
|
||||||
|
|
||||||
|
/* Reload the temp file. Do what load_buffer() would do, except for
|
||||||
|
* making a new buffer for the temp file if multibuffer support is
|
||||||
|
* available. */
|
||||||
|
open_file(tempfile_name, FALSE, &f);
|
||||||
|
read_file(f, tempfile_name);
|
||||||
|
current = fileage;
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
if (old_mark_set) {
|
||||||
|
filestruct *old_top = fileage;
|
||||||
|
|
||||||
|
/* If we added a magicline, remove it now. */
|
||||||
|
if (added_magicline)
|
||||||
|
remove_magicline();
|
||||||
|
|
||||||
|
/* If the mark was on, unpartition the filestruct so that it
|
||||||
|
* contains all the text again. Note that we've replaced the
|
||||||
|
* marked text originally in the partition with the
|
||||||
|
* spell-checked marked text in the temp file. */
|
||||||
|
unpartition_filestruct(filepart);
|
||||||
|
|
||||||
|
/* Renumber starting with the beginning line of the old
|
||||||
|
* partition. Also add the number of lines and characters in
|
||||||
|
* the spell-checked marked text to the saved values of totlines
|
||||||
|
* and totsize, and then make those saved values the actual
|
||||||
|
* values. */
|
||||||
|
renumber(old_top);
|
||||||
|
old_totlines += totlines;
|
||||||
|
old_totsize += totsize;
|
||||||
|
totlines = old_totlines;
|
||||||
|
totsize = old_totsize;
|
||||||
|
|
||||||
|
/* Assign mark_beginbuf to the line where the mark began
|
||||||
|
* before. */
|
||||||
do_gotopos(mbb_lineno_cur, mark_beginx, y_cur, 0);
|
do_gotopos(mbb_lineno_cur, mark_beginx, y_cur, 0);
|
||||||
mark_beginbuf = current;
|
mark_beginbuf = current;
|
||||||
/* In case the line got shorter, assign mark_beginx. */
|
|
||||||
mark_beginx = current_x;
|
|
||||||
SET(MARK_ISSET);
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
/* Only reload the temp file if it isn't a marked selection. */
|
|
||||||
free_filestruct(fileage);
|
|
||||||
global_init(TRUE);
|
|
||||||
|
|
||||||
/* Do what load_buffer() would do, except for making a new
|
/* Assign mark_beginx to the location in mark_beginbuf where the
|
||||||
* buffer for the temp file if multibuffer support is
|
* mark began before, adjusted for any shortening of the
|
||||||
* available. */
|
* line. */
|
||||||
open_file(tempfile_name, FALSE, &f);
|
mark_beginx = current_x;
|
||||||
read_file(f, tempfile_name);
|
|
||||||
current = fileage;
|
/* Turn the mark back on. */
|
||||||
#ifndef NANO_SMALL
|
SET(MARK_ISSET);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2845,6 +3015,10 @@ void handle_sigwinch(int s)
|
||||||
memset(hblank, ' ', COLS);
|
memset(hblank, ' ', COLS);
|
||||||
hblank[COLS] = '\0';
|
hblank[COLS] = '\0';
|
||||||
|
|
||||||
|
/* If we've partitioned the filestruct, unpartition it now. */
|
||||||
|
if (filepart != NULL)
|
||||||
|
unpartition_filestruct(filepart);
|
||||||
|
|
||||||
#ifdef USE_SLANG
|
#ifdef USE_SLANG
|
||||||
/* Slang curses emulation brain damage, part 1: If we just do what
|
/* Slang curses emulation brain damage, part 1: If we just do what
|
||||||
* curses does here, it'll only work properly if the resize made the
|
* curses does here, it'll only work properly if the resize made the
|
||||||
|
|
11
src/nano.h
11
src/nano.h
|
@ -183,6 +183,17 @@ typedef struct openfilestruct {
|
||||||
} openfilestruct;
|
} openfilestruct;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
typedef struct partition {
|
||||||
|
filestruct *fileage;
|
||||||
|
filestruct *top_prev;
|
||||||
|
char *top_data;
|
||||||
|
filestruct *filebot;
|
||||||
|
filestruct *bot_next;
|
||||||
|
char *bot_data;
|
||||||
|
} partition;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct shortcut {
|
typedef struct shortcut {
|
||||||
/* Key values that aren't used should be set to NANO_NO_KEY. */
|
/* Key values that aren't used should be set to NANO_NO_KEY. */
|
||||||
int ctrlval; /* Special sentinel key or control key we want
|
int ctrlval; /* Special sentinel key or control key we want
|
||||||
|
|
|
@ -87,6 +87,7 @@ extern struct stat fileinfo;
|
||||||
extern filestruct *current, *fileage, *edittop, *filebot;
|
extern filestruct *current, *fileage, *edittop, *filebot;
|
||||||
extern filestruct *cutbuffer;
|
extern filestruct *cutbuffer;
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
|
extern partition *filepart;
|
||||||
extern filestruct *mark_beginbuf;
|
extern filestruct *mark_beginbuf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -301,6 +302,11 @@ void unlink_node(const filestruct *fileptr);
|
||||||
void delete_node(filestruct *fileptr);
|
void delete_node(filestruct *fileptr);
|
||||||
filestruct *copy_filestruct(const filestruct *src);
|
filestruct *copy_filestruct(const filestruct *src);
|
||||||
void free_filestruct(filestruct *src);
|
void free_filestruct(filestruct *src);
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||||
|
filestruct *bot, size_t bot_x);
|
||||||
|
void unpartition_filestruct(partition *p);
|
||||||
|
#endif
|
||||||
void renumber_all(void);
|
void renumber_all(void);
|
||||||
void renumber(filestruct *fileptr);
|
void renumber(filestruct *fileptr);
|
||||||
void print1opt(const char *shortflag, const char *longflag, const char
|
void print1opt(const char *shortflag, const char *longflag, const char
|
||||||
|
@ -496,6 +502,9 @@ char *mallocstrcpy(char *dest, const char *src);
|
||||||
char *mallocstrassn(char *dest, char *src);
|
char *mallocstrassn(char *dest, char *src);
|
||||||
void new_magicline(void);
|
void new_magicline(void);
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
|
void remove_magicline(void);
|
||||||
|
void get_totals(const filestruct *begin, const filestruct *end, int
|
||||||
|
*lines, long *size);
|
||||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||||
**bot, size_t *bot_x);
|
**bot, size_t *bot_x);
|
||||||
#endif
|
#endif
|
||||||
|
|
62
src/search.c
62
src/search.c
|
@ -669,8 +669,22 @@ ssize_t do_replace_loop(const char *needle, const filestruct
|
||||||
#endif
|
#endif
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
bool old_mark_set = ISSET(MARK_ISSET);
|
bool old_mark_set = ISSET(MARK_ISSET);
|
||||||
|
filestruct *edittop_save = edittop, *top, *bot;
|
||||||
|
size_t top_x, bot_x;
|
||||||
|
bool right_side_up = FALSE;
|
||||||
|
/* TRUE if (mark_beginbuf, mark_beginx) is the top of the mark,
|
||||||
|
* FALSE if (current, current_x) is. */
|
||||||
|
|
||||||
if (old_mark_set) {
|
if (old_mark_set) {
|
||||||
|
/* If the mark is on, partition the filestruct so that it
|
||||||
|
* contains only the marked text, set right_side_up properly,
|
||||||
|
* set edittop to the top of the marked text, turn the mark off,
|
||||||
|
* and refresh the screen. */
|
||||||
|
mark_order((const filestruct **)&top, &top_x,
|
||||||
|
(const filestruct **)&bot, &bot_x);
|
||||||
|
right_side_up = (bot == current && bot_x == current_x);
|
||||||
|
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
||||||
|
edittop = fileage;
|
||||||
UNSET(MARK_ISSET);
|
UNSET(MARK_ISSET);
|
||||||
edit_refresh();
|
edit_refresh();
|
||||||
}
|
}
|
||||||
|
@ -764,18 +778,33 @@ ssize_t do_replace_loop(const char *needle, const filestruct
|
||||||
length_change = strlen(copy) - strlen(current->data);
|
length_change = strlen(copy) - strlen(current->data);
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
|
/* Keep mark_beginx in sync with the text changes. */
|
||||||
if (current == mark_beginbuf && mark_beginx > current_x) {
|
if (current == mark_beginbuf && mark_beginx > current_x) {
|
||||||
if (mark_beginx < current_x + match_len)
|
/* If the mark was on and (mark_beginbuf, mark_begin_x)
|
||||||
mark_beginx = current_x;
|
* was the top of it, don't change mark_beginx. */
|
||||||
else
|
if (!old_mark_set || !right_side_up) {
|
||||||
mark_beginx += length_change;
|
if (mark_beginx < current_x + match_len)
|
||||||
|
mark_beginx = current_x;
|
||||||
|
else
|
||||||
|
mark_beginx += length_change;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (current == real_current && current_x <= *real_current_x) {
|
/* Keep real_current_x in sync with the text changes. */
|
||||||
if (*real_current_x < current_x + match_len)
|
if (current == real_current && current_x <=
|
||||||
*real_current_x = current_x + match_len;
|
*real_current_x) {
|
||||||
*real_current_x += length_change;
|
#ifndef NANO_SMALL
|
||||||
|
/* If the mark was on and (current, current_x) was the
|
||||||
|
* top of it, don't change real_current_x. */
|
||||||
|
if (!old_mark_set || right_side_up) {
|
||||||
|
#endif
|
||||||
|
if (*real_current_x < current_x + match_len)
|
||||||
|
*real_current_x = current_x + match_len;
|
||||||
|
*real_current_x += length_change;
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the cursor at the last character of the replacement
|
/* Set the cursor at the last character of the replacement
|
||||||
|
@ -806,15 +835,22 @@ ssize_t do_replace_loop(const char *needle, const filestruct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
/* If the mark was on, unpartition the filestruct so that it
|
||||||
|
* contains all the text again, set edittop back to what it was
|
||||||
|
* before, turn the mark back on, and refresh the screen. */
|
||||||
|
if (old_mark_set) {
|
||||||
|
unpartition_filestruct(filepart);
|
||||||
|
edittop = edittop_save;
|
||||||
|
SET(MARK_ISSET);
|
||||||
|
edit_refresh();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If text has been added to the magicline, make a new magicline. */
|
/* If text has been added to the magicline, make a new magicline. */
|
||||||
if (filebot->data[0] != '\0')
|
if (filebot->data[0] != '\0')
|
||||||
new_magicline();
|
new_magicline();
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
|
||||||
if (old_mark_set)
|
|
||||||
SET(MARK_ISSET);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return numreplaced;
|
return numreplaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
src/utils.c
51
src/utils.c
|
@ -441,6 +441,57 @@ void new_magicline(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
|
/* Remove the magicline from filebot, if there is one. */
|
||||||
|
void remove_magicline(void)
|
||||||
|
{
|
||||||
|
if (filebot->data[0] == '\0') {
|
||||||
|
filebot = filebot->prev;
|
||||||
|
free_filestruct(filebot->next);
|
||||||
|
filebot->next = NULL;
|
||||||
|
totlines--;
|
||||||
|
totsize--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the number of lines and the number of characters between
|
||||||
|
* begin and end, and return them in lines and size, respectively. */
|
||||||
|
void get_totals(const filestruct *begin, const filestruct *end, int
|
||||||
|
*lines, long *size)
|
||||||
|
{
|
||||||
|
const filestruct *f;
|
||||||
|
|
||||||
|
if (lines != NULL)
|
||||||
|
*lines = 0;
|
||||||
|
if (size != NULL)
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
|
/* Go through the lines from begin to end->prev, if we can. */
|
||||||
|
for (f = begin; f != NULL && f != end; f = f->next) {
|
||||||
|
/* Count this line. */
|
||||||
|
(*lines)++;
|
||||||
|
|
||||||
|
/* Count the number of characters on this line. */
|
||||||
|
*size += strlen(f->data);
|
||||||
|
|
||||||
|
/* Count the newline if we have one. */
|
||||||
|
if (f->next != NULL)
|
||||||
|
(*size)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go through the line at end, if we can. */
|
||||||
|
if (f != NULL) {
|
||||||
|
/* Count this line. */
|
||||||
|
(*lines)++;
|
||||||
|
|
||||||
|
/* Count the number of characters on this line. */
|
||||||
|
*size += strlen(f->data);
|
||||||
|
|
||||||
|
/* Count the newline if we have one. */
|
||||||
|
if (f->next != NULL)
|
||||||
|
(*size)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set top_x and bot_x to the top and bottom x-coordinates of the mark,
|
/* Set top_x and bot_x to the top and bottom x-coordinates of the mark,
|
||||||
* respectively, based on the locations of top and bot. */
|
* respectively, based on the locations of top and bot. */
|
||||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||||
|
|
Loading…
Reference in New Issue