Skip to content

Commit

Permalink
Merge pull request #405 from essentialkaos/develop
Browse files Browse the repository at this point in the history
Version 12.88.0
  • Loading branch information
andyone authored Nov 21, 2023
2 parents 57cbd2f + c83c0ee commit 3662964
Show file tree
Hide file tree
Showing 17 changed files with 407 additions and 45 deletions.
4 changes: 3 additions & 1 deletion .scripts/packages.list
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* + mathutil
L + netutil
* + options
* + pager
* + passwd
* + path
* + pid
Expand All @@ -53,7 +54,8 @@ L - system/process
* - system/procname
L + system/sensors
* - terminal
* ! terminal/window
* ! terminal/tty
* - terminal/window
* + timeutil
* + tmp
* + usage
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## Changelog

### 12.88.0

* `[pager]` Added new package for pager (`less`/`more`) setup
* `[terminal/tty]` Added new package for working with TTY
* `[fmtc]` Added method `IsColorsSupported`

### 12.87.0

* `[fmtc]` Added tag for italic text (`{&}`)
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ If you are using SublimeText 4 (`4075+`), we strongly recommend that you install
* [`mathutil`](https://kaos.sh/g/ek.v12/mathutil) — Package provides some additional math methods
* [`netutil`](https://kaos.sh/g/ek.v12/netutil) — Package provides methods for working with network
* [`options`](https://kaos.sh/g/ek.v12/options) — Package provides methods for working with command-line options
* [`pager`](https://kaos.sh/g/ek.v12/pager) — Package provides methods for pager setup (more/less)
* [`passwd`](https://kaos.sh/g/ek.v12/passwd) — Package contains methods for working with passwords
* [`path`](https://kaos.sh/g/ek.v12/path) — Package for working with paths (fully compatible with base path package)
* [`pid`](https://kaos.sh/g/ek.v12/pid) — Package for working with PID files
Expand All @@ -99,7 +100,7 @@ If you are using SublimeText 4 (`4075+`), we strongly recommend that you install
* [`system/sensors`](https://kaos.sh/g/ek.v12/system/sensors) — Package provide methods for collecting sensors information
* [`system`](https://kaos.sh/g/ek.v12/system) — Package provides methods for working with system data (metrics/users)
* [`terminal`](https://kaos.sh/g/ek.v12/terminal) — Package provides methods for working with user input
* [`terminal/window`](https://kaos.sh/g/ek.v12/terminal/window) — Package provides methods for working terminal window
* [`terminal/tty`](https://kaos.sh/g/ek.v12/terminal/tty) — Package provides methods for working with TTY
* [`timeutil`](https://kaos.sh/g/ek.v12/timeutil) — Package provides methods for working with time and date
* [`tmp`](https://kaos.sh/g/ek.v12/tmp) — Package provides methods for working with temporary data
* [`usage`](https://kaos.sh/g/ek.v12/usage) — Package usage provides methods and structs for generating usage info for command-line tools
Expand Down
2 changes: 1 addition & 1 deletion ek.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
// ////////////////////////////////////////////////////////////////////////////////// //

// VERSION is current ek package version
const VERSION = "12.87.0"
const VERSION = "12.88.0"

// ////////////////////////////////////////////////////////////////////////////////// //

Expand Down
4 changes: 4 additions & 0 deletions fmtc/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ func ExampleClean() {
// Output: Text
}

func ExampleIsColorsSupported() {
fmt.Printf("16 Colors Supported: %t\n", IsColorsSupported())
}

func ExampleIs256ColorsSupported() {
fmt.Printf("256 Colors Supported: %t\n", Is256ColorsSupported())
}
Expand Down
23 changes: 21 additions & 2 deletions fmtc/fmtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ var DisableColors = os.Getenv("NO_COLOR") != ""

// ////////////////////////////////////////////////////////////////////////////////// //

var colors256Supported bool
var colorsTCSupported bool
var colorsSupported bool // 16 colors support
var colors256Supported bool // 256 colors support
var colorsTCSupported bool // 24bit (TrueColor) colors support
var colorsSupportChecked bool

var colorsMap *sync.Map
Expand Down Expand Up @@ -328,6 +329,17 @@ func Bell() {
fmt.Print(_CODE_BELL)
}

// IsColorsSupported returns true if 16 colors is supported by terminal
func IsColorsSupported() bool {
if colorsSupportChecked {
return colorsSupported
}

checkForColorsSupport()

return colorsSupported
}

// Is256ColorsSupported returns true if 256 colors is supported by terminal
func Is256ColorsSupported() bool {
if colorsSupportChecked {
Expand Down Expand Up @@ -644,6 +656,13 @@ func isValidNamedTag(tag string) bool {
}

func checkForColorsSupport() {
switch {
case strings.Contains(term, "xterm"),
strings.Contains(term, "color"),
term == "screen":
colorsSupported = true
}

if strings.Contains(term, "256color") {
colors256Supported = true
}
Expand Down
1 change: 1 addition & 0 deletions fmtc/fmtc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ func (s *FormatSuite) Test24BitColors(c *C) {

c.Assert(IsTrueColorSupported(), Equals, true)
c.Assert(Is256ColorsSupported(), Equals, true)
c.Assert(IsColorsSupported(), Equals, true)

colorsSupportChecked = false
colors256Supported = false
Expand Down
20 changes: 20 additions & 0 deletions pager/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package pager

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2023 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

func ExampleSetup() {
// Use pager from PAGER env var or default (more)
Setup("")

// Or provide specific command.
Setup("less -MQR")

// Complete must be called at the end of the program work. You can call it with defer
// in your main function.
defer Complete()
}
95 changes: 95 additions & 0 deletions pager/pager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Package pager provides methods for pager setup (more/less)
package pager

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2023 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import (
"errors"
"os"
"os/exec"
"strings"
)

// ////////////////////////////////////////////////////////////////////////////////// //

// DEFAULT is default pager command
const DEFAULT = "more"

// ////////////////////////////////////////////////////////////////////////////////// //

var pagerCmd *exec.Cmd
var pagerOut *os.File

var stdout *os.File
var stderr *os.File

// ////////////////////////////////////////////////////////////////////////////////// //

var ErrAlreadySet = errors.New("Pager already set")

// ////////////////////////////////////////////////////////////////////////////////// //

// Setup set up pager for work. After calling this method, any data sent to Stdout and
// Stderr (using fmt, fmtc, or terminal packages) will go to the pager.
func Setup(pager string) error {
if pagerCmd != nil {
return ErrAlreadySet
}

pagerCmd = getPagerCommand(pager)

pagerCmd.Stdout, stdout = os.Stdout, os.Stdout
pagerCmd.Stderr, stderr = os.Stderr, os.Stderr

w, err := pagerCmd.StdinPipe()

if err != nil {
return err
}

pagerOut = w.(*os.File)
os.Stdout = pagerOut

return pagerCmd.Start()
}

// Complete finishes pager work
func Complete() {
if pagerOut != nil {
pagerOut.Close()
pagerOut = nil
}

if pagerCmd != nil {
pagerCmd.Wait()
pagerCmd = nil
}

os.Stdout = stdout
os.Stderr = stderr
}

// ////////////////////////////////////////////////////////////////////////////////// //

// getPagerCommand creates command for pager
func getPagerCommand(pager string) *exec.Cmd {
if pager == "" {
pager = os.Getenv("PAGER")
}

if pager == "" {
pager = DEFAULT
}

if strings.Contains(pager, " ") {
cmdSlice := strings.Fields(pager)
return exec.Command(cmdSlice[0], cmdSlice[1:]...)
}

return exec.Command(pager)
}
55 changes: 55 additions & 0 deletions pager/pager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package pager

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2023 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import (
"os"
"testing"

. "github.com/essentialkaos/check"
)

// ////////////////////////////////////////////////////////////////////////////////// //

func Test(t *testing.T) { TestingT(t) }

type PagerSuite struct{}

// ////////////////////////////////////////////////////////////////////////////////// //

var _ = Suite(&PagerSuite{})

// ////////////////////////////////////////////////////////////////////////////////// //

func (s *PagerSuite) TearDownSuite(c *C) {
Complete()
}

func (s *PagerSuite) TestPager(c *C) {
c.Assert(Setup("cat"), IsNil)
c.Assert(Setup("cat"), NotNil)

Complete()

c.Assert(pagerCmd, IsNil)
c.Assert(pagerOut, IsNil)
}

func (s *PagerSuite) TestPagerSearch(c *C) {
os.Setenv("PAGER", "")

cmd := getPagerCommand("cat")
c.Assert(cmd.Args, DeepEquals, []string{"cat"})

cmd = getPagerCommand("")
c.Assert(cmd.Args, DeepEquals, []string{"more"})

os.Setenv("PAGER", "less -MQR")
cmd = getPagerCommand("")
c.Assert(cmd.Args, DeepEquals, []string{"less", "-MQR"})
}
33 changes: 33 additions & 0 deletions pager/pager_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Package pager provides methods for pager setup (more/less)
package pager

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2023 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import "errors"

// ////////////////////////////////////////////////////////////////////////////////// //

// DEFAULT is default pager command
const DEFAULT = "more"

// ////////////////////////////////////////////////////////////////////////////////// //

var ErrAlreadySet = errors.New("Pager already set")

// ////////////////////////////////////////////////////////////////////////////////// //

// ❗ Setup set up pager for work. After calling this method, any data sent to Stdout and
// Stderr (using fmt, fmtc, or terminal packages) will go to the pager.
func Setup(pager string) error {
return nil
}

// ❗ Complete finishes pager work
func Complete() {
return
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package window
package tty

// ////////////////////////////////////////////////////////////////////////////////// //
// //
Expand Down
64 changes: 64 additions & 0 deletions terminal/tty/size_posix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//go:build !windows
// +build !windows

package tty

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2023 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import (
"os"
"syscall"
"unsafe"
)

// ////////////////////////////////////////////////////////////////////////////////// //

type winsize struct {
rows uint16
cols uint16
xpixels uint16
ypixels uint16
}

// ////////////////////////////////////////////////////////////////////////////////// //

// tty is a path to TTY device file
var tty = "/dev/tty"

// ////////////////////////////////////////////////////////////////////////////////// //

// GetSize returns window width and height
func GetSize() (int, int) {
t, err := os.OpenFile(tty, syscall.O_RDONLY, 0)

if err != nil {
return -1, -1
}

var sz winsize

_, _, _ = syscall.Syscall(
syscall.SYS_IOCTL, t.Fd(),
uintptr(syscall.TIOCGWINSZ),
uintptr(unsafe.Pointer(&sz)),
)

return int(sz.cols), int(sz.rows)
}

// GetWidth returns window width
func GetWidth() int {
w, _ := GetSize()
return w
}

// GetHeight returns window height
func GetHeight() int {
_, h := GetSize()
return h
}
Loading

0 comments on commit 3662964

Please sign in to comment.