Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

History navigation in notebook #2203

Closed
wants to merge 2 commits into from
Closed

History navigation in notebook #2203

wants to merge 2 commits into from

Conversation

v923z
Copy link
Contributor

@v923z v923z commented Jul 25, 2012

Hi all,

As discussed somewhere on the mailing list (I can dig out the reference, if necessary), I implemented basic history navigation in the notebook. Shift+UpArrow or Shift+DownArrow copies the content of the previous, previous-previous, previous-previous-previous (you get the idea) cells into the current cell.

I would like to emphasize that this works on notebook cells, and not on the kernel history. My reason for this would be that first, this would work without the kernel, so one could use it when, e.g., updating documentation in the notebook, but not having access to the kernel, and second, it would be visually rather confusing, if the we were paging through the kernel history, for the kernel commands are not necessarily executed in the order given in the notebook.

Let me know, if there is interest in this feature, and what should be improved upon.
Cheers,
Zoltán

@ellisonbg
Copy link
Member

Can you check to confirm that these keyboard shortcuts are not used on
any platform/browser combination?

On Wed, Jul 25, 2012 at 11:16 AM, v923z
reply@reply.github.com
wrote:

Hi all,

As discussed somewhere on the mailing list (I can dig out the reference, if necessary), I implemented basic history navigation in the notebook. Shift+UpArrow or Shift+DownArrow copies the content of the previous, previous-previous, previous-previous-previous (you get the idea) cells into the current cell.

I would like to emphasize that this works on notebook cells, and not on the kernel history. My reason for this would be that first, this would work without the kernel, so one could use it when, e.g., updating documentation in the notebook, but not having access to the kernel, and second, it would be visually rather confusing, if the we were paging through the kernel history, for the kernel commands are not necessarily executed in the order given in the notebook.

Let me know, if there is interest in this feature, and what should be improved upon.
Cheers,
Zoltán

You can merge this Pull Request by running:

git pull https://github.com/v923z/ipython master

Or you can view, comment on it, or merge it online at:

#2203

-- Commit Summary --

  • Added history navigation
  • Added history navigation

-- File Changes --

M IPython/frontend/html/notebook/static/js/notebook.js (30)

-- Patch Links --

https://github.com/ipython/ipython/pull/2203.patch
https://github.com/ipython/ipython/pull/2203.diff


Reply to this email directly or view it on GitHub:
#2203

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

I could check firefox and chrome on linux, and they both seem to do what I expect. As far as I remember, shift+pageup, and shift+pagedown are used somewhere, but I don't know where.

@ellisonbg
Copy link
Member

Checking to make sure they do as you expect is not enough in this
case. We have to make sure we didn't clobber some other keyboard
shortcut in the process.

On Wed, Jul 25, 2012 at 11:37 AM, v923z
reply@reply.github.com
wrote:

I could check firefox and chrome on linux, and they both seem to do what I expect. As far as I remember, shift+pageup, and shift+pagedown are used somewhere, but I don't know where.


Reply to this email directly or view it on GitHub:
#2203 (comment)

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

@minrk
Copy link
Member

minrk commented Jul 25, 2012

Shouldn't this be using history_request, rather than getting it from the cells? That would allow it to use the real IPython history, and retrieve inputs from other sessions, and deleted cells.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@minrk I see your point, but it could become really confusing. Basically, you would not have an idea as to which line is going to come up until you actually see it. Also, what about cells that do not concern the kernel, like headings, markdowns and so on?

@takluyver
Copy link
Member

Shift & arrow keys are used to select text with the keyboard.

I'm not sure whether I'd expect it to go through notebook cells or execution history. I'll have to think more about that.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@minrk
Copy link
Member

minrk commented Jul 25, 2012

My main reasoning is selfish: I have many times wanted to get code from my IPython history, but I have not had any need for getting code from one cell to another to be better than conventional copy/paste.

You bring up a good point about multiple cell types - this shouldn't get cross-type content (no markdown in a code cell, etc.), so if we do it this way, it should skip over cells not of matching type.

