1. Ivan Andrus
  2. sage-mode
  3. Pull requests

Pull requests

#2 Merged at 9e9d405

Add support functionality for structuring code in "sheets" with "blocks" of code.

  1. Johan Rosenkilde

I write Sage code in basically two ways: library-like code and experiment code. Libraries is for code in Sage proper or for my own, more idiosyncratic library of amassed code. For this purpose, sage-mode is already pretty good, in particularly with the function sage-send-buffer.

For experimentation, however, I work similar to how one does in the Notebook: I get simple code creating lots of top-level objects, which are various instances of my library code, and I am interested in results of computations on these. Each such computations almost always span multiple lines of setup and post-processing. For most experiments, I also end up with a few specifically tailored helper-functions. Obviously, I don't want to write too much of such code directly in the sage-shell since I would loose it.

My solution is the following: I put such code in .sheet files and rarely write anything but names of objects directly in the shell.

I have the concept of "blocks", which is similar to one box of code in the Notebook. In source, I delimit these with ###-comment lines (and blank lines for overview). I then have a simple function sage-send-current-block for evaluation, as well as move functions sage-backward-block and sage-forward-block.

I also wrote sage-eval-next-block for when I am standing in the sage shell: it jumps to the last visited .sage/.sheet file, evaluates the current block, and returns to the shell. Since sage-send-current-block moves to the beginning of the next block after evaluation, repeatedly calling this sage-eval-next-block is a convenient way to evaluate several blocks in a row from the same source file.

Comments (11)

  1. Johan Rosenkilde author

    I am intending this pull request as an RFC, so progress and fixes more easily can be discussed. I have also not created or modified a real Emacs package before, so I might have done something stupid. That said, I think the code works as intended.

    Cheers, Johan

  2. Johan Rosenkilde author

    I forgot when I made the pull request, but if this should be added, a short text about it could also be put into the introduction to sage-mode. I can of course also write that.

  3. Ivan Andrus repo owner

    Mentioning it in the intro would be nice so people know they can use it, but that can be a separate pull request if you want.

    I have made some comments on various lines. Overall, it's smaller than I thought it would be. Very nice! I can see this being useful to a lot of people.

    Thanks for contributing!

  4. Johan Rosenkilde author

    Thanks for your detailed feedback - I'm glad you like it, and I'll get on thinking about the issues and we can get to round two.

    I don't consider your reply having taken very long, by the way :-) Also considering that I might now have to wait until the Christmas holidays before I have time to look at it again.

  5. Johan Rosenkilde

    Unfortunately, I didn't get to look at this over Christmas and now I'm quite busy for a few weeks. I just want to let you know that I haven't forgotten about this, and I will get back to it soon.

  6. Johan Rosenkilde author

    Ok, so I looked carefully through your comments.

    You spotted a mistake in the forward/backward code. I'll describe now the behaviour I desire, and your sharp Emacs eye can tell me if I succeeded with the current code:

    • One is "inside" of a block whenever the cursor is not inside a delimiter or just behind the first character of a delimiter.
    • When inside a block, ``sage-backward-block'' should take the cursor behind the first character of the latest delimiter, whose end is before the point. That is, if you're in the middle of a delimiter, go to the delimiter before it.
    • When inside a block, ``sage-forward-block'' should go to the start of the next delimiter. I.e. if you're standing in the middle of a delimiter, go to the beginning of the one after this.
    • When inside a block, ``sage-send-current-block'' will mark from backward-block to forward-block.
    • When just before a delimiter (i.e. "outside a block") sage-backward-block'' goes to the beginning of the previous delimiter.sage-forward-block'' goes to the next. sage-send-current-block'' sends from just before the delimiter we're on and untilsage-forward-block''.

    Due to the above, sage-send-current-block will need a special case: it has to behave differently than sage-backward-block if it is standing on a delimiter.

    I think it is too invasive to override paragraph movement. You might well make a rather long block, and in that case, would want to preserve paragraph moving. I use Evil mode, so "}" is forward paragraph for me (and I use this all the time, also when editing Sage code).

    Can you suggest a different standard binding, more Pure Emacsy®?

    I assume that the paragraph-moving functions should not push the mark? As an Evil user, I use the mark all the time for "history" of we're I've been, but that's not so Emacsy as far as I understand?

  7. Ivan Andrus repo owner

    I merged this and made a few changes. I hope they are okay with you. If not feel free to push back. Thanks for your work and sorry I took so long to get to it.

  8. Johan Rosenkilde author

    Cool, I'm glad you merged it.

    I looked through your changes and some made the code more robust, some more usable (like the args), and some I didn't quite get. Why, for example, do you prefer search-forward-regexp with third argument nil and then manually move the point to max-point, instead of having search-forward-regexp doing it itself?

    Cheers, Johan