Vim won't accept newline as enter - linux

I have a default installation of vim on linux, on a system with a vt52 terminal emulator and unicode capability.
Everything has been working fine until today when I moved my vt52 terminfo file from the temporary local user directory to the permanent system directory ... at first it seemed fine, but all the sudden, when I try to execute a colon command by pressing enter (either CTRL-J, or the key itself == decimal 10), vim just flashes the screen but doesn't execute the command or leave command entry mode.
However, If I press CTRL-M to get a carriage return character (decimal 13), vim does accept the command.
I tried copying the file back to ~/.terminfo again, but it didn't fix the problem...
I thought this might be either a tty issue or a corrupted vimrc file, so...
first I tried deleting the .viminfo and .vimrc files, and doing a stty sane before starting vim but neither helps. I just noticed that enter doesn't work in insert mode either, but CTRL-M does.
Then I checked from the bash shell, using CTRL-V, that when I press CTRL-M, it shows ^M and when I press CTRL-J, it just enters and shows nothing. So -- to double check -- I did a stty raw and cat - | hexdumpx, and sure enough pressing enter returns only 0x0a, and pressing CTRL-M returns only 0x0d ; so the keyboard driver is returning the proper character in raw mode, and I retested in sane mode which apparently maps both of them to 0x0A.
The termcap file I re-compiled with tic, and copied to both ~/.terminfo/v/vt52u where it worked fine before -- and over to /usr/share/terminfo/v/vt52u.
But I don't see anything in the termcap file which could possibly cause the problem.
vt52u|vt52 with UTF-8:\
:am:eo:rs=\Ee\Eb0\Eco:is=\EE\Ee:\
:nl=^j:sr=\EI:bl=^g:ta=^i:\
:ho=\EH:cr=^m:le=\ED:nd=\EC:do=\EB:up=\EA:ta=^i:nw=^j^m:xn:\
:cm=\EY%+ %+ :it#8:co#75:li#24:\
:sc=\Ej:rc=\Ek:\
:vi=\Ef:ve=\Ee:\
:so=\Eb0\Ec3:se=\Eb0\Eco:mh=\Eb8\Eco:mr=\Ebo\Ec0:me=\Eb0\Eco:\
:cl=\EH\EJ:cb=\Eo:cd=\EJ:ce=\EK:\
:km:kb=^h:
EDIT:
I've isolated the problem by experiment 5 listed below, as being caused by something either in or missing from the above termcap file, or in the tic compiler's conversion of it to terminfo.
So -- what termcap entry is missing or which existing one is causing the problem?
---------------------- Additional experiments as I try to figure it out -------------------
1: doing a :set term in vim reveals term=vt52u .... which is correct. So VIM should be using the above termcap file, but I don't know from where (eg: cached version, or not -- or corrupted.) and :version only reveals +termcap which says vim should be using a tic compiled termcap file which is what I've been trying to give it.
2: I recompiled ncurses-5.9, and re-installed it to make absolutely sure no corrupt files exist. Nothing changed even with: ./configure --prefix=/usr --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --with-build-cc=gcc --with-shared --without-debug --without-profile --without-gpm --without-dlsym --without-sysmouse --enable-sigwinch --enable-hashmap --enable-scroll-hints --build=i686-linux --host=arm-linux-gnueabi --without-pthread --enable-widec --with-fallbacks=vt52u --disable-big-core --enable-termcap --enable-getcap-cache
3: doing a :set termcap shows more keys defined than the termcap file has, which is bad... termcap only defined one key ... and that one should be ^H not ^?, so VIM's value doesn't match, but the other termcap values all match, since ^[ is the same as escape \E in the termcap file. So, I have proof that vim is definitely loading the proper termcap file because t_so 's value is unique to the vt52u. So -- it's not a corrupt termcap.... :( weird.
t_kb <BS> ^? <DecMouse> ^[[
t_kd <Down> ^# <NetMouse> ^[}
t_sr=^[I t_bc=^[D t_le=^[D t_cd=^[J t_ce=^[K t_cl=^[H^[J
t_me=^[b0^[co t_mr=^[b0^[co t_ve=^[e t_vi=^[f t_nd=^[C t_se=^[b0^[c0
t_ZH=^[bo^[c0 t_ZR=^[b0^[co t_so=^b0^[c3 t_cm=^[Y%p1%' '%+%c%p2%' '%+%c
4: Recompiled vim 7.4, to remove all built in terminals, and to insure no corrupt files. Had no effect; did not fix default value of backspace key being wrong.
echo "Please Edit feature.h so that NO_BUILTIN_TERMCAPS is always #defined."
sleep 5
vim /src/feature.h
./configure --prefix=/usr/ --build=i686-linux --host=arm-linux-gnueabi --with-features=big --disable-darwin --disable-selinux --disable-xsmp --disable-xsmp-interact --disable-mzschemeinterp --disable-tclinterp --disable-netbeans --disable-sniff --disable-gui --disable-cscope --disable-workshop --enable-multibyte --disable-gtktest --disable-gpm --disable-sysmouse --disable-xim --enable-pythoninterp=dynamic --without-x --with-tlib=ncursesw vim_cv_toupper_broken="yes" vim_cv_terminfo="yes" vim_cv_tty_group="world" vim_cv_tty_mode="0620" vim_cv_getcwd_broken="yes" vim_cv_stat_ignores_slash="yes" vim_cv_memmove_handles_overlap="yes"
echo "Please Edit src/Makefile such that STRIP=arm-linux-gnueabi-strip"
sleep 5
vim src/Makefile
make
make install
5: In bash, I changed the terminal type to generic "export TERM=VT52" rather than the unicode version, with color support which I compiled with tic. ** THE NEWLINE PROBLEM WENT AWAY WITH THE SACRIFICE OF COLOR COMMANDS, AND OTHER FEATURES OF VT52U ** I need the features, but apparently something about the termcap file I listed above is defective.

This was an ugly bug to track down by trial and error...
Vim appears to require keydown to be defined, and if not defined it assumes a default value of ^# ; for an unknown reason, it then treats the enter key as if it were a key down, rather than newline. ^# is logically the value for character code 0, null; which is the only character that would be found in an empty string in "C" which vim is written in and appears to trigger the issue/feature/bug.
But in any event in the termcap shown in the opening post, the kd symbol is not defined; and that's what is causing the problem.
Within vim, the problem can be solved by setting the termcap keydown variable as the same escape sequence which would normally exit insert mode, and then do letter j (down):
:set t_kd=\Ej
The same default can always be added to the termcap entries, too;
Since this is an input escape sequence and not a terminal output escape sequence, it doesn't conflict with the VT52's "save cursor" escape sequence defined in the termcap; eg: The VT52 will never see it since Linux tty's when in line entry mode do not echo escape sequences that come from the keyboard back to the terminal's output.
If a terminal doesn't have true arrow keys -- defining the arrow keys as escaped versions of vim's h,j,k,and l keys might be a reasonably compatible solution as long as it doesn't conflict with other programs which might want to use those input escape sequences for other things. I don't use emacs and other popular programs which might want those escape sequences for something, so if anyone else knows which (if any) programs would have problems with that solution, a comment would be appropriate.
In ncurses 5.9,there appears to be a bug in the terminfo compiler, so that on many installations (eg: slackware 14), 'tic' will not be able to compile terminfo source files -- but only termcap source files. If you want the termcap source code for an arbitrary terminal, you can run "infocmp -C fooTerminalName > fooTerminalName.tcap" to have the system generate a termcap source file for you that can be edited and recompiled with tic successfully.

Related

Ctrl-p Vim bug - unclear what error message is telling me

prt path <mru>={ files }=<buf> <-> /home/....
Error detected while processing function <SNR>48_NormalPasta:
line 13:
E21: Cannot make changes, 'modifiable' is off
Press ENTER or type command to continue
kind of a strange vim error I get when I try to type the 'p' character using vim & ctrlp, using linux ubuntu here
Let's take that message one line at a time:
Error detected while processing function <SNR>48_NormalPasta:
There is an error in function NormalPasta() in the 48th script that was sourced by Vim.
line 13:
The error is on line 13 of that function.
E21: Cannot make changes, 'modifiable' is off
The function is trying to edit a non-modifiable buffer.
From there, you can do:
:filter 48 scriptnames
or:
$ grep -R NormalPasta ~/.vim/**/*.vim
to find in what script the problematic function is located.
This leads to this plugin, which appears to be OK. The whole situation seems rather strange, though, because the problematic function is supposed to be called from normal mode and I don't think a) that you should be in normal mode at CtrlP's prompt and b) that the CtrlP prompt is supposed to be non-modifiable.
My opinion is that the vim-pasta plugin is OK and thus that there is something fishy going on with CtrlP itself or the way you use it.

Make Vim handle medium-sized text files on windows?

I am trying to open a 200MB text file in gvim on Windows, and it's choking. The vim window opens and just remains blank and unresponsive. My system has 8GB of RAM and the file opens fine in about 2-5 seconds using notepad.
I found this SO post on editing very large text files in vim, and I tried opening the file with plugins turned off:
vim -u "NONE" my200MBfile.text
But that didn't help. Is there anything else I can do to make it work? It seems strange that vim would choke on my machine on what is not really such a large file.
Thanks!
Most likely it's the syntax plugin that makes vim halt. I never have any issues with files of Mbs-Gbs. Unless I accidentally open them with some - not-so-well-behaved - filetypes.
Press ^C while loading/hanging (interrupting plugins)
:syntax off
Does the trick. There are other options with syntax that makes it easier to work with a file without fully 'synchronized' syntax highlighting
I played around with this some more, and I found indeed some of my plugins would make operating on (very) large files very slow. I did this, for fun:
On a large input file (~600Mb):
$ wc input.txt.full
2674568 2674568 608825278 input.txt.full
I launched vim with the following tweaks:
vim -u NONE -n +'se nonu nowrap ul=-1 | syn off' input.txt.full
Note this
-u NONE prevents execution of initialization (user) scripts and plugins
-n disables the writing of swapfiles (extremely important on slow/small disks)
se nonu nowrap ul=-1 disables
line numbering
line wrapping
undo history (setting undolevels to a negative value)
Basically, everything that could take a lot of CPU or memory
syn off to disables syntax highlighing (should only make a difference if syntax highlighting was in effect for the file type)
Now, I wanted to duplicate each line on the line itself (globally: copy line, join with previous):
:g/^/t.|-j
Unfortunately, the file would become too large for available memory (~3Gb)1 so I opted to act on the first 20% (~535,000 lines):
:exec "norm 20%"|1,.g/^/t.|-j
This works in a "jiffy" and without problems. Manual navigation (jumps, scrolling, mode switching, searching etc.) seems to be responsive.
Commandline Benchmark:
$ xxd -c 44 /dev/urandom | head -n 3800000 > input.txt.full
$ wc input.txt.full
3800000 91820644 627000000 input.txt.full
$ time vim -u NONE -n +'se nonu nowrap ul=-1 | syn off' input.txt.full +'exec "norm 10%"|1,.g/^/t.|-j' +wq
real 0m7.778s
user 0m6.680s
sys 0m0.952s
$ wc input.txt.full
3800000 101002757 689940307 input.txt.full
(Note that 689940307 ÷ 627000000 = 110.03 %, so that is exactly right).
This isn't slow in my book. For comparison, the wc invocation itself takes the same amount of time (7.7s).
1 All test performed on tmpfs to avoid cache differences.
The problem is more likely that vim doesn't like lines that long very much.
Try using a tool like json_reformat on the file first...
If you absolutely have to edit the file as-is, try :syntax off and possibly :set nowrap before you :edit the file in question.
Although Vim doesn't have a problem opening files of that size (or bigger), it is mentioned that it has a problem of opening a file with, as is your case, only one line (of that size).
You could try various workarounds, but I would suggest going with the "right tool for the right job" approach, and try EmEditor, a text editor made specifically for editing large files (amongst other things).
Note that this is not Vim bashing, but Vim is an editor for editing source code mostly. An excellent one at that, but like every other tool it has its limitations.

Colorizing the output of :make, :grep, etc., in Vim

When building my application using the :make command in Vim, the output is not colorized. I have configured the makefile to use clang as the C compiler, and when running make outside of Vim or when running :!make, clang's output is colorized. :set makeprg returns makeprg=make, just for reference.
I have the same issue with grep: when running :grep, the output is not colorized; when running :!grep, it is. I have tried using the --color option with :grep, to no avail. :set grepprg returns grepprg=grep -n $* /dev/null.
I've read through VIM Unix commands printed in color and also How to color my vimgrep result patterns. The former seems to have the opposite problem (i.e. :!command output not colorized); the latter doesn't have any alternative to dropping down to the shell, which I don't feel is a "correct" fix for the issue.
The problem is that when Vim runs other commands via :make or :grep, those commands don't get a terminal for their standard output -- in the sense that for them isatty(STDOUT_FILENO) is false -- because Vim is capturing the output on its way to being displayed on the terminal. On the other hand, when you use :!make or :!grep, standard output is just going to the terminal.
Clang by default and grep --color=auto (which is probably how you have it aliased) use the terminalness of stdout to decide whether to colourise their output. This is convenient in that you get colourful output on your terminal but capture just the text when you redirect output to a file -- all without needing to add extra command line options.
So what you want to do is override these commands' usual smarts so that they always colourise their output.
For grep, you can use --color=always when it is run via :grep within Vim:
:set grepprg=grep\ --color=always\ -n\ $*\ /dev/null
and depending on your colour settings and version of grep this will work well enough.
For clang, you can change your Makefile to use clang -fcolor-diagnostics so as to force colourisation or more flexibly add an extra variable to $(CC) that will be overridden when run via :make within Vim:
:set makeprg=make\ EXTRA_CFLAGS=-fcolor-diagnostic
However (at least with clang 3.0 and vim 7.3) you will find that clang's style of colourisation prevents Vim from picking out filenames and line numbers from the diagnostics, so doing this wrecks the advantage of using :make rather than :!make.
You may be able to teach Vim to pick out the filenames etc from the surrounding ANSI escape sequences that do the colourisation by adding more entries to Vim's errorformat option to match the colourised clang-style diagnostics. (And similarly with grepformat if your grep colourisation colours the filenames or linenumbers.)
When you run :grep or :make (as opposed to :!grep or :!make),
the output is not only shown in the terminal,
but also sent to the quick-fix window, from which it is processed.
You can access the quick fix windo using the vim-command :copen.
The quick fix window is essentially a text file that is opened in read-only mode.
Like in any other text file, colors are not supported in the quick fix file.
Instead, they are represented with escape characters like [01;34m.
Therefore, producing colorized output from make (or grep) will
mess up the output as it is shown in the quick-fix window, even if you can get vim to process it,
and send the cursor to the selected error/warning/find message.
The question whether the output is colorized now becomes a little subtle: I suggest that the
terminal output should remain uncolored, but that the quick-fix output should be colorized.
The color scheme in the quick fix window is not defined by any color-indications in the file itself, but in the syntax highlighting
of the quick fix window, defined in the file qf.vim (/usr/share/vim/vim81/syntax/qf.vim on my computer).
The color scheme defined in qf.vim does not add much color to the quick fix window, but the syntax hightlighting
scheme may be extended by creating the file ~/.vim/syntax/after/qf.vim. I use cmake in combination with the
gnu and/or the intel compilers, and get nice-looking results with the following contents for ~/.vim/syntax/after/qf.vim:
syn match qBuilt "Built target *" nextgroup=qTarget
syn match qTarget ".*$" contained
syn match qEnteringLeaving ": \(Entering\|Leaving\) directory *" nextgroup=qdSeparator
syn match qdSeparator "'" nextgroup=qdName contained
syn match qdName "[^']*" contained
syn match qbProgress "\[ *[0-9]*%\]"
syn match qBuild "Building .* object"
syn match qWarn "warning\( *#[0-9]*\|\):"
syn match qError "error\( *#[0-9]*\|\):"
syn match qRemark "remark\( *#[0-9]*\|\):"
hi def link qTarget Constant
hi def link qError Error
hi def link qWarn Error
hi def link qRemark WarningMsg
hi def link qEnteringLeaving Keyword
hi def link qBuild Keyword
hi def link qBuilt Keyword
hi def link qdName Include
hi def link qbProgress Special

Why the -b(binary) option doesn't work in vim?

As vim doc said, I can use the -b option to open a binary file.
-b Binary mode. File I/O will only recognize <NL> to separate
lines. The 'expandtab' option will be reset. The 'textwidth'
option is set to 0. 'modeline' is reset. The 'binary' option
is set. This is done after reading the vimrc/exrc files but
before reading any file in the arglist. See also
|edit-binary|. {not in Vi}
I use this command to open vim:
$ vim --cmd 'set et' -u NONE -b
I type this command to view options:
:set et? bin?
expandtab
binary
The et(expandtab) option wasn't reset. Why?
Thanks for your help!
Well the issue is, simply, that --cmd -c or +cmd arguments are executed after processing the other flags. This makes sense, as it would not effectively do anything otherwise.
:verbose set et?
would tell you exactly that. In case you need a workaround for your particular sample vim +'set binary' (unlikely since et != binary)
You are right on the docs for --cmd. So it comes down to the order in which command line flags are interpreted, which is basically 'undefined'. Although
This is done after reading the vimrc/exrc files but before reading any file in the arglist
could be taken to imply 'before processing other command line arguments'.
Note The '+' commands essentially go with specific files and are (AFAICT) processed in the order in which they appear, even when intermixed with filename arguments.

using the -W option of vim

the -w and -W options of vim have theoretically the following effect:
-w {scriptout} All the characters that you type are recorded in the file
"scriptout", until you exit Vim.
This is useful if you want to create
a script file to be used with "vim -s"
or ":source!". When the "scriptout"
file already exists, new characters
are appended. See also
|complex-repeat|. {scriptout} cannot
start with a digit. {not in Vi}
-W {scriptout} Like -w, but do not append, overwrite an existing file.
{not in Vi}
But when I do this, the {scriptout} file will always begin with a hexadecimal sequence like 80 fd 60 (sometimes it is 80 fd 62).
I am using gvimportable.exe 7.3 from portableapps.com. With the -u NONE switch, it does the same.
What is this “magic number” for? Under Windows with gvim.exe I cannot replay my scriptout until I have removed those three leading bytes…
It seems that this feature, which could be very useful, is poorly documented.
Thank you for your answers.
(This answer is probably fragmented significantly, it took me a while playing around - I wanted to find a solution too because it intrigued me - not just the bounty of 200 :P. It more or less shows my train of thought and experimentation.)
I can now reproduce it with gvim on Linux, which is /usr/bin/vim.gnome -g; running as vim -g does just the same.
Delving into the code: (futile in this case, but fun to do and to learn how to do)
I've looked through the source code and I can now explain it somewhat (but not usefully!); it gets the outfile FILE (src/globals.h:1004) set (src/main.h:2275); this is then written to in src/getchar.h:1501, in the updatescript method which is used by gotchars (line 1215) which is used by vgetorpeek, which is used by vgetc and vpeekc... (no, I don't know where this is going!) then these are used in a number of places.
Anyway, I suppose the key is somewhere in src/gui.c, but I don't know where at the moment! It's also possible that some key sequence is being "sent" (physically or virtually, I don't know), but seeing as the issue is the same across platforms it would seem more likely to be a Vim issue than otherwise.
Interesting situations leading to a probable explanation:
It's also worth while noting that if you automatically quit, gvim -u NONE -w scriptout -c quit (:quit after loading) or gvim -u NONE -w scriptout -c quit (instant :quit, never shows GUI), the file scriptout is left empty.
Additionally, if you open gvim and then close it using the X button, pressing no keys:
0000000: 80fd 6280 fd63 80fd 62 ..b..c..b
If you open gvim, click away, click back and use :q:
0000000: 80fd 6280 fd63 80fd 6280 fd2c 80fd 2e3a ..b..c..b..,...:
0000010: 710d q.
So I think it's the window events are internally translated into something else. 80 fd 62 is the open sequence and 80 fd 63 80 fd 62 is the close sequence.
I've found another way of triggering 80fd as well, which leads me to thing it's some sort of "user has access to the window"; by default with GNOME in Ubuntu, Ctrl+Alt+S does something with the window (can't remember what it's called; slides it all up into the title bar, app inside loses keyboard control etc.). gvim ... (you know the arguments!), i<Ctrl+Alt+S (contracted) Ctrl+Alt+S (expanded) >Esc Z Q produces this for me:
0000000: 80fd 6269 3c80 fd63 80fd 623e 1b5a 51 ..bi<..c..b>.ZQ
Summary: so there we have what I believe is the solution; gVim catches the window messages in some form and - whether it should or shouldn't - puts them in its scriptout. If you think it shouldn't (or would like to know why they're left in or if they're even meant to be or whether you should care at all), ask on the Vim list, I think.
My best guess is that this is a bug in the GUI code of gVim.
Using gVim 7.3, if I run gvim -u NONE -W scriptout then I see the problem, but if I run vim -u NONE -W scriptout then the unwanted bytes are not present.
I also tested Vim 7.2 from the shell in Linux, the version of Vim included in Snow Leopard (7.2), and the GUI and terminal versions of MacVim 7.2 (with mvim -W and /Applications/MacVim/Contents/MacOS/Vim -W, respectively) and they all worked correctly.
Someone has done the hard work for us in the vimgolf project, in particular this well-commented file: https://github.com/igrigorik/vimgolf/blob/master/lib/vimgolf/lib/vimgolf/keylog.rb
0x80 in escape sequence for special two-byte codes. In this case they represent gvim focus events. See here:
# If you use gvim, you'll get an entry in your keylog every time the
# window gains or loses focus. These "keystrokes" should not show and
# should not be counted.
"\xfd\x60" => nil, # 7.2 Focus Gained compat
"\xfd\x61" => nil, # Focus Gained (GVIM) (>7.4.1433)
"\xfd\x62" => nil, # Focus Gained (GVIM)
"\xfd\x63" => nil, # Focus Lost (GVIM)

Resources