<jupyter_start><jupyter_text>ExtendLike its parent, `ipykernel`, `irobotframework` is extensible via a number of mechanisms.  Magics`irobotframework` ships with two magic functions, `%%python module` and `%%tidy`.Any python module, such as a test library, can extend these behaviors with `register_robot_cell_magic`.<jupyter_code>%%python module MagicShout
from irobotframework import register_robot_cell_magic

def magic_shout(code, **kwargs):
    return dict(
        status="ok", payload=[
            dict(source="set_next_input", 
                 text="\n".join(code.upper().split("\n")[1:]), 
                 replace=True)
        ]
    )

register_robot_cell_magic("SHOUT", r"%%SHOUT", magic_shout)<jupyter_output><empty_output><jupyter_text>Now, executing a cell that starts with `%%SHOUT` will update the cell to be all upper case. The above example returns a raw [execution result](https://jupyter-client.readthedocs.io/en/stable/messaging.htmlexecute), and so the code won't actually be executed. Returning a string will execute the code as normal, but not change the code.```robotframework%%SHOUT*** tasks ***unrelenting force    log  fus ro dah```Would yield the following:```robotframework*** TASKS ***UNRELENTING FORCE    LOG  FUS RO DAH```  UnmagicIf, for some reason, you'd like to remove a magic, you can do so with `unregister_robot_cell_magic`:<jupyter_code>%%python module Shush
from irobotframework import unregister_robot_cell_magic

unregister_robot_cell_magic(r"SHOUT")<jupyter_output><empty_output><jupyter_text>Now, you can't `%%SHOUT` anymore.  CompletionsCode completion is provided for a number of Robot Framework features:- magics- table names- importable libraries- suite and test/task settings- locally-defined variables- keywordsThese can be extended, again at the python level, with `register_robot_completion_finder`, which return a tuple of a simple list for more basic implementations and the `_jupyter_types_experimental` type:<jupyter_code>%%python module WuFinder
# typing for good luck
from typing import List, Tuple

from irobotframework.completer import Completer
from irobotframework import register_robot_completion_finder

def complete_wu_tang_discography(
    completer: Completer,
    line: str,
    code: str,
    cursor_pos: int,
    line_cursor: int,
    offset: int,
    history: List[str],
) -> Tuple[List[str], List[dict]]:
    if line.strip().endswith("Wu"):
        matches = [
            f"{line[:line_cursor-2]}{album}"
            for album in [
                "Enter the Wu-Tang (36 Chambers)",
                "Wu-Tang Forever",
                "The W",
                "Iron Flag",
                "8 Diagrams",
                "A Better Tomorrow",
                "Once Upon a Time in Shaolin"
            ]
        ]
        return matches, [
            {
                "start": cursor_pos,
                "end": offset + len(line),
                "type": "wu-tang album",
                "text": m,
            }
            for m in matches
        ],
    return [], []
    

register_robot_completion_finder(complete_wu_tang_discography)<jupyter_output><empty_output><jupyter_text>Now, pressing TAB on a line that ends with `Wu` will give back a number of different options.<jupyter_code>*** Test Case **
Check out an album
    Log  Wu<jupyter_output><empty_output><jupyter_text>PrioritizeAdditionally, you can pass a `before` or `after` completion finder (such as the defaults from `irobotframework.completion_finders`).  UncompleteOnce again, you can `register_robot_completion_finder`:<jupyter_code>%%python module WuFinder
from irobotframework import unregister_robot_completion_finder
import WuFinder
    
unregister_robot_completion_finder(WuFinder.complete_wu_tang_discography)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0933790556581377, 'fraction_numerical': 0.0013189132155104195, 'mean_word_length': 3.6757090012330456, 'pattern_counts': {'":': 4, '<': 21, '<?xml version=': 0, '>': 22, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '521426', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1169, 'n_tokens_neox': 1108, 'n_words': 331, 'path': 'docs/Extending.ipynb', 'repo_name': 'bollwyvl/irobotframework', 'size': '3791'}