jimenezrick/vimerl

indent unusable

avtobiff opened this issue · 23 comments

Hi!

I tried out Vimerl HEAD 4c4d1f0 and found out that indent is unusable.

When opening an erlang source file for edit as soon as any edit action
or closing the file is perfomed vim hangs. It seems to hang when
performing the erlang_indent.erl and its FIFO magic.

The last part of an strace with the vimerl indent on when I opened
the file and just exited (:q)

select(1, [0], NULL, [0], {0, 0}) = 0 (Timeout)
open("/home/avtobiff/.vim/indent/out_fifo.29410", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = ERESTARTSYS (To be restarted)
--- SIGHUP (Hangup) @ 0 (0) ---
--- SIGCONT (Continued) @ 0 (0) ---
sigreturn() = ? (mask now [])
write(1, "\33[?25l\33[1m\33[37m\33[41mError detect"..., 82) = -1 EIO (Input/output error)
write(1, "\33[m\r\r\n\33[33mline 1:", 21) = -1 EIO (Input/output error)
write(1, "\33[m\r\r\n\33[1m\33[37m\33[41mE482: Can't "..., 85) = -1 EIO (Input/output error)
write(1, "\r", 1) = -1 EIO (Input/output error)
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa3de94) = -1 EIO (Input/output error)
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = -1 EIO (Input/output error)
write(1, "\r\n\33[m\33[?1l\33>", 12) = -1 EIO (Input/output error)
write(1, "\33[?25h\33[2J\33[?47l\0338", 18) = -1 EIO (Input/output error)
close(4) = 0
unlink("/home/avtobiff/.vim/swp/socket_server.erl.swp") = 0
exit_group(0) = ?

Here is the relevant part of the strace for the same action when I run
vim -u NONE -U NONE

select(1, [0], NULL, [0], {0, 0}) = 0 (Timeout)
write(1, "\r", 1) = 1
write(1, "\33[?25l", 6) = 6
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(1, "\33[53;1H\33[K\33[53;1H\33[?1l\33>", 24) = 24
write(1, "\33[?25h\33[2J\33[?47l\0338", 18) = 18
close(4) = 0
unlink("/home/avtobiff/src/lab/erlang/.socket_server.erl.swp") = 0
brk(0x8c57000) = 0x8c57000
exit_group(0) = ?

Best,
Per

What version of Vim are you using? Which Linux distribution?

Hi!

On Fri, Feb 10, 2012 at 1:08 PM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

What version of Vim are you using? Which Linux distribution?

Sorry for missing this.

I am using Debian GNU/Linux, Sid (unstable).

Packages:

ii vim 2:7.3.363-1
Vi IMproved - enhanced vi editor

ii erlang 1:15.b-dfsg-2
Concurrent, real-time, distributed functional language

Best,
Per


Reply to this email directly or view it on GitHub:
#19 (comment)

I did a quick test on Mac OS X, Ubuntu 11.04 (Vim 7.3.35) and Arch Linux (Vim 7.3.401) and the latest version seems to work fine on my computers.

I suspect mainly of two things (but could be another issue...):

  • Some config in your vimrc wich cause this troubles
  • A Debian specific patch applied to Vim

So, if you haven't tried yet, use some minimal vimrc and see if the situation improves. A vimrc like this:

filetype plugin indent on
syntax on
set nocompatible
set autoindent

On Fri, Feb 10, 2012 at 3:39 PM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

I did a quick test on Mac OS X, Ubuntu 11.04 (Vim 7.3.35) and Arch Linux (Vim 7.3.401) and the latest version seems to work fine on my computers.

I suspect mainly of two things (but could be another issue...):

  • Some config in your vimrc wich cause this troubles
  • A Debian specific patch applied to Vim

I quickly skimmed through the Debian specific patches and could not
find anything relevant for this bug.

http://anonscm.debian.org/hg/pkg-vim/vim/file/c4a782c70b0a/debian/patches

So, if you haven't tried yet, use some minimal vimrc and see if the situation improves. A vimrc like this:

   filetype plugin indent on
   syntax on
   set nocompatible
   set autoindent

