On Wed, Jun 11, 2014 at 11:12:31AM -0400, Douglas Philips wrote:
> On 6/11/14 11:07 AM, Stefano Zacchiroli wrote:
> > I think it would be a much more useful default for --columns than
> > getenv(COLUMNS), as the latter is almost always gonna be empty.
> 
> I suggest that if the user has taken the effort to export COLUMNS, it
> should be used. If not, then the ioctl (assuming portability) is a
> reasonable fallback.

Sounds sensible.

Please find attached a patch that implements this behavior. If it's to
the liking of ledger maintainers, can someone please apply it to Git's
master?

Disclaimer: it's my first patch to ledger, so please feel free to point
out if I've missed any best practices. FWIW: it works for me --- for
"register" only, I don't use "select" myself so I haven't tested that
part --- and all tests pass.

I don't quite like the duplication between report.cc and select.cc, but
it's not clear to me if there is a common place where to store global
configuration information derived by further processing of the ledger
execution environment.

Cheers.
-- 
Stefano Zacchiroli  . . . . . . .  [email protected] . . . . o . . . o . o
Maître de conférences . . . . . http://upsilon.cc/zack . . . o . . . o o
Former Debian Project Leader  . . @zack on identi.ca . . o o o . . . o .
« the first rule of tautology club is the first rule of tautology club »

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"Ledger" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
>From 70205962eb0ebaa6ee384c4c439c618cba85f2b3 Mon Sep 17 00:00:00 2001
From: Stefano Zacchiroli <[email protected]>
Date: Wed, 11 Jun 2014 17:34:37 +0200
Subject: [PATCH] make --columns default to terminal width, as returned by
 ioctl()

If set, the COLUMNS environment variable will take precedence over terminal
width. However, please note that COLUMNS is usually *not* exported by shells to
child processes, so in most cases COLUMNS will be undefined for ledger.

Terminal width is queried using ioctl() on stdin. For the sake of portability
the querying is not done on WIN32 platforms.
---
 src/report.cc    | 7 +++++++
 src/select.cc    | 7 +++++++
 src/system.hh.in | 1 +
 3 files changed, 15 insertions(+)

diff --git a/src/report.cc b/src/report.cc
index 7bb79bd..22c044f 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -181,10 +181,17 @@ void report_t::normalize_options(const string& verb)
   }
 
   long cols = 0;
+#ifndef WIN32
+  struct winsize ws;
+#endif
   if (HANDLED(columns_))
     cols = lexical_cast<long>(HANDLER(columns_).value);
   else if (const char * columns = std::getenv("COLUMNS"))
     cols = lexical_cast<long>(columns);
+#ifndef WIN32
+  else if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != -1)
+      cols = ws.ws_col;
+#endif
   else
     cols = 80L;
 
diff --git a/src/select.cc b/src/select.cc
index 45ae34b..09375bb 100644
--- a/src/select.cc
+++ b/src/select.cc
@@ -145,10 +145,17 @@ value_t select_command(call_scope_t& args)
       string  thus_far = "";
 
       std::size_t cols = 0;
+#ifndef WIN32
+      struct winsize ws;
+#endif
       if (report.HANDLED(columns_))
         cols = lexical_cast<std::size_t>(report.HANDLER(columns_).value);
       else if (const char * columns_env = std::getenv("COLUMNS"))
         cols = lexical_cast<std::size_t>(columns_env);
+#ifndef WIN32
+      else if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != -1)
+          cols = ws.ws_col;
+#endif
       else
         cols = 80;
 
diff --git a/src/system.hh.in b/src/system.hh.in
index eaee14d..ba42477 100644
--- a/src/system.hh.in
+++ b/src/system.hh.in
@@ -145,6 +145,7 @@ typedef std::ostream::pos_type ostream_pos_type;
 #if defined(WIN32)
 #include <io.h>
 #else
+#include <sys/ioctl.h>
 #include <unistd.h>
 #endif
 #if HAVE_GETPWUID || HAVE_GETPWNAM
-- 
2.0.0

Reply via email to