1. Backspace doesn't work in 4.1.0 programs?
- Posted by RobertS May 05, 2022
- 1798 views
It's been a long time since I've been here - all those years, all things I needed always worked well. Sorry if this here has been discussed before - if so, I couldn't find it.
I have recently updated from 4.05 to 4.1.0 (64 bit), and now I find that the Backspace key doesn't work anymore with input from the console using gets(0), and thus also not with prompt_string(). Whether this is by design or a bug, it is seriously annoying as users will not expect this behavior, and may not be able to guess that they can use the left arrow key instead.
Thanks for any help! Robert
2. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by ChrisB (moderator) May 05, 2022
- 1761 views
Hi
Ok, there's a lot of guff in here, and most of it is plagerised from other programs, but this will read every key on the keyboard that you press, and return an integer
global object VOID --eu only --/* include graphics.e -- color names include dll.e include wildcard.e include misc.e include get.e include image.e --*/ without warning global constant EU_VERSION = 3, PLAT = platform() constant COLORS = 1, FGND = 1, BKGND = 2, -- box structure COORDS = 2, ROW = 1, COL = 2, SIZE = 3, HEIGHT = 1, WIDTH = 2, MINH = 4, MINW = 8, STYLE = 4, SHADOW = 5, HINT = 6, HINTCOLORS = 7, BUFFER = 8 global integer SGL, DBL, DHL, DVL, NONE, up, dn, left, right, ENTER, ESC, SP, pgup, pgdn, home, endd, insert, bksp, del, tab, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 global sequence Lines, Divider, Shadow global integer TL, HL, TR, VL, BL, BR global object ENV = "Windows" ESC = 27 global constant KEY_UP = {ESC, 91, 65}, KEY_DOWN = {ESC, 91, 66} tab = '\t' TL = 1 HL = 2 TR = 3 VL = 4 BL = 5 BR = 6 if platform() = LINUX then SGL = 1 DBL = 2 DHL = 3 DVL = 4 NONE = 5 -- border styles --key defines up = 259 dn = 258 left = 260 right = 261 ENTER = 10 ESC = 27 SP = 32 pgup = 339 pgdn = 338 home = 262 endd = 360 insert = 331 bksp = 263 del = 330 F1 = 265 F2 = 266 F3 = 267 F4 = 268 F5 = 269 F6 = 270 F7 = 271 F8 = 272 F9 = 273 F10 = 274 F11 = 275 F12 = 276 --these have been changed from the 'graphic' character set Lines = {{'+','-','+','|','+','+'}, -- single line borders {'+','-','+','|','+','+'}, -- double line borders {'+','-','+','|','+','+'}, -- double horizontal {'+','-','+','|','+','+'}, -- double vertical {' ',' ',' ',' ',' ',' '} } -- none Divider = {{'+','-','+'}, -- single style divider line {'+','-','+'}, {'+','-','+'}, -- double horizontal {'+','-','+'}, {' ',' ',' '}} Shadow = {' ',' ',' '} -- 3 different shadow backgrounds ENV = getenv("TERM") if sequence(ENV) and match(upper(ENV), "XTERM") = -10 then --set to -10 to ignore it for now --xterms seem to work differently - try Windows set Lines = {{218,196,191,179,192,217}, -- single line borders {201,205,187,186,200,188}, -- double line borders {213,205,184,179,212,190}, -- double horizontal {214,196,183,186,211,189}, -- double vertical {' ',' ',' ',' ',' ',' '}} -- none Divider = {{195,196,180}, -- single style divider line {204,205,185}, {198,205,181}, -- double horizontal {199,196,182}, {' ',' ',' '}} Shadow = {176,177,178} -- 3 different shadow backgrounds end if else SGL = 1 DBL = 2 DHL = 3 DVL = 4 NONE = 5 -- border styles --key defines wim32 / dos up = 328 dn = 336 left = 331 right = 333 ENTER = 13 ESC = 27 SP = 32 pgup = 329 pgdn = 337 home = 327 endd = 335 insert = 338 bksp = 8 del = 339 F1 = 315 F12 = 316 F3 = 317 F4 = 318 F5 = 319 F6 = 320 F7 = 321 F8 = 322 F9 = 323 F10 = 324 F11 = 325 F12 = 326 --redefining for windows version up = 1016400 dn = 1016432 left = 1016384 right = 1016416 pgup = 1016320 pgdn = 1016336 --have to work out codes for lines -- Lines = {{'?,'?,'¿','³','?,'?}, -- single line borders -- {'?,'?,'»','º','?,'¼'}, -- double line borders -- {'?,'?,'¸','³','?,'¾'}, -- double horizontal -- {'?,'?,'·','º','?,'½'}, -- double vertical -- {' ',' ',' ',' ',' ',' '}} -- none -- -- Divider = {{'?,'?,'´'}, -- single style divider line -- {'?,'?,'¹'}, -- {'?,'?,'µ'}, -- double horizontal -- {'?,'?,'¶'}, -- {' ',' ',' '}} -- -- Shadow = {'°','±','²'} -- 3 different shadow backgrounds Lines = {{218,196,191,179,192,217}, -- single line borders {201,205,187,186,200,188}, -- double line borders {213,205,184,179,212,190}, -- double horizontal {214,196,183,186,211,189}, -- double vertical {' ',' ',' ',' ',' ',' '}} -- none Divider = {{195,196,180}, -- single style divider line {204,205,185}, {198,205,181}, -- double horizontal {199,196,182}, {' ',' ',' '}} Shadow = {176,177,178} -- 3 different shadow backgrounds end if global atom SCREEN_BKGND SCREEN_BKGND = BLACK global atom LIST_KEY LIST_KEY = 0 global integer LISTBOXINDEX_INITIAL_FLAG --flag to set searching for first letter in list LISTBOXINDEX_INITIAL_FLAG = 0 --doesn't always respond to this --hence flag global integer INSERT_MODE --can set insert mode on and off from outside FDialogs INSERT_MODE = 0 global sequence DefaultBox DefaultBox = {{BRIGHT_WHITE,BLUE}, -- default colors {1,1}, -- coordinates top left corner {5,10}, -- box size SGL, -- single line border 1, -- light shadow "Press any key...", -- hint text {GREEN,BLACK}, -- hint colors {}} -- buffer for save screen --to accomodate usage in xterm or konsole that hasn't been set to 25 lines --if you know it has, then set it to 25, to appear at bottom of screen global integer SCREEN_LINES, SCREEN_COLS SCREEN_LINES = 24 SCREEN_COLS = 80 global sequence vid_conf integer TRUE = 1, FALSE = 0 sequence HIGHLIGHT_COLORS = {BRIGHT_GREEN, BRIGHT_MAGENTA, BRIGHT_WHITE, BRIGHT_BLUE, BRIGHT_CYAN, BRIGHT_RED, YELLOW} sequence LOWLIGHT_COLORS = {GREEN, MAGENTA, WHITE, BLUE, CYAN, RED, BROWN} global integer BKGRND_HIGHLIGHT_SWITCH = 1, WITH_SHADOW = FALSE --sets whether a box should have a shadow or not --------------------------------------------------------------------------------------------------------------------- vid_conf = video_config() SCREEN_LINES = vid_conf[VC_LINES] SCREEN_COLS = vid_conf[VC_COLUMNS] --------------------------------------------------------------------------------------------------------------------- global function resolve_queue(sequence kq) --------------------------------------------------------------------------------------------------------------------- if match(kq, {27,79,70}) then return endd end if if match(kq, {27,79,72}) then return home end if for i = 1 to length(kq) do if kq[1] = ESC then if kq[2] = -1 then return ESC elsif kq[2] = 79 then if kq[3] = 0 then return home elsif kq[3] = 101 then return endd elsif kq[3] = 80 then return F1 elsif kq[3] = 81 then return F1 + 1 elsif kq[3] = 82 then return F1 + 2 elsif kq[3] = 83 then return F1 + 3 end if elsif kq[2] = 91 then if kq[3] >= 65 and kq[3] <= 68 then if kq[3] = 65 then return up elsif kq[3] = 66 then return dn elsif kq[3] = 67 then return right else return left end if elsif kq[3] = 49 then if kq[4] = 126 then return home end if elsif kq[3] = 50 then if kq[4] = 126 then return insert end if elsif kq[3] = 51 then return del elsif kq[3] = 52 then return endd elsif kq[3] = 53 then return pgup elsif kq[3] = 54 then return pgdn else return F1 + kq[3] - 49 end if end if end if end for return -1 end function --------------------------------------------------------------------------------------------------------------------- global function wait_key_nn() --new non ncurses wait_key replacement for eu 3 --returns a single character, like versions previous to eu25t3 --will also return a single character with versions prior to eu25t3 --note lot of scrounging from ed.ex, RDS --------------------------------------------------------------------------------------------------------------------- atom key sequence kq object characters kq = {} --wait for the first key - less computing time! key = wait_key() --pre eu 3.0 compatability if EU_VERSION < 3 or PLAT = WIN32 then return key end if kq = {key} --now get the rest of the keys while 1 do key = get_key() if key = -1 then exit end if kq &= key end while --thats filled the sequence, now process it if length(kq) = 1 then if kq[1] = 127 then kq[1] = bksp end if return kq[1] end if --puts(1, "Key pressed") --for i = 1 to length(kq) do -- printf(1, "%d,", {kq[i]}) --end for key = resolve_queue(kq) return key end function --------------------------------------------------------------------------------------------------------------------- global function get_key_nn(object c) --replaces original get_key function for n0 ncurses eu version --this won't work if there are too many key presses too quickly, better to use a match --------------------------------------------------------------------------------------------------------------------- atom key sequence kq if EU_VERSION < 3 or PLAT = WIN32 then return c end if kq = {c} --the first element --now get the rest of the keys while 1 do key = get_key() if key = -1 then exit end if kq &= key end while --thats filled the sequence, now process it if length(kq) = 1 then if kq[1] = 127 then kq[1] = bksp end if return kq[1] end if --puts(1, "Key pressed") --for i = 1 to length(kq) do -- printf(1, "%d,", {kq[i]}) --end for key = resolve_queue(kq) return key end function integer c /* object k while 1 do k = wait_key() printf(1, ": %d\n", {k}) end while */ while 1 do c = wait_key_nn() printf(1, " - Returned key : %d\n", {c}) end while
It's from a heavily modded dialog.ex, for a menu system, which actually looks quite nice on windows
Cheers
Chris
3. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by ghaberek (admin) May 05, 2022
- 1760 views
It's been a long time since I've been here - all those years, all things I needed always worked well. Sorry if this here has been discussed before - if so, I couldn't find it.
I have recently updated from 4.05 to 4.1.0 (64 bit), and now I find that the Backspace key doesn't work anymore with input from the console using gets(0), and thus also not with prompt_string(). Whether this is by design or a bug, it is seriously annoying as users will not expect this behavior, and may not be able to guess that they can use the left arrow key instead.
Thanks for any help! Robert
It looks like this was fixed somewhere along the way but I'm unable to track down exactly where. I get the same behavior with the 2015-02-02 (57179171dbed) build on Windows, but not Linux.
I've got GitHub running builds when the repo changes (effectively, "nightly" builds) so you can try the binaries available here: https://github.com/OpenEuphoria/euphoria/actions/runs/1884336372
-Greg
4. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by RobertS May 06, 2022
- 1737 views
Chris: Thank you! I'm afraid I don't understand how to use it, though. I need it for reading single lines from the Windows console:
object line
line = prompt_string("? ")
That is, I need a function that returns a string, and that more or less looks like and works like entering something at the console prompt. Insert/delete as the console command line has it would be nice but isn't necessary, but Backspace is essential for fixing typing errors. If I can use the code you've provided as a replacement for prompt_string(), I haven't found how?
Greg: Thank you - but, I'm not familiar with GitHub, and I'm too stupid to figure it out: I do not find the files that I can download?
Robert
5. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by ChrisB (moderator) May 06, 2022
- 1726 views
Hi
Sorry, I should have been more specific - prompt_string() doesn't work because of the windows console in modern windows PC and eu. Annoying I know, I had the same problem on linux, so essentially wrote my own. It does mean you have to keep tighter control over what the screen is displaying though.
add this code onto the end (remove the other entry tests)
--------------------------------------------------------------------------------------------------------------------- global procedure printat(sequence coords, sequence text) --displays text at a position --------------------------------------------------------------------------------------------------------------------- position(coords[1],coords[2]) puts(1,text) end procedure --clear_screen() position(10,1) puts(1, "Enter string : ") sequence str = "" while 1 do printat({10, length("Enter string : ")}, str & " ") position(10, length("Enter string : " & str)) c = wait_key_nn() if c = bksp then if length(str) > 1 then str = str[1..length(str) - 1] end if else str = str & c --note - no checking for valid keys! end if if c = 13 then exit end if end while puts(1, "\n" & str & "\n") --need to do some tidying up, but thats the principle
6. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by ghaberek (admin) May 06, 2022
- 1712 views
Greg: Thank you - but, I'm not familiar with GitHub, and I'm too stupid to figure it out: I do not find the files that I can download?
The Artifacts listed at the bottom of the page include output from that run of the build. Clicking on an artifact will give you a zip file of the contents. Inside the zip file you'll find a new copy of each executable like eui.exe, etc. You can use these in place of the executables you currently have installed. So if you're currently using Euphoria 4.1.0 64-bit on Windows, download the euphoria-4.1.0-WINDOWS-x86_64-d8fb2e2 package and then grab the eui.exe from inside and copy it to your C:\Euphoria\bin directory. (I'd recommend renaming the existing one first in case you want to put it back.)
-Greg
7. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by RobertS May 07, 2022
- 1672 views
Chris: thank you, I'll try that out. But, up to and including 4.05 (I haven't tried 4.06 yet), prompt_string("") has worked well and still does, including Backspace, so, I'm not sure if this really is an unresolvable problem between Euphoria and Windows?
Greg: this is what I had thought, but - I've tried it out with three different browsers now - there is nothing to click in the four "Artifacts" lines. Next to the little cubes are the names and the file sizes, but none of it is clickable, just plain text!?
I can click on "4 jobs completed" or on the "Builds" on the left side of the screen, but they only lead me to a window with missing protocol files, nothing to download.
Thanks for all your help!
Robert
8. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by RobertS May 07, 2022
- 1658 views
I've just discovered something strange:
In this example, Backspace works with gets(0)
object line
line = gets(0)
puts(1, "\n")
puts(1, "input line: " & line)
After I write anything to the screen, Backspace stops working:
object line
puts(1, "anything\n")
line = gets(0)
puts(1, "\n")
puts(1, "input line: " & line)
Also, in the first example puts(1, "\n") creates an extra blank line, but as soon as something got written to the screen and Backspace stops working, \n is needed to start a new line - as it had been until 4.05.
Maybe this can give a hint where the problem may lie?
Still have to try Chris's code! Thanks, Robert
9. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by RobertS May 08, 2022
- 1618 views
- Last edited Jun 07, 2022
I think I've found a solution - thank you, Chris, for pointing me to "position". I hope more testing won't bring some unpleasant surprise, but as far as I've tested it (with Euphoria 4.1 and Windows 10), this seems to work as a Backspace-enabled alternative to prompt_string()
I’ve deleted the code, because it was just a proof of concept, flawed and incomplete. I’ll post a proper version below.
I think it won't be too difficult to add cursor left/right, and insert/delete, but the important thing is that Backspace works.
Thanks again!
Robert
10. Re: Backspace doesn't work in 4.1.0 programs?
- Posted by ChrisB (moderator) May 09, 2022
- 1530 views
You're welcome!
Chris
11. prompt_string() replacement with basic editing functions
- Posted by RobertS Jun 07, 2022
- 1096 views
Here is a prompt_string() replacement with some basic editing functions (I've tested it with Phix 1.0.1):
Left, right, home, and end keys move the cursor
Backspace deletes character left of cursor
Delete deletes character at cursor position
Any character typed is appended or inserted at cursor position
Enter returns input string regardless of cursor position
No line wrap, max length of input string = screen width minus 1 minus length of promt string
include graphics.e global function prompt_string_ed(sequence prompt) object scrn -- for calling video_config() object pos -- for calling get_position object in_string -- input string integer s -- pressed key integer in_c -- cursor position in input string integer pl -- prompt length integer in_max -- input max length integer in_l -- current length of input string integer screen_li -- screen cursor position line scrn = video_config() in_max = scrn[10] - length(prompt) - 1 puts(1, prompt) pl = length(prompt) in_string = "" in_l = 0 in_c = 1 pos = get_position() screen_li = pos[1] while 1 do -- loop exited when return key pressed s = wait_key() if s < 32 then -- ctrl characters if s = 13 then -- return exit elsif s = 8 then -- backspace if in_l > 0 then if in_l = in_c - 1 then in_string = in_string[1..in_l-1] in_l -= 1 in_c -= 1 position (screen_li, in_c + pl) puts(1, " ") position (screen_li, in_c + pl) elsif in_c > 1 then in_string = in_string[1..in_c-2] & in_string[in_c..$] in_l -= 1 in_c -= 1 position (screen_li, in_c + pl) puts(1, in_string[in_c..$] & " ") position (screen_li, in_c + pl) end if end if end if elsif s = 339 then -- delete if in_l > 0 then if in_c < in_l + 1 then in_string = in_string[1..in_c-1] & in_string[in_c+1..$] in_l -= 1 position (screen_li, in_c + pl) puts(1, in_string[in_c..$] & " ") position (screen_li, in_c + pl) end if end if elsif s = 327 then -- home in_c = 1 position (screen_li, in_c + pl) elsif s = 335 then -- end in_c = in_l + 1 position (screen_li, in_c + pl) elsif s = 331 then -- arrow left if in_c > 1 then in_c -= 1 position (screen_li, in_c + pl) end if elsif s = 333 then -- arrow right if in_c < in_l + 1 then in_c += 1 position (screen_li, in_c + pl) end if elsif s < 128 then -- printable characters, change to 256 to allow 8-bit characters if in_l < in_max then -- max length of input string not yet reached if in_l = in_c - 1 then -- cursor at line end puts(1, s) in_string = in_string & s else in_string = in_string[1..in_c-1] & s & in_string[in_c..$] position (screen_li, in_c + pl) puts(1, in_string[in_c..$]) position (screen_li, in_c + pl + 1) end if in_l += 1 in_c += 1 end if end if end while puts(1, "\n") return in_string end function
Comments welcome, should anyone actually be interested in this.
Robert