home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 5
/
DATAFILE_PDCD5.iso
/
utilities
/
p
/
psh
/
c
/
readlines
< prev
next >
Wrap
Text File
|
1995-05-08
|
4KB
|
198 lines
/* vi:tabstop=4:shiftwidth=4:smartindent
*
* readlines.c - Initialise readline and history stuff
*
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <readline.h>
#include <history.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/os.h>
#include "psh.h"
extern char *rl_line_buffer;
extern int rl_point;
extern void rl_delete_text(int start, int end);
extern void rl_insert_text(char *);
extern void rl_begin_undo_group(void);
extern void rl_end_undo_group(void);
/* Grabs the word under the cursor. Returns this in an
* array. The word is deleted from the text, and an
* undo-group started before the deletion. The variable
* rl_point is adjusted to point to the word's start.
* Returns NULL if no word was under the cursor.
*/
static char *extract_word(void)
{
char *s, *e, *t;
static char tmp[MAXLEN];
s = rl_line_buffer+rl_point;
/* If we're on a space or end of line, take one step back.
*/
if ((*s == '\0') || (isspace(*s)))
{
s--;
/* If, after stepping back, we're still on a space, or are
* before the string start, then there's nothing to convert.
*/
if ((s<rl_line_buffer) || (isspace(*s)))
{
return NULL;
}
}
/* Search backwards for the space or string start.
* After this, s points to the first character of the word.
*/
while (!isspace(*s) && (s >= rl_line_buffer)) s--;
s++;
/* Now search forward from the word start, to the
* first space or string end.
* After this, e points to the last character of the word.
*/
e = s;
t = tmp;
while (!isspace(*e) && (*e != '\0')) *t++ = *e++;
e--;
*t = '\0';
/* Start the undo-group
*/
rl_begin_undo_group();
/* Remove the word from the line
*/
rl_delete_text(s-rl_line_buffer, e-rl_line_buffer+1);
/* Adjust the cursor pointer.
*/
rl_point = s-rl_line_buffer;
return tmp;
}
/* Allow old RISC OS cursor key editing
*/
int cursor_on(int count, int key)
{
int retvals[3];
os_byte(4, 0, 0, retvals);
return 0;
}
/* Disallow old RISC OS cursor key editing
*/
int cursor_off(int count, int key)
{
int retvals[3];
os_byte(4, 2, 0, retvals);
os_vdu(13);
rl_forced_update_display();
return 0;
}
/* An additional readline function. This takes the word under
* the cursor and does Unix->RISC OS conversion on it. By default
* it is mapped to Meta-k, though can be remapped in the .inputrc
* by binding the function riscos-name. The function also escapes
* any ! or ^ in the converted name.
*/
int riscos_name(int count, int key)
{
char *w, *k, *p;
char tmp[MAXLEN], tmp2[MAXLEN], tmp3[MAXLEN];
if ((w = extract_word()) != NULL)
{
p = w = strcpy(tmp3, __uname(w, 0));
k = tmp;
while (*w)
{
if ((*w == '^') || (*w == '!'))
{
*k++ = '\\';
}
if ((*w == '~') && !((w > p) && isspace(*(w-1))))
{
strcpy(tmp2, w);
p = strtok(tmp2, " .\t\n\r");
DEBUG(printf("\nGot dirname %s\n", p);rl_refresh_line();)
if (p[1])
{
struct passwd *user;
p++;
user = getpwnam(p);
if (user)
{
w += strlen(p)+1;
strcpy(k, __uname(user->pw_dir, 0));
k += strlen(k);
}
else
{
*k++ = *w++;
}
}
else
{
*k++ = '&';
w++;
}
}
else
{
*k++ = *w++;
}
}
*k = '\0';
rl_insert_text(tmp);
/* End of action
*/
rl_end_undo_group();
}
return 0;
}
/* Initialises the readline stuff and reads in the history
*/
void init_readline(char *me)
{
/* What's my name ?
*/
rl_readline_name = me;
/* Add a function to do Unix->RISC OS name conversions.
* This is mapped to Meta-k, so doing
* cd /usr/local/bin[ESC][k] will change the line
* to
* cd $.usr.local.bin or whatever.
*/
rl_add_defun("riscos-name", riscos_name, META('k'));
/* Copy generates Meta-K, so map this to something which
* does *fx4,0 and so turns cursor editing on.
*/
rl_add_defun("cursor-edit-on", cursor_on, META('K'));
/* Bind Meta-Control-[ (Escape-Escape) to turn RISC OS cursor
* editing off.
*/
rl_add_defun("cursor-edit-off", cursor_off, META(CTRL('[')));
/* Bring in ~/.history
*/
read_history(NULL);
}