161 lines
4.9 KiB
Diff
161 lines
4.9 KiB
Diff
|
From 207fc803e1ceffb384ef9d0c6b2f2614bc8fdb67 Mon Sep 17 00:00:00 2001
|
||
|
From: "David B. Lamkins" <david@lamkins.net>
|
||
|
Date: Sun, 1 Oct 2017 10:43:56 -0700
|
||
|
Subject: [PATCH] Add vis-highlight command.
|
||
|
|
||
|
---
|
||
|
README.md | 2 +
|
||
|
man/vis-highlight.1 | 41 +++++++++++++++++++++++
|
||
|
vis-highlight | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
3 files changed, 132 insertions(+)
|
||
|
create mode 100644 man/vis-highlight.1
|
||
|
create mode 100755 vis-highlight
|
||
|
|
||
|
--- a/README.md
|
||
|
+++ b/README.md
|
||
|
@@ -53,6 +53,8 @@ compatible environment as well as:
|
||
|
* [Lua](http://www.lua.org/) >= 5.2 (optional)
|
||
|
* [LPeg](http://www.inf.puc-rio.br/~roberto/lpeg/) >= 0.12
|
||
|
(optional runtime dependency required for syntax highlighting)
|
||
|
+ * [lua-term](https://github.com/hoelzro/lua-term) >= 0.07
|
||
|
+ (optional runtime dependency required for CLI highlighting using vis-highlight)
|
||
|
* [TRE](http://laurikari.net/tre/) (optional for more memory efficient regex search)
|
||
|
|
||
|
Assuming these dependencies are met, execute:
|
||
|
--- /dev/null
|
||
|
+++ b/man/vis-highlight.1
|
||
|
@@ -0,0 +1,41 @@
|
||
|
+.Dd October 1, 2017
|
||
|
+.Dt VIS-HIGHLIGHT 1
|
||
|
+.Os Vis VERSION
|
||
|
+.
|
||
|
+.Sh NAME
|
||
|
+.Nm vis-highlight
|
||
|
+.Nd Highlight files using vis' lexers
|
||
|
+.
|
||
|
+.Sh SYNOPSIS
|
||
|
+.Nm vis-highlight
|
||
|
+.Ar lexer
|
||
|
+.Ar files
|
||
|
+.
|
||
|
+.Sh DESCRIPTION
|
||
|
+.Nm vis-highlight
|
||
|
+applies a vis lexer to highlight one or more files to standard output.
|
||
|
+.
|
||
|
+.Sh ENVIRONMENT
|
||
|
+.
|
||
|
+The following environment variables affect the operation of
|
||
|
+.Nm vis-highlight :
|
||
|
+.
|
||
|
+.Bl -tag -width Ev
|
||
|
+.It Ev VIS_PATH
|
||
|
+The default path to use to load Lua support files.
|
||
|
+.El
|
||
|
+.
|
||
|
+.Sh EXIT STATUS
|
||
|
+.Ex -std vis-highlight
|
||
|
+.
|
||
|
+.Sh EXAMPLES
|
||
|
+Highlight the visrc.lua file:
|
||
|
+.Bd -literal -offset indent
|
||
|
+vis-highlight lua ~/.config/vis/visrc.lua
|
||
|
+.Ed
|
||
|
+.
|
||
|
+.Sh BUGS
|
||
|
+An ANSI-compatible terminal is assumed.
|
||
|
+.
|
||
|
+.Sh SEE ALSO
|
||
|
+.Xr vis 1
|
||
|
--- /dev/null
|
||
|
+++ b/vis-highlight
|
||
|
@@ -0,0 +1,89 @@
|
||
|
+#! /usr/bin/env lua
|
||
|
+
|
||
|
+-- Standalone syntax highlighter uses the lexers provided by `vis`.
|
||
|
+
|
||
|
+if #arg < 2 then
|
||
|
+ print('usage: ' .. arg[0] .. ' LEXER-NAME FILE...')
|
||
|
+ return 1
|
||
|
+end
|
||
|
+
|
||
|
+vis_path = os.getenv('VIS_PATH')
|
||
|
+if vis_path ~= nil then
|
||
|
+ package.path = package.path .. ';' .. vis_path .. '/?.lua'
|
||
|
+end
|
||
|
+package.path = package.path .. ';/usr/local/share/vis/?.lua'
|
||
|
+package.path = package.path .. ';/usr/share/vis/?.lua'
|
||
|
+
|
||
|
+local syntax = arg[1]
|
||
|
+local lexers = require('lexer')
|
||
|
+local lexer = lexers.load(syntax)
|
||
|
+
|
||
|
+if not lexer then
|
||
|
+ print(string.format('Failed to load lexer: `%s`', syntax))
|
||
|
+ return 1
|
||
|
+end
|
||
|
+
|
||
|
+local term = require('term')
|
||
|
+local colors = term.colors
|
||
|
+
|
||
|
+local token_styles = {
|
||
|
+ -- bold => bright
|
||
|
+ -- italics => underscore
|
||
|
+ ['default'] = colors.default .. colors.onblack .. colors.white,
|
||
|
+ ['nothing'] = colors.default .. colors.onblack,
|
||
|
+ ['class'] = colors.default .. colors.yellow .. colors.bright,
|
||
|
+ ['comment'] = colors.default .. colors.blue .. colors.bright,
|
||
|
+ ['constant'] = colors.default .. colors.cyan .. colors.bright,
|
||
|
+ ['definition'] = colors.default .. colors.blue .. colors.bright,
|
||
|
+ ['error'] = colors.default .. colors.red .. colors.underscore,
|
||
|
+ ['function'] = colors.default .. colors.blue .. colors.bright,
|
||
|
+ ['keyword'] = colors.default .. colors.yellow .. colors.bright,
|
||
|
+ ['label'] = colors.default .. colors.green .. colors.bright,
|
||
|
+ ['number'] = colors.default .. colors.red .. colors.bright,
|
||
|
+ ['operator'] = colors.default .. colors.cyan .. colors.bright,
|
||
|
+ ['regex'] = colors.default .. colors.green .. colors.bright,
|
||
|
+ ['string'] = colors.default .. colors.red .. colors.bright,
|
||
|
+ ['preprocessor'] = colors.default .. colors.magenta .. colors.bright,
|
||
|
+ ['tag'] = colors.default .. colors.red .. colors.bright,
|
||
|
+ ['type'] = colors.default .. colors.green .. colors.bright,
|
||
|
+ ['variable'] = colors.default .. colors.blue .. colors.bright,
|
||
|
+ ['whitespace'] = '',
|
||
|
+ ['embedded'] = colors.default .. colors.onblue .. colors.bright,
|
||
|
+ ['identifier'] = colors.default .. colors.white,
|
||
|
+}
|
||
|
+
|
||
|
+for i = 2, #arg do
|
||
|
+ local filename = arg[i]
|
||
|
+ local file = assert(io.open(filename, 'r'))
|
||
|
+ local text = file:read('*all')
|
||
|
+ file:close()
|
||
|
+ local tokens = lexer:lex(text, 1)
|
||
|
+ local token_start = 1
|
||
|
+ local last = ''
|
||
|
+
|
||
|
+ for i = 1, #tokens, 2 do
|
||
|
+ local token_end = tokens[i+1] - 1
|
||
|
+ local name = tokens[i]
|
||
|
+ local style = token_styles[name]
|
||
|
+ if style ~= nil then
|
||
|
+ -- Whereas the lexer reports all other syntaxes over
|
||
|
+ -- the entire span of a token, it reports 'default'
|
||
|
+ -- byte-by-byte. We emit only the first 'default' of
|
||
|
+ -- a series in order to properly display multibyte
|
||
|
+ -- UTF-8 characters.
|
||
|
+ if not (last == 'default' and name == 'default') then
|
||
|
+ io.write(tostring(style))
|
||
|
+ end
|
||
|
+ last = name
|
||
|
+ end
|
||
|
+ local token = text:sub(token_start, token_end)
|
||
|
+ if style ~= nil then
|
||
|
+ -- Replicate the style after every newline within
|
||
|
+ -- the token, because less -R forgets attributes
|
||
|
+ -- with each newline.
|
||
|
+ token = token:gsub("\n", "\n" .. tostring(style))
|
||
|
+ end
|
||
|
+ io.write(token)
|
||
|
+ token_start = token_end + 1
|
||
|
+ end
|
||
|
+end
|