Commit 65e6ecb1 authored by David Lawrence Ramsey's avatar David Lawrence Ramsey
Browse files

add DB's pverhaul the tab completion code and a few related functions to

increase efficiency and support multibyte characters; also add a few
miscellaneous tweaks of mine


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2309 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
parent daa533a7
Showing with 331 additions and 503 deletions
+331 -503
......@@ -149,6 +149,15 @@ CVS code -
get the value of totsize in a few more places. Changes to
read_line(), read_file(), do_delete(), do_input(),
get_totals(), and do_cursorpos(). (DLR)
- Overhaul the tab completion code and a few related functions
to increase efficiency and support multibyte characters. New
functions strrchrn() and is_dir(); changes to diralphasort(),
username_tab_completion(), cwd_tab_completion(), input_tab(),
tail(), and striponedir(); removal of append_slash_if_dir()
and check_wildcard_match(). (David Benbennick) DLR: Move the
routine to get the current user's home directory into the new
function get_homedir(), and use it where necessary. Also add
a few miscellaneous tweaks.
- cut.c:
do_cut_text()
- If keep_cutbuffer is FALSE, only blow away the text in the
......
......@@ -41,13 +41,13 @@
/* Return TRUE if the value of c is in byte range, and FALSE
* otherwise. */
bool is_byte(unsigned int c)
bool is_byte(int c)
{
return (c == (unsigned char)c);
return ((unsigned int)c == (unsigned char)c);
}
/* This function is equivalent to isalnum(). */
bool is_alnum_char(unsigned int c)
bool is_alnum_char(int c)
{
return isalnum(c);
}
......@@ -82,7 +82,7 @@ bool is_alnum_wchar(wchar_t wc)
#endif
/* This function is equivalent to isblank(). */
bool is_blank_char(unsigned int c)
bool is_blank_char(int c)
{
return
#ifdef HAVE_ISBLANK
......@@ -130,9 +130,10 @@ bool is_blank_wchar(wchar_t wc)
/* This function is equivalent to iscntrl(), except in that it also
* handles control characters with their high bits set. */
bool is_cntrl_char(unsigned int c)
bool is_cntrl_char(int c)
{
return (0 <= c && c < 32) || (127 <= c && c < 160);
return (-128 <= c && c < -96) || (0 <= c && c < 32) ||
(127 <= c && c < 160);
}
/* This function is equivalent to iscntrl() for multibyte characters,
......@@ -273,7 +274,7 @@ int mb_cur_max(void)
/* Convert the value in chr to a multibyte character with the same
* wide character value as chr. Return the multibyte character and its
* length. */
char *make_mbchar(unsigned int chr, char *chr_mb, int *chr_mb_len)
char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len)
{
assert(chr_mb != NULL && chr_mb_len != NULL);
......@@ -412,7 +413,7 @@ size_t move_mbleft(const char *buf, size_t pos)
#endif
, NULL);
if (pos_prev <= buf_mb_len)
if (pos_prev <= (size_t)buf_mb_len)
break;
pos_prev -= buf_mb_len;
......@@ -760,3 +761,17 @@ size_t mbstrnlen(const char *s, size_t maxlen)
nstrnlen(s, maxlen);
#endif
}
/* Find the one-based position of the last occurrence of character c in
* the first n characters of s. Return 0 if c is not found. */
size_t strrchrn(const char *s, int c, size_t n)
{
assert(n <= strlen(s));
for (s += n - 1; n >= 1; n--, s--) {
if (c == *s)
return n;
}
return 0;
}
This diff is collapsed.
......@@ -183,9 +183,7 @@ bool curses_ended = FALSE; /* Indicates to statusbar() to simply
* write to stderr, since endwin() has
* ended curses mode. */
#ifdef ENABLE_NANORC
char *homedir = NULL; /* $HOME or from /etc/passwd. */
#endif
size_t length_of_list(const shortcut *s)
{
......
......@@ -144,25 +144,23 @@ extern historyheadtype replace_history;
extern bool curses_ended;
#ifdef ENABLE_NANORC
extern char *homedir;
#endif
/* Functions we want available. */
/* Public functions in chars.c. */
bool is_byte(unsigned int c);
bool is_alnum_char(unsigned int c);
bool is_byte(int c);
bool is_alnum_char(int c);
bool is_alnum_mbchar(const char *c);
#ifdef NANO_WIDE
bool is_alnum_wchar(wchar_t wc);
#endif
bool is_blank_char(unsigned int c);
bool is_blank_char(int c);
bool is_blank_mbchar(const char *c);
#ifdef NANO_WIDE
bool is_blank_wchar(wchar_t wc);
#endif
bool is_cntrl_char(unsigned int c);
bool is_cntrl_char(int c);
bool is_cntrl_mbchar(const char *c);
#ifdef NANO_WIDE
bool is_cntrl_wchar(wchar_t wc);
......@@ -174,7 +172,7 @@ wchar_t control_wrep(wchar_t c);
#endif
int mbwidth(const char *c);
int mb_cur_max(void);
char *make_mbchar(unsigned int chr, char *chr_mb, int *chr_mb_len);
char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len);
int parse_mbchar(const char *buf, char *chr
#ifdef NANO_WIDE
, bool *bad_chr
......@@ -207,6 +205,7 @@ size_t mbstrlen(const char *s);
size_t nstrnlen(const char *s, size_t maxlen);
#endif
size_t mbstrnlen(const char *s, size_t maxlen);
size_t strrchrn(const char *s, int c, size_t n);
/* Public functions in color.c. */
#ifdef ENABLE_COLOR
......@@ -287,16 +286,18 @@ int write_marked(const char *name, bool tmp, int append);
int do_writeout(bool exiting);
void do_writeout_void(void);
char *real_dir_from_tilde(const char *buf);
#if !defined(DISABLE_TABCOMP) || !defined(DISABLE_BROWSER)
int diralphasort(const void *va, const void *vb);
#endif
#ifndef DISABLE_TABCOMP
int append_slash_if_dir(char *buf, bool *lastwastab, int *place);
char **username_tab_completion(char *buf, int *num_matches);
char **cwd_tab_completion(char *buf, int *num_matches);
char *input_tab(char *buf, int place, bool *lastwastab, int *newplace,
bool *list);
char **username_tab_completion(const char *buf, size_t *num_matches,
size_t buflen);
char **cwd_tab_completion(const char *buf, size_t *num_matches, size_t
buflen);
char *input_tab(char *buf, size_t *place, bool *lastwastab, bool *list);
#endif
const char *tail(const char *foo);
#ifndef DISABLE_BROWSER
int diralphasort(const void *va, const void *vb);
void free_charptrarray(char **array, size_t len);
void striponedir(char *foo);
int readable_dir(const char *path);
......@@ -531,6 +532,7 @@ int regexec_safe(const regex_t *preg, const char *string, size_t nmatch,
int regexp_bol_or_eol(const regex_t *preg, const char *string);
#endif
int num_of_digits(int n);
void get_homedir(void);
bool parse_num(const char *str, ssize_t *val);
void align(char **strp);
void null_at(char **data, size_t index);
......@@ -560,9 +562,6 @@ void mark_order(const filestruct **top, size_t *top_x, const filestruct
#endif
void get_totals(const filestruct *begin, const filestruct *end, int
*lines, size_t *size);
#ifndef DISABLE_TABCOMP
int check_wildcard_match(const char *text, const char *pattern);
#endif
/* Public functions in winio.c. */
#ifndef NANO_SMALL
......
......@@ -30,7 +30,6 @@
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <pwd.h>
#include <ctype.h>
#include <assert.h>
#include "proto.h"
......@@ -666,18 +665,7 @@ void do_rcfile(void)
lineno = 0;
{
const char *homenv = getenv("HOME");
/* Rely on $HOME, fall back on getpwuid() */
if (homenv == NULL) {
const struct passwd *userage = getpwuid(geteuid());
if (userage != NULL)
homenv = userage->pw_dir;
}
homedir = mallocstrcpy(NULL, homenv);
}
get_homedir();
if (homedir == NULL) {
rcfile_error(N_("I can't find my home directory! Wah!"));
......
......@@ -27,6 +27,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
......@@ -67,6 +68,23 @@ int num_of_digits(int n)
return i;
}
/* Return the user's home directory. We use $HOME, and if that fails,
* we fall back on getpwuid(). */
void get_homedir(void)
{
if (homedir == NULL) {
const char *homenv = getenv("HOME");
if (homenv == NULL) {
const struct passwd *userage = getpwuid(geteuid());
if (userage != NULL)
homenv = userage->pw_dir;
}
homedir = mallocstrcpy(NULL, homenv);
}
}
/* Read a ssize_t from str, and store it in *val (if val is not NULL).
* On error, we return FALSE and don't change *val. Otherwise, we
* return TRUE. */
......@@ -414,105 +432,3 @@ void get_totals(const filestruct *begin, const filestruct *end, int
}
}
}
#ifndef DISABLE_TABCOMP
/*
* Routine to see if a text string is matched by a wildcard pattern.
* Returns TRUE if the text is matched, or FALSE if it is not matched
* or if the pattern is invalid.
* * matches zero or more characters
* ? matches a single character
* [abc] matches 'a', 'b' or 'c'
* \c quotes character c
* Adapted from code written by Ingo Wilken, and
* then taken from sash, Copyright (c) 1999 by David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
* Permission to distribute this code under the GPL has been granted.
*/
int check_wildcard_match(const char *text, const char *pattern)
{
const char *retrypat;
const char *retrytext;
int ch;
int found;
int len;
retrypat = NULL;
retrytext = NULL;
while (*text != '\0' || *pattern != '\0') {
ch = *pattern++;
switch (ch) {
case '*':
retrypat = pattern;
retrytext = text;
break;
case '[':
found = FALSE;
while ((ch = *pattern++) != ']') {
if (ch == '\\')
ch = *pattern++;
if (ch == '\0')
return FALSE;
if (*text == ch)
found = TRUE;
}
len = strlen(text);
if (!found && len != 0) {
return FALSE;
}
if (found) {
if (strlen(pattern) == 0 && len == 1) {
return TRUE;
}
if (len != 0) {
text++;
continue;
}
}
/* fall into next case */
case '?':
if (*text++ == '\0')
return FALSE;
break;
case '\\':
ch = *pattern++;
if (ch == '\0')
return FALSE;
/* fall into next case */
default:
if (*text == ch) {
if (*text != '\0')
text++;
break;
}
if (*text != '\0') {
pattern = retrypat;
text = ++retrytext;
break;
}
return FALSE;
}
if (pattern == NULL)
return FALSE;
}
return TRUE;
}
#endif
......@@ -2530,17 +2530,11 @@ int nanogetstr(bool allow_tabs, const char *buf, const char *def,
#endif
#ifndef DISABLE_TABCOMP
if (allow_tabs) {
int shift = 0;
answer = input_tab(answer, statusbar_x, &tabbed, &shift,
list);
statusbar_xend = strlen(answer);
statusbar_x += shift;
if (statusbar_x > statusbar_xend)
statusbar_x = statusbar_xend;
answer = input_tab(answer, &statusbar_x, &tabbed, list);
statusbar_xend = statusbar_x;
}
#endif
break;
#endif
case NANO_PREVLINE_KEY:
#ifndef NANO_SMALL
if (history_list != NULL) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment