How do some programs edit whats being displayed on the terminal (to pick a random example, the program 'sl')? I'm thinking of the Linux terminal here, it may happen in other OS's too, I don't know. I've always thought once some text was displayed, it stayed there. How do you change it without redrawing the entire screen?
Depending on the terminal you send control seuqences. Common sequences are for example esc[;H to send the cursor to a specific position (e.g. on Ansi, Xterm, Linux, VT100). However, this will vary with the type or terminal the user has ... curses (in conjunction with the terminfo files) will wrap that information for you.
Many applications make use of the curses library, or some language binding to it.
For rewriting on a single line, such as updating progress information, the special character "carriage return", often specified by the escape sequence "\r", can return the cursor to the start of the current line allowing subsequent output to overwrite what was previously written there.
try this shellscript
#!/bin/bash
i=1
while [ true ]
do
echo -e -n "\r $i"
i=$((i+1))
done
the -n options prevents the newline ... and the \r does the carriage return ... you write again and again into the same line - no scroling or what so ever
If you terminate a line sent to the terminal with a carriage return ('\r') instead of a linefeed ('\n'), it will move the cursor to the beginning of the current line, allowing the program to print more text over top of what it printed before. I use this occasionally for progress messages for long tasks.
If you ever need to do more terminal editing than that, use ncurses or a variant thereof.
There are characters that can be sent to the terminal that move the cursor back. Then text can be overwritten.
There is a list here. Note the "move cursor something" lines.
NCurses is a cross-platform library that lets you draw user interfaces on smart terminals.
Corporal Touchy has answered how this is done at the lowest level. For easier development the curses library gives a higher level of control than simply sending characters to the terminal.
To build on #Corporal Touchy's answer, there are libraries available that will handle some of this functionality for you such as curses/ncurses
I agree with danio, ncurses is the way to go. Here's a good tutorial:
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
Related
I encountered a problem with my terminal where when I paste text, it is prefixed by 00~ and suffixed with 01~.
For example, I will highlight text and push Command-C. I then push Command-V into the terminal and I see those weird characters pop up at the beginning and end of the text.
For example, I can highlight text and paste it into the terminal. I then see 00~text01~.
The text can be from anywhere, even from the Terminal itself. I do not have any copy/paste plugins installed, this is just the normal Copy/Paste. I am using the default Mac Terminal without any modifications.
I did some searching online, apparently the Paste wraps the text in special characters so that certain applications will see that this is pasted text and will handle it properly. However, the terminal is not handling this correctly, and is therefore not removing the weird characters. Apparently this paste mode is called the "Bracketed Paste Mode" http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode
I found another question that gave a solution on how to solve this issue on a linux machine, but after trying that solution I still have that same problem.
Can someone tell me how I can disable bracketed paste mode for the terminal? Or tell me the right way to get rid of these annoying characters?
What happens when text is pasted
Text has made it into the "system" (e.g. X, MacOS/Aqua) copy buffer from somewhere, maybe from the same terminal. The text is not altered here.
The text is pasted into the terminal; that is, "system" sees to that the terminal (e.g. xterm) receives the unaltered character sequence from the copy buffer. The terminal is aware that this is a paste, not keyboard input.
The terminal sends the char sequence in the buffer to the program running in the foreground (a shell, an editor, whatever). To the program the received data is indistinguishable from user input through the keyboard.
Discussion
This transparency (or opaqueness? whatever) is often a good thing much like the Unix paradigm of transparent pipe plumbing in general. But sometimes programs could deal with the data better if they knew it is pasted. For example an editor like vim could switch off auto indent — after all, the code is likely indented already!
Bracketed paste
Enter bracketed paste. For principal reasons the paradigm of transparent data piping cannot be altered; but the data can be decorated with sequences which would ordinarily not appear in terminal input to mark its start and end. If the terminal is so configured — for the xterm the configuration would be to send ESC [ ? 2 0 0 4 h — the pasted data is bracketed with escape sequences: ESC [ 2 0 0 ~ <buffer contents> ESC [ 2 0 1 ~.
The foreground program receives this "decorated" data, and it's up to to the program to handle it. A naive program treats all of it as user input, which is what you see.
A good discussion of bracketed paste can be found in this article.
Remedies
There are two issues in your case: The terminal ends up unexpectedly in bracketed paste mode; and the receiving program — presumably the shell — does not handle it.
One solution is user83536's: Identify the program which leaves the terminal in that state and call it through a wrapper which simply switches bracketed paste mode off again after the program has ended.
The program probably tried to switch bracketed paste mode off but failed. One reason can be that it sends the wrong escape sequence. Try setting the TERMINAL environment variable to the value best describing your terminal.
Try to switch off bracketed paste in the offending application. In vim one would say set t_BE=. That prevents vim from putting the terminal in bracketed paste mode and when it is set in a session, sends the "end bracketed paste mode" to the terminal.
Embrace bracketed paste. It seems to be a good idea. For the bash and other programs using readline one would put set enable-bracketed-paste on. For vim one could follow the suggestions here.
This may not apply directly to your problem, but I found this symptom to probably, in my case, be caused by my editor-of-choice 'mcedit' (Midnight Commander)
To alleviate the bug problem, I added the following function to my .bashrc file:
### vvv 'function mcedit' is a fix-up for the ~0/~1 paste problem
function mcedit() { command mcedit $# ; printf '\e[?2004l' ; }
Then 'source .bashrc'
Now every time I execute 'mcedit', it automatically adds the 'printf "\e[?2004l"' when I close out to reset the "Bracketed Paste Mode"
Works for me, YMMV.
To disable bracketed paste mode in your terminal, run the following command:
printf '\e[?2004l'
To disable bracketed paste globally, on Linux, add this line to ~/.inputrc :
set enable-bracketed-paste 0
To disable only in the current running Xterm (v 372) (running bash shell version 5.1.16 (probably earlier too, but I don't know)):
% bind 'set enable-bracketed-paste 0'
With either of the above two methods, you can re-enable bracketed paste (in the current Xterm) in the obvious way, namely:
% bind 'set enable-bracketed-paste 1'
i have Vim with plugin vim-go and neocomplete, when o move the cursor from left to right in insert mode this happens
Note: this only happens with go code and vim-go required binaries (such as gocode, godef, goimports, etc..)
someone have same problem?
i am running Ubuntu 14.04.2 LTS 64bits with Kernel 3.13.0-48 Vim 7.4.52 with lua support
thanks in advance
It looks as if you are using gnome-terminal or konsole.
When you use cursor-keys to move around in insert-mode, the keys send escape sequences. In particular, if you happen to press the shift- or control-keys, those can send different escape sequences (with numbers), possibly with semicolons to separate the numbers. There are some limitations on vim's handling strings of that sort, and in some cases (see this discussion) it will get confused and stop interpreting the string, leaving junk on the screen.
The root of the problem is that in vi, the program (mis)uses the escape character for two different reasons:
a special "command" character sent by the user to the editor
the first character in the strings sent by most special keys to an application (including an editor).
The latter requires the program (vim) to wait "a while" to determine which case to use. If you are using a slow machine (or a slow connection) and your keyboard-repeat is fast, that defeats vim's attempt to distinguish the two cases. Likewise, your plugins send many characters to the screen for each keystroke, making vim slower.
It is aggravated by modified keys (using shift- or control-modifiers) since xterm and other terminals encode that information as a number. gnome-terminal and konsole use an older variant of xterm's (see xterm FAQ How can I use shift- or control-modifiers?) which is more easily mistaken by vim as not being an escape sequence.
If it is only a matter of timing, then moving your cursor more slowly would avoid the problem (agreeing that is only a workaround). You can gauge the amount of output done by vim by running it in script to capture the output into a typescript file. I do that to analyze bugs, by sending the data back to the terminal more slowly. Some of those typescript files are surprisingly large, for the little apparent work done.
I changed from neocomplete to YouCompleteMe, the random characters is not showing anymore.
When I call gVim from Stata with shell (or equivalently with !) Stata doesn't wait for the command to finish and continues on with the .do file. I usually specify a short sleep and everything works great (discussed on the Stata mailing list here).
But sometimes the gVim call is lengthy and the length is unknown a priori. For example. I use gVim's argdo to remove headers from a folder of text files.
!gvim -c "argdo 1,3d | update" *sheet*.txt
Is there any way that I can force gVim to not return control to Stata? Or are my best options to complete this step outside the .do file or with a pause/lengthy sleep? Thanks!
Oh, I'm on Win 8 (64 bit) with gVim 7.3.
I think you would need to make this call a Stata command or the equivalent thereof.
That is, try running this separately from a do-file editor window or as wrapped up in a separate do-file.
I realise that is not an attractive solution, but in principle it seems the only one.
(sleep solutions I dislike as fudges, but I guess no one likes them on principle.)
This may be an odd question, but still. I use cat to display a file in bash (KDE Konsole),
cat foobar.rb
Now, I would like to use Vim to colourize that foobar.rb file according to what you would get when you start foobar.rb in Vim. Edit: But only for display purpose, on the terminal.
I am not sure this is possible, but I thought it would be neat if I could use Vim for that.
I really just want colourized keywords, and Vim has the perfect colour definitions.
So I thought combining this would be great.
Is this possible in Vim out of the box though?
One approach would be to use a library such as Pygments, which is a general purpose syntax highlighter. You could write a wrapper called ccat or something that would apply syntax highlighting to an input file and write to stdout.
If you want to page up and down in a highlighted file, you can use less with the -R switch, which passes control characters through to the terminal directly, preserving colours. So:
ccat file.rb | less -R
But at that point, you're pretty much at the capabilities of view.
I'm not sure if I understand your question correctly, but if you are only looking for a command that will give you a read-only view of the input file (like cat) but with coloured keywords, use view. view is an alternative way to start vim in read-only mode, so you have all syntax highlighting possibilities. From the vim man page:
view Start in read-only mode. You will be protected from writing
the files. Can also be done with the "-R" argument.
gvim gview
The GUI version. Starts a new window. Can also be done with
the "-g" argument.
evim eview
The GUI version in easy mode. Starts a new window. Can also
be done with the "-y" argument.
rvim rview rgvim rgview
Like the above, but with restrictions. It will not be possi-
ble to start shell commands, or suspend Vim. Can also be
done with the "-Z" argument.
I have always seen view on systems that have vim installed.
Closest is the less script that comes with vim:
cat myfile | vim -u /usr/share/vim/vim72/macros/less.vim -
Note the - argument to vim. You may need to change the vim72 to your version (and the whole path if you have it installed elsewhere)
Now, this isn't exactly what you want, because its behaviour is less-like, in that you have to press keys to make it scroll down or complete. However, they are briefer than usual vim. For example, space to scroll down; and q to quit (not :q).
You want a cat-like version; me too. But there doesn't seem to be one.
EDIT uh, there's also a vimpager project, that includes vimcat - exactly what you want. But it doesn't come with vim, and I haven't tried it yet.
vim.org: http://www.vim.org/scripts/script.php?script_id=1723
github: https://github.com/rkitover/vimpager
If I do something like:
$ cat /bin/ls
into my terminal, I understand why I see a bunch of binary data, representing the ls executable. But afterwards, when I get my prompt back, my own keystrokes look crazy. I type "a" and I get a weird diagonal line. I type "b" and I get a degree symbol.
Why does this happen?
Because somewhere in your binary data were some control sequences that your terminal interpreted as requests to, for example, change the character set used to draw. You can restore everything to normal like so:
reset
Just do a copy-paste:
echo -e '\017'
to your bash and characters will return to normal. If you don't run bash, try the following keystrokes:
<Ctrl-V><Ctrl-O><Enter>
and hopefully your terminal's status will return to normal when it complains that it can't find either a <Ctrl-V><Ctrl-O> or a <Ctrl-O> command to run.
<Ctrl-N>, or character 14 —when sent to your terminal— orders to switch to a special graphics mode, where letters and numbers are replaced with symbols. <Ctrl-O>, or character 15, restores things back to normal.
The terminal will try to interpret the binary data thrown at it as control codes, and garble itself up in the process, so you need to sanitize your tty.
Run:
stty sane
And things should be back to normal. Even if the command looks garbled as you type it, the actual characters are being stored correctly, and when you press return the command will be invoked.
You can find more information about the stty command here.
You're getting some control characters piped into the shell that are telling the shell to alter its behavior and print things differently.
VT100 is pretty much the standard command set used for terminal windows, but there are a lot of extensions. Some control character set used, keyboard mapping, etc.
When you send a lot of binary characters to such a terminal, a lot of settings change. Some terminals have options to 'clear' the settings back to default, but in general they simply weren't made for binary data.
VT100 and its successors are what allow Linux to print in color text (such as colored ls listings) in a simple terminal program.
-Adam
If you really must dump binary data to your terminal, you'd have much better luck if you pipe it to a pager like less, which will display it in a slightly more readable format. (You may also be interested in strings and od, both can be useful if you're fiddling around with binary files.)