@takluyver brings up a good point - shift-arrow is used for selecting text, so it must not be used here.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@takluyver That is true, if there is text in the direction of the arrow, i.e., if you are on the first line of a multiline cell, and press Shfit+down. But if you are on the last line, then nothing is going to be selected.

@minrk
Copy link
Member

minrk commented Jul 25, 2012

Then would you rather test against the edges of the text area, or use a different shortcut?

What if a user is selecting the body of the cell with shift-down, and hit it one too many times that would go off the edge? It would be pretty unpleasant if this not only cleared the selection, but replaced the content of the cell.

@ellisonbg
Copy link
Member

I think we need to steer clear of keyboard shortcuts that are already
used - especially common ones. Trying to guess the intension is
dangerous.

On Wed, Jul 25, 2012 at 11:53 AM, Min RK
reply@reply.github.com
wrote:

Then would you rather test against the edges of the text area, or use a different shortcut?

What if a user is selecting the body of the cell with shift-down, and hit it one too many times that would go off the edge? It would be pretty unpleasant if this not only cleared the selection, but replaced the content of the cell.


Reply to this email directly or view it on GitHub:
#2203 (comment)

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@minrk My main reasoning is selfish: I have many times wanted to get code from my IPython history, but I have not had any need for getting code from one cell to another to be better than conventional copy/paste.

Again, I tossed up the idea, but I am not going to fight tooth and nail for the current implementation. I think your point is valid.

... You bring up a good point about multiple cell types - this shouldn't get cross-type content (no markdown in a code cell, etc.), so if we do it this way, it should skip over cells not of matching type.

Right. That hasn't been implemented yet.

... @takluyver brings up a good point - shift-arrow is used for selecting text, so it must not be used here.
Then would you rather test against the edges of the text area, or use a different shortcut?

I am not pressing for this particular shortcut. If we find another one, I am fine with it.

@minrk
Copy link
Member

minrk commented Jul 25, 2012

Great, thanks! Finding safe shortcuts is increasingly difficult.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@ellisonbg Then what about Cntr+Shift+UpArrow or Cntr+Alt+UpArrow?

@ellisonbg
Copy link
Member

Honestly I am fine with any such shortcuts as long as they are 1)
intuitive (using up/down arrows) and 2) not already taken. I am fine
with both of the ones you suggest.

On Wed, Jul 25, 2012 at 11:59 AM, v923z
reply@reply.github.com
wrote:

@ellisonbg Then what about Cntr+Shift+UpArrow or Cntr+Alt+UpArrow?


Reply to this email directly or view it on GitHub:
#2203 (comment)

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

@Carreau
Copy link
Member

Carreau commented Jul 25, 2012

I did not try, but how is the history position reseted to 0 ?
If I remember correctly we want to have modal editor with the ability to move from cell to cell with keyboard.
What would make sens is

  • shotcut -> modal-past-select
  • move to desired cell
  • validate

boom, you are back to the first cell but with content of the selected one.

as for Cntr+Shift+UpArrow/Down the is a shortcut on some laptop Cntr+UpArrow/Down that don't have pageDown/pageUp and with shift, it select as the same time.

This would make me angry, as I often do Ctrl-shift``Left,Up

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@minrk If you think that navigation of the kernel history is more useful, then I would like to suggest that in addition to the content, we print as a comment the input line number on the first line, so that the user has an idea where the line came from. That would also indicate where you are in the history.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

@Carreau There are actually two position indicators, one that checks the position in the history, and another one that should indicate whether you have moved from the cell. If I understand your concern correctly, this has already been taken care of.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

Cntr+Alt+Up pages through the desktops on gnome, so that we can't take. @Carreau says that Cntr+Shift+Up would not work. But I believe, Cntr+M Up is not taken yet, is it?

@minrk
Copy link
Member

minrk commented Jul 25, 2012

I think ^M-UP is safe.

@v923z
Copy link
Contributor Author

v923z commented Jul 25, 2012

