{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "config:details",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Specific configuration details"
        }
      ],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Starting with 9.0, IPython will be able to use LLM providers to suggest code in the terminal. This requires a recent version of prompt_toolkit in order to allow multiline suggestions. There are currently a number of limitations, and feedback on the API is welcome."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Unlike many of IPython features, this is not enabled by default and requires multiple configuration options to be set to properly work:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "BulletList",
              "__tag": 4053,
              "ordered": false,
              "start": 1,
              "children": [
                {
                  "__type": "ListItem",
                  "__tag": 4054,
                  "children": [
                    {
                      "__type": "Paragraph",
                      "__tag": 4045,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "Set a keybinding to trigger LLM suggestions. Due to terminal limitations    across platforms and emulators, it is difficult to provide a default    keybinding. Note that not all keybindings are availables, in particular all    the "
                        },
                        {
                          "__type": "InlineRole",
                          "__tag": 4003,
                          "value": "Ctrl-Enter",
                          "domain": null,
                          "role": null,
                          "inventory": null
                        },
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": ", "
                        },
                        {
                          "__type": "InlineRole",
                          "__tag": 4003,
                          "value": "Alt-backslash",
                          "domain": null,
                          "role": null,
                          "inventory": null
                        },
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": " and "
                        },
                        {
                          "__type": "InlineRole",
                          "__tag": 4003,
                          "value": "Ctrl-Shift-Enter",
                          "domain": null,
                          "role": null,
                          "inventory": null
                        },
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": " are not available    without integration with your terminal emulator."
                        }
                      ]
                    }
                  ]
                },
                {
                  "__type": "ListItem",
                  "__tag": 4054,
                  "children": [
                    {
                      "__type": "Paragraph",
                      "__tag": 4045,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "Chose a LLM "
                        },
                        {
                          "__type": "InlineRole",
                          "__tag": 4003,
                          "value": "provider",
                          "domain": null,
                          "role": null,
                          "inventory": null
                        },
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": ", usually from Jupyter-AI. This will be the interface    between IPython itself, and the LLM – that may be local or in on a server."
                        }
                      ]
                    }
                  ]
                },
                {
                  "__type": "ListItem",
                  "__tag": 4054,
                  "children": [
                    {
                      "__type": "Paragraph",
                      "__tag": 4045,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "Configure said provider with models, API keys, etc – this will depend on the    provider, and you will have to refer to Jupyter-AI documentation, and/or your    LLM documenatation."
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "While setting up IPython to use a real LLM, you can refer to "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "examples/auto_suggest_llm.py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " that both provide an example of how to set up IPython to use a Fake LLM provider, this can help ensure that the full setup is working before switching to a real LLM provider."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "LLM Suggestions"
        }
      ],
      "level": 1,
      "target": "llm_suggestions"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "You may want to refer on how to setup a keybinding in IPython, but in short you want to bind the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "IPython:auto_suggest.llm_autosuggestion"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " command to a keybinding, and have it active only when the default buffer isi focused, and when using the NavigableSuggestions suggestter (this is the default suggestter, the one that is history and LLM aware). Thus the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "navigable_suggestions & default_buffer_focused"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " filter should be used."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Usually "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Ctrl-Q"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " on macos is an available shortcut, note that is does use "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Ctrl"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and not "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Command"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The following example will bind "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Ctrl-Q"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " to the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "llm_autosuggestion"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " command, with the suggested filter      "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "c.TerminalInteractiveShell.shortcuts = [\n    {\n        \"new_keys\": [\"c-q\"],\n        \"command\": \"IPython:auto_suggest.llm_autosuggestion\",\n        \"new_filter\": \"navigable_suggestions & default_buffer_focused\",\n        \"create\": True,\n    },\n]",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Setup a keybinding"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Set the  "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "TerminalInteractiveShell.llm_provider_class"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " trait to the fully qualified name of the Provider you like, when testing from inside the IPython source tree, you can use "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "\"examples.auto_suggest_llm.ExampleCompletionProvider\""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " This will always stream an extract of the Little Prince by Antoine de Saint-Exupéry, and will not require any API key or real LLM."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In your configuration file adapt the following line to your needs:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "c.TerminalInteractiveShell.llm_provider_class = \"examples.auto_suggest_llm.ExampleCompletionProvider\"",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Choose a LLM provider"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "It the provider needs to be passed parameters at initialization, you can do so by setting the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "llm_construction_kwargs"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " traitlet."
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "c.TerminalInteractiveShell.llm_constructor_kwargs = {\"model\": \"skynet\"}",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This will depdend on the provider you chose, and you will have to refer to the provider documentation."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Extra configuration may be needed by setting environment variables, this will again depend on the provider you chose, and you will have to refer to the provider documentation."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Configure the provider"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The option "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c.TerminalInteractiveShell.llm_prefix_from_history"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " controls the context the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Provider"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " gets when trying to complete. See the help of this options ("
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "ipython --help-all"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ")      "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "Fully Qualifed name of a function that takes an IPython history manager and\nreturn a prefix to pass the llm provider in addition to the current buffer\ntext.\n\nYou can use:\n\n - no_prefix\n - input_history\n\nAs default value. `input_history` (default),  will use all the input history\nof current IPython session",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "LLM Context"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "versionchanged",
          "base_type": "neutral",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "versionchanged 5.0"
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "From IPython 5, prompts are produced as a list of Pygments tokens, which are tuples of (token_type, text). You can customise prompts by writing a method which generates a list of tokens."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "There are four kinds of prompt:"
            }
          ]
        },
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": false,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The "
                    },
                    {
                      "__type": "Strong",
                      "__tag": 4048,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "in"
                        }
                      ]
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " prompt is shown before the first line of input   (default like "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "In [1]:"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ")."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The "
                    },
                    {
                      "__type": "Strong",
                      "__tag": 4048,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "continuation"
                        }
                      ]
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " prompt is shown before further lines of input   (default like "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "...:"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ")."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The "
                    },
                    {
                      "__type": "Strong",
                      "__tag": 4048,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "rewrite"
                        }
                      ]
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " prompt is shown to highlight how special syntax has been   interpreted (default like "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "----->"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ")."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The "
                    },
                    {
                      "__type": "Strong",
                      "__tag": 4048,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "out"
                        }
                      ]
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " prompt is shown before the result from evaluating the input   (default like "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "Out[1]:"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ")."
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Custom prompts are supplied together as a class. If you want to customise only some of the prompts, inherit from "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "IPython.terminal.prompts.Prompts",
              "reference": {
                "__type": "RefInfo",
                "__tag": 4000,
                "module": "IPython",
                "version": "*",
                "kind": "api",
                "path": "IPython.terminal.prompts:Prompts"
              },
              "kind": "module"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", which defines the defaults. The required interface is like this:"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Here is an example Prompt class that will show the current working directory in the input prompt:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "from IPython.terminal.prompts import Prompts, Token\nimport os\n\nclass MyPrompt(Prompts):\n     def in_prompt_tokens(self):\n         return [(Token, os.getcwd()),\n                 (Token.Prompt, ' >>>')]",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To set the new prompt, assign it to the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "prompts"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " attribute of the IPython shell:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "In [2]: ip = get_ipython()\n   ...: ip.prompts = MyPrompt(ip)\n\n/home/bob >>> # it works",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "See "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "IPython/example/utils/cwd_prompt.py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for an example of how to write extensions to customise prompts."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Inside IPython or in a startup script, you can use a custom prompts class by setting "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "get_ipython().prompts"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " to an "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "instance"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " of the class. In configuration, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "TerminalInteractiveShell.prompts_class"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " may be set to either the class object, or a string of its full importable name."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To include invisible terminal control sequences in a prompt, use "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Token.ZeroWidthEscape"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " as the token type. Tokens with this type are ignored when calculating the width."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Colours in the prompt are determined by the token types and the highlighting style; see below for more details. The tokens used in the default prompts are "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Prompt"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "PromptNum"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "OutPrompt"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "OutPromptNum"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Custom Prompts"
        }
      ],
      "level": 1,
      "target": "custom_prompts"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "versionchanged",
          "base_type": "neutral",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "versionchanged 9.0"
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "IPython 9.0 changed almost all of the  color handling, which is now referred to as "
            },
            {
              "__type": "Strong",
              "__tag": 4048,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "themes"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". A Theme can do a bit more than purely colors, as it can handle bold, italic and basically any style that "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "pygments"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " support.  Themes also support a number of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Symbols"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", which allows you to – for example – change the shape of the arrow that mark the current frame and line numbers in the debugger and the tracebacks."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Most of the various IPython options that were used pre 9.0 have been renamed, with a exceptions a few, and most classes  that deal with themes can, now take a "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "theme_name"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " parameter."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To reflect this, the  "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "--colors"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " flag now is also aliased to "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "--theme"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The default themes included are the same, except lowercase, for ease of typing."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "'nocolor', 'neutral', 'linux', 'lightbg'"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", with the addition of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "'pride'"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " to celebrate the inclusively of this project (I welcome update to the pride theme as I'm not a designer myself)."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In addition, the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "--theme=pride"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " theme, is the first to make use of unicode symbols for the traceback separation line, and the debugger and traceback arrow,  as well as making some use of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "bold"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "italic"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " formatting, and not limit itself to the 16 base ANSI colors."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Terminal Colors"
        }
      ],
      "level": 1,
      "target": "termcolour"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "We encourage you to contribute themes, and to distribute them,  while currently you need to modify source code to add a theme, it should be possible to load theme from Json, Yaml, or any other declarative file type."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Since IPython 9.0, most of IPython internal code emit a sequence of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "(Token Type, string)",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", which is fed through pygments, and a theme is mapping from those token types to a style. For example: "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Token.Prompt : '#ansired underline'"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", or "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Token.Filename : 'bg:#A30262"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For simplicity, a theme can be derived from from a pygments style (which will give the basic code highlighting)."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "A theme can also define a few symbols (see the source for how), for example "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "arrow_body"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "arrow_head"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", can help customising line indicators."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Theme details"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "On some systems, the default pager has problems with ANSI colour codes. To configure your default pager to allow these:"
            }
          ]
        },
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": true,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Set the environment PAGER variable to "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "less"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Set the environment LESS variable to "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "-r"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " (plus any other options    you always want to pass to less by default). This tells less to    properly interpret control sequences, which is how color    information is given to your terminal."
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Colors in the pager"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "IPython can integrate with text editors in a number of different ways:"
            }
          ]
        },
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": false,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Editors (such as "
                    },
                    {
                      "__type": "Link",
                      "__tag": 4049,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "(X)Emacs"
                        }
                      ],
                      "url": "http://www.gnu.org/software/emacs/",
                      "title": ""
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ", "
                    },
                    {
                      "__type": "Link",
                      "__tag": 4049,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "vim"
                        }
                      ],
                      "url": "http://www.vim.org/",
                      "title": ""
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " and "
                    },
                    {
                      "__type": "Link",
                      "__tag": 4049,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "TextMate"
                        }
                      ],
                      "url": "http://macromates.com/",
                      "title": ""
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ") can   send code to IPython for execution."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "IPython's "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "%edit"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " magic command can open an editor of choice to edit   a code block."
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The %edit command (and its alias %ed) will invoke the editor set in your environment as "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "EDITOR",
              "domain": null,
              "role": "envvar",
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". If this variable is not set, it will default to vi under Linux/Unix and to notepad under Windows. You may want to set this variable properly and to a lightweight editor which doesn't take too long to start (that is, something other than a new instance of Emacs). This way you can edit multi-line code quickly and with the power of a real editor right inside IPython."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "You can also control the editor by setting "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "TerminalInteractiveShell.editor",
              "domain": null,
              "role": "attr",
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " in "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "ipython_config.py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Editor configuration"
        }
      ],
      "level": 1,
      "target": "editors"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Paul Ivanov's "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "vim-ipython"
                }
              ],
              "url": "https://github.com/ivanov/vim-ipython",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " provides powerful IPython integration for vim."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Vim"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "If you are a dedicated Emacs user, and want to use Emacs when IPython's "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "%edit"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " magic command is called you should set up the Emacs server so that new requests are handled by the original process. This means that almost no time is spent in handling the request (assuming an Emacs process is already running). For this to work, you need to set your EDITOR environment variable to 'emacsclient'. The code below, supplied by Francois Pinard, can then be used in your "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": ".emacs"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " file to enable the server:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "(defvar server-buffer-clients)\n(when (and (fboundp 'server-start) (string-equal (getenv \"TERM\") 'xterm))\n  (server-start)\n  (defun fp-kill-server-with-buffer-routine ()\n    (and server-buffer-clients (server-done)))\n  (add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Thanks to the work of Alexander Schmolck and Prabhu Ramachandran, currently (X)Emacs and IPython get along very well in other ways."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "With (X)EMacs >= 24, You can enable IPython in python-mode with:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "(require 'python)\n(setq python-shell-interpreter \"ipython\")",
          "execution_status": null
        },
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "(X)Emacs"
        },
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "TextMate"
        },
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "vim"
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "(X)Emacs"
        }
      ],
      "level": 2,
      "target": "emacs"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "versionadded",
          "base_type": "neutral",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "versionadded 8.11"
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "You can modify, disable or modify keyboard shortcuts for IPython Terminal using "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "TerminalInteractiveShell.shortcuts",
              "domain": "std",
              "role": "configtrait",
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " traitlet."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The list of shortcuts is available in the Configuring IPython "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "terminal-shortcuts-list",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "config:shortcuts:index"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " section."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Keyboard Shortcuts"
        }
      ],
      "level": 1,
      "target": "custom_keyboard_shortcuts"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "versionchanged",
          "base_type": "neutral",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "versionchanged 5.0"
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Creating custom commands requires adding custom code to a "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "startup file",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "interactive:tutorial"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":      "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "from IPython import get_ipython\nfrom prompt_toolkit.enums import DEFAULT_BUFFER\nfrom prompt_toolkit.keys import Keys\nfrom prompt_toolkit.filters import HasFocus, HasSelection, ViInsertMode, EmacsInsertMode\n\nip = get_ipython()\ninsert_mode = ViInsertMode() | EmacsInsertMode()\n\ndef insert_unexpected(event):\n    buf = event.current_buffer\n    buf.insert_text('The Spanish Inquisition')\n# Register the shortcut if IPython is using prompt_toolkit\nif getattr(ip, 'pt_app', None):\n    registry = ip.pt_app.key_bindings\n    registry.add_binding(Keys.ControlN,\n                     filter=(HasFocus(DEFAULT_BUFFER)\n                             & ~HasSelection()\n                             & insert_mode))(insert_unexpected)",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Here is a second example that bind the key sequence "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "j"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "k"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " to switch to VI input mode to "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Normal"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " when in insert mode     "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "from IPython import get_ipython\nfrom prompt_toolkit.enums import DEFAULT_BUFFER\nfrom prompt_toolkit.filters import HasFocus, ViInsertMode\nfrom prompt_toolkit.key_binding.vi_state import InputMode\n\nip = get_ipython()\n\ndef switch_to_navigation_mode(event):\n   vi_state = event.cli.vi_state\n   vi_state.input_mode = InputMode.NAVIGATION\n\nif getattr(ip, 'pt_app', None):\n   registry = ip.pt_app.key_bindings\n   registry.add_binding(u'j',u'k',\n                        filter=(HasFocus(DEFAULT_BUFFER)\n                                 & ViInsertMode()))(switch_to_navigation_mode)",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For more information on filters and what you can do with the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "event"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " object, "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "see the prompt_toolkit docs"
                }
              ],
              "url": "https://python-prompt-toolkit.readthedocs.io/en/latest/pages/asking_for_input.html#adding-custom-key-bindings",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Advanced configuration"
        }
      ],
      "level": 2,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In the Terminal IPython shell – which by default uses the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "prompt_toolkit"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " interface, the semantic meaning of pressing the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Enter"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " key can be ambiguous. In some case "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Enter"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " should execute code, and in others it should add a new line. IPython uses heuristics to decide whether to execute or insert a new line at cursor position. For example, if we detect that the current code is not valid Python, then the user is likely editing code and the right behavior is to likely to insert a new line. If the current code is a simple statement like "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "ord('*')",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", then the right behavior is likely to execute. Though the exact desired semantics often varies from users to users."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "As the exact behavior of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "Enter"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " is ambiguous, it has been special cased to allow users to completely configure the behavior they like. Hence you can have enter always execute code. If you prefer fancier behavior, you need to get your hands dirty and read the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "prompt_toolkit"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and IPython documentation though. See "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "#10500"
                }
              ],
              "url": "https://github.com/IPython/IPython/pull/10500",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", set the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "c.TerminalInteractiveShell.handle_return"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " option and get inspiration from the following example that only auto-executes the input if it begins with a bang or a modulo character ("
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "!"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " or "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "%"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "). To use the following code, add it to your IPython configuration      "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "def custom_return(shell):\n\n    \"\"\"This function is required by the API. It takes a reference to\n    the shell, which is the same thing `get_ipython()` evaluates to.\n    This function must return a function that handles each keypress\n    event. That function, named `handle` here, references `shell`\n    by closure.\"\"\"\n\n    def handle(event):\n\n        \"\"\"This function is called each time `Enter` is pressed,\n        and takes a reference to a Prompt Toolkit event object.\n        If the current input starts with a bang or modulo, then\n        the input is executed, otherwise a newline is entered,\n        followed by any spaces needed to auto-indent.\"\"\"\n\n        # set up a few handy references to nested items...\n\n        buffer = event.current_buffer\n        document = buffer.document\n        text = document.text\n\n        if text.startswith('!') or text.startswith('%'): # execute the input...\n\n            buffer.accept_action.validate_and_handle(event.cli, buffer)\n\n        else: # insert a newline with auto-indentation...\n\n            if document.line_count > 1: text = text[:document.cursor_position]\n            indent = shell.check_complete(text)[1]\n            buffer.insert_text('\\n' + indent)\n\n            # if you just wanted a plain newline without any indentation, you\n            # could use `buffer.insert_text('\\n')` instead of the lines above\n\n    return handle\n\nc.TerminalInteractiveShell.handle_return = custom_return",
          "execution_status": null
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Enter to execute"
        }
      ],
      "level": 2,
      "target": null
    }
  ],
  "local_refs": []
}