mirror of
git://git.sv.gnu.org/nano.git
synced 2024-12-29 05:39:55 +03:00
add multibyte character support to help_line_len(), so that UTF-8 help
text is wrapped properly git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2393 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
parent
d456bfa10d
commit
9bd56204ee
20
ChangeLog
20
ChangeLog
@ -99,12 +99,12 @@ CVS code -
|
||||
control_mbrep(), control_wrep(), mbwidth(), mb_cur_max(),
|
||||
make_mbchar(), mbstrlen(), mbstrnlen(), mbstrcasecmp(),
|
||||
mbstrncasecmp(), mbstrcasestr(), and mbrevstrcasestr();
|
||||
changes to help_init(), is_byte() (moved to chars.c),
|
||||
is_blank_char() (moved to chars.c), is_cntrl_char() (moved to
|
||||
chars.c), nstricmp() (renamed nstrcasecmp() and moved to
|
||||
chars.c), nstrnicmp() (renamed nstrncasecmp() and moved to
|
||||
chars.c), nstristr() (renamed nstrcasestr() and moved to
|
||||
chars.c), revstrstr() (moved to chars.c), revstristr()
|
||||
changes to help_init(), break_line(), is_byte() (moved to
|
||||
chars.c), is_blank_char() (moved to chars.c), is_cntrl_char()
|
||||
(moved to chars.c), nstricmp() (renamed nstrcasecmp() and
|
||||
moved to chars.c), nstrnicmp() (renamed nstrncasecmp() and
|
||||
moved to chars.c), nstristr() (renamed nstrcasestr() and moved
|
||||
to chars.c), revstrstr() (moved to chars.c), revstristr()
|
||||
(renamed revstrcasestr() and moved to chars.c), nstrnlen()
|
||||
(moved to chars.c), parse_char() (renamed parse_mbchar() and
|
||||
moved to chars.c), move_left() (renamed move_mbleft() and
|
||||
@ -116,9 +116,9 @@ CVS code -
|
||||
unget_input(), unget_kbinput(), get_input(), parse_kbinput(),
|
||||
unparse_kbinput(), parse_verbatim_kbinput(),
|
||||
do_statusbar_input(), do_statusbar_home(),
|
||||
do_statusbar_verbatim_kbinput(), do_statusbar_output(), and
|
||||
display_string(); removal of buffer_to_keys() and
|
||||
keys_to_buffer(). (DLR)
|
||||
do_statusbar_verbatim_kbinput(), do_statusbar_output(),
|
||||
do_help(), help_line_len(), and display_string(); removal of
|
||||
buffer_to_keys() and keys_to_buffer(). (DLR)
|
||||
- Add -O/--morespace command line option, plus a corresponding
|
||||
Meta-O toggle and a "morespace" rcfile option. When these are
|
||||
used, the normally-unused blank line below the titlebar will
|
||||
@ -188,7 +188,7 @@ CVS code -
|
||||
make whitespace display mode work with multibyte characters,
|
||||
and add a few related documentation updates. New function
|
||||
make_mbstring(); changes to make_mbchar(), make_mbstring(),
|
||||
do_help(), main(), parse_rcfile(), and display_string(). (DLR)
|
||||
main(), parse_rcfile(), display_string(), and do_help(). (DLR)
|
||||
- cut.c:
|
||||
do_cut_text()
|
||||
- If keep_cutbuffer is FALSE, only blow away the text in the
|
||||
|
4
TODO
4
TODO
@ -2,8 +2,8 @@ TODO file (? means the feature may be implemented, but not definitely)
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
For version 1.4:
|
||||
- UTF-8 support. [DONE except for edit window text wrapping, help window
|
||||
text wrapping, and the NO_CONVERT flag.]
|
||||
- UTF-8 support. [DONE except for edit window text wrapping and the
|
||||
NO_CONVERT flag, which should allow editing UTF-8 as raw bytes.]
|
||||
- Support for paragraph searches. [DONE]
|
||||
- Support for justifying the entire file at once. [DONE]
|
||||
- Support for filename searches in the file browser.
|
||||
|
154
src/nano.c
154
src/nano.c
@ -2323,6 +2323,86 @@ void do_spell(void)
|
||||
}
|
||||
#endif /* !DISABLE_SPELLER */
|
||||
|
||||
#if !defined(DISABLE_HELP) || !defined(DISABLE_JUSTIFY)
|
||||
/* We are trying to break a chunk off line. We find the last blank such
|
||||
* that the display length to there is at most goal + 1. If there is no
|
||||
* such blank, and force is TRUE, then we find the first blank. Anyway,
|
||||
* we then take the last blank in that group of blanks. The terminating
|
||||
* '\0' counts as a blank, as does a '\n' if newline is TRUE. */
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool newline, bool
|
||||
force)
|
||||
{
|
||||
ssize_t blank_loc = -1;
|
||||
/* Current tentative return value. Index of the last blank we
|
||||
* found with short enough display width. */
|
||||
ssize_t cur_loc = 0;
|
||||
/* Current index in line. */
|
||||
int line_len;
|
||||
|
||||
assert(line != NULL);
|
||||
|
||||
while (*line != '\0' && goal >= 0) {
|
||||
size_t pos = 0;
|
||||
|
||||
line_len = parse_mbchar(line, NULL, NULL, &pos);
|
||||
|
||||
if (is_blank_mbchar(line) || (newline && *line == '\n')) {
|
||||
blank_loc = cur_loc;
|
||||
|
||||
if (newline && *line == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
goal -= pos;
|
||||
line += line_len;
|
||||
cur_loc += line_len;
|
||||
}
|
||||
|
||||
if (goal >= 0)
|
||||
/* In fact, the whole line displays shorter than goal. */
|
||||
return cur_loc;
|
||||
|
||||
if (blank_loc == -1) {
|
||||
/* No blank was found that was short enough. */
|
||||
if (force) {
|
||||
bool found_blank = FALSE;
|
||||
|
||||
while (*line != '\0') {
|
||||
line_len = parse_mbchar(line, NULL, NULL, NULL);
|
||||
|
||||
if (is_blank_mbchar(line) ||
|
||||
(newline && *line == '\n')) {
|
||||
if (!found_blank)
|
||||
found_blank = TRUE;
|
||||
} else if (found_blank)
|
||||
return cur_loc - line_len;
|
||||
|
||||
line += line_len;
|
||||
cur_loc += line_len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the last blank after blank_loc, if there is one. */
|
||||
line -= cur_loc;
|
||||
line += blank_loc;
|
||||
line_len = parse_mbchar(line, NULL, NULL, NULL);
|
||||
line += line_len;
|
||||
|
||||
while (*line != '\0' && (is_blank_mbchar(line) ||
|
||||
(newline && *line == '\n'))) {
|
||||
line_len = parse_mbchar(line, NULL, NULL, NULL);
|
||||
|
||||
line += line_len;
|
||||
blank_loc += line_len;
|
||||
}
|
||||
|
||||
return blank_loc;
|
||||
}
|
||||
#endif /* !DISABLE_HELP || !DISABLE_JUSTIFY */
|
||||
|
||||
#if !defined(NANO_SMALL) || !defined(DISABLE_JUSTIFY)
|
||||
/* The "indentation" of a line is the whitespace between the quote part
|
||||
* and the non-whitespace of the line. */
|
||||
@ -2759,77 +2839,6 @@ filestruct *backup_lines(filestruct *first_line, size_t par_len, size_t
|
||||
return first_line;
|
||||
}
|
||||
|
||||
/* We are trying to break a chunk off line. We find the last blank such
|
||||
* that the display length to there is at most goal + 1. If there is no
|
||||
* such blank, and force is TRUE, then we find the first blank. Anyway,
|
||||
* we then take the last blank in that group of blanks. The terminating
|
||||
* '\0' counts as a blank. */
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool force)
|
||||
{
|
||||
ssize_t blank_loc = -1;
|
||||
/* Current tentative return value. Index of the last blank we
|
||||
* found with short enough display width. */
|
||||
ssize_t cur_loc = 0;
|
||||
/* Current index in line. */
|
||||
int line_len;
|
||||
|
||||
assert(line != NULL);
|
||||
|
||||
while (*line != '\0' && goal >= 0) {
|
||||
size_t pos = 0;
|
||||
|
||||
line_len = parse_mbchar(line, NULL, NULL, &pos);
|
||||
|
||||
if (is_blank_mbchar(line))
|
||||
blank_loc = cur_loc;
|
||||
|
||||
goal -= pos;
|
||||
line += line_len;
|
||||
cur_loc += line_len;
|
||||
}
|
||||
|
||||
if (goal >= 0)
|
||||
/* In fact, the whole line displays shorter than goal. */
|
||||
return cur_loc;
|
||||
|
||||
if (blank_loc == -1) {
|
||||
/* No blank was found that was short enough. */
|
||||
if (force) {
|
||||
bool found_blank = FALSE;
|
||||
|
||||
while (*line != '\0') {
|
||||
line_len = parse_mbchar(line, NULL, NULL, NULL);
|
||||
|
||||
if (is_blank_mbchar(line)) {
|
||||
if (!found_blank)
|
||||
found_blank = TRUE;
|
||||
} else if (found_blank)
|
||||
return cur_loc - line_len;
|
||||
|
||||
line += line_len;
|
||||
cur_loc += line_len;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to the last blank after blank_loc, if there is one. */
|
||||
line -= cur_loc;
|
||||
line += blank_loc;
|
||||
line_len = parse_mbchar(line, NULL, NULL, NULL);
|
||||
line += line_len;
|
||||
|
||||
while (*line != '\0' && is_blank_mbchar(line)) {
|
||||
line_len = parse_mbchar(line, NULL, NULL, NULL);
|
||||
|
||||
line += line_len;
|
||||
blank_loc += line_len;
|
||||
}
|
||||
|
||||
return blank_loc;
|
||||
}
|
||||
|
||||
/* Find the beginning of the current paragraph if we're in one, or the
|
||||
* beginning of the next paragraph if we're not. Afterwards, save the
|
||||
* quote length and paragraph length in *quote and *par. Return TRUE if
|
||||
@ -3082,7 +3091,8 @@ void do_justify(bool full_justify)
|
||||
/* If this line is too long, try to wrap it to the next line
|
||||
* to make it short enough. */
|
||||
break_pos = break_line(current->data + indent_len,
|
||||
fill - strnlenpt(current->data, indent_len), TRUE);
|
||||
fill - strnlenpt(current->data, indent_len), FALSE,
|
||||
TRUE);
|
||||
|
||||
/* We can't break the line, or don't need to, so get out. */
|
||||
if (break_pos == -1 || break_pos + indent_len == line_len)
|
||||
|
@ -413,6 +413,10 @@ const char *do_int_speller(const char *tempfile_name);
|
||||
const char *do_alt_speller(char *tempfile_name);
|
||||
void do_spell(void);
|
||||
#endif
|
||||
#if !defined(DISABLE_HELP) || !defined(DISABLE_JUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool newline, bool
|
||||
force);
|
||||
#endif
|
||||
#if !defined(NANO_SMALL) || !defined(DISABLE_JUSTIFY)
|
||||
size_t indent_length(const char *line);
|
||||
#endif
|
||||
@ -431,7 +435,6 @@ void do_para_end(bool allow_update);
|
||||
void do_para_end_void(void);
|
||||
filestruct *backup_lines(filestruct *first_line, size_t par_len, size_t
|
||||
quote_len);
|
||||
ssize_t break_line(const char *line, ssize_t goal, bool force);
|
||||
bool find_paragraph(size_t *const quote, size_t *const par);
|
||||
void do_justify(bool full_justify);
|
||||
void do_justify_void(void);
|
||||
@ -680,7 +683,7 @@ void display_main_list(void);
|
||||
void do_cursorpos(bool constant);
|
||||
void do_cursorpos_void(void);
|
||||
#ifndef DISABLE_HELP
|
||||
int help_line_len(const char *ptr);
|
||||
size_t help_line_len(const char *ptr);
|
||||
void do_help(void);
|
||||
#endif
|
||||
void do_replace_highlight(bool highlight_flag, const char *word);
|
||||
|
41
src/winio.c
41
src/winio.c
@ -3826,31 +3826,26 @@ void do_cursorpos_void(void)
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
/* Calculate the next line of help_text, starting at ptr. */
|
||||
int help_line_len(const char *ptr)
|
||||
size_t help_line_len(const char *ptr)
|
||||
{
|
||||
int j = 0;
|
||||
int help_cols = (COLS > 80) ? COLS - 8 : 72;
|
||||
|
||||
while (*ptr != '\n' && *ptr != '\0' && j < COLS - 5) {
|
||||
ptr++;
|
||||
j++;
|
||||
}
|
||||
if (j == COLS - 5) {
|
||||
/* Don't wrap at the first of two spaces following a period. */
|
||||
if (*ptr == ' ' && *(ptr + 1) == ' ')
|
||||
j++;
|
||||
/* Don't print half a word if we've run out of space. */
|
||||
while (*ptr != ' ' && j > 0) {
|
||||
ptr--;
|
||||
j--;
|
||||
}
|
||||
/* A word longer than (COLS - 5) chars just gets broken. */
|
||||
if (j == 0)
|
||||
j = COLS - 5;
|
||||
}
|
||||
/* Try to break the line at (COLS - 8) columns if we have more than
|
||||
* 80 columns, and at 72 columns otherwise. */
|
||||
size_t retval = break_line(ptr, help_cols, TRUE, TRUE);
|
||||
size_t retval_save = retval;
|
||||
|
||||
assert(j >= 0 && j <= COLS - 4 && (j > 0 || *ptr == '\n'));
|
||||
/* Get the length of the entire line up to a null or a newline. */
|
||||
while (*(ptr + retval) != '\0' && *(ptr + retval) != '\n')
|
||||
retval += move_mbright(ptr + retval, 0);
|
||||
|
||||
return j;
|
||||
/* If the entire line doesn't go more than 8 columns beyond where we
|
||||
* tried to break it, we should display it as-is. Otherwise, we
|
||||
* should display it only up to the break. */
|
||||
if (strnlenpt(ptr, retval) > help_cols + 8)
|
||||
retval = retval_save;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Our dynamic, shortcut-list-compliant help function. */
|
||||
@ -3944,8 +3939,6 @@ void do_help(void)
|
||||
blank_edit();
|
||||
}
|
||||
|
||||
assert(COLS > 5);
|
||||
|
||||
/* Calculate where in the text we should be, based on the
|
||||
* page. */
|
||||
for (i = 0; i < line; i++) {
|
||||
@ -3955,7 +3948,7 @@ void do_help(void)
|
||||
}
|
||||
|
||||
for (i = 0; i < editwinrows && *ptr != '\0'; i++) {
|
||||
int j = help_line_len(ptr);
|
||||
size_t j = help_line_len(ptr);
|
||||
|
||||
mvwaddnstr(edit, i, 0, ptr, j);
|
||||
ptr += j;
|
||||
|
Loading…
Reference in New Issue
Block a user