') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - DannyBen/pm: Friendly Pacman Wrapper for Arch Linux · GitHub
Skip to content

Repository files navigation

pm - Friendly Pacman

repocard

pm is a friendly command-line interface for Arch Linux's pacman package manager. It replaces hard-to-remember combinations of uppercase and lowercase flags with clear commands such as pm install, pm search, and pm outdated.

pm was developed using the Bashly Command Line Framework and is distributed as a single Bash script.

Install

Installing using the setup script

The setup script installs the latest pm release and its Bash completions:

curl -Ls get.dannyb.co/pm/setup | bash

Feel free to inspect the setup script before running.

Installing manually

Download the pm script from the latest release, place it somewhere in your path, and make it executable:

wget https://github.com/DannyBen/pm/releases/latest/download/pm
sudo install -m 0755 pm /usr/local/bin/

Generate Bash completions with:

pm completions

Concept

Commands that can query two package sources use the same rule everywhere:

# Query packages installed on this system
pm list
pm info git
pm search terminal
pm browse
# Query all packages available in configured repositories
pm list --available
pm info git --available
pm search terminal --available
pm browse --available

--available can also be written as -a.

pm operates on pacman packages and configured binary repositories. It does not search, build, or update AUR packages.

Examples

# Install, update, and uninstall packages
pm install git fzf
pm update
pm uninstall fzf
# Check for available updates without upgrading
pm outdated
# Inspect package relationships and history
pm tree git
pm tree git --depth 1
pm tree git --reverse
pm origin /usr/bin/git
pm history
pm history git
# Inspect repositories and foreign packages
pm repos
pm foreign
# Preview package-cache cleanup
pm clean --dry-run

Usage

pm - A friendly interface for pacman
Usage:
pm COMMAND
pm [COMMAND] --help | -h
pm --version | -v
Package Management Commands:
update Update package databases and upgrade the system
install Install packages
uninstall Remove packages and their unneeded dependencies
Package Maintenance Commands:
update-keys Update the Arch Linux keyring
clean Remove old packages from the package cache
outdated List installed packages with available updates
Package Query Commands:
list List package names
info Show package information
search Search packages
browse Browse packages interactively
Package Analysis Commands:
provides Find packages that provide a command
tree Show a package dependency tree
origin Show which installed package owns a file
history Show package activity from the pacman log
foreign List installed packages absent from configured repositories
repos List configured package repositories
Internal Commands:
completions Generate bash completions

Run pm COMMAND --help for command-specific options and examples.

Optional dependencies

Most pm commands only require pacman. Additional commands declare their own dependencies and show installation instructions when needed:

CommandsPackage
clean, treepacman-contrib
outdatedpacman-contrib, fakeroot
browsefzf
providespkgfile
historyripgrep

Uninstall

curl -Ls get.dannyb.co/pm/uninstall | bash

Contributing / Support

If you experience an issue, have a question or suggestion, or wish to contribute, feel free to open an issue.


About

Friendly Pacman Wrapper for Arch Linux

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages