Martchus / syncthingtray

Tray application and Dolphin/Plasma integration for Syncthing
https://martchus.github.io/syncthingtray/
Other
1.57k stars 43 forks source link

Disable ANSI escape codes automatically in environments which are known to not support it #132

Closed tomasz1986 closed 2 years ago

tomasz1986 commented 2 years ago

Relevant components

Environment and versions

Bug description

Result of running syncthingctl --help:

Syncthing control (Qt 6), version 1.1.17

Command line app to control Syncthing

Available operations:
status, -s
  shows the overall status and/or directory/device specific status
  --stats
    shows overall statistics
  --dir, -d [ID]
    specifies a directory by ID
  --dev [ID/name]
    specifies a device by ID or name
  --all-dirs
    applies the operation for all directories
  --all-devs
    applies the operation for all devices

  example: syncthingctl status # shows all dirs and devs
           syncthingctl status --dir dir1 --dir dir2 --dev dev1 --dev dev2

log, -l
  shows the Syncthing log

stop
  stops Syncthing

restart
  restarts Syncthing

rescan, -r [dir ID] ...
  rescans the specified directories
  example: syncthingctl rescan dir1 dir2 dir4 dir5

rescan-all
  rescans all directories

pause
  pauses the specified directories and devices
  --dir, -d [ID]
    specifies a directory by ID
  --dev [ID/name]
    specifies a device by ID or name
  --all-dirs
    applies the operation for all directories
  --all-devs
    applies the operation for all devices

  example: syncthingctl pause --dir dir1 --dir dir2 --dev dev1 --dev dev2
           syncthingctl pause --all-dirs

resume
  resumes the specified directories and devices
  --dir, -d [ID]
    specifies a directory by ID
  --dev [ID/name]
    specifies a device by ID or name
  --all-dirs
    applies the operation for all directories
  --all-devs
    applies the operation for all devices

  example: syncthingctl resume --dir dir1 --dir dir2 --dev dev1 --dev dev2
           syncthingctl resume --all-devs

wait-for-idle, -w
  waits until the specified dirs/devs are idling
  --dir, -d [ID]
    specifies a directory by ID
  --dev [ID/name]
    specifies a device by ID or name
  --all-dirs
    applies the operation for all directories
  --all-devs
    applies the operation for all devices
  --at-least, -a [number]
    specifies for how many milliseconds Syncthing must idle (prevents exiting too early in case of flaky status)
  --timeout, -t [number]
    specifies how many milliseconds to wait at most

  example: syncthingctl wait-for-idle --timeout 1800000 --at-least 5000 && systemctl poweroff
           syncthingctl wait-for-idle --dir dir1 --dir dir2 --dev dev1 --dev dev2 --at-least 5000

pwd, -p
  operates in the current working directory
  status, -s
    prints the status of the current working directory
  rescan, -r
    rescans the current working directory
  pause, -p
    pauses the current working directory
  resume
    resumes the current working directory

cat
  prints the current Syncthing configuration

edit
  allows editing the Syncthing configuration using an external editor
  --editor [editor name] [editor option] ...
    specifies the editor to be opened
    default environment variable: EDITOR
  --script [path]
    runs the specified UTF-8 encoded ECMAScript on the configuration rather than opening an editor
  --js-lines [line] ...
    runs the specified ECMAScript lines on the configuration rather than opening an editor
  --dry-run
    writes the altered configuration to stdout instead of posting it to Syncthing

Available top-level options:
--config-file, -f [path]
  specifies the Syncthing config file to read API key and URL from, when not explicitly specified
  default environment variable: SYNCTHING_CTL_CONFIG_FILE
  example: syncthingctl status --dir dir1 --config-file ~/.config/syncthing/config.xml

--api-key, -k [key]
  specifies the API key
  default environment variable: SYNCTHING_CTL_API_KEY

--url, -u [URL]
  specifies the Syncthing URL, default is http://localhost:8080
  default environment variable: SYNCTHING_CTL_URL

