tmuxp search - tmuxp.cli.search¶
CLI for tmuxp search subcommand.
Search workspace configuration files by name, session, path, and content.
Examples
>>> from tmuxp.cli.search import SearchToken, normalize_fields
Parse field aliases to canonical names:
>>> normalize_fields(["s", "name"])
('session_name', 'name')
Create search tokens from query terms:
>>> from tmuxp.cli.search import parse_query_terms, DEFAULT_FIELDS
>>> tokens = parse_query_terms(["name:dev", "editor"], default_fields=DEFAULT_FIELDS)
>>> tokens[0]
SearchToken(fields=('name',), pattern='dev')
>>> tokens[1]
SearchToken(fields=('name', 'session_name', 'path', 'window', 'pane'), pattern='editor')
- tmuxp.cli.search.FIELD_ALIASES: dict[str, str] = {'n': 'name', 'name': 'name', 'p': 'path', 'pane': 'pane', 'path': 'path', 's': 'session_name', 'session': 'session_name', 'session_name': 'session_name', 'w': 'window', 'window': 'window'}¶
Field name aliases for search queries
- tmuxp.cli.search.VALID_FIELDS: frozenset[str] = frozenset({'name', 'pane', 'path', 'session_name', 'window'})¶
Valid field names after alias resolution
- tmuxp.cli.search.DEFAULT_FIELDS: tuple[str, ...] = ('name', 'session_name', 'path', 'window', 'pane')¶
Default fields to search when no field prefix is specified
- class tmuxp.cli.search.SearchToken(fields: tuple[str, ...], pattern: str)[source]¶
Bases:
NamedTupleParsed search token with target fields and raw pattern.
Examples
>>> token = SearchToken(fields=("name",), pattern="dev") >>> token.fields ('name',) >>> token.pattern 'dev'
- _field_defaults = {}¶
- _fields = ('fields', 'pattern')¶
- class tmuxp.cli.search.SearchPattern(fields: tuple[str, ...], raw: str, regex: re.Pattern[str])[source]¶
Bases:
NamedTupleCompiled search pattern with regex and metadata.
- regex¶
Compiled regex pattern for matching.
- Type:
Examples
>>> import re >>> pattern = SearchPattern( ... fields=("name",), ... raw="dev", ... regex=re.compile("dev"), ... ) >>> pattern.fields ('name',) >>> bool(pattern.regex.search("development")) True
- _field_defaults = {}¶
- _fields = ('fields', 'raw', 'regex')¶
- exception tmuxp.cli.search.InvalidFieldError(field)[source]¶
Bases:
ValueErrorRaised when an invalid field name is specified.
Examples
>>> raise InvalidFieldError("invalid") Traceback (most recent call last): ... tmuxp.cli.search.InvalidFieldError: Unknown search field: 'invalid'. ...
- tmuxp.cli.search.normalize_fields(fields)[source]¶
Normalize field names using aliases.
- Return type:
- Parameters:
fields (list[str] | None) – Field names or aliases to normalize. If None, returns DEFAULT_FIELDS.
- Returns:
Tuple of canonical field names.
- Return type:
- Raises:
InvalidFieldError – If a field name is not recognized.
Examples
>>> normalize_fields(None) ('name', 'session_name', 'path', 'window', 'pane')
>>> normalize_fields(["s", "n"]) ('session_name', 'name')
>>> normalize_fields(["session_name", "path"]) ('session_name', 'path')
>>> normalize_fields(["invalid"]) Traceback (most recent call last): ... tmuxp.cli.search.InvalidFieldError: Unknown search field: 'invalid'. ...
- tmuxp.cli.search._parse_field_prefix(term)[source]¶
Extract field prefix from a search term.
- Return type:
- Parameters:
term (str) – Search term, possibly with field prefix (e.g., “name:dev”).
- Returns:
Tuple of (field_prefix, pattern). field_prefix is None if no prefix.
- Return type:
Examples
>>> _parse_field_prefix("name:dev") ('name', 'dev')
>>> _parse_field_prefix("s:myproject") ('s', 'myproject')
>>> _parse_field_prefix("development") (None, 'development')
>>> _parse_field_prefix("path:/home/user") ('path', '/home/user')
>>> _parse_field_prefix("window:") ('window', '')
- tmuxp.cli.search.parse_query_terms(terms, *, default_fields=('name', 'session_name', 'path', 'window', 'pane'))[source]¶
Parse query terms into search tokens.
Each term can optionally have a field prefix (e.g., “name:dev”). Terms without prefixes search the default fields.
- Return type:
- Parameters:
- Returns:
List of parsed search tokens.
- Return type:
- Raises:
InvalidFieldError – If a field prefix is not recognized.
Examples
>>> tokens = parse_query_terms(["dev"]) >>> tokens[0].fields ('name', 'session_name', 'path', 'window', 'pane') >>> tokens[0].pattern 'dev'
>>> tokens = parse_query_terms(["name:dev", "s:prod"]) >>> tokens[0] SearchToken(fields=('name',), pattern='dev') >>> tokens[1] SearchToken(fields=('session_name',), pattern='prod')
>>> tokens = parse_query_terms(["window:editor", "shell"]) >>> tokens[0].fields ('window',) >>> tokens[1].fields ('name', 'session_name', 'path', 'window', 'pane')
Unknown prefixes are treated as literal patterns (allows URLs, etc.):
>>> tokens = parse_query_terms(["http://example.com"]) >>> tokens[0].pattern 'http://example.com' >>> tokens[0].fields # Searches default fields ('name', 'session_name', 'path', 'window', 'pane')
- tmuxp.cli.search._has_uppercase(pattern)[source]¶
Check if pattern contains uppercase letters.
Used for smart-case detection.
- Return type:
- Parameters:
pattern (str) – Pattern to check.
- Returns:
True if pattern contains at least one uppercase letter.
- Return type:
Examples
>>> _has_uppercase("dev") False
>>> _has_uppercase("Dev") True
>>> _has_uppercase("DEV") True
>>> _has_uppercase("123") False
>>> _has_uppercase("") False
- tmuxp.cli.search.compile_search_patterns(tokens, *, ignore_case=False, smart_case=False, fixed_strings=False, word_regexp=False)[source]¶
Compile search tokens into regex patterns.
- Return type:
- Parameters:
tokens (list[SearchToken]) – Parsed search tokens to compile.
ignore_case (bool) – If True, always ignore case. Default False.
smart_case (bool) – If True, ignore case unless pattern has uppercase. Default False.
fixed_strings (bool) – If True, treat patterns as literal strings, not regex. Default False.
word_regexp (bool) – If True, match whole words only. Default False.
- Returns:
List of compiled search patterns.
- Return type:
- Raises:
re.error – If a pattern is invalid regex (when fixed_strings=False).
Examples
Basic compilation:
>>> tokens = [SearchToken(fields=("name",), pattern="dev")] >>> patterns = compile_search_patterns(tokens) >>> patterns[0].raw 'dev' >>> bool(patterns[0].regex.search("development")) True
Case-insensitive matching:
>>> tokens = [SearchToken(fields=("name",), pattern="DEV")] >>> patterns = compile_search_patterns(tokens, ignore_case=True) >>> bool(patterns[0].regex.search("development")) True
Smart-case (uppercase = case-sensitive):
>>> tokens = [SearchToken(fields=("name",), pattern="Dev")] >>> patterns = compile_search_patterns(tokens, smart_case=True) >>> bool(patterns[0].regex.search("Developer")) True >>> bool(patterns[0].regex.search("developer")) False
Smart-case (lowercase = case-insensitive):
>>> tokens = [SearchToken(fields=("name",), pattern="dev")] >>> patterns = compile_search_patterns(tokens, smart_case=True) >>> bool(patterns[0].regex.search("DEVELOPMENT")) True
Fixed strings (escape regex metacharacters):
>>> tokens = [SearchToken(fields=("name",), pattern="dev.*")] >>> patterns = compile_search_patterns(tokens, fixed_strings=True) >>> bool(patterns[0].regex.search("dev.*project")) True >>> bool(patterns[0].regex.search("development")) False
Word boundaries:
>>> tokens = [SearchToken(fields=("name",), pattern="dev")] >>> patterns = compile_search_patterns(tokens, word_regexp=True) >>> bool(patterns[0].regex.search("my dev project")) True >>> bool(patterns[0].regex.search("development")) False
- class tmuxp.cli.search.WorkspaceFields[source]¶
Bases:
TypedDictExtracted searchable fields from a workspace file.
Examples
>>> fields: WorkspaceFields = { ... "name": "dev", ... "path": "~/.tmuxp/dev.yaml", ... "session_name": "development", ... "windows": ["editor", "shell"], ... "panes": ["vim", "git status"], ... } >>> fields["name"] 'dev'
- class tmuxp.cli.search.WorkspaceSearchResult[source]¶
Bases:
TypedDictSearch result for a workspace that matched.
- fields¶
Extracted searchable fields.
- Type:
Examples
>>> result: WorkspaceSearchResult = { ... "filepath": "/home/user/.tmuxp/dev.yaml", ... "source": "global", ... "fields": { ... "name": "dev", ... "path": "~/.tmuxp/dev.yaml", ... "session_name": "development", ... "windows": ["editor"], ... "panes": [], ... }, ... "matches": {"name": ["dev"]}, ... } >>> result["source"] 'global'
-
fields:
WorkspaceFields¶
- tmuxp.cli.search.extract_workspace_fields(filepath)[source]¶
Extract searchable fields from a workspace file.
Parses the workspace configuration and extracts name, path, session_name, window names, and pane commands for searching.
- Return type:
- Parameters:
filepath (pathlib.Path) – Path to the workspace file.
- Returns:
Dictionary of extracted fields.
- Return type:
Examples
>>> import tempfile >>> import pathlib >>> content = ''' ... session_name: my-project ... windows: ... - window_name: editor ... panes: ... - vim ... - shell_command: git status ... - window_name: shell ... ''' >>> with tempfile.NamedTemporaryFile( ... suffix='.yaml', delete=False, mode='w' ... ) as f: ... _ = f.write(content) ... temp_path = pathlib.Path(f.name) >>> fields = extract_workspace_fields(temp_path) >>> fields["session_name"] 'my-project' >>> sorted(fields["windows"]) ['editor', 'shell'] >>> 'vim' in fields["panes"] True >>> temp_path.unlink()
- tmuxp.cli.search._get_field_values(fields, field_name)[source]¶
Get values for a field, normalizing to list.
- Return type:
- Parameters:
fields (WorkspaceFields) – Extracted workspace fields.
field_name (str) – Canonical field name to retrieve.
- Returns:
List of values for the field.
- Return type:
Examples
>>> fields: WorkspaceFields = { ... "name": "dev", ... "path": "~/.tmuxp/dev.yaml", ... "session_name": "development", ... "windows": ["editor", "shell"], ... "panes": ["vim"], ... } >>> _get_field_values(fields, "name") ['dev'] >>> _get_field_values(fields, "windows") ['editor', 'shell'] >>> _get_field_values(fields, "window") ['editor', 'shell']
- tmuxp.cli.search.evaluate_match(fields, patterns, *, match_any=False)[source]¶
Evaluate if workspace fields match search patterns.
- Return type:
- Parameters:
fields (WorkspaceFields) – Extracted workspace fields to search.
patterns (list[SearchPattern]) – Compiled search patterns.
match_any (bool) – If True, match if ANY pattern matches (OR logic). If False, ALL patterns must match (AND logic). Default False.
- Returns:
Tuple of (matched, {field_name: [matched_strings]}). The matches dict contains actual matched text for highlighting.
- Return type:
Examples
>>> import re >>> fields: WorkspaceFields = { ... "name": "dev-project", ... "path": "~/.tmuxp/dev-project.yaml", ... "session_name": "development", ... "windows": ["editor", "shell"], ... "panes": ["vim", "git status"], ... }
Single pattern match:
>>> pattern = SearchPattern( ... fields=("name",), ... raw="dev", ... regex=re.compile("dev"), ... ) >>> matched, matches = evaluate_match(fields, [pattern]) >>> matched True >>> "name" in matches True
AND logic (default) - all patterns must match:
>>> p1 = SearchPattern(fields=("name",), raw="dev", regex=re.compile("dev")) >>> p2 = SearchPattern(fields=("name",), raw="xyz", regex=re.compile("xyz")) >>> matched, _ = evaluate_match(fields, [p1, p2], match_any=False) >>> matched False
OR logic - any pattern can match:
>>> matched, _ = evaluate_match(fields, [p1, p2], match_any=True) >>> matched True
Window field search:
>>> p_win = SearchPattern( ... fields=("window",), ... raw="editor", ... regex=re.compile("editor"), ... ) >>> matched, matches = evaluate_match(fields, [p_win]) >>> matched True >>> "window" in matches True
- tmuxp.cli.search.find_search_matches(workspaces, patterns, *, match_any=False, invert_match=False)[source]¶
Find workspaces matching search patterns.
- Return type:
- Parameters:
workspaces (list[tuple[pathlib.Path, str]]) – List of (filepath, source) tuples to search. Source is “local” or “global”.
patterns (list[SearchPattern]) – Compiled search patterns.
match_any (bool) – If True, match if ANY pattern matches (OR logic). Default False (AND).
invert_match (bool) – If True, return workspaces that do NOT match. Default False.
- Returns:
List of matching workspace results with match information.
- Return type:
Examples
>>> import tempfile >>> import pathlib >>> import re >>> content = "session_name: dev-session" + chr(10) + "windows: []" >>> with tempfile.NamedTemporaryFile( ... suffix='.yaml', delete=False, mode='w' ... ) as f: ... _ = f.write(content) ... temp_path = pathlib.Path(f.name)
>>> pattern = SearchPattern( ... fields=("session_name",), ... raw="dev", ... regex=re.compile("dev"), ... ) >>> results = find_search_matches([(temp_path, "global")], [pattern]) >>> len(results) 1 >>> results[0]["source"] 'global'
Invert match returns non-matching workspaces:
>>> pattern_nomatch = SearchPattern( ... fields=("name",), ... raw="nonexistent", ... regex=re.compile("nonexistent"), ... ) >>> results = find_search_matches( ... [(temp_path, "global")], [pattern_nomatch], invert_match=True ... ) >>> len(results) 1 >>> temp_path.unlink()
- tmuxp.cli.search.highlight_matches(text, patterns, *, colors)[source]¶
Highlight regex matches in text.
- Return type:
- Parameters:
text (str) – Text to search and highlight.
patterns (list[SearchPattern]) – Compiled search patterns (uses their regex attribute).
colors (Colors) – Color manager for highlighting.
- Returns:
Text with matches highlighted, or original text if no matches.
- Return type:
Examples
>>> from tmuxp.cli._colors import ColorMode, Colors >>> colors = Colors(ColorMode.NEVER) >>> pattern = SearchPattern( ... fields=("name",), ... raw="dev", ... regex=re.compile("dev"), ... ) >>> highlight_matches("development", [pattern], colors=colors) 'development'
With colors enabled (ALWAYS mode):
>>> colors_on = Colors(ColorMode.ALWAYS) >>> result = highlight_matches("development", [pattern], colors=colors_on) >>> "dev" in result True >>> chr(27) in result # Contains ANSI escape True
- tmuxp.cli.search._output_search_results(results, patterns, formatter, colors)[source]¶
Output search results in human-readable or JSON format.
- Return type:
- Parameters:
results (list[WorkspaceSearchResult]) – Search results to output.
patterns (list[SearchPattern]) – Patterns used for highlighting.
formatter (OutputFormatter) – Output formatter for JSON/NDJSON/human modes.
colors (Colors) – Color manager.
- class tmuxp.cli.search.CLISearchNamespace(**kwargs)[source]¶
Bases:
NamespaceTyped
argparse.Namespacefor tmuxp search command.Examples
>>> ns = CLISearchNamespace() >>> ns.query_terms = ["dev"] >>> ns.query_terms ['dev']
- color: CLIColorModeLiteral¶
- query_terms: list[str]¶
- field: list[str] | None¶
- ignore_case: bool¶
- smart_case: bool¶
- fixed_strings: bool¶
- word_regexp: bool¶
- invert_match: bool¶
- match_any: bool¶
- output_json: bool¶
- output_ndjson: bool¶
- print_help: t.Callable[[], None]¶
- tmuxp.cli.search.create_search_subparser(parser)[source]¶
Augment
argparse.ArgumentParserwithsearchsubcommand.- Return type:
- Parameters:
parser (argparse.ArgumentParser) – The parser to augment.
- Returns:
The augmented parser.
- Return type:
Examples
>>> import argparse >>> parser = argparse.ArgumentParser() >>> result = create_search_subparser(parser) >>> result is parser True
- tmuxp.cli.search.command_search(args=None, parser=None)[source]¶
Entrypoint for
tmuxp searchsubcommand.Searches workspace files in local (cwd and parents) and global (~/.tmuxp/) directories.
- Return type:
- Parameters:
args (CLISearchNamespace | None) – Parsed command-line arguments.
parser (argparse.ArgumentParser | None) – The argument parser (unused but required by CLI interface).
Examples
>>> # command_search() searches workspaces with given patterns