Code Monkey home page Code Monkey logo

fuzzy-pkg-finder's Introduction

๐Ÿ“ฆ
Fuzzy-pkg-finder

Simple cli utility using fzf to search and install/list/remove packages.

Screenshot

Leverages the power of fzf to search package names and descriptions then presents complete package information in preview pane.
On selection will hand off to Pacman or Paru/Yay to complete transaction.

For use with Pacman/Yay/Paru package managers only.

There are countless fzf package manager wrappers out there, some much more built out that this.
What separates Fuzzy-pkg-finder?

  • It's mine and it works the way I like it to
  • It works as a simple script to wrap pacman/yay/paru, no need to rebuild the wheel
  • Searches both package names and descriptions for keyword
  • Hide preview window to see only packages and descriptions
  • Shows files list and/or missing files for official repo or installed AUR packages
  • Toggle between package info view and PKGBUILD view on AUR package preview
  • Update feature shows package information and link to recent commits


    Installation:
    For Arch and arch-based distros, it is available in the AUR.
    Use: paru -S fuzzy-pkg-finder or yay -S fuzzy-pkg-finder

    Manual build and install:
git clone https://github.com/ericlay/fuzzy-pkg-finder
cd fuzzy-pkg-finder
makepkg -sric


Usage:

Syntax: fpf [-a| --aur] [-l| --list-installed] [-la| --list-aur-installed]
              [R| --remove] [-o| --orphans] [-U | --update] [-h | --help]
Defaults to Pacman if no options passed

Searching for a package:
ex: fpf [pkg name] for official repo search
ex: fpf -a [pkg name] for aur search

Options:
-a, --aur
    Search/List and install from AUR with Yay

-l, --list-installed
    Search/List installed packages from official repo

-la, --list-aur-installed
    Search/List installed packages from AUR 

-R, -remove
     Search/List installed packages for removal

-o, --orphans
     Search/List orphaned packages for removal

-U, --update
     Shows packages with updates available

-h, --help
     Print this help screen


Keybinds:

'ctrl + /' Toggle the preview window
'ctrl + h' Show help in the preview window
'ctrl + k' Show the keybinds in the preview window
'ctrl + n' Move to the next selected item
'ctrl + b' Back to previoius selected item

When browsing AUR or installed Aur pkgs:
'ctrl + p' Preview the highlighted pkgbuild file
'ctrl + x' Return to the highlighted pkg info

fuzzy-pkg-finder's People

Contributors

ericlay avatar yochananmarqos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fuzzy-pkg-finder's Issues

Description shown next to the package

Hi there :)

I just installed your script - on Garuda - and wonder why there is the description added next to the package name.

Screenshot_20230919_163930

This is not the case in your screenshot, and I would prefer it that way.

Hey something for you to have a look at

Hey love the idea of what your going for here and the amount of work i know went into this script and getting it up onto aur. So i want you to know this isn't a shot at your effort or the turn out. I wanted to bring to your attention a script that does this very well however no longer appears to be actively maintained and has some really nice functionality you could incorporate/borrow from.

pkgsearch
asciicast

#!/usr/bin/env bash

declare -r esc=$'\033'
declare -r c_reset="${esc}[0m"
declare -r c_red="${esc}[31m"
declare -r c_green="${esc}[32m"
declare -r c_blue="${esc}[34m"
declare distro
declare preview_pos='right:hidden'

usage() {
  LESS=-FEXR less <<HELP
pkgsearch [options] [query]
  lists and installs packages from your distro's repositories
  without any arguments pkgsearch will list all available packages from your cache
  note: on Arch Linux you must pass a string to query the AUR
HELP
}

err() {
  printf "${c_red}%s${c_reset}\n" "$*" >&2
}

die() {
  exit 1
}

has() {
  local verbose=0
  if [[ $1 = '-v' ]]; then
    verbose=1
    shift
  fi
  for c; do c="${c%% *}"
    if ! command -v "$c" &> /dev/null; then
      (( "$verbose" > 0 )) && err "$c not found"
      return 1
    fi
  done
}

select_from() {
  local cmd='command -v'
  for a; do
    case "$a" in
      -c)
        cmd="$2"
        shift 2
        ;;
    esac
  done
  for c; do
    if $cmd "${c%% *}" &> /dev/null; then
      echo "$c"
      return 0
    fi
  done
  return 1
}

fzf() {
  command fzf -e +s --multi --cycle --ansi \
    --bind='Ctrl-X:toggle-preview' \
    --no-hscroll --inline-info \
    --header='tab to select multiple packages, Ctrl-X for more info on a package' "$@"
}

install() {
  local pkgs count
  mapfile -t pkgs
  (( ${#pkgs} > 0 )) || exit
  count="${#pkgs[@]} package"
  (( ${#pkgs[@]} > 1 )) && count+='s'
  printf "installing %s: %s\n" "$count" "${pkgs[*]}"
  $1 "${pkgs[@]}" < /dev/tty
}

debian() {
  fzf --preview='apt-cache show {1}' \
      --query="$1" \
    < <(apt-cache search '.*' | sort |
      sed -u -r "s|^([^ ]+)|${c_green}\1${c_reset}|") |
    cut -d' ' -f1 |
    install "sudo $(select_from 'apt' 'aptitude' 'apt-get') install"
}

arch() {
  local search packages
  search='pacman'
  [[ -n "$1" ]] && search=$(select_from 'pacaur' 'trizen' 'yaourt' 'packer' 'apacman' 'pacman')
  packages=$(fzf --preview="$search -Si {2}" \
    < <( $search -Ss "$1" |
      gawk '{
        getline descr;
        sub(/ */,"", descr);
        repo = blue "[" gensub(/\/.*/, "", 1) "]" reset;
        name = green gensub(/.*\//, "", 1, $1) reset;
        info = gensub(/[^ ]* /, "", 1);
        print repo, name, info, descr;
      }' blue="$c_blue" green="$c_green" reset="$c_reset"
    ) | cut -d' ' -f2)
  [[ "$search" = "pacman" ]] && search="sudo pacman"
  install "$search -S" <<< "$packages"
}

void() {
  local package_list packagename='{ sub(/-[^\-]*$/, "", $2); print $2 }'
  package_list=$(xbps-query -Rs '' | sort)
  fzf --preview="p=\$(awk \"$packagename\" <<< {}); xbps-query -Rx \$p" \
      --query="$1" <<< "$package_list" |
    awk "$packagename" |
    install 'xbps-install -S'
}

fedora() {
  fzf --query="$*" --preview='p={}; p="${p%% *}"; dnf -q info "${p%.*}"' \
    < <(dnf -qC repoquery --qf "${c_green}%{name} ${c_reset} - %{summary}" \*) |
    awk '{ package=$1; sub(/\.\S+/, "", package); print package }' |
    install 'sudo dnf install'
}

while true; do
  case "$1" in
    -h|--help) usage; exit ;;
    -p|--preview) preview_pos="$2"; shift 2 ;;
    *) break
  esac
done

has -v fzf gawk || die

request="$*"

if [[ -r /etc/os-release ]]; then
  distro=$(awk -F'=' '"NAME" == $1 { gsub("\"", "", $2); print tolower($2); }' /etc/os-release)
  distro="${distro%% *}"
fi

case "$distro" in
  debian|ubuntu) debian "$request" ;;
  arch) arch "$request" ;;
  void) void "$request" ;;
  fedora) fedora "$request" ;;
  *) die 'unknown distro :(' ;;
esac

pkgrm
https://asciinema.org/a/DYCtFIsVOrvnofg8TBi3A4JZT

#!/usr/bin/env bash

declare by_size

has() {
  local verbose=0
  if [[ $1 = '-v' ]]; then
    verbose=1
    shift
  fi
  for c; do c="${c%% *}"
    if ! command -v "$c" &> /dev/null; then
      (( "$verbose" > 0 )) && err "$c not found"
      return 1
    fi
  done
}

err() {
  printf "\e[31m%s\e[0m\n" "$*" >&2
}

die() {
  (( $# > 0 )) && err "$*"
  exit 1
}

select_from() {
  local o c cmd OPTARG OPTIND
  cmd='command -v'
  while getopts 'c:' o; do
    case "$o" in
      c) cmd="$OPTARG" ;;
    esac
  done
  shift "$((OPTIND-1))"
  for c; do
    if $cmd "${c%% *}" &> /dev/null; then
      echo "$c"
      return 0
    fi
  done
  return 1
}

has -v fzf expac || die

fzf() {
  command fzf -e --multi --no-hscroll --inline-info --cycle --bind='Ctrl-a:toggle-all' "$@"
}

case $1 in
  -s|--size) by_size=1; shift;
esac

if (( $# > 0 )); then
  sudo pacman -Rcusn "$@"
  exit
fi

preview=$(select_from pacaur pacman)

if (( by_size )); then
  mapfile -t pkgs < <(expac -H M '%m\t%n' | sort -hr | fzf +s --preview="$preview --color=always -Si {3}" -q '!^lib ' | cut -f2)
else
  mapfile -t pkgs < <(expac '%n' | fzf +s --preview="$preview --color=always -Si {1}" -q '!^lib ' | cut -d' ' -f1)
fi

(( ${#pkgs[@]} > 0 )) && sudo pacman -Rcusn "${pkgs[@]}"

js (fzf package search in npm requires npm, jq)
asciicast

#!/usr/bin/env bash

declare -r esc=$'\033'
declare -r c_reset="${esc}[0m"
declare -r c_red="${esc}[31m"
declare OPTIND
declare -a opts=( -\# )
declare id

usage() {
  LESS=-FEXR less <<'HELP'
ix [OPTIONS]
-l             list all pastes, uses fzf for interactive use
-d [id]        delete the paste at [id]
-i [id]        replaces the paste with stdin
-h             print this help
HELP
}

err() {
  printf "${c_red}%s${c_reset}\n" "$@" >&2
}

die() {
  err "$@"
  exit 1
}

has() {
  local verbose=0
  if [[ $1 == '-v' ]]; then
    verbose=1
    shift
  fi
  for c; do c="${c%% *}"
    if ! command -v "$c" &> /dev/null; then
      (( verbose > 0 )) && err "$c not found"
      return 1
    fi
  done
}

select_from() {
  local cmd='command -v'
  for a; do
    case "$a" in
      -c) cmd="$2"; shift 2 ;;
    esac
  done
  for c; do
    if $cmd "${c%% *}" &> /dev/null; then
      echo "$c"
      return 0
    fi
  done
  return 1
}

has_account() {
  [[ -r ~/.netrc ]] && grep -qF 'ix.io' ~/.netrc
}

create_account() {
  echo "It seems you don't have a ~/.netrc with ix.io in it. Let's make one!"
  read -r -p 'enter a username: ' username
  read -rs -p 'enter a password (this will be hashed with sha256sum): ' password
  echo ''
  password=$(sha256sum <<< "$password")
  password="${password/%  -}"
  printf "machine ix.io login %s password %s" "$username" "$password" >> ~/.netrc
  chmod 600 ~/.netrc
  if has_account; then
    echo 'success!'
  else
    die 'could not create account!'
  fi
}

get_user_name() {
  awk '"ix.io" == $2 { print $4 }' ~/.netrc
}

get_pastes() {
  curl -s "http://ix.io/user/$1" |
    grep -A1 -P '\<a href="\/[a-zA-Z0-9]+"\>' |
    awk -F'--' '
      BEGIN {FS="<a href=\""}
      /a href/{ sub(/\">\[r\]<\/a>/, "\t", $2); printf "http://ix.io" $2 }
      /@/{sub(/^\s+/, "", $0); print}
    '
}

list_pastes() {
  local highlighter
  highlighter=$(select_from 'bat --color always --style numbers,header,snip' 'highlight -q --force -O ansi' pygmentize cat)
  url=$(get_pastes "$(get_user_name)" | fzf \
    --inline-info --cycle \
    --header='Ctrl-E = edit; Ctrl-V = view; Ctrl-D = delete' \
    --preview="curl -s '{1}' | ${highlighter}" \
    --bind 'space:jump' \
    --bind 'q:abort' \
    --bind "Ctrl-V:execute:less -R < <(curl -s '{1}' ${highlighter:+ | $highlighter}) > /dev/tty" \
    --bind 'Ctrl-E:execute:p={1}; edit=$(curl -s "$p" | vipe); ix -i "${p##*/}" <<< "$edit"' \
    --expect='Ctrl-D')
  if [[ -n "$url" ]]; then
    mapfile -t res <<< "$url"
    if [[ "${res[0]}" = 'Ctrl-D' ]]; then
      id="${res[1]}"
      id="${id#*ix.io/}"
      id="${id%%$'\t'*}"
      ix -d "$id"
      list_pastes
      exit
    fi
  fi
}

has -v curl || die

has_account || create_account

[[ -e ~/.netrc ]] && opts+=( '-n' )

while getopts ":hld:i:n:" x; do
  case "$x" in
    h) usage; exit ;;
    d) curl -s "${opts[@]}" -X DELETE "$OPTARG"; exit ;;
    l)
      if [[ -e ~/.netrc ]]; then
        url=$(list_pastes)
        [[ -n "$url" ]] && cut -f1 <<< "$url" | tee | xclip
      else
        die 'no netrc found'
      fi
      exit ;;
    i) opts+=( -X PUT ); id="$OPTARG" ;;
    n) opts+=( -F "read:1=$OPTARG" ) ;;
  esac
done
shift $(( OPTIND - 1 ))

if [[ -t 0 ]]; then
  if [[ -n "$1" ]]; then
    filename="$1"
    shift
    response=$(curl "${opts[@]}" -F f:1=@"$filename" "$@" "ix.io/$id")
    clipboard=$(select_from 'xclip -r ' 'xsel')
    if [[ -n "$clipboard" ]]; then
      tee /dev/tty <<< "$response" | $clipboard
    else
      echo "$response"
    fi
    exit
  fi
  echo "^C to cancel, ^D to send."
fi

curl "${opts[@]}" -F f:1='<-' "$@" "ix.io/$id"

pkgup (lists upgradable package and upgrades selection)
asciicast

#!/usr/bin/env bash

has() {
  local verbose=0
  if [[ $1 = '-v' ]]; then
    verbose=1
    shift
  fi
  for c; do c="${c%% *}"
    if ! command -v "$c" &> /dev/null; then
      (( "$verbose" > 0 )) && err "$c not found"
      return 1
    fi
  done
}

err() {
  printf "\e[31m%s\e[0m\n" "$*" >&2
}

die() {
  (( $# > 0 )) && err "$*"
  exit 1
}

select_from() {
  local cmd='command -v'
  for a; do
    case "$a" in
      -c)
        cmd="$2"
        shift 2
        ;;
    esac
  done
  for c; do
    if $cmd "${c%% *}" &> /dev/null; then
      echo "$c"
      return 0
    fi
  done
  return 1
}

has -v fzf || die

helper=$(select_from pacaur trizen packer apacman pacman)

mapfile -t pkgs < <(
  $helper -Qu --color=always |
  fzf --ansi -e -m --inline-info --cycle --reverse --bind='Ctrl-A:toggle-all' |
  awk '{print $3}'
)

count="${#pkgs[@]} package"
(( ${#pkgs[@]} > 1 )) && count+='s'
printf "upgrading %s: %s\n" "$count" "${pkgs[*]}"

(( ${#pkgs[@]} > 0 )) && $helper -S "${pkgs[@]}"

these scripts were courtasy of daniel grey and are under the gnu genereal public licence https://www.gnu.org/licenses/

Fish: Invalid redirection target:

โ”‚ fish: Invalid redirection target: โ”‚
โ”‚ cat <(pacman -Si 'a2ps') <(pacman -Fl 'a2ps' | awk "{print $2}") โ”‚
โ”‚ ^~~~~~~~~~~~~~~~~~~^

Even running it in zsh, and bashi get this. (In the preview plane)
Finding the name itself works.

fish shell redirection problem

It is a convenient script for package management.
I have substituted yay with paru

I am able to install and remove packages without problem.
but, fzf preview pane is showing error as shown below.

screenshot_20210709202144

it is showing error as fish shell piping output (redirection).

how can this shell redirection error can be avoided ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.