Opened 13 years ago

Closed 13 years ago

Last modified 12 years ago

#15488 closed defect (fixed)

wrap text to terminal width

Reported by: ryandesign (Ryan Schmidt) Owned by: raimue (Rainer Müller)
Priority: Normal Milestone: MacPorts 1.7.0
Component: base Version: 1.7.0
Keywords: Cc:
Port:

Description

MacPorts base in trunk now wraps output to 80 characters, but the terminal window is not necessarily 80 characters wide. It may be wider or narrower.

As a first step, I'd like to see the wrap-to width moved into a variable/constant that's defined only once. Magic numbers in source are bad.

Next step would be to wrap to the actual terminal width (if output is to a terminal) or not wrap at all (if output is to a file or pipe).

Rainer, since you've been working on some stuff near this the past few days, maybe you could at least take care of abstracting the wrap-to width into a variable?

Change History (8)

comment:1 Changed 13 years ago by raimue (Rainer Müller)

Status: newassigned

My main intention to hardcode that to 80 chars was to make it easier readable, even if you are using a wide terminal size.

Changed the behavior of port to use the current size of the terminal window (using COLUMNS environment variable, so you can even customize this). If COLUMNS is not available, it calls stty size to get the size. If even this is not available, it prints a warning and uses a default of 80x24.

COLUMNS should be updated when the terminal is resized, so this also should work fine with longer sessions in interactive mode, where the user could resize the terminal window. I still have to check what happens when port resets the environment to boot_env, which is done on some places.

Committed in r37316.

I don't know how to determine if stdout is attached to a terminal or a pipe (or at least not with Tcl, I think this would require some work with <termios.h> in C). Also, I think wrapping is even a good idea when using a pipe, for example port info |less or similar.

comment:2 Changed 13 years ago by ryandesign (Ryan Schmidt)

This works:

$ port info zlib
zlib @1.2.3, Revision 1 (archivers)
Variants:    examples, (+)universal

zlib is designed to be a free, general-purpose, legally unencumbered, lossless data-compression
library for use on virtually any computer hardware and operating system.
Homepage:    http://www.zlib.net/

Platforms: darwin, freebsd
Maintainers: landonf@macports.org ryandesign@macports.org openmaintainer@macports.org
$

But this doesn't:

$ echo zlib | xargs port info
Warning: Unable to get terminal size, using 80x24!
zlib @1.2.3, Revision 1 (archivers)
can't read "env(COLUMNS)": no such variable
    while executing
"set maxlen $env(COLUMNS)"
    (procedure "wrap" line 5)
    invoked from within
"wrap $vars 0 [string repeat " " 13] 0"
    invoked from within
"if {[llength $fields]} {
            # Show specific fields
            puts [join $fields $field_sep]
        } else {
            # If we weren't as..."
    ("uplevel" body line 130)
    invoked from within
"uplevel 1 $block"
    (procedure "foreachport" line 16)
    invoked from within
"foreachport $portlist {
        puts -nonewline $separator
        # If we have a url, use that, since it's most specific
        # otherwise try to m..."
    (procedure "action_info" line 8)
    invoked from within
"$action_proc $action $portlist [array get global_options]"
    (procedure "process_cmd" line 86)
    invoked from within
"process_cmd $remaining_args"
    invoked from within
"if { [llength $remaining_args] > 0 } {

    # If there are remaining arguments, process those as a command

    # Exit immediately, by default, unless..."
    (file "/mp/bin/port" line 3165)
Variants:    $

comment:3 Changed 13 years ago by raimue (Rainer Müller)

Okay, I did a workaround in r37526.

If no COLUMNS is in the environment (which happens when the input is not a tty), there is no line wrapping at all. I removed 80x24 as fallback, as this is not useful when using pipes.

I don't know if there is a better way to fix it. Even if stdout is a tty, COLUMNS is not available in env and stty size only returns stty: stdin isn't a terminal.

comment:4 Changed 13 years ago by raimue (Rainer Müller)

stty -f /dev/stdout size could be a possible solution. Also, I should look into adding a wrapper for isatty(3) to pextlib1.0.

Linking against ncurses to get this from terminfo could help as well, but I am not very confident with introducing new dependencies for MacPorts itself.

comment:5 Changed 13 years ago by raimue (Rainer Müller)

I tried the stty -f /dev/stdout approach today. But it does not seem to work, I always get a "Permission denied" error.

So it needs an extension in Pextlib. I will look into determining the current size of the terminal using something like:

#include <sys/ioctl.h>
struct winsize = {0, 0, 0, 0};
ioctl(STDOUT_FILENO, TIOCGWINSZ, &s);

comment:6 Changed 13 years ago by raimue (Rainer Müller)

Resolution: fixed
Status: assignedclosed

Implemented in r38940 and r38941. Hopefully it is now working as expected.

Now even something like echo vim | xargs port info wraps at the correct width.

comment:7 Changed 13 years ago by tobypeterson

Milestone: MacPorts base bugsMacPorts Future

Milestone MacPorts base bugs deleted

comment:8 Changed 12 years ago by jmroot (Joshua Root)

Milestone: MacPorts FutureMacPorts 1.7.0
Note: See TracTickets for help on using tickets.