Edit IPython cell in an external editor

前端 未结 4 1069
灰色年华
灰色年华 2021-02-03 12:45

It would be great to have a keyboard short-cut in IPython notebook, which would allow to edit the content of the current cell in an external editor (e.g. gvim). Maybe just copy

4条回答
  •  借酒劲吻你
    2021-02-03 13:24

    Building off of the accepted answer by @david-brochart, I've taken his code and wrapped it up into a magic function so now I only need to run the line magic%gvim in a notebook in order to enable editing any cell's contents via Gvim for the entire notebook (and I can reuse the same line magic in any other notebook running on my system).

    If you'd like to do something similar, just create a file named something like my_magic_functions.py inside your ipython startup folder (your ipython startup path is likely similar to ~/.ipython/profile_default/startup) and then put the following code inside that file (and save it):

    import IPython.core.magic as ipym
    from IPython import get_ipython
    
    @ipym.magics_class
    class MareBearMagics(ipym.Magics):
        @ipym.line_magic
        def gvim(self, line):
            cell_text = """
    IPython.keyboard_manager.command_shortcuts.add_shortcut('g', {
        handler : function (event) {
            var input = IPython.notebook.get_selected_cell().get_text();
            var cmd = "f = open('.toto.py', 'w');f.close()";
            if (input != "") {
                cmd = '%%writefile .toto.py\\n' + input;
            }
            IPython.notebook.kernel.execute(cmd);
            cmd = "import os;os.system('gvim .toto.py')";
            IPython.notebook.kernel.execute(cmd);
            return false;
        }}
    );
    
    IPython.keyboard_manager.command_shortcuts.add_shortcut('u', {
        handler : function (event) {
            function handle_output(msg) {
                var ret = msg.content.text;
                IPython.notebook.get_selected_cell().set_text(ret);
            }
            var callback = {'output': handle_output};
            var cmd = "f = open('.toto.py', 'r');print(f.read())";
            IPython.notebook.kernel.execute(cmd, {iopub: callback}, {silent: false});
            return false;
        }}
    );
            """
            ipython = get_ipython()
            ipython.run_cell_magic(
                magic_name='javascript', line=None, cell=cell_text)
            print("Cell contents can now be edited via Gvim. From command mode "
                  "use 'g' to open current cell contents in Gvim. After ':wq' "
                  "from Gvim, use 'u' in command mode to update cell contents.")
    
    
    if __name__ == '__main__':
        get_ipython().register_magics(MareBearMagics)
    

    Now start up your Jupyter notebook kernel, and you should be able to type %gvim% into a cell (and you can use auto-completion to find the new magic command) and then run the cell to enable editing the notebook's cell contents in Gvim. You'll receive an output message that lets you know the magic command took effect:

    Cell contents can now be edited via Gvim. From command mode use 'g' to open current cell contents in Gvim. After ':wq' from Gvim, use 'u' in command mode to update cell contents.

    Thanks to the folks in this stackoverflow question and these as well for giving me the ingredients to pull this together. :-)

    • How to run an IPython magic from a script (or timing a Python script)
    • How do I define custom magics in jupyter?

提交回复
热议问题