lua-users home
lua-l archive

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


It was thus said that the Great Daurnimator once stated:
> On 29 October 2017 at 17:22, Sean Conner <sean@conman.org> wrote:
> >   It's close to what I want, but not fully there.  The function u8_width()
> > is close, but the documentation states, "[t]his function ignores control
> > characters in the string," which to me, says it will treat this:
> >
> >         Стоял он, дум\27[31;41m великих полн
> >
> > as
> >
> >         Стоял он, дум[31;41m великих полн
> >
> > and not
> >
> >         Стоял он, дум великих полн
> >
> > which is what I'm trying to do.  I'm also having to treat HT (the tab
> > character) specially because it can be anywhere from 0 to 8 terminal
> > positions, depending upon where it occurs in the string (I don't want it
> > ignored).  I'm pretty sure I can work around control codes and escape
> > sequences using u8_width().
> >
> >   -spc (So I'm still interested in non-LPeg solutions to this)
> 
> Generally you're going to want to pre-process (or post-process)
> control characters yourself. e.g. escape them.
> Otherwise a user's string may contain the escape code for "go to start
> of line", and nothing ends up how you expected. (or worse: clear
> screen).

  Touche.

  What touched this off is this:

	require "colortty"
	
	colors =
	{
	  emerg  = "\27[1;31m", -- [1]
	  alert  = "\27[0;31m",
	  crit   = "\27[0;31m",
	  err    = "\27[0;31m",
	  warn   = "\27[1;33m",
	  notice = "\27[1;32m",
	  info   = "\27[0;32m",
	  debug  = "\27[1;34m"
	}
	
	function log(msg)
	  local bar = string.format("\27[1;39m\27(0x\27(B%s",colors[msg.level])
	
	  io.stdout:write(colortty(string.format(
	        "%s%15.15s %-15.15s %-6s %6s %s %s\n",
	        colors[msg.level],
	        msg.host,
	        msg.program,
	        msg.facility,
	        msg.level,
	        bar, -- os.date("%b %d %H:%M:%S",msg.timestamp),
	        msg.msg
	        )))
	  io.stdout:flush()
	end

It's from my syslog replacement [2] (the realtime.lua script to be exact)
and I use it to monitor syslog in realtime [4] (I treat it as a screen
saver).  The function colortty() is some pretty grotty C code to ensure I
don't write past the right edge of the screen.  I realize now (but not at
the time I wrote this) that I could skip this and do:

	  io.stdout:write(string.format(
	        "%s%15.15s %-15.15s %-6s %6s %s %s\n",
	        colors[msg.level],
	        msg.host,
	        msg.program,
	        msg.facility,
	        msg.level,
	        bar, -- os.date("%b %d %H:%M:%S",msg.timestamp),
	        msg.msg:sub(1,WIDTH-48) -- if I counted correctly
	        ))
	  io.stdout:flush()
	end

where WIDTH is defined as the width of the screen.  But this requires
recalculating the width if the format changes (which it hasn't, but I'm
going for the general case here).

> A notable behaviour is that bash will count any chars between \1 and
> \2 as zero width for the purpose of a PS1 prompt.

  It's interesting to note that \1 is SOH (Start Of Header) and \2 is STX
(Start of Text) respecitively, in ASCII.

> I take advantage of that here:
> https://gist.github.com/daurnimator/4484437#file-bash_prompt-lua-L57-L61
> (sorry this is an old version, I haven't uploaded a more recent copy anywhere)
> 
> Tabs are a bit of an interesting case, as they generally have the
> semantics of "go to next 8-aligned column".
> However in a richer terminal ui, a text box may be offset in the x
> coordinate, or you may want the facility to provide custom tab-stops.
> So generally I end up handling tabs and such explicitly.

  I've found that terminals have varying degrees of support for ISO-2022, so
I'm not sure if I can query an arbitrary terminal for tabstops or not.  For
me, just setting it to 8 works for me.

  -spc (Current have nine rules to parse control codes and sequences)

[1]	The chances of me running ths program on a terminal (or virtual
	terminal) that *doesn't* support ISO-2022 [3] is practically zero. 
	The last non-ISO-2022 terminal I used was effectively fifteen years
	ago, and even *if* I used curses/ncurses for this stuff so I could
	run this on said terminal, said terminal never supported color, so
	it's moot anyway.

[2]	https://github.com/spc476/syslogintr

[3]	aka ANSI escape sequences.

[4]	My syslog daemon strips out control codes on input.  So someone
	trying to do:

		syslog(LOG_CRIT,"clearing da screen! \033[2J");

	won't work.  What gets logged is:

		clearing da screen! [2J