How to create a syntax file for text files? - vim

I wish I could format pieces of text in standard text files.
I would like to select a phrase or a word, invoke a simple command, and format it with these formatting:
bold
italic
underline
red font color
yellow background color
Is that possible?
(something like syntax highlighting in vim files but in my case with selected text)
I know there is a Txtfmt plugin in vim, I tried it 2 times the last years but uninstalled it every time.
This is why:
There is no way to visual select text and format it, you have to insert a begin code in the command-line write the text and insert an end code in the command-line.
You cannot copy the text because Txtfmt plugin inserts hidden formatting codes in the text
It is too complicate to insert a begin code and end code in the command line (after invoking a general command) and the codes are too complicated

There needs to be a kind of markup inserted into your text. Vim operates on plain text, it has no separate meta data layer like a word processor. With syntax highlighting and the new conceal feature, you can partially make Vim appear to be WYSIWYG, but actually you're still operating on the raw text.
If you're fine with that limitation and want to stick with Vim for your editing tasks, I'd suggest to use an existing markup solution instead of inventing a new one from scratch. By now, there are several syntaxes to choose from, with Markdown probably a favorite. (It's used here on Stack Overflow, too!) With an existing syntax, you can leverage all the existing plugins / mappings / commands, and even some external tools (e.g. for converting to HTML).

Here is probably the simplest possible implementation of what I believe you want. It allows custom strings to be highlighted in the current buffer using the colour/style you describe. The custom strings you choose to be highlighted cannot be saved between Vim sessions.
Firstly, define the highlight group SpecialTxt for your bespoke highlighting:
au ColorScheme * hi SpecialTxt guibg=yellow guifg=red gui=bold,underline,italic
(note that this has to be done via an autocmd so that loading a new colourscheme doesn't overwrite it).
Now you can select any regular expression to inherit this colour using:
call matchadd( 'SpecialTxt', [YOUR_REGEX], 1 )
Or you could write a simple command to set the match:
command! -nargs=1 Special :call matchadd('SpecialTxt',"<args>",1)
Or create a map so that double clicking on a word sets it to this colouring:
nnoremap <silent> <2-LeftMouse> :call matchadd('SpecialTxt',expand('<cword>'),1)<CR>
Hope that helps. Apologies if it is not quite what you are after.

Related

Highlighting and syntax trouble in vim using rmarkdown

I would like to get Vim to stop highlighting list characters (-,*) and heading characters (#) in rmarkdown. You can find a screenshot here: https://imgur.com/a/0YSB8V8.
This is happening when I set the file type to either pandoc or rmd. This is also happening no matter what terminal or colortheme I use.
I have the plugins: vim-pandoc, vim-pandoc-syntax, and vim-rmarkdown installed.
I would like to know a way to make the two characters just appear normally.
I would also like to know if there is a way to make italicized text in tables and headings appear italicized. As far as modifying the appearance of italicized text, I've tried using: hi Italic ctermfg=red cterm=italic in my vimrc, but that does not seem to affect the text in between asterisks (*) in rmd files. I admit I don't know much about the way that syntax works in Vim. Do I need to modify after/ftplugin/rmd.vim or runtime/syntax/rmd.vim? What is the difference between the two?
Any help would be appreciated!
Your syntax highlighter does not seem to recognize the bullet points, but thinks that they mark the beginning of an italic span. Maybe you have a clash of plugins. You could also try another highlighter (e.g. vim-polyglot, supports italics).
vim-pandoc-syntax uses the conceal feature (:h conceal). You can recolor the highlighting group Conceal to change the appearance of the replacement characters.
You can put changes to existing syntax files in .vim/after/syntax/rmd.vim. Files in syntax are executed when they are needed for the first time, but at most once per session. Files in ftplugin are executed every time the file type is changed.

How to "highlight" using text in Vim?

These three lines of Vim script "highlights" all instances of TODO in my source code by placing [[[ and ]]] around it.
:set t_Co=1
:highlight Braces start=[[[ stop=]]]
:call matchadd("Braces", "TODO")
Unfortunately, this only works in "normal terminals". This is why I have to set t_Co to 1.
Can something similar be achieved in a color terminal or in gui? (Or in NeoVim?). This could be an extremely useful way of augmenting your code with meta information.
Please keep in mind that Vim is a text editor; these display the file contents mostly as-is. In order to augment your code with meta information, Vim offers:
(syntax) highlighting: colors and text attributes like bold or italic
concealment: hide or condense matches to nothing / a single character
signs (shown in a column left of the window)
Your approach is a hack that misuses the definition of raw terminal codes; these are meant to be invisible control sequences interpreted by the terminal, but you send visible text.
As you've found out at :help highlight-args:
There are three types of terminals for highlighting:
term a normal terminal (vt100, xterm)
cterm a color terminal (MS-DOS console, color-xterm, these have the "Co"
termcap entry)
gui the GUI
The start= and end= arguments (that your hack relies on) are only supported for "normal terminals", not for cterm and gui. That's why you have to :set t_Co=1 (i.e. force a non-color terminal) for this to work.
Because of these downsides (and more: redrawing problems, vertical navigation that's off), I would recommend to drop this, and use one of the "approved" methods listed above. There are so many Vim users, and they seem to be fine with them as well.

Is it possible to display page feed symbols differently in Vim?

One of the nice things about Vim is that one can insert a page feed symbol (Ctrl-L in Insert mode), which delegates the printer to start printing the following on a new page. It shows as ^L in text.
Is it possible to make this symbol show as something else, for example as
----------------- new page here -----------------
so it is somewhat more visible while scrolling through pages of text?
That is, without rebuilding Vim from source.
If you do not use folding extensively when editing those files
containing page feed symbols, you can use one-line folds to mark
them out.
Using the foldexpr option, it is possible to increase the fold level
of the lines that contain page feed symbol. (Herein, for the sake of
efficiency of evaluating foldexpr, I assume that page feed symbols
are always the first characters on their lines.) To achieve the
desired effect of a screen-wide separator, these folds can be made
auto-closable.
The following function configures folding according to the idea
described above. Call it (manually or by means of an autocommand)
to enable page feed symbol folding in the current buffer.
function! FoldPageFeed()
setl foldmethod=expr
setl foldexpr=getline(v:lnum)[0]==\"\\<c-l>\"
setl foldminlines=0
setl foldtext='---\ new\ page\ '
setl foldlevel=0
set foldclose=all
endfunction
Resulting separators appear as the text --- new page followed by
a continuing string of filling characters to the right of the window
(see :help fillchars, under the fold: item).
I don't think you can. There is a non-text highlight group which could help.
Another way (a bit ugly) would be to write some autocommand to expand ^L to ---- new page ---- and vice versa when on InsertLeave, BufRead and BufSave.
Anyway, the answer of your question is no, if you just want to change the display, and probably yes with a nasty plugin.
If it could, I would be uncomfortable knowing that Vim, my heavily trusted tool and friend, could misrepresent a text file.
Of course, you could always execute this command (perhaps as a macro) to do the same thing:
:%s/^L/----------------- new page here -----------------/
If you defined your own highlight group in Vim to be just the ^L symbol, then you could have a custom highlighted background for all lines that contain that character.
It’s not quite a ---- new page here ----, but it would make page breaks easily visible when scrolling through large amounts of text.
I don’t know enough Vim to actually tell you how to set the highlight group though…

Using AStyle in Vim

I am trying to get AStyle working with Vim so that I can use the "=" key to re-indent various sections of code. For example, I'd like to be able to type my usual =iB to indent the current block of code using AStyle rather than the built in indenter.
I tried just setting equalprg=astyle in my vimrc, but the problem is that astyle only receives the selected block but thinks that it's receiving a whole file. Therefore, the indentation is completely off when I try to only indent a nested class.
I know that I can always reformat an entire file at once, but is there a way to use astyle in vim which completely replicates the original formatting behavior of vim (all my =-movement commands work - and bonus points for autoindent using astyle as well!)?
Unless there is a version of AStyle that has a partial file formatting option, you'll need to apply the extra indentation after you run AStyle.
I'm not sure how you can do this with motions.
With visual selection, you could grab the indentation from the first line, pass the code to equalprg, and then add that indentation to all of the lines:
vnoremap = <Esc>`<dwgv=`<<C-v>`>I<C-r>"<Esc>
Breaking it down:
vnoremap -- so we can use = for equalprg
<Esc>`< -- stop selecting and go to beginning of line at beginning of selection
dw -- grab the initial indentation
gv= -- reselect and indent as normal
`<<C-v>`> -- block select the selection
I<C-r>"<Esc> -- insert the initial indentation
Maybe you can do something similar with motions?
It only works for formatters that have a partial file formatting option, like idbrii already pointed out. An example of a formatter that does this is clang-format.
One way to integrate this into vim is by using vim-autoformat. Using this plugin you can viB and then press your self-defined format key, like <F3>. This will then only format the selected inner code block.

Applying different colorschemes to different windows

I want to used different colorschemes for different filetypes and I added the following code in my .vimrc
function SetColorScheme ()
if &filetype != "vo_base"
colorscheme desertEx
endif
endfunction
au WinEnter * call SetColorScheme()
This works fine with one issue.
If I open a .otl file, say todo.otl (vo_base), and then open another file, say example.xml, using :sp the colorscheme desertEx does not get applied to the second window (the one having example.xml).
If I use BufEnter instead of WinEnter than desertEx gets applied to both the windows.
Is there a way to make sure that when I open a window with :sp the above function (a) runs, and (b) runs only for that particular window and not all the windows in the current session.
No there's no way to do that. There can be only one active colorscheme at the same time in vim.
Something that comes to mind is to create a color scheme that directly points to the low-level syntax groups in the Vim syntax files.
Take for instance c.vim for the C programming language. You will find for instance syntax hightlighting groups such as: cStatement, cLabel, cConditional, cType.. etc.
Take python.vim and you will find pythonDefStatement, pythonFunction, pythonConditional, etc..
So, if you want to use different color schemes for C code and python, you would copy the two original color schemes to ~/.vim/colors/mycolorscheme.vim and edit them to point to the low-level syntax groups instead of the generic high level groups such as Comment, Constant, Error, Identifier, etc. that are found in many available color schemes.
Note that you would probably want keep a default stanza of 'highlight' statements on top of these other two to take care of syntax highlighting for files that contain neither C nor python code.
To clarify, you could edit the celebrated 'Hello World' code and issue the following from the Vim command line:
:hi cInclude ctermfg=cyan guifg=cyan
You have not changed color schemes, other files displayed in other windows or tabs are unaffected, and yet the '#include' is now displayed in a different color.
Unless you absolutely need the feature, I would advise against it, because it pretty much breaks Vim's syntax highlighting. Besides, it will require significant work to convert the existing ':hi' statements comprised in the original color schemes because there are usually many low-level syntax highlighting groups.
A somewhat better approach might be to link the language-specific low level groups to high-level groups that are also specific to each language. This would help keep the custom color scheme file reasonably small, but requires additional inventory work.

Resources