Skip to content

Commit

Permalink
v0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
docelic committed Nov 30, 2019
1 parent 118704d commit a2412f2
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 137 deletions.
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Tput is a low-level component for building term/console applications in Crystal.
It is closely related to shard [Terminfo](https://github.com/crystallabs/terminfo).
Terminfo parses terminfo files into instances of `Terminfo::Data` or custom classes.

Tput builds on this basic functionality to provide a fully-functional environment.
Tput builds on this basic functionality to provide a more functional environment.
In addition to using the Terminfo data, it also detects the terminal program and its
known bugs or quirks, and configures itself for outputting the correct escape sequences.

Expand All @@ -26,12 +26,13 @@ Add the dependency to `shard.yml`:
dependencies:
tput:
github: crystallabs/tput
version: 0.1.0
version: 0.2.0
```
## Usage in a nutshell
Here is a basic example that initializes Tput and checks some of the boolean and numeric capabilities.
Here is a basic example that initializes Tput, checks some of the boolean and numeric capabilities,
and then moves the cursor 10 times diagonally.
```crystal
require "tput"
Expand All @@ -40,10 +41,10 @@ require "tput"
class MyClass
include Tput
end
my = MyClass.new
my = MyClass.new(use_buffer: false)

# With built-in class
my = Tput::Data.new
my = Tput::Data.new(use_buffer: false)

# Check whether we are running under an XTerm:
p my.xterm?
Expand All @@ -55,6 +56,12 @@ p my.booleans["over_strike"] # Same as ["os"]
# Print a couple numeric values
p my.numbers["columns"] # Same as ["cols"] or ["co"]
p my.numbers["lines"] # Same as ["lines"] or ["li"]

10.times do |i|
my.rmove 1, -1
my.print i.to_s
sleep 0.5
end
```

Tput can also output string capabilities. Most of the string capabilities are
Expand Down Expand Up @@ -117,4 +124,5 @@ Also, see examples in the directory `examples/`.

List of interesting or similar projects in no particular order:

- https://github.com/crystallabs/crysterm - Term/console toolkit for Crystal
- https://github.com/crystallabs/term_app - Basic app environment on top of tput
- https://github.com/crystallabs/crysterm - Complete term/console toolkit for Crystal
24 changes: 24 additions & 0 deletions examples/move10.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require "../src/tput"

# With own class
class MyClass
include Tput
end
my = MyClass.new(use_buffer: false)

# Check whether we are running under an XTerm:
p my.xterm?

# Test a couple boolean capabilities
p my.booleans["needs_xon_xoff"] # Same as ["nxon"] or ["nx"]
p my.booleans["over_strike"] # Same as ["os"]

# Print a couple numeric values
p my.numbers["columns"] # Same as ["cols"] or ["co"]
p my.numbers["lines"] # Same as ["lines"] or ["li"]

10.times do |i|
my.rmove 1, -1
my.print i.to_s
sleep 0.5
end
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: tput
version: 0.1.0
version: 0.2.0

authors:
- Davor Ocelic <[email protected]>
Expand Down
138 changes: 16 additions & 122 deletions src/methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,87 +3,6 @@ require "./macros"
module Tput
module Methods

def _owrite(text)
# TODO
#return unless @output.writable?
@output.write text.to_slice
end
alias_previous write

def _buffer(text)
if @_exiting
flush
_owrite(text)
return
end

if @_buf
@_buf += text
return
end

@_buf = text
flush
true
end

def flush
if (!@_buf)
return
end
_owrite(@_buf)
@_buf = ""
end

def _write(text)
return text if @ret
return _buffer(text) if @use_buffer
_owrite text
end

# Example: `DCS tmux; ESC Pt ST`
# Real: `DCS tmux; ESC Pt ESC \`
def _twrite(data)
iterations = 0
timer = nil

if false # TODO @is_tmux
# Replace all STs with BELs so they can be nested within the DCS code.
data = data.gsub /\x1b\\/, "\x07"

# Wrap in tmux forward DCS:
data = "\x1bPtmux;\x1b" + data + "\x1b\\"

# If we've never even flushed yet, it means we're still in
# the normal buffer. Wait for alt screen buffer.
# TODO
#if @output.bytes_written == 0
# timer = setInterval(function() {
# if (self.output.bytesWritten > 0 || ++iterations == 50) {
# clearInterval(timer)
# self.flush()
# self._owrite(data)
# end
# }, 100);
# return true
#end

# NOTE: Flushing the buffer is required in some cases.
# The DCS code must be at the start of the output.
flush

# Write out raw now that the buffer is flushed.
_owrite data
end

_write data
end

def print(txt, attr)
attr ? _write(text(txt, attr)) : _write(txt)
end
alias_previous echo

def _ncoords
if @x<0
@x=0
Expand Down Expand Up @@ -331,15 +250,20 @@ module Tput
alias_previous carriage_return # TODO can't alias 'return'

def feed
if @terminfo && @bools["eat_newline_glitch"] && (@x >= @cols)
if @terminfo && @booleans["eat_newline_glitch"] && (@x >= @cols)
return
end
@x = 0
@y+=1
_ncoords
(has("nel")) ? (put "nel") : _write("\n")
end
alias_previous nel, newline
alias_previous nel, newline, line_feed, lf

def crlf
cr
lf
end

# Esc

Expand Down Expand Up @@ -609,12 +533,12 @@ module Tput
end
_write("\x1b[" + (param || "").to_s + "A")
end
alias_method cuu, up
alias_previous cuu, up

# CSI Ps B
# Cursor Down Ps Times (default = 1) (CUD).
def cursor_down(param)
@y += param || 1
def cursor_down(param = 1)
@y += param
_ncoords
if @terminfo
if !@strings["parm_down_cursor"]
Expand Down Expand Up @@ -1081,7 +1005,7 @@ module Tput
end

@x = param
@y = 0
#@y = 0 # Bug in blessed
_ncoords

@terminfo ? put("hpa", param) : _write("\x1b[" + (param + 1).to_s + 'G')
Expand Down Expand Up @@ -1151,14 +1075,10 @@ module Tput
# CSI Pm d
# Line Position Absolute [row] (default = [1,column]) (VPA).
# NOTE: Can't find in terminfo, no idea why it has multiple params.
def line_pos_absolute(param)
@y = param || 1
def line_pos_absolute(*arguments)
@y = arguments[0]? || 1
_ncoords()
# TODO verify this
return(put "vpa", param) if @terminfo

param = arguments.join ';'
_write("\x1b[" + param.to_s + 'd')
@terminfo ? put("vpa", *arguments) : _write("\x1b[" + arguments.join(';').to_s + 'G')
end
alias_previous vpa

Expand Down Expand Up @@ -1929,39 +1849,13 @@ module Tput

# Returns number of columns.
def cols
::Tput::Methods.cols
@cols ||= ::Tput.cols
end
alias_previous columns

# Returns number of lines.
def lines
::Tput::Methods.lines
end
alias_previous rows

# Returns number of columns.
#
# Currently this uses ENV variables. For it to work, variable COLUMNS must be
# exposed to environment with `declare -X COLUMNS` or `export COLUMNS`.
# As such, it is effectively broken.
#
# Maybe it could issue `stty size` or `tput cols/lines`.
# Or do something like https://github.com/crystal-lang/crystal/issues/2061
def self.cols
ENV["COLUMNS"]?.try &.to_i || 1
end
alias_previous columns

# Returns number of lines.
#
# Currently this uses ENV variables. For it to work, variable LINES must be
# exposed to environment with `declare -X LINES` or `export LINES`.
# As such, it is effectively broken.
#
# Maybe it could issue `stty size` or `tput cols/lines`.
# Or do something like https://github.com/crystal-lang/crystal/issues/2061
def self.lines
ENV["LINES"]?.try &.to_i || 1
@rows ||= ::Tput.lines
end
alias_previous rows

Expand Down
Loading

0 comments on commit a2412f2

Please sign in to comment.