insert_after_symbol
Inserts code after a specified symbol's definition in files. Use to add new classes, functions, methods, fields, or variable assignments by providing the symbol's name path, file location, and content to insert.
Instructions
Inserts the given body/content after the end of the definition of the given symbol (via the symbol's location). A typical use case is to insert a new class, function, method, field or variable assignment.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name_path | Yes | Name path of the symbol after which to insert content (definitions in the `find_symbol` tool apply). | |
| relative_path | Yes | The relative path to the file containing the symbol. | |
| body | Yes | The body/content to be inserted. The inserted code shall begin with the next line after the symbol. |
Implementation Reference
- src/serena/symbol.py:728-742 (handler)Main handler method for insert_after_symbol tool, finds the symbol by name and delegates to insert_after_symbol_at_location.def insert_after_symbol(self, name_path: str, relative_file_path: str, body: str, *, use_same_indentation: bool = True) -> None: """ Inserts content after the symbol with the given name in the given file. """ symbol_candidates = self.find_by_name(name_path, within_relative_path=relative_file_path) if len(symbol_candidates) == 0: raise ValueError(f"No symbol with name {name_path} found in file {relative_file_path}") if len(symbol_candidates) > 1: raise ValueError( f"Found multiple {len(symbol_candidates)} symbols with name {name_path} in file {relative_file_path}. " f"May be an overwritten variable, in which case you can ignore this error. Proceeding with the last one. " f"Found symbols at locations: \n" + json.dumps([s.location.to_dict() for s in symbol_candidates], indent=2) ) symbol = symbol_candidates[-1] return self.insert_after_symbol_at_location(symbol.location, body, use_same_indentation=use_same_indentation)
- src/serena/symbol.py:744-808 (handler)Core implementation logic for inserting code after a symbol's body end position, handling indentation, newlines, and file editing.def insert_after_symbol_at_location(self, location: SymbolLocation, body: str, *, use_same_indentation: bool = True) -> None: """ Appends content after the given symbol :param location: the location of the symbol after which to add new lines :param body: the body of the entity to append """ # make sure body always ends with at least one newline if not body.endswith("\n"): body += "\n" assert location.relative_path is not None # Find the symbol to get its end position symbol = self.find_by_location(location) if symbol is None: raise ValueError("Symbol not found/has no defined location within a file") pos = symbol.body_end_position if pos is None: raise ValueError(f"Symbol at {location} does not have a defined end position.") # start at the beginning of the next line col = 0 line = pos["line"] + 1 # make sure a suitable number of leading empty lines is used (at least 0/1 depending on the symbol type, # otherwise as many as the caller wanted to insert) original_leading_newlines = self._count_leading_newlines(body) body = body.lstrip("\r\n") min_empty_lines = 0 if symbol.is_neighbouring_definition_separated_by_empty_line(): min_empty_lines = 1 num_leading_empty_lines = max(min_empty_lines, original_leading_newlines) if num_leading_empty_lines: body = ("\n" * num_leading_empty_lines) + body # make sure the one line break succeeding the original symbol, which we repurposed as prefix via # `line += 1`, is replaced body = body.rstrip("\r\n") + "\n" if use_same_indentation: symbol_start_pos = symbol.body_start_position assert symbol_start_pos is not None, f"Symbol at {location=} does not have a defined start position." symbol_identifier_col = symbol_start_pos["character"] indent = " " * (symbol_identifier_col) body = "\n".join(indent + line for line in body.splitlines()) # IMPORTANT: without this, the insertion does the wrong thing. See implementation of insert_text_at_position in TextUtils, # it is somewhat counterintuitive (never inserts whitespace) # I am not 100% sure whether col=0 is always the best choice here. # # Without col=0, inserting after dataclass_instance in variables.py: # > dataclass_instance = VariableDataclass(id=1, name="Test") # > test test # > dataclass_instancetest test # > second line # > .status = "active" # Reassign dataclass field # # With col=0: # > dataclass_instance = VariableDataclass(id=1, name="Test") # > test test # > second line # > dataclass_instance.status = "active" # Reassign dataclass field with self._edited_symbol_location(location): self._lang_server.insert_text_at_position(location.relative_path, line=line, column=col, text_to_be_inserted=body)