{"id":46705999,"url":"https://github.com/pppp606/hiliner","last_synced_at":"2026-03-09T08:11:32.504Z","repository":{"id":311037591,"uuid":"1041900236","full_name":"pppp606/hiliner","owner":"pppp606","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-28T14:17:09.000Z","size":646,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-28T21:40:32.185Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pppp606.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-21T07:17:09.000Z","updated_at":"2025-08-28T14:17:14.000Z","dependencies_parsed_at":"2025-08-21T20:07:49.673Z","dependency_job_id":"856c95d5-9cb0-4c7e-943a-9b16a0081a5a","html_url":"https://github.com/pppp606/hiliner","commit_stats":null,"previous_names":["pppp606/hiliner"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pppp606/hiliner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pppp606%2Fhiliner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pppp606%2Fhiliner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pppp606%2Fhiliner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pppp606%2Fhiliner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pppp606","download_url":"https://codeload.github.com/pppp606/hiliner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pppp606%2Fhiliner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30287501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-09T08:11:32.018Z","updated_at":"2026-03-09T08:11:32.482Z","avatar_url":"https://github.com/pppp606.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hiliner\n\nAn interactive CLI file viewer built with Ink (React for CLI) providing a full-screen terminal-based file browser with advanced syntax highlighting and navigation features.\n\n## Features\n\n### Interactive File Viewing\n- **Full-screen terminal interface**: Optimized for seamless file browsing\n- **Keyboard navigation**: Vim-style shortcuts for efficient navigation\n- **Multi-line selection**: Advanced selection system with visual indicators\n\n### Syntax Highlighting\n- **Automatic language detection**: Uses VS Code's machine learning model for accurate language detection\n- **50+ programming languages**: JavaScript, Python, TypeScript, Rust, Go, Java, C++, and many more\n- **60+ themes available**: Choose from the full collection of [Shiki bundled themes](https://shiki.style/themes)\n- **Terminal-optimized rendering**: ANSI escape sequences for fast, colorful display\n- **Fallback support**: Graceful degradation to plain text when highlighting fails\n- **Performance optimized**: Viewport-limited processing with 50MB cache for smooth scrolling\n\n### Multi-Selection Support\n- Select multiple lines for visual highlighting and reference\n- Visual indicators show selected line numbers in the status bar\n- Keyboard shortcuts for efficient selection management\n\n### Status Bar Information\n- Current line and column position\n- File size and total lines\n- Active syntax highlighting theme (when applicable)\n- Selected line count (when multi-selection is active)\n\n### Terminal Navigation\n- Vim-style navigation (arrow keys, page up/down, go to start/end)\n- Smooth scrolling with viewport management\n- iTerm2 optimized display to prevent screen flickering\n\n## Installation\n\n```bash\nnpm install -g hiliner\n```\n\nOr for local development:\n\n```bash\ngit clone \u003crepository-url\u003e\ncd hiliner\nnpm install\nnpm run build\n```\n\n## Usage\n\nLaunch the interactive file viewer:\n\n```bash\nhiliner path/to/file.txt\n\n# With custom theme\nhiliner --theme github-light path/to/file.txt\nhiliner -t monokai path/to/file.txt\nhiliner --theme dracula path/to/file.txt\n```\n\n## Keyboard Shortcuts\n\n### Built-in Navigation\n| Key | Action |\n|-----|--------|\n| `↑` `↓` `j` `k` | Move cursor up/down one line |\n| `b` | Page up (viewport height - 1) |\n| `f` | Page down (viewport height - 1) |\n| `g` | Go to start of file |\n| `G` | Go to end of file |\n| `q` | Quit application |\n\n### Built-in Multi-Selection\n| Key | Action |\n|-----|--------|\n| `Tab` | Toggle selection of current line |\n| `Shift+Tab` | Range selection from previously selected line |\n| `a` | Select all visible lines (within current viewport) |\n| `c` | Clear all selections |\n\n### Built-in File Operations  \n| Key | Action |\n|-----|--------|\n| `r` | Reload current file |\n| `?` | Show help and key bindings |\n\n### Custom Actions (Example)\nUse `hiliner --keymap` to see your complete keymap including custom actions.\n\n| Key | Action | Source |\n|-----|--------|--------|\n| `y` | Copy Selected Text | clipboard.json |\n| `p` | Copy File Path | clipboard.json |\n| `e` | Open in VS Code | development.json |\n| `h` | JavaScript Hello | javascript-test.json |\n\n**Note:** Custom action keys depend on your configuration files in the `actions/` directory.\n\n## Multi-Selection Feature\n\nThe multi-selection feature allows you to highlight and track multiple lines while browsing files:\n\n### Visual Indicators\n- **Selected lines**: Display with highlighted background\n- **Status bar**: Shows count of selected lines (e.g., \"3 selected\")\n- **Line numbers**: Selected lines are visually distinct\n\n### Selection Modes\n- **Individual selection**: Use `Tab` to toggle selection of the current line\n- **Viewport selection**: Use `a` to select all currently visible lines\n- **Clear selection**: Use `d` or `Escape` to deselect all lines\n\n### Use Cases\n- Code review: Mark lines of interest for discussion\n- Documentation: Highlight important sections while reading\n- Debugging: Track multiple error locations or relevant code sections\n- Reference: Mark key lines while navigating large files\n\n## Custom Action System\n\nHiliner supports a powerful custom action system that allows you to create personalized commands and scripts to enhance your file viewing experience.\n\n### Quick Start\n\n1. **View Available Actions**: See all built-in and custom key bindings\n   ```bash\n   hiliner --keymap\n   ```\n\n2. **Create Action Directory**: Set up your custom actions\n   ```bash\n   mkdir actions\n   ```\n\n3. **Add Custom Actions**: Create JSON configuration files\n   ```json\n   {\n     \"$schema\": \"./src/schemas/actionConfig.schema.json\",\n     \"version\": \"1.0.0\",\n     \"actions\": [\n       {\n         \"id\": \"copy-path\",\n         \"name\": \"Copy File Path\",\n         \"description\": \"Copy current file path to clipboard\",\n         \"key\": \"p\",\n         \"script\": \"echo \\\"$FILE_PATH\\\" | pbcopy \u0026\u0026 echo \\\"Copied: $FILE_PATH\\\"\"\n       }\n     ]\n   }\n   ```\n\n4. **Use Your Actions**: Press your custom key bindings in interactive mode\n   ```bash\n   hiliner file.js  # Then press 'p' to copy file path\n   ```\n\n### Configuration Structure\n\n**Directory Layout:**\n```\nyour-project/\n├── actions/           # Auto-loaded custom actions\n│   ├── clipboard.json\n│   ├── development.json\n│   └── analysis.json\n└── scripts/           # External JavaScript files\n    └── javascript/\n        ├── analyze.js\n        └── transform.js\n```\n\n**JSON Configuration Format:**\n```json\n{\n  \"$schema\": \"./src/schemas/actionConfig.schema.json\",\n  \"version\": \"1.0.0\",\n  \"actions\": [\n    {\n      \"id\": \"unique-action-id\",\n      \"name\": \"Display Name\",\n      \"description\": \"What this action does\",\n      \"key\": \"x\",\n      \"script\": \"command to execute\",\n      \"when\": {\n        \"hasSelection\": true\n      }\n    }\n  ]\n}\n```\n\n### Action Types\n\n**1. Shell Commands:**\n```json\n{\n  \"id\": \"open-editor\",\n  \"key\": \"e\",\n  \"script\": \"code \\\"$FILE_PATH\\\"\"\n}\n```\n\n**2. JavaScript Scripts:**\n```json\n{\n  \"id\": \"hello-js\",\n  \"key\": \"h\",\n  \"script\": \"hiliner.updateStatus('Hello from JavaScript!');\"\n}\n```\n\n**3. External JavaScript Files:**\n```json\n{\n  \"id\": \"complex-analysis\",\n  \"key\": \"a\",\n  \"script\": \"scripts/javascript/analyze.js\"\n}\n```\n\n### Environment Variables\n\nYour scripts have access to these environment variables:\n\n| Variable | Description | Example |\n|----------|-------------|---------|\n| `$SELECTED_TEXT` | Content of selected lines | \"line1\\nline2\\nline3\" |\n| `$FILE_PATH` | Absolute path to current file | \"/Users/name/project/file.js\" |\n| `$LINE_START` | First line number in selection | \"5\" |\n| `$LINE_END` | Last line number in selection | \"10\" |\n| `$LANGUAGE` | Detected programming language | \"javascript\" |\n| `$SELECTION_COUNT` | Number of selected lines | \"6\" |\n| `$TOTAL_LINES` | Total lines in file | \"150\" |\n| `$CURRENT_LINE` | Current cursor position | \"25\" |\n\n### JavaScript API\n\nFor JavaScript scripts, use the `hiliner` global object:\n\n```javascript\n// Update status bar\nhiliner.updateStatus('Processing complete!');\n\n// Get file information\nconst info = hiliner.getFileInfo();\nconsole.log(`File: ${info.path} (${info.totalLines} lines)`);\n\n// Get selection information  \nconst selection = hiliner.getSelectionInfo();\nhiliner.updateStatus(`Selected ${selection.selectionCount} lines`);\n\n// Clear status bar\nhiliner.clearStatus();\n```\n\n### Example Configurations\n\n**Clipboard Operations (`actions/clipboard.json`):**\n```json\n{\n  \"version\": \"1.0.0\",\n  \"actions\": [\n    {\n      \"id\": \"copy-selected\",\n      \"name\": \"Copy Selected Text\",\n      \"key\": \"y\",\n      \"script\": \"echo \\\"$SELECTED_TEXT\\\" | pbcopy\",\n      \"when\": { \"hasSelection\": true }\n    },\n    {\n      \"id\": \"copy-path\",\n      \"name\": \"Copy File Path\",\n      \"key\": \"p\",\n      \"script\": \"echo \\\"$FILE_PATH\\\" | pbcopy\"\n    }\n  ]\n}\n```\n\n**Development Tools (`actions/development.json`):**\n```json\n{\n  \"version\": \"1.0.0\", \n  \"actions\": [\n    {\n      \"id\": \"open-vscode\",\n      \"name\": \"Open in VS Code\",\n      \"key\": \"e\",\n      \"script\": \"code \\\"$FILE_PATH\\\"\"\n    },\n    {\n      \"id\": \"run-tests\",\n      \"name\": \"Run Tests\",\n      \"key\": \"t\",\n      \"script\": \"npm test\"\n    }\n  ]\n}\n```\n\n**JavaScript Analysis (`actions/analysis.json`):**\n```json\n{\n  \"version\": \"1.0.0\",\n  \"actions\": [\n    {\n      \"id\": \"file-stats\",\n      \"name\": \"File Statistics\",\n      \"key\": \"s\",\n      \"script\": \"scripts/javascript/file-stats.js\"\n    }\n  ]\n}\n```\n\n**External JavaScript Example (`scripts/javascript/file-stats.js`):**\n```javascript\nconst fs = require('fs');\nconst fileInfo = hiliner.getFileInfo();\n\ntry {\n  const content = fs.readFileSync(fileInfo.path, 'utf-8');\n  const lines = content.split('\\n');\n  \n  const stats = {\n    totalLines: lines.length,\n    nonEmpty: lines.filter(l =\u003e l.trim()).length,\n    comments: lines.filter(l =\u003e l.trim().startsWith('//')).length\n  };\n  \n  hiliner.updateStatus(\n    `📊 ${stats.nonEmpty}/${stats.totalLines} lines, ${stats.comments} comments`\n  );\n} catch (error) {\n  hiliner.updateStatus(`❌ Error: ${error.message}`);\n}\n```\n\n### Conditional Actions\n\nUse the `when` clause to control when actions are available:\n\n```json\n{\n  \"id\": \"copy-selection\",\n  \"key\": \"c\",\n  \"script\": \"echo \\\"$SELECTED_TEXT\\\" | pbcopy\",\n  \"when\": {\n    \"hasSelection\": true\n  }\n}\n```\n\n### Usage Examples\n\n```bash\n# View complete keymap including your custom actions\nhiliner --keymap\n\n# Use custom config file\nhiliner --config my-actions.json file.txt\n\n# Debug mode to see action loading\nhiliner --debug file.txt\n```\n\n## Command Line Options\n\n### Global Options\n```\n-h, --help             Show help message\n-v, --version          Show version information\n-k, --keymap           Show complete keymap (built-in + custom actions)\n-c, --config \u003cpath\u003e    Path to custom action configuration file\n-t, --theme \u003cname\u003e     Set syntax highlighting theme (default: dark-plus)\n--debug                Enable debug mode\n```\n\n### Static Mode Options\n```\n--no-line-numbers      Hide line numbers\n--marker \u003cstring\u003e      Custom line marker (default: \"\u003e\u003e\u003e\")\n--context \u003cnumber\u003e     Lines of context around highlighted lines\n--relative             Use relative line numbering\n-t, --theme \u003cname\u003e     Set syntax highlighting theme (also available in interactive mode)\n```\n\n## Examples\n\n### Interactive Mode Examples\n\n```bash\n# Browse a configuration file\nhiliner config/app.json\n\n# View source code with custom actions\nhiliner src/components/App.tsx\n# Use Tab to select lines of interest\n# Use 'y' to copy selected text (if configured)\n# Use 'p' to copy file path (if configured)\n# Use 'e' to open in VS Code (if configured)\n\n# Use custom configuration\nhiliner --config my-actions.json src/app.js\n\n# View all available key bindings\nhiliner --keymap\n```\n\n### Static Mode Examples\n\n```bash\n# CI/CD: Highlight failed test lines with syntax highlighting\nhiliner test-output.log 45-67 --marker \"FAIL\"\n\n# Code review: Show specific TypeScript changes with syntax colors\nhiliner src/utils.ts 120-125,140,155-160\n\n# Documentation: Extract key sections from Markdown with highlighting\nhiliner README.md 1-10,50-60 --context 2\n\n# View Python function with syntax highlighting and custom marker\nhiliner app.py 25-45 --marker \"\u003e\u003e\u003e\"\n```\n\n### Syntax Highlighting Examples\n\n```bash\n# Interactive mode with automatic language detection\nhiliner src/main.rs                    # Rust syntax highlighting\nhiliner components/App.tsx              # TypeScript/JSX highlighting\nhiliner api/server.py                   # Python highlighting\n\n# Interactive mode with custom themes\nhiliner --theme dracula src/main.rs     # Rust with Dracula theme\nhiliner -t monokai components/App.tsx   # TypeScript with Monokai theme\nhiliner --theme github-dark api/server.py # Python with GitHub Dark theme\n```\n\n### Theme Switching\n\nHiliner supports 60+ syntax highlighting themes from the [Shiki theme collection](https://shiki.style/themes). Use the `--theme` or `-t` option to specify a theme:\n\n```bash\n# Popular themes\nhiliner --theme dark-plus file.js       # VS Code Dark+ (default)\nhiliner --theme monokai file.py         # Monokai\nhiliner --theme dracula file.rs         # Dracula\nhiliner --theme github-dark file.go     # GitHub Dark\nhiliner --theme one-dark-pro file.ts    # One Dark Pro\n\n# Light themes\nhiliner --theme light-plus file.js      # VS Code Light+\nhiliner --theme github-light file.py    # GitHub Light\nhiliner --theme catppuccin-latte file.rs # Catppuccin Latte\n\n# Works in both interactive and static modes\nhiliner --theme nord file.txt           # Interactive with Nord theme\nhiliner --theme solarized-dark # Static with Solarized Dark\n```\n\n**Theme Requirements**:\n- Theme names are case-sensitive and must match exactly (lowercase with hyphens)\n- Invalid theme names will display a warning and fall back to the default `dark-plus` theme\n- In interactive mode, the current theme name is displayed in the status bar\n- For the complete list of available themes, visit the [Shiki themes page](https://shiki.style/themes)\n\n**Error Handling**:\n```bash\n# Invalid theme example\nhiliner --theme invalid-theme file.js\n# Warning: Theme 'invalid-theme' not found. Using default theme 'dark-plus'.\n```\n\n## File Support\n\n### Supported File Types\nHiliner automatically detects and provides syntax highlighting for:\n\n- **JavaScript/TypeScript**: `.js`, `.jsx`, `.ts`, `.tsx`\n- **Python**: `.py`\n- **Rust**: `.rs`\n- **Go**: `.go`\n- **Java**: `.java`\n- **C/C++**: `.c`, `.cpp`, `.h`, `.hpp`\n- **C#**: `.cs`\n- **PHP**: `.php`\n- **Ruby**: `.rb`\n- **Swift**: `.swift`\n- **Kotlin**: `.kt`\n- **Scala**: `.scala`\n- **Shell scripts**: `.sh`, `.bash`, `.zsh`, `.fish`\n- **Web technologies**: `.html`, `.css`, `.scss`, `.json`, `.xml`, `.yaml`\n- **Configuration files**: `.toml`, `.ini`, `.dockerfile`\n- **Documentation**: `.md`, `.rst`\n- **And many more...**\n\nFor files without extensions or unknown types, hiliner uses content-based language detection.\n\n### File Size Limits\n- Default maximum: 10MB\n- Configurable via environment or options\n- Memory-efficient streaming for large files\n\n### Binary File Handling\n- Automatic detection of binary files\n- Graceful fallback with informative message\n- File type detection based on extension and content\n\n## Development\n\n### Building the Project\n\n```bash\nnpm run build          # Compile TypeScript to dist/\nnpm run typecheck      # Type checking without compilation\nnpm run lint           # ESLint with TypeScript and React rules  \nnpm run lint:fix       # Auto-fix ESLint issues\nnpm run format         # Prettier formatting\n```\n\n### Testing\n\n```bash\nnpm test               # Run all tests (Jest with ts-jest)\nnpm run test:watch     # Watch mode for development\nnpm run test:coverage  # Coverage report with 80% threshold\n```\n\n### Running Development Build\n\n```bash\nnpm run build \u0026\u0026 node bin/hiliner.js path/to/file.txt\n```\n\n## Architecture\n\n### Core Components\n- **CLI Entry Point** (`src/cli.ts`): Argument parsing and mode detection\n- **Interactive UI** (`src/components/`): Ink React components for terminal rendering\n- **File Loading** (`src/utils/fileLoader.ts`): Optimized file operations with validation\n- **Multi-Selection** (`src/hooks/useSelection.ts`): State management for line selection\n\n### Performance Features\n- Single text block rendering to prevent DOM fragmentation\n- React.memo usage to minimize re-renders\n- iTerm2 compatibility with height constraints\n- Throttled keyboard input handling\n- Memory-efficient file loading with size limits\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes following the coding guidelines\n4. Add tests for new functionality\n5. Ensure all tests pass (`npm test`)\n6. Run linting and formatting (`npm run lint:fix \u0026\u0026 npm run format`)\n7. Commit your changes (`git commit -m 'Add amazing feature'`)\n8. Push to the branch (`git push origin feature/amazing-feature`)\n9. Open a Pull Request\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details.\n\n## Changelog\n\n### v0.2.0 (Current)\n- **🚀 Custom Action System**: Powerful scripting framework for personalized workflows\n  - JSON-based action configuration with automatic loading from `actions/` directory\n  - Support for shell commands, inline JavaScript, and external JavaScript files\n  - 8 environment variables (`$SELECTED_TEXT`, `$FILE_PATH`, etc.) for context-aware scripting\n  - JavaScript API (`hiliner.updateStatus()`, `hiliner.getFileInfo()`, etc.) for UI integration\n  - Conditional actions with `when` clauses (e.g., `hasSelection: true`)\n  - Schema validation and key binding conflict detection\n- **🗺️ Enhanced Help System**: Complete keymap visualization\n  - `--keymap` command line option to display all available key bindings\n  - Categorized display showing built-in and custom actions with source files\n  - Improved formatting with proper alignment and arrow symbols (↑↓)\n- **⚡ Performance Improvements**: Streamlined key bindings and UI optimizations\n  - Removed redundant PageUp/PageDown alternative key bindings\n  - Optimized action execution pipeline with operation IDs to prevent race conditions\n- **🔧 Developer Experience**: Enhanced configuration and debugging capabilities\n  - `--config` option for custom action configuration files\n  - `--debug` mode for action system troubleshooting\n  - External script file support with automatic API injection\n\n### v0.1.0\n- Initial release with interactive and static modes\n- **Syntax highlighting** for 50+ programming languages using Shiki and VS Code language detection\n- **Automatic language detection** with ML-based content analysis and file extension mapping\n- **Terminal-optimized rendering** with ANSI escape sequences for fast display\n- **Performance optimization** with viewport-limited processing and 50MB caching system\n- Multi-selection functionality with keyboard shortcuts\n- Optimized terminal rendering and navigation\n- File loading with validation and error handling\n- Comprehensive test coverage with end-to-end testing","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpppp606%2Fhiliner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpppp606%2Fhiliner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpppp606%2Fhiliner/lists"}