3

I have a file mk.out that contains ANSI codes, which can be cleaned up by opening it in Vim and issuing:

:term cat % " Interpret codes in new buffer
:only       " Close source buffer `mk.out`
:w! mk.out  " Overwrite `mk.out` with cleaned up text

This works fine, but problems arose when I tried to automate this:

vim -c ":term cat %" -c ":only" -c ":w! mk.out" mk.out

I am perplexed by the fact that this results in an empty buffer for cleaned up code and for mk.out. If I remove the command to overwrite mk.out, however, the new buffer ends up still containing the cleaned up text, and I can manually issue the overwrite command.

I also tried overwriting to a different file mk.cln (cln is for clean). In contrast to the above, the new buffer for the clean text doesn't mysteriously become empty (good), but the written file mk.cln is still empty:

vim -c ":term cat %" -c ":only" -c ":w! mk.cln" mk.out

This is regardless of whether the "bang" ! is present in the write command. As expected, mk.out is not disturbed. To rule out problems from prompting to overwrite mk.cln, I ensured that mk.cln did not exist beforehand.

For :term's new buffer, what would cause the :write command to write an empty file when submitted via Vim's -c switch, but not when issued interactively?


Other contextual details

Writing a new file from an existing file works, but the ANSI codes are not cleaned up:

vim -c ":w! mk.cln" mk.out

I realize that I need :wq, but I'm just trying to troubleshoot for now.

Vim version

VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar 30 2020 21:51:17)
Included patches: 1-486
Modified by <cygwin@cygwin.com>
Compiled by <cygwin@cygwin.com>
Huge version with GTK3 GUI.  Features included (+) or not (-):
+acl               -farsi             -mouse_sysmouse    -tag_old_static
+arabic            +file_in_path      +mouse_urxvt       -tag_any_white
+autocmd           +find_in_path      +mouse_xterm       -tcl
+autochdir         +float             +multi_byte        +termguicolors
-autoservername    +folding           +multi_lang        +terminal
+balloon_eval      -footer            -mzscheme          +terminfo
+balloon_eval_term +fork()            +netbeans_intg     +termresponse
+browse            +gettext           +num64             +textobjects
++builtin_terms    -hangul_input      +packages          +textprop
+byte_offset       +iconv             +path_extra        +timers
+channel           +insert_expand     +perl/dyn          +title
+cindent           +job               +persistent_undo   +toolbar
+clientserver      +jumplist          +popupwin          +user_commands
+clipboard         +keymap            +postscript        +vartabs
+cmdline_compl     +lambda            +printer           +vertsplit
+cmdline_hist      +langmap           +profile           +virtualedit
+cmdline_info      +libcall           +python/dyn        +visual
+comments          +linebreak         +python3/dyn       +visualextra
+conceal           +lispindent        +quickfix          +viminfo
+cryptv            +listcmds          +reltime           +vreplace
+cscope            +localmap          +rightleft         +wildignore
+cursorbind        +lua/dyn           +ruby/dyn          +wildmenu
+cursorshape       +menu              +scrollbind        +windows
+dialog_con_gui    +mksession         +signs             +writebackup
+diff              +modify_fname      +smartindent       +X11
+digraphs          +mouse             +sound             -xfontset
+dnd               +mouseshape        +spell             +xim
-ebcdic            +mouse_dec         +startuptime       +xpm
+emacs_tags        -mouse_gpm         +statusline        +xsmp_interact
+eval              -mouse_jsbterm     -sun_workshop      +xterm_clipboard
+ex_extra          +mouse_netterm     +syntax            -xterm_save
+extra_search      +mouse_sgr         +tag_binary        
   system vimrc file: "/etc/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  system gvimrc file: "/etc/gvimrc"
    user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
    system menu file: "$VIMRUNTIME/menu.vim"
  fall-back for $VIM: "/etc"
 f-b for $VIMRUNTIME: "/usr/share/vim/vim82"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK  -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/uuid -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -D_REENTRANT    -ggdb -O2 -pipe -Wall -Werror=format-security -fstack-protector-strong --param=ssp-buffer-size=4 -fdebug-prefix-map=/usr/src/ports/vim/vim-8.2.0486-1.x86_64/build=/usr/src/debug/vim-8.2.0486-1 -fdebug-prefix-map=/usr/src/ports/vim/vim-8.2.0486-1.x86_64/src/vim-8.2.0486=/usr/src/debug/vim-8.2.0486-1 -fstack-protector-strong -D_REENTRANT  -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1       
