cless 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/Readme.md +1 -0
- data/bin/cless +287 -0
- data/lib/cless/assert.rb +3 -0
- data/lib/cless/cless.rb +816 -0
- data/lib/cless/data.rb +633 -0
- data/lib/cless/display.rb +639 -0
- data/lib/cless/export.rb +92 -0
- data/lib/cless/help.rb +97 -0
- data/lib/cless/optionsdb.rb +29 -0
- data/lib/cless/version.rb +1 -0
- metadata +70 -0
data/lib/cless/export.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Export
|
2
|
+
Format = {}
|
3
|
+
|
4
|
+
def self.questions(format)
|
5
|
+
Format[format]::Questions rescue nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.export(file, format, lines, data, display, opts = {})
|
9
|
+
current_line = nil
|
10
|
+
mod = Format[format] or raise "Unsupported format '#{format}'"
|
11
|
+
line_s = lines.begin
|
12
|
+
line_e = lines.end
|
13
|
+
if !line_s.kind_of?(Integer) || !line_e.kind_of?(Integer) ||
|
14
|
+
line_s > line_e || line_s < 0
|
15
|
+
raise "Invalid line range '#{lines}'"
|
16
|
+
end
|
17
|
+
|
18
|
+
current_line = data.line + 1
|
19
|
+
nb_lines = line_e - line_s + 1
|
20
|
+
data.goto_line(line_s)
|
21
|
+
data.cache_fill(nb_lines)
|
22
|
+
nb_col = data.sizes.size
|
23
|
+
|
24
|
+
col_start = display.col_start
|
25
|
+
hidden = display.col_hidden
|
26
|
+
hidden.map! { |x| x - col_start } # Make it 0 based
|
27
|
+
col_show = (0...nb_col).to_a - hidden
|
28
|
+
nb_col = col_show.size
|
29
|
+
|
30
|
+
lines = proc { |b|
|
31
|
+
data.lines(nb_lines) { |l|
|
32
|
+
next if l.kind_of?(IgnoredLine)
|
33
|
+
a = l.values_at(*col_show)
|
34
|
+
b.call(a)
|
35
|
+
}
|
36
|
+
}
|
37
|
+
class << lines
|
38
|
+
def each(&b); self.call(b); end
|
39
|
+
end
|
40
|
+
|
41
|
+
columns = if display.col_names
|
42
|
+
display.col_headers.values_at(*col_show)
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
File.open(file, "w") { |fd|
|
49
|
+
mod.export(fd, nb_col, lines, columns, opts)
|
50
|
+
return fd.pos
|
51
|
+
}
|
52
|
+
ensure
|
53
|
+
if current_line
|
54
|
+
data.clear_cache
|
55
|
+
data.goto_line(current_line)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module Export::TeX
|
61
|
+
Export::Format["tex"] = self
|
62
|
+
Questions = []
|
63
|
+
|
64
|
+
def self.export(io, nb_col, lines, headers, opts = {})
|
65
|
+
io << "\\begin{tabular}{|" << (["c"] * nb_col).join("|") << "|}\\hline\n"
|
66
|
+
if headers
|
67
|
+
io << headers.join(" & ")
|
68
|
+
io << "\\tabularnewline\\hline\\hline\n"
|
69
|
+
end
|
70
|
+
lines.each { |a|
|
71
|
+
a.map! { |t| t && t.gsub(/\&/, '\&').gsub(/\\/, "\\textbackslash{}") }
|
72
|
+
io << a.join(" & ") << "\\tabularnewline\\hline\n"
|
73
|
+
}
|
74
|
+
io << "\\end{tabular}\n"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module Export::CSV
|
79
|
+
Export::Format["csv"] = self
|
80
|
+
Questions = [[ :separator, "Separator", ","]]
|
81
|
+
|
82
|
+
def self.export(io, nb_col, lines, headers, opts = {})
|
83
|
+
sep = opts[:separator] || ','
|
84
|
+
raise "CSV separator must be 1 character" if sep.length != 1
|
85
|
+
require 'csv'
|
86
|
+
|
87
|
+
CSV::Writer.generate(io, sep) { |csv|
|
88
|
+
csv << headers if headers
|
89
|
+
lines.each { |a| csv << a }
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
data/lib/cless/help.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
module Help
|
2
|
+
CONTENT = <<EOF
|
3
|
+
CLESS HELP
|
4
|
+
Press q to quit
|
5
|
+
|
6
|
+
Key binding
|
7
|
+
===========
|
8
|
+
|
9
|
+
Key binding is mostly compatible with the original less.
|
10
|
+
|
11
|
+
ARROW_DOWN, ENTER, ^N, ^E, j scroll down one line
|
12
|
+
SPACE BAR, PAGE_DOWN, ^V, ^F, f scroll down one page
|
13
|
+
ARROW_UP, ^Y, ^P, ^K, y, k scroll up one line
|
14
|
+
PAGE_UP, ^B, b scroll up one page
|
15
|
+
ARROW_RIGHT, ESC-) scroll right one column
|
16
|
+
ARROW_LEFT, ESC-( scroll left one column
|
17
|
+
d scroll down half screen
|
18
|
+
u scroll up half screen
|
19
|
+
HOME, g, < go to top of file
|
20
|
+
END, G, > go to end of file
|
21
|
+
+ increase column spacing
|
22
|
+
- decrease column spacing
|
23
|
+
c show/hide the column numbers
|
24
|
+
l show/hide the line numbers (1 based)
|
25
|
+
L show byte offset instead of line number
|
26
|
+
h hide column (space separated list)
|
27
|
+
H show column (space separated list)
|
28
|
+
` (back-tick) change first column index
|
29
|
+
o toggle highlighting of alternate lines
|
30
|
+
O toggle highlighting of alternate columns
|
31
|
+
m shift line highlighting start
|
32
|
+
M shift column highlighting start
|
33
|
+
F go to. 10 -> absolute line number
|
34
|
+
10o -> absolute offset
|
35
|
+
10% -> percentage in file
|
36
|
+
p go to percentage.
|
37
|
+
v format columns.
|
38
|
+
i ignore lines. Lines or regexp
|
39
|
+
I remove ignore lines patterns
|
40
|
+
/ forward search
|
41
|
+
? backward search
|
42
|
+
n repeat previous search
|
43
|
+
N repeat previous search, reversed direction
|
44
|
+
s save content to file
|
45
|
+
E export content to some format (tex, csv)
|
46
|
+
S change split regexp
|
47
|
+
t toggle column names
|
48
|
+
^ use a line from file for column headers
|
49
|
+
| change column separator character
|
50
|
+
[ shift content of a column to the left
|
51
|
+
] shift content of a column to the right
|
52
|
+
{ shift content of a column to the start
|
53
|
+
} shift content of a column to the end
|
54
|
+
( reduce width of a column
|
55
|
+
) increase width of a column
|
56
|
+
\\ change column padding string
|
57
|
+
r, R, ^R, ^L refresh display
|
58
|
+
: command menu
|
59
|
+
q quit
|
60
|
+
|
61
|
+
Notes on Searching
|
62
|
+
==================
|
63
|
+
|
64
|
+
The search patterns are Perl compatible regular expressions. It is ill
|
65
|
+
advised to use patterns that match white spaces as the spaces are
|
66
|
+
ignored when displayed. I.e., a match MUST be contained within a
|
67
|
+
column to be properly displayed. If a match span accross columns,
|
68
|
+
strange behavior may occure. To force a match to be the entire column
|
69
|
+
width, use the word boundary anchor: \\b. E.g., to match the line with
|
70
|
+
a column having only 0 (instead of any column which contains a 0), use
|
71
|
+
the following pattern: \\b0\\b.
|
72
|
+
|
73
|
+
Note also that the match might be in a hidden column. In any case, if
|
74
|
+
the line numbers are displayed, a line having a match will have its
|
75
|
+
line number in reverse video.
|
76
|
+
|
77
|
+
Environment variable
|
78
|
+
====================
|
79
|
+
|
80
|
+
If set, the environment variable CLESS gives switches to be added to the
|
81
|
+
switches found on the command line. For example, to always display the line
|
82
|
+
numbers and columns:
|
83
|
+
CLESS="--lines --column"
|
84
|
+
EOF
|
85
|
+
|
86
|
+
|
87
|
+
OPTIONS = "--no-column --no-line --no-offset --no-line-highlight " +
|
88
|
+
"--no-column-highlight --no-column-names --no-parse-header " +
|
89
|
+
"--ignore '/^\s/'"
|
90
|
+
|
91
|
+
def self.display
|
92
|
+
io = open("|#{$0} #{OPTIONS}", "w")
|
93
|
+
io.write(CONTENT)
|
94
|
+
io.close
|
95
|
+
Process.wait rescue nil
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class OptionsDB
|
2
|
+
def initialize(*files)
|
3
|
+
@names = {}
|
4
|
+
@regexps = {}
|
5
|
+
files.each { |f| parse_file(f) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse_file(name)
|
9
|
+
File.open(File.expand_path(name)) do |fd|
|
10
|
+
fd.each_line do |l|
|
11
|
+
a = l.split_with_quotes
|
12
|
+
n = a.shift
|
13
|
+
r = a.shift
|
14
|
+
@names[n] = a
|
15
|
+
@regexps[Regexp.new(r)] = a
|
16
|
+
end
|
17
|
+
end
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def match(fname)
|
22
|
+
@regexps.each do |regexp, v|
|
23
|
+
return v if fname =~ regexp
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](name); name.nil? ? nil : @names[name]; end
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Version = [0, 3, 20]
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cless
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.20
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guillaume Marçais
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ncursesw
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
description: cless displays column oriented files.
|
28
|
+
email:
|
29
|
+
- gmarcais@cs.cmu.edu
|
30
|
+
executables:
|
31
|
+
- cless
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- Readme.md
|
37
|
+
- bin/cless
|
38
|
+
- lib/cless/assert.rb
|
39
|
+
- lib/cless/cless.rb
|
40
|
+
- lib/cless/data.rb
|
41
|
+
- lib/cless/display.rb
|
42
|
+
- lib/cless/export.rb
|
43
|
+
- lib/cless/help.rb
|
44
|
+
- lib/cless/optionsdb.rb
|
45
|
+
- lib/cless/version.rb
|
46
|
+
homepage: https://github.com/gmarcais/cless
|
47
|
+
licenses:
|
48
|
+
- GPL-3.0
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.7.6
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: A column oriented less
|
70
|
+
test_files: []
|