New linutil website (#1215)
* Add Hugo build artifacts to .gitignore Ignore docs/public/, docs/resources/, and docs/.hugo_build.lock so generated Hugo output is never accidentally committed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add Hugo site infrastructure for Linutil docs Adds the Hugo configuration, theme module (hextra), layout shortcodes, i18n strings, static assets (favicons, nav logo), and archetype template needed to build the documentation site. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add docs site homepage Adds the root _index.md with badges, the quick-start curl command, and an important-note callout about frequent updates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add user guide content pages for Linutil Rewrites all user guide sections from Winutil (Windows) content to accurate Linutil (Linux) documentation: - _index.md: overview, feature summary, quick links - getting-started.md: how to run, install options, TUI navigation, keyboard shortcuts - store/_index.md: application installation guide with category tables - tweaks/_index.md: distro-specific system setup (Arch, Fedora, Debian, Ubuntu, Alpine) - features/_index.md: security, gaming, emulators, and utilities reference - updates/_index.md: how to keep Linutil up to date - automation/_index.md: TOML config file usage and use-case examples Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add FAQ, known issues, and contributing guide pages - faq.md: answers for general usage, running, scripts, contributing, and updates - KnownIssues.md: documents terminal size, rendering, distro support, Nvidia, and Cargo update issues - CONTRIBUTING.md: full contributing guide based on .github/CONTRIBUTING.md, formatted for the docs site Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add developer reference section and architecture docs - dev/_index.md: landing page for the developer reference section - dev/architecture.md: comprehensive architecture doc covering workspace layout, data model (Tab/ListNode/Command), tab_data.toml format, task list flags, preconditions system, script embedding via include_dir!, the script execution pipeline (PTY/vt100/tui-term), TUI layout and focus state machine, config file parsing, and key dependencies Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docgen: write walkthrough to docs/content/userguide/walkthrough.md - Rename generated file from userguide.md to walkthrough.md to better reflect that it is an auto-generated script reference/walkthrough - Update USER_GUIDE path to docs/content/userguide/walkthrough.md so cargo xtask docgen writes to the correct Hugo content location - Update automation guide link to point to ../walkthrough/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: remove unused Winutil screenshot assets All images in docs/assets/images/ were Winutil (Windows) screenshots copied over from the Winutil docs. None are referenced by any content file. Keeping only favicon.png and navlogo.png at the assets root, which are used by hugo.toml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update CNAME * updated hugo configs * docs: add preview.gif to homepage via Hugo mount Mount .github/preview.gif directly into Hugo's static pipeline using includeFiles so only the gif is exposed (no workflows or other .github files). This means any update to .github/preview.gif is automatically reflected on the site without any manual copying. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * added workflow * Delete docs/assets/navlogo.png can change this to something else * Delete navlogo.png * Update docs.yaml * Update hugo.toml * Update _index.md * fix typo --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@@ -0,0 +1,87 @@
|
||||
name: Deploy Hugo site to Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "docs/**"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository == 'ChrisTitusTech/linutil'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
HUGO_VERSION: 0.147.7
|
||||
HUGO_ENVIRONMENT: production
|
||||
TZ: America/Chicago
|
||||
steps:
|
||||
- name: Install Hugo CLI
|
||||
run: |
|
||||
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
|
||||
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: "cd docs && [[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
|
||||
- name: Cache Restore
|
||||
id: cache-restore
|
||||
uses: actions/cache/restore@v5
|
||||
with:
|
||||
path: |
|
||||
${{ runner.temp }}/hugo_cache
|
||||
key: hugo-${{ github.run_id }}
|
||||
restore-keys: hugo-
|
||||
- name: Build with Hugo
|
||||
run: |
|
||||
hugo \
|
||||
--gc \
|
||||
--minify \
|
||||
--cleanDestinationDir \
|
||||
--source docs \
|
||||
--cacheDir "${{ runner.temp }}/hugo_cache"
|
||||
- name: Cache Save
|
||||
id: cache-save
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
path: |
|
||||
${{ runner.temp }}/hugo_cache
|
||||
key: ${{ steps.cache-restore.outputs.cache-primary-key }}
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: ./docs/public
|
||||
|
||||
deploy:
|
||||
if: github.repository == 'ChrisTitusTech/linutil'
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
@@ -4,3 +4,9 @@
|
||||
rust/target
|
||||
rust/build
|
||||
/build/linutil
|
||||
|
||||
# Hugo Files
|
||||
docs/public/
|
||||
docs/.hugo_build.lock
|
||||
docs/resources/
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||
description: ""
|
||||
date: '{{ .Date }}'
|
||||
draft: true
|
||||
---
|
||||
|
After Width: | Height: | Size: 9.6 KiB |
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Contributing Guide
|
||||
toc: true
|
||||
---
|
||||
|
||||
Thank you for considering contributing to Linutil! We appreciate your effort in helping improve this project. Please follow these guidelines to make the contribution process smooth for everyone.
|
||||
|
||||
## 1. Install Rust
|
||||
|
||||
Make sure you have Rust installed on your machine:
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
Or visit [rust-lang.org](https://www.rust-lang.org/tools/install) for full instructions.
|
||||
|
||||
## 2. Fork and Clone the Repo
|
||||
|
||||
1. Fork the repository on GitHub
|
||||
2. Clone your fork locally:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOUR_USERNAME/linutil.git
|
||||
cd linutil
|
||||
```
|
||||
|
||||
## 3. Make Your Changes
|
||||
|
||||
- Edit the relevant files
|
||||
- Run `cargo run` to test your changes locally
|
||||
- Ensure everything works as expected before submitting
|
||||
|
||||
## 4. Adding a New Script
|
||||
|
||||
If you're adding a new shell script:
|
||||
|
||||
1. Place it in the appropriate subdirectory under `tabs/`
|
||||
2. Fill out **all fields** in `tab_data.toml` for your script
|
||||
3. Run `cargo xtask docgen` to regenerate the documentation
|
||||
|
||||
Without completing `tab_data.toml` and running `docgen`, your script will not appear in the TUI or the documentation.
|
||||
|
||||
## 5. Understand the Existing Code
|
||||
|
||||
- **Have a clear reason**: Don't change the way things are done without a valid reason. Be prepared to explain why a change is necessary and how it improves the project.
|
||||
- **Respect existing conventions**: Changes should align with the existing code style and project philosophy.
|
||||
|
||||
## 6. Learn from Past Pull Requests
|
||||
|
||||
- **Check merged PRs**: Reviewing accepted contributions gives you a sense of what is welcome.
|
||||
- **Study rejected PRs**: This helps you avoid mistakes and proposals that have already been declined.
|
||||
|
||||
## 7. Write Clean Commit Messages
|
||||
|
||||
- Use the **imperative mood**: "Add feature X" not "Added feature X"
|
||||
- Be descriptive about what changed and why
|
||||
- Avoid committing a change and then immediately following it with a fix — amend or squash instead
|
||||
|
||||
## 8. Keep PRs Small and Focused
|
||||
|
||||
- One feature or fix per pull request
|
||||
- Avoid combining unrelated changes in a single PR — it makes review harder and may delay merging
|
||||
|
||||
## 9. Test Your Code
|
||||
|
||||
- Review your code for readability and correctness before submitting
|
||||
- Do not submit AI-generated code without thoroughly reviewing and testing it first
|
||||
- Failure to test after multiple review requests may result in the PR being closed
|
||||
|
||||
## 10. Code Review
|
||||
|
||||
- All PRs go through code review — expect feedback and be open to revisions
|
||||
- If you're comfortable, reviewing other contributors' PRs is a great way to give back
|
||||
|
||||
## 11. Contributing Beyond Code
|
||||
|
||||
- **Test the tool** across different distros and report issues
|
||||
- **Write clear bug reports** with steps to reproduce, distro info, and error output
|
||||
- **Propose reasonable feature requests** that fit the scope and style of the project
|
||||
- **Improve documentation** to help other users
|
||||
|
||||
## 12. License
|
||||
|
||||
By contributing to Linutil, you agree that your contributions will be licensed under the project's [MIT License](https://github.com/ChrisTitusTech/linutil/blob/main/LICENSE).
|
||||
|
||||
---
|
||||
|
||||
We look forward to your contributions — thank you for helping make Linutil better for everyone!
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Known Issues
|
||||
toc: true
|
||||
---
|
||||
|
||||
This page tracks known issues and limitations in Linutil. If you encounter a bug not listed here, please [open an issue on GitHub](https://github.com/ChrisTitusTech/linutil/issues).
|
||||
|
||||
## Terminal Compatibility
|
||||
|
||||
### Minimum Terminal Size
|
||||
|
||||
Linutil requires a minimum terminal size to display the TUI correctly. If your terminal is too small, you will see a warning and the TUI will not load.
|
||||
|
||||
**Workaround**: Resize your terminal to be larger, or use the `--size-bypass` flag:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh -s -- --size-bypass
|
||||
```
|
||||
|
||||
### Rendering Issues in Some Terminals
|
||||
|
||||
The TUI is built with `ratatui` and tested against common terminals (Alacritty, Kitty, GNOME Terminal, Konsole, etc.). Older or minimalist terminals may have rendering issues with box-drawing characters.
|
||||
|
||||
**Workaround**: Use a modern terminal emulator.
|
||||
|
||||
## Script-Specific Issues
|
||||
|
||||
### Scripts May Fail on Unsupported Distros
|
||||
|
||||
Some scripts are written for a specific distribution (e.g., Arch, Fedora). Running them on an unsupported distro may fail or produce unexpected results.
|
||||
|
||||
**Workaround**: Only run scripts listed under your distro's section in **System Setup**, or scripts that are explicitly distro-agnostic.
|
||||
|
||||
### Nvidia Driver Scripts Require Manual Steps on Some Systems
|
||||
|
||||
The Nvidia driver installation scripts may not cover every hardware configuration. Secure Boot, older GPUs, or custom kernel setups can cause driver installation to fail.
|
||||
|
||||
**Workaround**: Refer to your distro's official Nvidia documentation for manual installation if the script fails.
|
||||
|
||||
### Cargo Installs Require Manual Updates
|
||||
|
||||
If you installed Linutil via `cargo install linutil_tui`, updates are not automatic.
|
||||
|
||||
**Workaround**: Use the built-in **Linutil Updater** script inside the TUI, or run:
|
||||
|
||||
```bash
|
||||
cargo install --force linutil_tui
|
||||
```
|
||||
|
||||
## Active Development
|
||||
|
||||
Linutil is under active development. Since scripts are contributed by the community and updated frequently, some scripts may:
|
||||
|
||||
- Lag behind upstream package name changes
|
||||
- Temporarily break after a distro update changes a package or dependency
|
||||
- Not yet cover all edge cases for every distro version
|
||||
|
||||
**Workaround**: Check [open issues](https://github.com/ChrisTitusTech/linutil/issues) and [recent pull requests](https://github.com/ChrisTitusTech/linutil/pulls) for known fixes. Running the stable curl command always fetches the latest release:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh
|
||||
```
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
When opening a bug report, please include:
|
||||
|
||||
- Your Linux distribution and version
|
||||
- Terminal emulator being used
|
||||
- The exact script or menu item that failed
|
||||
- The full error output from the terminal
|
||||
- Steps to reproduce the issue
|
||||
|
||||
[Open an issue on GitHub →](https://github.com/ChrisTitusTech/linutil/issues/new)
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Welcome to Linutil Documentation!
|
||||
toc: false
|
||||
width: full
|
||||
---
|
||||
|
||||
<div style="display: flex; justify-content: center; align-items: center; width: 100%; flex-wrap: wrap; gap: 5px;margin-top:30px;" >
|
||||
<a href="https://img.shields.io/github/v/release/ChrisTitusTech/linutil?color=%230567ff&label=Latest%20Release&style=for-the-badge"><img src="https://img.shields.io/github/v/release/ChrisTitusTech/linutil?color=%230567ff&label=Latest%20Release&style=for-the-badge" alt="Version" style="height: 28px; width: auto; min-width: 10px; object-fit: contain; margin: 0;"></a>
|
||||
<img src="https://img.shields.io/github/downloads/ChrisTitusTech/linutil/linutil?label=Total%20Downloads&style=for-the-badge" alt="GitHub Downloads" style="height: 28px; width: auto; min-width: 10px; object-fit: contain; margin: 0;">
|
||||
<a href="https://discord.gg/RUbZUZyByQ"><img src="https://dcbadge.limes.pink/api/server/https://discord.gg/RUbZUZyByQ" alt="Discord Community Server" style="height: 28px; width: auto; min-width: 10px; object-fit: contain; margin: 0;"></a>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin: 24px 0;">
|
||||
<img src="/preview.gif" alt="Linutil preview" style="max-width: 100%; border-radius: 8px;">
|
||||
</div>
|
||||
|
||||
Welcome to the official documentation for Linutil, your go-to utility for optimizing and managing your Linux environment. Whether you’re an IT professional, power user, or regular user, Linutil provides a comprehensive set of tools to enhance your Linux experience.
|
||||
|
||||
## Running the latest release of Linutil
|
||||
|
||||
* You will first need to start a terminal.
|
||||
* Now you can run the following command:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh
|
||||
```
|
||||
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Linutil is updated frequently as of the time of writing. Consequently, features and functionalities may evolve, and the documentation may not always reflect the most current images or information.
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: Developer Reference
|
||||
weight: 3
|
||||
toc: false
|
||||
---
|
||||
|
||||
> [!NOTE]
|
||||
> This section contains technical documentation for developers. For end-user documentation, see the [User Guide](../userguide/).
|
||||
|
||||
## Architecture
|
||||
|
||||
- [Architecture & Design](architecture/) - Code structure, data flow, and how Linutil works internally
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
---
|
||||
title: Architecture & Design
|
||||
weight: 1
|
||||
toc: true
|
||||
---
|
||||
|
||||
This document describes how Linutil is structured internally — the crate layout, data model, TUI design, script execution pipeline, and the build tooling.
|
||||
|
||||
## Workspace Layout
|
||||
|
||||
Linutil is a Cargo workspace with three crates:
|
||||
|
||||
```
|
||||
linutil/
|
||||
├── core/ # linutil_core — backend library
|
||||
├── tui/ # linutil_tui — binary (the TUI you run)
|
||||
└── xtask/ # build tooling (cargo xtask docgen)
|
||||
```
|
||||
|
||||
### `core/` — `linutil_core`
|
||||
|
||||
The library crate. Responsible for:
|
||||
|
||||
- Defining the data model (`Tab`, `ListNode`, `Command`)
|
||||
- Parsing all `tab_data.toml` files and building the menu tree
|
||||
- **Embedding all scripts into the binary at compile time** using `include_dir!`
|
||||
- Extracting embedded scripts to a temp directory at runtime
|
||||
- Evaluating preconditions to filter out scripts unsupported on the current system
|
||||
- Parsing the user's TOML config file
|
||||
|
||||
### `tui/` — `linutil_tui`
|
||||
|
||||
The binary crate. Responsible for:
|
||||
|
||||
- Setting up the terminal (crossterm alternate screen, raw mode)
|
||||
- Running the main event loop
|
||||
- Rendering the entire TUI layout via `ratatui`
|
||||
- Handling all keyboard and mouse input
|
||||
- Launching scripts in a pseudo-terminal (PTY) via `portable-pty`
|
||||
- Parsing CLI arguments via `clap`
|
||||
|
||||
### `xtask/`
|
||||
|
||||
Cargo's task runner extension. Run with:
|
||||
|
||||
```bash
|
||||
cargo xtask docgen
|
||||
```
|
||||
|
||||
This reads all `tab_data.toml` files and generates `docs/content/userguide/userguide.md` — the auto-generated walkthrough page. **Always run this after adding or editing a script entry.**
|
||||
|
||||
---
|
||||
|
||||
## Data Model
|
||||
|
||||
The menu is a tree of `ListNode` items, grouped into named `Tab`s.
|
||||
|
||||
### `Tab`
|
||||
|
||||
```rust
|
||||
pub struct Tab {
|
||||
pub name: String,
|
||||
pub tree: Tree<Rc<ListNode>>,
|
||||
}
|
||||
```
|
||||
|
||||
Each `Tab` maps to one top-level category. The five built-in tabs are defined in `core/tabs/tabs.toml`:
|
||||
|
||||
```toml
|
||||
directories = [
|
||||
"applications-setup",
|
||||
"gaming",
|
||||
"security",
|
||||
"system-setup",
|
||||
"utils"
|
||||
]
|
||||
```
|
||||
|
||||
### `ListNode`
|
||||
|
||||
```rust
|
||||
pub struct ListNode {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub command: Command,
|
||||
pub task_list: String,
|
||||
pub multi_select: bool,
|
||||
}
|
||||
```
|
||||
|
||||
Every item in the TUI is a `ListNode`. A node is either a **directory** (has children, `command = Command::None`) or a **leaf command** (no children, has a runnable `command`).
|
||||
|
||||
### `Command`
|
||||
|
||||
```rust
|
||||
pub enum Command {
|
||||
Raw(String), // inline shell command
|
||||
LocalFile { // shell script file
|
||||
executable: String,
|
||||
args: Vec<String>,
|
||||
file: PathBuf,
|
||||
},
|
||||
None, // directory node
|
||||
}
|
||||
```
|
||||
|
||||
- `Raw` — a short command string run directly by the shell
|
||||
- `LocalFile` — a script file whose interpreter is read from the shebang line (e.g. `#!/bin/bash`)
|
||||
- `None` — marks a category/folder node
|
||||
|
||||
---
|
||||
|
||||
## Tab Data Format
|
||||
|
||||
Each tab is defined by a `tab_data.toml` file inside `core/tabs/<tab-name>/`. Example:
|
||||
|
||||
```toml
|
||||
name = "Applications Setup"
|
||||
|
||||
[[data]]
|
||||
name = "Communication Apps"
|
||||
|
||||
[[data.entries]]
|
||||
name = "Discord"
|
||||
description = "Discord is a versatile communication platform..."
|
||||
script = "communication-apps/discord-setup.sh"
|
||||
task_list = "I"
|
||||
|
||||
[[data.entries]]
|
||||
name = "Some Inline Command"
|
||||
description = "Runs a quick command"
|
||||
command = "echo hello"
|
||||
task_list = "MP"
|
||||
```
|
||||
|
||||
### Entry Fields
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| `name` | Yes | Display name shown in the TUI |
|
||||
| `description` | No | Shown in the description floating window (`d` key) |
|
||||
| `script` | One of | Path to a shell script (relative to the tab directory) |
|
||||
| `command` | One of | Inline shell command string |
|
||||
| `entries` | One of | Nested sub-entries (makes this node a directory) |
|
||||
| `task_list` | No | One or more flag codes shown next to the item name |
|
||||
| `multi_select` | No | Whether this command can be queued in multi-select mode (default: `true`) |
|
||||
| `preconditions` | No | Conditions that must pass for the entry to be shown |
|
||||
|
||||
### Task List Flags
|
||||
|
||||
Flags shown to the right of each command name, defined in `state.rs`:
|
||||
|
||||
| Flag | Meaning |
|
||||
|------|---------|
|
||||
| `D` | Disk modifications (privileged) |
|
||||
| `FI` | Flatpak installation |
|
||||
| `FM` | File modification |
|
||||
| `I` | Installation (privileged) |
|
||||
| `K` | Kernel modifications (privileged) |
|
||||
| `MP` | Package manager actions |
|
||||
| `SI` | Full system installation |
|
||||
| `SS` | Systemd actions (privileged) |
|
||||
| `RP` | Package removal |
|
||||
|
||||
---
|
||||
|
||||
## Preconditions
|
||||
|
||||
Preconditions let a script declare when it should be visible. If any precondition fails, the entry is hidden from the TUI.
|
||||
|
||||
```toml
|
||||
[[data.entries]]
|
||||
name = "Paru AUR Helper"
|
||||
script = "paru-setup.sh"
|
||||
|
||||
[[data.entries.preconditions]]
|
||||
matches = true
|
||||
data = { containing_file = "/etc/os-release" }
|
||||
values = ["Arch Linux", "Manjaro"]
|
||||
```
|
||||
|
||||
### Precondition Types
|
||||
|
||||
| Type | Checks |
|
||||
|------|--------|
|
||||
| `environment` | Whether an environment variable equals one of the given values |
|
||||
| `containing_file` | Whether a file's contents contain all of the given strings |
|
||||
| `command_exists` | Whether a command is present on `$PATH` |
|
||||
| `file_exists` | Whether a file path exists on disk |
|
||||
|
||||
The `matches` field inverts the check when `false` (i.e. "must NOT match").
|
||||
|
||||
---
|
||||
|
||||
## Script Embedding
|
||||
|
||||
All files under `core/tabs/` are embedded into the compiled binary at build time using the `include_dir!` macro:
|
||||
|
||||
```rust
|
||||
const TAB_DATA: Dir = include_dir!("$CARGO_MANIFEST_DIR/tabs");
|
||||
```
|
||||
|
||||
At runtime, `get_tabs()` extracts the embedded directory to a system temp directory (`/tmp/linutil_scripts_XXXX`), and all `LocalFile` commands reference scripts inside that temp dir. The temp directory is cleaned up automatically when `TabList` is dropped.
|
||||
|
||||
This means **a single binary contains everything** — no external script files needed after build.
|
||||
|
||||
---
|
||||
|
||||
## Script Execution Pipeline
|
||||
|
||||
When a user selects a command and confirms it:
|
||||
|
||||
1. `AppState::handle_confirm_command()` creates a `RunningCommand` from the list of selected `Command` values
|
||||
2. `RunningCommand::new()` allocates a PTY via `portable-pty` (`NativePtySystem`)
|
||||
3. The command is spawned inside the PTY as a child process
|
||||
4. A **reader thread** reads output from the PTY master and writes it into a shared `Arc<Mutex<Vec<u8>>>` buffer
|
||||
5. An **atomic flag** (`TERMINAL_UPDATED`) is set when new output arrives, triggering a TUI redraw
|
||||
6. The PTY output is decoded by a `vt100` parser and rendered as a `PseudoTerminal` widget (from `tui-term`) inside a floating window
|
||||
7. The user can scroll up/down to review output, or press `Ctrl-C` to kill the process
|
||||
8. When the process exits, the floating window title changes to `SUCCESS` (green) or `FAILED` (red)
|
||||
|
||||
Using a real PTY (instead of piped stdio) means scripts that use terminal colors, interactive prompts, or check `isatty()` work correctly.
|
||||
|
||||
---
|
||||
|
||||
## TUI Layout
|
||||
|
||||
The TUI is rendered by `AppState::draw()` and divided into these regions:
|
||||
|
||||
```
|
||||
┌──────────────┬────────────────────────────────┐
|
||||
│ Logo / │ [ Search bar ] │
|
||||
│ Version ├────────────────────────────────┤
|
||||
│ │ │
|
||||
│ Tab List │ Item List │
|
||||
│ │ │
|
||||
│ System Info │ │
|
||||
├──────────────┴────────────────────────────────┤
|
||||
│ Keyboard hint bar │
|
||||
└───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **Left column**: Logo (or version label), tab list, system info panel
|
||||
- **Right column**: Search bar (top) + scrollable item list
|
||||
- **Bottom bar**: Context-sensitive keyboard shortcut hints
|
||||
- **Floating windows**: Overlaid on the item list for running commands, previews, descriptions, and confirmation prompts
|
||||
|
||||
### Focus State Machine
|
||||
|
||||
`AppState` tracks a `Focus` enum:
|
||||
|
||||
| State | Description |
|
||||
|-------|-------------|
|
||||
| `TabList` | User is navigating the left tab panel |
|
||||
| `List` | User is navigating the item list |
|
||||
| `Search` | The search bar is active |
|
||||
| `FloatingWindow` | A modal is open (preview, description, running command, guide) |
|
||||
| `ConfirmationPrompt` | User is being asked to confirm before running a command |
|
||||
|
||||
Input is dispatched to the currently focused component.
|
||||
|
||||
---
|
||||
|
||||
## Config File
|
||||
|
||||
Linutil reads an optional TOML config file at startup (`--config path`). The `linutil_core::Config` struct deserializes it:
|
||||
|
||||
```rust
|
||||
pub struct Config {
|
||||
auto_execute: Option<Vec<String>>,
|
||||
skip_confirmation: Option<bool>,
|
||||
size_bypass: Option<bool>,
|
||||
}
|
||||
```
|
||||
|
||||
After parsing, `auto_execute` command names are looked up by name in the loaded `TabList` (using `Tab::find_command_by_name`), and the resulting `Vec<Rc<ListNode>>` is placed directly into `selected_commands` to be run immediately on startup.
|
||||
|
||||
---
|
||||
|
||||
## Adding a New Script
|
||||
|
||||
1. Create a shell script in `core/tabs/<tab-name>/<category>/your-script.sh`
|
||||
2. Add an entry to the corresponding `tab_data.toml`:
|
||||
|
||||
```toml
|
||||
[[data.entries]]
|
||||
name = "Your Script"
|
||||
description = "What it does."
|
||||
script = "<category>/your-script.sh"
|
||||
task_list = "I"
|
||||
```
|
||||
|
||||
3. Add preconditions if the script is distro-specific
|
||||
4. Run `cargo xtask docgen` to update the documentation
|
||||
5. Run `cargo run` to test it locally
|
||||
|
||||
---
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
| Crate | Purpose |
|
||||
|-------|---------|
|
||||
| `ratatui` | TUI rendering framework |
|
||||
| `crossterm` | Cross-platform terminal control (raw mode, events) |
|
||||
| `portable-pty` | Pseudo-terminal allocation for running commands |
|
||||
| `tui-term` | PTY output rendering widget for ratatui |
|
||||
| `vt100-ctt` | VT100 terminal emulator (parses ANSI escape codes) |
|
||||
| `ego-tree` | Generic tree structure used for the menu |
|
||||
| `include_dir` | Embed entire directory trees into the binary at compile time |
|
||||
| `serde` + `toml` | Deserialize `tab_data.toml` and config files |
|
||||
| `clap` | CLI argument parsing |
|
||||
| `tree-sitter-bash` | Bash syntax highlighting in script previews |
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "Features"
|
||||
weight: 1
|
||||
toc: false
|
||||
---
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Tweaks"
|
||||
weight: 2
|
||||
toc: false
|
||||
---
|
||||
@@ -0,0 +1,117 @@
|
||||
---
|
||||
title: Frequently Asked Questions
|
||||
toc: true
|
||||
---
|
||||
|
||||
## General
|
||||
|
||||
### What is Linutil?
|
||||
|
||||
Linutil is Chris Titus Tech's Linux Utility — a distro-agnostic TUI toolbox built in Rust for installing apps, configuring your system, and running common Linux setup tasks.
|
||||
|
||||
### Is Linutil safe to use?
|
||||
|
||||
Yes. All scripts are open source and available on [GitHub](https://github.com/ChrisTitusTech/linutil). You can inspect any script before running it. However, always review what a script does before executing it, as some scripts make significant system changes.
|
||||
|
||||
### What Linux distributions does Linutil support?
|
||||
|
||||
Linutil is distro-agnostic — it runs on any modern Linux distribution. Some scripts are distro-specific (Arch, Fedora, Debian, Ubuntu, Alpine), while others work across all distros.
|
||||
|
||||
### Does Linutil require root/sudo?
|
||||
|
||||
Linutil itself does not require root to launch. Individual scripts that make system-level changes will prompt for `sudo` when needed.
|
||||
|
||||
---
|
||||
|
||||
## Running Linutil
|
||||
|
||||
### How do I run Linutil?
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh
|
||||
```
|
||||
|
||||
### What's the difference between the stable and dev branch?
|
||||
|
||||
- **Stable** (`https://christitus.com/linux`) — Tested, recommended for daily use
|
||||
- **Dev** (`https://christitus.com/linuxdev`) — Latest commits, may be unstable
|
||||
|
||||
### Can I install Linutil permanently?
|
||||
|
||||
Yes. It's available via:
|
||||
- **AUR** (Arch): `paru -S linutil` or `paru -S linutil-bin`
|
||||
- **openSUSE**: `sudo zypper install linutil`
|
||||
- **Cargo**: `cargo install linutil_tui`
|
||||
|
||||
### The TUI won't open — it says my terminal is too small
|
||||
|
||||
Resize your terminal window to be larger, or bypass the size check:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh -s -- --size-bypass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scripts & Features
|
||||
|
||||
### How do I find a specific script in the TUI?
|
||||
|
||||
Press `/` while in the TUI to open the search filter and type part of the script name.
|
||||
|
||||
### Can I run scripts without the interactive TUI?
|
||||
|
||||
Yes, using a TOML config file with `auto_execute`. See the [Automation guide](userguide/automation/) for details.
|
||||
|
||||
### A script failed — what should I do?
|
||||
|
||||
1. Check the error output shown in the terminal
|
||||
2. Make sure your system is fully updated before running scripts
|
||||
3. Search [GitHub Issues](https://github.com/ChrisTitusTech/linutil/issues) for the same error
|
||||
4. Open a new issue if it hasn't been reported
|
||||
|
||||
### Can I undo changes made by a script?
|
||||
|
||||
This depends on the script. Some changes (like installing packages) can be reversed manually. For major system changes, it's good practice to have backups or snapshots beforehand (e.g., using Btrfs + Snapper on Fedora).
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
### How can I contribute?
|
||||
|
||||
See the [Contributing Guide](contributing/) for full details. In short:
|
||||
|
||||
1. Fork and clone the repo
|
||||
2. Make your changes (scripts go in the appropriate `tabs/` subdirectory)
|
||||
3. Test with `cargo run`
|
||||
4. Submit a pull request
|
||||
|
||||
### How do I add a new script?
|
||||
|
||||
Fill out all fields in `tab_data.toml` for your script, then run `cargo xtask docgen` to regenerate the documentation. See the [Contributing Guide](contributing/) for more.
|
||||
|
||||
### Where do I report bugs?
|
||||
|
||||
Open an issue on [GitHub](https://github.com/ChrisTitusTech/linutil/issues). Include your distro, terminal, and any relevant error output.
|
||||
|
||||
---
|
||||
|
||||
## Updates
|
||||
|
||||
### How do I update Linutil?
|
||||
|
||||
- **Curl method**: Just re-run `curl -fsSL https://christitus.com/linux | sh` — it always fetches the latest
|
||||
- **Cargo**: Use the built-in **Linutil Updater** script, or run `cargo install --force linutil_tui`
|
||||
- **AUR**: `paru -Syu linutil`
|
||||
- **openSUSE**: `sudo zypper update linutil`
|
||||
|
||||
### How do I check what version I'm running?
|
||||
|
||||
```bash
|
||||
linutil --version
|
||||
```
|
||||
|
||||
### Where can I see release notes?
|
||||
|
||||
On the [GitHub Releases page](https://github.com/ChrisTitusTech/linutil/releases).
|
||||
@@ -0,0 +1,127 @@
|
||||
---
|
||||
title: User Guide
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Welcome to the official User Guide for **Linutil**, Chris Titus Tech's Linux Utility!
|
||||
|
||||
## What is Linutil?
|
||||
|
||||
Linutil is a distro-agnostic toolbox designed to simplify everyday Linux tasks. Built in Rust for performance and reliability, it provides an interactive terminal UI (TUI) that helps you:
|
||||
|
||||
- **Install Applications**: Quickly set up popular software for your Linux system
|
||||
- **System Setup**: Configure your distro with optimized settings and tools
|
||||
- **Security**: Apply firewall baselines and harden your system
|
||||
- **Utilities**: Manage monitors, printers, Bluetooth, WiFi, and more
|
||||
- **Gaming**: Set up gaming dependencies and emulators
|
||||
|
||||
## Who Should Use Linutil?
|
||||
|
||||
Linutil is designed for:
|
||||
|
||||
- **Linux Beginners**: Wanting an easy way to set up a fresh install
|
||||
- **Power Users**: Needing quick access to common configuration tasks
|
||||
- **Developers**: Setting up clean development environments fast
|
||||
- **Gamers**: Installing gaming dependencies and optimizing Linux for gaming
|
||||
- **Privacy-Conscious Users**: Applying firewall rules and security hardening
|
||||
|
||||
## Getting Started
|
||||
|
||||
New to Linutil? Start here:
|
||||
|
||||
1. **[Getting Started Guide](getting-started/)** - How to run Linutil and navigate the TUI
|
||||
2. **[Application Setup](store/)** - Installing software via the TUI
|
||||
3. **[System Setup](tweaks/)** - Distro-specific setup and configuration
|
||||
4. **[Features & Utilities](features/)** - Security, gaming, and utility tools
|
||||
5. **[Automation](automation/)** - Run Linutil unattended with a config file
|
||||
|
||||
## Running Linutil
|
||||
|
||||
### Stable Branch (Recommended)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh
|
||||
```
|
||||
|
||||
### Dev Branch
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linuxdev | sh
|
||||
```
|
||||
|
||||
## Main Categories
|
||||
|
||||
### Applications Setup
|
||||
|
||||
Browse and install hundreds of popular Linux applications from within the TUI. Categories include browsers, developer tools, communication apps, design tools, and more.
|
||||
|
||||
**[Read the Application Setup Guide →](store/)**
|
||||
|
||||
### System Setup
|
||||
|
||||
Distro-specific scripts for Arch, Fedora, Debian, Ubuntu, and more. Includes AUR helpers, desktop environment installers, driver setup, and system configuration.
|
||||
|
||||
**[Read the System Setup Guide →](tweaks/)**
|
||||
|
||||
### Security
|
||||
|
||||
Apply firewall baselines using UFW or FirewallD, following CTT's recommended security rules.
|
||||
|
||||
**[Read the Features Guide →](features/)**
|
||||
|
||||
### Utilities
|
||||
|
||||
Tools for monitor management, printer setup, Bluetooth, WiFi, service management, and more.
|
||||
|
||||
**[Read the Features Guide →](features/)**
|
||||
|
||||
### Gaming
|
||||
|
||||
Install gaming dependencies, emulators, and game-specific optimizations.
|
||||
|
||||
**[Read the Features Guide →](features/)**
|
||||
|
||||
### Automation
|
||||
|
||||
Run Linutil automatically with a TOML config file for scripted or batch setups.
|
||||
|
||||
**[Read the Automation Guide →](automation/)**
|
||||
|
||||
## Quick Links
|
||||
|
||||
| I want to... | Go to... |
|
||||
|--------------|----------|
|
||||
| Run Linutil for the first time | [Getting Started](getting-started/) |
|
||||
| Install applications | [Application Setup](store/) |
|
||||
| Set up Arch Linux | [System Setup](tweaks/) |
|
||||
| Harden my firewall | [Features & Utilities](features/) |
|
||||
| Automate Linutil for multiple machines | [Automation](automation/) |
|
||||
|
||||
## Safety and Best Practices
|
||||
|
||||
Before using Linutil:
|
||||
|
||||
- Read what each script does before running it
|
||||
- Test on non-production systems when trying new configurations
|
||||
- Keep backups of important configuration files
|
||||
|
||||
## Getting Help
|
||||
|
||||
Need assistance?
|
||||
|
||||
- **Documentation**: You're reading it! Use the navigation menu
|
||||
- **FAQ**: Check [Frequently Asked Questions](../faq/)
|
||||
- **Known Issues**: Review [Known Issues](../knownissues/)
|
||||
- **Discord**: Join the [community Discord](https://discord.gg/RUbZUZyByQ)
|
||||
- **GitHub**: Report bugs on [GitHub Issues](https://github.com/ChrisTitusTech/linutil/issues)
|
||||
|
||||
## Contributing
|
||||
|
||||
Want to help improve Linutil?
|
||||
|
||||
- **Report Bugs**: Submit issues on GitHub
|
||||
- **Suggest Features**: Open feature requests
|
||||
- **Contribute Scripts**: Add new bash scripts
|
||||
- **Improve Docs**: Help expand this documentation
|
||||
|
||||
**[Read Contributing Guide →](../contributing/)**
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: Automation
|
||||
weight: 6
|
||||
---
|
||||
|
||||
Linutil supports automation via a TOML config file. This lets you run predefined scripts automatically — useful for setting up multiple machines, provisioning servers, or scripting a consistent Linux environment.
|
||||
|
||||
## Config File
|
||||
|
||||
Create a TOML file with your desired settings:
|
||||
|
||||
```toml
|
||||
# example_config.toml
|
||||
|
||||
auto_execute = [
|
||||
"Fastfetch",
|
||||
"Alacritty",
|
||||
"Kitty"
|
||||
]
|
||||
|
||||
skip_confirmation = true
|
||||
size_bypass = true
|
||||
```
|
||||
|
||||
Then run Linutil with your config:
|
||||
|
||||
```bash
|
||||
linutil --config /path/to/example_config.toml
|
||||
```
|
||||
|
||||
Or via the one-liner:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh -s -- --config /path/to/example_config.toml
|
||||
```
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `auto_execute` | list of strings | Script names to run automatically on launch |
|
||||
| `skip_confirmation` | boolean | Skip confirmation prompts before running scripts |
|
||||
| `size_bypass` | boolean | Bypass terminal size requirements |
|
||||
|
||||
## CLI Flags
|
||||
|
||||
The same options are available as command-line flags:
|
||||
|
||||
```bash
|
||||
linutil --skip-confirmation --size-bypass
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--config` / `-c` | Path to TOML config file |
|
||||
| `--skip-confirmation` | Skip all confirmation prompts |
|
||||
| `--size-bypass` | Bypass minimum terminal size check |
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Provision a New Machine
|
||||
|
||||
Create a config that installs your standard set of tools:
|
||||
|
||||
```toml
|
||||
auto_execute = [
|
||||
"Bash Prompt",
|
||||
"Fastfetch",
|
||||
"VS Code",
|
||||
"Docker",
|
||||
"ZSH Prompt"
|
||||
]
|
||||
|
||||
skip_confirmation = true
|
||||
```
|
||||
|
||||
Run it on any new Linux install to get your environment set up in one shot.
|
||||
|
||||
### Server Setup
|
||||
|
||||
```toml
|
||||
auto_execute = [
|
||||
"Full System Update",
|
||||
"UFW Firewall Baselines (CTT)",
|
||||
"Docker"
|
||||
]
|
||||
|
||||
skip_confirmation = true
|
||||
```
|
||||
|
||||
### Finding Script Names
|
||||
|
||||
Script names in `auto_execute` must match exactly as they appear in the Linutil TUI. Browse the TUI to find the exact name, or check the auto-generated [Walkthrough](../walkthrough/) page for a complete list.
|
||||
|
||||
> [!TIP]
|
||||
> Use `--skip-confirmation` together with `auto_execute` for fully unattended runs. Without it, Linutil will still pause and ask before executing each script.
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: Features & Utilities
|
||||
weight: 4
|
||||
---
|
||||
|
||||
Beyond application installation and system setup, Linutil includes categories for security hardening, gaming, and a wide range of system utilities.
|
||||
|
||||
## Security
|
||||
|
||||
Apply firewall baselines to protect your Linux system. Based on CTT's recommended security rules — for more detail see [christitus.com/linux-security-mistakes](https://christitus.com/linux-security-mistakes).
|
||||
|
||||
### UFW Firewall Baselines
|
||||
|
||||
UFW (Uncomplicated Firewall) is a user-friendly frontend for `iptables`. This script:
|
||||
|
||||
- Installs UFW if not present
|
||||
- Applies CTT's recommended baseline rules for IPv4 and IPv6
|
||||
- Enables the firewall
|
||||
|
||||
```bash
|
||||
# Check UFW status after running the script
|
||||
sudo ufw status verbose
|
||||
```
|
||||
|
||||
### FirewallD Baselines
|
||||
|
||||
An alternative to UFW, FirewallD is the default firewall manager on Fedora and RHEL-based systems. This script configures FirewallD with CTT's recommended rules.
|
||||
|
||||
## Gaming
|
||||
|
||||
### Gaming Dependencies
|
||||
|
||||
Installs the libraries and tools needed to run games on Linux across different distributions (Steam, Wine, DXVK, Vulkan drivers, etc.).
|
||||
|
||||
### Emulators
|
||||
|
||||
| Emulator | Console |
|
||||
|----------|---------|
|
||||
| RetroArch | Multi-system frontend |
|
||||
| Dolphin | GameCube / Wii |
|
||||
| PCSX2 | PlayStation 2 |
|
||||
| RPCS3 | PlayStation 3 |
|
||||
| Ryujinx | Nintendo Switch |
|
||||
| mGBA | Game Boy Advance |
|
||||
| MelonDS | Nintendo DS / DSi |
|
||||
| bsnes / snes9x | Super Nintendo |
|
||||
| Mupen64Plus / Gopher64 | Nintendo 64 |
|
||||
| Flycast | Sega Dreamcast |
|
||||
| Kronos | Sega Saturn |
|
||||
| XEMU | Original Xbox |
|
||||
| Blastem | Sega Genesis |
|
||||
|
||||
> [!NOTE]
|
||||
> No game ROMs or BIOS files are included. You must supply your own legally obtained files.
|
||||
|
||||
### Game-Specific Configs
|
||||
|
||||
- **Diablo II Resurrected — Loot Filter**: Highlights high-value drops for Battle.net and single player
|
||||
- **Fallout 76 — INI & Mods**: Performance and stability improvements
|
||||
- **Arc Raiders — Match Optimizations**: Shorter transition videos and optimized config for VRR
|
||||
|
||||
## Utilities
|
||||
|
||||
### Monitor Control
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Auto Detect Displays | Detect and apply recommended monitor config |
|
||||
| Set Resolution | Change the resolution of a connected monitor |
|
||||
| Set Brightness | Adjust monitor brightness |
|
||||
| Change Orientation | Rotate a monitor |
|
||||
| Scale Monitors | Change display scaling |
|
||||
| Set Primary Monitor | Designate the primary display |
|
||||
| Extend Displays | Extend across multiple monitors |
|
||||
| Duplicate Displays | Mirror displays |
|
||||
| Disable / Enable Monitor | Toggle a monitor on or off |
|
||||
| Manage Arrangement | Set the physical arrangement of monitors |
|
||||
| Reset Scaling | Revert scaling to default |
|
||||
|
||||
### Printers
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| CUPS | Install the CUPS printing system |
|
||||
| Epson Drivers | Install Epson printer drivers |
|
||||
| HP Drivers | Install HP printer drivers |
|
||||
|
||||
### System Utilities
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Bluetooth Manager | Manage Bluetooth devices |
|
||||
| WiFi Manager | Manage wireless connections |
|
||||
| Service Manager | Enable, disable, and manage systemd services |
|
||||
| Numlock on Startup | Enable Num Lock at boot |
|
||||
| Auto Mount Drive | Automate mounting a drive at startup |
|
||||
| Ollama | Manage Ollama (local AI model runner) |
|
||||
| US Locale Setup | Fix US UTF-8 locale and folder listings |
|
||||
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: Getting Started with Linutil
|
||||
weight: 1
|
||||
---
|
||||
|
||||
## Welcome to Linutil!
|
||||
|
||||
Linutil is a distro-agnostic Linux toolbox built in Rust. It provides an interactive terminal UI (TUI) for installing applications, configuring your system, and running common Linux setup tasks — all from one place.
|
||||
|
||||
## System Requirements
|
||||
|
||||
Before running Linutil, ensure your system meets these requirements:
|
||||
|
||||
- **Operating System**: Any modern Linux distribution (Arch, Fedora, Debian, Ubuntu, openSUSE, etc.)
|
||||
- **Shell**: Bash or a compatible POSIX shell
|
||||
- **Internet Connection**: Required for downloading applications and scripts
|
||||
- **curl**: Pre-installed on most distributions
|
||||
|
||||
## Running Linutil
|
||||
|
||||
Linutil runs directly from a single curl command — no installation required.
|
||||
|
||||
### Stable Branch (Recommended)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh
|
||||
```
|
||||
|
||||
### Dev Branch (Latest Features)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linuxdev | sh
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The dev branch may contain untested features. Use the stable branch for day-to-day use.
|
||||
|
||||
## Installing Linutil Locally
|
||||
|
||||
If you prefer a persistent local install, Linutil is available through several package managers.
|
||||
|
||||
### Arch Linux (AUR)
|
||||
|
||||
```bash
|
||||
# Using paru
|
||||
paru -S linutil
|
||||
|
||||
# Using yay
|
||||
yay -S linutil
|
||||
|
||||
# Stable pre-compiled binary
|
||||
paru -S linutil-bin
|
||||
```
|
||||
|
||||
### openSUSE
|
||||
|
||||
```bash
|
||||
sudo zypper install linutil
|
||||
```
|
||||
|
||||
### Cargo
|
||||
|
||||
```bash
|
||||
cargo install linutil_tui
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Cargo installs require manual updates via `cargo install --force linutil_tui`, or use the built-in **Linutil Updater** script inside the tool.
|
||||
|
||||
## CLI Arguments
|
||||
|
||||
View all available options:
|
||||
|
||||
```bash
|
||||
linutil --help
|
||||
```
|
||||
|
||||
### Common Options
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--config` / `-c` | Path to a TOML config file |
|
||||
| `--skip-confirmation` | Skip confirmation prompts |
|
||||
| `--size-bypass` | Bypass terminal size requirements |
|
||||
|
||||
## Navigating the TUI
|
||||
|
||||
Once Linutil launches, you'll see a tree-style menu on the left and a description panel on the right.
|
||||
|
||||
### Keyboard Shortcuts
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `↑` / `↓` or `j` / `k` | Move up/down in the list |
|
||||
| `Enter` or `→` | Select / expand item |
|
||||
| `←` | Collapse / go back |
|
||||
| `Space` | Multi-select an item |
|
||||
| `/` | Search/filter items |
|
||||
| `q` or `Escape` | Quit / go back |
|
||||
| `t` | Toggle multi-select mode |
|
||||
|
||||
### Menu Structure
|
||||
|
||||
Linutil is organized into these main categories:
|
||||
|
||||
- **Applications Setup** — Install popular Linux software
|
||||
- **Gaming** — Gaming dependencies, emulators, game configs
|
||||
- **Security** — Firewall setup and hardening
|
||||
- **System Setup** — Distro-specific configuration (Arch, Fedora, Debian, Ubuntu, etc.)
|
||||
- **Utilities** — Monitor control, printers, Bluetooth, WiFi, and more
|
||||
|
||||
## Your First Steps
|
||||
|
||||
Here are recommended actions for new users:
|
||||
|
||||
### 1. Browse and Install Applications
|
||||
|
||||
1. Navigate to **Applications Setup**
|
||||
2. Browse categories (browsers, developer tools, communication apps, etc.)
|
||||
3. Select an application and press `Enter` to run the install script
|
||||
|
||||
### 2. Set Up Your Distro
|
||||
|
||||
1. Navigate to **System Setup**
|
||||
2. Find your distribution (Arch, Fedora, Debian, Ubuntu)
|
||||
3. Run distro-specific scripts like AUR helpers, RPM Fusion, or package updates
|
||||
|
||||
### 3. Configure Utilities
|
||||
|
||||
1. Navigate to **Utilities**
|
||||
2. Set up monitors, manage Bluetooth/WiFi, or configure services
|
||||
|
||||
## Troubleshooting First Run
|
||||
|
||||
### Script Won't Download
|
||||
|
||||
If the curl command fails, check your internet connection or try:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/ChrisTitusTech/linutil/main/linutil.sh | sh
|
||||
```
|
||||
|
||||
### Permission Errors
|
||||
|
||||
Most scripts require sudo access. Linutil will prompt for your password when needed.
|
||||
|
||||
### Terminal Size Warning
|
||||
|
||||
If you get a terminal size warning, resize your terminal to be larger, or use the `--size-bypass` flag:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh -s -- --size-bypass
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Application Setup](../store/) — Learn about installing software
|
||||
- [System Setup](../tweaks/) — Distro-specific configuration
|
||||
- [Features & Utilities](../features/) — Security, gaming, and utilities
|
||||
- [Automation](../automation/) — Run Linutil with a config file
|
||||
- [FAQ](../../faq/) — Common questions and answers
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: Application Setup
|
||||
weight: 2
|
||||
---
|
||||
|
||||
The **Applications Setup** section of Linutil lets you install popular Linux software through pre-written install scripts. Each script handles package manager differences across distros automatically.
|
||||
|
||||
## Finding Applications
|
||||
|
||||
Use the search feature to quickly find what you need:
|
||||
|
||||
- Press `/` while in the TUI to open the search/filter
|
||||
- Type part of the application name
|
||||
- The list filters in real time
|
||||
|
||||
## Installing an Application
|
||||
|
||||
1. Navigate to **Applications Setup** in the main menu
|
||||
2. Browse categories or search for the app you want
|
||||
3. Select the application and press `Enter`
|
||||
4. Linutil will run the install script — you may be prompted for your `sudo` password
|
||||
|
||||
## Application Categories
|
||||
|
||||
### Communication Apps
|
||||
|
||||
| App | Description |
|
||||
|-----|-------------|
|
||||
| Discord | Voice, video, and text chat for communities |
|
||||
| Signal | End-to-end encrypted messaging |
|
||||
| Slack | Team collaboration platform |
|
||||
| Telegram | Fast, cloud-based messaging |
|
||||
| Thunderbird | Open-source email client |
|
||||
| Zoom | Video conferencing |
|
||||
|
||||
### Developer Tools
|
||||
|
||||
| App | Description |
|
||||
|-----|-------------|
|
||||
| VS Code | Lightweight code editor by Microsoft |
|
||||
| VS Codium | VS Code without Microsoft telemetry |
|
||||
| Cursor | AI-powered code editor |
|
||||
| Neovim | CTT's configured Neovim setup |
|
||||
| Zed | High-performance code editor written in Rust |
|
||||
| GitHub Desktop | GUI for Git and GitHub |
|
||||
| Docker | Container platform |
|
||||
| Podman | Daemonless container engine |
|
||||
|
||||
### Web Browsers
|
||||
|
||||
| App | Description |
|
||||
|-----|-------------|
|
||||
| Firefox | Open-source browser by Mozilla |
|
||||
| Brave | Privacy-focused Chromium browser |
|
||||
| LibreWolf | Privacy-hardened Firefox fork |
|
||||
| Chromium | Open-source base for Chrome |
|
||||
| Zen Browser | Privacy-focused browser |
|
||||
| Tor Browser | Anonymity browser via Tor network |
|
||||
|
||||
### Design Tools
|
||||
|
||||
| App | Description |
|
||||
|-----|-------------|
|
||||
| GIMP | Full-featured raster image editor |
|
||||
| Inkscape | Vector graphics editor |
|
||||
| Krita | Digital painting and 2D animation |
|
||||
| Blender | 3D modeling and animation |
|
||||
| OBS Studio | Screen recording and live streaming |
|
||||
| Kdenlive | Non-linear video editor |
|
||||
|
||||
### Terminal & Shell
|
||||
|
||||
| App | Description |
|
||||
|-----|-------------|
|
||||
| Alacritty | GPU-accelerated terminal emulator |
|
||||
| Kitty | Feature-rich GPU terminal emulator |
|
||||
| Ghostty | Highly customizable terminal |
|
||||
| Bash Prompt | CTT's `.bashrc` configuration |
|
||||
| ZSH Prompt | ZSH shell with basic configuration |
|
||||
|
||||
### Other Notable Apps
|
||||
|
||||
| App | Description |
|
||||
|-----|-------------|
|
||||
| Fastfetch | System info display tool |
|
||||
| Flatpak / Flathub | Universal Linux app sandbox |
|
||||
| Bottles | Run Windows apps on Linux |
|
||||
| Waydroid | Run Android apps on Linux |
|
||||
| DWM-Titus | CTT's configured DWM window manager |
|
||||
| Rofi | App launcher and window switcher |
|
||||
| Auto CPU Frequency | Automatic CPU power optimizer |
|
||||
|
||||
## Updating Linutil Itself
|
||||
|
||||
Two scripts in Applications Setup manage Linutil's own lifecycle:
|
||||
|
||||
- **Linutil Installer** — Installs a distro-specific Linutil package locally
|
||||
- **Linutil Updater** — Updates your local Linutil crate installation
|
||||
|
||||
> [!TIP]
|
||||
> If you installed Linutil via `cargo install linutil_tui`, use the **Linutil Updater** script to keep it current instead of running `cargo install --force` manually.
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: System Setup
|
||||
weight: 3
|
||||
---
|
||||
|
||||
The **System Setup** section contains distro-specific and general configuration scripts to get your Linux system set up quickly. These scripts handle driver installation, package manager configuration, desktop environments, and more.
|
||||
|
||||
## Distro-Specific Setup
|
||||
|
||||
### Arch Linux
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Arch Server Setup | Minimal Arch server install in under 5 minutes |
|
||||
| Hyprland (JaKooLit) | Install JaKooLit's Hyprland configuration |
|
||||
| Paru AUR Helper | Install the `paru` AUR helper |
|
||||
| Yay AUR Helper | Install the `yay` AUR helper |
|
||||
| Install Chaotic-AUR | Add the Chaotic-AUR repo for prebuilt AUR packages |
|
||||
| Nvidia Drivers + HW Accel | Install and configure Nvidia drivers with hardware acceleration |
|
||||
| Omarchy Rice by DHH | Simplified Hyprland config by DHH |
|
||||
| Linux Neptune (SteamDeck) | Valve's fork of the Linux kernel for Steam Deck |
|
||||
| Virtualization | Install QEMU, Libvirt, and Virt-Manager |
|
||||
|
||||
### Fedora
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Configure DNF | Optimize DNF for parallel downloads |
|
||||
| RPM Fusion | Add RPM Fusion free and non-free repositories |
|
||||
| Multimedia Codecs | Install multimedia codecs with RPM Fusion |
|
||||
| Nvidia Proprietary Drivers | Install proprietary Nvidia drivers |
|
||||
| Hyprland (JaKooLit) | Install JaKooLit's Hyprland configuration |
|
||||
| Virtualization | Enable virtualization via DNF |
|
||||
| Btrfs Assistant + Snapper | Btrfs snapshots with grub-btrfs integration |
|
||||
| Upgrade Fedora Release | Upgrade system to the next Fedora release |
|
||||
|
||||
### Debian
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Hyprland (JaKooLit) | Install JaKooLit's Hyprland configuration |
|
||||
|
||||
### Ubuntu
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Hyprland (JaKooLit) | Install JaKooLit's Hyprland configuration |
|
||||
| Full System Cleanup | Remove unused packages, clear cache, empty trash |
|
||||
| Full System Update | Update all packages to the latest available |
|
||||
| Gaming Dependencies | Install gaming dependencies across distros |
|
||||
| Global Theme | Install and configure a global desktop theme |
|
||||
| Remove Snaps | Remove Snap and prevent it from reinstalling |
|
||||
| Build Prerequisites | Install software build dependencies |
|
||||
| TTY Fonts | Set the default TTY font to Terminus 32 Bold |
|
||||
|
||||
### Alpine
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Alpine Update | Upgrade Alpine to the latest stable or edge release |
|
||||
|
||||
## Desktop Environment Setup
|
||||
|
||||
These scripts work across distros and let you install or uninstall full desktop environments and window managers interactively.
|
||||
|
||||
### Install Desktop Environment
|
||||
|
||||
An interactive menu lets you choose from:
|
||||
|
||||
**Desktop Environments**: GNOME, KDE Plasma, XFCE, Cinnamon, MATE, Budgie, LXQt, LXDE
|
||||
|
||||
**Window Managers**: i3, Sway, DWM, Awesome, BSPWM, Openbox, Fluxbox
|
||||
|
||||
### Uninstall Desktop Environment
|
||||
|
||||
The reverse operation — interactively select which DE or WM to remove.
|
||||
|
||||
## General System Scripts
|
||||
|
||||
These scripts work across all distributions:
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| Full System Update | Update all packages using your distro's package manager |
|
||||
| Full System Cleanup | Clear package caches, temp files, and trash |
|
||||
| Gaming Dependencies | Install dependencies needed for gaming on Linux |
|
||||
| Build Prerequisites | Install common software build dependencies |
|
||||
|
||||
> [!TIP]
|
||||
> Always run a **Full System Update** before installing new software or applying major configuration changes.
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Updating Linutil
|
||||
weight: 5
|
||||
---
|
||||
|
||||
Linutil is actively developed and updated frequently. There are a few ways to keep your installation current.
|
||||
|
||||
## Running the Latest Version Directly
|
||||
|
||||
The simplest way to always use the latest release is to run the curl command each time:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linux | sh
|
||||
```
|
||||
|
||||
This always pulls the latest stable release without any local install needed.
|
||||
|
||||
## Updating a Local Install
|
||||
|
||||
If you installed Linutil locally (via Cargo, AUR, or openSUSE packages), use the appropriate method to update.
|
||||
|
||||
### Linutil Updater (Built-in)
|
||||
|
||||
The easiest way to update a Cargo-based install is the **Linutil Updater** script inside the tool itself:
|
||||
|
||||
1. Run Linutil
|
||||
2. Navigate to **Applications Setup**
|
||||
3. Select **Linutil Updater**
|
||||
4. The script will update your local `linutil_tui` crate
|
||||
|
||||
### Cargo
|
||||
|
||||
```bash
|
||||
cargo install --force linutil_tui
|
||||
```
|
||||
|
||||
### Arch Linux (AUR)
|
||||
|
||||
```bash
|
||||
# Using paru
|
||||
paru -Syu linutil
|
||||
|
||||
# Using yay
|
||||
yay -Syu linutil
|
||||
```
|
||||
|
||||
### openSUSE
|
||||
|
||||
```bash
|
||||
sudo zypper update linutil
|
||||
```
|
||||
|
||||
## Dev Branch
|
||||
|
||||
To test the latest unreleased features, use the dev branch:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://christitus.com/linuxdev | sh
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> The dev branch may contain untested or unstable features. Not recommended for daily use.
|
||||
|
||||
## Checking the Current Version
|
||||
|
||||
After installing Linutil locally, you can check the version with:
|
||||
|
||||
```bash
|
||||
linutil --version
|
||||
```
|
||||
|
||||
## Release Notes
|
||||
|
||||
All releases and changelogs are available on the [GitHub Releases page](https://github.com/ChrisTitusTech/linutil/releases).
|
||||
@@ -0,0 +1,5 @@
|
||||
module github.com/ChrisTitusTech/linUtil
|
||||
|
||||
go 1.23.3
|
||||
|
||||
require github.com/imfing/hextra v0.11.1 // indirect
|
||||
@@ -0,0 +1,2 @@
|
||||
github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI=
|
||||
github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
|
||||
@@ -0,0 +1,118 @@
|
||||
baseURL = "https://linutil.christitus.com/"
|
||||
languageCode = "en-us"
|
||||
title = "Linutil Documentation"
|
||||
enableGitInfo = true
|
||||
canonifyURLs = true
|
||||
|
||||
[[module.mounts]]
|
||||
source = "assets"
|
||||
target = "assets"
|
||||
|
||||
[[module.mounts]]
|
||||
source = "static"
|
||||
target = "static"
|
||||
|
||||
[[module.mounts]]
|
||||
source = "../.github"
|
||||
target = "static"
|
||||
includeFiles = "preview.gif"
|
||||
|
||||
[[module.imports]]
|
||||
path = "github.com/imfing/hextra"
|
||||
|
||||
[[menu.main]]
|
||||
name = "Developer Documentation"
|
||||
pageRef = "/dev"
|
||||
weight = 1
|
||||
|
||||
[[menu.main]]
|
||||
name = "User Guides"
|
||||
pageRef = "/userguide"
|
||||
weight = 2
|
||||
|
||||
[[menu.main]]
|
||||
name = "Contribution Guides"
|
||||
pageRef = "CONTRIBUTING.md"
|
||||
weight = 3
|
||||
|
||||
[[menu.main]]
|
||||
name = "FAQ"
|
||||
pageRef = "faq.md"
|
||||
weight = 4
|
||||
|
||||
[[menu.main]]
|
||||
name = "Known Issues"
|
||||
pageRef = "KnownIssues.md"
|
||||
weight = 4
|
||||
|
||||
[[menu.main]]
|
||||
name = "Search"
|
||||
weight = 6
|
||||
|
||||
[menu.main.params]
|
||||
type = "search"
|
||||
|
||||
[[menu.main]]
|
||||
name = "GitHub"
|
||||
weight = 7
|
||||
url = "https://github.com/christitustech/linutil"
|
||||
|
||||
[menu.main.params]
|
||||
icon = "github"
|
||||
|
||||
[params]
|
||||
description = "Chris Titus Tech's Linux Utility - Install Programs, Tweaks, Fixes, and Updates"
|
||||
displayUpdatedDate = true
|
||||
dateFormat = "January 2, 2006"
|
||||
|
||||
[params.navbar]
|
||||
displayTitle = false
|
||||
displayLogo = false
|
||||
|
||||
[params.navbar.logo]
|
||||
path = "navlogo.png"
|
||||
dark = "navlogo.png"
|
||||
link = "/"
|
||||
width = 150
|
||||
height = 50
|
||||
|
||||
[params.theme]
|
||||
default = "system"
|
||||
displayToggle = true
|
||||
|
||||
[params.page]
|
||||
width = "wide"
|
||||
|
||||
[params.footer]
|
||||
enable = true
|
||||
displayCopyright = true
|
||||
displayPoweredBy = false
|
||||
width = "normal"
|
||||
|
||||
[params.highlight.copy]
|
||||
enable = true
|
||||
display = "hover"
|
||||
|
||||
[menu]
|
||||
|
||||
[[menu.sidebar]]
|
||||
name = "Links"
|
||||
weight = 1
|
||||
[menu.sidebar.params]
|
||||
type = "separator"
|
||||
|
||||
[[menu.sidebar]]
|
||||
name = "Github Repo ↗"
|
||||
url = "https://github.com/ChrisTitusTech/linutil"
|
||||
weight = 2
|
||||
|
||||
[[menu.sidebar]]
|
||||
name = "Discord Server ↗"
|
||||
url = "https://discord.gg/RUbZUZyByQ"
|
||||
weight = 3
|
||||
|
||||
|
||||
[markup]
|
||||
[markup.goldmark]
|
||||
[markup.goldmark.renderer]
|
||||
unsafe = true
|
||||
@@ -0,0 +1,24 @@
|
||||
copyright: "© <script>document.write(new Date().getFullYear())</script> <a href='https://christitus.com'>Chris Titus Tech</a>. All rights reserved."
|
||||
|
||||
backToTop: "Scroll to top"
|
||||
changeLanguage: "Change language"
|
||||
changeTheme: "Change theme"
|
||||
copy: "Copy"
|
||||
copied: "Copied!"
|
||||
copyAsMarkdown: "Copy as Markdown"
|
||||
copyPage: "Copy Page"
|
||||
copyCode: "Copy code"
|
||||
dark: "Dark"
|
||||
editThisPage: "Edit this page on GitHub →"
|
||||
lastUpdated: "Last updated on"
|
||||
light: "Light"
|
||||
next: "Next"
|
||||
noResultsFound: "No results found."
|
||||
onThisPage: "On this page"
|
||||
poweredBy: "Powered by Chris Titus Tech"
|
||||
previous: "Prev"
|
||||
readMore: "Read more →"
|
||||
searchPlaceholder: "Search..."
|
||||
system: "System"
|
||||
tags: "Tags"
|
||||
viewAsMarkdown: "View as Markdown"
|
||||
@@ -0,0 +1,17 @@
|
||||
{{- $section := .Get "section" | lower -}}
|
||||
{{- $pages := slice -}}
|
||||
{{- range .Site.RegularPages -}}
|
||||
{{- if in .RelPermalink $section -}}
|
||||
{{- $pageTitle := .Title -}}
|
||||
{{- if eq $pageTitle "" -}}
|
||||
{{- $pageTitle = .File.BaseFileName | humanize | title -}}
|
||||
{{- end -}}
|
||||
{{- $pageDesc := .Description -}}
|
||||
{{- $pages = $pages | append (dict "title" $pageTitle "description" $pageDesc "url" .RelPermalink) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
<ul>
|
||||
{{- range sort $pages "title" "asc" }}
|
||||
<li><a href="{{ .url }}">{{ .title }}</a>{{ with .description }} - {{ . }}{{ end }}</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
@@ -0,0 +1,114 @@
|
||||
{{/*Retrieve Passed Shortcode Parameters*/}}
|
||||
{{ $src := .Get "src" }}
|
||||
{{ $alt := .Get "alt" }}
|
||||
|
||||
{{/*Define sizes*/}}
|
||||
{{ $Small := 200 }}
|
||||
{{ $Medium := 600 }}
|
||||
{{ $Large := 1000 }}
|
||||
|
||||
{{/*Define Image variables as global variables to make them easily accessible in this shortcode*/}}
|
||||
{{ $DarkImage := "" }} {{ $DarkSmallImage := "" }} {{ $DarkMediumImage := "" }} {{ $DarkLargeImage := "" }}
|
||||
{{ $LightImage := "" }} {{ $LightSmallImage := "" }} {{ $LightMediumImage := "" }} {{ $LightLargeImage := "" }}
|
||||
{{ $SingleImage := "" }} {{ $SingleSmallImage := "" }} {{ $SingleMediumImage := "" }} {{ $SingleLargeImage := "" }}
|
||||
|
||||
{{/*Find images and update the previous Single,Dark,Light Images variables*/}}
|
||||
{{ with resources.GetMatch (print $src ".jpg") }} {{ $SingleImage = . }} {{ end }}
|
||||
{{ with resources.GetMatch (print $src "-Dark" ".jpg") }} {{ $DarkImage = . }} {{ end }}
|
||||
{{ with resources.GetMatch (print $src "-Light" ".jpg") }} {{ $LightImage = . }} {{ end }}
|
||||
{{ with resources.GetMatch (print $src ".png") }} {{ $SingleImage = . }} {{ end }}
|
||||
{{ with resources.GetMatch (print $src "-Dark" ".png") }} {{ $DarkImage = . }} {{ end }}
|
||||
{{ with resources.GetMatch (print $src "-Light" ".png") }} {{ $LightImage = . }} {{ end }}
|
||||
|
||||
{{/*Applying Image Processing*/}}
|
||||
{{ with $SingleImage }}
|
||||
{{ with .Resize (printf "%dx%d webp q50" .Width .Height) }}
|
||||
{{ $SingleImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with $DarkImage }}
|
||||
{{ with .Resize (printf "%dx%d webp q50" .Width .Height) }}
|
||||
{{ $DarkImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with $LightImage }}
|
||||
{{ with .Resize (printf "%dx%d webp q50" .Width .Height) }}
|
||||
{{ $LightImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{/*Make different sized versions to images if applicable*/}}
|
||||
{{ with $SingleImage }}
|
||||
{{ if gt (.Width) ($Small) }}
|
||||
{{ with .Resize (printf "%dx" $Small) }}
|
||||
{{ $SingleSmallImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if gt (.Width) ($Medium) }}
|
||||
{{ with .Resize (printf "%dx" $Medium) }}
|
||||
{{ $SingleMediumImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if gt (.Width) ($Large) }}
|
||||
{{ with .Resize (printf "%dx" $Large) }}
|
||||
{{ $SingleLargeImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with $DarkImage }}
|
||||
{{ if gt (.Width) ($Small) }}
|
||||
{{ with .Resize (printf "%dx" $Small) }}
|
||||
{{ $DarkSmallImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if gt (.Width) ($Medium) }}
|
||||
{{ with .Resize (printf "%dx" $Medium) }}
|
||||
{{ $DarkMediumImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if gt (.Width) ($Large) }}
|
||||
{{ with .Resize (printf "%dx" $Large) }}
|
||||
{{ $DarkLargeImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with $LightImage }}
|
||||
{{ if gt (.Width) ($Small) }}
|
||||
{{ with .Resize (printf "%dx" $Small) }}
|
||||
{{ $LightSmallImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if gt (.Width) ($Medium) }}
|
||||
{{ with .Resize (printf "%dx" $Medium) }}
|
||||
{{ $LightMediumImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if gt (.Width) ($Large) }}
|
||||
{{ with .Resize (printf "%dx" $Large) }}
|
||||
{{ $LightLargeImage = . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{ if $SingleImage }}
|
||||
<picture>
|
||||
{{ with $SingleSmallImage }}<source media='(max-width: {{ printf "%dpx" $Small}})' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $SingleMediumImage }}<source media='(min-width: {{ printf "%dpx" $Small}}) and (max-width: {{ printf "%dpx" $Medium}})' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $SingleLargeImage }}<source media='(min-width: {{ printf "%dpx" $Medium}}) and (max-width: {{ printf "%dpx" $Large}})' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $SingleImage }}<img loading="lazy" src="{{ .RelPermalink }}" Width="{{ .Width }}" height="{{ .Height }}" {{ with $alt }}alt="{{.}}"{{ else }}alt=""{{ end }}/>{{ end }}
|
||||
</picture>
|
||||
{{ else }}
|
||||
<picture>
|
||||
{{ with $DarkSmallImage }}<source media='(max-width: {{ printf "%dpx" $Small}}) and (prefers-color-scheme: dark)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $DarkMediumImage }}<source media='(min-width: {{ printf "%dpx" $Small}}) and (max-width: {{ printf "%dpx" $Medium}}) and (prefers-color-scheme: dark)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $DarkLargeImage }}<source media='(min-width: {{ printf "%dpx" $Medium}}) and (max-width: {{ printf "%dpx" $Large}}) and (prefers-color-scheme: dark)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $DarkImage }}<source media='(prefers-color-scheme: dark)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $LightSmallImage }}<source media='(max-width: {{ printf "%dpx" $Small}}) and (prefers-color-scheme: light)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $LightMediumImage }}<source media='(min-width: {{ printf "%dpx" $Small}}) and (max-width: {{ printf "%dpx" $Medium}}) and (prefers-color-scheme: light)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $LightLargeImage }}<source media='(min-width: {{ printf "%dpx" $Medium}}) and (max-width: {{ printf "%dpx" $Large}}) and (prefers-color-scheme: light)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $LightImage }}<source media='(prefers-color-scheme: light)' srcset='{{ .RelPermalink }}'>{{ end }}
|
||||
{{ with $LightImage }}<img loading="lazy" src="{{ .RelPermalink }}" Width="{{ .Width }}" height="{{ .Height }}" {{ with $alt }}alt="{{.}}"{{ else }}alt=""{{ end }}/>
|
||||
{{ else with $DarkImage }}<img loading="lazy" src="{{ .RelPermalink }}" Width="{{ .Width }}" height="{{ .Height }}" {{ with $alt }}alt="{{.}}"{{ else }}alt=""{{ end }}/>{{ end }}
|
||||
</picture>
|
||||
{{ end }}
|
||||
@@ -0,0 +1 @@
|
||||
linutil.christitus.com
|
||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 877 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
@@ -4,7 +4,7 @@ use linutil_core::Command;
|
||||
|
||||
use crate::{path, DynError};
|
||||
|
||||
pub const USER_GUIDE: &str = "userguide.md";
|
||||
pub const USER_GUIDE: &str = "content/userguide/walkthrough.md";
|
||||
|
||||
pub fn userguide() -> Result<String, DynError> {
|
||||
let mut md = String::new();
|
||||
|
||||