Linking: gcc   -L. -fstack-protector-strong  -L/usr/local/lib -Wl,--as-needed -o vim.exe   -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl  -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE  -lm    -lncursesw -lcanberra  -liconv -lacl -lattr -lintl   -Wl,--enable-auto-import -Wl,--export-all-symbols -Wl,--enable-auto-image-base -fstack-protector-strong  -L/usr/lib/perl5/5.30/x86_64-cygwin-threads/CORE -lperl -lpthread -ldl -lcrypt        
user2153235
  • 905
  • 5
  • 14

1 Answers1

2

For :term's new buffer, what would cause the :write command to write an empty file when submitted via Vim's -c switch, but not when issued interactively?

You probably need to wait for pending updates. If so, you need term_wait().

Try this shell command:

vim -Nu NONE -i NONE -U NONE +'term cat %' +'call term_wait(bufnr("")) | bw! # | w! mk.out | qa!' mk.out

If it doesn't work, try to increase the waiting time:

vim -Nu NONE -i NONE -U NONE +'term cat %' +'call term_wait(bufnr(""), 100) | bw! # | w! mk.out | qa!' mk.out
                                                                       ^^^
                                                                       wait 100ms instead of 10

See :h term_wait().


If term_wait doesn't work, success has been had in at least the OP's case by replacing call term_wait(bufnr(""), xxx ) with sleep xxx m, where xxx is the wait time in milliseconds (500 worked for the OP). The final command can then be shortened to

`vim -Nu NONE -i NONE -U NONE +':term cat mk.out' +'sleep 500 m | silent! w! mk.out | qa'`.
user2153235
  • 905
  • 5
  • 14
user938271
  • 5,947
  • 1
  • 15
  • 24
  • I tried your 2nd code pattern with 500ms, but everything after physical line 4 is gone in the overwritten mk.out. I experimented with writing to mk.cln: vim -c ":term cat %" -c 'call bufnr("")->term_wait(500)' -c ":only" -c ":w! mk.cln" mk.out. In this case, mk.out contains the full unclean file while mk.cln contains the top 4 lines. Very odd. – user2153235 Sep 08 '20 at 00:50
  • It works for me when mk.out contains this text. – user938271 Sep 08 '20 at 01:00
  • I just saved your test file and tried your 2nd code pattern with 500ms. The resulting mk.out is an empty file.....thanks for your help. I'm going to try messing around to see if I can get an idea of what's going wrong. If I don't figure out within a certain amount of time, I will have to manually intervene in every cleanup. – user2153235 Sep 08 '20 at 01:05
  • I'm not sure why term_wait didn't work, but sleep seemed to have worked: vim +":term cat %" +"sleep 500 m | bw! # | w! mk.out | qa" mk.out. – user2153235 Sep 08 '20 at 01:43
  • Which Vim version are you using? – user938271 Sep 08 '20 at 01:45
  • I added the Vim version to the originally posted question. Since I may lose long output from javac if my sleep is not long enough, I chose to save the cleaned text to a different file than the javac output. My final command is vim +":term cat %" +"sleep 500 m | silent! w! mk.cln | qa" mk.out. My Gvim has a constant window opened on mk.cln, and the silent! is needed to suppress messages about the swap file existing. – user2153235 Sep 08 '20 at 01:54
  • Try to disable all your configuration; you probably don't need it, and it can badly interfere. That's why I included -Nu NONE -i NONE -U NONE in the shell command. – user938271 Sep 08 '20 at 14:05
  • The following yielded a mk.cln that was truncated after 3 lines: vim -Nu NONE -i NONE -U NONE +':term cat %' +'call bufnr("")->term_wait(500) | silent! w! mk.cln | qa' mk.out. The following yielded a mk.cln that contained all of the content, cleaned up: vim -Nu NONE -i NONE -U NONE +':term cat %' +'sleep 500 m | silent! w! mk.cln | qa' mk.out. I have to admit, I knew nothing about vim's terminal functionality before this, so I'm ill-equipped to fathom the likely causes. BTW, what version of Vim are you using? – user2153235 Sep 08 '20 at 15:19
  • I'm using Vim 8.2.1634. I can't help further because I can't reproduce the issue. Just a guess, but maybe the shell or terminal configuration interferes. You can start a bash shell without config with bash --norc --noprofile. Although, just to be sure, I would make a test after temporarily commenting out the whole shell and terminal config. – user938271 Sep 08 '20 at 15:26
  • 1
    In the script containing the Vim command, Bash apparently won't allow both switches simultaneously, so I tried each in succession, with the same result. I fell back to sleep rather than term_wait. The final version "boldly" cuts out mk.cln and so far works with my small mk.out: vim -Nu NONE -i NONE -U NONE +':term cat mk.out' +'sleep 500 m | silent! w! mk.out | qa'. Thanks so much for the investigation that you've done. – user2153235 Sep 08 '20 at 15:35