Thanks! Then the second issue was whether we should take the kernel history, or the notebook history. You have already put down your vote, but others haven't yet chipped in. Should we wait for feedback on that?

@Carreau
Copy link
Member

Carreau commented Jul 25, 2012

If ^M``up,up,up,up works, we could have 2 bindings for kernel and cell history.
like
^M h``up,up,up,up for kernel
^M c``up,up,up,up for cell

well obviously not c because it's already binded to cut ... but I guess you see the point.
As we also want to refactor the shortcut handeling, what about storing function that should be called in a tree that we walk at each key press after ^mas long as ctrl has not been released, eventually looping on the leaves that are callable to allow quick repeat of actions...

@takluyver
Copy link
Member

I think Ctrl+m,h,up is getting over complicated for the user.

I'm leaning towards Min's position - it's already easy to copy&paste
cells within a notebook, so having execution history is more useful.
Especially if, e.g. you open a Qt console on the same kernel and want
to use a cell you entered there in the notebook.

@v923z
Copy link
Contributor Author

v923z commented Jul 26, 2012

On 07/25/2012 10:36 PM, Thomas Kluyver wrote:

I think Ctrl+m,h,up is getting over complicated for the user.
As it turns out, Ctrl+m h is already taken for the help menu. Only
letters e, f, g, q, r, and z are free in the Ctrl+m top level menu.
I'm leaning towards Min's position - it's already easy to copy&paste
cells within a notebook
Possible? Yes. Easy? I don't quite agree. Or, I would at least say that
at times it is rather awkward. I really feel that the fact that one
doesn't have to scroll to the position of the copied-to-be cell makes
life much simpler.
Especially if, e.g. you open a Qt console on the same kernel and want
to use a cell you entered there in the notebook.
I think there is no question about the usefulness of the kernel history.
What I am trying to argue is that the notebook history would be just as
useful, and we should find a way to accommodate both.

@v923z
Copy link
Contributor Author

v923z commented Jul 26, 2012

@minrk , @Carreau I was trying to go along the lines you suggested, but I can't catch the Cntr-m up or Cntr-m down combination. This is not doing the trick

