[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Columnar package list style (patch included)



On 2016-03-04 15:31, Julian Andres Klode wrote:
On Wed, Mar 02, 2016 at 11:56:09PM +0100, Christian Blichmann wrote:
[...]
A patch formatted with git format-patch is a great idea.


Done. My git-fu is weak.

Comments:

diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index 8290859..406f9ba 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -173,7 +173,8 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
       addArg(0, "show-progress", "DpkgPM::Progress", 0);
       addArg('f', "fix-broken", "APT::Get::Fix-Broken", 0);
       addArg(0, "purge", "APT::Get::Purge", 0);
-      addArg('V',"verbose-versions","APT::Get::Show-Versions",0);
+      addArg('V', "verbose-versions", "APT::Get::Show-Versions", 0);
+      addArg(0, "list-columns", "APT::Get::Show-Columns", 0);

list or show columns?


Done. It's now List-Columns.

[...]
diff --git a/apt-private/private-output.h b/apt-private/private-output.h
index 8e4b50e..d99e2af 100644
--- a/apt-private/private-output.h
+++ b/apt-private/private-output.h
@@ -9,6 +9,7 @@
 #include <fstream>
 #include <string>
 #include <iostream>
+#include <vector>

 // forward declaration
 class pkgCacheFile;
@@ -34,6 +35,8 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now); APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now);

+void ShowColumnarList(std::ostream &out, const std::vector<std::string> &List, size_t Indent, size_t ScreenWidth);

Don't like columnar, but don't know why.


Done. Renamed to ShowWithColumns()

+
template<class Container, class PredicateC, class DisplayP, class DisplayV> bool ShowList(std::ostream &out, std::string const &Title,
       Container const &cont,
       PredicateC Predicate,
@@ -43,7 +46,9 @@ template<class Container, class PredicateC, class DisplayP, class DisplayV> bool size_t const ScreenWidth = (::ScreenWidth > 3) ? ::ScreenWidth - 3 : 0;
    int ScreenUsed = 0;
bool const ShowVersions = _config->FindB("APT::Get::Show-Versions", false); + bool const ShowColumnar = _config->FindB("APT::Get::Show-Columns", false);

columnar or columns?


Done. It's ListColumns now.

[...]
No changelog entries, we autogenerate them from git commit messages.

Done.
From 145006bf98a61a2b39e4787fbf26577dc0aac681 Mon Sep 17 00:00:00 2001
From: Christian Blichmann <christian@blichmann.eu>
Date: Tue, 1 Mar 2016 22:56:32 +0100
Subject: [PATCH] Add columnar output for package lists in the style of 'ls'

---
 apt-private/private-cmndline.cc |  3 +-
 apt-private/private-output.cc   | 77 +++++++++++++++++++++++++++++++++++++++++
 apt-private/private-output.h    | 39 ++++++++++++++-------
 doc/apt-get.8.xml               |  6 ++++
 4 files changed, 112 insertions(+), 13 deletions(-)

diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index 8290859..eb8b57d 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -173,7 +173,8 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
       addArg(0, "show-progress", "DpkgPM::Progress", 0);
       addArg('f', "fix-broken", "APT::Get::Fix-Broken", 0);
       addArg(0, "purge", "APT::Get::Purge", 0);
-      addArg('V',"verbose-versions","APT::Get::Show-Versions",0);
+      addArg('V', "verbose-versions", "APT::Get::Show-Versions", 0);
+      addArg(0, "list-columns", "APT::Get::List-Columns", 0);
       addArg(0, "auto-remove", "APT::Get::AutomaticRemove", 0);
       addArg(0, "reinstall", "APT::Get::ReInstall", 0);
       addArg(0, "solver", "APT::Solver", CommandLine::HasArg);
diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc
index 458d78d..9a9f277 100644
--- a/apt-private/private-output.cc
+++ b/apt-private/private-output.cc
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <signal.h>
 #include <sys/ioctl.h>
+#include <vector>
 
 #include <sstream>
 
@@ -301,6 +302,82 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,	/*{{{*/
    out << output;
 }
 									/*}}}*/
