Troubleshooting =============== Installation issues ------------------- Android ^^^^^^^ To run on Android, you need access to a CLI environment. I've found that https://termux.com does the trick, but you need to install some extra packages before you can install asciimatics. After installing termux, start up the app and run the following commands: .. code-block:: bash apt update   apt-get install clang python-dev libjpeg-turbo-dev LDFLAGS=-L/system/lib pip install Pillow pip install asciimatics Linux ^^^^^ Although asciimatics is a pure python implementation, it depends on Pillow (a fork of the Python Imaging Library). This package depends on some native libraries that must be installed first. For details of what libraries you need, see `the Pillow documentation `__. For a list of possible solutions, see the `answer on Stackoverflow `__. In short, either install the native libraries you need, or force an installation of an older version (2.9.0) of Pillow. My application only runs on Windows ----------------------------------- Given that your application runs on Windows, but not any curses-based solution (i.e. Mac or Linux), the fundamental logic in your code is right. It might be a bug in asciimatics, but it could also be a bug in your system installation. Curses-based systems date back to an era when people connected to a computer via dumb terminals. Each terminal needed different control character sequences to tell it what to do. These differences are handled by curses, which picks the right definition based on your `TERM` environment variable. If you have the wrong terminal definition, you may find that curses believes some fundamental services are unavailable to your application. In particular, if you use ``xterm-color``, you are using a definition of xterm that dates back to 1996 and will see errors like this, where the critical point is that a curses function returned an unexpected error (the "ERR" result). .. code-block:: bash Traceback (most recent call last): File "demo.py", line 18, in Screen.wrapper(demo) File "./lib/python3.6/site-packages/asciimatics/screen.py", line 1162, in wrapper unicode_aware=unicode_aware) File "./lib/python3.6/site-packages/asciimatics/screen.py", line 1131, in open unicode_aware=unicode_aware) File "./lib/python3.6/site-packages/asciimatics/screen.py", line 2001, in __init__ curses.curs_set(0) _curses.error: curs_set() returned ERR The fix is to use a more modern terminal definition like ``xterm`` or ``xterm-256color``. 256 colours not working ----------------------- By default a lot of terminals will only support 8/16 colours. Windows users are limited to just these options for a native Windows console. However other systems can enable extra colours by picking a terminal that supports the extended colour palettes. For details of which terminals support additional colours and how to enable them see `this Wikipedia article `_. In most cases, simply selecting a terminal type of ``xterm-256color`` will usually do the trick these days. My colours are wrong -------------------- When picking colours you may find that your selection doesn't have the desired effect. This is because terminals have a nasty habit of using different definitions of the standard colours. Asciimatics relies on the ANSI colour set for its standard settings. As you can see `here `__ each terminal has its own interpretation of the exact colour. However, you can usually tweak that in your terminal settings. For example, iTerm on Mac uses a dark grey for black, which you can change as shown below. .. image:: mac_settings.png :alt: Screen shot of iTerm settings The color theme resets when I resize the terminal ------------------------------------------------- There was a bug where asciimatics would not maintain its own colour themes on resize. This has been fixed as of early 2020. You should just upgrade to the latest version to fix this. However, there are also some other applications that change the terminal colour scheme on startup using the terminal's control sequences. These will not be invoked by asciimatics on a resize event. If you use such an application, you will need to invoke the control sequences yourself. For example, to re-apply a `pywal `__ color theme: .. code-block:: python from pathlib import Path from asciimatics.screen import ManagedScreen with ManagedScreen() as screen: # do stuff if screen.has_resized(): wal_sequences = Path.home() / ".cache" / "wal" / "sequences" try: with wal_sequences.open("rb") as fd: contents = fd.read() sys.stdout.buffer.write(contents) except Exception: pass .. _mouse-issues-ref: Mouse support not working ------------------------- Curses systems ^^^^^^^^^^^^^^ Mouse support isn't fully enabled by default on all terminal types. This will often require some extra extensions to be enabled as described `here `__. In addition, if you want 256 colours, you will need to mix modes as described `here `__. Although it is possible to get Linux terminals to report all mouse movement, the reporting of mouse buttons along with movement appears to be highly erratic. The best reporting appears to be using the button event mode - i.e. mixing ``xterm-1002`` with ``xterm-256color``. Windows ^^^^^^^ Asciimatics will reprogram the Windows console to report mouse events on start-up. However, it is possible to change this while the application is running. In particular, if you switch on QuickEdit mode, Windows will stop reporting mouse events and process them itself. It is not possible to have both, so if you want to use the mouse in your app, please switch off QuickEdit mode. Windows title does not change ----------------------------- Much like mouse support, the commands to set the window title is not supported on all terminal types. Windows should work without any changes. Other systems may need to use a similar method as above to mix modes to add status line support as described `here `_. Why can't I detect all key combinations? ---------------------------------------- Asciimatics is designed to run in terminals. These date back decades and so have many restrictions that were perfectly reasonable back then, but seem incomprehensible these days. The biggest one by a long way is that they can't detect exactly what the user types, even though computers have been able to detect exactly which key is being pressed (and when it is released) for a very long time. The fundamental reason for this limitation is that there is no standard for the terminal emulators to tell the application more than a limited set of keys (typically lower and upper case characters, a random smattering of special keys and then some basic control/shift modifiers). While some terminals do try to do a little better, the coverage is patchy and inconsistent. Until this improves the only way to get this sort of information is to run a system-wide keyboard hook, using something the the `keyboard` package on pypi. Unfortunately, this requires that you run as root and will not work on remote terminal sessions (e.g. over an SSH connection). For more details, you can read https://invisible-island.net/ncurses/ncurses.faq.html#modified_keys or https://blog.robertelder.org/detect-keyup-event-linux-terminal/. .. _ctrl-s-issues-ref: Ctrl+S does not work -------------------- In order to maintain legacy support for real terminal systems, most terminals/consoles still support software flow control using Ctrl+S/Ctrl+Q. You can switch this off on Linux by typing ``stty -ixon`` in your shell before you start asciimatics as explained `here `__. Sadly, there is nothing that can be done on Windows to prevent this as it is built in to the operating system, so you will never be able to detect the Ctrl+S key. See `here `__ for details. Backspace or delete are not working ----------------------------------- Some users have reported this on curses systems.  So far this has been tracked down to issues with the terminal configuration.  For an in-depth explanation of the problem and several possible solutions see `here `__ and `here `__. This seems to be particularly problematic for Mac OS X users, where the default terminal app as shipped with the OS doesn't match the terminfo definitions. Genius! If you're on OSX, running the following inside your terminal *should* fix up the mismatch. .. code-block:: bash infocmp "$TERM" | sed -Ee 's/(kbs)=[^,]*/\1=\\177/' -e 's/(kdch1)=[^,]*/\1=\\E[3~/' > "$TERM" tic "$TERM" rm -f "$TERM" In an attempt to minimize the number of affected platforms, asciimatics v1.9.0 and later will also check the OS terminal definitions for ERASE and use that for backspace if it differs from the curses terminal definition. There's a big delay when I press Escape --------------------------------------- This is a well-known default operation for ncurses. As documented `here `__ you need to set the `ESCDELAY` environment variable before opening the Screen so that ncurses uses a shorter delay. I can't run it inside PyCharm or other IDEs ------------------------------------------- Depending on which version you're using, you may see pywintypes.error 6 (ERROR_INVALID_HANDLE), or simply nothing (i.e. it looks like the program has hung). The reason for this is that the IDE Terminal/Console is not a true native terminal/console and so the native interfaces used by asciimatics will not work. There are 2 workarounds. 1. PyCharm, both Professional and Community editions, now offers an option to emulate console output directly in PyCharm. To enable this functionality, see *Run | Edit Configurations | Configuration | Execution | Emulate terminal in output console*. 2. Alternatively, you can just run asciimatics inside a real terminal or window - i.e. not inside PyCharm/the IDE. For example, you can force a real console from the Terminal window using `start cmd /c "python "`. It runs differently/does not work inside PyCharm ------------------------------------------------- While PyCharm's terminal support is constantly improving, it is not perfect and so there are still cases where the imperfections cause glitches in asciimatics applications. This is most common on Windows (e.g. unexpected keys detected on resizing), but it is not just a Windows issue. If you hit such glitches, the first thing to do is check whether you can also see them on a native terminal/console window of your operating system. If you can't reproduce on the native terminal/console, you need to raise the bug with JetBrains. .. _unicode-issues-ref: Unicode characters are not working ---------------------------------- Curses systems ^^^^^^^^^^^^^^ Most modern versions of Linux/OSX come with a good selection of glyphs supported as standard. The most likely issue is that you are not using a UTF-8 locale. To set this up, follow the instructions `here `__ for OSX or `here `__ for Linux. If that doesn't solve the problem and you are seeing unexpected lines in your block drawing characters, you are using a Terminal with extra spacing between your lines. OSX allows you to edit the spacing as explained `here `__, but Linux users will probably need to install a different terminal as explained `here `__. I have found that `rxvt-unicode-256color` is most likely to work. Windows ^^^^^^^ On Windows systems, there are a couple of potential issues. The first is that you might be using the wrong code page. Windows comes with `many `__ code pages. By default, asciimatics will only enable unicode features if you are using code page 65001 (the UTF-8 code page). You can fix this issue by running:: chcp 65001 If this does not solve the issue, the next possibility is that you may be using the Lucida Console or Consolas fonts. These do not have a full enough range of glyphs to support all the unicode output that asciimatics can generate. To fix this issue, you need to download a font with a wider range of glyphs and then install them as the default for your command prompt. Details of how to do that are available `here `__. I recommend that you use the `DejaVu Mono font `__, which you can extract from the ZIP file from the `download page `__ - it is DejaVuSansMono.ttf in the TTF folder of the ZIP. Redirecting STDIN ----------------- Generally speaking, it is not recommended that you try to do this as it will prevent asciimatics from being able to read the terminal input. However, if you must do this, `this question `__ on StackOverflow should give you some help on how to reconnect terminal input on curses based systems. It's just not working at all ---------------------------- Some people have reported truly strange issues where things simply don't start up at all. Symptoms vary wildly from blank screens to other applications or tests running instead. If you are hitting something like this with versions less than 1.14, check that you haven't created a file called ``test.py`` in your project. This is because the ``future`` package, which asciimatics uses for compatibility with Python 2 and 3, imports the test package. If you happen to have a file called ``test.py`` in your project, this import could pick up your file instead of the built-in package. Shout out to Andrew Penniman for spotting and solving this one! It's too slow! -------------- When people say this, they either mean that asciimatics is using too much CPU, or that it is unresponsive in some scenario. Either way, the solution is to reduce the work being done behind the scenes for your application. At a high-level you have 3 options. 1. Switch off any animations you don't need. 2. Move to a more responsive input loop. 3. Use a faster implementation of the underlying infrastructure. Lets look at these options in more detail... Switch off animations ^^^^^^^^^^^^^^^^^^^^^ The key to this optimization is to understand what you're drawing when. The biggest cost in the mainline loop is the actual re-drawing of all the content to the double-buffers, so asciimatics only does this when it knows something has, or may have, changed. You give hints to asciimatics as you construct your application - for example the rate at which a ``Print`` Effect needs to redraw, or whether you want to minimize CPU usage inside a ``Frame``. It then uses these hints and the current application state to decide whether to draw a new frame into the double-buffer. The first thing to look at is things that are not actually changing. For example if you use the ``Print`` Effect to display a static piece of text (like a ``FigletText`` renderer), the output never changes and so you only need to draw it once. in such cases, you should tell the Effect that it is pointless to refresh by specifying ``speed=0`` on construction. Next you should consider removing unnecessary Effects. This is only really an option for TUI systems. Simply avoid adding other ``Effects`` into your ``Scene`` and keep it down the to the ``Frame`` for your user input. Finally, consider switching off the cursor animation if you really need to minimize CPU usage. You can do this by setting ``reduce_cpu=True`` when constructing your ``Frame``. Input responsiveness ^^^^^^^^^^^^^^^^^^^^ First things first, you should make sure that you're running at least version 1.11. Once you have that installed, you can use the ``allow_int`` option in :py:meth:`.play` to permit mouse and keyboard input to interrupt the normal frame refresh rate. This should prevent users from seeing any delay in refreshes when they press a key. However there is a downside to this option - it will slightly mess up the timings for any animations, so it is only recommended to use it in TUI applications. Use faster infrastructure ^^^^^^^^^^^^^^^^^^^^^^^^^ Asciimatics needs to do a lot of array manipulation in order to provide equivalent features to ncurses. In v1.11, I benchmarked various options and optimized the buffering to use the fastest version. If you haven't already moved to that version (or later), please do that now. From here you have the usual options to speed up such calculations further. 1. Use ``numpy`` - which is a native C package to optimize array calculations 2. Use ``pypy`` - which is an optimized version of the Python language. Right now, asciimatics doesn't support ``numpy``, because I only got marginal gains when I made the prototype for 1.11. However, I got significant improvements from ``pypy`` and so I'd definitely recommend considering this option. For example, running some samples for 20s on my test machine, I got the following results: ==================== =========== julia.py Average CPU ==================== =========== Python 2.7 (1.10) 54.8% Python 2.7 (1.11) 47.8% Pypy 6.0 20.0% ==================== =========== ==================== =========== experimental.py Average CPU ==================== =========== Python 2.7 (1.10) 100.0% Python 2.7 (1.11) 71.4% Pypy 6.0 34.3% ==================== =========== Note that the v1.10 test for experimental.py was actually CPU-bound and so slow it was visibly juddering.