2 new very cool features (I think)

From: Jeremy Cowgar <jeremy_cowgar.com>
Date: Thu, 06 Sep 2007 20:27:00 -0400
Angel, List,

I've made a few things thus far, but two of which I think are complete
and very helpful. The first is session support. I made a config
variable, mp.config.save_session = 1 ... It obviously can be 0 and
sessions will not be saved or restored. I had to override the
mp.actions['exit'] procedure to make it all work, here is that function:

mp.actions['exit']    = sub (d) {
    local s, filenames;

    filenames = [];

    while(s = size(mp.docs))
    {
        local doc = mp.docs[mp.active_i];

        if (mp.config.save_session == 1 && doc.name ne "<unnamed>")
            push(filenames, sprintf("%s\t%i\t%i", doc.name, doc.txt.x,
doc.txt.y));

        /* close current document */
        mp.actions.close(doc);

        /* if the size of the list hasn't changed,
           action was cancelled, so don't exit */
        if(s == size(mp.docs)) return;
    }

    /*
       mp.actions['exit'] is being called twice, therefore the first
time thru
       a valid filenames array is being created and the .mp_session file is
       created correctly. However, the second time thru, no files are opened
       and therefore an empty .mp_session file is being created, thus
not really
       saving the session.

       I do not really like this solution of checking the size of filenames
       because one should be able to save an empty session too. However,
I am
       not sure how else to handle this

       I suspect that mp.exit() is calling this function also, but I
cannot find
       the definition of mp.exit() anywhere, so I'm guessing it's an
internal
       function that I cannot duplicate here.
    */

    if (mp.config.save_session == 1 && size(filenames) > 0) {
        local fh;

        if ((fh = open (HOMEDIR ~ "./.mp_session", "w")) != NULL) {
            write (fh, join("\n", filenames));
            close(fh);
        }
    }

    mp.exit();
};

Then at the end of my .mp.mpsl, I added session loading support:

if (mp.config.save_session == 1) {
    local sf;

    if ((sf = open(HOMEDIR ~ "./.mp_session", "r")) != NULL) {
        local l;

        while (l = read(sf)) {
            local data = split ("\t", mp.chomp(l));
            local doc = mp.open(data[0]);
            doc.txt.x = data[1];
            doc.txt.y = data[2];
        }
        close(sf);
    }
}

It's very simple code, but I think very helpful. Anyway. With this, as
you can tell, when loading MP again, the files you were editing are
restored. The only thing that may need help is my comment in the exit
procedure. I am not sure how to get around that function being called
twice and the second time around writing an empty .mp_session file.

Ok, for my second addition. This one I'm pretty excited about. It allows
you to have templates based on mode. It was another easy addition. Boy,
am I liking MP! What I did was instead of loading 1 template file,
.mp_templates, I changed .mp_templates into a directory. I then wrapped
the loading procedure in a foreach loop. It loads first the templates
for the current mode (therefore at the top of the list), it then loads a
global file. So, you can have:

.mp_templates/tcl
.mp_templates/ruby
.mp_templates/global

Or whatever you would like. Therefore, my ruby templates are not
polluting the list while editing Tcl files and visa versa. It's function is:

sub mp.read_templates_file()
/* reads files in the $HOME/.mp_templates directory into mp.templates */
{
    local f, l, k, v, n, d, filenames;

    d = mp.active();
    k = NULL;
    v = NULL;
    n = [];

    filenames = [ d.syntax.id, 'global' ];

    /* reset */
    mp.templates = {};

    foreach (local filename, filenames) {
        if ((f = open(HOMEDIR ~ "./.mp_templates/" ~ filename, "r")) !=
NULL)
        {
            while(l = read(f))
            {
                if(regex("/^%%/", l))
                {
                    /* new template: store previous, if any */
                    if(k && v)
                    {
                        push(n, k);
                        mp.templates[k] = v;
                    }

                    /* strip prefix */
                    k = sregex("/^%%/", mp.chomp(l), NULL);
                    v = NULL;
                }
                else
                {
                    /* add to v */
                    v = v ~ l;
                }
            }

            close(f);
        }
    }

    /* store last value */
    if(k && v)
    {
        push(n, k);
        mp.templates[k] = v;
    }

    /* check to see if we got any templates */
    if (size (mp.templates) == 0) {
        mp.alert("No templates found");
        return (NULL);
    }

    /* returns keys(mp.templates), but in its original order */
    return(n);
}

Now, I also added in a mp.alert() instead of just returning NULL. When I
first tried the Template menu item I thought it was broke. If it would
have told me no templates found or something, then I would have went
searching. With this function, I have a similar problem in that it's
called twice. I'm not sure if it's because I am overriding the functions
or something? Maybe they are in the stack twice so they are getting
called twice?

Ok. I hope that these functions and code are good enough and helpful
enough to make it into MP. I find them very helpful. Oh, I also made a
Select All function, but it was trivial enough that I can just give you
the idea and you'll make it better. Mine has one problem in that the
cursor location is not restored properly. It simply saves cursor x,y,
bof, marks, eof, marks, copy, sets x,y.

Let me know what you think.

Jeremy Cowgar




-- 
To unsubscribe, send mail to mp-unsubscribe_lists.triptico.com.
Received on Fri Sep 07 2007 - 02:27:14 CEST

This archive was generated by hypermail 2.2.0 : Thu Apr 10 2008 - 08:59:26 CEST