true beginning of the line. This option is disabled in tiny
mode. Changes to do_home(), nanogetstr(), etc. (DLR;
suggested by Stephan T. Lavavej)
+ - Minor tweaks to the punctuation in some statusbar messages.
+ (DLR)
- files.c:
add_open_file()
- Rearrange the NANO_SMALL #ifdef so that the code to set the
do_writeout()
- Refactor so that no recursion is needed if we try to exit with
a modified file that has no name when TEMP_OPT is set. (DLR)
+ do_browser()
+ - Call check_statblank() instead of blanking the statusbar
+ unconditionally, for consistency. (David Benbennick)
- nano.c:
do_toggle(), finish()
- Call blank_statusbar() and blank_bottombars() to blank out
during wait() and can then call cancel_fork() properly. (DLR)
do_delete()
- Tweak for efficiency. (David Benbennick)
+ do_spell()
+ - Tweak for efficiency. (David Benbennick)
+ - Change the statusbar entries used in cases of failure so that
+ they all display the actual error that occurred. (David
+ Benbennick and DLR)
+ do_int_speller(), do_alt_speller()
+ - Make these functions return const char*'s instead of char*'s.
+ (David Benbennick)
justify_format()
- Remove redundant assignment. (DLR)
do_para_search()
- Remove unneeded edit_update() calls. (David Benbennick)
do_justify()
- - Remove unneeded edit_update() calls. (David Benbennick)
+ - Remove unneeded edit_update() calls, and add a few minor
+ efficiency tweaks. (David Benbennick)
- Simplify an if statement. (DLR)
do_exit()
- Refactor so that no recursion is needed if we try to exit with
since 1.3.0. (David Benbennick)
- utils.c:
is_blank_char()
- - Add new function is_blank_char() as an isblank() equivalent,
- since isblank() is a GNU extension. (DLR)
+ - New function used as an isblank() equivalent, since isblank()
+ is a GNU extension. (DLR)
nstricmp(), nstrnicmp()
- Add extra blank lines for greater readability, and remove
unneeded test for n's being less than zero (since it's already
nstrnicmp(). (DLR) David Benbennick: Tweak for efficiency.
- Include and use only when strcasestr() is unavailable, since
strcasestr() is a GNU extension. (DLR)
+ nstrnlen()
+ - New function used as a strnlen() equivalent, since strnlen()
+ is a GNU extension. (DLR)
- winio.c:
get_verbatim_kbinput()
- Refactor the output in the DEBUG #ifdef. It didn't work
get_escape_seq_kbinput()
- Add proper support for the keypad values and escape sequences
generated by the NumLock glitch. (DLR)
+ get_mouseinput()
+ - Don't ungetch() anything if there's no control key and no meta
+ key defined in the shortcut we clicked. (DLR)
bottombars()
- Don't display any more than MAIN_VISIBLE shortcuts. Adding
justification of the entire file above made the search
shortcut list longer than this and hence made the shortcuts in
it so short as to be almost incomprehensible. (DLR)
+ - Tweak for efficiency and to better handle shorter screen
+ widths. (David Benbennick)
+ - Restructure the if block used for the sentinel key values,
+ dynamically allocate keystr based on the number of columns
+ available, and make sure we can display shortcuts even when
+ the number of available columns is too short for any complete
+ one. (DLR)
+ onekey()
+ - Don't bother padding the displayed shortcuts with spaces.
+ (David Benbennick)
+ - Convert len to a size_t. (DLR)
edit_add()
- Minor cosmetic reformatting. Also remove unused int
searched_later_lines. (DLR)
(David Benbennick)
blank_titlebar()
- New function used to blank the titlebar in topwin. (DLR)
+ blank_statusbar_refresh()
+ - Removed, as it's now unnecessary. (David Benbennick)
+ titlebar()
+ - Overhaul to use display_string() to display the filename, and
+ to better handle shorter screen widths. Also remove
+ now-unneeded wrefresh(topwin) calls. (David Benbennick)
+ DLR: Tweak to reserve enough space for "Modified" in all
+ cases, to make sure that the version message takes up no more
+ more than 1/3 of the available width, and to include a
+ reset_cursor() call so that the cursor is always in the right
+ place.
bottombars()
- Call blank_bottombars() instead of blank_bottomwin(). (David
Benbennick)
+ check_statblank()
+ - Overhaul for efficiency, (David Benbennick) DLR: Add
+ reset_cursor() call to ensure that the cursor is always in the
+ right place.
edit_refresh()
- Remove apparently unneeded leaveok() calls. (David Benbennick)
statusbar()
translations are done after initialization in order to avoid
an error when compiling with -pedantic. (David Benbennick)
- configure.ac:
- - Add tests for isblank() and strcasestr(), and define
- _GNU_SOURCE so that the tests work properly. Increase the
- minimum required autoconf version to 2.54. (DLR)
+ - Add tests for isblank(), strcasestr(), and strnlen(), and
+ define _GNU_SOURCE so that the tests work properly. Increase
+ the minimum required autoconf version to 2.54. (DLR)
- Reformat the test programs so that they aren't packed into
fewer lines than usual, so as to make them easier to read, and
remove unnecessary inclusion of stdio.h in the slang test
esac], [AC_MSG_RESULT(no)])
dnl Checks for functions
-AC_CHECK_FUNCS(snprintf vsnprintf isblank strcasecmp strncasecmp strcasestr)
+AC_CHECK_FUNCS(snprintf vsnprintf isblank strcasecmp strncasecmp strcasestr strnlen)
if test "x$ac_cv_func_snprintf" = "xno" -o "xac_cv_func_vsnprintf" = "xno"
then
AM_PATH_GLIB_2_0(2.0.0,,
/* If NOFOLLOW_SYMLINKS is set, it doesn't make sense to prepend or
* append to a symlink. Here we warn about the contradiction. */
if (ISSET(NOFOLLOW_SYMLINKS) && anyexists && S_ISLNK(lst.st_mode)) {
- statusbar(_("Cannot prepend or append to a symlink with --nofollow set."));
+ statusbar(_("Cannot prepend or append to a symlink with --nofollow set"));
goto cleanup_and_exit;
}
char *new_path;
/* Used by the Go To Directory prompt. */
- blank_statusbar_refresh();
+ check_statblank();
#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
currshortcut = browser_list;
if (errno != ENOENT) {
/* Don't save history when we quit. */
UNSET(HISTORYLOG);
- rcfile_error(_("Unable to open ~/.nano_history file, %s"), strerror(errno));
+ rcfile_error(_("Unable to open ~/.nano_history file: %s"), strerror(errno));
}
free(nanohist);
} else {
if (homenv != NULL || userage != NULL) {
hist = fopen(nanohist, "wb");
if (hist == NULL) {
- rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
+ rcfile_msg(_("Unable to write ~/.nano_history file: %s"), strerror(errno));
} else {
/* set rw only by owner for security ?? */
chmod(nanohist, S_IRUSR | S_IWUSR);
/* write oldest first */
- for (h = search_history.tail ; h->prev ; h = h->prev) {
+ for (h = search_history.tail; h->prev; h = h->prev) {
h->data = charealloc(h->data, strlen(h->data) + 2);
strcat(h->data, "\n");
if (fputs(h->data, hist) == EOF) {
- rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
+ rcfile_msg(_("Unable to write ~/.nano_history file: %s"), strerror(errno));
goto come_from;
}
}
if (fputs("\n", hist) == EOF) {
- rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
+ rcfile_msg(_("Unable to write ~/.nano_history file: %s"), strerror(errno));
goto come_from;
}
- for (h = replace_history.tail ; h->prev ; h = h->prev) {
+ for (h = replace_history.tail; h->prev; h = h->prev) {
h->data = charealloc(h->data, strlen(h->data) + 2);
strcat(h->data, "\n");
if (fputs(h->data, hist) == EOF) {
- rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
+ rcfile_msg(_("Unable to write ~/.nano_history file: %s"), strerror(errno));
goto come_from;
}
}
/* Integrated spell checking using 'spell' program. Return value: NULL
* for normal termination, otherwise the error string. */
-char *do_int_speller(char *tempfile_name)
+const char *do_int_speller(char *tempfile_name)
{
char *read_buff, *read_buff_ptr, *read_buff_word;
size_t pipe_buff_size, read_buff_size, read_buff_read, bytesread;
/* External spell checking. Return value: NULL for normal termination,
* otherwise the error string. */
-char *do_alt_speller(char *tempfile_name)
+const char *do_alt_speller(char *tempfile_name)
{
int alt_spell_status, lineno_cur = current->lineno;
int x_cur = current_x, y_cur = current_y, pww_cur = placewewant;
int do_spell(void)
{
int i;
- char *temp, *spell_msg;
+ char *temp = safe_tempnam(0, "nano.");
+ const char *spell_msg;
- if ((temp = safe_tempnam(0, "nano.")) == NULL) {
- statusbar(_("Could not create a temporary filename: %s"),
- strerror(errno));
+ if (temp == NULL) {
+ statusbar(_("Could not create temp file: %s"), strerror(errno));
return 0;
}
i = write_file(temp, 1, 0, 0);
if (i == -1) {
- statusbar(_("Spell checking failed: unable to write temp file!"));
+ statusbar(_("Unable to write temp file: %s"), strerror(errno));
free(temp);
return 0;
}
add_open_file(1);
#endif
- if (alt_speller != NULL)
- spell_msg = do_alt_speller(temp);
- else
- spell_msg = do_int_speller(temp);
+ spell_msg = alt_speller != NULL ? do_alt_speller(temp) :
+ do_int_speller(temp);
unlink(temp);
free(temp);
if (spell_msg != NULL) {
- statusbar(_("Spell checking failed: %s"), spell_msg);
+ statusbar(_("Spell checking failed: %s: %s"), spell_msg,
+ strerror(errno));
return 0;
- }
+ } else
+ statusbar(_("Finished checking spelling"));
- statusbar(_("Finished checking spelling"));
return 1;
}
#endif /* !DISABLE_SPELLER */
int break_pos;
/* Where we will break the line. */
- indent_len = indent_length(current->data + quote_len) +
- quote_len;
+ indent_len = quote_len + indent_length(current->data +
+ quote_len);
/* justify_format() removes excess spaces from the line, and
* changes tabs to spaces. After calling it, we call
#ifndef NANO_SMALL
if (mark_beginbuf == current->next) {
if (mark_beginx < indent_len + break_pos) {
- mark_beginbuf = current;
+ mark_beginbuf = current;
if (mark_beginx <= indent_len)
mark_beginx = line_len + 1;
else
/* Now get a keystroke and see if it's unjustify; if not, unget the
* keystroke and return. */
-
{
int meta_key;
i = get_kbinput(edit, &meta_key);
/* If it was a mouse click, parse it with do_mouse() and it
* might become the unjustify key. Else give it back to the
* input stream. */
- if (i == KEY_MOUSE)
+ if (i == KEY_MOUSE) {
do_mouse();
- else
- ungetch(i);
- i = get_kbinput(edit, &meta_key);
+ i = get_kbinput(edit, &meta_key);
+ }
#endif
}
cutbuffer->prev->next = cutbuffer;
} else
fileage = cutbuffer;
- cutbuffer = NULL;
last_par_line->next = NULL;
free_filestruct(first_par_line);
mark_beginx = mark_beginx_save;
#endif
flags = flags_save;
- if (!ISSET(MODIFIED)) {
+ if (!ISSET(MODIFIED))
titlebar(NULL);
- wrefresh(topwin);
- }
edit_refresh();
}
cutbuffer = cutbuffer_save;
- blank_statusbar_refresh();
+ /* Note that now cutbottom is invalid, but that's okay. */
+ blank_statusbar();
/* Display the shortcut list with UnCut. */
shortcut_init(0);
display_main_list();
# endif
#endif
-/* If no isblank(), strcasecmp(), strncasecmp(), or strcasestr(), use
- * the versions we have. */
+/* If no isblank(), strcasecmp(), strncasecmp(), strcasestr(), or
+ * strnlen(), use the versions we have. */
#ifndef HAVE_ISBLANK
#define isblank is_blank_char
#endif
#define strcasestr nstristr
#endif
+#ifndef HAVE_STRNLEN
+#define strnlen nstrnlen
+#endif
+
/* Assume ERR is defined as -1. To avoid duplicate case values when
* some key definitions are missing, we have to set all of these, and
* all of the special sentinel values below, to different negative
#endif
#ifndef DISABLE_SPELLER
int do_int_spell_fix(const char *word);
-char *do_int_speller(char *tempfile_name);
-char *do_alt_speller(char *tempfile_name);
+const char *do_int_speller(char *tempfile_name);
+const char *do_alt_speller(char *tempfile_name);
int do_spell(void);
#endif
#if !defined(DISABLE_WRAPPING) && !defined(NANO_SMALL) || !defined(DISABLE_JUSTIFY)
const char *revstristr(const char *haystack, const char *needle, const
char *rev_start);
#endif
+#ifndef HAVE_STRNLEN
+size_t nstrnlen(const char *s, size_t maxlen);
+#endif
const char *strstrwrapper(const char *haystack, const char *needle,
const char *start);
void nperror(const char *s);
void blank_titlebar(void);
void blank_edit(void);
void blank_statusbar(void);
-void blank_statusbar_refresh(void);
void check_statblank(void);
void blank_bottombars(void);
char *display_string(const char *buf, size_t start_col, size_t len);
void set_modified(void);
void statusbar(const char *msg, ...);
void bottombars(const shortcut *s);
-void onekey(const char *keystroke, const char *desc, int len);
+void onekey(const char *keystroke, const char *desc, size_t len);
#ifndef NDEBUG
int check_linenumbers(const filestruct *fileptr);
#endif
/* Calculate the size of the new line. */
#ifdef HAVE_REGEX_H
if (ISSET(USE_REGEXP)) {
- search_match_count = regmatches[0].rm_eo - regmatches[0].rm_so;
+ search_match_count = regmatches[0].rm_eo - regmatches[0].rm_so;
new_line_size = replace_regexp(NULL, 0);
} else {
#endif
}
#endif /* !NANO_SMALL */
+#ifndef HAVE_STRNLEN
+/* This function is equivalent to strnlen(). */
+size_t nstrnlen(const char *s, size_t maxlen)
+{
+ size_t n = 0;
+
+ assert(s != NULL);
+
+ for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
+ ;
+
+ return n;
+}
+#endif
+
/* If we are searching backwards, we will find the last match that
* starts no later than start. Otherwise we find the first match
* starting no earlier than start. If we are doing a regexp search, we
* both. */
if (s->ctrlval != NANO_NO_KEY)
ungetch(s->ctrlval);
- else {
+ else if (s->ctrlval != NANO_NO_KEY) {
ungetch(s->metaval);
ungetch(NANO_CONTROL_3);
}
mvwaddstr(bottomwin, 0, 0, hblank);
}
-void blank_statusbar_refresh(void)
-{
- blank_statusbar();
- wrefresh(bottomwin);
-}
-
void check_statblank(void)
{
if (statblank > 1)
statblank--;
else if (statblank == 1 && !ISSET(CONSTUPDATE)) {
- statblank--;
- blank_statusbar_refresh();
+ statblank = 0;
+ blank_statusbar();
+ wnoutrefresh(bottomwin);
+ reset_cursor();
+ wrefresh(edit);
}
}
void titlebar(const char *path)
{
- int namelen, space;
- const char *what = path;
-
- if (path == NULL)
- what = filename;
+ size_t space;
+ /* The space we have available for display. */
+ size_t verlen = strlen(VERMSG) + 1;
+ /* The length of the version message. */
+ const char *prefix;
+ /* "File:", "Dir:", or "New Buffer". Goes before filename. */
+ size_t prefixlen;
+ /* strlen(prefix) + 1. */
+ const char *state;
+ /* "Modified", "View", or spaces the length of "Modified".
+ * Tells the state of this buffer. */
+ size_t statelen = 0;
+ /* strlen(state) + 1. */
+ char *exppath = NULL;
+ /* The file name, expanded for display. */
+ size_t explen = 0;
+ /* strlen(exppath) + 1. */
+ int newbuffer = FALSE;
+ /* Do we say "New Buffer"? */
+ int dots = FALSE;
+ /* Do we put an ellipsis before the path? */
+
+ assert(path != NULL || filename != NULL);
+ assert(COLS >= 0);
wattron(topwin, A_REVERSE);
blank_titlebar();
- mvwaddnstr(topwin, 0, 2, VERMSG, COLS - 3);
- space = COLS - sizeof(VERMSG) - 23;
+ if (COLS <= 5 || COLS - 5 < verlen)
+ space = 0;
+ else {
+ space = COLS - 5 - verlen;
+ /* Reserve 2/3 of the screen for after the version message. */
+ if (space < COLS - (COLS / 3))
+ space = COLS - (COLS / 3);
+ }
- namelen = strlen(what);
+ if (COLS > 4) {
+ /* The version message should only take up 1/3 of the screen. */
+ mvwaddnstr(topwin, 0, 2, VERMSG, COLS / 3);
+ waddstr(topwin, " ");
+ }
- if (space > 0) {
- if (what[0] == '\0')
- mvwaddnstr(topwin, 0, COLS / 2 - 6, _("New Buffer"),
- COLS / 2 + COLS % 2 - 6);
- else if (namelen > space) {
- if (path == NULL)
- waddstr(topwin, _(" File: ..."));
- else
- waddstr(topwin, _(" DIR: ..."));
- waddstr(topwin, &what[namelen - space]);
- } else {
- if (path == NULL)
- mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1),
- _("File: "));
- else
- mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1),
- _(" DIR: "));
- waddstr(topwin, what);
- }
- } /* If we don't have space, we shouldn't bother */
if (ISSET(MODIFIED))
- mvwaddnstr(topwin, 0, COLS - 11, _(" Modified "), 11);
- else if (ISSET(VIEW_MODE))
- mvwaddnstr(topwin, 0, COLS - 11, _(" View "), 11);
+ state = _("Modified");
+ else if (path == NULL && ISSET(VIEW_MODE))
+ state = _("View");
+ else {
+ if (space > 0)
+ statelen = strnlen(_("Modified"), space - 1) + 1;
+ state = &hblank[COLS - statelen];
+ }
+ statelen = strnlen(state, COLS);
+ /* We need a space before state. */
+ if ((ISSET(MODIFIED) || ISSET(VIEW_MODE)) && statelen < COLS)
+ statelen++;
+
+ assert(space >= 0);
+ if (space == 0 || statelen >= space)
+ goto the_end;
+
+#ifndef DISABLE_BROWSER
+ if (path != NULL)
+ prefix = _("DIR:");
+ else
+#endif
+ if (filename[0] == '\0') {
+ prefix = _("New Buffer");
+ newbuffer = TRUE;
+ } else
+ prefix = _("File:");
+ assert(statelen < space);
+ prefixlen = strnlen(prefix, space - statelen);
+ /* If newbuffer is FALSE, we need a space after prefix. */
+ if (!newbuffer && prefixlen + statelen < space)
+ prefixlen++;
+
+ if (path == NULL)
+ path = filename;
+ if (space > prefixlen + statelen)
+ space -= prefixlen + statelen;
+ else
+ space = 0;
+ /* space is now the room we have for the file name. */
+ if (!newbuffer) {
+ size_t lenpt = strlenpt(path), start_col;
+
+ if (lenpt > space)
+ start_col = actual_x(path, lenpt - space);
+ else
+ start_col = 0;
+ exppath = display_string(path, start_col, space);
+ dots = (lenpt > space);
+ explen = strlen(exppath);
+ }
+
+ if (!dots) {
+ /* There is room for the whole filename, so we center it. */
+ waddnstr(topwin, hblank, (space - explen) / 3);
+ waddnstr(topwin, prefix, prefixlen);
+ if (!newbuffer) {
+ assert(strlen(prefix) + 1 == prefixlen);
+ waddch(topwin, ' ');
+ waddstr(topwin, exppath);
+ }
+ } else {
+ /* We will say something like "File: ...ename". */
+ waddnstr(topwin, prefix, prefixlen);
+ if (space == 0 || newbuffer)
+ goto the_end;
+ waddch(topwin, ' ');
+ waddnstr(topwin, "...", space);
+ if (space <= 3)
+ goto the_end;
+ space -= 3;
+ assert(explen = space + 3);
+ waddnstr(topwin, exppath + 3, space);
+ }
+
+ the_end:
+
+ free(exppath);
+
+ if (COLS <= 1 || statelen >= COLS - 1)
+ mvwaddnstr(topwin, 0, 0, state, COLS);
+ else {
+ assert(COLS - statelen - 2 >= 0);
+ mvwaddch(topwin, 0, COLS - statelen - 2, ' ');
+ mvwaddnstr(topwin, 0, COLS - statelen - 1, state, statelen);
+ }
wattroff(topwin, A_REVERSE);
- wrefresh(topwin);
+ wnoutrefresh(topwin);
reset_cursor();
+ wrefresh(edit);
}
/* If modified is not already set, set it and update titlebar. */
if (!ISSET(MODIFIED)) {
SET(MODIFIED);
titlebar(NULL);
- wrefresh(topwin);
}
}
void bottombars(const shortcut *s)
{
- int i, j, numcols;
- char keystr[9];
- int slen;
+ size_t i, colwidth, slen;
+ char *keystr;
if (ISSET(NO_HELP))
return;
if (s == main_list) {
slen = MAIN_VISIBLE;
- assert(MAIN_VISIBLE <= length_of_list(s));
+ assert(slen <= length_of_list(s));
} else {
slen = length_of_list(s);
- /* Don't show any more shortcuts than the main list does */
+ /* Don't show any more shortcuts than the main list does. */
if (slen > MAIN_VISIBLE)
slen = MAIN_VISIBLE;
}
- /* There will be this many columns of shortcuts */
- numcols = (slen + (slen % 2)) / 2;
+ /* There will be this many characters per column. We need at least
+ * 3 to display anything properly.*/
+ colwidth = COLS / ((slen / 2) + (slen % 2));
+ keystr = charalloc(colwidth);
blank_bottombars();
- for (i = 0; i < numcols; i++) {
- for (j = 0; j <= 1; j++) {
-
- wmove(bottomwin, 1 + j, i * (COLS / numcols));
+ for (i = 0; i < slen; i++, s = s->next) {
+ wmove(bottomwin, 1 + i % 2, (i / 2) * colwidth);
- /* Yucky sentinel values we can't handle a better way */
- if (s->ctrlval != NANO_NO_KEY) {
+ /* Yucky sentinel values we can't handle a better way. */
#ifndef NANO_SMALL
- if (s->ctrlval == NANO_HISTORY_KEY)
- strncpy(keystr, _("Up"), 8);
- else
+ if (s->ctrlval == NANO_HISTORY_KEY)
+ strncpy(keystr, _("Up"), colwidth);
+ else
#endif
- if (s->ctrlval == NANO_CONTROL_SPACE)
- strcpy(keystr, "^ ");
- else if (s->ctrlval == NANO_CONTROL_8)
- strcpy(keystr, "^?");
- else
- sprintf(keystr, "^%c", s->ctrlval + 64);
- } else if (s->metaval != NANO_NO_KEY)
- sprintf(keystr, "M-%c", toupper(s->metaval));
-
- onekey(keystr, s->desc, COLS / numcols);
-
- s = s->next;
- if (s == NULL)
- goto break_completely_out;
- }
+ if (s->ctrlval == NANO_CONTROL_SPACE)
+ strncpy(keystr, "^ ", colwidth);
+ else if (s->ctrlval == NANO_CONTROL_8)
+ strncpy(keystr, "^?", colwidth);
+ /* Normal values. Assume that the shortcut has an equivalent
+ * control key, meta key sequence, or both. */
+ else if (s->ctrlval != NANO_NO_KEY)
+ snprintf(keystr, colwidth, "^%c", s->ctrlval + 64);
+ else if (s->metaval != NANO_NO_KEY)
+ snprintf(keystr, colwidth, "M-%c", toupper(s->metaval));
+
+ onekey(keystr, s->desc, colwidth);
}
- break_completely_out:
- wrefresh(bottomwin);
+ free(keystr);
+
+ wnoutrefresh(bottomwin);
+ reset_cursor();
+ wrefresh(edit);
}
-/* Write a shortcut key to the help area at the bottom of the window.
- * keystroke is e.g. "^G" and desc is e.g. "Get Help".
- * We are careful to write exactly len characters, even if len is
- * very small and keystroke and desc are long. */
-void onekey(const char *keystroke, const char *desc, int len)
+/* Write a shortcut key to the help area at the bottom of the window.
+ * keystroke is e.g. "^G" and desc is e.g. "Get Help". We are careful
+ * to write at most len characters, even if len is very small and
+ * keystroke and desc are long. Note that waddnstr(,,(size_t)-1) adds
+ * the whole string! We do not bother padding the entry with blanks. */
+void onekey(const char *keystroke, const char *desc, size_t len)
{
+ assert(keystroke != NULL && desc != NULL && len >= 0);
wattron(bottomwin, A_REVERSE);
waddnstr(bottomwin, keystroke, len);
wattroff(bottomwin, A_REVERSE);
- len -= strlen(keystroke);
+ len -= strlen(keystroke) + 1;
if (len > 0) {
waddch(bottomwin, ' ');
- len--;
waddnstr(bottomwin, desc, len);
- len -= strlen(desc);
- for (; len > 0; len--)
- waddch(bottomwin, ' ');
}
}
nostr = _("Nn");
allstr = _("Aa");
- /* Remove gettext call for keybindings until we clear the thing
+ /* Remove gettext() call for keybindings until we clear the thing
* up. */
if (!ISSET(NO_HELP)) {
char shortstr[3]; /* Temp string for Y, N, A. */