Hi,

I'm using awesome more than a year, but I never got
into the lua stuff (except for a small widget box).

Yesterday I was playing around with the lua api and realized
that the awesome-client isn't the crown juwel of awesome.

So I made my own. In interaktiv mode you have a history
and multiple lines support. And you can run scripts with
> awc script.lua
or
> cat script.lua  | awc

The output is still whereever you've redirected the output of awesome.

You can compile it with
gcc awc.c liblua.a -lreadline -lncurses -lm -Wl,-E -o awc

It's a lazy and ugly hack, but maybe someone will find it useful, too.

Christian
/***********************************************
* public domain
************************************************/
#include <stdio.h>
#include <string.h>
#include <readline/readline.h>
#include <readline/history.h>

#define lua_c
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

/***********************************************
* funcs stolen from lua.c
************************************************/
static int incomplete (lua_State *L, int status) {
    if (status == LUA_ERRSYNTAX) {
        size_t lmsg;
        const char *msg = lua_tolstring(L, -1, &lmsg);
        const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
        if (strstr(msg, LUA_QL("<eof>")) == tp) {
            lua_pop(L, 1);
            return 1;
        }
    }
    return 0;  
}

static int pushline (lua_State *L, int firstline) {
    char buffer[LUA_MAXINPUT];
    char *b = buffer;
    size_t l;

    if ( isatty(0) )
        if (firstline ) b = readline("awesome> ");
        else b = readline("awesome>> ");
    else b = readline("");
    if (b == 0 ) return 0;

    l = strlen(b);
    if (l > 0 && b[l-1] == '\n')  /* line ends with newline? */
        b[l-1] = '\0';  /* remove it */
    if (firstline && b[0] == '=')  /* first line starts with `=' ? */
        lua_pushfstring(L, "return %s", b+1);  /* change it to `return' */
    else
        lua_pushstring(L, b);
    lua_freeline(L, b);
    return 1;
}


static int loadline (lua_State *L) {
    int status;
    lua_settop(L, 0);
    if (!pushline(L, 1)) return -1;  /* no input */

    for (;;) {  /* repeat until gets a complete line */
        status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");

        if (!incomplete(L, status)) break;  /* cannot try to add lines? */
        if (!pushline(L, 0))  /* no more input? */
            return -1;
        lua_pushliteral(L, "\n");  /* add a new line... */
        lua_insert(L, -2);  /* ...between the two lines */
        lua_concat(L, 3);  /* join them */
    }
    add_history(lua_tostring(L,1));
    return status;
}

static void dotty () {
    int status;

    using_history();

    lua_State *L = lua_open();  /* create state */
    //lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
    luaL_openlibs(L);  /* open libraries */
    //lua_gc(L, LUA_GCRESTART, 0);

    while ((status = loadline(L)) != -1) {
        FILE* f = fopen("/tmp/awc", "w");
        fputs( lua_tostring(L,1) , f);
        fclose(f);
        dbus_send("/tmp/awc");
    }
    lua_settop(L, 0);  /* clear stack */
    fputs("\n", stdout);
    fflush(stdout);
    lua_close(L);
}

/***********************************************
* dbus hack
************************************************/
dbus_send(char *input) {
    char  buf[500];

    /*
    if (tty)
        sprintf(buf, "dbus-send --dest=org.awesome --type=method_call --print-reply / org.awesome.Remote.Eval string:\"%s\" | tail -n +2", input);
    else
    */
    sprintf(buf, "dbus-send --dest=org.awesome --type=method_call --print-reply / org.awesome.Remote.Eval string:\"`cat %s | sed 's/\"/\\\"/g' `\" | tail -n +2", input);

    FILE* f = popen(buf, "w");
    pclose(f);
}

/***********************************************
* main
************************************************/
int main (int argc, char **argv) {

    if(argc > 2) {
        printf("awc: wrong aguments\nusage: awc [filename]\n");
        exit(1);
    }
    if(argc == 1 ) {
        dotty();
    } else {
        dbus_send(argv[1]);
    }
}

Reply via email to