Unable to Print ANSI Escape codes in Simply Scheme - scheme

I have been trying to use ANSI escape codes to clear the screen in simply scheme, but when I do so it either does not work and returns:
read-syntax: missing ']' to close preceding '[', found instead ')'
when trying (display '\033[2J)
Or when turning it into a string it prints out (in purple for some reason, even though it is the clear screen code)
[2J
when doing (display "\033[2J")
I have been stuck here for a while as (clear) does not work in Simply Scheme, and doing '\033\[2J only causes a different error. All help with this would be appreciated.

If you are interacting with Racket using DrRacket then ANSI escape codes won't work. If you are running Racket in a terminal which supports them, they will. There may be a way of erasing a buffer in DrRacket programmatically, but it's not this.

Related

Clearing the screen by printing a character?

I'm using chez-scheme and I can't find a way to clear the screen completely. (If someone knows a better way than printing I'd be interested in that too but it's not my question here)
From what I can find clearing the screen by ^L (control-L) or giving the clear command (in bash at least) is equivalent to outputting ASCII character 12: Form feed.
However, printing this does nothing. If I use (display (integer->char 12)) it just prints a newline. Another way to encode this character is \f (analogous to \n for newline), but in Python print("\f") as well as in Scheme (display "\f") is just a newline.
Is my understanding of the meaning of ASCII 12 just wrong, or are implementations lacking?
Is there any way to clear the screen that should work across languages, analogous to \n for a newline?
If you want to clear the screen, the "ANSI" sequence in a printf
\033[2J
clears the entire screen, e.g.,
printf '\033[2J'
The command-line clear program uses this, along with moving the cursor to the "home" position, again an "ANSI" sequence:
\033[H
The program gets the information from the terminal database. For example, for TERM=vt100, it might see this (using \E as \033):
clear=\E[H\E[J$<50>
(the $<50> indicates padding needed for real VT100s). You might notice that the 2 is absent from this string. That is because the cursor is first moved to the home (upper left) position, and the 2 (entire screen) is not necessary. Eliminating that from the string made VT100s a little faster.
On the other hand, if you just want to reset the terminal, you can use the VT100-style RIS:
\033c
but that has side-effects, besides not being in ECMA-48. These bug reports were for side-effects of \033c:
Debian Bug report logs - #60377
"reset" broken for dumb terminals
Debian Bug report logs - #239205
"reset changes a unicode console to non-unicode"
Further reading:
Why doesn't the screen clear when I type control/L?
XTerm Control Sequences
CSI Ps J Erase in Display (ED).
Ps = 0 -> Erase Below (default).
Ps = 1 -> Erase Above.
Ps = 2 -> Erase All.
Ps = 3 -> Erase Saved Lines (xterm).
ECMA-48: Control Functions for Coded Character Sets
You can print \033c which resets the terminal:
petite -q <<< '(display "\033c")'
\033 is escape and c is literal c.
I can't give you any information about how widely this is supported.

Dealing with unescaped strings

I wrote an alternative fonction to open AutoCAD drawings. However, AutoCAD made it really hard to change how a document is opened when it is ran from Windows Explorer (double click the file with file association). The only method I found is to change a registry key which is "OpenDdeExec". There is a supplied argument (%1) that gives me a unescaped path to the file to open.
I need to ignore the escaping in path or replace the backslashes with double backslashes before it gets parsed as being special characters. In C#, you could do something like string s = #"I\Like random\backslashes"; and backslashes would be taken as the actualy backslashe character. In lisp, the only equivalence I found is quote which has a weird behavior (since it's normal use isn't exactly what I'm trying to acheive).
If I write something like (quote (I\Like random\backslashes)), the outcome will be (I\\Like random\\backslashes) which is ALMOST what I need. However, I have to get rid of the parenthesis. Any idea how I can acheive this?
Note: Doing this (quote I\Like random\backslashes) will break due to the space. It would, however, work on (quote I\Like\backslashes). This would output I\\Like\\backslashes just like I want.
This is the current OpenDdeExec with the described issue:
(OPENFROMSHELL (QUOTE (%1)))
This is unfortunately not possible with AutoCAD's limited LISP.

How to escape unicode characters in bash prompt correctly

I have a specific method for my bash prompt, let's say it looks like this:
CHAR="༇ "
my_function="
prompt=\" \[\$CHAR\]\"
echo -e \$prompt"
PS1="\$(${my_function}) \$ "
To explain the above, I'm builidng my bash prompt by executing a function stored in a string, which was a decision made as the result of this question. Let's pretend like it works fine, because it does, except when unicode characters get involved
I am trying to find the proper way to escape a unicode character, because right now it messes with the bash line length. An easy way to test if it's broken is to type a long command, execute it, press CTRL-R and type to find it, and then pressing CTRL-A CTRL-E to jump to the beginning / end of the line. If the text gets garbled then it's not working.
I have tried several things to properly escape the unicode character in the function string, but nothing seems to be working.
Special characters like this work:
COLOR_BLUE=$(tput sgr0 && tput setaf 6)
my_function="
prompt="\\[\$COLOR_BLUE\\] \"
echo -e \$prompt"
Which is the main reason I made the prompt a function string. That escape sequence does NOT mess with the line length, it's just the unicode character.
The \[...\] sequence says to ignore this part of the string completely, which is useful when your prompt contains a zero-length sequence, such as a control sequence which changes the text color or the title bar, say. But in this case, you are printing a character, so the length of it is not zero. Perhaps you could work around this by, say, using a no-op escape sequence to fool Bash into calculating the correct line length, but it sounds like that way lies madness.
The correct solution would be for the line length calculations in Bash to correctly grok UTF-8 (or whichever Unicode encoding it is that you are using). Uhm, have you tried without the \[...\] sequence?
Edit: The following implements the solution I propose in the comments below. The cursor position is saved, then two spaces are printed, outside of \[...\], then the cursor position is restored, and the Unicode character is printed on top of the two spaces. This assumes a fixed font width, with double width for the Unicode character.
PS1='\['"`tput sc`"'\] \['"`tput rc`"'༇ \] \$ '
At least in the OSX Terminal, Bash 3.2.17(1)-release, this passes cursory [sic] testing.
In the interest of transparency and legibility, I have ignored the requirement to have the prompt's functionality inside a function, and the color coding; this just changes the prompt to the character, space, dollar prompt, space. Adapt to suit your somewhat more complex needs.
#tripleee wins it, posting the final solution here because it's a pain to post code in comments:
CHAR="༇"
my_function="
prompt=\" \\[`tput sc`\\] \\[`tput rc`\\]\\[\$CHAR\\] \"
echo -e \$prompt"
PS1="\$(${my_function}) \$ "
The trick as pointed out in #tripleee's link is the use of the commands tput sc and tput rc which save and then restore the cursor position. The code is effectively saving the cursor position, printing two spaces for width, restoring the cursor position to before the spaces, then printing the special character so that the width of the line is from the two spaces, not the character.
(Not the answer to your problem, but some pointers and general experience related to your issue.)
I see the behaviour you describe about cmd-line editing (Ctrl-R, ... Cntrl-A Ctrl-E ...) all the time, even without unicode chars.
At one work-site, I spent the time to figure out the diff between the terminals interpretation of the TERM setting VS the TERM definition used by the OS (well, stty I suppose).
NOW, when I have this problem, I escape out of my current attempt to edit the line, bring the line up again, and then immediately go to the 'vi' mode, which opens the vi editor. (press just the 'v' char, right?). All the ease of use of a full-fledged session of vi; why go with less ;-)?
Looking again at your problem description, when you say
my_function="
prompt=\" \[\$CHAR\]\"
echo -e \$prompt"
That is just a string definition, right? and I'm assuming your simplifying the problem definition by assuming this is the output of your my_function. It seems very likely in the steps of creating the function definition, calling the function AND using the values returned are a lot of opportunities for shell-quoting to not work the way you want it to.
If you edit your question to include the my_function definition, and its complete use (reducing your function to just what is causing the problem), it may be easier for others to help with this too. Finally, do you use set -vx regularly? It can help show how/wnen/what of variable expansions, you may find something there.
Failing all of those, look at Orielly termcap & terminfo. You may need to look at the man page for your local systems stty and related cmds AND you may do well to look for user groups specific to you Linux system (I'm assuming you use a Linux variant).
I hope this helps.

Whats up with the £ symbol

I'm a bit confused with the '£' symbol in Ruby.
In JRuby if I do :
puts '£40'
in a .rb file I run this, I get
£40
In JRuby IRB I get :
>> pung = 'h40'
=> "h40"
>> pung.gsub!('h', '£')
pung.gsub!('h', '£')
=> "\24340"
The pound symbol is output as \243.
In pure Ruby IRB, I cant even enter the £ symbol.. The cursor jumps to the left three spaces when I hit the £ key!
trying .toutf8 or toutf16 bring up even stranger characters!
Whats going on!??!? Why cant I just output a simple £?
Sometimes this is a problem with the way your console pastes the character. For example, the unicode character sequence may include a character the console uses to do backspace or arrow left. This is probably the issue with the IRB console not receiving your character ok.
For the script, it looks like JRuby's doing what it's supposed to. The issue with the console should probably be reported as a bug, however, since we do want IRB to support entering unicode characters. Pop over to JRuby's bug tracker at http://bugs.jruby.org and provide show a simple session or provide steps to reproduce (which should be easy).
Most likely, the symbol is a Unicode symbol and you are converting it (perhaps unintentionally). If you can't enter the pound sterling symbol, make sure your console supports Unicode.
What do you get when you do £.class ? String? Unicode::String? Perhaps explicitly declaring the character as a Unicode::String or Unicode::Character will give different results.
'\243' is the octal escape sequence for '£'.

Difference between Print and Display

PLT Scheme's documentation says:
The rationale for providing print
is that display and write both
have relatively standard output
conventions, and this standardization
restricts the ways that an environment
can change the behavior of these
procedures. No output conventions
should be assumed for print, so that
environments are free to modify the
actual output generated by print in
any way.
Could somebody please explain what that means for a noob and how is print and display different?
The thing is that programs can expect certain output formats from write and display. In PLT, it is possible to change how they behave, but a little involved to do so. This is intentional, since doing such a change can have dramatic and unexpected result.
OTOH, changing how print behaves is deliberately easy -- just see the current-print documentation. The idea is that print is used for debugging, for presenting code to you in an interactive REPL -- not as a tool that you will rely on for output that needs to be formatted in a specific way. (BTW, see also the "~v" directive for format, printf, etc.)
You are free to override print function. If you want to override standardized functions, for example the write, you must obey to the output standard, otherwise code that use it will possibly break.
About display and write:
The Scheme Programming Language, 3rd edition, pg. 178
(display obj)
(display obj output-port)
returns unspecified
display is similar to write
but prints strings and characters
found within obj directly. Strings
are printed without quotation marks or
slashes, and characters are printed
without #\ notation. For example,
both (display "(a b c)") and
(display '("a b" c)) would print (a b c). Because of this, display should not be used to print objects
that are indended to be read with
read. display is useful primarily for printing messages, with
obj most often being a string.
If you don't want to replace print you might try out SRFI-28 instead:
http://srfi.schemers.org/srfi-28/srfi-28.html
Basically print is meant for debugging ie, showing the data/value without any beautification or formatting, and display is meant for showing the data in your desired format or more beautified format
ex:
print(dataframe)
enter image description here
display(dataframe)
enter image description here

Resources