### Install srgn from Source using Cargo Source: https://github.com/alexpovel/srgn/blob/main/README.md Instructions for installing the 'srgn' tool directly from source using the Rust package manager, Cargo. This method requires the Rust toolchain and a C compiler to be pre-installed on the system. ```bash cargo install srgn ``` -------------------------------- ### Install srgn in CI using GitHub Actions Source: https://github.com/alexpovel/srgn/blob/main/README.md This snippet demonstrates how to install the 'srgn' binary in a GitHub Actions CI environment using the 'cargo-binstall' action. It ensures that 'srgn' is precompiled and available for use, significantly speeding up CI jobs. ```yaml jobs: srgn: name: Install srgn in CI # All three major OSes work runs-on: ubuntu-latest steps: - uses: cargo-bins/cargo-binstall@main - name: Install binary run: > cargo binstall --no-confirm srgn - name: Use binary run: srgn --version ``` -------------------------------- ### Bash: Custom Tree-Sitter Queries Source: https://context7.com/alexpovel/srgn/llms.txt Shows how to use custom Tree-Sitter queries for advanced language-specific matching with the srgn CLI. This example targets finding Python if-else return patterns. ```bash # Find Python if-else return patterns cat code.py | srgn --python-query '(if_statement consequence: (block (return_statement)) alternative: (else_clause body: (block (return_statement)))) @cond' ``` -------------------------------- ### Bash: Deletion and Squeezing Source: https://context7.com/alexpovel/srgn/llms.txt Illustrates deletion and squeezing operations via the srgn CLI. Examples show deleting all digits, squeezing repeated whitespace, and removing punctuation. ```bash # Delete all digits echo 'abc123def456' | srgn -d '\d+' # Output: abcdef # Squeeze repeated whitespace echo 'hello world' | srgn -s '\s+' # Output: hello world # Remove punctuation echo 'Hello, World!' | srgn -d '[[:punct:]]' # Output: Hello World ``` -------------------------------- ### Rust: Squeezing Repeated Content Source: https://context7.com/alexpovel/srgn/llms.txt Illustrates how to collapse consecutive matches into single occurrences using ScopedViewBuilder in Rust. This example scopes to punctuation marks and then squeezes them. ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::regex::Regex; use srgn::RegexPattern; fn main() -> Result<(), Box> { let input = "Hello!!! World??? !!!"; let mut builder = ScopedViewBuilder::new(input); // Scope to punctuation let pattern = RegexPattern::new(r"[!?]")?; let scoper = Regex::new(pattern); builder.explode(&scoper); let mut view = builder.build(); view.squeeze(); println!("{}", view.to_string()); // Output: Hello! World? ! Ok(()) } ``` -------------------------------- ### Mass import renaming in Python and Rust Source: https://github.com/alexpovel/srgn/blob/main/README.md Shows how to perform mass import renaming for a specific package, for example, when refactoring after an acquisition or moving to a `src/` layout. The examples cover both Python and Rust, demonstrating how to change import paths from 'good_company' to 'src.better_company' (Python) or 'better_company' (Rust). ```python import math from pathlib import Path import good_company.infra import good_company.aws.auth as aws_auth from good_company.util.iter import dedupe from good_company.shopping.cart import * # Ok but don't do this at home! good_company = "good_company" # good_company ``` ```bash cat imports.py | srgn --python 'imports' '^good_company' -- 'src.better_company' ``` ```python import math from pathlib import Path import src.better_company.infra import src.better_company.aws.auth as aws_auth from src.better_company.util.iter import dedupe from src.better_company.shopping.cart import * # Ok but don't do this at home! good_company = "good_company" # good_company ``` ```rust use std::collections::HashMap; use good_company::infra; use good_company::aws::auth as aws_auth; use good_company::util::iter::dedupe; use good_company::shopping::cart::*; good_company = "good_company"; // good_company ``` ```bash cat imports.rs | srgn --rust 'uses' '^good_company' -- 'better_company' ``` ```rust use std::collections::HashMap; use better_company::infra; use better_company::aws::auth as aws_auth; use better_company::util::iter::dedupe; use better_company::shopping::cart::*; good_company = "good_company"; // good_company ``` -------------------------------- ### Replace Emojis and Squeeze Source: https://github.com/alexpovel/srgn/blob/main/README.md This example shows replacing emojis with a specified emoji and then squeezing the output. The replacement happens first, followed by the squeeze action. Note that other elements are not squeezed as the scope was specific to emojis. ```console $ echo 'Mooood: 🤮🤒🤧🦠!!!' | srgn -s '\p{Emoji}' -- '😷' Mooood: 😷!!! ``` -------------------------------- ### Implement Custom Actions in Srgn Library using Rust Source: https://context7.com/alexpovel/srgn/llms.txt This Rust example shows how to create a custom action by implementing the `Action` trait. The `WrapInParens` struct demonstrates a simple custom transformation that adds parentheses around matched input. ```rust use srgn::actions::Action; struct WrapInParens; impl Action for WrapInParens { fn act(&self, input: &str) -> String { format!("({})", input) } } fn main() { use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::regex::Regex; use srgn::RegexPattern; let input = "The answer is 42 and 7 is lucky"; let pattern = RegexPattern::new(r"\d+").unwrap(); let mut builder = ScopedViewBuilder::new(input); builder.explode(&Regex::new(pattern)); let mut view = builder.build(); let action = WrapInParens; view.map_without_context(&action); println!("{}", view.to_string()); // Output: The answer is (42) and (7) is lucky } ``` -------------------------------- ### Find Unsafe Rust Code Blocks using Srgn CLI Source: https://context7.com/alexpovel/srgn/llms.txt This example shows how to use the srgn CLI to identify and flag 'unsafe' code blocks within Rust files. It demonstrates srgn's language-specific querying capabilities for Rust. ```bash cat lib.rs | srgn --rust 'unsafe' ``` -------------------------------- ### Fail if Any Match is Found (Bash) Source: https://github.com/alexpovel/srgn/blob/main/README.md Shows how to use srgn to fail if any pattern matches, which is useful for linting or validating against undesirable content. The example uses Python docstring parsing. ```bash cat oldtyping.py | srgn --python 'doc-strings' --fail-any 'param.+type' ``` -------------------------------- ### Bash: Language-Specific Code Transformations Source: https://context7.com/alexpovel/srgn/llms.txt Shows how to perform language-aware code transformations using the srgn CLI. Examples include Python import replacements, uppercasing Go struct names, removing C# comments, and replacing print statements in Python. ```bash # Find and replace in Python imports only cat myfile.py | srgn --python 'imports' 'old_module' -- 'new_module' # Uppercase all Go struct names containing "Test" cat code.go | srgn --go 'struct~Test' --upper # Remove all C# comments cat Program.cs | srgn --csharp 'comments' -d '.*' # Replace print with logging in Python function calls cat script.py | srgn --python 'function-calls' '^print$' -- 'logging.info' ``` -------------------------------- ### Control Srgn Output and Integration (stdout, Glob, Dry-run, Fail) Source: https://context7.com/alexpovel/srgn/llms.txt These examples demonstrate advanced control over srgn's input and output, including forcing machine-readable output to stdout, processing files using glob patterns, previewing changes with dry-run, and failing CI/CD builds if matches are found. ```bash # Force machine-readable output (file:line:cols format) echo 'test' | srgn --python 'strings' --stdout-detection force-pipe 'test' # Output: (stdin):1:0-4:test ``` ```bash # Process files with sorted output srgn --rust 'comments' --sorted --glob '**/*.rs' 'TODO' ``` ```bash # Dry run to preview changes srgn --go 'imports' --dry-run --glob '*.go' 'old' -- 'new' ``` ```bash # Fail if any matches found (for CI/CD linting) cat code.py | srgn --python 'doc-strings' --fail-any 'param.+type' ``` -------------------------------- ### Bash: Multi-File Operations with Glob Patterns Source: https://context7.com/alexpovel/srgn/llms.txt Demonstrates how to perform operations on multiple files in place using glob patterns with the srgn CLI. Examples include transforming Python files, removing debug statements from Go files, uppercasing Rust test function names, and replacing logging calls in TypeScript. ```bash # Transform all Python files in project srgn --python 'imports' 'old_pkg' --glob '**/*.py' -- 'new_pkg' # Remove debug print statements from Go files srgn --go 'func' --glob 'src/**/*.go' -d 'fmt\.Println("DEBUG.*' # Uppercase test function names in Rust srgn --rust 'test-fn' --glob 'tests/**/*.rs' --upper # Replace logging calls across TypeScript project srgn --typescript 'function-calls' 'console\.log' \ --glob 'src/**/*.ts' -- 'logger.info' ``` -------------------------------- ### Language Grammar-Aware Scoping in Rust (Python Comments) Source: https://context7.com/alexpovel/srgn/llms.txt Demonstrates language grammar-aware scoping in Rust using tree-sitter. This example scopes the input to only include Python comments by utilizing a pre-defined `CompiledQuery` for comments. This functionality relies on language-specific grammars being available. ```rust use srgn::scoping::langs::python::{CompiledQuery, PreparedQuery}; use srgn::scoping::view::ScopedViewBuilder; fn main() { let code = r#" def calculate(x): """Calculate something.""" return x * 2 # Double it # This is a comment result = calculate(5) "#; // Scope to Python comments only let query = CompiledQuery::from(PreparedQuery::Comments); let mut builder = ScopedViewBuilder::new(code); builder.explode(&query); let view = builder.build(); // Now only comments are in scope println!("Scoped view:\n{}", view.to_string()); } ``` -------------------------------- ### Combine Actions with Narrow Scope Source: https://github.com/alexpovel/srgn/blob/main/README.md This example shows combining actions ('-Sgu') with a specific scope ('\b\w{1,8}\b'). The scope applies to all actions equally. Word boundaries are crucial to prevent partial word matches. ```console $ echo 'Koeffizienten != Bruecken...' | srgn -Sgu '\b\w{1,8}\b' Koeffizienten != BRÜCKEN... ``` -------------------------------- ### Find methods lacking docstrings in Python using srgn Source: https://github.com/alexpovel/srgn/blob/main/README.md An advanced search example using srgn to find Python methods (defined within classes) that lack docstrings. It demonstrates multi-line searching and sophisticated pattern matching based on language syntax. ```console cat birds.py | srgn --python 'class' 'def .+:\n\s+[^"\s]{3}' # do not try this pattern at home ``` -------------------------------- ### Named Capture Group Replacement in srgn Source: https://github.com/alexpovel/srgn/blob/main/README.md Illustrates the use of named capture groups for variable substitution, offering more readable and maintainable regex replacements. This example refactors a variable declaration. ```console echo 'let x = 3;' | srgn 'let (?[a-z]+) = (?.+);' -- 'const $var$var = $expr + $expr;' # Output: const xx = 3 + 3; ``` -------------------------------- ### Rust: Deletion Action Source: https://context7.com/alexpovel/srgn/llms.txt Shows how to remove content that matches a given scope using the ScopedViewBuilder in Rust. This example specifically removes all Python comments from a given code string. ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::langs::python::{CompiledQuery, PreparedQuery}; fn main() { let code = r#" def foo(): """This is a docstring.""" x = 1 # inline comment return x "#; // Remove all Python comments let query = CompiledQuery::from(PreparedQuery::Comments); let mut builder = ScopedViewBuilder::new(code); builder.explode(&query); let mut view = builder.build(); view.delete(); println!("{}", view.to_string()); // Comments are removed, code structure preserved } ``` -------------------------------- ### Srgn High-Speed Search: Go Strings and Digits Source: https://github.com/alexpovel/srgn/blob/main/README.md Highlights srgn's performance by showing an example of searching a large Go codebase. It finds all occurrences of digits ('\d+') within literal Go strings recursively, processing a massive amount of code very quickly. ```console srgn --go strings '\d+' ``` -------------------------------- ### srgn Command-Line for Python Docstring Manipulation Source: https://github.com/alexpovel/srgn/blob/main/README.md This command-line example shows how to use srgn to process a Python file. It applies titlecasing, scopes the operation to Python docstrings, uses a regular expression to find specific patterns, and performs a replacement with variable substitution and Unicode support. ```bash cat gnu.py | srgn --titlecase --python 'doc-strings' '(? Result<(), Box> { let input = "Version: 1.2.3"; let mut builder = ScopedViewBuilder::new(input); // Scope to semantic version pattern with capture groups let pattern = RegexPattern::new(r"(\d+)\.(\d+)\.(\d+)")?; let scoper = Regex::new(pattern); builder.explode(&scoper); let mut view = builder.build(); // Replace using captured groups ($1, $2, $3) view.replace("$1.$2.{$3}-beta".to_string()); println!("{}", view.to_string()); // Output: Version: 1.2.{3}-beta Ok(()) } ``` -------------------------------- ### Advanced Regex with Lookarounds in srgn Source: https://github.com/alexpovel/srgn/blob/main/README.md Utilizes advanced regex features like lookarounds for more sophisticated pattern matching. This example uses a positive lookbehind to replace alphanumeric characters following 'ghp_'. Note the potential performance/safety considerations with untrusted input and advanced regex. ```console echo 'ghp_oHn0As3cr3T' | srgn '(?<=ghp_)[[:alnum:]]+' -- '*' # Output: ghp_* ``` -------------------------------- ### Match Go Struct Fields with Specific Tags using Srgn CLI Source: https://context7.com/alexpovel/srgn/llms.txt This snippet demonstrates how to use the srgn CLI to find Go struct fields that match a specific name pattern and have certain tags. It highlights srgn's ability to parse and query Go code based on its structure. ```bash cat model.go | srgn --go-query \ '(field_declaration name: (field_identifier) @name tag: (raw_string_literal) @tag (#match? @name "[tT]oken"))' ``` -------------------------------- ### Bash: Symbol and Unicode Transformations Source: https://context7.com/alexpovel/srgn/llms.txt Covers symbol and Unicode transformations using the srgn CLI. This includes converting ASCII math symbols to their Unicode equivalents, normalizing German text, and performing Unicode normalization to remove diacritics. ```bash # Convert ASCII math symbols echo 'x != y && a <= b' | srgn --symbols # Output: x ≠ y && a ≤ b # German text normalization echo 'Gruesse aus Muenchen' | srgn --german # Output: Grüße aus München # Unicode normalization (remove diacritics) echo 'Café résumé' | srgn --normalize # Output: Cafe resume ``` -------------------------------- ### Action API - Transforming Scoped Content Source: https://context7.com/alexpovel/srgn/llms.txt This section covers the actions that can be applied to the scoped content, primarily focusing on replacement. ```APIDOC ## Applying Replacement Actions ### Description Details how to perform text replacement on scoped content, including the use of capture groups for variable substitution. ### Method `view.replace(replacement_string)` ### Endpoint N/A (Library API) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::regex::Regex; use srgn::RegexPattern; fn main() -> Result<(), Box> { let input = "Version: 1.2.3"; let mut builder = ScopedViewBuilder::new(input); let pattern = RegexPattern::new(r"(\d+)\.(\d+)\.(\d+)")?; let scoper = Regex::new(pattern); builder.explode(&scoper); let mut view = builder.build(); view.replace("$1.$2.{3}-beta".to_string()); println!("{}", view.to_string()); // Output: Version: 1.2.{3}-beta Ok(()) } ``` ### Response #### Success Response (200) N/A (Library API) #### Response Example N/A (Library API) ``` -------------------------------- ### Scope Rust Code with Prepared Query Source: https://github.com/alexpovel/srgn/blob/main/README.md Provides options to scope Rust code elements using predefined queries. This facilitates common analysis tasks on Rust source files. Aliased as 'rs', the prepared query can be specified via the `RUST` environment variable. ```shell --rust Scope Rust code using a prepared query. [env: RUST=] [aliases: rs] ``` -------------------------------- ### Bash: Case Transformation Operations Source: https://context7.com/alexpovel/srgn/llms.txt Demonstrates various case transformation operations using the srgn CLI. This includes lowercasing all text, uppercasing specific patterns, and titlecasing words based on a regex pattern. ```bash # Lowercase all text echo 'HELLO WORLD' | srgn --lower # Output: hello world # Uppercase specific pattern echo 'error: connection failed' | srgn --upper '^error' # Output: ERROR: connection failed # Titlecase words echo 'hello world from earth' | srgn --titlecase '\b\w+\b' # Output: Hello World From Earth ``` -------------------------------- ### Convert Python `print` calls to `logging.info` Source: https://github.com/alexpovel/srgn/blob/main/README.md Demonstrates how to refactor Python code by replacing all direct `print` function calls with `logging.info`. This is useful when migrating from simple printing to a more robust logging system. Anchors in the regex ensure only standalone 'print' calls are affected, not function names like 'print_more'. ```python def print_money(): """Let's print money 💸.""" amount = 32 print("Got here.") print_more = lambda s: print(f"Printed {s}") print_more(23) # print the stuff print_money() print("Done.") ``` ```bash cat money.py | srgn --python 'function-calls' '^print$' -- 'logging.info' ``` ```python def print_money(): """Let's print money 💸.""" amount = 32 logging.info("Got here.") print_more = lambda s: logging.info(f"Printed {s}") print_more(23) # print the stuff print_money() logging.info("Done.") ``` -------------------------------- ### Core Library API - Building Scoped Views Source: https://context7.com/alexpovel/srgn/llms.txt This section details how to build scoped views for source code manipulation using the srgn library. ```APIDOC ## Creating a Basic Scoped View ### Description Demonstrates how to create a basic scoped view where all input text is initially considered in-scope. ### Method `ScopedViewBuilder::new(input).build()` ### Endpoint N/A (Library API) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::scope::{Scope::In, RWScope, RWScopes}; use std::borrow::Cow::Borrowed as B; fn main() { let input = "Hello, world!!"; let builder = ScopedViewBuilder::new(input); let view = builder.build(); assert_eq!(view.scopes(), &RWScopes(vec![RWScope(In(B("Hello, world!!", None)))])); println!("View created with {} scope(s)", view.scopes().0.len()); } ``` ### Response #### Success Response (200) N/A (Library API) #### Response Example N/A (Library API) ``` ```APIDOC ## Scoping with Regular Expressions ### Description Illustrates how to use regular expressions to define in-scope and out-of-scope regions within the input text. ### Method `builder.explode(&Regex::new(pattern))` ### Endpoint N/A (Library API) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::regex::Regex; use srgn::RegexPattern; use srgn::scoping::scope::{Scope::{In, Out}, RWScope}; fn main() -> Result<(), Box> { let input = "Contact: user@example.com or admin@test.org"; let mut builder = ScopedViewBuilder::new(input); let pattern = RegexPattern::new(r"\b[\w.]+@[\w.]+\.\w+\b")?; let scoper = Regex::new(pattern); builder.explode(&scoper); let view = builder.build(); for scope in view.scopes().0.iter() { match &scope.0 { In(text, _) => println!("In scope: {}", text), Out(text) => println!("Out of scope: {}", text), } } Ok(()) } ``` ### Response #### Success Response (200) N/A (Library API) #### Response Example N/A (Library API) ``` ```APIDOC ## Language Grammar-Aware Scoping ### Description Shows how to perform scoping based on language-specific constructs using tree-sitter queries. ### Method `builder.explode(&query)` where `query` is a compiled language-specific query. ### Endpoint N/A (Library API) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use srgn::scoping::langs::python::{CompiledQuery, PreparedQuery}; use srgn::scoping::view::ScopedViewBuilder; fn main() { let code = r#"\ndef calculate(x):\n """Calculate something."""\n return x * 2 # Double it\n\n# This is a comment\nresult = calculate(5)\n"#; let query = CompiledQuery::from(PreparedQuery::Comments); let mut builder = ScopedViewBuilder::new(code); builder.explode(&query); let view = builder.build(); println!("Scoped view:\n{}", view.to_string()); } ``` ### Response #### Success Response (200) N/A (Library API) #### Response Example N/A (Library API) ``` -------------------------------- ### Execute Custom Python Queries from File Source: https://github.com/alexpovel/srgn/blob/main/README.md Executes custom tree-sitter queries defined in a file against Python code. This is useful for complex queries that would be cumbersome to type directly in the command line. It takes a Python file as input and applies the specified query. ```bash cat cond.py | srgn --python-query-file 'docs/python_cond_query.scm' ``` -------------------------------- ### Automatic Output Formatting (Console) Source: https://github.com/alexpovel/srgn/blob/main/README.md Demonstrates srgn's automatic output formatting based on whether the output is a TTY or being piped. It shows how to force TTY or pipe output using --stdout-detection. ```console echo 'x = "foo bar"' | srgn --python 'strings' --stdout-detection 'force-pipe' '(foo|bar)' (stdin):1:5-8;9-12:x = "foo bar" echo 'x = "foo bar"' | srgn --python 'strings' --stdout-detection 'force-tty' '(foo|bar)' 1:x = "foo bar" ``` -------------------------------- ### Refine Scope with Piping Source: https://github.com/alexpovel/srgn/blob/main/README.md This illustrates how piping can be used to refine scopes when combining actions. The first command applies the combined actions with a word-based scope, and the second command, using a literal scope, corrects trailing punctuation. ```console $ echo 'Koeffizienten != Bruecken...' | srgn -Sgu '\b\w{1,8}\b' | srgn -s '\.' Koeffizienten != BRÜCKEN. ``` -------------------------------- ### Srgn Query: Python Class and Docstrings (AND) Source: https://github.com/alexpovel/srgn/blob/main/README.md Illustrates a srgn query on Python code, searching for lines that are both 'class' definitions and contain 'doc-strings'. This showcases the default AND behavior, where results must match all criteria. ```console $ cat birds.py | srgn --py 'class' --py 'doc-strings' 8: """A bird!""" 19: """Create a bird from an egg.""" ``` -------------------------------- ### Rust: Case Transformation Source: https://context7.com/alexpovel/srgn/llms.txt Demonstrates how to transform text case within specific scopes using the ScopedViewBuilder and Regex in Rust. It scopes to snake_case identifiers and applies a titlecase transformation. ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::regex::Regex; use srgn::RegexPattern; fn main() -> Result<(), Box> { let input = "http_request_handler and XMLParser"; let mut builder = ScopedViewBuilder::new(input); // Scope to snake_case identifiers let pattern = RegexPattern::new(r"\b[a-z]+(_[a-z]+)+\b")?; let scoper = Regex::new(pattern); builder.explode(&scoper); let mut view = builder.build(); // Apply titlecase transformation view.titlecase(); println!("{}", view.to_string()); // Output: Http_Request_Handler and XMLParser Ok(()) } ``` -------------------------------- ### Handle No Matches with Explicit Failure (Bash) Source: https://github.com/alexpovel/srgn/blob/main/README.md Demonstrates how to configure srgn to explicitly fail (non-zero exit code) when no matches are found for a given pattern. This is useful for ensuring patterns are present in the input. ```bash echo 'Some input...' | srgn --delete --fail-none '\d' ``` -------------------------------- ### Scope with Regular Expressions in Rust Source: https://context7.com/alexpovel/srgn/llms.txt Illustrates how to use regular expressions to define scopes within a ScopedView in Rust. The Regex scoper filters the input, making only the text matching the pattern in-scope and everything else out-of-scope. This requires the `regex` feature to be enabled. ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::regex::Regex; use srgn::RegexPattern; use srgn::scoping::scope::{Scope::{In, Out}, RWScope}; fn main() -> Result<(), Box> { let input = "Contact: user@example.com or admin@test.org"; let mut builder = ScopedViewBuilder::new(input); // Scope to email addresses only let pattern = RegexPattern::new(r"\b[\w.]+@[\w.]+\.\w+\b")?; let scoper = Regex::new(pattern); builder.explode(&scoper); let view = builder.build(); // Now only email addresses are In scope, everything else is Out for scope in view.scopes().0.iter() { match &scope.0 { In(text, _) => println!("In scope: {}", text), Out(text) => println!("Out of scope: {}", text), } } Ok(()) } ``` -------------------------------- ### Scope Python Code with Tree-Sitter Query File Source: https://github.com/alexpovel/srgn/blob/main/README.md Enables scoping of Python code elements using a tree-sitter query defined in an external file. This promotes reusability and organization of complex queries. The query file path can be managed via the `PYTHON_QUERY_FILE` environment variable. ```shell --python-query-file Scope Python code using a custom tree-sitter query from file. [env: PYTHON_QUERY_FILE=] ``` -------------------------------- ### Integrate Srgn as a Rust Library for Struct Scope Transformation Source: https://context7.com/alexpovel/srgn/llms.txt This Rust code snippet demonstrates using srgn as a library to programmatically scope transformations to struct definitions. It utilizes `ScopedViewBuilder` and applies an `Upper` action to the selected code. ```rust use srgn::scoping::view::ScopedViewBuilder; use srgn::scoping::langs::rust::{CompiledQuery, PreparedQuery}; use srgn::actions::{Action, Upper}; fn main() { let code = r#" pub struct User { name: String, email: String, } impl User { fn new(name: String) -> Self { User { name, email: String::new() } } } "#; // Scope to struct definitions only let query = CompiledQuery::from(PreparedQuery::Struct); let mut builder = ScopedViewBuilder::new(code); builder.explode(&query); let mut view = builder.build(); // Apply custom action let uppercase = Upper::default(); view.map_without_context(&uppercase); println!("{}", view.to_string()); // Only struct definition is uppercased } ``` -------------------------------- ### Scope Python Code with Tree-Sitter Query Source: https://github.com/alexpovel/srgn/blob/main/README.md Allows users to define custom tree-sitter queries to precisely scope Python code elements. This is useful for granular analysis or manipulation of Python source files. Environment variable `PYTHON_QUERY` can be used to pass the query directly. ```shell --python-query Scope Python code using a custom tree-sitter query. [env: PYTHON_QUERY=] ``` -------------------------------- ### File Input Output Formatting (Console) Source: https://github.com/alexpovel/srgn/blob/main/README.md Shows srgn's output format when processing files, including filename, line number, and column ranges. This output is designed for machine readability. ```console srgn --python 'class' --stdout-detection 'force-pipe' 'egg' docs/samples/birds:18:13-16;17-20: def from_egg(egg): docs/samples/birds:19:33-36: """Create a bird from an egg.""" docs/samples/birds.py:16:13-16;17-20: def from_egg(egg): docs/samples/birds.py:17:33-36: """Create a bird from an egg.""" ``` -------------------------------- ### Replace `allow` with `expect` lint level in Rust Source: https://github.com/alexpovel/srgn/blob/main/README.md Demonstrates how to refactor Rust code by replacing the `#[allow(unsafe_code)]` attribute with `#[expect(unsafe_code)]` using the `srgn` tool. This leverages the stabilization of the `expect` lint level in Rust 1.81. ```rust #[allow(unsafe_code)] if let Some(env_value) = env_value { unsafe { env::set_var(DEFAULT_FILTER_ENV, env_value); } } ``` ```bash cat allow.rs | srgn --rust 'attribute' '^allow' -- 'expect' ``` ```rust #[expect(unsafe_code)] if let Some(env_value) = env_value { unsafe { env::set_var(DEFAULT_FILTER_ENV, env_value); } } ``` -------------------------------- ### Greedy Replacement with Unicode Character Classes in srgn Source: https://github.com/alexpovel/srgn/blob/main/README.md Demonstrates greedy replacement using Unicode character classes, such as '[:alnum:]'. This replaces all occurrences of the matched pattern greedily across the entire string. ```console echo 'ghp_oHn0As3cr3T!!' | srgn 'ghp_[[:alnum:]]+' -- '*' # Output: *!! ``` -------------------------------- ### Combine Actions: Uppercase and German Characters Source: https://github.com/alexpovel/srgn/blob/main/README.md This demonstrates combining multiple actions in srgn. Here, '-S' (uppercase) and '-g' (German characters) are used together. The order of flags does not influence the application order, as replacements always occur first. ```console $ echo 'Koeffizienten != Bruecken...' | srgn -Sgu KOEFFIZIENTEN ≠ BRÜCKEN... ``` -------------------------------- ### Srgn Query: Rust Enum and Type Identifier Source: https://github.com/alexpovel/srgn/blob/main/README.md Demonstrates how to use srgn to query Rust code, specifically targeting 'pub-enum' and 'type-identifier' for 'Subgenre'. This performs a logical AND operation on the specified criteria. ```console $ cat music.rs | srgn --rust 'pub-enum' --rust 'type-identifier' 'Subgenre' # AND'ed together 2: Rock(Subgenre), ``` -------------------------------- ### Use Srgn Literal String Mode for Escaping Avoidance Source: https://context7.com/alexpovel/srgn/llms.txt This shows how to use srgn's `--literal-string` flag to treat patterns as literal strings rather than regular expressions. This simplifies matching characters that have special meaning in regex, like dots or dollar signs. ```bash # Match literal dots without escaping echo 'file.txt.backup' | srgn --literal-string '.' -- '_' # Output: file_txt_backup ``` ```bash # Match special regex characters literally echo 'cost: $100 (plus $20 tax)' | srgn --literal-string '$' -- 'USD ' # Output: cost: USD 100 (plus USD 20 tax) ``` -------------------------------- ### Custom query for Python conditional return statements Source: https://github.com/alexpovel/srgn/blob/main/README.md This snippet illustrates using a custom query with 'srgn' in Python to identify an anti-pattern where an 'if-else' statement returns values from different branches. The query aims to flag code that could be more idiomatically written using a conditional expression. ```python if x: return left else: return right ``` ```bash cat cond.py | srgn --python-query '(if_statement consequence: (block (return_statement (identifier))) alternative: (else_clause body: (block (return_statement (identifier))))) @cond' --fail-any # will fail ```