I'm making a simple ASCII animation, and I need the ability to place the cursor at an arbitrary point in the console screen.
While searching, I found this blog that shows this can be achieved by doing:
(print (str (char 27) "[2J")) ; clear screen
(print (str (char 27) "[;H")) ; move cursor to the top left corner of the screen
, which uses ANSI escape sequences.
The first line works as expected, but unfortunately, I haven't been able to find a console that allows for the second line to move the cursor.
After looking up how ANSI escape sequences work, I wrote up this function to ease it's use:
(defn move-cursor-to [x y]
(print (str (char 27) "[" y ";" x "H")))
But when I run (move-cursor-to 10 10), the output is wrong in every "console" I've tried:
IntelliJ/Cursive's REPL ignores it outright; printing nothing.
IntelliJ's Terminal prints the escape character as a ?, and literally prints the rest (?[10;10H)
The Window's 10 command prompt prints something similar to IntelliJ's Terminal, except the ? it prints is inside a box.
Am I doing something wrong? Is there a way to get this to work in the standard Windows 10 command prompt?
I wrote this to fill in the blanks in the meantime:
(defn move-cursor-to [x y]
(let [r #(apply str (repeat % %2))]
(print (str (r y \newline)
(r x \space)))))
but this is a poor solution. It requires clearing the screen prior to use, which for anything beyond a simple animation is unacceptable.
There is an easier way!
There is a much easier way to do this. Have a look at
the clojure-lanterna library.
This library will allow you to address an arbitrary location on a screen. It can
either use a terminal emulator or it can create a swing based window.
Another advantage of using this library is that it also incorporates support for
a virtual window or virtual screen, which can make your output appear to be
much smoother and reduces potential flicker.
The library also has support for ANSI colour codes and a few other nice
features.
Cursive only implements a limited subset of ANSI commands. In particular, most of the caret movement commands don't work. Feel free to file an issue for this, but fixing it is likely to be low priority since it's quite tricky to do in a REPL output pane.
Related
I'm currently designing a CLI interface for linux, and for various reasons I am not able to use ncurses. I am using exclusively C++ and the Qt framework.
Therefore, in order to have a user-friendly interface, I have to run this getch loop in a separate thread:
https://stackoverflow.com/a/912796/3605689
Which basically means I have to implement all basic functionalities (such as backspace) by myself. I have already implemented command completion and command history(like when you press tab or uparrow/downarrow in linux), but I can't figure out how to implement leftarrow/rightarrow (aka seeking through the typeahead).
Normally, I implement it like this: upon every gech which is not equal to -1, I check whether the user has pressed a special key (one that modifies the typeahead somehow). I then clear the stdout using the following function:
void inputobject::clear_line(int nletters)
{
QTextStream(stdout) << "\033[2K";
for(int i = 0; i < nletters;i++){
QTextStream(stdout) << "\b";
}
rewind(stdout);
}
And replace it with something else, effectively simulating the typeahead. For example, in the case of backspace, I would save the command call clear_line, and print the command out again, just with one less letter, behaving exactly as a normal console application would.
My real problem is with the cursor, in the case of left/rightarrow, I need to move the cursor visual in order to be able to indicate where in the text is the user seeking:
Because of the nature of how I rewrite the given stdout line to simulate the typeahead, it does not really matter where the cursor REALLY is, as long as it stays on the same line - it is just the visual that matters. How can I achieve moving the cursor visual on linux?
The answer was provided in the comment by Evilruff:
Cursor Movement
ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:
Position the Cursor:
\033[;H
Or
\033[L;Cf
puts the cursor at line L and column C.
Move the cursor up N lines:
\033[NA
Move the cursor down N lines:
\033[NB
Move the cursor forward N columns:
\033[NC
Move the cursor backward N columns:
\033[ND
Clear the screen, move to (0,0):
\033[2J
Erase to end of line:
\033[K
Save cursor position:
\033[s
Restore cursor position:
\033[u
Not using ncurses and co is a serious limitation.
It is hell to make correct input/output on shell for displaying anything.
The only others real solutions (I can't think as a solution to reimplement a ncurse-like library) I think of are:
making call to dialog (for some example www.linuxjournal.com/article/2807 and for the doc: http://linux.die.net/man/1/dialog)
using the framebuffer mecanism with Qt4 (here)
I'm very new to using lisp, so I'm sorry if this is a trivial question. I haven't been able to find solutions after a while googling, though I'm sure that this is fault on my part.
So. I'm trying to write a command which will revert all open buffers. Simple. I just do
(setq revert-without-query (buffer-list))
(mapc 'revert-buffer (buffer-list))`
Unfortunately, this ends up failing if there are any buffers which aren't associated with files- which is to say, always.
Doing C-x C-b to list-buffers prints something like
CRM Buffer Size Mode File
init.el 300 Emacs-lisp ~/.spacemacs.d/init.el
%scratch% 30 Test
Ok. Easy enough. If I was allowed to mix lisp and python, I'd do something like
(setq revert-without-query [b for b in buffer-list if b.File != ""])
;; Or would I test for nil? Decisions, decisions...
Upon some digging, I found that there exists remove-if. Unfortunately, being completely new to lisp, I have no idea how to access the list, their attributes, or... well... anything. Mind helping me out?
One possibility would be checking buffer-file-name which will return nil if the buffer isn't visiting a file, eg.
(cl-loop for buf in (buffer-list)
if (buffer-file-name buf)
collect buf)
or
(cl-remove-if-not 'buffer-file-name (buffer-list))
You probably want to revert dired directories also. Any type of buffer can have its own specialized revert (see revert-buffer-function). So you probably want to check for both buffer-file-name and dired-directory being non-nil.
(dolist (b (buffer-list))
(when (buffer-live-p b)
(with-current-buffer b
(when (or buffer-file-name dired-directory)
(revert-buffer 'ignore-auto 'noconfirm)))))
You can also use the ignore-errors hammer, but you're probably better off fixing corner cases as you encounter them.
I am new to Emacs functions. Today is my first attempt to create a function.
I know that count-matches will tell me how many times a regex appears in the rest of the buffer, but most of the time I need to count from the beginning of the buffer. So I tried this:
(defun count-matches-for-whole-buffer (text-to-count)
"Opens the ~/.emacs.d/init.el file"
(interactive "sText-to-count:")
(beginning-of-buffer)
(count-matches text-to-count))
I put this in ~/.emacs.d/init.el and then do "eval-buffer" on that buffer.
So now I have access to this function. And if I run it, it will ask me for text to search for.
But the function only gets as far as this line:
beginning-of-buffer
I never get the count. Why is that?
Two things.
You should use (goto-char (point-min)) instead of beginning-of-buffer.
count-matches will not display messages when called from lisp code unless you provide a parameter indicating so.
Try this code:
(defun count-matches-for-whole-buffer (text-to-count)
(interactive "sText-to-count:")
(count-matches text-to-count (point-min) (point-max) t))
I'm currently designing a CLI interface for linux, and for various reasons I am not able to use ncurses. I am using exclusively C++ and the Qt framework.
Therefore, in order to have a user-friendly interface, I have to run this getch loop in a separate thread:
https://stackoverflow.com/a/912796/3605689
Which basically means I have to implement all basic functionalities (such as backspace) by myself. I have already implemented command completion and command history(like when you press tab or uparrow/downarrow in linux), but I can't figure out how to implement leftarrow/rightarrow (aka seeking through the typeahead).
Normally, I implement it like this: upon every gech which is not equal to -1, I check whether the user has pressed a special key (one that modifies the typeahead somehow). I then clear the stdout using the following function:
void inputobject::clear_line(int nletters)
{
QTextStream(stdout) << "\033[2K";
for(int i = 0; i < nletters;i++){
QTextStream(stdout) << "\b";
}
rewind(stdout);
}
And replace it with something else, effectively simulating the typeahead. For example, in the case of backspace, I would save the command call clear_line, and print the command out again, just with one less letter, behaving exactly as a normal console application would.
My real problem is with the cursor, in the case of left/rightarrow, I need to move the cursor visual in order to be able to indicate where in the text is the user seeking:
Because of the nature of how I rewrite the given stdout line to simulate the typeahead, it does not really matter where the cursor REALLY is, as long as it stays on the same line - it is just the visual that matters. How can I achieve moving the cursor visual on linux?
The answer was provided in the comment by Evilruff:
Cursor Movement
ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:
Position the Cursor:
\033[;H
Or
\033[L;Cf
puts the cursor at line L and column C.
Move the cursor up N lines:
\033[NA
Move the cursor down N lines:
\033[NB
Move the cursor forward N columns:
\033[NC
Move the cursor backward N columns:
\033[ND
Clear the screen, move to (0,0):
\033[2J
Erase to end of line:
\033[K
Save cursor position:
\033[s
Restore cursor position:
\033[u
Not using ncurses and co is a serious limitation.
It is hell to make correct input/output on shell for displaying anything.
The only others real solutions (I can't think as a solution to reimplement a ncurse-like library) I think of are:
making call to dialog (for some example www.linuxjournal.com/article/2807 and for the doc: http://linux.die.net/man/1/dialog)
using the framebuffer mecanism with Qt4 (here)
How can I auto-format C++ code in emacs following GNU-style?
There's this auto-newlines thing: https://www.gnu.org/software/emacs/manual/html_node/ccmode/Auto_002dnewlines.html, but even when I set style to GNU it doesn't put the return value on a separate line from the function name.
I also want something that adds spaces between arguments in an argument-list. And something I can "run" on code after I've written (not just moves things around as I type)
Already been answered here. There's a tool called astyle (Artistic Style) that formats the code in C++.
(defun astyle-this-buffer (pmin pmax)
(interactive "r")
(shell-command-on-region pmin pmax
"astyle" ;; add options here...
(current-buffer) t
(get-buffer-create "*Astyle Errors*") t))