Writing Text to a Buffer

Let’s now expand OpenMPC to display the entire playlist from mpc. For now, we’ll have the function call mpc to get the playlist and then display that in a new split window. Modify the code to look like this:

plugin.1/mpc/plugin/mpc.vim
Line 1 
function​! OpenMPC()
let​ cmd = ​"mpc --format '%position% %artist% / %album% / %title%' playlist"
let​ playlist = ​split​(system(cmd), ​' '​)
new
for​ track in playlist
if​(playlist[0] == track)
execute ​"normal! I"​ . track
10 
else
call​ append(line(​'$'​), track)
endif
endfor
endfunction

And now let’s quickly go over this before we try it out.

On line 3 we define a List, playlist, to store the result of our mpc call. We assign it the output from that command, split by newlines. Then we open a new window using the :new command, which starts out its new window with a blank file. After that is where things (as they say) start to get interesting.

Once we’ve opened the window, we loop through each track in playlist (in lines 7 through 13). To see whether we’ve started outputting the list, we compare the track we’re on to the first item (on line 8), and if it’s the first item, we make use of a fascinating Vim command: :execute.

The :execute command takes a String and executes it as an Ex command. (If you’re looking to get into metaprogramming in VimL, :execute isn’t a bad place to start.) We’re using :execute to call the :normal command, which itself takes a String of normal mode commands and runs them. By combining :normal and :execute, like we do on line 9, we can script what would’ve been our manual interaction with a Vim buffer. In this case, we run the normal-mode command I, which enters insert mode at the beginning of the line, and then enter the text of the track.

Again, note the bang (!) appended to the :normal command. This is important: when we run a :normal command that the user has remapped, the bang works the same way that it does for a function declaration, and Vim will use the command’s unmapped default. For example, if our user had for some reason set up I to run :q!, :normal! would ignore that odd (if creative mapping) and enter insert mode at the beginning of the current line, as we would expect.

If we’ve already entered the first track, we call the built-in function append to enter the rest. This function appends the text we give it to a buffer after a certain line in the file—it’d be like using the p command in normal mode. It takes two arguments: a line number and a String to append below the line of that number. We’re giving append the line number of the last line in the buffer, using another built-in function, line.

The line function takes a file position and returns the line number of that position in the current file. (For the full list of file positions, see :help line().) We can use this to get the line number of a mark:

 
33G
 
ma
 
:echo line(​"'a"​)​ " → 33

We can get the number of the first (or last) visible line in the file’s window:

 
44G
 
:echo line(​"w0"​)​ " → 16
 
:echo line(​"w$"​)​ " → 44

We can get the line number of the current cursor position:

 
22G
 
:echo line(​"."​)​ " → 22

We can also get the last line in the current file:

 
:​new
 
:echo line(​"$"​)​ " → 1

For each of the remaining tracks in the playlist, we use this to append the text of the track to the buffer, and then our function ends.

One note about how we’re doing this: append can take a String value to append, but it can also take a List. If we give it a List, it will go through that List and append each item in turn. This means that we could’ve set up our function like so:

plugin.1/alternate.vim
 
function​! OpenMPC()
 
let​ cmd = ​"mpc --format '%position% %artist% / %album% / %title%' playlist"
 
let​ playlist = ​split​(system(cmd), ​' '​)
 
 
new
 
call​ append(0, playlist)
 
endfunction

And when we give 0 to append as the line number, it actually prepends the text to the buffer, or puts it before line 1, the first line. Cool, right? There wasn’t really any compelling reason to not write it like this; I just wanted to show you the coolness that is :normal combined with :execute.

So now that we have OpenMPC ready and we’ve seen what the new code is doing, let’s give this the proverbial whirl. Save the plugin file and run our trusty :source command:

 
:​source​ %

Then call the function:

 
:​call​ OpenMPC()

You should see something like what we have in the following figure.

images/PlaylistView01.png

Our plugin is still in its early stages, but we now have a basis to build on as we continue to learn about VimL. We have a function that interacts with the system, opens a new buffer, and runs normal-mode commands to manage that buffer. This is all in a single script file that could have been in our .vimrc, but what we have now is portable; another Vim user could add this functionality to a Vim installation just by dropping the file into the plugin directory.

In the next chapter, you’ll discover the autoload mechanism—the autoload directory is where we’ll be keeping the bulk of our plugin’s functionality. Among other uses, the autoload system helps us keep our plugin code organized. We’ll continue working with the operating system and mpc to make use of our newly displayable playlist.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.94.153