[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: os x readline support
- From: Asko Kauppi <asko.kauppi@...>
- Date: Fri, 17 Sep 2004 23:20:54 +0300
I noticed the fink Lua 5.0.2 doesn't have command line editing
(readline-like) enabled. This is possibly due to license restrictions
(readline being GPL), but there's a built-in 'editline' library in OS X
that can be used instead.
I feel it would be nice even for the off-the-shelf Lua to support this
library by default, I'll check if I can get the interfacing code
(below) to be under MIT/X11.
-ak
//
// READLINE-DARWIN.C
//
// Readline compatibility, using OS X's built-in editline library.
//
// Adopted from code at:
// http://www.opensource.apple.com/darwinsource/10.3/libedit-3/libedit/readline.c
//
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jaromir Dolecek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <histedit.h> // see 'man editline'
#include <termios.h>
static EditLine* el= NULL;
static History* h= NULL;
static const char* pr= NULL; // prompt (allocated)
static int h_len= 0;
const char* f_prompt( EditLine* e ) { return pr; }
static void rl_initialize(void)
{
HistEvent ev;
int editmode = 1;
struct termios t;
//
// See if we don't really want to run the editor
//
if (tcgetattr(fileno(stdin), &t) != -1 && (t.c_lflag & ECHO) == 0)
editmode= 0;
el= el_init( "" /*procname*/, stdin, stdout, stderr );
if (!editmode) el_set(el, EL_EDITMODE, 0);
h= history_init(); ASSUME( h && el );
history( h, &ev, H_SETSIZE, INT_MAX ); /* unlimited */
h_len= 0;
el_set( el, EL_HIST, history, h );
// for proper prompt printing in readline()
pr= strdup("");
el_set( el, EL_PROMPT, f_prompt );
el_set( el, EL_SIGNAL, 1 );
// Set default mode to "emacs"-style and read setting afterwards
// so this can be overriden
//
el_set( el, EL_EDITOR, "emacs" );
// read settings from configuration file
el_source( el, NULL );
}
char* readline( const char* prompt )
{
HistEvent ev;
int count;
const char* ret;
char* buf= NULL;
if (el==NULL || h==NULL) rl_initialize();
if (!prompt) prompt = "";
if (strcmp(pr,prompt) != 0)
{ free( (void*)pr ); pr= strdup(prompt); }
ret= el_gets(el, &count);
if (ret && count > 0)
{
int lastidx;
buf= strdup(ret);
lastidx= count-1;
if (buf[lastidx] == '\n')
buf[lastidx]= '\0';
}
history(h, &ev, H_GETSIZE);
h_len= ev.num;
return buf;
}
int add_history( const char* line )
{
HistEvent ev;
ASSUME( h );
(void) history( h, &ev, H_ENTER, line );
if ( history( h, &ev, H_GETSIZE ) == 0 )
h_len= ev.num;
return !(h_len > 0); // 0 if all is okay
}