Still hangs.

Per


Reply to this email directly or view it on GitHub:
#19 (comment)

I have this issue on OSX 10.7.3 with MacVim 7.3-64. I used the minimal config above and only loaded pathogen and vimerl; no other plugins are installed. Oddly enough, MacVIm locks up whenever I try to enter insert mode when using the GUI but appears to work fine when I am running it on the console. Note that I have a vim alias which points to the Vim executable inside the MacVIm package. I am not using the version of vim that comes with OSX.

I also checked GVim on Arch Linux, and MacVim on OSX with the GUI and the command line version of Vim that comes by default with OS X 10.6. They work fine :-/ In Linux I use Pathogen, so it should not be the problem.

Well, try these things please to see where can be the problem:

1. Test if the escript that helps Vim with the code indenting fails:

Execute this escript directly with a small code file to see if it fails with some exception:

1.1 Create foo.erl:

foo() ->
    Z = 1 +
        2,
    ok.

1.2 And execute: /path/to/vimerl/indent/erlang_indent.erl -f foo.erl <line>. This command will print one or two numbers that tell Vim how to indent that line. So, this command should output this:

erlang_indent.erl -f foo.erl 1
0
erlang_indent.erl -f foo.erl 2
1
erlang_indent.erl -f foo.erl 3
2 8

2. The next thing is to see if the communication between Vim and this escript fails. Vim uses a pair of named FIFOs to send the source code to the escript and this respond with the indentation level of the line.

2.1 Just open with Vim the previous foo.erl file and don´t do anything else.
2.2 Kill the escript, so locate the (Erlang VM) beam process executing the indenter and kill it.
2.3 In Vim, with the cursor in the first line, presh the o command to enter in INSERT mode in the line below, the line 2.
2.4 Do cat /path/to/vimerl/indent/out_fifo.XXXX where XXXX is the Vim's PID. This will show what Vim sent to the escript, something like this (the line to indent and the code previous to that line):

2
foo() ->

2.5 Now Vim hangs waiting for the answer from the escript (the indentation level), so fake it with echo 1 > /path/to/vimerl/indent/in_fifo.XXXX (one tab of indentation). Now Vim will let you edit the line 2 of foo.erl after indenting it.

So, please try these things to see if something fails. Any question or suggestion is welcome :-)

On Sat, Feb 11, 2012 at 2:35 AM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

I also checked GVim on Arch Linux, and MacVim on OSX with the GUI and the command line version of Vim that comes by default with OS X 10.6. They work fine :-/ In Linux I use Pathogen, so it should not be the problem.

Well, try these things please to see where can be the problem:

1. Test if the escript that helps Vim with the code indenting fails:

Execute this escript directly with a small code file to see if it fails with some exception:

1.1 Create foo.erl:

   foo() ->
       Z = 1 +
           2,
       ok.

1.2 And execute: /path/to/vimerl/indent/erlang_indent.erl -f foo.erl <line>. This command will print one or two numbers that tell Vim how to indent that line. So, this command should output this:

   erlang_indent.erl -f foo.erl 1
   0
   erlang_indent.erl -f foo.erl 2
   1
   erlang_indent.erl -f foo.erl 3
   2 8

I get a difference when running the last command

$ ./erlang_indent.erl -f foo.erl 1
0
$ ./erlang_indent.erl -f foo.erl 2
1
$ ./erlang_indent.erl -f foo.erl 3
2 7

2. The next thing is to see if the communication between Vim and this escript fails. Vim uses a pair of named FIFOs to send the source code to the escript and this respond with the indentation level of the line.

2.1 Just open with Vim the previous foo.erl file and don´t do anything else.
2.2 Kill the escript, so locate the (Erlang VM) beam process executing the indenter and kill it.

I have no escript or beam process.

2.3 In Vim, with the cursor in the first line, presh the o command to enter in INSERT mode in the line below, the line 2.

Vim hangs at this step and does not respond to anything.

