Files
YenandClaude ec1277167b Add comprehensive bash language support (#375)
* feat: Add comprehensive bash language support

Implement BashLanguageServer using bash-language-server (v5.4.0)
- Add automatic Node.js/npm dependency management
- Support .sh and .bash file extensions
- Include cross-platform compatibility (Windows .cmd handling)
- Add comprehensive test infrastructure with realistic bash scripts
- Integrate bash into Language enum and language server factory
- Add bash pytest marker for selective testing
- Include bash_language_server fixture for tests

Features:
* LSP capabilities: text sync, completion, hover, document symbols
* Runtime dependency installation via npm
* Symbol recognition for functions, variables, conditionals
* Proper LSP initialization and error handling
* Test repository with main.sh, utils.sh, and config.sh examples

Files:
+ src/solidlsp/language_servers/bash_language_server.py (new implementation)
+ test/solidlsp/bash/test_bash_basic.py (comprehensive test suite)
+ test/resources/repos/bash/test_repo/ (test scripts)
* src/solidlsp/ls_config.py (add BASH enum and file patterns)
* src/solidlsp/ls.py (integrate bash language server)
* pyproject.toml (add bash pytest marker)
* test/conftest.py (add bash_language_server fixture)

Tests: 2 passed, 7 appropriately skipped
All existing tests continue to pass (288 passed total)

* trigger flow

* feat: enhance bash function detection with hybrid LSP + regex approach

- Upgrade bash-language-server from 5.4.0 to 5.6.0 for better capabilities
- Add hybrid function detection: primary LSP + regex fallback when needed
- Implement _detect_bash_functions() with regex patterns for both syntax types:
  * function name() { } (function keyword syntax)
  * name() { } (regular function syntax)
- Add _find_function_end() with brace matching for accurate function boundaries
- Enhance request_document_symbols() with intelligent fallback logic
- Add comprehensive test suite with 4 new test functions:
  * test_bash_function_detection_hybrid_approach
  * test_bash_function_detection_with_body
  * test_bash_regex_fallback_detection
  * test_bash_function_syntax_patterns
- All tests passing: 6 passed, 7 skipped, 0 failed
- Maintains 100% backward compatibility
- Enables full symbolic operations for bash functions: find_symbol, replace_symbol_body, etc.

* remove trash

* clean: remove debug changes from Python services.py

- Remove 'MODIFIED VIA SYMBOLIC OPERATIONS!' debug comments
- Remove debug print statements added during testing
- Restore original clean docstring and code
- No functional changes to bash language support implementation

* fix: Remove non-bash specific directory ignoring from BashLanguageServer

- Removes is_ignored_dirname override that included generic directories like node_modules, .cache, tmp, temp
- These directories aren't bash-specific and gitignore already handles file exclusion
- Addresses PR feedback: 'that doesn't seem bash related. Note that gitignored files are ignored anyway'

* fix: Restructure bash tests to follow standard patterns and remove pytest.skip

- Replace custom bash_language_server fixture with standard parametrized language_server fixture
- Remove all pytest.skip statements and replace with proper assertions or failures
- Remove tests for non-existent methods (get_symbols_for_document, get_workspace_symbols, etc.)
- Keep only tests that use actual SolidLanguageServer methods like request_document_symbols
- All bash tests now pass successfully
- Addresses PR feedback about test structure and pytest.skip removal

* docs: Add bash language support to README

- Add Bash to the list of directly supported languages
- Note that it requires Node.js and npm for bash-language-server installation
- Addresses PR feedback about missing README extension for bash support

* docs: Add bash language support to CHANGELOG

- Document comprehensive bash language support with bash-language-server integration
- Highlight key features: .sh/.bash extensions, hybrid function detection, automatic dependency management
- Note cross-platform compatibility including Windows support
- Addresses PR feedback about missing CHANGELOG extension for bash support

* refactor: Change regex fallback to always-on hybrid detection for bash functions

- Remove conditional logic that only ran regex when LSP found no functions
- Implement always-on hybrid approach that runs both LSP and regex detection
- Add comprehensive documentation explaining bash-language-server limitations
- Add new _merge_function_detections method to combine results without duplicates
- Addresses reviewer feedback about files with mixed function notation styles

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-06 16:41:04 +02:00

84 lines
1.7 KiB
Bash

#!/bin/bash
# Utility functions for bash scripting
# String manipulation functions
function to_uppercase() {
echo "${1^^}"
}
function to_lowercase() {
echo "${1,,}"
}
function trim_whitespace() {
local var="$1"
var="${var#"${var%%[![:space:]]*}"}"
var="${var%"${var##*[![:space:]]}"}"
echo "$var"
}
# File operations
function backup_file() {
local file="$1"
local backup_dir="${2:-./backups}"
if [[ ! -f "$file" ]]; then
echo "Error: File '$file' does not exist" >&2
return 1
fi
mkdir -p "$backup_dir"
cp "$file" "${backup_dir}/$(basename "$file").$(date +%Y%m%d_%H%M%S).bak"
echo "Backup created for $file"
}
# Array operations
function contains_element() {
local element="$1"
shift
local array=("$@")
for item in "${array[@]}"; do
if [[ "$item" == "$element" ]]; then
return 0
fi
done
return 1
}
# Logging functions
function log_message() {
local level="$1"
local message="$2"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case "$level" in
"ERROR")
echo "[$timestamp] ERROR: $message" >&2
;;
"WARN")
echo "[$timestamp] WARN: $message" >&2
;;
"INFO")
echo "[$timestamp] INFO: $message"
;;
"DEBUG")
[[ "${DEBUG:-false}" == "true" ]] && echo "[$timestamp] DEBUG: $message"
;;
*)
echo "[$timestamp] $message"
;;
esac
}
# Validation functions
function is_valid_email() {
local email="$1"
[[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]
}
function is_number() {
[[ $1 =~ ^[0-9]+$ ]]
}