Add the "columns(str)" variant.

This commit is contained in:
Dianne Skoll
2022-10-11 13:18:44 -04:00
parent d7975634af
commit 8ada68ce54
8 changed files with 123 additions and 6 deletions

18
examples/alignment.rem Normal file
View File

@@ -0,0 +1,18 @@
# Demo the columns() function
#
# Run as: remind -@2 alignment.rem
SET $AddBlankLines 0
BANNER %
FSET center(x) pad("", " ", (columns() - columns(x))/2) + x
FSET right(x) pad("", " ", columns() - columns(x)) + x
MSG This is left-aligned.
MSG [ansicolor(0,255,0)]This is also left-aligned.[ansicolor("")]
MSG [center("This is centered.")]
MSG [ansicolor(0,255,0) + center("🌕 🌕 🌕 🌕 This is also centered. ") + ansicolor("")]
msg [right("This is right-aligned.")]
msg [ansicolor(0,255,0) + right("This is also right-aligned. 🌕 🌕 🌕") + ansicolor("")]

View File

@@ -2828,10 +2828,21 @@ above. A \fBSTRING\fR \fIarg\fR is converted by parsing it as an
integer.
.RE
.TP
.B columns()
.B columns([s_arg])
If called with no arguments, \fBcolumns()\fR behaves as follows:
If standard output is a TTY, returns the width of the terminal in columns.
If standard output is not a TTY, attempts to open "/dev/tty" to obtain
the terminal size. If this fails, returns -1.
.RS
.PP
If called with a single string argument, \fBcolumns(str)\fR returns
the number of columns \fBstr\fR will occupy if printed to a terminal.
ANSI color-changing sequences occupy zero columns whereas some Unicode
characters occupy two columns. \fBcolumns(str)\fR takes all of that
into account. Note that if Remind was compiled without Unicode support,
\fBcolumns(str)\fR returns a type mismatch error.
.RE
.TP
.B current()
Returns the current date and time as a DATETIME object. This may be the

View File

@@ -9,7 +9,7 @@
/* */
/***************************************************************/
#define _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#include "config.h"
#include "custom.h"

View File

@@ -13,6 +13,12 @@
#include "version.h"
#include "config.h"
#ifdef REM_USE_WCHAR
#define _XOPEN_SOURCE 600
#include <wctype.h>
#include <wchar.h>
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -230,7 +236,7 @@ BuiltinFunc Func[] = {
{ "char", 1, NO_MAX, 1, FChar },
{ "choose", 2, NO_MAX, 1, FChoose },
{ "coerce", 2, 2, 1, FCoerce },
{ "columns", 0, 0, 0, FColumns },
{ "columns", 0, 1, 0, FColumns },
{ "current", 0, 0, 0, FCurrent },
{ "date", 3, 3, 1, FDate },
{ "datepart", 1, 1, 1, FDatepart },
@@ -3409,5 +3415,44 @@ static int FRows(func_info *info)
}
static int FColumns(func_info *info)
{
return rows_or_cols(info, 0);
#ifdef REM_USE_WCHAR
size_t len;
wchar_t *buf, *s;
int width;
#endif
if (Nargs == 0) {
return rows_or_cols(info, 0);
}
ASSERT_TYPE(0, STR_TYPE);
#ifdef REM_USE_WCHAR
len = mbstowcs(NULL, ARGSTR(0), 0);
if (len == (size_t) -1) return E_NO_MEM;
buf = calloc(len+1, sizeof(wchar_t));
if (!buf) return E_NO_MEM;
(void) mbstowcs(buf, ARGSTR(0), len+1);
s = buf;
width = 0;
while (*s) {
if (*s == 0x1B && *(s+1) == '[') {
/* Skip escape sequences */
s += 2;
while (*s && (*s < 0x40 || *s > 0x7E)) {
s++;
}
if (*s) {
s++;
}
continue;
}
width += wcwidth(*s);
s++;
}
free(buf);
RetVal.type = INT_TYPE;
RETVAL = width;
return OK;
#else
return E_BAD_TYPE;
#endif
}

View File

@@ -10,7 +10,7 @@
/* */
/***************************************************************/
#define _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#include "config.h"
#include <errno.h>

View File

@@ -178,7 +178,7 @@ int have_callstack(void);
int print_callstack(FILE *fp);
void pop_call(void);
#ifdef REM_USE_WCHAR
#define _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#include <wctype.h>
#include <wchar.h>
void PutWideChar(wchar_t const wc);

View File

@@ -42,3 +42,8 @@ set a ansicolor(128, 128, 128, -1)
set a ansicolor(128, 128, 128, 0, 2)
set a ansicolor(128, 128, 128, 0, -1)
set a ansicolor(128,0,0)
set str a + "foo: 🌅"
set w columns(str)
MSG Width of [str] is: [w]

View File

@@ -5568,6 +5568,8 @@ keyword will wrap it so it's pleasantly readable.
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: -1
UseVTColors is: 1
Use256Colors is: 0
@@ -5629,6 +5631,8 @@ keyword will wrap it so
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: -1
UseVTColors is: 1
Use256Colors is: 1
@@ -5690,6 +5694,8 @@ keyword will wrap it[
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: -1
UseVTColors is: 1
Use256Colors is: 0
@@ -5751,6 +5757,8 @@ keyword will[38;2;0
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 0
UseVTColors is: 1
Use256Colors is: 0
@@ -5812,6 +5820,8 @@ keyword will wrap it so
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 0
UseVTColors is: 1
Use256Colors is: 1
@@ -5873,6 +5883,8 @@ keyword will wrap it[
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 0
UseVTColors is: 1
Use256Colors is: 0
@@ -5934,6 +5946,8 @@ keyword will[38;2;0
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 1
UseVTColors is: 1
Use256Colors is: 0
@@ -5995,6 +6009,8 @@ keyword will wrap it so
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 1
UseVTColors is: 1
Use256Colors is: 1
@@ -6056,6 +6072,8 @@ keyword will wrap it[
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 1
UseVTColors is: 1
Use256Colors is: 0
@@ -6117,6 +6135,8 @@ keyword will[38;2;0
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: -1
UseVTColors is: 1
Use256Colors is: 0
@@ -6178,6 +6198,8 @@ keyword will wrap it so
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: -1
UseVTColors is: 1
Use256Colors is: 1
@@ -6239,6 +6261,8 @@ keyword will wrap it[
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: -1
UseVTColors is: 1
Use256Colors is: 0
@@ -6300,6 +6324,8 @@ keyword will[38;2;0
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 0
UseVTColors is: 1
Use256Colors is: 0
@@ -6361,6 +6387,8 @@ keyword will wrap it so
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 0
UseVTColors is: 1
Use256Colors is: 1
@@ -6422,6 +6450,8 @@ keyword will wrap it[
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 0
UseVTColors is: 1
Use256Colors is: 0
@@ -6483,6 +6513,8 @@ keyword will[38;2;0
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 1
UseVTColors is: 1
Use256Colors is: 0
@@ -6544,6 +6576,8 @@ keyword will wrap it so
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 1
UseVTColors is: 1
Use256Colors is: 1
@@ -6605,6 +6639,8 @@ keyword will wrap it[
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
TerminalBackground is: 1
UseVTColors is: 1
Use256Colors is: 0
@@ -6666,6 +6702,8 @@ keyword will[38;2;0
../tests/ansicolors.rem(41): ansicolor(): Number too low
../tests/ansicolors.rem(42): ansicolor(): Number too high
../tests/ansicolors.rem(43): ansicolor(): Number too low
Width of foo: 🌅 is: 7
$AddBlankLines test
Reminders for Saturday, 1st January, 2022: