Extract Code Block to Named Function

VerifiedSafe

Extracts a selected code block into a new named function using LSP code actions, with a manual fallback and validation of scope and compilation.

Sby Skills Guide Bot
DevelopmentIntermediate
7/31/2026
Claude Code
#refactoring#lsp#code-actions#code-extraction#diagnostics

Recommended for

Automated summary

Extracts a selected line range in a source file into a named function, preferring the language server's extract-function code action and falling back to manual extraction.

Strengths

  • Uses native LSP refactor code actions, preserving language-aware edits when available.
  • Checks document symbols before editing to catch name collisions.
  • Includes post-extraction checks for captured variables, scope shadowing, and compilation/diagnostics.
  • Handles both command-based and edit-based code action responses.

Limitations

  • Requires the agent-lsp MCP server and a language server exposing code actions; otherwise the fallback path is needed.
  • The supplied SKILL.md is truncated in the manual fallback section, so the exact fallback and validation sequence is not fully specified.
  • It only restructures existing code and does not generate new implementations.
When to use it

Use it when an existing block of code should become a named function and your language server can provide a refactor action.

When not to use it

Do not use it to create new code from scratch or in environments without the required LSP MCP server.

Security analysis

Safe
Quality score86/100

The skill only uses LSP MCP tools: opening documents, listing symbols, querying code actions, applying workspace edits, reading diagnostics, and formatting. There is no shell execution, no network access, no credential handling, and no destructive filesystem operations. Edits are scoped to the named file and gated on a user confirmation step, and the primary path defers to the language server's own code action. The only notable inconsistency is a reference to a start_lsp tool not present in the declared tool list, which is harmless.

Findings
  • •Prerequisites instruct calling `mcp__lsp__start_lsp`, which is not included in the declared allowed-tools list — an inconsistency, though not a risk in itself
  • •The skill applies edits to user files via `mcp__lsp__apply_edit`, but only to the specified document with user confirmation on the proposed signature
How this analysis is made

Examples

Extract parser block
Extract lines 42-58 of /Users/me/project/src/parser.ts into a function named parseHeader, using the LSP extract-function code action and checking diagnostics afterward.
Collision-safe extraction
In /Users/me/project/src/service.ts, extract lines 110-135 into a new function called buildRequest. Check for an existing symbol with that name first and stop if there is a collision.
Manual fallback extraction
Extract the selected block on lines 25-40 of /Users/me/project/src/utils.py into normalize_path. If the language server offers no extract-function action, use the manual fallback and validate the result.

name: lsp-extract-function description: Extract a selected code block into a named function. Primary path uses the language server's extract-function code action; falls back to manual extraction when no code action is available. Validates captured variables, scope shadowing, and compilation after extraction. argument-hint: "[file-path] [start-line] [end-line] [new-function-name]" user-invocable: true allowed-tools: mcp__lsp__list_symbols mcp__lsp__suggest_fixes mcp__lsp__execute_command mcp__lsp__apply_edit mcp__lsp__get_diagnostics mcp__lsp__open_document mcp__lsp__format_document mcp__lsp__get_server_capabilities license: MIT compatibility: Requires the agent-lsp MCP server (github.com/blackwell-systems/agent-lsp) metadata: required-capabilities: codeActionProvider optional-capabilities: documentFormattingProvider documentSymbolProvider

Requires the agent-lsp MCP server.

lsp-extract-function: Extract Code Block into a Named Function

This skill RESTRUCTURES existing code — it takes code that already exists and moves it into a new function. This is distinct from /lsp-generate, which creates NEW code that does not yet exist (stubs, mocks, interface implementations). Use this skill when the code is already written; use /lsp-generate when you need to generate code from scratch.

Invocation: User provides file_path (absolute path), start_line and end_line (1-indexed range), and new_function_name (desired name for the extracted function).


Prerequisites

If LSP is not yet initialized, call mcp__lsp__start_lsp with the workspace root first. Auto-inference applies when file paths are provided, but an explicit start is required when switching workspaces.


Step 1 — Get context (document symbols)

Call mcp__lsp__open_document to open the file, then call mcp__lsp__list_symbols to understand the containing function and scope:

mcp__lsp__open_document({ "file_path": "<file_path>" })
mcp__lsp__list_symbols({ "file_path": "<file_path>" })

This establishes:

  • Which function contains the selection
  • Whether new_function_name already exists in the file (name collision check)

Mandatory name collision check: If new_function_name already exists as a symbol in the document symbols list, report the conflict and stop immediately:

Cannot extract: function new_function_name already exists in this file. Choose a different name and retry.


Step 2 — Check server capabilities

Call mcp__lsp__get_server_capabilities to understand what the language server supports:

mcp__lsp__get_server_capabilities({})

Check for codeActionProvider in the response. Note whether execute_command is listed in executeCommandProvider.commands. This determines whether the primary path (Step 3) is available.


Step 3 — Primary path: LSP code action

Call mcp__lsp__suggest_fixes with the selection range:

mcp__lsp__suggest_fixes({
  "file_path": "<file_path>",
  "start_line": N,
  "start_column": 1,
  "end_line": M,
  "end_column": 999
})

Filter the returned actions for extract-function actions: include any action whose kind contains "refactor.extract" OR whose title contains both "Extract" and "function" (case-insensitive).

If an extract-function action is found:

  • Display the action title to the user
  • If the action proposes a different name than new_function_name, ask for confirmation before proceeding
  • Execute via mcp__lsp__execute_command if the action has a command field:
    mcp__lsp__execute_command({
      "command": "<action.command.command>",
      "arguments": <action.command.arguments>
    })
    
  • OR apply directly via mcp__lsp__apply_edit if the action has an edit field:
    mcp__lsp__apply_edit({ "workspace_edit": <action.edit> })
    
  • Skip to Step 5 after applying.

If no extract-function action is found: fall through to Step 4 (manual fallback).


Step 4 — Manual fallback

When no code action is available, perform manual extraction:

a) Analyze the selection

Read the selected lines (start_line through end_line) and identify:

  • Parameters: Variables used inside the selection that are declared outside (captured from outer scope — must become function parameters)
  • Return values: Variables declared inside the selection that are used outside (must be returned from the extracted function)
  • Early returns: Return statements inside the selection (the extracted function must wrap these)

b) Construct and confirm the proposed signature

Build the extracted function signature based on the captured variables analysis. Display the proposed signature to the user before writing:

Proposed extraction:

func new_function_name(param1 Type1, param2 Type2) (ReturnType, error) {
    // selected lines
}

Proceed with this signature? [y/n]

Wait for user confirmation before applying any edit.

c) Apply the extraction (order matters)

Apply edits sequentially — do NOT batch edits from different line regions into a single apply_edit call:

  1. First: Replace the selected lines with a call to the new function:

    mcp__lsp__apply_edit({
      "workspace_edit": {
        "changes": {
          "<file_path>": [{
            "range": { "start": { "line": start_line-1, "character": 0 },
                       "end":   { "line": end_line,     "character": 0 } },
            "newText": "    result := new_function_name(args...)\n"
          }]
        }
      }
    })
    
  2. Second: Insert the new function definition after the containing function's closing brace:

    mcp__lsp__apply_edit({
      "workspace_edit": {
        "changes": {
          "<file_path>": [{
            "range": { "start": { "line": insert_line, "character": 0 },
                       "end":   { "line": insert_line, "character": 0 } },
            "newText": "\nfunc new_function_name(params) ReturnType {\n    ...\n}\n"
          }]
        }
      }
    })
    

Apply call-site replacement first, then insert the new function. This order preserves line numbers during editing: replacing call site does not shift the insertion point for the new function definition.


Step 5 — Validate

After extraction via either path:

1. Check diagnostics

mcp__lsp__get_diagnostics({ "file_path": "<file_path>" })

If errors are reported, display them with the table of common causes below.

2. Common post-extraction errors

| Error type | Likely cause | Fix | |------------|--------------|-----| | Undefined variable | Captured var not passed as parameter | Add parameter | | Type mismatch | Return type inferred incorrectly | Adjust return type in signature | | Name shadows outer | New function name matches outer scope | Choose different name | | Unused variable | Return value not captured at call site | Add variable at call site |

3. Format the document

mcp__lsp__format_document({ "file_path": "<file_path>" })

This cleans up indentation introduced by the extraction.


Output Format

After completing extraction, display:

## Extraction Summary
- File:           path/to/file.go
- Extracted:      lines N–M
- New function:   new_function_name
- Path used:      LSP code action / Manual fallback
- Post-extraction errors: 0

Follow with the Diagnostic Summary if any errors changed (format in references/patterns.md).


Language-Specific Notes

  • Go: gopls may offer "Extract function" in code actions for selection ranges. Check code actions first; gopls support varies by version.
  • TypeScript/JavaScript: typescript-language-server may offer "Extract to function in global scope" or "Extract to inner function" — filter for these titles in Step 3.
  • Python: pylsp and pyright-langserver typically do NOT offer extract-function code actions. Manual fallback (Step 4) is required for Python files.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/extract-code-block-to-named-function-ms8gxmvc/download' --output '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md.part' && mv '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md.part' '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

Environment declared by the author: Requires the agent-lsp MCP server (github.com/blackwell-systems/agent-lsp)

Tools declared by the author (check availability in your agent): mcp__lsp__list_symbols mcp__lsp__suggest_fixes mcp__lsp__execute_command mcp__lsp__apply_edit mcp__lsp__get_diagnostics mcp__lsp__open_document mcp__lsp__format_document mcp__lsp__get_server_capabilities

Original excerpt: Prerequisites

If LSP is not yet initialized, call mcp__lsp__start_lsp with the workspace root first. Auto-inference applies when file paths are provided, but an explicit start is required when switching workspaces.


The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md' && test -s '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/lsp-extract-function' && cp -R '.skill-downloads/extract-code-block-to-named-function-ms8gxmvc' '.claude/skills/lsp-extract-function'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/extract-code-block-to-named-function-ms8gxmvc'

openskills read 'extract-code-block-to-named-function-ms8gxmvc'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/extract-code-block-to-named-function-ms8gxmvc/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills