Vim: Javascript Documentation Search

    I usually work at Kate or Geany. But sometimes, like all people, I want to learn Vim. And each time, about the second minute of the “development”, a completely stupid question arises. For example, why when you press the arrows (or jk keys) does the cursor jump through all the lines of the paragraph at once?


    No matter how I try to formulate my questions, the search each time gives me about the same one hundred sites with headings like “100 most useful Vim commands”. And no matter what site I choose, it will not always miss exactly the “team” that I need right now.


    I thought how to find not a hundred, but generally all the Wim teams. And I found the same page on the network, which was called: "All Vim teams." And there really was a very large list - about six hundred words. But it was not indicated what these commands do - just a list of terms. This joke made me so angry that I finally decided to read the documentation and once and for all make up my own list of “all Vim teams”. Result on the screen. Details below.



    On the official website I was sent to study the documentation on the page vimdoc.sourceforge.net . On this page there are more than a hundred links to different files; the description of the tasks in them often intersects: for example, for me, editing.html, motion.html, insert.html - all this is like one solid “editing”. Some files are not needed at all to find a solution - for example, comparing versions like version5.html . Some are a bit of a tutorial ( usr_NN.html ).


    I chose everything more or less related to "reference", downloaded and decided to somehow organize a search filtering on all the material at once. After processing by sed and gluing, we got a file of 3.5 megabytes in size. The “teams” there turned out to be not 600, but six thousand (with all the pseudonyms and variants - which fit in about four thousand “articles” or “paragraphs”). They managed to find and select everything, because the author of the documentation, Bram Moolenaar, carefully enclosed them all in the tags " a name ".


    It is by this principle that I have divided the entire text of the documentation: one “keyword” (or a group of synonyms) - one segment of text. I wanted to organize “through” filtering so that when searching for an arbitrary word I could see fragments from different documentation files. And still do not lose the standard possibility of documentation - when you click on a term or "tag" jump to the text with the definition (or description) of this term.


    To do this, all the material was placed in one large html-table, and then a search using Javascript was organized in it.


    Everyone knows that such a large table - 4,000 rows, 3.5 megabytes - in the browser will barely toss and turn. But the eyes are afraid, the hands are doing. Javascript in modern browsers is a very fast language. Much more time is spent on displaying text on the screen. Therefore, it is not necessary to show the entire table at once.


    This is the first simple technique that gives the greatest load acceleration for a large page - specify a rule for the table display:none;. An invisible table loads an order of magnitude faster, after which you can slowly create all the necessary indexes. And later, when the user starts the search, we will display only a small part of the table. Sometimes, of course, a large one if you enter only one letter in the search field.


    To beat the user (that is, first of all, himself) from a long wait, we entered two parameters in the filtering script: _Table.tx = 2- we start searching only if the user has entered at least two letters; _Table.vrows = 100- show only the first 100 search results (no more).


    In Vim there are, of course, teams of two letters, and even of one letter. It is almost impossible to filter out the desired text using them, because many ordinary words will be found. So that when searching for the letters of the desired terms do not mix with the "usual letters", we enclose all the "terms" in the stars (more precisely, leave these stars as in the source files). To find, for example, a description of the “B” command (capital Latin B), you must enter the letter directly with asterisks in the search field:



    It is assumed that with the number of results, for example, 200, a reasonable user will continue filtering to reduce the number of rows found, for example, adding letters to the search field of another column. But if you really want to see all 4000 lines found, you can click the checkbox “Show hidden”.


    You can also search for terms and hotkeys using the usual one Ctrl+f- all the keywords are completely displayed on the page in a separate list on the right, almost like the site where "all Wim teams" are. Only on our page for any word you can click and see the detailed text from the documentation. In Ctrl+fthe list on the right, you can also find teams consisting of one letter - there they are also surrounded by asterisks.


    This is the second method of acceleration - the organization of the search in separate lists, and not in the entire solid text - for this we need a table with several columns, and, possibly, a couple of columns outside the table.


    The third trick is not to touch the DOM. Javascript searches are always best done using specially prepared arrays rather than real DOM nodes.


    The fourth technique is “indexing”. We associate a word from the list directly with a specific element of the array by its number. This is something like a primary key . Then, when you click on such a word, you can display the necessary information almost instantly - this is how the list of terms on the right works. We can associate the link with several elements of the array, then the search is also accelerated, because there is no search - the lines associated with the set of elements of the array are just displayed (something like a one-to-many relationship ). This is how the list of "categories" on the left works - it contains the names of the source documentation files: options, editing, motion ... True, the "acceleration" is not very noticeable when you click, for example, the vim.eval link, because in this section there are more than five hundred points (rows of the table), and they are displayed for a long time (if you, of course, check the "Show hidden" box).


    We search for text in Javascript using the function indexOf()- all values ​​in the array are sorted and compared with the letters entered for the search. Usually, to search with this method, all values ​​in the search arrays must be reduced to lower case. But in our case, gg is not the same as GG, so the search is made case-sensitive.


    ***

    There are many links in the documentation in each paragraph. Of course, these links were by no means created by hand, and sometimes quite strange things can be found in files. So, I had to completely remove links to the “motion.as” command - because there were more than a thousand such links in the resulting file (in statements of the form “ same as: map ”). I already decided the trouble had passed; but suddenly I accidentally saw the next set of “noise” links - with the word “do”.


    Then it ceased to seem to me that searching for the “latest” html documentation files was such a good idea. Although Vim isn’t the very last, my documentation doesn’t change every day anyway. Therefore, why not write “wget ...” in the console cp -R /usr/share/vim/vim74/doc ~/Downloads/vim7/source. And you don’t have to go far for the source files.


    In my vim74 / doc folder there were still .rux files - translations into Russian. There are a lot of files, and even with different extensions. And a whole range of files to search became defined slightly differently: not the "select all similar to the reference», and certainly does not remove the reference-: rm -R usr_*; rm -R version*; rm -R todo*.


    The number of “vim commands” or tags in the right list has increased to 9000. More precisely, it has even become “over 9000”. And part of the tags turned out to be associated not with one segment of the text, but with two - English and Russian (if there is a translation). In my opinion, this did not get worse. True, the number of rows in the table has also grown - to "over 8000". But the difference in the speed of the search between the table with 4000 rows and the table with 8000 rows with the naked eye is not noticeable.


    Vim tags

    Looking at the documentation files, I found a “list of Wim commands” in the tags file, but I couldn’t use it in Javascript - I didn’t understand what could be gained. It can be used earlier, when generating html, as the vim2html.pl script in the same folder does, to select keywords and mark them with html a name tags . But for searching on Javascript you don’t need exactly “a name”, any conditional labels are enough (we chose) And you don’t need such a complicated tool as vim2html.pl, you can place tags using ordinary regexps, sed (the code is given at the end of the article).


    Returning to Vim hjkl

    While I slowly sawed Javascript filtering for Vim docks in Kate, I typed this text in Vim at the same time. And the answer to his first question about jk navigation was received only at the very end of work, five days later. In the first approximation found a quick response - in an article right here on Habré: to move the cursor on the screen line, and not a paragraph, it is necessary to change the assignment of the keys via map instructions - in the file ~ / .vimrc: map k gk, map j gj.


    But that was the smallest part of the problem. Big was in ideology. The hjkl keys , used instead of the arrows, are designed to increase the convenience of navigation: no need to take your hand far from the main keys - to the arrows. Well, I moved to the right place in the text, pressed i , typed the letter. And then what? How to move on with these jk? If I press them, they just get printed.


    It is necessary to somehow go back to the "normal" mode - that is, still remove one of the hands from the main keys to the Esc key. Of course, it’s easier to click it than to move to the arrows. But the fact of frequent switching of modes for minor editing is annoying - any profit is lost.


    A wise idea about the «map k gk» suggested the next step: . And it worked perfectly for almost all four directions. Besidesimap gji, when pressed, Vim for some reason stubbornly refused to do anything. A fresh search of the documentation showed that this combination is not used by default anywhere. I went over several options, including all sorts of tricks:


    imap l
    map  li
    

    And in this last one, I suddenly noticed that the keys work somehow every other time. After observing a little more about the behavior of the patient , I found some strange solution that inexplicably turned out to be a worker:

    imap lli
    

    ***

    You can talk for a long time about the intrinsic beauty of Javascript and the intricacies of working with tables table-layout: fixed;, but I’m starting to feel Linus’s reproachful look: “Show me the code already!” Here it is, the code for processing the source documentation files:


    Html table generation code from Vim documentation files
    cd source
    rm -R usr_*
    rm -R version*
    rm -R todo*
    for f in *.txt; 
    do 
    	n=$(echo "$f" | sed -r 's/\.\w+//');
    	perl -pe 's/"$n".html;
    done;
    for f in *.rux; 
    do 
    	n=$(echo "$f" | sed -r 's/\.\w+//');
    	perl -pe 's/"$n"-ru.html;
    done;
    for f in *.html; 
    do 
    	n=$(echo "$f" | sed -r 's/\.\w+//');
    	for ((i=0; i < 3; i++)); do
    		sed -i -r "s:\|([^\t ]+)\|:\1:g; s:(^|\t| )(\*[^\t ]+\*)(\t| |$):\1\2\3:g" "$n".html;
    	done;
    	sed -i "//i<\/pre><\/td><\/tr>vim.$n<\/u><\/td>
    " "$n".html;
    done;
    cat *.html > ../table.htm
    cd ..
    sed -i '/vim:tw=78:ts=8:ft=help:norl/d' table.htm
    cat htm00.htm table.htm endhtm.htm >vim.html
    


    First, we encode in html all opening tags in the text. And at the same time copy the source to files with a different extension. Then we look for all the words with asterisks and wrap them in tags. The difficulty is not to catch occurrences of the form ": autocmd BufRead * / doc / *. Txt set tw = 78" - asterisks without keywords. Due to the difficult condition, the search has to be repeated several times, because part of the contexts intersect. When all keywords are found and marked out, relying on them, you can already divide the future html-table into lines.


    Then the files are glued together into one, it is added !DOCTYPEwith meta tags, 300 lines of js and 40 lines of css, which can be viewed directly inside the final file. Result: Vim docs


    PS While I was finalizing the description, I added something in Javascript: 1) double-clicking the mouse starts the search for the selected word; 2) you can select a few words with the mouse and click to search F2. 3) Ctrl + Left returns to the previous search result (Ctrl + Right - vice versa).


    Also popular now: