Writing vim scripts to open files in the steam structure

My objective was to write a script that will allow the user to open new files from inside the vim interface. There is a vim command available for normal files. However here I am not talking about normal files, these are files inside the steam structures, that is , inside rooms and containers. The commands that were doing this currently were edit.pike and the edit command from the steam-shell.

Issue opened: https://github.com/societyserver/sTeam/issues/53

As I started working on it one of the issue I faced was that I could not use the code in edit.pike or the edit command in steam-shell because for that I would have had to start a new process and the vim window would have come up as an another new process. Due to these process using the same terminal window there would be an overlap and vim will not be able to function, this was one of the problems with the original implementation of the edit command, which I had solved in the first week of GsoC.

Issue with edit command: https://github.com/societyserver/sTeam/issues/34
Solution: https://github.com/societyserver/sTeam/pull/36

My colleague Ajinkya Wavare had finished his task wherein we could execute pike code from a vim terminal. For this he had modified steam-shell and was passing the pike code as an argument to the call of steam-shell. One advantage of executing pike code this way is that all the steam objects and variables are available to use with the pike code. Basically it is like executing code on debug.pike. I based my solution to the problem on this newly added feature. I was able to pass in pike code to steam-shell, this would start a new process, execute the code and return me the output.

The tasks that I needed to do with the pike code was:

  • Find the required object in the steam server.
  • Get the content of the object.
  • Save the content in a temporary file.
  • Once the file is saved by vim, update the file on the sever and the logs in the vim buffer.

I created a new steam command ‘Open’ and passed the full path of the object as an argument. Given the full path it was easy to find the object on the sever. I was able to fetch the contents and save it in a file. Now I had a big problem. The name of the temporary file was available in the pike script, I needed this name in the vim script to open the file in a new tab. I spend more than a day trying to come up with a solution for this problem. I was able to get the name of the file in the output of the pike script and this output could be read into a vim buffer. However this output had a lot of other content including the result of execution of other pike statements also. I had to use vim search and select tools to get the file name isolated and stored in a vim script variable. Once I achieved this my task was almost done. I used vim command to open this file and the log in a new vim tab.

Result of execution of pike script containing the file name.
Result of execution of pike script containing the file name.

The next step was to get this file to be uploaded to the server and the logs updated. Ideally when a file is opened from the steam-shell using the edit command, there is a piece of code that gets called every one second and performs this tasks, however this couldn’t be used when the file is opened from inside vim as the steam-shell process that gets the file closes before the file is opened in vim. So I couldn’t have a pike script constantly watching the file. The solution I came up with was using auto commands to execute a pike script when the file is saved and update the file on the server and also the logs. This completed my task.

opening from vim
File being opened from inside vim.


file opened from vim
File opened in new tab.

Since I had a day left in the week I took up one more small task. This was due to a problem that arose due to my previous task that is letting users open multiple files for editing. There were too many vim buffers open at a time and it was a trouble closing them as :q used to be executed for each buffer. Therefore I made a used defined command in vim, :Q, that was able to close tabs at a time. :tabclose is a vim command that does the same thing however it cannot close the last tab, this shortcoming was overcome with :Q.

Issue: https://github.com/societyserver/sTeam/issues/62

solution: https://github.com/societyserver/sTeam/pull/65