else if (event.which === 38 && that.control_key_active) {
   // UPARROW: Move up in notebook history

and it seems that the up arrow is escaped somewhere else. Any comments on this?

On a slightly different note, if Cntr-m up could be made to work, then Cntr-m up, Cntr-m down, Cntr-m left, Cntr-m right could handle both the notebook and the kernel history, so both camps could be appeased, while we wouldn't have to sacrifice too much in terms of intuitivity.

@Carreau
Copy link
Member

Carreau commented Jul 26, 2012

did you try both Ctrl-m,Ctrl-Up and Ctrl-m,Up ... if you see the difference.

@v923z
Copy link
Contributor Author

v923z commented Jul 26, 2012

On 07/26/2012 11:03 AM, Bussonnier Matthias wrote:

did you try both Ctrl-m,Ctrl-Up and Ctrl-m,Up ... if you see the difference.
Yes, I have. None of them works, while I know that that.history_position
is true, because I printed it to the console. It is a bit eerie...

@ellisonbg
Copy link
Member

Sounds like the consensus is that we would rather have kernel-level history. @v923z do you think you will implement that in this PR, or should we close this one and open an issue for it?

@v923z
Copy link
Contributor Author

v923z commented Aug 10, 2012

Hi Brian,

I think I could implement it, but really the question is what we would
use for shortcut. I don't see any obvious choice for this at the moment.
If we can pin down the a keybinding for this, I can finish this off. So,
I would say, we should keep this PR open.
Cheers,
Zoltán

On 08/10/2012 04:05 AM, Brian E. Granger wrote:

Sounds like the consensus is that we would rather have kernel-level
history. @v923z https://github.com/v923z do you think you will
implement that in this PR, or should we close this one and open an
issue for it?


Reply to this email directly or view it on GitHub
#2203 (comment).

@v923z
Copy link
Contributor Author

v923z commented Aug 10, 2012

I have found 4 keys (Cntr+m Left, Cntr+m Right, Cntr+m PageDown, Cntr+m PageUp) that work without problems, so both versions of the history navigation could be implemented. However, I don't seem to be able to invoke history_request from the notebook. Shouldn't this return something:

console.log(that.kernel.history_request(content = {'output': false, 'raw': true, 'history_acces_type': 'tail', 'n': 5}));

I couldn't find any pieces of code that actually calls history_request, thus I am not quite sure whether this is the proper way of using this method. If someone could give me a pointer, I could quickly wrap up this PR.

@fperez
Copy link
Member

fperez commented Aug 10, 2012

On Fri, Aug 10, 2012 at 12:51 PM, v923z notifications@github.com wrote:

I couldn't find any pieces of code that actually calls history_request,
thus I am not quite sure whether this is the proper way of using this
method. If someone could give me a pointer, I could quickly wrap up this PR.

It's perfectly possible that this is part of the protocol that we specified
but haven't actually fully tested yet. So beware of cobwebs in this area :)

All to say that it may require a bit of extra work to get that part of the
code into shape, sorry...

@takluyver
Copy link
Member

The Qt console does call history_request when it starts up, so the kernel
side does work. I don't think the notebook uses history_request, though,
and I'm not familiar with the javascript.

@ellisonbg
Copy link
Member

The history request message type has not been implemented on the Javascript
side of things. You will have to consult our message spec:

http://ipython.org/ipython-doc/dev/development/messaging.html#history

And then implement things in kernel.js, looking at how we did execute.

Cheers,

Brian

On Fri, Aug 10, 2012 at 12:51 PM, v923z notifications@github.com wrote:

I have found 4 keys (Cntr+m Left, Cntr+m Right, Cntr+m PageDown, Cntr+m
PageUp) that work without problems, so both versions of the history
navigation could be implemented. However, I don't seem to be able to invoke
history_request from the notebook. Shouldn't this return something:

console.log(that.kernel.history_request(content = {'output': false, 'raw': true, 'history_acces_type': 'tail', 'n': 5}));

I couldn't find any pieces of code that actually calls history_request,
thus I am not quite sure whether this is the proper way of using this
method. If someone could give me a pointer, I could quickly wrap up this PR.


Reply to this email directly or view it on GitHubhttps://github.com//pull/2203#issuecomment-7654896.

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

@ellisonbg
Copy link
Member

There are two methods in kernel.js that already have the right logic:

https://github.com/ipython/ipython/blob/master/IPython/frontend/html/notebook/static/js/kernel.js#L180
https://github.com/ipython/ipython/blob/master/IPython/frontend/html/notebook/static/js/kernel.js#L204

Along with our message dev docs, it should be pretty simply to implement the history request message. You will need to think carefully about what should happen if the request takes some time (the kernel could be busy with other work) or fails.

@v923z
Copy link
Contributor Author

v923z commented Aug 11, 2012

Hi Brian,

There are two methods in kernel.js that already have the right logic:

https://github.com/ipython/ipython/blob/master/IPython/frontend/html/notebook/static/js/kernel.js#L180
https://github.com/ipython/ipython/blob/master/IPython/frontend/html/notebook/static/js/kernel.js#L204

Along with our message dev docs, it should be pretty simply to
implement the history request message. You will need to think
carefully about what should happen if the request takes some time (the
kernel could be busy with other work) or fails.

Thanks for the pointers! I will take a stab at implementing the
javascript side. As for your comment on safeguarding against failures
and timeouts, if such a thing happens, would it be OK to leave the
content of the present cell alone, and only insert a comment line at the
top of it, informing the user that they have to either wait, or try it
once more?
Zoltán

@Carreau
Copy link
Member

Carreau commented Aug 11, 2012

Just use the notification area, it is made (or will be) to alert users.
you can bind to [kernel.busy], and [kernel.idle] event to avoid requesting the kernel while it's busy (see completer for an example)

@v923z
Copy link
Contributor Author

v923z commented Aug 20, 2012

I have tried to implement request_history in kernel.js, but there are a couple of hurdles that I can't make. Basically, this is what I have at the moment

Kernel.prototype.history_request = function (hist_line) {
    // from http://ipython.org/ipython-doc/dev/development/messaging.html#history
   var callbacks = {
        'history_reply': $.proxy(this._handle_history_reply, this)
    }
        var content = {
            output : true,
            raw : true,
            hist_access_type : 'range',
            'start' : hist_line,
            'stop' : hist_line+1
        };
        var msg = this._get_msg("history_request", content);
        this.shell_channel.send(JSON.stringify(msg));
        this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
        return msg.content;
}

Kernel.prototype._handle_history_reply = function (content) {
    // This is quite fishy here...
    console.log(content.history[0][2][0]);
}

and this will print the history on the console. However, I would like to return the history as a string, so that the insertion can be handled in notebook.js. How do I return the string? Also, while the code above worked for the cases I tried, I am not completely convinced that

content.history[0][2][0]

is the best way to retrieve whatever is in the content. I have read http://ipython.org/ipython-doc/dev/development/messaging.html, but it is not clear to me how exactly I should treat whatever is returned by history_request.
Could someone comment on the issues that I raised?

@takluyver
Copy link
Member

You probably want to specify 'output': false in the request, then the
requested cell should be content.history[0][2]. This follows the spec: [0]
to get the first returned cell (you only requested one), and [2] to get the
content from a triple of (session number, cell number, content).

@v923z
Copy link
Contributor Author

v923z commented Aug 20, 2012

Good point, thanks!

@Carreau
Copy link
Member

Carreau commented Sep 28, 2012

@v923z did you make any progress with this PR ?

@v923z
Copy link
Contributor Author

v923z commented Sep 28, 2012

Hi Matthias,

I haven't had too much time recently, but I have already realised that
this might require a bit of tampering with the implementation of
codecell.js, kernel.js, and notebook.js. In other words, I don't see how
this could/should be done without potentially breaking the present code.
What I see as a problem is that I don't see where and how I should return

content.history[0][2][0]

tooltip.js, where object_info_request is called, seem to work along the
same logic, but it is not clear to me what happens with msg_id in the line

var msg_id = IPython.notebook.kernel.object_info_request(re.exec(func), callbacks);

for after that the function ends, so that variable doesn't seem to be
used at all. Am I wrong here?

In any case, I would be willing to work on this, but I just don't know
what the proper logic should be. I can, however, clean up the
client-side history navigation quickly, but as I understand, people want
to have the kernel-side history, too.

Cheers,
Zoltán

On 09/28/2012 05:11 PM, Bussonnier Matthias wrote:

@v923z https://github.com/v923z did you make any progress with this PR ?


Reply to this email directly or view it on GitHub
#2203 (comment).

@Carreau
Copy link
Member

Carreau commented Sep 28, 2012

I dont have the code nearby but i would say it is a leftover from previous
implementation where msg_id was used in the following lines to register the
answer to this request in order to be handle has tooltip request not to be
shown in pager, this is now what 'callback' is for.

Here 'callback' should be the function that get the response as first
argument. By making it a closure, you should be able to keep reference to
the current cell and use the reply to set the content of the cell.

i'll try to have a look.

Matthias.
Le 28 sept. 2012 19:25, "v923z" notifications@github.com a écrit :

Hi Matthias,

I haven't had too much time recently, but I have already realised that
this might require a bit of tampering with the implementation of
codecell.js, kernel.js, and notebook.js. In other words, I don't see how
this could/should be done without potentially breaking the present code.
What I see as a problem is that I don't see where and how I should return

| content.history[0][2][0]|

tooltip.js, where object_info_request is called, seem to work along the
same logic, but it is not clear to me what happens with msg_id in the line

var msg_id =
IPython.notebook.kernel.object_info_request(re.exec(func), callbacks);

for after that the function ends, so that variable doesn't seem to be
used at all. Am I wrong here?

In any case, I would be willing to work on this, but I just don't know
what the proper logic should be. I can, however, clean up the
client-side history navigation quickly, but as I understand, people want
to have the kernel-side history, too.

Cheers,
Zoltán

On 09/28/2012 05:11 PM, Bussonnier Matthias wrote:

@v923z https://github.com/v923z did you make any progress with this
PR ?


Reply to this email directly or view it on GitHub
#2203 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//pull/2203#issuecomment-8984633.

@Carreau
Copy link
Member

Carreau commented Sep 28, 2012

So I came up with that :

    Kernel.prototype.history_request = function (hist_line, callback) { //diff
        // from http://ipython.org/ipython-doc/dev/development/messaging.html#history
        var callbacks = {
            // diff, do not handle response in kernel, but pass a function 
            // that will handle a reply as parameters
            'history_reply': callback 
        }
        var content = {
            output : false,
            raw : true,
            hist_access_type : 'range',
            'start' : 0,
            'stop' : 100,
            session: 0, // diff
        };
        var msg = this._get_msg("history_request", content);
        this.shell_channel.send(JSON.stringify(msg));
        this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
        return msg.content;
    }

Then in Cell.js

Cell.prototype.hct = function (num){
    var that=this; // could be made with $.proxy(function, this)
        IPython.notebook.kernel.history_request(0,
            function(arg){
               that.code_mirror.setValue( 
                arg.history[num][2]
                )
            });
    }

from js console dooing

IPython.notebook.get_cell(y).hct(x)

Set the content of cell y to history x.

This does not of course fail gracefully when history does not exist... etc etc.

@Carreau
Copy link
Member

Carreau commented Sep 28, 2012

Just as a comment, I think the difficulties often came from the way of programming in Python vs JS.
in python you would do :

result = give_me_what_i_want(param)

do stuff with result
and some more

wherease in js you would do

function do_stuff(result):
   do stuff with result
   and some more

i_want_that_give_it_to_function(param, do_stuff)

where in python you would go down the stack, and alway return where things have been called,
in js you wrap every callbacks in a closure to get references to the current object from where you are calling and keep
passing it down. When function are long and already exist you can use $.proxyto set thisat later call time , otherwise, you make it a closure, eventually dooing the var that=this trick.

Does it make sens ?
Hope that help.

@Carreau
Copy link
Member

Carreau commented Sep 28, 2012

and BTW, in

var msg_id = IPython.notebook.kernel.object_info_request(re.exec(func), callbacks);

the var msg_id = part is indeed useless.

@v923z
Copy link
Contributor Author

v923z commented Sep 28, 2012

Hi Matthias,

Thanks for the comments! I will try to clean up the code over the weekend.
Cheers,
Zoltán

On 09/28/2012 08:49 PM, Bussonnier Matthias wrote:

Just as a comment, I think the difficulties often came from the way of
programming in Python vs JS.
in python you would do :

|result = give_me_what_i_want(param)

do stuff with result
and some more
|

wherease in js you would do

|function do_stuff(result):
do stuff with result
and some more

i_want_that_give_it_to_function(param, do_stuff)
|

where in python you would go down the stack, and alway return where
things have been called,
in js you wrap every callbacks in a closure to get references to the
current object from where you are calling and keep
passing it down. When function are long and already exist you can use
|$.proxy|to set |this|at later call time , otherwise, you make it a
closure, eventually dooing the |var that=this| trick.

Does it make sens ?
Hope that help.


Reply to this email directly or view it on GitHub
#2203 (comment).

@ellisonbg
Copy link
Member

I would like to close this PR because of 2 months of inactivity. I have created an issue to track it: #2648.

We would love to see this work continue, please feel free to reopen this PR once things get started again. Any objections to closing this?

@v923z
Copy link
Contributor Author

v923z commented Dec 5, 2012

Actually, I meant to suggest that this should be closed for now. I am not sure I will have the time to clean this up soon, so just go ahead, and close it. I will open a PR, if I have something working.
Thanks,
Zoltán

@ellisonbg
Copy link
Member

OK closing for now.

@ellisonbg ellisonbg closed this Dec 5, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants