diff --git a/assets/coverage-badge.svg b/assets/coverage-badge.svg
index 2a6facc..ac4f67b 100644
--- a/assets/coverage-badge.svg
+++ b/assets/coverage-badge.svg
@@ -11,7 +11,7 @@
coverage
coverage
- 19.2%
- 19.2%
+ 19.0%
+ 19.0%
diff --git a/e2e-tests/issue_59_rm_completion_test.go b/e2e-tests/issue_59_rm_completion_test.go
new file mode 100644
index 0000000..ff1b007
--- /dev/null
+++ b/e2e-tests/issue_59_rm_completion_test.go
@@ -0,0 +1,57 @@
+// ALR - Any Linux Repository
+// Copyright (C) 2025 Евгений Храмов
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//go:build e2e
+
+package e2etests_test
+
+import (
+ "testing"
+
+ "github.com/alecthomas/assert/v2"
+ "github.com/efficientgo/e2e"
+)
+
+func TestE2EIssue59RmCompletion(t *testing.T) {
+ dockerMultipleRun(
+ t,
+ "issue-59-rm-completion",
+ COMMON_SYSTEMS,
+ func(t *testing.T, r e2e.Runnable) {
+ err := r.Exec(e2e.NewCommand(
+ "alr",
+ "addrepo",
+ "--name",
+ "alr-repo",
+ "--url",
+ "https://gitea.plemya-x.ru/Maks1mS/repo-for-tests.git",
+ ))
+ assert.NoError(t, err)
+
+ err = r.Exec(e2e.NewCommand(
+ "alr", "in", "foo-pkg", "bar-pkg",
+ ))
+ assert.NoError(t, err)
+
+ err = r.Exec(e2e.NewCommand("sh", "-c", "alr rm --generate-bash-completion | grep ^foo-pkg$"))
+ assert.NoError(t, err)
+ err = r.Exec(e2e.NewCommand("sh", "-c", "alr rm --generate-bash-completion | grep ^bar-pkg$"))
+ assert.NoError(t, err)
+ err = r.Exec(e2e.NewCommand("sh", "-c", "alr rm --generate-bash-completion | grep ^test-autoreq-autoprov$"))
+ assert.Error(t, err)
+ },
+ )
+}
diff --git a/install.go b/install.go
index 9c7c7ac..f96b35c 100644
--- a/install.go
+++ b/install.go
@@ -162,6 +162,64 @@ func RemoveCmd() *cli.Command {
Name: "remove",
Usage: gotext.Get("Remove an installed package"),
Aliases: []string{"rm"},
+ BashComplete: func(c *cli.Context) {
+ cfg := config.New()
+ err := cfg.Load()
+ if err != nil {
+ slog.Error(gotext.Get("Error loading config"), "err", err)
+ os.Exit(1)
+ }
+
+ db := database.New(cfg)
+ err = db.Init(c.Context)
+ if err != nil {
+ slog.Error(gotext.Get("Error initialization database"), "err", err)
+ os.Exit(1)
+ }
+
+ installedAlrPackages := map[string]string{}
+ mgr := manager.Detect()
+ if mgr == nil {
+ slog.Error(gotext.Get("Unable to detect a supported package manager on the system"))
+ os.Exit(1)
+ }
+ installed, err := mgr.ListInstalled(&manager.Opts{AsRoot: false})
+ if err != nil {
+ slog.Error(gotext.Get("Error listing installed packages"), "err", err)
+ os.Exit(1)
+ }
+ for pkgName, version := range installed {
+ matches := build.RegexpALRPackageName.FindStringSubmatch(pkgName)
+ if matches != nil {
+ packageName := matches[build.RegexpALRPackageName.SubexpIndex("package")]
+ repoName := matches[build.RegexpALRPackageName.SubexpIndex("repo")]
+ installedAlrPackages[fmt.Sprintf("%s/%s", repoName, packageName)] = version
+ }
+ }
+
+ result, err := db.GetPkgs(c.Context, "true")
+ if err != nil {
+ slog.Error(gotext.Get("Error getting packages"), "err", err)
+ os.Exit(1)
+ }
+ defer result.Close()
+
+ for result.Next() {
+ var pkg database.Package
+ err = result.StructScan(&pkg)
+ if err != nil {
+ slog.Error(gotext.Get("Error iterating over packages"), "err", err)
+ os.Exit(1)
+ }
+
+ _, ok := installedAlrPackages[fmt.Sprintf("%s/%s", pkg.Repository, pkg.Name)]
+ if !ok {
+ continue
+ }
+
+ fmt.Println(pkg.Name)
+ }
+ },
Action: func(c *cli.Context) error {
args := c.Args()
if args.Len() < 1 {
diff --git a/internal/translations/default.pot b/internal/translations/default.pot
index 19526d6..9247f0d 100644
--- a/internal/translations/default.pot
+++ b/internal/translations/default.pot
@@ -166,11 +166,15 @@ msgstr ""
msgid "Remove an installed package"
msgstr ""
-#: install.go:168
+#: install.go:188
+msgid "Error listing installed packages"
+msgstr ""
+
+#: install.go:226
msgid "Command remove expected at least 1 argument, got %d"
msgstr ""
-#: install.go:183
+#: install.go:241
msgid "Error removing packages"
msgstr ""
@@ -307,10 +311,6 @@ msgstr ""
msgid "List ALR repo packages"
msgstr ""
-#: list.go:98
-msgid "Error listing installed packages"
-msgstr ""
-
#: main.go:45
msgid "Print the current ALR version and exit"
msgstr ""
diff --git a/internal/translations/po/ru/default.po b/internal/translations/po/ru/default.po
index 3b242ed..1671e6b 100644
--- a/internal/translations/po/ru/default.po
+++ b/internal/translations/po/ru/default.po
@@ -174,11 +174,15 @@ msgstr "Для команды install ожидался хотя бы 1 аргу
msgid "Remove an installed package"
msgstr "Удалить установленный пакет"
-#: install.go:168
+#: install.go:188
+msgid "Error listing installed packages"
+msgstr "Ошибка при составлении списка установленных пакетов"
+
+#: install.go:226
msgid "Command remove expected at least 1 argument, got %d"
msgstr "Для команды remove ожидался хотя бы 1 аргумент, получено %d"
-#: install.go:183
+#: install.go:241
msgid "Error removing packages"
msgstr "Ошибка при удалении пакетов"
@@ -317,10 +321,6 @@ msgstr "ОШИБКА"
msgid "List ALR repo packages"
msgstr "Список пакетов репозитория ALR"
-#: list.go:98
-msgid "Error listing installed packages"
-msgstr "Ошибка при составлении списка установленных пакетов"
-
#: main.go:45
msgid "Print the current ALR version and exit"
msgstr "Показать текущую версию ALR и выйти"