2.4 Do cat /path/to/vimerl/indent/out_fifo.XXXX where XXXX is the Vim's PID. This will show what Vim sent to the escript, something like this (the line to indent and the code previous to that line):

   2
   foo() ->

I saw in indent/erlang.vim that the script path is where the named
pipes are created. This path might pose a problem. When packaging
this for Debian the indent files are going into
/usr/share/vim/addons/indent/ (where normal users don't have write
access of course). They are then to be installed either system wide
or by the user by using vim-addon-manager which symlinks in a
system wide directory or in the users $HOME/.vim/ . (I don't know
how Vim handles symlinks like this, does it follow them?)

It might be better to create the named pipes in /tmp and naming
them something like "vimerl_{out,in}_fifo.XXXX"

Per

2.5 Now Vim hangs waiting for the answer from the escript (the indentation level), so fake it with echo 1 > /path/to/vimerl/indent/in_fifo.XXXX (one tab of indentation). Now Vim will let you edit the line 2 of foo.erl after indenting it.

So, please try these things to see if something fails. Any question or suggestion is welcome :-)


Reply to this email directly or view it on GitHub:
#19 (comment)

On Sun, Feb 12, 2012 at 12:51 AM, Per Andersson avtobiff@gmail.com wrote:

On Sat, Feb 11, 2012 at 2:35 AM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

I also checked GVim on Arch Linux, and MacVim on OSX with the GUI and the command line version of Vim that comes by default with OS X 10.6. They work fine :-/ In Linux I use Pathogen, so it should not be the problem.

Well, try these things please to see where can be the problem:

1. Test if the escript that helps Vim with the code indenting fails:

Execute this escript directly with a small code file to see if it fails with some exception:

1.1 Create foo.erl:

   foo() ->
       Z = 1 +
           2,
       ok.

1.2 And execute: /path/to/vimerl/indent/erlang_indent.erl -f foo.erl <line>. This command will print one or two numbers that tell Vim how to indent that line. So, this command should output this:

   erlang_indent.erl -f foo.erl 1
   0
   erlang_indent.erl -f foo.erl 2
   1
   erlang_indent.erl -f foo.erl 3
   2 8

I get a difference when running the last command

   $ ./erlang_indent.erl -f foo.erl 1
   0
   $ ./erlang_indent.erl -f foo.erl 2
   1
   $ ./erlang_indent.erl -f foo.erl 3
   2 7

2. The next thing is to see if the communication between Vim and this escript fails. Vim uses a pair of named FIFOs to send the source code to the escript and this respond with the indentation level of the line.

2.1 Just open with Vim the previous foo.erl file and don´t do anything else.
2.2 Kill the escript, so locate the (Erlang VM) beam process executing the indenter and kill it.

I have no escript or beam process.

2.3 In Vim, with the cursor in the first line, presh the o command to enter in INSERT mode in the line below, the line 2.

Vim hangs at this step and does not respond to anything.

2.4 Do cat /path/to/vimerl/indent/out_fifo.XXXX where XXXX is the Vim's PID. This will show what Vim sent to the escript, something like this (the line to indent and the code previous to that line):

   2
   foo() ->

I saw in indent/erlang.vim that the script path is where the named
pipes are created. This path might pose a problem. When packaging
this for Debian the indent files are going into
/usr/share/vim/addons/indent/ (where normal users don't have write
access of course). They are then to be installed either system wide
or by the user by using vim-addon-manager which symlinks in a
system wide directory or in the users $HOME/.vim/ . (I don't know
how Vim handles symlinks like this, does it follow them?)

It might be better to create the named pipes in /tmp and naming
them something like  "vimerl_{out,in}_fifo.XXXX"

BTW, I hacked indent/erlang.vim to put them there but I still get the
same resulting behaviour: Vim hangs when I start editing or save the
file and no escript or beam process is spawned.

Per

Per

2.5 Now Vim hangs waiting for the answer from the escript (the indentation level), so fake it with echo 1 > /path/to/vimerl/indent/in_fifo.XXXX (one tab of indentation). Now Vim will let you edit the line 2 of foo.erl after indenting it.