+// ShowWithColumns - Show a list in the style of ls			/*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out a vector of strings with the given indent and in as
+   many columns as will fit the screen width.
+   
+   The output looks like:
+  abiword                debootstrap                  gir1.2-upowerglib-1.0
+  abiword-common         dh-make                      google-chrome-beta
+  abiword-plugin-grammar dmeventd                     gstreamer1.0-clutter-3.0
+  binfmt-support         dmsetup                      hostname
+  console-setup          evolution-data-server        iproute2
+  console-setup-linux    evolution-data-server-common
+  coreutils              ffmpeg
+ */
+struct columnInfo
+{
+   bool ValidLen;
+   size_t LineWidth;
+   vector<size_t> RemainingWidths;
+};
+void ShowWithColumns(ostream &out, vector<string> const &List, size_t Indent, size_t ScreenWidth)
+{
+   enum { MinColumnWidth = 2, ColumnSpace = 1 };
+
+   size_t const ListSize = List.size();
+   size_t const MaxScreenCols = (ScreenWidth - Indent) /
+         MinColumnWidth;
+   size_t const MaxNumCols = min(MaxScreenCols, ListSize);
+
+   vector<columnInfo> ColumnInfo(MaxNumCols);
+   for (size_t I = 0; I < MaxNumCols; ++I) {
+      ColumnInfo[I].ValidLen = true;
+      ColumnInfo[I].LineWidth = (I + 1) * MinColumnWidth;
+      ColumnInfo[I].RemainingWidths.resize(I + 1, MinColumnWidth);
+   }
+
+   for (size_t I = 0; I < ListSize; ++I) {
+      for (size_t J = 0; J < MaxNumCols; ++J) {
+         auto& Col = ColumnInfo[J];
+         if (!Col.ValidLen)
+            continue;
+
+         size_t Idx = I / ((ListSize + J) / (J + 1));
+         size_t RealColLen = List[I].size() + (Idx == J ? 0 : ColumnSpace);
+         if (Col.RemainingWidths[Idx] < RealColLen) {
+            Col.LineWidth += RealColLen - Col.RemainingWidths[Idx];
+            Col.RemainingWidths[Idx] = RealColLen;
+            Col.ValidLen = Col.LineWidth < ScreenWidth;
+         }
+      }
+   }
+   size_t NumCols = MaxNumCols;
+   while (NumCols > 1 && !ColumnInfo[NumCols - 1].ValidLen)
+      --NumCols;
+
+   size_t NumRows = ListSize / NumCols + (ListSize % NumCols != 0);
+   auto const &LineFormat = ColumnInfo[NumCols - 1];
+   for (size_t Row = 0; Row < NumRows; ++Row) {
+      size_t Col = 0;
+      size_t I = Row;
+      out << string(Indent, ' ');
+      while (true) {
+         out << List[I];
+
+         size_t CurLen = List[I].size();
+         size_t MaxLen = LineFormat.RemainingWidths[Col++];
+         I += NumRows;
+         if (I >= ListSize)
+            break;
+
+         out << string(MaxLen - CurLen, ' ');
+      }
+      out << endl;
+   }
+}
+									/*}}}*/
 // ShowBroken - Debugging aide						/*{{{*/
 // ---------------------------------------------------------------------
 /* This prints out the names of all the packages that are broken along
diff --git a/apt-private/private-output.h b/apt-private/private-output.h
index 8e4b50e..b366d12 100644
--- a/apt-private/private-output.h
+++ b/apt-private/private-output.h
@@ -9,6 +9,7 @@
 #include <fstream>
 #include <string>
 #include <iostream>
+#include <vector>
 
 // forward declaration
 class pkgCacheFile;
@@ -34,6 +35,8 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
 APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now);
 APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now);
 
+void ShowWithColumns(std::ostream &out, const std::vector<std::string> &List, size_t Indent, size_t ScreenWidth);
+
 template<class Container, class PredicateC, class DisplayP, class DisplayV> bool ShowList(std::ostream &out, std::string const &Title,
       Container const &cont,
       PredicateC Predicate,
@@ -43,7 +46,9 @@ template<class Container, class PredicateC, class DisplayP, class DisplayV> bool
    size_t const ScreenWidth = (::ScreenWidth > 3) ? ::ScreenWidth - 3 : 0;
    int ScreenUsed = 0;
    bool const ShowVersions = _config->FindB("APT::Get::Show-Versions", false);
+   bool const ListColumns = _config->FindB("APT::Get::List-Columns", false);
    bool printedTitle = false;
+   std::vector<std::string> PackageList;
 
    for (auto const &Pkg: cont)
    {
@@ -66,24 +71,34 @@ template<class Container, class PredicateC, class DisplayP, class DisplayV> bool
       else
       {
 	 std::string const PkgName = PkgDisplay(Pkg);
-	 if (ScreenUsed == 0 || (ScreenUsed + PkgName.length()) >= ScreenWidth)
-	 {
-	    out << std::endl << "  ";
-	    ScreenUsed = 0;
-	 }
-	 else if (ScreenUsed != 0)
-	 {
-	    out << " ";
-	    ++ScreenUsed;
+	 if (ListColumns)
+	    PackageList.push_back(PkgName);
+	 else {
+	    if (ScreenUsed == 0 || (ScreenUsed + PkgName.length()) >= ScreenWidth)
+	    {
+	       out << std::endl << "  ";
+	       ScreenUsed = 0;
+	    }
+	    else if (ScreenUsed != 0)
+	    {
+	       out << " ";
+	       ++ScreenUsed;
+	    }
+	    out << PkgName;
+	    ScreenUsed += PkgName.length();
 	 }
-	 out << PkgName;
-	 ScreenUsed += PkgName.length();
       }
    }
 
    if (printedTitle == true)
    {
-      out << std::endl;
+      if (ListColumns)
+      {
+	 out << std::endl;
+	 ShowWithColumns(out, PackageList, 2, ScreenWidth);
+      }
+      else
+	 out << std::endl;
       return false;
    }
    return true;
diff --git a/doc/apt-get.8.xml b/doc/apt-get.8.xml
index 60fa46f..dae9557 100644
--- a/doc/apt-get.8.xml
+++ b/doc/apt-get.8.xml
@@ -368,6 +368,12 @@
      Configuration Item: <literal>APT::Get::Show-Versions</literal>.</para></listitem>
      </varlistentry>
 
+     <varlistentry><term><option>--list-columns</option></term>
+     <listitem><para>Display package lists in columnar format; prints package lists in the
+     style of the "ls" command.
+     Configuration Item: <literal>APT::Get::List-Columns</literal>.</para></listitem>
+     </varlistentry>
+
      <varlistentry><term><option>-a</option></term>
                    <term><option>--host-architecture</option></term>
      <listitem><para>This option controls the architecture packages are built for
-- 
2.7.0


Reply to: