[go: nahoru, domu]

Skip to content

jjaderberg/vim-ft-asciidoc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Vim AsciiDoc file type plugin

Installation

I recommend using git and Tim Pope’s pathogen plugin:

cd ~/.vim/bundle && \
git clone git://github.com/jjaderberg/vim-ft-asciidoc.git

If you are concerned about having your configuration overridden by a plugin, I salute you and please see Appendix A.

Features

  • Bindings for common editing operations

    • One sentence per line

    • Insert blocks (code, quote, NOTE, etc.)

    • Format text (words and chars)

    • Change/delete/yank document sections.

    • Insert macros (kbd, image, include, etc.)

    • Insert cross references

    • Toggle title (ATX/SetExt style)

    • Support for working with tables and lists

  • Set 'makeprg' for easy compiling (with asciidoctor, minimal support for parameters through buffer local variables.)

  • Support compile on save

  • Basic folding support

  • Navigation

    • Follow cross references

    • Follow external links

  • Set basic options, like the correct 'commentstring'.

  • Experimental

    • Block formatting by motions

    • Text objects for blocks and list items

    • Delete or change block delimiters (surroundings)

Failures

  1. Incomplete help. A first iteration is there, but plenty of work before it’s up to snuff.

  2. Bias.

    1. I use the Asciidoctor processor and abide by a company style guide. This informs how the plugin works.

    2. I mostly use a Mac with Vim 7.4.903 and Firefox. I have not really tested the plugin with other systems.

    3. Some things are hard coded in the plugin that shouldn’t be.

    4. Bloat. The plugin does too much and not enough. The compile stuff should be in a compiler plugin, for example, but then I would have to define error format for consumption in quick list, and…​

I’d like to see these things improved, but I don’t know when (if) I’ll have time.

Editing

Editing support includes:

  • Turn a paragraph into one-sentence-per-line.

  • Insert different kinds of paragraphs (blocks).

  • Format text.

  • Insert and edit tables.

  • Operate on sections.

  • Insert macros and cross references.

Important

All maps defined in the plugin begin with <LocalLeader>. Showing the full maps below would be cumbersome and unhelpful: <LocalLeader>te. I use , for local leader, therefore all the maps below lead with ,. Whatever you have assigned to <LocalLeader> is what you would use as the first key of each map.

Sentence per line

You have a paragraph of text. It contains multiple sentences. Are they written
on the same line? Do they contain arbitrary line breaks? Do you wish there were
a convenient way to Zenify the paragraph? You know, so that you get the benefits
of easy diffing, efficient editing, and the bonus safeguard: very long sentences
stick out like a sore thumb?

If you abide by the Zen of "one sentence per line", position the cursor anywhere in the paragraph and type ,spl.

You have a paragraph of text.
It contains multiple sentences.
Are they written on the same line?
Do they contain arbitrary line breaks?
Do you wish there were a convenient way to Zenify the paragraph?
You know, so that you get the benefits of easy diffing, efficient editing, and the bonus safeguard: very long sentences stick out like a sore thumb?

The operation will recognize some paragraph boundaries: empty line or line beginning with two or more of -_.*+=. It therefore usually works just fine to do this on a formatted block.

The operation may fail to recognize the boundaries of some paragraph, or you may want to format part of a paragraph. In this case, visually select the lines to format and the operation will limit itself to these lines.

Blocks

Work with different kinds of paragraphs/blocks. Insert a new code block, or turn a sentence or paragraph into a quote or admonition.

Insert paragraphs/blocks

Let’s say I write documentation and want to provide a "before" and "after" example. For this I may use two literal blocks, containing the "before" and "after" text. In insert mode I type ,literal. This gives me a literal block:

....
[]
....

[] signifies the location of the cursor.

Most editing operations have maps defined for normal, insert or visual mode. These use the same left hand side. If I have some text already present in a paragraph, I can insert that text into a block using the same keys. Take a paragraph like

Paragraph.
Short but sweet.
Indeed.

If I visually select this paragraph, for instance with vip, and then type ,literal, I get

....
Paragraph.
Short but sweet.
Indeed.
....

To comment out the visually selected block, I type ,comment.

////
Paragraph.
Short but sweet.
Indeed.
////

For blocks, the normal mode maps generally operate on the cursor line. If instead of selecting the paragraph I rest the cursor on the middle line, ,example gives

Paragraph.
====
Short but sweet.
====
Indeed.

Admonitions

Similar to code and example blocks, admonitions can be created from normal, insert and visual modes. Typing ,note in insert mode will give:

[NOTE]
--

--

With a visual selection, the selected text will be inside the block.

Note

I use open blocks for admonitions. To use a different block type you will have to fork and change the code. It would be desirable to let the block type be controlled by an option or parameter. If you decide to implement this, please consider sharing your improvements by submitting a PR.

Table 1. Maps for block editing

admonitions (NOTE, etc.)

,caution, ,important, ,note, ,tip, ,warning

comment

,comment

example

,example

listing (code)

,code

literal

,literal

passthrough

,passthrough

quote

,quote

sidebar

,sidebar

source

,source

verse

,verse

Each of these operations have maps with the same left hand side for normal, insert and visual modes.

Typing ,passthrough looks like about the same amount of work as making the corresponding edit manually. However, for all their verbosity, I find these maps tremendously helpful. I do think shorter lhs is desirable—​I just haven’t come up with the right convention yet.

Sugar

Some operations have added sugar. For example, typing ,quote to get a quote block will add the quote attribute, along with placeholder author and source. The author and source will be visually selected, and can easily be edited or removed with normal Vim commands.

[quote, author, source]
____
Parvus error in principio magnus est in fine.
____

Format text

Inline text formatting can be achieved for all the quote or format styles.

To emphasize a word, rest the cursor on it and type ,te.

To mark part of a word as strong, visually select that part and type ,ts.

To ma**rk** p**ar**t of a **wor**d as *strong*, **visu**ally select **tha**t part and type kbd:[,ts].

If the visual selection is over the entire word, the single format character is added. If the visual selection is over part of a word, the double format character is added. The same maps handle both of these notations.

In addition to the ordinary text formatting operations there are maps for strike out, and for "empty" attributes:

Strike me out and give me an attribute!

Select the first three words and press ,t-, then select the last four words and type ,ta.

[line-through]#Strike me out# and []#give me an attribute#!

When adding an empty attribute, the operation leaves the cursor in insert mode between the brackets.

Table 2. Maps for text formatting

code

,tc

emphasis

,te

passthrough

,tp

strong

,ts

subscript

,tj

superscript

,tk

strike-out

,t-

attribute

,ta

Tip

Mnemonic: text emphasis, etc. For subscript and superscript the memory devise is j for down and k for up. For strike-out, it’s a dash.

Tables

The plugin includes some table support:

  • Insert tables (or insert text into tables).

  • Operate on tables as text objects ,it ,at.

  • Add attributes to existing table.

Insert table

Similar to blocks, tables can be inserted with ,table. In insert mode this gives:

Insert mode
|===
|
|===

For normal and visual modes also, behaviour is similar to block editing.

Before
Paragraph.
Short but sweet.
Indeed.

In normal mode, the table will contain the cursor line. If necessary, a blank line is added above and below.

After, normal mode
Paragraph.

|===
| Short but sweet.
|===

Indeed.

For visual selections, the lines will be put into the table. Newline padding is added above and below, as needed. Selecting the two first lines in before and typing ,table will result in:

After, visual mode
|===
| Paragraph.
| Short but sweet.
|===

Indeed.

Text objects

There are two table text objects: ,it and ,at. To visually select "inner table", that is, the lines within the table, use v,it. To delete "a table", use d,at.

Attributes

There are also two shorthands for adding the attributes options="" and cols="". With the cursor inside the table, ,cols adds the latter and ,opts the former.

Motions

The cursor motions ]] and [[ move forward and backward to section titles. These motions can be used with all the ordinary Vim operators, allowing them to operate over document sections.

Table 3. Examples of operations over sections

c][

Change from cursor to end of section.

d2][

Delete from cursor to end of section and the following section.

y[[

Yank from cursor to beginning of section.

[]d[[

Delete the previous section.

[[v][

Visually select the whole current section.

]]g?][

ROT13-encode the section following the current section.

Macros

There is some support for inserting macros. Operations with macros are handled in two by two ways. A macro is either inserted as a block, or an inline macro. Additionally, input to the operation (if there is any) is treated as either macro attributes or macro target. Consider:

Look at images/image.img it is beautiful!

To turn the file path above into an image macro, rest the cursor on it and type ,img. (Visually selecting also works.)

Look at image:images/image.img[] it is beautiful!

In this case, the file path is the target of the image macro.

There are other cases, like the ] macros that are littered throughout this document. The text from which I want to create a kbd macro is not going to make sense as a target+but as attributes in the macro. If the cursor is over the text+or the text is visually selected+typing kbd:[,kbd will turn

\kbd

into

kbd:[,kbd]

The ,btn, ,kbd, and ,menu normal mode maps operate on the big WORD under the cursor.

Macros

image

,img

keyboard

,kbd

menu

,menu

button

,btn

include

,inc

Cross references

Another editing operation that is mapped is turning a string into a cross reference.

Check out the section on Macros if you haven't already.

Position the cursor over a word, or visually select some text, then type ,xr.

Check out the <<section-on-Macros, section on Macros>> if you haven't already.

The operation does some substitutions on the input to generate a valid ref target (though it doesn’t validate that the target exists). The input text remains and is now the name of the reference.

Toggle title

It is recommended to use the ATX style for titles rather than the Setex style. Both are valid AsciiDoc, however, and whether one chooses to go against recommendation, or is working with source created by others, it can be useful to toggle between the two styles. Typing ,tt will toggle the title of the current section between the two styles.

Compiling

The plugin sets up Vim’s 'makeprg' to use asciidoctor. Some buffer local variables can be set in order to pass parameters to the processor.

b:adoc_out_dir

-D …​

b:adoc_styles_dir

-a stylesdir=…​

b:adoc_stylesheet

-a stylesheet=…​

The buffer local variables are included in 'makefile' when the plugin is loaded. You can begin editing your file, set these options, and then reload the plugin by 're-editing', with :e. If you compile most of your documents on a proper build system, this is useful for the one-off open ended edits. For anything else this workflow is somewhat broken. I would like to see it improved, deo volente.

The nice feature here, however, is "compile on save". By typing ,qi, "Quick Iteration" mode is toggled. Every time the buffer is saved, the file is compiled. Use the same command to toggle it off.

Folding

A simple expression folding function is included to fold on section titles. The plugin sets fdm=expr without consideration for your preferences. If you don’t like this, consider removing that code, or setting a modeline. If you fork and edit the plugin to handle this more gracefully, please consider issuing a PR.

Navigating

Preview file

To preview the file being edited in an external application, type ,pf. This will run an !open command for the current file and ask application g:asciidoc_preview_app to open the current file.

The preview command is not very portable, especially since the preview application is hard coded to be Firefox. If you don’t use Firefox and asciidoctor.js for previewing, then you should change or not use this feature. (If you improve it, consider issuing a PR!)

Motions

For navigating between titles, use the ]] and [[ motions. These move to the next and previous section titles, respectively. ][ and [] move to next and previous section end. These motions can be used with operators, see Editing: Motions.

Jump around

Vim has excellent support for navigating between files, including the gf command to edit a file whose name is the text under the cursor. Similarly, with ctags or cscope, navigating different references between files is a breeze. With AsciiDoc, there are cases where these don’t work well, however. Particularly this is true when links or filenames contain attribute references.

Tip

Unrelated to this plugin, for ctags to play nice with AsciiDoc, consdier adding the following to your ~/.ctags file. I found this somewhere and it has been useful. It could do with some improvements, but here it is fwiw.

--langdef=asciidoc
--langmap=asciidoc:.ad.adoc.asciidoc
--regex-asciidoc=/^=[ \t]+(.*)/# \1/h/
--regex-asciidoc=/^==[ \t]+(.*)/. \1/h/
--regex-asciidoc=/^===[ \t]+(.*)/. . \1/h/
--regex-asciidoc=/^====[ \t]+(.*)/. . . \1/h/
--regex-asciidoc=/^=====[ \t]+(.*)/. . . . \1/h/
--regex-asciidoc=/^======[ \t]+(.*)/. . . . \1/h/
--regex-asciidoc=/^=======[ \t]+(.*)/. . . . \1/h/
--regex-asciidoc=/\[\[([^]]+)\]\]/\1/a/
--regex-asciidoc=/^\.([^ \t].+)/\1/t/
--regex-asciidoc=/image::([^\[]+)/\1/i/
--regex-asciidoc=/image:([^:][^\[]+)/\1/I/
--regex-asciidoc=/include::([^\[]+)/\1/n/

This plugin has mappings for navigating both internal and external links, and will substitute attribute values for their references in links. Consider this document:

= Doc
:attr1: some
:attr2: some-other
:attr3: someone-else

Compare <<{attr1}-section, Some section>> to <<other.adoc#{attr2}-section, Some other section>>.

Submit your questions to link:http://www.{attr3}.org[someone's website].

[[some-section]]
== Some section

Let’s assume that there is a file called other-doc.adoc containing the [[some-other-section]] anchor. With the cursor on either cross reference, type ,gf to go to the corresponding anchor. The plugin reads off all attributes in the document and performs the substitution.

If the resulting link contains both a filename and an anchor reference, then the file is opened and the anchor is searched for. If there is no filename, the anchor is searched for in the current document.

If there is a filename, but the file doesn’t exist, the user is prompted whether to proceed editing a new file. This is useful for creating a link before creating a new document, for instance in a note taking system or Wiki. If editing proceeds, a new buffer is opened for the file, but it is not saved. The anchor is put into the buffer as a reminder to include the link target which was used to navigate to the file.

Note

Attribute substitution only works for attributes that are set in the current document. If the attribute is set in another document, which includes the current document, the substitution will fail.

External links

As with cross references, external links can be navigated, using the same command. For the link above, the attribute attr3 is interpolated and the link http://www.someone-else.org/ is then followed. External links are opened with the application recorded in g:asciidoc_browser with a simple !open command. For now, the browser option is hard coded as Firefox. It should be easy to set that up properly, but it’s not a priority for me at the moment.

Table 4. Navigation maps (what other kinds are there?)

Preview file with g:asciidoc_preview_app application

,of

Follow link under cursor in

…​ the current buffer or browser

,gf

…​ a horizontal split or browser

,<C-W>f

…​ a vertical split or browser

,<C-W><C-F>

…​ a new tab or browser

,<C-W>gf

Experimental

Experimental features that may or may note mature.

Blocke operations by motion

By typing ,bl followed by a motion, the text encompassed by the motion can be formatted as a block. The command requests user input to determine which block type to produce:

'q': 'quote'
'-': 'listing'
'v': 'verse'
'o': 'open'
'*': 'sidebar'
'+': 'passthrough'
'=': 'example'
'.': 'literal'
'/': 'comment'

,blip/<CR> will format the inner paragraph surrounding the cursor as a comment block.

Block and list text objects

Doing c,ab changes a block, d,ib deletes inner block, v,il visually selects inner list item (useful for multi-line list items).

Block surround (delimiter) operations

There is also a poor man’s surround functionality for deleting or changing the delimiters of a block: ,dsb and ,csb respectively.

The experimental block operations generally prompt for which type of block to work with. The change block delimiters operation prompts twice: once for the removal and once for the replacement.

Appendix A

By default, the plugin will set a few options and variables, and create lots of maps. All maps are buffer local and begin with <LocalLeader>. You can prevent this by setting let g:asciidoc_use_defaults = [] in your vimrc. The functions and commands will be created, but they will not be mapped and no options will be set.

Here is how the plugin sets it if you don’t, use it for inspiration:

let g:asciidoc_use_defaults = ['folding', 'editing', 'navigating', 'compiling', 'options']
Tip

Not loading the defaults will render the plugin rather useless, why would you want to do that? For a start, it is polite to make it easy to prevent a plugin from overwriting ones configuration. Additionally, you may want to use some of the functionality but provide your own maps. For example, disable 'editing'. Then yank-put the editing section from ftplugin/asciidoc.vim into your own after/ftplugin/asciidoc.vim. Change the maps to your liking, et voila, a reasonably easy way to have it the Burger King way.

About

Vim ftplugin for asciidoc

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published