So, please try these things to see if something fails. Any question or suggestion is welcome :-)


Reply to this email directly or view it on GitHub:
#19 (comment)

Hi!

Ok, this was a user problem on my side. I had missed
installing the file indent/erlang_indent.erl in the
appropriate place. (I missed putting it in the yaml that
vim-addon-manager uses so it was not put in
$HOME/.vim/indent/ .)

Sorry for the noise.

Per

Don't worry :-)

So, everything works?

About the FIFOs, is it needed to put them in /tmp?

I am still seeing the problem. I followed you instructions and each step worked in isolation. I then spent quite a bit of time experimenting and this is what I have found. When vim is run from the console everything works as expected:

Spartan vimerl/indent ‹master*› » psgrep vim
  501 90424 90423   0  4:30PM ??         0:00.00 cat /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/out_fifo.90307
  501 90307 85064   0  4:30PM ttys002    0:00.35 /usr/local/Cellar/macvim/7.3-64/MacVim.app/Contents/MacOS/Vim erlang_indent.erl
  501 90419     1   0  4:30PM ttys002    0:00.72 /Users/ptoland/.kerl/installs/r15b/erts-5.9/bin/beam.smp -B -- -root /Users/ptoland/.kerl/installs/r15b -progname erl -- -home /Users/ptoland -- -boot start_clean -noshell -run escript start -extra /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/erlang_indent.erl /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/out_fifo.90307 /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/in_fifo.90307

Note pid 90424 is the cat subprocess reading the fifo. Now, the same thing only using the GUI MacVim:

Spartan vimerl/indent ‹master*› » psgrep vim
  501 90444   255   0  4:32PM ??         0:01.29 /usr/local/Cellar/macvim/7.3-64/MacVim.app/Contents/MacOS/MacVim -psn_0_3330861
  501 90446 90444   0  4:32PM ??         0:00.90 /usr/local/Cellar/macvim/7.3-64/MacVim.app/Contents/MacOS/Vim -g -f
  501 90535     1   0  4:33PM ??         0:00.20 /Users/ptoland/.kerl/installs/r15b/erts-5.9/bin/beam.smp -B -- -root /Users/ptoland/.kerl/installs/r15b -progname erl -- -home /Users/ptoland -- -boot start_clean -noshell -run escript start -extra /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/erlang_indent.erl /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/out_fifo.90446 /Users/ptoland/Projects/vimfiles/bundle/vimerl/indent/in_fifo.90446

Note that there is no cat subprocess reading the fifo. In fact, if I cat the fifo manually I get the output expected, so the erlang process hasn't even attempted to read the fifo. Just to be sure I added some debugging code to erlang_indent.erl to write to a file on startup. The file is never written to when it is started via GUI MacVim (everything works via the console). The erlang process is there, and is called in exactly the same way, but it appears to be in limbo. The only difference that jumps out to me is that the erlang process is associated with a tty in the first example (ttys002) but not in the second.

Anyway, this appears to be a fundamentally different issue than what avtobiff had. It looked like the same symptoms initially so I jumped in. Let me know if you want me to open a separate issue for my problem.

Don't worry @toland, keep the discussion here :-)

About the TTY, I would say that it makes sense to have one associated in the CLI Vim and not in the GUI Vim, so I'll let that detail out for the moment.

The thing that the escript can't write a file on startup is bizarre... I have no idea what could be the cause of that...

I'm thinking in these two things but I'm a bit lost in this issue :-/

  • Some kind of problem with the "cat trick" to read a FIFO in OS X 10.7
  • The escript is not correctly started in the GUI Vim because of the underlying shell?¿? Does GUI MacVim uses sh/bash inside to launch commands? Because I use the & to launch the escript as a background task.

Things to try:

  1. Test the "cat trick": create a named pipe with mkfifo, try to read it like in https://github.com/jimenezrick/vimerl/blob/master/indent/erlang_indent.erl#L41, let the Erlang VM hang waiting for text and then fill the FIFO with an echo 123 >FIFO
  2. Start the escript manually:

First, comment the next line, so Vim just creates the pair of named pipes but do not launch the escript: https://github.com/jimenezrick/vimerl/blob/master/indent/erlang.vim#L26

Then, before going to insert mode in Vim, where it will hang, start the escript as:

.../vimerl/indent/erlang_indent.erl .../vimerl/indent/out_fifo.XXX  .../vimerl/indent/in_fifo.XXX

(Note: what Vim considers the in FIFO, the escript considers it the out FIFO)

And see if that makes code indenting work. So that would mean that the problem is launching the escript from MacVim.

On Sun, Feb 12, 2012 at 5:38 PM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

Don't worry :-)

So, everything works?

Yes!

About the FIFOs, is it needed to put them in /tmp?

With Debian's vim-addon-manager there are two ways of installing
vim addons. Either in a user's $HOME/.vim/ or system-wide in
/var/lib/vim/addons/ where normal users don't have write access.

For the system-wide installation it is necessary to put the FIFOs
where the user has write access is ok, say $HOME/.vim/
would also be ok as would /tmp.

Per


Reply to this email directly or view it on GitHub:
#19 (comment)

I personally prefer to keep the FIFOs where they are, as most plugins do with the temporal files they create, seems more clear to me than populate the /tmp.

In the other hand I know that it makes impossible a wide system installation of Vimerl, but I think most peolple will install it in their local .vim.

Maybe I'll add an option to customize the path of the FIFOs, I'll think about it.

On Mon, Feb 13, 2012 at 10:55 PM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

I personally prefer to keep the FIFOs where they are, as most plugins do with the temporal files they create, seems more clear to me than populate the /tmp.

In the other hand I know that it makes impossible a wide system installation of Vimerl, but I think most peolple will install it in their local .vim.

Maybe I'll add an option to customize the path of the FIFOs, I'll think about it.

I can just patch it in the Debian package and you don't need to
think about it. :-)

Per


Reply to this email directly or view it on GitHub:
#19 (comment)

OK, if you don't mind @avtobiff, I prefer that solution you propose :-)

On Mon, Feb 13, 2012 at 11:02 PM, Ricardo Catalinas Jiménez
reply@reply.github.com
wrote:

OK, if you don't mind @avtobiff, I prefer that solution you propose :-)

Sure, I'll patch it in the Debian package.

Per


Reply to this email directly or view it on GitHub:
#19 (comment)

OK, I know roughly what is wrong and how to fix it. Apparently escript/erl is simply not designed to run in a situation where it isn't attached to a PTY or TTY. The run_erl script is typically used to work around this issue when deploying an Erlang application that you want to run as a daemon: http://www.erlang.org/doc/man/run_erl.html

I created a simple shell script to launch erlang_indent.erl using run_erl and then changed erlang.vim to call the shell script. Using this setup indentation worked in MacVim, although there was a noticeable delay when opening the first Erlang buffer. Here is what my script looks like:

#!/bin/bash
DIR=$(cd ${0%/*} && pwd)
exec run_erl -daemon $DIR/ $DIR "exec $DIR/erlang_indent.erl $1 $2"

What do you think?

Mmmm, it adds a complexity I'd like to avoid... :-/

Reading escript man pages I see:

On the third line (or second line depending on the presence of the Emacs directive),
it is possible to give arguments to the  emulator,  such as

%%! -smp enable -sname factorial -mnesia debug verbose

Do you think using -detached could also fix the issue?:

#!/usr/bin/env escript
%%! -detached

By the way, the other two escripts work (syntax check and omni completion)?

Yeah, I wasn't really pleased with the extra level of complexity myself.

So, a cursory test seems to confirm that adding the -detached argument fixes the problem. I think the root of the problem was that escript was trying to open stdin and stdout and hanging when they don't exist. I haven't noticed any problems with the syntax check or omnicomplete, but I don't use omnicomplete much. I will double check both this evening.

OK, please confirm later if the -detach fix works and I'll add it to master branch :-)

I used it all day today and did not have any problems.

Great!