--credentials, -c [user name] [password]
  specifies user name and password
  example: syncthingctl status --dir dir1 --credentials name supersecret

--cert [path]
  specifies the certificate used by the Syncthing instance
  default environment variable: SYNCTHING_CTL_CERTIFICATE

--no-color
  disables formatted/colorized output
  default environment variable: ENABLE_ESCAPE_CODES

Linked against: C++ Utilities (static): 5.14.0, Connection backend of Syncthing Tray (Qt 6): 1.1.17, Qt Qml: 6.2.4, Qt Core: 6.2.4, Qt Network: 6.2.4, Qt Gui: 6.2.4, Qt Svg: 6.2.4

Project website: https://github.com/Martchus/syncthingtray

Steps to reproduce

  1. Run syncthingctl --help from the default CMD console in Windows.

Expected behavior

The command line output should not contain characters that cannot be printed using the CMD console.

Screenshots

Additional context

Martchus commented 2 years ago

Use --no-color or set ENABLE_ESCAPE_CODES=0 to disable use of ANSI escape codes if they're not supported by your environment. However, I'd generally like to keep them enabled - e.g. they work just fine under Windows when using Mintty/MSYS2. When I remember correctly, it even worked in some new terminal emulator provided by Microsoft.

I consider it a feature request to disable the use of ANSI escape codes by default in environments which are known to not support it.

Martchus commented 2 years ago

Note that syncthingctl will also unconditionally print output as UTF-8 so you also need to set your consoles' code page to UTF-8 when using cmd.exe to avoid broken non-ASCII characters.

tomasz1986 commented 2 years ago

This happens with the console set to UTF-8 though. I've just found that the solution to get rid of the characters is to run it with the --no-color flag.

Martchus commented 2 years ago

Yes, see my first comment which also mentions an env var. The hint about UTF-8 is just in addition because it might be the next problem you might run into.

tomasz1986 commented 2 years ago

Just out of curiosity, are these escape codes only used to colorise the command line output? If yes, then is this the only way to achieve it? I'm asking, because both CMD and PowerShell console themselves are capable of displaying 16 colours, i.e.

image

and I've seen multiple colours used in other CLI programs, e.g. Git or aria2, so it's not like the command line in Windows itself is limited to two colours only.

Martchus commented 2 years ago

If yes, then is this the only way to achieve it?

No, one can use certain WinAPI functions under Windows. However, I'm not going to spend any effort on using them when I can just use a decent terminal. No reason to go the extra mile to cover Microsoft's non-standard ways of doing things.

tomasz1986 commented 2 years ago

I can just use a decent terminal.

Yeah, but please keep in mind that there are many situations, where you can't do that (e.g. when using the software on another person's computer for troubleshooting, or in a restricted office environment, or when you use other software that relies on CMD being the default console, etc.). Another problem is that this is broken in PowerShell as well, and there is no alternative to PowerShell as such.

Martchus commented 2 years ago

Note that I'd generally accept a (well written) PR to improve this. It is just that I'm not going to spend the effort myself as I don't see the use case myself.

tomasz1986 commented 2 years ago

My C-related skills are too minimal to be able to do anything really, so at this point my only request would be limited to at least not display the question marks and such by default there, as they make the output almost unreadable.

To tell the truth, I'm also not really a fan of replacing CMD with 3rd party terminals myself, as in my experience they don't really handle multi-language input well, especially when you need to input Asian scripts (e.g. Chinese characters).

Martchus commented 2 years ago

Looks like there's a registry hack to enable ANSI escape codes under Windows 10: https://stackoverflow.com/questions/16755142/how-to-make-win32-console-recognize-ansi-vt100-escape-sequences

And even better, it would be quite easy to enable ANSI escape codes from the application side: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#example-of-select-anniversary-update-features=

So I'll give it a try.

Martchus commented 2 years ago

This should be fixed by a90e79b78f69d8f2fdf87683b8c645b7271ce4e3.